/* * ReactOS kernel * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * PROJECT: ReactOS user32.dll * FILE: win32ss/user/user32/windows/input.c * PURPOSE: Input * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * UPDATE HISTORY: * 09-05-2001 CSH Created */ #include #include WINE_DEFAULT_DEBUG_CHANNEL(user32); /* * @implemented */ BOOL WINAPI DragDetect( HWND hWnd, POINT pt) { return NtUserDragDetect(hWnd, pt); #if 0 MSG msg; RECT rect; POINT tmp; ULONG dx = GetSystemMetrics(SM_CXDRAG); ULONG dy = GetSystemMetrics(SM_CYDRAG); rect.left = pt.x - dx; rect.right = pt.x + dx; rect.top = pt.y - dy; rect.bottom = pt.y + dy; SetCapture(hWnd); for (;;) { while ( PeekMessageW(&msg, 0, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE) || PeekMessageW(&msg, 0, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE) ) { if (msg.message == WM_LBUTTONUP) { ReleaseCapture(); return FALSE; } if (msg.message == WM_MOUSEMOVE) { tmp.x = LOWORD(msg.lParam); tmp.y = HIWORD(msg.lParam); if (!PtInRect(&rect, tmp)) { ReleaseCapture(); return TRUE; } } if (msg.message == WM_KEYDOWN) { if (msg.wParam == VK_ESCAPE) { ReleaseCapture(); return TRUE; } } } WaitMessage(); } return 0; #endif } /* * @implemented */ BOOL WINAPI EnableWindow(HWND hWnd, BOOL bEnable) { return NtUserxEnableWindow(hWnd, bEnable); } /* * @implemented */ SHORT WINAPI DECLSPEC_HOTPATCH GetAsyncKeyState(int vKey) { if (vKey < 0 || vKey > 256) return 0; return (SHORT)NtUserGetAsyncKeyState((DWORD)vKey); } /* * @implemented */ HKL WINAPI GetKeyboardLayout(DWORD idThread) { return NtUserxGetKeyboardLayout(idThread); } /* * @implemented */ UINT WINAPI GetKBCodePage(VOID) { return GetOEMCP(); } /* * @implemented */ int WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpString, int nSize) { LPWSTR pwszBuf; UINT cchBuf = 0; int iRet = 0; BOOL defChar = FALSE; pwszBuf = HeapAlloc(GetProcessHeap(), 0, nSize * sizeof(WCHAR)); if (!pwszBuf) return 0; cchBuf = NtUserGetKeyNameText(lParam, pwszBuf, nSize); iRet = WideCharToMultiByte(CP_ACP, 0, pwszBuf, cchBuf, lpString, nSize, ".", &defChar); // FIXME: do we need defChar? lpString[iRet] = 0; HeapFree(GetProcessHeap(), 0, pwszBuf); return iRet; } /* * @implemented */ int WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpString, int nSize) { return NtUserGetKeyNameText(lParam, lpString, nSize); } /* * @implemented */ SHORT WINAPI DECLSPEC_HOTPATCH GetKeyState(int nVirtKey) { return (SHORT)NtUserGetKeyState((DWORD)nVirtKey); } /* * @implemented */ BOOL WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID) { WCHAR buf[KL_NAMELENGTH]; if (!GetKeyboardLayoutNameW(buf)) return FALSE; if (!WideCharToMultiByte(CP_ACP, 0, buf, -1, pwszKLID, KL_NAMELENGTH, NULL, NULL)) return FALSE; return TRUE; } /* * @implemented */ BOOL WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID) { return NtUserGetKeyboardLayoutName(pwszKLID); } /* * @implemented */ int WINAPI GetKeyboardType(int nTypeFlag) { return NtUserxGetKeyboardType(nTypeFlag); } /* * @implemented */ BOOL WINAPI GetLastInputInfo(PLASTINPUTINFO plii) { TRACE("%p\n", plii); if (plii->cbSize != sizeof (*plii)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } plii->dwTime = gpsi->dwLastRITEventTickCount; return TRUE; } /* * @implemented */ HKL WINAPI LoadKeyboardLayoutA(LPCSTR pszKLID, UINT Flags) { WCHAR wszKLID[16]; if (!MultiByteToWideChar(CP_ACP, 0, pszKLID, -1, wszKLID, sizeof(wszKLID)/sizeof(wszKLID[0]))) { return FALSE; } return LoadKeyboardLayoutW(wszKLID, Flags); } /* * @implemented */ HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags) { DWORD dwhkl, dwType, dwSize; UNICODE_STRING ustrKbdName; UNICODE_STRING ustrKLID; WCHAR wszRegKey[256] = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"; WCHAR wszLayoutId[10], wszNewKLID[10]; HKEY hKey; /* LOWORD of dwhkl is Locale Identifier */ dwhkl = LOWORD(wcstoul(pwszKLID, NULL, 16)); if (Flags & KLF_SUBSTITUTE_OK) { /* Check substitutes key */ if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Keyboard Layout\\Substitutes", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(wszNewKLID); if (RegQueryValueExW(hKey, pwszKLID, NULL, &dwType, (LPBYTE)wszNewKLID, &dwSize) == ERROR_SUCCESS) { /* Use new KLID value */ pwszKLID = wszNewKLID; } /* Close the key now */ RegCloseKey(hKey); } } /* Append KLID at the end of registry key */ StringCbCatW(wszRegKey, sizeof(wszRegKey), pwszKLID); /* Open layout registry key for read */ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszRegKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { dwSize = sizeof(wszLayoutId); if (RegQueryValueExW(hKey, L"Layout Id", NULL, &dwType, (LPBYTE)wszLayoutId, &dwSize) == ERROR_SUCCESS) { /* If Layout Id is specified, use this value | f000 as HIWORD */ /* FIXME: Microsoft Office expects this value to be something specific * for Japanese and Korean Windows with an IME the value is 0xe001 * We should probably check to see if an IME exists and if so then * set this word properly. */ dwhkl |= (0xf000 | wcstol(wszLayoutId, NULL, 16)) << 16; } /* Close the key now */ RegCloseKey(hKey); } else { ERR("Could not find keyboard layout %S.\n", pwszKLID); return NULL; } /* If Layout Id is not given HIWORD == LOWORD (for dwhkl) */ if (!HIWORD(dwhkl)) dwhkl |= dwhkl << 16; ZeroMemory(&ustrKbdName, sizeof(ustrKbdName)); RtlInitUnicodeString(&ustrKLID, pwszKLID); return NtUserLoadKeyboardLayoutEx(NULL, 0, &ustrKbdName, NULL, &ustrKLID, dwhkl, Flags); } /* * @implemented */ UINT WINAPI MapVirtualKeyA(UINT uCode, UINT uMapType) { return MapVirtualKeyExA(uCode, uMapType, GetKeyboardLayout(0)); } /* * @implemented */ UINT WINAPI MapVirtualKeyExA(UINT uCode, UINT uMapType, HKL dwhkl) { return MapVirtualKeyExW(uCode, uMapType, dwhkl); } /* * @implemented */ UINT WINAPI MapVirtualKeyExW(UINT uCode, UINT uMapType, HKL dwhkl) { return NtUserMapVirtualKeyEx(uCode, uMapType, 0, dwhkl); } /* * @implemented */ UINT WINAPI MapVirtualKeyW(UINT uCode, UINT uMapType) { return MapVirtualKeyExW(uCode, uMapType, GetKeyboardLayout(0)); } /* * @implemented */ DWORD WINAPI OemKeyScan(WORD wOemChar) { WCHAR p; SHORT Vk; UINT Scan; MultiByteToWideChar(CP_OEMCP, 0, (PCSTR)&wOemChar, 1, &p, 1); Vk = VkKeyScanW(p); Scan = MapVirtualKeyW((Vk & 0x00ff), 0); if (!Scan) return -1; /* Page 450-1, MS W2k SuperBible by SAMS. Return, low word has the scan code and high word has the shift state. */ return ((Vk & 0xff00) << 8) | Scan; } /* * @implemented */ BOOL WINAPI SetDoubleClickTime(UINT uInterval) { return (BOOL)NtUserSystemParametersInfo(SPI_SETDOUBLECLICKTIME, uInterval, NULL, 0); } /* * @implemented */ BOOL WINAPI SwapMouseButton( BOOL fSwap) { return NtUserxSwapMouseButton(fSwap); } /* * @implemented */ int WINAPI ToAscii(UINT uVirtKey, UINT uScanCode, CONST BYTE *lpKeyState, LPWORD lpChar, UINT uFlags) { return ToAsciiEx(uVirtKey, uScanCode, lpKeyState, lpChar, uFlags, 0); } /* * @implemented */ int WINAPI ToAsciiEx(UINT uVirtKey, UINT uScanCode, CONST BYTE *lpKeyState, LPWORD lpChar, UINT uFlags, HKL dwhkl) { WCHAR UniChars[2]; int Ret, CharCount; Ret = ToUnicodeEx(uVirtKey, uScanCode, lpKeyState, UniChars, 2, uFlags, dwhkl); CharCount = (Ret < 0 ? 1 : Ret); WideCharToMultiByte(CP_ACP, 0, UniChars, CharCount, (LPSTR)lpChar, 2, NULL, NULL); return Ret; } /* * @implemented */ int WINAPI ToUnicode(UINT wVirtKey, UINT wScanCode, CONST BYTE *lpKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags) { return ToUnicodeEx(wVirtKey, wScanCode, lpKeyState, pwszBuff, cchBuff, wFlags, 0); } /* * @implemented */ int WINAPI ToUnicodeEx(UINT wVirtKey, UINT wScanCode, CONST BYTE *lpKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags, HKL dwhkl) { return NtUserToUnicodeEx(wVirtKey, wScanCode, (PBYTE)lpKeyState, pwszBuff, cchBuff, wFlags, dwhkl); } /* * @implemented */ SHORT WINAPI VkKeyScanA(CHAR ch) { WCHAR wChar; if (IsDBCSLeadByte(ch)) return -1; MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wChar, 1); return VkKeyScanW(wChar); } /* * @implemented */ SHORT WINAPI VkKeyScanExA(CHAR ch, HKL dwhkl) { WCHAR wChar; if (IsDBCSLeadByte(ch)) return -1; MultiByteToWideChar(CP_ACP, 0, &ch, 1, &wChar, 1); return VkKeyScanExW(wChar, dwhkl); } /* * @implemented */ SHORT WINAPI VkKeyScanExW(WCHAR ch, HKL dwhkl) { return (SHORT)NtUserVkKeyScanEx(ch, dwhkl, TRUE); } /* * @implemented */ SHORT WINAPI VkKeyScanW(WCHAR ch) { return (SHORT)NtUserVkKeyScanEx(ch, 0, FALSE); } /* * @implemented */ VOID WINAPI keybd_event( BYTE bVk, BYTE bScan, DWORD dwFlags, ULONG_PTR dwExtraInfo) { INPUT Input; Input.type = INPUT_KEYBOARD; Input.ki.wVk = bVk; Input.ki.wScan = bScan; Input.ki.dwFlags = dwFlags; Input.ki.time = 0; Input.ki.dwExtraInfo = dwExtraInfo; NtUserSendInput(1, &Input, sizeof(INPUT)); } /* * @implemented */ VOID WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, ULONG_PTR dwExtraInfo) { INPUT Input; Input.type = INPUT_MOUSE; Input.mi.dx = dx; Input.mi.dy = dy; Input.mi.mouseData = dwData; Input.mi.dwFlags = dwFlags; Input.mi.time = 0; Input.mi.dwExtraInfo = dwExtraInfo; NtUserSendInput(1, &Input, sizeof(INPUT)); } /* EOF */