Update contrib.
1 // Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
19 #include <graphics/fbsoogmmessage.h>
20 #include "FbsMessage.H"
22 #include "BackGroundCompression.h"
23 #include <shapeinfo.h>
24 #include <graphics/shaperparams.h>
25 #include "glyphatlas.h"
26 #include "OstTraceDefinitions.h"
28 #ifdef OST_TRACE_COMPILER_IN_USE
29 #include "FBSCLITraces.h"
34 Bitwise mask that sets the MSB to indicate to a font rasterizer
35 that a code is a glyphcode and not a character code
37 const TUint32 KTreatAsGlyphCodeFlag = 1UL << 31;
39 /** Helper function for converting a pointer to an offset from the passed
40 heap base. Use OffsetToPointer() to convert the returned offset back to a
42 @param aAny A pointer to be converted to an offset.
43 @param aHeapBase The heap base of the current process.
44 @return An offset representing the passed pointer that can be converted
45 back to a pointer using the function OffsetToPointer().
46 @see OffsetToPointer()
48 LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
51 if (aAny && aHeapBase)
53 offset = reinterpret_cast<TInt>(aAny) - aHeapBase;
58 /** Helper function for converting an offset (that was calculated using
59 PointerToOffset()) back to a pointer relative to the passed heap base.
60 @param aOffset The offset to be converted to a pointer.
61 @param aHeapBase The heap base of the current process.
62 @return A pointer relative to the passed heap base.
63 @see PointerToOffset()
65 LOCAL_C TAny* OffsetToPointer(TInt aOffset, TInt aHeapBase)
67 if (aOffset && aHeapBase)
69 return reinterpret_cast<TAny*>(aOffset + aHeapBase);
74 CFbClient::CFbClient(RHeap* aHeap):
78 ,iOwnHeapFailNumber(-1),
79 iSharedHeapFailNumber(-1)
84 CFbClient* CFbClient::NewL(RHeap* aHeap)
86 CFbClient* self = new (ELeave) CFbClient(aHeap);
87 CleanupStack::PushL(self);
89 CleanupStack::Pop(); // self;
94 Two-phase constructor.
95 @leave KErrNoMemory if TOpenFontGlyphData construction failed.
97 void CFbClient::ConstructL()
99 iOpenFontGlyphData = TOpenFontGlyphData::New(iHeap, 4 * 1024);
100 if (!iOpenFontGlyphData)
102 User::Leave(KErrNoMemory);
106 CFbClient::~CFbClient()
109 Don't call any CFontStore functions if CFbClient::NewL has left, or if FBSERV has already deleted the
110 font store, which happens in test programs like TFBS when FBSERV is closed before the client(s).
112 CFontStore* font_store = NULL;
113 CFbTop* fbTop = TopLevelStore();
116 font_store = fbTop->FontStore();
121 font_store->DeleteSessionCache(iSessionHandle);
122 font_store->CleanupCacheOnFbsSessionTermination(iSessionHandle);
124 // If the font store doesn't exist, neither will the shared heap owned by FBSERV.
125 iHeap->Free(iOpenFontGlyphData);
128 // delete fonts held by the client
131 // delete font files held by the client
134 TInt count = iFontFileIndex->Count();
135 for (TInt index = 0;index < count; index++)
139 font_store->RemoveFile(iFontFileIndex->At(0).iUid);
141 iFontFileIndex->Delete(0);
143 delete iFontFileIndex;
146 // Close the buffer used to hold the text that needs shaping.
147 iTextToShape.Close();
149 for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
151 iGlyphImagesInTransit[i].Close();
153 iGlyphImagesInTransit.Close();
156 void CFbClient::Init(TUint aConnectionHandle)
158 iConnectionHandle=aConnectionHandle;
161 void CFbClient::CreateL()
163 iIx=CObjectIx::NewL();
164 iFontFileIndex=new(ELeave) CArrayFixFlat<TFontFileIndex>(1);
167 CFontBitmapServer* CFbClient::FontBitmapServer()
169 return((CFontBitmapServer*)Server());
172 CFbTop* CFbClient::TopLevelStore()
174 CFontBitmapServer* server = FontBitmapServer();
177 return server->TopLevelStore();
185 void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
187 CBitmapFont* font=aFontObjPtr->iAddressPointer;
188 aFontInfo.iHandle = aHandle;
189 aFontInfo.iServerHandle=(TInt)aFontObjPtr;
190 aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
193 void CFbClient::ServiceL(const RMessage2& aMessage)
197 TBool resetOwnHeap=EFalse;
198 TBool resetSharedHeap=EFalse;
200 //the memory tests have been mostly written to have start and end memory
201 //function calls (or macros) at the start of this function call (ServiceL)
202 //and the matching call (or macro) is at the end of this function.
204 if (iOwnHeapFailNumber!=-1)
206 //if this not -1 then know to set the heap to fail on
207 //the given number of allocations
210 __UHEAP_SETFAIL(RHeap::EDeterministic,iOwnHeapFailNumber);
212 if (iSharedHeapFailNumber!=-1)
214 resetSharedHeap=ETrue;
215 __RHEAP_SETFAIL (iHeap, RHeap::EDeterministic,iSharedHeapFailNumber);
227 //Call close on RSgImage handles being used to share glyph data with clients.
228 //The glyph images are held open to prevent the GlyphAtlas from closing them
229 //before a client can use them.
230 for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
232 iGlyphImagesInTransit[i].Close();
233 iGlyphImagesInTransit.Remove(i);
236 switch(aMessage.Function())
240 Init(FontBitmapServer()->Init());
241 iSessionHandle = (TInt)this;
242 aMessage.Complete(iSessionHandle);
249 TInt localhandle=aMessage.Int0();
250 if(!iIx->At(localhandle))
252 aMessage.Panic(KFBSERVPanicCategory,KErrNotFound);
255 iIx->Remove(localhandle);
257 aMessage.Complete(KErrNone);
258 FBS_OST(OstTraceExt3( GRAPHICS_RESOURCE_MANAGEMENT_SEMANTICS, CFBCLIENT_SERVICEL_INFO, "# Server resource destroyed; iSSH=0x%08x; rc=%d; iH=0x%08x;", iSessionHandle, iResourceCount, localhandle);)
264 case EFbsMessResourceCount:
265 aMessage.Complete(iResourceCount);
271 case EFbsMessShutdown:
272 case EFbsMessNumTypefaces:
273 case EFbsMessTypefaceSupport:
274 case EFbsMessFontHeightInTwips:
275 case EFbsMessFontHeightInPixels:
276 case EFbsMessSetPixelHeight:
277 case EFbsMessDefaultAllocFail:
278 case EFbsMessDefaultMark:
279 case EFbsMessDefaultMarkEnd:
280 case EFbsMessUserAllocFail:
281 case EFbsMessUserMark:
282 case EFbsMessUserMarkEnd:
283 case EFbsMessHeapCheck:
284 case EFbsMessSetDefaultGlyphBitmapType:
285 case EFbsMessGetDefaultGlyphBitmapType:
286 case EFbsMessFontNameAlias:
287 case EFbsMessGetHeapSizes:
288 case EFbsMessDefaultLanguageForMetrics:
290 case EFbsMessFetchLinkedTypeface:
291 case EFbsMessRegisterLinkedTypeface:
292 case EFbsMessUpdateLinkedTypeface:
295 FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
297 FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
301 case EFbsMessFontDuplicate:
302 case EFbsMessGetNearestFontToDesignHeightInTwips:
303 case EFbsMessGetNearestFontToDesignHeightInPixels:
304 case EFbsMessGetNearestFontToMaxHeightInTwips:
305 case EFbsMessGetNearestFontToMaxHeightInPixels:
306 case EFbsMessGetFontById:
307 case EFbsMessInstallFontStoreFile:
308 case EFbsMessAddFontStoreFile:
309 case EFbsMessRemoveFontStoreFile:
310 case EFbsMessRasterize:
311 case EFbsMessFaceAttrib:
312 case EFbsMessHasCharacter:
313 case EFbsMessShapeText:
314 case EFbsMessShapeDelete:
315 case EFbsMessSetTwipsHeight:
316 case EFbsMessGetTwipsHeight:
317 case EFbsSetSystemDefaultTypefaceName:
318 case EFbsMessGetFontTable:
319 case EFbsMessReleaseFontTable:
320 case EFbsMessGetGlyphOutline:
321 case EFbsMessReleaseGlyphOutline:
323 case EFbsMessSetDuplicateFail:
325 case EFbsMessGetGlyphs:
326 case EFbsMessGetGlyphMetrics:
327 ProcFontMessage(aMessage);
330 case EFbsMessBitmapCreate:
331 case EFbsMessBitmapResize:
332 case EFbsMessBitmapDuplicate:
333 case EFbsMessBitmapLoad:
334 case EFbsMessBitmapCompress:
335 case EFbsMessBitmapBgCompress:
336 case EFbsMessBitmapClean:
337 case EFbsGetAllBitmapHandles:
338 case EFbsMessBitmapLoadFast:
339 case EFbsMessBitmapNotifyDirty:
340 case EFbsMessBitmapCancelNotifyDirty:
341 ProcBitmapMessage(aMessage);
344 case EFbsMessSetHeapFail:
345 case EFbsMessHeapCount:
346 case EFbsMessSetHeapReset:
347 case EFbsMessSetHeapCheck:
350 ProcMemMessage(aMessage);
352 aMessage.Complete(KErrNone);
355 // Glyph Atlas messages (debug-only)
356 case EFbsMessAtlasFontCount:
357 case EFbsMessAtlasGlyphCount:
359 ProcAtlasMessage(aMessage);
361 aMessage.Complete(KErrNotSupported);
364 case EFbsMessOogmNotification:
366 aMessage.Complete( HandleMesgOogmStatus( aMessage ) );
368 case EFbsMessGetGlyphCacheMetrics:
370 HandleMesgGlyphCacheMetrics( aMessage );
378 aMessage.Complete(KErrNone);
381 aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
386 //do not want a memory panic if the return code is OK
387 //__UHEAP_MARKEND does this
391 TUint32 badCell=User::Heap().__DbgMarkEnd(0);
394 //if the function call was a success, there may have been valid memory allocations,
395 //so only panic if the call failed, and the memory is not the same before and after the
397 __ASSERT_DEBUG (badCell==NULL,User::Panic(KFBSERVPanicCategory, KErrGeneral));
403 badCell2= __RHEAP_MARKEND(iHeap);
404 //the above function call does not panic if there is a failure, this is
405 //only for the user heap
408 __ASSERT_DEBUG (badCell2==NULL,User::Panic(KFBSERVPanicCategory, KErrGeneral));
411 //change the state of the memory check?
412 if (iOwnHeapCheckFlip)
414 //change the state of the memory testing
415 //if the mark was set still need to have a mark end
416 iOwnHeapCheckFlip=EFalse;
417 iOwnHeapCheck=!iOwnHeapCheck;
421 iHeapCheckFlip=EFalse;
422 iHeapCheck=!iHeapCheck;
427 //previously set failures, reset
432 __RHEAP_RESET (iHeap);
438 /** Handler for EFbsMessFontDuplicate message
439 @param aMessage input parameters
440 @param aPanicRequired flag that is set if a client panic is required
441 @return KErrNone if successful, otherwise a system wide error code
443 TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
446 if (iFontDuplicateToFail)
448 return KErrNoMemory; //return with this error since this error is possible
451 CFontObject* fontptr = (CFontObject*) aMessage.Int0();
452 if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
457 TPckgBuf<TFontInfo> fontinfo;
458 TInt localhandle = 0;
459 TInt ret = fontptr->Open();
464 TRAP(ret, localhandle=iIx->AddL(fontptr));
470 CopyFontInfo(fontptr,localhandle,fontinfo());
471 fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
472 ret = aMessage.Write(1, fontinfo);
475 iIx->Remove(localhandle);
476 aPanicRequired = ETrue;
482 FBS_OST(OstTraceExt3( GRAPHICS_RESOURCE_MANAGEMENT_SEMANTICS, CFBCLIENT_HANDLEMESGFONTDUPLICATE_INFO, "# Server font duplicated; iSSH=0x%08x; rc=%d; iH=0x%08x;", iSessionHandle, iResourceCount, localhandle);)
487 /** Handler for EFbsMessGetNearestFontToDesignHeightInTwips, EFbsMessGetNearestFontToDesignHeightInPixels,
488 EFbsMessGetNearestFontToMaxHeightInTwips or EFbsMessGetNearestFontToMaxHeightInPixels messages
489 @param aMessage input and output parameters
490 @param aPanicRequired flag that is set if a client panic is required
491 @return KErrNone if successful, otherwise a system wide error code
493 TInt CFbClient::HandleMesgGetNearestFont(const RMessage2& aMessage, TBool& aPanicRequired)
495 CFontObject* fontptr = NULL;
496 TPckgBuf<TFontSpec> pckgFontSpec;
498 TPckgBuf<TSizeInfo> info;
500 const TFbsMessage fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
502 TInt ret = aMessage.Read(0, pckgFontSpec);
503 TFontSpec& fontSpec = pckgFontSpec();
504 if (ret == KErrNone )
506 TInt length = fontSpec.iTypeface.iName.Length();
507 if((length < 0) || (length > TOpenFontFaceAttribBase::ENameLength))
509 aPanicRequired = ETrue;
513 ret = aMessage.Read(2, info);
516 pckgMaxHeight = info().iMaxHeight;
517 TopLevelStore()->FontStore()->iKPixelHeightInTwips=info().iDevSize.iHeight;
518 TopLevelStore()->FontStore()->iKPixelWidthInTwips=info().iDevSize.iWidth;
524 aPanicRequired = ETrue;
527 if ( (EFbsMessGetNearestFontToMaxHeightInTwips == fbsMessage) || (EFbsMessGetNearestFontToMaxHeightInPixels == fbsMessage) )
529 ret = TopLevelStore()->GetNearestFont(fontptr, fbsMessage, fontSpec, pckgMaxHeight);
533 ret = TopLevelStore()->GetNearestFont(fontptr, fbsMessage, fontSpec);
537 { // package up the result
538 ret = CopyFontInfoIntoReturnMessage(aMessage, aPanicRequired, fontptr, 1);
545 /** package up the font that was found - includes cleanup handling in case of error
546 @param aMessage input and output parameters
547 @param aPanicRequired flag that is set if a client panic is required
548 @param aFontObj the object that is to be returned
549 @param aWritePosition the slot position in the message pointing to the receiving object
550 @return KErrNone if successful, otherwise a system wide error code
552 TInt CFbClient::CopyFontInfoIntoReturnMessage(const RMessage2& aMessage, TBool& aPanicRequired, CFontObject* aFontObj, TInt aWritePosition)
554 TInt localhandle = 0;
555 TRAPD(ret, localhandle = iIx->AddL(aFontObj));
561 TPckgBuf<TFontInfo> pckgFontInfo;
562 CopyFontInfo(aFontObj, localhandle, pckgFontInfo());
563 ret = aMessage.Write(aWritePosition, pckgFontInfo);
566 iIx->Remove(localhandle);
567 aPanicRequired = ETrue;
572 FBS_OST(OstTraceExt3( GRAPHICS_RESOURCE_MANAGEMENT_SEMANTICS, CFBCLIENT_COPYFONTINFOINTORETURNMESSAGE_INFO, "# Server font duplicated; iSSH=0x%08x; rc=%d; iH=0x%08x;", iSessionHandle, iResourceCount, localhandle);)
577 /** Handler for EFbsMessGetFontById message
578 Works for Bitmap fonts only, see implementation in CFbTop::GetFontById() & CFontStore::GetFontById().
579 @param aMessage input and output parameters
580 @param aPanicRequired flag that is set if a client panic is required
581 @return KErrNone if successful, otherwise a system wide error code
583 TInt CFbClient::HandleMesgGetFontById(const RMessage2& aMessage, TBool& aPanicRequired)
585 CFontObject* fontptr = NULL;
586 TPckgBuf<TAlgStyle> algstyle;
587 TPckgBuf<TSize> size;
589 TInt ret = aMessage.Read(1, algstyle);
592 ret = aMessage.Read(3, size);
595 TopLevelStore()->FontStore()->iKPixelHeightInTwips = size().iHeight;
596 TopLevelStore()->FontStore()->iKPixelWidthInTwips = size().iWidth;
601 aPanicRequired = ETrue;
605 fileid.iUid = aMessage.Int2();
606 ret = TopLevelStore()->GetFontById(fontptr,fileid,algstyle());
609 { // package up the result
610 ret = CopyFontInfoIntoReturnMessage(aMessage, aPanicRequired, fontptr, 0);
617 /** Handler for EFbsMessInstallFontStoreFile or EFbsMessAddFontStoreFile messages
618 @param aMessage input and output parameters
619 @param aPanicRequired flag that is set if a client panic is required
620 @return KErrNone if successful, otherwise a system wide error code
622 TInt CFbClient::HandleMesgAddOrInstallFontFile(const RMessage2& aMessage, TBool& aPanicRequired)
624 TPckgBuf<TIntParcel> id;
625 TInt length=aMessage.Int1();
627 if(length < 0 || length * sizeof(TText) >= KMaxTInt/2)
629 aPanicRequired = ETrue;
633 TText* buffer=(TText*)User::Alloc(length*sizeof(TText));
638 TPtr filename(buffer,length,length);
639 TInt ret = aMessage.Read(0,filename);
643 aPanicRequired = ETrue;
646 TRAP(ret, id().iInt = TopLevelStore()->FontStore()->AddFileL(filename).iUid);
654 if (aMessage.Function() == EFbsMessAddFontStoreFile)
656 TRAP(ret, AddFontFileIndexL(uid));
659 TopLevelStore()->FontStore()->RemoveFile(uid);
663 ret = aMessage.Write(2,id);
666 RemoveFontFileIndex(uid);
667 aPanicRequired = ETrue;
673 /** Handler for EFbsMessRemoveFontStoreFile message
674 @param aMessage input parameters
675 @return KErrNone if successful
677 TInt CFbClient::HandleMesgRemoveFontFile(const RMessage2& aMessage)
680 uid.iUid=aMessage.Int0();
681 RemoveFontFileIndex(uid);
686 /** Handler for EFbsMessRasterize message
687 @param aMessage input parameters
688 @param aPanicRequired flag that is set if a client panic is required
689 @return ETrue if successful, EFalse or any system-wide error code if not successful.
691 TInt CFbClient::HandleMesgRasterize(const RMessage2& aMessage, TBool& aPanicRequired)
693 CFbTop* fbtop = TopLevelStore();
694 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
697 aPanicRequired = ETrue;
700 CBitmapFont* bitmapFont = fontptr->iAddressPointer;
701 const TUint charCode = aMessage.Int1();
703 if ( (bitmapFont != NULL) && (bitmapFont->Rasterize(iSessionHandle, charCode, iOpenFontGlyphData)) )
705 // Convert all pointers to be passed back to the client to offsets from
706 // the heap base so that they can be recreated client side relative to the
707 // client's heap base
708 TInt heapbase = fbtop->HeapBase();
709 TPckgBuf<TRasterizeParams> params;
710 params().iMetricsOffset = PointerToOffset(iOpenFontGlyphData->Metrics(), heapbase);
711 params().iBitmapPointerOffset = PointerToOffset(iOpenFontGlyphData->BitmapPointer(), heapbase);;
712 TInt err = aMessage.Write(2, params);
715 aPanicRequired = ETrue;
723 /** Handler for EFbsMessGetGlyphs message.
724 Reads a batch of up to KMaxGlyphBatchSize glyph codes, and on success returns
725 the corresponding TGlyphImageInfo objects.
726 @param aMessage input parameters
727 @param aPanicRequired flag that is set if a client panic is required
728 @return KErrNone if successful, otherwise any system-wide error code.
730 TInt CFbClient::HandleMesgGetGlyphs(const RMessage2& aMessage, TBool& aPanicRequired)
732 CFbTop* fbtop = TopLevelStore();
733 // Previously requested glyphs were closed in ServiceL()
734 CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
737 return KErrNotSupported;
739 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
742 aPanicRequired = ETrue;
743 return KErrBadHandle;
746 TUint glyphCodes[KMaxGlyphBatchSize];
747 TGlyphImageInfo glyphImageInfo[KMaxGlyphBatchSize];
748 TPckg<TUint[KMaxGlyphBatchSize]> glyphBatchPckg(glyphCodes);
750 TInt err = aMessage.Read(1, glyphBatchPckg);
753 aPanicRequired = ETrue;
756 TInt glyphCodesCount = glyphBatchPckg.Length() / sizeof(TUint);
757 if (glyphCodesCount > KMaxGlyphBatchSize)
759 aPanicRequired = ETrue;
763 TInt glyphsProcessed = 0;
764 CBitmapFont* font = fontptr->iAddressPointer;
765 for (; (glyphsProcessed < glyphCodesCount); ++glyphsProcessed)
767 TUint32 glyphCode = glyphCodes[glyphsProcessed];
768 err = glyphAtlas->GetGlyph(*font, glyphCode, glyphImageInfo[glyphsProcessed]);
769 // Search for glyph in glyph atlas
772 const TUint8* bitmapData = NULL;
773 TOpenFontCharMetrics metrics;
774 // search for glyph in font glyph cache and session cache.
775 if (!font->GetCharacterData(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, metrics, bitmapData))
777 // Rasterize the glyph
778 if(!font->Rasterize(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
783 metrics = *(iOpenFontGlyphData->Metrics());
784 bitmapData = iOpenFontGlyphData->BitmapPointer();
786 CGlyphAtlas::TAddGlyphArgs args(bitmapData, glyphCode, metrics);
787 err = glyphAtlas->AddGlyph(*font, args, glyphImageInfo[glyphsProcessed]);
789 if ((err == KErrNone) && (glyphImageInfo[glyphsProcessed].iImageId != KSgNullDrawableId))
791 // To prevent other threads closing the glyph image in the glyph atlas
792 // before client has had chance to open the drawable id, open a local
793 // handle to the glyph image for the session, which will be closed either
794 // next time a request is made or when EFbsMessCloseGlyphs is handled.
796 err = glyphImage.Open(glyphImageInfo[glyphsProcessed].iImageId);
799 err = iGlyphImagesInTransit.Append(glyphImage);
802 // If an error occurred during this iteration, abort now before the glyphsProcessed
803 // counter is incremented, which would give one too many processed glyphs.
810 // Even if there was an error, if at least one glyph was processed successfully
811 // send that back to the client, and reset the error code.
812 if (glyphsProcessed > 0)
814 TPckg<TGlyphImageInfo[KMaxGlyphBatchSize]> glyphImageInfoPckg(glyphImageInfo);
815 glyphImageInfoPckg.SetLength(glyphsProcessed * sizeof(TGlyphImageInfo));
816 err = aMessage.Write(2, glyphImageInfoPckg);
819 aPanicRequired = ETrue;
825 // No glyphs being returned, so an error code must be returned.
826 __ASSERT_DEBUG(err != KErrNone, User::Panic(KFBSERVPanicCategory, err));
832 Handler for EFbsMessGetGlyphMetrics message.
833 Reads an array of glyph codes, and returns the offset from the heap base for the
834 corresponding metrics object.
835 @pre The glyph codes have already been searched client-side in the font glyph
836 cache and the session cache.
837 @param aMessage input parameters
838 @param aPanicRequired flag that is set if a client panic is required
839 @return KErrNone if successful, otherwise any system-wide error code.
841 TInt CFbClient::HandleMesgGetGlyphMetrics(const RMessage2& aMessage, TBool& aPanicRequired)
843 CFbTop* fbtop = TopLevelStore();
844 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
847 aPanicRequired = ETrue;
848 return KErrBadHandle;
852 TUint glyphCodes[KMaxMetricsBatchSize];
853 TPckg<TUint[KMaxMetricsBatchSize]> glyphBatchPckg(glyphCodes);
854 err = aMessage.Read(1, glyphBatchPckg);
857 aPanicRequired = ETrue;
861 TInt numGlyphCodes = glyphBatchPckg.Length() / sizeof(TUint);
862 if (numGlyphCodes > KMaxMetricsBatchSize)
864 aPanicRequired = ETrue;
868 CBitmapFont* font = fontptr->iAddressPointer;
869 const TInt heapbase = fbtop->HeapBase();
872 TInt glyphMetricsOffsets[KMaxMetricsBatchSize];
873 for (glyphProcessed = 0; (glyphProcessed < numGlyphCodes) && (err == KErrNone); ++glyphProcessed)
875 if (font->Rasterize(iSessionHandle, glyphCodes[glyphProcessed] | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
877 // Convert all pointers to be passed back to the client to offsets from
878 // the heap base so that they can be recreated client side relative to the
879 // client's heap base
880 glyphMetricsOffsets[glyphProcessed] = PointerToOffset(iOpenFontGlyphData->Metrics(), heapbase);
890 TPckg<TInt[KMaxMetricsBatchSize]> glyphMetricsOffsetsPckg(glyphMetricsOffsets);
891 glyphMetricsOffsetsPckg.SetLength(glyphProcessed * sizeof(TInt));
892 err = aMessage.Write(2, glyphMetricsOffsetsPckg);
895 aPanicRequired = ETrue;
901 /** Handler for EFbsMessFaceAttrib message
902 @param aMessage Input and output parameters
903 @param aPanicRequired Flag that is set to ETrue if a client panic is required
904 @return ETrue if successful, EFalse or any system-wide error code if not successful.
905 An error code is only returned if aPanicRequired is set to ETrue.
907 TInt CFbClient::HandleMesgFaceAttrib(const RMessage2& aMessage, TBool& aPanicRequired)
909 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), TopLevelStore()->FontConUniqueID()));
912 aPanicRequired = ETrue;
915 CBitmapFont* bitmapFont = fontptr->iAddressPointer;
918 TPckgBuf<TOpenFontFaceAttrib> package;
919 if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
921 ret = aMessage.Write(1,package);
928 aPanicRequired = ETrue;
935 /** Handler for EFbsMessHasCharacter message
936 @param aMessage Input parameters
937 @param aPanicRequired Flag that is set to ETrue if a client panic is required
938 @return ETrue if the font has the character, EFalse if the font does not have
939 the character, or any system-wide error code if not successful. An error code
940 is only returned if aPanicRequired is set to ETrue.
942 TInt CFbClient::HandleMesgHasCharacter(const RMessage2& aMessage, TBool& aPanicRequired)
944 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), TopLevelStore()->FontConUniqueID()));
947 aPanicRequired = ETrue;
950 CBitmapFont* bitmapFont = fontptr->iAddressPointer;
953 TRAPD(error, ret = bitmapFont->HasCharacterL(aMessage.Int1()));
954 if (error != KErrNone)
962 /** Handler for EFbsMessShapeText message
963 @param aMessage Input and output parameters
964 @param aPanicRequired Flag that is set to ETrue if a client panic is required
965 @return An offset from the heap base where the pointer to the shape is located
966 if successful, otherwise 0 or any system-wide error code. An error code is
967 only returned if aPanicRequired is set to ETrue.
969 TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
971 TInt error = KErrNone;
972 TShapeHeader* shape = 0;
973 if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
975 aPanicRequired = ETrue;
979 CFbTop* fbtop = TopLevelStore();
980 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
983 aPanicRequired = ETrue;
987 TInt inputTextLength = aMessage.GetDesLength(1);
988 if (inputTextLength < 0)
990 error = inputTextLength;
991 aPanicRequired = ETrue;
997 if (iTextToShape.MaxLength() < inputTextLength)
999 error = iTextToShape.ReAlloc(inputTextLength);
1002 if (error == KErrNone)
1004 error = aMessage.Read(1, iTextToShape);
1005 if (error != KErrNone)
1007 aPanicRequired = ETrue;
1010 TPckgBuf<TShapeMessageParameters> sp;
1011 error = aMessage.Read(2, sp);
1012 if (error != KErrNone)
1014 aPanicRequired = ETrue;
1017 CBitmapFont* bitmapFont = fontptr->iAddressPointer;
1018 TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
1019 if (error == KErrNone)
1021 // Convert the pointer to be passed back to the client to an offset from
1022 // the heap base so that it can be recreated client side relative to the
1023 // client's heap base
1024 return PointerToOffset(shape, fbtop->HeapBase());
1031 /** Handler for EFbsMessShapeDelete message
1032 @param aMessage input and output parameters
1033 @param aPanicRequired flag that is set to ETrue if a client panic is required
1034 @return KErrNone if successful, otherwise a system wide error code
1035 An error code is only returned if aPanicRequired is set to ETrue.
1037 TInt CFbClient::HandleMesgShapeDelete(const RMessage2& aMessage, TBool& aPanicRequired)
1039 CFbTop* fbtop = TopLevelStore();
1040 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
1043 aPanicRequired = ETrue;
1044 return KErrArgument;
1046 CBitmapFont* bitmapFont = fontptr->iAddressPointer;
1048 // Combine the passed shape offset with the current heap base to get
1049 // a valid pointer to a shape header for use in this process
1050 TShapeHeader* shapeheader = reinterpret_cast<TShapeHeader*>(OffsetToPointer(aMessage.Int1(), fbtop->HeapBase()));
1052 bitmapFont->DeleteShape(iSessionHandle,shapeheader);
1056 TInt CFbClient::HandleMesgReleaseGlyphOutline(const RMessage2& aMessage, TBool& aPanicRequired)
1058 TInt ret = KErrNone;
1059 CFbTop* fbtop = TopLevelStore();
1060 TPckgBuf<TFBSGlyphOutlineParam> params;
1061 ret = aMessage.Read(0, params);
1062 if (KErrNone != ret)
1064 aPanicRequired = ETrue;
1067 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(params().iHandle, fbtop->FontConUniqueID()));
1070 aPanicRequired = ETrue;
1071 return KErrArgument;
1073 CBitmapFont* bitmapFont = fontptr->iAddressPointer;
1075 TInt count = params().iCount;
1076 TUint *glyphCodes = (TUint *)User::Alloc(count * sizeof(TUint));
1077 if (NULL == glyphCodes)
1079 return KErrNoMemory;
1081 // copy the glyph codes out of the IPC buffer...
1082 TPtr8 ptr((TUint8 *)glyphCodes, count * sizeof(TUint), count * sizeof(TUint));
1083 ret = aMessage.Read(1, ptr);
1085 if (KErrNone == ret)
1087 bitmapFont->ReleaseGlyphOutlines(count, glyphCodes,
1088 params().iHinted, iSessionHandle);
1092 aPanicRequired = ETrue;
1095 User::Free(glyphCodes);
1099 TInt CFbClient::HandleMesgGetGlyphOutline(const RMessage2& aMessage, TBool& aPanicRequired)
1101 TInt ret = KErrNone;
1102 CFbTop* fbtop = TopLevelStore();
1103 TPckgBuf<TFBSGlyphOutlineParam> params;
1104 ret = aMessage.Read(0, params);
1105 if (KErrNone != ret)
1107 aPanicRequired = ETrue;
1110 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(params().iHandle, fbtop->FontConUniqueID()));
1113 aPanicRequired = ETrue;
1114 return KErrArgument;
1116 CBitmapFont* bitmapFont = fontptr->iAddressPointer;
1118 TInt count = params().iCount;
1119 TUint* glyphCodes = (TUint *)User::Alloc(count * sizeof(TUint));
1120 if (NULL == glyphCodes)
1122 return KErrNoMemory;
1124 // copy the glyph codes out of the IPC buffer...
1125 TPtr8 ptr((TUint8 *)glyphCodes, count * sizeof(TUint), count * sizeof(TUint));
1126 ret = aMessage.Read(1, ptr);
1127 if (KErrNone != ret)
1129 User::Free(glyphCodes);
1130 aPanicRequired = ETrue;
1134 TOffsetLen* offsetLens =
1135 (TOffsetLen *)User::Alloc(count * sizeof(TOffsetLen));
1136 if (NULL == offsetLens)
1138 User::Free(glyphCodes);
1139 return KErrNoMemory;
1143 TAny* outline = NULL;
1144 for (TInt i = 0; i < count; ++i)
1146 bitmapFont->GetGlyphOutline(glyphCodes[i],
1147 params().iHinted, outline, len, iSessionHandle);
1149 offsetLens[i].iLen = len;
1150 offsetLens[i].iOffset = PointerToOffset((outline), fbtop->HeapBase());
1152 TPtr8 pkg2((TUint8 *)offsetLens, count * sizeof(TOffsetLen),
1153 count * sizeof(TOffsetLen));
1154 ret = aMessage.Write(2, pkg2);
1155 if (KErrNone != ret)
1157 aPanicRequired = ETrue;
1160 User::Free(glyphCodes);
1161 User::Free(offsetLens);
1165 TInt CFbClient::HandleMesgReleaseFontTable(const RMessage2& aMessage, TBool& aPanicRequired)
1167 CFbTop* fbtop = TopLevelStore();
1168 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
1171 aPanicRequired = ETrue;
1172 return KErrArgument;
1174 CBitmapFont* bitmapFont = fontptr->iAddressPointer;
1176 TUint32 tag = aMessage.Int1();
1178 bitmapFont->ReleaseFontTable(tag, iSessionHandle);
1183 TInt CFbClient::HandleMesgGetFontTable(const RMessage2& aMessage, TBool& aPanicRequired)
1185 TInt ret = KErrNone;
1186 CFbTop* fbtop = TopLevelStore();
1187 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
1190 aPanicRequired = ETrue;
1191 return KErrArgument;
1193 CBitmapFont* bitmapFont = fontptr->iAddressPointer;
1196 TAny* tablePtr = NULL;
1197 ret = bitmapFont->GetFontTable((TUint32)aMessage.Int1(), tablePtr, len, iSessionHandle);
1199 if (KErrNone == ret)
1201 TPckgBuf<TOffsetLen> params;
1202 params().iLen = len;
1203 params().iOffset = PointerToOffset(tablePtr, fbtop->HeapBase());
1204 ret = aMessage.Write(2, params);
1205 aPanicRequired = (KErrNone != ret);
1213 Called in response to the GoomMonitor framework's call into FbsOogmPlugin.
1214 We wish to either free some GPU memory, or reinstate its normal usage.
1216 @param aMessage The IPC message.
1217 @return KErrNone If the value contained in the TFbsOogmMessage enumeration member is meaningful and the glyph atlas is present.
1218 KErrNotSupported if there is no glyph atlas.
1219 KErrUnknown if the value contained in the TFbsOogmMessage enumeration member is not meaningful.
1221 TInt CFbClient::HandleMesgOogmStatus( const RMessage2& aMessage )
1223 TInt ret = KErrNone;
1224 CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
1226 if ( NULL == glyphAtlas )
1228 return KErrNotSupported;
1232 TPckgBuf<TFbsOogmMessage> oogmMessage;
1233 aMessage.Read( 0, oogmMessage );
1235 switch( oogmMessage().iOogmNotification )
1237 case TFbsOogmMessage::EFbsOogmNoAction:
1240 case TFbsOogmMessage::EFbsOogmLowNotification:
1242 glyphAtlas->ReleaseGpuMemory( oogmMessage().iBytesToFree, oogmMessage().iFlags );
1246 case TFbsOogmMessage::EFbsOogmOkayNotification:
1248 glyphAtlas->InstateGpuMemory( oogmMessage().iFlags );
1261 void CFbClient::HandleMesgGlyphCacheMetrics( const RMessage2& aMessage )
1263 CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
1264 TPckgBuf<TGlyphCacheMetrics> metrics;
1266 glyphAtlas->GetGlyphCacheMetrics( metrics() );
1268 aMessage.Complete( aMessage.Write(0, metrics) );
1272 void CFbClient::ProcFontMessage(const RMessage2& aMessage)
1274 TInt ret = KErrNone;
1275 TBool panicRequired = EFalse;
1277 switch(aMessage.Function())
1279 case EFbsMessFontDuplicate:
1280 ret = HandleMesgFontDuplicate(aMessage, panicRequired);
1283 case EFbsMessGetNearestFontToDesignHeightInTwips:
1284 case EFbsMessGetNearestFontToDesignHeightInPixels:
1285 case EFbsMessGetNearestFontToMaxHeightInTwips:
1286 case EFbsMessGetNearestFontToMaxHeightInPixels:
1287 ret = HandleMesgGetNearestFont(aMessage, panicRequired);
1290 case EFbsMessGetFontById:
1291 ret = HandleMesgGetFontById(aMessage, panicRequired);
1294 case EFbsMessInstallFontStoreFile:
1295 case EFbsMessAddFontStoreFile:
1296 ret = HandleMesgAddOrInstallFontFile(aMessage, panicRequired);
1299 case EFbsMessRemoveFontStoreFile:
1300 ret = HandleMesgRemoveFontFile(aMessage);
1303 case EFbsMessRasterize:
1304 ret = HandleMesgRasterize(aMessage, panicRequired);
1307 case EFbsMessFaceAttrib:
1308 ret = HandleMesgFaceAttrib(aMessage, panicRequired);
1311 case EFbsMessHasCharacter:
1312 ret = HandleMesgHasCharacter(aMessage, panicRequired);
1315 case EFbsMessShapeText:
1316 ret = HandleMesgShapeText(aMessage, panicRequired);
1319 case EFbsMessShapeDelete:
1320 ret = HandleMesgShapeDelete(aMessage, panicRequired);
1323 case EFbsMessSetTwipsHeight:
1325 TInt localhandle=aMessage.Int0();
1326 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(localhandle, TopLevelStore()->FontConUniqueID()));
1329 panicRequired = ETrue;
1333 fontptr->iHeightInTwips = aMessage.Int1();
1337 case EFbsMessGetTwipsHeight:
1339 TInt localhandle=aMessage.Int0();
1340 CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(localhandle, TopLevelStore()->FontConUniqueID()));
1343 panicRequired = ETrue;
1347 TPckgBuf<TInt> height;
1348 height() = fontptr->iHeightInTwips;
1349 ret = aMessage.Write(1,height);
1350 if (KErrNone != ret)
1352 panicRequired = ETrue;
1356 case EFbsSetSystemDefaultTypefaceName:
1358 TBuf<KMaxTypefaceNameLength> fontTypefaceName;
1359 ret = aMessage.GetDesLength(0);
1362 panicRequired = ETrue;
1365 if (ret <= KMaxTypefaceNameLength) // Size in characters i.e. 2 bytes for unicode
1367 ret = aMessage.Read(0, fontTypefaceName);
1368 if (ret == KErrNone)
1370 TopLevelStore()->SetSystemDefaultTypefaceName(fontTypefaceName);
1375 panicRequired = ETrue;
1381 case EFbsMessGetFontTable:
1383 ret = HandleMesgGetFontTable(aMessage, panicRequired);
1386 case EFbsMessGetGlyphOutline:
1388 ret = HandleMesgGetGlyphOutline(aMessage, panicRequired);
1391 case EFbsMessReleaseGlyphOutline:
1393 ret = HandleMesgReleaseGlyphOutline(aMessage, panicRequired);
1396 case EFbsMessReleaseFontTable:
1398 ret = HandleMesgReleaseFontTable(aMessage, panicRequired);
1401 case EFbsMessGetGlyphs:
1403 ret = HandleMesgGetGlyphs(aMessage, panicRequired);
1406 case EFbsMessGetGlyphMetrics:
1408 ret = HandleMesgGetGlyphMetrics(aMessage, panicRequired);
1413 case EFbsMessSetDuplicateFail:
1415 TInt argument =aMessage.Int0();
1418 iFontDuplicateToFail = ETrue;
1422 iFontDuplicateToFail = EFalse;
1432 // either have a result or an error code to panic the client with
1435 aMessage.Panic(KFBSERVPanicCategory, ret);
1439 if(!aMessage.IsNull())
1441 aMessage.Complete(ret);
1449 void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
1451 CBitmapObject* bmpptr=NULL;
1453 TInt ret = KErrNone;
1454 switch(aMessage.Function())
1456 case EFbsMessBitmapCreate:
1458 TPckgBuf<TBmpSpec> bs;
1459 ret = aMessage.Read(0,bs);
1462 aMessage.Panic(KFBSERVPanicCategory,ret);
1466 TBmpSpec& bmpSpec = bs();
1468 if(!TDisplayModeUtils::IsDisplayModeValid(bmpSpec.iDispMode))
1470 aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
1474 // client uses iHandle to pass UID and iServerHandle to pass data size
1475 TRAP(ret, bmpptr = TopLevelStore()->CreateBitmapL(bmpSpec.iSizeInPixels, bmpSpec.iDispMode, TUid::Uid(bmpSpec.iHandle), EFalse, bmpSpec.iServerHandle));
1478 TRAP(ret,localhandle=iIx->AddL(bmpptr));
1485 bmpSpec.iHandle=localhandle;
1486 bmpSpec.iServerHandle = bmpptr->Handle();
1487 bmpSpec.iAddressOffset=TInt(bmpptr->Address())-TopLevelStore()->HeapBase();
1488 ret = aMessage.Write(0,bs);
1491 iIx->Remove(localhandle);
1492 aMessage.Panic(KFBSERVPanicCategory,ret);
1496 FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_SEMANTICS, CFBCLIENT_PROCBITMAPMESSAGE_INFO, "# Server bitmap created; iSSH=0x%08x; rc=%d; iH=0x%08x; iSH=0x%08x; bytes=%d;", iSessionHandle, iResourceCount, bmpSpec.iHandle, bmpSpec.iServerHandle, bmpptr->Address()->DataStride() * bmpSpec.iSizeInPixels.iHeight);)
1500 case EFbsMessBitmapLoad:
1501 case EFbsMessBitmapLoadFast:
1503 TPckgBuf<TLoadBitmapArg> loadBitmapArg;
1504 ret = aMessage.Read(1,loadBitmapArg);
1507 aMessage.Panic(KFBSERVPanicCategory,ret);
1510 const TInt32 id=loadBitmapArg().iBitmapId;
1511 const TBool shareifloaded=loadBitmapArg().iShareIfLoaded;
1512 const TUint fileOffset = loadBitmapArg().iFileOffset;
1513 if(aMessage.Function() == EFbsMessBitmapLoad)
1516 ret=file.AdoptFromClient(aMessage,2,3);
1522 ret=file.FullName(filename);
1530 TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset,&file, iSessionHandle));
1534 TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, &file, iSessionHandle));
1541 ret = aMessage.Read(2,filename);
1544 aMessage.Panic(KFBSERVPanicCategory,ret);
1547 _LIT(KZDrive, "z:");
1548 if (filename.Left(2).CompareF(KZDrive))
1550 // File is not in the Z: drive.
1551 // So open the file and pass the file handle to LoadBitmapL() or ShareBitmapL() and close it afterwards.
1552 // The reason is that the cache cannot be used for files that are writable,
1553 // since they can't be kept open in the cache.
1555 ret = file.Open(TopLevelStore()->FileSession(),filename,EFileShareReadersOnly);
1562 TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset,&file, iSessionHandle));
1566 TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, &file, iSessionHandle));
1574 TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset, NULL, iSessionHandle));
1578 TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, NULL, iSessionHandle));
1586 TRAP(ret,localhandle=iIx->AddL(bmpptr));
1592 TPckgBuf<TBmpHandles> handlebuffer;
1593 handlebuffer().iHandle=localhandle;
1594 handlebuffer().iServerHandle = bmpptr->Handle();
1595 handlebuffer().iAddressOffset=TInt(bmpptr->Address())-TopLevelStore()->HeapBase();
1596 ret = aMessage.Write(0,handlebuffer);
1599 iIx->Remove(localhandle);
1600 aMessage.Panic(KFBSERVPanicCategory,ret);
1604 FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_SEMANTICS, CFBCLIENT_PROCBITMAPMESSAGE_INFO2, "# Server bitmap loaded; iSSH=0x%08x; rc=%d; iH=0x%08x; iSH=0x%08x; bytes=%d;", iSessionHandle, iResourceCount, handlebuffer().iHandle, handlebuffer().iServerHandle, bmpptr->Address()->DataStride() * bmpptr->Address()->SizeInPixels().iHeight);)
1607 case EFbsMessBitmapResize:
1609 localhandle=aMessage.Int0();
1610 CFbTop* fbtop = TopLevelStore();
1611 bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
1617 ret = fbtop->GetCleanBitmap(bmpptr);
1618 if (ret != KErrNone)
1622 TSize newsize(aMessage.Int1(),aMessage.Int2());
1623 const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM(); //It must be set before the resizing is done.
1624 const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
1625 CBitmapObject* newbmpptr = NULL;
1626 TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
1627 if (ret != KErrNone)
1631 ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
1632 if (ret != KErrNone)
1637 if (compressedInRam)
1639 // if the header says PaletteCompression specify.
1640 TBitmapfileCompressionScheme scheme = ERLECompression;
1641 if (bmpptr->Address()->iHeader.iCompression == EGenericPaletteCompression)
1642 scheme = EPaletteCompression;
1643 ret = newbmpptr->Address()->CompressData(scheme); // re-compress
1644 if (ret != KErrNone)
1650 TInt newlocalhandle = 0;
1651 TRAP(ret, newlocalhandle = iIx->AddL(newbmpptr));
1652 if (ret != KErrNone)
1657 ret = newbmpptr->Open();
1658 if (ret != KErrNone)
1660 iIx->Remove(newlocalhandle);
1663 bmpptr->SetCleanBitmap(newbmpptr);
1664 if (bmpptr->AccessCount() >= 2)
1666 fbtop->NotifyDirtyBitmap(*bmpptr, this);
1668 iIx->Remove(localhandle);
1669 TPckgBuf<TBmpHandles> handlebuffer;
1670 handlebuffer().iHandle = newlocalhandle;
1671 handlebuffer().iServerHandle = newbmpptr->Handle();
1672 handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
1673 ret = aMessage.Write(3, handlebuffer);
1674 if (ret != KErrNone)
1676 iIx->Remove(newlocalhandle);
1677 aMessage.Panic(KFBSERVPanicCategory, ret);
1680 FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_SEMANTICS, CFBCLIENT_PROCBITMAPMESSAGE_INFO4, "# Server bitmap resized; iSSH=0x%08x; iOldH=0x%08x; iNewH=0x%08x; iNewSH=0x%08x; newbytes=%d;", iSessionHandle, localhandle, newlocalhandle, newbmpptr->Handle(), newbmpptr->Address()->DataStride() * newsize.iHeight);)
1683 case EFbsMessBitmapDuplicate:
1685 bmpptr = TopLevelStore()->FindBitmap(aMessage.Int0());
1691 //coverity [check_return]
1692 //coverity [unchecked_value]
1693 TopLevelStore()->GetCleanBitmap(bmpptr);
1694 ret = bmpptr->Open();
1695 if (ret != KErrNone)
1699 TPckgBuf<TBmpHandles> handlebuffer;
1700 TRAP(ret,localhandle=iIx->AddL(bmpptr));
1706 handlebuffer().iHandle = localhandle;
1707 handlebuffer().iServerHandle = bmpptr->Handle();
1708 handlebuffer().iAddressOffset = TInt(bmpptr->Address()) - TopLevelStore()->HeapBase();
1709 ret = aMessage.Write(1, handlebuffer);
1712 iIx->Remove(localhandle);
1713 aMessage.Panic(KFBSERVPanicCategory,ret);
1717 FBS_OST(OstTraceExt5( GRAPHICS_RESOURCE_MANAGEMENT_SEMANTICS, CFBCLIENT_PROCBITMAPMESSAGE_INFO3, "# Server bitmap duplicated; iSSH=0x%08x; rc=%d; iH=0x%08x; iSH=0x%08x; bytes=%d;", iSessionHandle, iResourceCount, handlebuffer().iHandle, handlebuffer().iServerHandle, bmpptr->Address()->DataStride() * bmpptr->Address()->SizeInPixels().iHeight);)
1720 case EFbsMessBitmapCompress:
1722 localhandle = aMessage.Int0();
1723 CFbTop* fbtop = TopLevelStore();
1724 bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
1730 ret = fbtop->GetCleanBitmap(bmpptr);
1731 if (ret != KErrNone)
1735 const TSize size = bmpptr->Address()->SizeInPixels();
1736 const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
1737 CBitmapObject* newbmpptr = NULL;
1738 TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
1739 if (ret != KErrNone)
1743 ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
1744 if (ret != KErrNone)
1749 ret = newbmpptr->Address()->CompressData((TBitmapfileCompressionScheme)aMessage.Int1());
1750 if (ret != KErrNone)
1755 TInt newlocalhandle = 0;
1756 TRAP(ret, newlocalhandle = iIx->AddL(newbmpptr));
1757 if (ret != KErrNone)
1762 ret = newbmpptr->Open();
1763 if (ret != KErrNone)
1765 iIx->Remove(newlocalhandle);
1768 bmpptr->SetCleanBitmap(newbmpptr);
1769 if (bmpptr->AccessCount() >= 2)
1771 fbtop->NotifyDirtyBitmap(*bmpptr, this);
1773 iIx->Remove(localhandle);
1774 TPckgBuf<TBmpHandles> handlebuffer;
1775 handlebuffer().iHandle = newlocalhandle;
1776 handlebuffer().iServerHandle = newbmpptr->Handle();
1777 handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
1778 ret = aMessage.Write(2, handlebuffer);
1779 if (ret != KErrNone)
1781 iIx->Remove(newlocalhandle);
1782 aMessage.Panic(KFBSERVPanicCategory, ret);
1785 FBS_OST(OstTraceExt4( GRAPHICS_RESOURCE_MANAGEMENT_SEMANTICS, CFBCLIENT_PROCBITMAPMESSAGE_INFO5, "# Server bitmap compressed; iSSH=0x%08x; iOldH=0x%08x; iNewH=0x%08x; iNewSH=0x%08x;", (TUint)iSessionHandle, localhandle, newlocalhandle, handlebuffer().iServerHandle);)
1788 case EFbsMessBitmapBgCompress:
1790 localhandle = aMessage.Int0();
1791 TBitmapfileCompressionScheme scheme = (TBitmapfileCompressionScheme)aMessage.Int1();
1792 TBool async = aMessage.Int2();
1793 CFbTop* fbtop = TopLevelStore();
1794 bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
1800 ret = fbtop->GetCleanBitmap(bmpptr);
1801 if (ret != KErrNone)
1809 ret = bmpptr->Address()->CheckBackgroundCompressData();
1810 if (KErrNone == ret)
1812 ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
1813 if (ret == KErrNone && async)
1815 return; // do not complete the client's request - that will be done by the background compression thread
1818 if (KErrAlreadyExists == ret)
1824 case EFbsMessBitmapClean:
1826 TInt localhandle = aMessage.Int0();
1827 CFbTop* fbtop = TopLevelStore();
1828 bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
1834 ret = fbtop->GetCleanBitmap(bmpptr);
1835 if (ret != KErrNone)
1839 ret = bmpptr->Open();
1840 if (ret != KErrNone)
1844 TInt cleanlocalhandle = 0;
1845 TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
1846 if (ret != KErrNone)
1851 iIx->Remove(localhandle);
1852 TPckgBuf<TBmpHandles> handlebuffer;
1853 handlebuffer().iHandle = cleanlocalhandle;
1854 handlebuffer().iServerHandle = bmpptr->Handle();
1855 handlebuffer().iAddressOffset = TInt(bmpptr->Address()) - fbtop->HeapBase();
1856 ret = aMessage.Write(1, handlebuffer);
1857 if (ret != KErrNone)
1859 iIx->Remove(cleanlocalhandle);
1860 aMessage.Panic(KFBSERVPanicCategory, ret);
1863 FBS_OST(OstTraceExt3( GRAPHICS_RESOURCE_MANAGEMENT_SEMANTICS, CFBCLIENT_PROCBITMAPMESSAGE_INFO6, "# Server bitmap cleaned; iSSH=0x%08x; iOldH=0x%08x; iNewH=0x%08x;", iSessionHandle, localhandle, cleanlocalhandle);)
1866 case EFbsGetAllBitmapHandles:
1868 ret = TopLevelStore()->GetAllBitmapHandles(aMessage);
1872 case EFbsMessBitmapNotifyDirty:
1874 if (iHelper == NULL)
1876 iHelper = new TFbClientHelper(*this);
1877 if (iHelper == NULL)
1882 TopLevelStore()->AddClientHelper(*iHelper);
1884 if (!iHelper->iMessage.IsNull())
1886 aMessage.Panic(KFBSERVPanicCategory, KErrAlreadyExists);
1889 if (!iHelper->iDirty)
1891 iHelper->iMessage = aMessage;
1892 return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
1894 iHelper->iDirty = EFalse;
1897 case EFbsMessBitmapCancelNotifyDirty:
1899 if (iHelper != NULL && !iHelper->iMessage.IsNull())
1901 iHelper->iMessage.Complete(KErrCancel);
1909 if(!aMessage.IsNull())
1911 aMessage.Complete(ret);
1919 void CFbClient::NotifyDirtyBitmap(CBitmapObject& aBmpObj)
1921 if (iHelper != NULL && iIx->At(&aBmpObj) != KErrNotFound)
1923 iHelper->iDirty = ETrue;
1924 if (!iHelper->iMessage.IsNull())
1926 iHelper->iMessage.Complete(KErrNone);
1927 iHelper->iDirty = EFalse;
1932 void CFbClient::AddFontFileIndexL(TUid aId)
1934 TInt count=iFontFileIndex->Count();
1935 for (TInt index=0;index<count;index++)
1937 if (iFontFileIndex->At(index).iUid==aId)
1939 iFontFileIndex->At(index).iAccessCount++;
1940 TopLevelStore()->FontStore()->RemoveFile(aId);
1945 TFontFileIndex fontFileIndex;
1946 fontFileIndex.iUid=aId;
1947 fontFileIndex.iAccessCount=1;
1948 iFontFileIndex->AppendL(fontFileIndex);
1951 void CFbClient::RemoveFontFileIndex(TUid aId)
1953 TInt count=iFontFileIndex->Count();
1954 for (TInt index=0;index<count;index++)
1956 TFontFileIndex* fontFileIndex=&iFontFileIndex->At(index);
1957 if (fontFileIndex->iUid==aId)
1959 fontFileIndex->iAccessCount--;
1960 if (fontFileIndex->iAccessCount<1)
1962 TopLevelStore()->FontStore()->RemoveFile(fontFileIndex->iUid);
1963 iFontFileIndex->Delete(index);
1968 // not found - must be an installed file or rubbish, so try anyway
1969 TopLevelStore()->FontStore()->RemoveFile(aId);
1972 void CFbClient::Disconnect(const RMessage2 &aMessage)
1974 // if any bitmaps are in the background compression queue with a to-be-completed RMessage2 from this session,
1975 // the RMessage2 must be completed now as it is only possible to complete messages on existing sessions
1976 TopLevelStore()->BackgroundCompression()->CompleteOutstandingRequests(this);
1978 // if there is a to-be-completed request for dirty bitmap notification complete it now
1981 if (!iHelper->iMessage.IsNull())
1983 iHelper->iMessage.Complete(KErrDisconnected);
1990 // Clear the mbm file store cache resources that corresponds to this session
1991 TopLevelStore()->CloseFileStores(iSessionHandle);
1993 CSession2::Disconnect(aMessage);
1997 void CFbClient::ProcMemMessage(const RMessage2 &aMessage)
2000 TInt parameterForFunctionCall;
2001 TInt cells = User::Heap().Available(parameterForFunctionCall);
2002 switch(aMessage.Function())
2004 case EFbsMessSetHeapFail:
2005 if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
2007 iOwnHeapFailNumber=aMessage.Int1();
2011 iSharedHeapFailNumber=aMessage.Int1();
2014 case EFbsMessHeapCount:
2015 if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
2017 ret=User::CountAllocCells();
2024 case EFbsMessSetHeapReset:
2025 if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
2027 iOwnHeapFailNumber=-1;
2031 iSharedHeapFailNumber=-1;
2034 case EFbsMessSetHeapCheck:
2035 if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
2037 iOwnHeapCheckFlip=ETrue;
2041 iHeapCheckFlip=ETrue;
2050 aMessage.Complete(ret);
2055 Processes messages associated with the Glyph Atlas.
2056 @param aMessage The message used to perform IPC to the client.
2058 void CFbClient::ProcAtlasMessage(const RMessage2 &aMessage)
2060 TInt ret = KErrNone;
2061 CFbTop* fbtop = TopLevelStore();
2062 CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
2065 ret = KErrNotSupported;
2069 switch(aMessage.Function())
2071 case EFbsMessAtlasFontCount:
2072 ret = glyphAtlas->FontCount();
2074 case EFbsMessAtlasGlyphCount:
2076 TInt fontHandle = aMessage.Int0();
2077 if (fontHandle != 0)
2079 if (fbtop->ValidFontHandle(fontHandle))
2081 CFontObject* fontptr = reinterpret_cast<CFontObject*>(fontHandle);
2082 ret = glyphAtlas->GlyphCount(static_cast<CBitmapFont&>(*(fontptr->iAddressPointer)));
2091 ret = glyphAtlas->GlyphCount();
2099 aMessage.Complete(ret);