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: dll/win32/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
);
118 GetAsyncKeyState(int vKey
)
120 if (vKey
< 0 || vKey
> 256)
122 return (SHORT
)NtUserGetAsyncKeyState((DWORD
)vKey
);
130 GetKeyboardLayout(DWORD idThread
)
132 return NtUserxGetKeyboardLayout(idThread
);
150 GetKeyNameTextA(LONG lParam
,
157 BOOL defChar
= FALSE
;
159 pwszBuf
= HeapAlloc(GetProcessHeap(), 0, nSize
* sizeof(WCHAR
));
163 cchBuf
= NtUserGetKeyNameText(lParam
, pwszBuf
, nSize
);
165 iRet
= WideCharToMultiByte(CP_ACP
, 0,
167 lpString
, nSize
, ".", &defChar
); // FIXME: do we need defChar?
169 HeapFree(GetProcessHeap(), 0, pwszBuf
);
178 GetKeyNameTextW(LONG lParam
,
182 return NtUserGetKeyNameText(lParam
, lpString
, nSize
);
189 GetKeyState(int nVirtKey
)
191 return (SHORT
)NtUserGetKeyState((DWORD
)nVirtKey
);
198 GetKeyboardLayoutNameA(LPSTR pwszKLID
)
200 WCHAR buf
[KL_NAMELENGTH
];
202 if (!GetKeyboardLayoutNameW(buf
))
205 if (!WideCharToMultiByte(CP_ACP
, 0, buf
, -1, pwszKLID
, KL_NAMELENGTH
, NULL
, NULL
))
215 GetKeyboardLayoutNameW(LPWSTR pwszKLID
)
217 return NtUserGetKeyboardLayoutName(pwszKLID
);
224 GetKeyboardType(int nTypeFlag
)
226 return NtUserxGetKeyboardType(nTypeFlag
);
233 GetLastInputInfo(PLASTINPUTINFO plii
)
237 if (plii
->cbSize
!= sizeof (*plii
))
239 SetLastError(ERROR_INVALID_PARAMETER
);
243 plii
->dwTime
= gpsi
->dwLastRITEventTickCount
;
251 LoadKeyboardLayoutA(LPCSTR pszKLID
,
256 if (!MultiByteToWideChar(CP_ACP
, 0, pszKLID
, -1,
257 wszKLID
, sizeof(wszKLID
)/sizeof(wszKLID
[0])))
262 return LoadKeyboardLayoutW(wszKLID
, Flags
);
269 LoadKeyboardLayoutW(LPCWSTR pwszKLID
,
272 DWORD dwhkl
, dwType
, dwSize
;
273 UNICODE_STRING ustrKbdName
;
274 UNICODE_STRING ustrKLID
;
275 WCHAR wszRegKey
[256] = L
"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
276 WCHAR wszLayoutId
[10], wszNewKLID
[10];
279 /* LOWORD of dwhkl is Locale Identifier */
280 dwhkl
= wcstol(pwszKLID
, NULL
, 16);
282 if (Flags
& KLF_SUBSTITUTE_OK
)
284 /* Check substitutes key */
285 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Keyboard Layout\\Substitutes", 0,
286 KEY_READ
, &hKey
) == ERROR_SUCCESS
)
288 dwSize
= sizeof(wszNewKLID
);
289 if (RegQueryValueExW(hKey
, pwszKLID
, NULL
, &dwType
, (LPBYTE
)wszNewKLID
, &dwSize
) == ERROR_SUCCESS
)
291 /* Use new KLID value */
292 pwszKLID
= wszNewKLID
;
295 /* Close the key now */
300 /* Append KLID at the end of registry key */
301 StringCbCatW(wszRegKey
, sizeof(wszRegKey
), pwszKLID
);
303 /* Open layout registry key for read */
304 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, wszRegKey
, 0,
305 KEY_READ
, &hKey
) == ERROR_SUCCESS
)
307 dwSize
= sizeof(wszLayoutId
);
308 if (RegQueryValueExW(hKey
, L
"Layout Id", NULL
, &dwType
, (LPBYTE
)wszLayoutId
, &dwSize
) == ERROR_SUCCESS
)
310 /* If Layout Id is specified, use this value | f000 as HIWORD */
311 /* FIXME: Microsoft Office expects this value to be something specific
312 * for Japanese and Korean Windows with an IME the value is 0xe001
313 * We should probably check to see if an IME exists and if so then
314 * set this word properly.
316 dwhkl
|= (0xf000 | wcstol(wszLayoutId
, NULL
, 16)) << 16;
319 /* Close the key now */
323 ERR("RegOpenKeyExW failed!\n");
325 /* If Layout Id is not given HIWORD == LOWORD (for dwhkl) */
327 dwhkl
|= dwhkl
<< 16;
329 ZeroMemory(&ustrKbdName
, sizeof(ustrKbdName
));
330 RtlInitUnicodeString(&ustrKLID
, pwszKLID
);
331 return NtUserLoadKeyboardLayoutEx(NULL
, 0, &ustrKbdName
,
340 MapVirtualKeyA(UINT uCode
,
343 return MapVirtualKeyExA(uCode
, uMapType
, GetKeyboardLayout(0));
350 MapVirtualKeyExA(UINT uCode
,
354 return MapVirtualKeyExW(uCode
, uMapType
, dwhkl
);
362 MapVirtualKeyExW(UINT uCode
,
366 return NtUserMapVirtualKeyEx(uCode
, uMapType
, 0, dwhkl
);
374 MapVirtualKeyW(UINT uCode
,
377 return MapVirtualKeyExW(uCode
, uMapType
, GetKeyboardLayout(0));
385 OemKeyScan(WORD wOemChar
)
391 MultiByteToWideChar(CP_OEMCP
, 0, (PCSTR
)&wOemChar
, 1, &p
, 1);
393 Scan
= MapVirtualKeyW((Vk
& 0x00ff), 0);
394 if (!Scan
) return -1;
396 Page 450-1, MS W2k SuperBible by SAMS. Return, low word has the
397 scan code and high word has the shift state.
399 return ((Vk
& 0xff00) << 8) | Scan
;
407 SetDoubleClickTime(UINT uInterval
)
409 return (BOOL
)NtUserSystemParametersInfo(SPI_SETDOUBLECLICKTIME
,
424 return NtUserxSwapMouseButton(fSwap
);
432 ToAscii(UINT uVirtKey
,
434 CONST BYTE
*lpKeyState
,
438 return ToAsciiEx(uVirtKey
, uScanCode
, lpKeyState
, lpChar
, uFlags
, 0);
446 ToAsciiEx(UINT uVirtKey
,
448 CONST BYTE
*lpKeyState
,
456 Ret
= ToUnicodeEx(uVirtKey
, uScanCode
, lpKeyState
, UniChars
, 2, uFlags
, dwhkl
);
457 CharCount
= (Ret
< 0 ? 1 : Ret
);
458 WideCharToMultiByte(CP_ACP
, 0, UniChars
, CharCount
, (LPSTR
)lpChar
, 2, NULL
, NULL
);
468 ToUnicode(UINT wVirtKey
,
470 CONST BYTE
*lpKeyState
,
475 return ToUnicodeEx(wVirtKey
, wScanCode
, lpKeyState
, pwszBuff
, cchBuff
,
484 ToUnicodeEx(UINT wVirtKey
,
486 CONST BYTE
*lpKeyState
,
492 return NtUserToUnicodeEx(wVirtKey
, wScanCode
, (PBYTE
)lpKeyState
, pwszBuff
, cchBuff
,
506 if (IsDBCSLeadByte(ch
))
509 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
510 return VkKeyScanW(wChar
);
518 VkKeyScanExA(CHAR ch
,
523 if (IsDBCSLeadByte(ch
))
526 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
527 return VkKeyScanExW(wChar
, dwhkl
);
535 VkKeyScanExW(WCHAR ch
,
538 return (SHORT
)NtUserVkKeyScanEx(ch
, dwhkl
, TRUE
);
548 return (SHORT
)NtUserVkKeyScanEx(ch
, 0, FALSE
);
561 ULONG_PTR dwExtraInfo
)
565 Input
.type
= INPUT_KEYBOARD
;
567 Input
.ki
.wScan
= bScan
;
568 Input
.ki
.dwFlags
= dwFlags
;
570 Input
.ki
.dwExtraInfo
= dwExtraInfo
;
572 NtUserSendInput(1, &Input
, sizeof(INPUT
));
586 ULONG_PTR dwExtraInfo
)
590 Input
.type
= INPUT_MOUSE
;
593 Input
.mi
.mouseData
= dwData
;
594 Input
.mi
.dwFlags
= dwFlags
;
596 Input
.mi
.dwExtraInfo
= dwExtraInfo
;
598 NtUserSendInput(1, &Input
, sizeof(INPUT
));