Rename "SystemTime" to "t" (this is *not* SYSTEMTIME - avoid
[wine/wine-kai.git] / windows / input.c
blob018e669a63a2752009a6182b24f49897a5c87edc
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 "wine/server.h"
27 #include "win.h"
28 #include "input.h"
29 #include "keyboard.h"
30 #include "mouse.h"
31 #include "message.h"
32 #include "queue.h"
33 #include "debugtools.h"
34 #include "winerror.h"
36 DECLARE_DEBUG_CHANNEL(key);
37 DECLARE_DEBUG_CHANNEL(keyboard);
38 DECLARE_DEBUG_CHANNEL(win);
39 DEFAULT_DEBUG_CHANNEL(event);
41 static BOOL InputEnabled = TRUE;
42 static BOOL SwappedButtons;
44 BOOL MouseButtonsStates[3];
45 BOOL AsyncMouseButtonsStates[3];
46 BYTE InputKeyStateTable[256];
47 BYTE QueueKeyStateTable[256];
48 BYTE AsyncKeyStateTable[256];
50 /* Storage for the USER-maintained mouse positions */
51 static DWORD PosX, PosY;
53 #define GET_KEYSTATE() \
54 ((MouseButtonsStates[SwappedButtons ? 2 : 0] ? MK_LBUTTON : 0) | \
55 (MouseButtonsStates[1] ? MK_RBUTTON : 0) | \
56 (MouseButtonsStates[SwappedButtons ? 0 : 2] ? MK_MBUTTON : 0) | \
57 (InputKeyStateTable[VK_SHIFT] & 0x80 ? MK_SHIFT : 0) | \
58 (InputKeyStateTable[VK_CONTROL] & 0x80 ? MK_CONTROL : 0))
60 typedef union
62 struct
64 unsigned long count : 16;
65 unsigned long code : 8;
66 unsigned long extended : 1;
67 unsigned long unused : 2;
68 unsigned long win_internal : 2;
69 unsigned long context : 1;
70 unsigned long previous : 1;
71 unsigned long transition : 1;
72 } lp1;
73 unsigned long lp2;
74 } KEYLP;
77 /***********************************************************************
78 * queue_raw_hardware_message
80 * Add a message to the raw hardware queue.
81 * Note: the position is relative to the desktop window.
83 static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lParam,
84 int xPos, int yPos, DWORD time, DWORD extraInfo )
86 SERVER_START_REQ( send_message )
88 req->id = (void *)GetCurrentThreadId();
89 req->type = MSG_HARDWARE_RAW;
90 req->win = 0;
91 req->msg = message;
92 req->wparam = wParam;
93 req->lparam = lParam;
94 req->x = xPos;
95 req->y = yPos;
96 req->time = time;
97 req->info = extraInfo;
98 req->timeout = 0;
99 SERVER_CALL();
101 SERVER_END_REQ;
105 /***********************************************************************
106 * queue_kbd_event
108 * Put a keyboard event into a thread queue
110 static void queue_kbd_event( const KEYBDINPUT *ki )
112 UINT message;
113 KEYLP keylp;
115 keylp.lp2 = 0;
116 keylp.lp1.count = 1;
117 keylp.lp1.code = ki->wScan;
118 keylp.lp1.extended = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) != 0;
119 keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
120 * don't remember where I read it - AK */
121 /* it's '1' under windows, when a dialog box appears
122 * and you press one of the underlined keys - DF*/
124 if (ki->dwFlags & KEYEVENTF_KEYUP )
126 BOOL sysKey = ((InputKeyStateTable[VK_MENU] & 0x80) &&
127 !(InputKeyStateTable[VK_CONTROL] & 0x80) &&
128 !(ki->dwFlags & KEYEVENTF_WINE_FORCEEXTENDED)); /* for Alt from AltGr */
129 InputKeyStateTable[ki->wVk] &= ~0x80;
130 keylp.lp1.previous = 1;
131 keylp.lp1.transition = 1;
132 message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
134 else
136 keylp.lp1.previous = (InputKeyStateTable[ki->wVk] & 0x80) != 0;
137 keylp.lp1.transition = 0;
138 if (!(InputKeyStateTable[ki->wVk] & 0x80)) InputKeyStateTable[ki->wVk] ^= 0x01;
139 InputKeyStateTable[ki->wVk] |= 0x80;
140 AsyncKeyStateTable[ki->wVk] |= 0x80;
142 message = (InputKeyStateTable[VK_MENU] & 0x80) && !(InputKeyStateTable[VK_CONTROL] & 0x80)
143 ? WM_SYSKEYDOWN : WM_KEYDOWN;
146 if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP )
147 keylp.lp1.context = (InputKeyStateTable[VK_MENU] & 0x80) != 0; /* 1 if alt */
149 TRACE_(key)(" wParam=%04x, lParam=%08lx, InputKeyState=%x\n",
150 ki->wVk, keylp.lp2, InputKeyStateTable[ki->wVk] );
152 queue_raw_hardware_message( message, ki->wVk, keylp.lp2,
153 PosX, PosY, ki->time, ki->dwExtraInfo );
157 /***********************************************************************
158 * queue_mouse_event
160 static void queue_mouse_event( const MOUSEINPUT *mi, WORD keystate )
162 if (mi->dwFlags & MOUSEEVENTF_MOVE)
164 if (mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
166 PosX = (mi->dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
167 PosY = (mi->dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
169 else
171 int width = GetSystemMetrics(SM_CXSCREEN);
172 int height = GetSystemMetrics(SM_CYSCREEN);
173 long posX = (long) PosX, posY = (long) PosY;
175 /* dx and dy can be negative numbers for relative movements */
176 posX += (long)mi->dx;
177 posY += (long)mi->dy;
179 /* Clip to the current screen size */
180 if (posX < 0) PosX = 0;
181 else if (posX >= width) PosX = width - 1;
182 else PosX = posX;
184 if (posY < 0) PosY = 0;
185 else if (posY >= height) PosY = height - 1;
186 else PosY = posY;
190 if (mi->dwFlags & MOUSEEVENTF_MOVE)
192 queue_raw_hardware_message( WM_MOUSEMOVE, keystate, 0, PosX, PosY,
193 mi->time, mi->dwExtraInfo );
195 if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN))
197 MouseButtonsStates[0] = AsyncMouseButtonsStates[0] = TRUE;
198 queue_raw_hardware_message( WM_LBUTTONDOWN, keystate, 0, PosX, PosY,
199 mi->time, mi->dwExtraInfo );
201 if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP))
203 MouseButtonsStates[0] = FALSE;
204 queue_raw_hardware_message( WM_LBUTTONUP, keystate, 0, PosX, PosY,
205 mi->time, mi->dwExtraInfo );
207 if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN))
209 MouseButtonsStates[2] = AsyncMouseButtonsStates[2] = TRUE;
210 queue_raw_hardware_message( WM_RBUTTONDOWN, keystate, 0, PosX, PosY,
211 mi->time, mi->dwExtraInfo );
213 if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP))
215 MouseButtonsStates[2] = FALSE;
216 queue_raw_hardware_message( WM_RBUTTONUP, keystate, 0, PosX, PosY,
217 mi->time, mi->dwExtraInfo );
219 if (mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
221 MouseButtonsStates[1] = AsyncMouseButtonsStates[1] = TRUE;
222 queue_raw_hardware_message( WM_MBUTTONDOWN, keystate, 0, PosX, PosY,
223 mi->time, mi->dwExtraInfo );
225 if (mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
227 MouseButtonsStates[1] = FALSE;
228 queue_raw_hardware_message( WM_MBUTTONUP, keystate, 0, PosX, PosY,
229 mi->time, mi->dwExtraInfo );
231 if (mi->dwFlags & MOUSEEVENTF_WHEEL)
233 queue_raw_hardware_message( WM_MOUSEWHEEL, MAKELONG( keystate, mi->mouseData), 0,
234 PosX, PosY, mi->time, mi->dwExtraInfo );
239 /***********************************************************************
240 * SendInput (USER32.@)
242 UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
244 UINT i;
246 if (!InputEnabled) return 0;
248 for (i = 0; i < count; i++, inputs++)
250 switch(inputs->type)
252 case INPUT_MOUSE:
253 queue_mouse_event( &inputs->u.mi, GET_KEYSTATE() );
254 break;
255 case INPUT_KEYBOARD:
256 queue_kbd_event( &inputs->u.ki );
257 break;
258 case INPUT_HARDWARE:
259 FIXME( "INPUT_HARDWARE not supported\n" );
260 break;
263 return count;
267 /***********************************************************************
268 * keybd_event (USER32.@)
270 void WINAPI keybd_event( BYTE bVk, BYTE bScan,
271 DWORD dwFlags, DWORD dwExtraInfo )
273 INPUT input;
276 * If we are called by the Wine keyboard driver, use the additional
277 * info pointed to by the dwExtraInfo argument.
278 * Otherwise, we need to determine that info ourselves (probably
279 * less accurate, but we can't help that ...).
281 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_KEYBDEVENT) )
282 && ((WINE_KEYBDEVENT *)dwExtraInfo)->magic == WINE_KEYBDEVENT_MAGIC )
284 WINE_KEYBDEVENT *wke = (WINE_KEYBDEVENT *)dwExtraInfo;
285 input.u.ki.time = wke->time;
286 input.u.ki.dwExtraInfo = 0;
288 else
290 input.u.ki.time = GetTickCount();
291 input.u.ki.dwExtraInfo = dwExtraInfo;
293 input.type = INPUT_KEYBOARD;
294 input.u.ki.wVk = bVk;
295 input.u.ki.wScan = bScan;
296 input.u.ki.dwFlags = dwFlags;
297 SendInput( 1, &input, sizeof(input) );
301 /***********************************************************************
302 * keybd_event (USER.289)
304 void WINAPI keybd_event16( CONTEXT86 *context )
306 DWORD dwFlags = 0;
308 if (AH_reg(context) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
309 if (BH_reg(context) & 1 ) dwFlags |= KEYEVENTF_EXTENDEDKEY;
311 keybd_event( AL_reg(context), BL_reg(context),
312 dwFlags, MAKELONG(SI_reg(context), DI_reg(context)) );
316 /***********************************************************************
317 * mouse_event (USER32.@)
319 void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
320 DWORD dwData, DWORD dwExtraInfo )
322 INPUT input;
323 WORD keyState;
325 input.type = INPUT_MOUSE;
326 input.u.mi.dx = dx;
327 input.u.mi.dy = dy;
328 input.u.mi.mouseData = dwData;
329 input.u.mi.dwFlags = dwFlags;
332 * If we are called by the Wine mouse driver, use the additional
333 * info pointed to by the dwExtraInfo argument.
334 * Otherwise, we need to determine that info ourselves (probably
335 * less accurate, but we can't help that ...).
337 if (dwExtraInfo && !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
338 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC )
340 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
342 keyState = wme->keyState;
344 if (keyState != GET_KEYSTATE())
346 /* We need to update the keystate with what X provides us */
347 MouseButtonsStates[SwappedButtons ? 2 : 0] = (keyState & MK_LBUTTON ? TRUE : FALSE);
348 MouseButtonsStates[SwappedButtons ? 0 : 2] = (keyState & MK_RBUTTON ? TRUE : FALSE);
349 MouseButtonsStates[1] = (keyState & MK_MBUTTON ? TRUE : FALSE);
350 InputKeyStateTable[VK_SHIFT] = (keyState & MK_SHIFT ? 0x80 : 0);
351 InputKeyStateTable[VK_CONTROL] = (keyState & MK_CONTROL ? 0x80 : 0);
353 input.u.mi.time = wme->time;
354 input.u.mi.dwExtraInfo = wme->hWnd;
355 queue_mouse_event( &input.u.mi, keyState );
357 else
359 if ( dwFlags & MOUSEEVENTF_MOVE ) /* we have to actually move the cursor */
360 SetCursorPos( PosX, PosY );
362 input.u.mi.time = GetCurrentTime();
363 input.u.mi.dwExtraInfo = dwExtraInfo;
364 SendInput( 1, &input, sizeof(input) );
369 /***********************************************************************
370 * mouse_event (USER.299)
372 void WINAPI mouse_event16( CONTEXT86 *context )
374 mouse_event( AX_reg(context), BX_reg(context), CX_reg(context),
375 DX_reg(context), MAKELONG(SI_reg(context), DI_reg(context)) );
378 /***********************************************************************
379 * GetMouseEventProc (USER.337)
381 FARPROC16 WINAPI GetMouseEventProc16(void)
383 HMODULE16 hmodule = GetModuleHandle16("USER");
384 return GetProcAddress16( hmodule, "mouse_event" );
388 /**********************************************************************
389 * EnableHardwareInput (USER.331)
391 BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
393 BOOL16 bOldState = InputEnabled;
394 FIXME_(event)("(%d) - stub\n", bEnable);
395 InputEnabled = bEnable;
396 return bOldState;
400 /***********************************************************************
401 * SwapMouseButton (USER.186)
403 BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
405 BOOL16 ret = SwappedButtons;
406 SwappedButtons = fSwap;
407 return ret;
411 /***********************************************************************
412 * SwapMouseButton (USER32.@)
414 BOOL WINAPI SwapMouseButton( BOOL fSwap )
416 BOOL ret = SwappedButtons;
417 SwappedButtons = fSwap;
418 return ret;
422 /***********************************************************************
423 * GetCursorPos (USER.17)
425 BOOL16 WINAPI GetCursorPos16( POINT16 *pt )
427 POINT pos;
428 if (!pt) return 0;
429 GetCursorPos(&pos);
430 pt->x = pos.x;
431 pt->y = pos.y;
432 return 1;
436 /***********************************************************************
437 * GetCursorPos (USER32.@)
439 BOOL WINAPI GetCursorPos( POINT *pt )
441 if (!pt) return 0;
442 pt->x = PosX;
443 pt->y = PosY;
444 if (USER_Driver.pGetCursorPos) USER_Driver.pGetCursorPos( pt );
445 return 1;
449 /***********************************************************************
450 * SetCursorPos (USER.70)
452 void WINAPI SetCursorPos16( INT16 x, INT16 y )
454 SetCursorPos( x, y );
458 /***********************************************************************
459 * SetCursorPos (USER32.@)
461 BOOL WINAPI SetCursorPos( INT x, INT y )
463 if (USER_Driver.pSetCursorPos) USER_Driver.pSetCursorPos( x, y );
464 PosX = x;
465 PosY = y;
466 return TRUE;
470 /**********************************************************************
471 * EVENT_Capture
473 * We need this to be able to generate double click messages
474 * when menu code captures mouse in the window without CS_DBLCLK style.
476 HWND EVENT_Capture(HWND hwnd, INT16 ht)
478 HWND capturePrev = 0, captureWnd = 0;
479 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
480 WND* wndPtr = 0;
481 INT16 captureHT = 0;
483 capturePrev = GetCapture();
485 if (!hwnd)
487 captureWnd = 0;
488 captureHT = 0;
490 else
492 wndPtr = WIN_FindWndPtr( hwnd );
493 if (wndPtr)
495 TRACE_(win)("(0x%04x)\n", hwnd );
496 captureWnd = wndPtr->hwndSelf;
497 captureHT = ht;
501 /* Get the messageQ for the current thread */
502 if (!(pCurMsgQ = QUEUE_Current()))
504 WARN_(win)("\tCurrent message queue not found. Exiting!\n" );
505 goto CLEANUP;
508 /* Update the perQ capture window and send messages */
509 if( capturePrev != captureWnd )
511 if (wndPtr)
513 /* Retrieve the message queue associated with this window */
514 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
515 if ( !pMsgQ )
517 WARN_(win)("\tMessage queue not found. Exiting!\n" );
518 goto CLEANUP;
521 /* Make sure that message queue for the window we are setting capture to
522 * shares the same perQ data as the current threads message queue.
524 if ( pCurMsgQ->pQData != pMsgQ->pQData )
525 goto CLEANUP;
528 PERQDATA_SetCaptureWnd( captureWnd, captureHT );
529 if (capturePrev) SendMessageA( capturePrev, WM_CAPTURECHANGED, 0, hwnd );
532 CLEANUP:
533 /* Unlock the queues before returning */
534 if ( pMsgQ )
535 QUEUE_Unlock( pMsgQ );
537 WIN_ReleaseWndPtr(wndPtr);
538 return capturePrev;
542 /**********************************************************************
543 * SetCapture (USER.18)
545 HWND16 WINAPI SetCapture16( HWND16 hwnd )
547 return (HWND16)EVENT_Capture( hwnd, HTCLIENT );
551 /**********************************************************************
552 * SetCapture (USER32.@)
554 HWND WINAPI SetCapture( HWND hwnd )
556 return EVENT_Capture( hwnd, HTCLIENT );
560 /**********************************************************************
561 * ReleaseCapture (USER.19)
562 * ReleaseCapture (USER32.@)
564 BOOL WINAPI ReleaseCapture(void)
566 return (EVENT_Capture( 0, 0 ) != 0);
570 /**********************************************************************
571 * GetCapture (USER.236)
573 HWND16 WINAPI GetCapture16(void)
575 return (HWND16)GetCapture();
578 /**********************************************************************
579 * GetCapture (USER32.@)
581 HWND WINAPI GetCapture(void)
583 INT hittest;
584 return PERQDATA_GetCaptureWnd( &hittest );
587 /**********************************************************************
588 * GetKeyState (USER.106)
590 INT16 WINAPI GetKeyState16(INT16 vkey)
592 return GetKeyState(vkey);
595 /**********************************************************************
596 * GetKeyState (USER32.@)
598 * An application calls the GetKeyState function in response to a
599 * keyboard-input message. This function retrieves the state of the key
600 * at the time the input message was generated. (SDK 3.1 Vol 2. p 390)
602 SHORT WINAPI GetKeyState(INT vkey)
604 INT retval;
606 switch (vkey)
608 case VK_LBUTTON : /* VK_LBUTTON is 1 */
609 retval = MouseButtonsStates[0] ? 0x8000 : 0;
610 break;
611 case VK_MBUTTON : /* VK_MBUTTON is 4 */
612 retval = MouseButtonsStates[1] ? 0x8000 : 0;
613 break;
614 case VK_RBUTTON : /* VK_RBUTTON is 2 */
615 retval = MouseButtonsStates[2] ? 0x8000 : 0;
616 break;
617 default :
618 if (vkey >= 'a' && vkey <= 'z')
619 vkey += 'A' - 'a';
620 retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
621 (WORD)(QueueKeyStateTable[vkey] & 0x01);
623 /* TRACE(key, "(0x%x) -> %x\n", vkey, retval); */
624 return retval;
627 /**********************************************************************
628 * GetKeyboardState (USER.222)
629 * GetKeyboardState (USER32.@)
631 * An application calls the GetKeyboardState function in response to a
632 * keyboard-input message. This function retrieves the state of the keyboard
633 * at the time the input message was generated. (SDK 3.1 Vol 2. p 387)
635 BOOL WINAPI GetKeyboardState(LPBYTE lpKeyState)
637 TRACE_(key)("(%p)\n", lpKeyState);
638 if (lpKeyState != NULL) {
639 QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
640 QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
641 QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
642 memcpy(lpKeyState, QueueKeyStateTable, 256);
645 return TRUE;
648 /**********************************************************************
649 * SetKeyboardState (USER.223)
650 * SetKeyboardState (USER32.@)
652 BOOL WINAPI SetKeyboardState(LPBYTE lpKeyState)
654 TRACE_(key)("(%p)\n", lpKeyState);
655 if (lpKeyState != NULL) {
656 memcpy(QueueKeyStateTable, lpKeyState, 256);
657 MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0);
658 MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0);
659 MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0);
662 return TRUE;
665 /**********************************************************************
666 * GetAsyncKeyState (USER32.@)
668 * Determine if a key is or was pressed. retval has high-order
669 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
670 * been pressed.
672 * This uses the variable AsyncMouseButtonsStates and
673 * AsyncKeyStateTable (set in event.c) which have the mouse button
674 * number or key number (whichever is applicable) set to true if the
675 * mouse or key had been depressed since the last call to
676 * GetAsyncKeyState.
678 WORD WINAPI GetAsyncKeyState(INT nKey)
680 WORD retval;
682 switch (nKey) {
683 case VK_LBUTTON:
684 retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) |
685 (MouseButtonsStates[0] ? 0x8000 : 0);
686 AsyncMouseButtonsStates[0] = 0;
687 break;
688 case VK_MBUTTON:
689 retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) |
690 (MouseButtonsStates[1] ? 0x8000 : 0);
691 AsyncMouseButtonsStates[1] = 0;
692 break;
693 case VK_RBUTTON:
694 retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) |
695 (MouseButtonsStates[2] ? 0x8000 : 0);
696 AsyncMouseButtonsStates[2] = 0;
697 break;
698 default:
699 retval = ((AsyncKeyStateTable[nKey] & 0x80) ? 0x0001 : 0) |
700 ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
701 AsyncKeyStateTable[nKey] = 0;
702 break;
705 TRACE_(key)("(%x) -> %x\n", nKey, retval);
706 return retval;
709 /**********************************************************************
710 * GetAsyncKeyState (USER.249)
712 WORD WINAPI GetAsyncKeyState16(INT16 nKey)
714 return GetAsyncKeyState(nKey);
717 /***********************************************************************
718 * IsUserIdle (USER.333)
720 BOOL16 WINAPI IsUserIdle16(void)
722 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
723 return FALSE;
725 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
726 return FALSE;
728 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
729 return FALSE;
731 /* Should check for screen saver activation here ... */
733 return TRUE;
736 /**********************************************************************
737 * VkKeyScanA (USER32.@)
739 WORD WINAPI VkKeyScanA(CHAR cChar)
741 return VkKeyScan16(cChar);
744 /******************************************************************************
745 * VkKeyScanW (USER32.@)
747 WORD WINAPI VkKeyScanW(WCHAR cChar)
749 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
752 /**********************************************************************
753 * VkKeyScanExA (USER32.@)
755 WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
757 /* FIXME: complete workaround this is */
758 return VkKeyScan16(cChar);
761 /******************************************************************************
762 * VkKeyScanExW (USER32.@)
764 WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl)
766 /* FIXME: complete workaround this is */
767 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
770 /******************************************************************************
771 * GetKeyboardType (USER32.@)
773 INT WINAPI GetKeyboardType(INT nTypeFlag)
775 return GetKeyboardType16(nTypeFlag);
778 /******************************************************************************
779 * MapVirtualKeyA (USER32.@)
781 UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
783 return MapVirtualKey16(code,maptype);
786 /******************************************************************************
787 * MapVirtualKeyW (USER32.@)
789 UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype)
791 return MapVirtualKey16(code,maptype);
794 /******************************************************************************
795 * MapVirtualKeyExA (USER32.@)
797 UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl)
799 if (hkl)
800 FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
801 return MapVirtualKey16(code,maptype);
804 /******************************************************************************
805 * MapVirtualKeyExW (USER32.@)
807 UINT WINAPI MapVirtualKeyExW(UINT code, UINT maptype, HKL hkl)
809 if (hkl)
810 FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
811 return MapVirtualKey16(code,maptype);
814 /****************************************************************************
815 * GetKBCodePage (USER32.@)
817 UINT WINAPI GetKBCodePage(void)
819 return GetOEMCP();
822 /****************************************************************************
823 * GetKeyboardLayoutName (USER.477)
825 INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID)
827 return GetKeyboardLayoutNameA(pwszKLID);
830 /***********************************************************************
831 * GetKeyboardLayout (USER32.@)
833 * FIXME: - device handle for keyboard layout defaulted to
834 * the language id. This is the way Windows default works.
835 * - the thread identifier (dwLayout) is also ignored.
837 HKL WINAPI GetKeyboardLayout(DWORD dwLayout)
839 HKL layout;
840 layout = GetSystemDefaultLCID(); /* FIXME */
841 layout |= (layout<<16); /* FIXME */
842 TRACE_(keyboard)("returning %08x\n",layout);
843 return layout;
846 /****************************************************************************
847 * GetKeyboardLayoutNameA (USER32.@)
849 INT WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID)
851 sprintf(pwszKLID, "%08x",GetKeyboardLayout(0));
852 return 1;
855 /****************************************************************************
856 * GetKeyboardLayoutNameW (USER32.@)
858 INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID)
860 char buf[KL_NAMELENGTH];
861 int res = GetKeyboardLayoutNameA(buf);
862 MultiByteToWideChar( CP_ACP, 0, buf, -1, pwszKLID, KL_NAMELENGTH );
863 return res;
866 /****************************************************************************
867 * GetKeyNameTextA (USER32.@)
869 INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
871 return GetKeyNameText16(lParam,lpBuffer,nSize);
874 /****************************************************************************
875 * GetKeyNameTextW (USER32.@)
877 INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize)
879 int res;
880 LPSTR buf = HeapAlloc( GetProcessHeap(), 0, nSize );
881 if(buf == NULL) return 0; /* FIXME: is this the correct failure value?*/
882 res = GetKeyNameTextA(lParam,buf,nSize);
884 if (nSize > 0 && !MultiByteToWideChar( CP_ACP, 0, buf, -1, lpBuffer, nSize ))
885 lpBuffer[nSize-1] = 0;
886 HeapFree( GetProcessHeap(), 0, buf );
887 return res;
890 /****************************************************************************
891 * ToUnicode (USER32.@)
893 INT WINAPI ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
894 LPWSTR lpwStr, int size, UINT flags)
896 return USER_Driver.pToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
899 /****************************************************************************
900 * ToUnicodeEx (USER32.@)
902 INT WINAPI ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
903 LPWSTR lpwStr, int size, UINT flags, HKL hkl)
905 /* FIXME: need true implementation */
906 return ToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
909 /****************************************************************************
910 * ToAscii (USER32.@)
912 INT WINAPI ToAscii( UINT virtKey,UINT scanCode,LPBYTE lpKeyState,
913 LPWORD lpChar,UINT flags )
915 WCHAR uni_chars[2];
916 INT ret, n_ret;
918 ret = ToUnicode(virtKey, scanCode, lpKeyState, uni_chars, 2, flags);
919 if(ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */
920 else n_ret = ret;
921 WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL);
922 return ret;
925 /****************************************************************************
926 * ToAsciiEx (USER32.@)
928 INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
929 LPWORD lpChar, UINT flags, HKL dwhkl )
931 /* FIXME: need true implementation */
932 return ToAscii(virtKey, scanCode, lpKeyState, lpChar, flags);
935 /**********************************************************************
936 * ActivateKeyboardLayout (USER32.@)
938 * Call ignored. WINE supports only system default keyboard layout.
940 HKL WINAPI ActivateKeyboardLayout(HKL hLayout, UINT flags)
942 TRACE_(keyboard)("(%d, %d)\n", hLayout, flags);
943 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
944 return 0;
948 /***********************************************************************
949 * GetKeyboardLayoutList (USER32.@)
951 * FIXME: Supports only the system default language and layout and
952 * returns only 1 value.
954 * Return number of values available if either input parm is
955 * 0, per MS documentation.
958 INT WINAPI GetKeyboardLayoutList(INT nBuff,HKL *layouts)
960 TRACE_(keyboard)("(%d,%p)\n",nBuff,layouts);
961 if (!nBuff || !layouts)
962 return 1;
963 if (layouts)
964 layouts[0] = GetKeyboardLayout(0);
965 return 1;
969 /***********************************************************************
970 * RegisterHotKey (USER32.@)
972 BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk) {
973 FIXME_(keyboard)("(0x%08x,%d,0x%08x,%d): stub\n",hwnd,id,modifiers,vk);
974 return TRUE;
977 /***********************************************************************
978 * UnregisterHotKey (USER32.@)
980 BOOL WINAPI UnregisterHotKey(HWND hwnd,INT id) {
981 FIXME_(keyboard)("(0x%08x,%d): stub\n",hwnd,id);
982 return TRUE;
985 /***********************************************************************
986 * LoadKeyboardLayoutA (USER32.@)
987 * Call ignored. WINE supports only system default keyboard layout.
989 HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID, UINT Flags)
991 TRACE_(keyboard)("(%s, %d)\n", pwszKLID, Flags);
992 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
993 return 0;
996 /***********************************************************************
997 * LoadKeyboardLayoutW (USER32.@)
999 HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags)
1001 char buf[9];
1003 WideCharToMultiByte( CP_ACP, 0, pwszKLID, -1, buf, sizeof(buf), NULL, NULL );
1004 buf[8] = 0;
1005 return LoadKeyboardLayoutA(buf, Flags);