178 RArray<TDrawerHandler>* TWindowServerEvent::iDrawerHandlers; |
171 RArray<TDrawerHandler>* TWindowServerEvent::iDrawerHandlers; |
179 RArray<TWsEventHandler> TWindowServerEvent::iWsEventHandlers; |
172 RArray<TWsEventHandler> TWindowServerEvent::iWsEventHandlers; |
180 TInt TWindowServerEvent::iEventHandlerCount=0; |
173 TInt TWindowServerEvent::iEventHandlerCount=0; |
181 TRepeatKey CKeyboardRepeat::iCurrentRepeat; |
174 TRepeatKey CKeyboardRepeat::iCurrentRepeat; |
182 TRepeatKey CKeyboardRepeat::iAlternateRepeat; |
175 TRepeatKey CKeyboardRepeat::iAlternateRepeat; |
183 TRepeatKey CKeyboardRepeat::iLongRepeat; |
|
184 TInt CKeyboardRepeat::iRepeatRollover=1; |
176 TInt CKeyboardRepeat::iRepeatRollover=1; |
185 CKeyboardRepeat::TRepeatType CKeyboardRepeat::iRepeating=ERepeatNone; |
177 CKeyboardRepeat::TRepeatType CKeyboardRepeat::iRepeating=ERepeatNone; |
186 CKeyboardRepeat *CKeyboardRepeat::iThis=NULL; |
178 CKeyboardRepeat *CKeyboardRepeat::iThis=NULL; |
187 TTimeIntervalMicroSeconds32 CKeyboardRepeat::iInitialTime; |
179 TTimeIntervalMicroSeconds32 CKeyboardRepeat::iInitialTime; |
188 TTimeIntervalMicroSeconds32 CKeyboardRepeat::iTime; |
180 TTimeIntervalMicroSeconds32 CKeyboardRepeat::iTime; |
|
181 CWsWindowGroup *CKeyboardRepeat::iFocus=NULL; |
189 TBool CKeyboardRepeat::iAlternateRepeatExists=EFalse; |
182 TBool CKeyboardRepeat::iAlternateRepeatExists=EFalse; |
190 CWsCaptureLongKey* CKeyboardRepeat::iLongCapture=NULL; |
183 CWsCaptureLongKey* CKeyboardRepeat::iLongCapture=NULL; |
|
184 |
|
185 TTimeIntervalMicroSeconds TWindowServerEvent::iPauseInterval; |
|
186 TTime TWindowServerEvent::iPauseStartTime; |
|
187 TInt TWindowServerEvent::iConfigationPauseTime = 0; |
191 |
188 |
192 |
189 |
193 void TWindowServerEvent::DeleteHotKeys() |
190 void TWindowServerEvent::DeleteHotKeys() |
194 { |
191 { |
195 CWsHotKey *hotKey=iHotKeys; |
192 CWsHotKey *hotKey=iHotKeys; |
239 TBuf<16> keyDataDllName; |
234 TBuf<16> keyDataDllName; |
240 keyDataDllName.Format(KLitKeyDataDllName,keyboardIndex); |
235 keyDataDllName.Format(KLitKeyDataDllName,keyboardIndex); |
241 iKeyTranslator->ChangeKeyData(keyDataDllName); |
236 iKeyTranslator->ChangeKeyData(keyDataDllName); |
242 } |
237 } |
243 |
238 |
244 // CCaptureKeys is no longer used but a dummy object is required for |
|
245 // calls to CKeyTranslator::TranslateKey() until capture functionality |
|
246 // has been removed from ektran.dll. |
|
247 iCaptureKeys=new(ELeave) CCaptureKeys; |
239 iCaptureKeys=new(ELeave) CCaptureKeys; |
248 iCaptureKeys->Construct(); |
240 iCaptureKeys->Construct(); |
249 |
|
250 // Load the key event routing plug-in. The DLL name may be overridden |
|
251 // by setting the keyword KEYROUTERPLUGIN in wsini.ini. |
|
252 TPtrC pluginName(KDefaultKeyRouterPluginName); |
|
253 WsIniFile->FindVar(KWSERVIniFileVarKeyRouterPlugin, pluginName); |
|
254 const TUidType uidType(KDynamicLibraryUid, KKeyRouterPluginUid); |
|
255 TInt err = iKeyEventRouterLibrary.Load(pluginName, uidType); |
|
256 |
|
257 if (wsDebugLog) |
|
258 { |
|
259 TLogMessageText buf; |
|
260 |
|
261 if (err == KErrNone) |
|
262 { |
|
263 _LIT(KLogLoadOk, "Loaded plugin '%S' UID3 0x%x"); |
|
264 const TFileName& pluginPathname = iKeyEventRouterLibrary.FileName(); |
|
265 const TUid uid3 = iKeyEventRouterLibrary.Type()[2]; |
|
266 buf.Format(KLogLoadOk, &pluginPathname, uid3.iUid); |
|
267 } |
|
268 else |
|
269 { |
|
270 _LIT(KLogLoadError, "Failed to load plugin '%S' (error %d)"); |
|
271 buf.Format(KLogLoadError, &pluginName, err); |
|
272 } |
|
273 |
|
274 wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant, buf); |
|
275 } |
|
276 |
|
277 if (err != KErrNone) |
|
278 { |
|
279 #ifdef _DEBUG |
|
280 _LIT(KLoadError, "WServ: failed to load plugin '%S' (error %d)"); |
|
281 RDebug::Print(KLoadError, &pluginName, err); |
|
282 #endif |
|
283 User::Leave(err); |
|
284 } |
|
285 |
|
286 // Create the key event router |
|
287 typedef CKeyEventRouter* (*TCreateFunc)(); |
|
288 TCreateFunc newL = reinterpret_cast<TCreateFunc>(iKeyEventRouterLibrary.Lookup(1)); |
|
289 if (newL == NULL) |
|
290 { |
|
291 User::Leave(KErrNotFound); |
|
292 } |
|
293 iKeyEventRouter = (*newL)(); |
|
294 |
|
295 for (TInt index=0;index<TWindowServerEvent::ENumHotKeys;index++) |
241 for (TInt index=0;index<TWindowServerEvent::ENumHotKeys;index++) |
296 ConstructDefaultHotKeyL(index,DefaultHotKeys[index]); |
242 ConstructDefaultHotKeyL(index,DefaultHotKeys[index]); |
297 CKeyboardRepeat::NewL(); |
243 CKeyboardRepeat::NewL(); |
298 CKeyboardRepeat::SetRepeatTime(EDefaultInitialRepeatTime, EDefaultRepeatTime); |
244 CKeyboardRepeat::SetRepeatTime(EDefaultInitialRepeatTime, EDefaultRepeatTime); |
299 iEventHandlers=RArray<TRawEventHandler>(2); |
245 iEventHandlers=RArray<TRawEventHandler>(2); |
300 iNotificationHandlers=new(ELeave) CArrayFixFlat<SNotificationHandler>(2); |
246 iNotificationHandlers=new(ELeave) CArrayFixFlat<SNotificationHandler>(2); |
301 iDrawerHandlers = new(ELeave) RArray<TDrawerHandler>(4); |
247 iDrawerHandlers = new(ELeave) RArray<TDrawerHandler>(4); |
|
248 iPauseInterval = TTimeIntervalMicroSeconds(0); |
|
249 _LIT(KWSERVIniFileVarEventsPauseAfterRotation,"SUPPRESSEVENTSTIMEAFTERROTATION"); |
|
250 WsIniFile->FindVar(KWSERVIniFileVarEventsPauseAfterRotation,iConfigationPauseTime); |
302 } |
251 } |
303 |
252 |
304 void TWindowServerEvent::LinkHotKey(CWsHotKey *aWsHotKey) |
253 void TWindowServerEvent::LinkHotKey(CWsHotKey *aWsHotKey) |
305 { |
254 { |
306 aWsHotKey->SetLink(iHotKeys); |
255 aWsHotKey->SetLink(iHotKeys); |
716 return ETrue; |
664 return ETrue; |
717 } |
665 } |
718 |
666 |
719 void TWindowServerEvent::QueueKeyEvent(CWsWindowGroup *aWin, TWsEvent &aEvent, TWservEventPriorities aPriority) |
667 void TWindowServerEvent::QueueKeyEvent(CWsWindowGroup *aWin, TWsEvent &aEvent, TWservEventPriorities aPriority) |
720 { |
668 { |
721 #ifdef LOG_WSERV_EVENTS |
|
722 RDebug::Print(_L("_WSEVENT_KEY: TWindowServerEvent::QueueKeyEvent, Queuing event name %S for application read, window handle: %d"), &WsEventName(aEvent), CWsTop::FocusWindowGroup()->ClientHandle()); |
|
723 #endif |
|
724 aEvent.SetTimeNow(); |
669 aEvent.SetTimeNow(); |
725 aWin->EventQueue()->QueueEvent(aEvent, aPriority); |
670 aWin->EventQueue()->QueueEvent(aEvent, aPriority); |
726 } |
671 } |
727 |
672 |
728 /** |
673 void TWindowServerEvent::QueueKeyPress(const TKeyData& aKey, TInt aScanCode, CWsWindowGroup* aRepeatFocus, TBool aCheckRepeat,TInt aRepeats) |
729 Process a key press event. |
|
730 |
|
731 This function is called for every input key event and uses the Key Event |
|
732 Routing plug-in to check for short and long key capture and determine the |
|
733 destination window group for the queued event(s). |
|
734 Window server hotkeys are also processed. |
|
735 Note that the key repeat timer is started here but the key repeat events |
|
736 generated by the timer go directly to QueueKeyPress(). |
|
737 |
|
738 @param aKeyEvent Input key event |
|
739 @param aCheckRepeat Check for key repeat and long key capture |
|
740 @param aRepeats Repeat count |
|
741 */ |
|
742 void TWindowServerEvent::ProcessKeyPress(const TKeyEvent& aKeyEvent, TBool aCheckRepeat, TInt aRepeats) |
|
743 { |
674 { |
744 CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup(); |
675 CWsWindowGroup* focusWin=CWsTop::FocusWindowGroup(); |
745 TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid; |
676 TWsEvent event; |
746 |
677 TKeyEvent& keyEvent=*event.Key(); |
747 // Route the key event and check for short key capture. |
678 keyEvent.iCode=aKey.iKeyCode; |
748 // Note that the Key Routing plugin may translate or block key events. |
679 keyEvent.iScanCode=aScanCode; |
749 TKeyEventRouterInput input(ECaptureTypeKey, aKeyEvent, focusWin, focusAppUid); |
680 keyEvent.iModifiers=aKey.iModifiers; |
750 TKeyEventRouterOutput output; |
681 keyEvent.iRepeats=aRepeats; |
751 |
682 if (!aRepeatFocus && CClick::IsHandler()) |
752 #ifdef _DEBUG |
683 CClick::KeyEvent(EEventKey,keyEvent); |
753 // RouteKey() must not fail. Check for leaves in case the plug-in |
684 CWsCaptureLongKey* longCapture=NULL; |
754 // is badly behaved. |
685 if (aCheckRepeat) |
755 TRAPD(err, iKeyEventRouter->RouteKey(input, output)); |
686 longCapture=CWsCaptureLongKey::CheckForCapture(aKey.iKeyCode, aKey.iModifiers); |
756 WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave); |
687 if (aKey.iIsCaptureKey) |
757 #else |
688 { |
758 iKeyEventRouter->RouteKey(input, output); |
689 if (aKey.iApp==NULL) // Captured by Wserv itself |
759 #endif |
|
760 |
|
761 WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured || output.iResult == EConsumed, EWsPanicKeyEventRouterBadResult); |
|
762 |
|
763 if (output.iResult == EConsumed) |
|
764 { |
|
765 focusWin = NULL; |
|
766 } |
|
767 else |
|
768 { |
|
769 focusWin = static_cast<CWsWindowGroup*>(output.iWindowGroup); |
|
770 } |
|
771 WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup); |
|
772 |
|
773 // Ensure that short event is not marked with EModifierLongKey |
|
774 output.iKeyEvent.iModifiers &= ~EModifierLongKey; |
|
775 |
|
776 // Generate key click unless the event is consumed. This is consistent |
|
777 // with the behaviour when CKeyTranslator::TranslateKey() yields no |
|
778 // translation for a particular scan code. (Click events for key up/down |
|
779 // will still be generated by QueueKeyUpDown()). Note however that a long |
|
780 // key press may still be captured even if the short event is consumed. |
|
781 if (CClick::IsHandler() && output.iResult != EConsumed) |
|
782 { |
|
783 output.iKeyEvent.iRepeats = aRepeats; |
|
784 CClick::KeyEvent(EEventKey, output.iKeyEvent); |
|
785 } |
|
786 |
|
787 if (output.iResult == ECaptured) |
|
788 { |
|
789 if (output.iWindowGroup == NULL) // Captured by Wserv itself |
|
790 { |
690 { |
791 _LIT(KWSERVDebugLogCapturedKey,"WSERV Captured Key"); |
691 _LIT(KWSERVDebugLogCapturedKey,"WSERV Captured Key"); |
792 CScreen* focusScreen=CWsTop::CurrentFocusScreen(); |
692 CScreen* focusScreen=CWsTop::CurrentFocusScreen(); |
793 TInt screenNo=focusScreen->ScreenNumber(); |
693 TInt screenNo=focusScreen->ScreenNumber(); |
794 |
694 |
795 if (wsDebugLog) |
695 if (wsDebugLog) |
796 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogCapturedKey); |
696 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogCapturedKey); |
797 CWsHotKey *hotKey=iHotKeys; |
697 CWsHotKey *hotKey=iHotKeys; |
798 while(hotKey) |
698 while(hotKey) |
799 { |
699 { |
800 if (hotKey->KeyHandle() == reinterpret_cast<TInt>(output.iCaptureHandle)) |
700 if (hotKey->KeyHandle()==aKey.iHandle) |
801 { |
701 { |
802 switch(hotKey->HotKeyType()) |
702 switch(hotKey->HotKeyType()) |
803 { |
703 { |
804 case EHotKeyEnableLogging: |
704 case EHotKeyEnableLogging: |
805 CWsTop::EnableLogging(); |
705 CWsTop::EnableLogging(); |
880 hotKey=hotKey->iNext; |
780 hotKey=hotKey->iNext; |
881 } |
781 } |
882 WS_PANIC_ALWAYS(EWsPanicUnknownCaptureKey); |
782 WS_PANIC_ALWAYS(EWsPanicUnknownCaptureKey); |
883 return; |
783 return; |
884 } |
784 } |
885 |
785 focusWin=((CWsWindowGroup *)aKey.iApp); |
886 _LIT(KWSERVDebugLogKeyCapturedByApp,"Key captured by app %d"); |
786 _LIT(KWSERVDebugLogKeyCapturedByApp,"Key captured by app %d"); |
887 if (wsDebugLog) |
787 if (wsDebugLog) |
888 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyCapturedByApp,focusWin->Identifier()); |
788 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyCapturedByApp,focusWin->Identifier()); |
889 if (CWsPassword::PasswordModeActive() && focusWin!=CWsPassword::PasswordWindow()->WinGroup()) |
789 if (CWsPassword::PasswordModeActive() && focusWin!=CWsPassword::PasswordWindow()->WinGroup()) |
890 return; |
790 return; |
891 } |
791 } |
892 |
792 if (aRepeatFocus && aRepeatFocus!=focusWin) |
893 CWsCaptureLongKey* longCapture = NULL; |
|
894 TKeyEventRouterOutput longOutput; |
|
895 if (aCheckRepeat) |
|
896 { |
|
897 // Check for long key capture. |
|
898 // Note that a long key event can only result from capture, there is |
|
899 // no default detection or routing of long events. |
|
900 input.iType = ECaptureTypeLongKey; |
|
901 #ifdef _DEBUG |
|
902 TRAPD(err, iKeyEventRouter->RouteKey(input, longOutput)); |
|
903 WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave); |
|
904 #else |
|
905 iKeyEventRouter->RouteKey(input, longOutput); |
|
906 #endif |
|
907 |
|
908 if (longOutput.iResult == ECaptured) |
|
909 { |
|
910 longCapture = static_cast<CWsCaptureLongKey*>(longOutput.iCaptureHandle); |
|
911 |
|
912 // Mark long key events with EModifierLongKey so that applications |
|
913 // can easily distinguish short and long events. |
|
914 longOutput.iKeyEvent.iModifiers |= EModifierLongKey; |
|
915 |
|
916 // Start timer to detect long key press |
|
917 CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, &longOutput); |
|
918 } |
|
919 else if (output.iResult != EConsumed && output.iKeyEvent.iModifiers & EModifierAutorepeatable) |
|
920 { |
|
921 // Start timer for key repeat |
|
922 CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, NULL); |
|
923 } |
|
924 } |
|
925 |
|
926 // Queue the short event |
|
927 if (!longCapture || longCapture->iFlags & ELongCaptureShortEventImmediately) |
|
928 { |
|
929 QueueKeyPress(output, EFalse, aRepeats); |
|
930 } |
|
931 } |
|
932 |
|
933 /** |
|
934 Queue a key press event. |
|
935 |
|
936 This function is called for each key event produced by ProcessKeyPress(), |
|
937 for every key repeat and long key event generated by the timer and also for |
|
938 delayed short key events from KeyUp(). |
|
939 |
|
940 @param aOutput Output key event from routing plug-in |
|
941 @param aIsRepeat Event is due to key repeat |
|
942 @param aRepeats Repeat count |
|
943 */ |
|
944 void TWindowServerEvent::QueueKeyPress(const TKeyEventRouterOutput& aOutput, TBool aIsRepeat, TInt aRepeats) |
|
945 { |
|
946 if (aOutput.iResult == EConsumed) |
|
947 { |
|
948 // Don't deliver this key |
|
949 return; |
|
950 } |
|
951 |
|
952 TWsEvent event; |
|
953 TKeyEvent& keyEvent = *event.Key(); |
|
954 keyEvent = aOutput.iKeyEvent; |
|
955 keyEvent.iRepeats = aRepeats; |
|
956 |
|
957 CWsWindowGroup* focusWin = static_cast<CWsWindowGroup*>(aOutput.iWindowGroup); |
|
958 WS_ASSERT_DEBUG(focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW, EWsPanicKeyEventRouterBadWindowGroup); |
|
959 |
|
960 if (aIsRepeat && aOutput.iResult != ECaptured && focusWin != CWsTop::FocusWindowGroup()) |
|
961 CKeyboardRepeat::CancelRepeat(NULL); // Repeat is going to different window so cancel it and don't deliver this key |
793 CKeyboardRepeat::CancelRepeat(NULL); // Repeat is going to different window so cancel it and don't deliver this key |
962 else if (focusWin != NULL && focusWin->CheckForPriorityKey(keyEvent) == EFalse) |
794 else if (focusWin!=NULL && focusWin->CheckForPriorityKey(aKey,aScanCode)==EFalse) |
963 { |
795 { |
|
796 if (longCapture || (aCheckRepeat && !aRepeatFocus && aKey.iModifiers&EModifierAutorepeatable)) |
|
797 { |
|
798 if (CKeyboardRepeat::StartRepeat(aKey,aScanCode,focusWin,longCapture)) |
|
799 return; |
|
800 } |
964 event.SetType(EEventKey); |
801 event.SetType(EEventKey); |
965 event.SetHandle(focusWin->ClientHandle()); |
802 event.SetHandle(focusWin->ClientHandle()); |
966 if (aRepeats!=0) |
803 if (aRepeats!=0) |
967 { |
804 { |
968 CEventQueue* queue=focusWin->EventQueue(); |
805 CEventQueue* queue=focusWin->EventQueue(); |
969 queue->Wait(); |
806 queue->Wait(); |
970 const TWsEvent* prev=queue->PeekLastEvent(); |
807 const TWsEvent* prev=queue->PeekLastEvent(); |
971 if (prev != NULL && prev->Type() == EEventKey && prev->Key()->iRepeats > 0 && prev->Key()->iCode == keyEvent.iCode) |
808 if (prev!=NULL && prev->Type()==EEventKey && prev->Key()->iRepeats>0) |
972 { |
809 { |
973 prev->Key()->iRepeats += aRepeats; |
810 event= *prev; |
|
811 event.Key()->iRepeats+=aRepeats; |
|
812 queue->UpdateLastEvent(event); |
974 queue->Signal(); |
813 queue->Signal(); |
975 if (CClick::IsHandler()) |
814 if (CClick::IsHandler()) |
976 CClick::KeyEvent(EEventKeyRepeat, *prev->Key()); |
815 CClick::KeyEvent(EEventKeyRepeat,*event.Key()); |
977 return; |
816 return; |
978 } |
817 } |
979 queue->Signal(); |
818 queue->Signal(); |
|
819 event.Key()->iRepeats=aRepeats; |
980 if (CClick::IsHandler()) |
820 if (CClick::IsHandler()) |
981 CClick::KeyEvent(EEventKeyRepeat,keyEvent); |
821 CClick::KeyEvent(EEventKeyRepeat,keyEvent); |
982 } |
822 } |
983 QueueKeyEvent(focusWin, event, EEventPriorityLow); |
823 QueueKeyEvent(focusWin, event, EEventPriorityLow); |
984 } |
824 } |
985 } |
825 } |
986 |
826 |
987 /** |
|
988 Queue a key up/down event. |
|
989 |
|
990 @param aRawEvent Raw event |
|
991 */ |
|
992 void TWindowServerEvent::QueueKeyUpDown(const TRawEvent &aRawEvent) |
827 void TWindowServerEvent::QueueKeyUpDown(const TRawEvent &aRawEvent) |
993 { |
828 { |
994 #ifdef LOG_WSERV_EVENTS |
829 CWsWindowGroup *focusWin=CWsCaptureKeyUpsAndDowns::CheckForCapture(aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE, iModifierState); |
995 RDebug::Print(_L("_WSEVENT_KEY: TWindowServerEvent::QueueKeyUpDown, Event Name: %S, Scan code: %d"), &RawEventName(aRawEvent), aRawEvent.ScanCode()); |
830 if (!focusWin) // If not captured |
996 #endif |
831 focusWin=CWsTop::FocusWindowGroup(); |
997 TEventCode type = aRawEvent.Type() == TRawEvent::EKeyUp ? EEventKeyUp : EEventKeyDown; |
832 TWsEvent event; |
998 |
833 TEventCode type=aRawEvent.Type()==TRawEvent::EKeyUp ? EEventKeyUp : EEventKeyDown; |
999 // Check for key up/down capture |
834 event.Key()->iCode=0; |
1000 TKeyEvent keyEvent; |
|
1001 keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; |
|
1002 #if defined(__WINS__) |
|
1003 keyEvent.iCode = __WINS_CHARCODE(aRawEvent.ScanCode()); |
|
1004 #else |
|
1005 keyEvent.iCode = 0; |
|
1006 #endif |
|
1007 keyEvent.iModifiers = iModifierState; |
|
1008 keyEvent.iRepeats = 0; |
|
1009 |
|
1010 CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup(); |
|
1011 TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid; |
|
1012 |
|
1013 TKeyEventRouterInput input(ECaptureTypeKeyUpDown, keyEvent, focusWin, focusAppUid); |
|
1014 TKeyEventRouterOutput output; |
|
1015 #ifdef _DEBUG |
|
1016 TRAPD(err, iKeyEventRouter->RouteKey(input, output)); |
|
1017 WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave); |
|
1018 #else |
|
1019 iKeyEventRouter->RouteKey(input, output); |
|
1020 #endif |
|
1021 |
|
1022 if (output.iResult == EConsumed) |
|
1023 { |
|
1024 // Don't deliver this key. A key click is still generated for the |
|
1025 // input event. |
|
1026 if (CClick::IsHandler()) |
|
1027 { |
|
1028 CClick::KeyEvent(type, keyEvent); |
|
1029 } |
|
1030 return; |
|
1031 } |
|
1032 WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured, EWsPanicKeyEventRouterBadResult); |
|
1033 |
|
1034 focusWin = static_cast<CWsWindowGroup*>(output.iWindowGroup); |
|
1035 WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup); |
|
1036 #if defined(__WINS__) |
835 #if defined(__WINS__) |
1037 if (focusWin && !focusWin->WsOwner()->RemoveKeyCode()) |
836 if (focusWin && !focusWin->WsOwner()->RemoveKeyCode()) |
1038 { |
837 event.Key()->iScanCode=aRawEvent.ScanCode(); |
1039 // Restore WINS character code |
838 else |
1040 output.iKeyEvent.iScanCode |= output.iKeyEvent.iCode; |
|
1041 } |
|
1042 output.iKeyEvent.iCode = 0; |
|
1043 #endif |
839 #endif |
1044 |
840 event.Key()->iScanCode=aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; |
1045 output.iKeyEvent.iRepeats = 0; |
841 event.Key()->iModifiers=iModifierState; |
|
842 event.Key()->iRepeats=0; |
1046 if (CClick::IsHandler()) |
843 if (CClick::IsHandler()) |
1047 { |
844 CClick::KeyEvent(type,*event.Key()); |
1048 CClick::KeyEvent(type, output.iKeyEvent); |
|
1049 } |
|
1050 |
|
1051 TWsEvent event; |
|
1052 *event.Key() = output.iKeyEvent; |
|
1053 if (focusWin!=NULL) |
845 if (focusWin!=NULL) |
1054 { |
846 { |
1055 event.SetType(type); |
847 event.SetType(type); |
1056 event.SetHandle(focusWin->ClientHandle()); |
848 event.SetHandle(focusWin->ClientHandle()); |
1057 QueueKeyEvent(focusWin, event, EEventPriorityHigh); |
849 QueueKeyEvent(focusWin, event, EEventPriorityHigh); |
1157 break; |
949 break; |
1158 } |
950 } |
1159 } |
951 } |
1160 |
952 |
1161 /* |
953 /* |
1162 Process a raw event |
954 Pause in processing all raw pointer and key events (except processing by anim's dll plug-ins). |
1163 |
955 All events will be ignored except for anim's dll plug-ins. |
1164 @param aRawEvent Raw event |
956 Pause prevents pointer events to come to wrong windows due to screen width and size changes. |
|
957 @param aPauseInterval - the pause interval in microseconds. |
1165 */ |
958 */ |
|
959 void TWindowServerEvent::PauseProcessRawEvents(TInt aPauseInterval) |
|
960 { |
|
961 iPauseInterval = TTimeIntervalMicroSeconds(aPauseInterval); |
|
962 iPauseStartTime.UniversalTime(); |
|
963 #ifdef LOG_WSERV_EVENTS |
|
964 RDebug::Printf("{EVNT}TWindowServerEvent::PauseProcessRawEvents aPauseInterval = %d",aPauseInterval); |
|
965 #endif |
|
966 } |
|
967 |
1166 void TWindowServerEvent::ProcessRawEvent(const TRawEvent& aRawEvent) |
968 void TWindowServerEvent::ProcessRawEvent(const TRawEvent& aRawEvent) |
1167 // |
969 // |
1168 // Event has completed. |
970 // Event has completed. |
1169 // |
971 // |
1170 { |
972 { |
|
973 TBool pauseProcessEvents = EFalse; |
|
974 //Check if the pause in processing all raw pointer and key events was set. |
|
975 if(iPauseInterval.Int64() > 0) |
|
976 { |
|
977 TTime current; |
|
978 current.UniversalTime(); |
|
979 TTimeIntervalMicroSeconds interval = current.MicroSecondsFrom( |
|
980 iPauseStartTime); |
|
981 if ((interval.Int64() > iPauseInterval.Int64()) || (interval.Int64() < 0)) |
|
982 { |
|
983 iPauseInterval = TTimeIntervalMicroSeconds(0); |
|
984 } |
|
985 else |
|
986 { |
|
987 // Set flag ignore of processing all raw events (except processing by anim's dll plug-ins) |
|
988 // All events will be ignored except for anim's dll plug-ins. |
|
989 pauseProcessEvents = ETrue; |
|
990 } |
|
991 } |
|
992 |
|
993 #ifdef LOG_WSERV_EVENTS |
|
994 if(pauseProcessEvents) |
|
995 RDebug::Printf("{EVNT}TWindowServerEvent::ProcessRawEvent Processing of Raw Event - DISABLED"); |
|
996 else |
|
997 RDebug::Printf("{EVNT}TWindowServerEvent::ProcessRawEvent Processing of Raw Event - ENABLED"); |
|
998 #endif |
|
999 |
1171 TRawEvent::TType eventType = aRawEvent.Type(); |
1000 TRawEvent::TType eventType = aRawEvent.Type(); |
1172 TBool isPointerEvent = TWsPointer::IsPointerEventType(eventType); |
1001 TBool isPointerEvent = TWsPointer::IsPointerEventType(eventType); |
1173 if (isPointerEvent) |
1002 if (isPointerEvent) |
1174 { |
1003 { |
1175 #ifdef LOG_WSERV_EVENTS |
1004 #ifdef LOG_WSERV_EVENTS |
1176 RDebug::Print(_L("_WSEVENT_POINTER: TWindowServerEvent::ProcessRawEvent EventName = %S PointerNumber = %d PrimaryPointerNumber = %d Coordinates = ( %d, %d )"), |
1005 RDebug::Printf("{EVNT}TWindowServerEvent::ProcessRawEvent EventType = 0x0%X PointerNumber = %d PrimaryPointerNumber = %d XY(%d,%d)", |
1177 &RawEventName(aRawEvent),aRawEvent.PointerNumber(),TWsPointer::PrimaryPointer(),aRawEvent.Pos().iX,aRawEvent.Pos().iY); |
1006 aRawEvent.Type(),aRawEvent.PointerNumber(),TWsPointer::PrimaryPointer(),aRawEvent.Pos().iX,aRawEvent.Pos().iY); |
1178 #endif |
1007 #endif |
1179 TWsPointer::UpdatePrimaryPointer(aRawEvent); |
1008 TWsPointer::UpdatePrimaryPointer(aRawEvent); |
1180 } |
1009 } |
1181 TInt count=iEventHandlers.Count(); |
1010 TInt count=iEventHandlers.Count(); |
1182 TInt ii; |
1011 TInt ii; |
1302 CWsTop::WindowServer()->AnimationScheduler()->OnActive(); |
1125 CWsTop::WindowServer()->AnimationScheduler()->OnActive(); |
1303 #endif |
1126 #endif |
1304 break; |
1127 break; |
1305 case TRawEvent::EKeyDown: |
1128 case TRawEvent::EKeyDown: |
1306 { |
1129 { |
1307 #ifdef LOG_WSERV_EVENTS |
|
1308 RDebug::Printf("_WSEVENT_KEY: TRawEvent::EKeyDown"); |
|
1309 #endif |
|
1310 _LIT(KWSERVDebugLogKeyDownArrival,"Key down arrives %d"); |
1130 _LIT(KWSERVDebugLogKeyDownArrival,"Key down arrives %d"); |
1311 CScreen* screen = CWsTop::Screen(); |
1131 CScreen* screen = CWsTop::Screen(); |
1312 WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen); |
1132 WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen); |
1313 if(CDebugBar* dbg = screen->DebugBar()) |
1133 if(CDebugBar* dbg = screen->DebugBar()) |
1314 dbg->OnKeyEvent(); |
1134 dbg->OnKeyEvent(); |
1315 if (wsDebugLog) |
1135 if (wsDebugLog) |
1316 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyDownArrival,aRawEvent.ScanCode()); |
1136 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyDownArrival,aRawEvent.ScanCode()); |
1317 CKeyboardRepeat::KeyDown(); |
1137 CKeyboardRepeat::KeyDown(); |
1318 TKeyData keyData; |
1138 TKeyData keyData; |
1319 // Note iCaptureKeys is needed as dummy arg only. Key capture is |
|
1320 // now handled in ProcessKeyPress(). |
|
1321 TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), EFalse,*iCaptureKeys,keyData); |
1139 TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), EFalse,*iCaptureKeys,keyData); |
1322 ProcessModifierChanges(); |
1140 ProcessModifierChanges(); |
1323 QueueKeyUpDown(aRawEvent); |
1141 QueueKeyUpDown(aRawEvent); |
1324 if (translated) |
1142 if (translated) |
1325 { |
1143 QueueKeyPress(keyData,aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,ETrue,0); |
1326 TKeyEvent keyEvent; |
|
1327 keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; |
|
1328 keyEvent.iCode = keyData.iKeyCode; |
|
1329 keyEvent.iModifiers = keyData.iModifiers; |
|
1330 ProcessKeyPress(keyEvent, ETrue, 0); |
|
1331 } |
|
1332 } |
1144 } |
1333 break; |
1145 break; |
1334 case TRawEvent::EKeyUp: |
1146 case TRawEvent::EKeyUp: |
1335 { |
1147 { |
1336 #ifdef LOG_WSERV_EVENTS |
|
1337 RDebug::Printf("_WSEVENT_KEY: TRawEvent::EKeyUp"); |
|
1338 #endif |
|
1339 _LIT(KWSERVDebugLogKeyUpArrival,"Key up arrives %d"); |
1148 _LIT(KWSERVDebugLogKeyUpArrival,"Key up arrives %d"); |
1340 CScreen* screen = CWsTop::Screen(); |
1149 CScreen* screen = CWsTop::Screen(); |
1341 WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen); |
1150 WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen); |
1342 if(CDebugBar* dbg = screen->DebugBar()) |
1151 if(CDebugBar* dbg = screen->DebugBar()) |
1343 dbg->OnKeyEvent(); |
1152 dbg->OnKeyEvent(); |
1384 case TRawEvent::EKeyRepeat: |
1189 case TRawEvent::EKeyRepeat: |
1385 { |
1190 { |
1386 _LIT(KWSERVDebugLogRepeatingKeyArrival,"Repeating key arrives %d"); |
1191 _LIT(KWSERVDebugLogRepeatingKeyArrival,"Repeating key arrives %d"); |
1387 if (wsDebugLog) |
1192 if (wsDebugLog) |
1388 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogRepeatingKeyArrival,aRawEvent.ScanCode()); |
1193 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogRepeatingKeyArrival,aRawEvent.ScanCode()); |
1389 TKeyEvent keyEvent; |
1194 TKeyData keyData; |
1390 keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; |
1195 keyData.iModifiers=iKeyTranslator->GetModifierState(); |
1391 keyEvent.iCode = aRawEvent.ScanCode(); |
1196 keyData.iApp=0; |
1392 keyEvent.iModifiers = iKeyTranslator->GetModifierState(); |
1197 keyData.iHandle=0; |
1393 ProcessKeyPress(keyEvent, EFalse, aRawEvent.Repeats()); |
1198 keyData.iIsCaptureKey=EFalse; |
|
1199 keyData.iKeyCode=aRawEvent.ScanCode(); |
|
1200 iCaptureKeys->ProcessCaptureKeys(keyData); |
|
1201 QueueKeyPress(keyData, aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,EFalse,aRawEvent.Repeats()); |
1394 } |
1202 } |
1395 break; |
1203 break; |
1396 default: |
1204 default: |
1397 break; |
1205 break; |
1398 } |
1206 } |
1399 #ifdef LOG_WSERV_EVENTS |
1207 #ifdef LOG_WSERV_EVENTS |
1400 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); |
1208 RDebug::Printf("{EVNT}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); |
1401 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); |
1209 RDebug::Printf("{EVNT}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); |
1402 #endif |
1210 #endif |
1403 } |
1211 } |
1404 |
1212 |
1405 void TWindowServerEvent::ProcessKeyEvent(const TKeyEvent &aKeyEvent,TInt aRepeats) |
1213 void TWindowServerEvent::ProcessKeyEvent(const TKeyEvent &aKeyEvent,TInt aRepeats) |
1406 { |
1214 { |
1407 #ifdef LOG_WSERV_EVENTS |
|
1408 RDebug::Printf("_WSEVENT_KEY: TWindowServerEvent::ProcessKeyEvent, key code: %d, repeat: %d", aKeyEvent.iCode, aRepeats); |
|
1409 #endif |
|
1410 TKeyData keyData; |
1215 TKeyData keyData; |
1411 keyData.iModifiers=aKeyEvent.iModifiers; |
1216 keyData.iModifiers=aKeyEvent.iModifiers; |
1412 keyData.iApp=0; |
1217 keyData.iApp=0; |
1413 keyData.iHandle=0; |
1218 keyData.iHandle=0; |
1414 keyData.iIsCaptureKey=EFalse; |
1219 keyData.iIsCaptureKey=EFalse; |
1415 keyData.iKeyCode=aKeyEvent.iCode; |
1220 keyData.iKeyCode=aKeyEvent.iCode; |
1416 if (CKeyboardRepeat::IsAreadyActive()) |
1221 if (CKeyboardRepeat::IsAreadyActive()) |
1417 { |
1222 { |
1418 CKeyboardRepeat::CancelRepeat(NULL); |
1223 CKeyboardRepeat::CancelRepeat(NULL); |
1419 } |
1224 } |
1420 ProcessKeyPress(aKeyEvent, aRepeats == 0, aRepeats); |
1225 iCaptureKeys->ProcessCaptureKeys(keyData); |
1421 } |
1226 QueueKeyPress(keyData,aKeyEvent.iScanCode,NULL,aRepeats==0,aRepeats); |
1422 |
1227 } |
1423 void TWindowServerEvent::AddCaptureKeyL(const TKeyCaptureRequest& aRequest) |
1228 |
1424 { |
1229 void TWindowServerEvent::AddCaptureKeyL(const TCaptureKey &aCaptureKey) |
1425 iKeyEventRouter->AddCaptureKeyL(aRequest); |
1230 { |
1426 } |
1231 iCaptureKeys->AddCaptureKeyL(aCaptureKey,aCaptureKey.iKeyCodePattern.iFiller); |
1427 |
1232 } |
1428 void TWindowServerEvent::UpdateCaptureKeyL(const TKeyCaptureRequest& aRequest) |
1233 |
1429 { |
1234 void TWindowServerEvent::SetCaptureKey(TUint32 aHandle, const TCaptureKey &aCaptureKey) |
1430 iKeyEventRouter->UpdateCaptureKeyL(aRequest); |
1235 { |
1431 } |
1236 iCaptureKeys->SetCaptureKey(aHandle, aCaptureKey,aCaptureKey.iKeyCodePattern.iFiller); |
1432 |
1237 } |
1433 void TWindowServerEvent::CancelCaptureKey(TKeyCaptureType aType, TAny* aHandle) |
1238 |
1434 { |
1239 void TWindowServerEvent::CancelCaptureKey(TUint32 aHandle) |
1435 iKeyEventRouter->CancelCaptureKey(aType, aHandle); |
1240 { |
|
1241 iCaptureKeys->CancelCaptureKey(aHandle); |
1436 } |
1242 } |
1437 |
1243 |
1438 TInt TWindowServerEvent::GetModifierState() |
1244 TInt TWindowServerEvent::GetModifierState() |
1439 { |
1245 { |
1440 return(iKeyTranslator->GetModifierState()); |
1246 return(iKeyTranslator->GetModifierState()); |
1808 } |
1605 } |
1809 if (timer) |
1606 if (timer) |
1810 After(iTime); |
1607 After(iTime); |
1811 else |
1608 else |
1812 iRepeating=ERepeatNone; |
1609 iRepeating=ERepeatNone; |
1813 |
1610 TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iKey,iCurrentRepeat.iScanCode,iFocus,EFalse,1); |
1814 TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iOutput, ETrue, 1); |
1611 } |
1815 } |
1612 |
1816 |
1613 TBool CKeyboardRepeat::StartRepeat(const TKeyData &aKey, TInt aScanCode, CWsWindowGroup *aRepeatFocus, CWsCaptureLongKey* aLongCapture) |
1817 /** |
|
1818 Start key repeat and long key press timer |
|
1819 |
|
1820 @param aInputScanCode Original scan code (before routing) |
|
1821 @param aShortEvent Short key event (routing plug-in output) |
|
1822 @param aLongEvent Pointer to long key event (routing plug-in output) |
|
1823 or NULL if none. |
|
1824 |
|
1825 Note: When aLongEvent != NULL, iCurrentRepeat reflects the short key event |
|
1826 until the timer has expired. This is necessary to allow a delayed short key |
|
1827 event to be delivered by KeyUp(). CancelRepeat() must therefore examine |
|
1828 iCurrentRepeat or iLongRepeat according to the repeat type in iRepeat. |
|
1829 */ |
|
1830 void CKeyboardRepeat::StartRepeat(TInt aInputScanCode, const TKeyEventRouterOutput& aShortEvent, const TKeyEventRouterOutput* aLongEvent) |
|
1831 { |
1614 { |
1832 TTimeIntervalMicroSeconds32 time; |
1615 TTimeIntervalMicroSeconds32 time; |
1833 iCurrentRepeat.iInputScanCode = aInputScanCode; |
1616 TBool ret=EFalse; |
1834 iCurrentRepeat.iOutput = aShortEvent; |
1617 iCurrentRepeat.iScanCode=aScanCode; |
1835 |
1618 iCurrentRepeat.iKey=aKey; |
1836 if (aLongEvent) |
1619 |
1837 { |
1620 if (aLongCapture) |
1838 iRepeating = ERepeatLong; |
1621 { |
1839 iLongRepeat.iInputScanCode = aInputScanCode; |
1622 iLongCapture=aLongCapture; |
1840 iLongRepeat.iOutput = *aLongEvent; |
1623 iRepeating=ERepeatLong; |
1841 iLongCapture = static_cast<CWsCaptureLongKey*>(aLongEvent->iCaptureHandle); |
1624 time=aLongCapture->iData.delay; |
1842 time = iLongCapture->iDelay; |
1625 ret=!(aLongCapture->iData.flags&ELongCaptureShortEventImmediately); |
|
1626 //need window group from long capture key or even better delete it altogether. |
|
1627 iFocus=aLongCapture->WindowGroup(); |
1843 } |
1628 } |
1844 else |
1629 else |
1845 { |
1630 { |
1846 iLongCapture = NULL; |
1631 iFocus=aRepeatFocus; |
1847 iRepeating=ERepeatNormal; |
1632 iRepeating=ERepeatNormal; |
1848 time=iInitialTime; |
1633 time=iInitialTime; |
1849 } |
1634 } |
1850 iThis->After(time); |
1635 iThis->After(time); |
1851 } |
1636 return ret; |
1852 |
1637 } |
1853 /** |
1638 |
1854 Cancel key repeat processing |
|
1855 */ |
|
1856 void CKeyboardRepeat::doCancelRepeat() |
1639 void CKeyboardRepeat::doCancelRepeat() |
1857 { |
1640 { |
1858 iRepeating=ERepeatNone; |
1641 iRepeating=ERepeatNone; |
1859 iThis->Cancel(); |
1642 iThis->Cancel(); |
1860 } |
1643 } |
1861 |
1644 |
1862 /** |
|
1863 Cancel any key repeat associated with the specified window group |
|
1864 |
|
1865 @param aRepeatFocus Destination window group or NULL for all |
|
1866 */ |
|
1867 void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus) |
1645 void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus) |
1868 { |
1646 { |
1869 if (iRepeating != ERepeatNone) |
1647 if (aRepeatFocus==NULL || aRepeatFocus==iFocus) |
1870 { |
1648 { |
1871 if (aRepeatFocus == NULL || |
1649 if (iRepeating) |
1872 (iRepeating == ERepeatNormal) && (aRepeatFocus == iCurrentRepeat.iOutput.iWindowGroup) || |
1650 doCancelRepeat(); |
1873 (iRepeating >= ERepeatLong) && (aRepeatFocus == iLongRepeat.iOutput.iWindowGroup)) |
1651 iAlternateRepeatExists=EFalse; |
|
1652 } |
|
1653 else if (iRepeating >= ERepeatLong) |
|
1654 { |
|
1655 // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong |
|
1656 if (iLongCapture && iLongCapture->iWindowGroup == aRepeatFocus) |
1874 { |
1657 { |
1875 doCancelRepeat(); |
1658 doCancelRepeat(); |
1876 iAlternateRepeatExists=EFalse; |
1659 iAlternateRepeatExists=EFalse; |
1877 } |
1660 } |
1878 } |
1661 } |
1879 } |
1662 } |
1880 |
1663 |
1881 /** |
1664 void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus,TUint aScanCode,TBool aLongCaptureFlag,TUint aModifiers) |
1882 Cancel any key repeat associated with the specified capture handle |
|
1883 |
|
1884 @param aCaptureHandle Handle to capture request |
|
1885 @param aLongCaptureFlag ETrue for long key capture, EFalse for normal key |
|
1886 */ |
|
1887 void CKeyboardRepeat::CancelRepeat(const TAny* aCaptureHandle, TBool aLongCaptureFlag) |
|
1888 { |
1665 { |
1889 if (aLongCaptureFlag) |
1666 if (aLongCaptureFlag) |
1890 { |
1667 { |
1891 // Cancel repeat for long capture key |
1668 // long capture key is cancelled |
1892 if (iRepeating >= ERepeatLong && aCaptureHandle == iLongRepeat.iOutput.iCaptureHandle) |
1669 if (iRepeating >= ERepeatLong && iCurrentRepeat.iScanCode==aScanCode) |
1893 { |
1670 { |
1894 doCancelRepeat(); |
1671 // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong |
|
1672 if (iLongCapture && aRepeatFocus == iLongCapture->iWindowGroup && |
|
1673 (aModifiers & iLongCapture->iData.modifierMask) == iLongCapture->iData.modifiers) |
|
1674 { |
|
1675 doCancelRepeat(); |
|
1676 iAlternateRepeatExists=EFalse; |
|
1677 } |
|
1678 } |
|
1679 } |
|
1680 else |
|
1681 { |
|
1682 // normal capture key is cancelled |
|
1683 if (aRepeatFocus==iFocus) |
|
1684 { |
|
1685 if (iRepeating>=ERepeatNormal && iCurrentRepeat.iScanCode==aScanCode) |
|
1686 { |
|
1687 doCancelRepeat(); |
|
1688 } |
1895 iAlternateRepeatExists=EFalse; |
1689 iAlternateRepeatExists=EFalse; |
1896 } |
1690 } |
1897 } |
1691 } |
1898 else |
|
1899 { |
|
1900 // Cancel repeat for normal capture key |
|
1901 if (iRepeating == ERepeatNormal && aCaptureHandle == iCurrentRepeat.iOutput.iCaptureHandle) |
|
1902 { |
|
1903 doCancelRepeat(); |
|
1904 iAlternateRepeatExists=EFalse; |
|
1905 } |
|
1906 } |
|
1907 } |
1692 } |
1908 |
1693 |
1909 /** |
|
1910 Process a key down event during key repeat. |
|
1911 The current repeat data is saved for possible restoration after rollover. |
|
1912 */ |
|
1913 void CKeyboardRepeat::KeyDown() |
1694 void CKeyboardRepeat::KeyDown() |
1914 { |
1695 { |
1915 if (iRepeating!=ERepeatNone) |
1696 if (iRepeating!=ERepeatNone) |
1916 { |
1697 { |
1917 if (iRepeating==ERepeatNormal && iRepeatRollover>0) // 1 Allow key repeat rollover |
1698 if (iRepeating==ERepeatNormal && iRepeatRollover>0) // 1 Allow key repeat rollover |