Fix a bug in VkKeyScan
Dmitry Timoshkov
dmitry at baikal.ru
Sun Nov 9 05:49:29 CST 2003
Hello,
some apps, such as winword create their own virtual keyboard map
using VkKeyScan. Our implementation was returning same virtual key
for physically different characters, i.e. a later mapped character
was clobbering a previously mapped one.
This is due to the fact that we passed index > 3 to XKeycodeToKeysym.
Reading XFree86 sources confirmed that it's wrong. Indexes larger 3
are used for indexing other (not current) language groups.
Also I took the freedom to reformat the whole function body.
Changelog:
Dmitry Timoshkov <dmitry at codeweavers.com>
Fix a bug in VkKeyScan.
--- cvs/hq/wine/dlls/x11drv/keyboard.c Tue Nov 4 19:37:16 2003
+++ wine/dlls/x11drv/keyboard.c Sun Nov 9 19:23:06 2003
@@ -1501,48 +1501,67 @@ void X11DRV_MappingNotify( XMappingEvent
*/
WORD X11DRV_VkKeyScan(CHAR cChar)
{
- Display *display = thread_display();
- KeyCode keycode;
- KeySym keysym;
- int i,index;
- int highbyte=0;
-
- /* char->keysym (same for ANSI chars) */
- keysym=(unsigned char) cChar;/* (!) cChar is signed */
- if (keysym<=27) keysym+=0xFF00;/*special chars : return, backspace...*/
-
- keycode = TSXKeysymToKeycode(display, keysym); /* keysym -> keycode */
- if (!keycode)
- { /* It didn't work ... let's try with deadchar code. */
- keycode = TSXKeysymToKeycode(display, keysym | 0xFE00);
- }
-
- TRACE("'%c'(%#lx, %lu): got keycode %#.2x\n",
- cChar,keysym,keysym,keycode);
-
- if (keycode)
- {
- for (index=-1, i=0; (i<8) && (index<0); i++) /* find shift state */
- if (TSXKeycodeToKeysym(display,keycode,i)==keysym) index=i;
- switch (index) {
- case -1 :
- WARN("Keysym %lx not found while parsing the keycode table\n",keysym); break;
- case 0 : break;
- case 1 : highbyte = 0x0100; break;
- case 2 : highbyte = 0x0600; break;
- case 3 : highbyte = 0x0700; break;
- default : ERR("index %d found by XKeycodeToKeysym. please report! \n",index);
- }
- /*
- index : 0 adds 0x0000
- index : 1 adds 0x0100 (shift)
- index : ? adds 0x0200 (ctrl)
- index : 2 adds 0x0600 (ctrl+alt)
- index : 3 adds 0x0700 (ctrl+alt+shift)
- */
- }
- TRACE(" ... returning %#.2x\n", keyc2vkey[keycode]+highbyte);
- return keyc2vkey[keycode]+highbyte; /* keycode -> (keyc2vkey) vkey */
+ Display *display = thread_display();
+ KeyCode keycode;
+ KeySym keysym;
+ int i, index;
+ SHORT ret;
+
+ /* char->keysym (same for ANSI chars) */
+ keysym = (unsigned char)cChar; /* (!) cChar is signed */
+ if (keysym <= 27) keysym += 0xFF00; /* special chars : return, backspace... */
+
+ keycode = TSXKeysymToKeycode(display, keysym); /* keysym -> keycode */
+ if (!keycode)
+ { /* It didn't work ... let's try with deadchar code. */
+ TRACE("retrying with | 0xFE00\n");
+ keycode = TSXKeysymToKeycode(display, keysym | 0xFE00);
+ }
+
+ TRACE("'%c'(%#lx, %lu): got keycode %#.2x (%d)\n",
+ cChar, keysym, keysym, keycode, keycode);
+
+ /* keycode -> (keyc2vkey) vkey */
+ ret = keyc2vkey[keycode];
+
+ if (!keycode || !ret)
+ {
+ TRACE("keycode for '%c' not found, returning -1\n", cChar);
+ return -1;
+ }
+
+ index = -1;
+ for (i = 0; i < 4; i++) /* find shift state */
+ {
+ if (TSXKeycodeToKeysym(display, keycode, i) == keysym)
+ {
+ index = i;
+ break;
+ }
+ }
+
+ switch (index)
+ {
+ default:
+ case -1:
+ WARN("Keysym %lx not found while parsing the keycode table\n", keysym);
+ return -1;
+
+ case 0: break;
+ case 1: ret += 0x0100; break;
+ case 2: ret += 0x0600; break;
+ case 3: ret += 0x0700; break;
+ }
+ /*
+ index : 0 adds 0x0000
+ index : 1 adds 0x0100 (shift)
+ index : ? adds 0x0200 (ctrl)
+ index : 2 adds 0x0600 (ctrl+alt)
+ index : 3 adds 0x0700 (ctrl+alt+shift)
+ */
+
+ TRACE(" ... returning %#.2x\n", ret);
+ return ret;
}
/***********************************************************************
More information about the wine-patches
mailing list