--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fbs/fontandbitmapserver/sfbs/SERVER.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,591 @@
+// 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 "FBSVER.H"
+#include "SERVER.H"
+#include "BackGroundCompression.h"
+#include "linkedfonts.h"
+#include "BitwiseBitmap.inl"
+
+const TInt KFbsPriority = 0;
+
+// Setup security policies
+const TInt KRanges[] =
+ {
+ 0,
+ EFbsMessShutdown,
+ EFbsMessClose,
+ EFbsSetSystemDefaultTypefaceName,
+ EFbsGetAllBitmapHandles,
+ EFbsMessUnused1,
+ EFbsMessUnused2,
+ EFbsMessRegisterLinkedTypeface,
+ EFbsMessFetchLinkedTypeface,
+ EFbsMessUpdateLinkedTypeface,
+ };
+const TUint KRangeCount = sizeof(KRanges)/sizeof(TInt);
+const TUint8 KElementsIndex[KRangeCount] =
+ {
+ 0,
+ 3, // For EFbsMessShutdown
+ 0,
+ 1, // For EFbsSetSystemDefaultTypefaceName
+ 2, // For EFbsGetAllBitmapHandles
+ 0, // ECapability_None for EFbsMessUnused1
+ 0, // ECapability_None for EFbsMessUnused2 and beyond
+ 1, // ECapabilityWriteDeviceData for EFbsMessRegisterLinkedTypeface
+ 2, // ECapabilityReadDeviceData for EFbsMessFetchLinkedTypeface
+ 1, // ECapabilityWriteDeviceData for EFbsMessUpdateLinkedTypeface
+ };
+const CPolicyServer::TPolicyElement KElements[] =
+ {
+ {_INIT_SECURITY_POLICY_C1(ECapability_None), CPolicyServer::EFailClient},
+ {_INIT_SECURITY_POLICY_C1(ECapabilityWriteDeviceData), CPolicyServer::EFailClient},
+ {_INIT_SECURITY_POLICY_C1(ECapabilityReadDeviceData), CPolicyServer::EFailClient},
+ {_INIT_SECURITY_POLICY_C1(ECapabilityPowerMgmt), CPolicyServer::EFailClient},
+ };
+const CPolicyServer::TPolicy KFbsPolicy =
+ {
+ CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass
+ KRangeCount,
+ KRanges,
+ KElementsIndex,
+ KElements,
+ };
+
+CFontBitmapServer::CFontBitmapServer():
+ CPolicyServer(KFbsPriority, KFbsPolicy),
+ iConnectionId(0),
+ iTopLevelStore(NULL)
+ {
+ }
+
+CFontBitmapServer::~CFontBitmapServer()
+ {
+ delete iTopLevelStore;
+ iTopLevelStore = NULL; // so that CFBClient::~CFbClient can avoid using this pointer;
+ // it may be called inside CFontBitmapServer::~CFontBitmapServer
+ }
+
+CFontBitmapServer* CFontBitmapServer::NewL()
+ {
+ CFontBitmapServer* fbs=new(ELeave) CFontBitmapServer;
+ CleanupStack::PushL(fbs);
+ fbs->iTopLevelStore=CFbTop::NewL();
+
+ // If fbserv data paging is configured as unpaged, automatically pin client descriptors
+ if(!RProcess().DefaultDataPaged())
+ {
+ fbs->SetPinClientDescriptors(ETrue);
+ }
+
+ fbs->StartL(KFBSERVGlobalThreadName);
+ CleanupStack::Pop();
+ return(fbs);
+ }
+
+CFbTop* CFontBitmapServer::TopLevelStore()
+ {
+ return(iTopLevelStore);
+ }
+CSession2* CFontBitmapServer::NewSessionL(const TVersion& aVersion,const RMessage2& /*aMessage*/ ) const
+ {
+ TVersion v(KFbsMajorVersionNumber,KFbsMinorVersionNumber,KFbsBuildVersionNumber);
+ if(!User::QueryVersionSupported(v,aVersion))
+ User::Leave(KErrNotSupported);
+
+ CSession2* pSession2 = CFbClient::NewL(iTopLevelStore->Heap());
+ return pSession2;
+ }
+
+TInt CFontBitmapServer::Init()
+ {
+ return(iConnectionId++);
+ }
+
+
+TInt CFontBitmapServer::HandleMesgTypefaceSupport(const RMessage2& aMessage, TBool& aClientPanicRequired)
+ {
+ TTypefaceSupport tfi;
+ TPckgBuf<TTypefaceSupport> ttipckg(tfi);
+ TPckgBuf<TSize> pixelSize;
+ TInt index=aMessage.Int0();
+ TInt limit=iTopLevelStore->FontStore()->NumTypefaces();
+ if(index<0 || index>limit)
+ {
+ return KErrArgument;
+ }
+ TInt ret = aMessage.Read(2, pixelSize);
+ if (ret != KErrNone)
+ {
+ return ret;
+ }
+ iTopLevelStore->FontStore()->iKPixelHeightInTwips = pixelSize().iHeight;
+ iTopLevelStore->FontStore()->iKPixelWidthInTwips = pixelSize().iWidth;
+ iTopLevelStore->FontStore()->TypefaceSupport(ttipckg(),index);
+ ret = aMessage.Write(1,ttipckg);
+ if(ret!=KErrNone)
+ {
+ aClientPanicRequired = ETrue;
+ }
+ return ret;
+ }
+
+
+TInt CFontBitmapServer::HandleMesgFontHeight(const RMessage2& aMessage, TBool aInTwips)
+ {
+ TInt typefaceindex = aMessage.Int0();
+ TInt fontsize = aMessage.Int1();
+
+ if(typefaceindex < 0)
+ {
+ aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
+ return KErrArgument;
+ }
+
+ // pixel size (used to be set in a separate call)
+ TPckgBuf<TSize> size;
+ TInt ret = aMessage.Read(2, size);
+ if (ret != KErrNone)
+ {
+ return ret;
+ }
+
+ if(size().iHeight <= 0 || size().iWidth < 0)
+ {
+ aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
+ return KErrArgument;
+ }
+
+ iTopLevelStore->FontStore()->iKPixelHeightInTwips = size().iHeight;
+ iTopLevelStore->FontStore()->iKPixelWidthInTwips = size().iWidth;
+ if (aInTwips)
+ {
+ return iTopLevelStore->FontStore()->FontHeightInTwips(typefaceindex,fontsize);
+ }
+ else
+ {
+ return iTopLevelStore->FontStore()->FontHeightInPixels(typefaceindex,fontsize);
+ }
+ }
+
+
+#ifdef _DEBUG
+//aRet is used in debug builds to allow the server to know if the call was successful.
+//On success there should be no panics from out of memory testing, since memory
+//may have been genuinely allocated.
+void CFontBitmapServer::ProcMessage(const RMessage2& aMessage, TInt aSession, TInt& aRet)
+#else
+void CFontBitmapServer::ProcMessage(const RMessage2& aMessage, TInt aSession)
+#endif
+ {
+ TInt ret=KErrNone;
+ TBool clientPanicRequired = EFalse;
+#ifdef _DEBUG
+ TInt num=0;
+#endif
+ switch (aMessage.Function())
+ {
+ case EFbsMessShutdown:
+ CActiveScheduler::Stop();
+ break;
+ case EFbsMessNumTypefaces:
+ ret=iTopLevelStore->FontStore()->NumTypefaces();
+ break;
+ case EFbsMessTypefaceSupport:
+ ret = HandleMesgTypefaceSupport(aMessage, clientPanicRequired);
+ break;
+
+ case EFbsMessFontHeightInTwips:
+ ret = HandleMesgFontHeight(aMessage, ETrue);
+ break;
+
+ case EFbsMessFontHeightInPixels:
+ ret = HandleMesgFontHeight(aMessage, EFalse);
+ break;
+
+ case EFbsMessSetPixelHeight:
+ iTopLevelStore->FontStore()->iKPixelWidthInTwips=aMessage.Int0();
+ iTopLevelStore->FontStore()->iKPixelHeightInTwips=aMessage.Int1();
+ break;
+#ifdef _DEBUG
+ case EFbsMessDefaultAllocFail:
+ num=aMessage.Int0();
+ if(num) __UHEAP_FAILNEXT(num);
+ else __UHEAP_RESET;
+ break;
+ case EFbsMessDefaultMark:
+ __UHEAP_MARK;
+ break;
+ case EFbsMessDefaultMarkEnd:
+ num=aMessage.Int0();
+ if(num) __UHEAP_MARKENDC(num);
+ else __UHEAP_MARKEND;
+ break;
+ case EFbsMessUserAllocFail:
+ num=aMessage.Int0();
+ if(num) __RHEAP_FAILNEXT(iTopLevelStore->Heap(),num);
+ else __RHEAP_RESET(iTopLevelStore->Heap());
+ break;
+ case EFbsMessUserMark:
+ __RHEAP_MARK(iTopLevelStore->Heap());
+ break;
+ case EFbsMessUserMarkEnd:
+ num=aMessage.Int0();
+ if(num) __RHEAP_MARKENDC(iTopLevelStore->Heap(),num);
+ else __RHEAP_MARKEND(iTopLevelStore->Heap());
+ break;
+#endif
+ case EFbsMessHeapCheck:
+ iTopLevelStore->Heap()->Check();
+ User::Heap().Check();
+ break;
+ case EFbsMessSetDefaultGlyphBitmapType:
+ iTopLevelStore->FontStore()->SetDefaultBitmapType((TGlyphBitmapType)aMessage.Int0());
+ break;
+ case EFbsMessGetDefaultGlyphBitmapType:
+ ret = iTopLevelStore->FontStore()->DefaultBitmapType();
+ break;
+ case EFbsMessFontNameAlias:
+ TRAP(ret, iTopLevelStore->SetFontNameAliasL(aMessage));
+ break;
+ case EFbsMessGetHeapSizes:
+ TRAP(ret, GetHeapSizesL(aMessage));
+ break;
+ case EFbsMessDefaultLanguageForMetrics:
+ iTopLevelStore->SetDefaultLanguageForMetrics(aMessage);
+ break;
+ case EFbsCompress:
+ iTopLevelStore->BackgroundCompression()->CompressAll();
+ break;
+ case EFbsMessRegisterLinkedTypeface:
+ {
+ TPckgBuf<TLinkedTypefaceSpecificationArgs> buf;
+ ret=aMessage.Read(0,buf);
+ if (ret==KErrNone)
+ {
+ //Id used by original font linking; now unused.
+ TInt id;
+ ret=iTopLevelStore->FontStore()->CreateLinkedTypeface(buf(),aSession,id);
+ }
+ }
+ break;
+ case EFbsMessFetchLinkedTypeface:
+ {
+ TBuf<KMaxTypefaceNameLength> name;
+ ret = aMessage.GetDesLength(0);
+
+ if (ret < 0)
+ break;
+
+ if (ret > KMaxTypefaceNameLength)
+ {
+ clientPanicRequired = ETrue;
+ ret = KErrTooBig;
+ break;
+ }
+
+ ret = aMessage.Read(0,name);
+
+ TLinkedTypefaceSpecificationArgs spec;
+
+ spec.iName = name;
+
+ if (ret==KErrNone)
+ {
+ TRAP(ret, iTopLevelStore->FontStore()->GetLinkedTypefaceL(spec));
+
+ if (ret == KErrNone)
+ {
+ TPckgBuf<TLinkedTypefaceSpecificationArgs> specArgs = spec;
+ ret = aMessage.Write(2,specArgs);
+ }
+ }
+ }
+ break;
+ case EFbsMessUpdateLinkedTypeface:
+ {
+ TPckgBuf<TLinkedTypefaceSpecificationArgs> buf;
+ ret=aMessage.Read(0,buf);
+ if (ret==KErrNone)
+ {
+ TRAP(ret, iTopLevelStore->FontStore()->UpdateLinkedTypefaceL(buf()));
+ }
+ }
+ break;
+ }
+
+ if (clientPanicRequired)
+ {
+ aMessage.Panic(KFBSERVPanicCategory,ret);
+ }
+ else
+ {
+ if(!aMessage.IsNull())
+ {
+ aMessage.Complete(ret);
+ }
+ }
+
+#ifdef _DEBUG
+ aRet=ret;
+#endif
+ }
+
+/**
+Returns the current sizes of the FBServ default heap, the heap for large bitmaps,
+and the heap for small bitmaps.
+
+Not supported in release builds.
+
+@internalComponent
+@test
+@param aMessage Encapsulates references to integers supplied by the caller, which will on return contain the sizes of the default heap, heap for small bitmaps, and heap for large bitmaps.
+@leave KErrNotSupported when used in release mode.
+*/
+#ifdef _DEBUG
+void CFontBitmapServer::GetHeapSizesL(const RMessage2& aMessage)
+ {
+ TPckgBuf<THeapSizes> data;
+ TInt defaultHeapSize;
+ TInt smallBmpHeapSize;
+ TInt bigBmpHeapSize;
+
+ User::Heap().AllocSize(defaultHeapSize);
+ bigBmpHeapSize = iTopLevelStore->iLargeBitmapChunk.Size();
+ iTopLevelStore->Heap()->AllocSize(smallBmpHeapSize);
+
+ data().iDefault = defaultHeapSize;
+ data().iBig = bigBmpHeapSize;
+ data().iSmall = smallBmpHeapSize;
+
+ aMessage.WriteL(0, data);
+ }
+#else
+void CFontBitmapServer::GetHeapSizesL(const RMessage2&)
+ {
+ User::Leave(KErrNotSupported);
+ }
+#endif
+
+
+CFontObject::CFontObject(CFontStore* aFontStore):
+ CObject(),
+ iAddressPointer(NULL),
+ iFontStore(aFontStore)
+ {
+ }
+
+CFontObject::~CFontObject()
+ {
+ if (AccessCount()==1)
+ Dec();
+ iFontStore->ReleaseFont(iAddressPointer);
+ }
+
+// CBitmapObject constructor - takes ownership of aBmp
+CBitmapObject::CBitmapObject(CFbTop& aFbTop, CBitwiseBitmap* aBmp):
+ CObject(),
+ iFbTop(&aFbTop),
+ iAddressPointer(aBmp)
+ {
+ __ASSERT_DEBUG(iAddressPointer, User::Invariant());
+ }
+
+/** Second-phase constructor of reference counting objects for bitmaps.
+Adds the CBitmapObject to the bitmap object container and, if it is not a
+replacement for a dirty bitmap, assigns a server-wide handle to it and adds
+it to the server's bitmap index. When a replacement bitmap is attached to
+the corresponding dirty bitmap with a call to SetCleanBitmap(), then it is
+assigned the same server-wide handle as the bitmap to be replaced.
+
+@param aReplacement If ETrue the bitmap is being created as a replacement
+ for a bitmap being made dirty by a resize or compress operation.
+@internalComponent
+*/
+void CBitmapObject::ConstructL(TBool aReplacement)
+ {
+ iFbTop->iBitmapCon->AddL(this);
+ if (!aReplacement)
+ {
+ iHandle = reinterpret_cast<TInt>(this);
+ while (iFbTop->iBitmapObjectIndex.FindInOrder(this, Compare) != KErrNotFound)
+ ++iHandle;
+ User::LeaveIfError(iFbTop->iBitmapObjectIndex.InsertInOrder(this, Compare));
+ }
+ }
+
+void CleanupBitmapObject(TAny* aPtr)
+ {
+ CBitmapObject* ptr = static_cast<CBitmapObject*>(aPtr);
+ ptr->Close();
+ }
+
+/** Create a reference counting object for a new bitmap.
+
+@param aFbTop Reference to the CFbTop singleton.
+@param aBmp Bitmap to be attached to the new reference counting object.
+ The bitmap must have been pushed on the clean-up stack and it will be
+ popped out of the stack by this function. Ownership will be transferred
+ to the reference counting object.
+@param aReplacement If ETrue the bitmap is being created as a replacement
+ for a bitmap being made dirty by a resize or compress operation.
+@internalComponent
+*/
+CBitmapObject* CBitmapObject::NewL(CFbTop& aFbTop, CBitwiseBitmap* aBmp, TBool aReplacement)
+ {
+ CBitmapObject* bmpObj = new(ELeave) CBitmapObject(aFbTop, aBmp);
+ CleanupStack::Pop(aBmp); // aBmp is owned now by bmpObj
+ TCleanupItem bitmapObjectCleanupItem(CleanupBitmapObject, bmpObj);
+ CleanupStack::PushL(bitmapObjectCleanupItem);
+ bmpObj->ConstructL(aReplacement);
+ CleanupStack::Pop(bmpObj);
+ return bmpObj;
+ }
+
+CBitmapObject::~CBitmapObject()
+ {
+ iFbTop->BackgroundCompression()->RemoveFromCompressionQueue(this);
+ // the associated clean bitmap object cannot possibly be now in the background compression queue
+ if (iHandle)
+ {
+ if (Owner() == NULL)
+ {
+ TInt index = iFbTop->iBitmapObjectIndex.FindInOrder(this, Compare);
+ if (index != KErrNotFound)
+ {
+ if (iCleanBitmap)
+ iFbTop->iBitmapObjectIndex[index] = iCleanBitmap;
+ else
+ iFbTop->iBitmapObjectIndex.Remove(index);
+ }
+ }
+ if (iCleanBitmap != NULL)
+ {
+ iCleanBitmap->SetOwner(NULL);
+ iCleanBitmap->Close();
+ }
+ }
+ delete iAddressPointer;
+ }
+
+void CBitmapObject::SetCleanBitmap(CBitmapObject* aNewBmpObj)
+ {
+ __ASSERT_DEBUG(iHandle, User::Invariant());
+ __ASSERT_DEBUG(iCleanBitmap == NULL, User::Invariant());
+ __ASSERT_DEBUG(aNewBmpObj->Owner() == NULL, User::Invariant());
+ __ASSERT_DEBUG(aNewBmpObj->iHandle == 0, User::Invariant());
+ __ASSERT_DEBUG(aNewBmpObj->iCleanBitmap == NULL, User::Invariant());
+ iCleanBitmap = aNewBmpObj;
+ aNewBmpObj->SetOwner(this);
+ aNewBmpObj->iHandle = iHandle;
+ iAddressPointer->iSettings.SetDirtyBitmap();
+ aNewBmpObj->iAddressPointer->Extra()->iSerialNumber = iAddressPointer->Extra()->iSerialNumber;
+ aNewBmpObj->iAddressPointer->Extra()->iTouchCount = iAddressPointer->Extra()->iTouchCount + 1;
+ }
+
+void CBitmapObject::Close()
+ {
+ if (iCleanBitmap != NULL && Owner() != NULL && AccessCount() == 2)
+ {
+ static_cast<CBitmapObject*>(Owner())->iCleanBitmap = iCleanBitmap;
+ iCleanBitmap->SetOwner(Owner());
+ iHandle = 0;
+ Dec();
+ }
+ CObject::Close();
+ }
+
+TInt CBitmapObject::Compare(const CBitmapObject& aBmpObj1, const CBitmapObject& aBmpObj2)
+ {
+ return aBmpObj1.iHandle - aBmpObj2.iHandle;
+ }
+
+TInt CBitmapObject::Compare(const TInt* aHandle, const CBitmapObject& aBmpObj)
+ {
+ return *aHandle - aBmpObj.iHandle;
+ }
+
+// CSharedBitmapObject constructor - takes ownership of aBmp and aKey
+CSharedBitmapObject::CSharedBitmapObject(CFbTop& aFbTop, CBitwiseBitmap* aBmp, TDesC* aKey):
+ CBitmapObject(aFbTop, aBmp),
+ iKey(aKey),
+ iNext(NULL)
+ {
+ __ASSERT_DEBUG(iKey, User::Invariant());
+ }
+
+/** Second-phase constructor of reference counting objects for bitmaps
+loaded to share from a file. Adds the CSharedBitmapObject to the bitmap
+object container, assigns a server-wide handle to it and adds it to the
+server's bitmap index and to the server's shared bitmap hash map.
+
+@param aHash Hash value of the key associated with the bitmap.
+@internalComponent
+*/
+void CSharedBitmapObject::ConstructL(TUint aHash)
+ {
+ CBitmapObject::ConstructL(EFalse);
+ iFbTop->iSharedBitmapObjectHashMap.Insert(*this, aHash);
+ }
+
+/** Create a reference counting object for a bitmap loaded to share from a file.
+
+@param aFbTop Reference to the CFbTop singleton.
+@param aBmp Bitmap to be attached to the new reference counting object.
+ The bitmap must have been pushed on the clean-up stack and it will be
+ popped out of the stack by this function. Ownership will be transferred
+ to the reference counting object.
+@param aKey Key associated with the bitmap. The key must have been pushed on
+ the clean-up stack and it will be popped out of the stack by this function.
+ Ownership will be transferred to the reference counting object.
+@param aHash Hash value of the key associated with the bitmap.
+@internalComponent
+*/
+CSharedBitmapObject* CSharedBitmapObject::NewL(CFbTop& aFbTop, CBitwiseBitmap* aBmp, TDesC* aKey, TUint aHash)
+ {
+ CSharedBitmapObject* bmpObj = new(ELeave) CSharedBitmapObject(aFbTop, aBmp, aKey);
+ CleanupStack::Pop(2, aKey); // aBmp and aKey are owned now by bmpObj
+ TCleanupItem bitmapObjectCleanupItem(CleanupBitmapObject, bmpObj);
+ CleanupStack::PushL(bitmapObjectCleanupItem);
+ bmpObj->ConstructL(aHash);
+ CleanupStack::Pop(bmpObj);
+ return bmpObj;
+ }
+
+CSharedBitmapObject::~CSharedBitmapObject()
+ {
+ iFbTop->iSharedBitmapObjectHashMap.Remove(*this);
+ delete iKey;
+ }
+
+// Constructs a single key object from constituent parts that uniquely identify a bitmap
+HBufC* CSharedBitmapObject::KeyLC(const TDesC& aFileName, TInt aId, const TTime& aModTime)
+ {
+ static const TInt K16BitSizeOfTInt = sizeof(TInt) /sizeof(TUint16);
+ static const TInt K16BitSizeOfTTime = sizeof(TTime)/sizeof(TUint16);
+
+ HBufC* key = HBufC::NewLC(K16BitSizeOfTInt + K16BitSizeOfTTime + aFileName.Length());
+
+ TPtr keyPtr = key->Des();
+
+ keyPtr.Append(reinterpret_cast<const TUint16*>(&aId), K16BitSizeOfTInt);
+ keyPtr.Append(reinterpret_cast<const TUint16*>(&aModTime), K16BitSizeOfTTime);
+ keyPtr.Append(aFileName);
+
+ return key;
+ }