diff --git a/debian/patches/219_fedora-pointer-barriers.diff b/debian/patches/219_fedora-pointer-barriers.diff
+++ /dev/null
@@ -1,1020 +0,0 @@
-From 14f1112bec18ccece8e732fe6c200a56546230c7 Mon Sep 17 00:00:00 2001
-From: Adam Jackson <ajax@redhat.com>
-Date: Thu, 17 Mar 2011 13:56:17 -0400
-Subject: [PATCH] CRTC confine and pointer barriers
-
----
- dix/events.c | 7 +
- dix/getevents.c | 12 +-
- include/dix.h | 1 +
- include/protocol-versions.h | 2 +-
- mi/mipointer.c | 16 ++-
- mi/mipointer.h | 6 +
- randr/randr.c | 2 +
- randr/randrstr.h | 4 +
- randr/rrcrtc.c | 155 ++++++++++++++++
- xfixes/cursor.c | 399 ++++++++++++++++++++++++++++++++++++++++++-
- xfixes/xfixes.c | 24 ++-
- xfixes/xfixes.h | 17 ++
- xfixes/xfixesint.h | 16 ++
- 14 files changed, 658 insertions(+), 16 deletions(-)
-
-Index: xorg-server/dix/events.c
-===================================================================
---- xorg-server.orig/dix/events.c 2011-08-24 12:52:44.325647127 +0300
-+++ xorg-server/dix/events.c 2011-08-24 12:57:24.685651121 +0300
-@@ -328,6 +328,13 @@
- return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD;
- }
-
-+Bool
-+IsFloating(DeviceIntPtr dev)
-+{
-+ return GetMaster(dev, MASTER_KEYBOARD) == NULL;
-+}
-+
-+
- /**
- * Max event opcode.
- */
-Index: xorg-server/dix/getevents.c
-===================================================================
---- xorg-server.orig/dix/getevents.c 2011-08-24 12:52:44.315647128 +0300
-+++ xorg-server/dix/getevents.c 2011-08-24 12:57:20.625651063 +0300
-@@ -816,7 +816,11 @@
- * miPointerSetPosition() and then scale back into device coordinates (if
- * needed). miPSP will change x/y if the screen was crossed.
- *
-+ * The coordinates provided are always absolute. The parameter mode whether
-+ * it was relative or absolute movement that landed us at those coordinates.
-+ *
- * @param dev The device to be moved.
-+ * @param mode Movement mode (Absolute or Relative)
- * @param x Pointer to current x-axis value, may be modified.
- * @param y Pointer to current y-axis value, may be modified.
- * @param x_frac Fractional part of current x-axis value, may be modified.
-@@ -828,7 +832,8 @@
- * @param screeny_frac Fractional part of screen y coordinate, as above.
- */
- static void
--positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
-+positionSprite(DeviceIntPtr dev, int mode,
-+ int *x, int *y, float x_frac, float y_frac,
- ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac)
- {
- int old_screenx, old_screeny;
-@@ -867,7 +872,7 @@
- old_screeny = *screeny;
- /* This takes care of crossing screens for us, as well as clipping
- * to the current screen. */
-- miPointerSetPosition(dev, screenx, screeny);
-+ _miPointerSetPosition(dev, mode, screenx, screeny);
-
- if (dev->u.master) {
- dev->u.master->last.valuators[0] = *screenx;
-@@ -1202,7 +1207,8 @@
- if ((flags & POINTER_NORAW) == 0)
- set_raw_valuators(raw, &mask, raw->valuators.data);
-
-- positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
-+ positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
-+ &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
- updateHistory(pDev, &mask, ms);
-
- /* Update the valuators with the true value sent to the client*/
-Index: xorg-server/include/dix.h
-===================================================================
---- xorg-server.orig/include/dix.h 2011-08-24 12:52:44.355647127 +0300
-+++ xorg-server/include/dix.h 2011-08-24 12:57:24.695651123 +0300
-@@ -570,6 +570,7 @@
- extern Bool _X_EXPORT IsKeyboardDevice(DeviceIntPtr dev);
- extern Bool IsPointerEvent(InternalEvent *event);
- extern _X_EXPORT Bool IsMaster(DeviceIntPtr dev);
-+extern _X_EXPORT Bool IsFloating(DeviceIntPtr dev);
-
- extern _X_HIDDEN void CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
- extern _X_HIDDEN int CorePointerProc(DeviceIntPtr dev, int what);
-Index: xorg-server/include/protocol-versions.h
-===================================================================
---- xorg-server.orig/include/protocol-versions.h 2011-08-24 12:52:44.365647129 +0300
-+++ xorg-server/include/protocol-versions.h 2011-08-24 12:57:20.735651065 +0300
-@@ -126,7 +126,7 @@
- #define SERVER_XF86VIDMODE_MINOR_VERSION 2
-
- /* Fixes */
--#define SERVER_XFIXES_MAJOR_VERSION 4
-+#define SERVER_XFIXES_MAJOR_VERSION 5
- #define SERVER_XFIXES_MINOR_VERSION 0
-
- /* X Input */
-Index: xorg-server/mi/mipointer.c
-===================================================================
---- xorg-server.orig/mi/mipointer.c 2011-08-24 12:56:49.645650622 +0300
-+++ xorg-server/mi/mipointer.c 2011-08-24 12:56:49.825650624 +0300
-@@ -229,6 +229,10 @@
- SetupScreen (pScreen);
-
- GenerateEvent = generateEvent;
-+
-+ if (pScreen->ConstrainCursorHarder)
-+ pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y);
-+
- /* device dependent - must pend signal and call miPointerWarpCursor */
- (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y);
- if (!generateEvent)
-@@ -488,7 +492,7 @@
- }
-
- void
--miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
-+_miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y)
- {
- miPointerScreenPtr pScreenPriv;
- ScreenPtr pScreen;
-@@ -532,6 +536,9 @@
- 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)
- return;
-@@ -539,6 +546,13 @@
- miPointerMoveNoEvent(pDev, pScreen, *x, *y);
- }
-
-+/* ABI hack */
-+void
-+miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
-+{
-+ _miPointerSetPosition(pDev, Absolute, x, y);
-+}
-+
- void
- miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)
- {
-Index: xorg-server/mi/mipointer.h
-===================================================================
---- xorg-server.orig/mi/mipointer.h 2011-08-24 12:52:44.375647128 +0300
-+++ xorg-server/mi/mipointer.h 2011-08-24 12:56:49.825650624 +0300
-@@ -131,6 +131,12 @@
-
- /* Moves the cursor to the specified position. May clip the co-ordinates:
- * x and y are modified in-place. */
-+extern _X_EXPORT void _miPointerSetPosition(
-+ DeviceIntPtr pDev,
-+ int mode,
-+ int *x,
-+ int *y);
-+
- extern _X_EXPORT void miPointerSetPosition(
- DeviceIntPtr pDev,
- int *x,
-Index: xorg-server/randr/randr.c
-===================================================================
---- xorg-server.orig/randr/randr.c 2011-08-24 12:56:49.745650625 +0300
-+++ xorg-server/randr/randr.c 2011-08-24 12:56:49.825650624 +0300
-@@ -270,6 +270,8 @@
-
- wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
-
-+ pScreen->ConstrainCursorHarder = RRConstrainCursorHarder;
-+
- pScrPriv->numOutputs = 0;
- pScrPriv->outputs = NULL;
- pScrPriv->numCrtcs = 0;
-Index: xorg-server/randr/randrstr.h
-===================================================================
---- xorg-server.orig/randr/randrstr.h 2011-08-24 12:52:44.305647126 +0300
-+++ xorg-server/randr/randrstr.h 2011-08-24 12:56:49.825650624 +0300
-@@ -297,6 +297,7 @@
- int rate;
- int size;
- #endif
-+ Bool discontiguous;
- } rrScrPrivRec, *rrScrPrivPtr;
-
- extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
-@@ -700,6 +701,9 @@
- int
- ProcRRSetPanning (ClientPtr client);
-
-+void
-+RRConstrainCursorHarder (DeviceIntPtr, ScreenPtr, int, int *, int *);
-+
- /* rrdispatch.c */
- extern _X_EXPORT Bool
- RRClientKnowsRates (ClientPtr pClient);
-Index: xorg-server/randr/rrcrtc.c
-===================================================================
---- xorg-server.orig/randr/rrcrtc.c 2011-08-24 12:52:44.285647124 +0300
-+++ xorg-server/randr/rrcrtc.c 2011-08-24 12:56:49.825650624 +0300
-@@ -1,5 +1,6 @@
- /*
- * Copyright © 2006 Keith Packard
-+ * Copyright 2010 Red Hat, Inc
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
-@@ -22,6 +23,7 @@
-
- #include "randrstr.h"
- #include "swaprep.h"
-+#include "mipointer.h"
-
- RESTYPE RRCrtcType;
-
-@@ -292,6 +294,92 @@
- return FALSE;
- }
-
-+static void
-+crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
-+{
-+ *left = crtc->x;
-+ *top = crtc->y;
-+
-+ switch (crtc->rotation) {
-+ case RR_Rotate_0:
-+ case RR_Rotate_180:
-+ default:
-+ *right = crtc->x + crtc->mode->mode.width;
-+ *bottom = crtc->y + crtc->mode->mode.height;
-+ return;
-+ case RR_Rotate_90:
-+ case RR_Rotate_270:
-+ *right = crtc->x + crtc->mode->mode.height;
-+ *bottom = crtc->y + crtc->mode->mode.width;
-+ return;
-+ }
-+}
-+
-+/* overlapping counts as adjacent */
-+static Bool
-+crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b)
-+{
-+ /* left, right, top, bottom... */
-+ int al, ar, at, ab;
-+ int bl, br, bt, bb;
-+ int cl, cr, ct, cb; /* the overlap, if any */
-+
-+ crtc_bounds(a, &al, &ar, &at, &ab);
-+ crtc_bounds(b, &bl, &br, &bt, &bb);
-+
-+ cl = max(al, bl);
-+ cr = min(ar, br);
-+ ct = max(at, bt);
-+ cb = min(ab, bb);
-+
-+ return (cl <= cr) && (ct <= cb);
-+}
-+
-+/* Depth-first search and mark all CRTCs reachable from cur */
-+static void
-+mark_crtcs (rrScrPrivPtr pScrPriv, int *reachable, int cur)
-+{
-+ int i;
-+ reachable[cur] = TRUE;
-+ for (i = 0; i < pScrPriv->numCrtcs; ++i) {
-+ if (reachable[i] || !pScrPriv->crtcs[i]->mode)
-+ continue;
-+ if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i]))
-+ mark_crtcs(pScrPriv, reachable, i);
-+ }
-+}
-+
-+static void
-+RRComputeContiguity (ScreenPtr pScreen)
-+{
-+ rrScrPriv(pScreen);
-+ Bool discontiguous = TRUE;
-+ int i, n = pScrPriv->numCrtcs;
-+
-+ int *reachable = calloc(n, sizeof(int));
-+ if (!reachable)
-+ goto out;
-+
-+ /* Find first enabled CRTC and start search for reachable CRTCs from it */
-+ for (i = 0; i < n; ++i) {
-+ if (pScrPriv->crtcs[i]->mode) {
-+ mark_crtcs(pScrPriv, reachable, i);
-+ break;
-+ }
-+ }
-+
-+ /* Check that all enabled CRTCs were marked as reachable */
-+ for (i = 0; i < n; ++i)
-+ if (pScrPriv->crtcs[i]->mode && !reachable[i])
-+ goto out;
-+
-+ discontiguous = FALSE;
-+
-+out:
-+ free(reachable);
-+ pScrPriv->discontiguous = discontiguous;
-+}
-+
- /*
- * Request that the Crtc be reconfigured
- */
-@@ -306,6 +394,7 @@
- {
- ScreenPtr pScreen = crtc->pScreen;
- Bool ret = FALSE;
-+ Bool recompute = TRUE;
- rrScrPriv(pScreen);
-
- /* See if nothing changed */
-@@ -318,6 +407,7 @@
- !RRCrtcPendingProperties (crtc) &&
- !RRCrtcPendingTransform (crtc))
- {
-+ recompute = FALSE;
- ret = TRUE;
- }
- else
-@@ -381,6 +471,10 @@
- RRPostPendingProperties (outputs[o]);
- }
- }
-+
-+ if (recompute)
-+ RRComputeContiguity(pScreen);
-+
- return ret;
- }
-
-@@ -1349,3 +1443,64 @@
- free(reply);
- return Success;
- }
-+
-+void
-+RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x, int *y)
-+{
-+ rrScrPriv (pScreen);
-+ int i;
-+
-+ /* intentional dead space -> let it float */
-+ if (pScrPriv->discontiguous)
-+ return;
-+
-+ /* if we're moving inside a crtc, we're fine */
-+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
-+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
-+
-+ int left, right, top, bottom;
-+
-+ if (!crtc->mode)
-+ continue;
-+
-+ crtc_bounds(crtc, &left, &right, &top, &bottom);
-+
-+ if ((*x >= left) && (*x <= right) && (*y >= top) && (*y <= bottom))
-+ return;
-+ }
-+
-+ /* if we're trying to escape, clamp to the CRTC we're coming from */
-+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
-+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
-+ int nx, ny;
-+ int left, right, top, bottom;
-+
-+ if (!crtc->mode)
-+ continue;
-+
-+ crtc_bounds(crtc, &left, &right, &top, &bottom);
-+ miPointerGetPosition(pDev, &nx, &ny);
-+
-+ if ((nx >= left) && (nx <= right) && (ny >= top) && (ny <= bottom)) {
-+ if ((*x <= left) || (*x >= right)) {
-+ int dx = *x - nx;
-+
-+ if (dx > 0)
-+ *x = right;
-+ else if (dx < 0)
-+ *x = left;
-+ }
-+
-+ if ((*y <= top) || (*y >= bottom)) {
-+ int dy = *y - ny;
-+
-+ if (dy > 0)
-+ *y = bottom;
-+ else if (dy < 0)
-+ *y = top;
-+ }
-+
-+ return;
-+ }
-+ }
-+}
-Index: xorg-server/xfixes/cursor.c
-===================================================================
---- xorg-server.orig/xfixes/cursor.c 2011-08-24 12:52:44.345647126 +0300
-+++ xorg-server/xfixes/cursor.c 2011-08-24 12:56:49.825650624 +0300
-@@ -1,5 +1,6 @@
- /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
-+ * Copyright 2010 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
-@@ -50,13 +51,16 @@
- #include "cursorstr.h"
- #include "dixevents.h"
- #include "servermd.h"
-+#include "mipointer.h"
- #include "inputstr.h"
- #include "windowstr.h"
- #include "xace.h"
-+#include "list.h"
-
- static RESTYPE CursorClientType;
- static RESTYPE CursorHideCountType;
- static RESTYPE CursorWindowType;
-+RESTYPE PointerBarrierType;
- static CursorPtr CursorCurrent[MAXDEVICES];
-
- static DevPrivateKeyRec CursorScreenPrivateKeyRec;
-@@ -107,6 +111,14 @@
- XID resource;
- } CursorHideCountRec;
-
-+typedef struct PointerBarrierClient *PointerBarrierClientPtr;
-+
-+struct PointerBarrierClient {
-+ ScreenPtr screen;
-+ struct PointerBarrier barrier;
-+ struct list entry;
-+};
-+
- /*
- * Wrap DisplayCursor to catch cursor change events
- */
-@@ -114,7 +126,9 @@
- typedef struct _CursorScreen {
- DisplayCursorProcPtr DisplayCursor;
- CloseScreenProcPtr CloseScreen;
-+ ConstrainCursorHarderProcPtr ConstrainCursorHarder;
- CursorHideCountPtr pCursorHideCounts;
-+ struct list barriers;
- } CursorScreenRec, *CursorScreenPtr;
-
- #define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey))
-@@ -184,9 +198,11 @@
- Bool ret;
- CloseScreenProcPtr close_proc;
- DisplayCursorProcPtr display_proc;
-+ ConstrainCursorHarderProcPtr constrain_proc;
-
- Unwrap (cs, pScreen, CloseScreen, close_proc);
- Unwrap (cs, pScreen, DisplayCursor, display_proc);
-+ Unwrap (cs, pScreen, ConstrainCursorHarder, constrain_proc);
- deleteCursorHideCountsForScreen(pScreen);
- ret = (*pScreen->CloseScreen) (index, pScreen);
- free(cs);
-@@ -1029,6 +1045,382 @@
- return 1;
- }
-
-+static BOOL
-+barrier_is_horizontal(const struct PointerBarrier *barrier)
-+{
-+ return barrier->y1 == barrier->y2;
-+}
-+
-+static BOOL
-+barrier_is_vertical(const struct PointerBarrier *barrier)
-+{
-+ return barrier->x1 == barrier->x2;
-+}
-+
-+/**
-+ * @return The set of barrier movement directions the movement vector
-+ * x1/y1 → x2/y2 represents.
-+ */
-+int
-+barrier_get_direction(int x1, int y1, int x2, int y2)
-+{
-+ int direction = 0;
-+
-+ /* which way are we trying to go */
-+ if (x2 > x1)
-+ direction |= BarrierPositiveX;
-+ if (x2 < x1)
-+ direction |= BarrierNegativeX;
-+ if (y2 > y1)
-+ direction |= BarrierPositiveY;
-+ if (y2 < y1)
-+ direction |= BarrierNegativeY;
-+
-+ return direction;
-+}
-+
-+/**
-+ * Test if the barrier may block movement in the direction defined by
-+ * x1/y1 → x2/y2. This function only tests whether the directions could be
-+ * blocked, it does not test if the barrier actually blocks the movement.
-+ *
-+ * @return TRUE if the barrier blocks the direction of movement or FALSE
-+ * otherwise.
-+ */
-+BOOL
-+barrier_is_blocking_direction(const struct PointerBarrier *barrier, int direction)
-+{
-+ /* Barriers define which way is ok, not which way is blocking */
-+ return (barrier->directions & direction) != direction;
-+}
-+
-+/**
-+ * Test if the movement vector x1/y1 → x2/y2 is intersecting with the
-+ * barrier. A movement vector with the startpoint or endpoint adjacent to
-+ * the barrier itself counts as intersecting.
-+ *
-+ * @param x1 X start coordinate of movement vector
-+ * @param y1 Y start coordinate of movement vector
-+ * @param x2 X end coordinate of movement vector
-+ * @param y2 Y end coordinate of movement vector
-+ * @param[out] distance The distance between the start point and the
-+ * intersection with the barrier (if applicable).
-+ * @return TRUE if the barrier intersects with the given vector
-+ */
-+BOOL
-+barrier_is_blocking(const struct PointerBarrier *barrier,
-+ int x1, int y1, int x2, int y2,
-+ double *distance)
-+{
-+ BOOL rc = FALSE;
-+ float ua, ub, ud;
-+ int dir = barrier_get_direction(x1, y1, x2, y2);
-+
-+ /* Algorithm below doesn't handle edge cases well, hence the extra
-+ * checks. */
-+ if (barrier_is_vertical(barrier)) {
-+ /* handle immediate barrier adjacency, moving away */
-+ if (dir & BarrierPositiveX && x1 == barrier->x1)
-+ return FALSE;
-+ if (dir & BarrierNegativeX && x1 == (barrier->x1 - 1))
-+ return FALSE;
-+ /* startpoint adjacent to barrier, moving towards -> block */
-+ if (x1 == barrier->x1 && y1 >= barrier->y1 && y1 <= barrier->y2) {
-+ *distance = 0;
-+ return TRUE;
-+ }
-+ } else {
-+ /* handle immediate barrier adjacency, moving away */
-+ if (dir & BarrierPositiveY && y1 == barrier->y1)
-+ return FALSE;
-+ if (dir & BarrierNegativeY && y1 == (barrier->y1 - 1))
-+ return FALSE;
-+ /* startpoint adjacent to barrier, moving towards -> block */
-+ if (y1 == barrier->y1 && x1 >= barrier->x1 && x1 <= barrier->x2) {
-+ *distance = 0;
-+ return TRUE;
-+ }
-+ }
-+
-+ /* not an edge case, compute distance */
-+ ua = 0;
-+ ud = (barrier->y2 - barrier->y1) * (x2 - x1) - (barrier->x2 - barrier->x1) * (y2 - y1);
-+ if (ud != 0) {
-+ ua = ((barrier->x2 - barrier->x1) * (y1 - barrier->y1) -
-+ (barrier->y2 - barrier->y1) * (x1 - barrier->x1)) / ud;
-+ ub = ((x2 - x1) * (y1 - barrier->y1) -
-+ (y2 - y1) * (x1 - barrier->x1)) / ud;
-+ if (ua < 0 || ua > 1 || ub < 0 || ub > 1)
-+ ua = 0;
-+ }
-+
-+ if (ua > 0 && ua <= 1)
-+ {
-+ double ix = barrier->x1 + ua * (barrier->x2 - barrier->x1);
-+ double iy = barrier->y1 + ua * (barrier->y2 - barrier->y1);
-+
-+ *distance = sqrt(pow(x1 - ix, 2) + pow(y1 - iy, 2));
-+ rc = TRUE;
-+ }
-+
-+ return rc;
-+}
-+
-+/**
-+ * Find the nearest barrier that is blocking movement from x1/y1 to x2/y2.
-+ *
-+ * @param dir Only barriers blocking movement in direction dir are checked
-+ * @param x1 X start coordinate of movement vector
-+ * @param y1 Y start coordinate of movement vector
-+ * @param x2 X end coordinate of movement vector
-+ * @param y2 Y end coordinate of movement vector
-+ * @return The barrier nearest to the movement origin that blocks this movement.
-+ */
-+static struct PointerBarrier*
-+barrier_find_nearest(CursorScreenPtr cs, int dir,
-+ int x1, int y1, int x2, int y2)
-+{
-+ struct PointerBarrierClient *c;
-+ struct PointerBarrier *nearest = NULL;
-+ double min_distance = INT_MAX; /* can't get higher than that in X anyway */
-+
-+ list_for_each_entry(c, &cs->barriers, entry) {
-+ struct PointerBarrier *b = &c->barrier;
-+ double distance;
-+
-+ if (!barrier_is_blocking_direction(b, dir))
-+ continue;
-+
-+ if (barrier_is_blocking(b, x1, y1, x2, y2, &distance))
-+ {
-+ if (min_distance > distance)
-+ {
-+ min_distance = distance;
-+ nearest = b;
-+ }
-+ }
-+ }
-+
-+ return nearest;
-+}
-+
-+/**
-+ * Clamp to the given barrier given the movement direction specified in dir.
-+ *
-+ * @param barrier The barrier to clamp to
-+ * @param dir The movement direction
-+ * @param[out] x The clamped x coordinate.
-+ * @param[out] y The clamped x coordinate.
-+ */
-+void
-+barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x, int *y)
-+{
-+ if (barrier_is_vertical(barrier))
-+ {
-+ if ((dir & BarrierNegativeX) & ~barrier->directions)
-+ *x = barrier->x1;
-+ if ((dir & BarrierPositiveX) & ~barrier->directions)
-+ *x = barrier->x1 - 1;
-+ }
-+ if (barrier_is_horizontal(barrier))
-+ {
-+ if ((dir & BarrierNegativeY) & ~barrier->directions)
-+ *y = barrier->y1;
-+ if ((dir & BarrierPositiveY) & ~barrier->directions)
-+ *y = barrier->y1 - 1;
-+ }
-+}
-+
-+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 dir;
-+ struct PointerBarrier *nearest = NULL;
-+
-+ /* where are we coming from */
-+ miPointerGetPosition(dev, &ox, &oy);
-+
-+ /* How this works:
-+ * Given the origin and the movement vector, get the nearest barrier
-+ * to the origin that is blocking the movement.
-+ * Clamp to that barrier.
-+ * Then, check from the clamped intersection to the original
-+ * destination, again finding the nearest barrier and clamping.
-+ */
-+ dir = barrier_get_direction(ox, oy, *x, *y);
-+
-+ nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
-+ if (nearest) {
-+ barrier_clamp_to_barrier(nearest, dir, x, y);
-+
-+ if (barrier_is_vertical(nearest)) {
-+ dir &= ~(BarrierNegativeX | BarrierPositiveX);
-+ ox = *x;
-+ } else if (barrier_is_horizontal(nearest)) {
-+ dir &= ~(BarrierNegativeY | BarrierPositiveY);
-+ oy = *y;
-+ }
-+
-+ nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
-+ if (nearest) {
-+ barrier_clamp_to_barrier(nearest, dir, x, y);
-+ }
-+ }
-+ }
-+
-+ if (cs->ConstrainCursorHarder) {
-+ screen->ConstrainCursorHarder = cs->ConstrainCursorHarder;
-+ screen->ConstrainCursorHarder(dev, screen, mode, x, y);
-+ screen->ConstrainCursorHarder = CursorConstrainCursorHarder;
-+ }
-+}
-+
-+static struct PointerBarrierClient *
-+CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client,
-+ xXFixesCreatePointerBarrierReq *stuff)
-+{
-+ CursorScreenPtr cs = GetCursorScreen(screen);
-+ struct PointerBarrierClient *ret = malloc(sizeof(*ret));
-+
-+ if (ret) {
-+ ret->screen = screen;
-+ 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;
-+ 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;
-+}
-+
-+int
-+ProcXFixesCreatePointerBarrier (ClientPtr client)
-+{
-+ int err;
-+ WindowPtr pWin;
-+ struct PointerBarrierClient *barrier;
-+ struct PointerBarrier b;
-+ REQUEST (xXFixesCreatePointerBarrierReq);
-+
-+ REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq);
-+ 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 = CreatePointerBarrierClient(pWin->drawable.pScreen,
-+ client, stuff)))
-+ return BadAlloc;
-+
-+ if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier))
-+ return BadAlloc;
-+
-+ return Success;
-+}
-+
-+int
-+SProcXFixesCreatePointerBarrier (ClientPtr client)
-+{
-+ int n;
-+ REQUEST(xXFixesCreatePointerBarrierReq);
-+
-+ swaps(&stuff->length, n);
-+ REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq);
-+ swapl(&stuff->barrier, n);
-+ swapl(&stuff->window, n);
-+ swaps(&stuff->x1, n);
-+ swaps(&stuff->y1, n);
-+ swaps(&stuff->x2, n);
-+ swaps(&stuff->y2, n);
-+ swapl(&stuff->directions, n);
-+ return ProcXFixesVector[stuff->xfixesReqType](client);
-+}
-+
-+static int
-+CursorFreeBarrier(void *data, XID id)
-+{
-+ struct PointerBarrierClient *b = NULL, *barrier;
-+ ScreenPtr screen;
-+ CursorScreenPtr cs;
-+
-+ barrier = container_of(data, struct PointerBarrierClient, barrier);
-+ screen = barrier->screen;
-+ cs = GetCursorScreen(screen);
-+
-+ /* find and unlink from the screen private */
-+ list_for_each_entry(b, &cs->barriers, entry) {
-+ if (b == barrier) {
-+ list_del(&b->entry);
-+ break;
-+ }
-+ }
-+
-+ free(barrier);
-+ return Success;
-+}
-+
-+int
-+ProcXFixesDestroyPointerBarrier (ClientPtr client)
-+{
-+ int err;
-+ void *barrier;
-+ REQUEST (xXFixesDestroyPointerBarrierReq);
-+
-+ REQUEST_SIZE_MATCH(xXFixesDestroyPointerBarrierReq);
-+
-+ err = dixLookupResourceByType((void **)&barrier, stuff->barrier,
-+ PointerBarrierType, client,
-+ DixDestroyAccess);
-+ if (err != Success) {
-+ client->errorValue = stuff->barrier;
-+ return err;
-+ }
-+
-+ FreeResource(stuff->barrier, RT_NONE);
-+ return Success;
-+}
-+
-+int
-+SProcXFixesDestroyPointerBarrier (ClientPtr client)
-+{
-+ int n;
-+ REQUEST(xXFixesDestroyPointerBarrierReq);
-+
-+ swaps(&stuff->length, n);
-+ REQUEST_SIZE_MATCH(xXFixesDestroyPointerBarrierReq);
-+ swapl(&stuff->barrier, n);
-+ return ProcXFixesVector[stuff->xfixesReqType](client);
-+}
-+
- Bool
- XFixesCursorInit (void)
- {
-@@ -1048,8 +1440,10 @@
- cs = (CursorScreenPtr) calloc(1, sizeof (CursorScreenRec));
- if (!cs)
- return FALSE;
-+ list_init(&cs->barriers);
- Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
- Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
-+ Wrap (cs, pScreen, ConstrainCursorHarder, CursorConstrainCursorHarder);
- cs->pCursorHideCounts = NULL;
- SetCursorScreen (pScreen, cs);
- }
-@@ -1059,7 +1453,10 @@
- "XFixesCursorHideCount");
- CursorWindowType = CreateNewResourceType(CursorFreeWindow,
- "XFixesCursorWindow");
-+ PointerBarrierType = CreateNewResourceType(CursorFreeBarrier,
-+ "XFixesPointerBarrier");
-
-- return CursorClientType && CursorHideCountType && CursorWindowType;
-+ return CursorClientType && CursorHideCountType && CursorWindowType &&
-+ PointerBarrierType;
- }
-
-Index: xorg-server/xfixes/xfixes.c
-===================================================================
---- xorg-server.orig/xfixes/xfixes.c 2011-08-24 12:52:44.355647127 +0300
-+++ xorg-server/xfixes/xfixes.c 2011-08-24 12:56:49.825650624 +0300
-@@ -1,5 +1,6 @@
- /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
-+ * Copyright 2010 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
-@@ -47,10 +48,6 @@
-
- #include "xfixesint.h"
- #include "protocol-versions.h"
--/*
-- * Must use these instead of the constants from xfixeswire.h. They advertise
-- * what we implement, not what the protocol headers define.
-- */
-
- static unsigned char XFixesReqCode;
- int XFixesEventBase;
-@@ -97,11 +94,12 @@
-
- /* Major version controls available requests */
- static const int version_requests[] = {
-- X_XFixesQueryVersion, /* before client sends QueryVersion */
-- X_XFixesGetCursorImage, /* Version 1 */
-- X_XFixesChangeCursorByName, /* Version 2 */
-- X_XFixesExpandRegion, /* Version 3 */
-- X_XFixesShowCursor, /* Version 4 */
-+ X_XFixesQueryVersion, /* before client sends QueryVersion */
-+ X_XFixesGetCursorImage, /* Version 1 */
-+ X_XFixesChangeCursorByName, /* Version 2 */
-+ X_XFixesExpandRegion, /* Version 3 */
-+ X_XFixesShowCursor, /* Version 4 */
-+ X_XFixesDestroyPointerBarrier, /* Version 5 */
- };
-
- #define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0]))
-@@ -142,6 +140,9 @@
- /*************** Version 4 ****************/
- ProcXFixesHideCursor,
- ProcXFixesShowCursor,
-+/*************** Version 5 ****************/
-+ ProcXFixesCreatePointerBarrier,
-+ ProcXFixesDestroyPointerBarrier,
- };
-
- static int
-@@ -205,6 +206,9 @@
- /*************** Version 4 ****************/
- SProcXFixesHideCursor,
- SProcXFixesShowCursor,
-+/*************** Version 5 ****************/
-+ SProcXFixesCreatePointerBarrier,
-+ SProcXFixesDestroyPointerBarrier,
- };
-
- static int
-@@ -260,6 +264,8 @@
- EventSwapVector[XFixesEventBase + XFixesCursorNotify] =
- (EventSwapPtr) SXFixesCursorNotifyEvent;
- SetResourceTypeErrorValue(RegionResType, XFixesErrorBase + BadRegion);
-+ SetResourceTypeErrorValue(PointerBarrierType,
-+ XFixesErrorBase + BadBarrier);
- }
- }
-
-Index: xorg-server/xfixes/xfixes.h
-===================================================================
---- xorg-server.orig/xfixes/xfixes.h 2011-08-24 12:52:44.335647125 +0300
-+++ xorg-server/xfixes/xfixes.h 2011-08-24 12:56:49.825650624 +0300
-@@ -30,6 +30,7 @@
- #include "resource.h"
-
- extern _X_EXPORT RESTYPE RegionResType;
-+extern _X_EXPORT RESTYPE PointerBarrierType;
- extern _X_EXPORT int XFixesErrorBase;
-
- #define VERIFY_REGION(pRegion, rid, client, mode) \
-@@ -51,5 +52,21 @@
- extern _X_EXPORT RegionPtr
- XFixesRegionCopy (RegionPtr pRegion);
-
-+struct PointerBarrier {
-+ CARD16 x1, x2, y1, y2;
-+ CARD32 directions;
-+};
-+
-+
-+extern int
-+barrier_get_direction(int, int, int, int);
-+extern BOOL
-+barrier_is_blocking(const struct PointerBarrier*, int, int, int, int, double*);
-+extern BOOL
-+barrier_is_blocking_direction(const struct PointerBarrier*, int);
-+extern void
-+barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x, int *y);
-+
-+
-
- #endif /* _XFIXES_H_ */
-Index: xorg-server/xfixes/xfixesint.h
-===================================================================
---- xorg-server.orig/xfixes/xfixesint.h 2011-08-24 12:52:44.345647126 +0300
-+++ xorg-server/xfixes/xfixesint.h 2011-08-24 12:56:49.825650624 +0300
-@@ -1,5 +1,6 @@
- /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
-+ * Copyright 2010 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
-@@ -278,6 +279,21 @@
- int
- SProcXFixesShowCursor (ClientPtr client);
-
-+/* Version 5 */
-+
-+int
-+ProcXFixesCreatePointerBarrier (ClientPtr client);
-+
-+int
-+SProcXFixesCreatePointerBarrier (ClientPtr client);
-+
-+int
-+ProcXFixesDestroyPointerBarrier (ClientPtr client);
-+
-+int
-+SProcXFixesDestroyPointerBarrier (ClientPtr client);
-+
-+/* Xinerama */
- extern int (*PanoramiXSaveXFixesVector[XFixesNumberRequests])(ClientPtr);
- void PanoramiXFixesInit (void);
- void PanoramiXFixesReset (void);