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

Jeremy Huddleston jeremyhu at freedesktop.org
Fri May 13 17:11:29 PDT 2011


 Xext/xtest.c                   |    5 
 Xi/exevents.c                  |  205 +++---
 Xi/xichangehierarchy.c         |    2 
 Xi/xiqueryversion.c            |    7 
 composite/compalloc.c          |  147 +++-
 composite/compint.h            |    5 
 composite/compwindow.c         |   19 
 dbe/dbe.c                      |   25 
 dix/devices.c                  |   10 
 dix/eventconvert.c             |    2 
 dix/events.c                   |  664 +++++++++++++---------
 dix/getevents.c                |  204 ++++--
 dix/inpututils.c               |   28 
 doc/xml/Makefile.am            |    2 
 doc/xml/Xinput.xml             | 1209 +++++++++++++++++++++++++++++++++++++++++
 hw/dmx/input/dmxevents.c       |   66 --
 hw/kdrive/src/kinput.c         |   23 
 hw/xfree86/Makefile.am         |    2 
 hw/xfree86/common/xf86Events.c |    6 
 hw/xfree86/common/xf86Init.c   |    2 
 hw/xfree86/common/xf86Priv.h   |    3 
 hw/xfree86/common/xf86Xinput.c |   43 -
 hw/xnest/Events.c              |   36 -
 hw/xnest/Init.c                |    4 
 hw/xquartz/darwinEvents.c      |   21 
 hw/xwin/winkeybd.c             |    9 
 hw/xwin/winmouse.c             |   19 
 include/dix.h                  |    4 
 include/eventstr.h             |    4 
 include/input.h                |   50 -
 include/inputstr.h             |   10 
 include/inpututils.h           |    2 
 include/misc.h                 |   18 
 mi/mieq.c                      |   57 -
 mi/mipointer.c                 |    5 
 randr/rrdispatch.c             |    8 
 record/record.c                |    2 
 test/Makefile.am               |    3 
 test/misc.c                    |   62 ++
 xfixes/xfixes.c                |   12 
 xkb/xkb.c                      |   51 -
 xkb/xkbActions.c               |    4 
 xkb/xkbEvents.c                |   43 -
 43 files changed, 2263 insertions(+), 840 deletions(-)

New commits:
commit ba5540221f2a46133371b4ff0d527b1a0a1443b1
Merge: 6347a0b... 728d0bf...
Author: Keith Packard <keithp at keithp.com>
Date:   Fri May 13 13:59:36 2011 -0700

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

commit 6347a0b802812bb185ada1bf0951add306935184
Merge: 4d02c53... f144fb7...
Author: Keith Packard <keithp at keithp.com>
Date:   Fri May 13 13:54:29 2011 -0700

    Merge remote-tracking branch 'jeremyhu/master'

commit 4d02c5397114ac4d15e794908f0708427e258261
Merge: 043c175... eac37f3...
Author: Keith Packard <keithp at keithp.com>
Date:   Fri May 13 13:52:18 2011 -0700

    Merge remote-tracking branch 'vsyrjala/composite_validatetree_2'

commit 728d0bf20ed8e2612b100fca6526705fa6e1eef4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 11 13:35:39 2011 +1000

    dix: replace CORE_EVENT and XI2_EVENT macros with inline functions.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/dix/events.c b/dix/events.c
index e67c3a2..14f6f90 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -176,12 +176,23 @@ typedef const char *string;
 #define AllEventMasks (LastEventMask|(LastEventMask-1))
 
 
-#define CORE_EVENT(event) \
-    (!((event)->u.u.type & EXTENSION_EVENT_BASE) && \
-      (event)->u.u.type != GenericEvent)
-#define XI2_EVENT(event) \
-    (((event)->u.u.type == GenericEvent) && \
-    ((xGenericEvent*)(event))->extension == IReqCode)
+/* @return the core event type or 0 if the event is not a core event */
+static inline int
+core_get_type(const xEvent *event)
+{
+    int type = event->u.u.type;
+
+    return ((type & EXTENSION_EVENT_BASE) || type == GenericEvent) ? 0 : type;
+}
+
+/* @return the XI2 event type or 0 if the event is not a XI2 event */
+static inline int
+xi2_get_type(const xEvent *event)
+{
+    xGenericEvent* e = (xGenericEvent*)event;
+
+    return (e->type != GenericEvent || e->extension != IReqCode) ? 0 : e->evtype;
+}
 
 /**
  * Used to indicate a implicit passive grab created by a ButtonPress event.
@@ -414,10 +425,12 @@ static const Mask default_filter[128] =
 Mask
 GetEventFilter(DeviceIntPtr dev, xEvent *event)
 {
+    int evtype = 0;
+
     if (event->u.u.type != GenericEvent)
         return filters[dev ? dev->id : 0][event->u.u.type];
-    else if (XI2_EVENT(event))
-        return (1 << (((xXIDeviceEvent*)event)->evtype % 8));
+    else if ((evtype = xi2_get_type(event)))
+        return (1 << (evtype % 8));
     ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type);
     return 0;
 }
@@ -432,7 +445,7 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
     int filter;
     int evtype;
 
-    if (!inputMasks || !XI2_EVENT(ev))
+    if (!inputMasks || xi2_get_type(ev) == 0)
         return 0;
 
     evtype = ((xGenericEvent*)ev)->evtype;
@@ -446,14 +459,16 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
 Mask
 GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other)
 {
+    int evtype;
+
     /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */
-    if (XI2_EVENT(event))
+    if ((evtype = xi2_get_type(event)))
     {
-        int byte = ((xGenericEvent*)event)->evtype / 8;
+        int byte = evtype / 8;
         return (other->xi2mask[dev->id][byte] |
                 other->xi2mask[XIAllDevices][byte] |
                 (IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0));
-    } else if (CORE_EVENT(event))
+    } else if (core_get_type(event) != 0)
         return other->mask[XIAllDevices];
     else
         return other->mask[dev->id];
@@ -1952,11 +1967,8 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
         grabtype = GRABTYPE_CORE;
     else if (type == DeviceButtonPress)
         grabtype = GRABTYPE_XI;
-    else if (XI2_EVENT(event) && ((xGenericEvent*)event)->evtype == XI_ButtonPress)
-    {
-        type = ((xGenericEvent*)event)->evtype;
+    else if ((type = xi2_get_type(event)) == XI_ButtonPress)
         grabtype = GRABTYPE_XI2;
-    }
     else
         return FALSE;
 
@@ -2040,9 +2052,9 @@ DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events,
     enum EventDeliveryState rc = EVENT_SKIP;
     InputClients *other;
 
-    if (CORE_EVENT(events))
+    if (core_get_type(events) != 0)
         other = (InputClients *)wOtherClients(win);
-    else if (XI2_EVENT(events))
+    else if (xi2_get_type(events) != 0)
     {
         OtherInputMasks *inputMasks = wOtherInputMasks(win);
         /* Has any client selected for the event? */
@@ -2094,6 +2106,7 @@ out:
     return rc;
 }
 
+
 /**
  * Deliver events to a window. At this point, we do not yet know if the event
  * actually needs to be delivered. May activate a grab if the event is a
@@ -2127,7 +2140,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
     int type = pEvents->u.u.type;
 
     /* Deliver to window owner */
-    if ((filter == CantBeFiltered) || CORE_EVENT(pEvents))
+    if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0)
     {
         enum EventDeliveryState rc;
 
@@ -2313,22 +2326,29 @@ FixUpEventFromWindow(
     Window child,
     Bool calcChild)
 {
+    int evtype;
+
     if (calcChild)
         child = FindChildForEvent(pSprite, pWin);
 
-    if (XI2_EVENT(xE))
+    if ((evtype = xi2_get_type(xE)))
     {
         xXIDeviceEvent* event = (xXIDeviceEvent*)xE;
 
-        if (event->evtype == XI_RawKeyPress ||
-            event->evtype == XI_RawKeyRelease ||
-            event->evtype == XI_RawButtonPress ||
-            event->evtype == XI_RawButtonRelease ||
-            event->evtype == XI_RawMotion ||
-            event->evtype == XI_DeviceChanged ||
-            event->evtype == XI_HierarchyChanged ||
-            event->evtype == XI_PropertyEvent)
-            return;
+        switch (evtype)
+        {
+            case XI_RawKeyPress:
+            case XI_RawKeyRelease:
+            case XI_RawButtonPress:
+            case XI_RawButtonRelease:
+            case XI_RawMotion:
+            case XI_DeviceChanged:
+            case XI_HierarchyChanged:
+            case XI_PropertyEvent:
+                return;
+            default:
+                break;
+        }
 
         event->root = RootWindow(pSprite)->drawable.id;
         event->event = pWin->drawable.id;
commit ffd4874798ba54f86acac75779a15b4babeaa5f3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 11 12:20:50 2011 +1000

    include: add version_compare helper function
    
    Compare two version numbers in the major.minor form.
    Switch the few users of manual version switching over to the new function.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c
index ae63297..f647f98 100644
--- a/Xi/xiqueryversion.c
+++ b/Xi/xiqueryversion.c
@@ -58,7 +58,6 @@ ProcXIQueryVersion(ClientPtr client)
     xXIQueryVersionReply rep;
     XIClientPtr pXIClient;
     int major, minor;
-    unsigned int sversion, cversion;
 
     REQUEST(xXIQueryVersionReq);
     REQUEST_SIZE_MATCH(xXIQueryVersionReq);
@@ -72,10 +71,8 @@ ProcXIQueryVersion(ClientPtr client)
 
     pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
 
-    sversion = XIVersion.major_version * 1000 + XIVersion.minor_version;
-    cversion = stuff->major_version * 1000 + stuff->minor_version;
-
-    if (sversion > cversion)
+    if (version_compare(XIVersion.major_version, XIVersion.minor_version,
+                        stuff->major_version, stuff->minor_version) > 0)
     {
         major = stuff->major_version;
         minor = stuff->minor_version;
diff --git a/include/misc.h b/include/misc.h
index 803f5ba..bdcc8cc 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -223,6 +223,24 @@ pad_to_int32(const int bytes) {
 extern char**
 xstrtokenize(const char *str, const char* separators);
 
+/**
+ * Compare the two version numbers comprising of major.minor.
+ *
+ * @return A value less than 0 if a is less than b, 0 if a is equal to b,
+ * or a value greater than 0
+ */
+static inline int
+version_compare(uint16_t a_major, uint16_t a_minor,
+                uint16_t b_major, uint16_t b_minor)
+{
+    int a, b;
+
+    a = a_major << 16 | a_minor;
+    b = b_major << 16 | b_minor;
+
+    return (a - b);
+}
+
 /* some macros to help swap requests, replies, and events */
 
 #define LengthRestB(stuff) \
diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index 2135504..d1c99c2 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -28,8 +28,8 @@ RRClientKnowsRates (ClientPtr	pClient)
 {
     rrClientPriv(pClient);
 
-    return (pRRClient->major_version > 1 ||
-	    (pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
+    return version_compare(pRRClient->major_version, pRRClient->minor_version,
+                           1, 1) >= 0;
 }
 
 static int
@@ -47,8 +47,8 @@ ProcRRQueryVersion (ClientPtr client)
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
-    if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
-        (SERVER_RANDR_MAJOR_VERSION * 1000 + SERVER_RANDR_MINOR_VERSION))
+    if (version_compare(stuff->majorVersion, stuff->minorVersion,
+                        SERVER_RANDR_MAJOR_VERSION, SERVER_RANDR_MINOR_VERSION) < 0)
     {
 	rep.majorVersion = stuff->majorVersion;
 	rep.minorVersion = stuff->minorVersion;
diff --git a/test/Makefile.am b/test/Makefile.am
index fe9bc1f..b7ee070 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,7 +1,7 @@
 if ENABLE_UNIT_TESTS
 if HAVE_LD_WRAP
 SUBDIRS= . xi2
-noinst_PROGRAMS = xkb input xtest list
+noinst_PROGRAMS = xkb input xtest list misc
 check_LTLIBRARIES = libxservertest.la
 
 TESTS=$(noinst_PROGRAMS)
@@ -18,6 +18,7 @@ xkb_LDADD=$(TEST_LDADD)
 input_LDADD=$(TEST_LDADD)
 xtest_LDADD=$(TEST_LDADD)
 list_LDADD=$(TEST_LDADD)
+misc_LDADD=$(TEST_LDADD)
 
 libxservertest_la_LIBADD = \
             $(XSERVER_LIBS) \
diff --git a/test/misc.c b/test/misc.c
new file mode 100644
index 0000000..3d3b1a1
--- /dev/null
+++ b/test/misc.c
@@ -0,0 +1,62 @@
+/**
+ * Copyright © 2011 Red Hat, Inc.
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),
+ *  to deal in the Software without restriction, including without limitation
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice (including the next
+ *  paragraph) shall be included in all copies or substantial portions of the
+ *  Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdint.h>
+#include "misc.h"
+
+static void dix_version_compare(void)
+{
+    int rc;
+
+    rc = version_compare(0, 0, 1, 0);
+    assert(rc < 0);
+    rc = version_compare(1, 0, 0, 0);
+    assert(rc > 0);
+    rc = version_compare(0, 0, 0, 0);
+    assert(rc == 0);
+    rc = version_compare(1, 0, 1, 0);
+    assert(rc == 0);
+    rc = version_compare(1, 0, 0, 9);
+    assert(rc > 0);
+    rc = version_compare(0, 9, 1, 0);
+    assert(rc < 0);
+    rc = version_compare(1, 0, 1, 9);
+    assert(rc < 0);
+    rc = version_compare(1, 9, 1, 0);
+    assert(rc > 0);
+    rc = version_compare(2, 0, 1, 9);
+    assert(rc > 0);
+    rc = version_compare(1, 9, 2, 0);
+    assert(rc < 0);
+}
+
+int main(int argc, char** argv)
+{
+    dix_version_compare();
+
+    return 0;
+}
diff --git a/xfixes/xfixes.c b/xfixes/xfixes.c
index e8c7bf1..54f0df3 100644
--- a/xfixes/xfixes.c
+++ b/xfixes/xfixes.c
@@ -72,17 +72,17 @@ ProcXFixesQueryVersion(ClientPtr client)
     rep.type = X_Reply;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
-    if (stuff->majorVersion < SERVER_XFIXES_MAJOR_VERSION) {
+
+    if (version_compare(stuff->majorVersion, stuff->minorVersion,
+                        SERVER_XFIXES_MAJOR_VERSION, SERVER_XFIXES_MAJOR_VERSION) < 0)
+    {
 	rep.majorVersion = stuff->majorVersion;
 	rep.minorVersion = stuff->minorVersion;
     } else {
 	rep.majorVersion = SERVER_XFIXES_MAJOR_VERSION;
-	if (stuff->majorVersion == SERVER_XFIXES_MAJOR_VERSION &&
-	    stuff->minorVersion < SERVER_XFIXES_MINOR_VERSION)
-	    rep.minorVersion = stuff->minorVersion;
-	else
-	    rep.minorVersion = SERVER_XFIXES_MINOR_VERSION;
+        rep.minorVersion = SERVER_XFIXES_MINOR_VERSION;
     }
+
     pXFixesClient->major_version = rep.majorVersion;
     pXFixesClient->minor_version = rep.minorVersion;
     if (client->swapped) {
commit c4f9c3a07dbb05b81c8e2193a083102f710ebb27
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 11 11:43:16 2011 +1000

    dix: use a tmp variable instead of multiple rClient(other).
    
    no functional changes.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/dix/events.c b/dix/events.c
index 30b689a..e67c3a2 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2064,23 +2064,24 @@ DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events,
     for (; other; other = other->next)
     {
         Mask mask;
+        ClientPtr client = rClient(other);
 
-        if (IsInterferingGrab(rClient(other), dev, events))
+        if (IsInterferingGrab(client, dev, events))
             continue;
 
         mask = GetEventMask(dev, events, other);
 
-        if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), win,
+        if (XaceHook(XACE_RECEIVE_ACCESS, client, win,
                     events, count))
             /* do nothing */;
-        else if ( (attempt = TryClientEvents(rClient(other), dev,
+        else if ( (attempt = TryClientEvents(client, dev,
                         events, count,
                         mask, filter, grab)) )
         {
             if (attempt > 0)
             {
                 rc = EVENT_DELIVERED;
-                *client_return = rClient(other);
+                *client_return = client;
                 *mask_return = mask;
                 /* Success overrides non-success, so if we've been
                  * successful on one client, return that */
commit dc45d5816dd65168645f0017394eebfc5599d698
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 14 15:59:08 2011 +1000

    Xi: split DeviceStateNotify delivery into a separate function
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index d48d397..c6f9d46 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1189,6 +1189,108 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
     first += ev->num_valuators;
 }
 
+static void
+DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
+{
+    int evcount = 1;
+    deviceStateNotify *ev, *sev;
+    deviceKeyStateNotify *kev;
+    deviceButtonStateNotify *bev;
+
+    KeyClassPtr k;
+    ButtonClassPtr b;
+    ValuatorClassPtr v;
+    int nval = 0, nkeys = 0, nbuttons = 0, first = 0;
+
+    if (!(wOtherInputMasks(win)) ||
+        !(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask))
+        return;
+
+    if ((b = dev->button) != NULL) {
+        nbuttons = b->numButtons;
+        if (nbuttons > 32)
+            evcount++;
+    }
+    if ((k = dev->key) != NULL) {
+        nkeys = k->xkbInfo->desc->max_key_code -
+            k->xkbInfo->desc->min_key_code;
+        if (nkeys > 32)
+            evcount++;
+        if (nbuttons > 0) {
+            evcount++;
+        }
+    }
+    if ((v = dev->valuator) != NULL) {
+        nval = v->numAxes;
+
+        if (nval > 3)
+            evcount++;
+        if (nval > 6) {
+            if (!(k && b))
+                evcount++;
+            if (nval > 9)
+                evcount += ((nval - 7) / 3);
+        }
+    }
+
+    sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent));
+    FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
+
+    if (b != NULL) {
+        FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
+        first += 3;
+        nval -= 3;
+        if (nbuttons > 32) {
+            (ev - 1)->deviceid |= MORE_EVENTS;
+            bev = (deviceButtonStateNotify *) ev++;
+            bev->type = DeviceButtonStateNotify;
+            bev->deviceid = dev->id;
+            memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4);
+        }
+        if (nval > 0) {
+            (ev - 1)->deviceid |= MORE_EVENTS;
+            FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
+            first += 3;
+            nval -= 3;
+        }
+    }
+
+    if (k != NULL) {
+        FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
+        first += 3;
+        nval -= 3;
+        if (nkeys > 32) {
+            (ev - 1)->deviceid |= MORE_EVENTS;
+            kev = (deviceKeyStateNotify *) ev++;
+            kev->type = DeviceKeyStateNotify;
+            kev->deviceid = dev->id;
+            memmove((char *)&kev->keys[0], (char *)&k->down[4], 28);
+        }
+        if (nval > 0) {
+            (ev - 1)->deviceid |= MORE_EVENTS;
+            FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
+            first += 3;
+            nval -= 3;
+        }
+    }
+
+    while (nval > 0) {
+        FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
+        first += 3;
+        nval -= 3;
+        if (nval > 0) {
+            (ev - 1)->deviceid |= MORE_EVENTS;
+            FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
+            first += 3;
+            nval -= 3;
+        }
+    }
+
+    DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
+                          DeviceStateNotifyMask, NullGrab);
+    free(sev);
+}
+
 void
 DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
 		 WindowPtr pWin)
@@ -1255,104 +1357,8 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
 				DeviceFocusChangeMask, NullGrab);
 
-    if ((event.type == DeviceFocusIn) &&
-	(wOtherInputMasks(pWin)) &&
-	(wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask))
-    {
-	int evcount = 1;
-	deviceStateNotify *ev, *sev;
-	deviceKeyStateNotify *kev;
-	deviceButtonStateNotify *bev;
-
-	KeyClassPtr k;
-	ButtonClassPtr b;
-	ValuatorClassPtr v;
-	int nval = 0, nkeys = 0, nbuttons = 0, first = 0;
-
-	if ((b = dev->button) != NULL) {
-	    nbuttons = b->numButtons;
-	    if (nbuttons > 32)
-		evcount++;
-	}
-	if ((k = dev->key) != NULL) {
-	    nkeys = k->xkbInfo->desc->max_key_code -
-                    k->xkbInfo->desc->min_key_code;
-	    if (nkeys > 32)
-		evcount++;
-	    if (nbuttons > 0) {
-		evcount++;
-	    }
-	}
-	if ((v = dev->valuator) != NULL) {
-	    nval = v->numAxes;
-
-	    if (nval > 3)
-		evcount++;
-	    if (nval > 6) {
-		if (!(k && b))
-		    evcount++;
-		if (nval > 9)
-		    evcount += ((nval - 7) / 3);
-	    }
-	}
-
-	sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent));
-	FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
-
-	if (b != NULL) {
-	    FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
-	    first += 3;
-	    nval -= 3;
-	    if (nbuttons > 32) {
-		(ev - 1)->deviceid |= MORE_EVENTS;
-		bev = (deviceButtonStateNotify *) ev++;
-		bev->type = DeviceButtonStateNotify;
-		bev->deviceid = dev->id;
-		memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4);
-	    }
-	    if (nval > 0) {
-		(ev - 1)->deviceid |= MORE_EVENTS;
-		FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
-		first += 3;
-		nval -= 3;
-	    }
-	}
-
-	if (k != NULL) {
-	    FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
-	    first += 3;
-	    nval -= 3;
-	    if (nkeys > 32) {
-		(ev - 1)->deviceid |= MORE_EVENTS;
-		kev = (deviceKeyStateNotify *) ev++;
-		kev->type = DeviceKeyStateNotify;
-		kev->deviceid = dev->id;
-		memmove((char *)&kev->keys[0], (char *)&k->down[4], 28);
-	    }
-	    if (nval > 0) {
-		(ev - 1)->deviceid |= MORE_EVENTS;
-		FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
-		first += 3;
-		nval -= 3;
-	    }
-	}
-
-	while (nval > 0) {
-	    FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
-	    first += 3;
-	    nval -= 3;
-	    if (nval > 0) {
-		(ev - 1)->deviceid |= MORE_EVENTS;
-		FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
-		first += 3;
-		nval -= 3;
-	    }
-	}
-
-	DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount,
-				    DeviceStateNotifyMask, NullGrab);
-	free(sev);
-    }
+    if (event.type == DeviceFocusIn)
+        DeliverStateNotifyEvent(dev, pWin);
 }
 
 int
commit 5bcc22757e6e1f24ee2bfec65f68a5f567300532
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 14 15:43:56 2011 +1000

    dix: return deliveries from DeliverGrabbedEvent
    
    This isn't currently used by any of the callers but it will likely be in the
    future.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/dix/events.c b/dix/events.c
index aeb37aa..30b689a 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3884,8 +3884,10 @@ unwind:
  * grab. If not, TryClientEvents() is used.
  *
  * @param deactivateGrab True if the device's grab should be deactivated.
+ *
+ * @return The number of events delivered.
  */
-void
+int
 DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
                     Bool deactivateGrab)
 {
@@ -4053,6 +4055,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
     free(core);
     free(xi);
     free(xi2);
+
+    return deliveries;
 }
 
 /* This function is used to set the key pressed or key released state -
diff --git a/include/dix.h b/include/dix.h
index fb9be43..9a111e8 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -415,7 +415,7 @@ extern void DeliverFocusedEvent(
     InternalEvent* /* event */,
     WindowPtr /* window */);
 
-extern void DeliverGrabbedEvent(
+extern int DeliverGrabbedEvent(
     InternalEvent* /* event */,
     DeviceIntPtr /* thisDev */,
     Bool /* deactivateGrab */);
commit 2054ca73060a20b5a3025e8d5ef68182149484d3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 14 15:09:39 2011 +1000

    dix: move the grab activation condition into a if block.
    
    Rather than 3 conditions with if (deliveries && ...), have one block with
    the three in them.
    No functional changes.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/dix/events.c b/dix/events.c
index 77f8715..aeb37aa 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2173,24 +2173,22 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
         }
     }
 
-    /*
-     * Note that since core events are delivered first, an implicit grab may
-     * be activated on a core grab, stopping the XI events.
-     */
-    if (deliveries && !grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask))
-        /* grab activated */;
-    else if ((type == MotionNotify) && deliveries)
-	pDev->valuator->motionHintWindow = pWin;
-    else
-    {
-	if ((type == DeviceMotionNotify || type == DeviceButtonPress) &&
-	    deliveries)
-	    CheckDeviceGrabAndHintWindow (pWin, type,
-					  (deviceKeyButtonPointer*) pEvents,
-					  grab, client, deliveryMask);
-    }
     if (deliveries)
+    {
+        /*
+         * Note that since core events are delivered first, an implicit grab may
+         * be activated on a core grab, stopping the XI events.
+         */
+        if (!grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask))
+            /* grab activated */;
+        else if ((type == MotionNotify))
+            pDev->valuator->motionHintWindow = pWin;
+        else if (type == DeviceMotionNotify || type == DeviceButtonPress)
+                CheckDeviceGrabAndHintWindow (pWin, type,
+                                              (deviceKeyButtonPointer*) pEvents,
+                                              grab, client, deliveryMask);
 	return deliveries;
+    }
     return nondeliveries;
 }
 
commit 236ed6f50675dc0303a505ac6f0418c515438fe1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 12 14:04:37 2011 +1000

    dix: split out client delivery from DeliverEventsToWindow
    
    No real functional changes, this is just for improved readability.
    
    DeliverEventsToWindow used to return an int to specify the number of
    deliveries (or rejected deliveries if negative). The number wasn't used by
    any caller other than for > 0 comparison.
    
    This patch also changes the return value to be -1 or 1 even in case of
    multiple deliveries/rejections. The comment was updated accordingly.
    
    A future patch should probably use the enum EventDeliveryState for
    DeliverEventsToWindow.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/dix/events.c b/dix/events.c
index 4e9af8d..77f8715 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2025,6 +2025,75 @@ DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win,
 }
 
 /**
+ * Deliver events to clients registered on the window.
+ *
+ * @param client_return On successful delivery, set to the recipient.
+ * @param mask_return On successful delivery, set to the recipient's event
+ * mask for this event.
+ */
+static enum EventDeliveryState
+DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events,
+                      int count, Mask filter, GrabPtr grab,
+                      ClientPtr *client_return, Mask *mask_return)
+{
+    int attempt;
+    enum EventDeliveryState rc = EVENT_SKIP;
+    InputClients *other;
+
+    if (CORE_EVENT(events))
+        other = (InputClients *)wOtherClients(win);
+    else if (XI2_EVENT(events))
+    {
+        OtherInputMasks *inputMasks = wOtherInputMasks(win);
+        /* Has any client selected for the event? */
+        if (!GetWindowXI2Mask(dev, win, events))
+            goto out;
+        other = inputMasks->inputClients;
+    } else {
+        OtherInputMasks *inputMasks = wOtherInputMasks(win);
+        /* Has any client selected for the event? */
+        if (!inputMasks ||
+            !(inputMasks->inputEvents[dev->id] & filter))
+            goto out;
+
+        other = inputMasks->inputClients;
+    }
+
+    rc = EVENT_NOT_DELIVERED;
+
+    for (; other; other = other->next)
+    {
+        Mask mask;
+
+        if (IsInterferingGrab(rClient(other), dev, events))
+            continue;
+
+        mask = GetEventMask(dev, events, other);
+
+        if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), win,
+                    events, count))
+            /* do nothing */;
+        else if ( (attempt = TryClientEvents(rClient(other), dev,
+                        events, count,
+                        mask, filter, grab)) )
+        {
+            if (attempt > 0)
+            {
+                rc = EVENT_DELIVERED;
+                *client_return = rClient(other);
+                *mask_return = mask;
+                /* Success overrides non-success, so if we've been
+                 * successful on one client, return that */
+            } else if (rc == EVENT_NOT_DELIVERED)
+                rc = EVENT_REJECTED;
+        }
+    }
+
+out:
+    return rc;
+}
+
+/**
  * Deliver events to a window. At this point, we do not yet know if the event
  * actually needs to be delivered. May activate a grab if the event is a
  * button press.
@@ -2042,21 +2111,20 @@ DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win,
  * @param filter Mask based on event type.
  * @param grab Possible grab on the device that caused the event.
  *
- * @return Number of events delivered to various clients.
+ * @return a positive number if at least one successful delivery has been
+ * made, 0 if no events were delivered, or a negative number if the event
+ * has not been delivered _and_ rejected by at least one client.
  */
 int
 DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
         *pEvents, int count, Mask filter, GrabPtr grab)
 {
     int deliveries = 0, nondeliveries = 0;
-    int attempt;
-    InputClients *other;
     ClientPtr client = NullClient;
     Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
 		              this mask is the mask of the grab. */
     int type = pEvents->u.u.type;
 
-
     /* Deliver to window owner */
     if ((filter == CantBeFiltered) || CORE_EVENT(pEvents))
     {
@@ -2085,50 +2153,26 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
     /* CantBeFiltered means only window owner gets the event */
     if (filter != CantBeFiltered)
     {
-        if (CORE_EVENT(pEvents))
-            other = (InputClients *)wOtherClients(pWin);
-        else if (XI2_EVENT(pEvents))
-        {
-            OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
-            /* Has any client selected for the event? */
-            if (!GetWindowXI2Mask(pDev, pWin, pEvents))
-                return 0;
-            other = inputMasks->inputClients;
-        } else {
-            OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
-            /* Has any client selected for the event? */
-            if (!inputMasks ||
-                !(inputMasks->inputEvents[pDev->id] & filter))
-                return 0;
+        enum EventDeliveryState rc;
 
-            other = inputMasks->inputClients;
-        }
+        rc = DeliverEventToClients(pDev, pWin, pEvents, count, filter, grab,
+                                   &client, &deliveryMask);
 
-        for (; other; other = other->next)
+        switch(rc)
         {
-            Mask mask;
-            if (IsInterferingGrab(rClient(other), pDev, pEvents))
-                continue;
-
-            mask = GetEventMask(pDev, pEvents, other);
-
-            if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
-                        pEvents, count))
-                /* do nothing */;
-            else if ( (attempt = TryClientEvents(rClient(other), pDev,
-                            pEvents, count,
-                            mask, filter, grab)) )
-            {
-                if (attempt > 0)
-                {
-                    deliveries++;
-                    client = rClient(other);
-                    deliveryMask = mask;
-                } else
-                    nondeliveries--;
-            }
+            case EVENT_SKIP:
+                return 0;
+            case EVENT_REJECTED:
+                nondeliveries--;
+                break;
+            case EVENT_DELIVERED:
+                deliveries++;
+                break;
+            case EVENT_NOT_DELIVERED:
+                break;
         }
     }
+
     /*
      * Note that since core events are delivered first, an implicit grab may
      * be activated on a core grab, stopping the XI events.
commit 536ca28f1b0b4d8715a41b8acc5f30364c833f9b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 12 13:44:30 2011 +1000

    dix: split out window owner event delivery from DeliverEventsToWindow
    
    No functional changes, just for readability.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>

diff --git a/dix/events.c b/dix/events.c
index fb114a7..4e9af8d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1987,6 +1987,43 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
     return TRUE;
 }
 
+enum EventDeliveryState {
+    EVENT_DELIVERED,     /**< Event has been delivered to a client  */
+    EVENT_NOT_DELIVERED, /**< Event was not delivered to any client */
+    EVENT_SKIP,          /**< Event can be discarded by the caller  */
+    EVENT_REJECTED,      /**< Event was rejected for delivery to the client */
+};
+
+/**
+ * Attempt event delivery to the client owning the window.
+ */
+static enum EventDeliveryState
+DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win,
+                     xEvent *events, int count, Mask filter,
+                     GrabPtr grab)
+{
+    /* if nobody ever wants to see this event, skip some work */
+    if (filter != CantBeFiltered &&
+            !((wOtherEventMasks(win)|win->eventMask) & filter))
+        return EVENT_SKIP;
+
+    if (IsInterferingGrab(wClient(win), dev, events))
+        return EVENT_SKIP;
+
+    if (!XaceHook(XACE_RECEIVE_ACCESS, wClient(win), win, events, count))
+    {
+        int attempt = TryClientEvents(wClient(win), dev, events,
+                                      count, win->eventMask,
+                                      filter, grab);
+        if (attempt > 0)
+            return EVENT_DELIVERED;
+        if (attempt < 0)
+            return EVENT_REJECTED;
+    }
+
+    return EVENT_NOT_DELIVERED;
+}
+
 /**
  * Deliver events to a window. At this point, we do not yet know if the event
  * actually needs to be delivered. May activate a grab if the event is a
@@ -2023,28 +2060,26 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
     /* Deliver to window owner */
     if ((filter == CantBeFiltered) || CORE_EVENT(pEvents))
     {
-	/* if nobody ever wants to see this event, skip some work */
-	if (filter != CantBeFiltered &&
-	    !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
-	    return 0;
+        enum EventDeliveryState rc;
 
-        if (IsInterferingGrab(wClient(pWin), pDev, pEvents))
-                return 0;
+        rc = DeliverToWindowOwner(pDev, pWin, pEvents, count, filter, grab);
 
-	if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
-	    /* do nothing */;
-        else if ( (attempt = TryClientEvents(wClient(pWin), pDev, pEvents,
-                                             count, pWin->eventMask,
-                                             filter, grab)) )
-	{
-	    if (attempt > 0)
-	    {
-		deliveries++;
-		client = wClient(pWin);
-		deliveryMask = pWin->eventMask;
-	    } else
-		nondeliveries--;
-	}
+        switch(rc)
+        {
+            case EVENT_SKIP:
+                return 0;
+            case EVENT_REJECTED:
+                nondeliveries--;
+                break;
+            case EVENT_DELIVERED:
+                /* We delivered to the owner, with our event mask */
+                deliveries++;
+                client = wClient(pWin);
+                deliveryMask = pWin->eventMask;
+                break;
+            case EVENT_NOT_DELIVERED:
+                break;
+        }
     }
 
     /* CantBeFiltered means only window owner gets the event */
commit a311a03135f9734aa4f7dc0f2fa0e4c91768343b
Author: Jamey Sharp <jamey at minilop.net>
Date:   Wed May 11 14:08:28 2011 -0700

    dix: split implicit grab activation into a separate function.
    
    I'm not sure I like splitting the check for button-press event from the
    code which makes assumptions about that check. How about replacing
    patches 3 and 4 with this patch instead?
    
    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/dix/events.c b/dix/events.c
index 276bc75..fb114a7 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1939,6 +1939,54 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
     return 1;
 }
 
+static BOOL
+ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
+                     xEvent *event, Mask deliveryMask)
+{
+    GrabRec tempGrab;
+    OtherInputMasks *inputMasks;
+    CARD8 type = event->u.u.type;
+    GrabType grabtype;
+
+    if (type == ButtonPress)
+        grabtype = GRABTYPE_CORE;
+    else if (type == DeviceButtonPress)
+        grabtype = GRABTYPE_XI;
+    else if (XI2_EVENT(event) && ((xGenericEvent*)event)->evtype == XI_ButtonPress)
+    {
+        type = ((xGenericEvent*)event)->evtype;
+        grabtype = GRABTYPE_XI2;
+    }
+    else
+        return FALSE;
+
+    memset(&tempGrab, 0, sizeof(GrabRec));
+    tempGrab.next = NULL;
+    tempGrab.device = dev;
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.window = win;
+    tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+    tempGrab.eventMask = deliveryMask;
+    tempGrab.keyboardMode = GrabModeAsync;
+    tempGrab.pointerMode = GrabModeAsync;
+    tempGrab.confineTo = NullWindow;
+    tempGrab.cursor = NullCursor;
+    tempGrab.type = type;
+    tempGrab.grabtype = grabtype;
+
+    /* get the XI and XI2 device mask */
+    inputMasks = wOtherInputMasks(win);
+    tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
+
+    if (inputMasks)
+        memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
+               sizeof(tempGrab.xi2mask));
+
+    (*dev->deviceGrab.ActivateGrab)(dev, &tempGrab,
+                                    currentTime, TRUE | ImplicitGrabMask);
+    return TRUE;
+}
+
 /**
  * Deliver events to a window. At this point, we do not yet know if the event
  * actually needs to be delivered. May activate a grab if the event is a
@@ -2050,47 +2098,8 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
      * Note that since core events are delivered first, an implicit grab may
      * be activated on a core grab, stopping the XI events.
      */
-    if ((type == DeviceButtonPress || type == ButtonPress ||
-        ((XI2_EVENT(pEvents) && ((xGenericEvent*)pEvents)->evtype == XI_ButtonPress)))
-            && deliveries
-            && (!grab))
-    {
-	GrabRec tempGrab;
-        OtherInputMasks *inputMasks;
-
-        memset(&tempGrab, 0, sizeof(GrabRec));
-        tempGrab.next = NULL;
-	tempGrab.device = pDev;
-	tempGrab.resource = client->clientAsMask;
-	tempGrab.window = pWin;
-	tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
-	tempGrab.eventMask = deliveryMask;
-	tempGrab.keyboardMode = GrabModeAsync;
-	tempGrab.pointerMode = GrabModeAsync;
-	tempGrab.confineTo = NullWindow;
-	tempGrab.cursor = NullCursor;
-        tempGrab.type = type;
-        if (type == ButtonPress)
-            tempGrab.grabtype = GRABTYPE_CORE;
-        else if (type == DeviceButtonPress)
-            tempGrab.grabtype = GRABTYPE_XI;
-        else
-        {
-            tempGrab.type = ((xGenericEvent*)pEvents)->evtype;
-            tempGrab.grabtype = GRABTYPE_XI2;
-        }
-
-        /* get the XI and XI2 device mask */
-        inputMasks = wOtherInputMasks(pWin);
-        tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0;
-
-        if (inputMasks)
-            memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
-                    sizeof(tempGrab.xi2mask));
-
-	(*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab,
-                                        currentTime, TRUE | ImplicitGrabMask);
-    }
+    if (deliveries && !grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask))
+        /* grab activated */;
     else if ((type == MotionNotify) && deliveries)
 	pDev->valuator->motionHintWindow = pWin;
     else
commit c8674a328c68f03de6e4fad7790a595cdfc18736
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 14 16:45:56 2011 +1000

    dix: replace unneded goto with break.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 14731f4..024f2e8 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -156,7 +156,7 @@ EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
         case ET_RawButtonRelease:
         case ET_RawMotion:
             ret = BadMatch;
-            goto out;
+            break;
         default:
             /* XXX: */
             ErrorF("[dix] EventToCore: Not implemented yet \n");
commit 20fb07f436f7d4a0f330b2067a93a5a4829fccf5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 15 10:07:10 2011 +1000

    input: remove DDX event list handling
    
    The current approach to event posting required the DDX to request the event
    list (allocated by the DIX) and then pass that list into QueuePointerEvent
    and friends.
    
    Remove this step and use the DIX event list directly. This means that
    QueuePointerEvent is not reentrant but it wasn't before anyway.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/dix/events.c b/dix/events.c
index 895ab40..276bc75 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -5035,8 +5035,7 @@ InitEvents(void)
 	DontPropagateRefCnts[i] = 0;
     }
 
-    InputEventListLen = GetMaximumEventsNum();
-    InputEventList = InitEventList(InputEventListLen);
+    InputEventList = InitEventList(GetMaximumEventsNum());
     if (!InputEventList)
         FatalError("[dix] Failed to allocate input event list.\n");
 }
@@ -5044,8 +5043,7 @@ InitEvents(void)
 void
 CloseDownEvents(void)
 {
-    FreeEventList(InputEventList, InputEventListLen);
-    InputEventListLen = 0;
+    FreeEventList(InputEventList, GetMaximumEventsNum());
     InputEventList = NULL;
 }
 
diff --git a/dix/getevents.c b/dix/getevents.c
index e8c2f45..13789f6 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -68,19 +68,12 @@
 /* Number of motion history events to store. */
 #define MOTION_HISTORY_SIZE 256
 
-/* InputEventList is the storage for input events generated by the
- * DDX. The DDX is expected to call GetEventList() and then pass the list into
- * Get{Pointer|Keyboard}Events.
+/**
+ * InputEventList is the storage for input events generated by
+ * QueuePointerEvents, QueueKeyboardEvents, and QueueProximityEvents.
+ * This list is allocated on startup by the DIX.
  */
 InternalEvent* InputEventList = NULL;
-int InputEventListLen = 0;
-
-int
-GetEventList(InternalEvent** list)
-{
-    *list = InputEventList;
-    return InputEventListLen;
-}
 
 /**
  * Pick some arbitrary size for Xi motion history.
@@ -937,10 +930,10 @@ queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents)
  * Generate internal events representing this keyboard event and enqueue
  * them on the event queue.
  *
- * FIXME: don't require the event list to be passed in.
+ * This function is not reentrant. Disable signals before calling.
+ *
  * FIXME: flags for relative/abs motion?
  *
- * @param events Event list used as temporary storage
  * @param device The device to generate the event for
  * @param type Event type, one of KeyPress or KeyRelease
  * @param keycode Key code of the pressed/released key
@@ -948,13 +941,13 @@ queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents)
  *
  */
 void
-QueueKeyboardEvents(InternalEvent *events, DeviceIntPtr device, int type,
+QueueKeyboardEvents(DeviceIntPtr device, int type,
                     int keycode, const ValuatorMask *mask)
 {
     int nevents;
 
-    nevents = GetKeyboardEvents(events, device, type, keycode, mask);
-    queueEventList(device, events, nevents);
+    nevents = GetKeyboardEvents(InputEventList, device, type, keycode, mask);
+    queueEventList(device, InputEventList, nevents);
 }
 
 /**
@@ -1074,9 +1067,8 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y)
  * Generate internal events representing this pointer event and enqueue them
  * on the event queue.
  *
- * FIXME: don't require the event list to be passed in.
+ * This function is not reentrant. Disable signals before calling.
  *
- * @param events Set of events list used as temporary storage
  * @param device The device to generate the event for
  * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify
  * @param buttons Button number of the buttons modified. Must be 0 for
@@ -1085,13 +1077,13 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y)
  * @param mask Valuator mask for valuators present for this event.
  */
 void
-QueuePointerEvents(InternalEvent *events, DeviceIntPtr device, int type,
+QueuePointerEvents(DeviceIntPtr device, int type,
                    int buttons, int flags, const ValuatorMask *mask)
 {
     int nevents;
 
-    nevents = GetPointerEvents(events, device, type, buttons, flags, mask);
-    queueEventList(device, events, nevents);
+    nevents = GetPointerEvents(InputEventList, device, type, buttons, flags, mask);
+    queueEventList(device, InputEventList, nevents);
 }
 
 /**
@@ -1252,9 +1244,8 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons
  * Generate internal events representing this proximity event and enqueue
  * them on the event queue.
  *
- * FIXME: don't require the event list to be passed in.
+ * This function is not reentrant. Disable signals before calling.
  *
- * @param events Event list used as temporary storage
  * @param device The device to generate the event for
  * @param type Event type, one of ProximityIn or ProximityOut
  * @param keycode Key code of the pressed/released key
@@ -1262,13 +1253,13 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons
  *
  */
 void
-QueueProximityEvents(InternalEvent *events, DeviceIntPtr device, int type,
+QueueProximityEvents(DeviceIntPtr device, int type,
                      const ValuatorMask *mask)
 {
     int nevents;
 
-    nevents = GetProximityEvents(events, device, type, mask);
-    queueEventList(device, events, nevents);
+    nevents = GetProximityEvents(InputEventList, device, type, mask);
+    queueEventList(device, InputEventList, nevents);
 }
 
 /**
diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index 8aa1b80..41bc4bf 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -177,15 +177,13 @@ static void enqueueMotion(DevicePtr pDev, int x, int y)
     GETDMXLOCALFROMPDEV;
     DeviceIntPtr p = dmxLocal->pDevice;
     int valuators[3];
-    InternalEvent* events;
     int detail = 0;  /* XXX should this be mask of pressed buttons? */
     ValuatorMask mask;
     valuators[0] = x;
     valuators[1] = y;
 
     valuator_mask_set_range(&mask, 0, 2, valuators);
-    GetEventList(&events);
-    QueuePointerEvents(events, p, MotionNotify, detail,
+    QueuePointerEvents(p, MotionNotify, detail,
                        POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
     return;
 }
@@ -290,7 +288,6 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
     int                    thisX   = 0;
     int                    thisY   = 0;
     int                    count;
-    InternalEvent*         events;
     ValuatorMask           mask;
 
     memset(xE, 0, sizeof(xE));
@@ -372,8 +369,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
     if (block)
         dmxSigioBlock();
     valuator_mask_set_range(&mask, firstAxis, axesCount, v);
-    GetEventList(&events);
-    QueuePointerEvents(events, pDevice, MotionNotify, 0,
+    QueuePointerEvents(pDevice, MotionNotify, 0,
                        POINTER_ABSOLUTE, &mask);
 
     if (block)
@@ -389,7 +385,6 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     XDeviceMotionEvent     *me     = (XDeviceMotionEvent *)e;
     DeviceIntPtr           pDevice = dmxLocal->pDevice;
     int                    valuators[MAX_VALUATORS];
-    InternalEvent*         events;
     ValuatorMask           mask;
 
     if (!e)
@@ -446,8 +441,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
         if (block)
             dmxSigioBlock();
-        GetEventList(&events);
-        QueueKeyboardEvents(events, pDevice, event, ke->keycode, &mask);
+        QueueKeyboardEvents(pDevice, event, ke->keycode, &mask);
         if (block)
             dmxSigioUnblock();
         break;
@@ -457,8 +451,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
         if (block)
             dmxSigioBlock();
-        GetEventList(&events);
-        QueuePointerEvents(events, pDevice, event, ke->keycode,
+        QueuePointerEvents(pDevice, event, ke->keycode,
                            POINTER_ABSOLUTE, &mask);
         if (block)
             dmxSigioUnblock();
@@ -469,8 +462,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
         if (block)
             dmxSigioBlock();
-        GetEventList(&events);
-        QueueProximityEvents(events, pDevice, event, &mask);
+        QueueProximityEvents(pDevice, event, &mask);
         if (block)
             dmxSigioUnblock();
         break;
@@ -652,7 +644,6 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
     xEvent xE;
     DeviceIntPtr p = dmxLocal->pDevice;
     int valuators[3];
-    InternalEvent* events;
     ValuatorMask mask;
 
     DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail);
@@ -667,27 +658,24 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
         if (dmxLocal->sendsCore && dmxLocal != dmxLocalCoreKeyboard)
             xE.u.u.detail = dmxFixup(pDev, detail, keySym);
 
-        GetEventList(&events);
         /*ErrorF("KEY %d  sym %d\n", detail, (int) keySym);*/
-        QueueKeyboardEvents(events, p, type, detail, NULL);
+        QueueKeyboardEvents(p, type, detail, NULL);
         return;
 
     case ButtonPress:
     case ButtonRelease:
         detail = dmxGetButtonMapping(dmxLocal, detail);
         valuator_mask_zero(&mask);
-        GetEventList(&events);
-        QueuePointerEvents(events, p, type, detail,
+        QueuePointerEvents(p, type, detail,
                            POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
         return;
 
     case MotionNotify:
-        GetEventList(&events);
         valuators[0] = e->xmotion.x;
         valuators[1] = e->xmotion.y;
         valuators[2] = e->xmotion.state; /* FIXME: WTF?? */
         valuator_mask_set_range(&mask, 0, 3, valuators);
-        QueuePointerEvents(events, p, type, detail,
+        QueuePointerEvents(p, type, detail,
                            POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
         return;
 
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 62e8f78..cdf55d7 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -66,8 +66,6 @@ static struct KdConfigDevice *kdConfigPointers    = NULL;
 static KdKeyboardDriver *kdKeyboardDrivers = NULL;
 static KdPointerDriver  *kdPointerDrivers  = NULL;
 
-static InternalEvent*   kdEvents = NULL;
-
 static Bool		kdInputEnabled;
 static Bool		kdOffScreen;
 static unsigned long	kdOffScreenTime;
@@ -1803,8 +1801,7 @@ KdReleaseAllKeys (void)
              key++) {
             if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) {
                 KdHandleKeyboardEvent(ki, KeyRelease, key);
-                GetEventList(&kdEvents);
-                QueueGetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key, NULL);
+                QueueGetKeyboardEvents(ki->dixdev, KeyRelease, key, NULL);
             }
         }
     }
@@ -1860,8 +1857,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo   *ki,
 	else
 	    type = KeyPress;
 
-        GetEventList(&kdEvents);
-        QueueKeyboardEvents(kdEvents, ki->dixdev, type, key_code, NULL);
+        QueueKeyboardEvents(ki->dixdev, type, key_code, NULL);
     }
     else {
         ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n",
@@ -1969,8 +1965,7 @@ _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z,
 
     valuator_mask_set_range(&mask, 0, 3, valuators);
 
-    GetEventList(&kdEvents);
-    QueuePointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask);
+    QueuePointerEvents(pi->dixdev, type, b, absrel, &mask);
 }
 
 void
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 6402d72..c4a4db9 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -399,7 +399,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
          i++) {
         if (key_is_down(pDev, i, KEY_POSTED)) {
             sigstate = xf86BlockSIGIO ();
-            QueueKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL);
+            QueueKeyboardEvents(pDev, KeyRelease, i, NULL);
             xf86UnblockSIGIO(sigstate);
         }
     }
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 0b36163..53f763a 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -806,8 +806,6 @@ InitInput(int argc, char **argv)
 
     mieqInit();
 
-    GetEventList(&xf86Events);
-
     /* Initialize all configured input devices */
     for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
         /* Replace obsolete keyboard driver with kbd */
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 015e12c..5d91ab3 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -148,9 +148,6 @@ extern _X_EXPORT int xf86SetVerbosity(int verb);
 extern _X_EXPORT int xf86SetLogVerbosity(int verb);
 extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only );
 
-/* xf86Xinput.c */
-extern _X_EXPORT InternalEvent *xf86Events;
-
 #endif /* _NO_XF86_PROTOTYPES */
 
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 9827661..e7e1ce1 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -99,8 +99,6 @@
 		return;								\
 	}
 
-InternalEvent* xf86Events = NULL;
-
 static int
 xf86InputDevicePostInit(DeviceIntPtr dev);
 
@@ -1049,7 +1047,7 @@ xf86PostMotionEventM(DeviceIntPtr	device,
         }
 #endif
 
-    QueuePointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
+    QueuePointerEvents(device, MotionNotify, 0, flags, mask);
 }
 
 void
@@ -1094,8 +1092,7 @@ xf86PostProximityEventM(DeviceIntPtr	device,
                         int		is_in,
                         const ValuatorMask *mask)
 {
-    QueueProximityEvents(xf86Events, device,
-                         is_in ? ProximityIn : ProximityOut, mask);
+    QueueProximityEvents(device, is_in ? ProximityIn : ProximityOut, mask);
 }
 
 void
@@ -1166,7 +1163,7 @@ xf86PostButtonEventM(DeviceIntPtr	device,
     }
 #endif
 
-    QueuePointerEvents(xf86Events, device,
+    QueuePointerEvents(device,
                        is_down ? ButtonPress : ButtonRelease, button,
                        flags, mask);
 }
@@ -1233,7 +1230,7 @@ xf86PostKeyEventM(DeviceIntPtr	device,
     }
 #endif
 
-    QueueKeyboardEvents(xf86Events, device,
+    QueueKeyboardEvents(device,
                         is_down ? KeyPress : KeyRelease,
                         key_code, mask);
 }
diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c
index bbd70bf..619427d 100644
--- a/hw/xnest/Events.c
+++ b/hw/xnest/Events.c
@@ -43,8 +43,6 @@ is" without express or implied warranty.
 
 CARD32 lastEventTime = 0;
 
-extern InternalEvent *xnestEvents;
-
 void
 ProcessInputEvents(void)
 {
@@ -104,9 +102,8 @@ xnestCollectExposures(void)
 void
 xnestQueueKeyEvent(int type, unsigned int keycode)
 {
-  GetEventList(&xnestEvents);
   lastEventTime = GetTimeInMillis();
-  QueueKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode, NULL);
+  QueueKeyboardEvents(xnestKeyboardDevice, type, keycode, NULL);
 }
 
 void
@@ -116,7 +113,6 @@ xnestCollectEvents(void)
   int valuators[2];
   ValuatorMask mask;
   ScreenPtr pScreen;
-  GetEventList(&xnestEvents);
 
   while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
     switch (X.type) {
@@ -134,7 +130,7 @@ xnestCollectEvents(void)
       valuator_mask_set_range(&mask, 0, 0, NULL);
       xnestUpdateModifierState(X.xkey.state);
       lastEventTime = GetTimeInMillis();
-      QueuePointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
+      QueuePointerEvents(xnestPointerDevice, ButtonPress,
                          X.xbutton.button, POINTER_RELATIVE, &mask);
       break;
       
@@ -142,7 +138,7 @@ xnestCollectEvents(void)
       valuator_mask_set_range(&mask, 0, 0, NULL);
       xnestUpdateModifierState(X.xkey.state);
       lastEventTime = GetTimeInMillis();
-      QueuePointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
+      QueuePointerEvents(xnestPointerDevice, ButtonRelease,
                          X.xbutton.button, POINTER_RELATIVE, &mask);
       break;
       
@@ -151,7 +147,7 @@ xnestCollectEvents(void)
       valuators[1] = X.xmotion.y;
       valuator_mask_set_range(&mask, 0, 2, valuators);
       lastEventTime = GetTimeInMillis();
-      QueuePointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
+      QueuePointerEvents(xnestPointerDevice, MotionNotify,
                          0, POINTER_ABSOLUTE, &mask);
       break;
       
@@ -183,7 +179,7 @@ xnestCollectEvents(void)
           valuators[1] = X.xcrossing.y;
           valuator_mask_set_range(&mask, 0, 2, valuators);
           lastEventTime = GetTimeInMillis();
-          QueuePointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
+          QueuePointerEvents(xnestPointerDevice, MotionNotify,
                              0, POINTER_ABSOLUTE, &mask);
 	  xnestDirectInstallColormaps(pScreen);
 	}
diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c
index f8637f2..ee74101 100644
--- a/hw/xnest/Init.c
+++ b/hw/xnest/Init.c
@@ -45,8 +45,6 @@ is" without express or implied warranty.
 
 Bool xnestDoFullGeneration = True;
 
-InternalEvent *xnestEvents = NULL;
-
 void
 InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
 {
@@ -100,8 +98,6 @@ InitInput(int argc, char *argv[])
   if (rc != Success)
       FatalError("Failed to init Xnest default devices.\n");
 
-  GetEventList(&xnestEvents);
-
   mieqInit();
 
   AddEnabledDevice(XConnectionNumber(xnestDisplay));
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 6736e3d..fe744b7 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -485,8 +485,7 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa
     darwinEvents_lock(); {
         ValuatorMask mask;
         valuator_mask_set_range(&mask, 0, (pDev == darwinPointer) ? 2 : 5, valuators);
-        QueuePointerEvents(darwinEvents, pDev, ev_type, ev_button,
-                           POINTER_ABSOLUTE, &mask);
+        QueuePointerEvents(pDev, ev_type, ev_button, POINTER_ABSOLUTE, &mask);
         DarwinPokeEQ();
     } darwinEvents_unlock();
 }
@@ -499,7 +498,7 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
 	}
 
     darwinEvents_lock(); {
-        QueueKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL);
+        QueueKeyboardEvents(darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL);
         DarwinPokeEQ();
     } darwinEvents_unlock();
 }
@@ -526,7 +525,7 @@ void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x,
     darwinEvents_lock(); {
         ValuatorMask mask;
         valuator_mask_set_range(&mask, 0, 5, valuators);
-        QueueProximityEvents(darwinEvents, pDev, ev_type, &mask);
+        QueueProximityEvents(pDev, ev_type, &mask);
         DarwinPokeEQ();
     } darwinEvents_unlock();
 }
diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index 8b6be02..2fa6b3f 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -483,8 +483,7 @@ winSendKeyEvent (DWORD dwKey, Bool fDown)
   /* Update the keyState map */
   g_winKeyState[dwKey] = fDown;
 
-  GetEventList(&events);
-  QueueKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL);
+  QueueKeyboardEvents(g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL);
 
   winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n",
            dwKey, fDown, nevents);
diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c
index aaa4d4b..b1b0657 100644
--- a/hw/xwin/winmouse.c
+++ b/hw/xwin/winmouse.c
@@ -234,15 +234,13 @@ winMouseWheel (ScreenPtr pScreen, int iDeltaZ)
 void
 winMouseButtonsSendEvent (int iEventType, int iButton)
 {
-  InternalEvent* events;
   ValuatorMask mask;
 
   if (g_winMouseButtonMap)
     iButton = g_winMouseButtonMap[iButton];
 
   valuator_mask_zero(&mask);
-  GetEventList(&events);
-  QueuePointerEvents(events, g_pwinPointer, iEventType, iButton,
+  QueuePointerEvents(g_pwinPointer, iEventType, iButton,
 		     POINTER_RELATIVE, &mask);
 
 #if CYGDEBUG
@@ -365,15 +363,13 @@ void winEnqueueMotion(int x, int y)
 {
   int valuators[2];
   ValuatorMask mask;
-  InternalEvent* events;
 
   miPointerSetPosition(g_pwinPointer, POINTER_RELATIVE, &x, &y);
   valuators[0] = x;
   valuators[1] = y;
 
   valuator_mask_set_range(&mask, 0, 2, valuators);
-  GetEventList(&events);
-  QueuePointerEvents(events, g_pwinPointer, MotionNotify, 0,
+  QueuePointerEvents(g_pwinPointer, MotionNotify, 0,
 		     POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
 
 }
diff --git a/include/input.h b/include/input.h
index 3c7740d..4de4ff5 100644
--- a/include/input.h
+++ b/include/input.h
@@ -111,7 +111,6 @@ typedef struct _ValuatorMask ValuatorMask;
 
 /* The DIX stores incoming input events in this list */
 extern InternalEvent* InputEventList;
-extern int InputEventListLen;
 
 typedef int (*DeviceProc)(
     DeviceIntPtr /*device*/,
@@ -429,7 +428,6 @@ extern _X_EXPORT void CloseInput(void);
 
 extern _X_EXPORT int GetMaximumEventsNum(void);
 
-extern _X_EXPORT int GetEventList(InternalEvent** list);
 extern _X_EXPORT InternalEvent *InitEventList(int num_events);
 extern _X_EXPORT void FreeEventList(InternalEvent *list, int num_events);
 
@@ -452,7 +450,6 @@ extern _X_EXPORT int GetPointerEvents(
     const ValuatorMask *mask);
 
 extern _X_EXPORT void QueuePointerEvents(
-    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     int buttons,
@@ -467,7 +464,6 @@ extern _X_EXPORT int GetKeyboardEvents(
     const ValuatorMask *mask);
 
 extern _X_EXPORT void QueueKeyboardEvents(
-    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     int key_code,
@@ -480,7 +476,6 @@ extern int GetProximityEvents(
     const ValuatorMask *mask);
 
 extern void QueueProximityEvents(
-    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     const ValuatorMask *mask);
commit 8670c46bdfdade64e63119d2ebbd5ef63b6fa2c3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 14 22:05:41 2011 +1000

    input: replace EventListPtr with InternalEvent array
    
    EventListPtr is a relic from pre-1.6, when we had protocol events in the
    event queue and thus events of varying size.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 18e1ef7..daa6430 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -52,6 +52,7 @@
 #include "mipointer.h"
 #include "xserver-properties.h"
 #include "exevents.h"
+#include "eventstr.h"
 #include "inpututils.h"
 
 #include "modinit.h"
@@ -61,7 +62,7 @@ extern int DeviceValuator;
 /* XTest events are sent during request processing and may be interruped by
  * a SIGIO. We need a separate event list to avoid events overwriting each
  * other's memory */
-static EventListPtr xtest_evlist;
+static InternalEvent* xtest_evlist;
 
 /**
  * xtestpointer
@@ -428,7 +429,7 @@ ProcXTestFakeInput(ClientPtr client)
     }
 
     for (i = 0; i < nevents; i++)
-        mieqProcessDeviceEvent(dev, (InternalEvent*)(xtest_evlist+i)->event, NULL);
+        mieqProcessDeviceEvent(dev, &xtest_evlist[i], NULL);
 
     if (need_ptr_update)
         miPointerUpdateSprite(dev);
diff --git a/dix/devices.c b/dix/devices.c
index 7968c73..9a4498b 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2368,7 +2368,7 @@ RecalculateMasterButtons(DeviceIntPtr slave)
 void
 ReleaseButtonsAndKeys(DeviceIntPtr dev)
 {
-    EventListPtr        eventlist = InitEventList(GetMaximumEventsNum());
+    InternalEvent*      eventlist = InitEventList(GetMaximumEventsNum());
     ButtonClassPtr      b = dev->button;
     KeyClassPtr         k = dev->key;
     int                 i, j, nevents;
@@ -2383,7 +2383,7 @@ ReleaseButtonsAndKeys(DeviceIntPtr dev)
         {
             nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL);
             for (j = 0; j < nevents; j++)
-                mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL);
+                mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
         }
     }
 
@@ -2394,7 +2394,7 @@ ReleaseButtonsAndKeys(DeviceIntPtr dev)
         {
             nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i, NULL);
             for (j = 0; j < nevents; j++)
-                mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL);
+                mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
         }
     }
 
diff --git a/dix/getevents.c b/dix/getevents.c
index 68a5224..e8c2f45 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -68,15 +68,15 @@
 /* Number of motion history events to store. */
 #define MOTION_HISTORY_SIZE 256
 
-/* InputEventList is the container list for all input events generated by the
+/* InputEventList is the storage for input events generated by the
  * DDX. The DDX is expected to call GetEventList() and then pass the list into
  * Get{Pointer|Keyboard}Events.
  */
-EventListPtr InputEventList = NULL;
+InternalEvent* InputEventList = NULL;
 int InputEventListLen = 0;
 
 int
-GetEventList(EventListPtr* list)
+GetEventList(InternalEvent** list)
 {
     *list = InputEventList;
     return InputEventListLen;
@@ -224,7 +224,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask)
 }
 
 void
-CreateClassesChangedEvent(EventList* event,
+CreateClassesChangedEvent(InternalEvent* event,
                           DeviceIntPtr master,
                           DeviceIntPtr slave,
                           int type)
@@ -233,7 +233,7 @@ CreateClassesChangedEvent(EventList* event,
     DeviceChangedEvent *dce;
     CARD32 ms = GetTimeInMillis();
 
-    dce = (DeviceChangedEvent*)event->event;
+    dce = &event->changed_event;
     memset(dce, 0, sizeof(DeviceChangedEvent));
     dce->deviceid = slave->id;
     dce->masterid = master->id;
@@ -677,15 +677,15 @@ clipValuators(DeviceIntPtr pDev, ValuatorMask *mask)
  * is done in the event processing).
  * Pull in the coordinates from the MD if necessary.
  *
- * @param events Pointer to a pre-allocated event list.
+ * @param events Pointer to a pre-allocated event array.
  * @param dev The slave device that generated an event.
  * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT
  * @param num_events The current number of events, returns the number of
  *        events if a DCCE was generated.
  * @return The updated @events pointer.
  */
-EventListPtr
-UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
+InternalEvent*
+UpdateFromMaster(InternalEvent* events, DeviceIntPtr dev, int type, int *num_events)
 {
     DeviceIntPtr master;
 
@@ -926,12 +926,11 @@ updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms)
 }
 
 static void
-queueEventList(DeviceIntPtr device, EventList *events, int nevents)
+queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents)
 {
     int i;
-
     for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (InternalEvent*)((events + i)->event));
+        mieqEnqueue(device, &events[i]);
 }
 
 /**
@@ -949,7 +948,7 @@ queueEventList(DeviceIntPtr device, EventList *events, int nevents)
  *
  */
 void
-QueueKeyboardEvents(EventList *events, DeviceIntPtr device, int type,
+QueueKeyboardEvents(InternalEvent *events, DeviceIntPtr device, int type,
                     int keycode, const ValuatorMask *mask)
 {
     int nevents;
@@ -962,12 +961,13 @@ QueueKeyboardEvents(EventList *events, DeviceIntPtr device, int type,
  * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally
  * also with valuator events.
  *
- * events is not NULL-terminated; the return value is the number of events.
- * The DDX is responsible for allocating the event structure in the first
- * place via GetMaximumEventsNum(), and for freeing it.
+ * The DDX is responsible for allocating the event list in the first
+ * place via InitEventList(), and for freeing it.
+ *
+ * @return the number of events written into events.
  */
 int
-GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type,
+GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
                   int key_code, const ValuatorMask *mask_in) {
     int num_events = 0;
     CARD32 ms = 0;
@@ -1000,7 +1000,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     ms = GetTimeInMillis();
 
-    raw = (RawDeviceEvent*)events->event;
+    raw = &events->raw_event;
     events++;
     num_events++;
 
@@ -1013,7 +1013,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     set_raw_valuators(raw, &mask, raw->valuators.data);
 
-    event = (DeviceEvent*) events->event;
+    event = &events->device_event;
     init_event(pDev, event, ms);
     event->detail.key = key_code;
 
@@ -1034,37 +1034,16 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type,
 }
 
 /**
- * Initialize an event list and fill with 32 byte sized events.
+ * Initialize an event array large enough for num_events arrays.
  * This event list is to be passed into GetPointerEvents() and
  * GetKeyboardEvents().
  *
  * @param num_events Number of elements in list.
  */
-EventListPtr
+InternalEvent*
 InitEventList(int num_events)
 {
-    EventListPtr events;
-    int i;
-
-    events = (EventListPtr)calloc(num_events, sizeof(EventList));
-    if (!events)
-        return NULL;
-
-    for (i = 0; i < num_events; i++)
-    {
-        events[i].evlen = sizeof(InternalEvent);
-        events[i].event = calloc(1, sizeof(InternalEvent));
-        if (!events[i].event)
-        {
-            /* rollback */
-            while(i--)
-                free(events[i].event);
-            free(events);
-            events = NULL;
-            break;
-        }
-    }
-
+    InternalEvent *events = calloc(num_events, sizeof(InternalEvent));
     return events;
 }
 
@@ -1075,12 +1054,8 @@ InitEventList(int num_events)
  * @param num_events Number of elements in list.
  */
 void
-FreeEventList(EventListPtr list, int num_events)
+FreeEventList(InternalEvent *list, int num_events)
 {
-    if (!list)
-        return;
-    while(num_events--)
-        free(list[num_events].event);
     free(list);
 }
 
@@ -1101,7 +1076,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y)
  *
  * FIXME: don't require the event list to be passed in.
  *
- * @param events Event list used as temporary storage
+ * @param events Set of events list used as temporary storage
  * @param device The device to generate the event for
  * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify
  * @param buttons Button number of the buttons modified. Must be 0 for
@@ -1110,7 +1085,7 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y)
  * @param mask Valuator mask for valuators present for this event.
  */
 void
-QueuePointerEvents(EventList *events, DeviceIntPtr device, int type,
+QueuePointerEvents(InternalEvent *events, DeviceIntPtr device, int type,
                    int buttons, int flags, const ValuatorMask *mask)
 {
     int nevents;
@@ -1120,11 +1095,10 @@ QueuePointerEvents(EventList *events, DeviceIntPtr device, int type,
 }
 
 /**
- * Generate a series of InternalEvents (filled into the EventList)
- * representing pointer motion, or button presses.
+ * Generate a series of InternalEvents representing pointer motion, or
+ * button presses.
  *
- * events is not NULL-terminated; the return value is the number of events.
- * The DDX is responsible for allocating the event structure in the first
+ * The DDX is responsible for allocating the events in the first
  * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
  *
  * In the generated events rootX/Y will be in absolute screen coords and
@@ -1134,9 +1108,11 @@ QueuePointerEvents(EventList *events, DeviceIntPtr device, int type,
  * last.valuators[x] of the master device is in absolute screen coords.
  *
  * master->last.valuators[x] for x > 2 is undefined.
+ *
+ * @return the number of events written into events.
  */
 int
-GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
+GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons,
                  int flags, const ValuatorMask *mask_in) {
     int num_events = 1;
     CARD32 ms;
@@ -1174,7 +1150,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
-    raw = (RawDeviceEvent*)events->event;
+    raw = &events->raw_event;
     events++;
     num_events++;
 
@@ -1243,7 +1219,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     clipValuators(pDev, &mask);
 
-    event = (DeviceEvent*) events->event;
+    event = &events->device_event;
     init_event(pDev, event, ms);
 
     if (type == MotionNotify) {
@@ -1286,7 +1262,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
  *
  */
 void
-QueueProximityEvents(EventList *events, DeviceIntPtr device, int type,
+QueueProximityEvents(InternalEvent *events, DeviceIntPtr device, int type,
                      const ValuatorMask *mask)
 {
     int nevents;
@@ -1299,12 +1275,13 @@ QueueProximityEvents(EventList *events, DeviceIntPtr device, int type,
  * Generate ProximityIn/ProximityOut InternalEvents, accompanied by
  * valuators.
  *
- * events is not NULL-terminated; the return value is the number of events.
- * The DDX is responsible for allocating the event structure in the first
- * place via GetMaximumEventsNum(), and for freeing it.
+ * The DDX is responsible for allocating the events in the first place via
+ * InitEventList(), and for freeing it.
+ *
+ * @return the number of events written into events.
  */
 int
-GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in)
+GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in)
 {
     int num_events = 1, i;
     DeviceEvent *event;
@@ -1336,7 +1313,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const Valuato
 
     events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
-    event = (DeviceEvent *) events->event;
+    event = &events->device_event;
     init_event(pDev, event, GetTimeInMillis());
     event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
 
diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index 3f9035c..8aa1b80 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -177,7 +177,7 @@ static void enqueueMotion(DevicePtr pDev, int x, int y)
     GETDMXLOCALFROMPDEV;
     DeviceIntPtr p = dmxLocal->pDevice;
     int valuators[3];
-    EventListPtr events;
+    InternalEvent* events;
     int detail = 0;  /* XXX should this be mask of pressed buttons? */
     ValuatorMask mask;
     valuators[0] = x;
@@ -290,7 +290,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
     int                    thisX   = 0;
     int                    thisY   = 0;
     int                    count;
-    EventListPtr           events;
+    InternalEvent*         events;
     ValuatorMask           mask;
 
     memset(xE, 0, sizeof(xE));
@@ -389,7 +389,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     XDeviceMotionEvent     *me     = (XDeviceMotionEvent *)e;
     DeviceIntPtr           pDevice = dmxLocal->pDevice;
     int                    valuators[MAX_VALUATORS];
-    EventListPtr           events;
+    InternalEvent*         events;
     ValuatorMask           mask;
 
     if (!e)
@@ -652,7 +652,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
     xEvent xE;
     DeviceIntPtr p = dmxLocal->pDevice;
     int valuators[3];
-    EventListPtr events;
+    InternalEvent* events;
     ValuatorMask mask;
 
     DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail);
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 521542c..62e8f78 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -66,7 +66,7 @@ static struct KdConfigDevice *kdConfigPointers    = NULL;
 static KdKeyboardDriver *kdKeyboardDrivers = NULL;
 static KdPointerDriver  *kdPointerDrivers  = NULL;
 
-static EventListPtr     kdEvents = NULL;
+static InternalEvent*   kdEvents = NULL;
 
 static Bool		kdInputEnabled;
 static Bool		kdOffScreen;
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index 7137a53..015e12c 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -149,7 +149,7 @@ extern _X_EXPORT int xf86SetLogVerbosity(int verb);
 extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only );
 
 /* xf86Xinput.c */
-extern _X_EXPORT EventList *xf86Events;
+extern _X_EXPORT InternalEvent *xf86Events;
 
 #endif /* _NO_XF86_PROTOTYPES */
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 111f16f..9827661 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -99,7 +99,7 @@
 		return;								\
 	}
 
-EventListPtr xf86Events = NULL;
+InternalEvent* xf86Events = NULL;
 
 static int
 xf86InputDevicePostInit(DeviceIntPtr dev);
diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c
index 574e4e4..bbd70bf 100644
--- a/hw/xnest/Events.c
+++ b/hw/xnest/Events.c
@@ -43,7 +43,7 @@ is" without express or implied warranty.
 
 CARD32 lastEventTime = 0;
 
-extern EventList *xnestEvents;
+extern InternalEvent *xnestEvents;
 
 void
 ProcessInputEvents(void)
diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c
index 8a90cc6..f8637f2 100644
--- a/hw/xnest/Init.c
+++ b/hw/xnest/Init.c
@@ -45,7 +45,7 @@ is" without express or implied warranty.
 
 Bool xnestDoFullGeneration = True;
 
-EventList *xnestEvents = NULL;
+InternalEvent *xnestEvents = NULL;
 
 void
 InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 99956e0..6736e3d 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -88,7 +88,7 @@ static pthread_mutex_t fd_add_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t fd_add_ready_cond = PTHREAD_COND_INITIALIZER;
 static pthread_t fd_add_tid = NULL;
 
-static EventListPtr darwinEvents = NULL;
+static InternalEvent* darwinEvents = NULL;
 
 static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER;
diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index cf0dea2..8b6be02 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -472,7 +472,7 @@ winKeybdReleaseKeys (void)
 void
 winSendKeyEvent (DWORD dwKey, Bool fDown)
 {
-  EventListPtr events;
+  InternalEvent* events;
 
   /*
    * When alt-tabing between screens we can get phantom key up messages
diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c
index 0e36687..aaa4d4b 100644
--- a/hw/xwin/winmouse.c
+++ b/hw/xwin/winmouse.c
@@ -234,7 +234,7 @@ winMouseWheel (ScreenPtr pScreen, int iDeltaZ)
 void
 winMouseButtonsSendEvent (int iEventType, int iButton)
 {
-  EventListPtr events;
+  InternalEvent* events;
   ValuatorMask mask;
 
   if (g_winMouseButtonMap)
@@ -365,7 +365,7 @@ void winEnqueueMotion(int x, int y)
 {
   int valuators[2];
   ValuatorMask mask;
-  EventListPtr events;
+  InternalEvent* events;
 
   miPointerSetPosition(g_pwinPointer, POINTER_RELATIVE, &x, &y);
   valuators[0] = x;
diff --git a/include/input.h b/include/input.h
index 100c00f..3c7740d 100644
--- a/include/input.h
+++ b/include/input.h
@@ -109,18 +109,8 @@ typedef union _GrabMask GrabMask;
 
 typedef struct _ValuatorMask ValuatorMask;
 
-typedef struct _EventList {
-    xEvent* event;
-    int evlen; /* length of allocated memory for event in bytes.  This is not
-                  the actual length of the event. The event's actual length is
-                  32 for standard events or 32 +
-                  ((xGenericEvent*)event)->length * 4 for GenericEvents.
-                  For events in the EQ, the length is
-                  ((InternalEvent*)event)->u.any.length */
-} EventList, *EventListPtr;
-
 /* The DIX stores incoming input events in this list */
-extern EventListPtr InputEventList;
+extern InternalEvent* InputEventList;
 extern int InputEventListLen;
 
 typedef int (*DeviceProc)(
@@ -439,22 +429,22 @@ extern _X_EXPORT void CloseInput(void);
 
 extern _X_EXPORT int GetMaximumEventsNum(void);
 
-extern _X_EXPORT int GetEventList(EventListPtr* list);
-extern _X_EXPORT EventListPtr InitEventList(int num_events);
-extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events);
+extern _X_EXPORT int GetEventList(InternalEvent** list);
+extern _X_EXPORT InternalEvent *InitEventList(int num_events);
+extern _X_EXPORT void FreeEventList(InternalEvent *list, int num_events);
 
-extern void CreateClassesChangedEvent(EventListPtr event,
+extern void CreateClassesChangedEvent(InternalEvent *event,
                                       DeviceIntPtr master,
                                       DeviceIntPtr slave,
                                       int type);
-extern EventListPtr UpdateFromMaster(
-    EventListPtr events,
+extern InternalEvent * UpdateFromMaster(
+    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     int *num_events);
 
 extern _X_EXPORT int GetPointerEvents(
-    EventListPtr events,
+    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     int buttons,
@@ -462,7 +452,7 @@ extern _X_EXPORT int GetPointerEvents(
     const ValuatorMask *mask);
 
 extern _X_EXPORT void QueuePointerEvents(
-    EventListPtr events,
+    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     int buttons,
@@ -470,27 +460,27 @@ extern _X_EXPORT void QueuePointerEvents(
     const ValuatorMask *mask);
 
 extern _X_EXPORT int GetKeyboardEvents(
-    EventListPtr events,
+    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     int key_code,
     const ValuatorMask *mask);
 
 extern _X_EXPORT void QueueKeyboardEvents(
-    EventListPtr events,
+    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     int key_code,
     const ValuatorMask *mask);
 
 extern int GetProximityEvents(
-    EventListPtr events,
+    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     const ValuatorMask *mask);
 
 extern void QueueProximityEvents(
-    EventListPtr events,
+    InternalEvent *events,
     DeviceIntPtr pDev,
     int type,
     const ValuatorMask *mask);
diff --git a/mi/mieq.c b/mi/mieq.c
index 3e6f931..236ffcc 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -64,7 +64,7 @@ in this Software without prior written authorization from The Open Group.
 #define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen
 
 typedef struct _Event {
-    EventListPtr    events;
+    InternalEvent*  events;
     ScreenPtr	    pScreen;
     DeviceIntPtr    pDev; /* device this event _originated_ from */
 } EventRec, *EventPtr;
@@ -111,7 +111,7 @@ mieqInit(void)
     for (i = 0; i < QUEUE_SIZE; i++)
     {
 	if (miEventQueue.events[i].events == NULL) {
-	    EventListPtr evlist = InitEventList(1);
+	    InternalEvent* evlist = InitEventList(1);
 	    if (!evlist)
 		FatalError("Could not allocate event queue.\n");
 	    miEventQueue.events[i].events = evlist;
@@ -146,7 +146,7 @@ void
 mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
 {
     unsigned int           oldtail = miEventQueue.tail;
-    EventListPtr           evt;
+    InternalEvent*         evt;
     int                    isMotion = 0;
     int                    evlen;
     Time                   time;
@@ -188,21 +188,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
 
     evlen = e->any.length;
     evt = miEventQueue.events[oldtail].events;
-    if (evt->evlen < evlen)
-    {
-        evt->evlen = evlen;
-        evt->event = realloc(evt->event, evt->evlen);
-        if (!evt->event)
-        {
-            ErrorF("[mi] Running out of memory. Tossing event.\n");
-#ifdef XQUARTZ
-            pthread_mutex_unlock(&miEventQueueMutex);
-#endif
-            return;
-        }
-    }
-
-    memcpy(evt->event, e, evlen);
+    memcpy(evt, e, evlen);
 
     time = e->any.time;
     /* Make sure that event times don't go backwards - this
@@ -211,7 +197,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
         miEventQueue.lastEventTime - time < 10000)
         e->any.time = miEventQueue.lastEventTime;
 
-    miEventQueue.lastEventTime = ((InternalEvent*)evt->event)->any.time;
+    miEventQueue.lastEventTime = evt->any.time;
     miEventQueue.events[oldtail].pScreen = pDev ? EnqueueScreen(pDev) : NULL;
     miEventQueue.events[oldtail].pDev = pDev;
 
@@ -431,10 +417,8 @@ void
 mieqProcessInputEvents(void)
 {
     EventRec *e = NULL;
-    int evlen;
     ScreenPtr screen;
-    static InternalEvent *event = NULL;
-    static size_t event_size = 0;
+    static InternalEvent event;
     DeviceIntPtr dev = NULL,
                  master = NULL;
 
@@ -445,20 +429,7 @@ mieqProcessInputEvents(void)
     while (miEventQueue.head != miEventQueue.tail) {
         e = &miEventQueue.events[miEventQueue.head];
 
-        evlen   = e->events->evlen;
-        if(evlen > event_size)
-          {
-            event = realloc(event, evlen);
-            event_size = evlen;
-          }
-
-
-        if (!event)
-            FatalError("[mi] No memory left for event processing.\n");
-
-        memcpy(event, e->events->event, evlen);
-
-
+        event = *e->events;
         dev     = e->pDev;
         screen  = e->pScreen;
 
@@ -480,10 +451,10 @@ mieqProcessInputEvents(void)
             DPMSSet(serverClient, DPMSModeOn);
 #endif
 
-        mieqProcessDeviceEvent(dev, event, screen);
+        mieqProcessDeviceEvent(dev, &event, screen);
 
         /* Update the sprite now. Next event may be from different device. */
-        if (event->any.type == ET_Motion && master)
+        if (event.any.type == ET_Motion && master)
             miPointerUpdateSprite(dev);
 
 #ifdef XQUARTZ
diff --git a/mi/mipointer.c b/mi/mipointer.c
index db24381..322be9e 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -63,6 +63,7 @@ in this Software without prior written authorization from The Open Group.
 # include   "dixstruct.h"
 # include   "inputstr.h"
 # include   "inpututils.h"
+# include   "eventstr.h"
 
 DevPrivateKeyRec miPointerScreenKeyRec;
 
@@ -99,7 +100,7 @@ static void miPointerDeviceCleanup(DeviceIntPtr pDev,
                                    ScreenPtr pScreen);
 static void miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
 
-static EventList* events; /* for WarpPointer MotionNotifies */
+static InternalEvent* events; /* for WarpPointer MotionNotifies */
 
 Bool
 miPointerInitialize (ScreenPtr                  pScreen,
@@ -689,7 +690,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     darwinEvents_lock();
 #endif
     for (i = 0; i < nevents; i++)
-        mieqEnqueue(pDev, (InternalEvent*)events[i].event);
+        mieqEnqueue(pDev, &events[i]);
 #ifdef XQUARTZ
     darwinEvents_unlock();
 #endif
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index c4336d7..4b5405a 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1351,7 +1351,7 @@ static void
 InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask)
 {
     ScreenPtr           pScreen;
-    EventListPtr        events;
+    InternalEvent*      events;
     int                 nevents, i;
     DeviceIntPtr        ptr, mpointer, lastSlave = NULL;
     Bool                saveWait;
@@ -1377,7 +1377,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, Valuat
     OsReleaseSignals();
 
     for (i = 0; i < nevents; i++)
-        mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
+        mieqProcessDeviceEvent(ptr, &events[i], NULL);
 
     FreeEventList(events, GetMaximumEventsNum());
 
commit e7150db5350bc2113ff4126019b489847a4dc217
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Apr 11 15:48:15 2011 +1000

    input: Provide Queue{Button|Keyboard|Proximity}Event helpers
    
    Don't require every caller to use GPE + mieqEnqueue, provide matching
    Queue...Event functions instead.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index 5ffa1df..68a5224 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -47,6 +47,7 @@
 #include "eventstr.h"
 #include "eventconvert.h"
 #include "inpututils.h"
+#include "mi.h"
 
 #include <X11/extensions/XKBproto.h>
 #include "xkbsrv.h"
@@ -924,6 +925,39 @@ updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms)
     }
 }
 
+static void
+queueEventList(DeviceIntPtr device, EventList *events, int nevents)
+{
+    int i;
+
+    for (i = 0; i < nevents; i++)
+        mieqEnqueue(device, (InternalEvent*)((events + i)->event));
+}
+
+/**
+ * Generate internal events representing this keyboard event and enqueue
+ * them on the event queue.
+ *
+ * FIXME: don't require the event list to be passed in.
+ * FIXME: flags for relative/abs motion?
+ *
+ * @param events Event list used as temporary storage
+ * @param device The device to generate the event for
+ * @param type Event type, one of KeyPress or KeyRelease
+ * @param keycode Key code of the pressed/released key
+ * @param mask Valuator mask for valuators present for this event.
+ *
+ */
+void
+QueueKeyboardEvents(EventList *events, DeviceIntPtr device, int type,
+                    int keycode, const ValuatorMask *mask)
+{
+    int nevents;
+
+    nevents = GetKeyboardEvents(events, device, type, keycode, mask);
+    queueEventList(device, events, nevents);
+}
+
 /**
  * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally
  * also with valuator events.
@@ -1062,6 +1096,30 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y)
 }
 
 /**
+ * Generate internal events representing this pointer event and enqueue them
+ * on the event queue.
+ *
+ * FIXME: don't require the event list to be passed in.
+ *
+ * @param events Event list used as temporary storage
+ * @param device The device to generate the event for
+ * @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify
+ * @param buttons Button number of the buttons modified. Must be 0 for
+ * MotionNotify
+ * @param flags Event modification flags
+ * @param mask Valuator mask for valuators present for this event.
+ */
+void
+QueuePointerEvents(EventList *events, DeviceIntPtr device, int type,
+                   int buttons, int flags, const ValuatorMask *mask)
+{
+    int nevents;
+
+    nevents = GetPointerEvents(events, device, type, buttons, flags, mask);
+    queueEventList(device, events, nevents);
+}
+
+/**
  * Generate a series of InternalEvents (filled into the EventList)
  * representing pointer motion, or button presses.
  *
@@ -1214,6 +1272,28 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     return num_events;
 }
 
+/**
+ * Generate internal events representing this proximity event and enqueue
+ * them on the event queue.
+ *
+ * FIXME: don't require the event list to be passed in.
+ *
+ * @param events Event list used as temporary storage
+ * @param device The device to generate the event for
+ * @param type Event type, one of ProximityIn or ProximityOut
+ * @param keycode Key code of the pressed/released key
+ * @param mask Valuator mask for valuators present for this event.
+ *
+ */
+void
+QueueProximityEvents(EventList *events, DeviceIntPtr device, int type,
+                     const ValuatorMask *mask)
+{
+    int nevents;
+
+    nevents = GetProximityEvents(events, device, type, mask);
+    queueEventList(device, events, nevents);
+}
 
 /**
  * Generate ProximityIn/ProximityOut InternalEvents, accompanied by
diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index 15d80f5..3f9035c 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -176,7 +176,7 @@ static void enqueueMotion(DevicePtr pDev, int x, int y)
 {
     GETDMXLOCALFROMPDEV;
     DeviceIntPtr p = dmxLocal->pDevice;
-    int i, nevents, valuators[3];
+    int valuators[3];
     EventListPtr events;
     int detail = 0;  /* XXX should this be mask of pressed buttons? */
     ValuatorMask mask;
@@ -185,10 +185,8 @@ static void enqueueMotion(DevicePtr pDev, int x, int y)
 
     valuator_mask_set_range(&mask, 0, 2, valuators);
     GetEventList(&events);
-    nevents = GetPointerEvents(events, p, MotionNotify, detail,
-                               POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
-    for (i = 0; i < nevents; i++)
-       mieqEnqueue(p, (InternalEvent*)(events + i)->event);
+    QueuePointerEvents(events, p, MotionNotify, detail,
+                       POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
     return;
 }
 
@@ -291,10 +289,8 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
     deviceValuator         *xv     = (deviceValuator *)xev+1;
     int                    thisX   = 0;
     int                    thisY   = 0;
-    int                    i;
     int                    count;
     EventListPtr           events;
-    int                    nevents;
     ValuatorMask           mask;
 
     memset(xE, 0, sizeof(xE));
@@ -348,6 +344,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
             }
             count              = 2;
     } else {
+        int i;
         for (i = 0, count = 0; i < axesCount; i += 6) {
             xev->time          = GetTimeInMillis();
             xev->type          = DeviceMotionNotify;
@@ -376,10 +373,8 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
         dmxSigioBlock();
     valuator_mask_set_range(&mask, firstAxis, axesCount, v);
     GetEventList(&events);
-    nevents = GetPointerEvents(events, pDevice, MotionNotify, 0,
-                               POINTER_ABSOLUTE, &mask);
-    for (i = 0; i < nevents; i++)
-        mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
+    QueuePointerEvents(events, pDevice, MotionNotify, 0,
+                       POINTER_ABSOLUTE, &mask);
 
     if (block)
         dmxSigioUnblock();
@@ -395,7 +390,6 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     DeviceIntPtr           pDevice = dmxLocal->pDevice;
     int                    valuators[MAX_VALUATORS];
     EventListPtr           events;
-    int                    nevents, i;
     ValuatorMask           mask;
 
     if (!e)
@@ -453,11 +447,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         if (block)
             dmxSigioBlock();
         GetEventList(&events);
-        nevents = GetKeyboardEvents(events, pDevice, event,
-                                    ke->keycode, &mask);
-        for (i = 0; i < nevents; i++)
-            mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
-
+        QueueKeyboardEvents(events, pDevice, event, ke->keycode, &mask);
         if (block)
             dmxSigioUnblock();
         break;
@@ -468,11 +458,8 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         if (block)
             dmxSigioBlock();
         GetEventList(&events);
-        nevents = GetPointerEvents(events, pDevice, event, ke->keycode,
-                                   POINTER_ABSOLUTE, &mask);
-        for (i = 0; i < nevents; i++)
-            mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
-
+        QueuePointerEvents(events, pDevice, event, ke->keycode,
+                           POINTER_ABSOLUTE, &mask);
         if (block)
             dmxSigioUnblock();
         break;
@@ -483,10 +470,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
         if (block)
             dmxSigioBlock();
         GetEventList(&events);
-        nevents = GetProximityEvents(events, pDevice, event, &mask);
-        for (i = 0; i < nevents; i++)
-            mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
-
+        QueueProximityEvents(events, pDevice, event, &mask);
         if (block)
             dmxSigioUnblock();
         break;
@@ -667,7 +651,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
     GETDMXINPUTFROMPDEV;
     xEvent xE;
     DeviceIntPtr p = dmxLocal->pDevice;
-    int i, nevents, valuators[3];
+    int valuators[3];
     EventListPtr events;
     ValuatorMask mask;
 
@@ -685,9 +669,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
 
         GetEventList(&events);
         /*ErrorF("KEY %d  sym %d\n", detail, (int) keySym);*/
-        nevents = GetKeyboardEvents(events, p, type, detail, NULL);
-        for (i = 0; i < nevents; i++)
-            mieqEnqueue(p, (InternalEvent*)(events + i)->event);
+        QueueKeyboardEvents(events, p, type, detail, NULL);
         return;
 
     case ButtonPress:
@@ -695,10 +677,8 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
         detail = dmxGetButtonMapping(dmxLocal, detail);
         valuator_mask_zero(&mask);
         GetEventList(&events);
-        nevents = GetPointerEvents(events, p, type, detail,
-                                   POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
-        for (i = 0; i < nevents; i++)
-            mieqEnqueue(p, (InternalEvent*)(events + i)->event);
+        QueuePointerEvents(events, p, type, detail,
+                           POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
         return;
 
     case MotionNotify:
@@ -707,10 +687,8 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
         valuators[1] = e->xmotion.y;
         valuators[2] = e->xmotion.state; /* FIXME: WTF?? */
         valuator_mask_set_range(&mask, 0, 3, valuators);
-        nevents = GetPointerEvents(events, p, type, detail, 
-                                   POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
-        for (i = 0; i < nevents; i++)
-            mieqEnqueue(p, (InternalEvent*)(events + i)->event);
+        QueuePointerEvents(events, p, type, detail,
+                           POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
         return;
 
     case EnterNotify:
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index f21475f..521542c 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -1793,7 +1793,7 @@ void
 KdReleaseAllKeys (void)
 {
 #if 0
-    int	key, nEvents, i;
+    int	key;
     KdKeyboardInfo *ki;
 
     KdBlockSigio ();
@@ -1804,9 +1804,7 @@ KdReleaseAllKeys (void)
             if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) {
                 KdHandleKeyboardEvent(ki, KeyRelease, key);
                 GetEventList(&kdEvents);
-                nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key, NULL);
-                for (i = 0; i < nEvents; i++)
-                    KdQueueEvent (ki->dixdev, (kdEvents + i)->event);
+                QueueGetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key, NULL);
             }
         }
     }
@@ -1842,7 +1840,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo   *ki,
     unsigned char key_code;
     KeyClassPtr	keyc = NULL;
     KeybdCtrl *ctrl = NULL;
-    int type, nEvents, i;
+    int type;
 
     if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key)
 	return;
@@ -1863,10 +1861,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo   *ki,
 	    type = KeyPress;
 
         GetEventList(&kdEvents);
-
-        nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code, NULL);
-        for (i = 0; i < nEvents; i++)
-            KdQueueEvent(ki->dixdev, (InternalEvent *)((kdEvents + i)->event));
+        QueueKeyboardEvents(kdEvents, ki->dixdev, type, key_code, NULL);
     }
     else {
         ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n",
@@ -1965,7 +1960,6 @@ void
 _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z,
                         int b, int absrel, Bool force)
 {
-    int nEvents = 0, i = 0;
     int valuators[3] = { x, y, z };
     ValuatorMask mask;
 
@@ -1976,9 +1970,7 @@ _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z,
     valuator_mask_set_range(&mask, 0, 3, valuators);
 
     GetEventList(&kdEvents);
-    nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask);
-    for (i = 0; i < nEvents; i++)
-        KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event));
+    QueuePointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask);
 }
 
 void
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 3006ad1..6402d72 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -376,7 +376,7 @@ static void
 xf86ReleaseKeys(DeviceIntPtr pDev)
 {
     KeyClassPtr keyc;
-    int i, j, nevents, sigstate;
+    int i, sigstate;
 
     if (!pDev || !pDev->key)
         return;
@@ -399,9 +399,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
          i++) {
         if (key_is_down(pDev, i, KEY_POSTED)) {
             sigstate = xf86BlockSIGIO ();
-            nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL);
-            for (j = 0; j < nevents; j++)
-                mieqEnqueue(pDev, (InternalEvent*)(xf86Events + j)->event);
+            QueueKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL);
             xf86UnblockSIGIO(sigstate);
         }
     }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index aae6658..111f16f 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -1012,7 +1012,6 @@ xf86PostMotionEventM(DeviceIntPtr	device,
                      int		is_absolute,
                      const ValuatorMask	*mask)
 {
-    int i = 0, nevents = 0;
     int flags = 0;
 
     if (valuator_mask_num_valuators(mask) > 0)
@@ -1050,11 +1049,7 @@ xf86PostMotionEventM(DeviceIntPtr	device,
         }
 #endif
 
-    nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
-
-    for (i = 0; i < nevents; i++) {
-        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-    }
+    QueuePointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
 }
 
 void
@@ -1099,13 +1094,8 @@ xf86PostProximityEventM(DeviceIntPtr	device,
                         int		is_in,
                         const ValuatorMask *mask)
 {
-    int i, nevents;
-
-    nevents = GetProximityEvents(xf86Events, device,
-                                 is_in ? ProximityIn : ProximityOut, mask);
-    for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
+    QueueProximityEvents(xf86Events, device,
+                         is_in ? ProximityIn : ProximityOut, mask);
 }
 
 void
@@ -1157,7 +1147,6 @@ xf86PostButtonEventM(DeviceIntPtr	device,
                      int		is_down,
                      const ValuatorMask	*mask)
 {
-    int i = 0, nevents = 0;
     int flags = 0;
 
     if (valuator_mask_num_valuators(mask) > 0)
@@ -1177,13 +1166,9 @@ xf86PostButtonEventM(DeviceIntPtr	device,
     }
 #endif
 
-    nevents = GetPointerEvents(xf86Events, device,
-                               is_down ? ButtonPress : ButtonRelease, button,
-                               flags, mask);
-
-    for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
+    QueuePointerEvents(xf86Events, device,
+                       is_down ? ButtonPress : ButtonRelease, button,
+                       flags, mask);
 }
 
 void
@@ -1235,8 +1220,6 @@ xf86PostKeyEventM(DeviceIntPtr	device,
                   int		is_absolute,
                   const ValuatorMask *mask)
 {
-    int i = 0, nevents = 0;
-
 #if XFreeXDGA
     DeviceIntPtr pointer;
 
@@ -1250,12 +1233,9 @@ xf86PostKeyEventM(DeviceIntPtr	device,
     }
 #endif
 
-    nevents = GetKeyboardEvents(xf86Events, device,
-                                is_down ? KeyPress : KeyRelease,
-                                key_code, mask);
-
-    for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+    QueueKeyboardEvents(xf86Events, device,
+                        is_down ? KeyPress : KeyRelease,
+                        key_code, mask);
 }
 
 void
diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c
index 5c80086..574e4e4 100644
--- a/hw/xnest/Events.c
+++ b/hw/xnest/Events.c
@@ -104,20 +104,16 @@ xnestCollectExposures(void)
 void
 xnestQueueKeyEvent(int type, unsigned int keycode)
 {
-  int i, n;
-
   GetEventList(&xnestEvents);
   lastEventTime = GetTimeInMillis();
-  n = GetKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode, NULL);
-  for (i = 0; i < n; i++)
-    mieqEnqueue(xnestKeyboardDevice, (InternalEvent*)(xnestEvents + i)->event);
+  QueueKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode, NULL);
 }
 
 void
 xnestCollectEvents(void)
 {
   XEvent X;
-  int i, n, valuators[2];
+  int valuators[2];
   ValuatorMask mask;
   ScreenPtr pScreen;
   GetEventList(&xnestEvents);
@@ -138,20 +134,16 @@ xnestCollectEvents(void)
       valuator_mask_set_range(&mask, 0, 0, NULL);
       xnestUpdateModifierState(X.xkey.state);
       lastEventTime = GetTimeInMillis();
-      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
-                           X.xbutton.button, POINTER_RELATIVE, &mask);
-      for (i = 0; i < n; i++)
-        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
+      QueuePointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
+                         X.xbutton.button, POINTER_RELATIVE, &mask);
       break;
       
     case ButtonRelease:
       valuator_mask_set_range(&mask, 0, 0, NULL);
       xnestUpdateModifierState(X.xkey.state);
       lastEventTime = GetTimeInMillis();
-      n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
-                           X.xbutton.button, POINTER_RELATIVE, &mask);
-      for (i = 0; i < n; i++)
-        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
+      QueuePointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
+                         X.xbutton.button, POINTER_RELATIVE, &mask);
       break;
       
     case MotionNotify:
@@ -159,10 +151,8 @@ xnestCollectEvents(void)
       valuators[1] = X.xmotion.y;
       valuator_mask_set_range(&mask, 0, 2, valuators);
       lastEventTime = GetTimeInMillis();
-      n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
-                           0, POINTER_ABSOLUTE, &mask);
-      for (i = 0; i < n; i++)
-        mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
+      QueuePointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
+                         0, POINTER_ABSOLUTE, &mask);
       break;
       
     case FocusIn:
@@ -193,10 +183,8 @@ xnestCollectEvents(void)
           valuators[1] = X.xcrossing.y;
           valuator_mask_set_range(&mask, 0, 2, valuators);
           lastEventTime = GetTimeInMillis();
-          n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
-                               0, POINTER_ABSOLUTE, &mask);
-          for (i = 0; i < n; i++)
-            mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
+          QueuePointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
+                             0, POINTER_ABSOLUTE, &mask);
 	  xnestDirectInstallColormaps(pScreen);
 	}
       }
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index f3e1225..99956e0 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -433,7 +433,6 @@ static void DarwinPrepareValuators(DeviceIntPtr pDev, int *valuators, ScreenPtr
 void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y, 
 			     float pressure, float tilt_x, float tilt_y) {
 	static int darwinFakeMouseButtonDown = 0;
-	int i, num_events;
     ScreenPtr screen;
     int valuators[5];
 	
@@ -486,15 +485,13 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa
     darwinEvents_lock(); {
         ValuatorMask mask;
         valuator_mask_set_range(&mask, 0, (pDev == darwinPointer) ? 2 : 5, valuators);
-        num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button, 
-                                      POINTER_ABSOLUTE, &mask);
-        for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event);
-        if(num_events > 0) DarwinPokeEQ();
+        QueuePointerEvents(darwinEvents, pDev, ev_type, ev_button,
+                           POINTER_ABSOLUTE, &mask);
+        DarwinPokeEQ();
     } darwinEvents_unlock();
 }
 
 void DarwinSendKeyboardEvents(int ev_type, int keycode) {
-	int i, num_events;
 
 	if(!darwinEvents) {
 		DEBUG_LOG("DarwinSendKeyboardEvents called before darwinEvents was initialized\n");
@@ -502,15 +499,13 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
 	}
 
     darwinEvents_lock(); {
-        num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL);
-        for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard, (InternalEvent*)darwinEvents[i].event);
-        if(num_events > 0) DarwinPokeEQ();
+        QueueKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL);
+        DarwinPokeEQ();
     } darwinEvents_unlock();
 }
 
 void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, float pointer_y,  
                                float pressure, float tilt_x, float tilt_y) {
-    int i, num_events;
     ScreenPtr screen;
     int valuators[5];
 
@@ -531,9 +526,8 @@ void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x,
     darwinEvents_lock(); {
         ValuatorMask mask;
         valuator_mask_set_range(&mask, 0, 5, valuators);
-        num_events = GetProximityEvents(darwinEvents, pDev, ev_type, &mask);
-        for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event);
-        if(num_events > 0) DarwinPokeEQ();
+        QueueProximityEvents(darwinEvents, pDev, ev_type, &mask);
+        DarwinPokeEQ();
     } darwinEvents_unlock();
 }
 
diff --git a/hw/xwin/winkeybd.c b/hw/xwin/winkeybd.c
index 912e2de..cf0dea2 100644
--- a/hw/xwin/winkeybd.c
+++ b/hw/xwin/winkeybd.c
@@ -473,7 +473,6 @@ void
 winSendKeyEvent (DWORD dwKey, Bool fDown)
 {
   EventListPtr events;
-  int i, nevents;
 
   /*
    * When alt-tabing between screens we can get phantom key up messages
@@ -485,10 +484,7 @@ winSendKeyEvent (DWORD dwKey, Bool fDown)
   g_winKeyState[dwKey] = fDown;
 
   GetEventList(&events);
-  nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL);
-
-  for (i = 0; i < nevents; i++)
-    mieqEnqueue(g_pwinKeyboard, (InternalEvent*)events[i].event);
+  QueueKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL);
 
   winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n",
            dwKey, fDown, nevents);
diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c
index 080e096..0e36687 100644
--- a/hw/xwin/winmouse.c
+++ b/hw/xwin/winmouse.c
@@ -235,7 +235,6 @@ void
 winMouseButtonsSendEvent (int iEventType, int iButton)
 {
   EventListPtr events;
-  int i, nevents;
   ValuatorMask mask;
 
   if (g_winMouseButtonMap)
@@ -243,11 +242,8 @@ winMouseButtonsSendEvent (int iEventType, int iButton)
 
   valuator_mask_zero(&mask);
   GetEventList(&events);
-  nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton,
-			     POINTER_RELATIVE, &mask);
-
-  for (i = 0; i < nevents; i++)
-    mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event);
+  QueuePointerEvents(events, g_pwinPointer, iEventType, iButton,
+		     POINTER_RELATIVE, &mask);
 
 #if CYGDEBUG
   ErrorF("winMouseButtonsSendEvent: iEventType: %d, iButton: %d, nEvents %d\n",
@@ -367,7 +363,6 @@ winMouseButtonsHandle (ScreenPtr pScreen,
  */
 void winEnqueueMotion(int x, int y)
 {
-  int i, nevents;
   int valuators[2];
   ValuatorMask mask;
   EventListPtr events;
@@ -378,9 +373,7 @@ void winEnqueueMotion(int x, int y)
 
   valuator_mask_set_range(&mask, 0, 2, valuators);
   GetEventList(&events);
-  nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0,
-			     POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
+  QueuePointerEvents(events, g_pwinPointer, MotionNotify, 0,
+		     POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
 
-  for (i = 0; i < nevents; i++)
-    mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event);
 }
diff --git a/include/input.h b/include/input.h
index 6799a53..100c00f 100644
--- a/include/input.h
+++ b/include/input.h
@@ -461,6 +461,14 @@ extern _X_EXPORT int GetPointerEvents(
     int flags,
     const ValuatorMask *mask);
 
+extern _X_EXPORT void QueuePointerEvents(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    int buttons,
+    int flags,
+    const ValuatorMask *mask);
+
 extern _X_EXPORT int GetKeyboardEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
@@ -468,12 +476,25 @@ extern _X_EXPORT int GetKeyboardEvents(
     int key_code,
     const ValuatorMask *mask);
 
+extern _X_EXPORT void QueueKeyboardEvents(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    int key_code,
+    const ValuatorMask *mask);
+
 extern int GetProximityEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
     const ValuatorMask *mask);
 
+extern void QueueProximityEvents(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    const ValuatorMask *mask);
+
 extern void PostSyntheticMotion(
     DeviceIntPtr pDev,
     int x,
commit 1b8593a6c12315b1071a4fa586151e12f46458f5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 9 15:13:17 2011 +1000

    xfree86: print the device ID to the log when adding a device.
    
    Sometimes the name isn't enough, it's handy to see the device ID's from the
    log file.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index ef4542c..aae6658 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -329,8 +329,8 @@ xf86ActivateDevice(InputInfoPtr pInfo)
     dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL);
 
     if (serverGeneration == 1)
-        xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
-                pInfo->name, pInfo->type_name);
+        xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s, id %d)\n",
+                pInfo->name, pInfo->type_name, dev->id);
 
     return dev;
 }
commit 3231962db826f5efd431596a309c96e907a191d1
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Tue May 3 03:20:23 2011 +0100

    XKB: Fix sense inversion for core MapNotify events
    
    Due to an unfortunate sense inversion incident while switching from a
    if (foo) { ... } to if (!foo) continue; style in f06a9d, we punished any
    client who attempted to use XKB to restrict the MapNotify events they
    wanted by sending them exactly the events they _didn't_ want, and
    nothing else.
    
    NewKeyboardNotifies (coming from a client setting the map with an XKB
    request, when switching between master devices, etc) weren't affected,
    but this would impact anyone using xmodmap-style core requests.  Could
    explain a fair bit.
    
    Clarified the comments while I was at it.
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c
index d342acc..dfbf7f2 100644
--- a/xkb/xkbEvents.c
+++ b/xkb/xkbEvents.c
@@ -88,11 +88,15 @@ XkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed,
         if (!clients[i] || clients[i]->clientState != ClientStateRunning)
             continue;
 
-        /* Ignore clients which will have already received this.
-         * Inconsistent with themselves, but consistent with previous
-         * behaviour.*/
-        if (xkb_event == XkbMapNotify && (clients[i]->mapNotifyMask & changed))
+        /* XKB allows clients to restrict the MappingNotify events sent to
+         * them.  This was broken for three years.  Sorry. */
+        if (xkb_event == XkbMapNotify &&
+            (clients[i]->xkbClientFlags & _XkbClientInitialized) &&
+            !(clients[i]->mapNotifyMask & changed))
             continue;
+        /* Emulate previous server behaviour: any client which has activated
+         * XKB will not receive core events emulated from a NewKeyboardNotify
+         * at all. */
         if (xkb_event == XkbNewKeyboardNotify &&
             (clients[i]->xkbClientFlags & _XkbClientInitialized))
             continue;
commit 460a377ef2d645d9ae38a8356fb248ccc47bed4a
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Tue May 3 03:07:50 2011 +0100

    XKB: Send XKB events for all devices to all clients
    
    We were using XIShouldNotify(client, device) as a test for whether or
    not to send XKB map/state/etc changed events, which limits it to only
    sending events for the current ClientPointer/ClientKeyboard for that
    client.  While this makes perfect sense for core events (e.g.
    MappingNotify), XKB events carry a device ID, so are safe to send to all
    clients for all devices.
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c
index 7f91e9a..d342acc 100644
--- a/xkb/xkbEvents.c
+++ b/xkb/xkbEvents.c
@@ -164,9 +164,6 @@ XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN)
         if (!(clients[i]->newKeyboardNotifyMask & changed))
             continue;
 
-        if (!XIShouldNotify(clients[i], kbd))
-            continue;
-
         pNKN->sequenceNumber = clients[i]->sequence;
         pNKN->time = time;
         pNKN->changed = changed;
@@ -232,8 +229,7 @@ register CARD16	changed,bState;
 	if ((!interest->client->clientGone) &&
 	    (interest->client->requestVector != InitialVector) &&
 	    (interest->client->xkbClientFlags&_XkbClientInitialized) &&
-	    (interest->stateNotifyMask&changed) &&
-            XIShouldNotify(interest->client,kbd)) {
+	    (interest->stateNotifyMask&changed)) {
 	    pSN->sequenceNumber = interest->client->sequence;
 	    pSN->time = time;
 	    pSN->changed = changed;
@@ -280,9 +276,6 @@ XkbSendMapNotify(DeviceIntPtr kbd, xkbMapNotify *pMN)
         if (!(clients[i]->mapNotifyMask & changed))
             continue;
 
-        if (!XIShouldNotify(clients[i], kbd))
-            continue;
-
         pMN->time = time;
         pMN->sequenceNumber = clients[i]->sequence;
         pMN->changed = changed;
@@ -401,8 +394,7 @@ Time 		 	time = 0;
 	if ((!interest->client->clientGone) &&
 	    (interest->client->requestVector != InitialVector) &&
 	    (interest->client->xkbClientFlags&_XkbClientInitialized) &&
-	    (interest->ctrlsNotifyMask&changedControls) &&
-            XIShouldNotify(interest->client, kbd)) {
+	    (interest->ctrlsNotifyMask&changedControls)) {
 	    if (!initialized) {
 		pCN->type = XkbEventCode + XkbEventBase;
 		pCN->xkbType = XkbControlsNotify;
@@ -450,7 +442,6 @@ CARD32		state,changed;
 	if ((!interest->client->clientGone) &&
 	    (interest->client->requestVector != InitialVector) &&
 	    (interest->client->xkbClientFlags&_XkbClientInitialized) &&
-            XIShouldNotify(interest->client, kbd) &&
 	    (((xkbType==XkbIndicatorStateNotify)&&
 				(interest->iStateNotifyMask&changed))||
 	     ((xkbType==XkbIndicatorMapNotify)&&
@@ -534,8 +525,7 @@ XID		winID = 0;
 	if ((!interest->client->clientGone) &&
 	    (interest->client->requestVector != InitialVector) &&
 	    (interest->client->xkbClientFlags&_XkbClientInitialized) &&
-	    (interest->bellNotifyMask) &&
-            XIShouldNotify(interest->client,kbd)) {
+	    (interest->bellNotifyMask)) {
 	    if (!initialized) {
 		time = GetTimeInMillis();
 		bn.type = XkbEventCode + XkbEventBase;
@@ -589,8 +579,7 @@ CARD16		sk_delay,db_delay;
 	if ((!interest->client->clientGone) &&
 	    (interest->client->requestVector != InitialVector) &&
 	    (interest->client->xkbClientFlags&_XkbClientInitialized) &&
-	    (interest->accessXNotifyMask&(1<<pEv->detail)) &&
-            XIShouldNotify(interest->client, kbd)) {
+	    (interest->accessXNotifyMask&(1<<pEv->detail))) {
 	    if (!initialized) {
 		pEv->type = XkbEventCode + XkbEventBase;
 		pEv->xkbType = XkbAccessXNotify;
@@ -637,8 +626,7 @@ CARD32		changedIndicators;
 	if ((!interest->client->clientGone) &&
 	    (interest->client->requestVector != InitialVector) &&
 	    (interest->client->xkbClientFlags&_XkbClientInitialized) &&
-	    (interest->namesNotifyMask&pEv->changed) &&
-            XIShouldNotify(interest->client, kbd)) {
+	    (interest->namesNotifyMask&pEv->changed)) {
 	    if (!initialized) {
 		pEv->type = XkbEventCode + XkbEventBase;
 		pEv->xkbType = XkbNamesNotify;
@@ -683,8 +671,7 @@ CARD16		firstSI = 0, nSI = 0, nTotalSI = 0;
 	if ((!interest->client->clientGone) &&
 	    (interest->client->requestVector != InitialVector) &&
 	    (interest->client->xkbClientFlags&_XkbClientInitialized) &&
-	    (interest->compatNotifyMask) &&
-            XIShouldNotify(interest->client, kbd)) {
+	    (interest->compatNotifyMask)) {
 	    if (!initialized) {
 		pEv->type = XkbEventCode + XkbEventBase;
 		pEv->xkbType = XkbCompatMapNotify;
@@ -736,8 +723,7 @@ Time 		 time = 0;
 	if ((!interest->client->clientGone) &&
 	    (interest->client->requestVector != InitialVector) &&
 	    (interest->client->xkbClientFlags&_XkbClientInitialized) &&
-	    (interest->actionMessageMask) &&
-            XIShouldNotify(interest->client, kbd)) {
+	    (interest->actionMessageMask)) {
 	    if (!initialized) {
 		pEv->type = XkbEventCode + XkbEventBase;
 		pEv->xkbType = XkbActionMessage;
@@ -783,8 +769,7 @@ CARD16		 reason;
 	if ((!interest->client->clientGone) &&
 	    (interest->client->requestVector != InitialVector) &&
 	    (interest->client->xkbClientFlags&_XkbClientInitialized) &&
-	    (interest->extDevNotifyMask&reason) &&
-            XIShouldNotify(interest->client, dev)) {
+	    (interest->extDevNotifyMask&reason)) {
 	    if (!initialized) {
 		pEv->type = XkbEventCode + XkbEventBase;
 		pEv->xkbType = XkbExtensionDeviceNotify;
commit a79d4544fee806a25447d0147535ebc5a1cae6b9
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Tue May 3 03:03:06 2011 +0100

    XKB: Send NewKeyboardNotify for dev before its master/slaves
    
    When we change the keymap on a device, send the NewKeyboardNotify for
    that device before we copy the keymap to and notify for its attached
    master/slave devices.
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkb.c b/xkb/xkb.c
index 4d21200..86231a8 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5871,6 +5871,18 @@ ProcXkbGetKbdByName(ClientPtr client)
 	}
 	xkb->ctrls->num_groups= nTG;
 
+	nkn.deviceID= nkn.oldDeviceID= dev->id;
+	nkn.minKeyCode= new->min_key_code;
+	nkn.maxKeyCode= new->max_key_code;
+	nkn.oldMinKeyCode= xkb->min_key_code;
+	nkn.oldMaxKeyCode= xkb->max_key_code;
+	nkn.requestMajor= XkbReqCode;
+	nkn.requestMinor= X_kbGetKbdByName;
+	nkn.changed= XkbNKN_KeycodesMask;
+	if (geom_changed)
+	    nkn.changed|= XkbNKN_GeometryMask;
+	XkbSendNewKeyboardNotify(dev,&nkn);
+
         /* Update the map and LED info on the device itself, as well as
          * any slaves if it's an MD, or its MD if it's an SD and was the
          * last device used on that MD. */
@@ -5894,18 +5906,6 @@ ProcXkbGetKbdByName(ClientPtr client)
                 XkbFreeSrvLedInfo(old_sli);
             }
         }
-
-	nkn.deviceID= nkn.oldDeviceID= dev->id;
-	nkn.minKeyCode= new->min_key_code;
-	nkn.maxKeyCode= new->max_key_code;
-	nkn.oldMinKeyCode= xkb->min_key_code;
-	nkn.oldMaxKeyCode= xkb->max_key_code;
-	nkn.requestMajor= XkbReqCode;
-	nkn.requestMinor= X_kbGetKbdByName;
-	nkn.changed= XkbNKN_KeycodesMask;
-	if (geom_changed)
-	    nkn.changed|= XkbNKN_GeometryMask;
-	XkbSendNewKeyboardNotify(dev,&nkn);
     }
     if ((new!=NULL)&&(new!=xkb)) {
 	XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE);
commit c7634498d4cd42c8571805122224dc2d0e44a585
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Tue May 3 02:59:53 2011 +0100

    XKB: Remove duplicate keymap-copying loop
    
    Previously we had:
        foreach (device + slaves of device) {
            XkbCopyDeviceKeymap(i, device);
            [...]
        }
        if (device was last slave of its MD) {
            XkbCopyDeviceKeymap(master, device);
        }
    and now:
        foreach (device + slaves of device + MD if device was last slave) {
            XkbCopyDeviceKeymap(i, device);
            [...]
        }
    
    As an extra bonus, when changing the keymap on a slave device, we now
    ensure the LED info on the master is kept in sync.
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkb.c b/xkb/xkb.c
index e17e216..4d21200 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5586,6 +5586,7 @@ ProcXkbGetKbdByName(ClientPtr client)
 {
     DeviceIntPtr 		dev;
     DeviceIntPtr                tmpd;
+    DeviceIntPtr                master;
     xkbGetKbdByNameReply 	rep = {0};
     xkbGetMapReply		mrep = {0};
     xkbGetCompatMapReply	crep = {0};
@@ -5611,6 +5612,7 @@ ProcXkbGetKbdByName(ClientPtr client)
 	return BadAccess;
 
     CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
+    master = GetMaster(dev, MASTER_KEYBOARD);
 
     xkb = dev->key->xkbInfo->desc;
     status= Success;
@@ -5869,8 +5871,12 @@ ProcXkbGetKbdByName(ClientPtr client)
 	}
 	xkb->ctrls->num_groups= nTG;
 
+        /* Update the map and LED info on the device itself, as well as
+         * any slaves if it's an MD, or its MD if it's an SD and was the
+         * last device used on that MD. */
         for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
-            if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev)
+            if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev &&
+                (tmpd != master || dev != master->lastSlave))
                 continue;
 
             if (tmpd != dev)
@@ -5900,12 +5906,6 @@ ProcXkbGetKbdByName(ClientPtr client)
 	if (geom_changed)
 	    nkn.changed|= XkbNKN_GeometryMask;
 	XkbSendNewKeyboardNotify(dev,&nkn);
-
-	if (!IsMaster(dev)) {
-	    DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD);
-	    if (master && master->lastSlave == dev)
-		XkbCopyDeviceKeymap(master, dev);
-	}
     }
     if ((new!=NULL)&&(new!=xkb)) {
 	XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE);
commit b8540d18c7d3a0f93f9e2565a410986eddedcecb
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Tue May 3 02:50:48 2011 +0100

    XKB: Simplify a loop in ProcXkbGetKbdByName
    
    Replace:
        for (stuff; things; etc) {
            if (misc || other) {
                [...]
            }
        }
    with:
        for (stuff; things; etc) {
            if (!misc && !other)
                continue;
            [...]
        }
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkb.c b/xkb/xkb.c
index c4cb740..e17e216 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5870,21 +5870,22 @@ ProcXkbGetKbdByName(ClientPtr client)
 	xkb->ctrls->num_groups= nTG;
 
         for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
-            if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) {
-                if (tmpd != dev)
-                    XkbCopyDeviceKeymap(tmpd, dev);
-
-                if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
-                    old_sli = tmpd->kbdfeed->xkb_sli;
-                    tmpd->kbdfeed->xkb_sli = NULL;
-                    sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0);
-                    if (sli) {
-                        sli->explicitState = old_sli->explicitState;
-                        sli->effectiveState = old_sli->effectiveState;
-                    }
-                    tmpd->kbdfeed->xkb_sli = sli;
-                    XkbFreeSrvLedInfo(old_sli);
+            if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev)
+                continue;
+
+            if (tmpd != dev)
+                XkbCopyDeviceKeymap(tmpd, dev);
+
+            if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
+                old_sli = tmpd->kbdfeed->xkb_sli;
+                tmpd->kbdfeed->xkb_sli = NULL;
+                sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0);
+                if (sli) {
+                    sli->explicitState = old_sli->explicitState;
+                    sli->effectiveState = old_sli->effectiveState;
                 }
+                tmpd->kbdfeed->xkb_sli = sli;
+                XkbFreeSrvLedInfo(old_sli);
             }
         }
 
commit 72b6639c83df74767094a5e0c2861fdc5ea03ecd
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Tue May 3 02:39:55 2011 +0100

    XKB: Don't send unnecessary NewKeyboardNotifies
    
    In the XKB GetKeyboardByName handler, we had the following pseudocode:
        if (device was last slave of its MD) {
            XkbCopyDeviceKeymap(master, slave);
            XkbSendNewKeyboardNotify(slave, &notify);
        }
    
    Even if the SendNewKeyboardNotify line nominated the correct device,
    which it didn't, it's unnecessary as XkbCopyDeviceKeymap already sends a
    NewKeyboardNotify on the destination device.
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkb.c b/xkb/xkb.c
index 4044d33..c4cb740 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5902,10 +5902,8 @@ ProcXkbGetKbdByName(ClientPtr client)
 
 	if (!IsMaster(dev)) {
 	    DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD);
-	    if (master && master->lastSlave == dev) {
+	    if (master && master->lastSlave == dev)
 		XkbCopyDeviceKeymap(master, dev);
-		XkbSendNewKeyboardNotify(dev,&nkn);
-	    }
 	}
     }
     if ((new!=NULL)&&(new!=xkb)) {
commit 70cef8d8baf058bacaff87ef49e3851628269597
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Wed Jan 19 20:42:10 2011 +0000

    Input: Simplify CheckPassiveGrabsOnWindow loop
    
    Instead of a mega never-ending if branch with no else, just continue
    to the next iteration of the loop if the conditions aren't met - pretty
    much entirely reindentation.
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 17194b1..895ab40 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3430,7 +3430,7 @@ CheckPassiveGrabsOnWindow(
 	DeviceIntPtr	gdev;
 	XkbSrvInfoPtr	xkbi = NULL;
 	xEvent *xE = NULL;
-	xEvent core;
+        int count, rc;
 
 	gdev= grab->modifierDevice;
         if (grab->grabtype == GRABTYPE_CORE)
@@ -3478,135 +3478,129 @@ CheckPassiveGrabsOnWindow(
                 match = CORE_MATCH;
         }
 
-        if (match && (!grab->confineTo ||
-	     (grab->confineTo->realized &&
-				BorderSizeNotEmpty(device, grab->confineTo))))
-	{
-            int rc, count = 0;
-            xEvent *xE = NULL;
+        if (!match || (grab->confineTo &&
+                       (!grab->confineTo->realized ||
+                        !BorderSizeNotEmpty(device, grab->confineTo))))
+            continue;
 
-            grabinfo = &device->deviceGrab;
-            /* In some cases a passive core grab may exist, but the client
-             * already has a core grab on some other device. In this case we
-             * must not get the grab, otherwise we may never ungrab the
-             * device.
-             */
+        grabinfo = &device->deviceGrab;
+        /* In some cases a passive core grab may exist, but the client
+         * already has a core grab on some other device. In this case we
+         * must not get the grab, otherwise we may never ungrab the
+         * device.
+         */
 
-            if (grab->grabtype == GRABTYPE_CORE)
+        if (grab->grabtype == GRABTYPE_CORE)
+        {
+            DeviceIntPtr other;
+            BOOL interfering = FALSE;
+
+            /* A passive grab may have been created for a different device
+               than it is assigned to at this point in time.
+               Update the grab's device and modifier device to reflect the
+               current state.
+               Since XGrabDeviceButton requires to specify the
+               modifierDevice explicitly, we don't override this choice.
+               */
+            if (tempGrab.type < GenericEvent)
             {
-                DeviceIntPtr other;
-                BOOL interfering = FALSE;
-
-                /* A passive grab may have been created for a different device
-                   than it is assigned to at this point in time.
-                   Update the grab's device and modifier device to reflect the
-                   current state.
-                   Since XGrabDeviceButton requires to specify the
-                   modifierDevice explicitly, we don't override this choice.
-                   */
-                if (tempGrab.type < GenericEvent)
-                {
-                    grab->device = device;
-                    grab->modifierDevice = GetPairedDevice(device);
-                }
+                grab->device = device;
+                grab->modifierDevice = GetPairedDevice(device);
+            }
 
-                for (other = inputInfo.devices; other; other = other->next)
+            for (other = inputInfo.devices; other; other = other->next)
+            {
+                GrabPtr othergrab = other->deviceGrab.grab;
+                if (othergrab && othergrab->grabtype == GRABTYPE_CORE &&
+                    SameClient(grab, rClient(othergrab)) &&
+                    ((IsPointerDevice(grab->device) &&
+                     IsPointerDevice(othergrab->device)) ||
+                     (IsKeyboardDevice(grab->device) &&
+                      IsKeyboardDevice(othergrab->device))))
                 {
-                    GrabPtr othergrab = other->deviceGrab.grab;
-                    if (othergrab && othergrab->grabtype == GRABTYPE_CORE &&
-                        SameClient(grab, rClient(othergrab)) &&
-                        ((IsPointerDevice(grab->device) &&
-                         IsPointerDevice(othergrab->device)) ||
-                         (IsKeyboardDevice(grab->device) &&
-                          IsKeyboardDevice(othergrab->device))))
-                    {
-                        interfering = TRUE;
-                        break;
-                    }
+                    interfering = TRUE;
+                    break;
                 }
-                if (interfering)
-                    continue;
             }
+            if (interfering)
+                continue;
+        }
 
-            if (!activate)
-            {
-                return grab;
-            }
-            else if (!GetXIType(event) && !GetCoreType(event))
-            {
-                ErrorF("Event type %d in CheckPassiveGrabsOnWindow is"
-                       " neither XI 1.x nor core\n", event->any.type);
-                return NULL;
-            }
+        if (!activate)
+        {
+            return grab;
+        }
+        else if (!GetXIType(event) && !GetCoreType(event))
+        {
+            ErrorF("Event type %d in CheckPassiveGrabsOnWindow is neither"
+                   " XI 1.x nor core\n", event->any.type);
+            return NULL;
+        }
 
-            /* The only consumers of corestate are Xi 1.x and core events,
-             * which are guaranteed to come from DeviceEvents. */
-            if (match & (XI_MATCH | CORE_MATCH))
-            {
-                event->device_event.corestate &= 0x1f00;
-                event->device_event.corestate |=
-                    tempGrab.modifiersDetail.exact & (~0x1f00);
-            }
+        /* The only consumers of corestate are Xi 1.x and core events, which
+         * are guaranteed to come from DeviceEvents. */
+        if (match & (XI_MATCH | CORE_MATCH))
+        {
+            event->device_event.corestate &= 0x1f00;
+            event->device_event.corestate |= tempGrab.modifiersDetail.exact &
+                                              (~0x1f00);
+        }
 
-            if (match & CORE_MATCH)
+        if (match & CORE_MATCH)
+        {
+            rc = EventToCore(event, &xE, &count);
+            if (rc != Success)
             {
-                rc = EventToCore((InternalEvent*)event, &xE, &count);
-                if (rc != Success)
-                {
-                    if (rc != BadMatch)
-                        ErrorF("[dix] %s: core conversion failed in CPGFW "
-                                "(%d, %d).\n", device->name, event->any.type,
-                                rc);
-                    continue;
-                }
-            } else if (match & XI2_MATCH)
+                if (rc != BadMatch)
+                    ErrorF("[dix] %s: core conversion failed in CPGFW "
+                            "(%d, %d).\n", device->name, event->any.type, rc);
+                continue;
+            }
+        } else if (match & XI2_MATCH)
+        {
+            rc = EventToXI2(event, &xE);
+            if (rc != Success)
             {
-                rc = EventToXI2(event, &xE);
-                if (rc != Success)
-                {
-                    if (rc != BadMatch)
-                        ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
-                                "(%d, %d).\n", device->name, event->any.type,
-                                rc);
-                    continue;
-                }
-                count = 1;
-            } else
+                if (rc != BadMatch)
+                    ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
+                            "(%d, %d).\n", device->name, event->any.type, rc);
+                continue;
+            }
+            count = 1;
+        } else
+        {
+            rc = EventToXI(event, &xE, &count);
+            if (rc != Success)
             {
-                rc = EventToXI(event, &xE, &count);
-                if (rc != Success)
-                {
-                    if (rc != BadMatch)
-                        ErrorF("[dix] %s: XI conversion failed in CPGFW "
-                                "(%d, %d).\n", device->name, event->any.type,
-                                rc);
-                    continue;
-                }
+                if (rc != BadMatch)
+                    ErrorF("[dix] %s: XI conversion failed in CPGFW "
+                            "(%d, %d).\n", device->name, event->any.type, rc);
+                continue;
             }
+        }
 
-	    (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
+        (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
 
-            if (xE)
-            {
-                FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
+        if (xE)
+        {
+            FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
 
-                /* XXX: XACE? */
-                TryClientEvents(rClient(grab), device, xE, count,
-                                       GetEventFilter(device, xE),
-                                       GetEventFilter(device, xE), grab);
-            }
+            /* XXX: XACE? */
+            TryClientEvents(rClient(grab), device, xE, count,
+                            GetEventFilter(device, xE),
+                            GetEventFilter(device, xE), grab);
+        }
 
-	    if (grabinfo->sync.state == FROZEN_NO_EVENT)
-	    {
-                if (!grabinfo->sync.event)
-                    grabinfo->sync.event = calloc(1, sizeof(DeviceEvent));
-                *grabinfo->sync.event = event->device_event;
-		grabinfo->sync.state = FROZEN_WITH_EVENT;
-            }
+        if (grabinfo->sync.state == FROZEN_NO_EVENT)
+        {
+            if (!grabinfo->sync.event)
+                grabinfo->sync.event = calloc(1, sizeof(DeviceEvent));
+            *grabinfo->sync.event = event->device_event;
+            grabinfo->sync.state = FROZEN_WITH_EVENT;
+        }
 
-            free(xE);
-	    return grab;
-	}
+        free(xE);
+        return grab;
     }
     return NULL;
 #undef CORE_MATCH
commit 00ba884556c675b2b25e116f5ab4eb4590b6dd56
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Wed Jan 19 20:38:44 2011 +0000

    Input: Make CheckPassiveGrabsOnWindow take InternalEvent
    
    Previously, it only took DeviceEvents, but it would be much more useful
    if it took InternalEvents.  Any event that activates a grab must still
    be a DeviceEvent, so put in a check to enforce this.
    
    Change all callers to make the appropriate casts.
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index b0107a0..17194b1 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2663,7 +2663,8 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
     event.deviceid = dev->id;
     event.sourceid = dev->id;
     event.detail.button = 0;
-    rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL);
+    rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
+                                    TRUE) != NULL);
     if (rc)
         DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab);
     return rc;
@@ -2700,7 +2701,8 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
     event.deviceid = dev->id;
     event.sourceid = dev->id;
     event.detail.button = 0;
-    rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL);
+    rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
+                                    TRUE) != NULL);
     if (rc)
         DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
     return rc;
@@ -3387,7 +3389,7 @@ GrabPtr
 CheckPassiveGrabsOnWindow(
     WindowPtr pWin,
     DeviceIntPtr device,
-    DeviceEvent *event,
+    InternalEvent *event,
     BOOL checkCore,
     BOOL activate)
 {
@@ -3404,9 +3406,22 @@ CheckPassiveGrabsOnWindow(
 	return NULL;
     /* Fill out the grab details, but leave the type for later before
      * comparing */
+    switch (event->any.type)
+    {
+        case ET_KeyPress:
+        case ET_KeyRelease:
+            tempGrab.detail.exact = event->device_event.detail.key;
+            break;
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+            tempGrab.detail.exact = event->device_event.detail.button;
+            break;
+        default:
+            tempGrab.detail.exact = 0;
+            break;
+    }
     tempGrab.window = pWin;
     tempGrab.device = device;
-    tempGrab.detail.exact = event->detail.key;
     tempGrab.detail.pMask = NULL;
     tempGrab.modifiersDetail.pMask = NULL;
     tempGrab.next = NULL;
@@ -3414,6 +3429,8 @@ CheckPassiveGrabsOnWindow(
     {
 	DeviceIntPtr	gdev;
 	XkbSrvInfoPtr	xkbi = NULL;
+	xEvent *xE = NULL;
+	xEvent core;
 
 	gdev= grab->modifierDevice;
         if (grab->grabtype == GRABTYPE_CORE)
@@ -3439,16 +3456,15 @@ CheckPassiveGrabsOnWindow(
         tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
 
         /* Check for XI2 and XI grabs first */
-        tempGrab.type = GetXI2Type((InternalEvent*)event);
+        tempGrab.type = GetXI2Type(event);
         tempGrab.grabtype = GRABTYPE_XI2;
         if (GrabMatchesSecond(&tempGrab, grab, FALSE))
             match = XI2_MATCH;
 
-        tempGrab.detail.exact = event->detail.key;
         if (!match)
         {
             tempGrab.grabtype = GRABTYPE_XI;
-            if ((tempGrab.type = GetXIType((InternalEvent*)event)) &&
+            if ((tempGrab.type = GetXIType(event)) &&
                 (GrabMatchesSecond(&tempGrab, grab, FALSE)))
                 match = XI_MATCH;
         }
@@ -3457,7 +3473,7 @@ CheckPassiveGrabsOnWindow(
         if (!match && checkCore)
         {
             tempGrab.grabtype = GRABTYPE_CORE;
-            if ((tempGrab.type = GetCoreType((InternalEvent*)event)) &&
+            if ((tempGrab.type = GetCoreType(event)) &&
                 (GrabMatchesSecond(&tempGrab, grab, TRUE)))
                 match = CORE_MATCH;
         }
@@ -3469,8 +3485,6 @@ CheckPassiveGrabsOnWindow(
             int rc, count = 0;
             xEvent *xE = NULL;
 
-            event->corestate &= 0x1f00;
-            event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
             grabinfo = &device->deviceGrab;
             /* In some cases a passive core grab may exist, but the client
              * already has a core grab on some other device. In this case we
@@ -3515,7 +3529,24 @@ CheckPassiveGrabsOnWindow(
             }
 
             if (!activate)
+            {
                 return grab;
+            }
+            else if (!GetXIType(event) && !GetCoreType(event))
+            {
+                ErrorF("Event type %d in CheckPassiveGrabsOnWindow is"
+                       " neither XI 1.x nor core\n", event->any.type);
+                return NULL;
+            }
+
+            /* The only consumers of corestate are Xi 1.x and core events,
+             * which are guaranteed to come from DeviceEvents. */
+            if (match & (XI_MATCH | CORE_MATCH))
+            {
+                event->device_event.corestate &= 0x1f00;
+                event->device_event.corestate |=
+                    tempGrab.modifiersDetail.exact & (~0x1f00);
+            }
 
             if (match & CORE_MATCH)
             {
@@ -3524,28 +3555,31 @@ CheckPassiveGrabsOnWindow(
                 {
                     if (rc != BadMatch)
                         ErrorF("[dix] %s: core conversion failed in CPGFW "
-                                "(%d, %d).\n", device->name, event->type, rc);
+                                "(%d, %d).\n", device->name, event->any.type,
+                                rc);
                     continue;
                 }
             } else if (match & XI2_MATCH)
             {
-                rc = EventToXI2((InternalEvent*)event, &xE);
+                rc = EventToXI2(event, &xE);
                 if (rc != Success)
                 {
                     if (rc != BadMatch)
                         ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
-                                "(%d, %d).\n", device->name, event->type, rc);
+                                "(%d, %d).\n", device->name, event->any.type,
+                                rc);
                     continue;
                 }
                 count = 1;
             } else
             {
-                rc = EventToXI((InternalEvent*)event, &xE, &count);
+                rc = EventToXI(event, &xE, &count);
                 if (rc != Success)
                 {
                     if (rc != BadMatch)
                         ErrorF("[dix] %s: XI conversion failed in CPGFW "
-                                "(%d, %d).\n", device->name, event->type, rc);
+                                "(%d, %d).\n", device->name, event->any.type,
+                                rc);
                     continue;
                 }
             }
@@ -3566,7 +3600,7 @@ CheckPassiveGrabsOnWindow(
 	    {
                 if (!grabinfo->sync.event)
                     grabinfo->sync.event = calloc(1, sizeof(DeviceEvent));
-                *grabinfo->sync.event = *event;
+                *grabinfo->sync.event = event->device_event;
 		grabinfo->sync.state = FROZEN_WITH_EVENT;
             }
 
@@ -3641,7 +3675,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
 	for (; i < focus->traceGood; i++)
 	{
 	    pWin = focus->trace[i];
-	    if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE))
+	    if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
+                                          sendCore, TRUE))
 	    {
 		ret = TRUE;
 		goto out;
@@ -3657,7 +3692,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
     for (; i < device->spriteInfo->sprite->spriteTraceGood; i++)
     {
 	pWin = device->spriteInfo->sprite->spriteTrace[i];
-	if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE))
+	if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
+	                              sendCore, TRUE))
 	{
 	    ret = TRUE;
 	    goto out;
diff --git a/include/dix.h b/include/dix.h
index c201e3a..fb9be43 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -375,7 +375,7 @@ extern void ReleaseActiveGrabs(
 extern GrabPtr CheckPassiveGrabsOnWindow(
     WindowPtr /* pWin */,
     DeviceIntPtr /* device */,
-    DeviceEvent * /* event */,
+    InternalEvent * /* event */,
     BOOL /* checkCore */,
     BOOL /* activate */);
 
commit 56901998020b6f443cbaa5eb303100d979e81b22
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 5 08:48:19 2011 +1000

    input: change CHECKEVENT macro to verify_internal_event function
    
    The macro is sufficient if called during a development cycle, but not
    sufficient information when triggered by a user (e.g.
    https://bugzilla.redhat.com/show_bug.cgi?id=688693).
    
    Expand what this does to print the event content and a backtrace, so at
    least we know where we're coming from. Only the first 32 bytes are printed
    since if something goes wrong, the event we have is almost certainly an
    xEvent or xError, both restricted to 32 bytes.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 76d5c37..d48d397 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -77,6 +77,7 @@ SOFTWARE.
 #include "xiquerydevice.h" /* For List*Info */
 #include "eventconvert.h"
 #include "eventstr.h"
+#include "inpututils.h"
 
 #include <X11/extensions/XKBproto.h>
 #include "xkbsrv.h"
@@ -920,7 +921,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
     DeviceIntPtr mouse = NULL, kbd = NULL;
     DeviceEvent *event = &ev->device_event;
 
-    CHECKEVENT(ev);
+    verify_internal_event(ev);
 
     if (ev->any.type == ET_RawKeyPress ||
         ev->any.type == ET_RawKeyRelease ||
diff --git a/dix/events.c b/dix/events.c
index bc08f7b..b0107a0 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2377,7 +2377,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
     xEvent *xE = NULL, *core = NULL;
     int rc, mask, count = 0;
 
-    CHECKEVENT(event);
+    verify_internal_event(event);
 
     while (pWin)
     {
@@ -2723,7 +2723,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
     WindowPtr prevSpriteWin, newSpriteWin;
     SpritePtr pSprite = pDev->spriteInfo->sprite;
 
-    CHECKEVENT(ev);
+    verify_internal_event(ev);
 
     prevSpriteWin = pSprite->win;
 
diff --git a/dix/inpututils.c b/dix/inpututils.c
index 077ffce..aeace6e 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -36,6 +36,7 @@
 #include "xkbsrv.h"
 #include "xkbstr.h"
 #include "inpututils.h"
+#include "eventstr.h"
 
 /* Check if a button map change is okay with the device.
  * Returns -1 for BadValue, as it collides with MappingBusy. */
@@ -556,3 +557,30 @@ CountBits(const uint8_t *mask, int len)
 
     return ret;
 }
+
+/**
+ * Verifies sanity of the event. If the event is not an internal event,
+ * memdumps the first 32 bytes of event to the log, a backtrace, then kill
+ * the server.
+ */
+void verify_internal_event(const InternalEvent *ev)
+{
+    if (ev && ev->any.header != ET_Internal)
+    {
+        int i;
+        unsigned char *data = (unsigned char*)ev;
+
+        ErrorF("dix: invalid event type %d\n", ev->any.header);
+
+        for (i = 0; i < sizeof(xEvent); i++, data++)
+        {
+            ErrorF("%02hx ", *data);
+
+            if ((i % 8) == 7)
+                ErrorF("\n");
+        }
+
+        xorg_backtrace();
+        FatalError("Wrong event type %d. Aborting server\n", ev->any.header);
+    }
+}
diff --git a/include/eventstr.h b/include/eventstr.h
index 673207c..049688c 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -68,10 +68,6 @@ enum EventType {
     ET_Internal = 0xFF /* First byte */
 };
 
-#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->any.header != 0xFF) \
-                          FatalError("Wrong event type %d.\n", \
-                                     ((InternalEvent*)(ev))->any.header);
-
 /**
  * Used for ALL input device events internal in the server until
  * copied into the matching protocol event.
diff --git a/include/inpututils.h b/include/inpututils.h
index b8ca6ab..92a7543 100644
--- a/include/inpututils.h
+++ b/include/inpututils.h
@@ -37,4 +37,6 @@ struct _ValuatorMask {
     int         valuators[MAX_VALUATORS]; /* valuator data */
 };
 
+extern void verify_internal_event(const InternalEvent *ev);
+
 #endif
diff --git a/mi/mieq.c b/mi/mieq.c
index 08a0c87..3e6f931 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -156,7 +156,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
     pthread_mutex_lock(&miEventQueueMutex);
 #endif
 
-    CHECKEVENT(e);
+    verify_internal_event(e);
 
     /* avoid merging events from different devices */
     if (e->any.type == ET_Motion)
@@ -292,8 +292,8 @@ static void
 FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev,
                     InternalEvent* original, InternalEvent *master)
 {
-    CHECKEVENT(original);
-    CHECKEVENT(master);
+    verify_internal_event(original);
+    verify_internal_event(master);
     /* Ensure chained button mappings, i.e. that the detail field is the
      * value of the mapped button on the SD, not the physical button */
     if (original->any.type == ET_ButtonPress ||
@@ -323,7 +323,7 @@ CopyGetMasterEvent(DeviceIntPtr sdev,
     int type = original->any.type;
     int mtype; /* which master type? */
 
-    CHECKEVENT(original);
+    verify_internal_event(original);
 
     /* ET_XQuartz has sdev == NULL */
     if (!sdev || IsMaster(sdev) || IsFloating(sdev))
@@ -376,7 +376,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
     DeviceIntPtr master;
     InternalEvent mevent; /* master event */
 
-    CHECKEVENT(event);
+    verify_internal_event(event);
 
     /* Custom event handler */
     handler = miEventQueue.handlers[event->any.type];
commit bf2059b07a97e5e579c13c2c9d49707093427dc2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 15 14:06:20 2011 +1000

    input: Only release SD buttons for explicit floating/reattachment (#36146)
    
    Grabbing an SD device temporary floats the device but we must not release
    the buttons. Introduced in
    
        commit 9d23459415b84606ee4f38bb2d19054c432c8552
        Author: Peter Hutterer <peter.hutterer at who-t.net>
        Date:   Fri Feb 25 11:08:19 2011 +1000
    
        dix: release all buttons and keys before reattaching a device (#34182)
    
    X.Org Bug 36146 <http://bugs.freedesktop.org/show_bug.cgi?id=36146>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
index 0736a5a..96ead6f 100644
--- a/Xi/xichangehierarchy.c
+++ b/Xi/xichangehierarchy.c
@@ -355,6 +355,7 @@ detach_slave(ClientPtr client, xXIDetachSlaveInfo *c, int flags[MAXDEVICES])
         goto unwind;
     }
 
+    ReleaseButtonsAndKeys(dev);
     AttachDevice(client, dev, NULL);
     flags[dev->id] |= XISlaveDetached;
 
@@ -406,6 +407,7 @@ attach_slave(ClientPtr client, xXIAttachSlaveInfo *c,
         goto unwind;
     }
 
+    ReleaseButtonsAndKeys(dev);
     AttachDevice(client, dev, newmaster);
     flags[dev->id] |= XISlaveAttached;
 
diff --git a/dix/devices.c b/dix/devices.c
index 3f46ad6..7968c73 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2365,7 +2365,7 @@ RecalculateMasterButtons(DeviceIntPtr slave)
  * Generate release events for all keys/button currently down on this
  * device.
  */
-static void
+void
 ReleaseButtonsAndKeys(DeviceIntPtr dev)
 {
     EventListPtr        eventlist = InitEventList(GetMaximumEventsNum());
@@ -2434,8 +2434,6 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
         free(dev->spriteInfo->sprite);
     }
 
-    ReleaseButtonsAndKeys(dev);
-
     oldmaster = GetMaster(dev, MASTER_ATTACHED);
     dev->master = master;
 
diff --git a/include/input.h b/include/input.h
index 86078da..6799a53 100644
--- a/include/input.h
+++ b/include/input.h
@@ -495,6 +495,8 @@ extern _X_EXPORT int GetMotionHistory(
     ScreenPtr pScreen,
     BOOL core);
 
+extern void ReleaseButtonsAndKeys(DeviceIntPtr dev);
+
 extern int AttachDevice(ClientPtr client,
                         DeviceIntPtr slave,
                         DeviceIntPtr master);
commit eac37f32b85b631d94ee3ba11fa65b9d2cb72c38
Author: Ville Syrjälä <ville.syrjala at nokia.com>
Date:   Wed Apr 13 21:46:20 2011 +0300

    composite: Recompute clipping when changing between manual and automatic redirection
    
    Call compMarkWindows() when changing between manual and automatic
    redirection modes. Otherwise the window clipping won't be recomputed
    correctly.
    
    Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 37d2245..5c27631 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -226,6 +226,10 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	}
 	cw->update = CompositeRedirectManual;
     }
+    else if (cw->update == CompositeRedirectAutomatic && !cw->damageRegistered) {
+	if (!anyMarked)
+	    anyMarked = compMarkWindows (pWin, &pLayerWin);
+    }
 
     if (!compCheckRedirect (pWin))
     {
@@ -314,6 +318,8 @@ compFreeClientWindow (WindowPtr pWin, XID id)
     else if (cw->update == CompositeRedirectAutomatic &&
 	     !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
     {
+	anyMarked = compMarkWindows (pWin, &pLayerWin);
+
 	DamageRegister (&pWin->drawable, cw->damage);
 	cw->damageRegistered = TRUE;
 	pWin->redirectDraw = RedirectDrawAutomatic;
commit f2001b0f6dffa0a8f05def4a86ea37c4c91db724
Author: Ville Syrjälä <ville.syrjala at nokia.com>
Date:   Wed Apr 13 21:45:43 2011 +0300

    composite: Fix pWin->redirectDraw when changing between manual and automatic redirection
    
    compAllowPixmap() is not called when changing between manual and
    automatic redirection modes. That means pWin->redirectDraw is left
    with an incorrect value, and miComputeClips() gets confused whether
    the window is supposed to be treated as transparent or not. Fix
    the issue by updating pWin->redirectDraw in compCheckRedirect()
    even when not calling compAllocPixmap().
    
    Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>

diff --git a/composite/compwindow.c b/composite/compwindow.c
index bcbdf35..d2a866d 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -171,6 +171,11 @@ compCheckRedirect (WindowPtr pWin)
 	    compRestoreWindow (pWin, pPixmap);
 	    (*pScreen->DestroyPixmap) (pPixmap);
 	}
+    } else if (should) {
+	if (cw->update == CompositeRedirectAutomatic)
+	    pWin->redirectDraw = RedirectDrawAutomatic;
+	else
+	    pWin->redirectDraw = RedirectDrawManual;
     }
     return TRUE;
 }
commit 74663e61528346aeea9c11908b6980b51dcaeb68
Author: Ville Syrjälä <ville.syrjala at nokia.com>
Date:   Mon Dec 20 16:37:24 2010 +0200

    composite: Copy the window contents back from the pixmap
    
    Since extra expose events are no longer generated during window
    unredirection, the window contents must be preserved by the server.
    So copy the window contents back from the pixmap. The copy can only
    be done after the clips have been recomputed, so delay the copy and
    the pixmap destruction until ValidateTree is done. Window borders are
    restored by HandleExposures and thus don't need to be copied back.
    
    Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 23654a7..37d2245 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -239,6 +239,34 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
     return Success;
 }
 
+void
+compRestoreWindow (WindowPtr pWin, PixmapPtr pPixmap)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pParent = pWin->parent;
+
+    if (pParent->drawable.depth == pWin->drawable.depth) {
+	GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+	int bw = (int) pWin->borderWidth;
+	int x = bw;
+	int y = bw;
+	int w = pWin->drawable.width;
+	int h = pWin->drawable.height;
+
+	if (pGC) {
+	    ChangeGCVal val;
+	    val.val = IncludeInferiors;
+	    ChangeGC (NullClient, pGC, GCSubwindowMode, &val);
+	    ValidateGC(&pWin->drawable, pGC);
+	    (*pGC->ops->CopyArea) (&pPixmap->drawable,
+				   &pWin->drawable,
+				   pGC,
+				   x, y, w, h, 0, 0);
+	    FreeScratchGC (pGC);
+	}
+    }
+}
+
 /*
  * Free one of the per-client per-window resources, clearing
  * redirect and the per-window pointer as appropriate
@@ -246,10 +274,12 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 void
 compFreeClientWindow (WindowPtr pWin, XID id)
 {
+    ScreenPtr		pScreen = pWin->drawable.pScreen;
     CompWindowPtr	cw = GetCompWindow (pWin);
     CompClientWindowPtr	ccw, *prev;
     Bool		anyMarked = FALSE;
     WindowPtr		pLayerWin;
+    PixmapPtr           pPixmap = NULL;
 
     if (!cw)
 	return;
@@ -268,8 +298,10 @@ compFreeClientWindow (WindowPtr pWin, XID id)
     {
 	anyMarked = compMarkWindows (pWin, &pLayerWin);
     
-	if (pWin->redirectDraw != RedirectDrawNone)
-	    compFreePixmap (pWin);
+	if (pWin->redirectDraw != RedirectDrawNone) {
+	    pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+	    compSetParentPixmap (pWin);
+	}
 
 	if (cw->damage)
 	    DamageDestroy (cw->damage);
@@ -290,6 +322,11 @@ compFreeClientWindow (WindowPtr pWin, XID id)
 
     if (anyMarked)
 	compHandleMarkedWindows (pWin, pLayerWin);
+
+    if (pPixmap) {
+	compRestoreWindow (pWin, pPixmap);
+	(*pScreen->DestroyPixmap) (pPixmap);
+    }
 }
 
 /*
@@ -621,10 +658,10 @@ compAllocPixmap (WindowPtr pWin)
 }
 
 void
-compFreePixmap (WindowPtr pWin)
+compSetParentPixmap (WindowPtr pWin)
 {
     ScreenPtr	    pScreen = pWin->drawable.pScreen;
-    PixmapPtr	    pRedirectPixmap, pParentPixmap;
+    PixmapPtr	    pParentPixmap;
     CompWindowPtr   cw = GetCompWindow (pWin);
 
     if (cw->damageRegistered)
@@ -640,11 +677,9 @@ compFreePixmap (WindowPtr pWin)
      * parent exposed area; regions beyond the parent cause crashes
      */
     RegionCopy(&pWin->borderClip, &cw->borderClip);
-    pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
     pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
     pWin->redirectDraw = RedirectDrawNone;
     compSetPixmap (pWin, pParentPixmap);
-    (*pScreen->DestroyPixmap) (pRedirectPixmap);
 }
 
 /*
diff --git a/composite/compint.h b/composite/compint.h
index 57e0b5d..bb5335d 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -215,7 +215,10 @@ Bool
 compAllocPixmap (WindowPtr pWin);
 
 void
-compFreePixmap (WindowPtr pWin);
+compSetParentPixmap (WindowPtr pWin);
+
+void
+compRestoreWindow (WindowPtr pWin, PixmapPtr pPixmap);
 
 Bool
 compReallocPixmap (WindowPtr pWin, int x, int y,
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 2440f18..bcbdf35 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -164,8 +164,13 @@ compCheckRedirect (WindowPtr pWin)
     {
 	if (should)
 	    return compAllocPixmap (pWin);
-	else
-	    compFreePixmap (pWin);
+	else {
+	    ScreenPtr pScreen = pWin->drawable.pScreen;
+	    PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+	    compSetParentPixmap (pWin);
+	    compRestoreWindow (pWin, pPixmap);
+	    (*pScreen->DestroyPixmap) (pPixmap);
+	}
     }
     return TRUE;
 }
@@ -583,8 +588,11 @@ compDestroyWindow (WindowPtr pWin)
     while ((csw = GetCompSubwindows (pWin)))
 	FreeResource (csw->clients->id, RT_NONE);
 
-    if (pWin->redirectDraw != RedirectDrawNone)
-	compFreePixmap (pWin);
+    if (pWin->redirectDraw != RedirectDrawNone) {
+	PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
+	compSetParentPixmap (pWin);
+	(*pScreen->DestroyPixmap) (pPixmap);
+    }
     ret = (*pScreen->DestroyWindow) (pWin);
     cs->DestroyWindow = pScreen->DestroyWindow;
     pScreen->DestroyWindow = compDestroyWindow;
commit 193ecc8b453b22b3e60248b9354c768dbd405598
Author: Ville Syrjälä <ville.syrjala at nokia.com>
Date:   Fri Dec 17 23:46:34 2010 +0200

    composite: Get rid of the internal UnmapWindow+MapWindow cycle
    
    Eliminate the internal MapWindow+UnmapWindow cycle around window
    redirection changes. Instead do the work in a single pass by marking
    the afected windows and calling ValidateTree and HandleExposures
    directly. This gets rid of unnecessary expose events, and invalid
    ClipNotify calls during rediredction changes. Now ClipNotify will only
    get called with the final clip values, and expose events are only sent
    to areas that actually got exposed.
    
    Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 6d10b2e..23654a7 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -104,6 +104,35 @@ compDestroyDamage (DamagePtr pDamage, void *closure)
     cw->damage = 0;
 }
 
+static Bool
+compMarkWindows(WindowPtr pWin,
+		WindowPtr *ppLayerWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pLayerWin = pWin;
+
+    if (!pWin->viewable)
+	return FALSE;
+
+    (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+    (*pScreen->MarkWindow)(pLayerWin->parent);
+
+    *ppLayerWin = pLayerWin;
+
+    return TRUE;
+}
+
+static void
+compHandleMarkedWindows(WindowPtr pWin, WindowPtr pLayerWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+    (*pScreen->HandleExposures)(pLayerWin->parent);
+    if (pScreen->PostValidateTree)
+	(*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+}
+
 /*
  * Redirect one window for one client
  */
@@ -112,8 +141,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 {
     CompWindowPtr	cw = GetCompWindow (pWin);
     CompClientWindowPtr	ccw;
-    Bool		wasMapped = pWin->mapped;
     CompScreenPtr       cs = GetCompScreen(pWin->drawable.pScreen);
+    WindowPtr		pLayerWin;
+    Bool		anyMarked = FALSE;
     
     if (pWin == cs->pOverlayWin) {
 	return Success;
@@ -163,12 +193,8 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	    free(cw);
 	    return BadAlloc;
 	}
-	if (wasMapped)
-	{
-	    DisableMapUnmapEvents (pWin);
-	    UnmapWindow (pWin, FALSE);
-	    EnableMapUnmapEvents (pWin);
-	}
+
+	anyMarked = compMarkWindows (pWin, &pLayerWin);
 
 	/* Make sure our borderClip is correct for ValidateTree */
 	RegionNull(&cw->borderClip);
@@ -190,16 +216,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	return BadAlloc;
     if (ccw->update == CompositeRedirectManual)
     {
-	/* If the window was CompositeRedirectAutomatic, then
-	 * unmap the window so that the parent clip list will
-	 * be correctly recomputed.
-	 */
-	if (pWin->mapped) 
-	{
-	    DisableMapUnmapEvents (pWin);
-	    UnmapWindow (pWin, FALSE);
-	    EnableMapUnmapEvents (pWin);
-	}
+	if (!anyMarked)
+	    anyMarked = compMarkWindows (pWin, &pLayerWin);
+
 	if (cw->damageRegistered)
 	{
 	    DamageUnregister (&pWin->drawable, cw->damage);
@@ -213,15 +232,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	FreeResource (ccw->id, RT_NONE);
 	return BadAlloc;
     }
-    if (wasMapped && !pWin->mapped)
-    {
-	Bool	overrideRedirect = pWin->overrideRedirect;
-	pWin->overrideRedirect = TRUE;
-	DisableMapUnmapEvents (pWin);
-	MapWindow (pWin, pClient);
-	EnableMapUnmapEvents (pWin);
-	pWin->overrideRedirect = overrideRedirect;
-    }
+
+    if (anyMarked)
+	compHandleMarkedWindows (pWin, pLayerWin);
     
     return Success;
 }
@@ -235,7 +248,8 @@ compFreeClientWindow (WindowPtr pWin, XID id)
 {
     CompWindowPtr	cw = GetCompWindow (pWin);
     CompClientWindowPtr	ccw, *prev;
-    Bool		wasMapped = pWin->mapped;
+    Bool		anyMarked = FALSE;
+    WindowPtr		pLayerWin;
 
     if (!cw)
 	return;
@@ -252,12 +266,7 @@ compFreeClientWindow (WindowPtr pWin, XID id)
     }
     if (!cw->clients)
     {
-	if (wasMapped)
-	{
-	    DisableMapUnmapEvents (pWin);
-	    UnmapWindow (pWin, FALSE);
-	    EnableMapUnmapEvents (pWin);
-	}
+	anyMarked = compMarkWindows (pWin, &pLayerWin);
     
 	if (pWin->redirectDraw != RedirectDrawNone)
 	    compFreePixmap (pWin);
@@ -278,15 +287,9 @@ compFreeClientWindow (WindowPtr pWin, XID id)
 	pWin->redirectDraw = RedirectDrawAutomatic;
 	DamageDamageRegion(&pWin->drawable, &pWin->borderSize);
     }
-    if (wasMapped && !pWin->mapped)
-    {
-	Bool	overrideRedirect = pWin->overrideRedirect;
-	pWin->overrideRedirect = TRUE;
-	DisableMapUnmapEvents (pWin);
-	MapWindow (pWin, clients[CLIENT_ID(id)]);
-	EnableMapUnmapEvents (pWin);
-	pWin->overrideRedirect = overrideRedirect;
-    }
+
+    if (anyMarked)
+	compHandleMarkedWindows (pWin, pLayerWin);
 }
 
 /*
commit a6ae91746212203a19450ac955fbb7abffff1ed3
Author: Ville Syrjälä <ville.syrjala at nokia.com>
Date:   Mon Dec 20 16:30:52 2010 +0200

    composite: Initialize borderClip with current values
    
    ValidateTree needs a valid borderClip so initialize the parent
    constrained border clip with the window's current borderClip
    in compRedirectWindow.
    
    Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 2b68645..6d10b2e 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -170,9 +170,11 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	    EnableMapUnmapEvents (pWin);
 	}
 
+	/* Make sure our borderClip is correct for ValidateTree */
 	RegionNull(&cw->borderClip);
-	cw->borderClipX = 0;
-	cw->borderClipY = 0;
+	RegionCopy(&cw->borderClip, &pWin->borderClip);
+	cw->borderClipX = pWin->drawable.x;
+	cw->borderClipY = pWin->drawable.y;
 	cw->update = CompositeRedirectAutomatic;
 	cw->clients = 0;
 	cw->oldx = COMP_ORIGIN_INVALID;
commit ce9eff9e4c30deb16f059ed84b436d37da45d5d5
Author: Ville Syrjälä <ville.syrjala at nokia.com>
Date:   Mon Dec 20 16:33:36 2010 +0200

    composite: Call ValidateGC after ChangeGC
    
    ChangeGC changes the GC, so ValidateGC should be called after it, not
    before.
    
    Also pass NullClient instead of serverClient to ChangeGC() since we
    know the changed values to be valid, and setting
    serverClient->errorValue seems pointless anyway.
    
    Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 7164c0d..2b68645 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -536,9 +536,8 @@ compNewPixmap (WindowPtr pWin, int x, int y, int w, int h, Bool map)
 	{
 	    ChangeGCVal val;
 	    val.val = IncludeInferiors;
-	    
+	    ChangeGC (NullClient, pGC, GCSubwindowMode, &val);
 	    ValidateGC(&pPixmap->drawable, pGC);
-	    ChangeGC (serverClient, pGC, GCSubwindowMode, &val);
 	    (*pGC->ops->CopyArea) (&pParent->drawable,
 				   &pPixmap->drawable,
 				   pGC,
commit 043c1758652259fd12b88ae37720fe6e93eda76b
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Apr 19 19:02:54 2011 -0700

    Clean up memory better when GetVisualInfo fails in ProcDbeGetVisualInfo
    
    Use calloc to initialize pScrVisInfo array so we don't have to check
    which ones were already initialized when freeing them all.
    
    On failure, set rc if necessary, and jump to code at end that already
    frees all the necessary allocations and return rc.
    
    Fixes parfait reported error:
    Error: Memory leak (CWE 401)
       Memory leak of pointer 'pScrVisInfo' allocated with malloc((count * 16))
            at line 724 of dbe/dbe.c in function 'ProcDbeGetVisualInfo'.
              'pScrVisInfo' allocated at line 693 with malloc((count * 16)).
              pScrVisInfo leaks when rc != 0 at line 710
                  and j >= i at line 716.
    
    [ This bug was found by the Parfait 0.3.7 bug checking tool.
      For more information see http://labs.oracle.com/projects/parfait/ ]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/dbe/dbe.c b/dbe/dbe.c
index 77b616b..51bbdc6 100644
--- a/dbe/dbe.c
+++ b/dbe/dbe.c
@@ -690,8 +690,7 @@ ProcDbeGetVisualInfo(ClientPtr client)
     }
 
     count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
-    if (!(pScrVisInfo = (XdbeScreenVisualInfo *)malloc(count *
-                        sizeof(XdbeScreenVisualInfo))))
+    if (!(pScrVisInfo = calloc(count, sizeof(XdbeScreenVisualInfo))))
     {
         free(pDrawables);
 
@@ -707,21 +706,16 @@ ProcDbeGetVisualInfo(ClientPtr client)
         pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
 
 	rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
-	if ((rc != Success) ||
-	    !(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
+        if (rc != Success)
+            goto freeScrVisInfo;
+
+        if (!(*pDbeScreenPriv->GetVisualInfo)(pScreen, &pScrVisInfo[i]))
         {
             /* We failed to alloc pScrVisInfo[i].visinfo. */
+            rc = BadAlloc;
 
             /* Free visinfos that we allocated for previous screen infos.*/
-            for (j = 0; j < i; j++)
-            {
-                free(pScrVisInfo[j].visinfo);
-            }
-
-            /* Free pDrawables if we needed to allocate it above. */
-            free(pDrawables);
-
-            return (rc == Success) ? BadAlloc : rc;
+            goto freeScrVisInfo;
         }
 
         /* Account for n, number of xDbeVisInfo items in list. */
@@ -790,6 +784,9 @@ ProcDbeGetVisualInfo(ClientPtr client)
         }
     }
 
+    rc = Success;
+
+  freeScrVisInfo:
     /* Clean up memory. */
     for (i = 0; i < count; i++)
     {
@@ -799,7 +796,7 @@ ProcDbeGetVisualInfo(ClientPtr client)
 
     free(pDrawables);
 
-    return Success;
+    return rc;
 
 } /* ProcDbeGetVisualInfo() */
 
commit dadb0791ebfd05cd3bb82d4addf0fbc21aad6fbb
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Tue Apr 19 18:53:22 2011 -0700

    Only free pContext once when AddResource fails in ProcRecordCreateContext
    
    Since RecordDeleteContext frees its argument, don't fall through to free
    it again.
    
    Error: Double free (CWE 415)
       Double free of pointer 'malloc(1072)' defined by malloc
            at line 1964 of record/record.c in function 'ProcRecordCreateContext'.
              Previously freed at line 1960 with RecordDeleteContext.
              'malloc(1072)' was allocated at line 1926 with malloc.
    
    [ This bug was found by the Parfait 0.3.7 bug checking tool.
      For more information see http://labs.oracle.com/projects/parfait/ ]
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/record/record.c b/record/record.c
index 53be182..69fca72 100644
--- a/record/record.c
+++ b/record/record.c
@@ -1958,7 +1958,7 @@ ProcRecordCreateContext(ClientPtr client)
     else
     {
 	RecordDeleteContext((pointer)pContext, pContext->id);
-	err = BadAlloc;
+	return BadAlloc;
     }
 bailout:
     free(pContext);
commit 73de54210446e9eca81b96ea6775ee5ea1a31d75
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Mon Jan 24 08:40:10 2011 +1000

    Input: Fix event size confusion in CheckPassiveGrabsOnWindow
    
    We were just storing a DeviceEvent, but allocating enough space for an
    InternalEvent.
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Cyril Brulebois <kibi at debian.org>

diff --git a/dix/events.c b/dix/events.c
index 4a2815b..bc08f7b 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3565,7 +3565,7 @@ CheckPassiveGrabsOnWindow(
 	    if (grabinfo->sync.state == FROZEN_NO_EVENT)
 	    {
                 if (!grabinfo->sync.event)
-                    grabinfo->sync.event = calloc(1, sizeof(InternalEvent));
+                    grabinfo->sync.event = calloc(1, sizeof(DeviceEvent));
                 *grabinfo->sync.event = *event;
 		grabinfo->sync.state = FROZEN_WITH_EVENT;
             }
commit 706326491011be8cecb9b56c06f7241b7cbd425f
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Tue Jan 18 20:16:36 2011 +0000

    Input: Add DeepestSpriteWin function
    
    Does what it says on the box: returns the deepest child window in a
    given sprite's trace.
    
    Signed-off-by: Daniel Stone <daniel at fooishbar.org>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Keith Packard <keithp at keithp.com>

diff --git a/dix/events.c b/dix/events.c
index 1d513eb..4a2815b 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2182,7 +2182,7 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
 
 static Window FindChildForEvent(SpritePtr pSprite, WindowPtr event)
 {
-    WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1];
+    WindowPtr w = DeepestSpriteWin(pSprite);
     Window child = None;
 
     /* If the search ends up past the root should the child field be
@@ -2625,7 +2625,7 @@ XYToWindow(SpritePtr pSprite, int x, int y)
 	else
 	    pWin = pWin->nextSib;
     }
-    return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
+    return DeepestSpriteWin(pSprite);
 }
 
 /**
diff --git a/include/inputstr.h b/include/inputstr.h
index bd7c78d..bc0accc 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -591,4 +591,14 @@ typedef struct _EventSyncInfo {
 
 extern EventSyncInfoRec syncEvents;
 
+/**
+ * Given a sprite, returns the window at the bottom of the trace (i.e. the
+ * furthest window from the root).
+ */
+static inline WindowPtr DeepestSpriteWin(SpritePtr sprite)
+{
+    assert(sprite->spriteTraceGood > 0);
+    return sprite->spriteTrace[sprite->spriteTraceGood - 1];
+}
+
 #endif /* INPUTSTRUCT_H */
commit 65b54548dce80c8e8ff5ff91fc4f0659e9b2d921
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Tue Jan 18 20:08:09 2011 +0000

    Input: Pass co-ordinates by reference to transformAbsolute
    
    With the upcoming XI 2.1 touch work, the co-ordinate values will need to
    be passed by reference, rather than modified in-place.
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/dix/getevents.c b/dix/getevents.c
index 4267b61..5ffa1df 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1051,23 +1051,14 @@ FreeEventList(EventListPtr list, int num_events)
 }
 
 static void
-transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
+transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y)
 {
-    struct pixman_f_vector p;
-
-    /* p' = M * p in homogeneous coordinates */
-    p.v[0] = (valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) :
-              dev->last.valuators[0]);
-    p.v[1] = (valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) :
-              dev->last.valuators[1]);
-    p.v[2] = 1.0;
+    struct pixman_f_vector p = {.v = {*x, *y, 1}};
 
     pixman_f_transform_point(&dev->transform, &p);
 
-    if (lround(p.v[0]) != dev->last.valuators[0])
-        valuator_mask_set(mask, 0, lround(p.v[0]));
-    if (lround(p.v[1]) != dev->last.valuators[1])
-        valuator_mask_set(mask, 1, lround(p.v[1]));
+    *x = lround(p.v[0]);
+    *y = lround(p.v[1]);
 }
 
 /**
@@ -1158,7 +1149,16 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
             }
         }
 
-        transformAbsolute(pDev, &mask);
+        x = (valuator_mask_isset(&mask, 0) ? valuator_mask_get(&mask, 0) :
+             pDev->last.valuators[0]);
+        y = (valuator_mask_isset(&mask, 1) ? valuator_mask_get(&mask, 1) :
+             pDev->last.valuators[1]);
+        transformAbsolute(pDev, &mask, &x, &y);
+        if (valuator_mask_isset(&mask, 0))
+            valuator_mask_set(&mask, 0, x);
+        if (valuator_mask_isset(&mask, 1))
+            valuator_mask_set(&mask, 1, y);
+
         moveAbsolute(pDev, &x, &y, &mask);
     } else {
         if (flags & POINTER_ACCELERATE) {
commit a14a0c711397ff7ca0220946010300fc1b2a6e67
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Apr 22 22:19:39 2011 -0700

    Move event filter initializer out of the structure itself
    
    When kept in the structure, it causes the entire MAXDEVICES * 128 masks
    to be stored in the data segment and loaded from the file, and also leads
    to worries about later generations inheriting changes across server reset.
    
               text    data     bss     dec     hex filename
    Before:   91837   20528      32  112397   1b70d .libs/events.o
    After:    92277      48   20512  112837   1b8c5 .libs/events.o
    Before: 3013384  122696  163156 3299236  3257a4 Xorg
    After:  3013832  102216  183636 3299684  325964 Xorg
    
    File size before:       4337008 Xorg
    File size after:        4316568 Xorg
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Jamey Sharp <jamey at minilop.net>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/dix/events.c b/dix/events.c
index d70d62f..1d513eb 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -345,8 +345,8 @@ extern int DeviceMotionNotify;
 /**
  * Event masks for each event type.
  *
- * One set of filters for each device, but only the first layer
- * is initialized. The rest is memcpy'd in InitEvents.
+ * One set of filters for each device, initialized by memcpy of
+ * default_filter in InitEvents.
  *
  * Filters are used whether a given event may be delivered to a client,
  * usually in the form of if (window-event-mask & filter); then deliver event.
@@ -355,7 +355,9 @@ extern int DeviceMotionNotify;
  * time a button is pressed, the filter is modified to also contain the
  * matching ButtonXMotion mask.
  */
-static Mask filters[MAXDEVICES][128] = {
+static Mask filters[MAXDEVICES][128];
+
+static const Mask default_filter[128] =
 {
 	NoSuchEvent,		       /* 0 */
 	NoSuchEvent,		       /* 1 */
@@ -392,7 +394,7 @@ static Mask filters[MAXDEVICES][128] = {
 	ColormapChangeMask,	       /* ColormapNotify */
 	CantBeFiltered,		       /* ClientMessage */
 	CantBeFiltered		       /* MappingNotify */
-}};
+};
 
 /**
  * For the given event, return the matching event filter. This filter may then
@@ -4977,12 +4979,9 @@ InitEvents(void)
     inputInfo.off_devices = (DeviceIntPtr)NULL;
     inputInfo.keyboard = (DeviceIntPtr)NULL;
     inputInfo.pointer = (DeviceIntPtr)NULL;
-    /* The mask for pointer motion events may have changed in the last server
-     * generation. See comment above definition of filters. */
-    filters[0][PointerMotionMask] = MotionNotify;
-    for (i = 1; i < MAXDEVICES; i++)
+    for (i = 0; i < MAXDEVICES; i++)
     {
-        memcpy(&filters[i], filters[0], sizeof(filters[0]));
+        memcpy(&filters[i], default_filter, sizeof(default_filter));
     }
 
     syncEvents.replayDev = (DeviceIntPtr)NULL;
commit 8d229c4cf9e5bde78373ef3dd32708817ac97152
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Fri Mar 11 15:43:14 2011 -0800

    Make xorg.conf.example rule compatible with Solaris make
    
    Solaris make won't substitute $< in explicit rules, only implicit ones
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by: Gaetan Nadon <memsize at videotron.ca>

diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 09d875b..f1a759a 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -112,7 +112,7 @@ CONF_SUBSTS =	-e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' \
 		-e 's|DEFAULTFONTPATH|$(COMPILEDDEFAULTFONTPATH)|g'
 
 xorg.conf.example: xorgconf.cpp
-	$(AM_V_GEN)$(SED) $(CONF_SUBSTS) < $< > $@
+	$(AM_V_GEN)$(SED) $(CONF_SUBSTS) < $(srcdir)/xorgconf.cpp > $@
 
 relink:
 	$(AM_V_at)rm -f Xorg && $(MAKE) Xorg
commit c6029246ddcf5ead3884dbf2ab4f57e0c3586e93
Author: Alan Coopersmith <alan.coopersmith at oracle.com>
Date:   Wed Feb 2 17:00:25 2011 -0800

    Move Xinput server API documentation from libXi to doc/xml
    
    Documentation is quite out of date but still fits better here than
    in the client library.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Reviewed-by:  Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/doc/xml/Makefile.am b/doc/xml/Makefile.am
index 6c8178a..b793e7b 100644
--- a/doc/xml/Makefile.am
+++ b/doc/xml/Makefile.am
@@ -22,7 +22,7 @@
 #
 
 SUBDIRS = dtrace
-doc_sources =  Xserver-spec.xml
+doc_sources =  Xserver-spec.xml Xinput.xml
 
 # Developer's documentation is not installed
 if ENABLE_DEVEL_DOCS
diff --git a/doc/xml/Xinput.xml b/doc/xml/Xinput.xml
new file mode 100644
index 0000000..1ae7afe
--- /dev/null
+++ b/doc/xml/Xinput.xml
@@ -0,0 +1,1209 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+                   "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+
+<!-- lifted from troff+ms+XMan by doclifter -->
+<book id="porting">
+
+<bookinfo>
+   <title>X11 Input Extension Porting Document</title>
+   <releaseinfo>X Version 11, Release 6.7</releaseinfo>
+   <authorgroup>
+      <author>
+         <firstname>George</firstname><surname>Sachs</surname>
+         <affiliation><orgname>Hewlett-Packard</orgname></affiliation>
+      </author>
+   </authorgroup>
+   <corpname>X Consortium Standard</corpname>
+   <copyright><year>1989</year><holder>Hewlett-Packard Company</holder></copyright>
+   <copyright><year>1990</year><holder>Hewlett-Packard Company</holder></copyright>
+   <copyright><year>1991</year><holder>Hewlett-Packard Company</holder></copyright>
+
+   <copyright><year>1989</year><holder>X Consortium</holder></copyright>
+   <copyright><year>1990</year><holder>X Consortium</holder></copyright>
+   <copyright><year>1991</year><holder>X Consortium</holder></copyright>
+   <affiliation><orgname>X Consortium</orgname></affiliation>
+   <productnumber>X Version 11, Release 6.7</productnumber>
+
+<legalnotice>
+
+
+<para>
+Permission to use, copy, modify, and distribute this documentation for any purpose and without fee is
+hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
+Hewlett-Packard makes no representations about the suitability for any purpose of the information in this
+document. It is provided "as is" without express or implied warranty. This document is only a draft stan-
+dard of the X Consortium and is therefore subject to change.
+</para>
+
+<para>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</para>
+
+<para>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</para>
+
+<para>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</para>
+
+<para>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</para>
+
+<para>Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium.</para>
+
+<para>X Window System is a trademark of The Open Group.</para>
+</legalnotice>
+
+</bookinfo>
+
+<chapter id="x11_input_extension_porting_document">
+<title>X11 Input Extension Porting Document</title>
+
+<para>
+This document is intended to aid the process of integrating the 
+X11 Input Extension into an X server.
+</para>
+<para>
+<!-- .LP -->
+Most of the functionality provided by the input extension is 
+device- and implementation-independent, and should require no changes.  
+The functionality is implemented by
+routines that typically reside in the server source tree directory 
+extensions/server/xinput.
+This extension includes functions to enable and disable input extension devices,
+select input, grab and focus those device, query and change key 
+and button mappings, and others.  The only input extension requirements 
+for the device-dependent part of X are that the input devices be 
+correctly initialized and input events from those devices be correctly
+generated.  Device-dependent X is responsible for reading input data from 
+the input device hardware and if necessary, reformatting it into X events.
+</para>
+<para>
+<!-- .LP -->
+The process of initializing input extension devices is similar to that used 
+for the core devices, and is described in the following sections.  When
+multiple input devices are attached to X server, the choice of which devices
+to initially use as the core X pointer and keyboard is left 
+implementation-dependent.  It is also up to each implementation to decide
+whether all input devices will be opened by the server during its 
+initialization and kept open for the life of the server.  The alternative is
+to open only the X keyboard and X pointer during server initialization, and
+open other input devices only when requested by a client to do so.  Either
+type of implementation is supported by the input extension.
+</para>
+<para>
+<!-- .LP -->
+Input extension events generated by the X server use the same 32-byte xEvent
+wire event as do core input events.  However, additional information must be
+sent for input extension devices, requiring that multiple xEvents be generated
+each time data is received from an input extension device.  These xEvents are
+combined into a single client XEvent by the input extension library.  A later
+section of this document describes the format and generation of input extension
+events.
+</para>
+<sect1 id="Initializing_Extension_Devices">
+<title>Initializing Extension Devices</title>
+<para>
+<!-- .LP -->
+Extension input devices are initialized in the same manner as the core 
+X input devices.  Device-Independent X provides functions that can be 
+called from DDX to initialize these devices.  Which functions are called
+and when will vary by implementation, and will depend on whether the 
+implementation opens all the input devices available to X when X is initialized,
+or waits until a client requests that a device be opened.
+In the simplest case, DDX will open all input devices as part of its
+initialization, when the InitInput routine is called.
+</para>
+<sect2 id="Summary_of_Calling_Sequence">
+<title>Summary of Calling Sequence</title>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+Device-Independent X       |  Device-Dependent X
+--------------------       |  -------------------             
+                           |                                        
+InitInput -------------->  |  - do device-specific initialization
+                           |                                        
+                           |  - call AddInputDevice  (deviceProc,AutoStart)
+AddInputDevice             |   
+  - creates DeviceIntRec   |
+  - records deviceProc     |
+  - adds new device to     | 
+    list of off_devices.   |
+sets dev->startup=AutoStart|           
+                           |  - call one of:                       
+                           |    - RegisterPointerDevice (X pointer)
+                           |      - processInputProc = ProcessPointerEvents
+                           |    - RegisterKeyboardDevice (X keyboard)
+                           |      - processInputProc = ProcessKeyboardEvents
+                           |    - RegisterOtherDevice  (extension device)
+                           |      - processInputProc = ProcessOtherEvents
+                           |                                        
+                           |                                        
+InitAndStartDevices -----> |  - calls deviceProc with parameters
+                           |    (DEVICE_INIT, AutoStart)
+sets dev->inited = return  |
+  value from deviceProc    |    
+                           |                                        
+                           |  - in deviceProc, do one of:                       
+                           |    - call InitPointerDeviceStruct (X pointer)
+                           |    - call InitKeyboardDeviceStruct (X keybd)
+                           |    - init extension device by calling some of:
+                           |      - InitKeyClassDeviceStruct
+                           |      - InitButtonClassDeviceStruct
+                           |      - InitValuatorClassDeviceStruct
+                           |      - InitValuatorAxisStruct
+                           |      - InitFocusClassDeviceStruct
+                           |      - InitProximityClassDeviceStruct
+                           |      - InitKbdFeedbackClassDeviceStruct
+                           |      - InitPtrFeedbackClassDeviceStruct
+                           |      - InitLedFeedbackClassDeviceStruct
+                           |      - InitStringFeedbackClassDeviceStruct
+                           |      - InitIntegerFeedbackClassDeviceStruct
+                           |      - InitBellFeedbackClassDeviceStruct
+                           |    - init device name and type by:
+                           |      - calling MakeAtom with one of the 
+                           |        predefined names
+                           |      - calling AssignTypeAndName
+                           |                                        
+                           |                                        
+for each device added      |                                        
+    by AddInputDevice,     |                                        
+    InitAndStartDevices    |                                        
+    calls EnableDevice if  |  - EnableDevice calls deviceProc with 
+    dev->startup &         |    (DEVICE_ON, AutoStart)
+    dev->inited            |  
+                           |                                        
+If deviceProc returns      |  - core devices are now enabled, extension
+    Success, EnableDevice  |    devices are now available to be accessed
+    move the device from   |    through the input extension protocol
+    inputInfo.off_devices  |    requests.                           
+    to inputInfo.devices   |                                        
+</literallayout>
+</para>
+</sect2>
+<sect2 id="Initialization_Called_From_InitInput">
+<title>Initialization Called From InitInput</title>
+<para>
+<!-- .LP -->
+InitInput is the first DDX input entry point called during X server startup.
+This routine is responsible for
+device- and implementation- specific initialization, and for calling
+AddInputDevice to create and initialize the DeviceIntRec structure for each
+input device.  AddInputDevice is passed the address of a procedure to be called
+by the DIX routine InitAndStartDevices when input devices are enabled.
+This procedure is expected to perform X initialization for the input device.
+</para>
+<para>
+<!-- .LP -->
+If the device is to be used as the X pointer, DDX should then call
+RegisterPointerDevice, passing the DeviceIntRec pointer,
+to initialize the device as the X pointer.
+</para>
+<para>
+<!-- .LP -->
+If the device is to be used as the X keyboard, DDX should instead call
+RegisterKeyboardDevice to initialize the device as the X keyboard.
+</para>
+<para>
+<!-- .LP -->
+If the device is to be used as an extension device, DDX should instead
+call RegisterOtherDevice, passing the DeviceIntPtr returned by
+AddInputDevice.
+</para>
+<para>
+<!-- .LP -->
+A sample InitInput implementation is shown below.
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+InitInput(argc,argv)
+    {
+    int i, numdevs, ReadInput();
+    DeviceIntPtr dev;
+    LocalDevice localdevs[LOCAL_MAX_DEVS];
+    DeviceProc kbdproc, ptrproc, extproc;
+
+    /**************************************************************
+     * Open the appropriate input devices, determine which are 
+     * available, and choose an X pointer and X keyboard device
+     * in some implementation-dependent manner.
+     ***************************************************************/
+
+    open_input_devices (&numdevs, localdevs);
+
+    /**************************************************************
+     * Register a WakeupHandler to handle input when it is generated.
+     ***************************************************************/
+
+    RegisterBlockAndWakeupHandlers (NoopDDA, ReadInput, NULL);
+
+    /**************************************************************
+     * Register the input devices with DIX.
+     ***************************************************************/
+
+    for (i=0; i<numdevs; i++)
+        {
+        if (localdevs[i].use == IsXKeyboard)
+            {
+            dev = AddInputDevice (kbdproc, TRUE);
+            RegisterKeyboardDevice (dev);
+            }
+        else if (localdevs[i].use == IsXPointer)
+            {
+            dev = AddInputDevice (ptrproc, TRUE);
+            RegisterPointerDevice (dev);
+            }
+        else 
+            {
+            dev = AddInputDevice (extproc, FALSE);
+            RegisterOtherDevice (dev);
+            }
+        if (dev == NULL)
+            FatalError ("Too many input devices.");
+        dev->devicePrivate = (pointer) &localdevs[i];
+        }
+</literallayout>
+</para>
+</sect2>
+<sect2 id="Initialization_Called_From_InitAndStartDevices">
+<title>Initialization Called From InitAndStartDevices</title>
+<para>
+<!-- .LP -->
+After InitInput has returned,
+InitAndStartDevices is the DIX routine that is called to enable input devices. 
+It calls the device control routine that was passed to AddInputDevice,
+with a mode value of DEVICE_INIT.  The action taken by the device control
+routine depends on how the device is to be used.  If the device is to be
+the X pointer, the device control routine should call
+InitPointerDeviceStruct to initialize it.  If the device is to be the
+X keyboard, the device control routine should call
+InitKeyboardDeviceStruct.  Since input extension devices may support various
+combinations of keys, buttons, valuators, and feedbacks,
+each class of input that it supports must be initialized.
+Entry points are defined by DIX to initialize each of the supported classes of
+input, and are described in the following sections.
+</para>
+<para>
+<!-- .LP -->
+A sample device control routine called from InitAndStartDevices is 
+shown below.
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+Bool extproc (dev, mode)
+    DeviceIntPtr dev;
+    int mode;
+    {
+    LocalDevice *localdev = (LocalDevice *) dev->devicePrivate;
+
+    switch (mode)
+        {
+        case DEVICE_INIT:
+            if (strcmp(localdev->name, XI_TABLET) == 0)
+                {
+                /****************************************************
+                 * This device reports proximity, has buttons,
+                 * reports two axes of motion, and can be focused.
+                 * It also supports the same feedbacks as the X pointer
+                 * (acceleration and threshold can be set).
+                 ****************************************************/
+
+                InitButtonClassDeviceStruct (dev, button_count, button_map);
+                InitValuatorClassDeviceStruct (dev, localdev->n_axes,);
+                    motionproc, MOTION_BUF_SIZE, Absolute);
+                for (i=0; i<localdev->n_axes; i++)
+                    InitValuatorAxisStruct (dev, i, min_val, max_val, 
+                        resolution);
+                InitFocusClassDeviceStruct (dev);
+                InitProximityClassDeviceStruct (dev);
+                InitPtrFeedbackClassDeviceStruct (dev, p_controlproc);
+                }
+            else if (strcmp(localdev->name, XI_BUTTONBOX) == 0)
+                {
+                /****************************************************
+                 * This device has keys and LEDs, and can be focused.
+                 ****************************************************/
+
+                InitKeyClassDeviceStruct (dev, syms, modmap);
+                InitFocusClassDeviceStruct (dev);
+                InitLedFeedbackClassDeviceStruct (dev, ledcontrol);
+                }
+            else if (strcmp(localdev->name, XI_KNOBBOX) == 0)
+                {
+                /****************************************************
+                 * This device reports motion.
+                 * It can be focused.
+                 ****************************************************/
+
+                InitValuatorClassDeviceStruct (dev, localdev->n_axes,);
+                    motionproc, MOTION_BUF_SIZE, Absolute);
+                for (i=0; i<localdev->n_axes; i++)
+                    InitValuatorAxisStruct (dev, i, min_val, max_val, 
+                        resolution);
+                InitFocusClassDeviceStruct (dev);
+                }
+            localdev->atom = 
+                MakeAtom(localdev->name, strlen(localdev->name), FALSE);
+            AssignTypeAndName (dev, localdev->atom, localdev->name);
+            break;
+        case DEVICE_ON:
+            AddEnabledDevice (localdev->file_ds);
+            dev->on = TRUE;
+            break;
+        case DEVICE_OFF:
+            dev->on = FALSE;
+            RemoveEnabledDevice (localdev->file_ds);
+            break;
+        case DEVICE_CLOSE:
+            break;
+        }
+    }
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The device control routine is called with a mode value of DEVICE_ON
+by the DIX routine EnableDevice, which is called from InitAndStartDevices.  
+When called with this mode, it should call AddEnabledDevice to cause the 
+server to begin checking for available input from this device.
+</para>
+<para>
+<!-- .LP -->
+>From InitAndStartDevices, EnableDevice is called for all devices that have
+the "inited" and "startup" fields in the DeviceIntRec set to TRUE.  The
+"inited" field is set by InitAndStartDevices to the value returned by
+the deviceproc when called with a mode value of DEVICE_INIT.  The "startup"
+field is set by AddInputDevice to value of the second parameter (autoStart).
+</para>
+<para>
+<!-- .LP -->
+When the server is first initialized, it should only be checking for input
+from the core X keyboard and pointer.  One way to accomplish this is to
+call AddInputDevice for the core X keyboard and pointer with an
+autoStart value equal to TRUE, while calling AddInputDevice for 
+input extension devices with an autoStart value equal to FALSE.  If this is 
+done, EnableDevice will skip all input extension devices during server
+initialization.  In this case,
+the OpenInputDevice routine should set the "startup" field to TRUE
+when called for input extension devices.  This will cause ProcXOpenInputDevice
+to call EnableDevice for those devices when a client first does an
+XOpenDevice request.
+</para>
+</sect2>
+<sect2 id="DIX_Input_Class_Initialization_Routines">
+<title>DIX Input Class Initialization Routines</title>
+<para>
+<!-- .LP -->
+DIX routines are defined to initialize each of the defined input classes.
+The defined classes are:
+<!-- .RS -->
+<!-- .in +5n -->
+</para>
+<itemizedlist>
+  <listitem>
+    <para>
+KeyClass - the device has keys.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+ButtonClass - the device has buttons.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+ValuatorClass - the device reports motion data or positional data.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+Proximitylass - the device reports proximity information.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+FocusClass - the device can be focused.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+FeedbackClass - the device supports some kind of feedback
+<!-- .in -5n -->
+<!-- .RE -->
+    </para>
+  </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+DIX routines are provided to initialize the X pointer and keyboard, as in
+previous releases of X.  During X initialization, InitPointerDeviceStruct 
+is called to initialize the X pointer, and InitKeyboardDeviceStruct is
+called to initialize the X keyboard.  There is no
+corresponding routine for extension input devices, since they do not all
+support the same classes of input.  Instead, DDX is responsible for the 
+initialization of the input classes supported by extension devices.  
+A description of the routines provided by DIX to perform that initialization
+follows.
+</para>
+<sect3 id="InitKeyClassDeviceStruct">
+<title>InitKeyClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a KeyClassRec, and 
+should be called for extension devices that have keys.  It is passed a pointer
+to the device, and pointers to arrays of keysyms and modifiers reported by
+the device.  It returns FALSE if the KeyClassRec could not be allocated,
+or if the maps for the keysyms and and modifiers could not be allocated.
+Its parameters are:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+Bool
+InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers)
+    DeviceIntPtr dev;
+    KeySymsPtr pKeySyms;
+    CARD8 pModifiers[];
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The DIX entry point InitKeyboardDeviceStruct calls this routine for the
+core X keyboard.  It must be called explicitly for extension devices
+that have keys.
+</para>
+</sect3>
+<sect3 id="InitButtonClassDeviceStruct">
+<title>InitButtonClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a ButtonClassRec, and 
+should be called for extension devices that have buttons.  It is passed a 
+pointer to the device, the number of buttons supported, and a map of the 
+reported button codes.  It returns FALSE if the ButtonClassRec could not be 
+allocated.  Its parameters are:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+Bool
+InitButtonClassDeviceStruct(dev, numButtons, map)
+    register DeviceIntPtr dev;
+    int numButtons;
+    CARD8 *map;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The DIX entry point InitPointerDeviceStruct calls this routine for the
+core X pointer.  It must be called explicitly for extension devices that
+have buttons.
+</para>
+</sect3>
+<sect3 id="InitValuatorClassDeviceStruct">
+<title>InitValuatorClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a ValuatorClassRec, and 
+should be called for extension devices that have valuators.  It is passed the
+number of axes of motion reported by the device, the address of the motion
+history procedure for the device, the size of the motion history buffer,
+and the mode (Absolute or Relative) of the device.  It returns FALSE if 
+the ValuatorClassRec could not be allocated.  Its parameters are:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+Bool
+InitValuatorClassDeviceStruct(dev, numAxes, motionProc, numMotionEvents, mode)
+    DeviceIntPtr dev;
+    int (*motionProc)();
+    int numAxes;
+    int numMotionEvents;
+    int mode;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The DIX entry point InitPointerDeviceStruct calls this routine for the
+core X pointer.  It must be called explicitly for extension devices that
+report motion.
+</para>
+</sect3>
+<sect3 id="InitValuatorAxisStruct">
+<title>InitValuatorAxisStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to initialize an XAxisInfoRec, and 
+should be called for core and extension devices that have valuators.  
+The space for the XAxisInfoRec is allocated by 
+the InitValuatorClassDeviceStruct function, but is not initialized.
+</para>
+<para>
+<!-- .LP -->
+InitValuatorAxisStruct should be called once for each axis of motion 
+reported by the device.  Each
+invocation should be passed the axis number (starting with 0), the
+minimum value for that axis, the maximum value for that axis, and the
+resolution of the device in counts per meter.  If the device reports
+relative motion, 0 should be reported as the minimum and maximum values.
+InitValuatorAxisStruct has the following parameters:
+<literallayout class="monospaced">
+InitValuatorAxisStruct(dev, axnum, minval, maxval, resolution)
+    DeviceIntPtr dev;
+    int axnum;
+    int minval;
+    int maxval;
+    int resolution;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+This routine is not called by InitPointerDeviceStruct for the
+core X pointer.  It must be called explicitly for core and extension devices 
+that report motion.
+</para>
+</sect3>
+<sect3 id="InitFocusClassDeviceStruct">
+<title>InitFocusClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a FocusClassRec, and 
+should be called for extension devices that can be focused.  It is passed a
+pointer to the device, and returns FALSE if the allocation fails.
+It has the following parameter:
+<literallayout class="monospaced">
+Bool
+InitFocusClassDeviceStruct(dev)
+    DeviceIntPtr dev;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The DIX entry point InitKeyboardDeviceStruct calls this routine for the
+core X keyboard.  It must be called explicitly for extension devices
+that can be focused.  Whether or not a particular device can be focused
+is left implementation-dependent.
+</para>
+</sect3>
+<sect3 id="InitProximityClassDeviceStruct">
+<title>InitProximityClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a ProximityClassRec, and 
+should be called for extension absolute pointing devices that report proximity.
+It is passed a pointer to the device, and returns FALSE if the allocation fails.
+It has the following parameter:
+<literallayout class="monospaced">
+Bool
+InitProximityClassDeviceStruct(dev)
+    DeviceIntPtr dev;
+</literallayout>
+</para>
+</sect3>
+<sect3 id="Initializing_Feedbacks">
+<title>Initializing Feedbacks</title>
+<para>
+<!-- .LP -->
+</para>
+<sect4 id="InitKbdFeedbackClassDeviceStruct">
+<title>InitKbdFeedbackClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a KbdFeedbackClassRec, and 
+may be called for extension devices that support some or all of the 
+feedbacks that the core keyboard supports.  It is passed a
+pointer to the device, a pointer to the procedure that sounds the bell,
+and a pointer to the device control procedure.
+It returns FALSE if the allocation fails, and has the following parameters:
+<literallayout class="monospaced">
+Bool
+InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc)
+    DeviceIntPtr dev;
+    void (*bellProc)();
+    void (*controlProc)();
+</literallayout>
+The DIX entry point InitKeyboardDeviceStruct calls this routine for the
+core X keyboard.  It must be called explicitly for extension devices
+that have the same feedbacks as a keyboard.  Some feedbacks, such as LEDs and
+bell, can be supported either with a KbdFeedbackClass or with BellFeedbackClass
+and LedFeedbackClass feedbacks.
+</para>
+</sect4>
+<sect4 id="InitPtrFeedbackClassDeviceStruct">
+<title>InitPtrFeedbackClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a PtrFeedbackClassRec, and 
+should be called for extension devices that allow the setting of acceleration
+and threshold.  It is passed a pointer to the device,
+and a pointer to the device control procedure.
+It returns FALSE if the allocation fails, and has the following parameters:
+<literallayout class="monospaced">
+Bool
+InitPtrFeedbackClassDeviceStruct(dev, controlProc)
+    DeviceIntPtr dev;
+    void (*controlProc)();
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The DIX entry point InitPointerDeviceStruct calls this routine for the
+core X pointer.  It must be called explicitly for extension devices
+that support the setting of acceleration and threshold.
+</para>
+</sect4>
+<sect4 id="InitLedFeedbackClassDeviceStruct">
+<title>InitLedFeedbackClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a LedFeedbackClassRec, and 
+should be called for extension devices that have LEDs.
+It is passed a pointer to the device,
+and a pointer to the device control procedure.
+It returns FALSE if the allocation fails, and has the following parameters:
+<literallayout class="monospaced">
+Bool
+InitLedFeedbackClassDeviceStruct(dev, controlProc)
+    DeviceIntPtr dev;
+    void (*controlProc)();
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Up to 32 LEDs per feedback can be supported, and a device may have 
+multiple feedbacks of the same type.
+</para>
+</sect4>
+<sect4 id="InitBellFeedbackClassDeviceStruct">
+<title>InitBellFeedbackClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a BellFeedbackClassRec, 
+and should be called for extension devices that have a bell.
+It is passed a pointer to the device,
+and a pointer to the device control procedure.
+It returns FALSE if the allocation fails, and has the following parameters:
+<literallayout class="monospaced">
+Bool
+InitBellFeedbackClassDeviceStruct(dev, bellProc, controlProc)
+    DeviceIntPtr dev;
+    void (*bellProc)();
+    void (*controlProc)();
+</literallayout>
+</para>
+</sect4>
+<sect4 id="InitStringFeedbackClassDeviceStruct">
+<title>InitStringFeedbackClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize a StringFeedbackClassRec, 
+and should be called for extension devices that have a display upon which a 
+string can be displayed.
+It is passed a pointer to the device,
+and a pointer to the device control procedure.
+It returns FALSE if the allocation fails, and has the following parameters:
+<literallayout class="monospaced">
+Bool
+InitStringFeedbackClassDeviceStruct(dev, controlProc, max_symbols, 
+	num_symbols_supported, symbols)
+    DeviceIntPtr dev;
+    void (*controlProc)();
+    int max_symbols:
+    int num_symbols_supported;
+    KeySym *symbols;
+</literallayout>
+</para>
+</sect4>
+<sect4 id="InitIntegerFeedbackClassDeviceStruct">
+<title>InitIntegerFeedbackClassDeviceStruct</title>
+<para>
+<!-- .LP -->
+This function is provided to allocate and initialize an 
+IntegerFeedbackClassRec, 
+and should be called for extension devices that have a display upon which an
+integer can be displayed.
+It is passed a pointer to the device,
+and a pointer to the device control procedure.
+It returns FALSE if the allocation fails, and has the following parameters:
+<literallayout class="monospaced">
+Bool
+InitIntegerFeedbackClassDeviceStruct(dev, controlProc)
+    DeviceIntPtr dev;
+    void (*controlProc)();
+</literallayout>
+</para>
+</sect4>
+</sect3>
+</sect2>
+<sect2 id="Initializing_The_Device_Name_And_Type">
+<title>Initializing The Device Name And Type</title>
+<para>
+<!-- .LP -->
+The device name and type can be initialized by calling AssignTypeAndName
+with the following parameters:
+<literallayout class="monospaced">
+void
+AssignTypeAndName(dev, type, name)
+    DeviceIntPtr dev;
+    Atom type;
+    char *name;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+This will allocate space for the device name and copy the name that was passed.
+The device type can be obtained by calling MakeAtom with one of the names
+defined for input devices.  MakeAtom has the following parameters:
+<literallayout class="monospaced">
+Atom
+MakeAtom(name, len, makeit)
+    char *name;
+    int len;
+    Bool makeit;
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Since the atom was already made when the input extension was initialized, the
+value of makeit should be FALSE;
+</para>
+</sect2>
+</sect1>
+<sect1 id="Closing_Extension_Devices">
+<title>Closing Extension Devices</title>
+<para>
+<!-- .LP -->
+The DisableDevice entry point is provided by DIX to disable input devices.
+It calls the device control routine for the specified
+device with a mode value of DEVICE_OFF.  The device control routine should
+call RemoveEnabledDevice to stop the server from checking for input from
+that device.
+</para>
+<para>
+<!-- .LP -->
+DisableDevice is not called by any input extension routines.  It can be 
+called from the CloseInputDevice routine, which is called by
+ProcXCloseDevice when a client makes an XCloseDevice request.  If
+DisableDevice is called, it should only be called when the last client
+using the extension device has terminated or called XCloseDevice.
+</para>
+</sect1>
+<sect1 id="Implementation_Dependent_Routines">
+<title>Implementation-Dependent Routines</title>
+<para>
+<!-- .LP -->
+Several input extension protocol requests have 
+implementation-dependent  entry points.  Default routines
+are defined for these entry points and contained in the source
+file extensions/server/xinput/xstubs.c.  Some implementations may
+be able to use the default routines without change.
+The following sections describe each of these routines.
+</para>
+<sect2 id="AddOtherInputDevices">
+<title>AddOtherInputDevices</title>
+<para>
+<!-- .LP -->
+AddOtherInputDevice is called from ProcXListInputDevices as a result of 
+an XListInputDevices protocol request.  It may be needed by
+implementations that do not open extension input devices until requested
+to do so by some client.  These implementations may not initialize
+all devices when the X server starts up, because some of those devices
+may be in use.  Since the XListInputDevices
+function only lists those devices that have been initialized,
+AddOtherInputDevices is called to give DDX a chance to 
+initialize any previously unavailable input devices.
+</para>
+<para>
+<!-- .LP -->
+A sample AddOtherInputDevices routine might look like the following:
+<literallayout class="monospaced">
+void
+AddOtherInputDevices ()
+    {
+    DeviceIntPtr dev;
+    int i;
+
+    for (i=0; i<MAX_DEVICES; i++) 
+        {
+        if (!local_dev[i].initialized && available(local_dev[i]))
+            {
+            dev = (DeviceIntPtr) AddInputDevice (local_dev[i].deviceProc, TRUE);
+            dev->public.devicePrivate = local_dev[i];
+            RegisterOtherDevice (dev);
+            dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
+            }
+        }
+    }
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+The default AddOtherInputDevices routine in xstubs.c does nothing.
+If all input extension devices are initialized when the server 
+starts up, it can be left as a null routine.
+</para>
+</sect2>
+<sect2 id="OpenInputDevice">
+<title>OpenInputDevice</title>
+<para>
+<!-- .LP -->
+Some X server implementations open all input devices when the server
+is initialized and never close them.  Other implementations may open only
+the X pointer and keyboard devices during server initialization,
+and open other input devices only when some client makes an
+XOpenDevice request.  This entry point is for the latter type of 
+implementation.
+</para>
+<para>
+<!-- .LP -->
+If the physical device is not already open, it can be done in this routine.  
+In this case, the server must keep track of the fact that one or more clients 
+have the device open, and physically close it when the last client that has
+it open makes an XCloseDevice request.
+</para>
+<para>
+<!-- .LP -->
+The default implementation is to do nothing (assume all input devices
+are opened during X server initialization and kept open).
+</para>
+</sect2>
+<sect2 id="CloseInputDevice">
+<title>CloseInputDevice</title>
+<para>
+<!-- .LP -->
+Some implementations may close an input device when the last client
+using that device requests that it be closed, or terminates.
+CloseInputDevice is called from ProcXCloseDevice when a client
+makes an XCloseDevice protocol request.
+</para>
+<para>
+<!-- .LP -->
+The default implementation is to do nothing (assume all input devices
+are opened during X server initialization and kept open).
+</para>
+</sect2>
+<sect2 id="SetDeviceMode">
+<title>SetDeviceMode</title>
+<para>
+<!-- .LP -->
+Some implementations support input devices that can report 
+either absolute positional data or relative motion.  The XSetDeviceMode
+protocol request is provided to allow DDX to change the current mode of 
+such a device.
+</para>
+<para>
+<!-- .LP -->
+The default implementation is to always return a BadMatch error.  If the
+implementation does not support any input devices that are capable of 
+reporting both relative motion and absolute position information, the
+default implementation may be left unchanged.
+</para>
+</sect2>
+<sect2 id="SetDeviceValuators">
+<title>SetDeviceValuators</title>
+<para>
+<!-- .LP -->
+Some implementations support input devices that allow their valuators to be 
+set to an initial value.  The XSetDeviceValuators 
+protocol request is provided to allow DDX to set the valuators of
+such a device.
+</para>
+<para>
+<!-- .LP -->
+The default implementation is to always return a BadMatch error.  If the
+implementation does not support any input devices that are allow their
+valuators to be set, the default implementation may be left unchanged.
+</para>
+</sect2>
+<sect2 id="ChangePointerDevice">
+<title>ChangePointerDevice</title>
+<para>
+<!-- .LP -->
+The XChangePointerDevice protocol request is provided to change which device is
+used as the X pointer.  Some implementations may maintain information
+specific to the X pointer in the private data structure pointed to by
+the DeviceIntRec.  ChangePointerDevice is called to allow such 
+implementations to move that information to the new pointer device.
+The current location of the X cursor is an example of the type of 
+information that might be affected.
+</para>
+<para>
+<!-- .LP -->
+The DeviceIntRec structure that describes the X pointer device does not 
+contain a FocusRec.  If the device that has been made into the new X pointer 
+was previously a device that could be focused, ProcXChangePointerDevice will 
+free the FocusRec associated with that device.
+</para>
+<para>
+<!-- .LP -->
+If the server implementation desires to allow clients to focus the old pointer 
+device (which is now accessible through the input extension), it should call
+InitFocusClassDeviceStruct for the old pointer device.
+</para>
+<para>
+<!-- .LP -->
+The XChangePointerDevice protocol request also allows the client
+to choose which axes of the new pointer device are used to move 
+the X cursor in the X- and Y- directions.  If the axes are different
+than the default ones, the server implementation should record that fact.
+</para>
+<para>
+<!-- .LP -->
+If the server implementation supports input devices with valuators that 
+are not allowed to be used as the X pointer, they should be screened out
+by this routine and a  BadDevice error returned.
+</para>
+<para>
+<!-- .LP -->
+The default implementation is to do nothing. 
+</para>
+</sect2>
+<sect2 id="ChangeKeyboardDevice">
+<title>ChangeKeyboardDevice</title>
+<para>
+<!-- .LP -->
+The XChangeKeyboardDevice protocol request is provided to change which device is
+used as the X keyboard.  Some implementations may maintain information
+specific to the X keyboard in the private data structure pointed to by
+the DeviceIntRec.  ChangeKeyboardDevice is called to allow such 
+implementations to move that information to the new keyboard device.
+</para>
+<para>
+<!-- .LP -->
+The X keyboard device can be focused, and the DeviceIntRec that describes
+that device has a FocusRec.  If the device that has been made into the new X 
+keyboard did not previously have a FocusRec, 
+ProcXChangeKeyboardDevice will allocate one for it.
+</para>
+<para>
+<!-- .LP -->
+If the implementation does not want clients to be able to focus the old X 
+keyboard (which has now become available as an input extension device)
+it should call DeleteFocusClassDeviceStruct to free the FocusRec.
+</para>
+<para>
+<!-- .LP -->
+If the implementation supports input devices with keys that are not allowed
+to be used as the X keyboard, they should be checked for here, and a
+BadDevice error returned.
+</para>
+<para>
+<!-- .LP -->
+The default implementation is to do nothing. 
+</para>
+</sect2>
+</sect1>
+<sect1 id="Input_Extension_Events">
+<title>Input Extension Events</title>
+<para>
+<!-- .LP -->
+Events accessed through the input extension are analogous to the core input
+events, but have different event types.  They are of types 
+<function>DeviceKeyPress</function>, <function>DeviceKeyRelease</function>, <function>DeviceButtonPress</function>,
+<function>DeviceButtonRelease</function>, <function>DeviceDeviceMotionNotify</function>,
+<function>DeviceProximityIn</function>, <function>DeviceProximityOut</function>, and <function>DeviceValuator</function>.
+These event types are not constants.  Instead, they are external integers 
+defined by the input extension.  Their actual values will depend on which
+extensions are supported by a server, and the order in which they are
+initialized.
+</para>
+<para>
+<!-- .LP -->
+The data structures that define these
+events are defined in the file <function>extensions/include/XIproto.h</function>.  Other
+input extension constants needed by DDX are defined in the file
+<function>extensions/include/XI.h</function>.
+</para>
+<para>
+<!-- .LP -->
+Some events defined by the input extension contain more information than can
+be contained in the 32-byte xEvent data structure.  To send this information
+to clients, DDX must generate two or more 32-byte wire events.  The following
+sections describe the contents of these events. 
+</para>
+<sect2 id="Device_Key_Events">
+<title>Device Key Events</title>
+<para>
+<!-- .LP -->
+<function>DeviceKeyPresss</function> events contain all the information that is contained in
+a core <function>KeyPress</function> event, and also the following additional information:
+</para>
+<para>
+<!-- .LP -->
+<!-- .RS -->
+<!-- .in +5n -->
+</para>
+<itemizedlist>
+  <listitem>
+    <para>
+deviceid - the identifier of the device that generated the event.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+device_state - the state of any modifiers on the device that generated the event
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+num_valuators - the number of valuators reported in this event.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+first_valuator - the first valuator reported in this event.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+valuator0 through valuator5 - the values of the valuators.
+<!-- .in -5n -->
+<!-- .RE -->
+    </para>
+  </listitem>
+</itemizedlist>
+<para>
+<!-- .LP -->
+In order to pass this information to the input extension library, two 32-byte
+wire events must be generated by DDX.  The first has an event type of 
+<function>DeviceKeyPress</function>, and the second has an event type of \fPDeviceValuator\fP.
+</para>
+<para>
+<!-- .LP -->
+The following code fragment shows how the two wire events could be initialized:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+    extern int DeviceKeyPress;
+    DeviceIntPtr dev;
+    xEvent xE[2];
+    CARD8 id, num_valuators;
+    INT16 x, y, pointerx, pointery;
+    Time timestamp;
+    deviceKeyButtonPointer *xev = (deviceKeyButtonPointer *) xE;
+    deviceValuator *xv;
+
+    xev->type = DeviceKeyPress;                /* defined by input extension */
+    xev->detail = keycode;              /* key pressed on this device */
+    xev->time = timestamp;              /* same as for core events    */
+    xev->rootX = pointerx;              /* x location of core pointer */
+    xev->rootY = pointery;              /* y location of core pointer */
+
+    /******************************************************************/
+    /*                                                                */
+    /* The following field does not exist for core input events.      */
+    /* It contains the device id for the device that generated the    */
+    /* event, and also indicates whether more than one 32-byte wire   */
+    /* event is being sent.                                           */
+    /*                                                                */
+    /******************************************************************/
+
+    xev->deviceid = dev->id | MORE_EVENTS;        /* sending more than 1*/
+
+    /******************************************************************/
+    /* Fields in the second 32-byte wire event:                       */
+    /******************************************************************/
+
+    xv = (deviceValuator *) ++xev;
+    xv->type = DeviceValuator;          /* event type of second event */
+    xv->deviceid = dev->id;             /* id of this device          */
+    xv->num_valuators = 0;              /* no valuators being sent    */
+    xv->device_state  = 0;              /* will be filled in by DIX   */
+</literallayout>
+</para>
+</sect2>
+<sect2 id="Device_Button_Events">
+<title>Device Button Events</title>
+<para>
+<!-- .LP -->
+<function>DeviceButton</function> events contain all the information that is contained in
+a core button event, and also the same additional information that a 
+<function>DeviceKey</function> event contains.
+</para>
+</sect2>
+<sect2 id="Device_Motion_Events">
+<title>Device Motion Events</title>
+<para>
+<!-- .LP -->
+<function>DeviceMotion</function> events contain all the information that is contained in
+a core motion event, and also additional valuator information.  At least
+two wire events are required to contain this information.
+The following code fragment shows how the two wire events could be initialized:
+</para>
+<para>
+<!-- .LP -->
+<literallayout class="monospaced">
+    extern int DeviceMotionNotify;
+    DeviceIntPtr dev;
+    xEvent xE[2];
+    CARD8 id, num_valuators;
+    INT16 x, y, pointerx, pointery;
+    Time timestamp;
+    deviceKeyButtonPointer *xev = (deviceKeyButtonPointer *) xE;
+    deviceValuator *xv;
+
+    xev->type = DeviceMotionNotify;     /* defined by input extension */
+    xev->detail = keycode;              /* key pressed on this device */
+    xev->time = timestamp;              /* same as for core events    */
+    xev->rootX = pointerx;              /* x location of core pointer */
+    xev->rootY = pointery;              /* y location of core pointer */
+
+    /******************************************************************/
+    /*                                                                */
+    /* The following field does not exist for core input events.      */
+    /* It contains the device id for the device that generated the    */
+    /* event, and also indicates whether more than one 32-byte wire   */
+    /* event is being sent.                                           */
+    /*                                                                */
+    /******************************************************************/
+
+    xev->deviceid = dev->id | MORE_EVENTS;        /* sending more than 1*/
+
+    /******************************************************************/
+    /* Fields in the second 32-byte wire event:                       */
+    /******************************************************************/
+
+    xv = (deviceValuator *) ++xev;
+    xv->type = DeviceValuator;          /* event type of second event */
+    xv->deviceid = dev->id;             /* id of this device          */
+    xv->num_valuators = 2;              /* 2 valuators being sent     */
+    xv->first_valuator = 0;             /* first valuator being sent  */
+    xv->device_state  = 0;              /* will be filled in by DIX   */
+    xv->valuator0 = x;                  /* first axis of this device  */
+    xv->valuator1 = y;                  /* second axis of this device */
+</literallayout>
+</para>
+<para>
+<!-- .LP -->
+Up to six axes can be reported in the deviceValuator event.  If the device
+is reporting more than 6 axes, additional pairs of DeviceMotionNotify and
+DeviceValuator events should be sent,  with the first_valuator field
+set correctly.
+</para>
+</sect2>
+<sect2 id="Device_Proximity_Events">
+<title>Device Proximity Events</title>
+<para>
+<!-- .LP -->
+Some input devices that report absolute positional information, such as 
+graphics tablets and touchscreens, may report proximity events.  
+<function>ProximityIn</function>
+events are generated when a pointing device like a stylus, or in the case
+of a touchscreen, the user's finger, comes into close proximity with the
+surface of the input device.  <function>ProximityOut</function> events are generated when
+the stylus or finger leaves the proximity of the input devices surface.
+</para>
+<para>
+<!-- .LP -->
+<function>Proximity</function> events contain almost the same information as button events.
+The event type is <function>ProximityIn</function> or <function>ProximityOut</function>, and there is no
+detail information.
+<!-- .bp -->
+<!-- .\" .TC -->
+
+</para>
+</sect2>
+</sect1>
+</chapter>
+</book>


More information about the Xquartz-changes mailing list