[PATCH libXi 3/4] Added XIGrabDeviceWithConfine.

Peter Hutterer peter.hutterer at who-t.net
Thu Jun 2 00:13:33 PDT 2011


From: Philipp Reh <sefi at s-e-f-i.de>

The new function is like XIGrabDevice but it takes an
additional confine_to parameter. This functionality is important
for programs that need relative mouse movement but also need
the cursor to stay in their window (like games, for example).

The confine_to value is put after the variable length
mask, so the protocol doesn't need a completely new request.
To make this possible, it is first checked if the server supports
version 2.1 or greater, in which case it will expect the new
parameter. Otherwise the new WithConfine is unsupported.

Signed-off-by: Philipp Reh <sefi at s-e-f-i.de>
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Changes to previous version:
- moved addition of 2.1 constants into separate patch
- added man page
- use Data32 instead of memcpy for confine_to

 include/X11/extensions/XInput2.h |   13 +++++++++++
 man/Makefile.am                  |    2 +
 man/XIGrabDevice.txt             |   20 ++++++++++++++++-
 src/XIGrabDevice.c               |   44 ++++++++++++++++++++++++++++++++-----
 4 files changed, 72 insertions(+), 7 deletions(-)

diff --git a/include/X11/extensions/XInput2.h b/include/X11/extensions/XInput2.h
index 3fcf083..1ae818b 100644
--- a/include/X11/extensions/XInput2.h
+++ b/include/X11/extensions/XInput2.h
@@ -402,6 +402,19 @@ extern Status XIGrabDevice(
      XIEventMask        *mask
 );
 
+extern Status XIGrabDeviceWithConfine(
+     Display*           dpy,
+     int                deviceid,
+     Window             grab_window,
+     Window             confine_to,
+     Time               time,
+     Cursor             cursor,
+     int                grab_mode,
+     int                paired_device_mode,
+     Bool               owner_events,
+     XIEventMask        *mask
+);
+
 extern Status XIUngrabDevice(
      Display*           dpy,
      int                deviceid,
diff --git a/man/Makefile.am b/man/Makefile.am
index c8db111..ab5b5af 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -78,6 +78,7 @@ libman_xml = $(libman_txt:.txt=.xml)
 XI2_shadows = 					\
 	XIUndefineCursor.man			\
 	XIUngrabButton.man			\
+	XIGrabDeviceWithConfine.man		\
 	XIGrabKeycode.man			\
 	XIUngrabKeycode.man			\
 	XIUngrabDevice.man			\
@@ -150,6 +151,7 @@ XIDeleteProperty.man: XIChangeProperty.man
 XIUngrabEnter.man XIGrabFocusIn.man XIUngrabFocusIn.man: XIGrabEnter.man
 XIGetSelectedEvents.man: XISelectEvents.man
 XIFreeDeviceInfo.man: XIQueryDevice.man
+XIGrabDeviceWithConfine.man: XIGrabDevice.man
 
 # String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
 # Unable to use __libmansuffix__ as underscores are lost in txt --> xml conversion
diff --git a/man/XIGrabDevice.txt b/man/XIGrabDevice.txt
index bd749b7..d05643c 100644
--- a/man/XIGrabDevice.txt
+++ b/man/XIGrabDevice.txt
@@ -4,7 +4,7 @@ XIGRABDEVICE(libmansuffix)
 NAME
 ----
 
-   XIGrabDevice, XIUngrabDevice - grab or ungrab the device.
+   XIGrabDevice, XIGrabDeviceWithConfine, XIUngrabDevice - grab or ungrab the device.
 
 SYNOPSIS
 --------
@@ -20,6 +20,17 @@ SYNOPSIS
                         int paired_device_mode,
                         Bool owner_events,
                         XIEventMask *mask);
+
+    Status XIGrabDeviceWithConfine( Display *display,
+                                    int deviceid,
+                                    Window grab_window,
+                                    Window confine_to,
+                                    Time time,
+                                    Cursor cursor,
+                                    int grab_mode,
+                                    int paired_device_mode,
+                                    Bool owner_events,
+                                    XIEventMask *mask);
    
    Status XIUngrabDevice( Display *display,
                           int deviceid,
@@ -43,6 +54,10 @@ SYNOPSIS
    grab_window
           The grab window.
 
+   confine_to
+          The window to confine this device to if it is a
+          master pointer. Can be None.
+
    mask
           Event mask.
 
@@ -112,6 +127,9 @@ DESCRIPTION
    XIGrabDevice can generate BadDevice, BadValue, and BadWindow
    errors.
 
+   XIGrabDeviceWithConfine with confine_to set to None has the
+   same behaviour as XIGrabDevice.
+
    The XIUngrabDevice request releases the device and any queued
    events if this client has it actively grabbed from either
    XIGrabDevice or XIGrabKey or XIGrabButton. If other devices are
diff --git a/src/XIGrabDevice.c b/src/XIGrabDevice.c
index 94feaee..716f53a 100644
--- a/src/XIGrabDevice.c
+++ b/src/XIGrabDevice.c
@@ -29,11 +29,11 @@
 #include <X11/extensions/extutil.h>
 #include "XIint.h"
 
-
-Status
-XIGrabDevice(Display* dpy, int deviceid, Window grab_window, Time time,
-             Cursor cursor, int grab_mode, int paired_device_mode,
-             Bool owner_events, XIEventMask *mask)
+static Status
+_XIGrabDevice(Display* dpy, int deviceid, Window grab_window,
+              Window confine_to, Time time, Cursor cursor,
+              int grab_mode, int paired_device_mode,
+              Bool owner_events, XIEventMask *mask)
 {
     xXIGrabDeviceReq *req;
     xXIGrabDeviceReply reply;
@@ -65,10 +65,15 @@ XIGrabDevice(Display* dpy, int deviceid, Window grab_window, Time time,
     buff = calloc(1, len * 4);
     memcpy(buff, mask->mask, mask->mask_len);
 
+    len++; /* for the confine_to */
+
     SetReqLen(req, len, len);
-    Data(dpy, buff, len * 4);
+    Data(dpy, buff, (len - 1) * 4);
     free(buff);
 
+    /* put the confine_to window at the end */
+    Data32(dpy, &confine_to, 4);
+
     if (_XReply(dpy, (xReply *)&reply, 0, xTrue) == 0)
 	reply.status = GrabSuccess;
 
@@ -79,6 +84,33 @@ XIGrabDevice(Display* dpy, int deviceid, Window grab_window, Time time,
 }
 
 Status
+XIGrabDevice(Display* dpy, int deviceid, Window grab_window, Time time,
+             Cursor cursor, int grab_mode, int paired_device_mode,
+             Bool owner_events, XIEventMask *mask)
+{
+    return _XIGrabDevice(dpy, deviceid, grab_window, None, time,
+                         cursor, grab_mode, paired_device_mode,
+                         owner_events, mask);
+}
+
+Status
+XIGrabDeviceWithConfine(Display* dpy, int deviceid, Window grab_window,
+                        Window confine_to, Time time, Cursor cursor,
+                        int grab_mode, int paired_device_mode,
+                        Bool owner_events, XIEventMask *mask)
+{
+    XExtDisplayInfo *extinfo = XInput_find_display(dpy);
+
+    LockDisplay(dpy);
+    if (_XiCheckExtInit(dpy, XInput_2_1, extinfo) == -1)
+	return (NoSuchExtension);
+
+    return _XIGrabDevice(dpy, deviceid, grab_window, confine_to, time,
+                         cursor, grab_mode, paired_device_mode,
+                         owner_events, mask);
+}
+
+Status
 XIUngrabDevice(Display* dpy, int deviceid, Time time)
 {
     xXIUngrabDeviceReq *req;
-- 
1.7.5.1



More information about the xorg-devel mailing list