blob: 1adf1ae148da1c3e386eff0679b8d5fd2c66d142 [file] [log] [blame]
Ulrich Weigand2b067581998-11-08 12:26:36 +00001/*
2 * USER Input processing
3 *
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
9 *
10 */
11
12#include <stdlib.h>
13#include <string.h>
Jeremy Whited3e22d92000-02-10 19:03:02 +000014#include <stdio.h>
Ulrich Weigand2b067581998-11-08 12:26:36 +000015#include <ctype.h>
16#include <assert.h>
17
Jeremy Whited3e22d92000-02-10 19:03:02 +000018#include "windef.h"
19#include "wingdi.h"
Marcus Meissner61afa331999-02-22 10:16:00 +000020#include "winuser.h"
21#include "wine/winbase16.h"
22#include "wine/winuser16.h"
Marcus Meissner219cfd81999-02-24 13:05:13 +000023#include "wine/keyboard16.h"
Ulrich Weigand2b067581998-11-08 12:26:36 +000024#include "win.h"
Ulrich Weigand2b067581998-11-08 12:26:36 +000025#include "heap.h"
26#include "input.h"
27#include "keyboard.h"
28#include "mouse.h"
29#include "message.h"
Patrik Stridvall6cc47d42000-03-08 18:26:56 +000030#include "queue.h"
Ulrich Weigand24dd5d91999-09-20 18:49:02 +000031#include "module.h"
Ulrich Weigand2b067581998-11-08 12:26:36 +000032#include "debugtools.h"
33#include "struct32.h"
34#include "winerror.h"
Noel Borthwickb4278561999-02-05 10:37:53 +000035#include "task.h"
Ulrich Weigand2b067581998-11-08 12:26:36 +000036
Jeremy Whited3e22d92000-02-10 19:03:02 +000037DECLARE_DEBUG_CHANNEL(accel);
38DECLARE_DEBUG_CHANNEL(event);
39DECLARE_DEBUG_CHANNEL(key);
40DECLARE_DEBUG_CHANNEL(keyboard);
41DECLARE_DEBUG_CHANNEL(win);
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000042
Alexandre Julliarda3960291999-02-26 11:11:13 +000043static BOOL InputEnabled = TRUE;
Lionel Ulmeracc74671999-11-07 21:25:57 +000044BOOL SwappedButtons = FALSE;
Ulrich Weigand2b067581998-11-08 12:26:36 +000045
Alexandre Julliarda3960291999-02-26 11:11:13 +000046BOOL MouseButtonsStates[3];
47BOOL AsyncMouseButtonsStates[3];
Ulrich Weigand2b067581998-11-08 12:26:36 +000048BYTE InputKeyStateTable[256];
49BYTE QueueKeyStateTable[256];
50BYTE AsyncKeyStateTable[256];
51
Lionel Ulmeracc74671999-11-07 21:25:57 +000052/* Storage for the USER-maintained mouse positions */
53DWORD PosX, PosY;
54
Ulrich Weigand2b067581998-11-08 12:26:36 +000055typedef union
56{
57 struct
58 {
59 unsigned long count : 16;
60 unsigned long code : 8;
61 unsigned long extended : 1;
62 unsigned long unused : 2;
63 unsigned long win_internal : 2;
64 unsigned long context : 1;
65 unsigned long previous : 1;
66 unsigned long transition : 1;
67 } lp1;
68 unsigned long lp2;
69} KEYLP;
70
71/***********************************************************************
72 * keybd_event (USER32.583)
73 */
74void WINAPI keybd_event( BYTE bVk, BYTE bScan,
75 DWORD dwFlags, DWORD dwExtraInfo )
76{
Lionel Ulmeracc74671999-11-07 21:25:57 +000077 DWORD time, extra;
Ulrich Weigand2b067581998-11-08 12:26:36 +000078 WORD message;
79 KEYLP keylp;
80 keylp.lp2 = 0;
81
82 if (!InputEnabled) return;
83
84 /*
85 * If we are called by the Wine keyboard driver, use the additional
86 * info pointed to by the dwExtraInfo argument.
87 * Otherwise, we need to determine that info ourselves (probably
88 * less accurate, but we can't help that ...).
89 */
Alexandre Julliarda3960291999-02-26 11:11:13 +000090 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_KEYBDEVENT) )
Ulrich Weigand2b067581998-11-08 12:26:36 +000091 && ((WINE_KEYBDEVENT *)dwExtraInfo)->magic == WINE_KEYBDEVENT_MAGIC )
92 {
93 WINE_KEYBDEVENT *wke = (WINE_KEYBDEVENT *)dwExtraInfo;
Ulrich Weigand2b067581998-11-08 12:26:36 +000094 time = wke->time;
95 extra = 0;
96 }
97 else
98 {
Ulrich Weigand2b067581998-11-08 12:26:36 +000099 time = GetTickCount();
100 extra = dwExtraInfo;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000101 }
102
103
104 keylp.lp1.count = 1;
105 keylp.lp1.code = bScan;
106 keylp.lp1.extended = (dwFlags & KEYEVENTF_EXTENDEDKEY) != 0;
107 keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
108 * don't remember where I read it - AK */
109 /* it's '1' under windows, when a dialog box appears
110 * and you press one of the underlined keys - DF*/
111
112 if ( dwFlags & KEYEVENTF_KEYUP )
113 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000114 BOOL sysKey = (InputKeyStateTable[VK_MENU] & 0x80)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000115 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
116 && !(dwFlags & KEYEVENTF_WINE_FORCEEXTENDED); /* for Alt from AltGr */
117
118 InputKeyStateTable[bVk] &= ~0x80;
119 keylp.lp1.previous = 1;
120 keylp.lp1.transition = 1;
121 message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
122 }
123 else
124 {
125 keylp.lp1.previous = (InputKeyStateTable[bVk] & 0x80) != 0;
126 keylp.lp1.transition = 0;
127
128 if (!(InputKeyStateTable[bVk] & 0x80))
129 InputKeyStateTable[bVk] ^= 0x01;
130 InputKeyStateTable[bVk] |= 0x80;
131
132 message = (InputKeyStateTable[VK_MENU] & 0x80)
133 && !(InputKeyStateTable[VK_CONTROL] & 0x80)
134 ? WM_SYSKEYDOWN : WM_KEYDOWN;
135 }
136
137 if ( message == WM_SYSKEYDOWN || message == WM_SYSKEYUP )
138 keylp.lp1.context = (InputKeyStateTable[VK_MENU] & 0x80) != 0; /* 1 if alt */
139
140
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000141 TRACE_(key)(" wParam=%04X, lParam=%08lX\n", bVk, keylp.lp2 );
142 TRACE_(key)(" InputKeyState=%X\n", InputKeyStateTable[bVk] );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000143
Lionel Ulmeracc74671999-11-07 21:25:57 +0000144 hardware_event( message, bVk, keylp.lp2, PosX, PosY, time, extra );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000145}
146
147/***********************************************************************
Ulrich Weigand24dd5d91999-09-20 18:49:02 +0000148 * WIN16_keybd_event (USER.289)
149 */
150void WINAPI WIN16_keybd_event( CONTEXT86 *context )
151{
152 DWORD dwFlags = 0;
153
154 if (AH_reg(context) & 0x80) dwFlags |= KEYEVENTF_KEYUP;
155 if (BH_reg(context) & 1 ) dwFlags |= KEYEVENTF_EXTENDEDKEY;
156
157 keybd_event( AL_reg(context), BL_reg(context),
158 dwFlags, MAKELONG(SI_reg(context), DI_reg(context)) );
159}
160
161/***********************************************************************
Ulrich Weigand2b067581998-11-08 12:26:36 +0000162 * mouse_event (USER32.584)
163 */
164void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
165 DWORD cButtons, DWORD dwExtraInfo )
166{
Lionel Ulmeracc74671999-11-07 21:25:57 +0000167 DWORD time, extra;
168 DWORD keyState;
169
Ulrich Weigand2b067581998-11-08 12:26:36 +0000170 if (!InputEnabled) return;
171
Lionel Ulmeracc74671999-11-07 21:25:57 +0000172 if ( dwFlags & MOUSEEVENTF_MOVE )
173 {
174 if ( dwFlags & MOUSEEVENTF_ABSOLUTE )
175 {
176 PosX = (dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
177 PosY = (dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
178 }
179 else
180 {
181 int width = GetSystemMetrics(SM_CXSCREEN);
182 int height = GetSystemMetrics(SM_CYSCREEN);
183 long posX = (long) PosX, posY = (long) PosY;
184
185 /* dx and dy can be negative numbers for relative movements */
186 posX += (long) dx;
187 posY += (long) dy;
188
189 /* Clip to the current screen size */
190 if (posX < 0) PosX = 0;
191 else if (posX >= width) PosX = width - 1;
192 else PosX = posX;
193
194 if (posY < 0) PosY = 0;
195 else if (posY >= height) PosY = height - 1;
196 else PosY = posY;
197 }
198 }
199
Ulrich Weigand2b067581998-11-08 12:26:36 +0000200 /*
201 * If we are called by the Wine mouse driver, use the additional
202 * info pointed to by the dwExtraInfo argument.
203 * Otherwise, we need to determine that info ourselves (probably
204 * less accurate, but we can't help that ...).
205 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000206 if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
Ulrich Weigand2b067581998-11-08 12:26:36 +0000207 && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC )
208 {
209 WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000210 time = wme->time;
211 extra = (DWORD)wme->hWnd;
Lionel Ulmeracc74671999-11-07 21:25:57 +0000212 keyState = wme->keyState;
213
214 if (keyState != GET_KEYSTATE()) {
215 /* We need to update the keystate with what X provides us */
216 MouseButtonsStates[SwappedButtons ? 2 : 0] = (keyState & MK_LBUTTON ? TRUE : FALSE);
217 MouseButtonsStates[SwappedButtons ? 0 : 2] = (keyState & MK_RBUTTON ? TRUE : FALSE);
218 MouseButtonsStates[1] = (keyState & MK_MBUTTON ? TRUE : FALSE);
219 InputKeyStateTable[VK_SHIFT] = (keyState & MK_SHIFT ? 0x80 : 0);
220 InputKeyStateTable[VK_CONTROL] = (keyState & MK_CONTROL ? 0x80 : 0);
221 }
Ulrich Weigand2b067581998-11-08 12:26:36 +0000222 }
223 else
224 {
225 time = GetTickCount();
226 extra = dwExtraInfo;
Lionel Ulmeracc74671999-11-07 21:25:57 +0000227 keyState = GET_KEYSTATE();
228
229 if ( dwFlags & MOUSEEVENTF_MOVE )
230 {
231 /* We have to actually move the cursor */
232 SetCursorPos( PosX, PosY );
233 }
Ulrich Weigand2b067581998-11-08 12:26:36 +0000234 }
235
Lionel Ulmeracc74671999-11-07 21:25:57 +0000236
Ulrich Weigand2b067581998-11-08 12:26:36 +0000237 if ( dwFlags & MOUSEEVENTF_MOVE )
238 {
239 hardware_event( WM_MOUSEMOVE,
Lionel Ulmeracc74671999-11-07 21:25:57 +0000240 keyState, 0L, PosX, PosY, time, extra );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000241 }
242 if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN) )
243 {
244 MouseButtonsStates[0] = AsyncMouseButtonsStates[0] = TRUE;
245 hardware_event( WM_LBUTTONDOWN,
Lionel Ulmeracc74671999-11-07 21:25:57 +0000246 keyState, 0L, PosX, PosY, time, extra );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000247 }
248 if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP) )
249 {
250 MouseButtonsStates[0] = FALSE;
251 hardware_event( WM_LBUTTONUP,
Lionel Ulmeracc74671999-11-07 21:25:57 +0000252 keyState, 0L, PosX, PosY, time, extra );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000253 }
254 if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN) )
255 {
256 MouseButtonsStates[2] = AsyncMouseButtonsStates[2] = TRUE;
257 hardware_event( WM_RBUTTONDOWN,
Lionel Ulmeracc74671999-11-07 21:25:57 +0000258 keyState, 0L, PosX, PosY, time, extra );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000259 }
260 if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP) )
261 {
262 MouseButtonsStates[2] = FALSE;
263 hardware_event( WM_RBUTTONUP,
Lionel Ulmeracc74671999-11-07 21:25:57 +0000264 keyState, 0L, PosX, PosY, time, extra );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000265 }
266 if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN )
267 {
268 MouseButtonsStates[1] = AsyncMouseButtonsStates[1] = TRUE;
269 hardware_event( WM_MBUTTONDOWN,
Lionel Ulmeracc74671999-11-07 21:25:57 +0000270 keyState, 0L, PosX, PosY, time, extra );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000271 }
272 if ( dwFlags & MOUSEEVENTF_MIDDLEUP )
273 {
274 MouseButtonsStates[1] = FALSE;
275 hardware_event( WM_MBUTTONUP,
Lionel Ulmeracc74671999-11-07 21:25:57 +0000276 keyState, 0L, PosX, PosY, time, extra );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000277 }
Stephane Lussier4bdf4af2000-04-18 11:56:33 +0000278 if ( dwFlags & MOUSEEVENTF_WHEEL )
279 {
280 hardware_event( WM_MOUSEWHEEL,
281 keyState, 0L, PosX, PosY, time, extra );
282 }
Ulrich Weigand2b067581998-11-08 12:26:36 +0000283}
284
Ulrich Weigand24dd5d91999-09-20 18:49:02 +0000285/***********************************************************************
286 * WIN16_mouse_event (USER.299)
287 */
288void WINAPI WIN16_mouse_event( CONTEXT86 *context )
289{
290 mouse_event( AX_reg(context), BX_reg(context), CX_reg(context),
291 DX_reg(context), MAKELONG(SI_reg(context), DI_reg(context)) );
292}
293
294/***********************************************************************
295 * GetMouseEventProc (USER.337)
296 */
297FARPROC16 WINAPI GetMouseEventProc16(void)
298{
299 HMODULE16 hmodule = GetModuleHandle16("USER");
300 return NE_GetEntryPoint( hmodule, NE_GetOrdinal( hmodule, "mouse_event" ));
301}
302
303
Ulrich Weigand2b067581998-11-08 12:26:36 +0000304/**********************************************************************
305 * EnableHardwareInput (USER.331)
306 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000307BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000308{
309 BOOL16 bOldState = InputEnabled;
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000310 FIXME_(event)("(%d) - stub\n", bEnable);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000311 InputEnabled = bEnable;
312 return bOldState;
313}
314
315
316/***********************************************************************
317 * SwapMouseButton16 (USER.186)
318 */
319BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
320{
321 BOOL16 ret = SwappedButtons;
322 SwappedButtons = fSwap;
323 return ret;
324}
325
326
327/***********************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000328 * SwapMouseButton (USER32.537)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000329 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000330BOOL WINAPI SwapMouseButton( BOOL fSwap )
Ulrich Weigand2b067581998-11-08 12:26:36 +0000331{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000332 BOOL ret = SwappedButtons;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000333 SwappedButtons = fSwap;
334 return ret;
335}
336
337/**********************************************************************
338 * EVENT_Capture
339 *
340 * We need this to be able to generate double click messages
341 * when menu code captures mouse in the window without CS_DBLCLK style.
342 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000343HWND EVENT_Capture(HWND hwnd, INT16 ht)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000344{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000345 HWND capturePrev = 0, captureWnd = 0;
Noel Borthwickb4278561999-02-05 10:37:53 +0000346 MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
347 WND* wndPtr = 0;
348 INT16 captureHT = 0;
349
350 /* Get the messageQ for the current thread */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000351 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
Noel Borthwickb4278561999-02-05 10:37:53 +0000352 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000353 WARN_(win)("\tCurrent message queue not found. Exiting!\n" );
Noel Borthwickb4278561999-02-05 10:37:53 +0000354 goto CLEANUP;
355 }
356
357 /* Get the current capture window from the perQ data of the current message Q */
358 capturePrev = PERQDATA_GetCaptureWnd( pCurMsgQ->pQData );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000359
360 if (!hwnd)
361 {
362 captureWnd = 0L;
363 captureHT = 0;
364 }
365 else
366 {
Noel Borthwickb4278561999-02-05 10:37:53 +0000367 wndPtr = WIN_FindWndPtr( hwnd );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000368 if (wndPtr)
369 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000370 TRACE_(win)("(0x%04x)\n", hwnd );
Ulrich Weigand2b067581998-11-08 12:26:36 +0000371 captureWnd = hwnd;
372 captureHT = ht;
373 }
374 }
375
Noel Borthwickb4278561999-02-05 10:37:53 +0000376 /* Update the perQ capture window and send messages */
377 if( capturePrev != captureWnd )
378 {
379 if (wndPtr)
380 {
381 /* Retrieve the message queue associated with this window */
382 pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
383 if ( !pMsgQ )
384 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000385 WARN_(win)("\tMessage queue not found. Exiting!\n" );
Noel Borthwickb4278561999-02-05 10:37:53 +0000386 goto CLEANUP;
387 }
388
389 /* Make sure that message queue for the window we are setting capture to
390 * shares the same perQ data as the current threads message queue.
391 */
392 if ( pCurMsgQ->pQData != pMsgQ->pQData )
393 goto CLEANUP;
394 }
395
396 PERQDATA_SetCaptureWnd( pCurMsgQ->pQData, captureWnd );
397 PERQDATA_SetCaptureInfo( pCurMsgQ->pQData, captureHT );
398
399 if( capturePrev )
Ulrich Weigand2b067581998-11-08 12:26:36 +0000400 {
401 WND* wndPtr = WIN_FindWndPtr( capturePrev );
402 if( wndPtr && (wndPtr->flags & WIN_ISWIN32) )
Alexandre Julliarda3960291999-02-26 11:11:13 +0000403 SendMessageA( capturePrev, WM_CAPTURECHANGED, 0L, hwnd);
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000404 WIN_ReleaseWndPtr(wndPtr);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000405 }
Noel Borthwickb4278561999-02-05 10:37:53 +0000406}
407
408CLEANUP:
409 /* Unlock the queues before returning */
410 if ( pMsgQ )
411 QUEUE_Unlock( pMsgQ );
412 if ( pCurMsgQ )
413 QUEUE_Unlock( pCurMsgQ );
414
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000415 WIN_ReleaseWndPtr(wndPtr);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000416 return capturePrev;
417}
418
Ulrich Weigand2b067581998-11-08 12:26:36 +0000419
420/**********************************************************************
421 * SetCapture16 (USER.18)
422 */
423HWND16 WINAPI SetCapture16( HWND16 hwnd )
424{
425 return (HWND16)EVENT_Capture( hwnd, HTCLIENT );
426}
427
428
429/**********************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000430 * SetCapture (USER32.464)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000431 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000432HWND WINAPI SetCapture( HWND hwnd )
Ulrich Weigand2b067581998-11-08 12:26:36 +0000433{
434 return EVENT_Capture( hwnd, HTCLIENT );
435}
436
437
438/**********************************************************************
439 * ReleaseCapture (USER.19) (USER32.439)
440 */
Zygo Blaxell007f1331999-04-15 16:40:16 +0000441BOOL WINAPI ReleaseCapture(void)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000442{
Zygo Blaxell007f1331999-04-15 16:40:16 +0000443 return (EVENT_Capture( 0, 0 ) != 0);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000444}
445
446
447/**********************************************************************
448 * GetCapture16 (USER.236)
449 */
450HWND16 WINAPI GetCapture16(void)
451{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000452 return (HWND16)GetCapture();
Ulrich Weigand2b067581998-11-08 12:26:36 +0000453}
454
455/**********************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000456 * GetCapture (USER32.208)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000457 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000458HWND WINAPI GetCapture(void)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000459{
Noel Borthwickb4278561999-02-05 10:37:53 +0000460 MESSAGEQUEUE *pCurMsgQ = 0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000461 HWND hwndCapture = 0;
Noel Borthwickb4278561999-02-05 10:37:53 +0000462
463 /* Get the messageQ for the current thread */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000464 if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
Noel Borthwickb4278561999-02-05 10:37:53 +0000465{
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000466 TRACE_(win)("GetCapture32: Current message queue not found. Exiting!\n" );
Noel Borthwickb4278561999-02-05 10:37:53 +0000467 return 0;
468 }
469
470 /* Get the current capture window from the perQ data of the current message Q */
471 hwndCapture = PERQDATA_GetCaptureWnd( pCurMsgQ->pQData );
472
473 QUEUE_Unlock( pCurMsgQ );
474 return hwndCapture;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000475}
476
477/**********************************************************************
478 * GetKeyState (USER.106)
479 */
Uwe Bonnes9fdceb81998-11-08 13:12:49 +0000480INT16 WINAPI GetKeyState16(INT16 vkey)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000481{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000482 return GetKeyState(vkey);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000483}
484
485/**********************************************************************
486 * GetKeyState (USER32.249)
487 *
488 * An application calls the GetKeyState function in response to a
489 * keyboard-input message. This function retrieves the state of the key
490 * at the time the input message was generated. (SDK 3.1 Vol 2. p 390)
491 */
Patrik Stridvall8276f691999-09-23 11:48:02 +0000492SHORT WINAPI GetKeyState(INT vkey)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000493{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000494 INT retval;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000495
496 switch (vkey)
497 {
498 case VK_LBUTTON : /* VK_LBUTTON is 1 */
499 retval = MouseButtonsStates[0] ? 0x8000 : 0;
500 break;
501 case VK_MBUTTON : /* VK_MBUTTON is 4 */
502 retval = MouseButtonsStates[1] ? 0x8000 : 0;
503 break;
504 case VK_RBUTTON : /* VK_RBUTTON is 2 */
505 retval = MouseButtonsStates[2] ? 0x8000 : 0;
506 break;
507 default :
508 if (vkey >= 'a' && vkey <= 'z')
509 vkey += 'A' - 'a';
510 retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
511 (WORD)(QueueKeyStateTable[vkey] & 0x01);
512 }
513 /* TRACE(key, "(0x%x) -> %x\n", vkey, retval); */
514 return retval;
515}
516
517/**********************************************************************
518 * GetKeyboardState (USER.222)(USER32.254)
519 *
520 * An application calls the GetKeyboardState function in response to a
521 * keyboard-input message. This function retrieves the state of the keyboard
522 * at the time the input message was generated. (SDK 3.1 Vol 2. p 387)
523 */
Francis Beaudetee3c1d71999-05-08 09:35:37 +0000524BOOL WINAPI GetKeyboardState(LPBYTE lpKeyState)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000525{
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000526 TRACE_(key)("(%p)\n", lpKeyState);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000527 if (lpKeyState != NULL) {
528 QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
529 QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
530 QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
531 memcpy(lpKeyState, QueueKeyStateTable, 256);
532 }
Francis Beaudetee3c1d71999-05-08 09:35:37 +0000533
534 return TRUE;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000535}
536
537/**********************************************************************
538 * SetKeyboardState (USER.223)(USER32.484)
539 */
Francis Beaudetee3c1d71999-05-08 09:35:37 +0000540BOOL WINAPI SetKeyboardState(LPBYTE lpKeyState)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000541{
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000542 TRACE_(key)("(%p)\n", lpKeyState);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000543 if (lpKeyState != NULL) {
544 memcpy(QueueKeyStateTable, lpKeyState, 256);
545 MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0);
546 MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0);
547 MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0);
548 }
Francis Beaudetee3c1d71999-05-08 09:35:37 +0000549
550 return TRUE;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000551}
552
553/**********************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000554 * GetAsyncKeyState (USER32.207)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000555 *
556 * Determine if a key is or was pressed. retval has high-order
557 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
558 * been pressed.
559 *
560 * This uses the variable AsyncMouseButtonsStates and
561 * AsyncKeyStateTable (set in event.c) which have the mouse button
562 * number or key number (whichever is applicable) set to true if the
563 * mouse or key had been depressed since the last call to
564 * GetAsyncKeyState.
565 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000566WORD WINAPI GetAsyncKeyState(INT nKey)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000567{
568 short retval;
569
570 switch (nKey) {
571 case VK_LBUTTON:
572 retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) |
573 (MouseButtonsStates[0] ? 0x8000 : 0);
574 break;
575 case VK_MBUTTON:
576 retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) |
577 (MouseButtonsStates[1] ? 0x8000 : 0);
578 break;
579 case VK_RBUTTON:
580 retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) |
581 (MouseButtonsStates[2] ? 0x8000 : 0);
582 break;
583 default:
584 retval = AsyncKeyStateTable[nKey] |
585 ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
586 break;
587 }
588
589 /* all states to false */
590 memset( AsyncMouseButtonsStates, 0, sizeof(AsyncMouseButtonsStates) );
591 memset( AsyncKeyStateTable, 0, sizeof(AsyncKeyStateTable) );
592
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000593 TRACE_(key)("(%x) -> %x\n", nKey, retval);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000594 return retval;
595}
596
597/**********************************************************************
598 * GetAsyncKeyState16 (USER.249)
599 */
600WORD WINAPI GetAsyncKeyState16(INT16 nKey)
601{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000602 return GetAsyncKeyState(nKey);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000603}
604
Ulrich Weigand5cd47371999-05-22 19:00:27 +0000605/***********************************************************************
606 * IsUserIdle (USER.333)
607 */
608BOOL16 WINAPI IsUserIdle16(void)
609{
610 if ( GetAsyncKeyState( VK_LBUTTON ) & 0x8000 )
611 return FALSE;
612
613 if ( GetAsyncKeyState( VK_RBUTTON ) & 0x8000 )
614 return FALSE;
615
616 if ( GetAsyncKeyState( VK_MBUTTON ) & 0x8000 )
617 return FALSE;
618
619 /* Should check for screen saver activation here ... */
620
621 return TRUE;
622}
623
Ulrich Weigand2b067581998-11-08 12:26:36 +0000624/**********************************************************************
625 * KBD_translate_accelerator
626 *
627 * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP -messages
628 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000629static BOOL KBD_translate_accelerator(HWND hWnd,LPMSG msg,
Ulrich Weigand2b067581998-11-08 12:26:36 +0000630 BYTE fVirt,WORD key,WORD cmd)
631{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000632 BOOL sendmsg = FALSE;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000633
634 if(msg->wParam == key)
635 {
636 if (msg->message == WM_CHAR) {
637 if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )
638 {
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000639 TRACE_(accel)("found accel for WM_CHAR: ('%c')\n",
Ulrich Weigand2b067581998-11-08 12:26:36 +0000640 msg->wParam&0xff);
641 sendmsg=TRUE;
642 }
643 } else {
644 if(fVirt & FVIRTKEY) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000645 INT mask = 0;
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000646 TRACE_(accel)("found accel for virt_key %04x (scan %04x)\n",
Ulrich Weigand2b067581998-11-08 12:26:36 +0000647 msg->wParam,0xff & HIWORD(msg->lParam));
Alexandre Julliarda3960291999-02-26 11:11:13 +0000648 if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
649 if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
650 if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000651 if(mask == (fVirt & (FSHIFT | FCONTROL | FALT)))
652 sendmsg=TRUE;
653 else
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000654 TRACE_(accel)(", but incorrect SHIFT/CTRL/ALT-state\n");
Ulrich Weigand2b067581998-11-08 12:26:36 +0000655 }
656 else
657 {
658 if (!(msg->lParam & 0x01000000)) /* no special_key */
659 {
660 if ((fVirt & FALT) && (msg->lParam & 0x20000000))
661 { /* ^^ ALT pressed */
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000662 TRACE_(accel)("found accel for Alt-%c\n", msg->wParam&0xff);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000663 sendmsg=TRUE;
664 }
665 }
666 }
667 }
668
669 if (sendmsg) /* found an accelerator, but send a message... ? */
670 {
671 INT16 iSysStat,iStat,mesg=0;
672 HMENU16 hMenu;
673
674 if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
675 mesg=1;
676 else
Alexandre Julliarda3960291999-02-26 11:11:13 +0000677 if (GetCapture())
Ulrich Weigand2b067581998-11-08 12:26:36 +0000678 mesg=2;
679 else
Alexandre Julliarda3960291999-02-26 11:11:13 +0000680 if (!IsWindowEnabled(hWnd))
Ulrich Weigand2b067581998-11-08 12:26:36 +0000681 mesg=3;
682 else
683 {
684 WND* wndPtr = WIN_FindWndPtr(hWnd);
685
Alexandre Julliarda3960291999-02-26 11:11:13 +0000686 hMenu = (wndPtr->dwStyle & WS_CHILD) ? 0 : (HMENU)wndPtr->wIDmenu;
687 iSysStat = (wndPtr->hSysMenu) ? GetMenuState(GetSubMenu16(wndPtr->hSysMenu, 0),
Ulrich Weigand2b067581998-11-08 12:26:36 +0000688 cmd, MF_BYCOMMAND) : -1 ;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000689 iStat = (hMenu) ? GetMenuState(hMenu,
Ulrich Weigand2b067581998-11-08 12:26:36 +0000690 cmd, MF_BYCOMMAND) : -1 ;
691
Francois Boisvert6b1b41c1999-03-14 17:25:32 +0000692 WIN_ReleaseWndPtr(wndPtr);
693
Ulrich Weigand2b067581998-11-08 12:26:36 +0000694 if (iSysStat!=-1)
695 {
696 if (iSysStat & (MF_DISABLED|MF_GRAYED))
697 mesg=4;
698 else
699 mesg=WM_SYSCOMMAND;
700 }
701 else
702 {
703 if (iStat!=-1)
704 {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000705 if (IsIconic(hWnd))
Ulrich Weigand2b067581998-11-08 12:26:36 +0000706 mesg=5;
707 else
708 {
709 if (iStat & (MF_DISABLED|MF_GRAYED))
710 mesg=6;
711 else
712 mesg=WM_COMMAND;
713 }
714 }
715 else
716 mesg=WM_COMMAND;
717 }
718 }
Rein Klazesc18f6292000-03-24 19:46:13 +0000719 if( mesg==WM_COMMAND ) {
720 TRACE_(accel)(", sending WM_COMMAND, wParam=%0x\n", 0x10000 | cmd);
721 SendMessageA(hWnd, mesg, 0x10000 | cmd, 0L);
722 } else if( mesg==WM_SYSCOMMAND ) {
723 TRACE_(accel)(", sending WM_SYSCOMMAND, wParam=%0x\n", cmd);
Alexandre Julliarda3960291999-02-26 11:11:13 +0000724 SendMessageA(hWnd, mesg, cmd, 0x00010000L);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000725 }
726 else
727 {
728 /* some reasons for NOT sending the WM_{SYS}COMMAND message:
729 * #0: unknown (please report!)
730 * #1: for WM_KEYUP,WM_SYSKEYUP
731 * #2: mouse is captured
732 * #3: window is disabled
733 * #4: it's a disabled system menu option
734 * #5: it's a menu option, but window is iconic
735 * #6: it's a menu option, but disabled
736 */
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000737 TRACE_(accel)(", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000738 if(mesg==0)
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000739 ERR_(accel)(" unknown reason - please report!");
Ulrich Weigand2b067581998-11-08 12:26:36 +0000740 }
741 return TRUE;
742 }
743 }
744 return FALSE;
745}
746
747/**********************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000748 * TranslateAccelerator (USER32.551)(USER32.552)(USER32.553)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000749 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000750INT WINAPI TranslateAccelerator(HWND hWnd, HACCEL hAccel, LPMSG msg)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000751{
Marcus Meissner688c5651999-01-22 17:09:46 +0000752 /* YES, Accel16! */
Gerard Patel16c3cc21999-05-29 14:02:28 +0000753 LPACCEL16 lpAccelTbl;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000754 int i;
755
Gerard Patel16c3cc21999-05-29 14:02:28 +0000756 if (msg == NULL)
757 {
758 WARN_(accel)("msg null; should hang here to be win compatible\n");
759 return 0;
760 }
761 if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(hAccel)))
762 {
763 WARN_(accel)("invalid accel handle=%x\n", hAccel);
764 return 0;
765 }
766 if ((msg->message != WM_KEYDOWN &&
Ulrich Weigand2b067581998-11-08 12:26:36 +0000767 msg->message != WM_KEYUP &&
768 msg->message != WM_SYSKEYDOWN &&
769 msg->message != WM_SYSKEYUP &&
Gerard Patel16c3cc21999-05-29 14:02:28 +0000770 msg->message != WM_CHAR)) return 0;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000771
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000772 TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x,"
Gerard Patel16c3cc21999-05-29 14:02:28 +0000773 "msg->hwnd=%04x, msg->message=%04x, wParam=%08x, lParam=%lx\n",
774 hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000775
776 i = 0;
777 do
778 {
779 if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
780 lpAccelTbl[i].key,lpAccelTbl[i].cmd))
781 return 1;
782 } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000783 WARN_(accel)("couldn't translate accelerator key\n");
Ulrich Weigand2b067581998-11-08 12:26:36 +0000784 return 0;
785}
786
787/**********************************************************************
788 * TranslateAccelerator16 (USER.178)
789 */
790INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
791{
Gerard Patel16c3cc21999-05-29 14:02:28 +0000792 LPACCEL16 lpAccelTbl;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000793 int i;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000794 MSG msg32;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000795
Gerard Patel16c3cc21999-05-29 14:02:28 +0000796 if (msg == NULL)
797 {
798 WARN_(accel)("msg null; should hang here to be win compatible\n");
799 return 0;
800 }
801 if (!hAccel || !(lpAccelTbl = (LPACCEL16) LockResource16(hAccel)))
802 {
803 WARN_(accel)("invalid accel handle=%x\n", hAccel);
804 return 0;
805 }
806 if ((msg->message != WM_KEYDOWN &&
Ulrich Weigand2b067581998-11-08 12:26:36 +0000807 msg->message != WM_KEYUP &&
808 msg->message != WM_SYSKEYDOWN &&
809 msg->message != WM_SYSKEYUP &&
Gerard Patel16c3cc21999-05-29 14:02:28 +0000810 msg->message != WM_CHAR)) return 0;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000811
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000812 TRACE_(accel)("TranslateAccelerators hAccel=%04x, hWnd=%04x,\
Gerard Patel16c3cc21999-05-29 14:02:28 +0000813msg->hwnd=%04x, msg->message=%04x, wParam=%04x, lParam=%lx\n", hAccel,hWnd,msg->hwnd,msg->message,msg->wParam,msg->lParam);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000814
Gerard Patel16c3cc21999-05-29 14:02:28 +0000815 STRUCT32_MSG16to32(msg,&msg32);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000816
817 i = 0;
818 do
819 {
820 if (KBD_translate_accelerator(hWnd,&msg32,lpAccelTbl[i].fVirt,
821 lpAccelTbl[i].key,lpAccelTbl[i].cmd))
822 return 1;
823 } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000824 WARN_(accel)("couldn't translate accelerator key\n");
Ulrich Weigand2b067581998-11-08 12:26:36 +0000825 return 0;
826}
827
828
829/**********************************************************************
830 * VkKeyScanA (USER32.573)
831 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000832WORD WINAPI VkKeyScanA(CHAR cChar)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000833{
834 return VkKeyScan16(cChar);
835}
836
837/******************************************************************************
838 * VkKeyScanW (USER32.576)
839 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000840WORD WINAPI VkKeyScanW(WCHAR cChar)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000841{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000842 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
Ulrich Weigand2b067581998-11-08 12:26:36 +0000843}
844
Alexandre Julliardf80b2ab1999-03-28 13:15:40 +0000845/**********************************************************************
846 * VkKeyScanExA (USER32.574)
847 */
848WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
849{
850 /* FIXME: complete workaround this is */
851 return VkKeyScan16(cChar);
852}
853
854/******************************************************************************
855 * VkKeyScanExW (USER32.575)
856 */
857WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl)
858{
859 /* FIXME: complete workaround this is */
860 return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
861}
862
Ulrich Weigand2b067581998-11-08 12:26:36 +0000863/******************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000864 * GetKeyboardType (USER32.255)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000865 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000866INT WINAPI GetKeyboardType(INT nTypeFlag)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000867{
868 return GetKeyboardType16(nTypeFlag);
869}
870
871/******************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000872 * MapVirtualKeyA (USER32.383)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000873 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000874UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000875{
876 return MapVirtualKey16(code,maptype);
877}
878
879/******************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000880 * MapVirtualKeyW (USER32.385)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000881 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000882UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000883{
884 return MapVirtualKey16(code,maptype);
885}
886
Marcus Meissner592c9101999-02-13 08:53:22 +0000887/******************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000888 * MapVirtualKeyExA (USER32.384)
Marcus Meissner592c9101999-02-13 08:53:22 +0000889 */
Patrik Stridvall533d3332000-03-28 19:31:18 +0000890UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl)
Marcus Meissner592c9101999-02-13 08:53:22 +0000891{
892 if (hkl)
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000893 FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
Marcus Meissner592c9101999-02-13 08:53:22 +0000894 return MapVirtualKey16(code,maptype);
895}
896
Ulrich Weigand2b067581998-11-08 12:26:36 +0000897/****************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000898 * GetKBCodePage (USER32.246)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000899 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000900UINT WINAPI GetKBCodePage(void)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000901{
902 return GetKBCodePage16();
903}
904
905/****************************************************************************
Ulrich Weigand8bf078b1998-11-14 18:26:59 +0000906 * GetKeyboardLayoutName16 (USER.477)
907 */
908INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID)
909{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000910 return GetKeyboardLayoutNameA(pwszKLID);
Ulrich Weigand8bf078b1998-11-14 18:26:59 +0000911}
912
Guy Albertelli38d9ce81999-02-28 11:13:16 +0000913/***********************************************************************
914 * GetKeyboardLayout (USER32.250)
915 *
916 * FIXME: - device handle for keyboard layout defaulted to
917 * the language id. This is the way Windows default works.
918 * - the thread identifier (dwLayout) is also ignored.
919 */
920HKL WINAPI GetKeyboardLayout(DWORD dwLayout)
921{
922 HKL layout;
923 layout = GetSystemDefaultLCID(); /* FIXME */
924 layout |= (layout<<16); /* FIXME */
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000925 TRACE_(keyboard)("returning %08x\n",layout);
Guy Albertelli38d9ce81999-02-28 11:13:16 +0000926 return layout;
927}
928
Ulrich Weigand8bf078b1998-11-14 18:26:59 +0000929/****************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000930 * GetKeyboardLayoutNameA (USER32.252)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000931 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000932INT WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000933{
Guy Albertelli38d9ce81999-02-28 11:13:16 +0000934 sprintf(pwszKLID, "%08x",GetKeyboardLayout(0));
Ulrich Weigand8bf078b1998-11-14 18:26:59 +0000935 return 1;
Ulrich Weigand2b067581998-11-08 12:26:36 +0000936}
937
938/****************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000939 * GetKeyboardLayoutNameW (USER32.253)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000940 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000941INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000942{
Dimitrie O. Paun4d48dd32000-04-30 12:22:18 +0000943 char buf[9];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000944 int res = GetKeyboardLayoutNameA(buf);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000945 lstrcpyAtoW(pwszKLID,buf);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000946 return res;
947}
948
949/****************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000950 * GetKeyNameTextA (USER32.247)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000951 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000952INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000953{
954 return GetKeyNameText16(lParam,lpBuffer,nSize);
955}
956
957/****************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000958 * GetKeyNameTextW (USER32.248)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000959 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000960INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000961{
Dimitrie O. Paun4d48dd32000-04-30 12:22:18 +0000962 int res;
963 LPSTR buf = HeapAlloc( GetProcessHeap(), 0, nSize );
964 if(buf == NULL) return 0; /* FIXME: is this the correct failure value?*/
965 res = GetKeyNameTextA(lParam,buf,nSize);
Ulrich Weigand2b067581998-11-08 12:26:36 +0000966
967 lstrcpynAtoW(lpBuffer,buf,nSize);
968 HeapFree( GetProcessHeap(), 0, buf );
969 return res;
970}
971
972/****************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000973 * ToAscii (USER32.546)
Ulrich Weigand2b067581998-11-08 12:26:36 +0000974 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000975INT WINAPI ToAscii( UINT virtKey,UINT scanCode,LPBYTE lpKeyState,
976 LPWORD lpChar,UINT flags )
Ulrich Weigand2b067581998-11-08 12:26:36 +0000977{
978 return ToAscii16(virtKey,scanCode,lpKeyState,lpChar,flags);
979}
980
Alexandre Julliardf80b2ab1999-03-28 13:15:40 +0000981/****************************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000982 * ToAsciiEx (USER32.547)
Alexandre Julliardf80b2ab1999-03-28 13:15:40 +0000983 */
984INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
985 LPWORD lpChar, UINT flags, HKL dwhkl )
986{
987 /* FIXME: need true implementation */
988 return ToAscii16(virtKey,scanCode,lpKeyState,lpChar,flags);
989}
990
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +0000991/**********************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +0000992 * ActivateKeyboardLayout (USER32.1)
Guy Albertelli38d9ce81999-02-28 11:13:16 +0000993 *
994 * Call ignored. WINE supports only system default keyboard layout.
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +0000995 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000996HKL WINAPI ActivateKeyboardLayout(HKL hLayout, UINT flags)
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +0000997{
Alexandre Julliard06c275a1999-05-02 14:32:27 +0000998 TRACE_(keyboard)("(%d, %d)\n", hLayout, flags);
999 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001000 return 0;
1001}
1002
1003
Ulrich Weigand2b067581998-11-08 12:26:36 +00001004/***********************************************************************
1005 * GetKeyboardLayoutList (USER32.251)
Guy Albertelli38d9ce81999-02-28 11:13:16 +00001006 *
1007 * FIXME: Supports only the system default language and layout and
1008 * returns only 1 value.
1009 *
1010 * Return number of values available if either input parm is
1011 * 0, per MS documentation.
1012 *
Ulrich Weigand2b067581998-11-08 12:26:36 +00001013 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001014INT WINAPI GetKeyboardLayoutList(INT nBuff,HKL *layouts)
Ulrich Weigand2b067581998-11-08 12:26:36 +00001015{
Alexandre Julliard06c275a1999-05-02 14:32:27 +00001016 TRACE_(keyboard)("(%d,%p)\n",nBuff,layouts);
Guy Albertelli38d9ce81999-02-28 11:13:16 +00001017 if (!nBuff || !layouts)
1018 return 1;
Ulrich Weigand2b067581998-11-08 12:26:36 +00001019 if (layouts)
1020 layouts[0] = GetKeyboardLayout(0);
1021 return 1;
1022}
1023
1024
1025/***********************************************************************
1026 * RegisterHotKey (USER32.433)
1027 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001028BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk) {
Alexandre Julliard06c275a1999-05-02 14:32:27 +00001029 FIXME_(keyboard)("(0x%08x,%d,0x%08x,%d): stub\n",hwnd,id,modifiers,vk);
Ulrich Weigand2b067581998-11-08 12:26:36 +00001030 return TRUE;
1031}
1032
1033/***********************************************************************
1034 * UnregisterHotKey (USER32.565)
1035 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001036BOOL WINAPI UnregisterHotKey(HWND hwnd,INT id) {
Alexandre Julliard06c275a1999-05-02 14:32:27 +00001037 FIXME_(keyboard)("(0x%08x,%d): stub\n",hwnd,id);
Ulrich Weigand2b067581998-11-08 12:26:36 +00001038 return TRUE;
1039}
1040
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001041
1042/***********************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +00001043 * ToUnicode (USER32.548)
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001044 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001045INT WINAPI ToUnicode(
1046 UINT wVirtKey,
1047 UINT wScanCode,
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001048 PBYTE lpKeyState,
1049 LPWSTR pwszBuff,
Patrik Stridvall8276f691999-09-23 11:48:02 +00001050 INT cchBuff,
Alexandre Julliarda3960291999-02-26 11:11:13 +00001051 UINT wFlags) {
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001052
Alexandre Julliard06c275a1999-05-02 14:32:27 +00001053 FIXME_(keyboard)(": stub\n");
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001054 return 0;
1055}
1056
1057/***********************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +00001058 * LoadKeyboardLayoutA (USER32.367)
Guy Albertelli38d9ce81999-02-28 11:13:16 +00001059 * Call ignored. WINE supports only system default keyboard layout.
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001060 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001061HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID, UINT Flags)
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001062{
Alexandre Julliard06c275a1999-05-02 14:32:27 +00001063 TRACE_(keyboard)("(%s, %d)\n", pwszKLID, Flags);
1064 ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001065 return 0;
1066}
1067
1068/***********************************************************************
Patrik Stridvall533d3332000-03-28 19:31:18 +00001069 * LoadKeyboardLayoutW (USER32.368)
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001070 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001071HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags)
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001072{
Dimitrie O. Paun4d48dd32000-04-30 12:22:18 +00001073 char buf[9];
1074
Guy Albertelli38d9ce81999-02-28 11:13:16 +00001075 lstrcpynWtoA(buf,pwszKLID,8);
1076 buf[8] = 0;
Dimitrie O. Paun4d48dd32000-04-30 12:22:18 +00001077 return LoadKeyboardLayoutA(buf, Flags);
Alexandre Julliard0c0e3be1998-12-10 15:49:22 +00001078}