xserver: Branch 'master' - 27 commits

Jeremy Huddleston jeremyhu at apple.com
Fri Mar 23 17:57:19 PDT 2012


make check is failing on my linux/ppc and linux/ppc64 boxes with this push:

FAIL: xtest

http://tinderbox.x.org/builds/2012-03-23-0002/logs/xserver/#check

On Mar 22, 2012, at 14:36, Keith Packard wrote:

> Xext/saver.c                           |    7 -
> Xext/sync.c                            |  202 +++++++++++++++++++--------------
> Xext/syncsrv.h                         |   58 ++++-----
> Xext/xtest.c                           |   10 +
> Xi/exevents.c                          |   26 ++--
> Xi/xiqueryversion.c                    |    9 +
> dix/Xserver-dtrace.h.in                |    7 -
> dix/Xserver.d                          |    2 
> dix/devices.c                          |    8 +
> dix/events.c                           |   15 +-
> dix/getevents.c                        |   58 ++++++++-
> dix/globals.c                          |    2 
> dix/touch.c                            |    3 
> dix/window.c                           |    4 
> doc/dtrace/Xserver-DTrace.xml          |  153 ++++++++++++++++++++++++
> hw/kdrive/src/kinput.c                 |    3 
> hw/xfree86/os-support/linux/lnx_init.c |    3 
> include/dix.h                          |    3 
> include/dixstruct.h                    |    2 
> include/input.h                        |    3 
> include/inputstr.h                     |    2 
> include/os.h                           |    1 
> os/WaitFor.c                           |    2 
> os/log.c                               |    5 
> os/xdmcp.c                             |    2 
> xkb/xkbActions.c                       |   26 +++-
> 26 files changed, 457 insertions(+), 159 deletions(-)
> 
> New commits:
> commit a7eac500e652f30deffd9dc5e623fab701077738
> Merge: bf876c8... d645edd...
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Thu Mar 22 13:13:07 2012 +1000
> 
>    Merge branch 'per-device-sync-counters' into for-keith
> 
> commit d645edd11e7482f98c8b7e0d6c8693285c484907
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Mar 12 16:36:31 2012 +1000
> 
>    Xext: Add per-device SyncCounters
> 
>    Previously, we only had one idle alarm that was triggered for all devices,
>    whenever the user used any device, came back from suspend, etc.
> 
>    Add system SyncCounters for each device (named "DEVICEIDLETIME x", with x
>    being the device id) that trigger on that device only. This allows for
>    enabling/disabling devices based on interaction with other devices.
> 
>    Popular use-case: disable the touchpad when the keyboard just above the
>    touchpad stops being idle.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Jamey Sharp <jamey at minilop.net>
>    Reviewed-by: James Jones <jajones at nvidia.com>
> 
> diff --git a/Xext/sync.c b/Xext/sync.c
> index 8217e76..91968e4 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -69,6 +69,7 @@ PERFORMANCE OF THIS SOFTWARE.
> #include "syncsrv.h"
> #include "syncsdk.h"
> #include "protocol-versions.h"
> +#include "inputstr.h"
> 
> #include <stdio.h>
> #if !defined(WIN32)
> @@ -2594,13 +2595,23 @@ SyncInitServerTime(void)
> typedef struct {
>     XSyncValue *value_less;
>     XSyncValue *value_greater;
> +    int deviceid;
> } IdleCounterPriv;
> 
> static void
> IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
> {
> -    CARD32 idle = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds;
> +    int deviceid;
> +    CARD32 idle;
> 
> +    if (pCounter) {
> +        SyncCounter *counter = pCounter;
> +        IdleCounterPriv *priv = SysCounterGetPrivate(counter);
> +        deviceid = priv->deviceid;
> +    }
> +    else
> +        deviceid = XIAllDevices;
> +    idle = GetTimeInMillis() - lastDeviceEventTime[deviceid].milliseconds;
>     XSyncIntsToValue(pValue_return, idle, 0);
> }
> 
> @@ -2692,7 +2703,7 @@ IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
>     if (!less && !greater)
>         return;
> 
> -    IdleTimeQueryValue(NULL, &idle);
> +    IdleTimeQueryValue(pCounter, &idle);
> 
>     if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) ||
>         (less && XSyncValueLessOrEqual(idle, *less))) {
> @@ -2723,8 +2734,8 @@ IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less,
>     priv->value_less = pbracket_less;
> }
> 
> -static void
> -SyncInitIdleTime(void)
> +static SyncCounter*
> +init_system_idle_counter(const char *name, int deviceid)
> {
>     CARD64 resolution;
>     XSyncValue idle;
> @@ -2734,12 +2745,39 @@ SyncInitIdleTime(void)
>     IdleTimeQueryValue(NULL, &idle);
>     XSyncIntToValue(&resolution, 4);
> 
> -    idle_time_counter = SyncCreateSystemCounter("IDLETIME", idle, resolution,
> +    idle_time_counter = SyncCreateSystemCounter(name, idle, resolution,
>                                                 XSyncCounterUnrestricted,
>                                                 IdleTimeQueryValue,
>                                                 IdleTimeBracketValues);
> 
> +    priv->deviceid = deviceid;
>     priv->value_less = priv->value_greater = NULL;
> 
>     idle_time_counter->pSysCounterInfo->private = priv;
> +
> +    return idle_time_counter;
> +}
> +
> +static void
> +SyncInitIdleTime(void)
> +{
> +    init_system_idle_counter("IDLETIME", XIAllDevices);
> +}
> +
> +SyncCounter*
> +SyncInitDeviceIdleTime(DeviceIntPtr dev)
> +{
> +    char timer_name[64];
> +    sprintf(timer_name, "DEVICEIDLETIME %d", dev->id);
> +
> +    return init_system_idle_counter(timer_name, dev->id);
> +}
> +
> +void SyncRemoveDeviceIdleTime(SyncCounter *counter)
> +{
> +    /* FreeAllResources() frees all system counters before the devices are
> +       shut down, check if there are any left before freeing the device's
> +       counter */
> +    if (!xorg_list_is_empty(&SysCounterList))
> +        xorg_list_del(&counter->pSysCounterInfo->entry);
> }
> diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
> index d29c361..dbed476 100644
> --- a/Xext/syncsrv.h
> +++ b/Xext/syncsrv.h
> @@ -135,4 +135,7 @@ extern void SyncChangeCounter(SyncCounter *pCounter,
> extern void SyncDestroySystemCounter(pointer pCounter);
> 
> extern void SyncExtensionInit(void);
> +
> +extern SyncCounter *SyncInitDeviceIdleTime(DeviceIntPtr dev);
> +extern void SyncRemoveDeviceIdleTime(SyncCounter *counter);
> #endif                          /* _SYNCSRV_H_ */
> diff --git a/dix/devices.c b/dix/devices.c
> index 0125504..600f8b7 100644
> --- a/dix/devices.c
> +++ b/dix/devices.c
> @@ -84,6 +84,7 @@ SOFTWARE.
> #include "enterleave.h"         /* for EnterWindow() */
> #include "xserver-properties.h"
> #include "xichangehierarchy.h"  /* For XISendDeviceHierarchyEvent */
> +#include "syncsrv.h"
> 
> /** @file
>  * This file handles input device-related stuff.
> @@ -406,9 +407,13 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
> 
>     RecalculateMasterButtons(dev);
> 
> +    /* initialise an idle timer for this device*/
> +    dev->idle_counter = SyncInitDeviceIdleTime(dev);
> +
>     return TRUE;
> }
> 
> +
> /**
>  * Switch a device off through the driver and push it onto the off_devices
>  * list. A device will not send events while disabled. All clients are
> @@ -432,6 +437,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
>     if (*prev != dev)
>         return FALSE;
> 
> +    SyncRemoveDeviceIdleTime(dev->idle_counter);
> +    dev->idle_counter = NULL;
> +
>     /* float attached devices */
>     if (IsMaster(dev)) {
>         for (other = inputInfo.devices; other; other = other->next) {
> diff --git a/include/inputstr.h b/include/inputstr.h
> index 841e805..5a38924 100644
> --- a/include/inputstr.h
> +++ b/include/inputstr.h
> @@ -591,6 +591,8 @@ typedef struct _DeviceIntRec {
> 
>     /* XTest related master device id */
>     int xtest_master_id;
> +
> +    struct _SyncCounter *idle_counter;
> } DeviceIntRec;
> 
> typedef struct {
> commit 6aef209ebc2e54f5465da505a780f7b4cc273ee0
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Mar 12 13:51:02 2012 +1000
> 
>    Change lastDeviceIdleTime to be per-device
> 
>    Preparation work for per-device idle counters.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Jamey Sharp <jamey at minilop.net>
>    Reviewed-by: James Jones <jajones at nvidia.com>
> 
> diff --git a/Xext/saver.c b/Xext/saver.c
> index 159153c..61fc044 100644
> --- a/Xext/saver.c
> +++ b/Xext/saver.c
> @@ -46,6 +46,7 @@ in this Software without prior written authorization from the X Consortium.
> #include "cursorstr.h"
> #include "colormapst.h"
> #include "xace.h"
> +#include "inputstr.h"
> #ifdef PANORAMIX
> #include "panoramiX.h"
> #include "panoramiXsrv.h"
> @@ -388,8 +389,10 @@ ScreenSaverFreeSuspend(pointer value, XID id)
>         if (screenIsSaved != SCREEN_SAVER_ON)
> #endif
>         {
> +            DeviceIntPtr dev;
>             UpdateCurrentTimeIf();
> -            lastDeviceEventTime = currentTime;
> +            nt_list_for_each_entry(dev, inputInfo.devices, next)
> +                lastDeviceEventTime[dev->id] = currentTime;
>             SetScreenSaverTimer();
>         }
>     }
> @@ -672,7 +675,7 @@ ProcScreenSaverQueryInfo(ClientPtr client)
>     pPriv = GetScreenPrivate(pDraw->pScreen);
> 
>     UpdateCurrentTime();
> -    lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
> +    lastInput = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds;
> 
>     rep.type = X_Reply;
>     rep.length = 0;
> diff --git a/Xext/sync.c b/Xext/sync.c
> index 25379bb..8217e76 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -2599,7 +2599,7 @@ typedef struct {
> static void
> IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
> {
> -    CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
> +    CARD32 idle = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds;
> 
>     XSyncIntsToValue(pValue_return, idle, 0);
> }
> diff --git a/Xi/exevents.c b/Xi/exevents.c
> index f681a8b..ff22240 100644
> --- a/Xi/exevents.c
> +++ b/Xi/exevents.c
> @@ -1598,7 +1598,7 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
>         GetSpritePosition(device, &rootX, &rootY);
>         event->root_x = rootX;
>         event->root_y = rootY;
> -        NoticeEventTime((InternalEvent *) event);
> +        NoticeEventTime((InternalEvent *) event, device);
>         event->corestate = corestate;
>         key = event->detail.key;
>         break;
> diff --git a/dix/events.c b/dix/events.c
> index f7b9456..4470947 100644
> --- a/dix/events.c
> +++ b/dix/events.c
> @@ -1055,19 +1055,20 @@ MonthChangedOrBadTime(InternalEvent *ev)
> }
> 
> static void
> -NoticeTime(InternalEvent *ev)
> +NoticeTime(InternalEvent *ev, DeviceIntPtr dev)
> {
>     if (ev->any.time < currentTime.milliseconds)
>         MonthChangedOrBadTime(ev);
>     currentTime.milliseconds = ev->any.time;
> -    lastDeviceEventTime = currentTime;
> +    lastDeviceEventTime[XIAllDevices] = currentTime;
> +    lastDeviceEventTime[dev->id] = currentTime;
> }
> 
> void
> -NoticeEventTime(InternalEvent *ev)
> +NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev)
> {
>     if (!syncEvents.playingEvents)
> -        NoticeTime(ev);
> +        NoticeTime(ev, dev);
> }
> 
> /**************************************************************************
> @@ -1091,7 +1092,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
>     if (!xorg_list_is_empty(&syncEvents.pending))
>         tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next);
> 
> -    NoticeTime((InternalEvent *) event);
> +    NoticeTime((InternalEvent *)event, device);
> 
>     /* Fix for key repeating bug. */
>     if (device->key != NULL && device->key->xkbInfo != NULL &&
> @@ -5163,6 +5164,7 @@ InitEvents(void)
> 
>     for (i = 0; i < MAXDEVICES; i++) {
>         memcpy(&event_filters[i], default_filter, sizeof(default_filter));
> +        lastDeviceEventTime[i] = currentTime;
>     }
> 
>     syncEvents.replayDev = (DeviceIntPtr) NULL;
> @@ -5176,7 +5178,6 @@ InitEvents(void)
>     syncEvents.time.milliseconds = 0;   /* hardly matters */
>     currentTime.months = 0;
>     currentTime.milliseconds = GetTimeInMillis();
> -    lastDeviceEventTime = currentTime;
>     for (i = 0; i < DNPMCOUNT; i++) {
>         DontPropagateMasks[i] = 0;
>         DontPropagateRefCnts[i] = 0;
> diff --git a/dix/globals.c b/dix/globals.c
> index c0cae15..a564575 100644
> --- a/dix/globals.c
> +++ b/dix/globals.c
> @@ -122,7 +122,7 @@ Bool party_like_its_1989 = FALSE;
> Bool whiteRoot = FALSE;
> 
> TimeStamp currentTime;
> -TimeStamp lastDeviceEventTime;
> +TimeStamp lastDeviceEventTime[MAXDEVICES];
> 
> int defaultColorVisualClass = -1;
> int monitorResolution = 0;
> diff --git a/dix/window.c b/dix/window.c
> index a31e78f..98f5604 100644
> --- a/dix/window.c
> +++ b/dix/window.c
> @@ -3134,8 +3134,10 @@ dixSaveScreens(ClientPtr client, int on, int mode)
>     screenIsSaved = what;
>     if (mode == ScreenSaverReset) {
>         if (on == SCREEN_SAVER_FORCER) {
> +            DeviceIntPtr dev;
>             UpdateCurrentTimeIf();
> -            lastDeviceEventTime = currentTime;
> +            nt_list_for_each_entry(dev, inputInfo.devices, next)
> +                lastDeviceEventTime[dev->id] = currentTime;
>         }
>         SetScreenSaverTimer();
>     }
> diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
> index 692e511..e16fe78 100644
> --- a/hw/kdrive/src/kinput.c
> +++ b/hw/kdrive/src/kinput.c
> @@ -340,7 +340,8 @@ KdEnableInput(void)
> 
>     /* reset screen saver */
>     ev.any.time = GetTimeInMillis();
> -    NoticeEventTime(&ev);
> +    NoticeEventTime(&ev, pi->dixdev);
> +    NoticeEventTime(&ev, ki->dixdev);
> 
>     KdUnblockSigio();
> }
> diff --git a/include/dix.h b/include/dix.h
> index d604e06..5dc2ac5 100644
> --- a/include/dix.h
> +++ b/include/dix.h
> @@ -313,7 +313,8 @@ extern _X_EXPORT WindowPtr
> GetSpriteWindow(DeviceIntPtr pDev);
> 
> extern _X_EXPORT void
> -NoticeEventTime(InternalEvent *ev);
> +NoticeEventTime(InternalEvent *ev,
> +                DeviceIntPtr dev);
> 
> extern void
> EnqueueEvent(InternalEvent * /* ev */ ,
> diff --git a/include/dixstruct.h b/include/dixstruct.h
> index 75685a2..b2a168a 100644
> --- a/include/dixstruct.h
> +++ b/include/dixstruct.h
> @@ -156,7 +156,7 @@ typedef struct _WorkQueue {
> } WorkQueueRec;
> 
> extern _X_EXPORT TimeStamp currentTime;
> -extern _X_EXPORT TimeStamp lastDeviceEventTime;
> +extern _X_EXPORT TimeStamp lastDeviceEventTime[MAXDEVICES];
> 
> extern _X_EXPORT int
> CompareTimeStamps(TimeStamp /*a */ ,
> diff --git a/os/WaitFor.c b/os/WaitFor.c
> index 4c3be34..95e64ba 100644
> --- a/os/WaitFor.c
> +++ b/os/WaitFor.c
> @@ -547,7 +547,7 @@ NextDPMSTimeout(INT32 timeout)
> static CARD32
> ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg)
> {
> -    INT32 timeout = now - lastDeviceEventTime.milliseconds;
> +    INT32 timeout = now - lastDeviceEventTime[XIAllDevices].milliseconds;
>     CARD32 nextTimeout = 0;
> 
> #ifdef DPMSExtension
> diff --git a/os/xdmcp.c b/os/xdmcp.c
> index 8d0fbb5..87f04b4 100644
> --- a/os/xdmcp.c
> +++ b/os/xdmcp.c
> @@ -1391,7 +1391,7 @@ recv_alive_msg(unsigned length)
>         if (SessionRunning && AliveSessionID == SessionID) {
>             /* backoff dormancy period */
>             state = XDM_RUN_SESSION;
> -            if ((GetTimeInMillis() - lastDeviceEventTime.milliseconds) >
> +            if ((GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds) >
>                 keepaliveDormancy * 1000) {
>                 keepaliveDormancy <<= 1;
>                 if (keepaliveDormancy > XDM_MAX_DORMANCY)
> commit 20cf0ef825e3f14b0688b691691e0aeba0a4860a
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Tue Mar 13 10:21:23 2012 +1000
> 
>    Xext: strdup() the SystemSyncCounter name
> 
>    Required for future dynamic names.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Jamey Sharp <jamey at minilop.net>
>    Reviewed-by: James Jones <jajones at nvidia.com>
> 
> diff --git a/Xext/sync.c b/Xext/sync.c
> index 3c6ac5b..25379bb 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -961,7 +961,7 @@ SyncCreateSystemCounter(const char *name,
>         }
>         pCounter->pSysCounterInfo = psci;
>         psci->pCounter = pCounter;
> -        psci->name = name;
> +        psci->name = strdup(name);
>         psci->resolution = resolution;
>         psci->counterType = counterType;
>         psci->QueryValue = QueryValue;
> @@ -1115,6 +1115,7 @@ FreeCounter(void *env, XID id)
>     }
>     if (IsSystemCounter(pCounter)) {
>         xorg_list_del(&pCounter->pSysCounterInfo->entry);
> +        free(pCounter->pSysCounterInfo->name);
>         free(pCounter->pSysCounterInfo->private);
>         free(pCounter->pSysCounterInfo);
>     }
> diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
> index 2fa8687..d29c361 100644
> --- a/Xext/syncsrv.h
> +++ b/Xext/syncsrv.h
> @@ -76,7 +76,7 @@ typedef void (*SyncSystemCounterBracketValues)(pointer counter,
> 
> typedef struct _SysCounterInfo {
>     SyncCounter *pCounter;
> -    const char *name;
> +    char *name;
>     CARD64 resolution;
>     CARD64 bracket_greater;
>     CARD64 bracket_less;
> commit f1b28aea4156f0381ea733ad2afbdd1f34f75599
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Tue Mar 13 09:31:09 2012 +1000
> 
>    Xext: store the bracket values for idle counters in the private
> 
>    And drop the three global variables, we have a reference to the counter
>    everywhere now.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Jamey Sharp <jamey at minilop.net>
>    Reviewed-by: James Jones <jajones at nvidia.com>
> 
> diff --git a/Xext/sync.c b/Xext/sync.c
> index 94972ea..3c6ac5b 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -2590,9 +2590,10 @@ SyncInitServerTime(void)
>  * IDLETIME implementation
>  */
> 
> -static SyncCounter *IdleTimeCounter;
> -static XSyncValue *pIdleTimeValueLess;
> -static XSyncValue *pIdleTimeValueGreater;
> +typedef struct {
> +    XSyncValue *value_less;
> +    XSyncValue *value_greater;
> +} IdleCounterPriv;
> 
> static void
> IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
> @@ -2605,9 +2606,10 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
> static void
> IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMask)
> {
> -    SyncCounter *counter = IdleTimeCounter;
> -    XSyncValue *less = pIdleTimeValueLess,
> -               *greater = pIdleTimeValueGreater;
> +    SyncCounter *counter = pCounter;
> +    IdleCounterPriv *priv = SysCounterGetPrivate(counter);
> +    XSyncValue *less = priv->value_less,
> +               *greater = priv->value_greater;
>     XSyncValue idle, old_idle;
>     SyncTriggerList *list = counter->sync.pTriglist;
>     SyncTrigger *trig;
> @@ -2680,10 +2682,11 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa
> static void
> IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
> {
> -    SyncCounter *counter = IdleTimeCounter;
> +    SyncCounter *counter = pCounter;
> +    IdleCounterPriv *priv = SysCounterGetPrivate(counter);
> +    XSyncValue *less = priv->value_less,
> +               *greater = priv->value_greater;
>     XSyncValue idle;
> -    XSyncValue *less = pIdleTimeValueLess,
> -               *greater = pIdleTimeValueGreater;
> 
>     if (!less && !greater)
>         return;
> @@ -2700,8 +2703,10 @@ static void
> IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less,
>                       CARD64 * pbracket_greater)
> {
> -    XSyncValue *less = pIdleTimeValueLess,
> -               *greater = pIdleTimeValueGreater;
> +    SyncCounter *counter = pCounter;
> +    IdleCounterPriv *priv = SysCounterGetPrivate(counter);
> +    XSyncValue *less = priv->value_less,
> +               *greater = priv->value_greater;
>     Bool registered = (less || greater);
> 
>     if (registered && !pbracket_less && !pbracket_greater) {
> @@ -2713,8 +2718,8 @@ IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less,
>                                        IdleTimeWakeupHandler, pCounter);
>     }
> 
> -    pIdleTimeValueGreater = pbracket_greater;
> -    pIdleTimeValueLess = pbracket_less;
> +    priv->value_greater = pbracket_greater;
> +    priv->value_less = pbracket_less;
> }
> 
> static void
> @@ -2722,14 +2727,18 @@ SyncInitIdleTime(void)
> {
>     CARD64 resolution;
>     XSyncValue idle;
> +    IdleCounterPriv *priv = malloc(sizeof(IdleCounterPriv));
> +    SyncCounter *idle_time_counter;
> 
>     IdleTimeQueryValue(NULL, &idle);
>     XSyncIntToValue(&resolution, 4);
> 
> -    IdleTimeCounter = SyncCreateSystemCounter("IDLETIME", idle, resolution,
> -                                              XSyncCounterUnrestricted,
> -                                              IdleTimeQueryValue,
> -                                              IdleTimeBracketValues);
> +    idle_time_counter = SyncCreateSystemCounter("IDLETIME", idle, resolution,
> +                                                XSyncCounterUnrestricted,
> +                                                IdleTimeQueryValue,
> +                                                IdleTimeBracketValues);
> 
> -    pIdleTimeValueLess = pIdleTimeValueGreater = NULL;
> +    priv->value_less = priv->value_greater = NULL;
> +
> +    idle_time_counter->pSysCounterInfo->private = priv;
> }
> commit d9553b2bbe06fba0b209218ffed9465edd79b4d2
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Tue Mar 13 09:29:39 2012 +1000
> 
>    Xext: pass the counter into block/wakeup handlers
> 
>    No functional changes, currently unused. Preparation work, we don't need a
>    global variable if we can pass the counters around anyway.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Jamey Sharp <jamey at minilop.net>
>    Reviewed-by: James Jones <jajones at nvidia.com>
> 
> diff --git a/Xext/sync.c b/Xext/sync.c
> index a692b6e..94972ea 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -2603,7 +2603,7 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
> }
> 
> static void
> -IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
> +IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMask)
> {
>     SyncCounter *counter = IdleTimeCounter;
>     XSyncValue *less = pIdleTimeValueLess,
> @@ -2678,7 +2678,7 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
> }
> 
> static void
> -IdleTimeWakeupHandler(pointer env, int rc, pointer LastSelectMask)
> +IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask)
> {
>     SyncCounter *counter = IdleTimeCounter;
>     XSyncValue idle;
> @@ -2706,11 +2706,11 @@ IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less,
> 
>     if (registered && !pbracket_less && !pbracket_greater) {
>         RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler,
> -                                     IdleTimeWakeupHandler, NULL);
> +                                     IdleTimeWakeupHandler, pCounter);
>     }
>     else if (!registered && (pbracket_less || pbracket_greater)) {
>         RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
> -                                       IdleTimeWakeupHandler, NULL);
> +                                       IdleTimeWakeupHandler, pCounter);
>     }
> 
>     pIdleTimeValueGreater = pbracket_greater;
> commit 90e6dc6de1ac339212989fd8e54131b196ebb369
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Tue Mar 13 09:28:15 2012 +1000
> 
>    Xext: add a private field to SyncSystemCounters
> 
>    Will be used to store counter-specific data.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Jamey Sharp <jamey at minilop.net>
>    Reviewed-by: James Jones <jajones at nvidia.com>
> 
> diff --git a/Xext/sync.c b/Xext/sync.c
> index 0bc0fb8..a692b6e 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -113,6 +113,14 @@ static void SyncInitServerTime(void);
> 
> static void SyncInitIdleTime(void);
> 
> +static inline void*
> +SysCounterGetPrivate(SyncCounter *counter)
> +{
> +    BUG_WARN(!IsSystemCounter(counter));
> +
> +    return counter->pSysCounterInfo ? counter->pSysCounterInfo->private : NULL;
> +}
> +
> static Bool
> SyncCheckWarnIsCounter(const SyncObject * pSync, const char *warning)
> {
> @@ -958,6 +966,7 @@ SyncCreateSystemCounter(const char *name,
>         psci->counterType = counterType;
>         psci->QueryValue = QueryValue;
>         psci->BracketValues = BracketValues;
> +        psci->private = NULL;
>         XSyncMaxValue(&psci->bracket_greater);
>         XSyncMinValue(&psci->bracket_less);
>         xorg_list_add(&psci->entry, &SysCounterList);
> @@ -1106,6 +1115,7 @@ FreeCounter(void *env, XID id)
>     }
>     if (IsSystemCounter(pCounter)) {
>         xorg_list_del(&pCounter->pSysCounterInfo->entry);
> +        free(pCounter->pSysCounterInfo->private);
>         free(pCounter->pSysCounterInfo);
>     }
>     free(pCounter);
> diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
> index f2f7a0f..2fa8687 100644
> --- a/Xext/syncsrv.h
> +++ b/Xext/syncsrv.h
> @@ -83,6 +83,7 @@ typedef struct _SysCounterInfo {
>     SyncCounterType counterType;        /* how can this counter change */
>     SyncSystemCounterQueryValue QueryValue;
>     SyncSystemCounterBracketValues BracketValues;
> +    void *private;
>     struct xorg_list entry;
> } SysCounterInfo;
> 
> commit 3ddae647c307005309daa2d5dfe4bc6acb8170ab
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Mar 12 15:31:39 2012 +1000
> 
>    Xext: localise pIdleTimeValueLess/Greater
> 
>    Cleanup for future features, no functional changes.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Jamey Sharp <jamey at minilop.net>
>    Reviewed-by: James Jones <jajones at nvidia.com>
> 
> diff --git a/Xext/sync.c b/Xext/sync.c
> index 54a9fbb..0bc0fb8 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -2596,18 +2596,20 @@ static void
> IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
> {
>     SyncCounter *counter = IdleTimeCounter;
> +    XSyncValue *less = pIdleTimeValueLess,
> +               *greater = pIdleTimeValueGreater;
>     XSyncValue idle, old_idle;
>     SyncTriggerList *list = counter->sync.pTriglist;
>     SyncTrigger *trig;
> 
> -    if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
> +    if (!less && !greater)
>         return;
> 
>     old_idle = counter->value;
>     IdleTimeQueryValue(NULL, &idle);
>     counter->value = idle;      /* push, so CheckTrigger works */
> 
> -    if (pIdleTimeValueLess && XSyncValueLessOrEqual(idle, *pIdleTimeValueLess)) {
> +    if (less && XSyncValueLessOrEqual(idle, *less)) {
>         /*
>          * We've been idle for less than the threshold value, and someone
>          * wants to know about that, but now we need to know whether they
> @@ -2629,10 +2631,10 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
>          * idle time greater than this.  Schedule a wakeup for the next
>          * millisecond so we won't miss a transition.
>          */
> -        if (XSyncValueEqual(idle, *pIdleTimeValueLess))
> +        if (XSyncValueEqual(idle, *less))
>             AdjustWaitForDelay(wt, 1);
>     }
> -    else if (pIdleTimeValueGreater) {
> +    else if (greater) {
>         /*
>          * There's a threshold in the positive direction.  If we've been
>          * idle less than it, schedule a wakeup for sometime in the future.
> @@ -2641,11 +2643,11 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
>          */
>         unsigned long timeout = -1;
> 
> -        if (XSyncValueLessThan(idle, *pIdleTimeValueGreater)) {
> +        if (XSyncValueLessThan(idle, *greater)) {
>             XSyncValue value;
>             Bool overflow;
> 
> -            XSyncValueSubtract(&value, *pIdleTimeValueGreater, idle, &overflow);
> +            XSyncValueSubtract(&value, *greater, idle, &overflow);
>             timeout = min(timeout, XSyncValueLow32(value));
>         }
>         else {
> @@ -2670,16 +2672,16 @@ IdleTimeWakeupHandler(pointer env, int rc, pointer LastSelectMask)
> {
>     SyncCounter *counter = IdleTimeCounter;
>     XSyncValue idle;
> +    XSyncValue *less = pIdleTimeValueLess,
> +               *greater = pIdleTimeValueGreater;
> 
> -    if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
> +    if (!less && !greater)
>         return;
> 
>     IdleTimeQueryValue(NULL, &idle);
> 
> -    if ((pIdleTimeValueGreater &&
> -         XSyncValueGreaterOrEqual(idle, *pIdleTimeValueGreater)) ||
> -        (pIdleTimeValueLess &&
> -         XSyncValueLessOrEqual(idle, *pIdleTimeValueLess))) {
> +    if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) ||
> +        (less && XSyncValueLessOrEqual(idle, *less))) {
>         SyncChangeCounter(counter, idle);
>     }
> }
> @@ -2688,7 +2690,9 @@ static void
> IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less,
>                       CARD64 * pbracket_greater)
> {
> -    Bool registered = (pIdleTimeValueLess || pIdleTimeValueGreater);
> +    XSyncValue *less = pIdleTimeValueLess,
> +               *greater = pIdleTimeValueGreater;
> +    Bool registered = (less || greater);
> 
>     if (registered && !pbracket_less && !pbracket_greater) {
>         RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler,
> commit 43eb2f2758dfc6ca5a49afce97cc5baea8caf9f5
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Mar 12 15:27:56 2012 +1000
> 
>    Xext: localise use of IdleTimeCounter
> 
>    Instead of referring to the global IdleTimeCounter everywhere, only do it
>    once and use a local variable for the rest.
> 
>    Cleanup for future features, no functional changes.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Jamey Sharp <jamey at minilop.net>
>    Reviewed-by: James Jones <jajones at nvidia.com>
> 
> diff --git a/Xext/sync.c b/Xext/sync.c
> index fe0eac0..54a9fbb 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -2595,16 +2595,17 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return)
> static void
> IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
> {
> +    SyncCounter *counter = IdleTimeCounter;
>     XSyncValue idle, old_idle;
> -    SyncTriggerList *list = IdleTimeCounter->sync.pTriglist;
> +    SyncTriggerList *list = counter->sync.pTriglist;
>     SyncTrigger *trig;
> 
>     if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
>         return;
> 
> -    old_idle = IdleTimeCounter->value;
> +    old_idle = counter->value;
>     IdleTimeQueryValue(NULL, &idle);
> -    IdleTimeCounter->value = idle;      /* push, so CheckTrigger works */
> +    counter->value = idle;      /* push, so CheckTrigger works */
> 
>     if (pIdleTimeValueLess && XSyncValueLessOrEqual(idle, *pIdleTimeValueLess)) {
>         /*
> @@ -2615,7 +2616,7 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
>          * immediately so we can reschedule.
>          */
> 
> -        for (list = IdleTimeCounter->sync.pTriglist; list; list = list->next) {
> +        for (list = counter->sync.pTriglist; list; list = list->next) {
>             trig = list->pTrigger;
>             if (trig->CheckTrigger(trig, old_idle)) {
>                 AdjustWaitForDelay(wt, 0);
> @@ -2648,7 +2649,7 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
>             timeout = min(timeout, XSyncValueLow32(value));
>         }
>         else {
> -            for (list = IdleTimeCounter->sync.pTriglist; list;
> +            for (list = counter->sync.pTriglist; list;
>                  list = list->next) {
>                 trig = list->pTrigger;
>                 if (trig->CheckTrigger(trig, old_idle)) {
> @@ -2661,12 +2662,13 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask)
>         AdjustWaitForDelay(wt, timeout);
>     }
> 
> -    IdleTimeCounter->value = old_idle;  /* pop */
> +    counter->value = old_idle;  /* pop */
> }
> 
> static void
> IdleTimeWakeupHandler(pointer env, int rc, pointer LastSelectMask)
> {
> +    SyncCounter *counter = IdleTimeCounter;
>     XSyncValue idle;
> 
>     if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
> @@ -2678,7 +2680,7 @@ IdleTimeWakeupHandler(pointer env, int rc, pointer LastSelectMask)
>          XSyncValueGreaterOrEqual(idle, *pIdleTimeValueGreater)) ||
>         (pIdleTimeValueLess &&
>          XSyncValueLessOrEqual(idle, *pIdleTimeValueLess))) {
> -        SyncChangeCounter(IdleTimeCounter, idle);
> +        SyncChangeCounter(counter, idle);
>     }
> }
> 
> commit 1f12f059ef994e0b9b68fbd1f1556d0285c96b8b
> Author: Jamey Sharp <jamey at minilop.net>
> Date:   Wed Mar 14 17:22:18 2012 -0700
> 
>    sync: Use a linked list instead of an array for SysCounterList.
> 
>    Signed-off-by: Jamey Sharp <jamey at minilop.net>
>    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/sync.c b/Xext/sync.c
> index f2bcd25..fe0eac0 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -87,8 +87,7 @@ static RESTYPE RTAwait;
> static RESTYPE RTAlarm;
> static RESTYPE RTAlarmClient;
> static RESTYPE RTFence;
> -static int SyncNumSystemCounters = 0;
> -static SyncCounter **SysCounterList = NULL;
> +static struct xorg_list SysCounterList;
> static int SyncNumInvalidCounterWarnings = 0;
> 
> #define MAX_INVALID_COUNTER_WARNINGS	   5
> @@ -932,12 +931,6 @@ SyncCreateSystemCounter(const char *name,
> {
>     SyncCounter *pCounter;
> 
> -    SysCounterList = realloc(SysCounterList,
> -                             (SyncNumSystemCounters +
> -                              1) * sizeof(SyncCounter *));
> -    if (!SysCounterList)
> -        return NULL;
> -
>     /* this function may be called before SYNC has been initialized, so we
>      * have to make sure RTCounter is created.
>      */
> @@ -959,6 +952,7 @@ SyncCreateSystemCounter(const char *name,
>             return pCounter;
>         }
>         pCounter->pSysCounterInfo = psci;
> +        psci->pCounter = pCounter;
>         psci->name = name;
>         psci->resolution = resolution;
>         psci->counterType = counterType;
> @@ -966,7 +960,7 @@ SyncCreateSystemCounter(const char *name,
>         psci->BracketValues = BracketValues;
>         XSyncMaxValue(&psci->bracket_greater);
>         XSyncMinValue(&psci->bracket_less);
> -        SysCounterList[SyncNumSystemCounters++] = pCounter;
> +        xorg_list_add(&psci->entry, &SysCounterList);
>     }
>     return pCounter;
> }
> @@ -1111,26 +1105,8 @@ FreeCounter(void *env, XID id)
>         free(ptl);              /* destroy the trigger list as we go */
>     }
>     if (IsSystemCounter(pCounter)) {
> -        int i, found = 0;
> -
> +        xorg_list_del(&pCounter->pSysCounterInfo->entry);
>         free(pCounter->pSysCounterInfo);
> -
> -        /* find the counter in the list of system counters and remove it */
> -
> -        if (SysCounterList) {
> -            for (i = 0; i < SyncNumSystemCounters; i++) {
> -                if (SysCounterList[i] == pCounter) {
> -                    found = i;
> -                    break;
> -                }
> -            }
> -            if (found < (SyncNumSystemCounters - 1)) {
> -                for (i = found; i < SyncNumSystemCounters - 1; i++) {
> -                    SysCounterList[i] = SysCounterList[i + 1];
> -                }
> -            }
> -        }
> -        SyncNumSystemCounters--;
>     }
>     free(pCounter);
>     return Success;
> @@ -1221,20 +1197,20 @@ static int
> ProcSyncListSystemCounters(ClientPtr client)
> {
>     xSyncListSystemCountersReply rep;
> -    int i, len;
> +    SysCounterInfo *psci;
> +    int len = 0;
>     xSyncSystemCounter *list = NULL, *walklist = NULL;
> 
>     REQUEST_SIZE_MATCH(xSyncListSystemCountersReq);
> 
>     rep.type = X_Reply;
>     rep.sequenceNumber = client->sequence;
> -    rep.nCounters = SyncNumSystemCounters;
> -
> -    for (i = len = 0; i < SyncNumSystemCounters; i++) {
> -        const char *name = SysCounterList[i]->pSysCounterInfo->name;
> +    rep.nCounters = 0;
> 
> +    xorg_list_for_each_entry(psci, &SysCounterList, entry) {
>         /* pad to 4 byte boundary */
> -        len += pad_to_int32(sz_xSyncSystemCounter + strlen(name));
> +        len += pad_to_int32(sz_xSyncSystemCounter + strlen(psci->name));
> +        ++rep.nCounters;
>     }
> 
>     if (len) {
> @@ -1251,12 +1227,11 @@ ProcSyncListSystemCounters(ClientPtr client)
>         swapl(&rep.nCounters);
>     }
> 
> -    for (i = 0; i < SyncNumSystemCounters; i++) {
> +    xorg_list_for_each_entry(psci, &SysCounterList, entry) {
>         int namelen;
>         char *pname_in_reply;
> -        SysCounterInfo *psci = SysCounterList[i]->pSysCounterInfo;
> 
> -        walklist->counter = SysCounterList[i]->sync.id;
> +        walklist->counter = psci->pCounter->sync.id;
>         walklist->resolution_hi = XSyncValueHigh32(psci->resolution);
>         walklist->resolution_lo = XSyncValueLow32(psci->resolution);
>         namelen = strlen(psci->name);
> @@ -2441,8 +2416,6 @@ SAlarmNotifyEvent(xSyncAlarmNotifyEvent * from, xSyncAlarmNotifyEvent * to)
> static void
> SyncResetProc(ExtensionEntry * extEntry)
> {
> -    free(SysCounterList);
> -    SysCounterList = NULL;
>     RTCounter = 0;
> }
> 
> @@ -2455,6 +2428,8 @@ SyncExtensionInit(void)
>     ExtensionEntry *extEntry;
>     int s;
> 
> +    xorg_list_init(&SysCounterList);
> +
>     for (s = 0; s < screenInfo.numScreens; s++)
>         miSyncSetup(screenInfo.screens[s]);
> 
> diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
> index 1e59ded..f2f7a0f 100644
> --- a/Xext/syncsrv.h
> +++ b/Xext/syncsrv.h
> @@ -51,6 +51,7 @@ PERFORMANCE OF THIS SOFTWARE.
> #ifndef _SYNCSRV_H_
> #define _SYNCSRV_H_
> 
> +#include "list.h"
> #include "misync.h"
> #include "misyncstr.h"
> 
> @@ -74,6 +75,7 @@ typedef void (*SyncSystemCounterBracketValues)(pointer counter,
>     );
> 
> typedef struct _SysCounterInfo {
> +    SyncCounter *pCounter;
>     const char *name;
>     CARD64 resolution;
>     CARD64 bracket_greater;
> @@ -81,6 +83,7 @@ typedef struct _SysCounterInfo {
>     SyncCounterType counterType;        /* how can this counter change */
>     SyncSystemCounterQueryValue QueryValue;
>     SyncSystemCounterBracketValues BracketValues;
> +    struct xorg_list entry;
> } SysCounterInfo;
> 
> typedef struct _SyncAlarmClientList {
> commit bf876c87a9099fdfa63ed599f8ed9a954dd023d9
> Merge: 908ab3d... c0b0a9b...
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Thu Mar 22 11:34:43 2012 +1000
> 
>    Merge branch 'dtrace-input-abi' into for-keith
> 
> commit c0b0a9bce9237b0abe150c1a7b54939affecc751
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Mar 5 14:12:52 2012 +1000
> 
>    dix: add dtrace probes to input API
> 
>    For driver debugging, it is helpful to know whether the driver has actually
>    submitted an event to the server. dtrace hooks can help here.
> 
>    Note that GetPointerEvents and friends may also be triggered by the server
>    for other emulated devices, some care must be taken when analysing the
>    results.
> 
>    Additional difficulty: proximity events have a run-time assigned type, so
>    this may make automatic detection a tad harder. If in doubt, go for any
>    event > 64 since the only two that can have that value are ProximityIn and
>    ProximityOut.
> 
>    An example systemtap script is below:
> 
>      # Compile+run with
>      #       stap -g xorg.stp /usr/bin/Xorg
>      #
> 
>      function print_valuators:string(nvaluators:long, mask_in:long, valuators_in:long) %{
>              int i;
>              unsigned char *mask = (unsigned char*)THIS->mask_in;
>              double *valuators = (double*)THIS->valuators_in;
>              char str[128] = {0};
>              char *s = str;
> 
>      #define BitIsSet(ptr, bit) (((unsigned char*)(ptr))[(bit)>>3] & (1 << ((bit) & 7)))
> 
>              s += sprintf(s, "nval: %d ::", (int)THIS->nvaluators);
>              for (i = 0; i < THIS->nvaluators; i++)
>              {
>                      s += sprintf(s, "	%d: ", i);
>                      if (BitIsSet(mask, i))
>                          s += sprintf(s, "%d", (int)valuators[i]);
>              }
> 
>              sprintf(THIS->__retvalue, "%s", str);
>      %}
> 
>      probe process(@1).mark("input__event")
>      {
>          deviceid = $arg1
>          type = $arg2
>          detail = $arg3
>          flags = $arg4
>          nvaluators = $arg5
> 
>          str = print_valuators(nvaluators, $arg6, $arg7)
>          printf("Event: device %d type %d detail %d flags %#x %s\n",
>                  deviceid, type, detail, flags, str);
>      }
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Acked-by: Jeremy Huddleston <jeremyhu at apple.com>
> 
> diff --git a/dix/Xserver-dtrace.h.in b/dix/Xserver-dtrace.h.in
> index daf3faf..60ebbcd 100644
> --- a/dix/Xserver-dtrace.h.in
> +++ b/dix/Xserver-dtrace.h.in
> @@ -54,7 +54,8 @@ extern "C" {
> 	__dtrace_Xserver___resource__free(arg0, arg1, arg2, arg3)
> #define	XSERVER_SEND_EVENT(arg0, arg1, arg2) \
> 	__dtrace_Xserver___send__event(arg0, arg1, arg2)
> -
> +#define	XSERVER_INPUT_EVENT(arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
> +	__dtrace_Xserver___input__event(arg0, arg1, arg2, arg3, arg4, arg5, arg6)
> 
> extern void __dtrace_Xserver___client__auth(int, string, pid_t, zoneid_t);
> extern void __dtrace_Xserver___client__connect(int, int);
> @@ -64,6 +65,8 @@ extern void __dtrace_Xserver___request__start(string, uint8_t, uint16_t, int, vo
> extern void __dtrace_Xserver___resource__alloc(uint32_t, uint32_t, void *, string);
> extern void __dtrace_Xserver___resource__free(uint32_t, uint32_t, void *, string);
> extern void __dtrace_Xserver___send__event(int, uint8_t, void *);
> +extern void __dtrace_Xserver___input__event(int, uint16_t, uint32_t, uint32_t, int8_t, uint8_t *, double *);
> +
> 
> #else
> 
> @@ -75,6 +78,7 @@ extern void __dtrace_Xserver___send__event(int, uint8_t, void *);
> #define	XSERVER_RESOURCE_ALLOC(arg0, arg1, arg2, arg3)
> #define	XSERVER_RESOURCE_FREE(arg0, arg1, arg2, arg3)
> #define	XSERVER_SEND_EVENT(arg0, arg1, arg2)
> +#define	XSERVER_INPUT_EVENT(arg0, arg1, arg2, arg3, arg4, arg5, arg6)
> 
> #endif
> 
> @@ -86,6 +90,7 @@ extern void __dtrace_Xserver___send__event(int, uint8_t, void *);
> #define	XSERVER_RESOURCE_ALLOC_ENABLED() (1)
> #define	XSERVER_RESOURCE_FREE_ENABLED() (1)
> #define	XSERVER_SEND_EVENT_ENABLED() (1)
> +#define	XSERVER_INPUT_EVENT_ENABLED() (1)
> 
> #ifdef	__cplusplus
> }
> diff --git a/dix/Xserver.d b/dix/Xserver.d
> index 2ad3373..248d48e 100644
> --- a/dix/Xserver.d
> +++ b/dix/Xserver.d
> @@ -48,6 +48,8 @@ provider Xserver {
> 	probe resource__free(uint32_t, uint32_t, void *, string);
> 	/* client id, event type, event* */
> 	probe send__event(int, uint8_t, void *);
> +	/* deviceid, type, button/keycode/touchid, flags, nvalues, mask, values */
> +	probe input__event(int, int, uint32_t, uint32_t, int8_t, uint8_t*, double*);
> };
> 
> #pragma D attributes Unstable/Unstable/Common provider Xserver provider
> diff --git a/dix/getevents.c b/dix/getevents.c
> index 2f6f06c..6354e99 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -68,6 +68,12 @@
> #include "extnsionst.h"
> #include "listdev.h"            /* for sizing up DeviceClassesChangedEvent */
> 
> +#if XSERVER_DTRACE
> +#include <sys/types.h>
> +typedef const char *string;
> +#include <Xserver-dtrace.h>
> +#endif
> +
> /* Number of motion history events to store. */
> #define MOTION_HISTORY_SIZE 256
> 
> @@ -1025,6 +1031,15 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
>     RawDeviceEvent *raw;
>     ValuatorMask mask;
> 
> +#if XSERVER_DTRACE
> +    if (XSERVER_INPUT_EVENT_ENABLED()) {
> +        XSERVER_INPUT_EVENT(pDev->id, type, key_code, 0,
> +                            mask_in ? mask_in->last_bit + 1 : 0,
> +                            mask_in ? mask_in->mask : NULL,
> +                            mask_in ? mask_in->valuators : NULL);
> +    }
> +#endif
> +
>     /* refuse events from disabled devices */
>     if (!pDev->enabled)
>         return 0;
> @@ -1501,6 +1516,15 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
>     int i;
>     int realtype = type;
> 
> +#if XSERVER_DTRACE
> +    if (XSERVER_INPUT_EVENT_ENABLED()) {
> +        XSERVER_INPUT_EVENT(pDev->id, type, buttons, flags,
> +                            mask_in ? mask_in->last_bit + 1 : 0,
> +                            mask_in ? mask_in->mask : NULL,
> +                            mask_in ? mask_in->valuators : NULL);
> +    }
> +#endif
> +
>     /* refuse events from disabled devices */
>     if (!pDev->enabled)
>         return 0;
> @@ -1626,6 +1650,15 @@ GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
>     DeviceEvent *event;
>     ValuatorMask mask;
> 
> +#if XSERVER_DTRACE
> +    if (XSERVER_INPUT_EVENT_ENABLED()) {
> +        XSERVER_INPUT_EVENT(pDev->id, type, 0, 0,
> +                            mask_in ? mask_in->last_bit + 1 : 0,
> +                            mask_in ? mask_in->mask : NULL,
> +                            mask_in ? mask_in->valuators : NULL);
> +    }
> +#endif
> +
>     /* refuse events from disabled devices */
>     if (!pDev->enabled)
>         return 0;
> @@ -1750,6 +1783,15 @@ GetTouchEvents(InternalEvent *events, DeviceIntPtr dev, uint32_t ddx_touchid,
>     Bool emulate_pointer = FALSE;
>     int client_id = 0;
> 
> +#if XSERVER_DTRACE
> +    if (XSERVER_INPUT_EVENT_ENABLED()) {
> +        XSERVER_INPUT_EVENT(dev->id, type, ddx_touchid, flags,
> +                            mask_in ? mask_in->last_bit + 1 : 0,
> +                            mask_in ? mask_in->mask : NULL,
> +                            mask_in ? mask_in->valuators : NULL);
> +    }
> +#endif
> +
>     if (!dev->enabled || !t || !v)
>         return 0;
> 
> diff --git a/doc/dtrace/Xserver-DTrace.xml b/doc/dtrace/Xserver-DTrace.xml
> index 5ef0629..91ca254 100644
> --- a/doc/dtrace/Xserver-DTrace.xml
> +++ b/doc/dtrace/Xserver-DTrace.xml
> @@ -52,7 +52,9 @@ DEALINGS IN THE SOFTWARE.
>       facility in <productname>Solaris</productname> 10,
>       <productname>MacOS X</productname> 10.5, and later releases.  This
>       provider instruments various points in the X server, to allow
> -      tracing what client applications are up to.
> +      tracing what client applications are up to. DTrace probes may be used
> +      with <ulink url="http://sourceware.org/systemtap/">SystemTap</ulink>
> +      on GNU/Linux systems.
>     </para>
> 
>     <para>
> @@ -81,7 +83,7 @@ DEALINGS IN THE SOFTWARE.
> 
>     <table id="Probes_and_their_arguments">
>       <title>Probes and their arguments</title>
> -      <tgroup cols='7'>
> +      <tgroup cols='9'>
> 	<colspec colname="probe" colwidth="2*"/>
> 	<colspec colname="desc" colwidth="3*"/>
> 	<colspec colname="arg0" colwidth="1*"/>
> @@ -89,6 +91,8 @@ DEALINGS IN THE SOFTWARE.
> 	<colspec colname="arg2" colwidth="1*"/>
> 	<colspec colname="arg3" colwidth="1*"/>
> 	<colspec colname="arg4" colwidth="1*"/>
> +	<colspec colname="arg5" colwidth="1*"/>
> +	<colspec colname="arg6" colwidth="1*"/>
> 	<spanspec spanname="all" namest="probe" nameend="arg4"/>
> 	<thead>
> 	  <row>
> @@ -99,6 +103,8 @@ DEALINGS IN THE SOFTWARE.
> 	    <entry>arg2</entry>
> 	    <entry>arg3</entry>
> 	    <entry>arg4</entry>
> +	    <entry>arg5</entry>
> +	    <entry>arg6</entry>
> 	  </row>
> 	</thead>
> 	<tbody>
> @@ -113,6 +119,8 @@ DEALINGS IN THE SOFTWARE.
> 	    <entry><parameter>requestLength</parameter></entry>
> 	    <entry><parameter>clientId</parameter></entry>
> 	    <entry><parameter>requestBuffer</parameter></entry>
> +	    <entry nameend="arg5" class="unused"/>
> +	    <entry nameend="arg6" class="unused"/>
> 	  </row>
> 	  <row>
> 	    <entry>request-done</entry>
> @@ -122,6 +130,8 @@ DEALINGS IN THE SOFTWARE.
> 	    <entry><parameter>sequenceNumber</parameter></entry>
> 	    <entry><parameter>clientId</parameter></entry>
> 	    <entry><parameter>resultCode</parameter></entry>
> +	    <entry nameend="arg5" class="unused"/>
> +	    <entry nameend="arg6" class="unused"/>
> 	  </row>
> 	  <row>
> 	    <entry spanname="all" class="grouphead">Event Probes</entry>
> @@ -132,7 +142,10 @@ DEALINGS IN THE SOFTWARE.
> 	    <entry><parameter>clientId</parameter></entry>
> 	    <entry><parameter>eventCode</parameter></entry>
> 	    <entry><parameter>eventBuffer</parameter></entry>
> +	    <entry nameend="arg3" class="unused"/>
> 	    <entry nameend="arg4" class="unused"/>
> +	    <entry nameend="arg5" class="unused"/>
> +	    <entry nameend="arg6" class="unused"/>
> 	  </row>
> 	  <row>
> 	    <entry spanname="all" class="grouphead">Client Connection Probes</entry>
> @@ -142,7 +155,11 @@ DEALINGS IN THE SOFTWARE.
> 	    <entry>Called when a new connection is opened from a client</entry>
> 	    <entry><parameter>clientId</parameter></entry>
> 	    <entry><parameter>clientFD</parameter></entry>
> +	    <entry nameend="arg2" class="unused"/>
> +	    <entry nameend="arg3" class="unused"/>
> 	    <entry nameend="arg4" class="unused"/>
> +	    <entry nameend="arg5" class="unused"/>
> +	    <entry nameend="arg6" class="unused"/>
> 	  </row>
> 	  <row>
> 	    <entry>client-auth</entry>
> @@ -152,12 +169,19 @@ DEALINGS IN THE SOFTWARE.
> 	    <entry><parameter>clientPid</parameter></entry>
> 	    <entry><parameter>clientZoneId</parameter></entry>
> 	    <entry nameend="arg4" class="unused"/>
> +	    <entry nameend="arg5" class="unused"/>
> +	    <entry nameend="arg6" class="unused"/>
> 	  </row>
> 	  <row>
> 	    <entry>client-disconnect</entry>
> 	    <entry>Called when a client connection is closed</entry>
> 	    <entry><parameter>clientId</parameter></entry>
> +	    <entry nameend="arg1" class="unused"/>
> +	    <entry nameend="arg2" class="unused"/>
> +	    <entry nameend="arg3" class="unused"/>
> 	    <entry nameend="arg4" class="unused"/>
> +	    <entry nameend="arg5" class="unused"/>
> +	    <entry nameend="arg6" class="unused"/>
> 	  </row>
> 	  <row>
> 	    <entry spanname="all" class="grouphead">Resource Allocation Probes</entry>
> @@ -170,6 +194,8 @@ DEALINGS IN THE SOFTWARE.
> 	    <entry><parameter>resourceValue</parameter></entry>
> 	    <entry><parameter>resourceTypeName</parameter></entry>
> 	    <entry nameend="arg4" class="unused"/>
> +	    <entry nameend="arg5" class="unused"/>
> +	    <entry nameend="arg6" class="unused"/>
> 	  </row>
> 	  <row>
> 	    <entry>resource-free</entry>
> @@ -179,6 +205,24 @@ DEALINGS IN THE SOFTWARE.
> 	    <entry><parameter>resourceValue</parameter></entry>
> 	    <entry><parameter>resourceTypeName</parameter></entry>
> 	    <entry nameend="arg4" class="unused"/>
> +	    <entry nameend="arg5" class="unused"/>
> +	    <entry nameend="arg6" class="unused"/>
> +	  </row>
> +	  <row>
> +	    <entry spanname="all" class="grouphead">Input API probes</entry>
> +	  </row>
> +	  <row>
> +	    <entry>input-event</entry>
> +	    <entry>Called when an input event was submitted for processing</entry>
> +	    <entry><parameter>deviceid</parameter></entry>
> +	    <entry><parameter>eventtype</parameter></entry>
> +	    <entry><parameter>button</parameter> or
> +		   <parameter>keycode</parameter> or
> +		   <parameter>touchid</parameter></entry>
> +	    <entry><parameter>flags</parameter></entry>
> +	    <entry><parameter>nvalues</parameter></entry>
> +	    <entry><parameter>mask</parameter></entry>
> +	    <entry><parameter>values</parameter></entry>
> 	  </row>
> 	</tbody>
>       </tgroup>
> @@ -304,6 +348,44 @@ DEALINGS IN THE SOFTWARE.
> 	    <entry><type>uint32_t</type></entry>
> 	    <entry>Number of X request in in this connection</entry>
> 	  </row>
> +	  <row>
> +	    <entry><parameter>deviceid</parameter></entry>
> +	    <entry><type>int</type></entry>
> +	    <entry>The device's numerical ID</entry>
> +	  </row>
> +	  <row>
> +	    <entry><parameter>eventtype</parameter></entry>
> +	    <entry><type>int</type></entry>
> +	    <entry>Protocol event type</entry>
> +	  </row>
> +	  <row>
> +	    <entry><parameter>button, keycode, touchid</parameter></entry>
> +	    <entry><type>uint32_t</type></entry>
> +	    <entry>The button number, keycode or touch ID</entry>
> +	  </row>
> +	  <row>
> +	    <entry><parameter>flags</parameter></entry>
> +	    <entry><type>uint32_t</type></entry>
> +	    <entry>Miscellaneous event-specific server flags</entry>
> +	  </row>
> +	  <row>
> +	    <entry><parameter>nvalues</parameter></entry>
> +	    <entry><type>int8_t</type></entry>
> +	    <entry>Number of bits in <parameter>mask</parameter> and number of elements
> +		    in <parameter>values</parameter></entry>
> +	  </row>
> +	  <row>
> +	    <entry><parameter>mask</parameter></entry>
> +	    <entry><type>uint8_t*</type></entry>
> +	    <entry>Binary mask indicating which indices in <parameter>values</parameter> contain
> +		  valid data</entry>
> +	  </row>
> +	  <row>
> +	    <entry><parameter>values</parameter></entry>
> +	    <entry><type>double*</type></entry>
> +	    <entry>Valuator values. Values for indices for which the
> +		  <parameter>mask</parameter> is not set are undefined</entry>
> +	  </row>
> 	</tbody>
>       </tgroup>
>     </table>
> @@ -572,6 +654,73 @@ Xserver$1:::client-disconnect
> 
>     </example>
> 
> +    <example id="Input_API_monitoring_with_systemtap">
> +      <title>Input API monitoring with SystemTap</title>
> +
> +      <para>
> +	This script can be used to monitor events submitted by drivers to
> +	the server for enqueuing. Due to the integration of the input API
> +	probes, some server-enqueued events will show up too.
> +	<programlisting>
> +  # Compile+run with
> +  #       stap -g xorg.stp /usr/bin/Xorg
> +  #
> +
> +
> +  function print_valuators:string(nvaluators:long, mask_in:long, valuators_in:long) %{
> +	  int i;
> +	  unsigned char *mask = (unsigned char*)THIS->mask_in;
> +	  double *valuators = (double*)THIS->valuators_in;
> +	  char str[128] = {0};
> +	  char *s = str;
> +
> +  #define BitIsSet(ptr, bit) (((unsigned char*)(ptr))[(bit)>>3] &amp; (1 &lt;&lt; ((bit) &amp; 7)))
> +
> +	  s += sprintf(s, "nval: %d ::", (int)THIS->nvaluators);
> +	  for (i = 0; i &lt; THIS->nvaluators; i++)
> +	  {
> +		  s += sprintf(s, "	%d: ", i);
> +		  if (BitIsSet(mask, i))
> +		      s += sprintf(s, "%d", (int)valuators[i]);
> +	  }
> +
> +	  sprintf(THIS->__retvalue, "%s", str);
> +  %}
> +
> +  probe process(@1).mark("input__event")
> +  {
> +      deviceid = $arg1
> +      type = $arg2
> +      detail = $arg3
> +      flags = $arg4
> +      nvaluators = $arg5
> +
> +      str = print_valuators(nvaluators, $arg6, $arg7)
> +      printf("Event: device %d type %d detail %d flags %#x %s\n",
> +	      deviceid, type, detail, flags, str);
> +  }
> +	</programlisting>
> +
> +	Sample output from a run of this script:
> +	<screen><computeroutput>
> +Event: device 13 type 4 detail 1 flags 0x0 nval: 0 ::
> +Event: device 13 type 6 detail 0 flags 0xa nval: 1 ::	0: 1
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 2	1: -1
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 2	1: -1
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 4	1: -3
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 3	1: -3
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 3	1: -2
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 2	1: -2
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 2	1: -2
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 2	1: -2
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 	1: -1
> +Event: device 13 type 6 detail 0 flags 0xa nval: 2 ::	0: 	1: -1
> +Event: device 13 type 5 detail 1 flags 0x0 nval: 0 ::
> +	</computeroutput></screen>
> +
> +      </para>
> +
> +    </example>
> 
>   </sect1>
> 
> commit 61cb98da1c6199964825de158d9eee7682d9c983
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Mar 12 16:03:50 2012 +1000
> 
>    Xext: SyncCreateSystemCounter returns a SyncCounter*
> 
>    type safety++
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Bryce Harrington <bryce at canonical.com>
> 
> diff --git a/Xext/sync.c b/Xext/sync.c
> index 3764dbf..f2bcd25 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -921,7 +921,7 @@ static int FreeCounter(void *, XID);
>  * ***** System Counter utilities
>  */
> 
> -pointer
> +SyncCounter*
> SyncCreateSystemCounter(const char *name,
>                         CARD64 initial,
>                         CARD64 resolution,
> diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
> index f62b279..1e59ded 100644
> --- a/Xext/syncsrv.h
> +++ b/Xext/syncsrv.h
> @@ -116,12 +116,12 @@ typedef union {
>     SyncAwait await;
> } SyncAwaitUnion;
> 
> -extern pointer SyncCreateSystemCounter(const char *name,
> -                                       CARD64 initial_value,
> -                                       CARD64 resolution,
> -                                       SyncCounterType counterType,
> -                                       SyncSystemCounterQueryValue QueryValue,
> -                                       SyncSystemCounterBracketValues BracketValues
> +extern SyncCounter* SyncCreateSystemCounter(const char *name,
> +                                            CARD64 initial_value,
> +                                            CARD64 resolution,
> +                                            SyncCounterType counterType,
> +                                            SyncSystemCounterQueryValue QueryValue,
> +                                            SyncSystemCounterBracketValues BracketValues
>     );
> 
> extern void SyncChangeCounter(SyncCounter *pCounter,
> commit 908ab3d580188533168c8cdfd2cab9dc689b4218
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Wed Mar 21 14:05:29 2012 +1000
> 
>    dix: set raw event values before adding up relative values (#46976)
> 
>    Regression introduced in 4e52cc0ef48145134cd58d357fb7289e6f8bb709
> 
>    Raw event values are values as-is from the driver, modified only be
>    transformation or acceleration. 4e52cc caused the mask to be updated from
>    relative to absolute coordinates which then got written into the raw events.
> 
>    Move the raw event update into the respective branches for absolute/relative
>    events.
> 
>    X.Org Bug 46976 <http://bugs.freedesktop.org/show_bug.cgi?id=46976>
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
>    Reviewed-by: Daniel Stone <daniel at fooishbar.org>
>    Tested-by: Sven Arvidsson <sa at whiz.se>
>    Reviewed-by: Simon Thum <simon.thum at gmx.de>
> 
> diff --git a/dix/getevents.c b/dix/getevents.c
> index 260955b..fa85fe7 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -1314,18 +1314,19 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type,
> 
>         transformAbsolute(pDev, &mask);
>         clipAbsolute(pDev, &mask);
> +        if ((flags & POINTER_NORAW) == 0)
> +            set_raw_valuators(raw, &mask, raw->valuators.data);
>     }
>     else {
>         if (flags & POINTER_ACCELERATE)
>             accelPointer(pDev, &mask, ms);
> +        if ((flags & POINTER_NORAW) == 0)
> +            set_raw_valuators(raw, &mask, raw->valuators.data);
> +
>         moveRelative(pDev, &mask);
>     }
> 
>     /* valuators are in device coordinate system in absolute coordinates */
> -
> -    if ((flags & POINTER_NORAW) == 0)
> -        set_raw_valuators(raw, &mask, raw->valuators.data);
> -
>     scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny);
>     scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
>                          &mask, &devx, &devy, &screenx, &screeny);
> commit 45fe3085f8f45e529383025414fdd263d86dfd2b
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Mar 12 14:08:39 2012 +1000
> 
>    Xext: remove needless /* parameter */ comments in declaration
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Bryce Harrington <bryce at canonical.com>
> 
> diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
> index 1afaf5f..f62b279 100644
> --- a/Xext/syncsrv.h
> +++ b/Xext/syncsrv.h
> @@ -116,17 +116,16 @@ typedef union {
>     SyncAwait await;
> } SyncAwaitUnion;
> 
> -extern pointer SyncCreateSystemCounter(const char * /* name */ ,
> -                                       CARD64 /* inital_value */ ,
> -                                       CARD64 /* resolution */ ,
> -                                       SyncCounterType
> -                                       /* change characterization */ ,
> +extern pointer SyncCreateSystemCounter(const char *name,
> +                                       CARD64 initial_value,
> +                                       CARD64 resolution,
> +                                       SyncCounterType counterType,
>                                        SyncSystemCounterQueryValue QueryValue,
>                                        SyncSystemCounterBracketValues BracketValues
>     );
> 
> -extern void SyncChangeCounter(SyncCounter * /* pCounter */ ,
> -                              CARD64    /* new_value */
> +extern void SyncChangeCounter(SyncCounter *pCounter,
> +                              CARD64 new_value
>     );
> 
> extern void SyncDestroySystemCounter(pointer pCounter);
> commit 9c3bd3ae652af386b6821b197d24528f20ba867d
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Wed Mar 21 14:03:27 2012 +1000
> 
>    dix: fix compiler warning "unused variable 'scr'"
> 
>    getevents.c: In function 'updateSlaveDeviceCoords':
>    getevents.c:326:15: warning: unused variable 'scr' [-Wunused-variable]
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> 
> diff --git a/dix/getevents.c b/dix/getevents.c
> index 68bf58c..260955b 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -328,7 +328,6 @@ rescaleValuatorAxis(double coord, AxisInfoPtr from, AxisInfoPtr to,
> static void
> updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
> {
> -    ScreenPtr scr = miPointerGetScreen(pDev);
>     int i;
>     DeviceIntPtr lastSlave;
> 
> commit e21ffff4761d2b75815391c6947adcba425ab11e
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Mar 12 14:07:44 2012 +1000
> 
>    Xext: typedef QueryValue and BracketValue prototypes
> 
>    No functional changes, just for readability
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Bryce Harrington <bryce at canonical.com>
> 
> diff --git a/Xext/sync.c b/Xext/sync.c
> index 37c59c2..3764dbf 100644
> --- a/Xext/sync.c
> +++ b/Xext/sync.c
> @@ -926,11 +926,8 @@ SyncCreateSystemCounter(const char *name,
>                         CARD64 initial,
>                         CARD64 resolution,
>                         SyncCounterType counterType,
> -                        void (*QueryValue) (pointer /* pCounter */ ,
> -                                            CARD64 * /* pValue_return */ ),
> -                        void (*BracketValues) (pointer /* pCounter */ ,
> -                                               CARD64 * /* pbracket_less */ ,
> -                                               CARD64 * /* pbracket_greater */ )
> +                        SyncSystemCounterQueryValue QueryValue,
> +                        SyncSystemCounterBracketValues BracketValues
>     )
> {
>     SyncCounter *pCounter;
> diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
> index b0464b3..1afaf5f 100644
> --- a/Xext/syncsrv.h
> +++ b/Xext/syncsrv.h
> @@ -65,19 +65,22 @@ typedef enum {
>     XSyncCounterUnrestricted
> } SyncCounterType;
> 
> +typedef void (*SyncSystemCounterQueryValue)(pointer counter,
> +                                            CARD64 *value_return
> +    );
> +typedef void (*SyncSystemCounterBracketValues)(pointer counter,
> +                                               CARD64 *pbracket_less,
> +                                               CARD64 *pbracket_greater
> +    );
> +
> typedef struct _SysCounterInfo {
>     const char *name;
>     CARD64 resolution;
>     CARD64 bracket_greater;
>     CARD64 bracket_less;
>     SyncCounterType counterType;        /* how can this counter change */
> -    void (*QueryValue) (pointer /*pCounter */ ,
> -                        CARD64 *        /*freshvalue */
> -        );
> -    void (*BracketValues) (pointer /*pCounter */ ,
> -                           CARD64 * /*lessthan */ ,
> -                           CARD64 *     /*greaterthan */
> -        );
> +    SyncSystemCounterQueryValue QueryValue;
> +    SyncSystemCounterBracketValues BracketValues;
> } SysCounterInfo;
> 
> typedef struct _SyncAlarmClientList {
> @@ -118,21 +121,8 @@ extern pointer SyncCreateSystemCounter(const char * /* name */ ,
>                                        CARD64 /* resolution */ ,
>                                        SyncCounterType
>                                        /* change characterization */ ,
> -                                       void (* /*QueryValue */ )(
> -                                                                    pointer
> -                                                                    /* pCounter */
> -                                                                    ,
> -                                                                    CARD64 * /* pValue_return */ ),     /* XXX prototype */
> -                                       void (* /*BracketValues */ )(
> -                                                                       pointer
> -                                                                       /* pCounter */
> -                                                                       ,
> -                                                                       CARD64 *
> -                                                                       /* pbracket_less */
> -                                                                       ,
> -                                                                       CARD64 *
> -                                                                       /* pbracket_greater */
> -                                                                       )
> +                                       SyncSystemCounterQueryValue QueryValue,
> +                                       SyncSystemCounterBracketValues BracketValues
>     );
> 
> extern void SyncChangeCounter(SyncCounter * /* pCounter */ ,
> commit 14e3ea730eed344e6ed69c873f918d6f076d13dc
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Wed Mar 14 13:48:56 2012 +1000
> 
>    include: add an X_DEBUG message type
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jamey Sharp <jamey at minilop.net>
> 
> diff --git a/include/os.h b/include/os.h
> index 4b5b440..dd06a85 100644
> --- a/include/os.h
> +++ b/include/os.h
> @@ -578,6 +578,7 @@ typedef enum {
>     X_INFO,                     /* Informational message */
>     X_NONE,                     /* No prefix */
>     X_NOT_IMPLEMENTED,          /* Not implemented */
> +    X_DEBUG,                    /* Debug message */
>     X_UNKNOWN = -1              /* unknown -- this must always be last */
> } MessageType;
> 
> diff --git a/os/log.c b/os/log.c
> index 0ccd126..1b1b285 100644
> --- a/os/log.c
> +++ b/os/log.c
> @@ -164,6 +164,9 @@ asm(".desc ___crashreporter_info__, 0x10");
> #ifndef X_NOT_IMPLEMENTED_STRING
> #define X_NOT_IMPLEMENTED_STRING	"(NI)"
> #endif
> +#ifndef X_DEBUG_STRING
> +#define X_DEBUG_STRING			"(DB)"
> +#endif
> #ifndef X_NONE_STRING
> #define X_NONE_STRING                   ""
> #endif
> @@ -362,6 +365,8 @@ LogMessageTypeVerbString(MessageType type, int verb)
>         return X_UNKNOWN_STRING;
>     case X_NONE:
>         return X_NONE_STRING;
> +    case X_DEBUG:
> +        return X_DEBUG_STRING;
>     default:
>         return X_UNKNOWN_STRING;
>     }
> commit 5910f2df58beaae2187438fef0b62c29a563e853
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Mar 12 16:26:29 2012 +1000
> 
>    Xext: drop InitServertime() declaration.
> 
>    Not implemented anywhere.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Reviewed-by: Bryce Harrington <bryce at canonical.com>
> 
> diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h
> index e7ef1f4..b0464b3 100644
> --- a/Xext/syncsrv.h
> +++ b/Xext/syncsrv.h
> @@ -141,7 +141,5 @@ extern void SyncChangeCounter(SyncCounter * /* pCounter */ ,
> 
> extern void SyncDestroySystemCounter(pointer pCounter);
> 
> -extern void InitServertime(void);
> -
> extern void SyncExtensionInit(void);
> #endif                          /* _SYNCSRV_H_ */
> commit 31df08a449cf9b6e1740e1c02257997490630d93
> Author: Chase Douglas <chase.douglas at canonical.com>
> Date:   Wed Mar 7 16:06:27 2012 -0800
> 
>    Use a new sprite trace for indirect touches when all touches have physically ended
> 
>    All touches of an indirect device, such as a trackpad, are sent to the
>    same window set. When there are no active touches, a new window set is
>    created; otherwise, the window set of an existing touch is copied.
> 
>    The current code checks for any logically active touches. This includes
>    touches that have physically ended but are still logically active due to
>    unhandled touch grabs. Instead, we want a new window set whenever there
>    are no physically active touches.
> 
>    This change skips over logically active but pending end touches, which
>    are touches that have physically ended.
> 
>    Signed-off-by: Chase Douglas <chase.douglas at canonical.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/touch.c b/dix/touch.c
> index 5d7132e..0829b65 100644
> --- a/dix/touch.c
> +++ b/dix/touch.c
> @@ -510,7 +510,8 @@ TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite)
>     /* All touches should have the same sprite trace, so find and reuse an
>      * existing touch's sprite if possible, else use the device's sprite. */
>     for (i = 0; i < t->num_touches; i++)
> -        if (t->touches[i].sprite.spriteTraceGood > 0)
> +        if (!t->touches[i].pending_finish &&
> +            t->touches[i].sprite.spriteTraceGood > 0)
>             break;
>     if (i < t->num_touches)
>         srcsprite = &t->touches[i].sprite;
> commit 58427e08a4a36ce9e213e4b4fe5249d5db2c764d
> Author: Chase Douglas <chase.douglas at canonical.com>
> Date:   Wed Mar 7 16:06:26 2012 -0800
> 
>    Xi: Fix TouchEnd to TouchUpdate change for one accepted grab
> 
>    If there is only one listener of a touch, the listener is a grab, and is
>    accepted before the touch has ended, the current code will not end the
>    touch record when the touch does end.
> 
>    This change adds a listener state for when a touch is accepted but has
>    not yet ended. We now keep the touch record alive in this state, but end
>    it when the touch ends.
> 
>    Signed-off-by: Chase Douglas <chase.douglas at canonical.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 a690a19..f681a8b 100644
> --- a/Xi/exevents.c
> +++ b/Xi/exevents.c
> @@ -1210,6 +1210,8 @@ ProcessTouchOwnershipEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
>         /* Owner accepted after receiving end */
>         if (ti->listeners[0].state == LISTENER_HAS_END)
>             TouchEndTouch(dev, ti);
> +        else
> +            ti->listeners[0].state = LISTENER_HAS_ACCEPTED;
>     }
>     else {                      /* this is the very first ownership event for a grab */
>         DeliverTouchEvents(dev, ti, (InternalEvent *) ev, ev->resource);
> @@ -1730,7 +1732,11 @@ DeliverTouchBeginEvent(DeviceIntPtr dev, TouchPointInfoPtr ti,
>     else {
>         if (has_ownershipmask)
>             TouchSendOwnershipEvent(dev, ti, 0, listener->listener);
> -        state = LISTENER_IS_OWNER;
> +
> +        if (!has_ownershipmask || listener->type == LISTENER_REGULAR)
> +            state = LISTENER_HAS_ACCEPTED;
> +        else
> +            state = LISTENER_IS_OWNER;
>     }
>     listener->state = state;
> 
> @@ -1759,20 +1765,22 @@ DeliverTouchEndEvent(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev,
>         listener->state = LISTENER_HAS_END;
>     }
>     else if (TouchResourceIsOwner(ti, listener->listener)) {
> +        Bool normal_end = !(ev->device_event.flags & TOUCH_ACCEPT);
> +
>         /* FIXME: what about early acceptance */
> -        if (!(ev->device_event.flags & TOUCH_ACCEPT)) {
> -            if (listener->state != LISTENER_HAS_END)
> -                rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
> -            listener->state = LISTENER_HAS_END;
> -        }
> +        if (normal_end && listener->state != LISTENER_HAS_END)
> +            rc = DeliverOneTouchEvent(client, dev, ti, grab, win, ev);
> +
>         if ((ti->num_listeners > 1 ||
> -             (listener->type == LISTENER_GRAB &&
> -              xi2mask_isset(xi2mask, dev, XI_TouchOwnership))) &&
> +             listener->state != LISTENER_HAS_ACCEPTED) &&
>             (ev->device_event.flags & (TOUCH_ACCEPT | TOUCH_REJECT)) == 0) {
>             ev->any.type = ET_TouchUpdate;
>             ev->device_event.flags |= TOUCH_PENDING_END;
>             ti->pending_finish = TRUE;
>         }
> +
> +        if (normal_end)
> +            listener->state = LISTENER_HAS_END;
>     }
> 
>  out:
> diff --git a/include/input.h b/include/input.h
> index a9d0944..d891fe5 100644
> --- a/include/input.h
> +++ b/include/input.h
> @@ -523,7 +523,8 @@ enum TouchListenerState {
>     LISTENER_AWAITING_OWNER,       /**< Waiting for a TouchOwnership event */
>     LISTENER_EARLY_ACCEPT,         /**< Waiting for ownership, has already
>                                         accepted */
> -    LISTENER_IS_OWNER,             /**< Is the current owner */
> +    LISTENER_IS_OWNER,             /**< Is the current owner, hasn't accepted */
> +    LISTENER_HAS_ACCEPTED,         /**< Is the current owner, has accepted */
>     LISTENER_HAS_END,              /**< Has already received the end event */
> };
> 
> commit e884ff8ad4df2b3272a3d8ece772906207af5142
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Wed Mar 7 19:08:33 2012 +1000
> 
>    xfree86: remove out-of-date comment
> 
>    No idea what this was referring to but it goes past git history.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> 
> diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
> index c938b87..68c296b 100644
> --- a/hw/xfree86/os-support/linux/lnx_init.c
> +++ b/hw/xfree86/os-support/linux/lnx_init.c
> @@ -238,9 +238,6 @@ xf86OpenConsole(void)
>             cfsetispeed(&nTty, 9600);
>             cfsetospeed(&nTty, 9600);
>             tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
> -
> -            /* we really should have a InitOSInputDevices() function instead
> -             * of Init?$#*&Device(). So I just place it here */
>         }
>     }
>     else {                      /* serverGeneration != 1 */
> commit 5497ce3da442d27c2dc7796bfef6ccd670bbadc4
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Feb 20 12:09:33 2012 +1000
> 
>    dix: IsFloating() on master devices is always false
> 
>    There are a few subtle bugs during startup where IsFloating() returns true
>    if the device is a master device that is not yet paired with its keyboard
>    device.
> 
>    Force IsFloating() to always return FALSE for master devices, that was the
>    intent after all and any code that relies on the other behaviour should be
>    fixed instead.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
>    Tested-by: Jon TURNEY <jon.turney at dronecode.org.uk>
> 
> diff --git a/dix/events.c b/dix/events.c
> index 0e4ba86..f7b9456 100644
> --- a/dix/events.c
> +++ b/dix/events.c
> @@ -341,7 +341,7 @@ IsMaster(DeviceIntPtr dev)
> Bool
> IsFloating(DeviceIntPtr dev)
> {
> -    return GetMaster(dev, MASTER_KEYBOARD) == NULL;
> +    return !IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == NULL;
> }
> 
> /**
> commit 2c23ef83b0e03e163aeeb06133538606886f4e9c
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Feb 27 08:01:07 2012 +1000
> 
>    Xi: prohibit multiple XIQueryVersion requests with different versions
> 
>    Return BadValue if major or minor differs on the second call.
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
> 
> diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c
> index 95a8efa..fc0ca75 100644
> --- a/Xi/xiqueryversion.c
> +++ b/Xi/xiqueryversion.c
> @@ -70,6 +70,15 @@ ProcXIQueryVersion(ClientPtr client)
> 
>     pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
> 
> +    if (pXIClient->major_version &&
> +           (stuff->major_version != pXIClient->major_version ||
> +            stuff->minor_version != pXIClient->minor_version))
> +    {
> +        client->errorValue = stuff->major_version;
> +        return BadValue;
> +    }
> +
> +
>     if (version_compare(XIVersion.major_version, XIVersion.minor_version,
>                         stuff->major_version, stuff->minor_version) > 0) {
>         major = stuff->major_version;
> commit eb84c154ed38194c32651727b6dfe2d1bde4c599
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Mon Feb 27 10:09:44 2012 +1000
> 
>    dix: when rescaling from master, rescale from desktop dimensions (#46657)
> 
>    master->last.valuators[] is in desktop dimensions, so use those as
>    rescale axis ranges, not the screen. Otherwise, a rescale on any screen
>    not the top-left will cause out-of-bounds coordinates which will always
>    map to the bottom-right screen, causing the device to be stuck on that
>    screen.
> 
>    X.Org Bug 46657 <http://bugs.freedesktop.org/show_bug.cgi?id=46657>
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
>    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
> 
> diff --git a/dix/getevents.c b/dix/getevents.c
> index 2f6f06c..68bf58c 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -345,13 +345,15 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
>         pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0],
>                                                       NULL,
>                                                       pDev->valuator->axes + 0,
> -                                                      0, scr->width);
> +                                                      screenInfo.x,
> +                                                      screenInfo.width);
>     }
>     if (pDev->valuator->numAxes > 1) {
>         pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1],
>                                                       NULL,
>                                                       pDev->valuator->axes + 1,
> -                                                      0, scr->height);
> +                                                      screenInfo.y,
> +                                                      screenInfo.height);
>     }
> 
>     /* calculate the other axis as well based on info from the old
> commit 6b6afd3d013e3f4910fae3520d1d786df2b0e47a
> Author: Peter Hutterer <peter.hutterer at who-t.net>
> Date:   Thu Feb 16 15:11:40 2012 +1000
> 
>    Xext: return BadAccess if PickPointer fails (#45796)
> 
>    PickPointer or PickKeyboard return NULL, all MDs are currently disabled and
>    we cannot emulate a core event. This wasn't anticipated by the protocol, so
>    we don't really have an error code we may use here - BadAccess is simply the
>    least bad of the possible ones.
> 
>    And returning BadAccess beats crashing the server.
> 
>    X.Org Bug 45796 <http://bugs.freedesktop.org/show_bug.cgi?id=45796>
> 
>    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
> 
> diff --git a/Xext/xtest.c b/Xext/xtest.c
> index 2414457..e659b41 100644
> --- a/Xext/xtest.c
> +++ b/Xext/xtest.c
> @@ -118,6 +118,10 @@ ProcXTestCompareCursor(ClientPtr client)
>     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
>     if (rc != Success)
>         return rc;
> +
> +    if (!ptr)
> +        return BadAccess;
> +
>     if (stuff->cursor == None)
>         pCursor = NullCursor;
>     else if (stuff->cursor == XTestCurrentCursor)
> @@ -307,9 +311,15 @@ ProcXTestFakeInput(ClientPtr client)
>             return BadValue;
>         }
> 
> +        /* Technically the protocol doesn't allow for BadAccess here but
> +         * this can only happen when all MDs are disabled.  */
> +        if (!dev)
> +            return BadAccess;
> +
>         dev = GetXTestDevice(dev);
>     }
> 
> +
>     /* If the event has a time set, wait for it to pass */
>     if (ev->u.keyButtonPointer.time) {
>         TimeStamp activateTime;
> commit 9e017cf0cf1f0c9d0d9c2cfeb82ea5dc0eb5905e
> Author: Andreas Wettstein <wettstein509 at solnet.ch>
> Date:   Sat Feb 25 20:48:17 2012 +0100
> 
>    XKB: Redirect actions defunct with Gtk3 (XInput?)
> 
>    When redirect actions are used with Gtk3, Gtk3 complained about
>    events not holding a GdkDevice.  This was caused by device IDs
>    not being set for redirect actions.
> 
>    More seriously, Gtk3 did not receive state changes redirect
>    actions might specify.  This was because event_set_state in
>    dix/inpututils.c accesses the prev_state field, but the changes
>    for the redirect action were only put into the state field.
> 
>    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 c473df1..5ec1ed5 100644
> --- a/xkb/xkbActions.c
> +++ b/xkb/xkbActions.c
> @@ -799,7 +799,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
> {
>     DeviceEvent ev;
>     int x, y;
> -    XkbStateRec old;
> +    XkbStateRec old, old_prev;
>     unsigned mods, mask;
>     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
>     ProcessInputProc backupproc;
> @@ -807,6 +807,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
>     /* 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))
> @@ -818,6 +819,11 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
>     ev.time = GetTimeInMillis();
>     ev.root_x = x;
>     ev.root_y = y;
> +    /* redirect actions do not work across devices, therefore the following is
> +     * correct: */
> +    ev.deviceid = xkbi->device->id;
> +    /* filter->priv must be set up by the caller for the initial press. */
> +    ev.sourceid = filter->priv;
> 
>     if (filter->keycode == 0) { /* initial press */
>         if ((pAction->redirect.new_key < xkbi->desc->min_key_code) ||
> @@ -827,7 +833,6 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
>         filter->keycode = keycode;
>         filter->active = 1;
>         filter->filterOthers = 0;
> -        filter->priv = 0;
>         filter->filter = _XkbFilterRedirectKey;
>         filter->upAction = *pAction;
> 
> @@ -845,6 +850,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
> 
>         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;
> @@ -852,6 +858,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
>             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);
> @@ -860,8 +867,10 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
>         COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
>                                      xkbUnwrapProc);
> 
> -        if (mask || mods)
> +        if (mask || mods) {
>             xkbi->state = old;
> +            xkbi->prev_state = old_prev;
> +        }
>     }
>     else if (filter->keycode == keycode) {
> 
> @@ -879,6 +888,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
> 
>         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;
> @@ -886,6 +896,7 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
>             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);
> @@ -894,8 +905,10 @@ _XkbFilterRedirectKey(XkbSrvInfoPtr xkbi,
>         COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, backupproc,
>                                      xkbUnwrapProc);
> 
> -        if (mask || mods)
> +        if (mask || mods) {
>             xkbi->state = old;
> +            xkbi->prev_state = old_prev;
> +        }
> 
>         filter->keycode = 0;
>         filter->active = 0;
> @@ -1165,6 +1178,11 @@ XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent *event)
>                 break;
>             case XkbSA_RedirectKey:
>                 filter = _XkbNextFreeFilter(xkbi);
> +                /* redirect actions must create a new DeviceEvent.  The
> +                 * source device id for this event cannot be obtained from
> +                 * xkbi, so we pass it here explicitly. The field deviceid
> +                 * equals to xkbi->device->id. */
> +                filter->priv = event->sourceid;
>                 sendEvent = _XkbFilterRedirectKey(xkbi, filter, key, &act);
>                 break;
>             case XkbSA_DeviceBtn:
> _______________________________________________
> xorg-commit mailing list
> xorg-commit at lists.x.org
> http://lists.x.org/mailman/listinfo/xorg-commit
> 



More information about the xorg-devel mailing list