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

Jeremy Huddleston jeremyhu at freedesktop.org
Sat Feb 9 20:35:11 PST 2013


 Xext/xtest.c                           |   17 +-
 Xi/exevents.c                          |   40 +-----
 config/udev.c                          |    2 
 dix/devices.c                          |   46 ++++++-
 dix/events.c                           |   27 ++--
 dix/getevents.c                        |   83 +++++++++++--
 dix/ptrveloc.c                         |   40 +++---
 dix/touch.c                            |   38 +++---
 hw/dmx/config/xdmxconfig.c             |    3 
 hw/xfree86/common/xf86DGA.c            |   10 +
 hw/xfree86/common/xf86Events.c         |   10 -
 hw/xfree86/common/xf86Module.h         |    2 
 hw/xfree86/common/xf86Option.c         |    2 
 hw/xfree86/modes/xf86Crtc.c            |   15 +-
 hw/xfree86/os-support/linux/lnx_acpi.c |    9 -
 hw/xquartz/GL/capabilities.c           |    4 
 hw/xwin/winSetAppUserModelID.c         |    1 
 hw/xwin/winblock.c                     |   32 ++---
 hw/xwin/winconfig.c                    |    2 
 hw/xwin/winglobals.h                   |    4 
 hw/xwin/winkeybd.c                     |    8 -
 hw/xwin/winmultiwindowwm.c             |  115 ++++++++++++++++--
 hw/xwin/winmultiwindowwndproc.c        |   61 ++++------
 hw/xwin/wintrayicon.c                  |    2 
 hw/xwin/winwakeup.c                    |    4 
 hw/xwin/winwindow.h                    |    1 
 include/dixstruct.h                    |   12 -
 include/input.h                        |    7 -
 include/inputstr.h                     |   30 ++--
 include/list.h                         |    2 
 include/misc.h                         |    1 
 include/protocol-versions.h            |    4 
 include/xwin-config.h.in               |    3 
 mi/mieq.c                              |    6 
 os/log.c                               |   21 ++-
 os/utils.c                             |   32 +++++
 randr/randrstr.h                       |    2 
 render/animcur.c                       |    3 
 test/signal-logging.c                  |  200 ++++++++++++++++-----------------
 test/xi2/protocol-xiwarppointer.c      |    2 
 xkb/xkbActions.c                       |  147 ++++++++++++++----------
 xkb/xkbUtils.c                         |   10 +
 42 files changed, 670 insertions(+), 390 deletions(-)

New commits:
commit f09da85558f816c8d6c72bc2f986aba598ca517a
Author: Jeremy Huddleston Sequoia <jeremyhu at apple.com>
Date:   Sat Feb 9 20:34:33 2013 -0800

    XQuartz: Ensure <dix-config.h> is included in capabilities.c
    
    Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu at apple.com>

diff --git a/hw/xquartz/GL/capabilities.c b/hw/xquartz/GL/capabilities.c
index 4702595..5573629 100644
--- a/hw/xquartz/GL/capabilities.c
+++ b/hw/xquartz/GL/capabilities.c
@@ -20,6 +20,10 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
commit c1602d1c17967bdd4db9db19b3a9c0dfca6a58aa
Author: Dave Airlie <airlied at gmail.com>
Date:   Tue Feb 5 07:46:06 2013 -0800

    randr: bump advertised RandR version to 1.4
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
    Tested-by: Aaron Plattner <aplattner at nvidia.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index 10f5117..5ceaeb0 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -65,7 +65,7 @@
 
 /* RandR */
 #define SERVER_RANDR_MAJOR_VERSION		1
-#define SERVER_RANDR_MINOR_VERSION		3
+#define SERVER_RANDR_MINOR_VERSION		4
 
 /* Record */
 #define SERVER_RECORD_MAJOR_VERSION		1
diff --git a/randr/randrstr.h b/randr/randrstr.h
index a16302f..f52d0f2 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -57,7 +57,7 @@
 #define RANDR_13_INTERFACE 1    /* requires RANDR_12_INTERFACE */
 #define RANDR_GET_CRTC_INTERFACE 1
 
-#define RANDR_INTERFACE_VERSION 0x0103
+#define RANDR_INTERFACE_VERSION 0x0104
 
 typedef XID RRMode;
 typedef XID RROutput;
commit 9f79e93b6b3416055d08a0e8f9f16d5fd0649e36
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jan 30 03:20:07 2013 +0000

    Short-cut the input device cleanup process during AbortServer()
    
    If we're about to abort, we're already in the signal handler and cannot call
    down to the default device cleanup routines (which reset, free, alloc, and
    do a bunch of other things).
    
    Add a new DEVICE_ABORT mode to signal a driver's DeviceProc that it must
    reset the hardware if needed but do nothing else. An actual HW reset is only
    required for some drivers dealing with the HW directly.
    
    This is largely backwards-compatible, hence the input ABI minor bump only.
    
    Drivers we care about either return BadValue on a mode that's not
    DEVICE_{INIT|ON|OFF|CLOSE} or print an error and return BadValue. Exception
    here is vmmouse, which currently ignores it and would not reset anything.
    This should be fixed if the reset is required.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/devices.c b/dix/devices.c
index 530f15d..be236dd 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1056,6 +1056,25 @@ CloseDownDevices(void)
 }
 
 /**
+ * Signal all devices that we're in the process of aborting.
+ * This function is called from a signal handler.
+ */
+void
+AbortDevices(void)
+{
+    DeviceIntPtr dev;
+    nt_list_for_each_entry(dev, inputInfo.devices, next) {
+        if (!IsMaster(dev))
+            (*dev->deviceProc) (dev, DEVICE_ABORT);
+    }
+
+    nt_list_for_each_entry(dev, inputInfo.off_devices, next) {
+        if (!IsMaster(dev))
+            (*dev->deviceProc) (dev, DEVICE_ABORT);
+    }
+}
+
+/**
  * Remove the cursor sprite for all devices. This needs to be done before any
  * resources are freed or any device is deleted.
  */
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index e545c14..1393427 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -81,7 +81,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(14, 1)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(19, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(19, 1)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(7, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
diff --git a/include/input.h b/include/input.h
index 7b5ab94..5c65597 100644
--- a/include/input.h
+++ b/include/input.h
@@ -62,6 +62,7 @@ SOFTWARE.
 #define DEVICE_ON	1
 #define DEVICE_OFF	2
 #define DEVICE_CLOSE	3
+#define DEVICE_ABORT	4
 
 #define POINTER_RELATIVE	(1 << 1)
 #define POINTER_ABSOLUTE	(1 << 2)
@@ -269,6 +270,7 @@ extern void DisableAllDevices(void);
 extern int InitAndStartDevices(void);
 
 extern void CloseDownDevices(void);
+extern void AbortDevices(void);
 
 extern void UndisplayDevices(void);
 
diff --git a/os/log.c b/os/log.c
index 7b5c9ee..2697ace 100644
--- a/os/log.c
+++ b/os/log.c
@@ -663,7 +663,7 @@ AbortServer(void)
 #endif
     CloseWellKnownConnections();
     OsCleanup(TRUE);
-    CloseDownDevices();
+    AbortDevices();
     AbortDDX(EXIT_ERR_ABORT);
     fflush(stderr);
     if (CoreDump)
commit b58221f9da8c549d979215271359c6cd88b5568a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 8 14:52:02 2013 +1000

    dix: support the transformation matrix for relative devices.
    
    The transformation matrix we previously stored was a scaled matrix based on
    the axis ranges of the device. For relative movements, the scaling is not
    required (or desired).
    
    Store two separate matrices, one as requested by the client, one as the
    product of [scale . matrix . inv_scale]. Depending on the type of movement,
    apply the respective matrix.
    
    For relative movements, also drop the translation component since it doesn't
    really make sense to use that bit.
    
    Input ABI 19
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/devices.c b/dix/devices.c
index 172fc04..530f15d 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -93,9 +93,10 @@ SOFTWARE.
 static void RecalculateMasterButtons(DeviceIntPtr slave);
 
 static void
-DeviceSetTransform(DeviceIntPtr dev, float *transform)
+DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
 {
     struct pixman_f_transform scale;
+    struct pixman_f_transform transform;
     double sx, sy;
     int x, y;
 
@@ -122,16 +123,21 @@ DeviceSetTransform(DeviceIntPtr dev, float *transform)
     /* transform */
     for (y = 0; y < 3; y++)
         for (x = 0; x < 3; x++)
-            dev->transform.m[y][x] = *transform++;
+            transform.m[y][x] = *transform_data++;
 
-    pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
+    pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &transform);
 
     /* scale */
     pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
     scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
     scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
 
-    pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
+    pixman_f_transform_multiply(&dev->scale_and_transform, &dev->scale_and_transform, &scale);
+
+    /* remove translation component for relative movements */
+    dev->relative_transform = transform;
+    dev->relative_transform.m[0][2] = 0;
+    dev->relative_transform.m[1][2] = 0;
 }
 
 /**
@@ -308,9 +314,10 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
     /* unity matrix */
     memset(transform, 0, sizeof(transform));
     transform[0] = transform[4] = transform[8] = 1.0f;
-    dev->transform.m[0][0] = 1.0;
-    dev->transform.m[1][1] = 1.0;
-    dev->transform.m[2][2] = 1.0;
+    dev->relative_transform.m[0][0] = 1.0;
+    dev->relative_transform.m[1][1] = 1.0;
+    dev->relative_transform.m[2][2] = 1.0;
+    dev->scale_and_transform = dev->relative_transform;
 
     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
                            XIGetKnownProperty(XATOM_FLOAT), 32,
diff --git a/dix/getevents.c b/dix/getevents.c
index 7cc8d8c..a4f192c 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1202,6 +1202,27 @@ transform(struct pixman_f_transform *m, double *x, double *y)
     *y = p.v[1];
 }
 
+static void
+transformRelative(DeviceIntPtr dev, ValuatorMask *mask)
+{
+    double x = 0, y = 0;
+
+    valuator_mask_fetch_double(mask, 0, &x);
+    valuator_mask_fetch_double(mask, 1, &y);
+
+    transform(&dev->relative_transform, &x, &y);
+
+    if (x)
+        valuator_mask_set_double(mask, 0, x);
+    else
+        valuator_mask_unset(mask, 0);
+
+    if (y)
+        valuator_mask_set_double(mask, 1, y);
+    else
+        valuator_mask_unset(mask, 1);
+}
+
 /**
  * Apply the device's transformation matrix to the valuator mask and replace
  * the scaled values in mask. This transformation only applies to valuators
@@ -1229,7 +1250,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
         ox = dev->last.valuators[0];
         oy = dev->last.valuators[1];
 
-        pixman_f_transform_invert(&invert, &dev->transform);
+        pixman_f_transform_invert(&invert, &dev->scale_and_transform);
         transform(&invert, &ox, &oy);
 
         x = ox;
@@ -1242,7 +1263,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
     if (valuator_mask_isset(mask, 1))
         oy = y = valuator_mask_get_double(mask, 1);
 
-    transform(&dev->transform, &x, &y);
+    transform(&dev->scale_and_transform, &x, &y);
 
     if (valuator_mask_isset(mask, 0) || ox != x)
         valuator_mask_set_double(mask, 0, x);
@@ -1403,6 +1424,8 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
             set_raw_valuators(raw, &mask, raw->valuators.data);
     }
     else {
+        transformRelative(pDev, &mask);
+
         if (flags & POINTER_ACCELERATE)
             accelPointer(pDev, &mask, ms);
         if ((flags & POINTER_NORAW) == 0)
diff --git a/include/inputstr.h b/include/inputstr.h
index 48a29be..de96fae 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -588,8 +588,12 @@ typedef struct _DeviceIntRec {
         XIPropertyHandlerPtr handlers;  /* NULL-terminated */
     } properties;
 
-    /* coordinate transformation matrix for absolute input devices */
-    struct pixman_f_transform transform;
+    /* coordinate transformation matrix for relative movement. Matrix with
+     * the translation component dropped */
+    struct pixman_f_transform relative_transform;
+    /* scale matrix for absolute devices, this is the combined matrix of
+       [1/scale] . [transform] . [scale]. See DeviceSetTransform */
+    struct pixman_f_transform scale_and_transform;
 
     /* XTest related master device id */
     int xtest_master_id;
commit b173eb2ae3349c557db1ff9e424fa540b8289bb2
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Feb 8 08:57:43 2013 -0800

    os: Round fraction in pnprintf %f format
    
    Truncating the fraction part leads to a test failure where -1203.30 is
    printed as -1203.29. Round this to the nearest value instead by adding
    0.5 before converting to an integer
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/utils.c b/os/utils.c
index 3ba6499..60e828e 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1999,7 +1999,7 @@ FormatDouble(double dbl, char *string)
     int slen = 0;
     uint64_t frac;
 
-    frac = (dbl > 0 ? dbl : -dbl) * 100.0;
+    frac = (dbl > 0 ? dbl : -dbl) * 100.0 + 0.5;
     frac %= 100;
 
     /* write decimal part to string */
commit 509b3c3dc82e7abce1900d5e1cddd90f23be5a87
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Feb 6 14:07:22 2013 +0100

    dix: Set focus field on XI2 crossing events
    
    Set on DeviceEnterLeaveEvent() the xXIEnterEvent->focus field
    similarly to how the CoreEnterLeaveEvent() function above does
    for core events.
    
    This fixes bug https://bugzilla.gnome.org/show_bug.cgi?id=677329
    reported to GTK+, where focus handling on window managers with
    sloppy focus or no window manager present was broken due to this
    field being always set to FALSE.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index f72cdc7..2682ecd 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4569,6 +4569,7 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
 {
     GrabPtr grab = mouse->deviceGrab.grab;
     xXIEnterEvent *event;
+    WindowPtr focus;
     int filter;
     int btlen, len, i;
     DeviceIntPtr kbd;
@@ -4610,6 +4611,11 @@ DeviceEnterLeaveEvent(DeviceIntPtr mouse,
         event->group.locked_group = kbd->key->xkbInfo->state.locked_group;
     }
 
+    focus = (kbd) ? kbd->focus->win : None;
+    if ((focus != NoneWin) &&
+        ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin)))
+        event->focus = TRUE;
+
     FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin,
                          None, FALSE);
 
commit 3e4be4033aed78b2bb3a18d51f0963989efd1af3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 25 11:47:32 2013 +1000

    dix: when shutting down slave devices, shut down xtest devices last
    
    XTest devices are the first ones in the list, being initialised together
    with the master devices. If we disable the devices in-order and a device has
    a button down when being disabled, the XTest device is checked for a
    required button release (xkbAccessX.c's ProcessPointerEvent). This fails if
    the device is already NULL.
    
    Instead of putting the check there, disable the devices in the reverse order
    they are initialised. Disable physical slaves first, then xtest devices,
    then the master devices.
    
    Testcase: shut down server with a button still held down on a physical
    device
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/devices.c b/dix/devices.c
index 3c7d480..172fc04 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -516,6 +516,12 @@ DisableAllDevices(void)
 {
     DeviceIntPtr dev, tmp;
 
+    /* Disable slave devices first, excluding XTest devices */
+    nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
+        if (!IsXTestDevice(dev, NULL) && !IsMaster(dev))
+            DisableDevice(dev, FALSE);
+    }
+    /* Disable XTest devices */
     nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
         if (!IsMaster(dev))
             DisableDevice(dev, FALSE);
commit 0d5bb882600ee7734af034fbea935a79d21d1e70
Merge: b33fcb1 61a99af
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 8 14:10:52 2013 +1000

    Merge branch 'ptraccel-fixes' into for-keith

commit 61a99aff9d33728a0b67920254d2d4d79f80cf39
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 14:22:07 2013 +1000

    dix: pre-scale relative events from abs devices to desktop ratio (#31636)
    
    Absolute devices may send relative events depending on the mode (synaptics
    by default, wacom per option). The relative events are added to the previous
    position, converted into device coordinates and then scaled into desktop
    coordinates for pointer movement.
    
    Because the device range must be mapped into the desktop coordinate range,
    this results in uneven scaling depending dimensions, e.g. on a setup with
    width == 2 * height, a relative movement of 10/10 in device coordinates
    results in a cursor movement of 20/10 (+ acceleration)
    
    Other commonly user-visible results:
    * the touchpad changing acceleration once an external monitor as added.
    * drawing a circle on a wacom tablet in relative mode gives an ellipsis in
      the same ratio as the desktop dimensions.
    
    Solution: pre-scale the incoming relative x/y coordinates by width/height
    ratio of the total desktop size. Then add them to the previous
    coordinates and scale back with the previous mapping, which will undo the
    pre-scaling and give us the right movement.
    
    X.Org Bug 31636 <http://bugs.freedesktop.org/show_bug.cgi?id=31636>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index a1e1938..5100607 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -776,11 +776,33 @@ add_to_scroll_valuator(DeviceIntPtr dev, ValuatorMask *mask, int valuator, doubl
  * @param[in,out] mask Valuator data for this event, modified in-place.
  */
 static void
-moveRelative(DeviceIntPtr dev, ValuatorMask *mask)
+moveRelative(DeviceIntPtr dev, int flags, ValuatorMask *mask)
 {
     int i;
     Bool clip_xy = IsMaster(dev) || !IsFloating(dev);
 
+    /* for abs devices in relative mode, we've just scaled wrong, since we
+       mapped the device's shape into the screen shape. Undo this. */
+    if ((flags & POINTER_ABSOLUTE) == 0 && dev->valuator &&
+        dev->valuator->axes[0].min_value < dev->valuator->axes[0].max_value) {
+
+        double ratio = 1.0 * screenInfo.width/screenInfo.height;
+
+        if (ratio > 1.0) {
+            double y;
+            if (valuator_mask_fetch_double(mask, 1, &y)) {
+                y *= ratio;
+                valuator_mask_set_double(mask, 1, y);
+            }
+        } else {
+            double x;
+            if (valuator_mask_fetch_double(mask, 0, &x)) {
+                x *= ratio;
+                valuator_mask_set_double(mask, 0, x);
+            }
+        }
+    }
+
     /* calc other axes, clip, drop back into valuators */
     for (i = 0; i < valuator_mask_size(mask); i++) {
         double val = dev->last.valuators[i];
@@ -1380,7 +1402,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
         if ((flags & POINTER_NORAW) == 0)
             set_raw_valuators(raw, &mask, raw->valuators.data);
 
-        moveRelative(pDev, &mask);
+        moveRelative(pDev, flags, &mask);
     }
 
     /* valuators are in device coordinate system in absolute coordinates */
commit a6ba2b79ae8ad0fdee3f208d5e030b012df48785
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 08:53:24 2013 +1000

    dix: unify prefix for ptraccel debugging in DebugAccelF macro
    
    If we're already using our own custom macro, might as well use it properly.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index b6d2dae..d6fef9c 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -77,7 +77,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr,
 /*#define PTRACCEL_DEBUGGING*/
 
 #ifdef PTRACCEL_DEBUGGING
-#define DebugAccelF ErrorFSigSafe
+#define DebugAccelF(...) ErrorFSigSafe("dix/ptraccel: " __VA_ARGS__)
 #else
 #define DebugAccelF(...)        /* */
 #endif
@@ -421,7 +421,7 @@ void
 InitTrackers(DeviceVelocityPtr vel, int ntracker)
 {
     if (ntracker < 1) {
-        ErrorF("(dix ptracc) invalid number of trackers\n");
+        ErrorF("invalid number of trackers\n");
         return;
     }
     free(vel->tracker);
@@ -566,7 +566,7 @@ FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
     vel->tracker[n].dy = 0.0;
     vel->tracker[n].time = cur_t;
     vel->tracker[n].dir = GetDirection(dx, dy);
-    DebugAccelF("(dix prtacc) motion [dx: %f dy: %f dir:%d diff: %d]\n",
+    DebugAccelF("motion [dx: %f dy: %f dir:%d diff: %d]\n",
                 dx, dy, vel->tracker[n].dir,
                 cur_t - vel->tracker[vel->cur_tracker].time);
     vel->cur_tracker = n;
@@ -614,7 +614,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
 
         /* bail out if data is too old and protect from overrun */
         if (age_ms >= vel->reset_time || age_ms < 0) {
-            DebugAccelF("(dix prtacc) query: tracker too old (reset after %d, age is %d)\n",
+            DebugAccelF("query: tracker too old (reset after %d, age is %d)\n",
                         vel->reset_time, age_ms);
             break;
         }
@@ -627,7 +627,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
          */
         dir &= tracker->dir;
         if (dir == 0) {         /* we've changed octant of movement (e.g. NE → NW) */
-            DebugAccelF("(dix prtacc) query: no longer linear\n");
+            DebugAccelF("query: no longer linear\n");
             /* instead of breaking it we might also inspect the partition after,
              * but actual improvement with this is probably rare. */
             break;
@@ -648,7 +648,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
                 velocity_diff / (initial_velocity + tracker_velocity) >=
                 vel->max_rel_diff) {
                 /* we're not in range, quit - it won't get better. */
-                DebugAccelF("(dix prtacc) query: tracker too different:"
+                DebugAccelF("query: tracker too different:"
                             " old %2.2f initial %2.2f diff: %2.2f\n",
                             tracker_velocity, initial_velocity, velocity_diff);
                 break;
@@ -661,14 +661,14 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
         }
     }
     if (offset == vel->num_tracker) {
-        DebugAccelF("(dix prtacc) query: last tracker in effect\n");
+        DebugAccelF("query: last tracker in effect\n");
         used_offset = vel->num_tracker - 1;
     }
     if (used_offset >= 0) {
 #ifdef PTRACCEL_DEBUGGING
         MotionTracker *tracker = TRACKER(vel, used_offset);
 
-        DebugAccelF("(dix prtacc) result: offset %i [dx: %f dy: %f diff: %i]\n",
+        DebugAccelF("result: offset %i [dx: %f dy: %f diff: %i]\n",
                     used_offset, tracker->dx, tracker->dy,
                     cur_t - tracker->time);
 #endif
@@ -694,6 +694,8 @@ ProcessVelocityData2D(DeviceVelocityPtr vel, double dx, double dy, int time)
 
     velocity = QueryTrackers(vel, time);
 
+    DebugAccelF("velocity is %f\n", velocity);
+
     vel->velocity = velocity;
     return velocity == 0;
 }
@@ -769,7 +771,7 @@ ComputeAcceleration(DeviceIntPtr dev,
     double result;
 
     if (vel->velocity <= 0) {
-        DebugAccelF("(dix ptracc) profile skipped\n");
+        DebugAccelF("profile skipped\n");
         /*
          * If we have no idea about device velocity, don't pretend it.
          */
@@ -793,13 +795,13 @@ ComputeAcceleration(DeviceIntPtr dev,
                                             threshold,
                                             acc);
         result /= 6.0f;
-        DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
+        DebugAccelF("profile average [%.2f ... %.2f] is %.3f\n",
                     vel->velocity, vel->last_velocity, result);
     }
     else {
         result = BasicComputeAcceleration(dev, vel,
                                           vel->velocity, threshold, acc);
-        DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
+        DebugAccelF("profile sample [%.2f] is %.3f\n",
                     vel->velocity, result);
     }
 
@@ -1111,6 +1113,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
                                        (double) dev->ptrfeed->ctrl.num /
                                        (double) dev->ptrfeed->ctrl.den);
 
+            DebugAccelF("mult is %f\n", mult);
             if (mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
                 if (mult > 1.0f && soften)
                     ApplySoftening(velocitydata, &dx, &dy);
commit 0d7d79406011169ad95e23c6e937f6d15a5ec3cc
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 08:52:08 2013 +1000

    dix: use BUG_RETURN_VAL for an error message
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 6994bd5..b6d2dae 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -1051,11 +1051,8 @@ SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel,
 DeviceVelocityPtr
 GetDevicePredictableAccelData(DeviceIntPtr dev)
 {
-    /*sanity check */
-    if (!dev) {
-        ErrorF("[dix] accel: DeviceIntPtr was NULL");
-        return NULL;
-    }
+    BUG_RETURN_VAL(!dev, NULL);
+
     if (dev->valuator &&
         dev->valuator->accelScheme.AccelSchemeProc ==
         acceleratePointerPredictable &&
commit a0c38ea6cbad61edcfefff0e5dd6330edb706f13
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 08:49:15 2013 +1000

    dix: add some more info to a ptraccel debug msg
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index b95f194..6994bd5 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -614,7 +614,8 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
 
         /* bail out if data is too old and protect from overrun */
         if (age_ms >= vel->reset_time || age_ms < 0) {
-            DebugAccelF("(dix prtacc) query: tracker too old\n");
+            DebugAccelF("(dix prtacc) query: tracker too old (reset after %d, age is %d)\n",
+                        vel->reset_time, age_ms);
             break;
         }
 
commit 95125a7c0cbbbae40216a0497acdd863ddc645ed
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 10 13:19:27 2013 +1000

    dix: fix ptraccel debugging printfs
    
    This is mostly sigsafe code, so use sigsave printf. And update some fields
    to double that used to be int.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index c7994b0..b95f194 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -77,7 +77,7 @@ DeletePredictableAccelerationProperties(DeviceIntPtr,
 /*#define PTRACCEL_DEBUGGING*/
 
 #ifdef PTRACCEL_DEBUGGING
-#define DebugAccelF ErrorF
+#define DebugAccelF ErrorFSigSafe
 #else
 #define DebugAccelF(...)        /* */
 #endif
@@ -566,7 +566,7 @@ FeedTrackers(DeviceVelocityPtr vel, double dx, double dy, int cur_t)
     vel->tracker[n].dy = 0.0;
     vel->tracker[n].time = cur_t;
     vel->tracker[n].dir = GetDirection(dx, dy);
-    DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
+    DebugAccelF("(dix prtacc) motion [dx: %f dy: %f dir:%d diff: %d]\n",
                 dx, dy, vel->tracker[n].dir,
                 cur_t - vel->tracker[vel->cur_tracker].time);
     vel->cur_tracker = n;
@@ -667,7 +667,7 @@ QueryTrackers(DeviceVelocityPtr vel, int cur_t)
 #ifdef PTRACCEL_DEBUGGING
         MotionTracker *tracker = TRACKER(vel, used_offset);
 
-        DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
+        DebugAccelF("(dix prtacc) result: offset %i [dx: %f dy: %f diff: %i]\n",
                     used_offset, tracker->dx, tracker->dy,
                     cur_t - tracker->time);
 #endif
@@ -799,7 +799,7 @@ ComputeAcceleration(DeviceIntPtr dev,
         result = BasicComputeAcceleration(dev, vel,
                                           vel->velocity, threshold, acc);
         DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
-                    vel->velocity, res);
+                    vel->velocity, result);
     }
 
     return result;
@@ -1122,8 +1122,7 @@ acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask *val, CARD32 evtime)
                     valuator_mask_set_double(val, 0, mult * dx);
                 if (dy != 0.0)
                     valuator_mask_set_double(val, 1, mult * dy);
-                DebugAccelF("pos (%i | %i) delta x:%.3f y:%.3f\n", mult * dx,
-                            mult * dy);
+                DebugAccelF("delta x:%.3f y:%.3f\n", mult * dx, mult * dy);
             }
         }
     }
commit b33fcb149710a28fd8767b2307a97bf367de695e
Author: Andreas Wettstein <wettstein509 at solnet.ch>
Date:   Tue Jan 29 21:49:20 2013 +0100

    xkb: Fix repeat behaviour of redirect and message actions
    
    The redirect and the message action filter functions implicitly assumed that
    when they receive an event for the same keycode they were activated for, that
    this is the a release of the key that activated the filter.  This is not true
    if the key autorepeats.  Due to the incorrect assumption, the effective key
    repeat rate was effectively halved.
    
    Signed-off-by: Andreas Wettstein <wettstein509 at solnet.ch>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 1adb389..416de92 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -747,6 +747,15 @@ _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
     XkbMessageAction *pMsg;
     DeviceIntPtr kbd;
 
+    if ((filter->keycode != 0) && (filter->keycode != keycode))
+	return 1;
+
+    /* This can happen if the key repeats, and the state (modifiers or group)
+       changes meanwhile. */
+    if ((filter->keycode == keycode) && pAction &&
+	(pAction->type != XkbSA_ActionMessage))
+	return 1;
+
     kbd = xkbi->device;
     if (filter->keycode == 0) { /* initial press */
         pMsg = &pAction->msg;
@@ -774,20 +783,27 @@ _XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
     }
     else if (filter->keycode == keycode) {
         pMsg = &filter->upAction.msg;
-        if (pMsg->flags & XkbSA_MessageOnRelease) {
-            xkbActionMessage msg;
-
-            msg.keycode = keycode;
-            msg.press = 0;
-            msg.keyEventFollows =
-                ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
-            memcpy((char *) msg.message, (char *) pMsg->message,
-                   XkbActionMessageLength);
-            XkbSendActionMessage(kbd, &msg);
+	if (pAction == NULL) {
+	    if (pMsg->flags & XkbSA_MessageOnRelease) {
+		xkbActionMessage msg;
+
+		msg.keycode = keycode;
+		msg.press = 0;
+		msg.keyEventFollows =
+		    ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
+		memcpy((char *) msg.message, (char *) pMsg->message,
+		       XkbActionMessageLength);
+		XkbSendActionMessage(kbd, &msg);
+	    }
+	    filter->keycode = 0;
+	    filter->active = 0;
+	    return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
+	} else if (memcmp(pMsg, pAction, 8) == 0) {
+	    /* Repeat: If we send the same message, avoid multiple messages
+	       on release from piling up. */
+	    filter->keycode = 0;
+	    filter->active = 0;
         }
-        filter->keycode = 0;
-        filter->active = 0;
-        return ((pMsg->flags & XkbSA_MessageGenKeyEvent) != 0);
     }
     return 1;
 }
@@ -803,15 +819,21 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
     ProcessInputProc backupproc;
 
+    if ((filter->keycode != 0) && (filter->keycode != keycode))
+        return 1;
+
+    /* This can happen if the key repeats, and the state (modifiers or group)
+       changes meanwhile. */
+    if ((filter->keycode == keycode) && pAction &&
+	(pAction->type != XkbSA_RedirectKey))
+	return 1;
+
     /* never actually used uninitialised, but gcc isn't smart enough
      * to work that out. */
     memset(&old, 0, sizeof(old));
     memset(&old_prev, 0, sizeof(old_prev));
     memset(&ev, 0, sizeof(ev));
 
-    if ((filter->keycode != 0) && (filter->keycode != keycode))
-        return 1;
-
     GetSpritePosition(xkbi->device, &x, &y);
     ev.header = ET_Internal;
     ev.length = sizeof(DeviceEvent);
@@ -870,49 +892,60 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
             xkbi->state = old;
             xkbi->prev_state = old_prev;
         }
+	return 0;
     }
-    else if (filter->keycode == keycode) {
-
-        ev.type = ET_KeyRelease;
-        ev.detail.key = filter->upAction.redirect.new_key;
-
-        mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
-        mods = XkbSARedirectVMods(&filter->upAction.redirect);
-        if (mask)
-            XkbVirtualModsToReal(xkbi->desc, mask, &mask);
-        if (mods)
-            XkbVirtualModsToReal(xkbi->desc, mods, &mods);
-        mask |= filter->upAction.redirect.mods_mask;
-        mods |= filter->upAction.redirect.mods;
-
-        if (mask || mods) {
-            old = xkbi->state;
-            old_prev = xkbi->prev_state;
-            xkbi->state.base_mods &= ~mask;
-            xkbi->state.base_mods |= (mods & mask);
-            xkbi->state.latched_mods &= ~mask;
-            xkbi->state.latched_mods |= (mods & mask);
-            xkbi->state.locked_mods &= ~mask;
-            xkbi->state.locked_mods |= (mods & mask);
-            XkbComputeDerivedState(xkbi);
-            xkbi->prev_state = xkbi->state;
-        }
-
-        UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
-        xkbi->device->public.processInputProc((InternalEvent *) &ev,
-                                              xkbi->device);
-        COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
-                                     xkbUnwrapProc);
-
-        if (mask || mods) {
-            xkbi->state = old;
-            xkbi->prev_state = old_prev;
-        }
-
-        filter->keycode = 0;
-        filter->active = 0;
+    else {
+	/* If it is a key release, or we redirect to another key, release the
+	   previous new_key.  Otherwise, repeat. */
+	ev.detail.key = filter->upAction.redirect.new_key;
+	if (pAction == NULL ||  ev.detail.key != pAction->redirect.new_key) {
+	    ev.type = ET_KeyRelease;
+	    filter->active = 0;
+	}
+	else {
+	    ev.type = ET_KeyPress;
+	    ev.key_repeat = TRUE;
+	}
+
+	mask = XkbSARedirectVModsMask(&filter->upAction.redirect);
+	mods = XkbSARedirectVMods(&filter->upAction.redirect);
+	if (mask)
+	    XkbVirtualModsToReal(xkbi->desc, mask, &mask);
+	if (mods)
+	    XkbVirtualModsToReal(xkbi->desc, mods, &mods);
+	mask |= filter->upAction.redirect.mods_mask;
+	mods |= filter->upAction.redirect.mods;
+
+	if (mask || mods) {
+	    old = xkbi->state;
+	    old_prev = xkbi->prev_state;
+	    xkbi->state.base_mods &= ~mask;
+	    xkbi->state.base_mods |= (mods & mask);
+	    xkbi->state.latched_mods &= ~mask;
+	    xkbi->state.latched_mods |= (mods & mask);
+	    xkbi->state.locked_mods &= ~mask;
+	    xkbi->state.locked_mods |= (mods & mask);
+	    XkbComputeDerivedState(xkbi);
+	    xkbi->prev_state = xkbi->state;
+	}
+
+	UNWRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc);
+	xkbi->device->public.processInputProc((InternalEvent *) &ev,
+					      xkbi->device);
+	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
+				     xkbUnwrapProc);
+
+	if (mask || mods) {
+	    xkbi->state = old;
+	    xkbi->prev_state = old_prev;
+	}
+
+	/* We return 1 in case we have sent a release event because the new_key
+	   has changed.  Then, subsequently, we will call this function again
+	   with the same pAction, which will create the press for the new
+	   new_key. */
+	return (pAction && ev.detail.key != pAction->redirect.new_key);
     }
-    return 0;
 }
 
 static int
commit 8571c648a79444bcee9a0fe6e395129116372f49
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Jan 26 15:53:08 2013 +1000

    Xext: if a root window is given in XTestFakeInput, move to that
    
    For absolute events, if the client specifies a screen number offset the
    coordinates by that. And add a new flag so we know when _not_ to add the
    screen offset in GPE.
    
    Without this offset and the flag, GPE would simply add the offset of the
    current screen if POINTER_SCREEN is set.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 209bbdd..0a854f3 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -305,7 +305,7 @@ ProcXTestFakeInput(ClientPtr client)
             numValuators = 2;
             firstValuator = 0;
             if (ev->u.u.detail == xFalse)
-                flags = POINTER_ABSOLUTE | POINTER_SCREEN;
+                flags = POINTER_ABSOLUTE | POINTER_DESKTOP;
             break;
         default:
             client->errorValue = ev->u.u.type;
@@ -376,6 +376,14 @@ ProcXTestFakeInput(ClientPtr client)
                 client->errorValue = ev->u.keyButtonPointer.root;
                 return BadValue;
             }
+
+            /* Add the root window's offset to the valuators */
+            if ((flags & POINTER_ABSOLUTE) && firstValuator <= 1 && numValuators > 0) {
+                if (firstValuator == 0)
+                    valuators[0] += root->drawable.pScreen->x;
+                if (firstValuator < 2 && firstValuator + numValuators > 1)
+                    valuators[1 - firstValuator] += root->drawable.pScreen->y;
+            }
         }
         if (ev->u.u.detail != xTrue && ev->u.u.detail != xFalse) {
             client->errorValue = ev->u.u.detail;
diff --git a/dix/getevents.c b/dix/getevents.c
index 8fe54d7..02f5366 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -820,24 +820,30 @@ accelPointer(DeviceIntPtr dev, ValuatorMask *valuators, CARD32 ms)
  * device's coordinate range.
  *
  * @param dev The device to scale for.
- * @param[in, out] mask The mask in desktop coordinates, modified in place
+ * @param[in, out] mask The mask in desktop/screen coordinates, modified in place
  * to contain device coordinate range.
+ * @param flags If POINTER_SCREEN is set, mask is in per-screen coordinates.
+ *              Otherwise, mask is in desktop coords.
  */
 static void
-scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask)
+scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask, int flags)
 {
     double scaled;
     ScreenPtr scr = miPointerGetScreen(dev);
 
     if (valuator_mask_isset(mask, 0)) {
-        scaled = valuator_mask_get_double(mask, 0) + scr->x;
+        scaled = valuator_mask_get_double(mask, 0);
+        if (flags & POINTER_SCREEN)
+            scaled += scr->x;
         scaled = rescaleValuatorAxis(scaled,
                                      NULL, dev->valuator->axes + 0,
                                      screenInfo.x, screenInfo.width);
         valuator_mask_set_double(mask, 0, scaled);
     }
     if (valuator_mask_isset(mask, 1)) {
-        scaled = valuator_mask_get_double(mask, 1) + scr->y;
+        scaled = valuator_mask_get_double(mask, 1);
+        if (flags & POINTER_SCREEN)
+            scaled += scr->y;
         scaled = rescaleValuatorAxis(scaled,
                                      NULL, dev->valuator->axes + 1,
                                      screenInfo.y, screenInfo.height);
@@ -1363,10 +1369,10 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
     /* valuators are in driver-native format (rel or abs) */
 
     if (flags & POINTER_ABSOLUTE) {
-        if (flags & POINTER_SCREEN) {    /* valuators are in screen coords */
+        if (flags & (POINTER_SCREEN | POINTER_DESKTOP)) {    /* valuators are in screen/desktop coords */
             sx = valuator_mask_get(&mask, 0);
             sy = valuator_mask_get(&mask, 1);
-            scale_from_screen(pDev, &mask);
+            scale_from_screen(pDev, &mask, flags);
         }
 
         transformAbsolute(pDev, &mask);
diff --git a/include/input.h b/include/input.h
index f53ed99..7b5ab94 100644
--- a/include/input.h
+++ b/include/input.h
@@ -69,6 +69,7 @@ SOFTWARE.
 #define POINTER_SCREEN		(1 << 4)        /* Data in screen coordinates */
 #define POINTER_NORAW		(1 << 5)        /* Don't generate RawEvents */
 #define POINTER_EMULATED	(1 << 6)        /* Event was emulated from another event */
+#define POINTER_DESKTOP		(1 << 7)        /* Data in desktop coordinates */
 
 /* GetTouchEvent flags */
 #define TOUCH_ACCEPT            (1 << 0)
commit 9fd6cb89539fde44a41ae5183c89ef9c8831c8dd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 29 15:13:44 2013 +1000

    Xext: pass the current screen to miProcessDeviceEvent() from xtest calls
    
    Not passing in a screen means we skip the screen crossing updates, so a
    xtest event that changes between ScreenRecs won't do so until the next
    physical event comes in or never, whichever comes earlier.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 6519b9c..209bbdd 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -418,7 +418,7 @@ ProcXTestFakeInput(ClientPtr client)
     }
 
     for (i = 0; i < nevents; i++)
-        mieqProcessDeviceEvent(dev, &xtest_evlist[i], NULL);
+        mieqProcessDeviceEvent(dev, &xtest_evlist[i], miPointerGetScreen(inputInfo.pointer));
 
     if (need_ptr_update)
         miPointerUpdateSprite(dev);
commit a191dbfe850ed9c6440346f59cb0078e0e844edc
Author: Sybren van Elderen <sowmestno at msn.com>
Date:   Tue Jan 29 15:43:57 2013 +1000

    dix: when scaling from desktop coord, take the total desktop size (#51904)
    
    Scaled is already in desktop coordinates, take the total width into account,
    not just the current screen's width.
    
    Fixes Xdmx pointer position calculation.
    
    X.Org Bug 51904 <http://bugs.freedesktop.org/show_bug.cgi?id=51904>
    
    Signed-off-by: Sybren van Elderen <sowmestno at msn.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index a1e1938..8fe54d7 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -833,14 +833,14 @@ scale_from_screen(DeviceIntPtr dev, ValuatorMask *mask)
         scaled = valuator_mask_get_double(mask, 0) + scr->x;
         scaled = rescaleValuatorAxis(scaled,
                                      NULL, dev->valuator->axes + 0,
-                                     0, scr->width);
+                                     screenInfo.x, screenInfo.width);
         valuator_mask_set_double(mask, 0, scaled);
     }
     if (valuator_mask_isset(mask, 1)) {
         scaled = valuator_mask_get_double(mask, 1) + scr->y;
         scaled = rescaleValuatorAxis(scaled,
                                      NULL, dev->valuator->axes + 1,
-                                     0, scr->height);
+                                     screenInfo.y, screenInfo.height);
         valuator_mask_set_double(mask, 1, scaled);
     }
 }
commit 1cb19803f0f8dfd1e0fb9d189afe2262e24a0be5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 29 12:51:15 2013 +1000

    include: fix typo in list description
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/list.h b/include/list.h
index 2d48a86..067c679 100644
--- a/include/list.h
+++ b/include/list.h
@@ -358,7 +358,7 @@ xorg_list_is_empty(struct xorg_list *head)
  * struct foo *element = list;
  * while ((element = nt_list_next(element, next)) { }
  *
- * This macro is not safe for node deletion. Use xorg_list_for_each_entry_safe
+ * This macro is not safe for node deletion. Use nt_list_for_each_entry_safe
  * instead.
  *
  * @param list The list or current element.
commit 3d35dfcf5bad1b0a028fbecd65cb6cf6ebf12503
Author: Ted Felix <ted at tedfelix.com>
Date:   Tue Jan 29 16:36:48 2013 +1000

    xfree86: bail on misformed acpi strings (#73227)
    
    If acpid sends a string in a format that we can't parse, bail out instead of
    potentially dereferencing a NULL-pointer.
    
    X.Org Bug 73227 <http://bugs.freedesktop.org/show_bug.cgi?id=73227>
    
    Signed-off-by: Ted Felix <ted at tedfelix.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c
index d98efa2..dcaa19e 100644
--- a/hw/xfree86/os-support/linux/lnx_acpi.c
+++ b/hw/xfree86/os-support/linux/lnx_acpi.c
@@ -82,18 +82,21 @@ lnxACPIGetEventFromOs(int fd, pmEvent * events, int num)
 
         video = strtok(ev, " ");
 
-        GFX = strtok(NULL, " ");
+        if (!(GFX = strtok(NULL, " ")))
+            return 0;
 #if 0
         ErrorF("GFX: %s\n", GFX);
 #endif
 
-        notify = strtok(NULL, " ");
+        if (!(notify = strtok(NULL, " ")))
+            return 0;
         notify_l = strtoul(notify, NULL, 16);
 #if 0
         ErrorF("notify: 0x%lx\n", notify_l);
 #endif
 
-        data = strtok(NULL, " ");
+        if (!(data = strtok(NULL, " ")))
+            return 0;
         data_l = strtoul(data, NULL, 16);
 #if 0
         ErrorF("data: 0x%lx\n", data_l);
commit fdc451588816c4bc798d54e56316530e9066be80
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 29 11:01:29 2013 +1000

    Xi: limit valuator copy to valuator array size (#59939)
    
    mask[(MAX_VALUATORS + 7)/8] is larger than data[MAX_VALUATORS], so static
    code checkers think we may be running OOB on the data array. Mask is
    initialized to 0, so this should not happen, but change it anyway to shut up
    code analyzer noise.
    
    X.Org Bug 59939 <http://bugs.freedesktop.org/show_bug.cgi?id=59939>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 74f3610..609b126 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1263,7 +1263,7 @@ TouchCopyValuatorData(DeviceEvent *ev, TouchPointInfoPtr ti)
 {
     int i;
 
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    for (i = 0; i < ARRAY_SIZE(ev->valuators.data); i++)
         if (BitIsOn(ev->valuators.mask, i))
             valuator_mask_set_double(ti->valuators, i, ev->valuators.data[i]);
 }
commit 48bc30c5413a1be0039fa77affcbbb4fe677479f
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Jan 29 10:24:32 2013 +1000

    Xext: avoid null-pointer dereference in XTestFakeInput (#59937)
    
    dv is still NULL at this point, so return firstValuator instead (which is
    the same value dv->firstValuator would be once initialized)
    
    X.Org Bug 59937 <http://bugs.freedesktop.org/show_bug.cgi?id=59937>
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 2abdc7f..6519b9c 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -156,7 +156,6 @@ ProcXTestFakeInput(ClientPtr client)
     DeviceIntPtr dev = NULL;
     WindowPtr root;
     Bool extension = FALSE;
-    deviceValuator *dv = NULL;
     ValuatorMask mask;
     int valuators[MAX_VALUATORS] = { 0 };
     int numValuators = 0;
@@ -241,14 +240,14 @@ ProcXTestFakeInput(ClientPtr client)
         }
 
         if (nev > 1 && !dev->valuator) {
-            client->errorValue = dv->first_valuator;
+            client->errorValue = firstValuator;
             return BadValue;
         }
 
         /* check validity of valuator events */
         base = firstValuator;
         for (n = 1; n < nev; n++) {
-            dv = (deviceValuator *) (ev + n);
+            deviceValuator *dv = (deviceValuator *) (ev + n);
             if (dv->type != DeviceValuator) {
                 client->errorValue = dv->type;
                 return BadValue;
commit 1058fcf57fdcb94d92e7b5f4483b347853d5f8e6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Jan 26 14:13:33 2013 +1000

    dmx: don't include dmx-config.h from xdmxconfig (#37502)
    
    dmx-config.h is a server header which includes dix-config.h. That again
    defines a bunch of server-specifics, including setting the size of XID to
    32 bit.
    
    libX11 uses unsigned long (8 bits on x86_64). XGCValues thus ends up being
    16 bytes smaller in xdmxconfig than in the library, causing garbage to be
    sent to the server.
    
    X.Org Bug 37502 <http://bugs.freedesktop.org/show_bug.cgi?id=37502>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/hw/dmx/config/xdmxconfig.c b/hw/dmx/config/xdmxconfig.c
index f308412..2121dd7 100644
--- a/hw/dmx/config/xdmxconfig.c
+++ b/hw/dmx/config/xdmxconfig.c
@@ -31,9 +31,6 @@
  *
  */
 
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
 
 #include <stdio.h>
 #include <stdlib.h>
commit 7fe5e6dfa5c1e71d8b7540b28c1d508687a2fbee
Author: Jasper St. Pierre <jstpierre at mecheye.net>
Date:   Wed Jan 23 13:11:55 2013 -0500

    protocol-versions: Bump minor version of XI
    
    This was accidentally excluded when we added barriers.
    
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index cb8e213..10f5117 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -127,7 +127,7 @@
 
 /* X Input */
 #define SERVER_XI_MAJOR_VERSION			2
-#define SERVER_XI_MINOR_VERSION			2
+#define SERVER_XI_MINOR_VERSION			3
 
 /* XKB */
 #define SERVER_XKB_MAJOR_VERSION		1
commit 70b127c9f1c53bdb42f078265e67f76b464deae2
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Thu Jan 10 17:01:17 2013 -0800

    config/udev: fix "removing GPU device" format string mistake
    
     udev.c: In function 'device_removed':
     udev.c:270:9: warning: format '%d' expects argument of type 'int', but argument 3 has type 'const char *' [-Wformat]
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/config/udev.c b/config/udev.c
index 454838f..de89241 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -267,7 +267,7 @@ device_removed(struct udev_device *device)
 
         if (strncmp(sysname,"card", 4) != 0)
             return;
-        ErrorF("removing GPU device %s %d\n", syspath, path);
+        ErrorF("removing GPU device %s %s\n", syspath, path);
         if (!path)
             return;
 
commit 605dfc6804a05ff2bda5692fec26c37344fd95cb
Author: Dave Airlie <airlied at gmail.com>
Date:   Tue Jan 22 07:39:53 2013 +1000

    xserver: fix build regression since 91ab237358c6e33da854914d3de493a9cbea7637
    
    inputstr, double defines TouchListener typedef, maybe some gcc handles it,
    but not all.
    
    fixes tinderbox
    
    Reported-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/inputstr.h b/include/inputstr.h
index fc21913..48a29be 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -327,8 +327,6 @@ typedef struct _TouchPointInfo {
     size_t history_size;        /* Size of history in elements */
 } TouchPointInfoRec;
 
-typedef struct _TouchListener TouchListener;
-
 typedef struct _DDXTouchPointInfo {
     uint32_t client_id;         /* touch ID as seen in client events */
     Bool active;                /* whether or not the touch is active */
commit 069d8ed3eb659c48dd2b0f8b7b8c11f092fdb362
Merge: 591c062 d6dcde7
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 20 15:58:38 2013 -0800

    Merge remote-tracking branch 'jturney/xserver-next'

commit 591c06277bb120ab9615633f2d28addbd3a2aa5f
Merge: 6703a7c fa6ab7d
Author: Keith Packard <keithp at keithp.com>
Date:   Sun Jan 20 15:52:26 2013 -0800

    Merge remote-tracking branch 'whot/for-keith'

commit cde7cbe9674e8a771f9a4e646c1772a46a8230fb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 10 13:20:12 2013 +1000

    os: add support for %f to pnprintf
    
    This is the lazy man's %f support. Print the decimal part of the number,
    then append a decimal point, then print the first two digits of the
    fractional part. So %f in sigsafe printing is really %.2f.
    
    No boundary checks in place here.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/include/misc.h b/include/misc.h
index 3487176..0c67f11 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -250,6 +250,7 @@ extern char **xstrtokenize(const char *str, const char *separators);
 extern void FormatInt64(int64_t num, char *string);
 extern void FormatUInt64(uint64_t num, char *string);
 extern void FormatUInt64Hex(uint64_t num, char *string);
+extern void FormatDouble(double dbl, char *string);
 
 /**
  * Compare the two version numbers comprising of major.minor.
diff --git a/os/log.c b/os/log.c
index 2139064..7b5c9ee 100644
--- a/os/log.c
+++ b/os/log.c
@@ -351,7 +351,16 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
             for (i = 0; i < p_len && s_idx < size - 1; i++)
                 string[s_idx++] = number[i];
             break;
-
+        case 'f':
+            {
+                double d = va_arg(args, double);
+                FormatDouble(d, number);
+                p_len = strlen_sigsafe(number);
+
+                for (i = 0; i < p_len && s_idx < size - 1; i++)
+                    string[s_idx++] = number[i];
+            }
+            break;
         default:
             va_arg(args, char*);
             string[s_idx++] = '%';
diff --git a/os/utils.c b/os/utils.c
index e396ba4..3ba6499 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -1990,6 +1990,38 @@ FormatUInt64(uint64_t num, char *string)
     string[len] = '\0';
 }
 
+/**
+ * Format a double number as %.2f.
+ */
+void
+FormatDouble(double dbl, char *string)
+{
+    int slen = 0;
+    uint64_t frac;
+
+    frac = (dbl > 0 ? dbl : -dbl) * 100.0;
+    frac %= 100;
+
+    /* write decimal part to string */
+    if (dbl < 0 && dbl > -1)
+        string[slen++] = '-';
+    FormatInt64((int64_t)dbl, &string[slen]);
+
+    while(string[slen] != '\0')
+        slen++;
+
+    /* append fractional part, but only if we have enough characters. We
+     * expect string to be 21 chars (incl trailing \0) */
+    if (slen <= 17) {
+        string[slen++] = '.';
+        if (frac < 10)
+            string[slen++] = '0';
+
+        FormatUInt64(frac, &string[slen]);
+    }
+}
+
+
 /* Format a number into a hexadecimal string in a signal safe manner. The string
  * should be at least 17 characters in order to handle all uint64_t values. */
 void
diff --git a/test/signal-logging.c b/test/signal-logging.c
index 127a28f..1ef17af 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -41,6 +41,11 @@ struct signed_number_format_test {
     char string[21];
 };
 
+struct float_number_format_test {
+    double number;
+    char string[21];
+};
+
 static Bool
 check_signed_number_format_test(long int number)
 {
@@ -59,6 +64,25 @@ check_signed_number_format_test(long int number)
 }
 
 static Bool
+check_float_format_test(double number)
+{
+    char string[21];
+    char expected[21];
+
+    /* we currently always print float as .2f */
+    sprintf(expected, "%.2f", number);
+
+    FormatDouble(number, string);
+    if(strncmp(string, expected, 21) != 0) {
+        fprintf(stderr, "Failed to convert %f to string (%s vs %s)\n",
+                number, expected, string);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static Bool
 check_number_format_test(long unsigned int number)
 {
     char string[21];
@@ -84,6 +108,11 @@ check_number_format_test(long unsigned int number)
     return TRUE;
 }
 
+/* FIXME: max range stuff */
+double float_tests[] = { 0, 5, 0.1, 0.01, 5.2342, 10.2301,
+                         -1, -2.00, -0.6023, -1203.30
+                        };
+
 static void
 number_formatting(void)
 {
@@ -116,6 +145,9 @@ number_formatting(void)
 
     for (i = 0; i < sizeof(unsigned_tests) / sizeof(signed_tests[0]); i++)
         assert(check_signed_number_format_test(signed_tests[i]));
+
+    for (i = 0; i < sizeof(float_tests) / sizeof(float_tests[0]); i++)
+        assert(check_float_format_test(float_tests[i]));
 }
 
 #pragma GCC diagnostic ignored "-Wformat-security"
@@ -232,6 +264,30 @@ static void logging_format(void)
         ptr <<= 1;
     } while(ptr);
 
+
+    for (i = 0; i < sizeof(float_tests)/sizeof(float_tests[0]); i++) {
+        double d = float_tests[i];
+        char expected[30];
+        sprintf(expected, "(EE) %.2f\n", d);
+        LogMessageVerbSigSafe(X_ERROR, -1, "%f\n", d);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        /* test for length modifiers, we just ignore them atm */
+        LogMessageVerbSigSafe(X_ERROR, -1, "%.3f\n", d);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        LogMessageVerbSigSafe(X_ERROR, -1, "%3f\n", d);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+
+        LogMessageVerbSigSafe(X_ERROR, -1, "%.0f\n", d);
+        read_log_msg(logmsg);
+        assert(strcmp(logmsg, expected) == 0);
+    }
+
+
     LogClose(EXIT_NO_ERROR);
     unlink(log_file_path);
 
commit 20def57632583aef095ca18792c7fce16d2d9004
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 10 13:24:05 2013 +1000

    os: silently ignore length modifiers in pnprintf
    
    Until we have support for them, ignore any length modifiers so we don't need
    to update all callers.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/os/log.c b/os/log.c
index 4820e9a..2139064 100644
--- a/os/log.c
+++ b/os/log.c
@@ -298,7 +298,13 @@ pnprintf(char *string, size_t size, const char *f, va_list args)
             continue;
         }
 
-        switch (f[++f_idx]) {
+        f_idx++;
+
+        /* silently swallow length modifiers */
+        while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
+            f_idx++;
+
+        switch (f[f_idx]) {
         case 's':
             string_arg = va_arg(args, char*);
             p_len = strlen_sigsafe(string_arg);
commit f53b2012f39085d866f267dda1442a48ace3c5a5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 17 16:19:51 2013 +1000

    test/signal-logging: simplify tests using sprintf
    
    Ever looked at your own code and thought 'WTF was I thinking?'. yeah, that.
    
    Instead of passing in the expected string just use sprintf to print the
    number for us and compare. In the end we're just trying to emulate printf
    behaviour anyway.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/test/signal-logging.c b/test/signal-logging.c
index 810bd20..127a28f 100644
--- a/test/signal-logging.c
+++ b/test/signal-logging.c
@@ -42,14 +42,16 @@ struct signed_number_format_test {
 };
 
 static Bool
-check_signed_number_format_test(const struct signed_number_format_test *test)
+check_signed_number_format_test(long int number)
 {
     char string[21];
+    char expected[21];
 
-    FormatInt64(test->number, string);
-    if(strncmp(string, test->string, 21) != 0) {
-        fprintf(stderr, "Failed to convert %jd to decimal string (%s vs %s)\n",
-                test->number, test->string, string);
+    sprintf(expected, "%ld", number);
+    FormatInt64(number, string);
+    if(strncmp(string, expected, 21) != 0) {
+        fprintf(stderr, "Failed to convert %jd to decimal string (expected %s but got %s)\n",
+                number, expected, string);
         return FALSE;
     }
 
@@ -57,21 +59,25 @@ check_signed_number_format_test(const struct signed_number_format_test *test)
 }
 
 static Bool
-check_number_format_test(const struct number_format_test *test)
+check_number_format_test(long unsigned int number)
 {
     char string[21];
+    char expected[21];
 
-    FormatUInt64(test->number, string);
-    if(strncmp(string, test->string, 21) != 0) {
+    sprintf(expected, "%lu", number);
+
+    FormatUInt64(number, string);
+    if(strncmp(string, expected, 21) != 0) {
         fprintf(stderr, "Failed to convert %ju to decimal string (%s vs %s)\n",
-                test->number, test->string, string);
+                number, expected, string);
         return FALSE;
     }
-    FormatUInt64Hex(test->number, string);
-    if(strncmp(string, test->hex_string, 17) != 0) {
-        fprintf(stderr,
-                "Failed to convert %ju to hexadecimal string (%s vs %s)\n",
-                test->number, test->hex_string, string);
+
+    sprintf(expected, "%lx", number);
+    FormatUInt64Hex(number, string);
+    if(strncmp(string, expected, 17) != 0) {
+        fprintf(stderr, "Failed to convert %ju to hexadecimal string (%s vs %s)\n",
+                number, expected, string);
         return FALSE;
     }
 
@@ -82,100 +88,34 @@ static void
 number_formatting(void)
 {
     int i;
-    struct number_format_test unsigned_tests[] = {
-        { /* Zero */
-            0,
-            "0",
-            "0",
-        },
-        { /* Single digit number */
-            5,
-            "5",
-            "5",
-        },
-        { /* Two digit decimal number */
-            12,
-            "12",
-            "c",
-        },
-        { /* Two digit hex number */
-            37,
-            "37",
-            "25",
-        },
-        { /* Large < 32 bit number */
-            0xC90B2,
-            "823474",
-            "c90b2",
-        },
-        { /* Large > 32 bit number */
-            0x15D027BF211B37A,
-            "98237498237498234",
-            "15d027bf211b37a",
-        },
-        { /* Maximum 64-bit number */
-            0xFFFFFFFFFFFFFFFF,
-            "18446744073709551615",
-            "ffffffffffffffff",
-        },
+    long unsigned int unsigned_tests[] = { 0,/* Zero */
+                                           5, /* Single digit number */
+                                           12, /* Two digit decimal number */
+                                           37, /* Two digit hex number */
+                                           0xC90B2, /* Large < 32 bit number */
+                                           0x15D027BF211B37A, /* Large > 32 bit number */
+                                           0xFFFFFFFFFFFFFFFF, /* Maximum 64-bit number */
     };
 
-    struct signed_number_format_test signed_tests[] = {
-        { /* Zero */
-            0,
-            "0",
-        },
-        { /* Single digit number */
-            5,
-            "5",
-        },
-        { /* Two digit decimal number */
-            12,
-            "12",
-        },
-        { /* Two digit hex number */
-            37,
-            "37",
-        },
-        { /* Large < 32 bit number */
-            0xC90B2,
-            "823474",
-        },
-        { /* Large > 32 bit number */
-            0x15D027BF211B37A,
-            "98237498237498234",
-        },
-        { /* Maximum 64-bit signed number */
-            0x7FFFFFFFFFFFFFFF,
-            "9223372036854775807",
-        },
-        { /* Single digit number */
-            -1,
-            "-1",
-        },
-        { /* Two digit decimal number */
-            -12,
-            "-12",
-        },
-        { /* Large < 32 bit number */
-            -0xC90B2,
-            "-823474",
-        },
-        { /* Large > 32 bit number */
-            -0x15D027BF211B37A,
-            "-98237498237498234",
-        },
-        { /* Maximum 64-bit number */
-            -0x7FFFFFFFFFFFFFFF,
-            "-9223372036854775807",
-        },
-    };
+    long int signed_tests[] = { 0,/* Zero */
+                                5, /* Single digit number */
+                                12, /* Two digit decimal number */
+                                37, /* Two digit hex number */
+                                0xC90B2, /* Large < 32 bit number */
+                                0x15D027BF211B37A, /* Large > 32 bit number */
+                                0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */
+                                -1, /* Single digit number */
+                                -12, /* Two digit decimal number */
+                                -0xC90B2, /* Large < 32 bit number */
+                                -0x15D027BF211B37A, /* Large > 32 bit number */
+                                -0x7FFFFFFFFFFFFFFF, /* Maximum 64-bit signed number */
+    } ;
 
     for (i = 0; i < sizeof(unsigned_tests) / sizeof(unsigned_tests[0]); i++)
-        assert(check_number_format_test(unsigned_tests + i));
+        assert(check_number_format_test(unsigned_tests[i]));
 
     for (i = 0; i < sizeof(unsigned_tests) / sizeof(signed_tests[0]); i++)
-        assert(check_signed_number_format_test(signed_tests + i));
+        assert(check_signed_number_format_test(signed_tests[i]));
 }
 
 #pragma GCC diagnostic ignored "-Wformat-security"
commit d6dcde7a03bb38c17ffc4ec5f0ca1c161e54569f
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sat Feb 11 12:22:17 2012 +0000

    hw/xwin: Stop assuming WS_EX_APPWINDOW style in WM_SHOWWINDOW
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index f7c6f2b..0e46ea7 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -870,41 +870,36 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 
         /* */
         if (!pWin->overrideRedirect) {
+            HWND zstyle = HWND_NOTOPMOST;
+
             /* Flag that this window needs to be made active when clicked */
             SetProp(hwnd, WIN_NEEDMANAGE_PROP, (HANDLE) 1);
 
-            if (!(GetWindowLongPtr(hwnd, GWL_EXSTYLE) & WS_EX_APPWINDOW)) {
-                HWND zstyle = HWND_NOTOPMOST;
-
-                /* Set the window extended style flags */
-                SetWindowLongPtr(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW);
-
-                /* Set the transient style flags */
-                if (GetParent(hwnd))
-                    SetWindowLongPtr(hwnd, GWL_STYLE,
-                                     WS_POPUP | WS_OVERLAPPED | WS_SYSMENU |
-                                     WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
-                /* Set the window standard style flags */
-                else
-                    SetWindowLongPtr(hwnd, GWL_STYLE,
-                                     (WS_POPUP | WS_OVERLAPPEDWINDOW |
-                                      WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
-                                     & ~WS_CAPTION & ~WS_SIZEBOX);
-
-                winUpdateWindowPosition(hwnd, &zstyle);
-
-                {
-                    WinXWMHints hints;
-
-                    if (winMultiWindowGetWMHints(pWin, &hints)) {
-                        /*
-                           Give the window focus, unless it has an InputHint
-                           which is FALSE (this is used by e.g. glean to
-                           avoid every test window grabbing the focus)
-                         */
-                        if (!((hints.flags & InputHint) && (!hints.input))) {
-                            SetForegroundWindow(hwnd);
-                        }
+            /* Set the transient style flags */
+            if (GetParent(hwnd))
+                SetWindowLongPtr(hwnd, GWL_STYLE,
+                                 WS_POPUP | WS_OVERLAPPED | WS_SYSMENU |
+                                 WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+            /* Set the window standard style flags */
+            else
+                SetWindowLongPtr(hwnd, GWL_STYLE,
+                                 (WS_POPUP | WS_OVERLAPPEDWINDOW |
+                                  WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
+                                 & ~WS_CAPTION & ~WS_SIZEBOX);
+
+            winUpdateWindowPosition(hwnd, &zstyle);
+
+            {
+                WinXWMHints hints;
+
+                if (winMultiWindowGetWMHints(pWin, &hints)) {
+                    /*
+                       Give the window focus, unless it has an InputHint
+                       which is FALSE (this is used by e.g. glean to
+                       avoid every test window grabbing the focus)
+                     */
+                    if (!((hints.flags & InputHint) && (!hints.input))) {
+                        SetForegroundWindow(hwnd);
                     }
                 }
             }
commit 56e94403f8f9182e05428d895a983371c7737d2a
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Jan 9 20:15:01 2013 +0000

    hw/xwin: Use ITaskBarList interface to ensure show-on-taskbar state is updated correctly
    
    Use ITaskBarList interface to ensure that the taskbar notices if the window has
    changed it's style in a way which affects if the taskbar shows it or not.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 0c6b09a..4f6dec7 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -614,6 +614,19 @@ UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
     if (zstyle == HWND_NOTOPMOST)
         flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
     SetWindowPos(hWnd, NULL, 0, 0, 0, 0, flags);
+
+    /*
+       Use the WS_EX_TOOLWINDOW style to remove window from Alt-Tab window switcher
+
+       According to MSDN, this is supposed to remove the window from the taskbar as well,
+       if we SW_HIDE before changing the style followed by SW_SHOW afterwards.
+
+       But that doesn't seem to work reliably, and causes the window to flicker, so use
+       the iTaskbarList interface to tell the taskbar to show or hide this window.
+     */
+    winShowWindowOnTaskbar(hWnd,
+                           (GetWindowLongPtr(hWnd, GWL_EXSTYLE) &
+                            WS_EX_APPWINDOW) ? TRUE : FALSE);
 }
 
 #if 0
commit c94d1cb0a49106f44714f4511720a197cc549164
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Jan 10 14:35:56 2013 +0000

    hw/xwin: Ensure full styling is applied when the window is mapped
    
    Move styling update code from WM_WM_HINTS_EVENT to a function UpdateStyle(),
    which is also invoked from WM_WM_MAP3, so everything which needs to be done
    to style the window happens when it is mapped
    
    (Otherwise, the appearance of the window is sensitive to the timing of the
    notification of the windows appearance hint properties being set relative to
    window creation. e.g. see [1])
    
    [1] http://sourceware.org/ml/cygwin-xfree/2012-06/msg00004.html
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 1dc31fd..0c6b09a 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -590,6 +590,32 @@ UpdateIcon(WMInfoPtr pWMInfo, Window iWindow)
     winUpdateIcon(hWnd, pWMInfo->pDisplay, iWindow, hIconNew);
 }
 
+/*
+ * Updates the style of a HWND according to its X style properties
+ */
+
+static void
+UpdateStyle(WMInfoPtr pWMInfo, Window iWindow)
+{
+    HWND hWnd;
+    HWND zstyle = HWND_NOTOPMOST;
+    UINT flags;
+
+    hWnd = getHwnd(pWMInfo, iWindow);
+    if (!hWnd)
+        return;
+
+    /* Determine the Window style, which determines borders and clipping region... */
+    winApplyHints(pWMInfo->pDisplay, iWindow, hWnd, &zstyle);
+    winUpdateWindowPosition(hWnd, &zstyle);
+
+    /* Apply the updated window style, without changing it's show or activation state */
+    flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
+    if (zstyle == HWND_NOTOPMOST)
+        flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
+    SetWindowPos(hWnd, NULL, 0, 0, 0, 0, flags);
+}
+
 #if 0
 /*
  * Fix up any differences between the X11 and Win32 window stacks
@@ -737,13 +763,8 @@ winMultiWindowWMProc(void *pArg)
                             (unsigned char *) &(pNode->msg.hwndWindow), 1);
             UpdateName(pWMInfo, pNode->msg.iWindow);
             UpdateIcon(pWMInfo, pNode->msg.iWindow);
-            {
-                HWND zstyle = HWND_NOTOPMOST;
+            UpdateStyle(pWMInfo, pNode->msg.iWindow);
 
-                winApplyHints(pWMInfo->pDisplay, pNode->msg.iWindow,
-                              pNode->msg.hwndWindow, &zstyle);
-                winUpdateWindowPosition(pNode->msg.hwndWindow, &zstyle);
-            }
 
             /* Reshape */
             {
@@ -815,8 +836,6 @@ winMultiWindowWMProc(void *pArg)
 
         case WM_WM_HINTS_EVENT:
             {
-            HWND zstyle = HWND_NOTOPMOST;
-            UINT flags;
             XWindowAttributes attr;
 
             /* Don't do anything if this is an override-redirect window */
@@ -824,18 +843,7 @@ winMultiWindowWMProc(void *pArg)
             if (attr.override_redirect)
               break;
 
-            pNode->msg.hwndWindow = getHwnd(pWMInfo, pNode->msg.iWindow);
-
-            /* Determine the Window style, which determines borders and clipping region... */
-            winApplyHints(pWMInfo->pDisplay, pNode->msg.iWindow,
-                          pNode->msg.hwndWindow, &zstyle);
-            winUpdateWindowPosition(pNode->msg.hwndWindow, &zstyle);
-
-            /* Apply the updated window style, without changing it's show or activation state */
-            flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
-            if (zstyle == HWND_NOTOPMOST)
-                flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
-            SetWindowPos(pNode->msg.hwndWindow, NULL, 0, 0, 0, 0, flags);
+            UpdateStyle(pWMInfo, pNode->msg.iWindow);
             }
             break;
 
commit ef61f8cacc84080c9156675f9ce26a27e8a90ac1
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sat Mar 31 18:45:28 2012 +0100

    hw/xwin: Make sure that WM_WM_HINTS_EVENT does nothing for override-redirect windows
    
    Future work: It looks like this code could be rationalized quite a lot: It might
    make sense to pull the checking for override-redirect up out of UpdateIcon() and
    UpdateName() and consolidate WM_WM_MAP2 and WM_WM_MAP3
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 1200243..1dc31fd 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -817,6 +817,12 @@ winMultiWindowWMProc(void *pArg)
             {
             HWND zstyle = HWND_NOTOPMOST;
             UINT flags;
+            XWindowAttributes attr;
+
+            /* Don't do anything if this is an override-redirect window */
+            XGetWindowAttributes (pWMInfo->pDisplay, pNode->msg.iWindow, &attr);
+            if (attr.override_redirect)
+              break;
 
             pNode->msg.hwndWindow = getHwnd(pWMInfo, pNode->msg.iWindow);
 
commit 3628559e594fcbdfcc14b1e8fa60aa841f184e19
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Sun Feb 5 11:25:39 2012 +0000

    hw/xwin: Add a new WM_WM_HINTS_EVENT event to update window style
    
    Add a new WM_WM_HINTS_EVENT event to update window style if any of the
    properties which affect window style change
    
    Check PropertyNotify events for any of the window properties which we consider
    to decide on the window style, and update the window style by sending a
    WM_WM_HINTS_EVENT message to the WM.
    
    This allows the styling of the window to change during it's lifetime.
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index feefcf4..1200243 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -813,6 +813,26 @@ winMultiWindowWMProc(void *pArg)
             UpdateIcon(pWMInfo, pNode->msg.iWindow);
             break;
 
+        case WM_WM_HINTS_EVENT:
+            {
+            HWND zstyle = HWND_NOTOPMOST;
+            UINT flags;
+
+            pNode->msg.hwndWindow = getHwnd(pWMInfo, pNode->msg.iWindow);
+
+            /* Determine the Window style, which determines borders and clipping region... */
+            winApplyHints(pWMInfo->pDisplay, pNode->msg.iWindow,
+                          pNode->msg.hwndWindow, &zstyle);
+            winUpdateWindowPosition(pNode->msg.hwndWindow, &zstyle);
+
+            /* Apply the updated window style, without changing it's show or activation state */
+            flags = SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE;
+            if (zstyle == HWND_NOTOPMOST)
+                flags |= SWP_NOZORDER | SWP_NOOWNERZORDER;
+            SetWindowPos(pNode->msg.hwndWindow, NULL, 0, 0, 0, 0, flags);
+            }
+            break;
+
         case WM_WM_CHANGE_STATE:
             /* Minimize the window in Windows */
             winMinimizeWindow(pNode->msg.iWindow);
@@ -862,6 +882,7 @@ winMultiWindowXMsgProc(void *pArg)
     Atom atmWmHints;
     Atom atmWmChange;
     Atom atmNetWmIcon;
+    Atom atmWindowState, atmMotifWmHints, atmWindowType, atmNormalHints;
     int iReturn;
     XIconSize *xis;
 
@@ -988,6 +1009,10 @@ winMultiWindowXMsgProc(void *pArg)
     atmWmHints = XInternAtom(pProcArg->pDisplay, "WM_HINTS", False);
     atmWmChange = XInternAtom(pProcArg->pDisplay, "WM_CHANGE_STATE", False);
     atmNetWmIcon = XInternAtom(pProcArg->pDisplay, "_NET_WM_ICON", False);
+    atmWindowState = XInternAtom(pProcArg->pDisplay, "_NET_WM_STATE", False);
+    atmMotifWmHints = XInternAtom(pProcArg->pDisplay, "_MOTIF_WM_HINTS", False);
+    atmWindowType = XInternAtom(pProcArg->pDisplay, "_NET_WM_WINDOW_TYPE", False);
+    atmNormalHints = XInternAtom(pProcArg->pDisplay, "WM_NORMAL_HINTS", False);
 
     /*
        iiimxcf had a bug until 2009-04-27, assuming that the
@@ -1125,14 +1150,34 @@ winMultiWindowXMsgProc(void *pArg)
                 /* Other fields ignored */
                 winSendMessageToWM(pProcArg->pWMInfo, &msg);
             }
-            else if ((event.xproperty.atom == atmWmHints) ||
-                     (event.xproperty.atom == atmNetWmIcon)) {
-                memset(&msg, 0, sizeof(msg));
-                msg.msg = WM_WM_ICON_EVENT;
-                msg.iWindow = event.xproperty.window;
+            else {
+                /*
+                   Several properties are considered for WM hints, check if this property change affects any of them...
+                   (this list needs to be kept in sync with winApplyHints())
+                 */
+                if ((event.xproperty.atom == atmWmHints) ||
+                    (event.xproperty.atom == atmWindowState) ||
+                    (event.xproperty.atom == atmMotifWmHints) ||
+                    (event.xproperty.atom == atmWindowType) ||
+                    (event.xproperty.atom == atmNormalHints)) {
+                    memset(&msg, 0, sizeof(msg));
+                    msg.msg = WM_WM_HINTS_EVENT;
+                    msg.iWindow = event.xproperty.window;
+
+                    /* Other fields ignored */
+                    winSendMessageToWM(pProcArg->pWMInfo, &msg);
+                }
 
-                /* Other fields ignored */
-                winSendMessageToWM(pProcArg->pWMInfo, &msg);
+                /* Not an else as WM_HINTS affects both style and icon */
+                if ((event.xproperty.atom == atmWmHints) ||
+                    (event.xproperty.atom == atmNetWmIcon)) {
+                    memset(&msg, 0, sizeof(msg));
+                    msg.msg = WM_WM_ICON_EVENT;
+                    msg.iWindow = event.xproperty.window;
+
+                    /* Other fields ignored */
+                    winSendMessageToWM(pProcArg->pWMInfo, &msg);
+                }
             }
         }
         else if (event.type == ClientMessage
diff --git a/hw/xwin/winwindow.h b/hw/xwin/winwindow.h
index 37b9752..25826ec 100644
--- a/hw/xwin/winwindow.h
+++ b/hw/xwin/winwindow.h
@@ -110,6 +110,7 @@ typedef struct _winWMMessageRec {
 #define		WM_WM_CHANGE_STATE	(WM_USER + 11)
 #define		WM_WM_MAP2		(WM_USER + 12)
 #define		WM_WM_MAP3		(WM_USER + 13)
+#define		WM_WM_HINTS_EVENT	(WM_USER + 14)
 #define		WM_MANAGE		(WM_USER + 100)
 #define		WM_UNMANAGE		(WM_USER + 102)
 
commit 066ecbd11d516ea68d7ebc7470232d01c5717546
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Jan 10 14:37:45 2013 +0000

    hw/xwin: Move reshape code from winUpdateWindowPosition() to the map event handler
    
    Move reshape code, which was only used when handling a map event, from
    winUpdateWindowPosition(), to put it explicitly in the map event handler.
    
    Remove 'reshape' parameter from winUpdatePosition().
    
    (Note that there's no handling of the ShapeNotify event to notice when the
    window shape changes, instead we hook the screen SetShape procedure and reshape
    the native window then)
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winmultiwindowwm.c b/hw/xwin/winmultiwindowwm.c
index 773fc97..feefcf4 100644
--- a/hw/xwin/winmultiwindowwm.c
+++ b/hw/xwin/winmultiwindowwm.c
@@ -186,7 +186,7 @@ static void
  winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle);
 
 void
- winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle);
+ winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
 
 /*
  * Local globals
@@ -742,8 +742,19 @@ winMultiWindowWMProc(void *pArg)
 
                 winApplyHints(pWMInfo->pDisplay, pNode->msg.iWindow,
                               pNode->msg.hwndWindow, &zstyle);
-                winUpdateWindowPosition(pNode->msg.hwndWindow, TRUE, &zstyle);
+                winUpdateWindowPosition(pNode->msg.hwndWindow, &zstyle);
             }
+
+            /* Reshape */
+            {
+                WindowPtr pWin =
+                    GetProp(pNode->msg.hwndWindow, WIN_WINDOW_PROP);
+                if (pWin) {
+                    winReshapeMultiWindow(pWin);
+                    winUpdateRgnMultiWindow(pWin);
+                }
+            }
+
             break;
 
         case WM_WM_UNMAP:
@@ -1749,7 +1760,7 @@ winApplyHints(Display * pDisplay, Window iWindow, HWND hWnd, HWND * zstyle)
 }
 
 void
-winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
+winUpdateWindowPosition(HWND hWnd, HWND * zstyle)
 {
     int iX, iY, iWidth, iHeight;
     int iDx, iDy;
@@ -1800,8 +1811,4 @@ winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle)
     SetWindowPos(hWnd, *zstyle, rcNew.left, rcNew.top,
                  rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, 0);
 
-    if (reshape) {
-        winReshapeMultiWindow(pWin);
-        winUpdateRgnMultiWindow(pWin);
-    }
 }
diff --git a/hw/xwin/winmultiwindowwndproc.c b/hw/xwin/winmultiwindowwndproc.c
index c2292c6..f7c6f2b 100644
--- a/hw/xwin/winmultiwindowwndproc.c
+++ b/hw/xwin/winmultiwindowwndproc.c
@@ -42,7 +42,7 @@
 #include "winmsg.h"
 #include "inputstr.h"
 
-extern void winUpdateWindowPosition(HWND hWnd, Bool reshape, HWND * zstyle);
+extern void winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
 
 /*
  * Local globals
@@ -891,7 +891,7 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
                                       WS_CLIPCHILDREN | WS_CLIPSIBLINGS)
                                      & ~WS_CAPTION & ~WS_SIZEBOX);
 
-                winUpdateWindowPosition(hwnd, FALSE, &zstyle);
+                winUpdateWindowPosition(hwnd, &zstyle);
 
                 {
                     WinXWMHints hints;
commit 852d1fb042f4160fe023a015f1c9a34126bf911a
Author: Ryan Pavlik <rpavlik at iastate.edu>
Date:   Sat Dec 1 16:58:40 2012 +0000

    hw/xwin: Add missing include xwin-config.h to winglobals.h
    
    winglobals.h checks if RELOCATE_PROJECTROOT is defined to see if a declaration
    of g_fLogFileChanged is needed, so must include xwin-config.h
    
    Signed-off-by: Ryan Pavlik <rpavlik at iastate.edu>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winglobals.h b/hw/xwin/winglobals.h
index 2edf957..d2e2ba2 100644
--- a/hw/xwin/winglobals.h
+++ b/hw/xwin/winglobals.h
@@ -26,6 +26,10 @@
 #ifndef WINGLOBALS_H
 #define WINGLOBALS_H
 
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
 /*
  * References to external symbols
  */
commit ab686ce029208abf970a4bcd1435bf8411a44de9
Author: Ryan Pavlik <rpavlik at iastate.edu>
Date:   Wed Oct 26 17:03:25 2011 -0500

    include: Add RELOCATE_PROJECTROOT to xwin-config.h header
    
    RELOCATE_PROJECTROOT is AC_DEFINED in configure.ac, but currently has no effect
    as it doesn't appear in any AC_CONFIG_HEADER header.
    
    When packaged for Windows, we do not have a unix-style filesystem tree, where
    file needed by the X server can be found in fixed, absolute paths under the
    prefix (PROJECTROOT).
    
    Instead, the filesystem tree containing files needed by the X server and clients
    will be installed with the directory containing the X server executable as the
    root directory of that tree.
    
    (Typically, this will be in the Program Files directory, which does not have a
    fixed name, as it can be moved, localized, or added to to indicate x86 or x64
    binaries)
    
    So, RELOCATE_PROJECTROOT is used to make a native Windows build of the X server
    look for various files (fonts, xkb data) in locations relative to the X server
    rather than at absolute paths, by translating those paths at run-time.
    
    Additionally the XKEYSYMDB, XERRORDB, XLOCALEDIR env vars checked by libX11 are
    set appropriately for clients started by the X server.
    
    Signed-off-by: Ryan Pavlik <rpavlik at iastate.edu>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/include/xwin-config.h.in b/include/xwin-config.h.in
index 8122f55..c5119f2 100644
--- a/include/xwin-config.h.in
+++ b/include/xwin-config.h.in
@@ -31,3 +31,6 @@
 
 /* Default log location */
 #undef DEFAULT_LOGDIR
+
+/* Whether we should re-locate the root to where the executable lives */
+#undef RELOCATE_PROJECTROOT
commit fa6ab7d9b2d7fd8184f1e068360607845f5c33ab
Merge: adde4e6 0e1ab43
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 11 14:58:17 2013 +1000

    Merge branch 'pointer-emulation-fixes-56558-v2' into for-keith

commit adde4e64480315dc5b47a727ee37d86f5cd8584f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 10 10:33:05 2013 +1000

    dix: typo fix in comment
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 338f415..c7994b0 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -738,7 +738,7 @@ ApplyConstantDeceleration(DeviceVelocityPtr vel, double *fdx, double *fdy)
 }
 
 /*
- * compute the acceleration for given velocity and enforce min_acceleartion
+ * compute the acceleration for given velocity and enforce min_acceleration
  */
 double
 BasicComputeAcceleration(DeviceIntPtr dev,
commit 05ed095dd8d6cf939b4ebd9a59d70ce32705df7c
Author: Benjamin Tissoires <benjamin.tissoires at gmail.com>
Date:   Wed Jan 9 19:32:19 2013 +0100

    dix: fix error logging occuring in signal context of GetTouchEvents
    
    GetTouchEvents is usually called in a signal context.
    Calling ErrorF for the error messages leads to X complaining about log:
    
    (EE) BUG: triggered 'if (inSignalContext)'
    (EE) BUG: log.c:484 in LogVMessageVerb()
    (EE) Warning: attempting to log data in a signal unsafe manner while in signal context.
    Please update to check inSignalContext and/or use LogMessageVerbSigSafe() or ErrorFSigSafe().
    The offending log format message is:
    %s: Attempted to start touch without x/y (driver bug)
    
    Signed-off-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 3d41e1e..a1e1938 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1895,16 +1895,16 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
         if (!mask_in ||
             !valuator_mask_isset(mask_in, 0) ||
             !valuator_mask_isset(mask_in, 1)) {
-            ErrorF("%s: Attempted to start touch without x/y (driver bug)\n",
-                   dev->name);
+            ErrorFSigSafe("%s: Attempted to start touch without x/y "
+                          "(driver bug)\n", dev->name);
             return 0;
         }
         break;
     case XI_TouchUpdate:
         event->type = ET_TouchUpdate;
         if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0) {
-            ErrorF("%s: TouchUpdate with no valuators? Driver bug\n",
-                   dev->name);
+            ErrorFSigSafe("%s: TouchUpdate with no valuators? Driver bug\n",
+                          dev->name);
         }
         break;
     case XI_TouchEnd:
commit f4a58469a298c226668fd8dce375bf22331c902d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jan 9 13:58:56 2013 +1000

    xfree86: don't access the old input handler after freeing it
    
    Introduced in 323869f3298cbbfe864af9404a8aed1bf7995d79
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index d8d4fad..377e936 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -619,14 +619,16 @@ InputHandlerProc
 xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
 {
     static IHPtr handler = NULL;
-    IHPtr old_handler = handler;
+    InputHandlerProc old_proc = NULL;
 
-    if (old_handler)
-        xf86RemoveGeneralHandler(old_handler);
+    if (handler) {
+        old_proc = handler->ihproc;
+        xf86RemoveGeneralHandler(handler);
+    }
 
     handler = xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
 
-    return (old_handler) ? old_handler->ihproc : NULL;
+    return old_proc;
 }
 
 static void
commit 205cfbd6d9824fb9a67c21b19bc8f1e66c9df4d2
Author: Dave Airlie <airlied at gmail.com>
Date:   Sat Jan 5 18:35:42 2013 +1000

    xf86: bump input ABI version to 19
    
    The changes to miPointerSetPosition interface from int->double breaks
    the SIS driver build, so time to bump this.
    
    Signed-off-by: Dave Airlie <airlied at redhat.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 1be7ba5..e545c14 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -81,7 +81,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(14, 1)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(18, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(19, 0)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(7, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
commit ad3bc571348a7007a2960bf87ae739397c5511ee
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 8 11:19:09 2013 +1000

    xfree86: update the device state for all DGA events (#59100)
    
    DGA only handles master devices but it does intercept slave device events as
    well (since the event handlers are per event type, not per device).
    
    The DGA code must thus call into UpdateDeviceState to reset the button/key
    state on the slave device before it discards the remainder of the event.
    
    Test case:
    - Passive GrabModeSync on VCP
    - Press button
    - Enable DGA after ButtonPress
    - AllowEvents(SyncPointer)
    - Release button
    
    The button release is handled by DGAProcessPointerEvent but the device state
    is never updated, so the slave ends up with the button permanently down.
    And since the master's button state is the union of the slave states, the
    master has the button permanently down.
    
    X.Org Bug 59100 <http://bugs.freedesktop.org/show_bug.cgi?id=59100>
    
    Reported-by: Steven Elliott <selliott4 at austin.rr.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index c10dd32..6a05ce5 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1033,6 +1033,9 @@ DGAProcessKeyboardEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr keybd)
 
     UpdateDeviceState(keybd, &ev);
 
+    if (!IsMaster(keybd))
+        return;
+
     /*
      * Deliver the DGA event
      */
@@ -1084,6 +1087,9 @@ DGAProcessPointerEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr mouse)
 
     UpdateDeviceState(mouse, &ev);
 
+    if (!IsMaster(mouse))
+        return;
+
     /*
      * Deliver the DGA event
      */
@@ -1191,9 +1197,6 @@ DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
     if (!pScreenPriv)
         return;
 
-    if (!IsMaster(device))
-        return;
-
     switch (event->subtype) {
     case KeyPress:
     case KeyRelease:
commit c5f2818edbec2f87383baa6c6be5c389b73ca6f9
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jan 8 10:13:53 2013 +1000

    xfree86: set event->detail for DGA pointer events
    
    Reported-by: Steven Elliott <selliott4 at austin.rr.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index c25a274..c10dd32 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1074,6 +1074,7 @@ DGAProcessPointerEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr mouse)
     DeviceEvent ev = {
         .header = ET_Internal,
         .length = sizeof(ev),
+        .detail.key = event->detail,
         .type = event->subtype,
         .corestate = butc ? butc->state : 0
     };
commit 519d183d78e0b0eaf47a473e94f5d8611baf8463
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jan 7 10:44:33 2013 +1000

    Fix two typos "requires an string value"
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index c2ec79a..40c9d15 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -515,7 +515,7 @@ ParseOptionValue(int scrnIndex, XF86OptionPtr options, OptionInfoPtr p,
             if (*s == '\0') {
                 if (markUsed) {
                     xf86DrvMsg(scrnIndex, X_WARNING,
-                               "Option \"%s\" requires an string value\n",
+                               "Option \"%s\" requires a string value\n",
                                p->name);
                 }
                 p->found = FALSE;
diff --git a/hw/xwin/winconfig.c b/hw/xwin/winconfig.c
index 313320f..9e38113 100644
--- a/hw/xwin/winconfig.c
+++ b/hw/xwin/winconfig.c
@@ -762,7 +762,7 @@ ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p)
         case OPTV_STRING:
             if (*s == '\0') {
                 winDrvMsg(scrnIndex, X_WARNING,
-                          "Option \"%s\" requires an string value\n", p->name);
+                          "Option \"%s\" requires a string value\n", p->name);
                 p->found = FALSE;
             }
             else {
commit 4e13dd90144dde47550aceea4db4b4329e531279
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Aug 22 10:34:07 2012 +1000

    dix: don't filter RawEvents if the grab window is not the root window (#53897)
    
    If a XI2.1+ client has a grab on a non-root window, it  must still receive
    raw events on the root window.
    
    Test case: register for XI_ButtonPress on window and XI_RawMotion on root.
    No raw events are received once the press activates an implicit grab on the
    window.
    
    X.Org Bug 53897 <http://bugs.freedesktop.org/show_bug.cgi?id=53897>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/events.c b/dix/events.c
index 7359362..adbb762 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2246,7 +2246,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
  * @return TRUE if the event should be discarded, FALSE otherwise.
  */
 static BOOL
-FilterRawEvents(const ClientPtr client, const GrabPtr grab)
+FilterRawEvents(const ClientPtr client, const GrabPtr grab, WindowPtr root)
 {
     XIClientPtr client_xi_version;
     int cmp;
@@ -2262,7 +2262,10 @@ FilterRawEvents(const ClientPtr client, const GrabPtr grab)
                           client_xi_version->minor_version, 2, 0);
     /* XI 2.0: if device is grabbed, skip
        XI 2.1: if device is grabbed by us, skip, we've already delivered */
-    return (cmp == 0) ? TRUE : SameClient(grab, client);
+    if (cmp == 0)
+        return TRUE;
+
+    return (grab->window != root) ? FALSE : SameClient(grab, client);
 }
 
 /**
@@ -2315,7 +2318,7 @@ DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
              */
             ic.next = NULL;
 
-            if (!FilterRawEvents(rClient(&ic), grab))
+            if (!FilterRawEvents(rClient(&ic), grab, root))
                 DeliverEventToInputClients(device, &ic, root, xi, 1,
                                            filter, NULL, &c, &m);
         }
commit a2037d7080ae64ea55f7d76971716346aa3ec6d3
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Wed Nov 28 22:25:35 2012 +0000

    hw/xwin: Fix MinGW build of winSetAppModelID.c
    
    Add missing #include <pthread.h>
    
    In file included from /jhbuild/checkout/xorg/xserver/hw/xwin/winSetAppUserModelID.c:31:0:
    /jhbuild/checkout/xorg/xserver/hw/xwin/winwindow.h:140:11: error: expected declaration specifiers or ‘...’ before ‘pthread_t’
    /jhbuild/checkout/xorg/xserver/hw/xwin/winwindow.h:141:11: error: expected declaration specifiers or ‘...’ before ‘pthread_t’
    /jhbuild/checkout/xorg/xserver/hw/xwin/winwindow.h:142:11: error: expected declaration specifiers or ‘...’ before ‘pthread_mutex_t’
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winSetAppUserModelID.c b/hw/xwin/winSetAppUserModelID.c
index ce9da5e..41615e1 100644
--- a/hw/xwin/winSetAppUserModelID.c
+++ b/hw/xwin/winSetAppUserModelID.c
@@ -28,6 +28,7 @@
 #include <X11/Xlib.h>
 #include <X11/Xproto.h>
 #include <X11/Xwindows.h>
+#include <pthread.h>
 #include "winwindow.h"
 #include "os.h"
 #include "winmsg.h"
commit f57100bb36eae3b4d75f3c315973405f705b8de6
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Feb 23 13:38:48 2010 +0000

    hw/xwin: Process one Windows message per wakeup, rather than all of them.
    
    De-queuing Windows messages and X events happens in the same thread of
    execution.  Draining the windows message queue can lead to the X event queue
    overflowing if lots of those windows messages cause X events (e.g. if a keyboard
    macro program has just dumped thousands of keypresses into the Windows message
    queue).  See the mailing list thread [1] for more details.
    
    Processing one Windows message per wakeup, rather than all of them gives the X
    server a chance to do stuff as well after each message.
    
    [1] http://cygwin.com/ml/cygwin-xfree/2010-01/msg00056.html
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winblock.c b/hw/xwin/winblock.c
index a4ae866..c3ef4be 100644
--- a/hw/xwin/winblock.c
+++ b/hw/xwin/winblock.c
@@ -42,14 +42,26 @@ winBlockHandler(ScreenPtr pScreen,
 #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
     winScreenPriv(pScreen);
 #endif
-    MSG msg;
 
 #ifndef HAS_DEVWINDOWS
     struct timeval **tvp = pTimeout;
 
     if (*tvp != NULL) {
+      if (GetQueueStatus(QS_ALLINPUT | QS_ALLPOSTMESSAGE) != 0) {
+        /* If there are still messages to process on the Windows message
+           queue, make sure select() just polls rather than blocking.
+        */
+        (*tvp)->tv_sec = 0;
+        (*tvp)->tv_usec = 0;
+      }
+      else {
+        /* Otherwise, lacking /dev/windows, we must wake up again in
+           a reasonable time to check the Windows message queue. without
+           noticeable delay.
+         */
         (*tvp)->tv_sec = 0;
         (*tvp)->tv_usec = 100;
+      }
     }
 #endif
 
@@ -68,24 +80,12 @@ winBlockHandler(ScreenPtr pScreen,
         if (iReturn != 0) {
             ErrorF("winBlockHandler - pthread_mutex_unlock () failed: %d\n",
                    iReturn);
-            goto winBlockHandler_ProcessMessages;
         }
-
-        winDebug("winBlockHandler - pthread_mutex_unlock () returned\n");
-    }
-
- winBlockHandler_ProcessMessages:
-#endif
-
-    /* Process all messages on our queue */
-    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
-        if ((g_hDlgDepthChange == 0
-             || !IsDialogMessage(g_hDlgDepthChange, &msg))
-            && (g_hDlgExit == 0 || !IsDialogMessage(g_hDlgExit, &msg))
-            && (g_hDlgAbout == 0 || !IsDialogMessage(g_hDlgAbout, &msg))) {
-            DispatchMessage(&msg);
+        else {
+            winDebug("winBlockHandler - pthread_mutex_unlock () returned\n");
         }
     }
+#endif
 
   /*
     At least one X client has asked to suspend the screensaver, so
diff --git a/hw/xwin/winwakeup.c b/hw/xwin/winwakeup.c
index 77c1605..795221a 100644
--- a/hw/xwin/winwakeup.c
+++ b/hw/xwin/winwakeup.c
@@ -43,8 +43,8 @@ winWakeupHandler(ScreenPtr pScreen,
 {
     MSG msg;
 
-    /* Process all messages on our queue */
-    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+    /* Process one message from our queue */
+    if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
         if ((g_hDlgDepthChange == 0
              || !IsDialogMessage(g_hDlgDepthChange, &msg))
             && (g_hDlgExit == 0 || !IsDialogMessage(g_hDlgExit, &msg))
commit e30e1ea98720acc583f34c830a1c1b7e3e88f694
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Mon Dec 17 22:38:25 2012 +0000

    hw/xwin: Fix some comments in winkeybd.c
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index a70cdcd..27c114c 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -56,7 +56,7 @@ static void
 static void
  winKeybdCtrl(DeviceIntPtr pDevice, KeybdCtrl * pCtrl);
 
-/* 
+/*
  * Translate a Windows WM_[SYS]KEY(UP/DOWN) message
  * into an ASCII scan code.
  *
@@ -134,7 +134,7 @@ winKeybdCtrl(DeviceIntPtr pDevice, KeybdCtrl * pCtrl)
 {
 }
 
-/* 
+/*
  * See Porting Layer Definition - p. 18
  * winKeybdProc is known as a DeviceProc.
  */
@@ -509,8 +509,8 @@ winCheckKeyPressed(WPARAM wParam, LPARAM lParam)
     return FALSE;
 }
 
-/* Only on shift release message is sent even if both are pressed.
- * Fix this here 
+/* Only one shift release message is sent even if both are pressed.
+ * Fix this here
  */
 void
 winFixShiftKeys(int iScanCode)
commit 6f4a48f8a55bc54b6d3e9d80734be05750c024de
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Thu Apr 1 15:08:26 2010 +0100

    hw/xwin: Bring the X screen window to the front on a single left-click on the tray icon
    
    Bring the X screen window to the front on a single left click on the tray icon,
    like the comment says we do
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Colin Harrison <colin.harrison at virgin.net>

diff --git a/hw/xwin/wintrayicon.c b/hw/xwin/wintrayicon.c
index dbc4725..f168b88 100644
--- a/hw/xwin/wintrayicon.c
+++ b/hw/xwin/wintrayicon.c
@@ -114,7 +114,7 @@ winHandleIconMessage(HWND hwnd, UINT message,
     switch (lParam) {
     case WM_LBUTTONUP:
         /* Restack and bring all windows to top */
-        SetForegroundWindow(hwnd);
+        SetForegroundWindow (pScreenPriv->hwndScreen);
 
 #ifdef XWIN_MULTIWINDOWEXTWM
         if (pScreenInfo->fMWExtWM)
commit 6703a7c7cf1a349c137e247a0c8eb462ff7b07be
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Jan 8 20:24:32 2013 -0800

    hw/xfree86: Require only one working CRTC to start the server.
    
    Instead of requiring every mode set to complete successfully, start up
    as long as at least one CRTC is working. This avoids failures when one
    or more CRTCs can't start due to mode setting conflicts.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Dave Airlie <airlied at redhat.com>

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 13251cf..b3ded5a 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2605,6 +2605,7 @@ xf86SetDesiredModes(ScrnInfoPtr scrn)
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
     xf86CrtcPtr crtc = config->crtc[0];
     int c;
+    int enabled = 0;
 
     /* A driver with this hook will take care of this */
     if (!crtc->funcs->set_mode_major) {
@@ -2655,14 +2656,20 @@ xf86SetDesiredModes(ScrnInfoPtr scrn)
             transform = &crtc->desiredTransform;
         else
             transform = NULL;
-        if (!xf86CrtcSetModeTransform
+        if (xf86CrtcSetModeTransform
             (crtc, &crtc->desiredMode, crtc->desiredRotation, transform,
-             crtc->desiredX, crtc->desiredY))
-            return FALSE;
+             crtc->desiredX, crtc->desiredY)) {
+            ++enabled;
+        } else {
+            for (o = 0; o < config->num_output; o++)
+                if (config->output[o]->crtc == crtc)
+                    config->output[o]->crtc = NULL;
+            crtc->enabled = FALSE;
+	}
     }
 
     xf86DisableUnusedFunctions(scrn);
-    return TRUE;
+    return enabled != 0;
 }
 
 /**
commit 0e1ab433f4048b3367bb2f01d16cd00502538e4d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 4 12:26:58 2013 +1000

    dix: remove already-moved hunk
    
    Should've been removed in bc1f90a615018c05994fae3e678dd2341256cd82a, but got
    left here due to a botched rebase.
    
    Fixes stray button events sent to clients after deactivating an async
    pointer grab on a pointer-emulating-touch.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/events.c b/dix/events.c
index b742f67..a46aaf6 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1551,15 +1551,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
         ReattachToOldMaster(mouse);
 
     ComputeFreezes();
-
-    /* If an explicit grab was deactivated, we must remove it from the head of
-     * all the touches' listener lists. */
-    for (i = 0; mouse->touch && i < mouse->touch->num_touches; i++) {
-        TouchPointInfoPtr ti = mouse->touch->touches + i;
-
-        if (ti->active && TouchResourceIsOwner(ti, grab_resource))
-            TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
-    }
 }
 
 /**
commit 32a6d8a6b59c42f8d65002d7ca1cafb1957b656f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 20 16:25:43 2012 +1000

    dix: check for the right device's xi2 mask
    
    events.c: In function 'DeactivatePointerGrab':
    events.c:1524:51: warning: 'dev' may be used uninitialized in this function
    [-Wuninitialized
    
    dev is unset when we get here, the device to check is "mouse".
    Introduced in ece8157a59751b3ed492fb2e1eb8d5f20221e195.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/events.c b/dix/events.c
index bea68cc..b742f67 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1522,7 +1522,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
                emulate a ButtonRelease here. So pretend the listener
                already has the end event */
             if (grab->grabtype == CORE || grab->grabtype == XI ||
-                    !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))
+                    !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin))
                 ti->listeners[0].state = LISTENER_HAS_END;
             TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
         }
commit f59499b5d05fde83813709e9848152951592120d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Oct 30 12:44:08 2012 +1000

    dix: add resource type to touch listeners
    
    Instead of guessing what resource type the listener is and what property to
    retrieve, store the resource type in the listener directly.
    
    Breaks XIT test cases:
    TouchGrabTestMultipleTaps.PassiveGrabPointerEmulationMultipleTouchesFastSuccession
    
    Fixes https://bugs.freedesktop.org/show_bug.cgi?id=56557
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Chase Douglas <chase.douglas at ubuntu.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 22bb563..74f3610 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1305,13 +1305,9 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
         *mask = (*grab)->xi2mask;
     }
     else {
-        if (listener->level == CORE)
-            rc = dixLookupWindow(win, listener->listener,
-                                 serverClient, DixSendAccess);
-        else
-            rc = dixLookupResourceByType((pointer *) win, listener->listener,
-                                         RT_INPUTCLIENT,
-                                         serverClient, DixSendAccess);
+        rc = dixLookupResourceByType((pointer *) win, listener->listener,
+                                     listener->resource_type,
+                                     serverClient, DixSendAccess);
         if (rc != Success)
             return FALSE;
 
@@ -1452,6 +1448,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
             l = &ti->listeners[ti->num_listeners - 1];
             l->listener = devgrab->resource;
             l->grab = devgrab;
+            //l->resource_type = RT_NONE;
 
             if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
                 l->type = LISTENER_POINTER_GRAB;
diff --git a/dix/touch.c b/dix/touch.c
index 99f105b..0db842c 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -675,12 +675,13 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource)
  * Add the resource to this touch's listeners.
  */
 void
-TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level,
-                 enum TouchListenerType type, enum TouchListenerState state,
-                 WindowPtr window,
+TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
+                 enum InputLevel level, enum TouchListenerType type,
+                 enum TouchListenerState state, WindowPtr window,
                  GrabPtr grab)
 {
     ti->listeners[ti->num_listeners].listener = resource;
+    ti->listeners[ti->num_listeners].resource_type = resource_type;
     ti->listeners[ti->num_listeners].level = level;
     ti->listeners[ti->num_listeners].state = state;
     ti->listeners[ti->num_listeners].type = type;
@@ -741,7 +742,8 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
         type = LISTENER_POINTER_GRAB;
     }
 
-    TouchAddListener(ti, grab->resource, grab->grabtype,
+    /* grab listeners are always RT_NONE since we keep the grab pointer */
+    TouchAddListener(ti, grab->resource, RT_NONE, grab->grabtype,
                      type, LISTENER_AWAITING_BEGIN, grab->window, grab);
 }
 
@@ -797,7 +799,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
             if (!xi2mask_isset(iclients->xi2mask, dev, XI_TouchOwnership))
                 TouchEventHistoryAllocate(ti);
 
-            TouchAddListener(ti, iclients->resource, XI2,
+            TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI2,
                              type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
@@ -812,7 +814,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 continue;
 
             TouchEventHistoryAllocate(ti);
-            TouchAddListener(ti, iclients->resource, XI,
+            TouchAddListener(ti, iclients->resource, RT_INPUTCLIENT, XI,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
                              win, NULL);
             return TRUE;
@@ -827,7 +829,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
         /* window owner */
         if (IsMaster(dev) && (win->eventMask & core_filter)) {
             TouchEventHistoryAllocate(ti);
-            TouchAddListener(ti, win->drawable.id, CORE,
+            TouchAddListener(ti, win->drawable.id, RT_WINDOW, CORE,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
                              win, NULL);
             return TRUE;
@@ -839,7 +841,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 continue;
 
             TouchEventHistoryAllocate(ti);
-            TouchAddListener(ti, oclients->resource, CORE,
+            TouchAddListener(ti, oclients->resource, RT_OTHERCLIENT, CORE,
                              type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
diff --git a/include/input.h b/include/input.h
index 79739e2..f53ed99 100644
--- a/include/input.h
+++ b/include/input.h
@@ -565,7 +565,7 @@ extern void TouchEventHistoryPush(TouchPointInfoPtr ti, const DeviceEvent *ev);
 extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev,
                                     XID resource);
 extern Bool TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource);
-extern void TouchAddListener(TouchPointInfoPtr ti, XID resource,
+extern void TouchAddListener(TouchPointInfoPtr ti, XID resource, int resource_type,
                              enum InputLevel level, enum TouchListenerType type,
                              enum TouchListenerState state, WindowPtr window, GrabPtr grab);
 extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource);
diff --git a/include/inputstr.h b/include/inputstr.h
index 32d7b62..fc21913 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -301,6 +301,7 @@ typedef struct _ValuatorClassRec {
 typedef struct _TouchListener {
     XID listener;           /* grabs/event selection IDs receiving
                              * events for this touch */
+    int resource_type;      /* listener's resource type */
     enum TouchListenerType type;
     enum TouchListenerState state;
     enum InputLevel level;  /* matters only for emulating touches */
commit 9ad0fdb135a1c336771aee1f6eab75a6ad874aff
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 27 11:21:17 2012 -0800

    input: Record grab pointer in TouchListener
    
    This places a pointer to the grab related to a TouchListener directly
    in the TouchListener structure rather than hoping to find the grab
    later on using the resource ID.
    
    Passive grabs have resource ID in the resource DB so they can be
    removed when a client exits, and those resource IDs get copied when
    activated, but implicit grabs are constructed on-the-fly and have no
    resource DB entry.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 58fe493..22bb563 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1187,7 +1187,6 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
               TouchOwnershipEvent *ev)
 {
     Bool was_owner = (resource == ti->listeners[0].listener);
-    void *grab;
     int i;
 
     /* Send a TouchEnd event to the resource being removed, but only if they
@@ -1202,11 +1201,7 @@ TouchRejected(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, XID resource,
 
     /* Remove the resource from the listener list, updating
      * ti->num_listeners, as well as ti->num_grabs if it was a grab. */
-    if (TouchRemoveListener(ti, resource)) {
-        if (dixLookupResourceByType(&grab, resource, RT_PASSIVEGRAB,
-                                    serverClient, DixGetAttrAccess) == Success)
-            ti->num_grabs--;
-    }
+    TouchRemoveListener(ti, resource);
 
     /* If the current owner was removed and there are further listeners, deliver
      * the TouchOwnership or TouchBegin event to the new owner. */
@@ -1300,21 +1295,10 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
     if (listener->type == LISTENER_GRAB ||
         listener->type == LISTENER_POINTER_GRAB) {
-        rc = dixLookupResourceByType((pointer *) grab, listener->listener,
-                                     RT_PASSIVEGRAB,
-                                     serverClient, DixSendAccess);
-        if (rc != Success) {
-            /* the grab doesn't exist but we have a grabbing listener - this
-             * is an implicit/active grab */
-            rc = dixLookupClient(client, listener->listener, serverClient,
-                                 DixSendAccess);
-            if (rc != Success)
-                return FALSE;
-
-            *grab = dev->deviceGrab.grab;
-            if (!*grab)
-                return FALSE;
-        }
+
+        *grab = listener->grab;
+
+        BUG_RETURN_VAL(!*grab, FALSE);
 
         *client = rClient(*grab);
         *win = (*grab)->window;
@@ -1467,6 +1451,7 @@ DeliverTouchEmulatedEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
              */
             l = &ti->listeners[ti->num_listeners - 1];
             l->listener = devgrab->resource;
+            l->grab = devgrab;
 
             if (devgrab->grabtype != XI2 || devgrab->type != XI_TouchBegin)
                 l->type = LISTENER_POINTER_GRAB;
diff --git a/dix/events.c b/dix/events.c
index 7359362..bea68cc 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1438,6 +1438,7 @@ UpdateTouchesForGrab(DeviceIntPtr mouse)
                 ti->listeners[0].type = LISTENER_POINTER_GRAB;
             else
                 ti->listeners[0].type = LISTENER_GRAB;
+            ti->listeners[0].grab = grab;
         }
     }
 }
diff --git a/dix/touch.c b/dix/touch.c
index d890b62..99f105b 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -677,13 +677,17 @@ TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource)
 void
 TouchAddListener(TouchPointInfoPtr ti, XID resource, enum InputLevel level,
                  enum TouchListenerType type, enum TouchListenerState state,
-                 WindowPtr window)
+                 WindowPtr window,
+                 GrabPtr grab)
 {
     ti->listeners[ti->num_listeners].listener = resource;
     ti->listeners[ti->num_listeners].level = level;
     ti->listeners[ti->num_listeners].state = state;
     ti->listeners[ti->num_listeners].type = type;
     ti->listeners[ti->num_listeners].window = window;
+    ti->listeners[ti->num_listeners].grab = grab;
+    if (grab)
+        ti->num_grabs++;
     ti->num_listeners++;
 }
 
@@ -702,6 +706,11 @@ TouchRemoveListener(TouchPointInfoPtr ti, XID resource)
         if (ti->listeners[i].listener == resource) {
             int j;
 
+            if (ti->listeners[i].grab) {
+                ti->listeners[i].grab = NULL;
+                ti->num_grabs--;
+            }
+
             for (j = i; j < ti->num_listeners - 1; j++)
                 ti->listeners[j] = ti->listeners[j + 1];
             ti->num_listeners--;
@@ -733,8 +742,7 @@ TouchAddGrabListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
     }
 
     TouchAddListener(ti, grab->resource, grab->grabtype,
-                     type, LISTENER_AWAITING_BEGIN, grab->window);
-    ti->num_grabs++;
+                     type, LISTENER_AWAITING_BEGIN, grab->window, grab);
 }
 
 /**
@@ -790,7 +798,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
                 TouchEventHistoryAllocate(ti);
 
             TouchAddListener(ti, iclients->resource, XI2,
-                             type, LISTENER_AWAITING_BEGIN, win);
+                             type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
     }
@@ -806,7 +814,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
             TouchEventHistoryAllocate(ti);
             TouchAddListener(ti, iclients->resource, XI,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
-                             win);
+                             win, NULL);
             return TRUE;
         }
     }
@@ -821,7 +829,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
             TouchEventHistoryAllocate(ti);
             TouchAddListener(ti, win->drawable.id, CORE,
                              LISTENER_POINTER_REGULAR, LISTENER_AWAITING_BEGIN,
-                             win);
+                             win, NULL);
             return TRUE;
         }
 
@@ -832,7 +840,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
 
             TouchEventHistoryAllocate(ti);
             TouchAddListener(ti, oclients->resource, CORE,
-                             type, LISTENER_AWAITING_BEGIN, win);
+                             type, LISTENER_AWAITING_BEGIN, win, NULL);
             return TRUE;
         }
     }
diff --git a/include/input.h b/include/input.h
index 23a20b5..79739e2 100644
--- a/include/input.h
+++ b/include/input.h
@@ -567,7 +567,7 @@ extern void TouchEventHistoryReplay(TouchPointInfoPtr ti, DeviceIntPtr dev,
 extern Bool TouchResourceIsOwner(TouchPointInfoPtr ti, XID resource);
 extern void TouchAddListener(TouchPointInfoPtr ti, XID resource,
                              enum InputLevel level, enum TouchListenerType type,
-                             enum TouchListenerState state, WindowPtr window);
+                             enum TouchListenerState state, WindowPtr window, GrabPtr grab);
 extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource);
 extern void TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti,
                                 InternalEvent *ev);
diff --git a/include/inputstr.h b/include/inputstr.h
index a9d46cc..32d7b62 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -305,6 +305,7 @@ typedef struct _TouchListener {
     enum TouchListenerState state;
     enum InputLevel level;  /* matters only for emulating touches */
     WindowPtr window;
+    GrabPtr grab;
 } TouchListener;
 
 typedef struct _TouchPointInfo {
commit 91ab237358c6e33da854914d3de493a9cbea7637
Author: Keith Packard <keithp at keithp.com>
Date:   Tue Nov 27 11:21:16 2012 -0800

    input: Pull TouchListener declaration to top-level
    
    No reason to have a struct declared inside another struct
    
    Signed-off-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/inputstr.h b/include/inputstr.h
index 17cee98..a9d46cc 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -298,6 +298,15 @@ typedef struct _ValuatorClassRec {
     int v_scroll_axis;          /* vert smooth-scrolling axis */
 } ValuatorClassRec;
 
+typedef struct _TouchListener {
+    XID listener;           /* grabs/event selection IDs receiving
+                             * events for this touch */
+    enum TouchListenerType type;
+    enum TouchListenerState state;
+    enum InputLevel level;  /* matters only for emulating touches */
+    WindowPtr window;
+} TouchListener;
+
 typedef struct _TouchPointInfo {
     uint32_t client_id;         /* touch ID as seen in client events */
     int sourceid;               /* Source device's ID for this touchpoint */
@@ -306,14 +315,7 @@ typedef struct _TouchPointInfo {
                                  * but still owned by a grab */
     SpriteRec sprite;           /* window trace for delivery */
     ValuatorMask *valuators;    /* last recorded axis values */
-    struct _TouchListener {
-        XID listener;           /* grabs/event selection IDs receiving
-                                 * events for this touch */
-        enum TouchListenerType type;
-        enum TouchListenerState state;
-        enum InputLevel level;  /* matters only for emulating touches */
-        WindowPtr window;
-    } *listeners;
+    TouchListener *listeners;   /* set of listeners */
     int num_listeners;
     int num_grabs;              /* number of open grabs on this touch
                                  * which have not accepted or rejected */
commit 3578cc3c2e1b5cb8eb191e2d12ad88e1bc9e6e1e
Author: Andreas Wettstein <wettstein509 at solnet.ch>
Date:   Wed Dec 19 18:13:21 2012 +0100

    xkb: Do not use base group as an array index.
    
    The base group is not brought into range and, therefore, using it as an array
    index crashed the X server.  Also, at this place, we should ignore locked
    groups, but not latched groups.  Therefore, use sum of base and latched groups,
    brought into range.
    
    Reproducible with:
    key <FK07> {
        type= "ONE_LEVEL",
        symbols[Group1]= [              NoSymbol ],
        actions[Group1]= [ LatchGroup(group=-1, clearLocks) ]
    };
    
    And hitting F7 will exceed the group level and access arbitrary memory.
    
    Signed-off-by: Andreas Wettstein <wettstein509 at solnet.ch>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index c23cd77..6c6af60 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -642,6 +642,7 @@ XkbComputeCompatState(XkbSrvInfoPtr xkbi)
     CARD16 grp_mask;
     XkbStatePtr state = &xkbi->state;
     XkbCompatMapPtr map;
+    XkbControlsPtr ctrls;
 
     if (!state || !xkbi->desc || !xkbi->desc->ctrls || !xkbi->desc->compat)
         return;
@@ -650,9 +651,14 @@ XkbComputeCompatState(XkbSrvInfoPtr xkbi)
     grp_mask = map->groups[state->group].mask;
     state->compat_state = state->mods | grp_mask;
     state->compat_lookup_mods = state->lookup_mods | grp_mask;
+    ctrls= xkbi->desc->ctrls;
 
-    if (xkbi->desc->ctrls->enabled_ctrls & XkbIgnoreGroupLockMask)
-        grp_mask = map->groups[state->base_group].mask;
+    if (ctrls->enabled_ctrls & XkbIgnoreGroupLockMask) {
+	unsigned char grp = state->base_group+state->latched_group;
+	if (grp >= ctrls->num_groups)
+	    grp = XkbAdjustGroup(XkbCharToInt(grp), ctrls);
+        grp_mask = map->groups[grp].mask;
+    }
     state->compat_grab_mods = state->grab_mods | grp_mask;
     return;
 }
commit df746a73410b892a4d41a2934cf9cd2e8ad7ba51
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Dec 19 18:42:39 2012 +0100

    render: Unwrap early on the animated cursor BlockHandler
    
    The loop above the previous call may end up triggering other
    handlers attaching to the same function slot, so unwrapping
    the handler after that could leave the just attached handler
    in a dangling but not unset state.
    
    This issue was most visible on the XO, where destroying a
    window with an animated cursor set and running  would trigger
    this inconsistent state, never calling the miSpriteBlockHandler
    again after the animated cursor is unset.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/render/animcur.c b/render/animcur.c
index ebc5b8e..9cbba83 100644
--- a/render/animcur.c
+++ b/render/animcur.c
@@ -143,6 +143,8 @@ AnimCurScreenBlockHandler(ScreenPtr pScreen,
     Bool activeDevice = FALSE;
     CARD32 now = 0, soonest = ~0;       /* earliest time to wakeup again */
 
+    Unwrap(as, pScreen, BlockHandler);
+
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if (IsPointerDevice(dev) && pScreen == dev->spriteInfo->anim.pScreen) {
             if (!activeDevice) {
@@ -180,7 +182,6 @@ AnimCurScreenBlockHandler(ScreenPtr pScreen,
     if (activeDevice)
         AdjustWaitForDelay(pTimeout, soonest - now);
 
-    Unwrap(as, pScreen, BlockHandler);
     (*pScreen->BlockHandler) (pScreen, pTimeout, pReadmask);
     if (activeDevice)
         Wrap(as, pScreen, BlockHandler, AnimCurScreenBlockHandler);
commit 0fbd779a82919d5dbf8776be9b57a76c0eae6b14
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Wed Dec 19 18:42:38 2012 +0100

    mi: Ensure pointer emulating touch events update the sprite
    
    Different miPointerSpriteFuncRec implementations do a varying
    business at ultimately calling miPointerUpdateSprite(), this
    particularly fails when using the plain mi sprite on touch events,
    where the sprite is just moved/updated on cursor changes.
    
    So, ensure miPointerUpdateSprite() is called generically for
    pointer emulating touch events as with regular motion events.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mieq.c b/mi/mieq.c
index 22f8c91..d7d73de 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -627,7 +627,11 @@ mieqProcessInputEvents(void)
         mieqProcessDeviceEvent(dev, &event, screen);
 
         /* Update the sprite now. Next event may be from different device. */
-        if (event.any.type == ET_Motion && master)
+        if (master &&
+            (event.any.type == ET_Motion ||
+             ((event.any.type == ET_TouchBegin ||
+               event.any.type == ET_TouchUpdate) &&
+              event.device_event.flags & TOUCH_POINTER_EMULATED)))
             miPointerUpdateSprite(dev);
 
 #ifdef XQUARTZ
commit 8b328d4ee3873bc0a7a34f2cb9d301827244b98c
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Fri Dec 21 07:37:33 2012 -0800

    dix: Make small bitfields that store enums unsigned
    
    Commit 31bf81772e146af79b0c456aae2159eba8b0280f changed the clientState field
    from a signed int to a signed int 2-bit bitfield.  The ClientState enum that is
    expected to be assigned to this field has four values: ClientStateInitial (0),
    ClientStateRunning (1), ClientStateRetained (2), and ClientStateGone (3).
    However, because this bitfield is signed, ClientStateRetained becomes -2 when
    assigned, and ClientStateGone becomes -1.  This causes warnings:
    
     test.c:54:10: error: case label value exceeds maximum value for type [-Werror]
     test.c:55:10: error: case label value exceeds maximum value for type [-Werror]
    
    The code here is a switch statement:
    
     53     switch (client->clientState) {
     54     case ClientStateGone:
     55     case ClientStateRetained:
     56         [...]
     57         break;
     58
     59     default:
     60         [...]
     61         break;
     62     }
    
    It also causes bizarre problems like this:
    
     client->clientState = ClientStateGone;
     assert(client->clientState == ClientStateGone); // this assert fails
    
    Also change the signedness of nearby bitfields to match.
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
    Reviewed-by:  Colin Harrison <colin.harrison at virgin.net>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/include/dixstruct.h b/include/dixstruct.h
index c1236f5..6784819 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -90,12 +90,12 @@ typedef struct _Client {
     Mask clientAsMask;
     short index;
     unsigned char majorOp, minorOp;
-    int swapped:1;
-    int local:1;
-    int big_requests:1;          /* supports large requests */
-    int clientGone:1;
-    int closeDownMode:2;
-    int clientState:2;
+    unsigned int swapped:1;
+    unsigned int local:1;
+    unsigned int big_requests:1; /* supports large requests */
+    unsigned int clientGone:1;
+    unsigned int closeDownMode:2;
+    unsigned int clientState:2;
     char smart_priority;
     short noClientException;      /* this client died or needs to be killed */
     int priority;
commit 8f4820be7a2e0f6e286ddc85c4b75bccdbe8a730
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Dec 20 12:44:16 2012 +1000

    test/xi2: fix compiler warning
    
    protocol-xiwarppointer.c: In function ‘ScreenSetCursorPosition’:
    protocol-xiwarppointer.c:71:53: warning: declaration of ‘screen’ shadows a
    global declaration [-Wshadow]
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/xi2/protocol-xiwarppointer.c b/test/xi2/protocol-xiwarppointer.c
index 4bea333..f7986c1 100644
--- a/test/xi2/protocol-xiwarppointer.c
+++ b/test/xi2/protocol-xiwarppointer.c
@@ -68,7 +68,7 @@ __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, Mask access)
  * This function overrides the one in the screen rec.
  */
 static Bool
-ScreenSetCursorPosition(DeviceIntPtr dev, ScreenPtr screen,
+ScreenSetCursorPosition(DeviceIntPtr dev, ScreenPtr scr,
                         int x, int y, Bool generateEvent)
 {
     assert(x == expected_x);


More information about the Xquartz-changes mailing list