From 32fb580515130b61adefbe344df7d4b340a10130 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 18 Oct 2001 21:38:59 +0000 Subject: [PATCH] Changed X11 mouse driver to use SendInput, and removed WINE_MOUSEEVENT hack. Moved mouse.c to dlls/x11drv. Added KeymapNotify event handler, and fixed handling with multiple alt/shift/control keys. Removed dinput functions from USER driver. --- dlls/ttydrv/ttydrv.h | 1 - dlls/ttydrv/ttydrv.spec | 4 - dlls/ttydrv/user.c | 31 ---- dlls/user/mouse.c | 27 +-- dlls/user/mouse.spec | 2 +- dlls/user/user_main.c | 6 +- dlls/x11drv/Makefile.in | 1 + {windows => dlls}/x11drv/mouse.c | 291 ++++++++++++++++++++--------- dlls/x11drv/window.c | 2 +- dlls/x11drv/x11drv.spec | 2 - include/mouse.h | 25 --- include/user.h | 14 +- include/x11drv.h | 11 -- windows/input.c | 146 +++++++-------- windows/x11drv/Makefile.in | 3 +- windows/x11drv/event.c | 265 ++------------------------ windows/x11drv/keyboard.c | 306 ++++++++++++------------------- 17 files changed, 422 insertions(+), 715 deletions(-) rename {windows => dlls}/x11drv/mouse.c (57%) delete mode 100644 include/mouse.h diff --git a/dlls/ttydrv/ttydrv.h b/dlls/ttydrv/ttydrv.h index 03c771d4fa7..6d0cae70b8f 100644 --- a/dlls/ttydrv/ttydrv.h +++ b/dlls/ttydrv/ttydrv.h @@ -29,7 +29,6 @@ struct tagWND; struct tagCURSORICONINFO; struct tagCREATESTRUCTA; struct tagWINDOWPOS; -struct DIDEVICEOBJECTDATA; #if defined(HAVE_LIBCURSES) || defined(HAVE_LIBNCURSES) #define WINE_CURSES diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec index 696f0c372c2..2ff911efe63 100644 --- a/dlls/ttydrv/ttydrv.spec +++ b/dlls/ttydrv/ttydrv.spec @@ -47,15 +47,11 @@ debug_channels (ttydrv) # USER driver -@ cdecl InitKeyboard() TTYDRV_InitKeyboard @ cdecl VkKeyScan(long) TTYDRV_VkKeyScan @ cdecl MapVirtualKey(long long) TTYDRV_MapVirtualKey @ cdecl GetKeyNameText(long str long) TTYDRV_GetKeyNameText @ cdecl ToUnicode(long long ptr ptr long long) TTYDRV_ToUnicode @ cdecl Beep() TTYDRV_Beep -@ cdecl GetDIState(long ptr) TTYDRV_GetDIState -@ cdecl GetDIData(ptr long ptr ptr long) TTYDRV_GetDIData -@ cdecl InitMouse(ptr) TTYDRV_InitMouse @ cdecl SetCursor(ptr) TTYDRV_SetCursor @ cdecl GetScreenSaveActive() TTYDRV_GetScreenSaveActive @ cdecl SetScreenSaveActive(long) TTYDRV_SetScreenSaveActive diff --git a/dlls/ttydrv/user.c b/dlls/ttydrv/user.c index ecd107a30a3..0aeaf7b987b 100644 --- a/dlls/ttydrv/user.c +++ b/dlls/ttydrv/user.c @@ -12,13 +12,6 @@ DEFAULT_DEBUG_CHANNEL(ttydrv); -/*********************************************************************** - * InitKeyboard (TTYDRV.@) - */ -void TTYDRV_InitKeyboard(void) -{ -} - /*********************************************************************** * VkKeyScan (TTYDRV.@) */ @@ -63,30 +56,6 @@ void TTYDRV_Beep(void) { } -/*********************************************************************** - * GetDIState (TTYDRV.@) - */ -BOOL TTYDRV_GetDIState(DWORD len, LPVOID ptr) -{ - return TRUE; -} - -/*********************************************************************** - * GetDIData (TTYDRV.@) - */ -BOOL TTYDRV_GetDIData( BYTE *keystate, DWORD dodsize, LPDIDEVICEOBJECTDATA dod, - LPDWORD entries, DWORD flags ) -{ - return TRUE; -} - -/*********************************************************************** - * InitMouse (TTYDRV.@) - */ -void TTYDRV_InitMouse(LPMOUSE_EVENT_PROC proc) -{ -} - /*********************************************************************** * SetCursor (TTYDRV.@) */ diff --git a/dlls/user/mouse.c b/dlls/user/mouse.c index 8ec60ae0181..4f206a57acb 100644 --- a/dlls/user/mouse.c +++ b/dlls/user/mouse.c @@ -10,7 +10,6 @@ #include "debugtools.h" #include "callback.h" #include "builtin16.h" -#include "mouse.h" #include "windef.h" #include "wingdi.h" #include "winuser.h" @@ -35,6 +34,8 @@ typedef struct _MOUSEINFO /**********************************************************************/ +typedef VOID CALLBACK (*LPMOUSE_EVENT_PROC)(DWORD,DWORD,DWORD,DWORD,DWORD); + static LPMOUSE_EVENT_PROC DefMouseEventProc = NULL; /*********************************************************************** @@ -55,16 +56,6 @@ WORD WINAPI MOUSE_Inquire(LPMOUSEINFO mouseInfo) return sizeof(MOUSEINFO); } -/*********************************************************************** - * Enable (MOUSE.2) - */ -VOID WINAPI MOUSE_Enable(LPMOUSE_EVENT_PROC lpMouseEventProc) -{ - THUNK_Free( (FARPROC)DefMouseEventProc ); - DefMouseEventProc = lpMouseEventProc; - USER_Driver.pInitMouse( lpMouseEventProc ); -} - /**********************************************************************/ static VOID WINAPI MOUSE_CallMouseEventProc( FARPROC16 proc, @@ -86,14 +77,13 @@ static VOID WINAPI MOUSE_CallMouseEventProc( FARPROC16 proc, wine_call_to_16_regs_short( &context, 0 ); } -/**********************************************************************/ - -VOID WINAPI WIN16_MOUSE_Enable( FARPROC16 proc ) +/*********************************************************************** + * Enable (MOUSE.2) + */ +VOID WINAPI MOUSE_Enable( FARPROC16 proc ) { - LPMOUSE_EVENT_PROC thunk = - (LPMOUSE_EVENT_PROC)THUNK_Alloc( proc, (RELAY)MOUSE_CallMouseEventProc ); - - MOUSE_Enable( thunk ); + THUNK_Free( (FARPROC)DefMouseEventProc ); + DefMouseEventProc = (LPMOUSE_EVENT_PROC)THUNK_Alloc( proc, (RELAY)MOUSE_CallMouseEventProc ); } /*********************************************************************** @@ -103,5 +93,4 @@ VOID WINAPI MOUSE_Disable(VOID) { THUNK_Free( (FARPROC)DefMouseEventProc ); DefMouseEventProc = 0; - USER_Driver.pInitMouse( 0 ); } diff --git a/dlls/user/mouse.spec b/dlls/user/mouse.spec index 8f76b8a8544..423c295b3c6 100644 --- a/dlls/user/mouse.spec +++ b/dlls/user/mouse.spec @@ -4,7 +4,7 @@ owner user32 rsrc resources/mouse.res 1 pascal16 Inquire(ptr) MOUSE_Inquire -2 pascal16 Enable(segptr) WIN16_MOUSE_Enable +2 pascal16 Enable(segptr) MOUSE_Enable 3 pascal16 Disable() MOUSE_Disable 4 stub MOUSEGETINTVECT 5 stub GETSETMOUSEDATA diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c index 80f84fb5f7b..92dc3f52360 100644 --- a/dlls/user/user_main.c +++ b/dlls/user/user_main.c @@ -67,8 +67,6 @@ static BOOL load_driver(void) GET_USER_FUNC(GetKeyNameText); GET_USER_FUNC(ToUnicode); GET_USER_FUNC(Beep); - GET_USER_FUNC(GetDIState); - GET_USER_FUNC(GetDIData); GET_USER_FUNC(InitMouse); GET_USER_FUNC(SetCursor); GET_USER_FUNC(GetCursorPos); @@ -245,10 +243,10 @@ static BOOL process_attach(void) if (!WIN_CreateDesktopWindow()) return FALSE; /* Initialize keyboard driver */ - USER_Driver.pInitKeyboard( InputKeyStateTable ); + if (USER_Driver.pInitKeyboard) USER_Driver.pInitKeyboard( InputKeyStateTable ); /* Initialize mouse driver */ - MOUSE_Enable( mouse_event ); + if (USER_Driver.pInitMouse) USER_Driver.pInitMouse( InputKeyStateTable ); /* Initialize 16-bit serial communications */ COMM_Init(); diff --git a/dlls/x11drv/Makefile.in b/dlls/x11drv/Makefile.in index 9ad31aabdb8..cac15b1b0cd 100644 --- a/dlls/x11drv/Makefile.in +++ b/dlls/x11drv/Makefile.in @@ -9,6 +9,7 @@ IMPORTS = user32 gdi32 kernel32 C_SRCS = \ desktop.c \ dga2.c \ + mouse.c \ scroll.c \ window.c \ winpos.c \ diff --git a/windows/x11drv/mouse.c b/dlls/x11drv/mouse.c similarity index 57% rename from windows/x11drv/mouse.c rename to dlls/x11drv/mouse.c index a75f7735ec6..0d4d5b190ff 100644 --- a/windows/x11drv/mouse.c +++ b/dlls/x11drv/mouse.c @@ -7,21 +7,117 @@ #include "config.h" #include "ts_xlib.h" +#ifdef HAVE_LIBXXF86DGA2 +#include "ts_xf86dga2.h" +#endif #include "windef.h" #include "wine/winuser16.h" -#include "debugtools.h" -#include "mouse.h" -#include "win.h" #include "x11drv.h" +#include "debugtools.h" DEFAULT_DEBUG_CHANNEL(cursor); /**********************************************************************/ -static LONG X11DRV_MOUSE_WarpPointer = 0; /* hack; see DISPLAY_MoveCursor */ -static LPMOUSE_EVENT_PROC DefMouseEventProc = NULL; +#define NB_BUTTONS 5 /* Windows can handle 3 buttons and the wheel too */ + +static const UINT button_down_flags[NB_BUTTONS] = +{ + MOUSEEVENTF_LEFTDOWN, + MOUSEEVENTF_MIDDLEDOWN, + MOUSEEVENTF_RIGHTDOWN, + MOUSEEVENTF_WHEEL, + MOUSEEVENTF_WHEEL +}; + +static const UINT button_up_flags[NB_BUTTONS] = +{ + MOUSEEVENTF_LEFTUP, + MOUSEEVENTF_MIDDLEUP, + MOUSEEVENTF_RIGHTUP, + 0, + 0 +}; + +static BYTE *pKeyStateTable; + + +/*********************************************************************** + * get_coords + * + * get the coordinates of a mouse event + */ +static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt ) +{ + struct x11drv_win_data *data; + WND *win; + + if (!(win = WIN_GetPtr( *hwnd )) || win == WND_OTHER_PROCESS) return; + data = win->pDriverData; + + if (window == data->whole_window) + { + x -= data->client_rect.left; + y -= data->client_rect.top; + } + WIN_ReleasePtr( win ); + + pt->x = x; + pt->y = y; + if (*hwnd != GetDesktopWindow()) + { + ClientToScreen( *hwnd, pt ); + *hwnd = GetAncestor( *hwnd, GA_ROOT ); + } +} + + +/*********************************************************************** + * update_key_state + * + * Update the key state with what X provides us + */ +static void update_key_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); + pKeyStateTable[VK_SHIFT] = (state & ShiftMask ? 0x80 : 0); + pKeyStateTable[VK_CONTROL] = (state & ControlMask ? 0x80 : 0); +} + + +/*********************************************************************** + * send_mouse_event + */ +static void send_mouse_event( HWND hwnd, DWORD flags, DWORD posX, DWORD posY, + DWORD data, Time time ) +{ + INPUT input; + + TRACE("(%04lX,%ld,%ld)\n", flags, posX, posY ); + + 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; + } + + 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 = time - X11DRV_server_startticks; + input.u.mi.dwExtraInfo = (ULONG_PTR)hwnd; + SendInput( 1, &input, sizeof(input) ); +} + /*********************************************************************** * X11DRV_GetCursor @@ -198,46 +294,16 @@ void X11DRV_SetCursor( CURSORICONINFO *lpCursor ) /*********************************************************************** * SetCursorPos (X11DRV.@) */ -void X11DRV_SetCursorPos(INT wAbsX, INT wAbsY) +void X11DRV_SetCursorPos( INT x, INT y ) { - /* - * We do not want to create MotionNotify events here, - * otherwise we will get an endless recursion: - * XMotionEvent -> MOUSEEVENTF_MOVE -> mouse_event -> DisplayMoveCursor - * -> XWarpPointer -> XMotionEvent -> ... - * - * Unfortunately, the XWarpPointer call does create a MotionNotify - * event. So, we use a hack: before MOUSE_SendEvent calls the mouse event - * procedure, it sets a global flag. If this flag is set, we skip the - * XWarpPointer call. If we are *not* called from within MOUSE_SendEvent, - * we will call XWarpPointer, which will create a MotionNotify event. - * Strictly speaking, this is also wrong, but that should normally not - * have any negative effects ... - * - * But first of all, we check whether we already are at the position - * are supposed to move to; if so, we don't need to do anything. - */ + Display *display = thread_display(); - Display *display = thread_display(); - Window root, child; - int rootX, rootY, winX, winY; - unsigned int xstate; - - if (X11DRV_MOUSE_WarpPointer < 0) return; + TRACE( "warping to (%d,%d)\n", x, y ); - if (!TSXQueryPointer( display, root_window, &root, &child, - &rootX, &rootY, &winX, &winY, &xstate )) - return; - - if ( winX == wAbsX && winY == wAbsY ) - return; - - TRACE("(%d,%d): moving from (%d,%d)\n", wAbsX, wAbsY, winX, winY ); - - wine_tsx11_lock(); - XWarpPointer( display, root_window, root_window, 0, 0, 0, 0, wAbsX, wAbsY ); - XFlush( display ); /* just in case */ - wine_tsx11_unlock(); + wine_tsx11_lock(); + XWarpPointer( display, root_window, root_window, 0, 0, 0, 0, x, y ); + XFlush( display ); /* just in case */ + wine_tsx11_unlock(); } /*********************************************************************** @@ -262,62 +328,113 @@ void X11DRV_GetCursorPos(LPPOINT pos) /*********************************************************************** * InitMouse (X11DRV.@) */ -void X11DRV_InitMouse( LPMOUSE_EVENT_PROC proc ) +void X11DRV_InitMouse( BYTE *key_state_table ) { - static int init_done; + Window root, child; + int root_x, root_y, child_x, child_y; + unsigned int KeyState; - DefMouseEventProc = proc; - - if (!init_done) - { - Window root, child; - int root_x, root_y, child_x, child_y; - unsigned int KeyState; - - init_done = 1; - /* Get the current mouse position and simulate an absolute mouse - movement to initialize the mouse global variables */ - TSXQueryPointer( thread_display(), root_window, &root, &child, - &root_x, &root_y, &child_x, &child_y, &KeyState); - X11DRV_SendEvent(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, - root_x, root_y, X11DRV_EVENT_XStateToKeyState(KeyState), - 0, GetTickCount(), 0 ); - } + pKeyStateTable = key_state_table; + /* Get the current mouse position and simulate an absolute mouse + movement to initialize the mouse global variables */ + TSXQueryPointer( thread_display(), root_window, &root, &child, + &root_x, &root_y, &child_x, &child_y, &KeyState); + update_key_state( KeyState ); + send_mouse_event( 0, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, + root_x, root_y, 0, GetTickCount() + X11DRV_server_startticks ); } /*********************************************************************** - * X11DRV_SendEvent (internal) + * X11DRV_ButtonPress */ -void X11DRV_SendEvent( DWORD mouseStatus, DWORD posX, DWORD posY, - WORD keyState, DWORD data, DWORD time, HWND hWnd ) +void X11DRV_ButtonPress( HWND hwnd, XButtonEvent *event ) { - int iWndsLocks; - WINE_MOUSEEVENT wme; + int buttonNum = event->button - 1; + WORD wData = 0; + POINT pt; - if ( !DefMouseEventProc ) return; + if (buttonNum >= NB_BUTTONS) return; - TRACE("(%04lX,%ld,%ld)\n", mouseStatus, posX, posY ); + get_coords( &hwnd, event->window, event->x, event->y, &pt ); - if (mouseStatus & MOUSEEVENTF_ABSOLUTE) + switch (buttonNum) { - int width = GetSystemMetrics( SM_CXSCREEN ); - int height = GetSystemMetrics( SM_CYSCREEN ); - /* Relative mouse movements seems not to be scaled as absolute ones */ - posX = (((long)posX << 16) + width-1) / width; - posY = (((long)posY << 16) + height-1) / height; + case 3: + wData = WHEEL_DELTA; + break; + case 4: + wData = -WHEEL_DELTA; + break; } - - wme.magic = WINE_MOUSEEVENT_MAGIC; - wme.time = time; - wme.hWnd = hWnd; - wme.keyState = keyState; - - InterlockedDecrement( &X11DRV_MOUSE_WarpPointer ); - /* To avoid deadlocks, we have to suspend all locks on windows structures - before the program control is passed to the mouse driver */ - iWndsLocks = WIN_SuspendWndsLock(); - DefMouseEventProc( mouseStatus, posX, posY, data, (DWORD)&wme ); - WIN_RestoreWndsLock(iWndsLocks); - InterlockedIncrement( &X11DRV_MOUSE_WarpPointer ); + update_key_state( event->state ); + send_mouse_event( hwnd, button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE, + pt.x, pt.y, wData, event->time ); } + + +/*********************************************************************** + * X11DRV_ButtonRelease + */ +void X11DRV_ButtonRelease( HWND hwnd, XButtonEvent *event ) +{ + int buttonNum = event->button - 1; + POINT pt; + + if (buttonNum >= NB_BUTTONS || !button_up_flags[buttonNum]) return; + + 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_MotionNotify + */ +void X11DRV_MotionNotify( HWND hwnd, XMotionEvent *event ) +{ + POINT pt; + + 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 ); +} + + +#ifdef HAVE_LIBXXF86DGA2 +/********************************************************************** + * X11DRV_DGAMotionEvent + */ +void X11DRV_DGAMotionEvent( HWND hwnd, XDGAMotionEvent *event ) +{ + update_key_state( event->state ); + send_mouse_event( hwnd, MOUSEEVENTF_MOVE, event->dx, event->dy, 0, event->time ); +} + +/********************************************************************** + * X11DRV_DGAButtonPressEvent + */ +void X11DRV_DGAButtonPressEvent( HWND hwnd, XDGAButtonEvent *event ) +{ + int buttonNum = event->button - 1; + + if (buttonNum >= NB_BUTTONS) return; + update_key_state( event->state ); + send_mouse_event( hwnd, button_down_flags[buttonNum], 0, 0, 0, event->time ); +} + +/********************************************************************** + * X11DRV_DGAButtonReleaseEvent + */ +void X11DRV_DGAButtonReleaseEvent( HWND hwnd, XDGAButtonEvent *event ) +{ + int buttonNum = event->button - 1; + + if (buttonNum >= NB_BUTTONS) return; + update_key_state( event->state ); + send_mouse_event( hwnd, button_up_flags[buttonNum], 0, 0, 0, event->time ); +} +#endif /* HAVE_LIBXXF86DGA2 */ diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c index 380912e0bf1..bf5d0fa5ee7 100644 --- a/dlls/x11drv/window.c +++ b/dlls/x11drv/window.c @@ -117,7 +117,7 @@ static int get_window_attributes( Display *display, WND *win, XSetWindowAttribut ButtonPressMask | ButtonReleaseMask); if (is_window_top_level( win )) { - attr->event_mask |= StructureNotifyMask | FocusChangeMask; + attr->event_mask |= StructureNotifyMask | FocusChangeMask | KeymapStateMask; attr->cursor = X11DRV_GetCursor( display, GlobalLock16(GetCursor()) ); } return (CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap | CWCursor); diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec index ac08c9ec3c7..2c3efaf04a3 100644 --- a/dlls/x11drv/x11drv.spec +++ b/dlls/x11drv/x11drv.spec @@ -66,8 +66,6 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics @ cdecl GetKeyNameText(long str long) X11DRV_GetKeyNameText @ cdecl ToUnicode(long long ptr ptr long long) X11DRV_ToUnicode @ cdecl Beep() X11DRV_Beep -@ cdecl GetDIState(long ptr) X11DRV_GetDIState -@ cdecl GetDIData(ptr long ptr ptr long) X11DRV_GetDIData @ cdecl InitMouse(ptr) X11DRV_InitMouse @ cdecl SetCursor(ptr) X11DRV_SetCursor @ cdecl GetCursorPos(ptr) X11DRV_GetCursorPos diff --git a/include/mouse.h b/include/mouse.h deleted file mode 100644 index 7e5b9bad2df..00000000000 --- a/include/mouse.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * MOUSE driver interface - * - * Copyright 1998 Ulrich Weigand - */ - -#ifndef __WINE_MOUSE_H -#define __WINE_MOUSE_H - -#include "windef.h" -#include "user.h" - -/* Wine internals */ - -#define WINE_MOUSEEVENT_MAGIC ( ('M'<<24)|('A'<<16)|('U'<<8)|'S' ) -typedef struct _WINE_MOUSEEVENT -{ - DWORD magic; - DWORD keyState; - DWORD time; - HWND hWnd; -} WINE_MOUSEEVENT; - -#endif /* __WINE_MOUSE_H */ - diff --git a/include/user.h b/include/user.h index 8a4ac77e511..fb5603dfa72 100644 --- a/include/user.h +++ b/include/user.h @@ -31,9 +31,6 @@ extern WORD USER_HeapSel; #define USUD_FIRSTCLASS 0x0005 struct tagCURSORICONINFO; -struct DIDEVICEOBJECTDATA; - -typedef VOID CALLBACK (*LPMOUSE_EVENT_PROC)(DWORD,DWORD,DWORD,DWORD,DWORD); /* internal messages codes */ enum wine_internal_message @@ -44,6 +41,10 @@ enum wine_internal_message WM_WINE_SETPARENT }; +/* internal SendInput codes (FIXME) */ +#define WINE_INTERNAL_INPUT_MOUSE (16+INPUT_MOUSE) +#define WINE_INTERNAL_INPUT_KEYBOARD (16+INPUT_KEYBOARD) + typedef struct tagUSER_DRIVER { /* keyboard functions */ void (*pInitKeyboard)(LPBYTE); @@ -52,10 +53,8 @@ typedef struct tagUSER_DRIVER { INT (*pGetKeyNameText)(LONG,LPSTR,INT); INT (*pToUnicode)(UINT, UINT, LPBYTE, LPWSTR, int, UINT); void (*pBeep)(void); - BOOL (*pGetDIState)(DWORD, LPVOID); - BOOL (*pGetDIData)(BYTE *, DWORD, struct DIDEVICEOBJECTDATA *, LPDWORD, DWORD); /* mouse functions */ - void (*pInitMouse)(LPMOUSE_EVENT_PROC); + void (*pInitMouse)(LPBYTE); void (*pSetCursor)(struct tagCURSORICONINFO *); void (*pGetCursorPos)(LPPOINT); void (*pSetCursorPos)(INT,INT); @@ -108,9 +107,6 @@ extern void USER_CheckNotLock(void); extern BOOL USER_IsExitingThread( DWORD tid ); -VOID WINAPI MOUSE_Enable(LPMOUSE_EVENT_PROC lpMouseEventProc); -VOID WINAPI MOUSE_Disable(VOID); - /* Wine look */ typedef enum diff --git a/include/x11drv.h b/include/x11drv.h index 001e271eaa0..bd6a90c8b80 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -30,7 +30,6 @@ struct tagDC; struct tagDeviceCaps; struct tagPALETTEOBJ; struct tagWINDOWPOS; -struct DIDEVICEOBJECTDATA; /* X physical pen */ typedef struct @@ -349,8 +348,6 @@ extern BOOL X11DRV_GetClipboardData(UINT wFormat); /* X11 event driver */ -extern WORD X11DRV_EVENT_XStateToKeyState( int state ) ; - typedef enum { X11DRV_INPUT_RELATIVE, X11DRV_INPUT_ABSOLUTE @@ -361,14 +358,6 @@ extern INPUT_TYPE X11DRV_EVENT_SetInputMethod(INPUT_TYPE type); void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base) ; #endif -/* X11 mouse driver */ - -extern void X11DRV_InitMouse(LPMOUSE_EVENT_PROC); -extern void X11DRV_SetCursor(struct tagCURSORICONINFO *lpCursor); -extern void X11DRV_MoveCursor(WORD wAbsX, WORD wAbsY); -extern void X11DRV_SendEvent( DWORD mouseStatus, DWORD posX, DWORD posY, - WORD keyState, DWORD data, DWORD time, HWND hWnd ); - /* x11drv private window data */ struct x11drv_win_data { diff --git a/windows/input.c b/windows/input.c index 73cd69a193b..702e33445ae 100644 --- a/windows/input.c +++ b/windows/input.c @@ -26,7 +26,6 @@ #include "win.h" #include "hook.h" #include "input.h" -#include "mouse.h" #include "message.h" #include "queue.h" #include "debugtools.h" @@ -46,13 +45,6 @@ BYTE AsyncKeyStateTable[256]; /* Storage for the USER-maintained mouse positions */ static DWORD PosX, PosY; -#define GET_KEYSTATE() \ - ((InputKeyStateTable[SwappedButtons ? VK_RBUTTON : VK_LBUTTON] & 0x80 ? MK_LBUTTON : 0) | \ - (InputKeyStateTable[SwappedButtons ? VK_LBUTTON : VK_RBUTTON] & 0x80 ? MK_RBUTTON : 0) | \ - (InputKeyStateTable[VK_MBUTTON] & 0x80 ? MK_MBUTTON : 0) | \ - (InputKeyStateTable[VK_SHIFT] & 0x80 ? MK_SHIFT : 0) | \ - (InputKeyStateTable[VK_CONTROL] & 0x80 ? MK_CONTROL : 0)) - typedef union { struct @@ -70,6 +62,32 @@ typedef union } KEYLP; +/*********************************************************************** + * get_key_state + */ +static WORD get_key_state(void) +{ + WORD ret = 0; + + if (SwappedButtons) + { + if (InputKeyStateTable[VK_RBUTTON] & 0x80) ret |= MK_LBUTTON; + if (InputKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_RBUTTON; + } + else + { + if (InputKeyStateTable[VK_LBUTTON] & 0x80) ret |= MK_LBUTTON; + if (InputKeyStateTable[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; + return ret; +} + + /*********************************************************************** * queue_raw_hardware_message * @@ -103,7 +121,7 @@ static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lPar * * Put a keyboard event into a thread queue */ -static void queue_kbd_event( const KEYBDINPUT *ki ) +static void queue_kbd_event( const KEYBDINPUT *ki, UINT injected_flags ) { UINT message; KEYLP keylp; @@ -147,7 +165,7 @@ static void queue_kbd_event( const KEYBDINPUT *ki ) hook.vkCode = ki->wVk; hook.scanCode = ki->wScan; - hook.flags = keylp.lp2 >> 24; /* FIXME: LLKHF_INJECTED flag */ + hook.flags = (keylp.lp2 >> 24) | injected_flags; hook.time = ki->time; hook.dwExtraInfo = ki->dwExtraInfo; if (!HOOK_CallHooksW( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook )) @@ -159,27 +177,27 @@ static void queue_kbd_event( const KEYBDINPUT *ki ) /*********************************************************************** * queue_raw_mouse_message */ -static void queue_raw_mouse_message( UINT message, WPARAM wParam, LPARAM lParam, - int xPos, int yPos, DWORD time, ULONG_PTR extra_info ) +static void queue_raw_mouse_message( UINT message, UINT flags, INT x, INT y, const MOUSEINPUT *mi ) { MSLLHOOKSTRUCT hook; - hook.pt.x = xPos; - hook.pt.y = yPos; - hook.mouseData = wParam; - hook.flags = 0; /* FIXME: LLMHF_INJECTED flag */ - hook.time = time; - hook.dwExtraInfo = extra_info; + 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_CallHooksW( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook )) - queue_raw_hardware_message( message, wParam, lParam, xPos, yPos, time, extra_info ); + queue_raw_hardware_message( message, MAKEWPARAM( get_key_state(), mi->mouseData ), + 0, x, y, mi->time, mi->dwExtraInfo ); } /*********************************************************************** * queue_mouse_event */ -static void queue_mouse_event( const MOUSEINPUT *mi, WORD keystate ) +static void queue_mouse_event( const MOUSEINPUT *mi, UINT flags ) { if (mi->dwFlags & MOUSEEVENTF_ABSOLUTE) { @@ -208,53 +226,51 @@ static void queue_mouse_event( const MOUSEINPUT *mi, WORD keystate ) if (mi->dwFlags & MOUSEEVENTF_MOVE) { - queue_raw_mouse_message( WM_MOUSEMOVE, keystate, 0, PosX, PosY, - mi->time, mi->dwExtraInfo ); + queue_raw_mouse_message( WM_MOUSEMOVE, flags, PosX, PosY, mi ); } - if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN)) + if (mi->dwFlags & MOUSEEVENTF_LEFTDOWN) { InputKeyStateTable[VK_LBUTTON] |= 0x80; AsyncKeyStateTable[VK_LBUTTON] |= 0x80; - queue_raw_mouse_message( WM_LBUTTONDOWN, keystate, 0, PosX, PosY, - mi->time, mi->dwExtraInfo ); + queue_raw_mouse_message( SwappedButtons ? WM_RBUTTONDOWN : WM_LBUTTONDOWN, + flags, PosX, PosY, mi ); } - if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP)) + if (mi->dwFlags & MOUSEEVENTF_LEFTUP) { InputKeyStateTable[VK_LBUTTON] &= ~0x80; - queue_raw_mouse_message( WM_LBUTTONUP, keystate, 0, PosX, PosY, - mi->time, mi->dwExtraInfo ); + queue_raw_mouse_message( SwappedButtons ? WM_RBUTTONUP : WM_LBUTTONUP, + flags, PosX, PosY, mi ); } - if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN)) + if (mi->dwFlags & MOUSEEVENTF_RIGHTDOWN) { InputKeyStateTable[VK_RBUTTON] |= 0x80; AsyncKeyStateTable[VK_RBUTTON] |= 0x80; - queue_raw_mouse_message( WM_RBUTTONDOWN, keystate, 0, PosX, PosY, - mi->time, mi->dwExtraInfo ); + queue_raw_mouse_message( SwappedButtons ? WM_LBUTTONDOWN : WM_RBUTTONDOWN, + flags, PosX, PosY, mi ); } - if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP)) + if (mi->dwFlags & MOUSEEVENTF_RIGHTUP) { InputKeyStateTable[VK_RBUTTON] &= ~0x80; - queue_raw_mouse_message( WM_RBUTTONUP, keystate, 0, PosX, PosY, - mi->time, mi->dwExtraInfo ); + queue_raw_mouse_message( SwappedButtons ? 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, keystate, 0, PosX, PosY, - mi->time, mi->dwExtraInfo ); + 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, keystate, 0, PosX, PosY, - mi->time, mi->dwExtraInfo ); + queue_raw_mouse_message( WM_MBUTTONUP, flags, PosX, PosY, mi ); } if (mi->dwFlags & MOUSEEVENTF_WHEEL) { - queue_raw_mouse_message( WM_MOUSEWHEEL, MAKELONG( keystate, mi->mouseData), 0, - PosX, PosY, mi->time, mi->dwExtraInfo ); + queue_raw_mouse_message( WM_MOUSEWHEEL, flags, PosX, PosY, mi ); } + if (flags & LLMHF_INJECTED) /* we have to actually move the cursor */ + SetCursorPos( PosX, PosY ); } @@ -272,10 +288,16 @@ UINT WINAPI SendInput( UINT count, LPINPUT inputs, int size ) switch(inputs->type) { case INPUT_MOUSE: - queue_mouse_event( &inputs->u.mi, GET_KEYSTATE() ); + 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 ); + 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" ); @@ -326,49 +348,15 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy, DWORD dwData, DWORD dwExtraInfo ) { INPUT input; - WORD keyState; input.type = INPUT_MOUSE; input.u.mi.dx = dx; input.u.mi.dy = dy; input.u.mi.mouseData = dwData; input.u.mi.dwFlags = dwFlags; - - /* - * If we are called by the Wine mouse driver, use the additional - * info pointed to by the dwExtraInfo argument. - * Otherwise, we need to determine that info ourselves (probably - * less accurate, but we can't help that ...). - */ - if (dwExtraInfo && !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) ) - && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC ) - { - WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo; - - keyState = wme->keyState; - - if (keyState != GET_KEYSTATE()) - { - /* We need to update the keystate with what X provides us */ - InputKeyStateTable[SwappedButtons ? VK_RBUTTON : VK_LBUTTON] = (keyState & MK_LBUTTON ? 0x80 : 0); - InputKeyStateTable[SwappedButtons ? VK_LBUTTON : VK_RBUTTON] = (keyState & MK_RBUTTON ? 0x80 : 0); - InputKeyStateTable[VK_MBUTTON] = (keyState & MK_MBUTTON ? 0x80 : 0); - InputKeyStateTable[VK_SHIFT] = (keyState & MK_SHIFT ? 0x80 : 0); - InputKeyStateTable[VK_CONTROL] = (keyState & MK_CONTROL ? 0x80 : 0); - } - input.u.mi.time = wme->time; - input.u.mi.dwExtraInfo = (ULONG_PTR)wme->hWnd; - queue_mouse_event( &input.u.mi, keyState ); - } - else - { - input.u.mi.time = GetCurrentTime(); - input.u.mi.dwExtraInfo = dwExtraInfo; - SendInput( 1, &input, sizeof(input) ); - - if ( dwFlags & MOUSEEVENTF_MOVE ) /* we have to actually move the cursor */ - SetCursorPos( PosX, PosY ); - } + input.u.mi.time = GetCurrentTime(); + input.u.mi.dwExtraInfo = dwExtraInfo; + SendInput( 1, &input, sizeof(input) ); } diff --git a/windows/x11drv/Makefile.in b/windows/x11drv/Makefile.in index a9b9f3d2241..81ab5ccf873 100644 --- a/windows/x11drv/Makefile.in +++ b/windows/x11drv/Makefile.in @@ -8,8 +8,7 @@ MODULE = x11drv C_SRCS = \ clipboard.c \ event.c \ - keyboard.c \ - mouse.c + keyboard.c PROGRAMS = wineclipsrv diff --git a/windows/x11drv/event.c b/windows/x11drv/event.c index b773187e611..530db1ff2a0 100644 --- a/windows/x11drv/event.c +++ b/windows/x11drv/event.c @@ -26,7 +26,6 @@ #include "dce.h" #include "debugtools.h" #include "input.h" -#include "mouse.h" #include "options.h" #include "win.h" #include "winpos.h" @@ -46,11 +45,6 @@ extern Atom wmDeleteWindow; extern Atom dndProtocol; extern Atom dndSelection; -extern void X11DRV_KEYBOARD_UpdateState(void); - -#define NB_BUTTONS 5 /* Windows can handle 3 buttons and the wheel too */ - - #define DndNotDnd -1 /* OffiX drag&drop */ #define DndUnknown 0 #define DndRawData 1 @@ -85,9 +79,6 @@ static void EVENT_ProcessEvent( XEvent *event ); static BOOL X11DRV_CheckFocus(void); /* Event handlers */ -static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event ); -static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event ); -static void EVENT_MotionNotify( HWND hWnd, XMotionEvent *event ); static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event ); static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event ); static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple ); @@ -95,7 +86,11 @@ static void EVENT_SelectionClear( HWND hWnd, XSelectionClearEvent *event); static void EVENT_PropertyNotify( XPropertyEvent *event ); static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *event ); +extern void X11DRV_ButtonPress( HWND hwnd, XButtonEvent *event ); +extern void X11DRV_ButtonRelease( HWND hwnd, XButtonEvent *event ); +extern void X11DRV_MotionNotify( HWND hwnd, XMotionEvent *event ); extern void X11DRV_KeyEvent( HWND hwnd, XKeyEvent *event ); +extern void X11DRV_KeymapNotify( HWND hwnd, XKeymapEvent *event ); extern void X11DRV_Expose( HWND hwnd, XExposeEvent *event ); extern void X11DRV_MapNotify( HWND hwnd, XMapEvent *event ); extern void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event ); @@ -112,9 +107,9 @@ static int DGAKeyReleaseEventType; static BOOL DGAUsed = FALSE; static HWND DGAhwnd = 0; -static void EVENT_DGAMotionEvent( XDGAMotionEvent *event ); -static void EVENT_DGAButtonPressEvent( XDGAButtonEvent *event ); -static void EVENT_DGAButtonReleaseEvent( XDGAButtonEvent *event ); +extern void X11DRV_DGAMotionEvent( HWND hwnd, XDGAMotionEvent *event ); +extern void X11DRV_DGAButtonPressEvent( HWND hwnd, XDGAButtonEvent *event ); +extern void X11DRV_DGAButtonReleaseEvent( HWND hwnd, XDGAButtonEvent *event ); #endif /* Static used for the current input method */ @@ -213,17 +208,17 @@ static void EVENT_ProcessEvent( XEvent *event ) if (DGAUsed) { if (event->type == DGAMotionEventType) { TRACE("DGAMotionEvent received.\n"); - EVENT_DGAMotionEvent((XDGAMotionEvent *) event); + X11DRV_DGAMotionEvent( DGAhwnd, (XDGAMotionEvent *)event ); return; } if (event->type == DGAButtonPressEventType) { TRACE("DGAButtonPressEvent received.\n"); - EVENT_DGAButtonPressEvent((XDGAButtonEvent *) event); + X11DRV_DGAButtonPressEvent( DGAhwnd, (XDGAButtonEvent *)event ); return; } if (event->type == DGAButtonReleaseEventType) { TRACE("DGAButtonReleaseEvent received.\n"); - EVENT_DGAButtonReleaseEvent((XDGAButtonEvent *) event); + X11DRV_DGAButtonReleaseEvent( DGAhwnd, (XDGAButtonEvent *)event ); return; } if ((event->type == DGAKeyPressEventType) || @@ -277,17 +272,17 @@ static void EVENT_ProcessEvent( XEvent *event ) /* FIXME: should generate a motion event if event point is different from current pos */ X11DRV_KeyEvent( hWnd, (XKeyEvent*)event ); break; - + case ButtonPress: - EVENT_ButtonPress( hWnd, (XButtonEvent*)event ); + X11DRV_ButtonPress( hWnd, (XButtonEvent*)event ); break; - + case ButtonRelease: - EVENT_ButtonRelease( hWnd, (XButtonEvent*)event ); + X11DRV_ButtonRelease( hWnd, (XButtonEvent*)event ); break; case MotionNotify: - EVENT_MotionNotify( hWnd, (XMotionEvent*)event ); + X11DRV_MotionNotify( hWnd, (XMotionEvent*)event ); break; case FocusIn: @@ -337,6 +332,10 @@ static void EVENT_ProcessEvent( XEvent *event ) X11DRV_UnmapNotify( hWnd, (XUnmapEvent *)event ); break; + case KeymapNotify: + X11DRV_KeymapNotify( hWnd, (XKeymapEvent *)event ); + break; + case MappingNotify: X11DRV_MappingNotify( (XMappingEvent *) event ); break; @@ -349,162 +348,6 @@ static void EVENT_ProcessEvent( XEvent *event ) TRACE( "returns.\n" ); } -/*********************************************************************** - * X11DRV_EVENT_XStateToKeyState - * - * Translate a X event state (Button1Mask, ShiftMask, etc...) to - * a Windows key state (MK_SHIFT, MK_CONTROL, etc...) - */ -WORD X11DRV_EVENT_XStateToKeyState( int state ) -{ - int kstate = 0; - - if (state & Button1Mask) kstate |= MK_LBUTTON; - if (state & Button2Mask) kstate |= MK_MBUTTON; - if (state & Button3Mask) kstate |= MK_RBUTTON; - if (state & ShiftMask) kstate |= MK_SHIFT; - if (state & ControlMask) kstate |= MK_CONTROL; - return kstate; -} - - -/* get the coordinates of a mouse event */ -static void get_coords( HWND *hwnd, Window window, int x, int y, POINT *pt ) -{ - struct x11drv_win_data *data; - WND *win; - - if (!(win = WIN_FindWndPtr( *hwnd ))) return; - data = win->pDriverData; - - if (window == data->whole_window) - { - x -= data->client_rect.left; - y -= data->client_rect.top; - } - WIN_ReleaseWndPtr( win ); - - pt->x = x; - pt->y = y; - if (*hwnd != GetDesktopWindow()) - { - ClientToScreen( *hwnd, pt ); - *hwnd = GetAncestor( *hwnd, GA_ROOT ); - } -} - - -/*********************************************************************** - * EVENT_MotionNotify - */ -static void EVENT_MotionNotify( HWND hWnd, XMotionEvent *event ) -{ - POINT pt; - - if (current_input_type == X11DRV_INPUT_ABSOLUTE) - { - get_coords( &hWnd, event->window, event->x, event->y, &pt ); - X11DRV_SendEvent( MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE, pt.x, pt.y, - X11DRV_EVENT_XStateToKeyState( event->state ), 0, - event->time - X11DRV_server_startticks, hWnd); - } - else - { - X11DRV_SendEvent( MOUSEEVENTF_MOVE, - event->x_root, event->y_root, - X11DRV_EVENT_XStateToKeyState( event->state ), 0, - event->time - X11DRV_server_startticks, hWnd); - } -} - - -/*********************************************************************** - * EVENT_ButtonPress - */ -static void EVENT_ButtonPress( HWND hWnd, XButtonEvent *event ) -{ - static const WORD statusCodes[NB_BUTTONS] = { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN, - MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_WHEEL, - MOUSEEVENTF_WHEEL}; - int buttonNum = event->button - 1; - WORD keystate, wData = 0; - POINT pt; - - if (buttonNum >= NB_BUTTONS) return; - - get_coords( &hWnd, event->window, event->x, event->y, &pt ); - - /* Get the compatible keystate */ - keystate = X11DRV_EVENT_XStateToKeyState( event->state ); - - /* - * Make sure that the state of the button that was just - * pressed is "down". - */ - switch (buttonNum) - { - case 0: - keystate |= MK_LBUTTON; - break; - case 1: - keystate |= MK_MBUTTON; - break; - case 2: - keystate |= MK_RBUTTON; - break; - case 3: - wData = WHEEL_DELTA; - break; - case 4: - wData = -WHEEL_DELTA; - break; - } - - X11DRV_SendEvent( statusCodes[buttonNum] | MOUSEEVENTF_ABSOLUTE, pt.x, pt.y, - keystate, wData, event->time - X11DRV_server_startticks, hWnd); -} - - -/*********************************************************************** - * EVENT_ButtonRelease - */ -static void EVENT_ButtonRelease( HWND hWnd, XButtonEvent *event ) -{ - static const WORD statusCodes[NB_BUTTONS] = { MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP, - MOUSEEVENTF_RIGHTUP, 0, 0 }; - int buttonNum = event->button - 1; - WORD keystate; - POINT pt; - - if (buttonNum >= NB_BUTTONS) return; - - get_coords( &hWnd, event->window, event->x, event->y, &pt ); - - /* Get the compatible keystate */ - keystate = X11DRV_EVENT_XStateToKeyState( event->state ); - - /* - * Make sure that the state of the button that was just - * released is "up". - */ - switch (buttonNum) - { - case 0: - keystate &= ~MK_LBUTTON; - break; - case 1: - keystate &= ~MK_MBUTTON; - break; - case 2: - keystate &= ~MK_RBUTTON; - break; - default: - return; - } - X11DRV_SendEvent( statusCodes[buttonNum] | MOUSEEVENTF_ABSOLUTE, pt.x, pt.y, - keystate, 0, event->time - X11DRV_server_startticks, hWnd); -} - /********************************************************************** * EVENT_FocusIn @@ -543,10 +386,7 @@ static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event ) } if (event->detail != NotifyPointer && hWnd != GetForegroundWindow()) - { SetForegroundWindow( hWnd ); - X11DRV_KEYBOARD_UpdateState(); - } } @@ -1470,71 +1310,4 @@ void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base) DGAKeyReleaseEventType = event_base + KeyRelease; } } - -/* DGA2 event handlers */ -static void EVENT_DGAMotionEvent( XDGAMotionEvent *event ) -{ - X11DRV_SendEvent( MOUSEEVENTF_MOVE, event->dx, event->dy, - X11DRV_EVENT_XStateToKeyState( event->state ), 0, - event->time - X11DRV_server_startticks, DGAhwnd ); -} - -static void EVENT_DGAButtonPressEvent( XDGAButtonEvent *event ) -{ - static WORD statusCodes[NB_BUTTONS] = - { MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_RIGHTDOWN }; - int buttonNum = event->button - 1; - - WORD keystate; - - if (buttonNum >= NB_BUTTONS) return; - - keystate = X11DRV_EVENT_XStateToKeyState( event->state ); - - switch (buttonNum) - { - case 0: - keystate |= MK_LBUTTON; - break; - case 1: - keystate |= MK_MBUTTON; - break; - case 2: - keystate |= MK_RBUTTON; - break; - } - - X11DRV_SendEvent( statusCodes[buttonNum], 0, 0, keystate, 0, - event->time - X11DRV_server_startticks, DGAhwnd ); -} - -static void EVENT_DGAButtonReleaseEvent( XDGAButtonEvent *event ) -{ - static WORD statusCodes[NB_BUTTONS] = - { MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_RIGHTUP }; - int buttonNum = event->button - 1; - - WORD keystate; - - if (buttonNum >= NB_BUTTONS) return; - - keystate = X11DRV_EVENT_XStateToKeyState( event->state ); - - switch (buttonNum) - { - case 0: - keystate &= ~MK_LBUTTON; - break; - case 1: - keystate &= ~MK_MBUTTON; - break; - case 2: - keystate &= ~MK_RBUTTON; - break; - } - - X11DRV_SendEvent( statusCodes[buttonNum], 0, 0, keystate, 0, - event->time - X11DRV_server_startticks, DGAhwnd ); -} - #endif diff --git a/windows/x11drv/keyboard.c b/windows/x11drv/keyboard.c index 30145629194..0ff17cb2ade 100644 --- a/windows/x11drv/keyboard.c +++ b/windows/x11drv/keyboard.c @@ -27,12 +27,10 @@ #include "windef.h" #include "wingdi.h" #include "wine/winuser16.h" -#include "dinput.h" -#include "debugtools.h" -#include "user.h" #include "winnls.h" #include "win.h" #include "x11drv.h" +#include "debugtools.h" DEFAULT_DEBUG_CHANNEL(keyboard); DECLARE_DEBUG_CHANNEL(key); @@ -512,92 +510,102 @@ static unsigned kbd_layout=0; /* index into above table of layouts */ /* Yes, to distinguish based on scan codes, also for PrtScn key ... GA */ -static const WORD special_key_vkey[] = +static const WORD nonchar_key_vkey[256] = { + /* unused */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF00 */ + /* special keys */ VK_BACK, VK_TAB, 0, VK_CLEAR, 0, VK_RETURN, 0, 0, /* FF08 */ 0, 0, 0, VK_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */ - 0, 0, 0, VK_ESCAPE /* FF18 */ -}; -static const WORD special_key_scan[] = -{ - 0x0E, 0x0F, 0, /*?*/ 0, 0, 0x1C, 0, 0, /* FF08 */ - 0, 0, 0, 0x45, 0x46, 0 , 0, 0, /* FF10 */ - 0, 0, 0, 0x01 /* FF18 */ -}; - -static const WORD cursor_key_vkey[] = -{ - VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR, - VK_NEXT, VK_END /* FF50 */ -}; -static const WORD cursor_key_scan[] = -{ - 0x147, 0x14B, 0x148, 0x14D, 0x150, 0x149, 0x151, 0x14F /* FF50 */ -}; - -static const WORD misc_key_vkey[] = -{ + 0, 0, 0, VK_ESCAPE, 0, 0, 0, 0, /* FF18 */ + /* unused */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF20 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF28 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF30 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF38 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF40 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF48 */ + /* cursor keys */ + VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, /* FF50 */ + VK_DOWN, VK_PRIOR, VK_NEXT, VK_END, + 0, 0, 0, 0, 0, 0, 0, 0, /* FF58 */ + /* misc keys */ VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */ - VK_CANCEL, VK_HELP, VK_CANCEL, VK_CANCEL /* FF68 */ -}; -static const WORD misc_key_scan[] = -{ - /*?*/ 0, 0x137, /*?*/ 0, 0x152, 0, 0, 0, 0, /* FF60 */ - /*?*/ 0, /*?*/ 0, 0x38, 0x146 /* FF68 */ -}; - -static const WORD keypad_key_vkey[] = -{ - 0, VK_NUMLOCK, /* FF7E */ + VK_CANCEL, VK_HELP, VK_CANCEL, VK_CANCEL, 0, 0, 0, 0, /* FF68 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FF70 */ + /* keypad keys */ + 0, 0, 0, 0, 0, 0, 0, VK_NUMLOCK, /* FF78 */ 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */ 0, 0, 0, 0, 0, VK_RETURN, 0, 0, /* FF88 */ 0, 0, 0, 0, 0, VK_HOME, VK_LEFT, VK_UP, /* FF90 */ - VK_RIGHT, VK_DOWN, VK_PRIOR, VK_NEXT, VK_END, 0, - VK_INSERT, VK_DELETE, /* FF98 */ + VK_RIGHT, VK_DOWN, VK_PRIOR, VK_NEXT, /* FF98 */ + VK_END, 0, VK_INSERT, VK_DELETE, 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */ - 0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT, - VK_DECIMAL, VK_DIVIDE, /* FFA8 */ - VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, - VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */ - VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */ -}; -static const WORD keypad_key_scan[] = -{ - 0x138, 0x145, /* FF7E */ - 0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */ - 0, 0, 0, 0, 0, 0x11C, 0, 0, /* FF88 */ - 0, 0, 0, 0, 0, 0x47, 0x4B, 0x48, /* FF90 */ - 0x4D, 0x50, 0x49, 0x51, 0x4F, 0x4C, 0x52, 0x53, /* FF98 */ - 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */ - 0, 0, 0x37, 0x4E, /*?*/ 0, 0x4A, 0x53, 0x135, /* FFA8 */ - 0x52, 0x4F, 0x50, 0x51, 0x4B, 0x4C, 0x4D, 0x47, /* FFB0 */ - 0x48, 0x49 /* FFB8 */ -}; - -static const WORD function_key_vkey[] = -{ - VK_F1, VK_F2, /* FFBE */ + 0, 0, VK_MULTIPLY, VK_ADD, /* FFA8 */ + VK_SEPARATOR, VK_SUBTRACT, VK_DECIMAL, VK_DIVIDE, + VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, /* FFB0 */ + VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, + VK_NUMPAD8, VK_NUMPAD9, 0, 0, 0, 0, /* FFB8 */ + /* function keys */ + VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */ - VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16 /* FFC8 */ -}; -static const WORD function_key_scan[] = -{ - 0x3B, 0x3C, /* FFBE */ - 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, /* FFC0 */ - 0x57, 0x58, 0, 0, 0, 0 /* FFC8 */ + VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16, 0, 0, /* FFC8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FFD0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FFD8 */ + /* modifier keys */ + 0, VK_SHIFT, VK_SHIFT, VK_CONTROL, /* FFE0 */ + VK_CONTROL, VK_CAPITAL, 0, VK_MENU, + VK_MENU, VK_MENU, VK_MENU, 0, 0, 0, 0, 0, /* FFE8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* FFF0 */ + 0, 0, 0, 0, 0, 0, 0, VK_DELETE /* FFF8 */ }; -static const WORD modifier_key_vkey[] = +static const WORD nonchar_key_scan[256] = { - VK_SHIFT, VK_SHIFT, VK_CONTROL, VK_CONTROL, VK_CAPITAL, 0, /* FFE1 */ - VK_MENU, VK_MENU, VK_MENU, VK_MENU /* FFE7 */ -}; -static const WORD modifier_key_scan[] = -{ - 0x2A, 0x36, 0x1D, 0x11D, 0x3A, 0, /* FFE1 */ - 0x38, 0x138, 0x38, 0x138 /* FFE7 */ + /* unused */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF00 */ + /* special keys */ + 0x0E, 0x0F, 0x00, /*?*/ 0, 0x00, 0x1C, 0x00, 0x00, /* FF08 */ + 0x00, 0x00, 0x00, 0x45, 0x46, 0x00, 0x00, 0x00, /* FF10 */ + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* FF18 */ + /* unused */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF20 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF28 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF30 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF38 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF40 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF48 */ + /* cursor keys */ + 0x147, 0x14B, 0x148, 0x14D, 0x150, 0x149, 0x151, 0x14F, /* FF50 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF58 */ + /* misc keys */ + /*?*/ 0, 0x137, /*?*/ 0, 0x152, 0x00, 0x00, 0x00, 0x00, /* FF60 */ + /*?*/ 0, /*?*/ 0, 0x38, 0x146, 0x00, 0x00, 0x00, 0x00, /* FF68 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF70 */ + /* keypad keys */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x138, 0x145, /* FF78 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF80 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x11C, 0x00, 0x00, /* FF88 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x4B, 0x48, /* FF90 */ + 0x4D, 0x50, 0x49, 0x51, 0x4F, 0x4C, 0x52, 0x53, /* FF98 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFA0 */ + 0x00, 0x00, 0x37, 0x4E, /*?*/ 0, 0x4A, 0x53, 0x135, /* FFA8 */ + 0x52, 0x4F, 0x50, 0x51, 0x4B, 0x4C, 0x4D, 0x47, /* FFB0 */ + 0x48, 0x49, 0x00, 0x00, 0x00, 0x00, /* FFB8 */ + /* function keys */ + 0x3B, 0x3C, + 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, /* FFC0 */ + 0x57, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFC8 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFD0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFD8 */ + /* modifier keys */ + 0x00, 0x2A, 0x36, 0x1D, 0x11D, 0x3A, 0x00, 0x38, /* FFE0 */ + 0x138, 0x38, 0x138, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFE8 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FFF0 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x153 /* FFF8 */ }; + /* Returns the Windows virtual key code associated with the X event */ static WORD EVENT_event_to_vkey( XKeyEvent *e) { @@ -609,7 +617,7 @@ static WORD EVENT_event_to_vkey( XKeyEvent *e) && (e->state & NumLockMask)) /* Only the Keypad keys 0-9 and . send different keysyms * depending on the NumLock state */ - return keypad_key_vkey[(keysym & 0xFF) - 0x7E]; + return nonchar_key_vkey[keysym & 0xFF]; return keyc2vkey[e->keycode]; } @@ -620,11 +628,11 @@ static BOOL NumState=FALSE, CapsState=FALSE; /*********************************************************************** * send_keyboard_input */ -void send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time ) +static void send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time ) { INPUT input; - input.type = INPUT_KEYBOARD; + input.type = WINE_INTERNAL_INPUT_KEYBOARD; input.u.ki.wVk = wVk; input.u.ki.wScan = wScan; input.u.ki.dwFlags = dwFlags; @@ -686,7 +694,7 @@ static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, DWORD event_ * Updates internal state for , depending on key under X * */ -static void KEYBOARD_UpdateOneState ( int vkey, int state ) +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) @@ -695,41 +703,44 @@ static void KEYBOARD_UpdateOneState ( int vkey, int state ) vkey, pKeyStateTable[vkey]); /* Fake key being pressed inside wine */ - send_keyboard_input( vkey, 0, state? 0 : KEYEVENTF_KEYUP, GetTickCount() ); + send_keyboard_input( vkey, 0, state? 0 : KEYEVENTF_KEYUP, time ); TRACE("State after %#.2x \n",pKeyStateTable[vkey]); } } /*********************************************************************** - * X11DRV_KEYBOARD_UpdateState + * X11DRV_KeymapNotify * - * Update modifiers state (Ctrl, Alt, Shift) - * when window is activated (called by EVENT_FocusIn in event.c) + * Update modifiers state (Ctrl, Alt, Shift) when window is activated. * * This handles the case where one uses Ctrl+... Alt+... or Shift+.. to switch * from wine to another application and back. - * Toggle keys are handled in HandleEvent. (because XQueryKeymap says nothing - * about them) + * Toggle keys are handled in HandleEvent. */ -void X11DRV_KEYBOARD_UpdateState ( void ) +void X11DRV_KeymapNotify( HWND hwnd, XKeymapEvent *event ) { -/* extract a bit from the char[32] bit suite */ -#define KeyState(keycode) ((keys_return[keycode/8] & (1<<(keycode%8)))!=0) + int i, j, alt, control, shift; + DWORD time = GetCurrentTime(); - char keys_return[32]; - - TRACE("called\n"); - if (!TSXQueryKeymap(thread_display(), keys_return)) { - ERR("Error getting keymap !\n"); - return; + alt = control = shift = 0; + for (i = 0; i < 32; i++) + { + if (!event->key_vector[i]) continue; + for (j = 0; j < 8; j++) + { + if (!(event->key_vector[i] & (1<> 8) == 0xFF) /* non-character key */ { - int key = keysym & 0xff; - - if (key >= 0x08 && key <= 0x1B) { /* special key */ - vkey = special_key_vkey[key - 0x08]; - scan = special_key_scan[key - 0x08]; - } else if (key >= 0x50 && key <= 0x57) { /* cursor key */ - vkey = cursor_key_vkey[key - 0x50]; - scan = cursor_key_scan[key - 0x50]; - } else if (key >= 0x60 && key <= 0x6B) { /* miscellaneous key */ - vkey = misc_key_vkey[key - 0x60]; - scan = misc_key_scan[key - 0x60]; - } else if (key >= 0x7E && key <= 0xB9) { /* keypad key */ - vkey = keypad_key_vkey[key - 0x7E]; - scan = keypad_key_scan[key - 0x7E]; - } else if (key >= 0xBE && key <= 0xCD) { /* function key */ - vkey = function_key_vkey[key - 0xBE] | 0x100; /* set extended bit */ - scan = function_key_scan[key - 0xBE]; - } else if (key >= 0xE1 && key <= 0xEA) { /* modifier key */ - vkey = modifier_key_vkey[key - 0xE1]; - scan = modifier_key_scan[key - 0xE1]; - } else if (key == 0xFF) { /* DEL key */ - vkey = VK_DELETE; - scan = 0x153; - } + vkey = nonchar_key_vkey[keysym & 0xff]; + scan = nonchar_key_scan[keysym & 0xff]; /* set extended bit when necessary */ if (scan & 0x100) vkey |= 0x100; } else if (keysym == 0x20) { /* Spacebar */ @@ -1654,72 +1643,3 @@ void X11DRV_Beep(void) { TSXBell(thread_display(), 0); } - -/*********************************************************************** - * GetDIState (X11DRV.@) - */ -BOOL X11DRV_GetDIState(DWORD len, LPVOID ptr) -{ - if (len==256) { - int keyc,vkey; - - memset(ptr,0,256); - for (keyc=min_keycode;keyc