These changes are described in earlier posts to the ros-kernel list.

I believe everything here is correct, Alt+Gr works with the french keyboard,
Numlock and Capslock work normally in my testing.

svn path=/trunk/; revision=6772
This commit is contained in:
Art Yerkes 2003-11-24 00:22:53 +00:00
parent 108b5183a6
commit d792147982
10 changed files with 409 additions and 338 deletions

View file

@ -1,4 +1,4 @@
/* $Id: conio.c,v 1.56 2003/11/17 02:12:51 hyperion Exp $ /* $Id: conio.c,v 1.57 2003/11/24 00:22:52 arty Exp $
* *
* reactos/subsys/csrss/api/conio.c * reactos/subsys/csrss/api/conio.c
* *
@ -759,7 +759,6 @@ NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWOR
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
inline BOOLEAN CsrpIsEqualRect( inline BOOLEAN CsrpIsEqualRect(
SMALL_RECT Rect1, SMALL_RECT Rect1,
SMALL_RECT Rect2) SMALL_RECT Rect2)
@ -1363,6 +1362,18 @@ static DWORD CsrpGetShiftState( PBYTE KeyState ) {
case VK_RMENU: case VK_RMENU:
ssOut |= RIGHT_ALT_PRESSED | ENHANCED_KEY; ssOut |= RIGHT_ALT_PRESSED | ENHANCED_KEY;
break; break;
case VK_CAPITAL:
ssOut |= CAPSLOCK_ON;
break;
case VK_NUMLOCK:
ssOut |= NUMLOCK_ON;
break;
case VK_SCROLL:
ssOut |= SCROLLLOCK_ON;
break;
} }
} }
} }
@ -1375,70 +1386,64 @@ CsrpProcessKey(MSG *msg, PCSRSS_CONSOLE Console)
{ {
static PCSRSS_CONSOLE SwapConsole = 0; /* console we are thinking about swapping with */ static PCSRSS_CONSOLE SwapConsole = 0; /* console we are thinking about swapping with */
static BYTE KeyState[256] = { 0 }; static BYTE KeyState[256] = { 0 };
/* MSDN mentions that you should use the last virtual key code received
* when putting a virtual key identity to a WM_CHAR message since multiple
* or translated keys may be involved. */
static UINT LastVirtualKey = 0;
DWORD ShiftState;
ConsoleInput *ConInRec; ConsoleInput *ConInRec;
UINT RepeatCount; UINT RepeatCount;
CHAR AsciiChar;
WCHAR UnicodeChar; WCHAR UnicodeChar;
UINT VirtualKeyCode; UINT VirtualKeyCode;
UINT VirtualScanCode; UINT VirtualScanCode;
CHAR AsciiChar;
DWORD ShiftState;
BOOL Down = FALSE; BOOL Down = FALSE;
BOOL Ext = FALSE;
int RetChars;
WCHAR Chars[2] = { 0 };
INPUT_RECORD er; INPUT_RECORD er;
NTSTATUS Status; NTSTATUS Status;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
BYTE Mask; ULONG ResultSize = 0;
ULONG ResultSize;
RepeatCount = 1; RepeatCount = 1;
VirtualScanCode = (msg->lParam >> 16) & 0xff; VirtualScanCode = (msg->lParam >> 16) & 0xff;
VirtualKeyCode = msg->wParam; Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
Down = msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN; msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
Ext = msg->lParam & 0x01000000 ? TRUE : FALSE;
Mask = (Ext ? 0x40 : 0x80); NtUserGetKeyboardState((VOID *)KeyState);
ShiftState = CsrpGetShiftState(KeyState);
if (Down) if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR)
{ {
KeyState[VirtualScanCode] |= Mask; VirtualKeyCode = LastVirtualKey;
} UnicodeChar = msg->wParam;
}
else else
{ {
KeyState[VirtualScanCode] &= ~Mask; WCHAR Chars[2];
} INT RetChars = 0;
VirtualKeyCode = msg->wParam;
ShiftState = CsrpGetShiftState( KeyState ); RetChars = NtUserToUnicodeEx(VirtualKeyCode,
VirtualScanCode,
RetChars = NtUserToUnicodeEx(VirtualKeyCode, KeyState,
VirtualScanCode, Chars,
KeyState, 2,
Chars, 0,
2, 0);
0, UnicodeChar = (1 == RetChars ? Chars[0] : 0);
0);
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
RtlUnicodeToOemN(&AsciiChar,
1,
&ResultSize,
&UnicodeChar,
2);
if (0 == ResultSize)
{
AsciiChar = '\0';
} }
if (UnicodeChar)
RtlUnicodeToOemN(&AsciiChar,
1,
&ResultSize,
&UnicodeChar,
sizeof(WCHAR));
if (!ResultSize) AsciiChar = 0;
er.EventType = KEY_EVENT; er.EventType = KEY_EVENT;
er.Event.KeyEvent.bKeyDown = Down; er.Event.KeyEvent.bKeyDown = Down;
er.Event.KeyEvent.wRepeatCount = RepeatCount; er.Event.KeyEvent.wRepeatCount = RepeatCount;
// er.Event.KeyEvent.uChar.AsciiChar = AsciiChar; er.Event.KeyEvent.uChar.UnicodeChar = AsciiChar & 0xff;
// er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
er.Event.KeyEvent.uChar.UnicodeChar = AsciiChar;
er.Event.KeyEvent.dwControlKeyState = ShiftState; er.Event.KeyEvent.dwControlKeyState = ShiftState;
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode; er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode; er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
@ -1535,10 +1540,29 @@ CsrpProcessKey(MSG *msg, PCSRSS_CONSOLE Console)
} }
ConInRec->InputEvent = er; ConInRec->InputEvent = er;
ConInRec->Fake = FALSE; ConInRec->Fake = AsciiChar &&
(msg->message != WM_CHAR && msg->message != WM_SYSCHAR &&
msg->message != WM_KEYUP && msg->message != WM_SYSKEYUP);
ConInRec->NotChar = (msg->message != WM_CHAR && msg->message != WM_SYSCHAR);
ConInRec->Echoed = FALSE; ConInRec->Echoed = FALSE;
if (ConInRec->NotChar)
LastVirtualKey = msg->wParam;
DbgPrint("csrss: %s %s %s %s %02x %02x '%c' %04x\n",
Down ? "down" : "up ",
(msg->message == WM_CHAR || msg->message == WM_SYSCHAR) ?
"char" : "key ",
ConInRec->Fake ? "fake" : "real",
ConInRec->NotChar ? "notc" : "char",
VirtualScanCode,
VirtualKeyCode,
(AsciiChar >= ' ') ? AsciiChar : '.',
ShiftState);
CsrpProcessChar(Console, ConInRec); if (!ConInRec->Fake || !ConInRec->NotChar)
CsrpProcessChar(Console, ConInRec);
else
RtlFreeHeap(CsrssApiHeap,0,ConInRec);
UNLOCK; UNLOCK;
} }
@ -1559,8 +1583,9 @@ VOID Console_Api( DWORD RefreshEvent )
NtUserGetMessage( &msg, 0,0,0 ); NtUserGetMessage( &msg, 0,0,0 );
NtUserTranslateMessage( &msg, 0 ); NtUserTranslateMessage( &msg, 0 );
if (msg.message == WM_KEYDOWN || msg.message == WM_KEYUP || if ((msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP) { msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP)) {
CsrpProcessKey(&msg, ActiveConsole); CsrpProcessKey(&msg, ActiveConsole);
} }
} }

View file

@ -22,6 +22,7 @@ typedef struct ConsoleInput_t
INPUT_RECORD InputEvent; INPUT_RECORD InputEvent;
BOOLEAN Echoed; // already been echoed or not BOOLEAN Echoed; // already been echoed or not
BOOLEAN Fake; // synthesized, not a real event BOOLEAN Fake; // synthesized, not a real event
BOOLEAN NotChar; // message should not be used to return a character
} ConsoleInput; } ConsoleInput;
typedef struct CSRSS_CONSOLE_t *PCSRSS_CONSOLE; typedef struct CSRSS_CONSOLE_t *PCSRSS_CONSOLE;
@ -183,6 +184,8 @@ BOOL STDCALL CsrServerInitialization (ULONG ArgumentCount, PWSTR *ArgumentArray)
NTSTATUS STDCALL CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); NTSTATUS STDCALL CsrReleaseObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object ); NTSTATUS STDCALL CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
VOID STDCALL CsrDrawConsole(PCSRSS_CONSOLE Console); VOID STDCALL CsrDrawConsole(PCSRSS_CONSOLE Console);
NTSTATUS CsrpEchoUnicodeChar( PCSRSS_SCREEN_BUFFER Console,
WCHAR UnicodeChar );
NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length, BOOL Attrib ); NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWORD Length, BOOL Attrib );
#endif /* ndef _CSRSS_API_H */ #endif /* ndef _CSRSS_API_H */

View file

@ -1,4 +1,4 @@
/* $Id: guiconsole.c,v 1.1 2003/10/20 18:02:04 gvg Exp $ /* $Id: guiconsole.c,v 1.2 2003/11/24 00:22:53 arty Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -427,6 +427,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_KEYUP: case WM_KEYUP:
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
case WM_SYSKEYUP: case WM_SYSKEYUP:
case WM_CHAR:
GuiConsoleHandleKey(hWnd, msg, wParam, lParam); GuiConsoleHandleKey(hWnd, msg, wParam, lParam);
Result = 0; Result = 0;
break; break;

View file

@ -5,6 +5,8 @@
NTSTATUS FASTCALL NTSTATUS FASTCALL
InitInputImpl(VOID); InitInputImpl(VOID);
NTSTATUS FASTCALL
InitKeyboardImpl(VOID);
PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue(VOID); PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue(VOID);
PKBDTABLES W32kGetDefaultKeyLayout(VOID); PKBDTABLES W32kGetDefaultKeyLayout(VOID);
VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyLayout); VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyLayout);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: dllmain.c,v 1.53 2003/11/23 11:39:48 navaraf Exp $ /* $Id: dllmain.c,v 1.54 2003/11/24 00:22:53 arty Exp $
* *
* Entry Point for win32k.sys * Entry Point for win32k.sys
*/ */
@ -245,6 +245,13 @@ DllMain (
return(Status); return(Status);
} }
Status = InitKeyboardImpl();
if (!NT_SUCCESS(Status))
{
DbgPrint("Failed to initialize keyboard implementation.\n");
return(Status);
}
Status = MsqInitializeImpl(); Status = MsqInitializeImpl();
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: input.c,v 1.20 2003/11/23 12:24:21 weiden Exp $ /* $Id: input.c,v 1.21 2003/11/24 00:22:53 arty Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -63,7 +63,10 @@ KeyboardThreadMain(PVOID StartContext)
OBJECT_ATTRIBUTES KeyboardObjectAttributes; OBJECT_ATTRIBUTES KeyboardObjectAttributes;
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
NTSTATUS Status; NTSTATUS Status;
MSG msg;
PUSER_MESSAGE_QUEUE FocusQueue;
struct _ETHREAD *FocusThread;
RtlRosInitUnicodeStringFromLiteral(&KeyboardDeviceName, L"\\??\\Keyboard"); RtlRosInitUnicodeStringFromLiteral(&KeyboardDeviceName, L"\\??\\Keyboard");
InitializeObjectAttributes(&KeyboardObjectAttributes, InitializeObjectAttributes(&KeyboardObjectAttributes,
&KeyboardDeviceName, &KeyboardDeviceName,
@ -144,9 +147,55 @@ KeyboardThreadMain(PVOID StartContext)
/* FIXME: Support MOD_WIN */ /* FIXME: Support MOD_WIN */
lParam = KeyEvent.wRepeatCount |
((KeyEvent.wVirtualScanCode << 16) & 0x00FF0000) | 0x40000000;
/* Bit 24 indicates if this is an extended key */
if (KeyEvent.dwControlKeyState & ENHANCED_KEY)
{
lParam |= (1 << 24);
}
if (fsModifiers & MOD_ALT)
{
/* Context mode. 1 if ALT if pressed while the key is pressed */
lParam |= (1 << 29);
}
if(KeyEvent.bKeyDown && (fsModifiers & MOD_ALT))
msg.message = WM_SYSKEYDOWN;
else if(KeyEvent.bKeyDown)
msg.message = WM_KEYDOWN;
else if(fsModifiers & MOD_ALT)
msg.message = WM_SYSKEYUP;
else
msg.message = WM_KEYUP;
/* Find the target thread whose locale is in effect */
FocusQueue = IntGetFocusMessageQueue();
if (!FocusQueue) {
FocusQueue = W32kGetPrimitiveMessageQueue();
}
msg.wParam = KeyEvent.wVirtualKeyCode;
msg.lParam = lParam;
if (!FocusQueue) continue;
FocusThread = FocusQueue->Thread;
if (FocusThread && FocusThread->Win32Thread &&
FocusThread->Win32Thread->KeyboardLayout)
{
W32kKeyProcessMessage(&msg,
FocusThread->Win32Thread->KeyboardLayout);
}
else
continue;
if (GetHotKey(InputWindowStation, if (GetHotKey(InputWindowStation,
fsModifiers, fsModifiers,
KeyEvent.wVirtualKeyCode, msg.wParam,
&Thread, &Thread,
&hWnd, &hWnd,
&id)) &id))
@ -157,55 +206,16 @@ KeyboardThreadMain(PVOID StartContext)
MsqPostHotKeyMessage (Thread, MsqPostHotKeyMessage (Thread,
hWnd, hWnd,
(WPARAM)id, (WPARAM)id,
MAKELPARAM((WORD)fsModifiers, (WORD)KeyEvent.wVirtualKeyCode)); MAKELPARAM((WORD)fsModifiers,
(WORD)msg.wParam));
} }
} }
else else
/*
* Post a keyboard message.
*/
if (KeyEvent.bKeyDown)
{ {
lParam = KeyEvent.wRepeatCount | /*
((KeyEvent.wVirtualScanCode << 16) & 0x00FF0000) | 0x40000000; * Post a keyboard message.
*/
/* Bit 24 indicates if this is an extended key */ MsqPostKeyboardMessage(msg.message,msg.wParam,msg.lParam);
if (KeyEvent.dwControlKeyState & ENHANCED_KEY)
{
lParam |= (1 << 24);
}
if (fsModifiers & MOD_ALT)
{
/* Context mode. 1 if ALT if pressed while the key is pressed */
lParam |= (1 << 29);
}
MsqPostKeyboardMessage((fsModifiers & MOD_ALT) ? WM_SYSKEYDOWN : WM_KEYDOWN,
KeyEvent.wVirtualKeyCode,
lParam);
}
else
{
lParam = KeyEvent.wRepeatCount |
((KeyEvent.wVirtualScanCode << 16) & 0x00FF0000) | 0xC0000000;
/* Bit 24 indicates if this is an extended key */
if (KeyEvent.dwControlKeyState & ENHANCED_KEY)
{
lParam |= (1 << 24);
}
if (fsModifiers & MOD_ALT)
{
/* Context mode. 1 if ALT if pressed while the key is pressed */
lParam |= (1 << 29);
}
MsqPostKeyboardMessage((fsModifiers & MOD_ALT) ? WM_SYSKEYUP : WM_KEYUP,
KeyEvent.wVirtualKeyCode,
lParam);
} }
} }
DbgPrint( "Input Thread Stopped...\n" ); DbgPrint( "Input Thread Stopped...\n" );

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: keyboard.c,v 1.14 2003/11/07 19:58:43 arty Exp $ /* $Id: keyboard.c,v 1.15 2003/11/24 00:22:53 arty Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -44,131 +44,37 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* Directory to load key layouts from */
#define SYSTEMROOT_DIR L"\\SystemRoot\\System32\\" #define SYSTEMROOT_DIR L"\\SystemRoot\\System32\\"
/* Lock modifiers */
#define CAPITAL_BIT 0x80000000
#define NUMLOCK_BIT 0x40000000
#define MOD_BITS_MASK 0x3fffffff
#define MOD_KCTRL 0x02
/* Key States */
#define KS_DOWN_MASK 0xc0
#define KS_DOWN_BIT 0x80
#define KS_EXT_BIT 0x40
#define KS_LOCK_BIT 0x01
/* lParam bits */
#define LP_EXT_BIT (1<<24)
/* From kbdxx.c -- Key changes with numlock */
#define KNUMP 0x400
/* Lock the keyboard state to prevent unusual concurrent access */
KSPIN_LOCK QueueStateLock;
BYTE QueueKeyStateTable[256]; BYTE QueueKeyStateTable[256];
/* arty -- These should be phased out for the general kbdxx.dll tables */
struct accent_char
{
BYTE ac_accent;
BYTE ac_char;
BYTE ac_result;
};
static const struct accent_char accent_chars[] =
{
/* A good idea should be to read /usr/X11/lib/X11/locale/iso8859-x/Compose */
{'`', 'A', '\300'}, {'`', 'a', '\340'},
{'\'', 'A', '\301'}, {'\'', 'a', '\341'},
{'^', 'A', '\302'}, {'^', 'a', '\342'},
{'~', 'A', '\303'}, {'~', 'a', '\343'},
{'"', 'A', '\304'}, {'"', 'a', '\344'},
{'O', 'A', '\305'}, {'o', 'a', '\345'},
{'0', 'A', '\305'}, {'0', 'a', '\345'},
{'A', 'A', '\305'}, {'a', 'a', '\345'},
{'A', 'E', '\306'}, {'a', 'e', '\346'},
{',', 'C', '\307'}, {',', 'c', '\347'},
{'`', 'E', '\310'}, {'`', 'e', '\350'},
{'\'', 'E', '\311'}, {'\'', 'e', '\351'},
{'^', 'E', '\312'}, {'^', 'e', '\352'},
{'"', 'E', '\313'}, {'"', 'e', '\353'},
{'`', 'I', '\314'}, {'`', 'i', '\354'},
{'\'', 'I', '\315'}, {'\'', 'i', '\355'},
{'^', 'I', '\316'}, {'^', 'i', '\356'},
{'"', 'I', '\317'}, {'"', 'i', '\357'},
{'-', 'D', '\320'}, {'-', 'd', '\360'},
{'~', 'N', '\321'}, {'~', 'n', '\361'},
{'`', 'O', '\322'}, {'`', 'o', '\362'},
{'\'', 'O', '\323'}, {'\'', 'o', '\363'},
{'^', 'O', '\324'}, {'^', 'o', '\364'},
{'~', 'O', '\325'}, {'~', 'o', '\365'},
{'"', 'O', '\326'}, {'"', 'o', '\366'},
{'/', 'O', '\330'}, {'/', 'o', '\370'},
{'`', 'U', '\331'}, {'`', 'u', '\371'},
{'\'', 'U', '\332'}, {'\'', 'u', '\372'},
{'^', 'U', '\333'}, {'^', 'u', '\373'},
{'"', 'U', '\334'}, {'"', 'u', '\374'},
{'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
{'T', 'H', '\336'}, {'t', 'h', '\376'},
{'s', 's', '\337'}, {'"', 'y', '\377'},
{'s', 'z', '\337'}, {'i', 'j', '\377'},
/* iso-8859-2 uses this */
{'<', 'L', '\245'}, {'<', 'l', '\265'}, /* caron */
{'<', 'S', '\251'}, {'<', 's', '\271'},
{'<', 'T', '\253'}, {'<', 't', '\273'},
{'<', 'Z', '\256'}, {'<', 'z', '\276'},
{'<', 'C', '\310'}, {'<', 'c', '\350'},
{'<', 'E', '\314'}, {'<', 'e', '\354'},
{'<', 'D', '\317'}, {'<', 'd', '\357'},
{'<', 'N', '\322'}, {'<', 'n', '\362'},
{'<', 'R', '\330'}, {'<', 'r', '\370'},
{';', 'A', '\241'}, {';', 'a', '\261'}, /* ogonek */
{';', 'E', '\312'}, {';', 'e', '\332'},
{'\'', 'Z', '\254'}, {'\'', 'z', '\274'}, /* acute */
{'\'', 'R', '\300'}, {'\'', 'r', '\340'},
{'\'', 'L', '\305'}, {'\'', 'l', '\345'},
{'\'', 'C', '\306'}, {'\'', 'c', '\346'},
{'\'', 'N', '\321'}, {'\'', 'n', '\361'},
/* collision whith S, from iso-8859-9 !!! */
{',', 'S', '\252'}, {',', 's', '\272'}, /* cedilla */
{',', 'T', '\336'}, {',', 't', '\376'},
{'.', 'Z', '\257'}, {'.', 'z', '\277'}, /* dot above */
{'/', 'L', '\243'}, {'/', 'l', '\263'}, /* slash */
{'/', 'D', '\320'}, {'/', 'd', '\360'},
{'(', 'A', '\303'}, {'(', 'a', '\343'}, /* breve */
{'\275', 'O', '\325'}, {'\275', 'o', '\365'}, /* double acute */
{'\275', 'U', '\334'}, {'\275', 'u', '\374'},
{'0', 'U', '\332'}, {'0', 'u', '\372'}, /* ring above */
/* iso-8859-3 uses this */
{'/', 'H', '\241'}, {'/', 'h', '\261'}, /* slash */
{'>', 'H', '\246'}, {'>', 'h', '\266'}, /* circumflex */
{'>', 'J', '\254'}, {'>', 'j', '\274'},
{'>', 'C', '\306'}, {'>', 'c', '\346'},
{'>', 'G', '\330'}, {'>', 'g', '\370'},
{'>', 'S', '\336'}, {'>', 's', '\376'},
/* collision whith G( from iso-8859-9 !!! */
{'(', 'G', '\253'}, {'(', 'g', '\273'}, /* breve */
{'(', 'U', '\335'}, {'(', 'u', '\375'},
/* collision whith I. from iso-8859-3 !!! */
{'.', 'I', '\251'}, {'.', 'i', '\271'}, /* dot above */
{'.', 'C', '\305'}, {'.', 'c', '\345'},
{'.', 'G', '\325'}, {'.', 'g', '\365'},
/* iso-8859-4 uses this */
{',', 'R', '\243'}, {',', 'r', '\263'}, /* cedilla */
{',', 'L', '\246'}, {',', 'l', '\266'},
{',', 'G', '\253'}, {',', 'g', '\273'},
{',', 'N', '\321'}, {',', 'n', '\361'},
{',', 'K', '\323'}, {',', 'k', '\363'},
{'~', 'I', '\245'}, {'~', 'i', '\265'}, /* tilde */
{'-', 'E', '\252'}, {'-', 'e', '\272'}, /* macron */
{'-', 'A', '\300'}, {'-', 'a', '\340'},
{'-', 'I', '\317'}, {'-', 'i', '\357'},
{'-', 'O', '\322'}, {'-', 'o', '\362'},
{'-', 'U', '\336'}, {'-', 'u', '\376'},
{'/', 'T', '\254'}, {'/', 't', '\274'}, /* slash */
{'.', 'E', '\314'}, {'.', 'e', '\344'}, /* dot above */
{';', 'I', '\307'}, {';', 'i', '\347'}, /* ogonek */
{';', 'U', '\331'}, {';', 'u', '\371'},
/* iso-8859-9 uses this */
/* iso-8859-9 has really bad choosen G( S, and I. as they collide
* whith the same letters on other iso-8859-x (that is they are on
* different places :-( ), if you use turkish uncomment these and
* comment out the lines in iso-8859-2 and iso-8859-3 sections
* FIXME: should be dynamic according to chosen language
* if/when Wine has turkish support.
*/
/* collision whith G( from iso-8859-3 !!! */
/* {'(', 'G', '\320'}, {'(', 'g', '\360'}, */ /* breve */
/* collision whith S, from iso-8859-2 !!! */
/* {',', 'S', '\336'}, {',', 's', '\376'}, */ /* cedilla */
/* collision whith I. from iso-8859-3 !!! */
/* {'.', 'I', '\335'}, {'.', 'i', '\375'}, */ /* dot above */
};
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
/* Initialization -- Right now, just zero the key state and init the lock */
NTSTATUS FASTCALL InitKeyboardImpl(VOID) {
KeInitializeSpinLock(&QueueStateLock);
RtlZeroMemory(&QueueKeyStateTable,0x100);
return STATUS_SUCCESS;
}
/*** Statics used by TranslateMessage ***/ /*** Statics used by TranslateMessage ***/
static UINT DontDistinguishShifts( UINT ret ) { static UINT DontDistinguishShifts( UINT ret ) {
@ -178,8 +84,17 @@ static UINT DontDistinguishShifts( UINT ret ) {
return ret; return ret;
} }
static VOID STDCALL SetKeyState(DWORD key, BOOL down) { static VOID STDCALL SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down) {
QueueKeyStateTable[key] = down ? 0x80 : 0; /* Special handling for toggles like numpad and caps lock */
if (vk == VK_CAPITAL || vk == VK_NUMLOCK)
{
if (down) QueueKeyStateTable[key] ^= 1;
}
if (down)
QueueKeyStateTable[key] |= KS_DOWN_BIT | (ext ? KS_EXT_BIT : 0);
else
QueueKeyStateTable[key] &= ~KS_DOWN_MASK;
} }
VOID DumpKeyState( PBYTE KeyState ) { VOID DumpKeyState( PBYTE KeyState ) {
@ -195,14 +110,16 @@ VOID DumpKeyState( PBYTE KeyState ) {
static BYTE KeysSet( PKBDTABLES pkKT, PBYTE KeyState, static BYTE KeysSet( PKBDTABLES pkKT, PBYTE KeyState,
int Mod, int FakeModLeft, int FakeModRight ) { int Mod, int FakeModLeft, int FakeModRight ) {
int i; int i;
UINT Vk = 0;
if( !KeyState || !pkKT ) return 0; if( !KeyState || !pkKT ) return 0;
for( i = 0; i < pkKT->bMaxVSCtoVK; i++ ) { for( i = 0; i < pkKT->bMaxVSCtoVK; i++ ) {
if( KeyState[i] & 0xC0 && Vk = pkKT->pusVSCtoVK[i] & 0xff;
((pkKT->pusVSCtoVK[i] & 0xff) == Mod || if( KeyState[i] &&
(pkKT->pusVSCtoVK[i] & 0xff) == FakeModLeft || ((Vk == Mod) ||
(pkKT->pusVSCtoVK[i] & 0xff) == FakeModRight ) ) { (FakeModLeft && Vk == FakeModLeft) ||
(FakeModRight && Vk == FakeModRight)) ) {
return KeyState[i]; return KeyState[i];
} }
} }
@ -225,29 +142,41 @@ static DWORD ModBits( PKBDTABLES pkKT, PBYTE KeyState ) {
{ {
case VK_SHIFT: case VK_SHIFT:
Mask = KeysSet( pkKT, KeyState, Vk, VK_LSHIFT, VK_RSHIFT ); Mask = KeysSet( pkKT, KeyState, Vk, VK_LSHIFT, VK_RSHIFT );
if (Mask & 0xc0) if (Mask & KS_DOWN_MASK)
ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits; ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits;
break; break;
case VK_CONTROL: case VK_CONTROL:
Mask = KeysSet( pkKT, KeyState, Vk, VK_LCONTROL, VK_RCONTROL ); Mask = KeysSet( pkKT, KeyState, Vk, VK_LCONTROL, VK_RCONTROL );
if (Mask & 0xc0) if (Mask & KS_DOWN_MASK)
ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits; ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits;
break; break;
case VK_MENU: case VK_MENU:
Mask = KeysSet( pkKT, KeyState, Vk, VK_LMENU, VK_RMENU ); Mask = KeysSet( pkKT, KeyState, Vk, VK_LMENU, VK_RMENU );
if (Mask & 0xc0) if (Mask & KS_DOWN_MASK)
ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits; ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits;
if (Mask & 0x40) if (Mask & KS_EXT_BIT)
ModBits |= 0x02 /* KCTRL */; ModBits |= MOD_KCTRL;
break; break;
default: default:
Mask = KeysSet( pkKT, KeyState, Vk, 0, 0 ); Mask = KeysSet( pkKT, KeyState, Vk, 0, 0 );
if (Mask & 0x80) if (Mask & KS_DOWN_BIT)
ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits; ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits;
break; break;
} }
} }
/* Deal with VK_CAPITAL */
if (KeysSet( pkKT, KeyState, VK_CAPITAL, 0, 0 ) & KS_LOCK_BIT)
{
ModBits |= CAPITAL_BIT;
}
/* Deal with VK_NUMLOCK */
if (KeysSet( pkKT, KeyState, VK_NUMLOCK, 0, 0 ) & KS_LOCK_BIT)
{
ModBits |= NUMLOCK_BIT;
}
DPRINT( "Current Mod Bits: %x\n", ModBits ); DPRINT( "Current Mod Bits: %x\n", ModBits );
return ModBits; return ModBits;
@ -264,6 +193,10 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
PVK_TO_WCHARS10 vkPtr; PVK_TO_WCHARS10 vkPtr;
size_t size_this_entry; size_t size_this_entry;
int nMod, shift; int nMod, shift;
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 );
@ -275,7 +208,7 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++) for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
{ {
if (shift >= keyLayout->pVkToWcharTable[nMod].nModifications) if (shift > keyLayout->pVkToWcharTable[nMod].nModifications)
{ {
continue; continue;
} }
@ -284,11 +217,18 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars); vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
while(vkPtr->VirtualKey) while(vkPtr->VirtualKey)
{ {
if( wVirtKey == vkPtr->VirtualKey ) if( wVirtKey == (vkPtr->VirtualKey & 0xff) )
{ {
*pbDead = vkPtr->wch[shift] == WCH_DEAD; CapsMod =
*pbLigature = vkPtr->wch[shift] == WCH_LGTR; shift | ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0);
*pwcTranslatedChar = vkPtr->wch[shift];
*pbDead = vkPtr->wch[CapsMod] == WCH_DEAD;
*pbLigature = vkPtr->wch[CapsMod] == WCH_LGTR;
*pwcTranslatedChar = vkPtr->wch[CapsMod];
DPRINT("CapsMod %08x CapsState %08x shift %08x Char %04x\n",
CapsMod, CapsState, shift, *pwcTranslatedChar);
if( *pbDead ) if( *pbDead )
{ {
vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry); vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
@ -337,7 +277,6 @@ ToUnicodeInner(UINT wVirtKey,
return 0; return 0;
} }
/* DbgPrint( "Trans: %04x\n", wcTranslatedChar ); */
if( cchBuff > 0 ) pwszBuff[0] = wcTranslatedChar; if( cchBuff > 0 ) pwszBuff[0] = wcTranslatedChar;
return bDead ? -1 : 1; return bDead ? -1 : 1;
@ -351,15 +290,17 @@ STDCALL
NtUserGetKeyState( NtUserGetKeyState(
DWORD key) DWORD key)
{ {
DWORD ret; KIRQL OldIrql;
DWORD ret = 0;
KeAcquireSpinLock(&QueueStateLock, &OldIrql);
if( key < 0x100 ) { if( key < 0x100 ) {
ret = ((DWORD)(QueueKeyStateTable[key] & 0x80) << 8 ) | ret = ((DWORD)(QueueKeyStateTable[key] & KS_DOWN_BIT) << 8 ) |
(QueueKeyStateTable[key] & 0x80) | (QueueKeyStateTable[key] & KS_EXT_BIT) |
(QueueKeyStateTable[key] & 0x01); (QueueKeyStateTable[key] & KS_LOCK_BIT);
return ret;
} }
return 0; KeReleaseSpinLock(&QueueStateLock, OldIrql);
return ret;
} }
int STDCALL ToUnicodeEx( UINT wVirtKey, int STDCALL ToUnicodeEx( UINT wVirtKey,
@ -369,14 +310,21 @@ int STDCALL ToUnicodeEx( UINT wVirtKey,
int cchBuff, int cchBuff,
UINT wFlags, UINT wFlags,
HKL dwhkl ) { HKL dwhkl ) {
return ToUnicodeInner( wVirtKey, KIRQL OldIrql;
wScanCode, int ToUnicodeResult = 0;
lpKeyState,
pwszBuff, KeAcquireSpinLock(&QueueStateLock, &OldIrql);
cchBuff, ToUnicodeResult = ToUnicodeInner( wVirtKey,
wFlags, wScanCode,
PsGetWin32Thread() ? lpKeyState,
PsGetWin32Thread()->KeyboardLayout : 0 ); pwszBuff,
cchBuff,
wFlags,
PsGetWin32Thread() ?
PsGetWin32Thread()->KeyboardLayout : 0 );
KeReleaseSpinLock(&QueueStateLock, OldIrql);
return ToUnicodeResult;
} }
int STDCALL ToUnicode( UINT wVirtKey, int STDCALL ToUnicode( UINT wVirtKey,
@ -631,35 +579,32 @@ BOOL STDCALL
NtUserTranslateMessage(LPMSG lpMsg, NtUserTranslateMessage(LPMSG lpMsg,
HKL dwhkl) /* Used to pass the kbd layout */ HKL dwhkl) /* Used to pass the kbd layout */
{ {
KIRQL OldIrql;
static INT dead_char = 0; static INT dead_char = 0;
UINT ScanCode = 0;
LONG UState = 0; LONG UState = 0;
WCHAR wp[2] = { 0 }; WCHAR wp[2] = { 0 };
MSG NewMsg = { 0 }; MSG NewMsg = { 0 };
MSG InMsg = { 0 }; MSG InMsg = { 0 };
PUSER_MESSAGE UMsg; PUSER_MESSAGE UMsg;
PKBDTABLES keyLayout; PKBDTABLES keyLayout;
BOOL Result = FALSE;
DWORD ScanCode = 0;
if( !NT_SUCCESS(MmCopyFromCaller(&InMsg, lpMsg, sizeof(InMsg))) ) { if( !NT_SUCCESS(MmCopyFromCaller(&InMsg, lpMsg, sizeof(InMsg))) ) {
return FALSE; return FALSE;
} }
keyLayout = PsGetWin32Thread()->KeyboardLayout; keyLayout = PsGetWin32Thread()->KeyboardLayout;
if( !keyLayout ) return 0; if( !keyLayout )
return FALSE;
if (InMsg.message != WM_KEYDOWN && InMsg.message != WM_SYSKEYDOWN)
return FALSE;
ScanCode = (InMsg.lParam >> 16) & 0xff; ScanCode = (InMsg.lParam >> 16) & 0xff;
if (InMsg.message != WM_KEYDOWN && InMsg.message != WM_SYSKEYDOWN) KeAcquireSpinLock(&QueueStateLock, &OldIrql);
{
if (InMsg.message == WM_KEYUP) {
SetKeyState( ScanCode, FALSE ); /* Release key */
}
return(FALSE);
}
SetKeyState( ScanCode, TRUE ); /* Strike key */
/* Pass 2: Get Unicode Character */
UState = ToUnicodeInner(InMsg.wParam, HIWORD(InMsg.lParam) & 0xff, UState = ToUnicodeInner(InMsg.wParam, HIWORD(InMsg.lParam) & 0xff,
QueueKeyStateTable, wp, 2, 0, QueueKeyStateTable, wp, 2, 0,
keyLayout ); keyLayout );
@ -670,33 +615,42 @@ NtUserTranslateMessage(LPMSG lpMsg,
if (dead_char) if (dead_char)
{ {
ULONG i; ULONG i;
WCHAR first, second;
if (wp[0] == ' ') wp[0] = dead_char; DPRINT("PREVIOUS DEAD CHAR: %c\n", dead_char);
if (dead_char == 0xa2) dead_char = '(';
else if (dead_char == 0xa8) dead_char = '"'; for( i = 0; keyLayout->pDeadKey[i].dwBoth; i++ )
else if (dead_char == 0xb2) dead_char = ';';
else if (dead_char == 0xb4) dead_char = '\'';
else if (dead_char == 0xb7) dead_char = '<';
else if (dead_char == 0xb8) dead_char = ',';
else if (dead_char == 0xff) dead_char = '.';
for (i = 0; i < sizeof(accent_chars)/sizeof(accent_chars[0]); i++)
{ {
if ((accent_chars[i].ac_accent == dead_char) && first = keyLayout->pDeadKey[i].dwBoth >> 16;
(accent_chars[i].ac_char == wp[0])) second = keyLayout->pDeadKey[i].dwBoth;
{ if (first == dead_char && second == wp[0])
wp[0] = accent_chars[i].ac_result; {
break; wp[0] = keyLayout->pDeadKey[i].wchComposed;
} dead_char = 0;
break;
}
} }
dead_char = 0;
} DPRINT("FINAL CHAR: %c\n", wp[0]);
}
if (dead_char)
{
NewMsg.hwnd = InMsg.hwnd;
NewMsg.wParam = dead_char;
NewMsg.lParam = InMsg.lParam;
UMsg = MsqCreateMessage(&NewMsg);
dead_char = 0;
if (UMsg)
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
}
NewMsg.hwnd = InMsg.hwnd; NewMsg.hwnd = InMsg.hwnd;
NewMsg.wParam = wp[0]; NewMsg.wParam = wp[0];
NewMsg.lParam = InMsg.lParam; NewMsg.lParam = InMsg.lParam;
UMsg = MsqCreateMessage(&NewMsg); UMsg = MsqCreateMessage(&NewMsg);
DPRINT( "CHAR='%c' %04x %08x\n", wp[0], wp[0], InMsg.lParam ); DPRINT( "CHAR='%c' %04x %08x\n", wp[0], wp[0], InMsg.lParam );
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg); if (UMsg)
return(TRUE); MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
Result = TRUE;
} }
else if (UState == -1) else if (UState == -1)
{ {
@ -707,10 +661,13 @@ NtUserTranslateMessage(LPMSG lpMsg,
NewMsg.lParam = InMsg.lParam; NewMsg.lParam = InMsg.lParam;
dead_char = wp[0]; dead_char = wp[0];
UMsg = MsqCreateMessage(&NewMsg); UMsg = MsqCreateMessage(&NewMsg);
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg); if (UMsg)
return(TRUE); MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
Result = TRUE;
} }
return(FALSE);
KeReleaseSpinLock(&QueueStateLock, OldIrql);
return Result;
} }
HWND STDCALL HWND STDCALL
@ -724,11 +681,16 @@ STDCALL
NtUserGetKeyboardState( NtUserGetKeyboardState(
LPBYTE lpKeyState) LPBYTE lpKeyState)
{ {
KIRQL OldIrql;
BOOL Result = TRUE;
KeAcquireSpinLock(&QueueStateLock, &OldIrql);
if (lpKeyState) { if (lpKeyState) {
if(!NT_SUCCESS(MmCopyToCaller(lpKeyState, QueueKeyStateTable, 256))) if(!NT_SUCCESS(MmCopyToCaller(lpKeyState, QueueKeyStateTable, 256)))
return FALSE; Result = FALSE;
} }
return TRUE; KeReleaseSpinLock(&QueueStateLock, OldIrql);
return Result;
} }
DWORD DWORD
@ -736,11 +698,17 @@ STDCALL
NtUserSetKeyboardState( NtUserSetKeyboardState(
LPBYTE lpKeyState) LPBYTE lpKeyState)
{ {
if (lpKeyState) { KIRQL OldIrql;
if(! NT_SUCCESS(MmCopyFromCaller(QueueKeyStateTable, lpKeyState, 256))) BOOL Result = TRUE;
return FALSE;
} KeAcquireSpinLock(&QueueStateLock, &OldIrql);
return TRUE; if (lpKeyState) {
if(! NT_SUCCESS(MmCopyFromCaller(QueueKeyStateTable, lpKeyState, 256)))
Result = FALSE;
}
KeReleaseSpinLock(&QueueStateLock, OldIrql);
return Result;
} }
static UINT VkToScan( UINT Code, BOOL ExtCode, PKBDTABLES pkKT ) { static UINT VkToScan( UINT Code, BOOL ExtCode, PKBDTABLES pkKT ) {
@ -754,6 +722,11 @@ static UINT VkToScan( UINT Code, BOOL ExtCode, PKBDTABLES pkKT ) {
} }
UINT ScanToVk( UINT Code, BOOL ExtKey, PKBDTABLES pkKT ) { UINT ScanToVk( UINT Code, BOOL ExtKey, PKBDTABLES pkKT ) {
if( !pkKT ) {
DPRINT("ScanToVk: No layout\n");
return 0;
}
if( ExtKey ) { if( ExtKey ) {
int i; int i;
@ -792,13 +765,8 @@ UINT ScanToVk( UINT Code, BOOL ExtKey, PKBDTABLES pkKT ) {
* @implemented * @implemented
*/ */
UINT static UINT IntMapVirtualKeyEx( UINT Code, UINT Type, PKBDTABLES keyLayout ) {
STDCALL
NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl ) {
UINT ret = 0; UINT ret = 0;
PKBDTABLES keyLayout = PsGetWin32Thread()->KeyboardLayout;
if( !keyLayout ) return 0;
switch( Type ) { switch( Type ) {
case 0: case 0:
@ -811,7 +779,7 @@ NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl ) {
case 1: case 1:
ret = ret =
DontDistinguishShifts DontDistinguishShifts
(NtUserMapVirtualKeyEx( Code, 3, keyboardId, dwhkl ) ); (IntMapVirtualKeyEx( Code, 3, keyLayout ) );
break; break;
case 2: { case 2: {
@ -830,6 +798,17 @@ NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl ) {
return ret; return ret;
} }
UINT
STDCALL
NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl ) {
PKBDTABLES keyLayout = PsGetWin32Thread() ?
PsGetWin32Thread()->KeyboardLayout : 0;
if( !keyLayout ) return 0;
return IntMapVirtualKeyEx( Code, Type, keyLayout );
}
int int
STDCALL STDCALL
@ -935,7 +914,7 @@ NtUserGetKeyNameText( LONG lParam, LPWSTR lpString, int nSize ) {
if( ret == 0 ) { if( ret == 0 ) {
WCHAR UCName[2]; WCHAR UCName[2];
UCName[0] = W32kSimpleToupper(NtUserMapVirtualKeyEx( VkCode, 2, 0, 0 )); UCName[0] = W32kSimpleToupper(IntMapVirtualKeyEx( VkCode, 2, keyLayout ));
UCName[1] = 0; UCName[1] = 0;
ret = 1; ret = 1;
@ -952,12 +931,70 @@ NtUserGetKeyNameText( LONG lParam, LPWSTR lpString, int nSize ) {
*/ */
VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyboardLayout) { VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyboardLayout) {
if( !KeyboardLayout || !Msg) return; KIRQL OldIrql;
if( Msg->message != WM_KEYDOWN && Msg->message != WM_SYSKEYDOWN && DWORD ScanCode = 0, ModifierBits = 0;
Msg->message != WM_KEYUP && Msg->message != WM_SYSKEYUP ) { DWORD i = 0;
return; DWORD RawVk = 0;
} static WORD NumpadConversion[][2] =
Msg->wParam = NtUserMapVirtualKeyEx( (Msg->lParam >> 16) & 0xff, 1, 0, 0 ); { { VK_DELETE, VK_DECIMAL },
} { VK_INSERT, VK_NUMPAD0 },
{ VK_END, VK_NUMPAD1 },
{ VK_DOWN, VK_NUMPAD2 },
{ VK_NEXT, VK_NUMPAD3 },
{ VK_LEFT, VK_NUMPAD4 },
{ VK_CLEAR, VK_NUMPAD5 },
{ VK_RIGHT, VK_NUMPAD6 },
{ VK_HOME, VK_NUMPAD7 },
{ VK_UP, VK_NUMPAD8 },
{ VK_PRIOR, VK_NUMPAD9 },
{ 0,0 } };
if( !KeyboardLayout || !Msg ||
(Msg->message != WM_KEYDOWN && Msg->message != WM_SYSKEYDOWN &&
Msg->message != WM_KEYUP && Msg->message != WM_SYSKEYUP) )
{
return;
}
KeAcquireSpinLock(&QueueStateLock, &OldIrql);
/* 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);
/* Get the raw scan code, so we can look up whether the key is a numpad
* key */
ScanCode = (Msg->lParam >> 16) & 0xff;
Msg->wParam = IntMapVirtualKeyEx( ScanCode, 1, KeyboardLayout );
RawVk = KeyboardLayout->pusVSCtoVK[ScanCode];
if ((ModifierBits & NUMLOCK_BIT) && (RawVk & KNUMP))
{
/* The key in question is a numpad key. Search for a translation. */
for (i = 0; NumpadConversion[i][0]; i++)
{
if ((RawVk & 0xff) == NumpadConversion[i][0])
{
Msg->wParam = NumpadConversion[i][1];
break;
}
}
}
/* Now that we have the VK, we can set the keymap appropriately
* This is a better place for this code, as it's guaranteed to be
* run, unlike translate message. */
if (Msg->message == WM_KEYDOWN || Msg->message == WM_SYSKEYDOWN)
{
SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
TRUE ); /* Strike key */
}
else if (Msg->message == WM_KEYUP || Msg->message == WM_SYSKEYUP)
{
SetKeyState( ScanCode, Msg->wParam, Msg->lParam & LP_EXT_BIT,
FALSE ); /* Release key */
}
KeReleaseSpinLock(&QueueStateLock, OldIrql);
}
/* EOF */ /* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: message.c,v 1.35 2003/11/23 12:41:42 weiden Exp $ /* $Id: message.c,v 1.36 2003/11/24 00:22:53 arty Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -174,7 +174,6 @@ IntPeekMessage(LPMSG Msg,
{ {
MsqDestroyMessage(Message); MsqDestroyMessage(Message);
} }
W32kKeyProcessMessage(Msg,PsGetWin32Thread()->KeyboardLayout);
return TRUE; return TRUE;
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: msgqueue.c,v 1.37 2003/11/23 12:08:00 weiden Exp $ /* $Id: msgqueue.c,v 1.38 2003/11/24 00:22:53 arty Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -223,9 +223,10 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
*/ */
if (0 != Wnd && Wnd != IntGetFocusWindow()) if (0 != Wnd && Wnd != IntGetFocusWindow())
{ {
DbgPrint("Changing Focus window to 0x%X\n", Wnd); SpareLParam =
MAKELONG(WinPosWindowFromPoint(ScopeWin,
SpareLParam = MAKELONG(WinPosWindowFromPoint(ScopeWin, Message->Msg.pt, &Window), Msg); Message->Msg.pt,
&Window), Msg);
if(Window) if(Window)
{ {
@ -490,20 +491,15 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n", DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n",
uMsg, wParam, lParam); uMsg, wParam, lParam);
Msg.hwnd = 0;
Msg.message = uMsg;
Msg.wParam = wParam;
Msg.lParam = lParam;
/* FIXME: Initialize time and point. */
FocusMessageQueue = IntGetFocusMessageQueue(); FocusMessageQueue = IntGetFocusMessageQueue();
if( !IntGetScreenDC() ) { if( !IntGetScreenDC() ) {
Msg.hwnd = 0;
Msg.message = uMsg;
Msg.wParam = wParam;
Msg.lParam = lParam;
/* FIXME: Initialize time and point. */
if( W32kGetPrimitiveMessageQueue() ) { if( W32kGetPrimitiveMessageQueue() ) {
Msg.hwnd = 0;
Msg.message = uMsg;
Msg.wParam = wParam;
Msg.lParam = lParam;
/* FIXME: Initialize time and point. */
Message = MsqCreateMessage(&Msg); Message = MsqCreateMessage(&Msg);
MsqPostMessage(W32kGetPrimitiveMessageQueue(), Message); MsqPostMessage(W32kGetPrimitiveMessageQueue(), Message);
} }
@ -517,11 +513,6 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
if (FocusMessageQueue->FocusWindow != (HWND)0) if (FocusMessageQueue->FocusWindow != (HWND)0)
{ {
Msg.hwnd = FocusMessageQueue->FocusWindow; Msg.hwnd = FocusMessageQueue->FocusWindow;
Msg.message = uMsg;
Msg.wParam = wParam;
Msg.lParam = lParam;
/* FIXME: Initialize time and point. */
Message = MsqCreateMessage(&Msg); Message = MsqCreateMessage(&Msg);
MsqPostMessage(FocusMessageQueue, Message); MsqPostMessage(FocusMessageQueue, Message);
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: window.c,v 1.144 2003/11/23 12:31:53 weiden Exp $ /* $Id: window.c,v 1.145 2003/11/24 00:22:53 arty Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -842,7 +842,7 @@ IntSetFocusWindow(HWND hWnd)
hWndTop = NtUserGetAncestor(hWndTop, GA_PARENT); hWndTop = NtUserGetAncestor(hWndTop, GA_PARENT);
} }
#if 0 /* FIXME */ #if 0
/* call hooks */ /* call hooks */
if (HOOK_CallHooks(WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, TRUE)) if (HOOK_CallHooks(WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, TRUE))
{ {
@ -860,16 +860,13 @@ IntSetFocusWindow(HWND hWnd)
return NULL; return NULL;
} }
#endif #endif
#if 0 /* FIXME */
if (! NtUserIsWindow(hWnd)) if (! NtUserIsWindow(hWnd))
{ {
/* Abort if window destroyed */ /* Abort if window destroyed */
return NULL; return NULL;
} }
#endif
} }
} }
#if 0 /* FIXME */
else else
{ {
/* call hooks */ /* call hooks */
@ -879,7 +876,6 @@ IntSetFocusWindow(HWND hWnd)
return NULL; return NULL;
} }
} }
#endif
hWndOldFocus = set_focus_window(hWnd, WindowObject, hWndOldFocus); hWndOldFocus = set_focus_window(hWnd, WindowObject, hWndOldFocus);
if (WindowObject != NULL) if (WindowObject != NULL)