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 ******************************************************************/
32 #include <wine/debug.h>
33 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
35 /* GLOBALS *******************************************************************/
39 /* FUNCTIONS *****************************************************************/
51 return NtUserDragDetect(hWnd
, pt
);
56 ULONG dx
= GetSystemMetrics(SM_CXDRAG
);
57 ULONG dy
= GetSystemMetrics(SM_CYDRAG
);
59 rect
.left
= pt
.x
- dx
;
60 rect
.right
= pt
.x
+ dx
;
62 rect
.bottom
= pt
.y
+ dy
;
69 PeekMessageW(&msg
, 0, WM_MOUSEFIRST
, WM_MOUSELAST
, PM_REMOVE
) ||
70 PeekMessageW(&msg
, 0, WM_KEYFIRST
, WM_KEYLAST
, PM_REMOVE
)
73 if (msg
.message
== WM_LBUTTONUP
)
78 if (msg
.message
== WM_MOUSEMOVE
)
80 tmp
.x
= LOWORD(msg
.lParam
);
81 tmp
.y
= HIWORD(msg
.lParam
);
82 if (!PtInRect(&rect
, tmp
))
88 if (msg
.message
== WM_KEYDOWN
)
90 if (msg
.wParam
== VK_ESCAPE
)
107 EnableWindow(HWND hWnd
, BOOL bEnable
)
109 return NtUserxEnableWindow(hWnd
, bEnable
);
116 GetAsyncKeyState(int vKey
)
118 if (vKey
< 0 || vKey
> 256)
120 return (SHORT
)NtUserGetAsyncKeyState((DWORD
)vKey
);
128 GetKeyboardLayout(DWORD idThread
)
130 return NtUserxGetKeyboardLayout(idThread
);
148 GetKeyNameTextA(LONG lParam
,
155 BOOL defChar
= FALSE
;
157 pwszBuf
= HeapAlloc(GetProcessHeap(), 0, nSize
* sizeof(WCHAR
));
161 cchBuf
= NtUserGetKeyNameText(lParam
, pwszBuf
, nSize
);
163 iRet
= WideCharToMultiByte(CP_ACP
, 0,
165 lpString
, nSize
, ".", &defChar
); // FIXME: do we need defChar?
167 HeapFree(GetProcessHeap(), 0, pwszBuf
);
176 GetKeyNameTextW(LONG lParam
,
180 return NtUserGetKeyNameText(lParam
, lpString
, nSize
);
187 GetKeyState(int nVirtKey
)
189 return (SHORT
)NtUserGetKeyState((DWORD
)nVirtKey
);
196 GetKeyboardLayoutNameA(LPSTR pwszKLID
)
198 WCHAR buf
[KL_NAMELENGTH
];
200 if (!GetKeyboardLayoutNameW(buf
))
203 if (!WideCharToMultiByte(CP_ACP
, 0, buf
, -1, pwszKLID
, KL_NAMELENGTH
, NULL
, NULL
))
213 GetKeyboardLayoutNameW(LPWSTR pwszKLID
)
215 return NtUserGetKeyboardLayoutName(pwszKLID
);
222 GetKeyboardType(int nTypeFlag
)
224 return NtUserxGetKeyboardType(nTypeFlag
);
231 GetLastInputInfo(PLASTINPUTINFO plii
)
235 if (plii
->cbSize
!= sizeof (*plii
))
237 SetLastError(ERROR_INVALID_PARAMETER
);
241 plii
->dwTime
= gpsi
->dwLastRITEventTickCount
;
249 LoadKeyboardLayoutA(LPCSTR pszKLID
,
254 if (!MultiByteToWideChar(CP_ACP
, 0, pszKLID
, -1,
255 wszKLID
, sizeof(wszKLID
)/sizeof(wszKLID
[0])))
260 return LoadKeyboardLayoutW(wszKLID
, Flags
);
267 LoadKeyboardLayoutW(LPCWSTR pwszKLID
,
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];
277 /* LOWORD of dwhkl is Locale Identifier */
278 dwhkl
= wcstol(pwszKLID
, NULL
, 16);
280 if (Flags
& KLF_SUBSTITUTE_OK
)
282 /* Check substitutes key */
283 if (RegOpenKeyExW(HKEY_CURRENT_USER
, L
"Keyboard Layout\\Substitutes", 0,
284 KEY_READ
, &hKey
) == ERROR_SUCCESS
)
286 dwSize
= sizeof(wszNewKLID
);
287 if (RegQueryValueExW(hKey
, pwszKLID
, NULL
, &dwType
, (LPBYTE
)wszNewKLID
, &dwSize
) == ERROR_SUCCESS
)
289 /* Use new KLID value */
290 pwszKLID
= wszNewKLID
;
293 /* Close the key now */
298 /* Append KLID at the end of registry key */
299 StringCbCatW(wszRegKey
, sizeof(wszRegKey
), pwszKLID
);
301 /* Open layout registry key for read */
302 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, wszRegKey
, 0,
303 KEY_READ
, &hKey
) == ERROR_SUCCESS
)
305 dwSize
= sizeof(wszLayoutId
);
306 if (RegQueryValueExW(hKey
, L
"Layout Id", NULL
, &dwType
, (LPBYTE
)wszLayoutId
, &dwSize
) == ERROR_SUCCESS
)
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.
314 dwhkl
|= (0xf000 | wcstol(wszLayoutId
, NULL
, 16)) << 16;
317 /* Close the key now */
321 ERR("RegOpenKeyExW failed!\n");
323 /* If Layout Id is not given HIWORD == LOWORD (for dwhkl) */
325 dwhkl
|= dwhkl
<< 16;
327 ZeroMemory(&ustrKbdName
, sizeof(ustrKbdName
));
328 RtlInitUnicodeString(&ustrKLID
, pwszKLID
);
329 return NtUserLoadKeyboardLayoutEx(NULL
, 0, &ustrKbdName
,
338 MapVirtualKeyA(UINT uCode
,
341 return MapVirtualKeyExA(uCode
, uMapType
, GetKeyboardLayout(0));
348 MapVirtualKeyExA(UINT uCode
,
352 return MapVirtualKeyExW(uCode
, uMapType
, dwhkl
);
360 MapVirtualKeyExW(UINT uCode
,
364 return NtUserMapVirtualKeyEx(uCode
, uMapType
, 0, dwhkl
);
372 MapVirtualKeyW(UINT uCode
,
375 return MapVirtualKeyExW(uCode
, uMapType
, GetKeyboardLayout(0));
383 OemKeyScan(WORD wOemChar
)
389 MultiByteToWideChar(CP_OEMCP
, 0, (PCSTR
)&wOemChar
, 1, &p
, 1);
391 Scan
= MapVirtualKeyW((Vk
& 0x00ff), 0);
392 if (!Scan
) return -1;
394 Page 450-1, MS W2k SuperBible by SAMS. Return, low word has the
395 scan code and high word has the shift state.
397 return ((Vk
& 0xff00) << 8) | Scan
;
405 SetDoubleClickTime(UINT uInterval
)
407 return (BOOL
)NtUserSystemParametersInfo(SPI_SETDOUBLECLICKTIME
,
422 return NtUserxSwapMouseButton(fSwap
);
430 ToAscii(UINT uVirtKey
,
432 CONST BYTE
*lpKeyState
,
436 return ToAsciiEx(uVirtKey
, uScanCode
, lpKeyState
, lpChar
, uFlags
, 0);
444 ToAsciiEx(UINT uVirtKey
,
446 CONST BYTE
*lpKeyState
,
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
);
466 ToUnicode(UINT wVirtKey
,
468 CONST BYTE
*lpKeyState
,
473 return ToUnicodeEx(wVirtKey
, wScanCode
, lpKeyState
, pwszBuff
, cchBuff
,
482 ToUnicodeEx(UINT wVirtKey
,
484 CONST BYTE
*lpKeyState
,
490 return NtUserToUnicodeEx(wVirtKey
, wScanCode
, (PBYTE
)lpKeyState
, pwszBuff
, cchBuff
,
504 if (IsDBCSLeadByte(ch
))
507 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
508 return VkKeyScanW(wChar
);
516 VkKeyScanExA(CHAR ch
,
521 if (IsDBCSLeadByte(ch
))
524 MultiByteToWideChar(CP_ACP
, 0, &ch
, 1, &wChar
, 1);
525 return VkKeyScanExW(wChar
, dwhkl
);
533 VkKeyScanExW(WCHAR ch
,
536 return (SHORT
)NtUserVkKeyScanEx(ch
, dwhkl
, TRUE
);
546 return (SHORT
)NtUserVkKeyScanEx(ch
, 0, FALSE
);
559 ULONG_PTR dwExtraInfo
)
563 Input
.type
= INPUT_KEYBOARD
;
565 Input
.ki
.wScan
= bScan
;
566 Input
.ki
.dwFlags
= dwFlags
;
568 Input
.ki
.dwExtraInfo
= dwExtraInfo
;
570 NtUserSendInput(1, &Input
, sizeof(INPUT
));
584 ULONG_PTR dwExtraInfo
)
588 Input
.type
= INPUT_MOUSE
;
591 Input
.mi
.mouseData
= dwData
;
592 Input
.mi
.dwFlags
= dwFlags
;
594 Input
.mi
.dwExtraInfo
= dwExtraInfo
;
596 NtUserSendInput(1, &Input
, sizeof(INPUT
));