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
23 #include "wine/winbase16.h"
24 #include "wine/winuser16.h"
25 #include "wine/keyboard16.h"
26 #include "wine/server.h"
33 #include "debugtools.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 BYTE InputKeyStateTable[256];
45 BYTE AsyncKeyStateTable[256];
47 /* Storage for the USER-maintained mouse positions */
48 static DWORD PosX, PosY;
50 #define GET_KEYSTATE() \
51 ((InputKeyStateTable[SwappedButtons ? VK_RBUTTON : VK_LBUTTON] & 0x80 ? MK_LBUTTON : 0) | \
52 (InputKeyStateTable[SwappedButtons ? VK_LBUTTON : VK_RBUTTON] & 0x80 ? MK_RBUTTON : 0) | \
53 (InputKeyStateTable[VK_MBUTTON] & 0x80 ? MK_MBUTTON : 0) | \
54 (InputKeyStateTable[VK_SHIFT] & 0x80 ? MK_SHIFT : 0) | \
55 (InputKeyStateTable[VK_CONTROL] & 0x80 ? MK_CONTROL : 0))
61 unsigned long count : 16;
62 unsigned long code : 8;
63 unsigned long extended : 1;
64 unsigned long unused : 2;
65 unsigned long win_internal : 2;
66 unsigned long context : 1;
67 unsigned long previous : 1;
68 unsigned long transition : 1;
74 /***********************************************************************
75 * queue_raw_hardware_message
77 * Add a message to the raw hardware queue.
78 * Note: the position is relative to the desktop window.
80 static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lParam,
81 int xPos, int yPos, DWORD time, DWORD extraInfo )
83 SERVER_START_REQ( send_message )
85 req->id = (void *)GetCurrentThreadId();
86 req->type = MSG_HARDWARE_RAW;
94 req->info = extraInfo;
102 /***********************************************************************
105 * Put a keyboard event into a thread queue
107 static void queue_kbd_event( const KEYBDINPUT *ki )
114 keylp.lp1.code = ki->wScan;
115 keylp.lp1.extended = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) != 0;
116 keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
117 * don't remember where I read it - AK */
118 /* it's '1' under windows, when a dialog box appears
119 * and you press one of the underlined keys - DF*/
121 if (ki->dwFlags & KEYEVENTF_KEYUP )
123 BOOL sysKey = (InputKeyStateTable[VK_MENU] & 0x80) &&
124 !(InputKeyStateTable[VK_CONTROL] & 0x80);
125 InputKeyStateTable[ki->wVk] &= ~0x80;
126 keylp.lp1.previous = 1;
127 keylp.lp1.transition = 1;
128 message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
132 keylp.lp1.previous = (InputKeyStateTable[ki->wVk] & 0x80) != 0;
133 keylp.lp1.transition = 0;
134 if (!(InputKeyStateTable[ki->wVk] & 0x80)) InputKeyStateTable[ki->wVk] ^= 0x01;
135 InputKeyStateTable[ki->wVk] |= 0x80;
136 AsyncKeyStateTable[ki->wVk] |= 0x80;
138 message = (InputKeyStateTable[VK_MENU] & 0x80) && !(InputKeyStateTable[VK_CONTROL] & 0x80)
139 ? WM_SYSKEYDOWN : WM_KEYDOWN;
142 if (message == WM_SYSKEYDOWN || message == WM_SYSKEYUP )
143 keylp.lp1.context = (InputKeyStateTable[VK_MENU] & 0x80) != 0; /* 1 if alt */
145 TRACE_(key)(" wParam=%04x, lParam=%08lx, InputKeyState=%x\n",
146 ki->wVk, keylp.lp2, InputKeyStateTable[ki->wVk] );
148 queue_raw_hardware_message( message, ki->wVk, keylp.lp2,
149 PosX, PosY, ki->time, ki->dwExtraInfo );
153 /***********************************************************************
156 static void queue_mouse_event( const MOUSEINPUT *mi, WORD keystate )
158 if (mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
160 PosX = (mi->dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
161 PosY = (mi->dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
163 else if (mi->dwFlags & MOUSEEVENTF_MOVE)
165 int width = GetSystemMetrics(SM_CXSCREEN);
166 int height = GetSystemMetrics(SM_CYSCREEN);
167 long posX = (long) PosX, posY = (long) PosY;
169 /* dx and dy can be negative numbers for relative movements */
170 posX += (long)mi->dx;
171 posY += (long)mi->dy;
173 /* Clip to the current screen size */
174 if (posX < 0) PosX = 0;
175 else if (posX >= width) PosX = width - 1;
178 if (posY < 0) PosY = 0;
179 else if (posY >= height) PosY = height - 1;
183 if (mi->dwFlags & MOUSEEVENTF_MOVE)
185 queue_raw_hardware_message( WM_MOUSEMOVE, keystate, 0, PosX, PosY,
186 mi->time, mi->dwExtraInfo );
188 if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN))
190 InputKeyStateTable[VK_LBUTTON] |= 0x80;
191 AsyncKeyStateTable[VK_LBUTTON] |= 0x80;
192 queue_raw_hardware_message( WM_LBUTTONDOWN, keystate, 0, PosX, PosY,
193 mi->time, mi->dwExtraInfo );
195 if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP))
197 AsyncKeyStateTable[VK_LBUTTON] &= ~0x80;
198 queue_raw_hardware_message( WM_LBUTTONUP, keystate, 0, PosX, PosY,
199 mi->time, mi->dwExtraInfo );
201 if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN))
203 InputKeyStateTable[VK_RBUTTON] |= 0x80;
204 AsyncKeyStateTable[VK_RBUTTON] |= 0x80;
205 queue_raw_hardware_message( WM_RBUTTONDOWN, keystate, 0, PosX, PosY,
206 mi->time, mi->dwExtraInfo );
208 if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP))
210 AsyncKeyStateTable[VK_RBUTTON] &= ~0x80;
211 queue_raw_hardware_message( WM_RBUTTONUP, keystate, 0, PosX, PosY,
212 mi->time, mi->dwExtraInfo );
214 if (mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
216 InputKeyStateTable[VK_MBUTTON] |= 0x80;
217 AsyncKeyStateTable[VK_MBUTTON] |= 0x80;
218 queue_raw_hardware_message( WM_MBUTTONDOWN, keystate, 0, PosX, PosY,
219 mi->time, mi->dwExtraInfo );
221 if (mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
223 AsyncKeyStateTable[VK_MBUTTON] &= ~0x80;
224 queue_raw_hardware_message( WM_MBUTTONUP, keystate, 0, PosX, PosY,
225 mi->time, mi->dwExtraInfo );
227 if (mi->dwFlags & MOUSEEVENTF_WHEEL)
229 queue_raw_hardware_message( WM_MOUSEWHEEL, MAKELONG( keystate, mi->mouseData), 0,
230 PosX, PosY, mi->time, mi->dwExtraInfo );
235 /***********************************************************************
236 * SendInput (USER32.@)
238 UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
242 if (!InputEnabled) return 0;
244 for (i = 0; i < count; i++, inputs++)
249 queue_mouse_event( &inputs->u.mi, GET_KEYSTATE() );
252 queue_kbd_event( &inputs->u.ki );
255 FIXME( "INPUT_HARDWARE not supported\n" );
263 /***********************************************************************
264 * keybd_event (USER32.@)
266 void WINAPI keybd_event( BYTE bVk, BYTE bScan,
267 DWORD dwFlags, DWORD dwExtraInfo )
272 * If we are called by the Wine keyboard driver, use the additional
273 * info pointed to by the dwExtraInfo argument.
274 * Otherwise, we need to determine that info ourselves (probably
275 * less accurate, but we can't help that ...).
277 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_KEYBDEVENT) )
278 && ((WINE_KEYBDEVENT *)dwExtraInfo)->magic == WINE_KEYBDEVENT_MAGIC )
280 WINE_KEYBDEVENT *wke = (WINE_KEYBDEVENT *)dwExtraInfo;
281 input.u.ki.time = wke->time;
282 input.u.ki.dwExtraInfo = 0;
286 input.u.ki.time = GetTickCount();
287 input.u.ki.dwExtraInfo = dwExtraInfo;
289 input.type = INPUT_KEYBOARD;
290 input.u.ki.wVk = bVk;
291 input.u.ki.wScan = bScan;
292 input.u.ki.dwFlags = dwFlags;
293 SendInput( 1, &input, sizeof(input) );
297 /***********************************************************************
298 * keybd_event (USER.289)
300 void WINAPI keybd_event16( CONTEXT86 *context )
304 if (AH_reg(context) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
305 if (BH_reg(context) & 1 ) dwFlags |= KEYEVENTF_EXTENDEDKEY;
307 keybd_event( AL_reg(context), BL_reg(context),
308 dwFlags, MAKELONG(SI_reg(context), DI_reg(context)) );
312 /***********************************************************************
313 * mouse_event (USER32.@)
315 void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
316 DWORD dwData, DWORD dwExtraInfo )
321 input.type = INPUT_MOUSE;
324 input.u.mi.mouseData = dwData;
325 input.u.mi.dwFlags = dwFlags;
328 * If we are called by the Wine mouse driver, use the additional
329 * info pointed to by the dwExtraInfo argument.
330 * Otherwise, we need to determine that info ourselves (probably
331 * less accurate, but we can't help that ...).
333 if (dwExtraInfo && !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
334 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC )
336 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
338 keyState = wme->keyState;
340 if (keyState != GET_KEYSTATE())
342 /* We need to update the keystate with what X provides us */
343 InputKeyStateTable[SwappedButtons ? VK_RBUTTON : VK_LBUTTON] = (keyState & MK_LBUTTON ? 0x80 : 0);
344 InputKeyStateTable[SwappedButtons ? VK_LBUTTON : VK_RBUTTON] = (keyState & MK_RBUTTON ? 0x80 : 0);
345 InputKeyStateTable[VK_MBUTTON] = (keyState & MK_MBUTTON ? 0x80 : 0);
346 InputKeyStateTable[VK_SHIFT] = (keyState & MK_SHIFT ? 0x80 : 0);
347 InputKeyStateTable[VK_CONTROL] = (keyState & MK_CONTROL ? 0x80 : 0);
349 input.u.mi.time = wme->time;
350 input.u.mi.dwExtraInfo = (ULONG_PTR)wme->hWnd;
351 queue_mouse_event( &input.u.mi, keyState );
355 if ( dwFlags & MOUSEEVENTF_MOVE ) /* we have to actually move the cursor */
356 SetCursorPos( PosX, PosY );
358 input.u.mi.time = GetCurrentTime();
359 input.u.mi.dwExtraInfo = dwExtraInfo;
360 SendInput( 1, &input, sizeof(input) );
365 /***********************************************************************
366 * mouse_event (USER.299)
368 void WINAPI mouse_event16( CONTEXT86 *context )
370 mouse_event( AX_reg(context), BX_reg(context), CX_reg(context),
371 DX_reg(context), MAKELONG(SI_reg(context), DI_reg(context)) );
374 /***********************************************************************
375 * GetMouseEventProc (USER.337)
377 FARPROC16 WINAPI GetMouseEventProc16(void)
379 HMODULE16 hmodule = GetModuleHandle16("USER");
380 return GetProcAddress16( hmodule, "mouse_event" );
384 /**********************************************************************
385 * EnableHardwareInput (USER.331)
387 BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
389 BOOL16 bOldState = InputEnabled;
390 FIXME_(event)("(%d) - stub\n", bEnable);
391 InputEnabled = bEnable;
396 /***********************************************************************
397 * SwapMouseButton (USER.186)
399 BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
401 BOOL16 ret = SwappedButtons;
402 SwappedButtons = fSwap;
407 /***********************************************************************
408 * SwapMouseButton (USER32.@)
410 BOOL WINAPI SwapMouseButton( BOOL fSwap )
412 BOOL ret = SwappedButtons;
413 SwappedButtons = fSwap;
418 /***********************************************************************
419 * GetCursorPos (USER.17)
421 BOOL16 WINAPI GetCursorPos16( POINT16 *pt )
432 /***********************************************************************
433 * GetCursorPos (USER32.@)
435 BOOL WINAPI GetCursorPos( POINT *pt )
440 if (USER_Driver.pGetCursorPos) USER_Driver.pGetCursorPos( pt );
445 /***********************************************************************
446 * SetCursorPos (USER.70)
448 void WINAPI SetCursorPos16( INT16 x, INT16 y )
450 SetCursorPos( x, y );
454 /***********************************************************************
455 * SetCursorPos (USER32.@)
457 BOOL WINAPI SetCursorPos( INT x, INT y )
459 if (USER_Driver.pSetCursorPos) USER_Driver.pSetCursorPos( x, y );
466 /**********************************************************************
469 * We need this to be able to generate double click messages
470 * when menu code captures mouse in the window without CS_DBLCLK style.
472 HWND EVENT_Capture(HWND hwnd, INT16 ht)
474 HWND capturePrev = 0, captureWnd = 0;
475 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
479 capturePrev = GetCapture();
488 wndPtr = WIN_FindWndPtr( hwnd );
491 TRACE_(win)("(0x%04x)\n", hwnd );
492 captureWnd = wndPtr->hwndSelf;
497 /* Get the messageQ for the current thread */
498 if (!(pCurMsgQ = QUEUE_Current()))
500 WARN_(win)("\tCurrent message queue not found. Exiting!\n" );
504 /* Update the perQ capture window and send messages */
505 if( capturePrev != captureWnd )
509 /* Retrieve the message queue associated with this window */
510 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
513 WARN_(win)("\tMessage queue not found. Exiting!\n" );
517 /* Make sure that message queue for the window we are setting capture to
518 * shares the same perQ data as the current threads message queue.
520 if ( pCurMsgQ->pQData != pMsgQ->pQData )
524 PERQDATA_SetCaptureWnd( captureWnd, captureHT );
525 if (capturePrev) SendMessageA( capturePrev, WM_CAPTURECHANGED, 0, (LPARAM)hwnd );
529 /* Unlock the queues before returning */
531 QUEUE_Unlock( pMsgQ );
533 WIN_ReleaseWndPtr(wndPtr);
538 /**********************************************************************
539 * SetCapture (USER32.@)
541 HWND WINAPI SetCapture( HWND hwnd )
543 return EVENT_Capture( hwnd, HTCLIENT );
547 /**********************************************************************
548 * ReleaseCapture (USER32.@)
550 BOOL WINAPI ReleaseCapture(void)
552 return (EVENT_Capture( 0, 0 ) != 0);
556 /**********************************************************************
557 * GetCapture (USER32.@)
559 HWND WINAPI GetCapture(void)
562 return PERQDATA_GetCaptureWnd( &hittest );
565 /**********************************************************************
566 * GetAsyncKeyState (USER32.@)
568 * Determine if a key is or was pressed. retval has high-order
569 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
572 * This uses the variable AsyncMouseButtonsStates and
573 * AsyncKeyStateTable (set in event.c) which have the mouse button
574 * number or key number (whichever is applicable) set to true if the
575 * mouse or key had been depressed since the last call to
578 WORD WINAPI GetAsyncKeyState(INT nKey)
580 WORD retval = ((AsyncKeyStateTable[nKey] & 0x80) ? 0x0001 : 0) |
581 ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
582 AsyncKeyStateTable[nKey] = 0;
583 TRACE_(key)("(%x) -> %x\n", nKey, retval);
587 /**********************************************************************
588 * GetAsyncKeyState (USER.249)
590 WORD WINAPI GetAsyncKeyState16(INT16 nKey)
592 return GetAsyncKeyState(nKey);
595 /***********************************************************************
596 * IsUserIdle (USER.333)
598 BOOL16 WINAPI IsUserIdle16(void)
600 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
603 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
606 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
609 /* Should check for screen saver activation here ... */
614 /**********************************************************************
615 * VkKeyScanA (USER32.@)
617 WORD WINAPI VkKeyScanA(CHAR cChar)
619 return VkKeyScan16(cChar);
622 /******************************************************************************
623 * VkKeyScanW (USER32.@)
625 WORD WINAPI VkKeyScanW(WCHAR cChar)
627 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
630 /**********************************************************************
631 * VkKeyScanExA (USER32.@)
633 WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
635 /* FIXME: complete workaround this is */
636 return VkKeyScan16(cChar);
639 /******************************************************************************
640 * VkKeyScanExW (USER32.@)
642 WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl)
644 /* FIXME: complete workaround this is */
645 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
648 /******************************************************************************
649 * GetKeyboardType (USER32.@)
651 INT WINAPI GetKeyboardType(INT nTypeFlag)
653 return GetKeyboardType16(nTypeFlag);
656 /******************************************************************************
657 * MapVirtualKeyA (USER32.@)
659 UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
661 return MapVirtualKey16(code,maptype);
664 /******************************************************************************
665 * MapVirtualKeyW (USER32.@)
667 UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype)
669 return MapVirtualKey16(code,maptype);
672 /******************************************************************************
673 * MapVirtualKeyExA (USER32.@)
675 UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl)
678 FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
679 return MapVirtualKey16(code,maptype);
682 /******************************************************************************
683 * MapVirtualKeyExW (USER32.@)
685 UINT WINAPI MapVirtualKeyExW(UINT code, UINT maptype, HKL hkl)
688 FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
689 return MapVirtualKey16(code,maptype);
692 /****************************************************************************
693 * GetKBCodePage (USER32.@)
695 UINT WINAPI GetKBCodePage(void)
700 /****************************************************************************
701 * GetKeyboardLayoutName (USER.477)
703 INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID)
705 return GetKeyboardLayoutNameA(pwszKLID);
708 /***********************************************************************
709 * GetKeyboardLayout (USER32.@)
711 * FIXME: - device handle for keyboard layout defaulted to
712 * the language id. This is the way Windows default works.
713 * - the thread identifier (dwLayout) is also ignored.
715 HKL WINAPI GetKeyboardLayout(DWORD dwLayout)
718 layout = GetSystemDefaultLCID(); /* FIXME */
719 layout |= (layout<<16); /* FIXME */
720 TRACE_(keyboard)("returning %08x\n",layout);
724 /****************************************************************************
725 * GetKeyboardLayoutNameA (USER32.@)
727 INT WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID)
729 sprintf(pwszKLID, "%08x",GetKeyboardLayout(0));
733 /****************************************************************************
734 * GetKeyboardLayoutNameW (USER32.@)
736 INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID)
738 char buf[KL_NAMELENGTH];
739 int res = GetKeyboardLayoutNameA(buf);
740 MultiByteToWideChar( CP_ACP, 0, buf, -1, pwszKLID, KL_NAMELENGTH );
744 /****************************************************************************
745 * GetKeyNameTextA (USER32.@)
747 INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
749 return GetKeyNameText16(lParam,lpBuffer,nSize);
752 /****************************************************************************
753 * GetKeyNameTextW (USER32.@)
755 INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize)
758 LPSTR buf = HeapAlloc( GetProcessHeap(), 0, nSize );
759 if(buf == NULL) return 0; /* FIXME: is this the correct failure value?*/
760 res = GetKeyNameTextA(lParam,buf,nSize);
762 if (nSize > 0 && !MultiByteToWideChar( CP_ACP, 0, buf, -1, lpBuffer, nSize ))
763 lpBuffer[nSize-1] = 0;
764 HeapFree( GetProcessHeap(), 0, buf );
768 /****************************************************************************
769 * ToUnicode (USER32.@)
771 INT WINAPI ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
772 LPWSTR lpwStr, int size, UINT flags)
774 return USER_Driver.pToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
777 /****************************************************************************
778 * ToUnicodeEx (USER32.@)
780 INT WINAPI ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
781 LPWSTR lpwStr, int size, UINT flags, HKL hkl)
783 /* FIXME: need true implementation */
784 return ToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
787 /****************************************************************************
790 INT WINAPI ToAscii( UINT virtKey,UINT scanCode,LPBYTE lpKeyState,
791 LPWORD lpChar,UINT flags )
796 ret = ToUnicode(virtKey, scanCode, lpKeyState, uni_chars, 2, flags);
797 if(ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */
799 WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL);
803 /****************************************************************************
804 * ToAsciiEx (USER32.@)
806 INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
807 LPWORD lpChar, UINT flags, HKL dwhkl )
809 /* FIXME: need true implementation */
810 return ToAscii(virtKey, scanCode, lpKeyState, lpChar, flags);
813 /**********************************************************************
814 * ActivateKeyboardLayout (USER32.@)
816 * Call ignored. WINE supports only system default keyboard layout.
818 HKL WINAPI ActivateKeyboardLayout(HKL hLayout, UINT flags)
820 TRACE_(keyboard)("(%d, %d)\n", hLayout, flags);
821 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
826 /***********************************************************************
827 * GetKeyboardLayoutList (USER32.@)
829 * FIXME: Supports only the system default language and layout and
830 * returns only 1 value.
832 * Return number of values available if either input parm is
833 * 0, per MS documentation.
836 INT WINAPI GetKeyboardLayoutList(INT nBuff,HKL *layouts)
838 TRACE_(keyboard)("(%d,%p)\n",nBuff,layouts);
839 if (!nBuff || !layouts)
842 layouts[0] = GetKeyboardLayout(0);
847 /***********************************************************************
848 * RegisterHotKey (USER32.@)
850 BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk) {
851 FIXME_(keyboard)("(0x%08x,%d,0x%08x,%d): stub\n",hwnd,id,modifiers,vk);
855 /***********************************************************************
856 * UnregisterHotKey (USER32.@)
858 BOOL WINAPI UnregisterHotKey(HWND hwnd,INT id) {
859 FIXME_(keyboard)("(0x%08x,%d): stub\n",hwnd,id);
863 /***********************************************************************
864 * LoadKeyboardLayoutA (USER32.@)
865 * Call ignored. WINE supports only system default keyboard layout.
867 HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID, UINT Flags)
869 TRACE_(keyboard)("(%s, %d)\n", pwszKLID, Flags);
870 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
874 /***********************************************************************
875 * LoadKeyboardLayoutW (USER32.@)
877 HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags)
881 WideCharToMultiByte( CP_ACP, 0, pwszKLID, -1, buf, sizeof(buf), NULL, NULL );
883 return LoadKeyboardLayoutA(buf, Flags);