os/graphics/fbs/fontandbitmapserver/sfbs/FBSCLI.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include <fntstore.h>
sl@0
    17
#include <bitmap.h>
sl@0
    18
#include <openfont.h>
sl@0
    19
#include <graphics/fbsoogmmessage.h>
sl@0
    20
#include "FbsMessage.H"
sl@0
    21
#include "SERVER.H"
sl@0
    22
#include "BackGroundCompression.h"
sl@0
    23
#include <shapeinfo.h>
sl@0
    24
#include <graphics/shaperparams.h>
sl@0
    25
#include "glyphatlas.h"
sl@0
    26
#include "OstTraceDefinitions.h"
sl@0
    27
#include "fbstrace.h"
sl@0
    28
#ifdef OST_TRACE_COMPILER_IN_USE
sl@0
    29
#include "FBSCLITraces.h"
sl@0
    30
#endif
sl@0
    31
sl@0
    32
sl@0
    33
/**
sl@0
    34
Bitwise mask that sets the MSB to indicate to a font rasterizer
sl@0
    35
that a code is a glyphcode and not a character code
sl@0
    36
*/
sl@0
    37
const TUint32 KTreatAsGlyphCodeFlag = 1UL << 31;
sl@0
    38
sl@0
    39
/** Helper function for converting a pointer to an offset from the passed
sl@0
    40
heap base. Use OffsetToPointer() to convert the returned offset back to a
sl@0
    41
useable pointer.
sl@0
    42
@param aAny A pointer to be converted to an offset.
sl@0
    43
@param aHeapBase The heap base of the current process.
sl@0
    44
@return An offset representing the passed pointer that can be converted
sl@0
    45
back to a pointer using the function OffsetToPointer(). 
sl@0
    46
@see OffsetToPointer()
sl@0
    47
 */
sl@0
    48
LOCAL_C TInt PointerToOffset(const TAny* aAny, TInt aHeapBase)
sl@0
    49
	{
sl@0
    50
	TInt offset = 0;
sl@0
    51
	if (aAny && aHeapBase)
sl@0
    52
		{
sl@0
    53
		offset = reinterpret_cast<TInt>(aAny) - aHeapBase;
sl@0
    54
		}
sl@0
    55
	return offset;
sl@0
    56
	}
sl@0
    57
sl@0
    58
/** Helper function for converting an offset (that was calculated using
sl@0
    59
PointerToOffset()) back to a pointer relative to the passed heap base.
sl@0
    60
@param aOffset The offset to be converted to a pointer.
sl@0
    61
@param aHeapBase The heap base of the current process.
sl@0
    62
@return A pointer relative to the passed heap base.
sl@0
    63
@see PointerToOffset()
sl@0
    64
 */
sl@0
    65
LOCAL_C TAny* OffsetToPointer(TInt aOffset, TInt aHeapBase)
sl@0
    66
	{
sl@0
    67
	if (aOffset && aHeapBase)
sl@0
    68
		{
sl@0
    69
		return reinterpret_cast<TAny*>(aOffset + aHeapBase);
sl@0
    70
		}
sl@0
    71
	return NULL;
sl@0
    72
	}
sl@0
    73
sl@0
    74
CFbClient::CFbClient(RHeap* aHeap):
sl@0
    75
	CSession2(),
sl@0
    76
	iHeap(aHeap)
sl@0
    77
#ifdef _DEBUG
sl@0
    78
	,iOwnHeapFailNumber(-1),
sl@0
    79
	iSharedHeapFailNumber(-1)
sl@0
    80
#endif	
sl@0
    81
	{
sl@0
    82
	}
sl@0
    83
sl@0
    84
CFbClient* CFbClient::NewL(RHeap* aHeap)
sl@0
    85
	{
sl@0
    86
	CFbClient* self = new (ELeave) CFbClient(aHeap);
sl@0
    87
	CleanupStack::PushL(self);
sl@0
    88
	self->ConstructL();
sl@0
    89
	CleanupStack::Pop(); // self;
sl@0
    90
	return self;
sl@0
    91
	}
sl@0
    92
sl@0
    93
/**
sl@0
    94
Two-phase constructor.
sl@0
    95
@leave KErrNoMemory if TOpenFontGlyphData construction failed.
sl@0
    96
*/
sl@0
    97
void CFbClient::ConstructL()
sl@0
    98
	{
sl@0
    99
	iOpenFontGlyphData = TOpenFontGlyphData::New(iHeap, 4 * 1024);
sl@0
   100
	if (!iOpenFontGlyphData)
sl@0
   101
		{
sl@0
   102
		User::Leave(KErrNoMemory);
sl@0
   103
		}
sl@0
   104
	}
sl@0
   105
sl@0
   106
CFbClient::~CFbClient()
sl@0
   107
	{
sl@0
   108
	/*
sl@0
   109
	Don't call any CFontStore functions if CFbClient::NewL has left, or if FBSERV has already deleted the
sl@0
   110
	font store, which happens in test programs like TFBS when FBSERV is closed before the client(s).
sl@0
   111
	*/
sl@0
   112
	CFontStore* font_store = NULL;
sl@0
   113
	CFbTop* fbTop = TopLevelStore();
sl@0
   114
	if (fbTop)
sl@0
   115
		{
sl@0
   116
		font_store = fbTop->FontStore();
sl@0
   117
		}
sl@0
   118
	
sl@0
   119
	if (font_store)
sl@0
   120
		{
sl@0
   121
		font_store->DeleteSessionCache(iSessionHandle);
sl@0
   122
		font_store->CleanupCacheOnFbsSessionTermination(iSessionHandle);
sl@0
   123
		
sl@0
   124
		// If the font store doesn't exist, neither will the shared heap owned by FBSERV.
sl@0
   125
		iHeap->Free(iOpenFontGlyphData);
sl@0
   126
		}
sl@0
   127
	
sl@0
   128
	// delete fonts held by the client
sl@0
   129
	delete iIx;
sl@0
   130
	
sl@0
   131
	// delete font files held by the client
sl@0
   132
	if (iFontFileIndex)
sl@0
   133
		{
sl@0
   134
		TInt count = iFontFileIndex->Count();
sl@0
   135
		for (TInt index = 0;index < count; index++)
sl@0
   136
			{
sl@0
   137
			if (font_store)
sl@0
   138
				{
sl@0
   139
				font_store->RemoveFile(iFontFileIndex->At(0).iUid);
sl@0
   140
				}
sl@0
   141
			iFontFileIndex->Delete(0);
sl@0
   142
			}
sl@0
   143
		delete iFontFileIndex;
sl@0
   144
		}
sl@0
   145
sl@0
   146
	// Close the buffer used to hold the text that needs shaping.
sl@0
   147
	iTextToShape.Close();
sl@0
   148
sl@0
   149
	for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
sl@0
   150
		{
sl@0
   151
		iGlyphImagesInTransit[i].Close();
sl@0
   152
		}
sl@0
   153
	iGlyphImagesInTransit.Close();
sl@0
   154
	}
sl@0
   155
sl@0
   156
void CFbClient::Init(TUint aConnectionHandle)
sl@0
   157
	{
sl@0
   158
	iConnectionHandle=aConnectionHandle;
sl@0
   159
	}
sl@0
   160
sl@0
   161
void CFbClient::CreateL()
sl@0
   162
	{
sl@0
   163
	iIx=CObjectIx::NewL();
sl@0
   164
	iFontFileIndex=new(ELeave) CArrayFixFlat<TFontFileIndex>(1);
sl@0
   165
	}
sl@0
   166
sl@0
   167
CFontBitmapServer* CFbClient::FontBitmapServer()
sl@0
   168
	{
sl@0
   169
	return((CFontBitmapServer*)Server());
sl@0
   170
	}
sl@0
   171
sl@0
   172
CFbTop* CFbClient::TopLevelStore()
sl@0
   173
	{
sl@0
   174
	CFontBitmapServer* server = FontBitmapServer();
sl@0
   175
	if (server)
sl@0
   176
		{
sl@0
   177
		return server->TopLevelStore();
sl@0
   178
		}
sl@0
   179
	else
sl@0
   180
		{
sl@0
   181
		return NULL;
sl@0
   182
		}
sl@0
   183
	}
sl@0
   184
sl@0
   185
void CFbClient::CopyFontInfo(CFontObject* aFontObjPtr,TInt aHandle,TFontInfo& aFontInfo)
sl@0
   186
	{
sl@0
   187
	CBitmapFont* font=aFontObjPtr->iAddressPointer;
sl@0
   188
	aFontInfo.iHandle = aHandle;
sl@0
   189
	aFontInfo.iServerHandle=(TInt)aFontObjPtr;
sl@0
   190
	aFontInfo.iAddressOffset=TInt(font)-TopLevelStore()->HeapBase();
sl@0
   191
	}
sl@0
   192
sl@0
   193
void CFbClient::ServiceL(const RMessage2& aMessage)
sl@0
   194
	{
sl@0
   195
sl@0
   196
#ifdef _DEBUG
sl@0
   197
	TBool resetOwnHeap=EFalse;
sl@0
   198
	TBool resetSharedHeap=EFalse;
sl@0
   199
	
sl@0
   200
	//the memory tests have been mostly written to have start and end memory
sl@0
   201
	//function calls (or macros) at the start of this function call (ServiceL)
sl@0
   202
	//and the matching call (or macro) is at the end of this function.
sl@0
   203
	
sl@0
   204
	if (iOwnHeapFailNumber!=-1)
sl@0
   205
		{
sl@0
   206
		//if this not -1 then know to set the heap to fail on
sl@0
   207
		//the given number of allocations
sl@0
   208
		
sl@0
   209
		resetOwnHeap=ETrue;
sl@0
   210
		__UHEAP_SETFAIL(RHeap::EDeterministic,iOwnHeapFailNumber);
sl@0
   211
		}
sl@0
   212
	if (iSharedHeapFailNumber!=-1)
sl@0
   213
		{
sl@0
   214
		resetSharedHeap=ETrue;
sl@0
   215
		__RHEAP_SETFAIL (iHeap, RHeap::EDeterministic,iSharedHeapFailNumber);
sl@0
   216
		}	
sl@0
   217
sl@0
   218
	if (iOwnHeapCheck)
sl@0
   219
		{
sl@0
   220
		__UHEAP_MARK;
sl@0
   221
		}					
sl@0
   222
	if (iHeapCheck)
sl@0
   223
		{
sl@0
   224
		__RHEAP_MARK(iHeap);
sl@0
   225
		}		
sl@0
   226
#endif		
sl@0
   227
	//Call close on RSgImage handles being used to share glyph data with clients.
sl@0
   228
	//The glyph images are held open to prevent the GlyphAtlas from closing them
sl@0
   229
	//before a client can use them.
sl@0
   230
	for (TInt i = iGlyphImagesInTransit.Count() - 1; i >= 0; --i)
sl@0
   231
		{
sl@0
   232
		iGlyphImagesInTransit[i].Close();
sl@0
   233
		iGlyphImagesInTransit.Remove(i);
sl@0
   234
		}
sl@0
   235
	
sl@0
   236
	switch(aMessage.Function())
sl@0
   237
		{
sl@0
   238
// client messages
sl@0
   239
	case EFbsMessInit:
sl@0
   240
		Init(FontBitmapServer()->Init());
sl@0
   241
		iSessionHandle = (TInt)this;
sl@0
   242
		aMessage.Complete(iSessionHandle);
sl@0
   243
#ifdef _DEBUG
sl@0
   244
		iRet=KErrNone;
sl@0
   245
#endif		
sl@0
   246
		break;
sl@0
   247
	case EFbsMessClose:
sl@0
   248
		{
sl@0
   249
		TInt localhandle=aMessage.Int0();
sl@0
   250
		if(!iIx->At(localhandle))
sl@0
   251
			{
sl@0
   252
			aMessage.Panic(KFBSERVPanicCategory,KErrNotFound);
sl@0
   253
			break;
sl@0
   254
			}
sl@0
   255
		iIx->Remove(localhandle);
sl@0
   256
		iResourceCount--;
sl@0
   257
		aMessage.Complete(KErrNone);
sl@0
   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);)
sl@0
   259
#ifdef _DEBUG
sl@0
   260
		iRet=KErrNone;
sl@0
   261
#endif				
sl@0
   262
		break;
sl@0
   263
		}
sl@0
   264
	case EFbsMessResourceCount:
sl@0
   265
		aMessage.Complete(iResourceCount);
sl@0
   266
#ifdef _DEBUG
sl@0
   267
		iRet=iResourceCount;
sl@0
   268
#endif			
sl@0
   269
		break;
sl@0
   270
// server messages
sl@0
   271
	case EFbsMessShutdown:
sl@0
   272
	case EFbsMessNumTypefaces:
sl@0
   273
	case EFbsMessTypefaceSupport:
sl@0
   274
	case EFbsMessFontHeightInTwips:
sl@0
   275
	case EFbsMessFontHeightInPixels:
sl@0
   276
	case EFbsMessSetPixelHeight:
sl@0
   277
	case EFbsMessDefaultAllocFail:
sl@0
   278
	case EFbsMessDefaultMark:
sl@0
   279
	case EFbsMessDefaultMarkEnd:
sl@0
   280
	case EFbsMessUserAllocFail:
sl@0
   281
	case EFbsMessUserMark:
sl@0
   282
	case EFbsMessUserMarkEnd:
sl@0
   283
	case EFbsMessHeapCheck:
sl@0
   284
	case EFbsMessSetDefaultGlyphBitmapType:
sl@0
   285
	case EFbsMessGetDefaultGlyphBitmapType:
sl@0
   286
	case EFbsMessFontNameAlias:
sl@0
   287
	case EFbsMessGetHeapSizes:
sl@0
   288
	case EFbsMessDefaultLanguageForMetrics:
sl@0
   289
	case EFbsCompress:
sl@0
   290
	case EFbsMessFetchLinkedTypeface:
sl@0
   291
	case EFbsMessRegisterLinkedTypeface:
sl@0
   292
	case EFbsMessUpdateLinkedTypeface:
sl@0
   293
sl@0
   294
#ifdef _DEBUG
sl@0
   295
		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle,iRet);
sl@0
   296
#else
sl@0
   297
		FontBitmapServer()->ProcMessage(aMessage,iSessionHandle);
sl@0
   298
#endif			
sl@0
   299
		break;
sl@0
   300
// font messages
sl@0
   301
	case EFbsMessFontDuplicate:
sl@0
   302
	case EFbsMessGetNearestFontToDesignHeightInTwips:
sl@0
   303
	case EFbsMessGetNearestFontToDesignHeightInPixels:
sl@0
   304
	case EFbsMessGetNearestFontToMaxHeightInTwips:
sl@0
   305
	case EFbsMessGetNearestFontToMaxHeightInPixels:
sl@0
   306
	case EFbsMessGetFontById:
sl@0
   307
	case EFbsMessInstallFontStoreFile:
sl@0
   308
	case EFbsMessAddFontStoreFile:
sl@0
   309
	case EFbsMessRemoveFontStoreFile:
sl@0
   310
	case EFbsMessRasterize:
sl@0
   311
	case EFbsMessFaceAttrib:
sl@0
   312
	case EFbsMessHasCharacter:
sl@0
   313
	case EFbsMessShapeText:
sl@0
   314
	case EFbsMessShapeDelete:
sl@0
   315
	case EFbsMessSetTwipsHeight:
sl@0
   316
	case EFbsMessGetTwipsHeight:
sl@0
   317
	case EFbsSetSystemDefaultTypefaceName:
sl@0
   318
	case EFbsMessGetFontTable:
sl@0
   319
	case EFbsMessReleaseFontTable:
sl@0
   320
	case EFbsMessGetGlyphOutline:
sl@0
   321
	case EFbsMessReleaseGlyphOutline: 
sl@0
   322
#if (_DEBUG)
sl@0
   323
	case EFbsMessSetDuplicateFail:
sl@0
   324
#endif
sl@0
   325
	case EFbsMessGetGlyphs:
sl@0
   326
	case EFbsMessGetGlyphMetrics:
sl@0
   327
		ProcFontMessage(aMessage);
sl@0
   328
		break;
sl@0
   329
// bitmap messages
sl@0
   330
	case EFbsMessBitmapCreate:
sl@0
   331
	case EFbsMessBitmapResize:
sl@0
   332
	case EFbsMessBitmapDuplicate:
sl@0
   333
	case EFbsMessBitmapLoad:
sl@0
   334
	case EFbsMessBitmapCompress:
sl@0
   335
	case EFbsMessBitmapBgCompress:
sl@0
   336
	case EFbsMessBitmapClean:
sl@0
   337
	case EFbsGetAllBitmapHandles:
sl@0
   338
	case EFbsMessBitmapLoadFast:
sl@0
   339
	case EFbsMessBitmapNotifyDirty:
sl@0
   340
	case EFbsMessBitmapCancelNotifyDirty:
sl@0
   341
		ProcBitmapMessage(aMessage);
sl@0
   342
		break;
sl@0
   343
//Memory messages		
sl@0
   344
	case EFbsMessSetHeapFail:
sl@0
   345
	case EFbsMessHeapCount:
sl@0
   346
	case EFbsMessSetHeapReset:
sl@0
   347
	case EFbsMessSetHeapCheck:
sl@0
   348
	case EFbsMessHeap:
sl@0
   349
#ifdef _DEBUG	
sl@0
   350
		ProcMemMessage(aMessage);
sl@0
   351
#else
sl@0
   352
		aMessage.Complete(KErrNone);
sl@0
   353
#endif	
sl@0
   354
		break;
sl@0
   355
// Glyph Atlas messages (debug-only)
sl@0
   356
	case EFbsMessAtlasFontCount:
sl@0
   357
	case EFbsMessAtlasGlyphCount:
sl@0
   358
#ifdef _DEBUG
sl@0
   359
		ProcAtlasMessage(aMessage);
sl@0
   360
#else
sl@0
   361
		aMessage.Complete(KErrNotSupported);
sl@0
   362
#endif
sl@0
   363
		break;
sl@0
   364
    case EFbsMessOogmNotification:
sl@0
   365
sl@0
   366
        aMessage.Complete( HandleMesgOogmStatus( aMessage ) );
sl@0
   367
        break;
sl@0
   368
    case EFbsMessGetGlyphCacheMetrics:
sl@0
   369
sl@0
   370
        HandleMesgGlyphCacheMetrics( aMessage );
sl@0
   371
        break;
sl@0
   372
sl@0
   373
//No-op message
sl@0
   374
	case EFbsMessNoOp:
sl@0
   375
#ifdef _DEBUG
sl@0
   376
		iRet = KErrNone;
sl@0
   377
#endif
sl@0
   378
		aMessage.Complete(KErrNone);
sl@0
   379
		break;
sl@0
   380
	default:
sl@0
   381
		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
sl@0
   382
		break;
sl@0
   383
		}
sl@0
   384
#ifdef _DEBUG
sl@0
   385
sl@0
   386
	//do not want a memory panic if the return code is OK
sl@0
   387
	//__UHEAP_MARKEND does this
sl@0
   388
	
sl@0
   389
	if (iOwnHeapCheck)
sl@0
   390
		{
sl@0
   391
		TUint32 badCell=User::Heap().__DbgMarkEnd(0);
sl@0
   392
		if (iRet<0)
sl@0
   393
			{
sl@0
   394
			//if the function call was a success, there may have been valid memory allocations,
sl@0
   395
			//so only panic if the call failed, and the memory is not the same before and after the
sl@0
   396
			//function call
sl@0
   397
			__ASSERT_DEBUG (badCell==NULL,User::Panic(KFBSERVPanicCategory, KErrGeneral));
sl@0
   398
			}
sl@0
   399
		}					
sl@0
   400
	if (iHeapCheck)
sl@0
   401
		{
sl@0
   402
		TUint32 badCell2=0;
sl@0
   403
		badCell2= __RHEAP_MARKEND(iHeap);
sl@0
   404
		//the above function call does not panic if there is a failure, this is
sl@0
   405
		//only for the user heap
sl@0
   406
		if (iRet<0)
sl@0
   407
			{
sl@0
   408
			__ASSERT_DEBUG (badCell2==NULL,User::Panic(KFBSERVPanicCategory, KErrGeneral));
sl@0
   409
			}
sl@0
   410
		}
sl@0
   411
	//change the state of the memory check?	
sl@0
   412
	if (iOwnHeapCheckFlip)
sl@0
   413
		{
sl@0
   414
		//change the state of the memory testing
sl@0
   415
		//if the mark was set still need to have a mark end
sl@0
   416
		iOwnHeapCheckFlip=EFalse;
sl@0
   417
		iOwnHeapCheck=!iOwnHeapCheck;
sl@0
   418
		}
sl@0
   419
	if (iHeapCheckFlip)
sl@0
   420
		{
sl@0
   421
		iHeapCheckFlip=EFalse;
sl@0
   422
		iHeapCheck=!iHeapCheck;
sl@0
   423
		}
sl@0
   424
		
sl@0
   425
	if (resetOwnHeap)
sl@0
   426
		{
sl@0
   427
		//previously set failures, reset
sl@0
   428
		__UHEAP_RESET;
sl@0
   429
		}
sl@0
   430
	if (resetSharedHeap)
sl@0
   431
		{		
sl@0
   432
		__RHEAP_RESET (iHeap);
sl@0
   433
		}		
sl@0
   434
#endif		
sl@0
   435
	}
sl@0
   436
sl@0
   437
sl@0
   438
/** Handler for EFbsMessFontDuplicate message
sl@0
   439
 @param aMessage input parameters
sl@0
   440
 @param aPanicRequired flag that is set if a client panic is required
sl@0
   441
 @return KErrNone if successful, otherwise a system wide error code
sl@0
   442
 */
sl@0
   443
TInt CFbClient::HandleMesgFontDuplicate(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   444
	{
sl@0
   445
#if _DEBUG
sl@0
   446
	if (iFontDuplicateToFail)
sl@0
   447
		{
sl@0
   448
		return KErrNoMemory; //return with this error since this error is possible
sl@0
   449
		}
sl@0
   450
#endif
sl@0
   451
	CFontObject* fontptr = (CFontObject*) aMessage.Int0();
sl@0
   452
	if(!TopLevelStore()->ValidFontHandle((TInt)fontptr))
sl@0
   453
		{
sl@0
   454
		return KErrUnknown;
sl@0
   455
		}
sl@0
   456
sl@0
   457
	TPckgBuf<TFontInfo> fontinfo;
sl@0
   458
	TInt localhandle = 0;
sl@0
   459
	TInt ret = fontptr->Open();
sl@0
   460
	if (ret != KErrNone)
sl@0
   461
		{
sl@0
   462
		return ret;
sl@0
   463
		}
sl@0
   464
	TRAP(ret, localhandle=iIx->AddL(fontptr));
sl@0
   465
	if (ret != KErrNone)
sl@0
   466
		{
sl@0
   467
		fontptr->Close();
sl@0
   468
		return ret;
sl@0
   469
		}
sl@0
   470
	CopyFontInfo(fontptr,localhandle,fontinfo());
sl@0
   471
	fontptr->iHeightInTwips = ((fontptr->iAddressPointer->HeightInPixels() * fontptr->iFontStore->iKPixelHeightInTwips) + 667) / 1000;
sl@0
   472
	ret = aMessage.Write(1, fontinfo);
sl@0
   473
	if(ret != KErrNone)
sl@0
   474
		{
sl@0
   475
		iIx->Remove(localhandle);
sl@0
   476
		aPanicRequired = ETrue;
sl@0
   477
		return ret;
sl@0
   478
		}
sl@0
   479
sl@0
   480
	// success
sl@0
   481
	iResourceCount++;
sl@0
   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);)
sl@0
   483
	return KErrNone;
sl@0
   484
	}
sl@0
   485
sl@0
   486
sl@0
   487
/** Handler for EFbsMessGetNearestFontToDesignHeightInTwips, EFbsMessGetNearestFontToDesignHeightInPixels, 
sl@0
   488
 EFbsMessGetNearestFontToMaxHeightInTwips or EFbsMessGetNearestFontToMaxHeightInPixels messages
sl@0
   489
 @param aMessage input and output parameters
sl@0
   490
 @param aPanicRequired flag that is set if a client panic is required
sl@0
   491
 @return KErrNone if successful, otherwise a system wide error code
sl@0
   492
 */
sl@0
   493
TInt CFbClient::HandleMesgGetNearestFont(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   494
	{
sl@0
   495
	CFontObject* fontptr = NULL;
sl@0
   496
	TPckgBuf<TFontSpec> pckgFontSpec;
sl@0
   497
	TInt pckgMaxHeight;
sl@0
   498
	TPckgBuf<TSizeInfo> info;
sl@0
   499
sl@0
   500
	const TFbsMessage fbsMessage = static_cast<TFbsMessage>(aMessage.Function());
sl@0
   501
sl@0
   502
	TInt ret = aMessage.Read(0, pckgFontSpec);
sl@0
   503
	TFontSpec& fontSpec = pckgFontSpec();
sl@0
   504
	if (ret == KErrNone )
sl@0
   505
		{
sl@0
   506
		TInt length = fontSpec.iTypeface.iName.Length();
sl@0
   507
		if((length < 0) || (length > TOpenFontFaceAttribBase::ENameLength))
sl@0
   508
			{
sl@0
   509
			aPanicRequired = ETrue;
sl@0
   510
			return KErrArgument;
sl@0
   511
			}	
sl@0
   512
		
sl@0
   513
		ret = aMessage.Read(2, info);
sl@0
   514
		if (ret == KErrNone)
sl@0
   515
			{
sl@0
   516
			pckgMaxHeight = info().iMaxHeight;
sl@0
   517
			TopLevelStore()->FontStore()->iKPixelHeightInTwips=info().iDevSize.iHeight;
sl@0
   518
			TopLevelStore()->FontStore()->iKPixelWidthInTwips=info().iDevSize.iWidth;
sl@0
   519
			}
sl@0
   520
		}
sl@0
   521
sl@0
   522
	if (KErrNone != ret)
sl@0
   523
		{
sl@0
   524
		aPanicRequired = ETrue;
sl@0
   525
		return ret;
sl@0
   526
		}
sl@0
   527
	if ( (EFbsMessGetNearestFontToMaxHeightInTwips == fbsMessage) || (EFbsMessGetNearestFontToMaxHeightInPixels == fbsMessage) )
sl@0
   528
		{
sl@0
   529
		ret = TopLevelStore()->GetNearestFont(fontptr, fbsMessage, fontSpec, pckgMaxHeight);
sl@0
   530
		}
sl@0
   531
	else
sl@0
   532
		{
sl@0
   533
		ret = TopLevelStore()->GetNearestFont(fontptr, fbsMessage, fontSpec);
sl@0
   534
		}
sl@0
   535
sl@0
   536
	if (ret == KErrNone)
sl@0
   537
		{ // package up the result
sl@0
   538
		ret = CopyFontInfoIntoReturnMessage(aMessage, aPanicRequired, fontptr, 1);
sl@0
   539
		}
sl@0
   540
sl@0
   541
	return ret;
sl@0
   542
	}
sl@0
   543
sl@0
   544
sl@0
   545
 /** package up the font that was found - includes cleanup handling in case of error
sl@0
   546
 @param aMessage input and output parameters
sl@0
   547
 @param aPanicRequired flag that is set if a client panic is required
sl@0
   548
 @param aFontObj the object that is to be returned
sl@0
   549
 @param aWritePosition the slot position in the message pointing to the receiving object
sl@0
   550
 @return KErrNone if successful, otherwise a system wide error code
sl@0
   551
 */
sl@0
   552
TInt CFbClient::CopyFontInfoIntoReturnMessage(const RMessage2& aMessage, TBool& aPanicRequired, CFontObject* aFontObj, TInt aWritePosition)
sl@0
   553
	{
sl@0
   554
	TInt localhandle = 0;
sl@0
   555
	TRAPD(ret, localhandle = iIx->AddL(aFontObj));
sl@0
   556
	if (KErrNone != ret)
sl@0
   557
		{
sl@0
   558
		aFontObj->Close();
sl@0
   559
		return ret;
sl@0
   560
		}
sl@0
   561
	TPckgBuf<TFontInfo> pckgFontInfo;
sl@0
   562
	CopyFontInfo(aFontObj, localhandle, pckgFontInfo());
sl@0
   563
	ret = aMessage.Write(aWritePosition, pckgFontInfo);
sl@0
   564
	if (KErrNone != ret)
sl@0
   565
		{
sl@0
   566
		iIx->Remove(localhandle);
sl@0
   567
		aPanicRequired = ETrue;
sl@0
   568
		return ret;
sl@0
   569
		}
sl@0
   570
	// success
sl@0
   571
	iResourceCount++;
sl@0
   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);)
sl@0
   573
	return KErrNone;
sl@0
   574
	}
sl@0
   575
sl@0
   576
sl@0
   577
/** Handler for EFbsMessGetFontById message
sl@0
   578
 Works for Bitmap fonts only, see implementation in CFbTop::GetFontById() & CFontStore::GetFontById().
sl@0
   579
 @param aMessage input and output parameters
sl@0
   580
 @param aPanicRequired flag that is set if a client panic is required
sl@0
   581
 @return KErrNone if successful, otherwise a system wide error code
sl@0
   582
 */
sl@0
   583
TInt CFbClient::HandleMesgGetFontById(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   584
	{
sl@0
   585
	CFontObject* fontptr = NULL;
sl@0
   586
	TPckgBuf<TAlgStyle> algstyle;
sl@0
   587
	TPckgBuf<TSize> size;
sl@0
   588
sl@0
   589
	TInt ret = aMessage.Read(1, algstyle);
sl@0
   590
	if (ret == KErrNone)
sl@0
   591
		{ // get font size
sl@0
   592
		ret = aMessage.Read(3, size);
sl@0
   593
		if (ret == KErrNone)
sl@0
   594
			{
sl@0
   595
			TopLevelStore()->FontStore()->iKPixelHeightInTwips = size().iHeight;
sl@0
   596
			TopLevelStore()->FontStore()->iKPixelWidthInTwips = size().iWidth;
sl@0
   597
			}
sl@0
   598
		}
sl@0
   599
	if (ret != KErrNone)
sl@0
   600
		{
sl@0
   601
		aPanicRequired = ETrue;
sl@0
   602
		return ret;
sl@0
   603
		}
sl@0
   604
	TUid fileid;
sl@0
   605
	fileid.iUid = aMessage.Int2();
sl@0
   606
	ret = TopLevelStore()->GetFontById(fontptr,fileid,algstyle());
sl@0
   607
sl@0
   608
	if (ret == KErrNone)
sl@0
   609
		{ // package up the result
sl@0
   610
		ret = CopyFontInfoIntoReturnMessage(aMessage, aPanicRequired, fontptr, 0);
sl@0
   611
		}
sl@0
   612
sl@0
   613
	return ret;
sl@0
   614
	}
sl@0
   615
sl@0
   616
sl@0
   617
/** Handler for EFbsMessInstallFontStoreFile or EFbsMessAddFontStoreFile messages
sl@0
   618
 @param aMessage input and output parameters
sl@0
   619
 @param aPanicRequired flag that is set if a client panic is required
sl@0
   620
 @return KErrNone if successful, otherwise a system wide error code
sl@0
   621
 */
sl@0
   622
TInt CFbClient::HandleMesgAddOrInstallFontFile(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   623
	{
sl@0
   624
	TPckgBuf<TIntParcel> id;
sl@0
   625
	TInt length=aMessage.Int1();
sl@0
   626
	
sl@0
   627
	if(length < 0 || length * sizeof(TText) >= KMaxTInt/2)
sl@0
   628
		{
sl@0
   629
		aPanicRequired = ETrue;
sl@0
   630
		return KErrArgument;
sl@0
   631
		}
sl@0
   632
	
sl@0
   633
	TText* buffer=(TText*)User::Alloc(length*sizeof(TText));
sl@0
   634
	if(buffer==NULL)
sl@0
   635
		{
sl@0
   636
		return KErrNoMemory;
sl@0
   637
		}
sl@0
   638
	TPtr filename(buffer,length,length);
sl@0
   639
	TInt ret = aMessage.Read(0,filename);
sl@0
   640
	if(ret!=KErrNone)
sl@0
   641
		{
sl@0
   642
		User::Free(buffer);
sl@0
   643
		aPanicRequired = ETrue;
sl@0
   644
		return ret;
sl@0
   645
		}
sl@0
   646
	TRAP(ret, id().iInt = TopLevelStore()->FontStore()->AddFileL(filename).iUid);
sl@0
   647
	User::Free(buffer);
sl@0
   648
	if (ret != KErrNone)
sl@0
   649
		{
sl@0
   650
		return ret;
sl@0
   651
		}
sl@0
   652
	TUid uid;
sl@0
   653
	uid.iUid=id().iInt;
sl@0
   654
	if (aMessage.Function() == EFbsMessAddFontStoreFile)
sl@0
   655
		{
sl@0
   656
		TRAP(ret, AddFontFileIndexL(uid));
sl@0
   657
		if (ret!=KErrNone)
sl@0
   658
			{
sl@0
   659
			TopLevelStore()->FontStore()->RemoveFile(uid);
sl@0
   660
			return ret;
sl@0
   661
			}
sl@0
   662
		}
sl@0
   663
	ret = aMessage.Write(2,id);
sl@0
   664
	if (ret!=KErrNone)
sl@0
   665
		{
sl@0
   666
		RemoveFontFileIndex(uid);
sl@0
   667
		aPanicRequired = ETrue;
sl@0
   668
		}
sl@0
   669
	return ret;
sl@0
   670
	}
sl@0
   671
sl@0
   672
sl@0
   673
/** Handler for EFbsMessRemoveFontStoreFile message
sl@0
   674
 @param aMessage input parameters
sl@0
   675
 @return KErrNone if successful
sl@0
   676
 */
sl@0
   677
TInt CFbClient::HandleMesgRemoveFontFile(const RMessage2& aMessage)
sl@0
   678
	{
sl@0
   679
	TUid uid;
sl@0
   680
	uid.iUid=aMessage.Int0();
sl@0
   681
	RemoveFontFileIndex(uid);
sl@0
   682
	return KErrNone;
sl@0
   683
	}
sl@0
   684
sl@0
   685
sl@0
   686
/** Handler for EFbsMessRasterize message
sl@0
   687
 @param aMessage input parameters
sl@0
   688
 @param aPanicRequired flag that is set if a client panic is required
sl@0
   689
 @return ETrue if successful, EFalse or any system-wide error code if not successful.
sl@0
   690
 */
sl@0
   691
TInt CFbClient::HandleMesgRasterize(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   692
	{
sl@0
   693
	CFbTop* fbtop = TopLevelStore();
sl@0
   694
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
sl@0
   695
	if(!fontptr)
sl@0
   696
		{
sl@0
   697
		aPanicRequired = ETrue;
sl@0
   698
		return KErrArgument;
sl@0
   699
		}
sl@0
   700
	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
sl@0
   701
	const TUint charCode = aMessage.Int1();
sl@0
   702
sl@0
   703
	if ( (bitmapFont != NULL) && (bitmapFont->Rasterize(iSessionHandle, charCode, iOpenFontGlyphData)) )
sl@0
   704
		{
sl@0
   705
		// Convert all pointers to be passed back to the client to offsets from
sl@0
   706
		// the heap base so that they can be recreated client side relative to the
sl@0
   707
		// client's heap base
sl@0
   708
		TInt heapbase = fbtop->HeapBase();
sl@0
   709
		TPckgBuf<TRasterizeParams> params;
sl@0
   710
		params().iMetricsOffset = PointerToOffset(iOpenFontGlyphData->Metrics(), heapbase);
sl@0
   711
		params().iBitmapPointerOffset = PointerToOffset(iOpenFontGlyphData->BitmapPointer(), heapbase);;
sl@0
   712
		TInt err = aMessage.Write(2, params);
sl@0
   713
		if (KErrNone != err)
sl@0
   714
			{
sl@0
   715
			aPanicRequired = ETrue;
sl@0
   716
			return err;
sl@0
   717
			}
sl@0
   718
		return ETrue;
sl@0
   719
		}
sl@0
   720
	return EFalse;
sl@0
   721
	}
sl@0
   722
sl@0
   723
/** Handler for EFbsMessGetGlyphs message.
sl@0
   724
Reads a batch of up to KMaxGlyphBatchSize glyph codes, and on success returns
sl@0
   725
the corresponding TGlyphImageInfo objects.
sl@0
   726
 @param aMessage input parameters
sl@0
   727
 @param aPanicRequired flag that is set if a client panic is required
sl@0
   728
 @return KErrNone if successful, otherwise any system-wide error code.
sl@0
   729
 */
sl@0
   730
TInt CFbClient::HandleMesgGetGlyphs(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   731
	{
sl@0
   732
	CFbTop* fbtop = TopLevelStore();
sl@0
   733
	// Previously requested glyphs were closed in ServiceL()
sl@0
   734
	CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
sl@0
   735
	if (!glyphAtlas)
sl@0
   736
		{
sl@0
   737
		return KErrNotSupported;
sl@0
   738
		}
sl@0
   739
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
sl@0
   740
	if(!fontptr)
sl@0
   741
		{
sl@0
   742
		aPanicRequired = ETrue;
sl@0
   743
		return KErrBadHandle;
sl@0
   744
		}
sl@0
   745
sl@0
   746
	TUint glyphCodes[KMaxGlyphBatchSize];
sl@0
   747
	TGlyphImageInfo glyphImageInfo[KMaxGlyphBatchSize];
sl@0
   748
	TPckg<TUint[KMaxGlyphBatchSize]> glyphBatchPckg(glyphCodes);
sl@0
   749
sl@0
   750
	TInt err = aMessage.Read(1, glyphBatchPckg);
sl@0
   751
	if (err != KErrNone)
sl@0
   752
		{
sl@0
   753
		aPanicRequired = ETrue;
sl@0
   754
		return err;
sl@0
   755
		}
sl@0
   756
	TInt glyphCodesCount = glyphBatchPckg.Length() / sizeof(TUint);
sl@0
   757
	if (glyphCodesCount > KMaxGlyphBatchSize)
sl@0
   758
		{
sl@0
   759
		aPanicRequired = ETrue;
sl@0
   760
		return KErrOverflow;
sl@0
   761
		}
sl@0
   762
sl@0
   763
	TInt glyphsProcessed = 0;
sl@0
   764
	CBitmapFont* font = fontptr->iAddressPointer;
sl@0
   765
	for (; (glyphsProcessed < glyphCodesCount); ++glyphsProcessed)
sl@0
   766
		{
sl@0
   767
		TUint32 glyphCode = glyphCodes[glyphsProcessed];
sl@0
   768
		err = glyphAtlas->GetGlyph(*font, glyphCode, glyphImageInfo[glyphsProcessed]);
sl@0
   769
		// Search for glyph in glyph atlas
sl@0
   770
		if (KErrNone != err)
sl@0
   771
			{
sl@0
   772
			const TUint8* bitmapData = NULL;
sl@0
   773
			TOpenFontCharMetrics metrics;
sl@0
   774
			// search for glyph in font glyph cache and session cache.
sl@0
   775
			if (!font->GetCharacterData(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, metrics, bitmapData))
sl@0
   776
				{
sl@0
   777
				// Rasterize the glyph
sl@0
   778
				if(!font->Rasterize(iSessionHandle, glyphCode | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
sl@0
   779
					{
sl@0
   780
					err = KErrNoMemory;
sl@0
   781
					break;
sl@0
   782
					}
sl@0
   783
				metrics = *(iOpenFontGlyphData->Metrics());
sl@0
   784
				bitmapData = iOpenFontGlyphData->BitmapPointer();
sl@0
   785
				}
sl@0
   786
			CGlyphAtlas::TAddGlyphArgs args(bitmapData, glyphCode, metrics);
sl@0
   787
			err = glyphAtlas->AddGlyph(*font, args, glyphImageInfo[glyphsProcessed]);
sl@0
   788
			}
sl@0
   789
		if ((err == KErrNone) && (glyphImageInfo[glyphsProcessed].iImageId != KSgNullDrawableId))
sl@0
   790
			{
sl@0
   791
			// To prevent other threads closing the glyph image in the glyph atlas 
sl@0
   792
			// before client has had chance to open the drawable id, open a local
sl@0
   793
			// handle to the glyph image for the session, which will be closed either
sl@0
   794
			// next time a request is made or when EFbsMessCloseGlyphs is handled.
sl@0
   795
			RSgImage glyphImage;
sl@0
   796
			err = glyphImage.Open(glyphImageInfo[glyphsProcessed].iImageId);
sl@0
   797
			if (err == KErrNone)
sl@0
   798
				{
sl@0
   799
				err = iGlyphImagesInTransit.Append(glyphImage);
sl@0
   800
				}
sl@0
   801
			}
sl@0
   802
		// If an error occurred during this iteration, abort now before the glyphsProcessed
sl@0
   803
		// counter is incremented, which would give one too many processed glyphs.
sl@0
   804
		if (KErrNone != err)
sl@0
   805
			{
sl@0
   806
			break;
sl@0
   807
			}
sl@0
   808
		}
sl@0
   809
sl@0
   810
	// Even if there was an error, if at least one glyph was processed successfully
sl@0
   811
	// send that back to the client, and reset the error code.
sl@0
   812
	if (glyphsProcessed > 0)
sl@0
   813
		{
sl@0
   814
		TPckg<TGlyphImageInfo[KMaxGlyphBatchSize]> glyphImageInfoPckg(glyphImageInfo);
sl@0
   815
		glyphImageInfoPckg.SetLength(glyphsProcessed * sizeof(TGlyphImageInfo));
sl@0
   816
		err = aMessage.Write(2, glyphImageInfoPckg);
sl@0
   817
		if (err != KErrNone)
sl@0
   818
			{
sl@0
   819
			aPanicRequired = ETrue;
sl@0
   820
			return err;
sl@0
   821
			}
sl@0
   822
		}
sl@0
   823
	else
sl@0
   824
		{
sl@0
   825
		// No glyphs being returned, so an error code must be returned.
sl@0
   826
		__ASSERT_DEBUG(err != KErrNone, User::Panic(KFBSERVPanicCategory, err));
sl@0
   827
		}
sl@0
   828
	return err;
sl@0
   829
	}
sl@0
   830
sl@0
   831
/**
sl@0
   832
Handler for EFbsMessGetGlyphMetrics message.
sl@0
   833
Reads an array of glyph codes, and returns the offset from the heap base for the 
sl@0
   834
corresponding metrics object.
sl@0
   835
@pre The glyph codes have already been searched client-side in the font glyph
sl@0
   836
	cache and the session cache.
sl@0
   837
@param aMessage input parameters
sl@0
   838
@param aPanicRequired flag that is set if a client panic is required
sl@0
   839
@return KErrNone if successful, otherwise any system-wide error code.
sl@0
   840
 */
sl@0
   841
TInt CFbClient::HandleMesgGetGlyphMetrics(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   842
	{
sl@0
   843
	CFbTop* fbtop = TopLevelStore();
sl@0
   844
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
sl@0
   845
	if(!fontptr)
sl@0
   846
		{
sl@0
   847
		aPanicRequired = ETrue;
sl@0
   848
		return KErrBadHandle;
sl@0
   849
		}
sl@0
   850
	
sl@0
   851
	TInt err = KErrNone;
sl@0
   852
	TUint glyphCodes[KMaxMetricsBatchSize];
sl@0
   853
	TPckg<TUint[KMaxMetricsBatchSize]> glyphBatchPckg(glyphCodes);
sl@0
   854
	err = aMessage.Read(1, glyphBatchPckg);
sl@0
   855
	if (err != KErrNone)
sl@0
   856
		{
sl@0
   857
		aPanicRequired = ETrue;
sl@0
   858
		return err;
sl@0
   859
		}
sl@0
   860
	
sl@0
   861
	TInt numGlyphCodes = glyphBatchPckg.Length() / sizeof(TUint);	
sl@0
   862
	if (numGlyphCodes > KMaxMetricsBatchSize)
sl@0
   863
		{
sl@0
   864
		aPanicRequired = ETrue;
sl@0
   865
		return KErrOverflow;
sl@0
   866
		}
sl@0
   867
	
sl@0
   868
	CBitmapFont* font = fontptr->iAddressPointer;
sl@0
   869
	const TInt heapbase = fbtop->HeapBase();
sl@0
   870
sl@0
   871
	TInt glyphProcessed;
sl@0
   872
	TInt glyphMetricsOffsets[KMaxMetricsBatchSize];
sl@0
   873
	for (glyphProcessed = 0; (glyphProcessed < numGlyphCodes) && (err == KErrNone); ++glyphProcessed)
sl@0
   874
		{
sl@0
   875
		if (font->Rasterize(iSessionHandle, glyphCodes[glyphProcessed] | KTreatAsGlyphCodeFlag, iOpenFontGlyphData))
sl@0
   876
			{
sl@0
   877
			// Convert all pointers to be passed back to the client to offsets from
sl@0
   878
			// the heap base so that they can be recreated client side relative to the
sl@0
   879
			// client's heap base
sl@0
   880
			glyphMetricsOffsets[glyphProcessed] = PointerToOffset(iOpenFontGlyphData->Metrics(), heapbase);
sl@0
   881
			}
sl@0
   882
		else
sl@0
   883
			{
sl@0
   884
			err = KErrNoMemory;
sl@0
   885
			}
sl@0
   886
		}
sl@0
   887
sl@0
   888
	if (err == KErrNone)
sl@0
   889
		{
sl@0
   890
		TPckg<TInt[KMaxMetricsBatchSize]> glyphMetricsOffsetsPckg(glyphMetricsOffsets);
sl@0
   891
		glyphMetricsOffsetsPckg.SetLength(glyphProcessed * sizeof(TInt));
sl@0
   892
		err = aMessage.Write(2, glyphMetricsOffsetsPckg);
sl@0
   893
		if (err != KErrNone)
sl@0
   894
			{
sl@0
   895
			aPanicRequired = ETrue;
sl@0
   896
			}
sl@0
   897
		}	
sl@0
   898
	return err;
sl@0
   899
	}
sl@0
   900
sl@0
   901
/** Handler for EFbsMessFaceAttrib message
sl@0
   902
 @param aMessage Input and output parameters
sl@0
   903
 @param aPanicRequired Flag that is set to ETrue if a client panic is required
sl@0
   904
 @return ETrue if successful, EFalse or any system-wide error code if not successful.
sl@0
   905
	 An error code is only returned if aPanicRequired is set to ETrue.
sl@0
   906
 */
sl@0
   907
TInt CFbClient::HandleMesgFaceAttrib(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   908
	{
sl@0
   909
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), TopLevelStore()->FontConUniqueID()));
sl@0
   910
	if(!fontptr)
sl@0
   911
		{
sl@0
   912
		aPanicRequired = ETrue;
sl@0
   913
		return KErrArgument;
sl@0
   914
		}
sl@0
   915
	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
sl@0
   916
sl@0
   917
	TInt ret = EFalse;
sl@0
   918
	TPckgBuf<TOpenFontFaceAttrib> package;
sl@0
   919
	if ( (bitmapFont != NULL) && (bitmapFont->GetFaceAttrib(package())) )
sl@0
   920
		{
sl@0
   921
		ret = aMessage.Write(1,package);
sl@0
   922
		if (ret == KErrNone)
sl@0
   923
			{
sl@0
   924
			ret = ETrue;
sl@0
   925
			}
sl@0
   926
		else
sl@0
   927
			{
sl@0
   928
			aPanicRequired = ETrue;
sl@0
   929
			}
sl@0
   930
		}
sl@0
   931
	return ret;
sl@0
   932
	}
sl@0
   933
sl@0
   934
sl@0
   935
/** Handler for EFbsMessHasCharacter message
sl@0
   936
 @param aMessage Input parameters
sl@0
   937
 @param aPanicRequired Flag that is set to ETrue if a client panic is required
sl@0
   938
 @return ETrue if the font has the character, EFalse if the font does not have
sl@0
   939
  the character, or any system-wide error code if not successful. An error code
sl@0
   940
  is only returned if aPanicRequired is set to ETrue.
sl@0
   941
 */
sl@0
   942
TInt CFbClient::HandleMesgHasCharacter(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   943
	{
sl@0
   944
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), TopLevelStore()->FontConUniqueID()));
sl@0
   945
	if(!fontptr)
sl@0
   946
		{
sl@0
   947
		aPanicRequired = ETrue;
sl@0
   948
		return KErrArgument;
sl@0
   949
		}
sl@0
   950
	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
sl@0
   951
sl@0
   952
	TInt ret = 0;
sl@0
   953
	TRAPD(error, ret = bitmapFont->HasCharacterL(aMessage.Int1()));
sl@0
   954
	if (error != KErrNone)
sl@0
   955
		{
sl@0
   956
		return EFalse;
sl@0
   957
		}
sl@0
   958
	return ret;
sl@0
   959
	}
sl@0
   960
sl@0
   961
sl@0
   962
/** Handler for EFbsMessShapeText message
sl@0
   963
 @param aMessage Input and output parameters
sl@0
   964
 @param aPanicRequired Flag that is set to ETrue if a client panic is required
sl@0
   965
 @return An offset from the heap base where the pointer to the shape is located
sl@0
   966
	if successful, otherwise 0 or any system-wide error code. An error code is
sl@0
   967
	only returned if aPanicRequired is set to ETrue.
sl@0
   968
 */
sl@0
   969
TInt CFbClient::HandleMesgShapeText(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
   970
	{
sl@0
   971
	TInt error = KErrNone;
sl@0
   972
	TShapeHeader* shape = 0;
sl@0
   973
	if (aMessage.GetDesLength(2) != sizeof(TShapeMessageParameters))
sl@0
   974
		{
sl@0
   975
		aPanicRequired = ETrue;
sl@0
   976
		return KErrArgument;
sl@0
   977
		}
sl@0
   978
sl@0
   979
	CFbTop* fbtop = TopLevelStore();
sl@0
   980
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
sl@0
   981
	if(!fontptr)
sl@0
   982
		{
sl@0
   983
		aPanicRequired = ETrue;
sl@0
   984
		return KErrArgument;
sl@0
   985
		}
sl@0
   986
sl@0
   987
	TInt inputTextLength = aMessage.GetDesLength(1);
sl@0
   988
	if (inputTextLength < 0)
sl@0
   989
		{
sl@0
   990
		error = inputTextLength;
sl@0
   991
		aPanicRequired = ETrue;
sl@0
   992
		return error;
sl@0
   993
		}
sl@0
   994
	else
sl@0
   995
		{
sl@0
   996
		iTextToShape.Zero();
sl@0
   997
		if (iTextToShape.MaxLength() < inputTextLength)
sl@0
   998
			{
sl@0
   999
			error = iTextToShape.ReAlloc(inputTextLength);
sl@0
  1000
			}
sl@0
  1001
		}
sl@0
  1002
	if (error == KErrNone)
sl@0
  1003
		{
sl@0
  1004
		error = aMessage.Read(1, iTextToShape);
sl@0
  1005
		if (error != KErrNone)
sl@0
  1006
			{
sl@0
  1007
			aPanicRequired = ETrue;
sl@0
  1008
			return error;
sl@0
  1009
			}
sl@0
  1010
		TPckgBuf<TShapeMessageParameters> sp;
sl@0
  1011
		error = aMessage.Read(2, sp);
sl@0
  1012
		if (error != KErrNone)
sl@0
  1013
			{
sl@0
  1014
			aPanicRequired = ETrue;
sl@0
  1015
			return error;
sl@0
  1016
			}
sl@0
  1017
		CBitmapFont* bitmapFont = fontptr->iAddressPointer;
sl@0
  1018
		TRAP(error, shape = bitmapFont->ShapeTextL(iTextToShape, iSessionHandle, sp()) );
sl@0
  1019
		if (error == KErrNone)
sl@0
  1020
			{
sl@0
  1021
			// Convert the pointer to be passed back to the client to an offset from
sl@0
  1022
			// the heap base so that it can be recreated client side relative to the
sl@0
  1023
			// client's heap base
sl@0
  1024
			return PointerToOffset(shape, fbtop->HeapBase());
sl@0
  1025
			}
sl@0
  1026
		}
sl@0
  1027
	return 0;
sl@0
  1028
	}
sl@0
  1029
sl@0
  1030
sl@0
  1031
/** Handler for EFbsMessShapeDelete message
sl@0
  1032
 @param aMessage input and output parameters
sl@0
  1033
 @param aPanicRequired flag that is set to ETrue if a client panic is required
sl@0
  1034
 @return KErrNone if successful, otherwise a system wide error code
sl@0
  1035
	 An error code is only returned if aPanicRequired is set to ETrue.
sl@0
  1036
 */
sl@0
  1037
TInt CFbClient::HandleMesgShapeDelete(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
  1038
	{
sl@0
  1039
	CFbTop* fbtop = TopLevelStore();
sl@0
  1040
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
sl@0
  1041
	if(!fontptr)
sl@0
  1042
		{
sl@0
  1043
		aPanicRequired = ETrue;
sl@0
  1044
		return KErrArgument;
sl@0
  1045
		}
sl@0
  1046
	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
sl@0
  1047
sl@0
  1048
	// Combine the passed shape offset with the current heap base to get
sl@0
  1049
	// a valid pointer to a shape header for use in this process			
sl@0
  1050
	TShapeHeader* shapeheader = reinterpret_cast<TShapeHeader*>(OffsetToPointer(aMessage.Int1(), fbtop->HeapBase()));
sl@0
  1051
sl@0
  1052
	bitmapFont->DeleteShape(iSessionHandle,shapeheader);
sl@0
  1053
	return KErrNone;
sl@0
  1054
	}
sl@0
  1055
sl@0
  1056
TInt CFbClient::HandleMesgReleaseGlyphOutline(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
  1057
	{
sl@0
  1058
	TInt ret = KErrNone;
sl@0
  1059
	CFbTop* fbtop = TopLevelStore();
sl@0
  1060
	TPckgBuf<TFBSGlyphOutlineParam> params;
sl@0
  1061
	ret = aMessage.Read(0, params);
sl@0
  1062
	if (KErrNone != ret)
sl@0
  1063
		{
sl@0
  1064
		aPanicRequired = ETrue;
sl@0
  1065
		return ret;
sl@0
  1066
		}
sl@0
  1067
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(params().iHandle, fbtop->FontConUniqueID()));
sl@0
  1068
	if(!fontptr)
sl@0
  1069
		{
sl@0
  1070
		aPanicRequired = ETrue;
sl@0
  1071
		return KErrArgument;
sl@0
  1072
		}
sl@0
  1073
	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
sl@0
  1074
sl@0
  1075
	TInt count = params().iCount;
sl@0
  1076
	TUint *glyphCodes = (TUint *)User::Alloc(count * sizeof(TUint));
sl@0
  1077
	if (NULL == glyphCodes)
sl@0
  1078
		{
sl@0
  1079
		return KErrNoMemory;
sl@0
  1080
		}
sl@0
  1081
	// copy the glyph codes out of the IPC buffer...
sl@0
  1082
	TPtr8 ptr((TUint8 *)glyphCodes, count * sizeof(TUint), count * sizeof(TUint));
sl@0
  1083
	ret = aMessage.Read(1, ptr);  
sl@0
  1084
sl@0
  1085
	if (KErrNone == ret)
sl@0
  1086
		{
sl@0
  1087
		bitmapFont->ReleaseGlyphOutlines(count, glyphCodes,  
sl@0
  1088
				params().iHinted, iSessionHandle);
sl@0
  1089
		}
sl@0
  1090
	else 
sl@0
  1091
		{
sl@0
  1092
		aPanicRequired = ETrue;
sl@0
  1093
		}
sl@0
  1094
sl@0
  1095
	User::Free(glyphCodes);
sl@0
  1096
	return ret;
sl@0
  1097
	}
sl@0
  1098
sl@0
  1099
TInt CFbClient::HandleMesgGetGlyphOutline(const RMessage2& aMessage, TBool& aPanicRequired) 
sl@0
  1100
	{
sl@0
  1101
	TInt ret = KErrNone;
sl@0
  1102
	CFbTop* fbtop = TopLevelStore();
sl@0
  1103
	TPckgBuf<TFBSGlyphOutlineParam> params;
sl@0
  1104
	ret = aMessage.Read(0, params);
sl@0
  1105
	if (KErrNone != ret)
sl@0
  1106
		{
sl@0
  1107
		aPanicRequired = ETrue;
sl@0
  1108
		return ret;
sl@0
  1109
		}
sl@0
  1110
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(params().iHandle, fbtop->FontConUniqueID()));
sl@0
  1111
	if(!fontptr)
sl@0
  1112
		{
sl@0
  1113
		aPanicRequired = ETrue;
sl@0
  1114
		return KErrArgument;
sl@0
  1115
		}
sl@0
  1116
	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
sl@0
  1117
sl@0
  1118
	TInt count = params().iCount;
sl@0
  1119
	TUint* glyphCodes = (TUint *)User::Alloc(count * sizeof(TUint));
sl@0
  1120
	if (NULL == glyphCodes)
sl@0
  1121
		{
sl@0
  1122
		return KErrNoMemory;
sl@0
  1123
		}
sl@0
  1124
	// copy the glyph codes out of the IPC buffer...
sl@0
  1125
	TPtr8 ptr((TUint8 *)glyphCodes, count * sizeof(TUint), count * sizeof(TUint));
sl@0
  1126
	ret = aMessage.Read(1, ptr);
sl@0
  1127
	if (KErrNone != ret)
sl@0
  1128
		{
sl@0
  1129
		User::Free(glyphCodes);
sl@0
  1130
		aPanicRequired = ETrue;
sl@0
  1131
		return ret;
sl@0
  1132
		}
sl@0
  1133
sl@0
  1134
	TOffsetLen* offsetLens = 
sl@0
  1135
		(TOffsetLen *)User::Alloc(count * sizeof(TOffsetLen));
sl@0
  1136
	if (NULL == offsetLens)
sl@0
  1137
		{
sl@0
  1138
		User::Free(glyphCodes);
sl@0
  1139
		return KErrNoMemory;
sl@0
  1140
		}
sl@0
  1141
sl@0
  1142
	TInt len = 0;
sl@0
  1143
	TAny* outline = NULL;
sl@0
  1144
	for (TInt i = 0; i < count; ++i)
sl@0
  1145
		{
sl@0
  1146
		bitmapFont->GetGlyphOutline(glyphCodes[i],  
sl@0
  1147
			params().iHinted, outline, len, iSessionHandle);
sl@0
  1148
		
sl@0
  1149
		offsetLens[i].iLen = len;
sl@0
  1150
		offsetLens[i].iOffset = PointerToOffset((outline), fbtop->HeapBase());
sl@0
  1151
		}
sl@0
  1152
	TPtr8 pkg2((TUint8 *)offsetLens, count * sizeof(TOffsetLen), 
sl@0
  1153
			count * sizeof(TOffsetLen));
sl@0
  1154
	ret = aMessage.Write(2, pkg2);
sl@0
  1155
	if (KErrNone != ret)
sl@0
  1156
		{
sl@0
  1157
		aPanicRequired = ETrue;
sl@0
  1158
		}
sl@0
  1159
sl@0
  1160
	User::Free(glyphCodes);
sl@0
  1161
	User::Free(offsetLens);
sl@0
  1162
	return ret;  
sl@0
  1163
	}
sl@0
  1164
sl@0
  1165
TInt CFbClient::HandleMesgReleaseFontTable(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
  1166
	{
sl@0
  1167
	CFbTop* fbtop = TopLevelStore();
sl@0
  1168
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
sl@0
  1169
	if(!fontptr)
sl@0
  1170
		{
sl@0
  1171
		aPanicRequired = ETrue;
sl@0
  1172
		return KErrArgument;
sl@0
  1173
		}
sl@0
  1174
	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
sl@0
  1175
sl@0
  1176
	TUint32 tag = aMessage.Int1();
sl@0
  1177
sl@0
  1178
	bitmapFont->ReleaseFontTable(tag, iSessionHandle);
sl@0
  1179
sl@0
  1180
	return KErrNone;
sl@0
  1181
	}
sl@0
  1182
sl@0
  1183
TInt CFbClient::HandleMesgGetFontTable(const RMessage2& aMessage, TBool& aPanicRequired)
sl@0
  1184
	{
sl@0
  1185
	TInt ret = KErrNone;
sl@0
  1186
	CFbTop* fbtop = TopLevelStore();
sl@0
  1187
	CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(aMessage.Int0(), fbtop->FontConUniqueID()));
sl@0
  1188
	if(!fontptr)
sl@0
  1189
		{
sl@0
  1190
		aPanicRequired = ETrue;
sl@0
  1191
		return KErrArgument;
sl@0
  1192
		}
sl@0
  1193
	CBitmapFont* bitmapFont = fontptr->iAddressPointer;
sl@0
  1194
sl@0
  1195
	TInt len = 0;
sl@0
  1196
	TAny* tablePtr = NULL;
sl@0
  1197
	ret = bitmapFont->GetFontTable((TUint32)aMessage.Int1(), tablePtr, len, iSessionHandle);
sl@0
  1198
sl@0
  1199
	if (KErrNone == ret) 
sl@0
  1200
		{
sl@0
  1201
		TPckgBuf<TOffsetLen> params;
sl@0
  1202
		params().iLen = len;
sl@0
  1203
		params().iOffset = PointerToOffset(tablePtr, fbtop->HeapBase());
sl@0
  1204
		ret = aMessage.Write(2, params);
sl@0
  1205
		aPanicRequired = (KErrNone != ret);
sl@0
  1206
		}
sl@0
  1207
sl@0
  1208
	return ret;
sl@0
  1209
	}
sl@0
  1210
sl@0
  1211
sl@0
  1212
/**
sl@0
  1213
 Called in response to the GoomMonitor framework's call into FbsOogmPlugin.
sl@0
  1214
 We wish to either free some GPU memory, or reinstate its normal usage.
sl@0
  1215
sl@0
  1216
@param  aMessage The IPC message.
sl@0
  1217
@return KErrNone If the value contained in the TFbsOogmMessage enumeration member is meaningful and the glyph atlas is present.
sl@0
  1218
        KErrNotSupported if there is no glyph atlas.
sl@0
  1219
        KErrUnknown if the value contained in the TFbsOogmMessage enumeration member is not meaningful.
sl@0
  1220
 */
sl@0
  1221
TInt CFbClient::HandleMesgOogmStatus( const RMessage2& aMessage )
sl@0
  1222
    {
sl@0
  1223
    TInt ret = KErrNone;
sl@0
  1224
    CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
sl@0
  1225
sl@0
  1226
    if ( NULL == glyphAtlas )
sl@0
  1227
        {
sl@0
  1228
        return KErrNotSupported;
sl@0
  1229
        }
sl@0
  1230
sl@0
  1231
sl@0
  1232
    TPckgBuf<TFbsOogmMessage> oogmMessage;
sl@0
  1233
    aMessage.Read( 0, oogmMessage );
sl@0
  1234
sl@0
  1235
    switch( oogmMessage().iOogmNotification )
sl@0
  1236
        {
sl@0
  1237
    case TFbsOogmMessage::EFbsOogmNoAction:
sl@0
  1238
        break;
sl@0
  1239
sl@0
  1240
    case TFbsOogmMessage::EFbsOogmLowNotification:
sl@0
  1241
        {
sl@0
  1242
        glyphAtlas->ReleaseGpuMemory( oogmMessage().iBytesToFree, oogmMessage().iFlags );
sl@0
  1243
        }
sl@0
  1244
         break;
sl@0
  1245
sl@0
  1246
    case TFbsOogmMessage::EFbsOogmOkayNotification:
sl@0
  1247
        {
sl@0
  1248
        glyphAtlas->InstateGpuMemory( oogmMessage().iFlags );
sl@0
  1249
        }
sl@0
  1250
        break;
sl@0
  1251
sl@0
  1252
    default:
sl@0
  1253
        ret = KErrUnknown;
sl@0
  1254
        break;
sl@0
  1255
        }
sl@0
  1256
sl@0
  1257
    return ret;
sl@0
  1258
    }
sl@0
  1259
sl@0
  1260
sl@0
  1261
void CFbClient::HandleMesgGlyphCacheMetrics( const RMessage2& aMessage )
sl@0
  1262
    {
sl@0
  1263
    CGlyphAtlas* glyphAtlas = TopLevelStore()->GlyphAtlas();
sl@0
  1264
    TPckgBuf<TGlyphCacheMetrics>  metrics;
sl@0
  1265
sl@0
  1266
    glyphAtlas->GetGlyphCacheMetrics( metrics() );
sl@0
  1267
sl@0
  1268
    aMessage.Complete( aMessage.Write(0, metrics) );
sl@0
  1269
    }
sl@0
  1270
sl@0
  1271
sl@0
  1272
void CFbClient::ProcFontMessage(const RMessage2& aMessage)
sl@0
  1273
	{
sl@0
  1274
	TInt ret = KErrNone;
sl@0
  1275
	TBool panicRequired = EFalse;
sl@0
  1276
sl@0
  1277
	switch(aMessage.Function())
sl@0
  1278
		{
sl@0
  1279
		case EFbsMessFontDuplicate:
sl@0
  1280
			ret = HandleMesgFontDuplicate(aMessage, panicRequired);
sl@0
  1281
			break;
sl@0
  1282
sl@0
  1283
		case EFbsMessGetNearestFontToDesignHeightInTwips:
sl@0
  1284
		case EFbsMessGetNearestFontToDesignHeightInPixels:
sl@0
  1285
		case EFbsMessGetNearestFontToMaxHeightInTwips:
sl@0
  1286
		case EFbsMessGetNearestFontToMaxHeightInPixels:
sl@0
  1287
			ret = HandleMesgGetNearestFont(aMessage, panicRequired);
sl@0
  1288
			break;
sl@0
  1289
sl@0
  1290
		case EFbsMessGetFontById:
sl@0
  1291
			ret = HandleMesgGetFontById(aMessage, panicRequired);
sl@0
  1292
			break;
sl@0
  1293
sl@0
  1294
		case EFbsMessInstallFontStoreFile:
sl@0
  1295
		case EFbsMessAddFontStoreFile:
sl@0
  1296
			ret = HandleMesgAddOrInstallFontFile(aMessage, panicRequired);
sl@0
  1297
			break;
sl@0
  1298
sl@0
  1299
		case EFbsMessRemoveFontStoreFile:
sl@0
  1300
			ret = HandleMesgRemoveFontFile(aMessage);
sl@0
  1301
			break;
sl@0
  1302
sl@0
  1303
		case EFbsMessRasterize:
sl@0
  1304
			ret = HandleMesgRasterize(aMessage, panicRequired);
sl@0
  1305
			break;
sl@0
  1306
sl@0
  1307
		case EFbsMessFaceAttrib:
sl@0
  1308
			ret = HandleMesgFaceAttrib(aMessage, panicRequired);
sl@0
  1309
			break;
sl@0
  1310
sl@0
  1311
		case EFbsMessHasCharacter:
sl@0
  1312
			ret = HandleMesgHasCharacter(aMessage, panicRequired);
sl@0
  1313
			break;
sl@0
  1314
sl@0
  1315
		case EFbsMessShapeText:
sl@0
  1316
			ret = HandleMesgShapeText(aMessage, panicRequired);
sl@0
  1317
			break;
sl@0
  1318
sl@0
  1319
		case EFbsMessShapeDelete:
sl@0
  1320
			ret = HandleMesgShapeDelete(aMessage, panicRequired);
sl@0
  1321
			break;
sl@0
  1322
sl@0
  1323
		case EFbsMessSetTwipsHeight:
sl@0
  1324
			{
sl@0
  1325
			TInt localhandle=aMessage.Int0();
sl@0
  1326
			CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(localhandle, TopLevelStore()->FontConUniqueID()));
sl@0
  1327
			if(!fontptr)
sl@0
  1328
				{
sl@0
  1329
				panicRequired = ETrue;
sl@0
  1330
				ret = KErrArgument;
sl@0
  1331
				break;
sl@0
  1332
				}
sl@0
  1333
			fontptr->iHeightInTwips = aMessage.Int1();
sl@0
  1334
			ret = KErrNone;
sl@0
  1335
			break;	
sl@0
  1336
			}
sl@0
  1337
		case EFbsMessGetTwipsHeight:
sl@0
  1338
			{
sl@0
  1339
			TInt localhandle=aMessage.Int0();
sl@0
  1340
			CFontObject* fontptr = static_cast<CFontObject*>(iIx->At(localhandle, TopLevelStore()->FontConUniqueID()));
sl@0
  1341
			if(!fontptr)
sl@0
  1342
				{
sl@0
  1343
				panicRequired = ETrue;
sl@0
  1344
				ret = KErrArgument;
sl@0
  1345
				break;
sl@0
  1346
				}
sl@0
  1347
			TPckgBuf<TInt> height;
sl@0
  1348
			height() = fontptr->iHeightInTwips;
sl@0
  1349
			ret = aMessage.Write(1,height);
sl@0
  1350
			if (KErrNone != ret)
sl@0
  1351
				{
sl@0
  1352
				panicRequired = ETrue;
sl@0
  1353
				}
sl@0
  1354
			break;
sl@0
  1355
			}
sl@0
  1356
		case EFbsSetSystemDefaultTypefaceName:
sl@0
  1357
			{
sl@0
  1358
			TBuf<KMaxTypefaceNameLength> fontTypefaceName;
sl@0
  1359
			ret = aMessage.GetDesLength(0);
sl@0
  1360
			if (ret < 0)
sl@0
  1361
				{
sl@0
  1362
				panicRequired = ETrue;
sl@0
  1363
				break;
sl@0
  1364
				}
sl@0
  1365
			if (ret <= KMaxTypefaceNameLength) // Size in characters i.e. 2 bytes for unicode
sl@0
  1366
				{
sl@0
  1367
				ret = aMessage.Read(0, fontTypefaceName);
sl@0
  1368
				if (ret == KErrNone)
sl@0
  1369
					{
sl@0
  1370
					TopLevelStore()->SetSystemDefaultTypefaceName(fontTypefaceName);
sl@0
  1371
					}
sl@0
  1372
				}
sl@0
  1373
			else
sl@0
  1374
				{
sl@0
  1375
				panicRequired = ETrue;
sl@0
  1376
				ret = KErrTooBig;
sl@0
  1377
				}
sl@0
  1378
sl@0
  1379
			break;
sl@0
  1380
			}
sl@0
  1381
		case EFbsMessGetFontTable:
sl@0
  1382
			{
sl@0
  1383
			ret = HandleMesgGetFontTable(aMessage, panicRequired);
sl@0
  1384
			break;
sl@0
  1385
			}
sl@0
  1386
		case EFbsMessGetGlyphOutline:
sl@0
  1387
			{
sl@0
  1388
			ret = HandleMesgGetGlyphOutline(aMessage, panicRequired);
sl@0
  1389
			break;
sl@0
  1390
			}
sl@0
  1391
		case EFbsMessReleaseGlyphOutline:
sl@0
  1392
			{
sl@0
  1393
			ret = HandleMesgReleaseGlyphOutline(aMessage, panicRequired);
sl@0
  1394
			break;
sl@0
  1395
			}
sl@0
  1396
		case EFbsMessReleaseFontTable:
sl@0
  1397
			{
sl@0
  1398
			ret = HandleMesgReleaseFontTable(aMessage, panicRequired);
sl@0
  1399
			break;
sl@0
  1400
			}
sl@0
  1401
		case EFbsMessGetGlyphs:
sl@0
  1402
			{
sl@0
  1403
			ret = HandleMesgGetGlyphs(aMessage, panicRequired);
sl@0
  1404
			break;
sl@0
  1405
			}
sl@0
  1406
		case EFbsMessGetGlyphMetrics:
sl@0
  1407
			{
sl@0
  1408
			ret = HandleMesgGetGlyphMetrics(aMessage, panicRequired);
sl@0
  1409
			break;
sl@0
  1410
			}
sl@0
  1411
sl@0
  1412
#ifdef _DEBUG
sl@0
  1413
		case EFbsMessSetDuplicateFail:
sl@0
  1414
			{
sl@0
  1415
			TInt argument =aMessage.Int0();
sl@0
  1416
			if (argument)
sl@0
  1417
				{
sl@0
  1418
				iFontDuplicateToFail = ETrue;
sl@0
  1419
				}
sl@0
  1420
			else
sl@0
  1421
				{
sl@0
  1422
				iFontDuplicateToFail = EFalse;
sl@0
  1423
				}
sl@0
  1424
			ret=KErrNone;
sl@0
  1425
			break;
sl@0
  1426
			}
sl@0
  1427
#endif
sl@0
  1428
		default:
sl@0
  1429
			ret = KErrUnknown;
sl@0
  1430
		}
sl@0
  1431
sl@0
  1432
	// either have a result or an error code to panic the client with
sl@0
  1433
	if (panicRequired)
sl@0
  1434
		{
sl@0
  1435
		aMessage.Panic(KFBSERVPanicCategory, ret);
sl@0
  1436
		}
sl@0
  1437
	else
sl@0
  1438
		{
sl@0
  1439
		if(!aMessage.IsNull())
sl@0
  1440
			{
sl@0
  1441
			aMessage.Complete(ret);
sl@0
  1442
			}		
sl@0
  1443
		}
sl@0
  1444
#ifdef _DEBUG
sl@0
  1445
	iRet=ret;
sl@0
  1446
#endif	
sl@0
  1447
	}
sl@0
  1448
sl@0
  1449
void CFbClient::ProcBitmapMessage(const RMessage2 &aMessage)
sl@0
  1450
	{
sl@0
  1451
	CBitmapObject* bmpptr=NULL;
sl@0
  1452
	TInt localhandle=0;
sl@0
  1453
	TInt ret = KErrNone;
sl@0
  1454
	switch(aMessage.Function())
sl@0
  1455
		{
sl@0
  1456
	case EFbsMessBitmapCreate:
sl@0
  1457
		{
sl@0
  1458
		TPckgBuf<TBmpSpec> bs;
sl@0
  1459
		ret = aMessage.Read(0,bs);
sl@0
  1460
		if(ret!=KErrNone)
sl@0
  1461
			{
sl@0
  1462
			aMessage.Panic(KFBSERVPanicCategory,ret);
sl@0
  1463
			return;
sl@0
  1464
			}
sl@0
  1465
			
sl@0
  1466
		TBmpSpec& bmpSpec = bs();	
sl@0
  1467
		
sl@0
  1468
		if(!TDisplayModeUtils::IsDisplayModeValid(bmpSpec.iDispMode))
sl@0
  1469
			{
sl@0
  1470
			aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
sl@0
  1471
			return;
sl@0
  1472
			}
sl@0
  1473
sl@0
  1474
		// client uses iHandle to pass UID and iServerHandle to pass data size
sl@0
  1475
		TRAP(ret, bmpptr = TopLevelStore()->CreateBitmapL(bmpSpec.iSizeInPixels, bmpSpec.iDispMode, TUid::Uid(bmpSpec.iHandle), EFalse, bmpSpec.iServerHandle));
sl@0
  1476
		if(ret!=KErrNone)
sl@0
  1477
			break;
sl@0
  1478
		TRAP(ret,localhandle=iIx->AddL(bmpptr));
sl@0
  1479
		if(ret!=KErrNone)
sl@0
  1480
			{
sl@0
  1481
			bmpptr->Close();
sl@0
  1482
			break;
sl@0
  1483
			}
sl@0
  1484
		
sl@0
  1485
		bmpSpec.iHandle=localhandle;
sl@0
  1486
		bmpSpec.iServerHandle = bmpptr->Handle();
sl@0
  1487
		bmpSpec.iAddressOffset=TInt(bmpptr->Address())-TopLevelStore()->HeapBase();
sl@0
  1488
		ret = aMessage.Write(0,bs);
sl@0
  1489
		if(ret!=KErrNone)
sl@0
  1490
			{
sl@0
  1491
			iIx->Remove(localhandle);
sl@0
  1492
			aMessage.Panic(KFBSERVPanicCategory,ret);
sl@0
  1493
			return;
sl@0
  1494
			}
sl@0
  1495
		iResourceCount++;
sl@0
  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);)		
sl@0
  1497
		break;
sl@0
  1498
		}
sl@0
  1499
sl@0
  1500
	case EFbsMessBitmapLoad:
sl@0
  1501
	case EFbsMessBitmapLoadFast:
sl@0
  1502
		{
sl@0
  1503
		TPckgBuf<TLoadBitmapArg> loadBitmapArg;
sl@0
  1504
		ret = aMessage.Read(1,loadBitmapArg);
sl@0
  1505
		if(ret!=KErrNone)
sl@0
  1506
			{
sl@0
  1507
			aMessage.Panic(KFBSERVPanicCategory,ret);
sl@0
  1508
			return;
sl@0
  1509
			}
sl@0
  1510
		const TInt32 id=loadBitmapArg().iBitmapId;
sl@0
  1511
		const TBool shareifloaded=loadBitmapArg().iShareIfLoaded;
sl@0
  1512
		const TUint fileOffset = loadBitmapArg().iFileOffset;
sl@0
  1513
		if(aMessage.Function() == EFbsMessBitmapLoad)
sl@0
  1514
			{
sl@0
  1515
			RFile file;
sl@0
  1516
			ret=file.AdoptFromClient(aMessage,2,3);
sl@0
  1517
			if (ret!=KErrNone)
sl@0
  1518
				{
sl@0
  1519
				break;
sl@0
  1520
				}
sl@0
  1521
			TFileName filename;
sl@0
  1522
			ret=file.FullName(filename);
sl@0
  1523
			if (ret!=KErrNone)
sl@0
  1524
				{
sl@0
  1525
				break;
sl@0
  1526
				}
sl@0
  1527
sl@0
  1528
			if(shareifloaded)
sl@0
  1529
				{
sl@0
  1530
				TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset,&file, iSessionHandle));
sl@0
  1531
				}
sl@0
  1532
			else
sl@0
  1533
				{
sl@0
  1534
				TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, &file, iSessionHandle));
sl@0
  1535
				}
sl@0
  1536
			file.Close();
sl@0
  1537
			}
sl@0
  1538
		else
sl@0
  1539
			{
sl@0
  1540
			TFileName filename;
sl@0
  1541
			ret = aMessage.Read(2,filename);
sl@0
  1542
			if (ret!=KErrNone)
sl@0
  1543
				{
sl@0
  1544
				aMessage.Panic(KFBSERVPanicCategory,ret);
sl@0
  1545
				return;
sl@0
  1546
				}
sl@0
  1547
			_LIT(KZDrive, "z:");
sl@0
  1548
			if (filename.Left(2).CompareF(KZDrive))
sl@0
  1549
				{
sl@0
  1550
				// File is not in the Z: drive.
sl@0
  1551
				// So open the file and pass the file handle to LoadBitmapL() or ShareBitmapL() and close it afterwards.
sl@0
  1552
				// The reason is that the cache cannot be used for files that are writable,
sl@0
  1553
				// since they can't be kept open in the cache.
sl@0
  1554
				RFile file;
sl@0
  1555
				ret = file.Open(TopLevelStore()->FileSession(),filename,EFileShareReadersOnly);
sl@0
  1556
				if (ret!=KErrNone)
sl@0
  1557
					{
sl@0
  1558
					break;
sl@0
  1559
					}
sl@0
  1560
				if(shareifloaded)
sl@0
  1561
					{
sl@0
  1562
					TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset,&file, iSessionHandle));
sl@0
  1563
					}
sl@0
  1564
				else
sl@0
  1565
					{
sl@0
  1566
					TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, &file, iSessionHandle));
sl@0
  1567
					}
sl@0
  1568
				file.Close();
sl@0
  1569
				}
sl@0
  1570
			else
sl@0
  1571
				{
sl@0
  1572
				if(shareifloaded)
sl@0
  1573
					{
sl@0
  1574
					TRAP(ret, bmpptr=TopLevelStore()->ShareBitmapL(filename, id, fileOffset, NULL, iSessionHandle));
sl@0
  1575
					}
sl@0
  1576
				else
sl@0
  1577
					{
sl@0
  1578
					TRAP(ret, bmpptr=TopLevelStore()->LoadBitmapL(filename, id, fileOffset, NULL, iSessionHandle));
sl@0
  1579
					}
sl@0
  1580
				}
sl@0
  1581
			}
sl@0
  1582
		if(ret!=KErrNone)
sl@0
  1583
			{
sl@0
  1584
			break;
sl@0
  1585
			}
sl@0
  1586
		TRAP(ret,localhandle=iIx->AddL(bmpptr));
sl@0
  1587
		if(ret!=KErrNone)
sl@0
  1588
			{
sl@0
  1589
			bmpptr->Close();
sl@0
  1590
			break;
sl@0
  1591
			}
sl@0
  1592
		TPckgBuf<TBmpHandles> handlebuffer;
sl@0
  1593
		handlebuffer().iHandle=localhandle;
sl@0
  1594
		handlebuffer().iServerHandle = bmpptr->Handle();
sl@0
  1595
		handlebuffer().iAddressOffset=TInt(bmpptr->Address())-TopLevelStore()->HeapBase();
sl@0
  1596
		ret = aMessage.Write(0,handlebuffer);
sl@0
  1597
		if(ret!=KErrNone)
sl@0
  1598
			{
sl@0
  1599
			iIx->Remove(localhandle);
sl@0
  1600
			aMessage.Panic(KFBSERVPanicCategory,ret);
sl@0
  1601
			return;
sl@0
  1602
			}
sl@0
  1603
		iResourceCount++;
sl@0
  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);)
sl@0
  1605
		break;
sl@0
  1606
		}
sl@0
  1607
	case EFbsMessBitmapResize:
sl@0
  1608
		{
sl@0
  1609
		localhandle=aMessage.Int0();
sl@0
  1610
		CFbTop* fbtop = TopLevelStore();
sl@0
  1611
		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
sl@0
  1612
		if(!bmpptr)
sl@0
  1613
			{
sl@0
  1614
			ret=KErrUnknown;
sl@0
  1615
			break;
sl@0
  1616
			}
sl@0
  1617
		ret = fbtop->GetCleanBitmap(bmpptr);
sl@0
  1618
		if (ret != KErrNone)
sl@0
  1619
			{
sl@0
  1620
			break;
sl@0
  1621
			}
sl@0
  1622
		TSize newsize(aMessage.Int1(),aMessage.Int2());
sl@0
  1623
 		const TBool compressedInRam = bmpptr->Address()->IsCompressedInRAM();  //It must be set before the resizing is done.
sl@0
  1624
		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
sl@0
  1625
		CBitmapObject* newbmpptr = NULL;
sl@0
  1626
		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(newsize, dispMode, KUidCFbsBitmapCreation, ETrue));
sl@0
  1627
		if (ret != KErrNone)
sl@0
  1628
			{
sl@0
  1629
			break;
sl@0
  1630
			}
sl@0
  1631
		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
sl@0
  1632
		if (ret != KErrNone)
sl@0
  1633
			{
sl@0
  1634
			newbmpptr->Close();
sl@0
  1635
			break;
sl@0
  1636
			}
sl@0
  1637
 		if (compressedInRam)
sl@0
  1638
			{
sl@0
  1639
			// if the header says PaletteCompression specify.
sl@0
  1640
			TBitmapfileCompressionScheme scheme = ERLECompression;
sl@0
  1641
			if (bmpptr->Address()->iHeader.iCompression == EGenericPaletteCompression)
sl@0
  1642
				scheme = EPaletteCompression;
sl@0
  1643
			ret = newbmpptr->Address()->CompressData(scheme); // re-compress
sl@0
  1644
			if (ret != KErrNone)
sl@0
  1645
				{
sl@0
  1646
				newbmpptr->Close();
sl@0
  1647
				break;
sl@0
  1648
				}
sl@0
  1649
			}
sl@0
  1650
		TInt newlocalhandle = 0;
sl@0
  1651
		TRAP(ret, newlocalhandle = iIx->AddL(newbmpptr));
sl@0
  1652
		if (ret != KErrNone)
sl@0
  1653
			{
sl@0
  1654
			newbmpptr->Close();
sl@0
  1655
			break;
sl@0
  1656
			}
sl@0
  1657
		ret = newbmpptr->Open();
sl@0
  1658
		if (ret != KErrNone)
sl@0
  1659
			{
sl@0
  1660
			iIx->Remove(newlocalhandle);
sl@0
  1661
			break;
sl@0
  1662
			}
sl@0
  1663
		bmpptr->SetCleanBitmap(newbmpptr);
sl@0
  1664
		if (bmpptr->AccessCount() >= 2)
sl@0
  1665
			{
sl@0
  1666
			fbtop->NotifyDirtyBitmap(*bmpptr, this);
sl@0
  1667
			}
sl@0
  1668
		iIx->Remove(localhandle);
sl@0
  1669
		TPckgBuf<TBmpHandles> handlebuffer;
sl@0
  1670
		handlebuffer().iHandle = newlocalhandle;
sl@0
  1671
		handlebuffer().iServerHandle = newbmpptr->Handle();
sl@0
  1672
		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
sl@0
  1673
		ret = aMessage.Write(3, handlebuffer);
sl@0
  1674
		if (ret != KErrNone)
sl@0
  1675
			{
sl@0
  1676
			iIx->Remove(newlocalhandle);
sl@0
  1677
			aMessage.Panic(KFBSERVPanicCategory, ret);
sl@0
  1678
			return;
sl@0
  1679
			}
sl@0
  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);)
sl@0
  1681
		break;
sl@0
  1682
		}
sl@0
  1683
	case EFbsMessBitmapDuplicate:
sl@0
  1684
		{
sl@0
  1685
		bmpptr = TopLevelStore()->FindBitmap(aMessage.Int0());
sl@0
  1686
		if (bmpptr == NULL)
sl@0
  1687
			{
sl@0
  1688
			ret=KErrUnknown;
sl@0
  1689
			break;
sl@0
  1690
			}
sl@0
  1691
		//coverity [check_return]
sl@0
  1692
		//coverity [unchecked_value]
sl@0
  1693
		TopLevelStore()->GetCleanBitmap(bmpptr);
sl@0
  1694
		ret = bmpptr->Open();
sl@0
  1695
		if (ret != KErrNone)
sl@0
  1696
			{
sl@0
  1697
			break;
sl@0
  1698
			}
sl@0
  1699
		TPckgBuf<TBmpHandles> handlebuffer;
sl@0
  1700
		TRAP(ret,localhandle=iIx->AddL(bmpptr));
sl@0
  1701
		if(ret!=KErrNone)
sl@0
  1702
			{
sl@0
  1703
			bmpptr->Close();
sl@0
  1704
			break;
sl@0
  1705
			}
sl@0
  1706
		handlebuffer().iHandle = localhandle;
sl@0
  1707
		handlebuffer().iServerHandle = bmpptr->Handle();
sl@0
  1708
		handlebuffer().iAddressOffset = TInt(bmpptr->Address()) - TopLevelStore()->HeapBase();
sl@0
  1709
		ret = aMessage.Write(1, handlebuffer);
sl@0
  1710
		if(ret!=KErrNone)
sl@0
  1711
			{
sl@0
  1712
			iIx->Remove(localhandle);
sl@0
  1713
			aMessage.Panic(KFBSERVPanicCategory,ret);
sl@0
  1714
			return;
sl@0
  1715
			}
sl@0
  1716
		iResourceCount++;
sl@0
  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);)
sl@0
  1718
		break;
sl@0
  1719
		}
sl@0
  1720
	case EFbsMessBitmapCompress:
sl@0
  1721
		{
sl@0
  1722
		localhandle = aMessage.Int0();
sl@0
  1723
		CFbTop* fbtop = TopLevelStore();
sl@0
  1724
		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
sl@0
  1725
		if(!bmpptr)
sl@0
  1726
			{
sl@0
  1727
			ret = KErrUnknown;
sl@0
  1728
			break;
sl@0
  1729
			}
sl@0
  1730
		ret = fbtop->GetCleanBitmap(bmpptr);
sl@0
  1731
		if (ret != KErrNone)
sl@0
  1732
			{
sl@0
  1733
			break;
sl@0
  1734
			}
sl@0
  1735
		const TSize size = bmpptr->Address()->SizeInPixels();
sl@0
  1736
		const TDisplayMode dispMode = bmpptr->Address()->DisplayMode();
sl@0
  1737
		CBitmapObject* newbmpptr = NULL;
sl@0
  1738
		TRAP(ret, newbmpptr = fbtop->CreateBitmapL(size, dispMode, KUidCFbsBitmapCreation, ETrue));
sl@0
  1739
		if (ret != KErrNone)
sl@0
  1740
			{
sl@0
  1741
			break;
sl@0
  1742
			}
sl@0
  1743
		ret = newbmpptr->Address()->CopyData(*bmpptr->Address());
sl@0
  1744
		if (ret != KErrNone)
sl@0
  1745
			{
sl@0
  1746
			newbmpptr->Close();
sl@0
  1747
			break;
sl@0
  1748
			}
sl@0
  1749
		ret = newbmpptr->Address()->CompressData((TBitmapfileCompressionScheme)aMessage.Int1());
sl@0
  1750
		if (ret != KErrNone)
sl@0
  1751
			{
sl@0
  1752
			newbmpptr->Close();
sl@0
  1753
			break;
sl@0
  1754
			}
sl@0
  1755
		TInt newlocalhandle = 0;
sl@0
  1756
		TRAP(ret, newlocalhandle = iIx->AddL(newbmpptr));
sl@0
  1757
		if (ret != KErrNone)
sl@0
  1758
			{
sl@0
  1759
			newbmpptr->Close();
sl@0
  1760
			break;
sl@0
  1761
			}
sl@0
  1762
		ret = newbmpptr->Open();
sl@0
  1763
		if (ret != KErrNone)
sl@0
  1764
			{
sl@0
  1765
			iIx->Remove(newlocalhandle);
sl@0
  1766
			break;
sl@0
  1767
			}
sl@0
  1768
		bmpptr->SetCleanBitmap(newbmpptr);
sl@0
  1769
		if (bmpptr->AccessCount() >= 2)
sl@0
  1770
			{
sl@0
  1771
			fbtop->NotifyDirtyBitmap(*bmpptr, this);
sl@0
  1772
			}
sl@0
  1773
		iIx->Remove(localhandle);
sl@0
  1774
		TPckgBuf<TBmpHandles> handlebuffer;
sl@0
  1775
		handlebuffer().iHandle = newlocalhandle;
sl@0
  1776
		handlebuffer().iServerHandle = newbmpptr->Handle();
sl@0
  1777
		handlebuffer().iAddressOffset = TInt(newbmpptr->Address()) - fbtop->HeapBase();
sl@0
  1778
		ret = aMessage.Write(2, handlebuffer);
sl@0
  1779
		if (ret != KErrNone)
sl@0
  1780
			{
sl@0
  1781
			iIx->Remove(newlocalhandle);
sl@0
  1782
			aMessage.Panic(KFBSERVPanicCategory, ret);
sl@0
  1783
			return;
sl@0
  1784
			}
sl@0
  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);)
sl@0
  1786
		break;
sl@0
  1787
		}
sl@0
  1788
	case EFbsMessBitmapBgCompress:
sl@0
  1789
		{
sl@0
  1790
		localhandle = aMessage.Int0();
sl@0
  1791
		TBitmapfileCompressionScheme scheme = (TBitmapfileCompressionScheme)aMessage.Int1();
sl@0
  1792
		TBool async = aMessage.Int2();
sl@0
  1793
		CFbTop* fbtop = TopLevelStore();
sl@0
  1794
		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
sl@0
  1795
		if(!bmpptr)
sl@0
  1796
			{
sl@0
  1797
			ret = KErrUnknown;
sl@0
  1798
			break;
sl@0
  1799
			}
sl@0
  1800
		ret = fbtop->GetCleanBitmap(bmpptr);
sl@0
  1801
		if (ret != KErrNone)
sl@0
  1802
			{
sl@0
  1803
			if (!async)
sl@0
  1804
				{
sl@0
  1805
				ret = KErrNone;
sl@0
  1806
				}
sl@0
  1807
			break;
sl@0
  1808
			}
sl@0
  1809
		ret = bmpptr->Address()->CheckBackgroundCompressData();
sl@0
  1810
		if (KErrNone == ret)
sl@0
  1811
			{
sl@0
  1812
			ret = fbtop->BackgroundCompression()->AddToCompressionQueue(bmpptr, scheme, async ? &aMessage : NULL);
sl@0
  1813
			if (ret == KErrNone && async)
sl@0
  1814
				{
sl@0
  1815
				return; // do not complete the client's request - that will be done by the background compression thread
sl@0
  1816
				}
sl@0
  1817
			}
sl@0
  1818
		if (KErrAlreadyExists == ret)
sl@0
  1819
			{
sl@0
  1820
			ret = KErrNone;
sl@0
  1821
			}
sl@0
  1822
		break;
sl@0
  1823
		}
sl@0
  1824
	case EFbsMessBitmapClean:
sl@0
  1825
		{
sl@0
  1826
		TInt localhandle = aMessage.Int0();
sl@0
  1827
		CFbTop* fbtop = TopLevelStore();
sl@0
  1828
		bmpptr = static_cast<CBitmapObject*>(iIx->At(localhandle, fbtop->BitmapConUniqueID()));
sl@0
  1829
		if(!bmpptr)
sl@0
  1830
			{
sl@0
  1831
			ret = KErrUnknown;
sl@0
  1832
			break;
sl@0
  1833
			}
sl@0
  1834
		ret = fbtop->GetCleanBitmap(bmpptr);
sl@0
  1835
		if (ret != KErrNone)
sl@0
  1836
			{
sl@0
  1837
			break;
sl@0
  1838
			}
sl@0
  1839
		ret = bmpptr->Open();
sl@0
  1840
		if (ret != KErrNone)
sl@0
  1841
			{
sl@0
  1842
			break;
sl@0
  1843
			}
sl@0
  1844
		TInt cleanlocalhandle = 0;
sl@0
  1845
		TRAP(ret, cleanlocalhandle = iIx->AddL(bmpptr));
sl@0
  1846
		if (ret != KErrNone)
sl@0
  1847
			{
sl@0
  1848
			bmpptr->Close();
sl@0
  1849
			break;
sl@0
  1850
			}
sl@0
  1851
		iIx->Remove(localhandle);
sl@0
  1852
		TPckgBuf<TBmpHandles> handlebuffer;
sl@0
  1853
		handlebuffer().iHandle = cleanlocalhandle;
sl@0
  1854
		handlebuffer().iServerHandle = bmpptr->Handle();
sl@0
  1855
		handlebuffer().iAddressOffset = TInt(bmpptr->Address()) - fbtop->HeapBase();
sl@0
  1856
		ret = aMessage.Write(1, handlebuffer);
sl@0
  1857
		if (ret != KErrNone)
sl@0
  1858
			{
sl@0
  1859
			iIx->Remove(cleanlocalhandle);
sl@0
  1860
			aMessage.Panic(KFBSERVPanicCategory, ret);
sl@0
  1861
			return;
sl@0
  1862
			}
sl@0
  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);)
sl@0
  1864
		break;
sl@0
  1865
		}
sl@0
  1866
	case EFbsGetAllBitmapHandles:
sl@0
  1867
		{
sl@0
  1868
		ret = TopLevelStore()->GetAllBitmapHandles(aMessage);		
sl@0
  1869
		break;	
sl@0
  1870
		}	
sl@0
  1871
sl@0
  1872
	case EFbsMessBitmapNotifyDirty:
sl@0
  1873
		{
sl@0
  1874
		if (iHelper == NULL)
sl@0
  1875
			{
sl@0
  1876
			iHelper = new TFbClientHelper(*this);
sl@0
  1877
			if (iHelper == NULL)
sl@0
  1878
				{
sl@0
  1879
				ret = KErrNoMemory;
sl@0
  1880
				break;
sl@0
  1881
				}
sl@0
  1882
			TopLevelStore()->AddClientHelper(*iHelper);
sl@0
  1883
			}
sl@0
  1884
		if (!iHelper->iMessage.IsNull())
sl@0
  1885
			{
sl@0
  1886
			aMessage.Panic(KFBSERVPanicCategory, KErrAlreadyExists);
sl@0
  1887
			return;
sl@0
  1888
			}
sl@0
  1889
		if (!iHelper->iDirty)
sl@0
  1890
			{
sl@0
  1891
			iHelper->iMessage = aMessage;
sl@0
  1892
			return; // do not complete the client's request yet - that will be done when a bitmap becomes dirty
sl@0
  1893
			}
sl@0
  1894
		iHelper->iDirty = EFalse;
sl@0
  1895
		}
sl@0
  1896
		break;
sl@0
  1897
	case EFbsMessBitmapCancelNotifyDirty:
sl@0
  1898
		{
sl@0
  1899
		if (iHelper != NULL && !iHelper->iMessage.IsNull())
sl@0
  1900
			{
sl@0
  1901
			iHelper->iMessage.Complete(KErrCancel);
sl@0
  1902
			}
sl@0
  1903
		}
sl@0
  1904
		break;
sl@0
  1905
	default:
sl@0
  1906
		ret = KErrUnknown;
sl@0
  1907
		}
sl@0
  1908
		
sl@0
  1909
	if(!aMessage.IsNull())
sl@0
  1910
		{
sl@0
  1911
		aMessage.Complete(ret);
sl@0
  1912
		}
sl@0
  1913
	
sl@0
  1914
#ifdef _DEBUG
sl@0
  1915
	iRet=ret;
sl@0
  1916
#endif		
sl@0
  1917
	}
sl@0
  1918
sl@0
  1919
void CFbClient::NotifyDirtyBitmap(CBitmapObject& aBmpObj)
sl@0
  1920
	{
sl@0
  1921
	if (iHelper != NULL && iIx->At(&aBmpObj) != KErrNotFound)
sl@0
  1922
		{
sl@0
  1923
		iHelper->iDirty = ETrue;
sl@0
  1924
		if (!iHelper->iMessage.IsNull())
sl@0
  1925
			{
sl@0
  1926
			iHelper->iMessage.Complete(KErrNone);
sl@0
  1927
			iHelper->iDirty = EFalse;
sl@0
  1928
			}
sl@0
  1929
		}
sl@0
  1930
	}
sl@0
  1931
sl@0
  1932
void CFbClient::AddFontFileIndexL(TUid aId)
sl@0
  1933
	{
sl@0
  1934
	TInt count=iFontFileIndex->Count();
sl@0
  1935
	for (TInt index=0;index<count;index++)
sl@0
  1936
		{
sl@0
  1937
		if (iFontFileIndex->At(index).iUid==aId)
sl@0
  1938
			{
sl@0
  1939
			iFontFileIndex->At(index).iAccessCount++;
sl@0
  1940
			TopLevelStore()->FontStore()->RemoveFile(aId);
sl@0
  1941
			return;
sl@0
  1942
			}
sl@0
  1943
		}
sl@0
  1944
sl@0
  1945
	TFontFileIndex fontFileIndex;
sl@0
  1946
	fontFileIndex.iUid=aId;
sl@0
  1947
	fontFileIndex.iAccessCount=1;
sl@0
  1948
	iFontFileIndex->AppendL(fontFileIndex);
sl@0
  1949
	}
sl@0
  1950
sl@0
  1951
void CFbClient::RemoveFontFileIndex(TUid aId)
sl@0
  1952
	{
sl@0
  1953
	TInt count=iFontFileIndex->Count();
sl@0
  1954
	for (TInt index=0;index<count;index++)
sl@0
  1955
		{
sl@0
  1956
		TFontFileIndex* fontFileIndex=&iFontFileIndex->At(index);
sl@0
  1957
		if (fontFileIndex->iUid==aId)
sl@0
  1958
			{
sl@0
  1959
			fontFileIndex->iAccessCount--;
sl@0
  1960
			if (fontFileIndex->iAccessCount<1)
sl@0
  1961
				{
sl@0
  1962
				TopLevelStore()->FontStore()->RemoveFile(fontFileIndex->iUid);
sl@0
  1963
				iFontFileIndex->Delete(index);
sl@0
  1964
				}
sl@0
  1965
			return;
sl@0
  1966
			}
sl@0
  1967
		}
sl@0
  1968
	// not found - must be an installed file or rubbish, so try anyway
sl@0
  1969
	TopLevelStore()->FontStore()->RemoveFile(aId);
sl@0
  1970
	}
sl@0
  1971
sl@0
  1972
void CFbClient::Disconnect(const RMessage2 &aMessage)
sl@0
  1973
	{
sl@0
  1974
	// if any bitmaps are in the background compression queue with a to-be-completed RMessage2 from this session,
sl@0
  1975
	// the RMessage2 must be completed now as it is only possible to complete messages on existing sessions
sl@0
  1976
	TopLevelStore()->BackgroundCompression()->CompleteOutstandingRequests(this);
sl@0
  1977
sl@0
  1978
	// if there is a to-be-completed request for dirty bitmap notification complete it now
sl@0
  1979
	if (iHelper)
sl@0
  1980
		{
sl@0
  1981
		if (!iHelper->iMessage.IsNull())
sl@0
  1982
			{
sl@0
  1983
			iHelper->iMessage.Complete(KErrDisconnected);
sl@0
  1984
			}
sl@0
  1985
		iHelper->Deque();
sl@0
  1986
		delete iHelper;
sl@0
  1987
		iHelper = NULL;
sl@0
  1988
		}
sl@0
  1989
sl@0
  1990
	// Clear the mbm file store cache resources that corresponds to this session
sl@0
  1991
	TopLevelStore()->CloseFileStores(iSessionHandle);
sl@0
  1992
sl@0
  1993
	CSession2::Disconnect(aMessage);
sl@0
  1994
	}
sl@0
  1995
sl@0
  1996
#ifdef _DEBUG
sl@0
  1997
void CFbClient::ProcMemMessage(const RMessage2 &aMessage)
sl@0
  1998
	{
sl@0
  1999
	TInt ret=KErrNone;
sl@0
  2000
	TInt parameterForFunctionCall;
sl@0
  2001
	TInt cells = User::Heap().Available(parameterForFunctionCall);
sl@0
  2002
	switch(aMessage.Function())
sl@0
  2003
		{
sl@0
  2004
		case EFbsMessSetHeapFail:
sl@0
  2005
			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
sl@0
  2006
				{
sl@0
  2007
				iOwnHeapFailNumber=aMessage.Int1();
sl@0
  2008
				}
sl@0
  2009
			else
sl@0
  2010
				{
sl@0
  2011
				iSharedHeapFailNumber=aMessage.Int1();
sl@0
  2012
				}
sl@0
  2013
			break;
sl@0
  2014
		case EFbsMessHeapCount:
sl@0
  2015
			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
sl@0
  2016
				{
sl@0
  2017
				ret=User::CountAllocCells();
sl@0
  2018
				}
sl@0
  2019
			else
sl@0
  2020
				{
sl@0
  2021
				ret=iHeap->Count();
sl@0
  2022
				}	
sl@0
  2023
			break;
sl@0
  2024
		case EFbsMessSetHeapReset:
sl@0
  2025
			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
sl@0
  2026
				{
sl@0
  2027
				iOwnHeapFailNumber=-1;
sl@0
  2028
				}
sl@0
  2029
			else
sl@0
  2030
				{
sl@0
  2031
				iSharedHeapFailNumber=-1;
sl@0
  2032
				}				
sl@0
  2033
			break;
sl@0
  2034
		case EFbsMessSetHeapCheck:
sl@0
  2035
			if (aMessage.Int0()==RFbsSession::EHeapFailTypeServerMemory)
sl@0
  2036
				{
sl@0
  2037
				iOwnHeapCheckFlip=ETrue;
sl@0
  2038
				}
sl@0
  2039
			else
sl@0
  2040
				{
sl@0
  2041
				iHeapCheckFlip=ETrue;
sl@0
  2042
				}
sl@0
  2043
			break;
sl@0
  2044
		case EFbsMessHeap:
sl@0
  2045
			ret=(TInt)iHeap;
sl@0
  2046
			break;
sl@0
  2047
		default:
sl@0
  2048
			ret = KErrUnknown;
sl@0
  2049
		}
sl@0
  2050
	aMessage.Complete(ret);
sl@0
  2051
	iRet=ret;
sl@0
  2052
	}
sl@0
  2053
sl@0
  2054
/**
sl@0
  2055
Processes messages associated with the Glyph Atlas.
sl@0
  2056
@param aMessage The message used to perform IPC to the client.
sl@0
  2057
 */
sl@0
  2058
void CFbClient::ProcAtlasMessage(const RMessage2 &aMessage)
sl@0
  2059
	{
sl@0
  2060
	TInt ret = KErrNone;
sl@0
  2061
	CFbTop* fbtop = TopLevelStore();
sl@0
  2062
	CGlyphAtlas* glyphAtlas = fbtop->GlyphAtlas();
sl@0
  2063
	if (!glyphAtlas)
sl@0
  2064
		{
sl@0
  2065
		ret = KErrNotSupported;
sl@0
  2066
		}
sl@0
  2067
	else
sl@0
  2068
		{
sl@0
  2069
		switch(aMessage.Function())
sl@0
  2070
			{
sl@0
  2071
			case EFbsMessAtlasFontCount:
sl@0
  2072
				ret = glyphAtlas->FontCount();
sl@0
  2073
				break;
sl@0
  2074
			case EFbsMessAtlasGlyphCount:
sl@0
  2075
				{
sl@0
  2076
				TInt fontHandle = aMessage.Int0();
sl@0
  2077
				if (fontHandle != 0)
sl@0
  2078
					{
sl@0
  2079
					if (fbtop->ValidFontHandle(fontHandle))
sl@0
  2080
						{
sl@0
  2081
						CFontObject* fontptr = reinterpret_cast<CFontObject*>(fontHandle);
sl@0
  2082
						ret = glyphAtlas->GlyphCount(static_cast<CBitmapFont&>(*(fontptr->iAddressPointer)));
sl@0
  2083
						}
sl@0
  2084
					else
sl@0
  2085
						{
sl@0
  2086
						ret = KErrNotFound;
sl@0
  2087
						}
sl@0
  2088
					}
sl@0
  2089
				else
sl@0
  2090
					{
sl@0
  2091
					ret = glyphAtlas->GlyphCount();
sl@0
  2092
					}
sl@0
  2093
				}
sl@0
  2094
				break;
sl@0
  2095
			default:
sl@0
  2096
				ret = KErrUnknown;
sl@0
  2097
			}
sl@0
  2098
		}
sl@0
  2099
	aMessage.Complete(ret);
sl@0
  2100
	iRet=ret;
sl@0
  2101
	}
sl@0
  2102
#endif