229 TBuf<16> keyDataDllName; |
238 TBuf<16> keyDataDllName; |
230 keyDataDllName.Format(KLitKeyDataDllName,keyboardIndex); |
239 keyDataDllName.Format(KLitKeyDataDllName,keyboardIndex); |
231 iKeyTranslator->ChangeKeyData(keyDataDllName); |
240 iKeyTranslator->ChangeKeyData(keyDataDllName); |
232 } |
241 } |
233 |
242 |
|
243 // CCaptureKeys is no longer used but a dummy object is required for |
|
244 // calls to CKeyTranslator::TranslateKey() until capture functionality |
|
245 // has been removed from ektran.dll. |
234 iCaptureKeys=new(ELeave) CCaptureKeys; |
246 iCaptureKeys=new(ELeave) CCaptureKeys; |
235 iCaptureKeys->Construct(); |
247 iCaptureKeys->Construct(); |
|
248 |
|
249 // Load the key event routing plug-in. The DLL name may be overridden |
|
250 // by setting the keyword KEYROUTERPLUGIN in wsini.ini. |
|
251 TPtrC pluginName(KDefaultKeyRouterPluginName); |
|
252 WsIniFile->FindVar(KWSERVIniFileVarKeyRouterPlugin, pluginName); |
|
253 const TUidType uidType(KDynamicLibraryUid, KKeyRouterPluginUid); |
|
254 TInt err = iKeyEventRouterLibrary.Load(pluginName, uidType); |
|
255 |
|
256 if (wsDebugLog) |
|
257 { |
|
258 TLogMessageText buf; |
|
259 |
|
260 if (err == KErrNone) |
|
261 { |
|
262 _LIT(KLogLoadOk, "Loaded plugin '%S' UID3 0x%x"); |
|
263 const TFileName& pluginPathname = iKeyEventRouterLibrary.FileName(); |
|
264 const TUid uid3 = iKeyEventRouterLibrary.Type()[2]; |
|
265 buf.Format(KLogLoadOk, &pluginPathname, uid3.iUid); |
|
266 } |
|
267 else |
|
268 { |
|
269 _LIT(KLogLoadError, "Failed to load plugin '%S' (error %d)"); |
|
270 buf.Format(KLogLoadError, &pluginName, err); |
|
271 } |
|
272 |
|
273 wsDebugLog->MiscMessage(CDebugLogBase::ELogImportant, buf); |
|
274 } |
|
275 |
|
276 if (err != KErrNone) |
|
277 { |
|
278 #ifdef _DEBUG |
|
279 _LIT(KLoadError, "WServ: failed to load plugin '%S' (error %d)"); |
|
280 RDebug::Print(KLoadError, &pluginName, err); |
|
281 #endif |
|
282 User::Leave(err); |
|
283 } |
|
284 |
|
285 // Create the key event router |
|
286 typedef CKeyEventRouter* (*TCreateFunc)(); |
|
287 TCreateFunc newL = reinterpret_cast<TCreateFunc>(iKeyEventRouterLibrary.Lookup(1)); |
|
288 if (newL == NULL) |
|
289 { |
|
290 User::Leave(KErrNotFound); |
|
291 } |
|
292 iKeyEventRouter = (*newL)(); |
|
293 |
236 for (TInt index=0;index<TWindowServerEvent::ENumHotKeys;index++) |
294 for (TInt index=0;index<TWindowServerEvent::ENumHotKeys;index++) |
237 ConstructDefaultHotKeyL(index,DefaultHotKeys[index]); |
295 ConstructDefaultHotKeyL(index,DefaultHotKeys[index]); |
238 CKeyboardRepeat::NewL(); |
296 CKeyboardRepeat::NewL(); |
239 CKeyboardRepeat::SetRepeatTime(EDefaultInitialRepeatTime, EDefaultRepeatTime); |
297 CKeyboardRepeat::SetRepeatTime(EDefaultInitialRepeatTime, EDefaultRepeatTime); |
240 iEventHandlers=RArray<TRawEventHandler>(2); |
298 iEventHandlers=RArray<TRawEventHandler>(2); |
639 { |
713 { |
640 aEvent.SetTimeNow(); |
714 aEvent.SetTimeNow(); |
641 aWin->EventQueue()->QueueEvent(aEvent, aPriority); |
715 aWin->EventQueue()->QueueEvent(aEvent, aPriority); |
642 } |
716 } |
643 |
717 |
644 void TWindowServerEvent::QueueKeyPress(const TKeyData& aKey, TInt aScanCode, CWsWindowGroup* aRepeatFocus, TBool aCheckRepeat,TInt aRepeats) |
718 /** |
|
719 Process a key press event. |
|
720 |
|
721 This function is called for every input key event and uses the Key Event |
|
722 Routing plug-in to check for short and long key capture and determine the |
|
723 destination window group for the queued event(s). |
|
724 Window server hotkeys are also processed. |
|
725 Note that the key repeat timer is started here but the key repeat events |
|
726 generated by the timer go directly to QueueKeyPress(). |
|
727 |
|
728 @param aKeyEvent Input key event |
|
729 @param aCheckRepeat Check for key repeat and long key capture |
|
730 @param aRepeats Repeat count |
|
731 */ |
|
732 void TWindowServerEvent::ProcessKeyPress(const TKeyEvent& aKeyEvent, TBool aCheckRepeat, TInt aRepeats) |
645 { |
733 { |
646 CWsWindowGroup* focusWin=CWsTop::FocusWindowGroup(); |
734 CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup(); |
647 TWsEvent event; |
735 TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid; |
648 TKeyEvent& keyEvent=*event.Key(); |
736 |
649 keyEvent.iCode=aKey.iKeyCode; |
737 // Route the key event and check for short key capture. |
650 keyEvent.iScanCode=aScanCode; |
738 // Note that the Key Routing plugin may translate or block key events. |
651 keyEvent.iModifiers=aKey.iModifiers; |
739 TKeyEventRouterInput input(ECaptureTypeKey, aKeyEvent, focusWin, focusAppUid); |
652 keyEvent.iRepeats=aRepeats; |
740 TKeyEventRouterOutput output; |
653 if (!aRepeatFocus && CClick::IsHandler()) |
741 |
654 CClick::KeyEvent(EEventKey,keyEvent); |
742 #ifdef _DEBUG |
655 CWsCaptureLongKey* longCapture=NULL; |
743 // RouteKey() must not fail. Check for leaves in case the plug-in |
656 if (aCheckRepeat) |
744 // is badly behaved. |
657 longCapture=CWsCaptureLongKey::CheckForCapture(aKey.iKeyCode, aKey.iModifiers); |
745 TRAPD(err, iKeyEventRouter->RouteKey(input, output)); |
658 if (aKey.iIsCaptureKey) |
746 WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave); |
659 { |
747 #else |
660 if (aKey.iApp==NULL) // Captured by Wserv itself |
748 iKeyEventRouter->RouteKey(input, output); |
|
749 #endif |
|
750 |
|
751 WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured || output.iResult == EConsumed, EWsPanicKeyEventRouterBadResult); |
|
752 |
|
753 if (output.iResult == EConsumed) |
|
754 { |
|
755 focusWin = NULL; |
|
756 } |
|
757 else |
|
758 { |
|
759 focusWin = static_cast<CWsWindowGroup*>(output.iWindowGroup); |
|
760 } |
|
761 WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup); |
|
762 |
|
763 // Ensure that short event is not marked with EModifierLongKey |
|
764 output.iKeyEvent.iModifiers &= ~EModifierLongKey; |
|
765 |
|
766 // Generate key click unless the event is consumed. This is consistent |
|
767 // with the behaviour when CKeyTranslator::TranslateKey() yields no |
|
768 // translation for a particular scan code. (Click events for key up/down |
|
769 // will still be generated by QueueKeyUpDown()). Note however that a long |
|
770 // key press may still be captured even if the short event is consumed. |
|
771 if (CClick::IsHandler() && output.iResult != EConsumed) |
|
772 { |
|
773 output.iKeyEvent.iRepeats = aRepeats; |
|
774 CClick::KeyEvent(EEventKey, output.iKeyEvent); |
|
775 } |
|
776 |
|
777 if (output.iResult == ECaptured) |
|
778 { |
|
779 if (output.iWindowGroup == NULL) // Captured by Wserv itself |
661 { |
780 { |
662 _LIT(KWSERVDebugLogCapturedKey,"WSERV Captured Key"); |
781 _LIT(KWSERVDebugLogCapturedKey,"WSERV Captured Key"); |
663 CScreen* focusScreen=CWsTop::CurrentFocusScreen(); |
782 CScreen* focusScreen=CWsTop::CurrentFocusScreen(); |
664 TInt screenNo=focusScreen->ScreenNumber(); |
783 TInt screenNo=focusScreen->ScreenNumber(); |
665 |
784 |
666 if (wsDebugLog) |
785 if (wsDebugLog) |
667 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogCapturedKey); |
786 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogCapturedKey); |
668 CWsHotKey *hotKey=iHotKeys; |
787 CWsHotKey *hotKey=iHotKeys; |
669 while(hotKey) |
788 while(hotKey) |
670 { |
789 { |
671 if (hotKey->KeyHandle()==aKey.iHandle) |
790 if (hotKey->KeyHandle() == reinterpret_cast<TInt>(output.iCaptureHandle)) |
672 { |
791 { |
673 switch(hotKey->HotKeyType()) |
792 switch(hotKey->HotKeyType()) |
674 { |
793 { |
675 case EHotKeyEnableLogging: |
794 case EHotKeyEnableLogging: |
676 CWsTop::EnableLogging(); |
795 CWsTop::EnableLogging(); |
751 hotKey=hotKey->iNext; |
870 hotKey=hotKey->iNext; |
752 } |
871 } |
753 WS_PANIC_ALWAYS(EWsPanicUnknownCaptureKey); |
872 WS_PANIC_ALWAYS(EWsPanicUnknownCaptureKey); |
754 return; |
873 return; |
755 } |
874 } |
756 focusWin=((CWsWindowGroup *)aKey.iApp); |
875 |
757 _LIT(KWSERVDebugLogKeyCapturedByApp,"Key captured by app %d"); |
876 _LIT(KWSERVDebugLogKeyCapturedByApp,"Key captured by app %d"); |
758 if (wsDebugLog) |
877 if (wsDebugLog) |
759 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyCapturedByApp,focusWin->Identifier()); |
878 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyCapturedByApp,focusWin->Identifier()); |
760 if (CWsPassword::PasswordModeActive() && focusWin!=CWsPassword::PasswordWindow()->WinGroup()) |
879 if (CWsPassword::PasswordModeActive() && focusWin!=CWsPassword::PasswordWindow()->WinGroup()) |
761 return; |
880 return; |
762 } |
881 } |
763 if (aRepeatFocus && aRepeatFocus!=focusWin) |
882 |
|
883 CWsCaptureLongKey* longCapture = NULL; |
|
884 TKeyEventRouterOutput longOutput; |
|
885 if (aCheckRepeat) |
|
886 { |
|
887 // Check for long key capture. |
|
888 // Note that a long key event can only result from capture, there is |
|
889 // no default detection or routing of long events. |
|
890 input.iType = ECaptureTypeLongKey; |
|
891 #ifdef _DEBUG |
|
892 TRAPD(err, iKeyEventRouter->RouteKey(input, longOutput)); |
|
893 WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave); |
|
894 #else |
|
895 iKeyEventRouter->RouteKey(input, longOutput); |
|
896 #endif |
|
897 |
|
898 if (longOutput.iResult == ECaptured) |
|
899 { |
|
900 longCapture = static_cast<CWsCaptureLongKey*>(longOutput.iCaptureHandle); |
|
901 |
|
902 // Mark long key events with EModifierLongKey so that applications |
|
903 // can easily distinguish short and long events. |
|
904 longOutput.iKeyEvent.iModifiers |= EModifierLongKey; |
|
905 |
|
906 // Start timer to detect long key press |
|
907 CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, &longOutput); |
|
908 } |
|
909 else if (output.iResult != EConsumed && output.iKeyEvent.iModifiers & EModifierAutorepeatable) |
|
910 { |
|
911 // Start timer for key repeat |
|
912 CKeyboardRepeat::StartRepeat(aKeyEvent.iScanCode, output, NULL); |
|
913 } |
|
914 } |
|
915 |
|
916 // Queue the short event |
|
917 if (!longCapture || longCapture->iFlags & ELongCaptureShortEventImmediately) |
|
918 { |
|
919 QueueKeyPress(output, EFalse, aRepeats); |
|
920 } |
|
921 } |
|
922 |
|
923 /** |
|
924 Queue a key press event. |
|
925 |
|
926 This function is called for each key event produced by ProcessKeyPress(), |
|
927 for every key repeat and long key event generated by the timer and also for |
|
928 delayed short key events from KeyUp(). |
|
929 |
|
930 @param aOutput Output key event from routing plug-in |
|
931 @param aIsRepeat Event is due to key repeat |
|
932 @param aRepeats Repeat count |
|
933 */ |
|
934 void TWindowServerEvent::QueueKeyPress(const TKeyEventRouterOutput& aOutput, TBool aIsRepeat, TInt aRepeats) |
|
935 { |
|
936 if (aOutput.iResult == EConsumed) |
|
937 { |
|
938 // Don't deliver this key |
|
939 return; |
|
940 } |
|
941 |
|
942 TWsEvent event; |
|
943 TKeyEvent& keyEvent = *event.Key(); |
|
944 keyEvent = aOutput.iKeyEvent; |
|
945 keyEvent.iRepeats = aRepeats; |
|
946 |
|
947 CWsWindowGroup* focusWin = static_cast<CWsWindowGroup*>(aOutput.iWindowGroup); |
|
948 WS_ASSERT_DEBUG(focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW, EWsPanicKeyEventRouterBadWindowGroup); |
|
949 |
|
950 if (aIsRepeat && aOutput.iResult != ECaptured && focusWin != CWsTop::FocusWindowGroup()) |
764 CKeyboardRepeat::CancelRepeat(NULL); // Repeat is going to different window so cancel it and don't deliver this key |
951 CKeyboardRepeat::CancelRepeat(NULL); // Repeat is going to different window so cancel it and don't deliver this key |
765 else if (focusWin!=NULL && focusWin->CheckForPriorityKey(aKey,aScanCode)==EFalse) |
952 else if (focusWin != NULL && focusWin->CheckForPriorityKey(keyEvent) == EFalse) |
766 { |
953 { |
767 if (longCapture || (aCheckRepeat && !aRepeatFocus && aKey.iModifiers&EModifierAutorepeatable)) |
|
768 { |
|
769 if (CKeyboardRepeat::StartRepeat(aKey,aScanCode,focusWin,longCapture)) |
|
770 return; |
|
771 } |
|
772 event.SetType(EEventKey); |
954 event.SetType(EEventKey); |
773 event.SetHandle(focusWin->ClientHandle()); |
955 event.SetHandle(focusWin->ClientHandle()); |
774 if (aRepeats!=0) |
956 if (aRepeats!=0) |
775 { |
957 { |
776 CEventQueue* queue=focusWin->EventQueue(); |
958 CEventQueue* queue=focusWin->EventQueue(); |
777 queue->Wait(); |
959 queue->Wait(); |
778 const TWsEvent* prev=queue->PeekLastEvent(); |
960 const TWsEvent* prev=queue->PeekLastEvent(); |
779 if (prev!=NULL && prev->Type()==EEventKey && prev->Key()->iRepeats>0) |
961 if (prev != NULL && prev->Type() == EEventKey && prev->Key()->iRepeats > 0 && prev->Key()->iCode == keyEvent.iCode) |
780 { |
962 { |
781 event= *prev; |
963 prev->Key()->iRepeats += aRepeats; |
782 event.Key()->iRepeats+=aRepeats; |
|
783 queue->UpdateLastEvent(event); |
|
784 queue->Signal(); |
964 queue->Signal(); |
785 if (CClick::IsHandler()) |
965 if (CClick::IsHandler()) |
786 CClick::KeyEvent(EEventKeyRepeat,*event.Key()); |
966 CClick::KeyEvent(EEventKeyRepeat, *prev->Key()); |
787 return; |
967 return; |
788 } |
968 } |
789 queue->Signal(); |
969 queue->Signal(); |
790 event.Key()->iRepeats=aRepeats; |
|
791 if (CClick::IsHandler()) |
970 if (CClick::IsHandler()) |
792 CClick::KeyEvent(EEventKeyRepeat,keyEvent); |
971 CClick::KeyEvent(EEventKeyRepeat,keyEvent); |
793 } |
972 } |
794 QueueKeyEvent(focusWin, event, EEventPriorityLow); |
973 QueueKeyEvent(focusWin, event, EEventPriorityLow); |
795 } |
974 } |
796 } |
975 } |
797 |
976 |
|
977 /** |
|
978 Queue a key up/down event. |
|
979 |
|
980 @param aRawEvent Raw event |
|
981 */ |
798 void TWindowServerEvent::QueueKeyUpDown(const TRawEvent &aRawEvent) |
982 void TWindowServerEvent::QueueKeyUpDown(const TRawEvent &aRawEvent) |
799 { |
983 { |
800 CWsWindowGroup *focusWin=CWsCaptureKeyUpsAndDowns::CheckForCapture(aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE, iModifierState); |
984 TEventCode type = aRawEvent.Type() == TRawEvent::EKeyUp ? EEventKeyUp : EEventKeyDown; |
801 if (!focusWin) // If not captured |
985 |
802 focusWin=CWsTop::FocusWindowGroup(); |
986 // Check for key up/down capture |
803 TWsEvent event; |
987 TKeyEvent keyEvent; |
804 TEventCode type=aRawEvent.Type()==TRawEvent::EKeyUp ? EEventKeyUp : EEventKeyDown; |
988 keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; |
805 event.Key()->iCode=0; |
989 #if defined(__WINS__) |
|
990 keyEvent.iCode = __WINS_CHARCODE(aRawEvent.ScanCode()); |
|
991 #else |
|
992 keyEvent.iCode = 0; |
|
993 #endif |
|
994 keyEvent.iModifiers = iModifierState; |
|
995 keyEvent.iRepeats = 0; |
|
996 |
|
997 CWsWindowGroup* focusWin = CWsTop::FocusWindowGroup(); |
|
998 TUid focusAppUid = focusWin ? TUid::Uid(focusWin->Client()->SecureId().iId) : KNullUid; |
|
999 |
|
1000 TKeyEventRouterInput input(ECaptureTypeKeyUpDown, keyEvent, focusWin, focusAppUid); |
|
1001 TKeyEventRouterOutput output; |
|
1002 #ifdef _DEBUG |
|
1003 TRAPD(err, iKeyEventRouter->RouteKey(input, output)); |
|
1004 WS_ASSERT_DEBUG(err == KErrNone, EWsPanicKeyEventRouterLeave); |
|
1005 #else |
|
1006 iKeyEventRouter->RouteKey(input, output); |
|
1007 #endif |
|
1008 |
|
1009 if (output.iResult == EConsumed) |
|
1010 { |
|
1011 // Don't deliver this key. A key click is still generated for the |
|
1012 // input event. |
|
1013 if (CClick::IsHandler()) |
|
1014 { |
|
1015 CClick::KeyEvent(type, keyEvent); |
|
1016 } |
|
1017 return; |
|
1018 } |
|
1019 WS_ASSERT_DEBUG(output.iResult == ERouted || output.iResult == ECaptured, EWsPanicKeyEventRouterBadResult); |
|
1020 |
|
1021 focusWin = static_cast<CWsWindowGroup*>(output.iWindowGroup); |
|
1022 WS_ASSERT_DEBUG((focusWin == NULL || focusWin->Type() == WS_HANDLE_GROUP_WINDOW) && (output.iResult != ERouted || focusWin == CWsTop::FocusWindowGroup()), EWsPanicKeyEventRouterBadWindowGroup); |
806 #if defined(__WINS__) |
1023 #if defined(__WINS__) |
807 if (focusWin && !focusWin->WsOwner()->RemoveKeyCode()) |
1024 if (focusWin && !focusWin->WsOwner()->RemoveKeyCode()) |
808 event.Key()->iScanCode=aRawEvent.ScanCode(); |
1025 { |
809 else |
1026 // Restore WINS character code |
|
1027 output.iKeyEvent.iScanCode |= output.iKeyEvent.iCode; |
|
1028 } |
|
1029 output.iKeyEvent.iCode = 0; |
810 #endif |
1030 #endif |
811 event.Key()->iScanCode=aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; |
1031 |
812 event.Key()->iModifiers=iModifierState; |
1032 output.iKeyEvent.iRepeats = 0; |
813 event.Key()->iRepeats=0; |
|
814 if (CClick::IsHandler()) |
1033 if (CClick::IsHandler()) |
815 CClick::KeyEvent(type,*event.Key()); |
1034 { |
|
1035 CClick::KeyEvent(type, output.iKeyEvent); |
|
1036 } |
|
1037 |
|
1038 TWsEvent event; |
|
1039 *event.Key() = output.iKeyEvent; |
816 if (focusWin!=NULL) |
1040 if (focusWin!=NULL) |
817 { |
1041 { |
818 event.SetType(type); |
1042 event.SetType(type); |
819 event.SetHandle(focusWin->ClientHandle()); |
1043 event.SetHandle(focusWin->ClientHandle()); |
820 QueueKeyEvent(focusWin, event, EEventPriorityHigh); |
1044 QueueKeyEvent(focusWin, event, EEventPriorityHigh); |
1018 #endif |
1247 #endif |
1019 break; |
1248 break; |
1020 case TRawEvent::EKeyDown: |
1249 case TRawEvent::EKeyDown: |
1021 { |
1250 { |
1022 _LIT(KWSERVDebugLogKeyDownArrival,"Key down arrives %d"); |
1251 _LIT(KWSERVDebugLogKeyDownArrival,"Key down arrives %d"); |
1023 if(CDebugBar* dbg = CWsTop::Screen()->DebugBar()) |
1252 CScreen* screen = CWsTop::Screen(); |
|
1253 WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen); |
|
1254 if(CDebugBar* dbg = screen->DebugBar()) |
1024 dbg->OnKeyEvent(); |
1255 dbg->OnKeyEvent(); |
1025 if (wsDebugLog) |
1256 if (wsDebugLog) |
1026 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyDownArrival,aRawEvent.ScanCode()); |
1257 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyDownArrival,aRawEvent.ScanCode()); |
1027 CKeyboardRepeat::KeyDown(); |
1258 CKeyboardRepeat::KeyDown(); |
1028 TKeyData keyData; |
1259 TKeyData keyData; |
|
1260 // Note iCaptureKeys is needed as dummy arg only. Key capture is |
|
1261 // now handled in ProcessKeyPress(). |
1029 TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), EFalse,*iCaptureKeys,keyData); |
1262 TBool translated=iKeyTranslator->TranslateKey(aRawEvent.ScanCode(), EFalse,*iCaptureKeys,keyData); |
1030 ProcessModifierChanges(); |
1263 ProcessModifierChanges(); |
1031 QueueKeyUpDown(aRawEvent); |
1264 QueueKeyUpDown(aRawEvent); |
1032 if (translated) |
1265 if (translated) |
1033 QueueKeyPress(keyData,aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,ETrue,0); |
1266 { |
|
1267 TKeyEvent keyEvent; |
|
1268 keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; |
|
1269 keyEvent.iCode = keyData.iKeyCode; |
|
1270 keyEvent.iModifiers = keyData.iModifiers; |
|
1271 ProcessKeyPress(keyEvent, ETrue, 0); |
|
1272 } |
1034 } |
1273 } |
1035 break; |
1274 break; |
1036 case TRawEvent::EKeyUp: |
1275 case TRawEvent::EKeyUp: |
1037 { |
1276 { |
1038 _LIT(KWSERVDebugLogKeyUpArrival,"Key up arrives %d"); |
1277 _LIT(KWSERVDebugLogKeyUpArrival,"Key up arrives %d"); |
1039 if(CDebugBar* dbg = CWsTop::Screen()->DebugBar()) |
1278 CScreen* screen = CWsTop::Screen(); |
|
1279 WS_ASSERT_ALWAYS(screen, EWsPanicNoScreen); |
|
1280 if(CDebugBar* dbg = screen->DebugBar()) |
1040 dbg->OnKeyEvent(); |
1281 dbg->OnKeyEvent(); |
1041 if (wsDebugLog) |
1282 if (wsDebugLog) |
1042 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyUpArrival,aRawEvent.ScanCode()); |
1283 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogKeyUpArrival,aRawEvent.ScanCode()); |
1043 TKeyData keyData; |
1284 TKeyData keyData; |
1044 CKeyboardRepeat::KeyUp(aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE); |
1285 CKeyboardRepeat::KeyUp(aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE); |
1077 case TRawEvent::EKeyRepeat: |
1322 case TRawEvent::EKeyRepeat: |
1078 { |
1323 { |
1079 _LIT(KWSERVDebugLogRepeatingKeyArrival,"Repeating key arrives %d"); |
1324 _LIT(KWSERVDebugLogRepeatingKeyArrival,"Repeating key arrives %d"); |
1080 if (wsDebugLog) |
1325 if (wsDebugLog) |
1081 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogRepeatingKeyArrival,aRawEvent.ScanCode()); |
1326 wsDebugLog->MiscMessage(CDebugLogBase::ELogEverything,KWSERVDebugLogRepeatingKeyArrival,aRawEvent.ScanCode()); |
1082 TKeyData keyData; |
1327 TKeyEvent keyEvent; |
1083 keyData.iModifiers=iKeyTranslator->GetModifierState(); |
1328 keyEvent.iScanCode = aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE; |
1084 keyData.iApp=0; |
1329 keyEvent.iCode = aRawEvent.ScanCode(); |
1085 keyData.iHandle=0; |
1330 keyEvent.iModifiers = iKeyTranslator->GetModifierState(); |
1086 keyData.iIsCaptureKey=EFalse; |
1331 ProcessKeyPress(keyEvent, EFalse, aRawEvent.Repeats()); |
1087 keyData.iKeyCode=aRawEvent.ScanCode(); |
|
1088 iCaptureKeys->ProcessCaptureKeys(keyData); |
|
1089 QueueKeyPress(keyData, aRawEvent.ScanCode() __REMOVE_WINS_CHARCODE,NULL,EFalse,aRawEvent.Repeats()); |
|
1090 } |
1332 } |
1091 break; |
1333 break; |
1092 default: |
1334 default: |
1093 break; |
1335 break; |
1094 } |
1336 } |
1095 } |
1337 } |
1096 |
1338 |
1097 void TWindowServerEvent::ProcessKeyEvent(const TKeyEvent &aKeyEvent,TInt aRepeats) |
1339 void TWindowServerEvent::ProcessKeyEvent(const TKeyEvent &aKeyEvent,TInt aRepeats) |
1098 { |
1340 { |
1099 TKeyData keyData; |
|
1100 keyData.iModifiers=aKeyEvent.iModifiers; |
|
1101 keyData.iApp=0; |
|
1102 keyData.iHandle=0; |
|
1103 keyData.iIsCaptureKey=EFalse; |
|
1104 keyData.iKeyCode=aKeyEvent.iCode; |
|
1105 if (CKeyboardRepeat::IsAreadyActive()) |
1341 if (CKeyboardRepeat::IsAreadyActive()) |
1106 { |
1342 { |
1107 CKeyboardRepeat::CancelRepeat(NULL); |
1343 CKeyboardRepeat::CancelRepeat(NULL); |
1108 } |
1344 } |
1109 iCaptureKeys->ProcessCaptureKeys(keyData); |
1345 ProcessKeyPress(aKeyEvent, aRepeats == 0, aRepeats); |
1110 QueueKeyPress(keyData,aKeyEvent.iScanCode,NULL,aRepeats==0,aRepeats); |
1346 } |
1111 } |
1347 |
1112 |
1348 void TWindowServerEvent::AddCaptureKeyL(const TKeyCaptureRequest& aRequest) |
1113 void TWindowServerEvent::AddCaptureKeyL(const TCaptureKey &aCaptureKey) |
1349 { |
1114 { |
1350 iKeyEventRouter->AddCaptureKeyL(aRequest); |
1115 iCaptureKeys->AddCaptureKeyL(aCaptureKey,aCaptureKey.iKeyCodePattern.iFiller); |
1351 } |
1116 } |
1352 |
1117 |
1353 void TWindowServerEvent::UpdateCaptureKeyL(const TKeyCaptureRequest& aRequest) |
1118 void TWindowServerEvent::SetCaptureKey(TUint32 aHandle, const TCaptureKey &aCaptureKey) |
1354 { |
1119 { |
1355 iKeyEventRouter->UpdateCaptureKeyL(aRequest); |
1120 iCaptureKeys->SetCaptureKey(aHandle, aCaptureKey,aCaptureKey.iKeyCodePattern.iFiller); |
1356 } |
1121 } |
1357 |
1122 |
1358 void TWindowServerEvent::CancelCaptureKey(TKeyCaptureType aType, TAny* aHandle) |
1123 void TWindowServerEvent::CancelCaptureKey(TUint32 aHandle) |
1359 { |
1124 { |
1360 iKeyEventRouter->CancelCaptureKey(aType, aHandle); |
1125 iCaptureKeys->CancelCaptureKey(aHandle); |
|
1126 } |
1361 } |
1127 |
1362 |
1128 TInt TWindowServerEvent::GetModifierState() |
1363 TInt TWindowServerEvent::GetModifierState() |
1129 { |
1364 { |
1130 return(iKeyTranslator->GetModifierState()); |
1365 return(iKeyTranslator->GetModifierState()); |
1489 } |
1730 } |
1490 if (timer) |
1731 if (timer) |
1491 After(iTime); |
1732 After(iTime); |
1492 else |
1733 else |
1493 iRepeating=ERepeatNone; |
1734 iRepeating=ERepeatNone; |
1494 TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iKey,iCurrentRepeat.iScanCode,iFocus,EFalse,1); |
1735 |
1495 } |
1736 TWindowServerEvent::QueueKeyPress(iCurrentRepeat.iOutput, ETrue, 1); |
1496 |
1737 } |
1497 TBool CKeyboardRepeat::StartRepeat(const TKeyData &aKey, TInt aScanCode, CWsWindowGroup *aRepeatFocus, CWsCaptureLongKey* aLongCapture) |
1738 |
|
1739 /** |
|
1740 Start key repeat and long key press timer |
|
1741 |
|
1742 @param aInputScanCode Original scan code (before routing) |
|
1743 @param aShortEvent Short key event (routing plug-in output) |
|
1744 @param aLongEvent Pointer to long key event (routing plug-in output) |
|
1745 or NULL if none. |
|
1746 |
|
1747 Note: When aLongEvent != NULL, iCurrentRepeat reflects the short key event |
|
1748 until the timer has expired. This is necessary to allow a delayed short key |
|
1749 event to be delivered by KeyUp(). CancelRepeat() must therefore examine |
|
1750 iCurrentRepeat or iLongRepeat according to the repeat type in iRepeat. |
|
1751 */ |
|
1752 void CKeyboardRepeat::StartRepeat(TInt aInputScanCode, const TKeyEventRouterOutput& aShortEvent, const TKeyEventRouterOutput* aLongEvent) |
1498 { |
1753 { |
1499 TTimeIntervalMicroSeconds32 time; |
1754 TTimeIntervalMicroSeconds32 time; |
1500 TBool ret=EFalse; |
1755 iCurrentRepeat.iInputScanCode = aInputScanCode; |
1501 iCurrentRepeat.iScanCode=aScanCode; |
1756 iCurrentRepeat.iOutput = aShortEvent; |
1502 iCurrentRepeat.iKey=aKey; |
1757 |
1503 |
1758 if (aLongEvent) |
1504 if (aLongCapture) |
1759 { |
1505 { |
1760 iRepeating = ERepeatLong; |
1506 iLongCapture=aLongCapture; |
1761 iLongRepeat.iInputScanCode = aInputScanCode; |
1507 iRepeating=ERepeatLong; |
1762 iLongRepeat.iOutput = *aLongEvent; |
1508 time=aLongCapture->iData.delay; |
1763 iLongCapture = static_cast<CWsCaptureLongKey*>(aLongEvent->iCaptureHandle); |
1509 ret=!(aLongCapture->iData.flags&ELongCaptureShortEventImmediately); |
1764 time = iLongCapture->iDelay; |
1510 //need window group from long capture key or even better delete it altogether. |
|
1511 iFocus=aLongCapture->WindowGroup(); |
|
1512 } |
1765 } |
1513 else |
1766 else |
1514 { |
1767 { |
1515 iFocus=aRepeatFocus; |
1768 iLongCapture = NULL; |
1516 iRepeating=ERepeatNormal; |
1769 iRepeating=ERepeatNormal; |
1517 time=iInitialTime; |
1770 time=iInitialTime; |
1518 } |
1771 } |
1519 iThis->After(time); |
1772 iThis->After(time); |
1520 return ret; |
1773 } |
1521 } |
1774 |
1522 |
1775 /** |
|
1776 Cancel key repeat processing |
|
1777 */ |
1523 void CKeyboardRepeat::doCancelRepeat() |
1778 void CKeyboardRepeat::doCancelRepeat() |
1524 { |
1779 { |
1525 iRepeating=ERepeatNone; |
1780 iRepeating=ERepeatNone; |
1526 iThis->Cancel(); |
1781 iThis->Cancel(); |
1527 } |
1782 } |
1528 |
1783 |
|
1784 /** |
|
1785 Cancel any key repeat associated with the specified window group |
|
1786 |
|
1787 @param aRepeatFocus Destination window group or NULL for all |
|
1788 */ |
1529 void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus) |
1789 void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus) |
1530 { |
1790 { |
1531 if (aRepeatFocus==NULL || aRepeatFocus==iFocus) |
1791 if (iRepeating != ERepeatNone) |
1532 { |
1792 { |
1533 if (iRepeating) |
1793 if (aRepeatFocus == NULL || |
1534 doCancelRepeat(); |
1794 (iRepeating == ERepeatNormal) && (aRepeatFocus == iCurrentRepeat.iOutput.iWindowGroup) || |
1535 iAlternateRepeatExists=EFalse; |
1795 (iRepeating >= ERepeatLong) && (aRepeatFocus == iLongRepeat.iOutput.iWindowGroup)) |
1536 } |
|
1537 else if (iRepeating >= ERepeatLong) |
|
1538 { |
|
1539 // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong |
|
1540 if (iLongCapture && iLongCapture->iWindowGroup == aRepeatFocus) |
|
1541 { |
1796 { |
1542 doCancelRepeat(); |
1797 doCancelRepeat(); |
1543 iAlternateRepeatExists=EFalse; |
1798 iAlternateRepeatExists=EFalse; |
1544 } |
1799 } |
1545 } |
1800 } |
1546 } |
1801 } |
1547 |
1802 |
1548 void CKeyboardRepeat::CancelRepeat(CWsWindowGroup *aRepeatFocus,TUint aScanCode,TBool aLongCaptureFlag,TUint aModifiers) |
1803 /** |
|
1804 Cancel any key repeat associated with the specified capture handle |
|
1805 |
|
1806 @param aCaptureHandle Handle to capture request |
|
1807 @param aLongCaptureFlag ETrue for long key capture, EFalse for normal key |
|
1808 */ |
|
1809 void CKeyboardRepeat::CancelRepeat(const TAny* aCaptureHandle, TBool aLongCaptureFlag) |
1549 { |
1810 { |
1550 if (aLongCaptureFlag) |
1811 if (aLongCaptureFlag) |
1551 { |
1812 { |
1552 // long capture key is cancelled |
1813 // Cancel repeat for long capture key |
1553 if (iRepeating >= ERepeatLong && iCurrentRepeat.iScanCode==aScanCode) |
1814 if (iRepeating >= ERepeatLong && aCaptureHandle == iLongRepeat.iOutput.iCaptureHandle) |
1554 { |
1815 { |
1555 // Defensive programming - iLongCapture should never be NULL if iRepeating >= ERepeatLong |
1816 doCancelRepeat(); |
1556 if (iLongCapture && aRepeatFocus == iLongCapture->iWindowGroup && |
1817 iAlternateRepeatExists=EFalse; |
1557 (aModifiers & iLongCapture->iData.modifierMask) == iLongCapture->iData.modifiers) |
1818 } |
1558 { |
|
1559 doCancelRepeat(); |
|
1560 iAlternateRepeatExists=EFalse; |
|
1561 } |
|
1562 } |
|
1563 } |
1819 } |
1564 else |
1820 else |
1565 { |
1821 { |
1566 // normal capture key is cancelled |
1822 // Cancel repeat for normal capture key |
1567 if (aRepeatFocus==iFocus) |
1823 if (iRepeating == ERepeatNormal && aCaptureHandle == iCurrentRepeat.iOutput.iCaptureHandle) |
1568 { |
1824 { |
1569 if (iRepeating>=ERepeatNormal && iCurrentRepeat.iScanCode==aScanCode) |
1825 doCancelRepeat(); |
1570 { |
|
1571 doCancelRepeat(); |
|
1572 } |
|
1573 iAlternateRepeatExists=EFalse; |
1826 iAlternateRepeatExists=EFalse; |
1574 } |
1827 } |
1575 } |
1828 } |
1576 } |
1829 } |
1577 |
1830 |
|
1831 /** |
|
1832 Process a key down event during key repeat. |
|
1833 The current repeat data is saved for possible restoration after rollover. |
|
1834 */ |
1578 void CKeyboardRepeat::KeyDown() |
1835 void CKeyboardRepeat::KeyDown() |
1579 { |
1836 { |
1580 if (iRepeating!=ERepeatNone) |
1837 if (iRepeating!=ERepeatNone) |
1581 { |
1838 { |
1582 if (iRepeating==ERepeatNormal && iRepeatRollover>0) // 1 Allow key repeat rollover |
1839 if (iRepeating==ERepeatNormal && iRepeatRollover>0) // 1 Allow key repeat rollover |