fbs/fontandbitmapserver/sfbs/FBSCLI.CPP
changeset 0 5d03bc08d59c
child 4 15986eb6c500
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fbs/fontandbitmapserver/sfbs/FBSCLI.CPP	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1506 @@
+// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <fntstore.h>
+#include <bitmap.h>
+#include <openfont.h>
+#include "fbsmessage.h"
+#include "SERVER.H"
+#include "BackGroundCompression.h"
+#include <shapeinfo.h>
+#include <graphics/shaperparams.h>
+
+/** Helper function for converting a pointer to an offset from the passed
+heap base. Use OffsetToPointer() to convert the returned offset back to a
+useable pointer.
+@param aAny A pointer to be converted to an offset.
+@param aHeapBase The heap base of the current process.
+@return An offset representing the passed pointer that can be converted
+back to a pointer using the function OffsetToPointer(). 
+@see OffsetToPointer()
+ */
+LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
+	{
+	if (aAny && aHeapBase)
+		{
+		return (TInt)aAny - (TInt)aHeapBase;
+		}
+	return 0;
+	}
+
+/** Helper function for converting an offset (that was calculated using
+PointerToOffset()) back to a pointer relative to the passed heap base.
+@param aOffset The offset to be converted to a pointer.
+@param aHeapBase The heap base of the current process.
+@return A pointer relative to the passed heap base.
+@see PointerToOffset()
+ */
+LOCAL_C TAny* OffsetToPointer(const TInt aOffset, TInt aHeapBase)
+	{
+	if (aOffset && aHeapBase)
+		{
+		return (TAny*)(aOffset + (TInt)aHeapBase);
+		}
+	return NULL;
+	}
+
+CFbClient::CFbClient(RHeap* aHeap):
+	CSession2(),
+	iConnectionHandle(0),
+	iIx(NULL),
+	iResourceCount(0),
+	iHeap(aHeap)
+#ifdef _DEBUG
+	,iOwnHeapFailNumber(-1),
+	iSharedHeapFailNumber(-1)
+#endif	
+	{
+	}
+
+CFbClient* CFbClient::NewL(RHeap* aHeap)
+	{
+	CFbClient* c = new(ELeave) CFbClient(aHeap);
+	c->iOpenFontGlyphData = TOpenFontGlyphData::New(aHeap,4 * 1024);
+	if (!c->iOpenFontGlyphData)
+		{
+		delete c;
+		User::Leave(KErrNoMemory);
+		}
+	return c;
+	}
+
+CFbClient::~CFbClient()
+	{
+	/*
+	Don't call any CFontStore functions if CFbClient::NewL has left, or if FBSERV has already deleted the
+	font store, which happens in test programs like TFBS when FBSERV is closed before the client(s).
+	*/
+	CFontStore* font_store = NULL;
+	CFbTop* fbTop = TopLevelStore();
+	if (fbTop)
+		{
+		font_store = fbTop->FontStore();
+		}
+	
+	if (font_store)
+		font_store->DeleteSessionCache(iSessionHandle);
+	
+	// If the font store doesn't exist, neither will the shared heap owned by FBSERV.
+	if (font_store)
+		iHeap->Free(iOpenFontGlyphData);
+	
+	// delete fonts hold by the client
+	delete iIx;
+	
+	// delete font files hold by the client
+    if (iFontFileIndex)
+        {
+        TInt count = iFontFileIndex->Count();
+        for (TInt index = 0;index < count; index++)
+            {
+            if (font_store)
+                font_store->RemoveFile(iFontFileIndex->At(0).iUid);
+            iFontFileIndex->Delete(0);
+            }
+        delete iFontFileIndex;
+        }
+
+	// Close the buffer used to hold the text thats needs shaping.
+	iTextToShape.Close();
+	}
+
+void CFbClient::Init(TUint aConnectionHandle)
+	{
+	iConnectionHandle=aConnectionHandle;
+	}
+
+void CFbClient::CreateL()
+	{
+	iIx=CObjectIx::NewL();
+	iFontFileIndex=new(ELeave) CArrayFixFlat<TFontFileIndex>(1);
+	}
+
+CFontBitmapServer* CFbClient::FontBitmapServer()
+	{
+	return((CFontBitmapServer*)Server());
+	}
+
+CFbTop* CFbClient::TopLevelStore()
+	{
+	CFontBitmapServer* server = FontBitmapServer();
+	if (server)
+		return server->TopLevelStore();
+	else
+		return NULL;
+	}
+
+void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
+	{
+	CBitmapFont* font=aFontObjPtr->iAddressPointer;
+	aFontInfo.iHandle = aHandle;
+	aFontInfo.iServerHandle=(TInt)aFontObjPtr;
+	aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
+	}
+
+void CFbClient::ServiceL(const RMessage2& aMessage)
+	{
+#ifdef _DEBUG
+	TBool resetOwnHeap=EFalse;
+	TBool resetSharedHeap=EFalse;
+	
+	//the memory tests have been mostly written to have start and end memory
+	//function calls (or macros) at the start of this function call (ServiceL)
+	//and the matching call (or macro) is at the end of this function.
+	
+	if (iOwnHeapFailNumber!=-1)
+		{
+		//if this not -1 then know to set the heap to fail on
+		//the given number of allocations
+		
+		resetOwnHeap=ETrue;
+		__UHEAP_SETFAIL(RHeap::EDeterministic,iOwnHeapFailNumber);
+		}
+	if (iSharedHeapFailNumber!=-1)
+		{
+		resetSharedHeap=ETrue;
+		__RHEAP_SETFAIL (iHeap, RHeap::EDeterministic,iSharedHeapFailNumber);
+		}	
+
+	if (iOwnHeapCheck)
+		{
+		__UHEAP_MARK;
+		}					
+	if (iHeapCheck)
+		{
+		__RHEAP_MARK(iHeap);
+		}		
+#endif		
+	
+	switch(aMessage.Function())
+		{
+// client messages
+	case EFbsMessInit:
+		Init(FontBitmapServer()->Init());
+		iSessionHandle = (TInt)this;
+		aMessage.Complete(iSessionHandle);
+#ifdef _DEBUG
+		iRet=KErrNone;
+#endif		
+		break;
+	case EFbsMessClose:
+		{
+		TInt localhandle=aMessage.Int0();
+		if(!iIx->At(localhandle))
+			{
+			aMessage.Panic(KFBSERVPanicCategory,KErrNotFound);
+			break;
+			}
+		iIx->Remove(localhandle);
+		iResourceCount--;
+		aMessage.Complete(KErrNone);
+#ifdef _DEBUG
+		iRet=KErrNone;
+#endif				
+		break;
+		}
+	case EFbsMessResourceCount:
+		aMessage.Complete(iResourceCount);
+#ifdef _DEBUG
+		iRet=iResourceCount;
+#endif			
+		break;
+// server messages
+	case EFbsMessShutdown:
+	case EFbsMessNumTypefaces:
+	case EFbsMessTypefaceSupport:
+	case EFbsMessFontHeightInTwips:
+	case EFbsMessFontHeightInPixels:
+	case EFbsMessSetPixelHeight:
+	case EFbsMessDefaultAllocFail:
+	case EFbsMessDefaultMark:
+	case EFbsMessDefaultMarkEnd:
+	case EFbsMessUserAllocFail:
+	case EFbsMessUserMark:
+	case EFbsMessUserMarkEnd:
+	case EFbsMessHeapCheck:
+	case EFbsMessSetDefaultGlyphBitmapType:
+	case EFbsMessGetDefaultGlyphBitmapType:
+	case EFbsMessFontNameAlias:
+	case EFbsMessGetHeapSizes:
+	case EFbsMessDefaultLanguageForMetrics:
+	case EFbsCompress:
+	case EFbsMessFetchLinkedTypeface:
+	case EFbsMessRegisterLinkedTypeface:
+	case EFbsMessUpdateLinkedTypeface:
+#ifdef _DEBUG
+		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
+#else
+		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
+#endif			
+		break;
+// font messages
+	case EFbsMessFontDuplicate:
+	case EFbsMessGetNearestFontToDesignHeightInTwips:
+	case EFbsMessGetNearestFontToDesignHeightInPixels:
+	case EFbsMessGetNearestFontToMaxHeightInTwips:
+	case EFbsMessGetNearestFontToMaxHeightInPixels:
+	case EFbsMessGetFontById:
+	case EFbsMessInstallFontStoreFile:
+	case EFbsMessAddFontStoreFile:
+	case EFbsMessRemoveFontStoreFile:
+	case EFbsMessRasterize:
+	case EFbsMessFaceAttrib:
+	case EFbsMessHasCharacter:
+	case EFbsMessShapeText:
+	case EFbsMessShapeDelete:
+	case EFbsMessSetTwipsHeight:
+	case EFbsMessGetTwipsHeight:
+	case EFbsSetSystemDefaultTypefaceName:
+#if (_DEBUG)
+	case EFbsMessSetDuplicateFail:
+#endif
+		ProcFontMessage(aMessage);
+		break;
+// bitmap messages
+	case EFbsMessBitmapCreate:
+	case EFbsMessBitmapResize:
+	case EFbsMessBitmapDuplicate:
+	case EFbsMessBitmapLoad:
+	case EFbsMessBitmapCompress:
+	case EFbsMessBitmapBgCompress:
+	case EFbsMessBitmapClean:
+	case EFbsGetAllBitmapHandles:
+	case EFbsMessBitmapLoadFast:
+	case EFbsMessBitmapNotifyDirty:
+	case EFbsMessBitmapCancelNotifyDirty:
+		ProcBitmapMessage(aMessage);
+		break;
+//Memory messages		
+	case EFbsMessSetHeapFail:
+	case EFbsMessHeapCount:
+	case EFbsMessSetHeapReset:
+	case EFbsMessSetHeapCheck:
+	case EFbsMessHeap:
+#ifdef _DEBUG	
+		ProcMemMessage(aMessage);
+#else
+		aMessage.Complete(KErrNone);
+#endif	
+		break;
+	default:
+		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
+		break;
+		}
+#ifdef _DEBUG
+
+	//do not want a memory panic if the return code is OK
+	//__UHEAP_MARKEND does this
+	
+	if (iOwnHeapCheck)
+		{
+		TUint32 badCell=User::Heap().__DbgMarkEnd(0);
+		if (iRet<0)
+			{
+			//if the function call was a success, there may have been valid memory allocations,
+			//so only panic if the call failed, and the memory is not the same before and after the
+			//function call
+			__ASSERT_DEBUG (badCell==NULL,User::Panic(KFBSERVPanicCategory, KErrGeneral));
+			}
+		}					
+	if (iHeapCheck)
+		{
+		TUint32 badCell2=0;
+		badCell2= __RHEAP_MARKEND(iHeap);
+		//the above function call does not panic if there is a failure, this is
+		//only for the user heap
+		if (iRet<0)
+			{
+			__ASSERT_DEBUG (badCell2==NULL,User::Panic(KFBSERVPanicCategory, KErrGeneral));
+			}
+		}
+	//change the state of the memory check?	
+	if (iOwnHeapCheckFlip)
+		{
+		//change the state of the memory testing
+		//if the mark was set still need to have a mark end
+		iOwnHeapCheckFlip=EFalse;
+		iOwnHeapCheck=!iOwnHeapCheck;
+		}
+	if (iHeapCheckFlip)
+		{
+		iHeapCheckFlip=EFalse;
+		iHeapCheck=!iHeapCheck;
+		}
+		
+	if (resetOwnHeap)
+		{
+		//previously set failures, reset
+		__UHEAP_RESET;
+		}
+	if (resetSharedHeap)
+		{		
+		__RHEAP_RESET (iHeap);
+		}		
+#endif		
+	}
+
+
+/** Handler for EFbsMessFontDuplicate message
+ @param aMessage input parameters
+ @param aPanicRequired flag that is set if a client panic is required
+ @return KErrNone if successful, otherwise a system wide error code
+ */
+TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
+	{
+#if _DEBUG
+	if (iFontDuplicateToFail)
+		return KErrNoMemory; //return with this error since this error is possible
+#endif
+	CFontObject* fontptr = (CFontObject*) aMessage.Int0();
+	if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
+		{
+		return KErrUnknown;
+		}
+
+	TPckgBuf<TFontInfo> foninfo;
+	TInt localhandle = 0;
+	TInt ret = fontptr->Open();
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+	TRAP(ret, localhandle=iIx->AddL(fontptr));
+	if (ret != KErrNone)
+		{
+		fontptr->Close();
+		return ret;
+		}
+	CopyFontInfo(fontptr,localhandle,foninfo());
+	fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
+	ret = aMessage.Write(1, foninfo);
+	if(ret != KErrNone)
+		{
+		iIx->Remove(localhandle);
+		aPanicRequired = ETrue;
+		return ret;
+		}
+
+	// success
+	iResourceCount++;
+	return KErrNone;
+	}
+
+
+/** Handler for EFbsMessGetNearestFontToDesignHeightInTwips, EFbsMessGetNearestFontToDesignHeightInPixels, 
+ EFbsMessGetNearestFontToMaxHeightInTwips or EFbsMessGetNearestFontToMaxHeightInPixels messages
+ @param aMessage input and output parameters
+ @param aPanicRequired flag that is set if a client panic is required
+ @return KErrNone if successful, otherwise a system wide error code
+ */
+TInt CFbClient::HandleMesgGetNearestFont(const RMessage2& aMessage, TBool& aPanicRequired)
+	{
+	CFontObject* fontptr = NULL;
+	TPckgBuf<TFontSpec> pckgFontSpec;
+	TInt pckgMaxHeight;
+	TPckgBuf<TSizeInfo> info;
+
+	const TFbsMessage	fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
+
+	TInt ret = aMessage.Read(0, pckgFontSpec);
+	TFontSpec& fontSpec = pckgFontSpec();
+	if (ret == KErrNone )
+		{
+		TInt length = fontSpec.iTypeface.iName.Length();
+		if(length < 0 || length > TOpenFontFaceAttribBase::ENameLength)
+			{
+			aPanicRequired = ETrue;
+			return KErrArgument;
+			}	
+		
+		ret = aMessage.Read(2, info);
+		if (ret == KErrNone)
+			{
+			pckgMaxHeight = info().iMaxHeight;
+			TopLevelStore()->FontStore()->iKPixelHeightInTwips=info().iDevSize.iHeight;
+			TopLevelStore()->FontStore()->iKPixelWidthInTwips=info().iDevSize.iWidth;
+			}
+		}
+
+	if (KErrNone != ret)
+		{
+		aPanicRequired = ETrue;
+		return ret;
+		}
+	if ( (EFbsMessGetNearestFontToMaxHeightInTwips == fbsMessage) || (EFbsMessGetNearestFontToMaxHeightInPixels == fbsMessage) )
+		{
+		ret = TopLevelStore()->GetNearestFont(fontptr, fbsMessage, fontSpec, pckgMaxHeight);
+		}
+	else
+		{
+		ret = TopLevelStore()->GetNearestFont(fontptr, fbsMessage, fontSpec);
+		}
+
+	if (ret == KErrNone)
+		{ // package up the result
+		ret = CopyFontInfoIntoReturnMessage(aMessage, aPanicRequired, fontptr, 1);
+		}
+
+	return ret;
+	}
+
+
+ /** package up the font that was found - includes cleanup handling in case of error
+ @param aMessage input and output parameters
+ @param aPanicRequired flag that is set if a client panic is required
+ @param aFontObj the object that is to be returned
+ @param aWritePosition the slot position in the message pointing to the receiving object
+ @return KErrNone if successful, otherwise a system wide error code
+ */
+TInt CFbClient::CopyFontInfoIntoReturnMessage(const RMessage2& aMessage, TBool& aPanicRequired, CFontObject* aFontObj, TInt aWritePosition)
+	{
+	TInt localhandle = 0;
+	TRAPD(ret, localhandle = iIx->AddL(aFontObj));
+	if (KErrNone != ret)
+		{
+		aFontObj->Close();
+		return ret;
+		}
+	TPckgBuf<TFontInfo> pckgFontInfo;
+	CopyFontInfo(aFontObj, localhandle, pckgFontInfo());
+	ret = aMessage.Write(aWritePosition, pckgFontInfo);
+	if (KErrNone != ret)
+		{
+		iIx->Remove(localhandle);
+		aPanicRequired = ETrue;
+		return ret;
+		}
+	// success
+	iResourceCount++;
+	return KErrNone;
+	}
+
+
+/** Handler for EFbsMessGetFontById message
+ Works for Bitmap fonts only, see implementation in CFbTop::GetFontById() & CFontStore::GetFontById().
+ @param aMessage input and output parameters
+ @param aPanicRequired flag that is set if a client panic is required
+ @return KErrNone if successful, otherwise a system wide error code
+ */
+TInt CFbClient::HandleMesgGetFontById(const RMessage2& aMessage, TBool& aPanicRequired)
+	{
+	CFontObject* fontptr = NULL;
+	TPckgBuf<TAlgStyle> algstyle;
+	TPckgBuf<TSize> size;
+
+	TInt ret = aMessage.Read(1, algstyle);
+	if (ret == KErrNone)
+		{ // get font size
+		ret = aMessage.Read(3, size);
+		if (ret == KErrNone)
+			{
+			TopLevelStore()->FontStore()->iKPixelHeightInTwips = size().iHeight;
+			TopLevelStore()->FontStore()->iKPixelWidthInTwips = size().iWidth;
+			}
+		}
+	if (ret != KErrNone)
+		{
+		aPanicRequired = ETrue;
+		return ret;
+		}
+	TUid fileid;
+	fileid.iUid = aMessage.Int2();
+	ret = TopLevelStore()->GetFontById(fontptr,fileid,algstyle());
+
+	if (ret == KErrNone)
+		{ // package up the result
+		ret = CopyFontInfoIntoReturnMessage(aMessage, aPanicRequired, fontptr, 0);
+		}
+
+	return ret;
+	}
+
+
+/** Handler for EFbsMessInstallFontStoreFile or EFbsMessAddFontStoreFile messages
+ @param aMessage input and output parameters
+ @param aPanicRequired flag that is set if a client panic is required
+ @return KErrNone if successful, otherwise a system wide error code
+ */
+TInt CFbClient::HandleMesgAddOrInstallFontFile(const RMessage2& aMessage, TBool& aPanicRequired)
+	{
+	TPckgBuf<TIntParcel> id;
+	TInt length=aMessage.Int1();
+	
+	if(length < 0 || length * sizeof(TText) >= KMaxTInt/2)
+		{
+		aPanicRequired = ETrue;
+		return KErrArgument;
+		}
+	
+	TText* buffer=(TText*)User::Alloc(length*sizeof(TText));
+	if(buffer==NULL)
+		{
+		return KErrNoMemory;
+		}
+	TPtr filename(buffer,length,length);
+	TInt ret = aMessage.Read(0,filename);
+	if(ret!=KErrNone)
+		{
+		User::Free(buffer);
+		aPanicRequired = ETrue;
+		return ret;
+		}
+	TRAP(ret, id().iInt = TopLevelStore()->FontStore()->AddFileL(filename).iUid);
+	User::Free(buffer);
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+	TUid uid;
+	uid.iUid=id().iInt;
+	if (aMessage.Function() == EFbsMessAddFontStoreFile)
+		{
+		TRAP(ret, AddFontFileIndexL(uid));
+		if (ret!=KErrNone)
+			{
+			TopLevelStore()->FontStore()->RemoveFile(uid);
+			return ret;
+			}
+		}
+	ret = aMessage.Write(2,id);
+	if (ret!=KErrNone)
+		{
+		RemoveFontFileIndex(uid);
+		aPanicRequired = ETrue;
+		}
+	return ret;
+	}
+
+
+/** Handler for EFbsMessRemoveFontStoreFile message
+ @param aMessage input parameters
+ @return KErrNone if successful
+ */
+TInt CFbClient::HandleMesgRemoveFontFile(const RMessage2& aMessage)
+	{
+	TUid uid;
+	uid.iUid=aMessage.Int0();
+	RemoveFontFileIndex(uid);
+	return KErrNone;
+	}
+
+
+/** Handler for EFbsMessRasterize message
+ @param aMessage input parameters
+ @param aPanicRequired flag that is set if a client panic is required
+ @return ETrue if successful, EFalse or any system-wide error code if not successful.
+ */
+TInt CFbClient::HandleMesgRasterize(const RMessage2& aMessage, TBool& aPanicRequired)
+	{
+	CFbTop* fbtop = TopLevelStore();
+	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
+	if(!fontptr)
+		{
+		aPanicRequired = ETrue;
+		return KErrArgument;
+		}
+	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
+	const TUint charCode = aMessage.Int1();
+
+	if ( (bitmapFont != NULL) && (bitmapFont->Rasterize(iSessionHandle, charCode, iOpenFontGlyphData)) )
+		{
+		// Convert all pointers to be passed back to the client to offsets from
+		// the heap base so that they can be recreated client side relative to the
+		// client's heap base
+		TInt heapbase = fbtop->HeapBase();
+		TPckgBuf<TRasterizeParams> params;
+		params().iMetricsOffset = PointerToOffset(iOpenFontGlyphData->Metrics(), heapbase);
+		params().iBitmapPointerOffset = PointerToOffset(iOpenFontGlyphData->BitmapPointer(), heapbase);;
+		TInt err = aMessage.Write(2, params);
+		if (KErrNone != err)
+			{
+			aPanicRequired = ETrue;
+			return err;
+			}
+		return ETrue;
+		}
+	return EFalse;
+	}
+
+
+/** Handler for EFbsMessFaceAttrib message
+ @param aMessage Input and output parameters
+ @param aPanicRequired Flag that is set to ETrue if a client panic is required
+ @return ETrue if successful, EFalse or any system-wide error code if not successful.
+	 An error code is only returned if aPanicRequired is set to ETrue.
+ */
+TInt CFbClient::HandleMesgFaceAttrib(const RMessage2& aMessage, TBool& aPanicRequired)
+	{
+	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), TopLevelStore()->FontConUniqueID()));
+	if(!fontptr)
+		{
+		aPanicRequired = ETrue;
+		return KErrArgument;
+		}
+	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
+
+	TPckgBuf<TOpenFontFaceAttrib> package;
+	if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
+		{
+		TInt ret = aMessage.Write(1,package);
+		if (ret == KErrNone)
+			{
+			return ETrue;
+			}
+		else
+			{
+			aPanicRequired = ETrue;
+			return ret;
+			}
+		}
+	return EFalse;
+	}
+
+
+/** Handler for EFbsMessHasCharacter message
+ @param aMessage Input parameters
+ @param aPanicRequired Flag that is set to ETrue if a client panic is required
+ @return ETrue if the font has the character, EFalse if the font does not have
+  the character, or any system-wide error code if not successful. An error code
+  is only returned if aPanicRequired is set to ETrue.
+ */
+TInt CFbClient::HandleMesgHasCharacter(const RMessage2& aMessage, TBool& aPanicRequired)
+	{
+	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), TopLevelStore()->FontConUniqueID()));
+	if(!fontptr)
+		{
+		aPanicRequired = ETrue;
+		return KErrArgument;
+		}
+	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
+
+	TInt ret = 0;
+	TRAPD(error, ret = bitmapFont->HasCharacterL(aMessage.Int1()));
+	if (error != KErrNone)
+		{
+		return EFalse;
+		}
+	return ret;
+	}
+
+
+/** Handler for EFbsMessShapeText message
+ @param aMessage Input and output parameters
+ @param aPanicRequired Flag that is set to ETrue if a client panic is required
+ @return An offset from the heap base where the pointer to the shape is located
+	if successful, otherwise 0 or any system-wide error code. An error code is
+	only returned if aPanicRequired is set to ETrue.
+ */
+TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
+	{
+	TInt error = KErrNone;
+	TShapeHeader* shape = 0;
+	TPckgBuf<TShapeMessageParameters> sp;
+	if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
+		{
+		aPanicRequired = ETrue;
+		return KErrArgument;
+		}
+
+	CFbTop* fbtop = TopLevelStore();
+	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
+	if(!fontptr)
+		{
+		aPanicRequired = ETrue;
+		return KErrArgument;
+		}
+	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
+
+	TInt inputTextLength = aMessage.GetDesLength(1);
+	if (inputTextLength < 0)
+		{
+		error = inputTextLength;
+		aPanicRequired = ETrue;
+		return error;
+		}
+	else
+		{
+		iTextToShape.Zero();
+		if (iTextToShape.MaxLength() < inputTextLength)
+			error = iTextToShape.ReAlloc(inputTextLength);
+		}
+	if (error == KErrNone)
+		{
+		error = aMessage.Read(1, iTextToShape);
+		if (error != KErrNone)
+			{
+			aPanicRequired = ETrue;
+			return error;
+			}
+		error = aMessage.Read(2, sp);
+		if (error != KErrNone)
+			{
+			aPanicRequired = ETrue;
+			return error;
+			}
+		TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
+		if (error == KErrNone)
+			{
+			// Convert the pointer to be passed back to the client to an offset from
+			// the heap base so that it can be recreated client side relative to the
+			// client's heap base
+			return PointerToOffset(shape, fbtop->HeapBase());
+			}
+		}
+	return 0;
+	}
+
+
+/** Handler for EFbsMessShapeDelete message
+ @param aMessage input and output parameters
+ @param aPanicRequired flag that is set to ETrue if a client panic is required
+ @return KErrNone if successful, otherwise a system wide error code
+	 An error code is only returned if aPanicRequired is set to ETrue.
+ */
+TInt CFbClient::HandleMesgShapeDelete(const RMessage2& aMessage, TBool& aPanicRequired)
+	{
+	CFbTop* fbtop = TopLevelStore();
+	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
+	if(!fontptr)
+		{
+		aPanicRequired = ETrue;
+		return KErrArgument;
+		}
+	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
+
+	// Combine the passed shape offset with the current heap base to get
+	// a valid pointer to a shape header for use in this process			
+	TShapeHeader* shapeheader = reinterpret_cast<TShapeHeader*>(OffsetToPointer(aMessage.Int1(), fbtop->HeapBase()));
+
+	bitmapFont->DeleteShape(iSessionHandle,shapeheader);
+	return KErrNone;
+	}
+
+
+void CFbClient::ProcFontMessage(const RMessage2& aMessage)
+	{
+	TInt ret = KErrUnknown;
+	TBool panicRequired = EFalse;
+
+	switch(aMessage.Function())
+		{
+		case EFbsMessFontDuplicate:
+			ret = HandleMesgFontDuplicate(aMessage, panicRequired);
+			break;
+
+		case EFbsMessGetNearestFontToDesignHeightInTwips:
+		case EFbsMessGetNearestFontToDesignHeightInPixels:
+		case EFbsMessGetNearestFontToMaxHeightInTwips:
+		case EFbsMessGetNearestFontToMaxHeightInPixels:
+			ret = HandleMesgGetNearestFont(aMessage, panicRequired);
+			break;
+
+		case EFbsMessGetFontById:
+			ret = HandleMesgGetFontById(aMessage, panicRequired);
+			break;
+
+		case EFbsMessInstallFontStoreFile:
+		case EFbsMessAddFontStoreFile:
+			ret = HandleMesgAddOrInstallFontFile(aMessage, panicRequired);
+			break;
+
+		case EFbsMessRemoveFontStoreFile:
+			ret = HandleMesgRemoveFontFile(aMessage);
+			break;
+
+		case EFbsMessRasterize:
+			ret = HandleMesgRasterize(aMessage, panicRequired);
+			break;
+
+		case EFbsMessFaceAttrib:
+			ret = HandleMesgFaceAttrib(aMessage, panicRequired);
+			break;
+
+		case EFbsMessHasCharacter:
+			ret = HandleMesgHasCharacter(aMessage, panicRequired);
+			break;
+
+		case EFbsMessShapeText:
+			ret = HandleMesgShapeText(aMessage, panicRequired);
+			break;
+
+		case EFbsMessShapeDelete:
+			ret = HandleMesgShapeDelete(aMessage, panicRequired);
+			break;
+
+		case EFbsMessSetTwipsHeight:
+			{
+			TInt localhandle=aMessage.Int0();
+			CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(localhandle, TopLevelStore()->FontConUniqueID()));
+			if(!fontptr)
+				{
+				panicRequired = ETrue;
+				ret = KErrArgument;
+				break;
+				}
+			fontptr->iHeightInTwips = aMessage.Int1();
+			ret = KErrNone;
+			break;	
+			}
+		case EFbsMessGetTwipsHeight:
+			{
+			TInt localhandle=aMessage.Int0();
+			CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(localhandle, TopLevelStore()->FontConUniqueID()));
+			if(!fontptr)
+				{
+				panicRequired = ETrue;
+				ret = KErrArgument;
+				break;
+				}
+			TPckgBuf<TInt> height;
+			height() = fontptr->iHeightInTwips;
+			ret = aMessage.Write(1,height);
+			if (KErrNone != ret)
+				{
+				panicRequired = ETrue;
+				}
+			break;
+			}
+		case EFbsSetSystemDefaultTypefaceName:
+			{
+			TBuf<KMaxTypefaceNameLength> fontTypefaceName;
+			ret = aMessage.GetDesLength(0);
+			if (ret < 0)
+				{
+				panicRequired = ETrue;
+				break;
+				}
+			if (ret <= KMaxTypefaceNameLength) // Size in characters i.e. 2 bytes for unicode
+				{
+				ret = aMessage.Read(0, fontTypefaceName);
+				if (ret == KErrNone)
+					{
+					TopLevelStore()->SetSystemDefaultTypefaceName(fontTypefaceName);
+					}
+				}
+			else
+				{
+				panicRequired = ETrue;
+				ret = KErrTooBig;
+				}
+
+			break;
+			}
+
+#ifdef _DEBUG
+		case EFbsMessSetDuplicateFail:
+			TInt argument =aMessage.Int0();
+			if (argument)
+				{
+				iFontDuplicateToFail = ETrue;
+				}
+			else
+				{
+				iFontDuplicateToFail = EFalse;
+				}
+			ret=KErrNone;
+			break;
+#endif
+		}
+
+	// either have a result or an error code to panic the client with
+	if (panicRequired)
+		{
+		aMessage.Panic(KFBSERVPanicCategory, ret);
+		}
+	else
+		{
+		if(!aMessage.IsNull())
+			{
+			aMessage.Complete(ret);
+			}		
+		}
+#ifdef _DEBUG
+	iRet=ret;
+#endif	
+	}
+
+void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
+	{
+	CBitmapObject* bmpptr=NULL;
+	TInt localhandle=0;
+	TInt ret=KErrUnknown;
+	switch(aMessage.Function())
+		{
+	case EFbsMessBitmapCreate:
+		{
+		TPckgBuf<TBmpSpec> bs;
+		ret = aMessage.Read(0,bs);
+		if(ret!=KErrNone)
+			{
+			aMessage.Panic(KFBSERVPanicCategory,ret);
+			return;
+			}
+			
+		TBmpSpec& bmpSpec = bs();	
+		
+		if(!TDisplayModeUtils::IsDisplayModeValid(bmpSpec.iDispMode))
+			{
+			aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
+			return;
+			}
+
+		// client uses iHandle to pass UID and iServerHandle to pass data size
+		TRAP(ret, bmpptr = TopLevelStore()->CreateBitmapL(bmpSpec.iSizeInPixels, bmpSpec.iDispMode, TUid::Uid(bmpSpec.iHandle), EFalse, bmpSpec.iServerHandle));
+		if(ret!=KErrNone)
+			break;
+		TRAP(ret,localhandle=iIx->AddL(bmpptr));
+		if(ret!=KErrNone)
+			{
+			bmpptr->Close();
+			break;
+			}
+		bmpSpec.iHandle=localhandle;
+		bmpSpec.iServerHandle = bmpptr->Handle();
+		bmpSpec.iAddressOffset=TInt(bmpptr->Address())-TopLevelStore()->HeapBase();
+		ret = aMessage.Write(0,bs);
+		if(ret!=KErrNone)
+			{
+			iIx->Remove(localhandle);
+			aMessage.Panic(KFBSERVPanicCategory,ret);
+			return;
+			}
+		iResourceCount++;
+		break;
+		}
+
+	case EFbsMessBitmapLoad:
+	case EFbsMessBitmapLoadFast:
+		{
+		TPckgBuf<TLoadBitmapArg> loadBitmapArg;
+		ret = aMessage.Read(1,loadBitmapArg);
+		if(ret!=KErrNone)
+			{
+			aMessage.Panic(KFBSERVPanicCategory,ret);
+			return;
+			}
+		const TInt32 id=loadBitmapArg().iBitmapId;
+		const TBool shareifloaded=loadBitmapArg().iShareIfLoaded;
+		const TUint fileOffset = loadBitmapArg().iFileOffset;
+		if(aMessage.Function() == EFbsMessBitmapLoad)
+			{
+			RFile file;
+			ret=file.AdoptFromClient(aMessage,2,3);
+			if (ret!=KErrNone)
+				{
+				break;
+				}
+			TFileName filename;
+			ret=file.FullName(filename);
+			if (ret!=KErrNone)
+				{
+				break;
+				}
+
+			if(shareifloaded)
+				{
+				TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset,&file, iSessionHandle));
+				}
+			else
+				{
+				TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, &file, iSessionHandle));
+				}
+			file.Close();
+			}
+		else
+			{
+			TFileName filename;
+			ret = aMessage.Read(2,filename);
+			if (ret!=KErrNone)
+				{
+				aMessage.Panic(KFBSERVPanicCategory,ret);
+				return;
+				}
+			_LIT(KZDrive, "z:");
+			if (filename.Left(2).CompareF(KZDrive))
+				{
+				// File is not in the Z: drive.
+				// So open the file and pass the file handle to LoadBitmapL() or ShareBitmapL() and close it afterwards.
+				// The reason is that the cache cannot be used for files that are writable,
+				// since they can't be kept open in the cache.
+				RFile file;
+				ret = file.Open(TopLevelStore()->FileSession(),filename,EFileShareReadersOnly);
+				if (ret!=KErrNone)
+					{
+					break;
+					}
+				if(shareifloaded)
+					{
+					TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset,&file, iSessionHandle));
+					}
+				else
+					{
+					TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, &file, iSessionHandle));
+					}
+				file.Close();
+				}
+			else
+				{
+				if(shareifloaded)
+					{
+					TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset, NULL, iSessionHandle));
+					}
+				else
+					{
+					TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, NULL, iSessionHandle));
+					}
+				}
+			}
+		if(ret!=KErrNone)
+			{
+			break;
+			}
+		TRAP(ret,localhandle=iIx->AddL(bmpptr));
+		if(ret!=KErrNone)
+			{
+			bmpptr->Close();
+			break;
+			}
+		TPckgBuf<TBmpHandles> handlebuffer;
+		handlebuffer().iHandle=localhandle;
+		handlebuffer().iServerHandle = bmpptr->Handle();
+		handlebuffer().iAddressOffset=TInt(bmpptr->Address())-TopLevelStore()->HeapBase();
+		ret = aMessage.Write(0,handlebuffer);
+		if(ret!=KErrNone)
+			{
+			iIx->Remove(localhandle);
+			aMessage.Panic(KFBSERVPanicCategory,ret);
+			return;
+			}
+		iResourceCount++;
+		break;
+		}
+	case EFbsMessBitmapResize:
+		{
+		localhandle=aMessage.Int0();
+		CFbTop* fbtop = TopLevelStore();
+		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
+		if(!bmpptr)
+			{
+			ret=KErrUnknown;
+			break;
+			}
+		ret = fbtop->GetCleanBitmap(bmpptr);
+		if (ret != KErrNone)
+			break;
+		TSize newsize(aMessage.Int1(),aMessage.Int2());
+ 		const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM();  //It must be set before the resizing is done.
+		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
+		CBitmapObject* newbmpptr = NULL;
+		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
+		if (ret != KErrNone)
+			break;
+		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
+		if (ret != KErrNone)
+			{
+			newbmpptr->Close();
+			break;
+			}
+ 		if (compressedInRam)
+			{
+			// if the header says PaletteCompression specify.
+			TBitmapfileCompressionScheme scheme = ERLECompression;
+			if (bmpptr->Address()->iHeader.iCompression == EGenericPaletteCompression)
+				scheme = EPaletteCompression;
+			ret = newbmpptr->Address()->CompressData(scheme); // re-compress
+			if (ret != KErrNone)
+				{
+				newbmpptr->Close();
+				break;
+				}
+			}
+		TInt newlocalhandle = 0;
+		TRAP(ret, newlocalhandle = iIx->AddL(newbmpptr));
+		if (ret != KErrNone)
+			{
+			newbmpptr->Close();
+			break;
+			}
+		ret = newbmpptr->Open();
+		if (ret != KErrNone)
+			{
+			iIx->Remove(newlocalhandle);
+			break;
+			}
+		bmpptr->SetCleanBitmap(newbmpptr);
+		if (bmpptr->AccessCount() >= 2)
+			fbtop->NotifyDirtyBitmap(*bmpptr, this);
+		iIx->Remove(localhandle);
+		TPckgBuf<TBmpHandles> handlebuffer;
+		handlebuffer().iHandle = newlocalhandle;
+		handlebuffer().iServerHandle = newbmpptr->Handle();
+		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
+		ret = aMessage.Write(3, handlebuffer);
+		if (ret != KErrNone)
+			{
+			iIx->Remove(newlocalhandle);
+			aMessage.Panic(KFBSERVPanicCategory, ret);
+			return;
+			}
+		break;
+		}
+	case EFbsMessBitmapDuplicate:
+		{
+		bmpptr = TopLevelStore()->FindBitmap(aMessage.Int0());
+		if (bmpptr == NULL)
+			{
+			ret=KErrUnknown;
+			break;
+			}
+		//coverity [check_return]
+		//coverity [unchecked_value]
+		TopLevelStore()->GetCleanBitmap(bmpptr);
+		ret = bmpptr->Open();
+		if (ret != KErrNone)
+			break;
+		TPckgBuf<TBmpHandles> handlebuffer;
+		TRAP(ret,localhandle=iIx->AddL(bmpptr));
+		if(ret!=KErrNone)
+			{
+			bmpptr->Close();
+			break;
+			}
+		handlebuffer().iHandle = localhandle;
+		handlebuffer().iServerHandle = bmpptr->Handle();
+		handlebuffer().iAddressOffset = TInt(bmpptr->Address()) - TopLevelStore()->HeapBase();
+		ret = aMessage.Write(1, handlebuffer);
+		if(ret!=KErrNone)
+			{
+			iIx->Remove(localhandle);
+			aMessage.Panic(KFBSERVPanicCategory,ret);
+			return;
+			}
+		iResourceCount++;
+		break;
+		}
+	case EFbsMessBitmapCompress:
+		{
+		localhandle = aMessage.Int0();
+		CFbTop* fbtop = TopLevelStore();
+		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
+		if(!bmpptr)
+			{
+			ret = KErrUnknown;
+			break;
+			}
+		ret = fbtop->GetCleanBitmap(bmpptr);
+		if (ret != KErrNone)
+			break;
+		const TSize size = bmpptr->Address()->SizeInPixels();
+		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
+		CBitmapObject* newbmpptr = NULL;
+		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
+		if (ret != KErrNone)
+			break;
+		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
+		if (ret != KErrNone)
+			{
+			newbmpptr->Close();
+			break;
+			}
+		ret = newbmpptr->Address()->CompressData((TBitmapfileCompressionScheme)aMessage.Int1());
+		if (ret != KErrNone)
+			{
+			newbmpptr->Close();
+			break;
+			}
+		TInt newlocalhandle = 0;
+		TRAP(ret, newlocalhandle = iIx->AddL(newbmpptr));
+		if (ret != KErrNone)
+			{
+			newbmpptr->Close();
+			break;
+			}
+		ret = newbmpptr->Open();
+		if (ret != KErrNone)
+			{
+			iIx->Remove(newlocalhandle);
+			break;
+			}
+		bmpptr->SetCleanBitmap(newbmpptr);
+		if (bmpptr->AccessCount() >= 2)
+			fbtop->NotifyDirtyBitmap(*bmpptr, this);
+		iIx->Remove(localhandle);
+		TPckgBuf<TBmpHandles> handlebuffer;
+		handlebuffer().iHandle = newlocalhandle;
+		handlebuffer().iServerHandle = newbmpptr->Handle();
+		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
+		ret = aMessage.Write(2, handlebuffer);
+		if (ret != KErrNone)
+			{
+			iIx->Remove(newlocalhandle);
+			aMessage.Panic(KFBSERVPanicCategory, ret);
+			return;
+			}
+		break;
+		}
+	case EFbsMessBitmapBgCompress:
+		{
+		localhandle = aMessage.Int0();
+		TBitmapfileCompressionScheme scheme = (TBitmapfileCompressionScheme)aMessage.Int1();
+		TBool async = aMessage.Int2();
+		CFbTop* fbtop = TopLevelStore();
+		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
+		if(!bmpptr)
+			{
+			ret = KErrUnknown;
+			break;
+			}
+		ret = fbtop->GetCleanBitmap(bmpptr);
+		if (ret != KErrNone)
+			{
+			if (!async)
+				ret = KErrNone;
+			break;
+			}
+		ret = bmpptr->Address()->CheckBackgroundCompressData();
+		if (KErrNone == ret)
+			{
+			ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
+			if (ret == KErrNone && async)
+				return; // do not complete the client's request - that will be done by the background compression thread
+			}
+		if (KErrAlreadyExists == ret)
+			ret = KErrNone;
+		break;
+		}
+	case EFbsMessBitmapClean:
+		{
+		TInt localhandle = aMessage.Int0();
+		CFbTop* fbtop = TopLevelStore();
+		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
+		if(!bmpptr)
+			{
+			ret = KErrUnknown;
+			break;
+			}
+		ret = fbtop->GetCleanBitmap(bmpptr);
+		if (ret != KErrNone)
+			break;
+		ret = bmpptr->Open();
+		if (ret != KErrNone)
+			break;
+		TInt cleanlocalhandle = 0;
+		TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
+		if (ret != KErrNone)
+			{
+			bmpptr->Close();
+			break;
+			}
+		iIx->Remove(localhandle);
+		TPckgBuf<TBmpHandles> handlebuffer;
+		handlebuffer().iHandle = cleanlocalhandle;
+		handlebuffer().iServerHandle = bmpptr->Handle();
+		handlebuffer().iAddressOffset = TInt(bmpptr->Address()) - fbtop->HeapBase();
+		ret = aMessage.Write(1, handlebuffer);
+		if (ret != KErrNone)
+			{
+			iIx->Remove(cleanlocalhandle);
+			aMessage.Panic(KFBSERVPanicCategory, ret);
+			return;
+			}
+		break;
+		}
+	case EFbsGetAllBitmapHandles:
+		{
+		ret = TopLevelStore()->GetAllBitmapHandles(aMessage);		
+		break;	
+		}	
+
+	case EFbsMessBitmapNotifyDirty:
+		{
+		if (iHelper == NULL)
+			{
+			iHelper = new TFbClientHelper(*this);
+			if (iHelper == NULL)
+				{
+				ret = KErrNoMemory;
+				break;
+				}
+			TopLevelStore()->AddClientHelper(*iHelper);
+			}
+		if (!iHelper->iMessage.IsNull())
+			{
+			aMessage.Panic(KFBSERVPanicCategory, KErrAlreadyExists);
+			return;
+			}
+		if (!iHelper->iDirty)
+			{
+			iHelper->iMessage = aMessage;
+			return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
+			}
+		ret = KErrNone;
+		iHelper->iDirty = EFalse;
+		}
+		break;
+	case EFbsMessBitmapCancelNotifyDirty:
+		{
+		if (iHelper != NULL && !iHelper->iMessage.IsNull())
+			iHelper->iMessage.Complete(KErrCancel);
+		ret = KErrNone;
+		}
+		break;
+		}
+		
+	if(!aMessage.IsNull())
+		{
+		aMessage.Complete(ret);
+		}
+	
+#ifdef _DEBUG
+	iRet=ret;
+#endif		
+	}
+
+void CFbClient::NotifyDirtyBitmap(CBitmapObject& aBmpObj)
+	{
+	if (iHelper != NULL && iIx->At(&aBmpObj) != KErrNotFound)
+		{
+		iHelper->iDirty = ETrue;
+		if (!iHelper->iMessage.IsNull())
+			{
+			iHelper->iMessage.Complete(KErrNone);
+			iHelper->iDirty = EFalse;
+			}
+		}
+	}
+
+void CFbClient::AddFontFileIndexL(TUid aId)
+	{
+	TInt count=iFontFileIndex->Count();
+	for (TInt index=0;index<count;index++)
+		{
+		if (iFontFileIndex->At(index).iUid==aId)
+			{
+			iFontFileIndex->At(index).iAccessCount++;
+			TopLevelStore()->FontStore()->RemoveFile(aId);
+			return;
+			}
+		}
+
+	TFontFileIndex fontFileIndex;
+	fontFileIndex.iUid=aId;
+	fontFileIndex.iAccessCount=1;
+	iFontFileIndex->AppendL(fontFileIndex);
+	}
+
+void CFbClient::RemoveFontFileIndex(TUid aId)
+	{
+	TInt count=iFontFileIndex->Count();
+	for (TInt index=0;index<count;index++)
+		{
+		TFontFileIndex* fontFileIndex=&iFontFileIndex->At(index);
+		if (fontFileIndex->iUid==aId)
+			{
+			fontFileIndex->iAccessCount--;
+			if (fontFileIndex->iAccessCount<1)
+				{
+				TopLevelStore()->FontStore()->RemoveFile(fontFileIndex->iUid);
+				iFontFileIndex->Delete(index);
+				}
+			return;
+			}
+		}
+	// not found - must be an installed file or rubbish, so try anyway
+	TopLevelStore()->FontStore()->RemoveFile(aId);
+	}
+
+void CFbClient::Disconnect(const RMessage2 &aMessage)
+	{
+	// if any bitmaps are in the background compression queue with a to-be-completed RMessage2 from this session,
+	// the RMessage2 must be completed now as it is only possible to complete messages on existing sessions
+	TopLevelStore()->BackgroundCompression()->CompleteOutstandingRequests(this);
+
+	// if there is a to-be-completed request for dirty bitmap notification complete it now
+	if (iHelper)
+		{
+		if (!iHelper->iMessage.IsNull())
+			iHelper->iMessage.Complete(KErrDisconnected);
+		iHelper->Deque();
+		delete iHelper;
+		iHelper = NULL;
+		}
+
+	// Clear the mbm file store cache resources that corresponds to this session
+	TopLevelStore()->CloseFileStores(iSessionHandle);
+
+	CSession2::Disconnect(aMessage);
+	}
+
+#ifdef _DEBUG
+void CFbClient::ProcMemMessage(const RMessage2 &aMessage)
+	{
+	TInt ret=KErrNone;
+	TInt parameterForFunctionCall;
+	TInt cells = User::Heap().Available(parameterForFunctionCall);
+	switch(aMessage.Function())
+		{
+		case EFbsMessSetHeapFail:
+			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
+				{
+				iOwnHeapFailNumber=aMessage.Int1();
+				}
+			else
+				{
+				iSharedHeapFailNumber=aMessage.Int1();
+				}
+			break;
+		case EFbsMessHeapCount:
+			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
+				{
+				ret=User::CountAllocCells();
+				}
+			else
+				{
+				ret=iHeap->Count();
+				}	
+			break;
+		case EFbsMessSetHeapReset:
+			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
+				{
+				iOwnHeapFailNumber=-1;
+				}
+			else
+				{
+				iSharedHeapFailNumber=-1;
+				}				
+			break;
+		case EFbsMessSetHeapCheck:
+			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
+				{
+				iOwnHeapCheckFlip=ETrue;
+				}
+			else
+				{
+				iHeapCheckFlip=ETrue;
+				}
+			break;
+		case EFbsMessHeap:
+			ret=(TInt)iHeap;
+			break;			
+		}
+	aMessage.Complete(ret);
+	iRet=ret;
+	}
+#endif