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