Moved SendInput and related functions to the USER driver to avoid a

number of dll separation hacks.
This commit is contained in:
Alexandre Julliard 2005-03-09 16:45:23 +00:00
parent 6bd194d2fd
commit aef19abc82
10 changed files with 700 additions and 708 deletions

View File

@ -83,19 +83,19 @@ static BOOL load_driver(void)
ExitProcess(1); ExitProcess(1);
} }
GET_USER_FUNC(InitKeyboard); GET_USER_FUNC(ActivateKeyboardLayout);
GET_USER_FUNC(VkKeyScanEx); GET_USER_FUNC(Beep);
GET_USER_FUNC(MapVirtualKeyEx); GET_USER_FUNC(GetAsyncKeyState);
GET_USER_FUNC(GetKeyNameText); GET_USER_FUNC(GetKeyNameText);
GET_USER_FUNC(ToUnicodeEx);
GET_USER_FUNC(GetKeyboardLayoutList);
GET_USER_FUNC(GetKeyboardLayout); GET_USER_FUNC(GetKeyboardLayout);
GET_USER_FUNC(GetKeyboardLayoutList);
GET_USER_FUNC(GetKeyboardLayoutName); GET_USER_FUNC(GetKeyboardLayoutName);
GET_USER_FUNC(LoadKeyboardLayout); GET_USER_FUNC(LoadKeyboardLayout);
GET_USER_FUNC(ActivateKeyboardLayout); GET_USER_FUNC(MapVirtualKeyEx);
GET_USER_FUNC(SendInput);
GET_USER_FUNC(ToUnicodeEx);
GET_USER_FUNC(UnloadKeyboardLayout); GET_USER_FUNC(UnloadKeyboardLayout);
GET_USER_FUNC(Beep); GET_USER_FUNC(VkKeyScanEx);
GET_USER_FUNC(InitMouse);
GET_USER_FUNC(SetCursor); GET_USER_FUNC(SetCursor);
GET_USER_FUNC(GetCursorPos); GET_USER_FUNC(GetCursorPos);
GET_USER_FUNC(SetCursorPos); GET_USER_FUNC(SetCursorPos);
@ -244,12 +244,6 @@ static BOOL process_attach(void)
/* Create desktop window */ /* Create desktop window */
if (!WIN_CreateDesktopWindow()) return FALSE; if (!WIN_CreateDesktopWindow()) return FALSE;
/* Initialize keyboard driver */
if (USER_Driver.pInitKeyboard) USER_Driver.pInitKeyboard( InputKeyStateTable );
/* Initialize mouse driver */
if (USER_Driver.pInitMouse) USER_Driver.pInitMouse( InputKeyStateTable );
return TRUE; return TRUE;
} }

View File

@ -62,23 +62,23 @@ struct tagCURSORICONINFO;
typedef struct tagUSER_DRIVER { typedef struct tagUSER_DRIVER {
/* keyboard functions */ /* keyboard functions */
void (*pInitKeyboard)(LPBYTE); HKL (*pActivateKeyboardLayout)(HKL, UINT);
SHORT (*pVkKeyScanEx)(WCHAR, HKL); void (*pBeep)(void);
UINT (*pMapVirtualKeyEx)(UINT, UINT, HKL); SHORT (*pGetAsyncKeyState)(INT);
INT (*pGetKeyNameText)(LONG, LPWSTR, INT); INT (*pGetKeyNameText)(LONG, LPWSTR, INT);
INT (*pToUnicodeEx)(UINT, UINT, LPBYTE, LPWSTR, int, UINT, HKL);
UINT (*pGetKeyboardLayoutList)(INT, HKL *);
HKL (*pGetKeyboardLayout)(DWORD); HKL (*pGetKeyboardLayout)(DWORD);
UINT (*pGetKeyboardLayoutList)(INT, HKL *);
BOOL (*pGetKeyboardLayoutName)(LPWSTR); BOOL (*pGetKeyboardLayoutName)(LPWSTR);
HKL (*pLoadKeyboardLayout)(LPCWSTR, UINT); HKL (*pLoadKeyboardLayout)(LPCWSTR, UINT);
HKL (*pActivateKeyboardLayout)(HKL, UINT); UINT (*pMapVirtualKeyEx)(UINT, UINT, HKL);
UINT (*pSendInput)(UINT, LPINPUT, int);
INT (*pToUnicodeEx)(UINT, UINT, LPBYTE, LPWSTR, int, UINT, HKL);
BOOL (*pUnloadKeyboardLayout)(HKL); BOOL (*pUnloadKeyboardLayout)(HKL);
void (*pBeep)(void); SHORT (*pVkKeyScanEx)(WCHAR, HKL);
/* mouse functions */ /* mouse functions */
void (*pInitMouse)(LPBYTE);
void (*pSetCursor)(struct tagCURSORICONINFO *); void (*pSetCursor)(struct tagCURSORICONINFO *);
void (*pGetCursorPos)(LPPOINT); BOOL (*pGetCursorPos)(LPPOINT);
void (*pSetCursorPos)(INT,INT); BOOL (*pSetCursorPos)(INT,INT);
/* screen saver functions */ /* screen saver functions */
BOOL (*pGetScreenSaveActive)(void); BOOL (*pGetScreenSaveActive)(void);
void (*pSetScreenSaveActive)(BOOL); void (*pSetScreenSaveActive)(BOOL);
@ -119,8 +119,6 @@ typedef struct tagUSER_DRIVER {
extern USER_DRIVER USER_Driver; extern USER_DRIVER USER_Driver;
extern HMODULE user32_module; extern HMODULE user32_module;
extern BYTE InputKeyStateTable[256];
extern BYTE AsyncKeyStateTable[256];
extern DWORD USER16_AlertableWait; extern DWORD USER16_AlertableWait;
extern BOOL CLIPBOARD_ReleaseOwner(void); extern BOOL CLIPBOARD_ReleaseOwner(void);

View File

@ -951,3 +951,32 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
return 0; return 0;
} }
} }
/***********************************************************************
* X11DRV_SendInput (X11DRV.@)
*/
UINT X11DRV_SendInput( UINT count, LPINPUT inputs, int size )
{
UINT i;
for (i = 0; i < count; i++, inputs++)
{
switch(inputs->type)
{
case INPUT_MOUSE:
X11DRV_send_mouse_input( 0, inputs->u.mi.dwFlags, inputs->u.mi.dx, inputs->u.mi.dy,
inputs->u.mi.mouseData, inputs->u.mi.time,
inputs->u.mi.dwExtraInfo, LLMHF_INJECTED );
break;
case INPUT_KEYBOARD:
X11DRV_send_keyboard_input( inputs->u.ki.wVk, inputs->u.ki.wScan, inputs->u.ki.dwFlags,
inputs->u.ki.time, inputs->u.ki.dwExtraInfo, LLKHF_INJECTED );
break;
case INPUT_HARDWARE:
FIXME( "INPUT_HARDWARE not supported\n" );
break;
}
}
return count;
}

View File

@ -48,17 +48,47 @@
#include "winnls.h" #include "winnls.h"
#include "win.h" #include "win.h"
#include "x11drv.h" #include "x11drv.h"
#include "wine/server.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(keyboard); WINE_DEFAULT_DEBUG_CHANNEL(keyboard);
WINE_DECLARE_DEBUG_CHANNEL(key); WINE_DECLARE_DEBUG_CHANNEL(key);
WINE_DECLARE_DEBUG_CHANNEL(dinput);
typedef union
{
struct
{
#ifndef BITFIELDS_BIGENDIAN
unsigned long count : 16;
#endif
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;
#ifdef BITFIELDS_BIGENDIAN
unsigned long count : 16;
#endif
} lp1;
unsigned long lp2;
} KEYLP;
/* key state table bits:
0x80 -> key is pressed
0x40 -> key got pressed since last time
0x01 -> key is toggled
*/
BYTE key_state_table[256];
static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYSKEYUP
or a WM_KEYUP message */
static int min_keycode, max_keycode, keysyms_per_keycode; static int min_keycode, max_keycode, keysyms_per_keycode;
static WORD keyc2vkey[256], keyc2scan[256]; static WORD keyc2vkey[256], keyc2scan[256];
static LPBYTE pKeyStateTable;
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 */
@ -1005,19 +1035,85 @@ static BOOL NumState=FALSE, CapsState=FALSE;
/*********************************************************************** /***********************************************************************
* send_keyboard_input * X11DRV_send_keyboard_input
*/ */
static void send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time ) void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time,
DWORD dwExtraInfo, UINT injected_flags )
{ {
INPUT input; UINT message;
KEYLP keylp;
KBDLLHOOKSTRUCT hook;
input.type = WINE_INTERNAL_INPUT_KEYBOARD; keylp.lp2 = 0;
input.u.ki.wVk = wVk; keylp.lp1.count = 1;
input.u.ki.wScan = wScan; keylp.lp1.code = wScan;
input.u.ki.dwFlags = dwFlags; keylp.lp1.extended = (dwFlags & KEYEVENTF_EXTENDEDKEY) != 0;
input.u.ki.time = time; keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
input.u.ki.dwExtraInfo = 0; * don't remember where I read it - AK */
SendInput( 1, &input, sizeof(input) ); /* it's '1' under windows, when a dialog box appears
* and you press one of the underlined keys - DF*/
/* note that there is a test for all this */
if (dwFlags & KEYEVENTF_KEYUP )
{
message = WM_KEYUP;
if ((key_state_table[VK_MENU] & 0x80) &&
((wVk == VK_MENU) || (wVk == VK_CONTROL) || !(key_state_table[VK_CONTROL] & 0x80)))
{
if( TrackSysKey == VK_MENU || /* <ALT>-down/<ALT>-up sequence */
(wVk != VK_MENU)) /* <ALT>-down...<something else>-up */
message = WM_SYSKEYUP;
TrackSysKey = 0;
}
key_state_table[wVk] &= ~0x80;
keylp.lp1.previous = 1;
keylp.lp1.transition = 1;
}
else
{
keylp.lp1.previous = (key_state_table[wVk] & 0x80) != 0;
keylp.lp1.transition = 0;
if (!(key_state_table[wVk] & 0x80)) key_state_table[wVk] ^= 0x01;
key_state_table[wVk] |= 0xc0;
message = WM_KEYDOWN;
if ((key_state_table[VK_MENU] & 0x80) && !(key_state_table[VK_CONTROL] & 0x80))
{
message = WM_SYSKEYDOWN;
TrackSysKey = wVk;
}
}
keylp.lp1.context = (key_state_table[VK_MENU] & 0x80) != 0; /* 1 if alt */
TRACE_(key)(" wParam=%04x, lParam=%08lx, InputKeyState=%x\n",
wVk, keylp.lp2, key_state_table[wVk] );
hook.vkCode = wVk;
hook.scanCode = wScan;
hook.flags = (keylp.lp2 >> 24) | injected_flags;
hook.time = time;
hook.dwExtraInfo = dwExtraInfo;
if (HOOK_CallHooks( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook, TRUE )) return;
SERVER_START_REQ( send_message )
{
req->id = GetCurrentThreadId();
req->type = MSG_HARDWARE;
req->flags = 0;
req->win = 0;
req->msg = message;
req->wparam = wVk;
req->lparam = keylp.lp2;
req->x = cursor_pos.x;
req->y = cursor_pos.y;
req->time = time;
req->info = dwExtraInfo;
req->timeout = -1;
req->callback = NULL;
wine_server_call( req );
}
SERVER_END_REQ;
} }
@ -1039,30 +1135,31 @@ static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, DWORD event_
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("INTERM : don\'t treat release of toggle key. InputKeyStateTable[%#x] = %#x\n",vkey,pKeyStateTable[vkey]); TRACE("INTERM : don't treat release of toggle key. key_state_table[%#x] = %#x\n",
vkey,key_state_table[vkey]);
} else } else
{ {
down = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0); down = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0);
up = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0) | KEYEVENTF_KEYUP; up = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0) | KEYEVENTF_KEYUP;
if ( pKeyStateTable[vkey] & 0x1 ) /* it was ON */ if ( key_state_table[vkey] & 0x1 ) /* it was ON */
{ {
if (Evtype!=KeyPress) if (Evtype!=KeyPress)
{ {
TRACE("ON + KeyRelease => generating DOWN and UP messages.\n"); TRACE("ON + KeyRelease => generating DOWN and UP messages.\n");
send_keyboard_input( vkey, scan, down, event_time ); X11DRV_send_keyboard_input( vkey, scan, down, event_time, 0, 0 );
send_keyboard_input( vkey, scan, up, event_time ); X11DRV_send_keyboard_input( vkey, scan, up, event_time, 0, 0 );
*State=FALSE; *State=FALSE;
pKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */ key_state_table[vkey] &= ~0x01; /* Toggle state to off. */
} }
} }
else /* it was OFF */ else /* it was OFF */
if (Evtype==KeyPress) if (Evtype==KeyPress)
{ {
TRACE("OFF + Keypress => generating DOWN and UP messages.\n"); TRACE("OFF + Keypress => generating DOWN and UP messages.\n");
send_keyboard_input( vkey, scan, down, event_time ); X11DRV_send_keyboard_input( vkey, scan, down, event_time, 0, 0 );
send_keyboard_input( vkey, scan, up, event_time ); X11DRV_send_keyboard_input( vkey, scan, up, event_time, 0, 0 );
*State=TRUE; /* Goes to intermediary state before going to ON */ *State=TRUE; /* Goes to intermediary state before going to ON */
pKeyStateTable[vkey] |= 0x01; /* Toggle state to on. */ key_state_table[vkey] |= 0x01; /* Toggle state to on. */
} }
} }
} }
@ -1076,15 +1173,15 @@ static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, DWORD event_
inline static void KEYBOARD_UpdateOneState ( int vkey, int state, DWORD time ) inline static void KEYBOARD_UpdateOneState ( int vkey, int state, DWORD time )
{ {
/* Do something if internal table state != X state for keycode */ /* Do something if internal table state != X state for keycode */
if (((pKeyStateTable[vkey] & 0x80)!=0) != state) if (((key_state_table[vkey] & 0x80)!=0) != state)
{ {
TRACE("Adjusting state for vkey %#.2x. State before %#.2x\n", TRACE("Adjusting state for vkey %#.2x. State before %#.2x\n",
vkey, pKeyStateTable[vkey]); vkey, key_state_table[vkey]);
/* Fake key being pressed inside wine */ /* Fake key being pressed inside wine */
send_keyboard_input( vkey, 0, state? 0 : KEYEVENTF_KEYUP, time ); X11DRV_send_keyboard_input( vkey, 0, state? 0 : KEYEVENTF_KEYUP, time, 0, 0 );
TRACE("State after %#.2x\n",pKeyStateTable[vkey]); TRACE("State after %#.2x\n",key_state_table[vkey]);
} }
} }
@ -1213,20 +1310,20 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, event_time ); KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, event_time );
break; break;
case VK_CAPITAL: case VK_CAPITAL:
TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,pKeyStateTable[vkey]); TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,key_state_table[vkey]);
KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, event_time ); KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, event_time );
TRACE("State after : %#.2x\n",pKeyStateTable[vkey]); TRACE("State after : %#.2x\n",key_state_table[vkey]);
break; break;
default: default:
/* Adjust the NUMLOCK state if it has been changed outside wine */ /* Adjust the NUMLOCK state if it has been changed outside wine */
if (!(pKeyStateTable[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask)) if (!(key_state_table[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
{ {
TRACE("Adjusting NumLock state.\n"); TRACE("Adjusting NumLock state.\n");
KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, event_time ); KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, event_time );
KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, event_time ); KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, 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 (!(pKeyStateTable[VK_CAPITAL] & 0x01) != !(event->state & LockMask)) if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
{ {
TRACE("Adjusting Caps Lock state.\n"); TRACE("Adjusting Caps Lock state.\n");
KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, event_time ); KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, event_time );
@ -1243,7 +1340,7 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP; if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP;
if ( vkey & 0x100 ) dwFlags |= KEYEVENTF_EXTENDEDKEY; if ( vkey & 0x100 ) dwFlags |= KEYEVENTF_EXTENDEDKEY;
send_keyboard_input( vkey & 0xff, bScan, dwFlags, event_time ); X11DRV_send_keyboard_input( vkey & 0xff, bScan, dwFlags, event_time, 0, 0 );
} }
} }
} }
@ -1359,9 +1456,9 @@ X11DRV_KEYBOARD_DetectLayout (void)
} }
/********************************************************************** /**********************************************************************
* InitKeyboard (X11DRV.@) * X11DRV_InitKeyboard
*/ */
void X11DRV_InitKeyboard( BYTE *key_state_table ) void X11DRV_InitKeyboard(void)
{ {
Display *display = thread_display(); Display *display = thread_display();
KeySym *ksp; KeySym *ksp;
@ -1374,8 +1471,6 @@ void X11DRV_InitKeyboard( BYTE *key_state_table )
char ckey[4]={0,0,0,0}; char ckey[4]={0,0,0,0};
const char (*lkey)[MAIN_LEN][4]; const char (*lkey)[MAIN_LEN][4];
pKeyStateTable = key_state_table;
wine_tsx11_lock(); wine_tsx11_lock();
XDisplayKeycodes(display, &min_keycode, &max_keycode); XDisplayKeycodes(display, &min_keycode, &max_keycode);
ksp = XGetKeyboardMapping(display, min_keycode, ksp = XGetKeyboardMapping(display, min_keycode,
@ -1572,6 +1667,19 @@ void X11DRV_InitKeyboard( BYTE *key_state_table )
} }
/**********************************************************************
* GetAsyncKeyState (X11DRV.@)
*/
SHORT X11DRV_GetAsyncKeyState(INT key)
{
SHORT retval = ((key_state_table[key] & 0x40) ? 0x0001 : 0) |
((key_state_table[key] & 0x80) ? 0x8000 : 0);
key_state_table[key] &= ~0x40;
TRACE_(key)("(%x) -> %x\n", key, retval);
return retval;
}
/*********************************************************************** /***********************************************************************
* GetKeyboardLayoutList (X11DRV.@) * GetKeyboardLayoutList (X11DRV.@)
*/ */
@ -1713,7 +1821,7 @@ void X11DRV_MappingNotify( HWND dummy, XEvent *event )
wine_tsx11_lock(); wine_tsx11_lock();
XRefreshKeyboardMapping(&event->xmapping); XRefreshKeyboardMapping(&event->xmapping);
wine_tsx11_unlock(); wine_tsx11_unlock();
X11DRV_InitKeyboard( pKeyStateTable ); X11DRV_InitKeyboard();
hwnd = GetFocus(); hwnd = GetFocus();
if (!hwnd) hwnd = GetActiveWindow(); if (!hwnd) hwnd = GetActiveWindow();

View File

@ -34,6 +34,7 @@
#include "win.h" #include "win.h"
#include "x11drv.h" #include "x11drv.h"
#include "wine/server.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(cursor); WINE_DEFAULT_DEBUG_CHANNEL(cursor);
@ -60,8 +61,7 @@ static const UINT button_up_flags[NB_BUTTONS] =
0 0
}; };
static BYTE *pKeyStateTable; POINT cursor_pos;
/*********************************************************************** /***********************************************************************
* get_coords * get_coords
@ -86,9 +86,9 @@ static inline void get_coords( HWND hwnd, Window window, int x, int y, POINT *pt
*/ */
static void update_button_state( unsigned int state ) static void update_button_state( unsigned int state )
{ {
pKeyStateTable[VK_LBUTTON] = (state & Button1Mask ? 0x80 : 0); key_state_table[VK_LBUTTON] = (state & Button1Mask ? 0x80 : 0);
pKeyStateTable[VK_MBUTTON] = (state & Button2Mask ? 0x80 : 0); key_state_table[VK_MBUTTON] = (state & Button2Mask ? 0x80 : 0);
pKeyStateTable[VK_RBUTTON] = (state & Button3Mask ? 0x80 : 0); key_state_table[VK_RBUTTON] = (state & Button3Mask ? 0x80 : 0);
} }
@ -99,38 +99,190 @@ static void update_button_state( unsigned int state )
*/ */
static void update_key_state( unsigned int state ) static void update_key_state( unsigned int state )
{ {
pKeyStateTable[VK_SHIFT] = (state & ShiftMask ? 0x80 : 0); key_state_table[VK_SHIFT] = (state & ShiftMask ? 0x80 : 0);
pKeyStateTable[VK_CONTROL] = (state & ControlMask ? 0x80 : 0); key_state_table[VK_CONTROL] = (state & ControlMask ? 0x80 : 0);
} }
/*********************************************************************** /***********************************************************************
* send_mouse_event * get_key_state
*/ */
static void send_mouse_event( HWND hwnd, DWORD flags, DWORD posX, DWORD posY, static WORD get_key_state(void)
DWORD data, Time time )
{ {
INPUT input; WORD ret = 0;
TRACE("(%04lX,%ld,%ld)\n", flags, posX, posY ); if (GetSystemMetrics( SM_SWAPBUTTON ))
{
if (key_state_table[VK_RBUTTON] & 0x80) ret |= MK_LBUTTON;
if (key_state_table[VK_LBUTTON] & 0x80) ret |= MK_RBUTTON;
}
else
{
if (key_state_table[VK_LBUTTON] & 0x80) ret |= MK_LBUTTON;
if (key_state_table[VK_RBUTTON] & 0x80) ret |= MK_RBUTTON;
}
if (key_state_table[VK_MBUTTON] & 0x80) ret |= MK_MBUTTON;
if (key_state_table[VK_SHIFT] & 0x80) ret |= MK_SHIFT;
if (key_state_table[VK_CONTROL] & 0x80) ret |= MK_CONTROL;
if (key_state_table[VK_XBUTTON1] & 0x80) ret |= MK_XBUTTON1;
if (key_state_table[VK_XBUTTON2] & 0x80) ret |= MK_XBUTTON2;
return ret;
}
/***********************************************************************
* queue_raw_mouse_message
*/
static void queue_raw_mouse_message( UINT message, HWND hwnd, DWORD x, DWORD y,
DWORD data, DWORD time, DWORD extra_info, UINT injected_flags )
{
MSLLHOOKSTRUCT hook;
hook.pt.x = x;
hook.pt.y = y;
hook.mouseData = MAKELONG( 0, data );
hook.flags = injected_flags;
hook.time = time;
hook.dwExtraInfo = extra_info;
if (HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook, TRUE )) return;
SERVER_START_REQ( send_message )
{
req->id = GetCurrentThreadId();
req->type = MSG_HARDWARE;
req->flags = 0;
req->win = hwnd;
req->msg = message;
req->wparam = MAKEWPARAM( get_key_state(), data );
req->lparam = 0;
req->x = x;
req->y = y;
req->time = time;
req->info = extra_info;
req->timeout = -1;
req->callback = NULL;
wine_server_call( req );
}
SERVER_END_REQ;
}
/***********************************************************************
* X11DRV_send_mouse_input
*/
void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
DWORD data, DWORD time, DWORD extra_info, UINT injected_flags )
{
POINT pt;
if (flags & MOUSEEVENTF_ABSOLUTE) if (flags & MOUSEEVENTF_ABSOLUTE)
{ {
int width = GetSystemMetrics( SM_CXSCREEN ); if (injected_flags & LLMHF_INJECTED)
int height = GetSystemMetrics( SM_CYSCREEN ); {
/* Relative mouse movements seem not to be scaled as absolute ones */ pt.x = (x * screen_width) >> 16;
posX = (((long)posX << 16) + width-1) / width; pt.y = (y * screen_height) >> 16;
posY = (((long)posY << 16) + height-1) / height; }
else
{
pt.x = x;
pt.y = y;
}
wine_tsx11_lock();
cursor_pos = pt;
wine_tsx11_unlock();
}
else if (flags & MOUSEEVENTF_MOVE)
{
int accel[3], xMult = 1, yMult = 1;
/* dx and dy can be negative numbers for relative movements */
SystemParametersInfoW(SPI_GETMOUSE, 0, accel, 0);
if (x > accel[0] && accel[2] != 0)
{
xMult = 2;
if ((x > accel[1]) && (accel[2] == 2)) xMult = 4;
}
if (y > accel[0] && accel[2] != 0)
{
yMult = 2;
if ((y > accel[1]) && (accel[2] == 2)) yMult = 4;
}
wine_tsx11_lock();
pt.x = cursor_pos.x + (long)x * xMult;
pt.y = cursor_pos.y + (long)y * yMult;
/* Clip to the current screen size */
if (pt.x < 0) pt.x = 0;
else if (pt.x >= screen_width) pt.x = screen_width - 1;
if (pt.y < 0) pt.y = 0;
else if (pt.y >= screen_height) pt.y = screen_height - 1;
cursor_pos = pt;
wine_tsx11_unlock();
}
else
{
wine_tsx11_lock();
pt = cursor_pos;
wine_tsx11_unlock();
} }
input.type = WINE_INTERNAL_INPUT_MOUSE; if (flags & MOUSEEVENTF_MOVE)
input.u.mi.dx = posX; {
input.u.mi.dy = posY; queue_raw_mouse_message( WM_MOUSEMOVE, hwnd, pt.x, pt.y, data, time,
input.u.mi.mouseData = data; extra_info, injected_flags );
input.u.mi.dwFlags = flags; if (injected_flags & LLMHF_INJECTED) /* we have to actually move the cursor */
input.u.mi.time = EVENT_x11_time_to_win32_time(time); {
input.u.mi.dwExtraInfo = (ULONG_PTR)hwnd; TRACE( "warping to (%ld,%ld)\n", pt.x, pt.y );
SendInput( 1, &input, sizeof(input) ); wine_tsx11_lock();
XWarpPointer( thread_display(), root_window, root_window, 0, 0, 0, 0, pt.x, pt.y );
wine_tsx11_unlock();
}
}
if (flags & MOUSEEVENTF_LEFTDOWN)
{
key_state_table[VK_LBUTTON] |= 0xc0;
queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONDOWN : WM_LBUTTONDOWN,
hwnd, pt.x, pt.y, data, time, extra_info, injected_flags );
}
if (flags & MOUSEEVENTF_LEFTUP)
{
key_state_table[VK_LBUTTON] &= ~0x80;
queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONUP : WM_LBUTTONUP,
hwnd, pt.x, pt.y, data, time, extra_info, injected_flags );
}
if (flags & MOUSEEVENTF_RIGHTDOWN)
{
key_state_table[VK_RBUTTON] |= 0xc0;
queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN,
hwnd, pt.x, pt.y, data, time, extra_info, injected_flags );
}
if (flags & MOUSEEVENTF_RIGHTUP)
{
key_state_table[VK_RBUTTON] &= ~0x80;
queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONUP : WM_RBUTTONUP,
hwnd, pt.x, pt.y, data, time, extra_info, injected_flags );
}
if (flags & MOUSEEVENTF_MIDDLEDOWN)
{
key_state_table[VK_MBUTTON] |= 0xc0;
queue_raw_mouse_message( WM_MBUTTONDOWN, hwnd, pt.x, pt.y, data, time,
extra_info, injected_flags );
}
if (flags & MOUSEEVENTF_MIDDLEUP)
{
key_state_table[VK_MBUTTON] &= ~0x80;
queue_raw_mouse_message( WM_MBUTTONUP, hwnd, pt.x, pt.y, data, time,
extra_info, injected_flags );
}
if (flags & MOUSEEVENTF_WHEEL)
{
queue_raw_mouse_message( WM_MOUSEWHEEL, hwnd, pt.x, pt.y, data, time,
extra_info, injected_flags );
}
} }
@ -489,7 +641,7 @@ void X11DRV_SetCursor( CURSORICONINFO *lpCursor )
/*********************************************************************** /***********************************************************************
* SetCursorPos (X11DRV.@) * SetCursorPos (X11DRV.@)
*/ */
void X11DRV_SetCursorPos( INT x, INT y ) BOOL X11DRV_SetCursorPos( INT x, INT y )
{ {
Display *display = thread_display(); Display *display = thread_display();
@ -497,42 +649,37 @@ void X11DRV_SetCursorPos( INT x, INT y )
wine_tsx11_lock(); wine_tsx11_lock();
XWarpPointer( display, root_window, root_window, 0, 0, 0, 0, x, y ); XWarpPointer( display, root_window, root_window, 0, 0, 0, 0, x, y );
XFlush( display ); /* just in case */ cursor_pos.x = x;
cursor_pos.y = y;
wine_tsx11_unlock(); wine_tsx11_unlock();
return TRUE;
} }
/*********************************************************************** /***********************************************************************
* GetCursorPos (X11DRV.@) * GetCursorPos (X11DRV.@)
*/ */
void X11DRV_GetCursorPos(LPPOINT pos) BOOL X11DRV_GetCursorPos(LPPOINT pos)
{ {
Display *display = thread_display(); Display *display = thread_display();
Window root, child; Window root, child;
int rootX, rootY, winX, winY; int rootX, rootY, winX, winY;
unsigned int xstate; unsigned int xstate;
wine_tsx11_lock(); wine_tsx11_lock();
if (XQueryPointer( display, root_window, &root, &child, if (XQueryPointer( display, root_window, &root, &child,
&rootX, &rootY, &winX, &winY, &xstate )) &rootX, &rootY, &winX, &winY, &xstate ))
{ {
update_key_state( xstate ); update_key_state( xstate );
update_button_state( xstate ); update_button_state( xstate );
TRACE("pointer at (%d,%d)\n", winX, winY ); TRACE("pointer at (%d,%d)\n", winX, winY );
pos->x = winX; cursor_pos.x = winX;
pos->y = winY; cursor_pos.y = winY;
} }
wine_tsx11_unlock(); *pos = cursor_pos;
wine_tsx11_unlock();
return TRUE;
} }
/***********************************************************************
* InitMouse (X11DRV.@)
*/
void X11DRV_InitMouse( BYTE *key_state_table )
{
pKeyStateTable = key_state_table;
}
/*********************************************************************** /***********************************************************************
* X11DRV_ButtonPress * X11DRV_ButtonPress
*/ */
@ -559,8 +706,8 @@ void X11DRV_ButtonPress( HWND hwnd, XEvent *xev )
break; break;
} }
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( hwnd, button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE, X11DRV_send_mouse_input( hwnd, button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE,
pt.x, pt.y, wData, event->time ); pt.x, pt.y, wData, EVENT_x11_time_to_win32_time(event->time), 0, 0 );
} }
@ -579,8 +726,8 @@ void X11DRV_ButtonRelease( HWND hwnd, XEvent *xev )
update_cursor( hwnd, event->window ); update_cursor( hwnd, event->window );
get_coords( hwnd, event->window, event->x, event->y, &pt ); get_coords( hwnd, event->window, event->x, event->y, &pt );
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( hwnd, button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE, X11DRV_send_mouse_input( hwnd, button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE,
pt.x, pt.y, 0, event->time ); pt.x, pt.y, 0, EVENT_x11_time_to_win32_time(event->time), 0, 0 );
} }
@ -599,8 +746,8 @@ void X11DRV_MotionNotify( HWND hwnd, XEvent *xev )
update_cursor( hwnd, event->window ); update_cursor( hwnd, event->window );
get_coords( hwnd, event->window, event->x, event->y, &pt ); get_coords( hwnd, event->window, event->x, event->y, &pt );
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, X11DRV_send_mouse_input( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
pt.x, pt.y, 0, event->time ); pt.x, pt.y, 0, EVENT_x11_time_to_win32_time(event->time), 0, 0 );
} }
@ -621,8 +768,8 @@ void X11DRV_EnterNotify( HWND hwnd, XEvent *xev )
update_cursor( hwnd, event->window ); update_cursor( hwnd, event->window );
get_coords( hwnd, event->window, event->x, event->y, &pt ); get_coords( hwnd, event->window, event->x, event->y, &pt );
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, X11DRV_send_mouse_input( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
pt.x, pt.y, 0, event->time ); pt.x, pt.y, 0, EVENT_x11_time_to_win32_time(event->time), 0, 0 );
} }
@ -637,7 +784,8 @@ void X11DRV_DGAMotionEvent( HWND hwnd, XEvent *xev )
{ {
XDGAMotionEvent *event = (XDGAMotionEvent *)xev; XDGAMotionEvent *event = (XDGAMotionEvent *)xev;
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( DGAhwnd, MOUSEEVENTF_MOVE, event->dx, event->dy, 0, event->time ); X11DRV_send_mouse_input( DGAhwnd, MOUSEEVENTF_MOVE, event->dx, event->dy,
0, EVENT_x11_time_to_win32_time(event->time), 0, 0 );
} }
/********************************************************************** /**********************************************************************
@ -650,7 +798,8 @@ void X11DRV_DGAButtonPressEvent( HWND hwnd, XEvent *xev )
if (buttonNum >= NB_BUTTONS) return; if (buttonNum >= NB_BUTTONS) return;
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( DGAhwnd, button_down_flags[buttonNum], 0, 0, 0, event->time ); X11DRV_send_mouse_input( DGAhwnd, button_down_flags[buttonNum], 0, 0,
0, EVENT_x11_time_to_win32_time(event->time), 0, 0 );
} }
/********************************************************************** /**********************************************************************
@ -663,7 +812,8 @@ void X11DRV_DGAButtonReleaseEvent( HWND hwnd, XEvent *xev )
if (buttonNum >= NB_BUTTONS) return; if (buttonNum >= NB_BUTTONS) return;
update_key_state( event->state ); update_key_state( event->state );
send_mouse_event( DGAhwnd, button_up_flags[buttonNum], 0, 0, 0, event->time ); X11DRV_send_mouse_input( DGAhwnd, button_up_flags[buttonNum], 0, 0,
0, EVENT_x11_time_to_win32_time(event->time), 0, 0 );
} }
#endif /* HAVE_LIBXXF86DGA2 */ #endif /* HAVE_LIBXXF86DGA2 */

View File

@ -287,271 +287,6 @@ typedef struct
/* DIB Section sync state */ /* DIB Section sync state */
enum { DIB_Status_None, DIB_Status_InSync, DIB_Status_GdiMod, DIB_Status_AppMod, DIB_Status_AuxMod }; enum { DIB_Status_None, DIB_Status_InSync, DIB_Status_GdiMod, DIB_Status_AppMod, DIB_Status_AuxMod };
extern int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse,
WORD depth, const BITMAPINFO *info,
int *nColors );
extern INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev,INT,BOOL);
extern INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev,INT,BOOL);
extern void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev,BOOL);
extern INT X11DRV_CoerceDIBSection2(HBITMAP bmp,INT,BOOL);
extern INT X11DRV_LockDIBSection2(HBITMAP bmp,INT,BOOL);
extern void X11DRV_UnlockDIBSection2(HBITMAP bmp,BOOL);
extern HBITMAP X11DRV_DIB_CreateDIBSection(X11DRV_PDEVICE *physDev, const BITMAPINFO *bmi, UINT usage,
VOID **bits, HANDLE section, DWORD offset, DWORD ovr_pitch);
extern void X11DRV_DIB_DeleteDIBSection(struct tagBITMAPOBJ *bmp);
extern INT X11DRV_DIB_Coerce(struct tagBITMAPOBJ *,INT,BOOL);
extern INT X11DRV_DIB_Lock(struct tagBITMAPOBJ *,INT,BOOL);
extern void X11DRV_DIB_Unlock(struct tagBITMAPOBJ *,BOOL);
void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
DWORD width, DWORD height);
struct _DCICMD;
extern INT X11DRV_DCICommand(INT cbInput, const struct _DCICMD *lpCmd, LPVOID lpOutData);
/**************************************************************************
* X11 GDI driver
*/
extern void X11DRV_GDI_Initialize( Display *display );
extern void X11DRV_GDI_Finalize(void);
extern Display *gdi_display; /* display to use for all GDI functions */
/* X11 GDI palette driver */
#define X11DRV_PALETTE_FIXED 0x0001 /* read-only colormap - have to use XAllocColor (if not virtual) */
#define X11DRV_PALETTE_VIRTUAL 0x0002 /* no mapping needed - pixel == pixel color */
#define X11DRV_PALETTE_PRIVATE 0x1000 /* private colormap, identity mapping */
#define X11DRV_PALETTE_WHITESET 0x2000
extern Colormap X11DRV_PALETTE_PaletteXColormap;
extern UINT16 X11DRV_PALETTE_PaletteFlags;
extern int *X11DRV_PALETTE_PaletteToXPixel;
extern int *X11DRV_PALETTE_XPixelToPalette;
extern int X11DRV_PALETTE_mapEGAPixel[16];
extern int X11DRV_PALETTE_Init(void);
extern void X11DRV_PALETTE_Cleanup(void);
extern BOOL X11DRV_IsSolidColor(COLORREF color);
extern COLORREF X11DRV_PALETTE_ToLogical(int pixel);
extern int X11DRV_PALETTE_ToPhysical(X11DRV_PDEVICE *physDev, COLORREF color);
/* GDI escapes */
#define X11DRV_ESCAPE 6789
enum x11drv_escape_codes
{
X11DRV_GET_DISPLAY, /* get X11 display for a DC */
X11DRV_GET_DRAWABLE, /* get current drawable for a DC */
X11DRV_GET_FONT, /* get current X font for a DC */
X11DRV_SET_DRAWABLE, /* set current drawable for a DC */
X11DRV_START_EXPOSURES, /* start graphics exposures */
X11DRV_END_EXPOSURES, /* end graphics exposures */
};
struct x11drv_escape_set_drawable
{
enum x11drv_escape_codes code; /* escape code (X11DRV_SET_DRAWABLE) */
Drawable drawable; /* X drawable */
int mode; /* ClipByChildren or IncludeInferiors */
POINT org; /* origin of DC relative to drawable */
POINT drawable_org; /* origin of drawable relative to screen */
};
/**************************************************************************
* X11 USER driver
*/
struct x11drv_thread_data
{
Display *display;
HANDLE display_fd;
int process_event_count; /* recursion count for event processing */
Cursor cursor; /* current cursor */
Window cursor_window; /* current window that contains the cursor */
HWND last_focus; /* last window that had focus */
XIM xim; /* input method */
Window selection_wnd; /* window used for selection interactions */
};
extern struct x11drv_thread_data *x11drv_init_thread_data(void);
inline static struct x11drv_thread_data *x11drv_thread_data(void)
{
struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
if (!data) data = x11drv_init_thread_data();
return data;
}
inline static Display *thread_display(void) { return x11drv_thread_data()->display; }
extern Visual *visual;
extern Window root_window;
extern DWORD desktop_tid;
extern unsigned int screen_width;
extern unsigned int screen_height;
extern unsigned int screen_depth;
extern unsigned int text_caps;
extern int use_xkb;
extern int use_take_focus;
extern int managed_mode;
/* atoms */
enum x11drv_atoms
{
FIRST_XATOM = XA_LAST_PREDEFINED + 1,
XATOM_CLIPBOARD = FIRST_XATOM,
XATOM_COMPOUND_TEXT,
XATOM_MULTIPLE,
XATOM_SELECTION_DATA,
XATOM_TARGETS,
XATOM_TEXT,
XATOM_UTF8_STRING,
XATOM_RAW_ASCENT,
XATOM_RAW_DESCENT,
XATOM_RAW_CAP_HEIGHT,
XATOM_WM_PROTOCOLS,
XATOM_WM_DELETE_WINDOW,
XATOM_WM_TAKE_FOCUS,
XATOM_KWM_DOCKWINDOW,
XATOM_DndProtocol,
XATOM_DndSelection,
XATOM__MOTIF_WM_HINTS,
XATOM__KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
XATOM__NET_WM_MOVERESIZE,
XATOM__NET_WM_PID,
XATOM__NET_WM_PING,
XATOM__NET_WM_NAME,
XATOM__NET_WM_WINDOW_TYPE,
XATOM__NET_WM_WINDOW_TYPE_UTILITY,
XATOM_XdndAware,
XATOM_XdndEnter,
XATOM_XdndPosition,
XATOM_XdndStatus,
XATOM_XdndLeave,
XATOM_XdndFinished,
XATOM_XdndDrop,
XATOM_XdndActionCopy,
XATOM_XdndActionMove,
XATOM_XdndActionLink,
XATOM_XdndActionAsk,
XATOM_XdndActionPrivate,
XATOM_XdndSelection,
XATOM_XdndTarget,
XATOM_XdndTypeList,
XATOM_WCF_DIB,
XATOM_image_gif,
XATOM_text_html,
XATOM_text_plain,
XATOM_text_rtf,
XATOM_text_richtext,
NB_XATOMS
};
extern Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
#define x11drv_atom(name) (X11DRV_Atoms[XATOM_##name - FIRST_XATOM])
/* X11 event driver */
typedef void (*x11drv_event_handler)( HWND hwnd, XEvent *event );
extern void X11DRV_register_event_handler( int type, x11drv_event_handler handler );
extern void X11DRV_ButtonPress( HWND hwnd, XEvent *event );
extern void X11DRV_ButtonRelease( HWND hwnd, XEvent *event );
extern void X11DRV_MotionNotify( HWND hwnd, XEvent *event );
extern void X11DRV_EnterNotify( HWND hwnd, XEvent *event );
extern void X11DRV_KeyEvent( HWND hwnd, XEvent *event );
extern void X11DRV_KeymapNotify( HWND hwnd, XEvent *event );
extern void X11DRV_Expose( HWND hwnd, XEvent *event );
extern void X11DRV_MapNotify( HWND hwnd, XEvent *event );
extern void X11DRV_UnmapNotify( HWND hwnd, XEvent *event );
extern void X11DRV_ConfigureNotify( HWND hwnd, XEvent *event );
extern void X11DRV_SelectionRequest( HWND hWnd, XEvent *event );
extern void X11DRV_SelectionClear( HWND hWnd, XEvent *event );
extern void X11DRV_MappingNotify( HWND hWnd, XEvent *event );
extern void X11DRV_DGAMotionEvent( HWND hwnd, XEvent *event );
extern void X11DRV_DGAButtonPressEvent( HWND hwnd, XEvent *event );
extern void X11DRV_DGAButtonReleaseEvent( HWND hwnd, XEvent *event );
extern DWORD EVENT_x11_time_to_win32_time(Time time);
/* X11 driver private messages, must be in the range 0x80001000..0x80001fff */
enum x11drv_window_messages
{
WM_X11DRV_ACQUIRE_SELECTION = 0x80001000
};
/* x11drv private window data */
struct x11drv_win_data
{
HWND hwnd; /* hwnd that this private data belongs to */
Window whole_window; /* X window for the complete window */
Window icon_window; /* X window for the icon */
RECT window_rect; /* USER window rectangle relative to parent */
RECT whole_rect; /* X window rectangle for the whole window relative to parent */
RECT client_rect; /* client area relative to whole window */
XIC xic; /* X input context */
BOOL managed; /* is window managed? */
HBITMAP hWMIconBitmap;
HBITMAP hWMIconMask;
};
extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd );
extern POINT X11DRV_get_client_area_offset( HWND hwnd );
extern Window X11DRV_get_whole_window( HWND hwnd );
extern BOOL X11DRV_is_window_rect_mapped( const RECT *rect );
extern XIC X11DRV_get_ic( HWND hwnd );
/* X context to associate a hwnd to an X window */
extern XContext winContext;
extern void X11DRV_InitClipboard(void);
extern void X11DRV_AcquireClipboard(HWND hWndClipWindow);
extern void X11DRV_SetFocus( HWND hwnd );
extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
typedef int (*x11drv_error_callback)( Display *display, XErrorEvent *event, void *arg );
extern void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg );
extern int X11DRV_check_error(void);
extern void X11DRV_set_iconic_state( HWND hwnd );
extern void X11DRV_window_to_X_rect( struct x11drv_win_data *data, RECT *rect );
extern void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect );
extern void X11DRV_create_desktop_thread(void);
extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry );
extern void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data );
extern void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data,
UINT swp_flags, const RECT *new_client_rect,
const RECT *new_whole_rect );
extern BOOL X11DRV_set_window_pos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
const RECT *rectClient, UINT swp_flags, const RECT *validRects );
extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data );
extern void X11DRV_handle_desktop_resize(unsigned int width, unsigned int height);
extern void X11DRV_Settings_AddDepthModes(void);
extern void X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigned int bpp, unsigned int freq);
extern int X11DRV_Settings_CreateDriver(LPDDHALINFO info);
extern LPDDHALMODEINFO X11DRV_Settings_CreateModes(unsigned int max_modes, int reserve_depths);
unsigned int X11DRV_Settings_GetModeCount(void);
void X11DRV_Settings_Init(void);
extern void X11DRV_Settings_SetDefaultMode(int mode);
LPDDHALMODEINFO X11DRV_Settings_SetHandlers(const char *name,
int (*pNewGCM)(void),
void (*pNewSCM)(int),
unsigned int nmodes,
int reserve_depths);
typedef struct { typedef struct {
void (*Convert_5x5_asis)(int width, int height, void (*Convert_5x5_asis)(int width, int height,
const void* srcbits, int srclinebytes, const void* srcbits, int srclinebytes,
@ -682,5 +417,275 @@ typedef struct {
extern const dib_conversions dib_normal, dib_src_byteswap, dib_dst_byteswap; extern const dib_conversions dib_normal, dib_src_byteswap, dib_dst_byteswap;
extern INT X11DRV_DIB_MaskToShift(DWORD mask); extern INT X11DRV_DIB_MaskToShift(DWORD mask);
extern int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse,
WORD depth, const BITMAPINFO *info,
int *nColors );
extern INT X11DRV_CoerceDIBSection(X11DRV_PDEVICE *physDev,INT,BOOL);
extern INT X11DRV_LockDIBSection(X11DRV_PDEVICE *physDev,INT,BOOL);
extern void X11DRV_UnlockDIBSection(X11DRV_PDEVICE *physDev,BOOL);
extern INT X11DRV_CoerceDIBSection2(HBITMAP bmp,INT,BOOL);
extern INT X11DRV_LockDIBSection2(HBITMAP bmp,INT,BOOL);
extern void X11DRV_UnlockDIBSection2(HBITMAP bmp,BOOL);
extern HBITMAP X11DRV_DIB_CreateDIBSection(X11DRV_PDEVICE *physDev, const BITMAPINFO *bmi, UINT usage,
VOID **bits, HANDLE section, DWORD offset, DWORD ovr_pitch);
extern void X11DRV_DIB_DeleteDIBSection(struct tagBITMAPOBJ *bmp);
extern INT X11DRV_DIB_Coerce(struct tagBITMAPOBJ *,INT,BOOL);
extern INT X11DRV_DIB_Lock(struct tagBITMAPOBJ *,INT,BOOL);
extern void X11DRV_DIB_Unlock(struct tagBITMAPOBJ *,BOOL);
void X11DRV_DIB_CopyDIBSection(X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDevDst,
DWORD xSrc, DWORD ySrc, DWORD xDest, DWORD yDest,
DWORD width, DWORD height);
struct _DCICMD;
extern INT X11DRV_DCICommand(INT cbInput, const struct _DCICMD *lpCmd, LPVOID lpOutData);
/**************************************************************************
* X11 GDI driver
*/
extern void X11DRV_GDI_Initialize( Display *display );
extern void X11DRV_GDI_Finalize(void);
extern Display *gdi_display; /* display to use for all GDI functions */
/* X11 GDI palette driver */
#define X11DRV_PALETTE_FIXED 0x0001 /* read-only colormap - have to use XAllocColor (if not virtual) */
#define X11DRV_PALETTE_VIRTUAL 0x0002 /* no mapping needed - pixel == pixel color */
#define X11DRV_PALETTE_PRIVATE 0x1000 /* private colormap, identity mapping */
#define X11DRV_PALETTE_WHITESET 0x2000
extern Colormap X11DRV_PALETTE_PaletteXColormap;
extern UINT16 X11DRV_PALETTE_PaletteFlags;
extern int *X11DRV_PALETTE_PaletteToXPixel;
extern int *X11DRV_PALETTE_XPixelToPalette;
extern int X11DRV_PALETTE_mapEGAPixel[16];
extern int X11DRV_PALETTE_Init(void);
extern void X11DRV_PALETTE_Cleanup(void);
extern BOOL X11DRV_IsSolidColor(COLORREF color);
extern COLORREF X11DRV_PALETTE_ToLogical(int pixel);
extern int X11DRV_PALETTE_ToPhysical(X11DRV_PDEVICE *physDev, COLORREF color);
/* GDI escapes */
#define X11DRV_ESCAPE 6789
enum x11drv_escape_codes
{
X11DRV_GET_DISPLAY, /* get X11 display for a DC */
X11DRV_GET_DRAWABLE, /* get current drawable for a DC */
X11DRV_GET_FONT, /* get current X font for a DC */
X11DRV_SET_DRAWABLE, /* set current drawable for a DC */
X11DRV_START_EXPOSURES, /* start graphics exposures */
X11DRV_END_EXPOSURES, /* end graphics exposures */
};
struct x11drv_escape_set_drawable
{
enum x11drv_escape_codes code; /* escape code (X11DRV_SET_DRAWABLE) */
Drawable drawable; /* X drawable */
int mode; /* ClipByChildren or IncludeInferiors */
POINT org; /* origin of DC relative to drawable */
POINT drawable_org; /* origin of drawable relative to screen */
};
/**************************************************************************
* X11 USER driver
*/
struct x11drv_thread_data
{
Display *display;
HANDLE display_fd;
int process_event_count; /* recursion count for event processing */
Cursor cursor; /* current cursor */
Window cursor_window; /* current window that contains the cursor */
HWND last_focus; /* last window that had focus */
XIM xim; /* input method */
Window selection_wnd; /* window used for selection interactions */
};
extern struct x11drv_thread_data *x11drv_init_thread_data(void);
inline static struct x11drv_thread_data *x11drv_thread_data(void)
{
struct x11drv_thread_data *data = NtCurrentTeb()->driver_data;
if (!data) data = x11drv_init_thread_data();
return data;
}
inline static Display *thread_display(void) { return x11drv_thread_data()->display; }
extern Visual *visual;
extern Window root_window;
extern DWORD desktop_tid;
extern unsigned int screen_width;
extern unsigned int screen_height;
extern unsigned int screen_depth;
extern unsigned int text_caps;
extern int use_xkb;
extern int use_take_focus;
extern int managed_mode;
extern BYTE key_state_table[256];
extern POINT cursor_pos;
/* atoms */
enum x11drv_atoms
{
FIRST_XATOM = XA_LAST_PREDEFINED + 1,
XATOM_CLIPBOARD = FIRST_XATOM,
XATOM_COMPOUND_TEXT,
XATOM_MULTIPLE,
XATOM_SELECTION_DATA,
XATOM_TARGETS,
XATOM_TEXT,
XATOM_UTF8_STRING,
XATOM_RAW_ASCENT,
XATOM_RAW_DESCENT,
XATOM_RAW_CAP_HEIGHT,
XATOM_WM_PROTOCOLS,
XATOM_WM_DELETE_WINDOW,
XATOM_WM_TAKE_FOCUS,
XATOM_KWM_DOCKWINDOW,
XATOM_DndProtocol,
XATOM_DndSelection,
XATOM__MOTIF_WM_HINTS,
XATOM__KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR,
XATOM__NET_WM_MOVERESIZE,
XATOM__NET_WM_PID,
XATOM__NET_WM_PING,
XATOM__NET_WM_NAME,
XATOM__NET_WM_WINDOW_TYPE,
XATOM__NET_WM_WINDOW_TYPE_UTILITY,
XATOM_XdndAware,
XATOM_XdndEnter,
XATOM_XdndPosition,
XATOM_XdndStatus,
XATOM_XdndLeave,
XATOM_XdndFinished,
XATOM_XdndDrop,
XATOM_XdndActionCopy,
XATOM_XdndActionMove,
XATOM_XdndActionLink,
XATOM_XdndActionAsk,
XATOM_XdndActionPrivate,
XATOM_XdndSelection,
XATOM_XdndTarget,
XATOM_XdndTypeList,
XATOM_WCF_DIB,
XATOM_image_gif,
XATOM_text_html,
XATOM_text_plain,
XATOM_text_rtf,
XATOM_text_richtext,
NB_XATOMS
};
extern Atom X11DRV_Atoms[NB_XATOMS - FIRST_XATOM];
#define x11drv_atom(name) (X11DRV_Atoms[XATOM_##name - FIRST_XATOM])
/* X11 event driver */
typedef void (*x11drv_event_handler)( HWND hwnd, XEvent *event );
extern void X11DRV_register_event_handler( int type, x11drv_event_handler handler );
extern void X11DRV_ButtonPress( HWND hwnd, XEvent *event );
extern void X11DRV_ButtonRelease( HWND hwnd, XEvent *event );
extern void X11DRV_MotionNotify( HWND hwnd, XEvent *event );
extern void X11DRV_EnterNotify( HWND hwnd, XEvent *event );
extern void X11DRV_KeyEvent( HWND hwnd, XEvent *event );
extern void X11DRV_KeymapNotify( HWND hwnd, XEvent *event );
extern void X11DRV_Expose( HWND hwnd, XEvent *event );
extern void X11DRV_MapNotify( HWND hwnd, XEvent *event );
extern void X11DRV_UnmapNotify( HWND hwnd, XEvent *event );
extern void X11DRV_ConfigureNotify( HWND hwnd, XEvent *event );
extern void X11DRV_SelectionRequest( HWND hWnd, XEvent *event );
extern void X11DRV_SelectionClear( HWND hWnd, XEvent *event );
extern void X11DRV_MappingNotify( HWND hWnd, XEvent *event );
extern void X11DRV_DGAMotionEvent( HWND hwnd, XEvent *event );
extern void X11DRV_DGAButtonPressEvent( HWND hwnd, XEvent *event );
extern void X11DRV_DGAButtonReleaseEvent( HWND hwnd, XEvent *event );
extern DWORD EVENT_x11_time_to_win32_time(Time time);
/* X11 driver private messages, must be in the range 0x80001000..0x80001fff */
enum x11drv_window_messages
{
WM_X11DRV_ACQUIRE_SELECTION = 0x80001000
};
/* x11drv private window data */
struct x11drv_win_data
{
HWND hwnd; /* hwnd that this private data belongs to */
Window whole_window; /* X window for the complete window */
Window icon_window; /* X window for the icon */
RECT window_rect; /* USER window rectangle relative to parent */
RECT whole_rect; /* X window rectangle for the whole window relative to parent */
RECT client_rect; /* client area relative to whole window */
XIC xic; /* X input context */
BOOL managed; /* is window managed? */
HBITMAP hWMIconBitmap;
HBITMAP hWMIconMask;
};
extern struct x11drv_win_data *X11DRV_get_win_data( HWND hwnd );
extern POINT X11DRV_get_client_area_offset( HWND hwnd );
extern Window X11DRV_get_whole_window( HWND hwnd );
extern BOOL X11DRV_is_window_rect_mapped( const RECT *rect );
extern XIC X11DRV_get_ic( HWND hwnd );
/* X context to associate a hwnd to an X window */
extern XContext winContext;
extern void X11DRV_InitClipboard(void);
extern void X11DRV_AcquireClipboard(HWND hWndClipWindow);
extern void X11DRV_SetFocus( HWND hwnd );
extern Cursor X11DRV_GetCursor( Display *display, struct tagCURSORICONINFO *ptr );
extern void X11DRV_InitKeyboard(void);
extern void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time,
DWORD dwExtraInfo, UINT injected_flags );
extern void X11DRV_send_mouse_input( HWND hwnd, DWORD flags, DWORD x, DWORD y,
DWORD data, DWORD time, DWORD extra_info, UINT injected_flags );
typedef int (*x11drv_error_callback)( Display *display, XErrorEvent *event, void *arg );
extern void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg );
extern int X11DRV_check_error(void);
extern void X11DRV_set_iconic_state( HWND hwnd );
extern void X11DRV_window_to_X_rect( struct x11drv_win_data *data, RECT *rect );
extern void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect );
extern void X11DRV_create_desktop_thread(void);
extern Window X11DRV_create_desktop( XVisualInfo *desktop_vi, const char *geometry );
extern void X11DRV_sync_window_style( Display *display, struct x11drv_win_data *data );
extern void X11DRV_sync_window_position( Display *display, struct x11drv_win_data *data,
UINT swp_flags, const RECT *new_client_rect,
const RECT *new_whole_rect );
extern BOOL X11DRV_set_window_pos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
const RECT *rectClient, UINT swp_flags, const RECT *validRects );
extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data );
extern void X11DRV_handle_desktop_resize(unsigned int width, unsigned int height);
extern void X11DRV_Settings_AddDepthModes(void);
extern void X11DRV_Settings_AddOneMode(unsigned int width, unsigned int height, unsigned int bpp, unsigned int freq);
extern int X11DRV_Settings_CreateDriver(LPDDHALINFO info);
extern LPDDHALMODEINFO X11DRV_Settings_CreateModes(unsigned int max_modes, int reserve_depths);
unsigned int X11DRV_Settings_GetModeCount(void);
void X11DRV_Settings_Init(void);
extern void X11DRV_Settings_SetDefaultMode(int mode);
LPDDHALMODEINFO X11DRV_Settings_SetHandlers(const char *name,
int (*pNewGCM)(void),
void (*pNewSCM)(int),
unsigned int nmodes,
int reserve_depths);
#endif /* __WINE_X11DRV_H */ #endif /* __WINE_X11DRV_H */

View File

@ -63,19 +63,19 @@
# USER driver # USER driver
@ cdecl InitKeyboard(ptr) X11DRV_InitKeyboard @ cdecl ActivateKeyboardLayout(long long) X11DRV_ActivateKeyboardLayout
@ cdecl VkKeyScanEx(long long) X11DRV_VkKeyScanEx @ cdecl Beep() X11DRV_Beep
@ cdecl MapVirtualKeyEx(long long long) X11DRV_MapVirtualKeyEx @ cdecl GetAsyncKeyState(long) X11DRV_GetAsyncKeyState
@ cdecl GetKeyNameText(long ptr long) X11DRV_GetKeyNameText @ cdecl GetKeyNameText(long ptr long) X11DRV_GetKeyNameText
@ cdecl ToUnicodeEx(long long ptr ptr long long long) X11DRV_ToUnicodeEx
@ cdecl GetKeyboardLayoutList(long ptr) X11DRV_GetKeyboardLayoutList
@ cdecl GetKeyboardLayout(long) X11DRV_GetKeyboardLayout @ cdecl GetKeyboardLayout(long) X11DRV_GetKeyboardLayout
@ cdecl GetKeyboardLayoutList(long ptr) X11DRV_GetKeyboardLayoutList
@ cdecl GetKeyboardLayoutName(ptr) X11DRV_GetKeyboardLayoutName @ cdecl GetKeyboardLayoutName(ptr) X11DRV_GetKeyboardLayoutName
@ cdecl LoadKeyboardLayout(wstr long) X11DRV_LoadKeyboardLayout @ cdecl LoadKeyboardLayout(wstr long) X11DRV_LoadKeyboardLayout
@ cdecl ActivateKeyboardLayout(long long) X11DRV_ActivateKeyboardLayout @ cdecl MapVirtualKeyEx(long long long) X11DRV_MapVirtualKeyEx
@ cdecl SendInput(long ptr long) X11DRV_SendInput
@ cdecl ToUnicodeEx(long long ptr ptr long long long) X11DRV_ToUnicodeEx
@ cdecl UnloadKeyboardLayout(long) X11DRV_UnloadKeyboardLayout @ cdecl UnloadKeyboardLayout(long) X11DRV_UnloadKeyboardLayout
@ cdecl Beep() X11DRV_Beep @ cdecl VkKeyScanEx(long long) X11DRV_VkKeyScanEx
@ cdecl InitMouse(ptr) X11DRV_InitMouse
@ cdecl SetCursor(ptr) X11DRV_SetCursor @ cdecl SetCursor(ptr) X11DRV_SetCursor
@ cdecl GetCursorPos(ptr) X11DRV_GetCursorPos @ cdecl GetCursorPos(ptr) X11DRV_GetCursorPos
@ cdecl SetCursorPos(long long) X11DRV_SetCursorPos @ cdecl SetCursorPos(long long) X11DRV_SetCursorPos

View File

@ -394,6 +394,8 @@ static BOOL process_attach(void)
X11DRV_XF86DGA2_Init(); X11DRV_XF86DGA2_Init();
#endif #endif
X11DRV_InitKeyboard();
return TRUE; return TRUE;
} }

View File

@ -95,10 +95,6 @@ extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL );
extern HWND *WIN_ListChildren( HWND hwnd ); extern HWND *WIN_ListChildren( HWND hwnd );
extern void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id ); extern void MDI_CalcDefaultChildPos( HWND hwndClient, INT total, LPPOINT lpPos, INT delta, UINT *id );
/* internal SendInput codes (FIXME) */
#define WINE_INTERNAL_INPUT_MOUSE (16+INPUT_MOUSE)
#define WINE_INTERNAL_INPUT_KEYBOARD (16+INPUT_KEYBOARD)
/* user lock */ /* user lock */
extern void USER_Lock(void); extern void USER_Lock(void);
extern void USER_Unlock(void); extern void USER_Unlock(void);

View File

@ -40,46 +40,14 @@
#include "winuser.h" #include "winuser.h"
#include "winnls.h" #include "winnls.h"
#include "wine/server.h" #include "wine/server.h"
#include "win.h"
#include "message.h" #include "message.h"
#include "user_private.h" #include "user_private.h"
#include "winternl.h" #include "winternl.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "winerror.h" #include "winerror.h"
WINE_DECLARE_DEBUG_CHANNEL(key); WINE_DEFAULT_DEBUG_CHANNEL(key);
WINE_DECLARE_DEBUG_CHANNEL(keyboard); WINE_DECLARE_DEBUG_CHANNEL(keyboard);
WINE_DECLARE_DEBUG_CHANNEL(win);
WINE_DEFAULT_DEBUG_CHANNEL(event);
BYTE InputKeyStateTable[256];
static BYTE AsyncKeyStateTable[256];
static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYSKEYUP
or a WM_KEYUP message */
/* Storage for the USER-maintained mouse positions */
static DWORD PosX, PosY;
typedef union
{
struct
{
#ifndef BITFIELDS_BIGENDIAN
unsigned long count : 16;
#endif
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;
#ifdef BITFIELDS_BIGENDIAN
unsigned long count : 16;
#endif
} lp1;
unsigned long lp2;
} KEYLP;
/*********************************************************************** /***********************************************************************
@ -91,274 +59,30 @@ static WORD get_key_state(void)
if (GetSystemMetrics( SM_SWAPBUTTON )) if (GetSystemMetrics( SM_SWAPBUTTON ))
{ {
if (InputKeyStateTable[VK_RBUTTON] & 0x80) ret |= MK_LBUTTON; if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON;
if (InputKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_RBUTTON; if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON;
} }
else else
{ {
if (InputKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_LBUTTON; if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON;
if (InputKeyStateTable[VK_RBUTTON] & 0x80) ret |= MK_RBUTTON; if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON;
} }
if (InputKeyStateTable[VK_MBUTTON] & 0x80) ret |= MK_MBUTTON; if (GetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON;
if (InputKeyStateTable[VK_SHIFT] & 0x80) ret |= MK_SHIFT; if (GetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT;
if (InputKeyStateTable[VK_CONTROL] & 0x80) ret |= MK_CONTROL; if (GetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL;
if (InputKeyStateTable[VK_XBUTTON1] & 0x80) ret |= MK_XBUTTON1; if (GetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1;
if (InputKeyStateTable[VK_XBUTTON2] & 0x80) ret |= MK_XBUTTON2; if (GetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2;
return ret; return ret;
} }
/***********************************************************************
* queue_hardware_message
*
* Add a message to the hardware queue.
* Note: the position is relative to the desktop window.
*/
static void queue_hardware_message( UINT message, HWND hwnd, WPARAM wParam, LPARAM lParam,
int xPos, int yPos, DWORD time, ULONG_PTR extraInfo )
{
SERVER_START_REQ( send_message )
{
req->id = GetCurrentThreadId();
req->type = MSG_HARDWARE;
req->flags = 0;
req->win = hwnd;
req->msg = message;
req->wparam = wParam;
req->lparam = lParam;
req->x = xPos;
req->y = yPos;
req->time = time;
req->info = extraInfo;
req->timeout = -1;
req->callback = NULL;
wine_server_call( req );
}
SERVER_END_REQ;
}
/***********************************************************************
* queue_kbd_event
*
* Put a keyboard event into a thread queue
*/
static void queue_kbd_event( const KEYBDINPUT *ki, UINT injected_flags )
{
UINT message;
KEYLP keylp;
KBDLLHOOKSTRUCT hook;
keylp.lp2 = 0;
keylp.lp1.count = 1;
keylp.lp1.code = ki->wScan;
keylp.lp1.extended = (ki->dwFlags & KEYEVENTF_EXTENDEDKEY) != 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*/
/* note that there is a test for all this */
if (ki->dwFlags & KEYEVENTF_KEYUP )
{
message = WM_KEYUP;
if( (InputKeyStateTable[VK_MENU] & 0x80) && (
(ki->wVk == VK_MENU) || (ki->wVk == VK_CONTROL) ||
!(InputKeyStateTable[VK_CONTROL] & 0x80))) {
if( TrackSysKey == VK_MENU || /* <ALT>-down/<ALT>-up sequence */
(ki->wVk != VK_MENU)) /* <ALT>-down...<something else>-up */
message = WM_SYSKEYUP;
TrackSysKey = 0;
}
InputKeyStateTable[ki->wVk] &= ~0x80;
keylp.lp1.previous = 1;
keylp.lp1.transition = 1;
}
else
{
keylp.lp1.previous = (InputKeyStateTable[ki->wVk] & 0x80) != 0;
keylp.lp1.transition = 0;
if (!(InputKeyStateTable[ki->wVk] & 0x80)) InputKeyStateTable[ki->wVk] ^= 0x01;
InputKeyStateTable[ki->wVk] |= 0x80;
AsyncKeyStateTable[ki->wVk] |= 0x80;
message = WM_KEYDOWN;
if( (InputKeyStateTable[VK_MENU] & 0x80) &&
!(InputKeyStateTable[VK_CONTROL] & 0x80)) {
message = WM_SYSKEYDOWN;
TrackSysKey = ki->wVk;
}
}
keylp.lp1.context = (InputKeyStateTable[VK_MENU] & 0x80) != 0; /* 1 if alt */
TRACE_(key)(" wParam=%04x, lParam=%08lx, InputKeyState=%x\n",
ki->wVk, keylp.lp2, InputKeyStateTable[ki->wVk] );
hook.vkCode = ki->wVk;
hook.scanCode = ki->wScan;
hook.flags = (keylp.lp2 >> 24) | injected_flags;
hook.time = ki->time;
hook.dwExtraInfo = ki->dwExtraInfo;
if (!HOOK_CallHooks( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook, TRUE ))
queue_hardware_message( message, 0, ki->wVk, keylp.lp2,
PosX, PosY, ki->time, ki->dwExtraInfo );
}
/***********************************************************************
* queue_raw_mouse_message
*/
static void queue_raw_mouse_message( UINT message, UINT flags, INT x, INT y, const MOUSEINPUT *mi )
{
MSLLHOOKSTRUCT hook;
hook.pt.x = x;
hook.pt.y = y;
hook.mouseData = MAKELONG( 0, mi->mouseData );
hook.flags = flags;
hook.time = mi->time;
hook.dwExtraInfo = mi->dwExtraInfo;
if (!HOOK_CallHooks( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook, TRUE ))
queue_hardware_message( message, (HWND)mi->dwExtraInfo /*FIXME*/,
MAKEWPARAM( get_key_state(), mi->mouseData ),
0, x, y, mi->time, mi->dwExtraInfo );
}
/***********************************************************************
* queue_mouse_event
*/
static void queue_mouse_event( const MOUSEINPUT *mi, UINT flags )
{
if (mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
{
PosX = (mi->dx * GetSystemMetrics(SM_CXSCREEN)) >> 16;
PosY = (mi->dy * GetSystemMetrics(SM_CYSCREEN)) >> 16;
}
else if (mi->dwFlags & MOUSEEVENTF_MOVE)
{
int width = GetSystemMetrics(SM_CXSCREEN);
int height = GetSystemMetrics(SM_CYSCREEN);
long posX = (long) PosX, posY = (long) PosY;
int accel[3];
int accelMult;
/* dx and dy can be negative numbers for relative movements */
SystemParametersInfoA(SPI_GETMOUSE, 0, accel, 0);
accelMult = 1;
if (mi->dx > accel[0] && accel[2] != 0)
{
accelMult = 2;
if ((mi->dx > accel[1]) && (accel[2] == 2))
{
accelMult = 4;
}
}
posX += (long)mi->dx * accelMult;
accelMult = 1;
if (mi->dy > accel[0] && accel[2] != 0)
{
accelMult = 2;
if ((mi->dy > accel[1]) && (accel[2] == 2))
{
accelMult = 4;
}
}
posY += (long)mi->dy * accelMult;
/* Clip to the current screen size */
if (posX < 0) PosX = 0;
else if (posX >= width) PosX = width - 1;
else PosX = posX;
if (posY < 0) PosY = 0;
else if (posY >= height) PosY = height - 1;
else PosY = posY;
}
if (mi->dwFlags & MOUSEEVENTF_MOVE)
{
queue_raw_mouse_message( WM_MOUSEMOVE, flags, PosX, PosY, mi );
if (flags & LLMHF_INJECTED) /* we have to actually move the cursor */
SetCursorPos( PosX, PosY );
}
if (mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
{
InputKeyStateTable[VK_LBUTTON] |= 0x80;
AsyncKeyStateTable[VK_LBUTTON] |= 0x80;
queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONDOWN : WM_LBUTTONDOWN,
flags, PosX, PosY, mi );
}
if (mi->dwFlags & MOUSEEVENTF_LEFTUP)
{
InputKeyStateTable[VK_LBUTTON] &= ~0x80;
queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_RBUTTONUP : WM_LBUTTONUP,
flags, PosX, PosY, mi );
}
if (mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
{
InputKeyStateTable[VK_RBUTTON] |= 0x80;
AsyncKeyStateTable[VK_RBUTTON] |= 0x80;
queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN,
flags, PosX, PosY, mi );
}
if (mi->dwFlags & MOUSEEVENTF_RIGHTUP)
{
InputKeyStateTable[VK_RBUTTON] &= ~0x80;
queue_raw_mouse_message( GetSystemMetrics(SM_SWAPBUTTON) ? WM_LBUTTONUP : WM_RBUTTONUP,
flags, PosX, PosY, mi );
}
if (mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
{
InputKeyStateTable[VK_MBUTTON] |= 0x80;
AsyncKeyStateTable[VK_MBUTTON] |= 0x80;
queue_raw_mouse_message( WM_MBUTTONDOWN, flags, PosX, PosY, mi );
}
if (mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
{
InputKeyStateTable[VK_MBUTTON] &= ~0x80;
queue_raw_mouse_message( WM_MBUTTONUP, flags, PosX, PosY, mi );
}
if (mi->dwFlags & MOUSEEVENTF_WHEEL)
{
queue_raw_mouse_message( WM_MOUSEWHEEL, flags, PosX, PosY, mi );
}
}
/*********************************************************************** /***********************************************************************
* SendInput (USER32.@) * SendInput (USER32.@)
*/ */
UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size ) UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size )
{ {
UINT i; if (USER_Driver.pSendInput) return USER_Driver.pSendInput( count, inputs, size );
return 0;
for (i = 0; i < count; i++, inputs++)
{
switch(inputs->type)
{
case INPUT_MOUSE:
queue_mouse_event( &inputs->u.mi, LLMHF_INJECTED );
break;
case WINE_INTERNAL_INPUT_MOUSE:
queue_mouse_event( &inputs->u.mi, 0 );
break;
case INPUT_KEYBOARD:
queue_kbd_event( &inputs->u.ki, LLKHF_INJECTED );
break;
case WINE_INTERNAL_INPUT_KEYBOARD:
queue_kbd_event( &inputs->u.ki, 0 );
break;
case INPUT_HARDWARE:
FIXME( "INPUT_HARDWARE not supported\n" );
break;
}
}
return count;
} }
@ -404,11 +128,8 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
*/ */
BOOL WINAPI GetCursorPos( POINT *pt ) BOOL WINAPI GetCursorPos( POINT *pt )
{ {
if (!pt) return 0; if (pt && USER_Driver.pGetCursorPos) return USER_Driver.pGetCursorPos( pt );
pt->x = PosX; return FALSE;
pt->y = PosY;
if (USER_Driver.pGetCursorPos) USER_Driver.pGetCursorPos( pt );
return 1;
} }
@ -432,10 +153,8 @@ BOOL WINAPI GetCursorInfo( PCURSORINFO pci )
*/ */
BOOL WINAPI SetCursorPos( INT x, INT y ) BOOL WINAPI SetCursorPos( INT x, INT y )
{ {
if (USER_Driver.pSetCursorPos) USER_Driver.pSetCursorPos( x, y ); if (USER_Driver.pSetCursorPos) return USER_Driver.pSetCursorPos( x, y );
PosX = x; return FALSE;
PosY = y;
return TRUE;
} }
@ -496,20 +215,11 @@ HWND WINAPI GetCapture(void)
* Determine if a key is or was pressed. retval has high-order * 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 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
* been pressed. * 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.
*/ */
SHORT WINAPI GetAsyncKeyState(INT nKey) SHORT WINAPI GetAsyncKeyState(INT nKey)
{ {
SHORT retval = ((AsyncKeyStateTable[nKey] & 0x80) ? 0x0001 : 0) | if (USER_Driver.pGetAsyncKeyState) return USER_Driver.pGetAsyncKeyState( nKey );
((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0); return 0;
AsyncKeyStateTable[nKey] = 0;
TRACE_(key)("(%x) -> %x\n", nKey, retval);
return retval;
} }