[REACTOS]
[reactos.git] / reactos / win32ss / user / user32 / windows / input.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * PROJECT: ReactOS user32.dll
21 * FILE: dll/win32/user32/windows/input.c
22 * PURPOSE: Input
23 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
24 * UPDATE HISTORY:
25 * 09-05-2001 CSH Created
26 */
27
28 /* INCLUDES ******************************************************************/
29
30 #include <user32.h>
31
32 #include <wine/debug.h>
33 WINE_DEFAULT_DEBUG_CHANNEL(user32);
34
35 /* GLOBALS *******************************************************************/
36
37
38
39 /* FUNCTIONS *****************************************************************/
40
41
42 /*
43 * @implemented
44 */
45 BOOL
46 WINAPI
47 DragDetect(
48 HWND hWnd,
49 POINT pt)
50 {
51 return NtUserDragDetect(hWnd, pt);
52 #if 0
53 MSG msg;
54 RECT rect;
55 POINT tmp;
56 ULONG dx = GetSystemMetrics(SM_CXDRAG);
57 ULONG dy = GetSystemMetrics(SM_CYDRAG);
58
59 rect.left = pt.x - dx;
60 rect.right = pt.x + dx;
61 rect.top = pt.y - dy;
62 rect.bottom = pt.y + dy;
63
64 SetCapture(hWnd);
65
66 for (;;)
67 {
68 while (
69 PeekMessageW(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) ||
70 PeekMessageW(&msg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE)
71 )
72 {
73 if (msg.message == WM_LBUTTONUP)
74 {
75 ReleaseCapture();
76 return FALSE;
77 }
78 if (msg.message == WM_MOUSEMOVE)
79 {
80 tmp.x = LOWORD(msg.lParam);
81 tmp.y = HIWORD(msg.lParam);
82 if (!PtInRect(&rect, tmp))
83 {
84 ReleaseCapture();
85 return TRUE;
86 }
87 }
88 if (msg.message == WM_KEYDOWN)
89 {
90 if (msg.wParam == VK_ESCAPE)
91 {
92 ReleaseCapture();
93 return TRUE;
94 }
95 }
96 }
97 WaitMessage();
98 }
99 return 0;
100 #endif
101 }
102
103 /*
104 * @implemented
105 */
106 BOOL WINAPI
107 EnableWindow(HWND hWnd, BOOL bEnable)
108 {
109 return NtUserxEnableWindow(hWnd, bEnable);
110 }
111
112 /*
113 * @implemented
114 */
115 SHORT WINAPI
116 GetAsyncKeyState(int vKey)
117 {
118 if (vKey < 0 || vKey > 256)
119 return 0;
120 return (SHORT)NtUserGetAsyncKeyState((DWORD)vKey);
121 }
122
123
124 /*
125 * @implemented
126 */
127 HKL WINAPI
128 GetKeyboardLayout(DWORD idThread)
129 {
130 return NtUserxGetKeyboardLayout(idThread);
131 }
132
133
134 /*
135 * @implemented
136 */
137 UINT WINAPI
138 GetKBCodePage(VOID)
139 {
140 return GetOEMCP();
141 }
142
143
144 /*
145 * @implemented
146 */
147 int WINAPI
148 GetKeyNameTextA(LONG lParam,
149 LPSTR lpString,
150 int nSize)
151 {
152 LPWSTR pwszBuf;
153 UINT cchBuf = 0;
154 int iRet = 0;
155 BOOL defChar = FALSE;
156
157 pwszBuf = HeapAlloc(GetProcessHeap(), 0, nSize * sizeof(WCHAR));
158 if (!pwszBuf)
159 return 0;
160
161 cchBuf = NtUserGetKeyNameText(lParam, pwszBuf, nSize);
162
163 iRet = WideCharToMultiByte(CP_ACP, 0,
164 pwszBuf, cchBuf,
165 lpString, nSize, ".", &defChar); // FIXME: do we need defChar?
166 lpString[iRet] = 0;
167 HeapFree(GetProcessHeap(), 0, pwszBuf);
168
169 return iRet;
170 }
171
172 /*
173 * @implemented
174 */
175 int WINAPI
176 GetKeyNameTextW(LONG lParam,
177 LPWSTR lpString,
178 int nSize)
179 {
180 return NtUserGetKeyNameText(lParam, lpString, nSize);
181 }
182
183 /*
184 * @implemented
185 */
186 SHORT WINAPI
187 GetKeyState(int nVirtKey)
188 {
189 return (SHORT)NtUserGetKeyState((DWORD)nVirtKey);
190 }
191
192 /*
193 * @implemented
194 */
195 BOOL WINAPI
196 GetKeyboardLayoutNameA(LPSTR pwszKLID)
197 {
198 WCHAR buf[KL_NAMELENGTH];
199
200 if (!GetKeyboardLayoutNameW(buf))
201 return FALSE;
202
203 if (!WideCharToMultiByte(CP_ACP, 0, buf, -1, pwszKLID, KL_NAMELENGTH, NULL, NULL))
204 return FALSE;
205
206 return TRUE;
207 }
208
209 /*
210 * @implemented
211 */
212 BOOL WINAPI
213 GetKeyboardLayoutNameW(LPWSTR pwszKLID)
214 {
215 return NtUserGetKeyboardLayoutName(pwszKLID);
216 }
217
218 /*
219 * @implemented
220 */
221 int WINAPI
222 GetKeyboardType(int nTypeFlag)
223 {
224 return NtUserxGetKeyboardType(nTypeFlag);
225 }
226
227 /*
228 * @implemented
229 */
230 BOOL WINAPI
231 GetLastInputInfo(PLASTINPUTINFO plii)
232 {
233 TRACE("%p\n", plii);
234
235 if (plii->cbSize != sizeof (*plii))
236 {
237 SetLastError(ERROR_INVALID_PARAMETER);
238 return FALSE;
239 }
240
241 plii->dwTime = gpsi->dwLastRITEventTickCount;
242 return TRUE;
243 }
244
245 /*
246 * @implemented
247 */
248 HKL WINAPI
249 LoadKeyboardLayoutA(LPCSTR pszKLID,
250 UINT Flags)
251 {
252 WCHAR wszKLID[16];
253
254 if (!MultiByteToWideChar(CP_ACP, 0, pszKLID, -1,
255 wszKLID, sizeof(wszKLID)/sizeof(wszKLID[0])))
256 {
257 return FALSE;
258 }
259
260 return LoadKeyboardLayoutW(wszKLID, Flags);
261 }
262
263 /*
264 * @implemented
265 */
266 HKL WINAPI
267 LoadKeyboardLayoutW(LPCWSTR pwszKLID,
268 UINT Flags)
269 {
270 DWORD dwhkl, dwType, dwSize;
271 UNICODE_STRING ustrKbdName;
272 UNICODE_STRING ustrKLID;
273 WCHAR wszRegKey[256] = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
274 WCHAR wszLayoutId[10], wszNewKLID[10];
275 HKEY hKey;
276
277 /* LOWORD of dwhkl is Locale Identifier */
278 dwhkl = wcstol(pwszKLID, NULL, 16);
279
280 if (Flags & KLF_SUBSTITUTE_OK)
281 {
282 /* Check substitutes key */
283 if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Substitutes", 0,
284 KEY_READ, &hKey) == ERROR_SUCCESS)
285 {
286 dwSize = sizeof(wszNewKLID);
287 if (RegQueryValueExW(hKey, pwszKLID, NULL, &dwType, (LPBYTE)wszNewKLID, &dwSize) == ERROR_SUCCESS)
288 {
289 /* Use new KLID value */
290 pwszKLID = wszNewKLID;
291 }
292
293 /* Close the key now */
294 RegCloseKey(hKey);
295 }
296 }
297
298 /* Append KLID at the end of registry key */
299 StringCbCatW(wszRegKey, sizeof(wszRegKey), pwszKLID);
300
301 /* Open layout registry key for read */
302 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszRegKey, 0,
303 KEY_READ, &hKey) == ERROR_SUCCESS)
304 {
305 dwSize = sizeof(wszLayoutId);
306 if (RegQueryValueExW(hKey, L"Layout Id", NULL, &dwType, (LPBYTE)wszLayoutId, &dwSize) == ERROR_SUCCESS)
307 {
308 /* If Layout Id is specified, use this value | f000 as HIWORD */
309 /* FIXME: Microsoft Office expects this value to be something specific
310 * for Japanese and Korean Windows with an IME the value is 0xe001
311 * We should probably check to see if an IME exists and if so then
312 * set this word properly.
313 */
314 dwhkl |= (0xf000 | wcstol(wszLayoutId, NULL, 16)) << 16;
315 }
316
317 /* Close the key now */
318 RegCloseKey(hKey);
319 }
320 else
321 ERR("RegOpenKeyExW failed!\n");
322
323 /* If Layout Id is not given HIWORD == LOWORD (for dwhkl) */
324 if (!HIWORD(dwhkl))
325 dwhkl |= dwhkl << 16;
326
327 ZeroMemory(&ustrKbdName, sizeof(ustrKbdName));
328 RtlInitUnicodeString(&ustrKLID, pwszKLID);
329 return NtUserLoadKeyboardLayoutEx(NULL, 0, &ustrKbdName,
330 NULL, &ustrKLID,
331 dwhkl, Flags);
332 }
333
334 /*
335 * @implemented
336 */
337 UINT WINAPI
338 MapVirtualKeyA(UINT uCode,
339 UINT uMapType)
340 {
341 return MapVirtualKeyExA(uCode, uMapType, GetKeyboardLayout(0));
342 }
343
344 /*
345 * @implemented
346 */
347 UINT WINAPI
348 MapVirtualKeyExA(UINT uCode,
349 UINT uMapType,
350 HKL dwhkl)
351 {
352 return MapVirtualKeyExW(uCode, uMapType, dwhkl);
353 }
354
355
356 /*
357 * @implemented
358 */
359 UINT WINAPI
360 MapVirtualKeyExW(UINT uCode,
361 UINT uMapType,
362 HKL dwhkl)
363 {
364 return NtUserMapVirtualKeyEx(uCode, uMapType, 0, dwhkl);
365 }
366
367
368 /*
369 * @implemented
370 */
371 UINT WINAPI
372 MapVirtualKeyW(UINT uCode,
373 UINT uMapType)
374 {
375 return MapVirtualKeyExW(uCode, uMapType, GetKeyboardLayout(0));
376 }
377
378
379 /*
380 * @implemented
381 */
382 DWORD WINAPI
383 OemKeyScan(WORD wOemChar)
384 {
385 WCHAR p;
386 SHORT Vk;
387 UINT Scan;
388
389 MultiByteToWideChar(CP_OEMCP, 0, (PCSTR)&wOemChar, 1, &p, 1);
390 Vk = VkKeyScanW(p);
391 Scan = MapVirtualKeyW((Vk & 0x00ff), 0);
392 if (!Scan) return -1;
393 /*
394 Page 450-1, MS W2k SuperBible by SAMS. Return, low word has the
395 scan code and high word has the shift state.
396 */
397 return ((Vk & 0xff00) << 8) | Scan;
398 }
399
400
401 /*
402 * @implemented
403 */
404 BOOL WINAPI
405 SetDoubleClickTime(UINT uInterval)
406 {
407 return (BOOL)NtUserSystemParametersInfo(SPI_SETDOUBLECLICKTIME,
408 uInterval,
409 NULL,
410 0);
411 }
412
413
414 /*
415 * @implemented
416 */
417 BOOL
418 WINAPI
419 SwapMouseButton(
420 BOOL fSwap)
421 {
422 return NtUserxSwapMouseButton(fSwap);
423 }
424
425
426 /*
427 * @implemented
428 */
429 int WINAPI
430 ToAscii(UINT uVirtKey,
431 UINT uScanCode,
432 CONST BYTE *lpKeyState,
433 LPWORD lpChar,
434 UINT uFlags)
435 {
436 return ToAsciiEx(uVirtKey, uScanCode, lpKeyState, lpChar, uFlags, 0);
437 }
438
439
440 /*
441 * @implemented
442 */
443 int WINAPI
444 ToAsciiEx(UINT uVirtKey,
445 UINT uScanCode,
446 CONST BYTE *lpKeyState,
447 LPWORD lpChar,
448 UINT uFlags,
449 HKL dwhkl)
450 {
451 WCHAR UniChars[2];
452 int Ret, CharCount;
453
454 Ret = ToUnicodeEx(uVirtKey, uScanCode, lpKeyState, UniChars, 2, uFlags, dwhkl);
455 CharCount = (Ret < 0 ? 1 : Ret);
456 WideCharToMultiByte(CP_ACP, 0, UniChars, CharCount, (LPSTR)lpChar, 2, NULL, NULL);
457
458 return Ret;
459 }
460
461
462 /*
463 * @implemented
464 */
465 int WINAPI
466 ToUnicode(UINT wVirtKey,
467 UINT wScanCode,
468 CONST BYTE *lpKeyState,
469 LPWSTR pwszBuff,
470 int cchBuff,
471 UINT wFlags)
472 {
473 return ToUnicodeEx(wVirtKey, wScanCode, lpKeyState, pwszBuff, cchBuff,
474 wFlags, 0);
475 }
476
477
478 /*
479 * @implemented
480 */
481 int WINAPI
482 ToUnicodeEx(UINT wVirtKey,
483 UINT wScanCode,
484 CONST BYTE *lpKeyState,
485 LPWSTR pwszBuff,
486 int cchBuff,
487 UINT wFlags,
488 HKL dwhkl)
489 {
490 return NtUserToUnicodeEx(wVirtKey, wScanCode, (PBYTE)lpKeyState, pwszBuff, cchBuff,
491 wFlags, dwhkl);
492 }
493
494
495
496 /*
497 * @implemented
498 */
499 SHORT WINAPI
500 VkKeyScanA(CHAR ch)
501 {
502 WCHAR wChar;
503
504 if (IsDBCSLeadByte(ch))
505 return -1;
506
507 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wChar, 1);
508 return VkKeyScanW(wChar);
509 }
510
511
512 /*
513 * @implemented
514 */
515 SHORT WINAPI
516 VkKeyScanExA(CHAR ch,
517 HKL dwhkl)
518 {
519 WCHAR wChar;
520
521 if (IsDBCSLeadByte(ch))
522 return -1;
523
524 MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wChar, 1);
525 return VkKeyScanExW(wChar, dwhkl);
526 }
527
528
529 /*
530 * @implemented
531 */
532 SHORT WINAPI
533 VkKeyScanExW(WCHAR ch,
534 HKL dwhkl)
535 {
536 return (SHORT)NtUserVkKeyScanEx(ch, dwhkl, TRUE);
537 }
538
539
540 /*
541 * @implemented
542 */
543 SHORT WINAPI
544 VkKeyScanW(WCHAR ch)
545 {
546 return (SHORT)NtUserVkKeyScanEx(ch, 0, FALSE);
547 }
548
549
550 /*
551 * @implemented
552 */
553 VOID
554 WINAPI
555 keybd_event(
556 BYTE bVk,
557 BYTE bScan,
558 DWORD dwFlags,
559 ULONG_PTR dwExtraInfo)
560 {
561 INPUT Input;
562
563 Input.type = INPUT_KEYBOARD;
564 Input.ki.wVk = bVk;
565 Input.ki.wScan = bScan;
566 Input.ki.dwFlags = dwFlags;
567 Input.ki.time = 0;
568 Input.ki.dwExtraInfo = dwExtraInfo;
569
570 NtUserSendInput(1, &Input, sizeof(INPUT));
571 }
572
573
574 /*
575 * @implemented
576 */
577 VOID
578 WINAPI
579 mouse_event(
580 DWORD dwFlags,
581 DWORD dx,
582 DWORD dy,
583 DWORD dwData,
584 ULONG_PTR dwExtraInfo)
585 {
586 INPUT Input;
587
588 Input.type = INPUT_MOUSE;
589 Input.mi.dx = dx;
590 Input.mi.dy = dy;
591 Input.mi.mouseData = dwData;
592 Input.mi.dwFlags = dwFlags;
593 Input.mi.time = 0;
594 Input.mi.dwExtraInfo = dwExtraInfo;
595
596 NtUserSendInput(1, &Input, sizeof(INPUT));
597 }
598
599 /* EOF */