* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Messages
/* lParam bits */
#define LP_EXT_BIT (1<<24)
/* From kbdxx.c -- Key changes with numlock */
-#define KNUMP 0x400
+#define KNUMP 0x400
-/* Lock the keyboard state to prevent unusual concurrent access */
+/* Lock the keyboard state to prevent unusual concurrent access */
FAST_MUTEX QueueStateLock;
BYTE QueueKeyStateTable[256];
/* Special handling for toggles like numpad and caps lock */
if (vk == VK_CAPITAL || vk == VK_NUMLOCK) {
if (down) QueueKeyStateTable[vk] ^= KS_LOCK_BIT;
- }
+ }
if (ext && vk == VK_LSHIFT)
vk = VK_RSHIFT;
DbgPrint( "};\n" );
}
-static BYTE KeysSet( PKBDTABLES pkKT, PBYTE KeyState,
+static BYTE KeysSet( PKBDTABLES pkKT, PBYTE KeyState,
int FakeModLeft, int FakeModRight ) {
if( !KeyState || !pkKT ) return 0;
static DWORD FASTCALL GetShiftBit( PKBDTABLES pkKT, DWORD Vk ) {
int i;
- for( i = 0; pkKT->pCharModifiers->pVkToBit[i].Vk; i++ )
- if( pkKT->pCharModifiers->pVkToBit[i].Vk == Vk )
+ for( i = 0; pkKT->pCharModifiers->pVkToBit[i].Vk; i++ )
+ if( pkKT->pCharModifiers->pVkToBit[i].Vk == Vk )
return pkKT->pCharModifiers->pVkToBit[i].ModBits;
return 0;
/* DumpKeyState( KeyState ); */
- if (KeysSet( pkKT, KeyState, VK_LSHIFT, VK_RSHIFT ) &
+ if (KeysSet( pkKT, KeyState, VK_LSHIFT, VK_RSHIFT ) &
KS_DOWN_BIT)
ModBits |= GetShiftBit( pkKT, VK_SHIFT );
-
- if (KeysSet( pkKT, KeyState, VK_LCONTROL, VK_RCONTROL ) &
+
+ if (KeysSet( pkKT, KeyState, VK_LCONTROL, VK_RCONTROL ) &
KS_DOWN_BIT )
ModBits |= GetShiftBit( pkKT, VK_CONTROL );
if (KeysSet( pkKT, KeyState, VK_RMENU, 0 ) &
KS_DOWN_BIT )
ModBits |= GetShiftBit( pkKT, VK_CONTROL );
-
+
/* Deal with VK_CAPITAL */
- if (KeysSet( pkKT, KeyState, VK_CAPITAL, 0 ) & KS_LOCK_BIT)
+ if (KeysSet( pkKT, KeyState, VK_CAPITAL, 0 ) & KS_LOCK_BIT)
{
ModBits |= CAPITAL_BIT;
}
/* Deal with VK_NUMLOCK */
- if (KeysSet( pkKT, KeyState, VK_NUMLOCK, 0 ) & KS_LOCK_BIT)
+ if (KeysSet( pkKT, KeyState, VK_NUMLOCK, 0 ) & KS_LOCK_BIT)
{
ModBits |= NUMLOCK_BIT;
}
PBOOL pbDead,
PBOOL pbLigature,
PWCHAR pwcTranslatedChar,
- PKBDTABLES keyLayout )
+ PKBDTABLES keyLayout )
{
PVK_TO_WCHAR_TABLE vtwTbl;
PVK_TO_WCHARS10 vkPtr;
size_t size_this_entry;
- int nMod, shift;
+ int nMod;
DWORD CapsMod = 0, CapsState = 0;
CapsState = ModBits & ~MOD_BITS_MASK;
ModBits = ModBits & MOD_BITS_MASK;
- DPRINT ( "TryToTranslate: %04x %x\n", wVirtKey, ModBits );
+ DPRINT ( "TryToTranslate: %04x %x\n", wVirtKey, ModBits );
if (ModBits > keyLayout->pCharModifiers->wMaxModBits)
{
return FALSE;
}
- shift = keyLayout->pCharModifiers->ModNumber[ModBits];
-
for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
{
vtwTbl = &keyLayout->pVkToWcharTable[nMod];
{
if( wVirtKey == (vkPtr->VirtualKey & 0xff) )
{
- CapsMod =
- shift | ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0);
+ CapsMod = keyLayout->pCharModifiers->ModNumber
+ [ModBits ^
+ ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0)];
if( CapsMod > keyLayout->pVkToWcharTable[nMod].nModifications ) {
DWORD MaxBit = 1;
- while( MaxBit <
+ while( MaxBit <
keyLayout->pVkToWcharTable[nMod].nModifications )
MaxBit <<= 1;
CapsMod &= MaxBit - 1; /* Guarantee that CapsMod lies
in bounds. */
}
-
+
*pbDead = vkPtr->wch[CapsMod] == WCH_DEAD;
*pbLigature = vkPtr->wch[CapsMod] == WCH_LGTR;
*pwcTranslatedChar = vkPtr->wch[CapsMod];
-
- DPRINT("%d %04x: CapsMod %08x CapsState %08x shift %08x Char %04x\n",
+
+ DPRINT("%d %04x: CapsMod %08x CapsState %08x Char %04x\n",
nMod, wVirtKey,
- CapsMod, CapsState, shift, *pwcTranslatedChar);
+ CapsMod, CapsState, *pwcTranslatedChar);
- if( *pbDead )
+ if( *pbDead )
{
vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
- if( vkPtr->VirtualKey != 0xff )
+ if( vkPtr->VirtualKey != 0xff )
{
DPRINT( "Found dead key with no trailer in the table.\n" );
DPRINT( "VK: %04x, ADDR: %08x\n", wVirtKey, (int)vkPtr );
return FALSE;
}
- *pwcTranslatedChar = vkPtr->wch[shift];
+ *pwcTranslatedChar = vkPtr->wch[CapsMod];
}
return TRUE;
}
ModBits( pkKT, lpKeyState ),
&bDead,
&bLigature,
- &wcTranslatedChar,
- pkKT ) )
+ &wcTranslatedChar,
+ pkKT ) )
{
- if( bLigature )
+ if( bLigature )
{
DPRINT("Not handling ligature (yet)\n" );
return 0;
return ret;
}
+DWORD
+STDCALL
+NtUserGetAsyncKeyState(
+ DWORD key)
+{
+ DWORD ret = 0;
+
+ IntLockQueueState;
+ if( key < 0x100 ) {
+ ret = ((DWORD)(QueueKeyStateTable[key] & KS_DOWN_BIT) << 8 ) |
+ (QueueKeyStateTable[key] & KS_LOCK_BIT);
+ }
+ IntUnLockQueueState;
+ return ret;
+}
+
+
+
int STDCALL ToUnicodeEx( UINT wVirtKey,
UINT wScanCode,
PBYTE lpKeyState,
pwszBuff,
cchBuff,
wFlags,
- PsGetWin32Thread() ?
+ PsGetWin32Thread() ?
PsGetWin32Thread()->KeyboardLayout : 0 );
IntUnLockQueueState;
}
0 );
}
-/*
+/*
* Utility to copy and append two unicode strings.
*
* IN OUT PUNICODE_STRING ResultFirst -> First string and result
PUNICODE_STRING Second,
BOOL Deallocate) {
NTSTATUS Status;
- PWSTR new_string =
+ PWSTR new_string =
ExAllocatePoolWithTag(PagedPool,
(ResultFirst->Length + Second->Length + sizeof(WCHAR)),
TAG_STRING);
if( !new_string ) {
return STATUS_NO_MEMORY;
}
- memcpy( new_string, ResultFirst->Buffer,
+ memcpy( new_string, ResultFirst->Buffer,
ResultFirst->Length );
memcpy( new_string + ResultFirst->Length / sizeof(WCHAR),
Second->Buffer,
ResultFirst->Length += Second->Length;
ResultFirst->MaximumLength = ResultFirst->Length;
new_string[ResultFirst->Length / sizeof(WCHAR)] = 0;
- Status = RtlCreateUnicodeString(ResultFirst,new_string) ?
+ Status = RtlCreateUnicodeString(ResultFirst,new_string) ?
STATUS_SUCCESS : STATUS_NO_MEMORY;
ExFreePool(new_string);
return Status;
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 =
+ KeyValuePartialInfo =
ExAllocatePoolWithTag(PagedPool, ResLength, TAG_STRING);
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);
ExFreePool(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"");
AppendUnicodeString(ReturnedValue,&Temp,FALSE);
-
+
ExFreePool(KeyValuePartialInfo);
NtClose(KeyHandle);
-
+
return Status;
}
RtlInitUnicodeString(&FullLayoutPath,SYSTEMROOT_DIR);
if( !NT_SUCCESS(Status) ) {
- DPRINT1("Got default locale but not layout file. (%08x)\n",
+ DPRINT1("Got default locale but not layout file. (%08lx)\n",
Status);
- RtlFreeUnicodeString(&LayoutFile);
} else {
DPRINT("Read registry and got %wZ\n", &LayoutFile);
-
+
RtlFreeUnicodeString(&LayoutKeyName);
AppendUnicodeString(&FullLayoutPath,&LayoutFile,FALSE);
RtlFreeUnicodeString(&LayoutFile);
- KeyboardLayoutWSTR =
+ KeyboardLayoutWSTR =
ExAllocatePoolWithTag(PagedPool,
- FullLayoutPath.Length + sizeof(WCHAR),
+ FullLayoutPath.Length + sizeof(WCHAR),
TAG_STRING);
if( !KeyboardLayoutWSTR ) {
if( !kbModule )
DPRINT1( "Load Keyboard Layout: No %wZ\n", &FullLayoutPath );
- }
- RtlFreeUnicodeString(&FullLayoutPath);
+ RtlFreeUnicodeString(&FullLayoutPath);
+ }
}
if( !kbModule )
{
DPRINT1("Trying to load US Keyboard Layout\n");
kbModule = EngLoadImage(L"\\SystemRoot\\system32\\kbdus.dll");
-
+
if (!kbModule)
{
DPRINT1("Failed to load any Keyboard Layout\n");
&kbdProcedureName,
0,
(PVOID*)&layerDescGetFn);
-
+
if( layerDescGetFn ) {
*pkKeyboardLayout = layerDescGetFn();
}
IntLockQueueState;
+ /* All messages have to contain the cursor point. */
+ IntGetCursorLocation(PsGetWin32Thread()->Desktop->WindowStation,
+ &NewMsg.pt);
+
UState = ToUnicodeInner(lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff,
- QueueKeyStateTable, wp, 2, 0,
+ QueueKeyStateTable, wp, 2, 0,
keyLayout );
if (UState == 1)
{
first = keyLayout->pDeadKey[i].dwBoth >> 16;
second = keyLayout->pDeadKey[i].dwBoth;
- if (first == dead_char && second == wp[0])
+ if (first == dead_char && second == wp[0])
{
wp[0] = keyLayout->pDeadKey[i].wchComposed;
dead_char = 0;
DPRINT("FINAL CHAR: %c\n", wp[0]);
}
- if (dead_char)
+
+ if (dead_char)
{
NewMsg.hwnd = lpMsg->hwnd;
NewMsg.wParam = dead_char;
dead_char = 0;
MsqPostMessage(PsGetWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
}
-
+
NewMsg.hwnd = lpMsg->hwnd;
NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam;
}
else if (UState == -1)
{
- NewMsg.message =
+ NewMsg.message =
(lpMsg->message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;
NewMsg.hwnd = lpMsg->hwnd;
NewMsg.wParam = wp[0];
Result = FALSE;
}
IntUnLockQueueState;
-
+
return Result;
}
int i;
for( i = 0; pkKT->pVSCtoVK_E0[i].Vsc; i++ ) {
- if( pkKT->pVSCtoVK_E0[i].Vsc == Code )
+ if( pkKT->pVSCtoVK_E0[i].Vsc == Code )
return pkKT->pVSCtoVK_E0[i].Vk & 0xff;
}
for( i = 0; pkKT->pVSCtoVK_E1[i].Vsc; i++ ) {
- if( pkKT->pVSCtoVK_E1[i].Vsc == Code )
+ if( pkKT->pVSCtoVK_E1[i].Vsc == Code )
return pkKT->pVSCtoVK_E1[i].Vk & 0xff;
}
break;
case 1:
- ret =
+ ret =
DontDistinguishShifts
(IntMapVirtualKeyEx( Code, 3, keyLayout ) );
break;
} break;
case 3:
-
+
ret = ScanToVk( Code, FALSE, keyLayout );
break;
}
UINT
STDCALL
NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl ) {
- PKBDTABLES keyLayout = PsGetWin32Thread() ?
+ PKBDTABLES keyLayout = PsGetWin32Thread() ?
PsGetWin32Thread()->KeyboardLayout : 0;
if( !keyLayout ) return 0;
BYTE KeyStateBuf[0x100];
PWCHAR OutPwszBuff = 0;
int ret = 0;
-
+
if( !NT_SUCCESS(MmCopyFromCaller(KeyStateBuf,
lpKeyState,
OutPwszBuff,
cchBuff,
wFlags,
- dwhkl );
+ dwhkl );
MmCopyToCaller(pwszBuff,OutPwszBuff,sizeof(WCHAR)*cchBuff);
ExFreePool(OutPwszBuff);
UINT VkCode = 0;
UINT ScanCode = (lParam >> 16) & 0xff;
BOOL ExtKey = lParam & (1<<24) ? TRUE : FALSE;
- PKBDTABLES keyLayout =
- PsGetWin32Thread() ?
+ PKBDTABLES keyLayout =
+ PsGetWin32Thread() ?
PsGetWin32Thread()->KeyboardLayout : 0;
if( !keyLayout || nSize < 1 ) return 0;
VSC_LPWSTR *KeyNames = 0;
- if( CareVk != VkCode )
+ if( CareVk != VkCode )
ScanCode = VkToScan( VkCode, ExtKey, keyLayout );
-
- if( ExtKey )
+
+ if( ExtKey )
KeyNames = keyLayout->pKeyNamesExt;
- else
+ else
KeyNames = keyLayout->pKeyNames;
for( i = 0; KeyNames[i].pwsz; i++ ) {
UINT StrLen = wcslen(KeyNames[i].pwsz);
UINT StrMax = StrLen > (nSize - 1) ? (nSize - 1) : StrLen;
WCHAR null_wc = 0;
- if( NT_SUCCESS( MmCopyToCaller( lpString,
- KeyNames[i].pwsz,
+ if( NT_SUCCESS( MmCopyToCaller( lpString,
+ KeyNames[i].pwsz,
StrMax * sizeof(WCHAR) ) ) &&
NT_SUCCESS( MmCopyToCaller( lpString + StrMax,
&null_wc,
DWORD i = 0;
DWORD BaseMapping = 0;
DWORD RawVk = 0;
- static WORD NumpadConversion[][2] =
+ static WORD NumpadConversion[][2] =
{ { VK_DELETE, VK_DECIMAL },
{ VK_INSERT, VK_NUMPAD0 },
{ VK_END, VK_NUMPAD1 },
{ VK_PRIOR, VK_NUMPAD9 },
{ 0,0 } };
- if( !KeyboardLayout || !Msg ||
+ if( !KeyboardLayout || !Msg ||
(Msg->message != WM_KEYDOWN && Msg->message != WM_SYSKEYDOWN &&
- Msg->message != WM_KEYUP && Msg->message != WM_SYSKEYUP) )
+ Msg->message != WM_KEYUP && Msg->message != WM_SYSKEYUP) )
{
return;
}
IntLockQueueState;
- /* arty -- handle numpad -- On real windows, the actual key produced
+ /* arty -- handle numpad -- On real windows, the actual key produced
* by the messaging layer is different based on the state of numlock. */
ModifierBits = ModBits(KeyboardLayout,QueueKeyStateTable);
*
* Shift and the LP_EXT_BIT cancel. */
ScanCode = (Msg->lParam >> 16) & 0xff;
- BaseMapping = Msg->wParam =
+ BaseMapping = Msg->wParam =
IntMapVirtualKeyEx( ScanCode, 1, KeyboardLayout );
if( ScanCode >= KeyboardLayout->bMaxVSCtoVK )
RawVk = 0;
else
RawVk = KeyboardLayout->pusVSCtoVK[ScanCode];
- if ((ModifierBits & NUMLOCK_BIT) &&
- !(ModifierBits & GetShiftBit(KeyboardLayout, VK_SHIFT)) &&
+ if ((ModifierBits & NUMLOCK_BIT) &&
+ !(ModifierBits & GetShiftBit(KeyboardLayout, VK_SHIFT)) &&
(RawVk & KNUMP) &&
!(Msg->lParam & LP_EXT_BIT))
{
/* The key in question is a numpad key. Search for a translation. */
- for (i = 0; NumpadConversion[i][0]; i++)
+ for (i = 0; NumpadConversion[i][0]; i++)
{
if ((BaseMapping & 0xff) == NumpadConversion[i][0]) /* RawVk? */
{
IntUnLockQueueState;
}
+
+DWORD
+STDCALL
+NtUserGetKeyboardLayoutList(
+ DWORD Items,
+ DWORD pHklBuff)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+DWORD
+STDCALL
+NtUserGetKeyboardLayoutName(
+ DWORD lpszName)
+{
+ UNIMPLEMENTED
+
+ return 0;
+}
+
+HKL
+STDCALL
+NtUserGetKeyboardLayout(
+ DWORD dwThreadId)
+{
+ NTSTATUS Status;
+ PETHREAD Thread;
+ PW32THREAD W32Thread;
+ PKBDTABLES layout;
+
+ if (!dwThreadId)
+ W32Thread = PsGetWin32Thread();
+ else
+ {
+ Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+ W32Thread = Thread->Tcb.Win32Thread;
+ }
+ layout = W32Thread->KeyboardLayout;
+ if(!layout) return 0;
+ return (HKL)layout;
+}
+
+
+DWORD
+STDCALL
+NtUserGetKeyboardType(
+ DWORD TypeFlag)
+{
+ switch(TypeFlag)
+ {
+ case 0: /* Keyboard type */
+ return 4; /* AT-101 */
+ case 1: /* Keyboard Subtype */
+ return 0; /* There are no defined subtypes */
+ case 2: /* Number of F-keys */
+ return 12; /* We're doing an 101 for now, so return 12 F-keys */
+ default:
+ DPRINT1("Unknown type!\n");
+ return 0; /* The book says 0 here, so 0 */
+ }
+}
+
+
+/*
+ Based on TryToTranslateChar, instead of processing VirtualKey match,
+ look for wChar match.
+ */
+DWORD
+STDCALL
+NtUserVkKeyScanEx(
+ DWORD wChar,
+ DWORD KeyboardLayout,
+ DWORD Unknown2)
+{
+ PKBDTABLES KeyLayout;
+ PVK_TO_WCHAR_TABLE vtwTbl;
+ PVK_TO_WCHARS10 vkPtr;
+ size_t size_this_entry;
+ int nMod;
+ DWORD CapsMod = 0, CapsState = 0;
+
+ if(!KeyboardLayout) return -1;
+ KeyLayout = (PKBDTABLES) KeyboardLayout;
+
+ for (nMod = 0; KeyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
+ {
+ vtwTbl = &KeyLayout->pVkToWcharTable[nMod];
+ size_this_entry = vtwTbl->cbSize;
+ vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
+
+ while(vkPtr->VirtualKey)
+ {
+ /*
+ 0x01 Shift key
+ 0x02 Ctrl key
+ 0x04 Alt key
+ Should have only 8 valid possibilities. Including zero.
+ */
+ for(CapsState = 0; CapsState < vtwTbl->nModifications; CapsState++)
+ {
+ if(vkPtr->wch[CapsState] == wChar)
+ {
+ CapsMod = KeyLayout->pCharModifiers->ModNumber[CapsState];
+ DPRINT("nMod %d wC %04x: CapsMod %08x CapsState %08x MaxModBits %08x\n",
+ nMod, wChar, CapsMod, CapsState, KeyLayout->pCharModifiers->wMaxModBits);
+ return ((CapsMod << 8)|(vkPtr->VirtualKey & 0xff));
+ }
+ }
+ vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
+ }
+ }
+ return -1;
+}
+
+
/* EOF */