1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/graphics/windowing/windowserver/nga/SERVER/EVENT.CPP Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,2084 @@
1.4 +// Copyright (c) 1994-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// Top level window server code
1.18 +//
1.19 +//
1.20 +
1.21 +#include "EVENT.H"
1.22 +
1.23 +#include "W32STD.H"
1.24 +#include <e32uid.h>
1.25 +#include <hal.h>
1.26 +#include <w32adll.h>
1.27 +#include "W32CLICK.H"
1.28 +#include "server.h"
1.29 +#include "windowgroup.h"
1.30 +#include "KEYCLICK.H"
1.31 +#include "wstop.h"
1.32 +#include "panics.h"
1.33 +#include "screen.h"
1.34 +#include "inifile.h"
1.35 +#include "password.h"
1.36 +#include "pointer.h"
1.37 +#include "debugbar.h"
1.38 +#include "advancedpointereventhelper.h"
1.39 +#include "graphics/wsgraphicdrawerinternal.h"
1.40 +#include "debughelper.h"
1.41 +
1.42 +GLREF_D CDebugLogBase *wsDebugLog;
1.43 +
1.44 +GLREF_C void StateDump();
1.45 +GLREF_C void HeapDump();
1.46 +
1.47 +_LIT(KDefaultKeyRouterPluginName, "keyrouter.dll");
1.48 +_LIT(KWSERVIniFileVarKeyRouterPlugin, "KEYROUTERPLUGIN");
1.49 +
1.50 +#define IMPOSSIBLE 0xFFFFFFFF
1.51 +
1.52 +const TWsWinCmdCaptureKey ImpossibleKeyPress=
1.53 + {
1.54 + IMPOSSIBLE, // Impossible to hit key combination, used for disabling Hot Keys
1.55 + IMPOSSIBLE,
1.56 + IMPOSSIBLE};
1.57 +
1.58 +const TWsWinCmdCaptureKey DefaultHotKeys[TWindowServerEvent::ENumHotKeys]={
1.59 + { // Enable logging
1.60 + EModifierFunc|EModifierCtrl|EModifierShift,
1.61 + EModifierFunc|EModifierCtrl|EModifierShift,
1.62 + 5}, // E
1.63 + { // Disable logging
1.64 + EModifierFunc|EModifierCtrl|EModifierShift,
1.65 + EModifierFunc|EModifierCtrl|EModifierShift,
1.66 + 4}, // D
1.67 + { // Window server internal dump to log
1.68 + EModifierFunc|EModifierCtrl|EModifierShift,
1.69 + EModifierFunc|EModifierCtrl|EModifierShift,
1.70 + 23},// W
1.71 + { // The key of death
1.72 + EModifierFunc|EModifierCtrl|EModifierShift,
1.73 + EModifierFunc|EModifierCtrl|EModifierShift,
1.74 + 11},// K
1.75 + { // Shutdown window server
1.76 +#if defined(_DEBUG)
1.77 + EModifierFunc|EModifierCtrl|EModifierShift,
1.78 + EModifierFunc|EModifierCtrl|EModifierShift,
1.79 + 24},// X
1.80 +#else
1.81 + IMPOSSIBLE, // Impossible to hit key combination, effectively disables shutdown key in release builds
1.82 + IMPOSSIBLE,
1.83 + IMPOSSIBLE},
1.84 +#endif
1.85 + { // Heap dump
1.86 + EModifierFunc|EModifierCtrl|EModifierShift,
1.87 + EModifierFunc|EModifierCtrl|EModifierShift,
1.88 + 8}, // H
1.89 + { // Inc Contrast
1.90 + 0,
1.91 + 0,
1.92 + EKeyIncContrast},
1.93 + { // Dec Contrast
1.94 + 0,
1.95 + 0,
1.96 + EKeyDecContrast},
1.97 + { // Off
1.98 + 0,
1.99 + 0,
1.100 + EKeyOff},
1.101 + { // Backlight on
1.102 + 0,
1.103 + 0,
1.104 + EKeyBacklightOn},
1.105 + { // Backlight off
1.106 + 0,
1.107 + 0,
1.108 + EKeyBacklightOff},
1.109 + { // Backlight toggle
1.110 + 0,
1.111 + 0,
1.112 + EKeyBacklightToggle},
1.113 + { // Screen Dimension Change
1.114 + 0,
1.115 + 0,
1.116 + EKeyScreenDimension0},
1.117 + {
1.118 + 0,
1.119 + 0,
1.120 + EKeyScreenDimension1},
1.121 + {
1.122 + 0,
1.123 + 0,
1.124 + EKeyScreenDimension2},
1.125 + {
1.126 + 0,
1.127 + 0,
1.128 + EKeyScreenDimension3},
1.129 +#if defined(_DEBUG)
1.130 + { // Display mode cycle
1.131 + EModifierFunc|EModifierCtrl|EModifierShift,
1.132 + EModifierFunc|EModifierCtrl|EModifierShift,
1.133 + 21},// U
1.134 + { // Orientation cycle
1.135 + EModifierFunc|EModifierCtrl|EModifierShift,
1.136 + EModifierFunc|EModifierCtrl|EModifierShift,
1.137 + 15},// O
1.138 +#else
1.139 + { // Display mode cycle
1.140 + IMPOSSIBLE, // Impossible to hit key combination
1.141 + IMPOSSIBLE,
1.142 + IMPOSSIBLE},
1.143 + { // Orientation cycle
1.144 + IMPOSSIBLE, // Impossible to hit key combination
1.145 + IMPOSSIBLE,
1.146 + IMPOSSIBLE},
1.147 +#endif
1.148 + { // Inc Brightness
1.149 + 0,
1.150 + 0,
1.151 + EKeyIncBrightness},
1.152 + { // Dec Brightness
1.153 + 0,
1.154 + 0,
1.155 + EKeyDecBrightness},
1.156 + { // Cycle focus screen
1.157 + EModifierFunc|EModifierCtrl|EModifierShift,
1.158 + EModifierFunc|EModifierCtrl|EModifierShift,
1.159 + 9}, // I
1.160 + };
1.161 +
1.162 +CKeyTranslator *TWindowServerEvent::iKeyTranslator=NULL;
1.163 +TEventRequestQueue TWindowServerEvent::iSwitchOnQueue;
1.164 +TEventRequestQueue TWindowServerEvent::iErrorMessageQueue;
1.165 +TEventRequestQueue TWindowServerEvent::iModifierChangedQueue;
1.166 +TEventRequestQueue TWindowServerEvent::iGroupChangedQueue;
1.167 +TEventRequestQueue TWindowServerEvent::iFocusChangedQueue;
1.168 +TEventRequestQueue TWindowServerEvent::iGroupListChangedQueue;
1.169 +TEventRequestQueue TWindowServerEvent::iScreenDeviceChangedQueue;
1.170 +TTime TWindowServerEvent::iPrevOomMessageTime;
1.171 +CCaptureKeys *TWindowServerEvent::iCaptureKeys;
1.172 +CKeyEventRouter* TWindowServerEvent::iKeyEventRouter;
1.173 +RLibrary TWindowServerEvent::iKeyEventRouterLibrary;
1.174 +CWsHotKey *TWindowServerEvent::iHotKeys;
1.175 +TInt TWindowServerEvent::iModifierState;
1.176 +CRawEventReceiver *TWindowServerEvent::iEventReceiver;
1.177 +RArray<TWindowServerEvent::TRawEventHandler> TWindowServerEvent::iEventHandlers;
1.178 +CArrayFixFlat<SNotificationHandler> *TWindowServerEvent::iNotificationHandlers;
1.179 +TInt TWindowServerEvent::iPotentialEventHandlers=0;
1.180 +TUint32 TWindowServerEvent::iBinaryFlags=0x00;
1.181 +RArray<TDrawerHandler>* TWindowServerEvent::iDrawerHandlers;
1.182 +RArray<TWsEventHandler> TWindowServerEvent::iWsEventHandlers;
1.183 +TInt TWindowServerEvent::iEventHandlerCount=0;
1.184 +TRepeatKey CKeyboardRepeat::iCurrentRepeat;
1.185 +TRepeatKey CKeyboardRepeat::iAlternateRepeat;
1.186 +TRepeatKey CKeyboardRepeat::iLongRepeat;
1.187 +TInt CKeyboardRepeat::iRepeatRollover=1;
1.188 +CKeyboardRepeat::TRepeatType CKeyboardRepeat::iRepeating=ERepeatNone;
1.189 +CKeyboardRepeat *CKeyboardRepeat::iThis=NULL;
1.190 +TTimeIntervalMicroSeconds32 CKeyboardRepeat::iInitialTime;
1.191 +TTimeIntervalMicroSeconds32 CKeyboardRepeat::iTime;
1.192 +TBool CKeyboardRepeat::iAlternateRepeatExists=EFalse;
1.193 +CWsCaptureLongKey* CKeyboardRepeat::iLongCapture=NULL;
1.194 +
1.195 +
1.196 +void TWindowServerEvent::DeleteHotKeys()
1.197 + {
1.198 + CWsHotKey *hotKey=iHotKeys;
1.199 + while(hotKey)
1.200 + {
1.201 + CWsHotKey *next=hotKey->iNext;
1.202 + delete hotKey;
1.203 + hotKey=next;
1.204 + }
1.205 + iHotKeys=NULL;
1.206 + }
1.207 +
1.208 +void TWindowServerEvent::DeleteStatics()
1.209 + {
1.210 + DeleteHotKeys();
1.211 + delete iCaptureKeys;
1.212 + delete iKeyEventRouter;
1.213 + iKeyEventRouterLibrary.Close();
1.214 + CKeyboardRepeat::Destroy();
1.215 + delete iKeyTranslator;
1.216 + delete iEventReceiver;
1.217 + iEventHandlers.Close();
1.218 + delete iNotificationHandlers;
1.219 + iDrawerHandlers->Close();
1.220 + delete iDrawerHandlers;
1.221 + iWsEventHandlers.Close();
1.222 + }
1.223 +
1.224 +void TWindowServerEvent::InitStaticsL()
1.225 +//
1.226 +// Create the CEvent active object.
1.227 +//
1.228 + {
1.229 +#if defined(__WINS__)
1.230 + WS_ASSERT_DEBUG(TWindowServerEvent::ENumHotKeys==EHotKeyLastKeyType+1, EWsPanicUnknownCaptureKey);
1.231 +#endif
1.232 + iEventReceiver=new(ELeave) CRawEventReceiver(EEventPriority);
1.233 + iEventReceiver->ConstructL();
1.234 + iKeyTranslator=CKeyTranslator::New();
1.235 + User::LeaveIfNull(iKeyTranslator);
1.236 +
1.237 +// Change keyboard mapping according to information the HAL
1.238 + TInt keyboardIndex;
1.239 + if (HAL::Get(HALData::EKeyboardIndex,keyboardIndex)==KErrNone)
1.240 + {
1.241 + _LIT(KLitKeyDataDllName,"EKDATA.%02d");
1.242 + TBuf<16> keyDataDllName;
1.243 + keyDataDllName.Format(KLitKeyDataDllName,keyboardIndex);
1.244 + iKeyTranslator->ChangeKeyData(keyDataDllName);
1.245 + }
1.246 +
1.247 + // CCaptureKeys is no longer used but a dummy object is required for
1.248 + // calls to CKeyTranslator::TranslateKey() until capture functionality
1.249 + // has been removed from ektran.dll.
1.250 + iCaptureKeys=new(ELeave) CCaptureKeys;
1.251 + iCaptureKeys->Construct();
1.252 +
1.253 + // Load the key event routing plug-in. The DLL name may be overridden
1.254 + // by setting the keyword KEYROUTERPLUGIN in wsini.ini.
1.255 + TPtrC pluginName(KDefaultKeyRouterPluginName);
1.256 + WsIniFile->FindVar(KWSERVIniFileVarKeyRouterPlugin, pluginName);
1.257 + const TUidType uidType(KDynamicLibraryUid, KKeyRouterPluginUid);
1.258 + TInt err = iKeyEventRouterLibrary.Load(pluginName, uidType);
1.259 +
1.260 + if (wsDebugLog)
1.261 + {
1.262 + TLogMessageText buf;
1.263 +
1.264 + if (err == KErrNone)
1.265 + {
1.266 + _LIT(KLogLoadOk, "Loaded plugin '%S' UID3 0x%x");
1.267 + const TFileName& pluginPathname = iKeyEventRouterLibrary.FileName();
1.268 + const TUid uid3 = iKeyEventRouterLibrary.Type()[2];
1.269 + buf.Format(KLogLoadOk, &pluginPathname, uid3.iUid);
1.270 + }
1.271 + else
1.272 + {
1.273 + _LIT(KLogLoadError, "Failed to load plugin '%S' (error %d)");
1.274 + buf.Format(KLogLoadError, &pluginName, err);
1.275 + }
1.276 +
1.277 + wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant, buf);
1.278 + }
1.279 +
1.280 + if (err != KErrNone)
1.281 + {
1.282 +#ifdef _DEBUG
1.283 + _LIT(KLoadError, "WServ: failed to load plugin '%S' (error %d)");
1.284 + RDebug::Print(KLoadError, &pluginName, err);
1.285 +#endif
1.286 + User::Leave(err);
1.287 + }
1.288 +
1.289 + // Create the key event router
1.290 + typedef CKeyEventRouter* (*TCreateFunc)();
1.291 + TCreateFunc newL = reinterpret_cast<TCreateFunc>(iKeyEventRouterLibrary.Lookup(1));
1.292 + if (newL == NULL)
1.293 + {
1.294 + User::Leave(KErrNotFound);
1.295 + }
1.296 + iKeyEventRouter = (*newL)();
1.297 +
1.298 + for (TInt index=0;index<TWindowServerEvent::ENumHotKeys;index++)
1.299 + ConstructDefaultHotKeyL(index,DefaultHotKeys[index]);
1.300 + CKeyboardRepeat::NewL();
1.301 + CKeyboardRepeat::SetRepeatTime(EDefaultInitialRepeatTime, EDefaultRepeatTime);
1.302 + iEventHandlers=RArray<TRawEventHandler>(2);
1.303 + iNotificationHandlers=new(ELeave) CArrayFixFlat<SNotificationHandler>(2);
1.304 + iDrawerHandlers = new(ELeave) RArray<TDrawerHandler>(4);
1.305 + }
1.306 +
1.307 +void TWindowServerEvent::LinkHotKey(CWsHotKey *aWsHotKey)
1.308 + {
1.309 + aWsHotKey->SetLink(iHotKeys);
1.310 + iHotKeys=aWsHotKey;
1.311 + }
1.312 +
1.313 +void TWindowServerEvent::ConstructDefaultHotKeyL(TInt aHotKey, const TWsWinCmdCaptureKey &aSystemKey)
1.314 + {
1.315 + CWsHotKey* hotKey=new(ELeave) CWsHotKey(aHotKey, ETrue);
1.316 + // hotKey is pushed onto the cleanup stack in method ConstructLD.
1.317 + hotKey->ConstructLD(aSystemKey);
1.318 + LinkHotKey(hotKey);
1.319 + }
1.320 +
1.321 +CWsHotKey* TWindowServerEvent::ClearHotKeysL(TInt aHotKey)
1.322 + {
1.323 + if (aHotKey>ENumHotKeys)
1.324 + {
1.325 + User::Leave(KErrArgument);
1.326 + }
1.327 + CWsHotKey** pHotKey= &iHotKeys;
1.328 + CWsHotKey* defaultHotKey=NULL;
1.329 + while(*pHotKey)
1.330 + {
1.331 + TBool unlinked=EFalse;
1.332 + if ((*pHotKey)->HotKeyType()==aHotKey)
1.333 + {
1.334 + CWsHotKey *free=*pHotKey;
1.335 + if (free->IsDefault())
1.336 + {
1.337 + free->SetL(ImpossibleKeyPress);
1.338 + defaultHotKey=free;
1.339 + }
1.340 + else
1.341 + {
1.342 + *pHotKey=(*pHotKey)->iNext;
1.343 + delete free;
1.344 + unlinked=ETrue;
1.345 + }
1.346 + }
1.347 + if (!unlinked)
1.348 + {
1.349 + pHotKey=&(*pHotKey)->iNext;
1.350 + }
1.351 + }
1.352 + return(defaultHotKey);
1.353 + }
1.354 +
1.355 +void TWindowServerEvent::ResetDefaultHotKeyL(TInt aHotKey)
1.356 + {
1.357 + if ((aHotKey<0) || (aHotKey>=ENumHotKeys))
1.358 + {
1.359 + User::Leave(KErrArgument);
1.360 + }
1.361 + CWsHotKey* defaultHotKey=ClearHotKeysL(aHotKey);
1.362 + WS_ASSERT_DEBUG(defaultHotKey, EWsPanicDefaultHotKeyNotFound);
1.363 + defaultHotKey->SetL(DefaultHotKeys[aHotKey]);
1.364 + }
1.365 +
1.366 +void TWindowServerEvent::SetHotKeyL(const TWsClCmdSetHotKey &aHotKey)
1.367 + {
1.368 + if (aHotKey.type>ENumHotKeys)
1.369 + User::Leave(KErrArgument);
1.370 +//
1.371 + CWsHotKey *hotKey=new(ELeave) CWsHotKey(aHotKey.type, EFalse);
1.372 +//
1.373 + TWsWinCmdCaptureKey captureKey;
1.374 + captureKey.modifiers=aHotKey.modifiers;
1.375 + captureKey.modifierMask=aHotKey.modifierMask;
1.376 + captureKey.key=aHotKey.keycode;
1.377 + captureKey.priority = 0;
1.378 + hotKey->ConstructLD(captureKey);
1.379 +//
1.380 + LinkHotKey(hotKey);
1.381 + }
1.382 +
1.383 +void TWindowServerEvent::AddEventHandler(MEventHandler *aEventHandler, TBool aAdvancedPointersEnabled)
1.384 + {
1.385 +#if defined(_DEBUG)
1.386 + TRAPD(err,iEventHandlers.AppendL(TRawEventHandler(aEventHandler, aAdvancedPointersEnabled)));
1.387 + WS_ASSERT_DEBUG(err==KErrNone, EWsPanicEventHandlerInconsistency);
1.388 +#else
1.389 + iEventHandlers.AppendL(TRawEventHandler(aEventHandler, aAdvancedPointersEnabled)); //Shouldn't leave
1.390 +#endif
1.391 +#ifdef LOG_WSERV_EVENTS
1.392 + RDebug::Printf("_WSEVENT_POINTER: TWindowServerEvent::AddEventHandler Added handler = %d AdvancedPointerEnabled = %d", iEventHandlers.Count(),aAdvancedPointersEnabled);
1.393 +#endif
1.394 + }
1.395 +
1.396 +void TWindowServerEvent::RemoveEventHandler(const MEventHandler *aEventHandler)
1.397 + {
1.398 + TInt count=iEventHandlers.Count();
1.399 + TInt ii;
1.400 + for(ii=0;ii<count;++ii)
1.401 + {
1.402 + if (iEventHandlers[ii].iEventHandler==aEventHandler)
1.403 + {
1.404 +#ifdef LOG_WSERV_EVENTS
1.405 + RDebug::Printf("_WSEVENT_POINTER: TWindowServerEvent::RemoveEventHandler Removed handler = %d",ii);
1.406 +#endif
1.407 + if (iEventHandlerCount>0)
1.408 + {
1.409 + iBinaryFlags |= ERemovedEventHandlerWhileProcessingRawEvents;
1.410 + iEventHandlers[ii].iEventHandler=NULL; // replace the Handler with null to keep size of the array
1.411 + }
1.412 + else
1.413 + {
1.414 + iEventHandlers.Remove(ii);
1.415 + }
1.416 + return;
1.417 + }
1.418 + }
1.419 + }
1.420 +
1.421 +void TWindowServerEvent::PotentialEventHandlerL(TInt aNum)
1.422 + {
1.423 + iPotentialEventHandlers+=aNum;
1.424 + WS_ASSERT_DEBUG(iPotentialEventHandlers>=iEventHandlers.Count(), EWsPanicEventHandlerInconsistency);
1.425 + TRAPD(err,iEventHandlers.Reserve(iPotentialEventHandlers));
1.426 + if (err!=KErrNone)
1.427 + {
1.428 + if (aNum>0)
1.429 + User::Leave(err);
1.430 + }
1.431 + else if (iPotentialEventHandlers==0)
1.432 + iEventHandlers.Compress();
1.433 + }
1.434 +
1.435 +void SendSwitchOnEvent(TEventRequestItem *aQptr, TInt aEvent, TInt )
1.436 + {
1.437 + aQptr->iWindow->QueueEvent(aEvent);
1.438 + }
1.439 +
1.440 +/*void SendSwitchOffEvent(TEventRequestItem *aQptr, TInt , TInt )
1.441 + {
1.442 + aQptr->iWindow->QueueEvent(EEventSwitchOff);
1.443 + }*/
1.444 +
1.445 +void SendErrorMessage(TEventRequestItem *aQptr, TInt aCategory, TInt aError)
1.446 + {
1.447 + TWsEvent event;
1.448 + event.SetType(EEventErrorMessage);
1.449 + event.SetHandle(aQptr->iWindow->ClientHandle());
1.450 + event.ErrorMessage()->iErrorCategory=(TWsErrorMessage::TErrorCategory)aCategory;
1.451 + event.ErrorMessage()->iError=aError;
1.452 + event.SetTimeNow();
1.453 + aQptr->iWindow->EventQueue()->QueueEvent(event,EEventPriorityHigh);
1.454 + }
1.455 +
1.456 +void SendModifierChangedEvent(TEventRequestItem *aQptr, TInt aChanged, TInt )
1.457 + {
1.458 + TInt tmpChanged=aChanged&aQptr->iParam;
1.459 + if (tmpChanged)
1.460 + {
1.461 + TWsEvent event;
1.462 + event.SetType(EEventModifiersChanged);
1.463 + event.SetHandle(aQptr->iWindow->ClientHandle());
1.464 + event.ModifiersChanged()->iChangedModifiers=tmpChanged;
1.465 + event.ModifiersChanged()->iModifiers=TWindowServerEvent::GetStoredModifierState();
1.466 + event.SetTimeNow();
1.467 + aQptr->iWindow->EventQueue()->QueueEvent(event,EEventPriorityHigh);
1.468 + }
1.469 + }
1.470 +
1.471 +void TWindowServerEvent::ProcessEventQueue(TEventRequestQueue &aQueue, TSendEventFunc aFunc, TInt aParam1, TInt aParam2)
1.472 + {
1.473 + TSglQueIter<TEventRequestItem> iter(aQueue.Queue());
1.474 + TEventRequestItem *qPtr;
1.475 + CWsWindowGroup *focusWin=CWsTop::FocusWindowGroup();
1.476 + while((qPtr=iter++)!=NULL)
1.477 + {
1.478 + if (qPtr->iCircumstances==EEventControlAlways ||
1.479 + (qPtr->iCircumstances==EEventControlOnlyWithKeyboardFocus && qPtr->iWindow->WinGroup()==focusWin) ||
1.480 + (qPtr->iCircumstances==EEventControlOnlyWhenVisible && !qPtr->iWindow->TreeIsObscured()))
1.481 + aFunc(qPtr, aParam1, aParam2);
1.482 + }
1.483 + }
1.484 +
1.485 +void TWindowServerEvent::NotifyOom()
1.486 + {
1.487 + TTime now;
1.488 + now.UniversalTime();
1.489 + TTimeIntervalSeconds interval;
1.490 + TInt err=now.SecondsFrom(iPrevOomMessageTime,interval);
1.491 + if (err!=KErrNone || interval.Int()<0 || interval.Int()>EOomEventSecondGap)
1.492 + {
1.493 + ProcessErrorMessages(TWsErrorMessage::EDrawingRegion,KErrNoMemory);
1.494 + iPrevOomMessageTime=now;
1.495 + }
1.496 + }
1.497 +
1.498 +TBool TWindowServerEvent::ProcessErrorMessages(TWsErrorMessage::TErrorCategory aCategory, TInt aError)
1.499 + {
1.500 + if (aError!=KErrNone)
1.501 + {
1.502 + ProcessEventQueue(iErrorMessageQueue, SendErrorMessage, aCategory, aError);
1.503 + return ETrue;
1.504 + }
1.505 + return EFalse;
1.506 + }
1.507 +
1.508 +void TWindowServerEvent::ProcessModifierChanges()
1.509 + {
1.510 + TInt newState=iKeyTranslator->GetModifierState();
1.511 + if (newState!=iModifierState)
1.512 + {
1.513 + TInt changed=iModifierState^newState;
1.514 + iModifierState=newState;
1.515 + ProcessEventQueue(iModifierChangedQueue, SendModifierChangedEvent, changed, 0);
1.516 + }
1.517 + }
1.518 +
1.519 +TEventQueueWalkRet FindScreenDeviceChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent)
1.520 + {
1.521 + if (aEvent->Type()==EEventScreenDeviceChanged && aEvent->Handle()==*(TUint *)aHandlePtr)
1.522 + *(TUint *)aHandlePtr=0; // Indicates event found
1.523 + return(EEventQueueWalkOk);
1.524 + }
1.525 +
1.526 +void TWindowServerEvent::SendScreenDeviceChangedEvents(CScreen* aScreen)
1.527 + {
1.528 + TSglQueIter<TEventRequestItem> iter(iScreenDeviceChangedQueue .Queue());
1.529 + TEventRequestItem *qPtr;
1.530 + while((qPtr=iter++)!=NULL)
1.531 + SendScreenDeviceChangedEvent(qPtr->iWindow);
1.532 + if(CClick::IsHandler())
1.533 + {
1.534 + TClickMakerData clickMakerData;
1.535 + clickMakerData.screenDeviceMode=aScreen->ScreenSizeMode();
1.536 + CClick::OtherEvent(EEventScreenDeviceChanged, &clickMakerData);
1.537 + }
1.538 + TWsEvent wsEvent;
1.539 + wsEvent.SetType(EEventScreenDeviceChanged);
1.540 + TWindowServerEvent::PublishNotification(wsEvent);
1.541 + TWservCrEvent crEvent(TWservCrEvent::EScreenSizeModeChanged,aScreen->ScreenSizeMode());
1.542 + TWindowServerEvent::NotifyDrawer(crEvent);
1.543 + }
1.544 +
1.545 +void TWindowServerEvent::SendScreenDeviceChangedEvent(const CWsWindowBase *aWindow)
1.546 + {
1.547 + CEventQueue *queue=aWindow->EventQueue();
1.548 + TUint32 handle=aWindow->ClientHandle();
1.549 + queue->WalkEventQueue(&FindScreenDeviceChangedEvent,&handle);
1.550 + if (handle!=NULL) // Indicates event not found
1.551 + queue->QueueEvent(handle, EEventScreenDeviceChanged);
1.552 + }
1.553 +
1.554 +TEventQueueWalkRet FindGroupChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent)
1.555 + {
1.556 + if (aEvent->Type()==EEventWindowGroupsChanged && aEvent->Handle()==*(TUint *)aHandlePtr)
1.557 + {
1.558 + *(TUint *)aHandlePtr=0; // Indicates event found
1.559 + }
1.560 + return(EEventQueueWalkOk);
1.561 + }
1.562 +
1.563 +void TWindowServerEvent::SendGroupChangedEvents()
1.564 + {
1.565 + TSglQueIter<TEventRequestItem> iter(iGroupChangedQueue.Queue());
1.566 + TEventRequestItem *qPtr;
1.567 + while((qPtr=iter++)!=NULL)
1.568 + {
1.569 + const CWsWindowBase *win=qPtr->iWindow;
1.570 + CEventQueue *queue=win->EventQueue();
1.571 + TUint32 handle=win->ClientHandle();
1.572 + queue->WalkEventQueue(&FindGroupChangedEvent,&handle);
1.573 + if (handle!=NULL) // Indicates event not found
1.574 + {
1.575 + queue->QueueEvent(handle, EEventWindowGroupsChanged);
1.576 + }
1.577 + }
1.578 + }
1.579 +
1.580 +TEventQueueWalkRet FindFocusChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent)
1.581 + {
1.582 + if (aEvent->Type()==EEventFocusGroupChanged && aEvent->Handle()==*(TUint *)aHandlePtr)
1.583 + {
1.584 + *(TUint *)aHandlePtr=0; // Indicates event found
1.585 + }
1.586 + return(EEventQueueWalkOk);
1.587 + }
1.588 +
1.589 +void TWindowServerEvent::SendFocusChangedEvents()
1.590 + {
1.591 + TInt identifier=0; // Zero Identifier indicates, currently there is no focused window group
1.592 + CScreen* currentFocusScreen=CWsTop::CurrentFocusScreen();
1.593 + TInt screenNumber=currentFocusScreen->ScreenNumber();
1.594 + CWsWindowGroup* currentFocusWG=currentFocusScreen->FocusWindowGroup();
1.595 + if(currentFocusWG)
1.596 + {
1.597 + identifier=currentFocusWG->Identifier();
1.598 + }
1.599 + TWindowServerEvent::NotifyDrawer(TWservCrEvent(TWservCrEvent::EWindowGroupChanged,
1.600 + screenNumber, reinterpret_cast<TAny*>(identifier)));
1.601 +
1.602 + TSglQueIter<TEventRequestItem> iter(iFocusChangedQueue.Queue());
1.603 + TEventRequestItem *qPtr;
1.604 + while((qPtr=iter++)!=NULL)
1.605 + {
1.606 + const CWsWindowBase *win=qPtr->iWindow;
1.607 + CEventQueue *queue=win->EventQueue();
1.608 + TUint32 handle=win->ClientHandle();
1.609 + queue->WalkEventQueue(&FindFocusChangedEvent,&handle);
1.610 + if (handle!=NULL) // Indicates event not found
1.611 + {
1.612 + queue->QueueEvent(handle, EEventFocusGroupChanged);
1.613 + }
1.614 + }
1.615 + }
1.616 +
1.617 +TEventQueueWalkRet FindGroupListChangedEvent(TAny *aHandlePtr, TWsEvent *aEvent)
1.618 + {
1.619 + if (aEvent->Type()==EEventWindowGroupListChanged && aEvent->Handle()==*(TUint *)aHandlePtr)
1.620 + {
1.621 + *(TUint *)aHandlePtr=0; // Indicates event found
1.622 + }
1.623 + return(EEventQueueWalkOk);
1.624 + }
1.625 +
1.626 +void TWindowServerEvent::SendGroupListChangedEvents()
1.627 + {
1.628 + TSglQueIter<TEventRequestItem> iter(iGroupListChangedQueue.Queue());
1.629 + TEventRequestItem *qPtr;
1.630 + while((qPtr=iter++)!=NULL)
1.631 + {
1.632 + const CWsWindowBase *win=qPtr->iWindow;
1.633 + CEventQueue *queue=win->EventQueue();
1.634 + TUint32 handle=win->ClientHandle();
1.635 + queue->WalkEventQueue(&FindGroupListChangedEvent,&handle);
1.636 + if (handle!=NULL) // Indicates event not found
1.637 + {
1.638 + queue->QueueEvent(handle, EEventWindowGroupListChanged);
1.639 + }
1.640 + }
1.641 + }
1.642 +
1.643 +TEventQueueWalkRet OverrideVisibilityChangedEvent(TAny *aNewEvent, TWsEvent *aOldEvent)
1.644 + {
1.645 + // This replaces the first visibility event it finds for the given window with the
1.646 + // one given. This is fine, so long as the meaning of all visibility events remains
1.647 + // independent of the ones before.
1.648 + TWsEvent* newEvent = static_cast<TWsEvent*>(aNewEvent);
1.649 + if (aOldEvent->Type()==EEventWindowVisibilityChanged && aOldEvent->Handle()==newEvent->Handle())
1.650 + {
1.651 + aOldEvent->SetTimeNow();
1.652 + aOldEvent->VisibilityChanged()->iFlags = newEvent->VisibilityChanged()->iFlags;
1.653 + newEvent->SetHandle(NULL);
1.654 + }
1.655 + return EEventQueueWalkOk;
1.656 + }
1.657 +
1.658 +void TWindowServerEvent::SendVisibilityChangedEvents(CWsWindowBase* aWin, TUint aFlags)
1.659 + {
1.660 + CEventQueue *queue=aWin->EventQueue();
1.661 + TWsEvent event;
1.662 + event.SetType(EEventWindowVisibilityChanged);
1.663 + event.SetHandle(aWin->ClientHandle());
1.664 + event.SetTimeNow();
1.665 + TWsVisibilityChangedEvent* visevent = event.VisibilityChanged();
1.666 + visevent->iFlags = aFlags;
1.667 + queue->WalkEventQueue(&OverrideVisibilityChangedEvent,&event);
1.668 + if (event.Handle()!=NULL)
1.669 + {
1.670 + queue->QueueEvent(event);
1.671 + }
1.672 + }
1.673 +
1.674 +TEventQueueWalkRet OverrideDisplayChangedEvent(TAny *aNewEvent, TWsEvent *aOldEvent)
1.675 + {
1.676 + TWsEvent* newEvent = static_cast<TWsEvent*>(aNewEvent);
1.677 + if (aOldEvent->Type() == EEventDisplayChanged &&
1.678 + aOldEvent->DisplayChanged()->iDisplayNumber == newEvent->DisplayChanged()->iDisplayNumber)
1.679 + {
1.680 + aOldEvent->SetTimeNow();
1.681 + aOldEvent->DisplayChanged()->iConfigurationChangeId = newEvent->DisplayChanged()->iConfigurationChangeId;
1.682 + aOldEvent->DisplayChanged()->iResolutionListChangeId = newEvent->DisplayChanged()->iResolutionListChangeId;
1.683 + newEvent->DisplayChanged()->iDisplayNumber = KErrNotFound; //So the new event won't be placed on event queue again
1.684 + }
1.685 + return EEventQueueWalkOk;
1.686 + }
1.687 +
1.688 +TBool TWindowServerEvent::SendDisplayChangedEvents(CWsClient* aWsClient, TInt aDisplayNumber, TInt aConfigurationChangeId, TInt aResolutionListChangeId)
1.689 + {
1.690 + CEventQueue *queue = aWsClient->EventQueue();
1.691 + TWsEvent event;
1.692 + event.SetType(EEventDisplayChanged);
1.693 + event.SetTimeNow();
1.694 +
1.695 + // fill in the handle otherwise CONE will discard the notification
1.696 + CWsObjectIx* clientObjList = aWsClient->ObjectIndex();
1.697 + const TWsObject* ptr=clientObjList->FirstObject();
1.698 + const TWsObject* end=ptr+clientObjList->Length();
1.699 + while(++ptr<end) // first one should always have a NULL object
1.700 + {
1.701 + const CWsObject* obj=ptr->iObject;
1.702 + if (obj && obj->Type()==WS_HANDLE_GROUP_WINDOW)
1.703 + {
1.704 + event.SetHandle(ptr->iHandle);
1.705 + break;
1.706 + }
1.707 + }
1.708 +
1.709 + TWsDisplayChangedEvent* dispEvent = event.DisplayChanged();
1.710 + dispEvent->iDisplayNumber = aDisplayNumber;
1.711 + dispEvent->iConfigurationChangeId = aConfigurationChangeId;
1.712 + dispEvent->iResolutionListChangeId = aResolutionListChangeId;
1.713 + queue->WalkEventQueue(&OverrideDisplayChangedEvent, &event);
1.714 + //place the new event on the queue only when its display number is valid (!=KErrNotFound)
1.715 + if(event.DisplayChanged()->iDisplayNumber >= 0)
1.716 + {
1.717 + return queue->QueueEvent(event);
1.718 + }
1.719 + return ETrue;
1.720 + }
1.721 +
1.722 +void TWindowServerEvent::QueueKeyEvent(CWsWindowGroup *aWin, TWsEvent &aEvent, TWservEventPriorities aPriority)
1.723 + {
1.724 +#ifdef LOG_WSERV_EVENTS
1.725 + RDebug::Print(_L("_WSEVENT_KEY: TWindowServerEvent::QueueKeyEvent, Queuing event name %S for application read, window handle: %d"), &WsEventName(aEvent), CWsTop::FocusWindowGroup()->ClientHandle());
1.726 +#endif
1.727 + aEvent.SetTimeNow();
1.728 + aWin->EventQueue()->QueueEvent(aEvent, aPriority);
1.729 + }
1.730 +
1.731 +/**
1.732 +Process a key press event.
1.733 +
1.734 +This function is called for every input key event and uses the Key Event
1.735 +Routing plug-in to check for short and long key capture and determine the
1.736 +destination window group for the queued event(s).
1.737 +Window server hotkeys are also processed.
1.738 +Note that the key repeat timer is started here but the key repeat events
1.739 +generated by the timer go directly to QueueKeyPress().
1.740 +
1.741 +@param aKeyEvent Input key event
1.742 +@param aCheckRepeat Check for key repeat and long key capture
1.743 +@param aRepeats Repeat count
1.744 +*/
1.745 +void TWindowServerEvent::ProcessKeyPress(const TKeyEvent& aKeyEvent, TBool aCheckRepeat, TInt aRepeats)
1.746 + {
1.747 + CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup();
1.748 + TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid;
1.749 +
1.750 + // Route the key event and check for short key capture.
1.751 + // Note that the Key Routing plugin may translate or block key events.
1.752 + TKeyEventRouterInput input(ECaptureTypeKey, aKeyEvent, focusWin, focusAppUid);
1.753 + TKeyEventRouterOutput output;
1.754 +
1.755 +#ifdef _DEBUG
1.756 + // RouteKey() must not fail. Check for leaves in case the plug-in
1.757 + // is badly behaved.
1.758 + TRAPD(err, iKeyEventRouter->RouteKey(input, output));
1.759 + WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave);
1.760 +#else
1.761 + iKeyEventRouter->RouteKey(input, output);
1.762 +#endif
1.763 +
1.764 + WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured || output.iResult == EConsumed, EWsPanicKeyEventRouterBadResult);
1.765 +
1.766 + if (output.iResult == EConsumed)
1.767 + {
1.768 + focusWin = NULL;
1.769 + }
1.770 + else
1.771 + {
1.772 + focusWin = static_cast<CWsWindowGroup*>(output.iWindowGroup);
1.773 + }
1.774 + WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup);
1.775 +
1.776 + // Ensure that short event is not marked with EModifierLongKey
1.777 + output.iKeyEvent.iModifiers &= ~EModifierLongKey;
1.778 +
1.779 + // Generate key click unless the event is consumed. This is consistent
1.780 + // with the behaviour when CKeyTranslator::TranslateKey() yields no
1.781 + // translation for a particular scan code. (Click events for key up/down
1.782 + // will still be generated by QueueKeyUpDown()). Note however that a long
1.783 + // key press may still be captured even if the short event is consumed.
1.784 + if (CClick::IsHandler() && output.iResult != EConsumed)
1.785 + {
1.786 + output.iKeyEvent.iRepeats = aRepeats;
1.787 + CClick::KeyEvent(EEventKey, output.iKeyEvent);
1.788 + }
1.789 +
1.790 + if (output.iResult == ECaptured)
1.791 + {
1.792 + if (output.iWindowGroup == NULL) // Captured by Wserv itself
1.793 + {
1.794 + _LIT(KWSERVDebugLogCapturedKey,"WSERV Captured Key");
1.795 + CScreen* focusScreen=CWsTop::CurrentFocusScreen();
1.796 + TInt screenNo=focusScreen->ScreenNumber();
1.797 +
1.798 + if (wsDebugLog)
1.799 + wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogCapturedKey);
1.800 + CWsHotKey *hotKey=iHotKeys;
1.801 + while(hotKey)
1.802 + {
1.803 + if (hotKey->KeyHandle() == reinterpret_cast<TInt>(output.iCaptureHandle))
1.804 + {
1.805 + switch(hotKey->HotKeyType())
1.806 + {
1.807 + case EHotKeyEnableLogging:
1.808 + CWsTop::EnableLogging();
1.809 + break;
1.810 + case EHotKeyDisableLogging:
1.811 + CWsTop::DisableLogging();
1.812 + break;
1.813 + case EHotKeyStateDump:
1.814 + StateDump();
1.815 + break;
1.816 + case EHotKeyHeapDump:
1.817 + HeapDump();
1.818 + break;
1.819 + case EHotKeyOfDeath:
1.820 + if (!CWsPassword::PasswordModeActive())
1.821 + {
1.822 + const TBool currentJustInTimeValue=User::JustInTime();
1.823 + if (currentJustInTimeValue)
1.824 + {
1.825 + User::SetJustInTime(EFalse);
1.826 + }
1.827 + CWsTop::KillForegroundSession();
1.828 + if (currentJustInTimeValue)
1.829 + {
1.830 + User::SetJustInTime(ETrue);
1.831 + }
1.832 + }
1.833 + break;
1.834 + case EHotKeyShutDown:
1.835 + CWsTop::Exit();
1.836 + break;
1.837 + case EHotKeyIncContrast:
1.838 + focusScreen->IncContrast();
1.839 + break;
1.840 + case EHotKeyDecContrast:
1.841 + focusScreen->DecContrast();
1.842 + break;
1.843 + case EHotKeyOff:
1.844 + CWsTop::HandleSwitchOff(EEventKeySwitchOff,ETrue);
1.845 + break;
1.846 + case EHotKeyBacklightToggle:
1.847 + {
1.848 + TInt state;
1.849 + if (!ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Get(screenNo,HALData::EBacklightState,state)))
1.850 + ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(screenNo,HALData::EBacklightState,!state));
1.851 + }
1.852 + break;
1.853 + case EHotKeyBacklightOn:
1.854 + ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(screenNo,HALData::EBacklightState,ETrue));
1.855 + break;
1.856 + case EHotKeyBacklightOff:
1.857 + ProcessErrorMessages(TWsErrorMessage::EBackLight, HAL::Set(screenNo,HALData::EBacklightState,EFalse));
1.858 + break;
1.859 + case EHotKeyScreenDimension0:
1.860 + case EHotKeyScreenDimension1:
1.861 + case EHotKeyScreenDimension2:
1.862 + case EHotKeyScreenDimension3:
1.863 + focusScreen->doSetScreenMode(hotKey->HotKeyType()-EHotKeyScreenDimension0);
1.864 + break;
1.865 + case EHotKeyCycleDisplaySize:
1.866 + focusScreen->CycleDisplaySize();
1.867 + break;
1.868 + case EHotKeyCycleOrientation:
1.869 + focusScreen->CycleOrientation();
1.870 + break;
1.871 + case EHotKeyIncBrightness:
1.872 + focusScreen->IncBrightness();
1.873 + break;
1.874 + case EHotKeyDecBrightness:
1.875 + focusScreen->DecBrightness();
1.876 + break;
1.877 + case EHotKeyCycleFocusScreen:
1.878 + CWsTop::SetCurrentFocusScreen((CWsTop::CurrentFocusScreen()->ScreenNumber()+1)%CWsTop::NumberOfScreens());
1.879 + break;
1.880 + }
1.881 + return;
1.882 + }
1.883 + hotKey=hotKey->iNext;
1.884 + }
1.885 + WS_PANIC_ALWAYS(EWsPanicUnknownCaptureKey);
1.886 + return;
1.887 + }
1.888 +
1.889 + _LIT(KWSERVDebugLogKeyCapturedByApp,"Key captured by app %d");
1.890 + if (wsDebugLog)
1.891 + wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyCapturedByApp,focusWin->Identifier());
1.892 + if (CWsPassword::PasswordModeActive() && focusWin!=CWsPassword::PasswordWindow()->WinGroup())
1.893 + return;
1.894 + }
1.895 +
1.896 + CWsCaptureLongKey* longCapture = NULL;
1.897 + TKeyEventRouterOutput longOutput;
1.898 + if (aCheckRepeat)
1.899 + {
1.900 + // Check for long key capture.
1.901 + // Note that a long key event can only result from capture, there is
1.902 + // no default detection or routing of long events.
1.903 + input.iType = ECaptureTypeLongKey;
1.904 +#ifdef _DEBUG
1.905 + TRAPD(err, iKeyEventRouter->RouteKey(input, longOutput));
1.906 + WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave);
1.907 +#else
1.908 + iKeyEventRouter->RouteKey(input, longOutput);
1.909 +#endif
1.910 +
1.911 + if (longOutput.iResult == ECaptured)
1.912 + {
1.913 + longCapture = static_cast<CWsCaptureLongKey*>(longOutput.iCaptureHandle);
1.914 +
1.915 + // Mark long key events with EModifierLongKey so that applications
1.916 + // can easily distinguish short and long events.
1.917 + longOutput.iKeyEvent.iModifiers |= EModifierLongKey;
1.918 +
1.919 + // Start timer to detect long key press
1.920 + CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, &longOutput);
1.921 + }
1.922 + else if (output.iResult != EConsumed && output.iKeyEvent.iModifiers & EModifierAutorepeatable)
1.923 + {
1.924 + // Start timer for key repeat
1.925 + CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, NULL);
1.926 + }
1.927 + }
1.928 +
1.929 + // Queue the short event
1.930 + if (!longCapture || longCapture->iFlags & ELongCaptureShortEventImmediately)
1.931 + {
1.932 + QueueKeyPress(output, EFalse, aRepeats);
1.933 + }
1.934 + }
1.935 +
1.936 +/**
1.937 +Queue a key press event.
1.938 +
1.939 +This function is called for each key event produced by ProcessKeyPress(),
1.940 +for every key repeat and long key event generated by the timer and also for
1.941 +delayed short key events from KeyUp().
1.942 +
1.943 +@param aOutput Output key event from routing plug-in
1.944 +@param aIsRepeat Event is due to key repeat
1.945 +@param aRepeats Repeat count
1.946 +*/
1.947 +void TWindowServerEvent::QueueKeyPress(const TKeyEventRouterOutput& aOutput, TBool aIsRepeat, TInt aRepeats)
1.948 + {
1.949 + if (aOutput.iResult == EConsumed)
1.950 + {
1.951 + // Don't deliver this key
1.952 + return;
1.953 + }
1.954 +
1.955 + TWsEvent event;
1.956 + TKeyEvent& keyEvent = *event.Key();
1.957 + keyEvent = aOutput.iKeyEvent;
1.958 + keyEvent.iRepeats = aRepeats;
1.959 +
1.960 + CWsWindowGroup* focusWin = static_cast<CWsWindowGroup*>(aOutput.iWindowGroup);
1.961 + WS_ASSERT_DEBUG(focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW, EWsPanicKeyEventRouterBadWindowGroup);
1.962 +
1.963 + if (aIsRepeat && aOutput.iResult != ECaptured && focusWin != CWsTop::FocusWindowGroup())
1.964 + CKeyboardRepeat::CancelRepeat(NULL); // Repeat is going to different window so cancel it and don't deliver this key
1.965 + else if (focusWin != NULL && focusWin->CheckForPriorityKey(keyEvent) == EFalse)
1.966 + {
1.967 + event.SetType(EEventKey);
1.968 + event.SetHandle(focusWin->ClientHandle());
1.969 + if (aRepeats!=0)
1.970 + {
1.971 + CEventQueue* queue=focusWin->EventQueue();
1.972 + queue->Wait();
1.973 + const TWsEvent* prev=queue->PeekLastEvent();
1.974 + if (prev != NULL && prev->Type() == EEventKey && prev->Key()->iRepeats > 0 && prev->Key()->iCode == keyEvent.iCode)
1.975 + {
1.976 + prev->Key()->iRepeats += aRepeats;
1.977 + queue->Signal();
1.978 + if (CClick::IsHandler())
1.979 + CClick::KeyEvent(EEventKeyRepeat, *prev->Key());
1.980 + return;
1.981 + }
1.982 + queue->Signal();
1.983 + if (CClick::IsHandler())
1.984 + CClick::KeyEvent(EEventKeyRepeat,keyEvent);
1.985 + }
1.986 + QueueKeyEvent(focusWin, event, EEventPriorityLow);
1.987 + }
1.988 + }
1.989 +
1.990 +/**
1.991 +Queue a key up/down event.
1.992 +
1.993 +@param aRawEvent Raw event
1.994 +*/
1.995 +void TWindowServerEvent::QueueKeyUpDown(const TRawEvent &aRawEvent)
1.996 + {
1.997 +#ifdef LOG_WSERV_EVENTS
1.998 + RDebug::Print(_L("_WSEVENT_KEY: TWindowServerEvent::QueueKeyUpDown, Event Name: %S, Scan code: %d"), &RawEventName(aRawEvent), aRawEvent.ScanCode());
1.999 +#endif
1.1000 + TEventCode type = aRawEvent.Type() == TRawEvent::EKeyUp ? EEventKeyUp : EEventKeyDown;
1.1001 +
1.1002 + // Check for key up/down capture
1.1003 + TKeyEvent keyEvent;
1.1004 + keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
1.1005 +#if defined(__WINS__)
1.1006 + keyEvent.iCode = __WINS_CHARCODE(aRawEvent.ScanCode());
1.1007 +#else
1.1008 + keyEvent.iCode = 0;
1.1009 +#endif
1.1010 + keyEvent.iModifiers = iModifierState;
1.1011 + keyEvent.iRepeats = 0;
1.1012 +
1.1013 + CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup();
1.1014 + TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid;
1.1015 +
1.1016 + TKeyEventRouterInput input(ECaptureTypeKeyUpDown, keyEvent, focusWin, focusAppUid);
1.1017 + TKeyEventRouterOutput output;
1.1018 +#ifdef _DEBUG
1.1019 + TRAPD(err, iKeyEventRouter->RouteKey(input, output));
1.1020 + WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave);
1.1021 +#else
1.1022 + iKeyEventRouter->RouteKey(input, output);
1.1023 +#endif
1.1024 +
1.1025 + if (output.iResult == EConsumed)
1.1026 + {
1.1027 + // Don't deliver this key. A key click is still generated for the
1.1028 + // input event.
1.1029 + if (CClick::IsHandler())
1.1030 + {
1.1031 + CClick::KeyEvent(type, keyEvent);
1.1032 + }
1.1033 + return;
1.1034 + }
1.1035 + WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured, EWsPanicKeyEventRouterBadResult);
1.1036 +
1.1037 + focusWin = static_cast<CWsWindowGroup*>(output.iWindowGroup);
1.1038 + WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup);
1.1039 +#if defined(__WINS__)
1.1040 + if (focusWin && !focusWin->WsOwner()->RemoveKeyCode())
1.1041 + {
1.1042 + // Restore WINS character code
1.1043 + output.iKeyEvent.iScanCode |= output.iKeyEvent.iCode;
1.1044 + }
1.1045 + output.iKeyEvent.iCode = 0;
1.1046 +#endif
1.1047 +
1.1048 + output.iKeyEvent.iRepeats = 0;
1.1049 + if (CClick::IsHandler())
1.1050 + {
1.1051 + CClick::KeyEvent(type, output.iKeyEvent);
1.1052 + }
1.1053 +
1.1054 + TWsEvent event;
1.1055 + *event.Key() = output.iKeyEvent;
1.1056 + if (focusWin!=NULL)
1.1057 + {
1.1058 + event.SetType(type);
1.1059 + event.SetHandle(focusWin->ClientHandle());
1.1060 + QueueKeyEvent(focusWin, event, EEventPriorityHigh);
1.1061 + }
1.1062 + }
1.1063 +
1.1064 +LOCAL_D void GetPointerEvent(TPointerEvent::TType& aType, const TRawEvent &aRawEvent, TBool& aHandled)
1.1065 + {
1.1066 + aHandled=ETrue;
1.1067 + switch(aRawEvent.Type())
1.1068 + {
1.1069 + case TRawEvent::EButton1Down:
1.1070 + aType=TPointerEvent::EButton1Down;
1.1071 + break;
1.1072 + case TRawEvent::EButton1Up:
1.1073 + aType=TPointerEvent::EButton1Up;
1.1074 + break;
1.1075 + case TRawEvent::EButton2Down:
1.1076 + aType=TPointerEvent::EButton2Down;
1.1077 + break;
1.1078 + case TRawEvent::EButton2Up:
1.1079 + aType=TPointerEvent::EButton2Up;
1.1080 + break;
1.1081 + case TRawEvent::EButton3Down:
1.1082 + aType=TPointerEvent::EButton3Down;
1.1083 + break;
1.1084 + case TRawEvent::EButton3Up:
1.1085 + aType=TPointerEvent::EButton3Up;
1.1086 + break;
1.1087 + case TRawEvent::EPointerMove:
1.1088 + aType=TPointerEvent::EMove;
1.1089 + break;
1.1090 + case TRawEvent::EPointerSwitchOn:
1.1091 + aType=TPointerEvent::ESwitchOn;
1.1092 + break;
1.1093 + case TRawEvent::EPointer3DOutOfRange:
1.1094 + aType=TPointerEvent::EOutOfRange;
1.1095 + break;
1.1096 + default:
1.1097 + aHandled=EFalse;
1.1098 + }
1.1099 + }
1.1100 +
1.1101 +TBool TWindowServerEvent::MousePress(const TRawEvent &aRawEvent, const CWsWindowGroup *aGroupWin)
1.1102 + //
1.1103 + //Return EFalse if known not to be a Mouse Event
1.1104 + //
1.1105 + {
1.1106 + TBool handled=ETrue;
1.1107 + TPointerEvent::TType type;
1.1108 + GetPointerEvent(type, aRawEvent, handled);
1.1109 + if (handled)
1.1110 + {
1.1111 + TPoint3D point3D(0,0,0);
1.1112 + if (type != TPointerEvent::EOutOfRange)
1.1113 + {
1.1114 + point3D = aRawEvent.Pos3D();
1.1115 + }
1.1116 + TWsEvent event;
1.1117 + TAdvancedPointerEventHelper::InitAdvancedPointerEvent(event, type,iKeyTranslator->GetModifierState(),point3D,aRawEvent.PointerNumber());
1.1118 + TWsPointer::ProcessWsEvent(event, aGroupWin, ETrue);
1.1119 + }
1.1120 + return handled;
1.1121 + }
1.1122 +
1.1123 +LOCAL_D void SendEventToKeyClick(const TRawEvent& aRawEvent)
1.1124 + {
1.1125 + switch(aRawEvent.Type())
1.1126 + {
1.1127 + case TRawEvent::EKeyDown:
1.1128 + case TRawEvent::EKeyUp:
1.1129 + {
1.1130 + TKeyEvent keyEvent;
1.1131 + keyEvent.iCode=0;
1.1132 + keyEvent.iScanCode=aRawEvent.ScanCode();
1.1133 + keyEvent.iModifiers=0;
1.1134 + keyEvent.iRepeats=0;
1.1135 + CClick::KeyEvent(EEventKey,keyEvent);
1.1136 + }
1.1137 + break;
1.1138 + case TRawEvent::EButton1Down:
1.1139 + case TRawEvent::EButton1Up:
1.1140 + case TRawEvent::EButton2Down:
1.1141 + case TRawEvent::EButton2Up:
1.1142 + case TRawEvent::EButton3Down:
1.1143 + case TRawEvent::EButton3Up:
1.1144 + case TRawEvent::EPointerMove:
1.1145 + case TRawEvent::EPointerSwitchOn:
1.1146 + {
1.1147 + TBool handled=ETrue;
1.1148 + TPointerEvent::TType type;
1.1149 + GetPointerEvent(type, aRawEvent, handled);
1.1150 + if (handled)
1.1151 + {
1.1152 + TWsEvent event;
1.1153 + TAdvancedPointerEventHelper::InitAdvancedPointerEvent(event, type, 0, aRawEvent.Pos3D(), TPoint(), aRawEvent.PointerNumber());
1.1154 + TAdvancedPointerEvent& pointerEvent = *event.Pointer();
1.1155 + CClick::PointerEvent(pointerEvent.iPosition,pointerEvent);
1.1156 + }
1.1157 + }
1.1158 + break;
1.1159 + default:
1.1160 + break;
1.1161 + }
1.1162 + }
1.1163 +
1.1164 +/*
1.1165 +Process a raw event
1.1166 +
1.1167 +@param aRawEvent Raw event
1.1168 +*/
1.1169 +void TWindowServerEvent::ProcessRawEvent(const TRawEvent& aRawEvent)
1.1170 +//
1.1171 +// Event has completed.
1.1172 +//
1.1173 + {
1.1174 + TRawEvent::TType eventType = aRawEvent.Type();
1.1175 + TBool isPointerEvent = TWsPointer::IsPointerEventType(eventType);
1.1176 + if (isPointerEvent)
1.1177 + {
1.1178 +#ifdef LOG_WSERV_EVENTS
1.1179 + RDebug::Print(_L("_WSEVENT_POINTER: TWindowServerEvent::ProcessRawEvent EventName = %S PointerNumber = %d PrimaryPointerNumber = %d Coordinates = ( %d, %d )"),
1.1180 + &RawEventName(aRawEvent),aRawEvent.PointerNumber(),TWsPointer::PrimaryPointer(),aRawEvent.Pos().iX,aRawEvent.Pos().iY);
1.1181 +#endif
1.1182 + TWsPointer::UpdatePrimaryPointer(aRawEvent);
1.1183 + }
1.1184 + TInt count=iEventHandlers.Count();
1.1185 + TInt ii;
1.1186 + TBool eventHandled = EFalse;
1.1187 + iEventHandlerCount++;
1.1188 + for(ii=0;ii<count;++ii)
1.1189 + {
1.1190 + TRawEventHandler &handler = iEventHandlers[ii];
1.1191 + if (handler.iEventHandler != NULL &&
1.1192 + (!isPointerEvent ||
1.1193 + handler.iAdvancedPointersEnabled ||
1.1194 + aRawEvent.PointerNumber() == TWsPointer::PrimaryPointer()) &&
1.1195 + handler.iEventHandler->OfferRawEvent(aRawEvent))
1.1196 + {
1.1197 + if (CClick::IsHandler())
1.1198 + {
1.1199 +#ifdef LOG_WSERV_EVENTS
1.1200 + RDebug::Print(_L("_WSEVENT_KEY: Send event %S for Key Click"), &RawEventName(aRawEvent));
1.1201 +#endif
1.1202 + SendEventToKeyClick(aRawEvent);
1.1203 + }
1.1204 + eventHandled = ETrue;
1.1205 +#ifdef LOG_WSERV_EVENTS
1.1206 + RDebug::Printf("_WSEVENT_POINTER: TWindowServerEvent::ProcessRawEvent Event Consumed by ANIM.dll Handler No = %d Advanced Pointer Enabled = %d",ii,handler.iAdvancedPointersEnabled);
1.1207 +#endif
1.1208 + break;
1.1209 + }
1.1210 + }
1.1211 + if (--iEventHandlerCount == 0)
1.1212 + {
1.1213 + if (ERemovedEventHandlerWhileProcessingRawEvents & iBinaryFlags) // Handler was deleted while previous loop
1.1214 + {
1.1215 + iBinaryFlags &= ~ERemovedEventHandlerWhileProcessingRawEvents;
1.1216 + for(ii=count-1;ii>=0;--ii)
1.1217 + {
1.1218 + if (iEventHandlers[ii].iEventHandler==NULL) iEventHandlers.Remove(ii);
1.1219 + }
1.1220 + }
1.1221 + }
1.1222 + if (eventHandled)
1.1223 + {
1.1224 +#ifdef LOG_WSERV_EVENTS
1.1225 + RDebug::Printf("_WSEVENT: Event is already handled by anim dll not by window server");
1.1226 + // This is to determine when we press the power button which bring power dialog
1.1227 + // whether it is a pointer event or key event
1.1228 + // Also when we plugin the charging cable this is to determine whether it is a pointer event or key event
1.1229 + RDebug::Print(_L("_WSEVENT: RawEvent Name = %S"), &RawEventName(aRawEvent));
1.1230 +#endif
1.1231 + if (isPointerEvent)
1.1232 + {
1.1233 +#ifdef LOG_WSERV_EVENTS
1.1234 + 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);
1.1235 + 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);
1.1236 +#endif
1.1237 + //Prevention of the phone pointer event "dead lock".
1.1238 + TPointerEvent::TType type;
1.1239 + TBool handled = ETrue;
1.1240 + GetPointerEvent(type, aRawEvent, handled);
1.1241 + switch(type)
1.1242 + {
1.1243 + case TPointerEvent::EButton1Down:
1.1244 + case TPointerEvent::EButton2Down:
1.1245 + case TPointerEvent::EButton3Down:
1.1246 + TWsPointer::iPointers[aRawEvent.PointerNumber()].iState = TWsPointer::EPointerStateDown;
1.1247 + break;
1.1248 + case TPointerEvent::EButton1Up:
1.1249 + case TPointerEvent::EButton2Up:
1.1250 + case TPointerEvent::EButton3Up:
1.1251 + TWsPointer::iPointers[aRawEvent.PointerNumber()].iState = TWsPointer::EPointerStateUp;
1.1252 + break;
1.1253 + case TPointerEvent::EOutOfRange:
1.1254 + TWsPointer::iPointers[aRawEvent.PointerNumber()].iState = TWsPointer::EPointerStateOutOfRange;
1.1255 + break;
1.1256 + default:
1.1257 + break;
1.1258 + }
1.1259 + }
1.1260 + return;
1.1261 + }
1.1262 +
1.1263 + switch(eventType)
1.1264 + {
1.1265 + case TRawEvent::ERedraw:
1.1266 + CWsTop::RedrawScreens();
1.1267 + break;
1.1268 + case TRawEvent::ESwitchOn:
1.1269 + case TRawEvent::ECaseOpen:
1.1270 + {
1.1271 + TInt event=EEventCaseOpened;
1.1272 + CKeyboardRepeat::CancelRepeat(NULL);
1.1273 + CWsPassword::SwitchOn();
1.1274 + if (eventType==TRawEvent::ESwitchOn)
1.1275 + {
1.1276 + UserSvr::WsSwitchOnScreen();
1.1277 + HAL::Set(HALData::EDisplayState,1);
1.1278 + event=EEventSwitchOn;
1.1279 + }
1.1280 + ProcessEventQueue(iSwitchOnQueue, SendSwitchOnEvent, event, 0);
1.1281 + break;
1.1282 + }
1.1283 + case TRawEvent::ESwitchOff:
1.1284 + case TRawEvent::ECaseClose:
1.1285 + {
1.1286 + TBool switchOff=(eventType==TRawEvent::ESwitchOff);
1.1287 + CWsTop::HandleSwitchOff(switchOff? EEventSwitchOff:EEventCaseClosed,switchOff);
1.1288 + break;
1.1289 + }
1.1290 +#ifdef SYMBIAN_PROCESS_MONITORING_AND_STARTUP
1.1291 + case TRawEvent::ERestartSystem:
1.1292 + { /* restart event being handled */
1.1293 + CWsTop::HandleSwitchOff(EEventRestartSystem,ETrue);
1.1294 + break;
1.1295 + }
1.1296 +#endif
1.1297 + case TRawEvent::EInactive:
1.1298 +#ifndef __WINS__
1.1299 + CWsTop::WindowServer()->AnimationScheduler()->OnInactive();
1.1300 +#endif
1.1301 + CKeyboardRepeat::CancelRepeat(NULL);
1.1302 + break;
1.1303 + case TRawEvent::EActive:
1.1304 +#ifndef __WINS__
1.1305 + CWsTop::WindowServer()->AnimationScheduler()->OnActive();
1.1306 +#endif
1.1307 + break;
1.1308 + case TRawEvent::EKeyDown:
1.1309 + {
1.1310 +#ifdef LOG_WSERV_EVENTS
1.1311 + RDebug::Printf("_WSEVENT_KEY: TRawEvent::EKeyDown");
1.1312 +#endif
1.1313 + _LIT(KWSERVDebugLogKeyDownArrival,"Key down arrives %d");
1.1314 + CScreen* screen = CWsTop::Screen();
1.1315 + WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen);
1.1316 + if(CDebugBar* dbg = screen->DebugBar())
1.1317 + dbg->OnKeyEvent();
1.1318 + if (wsDebugLog)
1.1319 + wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyDownArrival,aRawEvent.ScanCode());
1.1320 + CKeyboardRepeat::KeyDown();
1.1321 + TKeyData keyData;
1.1322 + // Note iCaptureKeys is needed as dummy arg only. Key capture is
1.1323 + // now handled in ProcessKeyPress().
1.1324 + TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), EFalse,*iCaptureKeys,keyData);
1.1325 + ProcessModifierChanges();
1.1326 + QueueKeyUpDown(aRawEvent);
1.1327 + if (translated)
1.1328 + {
1.1329 + TKeyEvent keyEvent;
1.1330 + keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
1.1331 + keyEvent.iCode = keyData.iKeyCode;
1.1332 + keyEvent.iModifiers = keyData.iModifiers;
1.1333 + ProcessKeyPress(keyEvent, ETrue, 0);
1.1334 + }
1.1335 + }
1.1336 + break;
1.1337 + case TRawEvent::EKeyUp:
1.1338 + {
1.1339 +#ifdef LOG_WSERV_EVENTS
1.1340 + RDebug::Printf("_WSEVENT_KEY: TRawEvent::EKeyUp");
1.1341 +#endif
1.1342 + _LIT(KWSERVDebugLogKeyUpArrival,"Key up arrives %d");
1.1343 + CScreen* screen = CWsTop::Screen();
1.1344 + WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen);
1.1345 + if(CDebugBar* dbg = screen->DebugBar())
1.1346 + dbg->OnKeyEvent();
1.1347 + if (wsDebugLog)
1.1348 + wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyUpArrival,aRawEvent.ScanCode());
1.1349 + TKeyData keyData;
1.1350 + CKeyboardRepeat::KeyUp(aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE);
1.1351 + TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), ETrue,*iCaptureKeys,keyData);
1.1352 + ProcessModifierChanges();
1.1353 + QueueKeyUpDown(aRawEvent);
1.1354 + if (translated)
1.1355 + {
1.1356 + CKeyboardRepeat::CancelRepeat(NULL);
1.1357 + TKeyEvent keyEvent;
1.1358 + keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
1.1359 + keyEvent.iCode = keyData.iKeyCode;
1.1360 + keyEvent.iModifiers = keyData.iModifiers;
1.1361 + ProcessKeyPress(keyEvent, EFalse, 0);
1.1362 + }
1.1363 + }
1.1364 + break;
1.1365 + case TRawEvent::EButton1Down:
1.1366 + case TRawEvent::EButton2Down:
1.1367 + case TRawEvent::EButton3Down:
1.1368 + case TRawEvent::EPointerSwitchOn:
1.1369 +#ifndef __WINS__
1.1370 + CWsTop::WindowServer()->AnimationScheduler()->OnActive();
1.1371 +#endif
1.1372 + // fall through
1.1373 + case TRawEvent::EButton1Up:
1.1374 + case TRawEvent::EButton2Up:
1.1375 + case TRawEvent::EButton3Up:
1.1376 + case TRawEvent::EPointerMove:
1.1377 + case TRawEvent::EPointer3DOutOfRange:
1.1378 + #if defined(_DEBUG)
1.1379 + WS_ASSERT_DEBUG(MousePress(aRawEvent,NULL), EWsPanicEventType);
1.1380 + #else
1.1381 + MousePress(aRawEvent,NULL);
1.1382 + #endif
1.1383 + break;
1.1384 + case TRawEvent::EUpdateModifiers:
1.1385 + iKeyTranslator->UpdateModifiers(aRawEvent.Modifiers());
1.1386 + break;
1.1387 + case TRawEvent::EKeyRepeat:
1.1388 + {
1.1389 + _LIT(KWSERVDebugLogRepeatingKeyArrival,"Repeating key arrives %d");
1.1390 + if (wsDebugLog)
1.1391 + wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogRepeatingKeyArrival,aRawEvent.ScanCode());
1.1392 + TKeyEvent keyEvent;
1.1393 + keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE;
1.1394 + keyEvent.iCode = aRawEvent.ScanCode();
1.1395 + keyEvent.iModifiers = iKeyTranslator->GetModifierState();
1.1396 + ProcessKeyPress(keyEvent, EFalse, aRawEvent.Repeats());
1.1397 + }
1.1398 + break;
1.1399 + default:
1.1400 + break;
1.1401 + }
1.1402 +#ifdef LOG_WSERV_EVENTS
1.1403 + 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);
1.1404 + 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);
1.1405 +#endif
1.1406 + }
1.1407 +
1.1408 +void TWindowServerEvent::ProcessKeyEvent(const TKeyEvent &aKeyEvent,TInt aRepeats)
1.1409 + {
1.1410 +#ifdef LOG_WSERV_EVENTS
1.1411 + RDebug::Printf("_WSEVENT_KEY: TWindowServerEvent::ProcessKeyEvent, key code: %d, repeat: %d", aKeyEvent.iCode, aRepeats);
1.1412 +#endif
1.1413 + TKeyData keyData;
1.1414 + keyData.iModifiers=aKeyEvent.iModifiers;
1.1415 + keyData.iApp=0;
1.1416 + keyData.iHandle=0;
1.1417 + keyData.iIsCaptureKey=EFalse;
1.1418 + keyData.iKeyCode=aKeyEvent.iCode;
1.1419 + if (CKeyboardRepeat::IsAreadyActive())
1.1420 + {
1.1421 + CKeyboardRepeat::CancelRepeat(NULL);
1.1422 + }
1.1423 + ProcessKeyPress(aKeyEvent, aRepeats == 0, aRepeats);
1.1424 + }
1.1425 +
1.1426 +void TWindowServerEvent::AddCaptureKeyL(const TKeyCaptureRequest& aRequest)
1.1427 + {
1.1428 + iKeyEventRouter->AddCaptureKeyL(aRequest);
1.1429 + }
1.1430 +
1.1431 +void TWindowServerEvent::UpdateCaptureKeyL(const TKeyCaptureRequest& aRequest)
1.1432 + {
1.1433 + iKeyEventRouter->UpdateCaptureKeyL(aRequest);
1.1434 + }
1.1435 +
1.1436 +void TWindowServerEvent::CancelCaptureKey(TKeyCaptureType aType, TAny* aHandle)
1.1437 + {
1.1438 + iKeyEventRouter->CancelCaptureKey(aType, aHandle);
1.1439 + }
1.1440 +
1.1441 +TInt TWindowServerEvent::GetModifierState()
1.1442 + {
1.1443 + return(iKeyTranslator->GetModifierState());
1.1444 + }
1.1445 +
1.1446 +void TWindowServerEvent::SetModifierState(TEventModifier aModifier,TModifierState aState)
1.1447 + {
1.1448 + iKeyTranslator->SetModifierState(aModifier,aState);
1.1449 + }
1.1450 +
1.1451 +TInt TWindowServerEvent::AddNotificationHandler(CAnim* aAnim, TUint32 aNotifications)
1.1452 + {
1.1453 + SNotificationHandler notif;
1.1454 + notif.iAnim = aAnim;
1.1455 + notif.iNotifications = aNotifications;
1.1456 +
1.1457 + // update the entry if the anim is already in the array
1.1458 + TInt count=iNotificationHandlers->Count();
1.1459 + TInt ii;
1.1460 + for(ii=0;ii<count;++ii)
1.1461 + {
1.1462 + if ((*iNotificationHandlers)[ii].iAnim==aAnim)
1.1463 + {
1.1464 + (*iNotificationHandlers)[ii]=notif;
1.1465 + return KErrNone;
1.1466 + }
1.1467 + }
1.1468 +
1.1469 + // otherwise add it to the array
1.1470 + TRAPD(err,iNotificationHandlers->AppendL(notif));
1.1471 + return err;
1.1472 + }
1.1473 +
1.1474 +void TWindowServerEvent::RemoveNotificationHandler(CAnim* aAnim)
1.1475 + {
1.1476 + TInt count=iNotificationHandlers->Count();
1.1477 + TInt ii;
1.1478 + for(ii=0;ii<count;++ii)
1.1479 + {
1.1480 + if ((*iNotificationHandlers)[ii].iAnim==aAnim)
1.1481 + {
1.1482 + iNotificationHandlers->Delete(ii);
1.1483 + return;
1.1484 + }
1.1485 + }
1.1486 + }
1.1487 +
1.1488 +void TWindowServerEvent::PublishNotification(const TWsEvent& aWsEvent)
1.1489 + {
1.1490 + TInt count=iNotificationHandlers->Count();
1.1491 + TInt ii;
1.1492 + for(ii=0;ii<count;++ii)
1.1493 + {
1.1494 + SNotificationHandler notif = (*iNotificationHandlers)[ii];
1.1495 + switch (aWsEvent.Type())
1.1496 + {
1.1497 + case EEventDirectScreenAccessBegin:
1.1498 + case EEventDirectScreenAccessEnd:
1.1499 + if (notif.iNotifications & EDirectScreenAccess)
1.1500 + {
1.1501 + notif.iAnim->HandleNotification(aWsEvent);
1.1502 + }
1.1503 + break;
1.1504 + case EEventHeartbeatTimerStateChange:
1.1505 + if (notif.iNotifications & EHeartbeatTimer)
1.1506 + {
1.1507 + notif.iAnim->HandleNotification(aWsEvent);
1.1508 + }
1.1509 + break;
1.1510 + case EEventScreenDeviceChanged:
1.1511 + if (notif.iNotifications & EScreenDeviceChange)
1.1512 + {
1.1513 + notif.iAnim->HandleNotification(aWsEvent);
1.1514 + }
1.1515 + break;
1.1516 + default:
1.1517 + break;
1.1518 + }
1.1519 + }
1.1520 +
1.1521 + }
1.1522 +
1.1523 +TBool TWindowServerEvent::DrawerCompareFunc(const TDrawerHandler& lhs, const TDrawerHandler& rhs)
1.1524 + {
1.1525 + return lhs.iDrawer == rhs.iDrawer;
1.1526 + }
1.1527 +
1.1528 +TInt TWindowServerEvent::RegisterDrawerHandler(CWsGraphicDrawer* aDrawer, TUint32 aEvents)
1.1529 + {
1.1530 + TInt idx = iDrawerHandlers->Find(TDrawerHandler(aDrawer, aEvents),
1.1531 + TIdentityRelation<TDrawerHandler>(TWindowServerEvent::DrawerCompareFunc));
1.1532 + if (idx != KErrNotFound)
1.1533 + {
1.1534 + // replace event mask for this drawer
1.1535 + (*iDrawerHandlers)[idx].iEvents = aEvents;
1.1536 + idx = KErrNone;
1.1537 + }
1.1538 + else
1.1539 + idx = iDrawerHandlers->Append(TDrawerHandler(aDrawer,aEvents));
1.1540 +
1.1541 + return idx;
1.1542 + }
1.1543 +
1.1544 +TInt TWindowServerEvent::UnregisterDrawerHandler(CWsGraphicDrawer* aDrawer)
1.1545 + {
1.1546 + TInt idx = iDrawerHandlers->Find(TDrawerHandler(aDrawer,0),
1.1547 + TIdentityRelation<TDrawerHandler>(TWindowServerEvent::DrawerCompareFunc));
1.1548 + if (idx == KErrNotFound)
1.1549 + return idx;
1.1550 + (*iDrawerHandlers)[idx].iDrawer = NULL; //NotifyDrawer() will clean up the array
1.1551 + return KErrNone;
1.1552 + }
1.1553 +
1.1554 +TInt TWindowServerEvent::RegisterWsEventHandler(MWsEventHandler * aHandler, TUint32 aEvents)
1.1555 + {
1.1556 + TWsEventHandler handler(aHandler, aEvents);
1.1557 + TInt idx = iWsEventHandlers.Find(handler, TIdentityRelation<TWsEventHandler>(TWsEventHandler::CompareHandler));
1.1558 + if (idx < 0)
1.1559 + {
1.1560 + TInt err = iWsEventHandlers.Append(handler);
1.1561 + return err;
1.1562 + }
1.1563 + else
1.1564 + {
1.1565 + iWsEventHandlers[idx].iEvents = aEvents;
1.1566 + return KErrNone;
1.1567 + }
1.1568 + }
1.1569 +
1.1570 +TInt TWindowServerEvent::UnregisterWsEventHandler(MWsEventHandler * aHandler)
1.1571 + {
1.1572 + TWsEventHandler handler(aHandler, 0);
1.1573 + TInt idx = iWsEventHandlers.Find(handler, TIdentityRelation<TWsEventHandler>(TWsEventHandler::CompareHandler));
1.1574 + if (idx < 0)
1.1575 + return idx;
1.1576 + iWsEventHandlers[idx].iEvents = NULL; //NotifyDrawer() will clean up the array
1.1577 + return KErrNone;
1.1578 + }
1.1579 +
1.1580 +
1.1581 +void TWindowServerEvent::NotifyDrawer(const TWservCrEvent& aEvent)
1.1582 + {
1.1583 + TInt drawerCount = iDrawerHandlers->Count();
1.1584 + for (TInt idx = 0; idx < drawerCount; idx++)
1.1585 + {
1.1586 + TDrawerHandler hd = (*iDrawerHandlers)[idx];
1.1587 + if (!hd.iDrawer)
1.1588 + { //If the handler has been removed
1.1589 + iDrawerHandlers->Remove(idx); //Remove from the array
1.1590 + drawerCount -= 1; //Update the counters
1.1591 + idx -= 1;
1.1592 + }
1.1593 + else
1.1594 + {
1.1595 + if (hd.iEvents & aEvent.Type())
1.1596 + {
1.1597 + hd.iDrawer->HandleEvent(aEvent);
1.1598 + }
1.1599 + }
1.1600 + }
1.1601 +
1.1602 + TInt eventHandlerCount = iWsEventHandlers.Count();
1.1603 + for (TInt idx = 0; idx < eventHandlerCount; ++idx)
1.1604 + {
1.1605 + TWsEventHandler* eh = &iWsEventHandlers[idx];
1.1606 + if (!eh->iEvents)
1.1607 + { //If the handler has been removed
1.1608 + iWsEventHandlers.Remove(idx); //Remove from the array
1.1609 + eventHandlerCount -= 1; //Update the counters
1.1610 + idx -= 1;
1.1611 + }
1.1612 + else
1.1613 + {
1.1614 + if (eh->iEvents & aEvent.Type())
1.1615 + {
1.1616 + eh->iHandler->DoHandleEvent(aEvent);
1.1617 + }
1.1618 + }
1.1619 + }
1.1620 + }
1.1621 +
1.1622 +void TWindowServerEvent::NotifyScreenDrawingEvent(const TRegion* aRegion)
1.1623 + {
1.1624 + if (aRegion && !aRegion->IsEmpty())
1.1625 + {
1.1626 + TWservCrEvent event(TWservCrEvent::EScreenDrawing,0,const_cast<TRegion*>(aRegion));
1.1627 + NotifyDrawer(event);
1.1628 + }
1.1629 + }
1.1630 +
1.1631 +void TWindowServerEvent::NotifyScreenDrawingEvent(const TRect& aRect)
1.1632 + {
1.1633 + TRegionFix<1> reg(aRect);
1.1634 + TWservCrEvent event(TWservCrEvent::EScreenDrawing,0,®);
1.1635 + NotifyDrawer(event);
1.1636 + }
1.1637 +
1.1638 +//
1.1639 +// CRawEventReceiver //
1.1640 +//
1.1641 +
1.1642 +CRawEventReceiver::CRawEventReceiver(TInt aPriority) : CActive(aPriority)
1.1643 +//
1.1644 +// Constructor
1.1645 +//
1.1646 + {
1.1647 + __DECLARE_NAME(_S("CRawEventReceiver"));
1.1648 + }
1.1649 +
1.1650 +CRawEventReceiver::~CRawEventReceiver()
1.1651 + {
1.1652 + CActive::Cancel();
1.1653 + }
1.1654 +
1.1655 +void CRawEventReceiver::ConstructL()
1.1656 + {
1.1657 + CActiveScheduler::Add(this);
1.1658 + UserSvr::CaptureEventHook();
1.1659 + Request();
1.1660 + }
1.1661 +
1.1662 +void CRawEventReceiver::Request()
1.1663 +//
1.1664 +// Issue a request for the next event.
1.1665 +//
1.1666 + {
1.1667 + UserSvr::RequestEvent(iEventBuf,iStatus);
1.1668 + SetActive();
1.1669 + }
1.1670 +
1.1671 +void CRawEventReceiver::DoCancel()
1.1672 +//
1.1673 +// Cancel a pending event.
1.1674 +//
1.1675 + {
1.1676 + UserSvr::RequestEventCancel();
1.1677 + }
1.1678 +
1.1679 +void CRawEventReceiver::RunL()
1.1680 + {
1.1681 +#ifdef LOG_WSERV_EVENTS
1.1682 + RDebug::Printf("_WSEVENT_KEY: CRawEventReceiver::RunL Entry point for event receiver");
1.1683 +#endif
1.1684 +//__PROFILE_START(11);
1.1685 + if (TWsPointer::PreProcessDriverEvent(iEventBuf.Event()
1.1686 +#if defined(__WINS__)
1.1687 + ,ETrue
1.1688 +#endif
1.1689 + ))
1.1690 + TWindowServerEvent::ProcessRawEvent(iEventBuf.Event());
1.1691 + Request();
1.1692 +//__PROFILE_END(11);
1.1693 + }
1.1694 +
1.1695 +//
1.1696 +// TEventRequestQueue //
1.1697 +//
1.1698 +
1.1699 +TEventRequestQueue::TEventRequestQueue() : iQueue(_FOFF(TEventRequestItem,iQue))
1.1700 + {}
1.1701 +
1.1702 +inline TSglQue<TEventRequestItem> &TEventRequestQueue::Queue()
1.1703 + {return(iQueue);}
1.1704 +
1.1705 +TEventRequestItem *TEventRequestQueue::FindInEventRequestQueueList(const CWsWindowBase &aWindow)
1.1706 +//
1.1707 +// Return a pointer to the link in the queue for the window, or NULL if not in the queue
1.1708 +//
1.1709 + {
1.1710 + TSglQueIter<TEventRequestItem> iter(iQueue);
1.1711 + TEventRequestItem *qPtr;
1.1712 + while((qPtr=iter++)!=NULL)
1.1713 + if (qPtr->iWindow==&aWindow)
1.1714 + break;
1.1715 + return(qPtr);
1.1716 + }
1.1717 +
1.1718 +void TEventRequestQueue::AddToEventRequestListL(const CWsWindowBase &aWindow, TInt aParam, TEventControl aCircumstances)
1.1719 +//
1.1720 +// Add a link to the on event list
1.1721 +//
1.1722 + {
1.1723 + TEventRequestItem *item=FindInEventRequestQueueList(aWindow);
1.1724 + if (!item)
1.1725 + {
1.1726 + item=new(ELeave) TEventRequestItem;
1.1727 + item->iWindow= &aWindow;
1.1728 + item->iParam=aParam;
1.1729 + item->iCircumstances=aCircumstances;
1.1730 + iQueue.AddFirst(*item);
1.1731 + }
1.1732 + item->iCircumstances=aCircumstances;
1.1733 + item->iParam=aParam; // Just update the parameter if already exists
1.1734 + }
1.1735 +
1.1736 +void TEventRequestQueue::RemoveFromEventRequestListL(const CWsWindowBase &aWindow)
1.1737 +//
1.1738 +// Remove a link from the on event list
1.1739 +//
1.1740 + {
1.1741 + TEventRequestItem *qPtr=FindInEventRequestQueueList(aWindow);
1.1742 + if (qPtr)
1.1743 + {
1.1744 + iQueue.Remove(*qPtr);
1.1745 + delete qPtr;
1.1746 + }
1.1747 + }
1.1748 +
1.1749 +//
1.1750 +// Keyboard auto repeat class //
1.1751 +//
1.1752 +
1.1753 +CKeyboardRepeat::CKeyboardRepeat() : CTimer(EKeyRepeatPriority)
1.1754 + {}
1.1755 +
1.1756 +void CKeyboardRepeat::NewL()
1.1757 + {
1.1758 + iThis=new(ELeave) CKeyboardRepeat();
1.1759 + iThis->ConstructL();
1.1760 + CActiveScheduler::Add(iThis);
1.1761 + _LIT(KWSERVIniFileVarRepeatRollover,"REPEATROLLOVER");
1.1762 + WsIniFile->FindVar(KWSERVIniFileVarRepeatRollover,iRepeatRollover);
1.1763 + }
1.1764 +
1.1765 +void CKeyboardRepeat::Destroy()
1.1766 + {
1.1767 + delete iThis;
1.1768 + }
1.1769 +
1.1770 +void CKeyboardRepeat::GetRepeatTime(TTimeIntervalMicroSeconds32 &aInitialTime, TTimeIntervalMicroSeconds32 &aTime)
1.1771 + {
1.1772 + aInitialTime=iInitialTime;
1.1773 + aTime=iTime;
1.1774 + }
1.1775 +
1.1776 +void CKeyboardRepeat::SetRepeatTime(const TTimeIntervalMicroSeconds32 &aInitialTime, const TTimeIntervalMicroSeconds32 &aTime)
1.1777 + {
1.1778 + iInitialTime=aInitialTime;
1.1779 + iTime=aTime;
1.1780 + }
1.1781 +
1.1782 +/**
1.1783 +Process timer events.
1.1784 +
1.1785 +Called when the key repeat timer expires, this function generates the
1.1786 +appropriate long key or repeated key event. If the timer was started for
1.1787 +normal key repeat or if the long key event was captured with the automatic
1.1788 +repeat option specified then the timer is restarted.
1.1789 +*/
1.1790 +void CKeyboardRepeat::RunL()
1.1791 + {
1.1792 + User::ResetInactivityTime();
1.1793 + WS_ASSERT_DEBUG(iRepeating != ERepeatNone, EWsPanicKeyRepeat);
1.1794 + TBool timer=ETrue;
1.1795 + if (iRepeating>=ERepeatLong)
1.1796 + {
1.1797 + // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
1.1798 + WS_ASSERT_DEBUG(iLongCapture != NULL, EWsPanicKeyRepeat);
1.1799 + if (iLongCapture)
1.1800 + {
1.1801 + iCurrentRepeat = iLongRepeat;
1.1802 + timer = iLongCapture->iFlags & ELongCaptureRepeatEvents;
1.1803 + iRepeating=ERepeatLongRepeated;
1.1804 + }
1.1805 + else
1.1806 + {
1.1807 + // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
1.1808 + // Stop key repeat if this incorrect condition occurs
1.1809 + timer=EFalse;
1.1810 + }
1.1811 + }
1.1812 + if (timer)
1.1813 + After(iTime);
1.1814 + else
1.1815 + iRepeating=ERepeatNone;
1.1816 +
1.1817 + TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iOutput, ETrue, 1);
1.1818 + }
1.1819 +
1.1820 +/**
1.1821 +Start key repeat and long key press timer
1.1822 +
1.1823 +@param aInputScanCode Original scan code (before routing)
1.1824 +@param aShortEvent Short key event (routing plug-in output)
1.1825 +@param aLongEvent Pointer to long key event (routing plug-in output)
1.1826 + or NULL if none.
1.1827 +
1.1828 +Note: When aLongEvent != NULL, iCurrentRepeat reflects the short key event
1.1829 +until the timer has expired. This is necessary to allow a delayed short key
1.1830 +event to be delivered by KeyUp(). CancelRepeat() must therefore examine
1.1831 +iCurrentRepeat or iLongRepeat according to the repeat type in iRepeat.
1.1832 +*/
1.1833 +void CKeyboardRepeat::StartRepeat(TInt aInputScanCode, const TKeyEventRouterOutput& aShortEvent, const TKeyEventRouterOutput* aLongEvent)
1.1834 + {
1.1835 + TTimeIntervalMicroSeconds32 time;
1.1836 + iCurrentRepeat.iInputScanCode = aInputScanCode;
1.1837 + iCurrentRepeat.iOutput = aShortEvent;
1.1838 +
1.1839 + if (aLongEvent)
1.1840 + {
1.1841 + iRepeating = ERepeatLong;
1.1842 + iLongRepeat.iInputScanCode = aInputScanCode;
1.1843 + iLongRepeat.iOutput = *aLongEvent;
1.1844 + iLongCapture = static_cast<CWsCaptureLongKey*>(aLongEvent->iCaptureHandle);
1.1845 + time = iLongCapture->iDelay;
1.1846 + }
1.1847 + else
1.1848 + {
1.1849 + iLongCapture = NULL;
1.1850 + iRepeating=ERepeatNormal;
1.1851 + time=iInitialTime;
1.1852 + }
1.1853 + iThis->After(time);
1.1854 + }
1.1855 +
1.1856 +/**
1.1857 +Cancel key repeat processing
1.1858 +*/
1.1859 +void CKeyboardRepeat::doCancelRepeat()
1.1860 + {
1.1861 + iRepeating=ERepeatNone;
1.1862 + iThis->Cancel();
1.1863 + }
1.1864 +
1.1865 +/**
1.1866 +Cancel any key repeat associated with the specified window group
1.1867 +
1.1868 +@param aRepeatFocus Destination window group or NULL for all
1.1869 +*/
1.1870 +void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus)
1.1871 + {
1.1872 + if (iRepeating != ERepeatNone)
1.1873 + {
1.1874 + if (aRepeatFocus == NULL ||
1.1875 + (iRepeating == ERepeatNormal) && (aRepeatFocus == iCurrentRepeat.iOutput.iWindowGroup) ||
1.1876 + (iRepeating >= ERepeatLong) && (aRepeatFocus == iLongRepeat.iOutput.iWindowGroup))
1.1877 + {
1.1878 + doCancelRepeat();
1.1879 + iAlternateRepeatExists=EFalse;
1.1880 + }
1.1881 + }
1.1882 + }
1.1883 +
1.1884 +/**
1.1885 +Cancel any key repeat associated with the specified capture handle
1.1886 +
1.1887 +@param aCaptureHandle Handle to capture request
1.1888 +@param aLongCaptureFlag ETrue for long key capture, EFalse for normal key
1.1889 +*/
1.1890 +void CKeyboardRepeat::CancelRepeat(const TAny* aCaptureHandle, TBool aLongCaptureFlag)
1.1891 + {
1.1892 + if (aLongCaptureFlag)
1.1893 + {
1.1894 + // Cancel repeat for long capture key
1.1895 + if (iRepeating >= ERepeatLong && aCaptureHandle == iLongRepeat.iOutput.iCaptureHandle)
1.1896 + {
1.1897 + doCancelRepeat();
1.1898 + iAlternateRepeatExists=EFalse;
1.1899 + }
1.1900 + }
1.1901 + else
1.1902 + {
1.1903 + // Cancel repeat for normal capture key
1.1904 + if (iRepeating == ERepeatNormal && aCaptureHandle == iCurrentRepeat.iOutput.iCaptureHandle)
1.1905 + {
1.1906 + doCancelRepeat();
1.1907 + iAlternateRepeatExists=EFalse;
1.1908 + }
1.1909 + }
1.1910 + }
1.1911 +
1.1912 +/**
1.1913 +Process a key down event during key repeat.
1.1914 +The current repeat data is saved for possible restoration after rollover.
1.1915 +*/
1.1916 +void CKeyboardRepeat::KeyDown()
1.1917 + {
1.1918 + if (iRepeating!=ERepeatNone)
1.1919 + {
1.1920 + if (iRepeating==ERepeatNormal && iRepeatRollover>0) // 1 Allow key repeat rollover
1.1921 + {
1.1922 + iAlternateRepeat=iCurrentRepeat;
1.1923 + iAlternateRepeatExists=ETrue;
1.1924 + }
1.1925 + doCancelRepeat();
1.1926 + }
1.1927 + }
1.1928 +
1.1929 +/**
1.1930 +Process a key up event during key repeat.
1.1931 +Send delayed short key event if necessary for long key event processing.
1.1932 +Switch to alternate repeat if rollover key was released.
1.1933 +
1.1934 +@param aScanCode Scan code
1.1935 +*/
1.1936 +void CKeyboardRepeat::KeyUp(TInt aScanCode)
1.1937 + {
1.1938 + if (iAlternateRepeatExists && iAlternateRepeat.iInputScanCode == aScanCode)
1.1939 + iAlternateRepeatExists=EFalse;
1.1940 + if (iRepeating != ERepeatNone && iCurrentRepeat.iInputScanCode == aScanCode)
1.1941 + {
1.1942 + if (iRepeating==ERepeatLong)
1.1943 + {
1.1944 + // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong
1.1945 + WS_ASSERT_DEBUG(iLongCapture != NULL, EWsPanicKeyRepeat);
1.1946 + if (iLongCapture && !(iLongCapture->iFlags & ELongCaptureShortEventImmediately))
1.1947 + {
1.1948 + TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iOutput, EFalse, 0);
1.1949 + }
1.1950 + }
1.1951 + if (iAlternateRepeatExists)
1.1952 + {
1.1953 + iAlternateRepeatExists=EFalse;
1.1954 + iCurrentRepeat=iAlternateRepeat;
1.1955 + iRepeating=ERepeatNormal;
1.1956 + }
1.1957 + else
1.1958 + doCancelRepeat();
1.1959 + }
1.1960 + }
1.1961 +
1.1962 +//
1.1963 +// CWsHotKey //
1.1964 +//
1.1965 +
1.1966 +CWsHotKey::CWsHotKey(TInt aHotKeyType, TBool aIsDefault) :
1.1967 + iHotKeyType(aHotKeyType),
1.1968 + iIsDefault(aIsDefault)
1.1969 + {
1.1970 + }
1.1971 +
1.1972 +CWsHotKey::~CWsHotKey()
1.1973 + {
1.1974 + delete iCaptureKey;
1.1975 + }
1.1976 +
1.1977 +void CWsHotKey::ConstructLD(const TWsWinCmdCaptureKey &aCaptureKey)
1.1978 + {
1.1979 + CleanupStack::PushL(this);
1.1980 + iCaptureKey=new(ELeave) CWsCaptureKey(NULL);
1.1981 + iCaptureKey->ConstructL(aCaptureKey);
1.1982 + CleanupStack::Pop();
1.1983 + }
1.1984 +
1.1985 +void CWsHotKey::SetL(const TWsWinCmdCaptureKey &aCaptureKey)
1.1986 + {
1.1987 + iCaptureKey->SetL(aCaptureKey);
1.1988 + }
1.1989 +
1.1990 +//
1.1991 +//CEventQueueRetry//
1.1992 +//
1.1993 +CEventQueueRetry* CEventQueueRetry::NewL()
1.1994 + {
1.1995 + CEventQueueRetry* self = new (ELeave) CEventQueueRetry;
1.1996 + CleanupStack::PushL(self);
1.1997 + self->ConstructL();
1.1998 + CleanupStack::Pop(self);
1.1999 + return self;
1.2000 + }
1.2001 +
1.2002 +void CEventQueueRetry::ConstructL()
1.2003 + {
1.2004 + User::LeaveIfError(iTimer.CreateLocal());
1.2005 + CActiveScheduler::Add(this);
1.2006 + }
1.2007 +
1.2008 +CEventQueueRetry::CEventQueueRetry() : CActive(EPriorityStandard), iRetrySpinner(1)
1.2009 + {
1.2010 +
1.2011 + }
1.2012 +
1.2013 +CEventQueueRetry::~CEventQueueRetry()
1.2014 + {
1.2015 + Cancel();
1.2016 + iTimer.Close();
1.2017 + iClientArray.Close();
1.2018 + }
1.2019 +
1.2020 +void CEventQueueRetry::DoCancel()
1.2021 + {
1.2022 + iTimer.Cancel();
1.2023 + iRetrySpinner = 0;
1.2024 + iClientArray.Reset();
1.2025 + }
1.2026 +
1.2027 +void CEventQueueRetry::RunL()
1.2028 + {
1.2029 + //some clients may be no longer interested in listening
1.2030 + //so we need to refresh the client list each round of retry
1.2031 + iClientArray.Reset();
1.2032 + TInt err = iOwner->GetNotificationClients(iClientArray);
1.2033 + if(err != KErrNone)
1.2034 + {
1.2035 + iClientArray.Reset(); //so the retry won't kick off
1.2036 + }
1.2037 + if(iClientArray.Count() > 0)
1.2038 + {
1.2039 + TBool eventOnAllQueues = ETrue;
1.2040 + for(TInt i = 0; i < iClientArray.Count(); i++)
1.2041 + {
1.2042 + if(iClientArray[i]->RetryEvent(EEventDisplayChanged))
1.2043 + {
1.2044 + if(TWindowServerEvent::SendDisplayChangedEvents(iClientArray[i], iOwner->ScreenNumber(),
1.2045 + iOwner->ConfigSpinner(), iOwner->DisplaySpinner()))
1.2046 + {
1.2047 + iClientArray[i]->RemoveRetryFlag(EEventDisplayChanged);
1.2048 + }
1.2049 + else
1.2050 + {
1.2051 + eventOnAllQueues = EFalse;
1.2052 + }
1.2053 + }
1.2054 + }
1.2055 +
1.2056 + if(!eventOnAllQueues)
1.2057 + {//another retry needed, but with increased time interval
1.2058 + iRetrySpinner++;
1.2059 + Retry(KRetryInitialDelay*iRetrySpinner);
1.2060 + }
1.2061 + }
1.2062 +
1.2063 + }
1.2064 +
1.2065 +void CEventQueueRetry::Retry(TInt aDelay)
1.2066 + {
1.2067 + //the retry might be infinite, with an increasing interval, as delivery of the event is garuanteed
1.2068 + //if aDelay is greater than max TInt, it will be negative number so we reset it to KRetryInitialDelay
1.2069 + if(aDelay < 0)
1.2070 + {
1.2071 + aDelay = KRetryInitialDelay;
1.2072 + }
1.2073 + iTimer.After(iStatus, aDelay);
1.2074 + SetActive();
1.2075 + }
1.2076 +
1.2077 +void CEventQueueRetry::Init(CScreen *aOwner)
1.2078 + {
1.2079 + iOwner = aOwner;
1.2080 + iRetrySpinner = 0;
1.2081 +
1.2082 + }
1.2083 +
1.2084 +void CEventQueueRetry::CancelRetry()
1.2085 + {
1.2086 + Cancel();
1.2087 + }