Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
bd3ec1a9
Commit
bd3ec1a9
authored
Apr 13, 2011
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winex11: Retrieve raw mouse events through XInput2 while the cursor is clipped.
parent
338fe8b9
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
179 additions
and
5 deletions
+179
-5
event.c
dlls/winex11.drv/event.c
+1
-1
mouse.c
dlls/winex11.drv/mouse.c
+174
-4
x11drv.h
dlls/winex11.drv/x11drv.h
+3
-0
x11drv_main.c
dlls/winex11.drv/x11drv_main.c
+1
-0
No files found.
dlls/winex11.drv/event.c
View file @
bd3ec1a9
...
...
@@ -795,7 +795,7 @@ static void X11DRV_MapNotify( HWND hwnd, XEvent *event )
*/
static
void
X11DRV_UnmapNotify
(
HWND
hwnd
,
XEvent
*
event
)
{
if
(
event
->
xany
.
window
==
clip_window
)
clipping_
cursor
=
0
;
if
(
event
->
xany
.
window
==
clip_window
)
clipping_
window_unmapped
()
;
}
...
...
dlls/winex11.drv/mouse.c
View file @
bd3ec1a9
...
...
@@ -128,6 +128,17 @@ static XContext cursor_context;
static
RECT
clip_rect
;
static
Cursor
create_cursor
(
HANDLE
handle
);
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
static
BOOL
xinput2_available
;
static
int
xinput2_opcode
;
static
int
xinput2_core_pointer
;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
MAKE_FUNCPTR
(
XIFreeDeviceInfo
);
MAKE_FUNCPTR
(
XIQueryDevice
);
MAKE_FUNCPTR
(
XIQueryVersion
);
MAKE_FUNCPTR
(
XISelectEvents
);
#undef MAKE_FUNCPTR
#endif
/***********************************************************************
* X11DRV_Xcursor_Init
...
...
@@ -239,6 +250,124 @@ void sync_window_cursor( Window window )
}
/***********************************************************************
* enable_xinput2
*/
static
void
enable_xinput2
(
void
)
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
struct
x11drv_thread_data
*
data
=
x11drv_thread_data
();
XIDeviceInfo
*
devices
;
XIEventMask
mask
;
unsigned
char
mask_bits
[
XIMaskLen
(
XI_LASTEVENT
)];
int
i
,
count
;
if
(
!
xinput2_available
)
return
;
if
(
data
->
xi2_state
==
xi_unknown
)
{
int
major
=
2
,
minor
=
0
;
wine_tsx11_lock
();
if
(
!
pXIQueryVersion
(
data
->
display
,
&
major
,
&
minor
))
data
->
xi2_state
=
xi_disabled
;
else
{
data
->
xi2_state
=
xi_unavailable
;
WARN
(
"X Input 2 not available
\n
"
);
}
wine_tsx11_unlock
();
}
if
(
data
->
xi2_state
==
xi_unavailable
)
return
;
wine_tsx11_lock
();
devices
=
pXIQueryDevice
(
data
->
display
,
XIAllDevices
,
&
count
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
if
(
devices
[
i
].
use
!=
XIMasterPointer
)
continue
;
TRACE
(
"Using %u (%s) as core pointer
\n
"
,
devices
[
i
].
deviceid
,
debugstr_a
(
devices
[
i
].
name
)
);
xinput2_core_pointer
=
devices
[
i
].
deviceid
;
break
;
}
mask
.
mask
=
mask_bits
;
mask
.
mask_len
=
sizeof
(
mask_bits
);
memset
(
mask_bits
,
0
,
sizeof
(
mask_bits
)
);
XISetMask
(
mask_bits
,
XI_RawButtonPress
);
XISetMask
(
mask_bits
,
XI_RawButtonRelease
);
XISetMask
(
mask_bits
,
XI_RawMotion
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
if
(
devices
[
i
].
use
==
XISlavePointer
&&
devices
[
i
].
attachment
==
xinput2_core_pointer
)
{
TRACE
(
"Device %u (%s) is attached to the core pointer
\n
"
,
devices
[
i
].
deviceid
,
debugstr_a
(
devices
[
i
].
name
)
);
mask
.
deviceid
=
devices
[
i
].
deviceid
;
pXISelectEvents
(
data
->
display
,
DefaultRootWindow
(
data
->
display
),
&
mask
,
1
);
data
->
xi2_state
=
xi_enabled
;
}
}
pXIFreeDeviceInfo
(
devices
);
wine_tsx11_unlock
();
#endif
}
/***********************************************************************
* disable_xinput2
*/
static
void
disable_xinput2
(
void
)
{
#ifdef HAVE_X11_EXTENSIONS_XINPUT2_H
struct
x11drv_thread_data
*
data
=
x11drv_thread_data
();
XIEventMask
mask
;
XIDeviceInfo
*
devices
;
int
i
,
count
;
if
(
data
->
xi2_state
!=
xi_enabled
)
return
;
TRACE
(
"disabling
\n
"
);
data
->
xi2_state
=
xi_disabled
;
mask
.
mask
=
NULL
;
mask
.
mask_len
=
0
;
wine_tsx11_lock
();
devices
=
pXIQueryDevice
(
data
->
display
,
XIAllDevices
,
&
count
);
for
(
i
=
0
;
i
<
count
;
++
i
)
{
if
(
devices
[
i
].
use
==
XISlavePointer
&&
devices
[
i
].
attachment
==
xinput2_core_pointer
)
{
mask
.
deviceid
=
devices
[
i
].
deviceid
;
pXISelectEvents
(
data
->
display
,
DefaultRootWindow
(
data
->
display
),
&
mask
,
1
);
}
}
pXIFreeDeviceInfo
(
devices
);
wine_tsx11_unlock
();
#endif
}
/***********************************************************************
* clipping_window_unmapped
*
* Turn off clipping when the window got unmapped.
*/
void
clipping_window_unmapped
(
void
)
{
struct
x11drv_thread_data
*
data
=
x11drv_thread_data
();
clipping_cursor
=
0
;
if
(
data
->
xi2_state
==
xi_enabled
)
{
RECT
rect
;
GetClipCursor
(
&
rect
);
if
(
EqualRect
(
&
rect
,
&
clip_rect
))
return
;
/* still clipped */
disable_xinput2
();
}
}
/***********************************************************************
* send_mouse_input
*
* Update the various window states on a mouse event.
...
...
@@ -254,7 +383,7 @@ static void send_mouse_input( HWND hwnd, Window window, unsigned int state, INPU
{
input
->
u
.
mi
.
dx
+=
clip_rect
.
left
;
input
->
u
.
mi
.
dy
+=
clip_rect
.
top
;
__wine_send_input
(
hwnd
,
input
);
if
(
x11drv_thread_data
()
->
xi2_state
!=
xi_enabled
)
__wine_send_input
(
hwnd
,
input
);
return
;
}
...
...
@@ -913,14 +1042,16 @@ void CDECL X11DRV_SetCursor( HCURSOR handle )
*/
BOOL
CDECL
X11DRV_SetCursorPos
(
INT
x
,
INT
y
)
{
Display
*
display
=
thread_init_display
();
struct
x11drv_thread_data
*
data
=
x11drv_init_thread_data
();
if
(
data
->
xi2_state
==
xi_enabled
)
return
TRUE
;
TRACE
(
"warping to (%d,%d)
\n
"
,
x
,
y
);
wine_tsx11_lock
();
XWarpPointer
(
display
,
root_window
,
root_window
,
0
,
0
,
0
,
0
,
XWarpPointer
(
d
ata
->
d
isplay
,
root_window
,
root_window
,
0
,
0
,
0
,
0
,
x
-
virtual_screen_rect
.
left
,
y
-
virtual_screen_rect
.
top
);
XFlush
(
display
);
/* avoids bad mouse lag in games that do their own mouse warping */
XFlush
(
d
ata
->
d
isplay
);
/* avoids bad mouse lag in games that do their own mouse warping */
wine_tsx11_unlock
();
return
TRUE
;
}
...
...
@@ -983,6 +1114,7 @@ BOOL CDECL X11DRV_ClipCursor( LPCRECT clip )
if
(
clipping_cursor
)
{
enable_xinput2
();
sync_window_cursor
(
clip_window
);
clip_rect
=
*
clip
;
return
TRUE
;
...
...
@@ -996,6 +1128,7 @@ BOOL CDECL X11DRV_ClipCursor( LPCRECT clip )
XUnmapWindow
(
display
,
clip_window
);
wine_tsx11_unlock
();
clipping_cursor
=
0
;
disable_xinput2
();
return
TRUE
;
}
...
...
@@ -1175,6 +1308,42 @@ static void X11DRV_RawMotion( XIRawEvent *event )
/***********************************************************************
* X11DRV_XInput2_Init
*/
void
X11DRV_XInput2_Init
(
void
)
{
#if defined(SONAME_LIBXI) && defined(HAVE_X11_EXTENSIONS_XINPUT2_H)
int
event
,
error
;
void
*
libxi_handle
=
wine_dlopen
(
SONAME_LIBXI
,
RTLD_NOW
,
NULL
,
0
);
if
(
!
libxi_handle
)
{
WARN
(
"couldn't load %s
\n
"
,
SONAME_LIBXI
);
return
;
}
#define LOAD_FUNCPTR(f) \
if (!(p##f = wine_dlsym( libxi_handle, #f, NULL, 0))) \
{ \
WARN("Failed to load %s.\n", #f); \
return; \
}
LOAD_FUNCPTR
(
XIFreeDeviceInfo
);
LOAD_FUNCPTR
(
XIQueryDevice
);
LOAD_FUNCPTR
(
XIQueryVersion
);
LOAD_FUNCPTR
(
XISelectEvents
);
#undef LOAD_FUNCPTR
wine_tsx11_lock
();
xinput2_available
=
XQueryExtension
(
gdi_display
,
"XInputExtension"
,
&
xinput2_opcode
,
&
event
,
&
error
);
wine_tsx11_unlock
();
#else
TRACE
(
"X Input 2 support not compiled in.
\n
"
);
#endif
}
/***********************************************************************
* X11DRV_GenericEvent
*/
void
X11DRV_GenericEvent
(
HWND
hwnd
,
XEvent
*
xev
)
...
...
@@ -1183,6 +1352,7 @@ void X11DRV_GenericEvent( HWND hwnd, XEvent *xev )
XGenericEventCookie
*
event
=
&
xev
->
xcookie
;
if
(
!
event
->
data
)
return
;
if
(
event
->
extension
!=
xinput2_opcode
)
return
;
switch
(
event
->
evtype
)
{
...
...
dlls/winex11.drv/x11drv.h
View file @
bd3ec1a9
...
...
@@ -258,6 +258,7 @@ extern void X11DRV_OpenGL_Cleanup(void);
extern
void
X11DRV_Xcursor_Init
(
void
);
extern
void
X11DRV_BITMAP_Init
(
void
);
extern
void
X11DRV_FONT_Init
(
int
log_pixels_x
,
int
log_pixels_y
);
extern
void
X11DRV_XInput2_Init
(
void
);
extern
int
bitmap_info_size
(
const
BITMAPINFO
*
info
,
WORD
coloruse
);
extern
XImage
*
X11DRV_DIB_CreateXImage
(
int
width
,
int
height
,
int
depth
);
...
...
@@ -550,6 +551,7 @@ struct x11drv_thread_data
XFontSet
font_set
;
/* international text drawing font set */
Window
selection_wnd
;
/* window used for selection interactions */
HKL
kbd_layout
;
/* active keyboard layout */
enum
{
xi_unavailable
=
-
1
,
xi_unknown
,
xi_disabled
,
xi_enabled
}
xi2_state
;
/* XInput2 state */
};
extern
struct
x11drv_thread_data
*
x11drv_init_thread_data
(
void
);
...
...
@@ -823,6 +825,7 @@ extern void X11DRV_ResetSelectionOwner(void);
extern
void
CDECL
X11DRV_SetFocus
(
HWND
hwnd
);
extern
void
set_window_cursor
(
Window
window
,
HCURSOR
handle
);
extern
void
sync_window_cursor
(
Window
window
);
extern
void
clipping_window_unmapped
(
void
);
extern
BOOL
CDECL
X11DRV_ClipCursor
(
LPCRECT
clip
);
extern
void
X11DRV_InitKeyboard
(
Display
*
display
);
extern
DWORD
CDECL
X11DRV_MsgWaitForMultipleObjectsEx
(
DWORD
count
,
const
HANDLE
*
handles
,
DWORD
timeout
,
...
...
dlls/winex11.drv/x11drv_main.c
View file @
bd3ec1a9
...
...
@@ -595,6 +595,7 @@ static BOOL process_attach(void)
#ifdef SONAME_LIBXCOMPOSITE
X11DRV_XComposite_Init
();
#endif
X11DRV_XInput2_Init
();
#ifdef HAVE_XKB
if
(
use_xkb
)
use_xkb
=
XkbUseExtension
(
gdi_display
,
NULL
,
NULL
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment