fbs/fontandbitmapserver/sfbs/FBSCLI.CPP
changeset 0 5d03bc08d59c
child 26 15986eb6c500
child 36 01a6848ebfd7
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 <fntstore.h>
       
    17 #include <bitmap.h>
       
    18 #include <openfont.h>
       
    19 #include "fbsmessage.h"
       
    20 #include "SERVER.H"
       
    21 #include "BackGroundCompression.h"
       
    22 #include <shapeinfo.h>
       
    23 #include <graphics/shaperparams.h>
       
    24 
       
    25 /** Helper function for converting a pointer to an offset from the passed
       
    26 heap base. Use OffsetToPointer() to convert the returned offset back to a
       
    27 useable pointer.
       
    28 @param aAny A pointer to be converted to an offset.
       
    29 @param aHeapBase The heap base of the current process.
       
    30 @return An offset representing the passed pointer that can be converted
       
    31 back to a pointer using the function OffsetToPointer(). 
       
    32 @see OffsetToPointer()
       
    33  */
       
    34 LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
       
    35 	{
       
    36 	if (aAny && aHeapBase)
       
    37 		{
       
    38 		return (TInt)aAny - (TInt)aHeapBase;
       
    39 		}
       
    40 	return 0;
       
    41 	}
       
    42 
       
    43 /** Helper function for converting an offset (that was calculated using
       
    44 PointerToOffset()) back to a pointer relative to the passed heap base.
       
    45 @param aOffset The offset to be converted to a pointer.
       
    46 @param aHeapBase The heap base of the current process.
       
    47 @return A pointer relative to the passed heap base.
       
    48 @see PointerToOffset()
       
    49  */
       
    50 LOCAL_C TAny* OffsetToPointer(const TInt aOffset, TInt aHeapBase)
       
    51 	{
       
    52 	if (aOffset && aHeapBase)
       
    53 		{
       
    54 		return (TAny*)(aOffset + (TInt)aHeapBase);
       
    55 		}
       
    56 	return NULL;
       
    57 	}
       
    58 
       
    59 CFbClient::CFbClient(RHeap* aHeap):
       
    60 	CSession2(),
       
    61 	iConnectionHandle(0),
       
    62 	iIx(NULL),
       
    63 	iResourceCount(0),
       
    64 	iHeap(aHeap)
       
    65 #ifdef _DEBUG
       
    66 	,iOwnHeapFailNumber(-1),
       
    67 	iSharedHeapFailNumber(-1)
       
    68 #endif	
       
    69 	{
       
    70 	}
       
    71 
       
    72 CFbClient* CFbClient::NewL(RHeap* aHeap)
       
    73 	{
       
    74 	CFbClient* c = new(ELeave) CFbClient(aHeap);
       
    75 	c->iOpenFontGlyphData = TOpenFontGlyphData::New(aHeap,4 * 1024);
       
    76 	if (!c->iOpenFontGlyphData)
       
    77 		{
       
    78 		delete c;
       
    79 		User::Leave(KErrNoMemory);
       
    80 		}
       
    81 	return c;
       
    82 	}
       
    83 
       
    84 CFbClient::~CFbClient()
       
    85 	{
       
    86 	/*
       
    87 	Don't call any CFontStore functions if CFbClient::NewL has left, or if FBSERV has already deleted the
       
    88 	font store, which happens in test programs like TFBS when FBSERV is closed before the client(s).
       
    89 	*/
       
    90 	CFontStore* font_store = NULL;
       
    91 	CFbTop* fbTop = TopLevelStore();
       
    92 	if (fbTop)
       
    93 		{
       
    94 		font_store = fbTop->FontStore();
       
    95 		}
       
    96 	
       
    97 	if (font_store)
       
    98 		font_store->DeleteSessionCache(iSessionHandle);
       
    99 	
       
   100 	// If the font store doesn't exist, neither will the shared heap owned by FBSERV.
       
   101 	if (font_store)
       
   102 		iHeap->Free(iOpenFontGlyphData);
       
   103 	
       
   104 	// delete fonts hold by the client
       
   105 	delete iIx;
       
   106 	
       
   107 	// delete font files hold by the client
       
   108     if (iFontFileIndex)
       
   109         {
       
   110         TInt count = iFontFileIndex->Count();
       
   111         for (TInt index = 0;index < count; index++)
       
   112             {
       
   113             if (font_store)
       
   114                 font_store->RemoveFile(iFontFileIndex->At(0).iUid);
       
   115             iFontFileIndex->Delete(0);
       
   116             }
       
   117         delete iFontFileIndex;
       
   118         }
       
   119 
       
   120 	// Close the buffer used to hold the text thats needs shaping.
       
   121 	iTextToShape.Close();
       
   122 	}
       
   123 
       
   124 void CFbClient::Init(TUint aConnectionHandle)
       
   125 	{
       
   126 	iConnectionHandle=aConnectionHandle;
       
   127 	}
       
   128 
       
   129 void CFbClient::CreateL()
       
   130 	{
       
   131 	iIx=CObjectIx::NewL();
       
   132 	iFontFileIndex=new(ELeave) CArrayFixFlat<TFontFileIndex>(1);
       
   133 	}
       
   134 
       
   135 CFontBitmapServer* CFbClient::FontBitmapServer()
       
   136 	{
       
   137 	return((CFontBitmapServer*)Server());
       
   138 	}
       
   139 
       
   140 CFbTop* CFbClient::TopLevelStore()
       
   141 	{
       
   142 	CFontBitmapServer* server = FontBitmapServer();
       
   143 	if (server)
       
   144 		return server->TopLevelStore();
       
   145 	else
       
   146 		return NULL;
       
   147 	}
       
   148 
       
   149 void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
       
   150 	{
       
   151 	CBitmapFont* font=aFontObjPtr->iAddressPointer;
       
   152 	aFontInfo.iHandle = aHandle;
       
   153 	aFontInfo.iServerHandle=(TInt)aFontObjPtr;
       
   154 	aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
       
   155 	}
       
   156 
       
   157 void CFbClient::ServiceL(const RMessage2& aMessage)
       
   158 	{
       
   159 #ifdef _DEBUG
       
   160 	TBool resetOwnHeap=EFalse;
       
   161 	TBool resetSharedHeap=EFalse;
       
   162 	
       
   163 	//the memory tests have been mostly written to have start and end memory
       
   164 	//function calls (or macros) at the start of this function call (ServiceL)
       
   165 	//and the matching call (or macro) is at the end of this function.
       
   166 	
       
   167 	if (iOwnHeapFailNumber!=-1)
       
   168 		{
       
   169 		//if this not -1 then know to set the heap to fail on
       
   170 		//the given number of allocations
       
   171 		
       
   172 		resetOwnHeap=ETrue;
       
   173 		__UHEAP_SETFAIL(RHeap::EDeterministic,iOwnHeapFailNumber);
       
   174 		}
       
   175 	if (iSharedHeapFailNumber!=-1)
       
   176 		{
       
   177 		resetSharedHeap=ETrue;
       
   178 		__RHEAP_SETFAIL (iHeap, RHeap::EDeterministic,iSharedHeapFailNumber);
       
   179 		}	
       
   180 
       
   181 	if (iOwnHeapCheck)
       
   182 		{
       
   183 		__UHEAP_MARK;
       
   184 		}					
       
   185 	if (iHeapCheck)
       
   186 		{
       
   187 		__RHEAP_MARK(iHeap);
       
   188 		}		
       
   189 #endif		
       
   190 	
       
   191 	switch(aMessage.Function())
       
   192 		{
       
   193 // client messages
       
   194 	case EFbsMessInit:
       
   195 		Init(FontBitmapServer()->Init());
       
   196 		iSessionHandle = (TInt)this;
       
   197 		aMessage.Complete(iSessionHandle);
       
   198 #ifdef _DEBUG
       
   199 		iRet=KErrNone;
       
   200 #endif		
       
   201 		break;
       
   202 	case EFbsMessClose:
       
   203 		{
       
   204 		TInt localhandle=aMessage.Int0();
       
   205 		if(!iIx->At(localhandle))
       
   206 			{
       
   207 			aMessage.Panic(KFBSERVPanicCategory,KErrNotFound);
       
   208 			break;
       
   209 			}
       
   210 		iIx->Remove(localhandle);
       
   211 		iResourceCount--;
       
   212 		aMessage.Complete(KErrNone);
       
   213 #ifdef _DEBUG
       
   214 		iRet=KErrNone;
       
   215 #endif				
       
   216 		break;
       
   217 		}
       
   218 	case EFbsMessResourceCount:
       
   219 		aMessage.Complete(iResourceCount);
       
   220 #ifdef _DEBUG
       
   221 		iRet=iResourceCount;
       
   222 #endif			
       
   223 		break;
       
   224 // server messages
       
   225 	case EFbsMessShutdown:
       
   226 	case EFbsMessNumTypefaces:
       
   227 	case EFbsMessTypefaceSupport:
       
   228 	case EFbsMessFontHeightInTwips:
       
   229 	case EFbsMessFontHeightInPixels:
       
   230 	case EFbsMessSetPixelHeight:
       
   231 	case EFbsMessDefaultAllocFail:
       
   232 	case EFbsMessDefaultMark:
       
   233 	case EFbsMessDefaultMarkEnd:
       
   234 	case EFbsMessUserAllocFail:
       
   235 	case EFbsMessUserMark:
       
   236 	case EFbsMessUserMarkEnd:
       
   237 	case EFbsMessHeapCheck:
       
   238 	case EFbsMessSetDefaultGlyphBitmapType:
       
   239 	case EFbsMessGetDefaultGlyphBitmapType:
       
   240 	case EFbsMessFontNameAlias:
       
   241 	case EFbsMessGetHeapSizes:
       
   242 	case EFbsMessDefaultLanguageForMetrics:
       
   243 	case EFbsCompress:
       
   244 	case EFbsMessFetchLinkedTypeface:
       
   245 	case EFbsMessRegisterLinkedTypeface:
       
   246 	case EFbsMessUpdateLinkedTypeface:
       
   247 #ifdef _DEBUG
       
   248 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
       
   249 #else
       
   250 		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
       
   251 #endif			
       
   252 		break;
       
   253 // font messages
       
   254 	case EFbsMessFontDuplicate:
       
   255 	case EFbsMessGetNearestFontToDesignHeightInTwips:
       
   256 	case EFbsMessGetNearestFontToDesignHeightInPixels:
       
   257 	case EFbsMessGetNearestFontToMaxHeightInTwips:
       
   258 	case EFbsMessGetNearestFontToMaxHeightInPixels:
       
   259 	case EFbsMessGetFontById:
       
   260 	case EFbsMessInstallFontStoreFile:
       
   261 	case EFbsMessAddFontStoreFile:
       
   262 	case EFbsMessRemoveFontStoreFile:
       
   263 	case EFbsMessRasterize:
       
   264 	case EFbsMessFaceAttrib:
       
   265 	case EFbsMessHasCharacter:
       
   266 	case EFbsMessShapeText:
       
   267 	case EFbsMessShapeDelete:
       
   268 	case EFbsMessSetTwipsHeight:
       
   269 	case EFbsMessGetTwipsHeight:
       
   270 	case EFbsSetSystemDefaultTypefaceName:
       
   271 #if (_DEBUG)
       
   272 	case EFbsMessSetDuplicateFail:
       
   273 #endif
       
   274 		ProcFontMessage(aMessage);
       
   275 		break;
       
   276 // bitmap messages
       
   277 	case EFbsMessBitmapCreate:
       
   278 	case EFbsMessBitmapResize:
       
   279 	case EFbsMessBitmapDuplicate:
       
   280 	case EFbsMessBitmapLoad:
       
   281 	case EFbsMessBitmapCompress:
       
   282 	case EFbsMessBitmapBgCompress:
       
   283 	case EFbsMessBitmapClean:
       
   284 	case EFbsGetAllBitmapHandles:
       
   285 	case EFbsMessBitmapLoadFast:
       
   286 	case EFbsMessBitmapNotifyDirty:
       
   287 	case EFbsMessBitmapCancelNotifyDirty:
       
   288 		ProcBitmapMessage(aMessage);
       
   289 		break;
       
   290 //Memory messages		
       
   291 	case EFbsMessSetHeapFail:
       
   292 	case EFbsMessHeapCount:
       
   293 	case EFbsMessSetHeapReset:
       
   294 	case EFbsMessSetHeapCheck:
       
   295 	case EFbsMessHeap:
       
   296 #ifdef _DEBUG	
       
   297 		ProcMemMessage(aMessage);
       
   298 #else
       
   299 		aMessage.Complete(KErrNone);
       
   300 #endif	
       
   301 		break;
       
   302 	default:
       
   303 		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
       
   304 		break;
       
   305 		}
       
   306 #ifdef _DEBUG
       
   307 
       
   308 	//do not want a memory panic if the return code is OK
       
   309 	//__UHEAP_MARKEND does this
       
   310 	
       
   311 	if (iOwnHeapCheck)
       
   312 		{
       
   313 		TUint32 badCell=User::Heap().__DbgMarkEnd(0);
       
   314 		if (iRet<0)
       
   315 			{
       
   316 			//if the function call was a success, there may have been valid memory allocations,
       
   317 			//so only panic if the call failed, and the memory is not the same before and after the
       
   318 			//function call
       
   319 			__ASSERT_DEBUG (badCell==NULL,User::Panic(KFBSERVPanicCategory, KErrGeneral));
       
   320 			}
       
   321 		}					
       
   322 	if (iHeapCheck)
       
   323 		{
       
   324 		TUint32 badCell2=0;
       
   325 		badCell2= __RHEAP_MARKEND(iHeap);
       
   326 		//the above function call does not panic if there is a failure, this is
       
   327 		//only for the user heap
       
   328 		if (iRet<0)
       
   329 			{
       
   330 			__ASSERT_DEBUG (badCell2==NULL,User::Panic(KFBSERVPanicCategory, KErrGeneral));
       
   331 			}
       
   332 		}
       
   333 	//change the state of the memory check?	
       
   334 	if (iOwnHeapCheckFlip)
       
   335 		{
       
   336 		//change the state of the memory testing
       
   337 		//if the mark was set still need to have a mark end
       
   338 		iOwnHeapCheckFlip=EFalse;
       
   339 		iOwnHeapCheck=!iOwnHeapCheck;
       
   340 		}
       
   341 	if (iHeapCheckFlip)
       
   342 		{
       
   343 		iHeapCheckFlip=EFalse;
       
   344 		iHeapCheck=!iHeapCheck;
       
   345 		}
       
   346 		
       
   347 	if (resetOwnHeap)
       
   348 		{
       
   349 		//previously set failures, reset
       
   350 		__UHEAP_RESET;
       
   351 		}
       
   352 	if (resetSharedHeap)
       
   353 		{		
       
   354 		__RHEAP_RESET (iHeap);
       
   355 		}		
       
   356 #endif		
       
   357 	}
       
   358 
       
   359 
       
   360 /** Handler for EFbsMessFontDuplicate message
       
   361  @param aMessage input parameters
       
   362  @param aPanicRequired flag that is set if a client panic is required
       
   363  @return KErrNone if successful, otherwise a system wide error code
       
   364  */
       
   365 TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
       
   366 	{
       
   367 #if _DEBUG
       
   368 	if (iFontDuplicateToFail)
       
   369 		return KErrNoMemory; //return with this error since this error is possible
       
   370 #endif
       
   371 	CFontObject* fontptr = (CFontObject*) aMessage.Int0();
       
   372 	if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
       
   373 		{
       
   374 		return KErrUnknown;
       
   375 		}
       
   376 
       
   377 	TPckgBuf<TFontInfo> foninfo;
       
   378 	TInt localhandle = 0;
       
   379 	TInt ret = fontptr->Open();
       
   380 	if (ret != KErrNone)
       
   381 		{
       
   382 		return ret;
       
   383 		}
       
   384 	TRAP(ret, localhandle=iIx->AddL(fontptr));
       
   385 	if (ret != KErrNone)
       
   386 		{
       
   387 		fontptr->Close();
       
   388 		return ret;
       
   389 		}
       
   390 	CopyFontInfo(fontptr,localhandle,foninfo());
       
   391 	fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
       
   392 	ret = aMessage.Write(1, foninfo);
       
   393 	if(ret != KErrNone)
       
   394 		{
       
   395 		iIx->Remove(localhandle);
       
   396 		aPanicRequired = ETrue;
       
   397 		return ret;
       
   398 		}
       
   399 
       
   400 	// success
       
   401 	iResourceCount++;
       
   402 	return KErrNone;
       
   403 	}
       
   404 
       
   405 
       
   406 /** Handler for EFbsMessGetNearestFontToDesignHeightInTwips, EFbsMessGetNearestFontToDesignHeightInPixels, 
       
   407  EFbsMessGetNearestFontToMaxHeightInTwips or EFbsMessGetNearestFontToMaxHeightInPixels messages
       
   408  @param aMessage input and output parameters
       
   409  @param aPanicRequired flag that is set if a client panic is required
       
   410  @return KErrNone if successful, otherwise a system wide error code
       
   411  */
       
   412 TInt CFbClient::HandleMesgGetNearestFont(const RMessage2& aMessage, TBool& aPanicRequired)
       
   413 	{
       
   414 	CFontObject* fontptr = NULL;
       
   415 	TPckgBuf<TFontSpec> pckgFontSpec;
       
   416 	TInt pckgMaxHeight;
       
   417 	TPckgBuf<TSizeInfo> info;
       
   418 
       
   419 	const TFbsMessage	fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
       
   420 
       
   421 	TInt ret = aMessage.Read(0, pckgFontSpec);
       
   422 	TFontSpec& fontSpec = pckgFontSpec();
       
   423 	if (ret == KErrNone )
       
   424 		{
       
   425 		TInt length = fontSpec.iTypeface.iName.Length();
       
   426 		if(length < 0 || length > TOpenFontFaceAttribBase::ENameLength)
       
   427 			{
       
   428 			aPanicRequired = ETrue;
       
   429 			return KErrArgument;
       
   430 			}	
       
   431 		
       
   432 		ret = aMessage.Read(2, info);
       
   433 		if (ret == KErrNone)
       
   434 			{
       
   435 			pckgMaxHeight = info().iMaxHeight;
       
   436 			TopLevelStore()->FontStore()->iKPixelHeightInTwips=info().iDevSize.iHeight;
       
   437 			TopLevelStore()->FontStore()->iKPixelWidthInTwips=info().iDevSize.iWidth;
       
   438 			}
       
   439 		}
       
   440 
       
   441 	if (KErrNone != ret)
       
   442 		{
       
   443 		aPanicRequired = ETrue;
       
   444 		return ret;
       
   445 		}
       
   446 	if ( (EFbsMessGetNearestFontToMaxHeightInTwips == fbsMessage) || (EFbsMessGetNearestFontToMaxHeightInPixels == fbsMessage) )
       
   447 		{
       
   448 		ret = TopLevelStore()->GetNearestFont(fontptr, fbsMessage, fontSpec, pckgMaxHeight);
       
   449 		}
       
   450 	else
       
   451 		{
       
   452 		ret = TopLevelStore()->GetNearestFont(fontptr, fbsMessage, fontSpec);
       
   453 		}
       
   454 
       
   455 	if (ret == KErrNone)
       
   456 		{ // package up the result
       
   457 		ret = CopyFontInfoIntoReturnMessage(aMessage, aPanicRequired, fontptr, 1);
       
   458 		}
       
   459 
       
   460 	return ret;
       
   461 	}
       
   462 
       
   463 
       
   464  /** package up the font that was found - includes cleanup handling in case of error
       
   465  @param aMessage input and output parameters
       
   466  @param aPanicRequired flag that is set if a client panic is required
       
   467  @param aFontObj the object that is to be returned
       
   468  @param aWritePosition the slot position in the message pointing to the receiving object
       
   469  @return KErrNone if successful, otherwise a system wide error code
       
   470  */
       
   471 TInt CFbClient::CopyFontInfoIntoReturnMessage(const RMessage2& aMessage, TBool& aPanicRequired, CFontObject* aFontObj, TInt aWritePosition)
       
   472 	{
       
   473 	TInt localhandle = 0;
       
   474 	TRAPD(ret, localhandle = iIx->AddL(aFontObj));
       
   475 	if (KErrNone != ret)
       
   476 		{
       
   477 		aFontObj->Close();
       
   478 		return ret;
       
   479 		}
       
   480 	TPckgBuf<TFontInfo> pckgFontInfo;
       
   481 	CopyFontInfo(aFontObj, localhandle, pckgFontInfo());
       
   482 	ret = aMessage.Write(aWritePosition, pckgFontInfo);
       
   483 	if (KErrNone != ret)
       
   484 		{
       
   485 		iIx->Remove(localhandle);
       
   486 		aPanicRequired = ETrue;
       
   487 		return ret;
       
   488 		}
       
   489 	// success
       
   490 	iResourceCount++;
       
   491 	return KErrNone;
       
   492 	}
       
   493 
       
   494 
       
   495 /** Handler for EFbsMessGetFontById message
       
   496  Works for Bitmap fonts only, see implementation in CFbTop::GetFontById() & CFontStore::GetFontById().
       
   497  @param aMessage input and output parameters
       
   498  @param aPanicRequired flag that is set if a client panic is required
       
   499  @return KErrNone if successful, otherwise a system wide error code
       
   500  */
       
   501 TInt CFbClient::HandleMesgGetFontById(const RMessage2& aMessage, TBool& aPanicRequired)
       
   502 	{
       
   503 	CFontObject* fontptr = NULL;
       
   504 	TPckgBuf<TAlgStyle> algstyle;
       
   505 	TPckgBuf<TSize> size;
       
   506 
       
   507 	TInt ret = aMessage.Read(1, algstyle);
       
   508 	if (ret == KErrNone)
       
   509 		{ // get font size
       
   510 		ret = aMessage.Read(3, size);
       
   511 		if (ret == KErrNone)
       
   512 			{
       
   513 			TopLevelStore()->FontStore()->iKPixelHeightInTwips = size().iHeight;
       
   514 			TopLevelStore()->FontStore()->iKPixelWidthInTwips = size().iWidth;
       
   515 			}
       
   516 		}
       
   517 	if (ret != KErrNone)
       
   518 		{
       
   519 		aPanicRequired = ETrue;
       
   520 		return ret;
       
   521 		}
       
   522 	TUid fileid;
       
   523 	fileid.iUid = aMessage.Int2();
       
   524 	ret = TopLevelStore()->GetFontById(fontptr,fileid,algstyle());
       
   525 
       
   526 	if (ret == KErrNone)
       
   527 		{ // package up the result
       
   528 		ret = CopyFontInfoIntoReturnMessage(aMessage, aPanicRequired, fontptr, 0);
       
   529 		}
       
   530 
       
   531 	return ret;
       
   532 	}
       
   533 
       
   534 
       
   535 /** Handler for EFbsMessInstallFontStoreFile or EFbsMessAddFontStoreFile messages
       
   536  @param aMessage input and output parameters
       
   537  @param aPanicRequired flag that is set if a client panic is required
       
   538  @return KErrNone if successful, otherwise a system wide error code
       
   539  */
       
   540 TInt CFbClient::HandleMesgAddOrInstallFontFile(const RMessage2& aMessage, TBool& aPanicRequired)
       
   541 	{
       
   542 	TPckgBuf<TIntParcel> id;
       
   543 	TInt length=aMessage.Int1();
       
   544 	
       
   545 	if(length < 0 || length * sizeof(TText) >= KMaxTInt/2)
       
   546 		{
       
   547 		aPanicRequired = ETrue;
       
   548 		return KErrArgument;
       
   549 		}
       
   550 	
       
   551 	TText* buffer=(TText*)User::Alloc(length*sizeof(TText));
       
   552 	if(buffer==NULL)
       
   553 		{
       
   554 		return KErrNoMemory;
       
   555 		}
       
   556 	TPtr filename(buffer,length,length);
       
   557 	TInt ret = aMessage.Read(0,filename);
       
   558 	if(ret!=KErrNone)
       
   559 		{
       
   560 		User::Free(buffer);
       
   561 		aPanicRequired = ETrue;
       
   562 		return ret;
       
   563 		}
       
   564 	TRAP(ret, id().iInt = TopLevelStore()->FontStore()->AddFileL(filename).iUid);
       
   565 	User::Free(buffer);
       
   566 	if (ret != KErrNone)
       
   567 		{
       
   568 		return ret;
       
   569 		}
       
   570 	TUid uid;
       
   571 	uid.iUid=id().iInt;
       
   572 	if (aMessage.Function() == EFbsMessAddFontStoreFile)
       
   573 		{
       
   574 		TRAP(ret, AddFontFileIndexL(uid));
       
   575 		if (ret!=KErrNone)
       
   576 			{
       
   577 			TopLevelStore()->FontStore()->RemoveFile(uid);
       
   578 			return ret;
       
   579 			}
       
   580 		}
       
   581 	ret = aMessage.Write(2,id);
       
   582 	if (ret!=KErrNone)
       
   583 		{
       
   584 		RemoveFontFileIndex(uid);
       
   585 		aPanicRequired = ETrue;
       
   586 		}
       
   587 	return ret;
       
   588 	}
       
   589 
       
   590 
       
   591 /** Handler for EFbsMessRemoveFontStoreFile message
       
   592  @param aMessage input parameters
       
   593  @return KErrNone if successful
       
   594  */
       
   595 TInt CFbClient::HandleMesgRemoveFontFile(const RMessage2& aMessage)
       
   596 	{
       
   597 	TUid uid;
       
   598 	uid.iUid=aMessage.Int0();
       
   599 	RemoveFontFileIndex(uid);
       
   600 	return KErrNone;
       
   601 	}
       
   602 
       
   603 
       
   604 /** Handler for EFbsMessRasterize message
       
   605  @param aMessage input parameters
       
   606  @param aPanicRequired flag that is set if a client panic is required
       
   607  @return ETrue if successful, EFalse or any system-wide error code if not successful.
       
   608  */
       
   609 TInt CFbClient::HandleMesgRasterize(const RMessage2& aMessage, TBool& aPanicRequired)
       
   610 	{
       
   611 	CFbTop* fbtop = TopLevelStore();
       
   612 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
       
   613 	if(!fontptr)
       
   614 		{
       
   615 		aPanicRequired = ETrue;
       
   616 		return KErrArgument;
       
   617 		}
       
   618 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
   619 	const TUint charCode = aMessage.Int1();
       
   620 
       
   621 	if ( (bitmapFont != NULL) && (bitmapFont->Rasterize(iSessionHandle, charCode, iOpenFontGlyphData)) )
       
   622 		{
       
   623 		// Convert all pointers to be passed back to the client to offsets from
       
   624 		// the heap base so that they can be recreated client side relative to the
       
   625 		// client's heap base
       
   626 		TInt heapbase = fbtop->HeapBase();
       
   627 		TPckgBuf<TRasterizeParams> params;
       
   628 		params().iMetricsOffset = PointerToOffset(iOpenFontGlyphData->Metrics(), heapbase);
       
   629 		params().iBitmapPointerOffset = PointerToOffset(iOpenFontGlyphData->BitmapPointer(), heapbase);;
       
   630 		TInt err = aMessage.Write(2, params);
       
   631 		if (KErrNone != err)
       
   632 			{
       
   633 			aPanicRequired = ETrue;
       
   634 			return err;
       
   635 			}
       
   636 		return ETrue;
       
   637 		}
       
   638 	return EFalse;
       
   639 	}
       
   640 
       
   641 
       
   642 /** Handler for EFbsMessFaceAttrib message
       
   643  @param aMessage Input and output parameters
       
   644  @param aPanicRequired Flag that is set to ETrue if a client panic is required
       
   645  @return ETrue if successful, EFalse or any system-wide error code if not successful.
       
   646 	 An error code is only returned if aPanicRequired is set to ETrue.
       
   647  */
       
   648 TInt CFbClient::HandleMesgFaceAttrib(const RMessage2& aMessage, TBool& aPanicRequired)
       
   649 	{
       
   650 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), TopLevelStore()->FontConUniqueID()));
       
   651 	if(!fontptr)
       
   652 		{
       
   653 		aPanicRequired = ETrue;
       
   654 		return KErrArgument;
       
   655 		}
       
   656 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
   657 
       
   658 	TPckgBuf<TOpenFontFaceAttrib> package;
       
   659 	if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
       
   660 		{
       
   661 		TInt ret = aMessage.Write(1,package);
       
   662 		if (ret == KErrNone)
       
   663 			{
       
   664 			return ETrue;
       
   665 			}
       
   666 		else
       
   667 			{
       
   668 			aPanicRequired = ETrue;
       
   669 			return ret;
       
   670 			}
       
   671 		}
       
   672 	return EFalse;
       
   673 	}
       
   674 
       
   675 
       
   676 /** Handler for EFbsMessHasCharacter message
       
   677  @param aMessage Input parameters
       
   678  @param aPanicRequired Flag that is set to ETrue if a client panic is required
       
   679  @return ETrue if the font has the character, EFalse if the font does not have
       
   680   the character, or any system-wide error code if not successful. An error code
       
   681   is only returned if aPanicRequired is set to ETrue.
       
   682  */
       
   683 TInt CFbClient::HandleMesgHasCharacter(const RMessage2& aMessage, TBool& aPanicRequired)
       
   684 	{
       
   685 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), TopLevelStore()->FontConUniqueID()));
       
   686 	if(!fontptr)
       
   687 		{
       
   688 		aPanicRequired = ETrue;
       
   689 		return KErrArgument;
       
   690 		}
       
   691 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
   692 
       
   693 	TInt ret = 0;
       
   694 	TRAPD(error, ret = bitmapFont->HasCharacterL(aMessage.Int1()));
       
   695 	if (error != KErrNone)
       
   696 		{
       
   697 		return EFalse;
       
   698 		}
       
   699 	return ret;
       
   700 	}
       
   701 
       
   702 
       
   703 /** Handler for EFbsMessShapeText message
       
   704  @param aMessage Input and output parameters
       
   705  @param aPanicRequired Flag that is set to ETrue if a client panic is required
       
   706  @return An offset from the heap base where the pointer to the shape is located
       
   707 	if successful, otherwise 0 or any system-wide error code. An error code is
       
   708 	only returned if aPanicRequired is set to ETrue.
       
   709  */
       
   710 TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
       
   711 	{
       
   712 	TInt error = KErrNone;
       
   713 	TShapeHeader* shape = 0;
       
   714 	TPckgBuf<TShapeMessageParameters> sp;
       
   715 	if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
       
   716 		{
       
   717 		aPanicRequired = ETrue;
       
   718 		return KErrArgument;
       
   719 		}
       
   720 
       
   721 	CFbTop* fbtop = TopLevelStore();
       
   722 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
       
   723 	if(!fontptr)
       
   724 		{
       
   725 		aPanicRequired = ETrue;
       
   726 		return KErrArgument;
       
   727 		}
       
   728 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
   729 
       
   730 	TInt inputTextLength = aMessage.GetDesLength(1);
       
   731 	if (inputTextLength < 0)
       
   732 		{
       
   733 		error = inputTextLength;
       
   734 		aPanicRequired = ETrue;
       
   735 		return error;
       
   736 		}
       
   737 	else
       
   738 		{
       
   739 		iTextToShape.Zero();
       
   740 		if (iTextToShape.MaxLength() < inputTextLength)
       
   741 			error = iTextToShape.ReAlloc(inputTextLength);
       
   742 		}
       
   743 	if (error == KErrNone)
       
   744 		{
       
   745 		error = aMessage.Read(1, iTextToShape);
       
   746 		if (error != KErrNone)
       
   747 			{
       
   748 			aPanicRequired = ETrue;
       
   749 			return error;
       
   750 			}
       
   751 		error = aMessage.Read(2, sp);
       
   752 		if (error != KErrNone)
       
   753 			{
       
   754 			aPanicRequired = ETrue;
       
   755 			return error;
       
   756 			}
       
   757 		TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
       
   758 		if (error == KErrNone)
       
   759 			{
       
   760 			// Convert the pointer to be passed back to the client to an offset from
       
   761 			// the heap base so that it can be recreated client side relative to the
       
   762 			// client's heap base
       
   763 			return PointerToOffset(shape, fbtop->HeapBase());
       
   764 			}
       
   765 		}
       
   766 	return 0;
       
   767 	}
       
   768 
       
   769 
       
   770 /** Handler for EFbsMessShapeDelete message
       
   771  @param aMessage input and output parameters
       
   772  @param aPanicRequired flag that is set to ETrue if a client panic is required
       
   773  @return KErrNone if successful, otherwise a system wide error code
       
   774 	 An error code is only returned if aPanicRequired is set to ETrue.
       
   775  */
       
   776 TInt CFbClient::HandleMesgShapeDelete(const RMessage2& aMessage, TBool& aPanicRequired)
       
   777 	{
       
   778 	CFbTop* fbtop = TopLevelStore();
       
   779 	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
       
   780 	if(!fontptr)
       
   781 		{
       
   782 		aPanicRequired = ETrue;
       
   783 		return KErrArgument;
       
   784 		}
       
   785 	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
       
   786 
       
   787 	// Combine the passed shape offset with the current heap base to get
       
   788 	// a valid pointer to a shape header for use in this process			
       
   789 	TShapeHeader* shapeheader = reinterpret_cast<TShapeHeader*>(OffsetToPointer(aMessage.Int1(), fbtop->HeapBase()));
       
   790 
       
   791 	bitmapFont->DeleteShape(iSessionHandle,shapeheader);
       
   792 	return KErrNone;
       
   793 	}
       
   794 
       
   795 
       
   796 void CFbClient::ProcFontMessage(const RMessage2& aMessage)
       
   797 	{
       
   798 	TInt ret = KErrUnknown;
       
   799 	TBool panicRequired = EFalse;
       
   800 
       
   801 	switch(aMessage.Function())
       
   802 		{
       
   803 		case EFbsMessFontDuplicate:
       
   804 			ret = HandleMesgFontDuplicate(aMessage, panicRequired);
       
   805 			break;
       
   806 
       
   807 		case EFbsMessGetNearestFontToDesignHeightInTwips:
       
   808 		case EFbsMessGetNearestFontToDesignHeightInPixels:
       
   809 		case EFbsMessGetNearestFontToMaxHeightInTwips:
       
   810 		case EFbsMessGetNearestFontToMaxHeightInPixels:
       
   811 			ret = HandleMesgGetNearestFont(aMessage, panicRequired);
       
   812 			break;
       
   813 
       
   814 		case EFbsMessGetFontById:
       
   815 			ret = HandleMesgGetFontById(aMessage, panicRequired);
       
   816 			break;
       
   817 
       
   818 		case EFbsMessInstallFontStoreFile:
       
   819 		case EFbsMessAddFontStoreFile:
       
   820 			ret = HandleMesgAddOrInstallFontFile(aMessage, panicRequired);
       
   821 			break;
       
   822 
       
   823 		case EFbsMessRemoveFontStoreFile:
       
   824 			ret = HandleMesgRemoveFontFile(aMessage);
       
   825 			break;
       
   826 
       
   827 		case EFbsMessRasterize:
       
   828 			ret = HandleMesgRasterize(aMessage, panicRequired);
       
   829 			break;
       
   830 
       
   831 		case EFbsMessFaceAttrib:
       
   832 			ret = HandleMesgFaceAttrib(aMessage, panicRequired);
       
   833 			break;
       
   834 
       
   835 		case EFbsMessHasCharacter:
       
   836 			ret = HandleMesgHasCharacter(aMessage, panicRequired);
       
   837 			break;
       
   838 
       
   839 		case EFbsMessShapeText:
       
   840 			ret = HandleMesgShapeText(aMessage, panicRequired);
       
   841 			break;
       
   842 
       
   843 		case EFbsMessShapeDelete:
       
   844 			ret = HandleMesgShapeDelete(aMessage, panicRequired);
       
   845 			break;
       
   846 
       
   847 		case EFbsMessSetTwipsHeight:
       
   848 			{
       
   849 			TInt localhandle=aMessage.Int0();
       
   850 			CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(localhandle, TopLevelStore()->FontConUniqueID()));
       
   851 			if(!fontptr)
       
   852 				{
       
   853 				panicRequired = ETrue;
       
   854 				ret = KErrArgument;
       
   855 				break;
       
   856 				}
       
   857 			fontptr->iHeightInTwips = aMessage.Int1();
       
   858 			ret = KErrNone;
       
   859 			break;	
       
   860 			}
       
   861 		case EFbsMessGetTwipsHeight:
       
   862 			{
       
   863 			TInt localhandle=aMessage.Int0();
       
   864 			CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(localhandle, TopLevelStore()->FontConUniqueID()));
       
   865 			if(!fontptr)
       
   866 				{
       
   867 				panicRequired = ETrue;
       
   868 				ret = KErrArgument;
       
   869 				break;
       
   870 				}
       
   871 			TPckgBuf<TInt> height;
       
   872 			height() = fontptr->iHeightInTwips;
       
   873 			ret = aMessage.Write(1,height);
       
   874 			if (KErrNone != ret)
       
   875 				{
       
   876 				panicRequired = ETrue;
       
   877 				}
       
   878 			break;
       
   879 			}
       
   880 		case EFbsSetSystemDefaultTypefaceName:
       
   881 			{
       
   882 			TBuf<KMaxTypefaceNameLength> fontTypefaceName;
       
   883 			ret = aMessage.GetDesLength(0);
       
   884 			if (ret < 0)
       
   885 				{
       
   886 				panicRequired = ETrue;
       
   887 				break;
       
   888 				}
       
   889 			if (ret <= KMaxTypefaceNameLength) // Size in characters i.e. 2 bytes for unicode
       
   890 				{
       
   891 				ret = aMessage.Read(0, fontTypefaceName);
       
   892 				if (ret == KErrNone)
       
   893 					{
       
   894 					TopLevelStore()->SetSystemDefaultTypefaceName(fontTypefaceName);
       
   895 					}
       
   896 				}
       
   897 			else
       
   898 				{
       
   899 				panicRequired = ETrue;
       
   900 				ret = KErrTooBig;
       
   901 				}
       
   902 
       
   903 			break;
       
   904 			}
       
   905 
       
   906 #ifdef _DEBUG
       
   907 		case EFbsMessSetDuplicateFail:
       
   908 			TInt argument =aMessage.Int0();
       
   909 			if (argument)
       
   910 				{
       
   911 				iFontDuplicateToFail = ETrue;
       
   912 				}
       
   913 			else
       
   914 				{
       
   915 				iFontDuplicateToFail = EFalse;
       
   916 				}
       
   917 			ret=KErrNone;
       
   918 			break;
       
   919 #endif
       
   920 		}
       
   921 
       
   922 	// either have a result or an error code to panic the client with
       
   923 	if (panicRequired)
       
   924 		{
       
   925 		aMessage.Panic(KFBSERVPanicCategory, ret);
       
   926 		}
       
   927 	else
       
   928 		{
       
   929 		if(!aMessage.IsNull())
       
   930 			{
       
   931 			aMessage.Complete(ret);
       
   932 			}		
       
   933 		}
       
   934 #ifdef _DEBUG
       
   935 	iRet=ret;
       
   936 #endif	
       
   937 	}
       
   938 
       
   939 void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
       
   940 	{
       
   941 	CBitmapObject* bmpptr=NULL;
       
   942 	TInt localhandle=0;
       
   943 	TInt ret=KErrUnknown;
       
   944 	switch(aMessage.Function())
       
   945 		{
       
   946 	case EFbsMessBitmapCreate:
       
   947 		{
       
   948 		TPckgBuf<TBmpSpec> bs;
       
   949 		ret = aMessage.Read(0,bs);
       
   950 		if(ret!=KErrNone)
       
   951 			{
       
   952 			aMessage.Panic(KFBSERVPanicCategory,ret);
       
   953 			return;
       
   954 			}
       
   955 			
       
   956 		TBmpSpec& bmpSpec = bs();	
       
   957 		
       
   958 		if(!TDisplayModeUtils::IsDisplayModeValid(bmpSpec.iDispMode))
       
   959 			{
       
   960 			aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
       
   961 			return;
       
   962 			}
       
   963 
       
   964 		// client uses iHandle to pass UID and iServerHandle to pass data size
       
   965 		TRAP(ret, bmpptr = TopLevelStore()->CreateBitmapL(bmpSpec.iSizeInPixels, bmpSpec.iDispMode, TUid::Uid(bmpSpec.iHandle), EFalse, bmpSpec.iServerHandle));
       
   966 		if(ret!=KErrNone)
       
   967 			break;
       
   968 		TRAP(ret,localhandle=iIx->AddL(bmpptr));
       
   969 		if(ret!=KErrNone)
       
   970 			{
       
   971 			bmpptr->Close();
       
   972 			break;
       
   973 			}
       
   974 		bmpSpec.iHandle=localhandle;
       
   975 		bmpSpec.iServerHandle = bmpptr->Handle();
       
   976 		bmpSpec.iAddressOffset=TInt(bmpptr->Address())-TopLevelStore()->HeapBase();
       
   977 		ret = aMessage.Write(0,bs);
       
   978 		if(ret!=KErrNone)
       
   979 			{
       
   980 			iIx->Remove(localhandle);
       
   981 			aMessage.Panic(KFBSERVPanicCategory,ret);
       
   982 			return;
       
   983 			}
       
   984 		iResourceCount++;
       
   985 		break;
       
   986 		}
       
   987 
       
   988 	case EFbsMessBitmapLoad:
       
   989 	case EFbsMessBitmapLoadFast:
       
   990 		{
       
   991 		TPckgBuf<TLoadBitmapArg> loadBitmapArg;
       
   992 		ret = aMessage.Read(1,loadBitmapArg);
       
   993 		if(ret!=KErrNone)
       
   994 			{
       
   995 			aMessage.Panic(KFBSERVPanicCategory,ret);
       
   996 			return;
       
   997 			}
       
   998 		const TInt32 id=loadBitmapArg().iBitmapId;
       
   999 		const TBool shareifloaded=loadBitmapArg().iShareIfLoaded;
       
  1000 		const TUint fileOffset = loadBitmapArg().iFileOffset;
       
  1001 		if(aMessage.Function() == EFbsMessBitmapLoad)
       
  1002 			{
       
  1003 			RFile file;
       
  1004 			ret=file.AdoptFromClient(aMessage,2,3);
       
  1005 			if (ret!=KErrNone)
       
  1006 				{
       
  1007 				break;
       
  1008 				}
       
  1009 			TFileName filename;
       
  1010 			ret=file.FullName(filename);
       
  1011 			if (ret!=KErrNone)
       
  1012 				{
       
  1013 				break;
       
  1014 				}
       
  1015 
       
  1016 			if(shareifloaded)
       
  1017 				{
       
  1018 				TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset,&file, iSessionHandle));
       
  1019 				}
       
  1020 			else
       
  1021 				{
       
  1022 				TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, &file, iSessionHandle));
       
  1023 				}
       
  1024 			file.Close();
       
  1025 			}
       
  1026 		else
       
  1027 			{
       
  1028 			TFileName filename;
       
  1029 			ret = aMessage.Read(2,filename);
       
  1030 			if (ret!=KErrNone)
       
  1031 				{
       
  1032 				aMessage.Panic(KFBSERVPanicCategory,ret);
       
  1033 				return;
       
  1034 				}
       
  1035 			_LIT(KZDrive, "z:");
       
  1036 			if (filename.Left(2).CompareF(KZDrive))
       
  1037 				{
       
  1038 				// File is not in the Z: drive.
       
  1039 				// So open the file and pass the file handle to LoadBitmapL() or ShareBitmapL() and close it afterwards.
       
  1040 				// The reason is that the cache cannot be used for files that are writable,
       
  1041 				// since they can't be kept open in the cache.
       
  1042 				RFile file;
       
  1043 				ret = file.Open(TopLevelStore()->FileSession(),filename,EFileShareReadersOnly);
       
  1044 				if (ret!=KErrNone)
       
  1045 					{
       
  1046 					break;
       
  1047 					}
       
  1048 				if(shareifloaded)
       
  1049 					{
       
  1050 					TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset,&file, iSessionHandle));
       
  1051 					}
       
  1052 				else
       
  1053 					{
       
  1054 					TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, &file, iSessionHandle));
       
  1055 					}
       
  1056 				file.Close();
       
  1057 				}
       
  1058 			else
       
  1059 				{
       
  1060 				if(shareifloaded)
       
  1061 					{
       
  1062 					TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset, NULL, iSessionHandle));
       
  1063 					}
       
  1064 				else
       
  1065 					{
       
  1066 					TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, NULL, iSessionHandle));
       
  1067 					}
       
  1068 				}
       
  1069 			}
       
  1070 		if(ret!=KErrNone)
       
  1071 			{
       
  1072 			break;
       
  1073 			}
       
  1074 		TRAP(ret,localhandle=iIx->AddL(bmpptr));
       
  1075 		if(ret!=KErrNone)
       
  1076 			{
       
  1077 			bmpptr->Close();
       
  1078 			break;
       
  1079 			}
       
  1080 		TPckgBuf<TBmpHandles> handlebuffer;
       
  1081 		handlebuffer().iHandle=localhandle;
       
  1082 		handlebuffer().iServerHandle = bmpptr->Handle();
       
  1083 		handlebuffer().iAddressOffset=TInt(bmpptr->Address())-TopLevelStore()->HeapBase();
       
  1084 		ret = aMessage.Write(0,handlebuffer);
       
  1085 		if(ret!=KErrNone)
       
  1086 			{
       
  1087 			iIx->Remove(localhandle);
       
  1088 			aMessage.Panic(KFBSERVPanicCategory,ret);
       
  1089 			return;
       
  1090 			}
       
  1091 		iResourceCount++;
       
  1092 		break;
       
  1093 		}
       
  1094 	case EFbsMessBitmapResize:
       
  1095 		{
       
  1096 		localhandle=aMessage.Int0();
       
  1097 		CFbTop* fbtop = TopLevelStore();
       
  1098 		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
       
  1099 		if(!bmpptr)
       
  1100 			{
       
  1101 			ret=KErrUnknown;
       
  1102 			break;
       
  1103 			}
       
  1104 		ret = fbtop->GetCleanBitmap(bmpptr);
       
  1105 		if (ret != KErrNone)
       
  1106 			break;
       
  1107 		TSize newsize(aMessage.Int1(),aMessage.Int2());
       
  1108  		const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM();  //It must be set before the resizing is done.
       
  1109 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
       
  1110 		CBitmapObject* newbmpptr = NULL;
       
  1111 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
       
  1112 		if (ret != KErrNone)
       
  1113 			break;
       
  1114 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
       
  1115 		if (ret != KErrNone)
       
  1116 			{
       
  1117 			newbmpptr->Close();
       
  1118 			break;
       
  1119 			}
       
  1120  		if (compressedInRam)
       
  1121 			{
       
  1122 			// if the header says PaletteCompression specify.
       
  1123 			TBitmapfileCompressionScheme scheme = ERLECompression;
       
  1124 			if (bmpptr->Address()->iHeader.iCompression == EGenericPaletteCompression)
       
  1125 				scheme = EPaletteCompression;
       
  1126 			ret = newbmpptr->Address()->CompressData(scheme); // re-compress
       
  1127 			if (ret != KErrNone)
       
  1128 				{
       
  1129 				newbmpptr->Close();
       
  1130 				break;
       
  1131 				}
       
  1132 			}
       
  1133 		TInt newlocalhandle = 0;
       
  1134 		TRAP(ret, newlocalhandle = iIx->AddL(newbmpptr));
       
  1135 		if (ret != KErrNone)
       
  1136 			{
       
  1137 			newbmpptr->Close();
       
  1138 			break;
       
  1139 			}
       
  1140 		ret = newbmpptr->Open();
       
  1141 		if (ret != KErrNone)
       
  1142 			{
       
  1143 			iIx->Remove(newlocalhandle);
       
  1144 			break;
       
  1145 			}
       
  1146 		bmpptr->SetCleanBitmap(newbmpptr);
       
  1147 		if (bmpptr->AccessCount() >= 2)
       
  1148 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
       
  1149 		iIx->Remove(localhandle);
       
  1150 		TPckgBuf<TBmpHandles> handlebuffer;
       
  1151 		handlebuffer().iHandle = newlocalhandle;
       
  1152 		handlebuffer().iServerHandle = newbmpptr->Handle();
       
  1153 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
       
  1154 		ret = aMessage.Write(3, handlebuffer);
       
  1155 		if (ret != KErrNone)
       
  1156 			{
       
  1157 			iIx->Remove(newlocalhandle);
       
  1158 			aMessage.Panic(KFBSERVPanicCategory, ret);
       
  1159 			return;
       
  1160 			}
       
  1161 		break;
       
  1162 		}
       
  1163 	case EFbsMessBitmapDuplicate:
       
  1164 		{
       
  1165 		bmpptr = TopLevelStore()->FindBitmap(aMessage.Int0());
       
  1166 		if (bmpptr == NULL)
       
  1167 			{
       
  1168 			ret=KErrUnknown;
       
  1169 			break;
       
  1170 			}
       
  1171 		//coverity [check_return]
       
  1172 		//coverity [unchecked_value]
       
  1173 		TopLevelStore()->GetCleanBitmap(bmpptr);
       
  1174 		ret = bmpptr->Open();
       
  1175 		if (ret != KErrNone)
       
  1176 			break;
       
  1177 		TPckgBuf<TBmpHandles> handlebuffer;
       
  1178 		TRAP(ret,localhandle=iIx->AddL(bmpptr));
       
  1179 		if(ret!=KErrNone)
       
  1180 			{
       
  1181 			bmpptr->Close();
       
  1182 			break;
       
  1183 			}
       
  1184 		handlebuffer().iHandle = localhandle;
       
  1185 		handlebuffer().iServerHandle = bmpptr->Handle();
       
  1186 		handlebuffer().iAddressOffset = TInt(bmpptr->Address()) - TopLevelStore()->HeapBase();
       
  1187 		ret = aMessage.Write(1, handlebuffer);
       
  1188 		if(ret!=KErrNone)
       
  1189 			{
       
  1190 			iIx->Remove(localhandle);
       
  1191 			aMessage.Panic(KFBSERVPanicCategory,ret);
       
  1192 			return;
       
  1193 			}
       
  1194 		iResourceCount++;
       
  1195 		break;
       
  1196 		}
       
  1197 	case EFbsMessBitmapCompress:
       
  1198 		{
       
  1199 		localhandle = aMessage.Int0();
       
  1200 		CFbTop* fbtop = TopLevelStore();
       
  1201 		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
       
  1202 		if(!bmpptr)
       
  1203 			{
       
  1204 			ret = KErrUnknown;
       
  1205 			break;
       
  1206 			}
       
  1207 		ret = fbtop->GetCleanBitmap(bmpptr);
       
  1208 		if (ret != KErrNone)
       
  1209 			break;
       
  1210 		const TSize size = bmpptr->Address()->SizeInPixels();
       
  1211 		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
       
  1212 		CBitmapObject* newbmpptr = NULL;
       
  1213 		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
       
  1214 		if (ret != KErrNone)
       
  1215 			break;
       
  1216 		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
       
  1217 		if (ret != KErrNone)
       
  1218 			{
       
  1219 			newbmpptr->Close();
       
  1220 			break;
       
  1221 			}
       
  1222 		ret = newbmpptr->Address()->CompressData((TBitmapfileCompressionScheme)aMessage.Int1());
       
  1223 		if (ret != KErrNone)
       
  1224 			{
       
  1225 			newbmpptr->Close();
       
  1226 			break;
       
  1227 			}
       
  1228 		TInt newlocalhandle = 0;
       
  1229 		TRAP(ret, newlocalhandle = iIx->AddL(newbmpptr));
       
  1230 		if (ret != KErrNone)
       
  1231 			{
       
  1232 			newbmpptr->Close();
       
  1233 			break;
       
  1234 			}
       
  1235 		ret = newbmpptr->Open();
       
  1236 		if (ret != KErrNone)
       
  1237 			{
       
  1238 			iIx->Remove(newlocalhandle);
       
  1239 			break;
       
  1240 			}
       
  1241 		bmpptr->SetCleanBitmap(newbmpptr);
       
  1242 		if (bmpptr->AccessCount() >= 2)
       
  1243 			fbtop->NotifyDirtyBitmap(*bmpptr, this);
       
  1244 		iIx->Remove(localhandle);
       
  1245 		TPckgBuf<TBmpHandles> handlebuffer;
       
  1246 		handlebuffer().iHandle = newlocalhandle;
       
  1247 		handlebuffer().iServerHandle = newbmpptr->Handle();
       
  1248 		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
       
  1249 		ret = aMessage.Write(2, handlebuffer);
       
  1250 		if (ret != KErrNone)
       
  1251 			{
       
  1252 			iIx->Remove(newlocalhandle);
       
  1253 			aMessage.Panic(KFBSERVPanicCategory, ret);
       
  1254 			return;
       
  1255 			}
       
  1256 		break;
       
  1257 		}
       
  1258 	case EFbsMessBitmapBgCompress:
       
  1259 		{
       
  1260 		localhandle = aMessage.Int0();
       
  1261 		TBitmapfileCompressionScheme scheme = (TBitmapfileCompressionScheme)aMessage.Int1();
       
  1262 		TBool async = aMessage.Int2();
       
  1263 		CFbTop* fbtop = TopLevelStore();
       
  1264 		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
       
  1265 		if(!bmpptr)
       
  1266 			{
       
  1267 			ret = KErrUnknown;
       
  1268 			break;
       
  1269 			}
       
  1270 		ret = fbtop->GetCleanBitmap(bmpptr);
       
  1271 		if (ret != KErrNone)
       
  1272 			{
       
  1273 			if (!async)
       
  1274 				ret = KErrNone;
       
  1275 			break;
       
  1276 			}
       
  1277 		ret = bmpptr->Address()->CheckBackgroundCompressData();
       
  1278 		if (KErrNone == ret)
       
  1279 			{
       
  1280 			ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
       
  1281 			if (ret == KErrNone && async)
       
  1282 				return; // do not complete the client's request - that will be done by the background compression thread
       
  1283 			}
       
  1284 		if (KErrAlreadyExists == ret)
       
  1285 			ret = KErrNone;
       
  1286 		break;
       
  1287 		}
       
  1288 	case EFbsMessBitmapClean:
       
  1289 		{
       
  1290 		TInt localhandle = aMessage.Int0();
       
  1291 		CFbTop* fbtop = TopLevelStore();
       
  1292 		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
       
  1293 		if(!bmpptr)
       
  1294 			{
       
  1295 			ret = KErrUnknown;
       
  1296 			break;
       
  1297 			}
       
  1298 		ret = fbtop->GetCleanBitmap(bmpptr);
       
  1299 		if (ret != KErrNone)
       
  1300 			break;
       
  1301 		ret = bmpptr->Open();
       
  1302 		if (ret != KErrNone)
       
  1303 			break;
       
  1304 		TInt cleanlocalhandle = 0;
       
  1305 		TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
       
  1306 		if (ret != KErrNone)
       
  1307 			{
       
  1308 			bmpptr->Close();
       
  1309 			break;
       
  1310 			}
       
  1311 		iIx->Remove(localhandle);
       
  1312 		TPckgBuf<TBmpHandles> handlebuffer;
       
  1313 		handlebuffer().iHandle = cleanlocalhandle;
       
  1314 		handlebuffer().iServerHandle = bmpptr->Handle();
       
  1315 		handlebuffer().iAddressOffset = TInt(bmpptr->Address()) - fbtop->HeapBase();
       
  1316 		ret = aMessage.Write(1, handlebuffer);
       
  1317 		if (ret != KErrNone)
       
  1318 			{
       
  1319 			iIx->Remove(cleanlocalhandle);
       
  1320 			aMessage.Panic(KFBSERVPanicCategory, ret);
       
  1321 			return;
       
  1322 			}
       
  1323 		break;
       
  1324 		}
       
  1325 	case EFbsGetAllBitmapHandles:
       
  1326 		{
       
  1327 		ret = TopLevelStore()->GetAllBitmapHandles(aMessage);		
       
  1328 		break;	
       
  1329 		}	
       
  1330 
       
  1331 	case EFbsMessBitmapNotifyDirty:
       
  1332 		{
       
  1333 		if (iHelper == NULL)
       
  1334 			{
       
  1335 			iHelper = new TFbClientHelper(*this);
       
  1336 			if (iHelper == NULL)
       
  1337 				{
       
  1338 				ret = KErrNoMemory;
       
  1339 				break;
       
  1340 				}
       
  1341 			TopLevelStore()->AddClientHelper(*iHelper);
       
  1342 			}
       
  1343 		if (!iHelper->iMessage.IsNull())
       
  1344 			{
       
  1345 			aMessage.Panic(KFBSERVPanicCategory, KErrAlreadyExists);
       
  1346 			return;
       
  1347 			}
       
  1348 		if (!iHelper->iDirty)
       
  1349 			{
       
  1350 			iHelper->iMessage = aMessage;
       
  1351 			return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
       
  1352 			}
       
  1353 		ret = KErrNone;
       
  1354 		iHelper->iDirty = EFalse;
       
  1355 		}
       
  1356 		break;
       
  1357 	case EFbsMessBitmapCancelNotifyDirty:
       
  1358 		{
       
  1359 		if (iHelper != NULL && !iHelper->iMessage.IsNull())
       
  1360 			iHelper->iMessage.Complete(KErrCancel);
       
  1361 		ret = KErrNone;
       
  1362 		}
       
  1363 		break;
       
  1364 		}
       
  1365 		
       
  1366 	if(!aMessage.IsNull())
       
  1367 		{
       
  1368 		aMessage.Complete(ret);
       
  1369 		}
       
  1370 	
       
  1371 #ifdef _DEBUG
       
  1372 	iRet=ret;
       
  1373 #endif		
       
  1374 	}
       
  1375 
       
  1376 void CFbClient::NotifyDirtyBitmap(CBitmapObject& aBmpObj)
       
  1377 	{
       
  1378 	if (iHelper != NULL && iIx->At(&aBmpObj) != KErrNotFound)
       
  1379 		{
       
  1380 		iHelper->iDirty = ETrue;
       
  1381 		if (!iHelper->iMessage.IsNull())
       
  1382 			{
       
  1383 			iHelper->iMessage.Complete(KErrNone);
       
  1384 			iHelper->iDirty = EFalse;
       
  1385 			}
       
  1386 		}
       
  1387 	}
       
  1388 
       
  1389 void CFbClient::AddFontFileIndexL(TUid aId)
       
  1390 	{
       
  1391 	TInt count=iFontFileIndex->Count();
       
  1392 	for (TInt index=0;index<count;index++)
       
  1393 		{
       
  1394 		if (iFontFileIndex->At(index).iUid==aId)
       
  1395 			{
       
  1396 			iFontFileIndex->At(index).iAccessCount++;
       
  1397 			TopLevelStore()->FontStore()->RemoveFile(aId);
       
  1398 			return;
       
  1399 			}
       
  1400 		}
       
  1401 
       
  1402 	TFontFileIndex fontFileIndex;
       
  1403 	fontFileIndex.iUid=aId;
       
  1404 	fontFileIndex.iAccessCount=1;
       
  1405 	iFontFileIndex->AppendL(fontFileIndex);
       
  1406 	}
       
  1407 
       
  1408 void CFbClient::RemoveFontFileIndex(TUid aId)
       
  1409 	{
       
  1410 	TInt count=iFontFileIndex->Count();
       
  1411 	for (TInt index=0;index<count;index++)
       
  1412 		{
       
  1413 		TFontFileIndex* fontFileIndex=&iFontFileIndex->At(index);
       
  1414 		if (fontFileIndex->iUid==aId)
       
  1415 			{
       
  1416 			fontFileIndex->iAccessCount--;
       
  1417 			if (fontFileIndex->iAccessCount<1)
       
  1418 				{
       
  1419 				TopLevelStore()->FontStore()->RemoveFile(fontFileIndex->iUid);
       
  1420 				iFontFileIndex->Delete(index);
       
  1421 				}
       
  1422 			return;
       
  1423 			}
       
  1424 		}
       
  1425 	// not found - must be an installed file or rubbish, so try anyway
       
  1426 	TopLevelStore()->FontStore()->RemoveFile(aId);
       
  1427 	}
       
  1428 
       
  1429 void CFbClient::Disconnect(const RMessage2 &aMessage)
       
  1430 	{
       
  1431 	// if any bitmaps are in the background compression queue with a to-be-completed RMessage2 from this session,
       
  1432 	// the RMessage2 must be completed now as it is only possible to complete messages on existing sessions
       
  1433 	TopLevelStore()->BackgroundCompression()->CompleteOutstandingRequests(this);
       
  1434 
       
  1435 	// if there is a to-be-completed request for dirty bitmap notification complete it now
       
  1436 	if (iHelper)
       
  1437 		{
       
  1438 		if (!iHelper->iMessage.IsNull())
       
  1439 			iHelper->iMessage.Complete(KErrDisconnected);
       
  1440 		iHelper->Deque();
       
  1441 		delete iHelper;
       
  1442 		iHelper = NULL;
       
  1443 		}
       
  1444 
       
  1445 	// Clear the mbm file store cache resources that corresponds to this session
       
  1446 	TopLevelStore()->CloseFileStores(iSessionHandle);
       
  1447 
       
  1448 	CSession2::Disconnect(aMessage);
       
  1449 	}
       
  1450 
       
  1451 #ifdef _DEBUG
       
  1452 void CFbClient::ProcMemMessage(const RMessage2 &aMessage)
       
  1453 	{
       
  1454 	TInt ret=KErrNone;
       
  1455 	TInt parameterForFunctionCall;
       
  1456 	TInt cells = User::Heap().Available(parameterForFunctionCall);
       
  1457 	switch(aMessage.Function())
       
  1458 		{
       
  1459 		case EFbsMessSetHeapFail:
       
  1460 			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
       
  1461 				{
       
  1462 				iOwnHeapFailNumber=aMessage.Int1();
       
  1463 				}
       
  1464 			else
       
  1465 				{
       
  1466 				iSharedHeapFailNumber=aMessage.Int1();
       
  1467 				}
       
  1468 			break;
       
  1469 		case EFbsMessHeapCount:
       
  1470 			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
       
  1471 				{
       
  1472 				ret=User::CountAllocCells();
       
  1473 				}
       
  1474 			else
       
  1475 				{
       
  1476 				ret=iHeap->Count();
       
  1477 				}	
       
  1478 			break;
       
  1479 		case EFbsMessSetHeapReset:
       
  1480 			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
       
  1481 				{
       
  1482 				iOwnHeapFailNumber=-1;
       
  1483 				}
       
  1484 			else
       
  1485 				{
       
  1486 				iSharedHeapFailNumber=-1;
       
  1487 				}				
       
  1488 			break;
       
  1489 		case EFbsMessSetHeapCheck:
       
  1490 			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
       
  1491 				{
       
  1492 				iOwnHeapCheckFlip=ETrue;
       
  1493 				}
       
  1494 			else
       
  1495 				{
       
  1496 				iHeapCheckFlip=ETrue;
       
  1497 				}
       
  1498 			break;
       
  1499 		case EFbsMessHeap:
       
  1500 			ret=(TInt)iHeap;
       
  1501 			break;			
       
  1502 		}
       
  1503 	aMessage.Complete(ret);
       
  1504 	iRet=ret;
       
  1505 	}
       
  1506 #endif