110 lines
2.7 KiB
Diff
110 lines
2.7 KiB
Diff
From: Keith Packard <keithp@keithp.com>
|
|
Date: Fri Oct 4 16:00:49 2013 -0700
|
|
Subject: [PATCH 1/2]Improved ConfineToShape
|
|
Patch-mainline: to be upstreamed
|
|
Git-commit: 0d0951624db7ae4686b362c7c6307f1ed46c8579
|
|
|
|
References: bnc#62146
|
|
Signed-off-by: Egbert Eich <eich@suse.com>
|
|
|
|
Find the box within the region which is closest to the point and move
|
|
there.
|
|
|
|
Signed-off-by: Keith Packard <keithp@keithp.com>
|
|
---
|
|
dix/events.c | 74 ++++++++++++++++++++++++++++++++++++++++--------------------
|
|
1 file changed, 50 insertions(+), 24 deletions(-)
|
|
|
|
diff --git a/dix/events.c b/dix/events.c
|
|
index efaf91d..5244781 100644
|
|
--- a/dix/events.c
|
|
+++ b/dix/events.c
|
|
@@ -666,37 +666,63 @@ SetCriticalEvent(int event)
|
|
criticalEvents[event >> 3] |= 1 << (event & 7);
|
|
}
|
|
|
|
+static uint32_t
|
|
+ConfineToBox(int x, int y, BoxPtr box, int *px, int *py)
|
|
+{
|
|
+ int dx, dy;
|
|
+
|
|
+ *px = x;
|
|
+ *py = y;
|
|
+
|
|
+ if (*px < box->x1)
|
|
+ *px = box->x1;
|
|
+ else if (*px >= box->x2)
|
|
+ *px = box->x2 - 1;
|
|
+
|
|
+ if (*py < box->y1)
|
|
+ *py = box->y1;
|
|
+ else if (*py >= box->y2)
|
|
+ *py = box->y2 - 1;
|
|
+
|
|
+ dx = x - *px;
|
|
+ if (dx < 0) dx = -dx;
|
|
+ if (dx > 32767)
|
|
+ dx = 32767;
|
|
+ dy = y - *py;
|
|
+ if (dy < 0) dy = -dy;
|
|
+ if (dy > 32767)
|
|
+ dy = 32767;
|
|
+
|
|
+ return (uint32_t) dx * (uint32_t) dx + (uint32_t) dy * (uint32_t) dy;
|
|
+}
|
|
+
|
|
void
|
|
ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py)
|
|
{
|
|
- BoxRec box;
|
|
+ BoxPtr box;
|
|
+ int nbox;
|
|
int x = *px, y = *py;
|
|
- int incx = 1, incy = 1;
|
|
+ int bx, by;
|
|
+ uint32_t box_dist_2;
|
|
+ int best_x = 0, best_y = 0;
|
|
+ uint32_t best_dist_2 = 0;
|
|
+ int i;
|
|
|
|
- if (RegionContainsPoint(shape, x, y, &box))
|
|
+ if (RegionContainsPoint(shape, x, y, NULL))
|
|
return;
|
|
- box = *RegionExtents(shape);
|
|
- /* this is rather crude */
|
|
- do {
|
|
- x += incx;
|
|
- if (x >= box.x2) {
|
|
- incx = -1;
|
|
- x = *px - 1;
|
|
- }
|
|
- else if (x < box.x1) {
|
|
- incx = 1;
|
|
- x = *px;
|
|
- y += incy;
|
|
- if (y >= box.y2) {
|
|
- incy = -1;
|
|
- y = *py - 1;
|
|
- }
|
|
- else if (y < box.y1)
|
|
- return; /* should never get here! */
|
|
+ box = REGION_RECTS(shape);
|
|
+ nbox = REGION_NUM_RECTS(shape);
|
|
+ for (i = 0; i < nbox; i++) {
|
|
+ box_dist_2 = ConfineToBox(x, y, &box[i], &bx, &by);
|
|
+ if (i == 0 || box_dist_2 < best_dist_2) {
|
|
+ best_dist_2 = box_dist_2;
|
|
+ best_x = bx;
|
|
+ best_y = by;
|
|
}
|
|
- } while (!RegionContainsPoint(shape, x, y, &box));
|
|
- *px = x;
|
|
- *py = y;
|
|
+ }
|
|
+
|
|
+ *px = best_x;
|
|
+ *py = best_y;
|
|
}
|
|
|
|
static void
|