os/graphics/fbs/fontandbitmapserver/sfbs/SESSION.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 1995-2010 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 #include <graphics/fbsoogmmessage.h>
    24 #include "OstTraceDefinitions.h"
    25 #include "fbstrace.h"
    26 #ifdef OST_TRACE_COMPILER_IN_USE
    27 #include "SESSIONTraces.h"
    28 #endif
    29 
    30 GLDEF_C void Panic(TFbsPanic aPanic)
    31 	{
    32 	_LIT(KFBSERVClientPanicCategory,"FBSCLI");
    33 	User::Panic(KFBSERVClientPanicCategory,aPanic);
    34 	}
    35 
    36 EXPORT_C TInt FbsStartup()
    37 	{
    38 	RChunk sharedchunk;
    39 	TInt ret = sharedchunk.OpenGlobal(KFBSERVSharedChunkName,EFalse);
    40 	if (ret == KErrNone)
    41 		{
    42 		sharedchunk.Close();
    43 		return KErrNone;
    44 		}
    45 
    46 	RProcess fbs;
    47 	_LIT(KFBSERVServerExe,"z:\\sys\\bin\\fbserv.exe");
    48 	ret = fbs.Create(KFBSERVServerExe,KNullDesC);
    49 
    50 	if (ret!=KErrNone)
    51 		return ret;
    52 	
    53   	
    54 	TRequestStatus stat;
    55 	fbs.Rendezvous(stat);
    56 	if (stat!=KRequestPending)
    57 		fbs.Kill(0);		// abort startup
    58 	else
    59 		fbs.Resume();	// logon OK - start the server
    60 	User::WaitForRequest(stat);		// wait for start or death
    61 	// we can't use the 'exit reason' if the server panicked as this
    62 	// is the panic 'reason' and may be '0' which cannot be distinguished
    63 	// from KErrNone
    64 	ret=(fbs.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
    65 	fbs.Close();
    66 	return ret;
    67 	}
    68 
    69 
    70 //
    71 // Fontbitmap server client side session
    72 //
    73 
    74 /** 
    75 @publishedAll 
    76 @released
    77 */
    78 EXPORT_C RFbsSession::RFbsSession():
    79 	RSessionBase(),
    80 	iConnections(0),
    81 	iCallBack(),
    82 	iSharedChunk(),
    83 	iHelper(NULL),
    84 	iRomFileAddrCache(NULL),
    85 	iDecompressionBuffer(NULL),
    86 	iScanLineBuffer(NULL),
    87 	iSpare(NULL)
    88 	{}
    89 
    90 /** Creates a session with the Font and Bitmap server.
    91 @param aFileServer A fuly constructed file server session
    92 @return KErrNone, if successful; KErrNoMemory if there is not enough memory 
    93 to create the session; otherwise another of the system-wide error codes. 
    94 @publishedAll 
    95 @released
    96 */
    97 EXPORT_C TInt RFbsSession::Connect(RFs& aFileServer)
    98 	{
    99     TInt ret = KErrNone;
   100 	RFbsSession* thisptr = (RFbsSession*)Dll::Tls();
   101 	FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_CONNECT_ENTRY, "> this=0x%08x;", (TUint)thisptr);)
   102 	if(thisptr)
   103 		{
   104 		thisptr->iConnections++;
   105 		FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_SEMANTICS, RFBSSESSION_CONNECT_INFO, "# Connected to existing session; this=0x%08x; iConnections=%d;", (TInt)thisptr, thisptr->iConnections);)
   106 		}
   107 	else
   108 	    {
   109         ret = RFbsSession::DoAlloc(thisptr);
   110         if(ret!=KErrNone)
   111             {
   112             FBS_OST(OstTrace1(TRACE_ERROR, RFBSSESSION_CONNECT_ERROR, "! DoAlloc returned %d", ret);)
   113             }
   114         else
   115             {
   116             ret = thisptr->DoConnect(aFileServer);
   117             if(ret!=KErrNone)
   118                 {
   119                 FBS_OST(OstTraceExt2(TRACE_ERROR, RFBSSESSION_CONNECT_ERROR2, "! this=0x%08x; DoConnect returned %d", (TInt)thisptr, ret);)
   120                 }
   121             }
   122 	    }
   123 	
   124 	FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_CONNECT_EXIT, "< this=0x%08x; ret=%d", (TUint)thisptr, ret);)
   125 	return ret; 
   126 	}
   127 
   128 /** Creates a session with the Font and Bitmap server.
   129 @return KErrNone, if successful; KErrNoMemory if there is not enough memory 
   130 to create the session; otherwise another of the system-wide error codes. 
   131 @publishedAll 
   132 @released
   133 */
   134 EXPORT_C TInt RFbsSession::Connect()
   135 	{
   136     TInt ret = KErrNone;
   137 	RFbsSession* thisptr = (RFbsSession*)Dll::Tls();
   138 	FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_CONNECT2_ENTRY, "> this=0x%08x;", (TUint)thisptr);)
   139 	if(thisptr)
   140 		{
   141 		thisptr->iConnections++;
   142 	    FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_SEMANTICS, RFBSSESSION_CONNECT2_INFO, "# Connected to existing session; this=0x%08x; iConnections=%d;", (TInt)thisptr, thisptr->iConnections);)
   143 		}
   144 	else
   145 	    {
   146         TInt ret = RFbsSession::DoAlloc(thisptr);
   147         if (ret!=KErrNone)
   148             {
   149             FBS_OST(OstTrace1(TRACE_ERROR, RFBSSESSION_CONNECT2_ERROR, "! DoAlloc returned %d", ret);)
   150             goto end;
   151             }
   152             
   153         ret = thisptr->iFileServer.Connect();
   154         if(ret!=KErrNone)
   155             {
   156             thisptr->Disconnect();
   157             FBS_OST(OstTraceExt2(TRACE_ERROR, RFBSSESSION_CONNECT2_ERROR2, "! this=0x%08x; RFs::Connect() returned %d", (TInt)thisptr, ret);)
   158             goto end;
   159             }
   160         
   161         ret = thisptr->DoConnect(thisptr->iFileServer);
   162         if(ret!=KErrNone)
   163             {
   164             FBS_OST(OstTraceExt2(TRACE_ERROR, RFBSSESSION_CONNECT2_ERROR3, "! this=0x%08x; DoConnect returned %d", (TInt)thisptr, ret);)
   165             }
   166 	    }
   167 end:
   168 	FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_CONNECT2_EXIT, "< this=0x%08x; ret=%d", (TUint)thisptr, ret);)
   169 	return ret;
   170 	}
   171 
   172 /** Closes the session with the Font and Bitmap server. 
   173 @publishedAll 
   174 @released
   175 */
   176 EXPORT_C void RFbsSession::Disconnect()
   177 	{
   178 	RFbsSession* thisptr=(RFbsSession*)Dll::Tls();
   179     FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_DISCONNECT_ENTRY, "> this=0x%08x;", (TUint)thisptr);)
   180 	if(thisptr)
   181 	    {
   182         TInt tempServerSessionHandle = thisptr->ServerSessionHandle();
   183         if(thisptr->iConnections>0)
   184             {
   185             thisptr->iCallBack.iPtr=NULL;
   186             thisptr->iCallBack.CallBack();
   187             // Destructor of CFbsSessionHelper may call SendCommand to cancel an
   188             // outstanding request, therefore destruction must be done before
   189             // iConnections is 0 to avoid an assertion going off.
   190             if(thisptr->iConnections==1)
   191                 {
   192                 delete thisptr->iHelper;
   193                 }
   194             thisptr->iConnections--;
   195             }
   196         if(thisptr->iConnections==0)
   197             {
   198             thisptr->iSharedChunk.Close();
   199             thisptr->iLargeBitmapChunk.Close();
   200             // Call close on the iFileServer regardless of whether this session owns it: 
   201             // if we don't own it, close will do nothing if there are still open files, 
   202             // so always calling close introduces extra safety
   203             thisptr->iFileServer.Close();
   204             delete thisptr->iRomFileAddrCache; 
   205             delete thisptr->iScanLineBuffer;
   206             delete thisptr->iDecompressionBuffer;
   207             thisptr->Close();
   208             delete thisptr;
   209             Dll::FreeTls();	
   210             }
   211         FBS_OST(OstTraceExt3(GRAPHICS_CONTROL_SEMANTICS, RFBSSESSION_DISCONNECT_INFO, "# Disconnected from session; this=0x%08x; iConnections=%d; iSSH=0x%08x", (TInt)thisptr, thisptr->iConnections, tempServerSessionHandle);)
   212 	    }
   213 	FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_DISCONNECT_EXIT2, "< this=0x%08x;", (TUint)thisptr);)
   214 	}
   215 
   216 /**  Gets the current Font and Bitmap server session.
   217 @return  A pointer to the current session or NULL if Connect() has not been 
   218 called yet. 
   219 @publishedAll 
   220 @released
   221 */
   222 EXPORT_C RFbsSession* RFbsSession::GetSession()
   223     {
   224 	return((RFbsSession*)Dll::Tls());
   225 	}
   226 
   227 /** Triggers the most recently registered callback. This is mainly called by 
   228 bitmaps when their twips size changes and when any FBSERV objects are closed 
   229 to notify clients of a change that may affect their operation. 
   230 @publishedAll 
   231 @released
   232 */
   233 EXPORT_C void RFbsSession::CallBack()
   234     {
   235 	iCallBack.CallBack();
   236 	iCallBack.iPtr=NULL;
   237 	}
   238 
   239 void RFbsSession::SetCallBackPtr(TInt* aBitmapHandle)const
   240 	{
   241 	iCallBack.iPtr=aBitmapHandle;
   242 	}
   243 	
   244 /** Sets the callback.
   245 @param aCallBack callback object to be called by CallBack(). Only one may be 
   246 in use at a time and subsequent calls will displace previous calls. 
   247 @publishedAll 
   248 @released
   249 */	
   250 EXPORT_C void RFbsSession::SetCallBack(TCallBack aCallBack)
   251     {
   252 	iCallBack=aCallBack;
   253 	}
   254 
   255 /** Resets the callback. 
   256 @publishedAll 
   257 @released
   258 */	
   259 EXPORT_C void RFbsSession::ResetCallBack()
   260 	{
   261 	TCallBack cb(NULL);
   262 	iCallBack=cb;
   263 	}
   264 
   265 /**  Returns the number of Font and Bitmap Server objects currently in 
   266 use by this session.
   267 @return The number of resources in use: bitmaps, fonts, typeface stores. 
   268 @publishedAll 
   269 @released
   270 */	
   271 EXPORT_C TInt RFbsSession::ResourceCount()
   272     {
   273 	return(SendCommand(EFbsMessResourceCount));
   274 	}
   275 
   276 /** Utility function for passing commands to the server.
   277 @param aMessage Integer code for the message to pass - see TFbsMessage.
   278 @param aInt0 Parameter 0 for the message.
   279 @param aInt1 Parameter 1 for the message.
   280 @param aInt2 Parameter 2 for the message.
   281 @param aInt3 Parameter 3 for the message.
   282 @return Return code from RSessionBase::SendReceive(). 
   283 @internalComponent
   284 */
   285 EXPORT_C TInt RFbsSession::SendCommand(TInt aMessage,TInt aInt0,TInt aInt1,TInt aInt2,TInt aInt3) const
   286    {
   287 	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
   288 
   289 	switch(aMessage)
   290 		{
   291 	case EFbsMessShutdown:
   292 	case EFbsMessClose:
   293 		SetCallBackPtr(aMessage==EFbsMessClose ? &aInt1 : 0);
   294 		iCallBack.CallBack();
   295 	default:
   296 		break;
   297 		}
   298 
   299 	TInt ret = SendReceive(aMessage, TIpcArgs(aInt0,aInt1,aInt2,aInt3));
   300 
   301 	return(ret);
   302 	}
   303 
   304 TInt RFbsSession::SendCommand(TInt aMessage, const TIpcArgs& aArgs) const
   305 	{
   306 	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
   307 	return SendReceive(aMessage,aArgs);
   308 	}
   309 
   310 void RFbsSession::SendCommand(TInt aMessage, const TIpcArgs& aArgs, TRequestStatus &aStatus) const
   311 	{
   312 	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
   313 	SendReceive(aMessage,aArgs,aStatus);
   314 	}
   315 	
   316 /** Gets the current Font and Bitmap server version.
   317 @return The current version of the server. 
   318 @publishedAll 
   319 @released
   320 */
   321 EXPORT_C TVersion RFbsSession::Version()
   322 	{
   323 	TVersion v(KFbsMajorVersionNumber,KFbsMinorVersionNumber,KFbsBuildVersionNumber);
   324 	return(v);
   325 	}
   326 
   327 /** Gets the address of first location in the global shared heap containing 
   328 fonts and bitmaps.
   329 @return Pointer to the base of the shared heap. 
   330 @publishedAll 
   331 @released
   332 */	
   333 EXPORT_C TUint8* RFbsSession::HeapBase() const
   334 	{
   335 	return(iSharedChunk.Base());
   336 	}
   337 
   338 TBool RFbsSession::LookupBitmapInROM(const TDesC& aFilename, TAny*& aAddr)
   339 	{
   340 	aAddr = iRomFileAddrCache->Lookup(aFilename);
   341 	if (aAddr)
   342 		return ETrue;
   343 	return EFalse;
   344    	}
   345 
   346 TInt RFbsSession::DoAlloc(RFbsSession*& aNewSession)
   347 	{
   348 	aNewSession = (RFbsSession*)User::Alloc(sizeof(RFbsSession));
   349 	if(!aNewSession) 
   350 		return KErrNoMemory;
   351 	new(aNewSession) RFbsSession;
   352 	aNewSession->iConnections = 1;
   353 	TInt ret = Dll::SetTls(aNewSession);
   354 	if(ret!=KErrNone)
   355 		{
   356 		delete aNewSession;
   357 		aNewSession = NULL;
   358 		}
   359 	return ret;
   360 	}
   361 
   362 /**  
   363 Do actual connect as common to both Connect() and Connect(RFs& aFileServer). Store fully constructed
   364 file server session to iSpare member variable
   365 @see Connect()
   366 @return KErrNone, if successful; KErrNoMemory if there is not enough memory 
   367 to create the session; otherwise another of the system-wide error codes. 
   368 @internalComponent
   369 */
   370 TInt RFbsSession::DoConnect(RFs& aFileServer)
   371 	{
   372 	//Allow this session to be accessed by other process to lead bitmap in server
   373 	TInt ret = aFileServer.ShareProtected();
   374 	if (ret!=KErrNone)
   375 		{
   376 		Disconnect();
   377 		return ret;
   378 		}
   379 	iRomFileAddrCache = CFbsRalCache::New(4, aFileServer);
   380 	if (!iRomFileAddrCache)
   381 		{
   382 		Disconnect();
   383 		return KErrNoMemory;
   384 		}
   385 
   386 	ret = CreateSession(KFBSERVGlobalThreadName,Version(),-1);
   387 	if(ret!=KErrNone)
   388 		{
   389 		Disconnect();
   390 		return ret;
   391 		}
   392 	const TInt serverAssignedHandle = SendReceive(EFbsMessInit);
   393 	if(serverAssignedHandle <= 0)
   394 		{
   395 		Disconnect();
   396 		return serverAssignedHandle;
   397 		}
   398 	ret = iSharedChunk.OpenGlobal(KFBSERVSharedChunkName,EFalse);
   399 	if(ret!=KErrNone) 
   400 		Panic(EFbsPanicChunkError);
   401 	iHelper = new CFbsSessionHelper(*this);
   402 	if (!iHelper)
   403 		{
   404 		Disconnect();
   405 		return KErrNoMemory;
   406 		}
   407 	iHelper->iServerSessionHandle = serverAssignedHandle;
   408 	
   409 	ret = iLargeBitmapChunk.OpenGlobal(KFBSERVLargeChunkName,EFalse);
   410 	if(ret!=KErrNone) 
   411 		Panic(EFbsPanicChunkError);
   412 	
   413 	iSpare = (TUint32*)&aFileServer;
   414 	
   415     FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_SEMANTICS, RFBSSESSION_DOCONNECT_INFO, "# New FBS Session created; this=0x%08x; iSSH=0x%08x;", (TInt)this, serverAssignedHandle);)
   416 	return KErrNone;
   417 	}
   418 	
   419 /**  
   420 Allocates the buffer for decoding compressed rom bitmaps.
   421  
   422 Internal use only.
   423 
   424 @param 	aSize Minimum size of the buffer required.  
   425 		If the buffer is too small an attempt to resize it will be made.
   426 @return KErrNone if successful, 
   427 		KErrNoMemory if the buffer was too small and could 
   428 		not be expanded.
   429 @publishedAll 
   430 @released
   431 */
   432 TInt RFbsSession::AllocScanLineBuffer(TInt aSize)
   433     {
   434 	if (iScanLineBuffer && iScanLineBuffer->Des().MaxSize() >= aSize)
   435 		{
   436 		return KErrNone;
   437 		}
   438 
   439 	HBufC8* newBuffer = HBufC8::New(aSize);
   440 
   441 	if (newBuffer)
   442 		{
   443 		delete iScanLineBuffer;
   444 		iScanLineBuffer = newBuffer;
   445 		return KErrNone;
   446 		}
   447 
   448 	return KErrNoMemory;
   449 	}
   450 
   451 /**  
   452 Gets a reference to the buffer currently in use for decoding
   453 compressed rom bitmaps. 
   454 
   455 Internal use only.
   456 
   457 @return  The buffer area currently in use,
   458 @publishedAll 
   459 @released
   460 */
   461 HBufC8* RFbsSession::GetScanLineBuffer()
   462     {
   463 	return iScanLineBuffer;
   464 	}
   465 
   466 /**  
   467 Gets a pointer to the buffer currently in use for decoding
   468 compressed mask bitmaps. 
   469 
   470 Internal use only.
   471 @param 	aSize Minimum size of the buffer required.  
   472 		If the buffer is too small an attempt to resize it will be made.
   473 @return  The buffer area currently in use or NULL if there is no memory.
   474 @internalComponent 
   475 */
   476 HBufC8* RFbsSession::GetDecompressionBuffer(TInt aSize)
   477 	{
   478 	if (iDecompressionBuffer)
   479 		{
   480 		if (iDecompressionBuffer->Des().MaxSize() < aSize)
   481 			{
   482 			HBufC8* tempBuffer = iDecompressionBuffer->ReAlloc(aSize);
   483 			if (!tempBuffer)
   484 				{
   485 				return NULL;
   486 				}
   487 			iDecompressionBuffer = tempBuffer;
   488 			}
   489 		}
   490 	else
   491 		{
   492 		iDecompressionBuffer = HBufC8::New(aSize);
   493 		}
   494 
   495 	return iDecompressionBuffer;
   496 	}
   497 
   498 /**  
   499 Gets a pointer to an extra buffer for general use. 
   500 
   501 Internal use only.
   502 @param 	aSize Minimum size of the buffer required.  
   503 		If the buffer is too small an attempt to resize it will be made.
   504 @return  The buffer area currently in use or NULL if there is no memory.
   505 @internalComponent 
   506 */
   507 HBufC8* RFbsSession::GetExtraBuffer(TInt aSize)
   508 	{
   509 	if (iHelper->iExtraBuffer)
   510 		{
   511 		if (iHelper->iExtraBuffer->Des().MaxSize() < aSize)
   512 			{
   513 			HBufC8* tempBuffer = iHelper->iExtraBuffer->ReAlloc(aSize);
   514 			if (!tempBuffer)
   515 				{
   516 				return NULL;
   517 				}
   518 			iHelper->iExtraBuffer = tempBuffer;
   519 			}
   520 		}
   521 	else
   522 		{
   523 		iHelper->iExtraBuffer = HBufC8::New(aSize);
   524 		}
   525 
   526 	return iHelper->iExtraBuffer;
   527 	}
   528 
   529 /**
   530 Returns a handle assigned to this session by the server upon connection.
   531 This method should be used instead of SessionHandle() when passing a session 
   532 handle to FbServ APIs that require Session handles. 
   533 @return A handle representing this session on the server. 
   534 @pre The session has successfully connected to the server.
   535  */
   536 TInt RFbsSession::ServerSessionHandle() const
   537 	{
   538 	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
   539 	return iHelper->iServerSessionHandle;
   540 	}
   541 
   542 EXPORT_C TInt RFbsSession::GetGlyphCacheMetrics( TGlyphCacheMetrics& aGlyphCacheMetrics )
   543     {
   544     TPckgBuf<TGlyphCacheMetrics> metrics;
   545     TIpcArgs args( &metrics );
   546 
   547     TInt ret = SendReceive( EFbsMessGetGlyphCacheMetrics, args );
   548     aGlyphCacheMetrics = metrics();
   549 
   550     return ret;
   551     }
   552 
   553 /**
   554  Perform the IPC to convey the desired OoGM action to the glyph atlas.
   555 
   556  @return KErrNone if IPC was successful. One of the system-wide error
   557          codes, as described for RSessionBase::SendReceive(), if not.
   558 
   559  @note The server-side platform security policy applied to this method is such that it is only useable by the GOoM framework.
   560 
   561  @param aOogmMessage. A reference to the class encapsulating the OoGM action required of the glyph atlas.
   562 */
   563 EXPORT_C TInt RFbsSession::ConveyOogmMessage( TFbsOogmMessage& aOogmMessage )
   564     {
   565     TPckgBuf<TFbsOogmMessage> oogmMessage;
   566     oogmMessage() = aOogmMessage;
   567     TIpcArgs args( &oogmMessage );
   568 
   569     return SendReceive( EFbsMessOogmNotification, args );
   570     }
   571 
   572 /**
   573 Returns the current sizes of the FBServ default heap, the heap for large bitmaps, 
   574 and the heap for small bitmaps.
   575 
   576 Not supported in release builds.
   577 
   578 @internalComponent
   579 @test
   580 @param aDefaultHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ default heap.
   581 @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
   582 @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
   583 @return KErrNone or one of the system wide error codes in debug mode, or KErrNotSupported in release mode.
   584 */
   585 #ifdef _DEBUG
   586 EXPORT_C TInt RFbsSession::GetHeapSizes(TInt& aDefaultHeapSize, TInt& aSmallBmpHeapSize, TInt& aBigBmpHeapSize)
   587  	{
   588  	TPckgBuf<THeapSizes> data;
   589  	TIpcArgs args(&data);
   590  	TInt ret = SendReceive(EFbsMessGetHeapSizes, args);
   591  	if(ret == KErrNone)
   592  		{
   593  		aDefaultHeapSize = data().iDefault;
   594  		aSmallBmpHeapSize = data().iSmall;
   595  		aBigBmpHeapSize = data().iBig;
   596  		}
   597  	return ret;
   598  	}
   599 #else
   600 EXPORT_C TInt RFbsSession::GetHeapSizes(TInt&, TInt&, TInt&)
   601 	{
   602 	return KErrNotSupported;
   603 	}
   604 #endif