uiacceltk/hitchcock/Client/src/alfscreenbuffer.cpp
changeset 0 15bf7259bb7c
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Screen buffer implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <coemain.h>
       
    21 
       
    22 #include "alflogger.h"
       
    23 #include "alf/alfenv.h"
       
    24 #include "alfclient.h"
       
    25 #include "alf/alfstatic.h"
       
    26 #include "alf/alfconstants.h"
       
    27 #include "alfuids.h"
       
    28 #include "alf/alfscreenbuffer.h"
       
    29 #include "alf/alfsymbiansbdrawer.h"
       
    30 
       
    31 #include <uiacceltk/HuiUtil.h>
       
    32 
       
    33 // *** class CAlfScreenBufferEventFetcher
       
    34 
       
    35 NONSHARABLE_CLASS(CAlfScreenBufferEventFetcher): public CActive
       
    36     {
       
    37 public: // Struct
       
    38     
       
    39     struct TScreenBufferInfo
       
    40     	{
       
    41     	MAlfScreenBufferObserver* iObserver; // Observer for this screen buffer. Not owned
       
    42     	TUid iBufferUid; // Uid of the buffer to be observed.
       
    43     	TInt iPriority;  // Priority of the buffer. Not yet used.
       
    44     	TInt iBitmapHandle; // Handle to the shared CFbsBitmap that contains the buffer.
       
    45     	TInt iMaskHandle; // Mask handle
       
    46     	TRect iLastDisplayRect; // Display rect
       
    47     	TRect iLastDirtyRect; // Dirty rect  	
       
    48     	};
       
    49 
       
    50     
       
    51 public: // New methods
       
    52 
       
    53     CAlfScreenBufferEventFetcher(RAlfClient& aClient, MAlfScreenBufferObserver& aScreenBufferObs)
       
    54         :CActive(CActive::EPriorityHigh), iClient(aClient), iEventAsDescriptor(iEvent)        
       
    55         {
       
    56         CAlfScreenBufferEventFetcher::TScreenBufferInfo info = {&aScreenBufferObs, KNullUid, 0, 0, 0, TRect(), TRect()};
       
    57         iBufferInfo = info;
       
    58         CActiveScheduler::Add(this);
       
    59         }
       
    60 
       
    61     ~CAlfScreenBufferEventFetcher()
       
    62         {
       
    63         Cancel();
       
    64         }
       
    65 
       
    66 	// Request a new event
       
    67 	void RequestBufferEvent()       
       
    68         {
       
    69         if(!IsActive())
       
    70             {
       
    71             SetActive();
       
    72         	iEvent.iBufferUid = iBufferInfo.iBufferUid;
       
    73         	iEvent.iEventId = 0;
       
    74         	iEvent.iDisplayRect = TRect();
       
    75         	iEvent.iDirtyRect = TRect();
       
    76     		iClient.SendAsyncCmd(EAlfSBufRequestEvent, iEventAsDescriptor, iStatus); 
       
    77             }
       
    78         }
       
    79         
       
    80     // Return buffer info    
       
    81     TScreenBufferInfo& ScreenBufferInfo()
       
    82     	{
       
    83     	return(iBufferInfo);
       
    84     	}
       
    85 
       
    86 private: // From CActive
       
    87     
       
    88     void RunL()
       
    89         {
       
    90         if(iStatus.Int() != KErrNone)
       
    91            	{ 
       
    92            	USER_INVARIANT();            	
       
    93            	}
       
    94           	
       
    95         // Issue a new event request first             
       
    96         TAlfScreenBufferEvent event = iEvent;
       
    97 		RequestBufferEvent();   
       
    98 		
       
    99 		// Handle event
       
   100 		
       
   101 		if (event.iEventId == MAlfScreenBufferObserver::ENone) // Buffer complete event    
       
   102 			{
       
   103         	if (iBufferInfo.iObserver->BufferComplete(event.iBufferUid, event.iDisplayRect, event.iDirtyRect))
       
   104         		{
       
   105         		// Request next  buffer automatically
       
   106    			    TUid uidEvent = event.iBufferUid; 
       
   107     			TPckg<TUid> eventPckg(uidEvent);
       
   108     			iClient.SendSyncCmd(EAlfSBufRequestNextBuffer, eventPckg);
       
   109         		}
       
   110 			}
       
   111 		else     
       
   112 			{
       
   113 			if (event.iEventId == MAlfScreenBufferObserver::ECreated)
       
   114 				{
       
   115 		   		// Add this buffer observer again to the array in Alf Server to get valid bitmap handles in return. 
       
   116     			TAlfScreenBufferBitmaps addObserverEvent = {iBufferInfo.iBufferUid, iBufferInfo.iPriority, NULL, NULL}; 
       
   117     			TPckg<TAlfScreenBufferBitmaps> eventPckg(addObserverEvent);
       
   118     			iClient.SendSyncCmd(EAlfSBufAddObserver, eventPckg);
       
   119     			
       
   120     			// Update bitmap handles
       
   121     			iBufferInfo.iBitmapHandle = addObserverEvent.iBitmapHandle; 
       
   122     			iBufferInfo.iMaskHandle = addObserverEvent.iMaskHandle;			
       
   123 				}
       
   124 			else if (event.iEventId == MAlfScreenBufferObserver::EDeleted)
       
   125 				{
       
   126     			// Invalidate bitmap handles
       
   127     			iBufferInfo.iBitmapHandle = NULL; 
       
   128     			iBufferInfo.iMaskHandle = NULL;							
       
   129 				}
       
   130     			
       
   131         	iBufferInfo.iObserver->HandleScreenBufferEvent(event.iBufferUid, event.iEventId);			
       
   132 			}
       
   133         }
       
   134         
       
   135     void DoCancel()
       
   136         {
       
   137     	// Remove this AO from the observer array in Alf Server
       
   138     	TAlfScreenBufferBitmaps event = {iBufferInfo.iBufferUid, 0, 0}; 
       
   139     	TPckg<TAlfScreenBufferBitmaps> eventPckg(event);
       
   140     	iClient.SendSyncCmd(EAlfSBufRemoveObserver, eventPckg);
       
   141         }
       
   142 
       
   143     TInt RunError(TInt /*aError*/)
       
   144         {
       
   145         // Ignore error
       
   146         return KErrNone;
       
   147         }
       
   148 
       
   149 private: // Data
       
   150 
       
   151     RAlfClient& iClient;
       
   152     TAlfScreenBufferEvent iEvent; // Event data for pending buffer event. 
       
   153     TPckg<TAlfScreenBufferEvent> iEventAsDescriptor;
       
   154     
       
   155     CAlfScreenBufferEventFetcher::TScreenBufferInfo iBufferInfo; // Buffer information
       
   156     };
       
   157 
       
   158 
       
   159 
       
   160 // *** Array item for CAlfScreenBuffer
       
   161 
       
   162 struct TAlfScreenBufferHandlerItem
       
   163 	{
       
   164 	TAlfScreenBufferHandlerItem( TInt aId, CAlfScreenBufferEventFetcher* aAoPtr) 
       
   165 		:iId( aId ), iAoPtr( aAoPtr )
       
   166 		{};
       
   167 	TInt iId; // Buffer uid
       
   168 	CAlfScreenBufferEventFetcher* iAoPtr; // Pointer to the active object that handles buffer events. Owned.
       
   169 	};
       
   170 		
       
   171 
       
   172 // *** Private data for CAlfScreenBuffer
       
   173 
       
   174 NONSHARABLE_CLASS(CAlfScreenBuffer::CPrivateData):public CBase
       
   175     {
       
   176     public:
       
   177     ~CPrivateData()
       
   178         {
       
   179         iScreenBufferHandlers.Close();
       
   180         if (iIsAlfEnvOwned)
       
   181         	{
       
   182         	delete(iEnv);
       
   183         	}
       
   184         }
       
   185         
       
   186     CAlfEnv* iEnv;   
       
   187     TBool iIsAlfEnvOwned; 
       
   188     RArray<TAlfScreenBufferHandlerItem> iScreenBufferHandlers; // List of all buffer observer Active Objects
       
   189     };
       
   190 
       
   191 
       
   192 // *** class CAlfScreenBuffer
       
   193 
       
   194 EXPORT_C CAlfScreenBuffer* CAlfScreenBuffer::NewL()
       
   195 	{
       
   196 	// Create own aAlf env if it does not exist.
       
   197 	TBool isAlfEnvOwned = EFalse; 
       
   198 	CAlfEnv* env = CAlfEnv::Static();
       
   199 	if (!env)
       
   200 		{
       
   201 		isAlfEnvOwned = ETrue;
       
   202 		env = CAlfEnv::NewL();
       
   203 		}
       
   204 	
       
   205 	// Create object	
       
   206     CAlfScreenBuffer* self = new( ELeave ) CAlfScreenBuffer();
       
   207     CleanupStack::PushL( self );        
       
   208     self->ConstructL(env, isAlfEnvOwned);
       
   209     CleanupStack::Pop( self );
       
   210     return self;	
       
   211 	};
       
   212 
       
   213 EXPORT_C CAlfScreenBuffer* CAlfScreenBuffer::NewL(CAlfEnv& aEnv)
       
   214 	{
       
   215     CAlfScreenBuffer* self = new( ELeave ) CAlfScreenBuffer();
       
   216     CleanupStack::PushL( self );        
       
   217     self->ConstructL(&aEnv, EFalse);
       
   218     CleanupStack::Pop( self );
       
   219     return self;	
       
   220 	};
       
   221 
       
   222 
       
   223 CAlfScreenBuffer::CAlfScreenBuffer()
       
   224 	{	
       
   225 	}
       
   226 
       
   227 // @deprecated
       
   228 EXPORT_C CAlfScreenBuffer::CAlfScreenBuffer(CAlfEnv& /*aEnv*/) 
       
   229 	{	
       
   230 	}
       
   231 
       
   232 
       
   233 EXPORT_C CAlfScreenBuffer::~CAlfScreenBuffer()
       
   234 	{
       
   235     for (TInt i = iData->iScreenBufferHandlers.Count()-1; i >= 0 ; i--)
       
   236    		{
       
   237         RemoveObserver(iData->iScreenBufferHandlers[i].iAoPtr->ScreenBufferInfo().iBufferUid);
       
   238         }
       
   239 
       
   240     delete iData;
       
   241 	}
       
   242 
       
   243 // @deprecated
       
   244 EXPORT_C void CAlfScreenBuffer::ConstructL()
       
   245     {
       
   246     // Not used, preserved for BC
       
   247     }
       
   248     
       
   249 void CAlfScreenBuffer::ConstructL(CAlfEnv* aEnv, TBool aIsAlfEnvOwned)
       
   250     {
       
   251     //@todo : should I check that only one instance is created per alf client? 
       
   252     // Create private data
       
   253     iData = new (ELeave) CPrivateData; 
       
   254     iData->iEnv = aEnv;
       
   255     iData->iIsAlfEnvOwned = aIsAlfEnvOwned;
       
   256     }
       
   257 
       
   258 
       
   259 EXPORT_C MAlfBufferDrawer* CAlfScreenBuffer::GetDrawingInterface(TUid aInterfaceUid, TUid aBufferUid)
       
   260 	{
       
   261 	// Symbian IF
       
   262 	if (aInterfaceUid == KAlfSymbianBufferDrawerUid)
       
   263 	    {
       
   264 	    TAlfScreenBufferHandlerItem item( aBufferUid.iUid, NULL );
       
   265 	    TInt index;
       
   266 	    if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone )
       
   267 		    {
       
   268 		    if (iData->iScreenBufferHandlers[index].iAoPtr->ScreenBufferInfo().iBitmapHandle)
       
   269 		    	{
       
   270        	    	CAlfSymbianBufferDrawer* drawer = NULL;
       
   271        	    	TRAPD(err, drawer = CAlfSymbianBufferDrawer::NewL());
       
   272        	    	if (!err)
       
   273        	    		{
       
   274                 	TRAP(err,drawer->SetBufferL(
       
   275                 		iData->iScreenBufferHandlers[index].iAoPtr->ScreenBufferInfo().iBitmapHandle,
       
   276                 		iData->iScreenBufferHandlers[index].iAoPtr->ScreenBufferInfo().iMaskHandle));
       
   277                 	if (err)
       
   278                 		{
       
   279                 		delete drawer;
       
   280                 		return NULL;
       
   281                 		}
       
   282                 	else
       
   283                 		{
       
   284                 		return drawer;
       
   285                 		}	
       
   286             		}   
       
   287 		    	}
       
   288 	        }
       
   289 	    }
       
   290 	return NULL;	            
       
   291 	}
       
   292 	
       
   293 
       
   294 EXPORT_C MAlfBufferGc* CAlfScreenBuffer::GetGraphicsContext(TUid /*aInterfaceUid*/, TUid /*aBufferUid*/)  
       
   295 	{	
       
   296 	return ((MAlfBufferGc*)NULL);
       
   297 	}
       
   298       
       
   299         
       
   300 EXPORT_C void CAlfScreenBuffer::AddObserverL(TUid aBufferId, MAlfScreenBufferObserver* aObserver, TInt aPriority) 
       
   301 	{
       
   302 	AddObserverL(aBufferId, CAlfScreenBuffer::EFlagNone, aObserver, aPriority); 
       
   303 	}
       
   304 
       
   305 	
       
   306 EXPORT_C void CAlfScreenBuffer::AddObserverL(TUid aBufferId, TUint aFlags, MAlfScreenBufferObserver* aObserver, TInt aPriority) 
       
   307 	{    
       
   308     // Add to the observer array in Alf Server, and get bitmap handles in return. 
       
   309     TAlfScreenBufferBitmaps event = {aBufferId, aPriority, aFlags, NULL, NULL}; 
       
   310     TPckg<TAlfScreenBufferBitmaps> eventPckg(event);
       
   311     User::LeaveIfError(iData->iEnv->Client().SendSyncCmd(EAlfSBufAddObserver, eventPckg)); 
       
   312     
       
   313   	// Append the handler to the client list
       
   314    	CAlfScreenBufferEventFetcher* eventFetcher =  new (ELeave) CAlfScreenBufferEventFetcher(iData->iEnv->Client(), *aObserver);
       
   315    	CAlfScreenBufferEventFetcher::TScreenBufferInfo info = {eventFetcher->ScreenBufferInfo().iObserver, event.iBufferUid, aPriority, event.iBitmapHandle, event.iMaskHandle, TRect(), TRect()};
       
   316    	eventFetcher->ScreenBufferInfo() = info;    
       
   317    	// Transfers ownership of eventFetcher
       
   318     TInt err = iData->iScreenBufferHandlers.InsertInUnsignedKeyOrder(TAlfScreenBufferHandlerItem(aBufferId.iUid, eventFetcher)); 
       
   319 
       
   320     if (err)
       
   321     	{
       
   322     	delete eventFetcher;
       
   323     	RemoveObserver(aBufferId); 
       
   324     	User::Leave(err);
       
   325     	}
       
   326     else
       
   327     	{
       
   328     	// Start observing any event 
       
   329     	eventFetcher->RequestBufferEvent(); 
       
   330     	}	
       
   331 	}
       
   332 	
       
   333 	
       
   334 // Note: This can be also called to already removed observers. In that case it has no effect. 
       
   335 EXPORT_C void CAlfScreenBuffer::RemoveObserver(TUid aBufferId) 
       
   336 	{	
       
   337     // Remove from the observer array in Alf Server
       
   338     TAlfScreenBufferBitmaps event = {aBufferId, 0, 0}; 
       
   339     TPckg<TAlfScreenBufferBitmaps> eventPckg(event);
       
   340     iData->iEnv->Client().SendSyncCmd(EAlfSBufRemoveObserver, eventPckg); 
       
   341      
       
   342   	// Remove the handler from the client list
       
   343    	TAlfScreenBufferHandlerItem item( aBufferId.iUid, NULL );
       
   344 	TInt index;
       
   345 	if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone )
       
   346 		{
       
   347 		delete(iData->iScreenBufferHandlers[index].iAoPtr);
       
   348 		iData->iScreenBufferHandlers.Remove(index);
       
   349 		}
       
   350 	}
       
   351 
       
   352 
       
   353 EXPORT_C void CAlfScreenBuffer::RequestNextBuffer(TUid aBufferId)       
       
   354 	{
       
   355    	TAlfScreenBufferHandlerItem item( aBufferId.iUid, NULL );
       
   356 	TInt index;
       
   357 	if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone )
       
   358 		{
       
   359 	    TUid event = aBufferId; 
       
   360     	TPckg<TUid> eventPckg(event);
       
   361     	iData->iEnv->Client().SendSyncCmd(EAlfSBufRequestNextBuffer, eventPckg);
       
   362 		}
       
   363 	else
       
   364 		{
       
   365 		// I am not a listener for this buffer 
       
   366 		__ALFLOGSTRING1( "CAlfScreenBuffer::RequestNextBuffer(). Observer not found for uid %x", aBufferId.iUid );
       
   367 		}
       
   368 	}
       
   369     
       
   370     
       
   371 EXPORT_C void CAlfScreenBuffer::RequestBufferDraw(TUid aBufferId)       
       
   372 	{
       
   373    	TAlfScreenBufferHandlerItem item( aBufferId.iUid, NULL );
       
   374 	TInt index;
       
   375 	if ( iData->iScreenBufferHandlers.FindInSignedKeyOrder( item, index ) == KErrNone )
       
   376 		{
       
   377 	    TUid event = aBufferId; 
       
   378     	TPckg<TUid> eventPckg(event);
       
   379     	iData->iEnv->Client().SendSyncCmd(EAlfSBufRequestBufferDraw, eventPckg);
       
   380 		}
       
   381 	else
       
   382 		{
       
   383 		// I am not a listener for this buffer 
       
   384 		__ALFLOGSTRING1( "CAlfScreenBuffer::RequestNextBuffer(). Observer not found for uid %x", aBufferId.iUid );
       
   385 		}
       
   386 	}
       
   387     
       
   388 
       
   389 
       
   390 
       
   391 
       
   392 
       
   393 
       
   394