Added support for low-level mouse and keyboard hooks.

Misc keyboard handling cleanups.
This commit is contained in:
Alexandre Julliard 2001-10-17 17:50:02 +00:00
parent 516e40e154
commit 4b62618122
16 changed files with 233 additions and 308 deletions

View file

@ -3,7 +3,7 @@ type win16
owner user32
1 pascal16 Inquire(ptr) KEYBOARD_Inquire
2 pascal16 Enable(segptr ptr) WIN16_KEYBOARD_Enable
2 pascal16 Enable(segptr ptr) KEYBOARD_Enable
3 pascal16 Disable() KEYBOARD_Disable
4 pascal16 ToAscii(word word ptr ptr word) ToAscii16
5 pascal16 AnsiToOem(str ptr) AnsiToOem16

View file

@ -18,7 +18,6 @@
#include "winerror.h"
#include "wine/exception.h"
#include "wine/keyboard16.h"
#include "wine/unicode.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"

View file

@ -16,7 +16,6 @@
#include "global.h"
#include "input.h"
#include "hook.h"
#include "keyboard.h"
#include "message.h"
#include "queue.h"
#include "spy.h"
@ -246,7 +245,7 @@ static BOOL process_attach(void)
if (!WIN_CreateDesktopWindow()) return FALSE;
/* Initialize keyboard driver */
KEYBOARD_Enable( keybd_event, InputKeyStateTable );
USER_Driver.pInitKeyboard( InputKeyStateTable );
/* Initialize mouse driver */
MOUSE_Enable( mouse_event );

View file

@ -1,45 +0,0 @@
/*
* KEYBOARD driver interface
*
* Copyright 1998 Ulrich Weigand
*/
#ifndef __WINE_KEYBOARD_H
#define __WINE_KEYBOARD_H
#include "windef.h"
#include "pshpack1.h"
typedef struct _KBINFO
{
BYTE Begin_First_Range;
BYTE End_First_Range;
BYTE Begin_Second_Range;
BYTE End_Second_Range;
WORD StateSize;
} KBINFO, *LPKBINFO;
#include "poppack.h"
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 void KEYBOARD_SendEvent(BYTE bVk, BYTE bScan, DWORD dwFlags, DWORD posX, DWORD posY, DWORD time);
#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

@ -13,6 +13,7 @@
#include "winuser.h"
#include "thread.h"
#define WH_NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
/* Per-queue data for the message queue
* Note that we currently only store the current values for

View file

@ -46,10 +46,10 @@ enum wine_internal_message
typedef struct tagUSER_DRIVER {
/* keyboard functions */
void (*pInitKeyboard)(void);
void (*pInitKeyboard)(LPBYTE);
WORD (*pVkKeyScan)(CHAR);
UINT16 (*pMapVirtualKey)(UINT16, UINT16);
INT16 (*pGetKeyNameText)(LONG, LPSTR, INT16);
UINT (*pMapVirtualKey)(UINT,UINT);
INT (*pGetKeyNameText)(LONG,LPSTR,INT);
INT (*pToUnicode)(UINT, UINT, LPBYTE, LPWSTR, int, UINT);
void (*pBeep)(void);
BOOL (*pGetDIState)(DWORD, LPVOID);

View file

@ -1,16 +0,0 @@
#ifndef __WINE_WINE_KEYBOARD16_H
#define __WINE_WINE_KEYBOARD16_H
#include "windef.h"
#include "wine/windef16.h"
VOID WINAPI ScreenSwitchEnable16(WORD);
INT16 WINAPI ToAscii16(UINT16,UINT16,LPBYTE,LPVOID,UINT16);
WORD WINAPI VkKeyScan16(CHAR);
INT16 WINAPI AnsiToOem16(LPCSTR,LPSTR);
VOID WINAPI AnsiToOemBuff16(LPCSTR,LPSTR,UINT16);
INT16 WINAPI OemToAnsi16(LPCSTR,LPSTR);
VOID WINAPI OemToAnsiBuff16(LPCSTR,LPSTR,UINT16);
#endif /* __WINE_WINE_KEYBOARD16_H */

View file

@ -102,6 +102,33 @@ typedef struct
} EVENTMSG, *PEVENTMSG, *LPEVENTMSG;
/* WH_KEYBOARD_LL structure */
typedef struct tagKBDLLHOOKSTRUCT
{
DWORD vkCode;
DWORD scanCode;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KBDLLHOOKSTRUCT, *LPKBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT;
#define LLKHF_EXTENDED (KF_EXTENDED >> 8)
#define LLKHF_INJECTED 0x00000010
#define LLKHF_ALTDOWN (KF_ALTDOWN >> 8)
#define LLKHF_UP (KF_UP >> 8)
/* WH_MOUSE_LL structure */
typedef struct tagMSLLHOOKSTRUCT
{
POINT pt;
DWORD mouseData;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MSLLHOOKSTRUCT, *LPMSLLHOOKSTRUCT, *PMSLLHOOKSTRUCT;
#define LLMHF_INJECTED 0x00000001
/* Mouse hook structure */
typedef struct
@ -1335,11 +1362,12 @@ typedef struct
#define WH_SHELL 10
#define WH_FOREGROUNDIDLE 11
#define WH_CALLWNDPROCRET 12
#define WH_MAX 12
#define WH_KEYBOARD_LL 13
#define WH_MOUSE_LL 14
#define WH_MAX 14
#define WH_MINHOOK WH_MIN
#define WH_MAXHOOK WH_MAX
#define WH_NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
/* Hook action codes */
#define HC_ACTION 0

View file

@ -361,16 +361,6 @@ extern INPUT_TYPE X11DRV_EVENT_SetInputMethod(INPUT_TYPE type);
void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base) ;
#endif
/* X11 keyboard driver */
extern void X11DRV_InitKeyboard(void);
extern WORD X11DRV_VkKeyScan(CHAR cChar);
extern UINT16 X11DRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType);
extern INT16 X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT16 nSize);
extern BOOL X11DRV_GetDIState(DWORD len, LPVOID ptr);
extern BOOL X11DRV_GetDIData(BYTE *keystate, DWORD dodsize, struct DIDEVICEOBJECTDATA *dod, LPDWORD entries, DWORD flags);
/* X11 mouse driver */
extern void X11DRV_InitMouse(LPMOUSE_EVENT_PROC);

View file

@ -40,7 +40,6 @@
#include "winnls.h"
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/keyboard16.h"
#include "thread.h"
#include "winerror.h"
#include "wincon.h"

View file

@ -231,6 +231,7 @@ static void HOOK_Map16To32Common(INT id, INT code, WPARAM *pwParam,
case WH_HARDWARE:
case WH_FOREGROUNDIDLE:
case WH_CALLWNDPROCRET:
default:
FIXME("\t[%i] 16to32 translation unimplemented\n", id);
}
}
@ -335,6 +336,7 @@ static void HOOK_UnMap16To32Common(INT id, INT code, WPARAM wParamOrig,
case WH_HARDWARE:
case WH_FOREGROUNDIDLE:
case WH_CALLWNDPROCRET:
default:
FIXME("\t[%i] skipping unmap\n", id);
break;
}
@ -499,6 +501,7 @@ static void HOOK_Map32To16Common(INT id, INT code, WPARAM *pwParam,
case WH_HARDWARE:
case WH_FOREGROUNDIDLE:
case WH_CALLWNDPROCRET:
default:
FIXME("\t[%i] 32to16 translation unimplemented\n", id);
}
}
@ -649,6 +652,7 @@ static void HOOK_UnMap32To16Common(INT id, INT code, WPARAM wParamOrig,
case WH_HARDWARE:
case WH_FOREGROUNDIDLE:
case WH_CALLWNDPROCRET:
default:
FIXME("\t[%i] skipping unmap\n", id);
}
}

View file

@ -22,11 +22,10 @@
#include "winuser.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "wine/keyboard16.h"
#include "wine/server.h"
#include "win.h"
#include "hook.h"
#include "input.h"
#include "keyboard.h"
#include "mouse.h"
#include "message.h"
#include "queue.h"
@ -78,7 +77,7 @@ typedef union
* Note: the position is relative to the desktop window.
*/
static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lParam,
int xPos, int yPos, DWORD time, DWORD extraInfo )
int xPos, int yPos, DWORD time, ULONG_PTR extraInfo )
{
SERVER_START_REQ( send_message )
{
@ -108,6 +107,7 @@ static void queue_kbd_event( const KEYBDINPUT *ki )
{
UINT message;
KEYLP keylp;
KBDLLHOOKSTRUCT hook;
keylp.lp2 = 0;
keylp.lp1.count = 1;
@ -145,8 +145,34 @@ static void queue_kbd_event( const KEYBDINPUT *ki )
TRACE_(key)(" wParam=%04x, lParam=%08lx, InputKeyState=%x\n",
ki->wVk, keylp.lp2, InputKeyStateTable[ki->wVk] );
queue_raw_hardware_message( message, ki->wVk, keylp.lp2,
PosX, PosY, ki->time, ki->dwExtraInfo );
hook.vkCode = ki->wVk;
hook.scanCode = ki->wScan;
hook.flags = keylp.lp2 >> 24; /* FIXME: LLKHF_INJECTED flag */
hook.time = ki->time;
hook.dwExtraInfo = ki->dwExtraInfo;
if (!HOOK_CallHooksW( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook ))
queue_raw_hardware_message( message, ki->wVk, keylp.lp2,
PosX, PosY, ki->time, ki->dwExtraInfo );
}
/***********************************************************************
* queue_raw_mouse_message
*/
static void queue_raw_mouse_message( UINT message, WPARAM wParam, LPARAM lParam,
int xPos, int yPos, DWORD time, ULONG_PTR extra_info )
{
MSLLHOOKSTRUCT hook;
hook.pt.x = xPos;
hook.pt.y = yPos;
hook.mouseData = wParam;
hook.flags = 0; /* FIXME: LLMHF_INJECTED flag */
hook.time = time;
hook.dwExtraInfo = extra_info;
if (!HOOK_CallHooksW( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook ))
queue_raw_hardware_message( message, wParam, lParam, xPos, yPos, time, extra_info );
}
@ -182,52 +208,52 @@ static void queue_mouse_event( const MOUSEINPUT *mi, WORD keystate )
if (mi->dwFlags & MOUSEEVENTF_MOVE)
{
queue_raw_hardware_message( WM_MOUSEMOVE, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
queue_raw_mouse_message( WM_MOUSEMOVE, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
}
if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN))
{
InputKeyStateTable[VK_LBUTTON] |= 0x80;
AsyncKeyStateTable[VK_LBUTTON] |= 0x80;
queue_raw_hardware_message( WM_LBUTTONDOWN, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
queue_raw_mouse_message( WM_LBUTTONDOWN, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
}
if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP))
{
AsyncKeyStateTable[VK_LBUTTON] &= ~0x80;
queue_raw_hardware_message( WM_LBUTTONUP, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
queue_raw_mouse_message( WM_LBUTTONUP, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
}
if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN))
{
InputKeyStateTable[VK_RBUTTON] |= 0x80;
AsyncKeyStateTable[VK_RBUTTON] |= 0x80;
queue_raw_hardware_message( WM_RBUTTONDOWN, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
queue_raw_mouse_message( WM_RBUTTONDOWN, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
}
if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP))
{
AsyncKeyStateTable[VK_RBUTTON] &= ~0x80;
queue_raw_hardware_message( WM_RBUTTONUP, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
queue_raw_mouse_message( WM_RBUTTONUP, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
}
if (mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
{
InputKeyStateTable[VK_MBUTTON] |= 0x80;
AsyncKeyStateTable[VK_MBUTTON] |= 0x80;
queue_raw_hardware_message( WM_MBUTTONDOWN, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
queue_raw_mouse_message( WM_MBUTTONDOWN, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
}
if (mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
{
AsyncKeyStateTable[VK_MBUTTON] &= ~0x80;
queue_raw_hardware_message( WM_MBUTTONUP, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
queue_raw_mouse_message( WM_MBUTTONUP, keystate, 0, PosX, PosY,
mi->time, mi->dwExtraInfo );
}
if (mi->dwFlags & MOUSEEVENTF_WHEEL)
{
queue_raw_hardware_message( WM_MOUSEWHEEL, MAKELONG( keystate, mi->mouseData), 0,
PosX, PosY, mi->time, mi->dwExtraInfo );
queue_raw_mouse_message( WM_MOUSEWHEEL, MAKELONG( keystate, mi->mouseData), 0,
PosX, PosY, mi->time, mi->dwExtraInfo );
}
}
@ -268,28 +294,12 @@ void WINAPI keybd_event( BYTE bVk, BYTE bScan,
{
INPUT input;
/*
* If we are called by the Wine keyboard driver, use the additional
* info pointed to by the dwExtraInfo argument.
* Otherwise, we need to determine that info ourselves (probably
* less accurate, but we can't help that ...).
*/
if ( !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_KEYBDEVENT) )
&& ((WINE_KEYBDEVENT *)dwExtraInfo)->magic == WINE_KEYBDEVENT_MAGIC )
{
WINE_KEYBDEVENT *wke = (WINE_KEYBDEVENT *)dwExtraInfo;
input.u.ki.time = wke->time;
input.u.ki.dwExtraInfo = 0;
}
else
{
input.u.ki.time = GetTickCount();
input.u.ki.dwExtraInfo = dwExtraInfo;
}
input.type = INPUT_KEYBOARD;
input.u.ki.wVk = bVk;
input.u.ki.wScan = bScan;
input.u.ki.dwFlags = dwFlags;
input.u.ki.time = GetTickCount();
input.u.ki.dwExtraInfo = dwExtraInfo;
SendInput( 1, &input, sizeof(input) );
}
@ -613,10 +623,24 @@ BOOL16 WINAPI IsUserIdle16(void)
/**********************************************************************
* VkKeyScanA (USER32.@)
*
* VkKeyScan translates an ANSI character to a virtual-key and shift code
* for the current keyboard.
* high-order byte yields :
* 0 Unshifted
* 1 Shift
* 2 Ctrl
* 3-5 Shift-key combinations that are not used for characters
* 6 Ctrl-Alt
* 7 Ctrl-Alt-Shift
* I.e. : Shift = 1, Ctrl = 2, Alt = 4.
* FIXME : works ok except for dead chars :
* VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
* VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
*/
WORD WINAPI VkKeyScanA(CHAR cChar)
{
return VkKeyScan16(cChar);
return USER_Driver.pVkKeyScan( cChar );
}
/******************************************************************************
@ -632,8 +656,8 @@ WORD WINAPI VkKeyScanW(WCHAR cChar)
*/
WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
{
/* FIXME: complete workaround this is */
return VkKeyScan16(cChar);
/* FIXME: complete workaround this is */
return VkKeyScanA(cChar);
}
/******************************************************************************
@ -641,16 +665,28 @@ WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
*/
WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl)
{
/* FIXME: complete workaround this is */
return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
/* FIXME: complete workaround this is */
return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
}
/******************************************************************************
* GetKeyboardType (USER32.@)
*/
INT WINAPI GetKeyboardType(INT nTypeFlag)
{
return GetKeyboardType16(nTypeFlag);
TRACE_(keyboard)("(%d)\n", nTypeFlag);
switch(nTypeFlag)
{
case 0: /* Keyboard type */
return 4; /* AT-101 */
case 1: /* Keyboard Subtype */
return 0; /* There are no defined subtypes */
case 2: /* Number of F-keys */
return 12; /* We're doing an 101 for now, so return 12 F-keys */
default:
WARN_(keyboard)("Unknown type\n");
return 0; /* The book says 0 here, so 0 */
}
}
/******************************************************************************
@ -658,7 +694,7 @@ INT WINAPI GetKeyboardType(INT nTypeFlag)
*/
UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
{
return MapVirtualKey16(code,maptype);
return USER_Driver.pMapVirtualKey( code, maptype );
}
/******************************************************************************
@ -666,7 +702,7 @@ UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
*/
UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype)
{
return MapVirtualKey16(code,maptype);
return MapVirtualKeyA(code,maptype);
}
/******************************************************************************
@ -676,7 +712,7 @@ UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl)
{
if (hkl)
FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
return MapVirtualKey16(code,maptype);
return MapVirtualKeyA(code,maptype);
}
/******************************************************************************
@ -686,7 +722,7 @@ UINT WINAPI MapVirtualKeyExW(UINT code, UINT maptype, HKL hkl)
{
if (hkl)
FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
return MapVirtualKey16(code,maptype);
return MapVirtualKeyA(code,maptype);
}
/****************************************************************************
@ -746,7 +782,7 @@ INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID)
*/
INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
{
return GetKeyNameText16(lParam,lpBuffer,nSize);
return USER_Driver.pGetKeyNameText( lParam, lpBuffer, nSize );
}
/****************************************************************************

View file

@ -17,9 +17,7 @@
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/keyboard16.h"
#include "win.h"
#include "keyboard.h"
#include "user.h"
#include "message.h"
#include "callback.h"
@ -28,12 +26,44 @@
#include "winerror.h"
DEFAULT_DEBUG_CHANNEL(keyboard);
DECLARE_DEBUG_CHANNEL(event);
#include "pshpack1.h"
typedef struct _KBINFO
{
BYTE Begin_First_Range;
BYTE End_First_Range;
BYTE Begin_Second_Range;
BYTE End_Second_Range;
WORD StateSize;
} KBINFO, *LPKBINFO;
#include "poppack.h"
/**********************************************************************/
static LPKEYBD_EVENT_PROC DefKeybEventProc = NULL;
LPBYTE pKeyStateTable = NULL;
typedef VOID CALLBACK (*LPKEYBD_EVENT_PROC)(BYTE,BYTE,DWORD,DWORD);
static LPKEYBD_EVENT_PROC DefKeybEventProc;
static LPBYTE pKeyStateTable;
/***********************************************************************
* KEYBOARD_CallKeybdEventProc
*/
static VOID WINAPI KEYBOARD_CallKeybdEventProc( FARPROC16 proc,
BYTE bVk, BYTE bScan,
DWORD dwFlags, DWORD dwExtraInfo )
{
CONTEXT86 context;
memset( &context, 0, sizeof(context) );
context.SegCs = SELECTOROF( proc );
context.Eip = OFFSETOF( proc );
context.Eax = bVk | ((dwFlags & KEYEVENTF_KEYUP)? 0x8000 : 0);
context.Ebx = bScan | ((dwFlags & KEYEVENTF_EXTENDEDKEY) ? 0x100 : 0);
context.Esi = LOWORD( dwExtraInfo );
context.Edi = HIWORD( dwExtraInfo );
wine_call_to_16_regs_short( &context, 0 );
}
/***********************************************************************
* Inquire (KEYBOARD.1)
@ -52,50 +82,13 @@ WORD WINAPI KEYBOARD_Inquire(LPKBINFO kbInfo)
/***********************************************************************
* Enable (KEYBOARD.2)
*/
VOID WINAPI KEYBOARD_Enable( LPKEYBD_EVENT_PROC lpKeybEventProc,
LPBYTE lpKeyState )
VOID WINAPI KEYBOARD_Enable( FARPROC16 proc, LPBYTE lpKeyState )
{
static BOOL initDone = FALSE;
if (DefKeybEventProc) THUNK_Free( (FARPROC)DefKeybEventProc );
DefKeybEventProc = (LPKEYBD_EVENT_PROC)THUNK_Alloc( proc, (RELAY)KEYBOARD_CallKeybdEventProc );
pKeyStateTable = lpKeyState;
THUNK_Free( (FARPROC)DefKeybEventProc );
DefKeybEventProc = lpKeybEventProc;
pKeyStateTable = lpKeyState;
/* all states to false */
memset( lpKeyState, 0, 256 );
if (!initDone) USER_Driver.pInitKeyboard();
initDone = TRUE;
}
/**********************************************************************/
static VOID WINAPI KEYBOARD_CallKeybdEventProc( FARPROC16 proc,
BYTE bVk, BYTE bScan,
DWORD dwFlags, DWORD dwExtraInfo )
{
CONTEXT86 context;
memset( &context, 0, sizeof(context) );
context.SegCs = SELECTOROF( proc );
context.Eip = OFFSETOF( proc );
context.Eax = bVk | ((dwFlags & KEYEVENTF_KEYUP)? 0x8000 : 0);
context.Ebx = bScan | ((dwFlags & KEYEVENTF_EXTENDEDKEY) ? 0x100 : 0);
context.Esi = LOWORD( dwExtraInfo );
context.Edi = HIWORD( dwExtraInfo );
wine_call_to_16_regs_short( &context, 0 );
}
/**********************************************************************/
VOID WINAPI WIN16_KEYBOARD_Enable( FARPROC16 proc, LPBYTE lpKeyState )
{
LPKEYBD_EVENT_PROC thunk =
(LPKEYBD_EVENT_PROC)THUNK_Alloc( proc, (RELAY)KEYBOARD_CallKeybdEventProc );
KEYBOARD_Enable( thunk, lpKeyState );
memset( lpKeyState, 0, 256 ); /* all states to false */
}
/***********************************************************************
@ -109,30 +102,6 @@ VOID WINAPI KEYBOARD_Disable(VOID)
pKeyStateTable = NULL;
}
/***********************************************************************
* KEYBOARD_SendEvent
*/
void KEYBOARD_SendEvent( BYTE bVk, BYTE bScan, DWORD dwFlags,
DWORD posX, DWORD posY, DWORD time )
{
WINE_KEYBDEVENT wke;
int iWndsLocks;
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;
/* To avoid deadlocks, we have to suspend all locks on windows structures
before the program control is passed to the keyboard driver */
iWndsLocks = WIN_SuspendWndsLock();
DefKeybEventProc( bVk, bScan, dwFlags, (DWORD)&wke );
WIN_RestoreWndsLock(iWndsLocks);
}
/**********************************************************************
* SetSpeed (KEYBOARD.7)
@ -164,25 +133,10 @@ DWORD WINAPI OemKeyScan(WORD wOemChar)
/**********************************************************************
* VkKeyScan (KEYBOARD.129)
*
* VkKeyScan translates an ANSI character to a virtual-key and shift code
* for the current keyboard.
* high-order byte yields :
* 0 Unshifted
* 1 Shift
* 2 Ctrl
* 3-5 Shift-key combinations that are not used for characters
* 6 Ctrl-Alt
* 7 Ctrl-Alt-Shift
* I.e. : Shift = 1, Ctrl = 2, Alt = 4.
* FIXME : works ok except for dead chars :
* VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
* VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
*/
WORD WINAPI VkKeyScan16(CHAR cChar)
{
return USER_Driver.pVkKeyScan(cChar);
return VkKeyScanA( cChar );
}
/******************************************************************************
@ -190,22 +144,7 @@ WORD WINAPI VkKeyScan16(CHAR cChar)
*/
INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
{
TRACE("(%d)\n", nTypeFlag);
switch(nTypeFlag)
{
case 0: /* Keyboard type */
return 4; /* AT-101 */
break;
case 1: /* Keyboard Subtype */
return 0; /* There are no defined subtypes */
break;
case 2: /* Number of F-keys */
return 12; /* We're doing an 101 for now, so return 12 F-keys */
break;
default:
WARN("Unknown type\n");
return 0; /* The book says 0 here, so 0 */
}
return GetKeyboardType( nTypeFlag );
}
/******************************************************************************
@ -215,7 +154,7 @@ INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
*/
UINT16 WINAPI MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
{
return USER_Driver.pMapVirtualKey(wCode,wMapType);
return MapVirtualKeyA(wCode,wMapType);
}
/****************************************************************************
@ -231,7 +170,7 @@ INT16 WINAPI GetKBCodePage16(void)
*/
INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
{
return USER_Driver.pGetKeyNameText(lParam, lpBuffer, nSize);
return GetKeyNameTextA( lParam, lpBuffer, nSize );
}
/****************************************************************************

View file

@ -17,7 +17,6 @@
#include "winerror.h"
#include "controls.h"
#include "keyboard.h"
#include "user.h"
#include "debugtools.h"
#include "sysmetrics.h"

View file

@ -26,7 +26,6 @@
#include "dce.h"
#include "debugtools.h"
#include "input.h"
#include "keyboard.h"
#include "mouse.h"
#include "options.h"
#include "win.h"
@ -48,7 +47,6 @@ extern Atom dndProtocol;
extern Atom dndSelection;
extern void X11DRV_KEYBOARD_UpdateState(void);
extern void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y );
#define NB_BUTTONS 5 /* Windows can handle 3 buttons and the wheel too */
@ -87,7 +85,6 @@ static void EVENT_ProcessEvent( XEvent *event );
static BOOL X11DRV_CheckFocus(void);
/* Event handlers */
static void EVENT_Key( HWND hWnd, XKeyEvent *event );
static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event );
static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event );
static void EVENT_MotionNotify( HWND hWnd, XMotionEvent *event );
@ -97,12 +94,13 @@ static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BO
static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event);
static void EVENT_PropertyNotify( XPropertyEvent *event );
static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event );
static void EVENT_MappingNotify( XMappingEvent *event );
extern void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event );
extern void X11DRV_Expose( HWND hwnd, XExposeEvent *event );
extern void X11DRV_MapNotify( HWND hwnd, XMapEvent *event );
extern void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event );
extern void X11DRV_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
extern void X11DRV_MappingNotify( XMappingEvent *event );
#ifdef HAVE_LIBXXF86DGA2
static int DGAMotionEventType;
@ -231,13 +229,11 @@ static void EVENT_ProcessEvent( XEvent *event )
if ((event->type == DGAKeyPressEventType) ||
(event->type == DGAKeyReleaseEventType)) {
/* Fill a XKeyEvent to send to EVENT_Key */
POINT pt;
XKeyEvent ke;
XDGAKeyEvent *evt = (XDGAKeyEvent *) event;
TRACE("DGAKeyPress/ReleaseEvent received.\n");
GetCursorPos( &pt );
if (evt->type == DGAKeyReleaseEventType)
ke.type = KeyRelease;
else
@ -249,15 +245,14 @@ static void EVENT_ProcessEvent( XEvent *event )
ke.root = 0;
ke.subwindow = 0;
ke.time = evt->time;
ke.x = pt.x;
ke.y = pt.y;
ke.x = -1;
ke.y = -1;
ke.x_root = -1;
ke.y_root = -1;
ke.state = evt->state;
ke.keycode = evt->keycode;
ke.same_screen = TRUE;
X11DRV_KEYBOARD_HandleEvent(&ke,pt.x,pt.y);
X11DRV_KeyEvent( 0, &ke );
return;
}
}
@ -279,7 +274,8 @@ static void EVENT_ProcessEvent( XEvent *event )
{
case KeyPress:
case KeyRelease:
EVENT_Key( hWnd, (XKeyEvent*)event );
/* FIXME: should generate a motion event if event point is different from current pos */
X11DRV_KeyEvent( hWnd, (XKeyEvent*)event );
break;
case ButtonPress:
@ -342,7 +338,7 @@ static void EVENT_ProcessEvent( XEvent *event )
break;
case MappingNotify:
EVENT_MappingNotify( (XMappingEvent *) event );
X11DRV_MappingNotify( (XMappingEvent *) event );
break;
default:
@ -398,19 +394,6 @@ static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt )
}
/***********************************************************************
* EVENT_Key
*
* Handle a X key event
*/
static void EVENT_Key( HWND hWnd, XKeyEvent *event )
{
POINT pt;
get_coords( &hWnd, event->window, event->x, event->y, &pt );
X11DRV_KEYBOARD_HandleEvent( event, pt.x, pt.y );
}
/***********************************************************************
* EVENT_MotionNotify
*/
@ -1454,18 +1437,6 @@ static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event )
}
/***********************************************************************
* EVENT_MappingNotify
*/
static void EVENT_MappingNotify( XMappingEvent *event )
{
TSXRefreshKeyboardMapping(event);
/* reinitialize Wine-X11 driver keyboard table */
X11DRV_InitKeyboard();
}
/**********************************************************************
* X11DRV_EVENT_SetInputMethod
*/

View file

@ -30,7 +30,6 @@
#include "dinput.h"
#include "debugtools.h"
#include "user.h"
#include "keyboard.h"
#include "winnls.h"
#include "win.h"
#include "x11drv.h"
@ -39,13 +38,10 @@ DEFAULT_DEBUG_CHANNEL(keyboard);
DECLARE_DEBUG_CHANNEL(key);
DECLARE_DEBUG_CHANNEL(dinput);
extern BYTE InputKeyStateTable[256];
extern LPBYTE pKeyStateTable;
int min_keycode, max_keycode, keysyms_per_keycode;
WORD keyc2vkey[256], keyc2scan[256];
static LPBYTE pKeyStateTable;
static int NumLockMask, AltGrMask; /* mask in the XKeyEvent state */
static int kcControl, kcAlt, kcShift, kcNumLock, kcCapsLock; /* keycodes */
#ifdef HAVE_XKB
@ -620,6 +616,24 @@ static WORD EVENT_event_to_vkey( XKeyEvent *e)
static BOOL NumState=FALSE, CapsState=FALSE;
/***********************************************************************
* send_keyboard_input
*/
void send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time )
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.u.ki.wVk = wVk;
input.u.ki.wScan = wScan;
input.u.ki.dwFlags = dwFlags;
input.u.ki.time = time;
input.u.ki.dwExtraInfo = 0;
SendInput( 1, &input, sizeof(input) );
}
/**********************************************************************
* KEYBOARD_GenerateMsg
*
@ -628,8 +642,7 @@ static BOOL NumState=FALSE, CapsState=FALSE;
* Convention : called with vkey only VK_NUMLOCK or VK_CAPITAL
*
*/
static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, INT event_x, INT event_y,
DWORD event_time )
static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, DWORD event_time )
{
BOOL * State = (vkey==VK_NUMLOCK? &NumState : &CapsState);
DWORD up, down;
@ -649,10 +662,8 @@ static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, INT event_x,
if (Evtype!=KeyPress)
{
TRACE("ON + KeyRelease => generating DOWN and UP messages.\n");
KEYBOARD_SendEvent( vkey, scan, down,
event_x, event_y, event_time );
KEYBOARD_SendEvent( vkey, scan, up,
event_x, event_y, event_time );
send_keyboard_input( vkey, scan, down, event_time );
send_keyboard_input( vkey, scan, up, event_time );
*State=FALSE;
pKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */
}
@ -661,10 +672,8 @@ static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, INT event_x,
if (Evtype==KeyPress)
{
TRACE("OFF + Keypress => generating DOWN and UP messages.\n");
KEYBOARD_SendEvent( vkey, scan, down,
event_x, event_y, event_time );
KEYBOARD_SendEvent( vkey, scan, up,
event_x, event_y, event_time );
send_keyboard_input( vkey, scan, down, event_time );
send_keyboard_input( vkey, scan, up, event_time );
*State=TRUE; /* Goes to intermediary state before going to ON */
pKeyStateTable[vkey] |= 0x01; /* Toggle state to on. */
}
@ -686,8 +695,7 @@ static void KEYBOARD_UpdateOneState ( int vkey, int state )
vkey, pKeyStateTable[vkey]);
/* Fake key being pressed inside wine */
KEYBOARD_SendEvent( vkey, 0, state? 0 : KEYEVENTF_KEYUP,
0, 0, GetTickCount() );
send_keyboard_input( vkey, 0, state? 0 : KEYEVENTF_KEYUP, GetTickCount() );
TRACE("State after %#.2x \n",pKeyStateTable[vkey]);
}
@ -725,11 +733,11 @@ void X11DRV_KEYBOARD_UpdateState ( void )
}
/***********************************************************************
* X11DRV_KEYBOARD_HandleEvent
* X11DRV_KeyEvent
*
* Handle a X key event
*/
void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y )
void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event )
{
char Str[24];
KeySym keysym;
@ -789,11 +797,11 @@ void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y )
switch (vkey & 0xff)
{
case VK_NUMLOCK:
KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, x, y, event_time );
KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, event_time );
break;
case VK_CAPITAL:
TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,pKeyStateTable[vkey]);
KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, x, y, event_time );
KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, event_time );
TRACE("State after : %#.2x\n",pKeyStateTable[vkey]);
break;
default:
@ -801,15 +809,15 @@ void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y )
if (!(pKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
{
TRACE("Adjusting NumLock state. \n");
KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, x, y, event_time );
KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, x, y, event_time );
KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, event_time );
KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, event_time );
}
/* Adjust the CAPSLOCK state if it has been changed outside wine */
if (!(pKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
{
TRACE("Adjusting Caps Lock state.\n");
KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, x, y, event_time );
KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, x, y, event_time );
KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, event_time );
KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, event_time );
}
/* Not Num nor Caps : end of intermediary states for both. */
NumState = FALSE;
@ -822,7 +830,7 @@ void X11DRV_KEYBOARD_HandleEvent( XKeyEvent *event, int x, int y )
if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP;
if ( vkey & 0x100 ) dwFlags |= KEYEVENTF_EXTENDEDKEY;
KEYBOARD_SendEvent( vkey & 0xff, bScan, dwFlags, x, y, event_time );
send_keyboard_input( vkey & 0xff, bScan, dwFlags, event_time );
}
}
}
@ -931,7 +939,7 @@ X11DRV_KEYBOARD_DetectLayout (void)
/**********************************************************************
* InitKeyboard (X11DRV.@)
*/
void X11DRV_InitKeyboard(void)
void X11DRV_InitKeyboard( BYTE *key_state_table )
{
#ifdef HAVE_XKB
int xkb_major = XkbMajorVersion, xkb_minor = XkbMinorVersion;
@ -947,6 +955,8 @@ void X11DRV_InitKeyboard(void)
char ckey[4]={0,0,0,0};
const char (*lkey)[MAIN_LEN][4];
pKeyStateTable = key_state_table;
#ifdef HAVE_XKB
wine_tsx11_lock();
is_xkb = XkbQueryExtension(display,
@ -1159,6 +1169,17 @@ void X11DRV_InitKeyboard(void)
kcCapsLock = TSXKeysymToKeycode(display, XK_Caps_Lock);
}
/***********************************************************************
* X11DRV_MappingNotify
*/
void X11DRV_MappingNotify( XMappingEvent *event )
{
TSXRefreshKeyboardMapping(event);
X11DRV_InitKeyboard( pKeyStateTable );
}
/***********************************************************************
* VkKeyScan (X11DRV.@)
*/
@ -1211,7 +1232,7 @@ WORD X11DRV_VkKeyScan(CHAR cChar)
/***********************************************************************
* MapVirtualKey (X11DRV.@)
*/
UINT16 X11DRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType)
UINT X11DRV_MapVirtualKey(UINT wCode, UINT wMapType)
{
Display *display = thread_display();
@ -1297,7 +1318,7 @@ UINT16 X11DRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType)
/***********************************************************************
* GetKeyNameText (X11DRV.@)
*/
INT16 X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT16 nSize)
INT X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT nSize)
{
int vkey, ansi, scanCode;
KeyCode keyc;
@ -1648,7 +1669,7 @@ BOOL X11DRV_GetDIState(DWORD len, LPVOID ptr)
/* X keycode to virtual key */
vkey = keyc2vkey[keyc] & 0xFF;
/* The windows scancode is keyc-min_keycode */
if (InputKeyStateTable[vkey]&0x80) {
if (pKeyStateTable[vkey]&0x80) {
((LPBYTE)ptr)[keyc-min_keycode]=0x80;
((LPBYTE)ptr)[(keyc-min_keycode)|0x80]=0x80;
}
@ -1682,18 +1703,18 @@ BOOL X11DRV_GetDIData(
{
/* X keycode to virtual key */
vkey = keyc2vkey[keyc] & 0xFF;
if (keystate[vkey] == (InputKeyStateTable[vkey]&0x80))
if (keystate[vkey] == (pKeyStateTable[vkey]&0x80))
continue;
if (dod) {
/* add an entry */
dod[n].dwOfs = keyc-min_keycode; /* scancode */
dod[n].dwData = InputKeyStateTable[vkey]&0x80;
dod[n].dwData = pKeyStateTable[vkey]&0x80;
dod[n].dwTimeStamp = 0; /* umm */
dod[n].dwSequence = 0; /* umm */
n++;
}
if (!(flags & DIGDD_PEEK))
keystate[vkey] = InputKeyStateTable[vkey]&0x80;
keystate[vkey] = pKeyStateTable[vkey]&0x80;
}