diff -r 000000000000 -r bde4ae8d615e os/graphics/fbs/fontandbitmapserver/sfbs/SESSION.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/graphics/fbs/fontandbitmapserver/sfbs/SESSION.CPP Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,604 @@ +// Copyright (c) 1995-2010 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 +#include "fbsdefs.h" +#include "UTILS.H" +#include "FBSVER.H" +#include "FbsRalc.h" +#include "fbshelper.h" +#include "FbsMessage.H" +#include +#include "OstTraceDefinitions.h" +#include "fbstrace.h" +#ifdef OST_TRACE_COMPILER_IN_USE +#include "SESSIONTraces.h" +#endif + +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) + { + TInt ret = KErrNone; + RFbsSession* thisptr = (RFbsSession*)Dll::Tls(); + FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_CONNECT_ENTRY, "> this=0x%08x;", (TUint)thisptr);) + if(thisptr) + { + thisptr->iConnections++; + FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_SEMANTICS, RFBSSESSION_CONNECT_INFO, "# Connected to existing session; this=0x%08x; iConnections=%d;", (TInt)thisptr, thisptr->iConnections);) + } + else + { + ret = RFbsSession::DoAlloc(thisptr); + if(ret!=KErrNone) + { + FBS_OST(OstTrace1(TRACE_ERROR, RFBSSESSION_CONNECT_ERROR, "! DoAlloc returned %d", ret);) + } + else + { + ret = thisptr->DoConnect(aFileServer); + if(ret!=KErrNone) + { + FBS_OST(OstTraceExt2(TRACE_ERROR, RFBSSESSION_CONNECT_ERROR2, "! this=0x%08x; DoConnect returned %d", (TInt)thisptr, ret);) + } + } + } + + FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_CONNECT_EXIT, "< this=0x%08x; ret=%d", (TUint)thisptr, ret);) + return ret; + } + +/** 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() + { + TInt ret = KErrNone; + RFbsSession* thisptr = (RFbsSession*)Dll::Tls(); + FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_CONNECT2_ENTRY, "> this=0x%08x;", (TUint)thisptr);) + if(thisptr) + { + thisptr->iConnections++; + FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_SEMANTICS, RFBSSESSION_CONNECT2_INFO, "# Connected to existing session; this=0x%08x; iConnections=%d;", (TInt)thisptr, thisptr->iConnections);) + } + else + { + TInt ret = RFbsSession::DoAlloc(thisptr); + if (ret!=KErrNone) + { + FBS_OST(OstTrace1(TRACE_ERROR, RFBSSESSION_CONNECT2_ERROR, "! DoAlloc returned %d", ret);) + goto end; + } + + ret = thisptr->iFileServer.Connect(); + if(ret!=KErrNone) + { + thisptr->Disconnect(); + FBS_OST(OstTraceExt2(TRACE_ERROR, RFBSSESSION_CONNECT2_ERROR2, "! this=0x%08x; RFs::Connect() returned %d", (TInt)thisptr, ret);) + goto end; + } + + ret = thisptr->DoConnect(thisptr->iFileServer); + if(ret!=KErrNone) + { + FBS_OST(OstTraceExt2(TRACE_ERROR, RFBSSESSION_CONNECT2_ERROR3, "! this=0x%08x; DoConnect returned %d", (TInt)thisptr, ret);) + } + } +end: + FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_CONNECT2_EXIT, "< this=0x%08x; ret=%d", (TUint)thisptr, ret);) + return ret; + } + +/** Closes the session with the Font and Bitmap server. +@publishedAll +@released +*/ +EXPORT_C void RFbsSession::Disconnect() + { + RFbsSession* thisptr=(RFbsSession*)Dll::Tls(); + FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_DISCONNECT_ENTRY, "> this=0x%08x;", (TUint)thisptr);) + if(thisptr) + { + TInt tempServerSessionHandle = thisptr->ServerSessionHandle(); + 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(); + } + FBS_OST(OstTraceExt3(GRAPHICS_CONTROL_SEMANTICS, RFBSSESSION_DISCONNECT_INFO, "# Disconnected from session; this=0x%08x; iConnections=%d; iSSH=0x%08x", (TInt)thisptr, thisptr->iConnections, tempServerSessionHandle);) + } + FBS_OST(OstTrace1(GRAPHICS_CONTROL_FUNCTIONS, RFBSSESSION_DISCONNECT_EXIT2, "< this=0x%08x;", (TUint)thisptr);) + } + +/** 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; + + FBS_OST(OstTraceExt2(GRAPHICS_CONTROL_SEMANTICS, RFBSSESSION_DOCONNECT_INFO, "# New FBS Session created; this=0x%08x; iSSH=0x%08x;", (TInt)this, serverAssignedHandle);) + 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; + } + +EXPORT_C TInt RFbsSession::GetGlyphCacheMetrics( TGlyphCacheMetrics& aGlyphCacheMetrics ) + { + TPckgBuf metrics; + TIpcArgs args( &metrics ); + + TInt ret = SendReceive( EFbsMessGetGlyphCacheMetrics, args ); + aGlyphCacheMetrics = metrics(); + + return ret; + } + +/** + Perform the IPC to convey the desired OoGM action to the glyph atlas. + + @return KErrNone if IPC was successful. One of the system-wide error + codes, as described for RSessionBase::SendReceive(), if not. + + @note The server-side platform security policy applied to this method is such that it is only useable by the GOoM framework. + + @param aOogmMessage. A reference to the class encapsulating the OoGM action required of the glyph atlas. +*/ +EXPORT_C TInt RFbsSession::ConveyOogmMessage( TFbsOogmMessage& aOogmMessage ) + { + TPckgBuf oogmMessage; + oogmMessage() = aOogmMessage; + TIpcArgs args( &oogmMessage ); + + return SendReceive( EFbsMessOogmNotification, args ); + } + +/** +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 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