fbs/fontandbitmapserver/sfbs/SESSION.CPP
changeset 0 5d03bc08d59c
child 18 57c618273d5c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fbs/fontandbitmapserver/sfbs/SESSION.CPP	Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,521 @@
+// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <fbs.h>
+#include "fbsdefs.h"
+#include "UTILS.H"
+#include "FBSVER.H"
+#include "FbsRalc.h"
+#include "fbshelper.h"
+#include "fbsmessage.h"
+
+GLDEF_C void Panic(TFbsPanic aPanic)
+	{
+	_LIT(KFBSERVClientPanicCategory,"FBSCLI");
+	User::Panic(KFBSERVClientPanicCategory,aPanic);
+	}
+
+EXPORT_C TInt FbsStartup()
+	{
+	RChunk sharedchunk;
+	TInt ret = sharedchunk.OpenGlobal(KFBSERVSharedChunkName,EFalse);
+	if (ret == KErrNone)
+		{
+		sharedchunk.Close();
+		return KErrNone;
+		}
+
+	RProcess fbs;
+	_LIT(KFBSERVServerExe,"z:\\sys\\bin\\fbserv.exe");
+	ret = fbs.Create(KFBSERVServerExe,KNullDesC);
+
+	if (ret!=KErrNone)
+		return ret;
+	
+  	
+	TRequestStatus stat;
+	fbs.Rendezvous(stat);
+	if (stat!=KRequestPending)
+		fbs.Kill(0);		// abort startup
+	else
+		fbs.Resume();	// logon OK - start the server
+	User::WaitForRequest(stat);		// wait for start or death
+	// we can't use the 'exit reason' if the server panicked as this
+	// is the panic 'reason' and may be '0' which cannot be distinguished
+	// from KErrNone
+	ret=(fbs.ExitType()==EExitPanic) ? KErrGeneral : stat.Int();
+	fbs.Close();
+	return ret;
+	}
+
+
+//
+// Fontbitmap server client side session
+//
+
+/** 
+@publishedAll 
+@released
+*/
+EXPORT_C RFbsSession::RFbsSession():
+	RSessionBase(),
+	iConnections(0),
+	iCallBack(),
+	iSharedChunk(),
+	iHelper(NULL),
+	iRomFileAddrCache(NULL),
+	iDecompressionBuffer(NULL),
+	iScanLineBuffer(NULL),
+	iSpare(NULL)
+	{}
+
+/** Creates a session with the Font and Bitmap server.
+@param aFileServer A fuly constructed file server session
+@return KErrNone, if successful; KErrNoMemory if there is not enough memory 
+to create the session; otherwise another of the system-wide error codes. 
+@publishedAll 
+@released
+*/
+EXPORT_C TInt RFbsSession::Connect(RFs& aFileServer)
+	{
+	RFbsSession* thisptr = (RFbsSession*)Dll::Tls();
+	if(thisptr)
+		{
+		thisptr->iConnections++;
+		return KErrNone;
+		}
+	TInt ret = RFbsSession::DoAlloc(thisptr);
+	if(ret!=KErrNone)
+		return ret;
+	return thisptr->DoConnect(aFileServer);
+	}
+
+/** Creates a session with the Font and Bitmap server.
+@return KErrNone, if successful; KErrNoMemory if there is not enough memory 
+to create the session; otherwise another of the system-wide error codes. 
+@publishedAll 
+@released
+*/
+EXPORT_C TInt RFbsSession::Connect()
+	{
+	RFbsSession* thisptr = (RFbsSession*)Dll::Tls();
+	if(thisptr)
+		{
+		thisptr->iConnections++;
+		return KErrNone;
+		}
+	TInt ret = RFbsSession::DoAlloc(thisptr);
+	if (ret!=KErrNone)
+		return ret;
+	ret = thisptr->iFileServer.Connect();
+	if(ret!=KErrNone)
+		{
+		thisptr->Disconnect();
+		return ret;
+		}
+	return thisptr->DoConnect(thisptr->iFileServer);
+	}
+
+/** Closes the session with the Font and Bitmap server. 
+@publishedAll 
+@released
+*/
+EXPORT_C void RFbsSession::Disconnect()
+	{
+	RFbsSession* thisptr=(RFbsSession*)Dll::Tls();
+	if(thisptr==NULL) return;
+	if(thisptr->iConnections>0)
+		{
+		thisptr->iCallBack.iPtr=NULL;
+		thisptr->iCallBack.CallBack();
+		// Destructor of CFbsSessionHelper may call SendCommand to cancel an
+		// outstanding request, therefore destruction must be done before
+		// iConnections is 0 to avoid an assertion going off.
+		if(thisptr->iConnections==1)
+			{
+			delete thisptr->iHelper;
+			}
+		thisptr->iConnections--;
+		}
+	if(thisptr->iConnections==0)
+		{
+		thisptr->iSharedChunk.Close();
+		thisptr->iLargeBitmapChunk.Close();
+		// Call close on the iFileServer regardless of whether this session owns it: 
+		// if we don't own it, close will do nothing if there are still open files, 
+		// so always calling close introduces extra safety
+		thisptr->iFileServer.Close();
+		delete thisptr->iRomFileAddrCache; 
+		delete thisptr->iScanLineBuffer;
+		delete thisptr->iDecompressionBuffer;
+		thisptr->Close();
+		delete thisptr;
+		Dll::FreeTls();
+		}
+	}
+
+/**  Gets the current Font and Bitmap server session.
+@return  A pointer to the current session or NULL if Connect() has not been 
+called yet. 
+@publishedAll 
+@released
+*/
+EXPORT_C RFbsSession* RFbsSession::GetSession()
+    {
+	return((RFbsSession*)Dll::Tls());
+	}
+
+/** Triggers the most recently registered callback. This is mainly called by 
+bitmaps when their twips size changes and when any FBSERV objects are closed 
+to notify clients of a change that may affect their operation. 
+@publishedAll 
+@released
+*/
+EXPORT_C void RFbsSession::CallBack()
+    {
+	iCallBack.CallBack();
+	iCallBack.iPtr=NULL;
+	}
+
+void RFbsSession::SetCallBackPtr(TInt* aBitmapHandle)const
+	{
+	iCallBack.iPtr=aBitmapHandle;
+	}
+	
+/** Sets the callback.
+@param aCallBack callback object to be called by CallBack(). Only one may be 
+in use at a time and subsequent calls will displace previous calls. 
+@publishedAll 
+@released
+*/	
+EXPORT_C void RFbsSession::SetCallBack(TCallBack aCallBack)
+    {
+	iCallBack=aCallBack;
+	}
+
+/** Resets the callback. 
+@publishedAll 
+@released
+*/	
+EXPORT_C void RFbsSession::ResetCallBack()
+	{
+	TCallBack cb(NULL);
+	iCallBack=cb;
+	}
+
+/**  Returns the number of Font and Bitmap Server objects currently in 
+use by this session.
+@return The number of resources in use: bitmaps, fonts, typeface stores. 
+@publishedAll 
+@released
+*/	
+EXPORT_C TInt RFbsSession::ResourceCount()
+    {
+	return(SendCommand(EFbsMessResourceCount));
+	}
+
+/** Utility function for passing commands to the server.
+@param aMessage Integer code for the message to pass - see TFbsMessage.
+@param aInt0 Parameter 0 for the message.
+@param aInt1 Parameter 1 for the message.
+@param aInt2 Parameter 2 for the message.
+@param aInt3 Parameter 3 for the message.
+@return Return code from RSessionBase::SendReceive(). 
+@internalComponent
+*/
+EXPORT_C TInt RFbsSession::SendCommand(TInt aMessage,TInt aInt0,TInt aInt1,TInt aInt2,TInt aInt3) const
+   {
+	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
+	switch(aMessage)
+		{
+	case EFbsMessShutdown:
+	case EFbsMessClose:
+		SetCallBackPtr(aMessage==EFbsMessClose ? &aInt1 : 0);
+		iCallBack.CallBack();
+	default:
+		break;
+		}
+	TInt ret = SendReceive(aMessage, TIpcArgs(aInt0,aInt1,aInt2,aInt3));
+	return(ret);
+	}
+
+TInt RFbsSession::SendCommand(TInt aMessage, const TIpcArgs& aArgs) const
+	{
+	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
+	return SendReceive(aMessage,aArgs);
+	}
+
+void RFbsSession::SendCommand(TInt aMessage, const TIpcArgs& aArgs, TRequestStatus &aStatus) const
+	{
+	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
+	SendReceive(aMessage,aArgs,aStatus);
+	}
+	
+/** Gets the current Font and Bitmap server version.
+@return The current version of the server. 
+@publishedAll 
+@released
+*/
+EXPORT_C TVersion RFbsSession::Version()
+	{
+	TVersion v(KFbsMajorVersionNumber,KFbsMinorVersionNumber,KFbsBuildVersionNumber);
+	return(v);
+	}
+
+/** Gets the address of first location in the global shared heap containing 
+fonts and bitmaps.
+@return Pointer to the base of the shared heap. 
+@publishedAll 
+@released
+*/	
+EXPORT_C TUint8* RFbsSession::HeapBase() const
+	{
+	return(iSharedChunk.Base());
+	}
+
+TBool RFbsSession::LookupBitmapInROM(const TDesC& aFilename, TAny*& aAddr)
+	{
+	aAddr = iRomFileAddrCache->Lookup(aFilename);
+	if (aAddr)
+		return ETrue;
+	return EFalse;
+   	}
+
+TInt RFbsSession::DoAlloc(RFbsSession*& aNewSession)
+	{
+	aNewSession = (RFbsSession*)User::Alloc(sizeof(RFbsSession));
+	if(!aNewSession) 
+		return KErrNoMemory;
+	new(aNewSession) RFbsSession;
+	aNewSession->iConnections = 1;
+	TInt ret = Dll::SetTls(aNewSession);
+	if(ret!=KErrNone)
+		{
+		delete aNewSession;
+		aNewSession = NULL;
+		}
+	return ret;
+	}
+
+/**  
+Do actual connect as common to both Connect() and Connect(RFs& aFileServer). Store fully constructed
+file server session to iSpare member variable
+@see Connect()
+@return KErrNone, if successful; KErrNoMemory if there is not enough memory 
+to create the session; otherwise another of the system-wide error codes. 
+@internalComponent
+*/
+TInt RFbsSession::DoConnect(RFs& aFileServer)
+	{
+	//Allow this session to be accessed by other process to lead bitmap in server
+	TInt ret = aFileServer.ShareProtected();
+	if (ret!=KErrNone)
+		{
+		Disconnect();
+		return ret;
+		}
+	iRomFileAddrCache = CFbsRalCache::New(4, aFileServer);
+	if (!iRomFileAddrCache)
+		{
+		Disconnect();
+		return KErrNoMemory;
+		}
+
+	ret = CreateSession(KFBSERVGlobalThreadName,Version(),-1);
+	if(ret!=KErrNone)
+		{
+		Disconnect();
+		return ret;
+		}
+	const TInt serverAssignedHandle = SendReceive(EFbsMessInit);
+	if(serverAssignedHandle <= 0)
+		{
+		Disconnect();
+		return serverAssignedHandle;
+		}
+	ret = iSharedChunk.OpenGlobal(KFBSERVSharedChunkName,EFalse);
+	if(ret!=KErrNone) 
+		Panic(EFbsPanicChunkError);
+	iHelper = new CFbsSessionHelper(*this);
+	if (!iHelper)
+		{
+		Disconnect();
+		return KErrNoMemory;
+		}
+	iHelper->iServerSessionHandle = serverAssignedHandle;
+	ret = iLargeBitmapChunk.OpenGlobal(KFBSERVLargeChunkName,EFalse);
+	if(ret!=KErrNone) 
+		Panic(EFbsPanicChunkError);
+	
+	iSpare = (TUint32*)&aFileServer;
+	return KErrNone;
+	}
+	
+/**  
+Allocates the buffer for decoding compressed rom bitmaps.
+ 
+Internal use only.
+
+@param 	aSize Minimum size of the buffer required.  
+		If the buffer is too small an attempt to resize it will be made.
+@return KErrNone if successful, 
+		KErrNoMemory if the buffer was too small and could 
+		not be expanded.
+@publishedAll 
+@released
+*/
+TInt RFbsSession::AllocScanLineBuffer(TInt aSize)
+    {
+	if (iScanLineBuffer && iScanLineBuffer->Des().MaxSize() >= aSize)
+		{
+		return KErrNone;
+		}
+
+	HBufC8* newBuffer = HBufC8::New(aSize);
+
+	if (newBuffer)
+		{
+		delete iScanLineBuffer;
+		iScanLineBuffer = newBuffer;
+		return KErrNone;
+		}
+
+	return KErrNoMemory;
+	}
+
+/**  
+Gets a reference to the buffer currently in use for decoding
+compressed rom bitmaps. 
+
+Internal use only.
+
+@return  The buffer area currently in use,
+@publishedAll 
+@released
+*/
+HBufC8* RFbsSession::GetScanLineBuffer()
+    {
+	return iScanLineBuffer;
+	}
+
+/**  
+Gets a pointer to the buffer currently in use for decoding
+compressed mask bitmaps. 
+
+Internal use only.
+@param 	aSize Minimum size of the buffer required.  
+		If the buffer is too small an attempt to resize it will be made.
+@return  The buffer area currently in use or NULL if there is no memory.
+@internalComponent 
+*/
+HBufC8* RFbsSession::GetDecompressionBuffer(TInt aSize)
+	{
+	if (iDecompressionBuffer)
+		{
+		if (iDecompressionBuffer->Des().MaxSize() < aSize)
+			{
+			HBufC8* tempBuffer = iDecompressionBuffer->ReAlloc(aSize);
+			if (!tempBuffer)
+				{
+				return NULL;
+				}
+			iDecompressionBuffer = tempBuffer;
+			}
+		}
+	else
+		{
+		iDecompressionBuffer = HBufC8::New(aSize);
+		}
+
+	return iDecompressionBuffer;
+	}
+
+/**  
+Gets a pointer to an extra buffer for general use. 
+
+Internal use only.
+@param 	aSize Minimum size of the buffer required.  
+		If the buffer is too small an attempt to resize it will be made.
+@return  The buffer area currently in use or NULL if there is no memory.
+@internalComponent 
+*/
+HBufC8* RFbsSession::GetExtraBuffer(TInt aSize)
+	{
+	if (iHelper->iExtraBuffer)
+		{
+		if (iHelper->iExtraBuffer->Des().MaxSize() < aSize)
+			{
+			HBufC8* tempBuffer = iHelper->iExtraBuffer->ReAlloc(aSize);
+			if (!tempBuffer)
+				{
+				return NULL;
+				}
+			iHelper->iExtraBuffer = tempBuffer;
+			}
+		}
+	else
+		{
+		iHelper->iExtraBuffer = HBufC8::New(aSize);
+		}
+
+	return iHelper->iExtraBuffer;
+	}
+
+/**
+Returns a handle assigned to this session by the server upon connection.
+This method should be used instead of SessionHandle() when passing a session 
+handle to FbServ APIs that require Session handles. 
+@return A handle representing this session on the server. 
+@pre The session has successfully connected to the server.
+ */
+TInt RFbsSession::ServerSessionHandle() const
+	{
+	__ASSERT_ALWAYS(iConnections>0,Panic(EFbsPanicBadConnection));
+	return iHelper->iServerSessionHandle;
+	}
+
+/**
+Returns the current sizes of the FBServ default heap, the heap for large bitmaps, 
+and the heap for small bitmaps.
+
+Not supported in release builds.
+
+@internalComponent
+@test
+@param aDefaultHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ default heap.
+@param aSmallBmpHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ heap for small bitmaps
+@param aBigBmpHeapSize A reference to an integer supplied by the caller. On return from this function, contains the size of the FBServ heap for large bitmaps
+@return KErrNone or one of the system wide error codes in debug mode, or KErrNotSupported in release mode.
+*/
+#ifdef _DEBUG
+EXPORT_C TInt RFbsSession::GetHeapSizes(TInt& aDefaultHeapSize, TInt& aSmallBmpHeapSize, TInt& aBigBmpHeapSize)
+ 	{
+ 	TPckgBuf<THeapSizes> data;
+ 	TIpcArgs args(&data);
+ 	TInt ret = SendReceive(EFbsMessGetHeapSizes, args);
+ 	if(ret == KErrNone)
+ 		{
+ 		aDefaultHeapSize = data().iDefault;
+ 		aSmallBmpHeapSize = data().iSmall;
+ 		aBigBmpHeapSize = data().iBig;
+ 		}
+ 	return ret;
+ 	}
+#else
+EXPORT_C TInt RFbsSession::GetHeapSizes(TInt&, TInt&, TInt&)
+	{
+	return KErrNotSupported;
+	}
+#endif