From: Keith Packard 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 Find the box within the region which is closest to the point and move there. Signed-off-by: Keith Packard --- 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