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; }
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
