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.
Shachar
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 @@ "zZ","xX","cC","vV","bB","nN","mM","öÖ","çÇ",".:" };
+/*** Israeli keyboard layout */ +static const char main_key_IL[MAIN_LEN][4] = +{ + "`~;","1!1","2@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);