--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/Client/src/alfscreenbuffer.cpp Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,394 @@
+/*
+* Copyright (c) 2006 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: Screen buffer implementation
+*
+*/
+
+
+
+#include <coemain.h>
+
+#include "alflogger.h"
+#include "alf/alfenv.h"
+#include "alfclient.h"
+#include "alf/alfstatic.h"
+#include "alf/alfconstants.h"
+#include "alfuids.h"
+#include "alf/alfscreenbuffer.h"
+#include "alf/alfsymbiansbdrawer.h"
+
+#include <uiacceltk/HuiUtil.h>
+
+// *** class CAlfScreenBufferEventFetcher
+
+NONSHARABLE_CLASS(CAlfScreenBufferEventFetcher): public CActive
+ {
+public: // Struct
+
+ struct TScreenBufferInfo
+ {
+ MAlfScreenBufferObserver* iObserver; // Observer for this screen buffer. Not owned
+ TUid iBufferUid; // Uid of the buffer to be observed.
+ TInt iPriority; // Priority of the buffer. Not yet used.
+ TInt iBitmapHandle; // Handle to the shared CFbsBitmap that contains the buffer.
+ TInt iMaskHandle; // Mask handle
+ TRect iLastDisplayRect; // Display rect
+ TRect iLastDirtyRect; // Dirty rect
+ };
+
+
+public: // New methods
+
+ CAlfScreenBufferEventFetcher(RAlfClient& aClient, MAlfScreenBufferObserver& aScreenBufferObs)
+ :CActive(CActive::EPriorityHigh), iClient(aClient), iEventAsDescriptor(iEvent)
+ {
+ CAlfScreenBufferEventFetcher::TScreenBufferInfo info = {&aScreenBufferObs, KNullUid, 0, 0, 0, TRect(), TRect()};
+ iBufferInfo = info;
+ CActiveScheduler::Add(this);
+ }
+
+ ~CAlfScreenBufferEventFetcher()
+ {
+ Cancel();
+ }
+
+ // Request a new event
+ void RequestBufferEvent()
+ {
+ if(!IsActive())
+ {
+ SetActive();
+ iEvent.iBufferUid = iBufferInfo.iBufferUid;
+ iEvent.iEventId = 0;
+ iEvent.iDisplayRect = TRect();
+ iEvent.iDirtyRect = TRect();
+ iClient.SendAsyncCmd(EAlfSBufRequestEvent, iEventAsDescriptor, iStatus);
+ }
+ }
+
+ // Return buffer info
+ TScreenBufferInfo& ScreenBufferInfo()
+ {
+ return(iBufferInfo);
+ }
+
+private: // From CActive
+
+ void RunL()
+ {
+ if(iStatus.Int() != KErrNone)
+ {
+ USER_INVARIANT();
+ }
+
+ // Issue a new event request first
+ TAlfScreenBufferEvent event = iEvent;
+ RequestBufferEvent();
+
+ // Handle event
+
+ if (event.iEventId == MAlfScreenBufferObserver::ENone) // Buffer complete event
+ {
+ if (iBufferInfo.iObserver->BufferComplete(event.iBufferUid, event.iDisplayRect, event.iDirtyRect))
+ {
+ // Request next buffer automatically
+ TUid uidEvent = event.iBufferUid;
+ TPckg<TUid> eventPckg(uidEvent);
+ iClient.SendSyncCmd(EAlfSBufRequestNextBuffer, eventPckg);
+ }
+ }
+ else
+ {
+ if (event.iEventId == MAlfScreenBufferObserver::ECreated)
+ {
+ // Add this buffer observer again to the array in Alf Server to get valid bitmap handles in return.
+ TAlfScreenBufferBitmaps addObserverEvent = {iBufferInfo.iBufferUid, iBufferInfo.iPriority, NULL, NULL};
+ TPckg<TAlfScreenBufferBitmaps> eventPckg(addObserverEvent);
+ iClient.SendSyncCmd(EAlfSBufAddObserver, eventPckg);
+
+ // Update bitmap handles
+ iBufferInfo.iBitmapHandle = addObserverEvent.iBitmapHandle;
+ iBufferInfo.iMaskHandle = addObserverEvent.iMaskHandle;
+ }
+ else if (event.iEventId == MAlfScreenBufferObserver::EDeleted)
+ {
+ // Invalidate bitmap handles
+ iBufferInfo.iBitmapHandle = NULL;
+ iBufferInfo.iMaskHandle = NULL;
+ }
+
+ iBufferInfo.iObserver->HandleScreenBufferEvent(event.iBufferUid, event.iEventId);
+ }
+ }
+
+ void DoCancel()
+ {
+ // Remove this AO from the observer array in Alf Server
+ TAlfScreenBufferBitmaps event = {iBufferInfo.iBufferUid, 0, 0};
+ TPckg<TAlfScreenBufferBitmaps> eventPckg(event);
+ iClient.SendSyncCmd(EAlfSBufRemoveObserver, eventPckg);
+ }
+
+ TInt RunError(TInt /*aError*/)
+ {
+ // Ignore error
+ return KErrNone;
+ }
+
+private: // Data
+
+ RAlfClient& iClient;
+ TAlfScreenBufferEvent iEvent; // Event data for pending buffer event.
+ TPckg<TAlfScreenBufferEvent> iEventAsDescriptor;
+
+ CAlfScreenBufferEventFetcher::TScreenBufferInfo iBufferInfo; // Buffer information
+ };
+
+
+
+// *** Array item for CAlfScreenBuffer
+
+struct TAlfScreenBufferHandlerItem
+ {
+ TAlfScreenBufferHandlerItem( TInt aId, CAlfScreenBufferEventFetcher* aAoPtr)
+ :iId( aId ), iAoPtr( aAoPtr )
+ {};
+ TInt iId; // Buffer uid
+ CAlfScreenBufferEventFetcher* iAoPtr; // Pointer to the active object that handles buffer events. Owned.
+ };
+
+
+// *** Private data for CAlfScreenBuffer
+
+NONSHARABLE_CLASS(CAlfScreenBuffer::CPrivateData):public CBase
+ {
+ public:
+ ~CPrivateData()
+ {
+ iScreenBufferHandlers.Close();
+ if (iIsAlfEnvOwned)
+ {
+ delete(iEnv);
+ }
+ }
+
+ CAlfEnv* iEnv;
+ TBool iIsAlfEnvOwned;
+ RArray<TAlfScreenBufferHandlerItem> iScreenBufferHandlers; // List of all buffer observer Active Objects
+ };
+
+
+// *** class CAlfScreenBuffer
+
+EXPORT_C CAlfScreenBuffer* CAlfScreenBuffer::NewL()
+ {
+ // Create own aAlf env if it does not exist.
+ TBool isAlfEnvOwned = EFalse;
+ CAlfEnv* env = CAlfEnv::Static();
+ if (!env)
+ {
+ isAlfEnvOwned = ETrue;
+ env = CAlfEnv::NewL();
+ }
+
+ // Create object
+ CAlfScreenBuffer* self = new( ELeave ) CAlfScreenBuffer();
+ CleanupStack::PushL( self );
+ self->ConstructL(env, isAlfEnvOwned);
+ CleanupStack::Pop( self );
+ return self;
+ };
+
+EXPORT_C CAlfScreenBuffer* CAlfScreenBuffer::NewL(CAlfEnv& aEnv)
+ {
+ CAlfScreenBuffer* self = new( ELeave ) CAlfScreenBuffer();
+ CleanupStack::PushL( self );
+ self->ConstructL(&aEnv, EFalse);
+ CleanupStack::Pop( self );
+ return self;
+ };
+
+
+CAlfScreenBuffer::CAlfScreenBuffer()
+ {
+ }
+
+// @deprecated
+EXPORT_C CAlfScreenBuffer::CAlfScreenBuffer(CAlfEnv& /*aEnv*/)
+ {
+ }
+
+
+EXPORT_C CAlfScreenBuffer::~CAlfScreenBuffer()
+ {
+ for (TInt i = iData->iScreenBufferHandlers.Count()-1; i >= 0 ; i--)
+ {
+ RemoveObserver(iData->iScreenBufferHandlers[i].iAoPtr->ScreenBufferInfo().iBufferUid);
+ }
+
+ delete iData;
+ }
+
+// @deprecated
+EXPORT_C void CAlfScreenBuffer::ConstructL()
+ {
+ // Not used, preserved for BC
+ }
+
+void CAlfScreenBuffer::ConstructL(CAlfEnv* aEnv, TBool aIsAlfEnvOwned)
+ {
+ //@todo : should I check that only one instance is created per alf client?
+ // Create private data
+ iData = new (ELeave) CPrivateData;
+ iData->iEnv = aEnv;
+ iData->iIsAlfEnvOwned = aIsAlfEnvOwned;
+ }
+
+
+EXPORT_C MAlfBufferDrawer* CAlfScreenBuffer::GetDrawingInterface(TUid aInterfaceUid, TUid aBufferUid)
+ {
+ // Symbian IF
+ if (aInterfaceUid == KAlfSymbianBufferDrawerUid)
+ {
+ TAlfScreenBufferHandlerItem item( aBufferUid.iUid, NULL );
+ TInt index;
+ if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone )
+ {
+ if (iData->iScreenBufferHandlers[index].iAoPtr->ScreenBufferInfo().iBitmapHandle)
+ {
+ CAlfSymbianBufferDrawer* drawer = NULL;
+ TRAPD(err, drawer = CAlfSymbianBufferDrawer::NewL());
+ if (!err)
+ {
+ TRAP(err,drawer->SetBufferL(
+ iData->iScreenBufferHandlers[index].iAoPtr->ScreenBufferInfo().iBitmapHandle,
+ iData->iScreenBufferHandlers[index].iAoPtr->ScreenBufferInfo().iMaskHandle));
+ if (err)
+ {
+ delete drawer;
+ return NULL;
+ }
+ else
+ {
+ return drawer;
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+ }
+
+
+EXPORT_C MAlfBufferGc* CAlfScreenBuffer::GetGraphicsContext(TUid /*aInterfaceUid*/, TUid /*aBufferUid*/)
+ {
+ return ((MAlfBufferGc*)NULL);
+ }
+
+
+EXPORT_C void CAlfScreenBuffer::AddObserverL(TUid aBufferId, MAlfScreenBufferObserver* aObserver, TInt aPriority)
+ {
+ AddObserverL(aBufferId, CAlfScreenBuffer::EFlagNone, aObserver, aPriority);
+ }
+
+
+EXPORT_C void CAlfScreenBuffer::AddObserverL(TUid aBufferId, TUint aFlags, MAlfScreenBufferObserver* aObserver, TInt aPriority)
+ {
+ // Add to the observer array in Alf Server, and get bitmap handles in return.
+ TAlfScreenBufferBitmaps event = {aBufferId, aPriority, aFlags, NULL, NULL};
+ TPckg<TAlfScreenBufferBitmaps> eventPckg(event);
+ User::LeaveIfError(iData->iEnv->Client().SendSyncCmd(EAlfSBufAddObserver, eventPckg));
+
+ // Append the handler to the client list
+ CAlfScreenBufferEventFetcher* eventFetcher = new (ELeave) CAlfScreenBufferEventFetcher(iData->iEnv->Client(), *aObserver);
+ CAlfScreenBufferEventFetcher::TScreenBufferInfo info = {eventFetcher->ScreenBufferInfo().iObserver, event.iBufferUid, aPriority, event.iBitmapHandle, event.iMaskHandle, TRect(), TRect()};
+ eventFetcher->ScreenBufferInfo() = info;
+ // Transfers ownership of eventFetcher
+ TInt err = iData->iScreenBufferHandlers.InsertInUnsignedKeyOrder(TAlfScreenBufferHandlerItem(aBufferId.iUid, eventFetcher));
+
+ if (err)
+ {
+ delete eventFetcher;
+ RemoveObserver(aBufferId);
+ User::Leave(err);
+ }
+ else
+ {
+ // Start observing any event
+ eventFetcher->RequestBufferEvent();
+ }
+ }
+
+
+// Note: This can be also called to already removed observers. In that case it has no effect.
+EXPORT_C void CAlfScreenBuffer::RemoveObserver(TUid aBufferId)
+ {
+ // Remove from the observer array in Alf Server
+ TAlfScreenBufferBitmaps event = {aBufferId, 0, 0};
+ TPckg<TAlfScreenBufferBitmaps> eventPckg(event);
+ iData->iEnv->Client().SendSyncCmd(EAlfSBufRemoveObserver, eventPckg);
+
+ // Remove the handler from the client list
+ TAlfScreenBufferHandlerItem item( aBufferId.iUid, NULL );
+ TInt index;
+ if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone )
+ {
+ delete(iData->iScreenBufferHandlers[index].iAoPtr);
+ iData->iScreenBufferHandlers.Remove(index);
+ }
+ }
+
+
+EXPORT_C void CAlfScreenBuffer::RequestNextBuffer(TUid aBufferId)
+ {
+ TAlfScreenBufferHandlerItem item( aBufferId.iUid, NULL );
+ TInt index;
+ if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone )
+ {
+ TUid event = aBufferId;
+ TPckg<TUid> eventPckg(event);
+ iData->iEnv->Client().SendSyncCmd(EAlfSBufRequestNextBuffer, eventPckg);
+ }
+ else
+ {
+ // I am not a listener for this buffer
+ __ALFLOGSTRING1( "CAlfScreenBuffer::RequestNextBuffer(). Observer not found for uid %x", aBufferId.iUid );
+ }
+ }
+
+
+EXPORT_C void CAlfScreenBuffer::RequestBufferDraw(TUid aBufferId)
+ {
+ TAlfScreenBufferHandlerItem item( aBufferId.iUid, NULL );
+ TInt index;
+ if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone )
+ {
+ TUid event = aBufferId;
+ TPckg<TUid> eventPckg(event);
+ iData->iEnv->Client().SendSyncCmd(EAlfSBufRequestBufferDraw, eventPckg);
+ }
+ else
+ {
+ // I am not a listener for this buffer
+ __ALFLOGSTRING1( "CAlfScreenBuffer::RequestNextBuffer(). Observer not found for uid %x", aBufferId.iUid );
+ }
+ }
+
+
+
+
+
+
+
+