[PATCH 03/29] barriers: Switch to an explicit hook for barrier constrainment

Peter Hutterer peter.hutterer at who-t.net
Tue Dec 11 23:18:56 PST 2012


From: "Jasper St. Pierre" <jstpierre at mecheye.net>

Rather than riding on the ConstrainCursorHarder hook, which has
several issues, move to an explicit hook, which will help us with
some RANDR interaction issues.

Signed-off-by: Jasper St. Pierre <jstpierre at mecheye.net>
---
 Xi/xibarriers.c | 56 ++++++++++++++++----------------------------------------
 include/input.h |  5 +++++
 mi/mipointer.c  | 16 ++++++++++++++++
 3 files changed, 37 insertions(+), 40 deletions(-)

diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c
index 9e43196..9c7affd 100644
--- a/Xi/xibarriers.c
+++ b/Xi/xibarriers.c
@@ -74,16 +74,12 @@ struct PointerBarrierClient {
 };
 
 typedef struct _BarrierScreen {
-    CloseScreenProcPtr CloseScreen;
-    ConstrainCursorHarderProcPtr ConstrainCursorHarder;
     struct xorg_list barriers;
 } BarrierScreenRec, *BarrierScreenPtr;
 
 #define GetBarrierScreen(s) ((BarrierScreenPtr)dixLookupPrivate(&(s)->devPrivates, BarrierScreenPrivateKey))
 #define GetBarrierScreenIfSet(s) GetBarrierScreen(s)
 #define SetBarrierScreen(s,p) dixSetPrivate(&(s)->devPrivates, BarrierScreenPrivateKey, p)
-#define Wrap(as,s,elt,func)	(((as)->elt = (s)->elt), (s)->elt = func)
-#define Unwrap(as,s,elt,backup)	(((backup) = (s)->elt), (s)->elt = (as)->elt)
 
 static BOOL
 barrier_is_horizontal(const struct PointerBarrier *barrier)
@@ -306,22 +302,22 @@ barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x,
     }
 }
 
-static void
-BarrierConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
-                             int *x, int *y)
+void
+input_constrain_cursor(DeviceIntPtr dev, ScreenPtr screen,
+                       int current_x, int current_y,
+                       int dest_x, int dest_y,
+                       int *out_x, int *out_y)
 {
+    /* Clamped coordinates here refer to screen edge clamping. */
     BarrierScreenPtr cs = GetBarrierScreen(screen);
+    int x = dest_x,
+        y = dest_y;
 
-    if (!xorg_list_is_empty(&cs->barriers) && !IsFloating(dev) &&
-        mode == Relative) {
-        int ox, oy;
+    if (!xorg_list_is_empty(&cs->barriers) && !IsFloating(dev)) {
         int dir;
         int i;
         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.
@@ -329,32 +325,29 @@ BarrierConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode,
          * 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);
+        dir = barrier_get_direction(current_x, current_y, x, y);
 
 #define MAX_BARRIERS 2
         for (i = 0; i < MAX_BARRIERS; i++) {
-            nearest = barrier_find_nearest(cs, dev, dir, ox, oy, *x, *y);
+            nearest = barrier_find_nearest(cs, dev, dir, current_x, current_y, x, y);
             if (!nearest)
                 break;
 
-            barrier_clamp_to_barrier(nearest, dir, x, y);
+            barrier_clamp_to_barrier(nearest, dir, &x, &y);
 
             if (barrier_is_vertical(nearest)) {
                 dir &= ~(BarrierNegativeX | BarrierPositiveX);
-                ox = *x;
+                current_x = x;
             }
             else if (barrier_is_horizontal(nearest)) {
                 dir &= ~(BarrierNegativeY | BarrierPositiveY);
-                oy = *y;
+                current_y = y;
             }
         }
     }
 
-    if (cs->ConstrainCursorHarder) {
-        screen->ConstrainCursorHarder = cs->ConstrainCursorHarder;
-        screen->ConstrainCursorHarder(dev, screen, mode, x, y);
-        screen->ConstrainCursorHarder = BarrierConstrainCursorHarder;
-    }
+    *out_x = x;
+    *out_y = y;
 }
 
 static int
@@ -493,21 +486,6 @@ XIDestroyPointerBarrier(ClientPtr client,
     return Success;
 }
 
-static Bool
-BarrierCloseScreen(ScreenPtr pScreen)
-{
-    BarrierScreenPtr cs = GetBarrierScreen(pScreen);
-    Bool ret;
-    _X_UNUSED CloseScreenProcPtr close_proc;
-    _X_UNUSED ConstrainCursorHarderProcPtr constrain_proc;
-
-    Unwrap(cs, pScreen, CloseScreen, close_proc);
-    Unwrap(cs, pScreen, ConstrainCursorHarder, constrain_proc);
-    ret = (*pScreen->CloseScreen) (pScreen);
-    free(cs);
-    return ret;
-}
-
 Bool
 XIBarrierInit(void)
 {
@@ -524,8 +502,6 @@ XIBarrierInit(void)
         if (!cs)
             return FALSE;
         xorg_list_init(&cs->barriers);
-        Wrap(cs, pScreen, CloseScreen, BarrierCloseScreen);
-        Wrap(cs, pScreen, ConstrainCursorHarder, BarrierConstrainCursorHarder);
         SetBarrierScreen(pScreen, cs);
     }
 
diff --git a/include/input.h b/include/input.h
index 2387dbf..a5d0462 100644
--- a/include/input.h
+++ b/include/input.h
@@ -678,4 +678,9 @@ extern _X_EXPORT void input_option_set_value(InputOption *opt,
 extern _X_HIDDEN Bool point_on_screen(ScreenPtr pScreen, int x, int y);
 extern _X_HIDDEN void update_desktop_dimensions(void);
 
+extern _X_HIDDEN void input_constrain_cursor(DeviceIntPtr pDev, ScreenPtr screen,
+                                             int current_x, int current_y,
+                                             int dest_x, int dest_y,
+                                             int *out_x, int *out_y);
+
 #endif                          /* INPUT_H */
diff --git a/mi/mipointer.c b/mi/mipointer.c
index f345063..d170824 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -588,6 +588,22 @@ miPointerSetPosition(DeviceIntPtr pDev, int mode, double *screenx,
     x -= pScreen->x;
     y -= pScreen->y;
 
+    if (mode == Relative) {
+        /* coordinates after clamped to a barrier */
+        int constrained_x, constrained_y;
+        int current_x, current_y; /* current position in per-screen coord */
+
+        current_x = MIPOINTER(pDev)->x - pScreen->y;
+        current_y = MIPOINTER(pDev)->y - pScreen->x;
+
+        input_constrain_cursor(pDev, pScreen,
+                               current_x, current_y, x, y,
+                               &constrained_x, &constrained_y);
+
+        x = constrained_x;
+        y = constrained_y;
+    }
+
     if (switch_screen) {
         pScreenPriv = GetScreenPrivate(pScreen);
         if (!pPointer->confined) {
-- 
1.8.0.1



More information about the xorg-devel mailing list