3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
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.
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.
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.
20 * PROJECT: ReactOS user32.dll
21 * FILE: win32ss/user/user32/windows/input.c
23 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
25 * 09-05-2001 CSH Created
28 /* INCLUDES ******************************************************************/
34 #include <wine/debug.h>
35 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
37 /* GLOBALS *******************************************************************/
41 /* FUNCTIONS *****************************************************************/
53 return NtUserDragDetect(hWnd
, pt
);
58 ULONG dx
= GetSystemMetrics(SM_CXDRAG
);
59 ULONG dy
= GetSystemMetrics(SM_CYDRAG
);
61 rect
.left
= pt
.x
- dx
;
62 rect
.right
= pt
.x
+ dx
;
64 rect
.bottom
= pt
.y
+ dy
;
71 PeekMessageW(&msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
, PM_REMOVE
) ||
72 PeekMessageW(&msg
, 0, WM_KEYFIRST
, WM_KEYLAST
, PM_REMOVE
)
75 if (msg
.message
== WM_LBUTTONUP
)
80 if (msg
.message
== WM_MOUSEMOVE
)
82 tmp
.x
= LOWORD(msg
.lParam
);
83 tmp
.y
= HIWORD(msg
.lParam
);
84 if (!PtInRect(&rect
, tmp
))
90 if (msg
.message
== WM_KEYDOWN
)
92 if (msg
.wParam
== VK_ESCAPE
)
109 EnableWindow(HWND hWnd
, BOOL bEnable
)
111 return NtUserxEnableWindow(hWnd
, bEnable
);
120 GetAsyncKeyState(int vKey
)
122 if (vKey
< 0 || vKey
> 256)
124 return (SHORT
)NtUserGetAsyncKeyState((DWORD
)vKey
);
132 GetKeyboardLayout(DWORD idThread
)
134 return NtUserxGetKeyboardLayout(idThread
);
152 GetKeyNameTextA(LONG lParam
,
159 BOOL defChar
= FALSE
;
161 pwszBuf
= HeapAlloc(GetProcessHeap(), 0, nSize
* sizeof(WCHAR
));
165 cchBuf
= NtUserGetKeyNameText(lParam
, pwszBuf
, nSize
);
167 iRet
= WideCharToMultiByte(CP_ACP
, 0,
169 lpString
, nSize
, ".", &defChar
); // FIXME: do we need defChar?
171 HeapFree(GetProcessHeap(), 0, pwszBuf
);
180 GetKeyNameTextW(LONG lParam
,
184 return NtUserGetKeyNameText(lParam
, lpString
, nSize
);
193 GetKeyState(int nVirtKey
)
195 return (SHORT
)NtUserGetKeyState((DWORD
)nVirtKey
);
202 GetKeyboardLayoutNameA(LPSTR pwszKLID
)
204 WCHAR buf
[KL_NAMELENGTH
];
206 if (!GetKeyboardLayoutNameW(buf
))
209 if (!WideCharToMultiByte(CP_ACP
, 0, buf
, -1, pwszKLID
, KL_NAMELENGTH
, NULL
, NULL
))
219 GetKeyboardLayoutNameW(LPWSTR pwszKLID
)
221 return NtUserGetKeyboardLayoutName(pwszKLID
);
228 GetKeyboardType(int nTypeFlag
)
230 return NtUserxGetKeyboardType(nTypeFlag
);
237 GetLastInputInfo(PLASTINPUTINFO plii
)
241 if (plii
->cbSize
!= sizeof (*plii
))
243 SetLastError(ERROR_INVALID_PARAMETER
);
247 plii
->dwTime
= gpsi
->dwLastRITEventTickCount
;
255 LoadKeyboardLayoutA(LPCSTR pszKLID
,
260 if (!MultiByteToWideChar(CP_ACP
, 0, pszKLID
, -1,
261 wszKLID
, sizeof(wszKLID
)/sizeof(wszKLID
[0])))
266 return LoadKeyboardLayoutW(wszKLID
, Flags
);
273 LoadKeyboardLayoutW(LPCWSTR pwszKLID
,
276 DWORD dwhkl
, dwType
, dwSize
;
277 UNICODE_STRING ustrKbdName
;
278 UNICODE_STRING ustrKLID
;
279 WCHAR wszRegKey
[256] = L
"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
280 WCHAR wszLayoutId
[10], wszNewKLID
[10];
283 /* LOWORD of dwhkl is Locale Identifier */
284 dwhkl
= LOWORD(wcstoul(pwszKLID
, NULL
, 16));
286 if (Flags
& KLF_SUBSTITUTE_OK
)
288 /* Check substitutes key */
289 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Keyboard Layout\\Substitutes", 0,
290 KEY_READ
, &hKey
) == ERROR_SUCCESS
)
292 dwSize
= sizeof(wszNewKLID
);
293 if (RegQueryValueExW(hKey
, pwszKLID
, NULL
, &dwType
, (LPBYTE
)wszNewKLID
, &dwSize
) == ERROR_SUCCESS
)
295 /* Use new KLID value */
296 pwszKLID
= wszNewKLID
;
299 /* Close the key now */
304 /* Append KLID at the end of registry key */
305 StringCbCatW(wszRegKey
, sizeof(wszRegKey
), pwszKLID
);
307 /* Open layout registry key for read */
308 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, wszRegKey
, 0,
309 KEY_READ
, &hKey
) == ERROR_SUCCESS
)
311 dwSize
= sizeof(wszLayoutId
);
312 if (RegQueryValueExW(hKey
, L
"Layout Id", NULL
, &dwType
, (LPBYTE
)wszLayoutId
, &dwSize
) == ERROR_SUCCESS
)
314 /* If Layout Id is specified, use this value | f000 as HIWORD */
315 /* FIXME: Microsoft Office expects this value to be something specific
316 * for Japanese and Korean Windows with an IME the value is 0xe001
317 * We should probably check to see if an IME exists and if so then
318 * set this word properly.
320 dwhkl
|= (0xf000 | wcstol(wszLayoutId
, NULL
, 16)) << 16;
323 /* Close the key now */
328 ERR("Could not find keyboard layout %S.\n", pwszKLID
);
332 /* If Layout Id is not given HIWORD == LOWORD (for dwhkl) */
334 dwhkl
|= dwhkl
<< 16;
336 ZeroMemory(&ustrKbdName
, sizeof(ustrKbdName
));
337 RtlInitUnicodeString(&ustrKLID
, pwszKLID
);
338 return NtUserLoadKeyboardLayoutEx(NULL
, 0, &ustrKbdName
,
347 MapVirtualKeyA(UINT uCode
,
350 return MapVirtualKeyExA(uCode
, uMapType
, GetKeyboardLayout(0));
357 MapVirtualKeyExA(UINT uCode
,
361 return MapVirtualKeyExW(uCode
, uMapType
, dwhkl
);
369 MapVirtualKeyExW(UINT uCode
,
373 return NtUserMapVirtualKeyEx(uCode
, uMapType
, 0, dwhkl
);
381 MapVirtualKeyW(UINT uCode
,
384 return MapVirtualKeyExW(uCode
, uMapType
, GetKeyboardLayout(0));
392 OemKeyScan(WORD wOemChar
)
398 MultiByteToWideChar(CP_OEMCP
, 0, (PCSTR
)&wOemChar
, 1, &p
, 1);
400 Scan
= MapVirtualKeyW((Vk
& 0x00ff), 0);
401 if (!Scan
) return -1;
403 Page 450-1, MS W2k SuperBible by SAMS. Return, low word has the
404 scan code and high word has the shift state.
406 return ((Vk
& 0xff00) << 8) | Scan
;
414 SetDoubleClickTime(UINT uInterval
)
416 return (BOOL
)NtUserSystemParametersInfo(SPI_SETDOUBLECLICKTIME
,
431 return NtUserxSwapMouseButton(fSwap
);
439 ToAscii(UINT uVirtKey
,
441 CONST BYTE
*lpKeyState
,
445 return ToAsciiEx(uVirtKey
, uScanCode
, lpKeyState
, lpChar
, uFlags
, 0);
453 ToAsciiEx(UINT uVirtKey
,
455 CONST BYTE
*lpKeyState
,
463 Ret
= ToUnicodeEx(uVirtKey
, uScanCode
, lpKeyState
, UniChars
, 2, uFlags
, dwhkl
);
464 CharCount
= (Ret
< 0 ? 1 : Ret
);
465 WideCharToMultiByte(CP_ACP
, 0, UniChars
, CharCount
, (LPSTR
)lpChar
, 2, NULL
, NULL
);
475 ToUnicode(UINT wVirtKey
,
477 CONST BYTE
*lpKeyState
,
482 return ToUnicodeEx(wVirtKey
, wScanCode
, lpKeyState
, pwszBuff
, cchBuff
,
491 ToUnicodeEx(UINT wVirtKey
,
493 CONST BYTE
*lpKeyState
,
499 return NtUserToUnicodeEx(wVirtKey
, wScanCode
, (PBYTE
)lpKeyState
, pwszBuff
, cchBuff
,
513 if (IsDBCSLeadByte(ch
))
516 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
517 return VkKeyScanW(wChar
);
525 VkKeyScanExA(CHAR ch
,
530 if (IsDBCSLeadByte(ch
))
533 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
534 return VkKeyScanExW(wChar
, dwhkl
);
542 VkKeyScanExW(WCHAR ch
,
545 return (SHORT
)NtUserVkKeyScanEx(ch
, dwhkl
, TRUE
);
555 return (SHORT
)NtUserVkKeyScanEx(ch
, 0, FALSE
);
568 ULONG_PTR dwExtraInfo
)
572 Input
.type
= INPUT_KEYBOARD
;
574 Input
.ki
.wScan
= bScan
;
575 Input
.ki
.dwFlags
= dwFlags
;
577 Input
.ki
.dwExtraInfo
= dwExtraInfo
;
579 NtUserSendInput(1, &Input
, sizeof(INPUT
));
593 ULONG_PTR dwExtraInfo
)
597 Input
.type
= INPUT_MOUSE
;
600 Input
.mi
.mouseData
= dwData
;
601 Input
.mi
.dwFlags
= dwFlags
;
603 Input
.mi
.dwExtraInfo
= dwExtraInfo
;
605 NtUserSendInput(1, &Input
, sizeof(INPUT
));