Release 980215
[wine/multimedia.git] / windows / keyboard.c
blobb99656d3ffd4ba1a1f3e7fe4607e99282d5436b6
1 /*
2 * Keyboard related functions
4 * Copyright 1993 Bob Amstadt
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1997 David Faure
8 */
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <ctype.h>
14 #include <X11/keysym.h>
15 #include "ts_xlib.h"
16 #include "ts_xresource.h"
17 #include "ts_xutil.h"
18 #include <X11/Xatom.h>
20 #include "windows.h"
21 #include "win.h"
22 #include "gdi.h"
23 #include "heap.h"
24 #include "keyboard.h"
25 #include "message.h"
26 #include "stddebug.h"
27 /* #define DEBUG_KEYBOARD */
28 #include "debug.h"
29 #include "struct32.h"
31 BOOL32 MouseButtonsStates[3];
32 BOOL32 AsyncMouseButtonsStates[3];
33 BYTE InputKeyStateTable[256];
34 BYTE QueueKeyStateTable[256];
35 BYTE AsyncKeyStateTable[256];
37 static int NumLockMask;
38 static int AltGrMask;
39 static int min_keycode, max_keycode;
40 static int keyc2vkey[256];
42 typedef union
44 struct
46 unsigned long count : 16;
47 unsigned long code : 8;
48 unsigned long extended : 1;
49 unsigned long unused : 2;
50 unsigned long win_internal : 2;
51 unsigned long context : 1;
52 unsigned long previous : 1;
53 unsigned long transition : 1;
54 } lp1;
55 unsigned long lp2;
56 } KEYLP;
58 /* Keyboard translation tables */
59 static const int special_key[] =
61 VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0, /* FF08 */
62 0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */
63 0, 0, 0, VK_ESCAPE /* FF18 */
66 static const int cursor_key[] =
68 VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR,
69 VK_NEXT, VK_END /* FF50 */
72 static const int misc_key[] =
74 VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */
75 VK_CANCEL, VK_HELP, VK_CANCEL, VK_MENU /* FF68 */
78 static const int keypad_key[] =
80 0, VK_NUMLOCK, /* FF7E */
81 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */
82 0, 0, 0, 0, 0, VK_RETURN, 0, 0, /* FF88 */
83 0, 0, 0, 0, 0, VK_HOME, VK_LEFT, VK_UP, /* FF90 */
84 VK_RIGHT, VK_DOWN, VK_PRIOR, VK_NEXT, VK_END, 0,
85 VK_INSERT, VK_DELETE, /* FF98 */
86 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
87 0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT,
88 VK_DECIMAL, VK_DIVIDE, /* FFA8 */
89 VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4,
90 VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */
91 VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */
94 static const int function_key[] =
96 VK_F1, VK_F2, /* FFBE */
97 VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */
98 VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16 /* FFC8 */
101 static const int modifier_key[] =
103 VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL, 0, /* FFE1 */
104 VK_MENU, VK_MENU, VK_MENU, VK_MENU /* FFE7 */
108 * Table for vkey to scancode translation - 5/29/97 chrisf@america.com
110 const BYTE vkey2scode[512] = {
111 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x0e,0x0f,0x00,0x00,0x00,0x1c,0x00,0x00,
112 0x2a,0x1d,0x38,0x00,0x3a,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
113 0x39,0x49,0x51,0x4f,0x47,0x4b,0x48,0x4d, 0x50,0x00,0x00,0x00,0x00,0x52,0x53,0x00,
114 0x0b,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,
115 0x00,0x1e,0x30,0x2e,0x20,0x12,0x21,0x22, 0x23,0x17,0x24,0x25,0x26,0x32,0x31,0x18,
116 0x19,0x10,0x13,0x1f,0x14,0x16,0x2f,0x11, 0x2d,0x15,0x2c,0x00,0x00,0x00,0x00,0x00,
117 0x0b,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x37,0x4e,0x00,0x4a,0x34,0x00,
118 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
119 0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
120 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
121 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
122 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x29,0x0c,0x0d,0x1a,0x1b,0x2b,
123 0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
124 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x28,0x33,0x34,0x35,0x4c,
125 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
126 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127 /* 256 */
128 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x00,
129 0x00,0x1d,0x38,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130 0x00,0x49,0x51,0x4f,0x47,0x4b,0x48,0x4d, 0x50,0x00,0x00,0x00,0x00,0x52,0x53,0x00,
131 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,
135 0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42, 0x43,0x44,0x57,0x58,0x00,0x00,0x00,0x00,
136 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
137 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
138 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
139 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
140 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
141 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
142 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
143 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
146 static WORD EVENT_event_to_vkey( XKeyEvent *e)
148 KeySym keysym;
150 TSXLookupString(e, NULL, 0, &keysym, NULL);
152 if ((keysym >= 0xFFAE) && (keysym <= 0xFFB9) && (e->state & NumLockMask))
153 /* Only the Keypad keys 0-9 and . send different keysyms
154 * depending on the NumLock state */
155 return keypad_key[(keysym & 0xFF) - 0x7E];
157 return keyc2vkey[e->keycode];
160 /**********************************************************************
161 * KEYBOARD_Init
163 BOOL32 KEYBOARD_Init(void)
165 int i, keysyms_per_keycode;
166 KeySym *ksp;
167 XModifierKeymap *mmp;
168 KeySym keysym;
169 KeyCode *kcp;
170 XKeyEvent e2;
171 WORD vkey, OEMvkey;
173 TSXDisplayKeycodes(display, &min_keycode, &max_keycode);
174 ksp = TSXGetKeyboardMapping(display, min_keycode,
175 max_keycode + 1 - min_keycode, &keysyms_per_keycode);
176 /* We are only interested in keysyms_per_keycode.
177 There is no need to hold a local copy of the keysyms table */
178 TSXFree(ksp);
179 mmp = TSXGetModifierMapping(display);
180 kcp = mmp->modifiermap;
181 for (i = 0; i < 8; i += 1) /* There are 8 modifier keys */
183 int j;
185 for (j = 0; j < mmp->max_keypermod; j += 1, kcp += 1)
186 if (*kcp)
188 int k;
190 for (k = 0; k < keysyms_per_keycode; k += 1)
191 if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Mode_switch)
193 AltGrMask = 1 << i;
194 dprintf_key(stddeb, "AltGrMask is %x\n", AltGrMask);
196 else if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Num_Lock)
198 NumLockMask = 1 << i;
199 dprintf_key(stddeb, "NumLockMask is %x\n", NumLockMask);
203 TSXFreeModifiermap(mmp);
205 /* Now build two conversion arrays :
206 * keycode -> vkey + extended
207 * vkey + extended -> keycode */
209 e2.display = display;
210 e2.state = 0;
212 OEMvkey = 0xb9; /* first OEM virtual key available is ba */
213 for (e2.keycode=min_keycode; e2.keycode<=max_keycode; e2.keycode++)
215 TSXLookupString(&e2, NULL, 0, &keysym, NULL);
216 vkey = 0;
217 if (keysym) /* otherwise, keycode not used */
219 if ((keysym >> 8) == 0xFF) /* non-character key */
221 int key = keysym & 0xff;
223 if (key >= 0x08 && key <= 0x1B) /* special key */
224 vkey = special_key[key - 0x08];
225 else if (key >= 0x50 && key <= 0x57) /* cursor key */
226 vkey = cursor_key[key - 0x50];
227 else if (key >= 0x60 && key <= 0x6B) /* miscellaneous key */
228 vkey = misc_key[key - 0x60];
229 else if (key >= 0x7E && key <= 0xB9) /* keypad key */
230 vkey = keypad_key[key - 0x7E];
231 else if (key >= 0xBE && key <= 0xCD) /* function key */
233 vkey = function_key[key - 0xBE];
234 vkey |= 0x100; /* set extended bit */
236 else if (key >= 0xE1 && key <= 0xEA) /* modifier key */
237 vkey = modifier_key[key - 0xE1];
238 else if (key == 0xFF) /* DEL key */
239 vkey = VK_DELETE;
240 /* extended must also be set for ALT_R, CTRL_R,
241 INS, DEL, HOME, END, PAGE_UP, PAGE_DOWN, ARROW keys,
242 keypad / and keypad ENTER (SDK 3.1 Vol.3 p 138) */
243 /* FIXME should we set extended bit for NumLock ? My
244 * Windows does ... DF */
245 switch (keysym)
247 case XK_Control_R :
248 case XK_Alt_R :
249 case XK_Insert :
250 case XK_Delete :
251 case XK_Home :
252 case XK_End :
253 case XK_Prior :
254 case XK_Next :
255 case XK_Left :
256 case XK_Up :
257 case XK_Right :
258 case XK_Down :
259 case XK_KP_Divide :
260 case XK_KP_Enter :
261 vkey |= 0x100;
264 for (i = 0; (i < keysyms_per_keycode) && (!vkey); i++)
266 keysym = TSXLookupKeysym(&e2, i);
267 if ((keysym >= VK_0 && keysym <= VK_9)
268 || (keysym >= VK_A && keysym <= VK_Z)
269 || keysym == VK_SPACE)
270 vkey = keysym;
273 if (!vkey)
275 /* Others keys: let's assign OEM virtual key codes in the allowed range,
276 * that is ([0xba,0xc0], [0xdb,0xe4], 0xe6 (given up) et [0xe9,0xf5]) */
277 switch (++OEMvkey)
279 case 0xc1 : OEMvkey=0xdb; break;
280 case 0xe5 : OEMvkey=0xe9; break;
281 case 0xf6 : OEMvkey=0xf5; fprintf(stderr,"No more OEM vkey available!\n");
284 vkey = OEMvkey;
286 if (debugging_keyboard)
288 fprintf(stddeb,"OEM specific virtual key %X assigned to keycode %X :\n ("
289 ,OEMvkey,e2.keycode);
290 for (i = 0; i < keysyms_per_keycode; i += 1)
292 char *ksname;
294 keysym = TSXLookupKeysym(&e2, i);
295 ksname = TSXKeysymToString(keysym);
296 if (!ksname)
297 ksname = "NoSymbol";
298 fprintf(stddeb, "%lX (%s) ", keysym, ksname);
300 fprintf(stddeb, ")\n");
304 keyc2vkey[e2.keycode] = vkey;
305 } /* for */
306 return TRUE;
309 static BOOL32 NumState=FALSE, CapsState=FALSE;
311 void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, INT32 event_x, INT32 event_y,
312 DWORD event_time, KEYLP localkeylp )
314 BOOL32 * State = (vkey==VK_NUMLOCK? &NumState : &CapsState);
316 if (*State) {
317 /* The INTERMEDIARY state means : just after a 'press' event, if a 'release' event comes,
318 don't treat it. It's from the same key press. Then the state goes to ON.
319 And from there, a 'release' event will switch off the toggle key. */
320 *State=FALSE;
321 dprintf_keyboard(stddeb,"INTERM : don\'t treat release of toggle key. InputKeyStateTable[%#x] = %#x\n",vkey,InputKeyStateTable[vkey]);
322 } else
324 if ( InputKeyStateTable[vkey] & 0x1 ) /* it was ON */
326 if (Evtype!=KeyPress)
328 dprintf_keyboard(stddeb,"ON + KeyRelease => generating DOWN and UP messages.\n");
329 localkeylp.lp1.previous = 0; /* ? */
330 localkeylp.lp1.transition = 0;
331 hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2,
332 event_x, event_y, event_time, 0 );
333 hardware_event( WM_KEYUP, vkey, localkeylp.lp2,
334 event_x, event_y, event_time, 0 );
335 *State=FALSE;
336 InputKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */
339 else /* it was OFF */
340 if (Evtype==KeyPress)
342 dprintf_keyboard(stddeb,"OFF + Keypress => generating DOWN and UP messages.\n");
343 hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2,
344 event_x, event_y, event_time, 0 );
345 localkeylp.lp1.previous = 1;
346 localkeylp.lp1.transition = 1;
347 hardware_event( WM_KEYUP, vkey, localkeylp.lp2,
348 event_x, event_y, event_time, 0 );
349 *State=TRUE; /* Goes to intermediary state before going to ON */
350 InputKeyStateTable[vkey] |= 0x01; /* Toggle state to on. */
355 /***********************************************************************
356 * KEYBOARD_HandleEvent
358 * Handle a X key event
360 void KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
362 char Str[24];
363 XComposeStatus cs;
364 KeySym keysym;
365 WORD vkey = 0;
366 KEYLP keylp;
367 static BOOL32 force_extended = FALSE; /* hack for AltGr translation */
369 int ascii_chars = TSXLookupString(event, Str, 1, &keysym, &cs);
371 INT32 event_x = pWnd->rectWindow.left + event->x;
372 INT32 event_y = pWnd->rectWindow.top + event->y;
373 DWORD event_time = event->time - MSG_WineStartTicks;
375 dprintf_key(stddeb, "EVENT_key : state = %X\n", event->state);
376 if (keysym == XK_Mode_switch)
378 dprintf_key(stddeb, "Alt Gr key event received\n");
379 event->keycode = TSXKeysymToKeycode(event->display, XK_Control_L);
380 dprintf_key(stddeb, "Control_L is keycode 0x%x\n", event->keycode);
381 KEYBOARD_HandleEvent( pWnd, event );
382 event->keycode = TSXKeysymToKeycode(event->display, XK_Alt_L);
383 dprintf_key(stddeb, "Alt_L is keycode 0x%x\n", event->keycode);
384 force_extended = TRUE;
385 KEYBOARD_HandleEvent( pWnd, event );
386 force_extended = FALSE;
387 return;
390 Str[ascii_chars] = '\0';
391 if (debugging_key)
393 char *ksname;
395 ksname = TSXKeysymToString(keysym);
396 if (!ksname)
397 ksname = "No Name";
398 fprintf(stddeb, "%s : keysym=%lX (%s), ascii chars=%u / %X / '%s'\n",
399 (event->type == KeyPress) ? "KeyPress" : "KeyRelease",
400 keysym, ksname, ascii_chars, Str[0] & 0xff, Str);
403 vkey = EVENT_event_to_vkey(event);
404 if (force_extended) vkey |= 0x100;
406 dprintf_key(stddeb, "keycode 0x%x converted to vkey 0x%x\n",
407 event->keycode, vkey);
409 if (vkey)
411 keylp.lp1.count = 1;
412 keylp.lp1.code = vkey2scode[vkey]; /* 5/29/97 chrisf@america.com */
413 keylp.lp1.extended = (vkey & 0x100 ? 1 : 0);
414 keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
415 * don't remember where I read it - AK */
416 /* it's '1' under windows, when a dialog box appears
417 * and you press one of the underlined keys - DF*/
418 vkey &= 0xff;
420 switch(vkey)
422 case VK_NUMLOCK:
423 KEYBOARD_GenerateMsg( VK_NUMLOCK, event->type, event_x, event_y,
424 event_time, keylp);
425 break;
426 case VK_CAPITAL:
427 dprintf_keyboard(stddeb,"Caps Lock event. (type %d). State before : %#.2x\n",event->type,InputKeyStateTable[vkey]);
428 KEYBOARD_GenerateMsg( VK_CAPITAL, event->type, event_x, event_y,
429 event_time, keylp );
430 dprintf_keyboard(stddeb,"State after : %#.2x\n",InputKeyStateTable[vkey]);
431 break;
432 default:
434 WORD message;
435 if (event->type == KeyPress)
437 keylp.lp1.previous = (InputKeyStateTable[vkey] & 0x80) != 0;
438 if (!(InputKeyStateTable[vkey] & 0x80))
439 InputKeyStateTable[vkey] ^= 0x01;
440 InputKeyStateTable[vkey] |= 0x80;
441 keylp.lp1.transition = 0;
442 message = (InputKeyStateTable[VK_MENU] & 0x80)
443 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
444 ? WM_SYSKEYDOWN : WM_KEYDOWN;
446 else
448 BOOL32 sysKey = (InputKeyStateTable[VK_MENU] & 0x80)
449 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
450 && (force_extended == FALSE); /* for Alt from AltGr */
452 InputKeyStateTable[vkey] &= ~0x80;
453 keylp.lp1.previous = 1;
454 keylp.lp1.transition = 1;
455 message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
457 keylp.lp1.context = ( (event->state & Mod1Mask) ||
458 (InputKeyStateTable[VK_MENU] & 0x80)) ? 1 : 0;
459 if (!(InputKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
461 dprintf_keyboard(stddeb,"Adjusting NumLock state. \n");
462 KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyPress, event_x, event_y,
463 event_time, keylp );
464 KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyRelease, event_x, event_y,
465 event_time, keylp );
467 if (!(InputKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
469 dprintf_keyboard(stddeb,"Adjusting Caps Lock state. State before %#.2x \n",InputKeyStateTable[VK_CAPITAL]);
470 KEYBOARD_GenerateMsg( VK_CAPITAL, KeyPress, event_x, event_y,
471 event_time, keylp );
472 KEYBOARD_GenerateMsg( VK_CAPITAL, KeyRelease, event_x, event_y,
473 event_time, keylp );
474 dprintf_keyboard(stddeb,"State after %#.2x \n",InputKeyStateTable[VK_CAPITAL]);
476 /* End of intermediary states. */
477 NumState = FALSE;
478 CapsState = FALSE;
480 dprintf_key(stddeb," wParam=%04X, lParam=%08lX\n",
481 vkey, keylp.lp2 );
482 dprintf_key(stddeb," InputKeyState=%X\n",
483 InputKeyStateTable[vkey]);
485 hardware_event( message, vkey, keylp.lp2,
486 event_x, event_y, event_time, 0 );
493 /**********************************************************************
494 * GetKeyState [USER.106]
496 WORD WINAPI GetKeyState16(INT16 vkey)
498 return GetKeyState32(vkey);
501 /**********************************************************************
502 * GetKeyState [USER32.248]
503 * An application calls the GetKeyState function in response to a
504 * keyboard-input message. This function retrieves the state of the key
505 * at the time the input message was generated. (SDK 3.1 Vol 2. p 390)
507 WORD WINAPI GetKeyState32(INT32 vkey)
509 INT32 retval;
511 switch (vkey)
513 case VK_LBUTTON : /* VK_LBUTTON is 1 */
514 retval = MouseButtonsStates[0] ? 0x8000 : 0;
515 break;
516 case VK_MBUTTON : /* VK_MBUTTON is 4 */
517 retval = MouseButtonsStates[1] ? 0x8000 : 0;
518 break;
519 case VK_RBUTTON : /* VK_RBUTTON is 2 */
520 retval = MouseButtonsStates[2] ? 0x8000 : 0;
521 break;
522 default :
523 if (vkey >= 'a' && vkey <= 'z')
524 vkey += 'A' - 'a';
525 retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
526 (WORD)(QueueKeyStateTable[vkey] & 0x01);
528 dprintf_key(stddeb, "GetKeyState(0x%x) -> %x\n", vkey, retval);
529 return retval;
532 /**********************************************************************
533 * GetKeyboardState [USER.222][USER32.253]
534 * An application calls the GetKeyboardState function in response to a
535 * keyboard-input message. This function retrieves the state of the keyboard
536 * at the time the input message was generated. (SDK 3.1 Vol 2. p 387)
538 VOID WINAPI GetKeyboardState(LPBYTE lpKeyState)
540 dprintf_key(stddeb, "GetKeyboardState()\n");
541 if (lpKeyState != NULL) {
542 QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
543 QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
544 QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
545 memcpy(lpKeyState, QueueKeyStateTable, 256);
549 /**********************************************************************
550 * SetKeyboardState [USER.223][USER32.483]
552 VOID WINAPI SetKeyboardState(LPBYTE lpKeyState)
554 dprintf_key(stddeb, "SetKeyboardState()\n");
555 if (lpKeyState != NULL) {
556 memcpy(QueueKeyStateTable, lpKeyState, 256);
557 MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0);
558 MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0);
559 MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0);
563 /**********************************************************************
564 * GetAsyncKeyState (USER32.206)
566 * Determine if a key is or was pressed. retval has high-order
567 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
568 * been pressed.
570 * This uses the variable AsyncMouseButtonsStates and
571 * AsyncKeyStateTable (set in event.c) which have the mouse button
572 * number or key number (whichever is applicable) set to true if the
573 * mouse or key had been depressed since the last call to
574 * GetAsyncKeyState.
576 WORD WINAPI GetAsyncKeyState32(INT32 nKey)
578 short retval;
580 switch (nKey) {
581 case VK_LBUTTON:
582 retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) |
583 (MouseButtonsStates[0] ? 0x8000 : 0);
584 break;
585 case VK_MBUTTON:
586 retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) |
587 (MouseButtonsStates[1] ? 0x8000 : 0);
588 break;
589 case VK_RBUTTON:
590 retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) |
591 (MouseButtonsStates[2] ? 0x8000 : 0);
592 break;
593 default:
594 retval = AsyncKeyStateTable[nKey] |
595 ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
596 break;
599 /* all states to false */
600 memset( AsyncMouseButtonsStates, 0, sizeof(AsyncMouseButtonsStates) );
601 memset( AsyncKeyStateTable, 0, sizeof(AsyncKeyStateTable) );
603 dprintf_key(stddeb, "GetAsyncKeyState(%x) -> %x\n", nKey, retval);
604 return retval;
607 /**********************************************************************
608 * GetAsyncKeyState (USER.249)
610 WORD WINAPI GetAsyncKeyState16(INT16 nKey)
612 return GetAsyncKeyState32(nKey);
615 /*********************************************************************
616 * CreateAcceleratorTable (USER.64)
618 HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries) {
619 fprintf(stderr, "CreateAcceleratorTable32A Stub\n");
620 return NULL;
623 /**********************************************************************
624 * TranslateAccelerator [USER.178][USER32.551..]
626 * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP -messages
628 static BOOL32 KBD_translate_accelerator(HWND32 hWnd,LPMSG32 msg,
629 BYTE fVirt,WORD key,WORD cmd)
631 BOOL32 sendmsg = FALSE;
633 if(msg->wParam == key)
635 if (msg->message == WM_CHAR) {
636 if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )
638 dprintf_accel(stddeb,"found accel for WM_CHAR: ('%c')",msg->wParam&0xff);
639 sendmsg=TRUE;
641 } else {
642 if(fVirt & FVIRTKEY) {
643 INT32 mask = 0;
644 dprintf_accel(stddeb,"found accel for virt_key %04x (scan %04x)",
645 msg->wParam,0xff & HIWORD(msg->lParam));
646 if(GetKeyState32(VK_SHIFT) & 0x8000) mask |= FSHIFT;
647 if(GetKeyState32(VK_CONTROL) & 0x8000) mask |= FCONTROL;
648 if(GetKeyState32(VK_MENU) & 0x8000) mask |= FALT;
649 if(mask == (fVirt & (FSHIFT | FCONTROL | FALT)))
650 sendmsg=TRUE;
651 else
652 dprintf_accel(stddeb,", but incorrect SHIFT/CTRL/ALT-state\n");
654 else
656 if (!(msg->lParam & 0x01000000)) /* no special_key */
658 if ((fVirt & FALT) && (msg->lParam & 0x20000000))
659 { /* ^^ ALT pressed */
660 dprintf_accel(stddeb,"found accel for Alt-%c", msg->wParam&0xff);
661 sendmsg=TRUE;
667 if (sendmsg) /* found an accelerator, but send a message... ? */
669 INT16 iSysStat,iStat,mesg=0;
670 HMENU16 hMenu;
672 if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
673 mesg=1;
674 else
675 if (GetCapture32())
676 mesg=2;
677 else
678 if (!IsWindowEnabled32(hWnd))
679 mesg=3;
680 else
682 WND* wndPtr = WIN_FindWndPtr(hWnd);
684 hMenu = (wndPtr->dwStyle & WS_CHILD) ? 0 : (HMENU32)wndPtr->wIDmenu;
685 iSysStat = (wndPtr->hSysMenu) ? GetMenuState32(GetSubMenu16(wndPtr->hSysMenu, 0),
686 cmd, MF_BYCOMMAND) : -1 ;
687 iStat = (hMenu) ? GetMenuState32(hMenu,
688 cmd, MF_BYCOMMAND) : -1 ;
690 if (iSysStat!=-1)
692 if (iSysStat & (MF_DISABLED|MF_GRAYED))
693 mesg=4;
694 else
695 mesg=WM_SYSCOMMAND;
697 else
699 if (iStat!=-1)
701 if (IsIconic32(hWnd))
702 mesg=5;
703 else
705 if (iStat & (MF_DISABLED|MF_GRAYED))
706 mesg=6;
707 else
708 mesg=WM_COMMAND;
711 else
712 mesg=WM_COMMAND;
715 if ( mesg==WM_COMMAND || mesg==WM_SYSCOMMAND )
717 dprintf_accel(stddeb,", sending %s, wParam=%0x\n",
718 mesg==WM_COMMAND ? "WM_COMMAND" : "WM_SYSCOMMAND",
719 cmd);
720 SendMessage32A(hWnd, mesg, cmd, 0x00010000L);
722 else
724 /* some reasons for NOT sending the WM_{SYS}COMMAND message:
725 * #0: unknown (please report!)
726 * #1: for WM_KEYUP,WM_SYSKEYUP
727 * #2: mouse is captured
728 * #3: window is disabled
729 * #4: it's a disabled system menu option
730 * #5: it's a menu option, but window is iconic
731 * #6: it's a menu option, but disabled
733 dprintf_accel(stddeb,", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
735 return TRUE;
738 return FALSE;
741 INT32 WINAPI TranslateAccelerator32(HWND32 hWnd, HACCEL32 hAccel, LPMSG32 msg)
743 LPACCEL32 lpAccelTbl = (LPACCEL32)LockResource32(hAccel);
744 int i;
746 if (hAccel == 0 || msg == NULL) return 0;
747 if (msg->message != WM_KEYDOWN &&
748 msg->message != WM_KEYUP &&
749 msg->message != WM_SYSKEYDOWN &&
750 msg->message != WM_SYSKEYUP &&
751 msg->message != WM_CHAR) return 0;
753 dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
754 msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
756 for (i = 0; lpAccelTbl[i].key ; i++)
757 if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
758 lpAccelTbl[i].key,lpAccelTbl[i].cmd))
759 return 1;
760 return 0;
763 INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
765 LPACCEL16 lpAccelTbl = (LPACCEL16)LockResource16(hAccel);
766 int i;
767 MSG32 msg32;
769 if (hAccel == 0 || msg == NULL) return 0;
770 if (msg->message != WM_KEYDOWN &&
771 msg->message != WM_KEYUP &&
772 msg->message != WM_SYSKEYDOWN &&
773 msg->message != WM_SYSKEYUP &&
774 msg->message != WM_CHAR) return 0;
776 dprintf_accel(stddeb, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
777 msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
778 STRUCT32_MSG16to32(msg,&msg32);
781 for (i=0;lpAccelTbl[i].key;i++)
782 if (KBD_translate_accelerator(hWnd,&msg32,lpAccelTbl[i].fVirt,
783 lpAccelTbl[i].key,lpAccelTbl[i].cmd))
784 return 1;
785 return 0;
789 /******************************************************************************
790 * OemKeyScan [KEYBOARD.128][USER32.400]
792 DWORD WINAPI OemKeyScan(WORD wOemChar)
794 dprintf_keyboard(stddeb,"*OemKeyScan (%d)\n",wOemChar);
796 return wOemChar;
799 /******************************************************************************
800 * VkKeyScanA [USER32.572]
802 /* VkKeyScan translates an ANSI character to a virtual-key and shift code
803 * for the current keyboard.
804 * high-order byte yields :
805 * 0 Unshifted
806 * 1 Shift
807 * 2 Ctrl
808 * 3-5 Shift-key combinations that are not used for characters
809 * 6 Ctrl-Alt
810 * 7 Ctrl-Alt-Shift
811 * I.e. : Shift = 1, Ctrl = 2, Alt = 4.
812 * FIXME : works ok except for dead chars :
813 * VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
814 * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
817 WORD WINAPI VkKeyScan32A(CHAR cChar)
819 KeyCode keycode;
820 KeySym keysym;
821 int i,index;
822 int highbyte=0;
824 /* char->keysym (same for ANSI chars) */
825 keysym=(unsigned char) cChar;/* (!) cChar is signed */
826 if (keysym<=27) keysym+=0xFF00;/*special chars : return, backspace...*/
828 keycode = TSXKeysymToKeycode(display, keysym); /* keysym -> keycode */
829 if (!keycode)
830 { /* It didn't work ... let's try with deadchar code. */
831 keycode = TSXKeysymToKeycode(display, keysym | 0xFE00);
834 dprintf_keyboard(stddeb,"VkKeyScan '%c'(%#lx, %lu) : got keycode %#.2x ",
835 cChar,keysym,keysym,keycode);
837 if (keycode)
839 for (index=-1, i=0; (i<8) && (index<0); i++) /* find shift state */
840 if (TSXKeycodeToKeysym(display,keycode,i)==keysym) index=i;
841 switch (index) {
842 case -1 :
843 fprintf(stderr,"Keysym %lx not found while parsing the keycode table\n",keysym); break;
844 case 0 : break;
845 case 1 : highbyte = 0x0100; break;
846 case 2 : highbyte = 0X0600; break;
847 default : fprintf(stderr,"index %d found by XKeycodeToKeysym. please report! \n",index);
850 index : 0 adds 0x0000
851 index : 1 adds 0x0100 (shift)
852 index : ? adds 0x0200 (ctrl)
853 index : 2 adds 0x0600 (ctrl+alt)
854 index : ? adds 0x0700 (ctrl+alt+shift (used?))
857 dprintf_keyboard(stddeb," ... returning %#.2x\n", keyc2vkey[keycode]+highbyte);
858 return keyc2vkey[keycode]+highbyte; /* keycode -> (keyc2vkey) vkey */
861 /******************************************************************************
862 * VkKeyScan [KEYBOARD.129]
864 WORD WINAPI VkKeyScan16(CHAR cChar)
866 return VkKeyScan32A(cChar);
869 /******************************************************************************
870 * VkKeyScanW [USER32.575]
872 WORD WINAPI VkKeyScan32W(WCHAR cChar)
874 return VkKeyScan32A((CHAR)cChar); /* FIXME: check unicode */
877 /******************************************************************************
878 * GetKeyboardType [KEYBOARD.130]
880 INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
882 return GetKeyboardType32(nTypeFlag);
885 /******************************************************************************
886 * GetKeyboardType [USER32.254]
888 INT32 WINAPI GetKeyboardType32(INT32 nTypeFlag)
890 dprintf_keyboard(stddeb,"GetKeyboardType(%d)\n",nTypeFlag);
891 switch(nTypeFlag)
893 case 0: /* Keyboard type */
894 return 4; /* AT-101 */
895 break;
896 case 1: /* Keyboard Subtype */
897 return 0; /* There are no defined subtypes */
898 break;
899 case 2: /* Number of F-keys */
900 return 12; /* We're doing an 101 for now, so return 12 F-keys */
901 break;
902 default:
903 fprintf(stderr, "Unknown type on GetKeyboardType\n");
904 return 0; /* The book says 0 here, so 0 */
909 /******************************************************************************
910 * MapVirtualKeyA [USER32.382]
912 UINT32 WINAPI MapVirtualKey32A(UINT32 code, UINT32 maptype)
914 return MapVirtualKey16(code,maptype);
917 /******************************************************************************
918 * MapVirtualKeyA [USER32.384]
920 UINT32 WINAPI MapVirtualKey32W(UINT32 code, UINT32 maptype)
922 return MapVirtualKey16(code,maptype);
925 /******************************************************************************
926 * MapVirtualKeyA [KEYBOARD.131]
927 * MapVirtualKey translates keycodes from one format to another
929 UINT16 WINAPI MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
931 #define returnMVK(value) { dprintf_keyboard(stddeb,"returning 0x%x.\n",value); return value; }
933 dprintf_keyboard(stddeb,"MapVirtualKey wCode=0x%x wMapType=%d ... ",wCode,wMapType);
934 switch(wMapType) {
935 case 0: { /* vkey-code to scan-code */
936 /* let's do vkey -> keycode -> scan */
937 KeyCode keyc;
938 for (keyc=min_keycode; keyc<=max_keycode; keyc++) /* see event.c */
939 if ((keyc2vkey[keyc] & 0xFF)== wCode)
940 returnMVK (keyc - 8);
941 return 0; }
943 case 1: /* scan-code to vkey-code */
944 /* let's do scan -> keycode -> vkey */
946 returnMVK (keyc2vkey[(wCode & 0xFF) + 8]);
948 case 2: { /* vkey-code to unshifted ANSI code */
949 /* (was FIXME) : what does unshifted mean ? 'a' or 'A' ? */
950 /* My Windows returns 'A'. */
951 /* let's do vkey -> keycode -> (XLookupString) ansi char */
952 XKeyEvent e;
953 KeySym keysym;
954 char s[2];
955 e.display = display;
956 e.state = 0; /* unshifted */
957 e.keycode = MapVirtualKey16( wCode, 0);
958 if (!TSXLookupString(&e, s , 2 , &keysym, NULL))
959 returnMVK (*s);
961 return 0;
963 default: /* reserved */
964 fprintf(stderr, "MapVirtualKey: unknown wMapType %d !\n",
965 wMapType);
966 return 0;
968 return 0;
972 /****************************************************************************
973 * GetKBCodePage16 (KEYBOARD.132)
975 INT16 WINAPI GetKBCodePage16(void)
977 dprintf_keyboard(stddeb,"GetKBCodePage()\n");
978 return 850;
982 /****************************************************************************
983 * GetKBCodePage32 (USER32.245)
985 UINT32 WINAPI GetKBCodePage32(void)
987 dprintf_keyboard(stddeb,"GetKbCodePage()\n");
988 return 850;
992 /****************************************************************************
993 * GetKeyNameText32W (USER32.247)
995 INT32 WINAPI GetKeyNameText32W(LONG lParam, LPWSTR lpBuffer, INT32 nSize)
997 LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, nSize );
998 int res = GetKeyNameText32A(lParam,buf,nSize);
1000 lstrcpynAtoW(lpBuffer,buf,nSize);
1001 HeapFree( GetProcessHeap(), 0, buf );
1002 return res;
1005 /****************************************************************************
1006 * GetKeyNameText32A (USER32.246)
1008 INT32 WINAPI GetKeyNameText32A(LONG lParam, LPSTR lpBuffer, INT32 nSize)
1010 return GetKeyNameText16(lParam,lpBuffer,nSize);
1013 /****************************************************************************
1014 * GetKeyNameText16 (KEYBOARD.133)
1016 INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
1018 /* int i; */
1020 dprintf_keyboard(stddeb,"GetKeyNameText(%ld,<ptr>,%d)\n",lParam,nSize);
1022 lParam >>= 16;
1023 lParam &= 0xff;
1025 /* for (i = 0 ; i != KeyTableSize ; i++)
1026 if (KeyTable[i].scancode == lParam) {
1027 lstrcpyn32A( lpBuffer, KeyTable[i].name, nSize );
1028 return strlen(lpBuffer);
1031 /* FIXME ! GetKeyNameText is still to do...
1033 *lpBuffer = 0;
1034 return 0;
1038 /****************************************************************************
1039 * ToAscii (KEYBOARD.4)
1041 INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState,
1042 LPVOID lpChar, UINT16 flags)
1044 return ToAscii32(virtKey,scanCode,lpKeyState,lpChar,flags);
1047 /****************************************************************************
1048 * ToAscii (USER32.545)
1050 INT32 WINAPI ToAscii32( UINT32 virtKey,UINT32 scanCode,LPBYTE lpKeyState,
1051 LPWORD lpChar,UINT32 flags )
1053 XKeyEvent e;
1054 KeySym keysym;
1055 static XComposeStatus cs;
1056 INT32 ret;
1057 WORD keyc;
1059 e.display = display;
1060 e.keycode = 0;
1061 for (keyc=min_keycode; keyc<=max_keycode; keyc++)
1062 { /* this could be speeded up by making another table, an array of struct vkey,keycode
1063 * (vkey -> keycode) with vkeys sorted .... but it takes memory (512*3 bytes)! DF */
1064 if ((keyc2vkey[keyc] & 0xFF)== virtKey) /* no need to make a more precise test (with the extended bit correctly set above virtKey ... VK* are different enough... */
1066 if ((e.keycode) && ((virtKey<0x10) || (virtKey>0x12)))
1067 /* it's normal to have 2 shift, control, and alt ! */
1068 dprintf_keyboard(stddeb,"ToAscii : The keycodes %d and %d are matching the same vkey %#X\n",
1069 e.keycode,keyc,virtKey);
1070 e.keycode = keyc;
1073 if ((!e.keycode) && (lpKeyState[VK_NUMLOCK] & 0x01))
1075 if ((virtKey>=VK_NUMPAD0) && (virtKey<=VK_NUMPAD9))
1076 e.keycode = TSXKeysymToKeycode(e.display, virtKey-VK_NUMPAD0+XK_KP_0);
1077 if (virtKey==VK_DECIMAL)
1078 e.keycode = TSXKeysymToKeycode(e.display, XK_KP_Decimal);
1080 if (!e.keycode)
1082 fprintf(stderr,"ToAscii : Unknown virtual key %X !!! \n",virtKey);
1083 return virtKey; /* whatever */
1085 e.state = 0;
1086 if (lpKeyState[VK_SHIFT] & 0x80)
1087 e.state |= ShiftMask;
1088 dprintf_keyboard(stddeb,"ToAscii : lpKeyState[0x14(VK_CAPITAL)]=%#x\n",lpKeyState[VK_CAPITAL]);
1089 if (lpKeyState[VK_CAPITAL] & 0x01)
1090 e.state |= LockMask;
1091 if (lpKeyState[VK_CONTROL] & 0x80)
1092 if (lpKeyState[VK_MENU] & 0x80)
1093 e.state |= AltGrMask;
1094 else
1095 e.state |= ControlMask;
1096 if (lpKeyState[VK_NUMLOCK] & 0x01)
1097 e.state |= NumLockMask;
1098 dprintf_key(stddeb, "ToAscii(%04X, %04X) : faked state = %X\n",
1099 virtKey, scanCode, e.state);
1100 ret = TSXLookupString(&e, (LPVOID)lpChar, 2, &keysym, &cs);
1101 if (ret == 0)
1103 BYTE dead_char = 0;
1105 ((char*)lpChar)[1] = '\0';
1106 switch (keysym)
1108 /* symbolic ASCII is the same as defined in rfc1345 */
1109 #ifdef XK_dead_tilde
1110 case XK_dead_tilde :
1111 #endif
1112 case 0x1000FE7E : /* Xfree's XK_Dtilde */
1113 dead_char = '~'; /* '? */
1114 break;
1115 #ifdef XK_dead_acute
1116 case XK_dead_acute :
1117 #endif
1118 case 0x1000FE27 : /* Xfree's XK_Dacute_accent */
1119 dead_char = 0xb4; /* '' */
1120 break;
1121 #ifdef XK_dead_circumflex
1122 case XK_dead_circumflex :
1123 #endif
1124 case 0x1000FE5E : /* Xfree's XK_Dcircumflex_accent */
1125 dead_char = '^'; /* '> */
1126 break;
1127 #ifdef XK_dead_grave
1128 case XK_dead_grave :
1129 #endif
1130 case 0x1000FE60 : /* Xfree's XK_Dgrave_accent */
1131 dead_char = '`'; /* '! */
1132 break;
1133 #ifdef XK_dead_diaeresis
1134 case XK_dead_diaeresis :
1135 #endif
1136 case 0x1000FE22 : /* Xfree's XK_Ddiaeresis */
1137 dead_char = 0xa8; /* ': */
1138 break;
1139 #ifdef XK_dead_cedilla
1140 case XK_dead_cedilla :
1141 dead_char = 0xb8; /* ', */
1142 break;
1143 #endif
1144 #ifdef XK_dead_macron
1145 case XK_dead_macron :
1146 dead_char = '-'; /* 'm isn't defined on iso-8859-x */
1147 break;
1148 #endif
1149 #ifdef XK_dead_breve
1150 case XK_dead_breve :
1151 dead_char = 0xa2; /* '( */
1152 break;
1153 #endif
1154 #ifdef XK_dead_abovedot
1155 case XK_dead_abovedot :
1156 dead_char = 0xff; /* '. */
1157 break;
1158 #endif
1159 #ifdef XK_dead_abovering
1160 case XK_dead_abovering :
1161 dead_char = '0'; /* '0 isn't defined on iso-8859-x */
1162 break;
1163 #endif
1164 #ifdef XK_dead_doubleacute
1165 case XK_dead_doubleacute :
1166 dead_char = 0xbd; /* '" */
1167 break;
1168 #endif
1169 #ifdef XK_dead_caron
1170 case XK_dead_caron :
1171 dead_char = 0xb7; /* '< */
1172 break;
1173 #endif
1174 #ifdef XK_dead_ogonek
1175 case XK_dead_ogonek :
1176 dead_char = 0xb2; /* '; */
1177 break;
1178 #endif
1179 /* FIXME: I don't know this three.
1180 case XK_dead_iota :
1181 dead_char = 'i';
1182 break;
1183 case XK_dead_voiced_sound :
1184 dead_char = 'v';
1185 break;
1186 case XK_dead_semivoiced_sound :
1187 dead_char = 's';
1188 break;
1191 if (dead_char)
1193 *(char*)lpChar = dead_char;
1194 ret = -1;
1196 else
1198 char *ksname;
1200 ksname = TSXKeysymToString(keysym);
1201 if (!ksname)
1202 ksname = "No Name";
1203 if ((keysym >> 8) != 0xff)
1205 fprintf(stderr, "Please report : no char for keysym %04lX (%s) :\n",
1206 keysym, ksname);
1207 fprintf(stderr, " virtKey = %X, scanCode = %X, keycode = %X, state = %X\n",
1208 virtKey, scanCode, e.keycode, e.state);
1212 dprintf_key(stddeb, "ToAscii about to return %d with char %x\n",
1213 ret, *(char*)lpChar);
1214 return ret;
1218 /***********************************************************************
1219 * GetKeyboardLayout (USER32.249)
1221 HKL32 WINAPI GetKeyboardLayout(DWORD dwLayout)
1223 fprintf(stderr,"GetKeyboardLayout(%ld),STUB!\n",dwLayout);
1224 return (0xcafe<<16)|GetSystemDefaultLCID(); /* FIXME */
1227 /***********************************************************************
1228 * GetKeyboardLayoutList (USER32.250)
1229 * FIXME
1231 INT32 WINAPI GetKeyboardLayoutList(INT32 nBuff,HKL32 *layouts)
1233 fprintf(stderr,"GetKeyboardLayoutList(%d,%p),STUB!\n",nBuff,layouts);
1234 if (layouts)
1235 layouts[0] = GetKeyboardLayout(0);
1236 return 1;
1240 /***********************************************************************
1241 * RegisterHotKey (USER32.433)
1243 BOOL32 WINAPI RegisterHotKey(HWND32 hwnd,INT32 id,UINT32 modifiers,UINT32 vk) {
1244 fprintf(stderr,"RegisterHotKey(%08x,%d,%08x,%d), STUB!\n",
1245 hwnd,id,modifiers,vk
1247 return TRUE;
1250 /***********************************************************************
1251 * UnregisterHotKey (USER32.565)
1253 BOOL32 WINAPI UnregisterHotKey(HWND32 hwnd,INT32 id) {
1254 fprintf(stderr,"UnregisterHotKey(%08x,%d),stub!\n",hwnd,id);
1255 return TRUE;