Egbert Eich <[email protected]> writes:

> Hi Keith,
>
> sorry for delaying this. I was occupied with other things and
> therefore wanted to wait for a bigger time window.

Thanks for your review in any case.

>> +static uint32_t
>> +ConfineToBox(int x, int y, BoxPtr box, int *px, int16_t *py)
>
>                                                     ^^^^^^
>    You probably want to use an int here or fix the other types
>    as well. As it is it will produce a big compiler warning.
>    I see your point here, you wanted to make sure that the 
>    distance ^ 2 still fits into an int. But this is already
>    done by clamping dx and dy to 32767.

Yes.

> You probably intended to do:
>
>        nbox = REGION_NUM_RECTS(shape);
>        for (i = 0; i < nbox; i++) {


And yes. Here's an updated version of the patch that also eliminates
three uninitialized variable warnings in the change:

From dca7a53898f419717098af3c22d6ce9ea0821a29 Mon Sep 17 00:00:00 2001
From: Keith Packard <[email protected]>
Date: Fri, 4 Oct 2013 16:00:49 -0700
Subject: [PATCH] Improved ConfineToShape

Find the box within the region which is closest to the point and move
there.

Signed-off-by: Keith Packard <[email protected]>
---
 dix/events.c | 74 ++++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 50 insertions(+), 24 deletions(-)

diff --git a/dix/events.c b/dix/events.c
index f05dada..011f865 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -672,37 +672,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
-- 
1.8.5.3

-- 
[email protected]

Attachment: pgptKFY0TQ8Pb.pgp
Description: PGP signature

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to