[PATCH libXi] Added XIGrabDeviceWithConfine.

Philipp Reh sefi at s-e-f-i.de
Wed May 18 09:29:44 PDT 2011


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.
---
 include/X11/extensions/XInput2.h |   13 ++++++++++
 man/XIGrabDevice.txt             |   18 +++++++++++++
 src/XExtInt.c                    |    3 +-
 src/XIGrabDevice.c               |   50 +++++++++++++++++++++++++++++++++----
 4 files changed, 77 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/XIGrabDevice.txt b/man/XIGrabDevice.txt
index bd749b7..c6db809 100644
--- a/man/XIGrabDevice.txt
+++ b/man/XIGrabDevice.txt
@@ -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/XExtInt.c b/src/XExtInt.c
index 55144c6..97b0d96 100644
--- a/src/XExtInt.c
+++ b/src/XExtInt.c
@@ -268,7 +268,8 @@ static XExtensionVersion versions[] = { {XI_Absent, 0, 0},
  XI_Add_DevicePresenceNotify_Minor},
 {XI_Present, XI_Add_DeviceProperties_Major,
  XI_Add_DeviceProperties_Minor},
-{XI_Present, XI_2_Major, XI_2_Minor}
+{XI_Present, XI_2_Major, XI_2_Minor},
+{XI_Present, XI_2_1_Major, XI_2_1_Minor}
 };
 
 /***********************************************************************
diff --git a/src/XIGrabDevice.c b/src/XIGrabDevice.c
index 94feaee..d943ca6 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, int version)
 {
     xXIGrabDeviceReq *req;
     xXIGrabDeviceReply reply;
@@ -43,7 +43,7 @@ XIGrabDevice(Display* dpy, int deviceid, Window grab_window, Time time,
     XExtDisplayInfo *extinfo = XInput_find_display(dpy);
 
     LockDisplay(dpy);
-    if (_XiCheckExtInit(dpy, XInput_2_0, extinfo) == -1)
+    if (_XiCheckExtInit(dpy, version, extinfo) == -1)
 	return (NoSuchExtension);
 
     GetReq(XIGrabDevice, req);
@@ -61,10 +61,18 @@ XIGrabDevice(Display* dpy, int deviceid, Window grab_window, Time time,
 
     /* mask->mask_len is in bytes, but we need 4-byte units on the wire,
      * and they need to be padded with 0 */
+    /* If the version is not XInput_2_0 (which means it is greater)
+     * we allocate one more word for the confine_to parameter */
     len = req->mask_len;
+    if(version != XInput_2_0)
+       ++len;
     buff = calloc(1, len * 4);
     memcpy(buff, mask->mask, mask->mask_len);
 
+    /* put the confine_to window at the end */
+    if(version != XInput_2_0)
+        memcpy(buff + mask->mask_len, (unsigned char *)&confine_to, 4);
+
     SetReqLen(req, len, len);
     Data(dpy, buff, len * 4);
     free(buff);
@@ -79,6 +87,36 @@ 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)
+{
+    /* The server either expects a 2_0 or a 2_1 request
+     * depending on which version it has available */
+    int version = XInput_2_1;
+    XExtDisplayInfo *extinfo = XInput_find_display(dpy);
+
+    LockDisplay(dpy);
+    if (_XiCheckExtInit(dpy, XInput_2_1, extinfo) == -1)
+        version = XInput_2_0;
+
+    return _XIGrabDevice(dpy, deviceid, grab_window, None, time,
+                         cursor, grab_mode, paired_device_mode,
+                         owner_events, mask, version);
+}
+
+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)
+{
+    return _XIGrabDevice(dpy, deviceid, grab_window, confine_to, time,
+                         cursor, grab_mode, paired_device_mode,
+                         owner_events, mask, XInput_2_1);
+}
+
+Status
 XIUngrabDevice(Display* dpy, int deviceid, Time time)
 {
     xXIUngrabDeviceReq *req;
-- 
1.7.5.rc3



More information about the xorg-devel mailing list