mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Adding Art Yerkes Keyboard Testing Code
svn path=/trunk/; revision=5323
This commit is contained in:
parent
9b70e2debd
commit
bf7329e25b
7 changed files with 476 additions and 51 deletions
|
@ -9,7 +9,7 @@ include $(PATH_TO_TOP)/rules.mak
|
|||
|
||||
# Console system utilities
|
||||
# cabman cat net objdir partinfo pice ps sc stats
|
||||
UTIL_APPS = cat objdir partinfo pnpdump sc stats tickcount
|
||||
UTIL_APPS = cat objdir partinfo pnpdump sc stats tickcount consw
|
||||
|
||||
UTIL_NET_APPS =
|
||||
|
||||
|
|
111
reactos/ntoskrnl/include/internal/kbd.h
Normal file
111
reactos/ntoskrnl/include/internal/kbd.h
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* ReactOS System Header -- kbd.h */
|
||||
#define __KBD_H
|
||||
|
||||
#if __GNUC__ >=3
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _VK_TO_BIT {
|
||||
BYTE Vk;
|
||||
BYTE ModBits;
|
||||
} VK_TO_BIT, *PVK_TO_BIT;
|
||||
|
||||
typedef struct _MODIFIERS {
|
||||
PVK_TO_BIT pVkToBit;
|
||||
WORD wMaxModBits;
|
||||
BYTE ModNumber[];
|
||||
} MODIFIERS, *PMODIFIERS;
|
||||
|
||||
#define TYPEDEF_VK_TO_WCHARS(i) \
|
||||
typedef struct _VK_TO_WCHARS ## i { \
|
||||
BYTE VirtualKey; \
|
||||
BYTE Attributes; \
|
||||
WCHAR wch[i]; \
|
||||
} VK_TO_WCHARS ## i, *PVK_TO_WCHARS ## i;
|
||||
|
||||
TYPEDEF_VK_TO_WCHARS(1)
|
||||
TYPEDEF_VK_TO_WCHARS(2)
|
||||
TYPEDEF_VK_TO_WCHARS(3)
|
||||
TYPEDEF_VK_TO_WCHARS(4)
|
||||
TYPEDEF_VK_TO_WCHARS(5)
|
||||
TYPEDEF_VK_TO_WCHARS(6)
|
||||
TYPEDEF_VK_TO_WCHARS(7)
|
||||
TYPEDEF_VK_TO_WCHARS(8)
|
||||
TYPEDEF_VK_TO_WCHARS(9)
|
||||
TYPEDEF_VK_TO_WCHARS(10)
|
||||
|
||||
typedef struct _VK_TO_WCHAR_TABLE {
|
||||
PVK_TO_WCHARS1 pVkToWchars;
|
||||
BYTE nModifications;
|
||||
BYTE cbSize;
|
||||
} VK_TO_WCHAR_TABLE, *PVK_TO_WCHAR_TABLE;
|
||||
|
||||
typedef struct _DEADKEY {
|
||||
DWORD dwBoth;
|
||||
WCHAR wchComposed;
|
||||
USHORT uFlags;
|
||||
} DEADKEY, *PDEADKEY;
|
||||
|
||||
#define DKF_DEAD 1
|
||||
|
||||
typedef struct _VSC_LPWSTR {
|
||||
BYTE vsc;
|
||||
LPWSTR pwsz;
|
||||
} VSC_LPWSTR, *PVSC_LPWSTR;
|
||||
|
||||
typedef struct _VSC_VK {
|
||||
BYTE Vsc;
|
||||
USHORT Vk;
|
||||
} VSC_VK, *PVSC_VK;
|
||||
|
||||
#define TYPEDEF_LIGATURE(i) \
|
||||
typedef struct _LIGATURE ## i { \
|
||||
BYTE VirtualKey; \
|
||||
WORD ModificationNumber; \
|
||||
WCHAR wch[i]; \
|
||||
} LIGATURE ## i, *PLIGATURE ## i;
|
||||
|
||||
TYPEDEF_LIGATURE(1)
|
||||
|
||||
#define KBD_VERSION 1
|
||||
#define GET_KBD_VERSION(p) (HIWORD((p)->fLocalFlags))
|
||||
#define KLLF_ALTGR 1
|
||||
#define KLLF_SHIFTLOCK 2
|
||||
#define KLLF_LRM_RLM 4
|
||||
|
||||
typedef struct _KBDTABLES {
|
||||
PMODIFIERS pCharModifiers;
|
||||
PVK_TO_WCHAR_TABLE pVkToWcharTable;
|
||||
PDEADKEY pDeadKey;
|
||||
VSC_LPWSTR *pKeyNames;
|
||||
VSC_LPWSTR *pKeyNamesExt;
|
||||
LPWSTR *pKeyNamesDead;
|
||||
USHORT *pusVSCtoVK;
|
||||
BYTE bMaxVSCtoVK;
|
||||
PVSC_VK pVSCtoVK_E0;
|
||||
PVSC_VK pVSCtoVK_E1;
|
||||
DWORD fLocalFlags;
|
||||
BYTE nLgMaxd;
|
||||
BYTE cbLgEntry;
|
||||
PLIGATURE1 pLigature;
|
||||
} KBDTABLES, *PKBDTABLES;
|
||||
|
||||
/* Constants that help table decoding */
|
||||
#define WCH_NONE 0xf000
|
||||
#define WCH_DEAD 0xf001
|
||||
#define WCH_LGTR 0xf002
|
||||
|
||||
#define CAPSLOK 1
|
||||
#define SGCAPS 2
|
||||
#define CAPLOKALTGR 4
|
||||
#define KANALOK 8
|
||||
#define GRPSELTAP 0x80
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif//__KBD_H
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: conio.c,v 1.48 2003/06/19 19:38:26 ea Exp $
|
||||
/* $Id: conio.c,v 1.49 2003/07/29 23:03:01 jimtabor Exp $
|
||||
*
|
||||
* reactos/subsys/csrss/api/conio.c
|
||||
*
|
||||
|
@ -33,6 +33,7 @@ static HANDLE KeyboardDeviceHandle;
|
|||
static PCSRSS_CONSOLE ActiveConsole;
|
||||
CRITICAL_SECTION ActiveConsoleLock;
|
||||
static COORD PhysicalConsoleSize;
|
||||
static BOOL KeyReadInhibit = FALSE;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -926,8 +927,12 @@ VOID Console_Api( DWORD RefreshEvent )
|
|||
continue;
|
||||
}
|
||||
KeyEventRecord->InputEvent.EventType = KEY_EVENT;
|
||||
Status = NtReadFile( KeyboardDeviceHandle, Events[0], NULL, NULL, &Iosb,
|
||||
&KeyEventRecord->InputEvent.Event.KeyEvent, sizeof( KEY_EVENT_RECORD ), NULL, 0 );
|
||||
if( !KeyReadInhibit ) {
|
||||
Status = NtReadFile( KeyboardDeviceHandle, Events[0], NULL, NULL, &Iosb,
|
||||
&KeyEventRecord->InputEvent.Event.KeyEvent, sizeof( KEY_EVENT_RECORD ), NULL, 0 );
|
||||
} else {
|
||||
Status = STATUS_PENDING;
|
||||
}
|
||||
if( !NT_SUCCESS( Status ) )
|
||||
{
|
||||
DbgPrint( "CSR: ReadFile on keyboard device failed\n" );
|
||||
|
@ -2462,9 +2467,20 @@ CSR_API(CsrWriteConsoleInput)
|
|||
*/
|
||||
static NTSTATUS FASTCALL SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
|
||||
{
|
||||
DbgPrint( "Console Hardware State: %d\n", ConsoleHwState );
|
||||
|
||||
if ( (CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
|
||||
||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
|
||||
{
|
||||
/* Inhibit keyboard input when hardware state ==
|
||||
* CONSOLE_HARDWARE_STATE_GDI_MANAGED */
|
||||
if (CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState) {
|
||||
DbgPrint( "Keyboard Inhibited.\n" );
|
||||
KeyReadInhibit = TRUE;
|
||||
} else {
|
||||
DbgPrint( "Keyboard Enabled.\n" );
|
||||
KeyReadInhibit = FALSE;
|
||||
}
|
||||
if (Console->HardwareState != ConsoleHwState)
|
||||
{
|
||||
/* TODO: implement switching from full screen to windowed mode */
|
||||
|
@ -2493,13 +2509,15 @@ CSR_API(CsrHardwareStateProperty)
|
|||
);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint( "Failed to get console handle in SetConsoleHardwareState\n" );
|
||||
Reply->Status = Status;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Console->Header.Type != CSRSS_CONSOLE_MAGIC)
|
||||
{
|
||||
Reply->Status = STATUS_INVALID_HANDLE;
|
||||
DbgPrint( "Bad magic on Console: %08x\n", Console->Header.Type );
|
||||
Reply->Status = STATUS_INVALID_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2510,6 +2528,7 @@ CSR_API(CsrHardwareStateProperty)
|
|||
break;
|
||||
|
||||
case CONSOLE_HARDWARE_STATE_SET:
|
||||
DbgPrint( "Setting console hardware state.\n" );
|
||||
Reply->Status = SetConsoleHardwareState (Console, Request->Data.ConsoleHardwareStateRequest.State);
|
||||
break;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: wapi.c,v 1.28 2003/03/09 21:42:47 hbirr Exp $
|
||||
/* $Id: wapi.c,v 1.29 2003/07/29 23:03:01 jimtabor Exp $
|
||||
*
|
||||
* reactos/subsys/csrss/api/wapi.c
|
||||
*
|
||||
|
@ -68,6 +68,7 @@ static const CsrFunc CsrFuncs[] = {
|
|||
CsrCloseHandle,
|
||||
CsrVerifyHandle,
|
||||
CsrDuplicateHandle,
|
||||
CsrHardwareStateProperty,
|
||||
0 };
|
||||
|
||||
static void Thread_Api2(HANDLE ServerPort)
|
||||
|
|
|
@ -16,13 +16,77 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: loader.c,v 1.11 2003/07/11 15:59:37 royce Exp $
|
||||
/* $Id: loader.c,v 1.12 2003/07/29 23:03:01 jimtabor Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/winddi.h>
|
||||
|
||||
/*
|
||||
* Blatantly stolen from ldr/utils.c in ntdll. I can't link ntdll from
|
||||
* here, though.
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
LdrGetProcedureAddress (IN PVOID BaseAddress,
|
||||
IN PANSI_STRING Name,
|
||||
IN ULONG Ordinal,
|
||||
OUT PVOID *ProcedureAddress)
|
||||
{
|
||||
PIMAGE_EXPORT_DIRECTORY ExportDir;
|
||||
PUSHORT OrdinalPtr;
|
||||
PULONG NamePtr;
|
||||
PULONG AddressPtr;
|
||||
ULONG i = 0;
|
||||
|
||||
DbgPrint("LdrGetProcedureAddress (BaseAddress %x Name %Z Ordinal %lu ProcedureAddress %x)\n",
|
||||
BaseAddress, Name, Ordinal, ProcedureAddress);
|
||||
|
||||
/* Get the pointer to the export directory */
|
||||
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
|
||||
RtlImageDirectoryEntryToData (BaseAddress,
|
||||
TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT,
|
||||
&i);
|
||||
|
||||
DbgPrint("ExportDir %x i %lu\n", ExportDir, i);
|
||||
|
||||
if (!ExportDir || !i || !ProcedureAddress)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
AddressPtr = (PULONG)((ULONG)BaseAddress + (ULONG)ExportDir->AddressOfFunctions);
|
||||
if (Name && Name->Length)
|
||||
{
|
||||
/* by name */
|
||||
OrdinalPtr = (PUSHORT)((ULONG)BaseAddress + (ULONG)ExportDir->AddressOfNameOrdinals);
|
||||
NamePtr = (PULONG)((ULONG)BaseAddress + (ULONG)ExportDir->AddressOfNames);
|
||||
for( i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
|
||||
{
|
||||
if (!_strnicmp(Name->Buffer, (char*)(BaseAddress + *NamePtr), Name->Length))
|
||||
{
|
||||
*ProcedureAddress = (PVOID)((ULONG)BaseAddress + (ULONG)AddressPtr[*OrdinalPtr]);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
DbgPrint("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* by ordinal */
|
||||
Ordinal &= 0x0000FFFF;
|
||||
if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions)
|
||||
{
|
||||
*ProcedureAddress = (PVOID)((ULONG)BaseAddress + (ULONG)AddressPtr[Ordinal - ExportDir->Base]);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
DbgPrint("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal);
|
||||
}
|
||||
|
||||
return STATUS_PROCEDURE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -60,4 +124,52 @@ EngLoadModule(LPWSTR ModuleName)
|
|||
return (HANDLE)GdiDriverInfo.ModuleBase;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is copied from ntdll... It's needed for loading keyboard dlls.
|
||||
*/
|
||||
|
||||
PVOID
|
||||
STDCALL
|
||||
RtlImageDirectoryEntryToData (
|
||||
PVOID BaseAddress,
|
||||
BOOLEAN bFlag,
|
||||
ULONG Directory,
|
||||
PULONG Size
|
||||
)
|
||||
{
|
||||
PIMAGE_NT_HEADERS NtHeader;
|
||||
PIMAGE_SECTION_HEADER SectionHeader;
|
||||
ULONG Va;
|
||||
ULONG Count;
|
||||
|
||||
NtHeader = RtlImageNtHeader (BaseAddress);
|
||||
if (NtHeader == NULL)
|
||||
return NULL;
|
||||
|
||||
if (Directory >= NtHeader->OptionalHeader.NumberOfRvaAndSizes)
|
||||
return NULL;
|
||||
|
||||
Va = NtHeader->OptionalHeader.DataDirectory[Directory].VirtualAddress;
|
||||
if (Va == 0)
|
||||
return NULL;
|
||||
|
||||
if (Size)
|
||||
*Size = NtHeader->OptionalHeader.DataDirectory[Directory].Size;
|
||||
|
||||
if (bFlag)
|
||||
return (PVOID)(BaseAddress + Va);
|
||||
|
||||
/* image mapped as ordinary file, we must find raw pointer */
|
||||
SectionHeader = (PIMAGE_SECTION_HEADER)(NtHeader + 1);
|
||||
Count = NtHeader->FileHeader.NumberOfSections;
|
||||
while (Count--)
|
||||
{
|
||||
if (SectionHeader->VirtualAddress == Va)
|
||||
return (PVOID)(BaseAddress + SectionHeader->PointerToRawData);
|
||||
SectionHeader++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: input.c,v 1.8 2003/07/05 16:04:01 chorns Exp $
|
||||
/* $Id: input.c,v 1.9 2003/07/29 23:03:01 jimtabor Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -108,6 +108,10 @@ KeyboardThreadMain(PVOID StartContext)
|
|||
sizeof(KEY_EVENT_RECORD),
|
||||
NULL,
|
||||
NULL);
|
||||
DbgPrint( "KeyRaw: %s %04x\n",
|
||||
KeyEvent.bKeyDown ? "down" : "up",
|
||||
KeyEvent.wVirtualScanCode );
|
||||
|
||||
if (Status == STATUS_ALERTED && !InputThreadsRunning)
|
||||
{
|
||||
break;
|
||||
|
@ -119,6 +123,7 @@ KeyboardThreadMain(PVOID StartContext)
|
|||
}
|
||||
|
||||
SysKey = KeyEvent.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED);
|
||||
DbgPrint( "Key: %s\n", KeyEvent.bKeyDown ? "down" : "up" );
|
||||
|
||||
/*
|
||||
* Post a keyboard message.
|
||||
|
@ -157,9 +162,7 @@ KeyboardThreadMain(PVOID StartContext)
|
|||
{
|
||||
lParam |= (1 << 29); /* Context mode. 1 if ALT if pressed while the key is pressed */
|
||||
}
|
||||
|
||||
|
||||
MsqPostKeyboardMessage(SysKey ? WM_SYSKEYDOWN : WM_KEYDOWN, KeyEvent.wVirtualKeyCode,
|
||||
MsqPostKeyboardMessage(SysKey ? WM_SYSKEYUP : WM_KEYUP, KeyEvent.wVirtualKeyCode,
|
||||
lParam);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: keyboard.c,v 1.5 2003/07/20 05:32:19 jimtabor Exp $
|
||||
/* $Id: keyboard.c,v 1.6 2003/07/29 23:03:01 jimtabor Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -32,6 +32,7 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include <win32k/win32k.h>
|
||||
#include <internal/safe.h>
|
||||
#include <internal/kbd.h>
|
||||
#include <include/guicheck.h>
|
||||
#include <include/msgqueue.h>
|
||||
#include <include/window.h>
|
||||
|
@ -43,9 +44,11 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
DWORD ModBits = 0;
|
||||
BYTE QueueKeyStateTable[256];
|
||||
static PVOID pkKeyboardLayout = 0;
|
||||
|
||||
/* arty -- These should be phased out for the general kbdxx.dll tables */
|
||||
|
||||
struct accent_char
|
||||
{
|
||||
|
@ -164,35 +167,225 @@ static const struct accent_char accent_chars[] =
|
|||
/* {'.', 'I', '\335'}, {'.', 'i', '\375'}, */ /* dot above */
|
||||
};
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*** Statics used by TranslateMessage ***/
|
||||
|
||||
static VOID STDCALL SetKeyState(DWORD key, BOOL down) {
|
||||
if( key >= 'a' && key <= 'z' ) key += 'A' - 'a';
|
||||
QueueKeyStateTable[key] = down;
|
||||
}
|
||||
|
||||
static BOOL SetModKey( PKBDTABLES pkKT, WORD wVK, BOOL down ) {
|
||||
int i;
|
||||
|
||||
for( i = 0; pkKT->pCharModifiers->pVkToBit[i].Vk; i++ ) {
|
||||
DbgPrint( "vk[%d] = { %04x, %x }\n", i,
|
||||
pkKT->pCharModifiers->pVkToBit[i].Vk,
|
||||
pkKT->pCharModifiers->pVkToBit[i].ModBits );
|
||||
if( pkKT->pCharModifiers->pVkToBit[i].Vk == wVK ) {
|
||||
if( down ) ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits;
|
||||
else ModBits &= ~pkKT->pCharModifiers->pVkToBit[i].ModBits;
|
||||
DbgPrint( "ModBits: %x\n", ModBits );
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL TryToTranslateChar( WORD wVirtKey,
|
||||
PVK_TO_WCHAR_TABLE vtwTbl,
|
||||
DWORD ModBits,
|
||||
PBOOL pbDead,
|
||||
PBOOL pbLigature,
|
||||
PWCHAR pwcTranslatedChar ) {
|
||||
int i,j;
|
||||
size_t size_this_entry = vtwTbl->cbSize;
|
||||
int nStates = vtwTbl->nModifications;
|
||||
PVK_TO_WCHARS10 vkPtr;
|
||||
|
||||
for( i = 0;; i++ ) {
|
||||
vkPtr = (PVK_TO_WCHARS10)
|
||||
(((BYTE *)vtwTbl->pVkToWchars) + i * size_this_entry);
|
||||
|
||||
if( !vkPtr->VirtualKey ) return FALSE;
|
||||
if( wVirtKey == vkPtr->VirtualKey ) {
|
||||
for( j = 0; j < nStates; j++ ) {
|
||||
if( j == ModBits ) { /* OK, we found a wchar with the correct
|
||||
shift state and vk */
|
||||
*pbDead = vkPtr->wch[j] == WCH_DEAD;
|
||||
*pbLigature = vkPtr->wch[j] == WCH_LGTR;
|
||||
*pwcTranslatedChar = vkPtr->wch[j];
|
||||
if( *pbDead ) {
|
||||
i++;
|
||||
vkPtr = (PVK_TO_WCHARS10)
|
||||
(((BYTE *)vtwTbl->pVkToWchars) + i * size_this_entry);
|
||||
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[j];
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int STDCALL
|
||||
ToUnicode(UINT wVirtKey,
|
||||
UINT wScanCode,
|
||||
PBYTE lpKeyState,
|
||||
LPWSTR pwszBuff,
|
||||
int cchBuff,
|
||||
UINT wFlags)
|
||||
ToUnicodeInner(UINT wVirtKey,
|
||||
UINT wScanCode,
|
||||
PBYTE lpKeyState,
|
||||
LPWSTR pwszBuff,
|
||||
int cchBuff,
|
||||
UINT wFlags,
|
||||
DWORD ModBits,
|
||||
PKBDTABLES pkKT)
|
||||
{
|
||||
return(0);
|
||||
int i;
|
||||
|
||||
DbgPrint("wVirtKey=%08x, wScanCode=%08x, lpKeyState=[], "
|
||||
"pwszBuff=%S, cchBuff=%d, wFlags=%x\n",
|
||||
wVirtKey, wScanCode, /* lpKeyState, */ pwszBuff,
|
||||
cchBuff, wFlags );
|
||||
|
||||
for( i = 0; pkKT->pVkToWcharTable[i].nModifications; i++ ) {
|
||||
WCHAR wcTranslatedChar;
|
||||
BOOL bDead;
|
||||
BOOL bLigature;
|
||||
|
||||
if( TryToTranslateChar( wVirtKey,
|
||||
&pkKT->pVkToWcharTable[i],
|
||||
ModBits,
|
||||
&bDead,
|
||||
&bLigature,
|
||||
&wcTranslatedChar ) ) {
|
||||
if( bLigature ) {
|
||||
DPRINT("Not handling ligature (yet)\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( cchBuff > 0 ) pwszBuff[0] = wcTranslatedChar;
|
||||
|
||||
if( bDead ) return -1;
|
||||
else return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
NtUserGetKeyState(
|
||||
DWORD key)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
if (key >= 'a' && key <= 'z') key += 'A' - 'a';
|
||||
ret = ((DWORD)(QueueKeyStateTable[key] & 0x80) << 8 ) |
|
||||
(QueueKeyStateTable[key] & 0x80) |
|
||||
(QueueKeyStateTable[key] & 0x01);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int STDCALL ToUnicode( UINT wVirtKey,
|
||||
UINT wScanCode,
|
||||
PBYTE lpKeyState,
|
||||
LPWSTR pwszBuff,
|
||||
int cchBuff,
|
||||
UINT wFlags ) {
|
||||
return ToUnicodeInner( wVirtKey,
|
||||
wScanCode,
|
||||
QueueKeyStateTable,
|
||||
pwszBuff,
|
||||
cchBuff,
|
||||
wFlags,
|
||||
ModBits,
|
||||
pkKeyboardLayout );
|
||||
}
|
||||
|
||||
typedef PVOID (*KbdLayerDescriptor)(VOID);
|
||||
NTSTATUS STDCALL LdrGetProcedureAddress(PVOID module,
|
||||
PANSI_STRING import_name,
|
||||
DWORD flags,
|
||||
PVOID *func_addr);
|
||||
|
||||
void InitKbdLayout( PVOID *pkKeyboardLayout ) {
|
||||
HMODULE kbModule = 0;
|
||||
ANSI_STRING kbdProcedureName;
|
||||
NTSTATUS Status;
|
||||
|
||||
KbdLayerDescriptor layerDescGetFn;
|
||||
|
||||
kbModule = EngLoadImage(L"\\SystemRoot\\system32\\kbdus.dll");
|
||||
|
||||
if( !kbModule ) {
|
||||
DbgPrint( "Foo: No kbdus.dll\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" );
|
||||
LdrGetProcedureAddress((PVOID)kbModule,
|
||||
&kbdProcedureName,
|
||||
0,
|
||||
&layerDescGetFn);
|
||||
if( layerDescGetFn ) {
|
||||
*pkKeyboardLayout = layerDescGetFn();
|
||||
}
|
||||
}
|
||||
|
||||
BOOL STDCALL
|
||||
NtUserTranslateMessage(LPMSG lpMsg,
|
||||
DWORD Unknown1)
|
||||
DWORD Unknown1) /* Used to pass the kbd layout */
|
||||
{
|
||||
LONG UState;
|
||||
WCHAR wp[2];
|
||||
MSG NewMsg;
|
||||
static INT dead_char;
|
||||
static INT dead_char = 0;
|
||||
LONG UState = 0;
|
||||
WCHAR wp[2] = { 0 };
|
||||
MSG NewMsg = { 0 };
|
||||
PUSER_MESSAGE UMsg;
|
||||
|
||||
/* FIXME: Should pass current keyboard layout for this thread. */
|
||||
/* At the moment, the keyboard layout is global. */
|
||||
/* Also, we're fixed at kbdus.dll ... */
|
||||
if( !pkKeyboardLayout ) InitKbdLayout( &pkKeyboardLayout );
|
||||
if( !pkKeyboardLayout ) {
|
||||
DbgPrint( "Not Translating due to empty layout.\n" );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
|
||||
{
|
||||
if (lpMsg->message == WM_KEYUP) {
|
||||
DbgPrint( "About to SetKeyState( %04x, FALSE );\n", lpMsg->wParam );
|
||||
SetKeyState( lpMsg->wParam, FALSE ); /* Release key */
|
||||
DbgPrint( "About to SetModKey();\n" );
|
||||
SetModKey( pkKeyboardLayout, lpMsg->wParam, FALSE );
|
||||
/* Release Mod if any */
|
||||
DbgPrint( "Done with keys.\n" );
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/* FIXME: Should pass current keyboard layout for this thread. */
|
||||
UState = ToUnicode(lpMsg->wParam, HIWORD(lpMsg->lParam),
|
||||
QueueKeyStateTable, wp, 2, 0);
|
||||
DbgPrint( "About to SetKeyState( %04x, TRUE );\n", lpMsg->wParam );
|
||||
SetKeyState( lpMsg->wParam, TRUE ); /* Strike key */
|
||||
|
||||
/* Pass 1: Search for modifiers */
|
||||
DbgPrint( "About to SetModKey();\n" );
|
||||
if( SetModKey( pkKeyboardLayout, lpMsg->wParam, TRUE ) ) return TRUE;
|
||||
DbgPrint( "Done with keys.\n" );
|
||||
|
||||
/* Pass 2: Get Unicode Character */
|
||||
DbgPrint( "Calling ToUnicodeString()\n" );
|
||||
UState = ToUnicodeInner(lpMsg->wParam, HIWORD(lpMsg->lParam),
|
||||
QueueKeyStateTable, wp, 2, 0, ModBits,
|
||||
pkKeyboardLayout);
|
||||
|
||||
DbgPrint( "UState is %d after key %04x\n", UState, wp[0] );
|
||||
if (UState == 1)
|
||||
{
|
||||
NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
|
||||
|
@ -218,13 +411,14 @@ NtUserTranslateMessage(LPMSG lpMsg,
|
|||
}
|
||||
dead_char = 0;
|
||||
}
|
||||
NewMsg.hwnd = lpMsg->hwnd;
|
||||
NewMsg.wParam = wp[0];
|
||||
NewMsg.lParam = lpMsg->lParam;
|
||||
UMsg = MsqCreateMessage(&NewMsg);
|
||||
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
NewMsg.hwnd = lpMsg->hwnd;
|
||||
NewMsg.wParam = wp[0];
|
||||
NewMsg.lParam = lpMsg->lParam;
|
||||
UMsg = MsqCreateMessage(&NewMsg);
|
||||
DbgPrint( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam );
|
||||
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
|
||||
return(TRUE);
|
||||
}
|
||||
else if (UState == -1)
|
||||
{
|
||||
|
@ -247,21 +441,6 @@ NtUserSetFocus(HWND hWnd)
|
|||
return W32kSetFocusWindow(hWnd);
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
NtUserGetKeyState(
|
||||
DWORD key)
|
||||
{
|
||||
DWORD ret;
|
||||
|
||||
if (key >= 'a' && key <= 'z') key += 'A' - 'a';
|
||||
ret = ((DWORD)(QueueKeyStateTable[key] & 0x80) << 8 ) |
|
||||
(QueueKeyStateTable[key] & 0x80) |
|
||||
(QueueKeyStateTable[key] & 0x01);
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD
|
||||
STDCALL
|
||||
NtUserGetKeyboardState(
|
||||
|
|
Loading…
Reference in a new issue