[Xquartz-changes] xserver: Branch 'master' - 2 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Thu Apr 19 19:01:49 PDT 2012


Rebased ref, commits from common ancestor:
commit 6570078e269032341070aec6ac5fdf72d6fa3e3f
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu Apr 19 18:48:22 2012 -0700

    XQuartz: Add a hack to better handle clicky wheel scroll mice
    
    We loose information from AppKit being in our way.  Before adopting
    smooth scrolling, we always rounded-up the number of scroll button
    clicks per NSEvent.  Now, the scroll value is accumulated in the
    dix, and clicky scroll wheels with legacy X11 clients are seeing
    an accumulation of error due to so many translations (button press
    to smooth scrolling value in AppKit, passed to the dix, and then
    synthesized into a button press).  This attempts to make the
    situation better.
    
    http://xquartz.macosforge.org/trac/ticket/562
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 3e9f108..9bd91f7 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -1643,6 +1643,17 @@ handle_mouse:
     {
         float deltaX = [e deltaX];
         float deltaY = [e deltaY];
+        CGEventRef cge = [e CGEvent];
+        BOOL isContinuous =
+            CGEventGetIntegerValueField(cge, kCGScrollWheelEventIsContinuous);
+
+        CGEventSourceRef source = CGEventCreateSourceFromEvent(cge);
+        if (source) {
+            double lineWidth = CGEventSourceGetPixelsPerLine(source);
+            CFRelease(source);
+            ErrorF("Pixels Per Line: %lf\n", lineWidth);
+        }
+        
 #if !defined(XPLUGIN_VERSION) || XPLUGIN_VERSION == 0
         /* If we're in the background, we need to send a MotionNotify event
          * first, since we aren't getting them on background mouse motion
@@ -1663,7 +1674,88 @@ handle_mouse:
             deltaY *= -1;
         }
 #endif
-        DarwinSendScrollEvents(deltaX, deltaY);
+        /* This hack is in place to better deal with "clicky" scroll wheels:
+         * http://xquartz.macosforge.org/trac/ticket/562
+         */
+        if (!isContinuous) {
+            CGEventSourceRef source;
+            static NSTimeInterval lastScrollTime = 0.0;
+
+            /* These store how much extra we have already scrolled.
+             * ie, this is how much we ignore on the next event.
+             */
+            static double deficit_x = 0.0;
+            static double deficit_y = 0.0;
+
+            /* If we have past 2 seconds since the last scroll, wipe the slate
+             * clean
+             */
+            if ([e timestamp] - lastScrollTime > 2.0) {
+                deficit_x = deficit_y = 0.0;
+            }
+            lastScrollTime = [e timestamp];
+            
+            /* Scale the scroll value by line height */
+            source = CGEventCreateSourceFromEvent(cge);
+            if (source) {
+                double lineWidth = CGEventSourceGetPixelsPerLine(source);
+                CFRelease(source);
+                
+                deltaX *= lineWidth;
+                deltaY *= lineWidth;
+            }
+            
+            if (deltaX != 0.0) {
+                /* If we changed directions, wipe the slate clean */
+                if ((deficit_x < 0.0 && deltaX > 0.0) ||
+                    (deficit_x > 0.0 && deltaX < 0.0)) {
+                    deficit_x = 0.0;
+                }
+
+                /* Eat up the deficit */
+                if (fabs(deltaX) > fabs(deficit_x)) {
+                    deltaX -= deficit_x;
+                    
+                    if (deltaX > 0.0) {
+                        deficit_x = ceil(deltaX) - deltaX;
+                        deltaX = ceil(deltaX);
+                    } else {
+                        deficit_x = floor(deltaX) - deltaX;
+                        deltaX = floor(deltaX);
+                    }
+                } else {
+                    deficit_x -= deltaX;
+                    deltaX = 0.0;
+                }
+            }
+
+            if (deltaY != 0.0) {
+                /* If we changed directions, wipe the slate clean */
+                if ((deficit_y < 0.0 && deltaY > 0.0) ||
+                    (deficit_y > 0.0 && deltaY < 0.0)) {
+                    deficit_y = 0.0;
+                }
+                
+                /* Eat up the deficit */
+                if (fabs(deltaY) > fabs(deficit_y)) {
+                    deltaY -= deficit_y;
+
+                    if (deltaY > 0.0) {
+                        deficit_y = ceil(deltaY) - deltaY;
+                        deltaY = ceil(deltaY);
+                    } else {
+                        deficit_y = floor(deltaY) - deltaY;
+                        deltaY = floor(deltaY);
+                    }
+                } else {
+                    deficit_y -= deltaY;
+                    deltaY = 0.0;
+                }
+            }
+        }
+
+        if (deltaX != 0.0 || deltaY != 0.0)
+            DarwinSendScrollEvents(deltaX, deltaY);
         break;
     }
 
commit e4148f0bde1b5e12fe34a91effef27283801261b
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu Apr 19 16:38:06 2012 -0700

    XQuartz: darwinPointer now sends both absolute and relative motion
    
    This should hopefully help out wine clients
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index f700c67..3e9f108 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -215,7 +215,8 @@ message_kit_thread(SEL selector, NSObject *arg)
     if (state) {
         if (bgMouseLocationUpdated) {
             DarwinSendPointerEvents(darwinPointer, MotionNotify, 0,
-                                    bgMouseLocation.x, bgMouseLocation.y);
+                                    bgMouseLocation.x, bgMouseLocation.y,
+                                    0.0, 0.0);
             bgMouseLocationUpdated = FALSE;
         }
         DarwinSendDDXEvent(kXquartzActivate, 0);
@@ -1595,14 +1596,16 @@ handle_mouse:
         if (bgMouseLocationUpdated) {
             if (!(ev_type == MotionNotify && ev_button == 0)) {
                 DarwinSendPointerEvents(darwinPointer, MotionNotify, 0,
-                                        location.x, location.y);
+                                        location.x, location.y,
+                                        0.0, 0.0);
             }
             bgMouseLocationUpdated = FALSE;
         }
 
         if (pDev == darwinPointer) {
             DarwinSendPointerEvents(pDev, ev_type, ev_button,
-                                    location.x, location.y);
+                                    location.x, location.y,
+                                    [e deltaX], [e deltaY]);
         } else {
             DarwinSendTabletEvents(pDev, ev_type, ev_button,
                                    location.x, location.y, pressure,
@@ -1647,7 +1650,8 @@ handle_mouse:
         if (!XQuartzServerVisible && noTestExtensions) {
             bgMouseLocationUpdated = FALSE;
             DarwinSendPointerEvents(darwinPointer, MotionNotify, 0,
-                                    location.x, location.y);
+                                    location.x, location.y,
+                                    0.0, 0.0);
         }
 #endif
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c
index 03030ad..ac7f199 100644
--- a/hw/xquartz/darwin.c
+++ b/hw/xquartz/darwin.c
@@ -309,7 +309,7 @@ static int
 DarwinMouseProc(DeviceIntPtr pPointer, int what)
 {
 #define NBUTTONS 3
-#define NAXES    4
+#define NAXES    6
     // 3 buttons: left, middle, right
     CARD8 map[NBUTTONS + 1] = { 0, 1, 2, 3};
     Atom btn_labels[NBUTTONS] = { 0 };
@@ -323,10 +323,12 @@ DarwinMouseProc(DeviceIntPtr pPointer, int what)
         btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
         btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
 
-        axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
-        axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
-        axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
-        axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL);
+        axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
+        axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+        axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+        axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+        axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_WHEEL);
+        axes_labels[5] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_HWHEEL);
 
         // Set button map.
         InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
@@ -334,21 +336,27 @@ DarwinMouseProc(DeviceIntPtr pPointer, int what)
                                 (PtrCtrlProcPtr)NoopDDA,
                                 GetMotionHistorySize(), NAXES,
                                 axes_labels);
-        InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 
+        InitValuatorAxisStruct(pPointer, 0, axes_labels[0],
+                               0, XQUARTZ_VALUATOR_LIMIT,
+                               1, 0, 1, Absolute);
+        InitValuatorAxisStruct(pPointer, 1, axes_labels[1],
+                               0, XQUARTZ_VALUATOR_LIMIT,
+                               1, 0, 1, Absolute);
+        InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 
                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
                                1, 0, 1, Relative);
-        InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 
+        InitValuatorAxisStruct(pPointer, 3, axes_labels[3], 
                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
                                1, 0, 1, Relative);
-        InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 
+        InitValuatorAxisStruct(pPointer, 4, axes_labels[4], 
                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
                                1, 0, 1, Relative);
-        InitValuatorAxisStruct(pPointer, 3, axes_labels[3], 
+        InitValuatorAxisStruct(pPointer, 5, axes_labels[5], 
                                NO_AXIS_LIMITS, NO_AXIS_LIMITS,
                                1, 0, 1, Relative);
 
-        SetScrollValuator(pPointer, 2, SCROLL_TYPE_VERTICAL, -1.0, SCROLL_FLAG_PREFERRED);
-        SetScrollValuator(pPointer, 3, SCROLL_TYPE_HORIZONTAL, -1.0, SCROLL_FLAG_NONE);
+        SetScrollValuator(pPointer, 4, SCROLL_TYPE_VERTICAL, -1.0, SCROLL_FLAG_PREFERRED);
+        SetScrollValuator(pPointer, 5, SCROLL_TYPE_HORIZONTAL, -1.0, SCROLL_FLAG_NONE);
         break;
 
     case DEVICE_ON:
@@ -399,23 +407,24 @@ DarwinTabletProc(DeviceIntPtr pPointer, int what)
                                 axes_labels);
         InitProximityClassDeviceStruct(pPointer);
 
-        InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0,
-                               XQUARTZ_VALUATOR_LIMIT, 1, 0, 1,
-                               Absolute);
-        InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0,
-                               XQUARTZ_VALUATOR_LIMIT, 1, 0, 1,
-                               Absolute);
-        InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0,
-                               XQUARTZ_VALUATOR_LIMIT, 1, 0, 1,
-                               Absolute);
+        InitValuatorAxisStruct(pPointer, 0, axes_labels[0],
+                               0, XQUARTZ_VALUATOR_LIMIT,
+                               1, 0, 1, Absolute);
+        InitValuatorAxisStruct(pPointer, 1, axes_labels[1],
+                               0, XQUARTZ_VALUATOR_LIMIT,
+                               1, 0, 1, Absolute);
+        InitValuatorAxisStruct(pPointer, 2, axes_labels[2],
+                               0, XQUARTZ_VALUATOR_LIMIT,
+                               1, 0, 1, Absolute);
         InitValuatorAxisStruct(pPointer, 3, axes_labels[3],
                                -XQUARTZ_VALUATOR_LIMIT,
-                               XQUARTZ_VALUATOR_LIMIT, 1, 0, 1,
-                               Absolute);
+                               XQUARTZ_VALUATOR_LIMIT,
+                               1, 0, 1, Absolute);
         InitValuatorAxisStruct(pPointer, 4, axes_labels[4],
                                -XQUARTZ_VALUATOR_LIMIT,
-                               XQUARTZ_VALUATOR_LIMIT, 1, 0, 1,
-                               Absolute);
+                               XQUARTZ_VALUATOR_LIMIT,
+                               1, 0, 1, Absolute);
+
         //          pPointer->use = IsXExtensionDevice;
         break;
 
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 25f011b..5dd2cfe 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -74,12 +74,6 @@
 
 #include <IOKit/hidsystem/IOLLEvent.h>
 
-/* Fake button press/release for scroll wheel move. */
-#define SCROLLWHEELUPFAKE    4
-#define SCROLLWHEELDOWNFAKE  5
-#define SCROLLWHEELLEFTFAKE  6
-#define SCROLLWHEELRIGHTFAKE 7
-
 #include <X11/extensions/applewmconst.h>
 #include "applewmExt.h"
 
@@ -497,12 +491,6 @@ DarwinSendTabletEvents(DeviceIntPtr pDev, int ev_type, int ev_button,
     pointer_x -= darwinMainScreenX + screen->x;
     pointer_y -= darwinMainScreenY + screen->y;
 
-    if (pointer_x < 0.0)
-        pointer_x = 0.0;
-
-    if (pointer_y < 0.0)
-        pointer_y = 0.0;
-    
     /* Adjust our pointer location to the [0,1] range */
     pointer_x = pointer_x / (double)screenInfo.width;
     pointer_y = pointer_y / (double)screenInfo.height;
@@ -528,11 +516,13 @@ DarwinSendTabletEvents(DeviceIntPtr pDev, int ev_type, int ev_button,
 
 void
 DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button,
-                        double pointer_x, double pointer_y)
+                        double pointer_x, double pointer_y,
+                        double pointer_dx, double pointer_dy)
 {
     static int darwinFakeMouseButtonDown = 0;
     ScreenPtr screen;
-    ValuatorMask valuators;
+    ValuatorMask valuators, deltaValuators;
+    BOOL sendDelta;
 
     if (!darwinEvents) {
         DEBUG_LOG("%s called before darwinEvents was initialized\n",
@@ -553,7 +543,7 @@ DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button,
             /* We're currently "down" with another button, so release it first */
             DarwinSendPointerEvents(pDev, ButtonRelease,
                                     darwinFakeMouseButtonDown,
-                                    pointer_x, pointer_y);
+                                    pointer_x, pointer_y, 0.0, 0.0);
             darwinFakeMouseButtonDown = 0;
         }
         if (darwin_all_modifier_flags & darwinFakeMouse2Mask) {
@@ -591,22 +581,34 @@ DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button,
     pointer_x -= darwinMainScreenX + screen->x;
     pointer_y -= darwinMainScreenY + screen->y;
 
-    if (pointer_x < 0.0)
-        pointer_x = 0.0;
-
-    if (pointer_y < 0.0)
-        pointer_y = 0.0;
+    /* Adjust our pointer location to the [0,1] range */
+    pointer_x = pointer_x / (double)screenInfo.width;
+    pointer_y = pointer_y / (double)screenInfo.height;
 
     valuator_mask_zero(&valuators);
-    valuator_mask_set_double(&valuators, 0, pointer_x);
-    valuator_mask_set_double(&valuators, 1, pointer_y);
+    valuator_mask_set_double(&valuators, 0, XQUARTZ_VALUATOR_LIMIT * pointer_x);
+    valuator_mask_set_double(&valuators, 1, XQUARTZ_VALUATOR_LIMIT * pointer_y);
+
+    sendDelta = (pointer_dx != 0.0 || pointer_dy != 0.0) &&
+                (ev_type == MotionNotify);
+
+    if (sendDelta) {
+        valuator_mask_zero(&deltaValuators);
+        valuator_mask_set_double(&deltaValuators, 2, pointer_dx);
+        valuator_mask_set_double(&deltaValuators, 3, pointer_dy);
+    }
 
     darwinEvents_lock();
     {
         QueuePointerEvents(pDev, ev_type, ev_button, POINTER_ABSOLUTE,
                            &valuators);
+        if (sendDelta) {
+            QueuePointerEvents(pDev, ev_type, 0, POINTER_RELATIVE,
+                               &deltaValuators);
+        }
+
         DarwinPokeEQ();
-    } darwinEvents_unlock();
+    } darwinEvents_unlock();   
 }
 
 void
@@ -647,8 +649,8 @@ DarwinSendScrollEvents(double scroll_x, double scroll_y) {
     }
 
     valuator_mask_zero(&valuators);
-    valuator_mask_set_double(&valuators, 2, scroll_y);
-    valuator_mask_set_double(&valuators, 3, scroll_x);
+    valuator_mask_set_double(&valuators, 4, scroll_y);
+    valuator_mask_set_double(&valuators, 5, scroll_x);
 
     darwinEvents_lock();
     {
diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h
index 812a5dc..448e730 100644
--- a/hw/xquartz/darwinEvents.h
+++ b/hw/xquartz/darwinEvents.h
@@ -49,7 +49,8 @@ DarwinSendTabletEvents(DeviceIntPtr pDev, int ev_type, int ev_button,
                        double tilt_x, double tilt_y);
 void
 DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button,
-                        double pointer_x, double pointer_y);
+                        double pointer_x, double pointer_y,
+                        double pointer_dx, double pointer_dy);
 void
 DarwinSendKeyboardEvents(int ev_type, int keycode);
 void


More information about the Xquartz-changes mailing list