2 * Keyboard related functions
4 * Copyright 1993 Bob Amstadt
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1997 David Faure
7 * Copyright 1998 Morten Welinder
14 #include <X11/keysym.h>
16 #include "ts_xresource.h"
18 #include <X11/Xatom.h>
27 #include "debugtools.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, AltGrMask; /* mask in the XKeyEvent state */
38 static int kcControl, kcAlt, kcShift, kcNumLock, kcCapsLock; /* keycodes */
39 static int min_keycode, max_keycode, keysyms_per_keycode;
40 static int keyc2vkey[256];
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;
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
109 * 0x00 -> 0x01 so that the scancode is not 0x00 unless for generated
110 * key events (e.g. down arrow when selecting a menu with Alt-letter)
111 * Lots of 0x01 here should be replaced with the actual scancode of the key
112 * but for this we have to run a spy program in Windows. - 24/Oct/98 faure@kde.org
114 const BYTE vkey2scode[512] = {
115 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x0e,0x0f,0x01,0x01,0x01,0x1c,0x01,0x01,
116 0x2a,0x1d,0x38,0x01,0x3a,0x01,0x01,0x01, 0x01,0x01,0x01,0x01/*real one*/,0x01,0x01,0x01,0x01,
117 0x39,0x49,0x51,0x4f,0x47,0x4b,0x48,0x4d, 0x50,0x01,0x01,0x01,0x01,0x52,0x53,0x01,
118 0x0b,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x01,0x01,0x01,0x01,0x01,0x01,
119 0x01,0x1e,0x30,0x2e,0x20,0x12,0x21,0x22, 0x23,0x17,0x24,0x25,0x26,0x32,0x31,0x18,
120 0x19,0x10,0x13,0x1f,0x14,0x16,0x2f,0x11, 0x2d,0x15,0x2c,0x01,0x01,0x01,0x01,0x01,
121 0x0b,0x02,0x03,0x04,0x05,0x06,0x07,0x08, 0x09,0x0a,0x37,0x4e,0x01,0x4a,0x34,0x01,
122 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
123 0x01,0x46,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
124 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
125 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
126 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x29,0x0c,0x0d,0x1a,0x1b,0x2b,
127 0x27,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
128 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x28,0x33,0x34,0x35,0x4c,
129 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
130 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
132 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x1c,0x01,0x01,
133 0x01,0x1d,0x38,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
134 0x01,0x49,0x51,0x4f,0x47,0x4b,0x48,0x4d, 0x50,0x01,0x01,0x01,0x01,0x52,0x53,0x01,
135 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
136 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
137 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
138 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x35,
139 0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42, 0x43,0x44,0x57,0x58,0x01,0x01,0x01,0x01,
140 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
141 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
142 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
143 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
144 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
145 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
146 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
147 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
150 static WORD EVENT_event_to_vkey( XKeyEvent *e)
154 TSXLookupString(e, NULL, 0, &keysym, NULL);
156 if ((keysym >= 0xFFAE) && (keysym <= 0xFFB9) && (e->state & NumLockMask))
157 /* Only the Keypad keys 0-9 and . send different keysyms
158 * depending on the NumLock state */
159 return keypad_key[(keysym & 0xFF) - 0x7E];
161 return keyc2vkey[e->keycode];
164 /**********************************************************************
167 BOOL32 KEYBOARD_Init(void)
171 XModifierKeymap *mmp;
178 TSXDisplayKeycodes(display, &min_keycode, &max_keycode);
179 ksp = TSXGetKeyboardMapping(display, min_keycode,
180 max_keycode + 1 - min_keycode, &keysyms_per_keycode);
181 /* We are only interested in keysyms_per_keycode.
182 There is no need to hold a local copy of the keysyms table */
184 mmp = TSXGetModifierMapping(display);
185 kcp = mmp->modifiermap;
186 for (i = 0; i < 8; i += 1) /* There are 8 modifier keys */
190 for (j = 0; j < mmp->max_keypermod; j += 1, kcp += 1)
195 for (k = 0; k < keysyms_per_keycode; k += 1)
196 if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Mode_switch)
199 TRACE(key, "AltGrMask is %x\n", AltGrMask);
201 else if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Num_Lock)
203 NumLockMask = 1 << i;
204 TRACE(key, "NumLockMask is %x\n", NumLockMask);
208 TSXFreeModifiermap(mmp);
210 /* Now build two conversion arrays :
211 * keycode -> vkey + extended
212 * vkey + extended -> keycode */
214 e2.display = display;
217 OEMvkey = VK_OEM_7; /* next is available. */
218 for (keyc = min_keycode; keyc <= max_keycode; keyc++)
220 e2.keycode = (KeyCode)keyc;
221 TSXLookupString(&e2, NULL, 0, &keysym, NULL);
223 if (keysym) /* otherwise, keycode not used */
225 if ((keysym >> 8) == 0xFF) /* non-character key */
227 int key = keysym & 0xff;
229 if (key >= 0x08 && key <= 0x1B) /* special key */
230 vkey = special_key[key - 0x08];
231 else if (key >= 0x50 && key <= 0x57) /* cursor key */
232 vkey = cursor_key[key - 0x50];
233 else if (key >= 0x60 && key <= 0x6B) /* miscellaneous key */
234 vkey = misc_key[key - 0x60];
235 else if (key >= 0x7E && key <= 0xB9) /* keypad key */
236 vkey = keypad_key[key - 0x7E];
237 else if (key >= 0xBE && key <= 0xCD) /* function key */
239 vkey = function_key[key - 0xBE];
240 vkey |= 0x100; /* set extended bit */
242 else if (key >= 0xE1 && key <= 0xEA) /* modifier key */
243 vkey = modifier_key[key - 0xE1];
244 else if (key == 0xFF) /* DEL key */
246 /* extended must also be set for ALT_R, CTRL_R,
247 INS, DEL, HOME, END, PAGE_UP, PAGE_DOWN, ARROW keys,
248 keypad / and keypad ENTER (SDK 3.1 Vol.3 p 138) */
249 /* FIXME should we set extended bit for NumLock ? My
250 * Windows does ... DF */
270 for (i = 0; (i < keysyms_per_keycode) && (!vkey); i++)
272 keysym = TSXLookupKeysym(&e2, i);
273 if ((keysym >= VK_0 && keysym <= VK_9)
274 || (keysym >= VK_A && keysym <= VK_Z)
275 || keysym == VK_SPACE)
279 for (i = 0; (i < keysyms_per_keycode) && (!vkey); i++)
281 keysym = TSXLookupKeysym(&e2, i);
284 case ';': vkey = VK_OEM_1; break;
285 case '/': vkey = VK_OEM_2; break;
286 case '`': vkey = VK_OEM_3; break;
287 case '[': vkey = VK_OEM_4; break;
288 case '\\': vkey = VK_OEM_5; break;
289 case ']': vkey = VK_OEM_6; break;
290 case '\'': vkey = VK_OEM_7; break;
291 case ',': vkey = VK_OEM_COMMA; break;
292 case '.': vkey = VK_OEM_PERIOD; break;
293 case '-': vkey = VK_OEM_MINUS; break;
294 case '+': vkey = VK_OEM_PLUS; break;
300 /* Others keys: let's assign OEM virtual key codes in the allowed range,
301 * that is ([0xba,0xc0], [0xdb,0xe4], 0xe6 (given up) et [0xe9,0xf5]) */
304 case 0xc1 : OEMvkey=0xdb; break;
305 case 0xe5 : OEMvkey=0xe9; break;
306 case 0xf6 : OEMvkey=0xf5; WARN(keyboard,"No more OEM vkey available!\n");
311 if (TRACE_ON(keyboard))
313 dbg_decl_str(keyboard, 1024);
315 TRACE(keyboard, "OEM specific virtual key %X assigned "
316 "to keycode %X:\n", OEMvkey, e2.keycode);
317 for (i = 0; i < keysyms_per_keycode; i += 1)
321 keysym = TSXLookupKeysym(&e2, i);
322 ksname = TSXKeysymToString(keysym);
325 dsprintf(keyboard, "%lX (%s) ", keysym, ksname);
327 TRACE(keyboard, "(%s)\n", dbg_str(keyboard));
331 keyc2vkey[e2.keycode] = vkey;
333 /* Now store one keycode for each modifier. Used to simulate keypresses. */
334 kcControl = TSXKeysymToKeycode(display, XK_Control_L);
335 kcAlt = TSXKeysymToKeycode(display, XK_Alt_L);
336 kcShift = TSXKeysymToKeycode(display, XK_Shift_L);
337 kcNumLock = TSXKeysymToKeycode(display, XK_Num_Lock);
338 kcCapsLock = TSXKeysymToKeycode(display, XK_Caps_Lock);
340 /* all states to false */
341 memset( InputKeyStateTable, 0, sizeof(InputKeyStateTable) );
346 static BOOL32 NumState=FALSE, CapsState=FALSE;
348 /**********************************************************************
349 * KEYBOARD_GenerateMsg
351 * Generate Down+Up messages when NumLock or CapsLock is pressed.
353 * Convention : called with vkey only VK_NUMLOCK or VK_CAPITAL
356 void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, INT32 event_x, INT32 event_y,
357 DWORD event_time, KEYLP localkeylp )
359 BOOL32 * State = (vkey==VK_NUMLOCK? &NumState : &CapsState);
362 /* The INTERMEDIARY state means : just after a 'press' event, if a 'release' event comes,
363 don't treat it. It's from the same key press. Then the state goes to ON.
364 And from there, a 'release' event will switch off the toggle key. */
366 TRACE(keyboard,"INTERM : don\'t treat release of toggle key. InputKeyStateTable[%#x] = %#x\n",vkey,InputKeyStateTable[vkey]);
369 if ( InputKeyStateTable[vkey] & 0x1 ) /* it was ON */
371 if (Evtype!=KeyPress)
373 TRACE(keyboard,"ON + KeyRelease => generating DOWN and UP messages.\n");
374 localkeylp.lp1.previous = 0; /* ? */
375 localkeylp.lp1.transition = 0;
376 hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2,
377 event_x, event_y, event_time, 0 );
378 hardware_event( WM_KEYUP, vkey, localkeylp.lp2,
379 event_x, event_y, event_time, 0 );
381 InputKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */
384 else /* it was OFF */
385 if (Evtype==KeyPress)
387 TRACE(keyboard,"OFF + Keypress => generating DOWN and UP messages.\n");
388 hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2,
389 event_x, event_y, event_time, 0 );
390 localkeylp.lp1.previous = 1;
391 localkeylp.lp1.transition = 1;
392 hardware_event( WM_KEYUP, vkey, localkeylp.lp2,
393 event_x, event_y, event_time, 0 );
394 *State=TRUE; /* Goes to intermediary state before going to ON */
395 InputKeyStateTable[vkey] |= 0x01; /* Toggle state to on. */
400 /***********************************************************************
401 * KEYBOARD_UpdateOneState
403 * Updates internal state for <vkey>, depending on key <state> under X
406 void KEYBOARD_UpdateOneState ( int vkey, int state, KEYLP keylp)
409 /* Do something if internal table state != X state for keycode */
410 if (((InputKeyStateTable[vkey] & 0x80)!=0) != state)
412 TRACE(keyboard,"Adjusting state for vkey %#.2x. State before %#.2x \n",
413 vkey, InputKeyStateTable[vkey]);
414 keylp.lp1.previous = !state; /* 1 if state = 0, 0 if state = 1 */
415 keylp.lp1.transition = !state;
416 if (state) { /* Fake key being pressed inside wine */
417 InputKeyStateTable[vkey] ^= 0x01;
418 InputKeyStateTable[vkey] |= 0x80;
419 message = (InputKeyStateTable[VK_MENU] & 0x80)
420 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
421 ? WM_SYSKEYDOWN : WM_KEYDOWN;
423 InputKeyStateTable[vkey] &= ~0x80;
424 message = (InputKeyStateTable[VK_MENU] & 0x80)
425 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
426 ? WM_SYSKEYUP : WM_KEYUP;
429 hardware_event( message, vkey, keylp.lp2, 0, 0,
430 GetTickCount() + MSG_WineStartTicks, 0 );
432 TRACE(keyboard,"State after %#.2x \n",InputKeyStateTable[vkey]);
436 /***********************************************************************
437 * KEYBOARD_UpdateState
439 * Update modifiers state (Ctrl, Alt, Shift)
440 * when window is activated (called by EVENT_FocusIn in event.c)
442 * This handles the case where one uses Ctrl+... Alt+... or Shift+.. to switch
443 * from wine to another application and back.
444 * Toggle keys are handled in HandleEvent. (because XQueryKeymap says nothing
447 void KEYBOARD_UpdateState ( void )
449 /* extract a bit from the char[32] bit suite */
450 #define KeyState(keycode) ((keys_return[keycode/8] & (1<<(keycode%8)))!=0)
452 char keys_return[32];
455 TRACE(keyboard,"called\n");
456 if (!TSXQueryKeymap(display, keys_return)) {
457 ERR(keyboard,"Error getting keymap !");
462 keylp.lp1.extended = 0; /* (vkey & 0x100 ? 1 : 0); */
463 keylp.lp1.win_internal = 0;
464 keylp.lp1.context = KeyState(kcAlt);/*(event->state & Mod1Mask)?1:0*/
466 /* Adjust the ALT and CONTROL state if any has been changed outside wine */
467 KEYBOARD_UpdateOneState(VK_MENU, KeyState(kcAlt), keylp);
468 KEYBOARD_UpdateOneState(VK_CONTROL, KeyState(kcControl), keylp);
469 KEYBOARD_UpdateOneState(VK_SHIFT, KeyState(kcShift), keylp);
474 /***********************************************************************
475 * KEYBOARD_HandleEvent
477 * Handle a X key event
479 void KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
486 static BOOL32 force_extended = FALSE; /* hack for AltGr translation */
490 INT32 event_x = pWnd->rectWindow.left + event->x;
491 INT32 event_y = pWnd->rectWindow.top + event->y;
492 DWORD event_time = event->time - MSG_WineStartTicks;
494 /* this allows support for dead keys */
495 if ((event->keycode >> 8) == 0x10)
496 event->keycode=(event->keycode & 0xff);
498 ascii_chars = TSXLookupString(event, Str, 1, &keysym, &cs);
500 TRACE(key, "EVENT_key : state = %X\n", event->state);
501 if (keysym == XK_Mode_switch)
503 TRACE(key, "Alt Gr key event received\n");
504 event->keycode = kcControl; /* Simulate Control */
505 KEYBOARD_HandleEvent( pWnd, event );
507 event->keycode = kcAlt; /* Simulate Alt */
508 force_extended = TRUE;
509 KEYBOARD_HandleEvent( pWnd, event );
510 force_extended = FALSE;
514 Str[ascii_chars] = '\0';
518 ksname = TSXKeysymToString(keysym);
521 TRACE(key, "%s : keysym=%lX (%s), ascii chars=%u / %X / '%s'\n",
522 (event->type == KeyPress) ? "KeyPress" : "KeyRelease",
523 keysym, ksname, ascii_chars, Str[0] & 0xff, Str);
526 vkey = EVENT_event_to_vkey(event);
527 if (force_extended) vkey |= 0x100;
529 TRACE(key, "keycode 0x%x converted to vkey 0x%x\n",
530 event->keycode, vkey);
535 keylp.lp1.code = vkey2scode[vkey]; /* 5/29/97 chrisf@america.com */
536 keylp.lp1.extended = (vkey & 0x100 ? 1 : 0);
537 keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
538 * don't remember where I read it - AK */
539 /* it's '1' under windows, when a dialog box appears
540 * and you press one of the underlined keys - DF*/
546 KEYBOARD_GenerateMsg( VK_NUMLOCK, event->type, event_x, event_y,
550 TRACE(keyboard,"Caps Lock event. (type %d). State before : %#.2x\n",event->type,InputKeyStateTable[vkey]);
551 KEYBOARD_GenerateMsg( VK_CAPITAL, event->type, event_x, event_y,
553 TRACE(keyboard,"State after : %#.2x\n",InputKeyStateTable[vkey]);
559 keylp.lp1.context = ( event->state & Mod1Mask ) ? 1 : 0; /* 1 if alt */
560 if (event->type == KeyPress)
562 keylp.lp1.previous = (InputKeyStateTable[vkey] & 0x80) != 0;
563 if (!(InputKeyStateTable[vkey] & 0x80))
564 InputKeyStateTable[vkey] ^= 0x01;
565 InputKeyStateTable[vkey] |= 0x80;
566 keylp.lp1.transition = 0;
567 message = (InputKeyStateTable[VK_MENU] & 0x80)
568 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
569 ? WM_SYSKEYDOWN : WM_KEYDOWN;
573 BOOL32 sysKey = (InputKeyStateTable[VK_MENU] & 0x80)
574 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
575 && (force_extended == FALSE); /* for Alt from AltGr */
577 InputKeyStateTable[vkey] &= ~0x80;
578 keylp.lp1.previous = 1;
579 keylp.lp1.transition = 1;
580 message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
582 /* Adjust the NUMLOCK state if it has been changed outside wine */
583 if (!(InputKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
585 TRACE(keyboard,"Adjusting NumLock state. \n");
586 KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyPress, event_x, event_y,
588 KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyRelease, event_x, event_y,
591 /* Adjust the CAPSLOCK state if it has been changed outside wine */
592 if (!(InputKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
594 TRACE(keyboard,"Adjusting Caps Lock state.\n");
595 KEYBOARD_GenerateMsg( VK_CAPITAL, KeyPress, event_x, event_y,
597 KEYBOARD_GenerateMsg( VK_CAPITAL, KeyRelease, event_x, event_y,
600 /* Not Num nor Caps : end of intermediary states for both. */
604 TRACE(key," wParam=%04X, lParam=%08lX\n",
606 TRACE(key," InputKeyState=%X\n",
607 InputKeyStateTable[vkey]);
609 hardware_event( message, vkey, keylp.lp2,
610 event_x, event_y, event_time, 0 );
617 /**********************************************************************
618 * GetKeyState (USER.106)
620 WORD WINAPI GetKeyState16(INT16 vkey)
622 return GetKeyState32(vkey);
625 /**********************************************************************
626 * GetKeyState (USER32.249)
628 * An application calls the GetKeyState function in response to a
629 * keyboard-input message. This function retrieves the state of the key
630 * at the time the input message was generated. (SDK 3.1 Vol 2. p 390)
632 WORD WINAPI GetKeyState32(INT32 vkey)
638 case VK_LBUTTON : /* VK_LBUTTON is 1 */
639 retval = MouseButtonsStates[0] ? 0x8000 : 0;
641 case VK_MBUTTON : /* VK_MBUTTON is 4 */
642 retval = MouseButtonsStates[1] ? 0x8000 : 0;
644 case VK_RBUTTON : /* VK_RBUTTON is 2 */
645 retval = MouseButtonsStates[2] ? 0x8000 : 0;
648 if (vkey >= 'a' && vkey <= 'z')
650 retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
651 (WORD)(QueueKeyStateTable[vkey] & 0x01);
653 /* TRACE(key, "(0x%x) -> %x\n", vkey, retval); */
657 /**********************************************************************
658 * GetKeyboardState (USER.222)(USER32.254)
660 * An application calls the GetKeyboardState function in response to a
661 * keyboard-input message. This function retrieves the state of the keyboard
662 * at the time the input message was generated. (SDK 3.1 Vol 2. p 387)
664 VOID WINAPI GetKeyboardState(LPBYTE lpKeyState)
666 TRACE(key, "(%p)\n", lpKeyState);
667 if (lpKeyState != NULL) {
668 QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
669 QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
670 QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
671 memcpy(lpKeyState, QueueKeyStateTable, 256);
675 /**********************************************************************
676 * SetKeyboardState (USER.223)(USER32.484)
678 VOID WINAPI SetKeyboardState(LPBYTE lpKeyState)
680 TRACE(key, "(%p)\n", lpKeyState);
681 if (lpKeyState != NULL) {
682 memcpy(QueueKeyStateTable, lpKeyState, 256);
683 MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0);
684 MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0);
685 MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0);
689 /**********************************************************************
690 * GetAsyncKeyState32 (USER32.207)
692 * Determine if a key is or was pressed. retval has high-order
693 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
696 * This uses the variable AsyncMouseButtonsStates and
697 * AsyncKeyStateTable (set in event.c) which have the mouse button
698 * number or key number (whichever is applicable) set to true if the
699 * mouse or key had been depressed since the last call to
702 WORD WINAPI GetAsyncKeyState32(INT32 nKey)
708 retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) |
709 (MouseButtonsStates[0] ? 0x8000 : 0);
712 retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) |
713 (MouseButtonsStates[1] ? 0x8000 : 0);
716 retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) |
717 (MouseButtonsStates[2] ? 0x8000 : 0);
720 retval = AsyncKeyStateTable[nKey] |
721 ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
725 /* all states to false */
726 memset( AsyncMouseButtonsStates, 0, sizeof(AsyncMouseButtonsStates) );
727 memset( AsyncKeyStateTable, 0, sizeof(AsyncKeyStateTable) );
729 TRACE(key, "(%x) -> %x\n", nKey, retval);
733 /**********************************************************************
734 * GetAsyncKeyState16 (USER.249)
736 WORD WINAPI GetAsyncKeyState16(INT16 nKey)
738 return GetAsyncKeyState32(nKey);
741 /**********************************************************************
742 * KBD_translate_accelerator
744 * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP -messages
746 static BOOL32 KBD_translate_accelerator(HWND32 hWnd,LPMSG32 msg,
747 BYTE fVirt,WORD key,WORD cmd)
749 BOOL32 sendmsg = FALSE;
751 if(msg->wParam == key)
753 if (msg->message == WM_CHAR) {
754 if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )
756 TRACE(accel,"found accel for WM_CHAR: ('%c')\n",
761 if(fVirt & FVIRTKEY) {
763 TRACE(accel,"found accel for virt_key %04x (scan %04x)\n",
764 msg->wParam,0xff & HIWORD(msg->lParam));
765 if(GetKeyState32(VK_SHIFT) & 0x8000) mask |= FSHIFT;
766 if(GetKeyState32(VK_CONTROL) & 0x8000) mask |= FCONTROL;
767 if(GetKeyState32(VK_MENU) & 0x8000) mask |= FALT;
768 if(mask == (fVirt & (FSHIFT | FCONTROL | FALT)))
771 TRACE(accel,", but incorrect SHIFT/CTRL/ALT-state\n");
775 if (!(msg->lParam & 0x01000000)) /* no special_key */
777 if ((fVirt & FALT) && (msg->lParam & 0x20000000))
778 { /* ^^ ALT pressed */
779 TRACE(accel,"found accel for Alt-%c\n", msg->wParam&0xff);
786 if (sendmsg) /* found an accelerator, but send a message... ? */
788 INT16 iSysStat,iStat,mesg=0;
791 if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
797 if (!IsWindowEnabled32(hWnd))
801 WND* wndPtr = WIN_FindWndPtr(hWnd);
803 hMenu = (wndPtr->dwStyle & WS_CHILD) ? 0 : (HMENU32)wndPtr->wIDmenu;
804 iSysStat = (wndPtr->hSysMenu) ? GetMenuState32(GetSubMenu16(wndPtr->hSysMenu, 0),
805 cmd, MF_BYCOMMAND) : -1 ;
806 iStat = (hMenu) ? GetMenuState32(hMenu,
807 cmd, MF_BYCOMMAND) : -1 ;
811 if (iSysStat & (MF_DISABLED|MF_GRAYED))
820 if (IsIconic32(hWnd))
824 if (iStat & (MF_DISABLED|MF_GRAYED))
834 if ( mesg==WM_COMMAND || mesg==WM_SYSCOMMAND )
836 TRACE(accel,", sending %s, wParam=%0x\n",
837 mesg==WM_COMMAND ? "WM_COMMAND" : "WM_SYSCOMMAND",
839 SendMessage32A(hWnd, mesg, cmd, 0x00010000L);
843 /* some reasons for NOT sending the WM_{SYS}COMMAND message:
844 * #0: unknown (please report!)
845 * #1: for WM_KEYUP,WM_SYSKEYUP
846 * #2: mouse is captured
847 * #3: window is disabled
848 * #4: it's a disabled system menu option
849 * #5: it's a menu option, but window is iconic
850 * #6: it's a menu option, but disabled
852 TRACE(accel,", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
854 ERR(accel, " unknown reason - please report!");
862 /**********************************************************************
863 * TranslateAccelerator32 (USER32.551)(USER32.552)(USER32.553)
865 INT32 WINAPI TranslateAccelerator32(HWND32 hWnd, HACCEL32 hAccel, LPMSG32 msg)
867 LPACCEL32 lpAccelTbl = (LPACCEL32)LockResource32(hAccel);
870 TRACE(accel,"hwnd=0x%x hacc=0x%x msg=0x%x wp=0x%x lp=0x%lx\n", hWnd, hAccel, msg->message, msg->wParam, msg->lParam);
872 if (hAccel == 0 || msg == NULL ||
873 (msg->message != WM_KEYDOWN &&
874 msg->message != WM_KEYUP &&
875 msg->message != WM_SYSKEYDOWN &&
876 msg->message != WM_SYSKEYUP &&
877 msg->message != WM_CHAR)) {
878 WARN(accel, "erraneous input parameters\n");
879 SetLastError(ERROR_INVALID_PARAMETER);
883 TRACE(accel, "TranslateAccelerators hAccel=%04x, hWnd=%04x,"
884 "msg->hwnd=%04x, msg->message=%04x\n",
885 hAccel,hWnd,msg->hwnd,msg->message);
890 if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
891 lpAccelTbl[i].key,lpAccelTbl[i].cmd))
893 } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
894 WARN(accel, "couldn't translate accelerator key");
898 /**********************************************************************
899 * TranslateAccelerator16 (USER.178)
901 INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
903 LPACCEL16 lpAccelTbl = (LPACCEL16)LockResource16(hAccel);
907 if (hAccel == 0 || msg == NULL ||
908 (msg->message != WM_KEYDOWN &&
909 msg->message != WM_KEYUP &&
910 msg->message != WM_SYSKEYDOWN &&
911 msg->message != WM_SYSKEYUP &&
912 msg->message != WM_CHAR)) {
913 WARN(accel, "erraneous input parameters\n");
914 SetLastError(ERROR_INVALID_PARAMETER);
918 TRACE(accel, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
919 msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
920 STRUCT32_MSG16to32(msg,&msg32);
926 if (KBD_translate_accelerator(hWnd,&msg32,lpAccelTbl[i].fVirt,
927 lpAccelTbl[i].key,lpAccelTbl[i].cmd))
929 } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
930 WARN(accel, "couldn't translate accelerator key");
935 /**********************************************************************
936 * ScreenSwitchEnable (KEYBOARD.100)
938 VOID WINAPI ScreenSwitchEnable(WORD unused)
940 FIXME(keyboard,"(%04x): stub\n",unused);
943 /**********************************************************************
944 * OemKeyScan (KEYBOARD.128)(USER32.401)
946 DWORD WINAPI OemKeyScan(WORD wOemChar)
948 TRACE(keyboard,"*OemKeyScan (%d)\n",wOemChar);
953 /**********************************************************************
954 * VkKeyScanA (USER32.573)
956 /* VkKeyScan translates an ANSI character to a virtual-key and shift code
957 * for the current keyboard.
958 * high-order byte yields :
962 * 3-5 Shift-key combinations that are not used for characters
965 * I.e. : Shift = 1, Ctrl = 2, Alt = 4.
966 * FIXME : works ok except for dead chars :
967 * VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
968 * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
971 WORD WINAPI VkKeyScan32A(CHAR cChar)
978 /* char->keysym (same for ANSI chars) */
979 keysym=(unsigned char) cChar;/* (!) cChar is signed */
980 if (keysym<=27) keysym+=0xFF00;/*special chars : return, backspace...*/
982 keycode = TSXKeysymToKeycode(display, keysym); /* keysym -> keycode */
984 { /* It didn't work ... let's try with deadchar code. */
985 keycode = TSXKeysymToKeycode(display, keysym | 0xFE00);
988 TRACE(keyboard,"VkKeyScan '%c'(%#lx, %lu): got keycode %#.2x\n",
989 cChar,keysym,keysym,keycode);
993 for (index=-1, i=0; (i<8) && (index<0); i++) /* find shift state */
994 if (TSXKeycodeToKeysym(display,keycode,i)==keysym) index=i;
997 WARN(keyboard,"Keysym %lx not found while parsing the keycode table\n",keysym); break;
999 case 1 : highbyte = 0x0100; break;
1000 case 2 : highbyte = 0X0600; break;
1001 default : ERR(keyboard,"index %d found by XKeycodeToKeysym. please report! \n",index);
1004 index : 0 adds 0x0000
1005 index : 1 adds 0x0100 (shift)
1006 index : ? adds 0x0200 (ctrl)
1007 index : 2 adds 0x0600 (ctrl+alt)
1008 index : ? adds 0x0700 (ctrl+alt+shift (used?))
1011 TRACE(keyboard," ... returning %#.2x\n", keyc2vkey[keycode]+highbyte);
1012 return keyc2vkey[keycode]+highbyte; /* keycode -> (keyc2vkey) vkey */
1015 /******************************************************************************
1016 * VkKeyScan [KEYBOARD.129]
1018 WORD WINAPI VkKeyScan16(CHAR cChar)
1020 return VkKeyScan32A(cChar);
1023 /******************************************************************************
1024 * VkKeyScanW (USER32.576)
1026 WORD WINAPI VkKeyScan32W(WCHAR cChar)
1028 return VkKeyScan32A((CHAR)cChar); /* FIXME: check unicode */
1031 /******************************************************************************
1032 * GetKeyboardType16 (KEYBOARD.130)
1034 INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
1036 return GetKeyboardType32(nTypeFlag);
1039 /******************************************************************************
1040 * GetKeyboardType32 (USER32.255)
1042 INT32 WINAPI GetKeyboardType32(INT32 nTypeFlag)
1044 TRACE(keyboard,"(%d)\n",nTypeFlag);
1047 case 0: /* Keyboard type */
1048 return 4; /* AT-101 */
1050 case 1: /* Keyboard Subtype */
1051 return 0; /* There are no defined subtypes */
1053 case 2: /* Number of F-keys */
1054 return 12; /* We're doing an 101 for now, so return 12 F-keys */
1057 WARN(keyboard, "Unknown type\n");
1058 return 0; /* The book says 0 here, so 0 */
1063 /******************************************************************************
1064 * MapVirtualKey32A (USER32.383)
1066 UINT32 WINAPI MapVirtualKey32A(UINT32 code, UINT32 maptype)
1068 return MapVirtualKey16(code,maptype);
1071 /******************************************************************************
1072 * MapVirtualKey32W (USER32.385)
1074 UINT32 WINAPI MapVirtualKey32W(UINT32 code, UINT32 maptype)
1076 return MapVirtualKey16(code,maptype);
1079 /******************************************************************************
1080 * MapVirtualKey16 (KEYBOARD.131)
1082 * MapVirtualKey translates keycodes from one format to another
1084 UINT16 WINAPI MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
1086 #define returnMVK(value) { TRACE(keyboard,"returning 0x%x.\n",value); return value; }
1088 TRACE(keyboard,"MapVirtualKey wCode=0x%x wMapType=%d ... \n",
1091 case 0: { /* vkey-code to scan-code */
1092 /* let's do vkey -> keycode -> scan */
1094 for (keyc=min_keycode; keyc<=max_keycode; keyc++) /* see event.c */
1095 if ((keyc2vkey[keyc] & 0xFF)== wCode)
1096 returnMVK (keyc - 8);
1099 case 1: /* scan-code to vkey-code */
1100 /* let's do scan -> keycode -> vkey */
1102 returnMVK (keyc2vkey[(wCode & 0xFF) + 8]);
1104 case 2: { /* vkey-code to unshifted ANSI code */
1105 /* (was FIXME) : what does unshifted mean ? 'a' or 'A' ? */
1106 /* My Windows returns 'A'. */
1107 /* let's do vkey -> keycode -> (XLookupString) ansi char */
1111 e.display = display;
1112 e.state = 0; /* unshifted */
1113 e.keycode = MapVirtualKey16( wCode, 0);
1114 if (!TSXLookupString(&e, s , 2 , &keysym, NULL))
1119 default: /* reserved */
1120 WARN(keyboard, "Unknown wMapType %d !\n",
1128 /****************************************************************************
1129 * GetKBCodePage16 (KEYBOARD.132)
1131 INT16 WINAPI GetKBCodePage16(void)
1133 TRACE(keyboard,"(void)\n");
1138 /****************************************************************************
1139 * GetKBCodePage32 (USER32.246)
1141 UINT32 WINAPI GetKBCodePage32(void)
1143 TRACE(keyboard,"(void)\n");
1147 /****************************************************************************
1148 * GetKeyboardLayoutName32A (USER32.252)
1150 INT32 WINAPI GetKeyboardLayoutName32A(LPSTR pwszKLID)
1152 return GetKeyboardLayoutName16(pwszKLID);
1155 /****************************************************************************
1156 * GetKeyboardLayoutName32W (USER32.253)
1158 INT32 WINAPI GetKeyboardLayoutName32W(LPWSTR pwszKLID)
1160 LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, strlen("00000409")+1);
1161 int res = GetKeyboardLayoutName32A(buf);
1162 lstrcpyAtoW(pwszKLID,buf);
1163 HeapFree( GetProcessHeap(), 0, buf );
1167 /****************************************************************************
1168 * GetKeyboardLayoutName16 (USER.477)
1170 INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID)
1172 FIXME(keyboard,"always returns primary U.S. English layout\n");
1173 strcpy(pwszKLID,"00000409");
1177 /****************************************************************************
1178 * GetKeyNameText32A (USER32.247)
1180 INT32 WINAPI GetKeyNameText32A(LONG lParam, LPSTR lpBuffer, INT32 nSize)
1182 return GetKeyNameText16(lParam,lpBuffer,nSize);
1185 /****************************************************************************
1186 * GetKeyNameText32W (USER32.248)
1188 INT32 WINAPI GetKeyNameText32W(LONG lParam, LPWSTR lpBuffer, INT32 nSize)
1190 LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, nSize );
1191 int res = GetKeyNameText32A(lParam,buf,nSize);
1193 lstrcpynAtoW(lpBuffer,buf,nSize);
1194 HeapFree( GetProcessHeap(), 0, buf );
1199 /****************************************************************************
1200 * GetKeyNameText16 (KEYBOARD.133)
1202 INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
1206 TRACE(keyboard,"(%ld,<ptr>,%d)\n",lParam,nSize);
1211 /* for (i = 0 ; i != KeyTableSize ; i++)
1212 if (KeyTable[i].scancode == lParam) {
1213 lstrcpyn32A( lpBuffer, KeyTable[i].name, nSize );
1214 return strlen(lpBuffer);
1217 /* FIXME ! GetKeyNameText is still to do...
1224 /****************************************************************************
1225 * ToAscii (KEYBOARD.4)
1227 INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState,
1228 LPVOID lpChar, UINT16 flags)
1230 return ToAscii32(virtKey,scanCode,lpKeyState,lpChar,flags);
1233 /****************************************************************************
1234 * ToAscii32 (USER32.546)
1236 INT32 WINAPI ToAscii32( UINT32 virtKey,UINT32 scanCode,LPBYTE lpKeyState,
1237 LPWORD lpChar,UINT32 flags )
1241 static XComposeStatus cs;
1246 /* This happens when doing Alt+letter : a fake 'down arrow' key press
1247 event is generated by windows. Just ignore it. */
1248 TRACE(keyboard,"scanCode=0, doing nothing\n");
1251 e.display = display;
1254 if (lpKeyState[VK_SHIFT] & 0x80)
1255 e.state |= ShiftMask;
1256 if (lpKeyState[VK_CAPITAL] & 0x01)
1257 e.state |= LockMask;
1258 if (lpKeyState[VK_CONTROL] & 0x80)
1260 if (lpKeyState[VK_MENU] & 0x80)
1261 e.state |= AltGrMask;
1263 e.state |= ControlMask;
1265 if (lpKeyState[VK_NUMLOCK] & 0x01)
1266 e.state |= NumLockMask;
1267 TRACE(key, "(%04X, %04X) : faked state = %X\n",
1268 virtKey, scanCode, e.state);
1269 /* We exit on the first keycode found, to speed up the thing. */
1270 for (keyc=min_keycode; (keyc<=max_keycode) && (!e.keycode) ; keyc++)
1271 { /* Find a keycode that could have generated this virtual key */
1272 if ((keyc2vkey[keyc] & 0xFF) == virtKey)
1273 { /* we can filter the extended bit, VK* are different enough... */
1274 e.keycode = keyc; /* Store it temporarily */
1275 if (EVENT_event_to_vkey(&e) != virtKey)
1276 e.keycode = 0; /* Wrong one (ex: because of the NumLock
1277 state), so set it to 0, we'll find another one */
1280 if ((!e.keycode) && (lpKeyState[VK_NUMLOCK] & 0x01))
1282 if ((virtKey>=VK_NUMPAD0) && (virtKey<=VK_NUMPAD9))
1283 e.keycode = TSXKeysymToKeycode(e.display, virtKey-VK_NUMPAD0+XK_KP_0);
1284 if (virtKey==VK_DECIMAL)
1285 e.keycode = TSXKeysymToKeycode(e.display, XK_KP_Decimal);
1289 WARN(keyboard,"Unknown virtual key %X !!! \n",virtKey);
1290 return virtKey; /* whatever */
1292 ret = TSXLookupString(&e, (LPVOID)lpChar, 2, &keysym, &cs);
1297 ((char*)lpChar)[1] = '\0';
1300 /* symbolic ASCII is the same as defined in rfc1345 */
1301 #ifdef XK_dead_tilde
1302 case XK_dead_tilde :
1304 case 0x1000FE7E : /* Xfree's XK_Dtilde */
1305 dead_char = '~'; /* '? */
1307 #ifdef XK_dead_acute
1308 case XK_dead_acute :
1310 case 0x1000FE27 : /* Xfree's XK_Dacute_accent */
1311 dead_char = 0xb4; /* '' */
1313 #ifdef XK_dead_circumflex
1314 case XK_dead_circumflex :
1316 case 0x1000FE5E : /* Xfree's XK_Dcircumflex_accent */
1317 dead_char = '^'; /* '> */
1319 #ifdef XK_dead_grave
1320 case XK_dead_grave :
1322 case 0x1000FE60 : /* Xfree's XK_Dgrave_accent */
1323 dead_char = '`'; /* '! */
1325 #ifdef XK_dead_diaeresis
1326 case XK_dead_diaeresis :
1328 case 0x1000FE22 : /* Xfree's XK_Ddiaeresis */
1329 dead_char = 0xa8; /* ': */
1331 #ifdef XK_dead_cedilla
1332 case XK_dead_cedilla :
1333 dead_char = 0xb8; /* ', */
1336 #ifdef XK_dead_macron
1337 case XK_dead_macron :
1338 dead_char = '-'; /* 'm isn't defined on iso-8859-x */
1341 #ifdef XK_dead_breve
1342 case XK_dead_breve :
1343 dead_char = 0xa2; /* '( */
1346 #ifdef XK_dead_abovedot
1347 case XK_dead_abovedot :
1348 dead_char = 0xff; /* '. */
1351 #ifdef XK_dead_abovering
1352 case XK_dead_abovering :
1353 dead_char = '0'; /* '0 isn't defined on iso-8859-x */
1356 #ifdef XK_dead_doubleacute
1357 case XK_dead_doubleacute :
1358 dead_char = 0xbd; /* '" */
1361 #ifdef XK_dead_caron
1362 case XK_dead_caron :
1363 dead_char = 0xb7; /* '< */
1366 #ifdef XK_dead_ogonek
1367 case XK_dead_ogonek :
1368 dead_char = 0xb2; /* '; */
1371 /* FIXME: I don't know this three.
1375 case XK_dead_voiced_sound :
1378 case XK_dead_semivoiced_sound :
1385 *(char*)lpChar = dead_char;
1392 ksname = TSXKeysymToString(keysym);
1395 if ((keysym >> 8) != 0xff)
1397 ERR(keyboard, "Please report: no char for keysym %04lX (%s) :\n",
1399 ERR(keyboard, "(virtKey=%X,scanCode=%X,keycode=%X,state=%X)\n",
1400 virtKey, scanCode, e.keycode, e.state);
1404 TRACE(key, "ToAscii about to return %d with char %x\n",
1405 ret, *(char*)lpChar);
1410 /***********************************************************************
1411 * GetKeyboardLayout (USER32.250)
1413 HKL32 WINAPI GetKeyboardLayout(DWORD dwLayout)
1415 FIXME(keyboard,"(%ld): stub\n",dwLayout);
1416 return (0xcafe<<16)|GetSystemDefaultLCID(); /* FIXME */
1419 /***********************************************************************
1420 * GetKeyboardLayoutList (USER32.251)
1423 INT32 WINAPI GetKeyboardLayoutList(INT32 nBuff,HKL32 *layouts)
1425 FIXME(keyboard,"(%d,%p): stub\n",nBuff,layouts);
1427 layouts[0] = GetKeyboardLayout(0);
1432 /***********************************************************************
1433 * RegisterHotKey (USER32.433)
1435 BOOL32 WINAPI RegisterHotKey(HWND32 hwnd,INT32 id,UINT32 modifiers,UINT32 vk) {
1436 FIXME(keyboard,"(0x%08x,%d,0x%08x,%d): stub\n",hwnd,id,modifiers,vk);
1440 /***********************************************************************
1441 * UnregisterHotKey (USER32.565)
1443 BOOL32 WINAPI UnregisterHotKey(HWND32 hwnd,INT32 id) {
1444 FIXME(keyboard,"(0x%08x,%d): stub\n",hwnd,id);
1448 /***********************************************************************
1449 * KeyboardInquire (KEYBOARD.1)
1453 typedef struct _KBINFO
1455 BYTE Begin_First_Range;
1456 BYTE End_First_Range;
1457 BYTE Begin_Second_Range;
1458 BYTE End_Second_Range;
1463 WORD WINAPI KeyboardInquire(KBINFO *kbInfo)
1465 kbInfo->Begin_First_Range = 0;
1466 kbInfo->End_First_Range = 0;
1467 kbInfo->Begin_Second_Range = 0;
1468 kbInfo->End_Second_Range = 0;
1469 kbInfo->StateSize = 16;
1471 return sizeof(KBINFO);
1474 /***********************************************************************
1475 * KeyboardEnable (KEYBOARD.2)
1477 VOID WINAPI KeyboardEnable(FARPROC16 eventProc, LPBYTE lpKeyState)
1479 FIXME(keyboard, "(%08lx,%08lx): stub\n",
1480 (DWORD)eventProc, (DWORD)lpKeyState);
1483 /***********************************************************************
1484 * KeyboardDisable (KEYBOARD.3)
1486 VOID WINAPI KeyboardDisable(VOID)
1488 FIXME(keyboard, "(): stub\n");
1492 /***********************************************************************
1493 * DisplayInquire (DISPLAY.101)
1497 typedef struct _CURSORINFO
1504 WORD WINAPI DisplayInquire(CURSORINFO *cursorInfo)
1506 cursorInfo->wXMickeys = 1;
1507 cursorInfo->wYMickeys = 1;
1509 return sizeof(CURSORINFO);
1512 /***********************************************************************
1513 * DisplaySetCursor (DISPLAY.102)
1515 VOID WINAPI DisplaySetCursor( LPVOID cursorShape )
1517 FIXME(keyboard, "(%p): stub\n", cursorShape );
1520 /***********************************************************************
1521 * DisplayMoveCursor (DISPLAY.103)
1523 VOID WINAPI DisplayMoveCursor( WORD wAbsX, WORD wAbsY )
1525 FIXME(keyboard, "(%d,%d): stub\n", wAbsX, wAbsY );
1528 /***********************************************************************
1529 * UserRepaintDisable (DISPLAY.103)
1531 VOID WINAPI UserRepaintDisable( BOOL16 disable )
1533 FIXME(keyboard, "(%d): stub\n", disable);