2009-08-04 21:52:16 +02:00
|
|
|
Index: dix/events.c
|
|
|
|
===================================================================
|
|
|
|
--- dix/events.c.orig
|
|
|
|
+++ dix/events.c
|
|
|
|
@@ -803,37 +803,80 @@ ConfineToShape(DeviceIntPtr pDev, Region
|
2008-04-03 02:42:46 +02:00
|
|
|
{
|
|
|
|
BoxRec box;
|
|
|
|
int x = *px, y = *py;
|
|
|
|
- int incx = 1, incy = 1;
|
2009-03-02 01:19:45 +01:00
|
|
|
SpritePtr pSprite;
|
2008-04-03 02:42:46 +02:00
|
|
|
+ int nbox;
|
|
|
|
+ BoxPtr pbox;
|
2009-03-02 01:19:45 +01:00
|
|
|
+ int d, min = (~0U >> 1), dx2, dy2, x_r, y_r;
|
|
|
|
|
|
|
|
pSprite = pDev->spriteInfo->sprite;
|
|
|
|
if (POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box))
|
2008-04-03 02:42:46 +02:00
|
|
|
return;
|
2009-03-02 01:19:45 +01:00
|
|
|
- box = *REGION_EXTENTS(pSprite->hot.pScreen, shape);
|
2008-04-03 02:42:46 +02:00
|
|
|
- /* this is rather crude */
|
|
|
|
- do {
|
|
|
|
- x += incx;
|
|
|
|
- if (x >= box.x2)
|
|
|
|
- {
|
|
|
|
- incx = -1;
|
|
|
|
- x = *px - 1;
|
|
|
|
+
|
|
|
|
+ for (nbox = REGION_NUM_RECTS (shape),
|
2009-03-02 01:19:45 +01:00
|
|
|
+ pbox = REGION_RECTS(shape);
|
2008-04-03 02:42:46 +02:00
|
|
|
+ nbox--;
|
|
|
|
+ pbox++)
|
|
|
|
+ {
|
2009-03-02 01:19:45 +01:00
|
|
|
+ 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;
|
|
|
|
+ }
|
|
|
|
+ }
|
2008-04-03 02:42:46 +02:00
|
|
|
}
|
|
|
|
- else if (x < box.x1)
|
|
|
|
- {
|
|
|
|
- incx = 1;
|
|
|
|
- x = *px;
|
|
|
|
- y += incy;
|
|
|
|
- if (y >= box.y2)
|
|
|
|
- {
|
|
|
|
- incy = -1;
|
|
|
|
- y = *py - 1;
|
2009-03-02 01:19:45 +01:00
|
|
|
+ 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;
|
2008-04-03 02:42:46 +02:00
|
|
|
}
|
|
|
|
- else if (y < box.y1)
|
|
|
|
- return; /* should never get here! */
|
|
|
|
}
|
2009-03-02 01:19:45 +01:00
|
|
|
- } while (!POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box));
|
2008-04-03 02:42:46 +02:00
|
|
|
- *px = x;
|
|
|
|
- *py = y;
|
2009-03-02 01:19:45 +01:00
|
|
|
+ }
|
2008-04-03 02:42:46 +02:00
|
|
|
}
|
|
|
|
|
2009-03-02 01:19:45 +01:00
|
|
|
static void
|