mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
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:
parent
108b5183a6
commit
d792147982
10 changed files with 409 additions and 338 deletions
|
@ -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
|
||||
*
|
||||
|
@ -759,7 +759,6 @@ NTSTATUS STDCALL CsrpWriteConsole( PCSRSS_SCREEN_BUFFER Buff, CHAR *Buffer, DWOR
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
inline BOOLEAN CsrpIsEqualRect(
|
||||
SMALL_RECT Rect1,
|
||||
SMALL_RECT Rect2)
|
||||
|
@ -1363,6 +1362,18 @@ static DWORD CsrpGetShiftState( PBYTE KeyState ) {
|
|||
case VK_RMENU:
|
||||
ssOut |= RIGHT_ALT_PRESSED | ENHANCED_KEY;
|
||||
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 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;
|
||||
UINT RepeatCount;
|
||||
CHAR AsciiChar;
|
||||
WCHAR UnicodeChar;
|
||||
UINT VirtualKeyCode;
|
||||
UINT VirtualScanCode;
|
||||
CHAR AsciiChar;
|
||||
DWORD ShiftState;
|
||||
BOOL Down = FALSE;
|
||||
BOOL Ext = FALSE;
|
||||
int RetChars;
|
||||
WCHAR Chars[2] = { 0 };
|
||||
INPUT_RECORD er;
|
||||
NTSTATUS Status;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
BYTE Mask;
|
||||
ULONG ResultSize;
|
||||
ULONG ResultSize = 0;
|
||||
|
||||
RepeatCount = 1;
|
||||
VirtualScanCode = (msg->lParam >> 16) & 0xff;
|
||||
VirtualKeyCode = msg->wParam;
|
||||
Down = msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN;
|
||||
Ext = msg->lParam & 0x01000000 ? TRUE : FALSE;
|
||||
Down = msg->message == WM_KEYDOWN || msg->message == WM_CHAR ||
|
||||
msg->message == WM_SYSKEYDOWN || msg->message == WM_SYSCHAR;
|
||||
|
||||
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
|
||||
{
|
||||
KeyState[VirtualScanCode] &= ~Mask;
|
||||
}
|
||||
|
||||
|
||||
ShiftState = CsrpGetShiftState( KeyState );
|
||||
|
||||
RetChars = NtUserToUnicodeEx(VirtualKeyCode,
|
||||
VirtualScanCode,
|
||||
KeyState,
|
||||
Chars,
|
||||
2,
|
||||
0,
|
||||
0);
|
||||
|
||||
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
|
||||
|
||||
|
||||
RtlUnicodeToOemN(&AsciiChar,
|
||||
1,
|
||||
&ResultSize,
|
||||
&UnicodeChar,
|
||||
2);
|
||||
if (0 == ResultSize)
|
||||
{
|
||||
AsciiChar = '\0';
|
||||
{
|
||||
WCHAR Chars[2];
|
||||
INT RetChars = 0;
|
||||
|
||||
VirtualKeyCode = msg->wParam;
|
||||
RetChars = NtUserToUnicodeEx(VirtualKeyCode,
|
||||
VirtualScanCode,
|
||||
KeyState,
|
||||
Chars,
|
||||
2,
|
||||
0,
|
||||
0);
|
||||
UnicodeChar = (1 == RetChars ? Chars[0] : 0);
|
||||
}
|
||||
|
||||
if (UnicodeChar)
|
||||
RtlUnicodeToOemN(&AsciiChar,
|
||||
1,
|
||||
&ResultSize,
|
||||
&UnicodeChar,
|
||||
sizeof(WCHAR));
|
||||
if (!ResultSize) AsciiChar = 0;
|
||||
|
||||
er.EventType = KEY_EVENT;
|
||||
er.Event.KeyEvent.bKeyDown = Down;
|
||||
er.Event.KeyEvent.wRepeatCount = RepeatCount;
|
||||
// er.Event.KeyEvent.uChar.AsciiChar = AsciiChar;
|
||||
// er.Event.KeyEvent.uChar.UnicodeChar = UnicodeChar;
|
||||
er.Event.KeyEvent.uChar.UnicodeChar = AsciiChar;
|
||||
er.Event.KeyEvent.uChar.UnicodeChar = AsciiChar & 0xff;
|
||||
er.Event.KeyEvent.dwControlKeyState = ShiftState;
|
||||
er.Event.KeyEvent.wVirtualKeyCode = VirtualKeyCode;
|
||||
er.Event.KeyEvent.wVirtualScanCode = VirtualScanCode;
|
||||
|
@ -1535,10 +1540,29 @@ CsrpProcessKey(MSG *msg, PCSRSS_CONSOLE Console)
|
|||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1559,8 +1583,9 @@ VOID Console_Api( DWORD RefreshEvent )
|
|||
NtUserGetMessage( &msg, 0,0,0 );
|
||||
NtUserTranslateMessage( &msg, 0 );
|
||||
|
||||
if (msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
|
||||
msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP) {
|
||||
if ((msg.message == WM_CHAR || msg.message == WM_SYSCHAR ||
|
||||
msg.message == WM_KEYDOWN || msg.message == WM_KEYUP ||
|
||||
msg.message == WM_SYSKEYDOWN || msg.message == WM_SYSKEYUP)) {
|
||||
CsrpProcessKey(&msg, ActiveConsole);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ typedef struct ConsoleInput_t
|
|||
INPUT_RECORD InputEvent;
|
||||
BOOLEAN Echoed; // already been echoed or not
|
||||
BOOLEAN Fake; // synthesized, not a real event
|
||||
BOOLEAN NotChar; // message should not be used to return a character
|
||||
} ConsoleInput;
|
||||
|
||||
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 CsrVerifyObject( PCSRSS_PROCESS_DATA ProcessData, HANDLE Object );
|
||||
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 );
|
||||
|
||||
#endif /* ndef _CSRSS_API_H */
|
||||
|
|
|
@ -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
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -427,6 +427,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
case WM_KEYUP:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_CHAR:
|
||||
GuiConsoleHandleKey(hWnd, msg, wParam, lParam);
|
||||
Result = 0;
|
||||
break;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
NTSTATUS FASTCALL
|
||||
InitInputImpl(VOID);
|
||||
NTSTATUS FASTCALL
|
||||
InitKeyboardImpl(VOID);
|
||||
PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue(VOID);
|
||||
PKBDTABLES W32kGetDefaultKeyLayout(VOID);
|
||||
VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyLayout);
|
||||
|
|
|
@ -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: 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
|
||||
*/
|
||||
|
@ -245,6 +245,13 @@ DllMain (
|
|||
return(Status);
|
||||
}
|
||||
|
||||
Status = InitKeyboardImpl();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DbgPrint("Failed to initialize keyboard implementation.\n");
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Status = MsqInitializeImpl();
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
|
|
@ -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.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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -63,7 +63,10 @@ KeyboardThreadMain(PVOID StartContext)
|
|||
OBJECT_ATTRIBUTES KeyboardObjectAttributes;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
NTSTATUS Status;
|
||||
|
||||
MSG msg;
|
||||
PUSER_MESSAGE_QUEUE FocusQueue;
|
||||
struct _ETHREAD *FocusThread;
|
||||
|
||||
RtlRosInitUnicodeStringFromLiteral(&KeyboardDeviceName, L"\\??\\Keyboard");
|
||||
InitializeObjectAttributes(&KeyboardObjectAttributes,
|
||||
&KeyboardDeviceName,
|
||||
|
@ -144,9 +147,55 @@ KeyboardThreadMain(PVOID StartContext)
|
|||
|
||||
/* 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,
|
||||
fsModifiers,
|
||||
KeyEvent.wVirtualKeyCode,
|
||||
fsModifiers,
|
||||
msg.wParam,
|
||||
&Thread,
|
||||
&hWnd,
|
||||
&id))
|
||||
|
@ -157,55 +206,16 @@ KeyboardThreadMain(PVOID StartContext)
|
|||
MsqPostHotKeyMessage (Thread,
|
||||
hWnd,
|
||||
(WPARAM)id,
|
||||
MAKELPARAM((WORD)fsModifiers, (WORD)KeyEvent.wVirtualKeyCode));
|
||||
MAKELPARAM((WORD)fsModifiers,
|
||||
(WORD)msg.wParam));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
/*
|
||||
* Post a keyboard message.
|
||||
*/
|
||||
if (KeyEvent.bKeyDown)
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
/*
|
||||
* Post a keyboard message.
|
||||
*/
|
||||
MsqPostKeyboardMessage(msg.message,msg.wParam,msg.lParam);
|
||||
}
|
||||
}
|
||||
DbgPrint( "Input Thread Stopped...\n" );
|
||||
|
|
|
@ -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.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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -44,131 +44,37 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* Directory to load key layouts from */
|
||||
#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];
|
||||
|
||||
/* 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 *****************************************************************/
|
||||
|
||||
/* 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 ***/
|
||||
|
||||
static UINT DontDistinguishShifts( UINT ret ) {
|
||||
|
@ -178,8 +84,17 @@ static UINT DontDistinguishShifts( UINT ret ) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static VOID STDCALL SetKeyState(DWORD key, BOOL down) {
|
||||
QueueKeyStateTable[key] = down ? 0x80 : 0;
|
||||
static VOID STDCALL SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down) {
|
||||
/* 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 ) {
|
||||
|
@ -195,14 +110,16 @@ VOID DumpKeyState( PBYTE KeyState ) {
|
|||
static BYTE KeysSet( PKBDTABLES pkKT, PBYTE KeyState,
|
||||
int Mod, int FakeModLeft, int FakeModRight ) {
|
||||
int i;
|
||||
UINT Vk = 0;
|
||||
|
||||
if( !KeyState || !pkKT ) return 0;
|
||||
|
||||
for( i = 0; i < pkKT->bMaxVSCtoVK; i++ ) {
|
||||
if( KeyState[i] & 0xC0 &&
|
||||
((pkKT->pusVSCtoVK[i] & 0xff) == Mod ||
|
||||
(pkKT->pusVSCtoVK[i] & 0xff) == FakeModLeft ||
|
||||
(pkKT->pusVSCtoVK[i] & 0xff) == FakeModRight ) ) {
|
||||
Vk = pkKT->pusVSCtoVK[i] & 0xff;
|
||||
if( KeyState[i] &&
|
||||
((Vk == Mod) ||
|
||||
(FakeModLeft && Vk == FakeModLeft) ||
|
||||
(FakeModRight && Vk == FakeModRight)) ) {
|
||||
return KeyState[i];
|
||||
}
|
||||
}
|
||||
|
@ -225,29 +142,41 @@ static DWORD ModBits( PKBDTABLES pkKT, PBYTE KeyState ) {
|
|||
{
|
||||
case VK_SHIFT:
|
||||
Mask = KeysSet( pkKT, KeyState, Vk, VK_LSHIFT, VK_RSHIFT );
|
||||
if (Mask & 0xc0)
|
||||
if (Mask & KS_DOWN_MASK)
|
||||
ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits;
|
||||
break;
|
||||
case VK_CONTROL:
|
||||
Mask = KeysSet( pkKT, KeyState, Vk, VK_LCONTROL, VK_RCONTROL );
|
||||
if (Mask & 0xc0)
|
||||
if (Mask & KS_DOWN_MASK)
|
||||
ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits;
|
||||
break;
|
||||
case VK_MENU:
|
||||
Mask = KeysSet( pkKT, KeyState, Vk, VK_LMENU, VK_RMENU );
|
||||
if (Mask & 0xc0)
|
||||
if (Mask & KS_DOWN_MASK)
|
||||
ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits;
|
||||
if (Mask & 0x40)
|
||||
ModBits |= 0x02 /* KCTRL */;
|
||||
if (Mask & KS_EXT_BIT)
|
||||
ModBits |= MOD_KCTRL;
|
||||
break;
|
||||
default:
|
||||
Mask = KeysSet( pkKT, KeyState, Vk, 0, 0 );
|
||||
if (Mask & 0x80)
|
||||
if (Mask & KS_DOWN_BIT)
|
||||
ModBits |= pkKT->pCharModifiers->pVkToBit[i].ModBits;
|
||||
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 );
|
||||
|
||||
return ModBits;
|
||||
|
@ -264,6 +193,10 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
|
|||
PVK_TO_WCHARS10 vkPtr;
|
||||
size_t size_this_entry;
|
||||
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 );
|
||||
|
||||
|
@ -275,7 +208,7 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
|
|||
|
||||
for (nMod = 0; keyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
|
||||
{
|
||||
if (shift >= keyLayout->pVkToWcharTable[nMod].nModifications)
|
||||
if (shift > keyLayout->pVkToWcharTable[nMod].nModifications)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -284,11 +217,18 @@ static BOOL TryToTranslateChar(WORD wVirtKey,
|
|||
vkPtr = (PVK_TO_WCHARS10)((BYTE *)vtwTbl->pVkToWchars);
|
||||
while(vkPtr->VirtualKey)
|
||||
{
|
||||
if( wVirtKey == vkPtr->VirtualKey )
|
||||
if( wVirtKey == (vkPtr->VirtualKey & 0xff) )
|
||||
{
|
||||
*pbDead = vkPtr->wch[shift] == WCH_DEAD;
|
||||
*pbLigature = vkPtr->wch[shift] == WCH_LGTR;
|
||||
*pwcTranslatedChar = vkPtr->wch[shift];
|
||||
CapsMod =
|
||||
shift | ((CapsState & CAPITAL_BIT) ? vkPtr->Attributes : 0);
|
||||
|
||||
*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 )
|
||||
{
|
||||
vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
|
||||
|
@ -337,7 +277,6 @@ ToUnicodeInner(UINT wVirtKey,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* DbgPrint( "Trans: %04x\n", wcTranslatedChar ); */
|
||||
if( cchBuff > 0 ) pwszBuff[0] = wcTranslatedChar;
|
||||
|
||||
return bDead ? -1 : 1;
|
||||
|
@ -351,15 +290,17 @@ STDCALL
|
|||
NtUserGetKeyState(
|
||||
DWORD key)
|
||||
{
|
||||
DWORD ret;
|
||||
KIRQL OldIrql;
|
||||
DWORD ret = 0;
|
||||
|
||||
KeAcquireSpinLock(&QueueStateLock, &OldIrql);
|
||||
if( key < 0x100 ) {
|
||||
ret = ((DWORD)(QueueKeyStateTable[key] & 0x80) << 8 ) |
|
||||
(QueueKeyStateTable[key] & 0x80) |
|
||||
(QueueKeyStateTable[key] & 0x01);
|
||||
return ret;
|
||||
ret = ((DWORD)(QueueKeyStateTable[key] & KS_DOWN_BIT) << 8 ) |
|
||||
(QueueKeyStateTable[key] & KS_EXT_BIT) |
|
||||
(QueueKeyStateTable[key] & KS_LOCK_BIT);
|
||||
}
|
||||
return 0;
|
||||
KeReleaseSpinLock(&QueueStateLock, OldIrql);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int STDCALL ToUnicodeEx( UINT wVirtKey,
|
||||
|
@ -369,14 +310,21 @@ int STDCALL ToUnicodeEx( UINT wVirtKey,
|
|||
int cchBuff,
|
||||
UINT wFlags,
|
||||
HKL dwhkl ) {
|
||||
return ToUnicodeInner( wVirtKey,
|
||||
wScanCode,
|
||||
lpKeyState,
|
||||
pwszBuff,
|
||||
cchBuff,
|
||||
wFlags,
|
||||
PsGetWin32Thread() ?
|
||||
PsGetWin32Thread()->KeyboardLayout : 0 );
|
||||
KIRQL OldIrql;
|
||||
int ToUnicodeResult = 0;
|
||||
|
||||
KeAcquireSpinLock(&QueueStateLock, &OldIrql);
|
||||
ToUnicodeResult = ToUnicodeInner( wVirtKey,
|
||||
wScanCode,
|
||||
lpKeyState,
|
||||
pwszBuff,
|
||||
cchBuff,
|
||||
wFlags,
|
||||
PsGetWin32Thread() ?
|
||||
PsGetWin32Thread()->KeyboardLayout : 0 );
|
||||
KeReleaseSpinLock(&QueueStateLock, OldIrql);
|
||||
|
||||
return ToUnicodeResult;
|
||||
}
|
||||
|
||||
int STDCALL ToUnicode( UINT wVirtKey,
|
||||
|
@ -631,35 +579,32 @@ BOOL STDCALL
|
|||
NtUserTranslateMessage(LPMSG lpMsg,
|
||||
HKL dwhkl) /* Used to pass the kbd layout */
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
static INT dead_char = 0;
|
||||
UINT ScanCode = 0;
|
||||
LONG UState = 0;
|
||||
WCHAR wp[2] = { 0 };
|
||||
MSG NewMsg = { 0 };
|
||||
MSG InMsg = { 0 };
|
||||
PUSER_MESSAGE UMsg;
|
||||
PKBDTABLES keyLayout;
|
||||
BOOL Result = FALSE;
|
||||
DWORD ScanCode = 0;
|
||||
|
||||
if( !NT_SUCCESS(MmCopyFromCaller(&InMsg, lpMsg, sizeof(InMsg))) ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (InMsg.message != WM_KEYDOWN && InMsg.message != WM_SYSKEYDOWN)
|
||||
{
|
||||
if (InMsg.message == WM_KEYUP) {
|
||||
SetKeyState( ScanCode, FALSE ); /* Release key */
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
KeAcquireSpinLock(&QueueStateLock, &OldIrql);
|
||||
|
||||
SetKeyState( ScanCode, TRUE ); /* Strike key */
|
||||
|
||||
/* Pass 2: Get Unicode Character */
|
||||
UState = ToUnicodeInner(InMsg.wParam, HIWORD(InMsg.lParam) & 0xff,
|
||||
QueueKeyStateTable, wp, 2, 0,
|
||||
keyLayout );
|
||||
|
@ -670,33 +615,42 @@ NtUserTranslateMessage(LPMSG lpMsg,
|
|||
if (dead_char)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
if (wp[0] == ' ') wp[0] = dead_char;
|
||||
if (dead_char == 0xa2) dead_char = '(';
|
||||
else if (dead_char == 0xa8) dead_char = '"';
|
||||
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++)
|
||||
WCHAR first, second;
|
||||
DPRINT("PREVIOUS DEAD CHAR: %c\n", dead_char);
|
||||
|
||||
for( i = 0; keyLayout->pDeadKey[i].dwBoth; i++ )
|
||||
{
|
||||
if ((accent_chars[i].ac_accent == dead_char) &&
|
||||
(accent_chars[i].ac_char == wp[0]))
|
||||
{
|
||||
wp[0] = accent_chars[i].ac_result;
|
||||
break;
|
||||
}
|
||||
first = keyLayout->pDeadKey[i].dwBoth >> 16;
|
||||
second = keyLayout->pDeadKey[i].dwBoth;
|
||||
if (first == dead_char && second == wp[0])
|
||||
{
|
||||
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.wParam = wp[0];
|
||||
NewMsg.lParam = InMsg.lParam;
|
||||
UMsg = MsqCreateMessage(&NewMsg);
|
||||
DPRINT( "CHAR='%c' %04x %08x\n", wp[0], wp[0], InMsg.lParam );
|
||||
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
|
||||
return(TRUE);
|
||||
if (UMsg)
|
||||
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
|
||||
Result = TRUE;
|
||||
}
|
||||
else if (UState == -1)
|
||||
{
|
||||
|
@ -707,10 +661,13 @@ NtUserTranslateMessage(LPMSG lpMsg,
|
|||
NewMsg.lParam = InMsg.lParam;
|
||||
dead_char = wp[0];
|
||||
UMsg = MsqCreateMessage(&NewMsg);
|
||||
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
|
||||
return(TRUE);
|
||||
if (UMsg)
|
||||
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
|
||||
Result = TRUE;
|
||||
}
|
||||
return(FALSE);
|
||||
|
||||
KeReleaseSpinLock(&QueueStateLock, OldIrql);
|
||||
return Result;
|
||||
}
|
||||
|
||||
HWND STDCALL
|
||||
|
@ -724,11 +681,16 @@ STDCALL
|
|||
NtUserGetKeyboardState(
|
||||
LPBYTE lpKeyState)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
BOOL Result = TRUE;
|
||||
|
||||
KeAcquireSpinLock(&QueueStateLock, &OldIrql);
|
||||
if (lpKeyState) {
|
||||
if(!NT_SUCCESS(MmCopyToCaller(lpKeyState, QueueKeyStateTable, 256)))
|
||||
return FALSE;
|
||||
Result = FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
KeReleaseSpinLock(&QueueStateLock, OldIrql);
|
||||
return Result;
|
||||
}
|
||||
|
||||
DWORD
|
||||
|
@ -736,11 +698,17 @@ STDCALL
|
|||
NtUserSetKeyboardState(
|
||||
LPBYTE lpKeyState)
|
||||
{
|
||||
if (lpKeyState) {
|
||||
if(! NT_SUCCESS(MmCopyFromCaller(QueueKeyStateTable, lpKeyState, 256)))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
KIRQL OldIrql;
|
||||
BOOL Result = TRUE;
|
||||
|
||||
KeAcquireSpinLock(&QueueStateLock, &OldIrql);
|
||||
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 ) {
|
||||
|
@ -754,6 +722,11 @@ static UINT VkToScan( UINT Code, BOOL ExtCode, PKBDTABLES pkKT ) {
|
|||
}
|
||||
|
||||
UINT ScanToVk( UINT Code, BOOL ExtKey, PKBDTABLES pkKT ) {
|
||||
if( !pkKT ) {
|
||||
DPRINT("ScanToVk: No layout\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( ExtKey ) {
|
||||
int i;
|
||||
|
||||
|
@ -792,13 +765,8 @@ UINT ScanToVk( UINT Code, BOOL ExtKey, PKBDTABLES pkKT ) {
|
|||
* @implemented
|
||||
*/
|
||||
|
||||
UINT
|
||||
STDCALL
|
||||
NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl ) {
|
||||
static UINT IntMapVirtualKeyEx( UINT Code, UINT Type, PKBDTABLES keyLayout ) {
|
||||
UINT ret = 0;
|
||||
PKBDTABLES keyLayout = PsGetWin32Thread()->KeyboardLayout;
|
||||
|
||||
if( !keyLayout ) return 0;
|
||||
|
||||
switch( Type ) {
|
||||
case 0:
|
||||
|
@ -811,7 +779,7 @@ NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl ) {
|
|||
case 1:
|
||||
ret =
|
||||
DontDistinguishShifts
|
||||
(NtUserMapVirtualKeyEx( Code, 3, keyboardId, dwhkl ) );
|
||||
(IntMapVirtualKeyEx( Code, 3, keyLayout ) );
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
|
@ -830,6 +798,17 @@ NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl ) {
|
|||
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
|
||||
STDCALL
|
||||
|
@ -935,7 +914,7 @@ NtUserGetKeyNameText( LONG lParam, LPWSTR lpString, int nSize ) {
|
|||
if( ret == 0 ) {
|
||||
WCHAR UCName[2];
|
||||
|
||||
UCName[0] = W32kSimpleToupper(NtUserMapVirtualKeyEx( VkCode, 2, 0, 0 ));
|
||||
UCName[0] = W32kSimpleToupper(IntMapVirtualKeyEx( VkCode, 2, keyLayout ));
|
||||
UCName[1] = 0;
|
||||
ret = 1;
|
||||
|
||||
|
@ -952,12 +931,70 @@ NtUserGetKeyNameText( LONG lParam, LPWSTR lpString, int nSize ) {
|
|||
*/
|
||||
|
||||
VOID FASTCALL W32kKeyProcessMessage(LPMSG Msg, PKBDTABLES KeyboardLayout) {
|
||||
if( !KeyboardLayout || !Msg) return;
|
||||
if( Msg->message != WM_KEYDOWN && Msg->message != WM_SYSKEYDOWN &&
|
||||
Msg->message != WM_KEYUP && Msg->message != WM_SYSKEYUP ) {
|
||||
return;
|
||||
}
|
||||
Msg->wParam = NtUserMapVirtualKeyEx( (Msg->lParam >> 16) & 0xff, 1, 0, 0 );
|
||||
}
|
||||
KIRQL OldIrql;
|
||||
DWORD ScanCode = 0, ModifierBits = 0;
|
||||
DWORD i = 0;
|
||||
DWORD RawVk = 0;
|
||||
static WORD NumpadConversion[][2] =
|
||||
{ { 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 */
|
||||
|
|
|
@ -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: 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -174,7 +174,6 @@ IntPeekMessage(LPMSG Msg,
|
|||
{
|
||||
MsqDestroyMessage(Message);
|
||||
}
|
||||
W32kKeyProcessMessage(Msg,PsGetWin32Thread()->KeyboardLayout);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -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: 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -223,9 +223,10 @@ MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
|
|||
*/
|
||||
if (0 != Wnd && Wnd != IntGetFocusWindow())
|
||||
{
|
||||
DbgPrint("Changing Focus window to 0x%X\n", Wnd);
|
||||
|
||||
SpareLParam = MAKELONG(WinPosWindowFromPoint(ScopeWin, Message->Msg.pt, &Window), Msg);
|
||||
SpareLParam =
|
||||
MAKELONG(WinPosWindowFromPoint(ScopeWin,
|
||||
Message->Msg.pt,
|
||||
&Window), Msg);
|
||||
|
||||
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",
|
||||
uMsg, wParam, lParam);
|
||||
|
||||
Msg.hwnd = 0;
|
||||
Msg.message = uMsg;
|
||||
Msg.wParam = wParam;
|
||||
Msg.lParam = lParam;
|
||||
/* FIXME: Initialize time and point. */
|
||||
|
||||
FocusMessageQueue = IntGetFocusMessageQueue();
|
||||
if( !IntGetScreenDC() ) {
|
||||
Msg.hwnd = 0;
|
||||
Msg.message = uMsg;
|
||||
Msg.wParam = wParam;
|
||||
Msg.lParam = lParam;
|
||||
/* FIXME: Initialize time and point. */
|
||||
|
||||
if( W32kGetPrimitiveMessageQueue() ) {
|
||||
Msg.hwnd = 0;
|
||||
Msg.message = uMsg;
|
||||
Msg.wParam = wParam;
|
||||
Msg.lParam = lParam;
|
||||
/* FIXME: Initialize time and point. */
|
||||
Message = MsqCreateMessage(&Msg);
|
||||
MsqPostMessage(W32kGetPrimitiveMessageQueue(), Message);
|
||||
}
|
||||
|
@ -517,11 +513,6 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|||
if (FocusMessageQueue->FocusWindow != (HWND)0)
|
||||
{
|
||||
Msg.hwnd = FocusMessageQueue->FocusWindow;
|
||||
Msg.message = uMsg;
|
||||
Msg.wParam = wParam;
|
||||
Msg.lParam = lParam;
|
||||
/* FIXME: Initialize time and point. */
|
||||
|
||||
Message = MsqCreateMessage(&Msg);
|
||||
MsqPostMessage(FocusMessageQueue, Message);
|
||||
}
|
||||
|
|
|
@ -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: 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -842,7 +842,7 @@ IntSetFocusWindow(HWND hWnd)
|
|||
hWndTop = NtUserGetAncestor(hWndTop, GA_PARENT);
|
||||
}
|
||||
|
||||
#if 0 /* FIXME */
|
||||
#if 0
|
||||
/* call hooks */
|
||||
if (HOOK_CallHooks(WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, TRUE))
|
||||
{
|
||||
|
@ -860,16 +860,13 @@ IntSetFocusWindow(HWND hWnd)
|
|||
return NULL;
|
||||
}
|
||||
#endif
|
||||
#if 0 /* FIXME */
|
||||
if (! NtUserIsWindow(hWnd))
|
||||
{
|
||||
/* Abort if window destroyed */
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if 0 /* FIXME */
|
||||
else
|
||||
{
|
||||
/* call hooks */
|
||||
|
@ -879,7 +876,6 @@ IntSetFocusWindow(HWND hWnd)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
hWndOldFocus = set_focus_window(hWnd, WindowObject, hWndOldFocus);
|
||||
if (WindowObject != NULL)
|
||||
|
|
Loading…
Reference in a new issue