Handle control characters in VkKeyScanEx similar to what Windows does
Dmitry Timoshkov
dmitry at baikal.ru
Mon Mar 28 07:57:44 CST 2005
Hello,
Ulrich Czekalla reported that an application he is working on calls
VkKeyScan(0xa) which fails under Wine. The app uses VkKeyScan to build
INPUT structures for SendInput.
I wrote a simple test app which dumps VkKeyScan output for characters
below 32 and uses MapVirtualKey to verify returned values under WIndows.
for (i = 0; i < 32; i++)
{
vkey = VkKeyScan(i);
printf("VkKeyScan(%d) -> 0x%04x\n", i, vkey);
vkey &= 0xff;
scan = MapVirtualKey(vkey, 2);
printf("MapVirtualKey(0x%04x) -> %d (0x%04x)\n", vkey, scan, scan);
}
Windows appears to add 0x240 to each not directly translated to a vkey
passed character. 0x200 aparently indicates a control char. What means 0x40
I don't know, and MSDN doesn't explain it either, perhaps that's just a fixup.
Attached patch seems to produce the results which resemble Windows behaviour
close enough.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Handle control characters in VkKeyScanEx similar to what Windows does.
--- cvs/hq/wine/dlls/x11drv/keyboard.c 2005-03-23 09:27:48.000000000 +0800
+++ wine/dlls/x11drv/keyboard.c 2005-03-27 14:48:43.000000000 +0900
@@ -1866,6 +1866,9 @@ SHORT X11DRV_VkKeyScanEx(WCHAR wChar, HK
CHAR cChar;
SHORT ret;
+ /* FIXME: what happens if wChar is not a Latin1 character and CP_UNIXCP
+ * is UTF-8 (multibyte encoding)?
+ */
if (!WideCharToMultiByte(CP_UNIXCP, 0, &wChar, 1, &cChar, 1, NULL, NULL))
{
WARN("no translation from unicode to CP_UNIXCP for 0x%02x\n", wChar);
@@ -1881,7 +1884,15 @@ SHORT X11DRV_VkKeyScanEx(WCHAR wChar, HK
wine_tsx11_lock();
keycode = XKeysymToKeycode(display, keysym); /* keysym -> keycode */
if (!keycode)
- { /* It didn't work ... let's try with deadchar code. */
+ {
+ if (keysym >= 0xFF00) /* Windows returns 0x0240 + cChar in this case */
+ {
+ ret = 0x0240 + cChar; /* 0x0200 indicates a control character */
+ TRACE(" ... returning ctrl char %#.2x\n", ret);
+ wine_tsx11_unlock();
+ return ret;
+ }
+ /* It didn't work ... let's try with deadchar code. */
TRACE("retrying with | 0xFE00\n");
keycode = XKeysymToKeycode(display, keysym | 0xFE00);
}
More information about the wine-patches
mailing list