Keyboard layout detection not working??

Shachar Shemesh wine-devel at
Fri May 31 05:35:46 CDT 2002

Shachar Shemesh wrote:

> Hi all,
> I am using Debian SID with KDE. In KDE, I defined two keyboard layouts
> (US and IL). I tried to add Israeli keyboard detection using the
> attached patch (layout.diff). When trying to test that patch, however, I
> perform the following task:
> I type in the command as suggested in the docs (wine --debugmsg
> +key,+keyboard >& key.log). Attached are two run attempts. key.log is
> with the US keyboard selected, key2.log is with the Hebrew keyboard
> selected.

Hi all,

Further research revealed the problem, and here is a working patch. I 
would like to both draw your attention to the reasons, and point out one 
thing in this patch that requires attention.

One of the reasons the previous patch did not work was that the X 
keymapping for Hebrew did all of the extra layout on the shifted 
characters. As a result, the first two characters of each key were the 
usual US keyboard, and therefor the US keyboard was matched.

I did notice two things which were rather strange, and I believe were 
bugs. One of them, I fixed. The other I did not.

The one fixed in this patch is on line 991 of dlls/x11drc/keyboard.c 
(inside the X11DRV_KEYBOARD_DetectLayout function), is says:
        /* Allow both one-byte and two-byte national keysyms */
        if ((keysym < 0x800) && (keysym != ' '))
          ckey[i] = keysym & 0xFF;
        else {
          ckey[i] = KEYBOARD_MapDeadKeysym(keysym);

The problem is that the Hebrew keysyms are at 0x0fe0-0x0ff9. They don't 
pass the condition, and the function tries to convert them using 
KEYBOARD_MapDeadKeysym, which obviously fails. My first idea was to 
change this to:
        if ((keysym < 0x1000) && (keysym != ' '))

But I then realized that this was probably just a missing 0, and was 
meant to be:
        if ((keysym < 0x8000) && (keysym != ' '))

That's the point where I give up (X is not my strongest side). Will 
anyone who knows how X uses the keyboard mappings have a look and find 
out which is the correct one? If 0x800 (the current) is the correct one, 
some code needs to be put in for languages (such as Hebrew) where the 
characters are above 0x800.

The second problem I encountered was that keymaps that had three letters 
per key, but the third letter was wrong, received the same score (i.e. - 
were not counted as mismatches) as keymaps that only had two letters. In 
fact, if the X representation had only two letters, the three letter 
keymaps were not penalized for trying to match a non-existing key. I 
believe this is not the right behaviour, but as it does not block me at 
the moment, I did not try to fix it.


-------------- next part --------------
Index: dlls/x11drv/keyboard.c
RCS file: /home/wine/wine/dlls/x11drv/keyboard.c,v
retrieving revision 1.1
diff -u -r1.1 keyboard.c
--- dlls/x11drv/keyboard.c	30 Apr 2002 21:16:39 -0000	1.1
+++ dlls/x11drv/keyboard.c	31 May 2002 10:14:32 -0000
@@ -531,6 +531,15 @@
+/*** Israeli keyboard layout */
+static const char main_key_IL[MAIN_LEN][4] =
+ "`~;","1!1","2 at 2","3#3","4$4","5%5","6^6","7&7","8*8","9(9","0)0","-_-","=+=",
+ "qQ/","wW'","eE÷","rRø","tTà","yYè","uUå","iIï","oOí","pPô","[{[","]}]",
+ "aAù","sSã","dDâ","fFë","gGò","hHé","jJç","kKì","lLê",";:ó","\'\",","\\|\\",
+ "zZæ","xXñ","cCá","vVä","bBð","nNî","mMö",",<ú",".>õ","/?."
 /*** VNC keyboard layout */
 static const WORD main_key_scan_vnc[MAIN_LEN] =
@@ -600,6 +609,7 @@
  {"Latin American keyboard layout", 28591, &main_key_LA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
  {"Lithuanian (Baltic) keyboard layout", 28603, &main_key_LT_B, &main_key_scan_qwerty, &main_key_vkey_qwerty},
  {"Turkish keyboard layout", 28599, &main_key_TK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {"Israeli keyboard layout", 28598, &main_key_IL, &main_key_scan_qwerty, &main_key_vkey_qwerty},
  {"VNC keyboard layout", 28591, &main_key_vnc, &main_key_scan_vnc, &main_key_vkey_vnc},
  {NULL, 0, NULL, NULL, NULL} /* sentinel */
@@ -989,7 +999,7 @@
       for (i = 0; i < syms; i++) {
 	keysym = TSXKeycodeToKeysym (display, keyc, i);
 	/* Allow both one-byte and two-byte national keysyms */
-	if ((keysym < 0x800) && (keysym != ' '))
+	if ((keysym < 0x8000) && (keysym != ' '))
 	  ckey[i] = keysym & 0xFF;
 	else {
 	  ckey[i] = KEYBOARD_MapDeadKeysym(keysym);

More information about the wine-devel mailing list