From 7e16dd3628334a5991b6713d778a46c1ce3b8b78 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Sat, 24 Nov 2012 19:39:47 -0500 Subject: [PATCH] barriers: Switch to an explicit hook for barrier constrainment 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 Reviewed-by: Peter Hutterer --- 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 9e43196f6..9c7affd4c 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 2387dbf4a..a5d0462c9 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 f34506326..d1708249f 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) {