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) {