--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/windowing/windowserver/nga/SERVER/EVENT.CPP Tue Feb 02 01:47:50 2010 +0200
@@ -0,0 +1,1741 @@
+// Copyright (c) 1994-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:
+// Top level window server code
+//
+//
+
+#include "EVENT.H"
+
+#include "W32STD.H"
+#include <hal.h>
+#include <w32adll.h>
+#include "W32CLICK.H"
+#include "server.h"
+#include "windowgroup.h"
+#include "KEYCLICK.H"
+#include "wstop.h"
+#include "panics.h"
+#include "screen.h"
+#include "inifile.h"
+#include "password.h"
+#include "pointer.h"
+#include "debugbar.h"
+#include "advancedpointereventhelper.h"
+
+GLREF_D CDebugLogBase *wsDebugLog;
+
+GLREF_C void StateDump();
+GLREF_C void HeapDump();
+
+#define IMPOSSIBLE 0xFFFFFFFF
+
+const TWsWinCmdCaptureKey ImpossibleKeyPress=
+ {
+ IMPOSSIBLE, // Impossible to hit key combination, used for disabling Hot Keys
+ IMPOSSIBLE,
+ IMPOSSIBLE};
+
+const TWsWinCmdCaptureKey DefaultHotKeys[TWindowServerEvent::ENumHotKeys]={
+ { // Enable logging
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ 5}, // E
+ { // Disable logging
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ 4}, // D
+ { // Window server internal dump to log
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ 23},// W
+ { // The key of death
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ 11},// K
+ { // Shutdown window server
+#if defined(_DEBUG)
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ 24},// X
+#else
+ IMPOSSIBLE, // Impossible to hit key combination, effectively disables shutdown key in release builds
+ IMPOSSIBLE,
+ IMPOSSIBLE},
+#endif
+ { // Heap dump
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ 8}, // H
+ { // Inc Contrast
+ 0,
+ 0,
+ EKeyIncContrast},
+ { // Dec Contrast
+ 0,
+ 0,
+ EKeyDecContrast},
+ { // Off
+ 0,
+ 0,
+ EKeyOff},
+ { // Backlight on
+ 0,
+ 0,
+ EKeyBacklightOn},
+ { // Backlight off
+ 0,
+ 0,
+ EKeyBacklightOff},
+ { // Backlight toggle
+ 0,
+ 0,
+ EKeyBacklightToggle},
+ { // Screen Dimension Change
+ 0,
+ 0,
+ EKeyScreenDimension0},
+ {
+ 0,
+ 0,
+ EKeyScreenDimension1},
+ {
+ 0,
+ 0,
+ EKeyScreenDimension2},
+ {
+ 0,
+ 0,
+ EKeyScreenDimension3},
+#if defined(_DEBUG)
+ { // Display mode cycle
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ 21},// U
+ { // Orientation cycle
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ 15},// O
+#else
+ { // Display mode cycle
+ IMPOSSIBLE, // Impossible to hit key combination
+ IMPOSSIBLE,
+ IMPOSSIBLE},
+ { // Orientation cycle
+ IMPOSSIBLE, // Impossible to hit key combination
+ IMPOSSIBLE,
+ IMPOSSIBLE},
+#endif
+ { // Inc Brightness
+ 0,
+ 0,
+ EKeyIncBrightness},
+ { // Dec Brightness
+ 0,
+ 0,
+ EKeyDecBrightness},
+ { // Cycle focus screen
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ EModifierFunc|EModifierCtrl|EModifierShift,
+ 9}, // I
+ };
+
+CKeyTranslator *TWindowServerEvent::iKeyTranslator=NULL;
+TEventRequestQueue TWindowServerEvent::iSwitchOnQueue;
+TEventRequestQueue TWindowServerEvent::iErrorMessageQueue;
+TEventRequestQueue TWindowServerEvent::iModifierChangedQueue;
+TEventRequestQueue TWindowServerEvent::iGroupChangedQueue;
+TEventRequestQueue TWindowServerEvent::iFocusChangedQueue;
+TEventRequestQueue TWindowServerEvent::iGroupListChangedQueue;
+TEventRequestQueue TWindowServerEvent::iScreenDeviceChangedQueue;
+TTime TWindowServerEvent::iPrevOomMessageTime;
+CCaptureKeys *TWindowServerEvent::iCaptureKeys;
+CWsHotKey *TWindowServerEvent::iHotKeys;
+TInt TWindowServerEvent::iModifierState;
+CRawEventReceiver *TWindowServerEvent::iEventReceiver;
+RArray<TWindowServerEvent::TRawEventHandler> TWindowServerEvent::iEventHandlers;
+CArrayFixFlat<SNotificationHandler> *TWindowServerEvent::iNotificationHandlers;
+TInt TWindowServerEvent::iPotentialEventHandlers=0;
+TUint32 TWindowServerEvent::iBinaryFlags=0x00;
+RArray<TDrawerHandler>* TWindowServerEvent::iDrawerHandlers;
+RArray<TWsEventHandler> TWindowServerEvent::iWsEventHandlers;
+TInt TWindowServerEvent::iEventHandlerCount=0;
+TRepeatKey CKeyboardRepeat::iCurrentRepeat;
+TRepeatKey CKeyboardRepeat::iAlternateRepeat;
+TInt CKeyboardRepeat::iRepeatRollover=1;
+CKeyboardRepeat::TRepeatType CKeyboardRepeat::iRepeating=ERepeatNone;
+CKeyboardRepeat *CKeyboardRepeat::iThis=NULL;
+TTimeIntervalMicroSeconds32 CKeyboardRepeat::iInitialTime;
+TTimeIntervalMicroSeconds32 CKeyboardRepeat::iTime;
+CWsWindowGroup *CKeyboardRepeat::iFocus=NULL;
+TBool CKeyboardRepeat::iAlternateRepeatExists=EFalse;
+CWsCaptureLongKey* CKeyboardRepeat::iLongCapture=NULL;
+
+
+void TWindowServerEvent::DeleteHotKeys()
+ {
+ CWsHotKey *hotKey=iHotKeys;
+ while(hotKey)
+ {
+ CWsHotKey *next=hotKey->iNext;
+ delete hotKey;
+ hotKey=next;
+ }
+ iHotKeys=NULL;
+ }
+
+void TWindowServerEvent::DeleteStatics()
+ {
+ DeleteHotKeys();
+ delete iCaptureKeys;
+ CKeyboardRepeat::Destroy();
+ delete iKeyTranslator;
+ delete iEventReceiver;
+ iEventHandlers.Close();
+ delete iNotificationHandlers;
+ iDrawerHandlers->Close();
+ delete iDrawerHandlers;
+ iWsEventHandlers.Close();
+ }
+
+void TWindowServerEvent::InitStaticsL()
+//
+// Create the CEvent active object.
+//
+ {
+#if defined(__WINS__)
+ WS_ASSERT_DEBUG(TWindowServerEvent::ENumHotKeys==EHotKeyLastKeyType+1, EWsPanicUnknownCaptureKey);
+#endif
+ iEventReceiver=new(ELeave) CRawEventReceiver(EEventPriority);
+ iEventReceiver->ConstructL();
+ iKeyTranslator=CKeyTranslator::New();
+ User::LeaveIfNull(iKeyTranslator);
+
+// Change keyboard mapping according to information the HAL
+ TInt keyboardIndex;
+ if (HAL::Get(HALData::EKeyboardIndex,keyboardIndex)==KErrNone)
+ {
+ _LIT(KLitKeyDataDllName,"EKDATA.%02d");
+ TBuf<16> keyDataDllName;
+ keyDataDllName.Format(KLitKeyDataDllName,keyboardIndex);
+ iKeyTranslator->ChangeKeyData(keyDataDllName);
+ }
+
+ iCaptureKeys=new(ELeave) CCaptureKeys;
+ iCaptureKeys->Construct();
+ for (TInt index=0;index<TWindowServerEvent::ENumHotKeys;index++)
+ ConstructDefaultHotKeyL(index,DefaultHotKeys[index]);
+ CKeyboardRepeat::NewL();
+ CKeyboardRepeat::SetRepeatTime(EDefaultInitialRepeatTime, EDefaultRepeatTime);
+ iEventHandlers=RArray<TRawEventHandler>(2);
+ iNotificationHandlers=new(ELeave) CArrayFixFlat<SNotificationHandler>(2);
+ iDrawerHandlers = new(ELeave) RArray<TDrawerHandler>(4);
+ }
+
+void TWindowServerEvent::LinkHotKey(CWsHotKey *aWsHotKey)
+ {
+ aWsHotKey->SetLink(iHotKeys);
+ iHotKeys=aWsHotKey;
+ }
+
+void TWindowServerEvent::ConstructDefaultHotKeyL(TInt aHotKey, const TWsWinCmdCaptureKey &aSystemKey)
+ {
+ CWsHotKey* hotKey=new(ELeave) CWsHotKey(aHotKey, ETrue);
+ // hotKey is pushed onto the cleanup stack in method ConstructLD.
+ hotKey->ConstructLD(aSystemKey);
+ LinkHotKey(hotKey);
+ }
+
+CWsHotKey* TWindowServerEvent::ClearHotKeysL(TInt aHotKey)
+ {
+ if (aHotKey>ENumHotKeys)
+ {
+ User::Leave(KErrArgument);
+ }
+ CWsHotKey** pHotKey= &iHotKeys;
+ CWsHotKey* defaultHotKey=NULL;
+ while(*pHotKey)
+ {
+ TBool unlinked=EFalse;
+ if ((*pHotKey)->HotKeyType()==aHotKey)
+ {
+ CWsHotKey *free=*pHotKey;
+ if (free->IsDefault())
+ {
+ free->SetL(ImpossibleKeyPress);
+ defaultHotKey=free;
+ }
+ else
+ {
+ *pHotKey=(*pHotKey)->iNext;
+ delete free;
+ unlinked=ETrue;
+ }
+ }
+ if (!unlinked)
+ {
+ pHotKey=&(*pHotKey)->iNext;
+ }
+ }
+ return(defaultHotKey);
+ }
+
+void TWindowServerEvent::ResetDefaultHotKeyL(TInt aHotKey)
+ {
+ if ((aHotKey<0) || (aHotKey>=ENumHotKeys))
+ {
+ User::Leave(KErrArgument);
+ }
+ CWsHotKey* defaultHotKey=ClearHotKeysL(aHotKey);
+ WS_ASSERT_DEBUG(defaultHotKey, EWsPanicDefaultHotKeyNotFound);
+ defaultHotKey->SetL(DefaultHotKeys[aHotKey]);
+ }
+
+void TWindowServerEvent::SetHotKeyL(const TWsClCmdSetHotKey &aHotKey)
+ {
+ if (aHotKey.type>ENumHotKeys)
+ User::Leave(KErrArgument);
+//
+ CWsHotKey *hotKey=new(ELeave) CWsHotKey(aHotKey.type, EFalse);
+//
+ TWsWinCmdCaptureKey captureKey;
+ captureKey.modifiers=aHotKey.modifiers;
+ captureKey.modifierMask=aHotKey.modifierMask;
+ captureKey.key=aHotKey.keycode;
+ hotKey->ConstructLD(captureKey);
+//
+ LinkHotKey(hotKey);
+ }
+
+void TWindowServerEvent::AddEventHandler(MEventHandler *aEventHandler, TBool aAdvancedPointersEnabled)
+ {
+#if defined(_DEBUG)
+ TRAPD(err,iEventHandlers.AppendL(TRawEventHandler(aEventHandler, aAdvancedPointersEnabled)));
+ WS_ASSERT_DEBUG(err==KErrNone, EWsPanicEventHandlerInconsistency);
+#else
+ iEventHandlers.AppendL(TRawEventHandler(aEventHandler, aAdvancedPointersEnabled)); //Shouldn't leave
+#endif
+ }
+
+void TWindowServerEvent::RemoveEventHandler(const MEventHandler *aEventHandler)
+ {
+ TInt count=iEventHandlers.Count();
+ TInt ii;
+ for(ii=0;ii<count;++ii)
+ {
+ if (iEventHandlers[ii].iEventHandler==aEventHandler)
+ {
+ if (iEventHandlerCount>0)
+ {
+ iBinaryFlags |= ERemovedEventHandlerWhileProcessingRawEvents;
+ iEventHandlers[ii].iEventHandler=NULL; // replace the Handler with null to keep size of the array
+ }
+ else
+ {
+ iEventHandlers.Remove(ii);
+ }
+ return;
+ }
+ }
+ }
+
+void TWindowServerEvent::PotentialEventHandlerL(TInt aNum)
+ {
+ iPotentialEventHandlers+=aNum;
+ WS_ASSERT_DEBUG(iPotentialEventHandlers>=iEventHandlers.Count(), EWsPanicEventHandlerInconsistency);
+ TRAPD(err,iEventHandlers.Reserve(iPotentialEventHandlers));
+ if (err!=KErrNone)
+ {
+ if (aNum>0)
+ User::Leave(err);
+ }
+ else if (iPotentialEventHandlers==0)
+ iEventHandlers.Compress();
+ }
+
+void SendSwitchOnEvent(TEventRequestItem *aQptr, TInt aEvent, TInt )
+ {
+ aQptr->iWindow->QueueEvent(aEvent);
+ }
+
+/*void SendSwitchOffEvent(TEventRequestItem *aQptr, TInt , TInt )
+ {
+ aQptr->iWindow->QueueEvent(EEventSwitchOff);
+ }*/
+
+void SendErrorMessage(TEventRequestItem *aQptr, TInt aCategory, TInt aError)
+ {
+ TWsEvent event;
+ event.SetType(EEventErrorMessage);
+ event.SetHandle(aQptr->iWindow->ClientHandle());
+ event.ErrorMessage()->iErrorCategory=(TWsErrorMessage::TErrorCategory)aCategory;
+ event.ErrorMessage()->iError=aError;
+ event.SetTimeNow();
+ aQptr->iWindow->EventQueue()->QueueEvent(event,EEventPriorityHigh);
+ }
+
+void SendModifierChangedEvent(TEventRequestItem *aQptr, TInt aChanged, TInt )
+ {
+ TInt tmpChanged=aChanged&aQptr->iParam;
+ if (tmpChanged)
+ {
+ TWsEvent event;
+ event.SetType(EEventModifiersChanged);
+ event.SetHandle(aQptr->iWindow->ClientHandle());
+ event.ModifiersChanged()->iChangedModifiers=tmpChanged;
+ event.ModifiersChanged()->iModifiers=TWindowServerEvent::GetStoredModifierState();
+ event.SetTimeNow();
+ aQptr->iWindow->EventQueue()->QueueEvent(event,EEventPriorityHigh);
+ }
+ }
+
+void TWindowServerEvent::ProcessEventQueue(TEventRequestQueue &aQueue, TSendEventFunc aFunc, TInt aParam1, TInt aParam2)
+ {
+ TSglQueIter<TEventRequestItem> iter(aQueue.Queue());
+ TEventRequestItem *qPtr;
+ CWsWindowGroup *focusWin=CWsTop::FocusWindowGroup();
+ while((qPtr=iter++)!=NULL)
+ {
+ if (qPtr->iCircumstances==EEventControlAlways ||
+ (qPtr->iCircumstances==EEventControlOnlyWithKeyboardFocus && qPtr->iWindow->WinGroup()==focusWin) ||
+ (qPtr->iCircumstances==EEventControlOnlyWhenVisible && !qPtr->iWindow->TreeIsObscured()))
+ aFunc(qPtr, aParam1, aParam2);
+ }
+ }
+
+void TWindowServerEvent::NotifyOom()
+ {
+ TTime now;
+ now.UniversalTime();
+ TTimeIntervalSeconds interval;
+ TInt err=now.SecondsFrom(iPrevOomMessageTime,interval);
+ if (err!=KErrNone || interval.Int()<0 || interval.Int()>EOomEventSecondGap)
+ {
+ ProcessErrorMessages(TWsErrorMessage::EDrawingRegion,KErrNoMemory);
+ iPrevOomMessageTime=now;
+ }
+ }
+
+TBool TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::TErrorCategory aCategory, TInt aError)
+ {
+ if (aError!=KErrNone)
+ {
+ ProcessEventQueue(iErrorMessageQueue, SendErrorMessage, aCategory, aError);
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+void TWindowServerEvent::ProcessModifierChanges()
+ {
+ TInt newState=iKeyTranslator->GetModifierState();
+ if (newState!=iModifierState)
+ {
+ TInt changed=iModifierState^newState;
+ iModifierState=newState;
+ ProcessEventQueue(iModifierChangedQueue, SendModifierChangedEvent, changed, 0);
+ }
+ }
+
+TEventQueueWalkRet FindScreenDeviceChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent)
+ {
+ if (aEvent->Type()==EEventScreenDeviceChanged && aEvent->Handle()==*(TUint *)aHandlePtr)
+ *(TUint *)aHandlePtr=0; // Indicates event found
+ return(EEventQueueWalkOk);
+ }
+
+void TWindowServerEvent::SendScreenDeviceChangedEvents(CScreen* aScreen)
+ {
+ TSglQueIter<TEventRequestItem> iter(iScreenDeviceChangedQueue .Queue());
+ TEventRequestItem *qPtr;
+ while((qPtr=iter++)!=NULL)
+ SendScreenDeviceChangedEvent(qPtr->iWindow);
+ if(CClick::IsHandler())
+ {
+ TClickMakerData clickMakerData;
+ clickMakerData.screenDeviceMode=aScreen->ScreenSizeMode();
+ CClick::OtherEvent(EEventScreenDeviceChanged, &clickMakerData);
+ }
+ TWsEvent wsEvent;
+ wsEvent.SetType(EEventScreenDeviceChanged);
+ TWindowServerEvent::PublishNotification(wsEvent);
+ TWservCrEvent crEvent(TWservCrEvent::EScreenSizeModeChanged,aScreen->ScreenSizeMode());
+ TWindowServerEvent::NotifyDrawer(crEvent);
+ }
+
+void TWindowServerEvent::SendScreenDeviceChangedEvent(const CWsWindowBase *aWindow)
+ {
+ CEventQueue *queue=aWindow->EventQueue();
+ TUint32 handle=aWindow->ClientHandle();
+ queue->WalkEventQueue(&FindScreenDeviceChangedEvent,&handle);
+ if (handle!=NULL) // Indicates event not found
+ queue->QueueEvent(handle, EEventScreenDeviceChanged);
+ }
+
+TEventQueueWalkRet FindGroupChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent)
+ {
+ if (aEvent->Type()==EEventWindowGroupsChanged && aEvent->Handle()==*(TUint *)aHandlePtr)
+ {
+ *(TUint *)aHandlePtr=0; // Indicates event found
+ }
+ return(EEventQueueWalkOk);
+ }
+
+void TWindowServerEvent::SendGroupChangedEvents()
+ {
+ TSglQueIter<TEventRequestItem> iter(iGroupChangedQueue.Queue());
+ TEventRequestItem *qPtr;
+ while((qPtr=iter++)!=NULL)
+ {
+ const CWsWindowBase *win=qPtr->iWindow;
+ CEventQueue *queue=win->EventQueue();
+ TUint32 handle=win->ClientHandle();
+ queue->WalkEventQueue(&FindGroupChangedEvent,&handle);
+ if (handle!=NULL) // Indicates event not found
+ {
+ queue->QueueEvent(handle, EEventWindowGroupsChanged);
+ }
+ }
+ }
+
+TEventQueueWalkRet FindFocusChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent)
+ {
+ if (aEvent->Type()==EEventFocusGroupChanged && aEvent->Handle()==*(TUint *)aHandlePtr)
+ {
+ *(TUint *)aHandlePtr=0; // Indicates event found
+ }
+ return(EEventQueueWalkOk);
+ }
+
+void TWindowServerEvent::SendFocusChangedEvents()
+ {
+ TInt identifier=0; // Zero Identifier indicates, currently there is no focused window group
+ CScreen* currentFocusScreen=CWsTop::CurrentFocusScreen();
+ TInt screenNumber=currentFocusScreen->ScreenNumber();
+ CWsWindowGroup* currentFocusWG=currentFocusScreen->FocusWindowGroup();
+ if(currentFocusWG)
+ {
+ identifier=currentFocusWG->Identifier();
+ }
+ TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EWindowGroupChanged,
+ screenNumber, reinterpret_cast<TAny*>(identifier)));
+
+ TSglQueIter<TEventRequestItem> iter(iFocusChangedQueue.Queue());
+ TEventRequestItem *qPtr;
+ while((qPtr=iter++)!=NULL)
+ {
+ const CWsWindowBase *win=qPtr->iWindow;
+ CEventQueue *queue=win->EventQueue();
+ TUint32 handle=win->ClientHandle();
+ queue->WalkEventQueue(&FindFocusChangedEvent,&handle);
+ if (handle!=NULL) // Indicates event not found
+ {
+ queue->QueueEvent(handle, EEventFocusGroupChanged);
+ }
+ }
+ }
+
+TEventQueueWalkRet FindGroupListChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent)
+ {
+ if (aEvent->Type()==EEventWindowGroupListChanged && aEvent->Handle()==*(TUint *)aHandlePtr)
+ {
+ *(TUint *)aHandlePtr=0; // Indicates event found
+ }
+ return(EEventQueueWalkOk);
+ }
+
+void TWindowServerEvent::SendGroupListChangedEvents()
+ {
+ TSglQueIter<TEventRequestItem> iter(iGroupListChangedQueue.Queue());
+ TEventRequestItem *qPtr;
+ while((qPtr=iter++)!=NULL)
+ {
+ const CWsWindowBase *win=qPtr->iWindow;
+ CEventQueue *queue=win->EventQueue();
+ TUint32 handle=win->ClientHandle();
+ queue->WalkEventQueue(&FindGroupListChangedEvent,&handle);
+ if (handle!=NULL) // Indicates event not found
+ {
+ queue->QueueEvent(handle, EEventWindowGroupListChanged);
+ }
+ }
+ }
+
+TEventQueueWalkRet OverrideVisibilityChangedEvent(TAny *aNewEvent, TWsEvent *aOldEvent)
+ {
+ // This replaces the first visibility event it finds for the given window with the
+ // one given. This is fine, so long as the meaning of all visibility events remains
+ // independent of the ones before.
+ TWsEvent* newEvent = static_cast<TWsEvent*>(aNewEvent);
+ if (aOldEvent->Type()==EEventWindowVisibilityChanged && aOldEvent->Handle()==newEvent->Handle())
+ {
+ aOldEvent->SetTimeNow();
+ aOldEvent->VisibilityChanged()->iFlags = newEvent->VisibilityChanged()->iFlags;
+ newEvent->SetHandle(NULL);
+ }
+ return EEventQueueWalkOk;
+ }
+
+void TWindowServerEvent::SendVisibilityChangedEvents(CWsWindowBase* aWin, TUint aFlags)
+ {
+ CEventQueue *queue=aWin->EventQueue();
+ TWsEvent event;
+ event.SetType(EEventWindowVisibilityChanged);
+ event.SetHandle(aWin->ClientHandle());
+ event.SetTimeNow();
+ TWsVisibilityChangedEvent* visevent = event.VisibilityChanged();
+ visevent->iFlags = aFlags;
+ queue->WalkEventQueue(&OverrideVisibilityChangedEvent,&event);
+ if (event.Handle()!=NULL)
+ {
+ queue->QueueEvent(event);
+ }
+ }
+
+TEventQueueWalkRet OverrideDisplayChangedEvent(TAny *aNewEvent, TWsEvent *aOldEvent)
+ {
+ TWsEvent* newEvent = static_cast<TWsEvent*>(aNewEvent);
+ if (aOldEvent->Type() == EEventDisplayChanged &&
+ aOldEvent->DisplayChanged()->iDisplayNumber == newEvent->DisplayChanged()->iDisplayNumber)
+ {
+ aOldEvent->SetTimeNow();
+ aOldEvent->DisplayChanged()->iConfigurationChangeId = newEvent->DisplayChanged()->iConfigurationChangeId;
+ aOldEvent->DisplayChanged()->iResolutionListChangeId = newEvent->DisplayChanged()->iResolutionListChangeId;
+ newEvent->DisplayChanged()->iDisplayNumber = KErrNotFound; //So the new event won't be placed on event queue again
+ }
+ return EEventQueueWalkOk;
+ }
+
+TBool TWindowServerEvent::SendDisplayChangedEvents(CWsClient* aWsClient, TInt aDisplayNumber, TInt aConfigurationChangeId, TInt aResolutionListChangeId)
+ {
+ CEventQueue *queue = aWsClient->EventQueue();
+ TWsEvent event;
+ event.SetType(EEventDisplayChanged);
+ event.SetTimeNow();
+ TWsDisplayChangedEvent* dispEvent = event.DisplayChanged();
+ dispEvent->iDisplayNumber = aDisplayNumber;
+ dispEvent->iConfigurationChangeId = aConfigurationChangeId;
+ dispEvent->iResolutionListChangeId = aResolutionListChangeId;
+ queue->WalkEventQueue(&OverrideDisplayChangedEvent, &event);
+ //place the new event on the queue only when its display number is valid (!=KErrNotFound)
+ if(event.DisplayChanged()->iDisplayNumber >= 0)
+ {
+ return queue->QueueEvent(event);
+ }
+ return ETrue;
+ }
+
+void TWindowServerEvent::QueueKeyEvent(CWsWindowGroup *aWin, TWsEvent &aEvent, TWservEventPriorities aPriority)
+ {
+ aEvent.SetTimeNow();
+ aWin->EventQueue()->QueueEvent(aEvent, aPriority);
+ }
+
+void TWindowServerEvent::QueueKeyPress(const TKeyData& aKey, TInt aScanCode, CWsWindowGroup* aRepeatFocus, TBool aCheckRepeat,TInt aRepeats)
+ {
+ CWsWindowGroup* focusWin=CWsTop::FocusWindowGroup();
+ TWsEvent event;
+ TKeyEvent& keyEvent=*event.Key();
+ keyEvent.iCode=aKey.iKeyCode;
+ keyEvent.iScanCode=aScanCode;
+ keyEvent.iModifiers=aKey.iModifiers;
+ keyEvent.iRepeats=aRepeats;
+ if (!aRepeatFocus && CClick::IsHandler())
+ CClick::KeyEvent(EEventKey,keyEvent);
+ CWsCaptureLongKey* longCapture=NULL;
+ if (aCheckRepeat)
+ longCapture=CWsCaptureLongKey::CheckForCapture(aKey.iKeyCode, aKey.iModifiers);
+ if (aKey.iIsCaptureKey)
+ {
+ if (aKey.iApp==NULL) // Captured by Wserv itself
+ {
+ _LIT(KWSERVDebugLogCapturedKey,"WSERV Captured Key");
+ CScreen* focusScreen=CWsTop::CurrentFocusScreen();
+ TInt screenNo=focusScreen->ScreenNumber();
+
+ if (wsDebugLog)
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogCapturedKey);
+ CWsHotKey *hotKey=iHotKeys;
+ while(hotKey)
+ {
+ if (hotKey->KeyHandle()==aKey.iHandle)
+ {
+ switch(hotKey->HotKeyType())
+ {
+ case EHotKeyEnableLogging:
+ CWsTop::EnableLogging();
+ break;
+ case EHotKeyDisableLogging:
+ CWsTop::DisableLogging();
+ break;
+ case EHotKeyStateDump:
+ StateDump();
+ break;
+ case EHotKeyHeapDump:
+ HeapDump();
+ break;
+ case EHotKeyOfDeath:
+ if (!CWsPassword::PasswordModeActive())
+ {
+ const TBool currentJustInTimeValue=User::JustInTime();
+ if (currentJustInTimeValue)
+ {
+ User::SetJustInTime(EFalse);
+ }
+ CWsTop::KillForegroundSession();
+ if (currentJustInTimeValue)
+ {
+ User::SetJustInTime(ETrue);
+ }
+ }
+ break;
+ case EHotKeyShutDown:
+ CWsTop::Exit();
+ break;
+ case EHotKeyIncContrast:
+ focusScreen->IncContrast();
+ break;
+ case EHotKeyDecContrast:
+ focusScreen->DecContrast();
+ break;
+ case EHotKeyOff:
+ CWsTop::HandleSwitchOff(EEventKeySwitchOff,ETrue);
+ break;
+ case EHotKeyBacklightToggle:
+ {
+ TInt state;
+ if (!ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(screenNo,HALData::EBacklightState,state)))
+ ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(screenNo,HALData::EBacklightState,!state));
+ }
+ break;
+ case EHotKeyBacklightOn:
+ ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(screenNo,HALData::EBacklightState,ETrue));
+ break;
+ case EHotKeyBacklightOff:
+ ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(screenNo,HALData::EBacklightState,EFalse));
+ break;
+ case EHotKeyScreenDimension0:
+ case EHotKeyScreenDimension1:
+ case EHotKeyScreenDimension2:
+ case EHotKeyScreenDimension3:
+ focusScreen->doSetScreenMode(hotKey->HotKeyType()-EHotKeyScreenDimension0);
+ break;
+ case EHotKeyCycleDisplaySize:
+ focusScreen->CycleDisplaySize();
+ break;
+ case EHotKeyCycleOrientation:
+ focusScreen->CycleOrientation();
+ break;
+ case EHotKeyIncBrightness:
+ focusScreen->IncBrightness();
+ break;
+ case EHotKeyDecBrightness:
+ focusScreen->DecBrightness();
+ break;
+ case EHotKeyCycleFocusScreen:
+ CWsTop::SetCurrentFocusScreen((CWsTop::CurrentFocusScreen()->ScreenNumber()+1)%CWsTop::NumberOfScreens());
+ break;
+ }
+ return;
+ }
+ hotKey=hotKey->iNext;
+ }
+ WS_PANIC_ALWAYS(EWsPanicUnknownCaptureKey);
+ return;
+ }
+ focusWin=((CWsWindowGroup *)aKey.iApp);
+ _LIT(KWSERVDebugLogKeyCapturedByApp,"Key captured by app %d");
+ if (wsDebugLog)
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyCapturedByApp,focusWin->Identifier());
+ if (CWsPassword::PasswordModeActive() && focusWin!=CWsPassword::PasswordWindow()->WinGroup())
+ return;
+ }
+ if (aRepeatFocus && aRepeatFocus!=focusWin)
+ CKeyboardRepeat::CancelRepeat(NULL); // Repeat is going to different window so cancel it and don't deliver this key
+ else if (focusWin!=NULL && focusWin->CheckForPriorityKey(aKey,aScanCode)==EFalse)
+ {
+ if (longCapture || (aCheckRepeat && !aRepeatFocus && aKey.iModifiers&EModifierAutorepeatable))
+ {
+ if (CKeyboardRepeat::StartRepeat(aKey,aScanCode,focusWin,longCapture))
+ return;
+ }
+ event.SetType(EEventKey);
+ event.SetHandle(focusWin->ClientHandle());
+ if (aRepeats!=0)
+ {
+ CEventQueue* queue=focusWin->EventQueue();
+ queue->Wait();
+ const TWsEvent* prev=queue->PeekLastEvent();
+ if (prev!=NULL && prev->Type()==EEventKey && prev->Key()->iRepeats>0)
+ {
+ event= *prev;
+ event.Key()->iRepeats+=aRepeats;
+ queue->UpdateLastEvent(event);
+ queue->Signal();
+ if (CClick::IsHandler())
+ CClick::KeyEvent(EEventKeyRepeat,*event.Key());
+ return;
+ }
+ queue->Signal();
+ event.Key()->iRepeats=aRepeats;
+ if (CClick::IsHandler())
+ CClick::KeyEvent(EEventKeyRepeat,keyEvent);
+ }
+ QueueKeyEvent(focusWin, event, EEventPriorityLow);
+ }
+ }
+
+void TWindowServerEvent::QueueKeyUpDown(const TRawEvent &aRawEvent)
+ {
+ CWsWindowGroup *focusWin=CWsCaptureKeyUpsAndDowns::CheckForCapture(aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE, iModifierState);
+ if (!focusWin) // If not captured
+ focusWin=CWsTop::FocusWindowGroup();
+ TWsEvent event;
+ TEventCode type=aRawEvent.Type()==TRawEvent::EKeyUp ? EEventKeyUp : EEventKeyDown;
+ event.Key()->iCode=0;
+#if defined(__WINS__)
+ if (focusWin && !focusWin->WsOwner()->RemoveKeyCode())
+ event.Key()->iScanCode=aRawEvent.ScanCode();
+ else
+#endif
+ event.Key()->iScanCode=aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
+ event.Key()->iModifiers=iModifierState;
+ event.Key()->iRepeats=0;
+ if (CClick::IsHandler())
+ CClick::KeyEvent(type,*event.Key());
+ if (focusWin!=NULL)
+ {
+ event.SetType(type);
+ event.SetHandle(focusWin->ClientHandle());
+ QueueKeyEvent(focusWin, event, EEventPriorityHigh);
+ }
+ }
+
+LOCAL_D void GetPointerEvent(TPointerEvent::TType& aType, const TRawEvent &aRawEvent, TBool& aHandled)
+ {
+ aHandled=ETrue;
+ switch(aRawEvent.Type())
+ {
+ case TRawEvent::EButton1Down:
+ aType=TPointerEvent::EButton1Down;
+ break;
+ case TRawEvent::EButton1Up:
+ aType=TPointerEvent::EButton1Up;
+ break;
+ case TRawEvent::EButton2Down:
+ aType=TPointerEvent::EButton2Down;
+ break;
+ case TRawEvent::EButton2Up:
+ aType=TPointerEvent::EButton2Up;
+ break;
+ case TRawEvent::EButton3Down:
+ aType=TPointerEvent::EButton3Down;
+ break;
+ case TRawEvent::EButton3Up:
+ aType=TPointerEvent::EButton3Up;
+ break;
+ case TRawEvent::EPointerMove:
+ aType=TPointerEvent::EMove;
+ break;
+ case TRawEvent::EPointerSwitchOn:
+ aType=TPointerEvent::ESwitchOn;
+ break;
+ case TRawEvent::EPointer3DOutOfRange:
+ aType=TPointerEvent::EOutOfRange;
+ break;
+ default:
+ aHandled=EFalse;
+ }
+ }
+
+TBool TWindowServerEvent::MousePress(const TRawEvent &aRawEvent, const CWsWindowGroup *aGroupWin)
+ //
+ //Return EFalse if known not to be a Mouse Event
+ //
+ {
+ TBool handled=ETrue;
+ TPointerEvent::TType type;
+ GetPointerEvent(type, aRawEvent, handled);
+ if (handled)
+ {
+ TPoint3D point3D(0,0,0);
+ if (type != TPointerEvent::EOutOfRange)
+ {
+ point3D = aRawEvent.Pos3D();
+ }
+ TWsEvent event;
+ TAdvancedPointerEventHelper::InitAdvancedPointerEvent(event, type,iKeyTranslator->GetModifierState(),point3D,aRawEvent.PointerNumber());
+ TWsPointer::ProcessWsEvent(event, aGroupWin, ETrue);
+ }
+ return handled;
+ }
+
+LOCAL_D void SendEventToKeyClick(const TRawEvent& aRawEvent)
+ {
+ switch(aRawEvent.Type())
+ {
+ case TRawEvent::EKeyDown:
+ case TRawEvent::EKeyUp:
+ {
+ TKeyEvent keyEvent;
+ keyEvent.iCode=0;
+ keyEvent.iScanCode=aRawEvent.ScanCode();
+ keyEvent.iModifiers=0;
+ keyEvent.iRepeats=0;
+ CClick::KeyEvent(EEventKey,keyEvent);
+ }
+ break;
+ case TRawEvent::EButton1Down:
+ case TRawEvent::EButton1Up:
+ case TRawEvent::EButton2Down:
+ case TRawEvent::EButton2Up:
+ case TRawEvent::EButton3Down:
+ case TRawEvent::EButton3Up:
+ case TRawEvent::EPointerMove:
+ case TRawEvent::EPointerSwitchOn:
+ {
+ TBool handled=ETrue;
+ TPointerEvent::TType type;
+ GetPointerEvent(type, aRawEvent, handled);
+ if (handled)
+ {
+ TWsEvent event;
+ TAdvancedPointerEventHelper::InitAdvancedPointerEvent(event, type, 0, aRawEvent.Pos3D(), TPoint(), aRawEvent.PointerNumber());
+ TAdvancedPointerEvent& pointerEvent = *event.Pointer();
+ CClick::PointerEvent(pointerEvent.iPosition,pointerEvent);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+void TWindowServerEvent::ProcessRawEvent(const TRawEvent& aRawEvent)
+//
+// Event has completed.
+//
+ {
+ TRawEvent::TType eventType = aRawEvent.Type();
+ TBool isPointerEvent = TWsPointer::IsPointerEventType(eventType);
+ if (isPointerEvent)
+ {
+ TWsPointer::UpdatePrimaryPointer(aRawEvent);
+ }
+ TInt count=iEventHandlers.Count();
+ TInt ii;
+ TBool eventHandled = EFalse;
+ iEventHandlerCount++;
+ for(ii=0;ii<count;++ii)
+ {
+ TRawEventHandler &handler = iEventHandlers[ii];
+ if (handler.iEventHandler != NULL &&
+ (!isPointerEvent ||
+ handler.iAdvancedPointersEnabled ||
+ aRawEvent.PointerNumber() == TWsPointer::PrimaryPointer()) &&
+ handler.iEventHandler->OfferRawEvent(aRawEvent))
+ {
+ if (CClick::IsHandler())
+ {
+ SendEventToKeyClick(aRawEvent);
+ }
+ eventHandled = ETrue;
+ break;
+ }
+ }
+ if (--iEventHandlerCount == 0)
+ {
+ if (ERemovedEventHandlerWhileProcessingRawEvents & iBinaryFlags) // Handler was deleted while previous loop
+ {
+ iBinaryFlags &= ~ERemovedEventHandlerWhileProcessingRawEvents;
+ for(ii=count-1;ii>=0;--ii)
+ {
+ if (iEventHandlers[ii].iEventHandler==NULL) iEventHandlers.Remove(ii);
+ }
+ }
+ }
+ if (eventHandled)
+ {
+ if (isPointerEvent)
+ {
+ TWsPointer::RollbackPrimaryPointer();
+ }
+ return;
+ }
+ switch(eventType)
+ {
+ case TRawEvent::ERedraw:
+ CWsTop::RedrawScreens();
+ break;
+ case TRawEvent::ESwitchOn:
+ case TRawEvent::ECaseOpen:
+ {
+ TInt event=EEventCaseOpened;
+ CKeyboardRepeat::CancelRepeat(NULL);
+ CWsPassword::SwitchOn();
+ if (eventType==TRawEvent::ESwitchOn)
+ {
+ UserSvr::WsSwitchOnScreen();
+ HAL::Set(HALData::EDisplayState,1);
+ event=EEventSwitchOn;
+ }
+ ProcessEventQueue(iSwitchOnQueue, SendSwitchOnEvent, event, 0);
+ break;
+ }
+ case TRawEvent::ESwitchOff:
+ case TRawEvent::ECaseClose:
+ {
+ TBool switchOff=(eventType==TRawEvent::ESwitchOff);
+ CWsTop::HandleSwitchOff(switchOff? EEventSwitchOff:EEventCaseClosed,switchOff);
+ break;
+ }
+#ifdef SYMBIAN_PROCESS_MONITORING_AND_STARTUP
+ case TRawEvent::ERestartSystem:
+ { /* restart event being handled */
+ CWsTop::HandleSwitchOff(EEventRestartSystem,ETrue);
+ break;
+ }
+#endif
+ case TRawEvent::EInactive:
+#ifndef __WINS__
+ CWsTop::WindowServer()->AnimationScheduler()->OnInactive();
+#endif
+ CKeyboardRepeat::CancelRepeat(NULL);
+ break;
+ case TRawEvent::EActive:
+#ifndef __WINS__
+ CWsTop::WindowServer()->AnimationScheduler()->OnActive();
+#endif
+ break;
+ case TRawEvent::EKeyDown:
+ {
+ _LIT(KWSERVDebugLogKeyDownArrival,"Key down arrives %d");
+ if(CDebugBar* dbg = CWsTop::Screen()->DebugBar())
+ dbg->OnKeyEvent();
+ if (wsDebugLog)
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyDownArrival,aRawEvent.ScanCode());
+ CKeyboardRepeat::KeyDown();
+ TKeyData keyData;
+ TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), EFalse,*iCaptureKeys,keyData);
+ ProcessModifierChanges();
+ QueueKeyUpDown(aRawEvent);
+ if (translated)
+ QueueKeyPress(keyData,aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,ETrue,0);
+ }
+ break;
+ case TRawEvent::EKeyUp:
+ {
+ _LIT(KWSERVDebugLogKeyUpArrival,"Key up arrives %d");
+ if(CDebugBar* dbg = CWsTop::Screen()->DebugBar())
+ dbg->OnKeyEvent();
+ if (wsDebugLog)
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyUpArrival,aRawEvent.ScanCode());
+ TKeyData keyData;
+ CKeyboardRepeat::KeyUp(aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE);
+ TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), ETrue,*iCaptureKeys,keyData);
+ ProcessModifierChanges();
+ QueueKeyUpDown(aRawEvent);
+ if (translated)
+ {
+ CKeyboardRepeat::CancelRepeat(NULL);
+ QueueKeyPress(keyData,aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,EFalse,0);
+ }
+ }
+ break;
+ case TRawEvent::EButton1Down:
+ case TRawEvent::EButton2Down:
+ case TRawEvent::EButton3Down:
+ case TRawEvent::EPointerSwitchOn:
+#ifndef __WINS__
+ CWsTop::WindowServer()->AnimationScheduler()->OnActive();
+#endif
+ // fall through
+ case TRawEvent::EButton1Up:
+ case TRawEvent::EButton2Up:
+ case TRawEvent::EButton3Up:
+ case TRawEvent::EPointerMove:
+ case TRawEvent::EPointer3DOutOfRange:
+ #if defined(_DEBUG)
+ WS_ASSERT_DEBUG(MousePress(aRawEvent,NULL), EWsPanicEventType);
+ #else
+ MousePress(aRawEvent,NULL);
+ #endif
+ break;
+ case TRawEvent::EUpdateModifiers:
+ iKeyTranslator->UpdateModifiers(aRawEvent.Modifiers());
+ break;
+ case TRawEvent::EKeyRepeat:
+ {
+ _LIT(KWSERVDebugLogRepeatingKeyArrival,"Repeating key arrives %d");
+ if (wsDebugLog)
+ wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogRepeatingKeyArrival,aRawEvent.ScanCode());
+ TKeyData keyData;
+ keyData.iModifiers=iKeyTranslator->GetModifierState();
+ keyData.iApp=0;
+ keyData.iHandle=0;
+ keyData.iIsCaptureKey=EFalse;
+ keyData.iKeyCode=aRawEvent.ScanCode();
+ iCaptureKeys->ProcessCaptureKeys(keyData);
+ QueueKeyPress(keyData, aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,EFalse,aRawEvent.Repeats());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+void TWindowServerEvent::ProcessKeyEvent(const TKeyEvent &aKeyEvent,TInt aRepeats)
+ {
+ TKeyData keyData;
+ keyData.iModifiers=aKeyEvent.iModifiers;
+ keyData.iApp=0;
+ keyData.iHandle=0;
+ keyData.iIsCaptureKey=EFalse;
+ keyData.iKeyCode=aKeyEvent.iCode;
+ if (CKeyboardRepeat::IsAreadyActive())
+ {
+ CKeyboardRepeat::CancelRepeat(NULL);
+ }
+ iCaptureKeys->ProcessCaptureKeys(keyData);
+ QueueKeyPress(keyData,aKeyEvent.iScanCode,NULL,aRepeats==0,aRepeats);
+ }
+
+void TWindowServerEvent::AddCaptureKeyL(const TCaptureKey &aCaptureKey)
+ {
+ iCaptureKeys->AddCaptureKeyL(aCaptureKey,aCaptureKey.iKeyCodePattern.iFiller);
+ }
+
+void TWindowServerEvent::SetCaptureKey(TUint32 aHandle, const TCaptureKey &aCaptureKey)
+ {
+ iCaptureKeys->SetCaptureKey(aHandle, aCaptureKey,aCaptureKey.iKeyCodePattern.iFiller);
+ }
+
+void TWindowServerEvent::CancelCaptureKey(TUint32 aHandle)
+ {
+ iCaptureKeys->CancelCaptureKey(aHandle);
+ }
+
+TInt TWindowServerEvent::GetModifierState()
+ {
+ return(iKeyTranslator->GetModifierState());
+ }
+
+void TWindowServerEvent::SetModifierState(TEventModifier aModifier,TModifierState aState)
+ {
+ iKeyTranslator->SetModifierState(aModifier,aState);
+ }
+
+TInt TWindowServerEvent::AddNotificationHandler(CAnim* aAnim, TUint32 aNotifications)
+ {
+ SNotificationHandler notif;
+ notif.iAnim = aAnim;
+ notif.iNotifications = aNotifications;
+
+ // update the entry if the anim is already in the array
+ TInt count=iNotificationHandlers->Count();
+ TInt ii;
+ for(ii=0;ii<count;++ii)
+ {
+ if ((*iNotificationHandlers)[ii].iAnim==aAnim)
+ {
+ (*iNotificationHandlers)[ii]=notif;
+ return KErrNone;
+ }
+ }
+
+ // otherwise add it to the array
+ TRAPD(err,iNotificationHandlers->AppendL(notif));
+ return err;
+ }
+
+void TWindowServerEvent::RemoveNotificationHandler(CAnim* aAnim)
+ {
+ TInt count=iNotificationHandlers->Count();
+ TInt ii;
+ for(ii=0;ii<count;++ii)
+ {
+ if ((*iNotificationHandlers)[ii].iAnim==aAnim)
+ {
+ iNotificationHandlers->Delete(ii);
+ return;
+ }
+ }
+ }
+
+void TWindowServerEvent::PublishNotification(const TWsEvent& aWsEvent)
+ {
+ TInt count=iNotificationHandlers->Count();
+ TInt ii;
+ for(ii=0;ii<count;++ii)
+ {
+ SNotificationHandler notif = (*iNotificationHandlers)[ii];
+ switch (aWsEvent.Type())
+ {
+ case EEventDirectScreenAccessBegin:
+ case EEventDirectScreenAccessEnd:
+ if (notif.iNotifications & EDirectScreenAccess)
+ {
+ notif.iAnim->HandleNotification(aWsEvent);
+ }
+ break;
+ case EEventHeartbeatTimerStateChange:
+ if (notif.iNotifications & EHeartbeatTimer)
+ {
+ notif.iAnim->HandleNotification(aWsEvent);
+ }
+ break;
+ case EEventScreenDeviceChanged:
+ if (notif.iNotifications & EScreenDeviceChange)
+ {
+ notif.iAnim->HandleNotification(aWsEvent);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ }
+
+TBool TWindowServerEvent::DrawerCompareFunc(const TDrawerHandler& lhs, const TDrawerHandler& rhs)
+ {
+ return lhs.iDrawer == rhs.iDrawer;
+ }
+
+TInt TWindowServerEvent::RegisterDrawerHandler(CWsGraphicDrawer* aDrawer, TUint32 aEvents)
+ {
+ TInt idx = iDrawerHandlers->Find(TDrawerHandler(aDrawer, aEvents),
+ TIdentityRelation<TDrawerHandler>(TWindowServerEvent::DrawerCompareFunc));
+ if (idx != KErrNotFound)
+ {
+ // replace event mask for this drawer
+ (*iDrawerHandlers)[idx].iEvents = aEvents;
+ idx = KErrNone;
+ }
+ else
+ idx = iDrawerHandlers->Append(TDrawerHandler(aDrawer,aEvents));
+
+ return idx;
+ }
+
+TInt TWindowServerEvent::UnregisterDrawerHandler(CWsGraphicDrawer* aDrawer)
+ {
+ TInt idx = iDrawerHandlers->Find(TDrawerHandler(aDrawer,0),
+ TIdentityRelation<TDrawerHandler>(TWindowServerEvent::DrawerCompareFunc));
+ if (idx == KErrNotFound)
+ return idx;
+ (*iDrawerHandlers)[idx].iDrawer = NULL; //NotifyDrawer() will clean up the array
+ return KErrNone;
+ }
+
+TInt TWindowServerEvent::RegisterWsEventHandler(MWsEventHandler * aHandler, TUint32 aEvents)
+ {
+ TWsEventHandler handler(aHandler, aEvents);
+ TInt idx = iWsEventHandlers.Find(handler, TIdentityRelation<TWsEventHandler>(TWsEventHandler::CompareHandler));
+ if (idx < 0)
+ {
+ TInt err = iWsEventHandlers.Append(handler);
+ return err;
+ }
+ else
+ {
+ iWsEventHandlers[idx].iEvents = aEvents;
+ return KErrNone;
+ }
+ }
+
+TInt TWindowServerEvent::UnregisterWsEventHandler(MWsEventHandler * aHandler)
+ {
+ TWsEventHandler handler(aHandler, 0);
+ TInt idx = iWsEventHandlers.Find(handler, TIdentityRelation<TWsEventHandler>(TWsEventHandler::CompareHandler));
+ if (idx < 0)
+ return idx;
+ iWsEventHandlers[idx].iEvents = NULL; //NotifyDrawer() will clean up the array
+ return KErrNone;
+ }
+
+
+void TWindowServerEvent::NotifyDrawer(const TWservCrEvent& aEvent)
+ {
+ TInt drawerCount = iDrawerHandlers->Count();
+ for (TInt idx = 0; idx < drawerCount; idx++)
+ {
+ TDrawerHandler hd = (*iDrawerHandlers)[idx];
+ if (!hd.iDrawer)
+ { //If the handler has been removed
+ iDrawerHandlers->Remove(idx); //Remove from the array
+ drawerCount -= 1; //Update the counters
+ idx -= 1;
+ }
+ else
+ {
+ if (hd.iEvents & aEvent.Type())
+ {
+ hd.iDrawer->HandleEvent(aEvent);
+ }
+ }
+ }
+
+ TInt eventHandlerCount = iWsEventHandlers.Count();
+ for (TInt idx = 0; idx < eventHandlerCount; ++idx)
+ {
+ TWsEventHandler* eh = &iWsEventHandlers[idx];
+ if (!eh->iEvents)
+ { //If the handler has been removed
+ iWsEventHandlers.Remove(idx); //Remove from the array
+ eventHandlerCount -= 1; //Update the counters
+ idx -= 1;
+ }
+ else
+ {
+ if (eh->iEvents & aEvent.Type())
+ {
+ eh->iHandler->DoHandleEvent(aEvent);
+ }
+ }
+ }
+ }
+
+void TWindowServerEvent::NotifyScreenDrawingEvent(const TRegion* aRegion)
+ {
+ if (aRegion && !aRegion->IsEmpty())
+ {
+ TWservCrEvent event(TWservCrEvent::EScreenDrawing,0,const_cast<TRegion*>(aRegion));
+ NotifyDrawer(event);
+ }
+ }
+
+void TWindowServerEvent::NotifyScreenDrawingEvent(const TRect& aRect)
+ {
+ TRegionFix<1> reg(aRect);
+ TWservCrEvent event(TWservCrEvent::EScreenDrawing,0,®);
+ NotifyDrawer(event);
+ }
+
+//
+// CRawEventReceiver //
+//
+
+CRawEventReceiver::CRawEventReceiver(TInt aPriority) : CActive(aPriority)
+//
+// Constructor
+//
+ {
+ __DECLARE_NAME(_S("CRawEventReceiver"));
+ }
+
+CRawEventReceiver::~CRawEventReceiver()
+ {
+ CActive::Cancel();
+ }
+
+void CRawEventReceiver::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ UserSvr::CaptureEventHook();
+ Request();
+ }
+
+void CRawEventReceiver::Request()
+//
+// Issue a request for the next event.
+//
+ {
+ UserSvr::RequestEvent(iEventBuf,iStatus);
+ SetActive();
+ }
+
+void CRawEventReceiver::DoCancel()
+//
+// Cancel a pending event.
+//
+ {
+ UserSvr::RequestEventCancel();
+ }
+
+void CRawEventReceiver::RunL()
+ {
+//__PROFILE_START(11);
+ if (TWsPointer::PreProcessDriverEvent(iEventBuf.Event()
+#if defined(__WINS__)
+ ,ETrue
+#endif
+ ))
+ TWindowServerEvent::ProcessRawEvent(iEventBuf.Event());
+ Request();
+//__PROFILE_END(11);
+ }
+
+//
+// TEventRequestQueue //
+//
+
+TEventRequestQueue::TEventRequestQueue() : iQueue(_FOFF(TEventRequestItem,iQue))
+ {}
+
+inline TSglQue<TEventRequestItem> &TEventRequestQueue::Queue()
+ {return(iQueue);}
+
+TEventRequestItem *TEventRequestQueue::FindInEventRequestQueueList(const CWsWindowBase &aWindow)
+//
+// Return a pointer to the link in the queue for the window, or NULL if not in the queue
+//
+ {
+ TSglQueIter<TEventRequestItem> iter(iQueue);
+ TEventRequestItem *qPtr;
+ while((qPtr=iter++)!=NULL)
+ if (qPtr->iWindow==&aWindow)
+ break;
+ return(qPtr);
+ }
+
+void TEventRequestQueue::AddToEventRequestListL(const CWsWindowBase &aWindow, TInt aParam, TEventControl aCircumstances)
+//
+// Add a link to the on event list
+//
+ {
+ TEventRequestItem *item=FindInEventRequestQueueList(aWindow);
+ if (!item)
+ {
+ item=new(ELeave) TEventRequestItem;
+ item->iWindow= &aWindow;
+ item->iParam=aParam;
+ item->iCircumstances=aCircumstances;
+ iQueue.AddFirst(*item);
+ }
+ item->iCircumstances=aCircumstances;
+ item->iParam=aParam; // Just update the parameter if already exists
+ }
+
+void TEventRequestQueue::RemoveFromEventRequestListL(const CWsWindowBase &aWindow)
+//
+// Remove a link from the on event list
+//
+ {
+ TEventRequestItem *qPtr=FindInEventRequestQueueList(aWindow);
+ if (qPtr)
+ {
+ iQueue.Remove(*qPtr);
+ delete qPtr;
+ }
+ }
+
+//
+// Keyboard auto repeat class //
+//
+
+CKeyboardRepeat::CKeyboardRepeat() : CTimer(EKeyRepeatPriority)
+ {}
+
+void CKeyboardRepeat::NewL()
+ {
+ iThis=new(ELeave) CKeyboardRepeat();
+ iThis->ConstructL();
+ CActiveScheduler::Add(iThis);
+ _LIT(KWSERVIniFileVarRepeatRollover,"REPEATROLLOVER");
+ WsIniFile->FindVar(KWSERVIniFileVarRepeatRollover,iRepeatRollover);
+ }
+
+void CKeyboardRepeat::Destroy()
+ {
+ delete iThis;
+ }
+
+void CKeyboardRepeat::GetRepeatTime(TTimeIntervalMicroSeconds32 &aInitialTime, TTimeIntervalMicroSeconds32 &aTime)
+ {
+ aInitialTime=iInitialTime;
+ aTime=iTime;
+ }
+
+void CKeyboardRepeat::SetRepeatTime(const TTimeIntervalMicroSeconds32 &aInitialTime, const TTimeIntervalMicroSeconds32 &aTime)
+ {
+ iInitialTime=aInitialTime;
+ iTime=aTime;
+ }
+
+void CKeyboardRepeat::RunL()
+ {
+ User::ResetInactivityTime();
+ //WS_ASSERT_DEBUG(iRepeating!=ERepeatNone, EWsPanicTemp);
+ TBool timer=ETrue;
+ if (iRepeating>=ERepeatLong)
+ {
+ // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
+ if (iLongCapture)
+ {
+ iCurrentRepeat.iKey.iApp=REINTERPRET_CAST(TUint32,iLongCapture->iWindowGroup);
+ iCurrentRepeat.iKey.iHandle=0;
+ iCurrentRepeat.iKey.iIsCaptureKey=ETrue;
+ iCurrentRepeat.iKey.iKeyCode=iLongCapture->iData.outputKey;
+ timer=iLongCapture->iData.flags&ELongCaptureRepeatEvents;
+ iRepeating=ERepeatLongRepeated;
+ }
+ else
+ {
+ // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
+ // Stop key repeat if this incorrect condition occurs
+ timer=EFalse;
+ }
+ }
+ if (timer)
+ After(iTime);
+ else
+ iRepeating=ERepeatNone;
+ TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iKey,iCurrentRepeat.iScanCode,iFocus,EFalse,1);
+ }
+
+TBool CKeyboardRepeat::StartRepeat(const TKeyData &aKey, TInt aScanCode, CWsWindowGroup *aRepeatFocus, CWsCaptureLongKey* aLongCapture)
+ {
+ TTimeIntervalMicroSeconds32 time;
+ TBool ret=EFalse;
+ iCurrentRepeat.iScanCode=aScanCode;
+ iCurrentRepeat.iKey=aKey;
+
+ if (aLongCapture)
+ {
+ iLongCapture=aLongCapture;
+ iRepeating=ERepeatLong;
+ time=aLongCapture->iData.delay;
+ ret=!(aLongCapture->iData.flags&ELongCaptureShortEventImmediately);
+ //need window group from long capture key or even better delete it altogether.
+ iFocus=aLongCapture->WindowGroup();
+ }
+ else
+ {
+ iFocus=aRepeatFocus;
+ iRepeating=ERepeatNormal;
+ time=iInitialTime;
+ }
+ iThis->After(time);
+ return ret;
+ }
+
+void CKeyboardRepeat::doCancelRepeat()
+ {
+ iRepeating=ERepeatNone;
+ iThis->Cancel();
+ }
+
+void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus)
+ {
+ if (aRepeatFocus==NULL || aRepeatFocus==iFocus)
+ {
+ if (iRepeating)
+ doCancelRepeat();
+ iAlternateRepeatExists=EFalse;
+ }
+ else if (iRepeating >= ERepeatLong)
+ {
+ // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
+ if (iLongCapture && iLongCapture->iWindowGroup == aRepeatFocus)
+ {
+ doCancelRepeat();
+ iAlternateRepeatExists=EFalse;
+ }
+ }
+ }
+
+void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus,TUint aScanCode,TBool aLongCaptureFlag,TUint aModifiers)
+ {
+ if (aLongCaptureFlag)
+ {
+ // long capture key is cancelled
+ if (iRepeating >= ERepeatLong && iCurrentRepeat.iScanCode==aScanCode)
+ {
+ // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
+ if (iLongCapture && aRepeatFocus == iLongCapture->iWindowGroup &&
+ (aModifiers & iLongCapture->iData.modifierMask) == iLongCapture->iData.modifiers)
+ {
+ doCancelRepeat();
+ iAlternateRepeatExists=EFalse;
+ }
+ }
+ }
+ else
+ {
+ // normal capture key is cancelled
+ if (aRepeatFocus==iFocus)
+ {
+ if (iRepeating>=ERepeatNormal && iCurrentRepeat.iScanCode==aScanCode)
+ {
+ doCancelRepeat();
+ }
+ iAlternateRepeatExists=EFalse;
+ }
+ }
+ }
+
+void CKeyboardRepeat::KeyDown()
+ {
+ if (iRepeating!=ERepeatNone)
+ {
+ if (iRepeating==ERepeatNormal && iRepeatRollover>0) // 1 Allow key repeat rollover
+ {
+ iAlternateRepeat=iCurrentRepeat;
+ iAlternateRepeatExists=ETrue;
+ }
+ doCancelRepeat();
+ }
+ }
+
+void CKeyboardRepeat::KeyUp(TInt aScanCode)
+ {
+ if (iAlternateRepeatExists && iAlternateRepeat.iScanCode==aScanCode)
+ iAlternateRepeatExists=EFalse;
+ if (iRepeating!=ERepeatNone && iCurrentRepeat.iScanCode==aScanCode)
+ {
+ if (iRepeating==ERepeatLong)
+ {
+ // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
+ if (iLongCapture && !(iLongCapture->iData.flags&ELongCaptureShortEventImmediately))
+ {
+ TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iKey,iCurrentRepeat.iScanCode,NULL,EFalse,0);
+ }
+ }
+ if (iAlternateRepeatExists)
+ {
+ iAlternateRepeatExists=EFalse;
+ iCurrentRepeat=iAlternateRepeat;
+ iRepeating=ERepeatNormal;
+ }
+ else
+ doCancelRepeat();
+ }
+ }
+
+//
+// CWsHotKey //
+//
+
+CWsHotKey::CWsHotKey(TInt aHotKeyType, TBool aIsDefault) :
+ iHotKeyType(aHotKeyType),
+ iIsDefault(aIsDefault)
+ {
+ }
+
+CWsHotKey::~CWsHotKey()
+ {
+ delete iCaptureKey;
+ }
+
+void CWsHotKey::ConstructLD(const TWsWinCmdCaptureKey &aCaptureKey)
+ {
+ CleanupStack::PushL(this);
+ iCaptureKey=new(ELeave) CWsCaptureKey(NULL);
+ iCaptureKey->ConstructL(aCaptureKey);
+ CleanupStack::Pop();
+ }
+
+void CWsHotKey::SetL(const TWsWinCmdCaptureKey &aCaptureKey)
+ {
+ iCaptureKey->SetL(aCaptureKey);
+ }
+
+//
+//CEventQueueRetry//
+//
+CEventQueueRetry* CEventQueueRetry::NewL()
+ {
+ CEventQueueRetry* self = new (ELeave) CEventQueueRetry;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CEventQueueRetry::ConstructL()
+ {
+ User::LeaveIfError(iTimer.CreateLocal());
+ CActiveScheduler::Add(this);
+ }
+
+CEventQueueRetry::CEventQueueRetry() : CActive(EPriorityStandard), iRetrySpinner(1)
+ {
+
+ }
+
+CEventQueueRetry::~CEventQueueRetry()
+ {
+ Cancel();
+ iTimer.Close();
+ iClientArray.Close();
+ }
+
+void CEventQueueRetry::DoCancel()
+ {
+ iTimer.Cancel();
+ iRetrySpinner = 0;
+ iClientArray.Reset();
+ }
+
+void CEventQueueRetry::RunL()
+ {
+ //some clients may be no longer interested in listening
+ //so we need to refresh the client list each round of retry
+ iClientArray.Reset();
+ TInt err = iOwner->GetNotificationClients(iClientArray);
+ if(err != KErrNone)
+ {
+ iClientArray.Reset(); //so the retry won't kick off
+ }
+ if(iClientArray.Count() > 0)
+ {
+ TBool eventOnAllQueues = ETrue;
+ for(TInt i = 0; i < iClientArray.Count(); i++)
+ {
+ if(iClientArray[i]->RetryEvent(EEventDisplayChanged))
+ {
+ if(TWindowServerEvent::SendDisplayChangedEvents(iClientArray[i], iOwner->ScreenNumber(),
+ iOwner->ConfigSpinner(), iOwner->DisplaySpinner()))
+ {
+ iClientArray[i]->RemoveRetryFlag(EEventDisplayChanged);
+ }
+ else
+ {
+ eventOnAllQueues = EFalse;
+ }
+ }
+ }
+
+ if(!eventOnAllQueues)
+ {//another retry needed, but with increased time interval
+ iRetrySpinner++;
+ Retry(KRetryInitialDelay*iRetrySpinner);
+ }
+ }
+
+ }
+
+void CEventQueueRetry::Retry(TInt aDelay)
+ {
+ //the retry might be infinite, with an increasing interval, as delivery of the event is garuanteed
+ //if aDelay is greater than max TInt, it will be negative number so we reset it to KRetryInitialDelay
+ if(aDelay < 0)
+ {
+ aDelay = KRetryInitialDelay;
+ }
+ iTimer.After(iStatus, aDelay);
+ SetActive();
+ }
+
+void CEventQueueRetry::Init(CScreen *aOwner)
+ {
+ iOwner = aOwner;
+ iRetrySpinner = 0;
+
+ }
+
+void CEventQueueRetry::CancelRetry()
+ {
+ Cancel();
+ }