For drawing a caret, internally replaced the brush by a bitmap (this
[wine/wine-kai.git] / windows / input.c
blob702e33445aedd1f986cca38c62e57ef3b1f7c382
1 /*
2 * USER Input processing
4 * Copyright 1993 Bob Amstadt
5 * Copyright 1996 Albrecht Kleine
6 * Copyright 1997 David Faure
7 * Copyright 1998 Morten Welinder
8 * Copyright 1998 Ulrich Weigand
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <ctype.h>
16 #include <assert.h>
18 #include "windef.h"
19 #include "winnls.h"
20 #include "winbase.h"
21 #include "wingdi.h"
22 #include "winuser.h"
23 #include "wine/winbase16.h"
24 #include "wine/winuser16.h"
25 #include "wine/server.h"
26 #include "win.h"
27 #include "hook.h"
28 #include "input.h"
29 #include "message.h"
30 #include "queue.h"
31 #include "debugtools.h"
32 #include "winerror.h"
34 DECLARE_DEBUG_CHANNEL(key);
35 DECLARE_DEBUG_CHANNEL(keyboard);
36 DECLARE_DEBUG_CHANNEL(win);
37 DEFAULT_DEBUG_CHANNEL(event);
39 static BOOL InputEnabled = TRUE;
40 static BOOL SwappedButtons;
42 BYTE InputKeyStateTable[256];
43 BYTE AsyncKeyStateTable[256];
45 /* Storage for the USER-maintained mouse positions */
46 static DWORD PosX, PosY;
48 typedef union
50 struct
52 unsigned long count : 16;
53 unsigned long code : 8;
54 unsigned long extended : 1;
55 unsigned long unused : 2;
56 unsigned long win_internal : 2;
57 unsigned long context : 1;
58 unsigned long previous : 1;
59 unsigned long transition : 1;
60 } lp1;
61 unsigned long lp2;
62 } KEYLP;
65 /***********************************************************************
66 * get_key_state
68 static WORD get_key_state(void)
70 WORD ret = 0;
72 if (SwappedButtons)
74 if (InputKeyStateTable[VK_RBUTTON] & 0x80) ret |= MK_LBUTTON;
75 if (InputKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_RBUTTON;
77 else
79 if (InputKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_LBUTTON;
80 if (InputKeyStateTable[VK_RBUTTON] & 0x80) ret |= MK_RBUTTON;
82 if (InputKeyStateTable[VK_MBUTTON] & 0x80) ret |= MK_MBUTTON;
83 if (InputKeyStateTable[VK_SHIFT] & 0x80) ret |= MK_SHIFT;
84 if (InputKeyStateTable[VK_CONTROL] & 0x80) ret |= MK_CONTROL;
85 if (InputKeyStateTable[VK_XBUTTON1] & 0x80) ret |= MK_XBUTTON1;
86 if (InputKeyStateTable[VK_XBUTTON2] & 0x80) ret |= MK_XBUTTON2;
87 return ret;
91 /***********************************************************************
92 * queue_raw_hardware_message
94 * Add a message to the raw hardware queue.
95 * Note: the position is relative to the desktop window.
97 static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lParam,
98 int xPos, int yPos, DWORD time, ULONG_PTR extraInfo )
100 SERVER_START_REQ( send_message )
102 req->id = (void *)GetCurrentThreadId();
103 req->type = MSG_HARDWARE_RAW;
104 req->win = 0;
105 req->msg = message;
106 req->wparam = wParam;
107 req->lparam = lParam;
108 req->x = xPos;
109 req->y = yPos;
110 req->time = time;
111 req->info = extraInfo;
112 req->timeout = 0;
113 SERVER_CALL();
115 SERVER_END_REQ;
119 /***********************************************************************
120 * queue_kbd_event
122 * Put a keyboard event into a thread queue
124 static void queue_kbd_event( const KEYBDINPUT *ki, UINT injected_flags )
126 UINT message;
127 KEYLP keylp;
128 KBDLLHOOKSTRUCT hook;
130 keylp.lp2 = 0;
131 keylp.lp1.count = 1;
132 keylp.lp1.code = ki->wScan;
133 keylp.lp1.extended = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) != 0;
134 keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
135 * don't remember where I read it - AK */
136 /* it's '1' under windows, when a dialog box appears
137 * and you press one of the underlined keys - DF*/
139 if (ki->dwFlags & KEYEVENTF_KEYUP )
141 BOOL sysKey = (InputKeyStateTable[VK_MENU] & 0x80) &&
142 !(InputKeyStateTable[VK_CONTROL] & 0x80);
143 InputKeyStateTable[ki->wVk] &= ~0x80;
144 keylp.lp1.previous = 1;
145 keylp.lp1.transition = 1;
146 message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
148 else
150 keylp.lp1.previous = (InputKeyStateTable[ki->wVk] & 0x80) != 0;
151 keylp.lp1.transition = 0;
152 if (!(InputKeyStateTable[ki->wVk] & 0x80)) InputKeyStateTable[ki->wVk] ^= 0x01;
153 InputKeyStateTable[ki->wVk] |= 0x80;
154 AsyncKeyStateTable[ki->wVk] |= 0x80;
156 message = (InputKeyStateTable[VK_MENU] & 0x80) && !(InputKeyStateTable[VK_CONTROL] & 0x80)
157 ? WM_SYSKEYDOWN : WM_KEYDOWN;
160 if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP )
161 keylp.lp1.context = (InputKeyStateTable[VK_MENU] & 0x80) != 0; /* 1 if alt */
163 TRACE_(key)(" wParam=%04x, lParam=%08lx, InputKeyState=%x\n",
164 ki->wVk, keylp.lp2, InputKeyStateTable[ki->wVk] );
166 hook.vkCode = ki->wVk;
167 hook.scanCode = ki->wScan;
168 hook.flags = (keylp.lp2 >> 24) | injected_flags;
169 hook.time = ki->time;
170 hook.dwExtraInfo = ki->dwExtraInfo;
171 if (!HOOK_CallHooksW( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook ))
172 queue_raw_hardware_message( message, ki->wVk, keylp.lp2,
173 PosX, PosY, ki->time, ki->dwExtraInfo );
177 /***********************************************************************
178 * queue_raw_mouse_message
180 static void queue_raw_mouse_message( UINT message, UINT flags, INT x, INT y, const MOUSEINPUT *mi )
182 MSLLHOOKSTRUCT hook;
184 hook.pt.x = x;
185 hook.pt.y = y;
186 hook.mouseData = MAKELONG( 0, mi->mouseData );
187 hook.flags = flags;
188 hook.time = mi->time;
189 hook.dwExtraInfo = mi->dwExtraInfo;
191 if (!HOOK_CallHooksW( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook ))
192 queue_raw_hardware_message( message, MAKEWPARAM( get_key_state(), mi->mouseData ),
193 0, x, y, mi->time, mi->dwExtraInfo );
197 /***********************************************************************
198 * queue_mouse_event
200 static void queue_mouse_event( const MOUSEINPUT *mi, UINT flags )
202 if (mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
204 PosX = (mi->dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
205 PosY = (mi->dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
207 else if (mi->dwFlags & MOUSEEVENTF_MOVE)
209 int width = GetSystemMetrics(SM_CXSCREEN);
210 int height = GetSystemMetrics(SM_CYSCREEN);
211 long posX = (long) PosX, posY = (long) PosY;
213 /* dx and dy can be negative numbers for relative movements */
214 posX += (long)mi->dx;
215 posY += (long)mi->dy;
217 /* Clip to the current screen size */
218 if (posX < 0) PosX = 0;
219 else if (posX >= width) PosX = width - 1;
220 else PosX = posX;
222 if (posY < 0) PosY = 0;
223 else if (posY >= height) PosY = height - 1;
224 else PosY = posY;
227 if (mi->dwFlags & MOUSEEVENTF_MOVE)
229 queue_raw_mouse_message( WM_MOUSEMOVE, flags, PosX, PosY, mi );
231 if (mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
233 InputKeyStateTable[VK_LBUTTON] |= 0x80;
234 AsyncKeyStateTable[VK_LBUTTON] |= 0x80;
235 queue_raw_mouse_message( SwappedButtons ? WM_RBUTTONDOWN : WM_LBUTTONDOWN,
236 flags, PosX, PosY, mi );
238 if (mi->dwFlags & MOUSEEVENTF_LEFTUP)
240 InputKeyStateTable[VK_LBUTTON] &= ~0x80;
241 queue_raw_mouse_message( SwappedButtons ? WM_RBUTTONUP : WM_LBUTTONUP,
242 flags, PosX, PosY, mi );
244 if (mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
246 InputKeyStateTable[VK_RBUTTON] |= 0x80;
247 AsyncKeyStateTable[VK_RBUTTON] |= 0x80;
248 queue_raw_mouse_message( SwappedButtons ? WM_LBUTTONDOWN : WM_RBUTTONDOWN,
249 flags, PosX, PosY, mi );
251 if (mi->dwFlags & MOUSEEVENTF_RIGHTUP)
253 InputKeyStateTable[VK_RBUTTON] &= ~0x80;
254 queue_raw_mouse_message( SwappedButtons ? WM_LBUTTONUP : WM_RBUTTONUP,
255 flags, PosX, PosY, mi );
257 if (mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
259 InputKeyStateTable[VK_MBUTTON] |= 0x80;
260 AsyncKeyStateTable[VK_MBUTTON] |= 0x80;
261 queue_raw_mouse_message( WM_MBUTTONDOWN, flags, PosX, PosY, mi );
263 if (mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
265 InputKeyStateTable[VK_MBUTTON] &= ~0x80;
266 queue_raw_mouse_message( WM_MBUTTONUP, flags, PosX, PosY, mi );
268 if (mi->dwFlags & MOUSEEVENTF_WHEEL)
270 queue_raw_mouse_message( WM_MOUSEWHEEL, flags, PosX, PosY, mi );
272 if (flags & LLMHF_INJECTED) /* we have to actually move the cursor */
273 SetCursorPos( PosX, PosY );
277 /***********************************************************************
278 * SendInput (USER32.@)
280 UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
282 UINT i;
284 if (!InputEnabled) return 0;
286 for (i = 0; i < count; i++, inputs++)
288 switch(inputs->type)
290 case INPUT_MOUSE:
291 queue_mouse_event( &inputs->u.mi, LLMHF_INJECTED );
292 break;
293 case WINE_INTERNAL_INPUT_MOUSE:
294 queue_mouse_event( &inputs->u.mi, 0 );
295 break;
296 case INPUT_KEYBOARD:
297 queue_kbd_event( &inputs->u.ki, LLKHF_INJECTED );
298 break;
299 case WINE_INTERNAL_INPUT_KEYBOARD:
300 queue_kbd_event( &inputs->u.ki, 0 );
301 break;
302 case INPUT_HARDWARE:
303 FIXME( "INPUT_HARDWARE not supported\n" );
304 break;
307 return count;
311 /***********************************************************************
312 * keybd_event (USER32.@)
314 void WINAPI keybd_event( BYTE bVk, BYTE bScan,
315 DWORD dwFlags, DWORD dwExtraInfo )
317 INPUT input;
319 input.type = INPUT_KEYBOARD;
320 input.u.ki.wVk = bVk;
321 input.u.ki.wScan = bScan;
322 input.u.ki.dwFlags = dwFlags;
323 input.u.ki.time = GetTickCount();
324 input.u.ki.dwExtraInfo = dwExtraInfo;
325 SendInput( 1, &input, sizeof(input) );
329 /***********************************************************************
330 * keybd_event (USER.289)
332 void WINAPI keybd_event16( CONTEXT86 *context )
334 DWORD dwFlags = 0;
336 if (AH_reg(context) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
337 if (BH_reg(context) & 1 ) dwFlags |= KEYEVENTF_EXTENDEDKEY;
339 keybd_event( AL_reg(context), BL_reg(context),
340 dwFlags, MAKELONG(SI_reg(context), DI_reg(context)) );
344 /***********************************************************************
345 * mouse_event (USER32.@)
347 void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
348 DWORD dwData, DWORD dwExtraInfo )
350 INPUT input;
352 input.type = INPUT_MOUSE;
353 input.u.mi.dx = dx;
354 input.u.mi.dy = dy;
355 input.u.mi.mouseData = dwData;
356 input.u.mi.dwFlags = dwFlags;
357 input.u.mi.time = GetCurrentTime();
358 input.u.mi.dwExtraInfo = dwExtraInfo;
359 SendInput( 1, &input, sizeof(input) );
363 /***********************************************************************
364 * mouse_event (USER.299)
366 void WINAPI mouse_event16( CONTEXT86 *context )
368 mouse_event( AX_reg(context), BX_reg(context), CX_reg(context),
369 DX_reg(context), MAKELONG(SI_reg(context), DI_reg(context)) );
372 /***********************************************************************
373 * GetMouseEventProc (USER.337)
375 FARPROC16 WINAPI GetMouseEventProc16(void)
377 HMODULE16 hmodule = GetModuleHandle16("USER");
378 return GetProcAddress16( hmodule, "mouse_event" );
382 /**********************************************************************
383 * EnableHardwareInput (USER.331)
385 BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
387 BOOL16 bOldState = InputEnabled;
388 FIXME_(event)("(%d) - stub\n", bEnable);
389 InputEnabled = bEnable;
390 return bOldState;
394 /***********************************************************************
395 * SwapMouseButton (USER.186)
397 BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
399 BOOL16 ret = SwappedButtons;
400 SwappedButtons = fSwap;
401 return ret;
405 /***********************************************************************
406 * SwapMouseButton (USER32.@)
408 BOOL WINAPI SwapMouseButton( BOOL fSwap )
410 BOOL ret = SwappedButtons;
411 SwappedButtons = fSwap;
412 return ret;
416 /***********************************************************************
417 * GetCursorPos (USER.17)
419 BOOL16 WINAPI GetCursorPos16( POINT16 *pt )
421 POINT pos;
422 if (!pt) return 0;
423 GetCursorPos(&pos);
424 pt->x = pos.x;
425 pt->y = pos.y;
426 return 1;
430 /***********************************************************************
431 * GetCursorPos (USER32.@)
433 BOOL WINAPI GetCursorPos( POINT *pt )
435 if (!pt) return 0;
436 pt->x = PosX;
437 pt->y = PosY;
438 if (USER_Driver.pGetCursorPos) USER_Driver.pGetCursorPos( pt );
439 return 1;
443 /***********************************************************************
444 * SetCursorPos (USER.70)
446 void WINAPI SetCursorPos16( INT16 x, INT16 y )
448 SetCursorPos( x, y );
452 /***********************************************************************
453 * SetCursorPos (USER32.@)
455 BOOL WINAPI SetCursorPos( INT x, INT y )
457 if (USER_Driver.pSetCursorPos) USER_Driver.pSetCursorPos( x, y );
458 PosX = x;
459 PosY = y;
460 return TRUE;
464 /**********************************************************************
465 * EVENT_Capture
467 * We need this to be able to generate double click messages
468 * when menu code captures mouse in the window without CS_DBLCLK style.
470 HWND EVENT_Capture(HWND hwnd, INT16 ht)
472 HWND capturePrev = 0, captureWnd = 0;
473 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
474 WND* wndPtr = 0;
475 INT16 captureHT = 0;
477 capturePrev = GetCapture();
479 if (!hwnd)
481 captureWnd = 0;
482 captureHT = 0;
484 else
486 wndPtr = WIN_FindWndPtr( hwnd );
487 if (wndPtr)
489 TRACE_(win)("(0x%04x)\n", hwnd );
490 captureWnd = wndPtr->hwndSelf;
491 captureHT = ht;
495 /* Get the messageQ for the current thread */
496 if (!(pCurMsgQ = QUEUE_Current()))
498 WARN_(win)("\tCurrent message queue not found. Exiting!\n" );
499 goto CLEANUP;
502 /* Update the perQ capture window and send messages */
503 if( capturePrev != captureWnd )
505 if (wndPtr)
507 /* Retrieve the message queue associated with this window */
508 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
509 if ( !pMsgQ )
511 WARN_(win)("\tMessage queue not found. Exiting!\n" );
512 goto CLEANUP;
515 /* Make sure that message queue for the window we are setting capture to
516 * shares the same perQ data as the current threads message queue.
518 if ( pCurMsgQ->pQData != pMsgQ->pQData )
519 goto CLEANUP;
522 PERQDATA_SetCaptureWnd( captureWnd, captureHT );
523 if (capturePrev) SendMessageA( capturePrev, WM_CAPTURECHANGED, 0, (LPARAM)hwnd );
526 CLEANUP:
527 /* Unlock the queues before returning */
528 if ( pMsgQ )
529 QUEUE_Unlock( pMsgQ );
531 WIN_ReleaseWndPtr(wndPtr);
532 return capturePrev;
536 /**********************************************************************
537 * SetCapture (USER32.@)
539 HWND WINAPI SetCapture( HWND hwnd )
541 return EVENT_Capture( hwnd, HTCLIENT );
545 /**********************************************************************
546 * ReleaseCapture (USER32.@)
548 BOOL WINAPI ReleaseCapture(void)
550 return (EVENT_Capture( 0, 0 ) != 0);
554 /**********************************************************************
555 * GetCapture (USER32.@)
557 HWND WINAPI GetCapture(void)
559 INT hittest;
560 return PERQDATA_GetCaptureWnd( &hittest );
563 /**********************************************************************
564 * GetAsyncKeyState (USER32.@)
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 GetAsyncKeyState(INT nKey)
578 WORD retval = ((AsyncKeyStateTable[nKey] & 0x80) ? 0x0001 : 0) |
579 ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
580 AsyncKeyStateTable[nKey] = 0;
581 TRACE_(key)("(%x) -> %x\n", nKey, retval);
582 return retval;
585 /**********************************************************************
586 * GetAsyncKeyState (USER.249)
588 WORD WINAPI GetAsyncKeyState16(INT16 nKey)
590 return GetAsyncKeyState(nKey);
593 /***********************************************************************
594 * IsUserIdle (USER.333)
596 BOOL16 WINAPI IsUserIdle16(void)
598 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
599 return FALSE;
601 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
602 return FALSE;
604 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
605 return FALSE;
607 /* Should check for screen saver activation here ... */
609 return TRUE;
612 /**********************************************************************
613 * VkKeyScanA (USER32.@)
615 * VkKeyScan translates an ANSI character to a virtual-key and shift code
616 * for the current keyboard.
617 * high-order byte yields :
618 * 0 Unshifted
619 * 1 Shift
620 * 2 Ctrl
621 * 3-5 Shift-key combinations that are not used for characters
622 * 6 Ctrl-Alt
623 * 7 Ctrl-Alt-Shift
624 * I.e. : Shift = 1, Ctrl = 2, Alt = 4.
625 * FIXME : works ok except for dead chars :
626 * VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
627 * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
629 WORD WINAPI VkKeyScanA(CHAR cChar)
631 return USER_Driver.pVkKeyScan( cChar );
634 /******************************************************************************
635 * VkKeyScanW (USER32.@)
637 WORD WINAPI VkKeyScanW(WCHAR cChar)
639 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
642 /**********************************************************************
643 * VkKeyScanExA (USER32.@)
645 WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
647 /* FIXME: complete workaround this is */
648 return VkKeyScanA(cChar);
651 /******************************************************************************
652 * VkKeyScanExW (USER32.@)
654 WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl)
656 /* FIXME: complete workaround this is */
657 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
660 /******************************************************************************
661 * GetKeyboardType (USER32.@)
663 INT WINAPI GetKeyboardType(INT nTypeFlag)
665 TRACE_(keyboard)("(%d)\n", nTypeFlag);
666 switch(nTypeFlag)
668 case 0: /* Keyboard type */
669 return 4; /* AT-101 */
670 case 1: /* Keyboard Subtype */
671 return 0; /* There are no defined subtypes */
672 case 2: /* Number of F-keys */
673 return 12; /* We're doing an 101 for now, so return 12 F-keys */
674 default:
675 WARN_(keyboard)("Unknown type\n");
676 return 0; /* The book says 0 here, so 0 */
680 /******************************************************************************
681 * MapVirtualKeyA (USER32.@)
683 UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
685 return USER_Driver.pMapVirtualKey( code, maptype );
688 /******************************************************************************
689 * MapVirtualKeyW (USER32.@)
691 UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype)
693 return MapVirtualKeyA(code,maptype);
696 /******************************************************************************
697 * MapVirtualKeyExA (USER32.@)
699 UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl)
701 if (hkl)
702 FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
703 return MapVirtualKeyA(code,maptype);
706 /******************************************************************************
707 * MapVirtualKeyExW (USER32.@)
709 UINT WINAPI MapVirtualKeyExW(UINT code, UINT maptype, HKL hkl)
711 if (hkl)
712 FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
713 return MapVirtualKeyA(code,maptype);
716 /****************************************************************************
717 * GetKBCodePage (USER32.@)
719 UINT WINAPI GetKBCodePage(void)
721 return GetOEMCP();
724 /****************************************************************************
725 * GetKeyboardLayoutName (USER.477)
727 INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID)
729 return GetKeyboardLayoutNameA(pwszKLID);
732 /***********************************************************************
733 * GetKeyboardLayout (USER32.@)
735 * FIXME: - device handle for keyboard layout defaulted to
736 * the language id. This is the way Windows default works.
737 * - the thread identifier (dwLayout) is also ignored.
739 HKL WINAPI GetKeyboardLayout(DWORD dwLayout)
741 HKL layout;
742 layout = GetSystemDefaultLCID(); /* FIXME */
743 layout |= (layout<<16); /* FIXME */
744 TRACE_(keyboard)("returning %08x\n",layout);
745 return layout;
748 /****************************************************************************
749 * GetKeyboardLayoutNameA (USER32.@)
751 INT WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID)
753 sprintf(pwszKLID, "%08x",GetKeyboardLayout(0));
754 return 1;
757 /****************************************************************************
758 * GetKeyboardLayoutNameW (USER32.@)
760 INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID)
762 char buf[KL_NAMELENGTH];
763 int res = GetKeyboardLayoutNameA(buf);
764 MultiByteToWideChar( CP_ACP, 0, buf, -1, pwszKLID, KL_NAMELENGTH );
765 return res;
768 /****************************************************************************
769 * GetKeyNameTextA (USER32.@)
771 INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
773 return USER_Driver.pGetKeyNameText( lParam, lpBuffer, nSize );
776 /****************************************************************************
777 * GetKeyNameTextW (USER32.@)
779 INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize)
781 int res;
782 LPSTR buf = HeapAlloc( GetProcessHeap(), 0, nSize );
783 if(buf == NULL) return 0; /* FIXME: is this the correct failure value?*/
784 res = GetKeyNameTextA(lParam,buf,nSize);
786 if (nSize > 0 && !MultiByteToWideChar( CP_ACP, 0, buf, -1, lpBuffer, nSize ))
787 lpBuffer[nSize-1] = 0;
788 HeapFree( GetProcessHeap(), 0, buf );
789 return res;
792 /****************************************************************************
793 * ToUnicode (USER32.@)
795 INT WINAPI ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
796 LPWSTR lpwStr, int size, UINT flags)
798 return USER_Driver.pToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
801 /****************************************************************************
802 * ToUnicodeEx (USER32.@)
804 INT WINAPI ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
805 LPWSTR lpwStr, int size, UINT flags, HKL hkl)
807 /* FIXME: need true implementation */
808 return ToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
811 /****************************************************************************
812 * ToAscii (USER32.@)
814 INT WINAPI ToAscii( UINT virtKey,UINT scanCode,LPBYTE lpKeyState,
815 LPWORD lpChar,UINT flags )
817 WCHAR uni_chars[2];
818 INT ret, n_ret;
820 ret = ToUnicode(virtKey, scanCode, lpKeyState, uni_chars, 2, flags);
821 if(ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */
822 else n_ret = ret;
823 WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL);
824 return ret;
827 /****************************************************************************
828 * ToAsciiEx (USER32.@)
830 INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
831 LPWORD lpChar, UINT flags, HKL dwhkl )
833 /* FIXME: need true implementation */
834 return ToAscii(virtKey, scanCode, lpKeyState, lpChar, flags);
837 /**********************************************************************
838 * ActivateKeyboardLayout (USER32.@)
840 * Call ignored. WINE supports only system default keyboard layout.
842 HKL WINAPI ActivateKeyboardLayout(HKL hLayout, UINT flags)
844 TRACE_(keyboard)("(%d, %d)\n", hLayout, flags);
845 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
846 return 0;
850 /***********************************************************************
851 * GetKeyboardLayoutList (USER32.@)
853 * FIXME: Supports only the system default language and layout and
854 * returns only 1 value.
856 * Return number of values available if either input parm is
857 * 0, per MS documentation.
860 INT WINAPI GetKeyboardLayoutList(INT nBuff,HKL *layouts)
862 TRACE_(keyboard)("(%d,%p)\n",nBuff,layouts);
863 if (!nBuff || !layouts)
864 return 1;
865 if (layouts)
866 layouts[0] = GetKeyboardLayout(0);
867 return 1;
871 /***********************************************************************
872 * RegisterHotKey (USER32.@)
874 BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk) {
875 FIXME_(keyboard)("(0x%08x,%d,0x%08x,%d): stub\n",hwnd,id,modifiers,vk);
876 return TRUE;
879 /***********************************************************************
880 * UnregisterHotKey (USER32.@)
882 BOOL WINAPI UnregisterHotKey(HWND hwnd,INT id) {
883 FIXME_(keyboard)("(0x%08x,%d): stub\n",hwnd,id);
884 return TRUE;
887 /***********************************************************************
888 * LoadKeyboardLayoutA (USER32.@)
889 * Call ignored. WINE supports only system default keyboard layout.
891 HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID, UINT Flags)
893 TRACE_(keyboard)("(%s, %d)\n", pwszKLID, Flags);
894 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
895 return 0;
898 /***********************************************************************
899 * LoadKeyboardLayoutW (USER32.@)
901 HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags)
903 char buf[9];
905 WideCharToMultiByte( CP_ACP, 0, pwszKLID, -1, buf, sizeof(buf), NULL, NULL );
906 buf[8] = 0;
907 return LoadKeyboardLayoutA(buf, Flags);