Implementation of ConfineTo

Egbert Eich eich at pdx.freedesktop.org
Fri May 20 09:15:09 PDT 2005


The current implementation of ConfineTo is pretty cheezy.
The cursor often times doesn't jump to the point inside the
region closest to the location of the previous location of
the pointer.
Attached patch will improve this considerably, however it
exposes a lot of the internals of the BoxRec and region internals
on the DIX level. Since there is no other place in DIX that does 
this I'm not sure if this is permitted on this level.

An alternative would be to create a wrapper function for this
and move this code to the mi level. 

Opinions?

Egbert.

-------------- next part --------------
Index: events.c
===================================================================
RCS file: /home/eich/cvs/xc/programs/Xserver/dix/events.c,v
retrieving revision 1.1.1.19
diff -u -r1.1.1.19 events.c
--- events.c	26 Aug 2004 12:09:13 -0000	1.1.1.19
+++ events.c	2 Mar 2005 20:04:13 -0000
@@ -656,35 +656,79 @@
 {
     BoxRec box;
     int x = *px, y = *py;
-    int incx = 1, incy = 1;
-
+    int         nbox;
+    BoxPtr      pbox;
+    int		d, min = (~0U >> 1), dx2, dy2, x_r, y_r;
+    
     if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
 	return;
-    box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
-    /* this is rather crude */
-    do {
-	x += incx;
-	if (x >= box.x2)
-	{
-	    incx = -1;
-	    x = *px - 1;
+
+    for (nbox = REGION_NUM_RECTS (shape),
+	     pbox = REGION_RECTS(shape);
+         nbox--;
+         pbox++)
+    {
+	if (pbox->x1 < x && pbox->x2 > x) {
+	    d = pbox->y1 - y;
+	    if (d >= 0) {
+		d *= d;
+		if (d < min) {
+		    *px = x;
+		    *py = pbox->y1 + 1;
+		    min = d;
+		}
+	    } else {
+		d = pbox->y2 - y; d *= d;
+		if (d < min) {
+		    *px = x;
+		    *py = pbox->y2 - 1;
+		    min = d;
+		}
+	    }
 	}
-	else if (x < box.x1)
-	{
-	    incx = 1;
-	    x = *px;
-	    y += incy;
-	    if (y >= box.y2)
-	    {
-		incy = -1;
-		y = *py - 1;
+	else if (pbox->y1 < y && pbox->y2 > y) {
+	    d = pbox->x1 - x;
+	    if (d >= 0) {
+		d *= d;
+		if (d < min) {
+		    *px = pbox->x1 + 1;
+		    *py = y;
+		    min = d;
+		}
+	    } else {
+		d = pbox->x2 - x; d *= d;		
+		if (d < min) {
+		    *px = pbox->x2 - 1;
+		    *py = y;
+		    min = d;
+		}
+	    }
+	    
+	} else {
+	    dx2 = pbox->x1 - x; 
+	    if (dx2 >= 0) {
+		dx2 *= dx2;
+		x_r = pbox->x1 + 1;
+	    } else {
+		dx2 = pbox->x2 - x; dx2 *= dx2;
+		x_r = pbox->x2 - 1;
+	    }
+	    dy2 = pbox->y1 - y; 
+	    if (dy2 >= 0) {
+		dy2 *= dy2;
+		y_r = pbox->y1 + 1;
+	    } else {
+		dy2 = pbox->y2 - y; dy2 *= dy2;
+		y_r = pbox->y2 - 1;
+	    }
+	    if ((d = dx2 + dy2) < min) {
+		*px = x_r;
+		*py = y_r;
+		min = d;
 	    }
-	    else if (y < box.y1)
-		return; /* should never get here! */
 	}
-    } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
-    *px = x;
-    *py = y;
+    }
+    
 }
 #endif
 


More information about the xorg-arch mailing list