📄 input.c
字号:
/*
* 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.
*/
/* $Id: input.c 25470 2007-01-15 20:33:07Z fireball $
*
* PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/input.c
* PURPOSE: Input
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* 09-05-2001 CSH Created
*/
/* INCLUDES ******************************************************************/
#include <user32.h>
#include <wine/debug.h>
/* Directory to load key layouts from */
#define SYSTEMROOT_DIR L"\\SystemRoot\\System32\\"
/* GLOBALS *******************************************************************/
typedef struct __TRACKINGLIST {
TRACKMOUSEEVENT tme;
POINT pos; /* center of hover rectangle */
} _TRACKINGLIST;
/* FIXME: move tracking stuff into a per thread data */
static _TRACKINGLIST tracking_info;
static UINT_PTR timer;
static const INT iTimerInterval = 50; /* msec for timer interval */
/* LOCALE FUNCTIONS **********************************************************/
/*
* Utility function to read a value from the registry more easily.
*
* IN PUNICODE_STRING KeyName -> Name of key to open
* IN PUNICODE_STRING ValueName -> Name of value to open
* OUT PUNICODE_STRING ReturnedValue -> String contained in registry
*
* Returns NTSTATUS
*/
static
NTSTATUS FASTCALL
ReadRegistryValue( PUNICODE_STRING KeyName,
PUNICODE_STRING ValueName,
PUNICODE_STRING ReturnedValue )
{
NTSTATUS Status;
HANDLE KeyHandle;
OBJECT_ATTRIBUTES KeyAttributes;
PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
ULONG Length = 0;
ULONG ResLength = 0;
UNICODE_STRING Temp;
InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE,
NULL, NULL);
Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &KeyAttributes);
if( !NT_SUCCESS(Status) )
{
return Status;
}
Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,
0,
0,
&ResLength);
if( Status != STATUS_BUFFER_TOO_SMALL )
{
NtClose(KeyHandle);
return Status;
}
ResLength += sizeof( *KeyValuePartialInfo );
KeyValuePartialInfo = LocalAlloc(LMEM_ZEROINIT, ResLength);
Length = ResLength;
if( !KeyValuePartialInfo )
{
NtClose(KeyHandle);
return STATUS_NO_MEMORY;
}
Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,
(PVOID)KeyValuePartialInfo,
Length,
&ResLength);
if( !NT_SUCCESS(Status) )
{
NtClose(KeyHandle);
LocalFree(KeyValuePartialInfo);
return Status;
}
Temp.Length = Temp.MaximumLength = KeyValuePartialInfo->DataLength;
Temp.Buffer = (PWCHAR)KeyValuePartialInfo->Data;
/* At this point, KeyValuePartialInfo->Data contains the key data */
RtlInitUnicodeString(ReturnedValue,L"");
RtlAppendUnicodeStringToString(ReturnedValue,&Temp);
LocalFree(KeyValuePartialInfo);
NtClose(KeyHandle);
return Status;
}
static
HKL FASTCALL
IntLoadKeyboardLayout( LPCWSTR pwszKLID,
UINT Flags)
{
HANDLE Handle;
HINSTANCE KBModule = 0;
FARPROC pAddr = 0;
DWORD offTable = 0;
HKL hKL;
NTSTATUS Status;
WCHAR LocaleBuffer[16];
UNICODE_STRING LayoutKeyName;
UNICODE_STRING LayoutValueName;
UNICODE_STRING DefaultLocale;
UNICODE_STRING LayoutFile;
UNICODE_STRING FullLayoutPath;
LCID LocaleId;
PWCHAR KeyboardLayoutWSTR;
ULONG_PTR layout;
LANGID langid;
layout = (ULONG_PTR) wcstoul(pwszKLID, NULL, 16);
// LocaleId = GetSystemDefaultLCID();
LocaleId = (LCID) layout;
/* Create the HKL to be used by NtUserLoadKeyboardLayoutEx*/
/*
* 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.
*/
langid = PRIMARYLANGID(LANGIDFROMLCID(layout));
if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
layout |= 0xe001 << 16; /* FIXME */
else
layout |= layout << 16;
DPRINT("Input = %S\n", pwszKLID );
DPRINT("DefaultLocale = %lx\n", LocaleId);
swprintf(LocaleBuffer, L"%08lx", LocaleId);
DPRINT("DefaultLocale = %S\n", LocaleBuffer);
RtlInitUnicodeString(&DefaultLocale, LocaleBuffer);
RtlInitUnicodeString(&LayoutKeyName,
L"\\REGISTRY\\Machine\\SYSTEM\\CurrentControlSet"
L"\\Control\\KeyboardLayouts\\");
RtlAppendUnicodeStringToString(&LayoutKeyName,&DefaultLocale);
RtlInitUnicodeString(&LayoutValueName,L"Layout File");
Status = ReadRegistryValue(&LayoutKeyName,&LayoutValueName,&LayoutFile);
RtlFreeUnicodeString(&LayoutKeyName);
DPRINT("Read registry and got %wZ\n", &LayoutFile);
RtlInitUnicodeString(&FullLayoutPath,SYSTEMROOT_DIR);
RtlAppendUnicodeStringToString(&FullLayoutPath,&LayoutFile);
DPRINT("Loading Keyboard DLL %wZ\n", &FullLayoutPath);
RtlFreeUnicodeString(&LayoutFile);
KeyboardLayoutWSTR = LocalAlloc(LMEM_ZEROINIT,
FullLayoutPath.Length + sizeof(WCHAR));
if( !KeyboardLayoutWSTR )
{
DPRINT1("Couldn't allocate a string for the keyboard layout name.\n");
RtlFreeUnicodeString(&FullLayoutPath);
return NULL;
}
memcpy(KeyboardLayoutWSTR,FullLayoutPath.Buffer, FullLayoutPath.Length);
KeyboardLayoutWSTR[FullLayoutPath.Length / sizeof(WCHAR)] = 0;
KBModule = LoadLibraryW(KeyboardLayoutWSTR);
DPRINT( "Load Keyboard Layout: %S\n", KeyboardLayoutWSTR );
if( !KBModule )
DPRINT1( "Load Keyboard Layout: No %wZ\n", &FullLayoutPath );
pAddr = GetProcAddress( KBModule, (LPCSTR) 1);
offTable = (DWORD) pAddr - (DWORD) KBModule; // Weeks to figure this out!
DPRINT( "Load Keyboard Module Offset: %x\n", offTable );
FreeLibrary(KBModule);
Handle = CreateFileW( KeyboardLayoutWSTR,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
hKL = NtUserLoadKeyboardLayoutEx( Handle,
offTable,
(HKL) layout,
&DefaultLocale,
(UINT) layout,
Flags);
NtClose(Handle);
LocalFree(KeyboardLayoutWSTR);
RtlFreeUnicodeString(&FullLayoutPath);
return hKL;
}
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
BOOL
STDCALL
DragDetect(
HWND hWnd,
POINT pt)
{
#if 0
return NtUserDragDetect(hWnd, pt.x, pt.y);
#else
MSG msg;
RECT rect;
POINT tmp;
ULONG dx = NtUserGetSystemMetrics(SM_CXDRAG);
ULONG dy = NtUserGetSystemMetrics(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))
{
if (msg.message == WM_LBUTTONUP)
{
ReleaseCapture();
return 0;
}
if (msg.message == WM_MOUSEMOVE)
{
tmp.x = LOWORD(msg.lParam);
tmp.y = HIWORD(msg.lParam);
if (!PtInRect(&rect, tmp))
{
ReleaseCapture();
return 1;
}
}
}
WaitMessage();
}
return 0;
#endif
}
/*
* @unimplemented
*/
HKL STDCALL
ActivateKeyboardLayout(HKL hkl,
UINT Flags)
{
UNIMPLEMENTED;
return (HKL)0;
}
/*
* @implemented
*/
BOOL STDCALL
BlockInput(BOOL fBlockIt)
{
return NtUserBlockInput(fBlockIt);
}
/*
* @implemented
*/
BOOL STDCALL
EnableWindow(HWND hWnd,
BOOL bEnable)
{
LONG Style = NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE);
/* check if updating is needed */
UINT bIsDisabled = (Style & WS_DISABLED);
if ( (bIsDisabled && bEnable) || (!bIsDisabled && !bEnable) )
{
if (bEnable)
{
Style &= ~WS_DISABLED;
}
else
{
Style |= WS_DISABLED;
/* Remove keyboard focus from that window if it had focus */
if (hWnd == GetFocus())
{
SetFocus(NULL);
}
}
NtUserSetWindowLong(hWnd, GWL_STYLE, Style, FALSE);
SendMessageA(hWnd, WM_ENABLE, (LPARAM) IsWindowEnabled(hWnd), 0);
}
// Return nonzero if it was disabled, or zero if it wasn't:
return IsWindowEnabled(hWnd);
}
/*
* @implemented
*/
SHORT STDCALL
GetAsyncKeyState(int vKey)
{
return (SHORT) NtUserGetAsyncKeyState((DWORD) vKey);
}
/*
* @implemented
*/
UINT
STDCALL
GetDoubleClickTime(VOID)
{
return NtUserGetDoubleClickTime();
}
/*
* @implemented
*/
HKL STDCALL
GetKeyboardLayout(DWORD idThread)
{
return (HKL)NtUserCallOneParam((DWORD) idThread, ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT);
}
/*
* @implemented
*/
UINT STDCALL
GetKBCodePage(VOID)
{
return GetOEMCP();
}
/*
* @implemented
*/
int STDCALL
GetKeyNameTextA(LONG lParam,
LPSTR lpString,
int nSize)
{
LPWSTR intermediateString =
HeapAlloc(GetProcessHeap(),0,nSize * sizeof(WCHAR));
int ret = 0;
UINT wstrLen = 0;
BOOL defChar = FALSE;
if( !intermediateString ) return 0;
ret = GetKeyNameTextW(lParam,intermediateString,nSize);
if( ret == 0 ) { lpString[0] = 0; return 0; }
wstrLen = wcslen( intermediateString );
ret = WideCharToMultiByte(CP_ACP, 0,
intermediateString, wstrLen,
lpString, nSize, ".", &defChar );
lpString[ret] = 0;
HeapFree(GetProcessHeap(),0,intermediateString);
return ret;
}
/*
* @implemented
*/
int STDCALL
GetKeyNameTextW(LONG lParam,
LPWSTR lpString,
int nSize)
{
return NtUserGetKeyNameText( lParam, lpString, nSize );
}
/*
* @implemented
*/
SHORT STDCALL
GetKeyState(int nVirtKey)
{
return (SHORT) NtUserGetKeyState((DWORD) nVirtKey);
}
/*
* @unimplemented
*/
UINT STDCALL
GetKeyboardLayoutList(int nBuff,
HKL FAR *lpList)
{
UNIMPLEMENTED;
return 0;
}
/*
* @implemented
*/
BOOL STDCALL
GetKeyboardLayoutNameA(LPSTR pwszKLID)
{
WCHAR buf[KL_NAMELENGTH];
if (GetKeyboardLayoutNameW(buf))
return WideCharToMultiByte( CP_ACP, 0, buf, -1, pwszKLID, KL_NAMELENGTH, NULL, NULL ) != 0;
return FALSE;
}
/*
* @implemented
*/
BOOL STDCALL
GetKeyboardLayoutNameW(LPWSTR pwszKLID)
{
return NtUserGetKeyboardLayoutName( pwszKLID );
}
/*
* @implemented
*/
BOOL STDCALL
GetKeyboardState(PBYTE lpKeyState)
{
return (BOOL) NtUserGetKeyboardState((LPBYTE) lpKeyState);
}
/*
* @implemented
*/
int STDCALL
GetKeyboardType(int nTypeFlag)
{
return (int)NtUserCallOneParam((DWORD) nTypeFlag, ONEPARAM_ROUTINE_GETKEYBOARDTYPE);
}
/*
* @implemented
*/
BOOL STDCALL
GetLastInputInfo(PLASTINPUTINFO plii)
{
return NtUserGetLastInputInfo(plii);
}
/*
* @implemented
*/
HKL STDCALL
LoadKeyboardLayoutA(LPCSTR pwszKLID,
UINT Flags)
{
HKL ret;
UNICODE_STRING pwszKLIDW;
if (pwszKLID) RtlCreateUnicodeStringFromAsciiz(&pwszKLIDW, pwszKLID);
else pwszKLIDW.Buffer = NULL;
ret = LoadKeyboardLayoutW(pwszKLIDW.Buffer, Flags);
RtlFreeUnicodeString(&pwszKLIDW);
return ret;
}
/*
* @implemented
*/
HKL STDCALL
LoadKeyboardLayoutW(LPCWSTR pwszKLID,
UINT Flags)
{
return IntLoadKeyboardLayout( pwszKLID, Flags);
}
/*
* @implemented
*/
UINT STDCALL
MapVirtualKeyA(UINT uCode,
UINT uMapType)
{
return MapVirtualKeyExA( uCode, uMapType, GetKeyboardLayout( 0 ) );
}
/*
* @implemented
*/
UINT STDCALL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -