Release 980315
[wine/multimedia.git] / windows / keyboard.c
blob5717db5d69134aec284f0f04024816be9d4c8556
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 "debug.h"
27 #include "struct32.h"
29 BOOL32 MouseButtonsStates[3];
30 BOOL32 AsyncMouseButtonsStates[3];
31 BYTE InputKeyStateTable[256];
32 BYTE QueueKeyStateTable[256];
33 BYTE AsyncKeyStateTable[256];
35 static int NumLockMask;
36 static int AltGrMask;
37 static int min_keycode, max_keycode;
38 static int keyc2vkey[256];
40 typedef union
42 struct
44 unsigned long count : 16;
45 unsigned long code : 8;
46 unsigned long extended : 1;
47 unsigned long unused : 2;
48 unsigned long win_internal : 2;
49 unsigned long context : 1;
50 unsigned long previous : 1;
51 unsigned long transition : 1;
52 } lp1;
53 unsigned long lp2;
54 } KEYLP;
56 /* Keyboard translation tables */
57 static const int special_key[] =
59 VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0, /* FF08 */
60 0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */
61 0, 0, 0, VK_ESCAPE /* FF18 */
64 static const int cursor_key[] =
66 VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR,
67 VK_NEXT, VK_END /* FF50 */
70 static const int misc_key[] =
72 VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */
73 VK_CANCEL, VK_HELP, VK_CANCEL, VK_MENU /* FF68 */
76 static const int keypad_key[] =
78 0, VK_NUMLOCK, /* FF7E */
79 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */
80 0, 0, 0, 0, 0, VK_RETURN, 0, 0, /* FF88 */
81 0, 0, 0, 0, 0, VK_HOME, VK_LEFT, VK_UP, /* FF90 */
82 VK_RIGHT, VK_DOWN, VK_PRIOR, VK_NEXT, VK_END, 0,
83 VK_INSERT, VK_DELETE, /* FF98 */
84 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
85 0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT,
86 VK_DECIMAL, VK_DIVIDE, /* FFA8 */
87 VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4,
88 VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */
89 VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */
92 static const int function_key[] =
94 VK_F1, VK_F2, /* FFBE */
95 VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */
96 VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16 /* FFC8 */
99 static const int modifier_key[] =
101 VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL, 0, /* FFE1 */
102 VK_MENU, VK_MENU, VK_MENU, VK_MENU /* FFE7 */
106 * Table for vkey to scancode translation - 5/29/97 chrisf@america.com
108 const BYTE vkey2scode[512] = {
109 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x0e,0x0f,0x00,0x00,0x00,0x1c,0x00,0x00,
110 0x2a,0x1d,0x38,0x00,0x3a,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
111 0x39,0x49,0x51,0x4f,0x47,0x4b,0x48,0x4d, 0x50,0x00,0x00,0x00,0x00,0x52,0x53,0x00,
112 0x0b,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,
113 0x00,0x1e,0x30,0x2e,0x20,0x12,0x21,0x22, 0x23,0x17,0x24,0x25,0x26,0x32,0x31,0x18,
114 0x19,0x10,0x13,0x1f,0x14,0x16,0x2f,0x11, 0x2d,0x15,0x2c,0x00,0x00,0x00,0x00,0x00,
115 0x0b,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x37,0x4e,0x00,0x4a,0x34,0x00,
116 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
117 0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
118 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
119 0x00,0x00,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,0x29,0x0c,0x0d,0x1a,0x1b,0x2b,
121 0x27,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,0x00,0x28,0x33,0x34,0x35,0x4c,
123 0x00,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,0x00,0x00,0x00,0x00,0x00,
125 /* 256 */
126 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x00,
127 0x00,0x1d,0x38,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128 0x00,0x49,0x51,0x4f,0x47,0x4b,0x48,0x4d, 0x50,0x00,0x00,0x00,0x00,0x52,0x53,0x00,
129 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x35,
133 0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42, 0x43,0x44,0x57,0x58,0x00,0x00,0x00,0x00,
134 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,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,
144 static WORD EVENT_event_to_vkey( XKeyEvent *e)
146 KeySym keysym;
148 TSXLookupString(e, NULL, 0, &keysym, NULL);
150 if ((keysym >= 0xFFAE) && (keysym <= 0xFFB9) && (e->state & NumLockMask))
151 /* Only the Keypad keys 0-9 and . send different keysyms
152 * depending on the NumLock state */
153 return keypad_key[(keysym & 0xFF) - 0x7E];
155 return keyc2vkey[e->keycode];
158 /**********************************************************************
159 * KEYBOARD_Init
161 BOOL32 KEYBOARD_Init(void)
163 int i, keysyms_per_keycode;
164 KeySym *ksp;
165 XModifierKeymap *mmp;
166 KeySym keysym;
167 KeyCode *kcp;
168 XKeyEvent e2;
169 WORD vkey, OEMvkey;
171 TSXDisplayKeycodes(display, &min_keycode, &max_keycode);
172 ksp = TSXGetKeyboardMapping(display, min_keycode,
173 max_keycode + 1 - min_keycode, &keysyms_per_keycode);
174 /* We are only interested in keysyms_per_keycode.
175 There is no need to hold a local copy of the keysyms table */
176 TSXFree(ksp);
177 mmp = TSXGetModifierMapping(display);
178 kcp = mmp->modifiermap;
179 for (i = 0; i < 8; i += 1) /* There are 8 modifier keys */
181 int j;
183 for (j = 0; j < mmp->max_keypermod; j += 1, kcp += 1)
184 if (*kcp)
186 int k;
188 for (k = 0; k < keysyms_per_keycode; k += 1)
189 if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Mode_switch)
191 AltGrMask = 1 << i;
192 TRACE(key, "AltGrMask is %x\n", AltGrMask);
194 else if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Num_Lock)
196 NumLockMask = 1 << i;
197 TRACE(key, "NumLockMask is %x\n", NumLockMask);
201 TSXFreeModifiermap(mmp);
203 /* Now build two conversion arrays :
204 * keycode -> vkey + extended
205 * vkey + extended -> keycode */
207 e2.display = display;
208 e2.state = 0;
210 OEMvkey = 0xb9; /* first OEM virtual key available is ba */
211 for (e2.keycode=min_keycode; e2.keycode<=max_keycode; e2.keycode++)
213 TSXLookupString(&e2, NULL, 0, &keysym, NULL);
214 vkey = 0;
215 if (keysym) /* otherwise, keycode not used */
217 if ((keysym >> 8) == 0xFF) /* non-character key */
219 int key = keysym & 0xff;
221 if (key >= 0x08 && key <= 0x1B) /* special key */
222 vkey = special_key[key - 0x08];
223 else if (key >= 0x50 && key <= 0x57) /* cursor key */
224 vkey = cursor_key[key - 0x50];
225 else if (key >= 0x60 && key <= 0x6B) /* miscellaneous key */
226 vkey = misc_key[key - 0x60];
227 else if (key >= 0x7E && key <= 0xB9) /* keypad key */
228 vkey = keypad_key[key - 0x7E];
229 else if (key >= 0xBE && key <= 0xCD) /* function key */
231 vkey = function_key[key - 0xBE];
232 vkey |= 0x100; /* set extended bit */
234 else if (key >= 0xE1 && key <= 0xEA) /* modifier key */
235 vkey = modifier_key[key - 0xE1];
236 else if (key == 0xFF) /* DEL key */
237 vkey = VK_DELETE;
238 /* extended must also be set for ALT_R, CTRL_R,
239 INS, DEL, HOME, END, PAGE_UP, PAGE_DOWN, ARROW keys,
240 keypad / and keypad ENTER (SDK 3.1 Vol.3 p 138) */
241 /* FIXME should we set extended bit for NumLock ? My
242 * Windows does ... DF */
243 switch (keysym)
245 case XK_Control_R :
246 case XK_Alt_R :
247 case XK_Insert :
248 case XK_Delete :
249 case XK_Home :
250 case XK_End :
251 case XK_Prior :
252 case XK_Next :
253 case XK_Left :
254 case XK_Up :
255 case XK_Right :
256 case XK_Down :
257 case XK_KP_Divide :
258 case XK_KP_Enter :
259 vkey |= 0x100;
262 for (i = 0; (i < keysyms_per_keycode) && (!vkey); i++)
264 keysym = TSXLookupKeysym(&e2, i);
265 if ((keysym >= VK_0 && keysym <= VK_9)
266 || (keysym >= VK_A && keysym <= VK_Z)
267 || keysym == VK_SPACE)
268 vkey = keysym;
271 if (!vkey)
273 /* Others keys: let's assign OEM virtual key codes in the allowed range,
274 * that is ([0xba,0xc0], [0xdb,0xe4], 0xe6 (given up) et [0xe9,0xf5]) */
275 switch (++OEMvkey)
277 case 0xc1 : OEMvkey=0xdb; break;
278 case 0xe5 : OEMvkey=0xe9; break;
279 case 0xf6 : OEMvkey=0xf5; fprintf(stderr,"No more OEM vkey available!\n");
282 vkey = OEMvkey;
284 if (TRACE_ON(keyboard))
286 dbg_decl_str(keyboard, 1024);
288 TRACE(keyboard, "OEM specific virtual key %X assigned"
289 "to keycode %X :\n", 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 dsprintf(keyboard, "%lX (%s) ", keysym, ksname);
300 TRACE(keyboard, "(%s)\n", dbg_str(keyboard));
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 TRACE(keyboard,"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 TRACE(keyboard,"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 TRACE(keyboard,"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 TRACE(key, "EVENT_key : state = %X\n", event->state);
376 if (keysym == XK_Mode_switch)
378 TRACE(key, "Alt Gr key event received\n");
379 event->keycode = TSXKeysymToKeycode(event->display, XK_Control_L);
380 TRACE(key, "Control_L is keycode 0x%x\n", event->keycode);
381 KEYBOARD_HandleEvent( pWnd, event );
382 event->keycode = TSXKeysymToKeycode(event->display, XK_Alt_L);
383 TRACE(key, "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 (TRACE_ON(key)){
392 char *ksname;
394 ksname = TSXKeysymToString(keysym);
395 if (!ksname)
396 ksname = "No Name";
397 TRACE(key, "%s : keysym=%lX (%s), ascii chars=%u / %X / '%s'\n",
398 (event->type == KeyPress) ? "KeyPress" : "KeyRelease",
399 keysym, ksname, ascii_chars, Str[0] & 0xff, Str);
402 vkey = EVENT_event_to_vkey(event);
403 if (force_extended) vkey |= 0x100;
405 TRACE(key, "keycode 0x%x converted to vkey 0x%x\n",
406 event->keycode, vkey);
408 if (vkey)
410 keylp.lp1.count = 1;
411 keylp.lp1.code = vkey2scode[vkey]; /* 5/29/97 chrisf@america.com */
412 keylp.lp1.extended = (vkey & 0x100 ? 1 : 0);
413 keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
414 * don't remember where I read it - AK */
415 /* it's '1' under windows, when a dialog box appears
416 * and you press one of the underlined keys - DF*/
417 vkey &= 0xff;
419 switch(vkey)
421 case VK_NUMLOCK:
422 KEYBOARD_GenerateMsg( VK_NUMLOCK, event->type, event_x, event_y,
423 event_time, keylp);
424 break;
425 case VK_CAPITAL:
426 TRACE(keyboard,"Caps Lock event. (type %d). State before : %#.2x\n",event->type,InputKeyStateTable[vkey]);
427 KEYBOARD_GenerateMsg( VK_CAPITAL, event->type, event_x, event_y,
428 event_time, keylp );
429 TRACE(keyboard,"State after : %#.2x\n",InputKeyStateTable[vkey]);
430 break;
431 default:
433 WORD message;
434 if (event->type == KeyPress)
436 keylp.lp1.previous = (InputKeyStateTable[vkey] & 0x80) != 0;
437 if (!(InputKeyStateTable[vkey] & 0x80))
438 InputKeyStateTable[vkey] ^= 0x01;
439 InputKeyStateTable[vkey] |= 0x80;
440 keylp.lp1.transition = 0;
441 message = (InputKeyStateTable[VK_MENU] & 0x80)
442 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
443 ? WM_SYSKEYDOWN : WM_KEYDOWN;
445 else
447 BOOL32 sysKey = (InputKeyStateTable[VK_MENU] & 0x80)
448 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
449 && (force_extended == FALSE); /* for Alt from AltGr */
451 InputKeyStateTable[vkey] &= ~0x80;
452 keylp.lp1.previous = 1;
453 keylp.lp1.transition = 1;
454 message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
456 keylp.lp1.context = ( (event->state & Mod1Mask) ||
457 (InputKeyStateTable[VK_MENU] & 0x80)) ? 1 : 0;
458 if (!(InputKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
460 TRACE(keyboard,"Adjusting NumLock state. \n");
461 KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyPress, event_x, event_y,
462 event_time, keylp );
463 KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyRelease, event_x, event_y,
464 event_time, keylp );
466 if (!(InputKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
468 TRACE(keyboard,"Adjusting Caps Lock state. State before %#.2x \n",InputKeyStateTable[VK_CAPITAL]);
469 KEYBOARD_GenerateMsg( VK_CAPITAL, KeyPress, event_x, event_y,
470 event_time, keylp );
471 KEYBOARD_GenerateMsg( VK_CAPITAL, KeyRelease, event_x, event_y,
472 event_time, keylp );
473 TRACE(keyboard,"State after %#.2x \n",InputKeyStateTable[VK_CAPITAL]);
475 /* End of intermediary states. */
476 NumState = FALSE;
477 CapsState = FALSE;
479 TRACE(key," wParam=%04X, lParam=%08lX\n",
480 vkey, keylp.lp2 );
481 TRACE(key," InputKeyState=%X\n",
482 InputKeyStateTable[vkey]);
484 hardware_event( message, vkey, keylp.lp2,
485 event_x, event_y, event_time, 0 );
492 /**********************************************************************
493 * GetKeyState [USER.106]
495 WORD WINAPI GetKeyState16(INT16 vkey)
497 return GetKeyState32(vkey);
500 /**********************************************************************
501 * GetKeyState [USER32.248]
502 * An application calls the GetKeyState function in response to a
503 * keyboard-input message. This function retrieves the state of the key
504 * at the time the input message was generated. (SDK 3.1 Vol 2. p 390)
506 WORD WINAPI GetKeyState32(INT32 vkey)
508 INT32 retval;
510 switch (vkey)
512 case VK_LBUTTON : /* VK_LBUTTON is 1 */
513 retval = MouseButtonsStates[0] ? 0x8000 : 0;
514 break;
515 case VK_MBUTTON : /* VK_MBUTTON is 4 */
516 retval = MouseButtonsStates[1] ? 0x8000 : 0;
517 break;
518 case VK_RBUTTON : /* VK_RBUTTON is 2 */
519 retval = MouseButtonsStates[2] ? 0x8000 : 0;
520 break;
521 default :
522 if (vkey >= 'a' && vkey <= 'z')
523 vkey += 'A' - 'a';
524 retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
525 (WORD)(QueueKeyStateTable[vkey] & 0x01);
527 TRACE(key, "(0x%x) -> %x\n", vkey, retval);
528 return retval;
531 /**********************************************************************
532 * GetKeyboardState [USER.222][USER32.253]
533 * An application calls the GetKeyboardState function in response to a
534 * keyboard-input message. This function retrieves the state of the keyboard
535 * at the time the input message was generated. (SDK 3.1 Vol 2. p 387)
537 VOID WINAPI GetKeyboardState(LPBYTE lpKeyState)
539 TRACE(key, "(%p)\n", lpKeyState);
540 if (lpKeyState != NULL) {
541 QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
542 QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
543 QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
544 memcpy(lpKeyState, QueueKeyStateTable, 256);
548 /**********************************************************************
549 * SetKeyboardState [USER.223][USER32.483]
551 VOID WINAPI SetKeyboardState(LPBYTE lpKeyState)
553 TRACE(key, "(%p)\n", lpKeyState);
554 if (lpKeyState != NULL) {
555 memcpy(QueueKeyStateTable, lpKeyState, 256);
556 MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0);
557 MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0);
558 MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0);
562 /**********************************************************************
563 * GetAsyncKeyState (USER32.206)
565 * Determine if a key is or was pressed. retval has high-order
566 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
567 * been pressed.
569 * This uses the variable AsyncMouseButtonsStates and
570 * AsyncKeyStateTable (set in event.c) which have the mouse button
571 * number or key number (whichever is applicable) set to true if the
572 * mouse or key had been depressed since the last call to
573 * GetAsyncKeyState.
575 WORD WINAPI GetAsyncKeyState32(INT32 nKey)
577 short retval;
579 switch (nKey) {
580 case VK_LBUTTON:
581 retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) |
582 (MouseButtonsStates[0] ? 0x8000 : 0);
583 break;
584 case VK_MBUTTON:
585 retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) |
586 (MouseButtonsStates[1] ? 0x8000 : 0);
587 break;
588 case VK_RBUTTON:
589 retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) |
590 (MouseButtonsStates[2] ? 0x8000 : 0);
591 break;
592 default:
593 retval = AsyncKeyStateTable[nKey] |
594 ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
595 break;
598 /* all states to false */
599 memset( AsyncMouseButtonsStates, 0, sizeof(AsyncMouseButtonsStates) );
600 memset( AsyncKeyStateTable, 0, sizeof(AsyncKeyStateTable) );
602 TRACE(key, "(%x) -> %x\n", nKey, retval);
603 return retval;
606 /**********************************************************************
607 * GetAsyncKeyState (USER.249)
609 WORD WINAPI GetAsyncKeyState16(INT16 nKey)
611 return GetAsyncKeyState32(nKey);
614 /*********************************************************************
615 * CreateAcceleratorTable (USER.64)
617 HACCEL32 WINAPI CreateAcceleratorTable32A(LPACCEL32 lpaccel, INT32 cEntries) {
618 fprintf(stderr, "CreateAcceleratorTable32A Stub\n");
619 return NULL;
622 /**********************************************************************
623 * TranslateAccelerator [USER.178][USER32.551..]
625 * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP -messages
627 static BOOL32 KBD_translate_accelerator(HWND32 hWnd,LPMSG32 msg,
628 BYTE fVirt,WORD key,WORD cmd)
630 BOOL32 sendmsg = FALSE;
632 if(msg->wParam == key)
634 if (msg->message == WM_CHAR) {
635 if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )
637 TRACE(accel,"found accel for WM_CHAR: ('%c')\n",
638 msg->wParam&0xff);
639 sendmsg=TRUE;
641 } else {
642 if(fVirt & FVIRTKEY) {
643 INT32 mask = 0;
644 TRACE(accel,"found accel for virt_key %04x (scan %04x)\n",
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 TRACE(accel,", 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 TRACE(accel,"found accel for Alt-%c\n", 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 TRACE(accel,", 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 TRACE(accel,", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
734 if(mesg==0)
735 ERR(accel, " unknown reason - please report!");
737 return TRUE;
740 return FALSE;
743 INT32 WINAPI TranslateAccelerator32(HWND32 hWnd, HACCEL32 hAccel, LPMSG32 msg)
745 LPACCEL32 lpAccelTbl = (LPACCEL32)LockResource32(hAccel);
746 int i;
748 if (hAccel == 0 || msg == NULL) return 0;
749 if (msg->message != WM_KEYDOWN &&
750 msg->message != WM_KEYUP &&
751 msg->message != WM_SYSKEYDOWN &&
752 msg->message != WM_SYSKEYUP &&
753 msg->message != WM_CHAR) return 0;
755 TRACE(accel, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
756 msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
758 for (i = 0; lpAccelTbl[i].key ; i++)
759 if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
760 lpAccelTbl[i].key,lpAccelTbl[i].cmd))
761 return 1;
762 return 0;
765 INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
767 LPACCEL16 lpAccelTbl = (LPACCEL16)LockResource16(hAccel);
768 int i;
769 MSG32 msg32;
771 if (hAccel == 0 || msg == NULL) return 0;
772 if (msg->message != WM_KEYDOWN &&
773 msg->message != WM_KEYUP &&
774 msg->message != WM_SYSKEYDOWN &&
775 msg->message != WM_SYSKEYUP &&
776 msg->message != WM_CHAR) return 0;
778 TRACE(accel, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
779 msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
780 STRUCT32_MSG16to32(msg,&msg32);
783 for (i=0;lpAccelTbl[i].key;i++)
784 if (KBD_translate_accelerator(hWnd,&msg32,lpAccelTbl[i].fVirt,
785 lpAccelTbl[i].key,lpAccelTbl[i].cmd))
786 return 1;
787 return 0;
791 /******************************************************************************
792 * OemKeyScan [KEYBOARD.128][USER32.400]
794 DWORD WINAPI OemKeyScan(WORD wOemChar)
796 TRACE(keyboard,"*OemKeyScan (%d)\n",wOemChar);
798 return wOemChar;
801 /******************************************************************************
802 * VkKeyScanA [USER32.572]
804 /* VkKeyScan translates an ANSI character to a virtual-key and shift code
805 * for the current keyboard.
806 * high-order byte yields :
807 * 0 Unshifted
808 * 1 Shift
809 * 2 Ctrl
810 * 3-5 Shift-key combinations that are not used for characters
811 * 6 Ctrl-Alt
812 * 7 Ctrl-Alt-Shift
813 * I.e. : Shift = 1, Ctrl = 2, Alt = 4.
814 * FIXME : works ok except for dead chars :
815 * VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
816 * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
819 WORD WINAPI VkKeyScan32A(CHAR cChar)
821 KeyCode keycode;
822 KeySym keysym;
823 int i,index;
824 int highbyte=0;
826 /* char->keysym (same for ANSI chars) */
827 keysym=(unsigned char) cChar;/* (!) cChar is signed */
828 if (keysym<=27) keysym+=0xFF00;/*special chars : return, backspace...*/
830 keycode = TSXKeysymToKeycode(display, keysym); /* keysym -> keycode */
831 if (!keycode)
832 { /* It didn't work ... let's try with deadchar code. */
833 keycode = TSXKeysymToKeycode(display, keysym | 0xFE00);
836 TRACE(keyboard,"VkKeyScan '%c'(%#lx, %lu): got keycode %#.2x\n",
837 cChar,keysym,keysym,keycode);
839 if (keycode)
841 for (index=-1, i=0; (i<8) && (index<0); i++) /* find shift state */
842 if (TSXKeycodeToKeysym(display,keycode,i)==keysym) index=i;
843 switch (index) {
844 case -1 :
845 fprintf(stderr,"Keysym %lx not found while parsing the keycode table\n",keysym); break;
846 case 0 : break;
847 case 1 : highbyte = 0x0100; break;
848 case 2 : highbyte = 0X0600; break;
849 default : fprintf(stderr,"index %d found by XKeycodeToKeysym. please report! \n",index);
852 index : 0 adds 0x0000
853 index : 1 adds 0x0100 (shift)
854 index : ? adds 0x0200 (ctrl)
855 index : 2 adds 0x0600 (ctrl+alt)
856 index : ? adds 0x0700 (ctrl+alt+shift (used?))
859 TRACE(keyboard," ... returning %#.2x\n", keyc2vkey[keycode]+highbyte);
860 return keyc2vkey[keycode]+highbyte; /* keycode -> (keyc2vkey) vkey */
863 /******************************************************************************
864 * VkKeyScan [KEYBOARD.129]
866 WORD WINAPI VkKeyScan16(CHAR cChar)
868 return VkKeyScan32A(cChar);
871 /******************************************************************************
872 * VkKeyScanW [USER32.575]
874 WORD WINAPI VkKeyScan32W(WCHAR cChar)
876 return VkKeyScan32A((CHAR)cChar); /* FIXME: check unicode */
879 /******************************************************************************
880 * GetKeyboardType [KEYBOARD.130]
882 INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
884 return GetKeyboardType32(nTypeFlag);
887 /******************************************************************************
888 * GetKeyboardType [USER32.254]
890 INT32 WINAPI GetKeyboardType32(INT32 nTypeFlag)
892 TRACE(keyboard,"(%d)\n",nTypeFlag);
893 switch(nTypeFlag)
895 case 0: /* Keyboard type */
896 return 4; /* AT-101 */
897 break;
898 case 1: /* Keyboard Subtype */
899 return 0; /* There are no defined subtypes */
900 break;
901 case 2: /* Number of F-keys */
902 return 12; /* We're doing an 101 for now, so return 12 F-keys */
903 break;
904 default:
905 fprintf(stderr, "Unknown type on GetKeyboardType\n");
906 return 0; /* The book says 0 here, so 0 */
911 /******************************************************************************
912 * MapVirtualKeyA [USER32.382]
914 UINT32 WINAPI MapVirtualKey32A(UINT32 code, UINT32 maptype)
916 return MapVirtualKey16(code,maptype);
919 /******************************************************************************
920 * MapVirtualKeyA [USER32.384]
922 UINT32 WINAPI MapVirtualKey32W(UINT32 code, UINT32 maptype)
924 return MapVirtualKey16(code,maptype);
927 /******************************************************************************
928 * MapVirtualKeyA [KEYBOARD.131]
929 * MapVirtualKey translates keycodes from one format to another
931 UINT16 WINAPI MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
933 #define returnMVK(value) { TRACE(keyboard,"returning 0x%x.\n",value); return value; }
935 TRACE(keyboard,"MapVirtualKey wCode=0x%x wMapType=%d ... \n",
936 wCode,wMapType);
937 switch(wMapType) {
938 case 0: { /* vkey-code to scan-code */
939 /* let's do vkey -> keycode -> scan */
940 KeyCode keyc;
941 for (keyc=min_keycode; keyc<=max_keycode; keyc++) /* see event.c */
942 if ((keyc2vkey[keyc] & 0xFF)== wCode)
943 returnMVK (keyc - 8);
944 return 0; }
946 case 1: /* scan-code to vkey-code */
947 /* let's do scan -> keycode -> vkey */
949 returnMVK (keyc2vkey[(wCode & 0xFF) + 8]);
951 case 2: { /* vkey-code to unshifted ANSI code */
952 /* (was FIXME) : what does unshifted mean ? 'a' or 'A' ? */
953 /* My Windows returns 'A'. */
954 /* let's do vkey -> keycode -> (XLookupString) ansi char */
955 XKeyEvent e;
956 KeySym keysym;
957 char s[2];
958 e.display = display;
959 e.state = 0; /* unshifted */
960 e.keycode = MapVirtualKey16( wCode, 0);
961 if (!TSXLookupString(&e, s , 2 , &keysym, NULL))
962 returnMVK (*s);
964 return 0;
966 default: /* reserved */
967 fprintf(stderr, "MapVirtualKey: unknown wMapType %d !\n",
968 wMapType);
969 return 0;
971 return 0;
975 /****************************************************************************
976 * GetKBCodePage16 (KEYBOARD.132)
978 INT16 WINAPI GetKBCodePage16(void)
980 TRACE(keyboard,"(void)\n");
981 return 850;
985 /****************************************************************************
986 * GetKBCodePage32 (USER32.245)
988 UINT32 WINAPI GetKBCodePage32(void)
990 TRACE(keyboard,"(void)\n");
991 return 850;
995 /****************************************************************************
996 * GetKeyNameText32W (USER32.247)
998 INT32 WINAPI GetKeyNameText32W(LONG lParam, LPWSTR lpBuffer, INT32 nSize)
1000 LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, nSize );
1001 int res = GetKeyNameText32A(lParam,buf,nSize);
1003 lstrcpynAtoW(lpBuffer,buf,nSize);
1004 HeapFree( GetProcessHeap(), 0, buf );
1005 return res;
1008 /****************************************************************************
1009 * GetKeyNameText32A (USER32.246)
1011 INT32 WINAPI GetKeyNameText32A(LONG lParam, LPSTR lpBuffer, INT32 nSize)
1013 return GetKeyNameText16(lParam,lpBuffer,nSize);
1016 /****************************************************************************
1017 * GetKeyNameText16 (KEYBOARD.133)
1019 INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
1021 /* int i; */
1023 TRACE(keyboard,"(%ld,<ptr>,%d)\n",lParam,nSize);
1025 lParam >>= 16;
1026 lParam &= 0xff;
1028 /* for (i = 0 ; i != KeyTableSize ; i++)
1029 if (KeyTable[i].scancode == lParam) {
1030 lstrcpyn32A( lpBuffer, KeyTable[i].name, nSize );
1031 return strlen(lpBuffer);
1034 /* FIXME ! GetKeyNameText is still to do...
1036 *lpBuffer = 0;
1037 return 0;
1041 /****************************************************************************
1042 * ToAscii (KEYBOARD.4)
1044 INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState,
1045 LPVOID lpChar, UINT16 flags)
1047 return ToAscii32(virtKey,scanCode,lpKeyState,lpChar,flags);
1050 /****************************************************************************
1051 * ToAscii (USER32.545)
1053 INT32 WINAPI ToAscii32( UINT32 virtKey,UINT32 scanCode,LPBYTE lpKeyState,
1054 LPWORD lpChar,UINT32 flags )
1056 XKeyEvent e;
1057 KeySym keysym;
1058 static XComposeStatus cs;
1059 INT32 ret;
1060 WORD keyc;
1062 e.display = display;
1063 e.keycode = 0;
1064 for (keyc=min_keycode; keyc<=max_keycode; keyc++)
1065 { /* this could be speeded up by making another table, an array of struct vkey,keycode
1066 * (vkey -> keycode) with vkeys sorted .... but it takes memory (512*3 bytes)! DF */
1067 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... */
1069 if ((e.keycode) && ((virtKey<0x10) || (virtKey>0x12)))
1070 /* it's normal to have 2 shift, control, and alt ! */
1071 TRACE(keyboard,"ToAscii : The keycodes %d and %d are matching the same vkey %#X\n",
1072 e.keycode,keyc,virtKey);
1073 e.keycode = keyc;
1076 if ((!e.keycode) && (lpKeyState[VK_NUMLOCK] & 0x01))
1078 if ((virtKey>=VK_NUMPAD0) && (virtKey<=VK_NUMPAD9))
1079 e.keycode = TSXKeysymToKeycode(e.display, virtKey-VK_NUMPAD0+XK_KP_0);
1080 if (virtKey==VK_DECIMAL)
1081 e.keycode = TSXKeysymToKeycode(e.display, XK_KP_Decimal);
1083 if (!e.keycode)
1085 fprintf(stderr,"ToAscii : Unknown virtual key %X !!! \n",virtKey);
1086 return virtKey; /* whatever */
1088 e.state = 0;
1089 if (lpKeyState[VK_SHIFT] & 0x80)
1090 e.state |= ShiftMask;
1091 TRACE(keyboard,"ToAscii : lpKeyState[0x14(VK_CAPITAL)]=%#x\n",lpKeyState[VK_CAPITAL]);
1092 if (lpKeyState[VK_CAPITAL] & 0x01)
1093 e.state |= LockMask;
1094 if (lpKeyState[VK_CONTROL] & 0x80)
1095 if (lpKeyState[VK_MENU] & 0x80)
1096 e.state |= AltGrMask;
1097 else
1098 e.state |= ControlMask;
1099 if (lpKeyState[VK_NUMLOCK] & 0x01)
1100 e.state |= NumLockMask;
1101 TRACE(key, "(%04X, %04X) : faked state = %X\n",
1102 virtKey, scanCode, e.state);
1103 ret = TSXLookupString(&e, (LPVOID)lpChar, 2, &keysym, &cs);
1104 if (ret == 0)
1106 BYTE dead_char = 0;
1108 ((char*)lpChar)[1] = '\0';
1109 switch (keysym)
1111 /* symbolic ASCII is the same as defined in rfc1345 */
1112 #ifdef XK_dead_tilde
1113 case XK_dead_tilde :
1114 #endif
1115 case 0x1000FE7E : /* Xfree's XK_Dtilde */
1116 dead_char = '~'; /* '? */
1117 break;
1118 #ifdef XK_dead_acute
1119 case XK_dead_acute :
1120 #endif
1121 case 0x1000FE27 : /* Xfree's XK_Dacute_accent */
1122 dead_char = 0xb4; /* '' */
1123 break;
1124 #ifdef XK_dead_circumflex
1125 case XK_dead_circumflex :
1126 #endif
1127 case 0x1000FE5E : /* Xfree's XK_Dcircumflex_accent */
1128 dead_char = '^'; /* '> */
1129 break;
1130 #ifdef XK_dead_grave
1131 case XK_dead_grave :
1132 #endif
1133 case 0x1000FE60 : /* Xfree's XK_Dgrave_accent */
1134 dead_char = '`'; /* '! */
1135 break;
1136 #ifdef XK_dead_diaeresis
1137 case XK_dead_diaeresis :
1138 #endif
1139 case 0x1000FE22 : /* Xfree's XK_Ddiaeresis */
1140 dead_char = 0xa8; /* ': */
1141 break;
1142 #ifdef XK_dead_cedilla
1143 case XK_dead_cedilla :
1144 dead_char = 0xb8; /* ', */
1145 break;
1146 #endif
1147 #ifdef XK_dead_macron
1148 case XK_dead_macron :
1149 dead_char = '-'; /* 'm isn't defined on iso-8859-x */
1150 break;
1151 #endif
1152 #ifdef XK_dead_breve
1153 case XK_dead_breve :
1154 dead_char = 0xa2; /* '( */
1155 break;
1156 #endif
1157 #ifdef XK_dead_abovedot
1158 case XK_dead_abovedot :
1159 dead_char = 0xff; /* '. */
1160 break;
1161 #endif
1162 #ifdef XK_dead_abovering
1163 case XK_dead_abovering :
1164 dead_char = '0'; /* '0 isn't defined on iso-8859-x */
1165 break;
1166 #endif
1167 #ifdef XK_dead_doubleacute
1168 case XK_dead_doubleacute :
1169 dead_char = 0xbd; /* '" */
1170 break;
1171 #endif
1172 #ifdef XK_dead_caron
1173 case XK_dead_caron :
1174 dead_char = 0xb7; /* '< */
1175 break;
1176 #endif
1177 #ifdef XK_dead_ogonek
1178 case XK_dead_ogonek :
1179 dead_char = 0xb2; /* '; */
1180 break;
1181 #endif
1182 /* FIXME: I don't know this three.
1183 case XK_dead_iota :
1184 dead_char = 'i';
1185 break;
1186 case XK_dead_voiced_sound :
1187 dead_char = 'v';
1188 break;
1189 case XK_dead_semivoiced_sound :
1190 dead_char = 's';
1191 break;
1194 if (dead_char)
1196 *(char*)lpChar = dead_char;
1197 ret = -1;
1199 else
1201 char *ksname;
1203 ksname = TSXKeysymToString(keysym);
1204 if (!ksname)
1205 ksname = "No Name";
1206 if ((keysym >> 8) != 0xff)
1208 fprintf(stderr, "Please report : no char for keysym %04lX (%s) :\n",
1209 keysym, ksname);
1210 fprintf(stderr, " virtKey = %X, scanCode = %X, keycode = %X, state = %X\n",
1211 virtKey, scanCode, e.keycode, e.state);
1215 TRACE(key, "ToAscii about to return %d with char %x\n",
1216 ret, *(char*)lpChar);
1217 return ret;
1221 /***********************************************************************
1222 * GetKeyboardLayout (USER32.249)
1224 HKL32 WINAPI GetKeyboardLayout(DWORD dwLayout)
1226 fprintf(stderr,"GetKeyboardLayout(%ld),STUB!\n",dwLayout);
1227 return (0xcafe<<16)|GetSystemDefaultLCID(); /* FIXME */
1230 /***********************************************************************
1231 * GetKeyboardLayoutList (USER32.250)
1232 * FIXME
1234 INT32 WINAPI GetKeyboardLayoutList(INT32 nBuff,HKL32 *layouts)
1236 fprintf(stderr,"GetKeyboardLayoutList(%d,%p),STUB!\n",nBuff,layouts);
1237 if (layouts)
1238 layouts[0] = GetKeyboardLayout(0);
1239 return 1;
1243 /***********************************************************************
1244 * RegisterHotKey (USER32.433)
1246 BOOL32 WINAPI RegisterHotKey(HWND32 hwnd,INT32 id,UINT32 modifiers,UINT32 vk) {
1247 fprintf(stderr,"RegisterHotKey(%08x,%d,%08x,%d), STUB!\n",
1248 hwnd,id,modifiers,vk
1250 return TRUE;
1253 /***********************************************************************
1254 * UnregisterHotKey (USER32.565)
1256 BOOL32 WINAPI UnregisterHotKey(HWND32 hwnd,INT32 id) {
1257 fprintf(stderr,"UnregisterHotKey(%08x,%d),stub!\n",hwnd,id);
1258 return TRUE;