Here are some patches for a quick, prototype implementation of this
protocol.  They're what we've been using to test the protocol is
sufficiently useful.

These are provided for people who'd like to test the behaviour; they are
in no way intended to be applied as-is.

Chris
diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index 479ac2f..f965d6f 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -122,7 +122,7 @@
 #define SERVER_XF86VIDMODE_MINOR_VERSION	2
 
 /* Fixes */
-#define SERVER_XFIXES_MAJOR_VERSION		5
+#define SERVER_XFIXES_MAJOR_VERSION		6
 #define SERVER_XFIXES_MINOR_VERSION		0
 
 /* X Input */
diff --git a/mi/mipointer.c b/mi/mipointer.c
index 998c86c..c728283 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -619,6 +619,9 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *scree
 	    }
 	}
     }
+    if (pScreen->ConstrainCursorHarder)
+       pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y);
+
     /* Constrain the sprite to the current limits. */
     if (x < pPointer->limits.x1)
 	x = pPointer->limits.x1;
@@ -629,9 +632,6 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx, double *scree
     if (y >= pPointer->limits.y2)
 	y = pPointer->limits.y2 - 1;
 
-    if (pScreen->ConstrainCursorHarder)
-       pScreen->ConstrainCursorHarder(pDev, pScreen, mode, &x, &y);
-
     if (pPointer->x != x || pPointer->y != y ||
             pPointer->pScreen != pScreen)
         miPointerMoveNoEvent(pDev, pScreen, x, y);
diff --git a/xfixes/cursor.c b/xfixes/cursor.c
index 53f9f20..40e1ff5 100644
--- a/xfixes/cursor.c
+++ b/xfixes/cursor.c
@@ -61,6 +61,7 @@ static RESTYPE		CursorClientType;
 static RESTYPE		CursorHideCountType;
 static RESTYPE		CursorWindowType;
 RESTYPE			PointerBarrierType;
+static RESTYPE		PointerBarrierClientType;
 static CursorPtr	CursorCurrent[MAXDEVICES];
 
 static DevPrivateKeyRec CursorScreenPrivateKeyRec;
@@ -129,6 +130,7 @@ typedef struct _CursorScreen {
     ConstrainCursorHarderProcPtr ConstrainCursorHarder;
     CursorHideCountPtr          pCursorHideCounts;
     struct list                 barriers;
+    struct list                 barrierClients;
 } CursorScreenRec, *CursorScreenPtr;
 
 #define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey))
@@ -1220,14 +1222,65 @@ barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x, int *y
 }
 
 static void
+SendBarrierEvent(CursorScreenPtr cs, struct PointerBarrier *barrier,
+		 int x, int y, int velocity, Bool threshold_exceeded)
+{
+    PointerBarrierEventClientPtr client;
+    list_for_each_entry(client, &cs->barrierClients, entry) {
+	xXFixesBarrierNotifyEvent	ev;
+	ev.type = XFixesEventBase + XFixesBarrierNotify;
+	ev.subtype = threshold_exceeded ? XFixesBarrierThresholdExceededNotify :
+					  XFixesBarrierHitNotify;
+	ev.event_id = barrier->barrierEventID;
+	ev.barrier = barrier->barrier;
+	ev.x = x;
+	ev.y = y;
+	ev.velocity = velocity;
+	ev.timestamp = currentTime.milliseconds;
+	WriteEventsToClient (client->client, 1, (xEvent *) &ev);
+    }
+}
+
+static void
+barrier_calculate_velocity_components (int x1, int y1, int x2, int y2,
+				       int *vel_x, int *vel_y)
+{
+    static CARD32 last_timestamp = 0;
+    CARD32 timestamp = GetTimeInMillis();
+    int dx, dy;
+    int dt = timestamp - last_timestamp;
+
+    if (last_timestamp == 0) {
+	/* Not much we can do for the first event */
+	*vel_x = 0;
+	*vel_y = 0;
+	last_timestamp = timestamp;
+	return;
+    }
+
+    /* Lets not divide by zero if we can avoid it */
+    dt = dt > 0 ? dt : 1;
+
+    dx = x2 - x1;
+    dy = y2 - y1;
+
+    *vel_x = abs(dx) * 1000.0 / dt;
+    *vel_y = abs(dy) * 1000.0 / dt;
+
+    last_timestamp = timestamp;  
+}
+
+static void
 CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, int *x, int *y)
 {
     CursorScreenPtr cs = GetCursorScreen(screen);
 
     if (!list_is_empty(&cs->barriers) && !IsFloating(dev) && mode == Relative) {
 	int ox, oy;
+	int vel_x, vel_y;
 	int dir;
 	struct PointerBarrier *nearest = NULL;
+	PointerBarrierClientPtr c;
 
 	/* where are we coming from */
 	miPointerGetPosition(dev, &ox, &oy);
@@ -1240,11 +1293,27 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, int *x
 	 * destination, again finding the nearest barrier and clamping.
 	 */
 	dir = barrier_get_direction(ox, oy, *x, *y);
+	barrier_calculate_velocity_components(ox, oy, *x, *y, &vel_x, &vel_y);
 
 	nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
 	if (nearest) {
-	    barrier_clamp_to_barrier(nearest, dir, x, y);
+	    int velocity = barrier_is_vertical(nearest) ? vel_x : vel_y;
+	    Bool threshold_exceeded = (nearest->velocity == 0) ||
+				      (velocity > nearest->velocity);
+
+	    if (!nearest->lastHit) {
+		/* This is the start of a new barrier event */
+		nearest->barrierEventID++;
+	    }
 
+	    if (!threshold_exceeded &&
+		(nearest->barrierEventID != nearest->releaseEventID)) {
+		barrier_clamp_to_barrier(nearest, dir, x, y);
+		nearest->hit = TRUE;
+	    }
+
+	    SendBarrierEvent(cs, nearest, *x, *y, velocity, threshold_exceeded);
+		
 	    if (barrier_is_vertical(nearest)) {
 		dir &= ~(BarrierNegativeX | BarrierPositiveX);
 		ox = *x;
@@ -1255,9 +1324,29 @@ CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, int *x
 
 	    nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
 	    if (nearest) {
-		barrier_clamp_to_barrier(nearest, dir, x, y);
+		velocity = barrier_is_vertical(nearest) ? vel_x : vel_y;
+		threshold_exceeded = (nearest->velocity == 0) ||
+				     (velocity > nearest->velocity);
+
+		if (!nearest->lastHit) {
+		    /* This is the start of a new barrier event */
+		    nearest->barrierEventID++;
+		}
+
+		if (!threshold_exceeded &&
+		    (nearest->barrierEventID != nearest->releaseEventID)) {
+		    barrier_clamp_to_barrier(nearest, dir, x, y);
+		    nearest->hit = TRUE;
+		}
+
+		SendBarrierEvent(cs, nearest, *x, *y, velocity, threshold_exceeded);
 	    }
 	}
+
+	list_for_each_entry(c, &cs->barriers, entry) {
+	    c->barrier.lastHit = c->barrier.hit;
+	    c->barrier.hit = FALSE;
+	}
     }
 
     if (cs->ConstrainCursorHarder) {
@@ -1276,11 +1365,41 @@ CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client,
 
     if (ret) {
 	ret->screen = screen;
+	ret->barrier.barrier = stuff->barrier;
 	ret->barrier.x1 = min(stuff->x1, stuff->x2);
 	ret->barrier.x2 = max(stuff->x1, stuff->x2);
 	ret->barrier.y1 = min(stuff->y1, stuff->y2);
 	ret->barrier.y2 = max(stuff->y1, stuff->y2);
 	ret->barrier.directions = stuff->directions & 0x0f;
+	ret->barrier.velocity = 0;
+	ret->barrier.barrierEventID = 0;
+	if (barrier_is_horizontal(&ret->barrier))
+	    ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
+	if (barrier_is_vertical(&ret->barrier))
+	    ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY);
+	list_add(&ret->entry, &cs->barriers);
+    }
+
+    return ret;
+}
+
+static struct PointerBarrierClient *
+CreatePointerBarrierVelocityClient(ScreenPtr screen, ClientPtr client,
+			   xXFixesCreatePointerBarrierVelocityReq *stuff)
+{
+    CursorScreenPtr cs = GetCursorScreen(screen);
+    struct PointerBarrierClient *ret = malloc(sizeof(*ret));
+
+    if (ret) {
+	ret->screen = screen;
+	ret->barrier.barrier = stuff->barrier;
+	ret->barrier.x1 = min(stuff->x1, stuff->x2);
+	ret->barrier.x2 = max(stuff->x1, stuff->x2);
+	ret->barrier.y1 = min(stuff->y1, stuff->y2);
+	ret->barrier.y2 = max(stuff->y1, stuff->y2);
+	ret->barrier.directions = stuff->directions & 0x0f;
+	ret->barrier.velocity = stuff->velocity;
+	ret->barrier.barrierEventID = 0;
 	if (barrier_is_horizontal(&ret->barrier))
 	    ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
 	if (barrier_is_vertical(&ret->barrier))
@@ -1352,6 +1471,68 @@ SProcXFixesCreatePointerBarrier (ClientPtr client)
     return ProcXFixesVector[stuff->xfixesReqType](client);
 }
 
+int
+ProcXFixesCreatePointerBarrierVelocity (ClientPtr client)
+{
+    int err;
+    WindowPtr pWin;
+    struct PointerBarrierClient *barrier;
+    struct PointerBarrier b;
+    REQUEST (xXFixesCreatePointerBarrierVelocityReq);
+
+    REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierVelocityReq);
+    LEGAL_NEW_RESOURCE(stuff->barrier, client);
+
+    err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+    if (err != Success) {
+	client->errorValue = stuff->window;
+	return err;
+    }
+
+    /* This sure does need fixing. */
+    if (stuff->num_devices)
+	return BadImplementation;
+
+    b.x1 = stuff->x1;
+    b.x2 = stuff->x2;
+    b.y1 = stuff->y1;
+    b.y2 = stuff->y2;
+
+    if (!barrier_is_horizontal(&b) && !barrier_is_vertical(&b))
+	return BadValue;
+
+    /* no 0-sized barriers */
+    if (barrier_is_horizontal(&b) && barrier_is_vertical(&b))
+	return BadValue;
+
+    if (!(barrier = CreatePointerBarrierVelocityClient(pWin->drawable.pScreen,
+						       client, stuff)))
+	return BadAlloc;
+
+    if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier))
+	return BadAlloc;
+
+    return Success;
+}
+
+int
+SProcXFixesCreatePointerBarrierVelocity (ClientPtr client)
+{
+    REQUEST(xXFixesCreatePointerBarrierVelocityReq);
+
+    swaps(&stuff->length);
+    REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq);
+    swapl(&stuff->barrier);
+    swapl(&stuff->window);
+    swaps(&stuff->x1);
+    swaps(&stuff->y1);
+    swaps(&stuff->x2);
+    swaps(&stuff->y2);
+    swapl(&stuff->directions);
+    swapl(&stuff->velocity);
+    return ProcXFixesVector[stuff->xfixesReqType](client);
+}
+
 static int
 CursorFreeBarrier(void *data, XID id)
 {
@@ -1407,6 +1588,127 @@ SProcXFixesDestroyPointerBarrier (ClientPtr client)
     return ProcXFixesVector[stuff->xfixesReqType](client);
 }
 
+static int
+CursorFreeBarrierClient(void *data, XID id)
+{
+    PointerBarrierEventClientPtr client = data, c;
+    ScreenPtr screen = client->screen;
+    CursorScreenPtr cs = GetCursorScreen(screen);
+
+    /* find and unlink from the screen private */
+    list_for_each_entry(c, &cs->barrierClients, entry) {
+	if (c == client) {
+	    list_del(&c->entry);
+	    break;
+	}
+    }
+
+    free(client);
+    return Success;
+}
+
+static struct PointerBarrierEventClient *
+CreatePointerBarrierEventClient(ScreenPtr screen, ClientPtr client,
+				   xXFixesSelectBarrierInputReq *stuff)
+{
+    CursorScreenPtr cs = GetCursorScreen(screen);
+    struct PointerBarrierEventClient *ret = malloc(sizeof(*ret));
+
+    if (ret) {
+	ret->screen = screen;
+	ret->client = client;
+	ret->eventMask = stuff->eventMask;
+	ret->window = stuff->window;
+	ret->resource = FakeClientID (client->index);      
+      list_add(&ret->entry, &cs->barrierClients);
+    }
+
+    return ret;
+}
+
+int
+ProcXFixesSelectBarrierInput (ClientPtr client)
+{
+    int err;
+    WindowPtr pWin;
+    struct PointerBarrierEventClient *eventClient;
+    REQUEST (xXFixesSelectBarrierInputReq);
+
+    REQUEST_SIZE_MATCH(xXFixesSelectBarrierInputReq);
+
+    err = dixLookupWindow(&pWin	, stuff->window, client, DixReadAccess);
+    if (err != Success) {
+	client->errorValue = stuff->window;
+	return err;
+    }
+
+    if (!(eventClient = CreatePointerBarrierEventClient(pWin->drawable.pScreen,
+							client,
+							stuff)))
+      return BadAlloc;
+
+    if (!AddResource (eventClient->resource, PointerBarrierClientType, eventClient))
+      return BadAlloc;
+    
+    return Success;
+}
+
+int
+SProcXFixesSelectBarrierInput (ClientPtr client)
+{
+    int err;
+    WindowPtr pWin;
+    struct PointerBarrierEventClient *eventClient;
+    REQUEST (xXFixesSelectBarrierInputReq);
+
+    REQUEST_SIZE_MATCH(xXFixesSelectBarrierInputReq);
+
+    err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+    if (err != Success) {
+	client->errorValue = stuff->window;
+	return err;
+    }
+
+    if (!(eventClient = CreatePointerBarrierEventClient(pWin->drawable.pScreen,
+							client,
+							stuff)))
+      return BadAlloc;
+    
+    if (!AddResource (FakeClientID(client->index), 
+		      PointerBarrierClientType,
+		      eventClient))
+      return BadAlloc;
+
+    return Success;
+}
+
+int
+ProcXFixesBarrierReleasePointer (ClientPtr client)
+{
+    int err;
+    struct PointerBarrier *barrier;
+    REQUEST (xXFixesBarrierReleasePointerReq);
+    REQUEST_SIZE_MATCH(xXFixesBarrierReleasePointerReq);
+
+    err = dixLookupResourceByType((void **)&barrier, stuff->barrier,
+				  PointerBarrierType, client,
+				  DixReadAccess);
+    if (err != Success) {
+	client->errorValue = stuff->barrier;
+	return err;
+    }
+
+    barrier->releaseEventID = stuff->event_id;
+    
+    return Success;
+}
+
+int
+SProcXFixesBarrierReleasePointer (ClientPtr client)
+{
+    return Success;
+}
+
 Bool
 XFixesCursorInit (void)
 {
@@ -1427,6 +1729,7 @@ XFixesCursorInit (void)
 	if (!cs)
 	    return FALSE;
 	list_init(&cs->barriers);
+	list_init(&cs->barrierClients);
 	Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
 	Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
 	Wrap (cs, pScreen, ConstrainCursorHarder, CursorConstrainCursorHarder);
@@ -1441,8 +1744,10 @@ XFixesCursorInit (void)
 					     "XFixesCursorWindow");
     PointerBarrierType = CreateNewResourceType(CursorFreeBarrier,
 					      "XFixesPointerBarrier");
+    PointerBarrierClientType = CreateNewResourceType(CursorFreeBarrierClient,
+						     "XFixesPointerBarrierClient");
 
     return CursorClientType && CursorHideCountType && CursorWindowType &&
-	   PointerBarrierType;
+	   PointerBarrierType && PointerBarrierClientType;
 }
 
diff --git a/xfixes/xfixes.c b/xfixes/xfixes.c
index 96d33c0..189998b 100644
--- a/xfixes/xfixes.c
+++ b/xfixes/xfixes.c
@@ -99,6 +99,7 @@ static const int version_requests[] = {
     X_XFixesExpandRegion,	    /* Version 3 */
     X_XFixesShowCursor,		    /* Version 4 */
     X_XFixesDestroyPointerBarrier,  /* Version 5 */
+    X_XFixesBarrierReleasePointer, /* Version 6 */
 };
 
 #define NUM_VERSION_REQUESTS	(sizeof (version_requests) / sizeof (version_requests[0]))
@@ -142,6 +143,10 @@ int	(*ProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
 /*************** Version 5 ****************/
     ProcXFixesCreatePointerBarrier,
     ProcXFixesDestroyPointerBarrier,
+/*************** Version 6 ****************/
+    ProcXFixesCreatePointerBarrierVelocity,
+    ProcXFixesSelectBarrierInput,
+    ProcXFixesBarrierReleasePointer,
 };
 
 static int
@@ -207,6 +212,10 @@ static int (*SProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
 /*************** Version 5 ****************/
     SProcXFixesCreatePointerBarrier,
     SProcXFixesDestroyPointerBarrier,
+/*************** Version 6 ****************/
+    SProcXFixesCreatePointerBarrierVelocity,
+    SProcXFixesSelectBarrierInput,
+    SProcXFixesBarrierReleasePointer,
 };
 
 static int
diff --git a/xfixes/xfixes.h b/xfixes/xfixes.h
index 5765e64..1d1eb84 100644
--- a/xfixes/xfixes.h
+++ b/xfixes/xfixes.h
@@ -28,6 +28,7 @@
 #define _XFIXES_H_
 
 #include "resource.h"
+#include "list.h"
 
 extern _X_EXPORT RESTYPE RegionResType;
 extern _X_EXPORT RESTYPE PointerBarrierType;
@@ -52,9 +53,27 @@ extern _X_EXPORT int XFixesErrorBase;
 extern _X_EXPORT RegionPtr
 XFixesRegionCopy (RegionPtr pRegion);
 
+typedef struct PointerBarrierEventClient *PointerBarrierEventClientPtr;
+
+struct PointerBarrierEventClient {
+    ScreenPtr screen;
+    ClientPtr client;
+    CARD32    eventMask;
+    XID window;
+    XID resource;
+    struct list entry;
+};
+
+  
+
 struct PointerBarrier {
+    XID    barrier;
     CARD16 x1, x2, y1, y2;
     CARD32 directions;
+    CARD32 velocity;
+    CARD32 barrierEventID;
+    CARD32 releaseEventID;
+    Bool   hit, lastHit;
 };
 
 
diff --git a/xfixes/xfixesint.h b/xfixes/xfixesint.h
index 6ba276e..cb00be6 100644
--- a/xfixes/xfixesint.h
+++ b/xfixes/xfixesint.h
@@ -59,6 +59,7 @@
 #include "windowstr.h"
 #include "selection.h"
 #include "xfixes.h"
+#include "list.h"
 
 extern int		XFixesEventBase;
 
@@ -293,6 +294,26 @@ ProcXFixesDestroyPointerBarrier (ClientPtr client);
 int
 SProcXFixesDestroyPointerBarrier (ClientPtr client);
 
+/* Version 6 */
+
+int
+ProcXFixesSelectBarrierInput (ClientPtr client);
+
+int
+SProcXFixesSelectBarrierInput (ClientPtr client);
+
+int
+ProcXFixesCreatePointerBarrierVelocity (ClientPtr client);
+
+int
+SProcXFixesCreatePointerBarrierVelocity (ClientPtr client);
+
+int
+ProcXFixesBarrierReleasePointer (ClientPtr client);
+
+int
+SProcXFixesBarrierReleasePointer (ClientPtr client);
+
 /* Xinerama */
 extern int (*PanoramiXSaveXFixesVector[XFixesNumberRequests])(ClientPtr);
 void PanoramiXFixesInit (void);
diff --git a/debian/changelog b/debian/changelog
index ee46d5f..3b6baa2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,21 @@
+libxfixes (1:5.0-6~hacking2) precise; urgency=low
+
+  * Hook up event-id & BarrierReleasePointer
+
+ -- Christopher James Halse Rogers <[email protected]>  Wed, 25 Jan 2012 14:42:06 +1100
+
+libxfixes (1:5.0-6~hacking1) precise; urgency=low
+
+  * More and different thresholding
+
+ -- Christopher James Halse Rogers <[email protected]>  Wed, 25 Jan 2012 11:56:16 +1100
+
+libxfixes (1:5.0-5) precise; urgency=low
+
+  * Pointer-barrier-thresholding
+
+ -- Christopher James Halse Rogers <[email protected]>  Wed, 18 Jan 2012 22:09:44 +1100
+
 libxfixes (1:5.0-4) unstable; urgency=low
 
   * Team upload.
diff --git a/debian/control b/debian/control
index a507388..dc27cb8 100644
--- a/debian/control
+++ b/debian/control
@@ -7,7 +7,7 @@ Build-Depends:
  debhelper (>= 8.1.3),
  dh-autoreconf,
  libx11-dev (>= 2:1.3.3-2),
- x11proto-fixes-dev (>= 1:5.0),
+ x11proto-fixes-dev (>= 1:5.0-5~hacking2~),
  pkg-config,
  quilt,
  xutils-dev (>= 1:7.5+4),
diff --git a/debian/libxfixes3.symbols b/debian/libxfixes3.symbols
index 2cedbeb..7f2eabc 100644
--- a/debian/libxfixes3.symbols
+++ b/debian/libxfixes3.symbols
@@ -1,9 +1,11 @@
 libXfixes.so.3 libxfixes3 #MINVER#
+ XFixesBarrierReleasePointer@Base 1:5.0-5~hacking2
  XFixesChangeCursor@Base 0
  XFixesChangeCursorByName@Base 0
  XFixesChangeSaveSet@Base 0
  XFixesCopyRegion@Base 0
  XFixesCreatePointerBarrier@Base 1:5.0
+ XFixesCreatePointerBarrierVelocity@Base 1:5.0-4
  XFixesCreateRegion@Base 0
  XFixesCreateRegionFromBitmap@Base 0
  XFixesCreateRegionFromGC@Base 0
@@ -25,6 +27,7 @@ libXfixes.so.3 libxfixes3 #MINVER#
  XFixesQueryExtension@Base 0
  XFixesQueryVersion@Base 0
  XFixesRegionExtents@Base 0
+ XFixesSelectBarrierInput@Base 1:5.0-4
  XFixesSelectCursorInput@Base 0
  XFixesSelectSelectionInput@Base 0
  XFixesSetCursorName@Base 0
diff --git a/include/X11/extensions/Xfixes.h b/include/X11/extensions/Xfixes.h
index 10a7e2e..9b1e03a 100644
--- a/include/X11/extensions/Xfixes.h
+++ b/include/X11/extensions/Xfixes.h
@@ -259,11 +259,48 @@ XFixesCreatePointerBarrier(Display *dpy, Window w, int x1, int y1,
 			   int x2, int y2, int directions,
 			   int num_devices, int *devices);
 
+PointerBarrier
+XFixesCreatePointerBarrierVelocity(Display *dpy, Window w, int x1, int y1,
+			   int x2, int y2, int directions, int velocity,
+			   int num_devices, int *devices);
+
 void
 XFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b);
 
 #endif /* XFIXES_MAJOR >= 5 */
 
+#if XFIXES_MAJOR >= 6
+
+typedef int32_t BarrierEventID;
+
+typedef struct {
+    int type;			/* event base */
+    int subtype;
+    unsigned long serial;
+    Bool send_event;
+    Display *display;
+    Window window;
+    BarrierEventID event_id;
+    int directions;
+    PointerBarrier barrier;
+    int x;
+    int y;
+    int velocity;
+    Time timestamp;
+} XFixesBarrierNotifyEvent;
+
+void
+XFixesSelectBarrierInput (Display	*dpy,
+			 Window		win,
+			 unsigned long	eventMask);
+
+void
+XFixesBarrierReleasePointer(Display *dpy,
+			    PointerBarrier b,
+			    BarrierEventID event_id);
+
+#endif
+
 _XFUNCPROTOEND
 
 #endif /* _XFIXES_H_ */
diff --git a/src/Cursor.c b/src/Cursor.c
index 0d656f7..e04422d 100644
--- a/src/Cursor.c
+++ b/src/Cursor.c
@@ -334,3 +334,84 @@ XFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b)
     UnlockDisplay (dpy);
     SyncHandle();
 }
+
+void
+XFixesSelectBarrierInput (Display *dpy, Window win, unsigned long eventMask)
+{
+    XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy);
+    xXFixesSelectBarrierInputReq *req;
+
+    XFixesSimpleCheckExtension (dpy, info);
+    if (info->major_version < 6)
+	return;
+
+    LockDisplay (dpy);
+    GetReq (XFixesSelectBarrierInput, req);
+    req->reqType = info->codes->major_opcode;
+    req->xfixesReqType = X_XFixesSelectBarrierInput;
+    req->window = win;
+    req->eventMask = eventMask;
+    UnlockDisplay (dpy);
+    SyncHandle();
+}
+
+PointerBarrier
+XFixesCreatePointerBarrierVelocity(Display *dpy, Window w, int x1, int y1,
+				   int x2, int y2, int directions, int velocity,
+			   int num_devices, int *devices)
+{
+    XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy);
+    xXFixesCreatePointerBarrierVelocityReq *req;
+    PointerBarrier barrier;
+    int extra = 0;
+
+    XFixesCheckExtension (dpy, info, 0);
+    if (info->major_version < 6)
+	return 0;
+
+    if (num_devices)
+	extra = (((2 * num_devices) + 3) / 4) * 4;
+
+    LockDisplay (dpy);
+    GetReqExtra (XFixesCreatePointerBarrierVelocity, extra, req);
+    req->reqType = info->codes->major_opcode;
+    req->xfixesReqType = X_XFixesCreatePointerBarrierVelocity;
+    barrier = req->barrier = XAllocID (dpy);
+    req->window = w;
+    req->x1 = x1;
+    req->y1 = y1;
+    req->x2 = x2;
+    req->y2 = y2;
+    req->directions = directions;
+    req->velocity = velocity;
+    if ((req->num_devices = num_devices)) {
+	int i;
+	CARD16 *devs = (CARD16 *)(req + 1);
+	for (i = 0; i < num_devices; i++)
+	    devs[i] = (CARD16)(devices[i]);
+    }
+
+    UnlockDisplay (dpy);
+    SyncHandle();
+    return barrier;
+}
+
+void
+XFixesBarrierReleasePointer(Display *dpy, PointerBarrier b, BarrierEventID event_id)
+{
+    XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy);
+    xXFixesBarrierReleasePointerReq *req;
+
+    XFixesSimpleCheckExtension (dpy, info);
+    if (info->major_version < 6)
+	return;
+
+    LockDisplay (dpy);
+    GetReq (XFixesBarrierReleasePointer, req);
+    req->reqType = info->codes->major_opcode;
+    req->xfixesReqType = X_XFixesBarrierReleasePointer;
+    req->barrier = b;
+    req->event_id = event_id;
+    UnlockDisplay (dpy);
+    SyncHandle();
+}
diff --git a/src/Xfixes.c b/src/Xfixes.c
index 7d3af84..f92fe7a 100644
--- a/src/Xfixes.c
+++ b/src/Xfixes.c
@@ -253,6 +253,26 @@ XFixesWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
 	aevent->cursor_name = awire->name;
 	return True;
     }
+    case XFixesBarrierNotify: {
+	XFixesBarrierNotifyEvent *aevent;
+	xXFixesBarrierNotifyEvent *awire;
+	awire = (xXFixesBarrierNotifyEvent *)wire;
+	aevent = (XFixesBarrierNotifyEvent *)event;
+	aevent->type = awire->type & 0x7F;
+	aevent->subtype = awire->subtype;
+	aevent->serial = _XSetLastRequestRead(dpy,
+					      (xGenericReply *) wire);
+	aevent->send_event = (awire->type & 0x80) != 0;
+	aevent->display = dpy;
+	aevent->window = awire->window;
+	aevent->event_id = awire->event_id;
+	aevent->barrier = awire->barrier;
+	aevent->x = awire->x;
+	aevent->y = awire->y;
+	aevent->velocity = awire->velocity;
+	aevent->timestamp = awire->timestamp;
+	return True;      
+    }
     }
     return False;
 }
@@ -292,6 +312,22 @@ XFixesEventToWire(Display *dpy, XEvent *event, xEvent *wire)
 	awire->cursorSerial = aevent->cursor_serial;
 	awire->name = aevent->cursor_name;
     }
+    case XFixesBarrierNotify: {
+	XFixesBarrierNotifyEvent *aevent;
+	xXFixesBarrierNotifyEvent *awire;
+	awire = (xXFixesBarrierNotifyEvent *)wire;
+	aevent = (XFixesBarrierNotifyEvent *)event;
+	awire->type = aevent->type | (aevent->send_event ? 0x80 : 0);
+	awire->subtype = aevent->subtype;
+	awire->window = aevent->window;
+	awire->event_id = aevent->event_id;
+	awire->barrier = aevent->barrier;
+	awire->x = aevent->x;
+	awire->y = aevent->y;
+	awire->velocity = aevent->velocity;
+	awire->timestamp = aevent->timestamp;
+	return True;      
+    }
     }
     return False;
 }

Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to