Apply Faisal's first patch from Bug 2354
- First resolve some the the bit rot in graphics MCL to get it to compile, then fix some performance issues in OpenWF
// Copyright (c) 1999-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:
// Definition of classes for the class that deals with client communication
//
//
#ifndef __CLIENT_H__
#define __CLIENT_H__
#include <Graphics/WSGRAPHICDRAWERINTERFACE.H>
#include "WSGRAPHICDRAWERARRAY.H"
#include <e32std.h>
#include <e32base.h>
#include "W32STD.H"
#include "w32cmd.h"
#include "WSOBJIX.H"
#include "EVQUEUE.H"
#include "PRIKEY.H"
#include "wstypes.h"
#include <e32hashtab.h> //RHashMap
class CWsWindowBase;
class CWsClientWindow;
class CWsPointerCursor;
class CWsCustomTextCursor;
class CWsSpriteBase;
class DWsScreenDevice;
class CScreen;
class RHandleBase;
class CWsGraphicDrawerObject;
class CWsGraphicDrawer;
class MWsElement;
class TSurfaceConfiguration;
class CWsRedrawMsgWindow;
/** Server-side object for a client session.
@internalComponent
@released
*/
class CWsClient : public CSession2, public MWsClient
{
private:
friend class CWsRedrawMsgWindow;
private:
class TWsCursorArrayItem;
enum{EObjectGranularity=5};
enum{ENoDefaultSystemPointerCursor=-1};
public:
enum{EPanicLeave=1};
public: // from MWsClient
TBool HasCapability(TCapability aCapability) const;
TSecureId SecureId() const;
TVendorId VendorId() const;
public:
CWsClient(RThread aClient);
~CWsClient();
static void InitStaticsL();
static void DeleteStatics();
inline TBool NotClosing() const;
inline CWsObjectIx* ObjectIndex();
inline const RMessage2& ClientMessage() const;
inline const RThread& Client() const;
static inline CWsClient* CurrentClient();
inline TInt ConnectionHandle() const;
inline DWsScreenDevice* PrimaryScreenDevice();
inline const DWsScreenDevice* PrimaryScreenDevice() const;
inline CScreen* Screen();
inline const CScreen* Screen() const;
static CWsPointerCursor* SystemPointerCursor(TInt aIndex);
static inline CWsPointerCursor* DefaultSystemPointerCursor();
static CWsCustomTextCursor* FindCustomTextCursor(TInt aIdentifier);
void SessionPanic(TClientPanic aReason) const;
// Window object access from handle
void HandleToWindow(TInt aHandle, CWsWindowBase** pWin);
void HandleToClientWindow(TInt aHandle, CWsClientWindow** pWin);
// Generic WsObject access from handle
CWsObject* HandleToObj(TInt aHandle, WH_HANDLES aType);
const CWsObject* HandleToObj(TInt aHandle, WH_HANDLES aType) const;
CWsObject* HandleToObjUntyped(TInt aHandle);
const CWsObject* HandleToObjUntyped(TInt aHandle) const;
CWsGraphicDrawerObject* DrawerObject(const CWsGraphicDrawer* aDrawer);
const CWsGraphicDrawerObject* DrawerObject(const CWsGraphicDrawer* aDrawer) const;
// Handle from object
inline TInt ObjectHandle(const CWsObject* aThis) const;
// Queue access
inline CEventQueue* EventQueue();
inline const CEventQueue* EventQueue() const;
inline CRedrawQueue* RedrawQueue();
inline const CRedrawQueue* RedrawQueue() const;
// Execute client command from buffer
void ExecuteCommandL(TInt aOpcode, const TAny* aCmdData);
static const TUint8* EndOfCommandBuffer();
static const TPtrC BufferTPtr(TText* aStart,TInt aLen);
static TBool BufferTPtrGc(TText* aStart,TInt aLen,TPtrC& aPtr);
static const TPtrC8 BufferTPtr8(TUint8* aStart,TInt aLen);
// Remote read data from client
void RemoteRead(TDes16& aDes, TInt aOffset);
void RemoteRead(TDes8& aDes, TInt aOffset);
void RemoteReadL(TDes16& aDes, TInt aOffset);
void RemoteReadL(TDes8& aDes, TInt aOffset);
// Send the reply to the client's request
void SetResponseHandle(RHandleBase* aHandle);
static void ReplyBuf(const TAny* aSource, TInt aLength);
static void ReplyBuf(const TDesC8 &aDes);
static void ReplyBuf(const TDesC16 &aDes);
static void ReplySize(const TSize &aSize);
static void ReplyPoint(const TPoint &aPoint);
static void ReplyRect(const TRect &aRect);
static void ReplyGroupName(HBufC* aName, TInt aMaxLength);
static void SetReply(TInt reply);
void RequestComplete(TRequestStatus*& aStatus, TInt aErr);
// Panic or terminate the client
static void PanicCurrentClient(TClientPanic aPanic);
static TInt ReplyBufSpace() ;
void PPanic(TClientPanic aPanic) const;
void SessionTerminate();
// All events
inline void EventReady(const RMessagePtr2& aEventMsg);
// Pointer events
inline void PurgePointerEvents();
// Key events
inline void PriorityKeyPressed(TInt aHandle, const TKeyData &aKey, TInt aScanCode);
// Notification of misc events
void AddNotificationL(TInt aKey, const RMessage2& aClientMsg);
void CompleteNotification(TInt aKey, TInt aReason);
inline void NotifyScreenDeviceDeleted(DWsScreenDevice* aDeletedScreenDevice);
// Redraw
void TriggerRedraw();
// Misc
void UpdateWindowOrdinalPrioritys();
void SetClientPriority(); // boost when in foreground
void CreateDrawableSourceL(const TWsClCmdCreateDrawableSource& aDrawableSourceData);
//retry putting events on event queue
void SetRetryFlag(TEventCode aEventCode);
void RemoveRetryFlag(TEventCode aEventCode);
TBool RetryEvent(TEventCode aEventCode);
inline void WgMsgQueueOverflow();// Set flag window group message queue is overflow and has pending messages
private: // from MWsClient
TInt SendMessage(const CWsGraphicDrawer* aOnBehalfOf, const TDesC8& aData);
TInt SendMessage(const CWsGraphicDrawer* aOnBehalfOf, CWsMessageData& aData);
private: // from CSession2
void ServiceL(const RMessage2 &aMessage);
void ServiceError(const RMessage2& aMessage,TInt aError);
private:
// Construction and destruction
inline TBool IsInitialised();
void StartInitializationL(TUint aConnectionHandle);
void CompleteInitializationL();
void InitialiseScreenDevices();
// Service client commands by dispatching them to the object associated with the op code
void DoServiceL(const RMessage2& aMessage, TBool& aCompleteRequest);
void DoServiceCommandBuf();
static TInt DoContinueDeferredServiceOfCommandBuf(TAny* aClient);
void DispatchCommandsInBufL();
void CompleteMessage(const RMessage2& aMessage,TInt aReason);
// Execute async client commands
void ExecuteAsyncClientCommandL(TInt aOpcode, const RMessage2& aMessage);
static inline TBool CheckBuffer(TInt aLength, TInt aMaxLength);
static TBool DebugEnforceRedrawCallingConvention();
// Create new objects
void CreateNewWindowGroupL(const TWsClCmdCreateWindowGroup &aCmd);
void CreateNewWindowL(const TWsClCmdCreateWindow &aCmd);
void CreateNewAnimDllL(const TWsClCmdUnion &aParams);
void CreateNewSpriteL(const TWsClCmdCreateSprite &aCmd);
void CreateNewPointerCursorL(const TWsClCmdCreatePointerCursor &aCmd);
void CreateNewBitmapL(const TWsClCmdCreateBitmap &aCmd);
void CreateNewClickHandlerL(const TUid& aUid);
void CreateNewScreenDeviceL( TInt aDefaultScreenNumber, TUint aClientScreenDevicePointer);
// Surface management
TInt RegisterSurface(const TWsClCmdUnion& pData);
void UnregisterSurface(const TWsClCmdUnion& pData);
// Text cursor
static inline CWsCustomTextCursor*& TextCursor (TInt aPosition);
void StartSetCustomTextCursorL(const TWsClCmdCustomTextCursorData& aCmd);
void CompleteSetCustomTextCursorL(TInt aErr);
// Pointer cursor
static inline CWsPointerCursor*& PointerCursor (TInt aPosition);
void SetSystemPointerCursorL(TInt aIndex, CWsPointerCursor* aCursor);
void ClearSystemPointerCursor(TInt aIndex);
void ClaimSystemPointerCursorListL();
void FreeSystemPointerCursorList();
void SetDefaultSystemPointerCursor(TInt aIndex);
static void DeleteSystemPointerListEntry(TInt aIndex);
static TBool FindCursorArrayItem(CArrayFixFlat<TWsCursorArrayItem>* aCursorArray,
TInt aIndex, TInt& aPosition);
// Key events
inline void CancelClientRequestForPriorityKeyEvent();
inline void HandleClientRequestForPriorityKeyData();
inline void PriorityKeyEventReady(const RMessagePtr2& aEventMsg);
// Redraw events
inline void CancelClientRequestForRedrawEvent();
inline void HandleClientRequestForRedrawData();
inline void RedrawEventReady(const RMessagePtr2& aEventMsg);
inline TBool ClientProcessingRedrawEvent();
// Client event requests
inline void HandleClientRequestForEventData();
inline void CancelClientRequestForEventData();
// Debugging
void DebugInfoL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const;
void DebugInfoUnclassifiedL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const;
TInt DebugInfoClassifiedL(TInt aFunction, TInt aParam, TBool aHasReplyBuf) const;
TInt DebugInfoScreenUiL(TInt aFunction, TInt aParam, TInt aReplyBufSize, CScreen& aScreen) const;
TInt DebugInfoScreenElementSetL(TInt aFunction, TInt aParam, TInt aReplyBufSize,const CScreen& aScreen) const;
TInt DebugInfoElementSetWindowL(TInt aFunction, TInt aParam, TInt aReplyBufSize,const CScreen& aScreen) const;
TInt DebugInfoElementSetElementL(TInt aFunction, TInt aParam, TInt aReplyBufSize,const CScreen& aScreen) const;
TInt DebugReturnConfig(TInt aReplyBufSize, MWsElement* aElement, TInt aFlags=0)const;
TInt DebugReturnBase(TInt aReplyBufSize, const MWsElement* aElement) const;
TInt DebugReturnFlags(TInt aReplyBufSize, const MWsElement* aElement, TInt aFlags=0) const;
TInt DebugReturnRegion(TInt aReplyBufSize, const TRegion* aRegion, TInt aErrCodeIfEmpty) const;
// Misc
void SetComputeMode(RWsSession::TComputeMode aComputeMode);
public:
static TWsCmdHeaderBase iCurrentCommand;
private:
class TWsCursorArrayItem
{
public:
CWsSpriteBase* iCursor;
TInt iIndex;
};
enum TInternalFlags
{
EIsInitialised = 0x01,
EPanicClientAsSoonAsPossible = 0x02, //The client should be panicked, but we have no way to panic him now
EClientIsClosing = 0x04, //The client is closing down, so the screen device may no longer be valid
EFinishedProcessingCommands=0x08, //Reached last command in command buffer or otherwised finihsed processing it
ERemoveKeyCode=0x10, //Remove the Win32 keycode emulator only
ERetryDisplayEvent=0x20,
EIsPerformingRedrawEvent=0x40, //The client is performing a RedrawEvent
EWgMsgQueueOverflow =0x80,
};
private:
RThread iClient;
CScreen* iScreen; //## This needs updating
TUint iConnectionHandle; // Connection ID, only needed for logging, could bin this
CEventQueue* iEventQueue;
CRedrawQueue* iRedrawQueue;
CPriorityKey* iPriorityKeyEvent;
CWsGraphicMessageQueue iGraphicMessageQueue;
RWsSession::TComputeMode iComputeMode;
CWsObjectIx* iObjectIndex;
DWsScreenDevice* iPrimaryScreenDevice;
TWsCursorArrayItem iTempCustomTextCursor;
mutable TInt iPanicReason;
mutable TUint iInternalFlags;
RMessage2 iClientMessage;
RHandleBase* iResponseHandle;
TInt iMessageIdSeq;
//Members for procerssing command buffer
static CWsClient* iCurrentClient; // Client who's buffer is currently being processed
static TInt iReply; // Value to reply
static TInt iReplyOffset; // Offset into reply to write next block of data
static TBuf8<EClientBufferMaxSize> iCmdBuf; // Buffer contain a block of client commands
static CWsObject* iDestObj; // Current object client command is for
static const TUint8* iNextCmd; // Pointer in buffer to the next command to be processed
static CIdle* iMoreCommands; // Active object responsible for executing more client commands
static TInt iDefaultSystemPointerCursorIndex; // Negative when there isn't one
static CWsPointerCursor* iDefaultSystemPointerCursor;
static CArrayFixFlat<TWsCursorArrayItem>* iSystemPointerCursors;
static CWsClient* iSystemPointerCursorListOwner;
static CArrayFixFlat<TWsCursorArrayItem>* iTextCursorArray;
static TUint iConnectionId;
static TKeyArrayFix iCursorKey;
static TBool iDebug_EnforceRedrawCallingConvention;
#if defined(__WINS__)
public:
inline TBool RemoveKeyCode();
#endif
};
//
// inlines //
//
inline const RThread& CWsClient::Client() const
{return iClient;}
inline void CWsClient::EventReady(const RMessagePtr2& aEventMsg)
{iEventQueue->EventReady(aEventMsg);}
inline void CWsClient::HandleClientRequestForEventData()
{iEventQueue->GetData();}
inline void CWsClient::CancelClientRequestForEventData()
{iEventQueue->CancelRead();}
inline void CWsClient::PurgePointerEvents()
{iEventQueue->PurgePointerEvents();}
inline void CWsClient::RedrawEventReady(const RMessagePtr2& aEventMsg)
{
iInternalFlags&=~EIsPerformingRedrawEvent;
iRedrawQueue->EventReady(aEventMsg);
}
inline TBool CWsClient::ClientProcessingRedrawEvent()
{return !!(iInternalFlags&EIsPerformingRedrawEvent);}
inline void CWsClient::HandleClientRequestForRedrawData()
{
iInternalFlags|=EIsPerformingRedrawEvent;
iRedrawQueue->GetData();
}
inline void CWsClient::CancelClientRequestForRedrawEvent()
{iRedrawQueue->CancelRead();}
inline void CWsClient::PriorityKeyEventReady(const RMessagePtr2& aEventMsg)
{iPriorityKeyEvent->EventReady(aEventMsg);}
inline void CWsClient::CancelClientRequestForPriorityKeyEvent()
{iPriorityKeyEvent->CancelRead();}
inline void CWsClient::HandleClientRequestForPriorityKeyData()
{iPriorityKeyEvent->GetData();}
inline void CWsClient::PriorityKeyPressed(TInt aHandle, const TKeyData &aKey, TInt aScanCode)
{iPriorityKeyEvent->PriorityKey(aHandle,aKey,aScanCode);}
inline TInt CWsClient::ObjectHandle(const CWsObject* aThis) const
{return(iObjectIndex->At(aThis));}
#if defined(__WINS__)
inline TBool CWsClient::RemoveKeyCode()
{return iInternalFlags&ERemoveKeyCode;}
#endif
inline CEventQueue* CWsClient::EventQueue()
{return(iEventQueue);}
inline const CEventQueue* CWsClient::EventQueue() const
{return(iEventQueue);}
inline CRedrawQueue* CWsClient::RedrawQueue()
{return(iRedrawQueue);}
inline const CRedrawQueue* CWsClient::RedrawQueue() const
{return(iRedrawQueue);}
inline CWsObjectIx* CWsClient::ObjectIndex()
{return(iObjectIndex);}
inline TInt CWsClient::ConnectionHandle() const
{return(iConnectionHandle);}
inline DWsScreenDevice* CWsClient::PrimaryScreenDevice()
{return(iPrimaryScreenDevice);}
inline const DWsScreenDevice* CWsClient::PrimaryScreenDevice() const
{return(iPrimaryScreenDevice);}
inline void CWsClient::NotifyScreenDeviceDeleted(DWsScreenDevice* aDeletedScreenDevice)
{
if (iPrimaryScreenDevice == aDeletedScreenDevice)
iPrimaryScreenDevice = NULL;
}
inline CWsPointerCursor*& CWsClient::PointerCursor(TInt aIndex)
{return (CWsPointerCursor*&)(*iSystemPointerCursors)[aIndex].iCursor;}
inline CWsCustomTextCursor*& CWsClient::TextCursor(TInt aIndex)
{return (CWsCustomTextCursor*&)(*iTextCursorArray)[aIndex].iCursor;}
inline const RMessage2& CWsClient::ClientMessage() const
{return iClientMessage;}
inline CScreen* CWsClient::Screen()
{return iScreen;}
inline const CScreen* CWsClient::Screen() const
{return iScreen;}
inline TBool CWsClient::NotClosing() const
{return !(iInternalFlags&EClientIsClosing);}
inline CWsClient* CWsClient::CurrentClient()
{return iCurrentClient;}
inline TBool CWsClient::CheckBuffer(TInt aLength, TInt aMaxLength)
{return TBool((aLength>=0) && (aLength<=aMaxLength));}
inline TBool CWsClient::IsInitialised()
{return iInternalFlags&EIsInitialised; }
inline void CWsClient::WgMsgQueueOverflow()
{iInternalFlags |= EWgMsgQueueOverflow;}
#endif