sl@0: // Copyright (c) 1994-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Top level window server code sl@0: // sl@0: // sl@0: sl@0: #include "EVENT.H" sl@0: sl@0: #include "W32STD.H" sl@0: #include sl@0: #include sl@0: #include sl@0: #include "W32CLICK.H" sl@0: #include "server.h" sl@0: #include "windowgroup.h" sl@0: #include "KEYCLICK.H" sl@0: #include "wstop.h" sl@0: #include "panics.h" sl@0: #include "screen.h" sl@0: #include "inifile.h" sl@0: #include "password.h" sl@0: #include "pointer.h" sl@0: #include "debugbar.h" sl@0: #include "advancedpointereventhelper.h" sl@0: #include "graphics/wsgraphicdrawerinternal.h" sl@0: #include "debughelper.h" sl@0: sl@0: GLREF_D CDebugLogBase *wsDebugLog; sl@0: sl@0: GLREF_C void StateDump(); sl@0: GLREF_C void HeapDump(); sl@0: sl@0: _LIT(KDefaultKeyRouterPluginName, "keyrouter.dll"); sl@0: _LIT(KWSERVIniFileVarKeyRouterPlugin, "KEYROUTERPLUGIN"); sl@0: sl@0: #define IMPOSSIBLE 0xFFFFFFFF sl@0: sl@0: const TWsWinCmdCaptureKey ImpossibleKeyPress= sl@0: { sl@0: IMPOSSIBLE, // Impossible to hit key combination, used for disabling Hot Keys sl@0: IMPOSSIBLE, sl@0: IMPOSSIBLE}; sl@0: sl@0: const TWsWinCmdCaptureKey DefaultHotKeys[TWindowServerEvent::ENumHotKeys]={ sl@0: { // Enable logging sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: 5}, // E sl@0: { // Disable logging sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: 4}, // D sl@0: { // Window server internal dump to log sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: 23},// W sl@0: { // The key of death sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: 11},// K sl@0: { // Shutdown window server sl@0: #if defined(_DEBUG) sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: 24},// X sl@0: #else sl@0: IMPOSSIBLE, // Impossible to hit key combination, effectively disables shutdown key in release builds sl@0: IMPOSSIBLE, sl@0: IMPOSSIBLE}, sl@0: #endif sl@0: { // Heap dump sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: 8}, // H sl@0: { // Inc Contrast sl@0: 0, sl@0: 0, sl@0: EKeyIncContrast}, sl@0: { // Dec Contrast sl@0: 0, sl@0: 0, sl@0: EKeyDecContrast}, sl@0: { // Off sl@0: 0, sl@0: 0, sl@0: EKeyOff}, sl@0: { // Backlight on sl@0: 0, sl@0: 0, sl@0: EKeyBacklightOn}, sl@0: { // Backlight off sl@0: 0, sl@0: 0, sl@0: EKeyBacklightOff}, sl@0: { // Backlight toggle sl@0: 0, sl@0: 0, sl@0: EKeyBacklightToggle}, sl@0: { // Screen Dimension Change sl@0: 0, sl@0: 0, sl@0: EKeyScreenDimension0}, sl@0: { sl@0: 0, sl@0: 0, sl@0: EKeyScreenDimension1}, sl@0: { sl@0: 0, sl@0: 0, sl@0: EKeyScreenDimension2}, sl@0: { sl@0: 0, sl@0: 0, sl@0: EKeyScreenDimension3}, sl@0: #if defined(_DEBUG) sl@0: { // Display mode cycle sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: 21},// U sl@0: { // Orientation cycle sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: 15},// O sl@0: #else sl@0: { // Display mode cycle sl@0: IMPOSSIBLE, // Impossible to hit key combination sl@0: IMPOSSIBLE, sl@0: IMPOSSIBLE}, sl@0: { // Orientation cycle sl@0: IMPOSSIBLE, // Impossible to hit key combination sl@0: IMPOSSIBLE, sl@0: IMPOSSIBLE}, sl@0: #endif sl@0: { // Inc Brightness sl@0: 0, sl@0: 0, sl@0: EKeyIncBrightness}, sl@0: { // Dec Brightness sl@0: 0, sl@0: 0, sl@0: EKeyDecBrightness}, sl@0: { // Cycle focus screen sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: EModifierFunc|EModifierCtrl|EModifierShift, sl@0: 9}, // I sl@0: }; sl@0: sl@0: CKeyTranslator *TWindowServerEvent::iKeyTranslator=NULL; sl@0: TEventRequestQueue TWindowServerEvent::iSwitchOnQueue; sl@0: TEventRequestQueue TWindowServerEvent::iErrorMessageQueue; sl@0: TEventRequestQueue TWindowServerEvent::iModifierChangedQueue; sl@0: TEventRequestQueue TWindowServerEvent::iGroupChangedQueue; sl@0: TEventRequestQueue TWindowServerEvent::iFocusChangedQueue; sl@0: TEventRequestQueue TWindowServerEvent::iGroupListChangedQueue; sl@0: TEventRequestQueue TWindowServerEvent::iScreenDeviceChangedQueue; sl@0: TTime TWindowServerEvent::iPrevOomMessageTime; sl@0: CCaptureKeys *TWindowServerEvent::iCaptureKeys; sl@0: CKeyEventRouter* TWindowServerEvent::iKeyEventRouter; sl@0: RLibrary TWindowServerEvent::iKeyEventRouterLibrary; sl@0: CWsHotKey *TWindowServerEvent::iHotKeys; sl@0: TInt TWindowServerEvent::iModifierState; sl@0: CRawEventReceiver *TWindowServerEvent::iEventReceiver; sl@0: RArray TWindowServerEvent::iEventHandlers; sl@0: CArrayFixFlat *TWindowServerEvent::iNotificationHandlers; sl@0: TInt TWindowServerEvent::iPotentialEventHandlers=0; sl@0: TUint32 TWindowServerEvent::iBinaryFlags=0x00; sl@0: RArray* TWindowServerEvent::iDrawerHandlers; sl@0: RArray TWindowServerEvent::iWsEventHandlers; sl@0: TInt TWindowServerEvent::iEventHandlerCount=0; sl@0: TRepeatKey CKeyboardRepeat::iCurrentRepeat; sl@0: TRepeatKey CKeyboardRepeat::iAlternateRepeat; sl@0: TRepeatKey CKeyboardRepeat::iLongRepeat; sl@0: TInt CKeyboardRepeat::iRepeatRollover=1; sl@0: CKeyboardRepeat::TRepeatType CKeyboardRepeat::iRepeating=ERepeatNone; sl@0: CKeyboardRepeat *CKeyboardRepeat::iThis=NULL; sl@0: TTimeIntervalMicroSeconds32 CKeyboardRepeat::iInitialTime; sl@0: TTimeIntervalMicroSeconds32 CKeyboardRepeat::iTime; sl@0: TBool CKeyboardRepeat::iAlternateRepeatExists=EFalse; sl@0: CWsCaptureLongKey* CKeyboardRepeat::iLongCapture=NULL; sl@0: sl@0: sl@0: void TWindowServerEvent::DeleteHotKeys() sl@0: { sl@0: CWsHotKey *hotKey=iHotKeys; sl@0: while(hotKey) sl@0: { sl@0: CWsHotKey *next=hotKey->iNext; sl@0: delete hotKey; sl@0: hotKey=next; sl@0: } sl@0: iHotKeys=NULL; sl@0: } sl@0: sl@0: void TWindowServerEvent::DeleteStatics() sl@0: { sl@0: DeleteHotKeys(); sl@0: delete iCaptureKeys; sl@0: delete iKeyEventRouter; sl@0: iKeyEventRouterLibrary.Close(); sl@0: CKeyboardRepeat::Destroy(); sl@0: delete iKeyTranslator; sl@0: delete iEventReceiver; sl@0: iEventHandlers.Close(); sl@0: delete iNotificationHandlers; sl@0: iDrawerHandlers->Close(); sl@0: delete iDrawerHandlers; sl@0: iWsEventHandlers.Close(); sl@0: } sl@0: sl@0: void TWindowServerEvent::InitStaticsL() sl@0: // sl@0: // Create the CEvent active object. sl@0: // sl@0: { sl@0: #if defined(__WINS__) sl@0: WS_ASSERT_DEBUG(TWindowServerEvent::ENumHotKeys==EHotKeyLastKeyType+1, EWsPanicUnknownCaptureKey); sl@0: #endif sl@0: iEventReceiver=new(ELeave) CRawEventReceiver(EEventPriority); sl@0: iEventReceiver->ConstructL(); sl@0: iKeyTranslator=CKeyTranslator::New(); sl@0: User::LeaveIfNull(iKeyTranslator); sl@0: sl@0: // Change keyboard mapping according to information the HAL sl@0: TInt keyboardIndex; sl@0: if (HAL::Get(HALData::EKeyboardIndex,keyboardIndex)==KErrNone) sl@0: { sl@0: _LIT(KLitKeyDataDllName,"EKDATA.%02d"); sl@0: TBuf<16> keyDataDllName; sl@0: keyDataDllName.Format(KLitKeyDataDllName,keyboardIndex); sl@0: iKeyTranslator->ChangeKeyData(keyDataDllName); sl@0: } sl@0: sl@0: // CCaptureKeys is no longer used but a dummy object is required for sl@0: // calls to CKeyTranslator::TranslateKey() until capture functionality sl@0: // has been removed from ektran.dll. sl@0: iCaptureKeys=new(ELeave) CCaptureKeys; sl@0: iCaptureKeys->Construct(); sl@0: sl@0: // Load the key event routing plug-in. The DLL name may be overridden sl@0: // by setting the keyword KEYROUTERPLUGIN in wsini.ini. sl@0: TPtrC pluginName(KDefaultKeyRouterPluginName); sl@0: WsIniFile->FindVar(KWSERVIniFileVarKeyRouterPlugin, pluginName); sl@0: const TUidType uidType(KDynamicLibraryUid, KKeyRouterPluginUid); sl@0: TInt err = iKeyEventRouterLibrary.Load(pluginName, uidType); sl@0: sl@0: if (wsDebugLog) sl@0: { sl@0: TLogMessageText buf; sl@0: sl@0: if (err == KErrNone) sl@0: { sl@0: _LIT(KLogLoadOk, "Loaded plugin '%S' UID3 0x%x"); sl@0: const TFileName& pluginPathname = iKeyEventRouterLibrary.FileName(); sl@0: const TUid uid3 = iKeyEventRouterLibrary.Type()[2]; sl@0: buf.Format(KLogLoadOk, &pluginPathname, uid3.iUid); sl@0: } sl@0: else sl@0: { sl@0: _LIT(KLogLoadError, "Failed to load plugin '%S' (error %d)"); sl@0: buf.Format(KLogLoadError, &pluginName, err); sl@0: } sl@0: sl@0: wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant, buf); sl@0: } sl@0: sl@0: if (err != KErrNone) sl@0: { sl@0: #ifdef _DEBUG sl@0: _LIT(KLoadError, "WServ: failed to load plugin '%S' (error %d)"); sl@0: RDebug::Print(KLoadError, &pluginName, err); sl@0: #endif sl@0: User::Leave(err); sl@0: } sl@0: sl@0: // Create the key event router sl@0: typedef CKeyEventRouter* (*TCreateFunc)(); sl@0: TCreateFunc newL = reinterpret_cast(iKeyEventRouterLibrary.Lookup(1)); sl@0: if (newL == NULL) sl@0: { sl@0: User::Leave(KErrNotFound); sl@0: } sl@0: iKeyEventRouter = (*newL)(); sl@0: sl@0: for (TInt index=0;index(2); sl@0: iNotificationHandlers=new(ELeave) CArrayFixFlat(2); sl@0: iDrawerHandlers = new(ELeave) RArray(4); sl@0: } sl@0: sl@0: void TWindowServerEvent::LinkHotKey(CWsHotKey *aWsHotKey) sl@0: { sl@0: aWsHotKey->SetLink(iHotKeys); sl@0: iHotKeys=aWsHotKey; sl@0: } sl@0: sl@0: void TWindowServerEvent::ConstructDefaultHotKeyL(TInt aHotKey, const TWsWinCmdCaptureKey &aSystemKey) sl@0: { sl@0: CWsHotKey* hotKey=new(ELeave) CWsHotKey(aHotKey, ETrue); sl@0: // hotKey is pushed onto the cleanup stack in method ConstructLD. sl@0: hotKey->ConstructLD(aSystemKey); sl@0: LinkHotKey(hotKey); sl@0: } sl@0: sl@0: CWsHotKey* TWindowServerEvent::ClearHotKeysL(TInt aHotKey) sl@0: { sl@0: if (aHotKey>ENumHotKeys) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: CWsHotKey** pHotKey= &iHotKeys; sl@0: CWsHotKey* defaultHotKey=NULL; sl@0: while(*pHotKey) sl@0: { sl@0: TBool unlinked=EFalse; sl@0: if ((*pHotKey)->HotKeyType()==aHotKey) sl@0: { sl@0: CWsHotKey *free=*pHotKey; sl@0: if (free->IsDefault()) sl@0: { sl@0: free->SetL(ImpossibleKeyPress); sl@0: defaultHotKey=free; sl@0: } sl@0: else sl@0: { sl@0: *pHotKey=(*pHotKey)->iNext; sl@0: delete free; sl@0: unlinked=ETrue; sl@0: } sl@0: } sl@0: if (!unlinked) sl@0: { sl@0: pHotKey=&(*pHotKey)->iNext; sl@0: } sl@0: } sl@0: return(defaultHotKey); sl@0: } sl@0: sl@0: void TWindowServerEvent::ResetDefaultHotKeyL(TInt aHotKey) sl@0: { sl@0: if ((aHotKey<0) || (aHotKey>=ENumHotKeys)) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: CWsHotKey* defaultHotKey=ClearHotKeysL(aHotKey); sl@0: WS_ASSERT_DEBUG(defaultHotKey, EWsPanicDefaultHotKeyNotFound); sl@0: defaultHotKey->SetL(DefaultHotKeys[aHotKey]); sl@0: } sl@0: sl@0: void TWindowServerEvent::SetHotKeyL(const TWsClCmdSetHotKey &aHotKey) sl@0: { sl@0: if (aHotKey.type>ENumHotKeys) sl@0: User::Leave(KErrArgument); sl@0: // sl@0: CWsHotKey *hotKey=new(ELeave) CWsHotKey(aHotKey.type, EFalse); sl@0: // sl@0: TWsWinCmdCaptureKey captureKey; sl@0: captureKey.modifiers=aHotKey.modifiers; sl@0: captureKey.modifierMask=aHotKey.modifierMask; sl@0: captureKey.key=aHotKey.keycode; sl@0: captureKey.priority = 0; sl@0: hotKey->ConstructLD(captureKey); sl@0: // sl@0: LinkHotKey(hotKey); sl@0: } sl@0: sl@0: void TWindowServerEvent::AddEventHandler(MEventHandler *aEventHandler, TBool aAdvancedPointersEnabled) sl@0: { sl@0: #if defined(_DEBUG) sl@0: TRAPD(err,iEventHandlers.AppendL(TRawEventHandler(aEventHandler, aAdvancedPointersEnabled))); sl@0: WS_ASSERT_DEBUG(err==KErrNone, EWsPanicEventHandlerInconsistency); sl@0: #else sl@0: iEventHandlers.AppendL(TRawEventHandler(aEventHandler, aAdvancedPointersEnabled)); //Shouldn't leave sl@0: #endif sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Printf("_WSEVENT_POINTER: TWindowServerEvent::AddEventHandler Added handler = %d AdvancedPointerEnabled = %d", iEventHandlers.Count(),aAdvancedPointersEnabled); sl@0: #endif sl@0: } sl@0: sl@0: void TWindowServerEvent::RemoveEventHandler(const MEventHandler *aEventHandler) sl@0: { sl@0: TInt count=iEventHandlers.Count(); sl@0: TInt ii; sl@0: for(ii=0;ii0) sl@0: { sl@0: iBinaryFlags |= ERemovedEventHandlerWhileProcessingRawEvents; sl@0: iEventHandlers[ii].iEventHandler=NULL; // replace the Handler with null to keep size of the array sl@0: } sl@0: else sl@0: { sl@0: iEventHandlers.Remove(ii); sl@0: } sl@0: return; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void TWindowServerEvent::PotentialEventHandlerL(TInt aNum) sl@0: { sl@0: iPotentialEventHandlers+=aNum; sl@0: WS_ASSERT_DEBUG(iPotentialEventHandlers>=iEventHandlers.Count(), EWsPanicEventHandlerInconsistency); sl@0: TRAPD(err,iEventHandlers.Reserve(iPotentialEventHandlers)); sl@0: if (err!=KErrNone) sl@0: { sl@0: if (aNum>0) sl@0: User::Leave(err); sl@0: } sl@0: else if (iPotentialEventHandlers==0) sl@0: iEventHandlers.Compress(); sl@0: } sl@0: sl@0: void SendSwitchOnEvent(TEventRequestItem *aQptr, TInt aEvent, TInt ) sl@0: { sl@0: aQptr->iWindow->QueueEvent(aEvent); sl@0: } sl@0: sl@0: /*void SendSwitchOffEvent(TEventRequestItem *aQptr, TInt , TInt ) sl@0: { sl@0: aQptr->iWindow->QueueEvent(EEventSwitchOff); sl@0: }*/ sl@0: sl@0: void SendErrorMessage(TEventRequestItem *aQptr, TInt aCategory, TInt aError) sl@0: { sl@0: TWsEvent event; sl@0: event.SetType(EEventErrorMessage); sl@0: event.SetHandle(aQptr->iWindow->ClientHandle()); sl@0: event.ErrorMessage()->iErrorCategory=(TWsErrorMessage::TErrorCategory)aCategory; sl@0: event.ErrorMessage()->iError=aError; sl@0: event.SetTimeNow(); sl@0: aQptr->iWindow->EventQueue()->QueueEvent(event,EEventPriorityHigh); sl@0: } sl@0: sl@0: void SendModifierChangedEvent(TEventRequestItem *aQptr, TInt aChanged, TInt ) sl@0: { sl@0: TInt tmpChanged=aChanged&aQptr->iParam; sl@0: if (tmpChanged) sl@0: { sl@0: TWsEvent event; sl@0: event.SetType(EEventModifiersChanged); sl@0: event.SetHandle(aQptr->iWindow->ClientHandle()); sl@0: event.ModifiersChanged()->iChangedModifiers=tmpChanged; sl@0: event.ModifiersChanged()->iModifiers=TWindowServerEvent::GetStoredModifierState(); sl@0: event.SetTimeNow(); sl@0: aQptr->iWindow->EventQueue()->QueueEvent(event,EEventPriorityHigh); sl@0: } sl@0: } sl@0: sl@0: void TWindowServerEvent::ProcessEventQueue(TEventRequestQueue &aQueue, TSendEventFunc aFunc, TInt aParam1, TInt aParam2) sl@0: { sl@0: TSglQueIter iter(aQueue.Queue()); sl@0: TEventRequestItem *qPtr; sl@0: CWsWindowGroup *focusWin=CWsTop::FocusWindowGroup(); sl@0: while((qPtr=iter++)!=NULL) sl@0: { sl@0: if (qPtr->iCircumstances==EEventControlAlways || sl@0: (qPtr->iCircumstances==EEventControlOnlyWithKeyboardFocus && qPtr->iWindow->WinGroup()==focusWin) || sl@0: (qPtr->iCircumstances==EEventControlOnlyWhenVisible && !qPtr->iWindow->TreeIsObscured())) sl@0: aFunc(qPtr, aParam1, aParam2); sl@0: } sl@0: } sl@0: sl@0: void TWindowServerEvent::NotifyOom() sl@0: { sl@0: TTime now; sl@0: now.UniversalTime(); sl@0: TTimeIntervalSeconds interval; sl@0: TInt err=now.SecondsFrom(iPrevOomMessageTime,interval); sl@0: if (err!=KErrNone || interval.Int()<0 || interval.Int()>EOomEventSecondGap) sl@0: { sl@0: ProcessErrorMessages(TWsErrorMessage::EDrawingRegion,KErrNoMemory); sl@0: iPrevOomMessageTime=now; sl@0: } sl@0: } sl@0: sl@0: TBool TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::TErrorCategory aCategory, TInt aError) sl@0: { sl@0: if (aError!=KErrNone) sl@0: { sl@0: ProcessEventQueue(iErrorMessageQueue, SendErrorMessage, aCategory, aError); sl@0: return ETrue; sl@0: } sl@0: return EFalse; sl@0: } sl@0: sl@0: void TWindowServerEvent::ProcessModifierChanges() sl@0: { sl@0: TInt newState=iKeyTranslator->GetModifierState(); sl@0: if (newState!=iModifierState) sl@0: { sl@0: TInt changed=iModifierState^newState; sl@0: iModifierState=newState; sl@0: ProcessEventQueue(iModifierChangedQueue, SendModifierChangedEvent, changed, 0); sl@0: } sl@0: } sl@0: sl@0: TEventQueueWalkRet FindScreenDeviceChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent) sl@0: { sl@0: if (aEvent->Type()==EEventScreenDeviceChanged && aEvent->Handle()==*(TUint *)aHandlePtr) sl@0: *(TUint *)aHandlePtr=0; // Indicates event found sl@0: return(EEventQueueWalkOk); sl@0: } sl@0: sl@0: void TWindowServerEvent::SendScreenDeviceChangedEvents(CScreen* aScreen) sl@0: { sl@0: TSglQueIter iter(iScreenDeviceChangedQueue .Queue()); sl@0: TEventRequestItem *qPtr; sl@0: while((qPtr=iter++)!=NULL) sl@0: SendScreenDeviceChangedEvent(qPtr->iWindow); sl@0: if(CClick::IsHandler()) sl@0: { sl@0: TClickMakerData clickMakerData; sl@0: clickMakerData.screenDeviceMode=aScreen->ScreenSizeMode(); sl@0: CClick::OtherEvent(EEventScreenDeviceChanged, &clickMakerData); sl@0: } sl@0: TWsEvent wsEvent; sl@0: wsEvent.SetType(EEventScreenDeviceChanged); sl@0: TWindowServerEvent::PublishNotification(wsEvent); sl@0: TWservCrEvent crEvent(TWservCrEvent::EScreenSizeModeChanged,aScreen->ScreenSizeMode()); sl@0: TWindowServerEvent::NotifyDrawer(crEvent); sl@0: } sl@0: sl@0: void TWindowServerEvent::SendScreenDeviceChangedEvent(const CWsWindowBase *aWindow) sl@0: { sl@0: CEventQueue *queue=aWindow->EventQueue(); sl@0: TUint32 handle=aWindow->ClientHandle(); sl@0: queue->WalkEventQueue(&FindScreenDeviceChangedEvent,&handle); sl@0: if (handle!=NULL) // Indicates event not found sl@0: queue->QueueEvent(handle, EEventScreenDeviceChanged); sl@0: } sl@0: sl@0: TEventQueueWalkRet FindGroupChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent) sl@0: { sl@0: if (aEvent->Type()==EEventWindowGroupsChanged && aEvent->Handle()==*(TUint *)aHandlePtr) sl@0: { sl@0: *(TUint *)aHandlePtr=0; // Indicates event found sl@0: } sl@0: return(EEventQueueWalkOk); sl@0: } sl@0: sl@0: void TWindowServerEvent::SendGroupChangedEvents() sl@0: { sl@0: TSglQueIter iter(iGroupChangedQueue.Queue()); sl@0: TEventRequestItem *qPtr; sl@0: while((qPtr=iter++)!=NULL) sl@0: { sl@0: const CWsWindowBase *win=qPtr->iWindow; sl@0: CEventQueue *queue=win->EventQueue(); sl@0: TUint32 handle=win->ClientHandle(); sl@0: queue->WalkEventQueue(&FindGroupChangedEvent,&handle); sl@0: if (handle!=NULL) // Indicates event not found sl@0: { sl@0: queue->QueueEvent(handle, EEventWindowGroupsChanged); sl@0: } sl@0: } sl@0: } sl@0: sl@0: TEventQueueWalkRet FindFocusChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent) sl@0: { sl@0: if (aEvent->Type()==EEventFocusGroupChanged && aEvent->Handle()==*(TUint *)aHandlePtr) sl@0: { sl@0: *(TUint *)aHandlePtr=0; // Indicates event found sl@0: } sl@0: return(EEventQueueWalkOk); sl@0: } sl@0: sl@0: void TWindowServerEvent::SendFocusChangedEvents() sl@0: { sl@0: TInt identifier=0; // Zero Identifier indicates, currently there is no focused window group sl@0: CScreen* currentFocusScreen=CWsTop::CurrentFocusScreen(); sl@0: TInt screenNumber=currentFocusScreen->ScreenNumber(); sl@0: CWsWindowGroup* currentFocusWG=currentFocusScreen->FocusWindowGroup(); sl@0: if(currentFocusWG) sl@0: { sl@0: identifier=currentFocusWG->Identifier(); sl@0: } sl@0: TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EWindowGroupChanged, sl@0: screenNumber, reinterpret_cast(identifier))); sl@0: sl@0: TSglQueIter iter(iFocusChangedQueue.Queue()); sl@0: TEventRequestItem *qPtr; sl@0: while((qPtr=iter++)!=NULL) sl@0: { sl@0: const CWsWindowBase *win=qPtr->iWindow; sl@0: CEventQueue *queue=win->EventQueue(); sl@0: TUint32 handle=win->ClientHandle(); sl@0: queue->WalkEventQueue(&FindFocusChangedEvent,&handle); sl@0: if (handle!=NULL) // Indicates event not found sl@0: { sl@0: queue->QueueEvent(handle, EEventFocusGroupChanged); sl@0: } sl@0: } sl@0: } sl@0: sl@0: TEventQueueWalkRet FindGroupListChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent) sl@0: { sl@0: if (aEvent->Type()==EEventWindowGroupListChanged && aEvent->Handle()==*(TUint *)aHandlePtr) sl@0: { sl@0: *(TUint *)aHandlePtr=0; // Indicates event found sl@0: } sl@0: return(EEventQueueWalkOk); sl@0: } sl@0: sl@0: void TWindowServerEvent::SendGroupListChangedEvents() sl@0: { sl@0: TSglQueIter iter(iGroupListChangedQueue.Queue()); sl@0: TEventRequestItem *qPtr; sl@0: while((qPtr=iter++)!=NULL) sl@0: { sl@0: const CWsWindowBase *win=qPtr->iWindow; sl@0: CEventQueue *queue=win->EventQueue(); sl@0: TUint32 handle=win->ClientHandle(); sl@0: queue->WalkEventQueue(&FindGroupListChangedEvent,&handle); sl@0: if (handle!=NULL) // Indicates event not found sl@0: { sl@0: queue->QueueEvent(handle, EEventWindowGroupListChanged); sl@0: } sl@0: } sl@0: } sl@0: sl@0: TEventQueueWalkRet OverrideVisibilityChangedEvent(TAny *aNewEvent, TWsEvent *aOldEvent) sl@0: { sl@0: // This replaces the first visibility event it finds for the given window with the sl@0: // one given. This is fine, so long as the meaning of all visibility events remains sl@0: // independent of the ones before. sl@0: TWsEvent* newEvent = static_cast(aNewEvent); sl@0: if (aOldEvent->Type()==EEventWindowVisibilityChanged && aOldEvent->Handle()==newEvent->Handle()) sl@0: { sl@0: aOldEvent->SetTimeNow(); sl@0: aOldEvent->VisibilityChanged()->iFlags = newEvent->VisibilityChanged()->iFlags; sl@0: newEvent->SetHandle(NULL); sl@0: } sl@0: return EEventQueueWalkOk; sl@0: } sl@0: sl@0: void TWindowServerEvent::SendVisibilityChangedEvents(CWsWindowBase* aWin, TUint aFlags) sl@0: { sl@0: CEventQueue *queue=aWin->EventQueue(); sl@0: TWsEvent event; sl@0: event.SetType(EEventWindowVisibilityChanged); sl@0: event.SetHandle(aWin->ClientHandle()); sl@0: event.SetTimeNow(); sl@0: TWsVisibilityChangedEvent* visevent = event.VisibilityChanged(); sl@0: visevent->iFlags = aFlags; sl@0: queue->WalkEventQueue(&OverrideVisibilityChangedEvent,&event); sl@0: if (event.Handle()!=NULL) sl@0: { sl@0: queue->QueueEvent(event); sl@0: } sl@0: } sl@0: sl@0: TEventQueueWalkRet OverrideDisplayChangedEvent(TAny *aNewEvent, TWsEvent *aOldEvent) sl@0: { sl@0: TWsEvent* newEvent = static_cast(aNewEvent); sl@0: if (aOldEvent->Type() == EEventDisplayChanged && sl@0: aOldEvent->DisplayChanged()->iDisplayNumber == newEvent->DisplayChanged()->iDisplayNumber) sl@0: { sl@0: aOldEvent->SetTimeNow(); sl@0: aOldEvent->DisplayChanged()->iConfigurationChangeId = newEvent->DisplayChanged()->iConfigurationChangeId; sl@0: aOldEvent->DisplayChanged()->iResolutionListChangeId = newEvent->DisplayChanged()->iResolutionListChangeId; sl@0: newEvent->DisplayChanged()->iDisplayNumber = KErrNotFound; //So the new event won't be placed on event queue again sl@0: } sl@0: return EEventQueueWalkOk; sl@0: } sl@0: sl@0: TBool TWindowServerEvent::SendDisplayChangedEvents(CWsClient* aWsClient, TInt aDisplayNumber, TInt aConfigurationChangeId, TInt aResolutionListChangeId) sl@0: { sl@0: CEventQueue *queue = aWsClient->EventQueue(); sl@0: TWsEvent event; sl@0: event.SetType(EEventDisplayChanged); sl@0: event.SetTimeNow(); sl@0: sl@0: // fill in the handle otherwise CONE will discard the notification sl@0: CWsObjectIx* clientObjList = aWsClient->ObjectIndex(); sl@0: const TWsObject* ptr=clientObjList->FirstObject(); sl@0: const TWsObject* end=ptr+clientObjList->Length(); sl@0: while(++ptriObject; sl@0: if (obj && obj->Type()==WS_HANDLE_GROUP_WINDOW) sl@0: { sl@0: event.SetHandle(ptr->iHandle); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: TWsDisplayChangedEvent* dispEvent = event.DisplayChanged(); sl@0: dispEvent->iDisplayNumber = aDisplayNumber; sl@0: dispEvent->iConfigurationChangeId = aConfigurationChangeId; sl@0: dispEvent->iResolutionListChangeId = aResolutionListChangeId; sl@0: queue->WalkEventQueue(&OverrideDisplayChangedEvent, &event); sl@0: //place the new event on the queue only when its display number is valid (!=KErrNotFound) sl@0: if(event.DisplayChanged()->iDisplayNumber >= 0) sl@0: { sl@0: return queue->QueueEvent(event); sl@0: } sl@0: return ETrue; sl@0: } sl@0: sl@0: void TWindowServerEvent::QueueKeyEvent(CWsWindowGroup *aWin, TWsEvent &aEvent, TWservEventPriorities aPriority) sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Print(_L("_WSEVENT_KEY: TWindowServerEvent::QueueKeyEvent, Queuing event name %S for application read, window handle: %d"), &WsEventName(aEvent), CWsTop::FocusWindowGroup()->ClientHandle()); sl@0: #endif sl@0: aEvent.SetTimeNow(); sl@0: aWin->EventQueue()->QueueEvent(aEvent, aPriority); sl@0: } sl@0: sl@0: /** sl@0: Process a key press event. sl@0: sl@0: This function is called for every input key event and uses the Key Event sl@0: Routing plug-in to check for short and long key capture and determine the sl@0: destination window group for the queued event(s). sl@0: Window server hotkeys are also processed. sl@0: Note that the key repeat timer is started here but the key repeat events sl@0: generated by the timer go directly to QueueKeyPress(). sl@0: sl@0: @param aKeyEvent Input key event sl@0: @param aCheckRepeat Check for key repeat and long key capture sl@0: @param aRepeats Repeat count sl@0: */ sl@0: void TWindowServerEvent::ProcessKeyPress(const TKeyEvent& aKeyEvent, TBool aCheckRepeat, TInt aRepeats) sl@0: { sl@0: CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup(); sl@0: TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid; sl@0: sl@0: // Route the key event and check for short key capture. sl@0: // Note that the Key Routing plugin may translate or block key events. sl@0: TKeyEventRouterInput input(ECaptureTypeKey, aKeyEvent, focusWin, focusAppUid); sl@0: TKeyEventRouterOutput output; sl@0: sl@0: #ifdef _DEBUG sl@0: // RouteKey() must not fail. Check for leaves in case the plug-in sl@0: // is badly behaved. sl@0: TRAPD(err, iKeyEventRouter->RouteKey(input, output)); sl@0: WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave); sl@0: #else sl@0: iKeyEventRouter->RouteKey(input, output); sl@0: #endif sl@0: sl@0: WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured || output.iResult == EConsumed, EWsPanicKeyEventRouterBadResult); sl@0: sl@0: if (output.iResult == EConsumed) sl@0: { sl@0: focusWin = NULL; sl@0: } sl@0: else sl@0: { sl@0: focusWin = static_cast(output.iWindowGroup); sl@0: } sl@0: WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup); sl@0: sl@0: // Ensure that short event is not marked with EModifierLongKey sl@0: output.iKeyEvent.iModifiers &= ~EModifierLongKey; sl@0: sl@0: // Generate key click unless the event is consumed. This is consistent sl@0: // with the behaviour when CKeyTranslator::TranslateKey() yields no sl@0: // translation for a particular scan code. (Click events for key up/down sl@0: // will still be generated by QueueKeyUpDown()). Note however that a long sl@0: // key press may still be captured even if the short event is consumed. sl@0: if (CClick::IsHandler() && output.iResult != EConsumed) sl@0: { sl@0: output.iKeyEvent.iRepeats = aRepeats; sl@0: CClick::KeyEvent(EEventKey, output.iKeyEvent); sl@0: } sl@0: sl@0: if (output.iResult == ECaptured) sl@0: { sl@0: if (output.iWindowGroup == NULL) // Captured by Wserv itself sl@0: { sl@0: _LIT(KWSERVDebugLogCapturedKey,"WSERV Captured Key"); sl@0: CScreen* focusScreen=CWsTop::CurrentFocusScreen(); sl@0: TInt screenNo=focusScreen->ScreenNumber(); sl@0: sl@0: if (wsDebugLog) sl@0: wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogCapturedKey); sl@0: CWsHotKey *hotKey=iHotKeys; sl@0: while(hotKey) sl@0: { sl@0: if (hotKey->KeyHandle() == reinterpret_cast(output.iCaptureHandle)) sl@0: { sl@0: switch(hotKey->HotKeyType()) sl@0: { sl@0: case EHotKeyEnableLogging: sl@0: CWsTop::EnableLogging(); sl@0: break; sl@0: case EHotKeyDisableLogging: sl@0: CWsTop::DisableLogging(); sl@0: break; sl@0: case EHotKeyStateDump: sl@0: StateDump(); sl@0: break; sl@0: case EHotKeyHeapDump: sl@0: HeapDump(); sl@0: break; sl@0: case EHotKeyOfDeath: sl@0: if (!CWsPassword::PasswordModeActive()) sl@0: { sl@0: const TBool currentJustInTimeValue=User::JustInTime(); sl@0: if (currentJustInTimeValue) sl@0: { sl@0: User::SetJustInTime(EFalse); sl@0: } sl@0: CWsTop::KillForegroundSession(); sl@0: if (currentJustInTimeValue) sl@0: { sl@0: User::SetJustInTime(ETrue); sl@0: } sl@0: } sl@0: break; sl@0: case EHotKeyShutDown: sl@0: CWsTop::Exit(); sl@0: break; sl@0: case EHotKeyIncContrast: sl@0: focusScreen->IncContrast(); sl@0: break; sl@0: case EHotKeyDecContrast: sl@0: focusScreen->DecContrast(); sl@0: break; sl@0: case EHotKeyOff: sl@0: CWsTop::HandleSwitchOff(EEventKeySwitchOff,ETrue); sl@0: break; sl@0: case EHotKeyBacklightToggle: sl@0: { sl@0: TInt state; sl@0: if (!ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(screenNo,HALData::EBacklightState,state))) sl@0: ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(screenNo,HALData::EBacklightState,!state)); sl@0: } sl@0: break; sl@0: case EHotKeyBacklightOn: sl@0: ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(screenNo,HALData::EBacklightState,ETrue)); sl@0: break; sl@0: case EHotKeyBacklightOff: sl@0: ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(screenNo,HALData::EBacklightState,EFalse)); sl@0: break; sl@0: case EHotKeyScreenDimension0: sl@0: case EHotKeyScreenDimension1: sl@0: case EHotKeyScreenDimension2: sl@0: case EHotKeyScreenDimension3: sl@0: focusScreen->doSetScreenMode(hotKey->HotKeyType()-EHotKeyScreenDimension0); sl@0: break; sl@0: case EHotKeyCycleDisplaySize: sl@0: focusScreen->CycleDisplaySize(); sl@0: break; sl@0: case EHotKeyCycleOrientation: sl@0: focusScreen->CycleOrientation(); sl@0: break; sl@0: case EHotKeyIncBrightness: sl@0: focusScreen->IncBrightness(); sl@0: break; sl@0: case EHotKeyDecBrightness: sl@0: focusScreen->DecBrightness(); sl@0: break; sl@0: case EHotKeyCycleFocusScreen: sl@0: CWsTop::SetCurrentFocusScreen((CWsTop::CurrentFocusScreen()->ScreenNumber()+1)%CWsTop::NumberOfScreens()); sl@0: break; sl@0: } sl@0: return; sl@0: } sl@0: hotKey=hotKey->iNext; sl@0: } sl@0: WS_PANIC_ALWAYS(EWsPanicUnknownCaptureKey); sl@0: return; sl@0: } sl@0: sl@0: _LIT(KWSERVDebugLogKeyCapturedByApp,"Key captured by app %d"); sl@0: if (wsDebugLog) sl@0: wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyCapturedByApp,focusWin->Identifier()); sl@0: if (CWsPassword::PasswordModeActive() && focusWin!=CWsPassword::PasswordWindow()->WinGroup()) sl@0: return; sl@0: } sl@0: sl@0: CWsCaptureLongKey* longCapture = NULL; sl@0: TKeyEventRouterOutput longOutput; sl@0: if (aCheckRepeat) sl@0: { sl@0: // Check for long key capture. sl@0: // Note that a long key event can only result from capture, there is sl@0: // no default detection or routing of long events. sl@0: input.iType = ECaptureTypeLongKey; sl@0: #ifdef _DEBUG sl@0: TRAPD(err, iKeyEventRouter->RouteKey(input, longOutput)); sl@0: WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave); sl@0: #else sl@0: iKeyEventRouter->RouteKey(input, longOutput); sl@0: #endif sl@0: sl@0: if (longOutput.iResult == ECaptured) sl@0: { sl@0: longCapture = static_cast(longOutput.iCaptureHandle); sl@0: sl@0: // Mark long key events with EModifierLongKey so that applications sl@0: // can easily distinguish short and long events. sl@0: longOutput.iKeyEvent.iModifiers |= EModifierLongKey; sl@0: sl@0: // Start timer to detect long key press sl@0: CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, &longOutput); sl@0: } sl@0: else if (output.iResult != EConsumed && output.iKeyEvent.iModifiers & EModifierAutorepeatable) sl@0: { sl@0: // Start timer for key repeat sl@0: CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, NULL); sl@0: } sl@0: } sl@0: sl@0: // Queue the short event sl@0: if (!longCapture || longCapture->iFlags & ELongCaptureShortEventImmediately) sl@0: { sl@0: QueueKeyPress(output, EFalse, aRepeats); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Queue a key press event. sl@0: sl@0: This function is called for each key event produced by ProcessKeyPress(), sl@0: for every key repeat and long key event generated by the timer and also for sl@0: delayed short key events from KeyUp(). sl@0: sl@0: @param aOutput Output key event from routing plug-in sl@0: @param aIsRepeat Event is due to key repeat sl@0: @param aRepeats Repeat count sl@0: */ sl@0: void TWindowServerEvent::QueueKeyPress(const TKeyEventRouterOutput& aOutput, TBool aIsRepeat, TInt aRepeats) sl@0: { sl@0: if (aOutput.iResult == EConsumed) sl@0: { sl@0: // Don't deliver this key sl@0: return; sl@0: } sl@0: sl@0: TWsEvent event; sl@0: TKeyEvent& keyEvent = *event.Key(); sl@0: keyEvent = aOutput.iKeyEvent; sl@0: keyEvent.iRepeats = aRepeats; sl@0: sl@0: CWsWindowGroup* focusWin = static_cast(aOutput.iWindowGroup); sl@0: WS_ASSERT_DEBUG(focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW, EWsPanicKeyEventRouterBadWindowGroup); sl@0: sl@0: if (aIsRepeat && aOutput.iResult != ECaptured && focusWin != CWsTop::FocusWindowGroup()) sl@0: CKeyboardRepeat::CancelRepeat(NULL); // Repeat is going to different window so cancel it and don't deliver this key sl@0: else if (focusWin != NULL && focusWin->CheckForPriorityKey(keyEvent) == EFalse) sl@0: { sl@0: event.SetType(EEventKey); sl@0: event.SetHandle(focusWin->ClientHandle()); sl@0: if (aRepeats!=0) sl@0: { sl@0: CEventQueue* queue=focusWin->EventQueue(); sl@0: queue->Wait(); sl@0: const TWsEvent* prev=queue->PeekLastEvent(); sl@0: if (prev != NULL && prev->Type() == EEventKey && prev->Key()->iRepeats > 0 && prev->Key()->iCode == keyEvent.iCode) sl@0: { sl@0: prev->Key()->iRepeats += aRepeats; sl@0: queue->Signal(); sl@0: if (CClick::IsHandler()) sl@0: CClick::KeyEvent(EEventKeyRepeat, *prev->Key()); sl@0: return; sl@0: } sl@0: queue->Signal(); sl@0: if (CClick::IsHandler()) sl@0: CClick::KeyEvent(EEventKeyRepeat,keyEvent); sl@0: } sl@0: QueueKeyEvent(focusWin, event, EEventPriorityLow); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Queue a key up/down event. sl@0: sl@0: @param aRawEvent Raw event sl@0: */ sl@0: void TWindowServerEvent::QueueKeyUpDown(const TRawEvent &aRawEvent) sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Print(_L("_WSEVENT_KEY: TWindowServerEvent::QueueKeyUpDown, Event Name: %S, Scan code: %d"), &RawEventName(aRawEvent), aRawEvent.ScanCode()); sl@0: #endif sl@0: TEventCode type = aRawEvent.Type() == TRawEvent::EKeyUp ? EEventKeyUp : EEventKeyDown; sl@0: sl@0: // Check for key up/down capture sl@0: TKeyEvent keyEvent; sl@0: keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; sl@0: #if defined(__WINS__) sl@0: keyEvent.iCode = __WINS_CHARCODE(aRawEvent.ScanCode()); sl@0: #else sl@0: keyEvent.iCode = 0; sl@0: #endif sl@0: keyEvent.iModifiers = iModifierState; sl@0: keyEvent.iRepeats = 0; sl@0: sl@0: CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup(); sl@0: TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid; sl@0: sl@0: TKeyEventRouterInput input(ECaptureTypeKeyUpDown, keyEvent, focusWin, focusAppUid); sl@0: TKeyEventRouterOutput output; sl@0: #ifdef _DEBUG sl@0: TRAPD(err, iKeyEventRouter->RouteKey(input, output)); sl@0: WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave); sl@0: #else sl@0: iKeyEventRouter->RouteKey(input, output); sl@0: #endif sl@0: sl@0: if (output.iResult == EConsumed) sl@0: { sl@0: // Don't deliver this key. A key click is still generated for the sl@0: // input event. sl@0: if (CClick::IsHandler()) sl@0: { sl@0: CClick::KeyEvent(type, keyEvent); sl@0: } sl@0: return; sl@0: } sl@0: WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured, EWsPanicKeyEventRouterBadResult); sl@0: sl@0: focusWin = static_cast(output.iWindowGroup); sl@0: WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup); sl@0: #if defined(__WINS__) sl@0: if (focusWin && !focusWin->WsOwner()->RemoveKeyCode()) sl@0: { sl@0: // Restore WINS character code sl@0: output.iKeyEvent.iScanCode |= output.iKeyEvent.iCode; sl@0: } sl@0: output.iKeyEvent.iCode = 0; sl@0: #endif sl@0: sl@0: output.iKeyEvent.iRepeats = 0; sl@0: if (CClick::IsHandler()) sl@0: { sl@0: CClick::KeyEvent(type, output.iKeyEvent); sl@0: } sl@0: sl@0: TWsEvent event; sl@0: *event.Key() = output.iKeyEvent; sl@0: if (focusWin!=NULL) sl@0: { sl@0: event.SetType(type); sl@0: event.SetHandle(focusWin->ClientHandle()); sl@0: QueueKeyEvent(focusWin, event, EEventPriorityHigh); sl@0: } sl@0: } sl@0: sl@0: LOCAL_D void GetPointerEvent(TPointerEvent::TType& aType, const TRawEvent &aRawEvent, TBool& aHandled) sl@0: { sl@0: aHandled=ETrue; sl@0: switch(aRawEvent.Type()) sl@0: { sl@0: case TRawEvent::EButton1Down: sl@0: aType=TPointerEvent::EButton1Down; sl@0: break; sl@0: case TRawEvent::EButton1Up: sl@0: aType=TPointerEvent::EButton1Up; sl@0: break; sl@0: case TRawEvent::EButton2Down: sl@0: aType=TPointerEvent::EButton2Down; sl@0: break; sl@0: case TRawEvent::EButton2Up: sl@0: aType=TPointerEvent::EButton2Up; sl@0: break; sl@0: case TRawEvent::EButton3Down: sl@0: aType=TPointerEvent::EButton3Down; sl@0: break; sl@0: case TRawEvent::EButton3Up: sl@0: aType=TPointerEvent::EButton3Up; sl@0: break; sl@0: case TRawEvent::EPointerMove: sl@0: aType=TPointerEvent::EMove; sl@0: break; sl@0: case TRawEvent::EPointerSwitchOn: sl@0: aType=TPointerEvent::ESwitchOn; sl@0: break; sl@0: case TRawEvent::EPointer3DOutOfRange: sl@0: aType=TPointerEvent::EOutOfRange; sl@0: break; sl@0: default: sl@0: aHandled=EFalse; sl@0: } sl@0: } sl@0: sl@0: TBool TWindowServerEvent::MousePress(const TRawEvent &aRawEvent, const CWsWindowGroup *aGroupWin) sl@0: // sl@0: //Return EFalse if known not to be a Mouse Event sl@0: // sl@0: { sl@0: TBool handled=ETrue; sl@0: TPointerEvent::TType type; sl@0: GetPointerEvent(type, aRawEvent, handled); sl@0: if (handled) sl@0: { sl@0: TPoint3D point3D(0,0,0); sl@0: if (type != TPointerEvent::EOutOfRange) sl@0: { sl@0: point3D = aRawEvent.Pos3D(); sl@0: } sl@0: TWsEvent event; sl@0: TAdvancedPointerEventHelper::InitAdvancedPointerEvent(event, type,iKeyTranslator->GetModifierState(),point3D,aRawEvent.PointerNumber()); sl@0: TWsPointer::ProcessWsEvent(event, aGroupWin, ETrue); sl@0: } sl@0: return handled; sl@0: } sl@0: sl@0: LOCAL_D void SendEventToKeyClick(const TRawEvent& aRawEvent) sl@0: { sl@0: switch(aRawEvent.Type()) sl@0: { sl@0: case TRawEvent::EKeyDown: sl@0: case TRawEvent::EKeyUp: sl@0: { sl@0: TKeyEvent keyEvent; sl@0: keyEvent.iCode=0; sl@0: keyEvent.iScanCode=aRawEvent.ScanCode(); sl@0: keyEvent.iModifiers=0; sl@0: keyEvent.iRepeats=0; sl@0: CClick::KeyEvent(EEventKey,keyEvent); sl@0: } sl@0: break; sl@0: case TRawEvent::EButton1Down: sl@0: case TRawEvent::EButton1Up: sl@0: case TRawEvent::EButton2Down: sl@0: case TRawEvent::EButton2Up: sl@0: case TRawEvent::EButton3Down: sl@0: case TRawEvent::EButton3Up: sl@0: case TRawEvent::EPointerMove: sl@0: case TRawEvent::EPointerSwitchOn: sl@0: { sl@0: TBool handled=ETrue; sl@0: TPointerEvent::TType type; sl@0: GetPointerEvent(type, aRawEvent, handled); sl@0: if (handled) sl@0: { sl@0: TWsEvent event; sl@0: TAdvancedPointerEventHelper::InitAdvancedPointerEvent(event, type, 0, aRawEvent.Pos3D(), TPoint(), aRawEvent.PointerNumber()); sl@0: TAdvancedPointerEvent& pointerEvent = *event.Pointer(); sl@0: CClick::PointerEvent(pointerEvent.iPosition,pointerEvent); sl@0: } sl@0: } sl@0: break; sl@0: default: sl@0: break; sl@0: } sl@0: } sl@0: sl@0: /* sl@0: Process a raw event sl@0: sl@0: @param aRawEvent Raw event sl@0: */ sl@0: void TWindowServerEvent::ProcessRawEvent(const TRawEvent& aRawEvent) sl@0: // sl@0: // Event has completed. sl@0: // sl@0: { sl@0: TRawEvent::TType eventType = aRawEvent.Type(); sl@0: TBool isPointerEvent = TWsPointer::IsPointerEventType(eventType); sl@0: if (isPointerEvent) sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Print(_L("_WSEVENT_POINTER: TWindowServerEvent::ProcessRawEvent EventName = %S PointerNumber = %d PrimaryPointerNumber = %d Coordinates = ( %d, %d )"), sl@0: &RawEventName(aRawEvent),aRawEvent.PointerNumber(),TWsPointer::PrimaryPointer(),aRawEvent.Pos().iX,aRawEvent.Pos().iY); sl@0: #endif sl@0: TWsPointer::UpdatePrimaryPointer(aRawEvent); sl@0: } sl@0: TInt count=iEventHandlers.Count(); sl@0: TInt ii; sl@0: TBool eventHandled = EFalse; sl@0: iEventHandlerCount++; sl@0: for(ii=0;iiOfferRawEvent(aRawEvent)) sl@0: { sl@0: if (CClick::IsHandler()) sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Print(_L("_WSEVENT_KEY: Send event %S for Key Click"), &RawEventName(aRawEvent)); sl@0: #endif sl@0: SendEventToKeyClick(aRawEvent); sl@0: } sl@0: eventHandled = ETrue; sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Printf("_WSEVENT_POINTER: TWindowServerEvent::ProcessRawEvent Event Consumed by ANIM.dll Handler No = %d Advanced Pointer Enabled = %d",ii,handler.iAdvancedPointersEnabled); sl@0: #endif sl@0: break; sl@0: } sl@0: } sl@0: if (--iEventHandlerCount == 0) sl@0: { sl@0: if (ERemovedEventHandlerWhileProcessingRawEvents & iBinaryFlags) // Handler was deleted while previous loop sl@0: { sl@0: iBinaryFlags &= ~ERemovedEventHandlerWhileProcessingRawEvents; sl@0: for(ii=count-1;ii>=0;--ii) sl@0: { sl@0: if (iEventHandlers[ii].iEventHandler==NULL) iEventHandlers.Remove(ii); sl@0: } sl@0: } sl@0: } sl@0: if (eventHandled) sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Printf("_WSEVENT: Event is already handled by anim dll not by window server"); sl@0: // This is to determine when we press the power button which bring power dialog sl@0: // whether it is a pointer event or key event sl@0: // Also when we plugin the charging cable this is to determine whether it is a pointer event or key event sl@0: RDebug::Print(_L("_WSEVENT: RawEvent Name = %S"), &RawEventName(aRawEvent)); sl@0: #endif sl@0: if (isPointerEvent) sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Printf("_WSEVENT_POINTER: TWindowServerEvent::ProcessRawEvent Pointer Number= %d State = %x XY(%d,%d)",TWsPointer::iPointers[0].iNumber,TWsPointer::iPointers[0].iState,TWsPointer::iPointers[0].iPos.iX,TWsPointer::iPointers[0].iPos.iY); sl@0: RDebug::Printf("_WSEVENT_POINTER: TWindowServerEvent::ProcessRawEvent Pointer Number= %d State = %x XY(%d,%d)",TWsPointer::iPointers[1].iNumber,TWsPointer::iPointers[1].iState,TWsPointer::iPointers[1].iPos.iX,TWsPointer::iPointers[1].iPos.iY); sl@0: #endif sl@0: //Prevention of the phone pointer event "dead lock". sl@0: TPointerEvent::TType type; sl@0: TBool handled = ETrue; sl@0: GetPointerEvent(type, aRawEvent, handled); sl@0: switch(type) sl@0: { sl@0: case TPointerEvent::EButton1Down: sl@0: case TPointerEvent::EButton2Down: sl@0: case TPointerEvent::EButton3Down: sl@0: TWsPointer::iPointers[aRawEvent.PointerNumber()].iState = TWsPointer::EPointerStateDown; sl@0: break; sl@0: case TPointerEvent::EButton1Up: sl@0: case TPointerEvent::EButton2Up: sl@0: case TPointerEvent::EButton3Up: sl@0: TWsPointer::iPointers[aRawEvent.PointerNumber()].iState = TWsPointer::EPointerStateUp; sl@0: break; sl@0: case TPointerEvent::EOutOfRange: sl@0: TWsPointer::iPointers[aRawEvent.PointerNumber()].iState = TWsPointer::EPointerStateOutOfRange; sl@0: break; sl@0: default: sl@0: break; sl@0: } sl@0: } sl@0: return; sl@0: } sl@0: sl@0: switch(eventType) sl@0: { sl@0: case TRawEvent::ERedraw: sl@0: CWsTop::RedrawScreens(); sl@0: break; sl@0: case TRawEvent::ESwitchOn: sl@0: case TRawEvent::ECaseOpen: sl@0: { sl@0: TInt event=EEventCaseOpened; sl@0: CKeyboardRepeat::CancelRepeat(NULL); sl@0: CWsPassword::SwitchOn(); sl@0: if (eventType==TRawEvent::ESwitchOn) sl@0: { sl@0: UserSvr::WsSwitchOnScreen(); sl@0: HAL::Set(HALData::EDisplayState,1); sl@0: event=EEventSwitchOn; sl@0: } sl@0: ProcessEventQueue(iSwitchOnQueue, SendSwitchOnEvent, event, 0); sl@0: break; sl@0: } sl@0: case TRawEvent::ESwitchOff: sl@0: case TRawEvent::ECaseClose: sl@0: { sl@0: TBool switchOff=(eventType==TRawEvent::ESwitchOff); sl@0: CWsTop::HandleSwitchOff(switchOff? EEventSwitchOff:EEventCaseClosed,switchOff); sl@0: break; sl@0: } sl@0: #ifdef SYMBIAN_PROCESS_MONITORING_AND_STARTUP sl@0: case TRawEvent::ERestartSystem: sl@0: { /* restart event being handled */ sl@0: CWsTop::HandleSwitchOff(EEventRestartSystem,ETrue); sl@0: break; sl@0: } sl@0: #endif sl@0: case TRawEvent::EInactive: sl@0: #ifndef __WINS__ sl@0: CWsTop::WindowServer()->AnimationScheduler()->OnInactive(); sl@0: #endif sl@0: CKeyboardRepeat::CancelRepeat(NULL); sl@0: break; sl@0: case TRawEvent::EActive: sl@0: #ifndef __WINS__ sl@0: CWsTop::WindowServer()->AnimationScheduler()->OnActive(); sl@0: #endif sl@0: break; sl@0: case TRawEvent::EKeyDown: sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Printf("_WSEVENT_KEY: TRawEvent::EKeyDown"); sl@0: #endif sl@0: _LIT(KWSERVDebugLogKeyDownArrival,"Key down arrives %d"); sl@0: CScreen* screen = CWsTop::Screen(); sl@0: WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen); sl@0: if(CDebugBar* dbg = screen->DebugBar()) sl@0: dbg->OnKeyEvent(); sl@0: if (wsDebugLog) sl@0: wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyDownArrival,aRawEvent.ScanCode()); sl@0: CKeyboardRepeat::KeyDown(); sl@0: TKeyData keyData; sl@0: // Note iCaptureKeys is needed as dummy arg only. Key capture is sl@0: // now handled in ProcessKeyPress(). sl@0: TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), EFalse,*iCaptureKeys,keyData); sl@0: ProcessModifierChanges(); sl@0: QueueKeyUpDown(aRawEvent); sl@0: if (translated) sl@0: { sl@0: TKeyEvent keyEvent; sl@0: keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; sl@0: keyEvent.iCode = keyData.iKeyCode; sl@0: keyEvent.iModifiers = keyData.iModifiers; sl@0: ProcessKeyPress(keyEvent, ETrue, 0); sl@0: } sl@0: } sl@0: break; sl@0: case TRawEvent::EKeyUp: sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Printf("_WSEVENT_KEY: TRawEvent::EKeyUp"); sl@0: #endif sl@0: _LIT(KWSERVDebugLogKeyUpArrival,"Key up arrives %d"); sl@0: CScreen* screen = CWsTop::Screen(); sl@0: WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen); sl@0: if(CDebugBar* dbg = screen->DebugBar()) sl@0: dbg->OnKeyEvent(); sl@0: if (wsDebugLog) sl@0: wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyUpArrival,aRawEvent.ScanCode()); sl@0: TKeyData keyData; sl@0: CKeyboardRepeat::KeyUp(aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE); sl@0: TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), ETrue,*iCaptureKeys,keyData); sl@0: ProcessModifierChanges(); sl@0: QueueKeyUpDown(aRawEvent); sl@0: if (translated) sl@0: { sl@0: CKeyboardRepeat::CancelRepeat(NULL); sl@0: TKeyEvent keyEvent; sl@0: keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; sl@0: keyEvent.iCode = keyData.iKeyCode; sl@0: keyEvent.iModifiers = keyData.iModifiers; sl@0: ProcessKeyPress(keyEvent, EFalse, 0); sl@0: } sl@0: } sl@0: break; sl@0: case TRawEvent::EButton1Down: sl@0: case TRawEvent::EButton2Down: sl@0: case TRawEvent::EButton3Down: sl@0: case TRawEvent::EPointerSwitchOn: sl@0: #ifndef __WINS__ sl@0: CWsTop::WindowServer()->AnimationScheduler()->OnActive(); sl@0: #endif sl@0: // fall through sl@0: case TRawEvent::EButton1Up: sl@0: case TRawEvent::EButton2Up: sl@0: case TRawEvent::EButton3Up: sl@0: case TRawEvent::EPointerMove: sl@0: case TRawEvent::EPointer3DOutOfRange: sl@0: #if defined(_DEBUG) sl@0: WS_ASSERT_DEBUG(MousePress(aRawEvent,NULL), EWsPanicEventType); sl@0: #else sl@0: MousePress(aRawEvent,NULL); sl@0: #endif sl@0: break; sl@0: case TRawEvent::EUpdateModifiers: sl@0: iKeyTranslator->UpdateModifiers(aRawEvent.Modifiers()); sl@0: break; sl@0: case TRawEvent::EKeyRepeat: sl@0: { sl@0: _LIT(KWSERVDebugLogRepeatingKeyArrival,"Repeating key arrives %d"); sl@0: if (wsDebugLog) sl@0: wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogRepeatingKeyArrival,aRawEvent.ScanCode()); sl@0: TKeyEvent keyEvent; sl@0: keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; sl@0: keyEvent.iCode = aRawEvent.ScanCode(); sl@0: keyEvent.iModifiers = iKeyTranslator->GetModifierState(); sl@0: ProcessKeyPress(keyEvent, EFalse, aRawEvent.Repeats()); sl@0: } sl@0: break; sl@0: default: sl@0: break; sl@0: } sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Printf("_WSEVENT_POINTER: TWindowServerEvent::ProcessRawEvent Number= %d State = %x XY(%d,%d)",TWsPointer::iPointers[0].iNumber,TWsPointer::iPointers[0].iState,TWsPointer::iPointers[0].iPos.iX,TWsPointer::iPointers[0].iPos.iY); sl@0: RDebug::Printf("_WSEVENT_POINTER: TWindowServerEvent::ProcessRawEvent Number= %d State = %x XY(%d,%d)",TWsPointer::iPointers[1].iNumber,TWsPointer::iPointers[1].iState,TWsPointer::iPointers[1].iPos.iX,TWsPointer::iPointers[1].iPos.iY); sl@0: #endif sl@0: } sl@0: sl@0: void TWindowServerEvent::ProcessKeyEvent(const TKeyEvent &aKeyEvent,TInt aRepeats) sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Printf("_WSEVENT_KEY: TWindowServerEvent::ProcessKeyEvent, key code: %d, repeat: %d", aKeyEvent.iCode, aRepeats); sl@0: #endif sl@0: TKeyData keyData; sl@0: keyData.iModifiers=aKeyEvent.iModifiers; sl@0: keyData.iApp=0; sl@0: keyData.iHandle=0; sl@0: keyData.iIsCaptureKey=EFalse; sl@0: keyData.iKeyCode=aKeyEvent.iCode; sl@0: if (CKeyboardRepeat::IsAreadyActive()) sl@0: { sl@0: CKeyboardRepeat::CancelRepeat(NULL); sl@0: } sl@0: ProcessKeyPress(aKeyEvent, aRepeats == 0, aRepeats); sl@0: } sl@0: sl@0: void TWindowServerEvent::AddCaptureKeyL(const TKeyCaptureRequest& aRequest) sl@0: { sl@0: iKeyEventRouter->AddCaptureKeyL(aRequest); sl@0: } sl@0: sl@0: void TWindowServerEvent::UpdateCaptureKeyL(const TKeyCaptureRequest& aRequest) sl@0: { sl@0: iKeyEventRouter->UpdateCaptureKeyL(aRequest); sl@0: } sl@0: sl@0: void TWindowServerEvent::CancelCaptureKey(TKeyCaptureType aType, TAny* aHandle) sl@0: { sl@0: iKeyEventRouter->CancelCaptureKey(aType, aHandle); sl@0: } sl@0: sl@0: TInt TWindowServerEvent::GetModifierState() sl@0: { sl@0: return(iKeyTranslator->GetModifierState()); sl@0: } sl@0: sl@0: void TWindowServerEvent::SetModifierState(TEventModifier aModifier,TModifierState aState) sl@0: { sl@0: iKeyTranslator->SetModifierState(aModifier,aState); sl@0: } sl@0: sl@0: TInt TWindowServerEvent::AddNotificationHandler(CAnim* aAnim, TUint32 aNotifications) sl@0: { sl@0: SNotificationHandler notif; sl@0: notif.iAnim = aAnim; sl@0: notif.iNotifications = aNotifications; sl@0: sl@0: // update the entry if the anim is already in the array sl@0: TInt count=iNotificationHandlers->Count(); sl@0: TInt ii; sl@0: for(ii=0;iiAppendL(notif)); sl@0: return err; sl@0: } sl@0: sl@0: void TWindowServerEvent::RemoveNotificationHandler(CAnim* aAnim) sl@0: { sl@0: TInt count=iNotificationHandlers->Count(); sl@0: TInt ii; sl@0: for(ii=0;iiDelete(ii); sl@0: return; sl@0: } sl@0: } sl@0: } sl@0: sl@0: void TWindowServerEvent::PublishNotification(const TWsEvent& aWsEvent) sl@0: { sl@0: TInt count=iNotificationHandlers->Count(); sl@0: TInt ii; sl@0: for(ii=0;iiHandleNotification(aWsEvent); sl@0: } sl@0: break; sl@0: case EEventHeartbeatTimerStateChange: sl@0: if (notif.iNotifications & EHeartbeatTimer) sl@0: { sl@0: notif.iAnim->HandleNotification(aWsEvent); sl@0: } sl@0: break; sl@0: case EEventScreenDeviceChanged: sl@0: if (notif.iNotifications & EScreenDeviceChange) sl@0: { sl@0: notif.iAnim->HandleNotification(aWsEvent); sl@0: } sl@0: break; sl@0: default: sl@0: break; sl@0: } sl@0: } sl@0: sl@0: } sl@0: sl@0: TBool TWindowServerEvent::DrawerCompareFunc(const TDrawerHandler& lhs, const TDrawerHandler& rhs) sl@0: { sl@0: return lhs.iDrawer == rhs.iDrawer; sl@0: } sl@0: sl@0: TInt TWindowServerEvent::RegisterDrawerHandler(CWsGraphicDrawer* aDrawer, TUint32 aEvents) sl@0: { sl@0: TInt idx = iDrawerHandlers->Find(TDrawerHandler(aDrawer, aEvents), sl@0: TIdentityRelation(TWindowServerEvent::DrawerCompareFunc)); sl@0: if (idx != KErrNotFound) sl@0: { sl@0: // replace event mask for this drawer sl@0: (*iDrawerHandlers)[idx].iEvents = aEvents; sl@0: idx = KErrNone; sl@0: } sl@0: else sl@0: idx = iDrawerHandlers->Append(TDrawerHandler(aDrawer,aEvents)); sl@0: sl@0: return idx; sl@0: } sl@0: sl@0: TInt TWindowServerEvent::UnregisterDrawerHandler(CWsGraphicDrawer* aDrawer) sl@0: { sl@0: TInt idx = iDrawerHandlers->Find(TDrawerHandler(aDrawer,0), sl@0: TIdentityRelation(TWindowServerEvent::DrawerCompareFunc)); sl@0: if (idx == KErrNotFound) sl@0: return idx; sl@0: (*iDrawerHandlers)[idx].iDrawer = NULL; //NotifyDrawer() will clean up the array sl@0: return KErrNone; sl@0: } sl@0: sl@0: TInt TWindowServerEvent::RegisterWsEventHandler(MWsEventHandler * aHandler, TUint32 aEvents) sl@0: { sl@0: TWsEventHandler handler(aHandler, aEvents); sl@0: TInt idx = iWsEventHandlers.Find(handler, TIdentityRelation(TWsEventHandler::CompareHandler)); sl@0: if (idx < 0) sl@0: { sl@0: TInt err = iWsEventHandlers.Append(handler); sl@0: return err; sl@0: } sl@0: else sl@0: { sl@0: iWsEventHandlers[idx].iEvents = aEvents; sl@0: return KErrNone; sl@0: } sl@0: } sl@0: sl@0: TInt TWindowServerEvent::UnregisterWsEventHandler(MWsEventHandler * aHandler) sl@0: { sl@0: TWsEventHandler handler(aHandler, 0); sl@0: TInt idx = iWsEventHandlers.Find(handler, TIdentityRelation(TWsEventHandler::CompareHandler)); sl@0: if (idx < 0) sl@0: return idx; sl@0: iWsEventHandlers[idx].iEvents = NULL; //NotifyDrawer() will clean up the array sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: void TWindowServerEvent::NotifyDrawer(const TWservCrEvent& aEvent) sl@0: { sl@0: TInt drawerCount = iDrawerHandlers->Count(); sl@0: for (TInt idx = 0; idx < drawerCount; idx++) sl@0: { sl@0: TDrawerHandler hd = (*iDrawerHandlers)[idx]; sl@0: if (!hd.iDrawer) sl@0: { //If the handler has been removed sl@0: iDrawerHandlers->Remove(idx); //Remove from the array sl@0: drawerCount -= 1; //Update the counters sl@0: idx -= 1; sl@0: } sl@0: else sl@0: { sl@0: if (hd.iEvents & aEvent.Type()) sl@0: { sl@0: hd.iDrawer->HandleEvent(aEvent); sl@0: } sl@0: } sl@0: } sl@0: sl@0: TInt eventHandlerCount = iWsEventHandlers.Count(); sl@0: for (TInt idx = 0; idx < eventHandlerCount; ++idx) sl@0: { sl@0: TWsEventHandler* eh = &iWsEventHandlers[idx]; sl@0: if (!eh->iEvents) sl@0: { //If the handler has been removed sl@0: iWsEventHandlers.Remove(idx); //Remove from the array sl@0: eventHandlerCount -= 1; //Update the counters sl@0: idx -= 1; sl@0: } sl@0: else sl@0: { sl@0: if (eh->iEvents & aEvent.Type()) sl@0: { sl@0: eh->iHandler->DoHandleEvent(aEvent); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: void TWindowServerEvent::NotifyScreenDrawingEvent(const TRegion* aRegion) sl@0: { sl@0: if (aRegion && !aRegion->IsEmpty()) sl@0: { sl@0: TWservCrEvent event(TWservCrEvent::EScreenDrawing,0,const_cast(aRegion)); sl@0: NotifyDrawer(event); sl@0: } sl@0: } sl@0: sl@0: void TWindowServerEvent::NotifyScreenDrawingEvent(const TRect& aRect) sl@0: { sl@0: TRegionFix<1> reg(aRect); sl@0: TWservCrEvent event(TWservCrEvent::EScreenDrawing,0,®); sl@0: NotifyDrawer(event); sl@0: } sl@0: sl@0: // sl@0: // CRawEventReceiver // sl@0: // sl@0: sl@0: CRawEventReceiver::CRawEventReceiver(TInt aPriority) : CActive(aPriority) sl@0: // sl@0: // Constructor sl@0: // sl@0: { sl@0: __DECLARE_NAME(_S("CRawEventReceiver")); sl@0: } sl@0: sl@0: CRawEventReceiver::~CRawEventReceiver() sl@0: { sl@0: CActive::Cancel(); sl@0: } sl@0: sl@0: void CRawEventReceiver::ConstructL() sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: UserSvr::CaptureEventHook(); sl@0: Request(); sl@0: } sl@0: sl@0: void CRawEventReceiver::Request() sl@0: // sl@0: // Issue a request for the next event. sl@0: // sl@0: { sl@0: UserSvr::RequestEvent(iEventBuf,iStatus); sl@0: SetActive(); sl@0: } sl@0: sl@0: void CRawEventReceiver::DoCancel() sl@0: // sl@0: // Cancel a pending event. sl@0: // sl@0: { sl@0: UserSvr::RequestEventCancel(); sl@0: } sl@0: sl@0: void CRawEventReceiver::RunL() sl@0: { sl@0: #ifdef LOG_WSERV_EVENTS sl@0: RDebug::Printf("_WSEVENT_KEY: CRawEventReceiver::RunL Entry point for event receiver"); sl@0: #endif sl@0: //__PROFILE_START(11); sl@0: if (TWsPointer::PreProcessDriverEvent(iEventBuf.Event() sl@0: #if defined(__WINS__) sl@0: ,ETrue sl@0: #endif sl@0: )) sl@0: TWindowServerEvent::ProcessRawEvent(iEventBuf.Event()); sl@0: Request(); sl@0: //__PROFILE_END(11); sl@0: } sl@0: sl@0: // sl@0: // TEventRequestQueue // sl@0: // sl@0: sl@0: TEventRequestQueue::TEventRequestQueue() : iQueue(_FOFF(TEventRequestItem,iQue)) sl@0: {} sl@0: sl@0: inline TSglQue &TEventRequestQueue::Queue() sl@0: {return(iQueue);} sl@0: sl@0: TEventRequestItem *TEventRequestQueue::FindInEventRequestQueueList(const CWsWindowBase &aWindow) sl@0: // sl@0: // Return a pointer to the link in the queue for the window, or NULL if not in the queue sl@0: // sl@0: { sl@0: TSglQueIter iter(iQueue); sl@0: TEventRequestItem *qPtr; sl@0: while((qPtr=iter++)!=NULL) sl@0: if (qPtr->iWindow==&aWindow) sl@0: break; sl@0: return(qPtr); sl@0: } sl@0: sl@0: void TEventRequestQueue::AddToEventRequestListL(const CWsWindowBase &aWindow, TInt aParam, TEventControl aCircumstances) sl@0: // sl@0: // Add a link to the on event list sl@0: // sl@0: { sl@0: TEventRequestItem *item=FindInEventRequestQueueList(aWindow); sl@0: if (!item) sl@0: { sl@0: item=new(ELeave) TEventRequestItem; sl@0: item->iWindow= &aWindow; sl@0: item->iParam=aParam; sl@0: item->iCircumstances=aCircumstances; sl@0: iQueue.AddFirst(*item); sl@0: } sl@0: item->iCircumstances=aCircumstances; sl@0: item->iParam=aParam; // Just update the parameter if already exists sl@0: } sl@0: sl@0: void TEventRequestQueue::RemoveFromEventRequestListL(const CWsWindowBase &aWindow) sl@0: // sl@0: // Remove a link from the on event list sl@0: // sl@0: { sl@0: TEventRequestItem *qPtr=FindInEventRequestQueueList(aWindow); sl@0: if (qPtr) sl@0: { sl@0: iQueue.Remove(*qPtr); sl@0: delete qPtr; sl@0: } sl@0: } sl@0: sl@0: // sl@0: // Keyboard auto repeat class // sl@0: // sl@0: sl@0: CKeyboardRepeat::CKeyboardRepeat() : CTimer(EKeyRepeatPriority) sl@0: {} sl@0: sl@0: void CKeyboardRepeat::NewL() sl@0: { sl@0: iThis=new(ELeave) CKeyboardRepeat(); sl@0: iThis->ConstructL(); sl@0: CActiveScheduler::Add(iThis); sl@0: _LIT(KWSERVIniFileVarRepeatRollover,"REPEATROLLOVER"); sl@0: WsIniFile->FindVar(KWSERVIniFileVarRepeatRollover,iRepeatRollover); sl@0: } sl@0: sl@0: void CKeyboardRepeat::Destroy() sl@0: { sl@0: delete iThis; sl@0: } sl@0: sl@0: void CKeyboardRepeat::GetRepeatTime(TTimeIntervalMicroSeconds32 &aInitialTime, TTimeIntervalMicroSeconds32 &aTime) sl@0: { sl@0: aInitialTime=iInitialTime; sl@0: aTime=iTime; sl@0: } sl@0: sl@0: void CKeyboardRepeat::SetRepeatTime(const TTimeIntervalMicroSeconds32 &aInitialTime, const TTimeIntervalMicroSeconds32 &aTime) sl@0: { sl@0: iInitialTime=aInitialTime; sl@0: iTime=aTime; sl@0: } sl@0: sl@0: /** sl@0: Process timer events. sl@0: sl@0: Called when the key repeat timer expires, this function generates the sl@0: appropriate long key or repeated key event. If the timer was started for sl@0: normal key repeat or if the long key event was captured with the automatic sl@0: repeat option specified then the timer is restarted. sl@0: */ sl@0: void CKeyboardRepeat::RunL() sl@0: { sl@0: User::ResetInactivityTime(); sl@0: WS_ASSERT_DEBUG(iRepeating != ERepeatNone, EWsPanicKeyRepeat); sl@0: TBool timer=ETrue; sl@0: if (iRepeating>=ERepeatLong) sl@0: { sl@0: // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong sl@0: WS_ASSERT_DEBUG(iLongCapture != NULL, EWsPanicKeyRepeat); sl@0: if (iLongCapture) sl@0: { sl@0: iCurrentRepeat = iLongRepeat; sl@0: timer = iLongCapture->iFlags & ELongCaptureRepeatEvents; sl@0: iRepeating=ERepeatLongRepeated; sl@0: } sl@0: else sl@0: { sl@0: // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong sl@0: // Stop key repeat if this incorrect condition occurs sl@0: timer=EFalse; sl@0: } sl@0: } sl@0: if (timer) sl@0: After(iTime); sl@0: else sl@0: iRepeating=ERepeatNone; sl@0: sl@0: TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iOutput, ETrue, 1); sl@0: } sl@0: sl@0: /** sl@0: Start key repeat and long key press timer sl@0: sl@0: @param aInputScanCode Original scan code (before routing) sl@0: @param aShortEvent Short key event (routing plug-in output) sl@0: @param aLongEvent Pointer to long key event (routing plug-in output) sl@0: or NULL if none. sl@0: sl@0: Note: When aLongEvent != NULL, iCurrentRepeat reflects the short key event sl@0: until the timer has expired. This is necessary to allow a delayed short key sl@0: event to be delivered by KeyUp(). CancelRepeat() must therefore examine sl@0: iCurrentRepeat or iLongRepeat according to the repeat type in iRepeat. sl@0: */ sl@0: void CKeyboardRepeat::StartRepeat(TInt aInputScanCode, const TKeyEventRouterOutput& aShortEvent, const TKeyEventRouterOutput* aLongEvent) sl@0: { sl@0: TTimeIntervalMicroSeconds32 time; sl@0: iCurrentRepeat.iInputScanCode = aInputScanCode; sl@0: iCurrentRepeat.iOutput = aShortEvent; sl@0: sl@0: if (aLongEvent) sl@0: { sl@0: iRepeating = ERepeatLong; sl@0: iLongRepeat.iInputScanCode = aInputScanCode; sl@0: iLongRepeat.iOutput = *aLongEvent; sl@0: iLongCapture = static_cast(aLongEvent->iCaptureHandle); sl@0: time = iLongCapture->iDelay; sl@0: } sl@0: else sl@0: { sl@0: iLongCapture = NULL; sl@0: iRepeating=ERepeatNormal; sl@0: time=iInitialTime; sl@0: } sl@0: iThis->After(time); sl@0: } sl@0: sl@0: /** sl@0: Cancel key repeat processing sl@0: */ sl@0: void CKeyboardRepeat::doCancelRepeat() sl@0: { sl@0: iRepeating=ERepeatNone; sl@0: iThis->Cancel(); sl@0: } sl@0: sl@0: /** sl@0: Cancel any key repeat associated with the specified window group sl@0: sl@0: @param aRepeatFocus Destination window group or NULL for all sl@0: */ sl@0: void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus) sl@0: { sl@0: if (iRepeating != ERepeatNone) sl@0: { sl@0: if (aRepeatFocus == NULL || sl@0: (iRepeating == ERepeatNormal) && (aRepeatFocus == iCurrentRepeat.iOutput.iWindowGroup) || sl@0: (iRepeating >= ERepeatLong) && (aRepeatFocus == iLongRepeat.iOutput.iWindowGroup)) sl@0: { sl@0: doCancelRepeat(); sl@0: iAlternateRepeatExists=EFalse; sl@0: } sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Cancel any key repeat associated with the specified capture handle sl@0: sl@0: @param aCaptureHandle Handle to capture request sl@0: @param aLongCaptureFlag ETrue for long key capture, EFalse for normal key sl@0: */ sl@0: void CKeyboardRepeat::CancelRepeat(const TAny* aCaptureHandle, TBool aLongCaptureFlag) sl@0: { sl@0: if (aLongCaptureFlag) sl@0: { sl@0: // Cancel repeat for long capture key sl@0: if (iRepeating >= ERepeatLong && aCaptureHandle == iLongRepeat.iOutput.iCaptureHandle) sl@0: { sl@0: doCancelRepeat(); sl@0: iAlternateRepeatExists=EFalse; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // Cancel repeat for normal capture key sl@0: if (iRepeating == ERepeatNormal && aCaptureHandle == iCurrentRepeat.iOutput.iCaptureHandle) sl@0: { sl@0: doCancelRepeat(); sl@0: iAlternateRepeatExists=EFalse; sl@0: } sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Process a key down event during key repeat. sl@0: The current repeat data is saved for possible restoration after rollover. sl@0: */ sl@0: void CKeyboardRepeat::KeyDown() sl@0: { sl@0: if (iRepeating!=ERepeatNone) sl@0: { sl@0: if (iRepeating==ERepeatNormal && iRepeatRollover>0) // 1 Allow key repeat rollover sl@0: { sl@0: iAlternateRepeat=iCurrentRepeat; sl@0: iAlternateRepeatExists=ETrue; sl@0: } sl@0: doCancelRepeat(); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: Process a key up event during key repeat. sl@0: Send delayed short key event if necessary for long key event processing. sl@0: Switch to alternate repeat if rollover key was released. sl@0: sl@0: @param aScanCode Scan code sl@0: */ sl@0: void CKeyboardRepeat::KeyUp(TInt aScanCode) sl@0: { sl@0: if (iAlternateRepeatExists && iAlternateRepeat.iInputScanCode == aScanCode) sl@0: iAlternateRepeatExists=EFalse; sl@0: if (iRepeating != ERepeatNone && iCurrentRepeat.iInputScanCode == aScanCode) sl@0: { sl@0: if (iRepeating==ERepeatLong) sl@0: { sl@0: // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong sl@0: WS_ASSERT_DEBUG(iLongCapture != NULL, EWsPanicKeyRepeat); sl@0: if (iLongCapture && !(iLongCapture->iFlags & ELongCaptureShortEventImmediately)) sl@0: { sl@0: TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iOutput, EFalse, 0); sl@0: } sl@0: } sl@0: if (iAlternateRepeatExists) sl@0: { sl@0: iAlternateRepeatExists=EFalse; sl@0: iCurrentRepeat=iAlternateRepeat; sl@0: iRepeating=ERepeatNormal; sl@0: } sl@0: else sl@0: doCancelRepeat(); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // CWsHotKey // sl@0: // sl@0: sl@0: CWsHotKey::CWsHotKey(TInt aHotKeyType, TBool aIsDefault) : sl@0: iHotKeyType(aHotKeyType), sl@0: iIsDefault(aIsDefault) sl@0: { sl@0: } sl@0: sl@0: CWsHotKey::~CWsHotKey() sl@0: { sl@0: delete iCaptureKey; sl@0: } sl@0: sl@0: void CWsHotKey::ConstructLD(const TWsWinCmdCaptureKey &aCaptureKey) sl@0: { sl@0: CleanupStack::PushL(this); sl@0: iCaptureKey=new(ELeave) CWsCaptureKey(NULL); sl@0: iCaptureKey->ConstructL(aCaptureKey); sl@0: CleanupStack::Pop(); sl@0: } sl@0: sl@0: void CWsHotKey::SetL(const TWsWinCmdCaptureKey &aCaptureKey) sl@0: { sl@0: iCaptureKey->SetL(aCaptureKey); sl@0: } sl@0: sl@0: // sl@0: //CEventQueueRetry// sl@0: // sl@0: CEventQueueRetry* CEventQueueRetry::NewL() sl@0: { sl@0: CEventQueueRetry* self = new (ELeave) CEventQueueRetry; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: void CEventQueueRetry::ConstructL() sl@0: { sl@0: User::LeaveIfError(iTimer.CreateLocal()); sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: CEventQueueRetry::CEventQueueRetry() : CActive(EPriorityStandard), iRetrySpinner(1) sl@0: { sl@0: sl@0: } sl@0: sl@0: CEventQueueRetry::~CEventQueueRetry() sl@0: { sl@0: Cancel(); sl@0: iTimer.Close(); sl@0: iClientArray.Close(); sl@0: } sl@0: sl@0: void CEventQueueRetry::DoCancel() sl@0: { sl@0: iTimer.Cancel(); sl@0: iRetrySpinner = 0; sl@0: iClientArray.Reset(); sl@0: } sl@0: sl@0: void CEventQueueRetry::RunL() sl@0: { sl@0: //some clients may be no longer interested in listening sl@0: //so we need to refresh the client list each round of retry sl@0: iClientArray.Reset(); sl@0: TInt err = iOwner->GetNotificationClients(iClientArray); sl@0: if(err != KErrNone) sl@0: { sl@0: iClientArray.Reset(); //so the retry won't kick off sl@0: } sl@0: if(iClientArray.Count() > 0) sl@0: { sl@0: TBool eventOnAllQueues = ETrue; sl@0: for(TInt i = 0; i < iClientArray.Count(); i++) sl@0: { sl@0: if(iClientArray[i]->RetryEvent(EEventDisplayChanged)) sl@0: { sl@0: if(TWindowServerEvent::SendDisplayChangedEvents(iClientArray[i], iOwner->ScreenNumber(), sl@0: iOwner->ConfigSpinner(), iOwner->DisplaySpinner())) sl@0: { sl@0: iClientArray[i]->RemoveRetryFlag(EEventDisplayChanged); sl@0: } sl@0: else sl@0: { sl@0: eventOnAllQueues = EFalse; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if(!eventOnAllQueues) sl@0: {//another retry needed, but with increased time interval sl@0: iRetrySpinner++; sl@0: Retry(KRetryInitialDelay*iRetrySpinner); sl@0: } sl@0: } sl@0: sl@0: } sl@0: sl@0: void CEventQueueRetry::Retry(TInt aDelay) sl@0: { sl@0: //the retry might be infinite, with an increasing interval, as delivery of the event is garuanteed sl@0: //if aDelay is greater than max TInt, it will be negative number so we reset it to KRetryInitialDelay sl@0: if(aDelay < 0) sl@0: { sl@0: aDelay = KRetryInitialDelay; sl@0: } sl@0: iTimer.After(iStatus, aDelay); sl@0: SetActive(); sl@0: } sl@0: sl@0: void CEventQueueRetry::Init(CScreen *aOwner) sl@0: { sl@0: iOwner = aOwner; sl@0: iRetrySpinner = 0; sl@0: sl@0: } sl@0: sl@0: void CEventQueueRetry::CancelRetry() sl@0: { sl@0: Cancel(); sl@0: }