Implementation of KEYBOARD.DRV (code mostly taken from previous

windows/keyboard.c).
This commit is contained in:
Ulrich Weigand 1998-11-08 12:19:23 +00:00 committed by Alexandre Julliard
parent e8b02745e3
commit d1b919c7e4
3 changed files with 149 additions and 705 deletions

View File

@ -1,9 +1,9 @@
name keyboard name keyboard
type win16 type win16
1 pascal16 Inquire(ptr) KeyboardInquire 1 pascal16 Inquire(ptr) KEYBOARD_Inquire
2 pascal16 Enable(segptr ptr) KeyboardEnable 2 pascal16 Enable(segptr ptr) THUNK_KEYBOARD_Enable
3 pascal16 Disable() KeyboardDisable 3 pascal16 Disable() KEYBOARD_Disable
4 pascal16 ToAscii(word word ptr ptr word) ToAscii16 4 pascal16 ToAscii(word word ptr ptr word) ToAscii16
5 pascal16 AnsiToOem(str ptr) AnsiToOem16 5 pascal16 AnsiToOem(str ptr) AnsiToOem16
6 pascal16 OemToAnsi(str ptr) OemToAnsi16 6 pascal16 OemToAnsi(str ptr) OemToAnsi16

View File

@ -1,20 +1,44 @@
/* /*
* Keyboard header file * KEYBOARD driver interface
* Copyright 1997 David Faure
* *
* Copyright 1998 Ulrich Weigand
*/ */
#ifndef __WINE_KEYBOARD_H #ifndef __WINE_KEYBOARD_H
#define __WINE_KEYBOARD_H #define __WINE_KEYBOARD_H
extern BOOL32 MouseButtonsStates[3]; #pragma pack(1)
extern BOOL32 AsyncMouseButtonsStates[3]; typedef struct _KBINFO
extern BYTE InputKeyStateTable[256]; {
extern BYTE QueueKeyStateTable[256]; BYTE Begin_First_Range;
extern BYTE AsyncKeyStateTable[256]; BYTE End_First_Range;
BYTE Begin_Second_Range;
BYTE End_Second_Range;
WORD StateSize;
} KBINFO, *LPKBINFO;
#pragma pack(4)
typedef VOID (CALLBACK *LPKEYBD_EVENT_PROC)(BYTE,BYTE,DWORD,DWORD);
WORD WINAPI KEYBOARD_Inquire(LPKBINFO kbInfo);
VOID WINAPI KEYBOARD_Enable(LPKEYBD_EVENT_PROC lpKeybEventProc,
LPBYTE lpKeyState);
VOID WINAPI KEYBOARD_Disable(VOID);
/* Wine internals */
extern BOOL32 KEYBOARD_Init(void);
extern void KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event ); extern void KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event );
extern void KEYBOARD_UpdateState( void ); extern void KEYBOARD_UpdateState( void );
#endif /* __WINE_KEYBOARD_H */ #define WINE_KEYBDEVENT_MAGIC ( ('K'<<24)|('E'<<16)|('Y'<<8)|'B' )
typedef struct _WINE_KEYBDEVENT
{
DWORD magic;
DWORD posX;
DWORD posY;
DWORD time;
} WINE_KEYBDEVENT;
#endif /* __WINE_KEYBOARD_H */

View File

@ -1,10 +1,11 @@
/* /*
* Keyboard related functions * KEYBOARD driver
* *
* Copyright 1993 Bob Amstadt * Copyright 1993 Bob Amstadt
* Copyright 1996 Albrecht Kleine * Copyright 1996 Albrecht Kleine
* Copyright 1997 David Faure * Copyright 1997 David Faure
* Copyright 1998 Morten Welinder * Copyright 1998 Morten Welinder
* Copyright 1998 Ulrich Weigand
* *
*/ */
@ -28,11 +29,8 @@
#include "struct32.h" #include "struct32.h"
#include "winerror.h" #include "winerror.h"
BOOL32 MouseButtonsStates[3]; static LPKEYBD_EVENT_PROC DefKeybEventProc = NULL;
BOOL32 AsyncMouseButtonsStates[3]; static LPBYTE pKeyStateTable = NULL;
BYTE InputKeyStateTable[256];
BYTE QueueKeyStateTable[256];
BYTE AsyncKeyStateTable[256];
int min_keycode, max_keycode, keysyms_per_keycode; int min_keycode, max_keycode, keysyms_per_keycode;
WORD keyc2vkey[256]; WORD keyc2vkey[256];
@ -40,22 +38,6 @@ WORD keyc2vkey[256];
static int NumLockMask, AltGrMask; /* mask in the XKeyEvent state */ static int NumLockMask, AltGrMask; /* mask in the XKeyEvent state */
static int kcControl, kcAlt, kcShift, kcNumLock, kcCapsLock; /* keycodes */ static int kcControl, kcAlt, kcShift, kcNumLock, kcCapsLock; /* keycodes */
typedef union
{
struct
{
unsigned long count : 16;
unsigned long code : 8;
unsigned long extended : 1;
unsigned long unused : 2;
unsigned long win_internal : 2;
unsigned long context : 1;
unsigned long previous : 1;
unsigned long transition : 1;
} lp1;
unsigned long lp2;
} KEYLP;
/* Keyboard translation tables */ /* Keyboard translation tables */
static const int special_key[] = static const int special_key[] =
{ {
@ -122,7 +104,7 @@ static WORD EVENT_event_to_vkey( XKeyEvent *e)
/********************************************************************** /**********************************************************************
* KEYBOARD_Init * KEYBOARD_Init
*/ */
BOOL32 KEYBOARD_Init(void) static void KEYBOARD_Init(void)
{ {
int i; int i;
KeySym *ksp; KeySym *ksp;
@ -294,13 +276,70 @@ BOOL32 KEYBOARD_Init(void)
kcShift = TSXKeysymToKeycode(display, XK_Shift_L); kcShift = TSXKeysymToKeycode(display, XK_Shift_L);
kcNumLock = TSXKeysymToKeycode(display, XK_Num_Lock); kcNumLock = TSXKeysymToKeycode(display, XK_Num_Lock);
kcCapsLock = TSXKeysymToKeycode(display, XK_Caps_Lock); kcCapsLock = TSXKeysymToKeycode(display, XK_Caps_Lock);
}
/***********************************************************************
* KEYBOARD_Inquire (KEYBOARD.1)
*/
WORD WINAPI KEYBOARD_Inquire(LPKBINFO kbInfo)
{
kbInfo->Begin_First_Range = 0;
kbInfo->End_First_Range = 0;
kbInfo->Begin_Second_Range = 0;
kbInfo->End_Second_Range = 0;
kbInfo->StateSize = 16;
return sizeof(KBINFO);
}
/***********************************************************************
* KEYBOARD_Enable (KEYBOARD.2)
*/
VOID WINAPI KEYBOARD_Enable( LPKEYBD_EVENT_PROC lpKeybEventProc,
LPBYTE lpKeyState )
{
static BOOL32 initDone = FALSE;
DefKeybEventProc = lpKeybEventProc;
pKeyStateTable = lpKeyState;
/* all states to false */ /* all states to false */
memset( InputKeyStateTable, 0, sizeof(InputKeyStateTable) ); memset( lpKeyState, 0, sizeof(lpKeyState) );
return TRUE; if (!initDone) KEYBOARD_Init();
initDone = TRUE;
} }
/***********************************************************************
* KEYBOARD_Disable (KEYBOARD.3)
*/
VOID WINAPI KEYBOARD_Disable(VOID)
{
DefKeybEventProc = NULL;
pKeyStateTable = NULL;
}
/***********************************************************************
* KEYBOARD_SendEvent
*/
void KEYBOARD_SendEvent( BYTE bVk, BYTE bScan, DWORD dwFlags,
DWORD posX, DWORD posY, DWORD time )
{
WINE_KEYBDEVENT wke;
if ( !DefKeybEventProc ) return;
TRACE( event, "(%d,%d,%04lX)\n", bVk, bScan, dwFlags );
wke.magic = WINE_KEYBDEVENT_MAGIC;
wke.posX = posX;
wke.posY = posY;
wke.time = time;
DefKeybEventProc( bVk, bScan, dwFlags, (DWORD)&wke );
}
static BOOL32 NumState=FALSE, CapsState=FALSE; static BOOL32 NumState=FALSE, CapsState=FALSE;
/********************************************************************** /**********************************************************************
@ -312,7 +351,7 @@ static BOOL32 NumState=FALSE, CapsState=FALSE;
* *
*/ */
void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, INT32 event_x, INT32 event_y, void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, INT32 event_x, INT32 event_y,
DWORD event_time, KEYLP localkeylp ) DWORD event_time )
{ {
BOOL32 * State = (vkey==VK_NUMLOCK? &NumState : &CapsState); BOOL32 * State = (vkey==VK_NUMLOCK? &NumState : &CapsState);
@ -321,36 +360,32 @@ void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, INT32 event_x, INT32 event_y,
don't treat it. It's from the same key press. Then the state goes to ON. don't treat it. It's from the same key press. Then the state goes to ON.
And from there, a 'release' event will switch off the toggle key. */ And from there, a 'release' event will switch off the toggle key. */
*State=FALSE; *State=FALSE;
TRACE(keyboard,"INTERM : don\'t treat release of toggle key. InputKeyStateTable[%#x] = %#x\n",vkey,InputKeyStateTable[vkey]); TRACE(keyboard,"INTERM : don\'t treat release of toggle key. InputKeyStateTable[%#x] = %#x\n",vkey,pKeyStateTable[vkey]);
} else } else
{ {
if ( InputKeyStateTable[vkey] & 0x1 ) /* it was ON */ if ( pKeyStateTable[vkey] & 0x1 ) /* it was ON */
{ {
if (Evtype!=KeyPress) if (Evtype!=KeyPress)
{ {
TRACE(keyboard,"ON + KeyRelease => generating DOWN and UP messages.\n"); TRACE(keyboard,"ON + KeyRelease => generating DOWN and UP messages.\n");
localkeylp.lp1.previous = 0; /* ? */ KEYBOARD_SendEvent( vkey, 0, 0,
localkeylp.lp1.transition = 0; event_x, event_y, event_time );
hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2, KEYBOARD_SendEvent( vkey, 0, KEYEVENTF_KEYUP,
event_x, event_y, event_time, 0 ); event_x, event_y, event_time );
hardware_event( WM_KEYUP, vkey, localkeylp.lp2,
event_x, event_y, event_time, 0 );
*State=FALSE; *State=FALSE;
InputKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */ pKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */
} }
} }
else /* it was OFF */ else /* it was OFF */
if (Evtype==KeyPress) if (Evtype==KeyPress)
{ {
TRACE(keyboard,"OFF + Keypress => generating DOWN and UP messages.\n"); TRACE(keyboard,"OFF + Keypress => generating DOWN and UP messages.\n");
hardware_event( WM_KEYDOWN, vkey, localkeylp.lp2, KEYBOARD_SendEvent( vkey, 0, 0,
event_x, event_y, event_time, 0 ); event_x, event_y, event_time );
localkeylp.lp1.previous = 1; KEYBOARD_SendEvent( vkey, 0, KEYEVENTF_KEYUP,
localkeylp.lp1.transition = 1; event_x, event_y, event_time );
hardware_event( WM_KEYUP, vkey, localkeylp.lp2,
event_x, event_y, event_time, 0 );
*State=TRUE; /* Goes to intermediary state before going to ON */ *State=TRUE; /* Goes to intermediary state before going to ON */
InputKeyStateTable[vkey] |= 0x01; /* Toggle state to on. */ pKeyStateTable[vkey] |= 0x01; /* Toggle state to on. */
} }
} }
} }
@ -361,33 +396,19 @@ void KEYBOARD_GenerateMsg( WORD vkey, int Evtype, INT32 event_x, INT32 event_y,
* Updates internal state for <vkey>, depending on key <state> under X * Updates internal state for <vkey>, depending on key <state> under X
* *
*/ */
void KEYBOARD_UpdateOneState ( int vkey, int state, KEYLP keylp) void KEYBOARD_UpdateOneState ( int vkey, int state )
{ {
WORD message;
/* Do something if internal table state != X state for keycode */ /* Do something if internal table state != X state for keycode */
if (((InputKeyStateTable[vkey] & 0x80)!=0) != state) if (((pKeyStateTable[vkey] & 0x80)!=0) != state)
{ {
TRACE(keyboard,"Adjusting state for vkey %#.2x. State before %#.2x \n", TRACE(keyboard,"Adjusting state for vkey %#.2x. State before %#.2x \n",
vkey, InputKeyStateTable[vkey]); vkey, pKeyStateTable[vkey]);
keylp.lp1.previous = !state; /* 1 if state = 0, 0 if state = 1 */
keylp.lp1.transition = !state;
if (state) { /* Fake key being pressed inside wine */
InputKeyStateTable[vkey] ^= 0x01;
InputKeyStateTable[vkey] |= 0x80;
message = (InputKeyStateTable[VK_MENU] & 0x80)
&& !(InputKeyStateTable[VK_CONTROL] & 0x80)
? WM_SYSKEYDOWN : WM_KEYDOWN;
} else {
InputKeyStateTable[vkey] &= ~0x80;
message = (InputKeyStateTable[VK_MENU] & 0x80)
&& !(InputKeyStateTable[VK_CONTROL] & 0x80)
? WM_SYSKEYUP : WM_KEYUP;
}
hardware_event( message, vkey, keylp.lp2, 0, 0,
GetTickCount() + MSG_WineStartTicks, 0 );
TRACE(keyboard,"State after %#.2x \n",InputKeyStateTable[vkey]); /* Fake key being pressed inside wine */
KEYBOARD_SendEvent( vkey, 0, state? 0 : KEYEVENTF_KEYUP,
0, 0, GetTickCount() );
TRACE(keyboard,"State after %#.2x \n",pKeyStateTable[vkey]);
} }
} }
@ -408,7 +429,6 @@ void KEYBOARD_UpdateState ( void )
#define KeyState(keycode) ((keys_return[keycode/8] & (1<<(keycode%8)))!=0) #define KeyState(keycode) ((keys_return[keycode/8] & (1<<(keycode%8)))!=0)
char keys_return[32]; char keys_return[32];
KEYLP keylp;
TRACE(keyboard,"called\n"); TRACE(keyboard,"called\n");
if (!TSXQueryKeymap(display, keys_return)) { if (!TSXQueryKeymap(display, keys_return)) {
@ -416,19 +436,13 @@ void KEYBOARD_UpdateState ( void )
return; return;
} }
keylp.lp1.count = 1;
keylp.lp1.extended = 0; /* (vkey & 0x100 ? 1 : 0); */
keylp.lp1.win_internal = 0;
keylp.lp1.context = KeyState(kcAlt);/*(event->state & Mod1Mask)?1:0*/
/* Adjust the ALT and CONTROL state if any has been changed outside wine */ /* Adjust the ALT and CONTROL state if any has been changed outside wine */
KEYBOARD_UpdateOneState(VK_MENU, KeyState(kcAlt), keylp); KEYBOARD_UpdateOneState(VK_MENU, KeyState(kcAlt));
KEYBOARD_UpdateOneState(VK_CONTROL, KeyState(kcControl), keylp); KEYBOARD_UpdateOneState(VK_CONTROL, KeyState(kcControl));
KEYBOARD_UpdateOneState(VK_SHIFT, KeyState(kcShift), keylp); KEYBOARD_UpdateOneState(VK_SHIFT, KeyState(kcShift));
#undef KeyState #undef KeyState
} }
/*********************************************************************** /***********************************************************************
* KEYBOARD_HandleEvent * KEYBOARD_HandleEvent
* *
@ -439,14 +453,14 @@ void KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
char Str[24]; char Str[24];
XComposeStatus cs; XComposeStatus cs;
KeySym keysym; KeySym keysym;
WORD vkey = 0; WORD vkey = 0, bScan;
KEYLP keylp; DWORD dwFlags;
static BOOL32 force_extended = FALSE; /* hack for AltGr translation */ static BOOL32 force_extended = FALSE; /* hack for AltGr translation */
int ascii_chars; int ascii_chars;
INT32 event_x = pWnd->rectWindow.left + event->x; INT32 event_x = (pWnd? pWnd->rectWindow.left : 0) + event->x;
INT32 event_y = pWnd->rectWindow.top + event->y; INT32 event_y = (pWnd? pWnd->rectWindow.top : 0) + event->y;
DWORD event_time = event->time - MSG_WineStartTicks; DWORD event_time = event->time - MSG_WineStartTicks;
/* this allows support for dead keys */ /* this allows support for dead keys */
@ -489,408 +503,55 @@ void KEYBOARD_HandleEvent( WND *pWnd, XKeyEvent *event )
if (vkey) if (vkey)
{ {
keylp.lp1.count = 1; switch (vkey & 0xff)
keylp.lp1.code = event->keycode - min_keycode; /* Windows starts from 0, X from
min_keycode (8 usually) */
keylp.lp1.extended = (vkey & 0x100 ? 1 : 0);
keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
* don't remember where I read it - AK */
/* it's '1' under windows, when a dialog box appears
* and you press one of the underlined keys - DF*/
vkey &= 0xff;
switch(vkey)
{ {
case VK_NUMLOCK: case VK_NUMLOCK:
KEYBOARD_GenerateMsg( VK_NUMLOCK, event->type, event_x, event_y, KEYBOARD_GenerateMsg( VK_NUMLOCK, event->type, event_x, event_y,
event_time, keylp); event_time );
break; break;
case VK_CAPITAL: case VK_CAPITAL:
TRACE(keyboard,"Caps Lock event. (type %d). State before : %#.2x\n",event->type,InputKeyStateTable[vkey]); TRACE(keyboard,"Caps Lock event. (type %d). State before : %#.2x\n",event->type,pKeyStateTable[vkey]);
KEYBOARD_GenerateMsg( VK_CAPITAL, event->type, event_x, event_y, KEYBOARD_GenerateMsg( VK_CAPITAL, event->type, event_x, event_y,
event_time, keylp ); event_time );
TRACE(keyboard,"State after : %#.2x\n",InputKeyStateTable[vkey]); TRACE(keyboard,"State after : %#.2x\n",pKeyStateTable[vkey]);
break; break;
default: default:
{
WORD message;
keylp.lp1.context = ( event->state & Mod1Mask ) ? 1 : 0; /* 1 if alt */
if (event->type == KeyPress)
{
keylp.lp1.previous = (InputKeyStateTable[vkey] & 0x80) != 0;
if (!(InputKeyStateTable[vkey] & 0x80))
InputKeyStateTable[vkey] ^= 0x01;
InputKeyStateTable[vkey] |= 0x80;
keylp.lp1.transition = 0;
message = (InputKeyStateTable[VK_MENU] & 0x80)
&& !(InputKeyStateTable[VK_CONTROL] & 0x80)
? WM_SYSKEYDOWN : WM_KEYDOWN;
}
else
{
BOOL32 sysKey = (InputKeyStateTable[VK_MENU] & 0x80)
&& !(InputKeyStateTable[VK_CONTROL] & 0x80)
&& (force_extended == FALSE); /* for Alt from AltGr */
InputKeyStateTable[vkey] &= ~0x80;
keylp.lp1.previous = 1;
keylp.lp1.transition = 1;
message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
}
/* Adjust the NUMLOCK state if it has been changed outside wine */ /* Adjust the NUMLOCK state if it has been changed outside wine */
if (!(InputKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask)) if (!(pKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
{ {
TRACE(keyboard,"Adjusting NumLock state. \n"); TRACE(keyboard,"Adjusting NumLock state. \n");
KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyPress, event_x, event_y, KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyPress, event_x, event_y,
event_time, keylp ); event_time );
KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyRelease, event_x, event_y, KEYBOARD_GenerateMsg( VK_NUMLOCK, KeyRelease, event_x, event_y,
event_time, keylp ); event_time );
} }
/* Adjust the CAPSLOCK state if it has been changed outside wine */ /* Adjust the CAPSLOCK state if it has been changed outside wine */
if (!(InputKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask)) if (!(pKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
{ {
TRACE(keyboard,"Adjusting Caps Lock state.\n"); TRACE(keyboard,"Adjusting Caps Lock state.\n");
KEYBOARD_GenerateMsg( VK_CAPITAL, KeyPress, event_x, event_y, KEYBOARD_GenerateMsg( VK_CAPITAL, KeyPress, event_x, event_y,
event_time, keylp ); event_time );
KEYBOARD_GenerateMsg( VK_CAPITAL, KeyRelease, event_x, event_y, KEYBOARD_GenerateMsg( VK_CAPITAL, KeyRelease, event_x, event_y,
event_time, keylp ); event_time );
} }
/* Not Num nor Caps : end of intermediary states for both. */ /* Not Num nor Caps : end of intermediary states for both. */
NumState = FALSE; NumState = FALSE;
CapsState = FALSE; CapsState = FALSE;
TRACE(key," wParam=%04X, lParam=%08lX\n", bScan = event->keycode - min_keycode; /* Windows starts from 0, X from
vkey, keylp.lp2 ); min_keycode (8 usually) */
TRACE(key," InputKeyState=%X\n", dwFlags = 0;
InputKeyStateTable[vkey]); if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP;
if ( vkey & 0x100 ) dwFlags |= KEYEVENTF_EXTENDEDKEY;
if ( force_extended ) dwFlags |= KEYEVENTF_WINE_FORCEEXTENDED;
hardware_event( message, vkey, keylp.lp2, KEYBOARD_SendEvent( vkey & 0xff, bScan, dwFlags,
event_x, event_y, event_time, 0 ); event_x, event_y, event_time );
}
} }
} }
} }
/**********************************************************************
* GetKeyState (USER.106)
*/
WORD WINAPI GetKeyState16(INT16 vkey)
{
return GetKeyState32(vkey);
}
/**********************************************************************
* GetKeyState (USER32.249)
*
* An application calls the GetKeyState function in response to a
* keyboard-input message. This function retrieves the state of the key
* at the time the input message was generated. (SDK 3.1 Vol 2. p 390)
*/
WORD WINAPI GetKeyState32(INT32 vkey)
{
INT32 retval;
switch (vkey)
{
case VK_LBUTTON : /* VK_LBUTTON is 1 */
retval = MouseButtonsStates[0] ? 0x8000 : 0;
break;
case VK_MBUTTON : /* VK_MBUTTON is 4 */
retval = MouseButtonsStates[1] ? 0x8000 : 0;
break;
case VK_RBUTTON : /* VK_RBUTTON is 2 */
retval = MouseButtonsStates[2] ? 0x8000 : 0;
break;
default :
if (vkey >= 'a' && vkey <= 'z')
vkey += 'A' - 'a';
retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
(WORD)(QueueKeyStateTable[vkey] & 0x01);
}
/* TRACE(key, "(0x%x) -> %x\n", vkey, retval); */
return retval;
}
/**********************************************************************
* GetKeyboardState (USER.222)(USER32.254)
*
* An application calls the GetKeyboardState function in response to a
* keyboard-input message. This function retrieves the state of the keyboard
* at the time the input message was generated. (SDK 3.1 Vol 2. p 387)
*/
VOID WINAPI GetKeyboardState(LPBYTE lpKeyState)
{
TRACE(key, "(%p)\n", lpKeyState);
if (lpKeyState != NULL) {
QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
memcpy(lpKeyState, QueueKeyStateTable, 256);
}
}
/**********************************************************************
* SetKeyboardState (USER.223)(USER32.484)
*/
VOID WINAPI SetKeyboardState(LPBYTE lpKeyState)
{
TRACE(key, "(%p)\n", lpKeyState);
if (lpKeyState != NULL) {
memcpy(QueueKeyStateTable, lpKeyState, 256);
MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0);
MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0);
MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0);
}
}
/**********************************************************************
* GetAsyncKeyState32 (USER32.207)
*
* Determine if a key is or was pressed. retval has high-order
* bit set to 1 if currently pressed, low-order bit set to 1 if key has
* been pressed.
*
* This uses the variable AsyncMouseButtonsStates and
* AsyncKeyStateTable (set in event.c) which have the mouse button
* number or key number (whichever is applicable) set to true if the
* mouse or key had been depressed since the last call to
* GetAsyncKeyState.
*/
WORD WINAPI GetAsyncKeyState32(INT32 nKey)
{
short retval;
switch (nKey) {
case VK_LBUTTON:
retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) |
(MouseButtonsStates[0] ? 0x8000 : 0);
break;
case VK_MBUTTON:
retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) |
(MouseButtonsStates[1] ? 0x8000 : 0);
break;
case VK_RBUTTON:
retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) |
(MouseButtonsStates[2] ? 0x8000 : 0);
break;
default:
retval = AsyncKeyStateTable[nKey] |
((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0);
break;
}
/* all states to false */
memset( AsyncMouseButtonsStates, 0, sizeof(AsyncMouseButtonsStates) );
memset( AsyncKeyStateTable, 0, sizeof(AsyncKeyStateTable) );
TRACE(key, "(%x) -> %x\n", nKey, retval);
return retval;
}
/**********************************************************************
* GetAsyncKeyState16 (USER.249)
*/
WORD WINAPI GetAsyncKeyState16(INT16 nKey)
{
return GetAsyncKeyState32(nKey);
}
/**********************************************************************
* KBD_translate_accelerator
*
* FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP -messages
*/
static BOOL32 KBD_translate_accelerator(HWND32 hWnd,LPMSG32 msg,
BYTE fVirt,WORD key,WORD cmd)
{
BOOL32 sendmsg = FALSE;
if(msg->wParam == key)
{
if (msg->message == WM_CHAR) {
if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )
{
TRACE(accel,"found accel for WM_CHAR: ('%c')\n",
msg->wParam&0xff);
sendmsg=TRUE;
}
} else {
if(fVirt & FVIRTKEY) {
INT32 mask = 0;
TRACE(accel,"found accel for virt_key %04x (scan %04x)\n",
msg->wParam,0xff & HIWORD(msg->lParam));
if(GetKeyState32(VK_SHIFT) & 0x8000) mask |= FSHIFT;
if(GetKeyState32(VK_CONTROL) & 0x8000) mask |= FCONTROL;
if(GetKeyState32(VK_MENU) & 0x8000) mask |= FALT;
if(mask == (fVirt & (FSHIFT | FCONTROL | FALT)))
sendmsg=TRUE;
else
TRACE(accel,", but incorrect SHIFT/CTRL/ALT-state\n");
}
else
{
if (!(msg->lParam & 0x01000000)) /* no special_key */
{
if ((fVirt & FALT) && (msg->lParam & 0x20000000))
{ /* ^^ ALT pressed */
TRACE(accel,"found accel for Alt-%c\n", msg->wParam&0xff);
sendmsg=TRUE;
}
}
}
}
if (sendmsg) /* found an accelerator, but send a message... ? */
{
INT16 iSysStat,iStat,mesg=0;
HMENU16 hMenu;
if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
mesg=1;
else
if (GetCapture32())
mesg=2;
else
if (!IsWindowEnabled32(hWnd))
mesg=3;
else
{
WND* wndPtr = WIN_FindWndPtr(hWnd);
hMenu = (wndPtr->dwStyle & WS_CHILD) ? 0 : (HMENU32)wndPtr->wIDmenu;
iSysStat = (wndPtr->hSysMenu) ? GetMenuState32(GetSubMenu16(wndPtr->hSysMenu, 0),
cmd, MF_BYCOMMAND) : -1 ;
iStat = (hMenu) ? GetMenuState32(hMenu,
cmd, MF_BYCOMMAND) : -1 ;
if (iSysStat!=-1)
{
if (iSysStat & (MF_DISABLED|MF_GRAYED))
mesg=4;
else
mesg=WM_SYSCOMMAND;
}
else
{
if (iStat!=-1)
{
if (IsIconic32(hWnd))
mesg=5;
else
{
if (iStat & (MF_DISABLED|MF_GRAYED))
mesg=6;
else
mesg=WM_COMMAND;
}
}
else
mesg=WM_COMMAND;
}
}
if ( mesg==WM_COMMAND || mesg==WM_SYSCOMMAND )
{
TRACE(accel,", sending %s, wParam=%0x\n",
mesg==WM_COMMAND ? "WM_COMMAND" : "WM_SYSCOMMAND",
cmd);
SendMessage32A(hWnd, mesg, cmd, 0x00010000L);
}
else
{
/* some reasons for NOT sending the WM_{SYS}COMMAND message:
* #0: unknown (please report!)
* #1: for WM_KEYUP,WM_SYSKEYUP
* #2: mouse is captured
* #3: window is disabled
* #4: it's a disabled system menu option
* #5: it's a menu option, but window is iconic
* #6: it's a menu option, but disabled
*/
TRACE(accel,", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
if(mesg==0)
ERR(accel, " unknown reason - please report!");
}
return TRUE;
}
}
return FALSE;
}
/**********************************************************************
* TranslateAccelerator32 (USER32.551)(USER32.552)(USER32.553)
*/
INT32 WINAPI TranslateAccelerator32(HWND32 hWnd, HACCEL32 hAccel, LPMSG32 msg)
{
LPACCEL32 lpAccelTbl = (LPACCEL32)LockResource32(hAccel);
int i;
TRACE(accel,"hwnd=0x%x hacc=0x%x msg=0x%x wp=0x%x lp=0x%lx\n", hWnd, hAccel, msg->message, msg->wParam, msg->lParam);
if (hAccel == 0 || msg == NULL ||
(msg->message != WM_KEYDOWN &&
msg->message != WM_KEYUP &&
msg->message != WM_SYSKEYDOWN &&
msg->message != WM_SYSKEYUP &&
msg->message != WM_CHAR)) {
WARN(accel, "erraneous input parameters\n");
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
TRACE(accel, "TranslateAccelerators hAccel=%04x, hWnd=%04x,"
"msg->hwnd=%04x, msg->message=%04x\n",
hAccel,hWnd,msg->hwnd,msg->message);
i = 0;
do
{
if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
lpAccelTbl[i].key,lpAccelTbl[i].cmd))
return 1;
} while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
WARN(accel, "couldn't translate accelerator key\n");
return 0;
}
/**********************************************************************
* TranslateAccelerator16 (USER.178)
*/
INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
{
LPACCEL16 lpAccelTbl = (LPACCEL16)LockResource16(hAccel);
int i;
MSG32 msg32;
if (hAccel == 0 || msg == NULL ||
(msg->message != WM_KEYDOWN &&
msg->message != WM_KEYUP &&
msg->message != WM_SYSKEYDOWN &&
msg->message != WM_SYSKEYUP &&
msg->message != WM_CHAR)) {
WARN(accel, "erraneous input parameters\n");
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
TRACE(accel, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
STRUCT32_MSG16to32(msg,&msg32);
i = 0;
do
{
if (KBD_translate_accelerator(hWnd,&msg32,lpAccelTbl[i].fVirt,
lpAccelTbl[i].key,lpAccelTbl[i].cmd))
return 1;
} while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
WARN(accel, "couldn't translate accelerator key\n");
return 0;
}
/********************************************************************** /**********************************************************************
* ScreenSwitchEnable (KEYBOARD.100) * ScreenSwitchEnable (KEYBOARD.100)
*/ */
@ -910,7 +571,7 @@ DWORD WINAPI OemKeyScan(WORD wOemChar)
} }
/********************************************************************** /**********************************************************************
* VkKeyScanA (USER32.573) * VkKeyScan [KEYBOARD.129]
*/ */
/* VkKeyScan translates an ANSI character to a virtual-key and shift code /* VkKeyScan translates an ANSI character to a virtual-key and shift code
* for the current keyboard. * for the current keyboard.
@ -927,7 +588,7 @@ DWORD WINAPI OemKeyScan(WORD wOemChar)
* VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00 * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
*/ */
WORD WINAPI VkKeyScan32A(CHAR cChar) WORD WINAPI VkKeyScan16(CHAR cChar)
{ {
KeyCode keycode; KeyCode keycode;
KeySym keysym; KeySym keysym;
@ -971,34 +632,10 @@ WORD WINAPI VkKeyScan32A(CHAR cChar)
return keyc2vkey[keycode]+highbyte; /* keycode -> (keyc2vkey) vkey */ return keyc2vkey[keycode]+highbyte; /* keycode -> (keyc2vkey) vkey */
} }
/******************************************************************************
* VkKeyScan [KEYBOARD.129]
*/
WORD WINAPI VkKeyScan16(CHAR cChar)
{
return VkKeyScan32A(cChar);
}
/******************************************************************************
* VkKeyScanW (USER32.576)
*/
WORD WINAPI VkKeyScan32W(WCHAR cChar)
{
return VkKeyScan32A((CHAR)cChar); /* FIXME: check unicode */
}
/****************************************************************************** /******************************************************************************
* GetKeyboardType16 (KEYBOARD.130) * GetKeyboardType16 (KEYBOARD.130)
*/ */
INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag) INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
{
return GetKeyboardType32(nTypeFlag);
}
/******************************************************************************
* GetKeyboardType32 (USER32.255)
*/
INT32 WINAPI GetKeyboardType32(INT32 nTypeFlag)
{ {
TRACE(keyboard,"(%d)\n",nTypeFlag); TRACE(keyboard,"(%d)\n",nTypeFlag);
switch(nTypeFlag) switch(nTypeFlag)
@ -1018,23 +655,6 @@ INT32 WINAPI GetKeyboardType32(INT32 nTypeFlag)
} }
} }
/******************************************************************************
* MapVirtualKey32A (USER32.383)
*/
UINT32 WINAPI MapVirtualKey32A(UINT32 code, UINT32 maptype)
{
return MapVirtualKey16(code,maptype);
}
/******************************************************************************
* MapVirtualKey32W (USER32.385)
*/
UINT32 WINAPI MapVirtualKey32W(UINT32 code, UINT32 maptype)
{
return MapVirtualKey16(code,maptype);
}
/****************************************************************************** /******************************************************************************
* MapVirtualKey16 (KEYBOARD.131) * MapVirtualKey16 (KEYBOARD.131)
* *
@ -1093,36 +713,6 @@ INT16 WINAPI GetKBCodePage16(void)
return 850; return 850;
} }
/****************************************************************************
* GetKBCodePage32 (USER32.246)
*/
UINT32 WINAPI GetKBCodePage32(void)
{
TRACE(keyboard,"(void)\n");
return 850;
}
/****************************************************************************
* GetKeyboardLayoutName32A (USER32.252)
*/
INT32 WINAPI GetKeyboardLayoutName32A(LPSTR pwszKLID)
{
return GetKeyboardLayoutName16(pwszKLID);
}
/****************************************************************************
* GetKeyboardLayoutName32W (USER32.253)
*/
INT32 WINAPI GetKeyboardLayoutName32W(LPWSTR pwszKLID)
{
LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, strlen("00000409")+1);
int res = GetKeyboardLayoutName32A(buf);
lstrcpyAtoW(pwszKLID,buf);
HeapFree( GetProcessHeap(), 0, buf );
return res;
}
/**************************************************************************** /****************************************************************************
* GetKeyboardLayoutName16 (USER.477) * GetKeyboardLayoutName16 (USER.477)
*/ */
@ -1133,28 +723,6 @@ INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID)
return 1; return 1;
} }
/****************************************************************************
* GetKeyNameText32A (USER32.247)
*/
INT32 WINAPI GetKeyNameText32A(LONG lParam, LPSTR lpBuffer, INT32 nSize)
{
return GetKeyNameText16(lParam,lpBuffer,nSize);
}
/****************************************************************************
* GetKeyNameText32W (USER32.248)
*/
INT32 WINAPI GetKeyNameText32W(LONG lParam, LPWSTR lpBuffer, INT32 nSize)
{
LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, nSize );
int res = GetKeyNameText32A(lParam,buf,nSize);
lstrcpynAtoW(lpBuffer,buf,nSize);
HeapFree( GetProcessHeap(), 0, buf );
return res;
}
/**************************************************************************** /****************************************************************************
* GetKeyNameText16 (KEYBOARD.133) * GetKeyNameText16 (KEYBOARD.133)
*/ */
@ -1179,21 +747,11 @@ INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
return 0; return 0;
} }
/**************************************************************************** /****************************************************************************
* ToAscii (KEYBOARD.4) * ToAscii (KEYBOARD.4)
*/ */
INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState, INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState,
LPVOID lpChar, UINT16 flags) LPVOID lpChar, UINT16 flags)
{
return ToAscii32(virtKey,scanCode,lpKeyState,lpChar,flags);
}
/****************************************************************************
* ToAscii32 (USER32.546)
*/
INT32 WINAPI ToAscii32( UINT32 virtKey,UINT32 scanCode,LPBYTE lpKeyState,
LPWORD lpChar,UINT32 flags )
{ {
XKeyEvent e; XKeyEvent e;
KeySym keysym; KeySym keysym;
@ -1365,141 +923,3 @@ INT32 WINAPI ToAscii32( UINT32 virtKey,UINT32 scanCode,LPBYTE lpKeyState,
return ret; return ret;
} }
/***********************************************************************
* GetKeyboardLayout (USER32.250)
*/
HKL32 WINAPI GetKeyboardLayout(DWORD dwLayout)
{
HKL32 layout;
FIXME(keyboard,"(%ld): stub\n",dwLayout);
layout = (0xcafe<<16)|GetSystemDefaultLCID(); /* FIXME */
TRACE(keyboard,"returning %x\n",layout);
return layout;
}
/***********************************************************************
* GetKeyboardLayoutList (USER32.251)
* FIXME
*/
INT32 WINAPI GetKeyboardLayoutList(INT32 nBuff,HKL32 *layouts)
{
FIXME(keyboard,"(%d,%p): stub\n",nBuff,layouts);
if (layouts)
layouts[0] = GetKeyboardLayout(0);
return 1;
}
/***********************************************************************
* RegisterHotKey (USER32.433)
*/
BOOL32 WINAPI RegisterHotKey(HWND32 hwnd,INT32 id,UINT32 modifiers,UINT32 vk) {
FIXME(keyboard,"(0x%08x,%d,0x%08x,%d): stub\n",hwnd,id,modifiers,vk);
return TRUE;
}
/***********************************************************************
* UnregisterHotKey (USER32.565)
*/
BOOL32 WINAPI UnregisterHotKey(HWND32 hwnd,INT32 id) {
FIXME(keyboard,"(0x%08x,%d): stub\n",hwnd,id);
return TRUE;
}
/***********************************************************************
* KeyboardInquire (KEYBOARD.1)
*/
#pragma pack(1)
typedef struct _KBINFO
{
BYTE Begin_First_Range;
BYTE End_First_Range;
BYTE Begin_Second_Range;
BYTE End_Second_Range;
WORD StateSize;
} KBINFO;
#pragma pack(4)
WORD WINAPI KeyboardInquire(KBINFO *kbInfo)
{
kbInfo->Begin_First_Range = 0;
kbInfo->End_First_Range = 0;
kbInfo->Begin_Second_Range = 0;
kbInfo->End_Second_Range = 0;
kbInfo->StateSize = 16;
return sizeof(KBINFO);
}
/***********************************************************************
* KeyboardEnable (KEYBOARD.2)
*/
VOID WINAPI KeyboardEnable(FARPROC16 eventProc, LPBYTE lpKeyState)
{
FIXME(keyboard, "(%08lx,%08lx): stub\n",
(DWORD)eventProc, (DWORD)lpKeyState);
}
/***********************************************************************
* KeyboardDisable (KEYBOARD.3)
*/
VOID WINAPI KeyboardDisable(VOID)
{
FIXME(keyboard, "(): stub\n");
}
/***********************************************************************
* DisplayInquire (DISPLAY.101)
*/
#pragma pack(1)
typedef struct _CURSORINFO
{
WORD wXMickeys;
WORD wYMickeys;
} CURSORINFO;
#pragma pack(4)
WORD WINAPI DisplayInquire(CURSORINFO *cursorInfo)
{
cursorInfo->wXMickeys = 1;
cursorInfo->wYMickeys = 1;
return sizeof(CURSORINFO);
}
/***********************************************************************
* DisplaySetCursor (DISPLAY.102)
*/
VOID WINAPI DisplaySetCursor( LPVOID cursorShape )
{
FIXME(keyboard, "(%p): stub\n", cursorShape );
}
/***********************************************************************
* DisplayMoveCursor (DISPLAY.103)
*/
VOID WINAPI DisplayMoveCursor( WORD wAbsX, WORD wAbsY )
{
FIXME(keyboard, "(%d,%d): stub\n", wAbsX, wAbsY );
}
/***********************************************************************
* DisplayCheckCursor (DISPLAY.104)
*/
VOID WINAPI DisplayCheckCursor()
{
FIXME(keyboard, "stub\n");
}
/***********************************************************************
* UserRepaintDisable (DISPLAY.103)
*/
VOID WINAPI UserRepaintDisable( BOOL16 disable )
{
FIXME(keyboard, "(%d): stub\n", disable);
}