fbs/fontandbitmapserver/sfbs/SESSION.CPP
changeset 0 5d03bc08d59c
child 18 57c618273d5c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <fbs.h>
       
    17 #include "fbsdefs.h"
       
    18 #include "UTILS.H"
       
    19 #include "FBSVER.H"
       
    20 #include "FbsRalc.h"
       
    21 #include "fbshelper.h"
       
    22 #include "fbsmessage.h"
       
    23 
       
    24 GLDEF_C void Panic(TFbsPanic aPanic)
       
    25 	{
       
    26 	_LIT(KFBSERVClientPanicCategory,"FBSCLI");
       
    27 	User::Panic(KFBSERVClientPanicCategory,aPanic);
       
    28 	}
       
    29 
       
    30 EXPORT_C TInt FbsStartup()
       
    31 	{
       
    32 	RChunk sharedchunk;
       
    33 	TInt ret = sharedchunk.OpenGlobal(KFBSERVSharedChunkName,EFalse);
       
    34 	if (ret == KErrNone)
       
    35 		{
       
    36 		sharedchunk.Close();
       
    37 		return KErrNone;
       
    38 		}
       
    39 
       
    40 	RProcess fbs;
       
    41 	_LIT(KFBSERVServerExe,"z:\\sys\\bin\\fbserv.exe");
       
    42 	ret = fbs.Create(KFBSERVServerExe,KNullDesC);
       
    43 
       
    44 	if (ret!=KErrNone)
       
    45 		return ret;
       
    46 	
       
    47   	
       
    48 	TRequestStatus stat;
       
    49 	fbs.Rendezvous(stat);
       
    50 	if (stat!=KRequestPending)
       
    51 		fbs.Kill(0);		// abort startup
       
    52 	else
       
    53 		fbs.Resume();	// logon OK - start the server
       
    54 	User::WaitForRequest(stat);		// wait for start or death
       
    55 	// we can't use the 'exit reason' if the server panicked as this
       
    56 	// is the panic 'reason' and may be '0' which cannot be distinguished
       
    57 	// from KErrNone
       
    58 	ret=(fbs.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
       
    59 	fbs.Close();
       
    60 	return ret;
       
    61 	}
       
    62 
       
    63 
       
    64 //
       
    65 // Fontbitmap server client side session
       
    66 //
       
    67 
       
    68 /** 
       
    69 @publishedAll 
       
    70 @released
       
    71 */
       
    72 EXPORT_C RFbsSession::RFbsSession():
       
    73 	RSessionBase(),
       
    74 	iConnections(0),
       
    75 	iCallBack(),
       
    76 	iSharedChunk(),
       
    77 	iHelper(NULL),
       
    78 	iRomFileAddrCache(NULL),
       
    79 	iDecompressionBuffer(NULL),
       
    80 	iScanLineBuffer(NULL),
       
    81 	iSpare(NULL)
       
    82 	{}
       
    83 
       
    84 /** Creates a session with the Font and Bitmap server.
       
    85 @param aFileServer A fuly constructed file server session
       
    86 @return KErrNone, if successful; KErrNoMemory if there is not enough memory 
       
    87 to create the session; otherwise another of the system-wide error codes. 
       
    88 @publishedAll 
       
    89 @released
       
    90 */
       
    91 EXPORT_C TInt RFbsSession::Connect(RFs& aFileServer)
       
    92 	{
       
    93 	RFbsSession* thisptr = (RFbsSession*)Dll::Tls();
       
    94 	if(thisptr)
       
    95 		{
       
    96 		thisptr->iConnections++;
       
    97 		return KErrNone;
       
    98 		}
       
    99 	TInt ret = RFbsSession::DoAlloc(thisptr);
       
   100 	if(ret!=KErrNone)
       
   101 		return ret;
       
   102 	return thisptr->DoConnect(aFileServer);
       
   103 	}
       
   104 
       
   105 /** Creates a session with the Font and Bitmap server.
       
   106 @return KErrNone, if successful; KErrNoMemory if there is not enough memory 
       
   107 to create the session; otherwise another of the system-wide error codes. 
       
   108 @publishedAll 
       
   109 @released
       
   110 */
       
   111 EXPORT_C TInt RFbsSession::Connect()
       
   112 	{
       
   113 	RFbsSession* thisptr = (RFbsSession*)Dll::Tls();
       
   114 	if(thisptr)
       
   115 		{
       
   116 		thisptr->iConnections++;
       
   117 		return KErrNone;
       
   118 		}
       
   119 	TInt ret = RFbsSession::DoAlloc(thisptr);
       
   120 	if (ret!=KErrNone)
       
   121 		return ret;
       
   122 	ret = thisptr->iFileServer.Connect();
       
   123 	if(ret!=KErrNone)
       
   124 		{
       
   125 		thisptr->Disconnect();
       
   126 		return ret;
       
   127 		}
       
   128 	return thisptr->DoConnect(thisptr->iFileServer);
       
   129 	}
       
   130 
       
   131 /** Closes the session with the Font and Bitmap server. 
       
   132 @publishedAll 
       
   133 @released
       
   134 */
       
   135 EXPORT_C void RFbsSession::Disconnect()
       
   136 	{
       
   137 	RFbsSession* thisptr=(RFbsSession*)Dll::Tls();
       
   138 	if(thisptr==NULL) return;
       
   139 	if(thisptr->iConnections>0)
       
   140 		{
       
   141 		thisptr->iCallBack.iPtr=NULL;
       
   142 		thisptr->iCallBack.CallBack();
       
   143 		// Destructor of CFbsSessionHelper may call SendCommand to cancel an
       
   144 		// outstanding request, therefore destruction must be done before
       
   145 		// iConnections is 0 to avoid an assertion going off.
       
   146 		if(thisptr->iConnections==1)
       
   147 			{
       
   148 			delete thisptr->iHelper;
       
   149 			}
       
   150 		thisptr->iConnections--;
       
   151 		}
       
   152 	if(thisptr->iConnections==0)
       
   153 		{
       
   154 		thisptr->iSharedChunk.Close();
       
   155 		thisptr->iLargeBitmapChunk.Close();
       
   156 		// Call close on the iFileServer regardless of whether this session owns it: 
       
   157 		// if we don't own it, close will do nothing if there are still open files, 
       
   158 		// so always calling close introduces extra safety
       
   159 		thisptr->iFileServer.Close();
       
   160 		delete thisptr->iRomFileAddrCache; 
       
   161 		delete thisptr->iScanLineBuffer;
       
   162 		delete thisptr->iDecompressionBuffer;
       
   163 		thisptr->Close();
       
   164 		delete thisptr;
       
   165 		Dll::FreeTls();
       
   166 		}
       
   167 	}
       
   168 
       
   169 /**  Gets the current Font and Bitmap server session.
       
   170 @return  A pointer to the current session or NULL if Connect() has not been 
       
   171 called yet. 
       
   172 @publishedAll 
       
   173 @released
       
   174 */
       
   175 EXPORT_C RFbsSession* RFbsSession::GetSession()
       
   176     {
       
   177 	return((RFbsSession*)Dll::Tls());
       
   178 	}
       
   179 
       
   180 /** Triggers the most recently registered callback. This is mainly called by 
       
   181 bitmaps when their twips size changes and when any FBSERV objects are closed 
       
   182 to notify clients of a change that may affect their operation. 
       
   183 @publishedAll 
       
   184 @released
       
   185 */
       
   186 EXPORT_C void RFbsSession::CallBack()
       
   187     {
       
   188 	iCallBack.CallBack();
       
   189 	iCallBack.iPtr=NULL;
       
   190 	}
       
   191 
       
   192 void RFbsSession::SetCallBackPtr(TInt* aBitmapHandle)const
       
   193 	{
       
   194 	iCallBack.iPtr=aBitmapHandle;
       
   195 	}
       
   196 	
       
   197 /** Sets the callback.
       
   198 @param aCallBack callback object to be called by CallBack(). Only one may be 
       
   199 in use at a time and subsequent calls will displace previous calls. 
       
   200 @publishedAll 
       
   201 @released
       
   202 */	
       
   203 EXPORT_C void RFbsSession::SetCallBack(TCallBack aCallBack)
       
   204     {
       
   205 	iCallBack=aCallBack;
       
   206 	}
       
   207 
       
   208 /** Resets the callback. 
       
   209 @publishedAll 
       
   210 @released
       
   211 */	
       
   212 EXPORT_C void RFbsSession::ResetCallBack()
       
   213 	{
       
   214 	TCallBack cb(NULL);
       
   215 	iCallBack=cb;
       
   216 	}
       
   217 
       
   218 /**  Returns the number of Font and Bitmap Server objects currently in 
       
   219 use by this session.
       
   220 @return The number of resources in use: bitmaps, fonts, typeface stores. 
       
   221 @publishedAll 
       
   222 @released
       
   223 */	
       
   224 EXPORT_C TInt RFbsSession::ResourceCount()
       
   225     {
       
   226 	return(SendCommand(EFbsMessResourceCount));
       
   227 	}
       
   228 
       
   229 /** Utility function for passing commands to the server.
       
   230 @param aMessage Integer code for the message to pass - see TFbsMessage.
       
   231 @param aInt0 Parameter 0 for the message.
       
   232 @param aInt1 Parameter 1 for the message.
       
   233 @param aInt2 Parameter 2 for the message.
       
   234 @param aInt3 Parameter 3 for the message.
       
   235 @return Return code from RSessionBase::SendReceive(). 
       
   236 @internalComponent
       
   237 */
       
   238 EXPORT_C TInt RFbsSession::SendCommand(TInt aMessage,TInt aInt0,TInt aInt1,TInt aInt2,TInt aInt3) const
       
   239    {
       
   240 	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
       
   241 	switch(aMessage)
       
   242 		{
       
   243 	case EFbsMessShutdown:
       
   244 	case EFbsMessClose:
       
   245 		SetCallBackPtr(aMessage==EFbsMessClose ? &aInt1 : 0);
       
   246 		iCallBack.CallBack();
       
   247 	default:
       
   248 		break;
       
   249 		}
       
   250 	TInt ret = SendReceive(aMessage, TIpcArgs(aInt0,aInt1,aInt2,aInt3));
       
   251 	return(ret);
       
   252 	}
       
   253 
       
   254 TInt RFbsSession::SendCommand(TInt aMessage, const TIpcArgs& aArgs) const
       
   255 	{
       
   256 	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
       
   257 	return SendReceive(aMessage,aArgs);
       
   258 	}
       
   259 
       
   260 void RFbsSession::SendCommand(TInt aMessage, const TIpcArgs& aArgs, TRequestStatus &aStatus) const
       
   261 	{
       
   262 	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
       
   263 	SendReceive(aMessage,aArgs,aStatus);
       
   264 	}
       
   265 	
       
   266 /** Gets the current Font and Bitmap server version.
       
   267 @return The current version of the server. 
       
   268 @publishedAll 
       
   269 @released
       
   270 */
       
   271 EXPORT_C TVersion RFbsSession::Version()
       
   272 	{
       
   273 	TVersion v(KFbsMajorVersionNumber,KFbsMinorVersionNumber,KFbsBuildVersionNumber);
       
   274 	return(v);
       
   275 	}
       
   276 
       
   277 /** Gets the address of first location in the global shared heap containing 
       
   278 fonts and bitmaps.
       
   279 @return Pointer to the base of the shared heap. 
       
   280 @publishedAll 
       
   281 @released
       
   282 */	
       
   283 EXPORT_C TUint8* RFbsSession::HeapBase() const
       
   284 	{
       
   285 	return(iSharedChunk.Base());
       
   286 	}
       
   287 
       
   288 TBool RFbsSession::LookupBitmapInROM(const TDesC& aFilename, TAny*& aAddr)
       
   289 	{
       
   290 	aAddr = iRomFileAddrCache->Lookup(aFilename);
       
   291 	if (aAddr)
       
   292 		return ETrue;
       
   293 	return EFalse;
       
   294    	}
       
   295 
       
   296 TInt RFbsSession::DoAlloc(RFbsSession*& aNewSession)
       
   297 	{
       
   298 	aNewSession = (RFbsSession*)User::Alloc(sizeof(RFbsSession));
       
   299 	if(!aNewSession) 
       
   300 		return KErrNoMemory;
       
   301 	new(aNewSession) RFbsSession;
       
   302 	aNewSession->iConnections = 1;
       
   303 	TInt ret = Dll::SetTls(aNewSession);
       
   304 	if(ret!=KErrNone)
       
   305 		{
       
   306 		delete aNewSession;
       
   307 		aNewSession = NULL;
       
   308 		}
       
   309 	return ret;
       
   310 	}
       
   311 
       
   312 /**  
       
   313 Do actual connect as common to both Connect() and Connect(RFs& aFileServer). Store fully constructed
       
   314 file server session to iSpare member variable
       
   315 @see Connect()
       
   316 @return KErrNone, if successful; KErrNoMemory if there is not enough memory 
       
   317 to create the session; otherwise another of the system-wide error codes. 
       
   318 @internalComponent
       
   319 */
       
   320 TInt RFbsSession::DoConnect(RFs& aFileServer)
       
   321 	{
       
   322 	//Allow this session to be accessed by other process to lead bitmap in server
       
   323 	TInt ret = aFileServer.ShareProtected();
       
   324 	if (ret!=KErrNone)
       
   325 		{
       
   326 		Disconnect();
       
   327 		return ret;
       
   328 		}
       
   329 	iRomFileAddrCache = CFbsRalCache::New(4, aFileServer);
       
   330 	if (!iRomFileAddrCache)
       
   331 		{
       
   332 		Disconnect();
       
   333 		return KErrNoMemory;
       
   334 		}
       
   335 
       
   336 	ret = CreateSession(KFBSERVGlobalThreadName,Version(),-1);
       
   337 	if(ret!=KErrNone)
       
   338 		{
       
   339 		Disconnect();
       
   340 		return ret;
       
   341 		}
       
   342 	const TInt serverAssignedHandle = SendReceive(EFbsMessInit);
       
   343 	if(serverAssignedHandle <= 0)
       
   344 		{
       
   345 		Disconnect();
       
   346 		return serverAssignedHandle;
       
   347 		}
       
   348 	ret = iSharedChunk.OpenGlobal(KFBSERVSharedChunkName,EFalse);
       
   349 	if(ret!=KErrNone) 
       
   350 		Panic(EFbsPanicChunkError);
       
   351 	iHelper = new CFbsSessionHelper(*this);
       
   352 	if (!iHelper)
       
   353 		{
       
   354 		Disconnect();
       
   355 		return KErrNoMemory;
       
   356 		}
       
   357 	iHelper->iServerSessionHandle = serverAssignedHandle;
       
   358 	ret = iLargeBitmapChunk.OpenGlobal(KFBSERVLargeChunkName,EFalse);
       
   359 	if(ret!=KErrNone) 
       
   360 		Panic(EFbsPanicChunkError);
       
   361 	
       
   362 	iSpare = (TUint32*)&aFileServer;
       
   363 	return KErrNone;
       
   364 	}
       
   365 	
       
   366 /**  
       
   367 Allocates the buffer for decoding compressed rom bitmaps.
       
   368  
       
   369 Internal use only.
       
   370 
       
   371 @param 	aSize Minimum size of the buffer required.  
       
   372 		If the buffer is too small an attempt to resize it will be made.
       
   373 @return KErrNone if successful, 
       
   374 		KErrNoMemory if the buffer was too small and could 
       
   375 		not be expanded.
       
   376 @publishedAll 
       
   377 @released
       
   378 */
       
   379 TInt RFbsSession::AllocScanLineBuffer(TInt aSize)
       
   380     {
       
   381 	if (iScanLineBuffer && iScanLineBuffer->Des().MaxSize() >= aSize)
       
   382 		{
       
   383 		return KErrNone;
       
   384 		}
       
   385 
       
   386 	HBufC8* newBuffer = HBufC8::New(aSize);
       
   387 
       
   388 	if (newBuffer)
       
   389 		{
       
   390 		delete iScanLineBuffer;
       
   391 		iScanLineBuffer = newBuffer;
       
   392 		return KErrNone;
       
   393 		}
       
   394 
       
   395 	return KErrNoMemory;
       
   396 	}
       
   397 
       
   398 /**  
       
   399 Gets a reference to the buffer currently in use for decoding
       
   400 compressed rom bitmaps. 
       
   401 
       
   402 Internal use only.
       
   403 
       
   404 @return  The buffer area currently in use,
       
   405 @publishedAll 
       
   406 @released
       
   407 */
       
   408 HBufC8* RFbsSession::GetScanLineBuffer()
       
   409     {
       
   410 	return iScanLineBuffer;
       
   411 	}
       
   412 
       
   413 /**  
       
   414 Gets a pointer to the buffer currently in use for decoding
       
   415 compressed mask bitmaps. 
       
   416 
       
   417 Internal use only.
       
   418 @param 	aSize Minimum size of the buffer required.  
       
   419 		If the buffer is too small an attempt to resize it will be made.
       
   420 @return  The buffer area currently in use or NULL if there is no memory.
       
   421 @internalComponent 
       
   422 */
       
   423 HBufC8* RFbsSession::GetDecompressionBuffer(TInt aSize)
       
   424 	{
       
   425 	if (iDecompressionBuffer)
       
   426 		{
       
   427 		if (iDecompressionBuffer->Des().MaxSize() < aSize)
       
   428 			{
       
   429 			HBufC8* tempBuffer = iDecompressionBuffer->ReAlloc(aSize);
       
   430 			if (!tempBuffer)
       
   431 				{
       
   432 				return NULL;
       
   433 				}
       
   434 			iDecompressionBuffer = tempBuffer;
       
   435 			}
       
   436 		}
       
   437 	else
       
   438 		{
       
   439 		iDecompressionBuffer = HBufC8::New(aSize);
       
   440 		}
       
   441 
       
   442 	return iDecompressionBuffer;
       
   443 	}
       
   444 
       
   445 /**  
       
   446 Gets a pointer to an extra buffer for general use. 
       
   447 
       
   448 Internal use only.
       
   449 @param 	aSize Minimum size of the buffer required.  
       
   450 		If the buffer is too small an attempt to resize it will be made.
       
   451 @return  The buffer area currently in use or NULL if there is no memory.
       
   452 @internalComponent 
       
   453 */
       
   454 HBufC8* RFbsSession::GetExtraBuffer(TInt aSize)
       
   455 	{
       
   456 	if (iHelper->iExtraBuffer)
       
   457 		{
       
   458 		if (iHelper->iExtraBuffer->Des().MaxSize() < aSize)
       
   459 			{
       
   460 			HBufC8* tempBuffer = iHelper->iExtraBuffer->ReAlloc(aSize);
       
   461 			if (!tempBuffer)
       
   462 				{
       
   463 				return NULL;
       
   464 				}
       
   465 			iHelper->iExtraBuffer = tempBuffer;
       
   466 			}
       
   467 		}
       
   468 	else
       
   469 		{
       
   470 		iHelper->iExtraBuffer = HBufC8::New(aSize);
       
   471 		}
       
   472 
       
   473 	return iHelper->iExtraBuffer;
       
   474 	}
       
   475 
       
   476 /**
       
   477 Returns a handle assigned to this session by the server upon connection.
       
   478 This method should be used instead of SessionHandle() when passing a session 
       
   479 handle to FbServ APIs that require Session handles. 
       
   480 @return A handle representing this session on the server. 
       
   481 @pre The session has successfully connected to the server.
       
   482  */
       
   483 TInt RFbsSession::ServerSessionHandle() const
       
   484 	{
       
   485 	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
       
   486 	return iHelper->iServerSessionHandle;
       
   487 	}
       
   488 
       
   489 /**
       
   490 Returns the current sizes of the FBServ default heap, the heap for large bitmaps, 
       
   491 and the heap for small bitmaps.
       
   492 
       
   493 Not supported in release builds.
       
   494 
       
   495 @internalComponent
       
   496 @test
       
   497 @param aDefaultHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ default heap.
       
   498 @param aSmallBmpHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ heap for small bitmaps
       
   499 @param aBigBmpHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ heap for large bitmaps
       
   500 @return KErrNone or one of the system wide error codes in debug mode, or KErrNotSupported in release mode.
       
   501 */
       
   502 #ifdef _DEBUG
       
   503 EXPORT_C TInt RFbsSession::GetHeapSizes(TInt& aDefaultHeapSize, TInt& aSmallBmpHeapSize, TInt& aBigBmpHeapSize)
       
   504  	{
       
   505  	TPckgBuf<THeapSizes> data;
       
   506  	TIpcArgs args(&data);
       
   507  	TInt ret = SendReceive(EFbsMessGetHeapSizes, args);
       
   508  	if(ret == KErrNone)
       
   509  		{
       
   510  		aDefaultHeapSize = data().iDefault;
       
   511  		aSmallBmpHeapSize = data().iSmall;
       
   512  		aBigBmpHeapSize = data().iBig;
       
   513  		}
       
   514  	return ret;
       
   515  	}
       
   516 #else
       
   517 EXPORT_C TInt RFbsSession::GetHeapSizes(TInt&, TInt&, TInt&)
       
   518 	{
       
   519 	return KErrNotSupported;
       
   520 	}
       
   521 #endif