Make GetCursorPos call XQueryPointer.
[wine/multimedia.git] / windows / input.c
blobd16614de89fb537fb9e4da00fb5d1e7c2051decd
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/keyboard16.h"
26 #include "server.h"
27 #include "win.h"
28 #include "heap.h"
29 #include "input.h"
30 #include "keyboard.h"
31 #include "mouse.h"
32 #include "message.h"
33 #include "queue.h"
34 #include "debugtools.h"
35 #include "winerror.h"
37 DECLARE_DEBUG_CHANNEL(key);
38 DECLARE_DEBUG_CHANNEL(keyboard);
39 DECLARE_DEBUG_CHANNEL(win);
40 DEFAULT_DEBUG_CHANNEL(event);
42 static BOOL InputEnabled = TRUE;
43 static BOOL SwappedButtons;
45 BOOL MouseButtonsStates[3];
46 BOOL AsyncMouseButtonsStates[3];
47 BYTE InputKeyStateTable[256];
48 BYTE QueueKeyStateTable[256];
49 BYTE AsyncKeyStateTable[256];
51 /* Storage for the USER-maintained mouse positions */
52 static DWORD PosX, PosY;
54 #define GET_KEYSTATE() \
55 ((MouseButtonsStates[SwappedButtons ? 2 : 0] ? MK_LBUTTON : 0) | \
56 (MouseButtonsStates[1] ? MK_RBUTTON : 0) | \
57 (MouseButtonsStates[SwappedButtons ? 0 : 2] ? MK_MBUTTON : 0) | \
58 (InputKeyStateTable[VK_SHIFT] & 0x80 ? MK_SHIFT : 0) | \
59 (InputKeyStateTable[VK_CONTROL] & 0x80 ? MK_CONTROL : 0))
61 typedef union
63 struct
65 unsigned long count : 16;
66 unsigned long code : 8;
67 unsigned long extended : 1;
68 unsigned long unused : 2;
69 unsigned long win_internal : 2;
70 unsigned long context : 1;
71 unsigned long previous : 1;
72 unsigned long transition : 1;
73 } lp1;
74 unsigned long lp2;
75 } KEYLP;
78 /***********************************************************************
79 * queue_raw_hardware_message
81 * Add a message to the raw hardware queue.
82 * Note: the position is relative to the desktop window.
84 static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lParam,
85 int xPos, int yPos, DWORD time, DWORD extraInfo )
87 SERVER_START_REQ( send_message )
89 req->kind = RAW_HW_MESSAGE;
90 req->id = (void *)GetCurrentThreadId();
91 req->type = QMSG_HARDWARE;
92 req->win = 0;
93 req->msg = message;
94 req->wparam = wParam;
95 req->lparam = lParam;
96 req->x = xPos;
97 req->y = yPos;
98 req->time = time;
99 req->info = extraInfo;
100 SERVER_CALL();
102 SERVER_END_REQ;
106 /***********************************************************************
107 * keybd_event (USER32.@)
109 void WINAPI keybd_event( BYTE bVk, BYTE bScan,
110 DWORD dwFlags, DWORD dwExtraInfo )
112 DWORD time, extra;
113 WORD message;
114 KEYLP keylp;
115 keylp.lp2 = 0;
117 if (!InputEnabled) return;
120 * If we are called by the Wine keyboard driver, use the additional
121 * info pointed to by the dwExtraInfo argument.
122 * Otherwise, we need to determine that info ourselves (probably
123 * less accurate, but we can't help that ...).
125 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_KEYBDEVENT) )
126 && ((WINE_KEYBDEVENT *)dwExtraInfo)->magic == WINE_KEYBDEVENT_MAGIC )
128 WINE_KEYBDEVENT *wke = (WINE_KEYBDEVENT *)dwExtraInfo;
129 time = wke->time;
130 extra = 0;
132 else
134 time = GetTickCount();
135 extra = dwExtraInfo;
139 keylp.lp1.count = 1;
140 keylp.lp1.code = bScan;
141 keylp.lp1.extended = (dwFlags & KEYEVENTF_EXTENDEDKEY) != 0;
142 keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
143 * don't remember where I read it - AK */
144 /* it's '1' under windows, when a dialog box appears
145 * and you press one of the underlined keys - DF*/
147 if ( dwFlags & KEYEVENTF_KEYUP )
149 BOOL sysKey = (InputKeyStateTable[VK_MENU] & 0x80)
150 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
151 && !(dwFlags & KEYEVENTF_WINE_FORCEEXTENDED); /* for Alt from AltGr */
153 InputKeyStateTable[bVk] &= ~0x80;
154 keylp.lp1.previous = 1;
155 keylp.lp1.transition = 1;
156 message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
158 else
160 keylp.lp1.previous = (InputKeyStateTable[bVk] & 0x80) != 0;
161 keylp.lp1.transition = 0;
163 if (!(InputKeyStateTable[bVk] & 0x80))
164 InputKeyStateTable[bVk] ^= 0x01;
165 InputKeyStateTable[bVk] |= 0x80;
166 AsyncKeyStateTable[bVk] |= 0x80;
168 message = (InputKeyStateTable[VK_MENU] & 0x80)
169 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
170 ? WM_SYSKEYDOWN : WM_KEYDOWN;
173 if ( message == WM_SYSKEYDOWN || message == WM_SYSKEYUP )
174 keylp.lp1.context = (InputKeyStateTable[VK_MENU] & 0x80) != 0; /* 1 if alt */
177 TRACE_(key)(" wParam=%04X, lParam=%08lX\n", bVk, keylp.lp2 );
178 TRACE_(key)(" InputKeyState=%X\n", InputKeyStateTable[bVk] );
180 queue_raw_hardware_message( message, bVk, keylp.lp2, PosX, PosY, time, extra );
183 /***********************************************************************
184 * keybd_event (USER.289)
186 void WINAPI WIN16_keybd_event( CONTEXT86 *context )
188 DWORD dwFlags = 0;
190 if (AH_reg(context) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
191 if (BH_reg(context) & 1 ) dwFlags |= KEYEVENTF_EXTENDEDKEY;
193 keybd_event( AL_reg(context), BL_reg(context),
194 dwFlags, MAKELONG(SI_reg(context), DI_reg(context)) );
197 /***********************************************************************
198 * mouse_event (USER32.@)
200 void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
201 DWORD cButtons, DWORD dwExtraInfo )
203 DWORD time, extra;
204 DWORD keyState;
206 if (!InputEnabled) return;
208 if ( dwFlags & MOUSEEVENTF_MOVE )
210 if ( dwFlags & MOUSEEVENTF_ABSOLUTE )
212 PosX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
213 PosY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
215 else
217 int width = GetSystemMetrics(SM_CXSCREEN);
218 int height = GetSystemMetrics(SM_CYSCREEN);
219 long posX = (long) PosX, posY = (long) PosY;
221 /* dx and dy can be negative numbers for relative movements */
222 posX += (long) dx;
223 posY += (long) dy;
225 /* Clip to the current screen size */
226 if (posX < 0) PosX = 0;
227 else if (posX >= width) PosX = width - 1;
228 else PosX = posX;
230 if (posY < 0) PosY = 0;
231 else if (posY >= height) PosY = height - 1;
232 else PosY = posY;
237 * If we are called by the Wine mouse driver, use the additional
238 * info pointed to by the dwExtraInfo argument.
239 * Otherwise, we need to determine that info ourselves (probably
240 * less accurate, but we can't help that ...).
242 if (dwExtraInfo && !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
243 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC )
245 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
246 time = wme->time;
247 extra = (DWORD)wme->hWnd;
248 keyState = wme->keyState;
250 if (keyState != GET_KEYSTATE()) {
251 /* We need to update the keystate with what X provides us */
252 MouseButtonsStates[SwappedButtons ? 2 : 0] = (keyState & MK_LBUTTON ? TRUE : FALSE);
253 MouseButtonsStates[SwappedButtons ? 0 : 2] = (keyState & MK_RBUTTON ? TRUE : FALSE);
254 MouseButtonsStates[1] = (keyState & MK_MBUTTON ? TRUE : FALSE);
255 InputKeyStateTable[VK_SHIFT] = (keyState & MK_SHIFT ? 0x80 : 0);
256 InputKeyStateTable[VK_CONTROL] = (keyState & MK_CONTROL ? 0x80 : 0);
259 else
261 time = GetTickCount();
262 extra = dwExtraInfo;
263 keyState = GET_KEYSTATE();
265 if ( dwFlags & MOUSEEVENTF_MOVE )
267 /* We have to actually move the cursor */
268 SetCursorPos( PosX, PosY );
273 if ( dwFlags & MOUSEEVENTF_MOVE )
275 queue_raw_hardware_message( WM_MOUSEMOVE, keyState, 0, PosX, PosY, time, extra );
277 if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN) )
279 MouseButtonsStates[0] = AsyncMouseButtonsStates[0] = TRUE;
280 queue_raw_hardware_message( WM_LBUTTONDOWN, keyState, 0, PosX, PosY, time, extra );
282 if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP) )
284 MouseButtonsStates[0] = FALSE;
285 queue_raw_hardware_message( WM_LBUTTONUP, keyState, 0, PosX, PosY, time, extra );
287 if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN) )
289 MouseButtonsStates[2] = AsyncMouseButtonsStates[2] = TRUE;
290 queue_raw_hardware_message( WM_RBUTTONDOWN, keyState, 0, PosX, PosY, time, extra );
292 if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP) )
294 MouseButtonsStates[2] = FALSE;
295 queue_raw_hardware_message( WM_RBUTTONUP, keyState, 0, PosX, PosY, time, extra );
297 if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN )
299 MouseButtonsStates[1] = AsyncMouseButtonsStates[1] = TRUE;
300 queue_raw_hardware_message( WM_MBUTTONDOWN, keyState, 0, PosX, PosY, time, extra );
302 if ( dwFlags & MOUSEEVENTF_MIDDLEUP )
304 MouseButtonsStates[1] = FALSE;
305 queue_raw_hardware_message( WM_MBUTTONUP, keyState, 0, PosX, PosY, time, extra );
307 if ( dwFlags & MOUSEEVENTF_WHEEL )
309 queue_raw_hardware_message( WM_MOUSEWHEEL, keyState, 0, PosX, PosY, time, extra );
313 /***********************************************************************
314 * mouse_event (USER.299)
316 void WINAPI WIN16_mouse_event( CONTEXT86 *context )
318 mouse_event( AX_reg(context), BX_reg(context), CX_reg(context),
319 DX_reg(context), MAKELONG(SI_reg(context), DI_reg(context)) );
322 /***********************************************************************
323 * GetMouseEventProc (USER.337)
325 FARPROC16 WINAPI GetMouseEventProc16(void)
327 HMODULE16 hmodule = GetModuleHandle16("USER");
328 return GetProcAddress16( hmodule, "mouse_event" );
332 /**********************************************************************
333 * EnableHardwareInput (USER.331)
335 BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
337 BOOL16 bOldState = InputEnabled;
338 FIXME_(event)("(%d) - stub\n", bEnable);
339 InputEnabled = bEnable;
340 return bOldState;
344 /***********************************************************************
345 * SwapMouseButton (USER.186)
347 BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
349 BOOL16 ret = SwappedButtons;
350 SwappedButtons = fSwap;
351 return ret;
355 /***********************************************************************
356 * SwapMouseButton (USER32.@)
358 BOOL WINAPI SwapMouseButton( BOOL fSwap )
360 BOOL ret = SwappedButtons;
361 SwappedButtons = fSwap;
362 return ret;
366 /***********************************************************************
367 * GetCursorPos (USER.17)
369 BOOL16 WINAPI GetCursorPos16( POINT16 *pt )
371 POINT pos;
372 if (!pt) return 0;
373 GetCursorPos(&pos);
374 pt->x = pos.x;
375 pt->y = pos.y;
376 return 1;
380 /***********************************************************************
381 * GetCursorPos (USER32.@)
383 BOOL WINAPI GetCursorPos( POINT *pt )
385 if (!pt) return 0;
386 pt->x = PosX;
387 pt->y = PosY;
388 if (USER_Driver.pGetCursorPos) USER_Driver.pGetCursorPos( pt );
389 return 1;
393 /***********************************************************************
394 * SetCursorPos (USER.70)
396 void WINAPI SetCursorPos16( INT16 x, INT16 y )
398 SetCursorPos( x, y );
402 /***********************************************************************
403 * SetCursorPos (USER32.@)
405 BOOL WINAPI SetCursorPos( INT x, INT y )
407 if (USER_Driver.pSetCursorPos) USER_Driver.pSetCursorPos( x, y );
408 PosX = x;
409 PosY = y;
410 return TRUE;
414 /**********************************************************************
415 * EVENT_Capture
417 * We need this to be able to generate double click messages
418 * when menu code captures mouse in the window without CS_DBLCLK style.
420 HWND EVENT_Capture(HWND hwnd, INT16 ht)
422 HWND capturePrev = 0, captureWnd = 0;
423 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
424 WND* wndPtr = 0;
425 INT16 captureHT = 0;
427 capturePrev = GetCapture();
429 if (!hwnd)
431 captureWnd = 0;
432 captureHT = 0;
434 else
436 wndPtr = WIN_FindWndPtr( hwnd );
437 if (wndPtr)
439 TRACE_(win)("(0x%04x)\n", hwnd );
440 captureWnd = hwnd;
441 captureHT = ht;
445 /* Get the messageQ for the current thread */
446 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
448 WARN_(win)("\tCurrent message queue not found. Exiting!\n" );
449 goto CLEANUP;
452 /* Update the perQ capture window and send messages */
453 if( capturePrev != captureWnd )
455 if (wndPtr)
457 /* Retrieve the message queue associated with this window */
458 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
459 if ( !pMsgQ )
461 WARN_(win)("\tMessage queue not found. Exiting!\n" );
462 goto CLEANUP;
465 /* Make sure that message queue for the window we are setting capture to
466 * shares the same perQ data as the current threads message queue.
468 if ( pCurMsgQ->pQData != pMsgQ->pQData )
469 goto CLEANUP;
472 PERQDATA_SetCaptureWnd( captureWnd, captureHT );
473 if (capturePrev) SendMessageA( capturePrev, WM_CAPTURECHANGED, 0, hwnd );
476 CLEANUP:
477 /* Unlock the queues before returning */
478 if ( pMsgQ )
479 QUEUE_Unlock( pMsgQ );
480 if ( pCurMsgQ )
481 QUEUE_Unlock( pCurMsgQ );
483 WIN_ReleaseWndPtr(wndPtr);
484 return capturePrev;
488 /**********************************************************************
489 * SetCapture (USER.18)
491 HWND16 WINAPI SetCapture16( HWND16 hwnd )
493 return (HWND16)EVENT_Capture( hwnd, HTCLIENT );
497 /**********************************************************************
498 * SetCapture (USER32.@)
500 HWND WINAPI SetCapture( HWND hwnd )
502 return EVENT_Capture( hwnd, HTCLIENT );
506 /**********************************************************************
507 * ReleaseCapture (USER.19) (USER32.@)
509 BOOL WINAPI ReleaseCapture(void)
511 return (EVENT_Capture( 0, 0 ) != 0);
515 /**********************************************************************
516 * GetCapture (USER.236)
518 HWND16 WINAPI GetCapture16(void)
520 return (HWND16)GetCapture();
523 /**********************************************************************
524 * GetCapture (USER32.@)
526 HWND WINAPI GetCapture(void)
528 INT hittest;
529 return PERQDATA_GetCaptureWnd( &hittest );
532 /**********************************************************************
533 * GetKeyState (USER.106)
535 INT16 WINAPI GetKeyState16(INT16 vkey)
537 return GetKeyState(vkey);
540 /**********************************************************************
541 * GetKeyState (USER32.@)
543 * An application calls the GetKeyState function in response to a
544 * keyboard-input message. This function retrieves the state of the key
545 * at the time the input message was generated. (SDK 3.1 Vol 2. p 390)
547 SHORT WINAPI GetKeyState(INT vkey)
549 INT retval;
551 switch (vkey)
553 case VK_LBUTTON : /* VK_LBUTTON is 1 */
554 retval = MouseButtonsStates[0] ? 0x8000 : 0;
555 break;
556 case VK_MBUTTON : /* VK_MBUTTON is 4 */
557 retval = MouseButtonsStates[1] ? 0x8000 : 0;
558 break;
559 case VK_RBUTTON : /* VK_RBUTTON is 2 */
560 retval = MouseButtonsStates[2] ? 0x8000 : 0;
561 break;
562 default :
563 if (vkey >= 'a' && vkey <= 'z')
564 vkey += 'A' - 'a';
565 retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
566 (WORD)(QueueKeyStateTable[vkey] & 0x01);
568 /* TRACE(key, "(0x%x) -> %x\n", vkey, retval); */
569 return retval;
572 /**********************************************************************
573 * GetKeyboardState (USER.222) (USER32.@)
575 * An application calls the GetKeyboardState function in response to a
576 * keyboard-input message. This function retrieves the state of the keyboard
577 * at the time the input message was generated. (SDK 3.1 Vol 2. p 387)
579 BOOL WINAPI GetKeyboardState(LPBYTE lpKeyState)
581 TRACE_(key)("(%p)\n", lpKeyState);
582 if (lpKeyState != NULL) {
583 QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
584 QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
585 QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
586 memcpy(lpKeyState, QueueKeyStateTable, 256);
589 return TRUE;
592 /**********************************************************************
593 * SetKeyboardState (USER.223) (USER32.@)
595 BOOL WINAPI SetKeyboardState(LPBYTE lpKeyState)
597 TRACE_(key)("(%p)\n", lpKeyState);
598 if (lpKeyState != NULL) {
599 memcpy(QueueKeyStateTable, lpKeyState, 256);
600 MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0);
601 MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0);
602 MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0);
605 return TRUE;
608 /**********************************************************************
609 * GetAsyncKeyState (USER32.@)
611 * Determine if a key is or was pressed. retval has high-order
612 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
613 * been pressed.
615 * This uses the variable AsyncMouseButtonsStates and
616 * AsyncKeyStateTable (set in event.c) which have the mouse button
617 * number or key number (whichever is applicable) set to true if the
618 * mouse or key had been depressed since the last call to
619 * GetAsyncKeyState.
621 WORD WINAPI GetAsyncKeyState(INT nKey)
623 WORD retval;
625 switch (nKey) {
626 case VK_LBUTTON:
627 retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) |
628 (MouseButtonsStates[0] ? 0x8000 : 0);
629 AsyncMouseButtonsStates[0] = 0;
630 break;
631 case VK_MBUTTON:
632 retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) |
633 (MouseButtonsStates[1] ? 0x8000 : 0);
634 AsyncMouseButtonsStates[1] = 0;
635 break;
636 case VK_RBUTTON:
637 retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) |
638 (MouseButtonsStates[2] ? 0x8000 : 0);
639 AsyncMouseButtonsStates[2] = 0;
640 break;
641 default:
642 retval = ((AsyncKeyStateTable[nKey] & 0x80) ? 0x0001 : 0) |
643 ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
644 AsyncKeyStateTable[nKey] = 0;
645 break;
648 TRACE_(key)("(%x) -> %x\n", nKey, retval);
649 return retval;
652 /**********************************************************************
653 * GetAsyncKeyState (USER.249)
655 WORD WINAPI GetAsyncKeyState16(INT16 nKey)
657 return GetAsyncKeyState(nKey);
660 /***********************************************************************
661 * IsUserIdle (USER.333)
663 BOOL16 WINAPI IsUserIdle16(void)
665 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
666 return FALSE;
668 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
669 return FALSE;
671 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
672 return FALSE;
674 /* Should check for screen saver activation here ... */
676 return TRUE;
679 /**********************************************************************
680 * VkKeyScanA (USER32.@)
682 WORD WINAPI VkKeyScanA(CHAR cChar)
684 return VkKeyScan16(cChar);
687 /******************************************************************************
688 * VkKeyScanW (USER32.@)
690 WORD WINAPI VkKeyScanW(WCHAR cChar)
692 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
695 /**********************************************************************
696 * VkKeyScanExA (USER32.@)
698 WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
700 /* FIXME: complete workaround this is */
701 return VkKeyScan16(cChar);
704 /******************************************************************************
705 * VkKeyScanExW (USER32.@)
707 WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl)
709 /* FIXME: complete workaround this is */
710 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
713 /******************************************************************************
714 * GetKeyboardType (USER32.@)
716 INT WINAPI GetKeyboardType(INT nTypeFlag)
718 return GetKeyboardType16(nTypeFlag);
721 /******************************************************************************
722 * MapVirtualKeyA (USER32.@)
724 UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
726 return MapVirtualKey16(code,maptype);
729 /******************************************************************************
730 * MapVirtualKeyW (USER32.@)
732 UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype)
734 return MapVirtualKey16(code,maptype);
737 /******************************************************************************
738 * MapVirtualKeyExA (USER32.@)
740 UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl)
742 if (hkl)
743 FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
744 return MapVirtualKey16(code,maptype);
747 /******************************************************************************
748 * MapVirtualKeyExW (USER32.@)
750 UINT WINAPI MapVirtualKeyExW(UINT code, UINT maptype, HKL hkl)
752 if (hkl)
753 FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
754 return MapVirtualKey16(code,maptype);
757 /****************************************************************************
758 * GetKBCodePage (USER32.@)
760 UINT WINAPI GetKBCodePage(void)
762 return GetOEMCP();
765 /****************************************************************************
766 * GetKeyboardLayoutName (USER.477)
768 INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID)
770 return GetKeyboardLayoutNameA(pwszKLID);
773 /***********************************************************************
774 * GetKeyboardLayout (USER32.@)
776 * FIXME: - device handle for keyboard layout defaulted to
777 * the language id. This is the way Windows default works.
778 * - the thread identifier (dwLayout) is also ignored.
780 HKL WINAPI GetKeyboardLayout(DWORD dwLayout)
782 HKL layout;
783 layout = GetSystemDefaultLCID(); /* FIXME */
784 layout |= (layout<<16); /* FIXME */
785 TRACE_(keyboard)("returning %08x\n",layout);
786 return layout;
789 /****************************************************************************
790 * GetKeyboardLayoutNameA (USER32.@)
792 INT WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID)
794 sprintf(pwszKLID, "%08x",GetKeyboardLayout(0));
795 return 1;
798 /****************************************************************************
799 * GetKeyboardLayoutNameW (USER32.@)
801 INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID)
803 char buf[KL_NAMELENGTH];
804 int res = GetKeyboardLayoutNameA(buf);
805 MultiByteToWideChar( CP_ACP, 0, buf, -1, pwszKLID, KL_NAMELENGTH );
806 return res;
809 /****************************************************************************
810 * GetKeyNameTextA (USER32.@)
812 INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
814 return GetKeyNameText16(lParam,lpBuffer,nSize);
817 /****************************************************************************
818 * GetKeyNameTextW (USER32.@)
820 INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize)
822 int res;
823 LPSTR buf = HeapAlloc( GetProcessHeap(), 0, nSize );
824 if(buf == NULL) return 0; /* FIXME: is this the correct failure value?*/
825 res = GetKeyNameTextA(lParam,buf,nSize);
827 if (nSize > 0 && !MultiByteToWideChar( CP_ACP, 0, buf, -1, lpBuffer, nSize ))
828 lpBuffer[nSize-1] = 0;
829 HeapFree( GetProcessHeap(), 0, buf );
830 return res;
833 /****************************************************************************
834 * ToUnicode (USER32.@)
836 INT WINAPI ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
837 LPWSTR lpwStr, int size, UINT flags)
839 return USER_Driver.pToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
842 /****************************************************************************
843 * ToUnicodeEx (USER32.@)
845 INT WINAPI ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
846 LPWSTR lpwStr, int size, UINT flags, HKL hkl)
848 /* FIXME: need true implementation */
849 return ToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
852 /****************************************************************************
853 * ToAscii (USER32.@)
855 INT WINAPI ToAscii( UINT virtKey,UINT scanCode,LPBYTE lpKeyState,
856 LPWORD lpChar,UINT flags )
858 WCHAR uni_chars[2];
859 INT ret, n_ret;
861 ret = ToUnicode(virtKey, scanCode, lpKeyState, uni_chars, 2, flags);
862 if(ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */
863 else n_ret = ret;
864 WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL);
865 return ret;
868 /****************************************************************************
869 * ToAsciiEx (USER32.@)
871 INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
872 LPWORD lpChar, UINT flags, HKL dwhkl )
874 /* FIXME: need true implementation */
875 return ToAscii(virtKey, scanCode, lpKeyState, lpChar, flags);
878 /**********************************************************************
879 * ActivateKeyboardLayout (USER32.@)
881 * Call ignored. WINE supports only system default keyboard layout.
883 HKL WINAPI ActivateKeyboardLayout(HKL hLayout, UINT flags)
885 TRACE_(keyboard)("(%d, %d)\n", hLayout, flags);
886 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
887 return 0;
891 /***********************************************************************
892 * GetKeyboardLayoutList (USER32.@)
894 * FIXME: Supports only the system default language and layout and
895 * returns only 1 value.
897 * Return number of values available if either input parm is
898 * 0, per MS documentation.
901 INT WINAPI GetKeyboardLayoutList(INT nBuff,HKL *layouts)
903 TRACE_(keyboard)("(%d,%p)\n",nBuff,layouts);
904 if (!nBuff || !layouts)
905 return 1;
906 if (layouts)
907 layouts[0] = GetKeyboardLayout(0);
908 return 1;
912 /***********************************************************************
913 * RegisterHotKey (USER32.@)
915 BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk) {
916 FIXME_(keyboard)("(0x%08x,%d,0x%08x,%d): stub\n",hwnd,id,modifiers,vk);
917 return TRUE;
920 /***********************************************************************
921 * UnregisterHotKey (USER32.@)
923 BOOL WINAPI UnregisterHotKey(HWND hwnd,INT id) {
924 FIXME_(keyboard)("(0x%08x,%d): stub\n",hwnd,id);
925 return TRUE;
928 /***********************************************************************
929 * LoadKeyboardLayoutA (USER32.@)
930 * Call ignored. WINE supports only system default keyboard layout.
932 HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID, UINT Flags)
934 TRACE_(keyboard)("(%s, %d)\n", pwszKLID, Flags);
935 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
936 return 0;
939 /***********************************************************************
940 * LoadKeyboardLayoutW (USER32.@)
942 HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags)
944 char buf[9];
946 WideCharToMultiByte( CP_ACP, 0, pwszKLID, -1, buf, sizeof(buf), NULL, NULL );
947 buf[8] = 0;
948 return LoadKeyboardLayoutA(buf, Flags);