[PATCH] dix: make clipping respect subpixels

Simon Thum simon.thum at gmx.de
Mon Jun 15 11:23:18 PDT 2009


Make clipping of coordinates optionally respect subpixels. This is
needed for XI2. The clipping rules intend to avoid enlarging the
screen by one pixel.
---
 dix/getevents.c |   45 ++++++++++++++++++++++++++++++++-------------
 1 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/dix/getevents.c b/dix/getevents.c
index 46e5080..9605af3 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -576,7 +576,7 @@ GetMaximumEventsNum(void) {
  * InitValuatorAxisClassStruct.
  */
 static void
-clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
+clipAxis(DeviceIntPtr pDev, int axisNum, int *val, float* remainder)
 {
     AxisInfoPtr axis = pDev->valuator->axes + axisNum;
     /* InitValuatoraAxisStruct ensures that (min < max). */
@@ -586,12 +586,28 @@ clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
 
     /* If a value range is defined, clip. If not, do nothing */
     if (axis->max_value <= axis->min_value)
-        return;
+	return;
+
+    if (*val < axis->min_value) {
+	*val = axis->min_value;
+	if (remainder)
+	    *remainder = 0.0f;
+	return;
+    }
+    if (*val == axis->min_value && remainder && (*remainder < 0.0f)) {
+	*remainder = 0.0f;
+	return;
+    }
 
-    if (*val < axis->min_value)
-        *val = axis->min_value;
-    if (*val > axis->max_value)
-        *val = axis->max_value;
+    if (*val > axis->max_value) {
+	*val = axis->max_value;
+	if (remainder)
+	    *remainder = 0.0f;
+	return;
+    }
+    if (*val == axis->max_value && remainder && (*remainder > 0.0f)) {
+	*remainder = 0.0f;
+    }
 }
 
 /**
@@ -604,7 +620,8 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
     int i;
 
     for (i = 0; i < num_valuators; i++)
-        clipAxis(pDev, i + first_valuator, &(valuators[i]));
+        clipAxis(pDev, i + first_valuator, &(valuators[i]),
+                 &pDev->last.remainder[i]);
 }
 
 /**
@@ -666,14 +683,15 @@ moveAbsolute(DeviceIntPtr dev, int *x, int *y,
     else
         *y = dev->last.valuators[1];
 
-    clipAxis(dev, 0, x);
-    clipAxis(dev, 1, y);
+    clipAxis(dev, 0, x, &dev->last.remainder[0]);
+    clipAxis(dev, 1, y, &dev->last.remainder[1]);
 
     i = (first > 2) ? 0 : 2;
     for (; i < num; i++)
     {
         dev->last.valuators[i + first] = valuators[i];
-        clipAxis(dev, i, &dev->last.valuators[i + first]);
+        clipAxis(dev, i, &dev->last.valuators[i + first],
+                 &dev->last.remainder[i + first]);
     }
 }
 
@@ -707,8 +725,8 @@ moveRelative(DeviceIntPtr dev, int *x, int *y,
      * co-ord space limit). If it is attached, we need x/y to go over the
      * limits to be able to change screens. */
     if(dev->u.master) {
-        clipAxis(dev, 0, x);
-        clipAxis(dev, 1, y);
+        clipAxis(dev, 0, x, &dev->last.remainder[0]);
+        clipAxis(dev, 1, y, &dev->last.remainder[1]);
     }
 
     /* calc other axes, clip, drop back into valuators */
@@ -716,7 +734,8 @@ moveRelative(DeviceIntPtr dev, int *x, int *y,
     for (; i < num; i++)
     {
         dev->last.valuators[i + first] += valuators[i];
-        clipAxis(dev, i, &dev->last.valuators[i + first]);
+        clipAxis(dev, i, &dev->last.valuators[i + first],
+                 &dev->last.remainder[i + first]);
         valuators[i] = dev->last.valuators[i + first];
     }
 }
-- 
1.6.3.3


--------------080406040009090002070007--


More information about the xorg-devel mailing list