[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