xorg-server: Changes to 'ubuntu'
debian/changelog | 13
debian/patches/500_pointer_barrier_thresholds.diff | 1231 +++++++++++++++++++--
2 files changed, 1175 insertions(+), 69 deletions(-)
New commits:
commit 1aeebd5760baafc1bb6d6ac05b538a6fb45e42ae
Author: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
Date: Fri Mar 2 09:05:17 2012 +1100
Multiple additions to pointer-barrier patch:
*) Add build-time tests for pointer barrier behaviour
*) Fix barrier corners incorrectly allowing the pointer through
*) Fix barrier notify events being sent from the SIGIO context (LP: 946954)
*) Add new build-depends for pointer barrier tests
diff --git a/debian/changelog b/debian/changelog
index 1fbc21e..f238360 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+xorg-server (2:1.11.4-0ubuntu5) UNRELEASED; urgency=low
+
+ * debian/patches/500_pointer_barrier_thresholds.diff:
+ - Don't try to send events from the context of the SIGIO handler. That
+ leads to the dark side, or at least to server freezes when trying to
+ reveal the launcher in Unity (LP: #946954)
+ - Add build-time tests to make check for barrier behaviour.
+ * debian/control:
+ - Add xserver-xorg-video-dummy, libxtst-dev, libgtest-dev, and
+ libxorg-gtest-dev to build-depends for new tests.
+
+ -- Christopher James Halse Rogers <raof@ubuntu.com> Tue, 06 Mar 2012 17:41:20 +1100
+
xorg-server (2:1.11.4-0ubuntu4) precise; urgency=low
* debian/patches/500_pointer_barrier_thresholds.diff:
diff --git a/debian/control b/debian/control
index 7da92bf..731617b 100644
--- a/debian/control
+++ b/debian/control
@@ -78,6 +78,10 @@ Build-Depends:
# unit tests
xkb-data,
x11-xkb-utils,
+ libxtst-dev,
+ xserver-xorg-video-dummy,
+ libgtest-dev,
+ libxorg-gtest-dev,
Standards-Version: 3.9.2
Vcs-Git: git://git.debian.org/git/pkg-xorg/xserver/xorg-server
Vcs-Browser: http://git.debian.org/?p=pkg-xorg/xserver/xorg-server.git
diff --git a/debian/patches/500_pointer_barrier_thresholds.diff b/debian/patches/500_pointer_barrier_thresholds.diff
index aeb983f..9e255ad 100644
--- a/debian/patches/500_pointer_barrier_thresholds.diff
+++ b/debian/patches/500_pointer_barrier_thresholds.diff
@@ -1,7 +1,7 @@
Index: xorg-server/include/protocol-versions.h
===================================================================
---- xorg-server.orig/include/protocol-versions.h 2012-02-29 14:01:49.926067501 +1100
-+++ xorg-server/include/protocol-versions.h 2012-02-29 14:02:32.866067406 +1100
+--- xorg-server.orig/include/protocol-versions.h 2012-03-07 22:24:45.540697115 +1100
++++ xorg-server/include/protocol-versions.h 2012-03-08 07:40:35.472111389 +1100
@@ -122,7 +122,7 @@
#define SERVER_XF86VIDMODE_MINOR_VERSION 2
@@ -13,8 +13,8 @@ Index: xorg-server/include/protocol-versions.h
/* X Input */
Index: xorg-server/xfixes/cursor.c
===================================================================
---- xorg-server.orig/xfixes/cursor.c 2012-02-29 14:01:49.934067502 +1100
-+++ xorg-server/xfixes/cursor.c 2012-02-29 14:02:32.870067406 +1100
+--- xorg-server.orig/xfixes/cursor.c 2012-03-07 22:24:45.580697117 +1100
++++ xorg-server/xfixes/cursor.c 2012-03-08 11:00:53.155469738 +1100
@@ -61,6 +61,7 @@
static RESTYPE CursorHideCountType;
static RESTYPE CursorWindowType;
@@ -43,38 +43,119 @@ Index: xorg-server/xfixes/cursor.c
} CursorScreenRec, *CursorScreenPtr;
#define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey))
-@@ -1232,18 +1239,90 @@
+@@ -1118,7 +1125,8 @@
+
+ /* Algorithm below doesn't handle edge cases well, hence the extra
+ * checks. */
+- if (barrier_is_vertical(barrier)) {
++ if (barrier_is_vertical(barrier) &&
++ (dir & (BarrierPositiveX | BarrierNegativeX))) {
+ /* handle immediate barrier adjacency, moving away */
+ if (dir & BarrierPositiveX && x1 == barrier->x1)
+ return FALSE;
+@@ -1129,7 +1137,8 @@
+ *distance = 0;
+ return TRUE;
+ }
+- } else {
++ } else if (barrier_is_horizontal(barrier) &&
++ (dir & (BarrierPositiveY | BarrierNegativeY))){
+ /* handle immediate barrier adjacency, moving away */
+ if (dir & BarrierPositiveY && y1 == barrier->y1)
+ return FALSE;
+@@ -1231,6 +1240,127 @@
+ }
}
- static void
-+SendBarrierEvent(CursorScreenPtr cs, struct PointerBarrier *barrier,
-+ int x, int y, int velocity, Bool threshold_exceeded)
++/*
++ * ConstrainCursorHarder is called from the SIGIO context.
++ * This means we cannot safely send a client event from anything in
++ * CursorConstrainCursorHarder's callgraph.
++ *
++ * Allocate a set of WorkQueue items to use.
++ */
++
++struct BarrierEventStore {
++ WorkQueueRec wq_item;
++ xXFixesBarrierNotifyEvent ev;
++ Bool in_use;
++};
++
++/* Let's guess that 100 events is enough of a buffer. */
++#define BARRIER_EVENT_QUEUE_SIZE 100
++struct BarrierEventStore barrierEventQueue[BARRIER_EVENT_QUEUE_SIZE];
++
++static void
++CursorWorkQueueDestroyProc (WorkQueuePtr this)
++{
++ struct BarrierEventStore *store;
++ store = container_of (this, struct BarrierEventStore, wq_item);
++
++ store->in_use = FALSE;
++}
++
++static Bool
++CursorSendBarrierEvent (ClientPtr client, pointer eventStore)
++{
++ struct BarrierEventStore *store = (struct BarrierEventStore *)eventStore;
++ WriteEventsToClient (client, 1, (xEvent *)&store->ev);
++
++ return TRUE;
++}
++
++static struct BarrierEventStore *
++CursorFindFreeEventStore (void)
++{
++ for (int i = 0; i < BARRIER_EVENT_QUEUE_SIZE; ++i) {
++ if (!barrierEventQueue[i].in_use) {
++ return &barrierEventQueue[i];
++ }
++ }
++ return NULL;
++}
++
++static void
++QueueBarrierEvent(CursorScreenPtr cs, struct PointerBarrier *barrier,
++ int x, int y, int velocity, Bool threshold_exceeded)
+{
+ PointerBarrierEventClientPtr client;
++ struct BarrierEventStore *store;
+ 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;
++ store = CursorFindFreeEventStore ();
++ if (store == NULL) {
++ ErrorF ("[xfixes] Barrier event queue full. Dropping further events\n");
++ return;
++ }
++
++ store->in_use = TRUE;
++
++ store->ev.type = XFixesEventBase + XFixesBarrierNotify;
++ store->ev.subtype = threshold_exceeded ? XFixesBarrierThresholdExceededNotify :
++ XFixesBarrierHitNotify;
++ store->ev.event_id = barrier->barrierEventID;
++ store->ev.barrier = barrier->barrier;
++ store->ev.x = x;
++ store->ev.y = y;
++ store->ev.velocity = velocity;
++ store->ev.timestamp = currentTime.milliseconds;
+
+ if (client->client->swapped) {
+ int n;
+
-+ swapl(&ev.event_id, n);
-+ swapl(&ev.barrier, n);
-+ swaps(&ev.x, n);
-+ swaps(&ev.y, n);
-+ swapl(&ev.velocity, n);
-+ swapl(&ev.timestamp, n);
++ swapl(&store->ev.event_id, n);
++ swapl(&store->ev.barrier, n);
++ swaps(&store->ev.x, n);
++ swaps(&store->ev.y, n);
++ swapl(&store->ev.velocity, n);
++ swapl(&store->ev.timestamp, n);
+ }
-+
-+ WriteEventsToClient (client->client, 1, (xEvent *) &ev);
++
++ store->wq_item.function = CursorSendBarrierEvent;
++ store->wq_item.client = client->client;
++ store->wq_item.closure = store;
++ store->wq_item.destroyProc = CursorWorkQueueDestroyProc;
++
++ QueueWorkItem (&store->wq_item);
+ }
+}
+
@@ -104,13 +185,13 @@ Index: xorg-server/xfixes/cursor.c
+ *vel_x = abs(dx) * 1000.0 / dt;
+ *vel_y = abs(dy) * 1000.0 / dt;
+
-+ last_timestamp = timestamp;
++ last_timestamp = timestamp;
+}
+
-+static void
+ static void
CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, int *x, int *y)
{
- CursorScreenPtr cs = GetCursorScreen(screen);
+@@ -1238,12 +1368,23 @@
if (!list_is_empty(&cs->barriers) && !IsFloating(dev) && mode == Relative) {
int ox, oy;
@@ -134,7 +215,7 @@ Index: xorg-server/xfixes/cursor.c
/* How this works:
* Given the origin and the movement vector, get the nearest barrier
* to the origin that is blocking the movement.
-@@ -1251,12 +1330,28 @@
+@@ -1251,11 +1392,27 @@
* Then, check from the clamped intersection to the original
* destination, again finding the nearest barrier and clamping.
*/
@@ -160,13 +241,12 @@ Index: xorg-server/xfixes/cursor.c
+ barrier_clamp_to_barrier(nearest, dir, x, y);
+ nearest->hit = TRUE;
+ }
++
++ QueueBarrierEvent(cs, nearest, *x, *y, velocity, threshold_exceeded);
-+ SendBarrierEvent(cs, nearest, *x, *y, velocity, threshold_exceeded);
-+
if (barrier_is_vertical(nearest)) {
dir &= ~(BarrierNegativeX | BarrierPositiveX);
- ox = *x;
-@@ -1265,11 +1360,31 @@
+@@ -1265,11 +1422,31 @@
oy = *y;
}
@@ -189,7 +269,7 @@ Index: xorg-server/xfixes/cursor.c
+ nearest->hit = TRUE;
+ }
+
-+ SendBarrierEvent(cs, nearest, *x, *y, velocity, threshold_exceeded);
++ QueueBarrierEvent(cs, nearest, *x, *y, velocity, threshold_exceeded);
}
}
+
@@ -200,7 +280,7 @@ Index: xorg-server/xfixes/cursor.c
}
if (cs->ConstrainCursorHarder) {
-@@ -1284,15 +1399,45 @@
+@@ -1284,15 +1461,45 @@
xXFixesCreatePointerBarrierReq *stuff)
{
CursorScreenPtr cs = GetCursorScreen(screen);
@@ -247,7 +327,7 @@ Index: xorg-server/xfixes/cursor.c
if (barrier_is_horizontal(&ret->barrier))
ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
if (barrier_is_vertical(&ret->barrier))
-@@ -1365,6 +1510,69 @@
+@@ -1365,6 +1572,69 @@
return ProcXFixesVector[stuff->xfixesReqType](client);
}
@@ -317,7 +397,7 @@ Index: xorg-server/xfixes/cursor.c
static int
CursorFreeBarrier(void *data, XID id)
{
-@@ -1421,6 +1629,118 @@
+@@ -1421,6 +1691,118 @@
return ProcXFixesVector[stuff->xfixesReqType](client);
}
@@ -352,7 +432,7 @@ Index: xorg-server/xfixes/cursor.c
+ ret->client = client;
+ ret->eventMask = stuff->eventMask;
+ ret->window = stuff->window;
-+ ret->resource = FakeClientID (client->index);
++ ret->resource = FakeClientID (client->index);
+ list_add(&ret->entry, &cs->barrierClients);
+ }
+
@@ -382,7 +462,7 @@ Index: xorg-server/xfixes/cursor.c
+
+ if (!AddResource (eventClient->resource, PointerBarrierClientType, eventClient))
+ return BadAlloc;
-+
++
+ return Success;
+}
+
@@ -416,7 +496,7 @@ Index: xorg-server/xfixes/cursor.c
+ }
+
+ barrier->releaseEventID = stuff->event_id;
-+
++
+ return Success;
+}
+
@@ -436,7 +516,7 @@ Index: xorg-server/xfixes/cursor.c
Bool
XFixesCursorInit (void)
{
-@@ -1441,6 +1761,7 @@
+@@ -1441,6 +1823,7 @@
if (!cs)
return FALSE;
list_init(&cs->barriers);
@@ -444,7 +524,7 @@ Index: xorg-server/xfixes/cursor.c
Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
Wrap (cs, pScreen, ConstrainCursorHarder, CursorConstrainCursorHarder);
-@@ -1455,8 +1776,10 @@
+@@ -1455,8 +1838,10 @@
"XFixesCursorWindow");
PointerBarrierType = CreateNewResourceType(CursorFreeBarrier,
"XFixesPointerBarrier");
@@ -458,8 +538,8 @@ Index: xorg-server/xfixes/cursor.c
Index: xorg-server/xfixes/xfixes.c
===================================================================
---- xorg-server.orig/xfixes/xfixes.c 2012-02-29 14:01:49.946067501 +1100
-+++ xorg-server/xfixes/xfixes.c 2012-02-29 14:02:32.870067406 +1100
+--- xorg-server.orig/xfixes/xfixes.c 2012-03-07 22:24:45.592697117 +1100
++++ xorg-server/xfixes/xfixes.c 2012-03-08 07:40:35.480111388 +1100
@@ -100,6 +100,7 @@
X_XFixesExpandRegion, /* Version 3 */
X_XFixesShowCursor, /* Version 4 */
@@ -492,8 +572,8 @@ Index: xorg-server/xfixes/xfixes.c
static int
Index: xorg-server/xfixes/xfixes.h
===================================================================
---- xorg-server.orig/xfixes/xfixes.h 2012-02-29 14:01:49.958067501 +1100
-+++ xorg-server/xfixes/xfixes.h 2012-02-29 14:02:32.870067406 +1100
+--- xorg-server.orig/xfixes/xfixes.h 2012-03-07 22:24:45.608697118 +1100
++++ xorg-server/xfixes/xfixes.h 2012-03-08 07:40:35.480111388 +1100
@@ -28,6 +28,7 @@
#define _XFIXES_H_
@@ -502,7 +582,7 @@ Index: xorg-server/xfixes/xfixes.h
extern _X_EXPORT RESTYPE RegionResType;
extern _X_EXPORT RESTYPE PointerBarrierType;
-@@ -52,9 +53,27 @@
+@@ -52,9 +53,25 @@
extern _X_EXPORT RegionPtr
XFixesRegionCopy (RegionPtr pRegion);
@@ -517,8 +597,6 @@ Index: xorg-server/xfixes/xfixes.h
+ struct list entry;
+};
+
-+
-+
struct PointerBarrier {
+ XID barrier;
CARD16 x1, x2, y1, y2;
@@ -532,8 +610,8 @@ Index: xorg-server/xfixes/xfixes.h
Index: xorg-server/xfixes/xfixesint.h
===================================================================
---- xorg-server.orig/xfixes/xfixesint.h 2012-02-29 14:01:49.966067502 +1100
-+++ xorg-server/xfixes/xfixesint.h 2012-02-29 14:02:32.870067406 +1100
+--- xorg-server.orig/xfixes/xfixesint.h 2012-03-07 22:24:45.616697118 +1100
++++ xorg-server/xfixes/xfixesint.h 2012-03-08 07:40:35.480111388 +1100
@@ -59,6 +59,7 @@
#include "windowstr.h"
#include "selection.h"
@@ -571,8 +649,8 @@ Index: xorg-server/xfixes/xfixesint.h
void PanoramiXFixesInit (void);
Index: xorg-server/dix/getevents.c
===================================================================
---- xorg-server.orig/dix/getevents.c 2012-02-29 14:01:49.974067501 +1100
-+++ xorg-server/dix/getevents.c 2012-02-29 14:02:32.874067406 +1100
+--- xorg-server.orig/dix/getevents.c 2012-03-07 22:24:45.624697119 +1100
++++ xorg-server/dix/getevents.c 2012-03-08 11:02:31.739464474 +1100
@@ -79,6 +79,12 @@
InternalEvent* InputEventList = NULL;
@@ -590,7 +668,7 @@ Index: xorg-server/dix/getevents.c
/* miPointerSetPosition takes care of crossing screens for us, as well as
* clipping to the current screen. Coordinates returned are in desktop
* coord system */
-+ /**
++ /**
+ * Hack to pass the unclipped values through to the pointer barrier code.
+ * Required (for now) to calculate the velocity.
+ */
@@ -605,8 +683,8 @@ Index: xorg-server/dix/getevents.c
Index: xorg-server/test/gtest/xfixes_barriers.cpp
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ xorg-server/test/gtest/xfixes_barriers.cpp 2012-02-29 14:02:32.874067406 +1100
-@@ -0,0 +1,362 @@
++++ xorg-server/test/gtest/xfixes_barriers.cpp 2012-03-08 07:42:49.188104249 +1100
+@@ -0,0 +1,828 @@
+/*
+
+Copyright (c) 2012, Canonical Ltd
@@ -632,6 +710,7 @@ Index: xorg-server/test/gtest/xfixes_barriers.cpp
+*/
+
+#include <iostream>
++#include <sys/time.h>
+#include <unistd.h>
+#include <gtest/gtest.h>
+#include <xorg/gtest/test.h>
@@ -645,7 +724,7 @@ Index: xorg-server/test/gtest/xfixes_barriers.cpp
+{
+ ::testing::InitGoogleTest (&argc, argv);
+ xorg::testing::Environment* environment = new xorg::testing::Environment ();
-+ environment->set_conf_file ("dummy.conf");
++ environment->set_conf_file (XORG_DUMMY_CONF);
+ environment->set_server (XORG_BINARY);
+ testing::AddGlobalTestEnvironment (environment);
+ return RUN_ALL_TESTS ();
@@ -655,6 +734,10 @@ Index: xorg-server/test/gtest/xfixes_barriers.cpp
+ public:
+ ::Display *dpy;
+ static XErrorEvent *lastError;
++ int xtest_eventbase;
++ int xtest_errorbase;
++ int fixes_eventbase;
++ int fixes_errorbase;
+
+ void AssertPointerPosition (int expected_x, int expected_y)
+ {
@@ -665,9 +748,31 @@ Index: xorg-server/test/gtest/xfixes_barriers.cpp
+ XQueryPointer (Display (), DefaultRootWindow (Display ()),
+ &unused_win, &unused_win, &x, &y,
+ &unused_int, &unused_int, &unused_uint);
-+
-+ ASSERT_EQ (expected_x, x);
-+ ASSERT_EQ (expected_y, y);
++
++ ASSERT_TRUE (x == expected_x && y == expected_y) <<
++ "Incorrect pointer position: Expected ("<<
++ expected_x<< ", "<<expected_y<<"), got "<<
++ "("<<x<<", "<<y<<")\n";
++ }
++
++ bool WaitForXEvent (int msTimeout = 1000)
++ {
++ fd_set fds;
++ int xfd = ConnectionNumber (Display ());
++ struct timeval tv;
++ int retval;
++
++ FD_ZERO (&fds);
++ FD_SET (xfd, &fds);
++
++ tv.tv_sec = msTimeout / 1000;
++ tv.tv_usec = (msTimeout % 1000) * 1000;
++
++ retval = select (xfd + 1, &fds, NULL, NULL, &tv);
++
++ EXPECT_NE (-1, retval)<<"Error waiting for X event";
++
++ return retval;
+ }
+
+ protected:
@@ -701,12 +806,7 @@ Index: xorg-server/test/gtest/xfixes_barriers.cpp
+ {
+ memcpy (lastError, error, sizeof (*lastError));
+ return 0;
-+ }
-+
-+ int xtest_eventbase;
-+ int xtest_errorbase;
-+ int fixes_eventbase;
-+ int fixes_errorbase;
++ }
+};
+
+XErrorEvent *BarrierTest::lastError = NULL;
@@ -735,244 +835,688 @@ Index: xorg-server/test/gtest/xfixes_barriers.cpp
+
+TEST_F (BarrierTest, CreateNonAxisAlignedBarrierFails)
+{
-+ PointerBarrier barrier;
-+
-+ barrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow(dpy),
-+ 0, 0,
-+ 100, 100,
-+ 0,
-+ 0, NULL);
++ XFixesCreatePointerBarrier (dpy, DefaultRootWindow(dpy),
++ 0, 0,
++ 100, 100,
++ 0,
++ 0, NULL);
+ XSync (Display (), false);
+ ASSERT_EQ(BadValue, lastError->error_code);
+}
-+
++
+TEST_F (BarrierTest, VerticalBidirectionalBarrierBlocksRelativeMotion)
+{
-+ PointerBarrier barrier;
-+ barrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow (dpy),
-+ 100, 0,
-+ 100, 300,
-+ 0,
-+ 0, NULL);
-+ // Absolute event will ignore barrier
++ int barrier_x = 100;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ barrier_x, 0,
++ barrier_x, 300,
++ 0, 0, NULL);
++
++ int x = 200, y = 100, dx = -200, dy = 0;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 100, 0);
++ x, y, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 100));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
+ // Relative motion should block on barrier
-+ XTestFakeRelativeMotionEvent (Display (), -200, 0, 0);
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (100, 100));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y));
+}
+
+TEST_F (BarrierTest, VerticalPositiveXBarrierBlocksMotion)
+{
-+ PointerBarrier positiveXBarrier;
-+ positiveXBarrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow (dpy),
-+ 100, 0,
-+ 100, 300,
-+ BarrierPositiveX,
-+ 0, NULL);
-+ // Absolute event will ignore barrier
++ int barrier_x = 100;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ barrier_x, 0,
++ barrier_x, 300,
++ BarrierPositiveX, 0, NULL);
++ int x = 200, y = 100, dx = -200, dy = 0;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 100, 0);
++ x, y, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 100));
-+
+ // Relative motion in -ve X direction should block on barrier
-+ XTestFakeRelativeMotionEvent (Display (), -200, 0, 0);
-+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (100, 100));
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y + dy));
+
-+ // Absolute event will ignore barrier
++ x = 0, y = 100, dx = 200, dy = 0;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 0, 100, 0);
++ x, y, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (0, 100));
-+
+ // Relative motion in +ve X direction should ignore barrier
-+ XTestFakeRelativeMotionEvent (Display (), 200, 0, 0);
-+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 100));
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
+}
+
+TEST_F (BarrierTest, VerticalNegativeXBarrierBlocksMotion)
+{
-+ PointerBarrier positiveXBarrier;
-+ positiveXBarrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow (dpy),
-+ 100, 0,
-+ 100, 300,
-+ BarrierNegativeX,
-+ 0, NULL);
-+ // Absolute event will ignore barrier
++ int barrier_x = 100;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ barrier_x, 0,
++ barrier_x, 300,
++ BarrierNegativeX,
++ 0, NULL);
++
++ int x = 200, y = 100, dx = -200, dy = 0;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 100, 0);
++ x, y, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 100));
-+
+ // Relative motion in -ve X direction should ignore barrier
-+ XTestFakeRelativeMotionEvent (Display (), -200, 0, 0);
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
++
++ x = 0, y = 100, dx = 200, dy = 0;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (0, 100));
-+
+ // Relative motion in +ve X direction should block on barrier
-+ XTestFakeRelativeMotionEvent (Display (), 200, 0, 0);
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (99, 100));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x - 1, y + dy));
+}
+
+TEST_F (BarrierTest, HorizontalBidirectionalBarrierBlocksRelativeMotion)
+{
-+ PointerBarrier barrier;
-+ barrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow (dpy),
-+ 0, 100,
-+ 300, 100,
-+ 0,
-+ 0, NULL);
-+ // Absolute event will ignore barrier
++ int barrier_y = 100;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ 0, barrier_y,
++ 300, barrier_y,
++ 0, 0, NULL);
++
++ int x = 200, y = 0;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 200, 0);
++ x, y, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 200));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ // Relative motion should block on barrier
-+ XTestFakeRelativeMotionEvent (Display (), 0, -200, 0);
++ // Relative motion in +ve Y direction should block on barrier
++ int dx = 0, dy = 200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 100));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y - 1));
+
-+ // Absolute event will ignore barrier
++ x = 100, y = 200;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 0, 0);
++ x, y, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 0));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ // Relative motion should block on barrier
-+ XTestFakeRelativeMotionEvent (Display (), 0, 200, 0);
++ // Relative motion in -ve Y direction should block on barrier
++ dx = 0, dy = -200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 99));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y));
+}
+
+TEST_F (BarrierTest, HorizontalPositiveYBarrierBlocksMotion)
+{
-+ PointerBarrier positiveXBarrier;
-+ positiveXBarrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow (dpy),
-+ 0, 100,
-+ 300, 100,
-+ BarrierPositiveY,
-+ 0, NULL);
-+ // Absolute event will ignore barrier
-+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 200, 0);
++ int barrier_y = 100;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ 0, barrier_y,
++ 300, barrier_y,
++ BarrierPositiveY, 0, NULL);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 200));
-+
-+ // Relative motion in -ve Y direction should block on barrier
-+ XTestFakeRelativeMotionEvent (Display (), 0, -200, 0);
++ int x = 200, y = 0;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 100));
++ // Relative motion in +ve Y direction should ignore barrier
++ int dx = 0, dy = 200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
+
-+ // Absolute event will ignore barrier
++ x = 100, y = 200;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 100, 0, 0);
++ x, y, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (100, 0));
-+
-+ // Relative motion in +ve X direction should ignore barrier
-+ XTestFakeRelativeMotionEvent (Display (), 0, 200, 0);
-+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (100, 200));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
++
++ // Relative motion in -ve Y direction should block on barrier
++ dx = 0, dy = -200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y));
+}
+
+TEST_F (BarrierTest, HorizontalNegativeYBarrierBlocksMotion)
+{
-+ PointerBarrier positiveXBarrier;
-+ positiveXBarrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow (dpy),
-+ 0, 100,
-+ 300, 100,
-+ BarrierNegativeY,
-+ 0, NULL);
-+ // Absolute event will ignore barrier
++ int barrier_y = 100;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ 0, barrier_y,
++ 300, barrier_y,
++ BarrierNegativeY, 0, NULL);
++
++ int x = 200, y = 0;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 200, 0);
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
++
++ // Relative motion in +ve Y direction should block on barrier
++ int dx = 0, dy = 200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y - 1));
++
++ x = 100, y = 200;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 200));
-+
+ // Relative motion in -ve Y direction should ignore barrier
-+ XTestFakeRelativeMotionEvent (Display (), 0, -200, 0);
++ dx = 0, dy = -200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 0));
-+
-+ // Relative motion in +ve Y direction should block on barrier
-+ XTestFakeRelativeMotionEvent (Display (), 0, 200, 0);
-+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 99));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
+}
+
+TEST_F (BarrierTest, DestroyPointerBarrierSucceeds)
+{
++ int barrier_x = 100;
+ PointerBarrier barrier;
-+ barrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow (dpy),
-+ 100, 0,
-+ 100, 300,
-+ 0,
-+ 0, NULL);
++ barrier = XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ barrier_x, 0,
++ barrier_x, 300,
++ 0, 0, NULL);
+
-+ XFixesDestroyPointerBarrier (Display (), barrier);
-+ // Absolute event will ignore barrier
++ int x = 0, y = 200;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 100, 0);
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 100));
++ // Check that the barrier exists before we destroy it.
++ int dx = 200, dy = 0;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x - 1, y + dy));
+
-+ // There should be no barrier to block this.
-+ XTestFakeRelativeMotionEvent (Display (), -200, 0, 0);
++ // Destroy the barrier...
++ XFixesDestroyPointerBarrier (Display (), barrier);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (0, 100));
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
++
++ // There should be no barrier to block this.
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
+}
+
+TEST_F (BarrierTest, BarrierIgnoresNonsensicalDirections)
+{
-+ PointerBarrier verticalBarrier;
-+ verticalBarrier = XFixesCreatePointerBarrier (Display (),
-+ DefaultRootWindow (Display ()),
-+ 100, 0,
-+ 100, 300,
-+ BarrierPositiveY | BarrierNegativeY,
-+ 0, NULL);
-+
-+ // Absolute event will ignore barrier
++ int barrier_x = 100;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ barrier_x, 0,
++ barrier_x, 300,
++ BarrierPositiveY | BarrierNegativeY,
++ 0, NULL);
++
++ int x = 200, y = 100;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 100, 0);
++ x, y, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 100));
++ int dx = -200, dy = 0;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
+
-+ // Barrier should block relative motion
-+ XTestFakeRelativeMotionEvent (Display (), -200, 0, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y + dy));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (100, 100));
++ int barrier_y = 100;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ 0, barrier_y,
++ 400, barrier_y,
++ BarrierPositiveX | BarrierNegativeX,
++ 0, NULL);
+
-+ PointerBarrier horizontalBarrier;
-+ horizontalBarrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow (dpy),
-+ 0, 100,
-+ 400, 100,
-+ BarrierPositiveX | BarrierNegativeX,
-+ 0, NULL);
-+ // Absolute event will ignore barrier
++ x = 100, y = 200;
+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
-+ 200, 200, 0);
++ x, y, 0);
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 200));
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ // Barrier should block relative motion
-+ XTestFakeRelativeMotionEvent (Display (), 0, -200, 0);
++ dx = 0, dy = -200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y));
++}
++
++TEST_F (BarrierTest, VerticalBarrierEdges)
++{
++ int barrier_x = 300, barrier_y1 = 300 , barrier_y2 = 500;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ barrier_x, barrier_y1,
++ barrier_x, barrier_y2,
++ 0, 0, NULL);
++
++ int x = barrier_x + 100, y = barrier_y1 - 1;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
++
++ // Motion should take us past the top of the barrier...
++ int dx = -200, dy = 0;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
++
++ x = barrier_x + 100, y = barrier_y1;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
++
++ // Motion should hit the top of the barrier...
++ dx = -200, dy = 0;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y + dy));
++
++ x = barrier_x + 100, y = barrier_y2;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
++
++ // Motion should hit the bottom of the barrier...
++ dx = -200, dy = 0;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y + dy));
++
++ x = barrier_x + 100, y = barrier_y2 + 1;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
+
-+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (200, 100));
++ // Motion should take us past the bottom of the barrier...
++ dx = -200, dy = 0;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
++}
++
++TEST_F (BarrierTest, HorizontalBarrierEdges)
++{
++ int barrier_x1 = 200, barrier_x2 = 500, barrier_y = 300;
++ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
++ barrier_x1, barrier_y,
++ barrier_x2, barrier_y,
++ 0, 0, NULL);
++
++ int x = barrier_x1 - 1, y = barrier_y - 100;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
++
++ // Motion should take us past the left edge of the barrier...
++ int dx = 0, dy = 200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
++
++ x = barrier_x1, y = barrier_y - 100;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
++
++ // Motion should hit the top of the barrier...
++ dx = 0, dy = 200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, barrier_y - 1));
++
++ x = barrier_x2, y = barrier_y - 100;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
++ x, y, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
++
++ // Motion should hit the bottom of the barrier...
++ dx = 0, dy = 200;
++ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
++ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y - 1));
++
++ x = barrier_x2 + 1, y = barrier_y - 100;
++ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
Reply to: