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.
This commit is contained in:
Alexandre Julliard 2001-10-18 21:38:59 +00:00
parent 7641ce3a5c
commit 32fb580515
17 changed files with 422 additions and 715 deletions

View File

@ -29,7 +29,6 @@ struct tagWND;
struct tagCURSORICONINFO; struct tagCURSORICONINFO;
struct tagCREATESTRUCTA; struct tagCREATESTRUCTA;
struct tagWINDOWPOS; struct tagWINDOWPOS;
struct DIDEVICEOBJECTDATA;
#if defined(HAVE_LIBCURSES) || defined(HAVE_LIBNCURSES) #if defined(HAVE_LIBCURSES) || defined(HAVE_LIBNCURSES)
#define WINE_CURSES #define WINE_CURSES

View File

@ -47,15 +47,11 @@ debug_channels (ttydrv)
# USER driver # USER driver
@ cdecl InitKeyboard() TTYDRV_InitKeyboard
@ cdecl VkKeyScan(long) TTYDRV_VkKeyScan @ cdecl VkKeyScan(long) TTYDRV_VkKeyScan
@ cdecl MapVirtualKey(long long) TTYDRV_MapVirtualKey @ cdecl MapVirtualKey(long long) TTYDRV_MapVirtualKey
@ cdecl GetKeyNameText(long str long) TTYDRV_GetKeyNameText @ cdecl GetKeyNameText(long str long) TTYDRV_GetKeyNameText
@ cdecl ToUnicode(long long ptr ptr long long) TTYDRV_ToUnicode @ cdecl ToUnicode(long long ptr ptr long long) TTYDRV_ToUnicode
@ cdecl Beep() TTYDRV_Beep @ 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 SetCursor(ptr) TTYDRV_SetCursor
@ cdecl GetScreenSaveActive() TTYDRV_GetScreenSaveActive @ cdecl GetScreenSaveActive() TTYDRV_GetScreenSaveActive
@ cdecl SetScreenSaveActive(long) TTYDRV_SetScreenSaveActive @ cdecl SetScreenSaveActive(long) TTYDRV_SetScreenSaveActive

View File

@ -12,13 +12,6 @@
DEFAULT_DEBUG_CHANNEL(ttydrv); DEFAULT_DEBUG_CHANNEL(ttydrv);
/***********************************************************************
* InitKeyboard (TTYDRV.@)
*/
void TTYDRV_InitKeyboard(void)
{
}
/*********************************************************************** /***********************************************************************
* VkKeyScan (TTYDRV.@) * 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.@) * SetCursor (TTYDRV.@)
*/ */

View File

@ -10,7 +10,6 @@
#include "debugtools.h" #include "debugtools.h"
#include "callback.h" #include "callback.h"
#include "builtin16.h" #include "builtin16.h"
#include "mouse.h"
#include "windef.h" #include "windef.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.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; static LPMOUSE_EVENT_PROC DefMouseEventProc = NULL;
/*********************************************************************** /***********************************************************************
@ -55,16 +56,6 @@ WORD WINAPI MOUSE_Inquire(LPMOUSEINFO mouseInfo)
return sizeof(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, 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 ); wine_call_to_16_regs_short( &context, 0 );
} }
/**********************************************************************/ /***********************************************************************
* Enable (MOUSE.2)
VOID WINAPI WIN16_MOUSE_Enable( FARPROC16 proc ) */
VOID WINAPI MOUSE_Enable( FARPROC16 proc )
{ {
LPMOUSE_EVENT_PROC thunk = THUNK_Free( (FARPROC)DefMouseEventProc );
(LPMOUSE_EVENT_PROC)THUNK_Alloc( proc, (RELAY)MOUSE_CallMouseEventProc ); DefMouseEventProc = (LPMOUSE_EVENT_PROC)THUNK_Alloc( proc, (RELAY)MOUSE_CallMouseEventProc );
MOUSE_Enable( thunk );
} }
/*********************************************************************** /***********************************************************************
@ -103,5 +93,4 @@ VOID WINAPI MOUSE_Disable(VOID)
{ {
THUNK_Free( (FARPROC)DefMouseEventProc ); THUNK_Free( (FARPROC)DefMouseEventProc );
DefMouseEventProc = 0; DefMouseEventProc = 0;
USER_Driver.pInitMouse( 0 );
} }

View File

@ -4,7 +4,7 @@ owner user32
rsrc resources/mouse.res rsrc resources/mouse.res
1 pascal16 Inquire(ptr) MOUSE_Inquire 1 pascal16 Inquire(ptr) MOUSE_Inquire
2 pascal16 Enable(segptr) WIN16_MOUSE_Enable 2 pascal16 Enable(segptr) MOUSE_Enable
3 pascal16 Disable() MOUSE_Disable 3 pascal16 Disable() MOUSE_Disable
4 stub MOUSEGETINTVECT 4 stub MOUSEGETINTVECT
5 stub GETSETMOUSEDATA 5 stub GETSETMOUSEDATA

View File

@ -67,8 +67,6 @@ static BOOL load_driver(void)
GET_USER_FUNC(GetKeyNameText); GET_USER_FUNC(GetKeyNameText);
GET_USER_FUNC(ToUnicode); GET_USER_FUNC(ToUnicode);
GET_USER_FUNC(Beep); GET_USER_FUNC(Beep);
GET_USER_FUNC(GetDIState);
GET_USER_FUNC(GetDIData);
GET_USER_FUNC(InitMouse); GET_USER_FUNC(InitMouse);
GET_USER_FUNC(SetCursor); GET_USER_FUNC(SetCursor);
GET_USER_FUNC(GetCursorPos); GET_USER_FUNC(GetCursorPos);
@ -245,10 +243,10 @@ static BOOL process_attach(void)
if (!WIN_CreateDesktopWindow()) return FALSE; if (!WIN_CreateDesktopWindow()) return FALSE;
/* Initialize keyboard driver */ /* Initialize keyboard driver */
USER_Driver.pInitKeyboard( InputKeyStateTable ); if (USER_Driver.pInitKeyboard) USER_Driver.pInitKeyboard( InputKeyStateTable );
/* Initialize mouse driver */ /* Initialize mouse driver */
MOUSE_Enable( mouse_event ); if (USER_Driver.pInitMouse) USER_Driver.pInitMouse( InputKeyStateTable );
/* Initialize 16-bit serial communications */ /* Initialize 16-bit serial communications */
COMM_Init(); COMM_Init();

View File

@ -9,6 +9,7 @@ IMPORTS = user32 gdi32 kernel32
C_SRCS = \ C_SRCS = \
desktop.c \ desktop.c \
dga2.c \ dga2.c \
mouse.c \
scroll.c \ scroll.c \
window.c \ window.c \
winpos.c \ winpos.c \

View File

@ -7,21 +7,117 @@
#include "config.h" #include "config.h"
#include "ts_xlib.h" #include "ts_xlib.h"
#ifdef HAVE_LIBXXF86DGA2
#include "ts_xf86dga2.h"
#endif
#include "windef.h" #include "windef.h"
#include "wine/winuser16.h" #include "wine/winuser16.h"
#include "debugtools.h"
#include "mouse.h"
#include "win.h"
#include "x11drv.h" #include "x11drv.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(cursor); DEFAULT_DEBUG_CHANNEL(cursor);
/**********************************************************************/ /**********************************************************************/
static LONG X11DRV_MOUSE_WarpPointer = 0; /* hack; see DISPLAY_MoveCursor */ #define NB_BUTTONS 5 /* Windows can handle 3 buttons and the wheel too */
static LPMOUSE_EVENT_PROC DefMouseEventProc = NULL;
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 * X11DRV_GetCursor
@ -198,46 +294,16 @@ void X11DRV_SetCursor( CURSORICONINFO *lpCursor )
/*********************************************************************** /***********************************************************************
* SetCursorPos (X11DRV.@) * SetCursorPos (X11DRV.@)
*/ */
void X11DRV_SetCursorPos(INT wAbsX, INT wAbsY) void X11DRV_SetCursorPos( INT x, INT y )
{ {
/* Display *display = thread_display();
* 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(); TRACE( "warping to (%d,%d)\n", x, y );
Window root, child;
int rootX, rootY, winX, winY;
unsigned int xstate;
if (X11DRV_MOUSE_WarpPointer < 0) return;
if (!TSXQueryPointer( display, root_window, &root, &child, wine_tsx11_lock();
&rootX, &rootY, &winX, &winY, &xstate )) XWarpPointer( display, root_window, root_window, 0, 0, 0, 0, x, y );
return; XFlush( display ); /* just in case */
wine_tsx11_unlock();
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();
} }
/*********************************************************************** /***********************************************************************
@ -262,62 +328,113 @@ void X11DRV_GetCursorPos(LPPOINT pos)
/*********************************************************************** /***********************************************************************
* InitMouse (X11DRV.@) * 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; pKeyStateTable = key_state_table;
/* Get the current mouse position and simulate an absolute mouse
if (!init_done) movement to initialize the mouse global variables */
{ TSXQueryPointer( thread_display(), root_window, &root, &child,
Window root, child; &root_x, &root_y, &child_x, &child_y, &KeyState);
int root_x, root_y, child_x, child_y; update_key_state( KeyState );
unsigned int KeyState; send_mouse_event( 0, MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
root_x, root_y, 0, GetTickCount() + X11DRV_server_startticks );
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 );
}
} }
/*********************************************************************** /***********************************************************************
* X11DRV_SendEvent (internal) * X11DRV_ButtonPress
*/ */
void X11DRV_SendEvent( DWORD mouseStatus, DWORD posX, DWORD posY, void X11DRV_ButtonPress( HWND hwnd, XButtonEvent *event )
WORD keyState, DWORD data, DWORD time, HWND hWnd )
{ {
int iWndsLocks; int buttonNum = event->button - 1;
WINE_MOUSEEVENT wme; 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 ); case 3:
int height = GetSystemMetrics( SM_CYSCREEN ); wData = WHEEL_DELTA;
/* Relative mouse movements seems not to be scaled as absolute ones */ break;
posX = (((long)posX << 16) + width-1) / width; case 4:
posY = (((long)posY << 16) + height-1) / height; wData = -WHEEL_DELTA;
break;
} }
update_key_state( event->state );
wme.magic = WINE_MOUSEEVENT_MAGIC; send_mouse_event( hwnd, button_down_flags[buttonNum] | MOUSEEVENTF_ABSOLUTE,
wme.time = time; pt.x, pt.y, wData, event->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 );
} }
/***********************************************************************
* 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 */

View File

@ -117,7 +117,7 @@ static int get_window_attributes( Display *display, WND *win, XSetWindowAttribut
ButtonPressMask | ButtonReleaseMask); ButtonPressMask | ButtonReleaseMask);
if (is_window_top_level( win )) if (is_window_top_level( win ))
{ {
attr->event_mask |= StructureNotifyMask | FocusChangeMask; attr->event_mask |= StructureNotifyMask | FocusChangeMask | KeymapStateMask;
attr->cursor = X11DRV_GetCursor( display, GlobalLock16(GetCursor()) ); attr->cursor = X11DRV_GetCursor( display, GlobalLock16(GetCursor()) );
} }
return (CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap | CWCursor); return (CWOverrideRedirect | CWSaveUnder | CWEventMask | CWColormap | CWCursor);

View File

@ -66,8 +66,6 @@ debug_channels (bitblt bitmap clipboard cursor dinput event font gdi graphics
@ cdecl GetKeyNameText(long str long) X11DRV_GetKeyNameText @ cdecl GetKeyNameText(long str long) X11DRV_GetKeyNameText
@ cdecl ToUnicode(long long ptr ptr long long) X11DRV_ToUnicode @ cdecl ToUnicode(long long ptr ptr long long) X11DRV_ToUnicode
@ cdecl Beep() X11DRV_Beep @ 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 InitMouse(ptr) X11DRV_InitMouse
@ cdecl SetCursor(ptr) X11DRV_SetCursor @ cdecl SetCursor(ptr) X11DRV_SetCursor
@ cdecl GetCursorPos(ptr) X11DRV_GetCursorPos @ cdecl GetCursorPos(ptr) X11DRV_GetCursorPos

View File

@ -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 */

View File

@ -31,9 +31,6 @@ extern WORD USER_HeapSel;
#define USUD_FIRSTCLASS 0x0005 #define USUD_FIRSTCLASS 0x0005
struct tagCURSORICONINFO; struct tagCURSORICONINFO;
struct DIDEVICEOBJECTDATA;
typedef VOID CALLBACK (*LPMOUSE_EVENT_PROC)(DWORD,DWORD,DWORD,DWORD,DWORD);
/* internal messages codes */ /* internal messages codes */
enum wine_internal_message enum wine_internal_message
@ -44,6 +41,10 @@ enum wine_internal_message
WM_WINE_SETPARENT 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 { typedef struct tagUSER_DRIVER {
/* keyboard functions */ /* keyboard functions */
void (*pInitKeyboard)(LPBYTE); void (*pInitKeyboard)(LPBYTE);
@ -52,10 +53,8 @@ typedef struct tagUSER_DRIVER {
INT (*pGetKeyNameText)(LONG,LPSTR,INT); INT (*pGetKeyNameText)(LONG,LPSTR,INT);
INT (*pToUnicode)(UINT, UINT, LPBYTE, LPWSTR, int, UINT); INT (*pToUnicode)(UINT, UINT, LPBYTE, LPWSTR, int, UINT);
void (*pBeep)(void); void (*pBeep)(void);
BOOL (*pGetDIState)(DWORD, LPVOID);
BOOL (*pGetDIData)(BYTE *, DWORD, struct DIDEVICEOBJECTDATA *, LPDWORD, DWORD);
/* mouse functions */ /* mouse functions */
void (*pInitMouse)(LPMOUSE_EVENT_PROC); void (*pInitMouse)(LPBYTE);
void (*pSetCursor)(struct tagCURSORICONINFO *); void (*pSetCursor)(struct tagCURSORICONINFO *);
void (*pGetCursorPos)(LPPOINT); void (*pGetCursorPos)(LPPOINT);
void (*pSetCursorPos)(INT,INT); void (*pSetCursorPos)(INT,INT);
@ -108,9 +107,6 @@ extern void USER_CheckNotLock(void);
extern BOOL USER_IsExitingThread( DWORD tid ); extern BOOL USER_IsExitingThread( DWORD tid );
VOID WINAPI MOUSE_Enable(LPMOUSE_EVENT_PROC lpMouseEventProc);
VOID WINAPI MOUSE_Disable(VOID);
/* Wine look */ /* Wine look */
typedef enum typedef enum

View File

@ -30,7 +30,6 @@ struct tagDC;
struct tagDeviceCaps; struct tagDeviceCaps;
struct tagPALETTEOBJ; struct tagPALETTEOBJ;
struct tagWINDOWPOS; struct tagWINDOWPOS;
struct DIDEVICEOBJECTDATA;
/* X physical pen */ /* X physical pen */
typedef struct typedef struct
@ -349,8 +348,6 @@ extern BOOL X11DRV_GetClipboardData(UINT wFormat);
/* X11 event driver */ /* X11 event driver */
extern WORD X11DRV_EVENT_XStateToKeyState( int state ) ;
typedef enum { typedef enum {
X11DRV_INPUT_RELATIVE, X11DRV_INPUT_RELATIVE,
X11DRV_INPUT_ABSOLUTE 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) ; void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base) ;
#endif #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 */ /* x11drv private window data */
struct x11drv_win_data struct x11drv_win_data
{ {

View File

@ -26,7 +26,6 @@
#include "win.h" #include "win.h"
#include "hook.h" #include "hook.h"
#include "input.h" #include "input.h"
#include "mouse.h"
#include "message.h" #include "message.h"
#include "queue.h" #include "queue.h"
#include "debugtools.h" #include "debugtools.h"
@ -46,13 +45,6 @@ BYTE AsyncKeyStateTable[256];
/* Storage for the USER-maintained mouse positions */ /* Storage for the USER-maintained mouse positions */
static DWORD PosX, PosY; 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 typedef union
{ {
struct struct
@ -70,6 +62,32 @@ typedef union
} KEYLP; } 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 * 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 * 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; UINT message;
KEYLP keylp; KEYLP keylp;
@ -147,7 +165,7 @@ static void queue_kbd_event( const KEYBDINPUT *ki )
hook.vkCode = ki->wVk; hook.vkCode = ki->wVk;
hook.scanCode = ki->wScan; 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.time = ki->time;
hook.dwExtraInfo = ki->dwExtraInfo; hook.dwExtraInfo = ki->dwExtraInfo;
if (!HOOK_CallHooksW( WH_KEYBOARD_LL, HC_ACTION, message, (LPARAM)&hook )) 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 * queue_raw_mouse_message
*/ */
static void queue_raw_mouse_message( UINT message, WPARAM wParam, LPARAM lParam, static void queue_raw_mouse_message( UINT message, UINT flags, INT x, INT y, const MOUSEINPUT *mi )
int xPos, int yPos, DWORD time, ULONG_PTR extra_info )
{ {
MSLLHOOKSTRUCT hook; MSLLHOOKSTRUCT hook;
hook.pt.x = xPos; hook.pt.x = x;
hook.pt.y = yPos; hook.pt.y = y;
hook.mouseData = wParam; hook.mouseData = MAKELONG( 0, mi->mouseData );
hook.flags = 0; /* FIXME: LLMHF_INJECTED flag */ hook.flags = flags;
hook.time = time; hook.time = mi->time;
hook.dwExtraInfo = extra_info; hook.dwExtraInfo = mi->dwExtraInfo;
if (!HOOK_CallHooksW( WH_MOUSE_LL, HC_ACTION, message, (LPARAM)&hook )) 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 * 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) if (mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
{ {
@ -208,53 +226,51 @@ static void queue_mouse_event( const MOUSEINPUT *mi, WORD keystate )
if (mi->dwFlags & MOUSEEVENTF_MOVE) if (mi->dwFlags & MOUSEEVENTF_MOVE)
{ {
queue_raw_mouse_message( WM_MOUSEMOVE, keystate, 0, PosX, PosY, queue_raw_mouse_message( WM_MOUSEMOVE, flags, PosX, PosY, mi );
mi->time, mi->dwExtraInfo );
} }
if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN)) if (mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
{ {
InputKeyStateTable[VK_LBUTTON] |= 0x80; InputKeyStateTable[VK_LBUTTON] |= 0x80;
AsyncKeyStateTable[VK_LBUTTON] |= 0x80; AsyncKeyStateTable[VK_LBUTTON] |= 0x80;
queue_raw_mouse_message( WM_LBUTTONDOWN, keystate, 0, PosX, PosY, queue_raw_mouse_message( SwappedButtons ? WM_RBUTTONDOWN : WM_LBUTTONDOWN,
mi->time, mi->dwExtraInfo ); flags, PosX, PosY, mi );
} }
if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP)) if (mi->dwFlags & MOUSEEVENTF_LEFTUP)
{ {
InputKeyStateTable[VK_LBUTTON] &= ~0x80; InputKeyStateTable[VK_LBUTTON] &= ~0x80;
queue_raw_mouse_message( WM_LBUTTONUP, keystate, 0, PosX, PosY, queue_raw_mouse_message( SwappedButtons ? WM_RBUTTONUP : WM_LBUTTONUP,
mi->time, mi->dwExtraInfo ); flags, PosX, PosY, mi );
} }
if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN)) if (mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
{ {
InputKeyStateTable[VK_RBUTTON] |= 0x80; InputKeyStateTable[VK_RBUTTON] |= 0x80;
AsyncKeyStateTable[VK_RBUTTON] |= 0x80; AsyncKeyStateTable[VK_RBUTTON] |= 0x80;
queue_raw_mouse_message( WM_RBUTTONDOWN, keystate, 0, PosX, PosY, queue_raw_mouse_message( SwappedButtons ? WM_LBUTTONDOWN : WM_RBUTTONDOWN,
mi->time, mi->dwExtraInfo ); flags, PosX, PosY, mi );
} }
if (mi->dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP)) if (mi->dwFlags & MOUSEEVENTF_RIGHTUP)
{ {
InputKeyStateTable[VK_RBUTTON] &= ~0x80; InputKeyStateTable[VK_RBUTTON] &= ~0x80;
queue_raw_mouse_message( WM_RBUTTONUP, keystate, 0, PosX, PosY, queue_raw_mouse_message( SwappedButtons ? WM_LBUTTONUP : WM_RBUTTONUP,
mi->time, mi->dwExtraInfo ); flags, PosX, PosY, mi );
} }
if (mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN) if (mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
{ {
InputKeyStateTable[VK_MBUTTON] |= 0x80; InputKeyStateTable[VK_MBUTTON] |= 0x80;
AsyncKeyStateTable[VK_MBUTTON] |= 0x80; AsyncKeyStateTable[VK_MBUTTON] |= 0x80;
queue_raw_mouse_message( WM_MBUTTONDOWN, keystate, 0, PosX, PosY, queue_raw_mouse_message( WM_MBUTTONDOWN, flags, PosX, PosY, mi );
mi->time, mi->dwExtraInfo );
} }
if (mi->dwFlags & MOUSEEVENTF_MIDDLEUP) if (mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
{ {
InputKeyStateTable[VK_MBUTTON] &= ~0x80; InputKeyStateTable[VK_MBUTTON] &= ~0x80;
queue_raw_mouse_message( WM_MBUTTONUP, keystate, 0, PosX, PosY, queue_raw_mouse_message( WM_MBUTTONUP, flags, PosX, PosY, mi );
mi->time, mi->dwExtraInfo );
} }
if (mi->dwFlags & MOUSEEVENTF_WHEEL) if (mi->dwFlags & MOUSEEVENTF_WHEEL)
{ {
queue_raw_mouse_message( WM_MOUSEWHEEL, MAKELONG( keystate, mi->mouseData), 0, queue_raw_mouse_message( WM_MOUSEWHEEL, flags, PosX, PosY, mi );
PosX, PosY, mi->time, mi->dwExtraInfo );
} }
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) switch(inputs->type)
{ {
case INPUT_MOUSE: 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; break;
case INPUT_KEYBOARD: 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; break;
case INPUT_HARDWARE: case INPUT_HARDWARE:
FIXME( "INPUT_HARDWARE not supported\n" ); FIXME( "INPUT_HARDWARE not supported\n" );
@ -326,49 +348,15 @@ void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
DWORD dwData, DWORD dwExtraInfo ) DWORD dwData, DWORD dwExtraInfo )
{ {
INPUT input; INPUT input;
WORD keyState;
input.type = INPUT_MOUSE; input.type = INPUT_MOUSE;
input.u.mi.dx = dx; input.u.mi.dx = dx;
input.u.mi.dy = dy; input.u.mi.dy = dy;
input.u.mi.mouseData = dwData; input.u.mi.mouseData = dwData;
input.u.mi.dwFlags = dwFlags; input.u.mi.dwFlags = dwFlags;
input.u.mi.time = GetCurrentTime();
/* input.u.mi.dwExtraInfo = dwExtraInfo;
* If we are called by the Wine mouse driver, use the additional SendInput( 1, &input, sizeof(input) );
* 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 );
}
} }

View File

@ -8,8 +8,7 @@ MODULE = x11drv
C_SRCS = \ C_SRCS = \
clipboard.c \ clipboard.c \
event.c \ event.c \
keyboard.c \ keyboard.c
mouse.c
PROGRAMS = wineclipsrv PROGRAMS = wineclipsrv

View File

@ -26,7 +26,6 @@
#include "dce.h" #include "dce.h"
#include "debugtools.h" #include "debugtools.h"
#include "input.h" #include "input.h"
#include "mouse.h"
#include "options.h" #include "options.h"
#include "win.h" #include "win.h"
#include "winpos.h" #include "winpos.h"
@ -46,11 +45,6 @@ extern Atom wmDeleteWindow;
extern Atom dndProtocol; extern Atom dndProtocol;
extern Atom dndSelection; 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 DndNotDnd -1 /* OffiX drag&drop */
#define DndUnknown 0 #define DndUnknown 0
#define DndRawData 1 #define DndRawData 1
@ -85,9 +79,6 @@ static void EVENT_ProcessEvent( XEvent *event );
static BOOL X11DRV_CheckFocus(void); static BOOL X11DRV_CheckFocus(void);
/* Event handlers */ /* 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_FocusIn( HWND hWnd, XFocusChangeEvent *event );
static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event ); static void EVENT_FocusOut( HWND hWnd, XFocusChangeEvent *event );
static void EVENT_SelectionRequest( HWND hWnd, XSelectionRequestEvent *event, BOOL bIsMultiple ); 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_PropertyNotify( XPropertyEvent *event );
static void EVENT_ClientMessage( HWND hWnd, XClientMessageEvent *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_KeyEvent( HWND hwnd, XKeyEvent *event );
extern void X11DRV_KeymapNotify( HWND hwnd, XKeymapEvent *event );
extern void X11DRV_Expose( HWND hwnd, XExposeEvent *event ); extern void X11DRV_Expose( HWND hwnd, XExposeEvent *event );
extern void X11DRV_MapNotify( HWND hwnd, XMapEvent *event ); extern void X11DRV_MapNotify( HWND hwnd, XMapEvent *event );
extern void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event ); extern void X11DRV_UnmapNotify( HWND hwnd, XUnmapEvent *event );
@ -112,9 +107,9 @@ static int DGAKeyReleaseEventType;
static BOOL DGAUsed = FALSE; static BOOL DGAUsed = FALSE;
static HWND DGAhwnd = 0; static HWND DGAhwnd = 0;
static void EVENT_DGAMotionEvent( XDGAMotionEvent *event ); extern void X11DRV_DGAMotionEvent( HWND hwnd, XDGAMotionEvent *event );
static void EVENT_DGAButtonPressEvent( XDGAButtonEvent *event ); extern void X11DRV_DGAButtonPressEvent( HWND hwnd, XDGAButtonEvent *event );
static void EVENT_DGAButtonReleaseEvent( XDGAButtonEvent *event ); extern void X11DRV_DGAButtonReleaseEvent( HWND hwnd, XDGAButtonEvent *event );
#endif #endif
/* Static used for the current input method */ /* Static used for the current input method */
@ -213,17 +208,17 @@ static void EVENT_ProcessEvent( XEvent *event )
if (DGAUsed) { if (DGAUsed) {
if (event->type == DGAMotionEventType) { if (event->type == DGAMotionEventType) {
TRACE("DGAMotionEvent received.\n"); TRACE("DGAMotionEvent received.\n");
EVENT_DGAMotionEvent((XDGAMotionEvent *) event); X11DRV_DGAMotionEvent( DGAhwnd, (XDGAMotionEvent *)event );
return; return;
} }
if (event->type == DGAButtonPressEventType) { if (event->type == DGAButtonPressEventType) {
TRACE("DGAButtonPressEvent received.\n"); TRACE("DGAButtonPressEvent received.\n");
EVENT_DGAButtonPressEvent((XDGAButtonEvent *) event); X11DRV_DGAButtonPressEvent( DGAhwnd, (XDGAButtonEvent *)event );
return; return;
} }
if (event->type == DGAButtonReleaseEventType) { if (event->type == DGAButtonReleaseEventType) {
TRACE("DGAButtonReleaseEvent received.\n"); TRACE("DGAButtonReleaseEvent received.\n");
EVENT_DGAButtonReleaseEvent((XDGAButtonEvent *) event); X11DRV_DGAButtonReleaseEvent( DGAhwnd, (XDGAButtonEvent *)event );
return; return;
} }
if ((event->type == DGAKeyPressEventType) || 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 */ /* FIXME: should generate a motion event if event point is different from current pos */
X11DRV_KeyEvent( hWnd, (XKeyEvent*)event ); X11DRV_KeyEvent( hWnd, (XKeyEvent*)event );
break; break;
case ButtonPress: case ButtonPress:
EVENT_ButtonPress( hWnd, (XButtonEvent*)event ); X11DRV_ButtonPress( hWnd, (XButtonEvent*)event );
break; break;
case ButtonRelease: case ButtonRelease:
EVENT_ButtonRelease( hWnd, (XButtonEvent*)event ); X11DRV_ButtonRelease( hWnd, (XButtonEvent*)event );
break; break;
case MotionNotify: case MotionNotify:
EVENT_MotionNotify( hWnd, (XMotionEvent*)event ); X11DRV_MotionNotify( hWnd, (XMotionEvent*)event );
break; break;
case FocusIn: case FocusIn:
@ -337,6 +332,10 @@ static void EVENT_ProcessEvent( XEvent *event )
X11DRV_UnmapNotify( hWnd, (XUnmapEvent *)event ); X11DRV_UnmapNotify( hWnd, (XUnmapEvent *)event );
break; break;
case KeymapNotify:
X11DRV_KeymapNotify( hWnd, (XKeymapEvent *)event );
break;
case MappingNotify: case MappingNotify:
X11DRV_MappingNotify( (XMappingEvent *) event ); X11DRV_MappingNotify( (XMappingEvent *) event );
break; break;
@ -349,162 +348,6 @@ static void EVENT_ProcessEvent( XEvent *event )
TRACE( "returns.\n" ); 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 * EVENT_FocusIn
@ -543,10 +386,7 @@ static void EVENT_FocusIn( HWND hWnd, XFocusChangeEvent *event )
} }
if (event->detail != NotifyPointer && hWnd != GetForegroundWindow()) if (event->detail != NotifyPointer && hWnd != GetForegroundWindow())
{
SetForegroundWindow( hWnd ); SetForegroundWindow( hWnd );
X11DRV_KEYBOARD_UpdateState();
}
} }
@ -1470,71 +1310,4 @@ void X11DRV_EVENT_SetDGAStatus(HWND hwnd, int event_base)
DGAKeyReleaseEventType = event_base + KeyRelease; 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 #endif

View File

@ -27,12 +27,10 @@
#include "windef.h" #include "windef.h"
#include "wingdi.h" #include "wingdi.h"
#include "wine/winuser16.h" #include "wine/winuser16.h"
#include "dinput.h"
#include "debugtools.h"
#include "user.h"
#include "winnls.h" #include "winnls.h"
#include "win.h" #include "win.h"
#include "x11drv.h" #include "x11drv.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(keyboard); DEFAULT_DEBUG_CHANNEL(keyboard);
DECLARE_DEBUG_CHANNEL(key); 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 /* Yes, to distinguish based on scan codes, also
for PrtScn key ... GA */ 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 */ 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_PAUSE, VK_SCROLL, 0, 0, 0, /* FF10 */
0, 0, 0, VK_ESCAPE /* FF18 */ 0, 0, 0, VK_ESCAPE, 0, 0, 0, 0, /* FF18 */
}; /* unused */
static const WORD special_key_scan[] = 0, 0, 0, 0, 0, 0, 0, 0, /* FF20 */
{ 0, 0, 0, 0, 0, 0, 0, 0, /* FF28 */
0x0E, 0x0F, 0, /*?*/ 0, 0, 0x1C, 0, 0, /* FF08 */ 0, 0, 0, 0, 0, 0, 0, 0, /* FF30 */
0, 0, 0, 0x45, 0x46, 0 , 0, 0, /* FF10 */ 0, 0, 0, 0, 0, 0, 0, 0, /* FF38 */
0, 0, 0, 0x01 /* FF18 */ 0, 0, 0, 0, 0, 0, 0, 0, /* FF40 */
}; 0, 0, 0, 0, 0, 0, 0, 0, /* FF48 */
/* cursor keys */
static const WORD cursor_key_vkey[] = VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, /* FF50 */
{ VK_DOWN, VK_PRIOR, VK_NEXT, VK_END,
VK_HOME, VK_LEFT, VK_UP, VK_RIGHT, VK_DOWN, VK_PRIOR, 0, 0, 0, 0, 0, 0, 0, 0, /* FF58 */
VK_NEXT, VK_END /* FF50 */ /* misc keys */
};
static const WORD cursor_key_scan[] =
{
0x147, 0x14B, 0x148, 0x14D, 0x150, 0x149, 0x151, 0x14F /* FF50 */
};
static const WORD misc_key_vkey[] =
{
VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */ VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, 0, /* FF60 */
VK_CANCEL, VK_HELP, VK_CANCEL, VK_CANCEL /* FF68 */ VK_CANCEL, VK_HELP, VK_CANCEL, VK_CANCEL, 0, 0, 0, 0, /* FF68 */
}; 0, 0, 0, 0, 0, 0, 0, 0, /* FF70 */
static const WORD misc_key_scan[] = /* keypad keys */
{ 0, 0, 0, 0, 0, 0, 0, VK_NUMLOCK, /* FF78 */
/*?*/ 0, 0x137, /*?*/ 0, 0x152, 0, 0, 0, 0, /* FF60 */
/*?*/ 0, /*?*/ 0, 0x38, 0x146 /* FF68 */
};
static const WORD keypad_key_vkey[] =
{
0, VK_NUMLOCK, /* FF7E */
0, 0, 0, 0, 0, 0, 0, 0, /* FF80 */ 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_RETURN, 0, 0, /* FF88 */
0, 0, 0, 0, 0, VK_HOME, VK_LEFT, VK_UP, /* FF90 */ 0, 0, 0, 0, 0, VK_HOME, VK_LEFT, VK_UP, /* FF90 */
VK_RIGHT, VK_DOWN, VK_PRIOR, VK_NEXT, VK_END, 0, VK_RIGHT, VK_DOWN, VK_PRIOR, VK_NEXT, /* FF98 */
VK_INSERT, VK_DELETE, /* FF98 */ VK_END, 0, VK_INSERT, VK_DELETE,
0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */ 0, 0, 0, 0, 0, 0, 0, 0, /* FFA0 */
0, 0, VK_MULTIPLY, VK_ADD, VK_SEPARATOR, VK_SUBTRACT, 0, 0, VK_MULTIPLY, VK_ADD, /* FFA8 */
VK_DECIMAL, VK_DIVIDE, /* FFA8 */ VK_SEPARATOR, VK_SUBTRACT, VK_DECIMAL, VK_DIVIDE,
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4, VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, /* FFB0 */
VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, /* FFB0 */ VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
VK_NUMPAD8, VK_NUMPAD9 /* FFB8 */ VK_NUMPAD8, VK_NUMPAD9, 0, 0, 0, 0, /* FFB8 */
}; /* function keys */
static const WORD keypad_key_scan[] = VK_F1, VK_F2,
{
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 */
VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, /* FFC0 */ 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 */ VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16, 0, 0, /* FFC8 */
}; 0, 0, 0, 0, 0, 0, 0, 0, /* FFD0 */
static const WORD function_key_scan[] = 0, 0, 0, 0, 0, 0, 0, 0, /* FFD8 */
{ /* modifier keys */
0x3B, 0x3C, /* FFBE */ 0, VK_SHIFT, VK_SHIFT, VK_CONTROL, /* FFE0 */
0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, /* FFC0 */ VK_CONTROL, VK_CAPITAL, 0, VK_MENU,
0x57, 0x58, 0, 0, 0, 0 /* FFC8 */ 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 */ /* unused */
VK_MENU, VK_MENU, VK_MENU, VK_MENU /* FFE7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* FF00 */
}; /* special keys */
static const WORD modifier_key_scan[] = 0x0E, 0x0F, 0x00, /*?*/ 0, 0x00, 0x1C, 0x00, 0x00, /* FF08 */
{ 0x00, 0x00, 0x00, 0x45, 0x46, 0x00, 0x00, 0x00, /* FF10 */
0x2A, 0x36, 0x1D, 0x11D, 0x3A, 0, /* FFE1 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* FF18 */
0x38, 0x138, 0x38, 0x138 /* FFE7 */ /* 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 <e> */ /* Returns the Windows virtual key code associated with the X event <e> */
static WORD EVENT_event_to_vkey( XKeyEvent *e) static WORD EVENT_event_to_vkey( XKeyEvent *e)
{ {
@ -609,7 +617,7 @@ static WORD EVENT_event_to_vkey( XKeyEvent *e)
&& (e->state & NumLockMask)) && (e->state & NumLockMask))
/* Only the Keypad keys 0-9 and . send different keysyms /* Only the Keypad keys 0-9 and . send different keysyms
* depending on the NumLock state */ * depending on the NumLock state */
return keypad_key_vkey[(keysym & 0xFF) - 0x7E]; return nonchar_key_vkey[keysym & 0xFF];
return keyc2vkey[e->keycode]; return keyc2vkey[e->keycode];
} }
@ -620,11 +628,11 @@ static BOOL NumState=FALSE, CapsState=FALSE;
/*********************************************************************** /***********************************************************************
* send_keyboard_input * 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 input;
input.type = INPUT_KEYBOARD; input.type = WINE_INTERNAL_INPUT_KEYBOARD;
input.u.ki.wVk = wVk; input.u.ki.wVk = wVk;
input.u.ki.wScan = wScan; input.u.ki.wScan = wScan;
input.u.ki.dwFlags = dwFlags; 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 <vkey>, depending on key <state> under X * Updates internal state for <vkey>, depending on key <state> 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 */ /* Do something if internal table state != X state for keycode */
if (((pKeyStateTable[vkey] & 0x80)!=0) != state) if (((pKeyStateTable[vkey] & 0x80)!=0) != state)
@ -695,41 +703,44 @@ static void KEYBOARD_UpdateOneState ( int vkey, int state )
vkey, pKeyStateTable[vkey]); vkey, pKeyStateTable[vkey]);
/* Fake key being pressed inside wine */ /* 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]); TRACE("State after %#.2x \n",pKeyStateTable[vkey]);
} }
} }
/*********************************************************************** /***********************************************************************
* X11DRV_KEYBOARD_UpdateState * X11DRV_KeymapNotify
* *
* Update modifiers state (Ctrl, Alt, Shift) * Update modifiers state (Ctrl, Alt, Shift) when window is activated.
* when window is activated (called by EVENT_FocusIn in event.c)
* *
* This handles the case where one uses Ctrl+... Alt+... or Shift+.. to switch * This handles the case where one uses Ctrl+... Alt+... or Shift+.. to switch
* from wine to another application and back. * from wine to another application and back.
* Toggle keys are handled in HandleEvent. (because XQueryKeymap says nothing * Toggle keys are handled in HandleEvent.
* about them)
*/ */
void X11DRV_KEYBOARD_UpdateState ( void ) void X11DRV_KeymapNotify( HWND hwnd, XKeymapEvent *event )
{ {
/* extract a bit from the char[32] bit suite */ int i, j, alt, control, shift;
#define KeyState(keycode) ((keys_return[keycode/8] & (1<<(keycode%8)))!=0) DWORD time = GetCurrentTime();
char keys_return[32]; alt = control = shift = 0;
for (i = 0; i < 32; i++)
TRACE("called\n"); {
if (!TSXQueryKeymap(thread_display(), keys_return)) { if (!event->key_vector[i]) continue;
ERR("Error getting keymap !\n"); for (j = 0; j < 8; j++)
return; {
if (!(event->key_vector[i] & (1<<j))) continue;
switch(keyc2vkey[(i * 8) + j] & 0xff)
{
case VK_MENU: alt = 1; break;
case VK_CONTROL: control = 1; break;
case VK_SHIFT: shift = 1; break;
}
}
} }
KEYBOARD_UpdateOneState( VK_MENU, alt, time );
/* Adjust the ALT and CONTROL state if any has been changed outside wine */ KEYBOARD_UpdateOneState( VK_CONTROL, control, time );
KEYBOARD_UpdateOneState(VK_MENU, KeyState(kcAlt)); KEYBOARD_UpdateOneState( VK_SHIFT, shift, time );
KEYBOARD_UpdateOneState(VK_CONTROL, KeyState(kcControl));
KEYBOARD_UpdateOneState(VK_SHIFT, KeyState(kcShift));
#undef KeyState
} }
/*********************************************************************** /***********************************************************************
@ -1022,30 +1033,8 @@ void X11DRV_InitKeyboard( BYTE *key_state_table )
{ {
if ((keysym >> 8) == 0xFF) /* non-character key */ if ((keysym >> 8) == 0xFF) /* non-character key */
{ {
int key = keysym & 0xff; vkey = nonchar_key_vkey[keysym & 0xff];
scan = nonchar_key_scan[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;
}
/* set extended bit when necessary */ /* set extended bit when necessary */
if (scan & 0x100) vkey |= 0x100; if (scan & 0x100) vkey |= 0x100;
} else if (keysym == 0x20) { /* Spacebar */ } else if (keysym == 0x20) { /* Spacebar */
@ -1654,72 +1643,3 @@ void X11DRV_Beep(void)
{ {
TSXBell(thread_display(), 0); 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<max_keycode;keyc++)
{
/* X keycode to virtual key */
vkey = keyc2vkey[keyc] & 0xFF;
/* The windows scancode is keyc-min_keycode */
if (pKeyStateTable[vkey]&0x80) {
((LPBYTE)ptr)[keyc-min_keycode]=0x80;
((LPBYTE)ptr)[(keyc-min_keycode)|0x80]=0x80;
}
}
return TRUE;
}
WARN("whoops, got len %ld?\n", len);
return TRUE;
}
/***********************************************************************
* GetDIData (X11DRV.@)
*/
BOOL X11DRV_GetDIData(
BYTE *keystate,
DWORD dodsize, LPDIDEVICEOBJECTDATA dod,
LPDWORD entries, DWORD flags)
{
int keyc,n,vkey,xentries;
/* FIXME !!! */
if (entries)
xentries = *entries;
else
xentries = 1;
n = 0;
for (keyc=min_keycode;(keyc<max_keycode) && (n<*entries);keyc++)
{
/* X keycode to virtual key */
vkey = keyc2vkey[keyc] & 0xFF;
if (keystate[vkey] == (pKeyStateTable[vkey]&0x80))
continue;
if (dod) {
/* add an entry */
dod[n].dwOfs = keyc-min_keycode; /* scancode */
dod[n].dwData = pKeyStateTable[vkey]&0x80;
dod[n].dwTimeStamp = 0; /* umm */
dod[n].dwSequence = 0; /* umm */
n++;
}
if (!(flags & DIGDD_PEEK))
keystate[vkey] = pKeyStateTable[vkey]&0x80;
}
if (n) TRACE_(dinput)("%d entries\n",n);
*entries = n;
return TRUE;
}