diff options
Diffstat (limited to 'xorg-server/hw/xwin/winkeybd.c')
-rw-r--r-- | xorg-server/hw/xwin/winkeybd.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/xorg-server/hw/xwin/winkeybd.c b/xorg-server/hw/xwin/winkeybd.c index d574f2053..84b7d8d85 100644 --- a/xorg-server/hw/xwin/winkeybd.c +++ b/xorg-server/hw/xwin/winkeybd.c @@ -49,10 +49,6 @@ static Bool g_winKeyState[NUM_KEYCODES]; -/* Stored to get internal mode key states. Must be read-only. */ -static unsigned short const *g_winInternalModeKeyStatesPtr = NULL; - - /* * Local prototypes */ @@ -84,6 +80,20 @@ winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode) int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2]; int iParamScanCode = LOBYTE (HIWORD (lParam)); +/* WM_ key messages faked by Vista speech recognition (WSR) don't have a + * scan code. + * + * Vocola 3 (Rick Mohr's supplement to WSR) uses + * System.Windows.Forms.SendKeys.SendWait(), which appears always to give a + * scan code of 1 + */ + if (iParamScanCode <= 1) + { + iParamScanCode = MapVirtualKeyEx(wParam, + /*MAPVK_VK_TO_VSC*/0, + GetKeyboardLayout(0)); + } + /* Branch on special extended, special non-extended, or normal key */ if ((HIWORD (lParam) & KF_EXTENDED) && iKeyFixupEx) *piScanCode = iKeyFixupEx; @@ -209,7 +219,6 @@ winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt, static void winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl) { - g_winInternalModeKeyStatesPtr = &(pDevice->key->state); } @@ -293,21 +302,35 @@ winKeybdProc (DeviceIntPtr pDeviceInt, int iState) { winErrorFVerb (1, "winKeybdProc - Error initializing keyboard AutoRepeat (No XKB)\n"); } + + XkbSetExtension(pDeviceInt, ProcessKeyboardEvent); } #endif - - g_winInternalModeKeyStatesPtr = &(pDeviceInt->key->state); break; - case DEVICE_ON: + case DEVICE_ON: + { + DeviceIntPtr master; pDevice->on = TRUE; - g_winInternalModeKeyStatesPtr = &(pDeviceInt->key->state); + + // immediately copy the state of this keyboard device to the VCK + // (which otherwise happens lazily after the first keypress) + master = (!pDeviceInt->isMaster && pDeviceInt->u.master) ? pDeviceInt->u.master : NULL; + if (master) + { + /* Force a copy of the key class into the VCK so that the layout + is transferred. */ + if (!master->key) + master = GetPairedDevice(master); + CopyKeyClass(pDeviceInt, master); + } + } + break; case DEVICE_CLOSE: case DEVICE_OFF: pDevice->on = FALSE; - g_winInternalModeKeyStatesPtr = NULL; break; } @@ -369,7 +392,7 @@ winRestoreModeKeyStates () unsigned short internalKeyStates; /* X server is being initialized */ - if (!g_winInternalModeKeyStatesPtr) + if (!inputInfo.keyboard) return; /* Only process events if the rootwindow is mapped. The keyboard events @@ -382,7 +405,9 @@ winRestoreModeKeyStates () mieqProcessInputEvents (); /* Read the mode key states of our X server */ - internalKeyStates = *g_winInternalModeKeyStatesPtr; + /* (stored in the virtual core keyboard) */ + internalKeyStates = inputInfo.keyboard->key->state; + winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates); /* * NOTE: The C XOR operator, ^, will not work here because it is @@ -580,6 +605,7 @@ winKeybdReleaseKeys () void winSendKeyEvent (DWORD dwKey, Bool fDown) { + DeviceIntPtr pDev; xEvent xCurrentEvent; /* @@ -593,11 +619,20 @@ winSendKeyEvent (DWORD dwKey, Bool fDown) ZeroMemory (&xCurrentEvent, sizeof (xCurrentEvent)); - xCurrentEvent.u.u.type = fDown ? KeyPress : KeyRelease; + xCurrentEvent.u.u.type = fDown ? DeviceKeyPress : DeviceKeyRelease; xCurrentEvent.u.keyButtonPointer.time = g_c32LastInputEventTime = GetTickCount (); xCurrentEvent.u.u.detail = dwKey + MIN_KEYCODE; - mieqEnqueue (&xCurrentEvent); + +#if CYGDEBUG + ErrorF("winSendKeyEvent: xCurrentEvent.u.u.type: %d, xCurrentEvent.u.u.detail: %d\n", + xCurrentEvent.u.u.type, xCurrentEvent.u.u.detail); +#endif + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) + if ((pDev->coreEvents && pDev != inputInfo.keyboard) && pDev->key) + { + mieqEnqueue (pDev, &xCurrentEvent); + } } BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam) |