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 <[email protected]> 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 <[email protected]> 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 ()), -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: http://lists.debian.org/[email protected]

