os/graphics/fbs/fontandbitmapserver/sfbs/SERVER.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/fbs/fontandbitmapserver/sfbs/SERVER.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,619 @@
     1.4 +// Copyright (c) 1995-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include <fntstore.h>
    1.20 +#include <bitmap.h>
    1.21 +#include "FBSVER.H"
    1.22 +#include "SERVER.H"
    1.23 +#include "BackGroundCompression.h"
    1.24 +#include "linkedfonts.h"
    1.25 +#include "BitwiseBitmap.inl"
    1.26 +
    1.27 +const TInt KFbsPriority = 0;
    1.28 +const TInt KFbsGoomMonitorSid = 0x10207218;
    1.29 +// Setup security policies
    1.30 +const TInt KRanges[] = 
    1.31 +	{
    1.32 +	0,
    1.33 +	EFbsMessShutdown,
    1.34 +	EFbsMessClose,
    1.35 +	EFbsSetSystemDefaultTypefaceName,
    1.36 +	EFbsGetAllBitmapHandles,
    1.37 +	EFbsMessUnused1,
    1.38 +	EFbsMessUnused2,
    1.39 +	EFbsMessRegisterLinkedTypeface,
    1.40 +	EFbsMessFetchLinkedTypeface,
    1.41 +	EFbsMessUpdateLinkedTypeface,
    1.42 +	EFbsMessGetFontTable,
    1.43 +    EFbsMessOogmNotification,
    1.44 +    EFbsMessGetGlyphCacheMetrics,
    1.45 +	};
    1.46 +
    1.47 +const TUint KRangeCount = sizeof(KRanges)/sizeof(TInt);
    1.48 +const TUint8 KElementsIndex[KRangeCount] = 
    1.49 +	{
    1.50 +	0,
    1.51 +	3, // For EFbsMessShutdown
    1.52 +	0,
    1.53 +	1, // For EFbsSetSystemDefaultTypefaceName
    1.54 +	2, // For EFbsGetAllBitmapHandles
    1.55 +	0, // ECapability_None for EFbsMessUnused1
    1.56 +	0, // ECapability_None for EFbsMessUnused2 and beyond
    1.57 +	1, // ECapabilityWriteDeviceData for EFbsMessRegisterLinkedTypeface
    1.58 +	2, // ECapabilityReadDeviceData for EFbsMessFetchLinkedTypeface
    1.59 +	1, // ECapabilityWriteDeviceData for EFbsMessUpdateLinkedTypeface
    1.60 +	0, // ECapability_None for EFbsMessGetFontTable and beyond
    1.61 +    4, // SID for EFbsMessOogmNotification.
    1.62 +    0, // For EFbsMessGetGlyphCacheMetrics and on.
    1.63 +	};
    1.64 +
    1.65 +const CPolicyServer::TPolicyElement KElements[] = 
    1.66 +	{
    1.67 +	{_INIT_SECURITY_POLICY_C1(ECapability_None), CPolicyServer::EFailClient},
    1.68 +	{_INIT_SECURITY_POLICY_C1(ECapabilityWriteDeviceData), CPolicyServer::EFailClient},
    1.69 +	{_INIT_SECURITY_POLICY_C1(ECapabilityReadDeviceData), CPolicyServer::EFailClient},
    1.70 +	{_INIT_SECURITY_POLICY_C1(ECapabilityPowerMgmt), CPolicyServer::EFailClient},
    1.71 +	{_INIT_SECURITY_POLICY_S0(KFbsGoomMonitorSid), CPolicyServer::EFailClient}
    1.72 + 	};
    1.73 +
    1.74 +const CPolicyServer::TPolicy KFbsPolicy =
    1.75 +	{
    1.76 +	CPolicyServer::EAlwaysPass, //specifies all connect attempts should pass
    1.77 +	KRangeCount,
    1.78 +	KRanges,
    1.79 +	KElementsIndex,
    1.80 +	KElements,
    1.81 +	};
    1.82 +
    1.83 +CFontBitmapServer::CFontBitmapServer():
    1.84 +	CPolicyServer(KFbsPriority, KFbsPolicy)
    1.85 +	{
    1.86 +	}
    1.87 +
    1.88 +CFontBitmapServer::~CFontBitmapServer()
    1.89 +	{
    1.90 +	delete iTopLevelStore;
    1.91 +	iTopLevelStore = NULL;	// so that CFBClient::~CFbClient can avoid using this pointer;
    1.92 +							// it may be called inside CFontBitmapServer::~CFontBitmapServer
    1.93 +	}
    1.94 +
    1.95 +CFontBitmapServer* CFontBitmapServer::NewL()
    1.96 +	{
    1.97 +	CFontBitmapServer* self = new(ELeave) CFontBitmapServer;
    1.98 +	CleanupStack::PushL(self);
    1.99 +	self->ConstructL();
   1.100 +	CleanupStack::Pop(); //self
   1.101 +	return self;
   1.102 +	}
   1.103 +
   1.104 +/**
   1.105 +Two-phase constructor.
   1.106 +*/
   1.107 +void CFontBitmapServer::ConstructL()
   1.108 +	{
   1.109 +	iTopLevelStore=CFbTop::NewL();
   1.110 +	
   1.111 +	// If fbserv data paging is configured as unpaged, automatically pin client descriptors 
   1.112 +	if(!RProcess().DefaultDataPaged())
   1.113 +		{
   1.114 +		SetPinClientDescriptors(ETrue);
   1.115 +		}
   1.116 +	StartL(KFBSERVGlobalThreadName);
   1.117 +	}
   1.118 +
   1.119 +CFbTop* CFontBitmapServer::TopLevelStore()
   1.120 +	{
   1.121 +	return(iTopLevelStore);
   1.122 +	}
   1.123 +
   1.124 +CSession2* CFontBitmapServer::NewSessionL(const TVersion& aVersion,const RMessage2& /*aMessage*/ ) const
   1.125 +	{
   1.126 +	TVersion v(KFbsMajorVersionNumber,KFbsMinorVersionNumber,KFbsBuildVersionNumber);
   1.127 +	if(!User::QueryVersionSupported(v,aVersion))
   1.128 +		User::Leave(KErrNotSupported);
   1.129 +
   1.130 +	CSession2* pSession2 = CFbClient::NewL(iTopLevelStore->Heap());
   1.131 +	return pSession2;
   1.132 +	}
   1.133 +
   1.134 +TInt CFontBitmapServer::Init()
   1.135 +	{
   1.136 +	return(iConnectionId++);
   1.137 +	}
   1.138 +
   1.139 +
   1.140 +TInt CFontBitmapServer::HandleMesgTypefaceSupport(const RMessage2& aMessage, TBool& aClientPanicRequired)
   1.141 +	{
   1.142 +	TTypefaceSupport tfi;
   1.143 +	TPckgBuf<TTypefaceSupport> ttipckg(tfi);
   1.144 +	TPckgBuf<TSize> pixelSize;
   1.145 +	TInt index=aMessage.Int0();
   1.146 +	TInt limit=iTopLevelStore->FontStore()->NumTypefaces();
   1.147 +	if(index < 0 || index > limit)
   1.148 +		{
   1.149 +		return KErrArgument;
   1.150 +		}
   1.151 +	TInt ret = aMessage.Read(2, pixelSize);
   1.152 +	if (ret != KErrNone)
   1.153 +		{
   1.154 +		return ret;
   1.155 +		}
   1.156 +	iTopLevelStore->FontStore()->iKPixelHeightInTwips = pixelSize().iHeight;
   1.157 +	iTopLevelStore->FontStore()->iKPixelWidthInTwips = pixelSize().iWidth;
   1.158 +	iTopLevelStore->FontStore()->TypefaceSupport(ttipckg(),index);
   1.159 +	ret = aMessage.Write(1,ttipckg);
   1.160 +	if(ret!=KErrNone)
   1.161 +		{
   1.162 +		aClientPanicRequired = ETrue;
   1.163 +		}
   1.164 +	return ret;
   1.165 +	}
   1.166 +
   1.167 +
   1.168 +TInt CFontBitmapServer::HandleMesgFontHeight(const RMessage2& aMessage, TBool aInTwips)
   1.169 +	{
   1.170 +	TInt typefaceindex = aMessage.Int0();
   1.171 +	TInt fontsize = aMessage.Int1();
   1.172 +
   1.173 +	if(typefaceindex < 0)
   1.174 +		{
   1.175 +		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   1.176 +		return KErrArgument;
   1.177 +		}
   1.178 +	
   1.179 +	// pixel size (used to be set in a separate call)
   1.180 +	TPckgBuf<TSize> size;
   1.181 +	TInt ret = aMessage.Read(2, size);
   1.182 +	if (ret != KErrNone)
   1.183 +		{
   1.184 +		return ret;
   1.185 +		}
   1.186 +		
   1.187 +	if(size().iHeight <=  0 || size().iWidth < 0)
   1.188 +		{
   1.189 +		aMessage.Panic(KFBSERVPanicCategory,KErrArgument);
   1.190 +		return KErrArgument;
   1.191 +		}
   1.192 +			
   1.193 +	iTopLevelStore->FontStore()->iKPixelHeightInTwips = size().iHeight;
   1.194 +	iTopLevelStore->FontStore()->iKPixelWidthInTwips = size().iWidth;
   1.195 +	if (aInTwips)
   1.196 +		{
   1.197 +		return iTopLevelStore->FontStore()->FontHeightInTwips(typefaceindex,fontsize);
   1.198 +		}
   1.199 +	else
   1.200 +		{
   1.201 +		return iTopLevelStore->FontStore()->FontHeightInPixels(typefaceindex,fontsize);
   1.202 +		}
   1.203 +	}
   1.204 +
   1.205 +
   1.206 +#ifdef _DEBUG
   1.207 +//aRet is used in debug builds to allow the server to know if the call was successful.
   1.208 +//On success there should be no panics from out of memory testing, since memory
   1.209 +//may have been genuinely allocated.
   1.210 +void CFontBitmapServer::ProcMessage(const RMessage2& aMessage, TInt aSession, TInt& aRet)
   1.211 +#else
   1.212 +void CFontBitmapServer::ProcMessage(const RMessage2& aMessage, TInt aSession)
   1.213 +#endif
   1.214 +	{
   1.215 +    TInt ret=KErrNone;
   1.216 +	TBool clientPanicRequired = EFalse;
   1.217 +#ifdef _DEBUG
   1.218 +	TInt num=0;
   1.219 +#endif
   1.220 +	switch (aMessage.Function())
   1.221 +		{
   1.222 +	case EFbsMessShutdown:
   1.223 +		CActiveScheduler::Stop();
   1.224 +		break;
   1.225 +	case EFbsMessNumTypefaces:
   1.226 +		ret=iTopLevelStore->FontStore()->NumTypefaces();
   1.227 +		break;
   1.228 +	case EFbsMessTypefaceSupport:
   1.229 +		ret = HandleMesgTypefaceSupport(aMessage, clientPanicRequired);
   1.230 +		break;
   1.231 +
   1.232 +	case EFbsMessFontHeightInTwips:
   1.233 +		ret = HandleMesgFontHeight(aMessage, ETrue);
   1.234 +		break;
   1.235 +
   1.236 +	case EFbsMessFontHeightInPixels:
   1.237 +		ret = HandleMesgFontHeight(aMessage, EFalse);
   1.238 +		break;
   1.239 +
   1.240 +	case EFbsMessSetPixelHeight:
   1.241 +		iTopLevelStore->FontStore()->iKPixelWidthInTwips=aMessage.Int0();
   1.242 +		iTopLevelStore->FontStore()->iKPixelHeightInTwips=aMessage.Int1();
   1.243 +		break;
   1.244 +#ifdef _DEBUG
   1.245 +	case EFbsMessDefaultAllocFail:
   1.246 +		num=aMessage.Int0();
   1.247 +		if(num) __UHEAP_FAILNEXT(num);
   1.248 +		else __UHEAP_RESET;
   1.249 +		break;
   1.250 +	case EFbsMessDefaultMark:
   1.251 +		__UHEAP_MARK;
   1.252 +		break;
   1.253 +	case EFbsMessDefaultMarkEnd:
   1.254 +		num=aMessage.Int0();
   1.255 +		if(num) __UHEAP_MARKENDC(num);
   1.256 +		else __UHEAP_MARKEND;
   1.257 +		break;
   1.258 +	case EFbsMessUserAllocFail:
   1.259 +		num=aMessage.Int0();
   1.260 +		if(num) __RHEAP_FAILNEXT(iTopLevelStore->Heap(),num);
   1.261 +		else __RHEAP_RESET(iTopLevelStore->Heap());
   1.262 +		break;
   1.263 +	case EFbsMessUserMark:
   1.264 +		__RHEAP_MARK(iTopLevelStore->Heap());
   1.265 +		break;
   1.266 +	case EFbsMessUserMarkEnd:
   1.267 +		num=aMessage.Int0();
   1.268 +		if(num) __RHEAP_MARKENDC(iTopLevelStore->Heap(),num);
   1.269 +		else __RHEAP_MARKEND(iTopLevelStore->Heap());
   1.270 +		break;
   1.271 +#endif
   1.272 +	case EFbsMessHeapCheck:
   1.273 +		iTopLevelStore->Heap()->Check();
   1.274 +		User::Heap().Check();
   1.275 +		break;
   1.276 +	case EFbsMessSetDefaultGlyphBitmapType:
   1.277 +		iTopLevelStore->FontStore()->SetDefaultBitmapType((TGlyphBitmapType)aMessage.Int0());
   1.278 +		break;
   1.279 +	case EFbsMessGetDefaultGlyphBitmapType:
   1.280 +		ret = iTopLevelStore->FontStore()->DefaultBitmapType();
   1.281 +		break;
   1.282 +	case EFbsMessFontNameAlias:
   1.283 +		TRAP(ret, iTopLevelStore->SetFontNameAliasL(aMessage));
   1.284 +		break;
   1.285 +	case EFbsMessGetHeapSizes:
   1.286 +		TRAP(ret, GetHeapSizesL(aMessage));
   1.287 +		break;
   1.288 +	case EFbsMessDefaultLanguageForMetrics:
   1.289 +		iTopLevelStore->SetDefaultLanguageForMetrics(aMessage);
   1.290 +		break;
   1.291 +	case EFbsCompress:
   1.292 +		iTopLevelStore->BackgroundCompression()->CompressAll();
   1.293 +		break;
   1.294 +	case EFbsMessRegisterLinkedTypeface:
   1.295 +		{
   1.296 +		TPckgBuf<TLinkedTypefaceSpecificationArgs> buf;
   1.297 +		ret=aMessage.Read(0,buf);
   1.298 +		if (ret==KErrNone)
   1.299 +			{
   1.300 +			//Id used by original font linking; now unused.
   1.301 +			TInt id;
   1.302 +			ret=iTopLevelStore->FontStore()->CreateLinkedTypeface(buf(),aSession,id);
   1.303 +			}
   1.304 +		}
   1.305 +		break;
   1.306 +	case EFbsMessFetchLinkedTypeface:
   1.307 +			{
   1.308 +			TBuf<KMaxTypefaceNameLength> name;
   1.309 +			ret = aMessage.GetDesLength(0);
   1.310 +				
   1.311 +			if (ret < 0) 
   1.312 +				break;
   1.313 +				
   1.314 +			if (ret > KMaxTypefaceNameLength)
   1.315 +				{
   1.316 +				clientPanicRequired = ETrue;
   1.317 +				ret = KErrTooBig;
   1.318 +				break;
   1.319 +				}
   1.320 +				
   1.321 +			ret = aMessage.Read(0,name);
   1.322 +	
   1.323 +			TLinkedTypefaceSpecificationArgs spec;
   1.324 +				
   1.325 +			spec.iName = name;
   1.326 +				
   1.327 +			if (ret==KErrNone)
   1.328 +				{
   1.329 +				TRAP(ret, iTopLevelStore->FontStore()->GetLinkedTypefaceL(spec));
   1.330 +	
   1.331 +				if (ret == KErrNone)
   1.332 +					{
   1.333 +					TPckgBuf<TLinkedTypefaceSpecificationArgs> specArgs = spec;					
   1.334 +					ret = aMessage.Write(2,specArgs);
   1.335 +					}
   1.336 +				}
   1.337 +			}
   1.338 +		break;
   1.339 +		case EFbsMessUpdateLinkedTypeface:
   1.340 +			{
   1.341 +			TPckgBuf<TLinkedTypefaceSpecificationArgs> buf;
   1.342 +			ret=aMessage.Read(0,buf);
   1.343 +			if (ret==KErrNone)
   1.344 +				{
   1.345 +				TRAP(ret, iTopLevelStore->FontStore()->UpdateLinkedTypefaceL(buf()));
   1.346 +				}
   1.347 +			}
   1.348 +		break;
   1.349 +	}
   1.350 +
   1.351 +	if (clientPanicRequired)
   1.352 +		{
   1.353 +		aMessage.Panic(KFBSERVPanicCategory,ret);
   1.354 +		}
   1.355 +	else
   1.356 +		{
   1.357 +		if(!aMessage.IsNull())
   1.358 +			{
   1.359 +			aMessage.Complete(ret);
   1.360 +			}		
   1.361 +		}
   1.362 +
   1.363 +#ifdef _DEBUG
   1.364 +	aRet=ret;
   1.365 +#endif	
   1.366 +
   1.367 +	}
   1.368 +
   1.369 +/**
   1.370 +Returns the current sizes of the FBServ default heap, the heap for large bitmaps, 
   1.371 +and the heap for small bitmaps.
   1.372 +
   1.373 +Not supported in release builds.
   1.374 +
   1.375 +@internalComponent
   1.376 +@test
   1.377 +@param aMessage Encapsulates references to integers supplied by the caller, which will on return contain the sizes of the default heap, heap for small bitmaps, and heap for large bitmaps.
   1.378 +@leave KErrNotSupported when used in release mode.
   1.379 +*/
   1.380 +#ifdef _DEBUG
   1.381 +void CFontBitmapServer::GetHeapSizesL(const RMessage2& aMessage)
   1.382 +	{
   1.383 +	TPckgBuf<THeapSizes> data;
   1.384 +	TInt defaultHeapSize = 0;
   1.385 +	TInt smallBmpHeapSize = 0;		
   1.386 +	TInt bigBmpHeapSize = 0;		
   1.387 +	
   1.388 +	User::Heap().AllocSize(defaultHeapSize);
   1.389 +	bigBmpHeapSize = iTopLevelStore->iLargeBitmapChunk.Size();
   1.390 +	iTopLevelStore->Heap()->AllocSize(smallBmpHeapSize);
   1.391 +	
   1.392 +	data().iDefault = defaultHeapSize;
   1.393 +	data().iBig = bigBmpHeapSize;
   1.394 +	data().iSmall = smallBmpHeapSize;
   1.395 +	
   1.396 +	aMessage.WriteL(0, data);
   1.397 +	}
   1.398 +#else
   1.399 +void CFontBitmapServer::GetHeapSizesL(const RMessage2&)
   1.400 +	{
   1.401 +	User::Leave(KErrNotSupported);	
   1.402 +	}	
   1.403 +#endif
   1.404 +
   1.405 +
   1.406 +CFontObject::CFontObject(CFontStore* aFontStore, CGlyphAtlas* aGlyphAtlas):
   1.407 +	CObject(),
   1.408 +	iFontStore(aFontStore),
   1.409 +	iGlyphAtlas(aGlyphAtlas)
   1.410 +	{
   1.411 +	}
   1.412 +
   1.413 +CFontObject::~CFontObject()
   1.414 +	{
   1.415 +	if (AccessCount()==1)
   1.416 +		{
   1.417 +		Dec();
   1.418 +		}
   1.419 +	iFontStore->ReleaseFont(iAddressPointer);
   1.420 +	if (iGlyphAtlas)
   1.421 +		{
   1.422 +		iGlyphAtlas->FontReleased(*iAddressPointer);
   1.423 +		}
   1.424 +	}
   1.425 +
   1.426 +// CBitmapObject constructor - takes ownership of aBmp
   1.427 +CBitmapObject::CBitmapObject(CFbTop& aFbTop, CBitwiseBitmap* aBmp):
   1.428 +	CObject(),
   1.429 +	iFbTop(&aFbTop),
   1.430 +	iAddressPointer(aBmp)
   1.431 +	{
   1.432 +	__ASSERT_DEBUG(iAddressPointer, User::Invariant());
   1.433 +	}
   1.434 +
   1.435 +/** Second-phase constructor of reference counting objects for bitmaps.
   1.436 +Adds the CBitmapObject to the bitmap object container and, if it is not a
   1.437 +replacement for a dirty bitmap, assigns a server-wide handle to it and adds
   1.438 +it to the server's bitmap index. When a replacement bitmap is attached to
   1.439 +the corresponding dirty bitmap with a call to SetCleanBitmap(), then it is
   1.440 +assigned the same server-wide handle as the bitmap to be replaced.
   1.441 +
   1.442 +@param aReplacement If ETrue the bitmap is being created as a replacement
   1.443 +	for a bitmap being made dirty by a resize or compress operation.
   1.444 +@internalComponent
   1.445 +*/
   1.446 +void CBitmapObject::ConstructL(TBool aReplacement)
   1.447 +	{
   1.448 +	iFbTop->iBitmapCon->AddL(this);
   1.449 +	if (!aReplacement)
   1.450 +		{
   1.451 +		iHandle = reinterpret_cast<TInt>(this);
   1.452 +		while (iFbTop->iBitmapObjectIndex.FindInOrder(this, Compare) != KErrNotFound)
   1.453 +			{
   1.454 +			++iHandle;
   1.455 +			}
   1.456 +		User::LeaveIfError(iFbTop->iBitmapObjectIndex.InsertInOrder(this, Compare));
   1.457 +		}
   1.458 +	}
   1.459 +
   1.460 +void CleanupBitmapObject(TAny* aPtr)
   1.461 +	{
   1.462 +	CBitmapObject* ptr = static_cast<CBitmapObject*>(aPtr);	
   1.463 +	ptr->Close();
   1.464 +	}
   1.465 +
   1.466 +/** Create a reference counting object for a new bitmap.
   1.467 +
   1.468 +@param aFbTop Reference to the CFbTop singleton.
   1.469 +@param aBmp Bitmap to be attached to the new reference counting object.
   1.470 +	The bitmap must have been pushed on the clean-up stack and it will be
   1.471 +	popped out of the stack by this function. Ownership will be transferred
   1.472 +	to the reference counting object.
   1.473 +@param aReplacement If ETrue the bitmap is being created as a replacement
   1.474 +	for a bitmap being made dirty by a resize or compress operation.
   1.475 +@internalComponent
   1.476 +*/
   1.477 +CBitmapObject* CBitmapObject::NewL(CFbTop& aFbTop, CBitwiseBitmap* aBmp, TBool aReplacement)
   1.478 +	{
   1.479 +	CBitmapObject* bmpObj = new(ELeave) CBitmapObject(aFbTop, aBmp);
   1.480 +	CleanupStack::Pop(aBmp); // aBmp is owned now by bmpObj
   1.481 +	TCleanupItem bitmapObjectCleanupItem(CleanupBitmapObject, bmpObj);
   1.482 +	CleanupStack::PushL(bitmapObjectCleanupItem);
   1.483 +	bmpObj->ConstructL(aReplacement);
   1.484 +	CleanupStack::Pop(bmpObj);
   1.485 +	return bmpObj;
   1.486 +	}
   1.487 +
   1.488 +CBitmapObject::~CBitmapObject()
   1.489 +	{
   1.490 +	iFbTop->BackgroundCompression()->RemoveFromCompressionQueue(this);
   1.491 +	// the associated clean bitmap object cannot possibly be now in the background compression queue
   1.492 +	if (iHandle)
   1.493 +		{
   1.494 +		if (Owner() == NULL)
   1.495 +			{
   1.496 +			TInt index = iFbTop->iBitmapObjectIndex.FindInOrder(this, Compare);
   1.497 +			if (index != KErrNotFound)
   1.498 +				{
   1.499 +				if (iCleanBitmap)
   1.500 +					{
   1.501 +					iFbTop->iBitmapObjectIndex[index] = iCleanBitmap;
   1.502 +					}
   1.503 +				else
   1.504 +					{
   1.505 +					iFbTop->iBitmapObjectIndex.Remove(index);
   1.506 +					}
   1.507 +				}
   1.508 +			}
   1.509 +		if (iCleanBitmap != NULL)
   1.510 +			{
   1.511 +			iCleanBitmap->SetOwner(NULL);
   1.512 +			iCleanBitmap->Close();
   1.513 +			}
   1.514 +		}
   1.515 +	delete iAddressPointer;
   1.516 +	}
   1.517 +
   1.518 +void CBitmapObject::SetCleanBitmap(CBitmapObject* aNewBmpObj)
   1.519 +	{
   1.520 +	__ASSERT_DEBUG(iHandle, User::Invariant());
   1.521 +	__ASSERT_DEBUG(iCleanBitmap == NULL, User::Invariant());
   1.522 +	__ASSERT_DEBUG(aNewBmpObj->Owner() == NULL, User::Invariant());
   1.523 +	__ASSERT_DEBUG(aNewBmpObj->iHandle == 0, User::Invariant());
   1.524 +	__ASSERT_DEBUG(aNewBmpObj->iCleanBitmap == NULL, User::Invariant());
   1.525 +	iCleanBitmap = aNewBmpObj;
   1.526 +	aNewBmpObj->SetOwner(this);
   1.527 +	aNewBmpObj->iHandle = iHandle;
   1.528 +	iAddressPointer->iSettings.SetDirtyBitmap();
   1.529 +	aNewBmpObj->iAddressPointer->Extra()->iSerialNumber = iAddressPointer->Extra()->iSerialNumber;
   1.530 +	aNewBmpObj->iAddressPointer->Extra()->iTouchCount = iAddressPointer->Extra()->iTouchCount + 1;
   1.531 +	}
   1.532 +
   1.533 +void CBitmapObject::Close()
   1.534 +	{
   1.535 +	if ((iCleanBitmap != NULL) && (Owner() != NULL) && (AccessCount() == 2))
   1.536 +		{
   1.537 +		static_cast<CBitmapObject*>(Owner())->iCleanBitmap = iCleanBitmap;
   1.538 +		iCleanBitmap->SetOwner(Owner());
   1.539 +		iHandle = 0;
   1.540 +		Dec();
   1.541 +		}
   1.542 +	CObject::Close();
   1.543 +	}
   1.544 +
   1.545 +TInt CBitmapObject::Compare(const CBitmapObject& aBmpObj1, const CBitmapObject& aBmpObj2)
   1.546 +	{
   1.547 +	return aBmpObj1.iHandle - aBmpObj2.iHandle;
   1.548 +	}
   1.549 +
   1.550 +TInt CBitmapObject::Compare(const TInt* aHandle, const CBitmapObject& aBmpObj)
   1.551 +	{
   1.552 +	return *aHandle - aBmpObj.iHandle;
   1.553 +	}
   1.554 +
   1.555 +// CSharedBitmapObject constructor - takes ownership of aBmp and aKey
   1.556 +CSharedBitmapObject::CSharedBitmapObject(CFbTop& aFbTop, CBitwiseBitmap* aBmp, TDesC* aKey):
   1.557 +	CBitmapObject(aFbTop, aBmp),
   1.558 +	iKey(aKey)
   1.559 +	{
   1.560 +	__ASSERT_DEBUG(iKey, User::Invariant());	
   1.561 +	}
   1.562 +
   1.563 +/** Second-phase constructor of reference counting objects for bitmaps
   1.564 +loaded to share from a file. Adds the CSharedBitmapObject to the bitmap
   1.565 +object container, assigns a server-wide handle to it and adds it to the
   1.566 +server's bitmap index and to the server's shared bitmap hash map.
   1.567 +
   1.568 +@param aHash Hash value of the key associated with the bitmap.
   1.569 +@internalComponent
   1.570 +*/
   1.571 +void CSharedBitmapObject::ConstructL(TUint aHash)
   1.572 +	{
   1.573 +	CBitmapObject::ConstructL(EFalse);
   1.574 +	iFbTop->iSharedBitmapObjectHashMap.Insert(*this, aHash);
   1.575 +	}
   1.576 +
   1.577 +/** Create a reference counting object for a bitmap loaded to share from a file.
   1.578 +
   1.579 +@param aFbTop Reference to the CFbTop singleton.
   1.580 +@param aBmp Bitmap to be attached to the new reference counting object.
   1.581 +	The bitmap must have been pushed on the clean-up stack and it will be
   1.582 +	popped out of the stack by this function. Ownership will be transferred
   1.583 +	to the reference counting object.
   1.584 +@param aKey Key associated with the bitmap. The key must have been pushed on
   1.585 +	the clean-up stack and it will be popped out of the stack by this function.
   1.586 +	Ownership will be transferred to the reference counting object.
   1.587 +@param aHash Hash value of the key associated with the bitmap.
   1.588 +@internalComponent
   1.589 +*/
   1.590 +CSharedBitmapObject* CSharedBitmapObject::NewL(CFbTop& aFbTop, CBitwiseBitmap* aBmp, TDesC* aKey, TUint aHash)
   1.591 +	{
   1.592 +	CSharedBitmapObject* bmpObj = new(ELeave) CSharedBitmapObject(aFbTop, aBmp, aKey);
   1.593 +	CleanupStack::Pop(2, aKey); // aBmp and aKey are owned now by bmpObj
   1.594 +	TCleanupItem bitmapObjectCleanupItem(CleanupBitmapObject, bmpObj);
   1.595 +	CleanupStack::PushL(bitmapObjectCleanupItem);
   1.596 +	bmpObj->ConstructL(aHash);
   1.597 +	CleanupStack::Pop(bmpObj);
   1.598 +	return bmpObj;
   1.599 +	}
   1.600 +
   1.601 +CSharedBitmapObject::~CSharedBitmapObject()
   1.602 +	{
   1.603 +	iFbTop->iSharedBitmapObjectHashMap.Remove(*this);
   1.604 +	delete iKey;
   1.605 +	}
   1.606 +
   1.607 +// Constructs a single key object from constituent parts that uniquely identify a bitmap
   1.608 +HBufC* CSharedBitmapObject::KeyLC(const TDesC& aFileName, TInt aId, const TTime& aModTime)
   1.609 +	{
   1.610 +	static const TInt K16BitSizeOfTInt  = sizeof(TInt) /sizeof(TUint16);
   1.611 +	static const TInt K16BitSizeOfTTime = sizeof(TTime)/sizeof(TUint16);
   1.612 +	
   1.613 +	HBufC* key = HBufC::NewLC(K16BitSizeOfTInt + K16BitSizeOfTTime + aFileName.Length());
   1.614 +	
   1.615 +	TPtr keyPtr = key->Des();
   1.616 +	
   1.617 +	keyPtr.Append(reinterpret_cast<const TUint16*>(&aId),      K16BitSizeOfTInt);
   1.618 +	keyPtr.Append(reinterpret_cast<const TUint16*>(&aModTime), K16BitSizeOfTTime);
   1.619 +	keyPtr.Append(aFileName);
   1.620 +
   1.621 +	return key;
   1.622 +	}