From aef19abc82d01816039f8a2d801cd6bf2fdea195 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 9 Mar 2005 16:45:23 +0000 Subject: [PATCH] Moved SendInput and related functions to the USER driver to avoid a number of dll separation hacks. --- dlls/user/user_main.c | 22 +-- dlls/user/user_private.h | 22 ++- dlls/x11drv/event.c | 29 ++++ dlls/x11drv/keyboard.c | 178 +++++++++++++++++---- dlls/x11drv/mouse.c | 276 ++++++++++++++++++++++++-------- dlls/x11drv/x11drv.h | 271 +++++++++++++++---------------- dlls/x11drv/x11drv.spec | 16 +- dlls/x11drv/x11drv_main.c | 2 + include/win.h | 4 - windows/input.c | 326 +++----------------------------------- 10 files changed, 569 insertions(+), 577 deletions(-) diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c index a5699bf7f1..c99d4aa1a3 100644 --- a/dlls/user/user_main.c +++ b/dlls/user/user_main.c @@ -83,19 +83,19 @@ static BOOL load_driver(void) ExitProcess(1); } - GET_USER_FUNC(InitKeyboard); - GET_USER_FUNC(VkKeyScanEx); - GET_USER_FUNC(MapVirtualKeyEx); + GET_USER_FUNC(ActivateKeyboardLayout); + GET_USER_FUNC(Beep); + GET_USER_FUNC(GetAsyncKeyState); GET_USER_FUNC(GetKeyNameText); - GET_USER_FUNC(ToUnicodeEx); - GET_USER_FUNC(GetKeyboardLayoutList); GET_USER_FUNC(GetKeyboardLayout); + GET_USER_FUNC(GetKeyboardLayoutList); GET_USER_FUNC(GetKeyboardLayoutName); 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(Beep); - GET_USER_FUNC(InitMouse); + GET_USER_FUNC(VkKeyScanEx); GET_USER_FUNC(SetCursor); GET_USER_FUNC(GetCursorPos); GET_USER_FUNC(SetCursorPos); @@ -244,12 +244,6 @@ static BOOL process_attach(void) /* Create desktop window */ 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; } diff --git a/dlls/user/user_private.h b/dlls/user/user_private.h index 873e3ebc19..43e849a3a0 100644 --- a/dlls/user/user_private.h +++ b/dlls/user/user_private.h @@ -62,23 +62,23 @@ struct tagCURSORICONINFO; typedef struct tagUSER_DRIVER { /* keyboard functions */ - void (*pInitKeyboard)(LPBYTE); - SHORT (*pVkKeyScanEx)(WCHAR, HKL); - UINT (*pMapVirtualKeyEx)(UINT, UINT, HKL); + HKL (*pActivateKeyboardLayout)(HKL, UINT); + void (*pBeep)(void); + SHORT (*pGetAsyncKeyState)(INT); INT (*pGetKeyNameText)(LONG, LPWSTR, INT); - INT (*pToUnicodeEx)(UINT, UINT, LPBYTE, LPWSTR, int, UINT, HKL); - UINT (*pGetKeyboardLayoutList)(INT, HKL *); HKL (*pGetKeyboardLayout)(DWORD); + UINT (*pGetKeyboardLayoutList)(INT, HKL *); BOOL (*pGetKeyboardLayoutName)(LPWSTR); 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); - void (*pBeep)(void); + SHORT (*pVkKeyScanEx)(WCHAR, HKL); /* mouse functions */ - void (*pInitMouse)(LPBYTE); void (*pSetCursor)(struct tagCURSORICONINFO *); - void (*pGetCursorPos)(LPPOINT); - void (*pSetCursorPos)(INT,INT); + BOOL (*pGetCursorPos)(LPPOINT); + BOOL (*pSetCursorPos)(INT,INT); /* screen saver functions */ BOOL (*pGetScreenSaveActive)(void); void (*pSetScreenSaveActive)(BOOL); @@ -119,8 +119,6 @@ typedef struct tagUSER_DRIVER { extern USER_DRIVER USER_Driver; extern HMODULE user32_module; -extern BYTE InputKeyStateTable[256]; -extern BYTE AsyncKeyStateTable[256]; extern DWORD USER16_AlertableWait; extern BOOL CLIPBOARD_ReleaseOwner(void); diff --git a/dlls/x11drv/event.c b/dlls/x11drv/event.c index 5405c2e6e2..01e69e5924 100644 --- a/dlls/x11drv/event.c +++ b/dlls/x11drv/event.c @@ -951,3 +951,32 @@ LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) 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; +} diff --git a/dlls/x11drv/keyboard.c b/dlls/x11drv/keyboard.c index 5b0fd78917..2e32ecf423 100644 --- a/dlls/x11drv/keyboard.c +++ b/dlls/x11drv/keyboard.c @@ -48,17 +48,47 @@ #include "winnls.h" #include "win.h" #include "x11drv.h" +#include "wine/server.h" #include "wine/unicode.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(keyboard); 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 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 */ @@ -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 ) -{ - INPUT input; +void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time, + DWORD dwExtraInfo, UINT injected_flags ) +{ + UINT message; + KEYLP keylp; + KBDLLHOOKSTRUCT hook; + + keylp.lp2 = 0; + keylp.lp1.count = 1; + keylp.lp1.code = wScan; + keylp.lp1.extended = (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 (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 || /* -down/-up sequence */ + (wVk != VK_MENU)) /* -down...-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 */ - input.type = WINE_INTERNAL_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) ); + 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. And from there, a 'release' event will switch off the toggle key. */ *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 { down = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0); 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) { TRACE("ON + KeyRelease => generating DOWN and UP messages.\n"); - send_keyboard_input( vkey, scan, down, event_time ); - send_keyboard_input( vkey, scan, up, event_time ); + X11DRV_send_keyboard_input( vkey, scan, down, event_time, 0, 0 ); + X11DRV_send_keyboard_input( vkey, scan, up, event_time, 0, 0 ); *State=FALSE; - pKeyStateTable[vkey] &= ~0x01; /* Toggle state to off. */ + key_state_table[vkey] &= ~0x01; /* Toggle state to off. */ } } else /* it was OFF */ if (Evtype==KeyPress) { TRACE("OFF + Keypress => generating DOWN and UP messages.\n"); - send_keyboard_input( vkey, scan, down, event_time ); - send_keyboard_input( vkey, scan, up, event_time ); + X11DRV_send_keyboard_input( vkey, scan, down, event_time, 0, 0 ); + X11DRV_send_keyboard_input( vkey, scan, up, event_time, 0, 0 ); *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 ) { /* 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", - vkey, pKeyStateTable[vkey]); + vkey, key_state_table[vkey]); /* 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 ); break; 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 ); - TRACE("State after : %#.2x\n",pKeyStateTable[vkey]); + TRACE("State after : %#.2x\n",key_state_table[vkey]); break; default: /* 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"); 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)) + if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & LockMask)) { TRACE("Adjusting Caps Lock state.\n"); 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 ( 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(); KeySym *ksp; @@ -1374,8 +1471,6 @@ void X11DRV_InitKeyboard( BYTE *key_state_table ) char ckey[4]={0,0,0,0}; const char (*lkey)[MAIN_LEN][4]; - pKeyStateTable = key_state_table; - wine_tsx11_lock(); XDisplayKeycodes(display, &min_keycode, &max_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.@) */ @@ -1713,7 +1821,7 @@ void X11DRV_MappingNotify( HWND dummy, XEvent *event ) wine_tsx11_lock(); XRefreshKeyboardMapping(&event->xmapping); wine_tsx11_unlock(); - X11DRV_InitKeyboard( pKeyStateTable ); + X11DRV_InitKeyboard(); hwnd = GetFocus(); if (!hwnd) hwnd = GetActiveWindow(); diff --git a/dlls/x11drv/mouse.c b/dlls/x11drv/mouse.c index 6697364f53..2917e18390 100644 --- a/dlls/x11drv/mouse.c +++ b/dlls/x11drv/mouse.c @@ -34,6 +34,7 @@ #include "win.h" #include "x11drv.h" +#include "wine/server.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(cursor); @@ -60,8 +61,7 @@ static const UINT button_up_flags[NB_BUTTONS] = 0 }; -static BYTE *pKeyStateTable; - +POINT cursor_pos; /*********************************************************************** * 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 ) { - pKeyStateTable[VK_LBUTTON] = (state & Button1Mask ? 0x80 : 0); - pKeyStateTable[VK_MBUTTON] = (state & Button2Mask ? 0x80 : 0); - pKeyStateTable[VK_RBUTTON] = (state & Button3Mask ? 0x80 : 0); + key_state_table[VK_LBUTTON] = (state & Button1Mask ? 0x80 : 0); + key_state_table[VK_MBUTTON] = (state & Button2Mask ? 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 ) { - pKeyStateTable[VK_SHIFT] = (state & ShiftMask ? 0x80 : 0); - pKeyStateTable[VK_CONTROL] = (state & ControlMask ? 0x80 : 0); + key_state_table[VK_SHIFT] = (state & ShiftMask ? 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, - DWORD data, Time time ) +static WORD get_key_state(void) { - INPUT input; + WORD ret = 0; + + 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; + +} - TRACE("(%04lX,%ld,%ld)\n", flags, posX, posY ); + +/*********************************************************************** + * 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) { - int width = GetSystemMetrics( SM_CXSCREEN ); - int height = GetSystemMetrics( SM_CYSCREEN ); - /* Relative mouse movements seem not to be scaled as absolute ones */ - posX = (((long)posX << 16) + width-1) / width; - posY = (((long)posY << 16) + height-1) / height; + if (injected_flags & LLMHF_INJECTED) + { + pt.x = (x * screen_width) >> 16; + pt.y = (y * screen_height) >> 16; + } + 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; - input.u.mi.dx = posX; - input.u.mi.dy = posY; - input.u.mi.mouseData = data; - input.u.mi.dwFlags = flags; - input.u.mi.time = EVENT_x11_time_to_win32_time(time); - input.u.mi.dwExtraInfo = (ULONG_PTR)hwnd; - SendInput( 1, &input, sizeof(input) ); + if (flags & MOUSEEVENTF_MOVE) + { + queue_raw_mouse_message( WM_MOUSEMOVE, hwnd, pt.x, pt.y, data, time, + extra_info, injected_flags ); + if (injected_flags & LLMHF_INJECTED) /* we have to actually move the cursor */ + { + TRACE( "warping to (%ld,%ld)\n", pt.x, pt.y ); + 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.@) */ -void X11DRV_SetCursorPos( INT x, INT y ) +BOOL X11DRV_SetCursorPos( INT x, INT y ) { Display *display = thread_display(); @@ -497,42 +649,37 @@ void X11DRV_SetCursorPos( INT x, INT y ) wine_tsx11_lock(); 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(); + return TRUE; } /*********************************************************************** * GetCursorPos (X11DRV.@) */ -void X11DRV_GetCursorPos(LPPOINT pos) +BOOL X11DRV_GetCursorPos(LPPOINT pos) { - Display *display = thread_display(); - Window root, child; - int rootX, rootY, winX, winY; - unsigned int xstate; - - wine_tsx11_lock(); - if (XQueryPointer( display, root_window, &root, &child, - &rootX, &rootY, &winX, &winY, &xstate )) - { - update_key_state( xstate ); - update_button_state( xstate ); - TRACE("pointer at (%d,%d)\n", winX, winY ); - pos->x = winX; - pos->y = winY; - } - wine_tsx11_unlock(); -} + Display *display = thread_display(); + Window root, child; + int rootX, rootY, winX, winY; + unsigned int xstate; -/*********************************************************************** - * InitMouse (X11DRV.@) - */ -void X11DRV_InitMouse( BYTE *key_state_table ) -{ - pKeyStateTable = key_state_table; + wine_tsx11_lock(); + if (XQueryPointer( display, root_window, &root, &child, + &rootX, &rootY, &winX, &winY, &xstate )) + { + update_key_state( xstate ); + update_button_state( xstate ); + TRACE("pointer at (%d,%d)\n", winX, winY ); + cursor_pos.x = winX; + cursor_pos.y = winY; + } + *pos = cursor_pos; + wine_tsx11_unlock(); + return TRUE; } - /*********************************************************************** * X11DRV_ButtonPress */ @@ -559,8 +706,8 @@ void X11DRV_ButtonPress( HWND hwnd, XEvent *xev ) break; } update_key_state( event->state ); - send_mouse_event( hwnd, button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE, - pt.x, pt.y, wData, event->time ); + X11DRV_send_mouse_input( hwnd, button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE, + 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 ); get_coords( hwnd, event->window, event->x, event->y, &pt ); update_key_state( event->state ); - send_mouse_event( hwnd, button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE, - pt.x, pt.y, 0, event->time ); + X11DRV_send_mouse_input( hwnd, button_up_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE, + 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 ); get_coords( hwnd, event->window, event->x, event->y, &pt ); update_key_state( event->state ); - send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, - pt.x, pt.y, 0, event->time ); + X11DRV_send_mouse_input( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, + 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 ); get_coords( hwnd, event->window, event->x, event->y, &pt ); update_key_state( event->state ); - send_mouse_event( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, - pt.x, pt.y, 0, event->time ); + X11DRV_send_mouse_input( hwnd, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, + 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; 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; 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; 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 */ diff --git a/dlls/x11drv/x11drv.h b/dlls/x11drv/x11drv.h index 075e8d5bf6..51dd6b7c59 100644 --- a/dlls/x11drv/x11drv.h +++ b/dlls/x11drv/x11drv.h @@ -287,6 +287,136 @@ typedef struct /* DIB Section sync state */ enum { DIB_Status_None, DIB_Status_InSync, DIB_Status_GdiMod, DIB_Status_AppMod, DIB_Status_AuxMod }; +typedef struct { + void (*Convert_5x5_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_565_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_565_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_0888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_555_to_0888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_5x5_to_any0888)(int width, int height, + const void* srcbits, int srclinebytes, + WORD rsrc, WORD gsrc, WORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst); + void (*Convert_565_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_555_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_555_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_0888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_565_to_0888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_555_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_555_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_565_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_565_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_0888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_888_to_0888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_rgb888_to_any0888)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst); + void (*Convert_bgr888_to_any0888)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst); + void (*Convert_0888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_any)(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + DWORD rdst, DWORD gdst, DWORD bdst); + void (*Convert_0888_to_555_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_to_555_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_to_565_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_to_565_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_any0888_to_5x5)(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes, + WORD rdst, WORD gdst, WORD bdst); + void (*Convert_0888_to_888_asis)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_0888_to_888_reverse)(int width, int height, + const void* srcbits, int srclinebytes, + void* dstbits, int dstlinebytes); + void (*Convert_any0888_to_rgb888)(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes); + void (*Convert_any0888_to_bgr888)(int width, int height, + const void* srcbits, int srclinebytes, + DWORD rsrc, DWORD gsrc, DWORD bsrc, + void* dstbits, int dstlinebytes); +} dib_conversions; + +extern const dib_conversions dib_normal, dib_src_byteswap, dib_dst_byteswap; + +extern INT X11DRV_DIB_MaskToShift(DWORD mask); extern int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth, const BITMAPINFO *info, int *nColors ); @@ -401,6 +531,9 @@ 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 @@ -518,6 +651,11 @@ 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 ); @@ -550,137 +688,4 @@ LPDDHALMODEINFO X11DRV_Settings_SetHandlers(const char *name, unsigned int nmodes, int reserve_depths); - - -typedef struct { - void (*Convert_5x5_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_555_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_555_to_565_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_555_to_565_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_555_to_888_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_555_to_888_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_555_to_0888_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_555_to_0888_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_5x5_to_any0888)(int width, int height, - const void* srcbits, int srclinebytes, - WORD rsrc, WORD gsrc, WORD bsrc, - void* dstbits, int dstlinebytes, - DWORD rdst, DWORD gdst, DWORD bdst); - void (*Convert_565_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_565_to_555_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_565_to_555_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_565_to_888_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_565_to_888_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_565_to_0888_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_565_to_0888_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_888_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_888_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_888_to_555_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_888_to_555_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_888_to_565_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_888_to_565_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_888_to_0888_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_888_to_0888_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_rgb888_to_any0888)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes, - DWORD rdst, DWORD gdst, DWORD bdst); - void (*Convert_bgr888_to_any0888)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes, - DWORD rdst, DWORD gdst, DWORD bdst); - void (*Convert_0888_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_0888_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_0888_any)(int width, int height, - const void* srcbits, int srclinebytes, - DWORD rsrc, DWORD gsrc, DWORD bsrc, - void* dstbits, int dstlinebytes, - DWORD rdst, DWORD gdst, DWORD bdst); - void (*Convert_0888_to_555_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_0888_to_555_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_0888_to_565_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_0888_to_565_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_any0888_to_5x5)(int width, int height, - const void* srcbits, int srclinebytes, - DWORD rsrc, DWORD gsrc, DWORD bsrc, - void* dstbits, int dstlinebytes, - WORD rdst, WORD gdst, WORD bdst); - void (*Convert_0888_to_888_asis)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_0888_to_888_reverse)(int width, int height, - const void* srcbits, int srclinebytes, - void* dstbits, int dstlinebytes); - void (*Convert_any0888_to_rgb888)(int width, int height, - const void* srcbits, int srclinebytes, - DWORD rsrc, DWORD gsrc, DWORD bsrc, - void* dstbits, int dstlinebytes); - void (*Convert_any0888_to_bgr888)(int width, int height, - const void* srcbits, int srclinebytes, - DWORD rsrc, DWORD gsrc, DWORD bsrc, - void* dstbits, int dstlinebytes); -} dib_conversions; - -extern const dib_conversions dib_normal, dib_src_byteswap, dib_dst_byteswap; - -extern INT X11DRV_DIB_MaskToShift(DWORD mask); - #endif /* __WINE_X11DRV_H */ diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec index 00304fa141..ea4460a9ad 100644 --- a/dlls/x11drv/x11drv.spec +++ b/dlls/x11drv/x11drv.spec @@ -63,19 +63,19 @@ # USER driver -@ cdecl InitKeyboard(ptr) X11DRV_InitKeyboard -@ cdecl VkKeyScanEx(long long) X11DRV_VkKeyScanEx -@ cdecl MapVirtualKeyEx(long long long) X11DRV_MapVirtualKeyEx +@ cdecl ActivateKeyboardLayout(long long) X11DRV_ActivateKeyboardLayout +@ cdecl Beep() X11DRV_Beep +@ cdecl GetAsyncKeyState(long) X11DRV_GetAsyncKeyState @ 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 GetKeyboardLayoutList(long ptr) X11DRV_GetKeyboardLayoutList @ cdecl GetKeyboardLayoutName(ptr) X11DRV_GetKeyboardLayoutName @ 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 Beep() X11DRV_Beep -@ cdecl InitMouse(ptr) X11DRV_InitMouse +@ cdecl VkKeyScanEx(long long) X11DRV_VkKeyScanEx @ cdecl SetCursor(ptr) X11DRV_SetCursor @ cdecl GetCursorPos(ptr) X11DRV_GetCursorPos @ cdecl SetCursorPos(long long) X11DRV_SetCursorPos diff --git a/dlls/x11drv/x11drv_main.c b/dlls/x11drv/x11drv_main.c index bbfe2cfa1f..c3d8de3cfb 100644 --- a/dlls/x11drv/x11drv_main.c +++ b/dlls/x11drv/x11drv_main.c @@ -394,6 +394,8 @@ static BOOL process_attach(void) X11DRV_XF86DGA2_Init(); #endif + X11DRV_InitKeyboard(); + return TRUE; } diff --git a/include/win.h b/include/win.h index ce1025aac2..b14b5f1aba 100644 --- a/include/win.h +++ b/include/win.h @@ -95,10 +95,6 @@ extern BOOL WIN_IsWindowDrawable( HWND hwnd, BOOL ); extern HWND *WIN_ListChildren( HWND hwnd ); 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 */ extern void USER_Lock(void); extern void USER_Unlock(void); diff --git a/windows/input.c b/windows/input.c index 228cb24590..b2eaa6ce01 100644 --- a/windows/input.c +++ b/windows/input.c @@ -40,46 +40,14 @@ #include "winuser.h" #include "winnls.h" #include "wine/server.h" -#include "win.h" #include "message.h" #include "user_private.h" #include "winternl.h" #include "wine/debug.h" #include "winerror.h" -WINE_DECLARE_DEBUG_CHANNEL(key); +WINE_DEFAULT_DEBUG_CHANNEL(key); 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 (InputKeyStateTable[VK_RBUTTON] & 0x80) ret |= MK_LBUTTON; - if (InputKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_RBUTTON; + if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON; + if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON; } else { - if (InputKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_LBUTTON; - if (InputKeyStateTable[VK_RBUTTON] & 0x80) ret |= MK_RBUTTON; + if (GetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON; + if (GetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON; } - if (InputKeyStateTable[VK_MBUTTON] & 0x80) ret |= MK_MBUTTON; - if (InputKeyStateTable[VK_SHIFT] & 0x80) ret |= MK_SHIFT; - if (InputKeyStateTable[VK_CONTROL] & 0x80) ret |= MK_CONTROL; - if (InputKeyStateTable[VK_XBUTTON1] & 0x80) ret |= MK_XBUTTON1; - if (InputKeyStateTable[VK_XBUTTON2] & 0x80) ret |= MK_XBUTTON2; + if (GetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON; + if (GetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT; + if (GetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL; + if (GetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1; + if (GetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2; 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 || /* -down/-up sequence */ - (ki->wVk != VK_MENU)) /* -down...-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.@) */ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size ) { - UINT i; - - 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; + if (USER_Driver.pSendInput) return USER_Driver.pSendInput( count, inputs, size ); + return 0; } @@ -404,11 +128,8 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, */ BOOL WINAPI GetCursorPos( POINT *pt ) { - if (!pt) return 0; - pt->x = PosX; - pt->y = PosY; - if (USER_Driver.pGetCursorPos) USER_Driver.pGetCursorPos( pt ); - return 1; + if (pt && USER_Driver.pGetCursorPos) return USER_Driver.pGetCursorPos( pt ); + return FALSE; } @@ -432,10 +153,8 @@ BOOL WINAPI GetCursorInfo( PCURSORINFO pci ) */ BOOL WINAPI SetCursorPos( INT x, INT y ) { - if (USER_Driver.pSetCursorPos) USER_Driver.pSetCursorPos( x, y ); - PosX = x; - PosY = y; - return TRUE; + if (USER_Driver.pSetCursorPos) return USER_Driver.pSetCursorPos( x, y ); + return FALSE; } @@ -496,20 +215,11 @@ HWND WINAPI GetCapture(void) * Determine if a key is or was pressed. retval has high-order * bit set to 1 if currently pressed, low-order bit set to 1 if key has * been pressed. - * - * This uses the variable AsyncMouseButtonsStates and - * AsyncKeyStateTable (set in event.c) which have the mouse button - * number or key number (whichever is applicable) set to true if the - * mouse or key had been depressed since the last call to - * GetAsyncKeyState. */ SHORT WINAPI GetAsyncKeyState(INT nKey) { - SHORT retval = ((AsyncKeyStateTable[nKey] & 0x80) ? 0x0001 : 0) | - ((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0); - AsyncKeyStateTable[nKey] = 0; - TRACE_(key)("(%x) -> %x\n", nKey, retval); - return retval; + if (USER_Driver.pGetAsyncKeyState) return USER_Driver.pGetAsyncKeyState( nKey ); + return 0; } -- 2.33.8