Paul Loewenstein wrote:
The XWin server uses primarily hardware scan codes for interpreting the
windows WM_KEYDOWN and WM_SYSKEYDOWN messages. Unfortunately, Vista
speech recognition (WSR) doesn't bother to fill in the scancode field in
the lParam entry. Neither does SendKeys.SendWait(), which is what
Vocola 3, a recently released supplement to WSR, uses to send input to
applications.
To work around these Microsoft bugs, I modified winkeybd.c as follows:
void
winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode)
{
int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1];
int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2];
int iParamScanCode = LOBYTE (HIWORD (lParam));
to
void
winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode)
{
HKL dwhkl = GetKeyboardLayout(0);
int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1];
int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2];
int iParamScanCode = MapVirtualKeyEx (wParam,
/*MAPVK_VK_TO_VSC*/0, dwhkl);
so that the scan code is regenerated from the keycode.
diff is your friend :-)
An initial test appears to work. However, it is not clear to me whether
I have introduced some subtle bugs. For example, its correctness depends
on extended codes having the same scan code as the non-extended
equivalent on all keyboard layouts.
How about writing it in the following form, that should address that concern,
if I've understood correctly (in all cases, assuming 0 is never a valid scancode)
$ quilt diff
Index: xorg-server-1.5.3/xserver/hw/xwin/winkeybd.c
===================================================================
--- xorg-server-1.5.3.orig/xserver/hw/xwin/winkeybd.c 2009-01-05
23:50:04.000000000 +0000
+++ xorg-server-1.5.3/xserver/hw/xwin/winkeybd.c 2009-01-10
21:55:40.000000000 +0000
@@ -80,6 +80,12 @@
int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2];
int iParamScanCode = LOBYTE (HIWORD (lParam));
+ /* WM_ key messages faked by speech recognizers don't have a scan code... */
+ if (iParamScanCode == 0)
+ {
+ 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;
Can someone tell me if I've broken anything? Or suggest a more robust
fix? It would be nice to be able to release it rather than having a
privately distributed modification solely for Vista speech recognition.
Well, my keyboard seems to still work with the above change. I don't think
there will be a problem including a patch like this, provided we can be fairly
confident it hasn't broken normal keyboards :-)
--
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
Problem reports: http://cygwin.com/problems.html
Documentation: http://x.cygwin.com/docs/
FAQ: http://x.cygwin.com/docs/faq/