Fixed mouse position processing for use with a touchscreen.
[wine] / windows / x11drv / keyboard.c
1 /*
2  * X11 keyboard driver
3  *
4  * Copyright 1993 Bob Amstadt
5  * Copyright 1996 Albrecht Kleine 
6  * Copyright 1997 David Faure
7  * Copyright 1998 Morten Welinder
8  * Copyright 1998 Ulrich Weigand
9  * Copyright 1999 Ove Kåven
10  */
11
12 #include "config.h"
13
14 #include <X11/Xatom.h>
15 #include <X11/keysym.h>
16
17 #include "ts_xlib.h"
18 #include "ts_xresource.h"
19 #include "ts_xutil.h"
20 #ifdef HAVE_XKB
21 #include <X11/XKBlib.h>
22 #endif
23
24 #include <ctype.h>
25 #include <string.h>
26
27 #include "windef.h"
28 #include "wingdi.h"
29 #include "wine/winuser16.h"
30 #include "dinput.h"
31 #include "debugtools.h"
32 #include "user.h"
33 #include "keyboard.h"
34 #include "winnls.h"
35 #include "win.h"
36 #include "x11drv.h"
37
38 DEFAULT_DEBUG_CHANNEL(keyboard);
39 DECLARE_DEBUG_CHANNEL(key);
40 DECLARE_DEBUG_CHANNEL(dinput);
41
42 extern BYTE InputKeyStateTable[256];
43
44 extern LPBYTE pKeyStateTable;
45
46 int min_keycode, max_keycode, keysyms_per_keycode;
47 WORD keyc2vkey[256], keyc2scan[256];
48
49 static int NumLockMask, AltGrMask; /* mask in the XKeyEvent state */
50 static int kcControl, kcAlt, kcShift, kcNumLock, kcCapsLock; /* keycodes */
51 #ifdef HAVE_XKB
52 static int is_xkb, xkb_opcode, xkb_event, xkb_error;
53 #endif
54
55 static char KEYBOARD_MapDeadKeysym(KeySym keysym);
56
57 /* Keyboard translation tables */
58 #define MAIN_LEN 48
59 static const WORD main_key_scan_qwerty[MAIN_LEN] =
60 {
61 /* this is my (102-key) keyboard layout, sorry if it doesn't quite match yours */
62    0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,
63    0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,
64    0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x2B,
65    0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
66    0x56 /* the 102nd key (actually to the right of l-shift) */
67 };
68
69 static const WORD main_key_vkey_qwerty[MAIN_LEN] =
70 {
71 /* NOTE: this layout must concur with the scan codes layout above */
72    VK_OEM_3,VK_1,VK_2,VK_3,VK_4,VK_5,VK_6,VK_7,VK_8,VK_9,VK_0,VK_OEM_MINUS,VK_OEM_PLUS,
73    VK_Q,VK_W,VK_E,VK_R,VK_T,VK_Y,VK_U,VK_I,VK_O,VK_P,VK_OEM_4,VK_OEM_6,
74    VK_A,VK_S,VK_D,VK_F,VK_G,VK_H,VK_J,VK_K,VK_L,VK_OEM_1,VK_OEM_7,VK_OEM_5,
75    VK_Z,VK_X,VK_C,VK_V,VK_B,VK_N,VK_M,VK_OEM_COMMA,VK_OEM_PERIOD,VK_OEM_2,
76    VK_OEM_102 /* the 102nd key (actually to the right of l-shift) */
77 };
78
79 static const WORD main_key_vkey_azerty[MAIN_LEN] =
80 {
81 /* NOTE: this layout must concur with the scan codes layout above */
82    VK_OEM_7,VK_1,VK_2,VK_3,VK_4,VK_5,VK_6,VK_7,VK_8,VK_9,VK_0,VK_OEM_4,VK_OEM_PLUS,
83    VK_A,VK_Z,VK_E,VK_R,VK_T,VK_Y,VK_U,VK_I,VK_O,VK_P,VK_OEM_6,VK_OEM_1,
84    VK_Q,VK_S,VK_D,VK_F,VK_G,VK_H,VK_J,VK_K,VK_L,VK_M,VK_OEM_3,VK_OEM_5,
85    VK_W,VK_X,VK_C,VK_V,VK_B,VK_N,VK_OEM_COMMA,VK_OEM_PERIOD,VK_OEM_2,VK_OEM_8,
86    VK_OEM_102 /* the 102nd key (actually to the right of l-shift) */
87 };
88
89 /* FIXME: add other layouts, such as DVORAK and German QWERTZ */
90
91 /*** DEFINE YOUR NEW LANGUAGE-SPECIFIC MAPPINGS BELOW, SEE EXISTING TABLES */
92
93 /* the VK mappings for the main keyboard will be auto-assigned as before,
94    so what we have here is just the character tables */
95 /* order: Normal, Shift, AltGr, Shift-AltGr */
96 /* We recommend you write just what is guaranteed to be correct (i.e. what's
97    written on the keycaps), not the bunch of special characters behind AltGr
98    and Shift-AltGr if it can vary among different X servers */
99 /* Remember that your 102nd key (to the right of l-shift) should be on a
100    separate line, see existing tables */
101 /* If Wine fails to match your new table, use -debugmsg +key to find out why */
102 /* Remember to also add your new table to the layout index table far below! */
103
104 /*** United States keyboard layout (mostly contributed by Uwe Bonnes) */
105 static const char main_key_US[MAIN_LEN][4] =
106 {
107  "`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+",
108  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}",
109  "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|",
110  "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?"
111 };
112
113 /*** United States keyboard layout (phantom key version) */
114 /* (XFree86 reports the <> key even if it's not physically there) */
115 static const char main_key_US_phantom[MAIN_LEN][4] =
116 {
117  "`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+",
118  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}",
119  "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|",
120  "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?",
121  "<>" /* the phantom key */
122 };
123
124 /*** British keyboard layout */
125 static const char main_key_UK[MAIN_LEN][4] =
126 {
127  "`","1!","2\"","3£","4$","5%","6^","7&","8*","9(","0)","-_","=+",
128  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}",
129  "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'@","#~",
130  "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?",
131  "\\|"
132 };
133
134 /*** French keyboard layout (contributed by Eric Pouech) */
135 static const char main_key_FR[MAIN_LEN][4] =
136 {
137  "²","&1","é2~","\"3#","'4{","(5[","-6|","è7","_8\\","ç9^±","à0@",")°]","=+}",
138  "aA","zZ","eE","rR","tT","yY","uU","iI","oO","pP","^¨","$£¤",
139  "qQ","sSß","dD","fF","gG","hH","jJ","kK","lL","mM","ù%","*µ",
140  "wW","xX","cC","vV","bB","nN",",?",";.",":/","!§",
141  "<>"
142 };
143
144 /*** Icelandic keyboard layout (contributed by Ríkharður Egilsson) */
145 static const char main_key_IS[MAIN_LEN][4] =
146 {
147  "°","1!","2\"","3#","4$","5%","6&","7/{","8([","9)]","0=}","öÖ\\","-_",
148  "qQ@","wW","eE","rR","tT","yY","uU","iI","oO","pP","ðÐ","'?~",
149  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","æÆ","´^","+*`",
150  "zZ","xX","cC","vV","bB","nN","mM",",;",".:","þÞ",
151  "<>|"
152 };
153
154 /*** German keyboard layout (contributed by Ulrich Weigand) */
155 static const char main_key_DE[MAIN_LEN][4] =
156 {
157  "^°","1!","2\"²","3§³","4$","5%","6&","7/{","8([","9)]","0=}","ß?\\","'`",
158  "qQ@","wW","eE\80","rR","tT","zZ","uU","iI","oO","pP","üÜ","+*~",
159  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","öÖ","äÄ","#´",
160  "yY","xX","cC","vV","bB","nN","mMµ",",;",".:","-_",
161  "<>|"
162 };
163
164 /*** German keyboard layout without dead keys */
165 static const char main_key_DE_nodead[MAIN_LEN][4] =
166 {
167  "^°","1!","2\"","3§","4$","5%","6&","7/{","8([","9)]","0=}","ß?\\","´",
168  "qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","üÜ","+*~",
169  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","öÖ","äÄ","#'",
170  "yY","xX","cC","vV","bB","nN","mM",",;",".:","-_",
171  "<>"
172 };
173
174 /*** Swiss German keyboard layout (contributed by Jonathan Naylor) */
175 static const char main_key_SG[MAIN_LEN][4] =
176 {
177  "§°","1+|","2\"@","3*#","4ç","5%","6&¬","7/¦","8(¢","9)","0=","'?´","^`~",
178  "qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","üè[","¨!]",
179  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","öé","äà{","$£}",
180  "yY","xX","cC","vV","bB","nN","mM",",;",".:","-_",
181  "<>\\"
182 };
183
184 /*** Swiss French keyboard layout (contributed by Philippe Froidevaux) */
185 static const char main_key_SF[MAIN_LEN][4] =
186 {
187  "§°","1+|","2\"@","3*#","4ç","5%","6&¬","7/¦","8(¢","9)","0=","'?´","^`~",
188  "qQ","wW","eE","rR","tT","zZ","uU","iI","oO","pP","èü[","¨!]",
189  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","éö","àä{","$£}",
190  "yY","xX","cC","vV","bB","nN","mM",",;",".:","-_",
191  "<>\\"
192 };
193
194 /*** Norwegian keyboard layout (contributed by Ove Kåven) */
195 static const char main_key_NO[MAIN_LEN][4] =
196 {
197  "|§","1!","2\"@","3#£","4¤$","5%","6&","7/{","8([","9)]","0=}","+?","\\`´",
198  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","åÅ","¨^~",
199  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","øØ","æÆ","'*",
200  "zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
201  "<>"
202 };
203
204 /*** Danish keyboard layout (contributed by Bertho Stultiens) */
205 static const char main_key_DA[MAIN_LEN][4] =
206 {
207  "½§","1!","2\"@","3#£","4¤$","5%","6&","7/{","8([","9)]","0=}","+?","´`|",
208  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","åÅ","¨^~",
209  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","æÆ","øØ","'*",
210  "zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
211  "<>\\"
212 };
213
214 /*** Swedish keyboard layout (contributed by Peter Bortas) */
215 static const char main_key_SE[MAIN_LEN][4] =
216 {
217  "§½","1!","2\"@","3#£","4¤$","5%","6&","7/{","8([","9)]","0=}","+?\\","´`",
218  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","åÅ","¨^~",
219  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","öÖ","äÄ","'*",
220  "zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
221  "<>|"
222 };
223
224 /*** Canadian French keyboard layout */
225 static const char main_key_CF[MAIN_LEN][4] =
226 {
227  "#|\\","1!±","2\"@","3/£","4$¢","5%¤","6?¬","7&¦","8*²","9(³","0)¼","-_½","=+¾",
228  "qQ","wW","eE","rR","tT","yY","uU","iI","oO§","pP¶","^^[","¸¨]",
229  "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:~","``{","<>}",
230  "zZ","xX","cC","vV","bB","nN","mM",",'-",".","éÉ",
231  "«»°"
232 };
233
234 /*** Portuguese keyboard layout */
235 static const char main_key_PT[MAIN_LEN][4] =
236 {
237  "\\¦","1!","2\"@","3#£","4$§","5%","6&","7/{","8([","9)]","0=}","'?","«»",
238  "qQ",  "wW","eE",  "rR", "tT", "yY", "uU", "iI", "oO", "pP", "+*\\¨","\\'\\`",
239  "aA",  "sS","dD",  "fF", "gG", "hH", "jJ", "kK", "lL", "çÇ", "ºª", "\\~\\^",
240  "zZ",  "xX","cC",  "vV", "bB", "nN", "mM", ",;", ".:", "-_",
241  "<>"
242 };
243
244 /*** Italian keyboard layout */
245 static const char main_key_IT[MAIN_LEN][4] =
246 {
247  "\\|","1!¹","2\"²","3£³","4$¼","5%½","6&¾","7/{","8([","9)]","0=}","'?`","ì^~",
248  "qQ@","wW","eE","rR","tT","yY","uU","iI","oOø","pPþ","èé[","+*]",
249  "aA","sSß","dDð","fF","gG","hH","jJ","kK","lL","òç@","à°#","ù§",
250  "zZ","xX","cC","vV","bB","nN","mMµ",",;",".:·","-_",
251  "<>|"
252 };
253
254 /*** Finnish keyboard layout */
255 static const char main_key_FI[MAIN_LEN][4] =
256 {
257  "","1!","2\"@","3#","4$","5%","6&","7/{","8([","9)]","0=}","+?\\","\'`",
258  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","","\"^~",
259  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","","","'*",
260  "zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
261  "<>|"
262 };
263
264 /*** Russian keyboard layout (contributed by Pavel Roskin) */
265 static const char main_key_RU[MAIN_LEN][4] =
266 {
267  "`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+",
268  "qQÊê","wWÃã","eEÕõ","rRËë","tTÅå","yYÎî","uUÇç","iIÛû","oOÝý","pPÚú","[{Èè","]}ßÿ",
269  "aAÆæ","sSÙù","dD×÷","fFÁá","gGÐð","hHÒò","jJÏï","kKÌì","lLÄä",";:Öö","'\"Üü","\\|",
270  "zZÑñ","xXÞþ","cCÓó","vVÍí","bBÉé","nNÔô","mMØø",",<Ââ",".>Àà","/?"
271 };
272
273 /*** Russian keyboard layout (phantom key version) */
274 static const char main_key_RU_phantom[MAIN_LEN][4] =
275 {
276  "`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+",
277  "qQÊê","wWÃã","eEÕõ","rRËë","tTÅå","yYÎî","uUÇç","iIÛû","oOÝý","pPÚú","[{Èè","]}ßÿ",
278  "aAÆæ","sSÙù","dD×÷","fFÁá","gGÐð","hHÒò","jJÏï","kKÌì","lLÄä",";:Öö","'\"Üü","\\|",
279  "zZÑñ","xXÞþ","cCÓó","vVÍí","bBÉé","nNÔô","mMØø",",<Ââ",".>Àà","/?",
280  "<>" /* the phantom key */
281 };
282
283 /*** Russian keyboard layout KOI8-R */
284 static const char main_key_RU_koi8r[MAIN_LEN][4] =
285 {
286  "()","1!","2\"","3/","4$","5:","6,","7.","8;","9?","0%","-_","=+",
287  "Êê","Ãã","Õõ","Ëë","Åå","Îî","Çç","Ûû","Ýý","Úú","Èè","ßÿ",
288  "Ææ","Ùù","×÷","Áá","Ðð","Òò","Ïï","Ìì","Ää","Öö","Üü","\\|",
289  "Ññ","Þþ","Óó","Íí","Éé","Ôô","Øø","Ââ","Àà","/?",
290  "<>" /* the phantom key */
291 };
292
293 /*** Ukrainian keyboard layout KOI8-U */
294 static const char main_key_UA[MAIN_LEN][4] =
295 {
296  "`~­½","1!1!","2@2\"","3#3'","4$4*","5%5:","6^6,","7&7.","8*8;","9(9(","0)0)","-_-_","=+=+",
297  "qQÊê","wWÃã","eEÕõ","rRËë","tTÅå","yYÎî","uUÇç","iIÛû","oOÝý","pPÚú","[{Èè","]}§·",
298  "aAÆæ","sS¦¶","dD×÷","fFÁá","gGÐð","hHÒò","jJÏï","kKÌì","lLÄä",";:Öö","'\"¤´","\\|\\|",
299  "zZÑñ","xXÞþ","cCÓó","vVÍí","bBÉé","nNÔô","mMØø",",<Ââ",".>Àà","/?/?",
300  "<>" /* the phantom key */
301 };
302
303 /*** Spanish keyboard layout (contributed by José Marcos López) */
304 static const char main_key_ES[MAIN_LEN][4] =
305 {
306  "ºª\\","1!|","2\"@","3·#","4$","5%","6&¬","7/","8(","9)","0=","'?","¡¿",
307  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","`^[","+*]",
308  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","ñÑ","'¨{","çÇ}",
309  "zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
310  "<>"
311 };
312
313 /*** Belgian keyboard layout ***/
314 static const char main_key_BE[MAIN_LEN][4] =
315 {
316  "","&1|","é2@","\"3#","'4","(5","§6^","è7","!8","ç9{","à0}",")°","-_",
317  "aA","zZ","eE¤","rR","tT","yY","uU","iI","oO","pP","^¨[","$*]",
318  "qQ","sSß","dD","fF","gG","hH","jJ","kK","lL","mM","ù%´","µ£`",
319  "wW","xX","cC","vV","bB","nN",",?",";.",":/","=+~",
320  "<>\\"
321 };
322
323 /*** Hungarian keyboard layout (contributed by Zoltán Kovács) */
324 static const char main_key_HU[MAIN_LEN][4] =
325 {
326  "0§","1'~","2\"·","3+^","4!¢","5%°","6/²","7=`","8(ÿ","9)´","öÖ½","üܨ","óÓ¸",
327  "qQ\\","wW|","eE","rR","tT","zZ","uU","iIÍ","oOø","pP","õÕ÷","úÚ×",
328  "aA","sSð","dDÐ","fF[","gG]","hH","jJí","kK³","lL£","éÉ$","áÁß","ûÛ¤",
329  "yY>","xX#","cC&","vV@","bB{","nN}","mM",",?;",".:·","-_*",
330  "íÍ<"
331 };
332
333 /*** Polish (programmer's) keyboard layout ***/
334 static const char main_key_PL[MAIN_LEN][4] =
335 {
336  "`~","1!","2@","3#","4$","5%","6^","7&§","8*","9(","0)","-_","=+",
337  "qQ","wW","eEêÊ","rR","tT","yY","uU","iI","oOóÓ","pP","[{","]}",
338  "aA±¡","sS¶¦","dD","fF","gG","hH","jJ","kK","lL³£",";:","'\"","\\|",
339  "zZ¿¯","xX¼¬","cCæÆ","vV","bB","nNñÑ","mM",",<",".>","/?",
340  "<>|"
341 };
342
343 /*** Croatian keyboard layout specific for me <jelly@srk.fer.hr> ***/
344 static const char main_key_HR_jelly[MAIN_LEN][4] =
345 {
346  "`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+",
347  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{¹©","]}ðÐ",
348  "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:èÈ","'\"æÆ","\\|¾®",
349  "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?",
350  "<>|"
351 };
352
353 /*** Croatian keyboard layout ***/
354 static const char main_key_HR[MAIN_LEN][4] =
355 {
356  "¸¨","1!","2\"·","3#^","4$¢","5%°","6&²","7/`","8(ÿ","9)´","0=½","'?¨","+*¸",
357  "qQ\\","wW|","eE","rR","tT","zZ","uU","iI","oO","pP","¹©÷","ðÐ×",
358  "aA","sS","dD","fF[","gG]","hH","jJ","kK³","lL£","èÈ","æÆß","¾®¤",
359  "yY","xX","cC","vV@","bB{","nN}","mM§",",;",".:","-_/",
360  "<>"
361 };
362
363 /*** Japanese 106 keyboard layout ***/
364 static const char main_key_JA_jp106[MAIN_LEN][4] =
365 {
366  "1!","2\"","3#","4$","5%","6&","7'","8(","9)","0~","-=","^~","\\|",
367  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","@`","[{",
368  "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";+",":*","]}",
369  "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?",
370  "\\_",
371 };
372
373 /*** Japanese pc98x1 keyboard layout ***/
374 static const char main_key_JA_pc98x1[MAIN_LEN][4] =
375 {
376  "1!","2\"","3#","4$","5%","6&","7'","8(","9)","0","-=","^`","\\|",
377  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","@~","[{",
378  "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";+",":*","]}",
379  "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?",
380  "\\_",
381 };
382
383 /*** Brazilian ABNT-2 keyboard layout (contributed by Raul Gomes Fernandes) */
384 static const char main_key_PT_br[MAIN_LEN][4] =
385 {
386  "'\"","1!","2@","3#","4$","5%","6\"","7&","8*","9(","0)","-_","=+",
387  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","'`","[{",
388  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","çÇ","~^","]}",
389  "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?"
390 };
391
392 /*** US international keyboard layout (contributed by Gustavo Noronha (kov@debian.org)) */
393 static const char main_key_US_intl[MAIN_LEN][4] =
394 {
395   "`~", "1!", "2@", "3#", "4$", "5%", "6^", "7&", "8*", "9(", "0)", "-_", "=+", "\\|",
396   "qQ", "wW", "eE", "rR", "tT", "yY", "uU", "iI", "oO", "pP", "[{", "]}",
397   "aA", "sS", "dD", "fF", "gG", "hH", "jJ", "kK", "lL", ";:", "'\"",
398   "zZ", "xX", "cC", "vV", "bB", "nN", "mM", ",<", ".>", "/?"
399 };
400
401 /*** Slovak keyboard layout (see cssk_ibm(sk_qwerty) in xkbsel)
402   - dead_abovering replaced with degree - no symbol in iso8859-2
403   - brokenbar replaced with bar                                 */
404 static const char main_key_SK[MAIN_LEN][4] =
405 {
406  ";°`'","+1","µ2","¹3","è4","»5","¾6","ý7","á8","í9","é0)","=%","",
407  "qQ\\","wW|","eE","rR","tT","yY","uU","iI","oO","pP","ú/÷","ä(×",
408  "aA","sSð","dDÐ","fF[","gG]","hH","jJ","kK³","lL£","ô\"$","§!ß","ò)¤",
409  "zZ>","xX#","cC&","vV@","bB{","nN}","mM",",?<",".:>","-_*",
410  "<>\\|"
411 };
412
413 /*** Slovak and Czech (programmer's) keyboard layout (see cssk_dual(cs_sk_ucw)) */
414 static const char main_key_SK_prog[MAIN_LEN][4] =
415 {
416  "`~","1!","2@","3#","4$","5%","6^","7&","8*","9(","0)","-_","=+",
417  "qQäÄ","wWìÌ","eEéÉ","rRøØ","tT»«","yYýÝ","uUùÙ","iIíÍ","oOóÓ","pPöÖ","[{","]}",
418  "aAáÁ","sS¹©","dDïÏ","fFëË","gGàÀ","hHúÚ","jJüÜ","kKôÔ","lLµ¥",";:","'\"","\\|",
419  "zZ¾®","xX¤","cCèÈ","vVçÇ","bB","nNòÒ","mMåÅ",",<",".>","/?",
420  "<>"
421 };
422
423 /*** Czech keyboard layout (see cssk_ibm(cs_qwerty) in xkbsel) */
424 static const char main_key_CS[MAIN_LEN][4] =
425 {
426  ";","+1","ì2","¹3","è4","ø5","¾6","ý7","á8","í9","é0½)","=%","",
427  "qQ\\","wW|","eE","rR","tT","yY","uU","iI","oO","pP","ú/[{",")(]}",
428  "aA","sSð","dDÐ","fF[","gG]","hH","jJ","kK³","lL£","ù\"$","§!ß","¨'",
429  "zZ>","xX#","cC&","vV@","bB{","nN}","mM",",?<",".:>","-_*",
430  "<>\\|"
431 };
432
433 /*** Latin American keyboard layout (contributed by Gabriel Orlando Garcia) */
434 static const char main_key_LA[MAIN_LEN][4] =
435 {
436  "|°¬","1!","2\"","3#","4$","5%","6&","7/","8(","9)","0=","'?\\","¡¿",
437  "qQ@","wW","eE","rR","tT","yY","uU","iI","oO","pP","´¨","+*~",
438  "aA","sS","dD","fF","gG","hH","jJ","kK","lL","ñÑ","{[^","}]`",
439  "zZ","xX","cC","vV","bB","nN","mM",",;",".:","-_",
440  "<>"
441 };
442
443 /*** Lithuanian (Baltic) keyboard layout (contributed by Nerijus Baliûnas) */
444 static const char main_key_LT_B[MAIN_LEN][4] =
445 {
446  "`~","àÀ","èÈ","æÆ","ëË","áÁ","ðÐ","øØ","ûÛ","((","))","-_","þÞ",
447  "qQ","wW","eE","rR","tT","yY","uU","iI","oO","pP","[{","]}",
448  "aA","sS","dD","fF","gG","hH","jJ","kK","lL",";:","'\"","\\|",
449  "zZ","xX","cC","vV","bB","nN","mM",",<",".>","/?"
450 };
451
452 /*** Turkish keyboard Layout */
453 static const char main_key_TK[MAIN_LEN][4] =
454 {
455 "\"é","1!","2'","3^#","4+$","5%","6&","7/{","8([","9)]","0=}","*?\\","-_",
456 "qQ@","wW","eE","rR","tT","yY","uU","ýIî","oO","pP","ðÐ","üÜ~",
457 "aAæ","sSß","dD","fF","gG","hH","jJ","kK","lL","þÞ","iÝ",",;`",
458 "zZ","xX","cC","vV","bB","nN","mM","öÖ","çÇ",".:"
459 };
460
461 /*** Layout table. Add your keyboard mappings to this list */
462 static const struct {
463     const char *comment;
464     const UINT layout_cp; /* Code page for this layout */
465     const char (*key)[MAIN_LEN][4];
466     const WORD (*scan)[MAIN_LEN]; /* scan codes mapping */
467     const WORD (*vkey)[MAIN_LEN]; /* virtual key codes mapping */
468 } main_key_tab[]={
469  {"United States keyboard layout", 28591, &main_key_US, &main_key_scan_qwerty, &main_key_vkey_qwerty},
470  {"United States keyboard layout (phantom key version)", 28591, &main_key_US_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty},
471  {"British keyboard layout", 28591, &main_key_UK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
472  {"German keyboard layout", 28591, &main_key_DE, &main_key_scan_qwerty, &main_key_vkey_qwerty},
473  {"German keyboard layout without dead keys", 28591, &main_key_DE_nodead, &main_key_scan_qwerty, &main_key_vkey_qwerty},
474  {"Swiss German keyboard layout", 28591, &main_key_SG, &main_key_scan_qwerty, &main_key_vkey_qwerty},
475  {"Swedish keyboard layout", 28591, &main_key_SE, &main_key_scan_qwerty, &main_key_vkey_qwerty},
476  {"Norwegian keyboard layout", 28591, &main_key_NO, &main_key_scan_qwerty, &main_key_vkey_qwerty},
477  {"Danish keyboard layout", 28591, &main_key_DA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
478  {"French keyboard layout", 28591, &main_key_FR, &main_key_scan_qwerty, &main_key_vkey_azerty},
479  {"Canadian French keyboard layout", 28591, &main_key_CF, &main_key_scan_qwerty, &main_key_vkey_qwerty},
480  {"Belgian keyboard layout", 28591, &main_key_BE, &main_key_scan_qwerty, &main_key_vkey_azerty},
481  {"Swiss French keyboard layout", 28591, &main_key_SF, &main_key_scan_qwerty, &main_key_vkey_qwerty},
482  {"Portuguese keyboard layout", 28591, &main_key_PT, &main_key_scan_qwerty, &main_key_vkey_qwerty},
483  {"Brazilian ABNT-2 keyboard layout", 28591, &main_key_PT_br, &main_key_scan_qwerty, &main_key_vkey_qwerty},
484  {"United States International keyboard layout", 28591, &main_key_US_intl, &main_key_scan_qwerty, &main_key_vkey_qwerty},
485  {"Finnish keyboard layout", 28591, &main_key_FI, &main_key_scan_qwerty, &main_key_vkey_qwerty},
486  {"Russian keyboard layout", 20866, &main_key_RU, &main_key_scan_qwerty, &main_key_vkey_qwerty},
487  {"Russian keyboard layout (phantom key version)", 20866, &main_key_RU_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty},
488  {"Russian keyboard layout KOI8-R", 20866, &main_key_RU_koi8r, &main_key_scan_qwerty, &main_key_vkey_qwerty},
489  {"Ukrainian keyboard layout KOI8-U", 20866, &main_key_UA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
490  {"Spanish keyboard layout", 28591, &main_key_ES, &main_key_scan_qwerty, &main_key_vkey_qwerty},
491  {"Italian keyboard layout", 28591, &main_key_IT, &main_key_scan_qwerty, &main_key_vkey_qwerty},
492  {"Icelandic keyboard layout", 28591, &main_key_IS, &main_key_scan_qwerty, &main_key_vkey_qwerty},
493  {"Hungarian keyboard layout", 28592, &main_key_HU, &main_key_scan_qwerty, &main_key_vkey_qwerty},
494  {"Polish (programmer's) keyboard layout", 28592, &main_key_PL, &main_key_scan_qwerty, &main_key_vkey_qwerty},
495  {"Croatian keyboard layout", 28592, &main_key_HR, &main_key_scan_qwerty, &main_key_vkey_qwerty},
496  {"Croatian keyboard layout (specific)", 28592, &main_key_HR_jelly, &main_key_scan_qwerty, &main_key_vkey_qwerty},
497  {"Japanese 106 keyboard layout", 932, &main_key_JA_jp106, &main_key_scan_qwerty, &main_key_vkey_qwerty},
498  {"Japanese pc98x1 keyboard layout", 932, &main_key_JA_pc98x1, &main_key_scan_qwerty, &main_key_vkey_qwerty},
499  {"Slovak keyboard layout", 28592, &main_key_SK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
500  {"Slovak and Czech keyboard layout without dead keys", 28592, &main_key_SK_prog, &main_key_scan_qwerty, &main_key_vkey_qwerty},
501  {"Czech keyboard layout", 28592, &main_key_CS, &main_key_scan_qwerty, &main_key_vkey_qwerty},
502  {"Latin American keyboard layout", 28591, &main_key_LA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
503  {"Lithuanian (Baltic) keyboard layout", 28603, &main_key_LT_B, &main_key_scan_qwerty, &main_key_vkey_qwerty},
504  {"Turkish keyboard layout", 28599, &main_key_TK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
505
506  {NULL, 0, NULL, NULL, NULL} /* sentinel */
507 };
508 static unsigned kbd_layout=0; /* index into above table of layouts */
509
510 /* maybe more of these scancodes should be extended? */
511                 /* extended must be set for ALT_R, CTRL_R,
512                    INS, DEL, HOME, END, PAGE_UP, PAGE_DOWN, ARROW keys,
513                    keypad / and keypad ENTER (SDK 3.1 Vol.3 p 138) */
514                 /* FIXME should we set extended bit for NumLock ? My
515                  * Windows does ... DF */
516                 /* Yes, to distinguish based on scan codes, also
517                    for PrtScn key ... GA */
518
519 static const WORD special_key_vkey[] =
520 {
521     VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0,           /* FF08 */
522     0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0,                      /* FF10 */
523     0, 0, 0, VK_ESCAPE                                          /* FF18 */
524 };
525 static const WORD special_key_scan[] =
526 {
527     0x0E, 0x0F, 0, /*?*/ 0, 0, 0x1C, 0, 0,                      /* FF08 */
528     0,    0,    0, 0x45, 0x46, 0   , 0, 0,                      /* FF10 */
529     0,    0,    0, 0x01                                         /* FF18 */
530 };
531
532 static const WORD cursor_key_vkey[] =
533 {
534     VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR, 
535                                        VK_NEXT, VK_END          /* FF50 */
536 };
537 static const WORD cursor_key_scan[] =
538 {
539     0x147, 0x14B, 0x148, 0x14D, 0x150, 0x149, 0x151, 0x14F      /* FF50 */
540 };
541
542 static const WORD misc_key_vkey[] =
543 {
544     VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0,  /* FF60 */
545     VK_CANCEL, VK_HELP, VK_CANCEL, VK_CANCEL                    /* FF68 */
546 };
547 static const WORD misc_key_scan[] =
548 {
549     /*?*/ 0, 0x137, /*?*/ 0, 0x152, 0, 0, 0, 0,                 /* FF60 */
550     /*?*/ 0, /*?*/ 0, 0x38, 0x146                               /* FF68 */
551 };
552
553 static const WORD keypad_key_vkey[] =
554 {
555     0, VK_NUMLOCK,                                              /* FF7E */
556     0, 0, 0, 0, 0, 0, 0, 0,                                     /* FF80 */
557     0, 0, 0, 0, 0, VK_RETURN, 0, 0,                             /* FF88 */
558     0, 0, 0, 0, 0, VK_HOME, VK_LEFT, VK_UP,                     /* FF90 */
559     VK_RIGHT, VK_DOWN, VK_PRIOR, VK_NEXT, VK_END, 0,
560                                  VK_INSERT, VK_DELETE,          /* FF98 */
561     0, 0, 0, 0, 0, 0, 0, 0,                                     /* FFA0 */
562     0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT, 
563                                VK_DECIMAL, VK_DIVIDE,           /* FFA8 */
564     VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4,
565                             VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */
566     VK_NUMPAD8, VK_NUMPAD9                                      /* FFB8 */
567 };
568 static const WORD keypad_key_scan[] =
569 {
570     0x138, 0x145,                                               /* FF7E */
571     0, 0, 0, 0, 0, 0, 0, 0,                                     /* FF80 */
572     0, 0, 0, 0, 0, 0x11C, 0, 0,                                 /* FF88 */
573     0, 0, 0, 0, 0, 0x47, 0x4B, 0x48,                            /* FF90 */
574     0x4D, 0x50, 0x49, 0x51, 0x4F, 0x4C, 0x52, 0x53,             /* FF98 */
575     0, 0, 0, 0, 0, 0, 0, 0,                                     /* FFA0 */
576     0, 0, 0x37, 0x4E, /*?*/ 0, 0x4A, 0x53, 0x135,               /* FFA8 */
577     0x52, 0x4F, 0x50, 0x51, 0x4B, 0x4C, 0x4D, 0x47,             /* FFB0 */
578     0x48, 0x49                                                  /* FFB8 */
579 };
580     
581 static const WORD function_key_vkey[] =
582 {
583     VK_F1, VK_F2,                                               /* FFBE */
584     VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10,    /* FFC0 */
585     VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16              /* FFC8 */
586 };
587 static const WORD function_key_scan[] =
588 {
589     0x3B, 0x3C,                                                 /* FFBE */
590     0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44,             /* FFC0 */
591     0x57, 0x58, 0, 0, 0, 0                                      /* FFC8 */
592 };
593
594 static const WORD modifier_key_vkey[] =
595 {
596     VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL, 0, /* FFE1 */
597     VK_MENU, VK_MENU, VK_MENU, VK_MENU                         /* FFE7 */
598 };
599 static const WORD modifier_key_scan[] =
600 {
601     0x2A, 0x36, 0x1D, 0x11D, 0x3A, 0,                          /* FFE1 */
602     0x38, 0x138, 0x38, 0x138                                   /* FFE7 */
603 };
604
605 /* Returns the Windows virtual key code associated with the X event <e> */
606 static WORD EVENT_event_to_vkey( XKeyEvent *e)
607 {
608     KeySym keysym;
609
610     TSXLookupString(e, NULL, 0, &keysym, NULL);
611
612     if ((keysym >= 0xFFAE) && (keysym <= 0xFFB9) && (keysym != 0xFFAF) 
613         && (e->state & NumLockMask)) 
614         /* Only the Keypad keys 0-9 and . send different keysyms
615          * depending on the NumLock state */
616         return keypad_key_vkey[(keysym & 0xFF) - 0x7E];
617
618     return keyc2vkey[e->keycode];
619 }
620
621 static BOOL NumState=FALSE, CapsState=FALSE, AltGrState=FALSE;
622
623 /**********************************************************************
624  *              KEYBOARD_GenerateMsg
625  *
626  * Generate Down+Up messages when NumLock or CapsLock is pressed.
627  *
628  * Convention : called with vkey only VK_NUMLOCK or VK_CAPITAL
629  *
630  */
631 static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, INT event_x, INT event_y,
632                            DWORD event_time )
633 {
634   BOOL * State = (vkey==VK_NUMLOCK? &NumState : &CapsState);
635   DWORD up, down;
636
637   if (*State) {
638     /* The INTERMEDIARY state means : just after a 'press' event, if a 'release' event comes,
639        don't treat it. It's from the same key press. Then the state goes to ON.
640        And from there, a 'release' event will switch off the toggle key. */
641     *State=FALSE;
642     TRACE("INTERM : don\'t treat release of toggle key. InputKeyStateTable[%#x] = %#x\n",vkey,pKeyStateTable[vkey]);
643   } else
644     {
645         down = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0);
646         up = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0) | KEYEVENTF_KEYUP;
647         if ( pKeyStateTable[vkey] & 0x1 ) /* it was ON */
648           {
649             if (Evtype!=KeyPress)
650               {
651                 TRACE("ON + KeyRelease => generating DOWN and UP messages.\n");
652                 KEYBOARD_SendEvent( vkey, scan, down,
653                                     event_x, event_y, event_time );
654                 KEYBOARD_SendEvent( vkey, scan, up, 
655                                     event_x, event_y, event_time );
656                 *State=FALSE;
657                 pKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */ 
658               } 
659           }
660         else /* it was OFF */
661           if (Evtype==KeyPress)
662             {
663               TRACE("OFF + Keypress => generating DOWN and UP messages.\n");
664               KEYBOARD_SendEvent( vkey, scan, down,
665                                   event_x, event_y, event_time );
666               KEYBOARD_SendEvent( vkey, scan, up, 
667                                   event_x, event_y, event_time );
668               *State=TRUE; /* Goes to intermediary state before going to ON */
669               pKeyStateTable[vkey] |= 0x01; /* Toggle state to on. */
670             }
671     }
672 }
673
674 /***********************************************************************
675  *           KEYBOARD_UpdateOneState
676  *
677  * Updates internal state for <vkey>, depending on key <state> under X
678  *
679  */
680 static void KEYBOARD_UpdateOneState ( int vkey, int state )
681 {
682     /* Do something if internal table state != X state for keycode */
683     if (((pKeyStateTable[vkey] & 0x80)!=0) != state)
684     {
685         TRACE("Adjusting state for vkey %#.2x. State before %#.2x \n",
686               vkey, pKeyStateTable[vkey]);
687
688         /* Fake key being pressed inside wine */
689         KEYBOARD_SendEvent( vkey, 0, state? 0 : KEYEVENTF_KEYUP, 
690                             0, 0, GetTickCount() );
691
692         TRACE("State after %#.2x \n",pKeyStateTable[vkey]);
693     }
694 }
695
696 /***********************************************************************
697  *           X11DRV_KEYBOARD_UpdateState
698  *
699  * Update modifiers state (Ctrl, Alt, Shift)
700  * when window is activated (called by EVENT_FocusIn in event.c)
701  *
702  * This handles the case where one uses Ctrl+... Alt+... or Shift+.. to switch
703  * from wine to another application and back.
704  * Toggle keys are handled in HandleEvent. (because XQueryKeymap says nothing
705  *  about them)
706  */
707 void X11DRV_KEYBOARD_UpdateState ( void )
708 {
709 /* extract a bit from the char[32] bit suite */
710 #define KeyState(keycode) ((keys_return[keycode/8] & (1<<(keycode%8)))!=0)
711
712     char keys_return[32];
713
714     TRACE("called\n");
715     if (!TSXQueryKeymap(thread_display(), keys_return)) {
716         ERR("Error getting keymap !\n");
717         return;
718     }
719
720     /* Adjust the ALT and CONTROL state if any has been changed outside wine */
721     KEYBOARD_UpdateOneState(VK_MENU, KeyState(kcAlt));
722     KEYBOARD_UpdateOneState(VK_CONTROL, KeyState(kcControl));
723     KEYBOARD_UpdateOneState(VK_SHIFT, KeyState(kcShift));
724 #undef KeyState
725 }
726
727 /***********************************************************************
728  *           X11DRV_KEYBOARD_HandleEvent
729  *
730  * Handle a X key event
731  */
732 void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y )
733 {
734     char Str[24]; 
735     KeySym keysym;
736     WORD vkey = 0, bScan;
737     DWORD dwFlags;
738     static BOOL force_extended = FALSE; /* hack for AltGr translation */
739     int ascii_chars;
740
741     DWORD event_time = event->time - X11DRV_server_startticks;
742
743     /* this allows support for dead keys */
744     if ((event->keycode >> 8) == 0x10)
745         event->keycode=(event->keycode & 0xff);
746
747     ascii_chars = TSXLookupString(event, Str, sizeof(Str), &keysym, NULL);
748
749     TRACE_(key)("state = %X\n", event->state);
750
751     /* If XKB extensions is used, the state mask for AltGr will used the group
752        index instead of the modifier mask. The group index is set in bits
753        13-14 of the state field in the XKeyEvent structure. So if AltGr is
754        pressed, look if the group index is diferent than 0. From XKB
755        extension documentation, the group index should for AltGr should 
756        be 2 (event->state = 0x2000). It's probably better to not assume a
757        predefined group index and find it dynamically
758
759        Ref: X Keyboard Extension: Library specification (section 14.1.1 and 17.1.1) */
760     if ( AltGrState && (event->state & 0x6000) )
761         AltGrMask = event->state & 0x6000;
762
763     if (keysym == XK_Mode_switch)
764         {
765         TRACE_(key)("Alt Gr key event received\n");
766         event->keycode = kcControl; /* Simulate Control */
767         X11DRV_KEYBOARD_HandleEvent( event, x, y );
768
769         event->keycode = kcAlt; /* Simulate Alt */
770         force_extended = TRUE;
771         X11DRV_KEYBOARD_HandleEvent( event, x, y );
772         force_extended = FALSE;
773     
774     /* Here we save the pressed/released state of the AltGr key, to be able to 
775        identify the group index associated with AltGr on the next key pressed *
776        see comment above. */
777     AltGrState = (event->type == KeyPress) ? TRUE : FALSE;
778     
779         return;
780         }
781
782     Str[ascii_chars] = '\0';
783     if (TRACE_ON(key)){
784         char    *ksname;
785
786         ksname = TSXKeysymToString(keysym);
787         if (!ksname)
788           ksname = "No Name";
789         TRACE_(key)("%s : keysym=%lX (%s), ascii chars=%u / %X / '%s'\n", 
790                     (event->type == KeyPress) ? "KeyPress" : "KeyRelease",
791                     keysym, ksname, ascii_chars, Str[0] & 0xff, Str);
792     }
793
794     vkey = EVENT_event_to_vkey(event);
795     if (force_extended) vkey |= 0x100;
796
797     TRACE_(key)("keycode 0x%x converted to vkey 0x%x\n",
798                 event->keycode, vkey);
799
800    if (vkey)
801    {
802     switch (vkey & 0xff)
803     {
804     case VK_NUMLOCK:    
805       KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, x, y, event_time );
806       break;
807     case VK_CAPITAL:
808       TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,pKeyStateTable[vkey]);
809       KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, x, y, event_time );
810       TRACE("State after : %#.2x\n",pKeyStateTable[vkey]);
811       break;
812     default:
813         /* Adjust the NUMLOCK state if it has been changed outside wine */
814         if (!(pKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
815           { 
816             TRACE("Adjusting NumLock state. \n");
817             KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, x, y, event_time );
818             KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, x, y, event_time );
819           }
820         /* Adjust the CAPSLOCK state if it has been changed outside wine */
821         if (!(pKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
822           {
823               TRACE("Adjusting Caps Lock state.\n");
824             KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, x, y, event_time );
825             KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, x, y, event_time );
826           }
827         /* Not Num nor Caps : end of intermediary states for both. */
828         NumState = FALSE;
829         CapsState = FALSE;
830
831         bScan = keyc2scan[event->keycode] & 0xFF;
832         TRACE_(key)("bScan = 0x%02x.\n", bScan);
833
834         dwFlags = 0;
835         if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP;
836         if ( vkey & 0x100 )              dwFlags |= KEYEVENTF_EXTENDEDKEY;
837         if ( force_extended )            dwFlags |= KEYEVENTF_WINE_FORCEEXTENDED;
838
839         KEYBOARD_SendEvent( vkey & 0xff, bScan, dwFlags, x, y, event_time );
840     }
841    }
842 }
843
844 /**********************************************************************
845  *              X11DRV_KEYBOARD_DetectLayout
846  *
847  * Called from X11DRV_InitKeyboard
848  *  This routine walks through the defined keyboard layouts and selects
849  *  whichever matches most closely.
850  */
851 static void
852 X11DRV_KEYBOARD_DetectLayout (void)
853 {
854   Display *display = thread_display();
855   unsigned current, match, mismatch, seq;
856   int score, keyc, i, key, pkey, ok, syms;
857   KeySym keysym;
858   const char (*lkey)[MAIN_LEN][4];
859   unsigned max_seq = 0;
860   int max_score = 0, ismatch = 0;
861   char ckey[4] =
862   {0, 0, 0, 0};
863
864   syms = keysyms_per_keycode;
865   if (syms > 4) {
866     WARN("%d keysyms per keycode not supported, set to 4\n", syms);
867     syms = 4;
868   }
869   for (current = 0; main_key_tab[current].comment; current++) {
870     TRACE("Attempting to match against \"%s\"\n", main_key_tab[current].comment);
871     match = 0;
872     mismatch = 0;
873     score = 0;
874     seq = 0;
875     lkey = main_key_tab[current].key;
876     pkey = -1;
877     for (keyc = min_keycode; keyc <= max_keycode; keyc++) {
878       /* get data for keycode from X server */
879       for (i = 0; i < syms; i++) {
880         keysym = TSXKeycodeToKeysym (display, keyc, i);
881         /* Allow both one-byte and two-byte national keysyms */
882         if ((keysym < 0x800) && (keysym != ' '))
883           ckey[i] = keysym & 0xFF;
884         else {
885           ckey[i] = KEYBOARD_MapDeadKeysym(keysym);
886         }
887       }
888       if (ckey[0]) {
889         /* search for a match in layout table */
890         /* right now, we just find an absolute match for defined positions */
891         /* (undefined positions are ignored, so if it's defined as "3#" in */
892         /* the table, it's okay that the X server has "3#£", for example) */
893         /* however, the score will be higher for longer matches */
894         for (key = 0; key < MAIN_LEN; key++) {
895           for (ok = 0, i = 0; (ok >= 0) && (i < syms); i++) {
896             if ((*lkey)[key][i] && ((*lkey)[key][i] == ckey[i]))
897               ok++;
898             if ((*lkey)[key][i] && ((*lkey)[key][i] != ckey[i]))
899               ok = -1;
900           }
901           if (ok > 0) {
902             score += ok;
903             break;
904           }
905         }
906         /* count the matches and mismatches */
907         if (ok > 0) {
908           match++;
909           /* and how much the keycode order matches */
910           if (key > pkey) seq++;
911           pkey = key;
912         } else {
913           TRACE_(key)("mismatch for keycode %d, character %c\n", keyc,
914                  ckey[0]);
915           mismatch++;
916           score -= syms;
917         }
918       }
919     }
920     TRACE("matches=%d, mismatches=%d, score=%d\n",
921            match, mismatch, score);
922     if ((score > max_score) ||
923         ((score == max_score) && (seq > max_seq))) {
924       /* best match so far */
925       kbd_layout = current;
926       max_score = score;
927       max_seq = seq;
928       ismatch = !mismatch;
929     }
930   }
931   /* we're done, report results if necessary */
932   if (!ismatch) {
933     FIXME(
934            "Your keyboard layout was not found!\n"
935            "Using closest match instead (%s) for scancode mapping.\n"
936            "Please define your layout in windows/x11drv/keyboard.c and submit them\n"
937            "to us for inclusion into future Wine releases.\n"
938            "See the Wine User Guide, chapter \"Keyboard\" for more information.\n",
939            main_key_tab[kbd_layout].comment);
940   }
941
942   TRACE("detected layout is \"%s\"\n", main_key_tab[kbd_layout].comment);
943 }
944
945 /**********************************************************************
946  *              InitKeyboard (X11DRV.@)
947  */
948 void X11DRV_InitKeyboard(void)
949 {
950 #ifdef HAVE_XKB
951     int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion;
952 #endif
953     Display *display = thread_display();
954     KeySym *ksp;
955     XModifierKeymap *mmp;
956     KeySym keysym;
957     KeyCode *kcp;
958     XKeyEvent e2;
959     WORD scan, vkey, OEMvkey;
960     int keyc, i, keyn, syms;
961     char ckey[4]={0,0,0,0};
962     const char (*lkey)[MAIN_LEN][4];
963
964 #ifdef HAVE_XKB
965     wine_tsx11_lock();
966     is_xkb = XkbQueryExtension(display,
967                                &xkb_opcode, &xkb_event, &xkb_error,
968                                &xkb_major, &xkb_minor);
969     if (is_xkb) {
970         /* we have XKB, approximate Windows behaviour */
971         XkbSetDetectableAutoRepeat(display, True, NULL);
972     }
973     wine_tsx11_unlock();
974 #endif
975     TSXDisplayKeycodes(display, &min_keycode, &max_keycode);
976     ksp = TSXGetKeyboardMapping(display, min_keycode,
977                               max_keycode + 1 - min_keycode, &keysyms_per_keycode);
978     /* We are only interested in keysyms_per_keycode.
979        There is no need to hold a local copy of the keysyms table */
980     TSXFree(ksp);
981     mmp = TSXGetModifierMapping(display);
982     kcp = mmp->modifiermap;
983     for (i = 0; i < 8; i += 1) /* There are 8 modifier keys */
984     {
985         int j;
986         
987         for (j = 0; j < mmp->max_keypermod; j += 1, kcp += 1)
988             if (*kcp)
989             {
990                 int k;
991                 
992                 for (k = 0; k < keysyms_per_keycode; k += 1)
993                     if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Mode_switch)
994                     {
995                         AltGrMask = 1 << i;
996                         TRACE_(key)("AltGrMask is %x\n", AltGrMask);
997                     }
998                     else if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Num_Lock)
999                     {
1000                         NumLockMask = 1 << i;
1001                         TRACE_(key)("NumLockMask is %x\n", NumLockMask);
1002                     }
1003             }
1004     }
1005     TSXFreeModifiermap(mmp);
1006
1007     /* Detect the keyboard layout */
1008     X11DRV_KEYBOARD_DetectLayout();
1009     lkey = main_key_tab[kbd_layout].key;
1010     syms = (keysyms_per_keycode > 4) ? 4 : keysyms_per_keycode;
1011
1012     /* Now build two conversion arrays :
1013      * keycode -> vkey + scancode + extended
1014      * vkey + extended -> keycode */
1015
1016     e2.display = display;
1017     e2.state = 0;
1018
1019     OEMvkey = VK_OEM_7; /* next is available.  */
1020     for (keyc = min_keycode; keyc <= max_keycode; keyc++)
1021     {
1022         e2.keycode = (KeyCode)keyc;
1023         TSXLookupString(&e2, NULL, 0, &keysym, NULL);
1024         vkey = 0; scan = 0;
1025         if (keysym)  /* otherwise, keycode not used */
1026         {
1027             if ((keysym >> 8) == 0xFF)         /* non-character key */
1028             {
1029                 int key = keysym & 0xff;
1030                 
1031                 if (key >= 0x08 && key <= 0x1B) {        /* special key */
1032                     vkey = special_key_vkey[key - 0x08];
1033                     scan = special_key_scan[key - 0x08];
1034                 } else if (key >= 0x50 && key <= 0x57) { /* cursor key */
1035                     vkey = cursor_key_vkey[key - 0x50];
1036                     scan = cursor_key_scan[key - 0x50];
1037                 } else if (key >= 0x60 && key <= 0x6B) { /* miscellaneous key */
1038                     vkey = misc_key_vkey[key - 0x60];
1039                     scan = misc_key_scan[key - 0x60];
1040                 } else if (key >= 0x7E && key <= 0xB9) { /* keypad key */
1041                     vkey = keypad_key_vkey[key - 0x7E];
1042                     scan = keypad_key_scan[key - 0x7E];
1043                 } else if (key >= 0xBE && key <= 0xCD) { /* function key */
1044                     vkey = function_key_vkey[key - 0xBE] | 0x100; /* set extended bit */
1045                     scan = function_key_scan[key - 0xBE];
1046                 } else if (key >= 0xE1 && key <= 0xEA) { /* modifier key */
1047                     vkey = modifier_key_vkey[key - 0xE1];
1048                     scan = modifier_key_scan[key - 0xE1];
1049                 } else if (key == 0xFF) {                /* DEL key */
1050                     vkey = VK_DELETE;
1051                     scan = 0x153;
1052                 }
1053                 /* set extended bit when necessary */
1054                 if (scan & 0x100) vkey |= 0x100;
1055             } else if (keysym == 0x20) {                 /* Spacebar */
1056                 vkey = VK_SPACE;
1057                 scan = 0x39;
1058             } else {
1059               /* we seem to need to search the layout-dependent scancodes */
1060               int maxlen=0,maxval=-1,ok;
1061               for (i=0; i<syms; i++) {
1062                 keysym = TSXKeycodeToKeysym(display, keyc, i);
1063                 if ((keysym<0x800) && (keysym!=' ')) {
1064                   ckey[i] = keysym & 0xFF;
1065                 } else {
1066                   ckey[i] = KEYBOARD_MapDeadKeysym(keysym);
1067                 }
1068               }
1069               /* find key with longest match streak */
1070               for (keyn=0; keyn<MAIN_LEN; keyn++) {
1071                 for (ok=(*lkey)[keyn][i=0]; ok&&(i<4); i++)
1072                   if ((*lkey)[keyn][i] && (*lkey)[keyn][i]!=ckey[i]) ok=0;
1073                 if (ok||(i>maxlen)) {
1074                   maxlen=i; maxval=keyn;
1075                 }
1076                 if (ok) break;
1077               }
1078               if (maxval>=0) {
1079                 /* got it */
1080                 const WORD (*lscan)[MAIN_LEN] = main_key_tab[kbd_layout].scan;
1081                 const WORD (*lvkey)[MAIN_LEN] = main_key_tab[kbd_layout].vkey;
1082                 scan = (*lscan)[maxval];
1083                 vkey = (*lvkey)[maxval];
1084               }
1085             }
1086
1087             /* find a suitable layout-dependent VK code */
1088             /* (most Winelib apps ought to be able to work without layout tables!) */
1089             for (i = 0; (i < keysyms_per_keycode) && (!vkey); i++)
1090             {
1091                 keysym = TSXLookupKeysym(&e2, i);
1092                 if ((keysym >= VK_0 && keysym <= VK_9)
1093                     || (keysym >= VK_A && keysym <= VK_Z)) {
1094                     vkey = keysym;
1095                 }
1096             }
1097
1098             for (i = 0; (i < keysyms_per_keycode) && (!vkey); i++)
1099             {
1100                 keysym = TSXLookupKeysym(&e2, i);
1101                 switch (keysym)
1102                 {
1103                 case ';':             vkey = VK_OEM_1; break;
1104                 case '/':             vkey = VK_OEM_2; break;
1105                 case '`':             vkey = VK_OEM_3; break;
1106                 case '[':             vkey = VK_OEM_4; break;
1107                 case '\\':            vkey = VK_OEM_5; break;
1108                 case ']':             vkey = VK_OEM_6; break;
1109                 case '\'':            vkey = VK_OEM_7; break;
1110                 case ',':             vkey = VK_OEM_COMMA; break;
1111                 case '.':             vkey = VK_OEM_PERIOD; break;
1112                 case '-':             vkey = VK_OEM_MINUS; break;
1113                 case '+':             vkey = VK_OEM_PLUS; break;
1114                 }
1115             }
1116
1117             if (!vkey)
1118             {
1119                 /* Others keys: let's assign OEM virtual key codes in the allowed range,
1120                  * that is ([0xba,0xc0], [0xdb,0xe4], 0xe6 (given up) et [0xe9,0xf5]) */
1121                 switch (++OEMvkey)
1122                 {
1123                 case 0xc1 : OEMvkey=0xdb; break;
1124                 case 0xe5 : OEMvkey=0xe9; break;
1125                 case 0xf6 : OEMvkey=0xf5; WARN("No more OEM vkey available!\n");
1126                 }
1127
1128                 vkey = OEMvkey;
1129                   
1130                 if (TRACE_ON(keyboard))
1131                 {
1132                     TRACE("OEM specific virtual key %X assigned to keycode %X:\n",
1133                                      OEMvkey, e2.keycode);
1134                     TRACE("(");
1135                     for (i = 0; i < keysyms_per_keycode; i += 1)
1136                     {
1137                         char    *ksname;
1138                         
1139                         keysym = TSXLookupKeysym(&e2, i);
1140                         ksname = TSXKeysymToString(keysym);
1141                         if (!ksname)
1142                             ksname = "NoSymbol";
1143                         DPRINTF( "%lX (%s) ", keysym, ksname);
1144                     }
1145                     DPRINTF(")\n");
1146                 }
1147             }
1148         }
1149         keyc2vkey[e2.keycode] = vkey;
1150         keyc2scan[e2.keycode] = scan;
1151     } /* for */
1152
1153     /* If some keys still lack scancodes, assign some arbitrary ones to them now */
1154     for (scan = 0x60, keyc = min_keycode; keyc <= max_keycode; keyc++)
1155       if (keyc2vkey[keyc]&&!keyc2scan[keyc]) {
1156         char *ksname;
1157         keysym = TSXKeycodeToKeysym(display, keyc, 0);
1158         ksname = TSXKeysymToString(keysym);
1159         if (!ksname) ksname = "NoSymbol";
1160
1161         /* should make sure the scancode is unassigned here, but >=0x60 currently always is */
1162
1163         TRACE_(key)("assigning scancode %02x to unidentified keycode %02x (%s)\n",scan,keyc,ksname);
1164         keyc2scan[keyc]=scan++;
1165       }
1166
1167     /* Now store one keycode for each modifier. Used to simulate keypresses. */
1168     kcControl = TSXKeysymToKeycode(display, XK_Control_L);
1169     kcAlt = TSXKeysymToKeycode(display, XK_Alt_L);
1170     if (!kcAlt) kcAlt = TSXKeysymToKeycode(display, XK_Meta_L);
1171     kcShift = TSXKeysymToKeycode(display, XK_Shift_L);
1172     kcNumLock = TSXKeysymToKeycode(display, XK_Num_Lock);
1173     kcCapsLock = TSXKeysymToKeycode(display, XK_Caps_Lock);
1174 }
1175
1176 /***********************************************************************
1177  *              VkKeyScan (X11DRV.@)
1178  */
1179 WORD X11DRV_VkKeyScan(CHAR cChar)
1180 {
1181         Display *display = thread_display();
1182         KeyCode keycode;
1183         KeySym keysym;          
1184         int i,index;
1185         int highbyte=0;
1186
1187         /* char->keysym (same for ANSI chars) */
1188         keysym=(unsigned char) cChar;/* (!) cChar is signed */
1189         if (keysym<=27) keysym+=0xFF00;/*special chars : return, backspace...*/
1190         
1191         keycode = TSXKeysymToKeycode(display, keysym);  /* keysym -> keycode */
1192         if (!keycode)
1193         { /* It didn't work ... let's try with deadchar code. */
1194           keycode = TSXKeysymToKeycode(display, keysym | 0xFE00);
1195         }
1196
1197         TRACE("VkKeyScan '%c'(%#lx, %lu): got keycode %#.2x\n",
1198               cChar,keysym,keysym,keycode);
1199         
1200         if (keycode)
1201           {
1202             for (index=-1, i=0; (i<8) && (index<0); i++) /* find shift state */
1203               if (TSXKeycodeToKeysym(display,keycode,i)==keysym) index=i;
1204             switch (index) {
1205             case -1 :
1206               WARN("Keysym %lx not found while parsing the keycode table\n",keysym); break;
1207             case 0 : break;
1208             case 1 : highbyte = 0x0100; break;
1209             case 2 : highbyte = 0x0600; break;
1210             case 3 : highbyte = 0x0700; break;
1211             default : ERR("index %d found by XKeycodeToKeysym. please report! \n",index);
1212             }
1213             /*
1214               index : 0     adds 0x0000
1215               index : 1     adds 0x0100 (shift)
1216               index : ?     adds 0x0200 (ctrl)
1217               index : 2     adds 0x0600 (ctrl+alt)
1218               index : 3     adds 0x0700 (ctrl+alt+shift)
1219              */
1220           }
1221         TRACE(" ... returning %#.2x\n", keyc2vkey[keycode]+highbyte);
1222         return keyc2vkey[keycode]+highbyte;   /* keycode -> (keyc2vkey) vkey */
1223 }
1224
1225 /***********************************************************************
1226  *              MapVirtualKey (X11DRV.@)
1227  */
1228 UINT16 X11DRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType)
1229 {
1230     Display *display = thread_display();
1231
1232 #define returnMVK(value) { TRACE("returning 0x%x.\n",value); return value; }
1233
1234         TRACE("MapVirtualKey wCode=0x%x wMapType=%d ... \n", wCode,wMapType);
1235         switch(wMapType) {
1236                 case 0: { /* vkey-code to scan-code */
1237                         /* let's do vkey -> keycode -> scan */
1238                         int keyc;
1239                         for (keyc=min_keycode; keyc<=max_keycode; keyc++)
1240                                 if ((keyc2vkey[keyc] & 0xFF) == wCode)
1241                                         returnMVK (keyc2scan[keyc] & 0xFF);
1242                         TRACE("returning no scan-code.\n");
1243                         return 0; }
1244
1245                 case 1: { /* scan-code to vkey-code */
1246                         /* let's do scan -> keycode -> vkey */
1247                         int keyc;
1248                         for (keyc=min_keycode; keyc<=max_keycode; keyc++)
1249                                 if ((keyc2scan[keyc] & 0xFF) == (wCode & 0xFF))
1250                                         returnMVK (keyc2vkey[keyc] & 0xFF);
1251                         TRACE("returning no vkey-code.\n");
1252                         return 0; }
1253
1254                 case 2: { /* vkey-code to unshifted ANSI code */
1255                         /* (was FIXME) : what does unshifted mean ? 'a' or 'A' ? */
1256                         /* My Windows returns 'A'. */
1257                         /* let's do vkey -> keycode -> (XLookupString) ansi char */
1258                         XKeyEvent e;
1259                         KeySym keysym;
1260                         int keyc;
1261                         char s[2];
1262                         e.display = display;
1263                         e.state = 0; /* unshifted */
1264
1265                         e.keycode = 0;
1266                         /* We exit on the first keycode found, to speed up the thing. */
1267                         for (keyc=min_keycode; (keyc<=max_keycode) && (!e.keycode) ; keyc++)
1268                         { /* Find a keycode that could have generated this virtual key */
1269                             if  ((keyc2vkey[keyc] & 0xFF) == wCode)
1270                             { /* We filter the extended bit, we don't know it */
1271                                 e.keycode = keyc; /* Store it temporarily */
1272                                 if ((EVENT_event_to_vkey(&e) & 0xFF) != wCode) {
1273                                     e.keycode = 0; /* Wrong one (ex: because of the NumLock
1274                                          state), so set it to 0, we'll find another one */
1275                                 }
1276                             }
1277                         }
1278
1279                         if ((wCode>=VK_NUMPAD0) && (wCode<=VK_NUMPAD9))
1280                           e.keycode = TSXKeysymToKeycode(e.display, wCode-VK_NUMPAD0+XK_KP_0);
1281           
1282                         if (wCode==VK_DECIMAL)
1283                           e.keycode = TSXKeysymToKeycode(e.display, XK_KP_Decimal);
1284
1285                         if (!e.keycode)
1286                         {
1287                           WARN("Unknown virtual key %X !!! \n", wCode);
1288                           return 0; /* whatever */
1289                         }
1290                         TRACE("Found keycode %d (0x%2X)\n",e.keycode,e.keycode);
1291
1292                         if (TSXLookupString(&e, s, 2, &keysym, NULL))
1293                           returnMVK (*s);
1294                         
1295                         TRACE("returning no ANSI.\n");
1296                         return 0;
1297                         }
1298
1299                 case 3:   /* **NT only** scan-code to vkey-code but distinguish between  */
1300                           /*             left and right  */
1301                           FIXME(" stub for NT\n");
1302                           return 0;
1303
1304                 default: /* reserved */
1305                         WARN("Unknown wMapType %d !\n", wMapType);
1306                         return 0;       
1307         }
1308         return 0;
1309 }
1310
1311 /***********************************************************************
1312  *              GetKeyNameText (X11DRV.@)
1313  */
1314 INT16 X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT16 nSize)
1315 {
1316   int vkey, ansi, scanCode;
1317   KeyCode keyc;
1318   KeySym keys;
1319   char *name;
1320         
1321   scanCode = lParam >> 16;
1322   scanCode &= 0x1ff;  /* keep "extended-key" flag with code */
1323
1324   /* FIXME: should use MVK type 3 (NT version that distinguishes right and left */
1325   vkey = X11DRV_MapVirtualKey(scanCode, 1);
1326
1327   /*  handle "don't care" bit (0x02000000) */
1328   if (!(lParam & 0x02000000)) {
1329     switch (vkey) {
1330          case VK_LSHIFT:
1331          case VK_RSHIFT:
1332                           vkey = VK_SHIFT;
1333                           break;
1334        case VK_LCONTROL:
1335        case VK_RCONTROL:
1336                           vkey = VK_CONTROL;
1337                           break;
1338           case VK_LMENU:
1339           case VK_RMENU:
1340                           vkey = VK_MENU;
1341                           break;
1342                default:
1343                           break;
1344     }
1345   }
1346
1347   ansi = X11DRV_MapVirtualKey(vkey, 2);
1348   TRACE("scan 0x%04x, vkey 0x%04x, ANSI 0x%04x\n", scanCode, vkey, ansi);
1349
1350   /* first get the name of the "regular" keys which is the Upper case
1351      value of the keycap imprint.                                     */
1352   if ( ((ansi >= 0x21) && (ansi <= 0x7e)) &&
1353        (scanCode != 0x137) &&   /* PrtScn   */
1354        (scanCode != 0x135) &&   /* numpad / */
1355        (scanCode != 0x37 ) &&   /* numpad * */
1356        (scanCode != 0x4a ) &&   /* numpad - */
1357        (scanCode != 0x4e ) )    /* numpad + */
1358       {
1359         if ((nSize >= 2) && lpBuffer)
1360         {
1361         *lpBuffer = toupper((char)ansi);
1362           *(lpBuffer+1) = 0;
1363           return 1;
1364         } 
1365      else
1366         return 0;
1367   }
1368
1369   /* FIXME: horrible hack to fix function keys. Windows reports scancode
1370             without "extended-key" flag. However Wine generates scancode
1371             *with* "extended-key" flag. Seems to occur *only* for the
1372             function keys. Soooo.. We will leave the table alone and
1373             fudge the lookup here till the other part is found and fixed!!! */
1374
1375   if ( ((scanCode >= 0x13b) && (scanCode <= 0x144)) ||
1376        (scanCode == 0x157) || (scanCode == 0x158))
1377     scanCode &= 0xff;   /* remove "extended-key" flag for Fx keys */
1378
1379   /* let's do scancode -> keycode -> keysym -> String */
1380
1381   for (keyc=min_keycode; keyc<=max_keycode; keyc++)
1382       if ((keyc2scan[keyc]) == scanCode)
1383          break;
1384   if (keyc <= max_keycode)
1385   {
1386       keys = TSXKeycodeToKeysym(thread_display(), keyc, 0);
1387       name = TSXKeysymToString(keys);
1388       TRACE("found scan=%04x keyc=%04x keysym=%04x string=%s\n",
1389             scanCode, keyc, (int)keys, name);
1390       if (lpBuffer && nSize && name)
1391       {
1392           lstrcpynA(lpBuffer, name, nSize);
1393           return 1;
1394       }
1395   }
1396
1397   /* Finally issue FIXME for unknown keys   */
1398
1399   FIXME("(%08lx,%p,%d): unsupported key, vkey=%04x, ansi=%04x\n",lParam,lpBuffer,nSize,vkey,ansi);
1400   if (lpBuffer && nSize)
1401     *lpBuffer = 0;
1402   return 0;
1403 }
1404
1405 /***********************************************************************
1406  *              X11DRV_KEYBOARD_MapDeadKeysym
1407  */
1408 static char KEYBOARD_MapDeadKeysym(KeySym keysym)
1409 {
1410         switch (keysym)
1411             {
1412         /* symbolic ASCII is the same as defined in rfc1345 */
1413 #ifdef XK_dead_tilde
1414             case XK_dead_tilde :
1415 #endif
1416             case 0x1000FE7E : /* Xfree's XK_Dtilde */
1417                 return '~';     /* '? */
1418 #ifdef XK_dead_acute
1419             case XK_dead_acute :
1420 #endif
1421             case 0x1000FE27 : /* Xfree's XK_Dacute_accent */
1422                 return 0xb4;    /* '' */
1423 #ifdef XK_dead_circumflex
1424             case XK_dead_circumflex:
1425 #endif
1426             case 0x1000FE5E : /* Xfree's XK_Dcircumflex_accent */
1427                 return '^';     /* '> */
1428 #ifdef XK_dead_grave
1429             case XK_dead_grave :
1430 #endif
1431             case 0x1000FE60 : /* Xfree's XK_Dgrave_accent */
1432                 return '`';     /* '! */
1433 #ifdef XK_dead_diaeresis
1434             case XK_dead_diaeresis :
1435 #endif
1436             case 0x1000FE22 : /* Xfree's XK_Ddiaeresis */
1437                 return 0xa8;    /* ': */
1438 #ifdef XK_dead_cedilla
1439             case XK_dead_cedilla :
1440                 return 0xb8;    /* ', */
1441 #endif
1442 #ifdef XK_dead_macron
1443             case XK_dead_macron :
1444                 return '-';     /* 'm isn't defined on iso-8859-x */
1445 #endif
1446 #ifdef XK_dead_breve
1447             case XK_dead_breve :
1448                 return 0xa2;    /* '( */
1449 #endif
1450 #ifdef XK_dead_abovedot
1451             case XK_dead_abovedot :
1452                 return 0xff;    /* '. */
1453 #endif
1454 #ifdef XK_dead_abovering
1455             case XK_dead_abovering :
1456                 return '0';     /* '0 isn't defined on iso-8859-x */
1457 #endif
1458 #ifdef XK_dead_doubleacute
1459             case XK_dead_doubleacute :
1460                 return 0xbd;    /* '" */
1461 #endif
1462 #ifdef XK_dead_caron
1463             case XK_dead_caron :
1464                 return 0xb7;    /* '< */
1465 #endif
1466 #ifdef XK_dead_ogonek
1467             case XK_dead_ogonek :
1468                 return 0xb2;    /* '; */
1469 #endif
1470 /* FIXME: I don't know this three.
1471             case XK_dead_iota :
1472                 return 'i';      
1473             case XK_dead_voiced_sound :
1474                 return 'v';
1475             case XK_dead_semivoiced_sound :
1476                 return 's';
1477 */
1478             }
1479         TRACE("no character for dead keysym 0x%08lx\n",keysym);
1480         return 0;
1481 }
1482
1483 /***********************************************************************
1484  *              ToUnicode (X11DRV.@)
1485  *
1486  * The ToUnicode function translates the specified virtual-key code and keyboard
1487  * state to the corresponding Windows character or characters.
1488  *
1489  * If the specified key is a dead key, the return value is negative. Otherwise,
1490  * it is one of the following values:
1491  * Value        Meaning
1492  * 0    The specified virtual key has no translation for the current state of the keyboard.
1493  * 1    One Windows character was copied to the buffer.
1494  * 2    Two characters were copied to the buffer. This usually happens when a
1495  *      dead-key character (accent or diacritic) stored in the keyboard layout cannot
1496  *      be composed with the specified virtual key to form a single character.
1497  *
1498  * FIXME : should do the above (return 2 for non matching deadchar+char combinations)
1499  *
1500  */
1501 INT X11DRV_ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
1502                      LPWSTR bufW, int bufW_size, UINT flags)
1503 {
1504     Display *display = thread_display();
1505     XKeyEvent e;
1506     KeySym keysym;
1507     INT ret;
1508     int keyc;
1509     BYTE lpChar[2];
1510
1511     if (scanCode==0) {
1512         /* This happens when doing Alt+letter : a fake 'down arrow' key press
1513            event is generated by windows. Just ignore it. */
1514         TRACE("scanCode=0, doing nothing\n");
1515         return 0;
1516     }
1517     if (scanCode & 0x8000)
1518     {
1519         TRACE("Key UP, doing nothing\n" );
1520         return 0;
1521     }
1522     e.display = display;
1523     e.keycode = 0;
1524     e.state = 0;
1525     if (lpKeyState[VK_SHIFT] & 0x80)
1526         e.state |= ShiftMask;
1527     if (lpKeyState[VK_CAPITAL] & 0x01)
1528         e.state |= LockMask;
1529     if (lpKeyState[VK_CONTROL] & 0x80)
1530     {
1531         if (lpKeyState[VK_MENU] & 0x80)
1532             e.state |= AltGrMask;
1533         else
1534             e.state |= ControlMask;
1535     }
1536     if (lpKeyState[VK_NUMLOCK] & 0x01)
1537         e.state |= NumLockMask;
1538     TRACE_(key)("(%04X, %04X) : faked state = %X\n",
1539                 virtKey, scanCode, e.state);
1540     /* We exit on the first keycode found, to speed up the thing. */
1541     for (keyc=min_keycode; (keyc<=max_keycode) && (!e.keycode) ; keyc++)
1542       { /* Find a keycode that could have generated this virtual key */
1543           if  ((keyc2vkey[keyc] & 0xFF) == virtKey)
1544           { /* We filter the extended bit, we don't know it */
1545               e.keycode = keyc; /* Store it temporarily */
1546               if ((EVENT_event_to_vkey(&e) & 0xFF) != virtKey) {
1547                   e.keycode = 0; /* Wrong one (ex: because of the NumLock
1548                          state), so set it to 0, we'll find another one */
1549               }
1550           }
1551       }
1552
1553     if ((virtKey>=VK_NUMPAD0) && (virtKey<=VK_NUMPAD9))
1554         e.keycode = TSXKeysymToKeycode(e.display, virtKey-VK_NUMPAD0+XK_KP_0);
1555           
1556     if (virtKey==VK_DECIMAL)
1557         e.keycode = TSXKeysymToKeycode(e.display, XK_KP_Decimal);
1558
1559     if (!e.keycode)
1560       {
1561         WARN("Unknown virtual key %X !!! \n",virtKey);
1562         return virtKey; /* whatever */
1563       }
1564     else TRACE("Found keycode %d (0x%2X)\n",e.keycode,e.keycode);
1565
1566     ret = TSXLookupString(&e, (LPVOID)lpChar, 2, &keysym, NULL);
1567     if (ret == 0)
1568         {
1569         BYTE dead_char;
1570
1571         dead_char = KEYBOARD_MapDeadKeysym(keysym);
1572         if (dead_char)
1573             {
1574             MultiByteToWideChar(main_key_tab[kbd_layout].layout_cp, 0, &dead_char, 1, bufW, bufW_size);
1575             ret = -1;
1576             }
1577         else
1578             {
1579             char        *ksname;
1580
1581             ksname = TSXKeysymToString(keysym);
1582             if (!ksname)
1583                 ksname = "No Name";
1584             if ((keysym >> 8) != 0xff)
1585                 {
1586                 ERR("Please report: no char for keysym %04lX (%s) :\n",
1587                     keysym, ksname);
1588                 ERR("(virtKey=%X,scanCode=%X,keycode=%X,state=%X)\n",
1589                     virtKey, scanCode, e.keycode, e.state);
1590                 }
1591             }
1592         }
1593     else {  /* ret != 0 */
1594         /* We have a special case to handle : Shift + arrow, shift + home, ...
1595            X returns a char for it, but Windows doesn't. Let's eat it. */
1596         if (!(e.state & NumLockMask)  /* NumLock is off */
1597             && (e.state & ShiftMask) /* Shift is pressed */
1598             && (keysym>=XK_KP_0) && (keysym<=XK_KP_9))
1599         {
1600             *(char*)lpChar = 0;
1601             ret = 0;
1602         }
1603
1604         /* more areas where X returns characters but Windows does not 
1605            CTRL + number or CTRL + symbol*/
1606         if (e.state & ControlMask)
1607         {
1608             if (((keysym>=33) && (keysym < 'A')) ||
1609                 ((keysym > 'Z') && (keysym < 'a')))
1610             {
1611                 *(char*)lpChar = 0;
1612                 ret = 0;
1613             }
1614         }
1615
1616         /* We have another special case for delete key (XK_Delete) on an
1617          extended keyboard. X returns a char for it, but Windows doesn't */
1618         if (keysym == XK_Delete)
1619         {
1620             *(char*)lpChar = 0;
1621             ret = 0;
1622         }
1623         else if((lpKeyState[VK_SHIFT] & 0x80) /* Shift is pressed */
1624                 && (keysym == XK_KP_Decimal))
1625         {
1626             *(char*)lpChar = 0;
1627             ret = 0;
1628         }
1629
1630         /* perform translation to unicode */
1631         if(ret)
1632         {
1633             TRACE_(key)("Translating char 0x%02x from code page %d to unicode\n",
1634                 *(BYTE *)lpChar, main_key_tab[kbd_layout].layout_cp);
1635             ret = MultiByteToWideChar(main_key_tab[kbd_layout].layout_cp, 0, (LPCSTR)lpChar, ret, bufW, bufW_size);
1636         }
1637     }
1638
1639     TRACE_(key)("ToUnicode about to return %d with char %x %s\n",
1640                 ret, bufW ? bufW[0] : 0, bufW ? "" : "(no buffer)");
1641     return ret;
1642 }
1643
1644 /***********************************************************************
1645  *              Beep (X11DRV.@)
1646  */
1647 void X11DRV_Beep(void)
1648 {
1649   TSXBell(thread_display(), 0);
1650 }
1651
1652 /***********************************************************************
1653  *              GetDIState (X11DRV.@)
1654  */
1655 BOOL X11DRV_GetDIState(DWORD len, LPVOID ptr)
1656 {
1657   if (len==256) {
1658     int keyc,vkey;
1659     
1660     memset(ptr,0,256);
1661     for (keyc=min_keycode;keyc<max_keycode;keyc++)
1662       {
1663         /* X keycode to virtual key */
1664         vkey = keyc2vkey[keyc] & 0xFF;
1665         /* The windows scancode is keyc-min_keycode */
1666         if (InputKeyStateTable[vkey]&0x80) {
1667           ((LPBYTE)ptr)[keyc-min_keycode]=0x80;
1668           ((LPBYTE)ptr)[(keyc-min_keycode)|0x80]=0x80;
1669         }
1670       }
1671     return TRUE;
1672   }
1673   WARN("whoops, got len %ld?\n", len);
1674   return TRUE;
1675 }
1676
1677 /***********************************************************************
1678  *              GetDIData (X11DRV.@)
1679  */
1680 BOOL X11DRV_GetDIData(
1681   BYTE *keystate,
1682   DWORD dodsize, LPDIDEVICEOBJECTDATA dod,
1683   LPDWORD entries, DWORD flags)
1684 {
1685   int keyc,n,vkey,xentries;
1686     
1687   /* FIXME !!! */
1688   
1689   if (entries)
1690     xentries = *entries; 
1691   else
1692     xentries = 1;
1693   
1694   n = 0;
1695   
1696   for (keyc=min_keycode;(keyc<max_keycode) && (n<*entries);keyc++)
1697     {
1698       /* X keycode to virtual key */
1699       vkey = keyc2vkey[keyc] & 0xFF;
1700       if (keystate[vkey] == (InputKeyStateTable[vkey]&0x80))
1701         continue;
1702       if (dod) {
1703         /* add an entry */
1704         dod[n].dwOfs            = keyc-min_keycode; /* scancode */
1705         dod[n].dwData           = InputKeyStateTable[vkey]&0x80;
1706         dod[n].dwTimeStamp      = 0; /* umm */
1707         dod[n].dwSequence       = 0; /* umm */
1708         n++;
1709       }
1710       if (!(flags & DIGDD_PEEK))
1711         keystate[vkey] = InputKeyStateTable[vkey]&0x80;
1712       
1713     }
1714   
1715   if (n) TRACE_(dinput)("%d entries\n",n);
1716   *entries = n;
1717
1718   return TRUE;
1719 }