xserver: Branch 'master' - 191 commits

Peter Hutterer whot at kemper.freedesktop.org
Wed Jun 3 22:49:12 PDT 2009


 Xext/geext.c                   |  192 ----
 Xext/geext.h                   |   38 
 Xext/xtest.c                   |    2 
 Xi/Makefile.am                 |   18 
 Xi/chdevcur.c                  |   16 
 Xi/chdevcur.h                  |    7 
 Xi/chdevhier.c                 |  288 +++++--
 Xi/chdevhier.h                 |    6 
 Xi/chgdctl.c                   |    4 
 Xi/exevents.c                  |  785 +++++++++++++-------
 Xi/exglobals.h                 |    2 
 Xi/extgrbdev.c                 |  212 -----
 Xi/extgrbdev.h                 |   43 -
 Xi/extinit.c                   |  370 ++++++---
 Xi/getcptr.c                   |   26 
 Xi/getcptr.h                   |   13 
 Xi/getvers.c                   |   16 
 Xi/grabdev.c                   |   10 
 Xi/grabdevb.c                  |   18 
 Xi/grabdevk.c                  |   17 
 Xi/listdev.c                   |   85 --
 Xi/listdev.h                   |   11 
 Xi/opendev.c                   |    9 
 Xi/querydev.c                  |  444 +++++++++++
 Xi/querydev.h                  |   45 +
 Xi/querydp.c                   |   97 +-
 Xi/querydp.h                   |   15 
 Xi/queryversion.c              |  117 +++
 Xi/queryversion.h              |   40 +
 Xi/selectev.c                  |    6 
 Xi/setcptr.c                   |   18 
 Xi/setcptr.h                   |    4 
 Xi/setmmap.c                   |    1 
 Xi/ungrdev.c                   |    2 
 Xi/ungrdevb.c                  |    1 
 Xi/ungrdevk.c                  |    1 
 Xi/warpdevp.c                  |   14 
 Xi/warpdevp.h                  |    7 
 Xi/xiallowev.c                 |  103 ++
 Xi/xiallowev.h                 |   32 
 Xi/xigrabdev.c                 |  154 +++
 Xi/xigrabdev.h                 |   37 
 Xi/xipassivegrab.c             |  317 ++++++++
 Xi/xipassivegrab.h             |   35 
 Xi/xiproperty.c                |  677 ++++++++++++-----
 Xi/xiproperty.h                |   15 
 Xi/xiselectev.c                |  246 ++++++
 Xi/xiselectev.h                |   35 
 Xi/xiselev.c                   |   79 --
 Xi/xiselev.h                   |   40 -
 Xi/xisetdevfocus.c             |  120 +++
 Xi/xisetdevfocus.h             |   35 
 configure.ac                   |    2 
 dix/devices.c                  |  218 +++--
 dix/enterleave.c               |   50 -
 dix/eventconvert.c             |  287 ++++++-
 dix/events.c                   | 1591 ++++++++++++++++++++++-------------------
 dix/getevents.c                |  187 +++-
 dix/grabs.c                    |  140 ++-
 dix/inpututils.c               |    4 
 dix/ptrveloc.c                 |    6 
 dix/window.c                   |   35 
 hw/xfree86/common/xf86Events.c |    6 
 hw/xfree86/common/xf86Module.h |    2 
 hw/xfree86/common/xf86PM.c     |    4 
 hw/xfree86/common/xf86Xinput.c |   34 
 hw/xfree86/ramdac/xf86Cursor.c |    4 
 include/dix.h                  |   91 +-
 include/dixgrabs.h             |   18 
 include/eventconvert.h         |    4 
 include/events.h               |   77 +
 include/exevents.h             |   61 +
 include/extinit.h              |    5 
 include/input.h                |   75 +
 include/inputstr.h             |   40 -
 include/windowstr.h            |   11 
 include/xkbsrv.h               |    5 
 mi/mi.h                        |    5 
 mi/mieq.c                      |   98 +-
 mi/mipointer.c                 |   21 
 mi/mipointer.h                 |    7 
 mi/misprite.c                  |   18 
 os/osinit.c                    |    4 
 test/Makefile.am               |    1 
 test/input.c                   |  507 ++++++++++++-
 xkb/xkb.c                      |   34 
 xkb/xkbAccessX.c               |   22 
 xkb/xkbActions.c               |    6 
 xkb/xkbEvents.c                |    4 
 xkb/xkbUtils.c                 |   30 
 90 files changed, 5916 insertions(+), 2723 deletions(-)

New commits:
commit 993daf06497c85bb6a1e70592df380503d721dfb
Merge: 2bda50e... e1e8c7d...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jun 4 15:11:36 2009 +1000

    Merge branch 'master' into xi2

commit 2bda50ee14b7873f28081bf0f1bfb7b79a40de43
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jun 4 14:51:32 2009 +1000

    Xi: memset the device name padding to 0.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/querydev.c b/Xi/querydev.c
index d881b76..0d661a9 100644
--- a/Xi/querydev.c
+++ b/Xi/querydev.c
@@ -359,8 +359,9 @@ ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
     info->enabled = dev->enabled;
     total_len = sizeof(xXIDeviceInfo);
 
-    strncpy(any, dev->name, info->name_len);
     len = ((info->name_len + 3)/4) * 4;
+    memset(any, 0, len);
+    strncpy(any, dev->name, info->name_len);
     any += len;
     total_len += len;
 
commit 09266d6cd1bb6e09fe8bcb875c63fb4011c05b55
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jun 4 13:36:29 2009 +1000

    Xi: XIQueryVersion requires major_version of 2 or higher.
    
    Otherwise, a BadValue error is sent.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/queryversion.c b/Xi/queryversion.c
index f96c6f0..385c965 100644
--- a/Xi/queryversion.c
+++ b/Xi/queryversion.c
@@ -62,6 +62,13 @@ ProcXIQueryVersion(ClientPtr client)
     REQUEST(xXIQueryVersionReq);
     REQUEST_SIZE_MATCH(xXIQueryVersionReq);
 
+    /* This request only exists after XI2 */
+    if (stuff->major_version < 2)
+    {
+        client->errorValue = stuff->major_version;
+        return BadValue;
+    }
+
     pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
 
     major = min(XIVersion.major_version, stuff->major_version);
commit 6ea76c550486bd17eb31f43757030fb44bdf1eab
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jun 4 12:55:59 2009 +1000

    Xi: reply with the XI2 version that is supported by both client and server.
    
    XIQueryVersion must return the client's version if the client's version is
    lower than or equal to the server's version, or the server's version
    otherwise.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/queryversion.c b/Xi/queryversion.c
index 3e0644b..f96c6f0 100644
--- a/Xi/queryversion.c
+++ b/Xi/queryversion.c
@@ -43,6 +43,7 @@
 #include "exglobals.h"
 #include "exevents.h"
 #include "queryversion.h"
+#include "misc.h"
 
 extern XExtensionVersion XIVersion; /* defined in getvers.c */
 /**
@@ -56,22 +57,26 @@ ProcXIQueryVersion(ClientPtr client)
 {
     xXIQueryVersionReply rep;
     XIClientPtr pXIClient;
+    int major, minor;
 
     REQUEST(xXIQueryVersionReq);
     REQUEST_SIZE_MATCH(xXIQueryVersionReq);
 
     pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
 
-    pXIClient->major_version = stuff->major_version;
-    pXIClient->minor_version = stuff->minor_version;
+    major = min(XIVersion.major_version, stuff->major_version);
+    minor = min(XIVersion.minor_version, stuff->minor_version);
+
+    pXIClient->major_version = major;
+    pXIClient->minor_version = minor;
 
     memset(&rep, 0, sizeof(xXIQueryVersionReply));
     rep.repType = X_Reply;
     rep.RepType = X_XIQueryVersion;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
-    rep.major_version = XIVersion.major_version;
-    rep.minor_version = XIVersion.minor_version;
+    rep.major_version = major;
+    rep.minor_version = minor;
 
     WriteReplyToClient(client, sizeof(xXIQueryVersionReply), &rep);
 
commit d979f443946011158b6a183582728a6899c33b85
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jun 4 11:40:14 2009 +1000

    test: check from INT_MIN to INT_MAX for core type conversion
    
    ErrorF is link-wrapped to reduce the run-time of the test.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/Makefile.am b/test/Makefile.am
index dbad93b..57a31c2 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -10,6 +10,7 @@ TEST_LDADD=libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) $(GLIB_LIBS)
 
 xkb_LDADD=$(TEST_LDADD)
 input_LDADD=$(TEST_LDADD)
+input_CFLAGS=$(AM_CFLAGS) -Wl,-wrap,ErrorF
 
 libxservertest_la_LIBADD = \
             $(XSERVER_LIBS) \
diff --git a/test/input.c b/test/input.c
index b80e1f5..dcce719 100644
--- a/test/input.c
+++ b/test/input.c
@@ -40,6 +40,10 @@
 
 #include <glib.h>
 
+void __wrap_ErrorF(const char *f, ...)
+{
+}
+
 /**
  * Init a device with axes.
  * Verify values set on the device.
@@ -254,36 +258,36 @@ static void dix_event_to_core_conversion(void)
 {
     DeviceEvent ev;
     xEvent core;
-    int rc;
+    int rc, i;
 
     ev.header   = 0xFF;
     ev.length   = sizeof(DeviceEvent);
 
-    ev.type     = 0;
-    rc = EventToCore((InternalEvent*)&ev, &core);
-    g_assert(rc == BadImplementation);
-
-    ev.type     = 1;
-    rc = EventToCore((InternalEvent*)&ev, &core);
-    g_assert(rc == BadImplementation);
-
-    ev.type     = ET_ProximityOut + 1;
-    rc = EventToCore((InternalEvent*)&ev, &core);
-    g_assert(rc == BadImplementation);
-
-    ev.type     = ET_ProximityIn;
-    rc = EventToCore((InternalEvent*)&ev, &core);
-    g_assert(rc == BadMatch);
-
-    ev.type     = ET_ProximityOut;
-    rc = EventToCore((InternalEvent*)&ev, &core);
-    g_assert(rc == BadMatch);
-
-    dix_event_to_core(ET_KeyPress);
-    dix_event_to_core(ET_KeyRelease);
-    dix_event_to_core(ET_ButtonPress);
-    dix_event_to_core(ET_ButtonRelease);
-    dix_event_to_core(ET_Motion);
+    for (i = INT_MIN; i < INT_MAX; i++)
+    {
+        switch(i)
+        {
+            case ET_KeyPress:
+            case ET_KeyRelease:
+            case ET_ButtonPress:
+            case ET_ButtonRelease:
+            case ET_Motion:
+                dix_event_to_core(i);
+                break;
+            case ET_Raw:
+            case ET_ProximityIn:
+            case ET_ProximityOut:
+                ev.type = i;
+                rc = EventToCore((InternalEvent*)&ev, &core);
+                g_assert(rc == BadMatch);
+                break;
+            default:
+                ev.type = i;
+                rc = EventToCore((InternalEvent*)&ev, &core);
+                g_assert(rc == BadImplementation);
+                break;
+        }
+    }
 }
 
 static void xi2_struct_sizes(void)
commit d8471bc7a19cd248fa3e0845496c86cd9251c013
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jun 4 11:32:15 2009 +1000

    test: adjust event_to_core_conversion test for new ProximityIn/Out behaviour
    
    Both types now return BadMatch.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/input.c b/test/input.c
index 2221c03..b80e1f5 100644
--- a/test/input.c
+++ b/test/input.c
@@ -271,13 +271,19 @@ static void dix_event_to_core_conversion(void)
     rc = EventToCore((InternalEvent*)&ev, &core);
     g_assert(rc == BadImplementation);
 
+    ev.type     = ET_ProximityIn;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    g_assert(rc == BadMatch);
+
+    ev.type     = ET_ProximityOut;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    g_assert(rc == BadMatch);
+
     dix_event_to_core(ET_KeyPress);
     dix_event_to_core(ET_KeyRelease);
     dix_event_to_core(ET_ButtonPress);
     dix_event_to_core(ET_ButtonRelease);
     dix_event_to_core(ET_Motion);
-    dix_event_to_core(ET_ProximityIn);
-    dix_event_to_core(ET_ProximityOut);
 }
 
 static void xi2_struct_sizes(void)
commit 6de67d3206f0a4e307070714564c19efc84da2ec
Merge: af4e658... 7f027d9...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jun 3 16:11:33 2009 +1000

    Merge branch 'master' into xi2

commit af4e658401ecbd2f2cc515b4c5abe5aee361cd64
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jun 3 12:30:49 2009 +1000

    mi: only process master if the SD is still attached.
    
    SDs may be detached during event processing (e.g. if a passive grab
    activates). In this case, the event must not be processed through the master
    device.
    
    Reported-by: Thomas Jaeger
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mieq.c b/mi/mieq.c
index 7ba755c..8ceda43 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -402,7 +402,9 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
             /* process slave first, then master */
             dev->public.processInputProc(event, dev);
 
-            if (master)
+            /* Check for the SD's master in case the device got detached
+             * during event processing */
+            if (master && dev->u.master)
                 master->public.processInputProc(
                         (InternalEvent*)masterEvents->event,
                         master);
commit eb3fe72cbcd10c3953d713e07c321e695194a328
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jun 3 12:19:14 2009 +1000

    dix: set the device state for XI valuator events.
    
    Valuator events need to include the device's state, while other device
    events need to include the state of the core devices.
    
    Reported-by: Thomas Jaeger
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index fa2684c..85ddd61 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -46,6 +46,7 @@
 #include "exglobals.h"
 #include "eventconvert.h"
 #include "querydev.h"
+#include "xkbsrv.h"
 
 
 static int countValuators(DeviceEvent *ev, int *first);
@@ -279,9 +280,19 @@ static int
 getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
 {
     int i;
+    int state = 0;
     int first_valuator, num_valuators;
 
+
     num_valuators = countValuators(ev, &first_valuator);
+    if (num_valuators > 0)
+    {
+        DeviceIntPtr dev = NULL;
+        dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
+        /* State needs to be assembled BEFORE the device is updated. */
+        state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0;
+        state |= (dev && dev->button) ? (dev->button->state) : 0;
+    }
 
     /* FIXME: non-continuous valuator data in internal events*/
     for (i = 0; i < num_valuators; i += 6, xv++) {
@@ -289,6 +300,7 @@ getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
         xv->first_valuator = first_valuator + i;
         xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
         xv->deviceid = ev->deviceid;
+        xv->device_state = state;
         switch (xv->num_valuators) {
         case 6:
             xv->valuator5 = ev->valuators.data[i + 5];
commit 08fd2ae652883393ecff6f3d5177e63408d58472
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jun 3 12:18:17 2009 +1000

    dix: use GetMaster in PickPointer and PickKeyboard.
    
    GetMaster is more reliable than GetPairedDevice, it always returns the
    keyboard/pointer if desired, even if the wrong device was passed in.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 26a9bf1..3a0c3a3 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -5733,8 +5733,7 @@ PickPointer(ClientPtr client)
         GrabPtr grab = it->deviceGrab.grab;
         if (grab && grab->grabtype == GRABTYPE_CORE && SameClient(grab, client))
         {
-            if (!IsPointerDevice(it))
-                it = GetPairedDevice(it);
+            it = GetMaster(it, MASTER_POINTER);
             return it; /* Always return a core grabbed device */
         }
     }
@@ -5763,7 +5762,7 @@ DeviceIntPtr
 PickKeyboard(ClientPtr client)
 {
     DeviceIntPtr ptr = PickPointer(client);
-    DeviceIntPtr kbd = ptr->spriteInfo->paired;
+    DeviceIntPtr kbd = GetMaster(ptr, MASTER_KEYBOARD);
 
     if (!kbd)
     {
commit a1d1dd06f8f91c1d1802f7581a4ba7568b85e69c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jun 3 12:15:32 2009 +1000

    Xi: fix wrong grabtype from ProcXGrabDevice.
    
    86077f0058ce88ee9b3df5d1ab854eeca43 switched from a boolean to a grabtype
    enum. ProcXGrabDevice didn't switch with it. PickPointer during an XI grab
    on a slave device would thus return a wrong (or NULL) device and crash the
    server.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/grabdev.c b/Xi/grabdev.c
index 6827fd1..adcd7e7 100644
--- a/Xi/grabdev.c
+++ b/Xi/grabdev.c
@@ -132,7 +132,7 @@ ProcXGrabDevice(ClientPtr client)
     rc = GrabDevice(client, dev, stuff->other_devices_mode,
                     stuff->this_device_mode, stuff->grabWindow,
 		    stuff->ownerEvents, stuff->time,
-		    &mask, FALSE, None, None,
+		    &mask, GRABTYPE_XI, None, None,
 		    &rep.status);
 
     if (rc != Success)
commit a371a47205fc58a587e1aecaa4a031184481c228
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jun 3 11:47:16 2009 +1000

    dix: EventToCore must return BadMatch for proximity events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index e104ce9..fa2684c 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -76,8 +76,6 @@ EventToCore(InternalEvent *event, xEvent *core)
         case ET_ButtonRelease:
         case ET_KeyPress:
         case ET_KeyRelease:
-        case ET_ProximityIn:
-        case ET_ProximityOut:
             {
                 DeviceEvent *e = (DeviceEvent*)event;
 
@@ -93,6 +91,8 @@ EventToCore(InternalEvent *event, xEvent *core)
                 core->u.keyButtonPointer.state = e->corestate;
             }
             break;
+        case ET_ProximityIn:
+        case ET_ProximityOut:
         case ET_Raw:
             return BadMatch;
         default:
commit 2bd5ea80652358565346071bed829070ddf5de85
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jun 3 10:45:28 2009 +1000

    dix: rework event conversion before delivery.
    
    Let EventToXI, EventToCore and EventToXI2 return BadMatch if there's no
    matching event for this protocol spec.
    Adjust the delivery paths to cope with BadMatch errors (and clean them up on
    the way).
    
    As a side-effect, this fixes server crashes on proximity events for a
    grabbed device.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 5072891..e104ce9 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -93,6 +93,8 @@ EventToCore(InternalEvent *event, xEvent *core)
                 core->u.keyButtonPointer.state = e->corestate;
             }
             break;
+        case ET_Raw:
+            return BadMatch;
         default:
             /* XXX: */
             ErrorF("[dix] EventToCore: Not implemented yet \n");
@@ -107,12 +109,16 @@ EventToCore(InternalEvent *event, xEvent *core)
  * count returns the number of events in xi. If count is 1, and the type of
  * xi is GenericEvent, then xi may be larger than 32 bytes.
  *
- * If the event cannot be converted into an XI event because of protocol
- * restrictions, count is 0 and Success is returned.
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no XI equivalent.
  *
  * @param[in] ev The event to convert into an XI 1 event.
  * @param[out] xi Future memory location for the XI event.
  * @param[out] count Number of elements in xi.
+ *
+ * @return Success or the error code.
  */
 int
 EventToXI(InternalEvent *ev, xEvent **xi, int *count)
@@ -131,7 +137,7 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
         case ET_Raw:
             *count = 0;
             *xi = NULL;
-            return Success;
+            return BadMatch;
     }
 
     ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
@@ -142,8 +148,10 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
  * Convert the given event to the respective XI 2.x event and store it in xi.
  * xi is allocated on demand and must be freed by the caller.
  *
- * If the event cannot be converted into an XI event because of protocol
- * restrictions, xi is NULL and Success is returned.
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no XI2 equivalent.
  *
  * @param[in] ev The event to convert into an XI2 event
  * @param[out] xi Future memory location for the XI2 event.
@@ -170,7 +178,7 @@ EventToXI2(InternalEvent *ev, xEvent **xi)
         case ET_ProximityIn:
         case ET_ProximityOut:
             *xi = NULL;
-            return Success;
+            return BadMatch;
         case ET_DeviceChanged:
             return eventToClassesChanged((DeviceChangedEvent*)ev, xi);
         case ET_Raw:
diff --git a/dix/events.c b/dix/events.c
index f0bb2b9..26a9bf1 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2401,78 +2401,64 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
 
     CHECKEVENT(event);
 
-    /* XXX: In theory, we could pass the internal events through to everything
-     * and only convert just before hitting the wire. We can't do that yet, so
-     * DDE is the last stop for internal events. From here onwards, we deal
-     * with core/XI events.
-     */
-    rc = EventToXI(event, &xE, &count);
-    if (rc != Success)
-    {
-        ErrorF("[dix] %s: XI conversion failed in DDE (%d, %d). Skipping delivery.\n",
-               dev->name, event->any.type, rc);
-        goto unwind;
-    } else if (count > 0)
-    {
-        if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count))
-            goto unwind;
-        /* if count is 0, we might still have XI2 events, don't have XACE for
-         * that yet */
-    }
-
-
     while (pWin)
     {
         if ((mask = EventIsDeliverable(dev, event, pWin)))
         {
+            /* XI2 events first */
             if (mask & XI2_MASK)
             {
                 xEvent *xi2 = NULL;
                 rc = EventToXI2(event, &xi2);
-                if (rc != Success)
+                if (rc == Success)
                 {
+                    /* XXX: XACE */
+                    filter = GetEventFilter(dev, xi2);
+                    FixUpEventFromWindow(dev, xi2, pWin, child, FALSE);
+                    deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1,
+                                                       filter, grab);
+                    xfree(xi2);
+                    if (deliveries > 0)
+                        goto unwind;
+                } else if (rc != BadMatch)
                     ErrorF("[dix] %s: XI2 conversion failed in DDE (%d).\n",
                             dev->name, rc);
-                    goto unwind;
-                }
-                filter = GetEventFilter(dev, xi2);
-                FixUpEventFromWindow(dev, xi2, pWin, child, FALSE);
-                deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1,
-                                                   filter, grab);
-                xfree(xi2);
-                if (deliveries > 0)
-                    goto unwind;
             }
 
-            /* XI events first */
+            /* XI events */
             if (mask & XI_MASK)
             {
-                filter = GetEventFilter(dev, xE);
-                FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
-                deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
-                                                   filter, grab);
-                if (deliveries > 0)
-                    goto unwind;
+                rc = EventToXI(event, &xE, &count);
+                if (rc == Success &&
+                    XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count) == Success)
+                {
+                    filter = GetEventFilter(dev, xE);
+                    FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
+                    deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
+                                                       filter, grab);
+                    if (deliveries > 0)
+                        goto unwind;
+                } else if (rc != BadMatch)
+                    ErrorF("[dix] %s: XI conversion failed in DDE (%d, %d). Skipping delivery.\n",
+                            dev->name, event->any.type, rc);
             }
 
             /* Core event */
             if ((mask & CORE_MASK) && IsMaster(dev) && dev->coreEvents)
             {
                 rc = EventToCore(event, &core);
-                if (rc != Success)
+                if (rc == Success &&
+                    XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success)
                 {
-                    if (rc != BadMatch)
+                    filter = GetEventFilter(dev, &core);
+                    FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
+                    deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
+                            filter, grab);
+                    if (deliveries > 0)
+                        goto unwind;
+                } else if (rc != BadMatch)
                         ErrorF("[dix] %s: Core conversion failed in DDE (%d, %d).\n",
                                 dev->name, event->any.type, rc);
-                    goto unwind;
-                }
-
-                filter = GetEventFilter(dev, &core);
-                FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
-                deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
-                                                   filter, grab);
-                if (deliveries > 0)
-                    goto unwind;
             }
 
             if ((deliveries < 0) || (pWin == stopAt) ||
@@ -3528,10 +3514,11 @@ CheckPassiveGrabsOnWindow(
             if (match & CORE_MATCH)
             {
                 rc = EventToCore((InternalEvent*)event, &core);
-                if (rc != Success && rc != BadMatch)
+                if (rc != Success)
                 {
-                    ErrorF("[dix] %s: core conversion failed in CPGFW "
-                           "(%d, %d).\n", device->name, event->type, rc);
+                    if (rc != BadMatch)
+                        ErrorF("[dix] %s: core conversion failed in CPGFW "
+                                "(%d, %d).\n", device->name, event->type, rc);
                     continue;
                 }
                 xE = &core;
@@ -3541,8 +3528,9 @@ CheckPassiveGrabsOnWindow(
                 rc = EventToXI2((InternalEvent*)event, &xE);
                 if (rc != Success)
                 {
-                    ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
-                           "(%d, %d).\n", device->name, event->type, rc);
+                    if (rc != BadMatch)
+                        ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
+                                "(%d, %d).\n", device->name, event->type, rc);
                     continue;
                 }
                 count = 1;
@@ -3551,11 +3539,11 @@ CheckPassiveGrabsOnWindow(
                 rc = EventToXI((InternalEvent*)event, &xE, &count);
                 if (rc != Success)
                 {
-                    ErrorF("[dix] %s: XI conversion failed in CPGFW "
-                           "(%d, %d).\n", device->name, event->type, rc);
+                    if (rc != BadMatch)
+                        ErrorF("[dix] %s: XI conversion failed in CPGFW "
+                                "(%d, %d).\n", device->name, event->type, rc);
                     continue;
                 }
-
             }
 
 	    (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
@@ -3696,60 +3684,53 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
 	if (DeliverDeviceEvents(window, event, NullGrab, focus, keybd))
 	    return;
     }
-    ptr = GetPairedDevice(keybd);
 
-    rc = EventToXI(event, &xE, &count);
-    if (rc != Success)
-    {
-        ErrorF("[dix] %s: XI conversion failed in DFE (%d, %d). Skipping delivery.\n",
-               keybd->name, event->any.type, rc);
-        goto unwind;
-    } else if (count == 0) /* no XI/Core event for you */
-        return;
+    /* just deliver it to the focus window */
+    ptr = GetPairedDevice(keybd);
 
-    if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count))
-	goto unwind;
 
     rc = EventToXI2(event, &xi2);
-    if (rc != Success)
-    {
-        ErrorF("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n",
-               keybd->name, event->any.type, rc);
-        goto unwind;
-    } else if (xi2)
+    if (rc == Success)
     {
+        /* XXX: XACE */
         int filter = GetEventFilter(keybd, xi2);
-        /* just deliver it to the focus window */
         FixUpEventFromWindow(ptr, xi2, focus, None, FALSE);
         deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1,
                                            filter, NullGrab);
         if (deliveries > 0)
             goto unwind;
-    }
+    } else if (rc != BadMatch)
+        ErrorF("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n",
+               keybd->name, event->any.type, rc);
 
-    /* just deliver it to the focus window */
-    FixUpEventFromWindow(ptr, xE, focus, None, FALSE);
-    deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
-                                       GetEventFilter(keybd, xE),
-                                       NullGrab);
+    rc = EventToXI(event, &xE, &count);
+    if (rc == Success &&
+        XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count) == Success)
+    {
+        FixUpEventFromWindow(ptr, xE, focus, None, FALSE);
+        deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
+                GetEventFilter(keybd, xE),
+                NullGrab);
 
-    if (deliveries > 0)
-        goto unwind;
+        if (deliveries > 0)
+            goto unwind;
+    } else if (rc != BadMatch)
+        ErrorF("[dix] %s: XI conversion failed in DFE (%d, %d). Skipping delivery.\n",
+               keybd->name, event->any.type, rc);
 
     if (sendCore)
     {
         rc = EventToCore(event, &core);
-        if (rc != Success)
+        if (rc == Success &&
+            XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, core, 1) == Success)
         {
+            FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
+            deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
+                                               GetEventFilter(keybd, &core),
+                                               NullGrab);
+        } else if (rc != BadMatch)
             ErrorF("[dix] %s: core conversion failed DFE (%d, %d). Skipping delivery.\n",
                     keybd->name, event->any.type, rc);
-            goto unwind;
-        }
-
-        FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
-        deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
-                                           GetEventFilter(keybd, &core),
-                                           NullGrab);
     }
 
 unwind:
@@ -3823,23 +3804,6 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
          * onwards, we deal with core/XI events.
          */
 
-        rc = EventToXI2(event, &xi2);
-        if (rc != Success)
-        {
-            ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n",
-                    thisDev->name, event->any.type, rc);
-            goto unwind;
-        }
-
-        rc = EventToXI(event, &xi, &count);
-        if (rc != Success)
-        {
-            ErrorF("[dix] %s: XI conversion failed in DGE (%d, %d). Skipping delivery.\n",
-                    thisDev->name, event->any.type, rc);
-            goto unwind;
-        } else if (count == 0) /* no XI/Core event for you */
-            goto unwind;
-
         mask = grab->eventMask;
 
         sendCore = (IsMaster(thisDev) && thisDev->coreEvents);
@@ -3849,68 +3813,77 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
             xEvent core;
 
             rc = EventToCore(event, &core);
-            if (rc != Success && rc != BadMatch)
+            if (rc == Success)
             {
+                FixUpEventFromWindow(thisDev, &core, grab->window,
+                        None, TRUE);
+                if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+                            grab->window, &core, 1) ||
+                        XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+                            grab->window, &core, 1))
+                    deliveries = 1; /* don't send, but pretend we did */
+                else if (!IsInterferingGrab(rClient(grab), thisDev, &core))
+                {
+                    deliveries = TryClientEvents(rClient(grab), thisDev,
+                            &core, 1, mask,
+                            GetEventFilter(thisDev, &core),
+                            grab);
+                }
+            } else if (rc != BadMatch)
                 ErrorF("[dix] DeliverGrabbedEvent. Core conversion failed.\n");
-                goto unwind;
-            }
-
-            FixUpEventFromWindow(thisDev, &core, grab->window,
-                    None, TRUE);
-            if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
-                        grab->window, &core, 1) ||
-                    XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
-                        grab->window, &core, 1))
-                deliveries = 1; /* don't send, but pretend we did */
-            else if (!IsInterferingGrab(rClient(grab), thisDev, &core))
-            {
-                deliveries = TryClientEvents(rClient(grab), thisDev,
-                        &core, 1, mask,
-                        GetEventFilter(thisDev, &core),
-                        grab);
-            }
         }
 
         if (!deliveries)
         {
-            int evtype = ((xGenericEvent*)xi2)->evtype;
-            mask = grab->xi2mask[XIAllDevices][evtype/8] |
-                   grab->xi2mask[XIAllMasterDevices][evtype/8] |
-                   grab->xi2mask[thisDev->id][evtype/8];
-            /* try XI2 event */
-            FixUpEventFromWindow(thisDev, xi2, grab->window, None, TRUE);
-            /* XXX: XACE */
-            deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask,
-                                         GetEventFilter(thisDev, xi2), grab);
+            rc = EventToXI2(event, &xi2);
+            if (rc == Success)
+            {
+                int evtype = ((xGenericEvent*)xi2)->evtype;
+                mask = grab->xi2mask[XIAllDevices][evtype/8] |
+                    grab->xi2mask[XIAllMasterDevices][evtype/8] |
+                    grab->xi2mask[thisDev->id][evtype/8];
+                /* try XI2 event */
+                FixUpEventFromWindow(thisDev, xi2, grab->window, None, TRUE);
+                /* XXX: XACE */
+                deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask,
+                        GetEventFilter(thisDev, xi2), grab);
+            } else if (rc != BadMatch)
+                ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n",
+                        thisDev->name, event->any.type, rc);
         }
 
         if (!deliveries)
         {
-            /* try XI event */
-            if (grabinfo->fromPassiveGrab  &&
-                    grabinfo->implicitGrab)
-                mask = grab->deviceMask;
-            else
-                mask = grab->eventMask;
-
-            FixUpEventFromWindow(thisDev, xi, grab->window,
-                    None, TRUE);
-
-            if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
-                        grab->window, xi, count) ||
-                    XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
-                        grab->window, xi, count))
-                deliveries = 1; /* don't send, but pretend we did */
-            else
+            rc = EventToXI(event, &xi, &count);
+            if (rc == Success)
             {
-                deliveries =
-                    TryClientEvents(rClient(grab), thisDev,
-                            xi, count,
-                            mask,
-                            GetEventFilter(thisDev, xi),
-                            grab);
-            }
-
+                /* try XI event */
+                if (grabinfo->fromPassiveGrab  &&
+                        grabinfo->implicitGrab)
+                    mask = grab->deviceMask;
+                else
+                    mask = grab->eventMask;
+
+                FixUpEventFromWindow(thisDev, xi, grab->window,
+                        None, TRUE);
+
+                if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+                            grab->window, xi, count) ||
+                        XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+                            grab->window, xi, count))
+                    deliveries = 1; /* don't send, but pretend we did */
+                else
+                {
+                    deliveries =
+                        TryClientEvents(rClient(grab), thisDev,
+                                xi, count,
+                                mask,
+                                GetEventFilter(thisDev, xi),
+                                grab);
+                }
+            } else if (rc != BadMatch)
+                ErrorF("[dix] %s: XI conversion failed in DGE (%d, %d). Skipping delivery.\n",
+                        thisDev->name, event->any.type, rc);
         }
 
         if (deliveries && (event->any.type == ET_Motion))
@@ -3944,7 +3917,6 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 	}
     }
 
-unwind:
     if (xi)
         xfree(xi);
     if (xi2)
commit fc8cfc3a055d8af4ac809799c71f3db0d5246433
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jun 2 16:53:41 2009 +1000

    dix: ensure EventIsDeliverable has inputMasks set at all times.
    
    For proximity events, the XI2 type is 0 and inputMasks never got set in the
    preceding condition. As a result, proximity events got never delivered.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index d73487a..f0bb2b9 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2326,7 +2326,7 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
     int rc = 0;
     int filter = 0;
     int type;
-    OtherInputMasks *inputMasks = NULL;
+    OtherInputMasks *inputMasks = wOtherInputMasks(win);
     xEvent ev;
 
     /* XXX: this makes me gag */
@@ -2335,7 +2335,7 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
     ((xGenericEvent*)&ev)->extension = IReqCode;
     ((xGenericEvent*)&ev)->evtype = type;
     filter = GetEventFilter(dev, &ev);
-    if (type && (inputMasks = wOtherInputMasks(win)) &&
+    if (type && inputMasks &&
         ((inputMasks->xi2mask[XIAllDevices][type/8] & filter) ||
          ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && IsMaster(dev)) ||
          (inputMasks->xi2mask[dev->id][type/8] & filter)))
commit ef9f851057a0ae214be02cb919f1e6634cead20b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jun 2 16:38:32 2009 +1000

    dix: protect against floating slaves in DeviceFocusEvent.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index b19c8e2..fbcf6e3 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1231,7 +1231,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     DeviceIntPtr mouse;
     int btlen, len, i;
 
-    mouse = (IsMaster(dev) || dev->u.master) ? GetPairedDevice(dev) : NULL;
+    mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev;
 
     /* XI 2 event */
     btlen = (mouse->button) ? (mouse->button->numButtons + 7)/8 : 0;
commit b40289c8766c5e7543b7288009b4d965f57c04ce
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jun 2 16:22:58 2009 +1000

    xkb: allow pointer events to pass through for floating SDs without a key class.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index 88d5d90..f0f7578 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -687,21 +687,28 @@ void
 ProcessPointerEvent(	InternalEvent   *ev,
 			DeviceIntPtr    mouse)
 {
-DeviceIntPtr	dev = GetPairedDevice(mouse);
-XkbSrvInfoPtr	xkbi = dev->key->xkbInfo;
+DeviceIntPtr	dev;
+XkbSrvInfoPtr	xkbi = NULL;
 unsigned 	changed = 0;
 ProcessInputProc backupproc;
 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(mouse);
 DeviceEvent     *event = (DeviceEvent*)ev;
 
-    xkbi->shiftKeyCount = 0;
-    xkbi->lastPtrEventTime= event->time;
+    dev = (IsMaster(mouse) || mouse->u.master) ? GetMaster(mouse, MASTER_KEYBOARD) : mouse;
+
+    if (dev && dev->key)
+    {
+	xkbi = dev->key->xkbInfo;
+	xkbi->shiftKeyCount = 0;
+	xkbi->lastPtrEventTime= event->time;
+    }
 
     if (event->type == ET_ButtonPress) {
 	    changed |= XkbPointerButtonMask;
     }
     else if (event->type == ET_ButtonRelease) {
-	xkbi->lockedPtrButtons&= ~(1 << (event->detail.key & 0x7));
+	if (xkbi)
+	    xkbi->lockedPtrButtons&= ~(1 << (event->detail.key & 0x7));
 	changed |= XkbPointerButtonMask;
     }
 
@@ -726,6 +733,9 @@ DeviceEvent     *event = (DeviceEvent*)ev;
     COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr,
 				     backupproc, xkbUnwrapProc);
 
+    if (!xkbi)
+	return;
+
     xkbi->state.ptr_buttons = (mouse->button) ? mouse->button->state : 0;
     
     /* clear any latched modifiers */
commit 38df8351b36195070232b42a6d3369a9a08df8df
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 17:09:03 2009 +1000

    test: add grab matching tests.

diff --git a/test/input.c b/test/input.c
index 2f7bc71..2221c03 100644
--- a/test/input.c
+++ b/test/input.c
@@ -36,6 +36,7 @@
 #include "inputstr.h"
 #include "eventconvert.h"
 #include "exevents.h"
+#include "dixgrabs.h"
 
 #include <glib.h>
 
@@ -309,6 +310,367 @@ static void xi2_struct_sizes(void)
 }
 
 
+static void dix_grab_matching(void)
+{
+    DeviceIntRec xi_all_devices, xi_all_master_devices, dev1, dev2;
+    GrabRec a, b;
+    BOOL rc;
+
+    memset(&a, 0, sizeof(a));
+    memset(&b, 0, sizeof(b));
+
+    /* different grabtypes must fail */
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_XI2;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI2;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_CORE;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    /* XI2 grabs for different devices must fail, regardless of ignoreDevice
+     * XI2 grabs for master devices must fail against a slave */
+    memset(&xi_all_devices, 0, sizeof(DeviceIntRec));
+    memset(&xi_all_master_devices, 0, sizeof(DeviceIntRec));
+    memset(&dev1, 0, sizeof(DeviceIntRec));
+    memset(&dev2, 0, sizeof(DeviceIntRec));
+
+    xi_all_devices.id = XIAllDevices;
+    xi_all_master_devices.id = XIAllMasterDevices;
+    dev1.id = 10;
+    dev1.type = SLAVE;
+    dev2.id = 11;
+    dev2.type = SLAVE;
+
+    inputInfo.all_devices = &xi_all_devices;
+    inputInfo.all_master_devices = &xi_all_master_devices;
+    a.grabtype = GRABTYPE_XI2;
+    b.grabtype = GRABTYPE_XI2;
+    a.device = &dev1;
+    b.device = &dev2;
+
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+
+    a.device = &dev2;
+    b.device = &dev1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&a, &b, TRUE);
+    g_assert(rc == FALSE);
+
+    a.device = inputInfo.all_master_devices;
+    b.device = &dev1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&a, &b, TRUE);
+    g_assert(rc == FALSE);
+
+    a.device = &dev1;
+    b.device = inputInfo.all_master_devices;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&a, &b, TRUE);
+    g_assert(rc == FALSE);
+
+    /* ignoreDevice FALSE must fail for different devices for CORE and XI */
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    a.device = &dev1;
+    b.device = &dev2;
+    a.modifierDevice = &dev1;
+    b.modifierDevice = &dev1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    a.device = &dev1;
+    b.device = &dev2;
+    a.modifierDevice = &dev1;
+    b.modifierDevice = &dev1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+
+    /* ignoreDevice FALSE must fail for different modifier devices for CORE
+     * and XI */
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    a.device = &dev1;
+    b.device = &dev1;
+    a.modifierDevice = &dev1;
+    b.modifierDevice = &dev2;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    a.device = &dev1;
+    b.device = &dev1;
+    a.modifierDevice = &dev1;
+    b.modifierDevice = &dev2;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+
+    /* different event type must fail */
+    a.grabtype = GRABTYPE_XI2;
+    b.grabtype = GRABTYPE_XI2;
+    a.device = &dev1;
+    b.device = &dev1;
+    a.modifierDevice = &dev1;
+    b.modifierDevice = &dev1;
+    a.type = XI_KeyPress;
+    b.type = XI_KeyRelease;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&a, &b, TRUE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    a.device = &dev1;
+    b.device = &dev1;
+    a.modifierDevice = &dev1;
+    b.modifierDevice = &dev1;
+    a.type = XI_KeyPress;
+    b.type = XI_KeyRelease;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&a, &b, TRUE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    a.device = &dev1;
+    b.device = &dev1;
+    a.modifierDevice = &dev1;
+    b.modifierDevice = &dev1;
+    a.type = XI_KeyPress;
+    b.type = XI_KeyRelease;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&a, &b, TRUE);
+    g_assert(rc == FALSE);
+
+    /* different modifiers must fail */
+    a.grabtype = GRABTYPE_XI2;
+    b.grabtype = GRABTYPE_XI2;
+    a.device = &dev1;
+    b.device = &dev1;
+    a.modifierDevice = &dev1;
+    b.modifierDevice = &dev1;
+    a.type = XI_KeyPress;
+    b.type = XI_KeyPress;
+    a.modifiersDetail.exact = 1;
+    b.modifiersDetail.exact = 2;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    /* AnyModifier must fail for XI2 */
+    a.grabtype = GRABTYPE_XI2;
+    b.grabtype = GRABTYPE_XI2;
+    a.modifiersDetail.exact = AnyModifier;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    /* XIAnyModifier must fail for CORE and XI */
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    a.modifiersDetail.exact = XIAnyModifier;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    a.modifiersDetail.exact = XIAnyModifier;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    /* different detail must fail */
+    a.grabtype = GRABTYPE_XI2;
+    b.grabtype = GRABTYPE_XI2;
+    a.detail.exact = 1;
+    b.detail.exact = 2;
+    a.modifiersDetail.exact = 1;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    /* detail of AnyModifier must fail */
+    a.grabtype = GRABTYPE_XI2;
+    b.grabtype = GRABTYPE_XI2;
+    a.detail.exact = AnyModifier;
+    b.detail.exact = 1;
+    a.modifiersDetail.exact = 1;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    /* detail of XIAnyModifier must fail */
+    a.grabtype = GRABTYPE_XI2;
+    b.grabtype = GRABTYPE_XI2;
+    a.detail.exact = XIAnyModifier;
+    b.detail.exact = 1;
+    a.modifiersDetail.exact = 1;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == FALSE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == FALSE);
+
+    /* XIAnyModifier or AnyModifer must succeed */
+    a.grabtype = GRABTYPE_XI2;
+    b.grabtype = GRABTYPE_XI2;
+    a.detail.exact = 1;
+    b.detail.exact = 1;
+    a.modifiersDetail.exact = XIAnyModifier;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == TRUE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == TRUE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    a.detail.exact = 1;
+    b.detail.exact = 1;
+    a.modifiersDetail.exact = AnyModifier;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == TRUE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == TRUE);
+
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    a.detail.exact = 1;
+    b.detail.exact = 1;
+    a.modifiersDetail.exact = AnyModifier;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == TRUE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == TRUE);
+
+    /* AnyKey or XIAnyKeysym must succeed */
+    a.grabtype = GRABTYPE_XI2;
+    b.grabtype = GRABTYPE_XI2;
+    a.detail.exact = XIAnyKeysym;
+    b.detail.exact = 1;
+    a.modifiersDetail.exact = 1;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == TRUE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == TRUE);
+
+    a.grabtype = GRABTYPE_CORE;
+    b.grabtype = GRABTYPE_CORE;
+    a.detail.exact = AnyKey;
+    b.detail.exact = 1;
+    a.modifiersDetail.exact = 1;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == TRUE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == TRUE);
+
+    a.grabtype = GRABTYPE_XI;
+    b.grabtype = GRABTYPE_XI;
+    a.detail.exact = AnyKey;
+    b.detail.exact = 1;
+    a.modifiersDetail.exact = 1;
+    b.modifiersDetail.exact = 1;
+    rc = GrabMatchesSecond(&a, &b, FALSE);
+    g_assert(rc == TRUE);
+    rc = GrabMatchesSecond(&b, &a, FALSE);
+    g_assert(rc == TRUE);
+}
+
 int main(int argc, char** argv)
 {
     g_test_init(&argc, &argv,NULL);
@@ -318,6 +680,7 @@ int main(int argc, char** argv)
     g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
     g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
     g_test_add_func("/dix/input/xi2-struct-sizes", xi2_struct_sizes);
+    g_test_add_func("/dix/input/grab_matching", dix_grab_matching);
 
     return g_test_run();
 }
commit a66686a83edd6093ed540414dda2b8700e4696fe
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 15:37:53 2009 +1000

    input: add support for XIAllDevices and XIAllMasterDevices passive grabs.
    
    These grabs are suported through two fake devices inputInfo.all_devices and
    inputInfo.all_master_devices. These devices are not part of the device list
    and are only initialised for their device id, nothing else.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index 7e5111d..23704b1 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -188,6 +188,9 @@ static struct dev_type
 CARD8 event_base[numInputClasses];
 XExtEventInfo EventInfo[32];
 
+static DeviceIntRec xi_all_devices;
+static DeviceIntRec xi_all_master_devices;
+
 /**
  * Dispatch vector. Functions defined in here will be called when the matching
  * request arrives.
@@ -1215,6 +1218,17 @@ XInputExtensionInit(void)
 	EventSwapVector[DevicePresenceNotify] = SEventIDispatch;
 
 	GERegisterExtension(IReqCode, XI2EventSwap);
+
+
+	memset(&xi_all_devices, 0, sizeof(xi_all_devices));
+	memset(&xi_all_master_devices, 0, sizeof(xi_all_master_devices));
+	xi_all_devices.id = XIAllDevices;
+	xi_all_devices.name = "XIAllDevices";
+	xi_all_master_devices.id = XIAllMasterDevices;
+	xi_all_master_devices.name = "XIAllMasterDevices";
+
+	inputInfo.all_devices = &xi_all_devices;
+	inputInfo.all_master_devices = &xi_all_master_devices;
     } else {
 	FatalError("IExtensionInit: AddExtensions failed\n");
     }
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index fab3335..0c74544 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -90,9 +90,16 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     REQUEST(xXIPassiveGrabDeviceReq);
     REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
 
-    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
-    if (ret != Success)
-	return ret;
+    if (stuff->deviceid == XIAllDevices)
+        dev = inputInfo.all_devices;
+    else if (stuff->deviceid == XIAllMasterDevices)
+        dev = inputInfo.all_master_devices;
+    else
+    {
+        ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
+        if (ret != Success)
+            return ret;
+    }
 
     if (stuff->grab_type != XIGrabtypeButton &&
         stuff->grab_type != XIGrabtypeKeysym &&
diff --git a/dix/events.c b/dix/events.c
index 13ef5b8..d73487a 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -248,6 +248,18 @@ static Bool CheckPassiveGrabsOnWindow(WindowPtr pWin,
  *
  *     inputInfo.numDevices
  *     Total number of devices.
+ *
+ *     inputInfo.all_devices
+ *     Virtual device used for XIAllDevices passive grabs. This device is
+ *     not part of the inputInfo.devices list and mostly unset except for
+ *     the deviceid. It exists because passivegrabs need a valid device
+ *     reference.
+ *
+ *     inputInfo.all_master_devices
+ *     Virtual device used for XIAllMasterDevices passive grabs. This device
+ *     is not part of the inputInfo.devices list and mostly unset except for
+ *     the deviceid. It exists because passivegrabs need a valid device
+ *     reference.
  */
 InputInfo inputInfo;
 
diff --git a/dix/grabs.c b/dix/grabs.c
index 02f63f9..cc77477 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -267,7 +267,25 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice)
     if (pFirstGrab->grabtype != pSecondGrab->grabtype)
         return FALSE;
 
-    if (!ignoreDevice &&
+    if (pFirstGrab->grabtype == GRABTYPE_XI2)
+    {
+        if (pFirstGrab->device == inputInfo.all_devices ||
+            pSecondGrab->device == inputInfo.all_devices)
+        {
+            /* do nothing */
+        } else if (pFirstGrab->device == inputInfo.all_master_devices)
+        {
+            if (pSecondGrab->device != inputInfo.all_master_devices &&
+                !IsMaster(pSecondGrab->device))
+                return FALSE;
+        } else if (pSecondGrab->device == inputInfo.all_master_devices)
+        {
+            if (pFirstGrab->device != inputInfo.all_master_devices &&
+                !IsMaster(pFirstGrab->device))
+                return FALSE;
+        } else if (pSecondGrab->device != pFirstGrab->device)
+            return FALSE;
+    } else if (!ignoreDevice &&
             ((pFirstGrab->device != pSecondGrab->device) ||
              (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice)))
             return FALSE;
diff --git a/include/inputstr.h b/include/inputstr.h
index 7f6e6ca..f233034 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -528,6 +528,8 @@ typedef struct {
     DeviceIntPtr	off_devices;	/* all devices turned off */
     DeviceIntPtr	keyboard;	/* the main one for the server */
     DeviceIntPtr	pointer;
+    DeviceIntPtr	all_devices;
+    DeviceIntPtr	all_master_devices;
 } InputInfo;
 
 extern _X_EXPORT InputInfo inputInfo;
commit f00cf7675164bb984ef310412f9e09582813adb1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jun 2 10:23:21 2009 +1000

    dix: get the current MD keyboard for the grab modifier state.
    
    A passive XI2 grab always uses the paired master device as a modifier
    device. After issuing a passive grab, the slave may be reattached to a
    different master and hence the modifier device may change.

diff --git a/dix/events.c b/dix/events.c
index 52c5e6c..13ef5b8 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3417,7 +3417,17 @@ CheckPassiveGrabsOnWindow(
                 gdev = GetPairedDevice(device);
             else
                 gdev = device;
+        } else if (grab->grabtype == GRABTYPE_XI2)
+        {
+            /* if the device is an attached slave device, gdev must be the
+             * attached master keyboard. Since the slave may have been
+             * reattached after the grab, the modifier device may not be the
+             * same. */
+            if (!IsMaster(grab->device) && device->u.master)
+                gdev = GetMaster(device, MASTER_KEYBOARD);
         }
+
+
         if (gdev && gdev->key)
             xkbi= gdev->key->xkbInfo;
 	tempGrab.modifierDevice = grab->modifierDevice;
commit 1cd7ed75d903b5b0ea4e1070d2c26f4f931bdec7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 17:14:06 2009 +1000

    dix: float slave devices during passive grabs.
    
    Exception - implicit passive grabs.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index cf9ee60..52c5e6c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1506,7 +1506,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
     Bool isPassive = autoGrab & ~ImplicitGrabMask;
 
     /* slave devices need to float for the duration of the grab. */
-    if (!isPassive && !IsMaster(mouse))
+    if (!(autoGrab & ImplicitGrabMask) && !IsMaster(mouse))
         DetachFromMaster(mouse);
 
     if (grab->confineTo)
@@ -1543,7 +1543,8 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
 {
     GrabPtr grab = mouse->deviceGrab.grab;
     DeviceIntPtr dev;
-    Bool  wasPassive= mouse->deviceGrab.fromPassiveGrab;
+    Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab &&
+                        mouse->deviceGrab.implicitGrab);
 
     mouse->valuator->motionHintWindow = NullWindow;
     mouse->deviceGrab.grab = NullGrab;
@@ -1563,7 +1564,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
     if (grab->cursor)
 	FreeCursor(grab->cursor, (Cursor)0);
 
-    if (!wasPassive)
+    if (!wasImplicit)
         ReattachToOldMaster(mouse);
 
     ComputeFreezes();
@@ -1581,7 +1582,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass
     WindowPtr oldWin;
 
     /* slave devices need to float for the duration of the grab. */
-    if (!passive && !IsMaster(keybd))
+    if (!(passive & ImplicitGrabMask) && !IsMaster(keybd))
         DetachFromMaster(keybd);
 
     if (grabinfo->grab)
@@ -1616,7 +1617,8 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
     DeviceIntPtr dev;
     WindowPtr focusWin = keybd->focus ? keybd->focus->win
                                            : keybd->spriteInfo->sprite->win;
-    Bool wasPassive = keybd->deviceGrab.fromPassiveGrab;
+    Bool wasImplicit = (keybd->deviceGrab.fromPassiveGrab &&
+                        keybd->deviceGrab.implicitGrab);
 
     if (focusWin == FollowKeyboardWin)
 	focusWin = inputInfo.keyboard->focus->win;
@@ -1633,7 +1635,7 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
     }
     DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
 
-    if (!wasPassive)
+    if (!wasImplicit)
         ReattachToOldMaster(keybd);
 
     ComputeFreezes();
commit f56ad22e8fabdca6d9fd1e408a539696e30599fc
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Jun 2 15:07:53 2009 +1000

    dix: rework temporary slave detachment.
    
    Rework addresses two issues:
    - storing the master device's pointer is a bad idea, we need to store the ID
      of the device in case it disappears during the grab.
    - restoring the old master did not actually reattach the device. Fixed now.

diff --git a/dix/events.c b/dix/events.c
index 8a340b6..cf9ee60 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1435,44 +1435,47 @@ CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
 /* Only ever used if a grab is called on an attached slave device. */
 static int GrabPrivateKeyIndex;
 static DevPrivateKey GrabPrivateKey = &GrabPrivateKeyIndex;
-typedef struct _GrabMemoryRec {
-    DeviceIntPtr oldmaster;
-} GrabMemoryRec, *GrabMemoryPtr;
 
 /**
  * Save the device's master device in the devPrivates. This needs to be done
  * if a client directly grabs a slave device that is attached to a master. For
  * the duration of the grab, the device is detached, ungrabbing re-attaches it
  * though.
+ *
+ * We store the ID of the master device only in case the master disappears
+ * while the device has a grab.
  */
 static void
-SaveOldMaster(DeviceIntPtr dev)
+DetachFromMaster(DeviceIntPtr dev)
 {
-    GrabMemoryPtr gm;
-
-    if (!(gm = xalloc(sizeof(GrabMemoryRec))))
-    {
-        ErrorF("[dix] Cannot allocate grab private. Grab not "
-                "possible on device.\n");
+    int id;
+    if (!dev->u.master)
         return;
-    }
-    gm->oldmaster = dev->u.master;
-    dixSetPrivate(&dev->devPrivates, GrabPrivateKey, gm);
+
+    id = dev->u.master->id;
+
+    dixSetPrivate(&dev->devPrivates, GrabPrivateKey, (void *)id);
+    AttachDevice(NULL, dev, NULL);
 }
 
 static void
-RestoreOldMaster(DeviceIntPtr dev)
+ReattachToOldMaster(DeviceIntPtr dev)
 {
-    GrabMemoryPtr gm;
+    int id;
+    void *p;
+    DeviceIntPtr master = NULL;
 
     if (IsMaster(dev))
         return;
 
-    gm = (GrabMemoryPtr)dixLookupPrivate(&dev->devPrivates, GrabPrivateKey);
-    if (gm)
+
+    p = dixLookupPrivate(&dev->devPrivates, GrabPrivateKey);
+    id = (int)p; /* silence gcc warnings */
+    dixLookupDevice(&master, id, serverClient, DixUseAccess);
+
+    if (master)
     {
-        dev->u.master = gm->oldmaster;
-        xfree(gm);
+        AttachDevice(serverClient, dev, master);
         dixSetPrivate(&dev->devPrivates, GrabPrivateKey, NULL);
     }
 }
@@ -1504,10 +1507,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
 
     /* slave devices need to float for the duration of the grab. */
     if (!isPassive && !IsMaster(mouse))
-    {
-        SaveOldMaster(mouse);
-        AttachDevice(NULL, mouse, NULL);
-    }
+        DetachFromMaster(mouse);
 
     if (grab->confineTo)
     {
@@ -1564,7 +1564,7 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
 	FreeCursor(grab->cursor, (Cursor)0);
 
     if (!wasPassive)
-        RestoreOldMaster(mouse);
+        ReattachToOldMaster(mouse);
 
     ComputeFreezes();
 }
@@ -1582,10 +1582,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass
 
     /* slave devices need to float for the duration of the grab. */
     if (!passive && !IsMaster(keybd))
-    {
-        SaveOldMaster(keybd);
-        AttachDevice(NULL, keybd, NULL);
-    }
+        DetachFromMaster(keybd);
 
     if (grabinfo->grab)
 	oldWin = grabinfo->grab->window;
@@ -1637,7 +1634,7 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
     DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
 
     if (!wasPassive)
-        RestoreOldMaster(keybd);
+        ReattachToOldMaster(keybd);
 
     ComputeFreezes();
 }
commit b3e4810a283d369e1a2c6c3288177fe79fd1e9d6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 16:22:51 2009 +1000

    dix: move grab device assignment into GRABTYPE_CORE block.
    
    grab->type is the device type and XI2 types overlap with core events (being
    less than GenericEvent). Thus, for passive grabs the grab device would be
    overwritten with whatever device was activating it.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 3fd1dab..8a340b6 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3461,19 +3461,6 @@ CheckPassiveGrabsOnWindow(
             event->corestate &= 0x1f00;
             event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
             grabinfo = &device->deviceGrab;
-            /* 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);
-            }
-
             /* 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
@@ -3484,6 +3471,20 @@ CheckPassiveGrabsOnWindow(
             {
                 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);
+                }
+
                 for (other = inputInfo.devices; other; other = other->next)
                 {
                     GrabPtr othergrab = other->deviceGrab.grab;
commit 18ae48670859d05788776e164c65985e3b35a723
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 16:06:52 2009 +1000

    dix: don't try to activate a passive grab on top of an active one.
    
    If we already have an active grab on the device, don't attempt to activate
    another one.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 229e67d..3fd1dab 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3393,6 +3393,9 @@ CheckPassiveGrabsOnWindow(
 #define XI2_MATCH        0x4
     int match = 0;
 
+    if (device->deviceGrab.grab)
+        return FALSE;
+
     if (!grab)
 	return FALSE;
     /* Fill out the grab details, but leave the type for later before
commit ff1d6244eba8367a8d50601ca393e951c60c94b6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 12:14:52 2009 +1000

    input: add support for XIAnyModifier in passive XI2 grabs.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 5aca521..b19c8e2 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1406,10 +1406,13 @@ CheckGrabValues(ClientPtr client, GrabParameters* param)
 	client->errorValue = param->other_devices_mode;
 	return BadValue;
     }
-    if ((param->modifiers != AnyModifier) && (param->modifiers & ~AllModifiersMask)) {
+
+    if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) &&
+        (param->modifiers & ~AllModifiersMask)) {
 	client->errorValue = param->modifiers;
 	return BadValue;
     }
+
     if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) {
 	client->errorValue = param->ownerEvents;
 	return BadValue;
diff --git a/dix/grabs.c b/dix/grabs.c
index cd90526..02f63f9 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -229,9 +229,12 @@ DetailSupersedesSecond(
 static Bool
 GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
 {
+    unsigned int any_modifier = (pFirstGrab->grabtype == GRABTYPE_XI2) ?
+                                (unsigned int)XIAnyModifier :
+                                (unsigned int)AnyModifier;
     if (!DetailSupersedesSecond(pFirstGrab->modifiersDetail,
 				pSecondGrab->modifiersDetail, 
-				(unsigned int)AnyModifier))
+				any_modifier))
 	return FALSE;
 
     if (DetailSupersedesSecond(pFirstGrab->detail,
@@ -257,6 +260,9 @@ GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
 Bool
 GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice)
 {
+    unsigned int any_modifier = (pFirstGrab->grabtype == GRABTYPE_XI2) ?
+                                (unsigned int)XIAnyModifier :
+                                (unsigned int)AnyModifier;
 
     if (pFirstGrab->grabtype != pSecondGrab->grabtype)
         return FALSE;
@@ -278,7 +284,7 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice)
 	&& 
 	DetailSupersedesSecond(pFirstGrab->modifiersDetail,
 			       pSecondGrab->modifiersDetail,
-			       (unsigned int)AnyModifier))
+			       any_modifier))
 	return TRUE;
 
     if (DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail,
@@ -286,7 +292,7 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice)
 	&& 
 	DetailSupersedesSecond(pSecondGrab->modifiersDetail,
 			       pFirstGrab->modifiersDetail,
-			       (unsigned int)AnyModifier))
+			       any_modifier))
 	return TRUE;
 
     return FALSE;
@@ -295,6 +301,10 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice)
 static Bool
 GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
 {
+    unsigned int any_modifier = (pFirstGrab->grabtype == GRABTYPE_XI2) ?
+                                (unsigned int)XIAnyModifier :
+                                (unsigned int)AnyModifier;
+
     if (pFirstGrab->grabtype != pSecondGrab->grabtype)
         return FALSE;
 
@@ -311,12 +321,13 @@ GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
                                (unsigned int)AnyKey)))
         return FALSE;
 
+
     if (!(DetailSupersedesSecond(pFirstGrab->modifiersDetail, 
                                pSecondGrab->modifiersDetail, 
-                               (unsigned int)AnyModifier) &&
+                               any_modifier) &&
         DetailSupersedesSecond(pSecondGrab->modifiersDetail,
                                pFirstGrab->modifiersDetail,
-                               (unsigned int)AnyModifier)))
+                               any_modifier)))
         return FALSE;
 
     return TRUE;
@@ -391,6 +402,8 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
     Mask ***updates, **details;
     int i, ndels, nadds, nups;
     Bool ok;
+    unsigned int any_modifier;
+    unsigned int any_key;
 
 #define UPDATE(mask,exact) \
 	if (!(details[nups] = DeleteDetailFromMask(mask, exact))) \
@@ -415,6 +428,11 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
 	if (deletes) xfree(deletes);
 	return FALSE;
     }
+
+    any_modifier = (pMinuendGrab->grabtype == GRABTYPE_XI2) ?
+                   (unsigned int)XIAnyModifier : (unsigned int)AnyModifier;
+    any_key = (pMinuendGrab->grabtype == GRABTYPE_XI2) ?
+                   (unsigned int)XIAnyKeysym : (unsigned int)AnyKey;
     ndels = nadds = nups = 0;
     ok = TRUE;
     for (grab = wPassiveGrabs(pMinuendGrab->window);
@@ -429,19 +447,19 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
 	{
 	    deletes[ndels++] = grab;
 	}
-	else if ((grab->detail.exact == AnyKey)
-		 && (grab->modifiersDetail.exact != AnyModifier))
+	else if ((grab->detail.exact == any_key)
+		 && (grab->modifiersDetail.exact != any_modifier))
 	{
 	    UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
 	}
-	else if ((grab->modifiersDetail.exact == AnyModifier) 
-		 && (grab->detail.exact != AnyKey))
+	else if ((grab->modifiersDetail.exact == any_modifier)
+		 && (grab->detail.exact != any_key))
 	{
 	    UPDATE(grab->modifiersDetail.pMask,
 		   pMinuendGrab->modifiersDetail.exact);
 	}
-	else if ((pMinuendGrab->detail.exact != AnyKey)
-		 && (pMinuendGrab->modifiersDetail.exact != AnyModifier))
+	else if ((pMinuendGrab->detail.exact != any_key)
+		 && (pMinuendGrab->modifiersDetail.exact != any_modifier))
 	{
 	    GrabPtr pNewGrab;
             GrabParameters param;
@@ -452,7 +470,7 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
             param.ownerEvents = grab->ownerEvents;
             param.this_device_mode = grab->keyboardMode;
             param.other_devices_mode = grab->pointerMode;
-            param.modifiers = AnyModifier;
+            param.modifiers = any_modifier;
 
 	    pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device,
 				  grab->modifierDevice, grab->window,
@@ -479,7 +497,7 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
 	    else
 		adds[nadds++] = pNewGrab;
 	}   
-	else if (pMinuendGrab->detail.exact == AnyKey)
+	else if (pMinuendGrab->detail.exact == any_key)
 	{
 	    UPDATE(grab->modifiersDetail.pMask,
 		   pMinuendGrab->modifiersDetail.exact);
commit 80ea32ad4f1440d068e18db65830f45498703b09
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 12:06:55 2009 +1000

    dix: switch grab checking from unsigned shorts to unsigned ints
    
    XIAnyModifier is outside of the unsigned short range.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/grabs.c b/dix/grabs.c
index 0df8ad1..cd90526 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -154,7 +154,7 @@ DeletePassiveGrab(pointer value, XID id)
 }
 
 static Mask *
-DeleteDetailFromMask(Mask *pDetailMask, unsigned short detail)
+DeleteDetailFromMask(Mask *pDetailMask, unsigned int detail)
 {
     Mask *mask;
     int i;
@@ -177,7 +177,7 @@ static Bool
 IsInGrabMask(
     DetailRec firstDetail,
     DetailRec secondDetail,
-    unsigned short exception)
+    unsigned int exception)
 {
     if (firstDetail.exact == exception)
     {
@@ -197,9 +197,9 @@ IsInGrabMask(
 
 static Bool 
 IdenticalExactDetails(
-    unsigned short firstExact,
-    unsigned short secondExact,
-    unsigned short exception)
+    unsigned int firstExact,
+    unsigned int secondExact,
+    unsigned int exception)
 {
     if ((firstExact == exception) || (secondExact == exception))
 	return FALSE;
@@ -214,7 +214,7 @@ static Bool
 DetailSupersedesSecond(
     DetailRec firstDetail,
     DetailRec secondDetail,
-    unsigned short exception)
+    unsigned int exception)
 {
     if (IsInGrabMask(firstDetail, secondDetail, exception))
 	return TRUE;
@@ -231,11 +231,11 @@ GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
 {
     if (!DetailSupersedesSecond(pFirstGrab->modifiersDetail,
 				pSecondGrab->modifiersDetail, 
-				(unsigned short)AnyModifier))
+				(unsigned int)AnyModifier))
 	return FALSE;
 
     if (DetailSupersedesSecond(pFirstGrab->detail,
-			       pSecondGrab->detail, (unsigned short)AnyKey))
+			       pSecondGrab->detail, (unsigned int)AnyKey))
 	return TRUE;
  
     return FALSE;
@@ -274,19 +274,19 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice)
 	return TRUE;
  
     if (DetailSupersedesSecond(pSecondGrab->detail, pFirstGrab->detail,
-			       (unsigned short)AnyKey) 
+			       (unsigned int)AnyKey)
 	&& 
 	DetailSupersedesSecond(pFirstGrab->modifiersDetail,
 			       pSecondGrab->modifiersDetail,
-			       (unsigned short)AnyModifier))
+			       (unsigned int)AnyModifier))
 	return TRUE;
 
     if (DetailSupersedesSecond(pFirstGrab->detail, pSecondGrab->detail,
-			       (unsigned short)AnyKey)
+			       (unsigned int)AnyKey)
 	&& 
 	DetailSupersedesSecond(pSecondGrab->modifiersDetail,
 			       pFirstGrab->modifiersDetail,
-			       (unsigned short)AnyModifier))
+			       (unsigned int)AnyModifier))
 	return TRUE;
 
     return FALSE;
@@ -305,18 +305,18 @@ GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
 
     if (!(DetailSupersedesSecond(pFirstGrab->detail, 
                                pSecondGrab->detail, 
-                               (unsigned short)AnyKey) && 
+                               (unsigned int)AnyKey) &&
         DetailSupersedesSecond(pSecondGrab->detail,
                                pFirstGrab->detail,
-                               (unsigned short)AnyKey)))
+                               (unsigned int)AnyKey)))
         return FALSE;
 
     if (!(DetailSupersedesSecond(pFirstGrab->modifiersDetail, 
                                pSecondGrab->modifiersDetail, 
-                               (unsigned short)AnyModifier) && 
+                               (unsigned int)AnyModifier) &&
         DetailSupersedesSecond(pSecondGrab->modifiersDetail,
                                pFirstGrab->modifiersDetail,
-                               (unsigned short)AnyModifier)))
+                               (unsigned int)AnyModifier)))
         return FALSE;
 
     return TRUE;
diff --git a/include/inputstr.h b/include/inputstr.h
index 5c74ba3..7f6e6ca 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -146,7 +146,7 @@ typedef struct _OtherInputMasks {
                                            3 buttons. */
 
 typedef struct _DetailRec {		/* Grab details may be bit masks */
-    unsigned short      exact;
+    unsigned int        exact;
     Mask                *pMask;
 } DetailRec;
 
commit 080b0331b3d1de1bab5ecdc9df175b287616e358
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 13:33:29 2009 +1000

    input: Add grabtype to GrabParameters.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 781f4b8..5aca521 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1388,6 +1388,14 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
 int
 CheckGrabValues(ClientPtr client, GrabParameters* param)
 {
+    if (param->grabtype != GRABTYPE_CORE &&
+        param->grabtype != GRABTYPE_XI &&
+        param->grabtype != GRABTYPE_XI2)
+    {
+        ErrorF("[Xi] grabtype is invalid. This is a bug.\n");
+        return BadImplementation;
+    }
+
     if ((param->this_device_mode != GrabModeSync) &&
 	(param->this_device_mode != GrabModeAsync)) {
 	client->errorValue = param->this_device_mode;
diff --git a/Xi/grabdevb.c b/Xi/grabdevb.c
index 0d1eb63..7cd5cc4 100644
--- a/Xi/grabdevb.c
+++ b/Xi/grabdevb.c
@@ -139,6 +139,7 @@ ProcXGrabDeviceButton(ClientPtr client)
 	return ret;
 
     memset(&param, 0, sizeof(param));
+    param.grabtype = GRABTYPE_XI;
     param.ownerEvents = stuff->ownerEvents;
     param.this_device_mode = stuff->this_device_mode;
     param.other_devices_mode = stuff->other_devices_mode;
diff --git a/Xi/grabdevk.c b/Xi/grabdevk.c
index 96e2e62..5ffecd2 100644
--- a/Xi/grabdevk.c
+++ b/Xi/grabdevk.c
@@ -137,6 +137,7 @@ ProcXGrabDeviceKey(ClientPtr client)
 
 
     memset(&param, 0, sizeof(param));
+    param.grabtype = GRABTYPE_XI;
     param.ownerEvents = stuff->ownerEvents;
     param.this_device_mode = stuff->this_device_mode;
     param.other_devices_mode = stuff->other_devices_mode;
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index fa76a77..fab3335 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -130,6 +130,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     rep.num_modifiers = 0;
 
     memset(&param, 0, sizeof(param));
+    param.grabtype = GRABTYPE_XI2;
     param.ownerEvents = stuff->owner_events;
     param.this_device_mode = stuff->grab_mode;
     param.other_devices_mode = stuff->paired_device_mode;
diff --git a/dix/events.c b/dix/events.c
index b5b0521..229e67d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -5172,6 +5172,7 @@ ProcGrabKey(ClientPtr client)
     REQUEST_SIZE_MATCH(xGrabKeyReq);
 
     memset(&param, 0, sizeof(param));
+    param.grabtype = GRABTYPE_CORE;
     param.ownerEvents = stuff->ownerEvents;
     param.this_device_mode = stuff->keyboardMode;
     param.other_devices_mode = stuff->pointerMode;
@@ -5287,6 +5288,7 @@ ProcGrabButton(ClientPtr client)
 	return rc;
 
     memset(&param, 0, sizeof(param));
+    param.grabtype = GRABTYPE_CORE;
     param.ownerEvents = stuff->ownerEvents;
     param.this_device_mode = stuff->keyboardMode;
     param.other_devices_mode = stuff->pointerMode;
diff --git a/include/exevents.h b/include/exevents.h
index 5878413..80eaa76 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -44,6 +44,7 @@ typedef struct _XIClientRec {
 
 
 typedef struct _GrabParameters {
+    int                 grabtype;               /* GRABTYPE_CORE, etc. */
     unsigned int        ownerEvents;
     unsigned int        this_device_mode;
     unsigned int        other_devices_mode;
diff --git a/test/input.c b/test/input.c
index 466d187..2f7bc71 100644
--- a/test/input.c
+++ b/test/input.c
@@ -86,6 +86,7 @@ static void dix_check_grab_values(void)
 
     memset(&client, 0, sizeof(client));
 
+    param.grabtype = GRABTYPE_CORE;
     param.this_device_mode = GrabModeSync;
     param.other_devices_mode = GrabModeSync;
     param.modifiers = AnyModifier;
commit bee02a154145c0e4ed97980f7857dc27a96b1be8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 10:49:22 2009 +1000

    dix: ensure implicit passive grabs have the xi2mask zeroed.
    
    This fixes XI2 enter/leave events being sent to non-xi2 clients.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 78663ea..b5b0521 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2065,6 +2065,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
 	GrabRec tempGrab;
         OtherInputMasks *inputMasks;
 
+        memset(&tempGrab, 0, sizeof(GrabRec));
         tempGrab.next = NULL;
 	tempGrab.device = pDev;
 	tempGrab.resource = client->clientAsMask;
commit cc71dfb4f5cf6113053951070dec9556e941aa24
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 13:19:30 2009 +1000

    test: Add GetSelectedEvents request to struct size tests.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/input.c b/test/input.c
index 013056f..466d187 100644
--- a/test/input.c
+++ b/test/input.c
@@ -303,6 +303,7 @@ static void xi2_struct_sizes(void)
     compare(xXIChangePropertyReq);
     compare(xXIDeletePropertyReq);
     compare(xXIGetPropertyReq);
+    compare(xXIGetSelectedEventsReq);
 #undef compare
 }
 
commit de5c5b1db083a9c1d23e1461b54ca646c5a5c445
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 1 13:21:36 2009 +1000

    test: fix compile error introduced with the removal of isMaster.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/input.c b/test/input.c
index cca1291..013056f 100644
--- a/test/input.c
+++ b/test/input.c
@@ -54,7 +54,7 @@ static void dix_init_valuators(void)
 
 
     memset(&dev, 0, sizeof(DeviceIntRec));
-    dev.isMaster = TRUE; /* claim it's a master to stop ptracccel */
+    dev.type = MASTER_POINTER; /* claim it's a master to stop ptracccel */
 
     g_assert(InitValuatorClassDeviceStruct(NULL, 0, 0, 0) == FALSE);
     g_assert(InitValuatorClassDeviceStruct(&dev, num_axes, 0, Absolute));
commit 0f47203a9a690498c18b1c04e2ef5deed23a0e3e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 29 14:18:37 2009 +1000

    dix: Set the implicit passive grab flag for keyboards too.
    
    Extension devices have ActivateKeyboardGrab as their grab activation
    function, hence we need to ensure the implicit passive grab flag is set
    accordingly in the grab for further event delivery.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index da9107e..78663ea 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1605,6 +1605,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass
     grabinfo->activeGrab = *grab;
     grabinfo->grab = &grabinfo->activeGrab;
     grabinfo->fromPassiveGrab = passive;
+    grabinfo->implicitGrab = passive & ImplicitGrabMask;
     CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
 }
 
commit 75c73ddbfc9236bb80a3709d467674c4a1018fa3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 29 14:01:21 2009 +1000

    dix: fix broken XI event delivery during grabs.
    
    If an implicit passive grab is active, the XI event mask is in
    grab->deviceMask. Otherwise, for explicit grabs, the XI event mask is in
    grab->eventMask.
    
    Reported-by: Thomas Jaeger
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 39cf295..da9107e 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3863,6 +3863,9 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
             if (grabinfo->fromPassiveGrab  &&
                     grabinfo->implicitGrab)
                 mask = grab->deviceMask;
+            else
+                mask = grab->eventMask;
+
             FixUpEventFromWindow(thisDev, xi, grab->window,
                     None, TRUE);
 
commit 29ec14625111a8ae600d245ccbf905f059074d7c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 29 13:26:22 2009 +1000

    Xi: passively grabbing slave devices must be possible.
    
    There's use-cases where this is useful, so take the check out preventing
    that.
    
    Reported-by: Thomas Jaeger
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index a8807bd..fa76a77 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -110,14 +110,6 @@ ProcXIPassiveGrabDevice(ClientPtr client)
         return BadValue;
     }
 
-    /* Can't grab for modifiers on an attached slave device */
-    if (!IsMaster(dev))
-    {
-        if (!dev->u.master)
-            stuff->paired_device_mode = GrabModeAsync;
-        else if (dev->u.master && stuff->num_modifiers)
-            return BadDevice;
-    }
     if ((stuff->mask_len * 4) > XI_LASTEVENT)
     {
         unsigned char *bits = (unsigned char*)&stuff[1];
commit 235cf5713a8fe535c439628cce9ea5b42432acb1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 29 12:09:06 2009 +1000

    dix: init inputMasks to NULL to avoid random value dereference.
    
    If the XI2 type is 0 (e.g. proximity events), inputMasks is never set and
    may not be NULL.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 0d0c419..39cf295 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2313,7 +2313,7 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
     int rc = 0;
     int filter = 0;
     int type;
-    OtherInputMasks *inputMasks;
+    OtherInputMasks *inputMasks = NULL;
     xEvent ev;
 
     /* XXX: this makes me gag */
commit 68d86adbe8d84099812c37a04098f2ab5ccc45a4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 29 12:03:07 2009 +1000

    dix: GetProximityEvents doesn't need extra events for valuators.
    
    With internal events, we only have one event for all the data, no need to
    calculate for extra events.
    
    Reported-by: Thomas Jaeger
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 9c7ac44..83aedbe 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1138,12 +1138,6 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
     if ((pDev->valuator->mode & 1) == Relative)
         num_valuators = 0;
 
-    if (num_valuators) {
-        if ((((num_valuators - 1) / 6) + 1) > MAX_VALUATOR_EVENTS)
-            num_valuators = MAX_VALUATOR_EVENTS * 6;
-        num_events += ((num_valuators - 1) / 6) + 1;
-    }
-
     /* You fail. */
     if (first_valuator < 0 ||
         (num_valuators + first_valuator) > pDev->valuator->numAxes)
commit d7aef3f663f4b5d861799f8615dcd301d5ce2906
Merge: a25f248... e08c6a0...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 28 17:20:58 2009 +1000

    Merge branch 'master' into xi2
    
    Conflicts:
    	Xext/geext.c
    	Xi/chdevcur.c
    	Xi/extgrbdev.c
    	Xi/xiproperty.c
    	configure.ac
    	dix/ptrveloc.c
    	hw/xfree86/common/xf86Config.c
    	mi/mipointer.h
    	test/input.c
    	xkb/xkb.c

diff --cc dix/events.c
index 503a58d,fd93376..0d0c419
--- a/dix/events.c
+++ b/dix/events.c
@@@ -5425,11 -5180,10 +5425,11 @@@ DeleteWindowFromAnyEvents(WindowPtr pWi
                                     to None
                                   */
  #ifdef NOTDEF
-                                 || clients[CLIENT_ID(parent->drawable.id)]->clientGone
+ 				 || wClient(parent)->clientGone
  #endif
                                  );
 -                        DoFocusEvents(keybd, pWin, parent, focusEventMode);
 +                        if (!ActivateFocusInGrab(keybd, pWin, parent))
 +                            DoFocusEvents(keybd, pWin, parent, focusEventMode);
                          focus->win = parent;
                          focus->revert = RevertToNone;
                          break;
diff --cc xkb/xkb.c
index 51feaa0,ec46238..e4e84ce
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@@ -3432,7 -3432,8 +3432,8 @@@ ProcXkbSetNamedIndicator(ClientPtr clie
          DeviceIntPtr other;
          for (other = inputInfo.devices; other; other = other->next)
          {
 -            if ((other != dev) && !other->isMaster && (other->u.master == dev) &&
 +            if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
+                 (other->kbdfeed || other->leds) &&
                  (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
              {
                  rc = _XkbCreateIndicatorMap(other, stuff->indicator,
@@@ -3455,7 -3456,8 +3456,8 @@@
          DeviceIntPtr other;
          for (other = inputInfo.devices; other; other = other->next)
          {
 -            if ((other != dev) && !other->isMaster && (other->u.master == dev) &&
 +            if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
+                 (other->kbdfeed || other->leds) &&
                  (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
              {
                  _XkbSetNamedIndicator(client, other, stuff);
commit a25f248fc3bd0375d91ca8a44320200d445ecfbb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 27 15:47:12 2009 +1000

    Xi: Send Enter or Leave events with XIPassive(Un)grabNotify
    
    If a passive enter or focus in grab activates, send additional enter or
    focus events with mode XIPassiveGrabNotify to the grabbing client.
    Likewise, if the grab deactivates, send additional leave or focus out
    events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 91a3461..781f4b8 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1872,7 +1872,7 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
 
 	switch (dev->focus->revert) {
 	case RevertToNone:
-	    if (!ActivateFocusInGrab(dev, NoneWin))
+	    if (!ActivateFocusInGrab(dev, pWin, NoneWin))
 		DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
 	    dev->focus->win = NoneWin;
 	    dev->focus->traceGood = 0;
@@ -1884,13 +1884,13 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
 		dev->focus->traceGood--;
 	    }
 	    while (!parent->realized);
-	    if (!ActivateFocusInGrab(dev, parent))
+	    if (!ActivateFocusInGrab(dev, pWin, parent))
 		DoFocusEvents(dev, pWin, parent, focusEventMode);
 	    dev->focus->win = parent;
 	    dev->focus->revert = RevertToNone;
 	    break;
 	case RevertToPointerRoot:
-	    if (!ActivateFocusInGrab(dev, PointerRootWin))
+	    if (!ActivateFocusInGrab(dev, pWin, PointerRootWin))
 		DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
 	    dev->focus->win = PointerRootWin;
 	    dev->focus->traceGood = 0;
@@ -1901,12 +1901,12 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
                 if (!kbd || (kbd == dev && kbd != inputInfo.keyboard))
                     kbd = inputInfo.keyboard;
 	    if (kbd->focus->win) {
-		if (!ActivateFocusInGrab(dev, kbd->focus->win))
+		if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win))
 		    DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
 		dev->focus->win = FollowKeyboardWin;
 		dev->focus->traceGood = 0;
 	    } else {
-                if (!ActivateFocusInGrab(dev, NoneWin))
+                if (!ActivateFocusInGrab(dev, pWin, NoneWin))
                     DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
 		dev->focus->win = NoneWin;
 		dev->focus->traceGood = 0;
diff --git a/dix/enterleave.c b/dix/enterleave.c
index eadcc45..d7f5f58 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -609,7 +609,8 @@ DoEnterLeaveEvents(DeviceIntPtr pDev,
     if (fromWin == toWin)
 	return;
 
-    CoreEnterLeaveEvents(pDev, fromWin, toWin, mode);
+    if (mode != XINotifyPassiveGrab && mode != XINotifyPassiveUngrab)
+        CoreEnterLeaveEvents(pDev, fromWin, toWin, mode);
     DeviceEnterLeaveEvents(pDev, fromWin, toWin, mode);
 }
 
diff --git a/dix/events.c b/dix/events.c
index 5d22016..503a58d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2635,8 +2635,9 @@ XYToWindow(DeviceIntPtr pDev, int x, int y)
  * @returns TRUE if the device has been grabbed, or FALSE otherwise.
  */
 BOOL
-ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win)
+ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
 {
+    BOOL rc = FALSE;
     DeviceEvent event;
 
     if (dev->deviceGrab.grab &&
@@ -2646,6 +2647,7 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win)
         if (dev->deviceGrab.grab->window == win ||
             IsParent(dev->deviceGrab.grab->window, win))
             return FALSE;
+        DoEnterLeaveEvents(dev, old, win, XINotifyPassiveUngrab);
         (*dev->deviceGrab.DeactivateGrab)(dev);
     }
 
@@ -2660,18 +2662,22 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win)
     event.deviceid = dev->id;
     event.sourceid = dev->id;
     event.detail.button = 0;
-    return CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
+    rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
+    if (rc)
+        DoEnterLeaveEvents(dev, old, win, XINotifyPassiveUngrab);
+    return rc;
 }
 
 /**
- * Ungrab a currently Enter grabbed device and grab the deice for the given
+ * Ungrab a currently Enter grabbed device and grab the device for the given
  * window.
  *
  * @returns TRUE if the device has been grabbed, or FALSE otherwise.
  */
 static BOOL
-ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win)
+ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
 {
+    BOOL rc = FALSE;
     DeviceEvent event;
 
     if (dev->deviceGrab.grab &&
@@ -2681,6 +2687,7 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win)
         if (dev->deviceGrab.grab->window == win ||
             IsParent(dev->deviceGrab.grab->window, win))
             return FALSE;
+        DoEnterLeaveEvents(dev, old, win, XINotifyPassiveUngrab);
         (*dev->deviceGrab.DeactivateGrab)(dev);
     }
 
@@ -2692,7 +2699,11 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win)
     event.deviceid = dev->id;
     event.sourceid = dev->id;
     event.detail.button = 0;
-    return CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
+    rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
+    if (rc)
+        DoEnterLeaveEvents(dev, old, win, XINotifyPassiveGrab);
+
+    return rc;
 }
 
 /**
@@ -2795,7 +2806,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
             UpdateCurrentTimeIf();
 
 	if (prevSpriteWin != NullWindow) {
-            if (!ActivateEnterGrab(pDev, newSpriteWin))
+            if (!ActivateEnterGrab(pDev, prevSpriteWin, newSpriteWin))
                 DoEnterLeaveEvents(pDev, prevSpriteWin,
                                    newSpriteWin, NotifyNormal);
         }
@@ -4267,6 +4278,10 @@ DeviceEnterLeaveEvent(
     int                 btlen, len, i;
     DeviceIntPtr        kbd;
 
+    if ((mode == XINotifyPassiveGrab && type == XI_Leave) ||
+        (mode == XINotifyPassiveUngrab && type == XI_Enter))
+        return;
+
     btlen = (mouse->button) ? (mouse->button->numButtons + 7)/8 : 0;
     btlen = (btlen + 3)/4;
     len = sizeof(xXIEnterEvent) + btlen * 4;
@@ -4426,11 +4441,11 @@ SetInputFocus(
     mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal;
     if (focus->win == FollowKeyboardWin)
     {
-        if (!ActivateFocusInGrab(dev, focusWin))
+        if (!ActivateFocusInGrab(dev, keybd->focus->win, focusWin))
             DoFocusEvents(dev, keybd->focus->win, focusWin, mode);
     } else
     {
-        if (!ActivateFocusInGrab(dev, focusWin))
+        if (!ActivateFocusInGrab(dev, focus->win, focusWin))
             DoFocusEvents(dev, focus->win, focusWin, mode);
     }
     focus->time = time;
@@ -5413,13 +5428,13 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
                                 || clients[CLIENT_ID(parent->drawable.id)]->clientGone
 #endif
                                 );
-                        if (!ActivateFocusInGrab(keybd, parent))
+                        if (!ActivateFocusInGrab(keybd, pWin, parent))
                             DoFocusEvents(keybd, pWin, parent, focusEventMode);
                         focus->win = parent;
                         focus->revert = RevertToNone;
                         break;
                     case RevertToPointerRoot:
-                        if (!ActivateFocusInGrab(keybd, PointerRootWin))
+                        if (!ActivateFocusInGrab(keybd, pWin, PointerRootWin))
                             DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
                         focus->win = PointerRootWin;
                         focus->traceGood = 0;
diff --git a/include/dix.h b/include/dix.h
index bfb0369..df73519 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -352,6 +352,7 @@ extern void DeactivateKeyboardGrab(
 
 extern BOOL ActivateFocusInGrab(
     DeviceIntPtr /* dev */,
+    WindowPtr /* old */,
     WindowPtr /* win */);
 
 extern void AllowSome(
commit a7e23a79c1fc429aedbf9b6c0e78b1c8d7e02238
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 26 14:42:25 2009 +1000

    Xi: Add support for Enter and FocusIn grabs.
    
    Enter grabs are checked for in CheckMotion(), each time the sprite window
    changes the current grab is deactivated (if applicable) and the new grab is
    activated (if applicable). Exception - if the grab is on a parent window of
    the current window since we keep the grab across descendants.
    
    Since CheckMotion() may change the grab status of a device, we mustn't get
    "dev->deviceGrab.grab" in ProcessOtherEvents until after CheckMotion().
    FocusIn grabs are checked in much the same manner.
    
    The event delivery for grabs replaces the NotifyNormal on window change with
    a NotifyGrab on window change. Note that this happens before the grab
    activates, so the EnterNotify(NotifyGrab) is still delivered to the window,
    not to the grabbing client. This is in line with the core protocol semantics
    for NotifyGrab events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 83891f8..91a3461 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -962,7 +962,7 @@ ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
 void
 ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
 {
-    GrabPtr grab = device->deviceGrab.grab;
+    GrabPtr grab;
     Bool deactivateDeviceGrab = FALSE;
     int key = 0, rootX, rootY;
     ButtonClassPtr b;
@@ -1060,6 +1060,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
 	CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
     }
 #endif
+    grab = device->deviceGrab.grab;
 
     switch(event->type)
     {
@@ -1509,6 +1510,52 @@ GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
     return AddPassiveGrabToList(client, grab);
 }
 
+/* Enter/FocusIn grab */
+int
+GrabWindow(ClientPtr client, DeviceIntPtr dev, int type,
+           GrabParameters *param, GrabMask *mask)
+{
+    WindowPtr pWin;
+    CursorPtr cursor;
+    GrabPtr grab;
+    Mask access_mode = DixGrabAccess;
+    int rc;
+
+    rc = CheckGrabValues(client, param);
+    if (rc != Success)
+        return rc;
+
+    rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
+    if (rc != Success)
+	return rc;
+    if (param->cursor == None)
+	cursor = NullCursor;
+    else {
+	rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
+				     RT_CURSOR, client, DixUseAccess);
+	if (rc != Success)
+	{
+	    client->errorValue = param->cursor;
+	    return (rc == BadValue) ? BadCursor : rc;
+	}
+	access_mode |= DixForceAccess;
+    }
+    if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
+	access_mode |= DixFreezeAccess;
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
+    if (rc != Success)
+	return rc;
+
+    grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2,
+                      mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn,
+                      0, NULL, cursor);
+
+    if (!grab)
+        return BadAlloc;
+
+    return AddPassiveGrabToList(client, grab);
+}
+
 int
 SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client,
 		Mask mask, Mask exclusivemasks)
@@ -1825,7 +1872,8 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
 
 	switch (dev->focus->revert) {
 	case RevertToNone:
-	    DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+	    if (!ActivateFocusInGrab(dev, NoneWin))
+		DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
 	    dev->focus->win = NoneWin;
 	    dev->focus->traceGood = 0;
 	    break;
@@ -1836,12 +1884,14 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
 		dev->focus->traceGood--;
 	    }
 	    while (!parent->realized);
-	    DoFocusEvents(dev, pWin, parent, focusEventMode);
+	    if (!ActivateFocusInGrab(dev, parent))
+		DoFocusEvents(dev, pWin, parent, focusEventMode);
 	    dev->focus->win = parent;
 	    dev->focus->revert = RevertToNone;
 	    break;
 	case RevertToPointerRoot:
-	    DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
+	    if (!ActivateFocusInGrab(dev, PointerRootWin))
+		DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
 	    dev->focus->win = PointerRootWin;
 	    dev->focus->traceGood = 0;
 	    break;
@@ -1851,11 +1901,13 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
                 if (!kbd || (kbd == dev && kbd != inputInfo.keyboard))
                     kbd = inputInfo.keyboard;
 	    if (kbd->focus->win) {
-		DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
+		if (!ActivateFocusInGrab(dev, kbd->focus->win))
+		    DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
 		dev->focus->win = FollowKeyboardWin;
 		dev->focus->traceGood = 0;
 	    } else {
-                DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+                if (!ActivateFocusInGrab(dev, NoneWin))
+                    DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
 		dev->focus->win = NoneWin;
 		dev->focus->traceGood = 0;
 	    }
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index f53b050..a8807bd 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -95,12 +95,21 @@ ProcXIPassiveGrabDevice(ClientPtr client)
 	return ret;
 
     if (stuff->grab_type != XIGrabtypeButton &&
-        stuff->grab_type != XIGrabtypeKeysym)
+        stuff->grab_type != XIGrabtypeKeysym &&
+        stuff->grab_type != XIGrabtypeEnter &&
+        stuff->grab_type != XIGrabtypeFocusIn)
     {
         client->errorValue = stuff->grab_type;
         return BadValue;
     }
 
+    if ((stuff->grab_type == XIGrabtypeEnter ||
+         stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
+    {
+        client->errorValue = stuff->detail;
+        return BadValue;
+    }
+
     /* Can't grab for modifiers on an attached slave device */
     if (!IsMaster(dev))
     {
@@ -175,6 +184,11 @@ ProcXIPassiveGrabDevice(ClientPtr client)
                 status = GrabKey(client, dev, mod_dev, stuff->detail,
                                  &param, GRABTYPE_XI2, &mask);
                 break;
+            case XIGrabtypeEnter:
+            case XIGrabtypeFocusIn:
+                status = GrabWindow(client, dev, stuff->grab_type,
+                                    &param, &mask);
+                break;
         }
 
         if (status != GrabSuccess)
@@ -251,12 +265,21 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
 	return rc;
 
     if (stuff->grab_type != XIGrabtypeButton &&
-        stuff->grab_type != XIGrabtypeKeysym)
+        stuff->grab_type != XIGrabtypeKeysym &&
+        stuff->grab_type != XIGrabtypeEnter &&
+        stuff->grab_type != XIGrabtypeFocusIn)
     {
         client->errorValue = stuff->grab_type;
         return BadValue;
     }
 
+    if ((stuff->grab_type == XIGrabtypeEnter ||
+         stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
+    {
+        client->errorValue = stuff->detail;
+        return BadValue;
+    }
+
     rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
     if (rc != Success)
         return rc;
@@ -269,8 +292,13 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
     tempGrab.resource = client->clientAsMask;
     tempGrab.device = dev;
     tempGrab.window = win;
-    tempGrab.type =
-        (stuff->grab_type == XIGrabtypeButton) ? XI_ButtonPress : XI_KeyPress;
+    switch(stuff->grab_type)
+    {
+        case XIGrabtypeButton:  tempGrab.type = XI_ButtonPress; break;
+        case XIGrabtypeKeysym:  tempGrab.type = XI_KeyPress;    break;
+        case XIGrabtypeEnter:   tempGrab.type = XI_Enter;       break;
+        case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn;     break;
+    }
     tempGrab.grabtype = GRABTYPE_XI2;
     tempGrab.modifierDevice = mod_dev;
     tempGrab.modifiersDetail.pMask = NULL;
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 403282c..5072891 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -155,6 +155,12 @@ EventToXI2(InternalEvent *ev, xEvent **xi)
 {
     switch (ev->any.type)
     {
+        /* Enter/FocusIn are for grabs. We don't need an actual event, since
+         * the real events delivered are triggered elsewhere */
+        case ET_Enter:
+        case ET_FocusIn:
+            *xi = NULL;
+            return Success;
         case ET_Motion:
         case ET_ButtonPress:
         case ET_ButtonRelease:
@@ -525,6 +531,8 @@ GetXI2Type(InternalEvent *event)
         case ET_Hierarchy:      xi2type = XI_HierarchyChanged; break;
         case ET_DeviceChanged:  xi2type = XI_DeviceChanged;    break;
         case ET_Raw:            xi2type = XI_RawEvent;         break;
+        case ET_FocusIn:        xi2type = XI_FocusIn;          break;
+        case ET_FocusOut:       xi2type = XI_FocusOut;         break;
         default:
             break;
     }
diff --git a/dix/events.c b/dix/events.c
index 5e1ab1f..5d22016 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -224,6 +224,10 @@ static void CheckPhysLimits(DeviceIntPtr pDev,
                             Bool generateEvents,
                             Bool confineToScreen,
                             ScreenPtr pScreen);
+static Bool CheckPassiveGrabsOnWindow(WindowPtr pWin,
+                                      DeviceIntPtr device,
+                                      DeviceEvent *event,
+                                      BOOL checkCore);
 
 /**
  * Main input device struct.
@@ -2624,6 +2628,74 @@ XYToWindow(DeviceIntPtr pDev, int x, int y)
 }
 
 /**
+ * Ungrab a currently FocusIn grabbed device and grab the device on the
+ * given window. If the win given is the NoneWin, the device is ungrabbed if
+ * applicable and FALSE is returned.
+ *
+ * @returns TRUE if the device has been grabbed, or FALSE otherwise.
+ */
+BOOL
+ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr win)
+{
+    DeviceEvent event;
+
+    if (dev->deviceGrab.grab &&
+        dev->deviceGrab.fromPassiveGrab &&
+        dev->deviceGrab.grab->type == XI_Enter)
+    {
+        if (dev->deviceGrab.grab->window == win ||
+            IsParent(dev->deviceGrab.grab->window, win))
+            return FALSE;
+        (*dev->deviceGrab.DeactivateGrab)(dev);
+    }
+
+    if (win == NoneWin || win == PointerRootWin)
+        return FALSE;
+
+    memset(&event, 0, sizeof(DeviceEvent));
+    event.header = ET_Internal;
+    event.type = ET_FocusIn;
+    event.length = sizeof(DeviceEvent);
+    event.time = GetTimeInMillis();
+    event.deviceid = dev->id;
+    event.sourceid = dev->id;
+    event.detail.button = 0;
+    return CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
+}
+
+/**
+ * Ungrab a currently Enter grabbed device and grab the deice for the given
+ * window.
+ *
+ * @returns TRUE if the device has been grabbed, or FALSE otherwise.
+ */
+static BOOL
+ActivateEnterGrab(DeviceIntPtr dev, WindowPtr win)
+{
+    DeviceEvent event;
+
+    if (dev->deviceGrab.grab &&
+        dev->deviceGrab.fromPassiveGrab &&
+        dev->deviceGrab.grab->type == XI_Enter)
+    {
+        if (dev->deviceGrab.grab->window == win ||
+            IsParent(dev->deviceGrab.grab->window, win))
+            return FALSE;
+        (*dev->deviceGrab.DeactivateGrab)(dev);
+    }
+
+    memset(&event, 0, sizeof(DeviceEvent));
+    event.header = ET_Internal;
+    event.type = ET_Enter;
+    event.length = sizeof(DeviceEvent);
+    event.time = GetTimeInMillis();
+    event.deviceid = dev->id;
+    event.sourceid = dev->id;
+    event.detail.button = 0;
+    return CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
+}
+
+/**
  * Update the sprite coordinates based on the event. Update the cursor
  * position, then update the event with the new coordinates that may have been
  * changed. If the window underneath the sprite has changed, change to new
@@ -2637,7 +2709,7 @@ XYToWindow(DeviceIntPtr pDev, int x, int y)
 Bool
 CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
 {
-    WindowPtr prevSpriteWin;
+    WindowPtr prevSpriteWin, newSpriteWin;
     SpritePtr pSprite = pDev->spriteInfo->sprite;
 
     CHECKEVENT(ev);
@@ -2715,17 +2787,23 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
 	ev->root_y = pSprite->hot.y;
     }
 
-    pSprite->win = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y);
+    newSpriteWin = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y);
 
-    if (pSprite->win != prevSpriteWin)
+    if (newSpriteWin != prevSpriteWin)
     {
+        if (!ev)
+            UpdateCurrentTimeIf();
+
 	if (prevSpriteWin != NullWindow) {
-	    if (!ev)
-		UpdateCurrentTimeIf();
-            DoEnterLeaveEvents(pDev, prevSpriteWin, pSprite->win,
-                               NotifyNormal);
+            if (!ActivateEnterGrab(pDev, newSpriteWin))
+                DoEnterLeaveEvents(pDev, prevSpriteWin,
+                                   newSpriteWin, NotifyNormal);
         }
-	PostNewCursor(pDev);
+        /* set pSprite->win after ActivateEnterGrab, otherwise
+           sprite window == grab_window and no enter/leave events are
+           sent. */
+        pSprite->win = newSpriteWin;
+        PostNewCursor(pDev);
         return FALSE;
     }
     return TRUE;
@@ -3443,11 +3521,14 @@ CheckPassiveGrabsOnWindow(
 
 	    (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
 
-	    FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
+            if (xE)
+            {
+                FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
 
-	    TryClientEvents(rClient(grab), device, xE, count,
-                                   GetEventFilter(device, xE),
-                                   GetEventFilter(device, xE), grab);
+                TryClientEvents(rClient(grab), device, xE, count,
+                                       GetEventFilter(device, xE),
+                                       GetEventFilter(device, xE), grab);
+            }
 
 	    if (grabinfo->sync.state == FROZEN_NO_EVENT)
 	    {
@@ -4344,9 +4425,14 @@ SetInputFocus(
 	return Success;
     mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal;
     if (focus->win == FollowKeyboardWin)
-	DoFocusEvents(dev, keybd->focus->win, focusWin, mode);
-    else
-	DoFocusEvents(dev, focus->win, focusWin, mode);
+    {
+        if (!ActivateFocusInGrab(dev, focusWin))
+            DoFocusEvents(dev, keybd->focus->win, focusWin, mode);
+    } else
+    {
+        if (!ActivateFocusInGrab(dev, focusWin))
+            DoFocusEvents(dev, focus->win, focusWin, mode);
+    }
     focus->time = time;
     focus->revert = revertTo;
     if (focusID == FollowKeyboard)
@@ -5327,12 +5413,14 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
                                 || clients[CLIENT_ID(parent->drawable.id)]->clientGone
 #endif
                                 );
-                        DoFocusEvents(keybd, pWin, parent, focusEventMode);
+                        if (!ActivateFocusInGrab(keybd, parent))
+                            DoFocusEvents(keybd, pWin, parent, focusEventMode);
                         focus->win = parent;
                         focus->revert = RevertToNone;
                         break;
                     case RevertToPointerRoot:
-                        DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+                        if (!ActivateFocusInGrab(keybd, PointerRootWin))
+                            DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
                         focus->win = PointerRootWin;
                         focus->traceGood = 0;
                         break;
diff --git a/include/dix.h b/include/dix.h
index d4bec5f..bfb0369 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -350,6 +350,10 @@ extern void ActivateKeyboardGrab(
 extern void DeactivateKeyboardGrab(
     DeviceIntPtr /* keybd */);
 
+extern BOOL ActivateFocusInGrab(
+    DeviceIntPtr /* dev */,
+    WindowPtr /* win */);
+
 extern void AllowSome(
     ClientPtr	/* client */,
     TimeStamp /* time */,
@@ -582,6 +586,7 @@ extern Bool IsKeyboardDevice(DeviceIntPtr dev);
 extern Bool IsPointerEvent(InternalEvent *event);
 extern Bool IsMaster(DeviceIntPtr dev);
 
+
 /*
  * These are deprecated compatibility functions and will be removed soon!
  * Please use the noted replacements instead.
diff --git a/include/exevents.h b/include/exevents.h
index 95d08cc..5878413 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -107,6 +107,13 @@ extern int GrabKey(
         GrabType               /* grabtype */,
 	GrabMask*              /* eventMask */);
 
+extern int GrabWindow(
+	ClientPtr              /* client */,
+	DeviceIntPtr           /* dev */,
+	int                    /* type */,
+	GrabParameters*        /* param */,
+	GrabMask*              /* eventMask */);
+
 extern int SelectForWindow(
 	DeviceIntPtr           /* dev */,
 	WindowPtr              /* pWin */,
commit ec2fe9660dbc0c16cdaca33b3b878011857e0fe2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 27 14:18:51 2009 +1000

    Require inputproto 1.9.99.10

diff --git a/configure.ac b/configure.ac
index 6c03951..56e8586 100644
--- a/configure.ac
+++ b/configure.ac
@@ -700,7 +700,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la'
 XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
 
 dnl Core modules for most extensions, et al.
-REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.9.3] [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto [xextproto >= 7.0.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] bigreqsproto resourceproto fontsproto [inputproto >= 1.9.99.9] [kbproto >= 1.0.3]"
+REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.9.3] [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto [xextproto >= 7.0.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] bigreqsproto resourceproto fontsproto [inputproto >= 1.9.99.10] [kbproto >= 1.0.3]"
 REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.13.2]"
 
 dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
commit 0ef6ba9f3b9e68307bfe623e12dc36d44440e97f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 27 11:15:54 2009 +1000

    Xi: set the passive grab's resource mask on ungrabbing.
    
    Not having the resource mask set means we never match an existing grab,
    hence we never actually ungrab.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 95acdf0..f53b050 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -266,6 +266,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
     else
         mod_dev = dev;
 
+    tempGrab.resource = client->clientAsMask;
     tempGrab.device = dev;
     tempGrab.window = win;
     tempGrab.type =
commit 1f61d6647f25add487c5cae9739643a6e33ef9f7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 27 11:15:23 2009 +1000

    Xi: use GetMaster(MASTER_KEYBOARD) to get the modifier device for XI2 pgrabs
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 3f46e67..95acdf0 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -157,8 +157,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     if (!modifiers_failed)
         return BadAlloc;
 
-    if (IsPointerDevice(dev) && IsMaster(dev))
-        mod_dev = GetPairedDevice(dev);
+    if (!IsMaster(dev) && dev->u.master)
+        mod_dev = GetMaster(dev, MASTER_KEYBOARD);
     else
         mod_dev = dev;
 
@@ -261,8 +261,8 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
     if (rc != Success)
         return rc;
 
-    if (IsMaster(dev))
-        mod_dev = GetPairedDevice(dev);
+    if (!IsMaster(dev) && dev->u.master)
+        mod_dev = GetMaster(dev, MASTER_KEYBOARD);
     else
         mod_dev = dev;
 
commit bedfd561fa534b65baea45c4a05b1752ef172c45
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 26 15:28:33 2009 +1000

    dix: fix wrong cast of eventMask into CreateGrab.

diff --git a/dix/grabs.c b/dix/grabs.c
index eb8bec8..0df8ad1 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -457,7 +457,7 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
 	    pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device,
 				  grab->modifierDevice, grab->window,
                                   grab->grabtype,
-				  (GrabMask*)grab->eventMask,
+				  (GrabMask*)&grab->eventMask,
                                   &param, (int)grab->type,
 				  pMinuendGrab->detail.exact,
 				  grab->confineTo, grab->cursor);
commit 023f959e6812e63f9d38b078158275bc13d238ae
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 26 14:56:40 2009 +1000

    Xi: fix an inputInfo.keyboard usage.
    
    In the case of a RevertToFollowKeyboard, the master device should be used
    (since this is the closest equivalent to the VCK as before). Only if the
    master keyboard is the same as the device, revert to the VCK itself.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 2bcc2e1..83891f8 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1846,16 +1846,20 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
 	    dev->focus->traceGood = 0;
 	    break;
 	case RevertToFollowKeyboard:
-	    if (inputInfo.keyboard->focus->win) {
-		DoFocusEvents(dev, pWin, inputInfo.keyboard->focus->win,
-			      focusEventMode);
+            {
+                DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD);
+                if (!kbd || (kbd == dev && kbd != inputInfo.keyboard))
+                    kbd = inputInfo.keyboard;
+	    if (kbd->focus->win) {
+		DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
 		dev->focus->win = FollowKeyboardWin;
 		dev->focus->traceGood = 0;
 	    } else {
-		DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+                DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
 		dev->focus->win = NoneWin;
 		dev->focus->traceGood = 0;
 	    }
+            }
 	    break;
 	}
     }
commit b3463fd6a89d50a7562c357aeb5314ce0fd6493d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 26 13:58:04 2009 +1000

    dix: convert window coordinates to FP1616 before calculating event_x/y
    
    root_x/y are already in FP1616 at this point.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 382fd8d..5e1ab1f 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2240,8 +2240,8 @@ FixUpEventFromWindow(
         event->event = pWin->drawable.id;
         if (pSprite->hot.pScreen == pWin->drawable.pScreen)
         {
-            event->event_x = FP1616(event->root_x - pWin->drawable.x, 0);
-            event->event_y = FP1616(event->root_y - pWin->drawable.y, 0);
+            event->event_x = event->root_x - FP1616(pWin->drawable.x, 0);
+            event->event_y = event->root_y - FP1616(pWin->drawable.y, 0);
             event->child = child;
         } else
         {
commit 10b5e981016132b4c07ad9ce68646d0a385e9c24
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 26 11:12:08 2009 +1000

    dix: take grabs into account for XI_Enter/Leave events.

diff --git a/dix/events.c b/dix/events.c
index 6f05272..382fd8d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4182,7 +4182,6 @@ DeviceEnterLeaveEvent(
 {
     GrabPtr             grab = mouse->deviceGrab.grab;
     xXIEnterEvent       *event;
-    Mask                mask;
     int                 filter;
     int                 btlen, len, i;
     DeviceIntPtr        kbd;
@@ -4223,19 +4222,22 @@ DeviceEnterLeaveEvent(
 
     FixUpEventFromWindow(mouse, (xEvent*)event, pWin, None, FALSE);
 
-
-    if (!GetWindowXI2Mask(mouse, pWin, (xEvent*)event))
-        return;
-
     filter = GetEventFilter(mouse, (xEvent*)event);
-    mask = 0x0; /* FIXME: we should handle grabs, once we can */
 
     if (grab)
+    {
+        Mask mask;
+        mask = grab->xi2mask[XIAllDevices][type/8] |
+               grab->xi2mask[XIAllMasterDevices][type/8] |
+               grab->xi2mask[mouse->id][type/8];
         TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask,
                         filter, grab);
-    else
+    } else {
+        if (!GetWindowXI2Mask(mouse, pWin, (xEvent*)event))
+            return;
         DeliverEventsToWindow(mouse, pWin, (xEvent*)event, 1, filter,
                               NullGrab);
+    }
     xfree(event);
 }
 
commit 1815defdb2f19e79f4ec0354d188ea763ff1f15e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 26 10:08:46 2009 +1000

    Xi: only deactivate passive grabs if the event type matches.
    
    This didn't use to be a problem when devices could only be pointers or
    keyboards, not both. Nowadays, slave devices may have both buttons and
    keyboards, and in this case we don't want to deactivate a passive keyboard
    grab when a button release is detected.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 2eec7f8..2bcc2e1 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1070,8 +1070,11 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
             }
             break;
         case ET_KeyRelease:
-            if (device->deviceGrab.fromPassiveGrab &&
-                    (key == device->deviceGrab.activatingKey))
+            if (grab && device->deviceGrab.fromPassiveGrab &&
+                (key == device->deviceGrab.activatingKey) &&
+                (device->deviceGrab.grab->type == KeyPress ||
+                 device->deviceGrab.grab->type == DeviceKeyPress ||
+                 device->deviceGrab.grab->type == XI_KeyPress))
                 deactivateDeviceGrab = TRUE;
             break;
         case ET_ButtonPress:
@@ -1092,7 +1095,11 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
                 event->detail.button = key;
                 return;
             }
-            if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab)
+            if (grab && !b->buttonsDown &&
+                device->deviceGrab.fromPassiveGrab &&
+                (device->deviceGrab.grab->type == ButtonPress ||
+                 device->deviceGrab.grab->type == DeviceButtonPress ||
+                 device->deviceGrab.grab->type == XI_ButtonPress))
                 deactivateDeviceGrab = TRUE;
     }
 
commit 9dc3810a034f067096d71b33b0b47f1f52092fe6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 27 13:53:46 2009 +1000

    dix: set the right grab event type for implicit passive grabs.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 19a9e1d..6f05272 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2069,6 +2069,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
 	tempGrab.pointerMode = GrabModeAsync;
 	tempGrab.confineTo = NullWindow;
 	tempGrab.cursor = NullCursor;
+        tempGrab.type = type;
         if (type == ButtonPress)
             tempGrab.grabtype = GRABTYPE_CORE;
         else if (type == DeviceButtonPress)
commit 53e821ab4a41cbc85932b9ef150311bc2e57c108
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 25 12:20:37 2009 +1000

    Xi: add request processing for XIGetSelectedEvents.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index a8f8f10..7e5111d 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -254,7 +254,8 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXIListProperties,                   /* 56 */
         ProcXIChangeProperty,                   /* 57 */
         ProcXIDeleteProperty,                   /* 58 */
-        ProcXIGetProperty                       /* 59 */
+        ProcXIGetProperty,                      /* 59 */
+        ProcXIGetSelectedEvents                 /* 60 */
 };
 
 /* For swapped clients */
@@ -318,7 +319,8 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXIListProperties,                   /* 56 */
         SProcXIChangeProperty,                   /* 57 */
         SProcXIDeleteProperty,                   /* 58 */
-        SProcXIGetProperty                       /* 59 */
+        SProcXIGetProperty,                      /* 59 */
+        SProcXIGetSelectedEvents                 /* 60 */
 };
 
 /*****************************************************************
@@ -516,6 +518,8 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
 	SRepXIListProperties(client, len, (xXIListPropertiesReply *) rep);
     else if (rep->RepType == X_XIGetProperty)
 	SRepXIGetProperty(client, len, (xXIGetPropertyReply *) rep);
+    else if (rep->RepType == X_XIGetSelectedEvents)
+	SRepXIGetSelectedEvents(client, len, (xXIGetSelectedEventsReply *) rep);
     else {
 	FatalError("XINPUT confused sending swapped reply");
     }
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index 5616182..31e6a77 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -128,3 +128,119 @@ ProcXISelectEvent(ClientPtr client)
     xfree(types);
     return Success;
 }
+
+
+int
+SProcXIGetSelectedEvents(ClientPtr client)
+{
+    char n;
+
+    REQUEST(xXIGetSelectedEventsReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq);
+    swapl(&stuff->window, n);
+
+    return (ProcXIGetSelectedEvents(client));
+}
+
+int
+ProcXIGetSelectedEvents(ClientPtr client)
+{
+    int rc, i;
+    WindowPtr win;
+    char n;
+    char *buffer = NULL;
+    xXIGetSelectedEventsReply reply;
+    OtherInputMasks *masks;
+    InputClientsPtr others = NULL;
+    xXIEventMask *evmask = NULL;
+
+    REQUEST(xXIGetSelectedEventsReq);
+    REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq);
+
+    rc = dixLookupWindow(&win, stuff->window, client, DixReceiveAccess);
+    if (rc != Success)
+        return rc;
+
+    reply.repType = X_Reply;
+    reply.RepType = X_XIGetSelectedEvents;
+    reply.length = 0;
+    reply.sequenceNumber = client->sequence;
+    reply.num_masks = 0;
+
+    masks = wOtherInputMasks(win);
+    if (masks)
+    {
+	for (others = wOtherInputMasks(win)->inputClients; others;
+	     others = others->next) {
+	    if (SameClient(others, client)) {
+                break;
+            }
+        }
+    }
+
+    if (!others)
+    {
+        WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply);
+        return Success;
+    }
+
+    buffer = xcalloc(MAXDEVICES, sizeof(xXIEventMask) + XI2MASKSIZE);
+    if (!buffer)
+        return BadAlloc;
+
+    evmask = (xXIEventMask*)buffer;
+    for (i = 0; i < MAXDEVICES; i++)
+    {
+        int j;
+        unsigned char *devmask = others->xi2mask[i];
+
+        for (j = XI2MASKSIZE - 1; j >= 0; j--)
+        {
+            if (devmask[j] != 0)
+            {
+                evmask->deviceid = i;
+                evmask->mask_len = (j + 4)/4; /* j is an index, hence + 4,
+                                                 not + 3 */
+
+                reply.num_masks++;
+                reply.length += sizeof(xXIEventMask)/4 + evmask->mask_len;
+
+                if (client->swapped)
+                {
+                    swaps(&evmask->deviceid, n);
+                    swaps(&evmask->mask_len, n);
+                }
+
+                memcpy(&evmask[1], devmask, j + 1);
+                evmask = (xXIEventMask*)((char*)evmask +
+                           sizeof(xXIEventMask) + evmask->mask_len * 4);
+                break;
+            }
+        }
+    }
+
+    WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply);
+
+    if (reply.num_masks)
+    {
+        WriteSwappedDataToClient(client, reply.length * 4, buffer);
+    }
+
+
+    xfree(buffer);
+    return Success;
+}
+
+void SRepXIGetSelectedEvents(ClientPtr client,
+                            int len, xXIGetSelectedEventsReply *rep)
+{
+    char n;
+
+    swaps(&rep->sequenceNumber, n);
+    swapl(&rep->length, n);
+    swaps(&rep->num_masks, n);
+    WriteToClient(client, len, (char *)rep);
+}
+
+
diff --git a/Xi/xiselectev.h b/Xi/xiselectev.h
index dc52712..5f5ffe3 100644
--- a/Xi/xiselectev.h
+++ b/Xi/xiselectev.h
@@ -29,3 +29,7 @@
 
 int SProcXISelectEvent(ClientPtr client);
 int ProcXISelectEvent(ClientPtr client);
+int SProcXIGetSelectedEvents(ClientPtr client);
+int ProcXIGetSelectedEvents(ClientPtr client);
+void SRepXIGetSelectedEvents(ClientPtr client,
+                             int len, xXIGetSelectedEventsReply *rep);
commit b377994336c978875dd786f4a4a9ef2e7b20e32c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 25 13:55:17 2009 +1000

    Xi: advance by the right number of bytes when trawling XI2 event masks.
    
    The wire layout is  [struct xXIEventMask][mask bytes]. So the pointer needs
    to not only be advanced by the mask bytes, but also by the size of the
    struct.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index 7309773..5616182 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -103,6 +103,7 @@ ProcXISelectEvent(ClientPtr client)
         }
 
         evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+        evmask++;
     }
 
     /* Set masks on window */
@@ -119,6 +120,7 @@ ProcXISelectEvent(ClientPtr client)
             dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess);
         XISetEventMask(dev, win, client, evmask->mask_len * 4, (unsigned char*)&evmask[1]);
         evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+        evmask++;
     }
 
     RecalculateDeliverableEvents(win);
commit b395da91c531d633ec47bb5a51e361d321663a3a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 22 15:24:46 2009 +1000

    Xi: silence two compiler warnings
    
    chdevcur.c:97: warning: ‘SecurityLookupIDByType’ is deprecated (declared at
    ../include/resource.h:269)
    
    xiproperty.c:200: warning: passing argument 2 of ‘GetEventFilter’ from
    incompatible pointer type
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/chdevcur.c b/Xi/chdevcur.c
index 0315edb..977095c 100644
--- a/Xi/chdevcur.c
+++ b/Xi/chdevcur.c
@@ -94,12 +94,10 @@ int ProcXIChangeCursor(ClientPtr client)
     }
     else
     {
-        pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
-                                RT_CURSOR, DixReadAccess);
-        if (!pCursor)
-        {
-            return BadCursor;
-        }
+	rc = dixLookupResourceByType((pointer*)&pCursor, stuff->cursor,
+				     RT_CURSOR, client, DixReadAccess);
+        if (rc != Success)
+            return rc;
     }
 
     ChangeWindowDeviceCursor(pWin, pDev, pCursor);
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 3cda82b..cd49460 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -197,7 +197,8 @@ static void send_property_event(DeviceIntPtr dev, Atom property, int what)
         xi2.time        = currentTime.milliseconds;
         xi2.property    = property;
         xi2.what        = what;
-        SendEventToAllWindows(dev, GetEventFilter(dev, &xi2), (xEvent*)&xi2, 1);
+        SendEventToAllWindows(dev, GetEventFilter(dev, (xEvent*)&xi2),
+                              (xEvent*)&xi2, 1);
 }
 
 static int list_atoms(DeviceIntPtr dev, int *natoms, Atom **atoms_return)
commit 4a36db60774640ea92a2133a3b08fbf1a48d2cb6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 22 15:16:43 2009 +1000

    os: fix compiler warning "too few arguments to format"
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/os/osinit.c b/os/osinit.c
index b7bd076..1559135 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -136,8 +136,8 @@ OsSigHandler(int signo)
 
 #ifdef SA_SIGINFO
   if (sip->si_code == SI_USER) {
-      ErrorF("Recieved signal %d sent by process %ld, uid %ld\n",
-	     (long) sip->si_pid, (long) sip->si_uid);
+      ErrorF("Recieved signal %ld sent by process %ld, uid %ld\n",
+              (long) sip->si_code, (long) sip->si_pid, (long) sip->si_uid);
   } else {
       switch (signo) {
           case SIGSEGV:
commit da0d3baf71b34657cc235d6c6b37d548541f9449
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 21 14:11:27 2009 +1000

    dix: protect event generation against single-valuator devices.
    
    If we have a single-axis device and it sends events it should not access
    non-existant memory.

diff --git a/dix/getevents.c b/dix/getevents.c
index fa3c781..9c7ac44 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -576,6 +576,9 @@ clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
     AxisInfoPtr axis = pDev->valuator->axes + axisNum;
     /* InitValuatoraAxisStruct ensures that (min < max). */
 
+    if (axisNum >= pDev->valuator->numAxes)
+        return;
+
     /* If a value range is defined, clip. If not, do nothing */
     if (axis->max_value <= axis->min_value)
         return;
@@ -751,8 +754,16 @@ positionSprite(DeviceIntPtr dev, int *x, int *y,
                ScreenPtr scr, int *screenx, int *screeny)
 {
     /* scale x&y to screen */
-    *screenx = rescaleValuatorAxis(*x, dev->valuator->axes + 0, NULL, scr->width);
-    *screeny = rescaleValuatorAxis(*y, dev->valuator->axes + 1, NULL, scr->height);
+    if (dev->valuator->numAxes > 0)
+        *screenx = rescaleValuatorAxis(*x, dev->valuator->axes + 0, NULL, scr->width);
+    else
+        *screenx = dev->last.valuators[0];
+
+    if (dev->valuator->numAxes > 1 )
+        *screeny = rescaleValuatorAxis(*y, dev->valuator->axes + 1, NULL, scr->height);
+    else
+        *screeny = dev->last.valuators[1];
+
     dev->last.valuators[0] = *screenx;
     dev->last.valuators[1] = *screeny;
 
@@ -1006,7 +1017,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     CARD32 ms;
     DeviceEvent *event;
     RawDeviceEvent    *raw;
-    int x, y, /* switches between device and screen coords */
+    int x = 0, y = 0, /* switches between device and screen coords */
         cx, cy; /* only screen coordinates */
     ScreenPtr scr = miPointerGetScreen(pDev);
 
@@ -1040,11 +1051,12 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         {
 
             valuators[0] = rescaleValuatorAxis(valuators[0], NULL,
-                                               pDev->valuator->axes + 0,
-                                               scr->width);
-            valuators[1] = rescaleValuatorAxis(valuators[1], NULL,
-                                               pDev->valuator->axes + 1,
-                                               scr->height);
+                    pDev->valuator->axes + 0,
+                    scr->width);
+            if (num_valuators > 1)
+                valuators[1] = rescaleValuatorAxis(valuators[1], NULL,
+                        pDev->valuator->axes + 1,
+                        scr->height);
         }
 
         moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators);
@@ -1055,7 +1067,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     }
 
     set_raw_valuators(raw, first_valuator, num_valuators, valuators,
-                      raw->valuators.data);
+            raw->valuators.data);
 
     positionSprite(pDev, &x, &y, scr, &cx, &cy);
     updateHistory(pDev, first_valuator, num_valuators, ms);
commit b25e29e8014927815d4fdc9c416bfeb2af0ecba6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 21 12:07:03 2009 +1000

    mi: use GetMaster() from MIPOINTER and MISPRITE.
    
    Both may in some cases be called for a SD attached to a master keyboard. In
    this case, we need to get the right master device (i.e. the pointer).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mipointer.c b/mi/mipointer.c
index fdad77b..e1f63be 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -51,9 +51,9 @@ static int miPointerPrivKeyIndex;
 static DevPrivateKey miPointerPrivKey = &miPointerPrivKeyIndex;
 
 #define MIPOINTER(dev) \
-    ((DevHasCursor((dev)) || (!IsMaster(isMaster) && !dev->u.master)) ? \
+    ((!IsMaster(dev) && !dev->u.master) ? \
         (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \
-        (miPointerPtr)dixLookupPrivate(&(dev)->u.master->devPrivates, miPointerPrivKey))
+        (miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey))
 
 static Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
                                    CursorPtr pCursor);
diff --git a/mi/misprite.c b/mi/misprite.c
index 3f4c573..2ec6782 100644
--- a/mi/misprite.c
+++ b/mi/misprite.c
@@ -143,9 +143,9 @@ typedef struct {
 #endif
 
 #define MISPRITE(dev) \
-    ((DevHasCursor(dev)) ? \
+    ((!IsMaster(dev) && !dev->u.master) ? \
        (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \
-       (miCursorInfoPtr)dixLookupPrivate(&dev->u.master->devPrivates, miSpriteDevPrivatesKey))
+       (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey))
 
 static void
 miSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
commit c9df51b070377ca33e48644dbc842b6e3dfb2975
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 21 11:16:37 2009 +1000

    input: allow for master pointers to not have a button class.
    
    There's devices (e.g. some barcode readers) that have axes but no buttons.
    When such a device sends a motion event, the valuator and button class is
    copied into the master pointer (i.e. removing the button class).
    So we need a couple of extra sanity checks for the button class to exist.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index a72fb84..2eec7f8 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -996,8 +996,8 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
     }
 
     /* State needs to be assembled BEFORE the device is updated. */
-    state = (kbd) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
-    state |= (mouse) ? (mouse->button->state) : 0;
+    state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
+    state |= (mouse && mouse->button) ? (mouse->button->state) : 0;
 
     for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
         if (BitIsOn(mouse->button->down, i))
diff --git a/dix/events.c b/dix/events.c
index 8400cfa..19a9e1d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4128,7 +4128,7 @@ CoreEnterLeaveEvent(
     event.u.enterLeave.child = child;
     event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
         ELFlagSameScreen : 0;
-    event.u.enterLeave.state = mouse->button->state & 0x1f00;
+    event.u.enterLeave.state = mouse->button ? (mouse->button->state & 0x1f00) : 0;
     if (keybd)
         event.u.enterLeave.state |=
                 XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
@@ -4793,7 +4793,7 @@ ProcQueryPointer(ClientPtr client)
     memset(&rep, 0, sizeof(xQueryPointerReply));
     rep.type = X_Reply;
     rep.sequenceNumber = client->sequence;
-    rep.mask = mouse->button->state;
+    rep.mask = mouse->button ? (mouse->button->state) : 0;
     rep.mask |= XkbStateFieldFromRec(&keyboard->key->xkbInfo->state);
     rep.length = 0;
     rep.root = (RootWindow(mouse))->drawable.id;
diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index 9bf8714..88d5d90 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -726,7 +726,7 @@ DeviceEvent     *event = (DeviceEvent*)ev;
     COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr,
 				     backupproc, xkbUnwrapProc);
 
-    xkbi->state.ptr_buttons = mouse->button->state;
+    xkbi->state.ptr_buttons = (mouse->button) ? mouse->button->state : 0;
     
     /* clear any latched modifiers */
     if ( xkbi->state.latched_mods && (event->type == ET_ButtonRelease) ) {
commit ebe45e1a72a81ad22413e5d0514869b3e45a69b7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 10:55:03 2009 +1000

    input: introduce partial class copying depending on the event.
    
    Copying all classes into the master device has drawbacks for hybrid devices
    (devices that are both mice and keyboards). If such a device posts an event,
    it's key classes are moved into the VCP. The key event itself is unaffected
    by keyboard grabs and the like.
    
    Partial class copying copies depending on the event and copies the classes
    into the right master device (i.e. the VCK for key events, the VCP for
    pointer events).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 884fe72..a72fb84 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -216,83 +216,6 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
 {
     ClassesPtr classes;
 
-    if (from->kbdfeed)
-    {
-        KbdFeedbackPtr *k, it;
-
-        if (!to->kbdfeed)
-        {
-            classes = dixLookupPrivate(&to->devPrivates,
-                                       UnusedClassesPrivateKey);
-
-            to->kbdfeed = classes->kbdfeed;
-            if (!to->kbdfeed)
-                InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
-        }
-
-        k = &to->kbdfeed;
-        for(it = from->kbdfeed; it; it = it->next)
-        {
-            if (!(*k))
-            {
-                *k = xcalloc(1, sizeof(KbdFeedbackClassRec));
-                if (!*k)
-                {
-                    ErrorF("[Xi] Cannot alloc memory for class copy.");
-                    return;
-                }
-            }
-            (*k)->BellProc = it->BellProc;
-            (*k)->CtrlProc = it->CtrlProc;
-            (*k)->ctrl     = it->ctrl;
-            if ((*k)->xkb_sli)
-                XkbFreeSrvLedInfo((*k)->xkb_sli);
-            (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
-
-            k = &(*k)->next;
-        }
-    } else if (to->kbdfeed && !from->kbdfeed)
-    {
-        ClassesPtr classes;
-        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
-        classes->kbdfeed = to->kbdfeed;
-        to->kbdfeed      = NULL;
-    }
-
-    if (from->ptrfeed)
-    {
-        PtrFeedbackPtr *p, it;
-        if (!to->ptrfeed)
-        {
-            classes = dixLookupPrivate(&to->devPrivates,
-                                       UnusedClassesPrivateKey);
-            to->ptrfeed = classes->ptrfeed;
-        }
-
-        p = &to->ptrfeed;
-        for (it = from->ptrfeed; it; it = it->next)
-        {
-            if (!(*p))
-            {
-                *p = xcalloc(1, sizeof(PtrFeedbackClassRec));
-                if (!*p)
-                {
-                    ErrorF("[Xi] Cannot alloc memory for class copy.");
-                    return;
-                }
-            }
-            (*p)->CtrlProc = it->CtrlProc;
-            (*p)->ctrl     = it->ctrl;
-
-            p = &(*p)->next;
-        }
-    } else if (to->ptrfeed && !from->ptrfeed)
-    {
-        ClassesPtr classes;
-        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
-        classes->ptrfeed = to->ptrfeed;
-        to->ptrfeed      = NULL;
-    }
 
     if (from->intfeed)
     {
@@ -443,31 +366,63 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
     }
 }
 
-/**
- * Copies the CONTENT of the classes of device from into the classes in device
- * to. From and to are identical after finishing.
- *
- * If to does not have classes from currenly has, the classes are stored in
- * to's devPrivates system. Later, we recover it again from there if needed.
- * Saves a few memory allocations.
- */
-
-void
-DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
+static void
+DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
 {
     ClassesPtr classes;
 
     /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the
      * kbdfeed to be set up properly, so let's do the feedback classes first.
      */
-    DeepCopyFeedbackClasses(from, to);
+    if (from->kbdfeed)
+    {
+        KbdFeedbackPtr *k, it;
+
+        if (!to->kbdfeed)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+
+            to->kbdfeed = classes->kbdfeed;
+            if (!to->kbdfeed)
+                InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
+        }
+
+        k = &to->kbdfeed;
+        for(it = from->kbdfeed; it; it = it->next)
+        {
+            if (!(*k))
+            {
+                *k = xcalloc(1, sizeof(KbdFeedbackClassRec));
+                if (!*k)
+                {
+                    ErrorF("[Xi] Cannot alloc memory for class copy.");
+                    return;
+                }
+            }
+            (*k)->BellProc = it->BellProc;
+            (*k)->CtrlProc = it->CtrlProc;
+            (*k)->ctrl     = it->ctrl;
+            if ((*k)->xkb_sli)
+                XkbFreeSrvLedInfo((*k)->xkb_sli);
+            (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
+
+            k = &(*k)->next;
+        }
+    } else if (to->kbdfeed && !from->kbdfeed)
+    {
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->kbdfeed = to->kbdfeed;
+        to->kbdfeed      = NULL;
+    }
 
     if (from->key)
     {
         if (!to->key)
         {
             classes = dixLookupPrivate(&to->devPrivates,
-                                       UnusedClassesPrivateKey);
+                    UnusedClassesPrivateKey);
             to->key = classes->key;
             if (!to->key)
                 InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
@@ -484,6 +439,89 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
         to->key      = NULL;
     }
 
+    /* We can't just copy over the focus class. When an app sets the focus,
+     * it'll do so on the master device. Copying the SDs focus means losing
+     * the focus.
+     * So we only copy the focus class if the device didn't have one,
+     * otherwise we leave it as it is.
+     */
+    if (from->focus)
+    {
+        if (!to->focus)
+        {
+            WindowPtr *oldTrace;
+
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->focus = classes->focus;
+            if (!to->focus)
+            {
+                to->focus = xcalloc(1, sizeof(FocusClassRec));
+                if (!to->focus)
+                    FatalError("[Xi] no memory for class shift.\n");
+            } else
+                classes->focus = NULL;
+
+            oldTrace = to->focus->trace;
+            memcpy(to->focus, from->focus, sizeof(FocusClassRec));
+            to->focus->trace = xrealloc(oldTrace,
+                                  to->focus->traceSize * sizeof(WindowPtr));
+            if (!to->focus->trace && to->focus->traceSize)
+                FatalError("[Xi] no memory for trace.\n");
+            memcpy(to->focus->trace, from->focus->trace,
+                    from->focus->traceSize * sizeof(WindowPtr));
+        }
+    } else if (to->focus)
+    {
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->focus = to->focus;
+        to->focus      = NULL;
+    }
+
+}
+
+static void
+DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
+{
+    ClassesPtr classes;
+
+    /* Feedback classes must be copied first */
+    if (from->ptrfeed)
+    {
+        PtrFeedbackPtr *p, it;
+        if (!to->ptrfeed)
+        {
+            classes = dixLookupPrivate(&to->devPrivates,
+                                       UnusedClassesPrivateKey);
+            to->ptrfeed = classes->ptrfeed;
+        }
+
+        p = &to->ptrfeed;
+        for (it = from->ptrfeed; it; it = it->next)
+        {
+            if (!(*p))
+            {
+                *p = xcalloc(1, sizeof(PtrFeedbackClassRec));
+                if (!*p)
+                {
+                    ErrorF("[Xi] Cannot alloc memory for class copy.");
+                    return;
+                }
+            }
+            (*p)->CtrlProc = it->CtrlProc;
+            (*p)->ctrl     = it->ctrl;
+
+            p = &(*p)->next;
+        }
+    } else if (to->ptrfeed && !from->ptrfeed)
+    {
+        ClassesPtr classes;
+        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+        classes->ptrfeed = to->ptrfeed;
+        to->ptrfeed      = NULL;
+    }
+
     if (from->valuator)
     {
         ValuatorClassPtr v;
@@ -552,47 +590,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
         to->button      = NULL;
     }
 
-
-    /* We can't just copy over the focus class. When an app sets the focus,
-     * it'll do so on the master device. Copying the SDs focus means losing
-     * the focus.
-     * So we only copy the focus class if the device didn't have one,
-     * otherwise we leave it as it is.
-     */
-    if (from->focus)
-    {
-        if (!to->focus)
-        {
-            WindowPtr *oldTrace;
-
-            classes = dixLookupPrivate(&to->devPrivates,
-                                       UnusedClassesPrivateKey);
-            to->focus = classes->focus;
-            if (!to->focus)
-            {
-                to->focus = xcalloc(1, sizeof(FocusClassRec));
-                if (!to->focus)
-                    FatalError("[Xi] no memory for class shift.\n");
-            } else
-                classes->focus = NULL;
-
-            oldTrace = to->focus->trace;
-            memcpy(to->focus, from->focus, sizeof(FocusClassRec));
-            to->focus->trace = xrealloc(oldTrace,
-                                  to->focus->traceSize * sizeof(WindowPtr));
-            if (!to->focus->trace && to->focus->traceSize)
-                FatalError("[Xi] no memory for trace.\n");
-            memcpy(to->focus->trace, from->focus->trace,
-                    from->focus->traceSize * sizeof(WindowPtr));
-        }
-    } else if (to->focus)
-    {
-        ClassesPtr classes;
-        classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
-        classes->focus = to->focus;
-        to->focus      = NULL;
-    }
-
     if (from->proximity)
     {
         if (!to->proximity)
@@ -643,6 +640,27 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
 }
 
 /**
+ * Copies the CONTENT of the classes of device from into the classes in device
+ * to. From and to are identical after finishing.
+ *
+ * If to does not have classes from currenly has, the classes are stored in
+ * to's devPrivates system. Later, we recover it again from there if needed.
+ * Saves a few memory allocations.
+ */
+void
+DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce)
+{
+    /* generic feedback classes, not tied to pointer and/or keyboard */
+    DeepCopyFeedbackClasses(from, to);
+
+    if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT))
+        DeepCopyKeyboardClasses(from, to);
+    if ((dce->flags & DEVCHANGE_POINTER_EVENT))
+        DeepCopyPointerClasses(from, to);
+}
+
+
+/**
  * Change MD to look like SD by copying all classes over. An event is sent to
  * all interested clients.
  * @param device The slave device
@@ -727,10 +745,14 @@ ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
     if (!master) /* if device was set floating between SIGIO and now */
         return;
 
+
+    master = GetMaster(device,
+             (dce->flags & DEVCHANGE_POINTER_EVENT) ? MASTER_POINTER : MASTER_KEYBOARD);
+
     master->public.devicePrivate = device->public.devicePrivate;
 
     /* FIXME: the classes may have changed since we generated the event. */
-    DeepCopyDeviceClasses(device, master);
+    DeepCopyDeviceClasses(device, master, dce);
     XISendDeviceChangedEvent(device, master, dce);
 }
 
diff --git a/dix/devices.c b/dix/devices.c
index c94e935..6266b63 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2320,7 +2320,8 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
             /* XXX: reset master back to defaults */
             event = InitEventList(1);
             SetMinimumEventSize(event, 1, sizeof(DeviceChangedEvent));
-            CreateClassesChangedEvent(event, oldmaster, oldmaster);
+            CreateClassesChangedEvent(event, oldmaster, oldmaster,
+                                      DEVCHANGE_POINTER_EVENT | DEVCHANGE_KEYBOARD_EVENT);
             XISendDeviceChangedEvent(oldmaster, oldmaster,
                                      (DeviceChangedEvent*)event->event);
             FreeEventList(event, 1);
diff --git a/dix/getevents.c b/dix/getevents.c
index 40cf4ca..fa3c781 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -187,7 +187,8 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator,
 void
 CreateClassesChangedEvent(EventList* event,
                           DeviceIntPtr master,
-                          DeviceIntPtr slave)
+                          DeviceIntPtr slave,
+                          int type)
 {
     int i;
     DeviceChangedEvent *dce;
@@ -200,6 +201,7 @@ CreateClassesChangedEvent(EventList* event,
     dce->length = sizeof(DeviceChangedEvent);
     dce->type = ET_DeviceChanged;
     dce->time = ms;
+    dce->flags = type;
     if (master->last.slave)
     {
         dce->flags |= DEVCHANGE_HAS_OLD_SLAVE;
@@ -605,12 +607,13 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
  *
  * @param events Pointer to a pre-allocated event list.
  * @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.
  */
 static EventListPtr
-updateFromMaster(EventListPtr events, DeviceIntPtr dev, int *num_events)
+updateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
 {
     DeviceIntPtr master;
 
@@ -618,7 +621,7 @@ updateFromMaster(EventListPtr events, DeviceIntPtr dev, int *num_events)
 
     if (master && master->last.slave != dev)
     {
-        CreateClassesChangedEvent(events, master, dev);
+        CreateClassesChangedEvent(events, master, dev, type);
         updateSlaveDeviceCoords(master, dev);
         master->last.slave = dev;
         master->last.numValuators = dev->last.numValuators;
@@ -852,7 +855,7 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     num_events = 1;
 
-    events = updateFromMaster(events, pDev, &num_events);
+    events = updateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
 
     /* Handle core repeating, via press/release/press/release. */
     if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
@@ -1021,7 +1024,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         (type == MotionNotify && num_valuators <= 0))
         return 0;
 
-    events = updateFromMaster(events, pDev, &num_events);
+    events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
     raw = (RawDeviceEvent*)events->event;
     events++;
@@ -1134,7 +1137,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
         (num_valuators + first_valuator) > pDev->valuator->numAxes)
         return 0;
 
-    events = updateFromMaster(events, pDev, &num_events);
+    events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
     event = (DeviceEvent *) events->event;
     init_event(pDev, event, GetTimeInMillis());
diff --git a/include/events.h b/include/events.h
index cc5092e..d44188b 100644
--- a/include/events.h
+++ b/include/events.h
@@ -115,6 +115,10 @@ typedef struct
 /* Flags used in DeviceChangedEvent to signal if new/old slave is present. */
 #define DEVCHANGE_HAS_OLD_SLAVE 0x1
 #define DEVCHANGE_HAS_NEW_SLAVE 0x2
+/* Flags used in DeviceChangedEvent to signal whether the event was a
+ * pointer event or a keyboard event */
+#define DEVCHANGE_POINTER_EVENT 0x4
+#define DEVCHANGE_KEYBOARD_EVENT 0x8
 
 /**
  * Sent whenever a device's capabilities have changed.
@@ -126,7 +130,8 @@ typedef struct
     int length;           /**< Length in bytes */
     Time time;            /**< Time in ms */
     int deviceid;         /**< Device whose capabilities have changed */
-    int flags;            /**< Mask of ::HAS_OLD_SLAVE or ::HAS_NEW_SLAVE */
+    int flags;            /**< Mask of ::HAS_OLD_SLAVE, ::HAS_NEW_SLAVE,
+                               ::POINTER_EVENT, ::KEYBOARD_EVENT */
     /** If flags & HAS_OLD_SLAVE is set, old_slaveid specifies SD previously
      * attached to this device. */
     int old_slaveid;
diff --git a/include/input.h b/include/input.h
index 194dbeb..437b392 100644
--- a/include/input.h
+++ b/include/input.h
@@ -412,7 +412,8 @@ extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events);
 
 extern void CreateClassesChangedEvent(EventListPtr event,
                                       DeviceIntPtr master,
-                                      DeviceIntPtr slave);
+                                      DeviceIntPtr slave,
+                                      int type);
 extern int GetPointerEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
@@ -480,7 +481,8 @@ extern int AllocDevicePair(ClientPtr client,
                              DeviceIntPtr* keybd,
                              Bool master);
 extern void DeepCopyDeviceClasses(DeviceIntPtr from,
-                                  DeviceIntPtr to);
+                                  DeviceIntPtr to,
+                                  DeviceChangedEvent *dce);
 
 /* Helper functions. */
 extern int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
diff --git a/mi/mi.h b/mi/mi.h
index 182cea5..4431239 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -221,11 +221,10 @@ extern _X_EXPORT void mieqProcessInputEvents(
     void
 );
 
-extern void CopyGetMasterEvent(
-    DeviceIntPtr /* mdev */,
+extern DeviceIntPtr CopyGetMasterEvent(
     DeviceIntPtr /* sdev */,
     InternalEvent* /* original */,
-    EventListPtr /* master */
+    EventListPtr /* mlist */
 );
 
 /**
diff --git a/mi/mieq.c b/mi/mieq.c
index d094e13..7ba755c 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -307,28 +307,53 @@ FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev,
 
 /**
  * Copy the given event into master.
- * @param mdev The master device
  * @param sdev The slave device the original event comes from
  * @param original The event as it came from the EQ
  * @param master The event after being copied
+ * @return The master device or NULL if the device is a floating slave.
  */
-void
-CopyGetMasterEvent(DeviceIntPtr mdev, DeviceIntPtr sdev,
-                   InternalEvent* original, EventListPtr master)
+DeviceIntPtr
+CopyGetMasterEvent(DeviceIntPtr sdev,
+                   InternalEvent* original, EventListPtr mlist)
 {
+    DeviceIntPtr mdev;
     int len = original->any.length;
     InternalEvent *mevent;
 
     CHECKEVENT(original);
 
-    if (master->evlen < len)
-        SetMinimumEventSize(master, 1, len);
+    if (!sdev->u.master)
+        return NULL;
+
+    switch(original->any.type)
+    {
+        case ET_KeyPress:
+        case ET_KeyRelease:
+            mdev = GetMaster(sdev, MASTER_KEYBOARD);
+            break;
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_Motion:
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            mdev = GetMaster(sdev, MASTER_POINTER);
+            break;
+        default:
+            mdev = sdev->u.master;
+            break;
+    }
+
+
+    if (mlist->evlen < len)
+        SetMinimumEventSize(mlist, 1, len);
 
-    mevent = (InternalEvent*)master->event;
+    mevent = (InternalEvent*)mlist->event;
 
     memcpy(mevent, original, len);
     ChangeDeviceID(mdev, mevent);
     FixUpEventForMaster(mdev, sdev, original, mevent);
+
+    return mdev;
 }
 
 
@@ -359,10 +384,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
         NewCurrentScreen (dev, DequeueScreen(dev), x, y);
     }
     else {
-        master  = (!IsMaster(dev) && dev->u.master) ? dev->u.master : NULL;
-
-        if (master)
-            CopyGetMasterEvent(master, dev, event, masterEvents);
+        master = CopyGetMasterEvent(dev, event, masterEvents);
 
         /* If someone's registered a custom event handler, let them
          * steal it. */
commit bc63c8a4570c989f19a036965854bceb9800ce19
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 12:33:49 2009 +1000

    dix: introduce GetMaster()
    
    For hybrid devices (keys + buttons/axes) the attached master device is
    generally the wrong one. One shouldn't post a button event through a
    keyboard and vice versa.
    
    GetMaster(dev) returns the right master device for the given type needed.
    This may be the MD paired with this device's MD.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/devices.c b/dix/devices.c
index 3d0d30d..c94e935 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2346,6 +2346,41 @@ GetPairedDevice(DeviceIntPtr dev)
 
 
 /**
+ * Returns the right master for the type of event needed. If the event is a
+ * keyboard event.
+ * This function may be called with a master device as argument. If so, the
+ * returned master is either the device itself or the paired master device.
+ * If dev is a floating slave device, NULL is returned.
+ *
+ * @type ::MASTER_KEYBOARD or ::MASTER_POINTER
+ */
+DeviceIntPtr
+GetMaster(DeviceIntPtr dev, int which)
+{
+    DeviceIntPtr master;
+
+    if (IsMaster(dev))
+        master = dev;
+    else
+        master = dev->u.master;
+
+    if (master)
+    {
+        if (which == MASTER_KEYBOARD)
+        {
+            if (master->type != MASTER_KEYBOARD)
+                master = GetPairedDevice(master);
+        } else
+        {
+            if (master->type != MASTER_POINTER)
+                master = GetPairedDevice(master);
+        }
+    }
+
+    return master;
+}
+
+/**
  * Create a new device pair (== one pointer, one keyboard device).
  * Only allocates the devices, you will need to call ActivateDevice() and
  * EnableDevice() manually.
diff --git a/dix/getevents.c b/dix/getevents.c
index ff249c8..40cf4ca 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -612,7 +612,10 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
 static EventListPtr
 updateFromMaster(EventListPtr events, DeviceIntPtr dev, int *num_events)
 {
-    DeviceIntPtr master = dev->u.master;
+    DeviceIntPtr master;
+
+    master = GetMaster(dev, (type & DEVCHANGE_POINTER_EVENT) ?  MASTER_POINTER : MASTER_KEYBOARD);
+
     if (master && master->last.slave != dev)
     {
         CreateClassesChangedEvent(events, master, dev);
@@ -793,8 +796,10 @@ updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms)
 {
     updateMotionHistory(dev, ms, first, num, &dev->last.valuators[first]);
     if (dev->u.master)
-        updateMotionHistory(dev->u.master, ms, first, num,
-                            &dev->last.valuators[first]);
+    {
+        DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
+        updateMotionHistory(master, ms, first, num, &dev->last.valuators[first]);
+    }
 }
 
 /**
diff --git a/include/input.h b/include/input.h
index 44990a0..194dbeb 100644
--- a/include/input.h
+++ b/include/input.h
@@ -472,6 +472,7 @@ extern int AttachDevice(ClientPtr client,
                         DeviceIntPtr master);
 
 extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
+extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
 
 extern int AllocDevicePair(ClientPtr client,
                              char* name,
commit d79318f269d959d566ec66239b4c985afd61b259
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 21 08:29:14 2009 +1000

    dix: Add a deviceid to the DeviceChangedEvent.
    
    ChangeDeviceId would actually overwrite the flags field if deviceid wasn't
    present. Aside from the event of course not telling which device generated
    it in the first place.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 5ff4f91..ff249c8 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -195,6 +195,7 @@ CreateClassesChangedEvent(EventList* event,
 
     dce = (DeviceChangedEvent*)event->event;
     memset(dce, 0, sizeof(DeviceChangedEvent));
+    dce->deviceid = master->id;
     dce->header = ET_Internal;
     dce->length = sizeof(DeviceChangedEvent);
     dce->type = ET_DeviceChanged;
diff --git a/include/events.h b/include/events.h
index ab8f217..cc5092e 100644
--- a/include/events.h
+++ b/include/events.h
@@ -125,6 +125,7 @@ typedef struct
     int type;             /**< ET_DeviceChanged */
     int length;           /**< Length in bytes */
     Time time;            /**< Time in ms */
+    int deviceid;         /**< Device whose capabilities have changed */
     int flags;            /**< Mask of ::HAS_OLD_SLAVE or ::HAS_NEW_SLAVE */
     /** If flags & HAS_OLD_SLAVE is set, old_slaveid specifies SD previously
      * attached to this device. */
commit eeffb83fea2d87070beafd0c692fb0ad54d8335b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 18 20:03:07 2009 +1000

    ABI_XINPUT_VERSION 6

diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index cbba3ed..993e297 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -83,7 +83,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(5, 0)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(5, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(6, 0)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(2, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
commit 438a4eafa5d14ab676827f7a5d58782c02db4cdf
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 17:02:50 2009 +1000

    input: remove nested union from InternalEvent.
    
    There's no need for internal events to be a struct with a single nested
    union, we might as well make the union itself the InternalEvent.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index d7fb599..884fe72 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -123,7 +123,7 @@ RegisterOtherDevice(DeviceIntPtr device)
 Bool
 IsPointerEvent(InternalEvent* event)
 {
-    switch(event->u.any.type)
+    switch(event->any.type)
     {
         case ET_ButtonPress:
         case ET_ButtonRelease:
@@ -953,7 +953,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
 
     CHECKEVENT(ev);
 
-    if (ev->u.any.type == ET_Raw)
+    if (ev->any.type == ET_Raw)
     {
         ProcessRawEvent((RawDeviceEvent*)ev, device);
         return;
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 97fc2ad..403282c 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -69,7 +69,7 @@ static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
 int
 EventToCore(InternalEvent *event, xEvent *core)
 {
-    switch(event->u.any.type)
+    switch(event->any.type)
     {
         case ET_Motion:
         case ET_ButtonPress:
@@ -117,7 +117,7 @@ EventToCore(InternalEvent *event, xEvent *core)
 int
 EventToXI(InternalEvent *ev, xEvent **xi, int *count)
 {
-    switch (ev->u.any.type)
+    switch (ev->any.type)
     {
         case ET_Motion:
         case ET_ButtonPress:
@@ -134,7 +134,7 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
             return Success;
     }
 
-    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->u.any.type);
+    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
     return BadImplementation;
 }
 
@@ -153,7 +153,7 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
 int
 EventToXI2(InternalEvent *ev, xEvent **xi)
 {
-    switch (ev->u.any.type)
+    switch (ev->any.type)
     {
         case ET_Motion:
         case ET_ButtonPress:
@@ -172,7 +172,7 @@ EventToXI2(InternalEvent *ev, xEvent **xi)
 
     }
 
-    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->u.any.type);
+    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
     return BadImplementation;
 }
 
@@ -472,7 +472,7 @@ int
 GetCoreType(InternalEvent *event)
 {
     int coretype = 0;
-    switch(event->u.any.type)
+    switch(event->any.type)
     {
         case ET_Motion:         coretype = MotionNotify;  break;
         case ET_ButtonPress:    coretype = ButtonPress;   break;
@@ -491,7 +491,7 @@ int
 GetXIType(InternalEvent *event)
 {
     int xitype = 0;
-    switch(event->u.any.type)
+    switch(event->any.type)
     {
         case ET_Motion:         xitype = DeviceMotionNotify;  break;
         case ET_ButtonPress:    xitype = DeviceButtonPress;   break;
@@ -513,7 +513,7 @@ GetXI2Type(InternalEvent *event)
 {
     int xi2type = 0;
 
-    switch(event->u.any.type)
+    switch(event->any.type)
     {
         case ET_Motion:         xi2type = XI_Motion;           break;
         case ET_ButtonPress:    xi2type = XI_ButtonPress;      break;
diff --git a/dix/events.c b/dix/events.c
index 3222950..8400cfa 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1075,18 +1075,18 @@ MonthChangedOrBadTime(InternalEvent *ev)
      * different sources in sorted order, then it's possible for time to go
      * backwards when it should not.  Here we ensure a decent time.
      */
-    if ((currentTime.milliseconds - ev->u.any.time) > TIMESLOP)
+    if ((currentTime.milliseconds - ev->any.time) > TIMESLOP)
 	currentTime.months++;
     else
-        ev->u.any.time = currentTime.milliseconds;
+        ev->any.time = currentTime.milliseconds;
 }
 
 static void
 NoticeTime(InternalEvent *ev)
 {
-    if (ev->u.any.time < currentTime.milliseconds)
+    if (ev->any.time < currentTime.milliseconds)
         MonthChangedOrBadTime(ev);
-    currentTime.milliseconds = ev->u.any.time;
+    currentTime.milliseconds = ev->any.time;
     lastDeviceEventTime = currentTime;
 }
 
@@ -1158,7 +1158,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
 	pSprite->hotPhys.y = event->root_y;
 	/* do motion compression, but not if from different devices */
 	if (tail &&
-	    (tail->event->u.any.type == ET_Motion) &&
+	    (tail->event->any.type == ET_Motion) &&
             (tail->device == device) &&
 	    (tail->pScreen == pSprite->hotPhys.pScreen))
 	{
@@ -1212,10 +1212,10 @@ PlayReleasedEvents(void)
             pDev = qe->device;
 	    if (*syncEvents.pendtail == *prev)
 		syncEvents.pendtail = prev;
-	    if (qe->event->u.any.type == ET_Motion)
+	    if (qe->event->any.type == ET_Motion)
 		CheckVirtualMotion(pDev, qe, NullWindow);
 	    syncEvents.time.months = qe->months;
-            syncEvents.time.milliseconds = qe->event->u.any.time;
+            syncEvents.time.milliseconds = qe->event->any.time;
 #ifdef PANORAMIX
 	   /* Translate back to the sprite screen since processInputProc
 	      will translate from sprite screen to screen 0 upon reentry
@@ -2391,7 +2391,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
     if (rc != Success)
     {
         ErrorF("[dix] %s: XI conversion failed in DDE (%d, %d). Skipping delivery.\n",
-               dev->name, event->u.any.type, rc);
+               dev->name, event->any.type, rc);
         goto unwind;
     } else if (count > 0)
     {
@@ -2444,7 +2444,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                 {
                     if (rc != BadMatch)
                         ErrorF("[dix] %s: Core conversion failed in DDE (%d, %d).\n",
-                                dev->name, event->u.any.type, rc);
+                                dev->name, event->any.type, rc);
                     goto unwind;
                 }
 
@@ -3581,7 +3581,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     if (rc != Success)
     {
         ErrorF("[dix] %s: XI conversion failed in DFE (%d, %d). Skipping delivery.\n",
-               keybd->name, event->u.any.type, rc);
+               keybd->name, event->any.type, rc);
         goto unwind;
     } else if (count == 0) /* no XI/Core event for you */
         return;
@@ -3593,7 +3593,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     if (rc != Success)
     {
         ErrorF("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n",
-               keybd->name, event->u.any.type, rc);
+               keybd->name, event->any.type, rc);
         goto unwind;
     } else if (xi2)
     {
@@ -3621,7 +3621,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
         if (rc != Success)
         {
             ErrorF("[dix] %s: core conversion failed DFE (%d, %d). Skipping delivery.\n",
-                    keybd->name, event->u.any.type, rc);
+                    keybd->name, event->any.type, rc);
             goto unwind;
         }
 
@@ -3706,7 +3706,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
         if (rc != Success)
         {
             ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n",
-                    thisDev->name, event->u.any.type, rc);
+                    thisDev->name, event->any.type, rc);
             goto unwind;
         }
 
@@ -3714,7 +3714,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
         if (rc != Success)
         {
             ErrorF("[dix] %s: XI conversion failed in DGE (%d, %d). Skipping delivery.\n",
-                    thisDev->name, event->u.any.type, rc);
+                    thisDev->name, event->any.type, rc);
             goto unwind;
         } else if (count == 0) /* no XI/Core event for you */
             goto unwind;
@@ -3789,10 +3789,10 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 
         }
 
-        if (deliveries && (event->u.any.type == ET_Motion))
+        if (deliveries && (event->any.type == ET_Motion))
             thisDev->valuator->motionHintWindow = grab->window;
     }
-    if (deliveries && !deactivateGrab && event->u.any.type != ET_Motion)
+    if (deliveries && !deactivateGrab && event->any.type != ET_Motion)
     {
 	switch (grabinfo->sync.state)
 	{
diff --git a/include/events.h b/include/events.h
index 8719320..ab8f217 100644
--- a/include/events.h
+++ b/include/events.h
@@ -63,9 +63,9 @@ enum {
     ET_Internal = 0xFF /* First byte */
 } EventType;
 
-#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->u.any.header != 0xFF) \
+#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->any.header != 0xFF) \
                           FatalError("Wrong event type %d.\n", \
-                                     ((InternalEvent*)(ev))->u.any.header);
+                                     ((InternalEvent*)(ev))->any.header);
 
 /**
  * Used for ALL input device events internal in the server until
@@ -204,9 +204,7 @@ typedef struct
  * Event type used inside the X server for input event
  * processing.
  */
-typedef struct
-{
-    union {
+typedef union {
         struct {
             unsigned char header; /**< Always ET_Internal */
             int type;             /**< One of ET_* */
@@ -219,7 +217,6 @@ typedef struct
         DGAEvent dga;
 #endif
         RawDeviceEvent raw;
-    } u;
 } InternalEvent;
 
 #endif
diff --git a/mi/mieq.c b/mi/mieq.c
index e2f18e2..d094e13 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -165,7 +165,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
     CHECKEVENT(e);
 
     /* avoid merging events from different devices */
-    if (e->u.any.type == ET_Motion)
+    if (e->any.type == ET_Motion)
         isMotion = pDev->id;
 
     if (isMotion && isMotion == miEventQueue.lastMotion &&
@@ -192,7 +192,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
 	stuck = 0;
     }
 
-    evlen = e->u.any.length;
+    evlen = e->any.length;
     evt = miEventQueue.events[oldtail].events;
     if (evt->evlen < evlen)
     {
@@ -210,14 +210,14 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
 
     memcpy(evt->event, e, evlen);
 
-    time = e->u.any.time;
+    time = e->any.time;
     /* Make sure that event times don't go backwards - this
      * is "unnecessary", but very useful. */
     if (time < miEventQueue.lastEventTime &&
         miEventQueue.lastEventTime - time < 10000)
-        e->u.any.time = miEventQueue.lastEventTime;
+        e->any.time = miEventQueue.lastEventTime;
 
-    miEventQueue.lastEventTime = ((InternalEvent*)evt->event)->u.any.time;
+    miEventQueue.lastEventTime = ((InternalEvent*)evt->event)->any.time;
     miEventQueue.events[oldtail].pScreen = EnqueueScreen(pDev);
     miEventQueue.events[oldtail].pDev = pDev;
 
@@ -264,7 +264,7 @@ mieqSetHandler(int event, mieqHandler handler)
 static void
 ChangeDeviceID(DeviceIntPtr dev, InternalEvent* event)
 {
-    switch(event->u.any.type)
+    switch(event->any.type)
     {
         case ET_Motion:
         case ET_KeyPress:
@@ -275,14 +275,14 @@ ChangeDeviceID(DeviceIntPtr dev, InternalEvent* event)
         case ET_ProximityOut:
         case ET_Hierarchy:
         case ET_DeviceChanged:
-            event->u.device.deviceid = dev->id;
+            event->device.deviceid = dev->id;
             break;
         case ET_Raw:
-            event->u.raw.deviceid = dev->id;
+            event->raw.deviceid = dev->id;
             break;
         default:
             ErrorF("[mi] Unknown event type (%d), cannot change id.\n",
-                   event->u.any.type);
+                   event->any.type);
     }
 }
 
@@ -294,14 +294,14 @@ FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev,
     CHECKEVENT(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->u.any.type == ET_ButtonPress ||
-        original->u.any.type == ET_ButtonRelease)
+    if (original->any.type == ET_ButtonPress ||
+        original->any.type == ET_ButtonRelease)
     {
-        int btn = original->u.device.detail.button;
+        int btn = original->device.detail.button;
         if (!sdev->button)
             return; /* Should never happen */
 
-        master->u.device.detail.button = sdev->button->map[btn];
+        master->device.detail.button = sdev->button->map[btn];
     }
 }
 
@@ -316,7 +316,7 @@ void
 CopyGetMasterEvent(DeviceIntPtr mdev, DeviceIntPtr sdev,
                    InternalEvent* original, EventListPtr master)
 {
-    int len = original->u.any.length;
+    int len = original->any.length;
     InternalEvent *mevent;
 
     CHECKEVENT(original);
@@ -349,13 +349,13 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
     CHECKEVENT(event);
 
     /* Custom event handler */
-    handler = miEventQueue.handlers[event->u.any.type];
+    handler = miEventQueue.handlers[event->any.type];
 
     if (screen && screen != DequeueScreen(dev) && !handler) {
         /* Assumption - screen switching can only occur on motion events. */
         DequeueScreen(dev) = screen;
-        x = event->u.device.root_x;
-        y = event->u.device.root_y;
+        x = event->device.root_x;
+        y = event->device.root_y;
         NewCurrentScreen (dev, DequeueScreen(dev), x, y);
     }
     else {
@@ -441,7 +441,7 @@ mieqProcessInputEvents(void)
         mieqProcessDeviceEvent(dev, event, screen);
 
         /* Update the sprite now. Next event may be from different device. */
-        if (event->u.any.type == ET_Motion && master)
+        if (event->any.type == ET_Motion && master)
             miPointerUpdateSprite(dev);
 
 #ifdef XQUARTZ
commit b12d302df8283186ce87882c29b2b0294adb2770
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 15:28:16 2009 +1000

    Input: rename DeviceIntRec->isMaster to ->type.
    
    isMaster is not enough as long as we differ between master pointers and
    keyboard. With flexible device classes, the usual checks for whether a
    master device is a pointer (currently check for ->button, ->valuators or
    ->key) do not work as an SD may post an event through a master and mess this
    check up.
    
    Example, a device with valuators but no buttons would remove the button
    class from the VCP and thus result in the
    IsPointerDevice(inputInfo.pointer) == FALSE.
    
    This will become worse in the future when new device classes are introduced
    that aren't provided in the current system (e.g. a switch class).
    
    This patch replaces isMaster with "type", one of SLAVE, MASTER_POINTER and
    MASTER_KEYBOARD. All checks for dev->isMaster are replaced with an
    IsMaster(dev).

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 96380b7..32abe2a 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -303,7 +303,7 @@ ProcXTestFakeInput(ClientPtr client)
          * virtual test device.
          */
         for(it = inputInfo.devices; it ; it = it->next )
-            if( !it->isMaster && it->u.master == dev &&
+            if( !IsMaster(it) && it->u.master == dev &&
                     dixLookupPrivate(&it->devPrivates, XTstDevicePrivateKey ))
                 break;
         dev= it;
diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
index e59bfab..927df55 100644
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@ -243,7 +243,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                     if (rc != Success)
                         goto unwind;
 
-                    if (!ptr->isMaster)
+                    if (!IsMaster(ptr))
                     {
                         client->errorValue = r->deviceid;
                         rc = BadDevice;
@@ -259,7 +259,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                     }
 
                     for(xtstdevice = inputInfo.devices; xtstdevice ; xtstdevice = xtstdevice->next )
-                        if( !xtstdevice->isMaster && xtstdevice->u.master == ptr &&
+                        if( !IsMaster(xtstdevice) && xtstdevice->u.master == ptr &&
                             dixLookupPrivate(&xtstdevice->devPrivates, XTstDevicePrivateKey ))
                             break;
 
@@ -296,7 +296,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                     {
                         /* Search the matching keyboard */
                         for(xtstdevice = inputInfo.devices; xtstdevice ; xtstdevice = xtstdevice->next )
-                            if( !xtstdevice->isMaster &&
+                            if( !IsMaster(xtstdevice) &&
                                 xtstdevice->u.master == keybd &&
                                 IsKeyboardDevice(xtstdevice) &&
                                 dixLookupPrivate(&xtstdevice->devPrivates, XTstDevicePrivateKey ))
@@ -315,7 +315,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                         xtstkeybd = xtstptr;
                         /* Search the matching pointer */
                         for(xtstdevice = inputInfo.devices; xtstdevice ; xtstdevice = xtstdevice->next )
-                            if( !xtstdevice->isMaster &&
+                            if( !IsMaster(xtstdevice) &&
                                 xtstdevice->u.master == ptr &&
                                 IsPointerDevice(xtstdevice) &&
                                 dixLookupPrivate(&xtstdevice->devPrivates, XTstDevicePrivateKey )
@@ -343,7 +343,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                         if (rc != Success)
                             goto unwind;
 
-                        if (!newptr->isMaster)
+                        if (!IsMaster(newptr))
                         {
                             client->errorValue = r->return_pointer;
                             rc = BadDevice;
@@ -355,7 +355,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                         if (rc != Success)
                             goto unwind;
 
-                        if (!newkeybd->isMaster)
+                        if (!IsMaster(newkeybd))
                         {
                             client->errorValue = r->return_keyboard;
                             rc = BadDevice;
@@ -366,7 +366,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                                 attached;
                                 attached = attached->next)
                         {
-                            if (!attached->isMaster) {
+                            if (!IsMaster(attached)) {
                                 if (attached->u.master == ptr)
                                 {
                                     AttachDevice(client, attached, newptr);
@@ -418,7 +418,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                     if (rc != Success)
                        goto unwind;
 
-                    if (ptr->isMaster)
+                    if (IsMaster(ptr))
                     {
                         client->errorValue = c->deviceid;
                         rc = BadDevice;
@@ -451,7 +451,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                     if (rc != Success)
                        goto unwind;
 
-                    if (ptr->isMaster)
+                    if (IsMaster(ptr))
                     {
                         client->errorValue = c->deviceid;
                         rc = BadDevice;
@@ -473,7 +473,7 @@ ProcXIChangeHierarchy(ClientPtr client)
                             client, DixWriteAccess);
                     if (rc != Success)
                         goto unwind;
-                    if (!newmaster->isMaster)
+                    if (!IsMaster(newmaster))
                     {
                         client->errorValue = c->new_master;
                         rc = BadDevice;
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 04a4fbd..d7fb599 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -721,7 +721,7 @@ ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
 {
     DeviceIntPtr master = device->u.master;
 
-    if (device->isMaster)
+    if (IsMaster(device))
         return;
 
     if (!master) /* if device was set floating between SIGIO and now */
@@ -866,7 +866,7 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
         kptr = &b->down[key>>3];
         if (!(*kptr & bit))
             return DONT_PROCESS;
-        if (device->isMaster) {
+        if (IsMaster(device)) {
             DeviceIntPtr sd;
 
             /*
@@ -875,7 +875,7 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
              * event being delivered through the slave first
              */
             for (sd = inputInfo.devices; sd; sd = sd->next) {
-                if (sd->isMaster || sd->u.master != device)
+                if (IsMaster(sd) || sd->u.master != device)
                     continue;
                 if (!sd->button)
                     continue;
@@ -1007,7 +1007,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
     b = device->button;
     k = device->key;
 
-    if (device->isMaster || !device->u.master)
+    if (IsMaster(device) || !device->u.master)
         CheckMotion(event, device);
 
     switch (event->type)
@@ -1201,7 +1201,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     DeviceIntPtr mouse;
     int btlen, len, i;
 
-    mouse = (dev->isMaster || dev->u.master) ? GetPairedDevice(dev) : NULL;
+    mouse = (IsMaster(dev) || dev->u.master) ? GetPairedDevice(dev) : NULL;
 
     /* XI 2 event */
     btlen = (mouse->button) ? (mouse->button->numButtons + 7)/8 : 0;
diff --git a/Xi/listdev.c b/Xi/listdev.c
index 294fec9..95c1532 100644
--- a/Xi/listdev.c
+++ b/Xi/listdev.c
@@ -177,9 +177,9 @@ CopySwapDevice(ClientPtr client, DeviceIntPtr d, int num_classes,
     dev->id = d->id;
     dev->type = d->xinput_type;
     dev->num_classes = num_classes;
-    if (d->isMaster && IsKeyboardDevice(d))
+    if (IsMaster(d) && IsKeyboardDevice(d))
 	dev->use = IsXKeyboard;
-    else if (d->isMaster && IsPointerDevice(d))
+    else if (IsMaster(d) && IsPointerDevice(d))
 	dev->use = IsXPointer;
     else if (d->key && d->kbdfeed)
         dev->use = IsXExtensionKeyboard;
@@ -344,7 +344,7 @@ ProcXListInputDevices(ClientPtr client)
     AddOtherInputDevices();
 
     for (d = inputInfo.devices; d; d = d->next) {
-        if (d->isMaster &&
+        if (IsMaster(d) &&
                 d != inputInfo.pointer &&
                 d != inputInfo.keyboard)
             continue; /* don't send master devices other than VCP/VCK */
@@ -357,7 +357,7 @@ ProcXListInputDevices(ClientPtr client)
     }
 
     for (d = inputInfo.off_devices; d; d = d->next) {
-        if (d->isMaster &&
+        if (IsMaster(d) &&
                 d != inputInfo.pointer &&
                 d != inputInfo.keyboard)
             continue; /* don't send master devices other than VCP/VCK */
@@ -378,7 +378,7 @@ ProcXListInputDevices(ClientPtr client)
     dev = (xDeviceInfoPtr) devbuf;
     for (d = inputInfo.devices; d; d = d->next)
     {
-        if (d->isMaster &&
+        if (IsMaster(d) &&
                 d != inputInfo.pointer &&
                 d != inputInfo.keyboard)
             continue; /* don't count master devices other than VCP/VCK */
@@ -388,7 +388,7 @@ ProcXListInputDevices(ClientPtr client)
 
     for (d = inputInfo.off_devices; d; d = d->next)
     {
-        if (d->isMaster &&
+        if (IsMaster(d) &&
                 d != inputInfo.pointer &&
                 d != inputInfo.keyboard)
             continue; /* don't count master devices other than VCP/VCK */
diff --git a/Xi/opendev.c b/Xi/opendev.c
index 4ad5af2..46d55a8 100644
--- a/Xi/opendev.c
+++ b/Xi/opendev.c
@@ -112,7 +112,7 @@ ProcXOpenDevice(ClientPtr client)
     } else if (status != Success)
 	return status;
 
-    if (dev->isMaster)
+    if (IsMaster(dev))
             return BadDevice;
 
     OpenInputDevice(dev, client, &status);
diff --git a/Xi/querydev.c b/Xi/querydev.c
index b50d038..d881b76 100644
--- a/Xi/querydev.c
+++ b/Xi/querydev.c
@@ -88,14 +88,14 @@ ProcXIQueryDevice(ClientPtr client)
         for (dev = inputInfo.devices; dev; dev = dev->next)
         {
             if (stuff->deviceid == XIAllDevices ||
-                (stuff->deviceid == XIAllMasterDevices && dev->isMaster))
+                (stuff->deviceid == XIAllMasterDevices && IsMaster(dev)))
                 len += SizeDeviceInfo(dev);
         }
 
         for (dev = inputInfo.off_devices; dev; dev = dev->next)
         {
             if (stuff->deviceid == XIAllDevices ||
-                (stuff->deviceid == XIAllMasterDevices && dev->isMaster))
+                (stuff->deviceid == XIAllMasterDevices && IsMaster(dev)))
                 len += SizeDeviceInfo(dev);
         }
 
@@ -126,7 +126,7 @@ ProcXIQueryDevice(ClientPtr client)
         for (dev = inputInfo.devices; dev; dev = dev->next)
         {
             if (stuff->deviceid == XIAllDevices ||
-                    (stuff->deviceid == XIAllMasterDevices && dev->isMaster))
+                    (stuff->deviceid == XIAllMasterDevices && IsMaster(dev)))
             {
                 len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
                 if (client->swapped)
@@ -139,7 +139,7 @@ ProcXIQueryDevice(ClientPtr client)
         for (dev = inputInfo.off_devices; dev; dev = dev->next)
         {
             if (stuff->deviceid == XIAllDevices ||
-                    (stuff->deviceid == XIAllMasterDevices && dev->isMaster))
+                    (stuff->deviceid == XIAllMasterDevices && IsMaster(dev)))
             {
                 len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
                 if (client->swapped)
@@ -326,7 +326,7 @@ int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment)
     DeviceIntPtr master = dev->u.master;
     int use;
 
-    if (dev->isMaster)
+    if (IsMaster(dev))
     {
         DeviceIntPtr paired = GetPairedDevice(dev);
         use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard;
diff --git a/Xi/setcptr.c b/Xi/setcptr.c
index 46b88bf..0bfc1ea 100644
--- a/Xi/setcptr.c
+++ b/Xi/setcptr.c
@@ -74,7 +74,7 @@ ProcXISetClientPointer(ClientPtr client)
     if (rc != Success)
         return rc;
 
-    if (!IsPointerDevice(pDev) || !pDev->isMaster)
+    if (!IsPointerDevice(pDev) || !IsMaster(pDev))
     {
         client->errorValue = stuff->deviceid;
         return BadDevice;
diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c
index 9eb36c4..3077e1a 100644
--- a/Xi/xiallowev.c
+++ b/Xi/xiallowev.c
@@ -82,15 +82,15 @@ ProcXIAllowEvents(ClientPtr client)
 	AllowSome(client, time, dev, THAWED);
 	break;
     case XIAsyncPairedDevice:
-        if (dev->isMaster)
+        if (IsMaster(dev))
             AllowSome(client, time, dev, THAW_OTHERS);
 	break;
     case XISyncPair:
-        if (dev->isMaster)
+        if (IsMaster(dev))
             AllowSome(client, time, dev, FREEZE_BOTH_NEXT_EVENT);
 	break;
     case XIAsyncPair:
-        if (dev->isMaster)
+        if (IsMaster(dev))
             AllowSome(client, time, dev, THAWED_BOTH);
 	break;
     default:
diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c
index 20f4e51..95beb83 100644
--- a/Xi/xigrabdev.c
+++ b/Xi/xigrabdev.c
@@ -74,7 +74,7 @@ ProcXIGrabDevice(ClientPtr client)
     if (ret != Success)
 	return ret;
 
-    if (!dev->isMaster)
+    if (!IsMaster(dev))
         stuff->paired_device_mode = GrabModeAsync;
 
     memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index d2dabba..3f46e67 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -102,7 +102,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     }
 
     /* Can't grab for modifiers on an attached slave device */
-    if (!dev->isMaster)
+    if (!IsMaster(dev))
     {
         if (!dev->u.master)
             stuff->paired_device_mode = GrabModeAsync;
@@ -157,7 +157,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     if (!modifiers_failed)
         return BadAlloc;
 
-    if (IsPointerDevice(dev) && dev->isMaster)
+    if (IsPointerDevice(dev) && IsMaster(dev))
         mod_dev = GetPairedDevice(dev);
     else
         mod_dev = dev;
@@ -261,7 +261,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
     if (rc != Success)
         return rc;
 
-    if (dev->isMaster)
+    if (IsMaster(dev))
         mod_dev = GetPairedDevice(dev);
     else
         mod_dev = dev;
diff --git a/dix/devices.c b/dix/devices.c
index e7da2ad..3d0d30d 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -152,7 +152,7 @@ PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd)
         return BadDevice;
 
     /* Don't allow pairing for slave devices */
-    if (!ptr->isMaster || !kbd->isMaster)
+    if (!IsMaster(ptr) || !IsMaster(kbd))
         return BadDevice;
 
     if (ptr->spriteInfo->paired)
@@ -180,7 +180,7 @@ NextFreePointerDevice(void)
 {
     DeviceIntPtr dev;
     for (dev = inputInfo.devices; dev; dev = dev->next)
-        if (dev->isMaster &&
+        if (IsMaster(dev) &&
                 dev->spriteInfo->spriteOwner &&
                 !dev->spriteInfo->paired)
             return dev;
@@ -306,7 +306,7 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
 
     if (!dev->spriteInfo->sprite)
     {
-        if (dev->isMaster)
+        if (IsMaster(dev))
         {
             /* Sprites appear on first root window, so we can hardcode it */
             if (dev->spriteInfo->spriteOwner)
@@ -398,7 +398,7 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
 	return FALSE;
 
     /* float attached devices */
-    if (dev->isMaster)
+    if (IsMaster(dev))
     {
         for (other = inputInfo.devices; other; other = other->next)
         {
@@ -413,12 +413,12 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
     {
         for (other = inputInfo.devices; other; other = other->next)
         {
-	    if (other->isMaster && other->u.lastSlave == dev)
+	    if (IsMaster(other) && other->u.lastSlave == dev)
 		other->u.lastSlave = NULL;
 	}
     }
 
-    if (dev->isMaster && dev->spriteInfo->sprite)
+    if (IsMaster(dev) && dev->spriteInfo->sprite)
     {
         for (other = inputInfo.devices; other; other = other->next)
         {
@@ -488,7 +488,7 @@ ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
         return ret;
 
     /* Initialize memory for sprites. */
-    if (dev->isMaster && dev->spriteInfo->spriteOwner)
+    if (IsMaster(dev) && dev->spriteInfo->spriteOwner)
         pScreen->DeviceCursorInitialize(dev, pScreen);
 
     SendDevicePresenceEvent(dev->id, DeviceAdded);
@@ -847,7 +847,7 @@ CloseDevice(DeviceIntPtr dev)
 	(void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
 
     /* free sprite memory */
-    if (dev->isMaster && dev->spriteInfo->sprite)
+    if (IsMaster(dev) && dev->spriteInfo->sprite)
         screen->DeviceCursorCleanup(dev, screen);
 
     /* free acceleration info */
@@ -859,7 +859,7 @@ CloseDevice(DeviceIntPtr dev)
     classes = (ClassesPtr)&dev->key;
     FreeAllDeviceClasses(classes);
 
-    if (dev->isMaster)
+    if (IsMaster(dev))
     {
         classes = dixLookupPrivate(&dev->devPrivates, UnusedClassesPrivateKey);
         FreeAllDeviceClasses(classes);
@@ -904,7 +904,7 @@ CloseDownDevices(void)
      */
     for (dev = inputInfo.devices; dev; dev = dev->next)
     {
-        if (!dev->isMaster && dev->u.master)
+        if (!IsMaster(dev) && dev->u.master)
             dev->u.master = NULL;
     }
 
@@ -990,7 +990,7 @@ RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
 	    else
 		prev->next = next;
 
-	    flags[tmp->id] = (tmp->isMaster) ? XIMasterRemoved : XISlaveRemoved;
+	    flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
 	    CloseDevice(tmp);
 	    ret = Success;
 	}
@@ -1000,7 +1000,7 @@ RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
     for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
 	next = tmp->next;
 	if (tmp == dev) {
-	    flags[tmp->id] = (tmp->isMaster) ? XIMasterRemoved : XISlaveRemoved;
+	    flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
 	    CloseDevice(tmp);
 
 	    if (prev == NULL)
@@ -1194,7 +1194,7 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
     }
 
     dev->last.numValuators = numAxes;
-    if(dev->isMaster) /* master devs do not accelerate */
+    if(IsMaster(dev)) /* master devs do not accelerate */
 	InitPointerAccelerationScheme(dev, PtrAccelNoOp);
     else
 	InitPointerAccelerationScheme(dev, PtrAccelDefault);
@@ -1226,7 +1226,7 @@ InitPointerAccelerationScheme(DeviceIntPtr dev,
     if(!val)
 	return FALSE;
 
-    if(dev->isMaster && (scheme != PtrAccelNoOp))
+    if(IsMaster(dev) && (scheme != PtrAccelNoOp))
         scheme = PtrAccelNoOp; /* no accel for master devices */
 
     for(x = 0; pointerAccelerationScheme[x].number >= 0; x++) {
@@ -1587,7 +1587,7 @@ ProcChangeKeyboardMapping(ClientPtr client)
                           stuff->keyCodes, NULL, client);
 
     for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
-        if (tmp->isMaster || tmp->u.master != pDev)
+        if (IsMaster(tmp) || tmp->u.master != pDev)
             continue;
         if (!tmp->key)
             continue;
@@ -1932,7 +1932,7 @@ ProcChangeKeyboardControl (ClientPtr client)
     keyboard = PickKeyboard(client);
 
     for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
-        if ((pDev == keyboard || (!pDev->isMaster && pDev->u.master == keyboard)) &&
+        if ((pDev == keyboard || (!IsMaster(keyboard) && pDev->u.master == keyboard)) &&
             pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
             ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
 	    if (ret != Success)
@@ -1941,7 +1941,7 @@ ProcChangeKeyboardControl (ClientPtr client)
     }
 
     for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
-        if ((pDev == keyboard || (!pDev->isMaster && pDev->u.master == keyboard)) &&
+        if ((pDev == keyboard || (!IsMaster(keyboard) && pDev->u.master == keyboard)) &&
             pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
             ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
             if (ret != Success)
@@ -2010,7 +2010,7 @@ ProcBell(ClientPtr client)
 	newpercent = base - newpercent + stuff->percent;
 
     for (dev = inputInfo.devices; dev; dev = dev->next) {
-        if ((dev == keybd || (!dev->isMaster && dev->u.master == keybd)) &&
+        if ((dev == keybd || (!IsMaster(dev) && dev->u.master == keybd)) &&
             dev->kbdfeed && dev->kbdfeed->BellProc) {
 
 	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess);
@@ -2082,7 +2082,7 @@ ProcChangePointerControl(ClientPtr client)
     }
 
     for (dev = inputInfo.devices; dev; dev = dev->next) {
-        if ((dev == mouse || (!dev->isMaster && dev->u.master == mouse)) &&
+        if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) &&
             dev->ptrfeed && dev->ptrfeed->CtrlProc) {
 	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
 	    if (rc != Success)
@@ -2091,7 +2091,7 @@ ProcChangePointerControl(ClientPtr client)
     }
 
     for (dev = inputInfo.devices; dev; dev = dev->next) {
-        if ((dev == mouse || (!dev->isMaster && dev->u.master == mouse)) &&
+        if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) &&
             dev->ptrfeed && dev->ptrfeed->CtrlProc) {
             dev->ptrfeed->ctrl = ctrl;
             (*dev->ptrfeed->CtrlProc)(dev, &mouse->ptrfeed->ctrl);
@@ -2246,10 +2246,10 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
 {
     ScreenPtr screen;
     DeviceIntPtr oldmaster;
-    if (!dev || dev->isMaster)
+    if (!dev || IsMaster(dev))
         return BadDevice;
 
-    if (master && !master->isMaster) /* can't attach to slaves */
+    if (master && !IsMaster(master)) /* can't attach to slaves */
         return BadDevice;
 
     /* set from floating to floating? */
@@ -2310,7 +2310,7 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
     {
         DeviceIntPtr it;
         for (it = inputInfo.devices; it; it = it->next)
-            if (!it->isMaster && it->u.master == oldmaster)
+            if (!IsMaster(it) && it->u.master == oldmaster)
                 break;
 
         if (!it)  /* no dev is paired with old master */
@@ -2338,7 +2338,7 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
 DeviceIntPtr
 GetPairedDevice(DeviceIntPtr dev)
 {
-    if (!dev->isMaster && dev->u.master)
+    if (!IsMaster(dev) && dev->u.master)
         dev = dev->u.master;
 
     return dev->spriteInfo->paired;
@@ -2380,7 +2380,7 @@ AllocDevicePair (ClientPtr client, char* name,
 
     pointer->u.lastSlave = NULL;
     pointer->last.slave = NULL;
-    pointer->isMaster = master;
+    pointer->type = (master) ? MASTER_POINTER : SLAVE;
 
     keyboard = AddInputDevice(client, CoreKeyboardProc, TRUE);
     if (!keyboard)
@@ -2403,7 +2403,7 @@ AllocDevicePair (ClientPtr client, char* name,
 
     keyboard->u.lastSlave = NULL;
     keyboard->last.slave = NULL;
-    keyboard->isMaster = master;
+    keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
 
 
     /* The ClassesRec stores the device classes currently not used. */
diff --git a/dix/enterleave.c b/dix/enterleave.c
index e45d061..eadcc45 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -546,7 +546,7 @@ CoreEnterLeaveEvents(DeviceIntPtr dev,
                      WindowPtr to,
                      int mode)
 {
-    if (!dev->isMaster)
+    if (!IsMaster(dev))
         return;
 
     LeaveWindow(dev, from, mode);
@@ -1216,7 +1216,7 @@ CoreFocusEvents(DeviceIntPtr dev,
                 WindowPtr to,
                 int mode)
 {
-    if (!dev->isMaster)
+    if (!IsMaster(dev))
         return;
 
     SetFocusOut(dev, from);
diff --git a/dix/events.c b/dix/events.c
index 10814fa..3222950 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -329,7 +329,7 @@ DevHasCursor(DeviceIntPtr pDev)
 Bool
 IsPointerDevice(DeviceIntPtr dev)
 {
-    return (dev->valuator && dev->button);
+    return (dev->type == MASTER_POINTER) || (dev->valuator && dev->button);
 }
 
 /*
@@ -342,7 +342,14 @@ IsPointerDevice(DeviceIntPtr dev)
 Bool
 IsKeyboardDevice(DeviceIntPtr dev)
 {
-    return (dev->key && dev->kbdfeed) && !IsPointerDevice(dev);
+    return (dev->type == MASTER_KEYBOARD) ||
+            ((dev->key && dev->kbdfeed) && !IsPointerDevice(dev));
+}
+
+Bool
+IsMaster(DeviceIntPtr dev)
+{
+    return (dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD);
 }
 
 static WindowPtr XYToWindow(
@@ -455,7 +462,7 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
 
     return ((inputMasks->xi2mask[dev->id][evtype/8] & filter) ||
             inputMasks->xi2mask[XIAllDevices][evtype/8] ||
-            (inputMasks->xi2mask[XIAllMasterDevices][evtype/8] && dev->isMaster));
+            (inputMasks->xi2mask[XIAllMasterDevices][evtype/8] && IsMaster(dev)));
 }
 
 static Mask
@@ -467,7 +474,7 @@ GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other)
         int byte = ((xGenericEvent*)event)->evtype / 8;
         return (other->xi2mask[dev->id][byte] |
                 other->xi2mask[XIAllDevices][byte] |
-                (dev->isMaster? other->xi2mask[XIAllMasterDevices][byte] : 0));
+                (IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0));
     } else if (CORE_EVENT(event))
         return other->mask[XIAllDevices];
     else
@@ -1404,7 +1411,7 @@ CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
         The correct thing to do would be to freeze all SDs attached to the
         paired master device.
      */
-    if (thisDev->isMaster)
+    if (IsMaster(thisDev))
     {
         dev = GetPairedDevice(thisDev);
         if (otherMode == GrabModeSync)
@@ -1453,7 +1460,7 @@ RestoreOldMaster(DeviceIntPtr dev)
 {
     GrabMemoryPtr gm;
 
-    if (dev->isMaster)
+    if (IsMaster(dev))
         return;
 
     gm = (GrabMemoryPtr)dixLookupPrivate(&dev->devPrivates, GrabPrivateKey);
@@ -1491,7 +1498,7 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
     Bool isPassive = autoGrab & ~ImplicitGrabMask;
 
     /* slave devices need to float for the duration of the grab. */
-    if (!isPassive && !mouse->isMaster)
+    if (!isPassive && !IsMaster(mouse))
     {
         SaveOldMaster(mouse);
         AttachDevice(NULL, mouse, NULL);
@@ -1569,7 +1576,7 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass
     WindowPtr oldWin;
 
     /* slave devices need to float for the duration of the grab. */
-    if (!passive && !keybd->isMaster)
+    if (!passive && !IsMaster(keybd))
     {
         SaveOldMaster(keybd);
         AttachDevice(NULL, keybd, NULL);
@@ -2311,7 +2318,7 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
     filter = GetEventFilter(dev, &ev);
     if (type && (inputMasks = wOtherInputMasks(win)) &&
         ((inputMasks->xi2mask[XIAllDevices][type/8] & filter) ||
-         ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && dev->isMaster) ||
+         ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && IsMaster(dev)) ||
          (inputMasks->xi2mask[dev->id][type/8] & filter)))
         rc |= XI2_MASK;
 
@@ -2430,7 +2437,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
             }
 
             /* Core event */
-            if ((mask & CORE_MASK) && dev->isMaster && dev->coreEvents)
+            if ((mask & CORE_MASK) && IsMaster(dev) && dev->coreEvents)
             {
                 rc = EventToCore(event, &core);
                 if (rc != Success)
@@ -3160,7 +3167,7 @@ ProcWarpPointer(ClientPtr client)
     dev = PickPointer(client);
 
     for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
-        if ((tmp == dev) || (!tmp->isMaster && tmp->u.master == dev)) {
+        if ((tmp == dev) || (!IsMaster(tmp) && tmp->u.master == dev)) {
 	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess);
 	    if (rc != Success)
 		return rc;
@@ -3492,7 +3499,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, int checkFirst)
     int i;
     WindowPtr pWin = NULL;
     FocusClassPtr focus = IsPointerEvent((InternalEvent*)event) ? NULL : device->focus;
-    BOOL sendCore = (device->isMaster && device->coreEvents);
+    BOOL sendCore = (IsMaster(device) && device->coreEvents);
 
     if (event->type != ET_ButtonPress &&
         event->type != ET_KeyPress)
@@ -3548,7 +3555,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
 {
     DeviceIntPtr ptr;
     WindowPtr focus = keybd->focus->win;
-    BOOL sendCore = (keybd->isMaster && keybd->coreEvents);
+    BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents);
     xEvent core;
     xEvent *xE = NULL, *xi2 = NULL;
     int count, rc;
@@ -3714,7 +3721,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 
         mask = grab->eventMask;
 
-        sendCore = (thisDev->isMaster && thisDev->coreEvents);
+        sendCore = (IsMaster(thisDev) && thisDev->coreEvents);
         /* try core event */
         if (sendCore && grab->grabtype == GRABTYPE_CORE)
         {
@@ -4201,7 +4208,7 @@ DeviceEnterLeaveEvent(
         if (BitIsOn(mouse->button->down, i))
             SetBit(&event[1], i);
 
-    kbd = (mouse->isMaster || mouse->u.master) ? GetPairedDevice(mouse) : NULL;
+    kbd = (IsMaster(mouse) || mouse->u.master) ? GetPairedDevice(mouse) : NULL;
     if (kbd && kbd->key)
     {
         event->mods.base_mods = kbd->key->xkbInfo->state.base_mods;
@@ -5583,7 +5590,7 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
 Bool
 SetClientPointer(ClientPtr client, ClientPtr setter, DeviceIntPtr device)
 {
-    if (!device->isMaster)
+    if (!IsMaster(device))
     {
         ErrorF("[dix] Need master device for ClientPointer. This is a bug.\n");
         return FALSE;
@@ -5627,7 +5634,7 @@ PickPointer(ClientPtr client)
         DeviceIntPtr it = inputInfo.devices;
         while (it)
         {
-            if (it->isMaster && it->spriteInfo->spriteOwner)
+            if (IsMaster(it) && it->spriteInfo->spriteOwner)
             {
                 client->clientPtr = it;
                 break;
diff --git a/dix/getevents.c b/dix/getevents.c
index e40b3db..5ff4f91 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -325,7 +325,7 @@ AllocateMotionHistory(DeviceIntPtr pDev)
      * potential valuators, plus the respective range of the valuators.
      * 3 * INT32 for (min_val, max_val, curr_val))
      */
-    if (pDev->isMaster)
+    if (IsMaster(pDev))
         size = sizeof(INT32) * 3 * MAX_VALUATORS;
     else
         size = sizeof(INT32) * pDev->valuator->numAxes;
@@ -369,7 +369,7 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
     if (core && !pScreen)
         return 0;
 
-    if (pDev->isMaster)
+    if (IsMaster(pDev))
         size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time);
     else
         size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
@@ -421,7 +421,7 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
                 coord = rescaleValuatorAxis(coord, &from, to, pScreen->height);
                 memcpy(corebuf, &coord, sizeof(INT16));
 
-            } else if (pDev->isMaster)
+            } else if (IsMaster(pDev))
             {
                 memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
 
@@ -497,7 +497,7 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
         return;
 
     v = pDev->valuator;
-    if (pDev->isMaster)
+    if (IsMaster(pDev))
     {
         buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) *
                 v->last_motion;
diff --git a/dix/inpututils.c b/dix/inpututils.c
index 1522145..79b6ab7 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -268,9 +268,9 @@ change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap,
     do_modmap_change(client, dev, modmap);
 
     /* Change any attached masters/slaves. */
-    if (dev->isMaster) {
+    if (IsMaster(dev)) {
         for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
-            if (!tmp->isMaster && tmp->u.master == dev)
+            if (!IsMaster(tmp) && tmp->u.master == dev)
                 if (check_modmap_change_slave(client, dev, tmp, modmap))
                     do_modmap_change(client, tmp, modmap);
         }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 6df0b8a..39186ac 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -323,7 +323,7 @@ xf86ActivateDevice(LocalDevicePtr local)
         local->dev = dev;      
         
         dev->coreEvents = local->flags & XI86_ALWAYS_CORE; 
-        dev->isMaster = FALSE;
+        dev->type = SLAVE;
         dev->spriteInfo->spriteOwner = FALSE;
 
         dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
@@ -664,7 +664,7 @@ DeleteInputDeviceRequest(DeviceIntPtr pDev)
     InputDriverPtr drv = NULL;
     IDevRec *idev = NULL;
     IDevPtr *it;
-    Bool isMaster = pDev->isMaster;
+    Bool isMaster = IsMaster(pDev);
 
     if (pInfo) /* need to get these before RemoveDevice */
     {
diff --git a/hw/xfree86/ramdac/xf86Cursor.c b/hw/xfree86/ramdac/xf86Cursor.c
index 2b73b16..b866550 100644
--- a/hw/xfree86/ramdac/xf86Cursor.c
+++ b/hw/xfree86/ramdac/xf86Cursor.c
@@ -315,7 +315,7 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
     /* only update for VCP, otherwise we get cursor jumps when removing a
        sprite. The second cursor is never HW rendered anyway. */
     if (pDev == inputInfo.pointer ||
-        (!pDev->isMaster && pDev->u.master == inputInfo.pointer))
+        (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer))
     {
 	ScreenPriv->CurrentCursor = pCurs;
 	ScreenPriv->x = x;
@@ -380,7 +380,7 @@ xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     /* only update coordinate state for first sprite, otherwise we get jumps
        when removing a sprite. The second sprite is never HW rendered anyway */
     if (pDev == inputInfo.pointer ||
-	(!pDev->isMaster && pDev->u.master == inputInfo.pointer))
+	(!IsMaster(pDev) && pDev->u.master == inputInfo.pointer))
     {
 	ScreenPriv->x = x;
 	ScreenPriv->y = y;
diff --git a/include/dix.h b/include/dix.h
index 7811982..d4bec5f 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -580,6 +580,7 @@ extern Bool DevHasCursor(DeviceIntPtr pDev);
 extern Bool IsPointerDevice( DeviceIntPtr dev);
 extern Bool IsKeyboardDevice(DeviceIntPtr dev);
 extern Bool IsPointerEvent(InternalEvent *event);
+extern Bool IsMaster(DeviceIntPtr dev);
 
 /*
  * These are deprecated compatibility functions and will be removed soon!
diff --git a/include/inputstr.h b/include/inputstr.h
index 0fd3488..5c74ba3 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -458,6 +458,11 @@ typedef struct _SpriteInfoRec {
                                         pointer that owns the sprite. */ 
 } SpriteInfoRec, *SpriteInfoPtr;
 
+/* device types */
+#define MASTER_POINTER          1
+#define MASTER_KEYBOARD         2
+#define SLAVE                   3
+
 typedef struct _DeviceIntRec {
     DeviceRec	public;
     DeviceIntPtr next;
@@ -470,7 +475,7 @@ typedef struct _DeviceIntRec {
     Bool        enabled;                /* TRUE if ON returns Success */
     Bool        coreEvents;             /* TRUE if device also sends core */
     GrabInfoRec deviceGrab;             /* grab on the device */
-    Bool        isMaster;               /* TRUE if device is master */
+    int         type;                   /* MASTER_POINTER, MASTER_KEYBOARD, SLAVE */
     Atom		xinput_type;
     char		*name;
     CARD8		id;
diff --git a/mi/mieq.c b/mi/mieq.c
index 4b3d700..e2f18e2 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -359,7 +359,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
         NewCurrentScreen (dev, DequeueScreen(dev), x, y);
     }
     else {
-        master  = (!dev->isMaster && dev->u.master) ? dev->u.master : NULL;
+        master  = (!IsMaster(dev) && dev->u.master) ? dev->u.master : NULL;
 
         if (master)
             CopyGetMasterEvent(master, dev, event, masterEvents);
@@ -426,7 +426,7 @@ mieqProcessInputEvents(void)
         pthread_mutex_unlock(&miEventQueueMutex);
 #endif
 
-        master  = (!dev->isMaster && dev->u.master) ? dev->u.master : NULL;
+        master  = (!IsMaster(dev) && dev->u.master) ? dev->u.master : NULL;
 
         if (screenIsSaved == SCREEN_SAVER_ON)
             dixSaveScreens (serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
diff --git a/mi/mipointer.c b/mi/mipointer.c
index c75c120..fdad77b 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -51,7 +51,7 @@ static int miPointerPrivKeyIndex;
 static DevPrivateKey miPointerPrivKey = &miPointerPrivKeyIndex;
 
 #define MIPOINTER(dev) \
-    ((DevHasCursor((dev)) || (!dev->isMaster && !dev->u.master)) ? \
+    ((DevHasCursor((dev)) || (!IsMaster(isMaster) && !dev->u.master)) ? \
         (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \
         (miPointerPtr)dixLookupPrivate(&(dev)->u.master->devPrivates, miPointerPrivKey))
 
@@ -186,8 +186,8 @@ miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
     miPointerPtr pPointer;
 
     /* return for keyboards */
-    if ((pDev->isMaster && !DevHasCursor(pDev)) ||
-        (!pDev->isMaster && pDev->u.master && !DevHasCursor(pDev->u.master)))
+    if ((IsMaster(pDev) && !DevHasCursor(pDev)) ||
+        (!IsMaster(pDev) && pDev->u.master && !DevHasCursor(pDev->u.master)))
             return FALSE;
 
     pPointer = MIPOINTER(pDev);
@@ -286,7 +286,7 @@ miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
 {
     SetupScreen(pScreen);
 
-    if (!pDev->isMaster && pDev->u.master)
+    if (!IsMaster(pDev) && pDev->u.master)
         return;
 
     (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
@@ -474,7 +474,7 @@ miPointerMoved (DeviceIntPtr pDev, ScreenPtr pScreen,
      * VCP, as this may cause a non-HW rendered cursor to be rendered during
      * SIGIO. This again leads to allocs during SIGIO which leads to SIGABRT.
      */
-    if ((pDev == inputInfo.pointer || (!pDev->isMaster && pDev->u.master == inputInfo.pointer))
+    if ((pDev == inputInfo.pointer || (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer))
         && !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen)
     {
 	pPointer->devx = x;
diff --git a/mi/misprite.c b/mi/misprite.c
index a2abbc2..3f4c573 100644
--- a/mi/misprite.c
+++ b/mi/misprite.c
@@ -764,7 +764,7 @@ miSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
     miCursorInfoPtr pCursorInfo;
 
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
-    if (!pDev->isMaster && !pDev->u.master)
+    if (!IsMaster(pDev) && !pDev->u.master)
     {
         ErrorF("[mi] miSpriteRealizeCursor called for floating device.\n");
         return FALSE;
@@ -795,7 +795,7 @@ miSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
 
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
 
-    if (!pDev->isMaster && !pDev->u.master)
+    if (!IsMaster(pDev) && !pDev->u.master)
     {
         ErrorF("[mi] miSpriteSetCursor called for floating device.\n");
         return;
@@ -912,7 +912,7 @@ miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     CursorPtr pCursor;
 
     pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, miSpriteScreenKey);
-    if (!pDev->isMaster && !pDev->u.master)
+    if (!IsMaster(pDev) && !pDev->u.master)
     {
         ErrorF("[mi] miSpriteMoveCursor called for floating device.\n");
         return;
@@ -980,7 +980,7 @@ miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
     miCursorInfoPtr     pCursorInfo;
 
 
-    if (!pDev->isMaster && !pDev->u.master)
+    if (!IsMaster(pDev) && !pDev->u.master)
     {
         ErrorF("[mi] miSpriteRemoveCursor called for floating device.\n");
         return;
@@ -1020,7 +1020,7 @@ miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen)
     CursorPtr		pCursor;
     miCursorInfoPtr     pCursorInfo;
 
-    if (!pDev->isMaster && !pDev->u.master)
+    if (!IsMaster(pDev) && !pDev->u.master)
     {
         ErrorF("[mi] miSpriteSaveUnderCursor called for floating device.\n");
         return;
@@ -1063,7 +1063,7 @@ miSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
     CursorPtr		pCursor;
     miCursorInfoPtr     pCursorInfo;
 
-    if (!pDev->isMaster && !pDev->u.master)
+    if (!IsMaster(pDev) && !pDev->u.master)
     {
         ErrorF("[mi] miSpriteRestoreCursor called for floating device.\n");
         return;
@@ -1107,7 +1107,7 @@ miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen)
     CursorPtr	    pCursor;
     miCursorInfoPtr pCursorInfo;
 
-    if (!pDev->isMaster && !pDev->u.master)
+    if (!IsMaster(pDev) && !pDev->u.master)
     {
         ErrorF("[mi] miSpriteComputeSaved called for floating device.\n");
         return;
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 1d97f9c..51feaa0 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -521,7 +521,7 @@ ProcXkbBell(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev))
+            if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
             {
                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess);
                 if (rc == Success)
@@ -604,7 +604,7 @@ ProcXkbLatchLockState(ClientPtr client)
     status = Success;
 
     for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
-        if ((tmpd == dev) || (!tmpd->isMaster && tmpd->u.master == dev)) {
+        if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
             if (!tmpd->key || !tmpd->key->xkbInfo)
                 continue;
 
@@ -746,7 +746,7 @@ ProcXkbSetControls(ClientPtr client)
     for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
         if (!tmpd->key || !tmpd->key->xkbInfo)
             continue;
-        if ((tmpd == dev) || (!tmpd->isMaster && tmpd->u.master == dev)) {
+        if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
             xkbi = tmpd->key->xkbInfo;
             ctrl = xkbi->desc->ctrls;
             new = *ctrl;
@@ -2556,7 +2556,7 @@ ProcXkbSetMap(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev))
+            if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
             {
                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
                 if (rc == Success)
@@ -2579,7 +2579,7 @@ ProcXkbSetMap(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev))
+            if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
             {
                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
                 if (rc == Success)
@@ -2886,7 +2886,7 @@ ProcXkbSetCompatMap(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev))
+            if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
             {
                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
                 if (rc == Success)
@@ -2909,7 +2909,7 @@ ProcXkbSetCompatMap(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev))
+            if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
             {
                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
                 if (rc == Success)
@@ -3164,7 +3164,7 @@ ProcXkbSetIndicatorMap(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev))
+            if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
             {
                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess);
                 if (rc == Success)
@@ -3432,7 +3432,7 @@ ProcXkbSetNamedIndicator(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && !other->isMaster && (other->u.master == dev) &&
+            if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
                 (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
             {
                 rc = _XkbCreateIndicatorMap(other, stuff->indicator,
@@ -3455,7 +3455,7 @@ ProcXkbSetNamedIndicator(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && !other->isMaster && (other->u.master == dev) &&
+            if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
                 (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
             {
                 _XkbSetNamedIndicator(client, other, stuff);
@@ -4245,7 +4245,7 @@ ProcXkbSetNames(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev))
+            if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
             {
 
                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
@@ -4270,7 +4270,7 @@ ProcXkbSetNames(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev))
+            if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
             {
 
                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
@@ -5321,7 +5321,7 @@ ProcXkbSetGeometry(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if ((other != dev) && other->key && !other->isMaster && (other->u.master == dev))
+            if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
             {
                 rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
                 if (rc == Success)
@@ -5835,7 +5835,7 @@ ProcXkbGetKbdByName(ClientPtr client)
 	xkb->ctrls->num_groups= nTG;
 
         for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
-            if ((tmpd == dev) || (!tmpd->isMaster && tmpd->u.master == dev)) {
+            if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
                 if (tmpd != dev)
                     XkbCopyDeviceKeymap(tmpd, dev);
 
@@ -6499,7 +6499,7 @@ ProcXkbSetDeviceInfo(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if (((other != dev) && !other->isMaster && (other->u.master == dev)) &&
+            if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) &&
                 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
                 (stuff->deviceSpec == XkbUseCorePtr && other->button)))
             {
@@ -6524,7 +6524,7 @@ ProcXkbSetDeviceInfo(ClientPtr client)
         DeviceIntPtr other;
         for (other = inputInfo.devices; other; other = other->next)
         {
-            if (((other != dev) && !other->isMaster && (other->u.master == dev)) &&
+            if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) &&
                 ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
                 (stuff->deviceSpec == XkbUseCorePtr && other->button)))
             {
commit add2defac7e59dcb355e5ba12b6de60861741d57
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 16:23:38 2009 +1000

    Split the signal-handler's lastSlave out into a separate variable.
    
    dev->u.lastSlave was not signal safe since it was accessed by the DIX and
    during signal handling.
    Replaced with:
    'dev->last.slave' for the signal handler's lastSlave (used to generate
                      DeviceChangedEvents), .
    'dev->u.lastSlave' for the DIX lastSlave (currently only used in
                       change_modmap)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 7772029..04a4fbd 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1010,7 +1010,6 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
     if (device->isMaster || !device->u.master)
         CheckMotion(event, device);
 
-
     switch (event->type)
     {
         case ET_Motion:
diff --git a/dix/devices.c b/dix/devices.c
index ff91608..e7da2ad 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -433,6 +433,18 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
 
     (void)(*dev->deviceProc)(dev, DEVICE_OFF);
     dev->enabled = FALSE;
+
+    /* now that the device is disabled, we can reset the signal handler's
+     * last.slave */
+    OsBlockSignals();
+    for (other = inputInfo.devices; other; other = other->next)
+    {
+        if (other->last.slave == dev)
+            other->last.slave = NULL;
+    }
+    OsReleaseSignals();
+
+
     *prev = dev->next;
     dev->next = inputInfo.off_devices;
     inputInfo.off_devices = dev;
@@ -2367,6 +2379,7 @@ AllocDevicePair (ClientPtr client, char* name,
     pointer->spriteInfo->spriteOwner = TRUE;
 
     pointer->u.lastSlave = NULL;
+    pointer->last.slave = NULL;
     pointer->isMaster = master;
 
     keyboard = AddInputDevice(client, CoreKeyboardProc, TRUE);
@@ -2389,6 +2402,7 @@ AllocDevicePair (ClientPtr client, char* name,
     keyboard->spriteInfo->spriteOwner = FALSE;
 
     keyboard->u.lastSlave = NULL;
+    keyboard->last.slave = NULL;
     keyboard->isMaster = master;
 
 
diff --git a/dix/getevents.c b/dix/getevents.c
index 652bd67..e40b3db 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -199,10 +199,10 @@ CreateClassesChangedEvent(EventList* event,
     dce->length = sizeof(DeviceChangedEvent);
     dce->type = ET_DeviceChanged;
     dce->time = ms;
-    if (master->u.lastSlave)
+    if (master->last.slave)
     {
         dce->flags |= DEVCHANGE_HAS_OLD_SLAVE;
-        dce->old_slaveid = master->u.lastSlave->id;
+        dce->old_slaveid = master->last.slave->id;
     }
     dce->flags |= DEVCHANGE_HAS_NEW_SLAVE;
     dce->new_slaveid = slave->id;
@@ -294,7 +294,7 @@ updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
      * slave-device. If the old slave had less axes than this one,
      * last.valuators is reset to 0.
      */
-    if ((lastSlave = master->u.lastSlave) && lastSlave->valuator) {
+    if ((lastSlave = master->last.slave) && lastSlave->valuator) {
         for (i = 2; i < pDev->valuator->numAxes; i++) {
             if (i >= lastSlave->valuator->numAxes)
                 pDev->last.valuators[i] = 0;
@@ -612,11 +612,11 @@ static EventListPtr
 updateFromMaster(EventListPtr events, DeviceIntPtr dev, int *num_events)
 {
     DeviceIntPtr master = dev->u.master;
-    if (master && master->u.lastSlave != dev)
+    if (master && master->last.slave != dev)
     {
         CreateClassesChangedEvent(events, master, dev);
         updateSlaveDeviceCoords(master, dev);
-        master->u.lastSlave = dev;
+        master->last.slave = dev;
         master->last.numValuators = dev->last.numValuators;
         (*num_events)++;
         events++;
diff --git a/include/inputstr.h b/include/inputstr.h
index 0a541a7..0fd3488 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -507,6 +507,7 @@ typedef struct _DeviceIntRec {
         int             valuators[MAX_VALUATORS];
         float           remainder[MAX_VALUATORS];
         int             numValuators;
+        DeviceIntPtr    slave;
     } last;
 
     /* Input device property handling. */
diff --git a/mi/mieq.c b/mi/mieq.c
index 08444e1..4b3d700 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -370,8 +370,11 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
         {
             handler(DequeueScreen(dev)->myNum, event, dev);
             if (master)
+            {
+                master->u.lastSlave = dev;
                 handler(DequeueScreen(master)->myNum,
                         (InternalEvent*)masterEvents->event, master);
+            }
         } else
         {
             /* process slave first, then master */
commit 73c7398aafa050950ad614483fb0d5bdd2da97ca
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 10:40:50 2009 +1000

    dix: 'namespace' HAS_OLD_SLAVE and HAS_NEW_SLAVE.
    
    We need more flags for this in the near future, so let's namespace them now.

diff --git a/dix/getevents.c b/dix/getevents.c
index 2f61537..652bd67 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -201,10 +201,10 @@ CreateClassesChangedEvent(EventList* event,
     dce->time = ms;
     if (master->u.lastSlave)
     {
-        dce->flags |= HAS_OLD_SLAVE;
+        dce->flags |= DEVCHANGE_HAS_OLD_SLAVE;
         dce->old_slaveid = master->u.lastSlave->id;
     }
-    dce->flags |= HAS_NEW_SLAVE;
+    dce->flags |= DEVCHANGE_HAS_NEW_SLAVE;
     dce->new_slaveid = slave->id;
 
     if (slave->button)
diff --git a/include/events.h b/include/events.h
index 6803b5b..8719320 100644
--- a/include/events.h
+++ b/include/events.h
@@ -112,9 +112,9 @@ typedef struct
 } DeviceEvent;
 
 
-/* Flags used in DeviceChangedEvent to signal if new/old slave is present */
-#define HAS_OLD_SLAVE 0x1
-#define HAS_NEW_SLAVE 0x2
+/* Flags used in DeviceChangedEvent to signal if new/old slave is present. */
+#define DEVCHANGE_HAS_OLD_SLAVE 0x1
+#define DEVCHANGE_HAS_NEW_SLAVE 0x2
 
 /**
  * Sent whenever a device's capabilities have changed.
commit 5b5e3fa2771383a85afff679be34df19d3a4e290
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 15 08:33:07 2009 +1000

    xfree86: treat other drivers as mouse drivers in the config.
    
    Historically, if no input device was referenced in the ServerLayout,
    the server would pick the first "mouse" device found in the xorg.conf.
    This patch gives evdev, synaptics, vmmouse and void the same status. If
    there is a section in the config file using this driver - use it as the core
    pointer.
    
    Device selection is in driver-order, not in config-order. If a "mouse"
    device is listed after a "synaptics" device, the "mouse" device gets
    preference. This replicates the original behaviour.
    
    This code only takes effect if AllowEmptyInput is off and there is no core
    pointer in the server layout.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 2ecb639..844e04a 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1091,8 +1091,8 @@ Bool xf86DRI2Enabled(void)
  *  2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
  *     the active ServerLayout.
  *  3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
- *  4. The first InputDevices that use the 'mouse' and 'keyboard' or 'kbd'
- *     drivers.
+ *  4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
+ *     driver (mouse, synaptics, evdev, vmmouse, void)
  *  5. Default devices with an empty (default) configuration.  These defaults
  *     will reference the 'mouse' and 'keyboard' drivers.
  */
@@ -1111,6 +1111,8 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
     int count = 0;
     MessageType from = X_DEFAULT;
     int found = 0;
+    const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse",
+				   "void", NULL };
 
     /*
      * First check if a core pointer or core keyboard have been specified
@@ -1220,13 +1222,15 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
 	}
     }
 
-    /* 4. First pointer with 'mouse' as the driver. */
+    /* 4. First pointer with an allowed mouse driver. */
     if (!foundPointer && !xf86Info.allowEmptyInput) {
+	const char **driver = mousedrivers;
 	confInput = xf86findInput(CONF_IMPLICIT_POINTER,
 				  xf86configptr->conf_input_lst);
-	if (!confInput) {
-	    confInput = xf86findInputByDriver("mouse",
+	while (driver && !confInput) {
+	    confInput = xf86findInputByDriver(*driver,
 					      xf86configptr->conf_input_lst);
+	    driver++;
 	}
 	if (confInput) {
 	    foundPointer = TRUE;
@@ -1281,10 +1285,13 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
      * section ... deal.
      */
     for (devs = servlayoutp->inputs; devs && *devs; devs++) {
-	if (!strcmp((*devs)->driver, "void") || !strcmp((*devs)->driver, "mouse") ||
-            !strcmp((*devs)->driver, "vmmouse") || !strcmp((*devs)->driver, "evdev") ||
-            !strcmp((*devs)->driver, "synaptics")) {
-	    found = 1; break;
+	const char **driver = mousedrivers;
+	while(*driver) {
+	    if (!strcmp((*devs)->driver, *driver)) {
+		found = 1;
+		break;
+	    }
+	    driver++;
 	}
     }
     if (!found && !xf86Info.allowEmptyInput) {
commit 1cce55cc0333a026474100cf2f784e220fd96473
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 14:07:03 2009 +1000

    input: rename device->type to device->xinput_type.
    
    This type is only used in XI to give a hint of what type this device may be.
    Call it xinput_type for clarity.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index 1f77729..a8f8f10 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -1079,7 +1079,7 @@ IResetProc(ExtensionEntry * unused)
 void
 AssignTypeAndName(DeviceIntPtr dev, Atom type, char *name)
 {
-    dev->type = type;
+    dev->xinput_type = type;
     dev->name = (char *)xalloc(strlen(name) + 1);
     strcpy(dev->name, name);
 }
diff --git a/Xi/listdev.c b/Xi/listdev.c
index e7d0a9d..294fec9 100644
--- a/Xi/listdev.c
+++ b/Xi/listdev.c
@@ -175,7 +175,7 @@ CopySwapDevice(ClientPtr client, DeviceIntPtr d, int num_classes,
     dev = (xDeviceInfoPtr) * buf;
 
     dev->id = d->id;
-    dev->type = d->type;
+    dev->type = d->xinput_type;
     dev->num_classes = num_classes;
     if (d->isMaster && IsKeyboardDevice(d))
 	dev->use = IsXKeyboard;
diff --git a/include/inputstr.h b/include/inputstr.h
index e562c0a..0a541a7 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -471,7 +471,7 @@ typedef struct _DeviceIntRec {
     Bool        coreEvents;             /* TRUE if device also sends core */
     GrabInfoRec deviceGrab;             /* grab on the device */
     Bool        isMaster;               /* TRUE if device is master */
-    Atom		type;
+    Atom		xinput_type;
     char		*name;
     CARD8		id;
     KeyClassPtr		key;
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 3688bfc..1d97f9c 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -6117,7 +6117,7 @@ char *			str;
     if (dev->button)
 	 rep.totalBtns= dev->button->numButtons;
     else rep.totalBtns= 0;
-    rep.devType=	dev->type;
+    rep.devType=	dev->xinput_type;
     rep.hasOwnState=	(dev->key && dev->key->xkbInfo);
     rep.nDeviceLedFBs = 0;
     if (dev->kbdfeed)	rep.dfltKbdFB= dev->kbdfeed->ctrl.id;
commit 81b3b0cce088866dc3cda099d7c8d6655849fd43
Author: Tomas Janousek <tomi at nomi.cz>
Date:   Wed May 20 15:03:01 2009 +0200

    Bug #6428, #16458, #21464: Fix crash due to uninitialized VModMap fields.
    
    In ProcXkbGetKbdByName, mrep.firstVModMapKey, .nVModMapKeys and
    .totalVModMapKeys were not initialized, contained random values and caused
    accesses to unallocated and later modified memory, causing
    XkbSizeVirtualModMap and XkbWriteVirtualModMap to see different number of
    nonzero values, resulting in writes past the end of an array in XkbSendMap.
    
    This patch initializes those values sensibly and reverts commits 5c0a2088 and
    6dd4fc46, which have been plain non-sense.
    
    Signed-off-by: Tomas Janousek <tomi at nomi.cz>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkb.c b/xkb/xkb.c
index e7c9a31..3688bfc 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -1308,7 +1308,7 @@ XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep)
 	rep->totalVModMapKeys= 0;
 	return 0;
     }
-    for (nRtrn=i=0;i<rep->nVModMapKeys-1;i++) {
+    for (nRtrn=i=0;i<rep->nVModMapKeys;i++) {
 	if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0)
 	    nRtrn++;
     }
@@ -1327,7 +1327,7 @@ unsigned short *	pMap;
 
     wire= (xkbVModMapWireDesc *)buf;
     pMap= &xkb->server->vmodmap[rep->firstVModMapKey];
-    for (i=0;i<rep->nVModMapKeys-1;i++,pMap++) {
+    for (i=0;i<rep->nVModMapKeys;i++,pMap++) {
 	if (*pMap!=0) {
 	    wire->key= i+rep->firstVModMapKey;
 	    wire->vmods= *pMap;
@@ -5668,7 +5668,7 @@ ProcXkbGetKbdByName(ClientPtr client)
 	    mrep.present = 0;
 	    mrep.totalSyms = mrep.totalActs =
 		mrep.totalKeyBehaviors= mrep.totalKeyExplicit= 
-		mrep.totalModMapKeys= 0;
+		mrep.totalModMapKeys= mrep.totalVModMapKeys= 0;
 	    if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) {
 		mrep.present|= XkbKeyTypesMask;
 		mrep.firstType = 0;
@@ -5694,6 +5694,8 @@ ProcXkbGetKbdByName(ClientPtr client)
 			mrep.firstKeyExplicit = new->min_key_code;
 		mrep.nKeyActs = mrep.nKeyBehaviors = 
 			mrep.nKeyExplicit = XkbNumKeys(new);
+		mrep.firstVModMapKey= new->min_key_code;
+		mrep.nVModMapKeys= XkbNumKeys(new);
 	    }
 	    else {
 		mrep.virtualMods= 0;
commit c2785ae7eb6197bbfc75e92e99fffbb8ad8064da
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 14:29:13 2009 +1000

    dix: refuse events from disabled devices.
    
    If the device is disabled ("off"), it must not send events to a client.
    The driver shouldn't send events in that case anyway, but just to make sure
    we simply drop events coming while the device is disabled.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 30b2c69..2f61537 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -835,6 +835,10 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
     DeviceEvent *event;
     RawDeviceEvent *raw;
 
+    /* refuse events from disabled devices */
+    if (!pDev->enabled)
+        return 0;
+
     if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
        (type != KeyPress && type != KeyRelease) ||
        (key_code < 8 || key_code > 255))
@@ -997,6 +1001,10 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         cx, cy; /* only screen coordinates */
     ScreenPtr scr = miPointerGetScreen(pDev);
 
+    /* refuse events from disabled devices */
+    if (!pDev->enabled)
+        return 0;
+
     ms = GetTimeInMillis(); /* before pointer update to help precision */
 
     if (!scr || !pDev->valuator || first_valuator < 0 ||
@@ -1096,6 +1104,10 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
     int num_events = 1;
     DeviceEvent *event;
 
+    /* refuse events from disabled devices */
+    if (!pDev->enabled)
+        return 0;
+
     /* Sanity checks. */
     if (type != ProximityIn && type != ProximityOut)
         return 0;
commit 47a89b1cba67a43ddc225f7e1b5d2b3b217c8d93
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 13:59:22 2009 +1000

    Xi: remove DeviceIsPointerType
    
    This approach is broken anyway. DIPT only checked for the XInput type
    "MOUSE" and the only user of this is xf86ActivateDevice when it sets the
    Activate/DeactivateGrab functions.
    Since synaptics and wacom set their own types, evdev only sets MOUSE for,
    well, mice half the devices didn't have this set correctly anyway.
    
    Instead, ActivatePointerGrab should be merged together with
    ActivateKeyboardGrab.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index b828010..1f77729 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -1069,21 +1069,6 @@ IResetProc(ExtensionEntry * unused)
     RestoreExtensionEvents();
 }
 
-/*****************************************************************
- *
- * Returns TRUE if the device has some sort of pointer type.
- *
- */
-
-Bool
-DeviceIsPointerType(DeviceIntPtr dev)
-{
-    if (dev_type[1].type == dev->type)
-        return TRUE;
-
-    return FALSE;
-}
-
 
 /***********************************************************************
  *
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index aa98dad..6df0b8a 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -326,15 +326,8 @@ xf86ActivateDevice(LocalDevicePtr local)
         dev->isMaster = FALSE;
         dev->spriteInfo->spriteOwner = FALSE;
 
-        if (DeviceIsPointerType(dev))
-        {
-            dev->deviceGrab.ActivateGrab = ActivatePointerGrab;
-            dev->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
-        } else 
-        {
-            dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
-            dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
-        }
+        dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+        dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
 
         RegisterOtherDevice(dev);
         XkbSetExtension(dev, ProcessKeyboardEvent);
diff --git a/include/extinit.h b/include/extinit.h
index 340433a..0b36d3b 100644
--- a/include/extinit.h
+++ b/include/extinit.h
@@ -37,11 +37,6 @@ XInputExtensionInit(
 	void
 	);
 
-extern _X_EXPORT Bool
-DeviceIsPointerType(
-        DeviceIntPtr dev
-        );
-
 extern _X_EXPORT void
 AssignTypeAndName (
 	DeviceIntPtr           /* dev */,
commit 7b891e450f005688e41e61016e6d3e394c67f6be
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 14:23:16 2009 +1000

    dix: Remove obsolete comment
    
    CorePointerProc doesn't back up the device classes anymore.

diff --git a/dix/devices.c b/dix/devices.c
index bcb9058..ff91608 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -538,9 +538,6 @@ CoreKeyboardProc(DeviceIntPtr pDev, int what)
 
 /**
  * Device control function for the Virtual Core Pointer.
- *
- * Aside from initialisation, it backs up the original device classes into the
- * devicePrivates. This only needs to be done for master devices.
  */
 static int
 CorePointerProc(DeviceIntPtr pDev, int what)
commit 42719ce5c715ac3a0c74c3c7df872d35e0449de9
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 20 14:38:25 2009 +1000

    dix: remove superfluous loop in change_modmap.
    
    A device can only be attached to a single master device. So instead of
    looping and searching for the master device, we can just use dev->u.master
    directly.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/inpututils.c b/dix/inpututils.c
index c630088..1522145 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -275,14 +275,10 @@ change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap,
                     do_modmap_change(client, tmp, modmap);
         }
     }
-    else {
-        for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
-            if (tmp->isMaster && tmp->u.lastSlave == dev) {
-                /* If this fails, expect the results to be weird. */
-                if (check_modmap_change(client, tmp, modmap))
-                    do_modmap_change(client, tmp, modmap);
-            }
-        }
+    else if (dev->u.master && dev->u.master->u.lastSlave == dev) {
+        /* If this fails, expect the results to be weird. */
+        if (check_modmap_change(client, dev->u.master, modmap))
+            do_modmap_change(client, dev->u.master, modmap);
     }
 
     return Success;
commit b89dcfbfbd38f8d19f1d4f24f81820b1048572c8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 18 16:07:08 2009 +1000

    Xi: fix length field in XIQueryPointer.
    
    Buttons append 4-byte units to the end of the reply, they need to be
    included too.
    
    Reported-by: Mark Dokter
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/querydp.c b/Xi/querydp.c
index 2925dde..2e2cfaa 100644
--- a/Xi/querydp.c
+++ b/Xi/querydp.c
@@ -127,6 +127,7 @@ ProcXIQueryPointer(ClientPtr client)
     {
         int i, down;
         rep.buttons_len = ((pDev->button->numButtons/8) + 3)/4;
+        rep.length += rep.buttons_len;
         buttons = xcalloc(rep.buttons_len, 4);
         if (!buttons)
             return BadAlloc;
commit 33fcaaaea5ea30be39156ecfdbcca891b47ab465
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 18 16:05:35 2009 +1000

    Fix missing parentheses in FP1616 macro.
    
    Missing parens led to interesting results if an expression instead of a
    constant was passed in (ProcXIQueryPointer for example).

diff --git a/include/eventconvert.h b/include/eventconvert.h
index dc3fd73..277a6c4 100644
--- a/include/eventconvert.h
+++ b/include/eventconvert.h
@@ -28,7 +28,7 @@
 #include "input.h"
 #include "events.h"
 
-#define FP1616(integral, frac) (integral * (1 << 16) + frac * (1 << 16))
+#define FP1616(integral, frac) ((integral) * (1 << 16) + (frac) * (1 << 16))
 
 _X_INTERNAL int EventToCore(InternalEvent *event, xEvent *core);
 _X_INTERNAL int EventToXI(InternalEvent *ev, xEvent **xi, int *count);
commit 6258bb1d6bb78ea4ba1d33470bc74e9b711b25f2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 15 20:24:45 2009 +1000

    require inputproto 1.9.99.9

diff --git a/configure.ac b/configure.ac
index 98f9332..6c03951 100644
--- a/configure.ac
+++ b/configure.ac
@@ -700,7 +700,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la'
 XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
 
 dnl Core modules for most extensions, et al.
-REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.9.3] [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto [xextproto >= 7.0.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] bigreqsproto resourceproto fontsproto [inputproto >= 1.9.99.8] [kbproto >= 1.0.3]"
+REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.9.3] [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto [xextproto >= 7.0.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] bigreqsproto resourceproto fontsproto [inputproto >= 1.9.99.9] [kbproto >= 1.0.3]"
 REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.13.2]"
 
 dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
commit e7e94ff5fd3205a9ee01fe9342d9f3a426b0a068
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 14 21:45:35 2009 +1000

    Xi: set the right length for the XIQueryPointer reply.

diff --git a/Xi/querydp.c b/Xi/querydp.c
index d7df733..2925dde 100644
--- a/Xi/querydp.c
+++ b/Xi/querydp.c
@@ -107,7 +107,7 @@ ProcXIQueryPointer(ClientPtr client)
     pSprite = pDev->spriteInfo->sprite;
     rep.repType = X_Reply;
     rep.RepType = X_XIQueryPointer;
-    rep.length = 0;
+    rep.length = 5;
     rep.sequenceNumber = client->sequence;
     rep.root = (GetCurrentRootWindow(pDev))->drawable.id;
     rep.root_x = FP1616(pSprite->hot.x, 0);
commit 00ab04d73c612ac85e024105015bdb7c79e8874b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 14 16:24:35 2009 +1000

    Include full modifier + button state in XIQueryPointer.

diff --git a/Xi/querydp.c b/Xi/querydp.c
index dee00fe..d7df733 100644
--- a/Xi/querydp.c
+++ b/Xi/querydp.c
@@ -75,6 +75,8 @@ ProcXIQueryPointer(ClientPtr client)
     DeviceIntPtr pDev, kbd;
     WindowPtr pWin, t;
     SpritePtr pSprite;
+    XkbStatePtr state;
+    char *buttons = NULL;
 
     REQUEST(xXIQueryPointerReq);
     REQUEST_SIZE_MATCH(xXIQueryPointerReq);
@@ -107,14 +109,40 @@ ProcXIQueryPointer(ClientPtr client)
     rep.RepType = X_XIQueryPointer;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
-    rep.mask = pDev->button->state;
-    if (kbd && kbd->key)
-        rep.mask |= XkbStateFieldFromRec(&kbd->key->xkbInfo->state);
     rep.root = (GetCurrentRootWindow(pDev))->drawable.id;
     rep.root_x = FP1616(pSprite->hot.x, 0);
     rep.root_y = FP1616(pSprite->hot.y, 0);
     rep.child = None;
-    rep.deviceid = pDev->id;
+
+    state = &kbd->key->xkbInfo->prev_state;
+    rep.mods.base_mods = state->base_mods;
+    rep.mods.latched_mods = state->latched_mods;
+    rep.mods.locked_mods = state->locked_mods;
+
+    rep.group.base_group = state->base_group;
+    rep.group.latched_group = state->latched_group;
+    rep.group.locked_group = state->locked_group;
+
+    if (pDev->button)
+    {
+        int i, down;
+        rep.buttons_len = ((pDev->button->numButtons/8) + 3)/4;
+        buttons = xcalloc(rep.buttons_len, 4);
+        if (!buttons)
+            return BadAlloc;
+
+        down = pDev->button->buttonsDown;
+
+        for (i = 0; i < pDev->button->numButtons && down; i++)
+        {
+            if (BitIsOn(pDev->button->down, i))
+            {
+                SetBit(buttons, i);
+                down--;
+            }
+        }
+    } else
+        rep.buttons_len = 0;
 
     if (pSprite->hot.pScreen == pWin->drawable.pScreen)
     {
@@ -147,6 +175,11 @@ ProcXIQueryPointer(ClientPtr client)
 #endif
 
     WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep);
+    if (buttons)
+        WriteToClient(client, rep.buttons_len * 4, buttons);
+
+    xfree(buttons);
+
     return Success;
 }
 
commit de78aab0ea3a2d8c61222493f25911258dea65a2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 14 15:53:00 2009 +1000

    Xi: take the paired device as modifier device only for MD pointers.

diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 2b77d18..d2dabba 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -157,7 +157,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     if (!modifiers_failed)
         return BadAlloc;
 
-    if (dev->isMaster)
+    if (IsPointerDevice(dev) && dev->isMaster)
         mod_dev = GetPairedDevice(dev);
     else
         mod_dev = dev;
commit 0e089f9ceb0edec532078c6e1df7f642f7220fb5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 14 15:29:20 2009 +1000

    Xi: check cursor and grab_window before attempting the passive grab.
    
    Both values need to fail the request, so we need to check them before
    looping through the modifier masks. Otherwise, a wrong grab_window will
    show up in each failed modifier return but not actually cause an error.

diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 1ba534a..2b77d18 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -85,6 +85,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     xXIGrabModifierInfo *modifiers_failed;
     GrabMask mask;
     GrabParameters param;
+    void *tmp;
 
     REQUEST(xXIPassiveGrabDeviceReq);
     REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
@@ -134,6 +135,23 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     param.grabWindow = stuff->grab_window;
     param.cursor = stuff->cursor;
 
+    if (stuff->cursor != None)
+    {
+        status = dixLookupResourceByType(&tmp, stuff->cursor,
+                                         RT_CURSOR, client, DixUseAccess);
+	if (status != Success)
+	{
+	    client->errorValue = stuff->cursor;
+	    return (status == BadValue) ? BadCursor : status;
+	}
+    }
+
+    status = dixLookupWindow((WindowPtr*)&tmp, stuff->grab_window, client, DixSetAttrAccess);
+    if (status != Success)
+	return status;
+
+    status = CheckGrabValues(client, &param);
+
     modifiers = (uint32_t*)&stuff[1] + stuff->mask_len;
     modifiers_failed = xcalloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
     if (!modifiers_failed)
commit 5c3e7289801c958e2c70e2629d3ebee122449be8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 13 16:54:01 2009 +1000

    dix: count must be 1 if we have an XI2 match.
    
    This fixes events that activated a grab not getting delivered to the client.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index e1410ed..10814fa 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3420,6 +3420,7 @@ CheckPassiveGrabsOnWindow(
                            "(%d, %d).\n", device->name, event->type, rc);
                     continue;
                 }
+                count = 1;
             } else
             {
                 rc = EventToXI((InternalEvent*)event, &xE, &count);
commit e083a0d0692baa5ad29002a38293b36dd3b4c06f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 13 15:23:42 2009 +1000

    Xi: set the correct length for XIPassiveGrab replies.

diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 0a6f0e5..1ba534a 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -166,6 +166,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
             info->status = status;
             info->modifiers = *modifiers;
             rep.num_modifiers++;
+            rep.length++;
         }
     }
 
commit 8ff1bff8f462b15e05fc298704e1e40cb244587f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 12 21:33:54 2009 +1000

    Update to new XI2 names

diff --git a/Xi/chdevcur.c b/Xi/chdevcur.c
index ed1570b..0315edb 100644
--- a/Xi/chdevcur.c
+++ b/Xi/chdevcur.c
@@ -54,25 +54,25 @@
  */
 
 int
-SProcXIChangeDeviceCursor(ClientPtr client)
+SProcXIChangeCursor(ClientPtr client)
 {
     char n;
 
-    REQUEST(xXIChangeDeviceCursorReq);
+    REQUEST(xXIChangeCursorReq);
     swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xXIChangeDeviceCursorReq);
-    return (ProcXIChangeDeviceCursor(client));
+    REQUEST_SIZE_MATCH(xXIChangeCursorReq);
+    return (ProcXIChangeCursor(client));
 }
 
-int ProcXIChangeDeviceCursor(ClientPtr client)
+int ProcXIChangeCursor(ClientPtr client)
 {
     int rc;
     WindowPtr pWin    = NULL;
     DeviceIntPtr pDev = NULL;
     CursorPtr pCursor = NULL;
 
-    REQUEST(xXIChangeDeviceCursorReq);
-    REQUEST_SIZE_MATCH(xXIChangeDeviceCursorReq);
+    REQUEST(xXIChangeCursorReq);
+    REQUEST_SIZE_MATCH(xXIChangeCursorReq);
 
     rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixSetAttrAccess);
     if (rc != Success)
diff --git a/Xi/chdevcur.h b/Xi/chdevcur.h
index 4f7f44b..dc6ccb1 100644
--- a/Xi/chdevcur.h
+++ b/Xi/chdevcur.h
@@ -30,7 +30,7 @@
 #ifndef CHDEVCUR_H
 #define CHDEVCUR_H 1
 
-int SProcXIChangeDeviceCursor(ClientPtr	/* client */);
-int ProcXIChangeDeviceCursor(ClientPtr	/* client */);
+int SProcXIChangeCursor(ClientPtr /* client */);
+int ProcXIChangeCursor(ClientPtr /* client */);
 
 #endif /* CHDEVCUR_H */
diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
index ae5377d..e59bfab 100644
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@ -61,7 +61,7 @@ extern DevPrivateKey XTstDevicePrivateKey;
  */
 void XISendDeviceHierarchyEvent(int flags[MAXDEVICES])
 {
-    xXIDeviceHierarchyEvent *ev;
+    xXIHierarchyEvent *ev;
     xXIHierarchyInfo *info;
     DeviceIntRec dummyDev;
     DeviceIntPtr dev;
@@ -70,7 +70,7 @@ void XISendDeviceHierarchyEvent(int flags[MAXDEVICES])
     if (!flags)
         return;
 
-    ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) +
+    ev = xcalloc(1, sizeof(xXIHierarchyEvent) +
                  MAXDEVICES * sizeof(xXIHierarchyInfo));
     ev->type = GenericEvent;
     ev->extension = IReqCode;
@@ -128,29 +128,29 @@ void XISendDeviceHierarchyEvent(int flags[MAXDEVICES])
  *
  */
 
-int SProcXIChangeDeviceHierarchy(ClientPtr client)
+int SProcXIChangeHierarchy(ClientPtr client)
 {
     char n;
 
-    REQUEST(xXIChangeDeviceHierarchyReq);
+    REQUEST(xXIChangeHierarchyReq);
     swaps(&stuff->length, n);
-    return (ProcXIChangeDeviceHierarchy(client));
+    return (ProcXIChangeHierarchy(client));
 }
 
 #define SWAPIF(cmd) if (client->swapped) { cmd; }
 
 int
-ProcXIChangeDeviceHierarchy(ClientPtr client)
+ProcXIChangeHierarchy(ClientPtr client)
 {
     DeviceIntPtr ptr, keybd, xtstptr, xtstkeybd;
     xXIAnyHierarchyChangeInfo *any;
-    int required_len = sizeof(xXIChangeDeviceHierarchyReq);
+    int required_len = sizeof(xXIChangeHierarchyReq);
     char n;
     int rc = Success;
     int flags[MAXDEVICES] = {0};
 
-    REQUEST(xXIChangeDeviceHierarchyReq);
-    REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq);
+    REQUEST(xXIChangeHierarchyReq);
+    REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq);
 
     if (!stuff->num_changes)
         return rc;
@@ -167,7 +167,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
 
         switch(any->type)
         {
-            case XICreateMasterDevice:
+            case XICreateMaster:
                 {
                     xXICreateMasterInfo* c = (xXICreateMasterInfo*)any;
                     char* name;
@@ -229,7 +229,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                     xfree(name);
                 }
                 break;
-            case XIRemoveMasterDevice:
+            case XIRemoveMaster:
                 {
                     xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)any;
                     DeviceIntPtr xtstdevice;
diff --git a/Xi/chdevhier.h b/Xi/chdevhier.h
index d4ce517..b46cfb4 100644
--- a/Xi/chdevhier.h
+++ b/Xi/chdevhier.h
@@ -36,8 +36,8 @@
 #ifndef CHDEVHIER_H
 #define CHDEVHIER_H 1
 
-int SProcXIChangeDeviceHierarchy(ClientPtr /* client */);
-int ProcXIChangeDeviceHierarchy(ClientPtr /* client */);
+int SProcXIChangeHierarchy(ClientPtr /* client */);
+int ProcXIChangeHierarchy(ClientPtr /* client */);
 
 void XISendDeviceHierarchyEvent(int flags[]);
 
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 4b82f62..b828010 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -235,17 +235,17 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXDeleteDeviceProperty,              /* 38 */
         ProcXGetDeviceProperty,                 /* 39 */
         /* XI 2 */
-        ProcXIQueryDevicePointer,               /* 40 */
-        ProcXIWarpDevicePointer,                /* 41 */
-        ProcXIChangeDeviceCursor,               /* 42 */
-        ProcXIChangeDeviceHierarchy,            /* 43 */
+        ProcXIQueryPointer,                     /* 40 */
+        ProcXIWarpPointer,                      /* 41 */
+        ProcXIChangeCursor,                     /* 42 */
+        ProcXIChangeHierarchy,                  /* 43 */
         ProcXISetClientPointer,                 /* 44 */
         ProcXIGetClientPointer,                 /* 45 */
         ProcXISelectEvent,                      /* 46 */
         ProcXIQueryVersion,                     /* 47 */
         ProcXIQueryDevice,                      /* 48 */
-        ProcXISetDeviceFocus,                   /* 49 */
-        ProcXIGetDeviceFocus,                   /* 50 */
+        ProcXISetFocus,                         /* 49 */
+        ProcXIGetFocus,                         /* 50 */
         ProcXIGrabDevice,                       /* 51 */
         ProcXIUngrabDevice,                     /* 52 */
         ProcXIAllowEvents,                      /* 53 */
@@ -299,17 +299,17 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXChangeDeviceProperty,              /* 37 */
         SProcXDeleteDeviceProperty,              /* 38 */
         SProcXGetDeviceProperty,                 /* 39 */
-        SProcXIQueryDevicePointer,               /* 40 */
-        SProcXIWarpDevicePointer,                /* 41 */
-        SProcXIChangeDeviceCursor,               /* 42 */
-        SProcXIChangeDeviceHierarchy,            /* 43 */
+        SProcXIQueryPointer,                     /* 40 */
+        SProcXIWarpPointer,                      /* 41 */
+        SProcXIChangeCursor,                     /* 42 */
+        SProcXIChangeHierarchy,                  /* 43 */
         SProcXISetClientPointer,                 /* 44 */
         SProcXIGetClientPointer,                 /* 45 */
         SProcXISelectEvent,                      /* 46 */
         SProcXIQueryVersion,                     /* 47 */
         SProcXIQueryDevice,                      /* 48 */
-        SProcXISetDeviceFocus,                   /* 49 */
-        SProcXIGetDeviceFocus,                   /* 50 */
+        SProcXISetFocus,                         /* 49 */
+        SProcXIGetFocus,                         /* 50 */
         SProcXIGrabDevice,                       /* 51 */
         SProcXIUngrabDevice,                     /* 52 */
         SProcXIAllowEvents,                      /* 53 */
@@ -502,9 +502,8 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
         SRepXListDeviceProperties(client, len, (xListDevicePropertiesReply*)rep);
     else if (rep->RepType == X_GetDeviceProperty)
 	SRepXGetDeviceProperty(client, len, (xGetDevicePropertyReply *) rep);
-    else if (rep->RepType == X_XIQueryDevicePointer)
-	SRepXIQueryDevicePointer(client, len,
-				(xXIQueryDevicePointerReply *) rep);
+    else if (rep->RepType == X_XIQueryPointer)
+	SRepXIQueryPointer(client, len, (xXIQueryPointerReply *) rep);
     else if (rep->RepType == X_XIGetClientPointer)
         SRepXIGetClientPointer(client, len, (xXIGetClientPointerReply*) rep);
     else if (rep->RepType == X_XIQueryDevice)
@@ -763,8 +762,8 @@ static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to)
     }
 }
 
-static void SDeviceHierarchyEvent(xXIDeviceHierarchyEvent *from,
-                                  xXIDeviceHierarchyEvent *to)
+static void SDeviceHierarchyEvent(xXIHierarchyEvent *from,
+                                  xXIHierarchyEvent *to)
 {
     int i;
     char n;
@@ -816,8 +815,7 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
                                 (xXIDeviceChangedEvent*)to);
             break;
         case XI_HierarchyChanged:
-            SDeviceHierarchyEvent((xXIDeviceHierarchyEvent*)from,
-                                  (xXIDeviceHierarchyEvent*)to);
+            SDeviceHierarchyEvent((xXIHierarchyEvent*)from, (xXIHierarchyEvent*)to);
             break;
         case XI_PropertyEvent:
             SXIPropertyEvent((xXIPropertyEvent*)from,
diff --git a/Xi/querydp.c b/Xi/querydp.c
index 1b45ae2..dee00fe 100644
--- a/Xi/querydp.c
+++ b/Xi/querydp.c
@@ -58,26 +58,26 @@
  */
 
 int
-SProcXIQueryDevicePointer(ClientPtr client)
+SProcXIQueryPointer(ClientPtr client)
 {
     char n;
 
-    REQUEST(xXIQueryDevicePointerReq);
+    REQUEST(xXIQueryPointerReq);
     swaps(&stuff->length, n);
-    return (ProcXIQueryDevicePointer(client));
+    return (ProcXIQueryPointer(client));
 }
 
 int
-ProcXIQueryDevicePointer(ClientPtr client)
+ProcXIQueryPointer(ClientPtr client)
 {
     int rc;
-    xXIQueryDevicePointerReply rep;
+    xXIQueryPointerReply rep;
     DeviceIntPtr pDev, kbd;
     WindowPtr pWin, t;
     SpritePtr pSprite;
 
-    REQUEST(xXIQueryDevicePointerReq);
-    REQUEST_SIZE_MATCH(xXIQueryDevicePointerReq);
+    REQUEST(xXIQueryPointerReq);
+    REQUEST_SIZE_MATCH(xXIQueryPointerReq);
 
     rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess);
     if (rc != Success)
@@ -92,7 +92,7 @@ ProcXIQueryDevicePointer(ClientPtr client)
     rc = dixLookupWindow(&pWin, stuff->win, client, DixReadAccess);
     if (rc != Success)
     {
-        SendErrorToClient(client, IReqCode, X_XIQueryDevicePointer,
+        SendErrorToClient(client, IReqCode, X_XIQueryPointer,
                 stuff->win, rc);
         return Success;
     }
@@ -104,7 +104,7 @@ ProcXIQueryDevicePointer(ClientPtr client)
 
     pSprite = pDev->spriteInfo->sprite;
     rep.repType = X_Reply;
-    rep.RepType = X_XIQueryDevicePointer;
+    rep.RepType = X_XIQueryPointer;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
     rep.mask = pDev->button->state;
@@ -146,20 +146,20 @@ ProcXIQueryDevicePointer(ClientPtr client)
     }
 #endif
 
-    WriteReplyToClient(client, sizeof(xXIQueryDevicePointerReply), &rep);
+    WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep);
     return Success;
 }
 
 /***********************************************************************
  *
- * This procedure writes the reply for the XIQueryDevicePointer function,
+ * This procedure writes the reply for the XIQueryPointer function,
  * if the client and server have a different byte ordering.
  *
  */
 
 void
-SRepXIQueryDevicePointer(ClientPtr client, int size,
-        xXIQueryDevicePointerReply * rep)
+SRepXIQueryPointer(ClientPtr client, int size,
+                   xXIQueryPointerReply * rep)
 {
     char n;
 
diff --git a/Xi/querydp.h b/Xi/querydp.h
index 48b6217..ea22376 100644
--- a/Xi/querydp.h
+++ b/Xi/querydp.h
@@ -30,10 +30,10 @@
 #ifndef QUERYDP_H
 #define QUERYDP_H 1
 
-int SProcXIQueryDevicePointer(ClientPtr	/* client */);
-int ProcXIQueryDevicePointer(ClientPtr	/* client */);
-void SRepXIQueryDevicePointer(ClientPtr /* client */ ,
-			   int /* size */ ,
-			   xXIQueryDevicePointerReply *	/* rep */);
+int SProcXIQueryPointer(ClientPtr /* client */);
+int ProcXIQueryPointer(ClientPtr /* client */);
+void SRepXIQueryPointer(ClientPtr /* client */ ,
+			int /* size */ ,
+			xXIQueryPointerReply *	/* rep */);
 
 #endif /* QUERYDP_H */
diff --git a/Xi/warpdevp.c b/Xi/warpdevp.c
index 2317c86..025a4ce 100644
--- a/Xi/warpdevp.c
+++ b/Xi/warpdevp.c
@@ -54,17 +54,17 @@
  */
 
 int
-SProcXIWarpDevicePointer(ClientPtr client)
+SProcXIWarpPointer(ClientPtr client)
 {
     char n;
 
-    REQUEST(xXIWarpDevicePointerReq);
+    REQUEST(xXIWarpPointerReq);
     swaps(&stuff->length, n);
-    return (ProcXIWarpDevicePointer(client));
+    return (ProcXIWarpPointer(client));
 }
 
 int
-ProcXIWarpDevicePointer(ClientPtr client)
+ProcXIWarpPointer(ClientPtr client)
 {
     int rc;
     int x, y;
@@ -73,8 +73,8 @@ ProcXIWarpDevicePointer(ClientPtr client)
     SpritePtr pSprite;
     ScreenPtr newScreen;
 
-    REQUEST(xXIWarpDevicePointerReq);
-    REQUEST_SIZE_MATCH(xXIWarpDevicePointerReq);
+    REQUEST(xXIWarpPointerReq);
+    REQUEST_SIZE_MATCH(xXIWarpPointerReq);
 
     /* FIXME: panoramix stuff is missing, look at ProcWarpPointer */
 
diff --git a/Xi/warpdevp.h b/Xi/warpdevp.h
index edf95c0..aafc739 100644
--- a/Xi/warpdevp.h
+++ b/Xi/warpdevp.h
@@ -30,7 +30,7 @@
 #ifndef WARPDEVP_H
 #define WARPDEVP_H 1
 
-int SProcXIWarpDevicePointer(ClientPtr	/* client */);
-int ProcXIWarpDevicePointer(ClientPtr	/* client */);
+int SProcXIWarpPointer(ClientPtr /* client */);
+int ProcXIWarpPointer(ClientPtr	/* client */);
 
 #endif /* WARPDEVP_H */
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index 601dec3..7309773 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -41,7 +41,7 @@ SProcXISelectEvent(ClientPtr client)
 {
     char n;
     int i;
-    xXIDeviceEventMask* evmask;
+    xXIEventMask* evmask;
 
     REQUEST(xXISelectEventsReq);
     swaps(&stuff->length, n);
@@ -49,12 +49,12 @@ SProcXISelectEvent(ClientPtr client)
     swapl(&stuff->window, n);
     swaps(&stuff->num_masks, n);
 
-    evmask = (xXIDeviceEventMask*)&stuff[1];
+    evmask = (xXIEventMask*)&stuff[1];
     for (i = 0; i < stuff->num_masks; i++)
     {
         swaps(&evmask->deviceid, n);
         swaps(&evmask->mask_len, n);
-        evmask = (xXIDeviceEventMask*)(((char*)evmask) + evmask->mask_len * 4);
+        evmask = (xXIEventMask*)(((char*)evmask) + evmask->mask_len * 4);
     }
 
     return (ProcXISelectEvent(client));
@@ -67,7 +67,7 @@ ProcXISelectEvent(ClientPtr client)
     WindowPtr win;
     DeviceIntPtr dev;
     DeviceIntRec dummy;
-    xXIDeviceEventMask *evmask;
+    xXIEventMask *evmask;
     int *types = NULL;
 
     REQUEST(xXISelectEventsReq);
@@ -78,7 +78,7 @@ ProcXISelectEvent(ClientPtr client)
         return rc;
 
     /* check request validity */
-    evmask = (xXIDeviceEventMask*)&stuff[1];
+    evmask = (xXIEventMask*)&stuff[1];
     num_masks = stuff->num_masks;
     while(num_masks--)
     {
@@ -102,11 +102,11 @@ ProcXISelectEvent(ClientPtr client)
             }
         }
 
-        evmask = (xXIDeviceEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+        evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
     }
 
     /* Set masks on window */
-    evmask = (xXIDeviceEventMask*)&stuff[1];
+    evmask = (xXIEventMask*)&stuff[1];
     num_masks = stuff->num_masks;
     while(num_masks--)
     {
@@ -118,7 +118,7 @@ ProcXISelectEvent(ClientPtr client)
         } else
             dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess);
         XISetEventMask(dev, win, client, evmask->mask_len * 4, (unsigned char*)&evmask[1]);
-        evmask = (xXIDeviceEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+        evmask = (xXIEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
     }
 
     RecalculateDeliverableEvents(win);
diff --git a/Xi/xisetdevfocus.c b/Xi/xisetdevfocus.c
index 7201e65..32f7e59 100644
--- a/Xi/xisetdevfocus.c
+++ b/Xi/xisetdevfocus.c
@@ -41,39 +41,39 @@
 #include "xisetdevfocus.h"
 
 int
-SProcXISetDeviceFocus(ClientPtr client)
+SProcXISetFocus(ClientPtr client)
 {
     char n;
 
-    REQUEST(xXISetDeviceFocusReq);
+    REQUEST(xXISetFocusReq);
     swaps(&stuff->length, n);
     swaps(&stuff->deviceid, n);
     swapl(&stuff->focus, n);
     swapl(&stuff->time, n);
 
-    return ProcXISetDeviceFocus(client);
+    return ProcXISetFocus(client);
 }
 
 int
-SProcXIGetDeviceFocus(ClientPtr client)
+SProcXIGetFocus(ClientPtr client)
 {
     char n;
 
-    REQUEST(xXIGetDeviceFocusReq);
+    REQUEST(xXIGetFocusReq);
     swaps(&stuff->length, n);
     swaps(&stuff->deviceid, n);
 
-    return ProcXIGetDeviceFocus(client);
+    return ProcXIGetFocus(client);
 }
 
 int
-ProcXISetDeviceFocus(ClientPtr client)
+ProcXISetFocus(ClientPtr client)
 {
     DeviceIntPtr dev;
     int ret;
 
-    REQUEST(xXISetDeviceFocusReq);
-    REQUEST_AT_LEAST_SIZE(xXISetDeviceFocusReq);
+    REQUEST(xXISetFocusReq);
+    REQUEST_AT_LEAST_SIZE(xXISetFocusReq);
 
     ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
     if (ret != Success)
@@ -86,14 +86,14 @@ ProcXISetDeviceFocus(ClientPtr client)
 }
 
 int
-ProcXIGetDeviceFocus(ClientPtr client)
+ProcXIGetFocus(ClientPtr client)
 {
-    xXIGetDeviceFocusReply rep;
+    xXIGetFocusReply rep;
     DeviceIntPtr dev;
     int ret;
 
-    REQUEST(xXIGetDeviceFocusReq);
-    REQUEST_AT_LEAST_SIZE(xXIGetDeviceFocusReq);
+    REQUEST(xXIGetFocusReq);
+    REQUEST_AT_LEAST_SIZE(xXIGetFocusReq);
 
     ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetFocusAccess);
     if (ret != Success)
@@ -102,7 +102,7 @@ ProcXIGetDeviceFocus(ClientPtr client)
 	return BadDevice;
 
     rep.repType = X_Reply;
-    rep.RepType = X_XIGetDeviceFocus;
+    rep.RepType = X_XIGetFocus;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
@@ -115,6 +115,6 @@ ProcXIGetDeviceFocus(ClientPtr client)
     else
 	rep.focus = dev->focus->win->drawable.id;
 
-    WriteReplyToClient(client, sizeof(xXIGetDeviceFocusReply), &rep);
+    WriteReplyToClient(client, sizeof(xXIGetFocusReply), &rep);
     return Success;
 }
diff --git a/Xi/xisetdevfocus.h b/Xi/xisetdevfocus.h
index 9bdeb77..5ec1fa2 100644
--- a/Xi/xisetdevfocus.h
+++ b/Xi/xisetdevfocus.h
@@ -26,10 +26,10 @@
 #ifndef XISETDEVFOCUS_H
 #define XISETDEVFOCUS_H 1
 
-int SProcXISetDeviceFocus(ClientPtr client);
-int ProcXISetDeviceFocus(ClientPtr client);
+int SProcXISetFocus(ClientPtr client);
+int ProcXISetFocus(ClientPtr client);
 
-int SProcXIGetDeviceFocus(ClientPtr client);
-int ProcXIGetDeviceFocus(ClientPtr client);
+int SProcXIGetFocus(ClientPtr client);
+int ProcXIGetFocus(ClientPtr client);
 
 #endif /* XISETDEVFOCUS_H */
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 58fd6d2..97fc2ad 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -422,9 +422,9 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
 static int
 eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
 {
-    xXIRawDeviceEvent* raw;
+    xXIRawEvent* raw;
     int vallen, nvals;
-    int i, len = sizeof(xXIRawDeviceEvent);
+    int i, len = sizeof(xXIRawEvent);
     char *ptr;
     FP3232 *axisval;
 
@@ -435,7 +435,7 @@ eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
     len += vallen * 4; /* valuators mask */
 
     *xi = xcalloc(1, len);
-    raw = (xXIRawDeviceEvent*)*xi;
+    raw = (xXIRawEvent*)*xi;
     raw->type           = GenericEvent;
     raw->extension      = IReqCode;
     raw->evtype         = GetXI2Type((InternalEvent*)ev);
diff --git a/test/input.c b/test/input.c
index 238cad3..cca1291 100644
--- a/test/input.c
+++ b/test/input.c
@@ -284,16 +284,16 @@ static void xi2_struct_sizes(void)
     g_assert(sizeof(req) == sz_##req);
 
     compare(xXIQueryVersionReq);
-    compare(xXIWarpDevicePointerReq);
-    compare(xXIChangeDeviceCursorReq);
-    compare(xXIChangeDeviceHierarchyReq);
+    compare(xXIWarpPointerReq);
+    compare(xXIChangeCursorReq);
+    compare(xXIChangeHierarchyReq);
     compare(xXISetClientPointerReq);
     compare(xXIGetClientPointerReq);
     compare(xXISelectEventsReq);
     compare(xXIQueryVersionReq);
     compare(xXIQueryDeviceReq);
-    compare(xXISetDeviceFocusReq);
-    compare(xXIGetDeviceFocusReq);
+    compare(xXISetFocusReq);
+    compare(xXIGetFocusReq);
     compare(xXIGrabDeviceReq);
     compare(xXIUngrabDeviceReq);
     compare(xXIAllowEventsReq);
commit bbf266cca3de726e3eb932d66dd5b8981ef40fa8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 12 21:24:07 2009 +1000

    mi: un-deprecate miPointerWarpCursor
    
    This function was deprecated in ef68273f5bdb27a492ec0b69548ec4fbede46c08
    because it didn't take a device argument. The device argument was added in
    1c7568b8a1417257fa67c7fca69aa253099b9461 though, so the deprecation is
    obsolete.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mipointer.h b/mi/mipointer.h
index f385b7e..22575ea 100644
--- a/mi/mipointer.h
+++ b/mi/mipointer.h
@@ -108,7 +108,7 @@ extern _X_EXPORT void miPointerWarpCursor(
     ScreenPtr /*pScreen*/,
     int /*x*/,
     int /*y*/
-) _X_DEPRECATED;
+);
 
 /* Deprecated in favour of miPointerGetScreen. */
 extern _X_EXPORT ScreenPtr miPointerCurrentScreen(
commit 273890924b8ed6f8b7949c0322c8258b9e6f8630
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 12 16:09:35 2009 +1000

    input: reduce the number of superfluous hierarchy events
    
    There's only two reasons for hierarchy events:
    - device is added, removed, etc. In this case we want to send the event as
      it happens.
    - devices are added in a XIChangeDeviceHierarchy request. In this case we
      only want one event cumulating all changes.

diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
index 1aaa371..ae5377d 100644
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@ -196,25 +196,25 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                         goto unwind;
                     }
 
-                    ActivateDevice(ptr);
-                    ActivateDevice(keybd);
+                    ActivateDevice(ptr, FALSE);
+                    ActivateDevice(keybd, FALSE);
                     flags[ptr->id] |= XIMasterAdded;
                     flags[keybd->id] |= XIMasterAdded;
 
-                    ActivateDevice(xtstptr);
-                    ActivateDevice(xtstkeybd);
+                    ActivateDevice(xtstptr, FALSE);
+                    ActivateDevice(xtstkeybd, FALSE);
                     flags[xtstptr->id] |= XISlaveAdded;
                     flags[xtstkeybd->id] |= XISlaveAdded;
 
                     if (c->enable)
                     {
-                        EnableDevice(ptr);
-                        EnableDevice(keybd);
+                        EnableDevice(ptr, FALSE);
+                        EnableDevice(keybd, FALSE);
                         flags[ptr->id] |= XIDeviceEnabled;
                         flags[keybd->id] |= XIDeviceEnabled;
 
-                        EnableDevice(xtstptr);
-                        EnableDevice(xtstkeybd);
+                        EnableDevice(xtstptr, FALSE);
+                        EnableDevice(xtstkeybd, FALSE);
                         flags[xtstptr->id] |= XIDeviceEnabled;
                         flags[xtstkeybd->id] |= XIDeviceEnabled;
                     }
@@ -389,19 +389,19 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
 
                     /* disable the remove the devices, xtst devices must be done first
                        else the sprites they rely on will be destroyed  */
-                    DisableDevice(xtstptr);
-                    DisableDevice(xtstkeybd);
-                    DisableDevice(keybd);
-                    DisableDevice(ptr);
+                    DisableDevice(xtstptr, FALSE);
+                    DisableDevice(xtstkeybd, FALSE);
+                    DisableDevice(keybd, FALSE);
+                    DisableDevice(ptr, FALSE);
                     flags[xtstptr->id] |= XIDeviceDisabled | XISlaveDetached;
                     flags[xtstkeybd->id] |= XIDeviceDisabled | XISlaveDetached;
                     flags[keybd->id] |= XIDeviceDisabled;
                     flags[ptr->id] |= XIDeviceDisabled;
 
-                    RemoveDevice(xtstptr);
-                    RemoveDevice(xtstkeybd);
-                    RemoveDevice(keybd);
-                    RemoveDevice(ptr);
+                    RemoveDevice(xtstptr, FALSE);
+                    RemoveDevice(xtstkeybd, FALSE);
+                    RemoveDevice(keybd, FALSE);
+                    RemoveDevice(ptr, FALSE);
                     flags[xtstptr->id] |= XISlaveRemoved;
                     flags[xtstkeybd->id] |= XISlaveRemoved;
                     flags[keybd->id] |= XIMasterRemoved;
diff --git a/Xi/chgdctl.c b/Xi/chgdctl.c
index f5dd08a..89e5a2d 100644
--- a/Xi/chgdctl.c
+++ b/Xi/chgdctl.c
@@ -253,9 +253,9 @@ ProcXChangeDeviceControl(ClientPtr client)
 
         if (status == Success) {
             if (e->enable)
-                EnableDevice(dev);
+                EnableDevice(dev, TRUE);
             else
-                DisableDevice(dev);
+                DisableDevice(dev, TRUE);
             ret = Success;
         } else if (status == DeviceBusy) {
             rep.status = DeviceBusy;
diff --git a/dix/devices.c b/dix/devices.c
index c59457f..bcb9058 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -130,9 +130,9 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
         if (!checkonly)
         {
             if ((*((CARD8*)prop->data)) && !dev->enabled)
-                EnableDevice(dev);
+                EnableDevice(dev, TRUE);
             else if (!(*((CARD8*)prop->data)) && dev->enabled)
-                DisableDevice(dev);
+                DisableDevice(dev, TRUE);
         }
     }
 
@@ -284,10 +284,11 @@ SendDevicePresenceEvent(int deviceid, int type)
  * device.
  *
  * @param The device to be enabled.
+ * @param sendevent True if an XI2 event should be sent.
  * @return TRUE on success or FALSE otherwise.
  */
 Bool
-EnableDevice(DeviceIntPtr dev)
+EnableDevice(DeviceIntPtr dev, BOOL sendevent)
 {
     DeviceIntPtr *prev;
     int ret;
@@ -362,8 +363,11 @@ EnableDevice(DeviceIntPtr dev)
                            TRUE);
 
     SendDevicePresenceEvent(dev->id, DeviceEnabled);
-    flags[dev->id] |= XIDeviceEnabled;
-    XISendDeviceHierarchyEvent(flags);
+    if (sendevent)
+    {
+        flags[dev->id] |= XIDeviceEnabled;
+        XISendDeviceHierarchyEvent(flags);
+    }
 
     return TRUE;
 }
@@ -376,10 +380,11 @@ EnableDevice(DeviceIntPtr dev)
  * Master keyboard devices have to be disabled before master pointer devices
  * otherwise things turn bad.
  *
+ * @param sendevent True if an XI2 event should be sent.
  * @return TRUE on success or FALSE otherwise.
  */
 Bool
-DisableDevice(DeviceIntPtr dev)
+DisableDevice(DeviceIntPtr dev, BOOL sendevent)
 {
     DeviceIntPtr *prev, other;
     BOOL enabled;
@@ -438,8 +443,11 @@ DisableDevice(DeviceIntPtr dev)
                            TRUE);
 
     SendDevicePresenceEvent(dev->id, DeviceDisabled);
-    flags[dev->id] = XIDeviceDisabled;
-    XISendDeviceHierarchyEvent(flags);
+    if (sendevent)
+    {
+        flags[dev->id] = XIDeviceDisabled;
+        XISendDeviceHierarchyEvent(flags);
+    }
     return TRUE;
 }
 
@@ -450,14 +458,14 @@ DisableDevice(DeviceIntPtr dev)
  * Must be called before EnableDevice.
  * The device will NOT send events until it is enabled!
  *
+ * @param sendevent True if an XI2 event should be sent.
  * @return Success or an error code on failure.
  */
 int
-ActivateDevice(DeviceIntPtr dev)
+ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
 {
     int ret = Success;
     ScreenPtr pScreen = screenInfo.screens[0];
-    int flags[MAXDEVICES];
 
     if (!dev || !dev->deviceProc)
         return BadImplementation;
@@ -472,8 +480,12 @@ ActivateDevice(DeviceIntPtr dev)
         pScreen->DeviceCursorInitialize(dev, pScreen);
 
     SendDevicePresenceEvent(dev->id, DeviceAdded);
-    flags[dev->id] = XISlaveAdded;
-    XISendDeviceHierarchyEvent(flags);
+    if (sendevent)
+    {
+        int flags[MAXDEVICES] = {0};
+        flags[dev->id] = XISlaveAdded;
+        XISendDeviceHierarchyEvent(flags);
+    }
     return ret;
 }
 
@@ -580,11 +592,11 @@ InitCoreDevices(void)
                         TRUE) != Success)
         FatalError("Failed to allocate core devices");
 
-    if (ActivateDevice(inputInfo.pointer) != Success ||
-        ActivateDevice(inputInfo.keyboard) != Success)
+    if (ActivateDevice(inputInfo.pointer, TRUE) != Success ||
+        ActivateDevice(inputInfo.keyboard, TRUE) != Success)
         FatalError("Failed to activate core devices.");
-    if (!EnableDevice(inputInfo.pointer) ||
-        !EnableDevice(inputInfo.keyboard))
+    if (!EnableDevice(inputInfo.pointer, TRUE) ||
+        !EnableDevice(inputInfo.keyboard, TRUE))
         FatalError("Failed to enable core devices.");
 
     /*
@@ -596,11 +608,11 @@ InitCoreDevices(void)
                        &vxtstkeyboard) != Success)
         FatalError("Failed to allocate XTst devices");
 
-    if (ActivateDevice(vxtstpointer) != Success ||
-        ActivateDevice(vxtstkeyboard) != Success)
+    if (ActivateDevice(vxtstpointer, TRUE) != Success ||
+        ActivateDevice(vxtstkeyboard, TRUE) != Success)
         FatalError("Failed to activate xtst core devices.");
-    if (!EnableDevice(vxtstpointer) ||
-        !EnableDevice(vxtstkeyboard))
+    if (!EnableDevice(vxtstpointer, TRUE) ||
+        !EnableDevice(vxtstkeyboard, TRUE))
         FatalError("Failed to enable xtst core devices.");
 
     AttachDevice(NULL, vxtstpointer, inputInfo.pointer);
@@ -627,7 +639,7 @@ InitAndStartDevices(void)
     for (dev = inputInfo.off_devices; dev; dev = dev->next) {
         DebugF("(dix) initialising device %d\n", dev->id);
         if (!dev->inited)
-            ActivateDevice(dev);
+            ActivateDevice(dev, TRUE);
     }
 
     /* enable real devices */
@@ -636,7 +648,7 @@ InitAndStartDevices(void)
         DebugF("(dix) enabling device %d\n", dev->id);
 	next = dev->next;
 	if (dev->inited && dev->startup)
-	    (void)EnableDevice(dev);
+	    EnableDevice(dev, TRUE);
     }
 
     return Success;
@@ -929,9 +941,11 @@ UndisplayDevices(void)
  * happen if a malloc fails during the addition of master devices. If
  * dev->init is FALSE it means the client never received a DeviceAdded event,
  * so let's not send a DeviceRemoved event either.
+ *
+ * @param sendevent True if an XI2 event should be sent.
  */
 int
-RemoveDevice(DeviceIntPtr dev)
+RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
 {
     DeviceIntPtr prev,tmp,next;
     int ret = BadMatch;
@@ -953,7 +967,7 @@ RemoveDevice(DeviceIntPtr dev)
         if (DevHasCursor(dev))
             screen->DisplayCursor(dev, screen, NullCursor);
 
-        DisableDevice(dev);
+        DisableDevice(dev, sendevent);
         flags[dev->id] = XIDeviceDisabled;
     }
 
@@ -992,7 +1006,8 @@ RemoveDevice(DeviceIntPtr dev)
     if (ret == Success && initialized) {
         inputInfo.numDevices--;
         SendDevicePresenceEvent(deviceid, DeviceRemoved);
-        XISendDeviceHierarchyEvent(flags);
+        if (sendevent)
+            XISendDeviceHierarchyEvent(flags);
     }
 
     return ret;
@@ -2360,7 +2375,7 @@ AllocDevicePair (ClientPtr client, char* name,
     keyboard = AddInputDevice(client, CoreKeyboardProc, TRUE);
     if (!keyboard)
     {
-        RemoveDevice(pointer);
+        RemoveDevice(pointer, FALSE);
         return BadAlloc;
     }
 
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index e9b4dfe..98175e9 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -462,7 +462,7 @@ xf86VTSwitch(void)
       if (pInfo->dev) {
           xf86ReleaseKeys(pInfo->dev);
           ProcessInputEvents();
-          DisableDevice(pInfo->dev);
+          DisableDevice(pInfo->dev, TRUE);
       }
     }
     xf86EnterServerState(SETUP);
@@ -497,7 +497,7 @@ xf86VTSwitch(void)
       pInfo = xf86InputDevs;
       while (pInfo) {
         if (pInfo->dev)
-            EnableDevice(pInfo->dev);
+            EnableDevice(pInfo->dev, TRUE);
 	pInfo = pInfo->next;
       }
       for (ih = InputHandlers; ih; ih = ih->next)
@@ -555,7 +555,7 @@ xf86VTSwitch(void)
     pInfo = xf86InputDevs;
     while (pInfo) {
       if (pInfo->dev)
-          EnableDevice(pInfo->dev);
+          EnableDevice(pInfo->dev, TRUE);
       pInfo = pInfo->next;
     }
 
diff --git a/hw/xfree86/common/xf86PM.c b/hw/xfree86/common/xf86PM.c
index 7c8320d..c51960e 100644
--- a/hw/xfree86/common/xf86PM.c
+++ b/hw/xfree86/common/xf86PM.c
@@ -76,7 +76,7 @@ suspend (pmEvent event, Bool undo)
     }
     pInfo = xf86InputDevs;
     while (pInfo) {
-	DisableDevice(pInfo->dev);
+	DisableDevice(pInfo->dev, TRUE);
 	pInfo = pInfo->next;
     }
     xf86EnterServerState(SETUP);
@@ -119,7 +119,7 @@ resume(pmEvent event, Bool undo)
     dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
     pInfo = xf86InputDevs;
     while (pInfo) {
-	EnableDevice(pInfo->dev);
+	EnableDevice(pInfo->dev, TRUE);
 	pInfo = pInfo->next;
     }
     xf86inSuspend = FALSE;
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 6b34aad..aa98dad 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -377,7 +377,7 @@ OpenInputDevice(DeviceIntPtr	dev,
                 int		*status)
 {
     if (!dev->inited)
-        ActivateDevice(dev);
+        ActivateDevice(dev, TRUE);
 
     *status = Success;
 }
@@ -544,18 +544,18 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
     }
 
     dev = pInfo->dev;
-    rval = ActivateDevice(dev);
+    rval = ActivateDevice(dev, TRUE);
     if (rval != Success)
     {
         xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
-        RemoveDevice(dev);
+        RemoveDevice(dev, TRUE);
         goto unwind;
     }
 
     /* Enable it if it's properly initialised and we're currently in the VT */
     if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema)
     {
-        EnableDevice(dev);
+        EnableDevice(dev, TRUE);
         if (!dev->enabled)
         {
             xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
@@ -680,7 +680,7 @@ DeleteInputDeviceRequest(DeviceIntPtr pDev)
     }
 
     OsBlockSignals();
-    RemoveDevice(pDev);
+    RemoveDevice(pDev, TRUE);
 
     if (!isMaster && pInfo != NULL)
     {
@@ -1065,7 +1065,7 @@ xf86DisableDevice(DeviceIntPtr dev, Bool panic)
 
     if(!panic)
     {
-        DisableDevice(dev);
+        DisableDevice(dev, TRUE);
     } else
     {
         ev.type = DevicePresenceNotify;
@@ -1088,7 +1088,7 @@ xf86DisableDevice(DeviceIntPtr dev, Bool panic)
 void
 xf86EnableDevice(DeviceIntPtr dev)
 {
-    EnableDevice(dev);
+    EnableDevice(dev, TRUE);
 }
 
 /* end of xf86Xinput.c */
diff --git a/include/input.h b/include/input.h
index e3509a9..44990a0 100644
--- a/include/input.h
+++ b/include/input.h
@@ -228,13 +228,16 @@ extern _X_EXPORT DeviceIntPtr AddInputDevice(
     Bool /*autoStart*/);
 
 extern _X_EXPORT Bool EnableDevice(
-    DeviceIntPtr /*device*/);
+    DeviceIntPtr /*device*/,
+    BOOL /* sendevent */);
 
 extern _X_EXPORT Bool ActivateDevice(
-    DeviceIntPtr /*device*/);
+    DeviceIntPtr /*device*/,
+    BOOL /* sendevent */);
 
 extern _X_EXPORT Bool DisableDevice(
-    DeviceIntPtr /*device*/);
+    DeviceIntPtr /*device*/,
+    BOOL /* sendevent */);
 
 extern int InitAndStartDevices(void);
 
@@ -243,7 +246,8 @@ extern void CloseDownDevices(void);
 extern void UndisplayDevices(void);
 
 extern _X_EXPORT int RemoveDevice(
-    DeviceIntPtr /*dev*/);
+    DeviceIntPtr /*dev*/,
+    BOOL /* sendevent */);
 
 extern _X_EXPORT int NumMotionEvents(void);
 
commit 033a2b12fcd02fa9a2c2f20a352bec0a43074512
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 12 14:50:57 2009 +1000

    Xi: set per-device hierarchy changed flags.
    
    Rather than have one field per hierarchy change, XI2 has two fields - one
    generic one and one per-device that include the device-specific flags.
    This requires some funky handling for removed devices, but oh well.

diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
index 96b515d..1aaa371 100644
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@ -59,25 +59,25 @@ extern DevPrivateKey XTstDevicePrivateKey;
 /**
  * Send the current state of the device hierarchy to all clients.
  */
-void XISendDeviceHierarchyEvent(int flags)
+void XISendDeviceHierarchyEvent(int flags[MAXDEVICES])
 {
     xXIDeviceHierarchyEvent *ev;
     xXIHierarchyInfo *info;
     DeviceIntRec dummyDev;
     DeviceIntPtr dev;
+    int i;
 
     if (!flags)
         return;
 
-    ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) + inputInfo.numDevices *
-            sizeof(xXIHierarchyInfo));
+    ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) +
+                 MAXDEVICES * sizeof(xXIHierarchyInfo));
     ev->type = GenericEvent;
     ev->extension = IReqCode;
     ev->evtype = XI_HierarchyChanged;
     ev->time = GetTimeInMillis();
-    ev->flags = flags;
+    ev->flags = 0;
     ev->num_devices = inputInfo.numDevices;
-    ev->length = (ev->num_devices * sizeof(xXIHierarchyInfo))/4;
 
     info = (xXIHierarchyInfo*)&ev[1];
     for (dev = inputInfo.devices; dev; dev = dev->next)
@@ -85,6 +85,8 @@ void XISendDeviceHierarchyEvent(int flags)
         info->deviceid = dev->id;
         info->enabled = dev->enabled;
         info->use = GetDeviceUse(dev, &info->attachment);
+        info->flags = flags[dev->id];
+        ev->flags |= info->flags;
         info++;
     }
     for (dev = inputInfo.off_devices; dev; dev = dev->next)
@@ -92,9 +94,28 @@ void XISendDeviceHierarchyEvent(int flags)
         info->deviceid = dev->id;
         info->enabled = dev->enabled;
         info->use = GetDeviceUse(dev, &info->attachment);
+        info->flags = flags[dev->id];
+        ev->flags |= info->flags;
         info++;
     }
 
+
+    for (i = 0; i < MAXDEVICES; i++)
+    {
+        if (flags[i] & (XIMasterRemoved | XISlaveRemoved))
+        {
+            info->deviceid = i;
+            info->enabled = FALSE;
+            info->flags = flags[i];
+            info->use = 0;
+            ev->flags |= info->flags;
+            ev->num_devices++;
+            info++;
+        }
+    }
+
+    ev->length = (ev->num_devices * sizeof(xXIHierarchyInfo))/4;
+
     dummyDev.id = XIAllDevices;
     SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1);
 }
@@ -126,7 +147,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
     int required_len = sizeof(xXIChangeDeviceHierarchyReq);
     char n;
     int rc = Success;
-    int flags = 0;
+    int flags[MAXDEVICES] = {0};
 
     REQUEST(xXIChangeDeviceHierarchyReq);
     REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq);
@@ -177,24 +198,35 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
 
                     ActivateDevice(ptr);
                     ActivateDevice(keybd);
+                    flags[ptr->id] |= XIMasterAdded;
+                    flags[keybd->id] |= XIMasterAdded;
+
                     ActivateDevice(xtstptr);
                     ActivateDevice(xtstkeybd);
+                    flags[xtstptr->id] |= XISlaveAdded;
+                    flags[xtstkeybd->id] |= XISlaveAdded;
 
                     if (c->enable)
                     {
                         EnableDevice(ptr);
                         EnableDevice(keybd);
+                        flags[ptr->id] |= XIDeviceEnabled;
+                        flags[keybd->id] |= XIDeviceEnabled;
+
                         EnableDevice(xtstptr);
                         EnableDevice(xtstkeybd);
+                        flags[xtstptr->id] |= XIDeviceEnabled;
+                        flags[xtstkeybd->id] |= XIDeviceEnabled;
                     }
 
                     /* Attach the XTest virtual devices to the newly
                        created master device */
                     AttachDevice(NULL, xtstptr, ptr);
                     AttachDevice(NULL, xtstkeybd, keybd);
+                    flags[xtstptr->id] |= XISlaveAttached;
+                    flags[xtstkeybd->id] |= XISlaveAttached;
 
                     xfree(name);
-                    flags |= XIMasterAdded;
                 }
                 break;
             case XIRemoveMasterDevice:
@@ -336,9 +368,15 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                         {
                             if (!attached->isMaster) {
                                 if (attached->u.master == ptr)
+                                {
                                     AttachDevice(client, attached, newptr);
+                                    flags[attached->id] |= XISlaveAttached;
+                                }
                                 if (attached->u.master == keybd)
+                                {
                                     AttachDevice(client, attached, newkeybd);
+                                    flags[attached->id] |= XISlaveAttached;
+                                }
                             }
                         }
                     }
@@ -355,12 +393,19 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                     DisableDevice(xtstkeybd);
                     DisableDevice(keybd);
                     DisableDevice(ptr);
+                    flags[xtstptr->id] |= XIDeviceDisabled | XISlaveDetached;
+                    flags[xtstkeybd->id] |= XIDeviceDisabled | XISlaveDetached;
+                    flags[keybd->id] |= XIDeviceDisabled;
+                    flags[ptr->id] |= XIDeviceDisabled;
 
                     RemoveDevice(xtstptr);
                     RemoveDevice(xtstkeybd);
                     RemoveDevice(keybd);
                     RemoveDevice(ptr);
-                    flags |= XIMasterRemoved;
+                    flags[xtstptr->id] |= XISlaveRemoved;
+                    flags[xtstkeybd->id] |= XISlaveRemoved;
+                    flags[keybd->id] |= XIMasterRemoved;
+                    flags[ptr->id] |= XIMasterRemoved;
                 }
                 break;
             case XIDetachSlave:
@@ -392,7 +437,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                     }
 
                     AttachDevice(client, ptr, NULL);
-                    flags |= XISlaveDetached;
+                    flags[ptr->id] |= XISlaveDetached;
                 }
                 break;
             case XIAttachSlave:
@@ -444,7 +489,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                         goto unwind;
                     }
                     AttachDevice(client, ptr, newmaster);
-                    flags |= XISlaveAttached;
+                    flags[ptr->id] |= XISlaveAttached;
                 }
                 break;
         }
diff --git a/Xi/chdevhier.h b/Xi/chdevhier.h
index d2d1001..d4ce517 100644
--- a/Xi/chdevhier.h
+++ b/Xi/chdevhier.h
@@ -39,6 +39,6 @@
 int SProcXIChangeDeviceHierarchy(ClientPtr /* client */);
 int ProcXIChangeDeviceHierarchy(ClientPtr /* client */);
 
-void XISendDeviceHierarchyEvent(int flags);
+void XISendDeviceHierarchyEvent(int flags[]);
 
 #endif
diff --git a/dix/devices.c b/dix/devices.c
index dc5de05..c59457f 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -296,6 +296,7 @@ EnableDevice(DeviceIntPtr dev)
     int listlen;
     EventListPtr evlist;
     BOOL enabled;
+    int flags[MAXDEVICES] = {0};
 
     for (prev = &inputInfo.off_devices;
 	 *prev && (*prev != dev);
@@ -361,7 +362,8 @@ EnableDevice(DeviceIntPtr dev)
                            TRUE);
 
     SendDevicePresenceEvent(dev->id, DeviceEnabled);
-    XISendDeviceHierarchyEvent(XIDeviceEnabled);
+    flags[dev->id] |= XIDeviceEnabled;
+    XISendDeviceHierarchyEvent(flags);
 
     return TRUE;
 }
@@ -381,6 +383,7 @@ DisableDevice(DeviceIntPtr dev)
 {
     DeviceIntPtr *prev, other;
     BOOL enabled;
+    int flags[MAXDEVICES] = {0};
 
     for (prev = &inputInfo.devices;
 	 *prev && (*prev != dev);
@@ -395,7 +398,10 @@ DisableDevice(DeviceIntPtr dev)
         for (other = inputInfo.devices; other; other = other->next)
         {
             if (other->u.master == dev)
+            {
                 AttachDevice(NULL, other, NULL);
+                flags[other->id] |= XISlaveDetached;
+            }
         }
     }
     else
@@ -432,7 +438,8 @@ DisableDevice(DeviceIntPtr dev)
                            TRUE);
 
     SendDevicePresenceEvent(dev->id, DeviceDisabled);
-    XISendDeviceHierarchyEvent(XIDeviceDisabled);
+    flags[dev->id] = XIDeviceDisabled;
+    XISendDeviceHierarchyEvent(flags);
     return TRUE;
 }
 
@@ -450,6 +457,7 @@ ActivateDevice(DeviceIntPtr dev)
 {
     int ret = Success;
     ScreenPtr pScreen = screenInfo.screens[0];
+    int flags[MAXDEVICES];
 
     if (!dev || !dev->deviceProc)
         return BadImplementation;
@@ -464,7 +472,8 @@ ActivateDevice(DeviceIntPtr dev)
         pScreen->DeviceCursorInitialize(dev, pScreen);
 
     SendDevicePresenceEvent(dev->id, DeviceAdded);
-    XISendDeviceHierarchyEvent(XISlaveAdded);
+    flags[dev->id] = XISlaveAdded;
+    XISendDeviceHierarchyEvent(flags);
     return ret;
 }
 
@@ -929,6 +938,7 @@ RemoveDevice(DeviceIntPtr dev)
     ScreenPtr screen = screenInfo.screens[0];
     int deviceid;
     int initialized;
+    int flags[MAXDEVICES] = {0};
 
     DebugF("(dix) removing device %d\n", dev->id);
 
@@ -944,6 +954,7 @@ RemoveDevice(DeviceIntPtr dev)
             screen->DisplayCursor(dev, screen, NullCursor);
 
         DisableDevice(dev);
+        flags[dev->id] = XIDeviceDisabled;
     }
 
     prev = NULL;
@@ -956,6 +967,7 @@ RemoveDevice(DeviceIntPtr dev)
 	    else
 		prev->next = next;
 
+	    flags[tmp->id] = (tmp->isMaster) ? XIMasterRemoved : XISlaveRemoved;
 	    CloseDevice(tmp);
 	    ret = Success;
 	}
@@ -965,6 +977,7 @@ RemoveDevice(DeviceIntPtr dev)
     for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
 	next = tmp->next;
 	if (tmp == dev) {
+	    flags[tmp->id] = (tmp->isMaster) ? XIMasterRemoved : XISlaveRemoved;
 	    CloseDevice(tmp);
 
 	    if (prev == NULL)
@@ -979,7 +992,7 @@ RemoveDevice(DeviceIntPtr dev)
     if (ret == Success && initialized) {
         inputInfo.numDevices--;
         SendDevicePresenceEvent(deviceid, DeviceRemoved);
-        XISendDeviceHierarchyEvent(XISlaveRemoved);
+        XISendDeviceHierarchyEvent(flags);
     }
 
     return ret;
commit 8fb51feae222ff4f4aa1c440b6973ce7383bbc09
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 11 15:45:46 2009 +1000

    xkb: if kbd init failed, NULL out the pointers after freeing them (#21278)
    
    Reproducible:
    Configure a server that uses the keyboard driver with an invalid ruleset,
    e.g. (Option "XkbRules" "foobar"). Ensure that Option "AllowEmptyInput" is
    "off" in the ServerFlags or ServerLayout section. Start the server.
    After failing to init the keymap, the server will try to clean up after the
    device, double-freeing some xkb structs that have not been reset properly.
    
    X.Org Bug 21278 <http://bugs.freedesktop.org/show_bug.cgi?id=21278>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 7c611bc..e85b318 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -622,10 +622,13 @@ unwind_desc:
     XkbFreeKeyboard(xkb, 0, TRUE);
 unwind_info:
     xfree(xkbi);
+    dev->key->xkbInfo = NULL;
 unwind_kbdfeed:
     xfree(dev->kbdfeed);
+    dev->kbdfeed = NULL;
 unwind_key:
     xfree(dev->key);
+    dev->key = NULL;
     return FALSE;
 }
 
commit 0cea199eda772a5ddd5ce72e4823a00ec14405d4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 11 12:53:56 2009 +1000

    kdrive: set Activate/Deactivate grab for input devices (#21591)
    
    X.Org Bug 21591 <http://bugs.freedesktop.org/show_bug.cgi?id=21591>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 7ed3601..0d216a9 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -915,6 +915,8 @@ KdAddKeyboard (KdKeyboardInfo *ki)
         return !Success;
     }
 
+    ki->dixdev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+    ki->dixdev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
     RegisterOtherDevice(ki->dixdev);
 
 #ifdef DEBUG
@@ -984,6 +986,8 @@ KdAddPointer (KdPointerInfo *pi)
         return BadDevice;
     }
 
+    pi->dixdev->deviceGrab.ActivateGrab = ActivatePointerGrab;
+    pi->dixdev->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
     RegisterOtherDevice(pi->dixdev);
 
     for (prev = &kdPointers; *prev; prev = &(*prev)->next);
commit fdce58ca822f4e43e03e84076190f52d7104e01f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 11 12:51:40 2009 +1000

    dix: ensure Activate/DeactivateGrab has a valid value.
    
    Xephyr doesn't manually set Activate/DeactivateGrab for new devices,
    resulting in a NULL-pointer dereference later when a grab is activated.
    Avoid the segfault by ensuring that the pointer is always valid.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/devices.c b/dix/devices.c
index 83285b4..dc5de05 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -226,6 +226,8 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
 
     /* device grab defaults */
     dev->deviceGrab.grabTime = currentTime;
+    dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+    dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
 
     dev->coreEvents = TRUE;
 
commit e3f296d91dfe6b827195e1d387e1a04aa73b85c3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat May 9 10:33:20 2009 +1000

    xfree86: Remove superfluous ifdef DEBUG checks.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 8040f58..8382d91 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -639,9 +639,7 @@ xf86EnableAccess(ScrnInfoPtr pScrn)
     register xf86AccessPtr pAcc;
     EntityAccessPtr tmp;
 
-#ifdef DEBUG
-    ErrorF("Enable access %i\n",pScrn->scrnIndex);
-#endif
+    DebugF("Enable access %i\n",pScrn->scrnIndex);
 
     /* Entity is not under access control or currently enabled */
     if (!pScrn->access) {
@@ -844,10 +842,8 @@ checkConflictBlock(resRange *range, resPtr pRes)
     case ResBlock:
 	if (range->rBegin < pRes->block_end &&
 	    range->rEnd > pRes->block_begin) {
-#ifdef DEBUG
-	    ErrorF("b-b conflict w: %lx %lx\n",
+	    DebugF("b-b conflict w: %lx %lx\n",
 		   pRes->block_begin,pRes->block_end);
-#endif
 	    return pRes->block_end < range->rEnd ?
 		pRes->block_end : range->rEnd;
 	}
@@ -856,12 +852,10 @@ checkConflictBlock(resRange *range, resPtr pRes)
 	if (pRes->sparse_base > range->rEnd) return 0;
 	
 	val = (~pRes->sparse_mask | pRes->sparse_base) & getMask(range->rEnd);
-#ifdef DEBUG
-	ErrorF("base = 0x%lx, mask = 0x%lx, begin = 0x%lx, end = 0x%lx ,"
+	DebugF("base = 0x%lx, mask = 0x%lx, begin = 0x%lx, end = 0x%lx ,"
 	       "val = 0x%lx\n",
 		pRes->sparse_base, pRes->sparse_mask, range->rBegin,
 		range->rEnd, val);
-#endif
 	i = sizeof(memType) * 8;
 	tmp = prev = pRes->sparse_base;
 	
@@ -873,11 +867,9 @@ checkConflictBlock(resRange *range, resPtr pRes)
 		prev = tmp;
 	}
 	if (tmp >= range->rBegin) {
-#ifdef DEBUG
-	    ErrorF("conflict found at: 0x%lx\n",tmp);
-	    ErrorF("b-d conflict w: %lx %lx\n",
+	    DebugF("conflict found at: 0x%lx\n",tmp);
+	    DebugF("b-d conflict w: %lx %lx\n",
 		   pRes->sparse_base,pRes->sparse_mask);
-#endif
 	    return tmp;
 	}
 	else
@@ -902,10 +894,8 @@ checkConflictSparse(resRange *range, resPtr pRes)
     case ResSparse:
 	tmp = pRes->sparse_mask & range->rMask;
 	if ((tmp & pRes->sparse_base) == (tmp & range->rBase)) {
-#ifdef DEBUG
-	    ErrorF("s-b conflict w: %lx %lx\n",
+	    DebugF("s-b conflict w: %lx %lx\n",
 		   pRes->sparse_base,pRes->sparse_mask);
-#endif
 	    return pRes->sparse_mask;
 	}
 	return 0;
@@ -918,9 +908,7 @@ checkConflictSparse(resRange *range, resPtr pRes)
 	tmp = prev = range->rBase;
 	
 	while (i) {
-#ifdef DEBUG
-	    ErrorF("tmp = 0x%lx\n",tmp);
-#endif
+	    DebugF("tmp = 0x%lx\n",tmp);
 	    tmp |= 1<< (--i) & val;
 	    if (tmp > pRes->block_end)
 		tmp = prev;
@@ -947,11 +935,9 @@ checkConflictSparse(resRange *range, resPtr pRes)
 		m_mask = mask > m_mask ? mask : m_mask;
 		base = base + mask + 1;
 	    }
-#ifdef DEBUG
-	    ErrorF("conflict found at: 0x%lx\n",tmp);
-	    ErrorF("b-b conflict w: %lx %lx\n",
+	    DebugF("conflict found at: 0x%lx\n",tmp);
+	    DebugF("b-b conflict w: %lx %lx\n",
 		   pRes->block_begin,pRes->block_end);
-#endif
 	    return ~m_mask; 
 	}
     }
@@ -1557,12 +1543,10 @@ xf86EnterServerState(xf86State state)
      * We take care not to call xf86BlockSIGIO() twice. 
      */
     SetSIGIOForState(state);
-#ifdef DEBUG
     if (state == SETUP)
-	ErrorF("Entering SETUP state\n");
+	DebugF("Entering SETUP state\n");
     else
-	ErrorF("Entering OPERATING state\n");
-#endif
+	DebugF("Entering OPERATING state\n");
 
     /* When servicing a dumb framebuffer we don't need to do anything */
     if (doFramebufferMode) return;
@@ -1620,10 +1604,8 @@ xf86EnterServerState(xf86State state)
 		xf86Screens[i]->busAccess = NULL;
 	}
 	
-#ifdef DEBUG
 	if (xf86Screens[i]->busAccess)
-	    ErrorF("Screen %i setting vga route\n",i);
-#endif
+	    DebugF("Screen %i setting vga route\n",i);
 	switch (rt) {
 	case MEM_IO:
 	    xf86MsgVerb(X_INFO, 3, "Screen %i shares mem & io resources\n",i);
@@ -1967,9 +1949,7 @@ xf86PostScreenInit(void)
 	return;
     }
 
-#ifdef DEBUG
-    ErrorF("PostScreenInit  generation: %i\n",serverGeneration);
-#endif
+    DebugF("PostScreenInit  generation: %i\n",serverGeneration);
     if (serverGeneration == 1) {
 	checkRoutingForScreens(OPERATING);
 	for (i=0; i<xf86NumEntities; i++) {
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 7ea6197..2ecb639 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1519,10 +1519,8 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
         adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
     }
 
-#ifdef DEBUG
-    ErrorF("Found %d screens in the layout section %s",
+    DebugF("Found %d screens in the layout section %s",
            count, conf_layout->lay_identifier);
-#endif
     if (!count) /* alloc enough storage even if no screen is specified */
         count = 1;
 
@@ -1679,10 +1677,8 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
         count++;
         idp = (XF86ConfInactivePtr)idp->list.next;
     }
-#ifdef DEBUG
-    ErrorF("Found %d inactive devices in the layout section %s\n",
+    DebugF("Found %d inactive devices in the layout section %s\n",
            count, conf_layout->lay_identifier);
-#endif
     gdp = xnfalloc((count + 1) * sizeof(GDevRec));
     gdp[count].identifier = NULL;
     idp = conf_layout->lay_inactive_lst;
@@ -1704,10 +1700,8 @@ configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
         count++;
         irp = (XF86ConfInputrefPtr)irp->list.next;
     }
-#ifdef DEBUG
-    ErrorF("Found %d input devices in the layout section %s\n",
+    DebugF("Found %d input devices in the layout section %s\n",
            count, conf_layout->lay_identifier);
-#endif
     indp = xnfcalloc((count + 1), sizeof(IDevPtr));
     indp[count] = NULL;
     irp = conf_layout->lay_input_lst;
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index aa818c3..e9b4dfe 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -183,9 +183,7 @@ ProcessInputEvents (void)
 void
 xf86ProcessActionEvent(ActionEvent action, void *arg)
 {
-#ifdef DEBUG
-    ErrorF("ProcessActionEvent(%d,%x)\n", (int) action, arg);
-#endif
+    DebugF("ProcessActionEvent(%d,%x)\n", (int) action, arg);
     switch (action) {
     case ACTION_TERMINATE:
 	if (!xf86Info.dontZap) {
@@ -429,9 +427,7 @@ xf86VTSwitch(void)
   InputInfoPtr pInfo;
   IHPtr ih;
 
-#ifdef DEBUG
-  ErrorF("xf86VTSwitch()\n");
-#endif
+  DebugF("xf86VTSwitch()\n");
 
 #ifdef XFreeXDGA
   if(!DGAVTSwitch())
@@ -444,10 +440,8 @@ xf86VTSwitch(void)
    */
   if (xf86Screens[0]->vtSema) {
 
-#ifdef DEBUG
-    ErrorF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
+    DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
 	   BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
-#endif
 #ifdef DPMSExtension
     if (DPMSPowerLevel != DPMSModeOn)
 	DPMSSet(serverClient, DPMSModeOn);
@@ -483,9 +477,7 @@ xf86VTSwitch(void)
        * switch failed
        */
 
-#ifdef DEBUG
-      ErrorF("xf86VTSwitch: Leave failed\n");
-#endif
+      DebugF("xf86VTSwitch: Leave failed\n");
       prevSIGIO = xf86BlockSIGIO();
       xf86AccessEnter();
       xf86EnterServerState(SETUP);
@@ -534,9 +526,7 @@ xf86VTSwitch(void)
     }
   } else {
 
-#ifdef DEBUG
-    ErrorF("xf86VTSwitch: Entering\n");
-#endif
+    DebugF("xf86VTSwitch: Entering\n");
     if (!xf86VTSwitchTo()) return;
 
     prevSIGIO = xf86BlockSIGIO();
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index 0db7717..d59c638 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -212,15 +212,13 @@ xf86AllocateScreen(DriverPtr drv, int flags)
     xf86Screens[i]->CurrentAccess = &xf86CurrentAccess;
     xf86Screens[i]->resourceType = MEM_IO;
 
-#ifdef DEBUG
     /* OOps -- What's this ? */
-    ErrorF("xf86AllocateScreen - xf86Screens[%d]->pScreen = %p\n",
+    DebugF("xf86AllocateScreen - xf86Screens[%d]->pScreen = %p\n",
 	   i, xf86Screens[i]->pScreen );
     if ( NULL != xf86Screens[i]->pScreen ) {
-      ErrorF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
+      DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
 	     i, xf86Screens[i]->pScreen->CreateWindow );
     }
-#endif
 
     xf86Screens[i]->DriverFunc = drv->driverFunc;
 
@@ -1735,9 +1733,7 @@ xf86MatchPciInstances(const char *driverName, int vendorID,
     }
 
 
-#ifdef DEBUG
-    ErrorF("%s instances found: %d\n", driverName, allocatedInstances);
-#endif
+    DebugF("%s instances found: %d\n", driverName, allocatedInstances);
 
    /*
     * Check for devices that need duplicated instances.  This is required
@@ -1820,9 +1816,7 @@ xf86MatchPciInstances(const char *driverName, int vendorID,
 	    instances[i].dev = dev;
 	}
     }
-#ifdef DEBUG
-    ErrorF("%s instances found: %d\n", driverName, numClaimedInstances);
-#endif
+    DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
     /*
      * Now check that a chipset or chipID override in the device section
      * is valid.  Chipset has precedence over chipID.
@@ -1926,11 +1920,9 @@ xf86MatchPciInstances(const char *driverName, int vendorID,
         if (instances[i].screen == 0 && !xf86CheckPciSlot( pPci ))
 	    continue;
 
-#ifdef DEBUG
-	ErrorF("%s: card at %d:%d:%d is claimed by a Device section\n",
+	DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
 	       driverName, pPci->bus, pPci->dev, pPci->func);
-#endif
-	
+
 	/* Allocate an entry in the lists to be returned */
 	numFound++;
 	retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
@@ -2621,10 +2613,8 @@ xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
     int i;
     Bool existing = FALSE;
 
-#ifdef DEBUG
-    ErrorF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
+    DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
 	   ScrnIndex, property, type, format, len, value);
-#endif
 
     if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) {
       return(BadMatch);
@@ -2660,15 +2650,11 @@ xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
     pNewProp->size = len;
     pNewProp->data = value;
 
-#ifdef DEBUG
-    ErrorF("new property filled\n");
-#endif
+    DebugF("new property filled\n");
 
     if (NULL==xf86RegisteredPropertiesTable) {
-#ifdef DEBUG
-      ErrorF("creating xf86RegisteredPropertiesTable[] size %d\n",
+      DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
 	     xf86NumScreens);
-#endif
       if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) {
 	return(BadAlloc);
       }
@@ -2677,12 +2663,10 @@ xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
       }
     }
 
-#ifdef DEBUG
-    ErrorF("xf86RegisteredPropertiesTable %p\n",
+    DebugF("xf86RegisteredPropertiesTable %p\n",
 	   (void *)xf86RegisteredPropertiesTable);
-    ErrorF("xf86RegisteredPropertiesTable[%d] %p\n",
+    DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
 	   ScrnIndex, (void *)xf86RegisteredPropertiesTable[ScrnIndex]);
-#endif
 
     if (!existing) {
       if ( xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
@@ -2690,17 +2674,13 @@ xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
       } else {
 	pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
 	while (pRegProp->next != NULL) {
-#ifdef DEBUG
-	  ErrorF("- next %p\n", (void *)pRegProp);
-#endif
+	  DebugF("- next %p\n", (void *)pRegProp);
 	  pRegProp = pRegProp->next;
         }
 	pRegProp->next = pNewProp;
       }
     }
-#ifdef DEBUG
-    ErrorF("xf86RegisterRootWindowProperty succeeded\n");
-#endif
+    DebugF("xf86RegisterRootWindowProperty succeeded\n");
     return(Success);
 }
 
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index cf28ae7..c4e5898 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -316,9 +316,7 @@ xf86CreateRootWindow(WindowPtr pWin)
   CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
       dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
 
-#ifdef DEBUG
-  ErrorF("xf86CreateRootWindow(%p)\n", pWin);
-#endif
+  DebugF("xf86CreateRootWindow(%p)\n", pWin);
 
   if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
     /* Can't find hook we are hung on */
@@ -365,9 +363,7 @@ xf86CreateRootWindow(WindowPtr pWin)
     }
   }
 
-#ifdef DEBUG
-  ErrorF("xf86CreateRootWindow() returns %d\n", ret);
-#endif
+  DebugF("xf86CreateRootWindow() returns %d\n", ret);
   return (ret);
 }
 
@@ -471,10 +467,8 @@ probe_devices_from_device_sections(DriverPtr drvp)
 		if ( (devList[i]->screen == 0) && !xf86CheckPciSlot( pPci ) )
 		  continue;
 
-#ifdef DEBUG
-		ErrorF("%s: card at %d:%d:%d is claimed by a Device section\n",
+		DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
 		       drvp->driverName, pPci->bus, pPci->dev, pPci->func);
-#endif
 
 		/* Allocate an entry in the lists to be returned */
 		entry = xf86ClaimPciSlot(pPci, drvp, device_id,
@@ -1246,12 +1240,10 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
 	FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
       }
 
-#ifdef DEBUG
-      ErrorF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
+      DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
 	     i, xf86Screens[i]->pScreen );
-      ErrorF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
+      DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
 	     i, xf86Screens[i]->pScreen->CreateWindow );
-#endif
 
       dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
 		    xf86CreateRootWindowKey,
diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c
index 522d3c2..6dcebe1 100644
--- a/hw/xfree86/common/xf86Mode.c
+++ b/hw/xfree86/common/xf86Mode.c
@@ -654,10 +654,8 @@ xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor)
 	return MODE_ERROR;
     }
 
-#ifdef DEBUG
-    ErrorF("xf86CheckModeForMonitor(%p %s, %p %s)\n",
+    DebugF("xf86CheckModeForMonitor(%p %s, %p %s)\n",
 	   mode, mode->name, monitor, monitor->id);
-#endif
 
     /* Some basic mode validity checks */
     if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
@@ -808,10 +806,8 @@ xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
 	return MODE_ERROR;
     }
 
-#ifdef DEBUG
-    ErrorF("xf86InitialCheckModeForDriver(%p, %p %s, %p, 0x%x, %d, %d, %d)\n",
+    DebugF("xf86InitialCheckModeForDriver(%p, %p %s, %p, 0x%x, %d, %d, %d)\n",
 	   scrp, mode, mode->name , clockRanges, strategy, maxPitch,  virtualX, virtualY);
-#endif
 
     /* Some basic mode validity checks */
     if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
@@ -1210,14 +1206,12 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
     range vrefresh[MAX_VREFRESH];
     Bool inferred_virtual = FALSE;
 
-#ifdef DEBUG
-    ErrorF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t  %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n",
+    DebugF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t  %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n",
 	   scrp, availModes, modeNames, clockRanges,
 	   linePitches, minPitch, maxPitch, pitchInc,
 	   minHeight, maxHeight, virtualX, virtualY,
 	   apertureSize, strategy
 	   );
-#endif
 
     /* Some sanity checking */
     if (scrp == NULL || scrp->name == NULL || !scrp->monitor ||
@@ -1860,15 +1854,13 @@ xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)
 
     do {
 	xf86SetModeCrtc(p, adjustFlags);
-#ifdef DEBUG
-	ErrorF("%sMode %s: %d (%d) %d %d (%d) %d %d (%d) %d %d (%d) %d\n",
+	DebugF("%sMode %s: %d (%d) %d %d (%d) %d %d (%d) %d %d (%d) %d\n",
 	       (p->type & M_T_DEFAULT) ? "Default " : "",
 	       p->name, p->CrtcHDisplay, p->CrtcHBlankStart,
 	       p->CrtcHSyncStart, p->CrtcHSyncEnd, p->CrtcHBlankEnd,
 	       p->CrtcHTotal, p->CrtcVDisplay, p->CrtcVBlankStart,
 	       p->CrtcVSyncStart, p->CrtcVSyncEnd, p->CrtcVBlankEnd,
 	       p->CrtcVTotal);
-#endif
 	p = p->next;
     } while (p != NULL && p != scrp->modes);
 }
diff --git a/hw/xfree86/common/xf86VidMode.c b/hw/xfree86/common/xf86VidMode.c
index d855bd1..49b86e7 100644
--- a/hw/xfree86/common/xf86VidMode.c
+++ b/hw/xfree86/common/xf86VidMode.c
@@ -56,12 +56,6 @@ static Bool VidModeClose(int i, ScreenPtr pScreen);
 
 #endif
 
-#ifdef DEBUG
-# define DEBUG_P(x) ErrorF(x"\n");
-#else
-# define DEBUG_P(x) /**/
-#endif
-
 Bool
 VidModeExtensionInit(ScreenPtr pScreen)
 {
@@ -69,7 +63,7 @@ VidModeExtensionInit(ScreenPtr pScreen)
     VidModePtr pVidMode;
     
     if (!xf86GetVidModeEnabled()) {
-	DEBUG_P("!xf86GetVidModeEnabled()");
+	DebugF("!xf86GetVidModeEnabled()\n");
 	return FALSE;
     }
 
@@ -77,7 +71,7 @@ VidModeExtensionInit(ScreenPtr pScreen)
 
     if (!dixSetPrivate(&pScreen->devPrivates, VidModeKey,
 		       xcalloc(sizeof(VidModeRec), 1))) {
-	DEBUG_P("xcalloc failed");
+	DebugF("xcalloc failed\n");
 	return FALSE;
     }
 
@@ -89,7 +83,7 @@ VidModeExtensionInit(ScreenPtr pScreen)
     VidModeCount++;
     return TRUE;
 #else
-    DEBUG_P("no vidmode extension");
+    DebugF("no vidmode extension\n");
     return FALSE;
 #endif
 }
@@ -123,13 +117,13 @@ VidModeAvailable(int scrnIndex)
     VidModePtr pVidMode;
 
     if (VidModeKey == NULL) {
-	DEBUG_P("VidModeKey == NULL");
+	DebugF("VidModeKey == NULL\n");
 	return FALSE;
     }
  
     pScrn = xf86Screens[scrnIndex];
     if (pScrn == NULL) {
-	DEBUG_P("pScrn == NULL");
+	DebugF("pScrn == NULL\n");
 	return FALSE;
     }
     
@@ -137,7 +131,7 @@ VidModeAvailable(int scrnIndex)
     if (pVidMode)
 	return TRUE;
     else {
-	DEBUG_P("pVidMode == NULL");
+	DebugF("pVidMode == NULL\n");
 	return FALSE;
     }
 }
diff --git a/hw/xfree86/common/xf86fbman.c b/hw/xfree86/common/xf86fbman.c
index 510c3d8..5b88717 100644
--- a/hw/xfree86/common/xf86fbman.c
+++ b/hw/xfree86/common/xf86fbman.c
@@ -802,10 +802,10 @@ LinearRemoveCBWrapper(FBAreaPtr area)
    xfree(pLink);
 }
 
-#ifdef DEBUG
 static void
-Dump(FBLinearLinkPtr pLink)
+DumpDebug(FBLinearLinkPtr pLink)
 {
+#ifdef DEBUG
    if (!pLink) ErrorF("MMmm, PLINK IS NULL!\n");
 
    while (pLink) {
@@ -817,8 +817,8 @@ Dump(FBLinearLinkPtr pLink)
 
 	 pLink = pLink->next;
    }
-}
 #endif
+}
 
 static FBLinearPtr
 AllocateLinear(
@@ -889,9 +889,7 @@ AllocateLinear(
    linear->linear.RemoveLinearCallback = NULL;
    linear->linear.devPrivate.ptr = NULL;
 
-#ifdef DEBUG
-   Dump(offman->LinearAreas);
-#endif
+   DumpDebug(offman->LinearAreas);
 
    return &(linear->linear);
 }
@@ -916,15 +914,11 @@ localAllocateOffscreenLinear(
 					   xf86FBScreenKey);
 
    /* Try to allocate from linear memory first...... */
-#ifdef DEBUG
-   ErrorF("ALLOCATING LINEAR\n");
-#endif
+   DebugF("ALLOCATING LINEAR\n");
    if ((linear = AllocateLinear(offman, length, gran, privData)))
   	return linear;
 
-#ifdef DEBUG
-   ErrorF("NOPE, ALLOCATING AREA\n");
-#endif
+   DebugF("NOPE, ALLOCATING AREA\n");
 
    if(!(link = xalloc(sizeof(FBLinearLink))))
      return NULL;
@@ -978,9 +972,7 @@ localAllocateOffscreenLinear(
    } else 
 	xfree(link);
 
-#ifdef DEBUG
-   Dump(offman->LinearAreas);
-#endif
+   DumpDebug(offman->LinearAreas);
 
    return linear;
 }
@@ -1005,17 +997,13 @@ localFreeOffscreenLinear(FBLinearPtr linear)
    }
 
    if(pLink->area) {  /* really an XY area */
-#ifdef DEBUG
-	ErrorF("FREEING AREA\n");
-#endif
+	DebugF("FREEING AREA\n");
 	localFreeOffscreenArea(pLink->area);
    	if(pLinkPrev)
 	    pLinkPrev->next = pLink->next;
    	else offman->LinearAreas = pLink->next;
    	xfree(pLink); 
-#ifdef DEBUG
-   	Dump(offman->LinearAreas);
-#endif
+	DumpDebug(offman->LinearAreas);
 	return;
    }
 
@@ -1037,10 +1025,8 @@ localFreeOffscreenLinear(FBLinearPtr linear)
     	}
    } 
    
-#ifdef DEBUG
-   ErrorF("FREEING LINEAR\n");
-   Dump(offman->LinearAreas);
-#endif
+   DebugF("FREEING LINEAR\n");
+   DumpDebug(offman->LinearAreas);
 }
 
 
diff --git a/hw/xfree86/common/xf86sbusBus.c b/hw/xfree86/common/xf86sbusBus.c
index 924c2bc..4936e75 100644
--- a/hw/xfree86/common/xf86sbusBus.c
+++ b/hw/xfree86/common/xf86sbusBus.c
@@ -435,9 +435,7 @@ xf86MatchSbusInstances(const char *driverName, int sbusDevId,
 	return actualcards;
     }
 
-#ifdef DEBUG
-    ErrorF("%s instances found: %d\n", driverName, allocatedInstances);
-#endif
+    DebugF("%s instances found: %d\n", driverName, allocatedInstances);
 
     for (i = 0; i < allocatedInstances; i++) {
 	char *promPath = NULL;
@@ -494,9 +492,7 @@ xf86MatchSbusInstances(const char *driverName, int sbusDevId,
 	    xfree(promPath);
     }
 
-#ifdef DEBUG
-    ErrorF("%s instances found: %d\n", driverName, numClaimedInstances);
-#endif
+    DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
 
     /*
      * Of the claimed instances, check that another driver hasn't already
@@ -510,11 +506,9 @@ xf86MatchSbusInstances(const char *driverName, int sbusDevId,
 	if (!xf86CheckSbusSlot(psdp->fbNum))
 	    continue;
 
-#ifdef DEBUG
-	ErrorF("%s: card at fb%d %08x is claimed by a Device section\n",
+	DebugF("%s: card at fb%d %08x is claimed by a Device section\n",
 	       driverName, psdp->fbNum, psdp->node.node);
-#endif
-	
+
 	/* Allocate an entry in the lists to be returned */
 	numFound++;
 	retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
diff --git a/hw/xfree86/os-support/linux/int10/linux.c b/hw/xfree86/os-support/linux/int10/linux.c
index 8274bbb..0cf3507 100644
--- a/hw/xfree86/os-support/linux/int10/linux.c
+++ b/hw/xfree86/os-support/linux/int10/linux.c
@@ -115,9 +115,7 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
     if ((!vidMem) || (!sysMem)) {
 	if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
 	    if (!sysMem) {
-#ifdef DEBUG
-		ErrorF("Mapping sys bios area\n");
-#endif
+		DebugF("Mapping sys bios area\n");
 		if ((sysMem = mmap((void *)(SYS_BIOS), BIOS_SIZE,
 				   PROT_READ | PROT_EXEC,
 				   MAP_SHARED | MAP_FIXED, fd, SYS_BIOS))
@@ -128,9 +126,7 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
 		}
 	    }
 	    if (!vidMem) {
-#ifdef DEBUG
-		ErrorF("Mapping VRAM area\n");
-#endif
+		DebugF("Mapping VRAM area\n");
 		if ((vidMem = mmap((void *)(V_RAM), VRAM_SIZE,
 				   PROT_READ | PROT_WRITE | PROT_EXEC,
 				   MAP_SHARED | MAP_FIXED, fd, V_RAM))
@@ -162,9 +158,7 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
 	(pointer)xnfcalloc(1, ALLOC_ENTRIES(pagesize));
 
     if (!xf86IsEntityPrimary(entityIndex)) {
-#ifdef DEBUG
-	ErrorF("Mapping high memory area\n");
-#endif
+	DebugF("Mapping high memory area\n");
 	if ((high_mem = shmget(counter++, HIGH_MEM_SIZE,
 			       IPC_CREAT | SHM_R | SHM_W)) == -1) {
 	    if (errno == ENOSYS)
@@ -176,9 +170,7 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
 	    goto error1;
 	}
     } else {
-#ifdef DEBUG
-	ErrorF("Mapping Video BIOS\n");
-#endif
+	DebugF("Mapping Video BIOS\n");
 	videoBiosMapped = TRUE;
 	if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
 	    if ((vMem = mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS,
@@ -195,9 +187,7 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
     }
     ((linuxInt10Priv*)pInt->private)->highMem = high_mem;
     
-#ifdef DEBUG
-    ErrorF("Mapping 640kB area\n");
-#endif
+    DebugF("Mapping 640kB area\n");
     if ((low_mem = shmget(counter++, V_RAM,
 			  IPC_CREAT | SHM_R | SHM_W)) == -1) {
 	xf86DrvMsg(screen, X_ERROR,
@@ -229,16 +219,12 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
     
     Int10Current = pInt;
 
-#ifdef DEBUG
-    ErrorF("Mapping int area\n");
-#endif
+    DebugF("Mapping int area\n");
     if (xf86ReadBIOS(0, 0, (unsigned char *)0, LOW_PAGE_SIZE) < 0) {
 	xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n");
 	goto error3;
     }
-#ifdef DEBUG
-    ErrorF("done\n");
-#endif
+    DebugF("done\n");
     /*
      * Read in everything between V_BIOS and SYS_BIOS as some system BIOSes
      * have executable code there.  Note that xf86ReadBIOS() can only bring in
@@ -246,17 +232,13 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
      */
     if (!videoBiosMapped) {
 	memset((pointer)V_BIOS, 0, SYS_BIOS - V_BIOS);
-#ifdef DEBUG
-	ErrorF("Reading BIOS\n");
-#endif
+	DebugF("Reading BIOS\n");
 	for (cs = V_BIOS;  cs < SYS_BIOS;  cs += V_BIOS_SIZE)
 	    if (xf86ReadBIOS(cs, 0, (pointer)cs, V_BIOS_SIZE) < V_BIOS_SIZE)
 		xf86DrvMsg(screen, X_WARNING,
 			   "Unable to retrieve all of segment 0x%06lX.\n",
 			   (long)cs);
-#ifdef DEBUG
-	ErrorF("done\n");
-#endif
+	DebugF("done\n");
     }
 
     if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
diff --git a/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c b/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c
index 9412b07..34afd95 100644
--- a/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c
+++ b/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c
@@ -172,9 +172,7 @@ vm86_GP_fault(xf86Int10InfoPtr pInt)
 	break;
 
     case 0xf4:
-#ifdef DEBUG
-	ErrorF("hlt at %p\n", lina);
-#endif
+	DebugF("hlt at %p\n", lina);
 	return FALSE;
 
     case 0x0f:
diff --git a/hw/xfree86/os-support/linux/lnx_acpi.c b/hw/xfree86/os-support/linux/lnx_acpi.c
index 8e11f4a..5fad194 100644
--- a/hw/xfree86/os-support/linux/lnx_acpi.c
+++ b/hw/xfree86/os-support/linux/lnx_acpi.c
@@ -135,15 +135,11 @@ lnxACPIOpen(void)
     int r = -1;
     static int warned = 0;
 
-#ifdef DEBUG
-    ErrorF("ACPI: OSPMOpen called\n");
-#endif
+    DebugF("ACPI: OSPMOpen called\n");
     if (ACPIihPtr || !xf86Info.pmFlag)
 	return NULL;
    
-#ifdef DEBUG
-    ErrorF("ACPI: Opening device\n");
-#endif
+    DebugF("ACPI: Opening device\n");
     if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) > -1) {
 	memset(&addr, 0, sizeof(addr));
 	addr.sun_family = AF_UNIX;
@@ -172,10 +168,8 @@ static void
 lnxCloseACPI(void)
 {
     int fd;
-    
-#ifdef DEBUG
-   ErrorF("ACPI: Closing device\n");
-#endif
+
+    DebugF("ACPI: Closing device\n");
     if (ACPIihPtr) {
 	fd = xf86RemoveGeneralHandler(ACPIihPtr);
 	shutdown(fd, 2);
diff --git a/hw/xfree86/os-support/linux/lnx_apm.c b/hw/xfree86/os-support/linux/lnx_apm.c
index 9dae00e..4ccc7d6 100644
--- a/hw/xfree86/os-support/linux/lnx_apm.c
+++ b/hw/xfree86/os-support/linux/lnx_apm.c
@@ -160,15 +160,11 @@ lnxAPMOpen(void)
 {
     int fd, pfd;    
 
-#ifdef DEBUG
-    ErrorF("APM: OSPMOpen called\n");
-#endif
+    DebugF("APM: OSPMOpen called\n");
     if (APMihPtr || !xf86Info.pmFlag)
 	return NULL;
    
-#ifdef DEBUG
-    ErrorF("APM: Opening device\n");
-#endif
+    DebugF("APM: Opening device\n");
     if ((fd = open( APM_DEVICE, O_RDWR )) > -1) {
 	if (access( APM_PROC, R_OK ) ||
 	    ((pfd = open( APM_PROC, O_RDONLY)) == -1)) {
@@ -191,10 +187,8 @@ static void
 lnxCloseAPM(void)
 {
     int fd;
-    
-#ifdef DEBUG
-   ErrorF("APM: Closing device\n");
-#endif
+
+    DebugF("APM: Closing device\n");
     if (APMihPtr) {
 	fd = xf86RemoveGeneralHandler(APMihPtr);
 	close(fd);
diff --git a/hw/xfree86/os-support/linux/lnx_axp.c b/hw/xfree86/os-support/linux/lnx_axp.c
index f7151c8..d259999 100644
--- a/hw/xfree86/os-support/linux/lnx_axp.c
+++ b/hw/xfree86/os-support/linux/lnx_axp.c
@@ -69,21 +69,15 @@ lnxGetAXP(void)
     switch (count) {
     case 1:
       sscanf(res, "cpu model : %s",cpu);
-#ifdef DEBUG
-      ErrorF("CPU %s\n",cpu);
-#endif
+      DebugF("CPU %s\n",cpu);
       break;
     case 5:
       sscanf(res, "system type : %s",systype);
-#ifdef DEBUG
-      ErrorF("system type : %s\n",systype);
-#endif
+      DebugF("system type : %s\n",systype);
       break;
     case 6:
       sscanf(res, "system variation : %s",sysvari);
-#ifdef DEBUG
-      ErrorF("system variation: %s\n",sysvari);
-#endif
+      DebugF("system variation: %s\n",sysvari);
       break;
     }
     count++;
diff --git a/hw/xfree86/os-support/linux/lnx_font.c b/hw/xfree86/os-support/linux/lnx_font.c
index e9a5b6a..5b2696a 100644
--- a/hw/xfree86/os-support/linux/lnx_font.c
+++ b/hw/xfree86/os-support/linux/lnx_font.c
@@ -65,9 +65,7 @@ getfont(int *width, int *height,
     op.flags = 0;
 
     SYSCALL(result = ioctl(xf86Info.consoleFd, KDFONTOP, &op));
-#ifdef DEBUG
-    ErrorF("Console font read: h: %i count: %i\n",op.height,op.charcount);
-#endif
+    DebugF("Console font read: h: %i count: %i\n",op.height,op.charcount);
 
     if (!result) {
 
@@ -130,9 +128,7 @@ lnx_savefont(void)
     int fd;
     int width = 32, height = 32, charcount = 2048;
 
-#ifdef DEBUG
-    ErrorF("SAVE font\n");
-#endif
+    DebugF("SAVE font\n");
 
 #if CHECK_OS_VERSION
     /* Check if the kernel has full support for this */
@@ -247,9 +243,7 @@ lnx_restorefont(void)
 {
     if (lnxfont.data == NULL)
 	return FALSE;
-#ifdef DEBUG
-    ErrorF("RESTORE font\n");
-#endif
+    DebugF("RESTORE font\n");
 #if 0
     /* must wack the height to make the kernel reprogram the VGA registers */
     if (!setfont(lnxfont.width, lnxfont.height + 1, lnxfont.charcount,
diff --git a/hw/xfree86/os-support/linux/lnx_video.c b/hw/xfree86/os-support/linux/lnx_video.c
index ed35766..73409df 100644
--- a/hw/xfree86/os-support/linux/lnx_video.c
+++ b/hw/xfree86/os-support/linux/lnx_video.c
@@ -292,9 +292,7 @@ mtrr_add_wc_region(int screenNum, unsigned long base, unsigned long size,
 		 lbase = lbase >> 1, d_size <<= 1);
 	    while (d_size > n_size)
 		d_size = d_size >> 1;
-#ifdef DEBUG
-	    ErrorF("WC_BASE: 0x%lx WC_END: 0x%lx\n",base,base+d_size-1);
-#endif
+	    DebugF("WC_BASE: 0x%lx WC_END: 0x%lx\n",base,base+d_size-1);
 	    n_base += d_size;
 	    n_size -= d_size;
 	    if (n_size) {
@@ -424,11 +422,9 @@ mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 
     realBase = Base & ~(getpagesize() - 1);
     alignOff = Base - realBase;
-#ifdef DEBUG
-    ErrorF("base: %lx, realBase: %lx, alignOff: %lx \n",
+    DebugF("base: %lx, realBase: %lx, alignOff: %lx \n",
 	   Base,realBase,alignOff);
-#endif
-    
+
 #if defined(__ia64__) || defined(__arm__) || defined(__s390__)
 #ifndef MAP_WRITECOMBINED
 #define MAP_WRITECOMBINED 0x00010000
@@ -469,9 +465,7 @@ mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
 		   " (0x%08lx,0x%lx) (%s)\n", Base, Size,
 		   strerror(errno));
     }
-#ifdef DEBUG
-    ErrorF("base: %lx aligned base: %lx\n",base, base + alignOff);
-#endif
+    DebugF("base: %lx aligned base: %lx\n",base, base + alignOff);
     return (char *)base + alignOff;
 }
 #endif /* !(__sparc__) */
@@ -481,10 +475,8 @@ unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
 {
     memType alignOff = (memType)Base 
 	- ((memType)Base & ~(getpagesize() - 1));
-    
-#ifdef DEBUG
-    ErrorF("alignment offset: %lx\n",alignOff);
-#endif
+
+    DebugF("alignment offset: %lx\n",alignOff);
     munmap((caddr_t)((memType)Base - alignOff), (Size + alignOff));
 }
 
diff --git a/hw/xfree86/os-support/sco/sco_video.c b/hw/xfree86/os-support/sco/sco_video.c
index 7edf71d..f63b71d 100644
--- a/hw/xfree86/os-support/sco/sco_video.c
+++ b/hw/xfree86/os-support/sco/sco_video.c
@@ -124,9 +124,7 @@ mapVidMemMMAP(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
   realBase = Base & ~(getpagesize() - 1);
   alignOff = Base - realBase;
 
-#ifdef DEBUG
-  ErrorF("base: %lx, realBase: %lx, alignOff: %lx\n", Base,realBase,alignOff);
-#endif
+  DebugF("base: %lx, realBase: %lx, alignOff: %lx\n", Base,realBase,alignOff);
 
   base = mmap((caddr_t)0, Size + alignOff,
 	      (flags & VIDMEM_READONLY) ? PROT_READ : (PROT_READ | PROT_WRITE),
@@ -138,9 +136,7 @@ mapVidMemMMAP(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
     return 0; /* NOTREACHED */
   }
 
-#ifdef DEBUG
-    ErrorF("base: %lx aligned base: %lx\n",base, base + alignOff);
-#endif
+    DebugF("base: %lx aligned base: %lx\n",base, base + alignOff);
     return (pointer)((char *)base + alignOff);
 }
 
diff --git a/hw/xfree86/os-support/shared/bios_mmap.c b/hw/xfree86/os-support/shared/bios_mmap.c
index 96d56bf..40afd5b 100644
--- a/hw/xfree86/os-support/shared/bios_mmap.c
+++ b/hw/xfree86/os-support/shared/bios_mmap.c
@@ -68,10 +68,8 @@ xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
 		close(fd);
 		return(-1);
 	}
-#ifdef DEBUG
-	ErrorF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
+	DebugF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
 		Base, ptr[0] | (ptr[1] << 8));
-#endif
 	(void)memcpy(Buf, (void *)(ptr + Offset), Len);
 	(void)munmap((caddr_t)ptr, mlen);
 	(void)close(fd);
diff --git a/hw/xfree86/os-support/shared/posix_tty.c b/hw/xfree86/os-support/shared/posix_tty.c
index 697d0e5..bf1bb03 100644
--- a/hw/xfree86/os-support/shared/posix_tty.c
+++ b/hw/xfree86/os-support/shared/posix_tty.c
@@ -400,17 +400,14 @@ int
 xf86ReadSerial (int fd, void *buf, int count)
 {
 	int r;
-#ifdef DEBUG
 	int i;
-#endif
+
 	SYSCALL (r = read (fd, buf, count));
-#ifdef DEBUG
-	ErrorF("ReadingSerial: 0x%x",
+	DebugF("ReadingSerial: 0x%x",
 	       (unsigned char)*(((unsigned char *)buf)));
 	for (i = 1; i < r; i++)
-	    ErrorF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i));
-	ErrorF("\n");
-#endif
+	    DebugF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i));
+	DebugF("\n");
 	return (r);
 }
 
@@ -418,14 +415,12 @@ int
 xf86WriteSerial (int fd, const void *buf, int count)
 {
 	int r;
-#ifdef DEBUG
 	int i;
 
-	ErrorF("WritingSerial: 0x%x",(unsigned char)*(((unsigned char *)buf)));
+	DebugF("WritingSerial: 0x%x",(unsigned char)*(((unsigned char *)buf)));
 	for (i = 1; i < count; i++)
 	    ErrorF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i));
-	ErrorF("\n");
-#endif
+	DebugF("\n");
 	SYSCALL (r = write (fd, buf, count));
 	return (r);
 }
@@ -482,9 +477,7 @@ xf86FlushInput(int fd)
 	struct timeval timeout;
 	char c[4];
 
-#ifdef DEBUG
-	ErrorF("FlushingSerial\n");
-#endif
+	DebugF("FlushingSerial\n");
 	if (tcflush(fd, TCIFLUSH) == 0)
 		return 0;
 
diff --git a/hw/xfree86/ramdac/TI.c b/hw/xfree86/ramdac/TI.c
index f421fc3..1c541d7 100644
--- a/hw/xfree86/ramdac/TI.c
+++ b/hw/xfree86/ramdac/TI.c
@@ -115,10 +115,8 @@ TIramdacCalculateMNPForClock(
     VCO = 8.0 * IntRef * best_m / best_n;
     ActualClock = VCO / ( 1 << p );
 
-#ifdef DEBUG
-    ErrorF( "f_out=%ld f_vco=%.1f n=%d m=%d p=%d\n",
+    DebugF( "f_out=%ld f_vco=%.1f n=%d m=%d p=%d\n",
 	    ActualClock, VCO, *rN, *rM, *rP);
-#endif
 
     return (ActualClock);
 }
diff --git a/hw/xfree86/vbe/vbeModes.c b/hw/xfree86/vbe/vbeModes.c
index fb730a7..1a4d240 100644
--- a/hw/xfree86/vbe/vbeModes.c
+++ b/hw/xfree86/vbe/vbeModes.c
@@ -414,11 +414,9 @@ VBESetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
 	    data->block->PixelClock = best->Clock * 1000;
 	    /* XXX May not have this. */
 	    clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock);
-#ifdef DEBUG
-	    ErrorF("Setting clock %.2fMHz, closest is %.2fMHz\n",
+	    DebugF("Setting clock %.2fMHz, closest is %.2fMHz\n",
 		(double)data->block->PixelClock / 1000000.0, 
 		(double)clock / 1000000.0);
-#endif
 	    if (clock)
 		data->block->PixelClock = clock;
 	    data->mode |= (1 << 11);
diff --git a/hw/xfree86/vgahw/vgaHW.c b/hw/xfree86/vgahw/vgaHW.c
index 9d466e3..004376b 100644
--- a/hw/xfree86/vgahw/vgaHW.c
+++ b/hw/xfree86/vgahw/vgaHW.c
@@ -1025,32 +1025,24 @@ vgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
 
     for (i = 0; i < save->numCRTC; i++) {
 	save->CRTC[i] = hwp->readCrtc(hwp, i);
-#ifdef DEBUG
-	ErrorF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
-#endif
+	DebugF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
     }
 
     hwp->enablePalette(hwp);
     for (i = 0; i < save->numAttribute; i++) {
 	save->Attribute[i] = hwp->readAttr(hwp, i);
-#ifdef DEBUG
-	ErrorF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
-#endif
+	DebugF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
     }
     hwp->disablePalette(hwp);
 
     for (i = 0; i < save->numGraphics; i++) {
 	save->Graphics[i] = hwp->readGr(hwp, i);
-#ifdef DEBUG
-	ErrorF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
-#endif
+	DebugF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
     }
 
     for (i = 1; i < save->numSequencer; i++) {
 	save->Sequencer[i] = hwp->readSeq(hwp, i);
-#ifdef DEBUG
-	ErrorF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
-#endif
+	DebugF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
     }
 }
 
@@ -1088,18 +1080,16 @@ vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save)
     hwp->writeDacReadAddr(hwp, 0x00);
     for (i = 0; i < 6; i++) {
 	save->DAC[i] = hwp->readDacData(hwp);
-#ifdef DEBUG
 	switch (i % 3) {
 	case 0:
-	    ErrorF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
+	    DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
 	    break;
 	case 1:
-	    ErrorF("0x%02x, ", save->DAC[i]);
+	    DebugF("0x%02x, ", save->DAC[i]);
 	    break;
 	case 2:
-	    ErrorF("0x%02x\n", save->DAC[i]);
+	    DebugF("0x%02x\n", save->DAC[i]);
 	}
-#endif
     }
 
     /*
@@ -1131,18 +1121,16 @@ vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save)
 	for (i = 6; i < 768; i++) {
 	    save->DAC[i] = hwp->readDacData(hwp);
 	    DACDelay(hwp);
-#ifdef DEBUG
 	    switch (i % 3) {
 	    case 0:
-		ErrorF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
+		DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
 		break;
 	    case 1:
-		ErrorF("0x%02x, ", save->DAC[i]);
+		DebugF("0x%02x, ", save->DAC[i]);
 		break;
 	    case 2:
-		ErrorF("0x%02x\n", save->DAC[i]);
+		DebugF("0x%02x\n", save->DAC[i]);
 	    }
-#endif
 	}
     }
 
@@ -1772,9 +1760,7 @@ vgaHWMapMem(ScrnInfoPtr scrp)
      * XXX This is not correct but we do it
      * for now.
      */
-#ifdef DEBUG
-    ErrorF("Mapping VGAMem\n");
-#endif
+    DebugF("Mapping VGAMem\n");
     hwp->Base = xf86MapDomainMemory(scr_index, VIDMEM_MMIO_32BIT, hwp->dev,
 				    hwp->MapPhys, hwp->MapSize);
     return hwp->Base != NULL;
@@ -1790,9 +1776,7 @@ vgaHWUnmapMem(ScrnInfoPtr scrp)
     if (hwp->Base == NULL)
 	return;
     
-#ifdef DEBUG
-    ErrorF("Unmapping VGAMem\n");
-#endif
+    DebugF("Unmapping VGAMem\n");
     xf86UnMapVidMem(scr_index, hwp->Base, hwp->MapSize);
     hwp->Base = NULL;
 }
commit 9c5b761c8c86cca56f4b4af272f42ba89c9c3ba5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat May 9 16:19:13 2009 +1000

    Revert "xkb: write the _XKB_RF_RULES_PROP to each device."
    
    This commit shouldn't have been pushed, we're still sorting out the API we
    want to use.
    
    This reverts commit 876910a951053f0bd31e30098de3da15a1c1f5d6.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index e37a68e..7c611bc 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -51,7 +51,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <X11/extensions/XKMformat.h>
 #include "xkbfile.h"
 #include "xkb.h"
-#include "exevents.h"
 
 #define	CREATE_ATOM(s)	MakeAtom(s,sizeof(s)-1,1)
 
@@ -155,22 +154,18 @@ XkbFreeRMLVOSet(XkbRMLVOSet *rmlvo, Bool freeRMLVO)
         memset(rmlvo, 0, sizeof(XkbRMLVOSet));
 }
 
-/**
- * Write the given used rules to the device, or (if device is NULL) to the
- * root window property.
- */
 static Bool
-XkbWriteRulesProp(DeviceIntPtr dev, XkbRMLVOSet *rmlvo)
+XkbWriteRulesProp(ClientPtr client, pointer closure)
 {
 int 			len,out;
 Atom			name;
 char *			pval;
 
-    len= (rmlvo->rules ? strlen(rmlvo->rules) : 0);
-    len+= (rmlvo->model ? strlen(rmlvo->model) : 0);
-    len+= (rmlvo->layout ? strlen(rmlvo->layout) : 0);
-    len+= (rmlvo->variant ? strlen(rmlvo->variant) : 0);
-    len+= (rmlvo->options ? strlen(rmlvo->options) : 0);
+    len= (XkbRulesUsed?strlen(XkbRulesUsed):0);
+    len+= (XkbModelUsed?strlen(XkbModelUsed):0);
+    len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0);
+    len+= (XkbVariantUsed?strlen(XkbVariantUsed):0);
+    len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0);
     if (len<1)
 	return True;
 
@@ -188,57 +183,41 @@ char *			pval;
 	return True;
     }
     out= 0;
-    if (rmlvo->rules) {
-	strcpy(&pval[out],rmlvo->rules);
-	out+= strlen(rmlvo->rules);
+    if (XkbRulesUsed) {
+	strcpy(&pval[out],XkbRulesUsed);
+	out+= strlen(XkbRulesUsed);
     }
     pval[out++]= '\0';
-    if (rmlvo->model) {
-	strcpy(&pval[out],rmlvo->model);
-	out+= strlen(rmlvo->model);
-    }
+    if (XkbModelUsed) {
+	strcpy(&pval[out],XkbModelUsed);
+	out+= strlen(XkbModelUsed);
+    } 
     pval[out++]= '\0';
-    if (rmlvo->layout) {
-	strcpy(&pval[out],rmlvo->layout);
-	out+= strlen(rmlvo->layout);
+    if (XkbLayoutUsed) {
+	strcpy(&pval[out],XkbLayoutUsed);
+	out+= strlen(XkbLayoutUsed);
     }
     pval[out++]= '\0';
-    if (rmlvo->variant) {
-	strcpy(&pval[out],rmlvo->variant);
-	out+= strlen(rmlvo->variant);
+    if (XkbVariantUsed) {
+	strcpy(&pval[out],XkbVariantUsed);
+	out+= strlen(XkbVariantUsed);
     }
     pval[out++]= '\0';
-    if (rmlvo->options) {
-	strcpy(&pval[out],rmlvo->options);
-	out+= strlen(rmlvo->options);
+    if (XkbOptionsUsed) {
+	strcpy(&pval[out],XkbOptionsUsed);
+	out+= strlen(XkbOptionsUsed);
     }
     pval[out++]= '\0';
     if (out!=len) {
 	ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
 								out,len);
     }
-    if (dev)
-        XIChangeDeviceProperty(dev, name, XA_STRING, 8, PropModeReplace, len,
-                               pval, True);
-    else
-        dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8,
-                                PropModeReplace, len, pval, True);
-
+    dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8,
+			    PropModeReplace, len, pval, True);
     xfree(pval);
     return True;
 }
 
-static Bool
-XkbWriteRootWindowRulesProp(ClientPtr client, pointer closure)
-{
-    Bool rc;
-    XkbRMLVOSet *rmlvo = (XkbRMLVOSet*)closure;
-
-    rc = XkbWriteRulesProp(NULL, rmlvo);
-    XkbFreeRMLVOSet(rmlvo, TRUE);
-    return rc;
-}
-
 static void
 XkbSetRulesUsed(XkbRMLVOSet *rmlvo)
 {
@@ -258,18 +237,7 @@ XkbSetRulesUsed(XkbRMLVOSet *rmlvo)
 	_XkbFree(XkbOptionsUsed);
     XkbOptionsUsed= (rmlvo->options?_XkbDupString(rmlvo->options):NULL);
     if (XkbWantRulesProp)
-    {
-        XkbRMLVOSet* rmlvo_used = xcalloc(1, sizeof(XkbRMLVOSet));
-        if (rmlvo_used)
-        {
-            rmlvo_used->rules = _XkbDupString(XkbRulesUsed);
-            rmlvo_used->model = _XkbDupString(XkbModelUsed);
-            rmlvo_used->layout = _XkbDupString(XkbLayoutUsed);
-            rmlvo_used->variant = _XkbDupString(XkbVariantUsed);
-            rmlvo_used->options = _XkbDupString(XkbOptionsUsed);
-            QueueWorkProc(XkbWriteRootWindowRulesProp,NULL,rmlvo_used);
-        }
-    }
+	QueueWorkProc(XkbWriteRulesProp,NULL,NULL);
     return;
 }
 
@@ -646,7 +614,6 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo,
 
     XkbSetRulesDflts(rmlvo);
     XkbSetRulesUsed(rmlvo);
-    XkbWriteRulesProp(dev, rmlvo);
     XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
 
     return TRUE;
commit 00bc043fa0398a1d14d46b87da2ff3031a9535dc
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 8 10:10:25 2009 +1000

    dix: export subpixel precision in XI2 events for root/event coordinates.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index e51b8ec..58fd6d2 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -385,8 +385,8 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
     xde->valuators_len  = vallen;
     xde->deviceid       = ev->deviceid;
     xde->sourceid       = ev->sourceid;
-    xde->root_x         = FP1616(ev->root_x, 0);
-    xde->root_y         = FP1616(ev->root_y, 0);
+    xde->root_x         = FP1616(ev->root_x, ev->root_x_frac);
+    xde->root_y         = FP1616(ev->root_y, ev->root_y_frac);
 
     xde->mods.base_mods         = ev->mods.base;
     xde->mods.latched_mods      = ev->mods.latched;
diff --git a/dix/getevents.c b/dix/getevents.c
index 7aafc98..30b2c69 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -44,6 +44,7 @@
 #include "dixevents.h"
 #include "mipointer.h"
 #include "events.h"
+#include "eventconvert.h"
 
 #include <X11/extensions/XKBproto.h>
 #include "xkbsrv.h"
@@ -1070,9 +1071,10 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         event->detail.button = buttons;
     }
 
-    /* XXX: this should be 16.16 fixed point */
     event->root_x = cx; /* root_x/y always in screen coords */
     event->root_y = cy;
+    event->root_x_frac = pDev->last.remainder[0];
+    event->root_y_frac = pDev->last.remainder[1];
 
     set_valuators(pDev, event, first_valuator, num_valuators, valuators);
 
diff --git a/include/events.h b/include/events.h
index da8f58a..6803b5b 100644
--- a/include/events.h
+++ b/include/events.h
@@ -86,8 +86,10 @@ typedef struct
         uint32_t button;  /**< Button number */
         uint32_t key;     /**< Key code */
     } detail;
-    uint32_t root_x;      /**< Pos relative to root window in 16.16 fixed pt */
-    uint32_t root_y;      /**< Pos relative to root window in 16.16 fixed pt */
+    uint16_t root_x;      /**< Pos relative to root window in integral data */
+    float root_x_frac;    /**< Pos relative to root window in frac part */
+    uint16_t root_y;      /**< Pos relative to root window in integral part */
+    float root_y_frac;    /**< Pos relative to root window in frac part */
     uint8_t    buttons[(MAX_BUTTONS + 7)/8]; /**< Button mask */
     struct {
         uint8_t  mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
commit bae070914fc27db122e6131ae4838559c4a72f65
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 7 16:52:31 2009 +1000

    input: update to inputproto 1.9.99.8 XI2 defines.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
index 746f4a5..96b515d 100644
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@ -95,7 +95,7 @@ void XISendDeviceHierarchyEvent(int flags)
         info++;
     }
 
-    dummyDev.id = AllDevices;
+    dummyDev.id = XIAllDevices;
     SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1);
 }
 
@@ -146,7 +146,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
 
         switch(any->type)
         {
-            case CH_CreateMasterDevice:
+            case XICreateMasterDevice:
                 {
                     xXICreateMasterInfo* c = (xXICreateMasterInfo*)any;
                     char* name;
@@ -194,16 +194,16 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                     AttachDevice(NULL, xtstkeybd, keybd);
 
                     xfree(name);
-                    flags |= HF_MasterAdded;
+                    flags |= XIMasterAdded;
                 }
                 break;
-            case CH_RemoveMasterDevice:
+            case XIRemoveMasterDevice:
                 {
                     xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)any;
                     DeviceIntPtr xtstdevice;
 
-                    if (r->return_mode != AttachToMaster &&
-                            r->return_mode != Floating)
+                    if (r->return_mode != XIAttachToMaster &&
+                            r->return_mode != XIFloating)
                         return BadValue;
 
                     rc = dixLookupDevice(&ptr, r->deviceid, client,
@@ -300,7 +300,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
 
                     /* Disabling sends the devices floating, reattach them if
                      * desired. */
-                    if (r->return_mode == AttachToMaster)
+                    if (r->return_mode == XIAttachToMaster)
                     {
                         DeviceIntPtr attached,
                                      newptr,
@@ -360,10 +360,10 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                     RemoveDevice(xtstkeybd);
                     RemoveDevice(keybd);
                     RemoveDevice(ptr);
-                    flags |= HF_MasterRemoved;
+                    flags |= XIMasterRemoved;
                 }
                 break;
-            case CH_DetachSlave:
+            case XIDetachSlave:
                 {
                     xXIDetachSlaveInfo* c = (xXIDetachSlaveInfo*)any;
                     DeviceIntPtr *xtstdevice;
@@ -392,10 +392,10 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                     }
 
                     AttachDevice(client, ptr, NULL);
-                    flags |= HF_SlaveDetached;
+                    flags |= XISlaveDetached;
                 }
                 break;
-            case CH_AttachSlave:
+            case XIAttachSlave:
                 {
                     xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)any;
                     DeviceIntPtr newmaster;
@@ -444,7 +444,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                         goto unwind;
                     }
                     AttachDevice(client, ptr, newmaster);
-                    flags |= HF_SlaveAttached;
+                    flags |= XISlaveAttached;
                 }
                 break;
         }
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 12c53eb..7772029 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -685,7 +685,7 @@ XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChanged
     dcce->time         = GetTimeInMillis();
     dcce->deviceid     = master->id;
     dcce->sourceid     = device->id;
-    dcce->reason       = SlaveSwitch;
+    dcce->reason       = XISlaveSwitch;
     dcce->num_classes  = 0;
     dcce->length = (len - sizeof(xEvent))/4;
 
diff --git a/Xi/querydev.c b/Xi/querydev.c
index c7ee0e1..b50d038 100644
--- a/Xi/querydev.c
+++ b/Xi/querydev.c
@@ -70,7 +70,7 @@ ProcXIQueryDevice(ClientPtr client)
     REQUEST(xXIQueryDeviceReq);
     REQUEST_SIZE_MATCH(xXIQueryDeviceReq);
 
-    if (stuff->deviceid != AllDevices && stuff->deviceid != AllMasterDevices)
+    if (stuff->deviceid != XIAllDevices && stuff->deviceid != XIAllMasterDevices)
     {
         rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
         if (rc != Success)
@@ -87,15 +87,15 @@ ProcXIQueryDevice(ClientPtr client)
         len = 0;
         for (dev = inputInfo.devices; dev; dev = dev->next)
         {
-            if (stuff->deviceid == AllDevices ||
-                (stuff->deviceid == AllMasterDevices && dev->isMaster))
+            if (stuff->deviceid == XIAllDevices ||
+                (stuff->deviceid == XIAllMasterDevices && dev->isMaster))
                 len += SizeDeviceInfo(dev);
         }
 
         for (dev = inputInfo.off_devices; dev; dev = dev->next)
         {
-            if (stuff->deviceid == AllDevices ||
-                (stuff->deviceid == AllMasterDevices && dev->isMaster))
+            if (stuff->deviceid == XIAllDevices ||
+                (stuff->deviceid == XIAllMasterDevices && dev->isMaster))
                 len += SizeDeviceInfo(dev);
         }
 
@@ -125,8 +125,8 @@ ProcXIQueryDevice(ClientPtr client)
     {
         for (dev = inputInfo.devices; dev; dev = dev->next)
         {
-            if (stuff->deviceid == AllDevices ||
-                    (stuff->deviceid == AllMasterDevices && dev->isMaster))
+            if (stuff->deviceid == XIAllDevices ||
+                    (stuff->deviceid == XIAllMasterDevices && dev->isMaster))
             {
                 len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
                 if (client->swapped)
@@ -138,8 +138,8 @@ ProcXIQueryDevice(ClientPtr client)
 
         for (dev = inputInfo.off_devices; dev; dev = dev->next)
         {
-            if (stuff->deviceid == AllDevices ||
-                    (stuff->deviceid == AllMasterDevices && dev->isMaster))
+            if (stuff->deviceid == XIAllDevices ||
+                    (stuff->deviceid == XIAllMasterDevices && dev->isMaster))
             {
                 len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
                 if (client->swapped)
@@ -329,14 +329,14 @@ int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment)
     if (dev->isMaster)
     {
         DeviceIntPtr paired = GetPairedDevice(dev);
-        use = IsPointerDevice(dev) ? MasterPointer : MasterKeyboard;
+        use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard;
         *attachment = (paired ? paired->id : 0);
     } else if (master)
     {
-        use = IsPointerDevice(master) ? SlavePointer : SlaveKeyboard;
+        use = IsPointerDevice(master) ? XISlavePointer : XISlaveKeyboard;
         *attachment = master->id;
     } else
-        use = FloatingSlave;
+        use = XIFloatingSlave;
 
     return use;
 }
diff --git a/Xi/selectev.c b/Xi/selectev.c
index 45bf68b..013fdc9 100644
--- a/Xi/selectev.c
+++ b/Xi/selectev.c
@@ -106,7 +106,7 @@ HandleDevicePresenceMask(ClientPtr client, WindowPtr win,
 
     /* We always only use mksidx = AllDevices for events not bound to
      * devices */
-    if (AddExtensionClient (win, client, mask, AllDevices) != Success)
+    if (AddExtensionClient (win, client, mask, XIAllDevices) != Success)
         return BadAlloc;
 
     RecalculateDeviceDeliverableEvents(win);
diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c
index 4df9a10..9eb36c4 100644
--- a/Xi/xiallowev.c
+++ b/Xi/xiallowev.c
@@ -72,24 +72,24 @@ ProcXIAllowEvents(ClientPtr client)
     time = ClientTimeToServerTime(stuff->time);
 
     switch (stuff->mode) {
-    case ReplayDevice:
+    case XIReplayDevice:
 	AllowSome(client, time, dev, NOT_GRABBED);
 	break;
-    case SyncDevice:
+    case XISyncDevice:
 	AllowSome(client, time, dev, FREEZE_NEXT_EVENT);
 	break;
-    case AsyncDevice:
+    case XIAsyncDevice:
 	AllowSome(client, time, dev, THAWED);
 	break;
-    case AsyncPairedDevice:
+    case XIAsyncPairedDevice:
         if (dev->isMaster)
             AllowSome(client, time, dev, THAW_OTHERS);
 	break;
-    case SyncPair:
+    case XISyncPair:
         if (dev->isMaster)
             AllowSome(client, time, dev, FREEZE_BOTH_NEXT_EVENT);
 	break;
-    case AsyncPair:
+    case XIAsyncPair:
         if (dev->isMaster)
             AllowSome(client, time, dev, THAWED_BOTH);
 	break;
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
index 61f36d2..0a6f0e5 100644
--- a/Xi/xipassivegrab.c
+++ b/Xi/xipassivegrab.c
@@ -93,8 +93,8 @@ ProcXIPassiveGrabDevice(ClientPtr client)
     if (ret != Success)
 	return ret;
 
-    if (stuff->grab_type != GrabtypeButton &&
-        stuff->grab_type != GrabtypeKeysym)
+    if (stuff->grab_type != XIGrabtypeButton &&
+        stuff->grab_type != XIGrabtypeKeysym)
     {
         client->errorValue = stuff->grab_type;
         return BadValue;
@@ -149,11 +149,11 @@ ProcXIPassiveGrabDevice(ClientPtr client)
         param.modifiers = *modifiers;
         switch(stuff->grab_type)
         {
-            case GrabtypeButton:
+            case XIGrabtypeButton:
                 status = GrabButton(client, dev, mod_dev, stuff->detail,
                                     &param, GRABTYPE_XI2, &mask);
                 break;
-            case GrabtypeKeysym:
+            case XIGrabtypeKeysym:
                 status = GrabKey(client, dev, mod_dev, stuff->detail,
                                  &param, GRABTYPE_XI2, &mask);
                 break;
@@ -231,8 +231,8 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
     if (rc != Success)
 	return rc;
 
-    if (stuff->grab_type != GrabtypeButton &&
-        stuff->grab_type != GrabtypeKeysym)
+    if (stuff->grab_type != XIGrabtypeButton &&
+        stuff->grab_type != XIGrabtypeKeysym)
     {
         client->errorValue = stuff->grab_type;
         return BadValue;
@@ -250,7 +250,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
     tempGrab.device = dev;
     tempGrab.window = win;
     tempGrab.type =
-        (stuff->grab_type == GrabtypeButton) ? XI_ButtonPress : XI_KeyPress;
+        (stuff->grab_type == XIGrabtypeButton) ? XI_ButtonPress : XI_KeyPress;
     tempGrab.grabtype = GRABTYPE_XI2;
     tempGrab.modifierDevice = mod_dev;
     tempGrab.modifiersDetail.pMask = NULL;
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index 607b9b4..601dec3 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -82,7 +82,8 @@ ProcXISelectEvent(ClientPtr client)
     num_masks = stuff->num_masks;
     while(num_masks--)
     {
-        if (evmask->deviceid != AllDevices && evmask->deviceid != AllMasterDevices)
+        if (evmask->deviceid != XIAllDevices &&
+            evmask->deviceid != XIAllMasterDevices)
             rc = dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess);
         else {
             /* XXX: XACE here? */
@@ -109,8 +110,8 @@ ProcXISelectEvent(ClientPtr client)
     num_masks = stuff->num_masks;
     while(num_masks--)
     {
-        if (evmask->deviceid == AllDevices ||
-            evmask->deviceid == AllMasterDevices)
+        if (evmask->deviceid == XIAllDevices ||
+            evmask->deviceid == XIAllMasterDevices)
         {
             dummy.id = evmask->deviceid;
             dev = &dummy;
diff --git a/configure.ac b/configure.ac
index d95b2e8..98f9332 100644
--- a/configure.ac
+++ b/configure.ac
@@ -700,7 +700,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la'
 XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
 
 dnl Core modules for most extensions, et al.
-REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.9.3] [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto [xextproto >= 7.0.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] bigreqsproto resourceproto fontsproto [inputproto >= 1.9.99.7] [kbproto >= 1.0.3]"
+REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.9.3] [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto [xextproto >= 7.0.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] bigreqsproto resourceproto fontsproto [inputproto >= 1.9.99.8] [kbproto >= 1.0.3]"
 REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.13.2]"
 
 dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
diff --git a/dix/devices.c b/dix/devices.c
index f7e32fe..83285b4 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -267,7 +267,7 @@ SendDevicePresenceEvent(int deviceid, int type)
     ev.time = currentTime.milliseconds;
     ev.devchange = type;
     ev.deviceid = deviceid;
-    dummyDev.id = AllDevices;
+    dummyDev.id = XIAllDevices;
     SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
                           (xEvent*)&ev, 1);
 }
@@ -359,7 +359,7 @@ EnableDevice(DeviceIntPtr dev)
                            TRUE);
 
     SendDevicePresenceEvent(dev->id, DeviceEnabled);
-    XISendDeviceHierarchyEvent(HF_DeviceEnabled);
+    XISendDeviceHierarchyEvent(XIDeviceEnabled);
 
     return TRUE;
 }
@@ -430,7 +430,7 @@ DisableDevice(DeviceIntPtr dev)
                            TRUE);
 
     SendDevicePresenceEvent(dev->id, DeviceDisabled);
-    XISendDeviceHierarchyEvent(HF_DeviceDisabled);
+    XISendDeviceHierarchyEvent(XIDeviceDisabled);
     return TRUE;
 }
 
@@ -462,7 +462,7 @@ ActivateDevice(DeviceIntPtr dev)
         pScreen->DeviceCursorInitialize(dev, pScreen);
 
     SendDevicePresenceEvent(dev->id, DeviceAdded);
-    XISendDeviceHierarchyEvent(HF_SlaveAdded);
+    XISendDeviceHierarchyEvent(XISlaveAdded);
     return ret;
 }
 
@@ -977,7 +977,7 @@ RemoveDevice(DeviceIntPtr dev)
     if (ret == Success && initialized) {
         inputInfo.numDevices--;
         SendDevicePresenceEvent(deviceid, DeviceRemoved);
-        XISendDeviceHierarchyEvent(HF_SlaveRemoved);
+        XISendDeviceHierarchyEvent(XISlaveRemoved);
     }
 
     return ret;
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index d97ed81..e51b8ec 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -323,7 +323,7 @@ eventToClassesChanged(DeviceChangedEvent *ev, xEvent **xi)
     dce->evtype = XI_DeviceChanged;
     dce->time = GetTimeInMillis();
     dce->sourceid = slave->id;
-    dce->reason = SlaveSwitch;
+    dce->reason = XISlaveSwitch;
     dce->length = (len - sizeof(xEvent))/4;
 
     /* FIXME: this should come from the event, not from the device. See
diff --git a/dix/events.c b/dix/events.c
index bfdb096..e1410ed 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -454,8 +454,8 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
     filter = GetEventFilter(dev, ev);
 
     return ((inputMasks->xi2mask[dev->id][evtype/8] & filter) ||
-            inputMasks->xi2mask[AllDevices][evtype/8] ||
-            (inputMasks->xi2mask[AllMasterDevices][evtype/8] && dev->isMaster));
+            inputMasks->xi2mask[XIAllDevices][evtype/8] ||
+            (inputMasks->xi2mask[XIAllMasterDevices][evtype/8] && dev->isMaster));
 }
 
 static Mask
@@ -466,10 +466,10 @@ GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other)
     {
         int byte = ((xGenericEvent*)event)->evtype / 8;
         return (other->xi2mask[dev->id][byte] |
-                other->xi2mask[AllDevices][byte] |
-                (dev->isMaster? other->xi2mask[AllMasterDevices][byte] : 0));
+                other->xi2mask[XIAllDevices][byte] |
+                (dev->isMaster? other->xi2mask[XIAllMasterDevices][byte] : 0));
     } else if (CORE_EVENT(event))
-        return other->mask[AllDevices];
+        return other->mask[XIAllDevices];
     else
         return other->mask[dev->id];
 }
@@ -2310,8 +2310,8 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
     ((xGenericEvent*)&ev)->evtype = type;
     filter = GetEventFilter(dev, &ev);
     if (type && (inputMasks = wOtherInputMasks(win)) &&
-        ((inputMasks->xi2mask[AllDevices][type/8] & filter) ||
-         ((inputMasks->xi2mask[AllMasterDevices][type/8] & filter) && dev->isMaster) ||
+        ((inputMasks->xi2mask[XIAllDevices][type/8] & filter) ||
+         ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && dev->isMaster) ||
          (inputMasks->xi2mask[dev->id][type/8] & filter)))
         rc |= XI2_MASK;
 
@@ -2499,7 +2499,7 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
     if (!count)
 	return 0;
 
-    dummy.id = AllDevices;
+    dummy.id = XIAllDevices;
     filter = GetEventFilter(&dummy, xE);
     if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
 	xE->u.destroyNotify.event = pWin->drawable.id;
@@ -3745,8 +3745,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
         if (!deliveries)
         {
             int evtype = ((xGenericEvent*)xi2)->evtype;
-            mask = grab->xi2mask[AllDevices][evtype/8] |
-                   grab->xi2mask[AllMasterDevices][evtype/8] |
+            mask = grab->xi2mask[XIAllDevices][evtype/8] |
+                   grab->xi2mask[XIAllMasterDevices][evtype/8] |
                    grab->xi2mask[thisDev->id][evtype/8];
             /* try XI2 event */
             FixUpEventFromWindow(thisDev, xi2, grab->window, None, TRUE);
commit 83f32d3972b8bfb0a87069dfb3fcd64b6b7c6424
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 7 10:05:29 2009 +1000

    Xi: Add XI2 property requests.

diff --git a/Xi/extinit.c b/Xi/extinit.c
index eb2a901..4b82f62 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -250,7 +250,11 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXIUngrabDevice,                     /* 52 */
         ProcXIAllowEvents,                      /* 53 */
         ProcXIPassiveGrabDevice,                /* 54 */
-        ProcXIPassiveUngrabDevice               /* 55 */
+        ProcXIPassiveUngrabDevice,              /* 55 */
+        ProcXIListProperties,                   /* 56 */
+        ProcXIChangeProperty,                   /* 57 */
+        ProcXIDeleteProperty,                   /* 58 */
+        ProcXIGetProperty                       /* 59 */
 };
 
 /* For swapped clients */
@@ -310,7 +314,11 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXIUngrabDevice,                     /* 52 */
         SProcXIAllowEvents,                      /* 53 */
         SProcXIPassiveGrabDevice,                /* 54 */
-        SProcXIPassiveUngrabDevice               /* 55 */
+        SProcXIPassiveUngrabDevice,              /* 55 */
+        SProcXIListProperties,                   /* 56 */
+        SProcXIChangeProperty,                   /* 57 */
+        SProcXIDeleteProperty,                   /* 58 */
+        SProcXIGetProperty                       /* 59 */
 };
 
 /*****************************************************************
@@ -505,6 +513,10 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
 	SRepXIGrabDevice(client, len, (xXIGrabDeviceReply *) rep);
     else if (rep->RepType == X_XIGrabDevice)
 	SRepXIPassiveGrabDevice(client, len, (xXIPassiveGrabDeviceReply *) rep);
+    else if (rep->RepType == X_XIListProperties)
+	SRepXIListProperties(client, len, (xXIListPropertiesReply *) rep);
+    else if (rep->RepType == X_XIGetProperty)
+	SRepXIGetProperty(client, len, (xXIGetPropertyReply *) rep);
     else {
 	FatalError("XINPUT confused sending swapped reply");
     }
@@ -777,6 +789,18 @@ static void SDeviceHierarchyEvent(xXIDeviceHierarchyEvent *from,
     }
 }
 
+static void SXIPropertyEvent(xXIPropertyEvent *from, xXIPropertyEvent *to)
+{
+    char n;
+
+    *to = *from;
+    swaps(&to->sequenceNumber, n);
+    swapl(&to->length, n);
+    swaps(&to->evtype, n);
+    swaps(&to->deviceid, n);
+    swapl(&to->property, n);
+}
+
 /** Event swapping function for XI2 events. */
 static void
 XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
@@ -795,6 +819,10 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
             SDeviceHierarchyEvent((xXIDeviceHierarchyEvent*)from,
                                   (xXIDeviceHierarchyEvent*)to);
             break;
+        case XI_PropertyEvent:
+            SXIPropertyEvent((xXIPropertyEvent*)from,
+                           (xXIPropertyEvent*)to);
+            break;
         default:
             SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to);
             break;
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 7725715..3cda82b 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -34,6 +34,7 @@
 #include <X11/extensions/XI.h>
 #include <X11/Xatom.h>
 #include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include "exglobals.h"
 #include "exevents.h"
 #include "swaprep.h"
@@ -169,6 +170,36 @@ static struct dev_properties
 
 static long XIPropHandlerID = 1;
 
+static void send_property_event(DeviceIntPtr dev, Atom property, int what)
+{
+        devicePropertyNotify    event;
+        xXIPropertyEvent        xi2;
+        int state;
+
+        if (what == XIPropertyDeleted)
+            state = PropertyDelete;
+        else
+            state = PropertyNewValue;
+
+        event.type      = DevicePropertyNotify;
+        event.deviceid  = dev->id;
+        event.state     = state;
+        event.atom      = property;
+        event.time      = currentTime.milliseconds;
+        SendEventToAllWindows(dev, DevicePropertyNotifyMask,
+                              (xEvent*)&event, 1);
+
+        xi2.type        = GenericEvent;
+        xi2.extension   = IReqCode;
+        xi2.length      = 0;
+        xi2.evtype      = XI_PropertyEvent;
+        xi2.deviceid    = dev->id;
+        xi2.time        = currentTime.milliseconds;
+        xi2.property    = property;
+        xi2.what        = what;
+        SendEventToAllWindows(dev, GetEventFilter(dev, &xi2), (xEvent*)&xi2, 1);
+}
+
 static int list_atoms(DeviceIntPtr dev, int *natoms, Atom **atoms_return)
 {
     XIPropertyPtr prop;
@@ -581,20 +612,11 @@ XIDeleteAllDeviceProperties (DeviceIntPtr device)
 {
     XIPropertyPtr               prop, next;
     XIPropertyHandlerPtr        curr_handler, next_handler;
-    devicePropertyNotify        event;
 
     for (prop = device->properties.properties; prop; prop = next)
     {
         next = prop->next;
-
-        event.type      = DevicePropertyNotify;
-        event.deviceid  = device->id;
-        event.state     = PropertyDelete;
-        event.atom      = prop->propertyName;
-        event.time      = currentTime.milliseconds;
-        SendEventToAllWindows(device, DevicePropertyNotifyMask,
-                (xEvent*)&event, 1);
-
+        send_property_event(device, prop->propertyName, XIPropertyDeleted);
         XIDestroyDeviceProperty(prop);
     }
 
@@ -613,7 +635,6 @@ int
 XIDeleteDeviceProperty (DeviceIntPtr device, Atom property, Bool fromClient)
 {
     XIPropertyPtr               prop, *prev;
-    devicePropertyNotify        event;
     int                         rc = Success;
 
     for (prev = &device->properties.properties; (prop = *prev); prev = &(prop->next))
@@ -640,13 +661,7 @@ XIDeleteDeviceProperty (DeviceIntPtr device, Atom property, Bool fromClient)
     if (prop)
     {
         *prev = prop->next;
-        event.type      = DevicePropertyNotify;
-        event.deviceid  = device->id;
-        event.state     = PropertyDelete;
-        event.atom      = prop->propertyName;
-        event.time      = currentTime.milliseconds;
-        SendEventToAllWindows(device, DevicePropertyNotifyMask,
-                              (xEvent*)&event, 1);
+        send_property_event(device, prop->propertyName, XIPropertyDeleted);
         XIDestroyDeviceProperty (prop);
     }
 
@@ -659,7 +674,6 @@ XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type,
                         pointer value, Bool sendevent)
 {
     XIPropertyPtr               prop;
-    devicePropertyNotify        event;
     int                         size_in_bytes;
     int                         total_size;
     unsigned long               total_len;
@@ -778,15 +792,9 @@ XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type,
     }
 
     if (sendevent)
-    {
-        event.type      = DevicePropertyNotify;
-        event.deviceid  = dev->id;
-        event.state     = PropertyNewValue;
-        event.atom      = prop->propertyName;
-        event.time      = currentTime.milliseconds;
-        SendEventToAllWindows(dev, DevicePropertyNotifyMask,
-                              (xEvent*)&event, 1);
-    }
+        send_property_event(dev, prop->propertyName,
+                            (add) ?  XIPropertyCreated : XIPropertyModified);
+
     return(Success);
 }
 
@@ -965,28 +973,7 @@ ProcXGetDeviceProperty (ClientPtr client)
     reply.length = (length + 3) >> 2;
 
     if (stuff->delete && (reply.bytesAfter == 0))
-    {
-        devicePropertyNotify    event;
-        xXIPropertyEvent        xi2;
-
-        event.type      = DevicePropertyNotify;
-        event.deviceid  = dev->id;
-        event.state     = PropertyDelete;
-        event.atom      = stuff->property;
-        event.time      = currentTime.milliseconds;
-        SendEventToAllWindows(dev, DevicePropertyNotifyMask,
-                              (xEvent*)&event, 1);
-
-        xi2.type        = GenericEvent;
-        xi2.extension   = IReqCode;
-        xi2.length      = 0;
-        xi2.evtype      = XI_PropertyEvent;
-        xi2.deviceid    = dev->id;
-        xi2.time        = currentTime.milliseconds;
-        xi2.property    = stuff->property;
-        xi2.what        = XIPropertyDeleted;
-        SendEventToAllWindows(dev, XI_PropertyEventMask, (xEvent*)&xi2, 1);
-    }
+        send_property_event(dev, stuff->property, XIPropertyDeleted);
 
     WriteReplyToClient(client, sizeof(xGenericReply), &reply);
 
@@ -1100,3 +1087,248 @@ SRepXGetDeviceProperty(ClientPtr client, int size,
     /* data will be swapped, see ProcXGetDeviceProperty */
     WriteToClient(client, size, (char*)rep);
 }
+
+/* XI2 Request/reply handling */
+int
+ProcXIListProperties(ClientPtr client)
+{
+    Atom                        *atoms;
+    xXIListPropertiesReply      rep;
+    int                         natoms;
+    DeviceIntPtr                dev;
+    int                         rc = Success;
+
+    REQUEST(xXIListPropertiesReq);
+    REQUEST_SIZE_MATCH(xXIListPropertiesReq);
+
+    rc = dixLookupDevice (&dev, stuff->deviceid, client, DixReadAccess);
+    if (rc != Success)
+        return rc;
+
+    rc = list_atoms(dev, &natoms, &atoms);
+    if (rc != Success)
+        return rc;
+
+    rep.repType = X_Reply;
+    rep.RepType = X_XIListProperties;
+    rep.length = natoms;
+    rep.sequenceNumber = client->sequence;
+    rep.num_properties = natoms;
+
+    WriteReplyToClient(client, sizeof(xXIListPropertiesReply), &rep);
+    if (natoms)
+    {
+        client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+        WriteSwappedDataToClient(client, natoms * sizeof(Atom), atoms);
+        xfree(atoms);
+    }
+    return rc;
+}
+
+int
+ProcXIChangeProperty(ClientPtr client)
+{
+    int                 rc;
+    DeviceIntPtr        dev;
+    int                 totalSize;
+    unsigned long       len;
+
+    REQUEST(xXIChangePropertyReq);
+    REQUEST_AT_LEAST_SIZE(xXIChangePropertyReq);
+    UpdateCurrentTime();
+
+    rc = dixLookupDevice (&dev, stuff->deviceid, client, DixWriteAccess);
+    if (rc != Success)
+        return rc;
+
+    rc = check_change_property(client, stuff->property, stuff->type,
+                               stuff->format, stuff->mode, stuff->num_items);
+    len = stuff->num_items;
+    if (len > ((0xffffffff - sizeof(xXIChangePropertyReq)) >> 2))
+        return BadLength;
+
+    totalSize = len * (stuff->format/8);
+    REQUEST_FIXED_SIZE(xXIChangePropertyReq, totalSize);
+
+    rc = change_property(client, dev, stuff->property, stuff->type,
+                         stuff->format, stuff->mode, len, (void*)&stuff[1]);
+    return rc;
+}
+
+int
+ProcXIDeleteProperty(ClientPtr client)
+{
+    DeviceIntPtr        dev;
+    int                 rc;
+    REQUEST(xXIDeletePropertyReq);
+
+    REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
+    UpdateCurrentTime();
+    rc =  dixLookupDevice (&dev, stuff->deviceid, client, DixWriteAccess);
+    if (rc != Success)
+        return rc;
+
+    if (!ValidAtom(stuff->property))
+    {
+        client->errorValue = stuff->property;
+        return (BadAtom);
+    }
+
+    rc = XIDeleteDeviceProperty(dev, stuff->property, TRUE);
+    return rc;
+}
+
+
+int
+ProcXIGetProperty(ClientPtr client)
+{
+    REQUEST(xXIGetPropertyReq);
+    DeviceIntPtr                dev;
+    xXIGetPropertyReply         reply;
+    int                         length;
+    int                         rc, format, nitems, bytes_after;
+    char                        *data;
+    Atom                        type;
+
+    REQUEST_SIZE_MATCH(xXIGetPropertyReq);
+    if (stuff->delete)
+        UpdateCurrentTime();
+    rc = dixLookupDevice (&dev, stuff->deviceid, client,
+                           stuff->delete ? DixWriteAccess :
+                           DixReadAccess);
+    if (rc != Success)
+        return rc;
+
+    rc = get_property(client, dev, stuff->property, stuff->type,
+            stuff->delete, stuff->offset, stuff->len,
+            &bytes_after, &type, &format, &nitems, &length, &data);
+
+    if (rc != Success)
+        return rc;
+
+    reply.repType = X_Reply;
+    reply.RepType = X_XIGetProperty;
+    reply.sequenceNumber = client->sequence;
+    reply.num_items = nitems;
+    reply.format = format;
+    reply.bytes_after = bytes_after;
+    reply.type = type;
+    reply.length = (length + 3)/4;
+
+    if (length && stuff->delete && (reply.bytes_after == 0))
+        send_property_event(dev, stuff->property, XIPropertyDeleted);
+
+    WriteReplyToClient(client, sizeof(xXIGetPropertyReply), &reply);
+
+    if (length)
+    {
+        switch (reply.format) {
+            case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+            case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+            default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+        }
+        WriteSwappedDataToClient(client, length, data);
+    }
+
+    /* delete the Property */
+    if (stuff->delete && (reply.bytes_after == 0))
+    {
+        XIPropertyPtr prop, *prev;
+        for (prev = &dev->properties.properties; (prop = *prev); prev = &prop->next)
+        {
+            if (prop->propertyName == stuff->property)
+            {
+                *prev = prop->next;
+                XIDestroyDeviceProperty(prop);
+                break;
+            }
+        }
+    }
+
+    return Success;
+}
+
+int
+SProcXIListProperties(ClientPtr client)
+{
+    char n;
+    REQUEST(xXIListPropertiesReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+
+    REQUEST_SIZE_MATCH(xXIListPropertiesReq);
+    return (ProcXIListProperties(client));
+}
+
+int
+SProcXIChangeProperty(ClientPtr client)
+{
+    char n;
+    REQUEST(xXIChangePropertyReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->property, n);
+    swapl(&stuff->type, n);
+    swapl(&stuff->num_items, n);
+    REQUEST_SIZE_MATCH(xXIChangePropertyReq);
+    return (ProcXIChangeProperty(client));
+}
+
+int
+SProcXIDeleteProperty(ClientPtr client)
+{
+    char n;
+    REQUEST(xXIDeletePropertyReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->property, n);
+    REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
+    return (ProcXIDeleteProperty(client));
+}
+
+int
+SProcXIGetProperty(ClientPtr client)
+{
+    char n;
+    REQUEST(xXIGetPropertyReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->property, n);
+    swapl(&stuff->type, n);
+    swapl(&stuff->offset, n);
+    swapl(&stuff->len, n);
+    REQUEST_SIZE_MATCH(xXIGetPropertyReq);
+    return (ProcXIGetProperty(client));
+}
+
+
+void
+SRepXIListProperties(ClientPtr client, int size,
+                     xXIListPropertiesReply *rep)
+{
+    char n;
+    swaps(&rep->sequenceNumber, n);
+    swapl(&rep->length, n);
+    swaps(&rep->num_properties, n);
+    /* properties will be swapped later, see ProcXIListProperties */
+    WriteToClient(client, size, (char*)rep);
+}
+
+void
+SRepXIGetProperty(ClientPtr client, int size,
+                  xXIGetPropertyReply *rep)
+{
+    char n;
+
+    swaps(&rep->sequenceNumber, n);
+    swapl(&rep->length, n);
+    swapl(&rep->type, n);
+    swapl(&rep->bytes_after, n);
+    swapl(&rep->num_items, n);
+    /* data will be swapped, see ProcXIGetProperty */
+    WriteToClient(client, size, (char*)rep);
+}
diff --git a/Xi/xiproperty.h b/Xi/xiproperty.h
index e66b447..bc4bbae 100644
--- a/Xi/xiproperty.h
+++ b/Xi/xiproperty.h
@@ -43,4 +43,19 @@ void SRepXListDeviceProperties(ClientPtr client, int size,
 void SRepXGetDeviceProperty(ClientPtr client, int size,
                             xGetDevicePropertyReply *rep);
 
+/* XI2 request/reply handling  */
+int ProcXIListProperties        (ClientPtr client);
+int ProcXIChangeProperty        (ClientPtr client);
+int ProcXIDeleteProperty        (ClientPtr client);
+int ProcXIGetProperty           (ClientPtr client);
+
+int SProcXIListProperties       (ClientPtr client);
+int SProcXIChangeProperty       (ClientPtr client);
+int SProcXIDeleteProperty       (ClientPtr client);
+int SProcXIGetProperty          (ClientPtr client);
+
+void SRepXIListProperties(ClientPtr client, int size,
+                          xXIListPropertiesReply *rep);
+void SRepXIGetProperty(ClientPtr client, int size,
+                       xXIGetPropertyReply *rep);
 #endif /* XIPROPERTY_H */
diff --git a/test/input.c b/test/input.c
index e49cc81..238cad3 100644
--- a/test/input.c
+++ b/test/input.c
@@ -299,6 +299,10 @@ static void xi2_struct_sizes(void)
     compare(xXIAllowEventsReq);
     compare(xXIPassiveGrabDeviceReq);
     compare(xXIPassiveUngrabDeviceReq);
+    compare(xXIListPropertiesReq);
+    compare(xXIChangePropertyReq);
+    compare(xXIDeletePropertyReq);
+    compare(xXIGetPropertyReq);
 #undef compare
 }
 
commit 9935bec6e860cba9a3cc5baadd372ddb89d72ef0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu May 7 09:43:56 2009 +1000

    Xi: split some code out of the XI 1.5 property request processing.
    
    This is in preparation for the XI2 property requests that can re-use much of
    this code.

diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 7e20e03..7725715 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -169,6 +169,165 @@ static struct dev_properties
 
 static long XIPropHandlerID = 1;
 
+static int list_atoms(DeviceIntPtr dev, int *natoms, Atom **atoms_return)
+{
+    XIPropertyPtr prop;
+    Atom *atoms         = NULL;
+    int nprops          = 0;
+
+    for (prop = dev->properties.properties; prop; prop = prop->next)
+        nprops++;
+    if (nprops)
+    {
+        Atom *a;
+
+        atoms = xalloc(nprops * sizeof(Atom));
+        if(!atoms)
+            return BadAlloc;
+        a = atoms;
+        for (prop = dev->properties.properties; prop; prop = prop->next, a++)
+            *a = prop->propertyName;
+    }
+
+    *natoms = nprops;
+    *atoms_return = atoms;
+    return Success;
+}
+
+static int
+get_property(ClientPtr client, DeviceIntPtr dev, Atom property, Atom type,
+             BOOL delete, int offset, int length,
+             int *bytes_after, Atom *type_return, int *format, int *nitems,
+             int *length_return, char **data)
+{
+    unsigned long n, len, ind;
+    int rc;
+    XIPropertyPtr prop;
+    XIPropertyValuePtr prop_value;
+
+    if (!ValidAtom(property))
+    {
+        client->errorValue = property;
+        return(BadAtom);
+    }
+    if ((delete != xTrue) && (delete != xFalse))
+    {
+        client->errorValue = delete;
+        return(BadValue);
+    }
+
+    if ((type != AnyPropertyType) && !ValidAtom(type))
+    {
+        client->errorValue = type;
+        return(BadAtom);
+    }
+
+    for (prop = dev->properties.properties; prop; prop = prop->next)
+        if (prop->propertyName == property)
+            break;
+
+    if (!prop)
+    {
+        *bytes_after = 0;
+        *type_return = None;
+        *format = 0;
+        *nitems = 0;
+        *length_return = 0;
+        return Success;
+    }
+
+    rc = XIGetDeviceProperty(dev, property, &prop_value);
+    if (rc != Success)
+    {
+        client->errorValue = property;
+        return rc;
+    }
+
+    /* If the request type and actual type don't match. Return the
+    property information, but not the data. */
+
+    if (((type != prop_value->type) && (type != AnyPropertyType)))
+    {
+        *bytes_after = prop_value->size;
+        *format = prop_value->format;
+        *length_return = 0;
+        *nitems = 0;
+        *type_return = prop_value->type;
+        return Success;
+    }
+
+    /* Return type, format, value to client */
+    n = (prop_value->format/8) * prop_value->size; /* size (bytes) of prop */
+    ind = offset << 2;
+
+   /* If offset is invalid such that it causes "len" to
+            be negative, it's a value error. */
+
+    if (n < ind)
+    {
+        client->errorValue = offset;
+        return BadValue;
+    }
+
+    len = min(n - ind, 4 * length);
+
+    *bytes_after = n - (ind + len);
+    *format = prop_value->format;
+    *length_return = len;
+    if (prop_value->format)
+        *nitems = len / (prop_value->format / 8);
+    else
+        *nitems = 0;
+    *type_return = prop_value->type;
+
+    *data = (char*)prop_value->data + ind;
+
+    return Success;
+}
+
+static int
+check_change_property(ClientPtr client, Atom property, Atom type, int format,
+                      int mode, int nitems)
+{
+    if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
+        (mode != PropModePrepend))
+    {
+        client->errorValue = mode;
+        return BadValue;
+    }
+    if ((format != 8) && (format != 16) && (format != 32))
+    {
+        client->errorValue = format;
+        return BadValue;
+    }
+
+    if (!ValidAtom(property))
+    {
+        client->errorValue = property;
+        return(BadAtom);
+    }
+    if (!ValidAtom(type))
+    {
+        client->errorValue = type;
+        return(BadAtom);
+    }
+
+    return Success;
+}
+
+static int
+change_property(ClientPtr client, DeviceIntPtr dev, Atom property, Atom type,
+                int format, int mode, int len, void *data)
+{
+    int rc = Success;
+
+    rc = XIChangeDeviceProperty(dev, property, type, format, mode, len, data, TRUE);
+    if (rc != Success)
+        client->errorValue = property;
+
+    return rc;
+}
+
 /**
  * Return the atom assigned to the specified string or 0 if the atom isn't known
  * to the DIX.
@@ -681,11 +840,10 @@ XISetDevicePropertyDeletable(DeviceIntPtr dev, Atom property, Bool deletable)
 int
 ProcXListDeviceProperties (ClientPtr client)
 {
-    Atom                        *pAtoms = NULL, *temppAtoms;
+    Atom                        *atoms;
     xListDevicePropertiesReply  rep;
-    int                         numProps = 0;
+    int                         natoms;
     DeviceIntPtr                dev;
-    XIPropertyPtr               prop;
     int                         rc = Success;
 
     REQUEST(xListDevicePropertiesReq);
@@ -695,27 +853,22 @@ ProcXListDeviceProperties (ClientPtr client)
     if (rc != Success)
         return rc;
 
-    for (prop = dev->properties.properties; prop; prop = prop->next)
-        numProps++;
-    if (numProps)
-        if(!(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom))))
-            return(BadAlloc);
+    rc = list_atoms(dev, &natoms, &atoms);
+    if (rc != Success)
+        return rc;
 
     rep.repType = X_Reply;
     rep.RepType = X_ListDeviceProperties;
-    rep.length = (numProps * sizeof(Atom)) >> 2;
+    rep.length = natoms;
     rep.sequenceNumber = client->sequence;
-    rep.nAtoms = numProps;
-    temppAtoms = pAtoms;
-    for (prop = dev->properties.properties; prop; prop = prop->next)
-        *temppAtoms++ = prop->propertyName;
+    rep.nAtoms = natoms;
 
     WriteReplyToClient(client, sizeof(xListDevicePropertiesReply), &rep);
-    if (numProps)
+    if (natoms)
     {
         client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
-        WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms);
-        xfree(pAtoms);
+        WriteSwappedDataToClient(client, natoms * sizeof(Atom), atoms);
+        xfree(atoms);
     }
     return rc;
 }
@@ -725,55 +878,29 @@ ProcXChangeDeviceProperty (ClientPtr client)
 {
     REQUEST(xChangeDevicePropertyReq);
     DeviceIntPtr        dev;
-    char                format, mode;
     unsigned long       len;
-    int                 sizeInBytes;
     int                 totalSize;
     int                 rc;
 
     REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq);
     UpdateCurrentTime();
-    format = stuff->format;
-    mode = stuff->mode;
-    if ((mode != PropModeReplace) && (mode != PropModeAppend) &&
-        (mode != PropModePrepend))
-    {
-        client->errorValue = mode;
-        return BadValue;
-    }
-    if ((format != 8) && (format != 16) && (format != 32))
-    {
-        client->errorValue = format;
-        return BadValue;
-    }
-    len = stuff->nUnits;
-    if (len > ((0xffffffff - sizeof(xChangeDevicePropertyReq)) >> 2))
-        return BadLength;
-    sizeInBytes = format>>3;
-    totalSize = len * sizeInBytes;
-    REQUEST_FIXED_SIZE(xChangeDevicePropertyReq, totalSize);
 
     rc = dixLookupDevice (&dev, stuff->deviceid, client, DixWriteAccess);
     if (rc != Success)
         return rc;
 
-    if (!ValidAtom(stuff->property))
-    {
-        client->errorValue = stuff->property;
-        return(BadAtom);
-    }
-    if (!ValidAtom(stuff->type))
-    {
-        client->errorValue = stuff->type;
-        return(BadAtom);
-    }
+    rc = check_change_property(client, stuff->property, stuff->type,
+                               stuff->format, stuff->mode, stuff->nUnits);
+
+    len = stuff->nUnits;
+    if (len > ((0xffffffff - sizeof(xChangeDevicePropertyReq)) >> 2))
+        return BadLength;
 
-    rc = XIChangeDeviceProperty(dev, stuff->property,
-                                 stuff->type, (int)format,
-                                 (int)mode, len, (pointer)&stuff[1], TRUE);
+    totalSize = len * (stuff->format/8);
+    REQUEST_FIXED_SIZE(xChangeDevicePropertyReq, totalSize);
 
-    if (rc != Success)
-        client->errorValue = stuff->property;
+    rc = change_property(client, dev, stuff->property, stuff->type,
+                         stuff->format, stuff->mode, len, (void*)&stuff[1]);
     return rc;
 }
 
@@ -804,12 +931,12 @@ int
 ProcXGetDeviceProperty (ClientPtr client)
 {
     REQUEST(xGetDevicePropertyReq);
-    XIPropertyPtr               prop, *prev;
-    XIPropertyValuePtr          prop_value;
-    unsigned long               n, len, ind;
     DeviceIntPtr                dev;
+    int                         length;
+    int                         rc, format, nitems, bytes_after;
+    char                        *data;
+    Atom                        type;
     xGetDevicePropertyReply     reply;
-    int                         rc;
 
     REQUEST_SIZE_MATCH(xGetDevicePropertyReq);
     if (stuff->delete)
@@ -820,121 +947,74 @@ ProcXGetDeviceProperty (ClientPtr client)
     if (rc != Success)
         return rc;
 
-    if (!ValidAtom(stuff->property))
-    {
-        client->errorValue = stuff->property;
-        return(BadAtom);
-    }
-    if ((stuff->delete != xTrue) && (stuff->delete != xFalse))
-    {
-        client->errorValue = stuff->delete;
-        return(BadValue);
-    }
-    if ((stuff->type != AnyPropertyType) && !ValidAtom(stuff->type))
-    {
-        client->errorValue = stuff->type;
-        return(BadAtom);
-    }
+    rc = get_property(client, dev, stuff->property, stuff->type,
+            stuff->delete, stuff->longOffset, stuff->longLength,
+            &bytes_after, &type, &format, &nitems, &length, &data);
 
-    for (prev = &dev->properties.properties; (prop = *prev); prev = &prop->next)
-        if (prop->propertyName == stuff->property)
-            break;
+    if (rc != Success)
+        return rc;
 
     reply.repType = X_Reply;
     reply.RepType = X_GetDeviceProperty;
     reply.sequenceNumber = client->sequence;
     reply.deviceid = dev->id;
-    if (!prop)
-    {
-        reply.nItems = 0;
-        reply.length = 0;
-        reply.bytesAfter = 0;
-        reply.propertyType = None;
-        reply.format = 0;
-        WriteReplyToClient(client, sizeof(xGetDevicePropertyReply), &reply);
-        return(client->noClientException);
-    }
-
-    rc = XIGetDeviceProperty(dev, stuff->property, &prop_value);
-    if (rc != Success)
-    {
-        client->errorValue = stuff->property;
-        return rc;
-    }
-
-    /* If the request type and actual type don't match. Return the
-    property information, but not the data. */
-
-    if (((stuff->type != prop_value->type) &&
-         (stuff->type != AnyPropertyType))
-       )
-    {
-        reply.bytesAfter = prop_value->size;
-        reply.format = prop_value->format;
-        reply.length = 0;
-        reply.nItems = 0;
-        reply.propertyType = prop_value->type;
-        WriteReplyToClient(client, sizeof(xGetDevicePropertyReply), &reply);
-        return(client->noClientException);
-    }
-
-/*
- *  Return type, format, value to client
- */
-    n = (prop_value->format/8) * prop_value->size; /* size (bytes) of prop */
-    ind = stuff->longOffset << 2;
-
-   /* If longOffset is invalid such that it causes "len" to
-            be negative, it's a value error. */
-
-    if (n < ind)
-    {
-        client->errorValue = stuff->longOffset;
-        return BadValue;
-    }
-
-    len = min(n - ind, 4 * stuff->longLength);
-
-    reply.bytesAfter = n - (ind + len);
-    reply.format = prop_value->format;
-    reply.length = (len + 3) >> 2;
-    if (prop_value->format)
-        reply.nItems = len / (prop_value->format / 8);
-    else
-        reply.nItems = 0;
-    reply.propertyType = prop_value->type;
+    reply.nItems = nitems;
+    reply.format = format;
+    reply.bytesAfter = bytes_after;
+    reply.propertyType = type;
+    reply.length = (length + 3) >> 2;
 
     if (stuff->delete && (reply.bytesAfter == 0))
     {
         devicePropertyNotify    event;
+        xXIPropertyEvent        xi2;
 
         event.type      = DevicePropertyNotify;
         event.deviceid  = dev->id;
         event.state     = PropertyDelete;
-        event.atom      = prop->propertyName;
+        event.atom      = stuff->property;
         event.time      = currentTime.milliseconds;
         SendEventToAllWindows(dev, DevicePropertyNotifyMask,
                               (xEvent*)&event, 1);
+
+        xi2.type        = GenericEvent;
+        xi2.extension   = IReqCode;
+        xi2.length      = 0;
+        xi2.evtype      = XI_PropertyEvent;
+        xi2.deviceid    = dev->id;
+        xi2.time        = currentTime.milliseconds;
+        xi2.property    = stuff->property;
+        xi2.what        = XIPropertyDeleted;
+        SendEventToAllWindows(dev, XI_PropertyEventMask, (xEvent*)&xi2, 1);
     }
 
     WriteReplyToClient(client, sizeof(xGenericReply), &reply);
-    if (len)
+
+    if (length)
     {
         switch (reply.format) {
-        case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
-        case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
-        default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+            case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+            case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+            default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
         }
-        WriteSwappedDataToClient(client, len,
-                                 (char *)prop_value->data + ind);
+        WriteSwappedDataToClient(client, length, data);
     }
 
+    /* delete the Property */
     if (stuff->delete && (reply.bytesAfter == 0))
-    { /* delete the Property */
-        *prev = prop->next;
-        XIDestroyDeviceProperty (prop);
+    {
+        XIPropertyPtr prop, *prev;
+        for (prev = &dev->properties.properties; (prop = *prev); prev = &prop->next)
+        {
+            if (prop->propertyName == stuff->property)
+            {
+                *prev = prop->next;
+                XIDestroyDeviceProperty(prop);
+                break;
+            }
+        }
     }
-    return(client->noClientException);
+    return Success;
 }
 
 
commit f6f1e417063d2d61d65731a7e3ebca3ec2bdaacc
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 6 22:25:28 2009 +1000

    Xi: fix copy/paste error causing sizeof against wrong struct.
    
    This wrong check may cause BadLength to be returned to the client even if the
    length is correct.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 8c6d53a..7e20e03 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -747,7 +747,7 @@ ProcXChangeDeviceProperty (ClientPtr client)
         return BadValue;
     }
     len = stuff->nUnits;
-    if (len > ((0xffffffff - sizeof(xChangePropertyReq)) >> 2))
+    if (len > ((0xffffffff - sizeof(xChangeDevicePropertyReq)) >> 2))
         return BadLength;
     sizeInBytes = format>>3;
     totalSize = len * sizeInBytes;
commit fc0013d744a345199f013ba5b6ef0e44201d0e68
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 6 16:55:32 2009 +1000

    Xi: don't double-swap the XListDeviceProperties reply.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index d633f51..8c6d53a 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -706,13 +706,6 @@ ProcXListDeviceProperties (ClientPtr client)
     rep.length = (numProps * sizeof(Atom)) >> 2;
     rep.sequenceNumber = client->sequence;
     rep.nAtoms = numProps;
-    if (client->swapped)
-    {
-        int n;
-        swaps (&rep.sequenceNumber, n);
-        swapl (&rep.length, n);
-        swaps (&rep.nAtoms, n);
-    }
     temppAtoms = pAtoms;
     for (prop = dev->properties.properties; prop; prop = prop->next)
         *temppAtoms++ = prop->propertyName;
commit 409012061b7d361a172b20455d4aaa5e47527c42
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 6 16:42:46 2009 +1000

    Xi: add missing break in XI event swapping function
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index ea778e6..eb2a901 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -794,6 +794,7 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
         case XI_HierarchyChanged:
             SDeviceHierarchyEvent((xXIDeviceHierarchyEvent*)from,
                                   (xXIDeviceHierarchyEvent*)to);
+            break;
         default:
             SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to);
             break;
commit c3c64978c4a231a3a8c18211d0716df875c75efa
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 6 15:05:06 2009 +1000

    Xi: fix a couple of wrong dixLookupDevice permission tags.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c
index a8cf1b6..4df9a10 100644
--- a/Xi/xiallowev.c
+++ b/Xi/xiallowev.c
@@ -65,7 +65,7 @@ ProcXIAllowEvents(ClientPtr client)
     REQUEST(xXIAllowEventsReq);
     REQUEST_SIZE_MATCH(xXIAllowEventsReq);
 
-    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
+    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
     if (ret != Success)
 	return ret;
 
diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c
index de13256..20f4e51 100644
--- a/Xi/xigrabdev.c
+++ b/Xi/xigrabdev.c
@@ -70,7 +70,7 @@ ProcXIGrabDevice(ClientPtr client)
     REQUEST(xXIGrabDeviceReq);
     REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
 
-    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
+    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
     if (ret != Success)
 	return ret;
 
diff --git a/Xi/xisetdevfocus.c b/Xi/xisetdevfocus.c
index 5945abd..7201e65 100644
--- a/Xi/xisetdevfocus.c
+++ b/Xi/xisetdevfocus.c
@@ -95,7 +95,7 @@ ProcXIGetDeviceFocus(ClientPtr client)
     REQUEST(xXIGetDeviceFocusReq);
     REQUEST_AT_LEAST_SIZE(xXIGetDeviceFocusReq);
 
-    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
+    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetFocusAccess);
     if (ret != Success)
 	return ret;
     if (!dev->focus)
commit 0d947aa8e87c5d92b702c60190c8bc5d32c9ba9c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 6 12:07:07 2009 +1000

    xfree86: fix xf86PostMotionEventP type checking
    
    We only put internal events into the queue now, so let's check for ET_Motion
    rather than the MotionNotify.
    
    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 3859741..6b34aad 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -744,7 +744,7 @@ xf86PostMotionEventP(DeviceIntPtr	device,
     int i = 0, nevents = 0;
     int dx = 0, dy = 0;
     Bool drag = xf86SendDragEvents(device);
-    xEvent *xE = NULL;
+    DeviceEvent *event;
     int index;
     int flags = 0;
 
@@ -790,10 +790,11 @@ xf86PostMotionEventP(DeviceIntPtr	device,
                                valuators);
 
     for (i = 0; i < nevents; i++) {
-        xE = (xf86Events + i)->event;
+        event = (DeviceEvent*)((xf86Events + i)->event);
         /* Don't post core motion events for devices not registered to send
          * drag events. */
-        if (xE->u.u.type != MotionNotify || drag) {
+        if (event->header == ET_Internal &&
+            (event->type != ET_Motion || drag)) {
             mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
         }
     }
commit 9457ce448988dacea9a3a1c14b6955767118ff31
Author: Simon Thum <simon.thum at gmx.de>
Date:   Thu Apr 30 13:01:17 2009 +0200

    dix: remove superfluous includes from ptrveloc.c
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 7c49cf5..7fa4200 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -28,11 +28,8 @@
 
 #include <math.h>
 #include <ptrveloc.h>
-#include <inputstr.h>
 #include <exevents.h>
 #include <X11/Xatom.h>
-#include <assert.h>
-#include <os.h>
 
 #include <xserver-properties.h>
 
commit ee30e1b102d779403eeda97e007b81e85f006a37
Author: Simon Thum <simon.thum at gmx.de>
Date:   Thu Apr 30 12:58:48 2009 +0200

    dix: fix warning in pointer acceleration
    
    newer gcc's warn against how this cast is done (though it eludes me why),
    and lrintf() is also faster especially on insane processors like the P4
    (http://www.mega-nerd.com/FPcast).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 1590cfd..7c49cf5 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -988,14 +988,20 @@ acceleratePointerPredictable(
 
                 if (dx) {
                     tmp = mult * fdx + pDev->last.remainder[0];
-                    *px = (int)roundf(tmp);
+                    /* Since it may not be apparent: lrintf() does not offer
+                     * strong statements about rounding; however because we
+                     * process each axis conditionally, there's no danger
+                     * of a toggling remainder. Its lack of guarantees hopefully
+                     * makes it faster on the average target. */
+                    *px = lrintf(tmp);
                     pDev->last.remainder[0] = tmp - (float)*px;
                 }
                 if (dy) {
                     tmp = mult * fdy + pDev->last.remainder[1];
-                    *py = (int)roundf(tmp);
+                    *py = lrintf(tmp);
                     pDev->last.remainder[1] = tmp - (float)*py;
                 }
+                DebugAccelF("pos (%i | %i) remainders x: %.3f y: %.3f delta x:%.3f y:%.3f\n", *px, *py, pDev->last.remainder[0], pDev->last.remainder[1], fdx, fdy);
             }
         }
     }
commit d220d6907d1d5138d1528c48b739e77f65616225
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 4 17:38:02 2009 +1000

    Xi: add GrabButton and GrabKeysym code.
    
    We don't do keycode grabs in XI2, they're pointless.

diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 1fa7b9a..56404b6 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -96,6 +96,8 @@ libXi_la_SOURCES =	\
 	xiallowev.h \
 	xigrabdev.c \
 	xigrabdev.h \
+	xipassivegrab.h \
+	xipassivegrab.c \
 	xiproperty.c \
 	xiproperty.h \
 	xiselectev.c \
diff --git a/Xi/exevents.c b/Xi/exevents.c
index a01432c..12c53eb 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1388,7 +1388,7 @@ GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
     WindowPtr pWin, confineTo;
     CursorPtr cursor;
     GrabPtr grab;
-    int rc;
+    int rc, type;
     Mask access_mode = DixGrabAccess;
 
     rc = CheckGrabValues(client, param);
@@ -1422,14 +1422,22 @@ GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
     if (rc != Success)
 	return rc;
 
+    if (grabtype == GRABTYPE_XI)
+        type = DeviceButtonPress;
+    else if (grabtype == GRABTYPE_XI2)
+        type = XI_ButtonPress;
 
     grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
-                      mask, param, DeviceButtonPress, button, confineTo, cursor);
+                      mask, param, type, button, confineTo, cursor);
     if (!grab)
 	return BadAlloc;
     return AddPassiveGrabToList(client, grab);
 }
 
+/**
+ * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If
+ * grabtype is GRABTYPE_XI2, the key is a keysym.
+ */
 int
 GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
         int key, GrabParameters *param, GrabType grabtype, GrabMask *mask)
@@ -1438,19 +1446,25 @@ GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
     GrabPtr grab;
     KeyClassPtr k = dev->key;
     Mask access_mode = DixGrabAccess;
-    int rc;
+    int rc, type;
 
     rc = CheckGrabValues(client, param);
     if (rc != Success)
         return rc;
     if (k == NULL)
 	return BadMatch;
-    if ((key > k->xkbInfo->desc->max_key_code ||
-         key < k->xkbInfo->desc->min_key_code)
-	&& (key != AnyKey)) {
-	client->errorValue = key;
-        return BadValue;
-    }
+    if (grabtype == GRABTYPE_XI)
+    {
+        if ((key > k->xkbInfo->desc->max_key_code ||
+                    key < k->xkbInfo->desc->min_key_code)
+                && (key != AnyKey)) {
+            client->errorValue = key;
+            return BadValue;
+        }
+        type = DeviceKeyPress;
+    } else if (grabtype == GRABTYPE_XI2)
+        type = XI_KeyPress;
+
     rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
     if (rc != Success)
 	return rc;
@@ -1461,7 +1475,7 @@ GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
 	return rc;
 
     grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
-                      mask, param, DeviceKeyPress, key, NULL, NULL);
+                      mask, param, type, key, NULL, NULL);
     if (!grab)
 	return BadAlloc;
     return AddPassiveGrabToList(client, grab);
diff --git a/Xi/extinit.c b/Xi/extinit.c
index fa7031e..ea778e6 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -122,6 +122,7 @@ SOFTWARE.
 #include "xiallowev.h"
 #include "xiselectev.h"
 #include "xigrabdev.h"
+#include "xipassivegrab.h"
 #include "xisetdevfocus.h"
 #include "xiproperty.h"
 
@@ -247,7 +248,9 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXIGetDeviceFocus,                   /* 50 */
         ProcXIGrabDevice,                       /* 51 */
         ProcXIUngrabDevice,                     /* 52 */
-        ProcXIAllowEvents                       /* 53 */
+        ProcXIAllowEvents,                      /* 53 */
+        ProcXIPassiveGrabDevice,                /* 54 */
+        ProcXIPassiveUngrabDevice               /* 55 */
 };
 
 /* For swapped clients */
@@ -305,7 +308,9 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXIGetDeviceFocus,                   /* 50 */
         SProcXIGrabDevice,                       /* 51 */
         SProcXIUngrabDevice,                     /* 52 */
-        SProcXIAllowEvents                       /* 53 */
+        SProcXIAllowEvents,                      /* 53 */
+        SProcXIPassiveGrabDevice,                /* 54 */
+        SProcXIPassiveUngrabDevice               /* 55 */
 };
 
 /*****************************************************************
@@ -498,6 +503,8 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
         SRepXIQueryDevice(client, len, (xXIQueryDeviceReply*)rep);
     else if (rep->RepType == X_XIGrabDevice)
 	SRepXIGrabDevice(client, len, (xXIGrabDeviceReply *) rep);
+    else if (rep->RepType == X_XIGrabDevice)
+	SRepXIPassiveGrabDevice(client, len, (xXIPassiveGrabDeviceReply *) rep);
     else {
 	FatalError("XINPUT confused sending swapped reply");
     }
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
new file mode 100644
index 0000000..61f36d2
--- /dev/null
+++ b/Xi/xipassivegrab.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+/***********************************************************************
+ *
+ * Request to grab or ungrab input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h"	/* DeviceIntPtr      */
+#include "windowstr.h"	/* window structure  */
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XI2proto.h>
+#include "swaprep.h"
+
+#include "exglobals.h" /* BadDevice */
+#include "exevents.h"
+#include "xipassivegrab.h"
+#include "dixgrabs.h"
+
+int
+SProcXIPassiveGrabDevice(ClientPtr client)
+{
+    int i;
+    char n;
+    xXIModifierInfo *mods;
+
+    REQUEST(xXIPassiveGrabDeviceReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->grab_window, n);
+    swapl(&stuff->cursor, n);
+    swapl(&stuff->time, n);
+    swapl(&stuff->detail, n);
+    swaps(&stuff->mask_len, n);
+    swaps(&stuff->num_modifiers, n);
+
+    mods = (xXIModifierInfo*)&stuff[1];
+
+    for (i = 0; i < stuff->num_modifiers; i++, mods++)
+    {
+        swapl(&mods->base_mods, n);
+        swapl(&mods->latched_mods, n);
+        swapl(&mods->locked_mods, n);
+    }
+
+    return ProcXIPassiveGrabDevice(client);
+}
+
+int
+ProcXIPassiveGrabDevice(ClientPtr client)
+{
+    DeviceIntPtr dev, mod_dev;
+    xXIPassiveGrabDeviceReply rep;
+    int i, ret = Success;
+    uint8_t status;
+    uint32_t *modifiers;
+    xXIGrabModifierInfo *modifiers_failed;
+    GrabMask mask;
+    GrabParameters param;
+
+    REQUEST(xXIPassiveGrabDeviceReq);
+    REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
+
+    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
+    if (ret != Success)
+	return ret;
+
+    if (stuff->grab_type != GrabtypeButton &&
+        stuff->grab_type != GrabtypeKeysym)
+    {
+        client->errorValue = stuff->grab_type;
+        return BadValue;
+    }
+
+    /* Can't grab for modifiers on an attached slave device */
+    if (!dev->isMaster)
+    {
+        if (!dev->u.master)
+            stuff->paired_device_mode = GrabModeAsync;
+        else if (dev->u.master && stuff->num_modifiers)
+            return BadDevice;
+    }
+    if ((stuff->mask_len * 4) > XI_LASTEVENT)
+    {
+        unsigned char *bits = (unsigned char*)&stuff[1];
+        for (i = XI_LASTEVENT; i < stuff->mask_len * 4; i++)
+        {
+            if (BitIsOn(bits, i))
+                return BadValue;
+        }
+    }
+
+    memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
+    memcpy(mask.xi2mask[stuff->deviceid], &stuff[1], stuff->mask_len * 4);
+
+    rep.repType = X_Reply;
+    rep.RepType = X_XIPassiveGrabDevice;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.num_modifiers = 0;
+
+    memset(&param, 0, sizeof(param));
+    param.ownerEvents = stuff->owner_events;
+    param.this_device_mode = stuff->grab_mode;
+    param.other_devices_mode = stuff->paired_device_mode;
+    param.grabWindow = stuff->grab_window;
+    param.cursor = stuff->cursor;
+
+    modifiers = (uint32_t*)&stuff[1] + stuff->mask_len;
+    modifiers_failed = xcalloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
+    if (!modifiers_failed)
+        return BadAlloc;
+
+    if (dev->isMaster)
+        mod_dev = GetPairedDevice(dev);
+    else
+        mod_dev = dev;
+
+    for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
+    {
+        param.modifiers = *modifiers;
+        switch(stuff->grab_type)
+        {
+            case GrabtypeButton:
+                status = GrabButton(client, dev, mod_dev, stuff->detail,
+                                    &param, GRABTYPE_XI2, &mask);
+                break;
+            case GrabtypeKeysym:
+                status = GrabKey(client, dev, mod_dev, stuff->detail,
+                                 &param, GRABTYPE_XI2, &mask);
+                break;
+        }
+
+        if (status != GrabSuccess)
+        {
+            xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
+
+            info->status = status;
+            info->modifiers = *modifiers;
+            rep.num_modifiers++;
+        }
+    }
+
+    WriteReplyToClient(client, sizeof(rep), &rep);
+    if (rep.num_modifiers)
+    {
+	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+        WriteSwappedDataToClient(client, rep.num_modifiers * 4, (char*)modifiers_failed);
+    }
+    xfree(modifiers_failed);
+    return ret;
+}
+
+void
+SRepXIPassiveGrabDevice(ClientPtr client, int size,
+                        xXIPassiveGrabDeviceReply * rep)
+{
+    char n;
+
+    swaps(&rep->sequenceNumber, n);
+    swapl(&rep->length, n);
+    swaps(&rep->num_modifiers, n);
+
+    WriteToClient(client, size, (char *)rep);
+}
+
+int
+SProcXIPassiveUngrabDevice(ClientPtr client)
+{
+    char n;
+    int i;
+    uint32_t *modifiers;
+
+    REQUEST(xXIPassiveUngrabDeviceReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->grab_window, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->detail, n);
+    swaps(&stuff->num_modifiers, n);
+
+    modifiers = (uint32_t*)&stuff[1];
+
+    for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
+        swapl(modifiers, n);
+
+    return ProcXIPassiveUngrabDevice(client);
+}
+
+int
+ProcXIPassiveUngrabDevice(ClientPtr client)
+{
+    DeviceIntPtr dev, mod_dev;
+    WindowPtr win;
+    GrabRec tempGrab;
+    uint32_t* modifiers;
+    int i, rc;
+
+    REQUEST(xXIPassiveUngrabDeviceReq);
+    REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
+
+    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
+    if (rc != Success)
+	return rc;
+
+    if (stuff->grab_type != GrabtypeButton &&
+        stuff->grab_type != GrabtypeKeysym)
+    {
+        client->errorValue = stuff->grab_type;
+        return BadValue;
+    }
+
+    rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
+    if (rc != Success)
+        return rc;
+
+    if (dev->isMaster)
+        mod_dev = GetPairedDevice(dev);
+    else
+        mod_dev = dev;
+
+    tempGrab.device = dev;
+    tempGrab.window = win;
+    tempGrab.type =
+        (stuff->grab_type == GrabtypeButton) ? XI_ButtonPress : XI_KeyPress;
+    tempGrab.grabtype = GRABTYPE_XI2;
+    tempGrab.modifierDevice = mod_dev;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.detail.exact = stuff->detail;
+    tempGrab.detail.pMask = NULL;
+
+    modifiers = (uint32_t*)&stuff[1];
+
+    for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
+    {
+        tempGrab.modifiersDetail.exact = *modifiers;
+        DeletePassiveGrabFromList(&tempGrab);
+    }
+
+    return Success;
+}
diff --git a/Xi/xipassivegrab.h b/Xi/xipassivegrab.h
new file mode 100644
index 0000000..84fb5eb
--- /dev/null
+++ b/Xi/xipassivegrab.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifndef XIPASSIVEGRAB_H
+#define XIPASSIVEGRAB_H
+
+int SProcXIPassiveUngrabDevice(ClientPtr client);
+int ProcXIPassiveUngrabDevice(ClientPtr client);
+void SRepXIPassiveGrabDevice(ClientPtr client, int size, xXIPassiveGrabDeviceReply * rep);
+int ProcXIPassiveGrabDevice(ClientPtr client);
+int SProcXIPassiveGrabDevice(ClientPtr client);
+
+#endif
diff --git a/dix/events.c b/dix/events.c
index 0ff8308..bfdb096 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3290,6 +3290,7 @@ CheckPassiveGrabsOnWindow(
     GrabInfoPtr grabinfo;
 #define CORE_MATCH      0x1
 #define XI_MATCH        0x2
+#define XI2_MATCH        0x4
     int match = 0;
 
     if (!grab)
@@ -3319,13 +3320,24 @@ CheckPassiveGrabsOnWindow(
             xkbi= gdev->key->xkbInfo;
 	tempGrab.modifierDevice = grab->modifierDevice;
         tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
-        /* FIXME: check for xi2 grabs */
 
-        /* Check for XI grabs first */
-        tempGrab.type = GetXIType((InternalEvent*)event);
-        tempGrab.grabtype = GRABTYPE_XI;
-	if (GrabMatchesSecond(&tempGrab, grab, FALSE))
-            match = XI_MATCH;
+        /* Check for XI2 and XI grabs first */
+        tempGrab.type = GetXI2Type((InternalEvent*)event);
+        tempGrab.grabtype = GRABTYPE_XI2;
+        if (event->type == ET_KeyPress)
+            tempGrab.detail.exact = XkbGetKeysym(device, event);
+        if (GrabMatchesSecond(&tempGrab, grab, FALSE))
+            match = XI2_MATCH;
+
+        tempGrab.detail.exact = event->detail.key;
+        if (!match)
+        {
+            tempGrab.type = GetXIType((InternalEvent*)event);
+            tempGrab.grabtype = GRABTYPE_XI;
+            if (GrabMatchesSecond(&tempGrab, grab, FALSE))
+                match = XI_MATCH;
+        }
+
         /* Check for a core grab (ignore the device when comparing) */
         if (!match && checkCore)
         {
@@ -3399,6 +3411,15 @@ CheckPassiveGrabsOnWindow(
                 }
                 xE = &core;
                 count = 1;
+            } else if (match & XI2_MATCH)
+            {
+                rc = EventToXI2((InternalEvent*)event, &xE);
+                if (rc != Success)
+                {
+                    ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
+                           "(%d, %d).\n", device->name, event->type, rc);
+                    continue;
+                }
             } else
             {
                 rc = EventToXI((InternalEvent*)event, &xE, &count);
@@ -3427,7 +3448,7 @@ CheckPassiveGrabsOnWindow(
 		grabinfo->sync.state = FROZEN_WITH_EVENT;
             }
 
-            if (match & XI_MATCH)
+            if (match & (XI_MATCH | XI2_MATCH))
                 xfree(xE); /* on core match xE == &core */
 	    return TRUE;
 	}
@@ -3435,6 +3456,7 @@ CheckPassiveGrabsOnWindow(
     return FALSE;
 #undef CORE_MATCH
 #undef XI_MATCH
+#undef XI2_MATCH
 }
 
 /**
diff --git a/dix/grabs.c b/dix/grabs.c
index 03776d2..eb8bec8 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -104,6 +104,9 @@ CreateGrab(
     grab->confineTo = confineTo;
     grab->cursor = cursor;
     grab->next = NULL;
+
+    if (grabtype == GRABTYPE_XI2)
+        memcpy(grab->xi2mask, mask->xi2mask, sizeof(mask->xi2mask));
     if (cursor)
 	cursor->refcnt++;
     return grab;
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 1ca0e30..64584ff 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -948,6 +948,10 @@ extern Bool XkbCopyDeviceKeymap(
         DeviceIntPtr            /* dst */,
         DeviceIntPtr            /* src */);
 
+extern int XkbGetKeysym(
+        DeviceIntPtr            /* dev */,
+        DeviceEvent*            /* event*/);
+
 #include "xkbfile.h"
 #include <X11/extensions/XKMformat.h>
 #include "xkbrules.h"
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 5ae426d..0bd41cd 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -2116,3 +2116,33 @@ XkbCopyDeviceKeymap(DeviceIntPtr dst, DeviceIntPtr src)
 
     return ret;
 }
+
+int
+XkbGetKeysym(DeviceIntPtr dev, DeviceEvent *event)
+{
+    XkbDescPtr xkb = dev->key->xkbInfo->desc;
+    XkbKeyTypePtr kt;
+    int group;
+    int i, level = 0;
+    int modmask;
+
+    group = event->group.base + event->group.latched + event->group.locked;
+
+    if (group >= xkb->ctrls->num_groups)
+        group = XkbAdjustGroup(group, xkb->ctrls);
+
+    modmask = event->mods.base | event->mods.latched; /* don't care about
+                                                         locked mods */
+    kt = XkbKeyKeyType(xkb, event->detail.key, group);
+
+    for (i = 0; i < kt->map_count; i++)
+    {
+        if (kt->map[i].mods.mask == modmask)
+        {
+            level = kt->map[i].level;
+            break;
+        }
+    }
+
+    return XkbKeySymEntry(xkb, event->detail.key, level, group);
+}
commit 1b593ced171d02f1d00034f0f733060706bb6d41
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 5 16:57:46 2009 +1000

    Xi: access the prev_state to get group/modifier state for key events.
    
    Key events may change the modifier state, so we need to get the prev_state for
    those (i.e. without the changes by the event already applied).
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 0793113..a01432c 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -983,13 +983,20 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
 
     if (kbd && kbd->key)
     {
-        event->mods.base = kbd->key->xkbInfo->state.base_mods;
-        event->mods.latched = kbd->key->xkbInfo->state.latched_mods;
-        event->mods.locked = kbd->key->xkbInfo->state.locked_mods;
-
-        event->group.base = kbd->key->xkbInfo->state.base_group;
-        event->group.latched = kbd->key->xkbInfo->state.latched_group;
-        event->group.locked = kbd->key->xkbInfo->state.locked_group;
+        XkbStatePtr state;
+        /* we need the state before the event happens */
+        if (event->type == ET_KeyPress || event->type == ET_KeyRelease)
+            state = &kbd->key->xkbInfo->prev_state;
+        else
+            state = &kbd->key->xkbInfo->state;
+
+        event->mods.base = state->base_mods;
+        event->mods.latched = state->latched_mods;
+        event->mods.locked = state->locked_mods;
+
+        event->group.base = state->base_group;
+        event->group.latched = state->latched_group;
+        event->group.locked = state->locked_group;
     }
 
     ret = UpdateDeviceState(device, event);
commit 35a4b8e7f4526a92d44cb16a783f21030cd1f6df
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue May 5 16:51:59 2009 +1000

    xkb: remove oldState from XkbHandleActions.
    
    I really don't know what the purpose of this variable is or was, aside from
    potentially clobbering up our key state since there's a path where it may be
    used uninitialised.
    
    Also, this means that xkbi->prev_state is now accessible from the DIX with
    meaningful data.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index fe58a18..417c617 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1075,7 +1075,6 @@ XkbSrvInfoPtr	xkbi;
 KeyClassPtr	keyc;
 int		changed,sendEvent;
 Bool		genStateNotify;
-XkbStateRec	oldState;
 XkbAction	act;
 XkbFilterPtr	filter;
 Bool		keyEvent;
@@ -1090,7 +1089,7 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
     /* The state may change, so if we're not in the middle of sending a state
      * notify, prepare for it */
     if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
-	oldState= xkbi->state;
+	xkbi->prev_state = xkbi->state;
 	xkbi->flags|= _XkbStateNotifyInProgress;
 	genStateNotify= True;
     }
@@ -1220,9 +1219,8 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
 	FixKeyState(event, dev);
     }
 
-    xkbi->prev_state= oldState;
     XkbComputeDerivedState(xkbi);
-    changed = XkbStateChangedFlags(&oldState,&xkbi->state);
+    changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state);
     if (genStateNotify) {
 	if (changed) {
 	    xkbStateNotify	sn;
commit d523fbe428e4513d85402caa83e9349256b680cc
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 4 17:00:57 2009 +1000

    test: add test for xi2 struct sizes.

diff --git a/test/input.c b/test/input.c
index a9027f0..e49cc81 100644
--- a/test/input.c
+++ b/test/input.c
@@ -25,10 +25,12 @@
 #include <dix-config.h>
 #endif
 
+#include <stdint.h>
 #include <X11/X.h>
 #include "misc.h"
 #include "resource.h"
 #include <X11/Xproto.h>
+#include <X11/extensions/XI2proto.h>
 #include <X11/Xatom.h>
 #include "windowstr.h"
 #include "inputstr.h"
@@ -276,6 +278,31 @@ static void dix_event_to_core_conversion(void)
     dix_event_to_core(ET_ProximityOut);
 }
 
+static void xi2_struct_sizes(void)
+{
+#define compare(req) \
+    g_assert(sizeof(req) == sz_##req);
+
+    compare(xXIQueryVersionReq);
+    compare(xXIWarpDevicePointerReq);
+    compare(xXIChangeDeviceCursorReq);
+    compare(xXIChangeDeviceHierarchyReq);
+    compare(xXISetClientPointerReq);
+    compare(xXIGetClientPointerReq);
+    compare(xXISelectEventsReq);
+    compare(xXIQueryVersionReq);
+    compare(xXIQueryDeviceReq);
+    compare(xXISetDeviceFocusReq);
+    compare(xXIGetDeviceFocusReq);
+    compare(xXIGrabDeviceReq);
+    compare(xXIUngrabDeviceReq);
+    compare(xXIAllowEventsReq);
+    compare(xXIPassiveGrabDeviceReq);
+    compare(xXIPassiveUngrabDeviceReq);
+#undef compare
+}
+
+
 int main(int argc, char** argv)
 {
     g_test_init(&argc, &argv,NULL);
@@ -284,6 +311,7 @@ int main(int argc, char** argv)
     g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
     g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
     g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
+    g_test_add_func("/dix/input/xi2-struct-sizes", xi2_struct_sizes);
 
     return g_test_run();
 }
commit 59358de4b68a01452bf68593beb83605087ebc8f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 4 17:30:19 2009 +1000

    input: ensure various ProcUngrabKey/Buttons have the right grabtype set.

diff --git a/Xi/ungrdevb.c b/Xi/ungrdevb.c
index a53dc5b..4e93f1a 100644
--- a/Xi/ungrdevb.c
+++ b/Xi/ungrdevb.c
@@ -132,6 +132,7 @@ ProcXUngrabDeviceButton(ClientPtr client)
     temporaryGrab.device = dev;
     temporaryGrab.window = pWin;
     temporaryGrab.type = DeviceButtonPress;
+    temporaryGrab.grabtype = GRABTYPE_XI;
     temporaryGrab.modifierDevice = mdev;
     temporaryGrab.modifiersDetail.exact = stuff->modifiers;
     temporaryGrab.modifiersDetail.pMask = NULL;
diff --git a/Xi/ungrdevk.c b/Xi/ungrdevk.c
index 7f5e4aa..3b4d626 100644
--- a/Xi/ungrdevk.c
+++ b/Xi/ungrdevk.c
@@ -139,6 +139,7 @@ ProcXUngrabDeviceKey(ClientPtr client)
     temporaryGrab.device = dev;
     temporaryGrab.window = pWin;
     temporaryGrab.type = DeviceKeyPress;
+    temporaryGrab.grabtype = GRABTYPE_XI;
     temporaryGrab.modifierDevice = mdev;
     temporaryGrab.modifiersDetail.exact = stuff->modifiers;
     temporaryGrab.modifiersDetail.pMask = NULL;
diff --git a/dix/events.c b/dix/events.c
index 86aa24f..0ff8308 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -5003,6 +5003,7 @@ ProcUngrabKey(ClientPtr client)
     tempGrab.modifiersDetail.pMask = NULL;
     tempGrab.modifierDevice = GetPairedDevice(keybd);
     tempGrab.type = KeyPress;
+    tempGrab.grabtype = GRABTYPE_CORE;
     tempGrab.detail.exact = stuff->key;
     tempGrab.detail.pMask = NULL;
     tempGrab.next = NULL;
@@ -5197,6 +5198,7 @@ ProcUngrabButton(ClientPtr client)
     tempGrab.modifierDevice = GetPairedDevice(ptr);
     tempGrab.type = ButtonPress;
     tempGrab.detail.exact = stuff->button;
+    tempGrab.grabtype = GRABTYPE_CORE;
     tempGrab.detail.pMask = NULL;
     tempGrab.next = NULL;
 
commit 834ea071b619506e0bef5bdbf0e3c59831cf6e99
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon May 4 15:58:15 2009 +1000

    dix: if grab types differ, two grabs cannot be the same.

diff --git a/dix/events.c b/dix/events.c
index e1feb4d..86aa24f 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3323,13 +3323,17 @@ CheckPassiveGrabsOnWindow(
 
         /* Check for XI grabs first */
         tempGrab.type = GetXIType((InternalEvent*)event);
+        tempGrab.grabtype = GRABTYPE_XI;
 	if (GrabMatchesSecond(&tempGrab, grab, FALSE))
             match = XI_MATCH;
         /* Check for a core grab (ignore the device when comparing) */
-        if (!match && checkCore &&
-            (tempGrab.type = GetCoreType((InternalEvent*)event)) &&
-            (GrabMatchesSecond(&tempGrab, grab, TRUE)))
+        if (!match && checkCore)
+        {
+            tempGrab.grabtype = GRABTYPE_CORE;
+            if ((tempGrab.type = GetCoreType((InternalEvent*)event)) &&
+                (GrabMatchesSecond(&tempGrab, grab, TRUE)))
                 match = CORE_MATCH;
+        }
 
         if (match && (!grab->confineTo ||
 	     (grab->confineTo->realized &&
diff --git a/dix/grabs.c b/dix/grabs.c
index 06e1ebb..03776d2 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -254,6 +254,10 @@ GrabSupersedesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
 Bool
 GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice)
 {
+
+    if (pFirstGrab->grabtype != pSecondGrab->grabtype)
+        return FALSE;
+
     if (!ignoreDevice &&
             ((pFirstGrab->device != pSecondGrab->device) ||
              (pFirstGrab->modifierDevice != pSecondGrab->modifierDevice)))
@@ -288,6 +292,9 @@ GrabMatchesSecond(GrabPtr pFirstGrab, GrabPtr pSecondGrab, Bool ignoreDevice)
 static Bool
 GrabsAreIdentical(GrabPtr pFirstGrab, GrabPtr pSecondGrab)
 {
+    if (pFirstGrab->grabtype != pSecondGrab->grabtype)
+        return FALSE;
+
     if (pFirstGrab->device != pSecondGrab->device || 
 	(pFirstGrab->modifierDevice != pSecondGrab->modifierDevice) ||
 	(pFirstGrab->type != pSecondGrab->type))
commit 63a3c727b35d1ffd8a850a5177bd6623cd78b179
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 1 15:24:02 2009 +1000

    Xext: shut up compiler warnings in xtest.c
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index cb32c28..96380b7 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -50,6 +50,7 @@
 #include <X11/extensions/XI.h>
 #include <X11/extensions/XIproto.h>
 #include "exglobals.h"
+#include "mipointer.h"
 
 #include "modinit.h"
 
@@ -162,7 +163,6 @@ ProcXTestFakeInput(ClientPtr client)
     int i;
     int base = 0;
     int flags = 0;
-    DeviceIntPtr xtstdevice;
 
     nev = (stuff->length << 2) - sizeof(xReq);
     if ((nev % sizeof(xEvent)) || !nev)
@@ -415,7 +415,7 @@ ProcXTestFakeInput(ClientPtr client)
     }
 
     for (i = 0; i < nevents; i++)
-        mieqProcessDeviceEvent(dev, (events+i)->event, NULL);
+        mieqProcessDeviceEvent(dev, (InternalEvent*)(events+i)->event, NULL);
 
     miPointerUpdateSprite(dev);
     return client->noClientException;
commit 226dd90597ef29998ac5db15c5457aad3fe9729e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 1 15:22:37 2009 +1000

    Xext: return BadDevice from XTest if we don't have keys/buttons/valuators.
    
    BadDevice is an XI error, but this cannot happen for core XTest fake input
    anyway since the device will be the matching virtual XTest slave device.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 8aca6a0..cb32c28 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -49,6 +49,7 @@
 #include <X11/extensions/xteststr.h>
 #include <X11/extensions/XI.h>
 #include <X11/extensions/XIproto.h>
+#include "exglobals.h"
 
 #include "modinit.h"
 
@@ -342,6 +343,9 @@ ProcXTestFakeInput(ClientPtr client)
     {
         case KeyPress:
         case KeyRelease:
+            if (!dev->key)
+                return BadDevice;
+
             if (ev->u.u.detail < dev->key->xkbInfo->desc->min_key_code ||
                 ev->u.u.detail > dev->key->xkbInfo->desc->max_key_code)
             {
@@ -350,6 +354,9 @@ ProcXTestFakeInput(ClientPtr client)
             }
             break;
         case MotionNotify:
+            if (!dev->valuator)
+                return BadDevice;
+
             /* broken lib, XI events have root uninitialized */
             if (extension || ev->u.keyButtonPointer.root == None)
                 root = GetCurrentRootWindow(dev);
@@ -376,6 +383,9 @@ ProcXTestFakeInput(ClientPtr client)
             break;
         case ButtonPress:
         case ButtonRelease:
+            if (!dev->button)
+                return BadDevice;
+
             if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
             {
                 client->errorValue = ev->u.u.detail;
commit 0fdff0a47a57a0096974ee83e07fefbad03075dd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 1 15:15:04 2009 +1000

    Xext: fix core Xtest button presses, don't call PickPointer.
    
    We already did the device selection before, so dev should be the XTest virtual
    pointer.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index d21eedc..8aca6a0 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -376,12 +376,6 @@ ProcXTestFakeInput(ClientPtr client)
             break;
         case ButtonPress:
         case ButtonRelease:
-            if (!extension)
-            {
-                dev = PickPointer(client);
-                if (dev->u.lastSlave)
-                    dev = dev->u.lastSlave;
-            }
             if (!ev->u.u.detail || ev->u.u.detail > dev->button->numButtons)
             {
                 client->errorValue = ev->u.u.detail;
commit f0124ed93cdcee8d22a6690e639a3f60b9a63c54
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 1 14:35:12 2009 +1000

    include: up the number of max. input devices to 40.
    
    With the Xtest virtual slave devices we have 4 devices for each MD
    pointer/keyboard pair, plus the AllDevices and AllMasterDevices reserved
    deviceids. It's quite easy to hit the current limit.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/misc.h b/include/misc.h
index 6a920cc..61dd947 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -86,7 +86,7 @@ OF THIS SOFTWARE.
 #define MAXCLIENTS	256
 #define MAXEXTENSIONS   128
 #define MAXFORMATS	8
-#define MAXDEVICES	20 /* input devices */
+#define MAXDEVICES	40 /* input devices */
 
 #define EXTENSION_EVENT_BASE 64
 #define EXTENSION_BASE 128
commit 08cd846000286eb5e07cc8d8cb313aff2d6e7faf
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri May 1 11:06:06 2009 +1000

    dix: only free the old cursor if the grab was successful.
    
    Testcase: start thunderbird and move a message around, crashes after two or
    three moves.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 6fe2182..e1feb4d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4446,7 +4446,7 @@ ProcGrabPointer(ClientPtr client)
     if (rc != Success)
         return rc;
 
-    if (oldCursor)
+    if (oldCursor && rep.status == GrabSuccess)
         FreeCursor (oldCursor, (Cursor)0);
 
     time = ClientTimeToServerTime(stuff->time);
commit 3d30789a05a730a03faa6058c73a5eda36ef3779
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 30 14:58:00 2009 +1000

    mi: don't crash if we're trying to update the pointer for a keyboard.
    
    If a device doesn't have a pointer, just return.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mipointer.c b/mi/mipointer.c
index e87fe79..c75c120 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -367,6 +367,9 @@ miPointerUpdateSprite (DeviceIntPtr pDev)
 
     pPointer = MIPOINTER(pDev);
 
+    if (!pPointer)
+        return;
+
     pScreen = pPointer->pScreen;
     if (!pScreen)
 	return;
commit 876910a951053f0bd31e30098de3da15a1c1f5d6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 30 14:46:45 2009 +1000

    xkb: write the _XKB_RF_RULES_PROP to each device.
    
    We only have one root window and writing the rules used to the same property
    for each device is quite pointless if you don't have the same RMLVO on all
    devices. So let's be sensible and write the same property to the device too,
    so at least we know which device got loaded with which RMLVO.

diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 7c611bc..e37a68e 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -51,6 +51,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <X11/extensions/XKMformat.h>
 #include "xkbfile.h"
 #include "xkb.h"
+#include "exevents.h"
 
 #define	CREATE_ATOM(s)	MakeAtom(s,sizeof(s)-1,1)
 
@@ -154,18 +155,22 @@ XkbFreeRMLVOSet(XkbRMLVOSet *rmlvo, Bool freeRMLVO)
         memset(rmlvo, 0, sizeof(XkbRMLVOSet));
 }
 
+/**
+ * Write the given used rules to the device, or (if device is NULL) to the
+ * root window property.
+ */
 static Bool
-XkbWriteRulesProp(ClientPtr client, pointer closure)
+XkbWriteRulesProp(DeviceIntPtr dev, XkbRMLVOSet *rmlvo)
 {
 int 			len,out;
 Atom			name;
 char *			pval;
 
-    len= (XkbRulesUsed?strlen(XkbRulesUsed):0);
-    len+= (XkbModelUsed?strlen(XkbModelUsed):0);
-    len+= (XkbLayoutUsed?strlen(XkbLayoutUsed):0);
-    len+= (XkbVariantUsed?strlen(XkbVariantUsed):0);
-    len+= (XkbOptionsUsed?strlen(XkbOptionsUsed):0);
+    len= (rmlvo->rules ? strlen(rmlvo->rules) : 0);
+    len+= (rmlvo->model ? strlen(rmlvo->model) : 0);
+    len+= (rmlvo->layout ? strlen(rmlvo->layout) : 0);
+    len+= (rmlvo->variant ? strlen(rmlvo->variant) : 0);
+    len+= (rmlvo->options ? strlen(rmlvo->options) : 0);
     if (len<1)
 	return True;
 
@@ -183,41 +188,57 @@ char *			pval;
 	return True;
     }
     out= 0;
-    if (XkbRulesUsed) {
-	strcpy(&pval[out],XkbRulesUsed);
-	out+= strlen(XkbRulesUsed);
+    if (rmlvo->rules) {
+	strcpy(&pval[out],rmlvo->rules);
+	out+= strlen(rmlvo->rules);
     }
     pval[out++]= '\0';
-    if (XkbModelUsed) {
-	strcpy(&pval[out],XkbModelUsed);
-	out+= strlen(XkbModelUsed);
-    } 
+    if (rmlvo->model) {
+	strcpy(&pval[out],rmlvo->model);
+	out+= strlen(rmlvo->model);
+    }
     pval[out++]= '\0';
-    if (XkbLayoutUsed) {
-	strcpy(&pval[out],XkbLayoutUsed);
-	out+= strlen(XkbLayoutUsed);
+    if (rmlvo->layout) {
+	strcpy(&pval[out],rmlvo->layout);
+	out+= strlen(rmlvo->layout);
     }
     pval[out++]= '\0';
-    if (XkbVariantUsed) {
-	strcpy(&pval[out],XkbVariantUsed);
-	out+= strlen(XkbVariantUsed);
+    if (rmlvo->variant) {
+	strcpy(&pval[out],rmlvo->variant);
+	out+= strlen(rmlvo->variant);
     }
     pval[out++]= '\0';
-    if (XkbOptionsUsed) {
-	strcpy(&pval[out],XkbOptionsUsed);
-	out+= strlen(XkbOptionsUsed);
+    if (rmlvo->options) {
+	strcpy(&pval[out],rmlvo->options);
+	out+= strlen(rmlvo->options);
     }
     pval[out++]= '\0';
     if (out!=len) {
 	ErrorF("[xkb] Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n",
 								out,len);
     }
-    dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8,
-			    PropModeReplace, len, pval, True);
+    if (dev)
+        XIChangeDeviceProperty(dev, name, XA_STRING, 8, PropModeReplace, len,
+                               pval, True);
+    else
+        dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8,
+                                PropModeReplace, len, pval, True);
+
     xfree(pval);
     return True;
 }
 
+static Bool
+XkbWriteRootWindowRulesProp(ClientPtr client, pointer closure)
+{
+    Bool rc;
+    XkbRMLVOSet *rmlvo = (XkbRMLVOSet*)closure;
+
+    rc = XkbWriteRulesProp(NULL, rmlvo);
+    XkbFreeRMLVOSet(rmlvo, TRUE);
+    return rc;
+}
+
 static void
 XkbSetRulesUsed(XkbRMLVOSet *rmlvo)
 {
@@ -237,7 +258,18 @@ XkbSetRulesUsed(XkbRMLVOSet *rmlvo)
 	_XkbFree(XkbOptionsUsed);
     XkbOptionsUsed= (rmlvo->options?_XkbDupString(rmlvo->options):NULL);
     if (XkbWantRulesProp)
-	QueueWorkProc(XkbWriteRulesProp,NULL,NULL);
+    {
+        XkbRMLVOSet* rmlvo_used = xcalloc(1, sizeof(XkbRMLVOSet));
+        if (rmlvo_used)
+        {
+            rmlvo_used->rules = _XkbDupString(XkbRulesUsed);
+            rmlvo_used->model = _XkbDupString(XkbModelUsed);
+            rmlvo_used->layout = _XkbDupString(XkbLayoutUsed);
+            rmlvo_used->variant = _XkbDupString(XkbVariantUsed);
+            rmlvo_used->options = _XkbDupString(XkbOptionsUsed);
+            QueueWorkProc(XkbWriteRootWindowRulesProp,NULL,rmlvo_used);
+        }
+    }
     return;
 }
 
@@ -614,6 +646,7 @@ InitKeyboardDeviceStruct(DeviceIntPtr dev, XkbRMLVOSet *rmlvo,
 
     XkbSetRulesDflts(rmlvo);
     XkbSetRulesUsed(rmlvo);
+    XkbWriteRulesProp(dev, rmlvo);
     XkbFreeRMLVOSet(&rmlvo_dflts, FALSE);
 
     return TRUE;
commit 44044adc92e6bb6537f48c84727523d5cb23528c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 30 11:39:50 2009 +1000

    xfree86: print a message if NIDR fails due to AutoAddDevices off.
    
    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 a035fca..3859741 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -620,12 +620,11 @@ NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev)
         /* Right now, the only automatic config we know of is HAL. */
         if (strcmp(option->key, "_source") == 0 &&
             strcmp(option->value, "server/hal") == 0) {
+            is_auto = 1;
             if (!xf86Info.autoAddDevices) {
                 rval = BadMatch;
                 goto unwind;
             }
-
-            is_auto = 1;
         }
     }
     if (!idev->driver || !idev->identifier) {
@@ -654,6 +653,8 @@ NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev)
         return Success;
 
 unwind:
+    if (is_auto && !xf86Info.autoAddDevices)
+        xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
     if(idev->driver)
         xfree(idev->driver);
     if(idev->identifier)
commit 43dbbc30327f826068bc7cd2cdaf870ed61b4522
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 28 21:01:36 2009 +1000

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

diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c
index 11c7679..de13256 100644
--- a/Xi/xigrabdev.c
+++ b/Xi/xigrabdev.c
@@ -68,7 +68,7 @@ ProcXIGrabDevice(ClientPtr client)
     GrabMask mask;
 
     REQUEST(xXIGrabDeviceReq);
-    REQUEST_AT_LEAST_SIZE(xXIGetDeviceFocusReq);
+    REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq);
 
     ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
     if (ret != Success)
commit 6a618929a0c06ba0d6dac13d7e644cd9658d98ed
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 28 16:49:45 2009 +1000

    input: reshuffle CreateGrab and friends to take a GrabParameters param.
    
    This is cleaning up work in preparation for XI2 passive grabs.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 164f071..0793113 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1349,36 +1349,34 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     }
 }
 
-static int
-CheckGrabValues(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
-                BYTE other_devices_mode, CARD16 modifiers, BOOL ownerEvents)
+int
+CheckGrabValues(ClientPtr client, GrabParameters* param)
 {
-    if ((this_device_mode != GrabModeSync) &&
-	(this_device_mode != GrabModeAsync)) {
-	client->errorValue = this_device_mode;
+    if ((param->this_device_mode != GrabModeSync) &&
+	(param->this_device_mode != GrabModeAsync)) {
+	client->errorValue = param->this_device_mode;
 	return BadValue;
     }
-    if ((other_devices_mode != GrabModeSync) &&
-	(other_devices_mode != GrabModeAsync)) {
-	client->errorValue = other_devices_mode;
+    if ((param->other_devices_mode != GrabModeSync) &&
+	(param->other_devices_mode != GrabModeAsync)) {
+	client->errorValue = param->other_devices_mode;
 	return BadValue;
     }
-    if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) {
-	client->errorValue = modifiers;
+    if ((param->modifiers != AnyModifier) && (param->modifiers & ~AllModifiersMask)) {
+	client->errorValue = param->modifiers;
 	return BadValue;
     }
-    if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) {
-	client->errorValue = ownerEvents;
+    if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) {
+	client->errorValue = param->ownerEvents;
 	return BadValue;
     }
     return Success;
 }
 
 int
-GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
-	   BYTE other_devices_mode, CARD16 modifiers,
-	   DeviceIntPtr modifier_device, CARD8 button, Window grabWindow,
-	   BOOL ownerEvents, Cursor rcursor, Window rconfineTo, Mask eventMask)
+GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
+           int button, GrabParameters *param, GrabType grabtype,
+	   GrabMask *mask)
 {
     WindowPtr pWin, confineTo;
     CursorPtr cursor;
@@ -1386,53 +1384,48 @@ GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
     int rc;
     Mask access_mode = DixGrabAccess;
 
-    rc = CheckGrabValues(client, dev, this_device_mode, other_devices_mode,
-                         modifiers, ownerEvents);
+    rc = CheckGrabValues(client, param);
     if (rc != Success)
 	return rc;
-    if (rconfineTo == None)
+    if (param->confineTo == None)
 	confineTo = NullWindow;
     else {
-	rc = dixLookupWindow(&confineTo, rconfineTo, client, DixSetAttrAccess);
+	rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess);
 	if (rc != Success)
 	    return rc;
     }
-    if (rcursor == None)
+    if (param->cursor == None)
 	cursor = NullCursor;
     else {
-	rc = dixLookupResourceByType((pointer *)&cursor, rcursor, RT_CURSOR,
-			       client, DixUseAccess);
+	rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
+				     RT_CURSOR, client, DixUseAccess);
 	if (rc != Success)
 	{
-	    client->errorValue = rcursor;
+	    client->errorValue = param->cursor;
 	    return (rc == BadValue) ? BadCursor : rc;
 	}
 	access_mode |= DixForceAccess;
     }
-    if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync)
+    if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
 	access_mode |= DixFreezeAccess;
     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
     if (rc != Success)
 	return rc;
-    rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
+    rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
     if (rc != Success)
 	return rc;
 
 
-    grab = CreateGrab(client->index, dev, pWin, eventMask,
-		      (Bool) ownerEvents, (Bool) this_device_mode,
-		      (Bool) other_devices_mode, modifier_device, modifiers,
-		      DeviceButtonPress, GRABTYPE_XI, button, confineTo, cursor);
+    grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
+                      mask, param, DeviceButtonPress, button, confineTo, cursor);
     if (!grab)
 	return BadAlloc;
     return AddPassiveGrabToList(client, grab);
 }
 
 int
-GrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
-	BYTE other_devices_mode, CARD16 modifiers,
-	DeviceIntPtr modifier_device, CARD8 key, Window grabWindow,
-	BOOL ownerEvents, Mask mask)
+GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
+        int key, GrabParameters *param, GrabType grabtype, GrabMask *mask)
 {
     WindowPtr pWin;
     GrabPtr grab;
@@ -1440,8 +1433,7 @@ GrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
     Mask access_mode = DixGrabAccess;
     int rc;
 
-    rc = CheckGrabValues(client, dev, this_device_mode, other_devices_mode,
-                         modifiers, ownerEvents);
+    rc = CheckGrabValues(client, param);
     if (rc != Success)
         return rc;
     if (k == NULL)
@@ -1452,19 +1444,17 @@ GrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
 	client->errorValue = key;
         return BadValue;
     }
-    rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
+    rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
     if (rc != Success)
 	return rc;
-    if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync)
+    if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
 	access_mode |= DixFreezeAccess;
     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
     if (rc != Success)
 	return rc;
 
-    grab = CreateGrab(client->index, dev, pWin,
-		      mask, ownerEvents, this_device_mode, other_devices_mode,
-		      modifier_device, modifiers, DeviceKeyPress, GRABTYPE_XI,
-		      key, NullWindow, NullCursor);
+    grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
+                      mask, param, DeviceKeyPress, key, NULL, NULL);
     if (!grab)
 	return BadAlloc;
     return AddPassiveGrabToList(client, grab);
diff --git a/Xi/grabdevb.c b/Xi/grabdevb.c
index 61ced48..0d1eb63 100644
--- a/Xi/grabdevb.c
+++ b/Xi/grabdevb.c
@@ -103,6 +103,8 @@ ProcXGrabDeviceButton(ClientPtr client)
     DeviceIntPtr mdev;
     XEventClass *class;
     struct tmask tmp[EMASKSIZE];
+    GrabParameters param;
+    GrabMask mask;
 
     REQUEST(xGrabDeviceButtonReq);
     REQUEST_AT_LEAST_SIZE(xGrabDeviceButtonReq);
@@ -135,10 +137,17 @@ ProcXGrabDeviceButton(ClientPtr client)
 				  stuff->event_count, tmp, dev,
 				  X_GrabDeviceButton)) != Success)
 	return ret;
-    ret = GrabButton(client, dev, stuff->this_device_mode,
-		     stuff->other_devices_mode, stuff->modifiers, mdev,
-		     stuff->button, stuff->grabWindow, stuff->ownerEvents,
-		     (Cursor) 0, (Window) 0, tmp[stuff->grabbed_device].mask);
+
+    memset(&param, 0, sizeof(param));
+    param.ownerEvents = stuff->ownerEvents;
+    param.this_device_mode = stuff->this_device_mode;
+    param.other_devices_mode = stuff->other_devices_mode;
+    param.grabWindow = stuff->grabWindow;
+    param.modifiers = stuff->modifiers;
+    mask.xi = tmp[stuff->grabbed_device].mask;
+
+    ret = GrabButton(client, dev, mdev, stuff->button, &param,
+                     GRABTYPE_XI, &mask);
 
     return ret;
 }
diff --git a/Xi/grabdevk.c b/Xi/grabdevk.c
index aefe11b..96e2e62 100644
--- a/Xi/grabdevk.c
+++ b/Xi/grabdevk.c
@@ -101,6 +101,8 @@ ProcXGrabDeviceKey(ClientPtr client)
     DeviceIntPtr mdev;
     XEventClass *class;
     struct tmask tmp[EMASKSIZE];
+    GrabParameters param;
+    GrabMask mask;
 
     REQUEST(xGrabDeviceKeyReq);
     REQUEST_AT_LEAST_SIZE(xGrabDeviceKeyReq);
@@ -133,10 +135,16 @@ ProcXGrabDeviceKey(ClientPtr client)
 				  X_GrabDeviceKey)) != Success)
 	return ret;
 
-    ret = GrabKey(client, dev, stuff->this_device_mode,
-		  stuff->other_devices_mode, stuff->modifiers, mdev,
-		  stuff->key, stuff->grabWindow, stuff->ownerEvents,
-		  tmp[stuff->grabbed_device].mask);
+
+    memset(&param, 0, sizeof(param));
+    param.ownerEvents = stuff->ownerEvents;
+    param.this_device_mode = stuff->this_device_mode;
+    param.other_devices_mode = stuff->other_devices_mode;
+    param.grabWindow = stuff->grabWindow;
+    param.modifiers = stuff->modifiers;
+    mask.xi = tmp[stuff->grabbed_device].mask;
+
+    ret = GrabKey(client, dev, mdev, stuff->key, &param, GRABTYPE_XI, &mask);
 
     return ret;
 }
diff --git a/dix/events.c b/dix/events.c
index c87a361..6fe2182 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -5022,25 +5022,21 @@ ProcGrabKey(ClientPtr client)
     GrabPtr grab;
     DeviceIntPtr keybd = PickKeyboard(client);
     int rc;
+    GrabParameters param;
+    GrabMask mask;
 
     REQUEST_SIZE_MATCH(xGrabKeyReq);
-    if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
-    {
-	client->errorValue = stuff->ownerEvents;
-	return(BadValue);
-    }
-    if ((stuff->pointerMode != GrabModeSync) &&
-	(stuff->pointerMode != GrabModeAsync))
-    {
-	client->errorValue = stuff->pointerMode;
-        return BadValue;
-    }
-    if ((stuff->keyboardMode != GrabModeSync) &&
-	(stuff->keyboardMode != GrabModeAsync))
-    {
-	client->errorValue = stuff->keyboardMode;
-        return BadValue;
-    }
+
+    memset(&param, 0, sizeof(param));
+    param.ownerEvents = stuff->ownerEvents;
+    param.this_device_mode = stuff->keyboardMode;
+    param.other_devices_mode = stuff->pointerMode;
+    param.modifiers = stuff->modifiers;
+
+    rc = CheckGrabValues(client, &param);
+    if (rc != Success)
+        return rc;
+
     if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) ||
 	 (stuff->key < keybd->key->xkbInfo->desc->min_key_code))
 	&& (stuff->key != AnyKey))
@@ -5048,21 +5044,15 @@ ProcGrabKey(ClientPtr client)
 	client->errorValue = stuff->key;
         return BadValue;
     }
-    if ((stuff->modifiers != AnyModifier) &&
-	(stuff->modifiers & ~AllModifiersMask))
-    {
-	client->errorValue = stuff->modifiers;
-	return BadValue;
-    }
     rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess);
     if (rc != Success)
 	return rc;
 
-    grab = CreateGrab(client->index, keybd, pWin,
-	(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
-	(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
-	keybd, stuff->modifiers, KeyPress, GRABTYPE_CORE, stuff->key,
-	NullWindow, NullCursor);
+
+    mask.core = (KeyPressMask | KeyReleaseMask);
+
+    grab = CreateGrab(client->index, keybd, keybd, pWin, GRABTYPE_CORE, &mask,
+                      &param, KeyPress, stuff->key, NullWindow, NullCursor);
     if (!grab)
 	return BadAlloc;
     return AddPassiveGrabToList(client, grab);
@@ -5084,6 +5074,8 @@ ProcGrabButton(ClientPtr client)
     GrabPtr grab;
     DeviceIntPtr ptr, modifierDevice;
     Mask access_mode = DixGrabAccess;
+    GrabMask mask;
+    GrabParameters param;
     int rc;
 
     REQUEST_SIZE_MATCH(xGrabButtonReq);
@@ -5150,11 +5142,17 @@ ProcGrabButton(ClientPtr client)
     if (rc != Success)
 	return rc;
 
-    grab = CreateGrab(client->index, ptr, pWin,
-        (Mask)stuff->eventMask, (Bool)stuff->ownerEvents,
-        (Bool) stuff->keyboardMode, (Bool)stuff->pointerMode,
-        modifierDevice, stuff->modifiers, ButtonPress, GRABTYPE_CORE,
-        stuff->button, confineTo, cursor);
+    memset(&param, 0, sizeof(param));
+    param.ownerEvents = stuff->ownerEvents;
+    param.this_device_mode = stuff->keyboardMode;
+    param.other_devices_mode = stuff->pointerMode;
+    param.modifiers = stuff->modifiers;
+
+    mask.core = stuff->eventMask;
+
+    grab = CreateGrab(client->index, ptr, modifierDevice, pWin,
+                      GRABTYPE_CORE, &mask, &param, ButtonPress,
+                      stuff->button, confineTo, cursor);
     if (!grab)
 	return BadAlloc;
     return AddPassiveGrabToList(client, grab);
diff --git a/dix/grabs.c b/dix/grabs.c
index cd34f7e..06e1ebb 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -58,6 +58,7 @@ SOFTWARE.
 #include "cursorstr.h"
 #include "dixgrabs.h"
 #include "xace.h"
+#include "exevents.h"
 
 #define BITMASK(i) (((Mask)1) << ((i) & 31))
 #define MASKIDX(i) ((i) >> 5)
@@ -70,13 +71,12 @@ GrabPtr
 CreateGrab(
     int client,
     DeviceIntPtr device,
-    WindowPtr window,
-    Mask eventMask,
-    Bool ownerEvents, Bool keyboardMode, Bool pointerMode,
     DeviceIntPtr modDevice,
-    unsigned short modifiers,
+    WindowPtr window,
+    GrabType grabtype,
+    GrabMask *mask,
+    GrabParameters *param,
     int type,
-    int grabtype,
     KeyCode keybut,	/* key or button */
     WindowPtr confineTo,
     CursorPtr cursor)
@@ -89,12 +89,12 @@ CreateGrab(
     grab->resource = FakeClientID(client);
     grab->device = device;
     grab->window = window;
-    grab->eventMask = eventMask;
+    grab->eventMask = mask->core; /* same for XI */
     grab->deviceMask = 0;
-    grab->ownerEvents = ownerEvents;
-    grab->keyboardMode = keyboardMode;
-    grab->pointerMode = pointerMode;
-    grab->modifiersDetail.exact = modifiers;
+    grab->ownerEvents = param->ownerEvents;
+    grab->keyboardMode = param->this_device_mode;
+    grab->pointerMode = param->other_devices_mode;
+    grab->modifiersDetail.exact = param->modifiers;
     grab->modifiersDetail.pMask = NULL;
     grab->modifierDevice = modDevice;
     grab->type = type;
@@ -434,17 +434,21 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
 		 && (pMinuendGrab->modifiersDetail.exact != AnyModifier))
 	{
 	    GrabPtr pNewGrab;
+            GrabParameters param;
 
 	    UPDATE(grab->detail.pMask, pMinuendGrab->detail.exact);
 
+            memset(&param, 0, sizeof(param));
+            param.ownerEvents = grab->ownerEvents;
+            param.this_device_mode = grab->keyboardMode;
+            param.other_devices_mode = grab->pointerMode;
+            param.modifiers = AnyModifier;
+
 	    pNewGrab = CreateGrab(CLIENT_ID(grab->resource), grab->device,
-				  grab->window, (Mask)grab->eventMask,
-				  (Bool)grab->ownerEvents,
-				  (Bool)grab->keyboardMode,
-				  (Bool)grab->pointerMode,
-				  grab->modifierDevice,
-				  AnyModifier, (int)grab->type,
+				  grab->modifierDevice, grab->window,
                                   grab->grabtype,
+				  (GrabMask*)grab->eventMask,
+                                  &param, (int)grab->type,
 				  pMinuendGrab->detail.exact,
 				  grab->confineTo, grab->cursor);
 	    if (!pNewGrab)
diff --git a/include/dixgrabs.h b/include/dixgrabs.h
index 5127239..3b2a46d 100644
--- a/include/dixgrabs.h
+++ b/include/dixgrabs.h
@@ -26,21 +26,20 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #ifndef DIXGRABS_H
 #define DIXGRABS_H 1
 
-extern _X_EXPORT GrabPtr CreateGrab(
+struct _GrabParameters;
+
+extern GrabPtr CreateGrab(
 	int /* client */,
 	DeviceIntPtr /* device */,
-	WindowPtr /* window */,
-	Mask /* eventMask */,
-	Bool /* ownerEvents */,
-	Bool /* keyboardMode */,
-	Bool /* pointerMode */,
 	DeviceIntPtr /* modDevice */,
-	unsigned short /* modifiers */,
+	WindowPtr /* window */,
+        GrabType /* grabtype */,
+        GrabMask * /* mask */,
+        struct _GrabParameters * /* param */,
 	int /* type */,
-	int /* grabtype */,
 	KeyCode /* keybut */,
-	WindowPtr /* confineTo */,
-	CursorPtr /* cursor */);
+        WindowPtr /* confineTo */,
+        CursorPtr /* cursor */);
 
 extern _X_EXPORT int DeletePassiveGrab(
 	pointer /* value */,
diff --git a/include/exevents.h b/include/exevents.h
index fc1c23f..95d08cc 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -42,6 +42,18 @@ typedef struct _XIClientRec {
         int minor_version;
 } XIClientRec, *XIClientPtr;
 
+
+typedef struct _GrabParameters {
+    unsigned int        ownerEvents;
+    unsigned int        this_device_mode;
+    unsigned int        other_devices_mode;
+    Window              grabWindow;
+    Window              confineTo;
+    Cursor              cursor;
+    unsigned int        modifiers;
+} GrabParameters;
+
+
 extern _X_EXPORT void RegisterOtherDevice (
 	DeviceIntPtr           /* device */);
 
@@ -73,31 +85,27 @@ extern _X_EXPORT void DeviceFocusEvent(
 	int                    /* detail */,
 	WindowPtr              /* pWin */);
 
-extern _X_EXPORT int GrabButton(
+extern int CheckGrabValues(
+        ClientPtr              /* client */,
+        GrabParameters*        /* param */);
+
+extern int GrabButton(
 	ClientPtr              /* client */,
 	DeviceIntPtr           /* dev */,
-	BYTE                   /* this_device_mode */,
-	BYTE                   /* other_devices_mode */,
-	CARD16                 /* modifiers */,
 	DeviceIntPtr           /* modifier_device */,
-	CARD8                  /* button */,
-	Window                 /* grabWindow */,
-	BOOL                   /* ownerEvents */,
-	Cursor                 /* rcursor */,
-	Window                 /* rconfineTo */,
-	Mask                   /* eventMask */);
-
-extern _X_EXPORT int GrabKey(
+	int                    /* button */,
+        GrabParameters*        /* param */,
+        GrabType               /* grabtype */,
+	GrabMask*              /* eventMask */);
+
+extern int GrabKey(
 	ClientPtr              /* client */,
 	DeviceIntPtr           /* dev */,
-	BYTE                   /* this_device_mode */,
-	BYTE                   /* other_devices_mode */,
-	CARD16                 /* modifiers */,
 	DeviceIntPtr           /* modifier_device */,
-	CARD8                  /* key */,
-	Window                 /* grabWindow */,
-	BOOL                   /* ownerEvents */,
-	Mask                   /* mask */);
+	int                    /* key */,
+        GrabParameters*        /* param */,
+        GrabType               /* grabtype */,
+	GrabMask*              /* eventMask */);
 
 extern int SelectForWindow(
 	DeviceIntPtr           /* dev */,
diff --git a/test/input.c b/test/input.c
index eb0543e..a9027f0 100644
--- a/test/input.c
+++ b/test/input.c
@@ -33,6 +33,7 @@
 #include "windowstr.h"
 #include "inputstr.h"
 #include "eventconvert.h"
+#include "exevents.h"
 
 #include <glib.h>
 
@@ -73,6 +74,66 @@ static void dix_init_valuators(void)
     g_assert(dev.last.numValuators == num_axes);
 }
 
+/* just check the known success cases, and that error cases set the client's
+ * error value correctly. */
+static void dix_check_grab_values(void)
+{
+    ClientRec client;
+    GrabParameters param;
+    int rc;
+
+    memset(&client, 0, sizeof(client));
+
+    param.this_device_mode = GrabModeSync;
+    param.other_devices_mode = GrabModeSync;
+    param.modifiers = AnyModifier;
+    param.ownerEvents = FALSE;
+
+    rc = CheckGrabValues(&client, &param);
+    g_assert(rc == Success);
+
+    param.this_device_mode = GrabModeAsync;
+    rc = CheckGrabValues(&client, &param);
+    g_assert(rc == Success);
+
+    param.this_device_mode = GrabModeAsync + 1;
+    rc = CheckGrabValues(&client, &param);
+    g_assert(rc == BadValue);
+    g_assert(client.errorValue == param.this_device_mode);
+    g_assert(client.errorValue == GrabModeAsync + 1);
+
+    param.this_device_mode = GrabModeSync;
+    param.other_devices_mode = GrabModeAsync;
+    rc = CheckGrabValues(&client, &param);
+    g_assert(rc == Success);
+
+    param.other_devices_mode = GrabModeAsync + 1;
+    rc = CheckGrabValues(&client, &param);
+    g_assert(rc == BadValue);
+    g_assert(client.errorValue == param.other_devices_mode);
+    g_assert(client.errorValue == GrabModeAsync + 1);
+
+    param.other_devices_mode = GrabModeSync;
+
+    param.modifiers = 1 << 13;
+    rc = CheckGrabValues(&client, &param);
+    g_assert(rc == BadValue);
+    g_assert(client.errorValue == param.modifiers);
+    g_assert(client.errorValue == (1 << 13));
+
+
+    param.modifiers = AnyModifier;
+    param.ownerEvents = TRUE;
+    rc = CheckGrabValues(&client, &param);
+    g_assert(rc == Success);
+
+    param.ownerEvents = 3;
+    rc = CheckGrabValues(&client, &param);
+    g_assert(rc == BadValue);
+    g_assert(client.errorValue == param.ownerEvents);
+    g_assert(client.errorValue == 3);
+}
+
 
 /**
  * Convert various internal events to the matching core event and verify the
@@ -222,6 +283,7 @@ int main(int argc, char** argv)
 
     g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
     g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
+    g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
 
     return g_test_run();
 }
commit e8e26f700c9c70d3f1bb53bdb71d1100f5c43a69
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 26 21:43:25 2009 +1000

    Xi: split some grab parameter checking out of GrabButton and GrabKey.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index ed6a3ed..164f071 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1349,18 +1349,10 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     }
 }
 
-int
-GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
-	   BYTE other_devices_mode, CARD16 modifiers,
-	   DeviceIntPtr modifier_device, CARD8 button, Window grabWindow,
-	   BOOL ownerEvents, Cursor rcursor, Window rconfineTo, Mask eventMask)
+static int
+CheckGrabValues(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
+                BYTE other_devices_mode, CARD16 modifiers, BOOL ownerEvents)
 {
-    WindowPtr pWin, confineTo;
-    CursorPtr cursor;
-    GrabPtr grab;
-    Mask access_mode = DixGrabAccess;
-    int rc;
-
     if ((this_device_mode != GrabModeSync) &&
 	(this_device_mode != GrabModeAsync)) {
 	client->errorValue = this_device_mode;
@@ -1379,7 +1371,23 @@ GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
 	client->errorValue = ownerEvents;
 	return BadValue;
     }
-    rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
+    return Success;
+}
+
+int
+GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
+	   BYTE other_devices_mode, CARD16 modifiers,
+	   DeviceIntPtr modifier_device, CARD8 button, Window grabWindow,
+	   BOOL ownerEvents, Cursor rcursor, Window rconfineTo, Mask eventMask)
+{
+    WindowPtr pWin, confineTo;
+    CursorPtr cursor;
+    GrabPtr grab;
+    int rc;
+    Mask access_mode = DixGrabAccess;
+
+    rc = CheckGrabValues(client, dev, this_device_mode, other_devices_mode,
+                         modifiers, ownerEvents);
     if (rc != Success)
 	return rc;
     if (rconfineTo == None)
@@ -1406,6 +1414,10 @@ GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
     if (rc != Success)
 	return rc;
+    rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
+    if (rc != Success)
+	return rc;
+
 
     grab = CreateGrab(client->index, dev, pWin, eventMask,
 		      (Bool) ownerEvents, (Bool) this_device_mode,
@@ -1428,32 +1440,18 @@ GrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
     Mask access_mode = DixGrabAccess;
     int rc;
 
+    rc = CheckGrabValues(client, dev, this_device_mode, other_devices_mode,
+                         modifiers, ownerEvents);
+    if (rc != Success)
+        return rc;
     if (k == NULL)
 	return BadMatch;
-    if ((other_devices_mode != GrabModeSync) &&
-	(other_devices_mode != GrabModeAsync)) {
-	client->errorValue = other_devices_mode;
-	return BadValue;
-    }
-    if ((this_device_mode != GrabModeSync) &&
-	(this_device_mode != GrabModeAsync)) {
-	client->errorValue = this_device_mode;
-	return BadValue;
-    }
     if ((key > k->xkbInfo->desc->max_key_code ||
          key < k->xkbInfo->desc->min_key_code)
 	&& (key != AnyKey)) {
 	client->errorValue = key;
         return BadValue;
     }
-    if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) {
-	client->errorValue = modifiers;
-	return BadValue;
-    }
-    if ((ownerEvents != xTrue) && (ownerEvents != xFalse)) {
-	client->errorValue = ownerEvents;
-	return BadValue;
-    }
     rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
     if (rc != Success)
 	return rc;
commit 98a1fa994158feca8bc80a10296a7675465c0e56
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 21 22:18:23 2009 +1000

    test: add InternalEvent to core event conversion tests.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/input.c b/test/input.c
index bcb4c57..eb0543e 100644
--- a/test/input.c
+++ b/test/input.c
@@ -32,6 +32,7 @@
 #include <X11/Xatom.h>
 #include "windowstr.h"
 #include "inputstr.h"
+#include "eventconvert.h"
 
 #include <glib.h>
 
@@ -72,12 +73,155 @@ static void dix_init_valuators(void)
     g_assert(dev.last.numValuators == num_axes);
 }
 
+
+/**
+ * Convert various internal events to the matching core event and verify the
+ * parameters.
+ */
+static void dix_event_to_core(int type)
+{
+    DeviceEvent ev;
+    xEvent core;
+    int time;
+    int x, y;
+    int rc;
+    int state;
+    int detail;
+
+    /* EventToCore memsets the event to 0 */
+#define test_event() \
+    g_assert(rc == Success); \
+    g_assert(core.u.u.type == type); \
+    g_assert(core.u.u.detail == detail); \
+    g_assert(core.u.keyButtonPointer.time == time); \
+    g_assert(core.u.keyButtonPointer.rootX == x); \
+    g_assert(core.u.keyButtonPointer.rootY == y); \
+    g_assert(core.u.keyButtonPointer.state == state); \
+    g_assert(core.u.keyButtonPointer.eventX == 0); \
+    g_assert(core.u.keyButtonPointer.eventY == 0); \
+    g_assert(core.u.keyButtonPointer.root == 0); \
+    g_assert(core.u.keyButtonPointer.event == 0); \
+    g_assert(core.u.keyButtonPointer.child == 0); \
+    g_assert(core.u.keyButtonPointer.sameScreen == FALSE);
+
+    x = 0;
+    y = 0;
+    time = 12345;
+    state = 0;
+    detail = 0;
+
+    ev.header   = 0xFF;
+    ev.length   = sizeof(DeviceEvent);
+    ev.time     = time;
+    ev.root_y   = x;
+    ev.root_x   = y;
+    ev.corestate = state;
+    ev.detail.key = detail;
+
+    ev.type = type;
+    ev.detail.key = 0;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    test_event();
+
+    x = 1;
+    y = 2;
+    ev.root_x = x;
+    ev.root_y = y;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    test_event();
+
+    x = 0x7FFF;
+    y = 0x7FFF;
+    ev.root_x = x;
+    ev.root_y = y;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    test_event();
+
+    x = 0x8000; /* too high */
+    y = 0x8000; /* too high */
+    ev.root_x = x;
+    ev.root_y = y;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    g_assert(core.u.keyButtonPointer.rootX != x);
+    g_assert(core.u.keyButtonPointer.rootY != y);
+
+    x = 0x7FFF;
+    y = 0x7FFF;
+    ev.root_x = x;
+    ev.root_y = y;
+    time = 0;
+    ev.time = time;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    test_event();
+
+    detail = 1;
+    ev.detail.key = detail;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    test_event();
+
+    detail = 0xFF; /* highest value */
+    ev.detail.key = detail;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    test_event();
+
+    detail = 0xFFF; /* too big */
+    ev.detail.key = detail;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    g_assert(rc == BadMatch);
+
+    detail = 0xFF; /* too big */
+    ev.detail.key = detail;
+    state = 0xFFFF; /* highest value */
+    ev.corestate = state;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    test_event();
+
+    state = 0x10000; /* too big */
+    ev.corestate = state;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    g_assert(core.u.keyButtonPointer.state != state);
+    g_assert(core.u.keyButtonPointer.state == (state & 0xFFFF));
+
+#undef test_event
+}
+
+static void dix_event_to_core_conversion(void)
+{
+    DeviceEvent ev;
+    xEvent core;
+    int rc;
+
+    ev.header   = 0xFF;
+    ev.length   = sizeof(DeviceEvent);
+
+    ev.type     = 0;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    g_assert(rc == BadImplementation);
+
+    ev.type     = 1;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    g_assert(rc == BadImplementation);
+
+    ev.type     = ET_ProximityOut + 1;
+    rc = EventToCore((InternalEvent*)&ev, &core);
+    g_assert(rc == BadImplementation);
+
+    dix_event_to_core(ET_KeyPress);
+    dix_event_to_core(ET_KeyRelease);
+    dix_event_to_core(ET_ButtonPress);
+    dix_event_to_core(ET_ButtonRelease);
+    dix_event_to_core(ET_Motion);
+    dix_event_to_core(ET_ProximityIn);
+    dix_event_to_core(ET_ProximityOut);
+}
+
 int main(int argc, char** argv)
 {
     g_test_init(&argc, &argv,NULL);
     g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
 
     g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
+    g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
 
     return g_test_run();
 }
commit 990e8362a76fadc173e890d9052a2e5274b6eac5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 16 11:41:58 2009 +1000

    test: add a simple test to verify device axis intialization.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/Makefile.am b/test/Makefile.am
index 5b1daac..dbad93b 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,5 +1,5 @@
 if UNITTESTS
-check_PROGRAMS = xkb
+check_PROGRAMS = xkb input
 check_LTLIBRARIES = libxservertest.la
 
 TESTS=$(check_PROGRAMS)
@@ -9,7 +9,7 @@ INCLUDES = @XORG_INCS@
 TEST_LDADD=libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) $(GLIB_LIBS)
 
 xkb_LDADD=$(TEST_LDADD)
-
+input_LDADD=$(TEST_LDADD)
 
 libxservertest_la_LIBADD = \
             $(XSERVER_LIBS) \
diff --git a/test/input.c b/test/input.c
new file mode 100644
index 0000000..bcb4c57
--- /dev/null
+++ b/test/input.c
@@ -0,0 +1,83 @@
+/**
+ * Copyright © 2009 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 <X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include "windowstr.h"
+#include "inputstr.h"
+
+#include <glib.h>
+
+/**
+ * Init a device with axes.
+ * Verify values set on the device.
+ *
+ * Result: All axes set to default values (usually 0).
+ */
+static void dix_init_valuators(void)
+{
+    DeviceIntRec dev;
+    ValuatorClassPtr val;
+    const int num_axes = 2;
+    int i;
+
+
+    memset(&dev, 0, sizeof(DeviceIntRec));
+    dev.isMaster = TRUE; /* claim it's a master to stop ptracccel */
+
+    g_assert(InitValuatorClassDeviceStruct(NULL, 0, 0, 0) == FALSE);
+    g_assert(InitValuatorClassDeviceStruct(&dev, num_axes, 0, Absolute));
+
+    val = dev.valuator;
+    g_assert(val);
+    g_assert(val->numAxes == num_axes);
+    g_assert(val->numMotionEvents == 0);
+    g_assert(val->mode == Absolute);
+    g_assert(val->axisVal);
+
+    for (i = 0; i < num_axes; i++)
+    {
+        g_assert(val->axisVal[i] == 0);
+        g_assert(val->axes->min_value == NO_AXIS_LIMITS);
+        g_assert(val->axes->max_value == NO_AXIS_LIMITS);
+    }
+
+    g_assert(dev.last.numValuators == num_axes);
+}
+
+int main(int argc, char** argv)
+{
+    g_test_init(&argc, &argv,NULL);
+    g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
+
+    g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
+
+    return g_test_run();
+}
commit 4eac0df060b897470fb01cfd3b70f500da757c74
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 15 17:21:08 2009 +1000

    Add a test-suite for in-server unit-testing.
    
    This patch adds a test/ directory that contains the setup for a unit-testing
    suite designed for in-server unit-testing. All functions available to the X
    server are available to the test binaries through static linking.
    
    This test suite uses the glib testing framework.
    Do not use glib calls outside of the test/ directory.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index d907e88..d95b2e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -439,6 +439,9 @@ AC_ARG_ENABLE(werror,        AS_HELP_STRING([--enable-werror],
 AC_ARG_ENABLE(debug,         AS_HELP_STRING([--enable-debug],
 				  [Enable debugging (default: disabled)]),
 			        [DEBUGGING=$enableval], [DEBUGGING=no])
+AC_ARG_ENABLE(unit-tests,    AS_HELP_STRING([--enable-unit-tests],
+                                  [Enable unit-tests (default: enabled)]),
+                                [UNITTESTS=$enableval], [UNITTESTS=yes])
 AC_ARG_WITH(int10,           AS_HELP_STRING([--with-int10=BACKEND], [int10 backend: vm86, x86emu or stub]),
 				[INT10="$withval"],
 				[INT10="$DEFAULT_INT10"])
@@ -1141,6 +1144,14 @@ if test "x$DEBUGGING" = xyes; then
 fi
 AM_CONDITIONAL(DEBUG, [test "x$DEBUGGING" = xyes])
 
+if test "x$UNITTESTS" = xyes; then
+       AC_DEFINE(UNITTESTS, 1, [Enable unit tests])
+       PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.16])
+       AC_SUBST([GLIB_LIBS])
+       AC_SUBST([GLIB_CFLAGS])
+fi
+AM_CONDITIONAL(UNITTESTS, [test "x$UNITTESTS" = xyes])
+
 AC_DEFINE(XTEST, 1, [Support XTest extension])
 AC_DEFINE(XSYNC, 1, [Support XSync extension])
 AC_DEFINE(XCMISC, 1, [Support XCMisc extension])
@@ -1980,5 +1991,6 @@ hw/kdrive/fbdev/Makefile
 hw/kdrive/linux/Makefile
 hw/kdrive/sdl/Makefile
 hw/kdrive/src/Makefile
+test/Makefile
 xorg-server.pc
 ])
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..5b1daac
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,39 @@
+if UNITTESTS
+check_PROGRAMS = xkb
+check_LTLIBRARIES = libxservertest.la
+
+TESTS=$(check_PROGRAMS)
+
+AM_CFLAGS = $(DIX_CFLAGS) $(GLIB_CFLAGS) @XORG_CFLAGS@
+INCLUDES = @XORG_INCS@
+TEST_LDADD=libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) $(GLIB_LIBS)
+
+xkb_LDADD=$(TEST_LDADD)
+
+
+libxservertest_la_LIBADD = \
+            $(XSERVER_LIBS) \
+            $(top_builddir)/hw/xfree86/loader/libloader.la \
+            $(top_builddir)/hw/xfree86/os-support/libxorgos.la \
+            $(top_builddir)/hw/xfree86/common/libcommon.la \
+            $(top_builddir)/hw/xfree86/parser/libxf86config.la \
+            $(top_builddir)/hw/xfree86/dixmods/libdixmods.la \
+            $(top_builddir)/hw/xfree86/modes/libxf86modes.la \
+            $(top_builddir)/hw/xfree86/ramdac/libramdac.la \
+            $(top_builddir)/hw/xfree86/ddc/libddc.la \
+            $(top_builddir)/hw/xfree86/i2c/libi2c.la \
+            $(top_builddir)/hw/xfree86/dixmods/libxorgxkb.la \
+            $(top_builddir)/hw/xfree86/libxorg.la \
+            $(top_builddir)/mi/libmi.la \
+            $(top_builddir)/os/libos.la \
+            @XORG_LIBS@
+
+CLEANFILES=libxservertest.c
+
+libxservertest.c:
+	touch $@
+
+all:
+	@echo "Run 'make check' to run the test suite"
+
+endif
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..5759a72
--- /dev/null
+++ b/test/README
@@ -0,0 +1,36 @@
+                        X server test suite
+
+This suite contains a set of tests to verify the behaviour of functions used
+internally to the server. This test suite is based on glib's testing
+framework [1].
+
+= How it works =
+Through some automake abuse, we link the test programs with the same static
+libraries as the Xorg binary. The test suites can then call various functions
+and verify their behaviour - without the need to start the server or connect
+clients.
+
+This testing only works for functions that do not rely on a particular state
+of the X server. Unless the test suite replicates the expected state, which
+may be difficult.
+
+= How to run the tests =
+Run "make check" the test directory. This will compile the tests and execute
+them in the order specified in the TESTS variable in test/Makefile.am.
+
+Each set of tests related to a subsystem are available as a binary that can be
+executed directly. For example, run "xkb" to perform some xkb-related tests.
+
+== Adding a new test ==
+When adding a new test, ensure that you add a short description of what the
+test does and what the expected outcome is. If the test reproduces a
+particular bug, using g_test_bug().
+
+== Misc ==
+
+The programs "gtester" and "gtester-report" may be used to generate XML/HTML
+log files of tests succeeded and failed.
+
+---------
+
+[1] http://library.gnome.org/devel/glib/stable/glib-Testing.html
diff --git a/test/xkb.c b/test/xkb.c
new file mode 100644
index 0000000..6fbb26a
--- /dev/null
+++ b/test/xkb.c
@@ -0,0 +1,173 @@
+/**
+ * Copyright © 2009 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 <xkb-config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "opaque.h"
+#include "property.h"
+#define	XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+#include "../xkb/xkbgeom.h"
+#include <X11/extensions/XKMformat.h>
+#include "xkbfile.h"
+#include "../xkb/xkb.h"
+
+#include <glib.h>
+
+/**
+ * Initialize an empty XkbRMLVOSet.
+ * Call XkbGetRulesDflts to obtain the default ruleset.
+ * Compare obtained ruleset with the built-in defaults.
+ *
+ * Result: RMLVO defaults are the same as obtained.
+ */
+static void xkb_get_rules_test(void)
+{
+    XkbRMLVOSet rmlvo = { NULL};
+    XkbGetRulesDflts(&rmlvo);
+
+
+    g_assert(rmlvo.rules);
+    g_assert(rmlvo.model);
+    g_assert(rmlvo.layout);
+    g_assert(rmlvo.variant);
+    g_assert(rmlvo.options);
+    g_assert(strcmp(rmlvo.rules, XKB_DFLT_RULES) == 0);
+    g_assert(strcmp(rmlvo.model, XKB_DFLT_MODEL) == 0);
+    g_assert(strcmp(rmlvo.layout, XKB_DFLT_LAYOUT) == 0);
+    g_assert(strcmp(rmlvo.variant, XKB_DFLT_VARIANT) == 0);
+    g_assert(strcmp(rmlvo.options, XKB_DFLT_OPTIONS) == 0);
+}
+
+/**
+ * Initialize an random XkbRMLVOSet.
+ * Call XkbGetRulesDflts to obtain the default ruleset.
+ * Compare obtained ruleset with the built-in defaults.
+ * Result: RMLVO defaults are the same as obtained.
+ */
+static void xkb_set_rules_test(void)
+{
+    XkbRMLVOSet rmlvo = {
+        .rules = "test-rules",
+        .model = "test-model",
+        .layout = "test-layout",
+        .variant = "test-variant",
+        .options = "test-options"
+    };
+    XkbRMLVOSet rmlvo_new = { NULL };
+
+    XkbSetRulesDflts(&rmlvo);
+    XkbGetRulesDflts(&rmlvo_new);
+
+    /* XkbGetRulesDflts strdups the values */
+    g_assert(rmlvo.rules != rmlvo_new.rules);
+    g_assert(rmlvo.model != rmlvo_new.model);
+    g_assert(rmlvo.layout != rmlvo_new.layout);
+    g_assert(rmlvo.variant != rmlvo_new.variant);
+    g_assert(rmlvo.options != rmlvo_new.options);
+
+    g_assert(strcmp(rmlvo.rules, rmlvo_new.rules) == 0);
+    g_assert(strcmp(rmlvo.model, rmlvo_new.model) == 0);
+    g_assert(strcmp(rmlvo.layout, rmlvo_new.layout) == 0);
+    g_assert(strcmp(rmlvo.variant, rmlvo_new.variant) == 0);
+    g_assert(strcmp(rmlvo.options, rmlvo_new.options) == 0);
+}
+
+
+/**
+ * Get the default RMLVO set.
+ * Set the default RMLVO set.
+ * Get the default RMLVO set.
+ * Repeat the last two steps.
+ *
+ * Result: RMLVO set obtained is the same as previously set.
+ */
+static void xkb_set_get_rules_test(void)
+{
+/* This test failed before XkbGetRulesDftlts changed to strdup.
+   We test this twice because the first time using XkbGetRulesDflts we obtain
+   the built-in defaults. The unexpected free isn't triggered until the second
+   XkbSetRulesDefaults.
+ */
+    XkbRMLVOSet rmlvo = { NULL };
+    XkbRMLVOSet rmlvo_backup;
+
+    XkbGetRulesDflts(&rmlvo);
+
+    /* pass 1 */
+    XkbSetRulesDflts(&rmlvo);
+    XkbGetRulesDflts(&rmlvo);
+
+    /* Make a backup copy */
+    rmlvo_backup.rules = strdup(rmlvo.rules);
+    rmlvo_backup.layout = strdup(rmlvo.layout);
+    rmlvo_backup.model = strdup(rmlvo.model);
+    rmlvo_backup.variant = strdup(rmlvo.variant);
+    rmlvo_backup.options = strdup(rmlvo.options);
+
+    /* pass 2 */
+    XkbSetRulesDflts(&rmlvo);
+
+    /* This test is iffy, because strictly we may be comparing against already
+     * freed memory */
+    g_assert(strcmp(rmlvo.rules, rmlvo_backup.rules) == 0);
+    g_assert(strcmp(rmlvo.model, rmlvo_backup.model) == 0);
+    g_assert(strcmp(rmlvo.layout, rmlvo_backup.layout) == 0);
+    g_assert(strcmp(rmlvo.variant, rmlvo_backup.variant) == 0);
+    g_assert(strcmp(rmlvo.options, rmlvo_backup.options) == 0);
+
+    XkbGetRulesDflts(&rmlvo);
+    g_assert(strcmp(rmlvo.rules, rmlvo_backup.rules) == 0);
+    g_assert(strcmp(rmlvo.model, rmlvo_backup.model) == 0);
+    g_assert(strcmp(rmlvo.layout, rmlvo_backup.layout) == 0);
+    g_assert(strcmp(rmlvo.variant, rmlvo_backup.variant) == 0);
+    g_assert(strcmp(rmlvo.options, rmlvo_backup.options) == 0);
+}
+
+
+int main(int argc, char** argv)
+{
+    g_test_init(&argc, &argv,NULL);
+    g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
+
+    g_test_add_func("/xkb/set-get-rules", xkb_set_get_rules_test);
+    g_test_add_func("/xkb/get-rules", xkb_get_rules_test);
+    g_test_add_func("/xkb/set-rules", xkb_set_rules_test);
+
+    return g_test_run();
+}
commit c2c515ead38d9a6c9eae0b83aa7a82208f177b7e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 22 13:26:40 2009 +1000

    dix: remove all but main() from main.c
    
    All other functions are pushed into where they seemed to fit.
    main.c is now linked separately into libmain.a and linked in by the various
    DDXs.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/configure.ac b/configure.ac
index fd60203..d907e88 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1153,6 +1153,10 @@ else
   DIX_LIB='$(top_builddir)/dix/libdix.la'
   OS_LIB='$(top_builddir)/os/libos.la'
 fi
+
+MAIN_LIB='$(top_builddir)/dix/libmain.la'
+AC_SUBST([MAIN_LIB])
+
 MI_LIB='$(top_builddir)/mi/libmi.la'
 MI_EXT_LIB='$(top_builddir)/mi/libmiext.la'
 MI_INC='-I$(top_srcdir)/mi'
@@ -1271,7 +1275,7 @@ AC_MSG_RESULT([$XNEST])
 AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
 
 if test "x$XNEST" = xyes; then
-	XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DIX_LIB $OS_LIB $CONFIG_LIB"
+	XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DIX_LIB $MAIN_LIB $OS_LIB $CONFIG_LIB"
 	XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS"
 	AC_SUBST([XNEST_LIBS])
 	AC_SUBST([XNEST_SYS_LIBS])
@@ -1643,7 +1647,7 @@ if test "x$XQUARTZ" = xyes; then
 	AC_DEFINE(XQUARTZ,1,[Have Quartz])
 	AC_DEFINE(ROOTLESS,1,[Build Rootless code])
 
-	DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB"
+	DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB"
 	AC_SUBST([DARWIN_LIBS])
 
 	AC_CHECK_LIB([Xplugin],[xp_init],[:])
@@ -1828,7 +1832,7 @@ if test "$KDRIVE" = yes; then
 	    ;;
     esac
     KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.la'
-    KDRIVE_LOCAL_LIBS="$DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB"
+    KDRIVE_LOCAL_LIBS="$DIX_LIB $MAIN_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
     KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB"
     KDRIVE_LIBS="$TSLIB_LIBS $KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $GLX_SYS_LIBS"
diff --git a/dix/Makefile.am b/dix/Makefile.am
index 83b8c62..ab702f7 100644
--- a/dix/Makefile.am
+++ b/dix/Makefile.am
@@ -1,7 +1,10 @@
-noinst_LTLIBRARIES = libdix.la
+noinst_LTLIBRARIES = libdix.la libmain.la
 
 AM_CFLAGS = $(DIX_CFLAGS)
 
+libmain_la_SOURCES =    \
+	main.c
+
 libdix_la_SOURCES = 	\
 	atom.c		\
 	colormap.c	\
@@ -26,7 +29,6 @@ libdix_la_SOURCES = 	\
 	grabs.c		\
 	initatoms.c	\
 	inpututils.c	\
-	main.c		\
 	pixmap.c	\
 	privates.c	\
 	property.c	\
diff --git a/dix/dispatch.c b/dix/dispatch.c
index a9f9367..16a51bd 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -107,6 +107,7 @@ Equipment Corporation.
 
 #ifdef HAVE_DIX_CONFIG_H
 #include <dix-config.h>
+#include <version-config.h>
 #endif
 
 #ifdef PANORAMIX_DEBUG
@@ -134,6 +135,7 @@ int ProcInitialConnection();
 #include "xace.h"
 #include "inputstr.h"
 #include "xkbsrv.h"
+#include "site.h"
 
 #ifdef XSERVER_DTRACE
 #include "registry.h"
@@ -150,7 +152,9 @@ typedef const char *string;
 #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
 #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
 
-extern xConnSetupPrefix connSetupPrefix;
+xConnSetupPrefix connSetupPrefix;
+
+PaddingInfo PixmapWidthPaddingInfo[33];
 
 static ClientPtr grabClient;
 #define GrabNone 0
@@ -160,7 +164,7 @@ static int grabState = GrabNone;
 static long grabWaiters[mskcnt];
 CallbackListPtr ServerGrabCallback = NULL;
 HWEventQueuePtr checkForInput[2];
-extern int connBlockScreenStart;
+int connBlockScreenStart;
 
 static void KillAllClients(void);
 
@@ -461,6 +465,166 @@ Dispatch(void)
 
 #undef MAJOROP
 
+static int  VendorRelease = VENDOR_RELEASE;
+static char *VendorString = VENDOR_NAME;
+
+static const int padlength[4] = {0, 3, 2, 1};
+
+void
+SetVendorRelease(int release)
+{
+    VendorRelease = release;
+}
+
+void
+SetVendorString(char *string)
+{
+    VendorString = string;
+}
+
+Bool
+CreateConnectionBlock(void)
+{
+    xConnSetup setup;
+    xWindowRoot root;
+    xDepth	depth;
+    xVisualType visual;
+    xPixmapFormat format;
+    unsigned long vid;
+    int i, j, k,
+        lenofblock,
+        sizesofar = 0;
+    char *pBuf;
+
+
+    memset(&setup, 0, sizeof(xConnSetup));
+    /* Leave off the ridBase and ridMask, these must be sent with
+       connection */
+
+    setup.release = VendorRelease;
+    /*
+     * per-server image and bitmap parameters are defined in Xmd.h
+     */
+    setup.imageByteOrder = screenInfo.imageByteOrder;
+
+    setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
+    setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
+
+    setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
+    setup.motionBufferSize = NumMotionEvents();
+    setup.numRoots = screenInfo.numScreens;
+    setup.nbytesVendor = strlen(VendorString);
+    setup.numFormats = screenInfo.numPixmapFormats;
+    setup.maxRequestSize = MAX_REQUEST_SIZE;
+    QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
+
+    lenofblock = sizeof(xConnSetup) +
+            ((setup.nbytesVendor + 3) & ~3) +
+	    (setup.numFormats * sizeof(xPixmapFormat)) +
+            (setup.numRoots * sizeof(xWindowRoot));
+    ConnectionInfo = xalloc(lenofblock);
+    if (!ConnectionInfo)
+	return FALSE;
+
+    memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
+    sizesofar = sizeof(xConnSetup);
+    pBuf = ConnectionInfo + sizeof(xConnSetup);
+
+    memmove(pBuf, VendorString, (int)setup.nbytesVendor);
+    sizesofar += setup.nbytesVendor;
+    pBuf += setup.nbytesVendor;
+    i = padlength[setup.nbytesVendor & 3];
+    sizesofar += i;
+    while (--i >= 0)
+	*pBuf++ = 0;
+
+    memset(&format, 0, sizeof(xPixmapFormat));
+    for (i=0; i<screenInfo.numPixmapFormats; i++)
+    {
+	format.depth = screenInfo.formats[i].depth;
+	format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
+	format.scanLinePad = screenInfo.formats[i].scanlinePad;
+	memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
+	pBuf += sizeof(xPixmapFormat);
+	sizesofar += sizeof(xPixmapFormat);
+    }
+
+    connBlockScreenStart = sizesofar;
+    memset(&depth, 0, sizeof(xDepth));
+    memset(&visual, 0, sizeof(xVisualType));
+    for (i=0; i<screenInfo.numScreens; i++)
+    {
+	ScreenPtr	pScreen;
+	DepthPtr	pDepth;
+	VisualPtr	pVisual;
+
+	pScreen = screenInfo.screens[i];
+	root.windowId = WindowTable[i]->drawable.id;
+	root.defaultColormap = pScreen->defColormap;
+	root.whitePixel = pScreen->whitePixel;
+	root.blackPixel = pScreen->blackPixel;
+	root.currentInputMask = 0;    /* filled in when sent */
+	root.pixWidth = pScreen->width;
+	root.pixHeight = pScreen->height;
+	root.mmWidth = pScreen->mmWidth;
+	root.mmHeight = pScreen->mmHeight;
+	root.minInstalledMaps = pScreen->minInstalledCmaps;
+	root.maxInstalledMaps = pScreen->maxInstalledCmaps;
+	root.rootVisualID = pScreen->rootVisual;
+	root.backingStore = pScreen->backingStoreSupport;
+	root.saveUnders = FALSE;
+	root.rootDepth = pScreen->rootDepth;
+	root.nDepths = pScreen->numDepths;
+	memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
+	sizesofar += sizeof(xWindowRoot);
+	pBuf += sizeof(xWindowRoot);
+
+	pDepth = pScreen->allowedDepths;
+	for(j = 0; j < pScreen->numDepths; j++, pDepth++)
+	{
+	    lenofblock += sizeof(xDepth) +
+		    (pDepth->numVids * sizeof(xVisualType));
+	    pBuf = (char *)xrealloc(ConnectionInfo, lenofblock);
+	    if (!pBuf)
+	    {
+		xfree(ConnectionInfo);
+		return FALSE;
+	    }
+	    ConnectionInfo = pBuf;
+	    pBuf += sizesofar;
+	    depth.depth = pDepth->depth;
+	    depth.nVisuals = pDepth->numVids;
+	    memmove(pBuf, (char *)&depth, sizeof(xDepth));
+	    pBuf += sizeof(xDepth);
+	    sizesofar += sizeof(xDepth);
+	    for(k = 0; k < pDepth->numVids; k++)
+	    {
+		vid = pDepth->vids[k];
+		for (pVisual = pScreen->visuals;
+		     pVisual->vid != vid;
+		     pVisual++)
+		    ;
+		visual.visualID = vid;
+		visual.class = pVisual->class;
+		visual.bitsPerRGB = pVisual->bitsPerRGBValue;
+		visual.colormapEntries = pVisual->ColormapEntries;
+		visual.redMask = pVisual->redMask;
+		visual.greenMask = pVisual->greenMask;
+		visual.blueMask = pVisual->blueMask;
+		memmove(pBuf, (char *)&visual, sizeof(xVisualType));
+		pBuf += sizeof(xVisualType);
+		sizesofar += sizeof(xVisualType);
+	    }
+	}
+    }
+    connSetupPrefix.success = xTrue;
+    connSetupPrefix.length = lenofblock/4;
+    connSetupPrefix.majorVersion = X_PROTOCOL;
+    connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
+    return TRUE;
+}
+
+
 int
 ProcBadRequest(ClientPtr client)
 {
@@ -3700,3 +3864,176 @@ MarkClientException(ClientPtr client)
 {
     client->noClientException = -1;
 }
+
+/*
+ * This array encodes the answer to the question "what is the log base 2
+ * of the number of pixels that fit in a scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int answer[6][4] = {
+	/* pad   pad   pad     pad*/
+	/*  8     16    32    64 */
+
+	{   3,     4,    5 ,   6 },	/* 1 bit per pixel */
+	{   1,     2,    3 ,   4 },	/* 4 bits per pixel */
+	{   0,     1,    2 ,   3 },	/* 8 bits per pixel */
+	{   ~0,    0,    1 ,   2 },	/* 16 bits per pixel */
+	{   ~0,    ~0,   0 ,   1 },	/* 24 bits per pixel */
+	{   ~0,    ~0,   0 ,   1 }	/* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the first index for
+ * the answer array above given the number of bits per pixel?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForBitsPerPixel[ 33 ] = {
+	~0, 0, ~0, ~0,	/* 1 bit per pixel */
+	1, ~0, ~0, ~0,	/* 4 bits per pixel */
+	2, ~0, ~0, ~0,	/* 8 bits per pixel */
+	~0,~0, ~0, ~0,
+	3, ~0, ~0, ~0,	/* 16 bits per pixel */
+	~0,~0, ~0, ~0,
+	4, ~0, ~0, ~0,	/* 24 bits per pixel */
+	~0,~0, ~0, ~0,
+	5		/* 32 bits per pixel */
+};
+
+/*
+ * This array gives the bytesperPixel value for cases where the number
+ * of bits per pixel is a multiple of 8 but not a power of 2.
+ */
+static int answerBytesPerPixel[ 33 ] = {
+	~0, 0, ~0, ~0,	/* 1 bit per pixel */
+	0, ~0, ~0, ~0,	/* 4 bits per pixel */
+	0, ~0, ~0, ~0,	/* 8 bits per pixel */
+	~0,~0, ~0, ~0,
+	0, ~0, ~0, ~0,	/* 16 bits per pixel */
+	~0,~0, ~0, ~0,
+	3, ~0, ~0, ~0,	/* 24 bits per pixel */
+	~0,~0, ~0, ~0,
+	0		/* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the second index for
+ * the answer array above given the number of bits per scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForScanlinePad[ 65 ] = {
+	~0, ~0, ~0, ~0,
+	~0, ~0, ~0, ~0,
+	 0, ~0, ~0, ~0,	/* 8 bits per scanline pad unit */
+	~0, ~0, ~0, ~0,
+	 1, ~0, ~0, ~0,	/* 16 bits per scanline pad unit */
+	~0, ~0, ~0, ~0,
+	~0, ~0, ~0, ~0,
+	~0, ~0, ~0, ~0,
+	 2, ~0, ~0, ~0,	/* 32 bits per scanline pad unit */
+	~0, ~0, ~0, ~0,
+	~0, ~0, ~0, ~0,
+	~0, ~0, ~0, ~0,
+	~0, ~0, ~0, ~0,
+	~0, ~0, ~0, ~0,
+	~0, ~0, ~0, ~0,
+	~0, ~0, ~0, ~0,
+	 3		/* 64 bits per scanline pad unit */
+};
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+/*
+	grow the array of screenRecs if necessary.
+	call the device-supplied initialization procedure
+with its screen number, a pointer to its ScreenRec, argc, and argv.
+	return the number of successfully installed screens.
+
+*/
+
+int
+AddScreen(
+    Bool	(* pfnInit)(
+	int /*index*/,
+	ScreenPtr /*pScreen*/,
+	int /*argc*/,
+	char ** /*argv*/
+		),
+    int argc,
+    char **argv)
+{
+
+    int i;
+    int scanlinepad, format, depth, bitsPerPixel, j, k;
+    ScreenPtr pScreen;
+
+    i = screenInfo.numScreens;
+    if (i == MAXSCREENS)
+	return -1;
+
+    pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec));
+    if (!pScreen)
+	return -1;
+
+    pScreen->devPrivates = NULL;
+    pScreen->myNum = i;
+    pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8);
+    pScreen->ClipNotify = 0;	/* for R4 ddx compatibility */
+    pScreen->CreateScreenResources = 0;
+
+    /*
+     * This loop gets run once for every Screen that gets added,
+     * but thats ok.  If the ddx layer initializes the formats
+     * one at a time calling AddScreen() after each, then each
+     * iteration will make it a little more accurate.  Worst case
+     * we do this loop N * numPixmapFormats where N is # of screens.
+     * Anyway, this must be called after InitOutput and before the
+     * screen init routine is called.
+     */
+    for (format=0; format<screenInfo.numPixmapFormats; format++)
+    {
+	depth = screenInfo.formats[format].depth;
+	bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
+	scanlinepad = screenInfo.formats[format].scanlinePad;
+	j = indexForBitsPerPixel[ bitsPerPixel ];
+	k = indexForScanlinePad[ scanlinepad ];
+	PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
+	PixmapWidthPaddingInfo[ depth ].padRoundUp =
+	    (scanlinepad/bitsPerPixel) - 1;
+	j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
+	PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
+	PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
+	if (answerBytesPerPixel[bitsPerPixel])
+	{
+	    PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
+	    PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
+		answerBytesPerPixel[bitsPerPixel];
+	}
+	else
+	{
+	    PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
+	}
+    }
+
+    /* This is where screen specific stuff gets initialized.  Load the
+       screen structure, call the hardware, whatever.
+       This is also where the default colormap should be allocated and
+       also pixel values for blackPixel, whitePixel, and the cursor
+       Note that InitScreen is NOT allowed to modify argc, argv, or
+       any of the strings pointed to by argv.  They may be passed to
+       multiple screens.
+    */
+    pScreen->rgf = ~0L;  /* there are no scratch GCs yet*/
+    WindowTable[i] = NullWindow;
+    screenInfo.screens[i] = pScreen;
+    screenInfo.numScreens++;
+    if (!(*pfnInit)(i, pScreen, argc, argv))
+    {
+	dixFreePrivates(pScreen->devPrivates);
+	xfree(pScreen);
+	screenInfo.numScreens--;
+	return -1;
+    }
+    return i;
+}
diff --git a/dix/events.c b/dix/events.c
index 1057eb4..c87a361 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -283,6 +283,12 @@ static struct {
 static xEvent* swapEvent = NULL;
 static int swapEventLen = 0;
 
+void
+NotImplemented(xEvent *from, xEvent *to)
+{
+    FatalError("Not implemented");
+}
+
 /**
  * Convert the given event type from an XI event to a core event.
  * @param[in] The XI 1.x event type.
diff --git a/dix/main.c b/dix/main.c
index 9d5d839..25b085e 100644
--- a/dix/main.c
+++ b/dix/main.c
@@ -118,120 +118,7 @@ Equipment Corporation.
 
 extern void Dispatch(void);
 
-xConnSetupPrefix connSetupPrefix;
-
-extern FontPtr defaultFont;
-
 extern void InitProcVectors(void);
-extern Bool CreateGCperDepthArray(void);
-
-#ifndef PANORAMIX
-static
-#endif
-Bool CreateConnectionBlock(void);
-
-PaddingInfo PixmapWidthPaddingInfo[33];
-
-int connBlockScreenStart;
-
-void
-NotImplemented(xEvent *from, xEvent *to)
-{
-    FatalError("Not implemented");
-}
-
-/*
- * Dummy entry for ReplySwapVector[]
- */
-
-void
-ReplyNotSwappd(
-	ClientPtr pClient ,
-	int size ,
-	void * pbuf
-	)
-{
-    FatalError("Not implemented");
-}
-
-/*
- * This array encodes the answer to the question "what is the log base 2
- * of the number of pixels that fit in a scanline pad unit?"
- * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
- */
-static int answer[6][4] = {
-	/* pad   pad   pad     pad*/
-	/*  8     16    32    64 */
-
-	{   3,     4,    5 ,   6 },	/* 1 bit per pixel */
-	{   1,     2,    3 ,   4 },	/* 4 bits per pixel */
-	{   0,     1,    2 ,   3 },	/* 8 bits per pixel */
-	{   ~0,    0,    1 ,   2 },	/* 16 bits per pixel */
-	{   ~0,    ~0,   0 ,   1 },	/* 24 bits per pixel */
-	{   ~0,    ~0,   0 ,   1 }	/* 32 bits per pixel */
-};
-
-/*
- * This array gives the answer to the question "what is the first index for
- * the answer array above given the number of bits per pixel?"
- * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
- */
-static int indexForBitsPerPixel[ 33 ] = {
-	~0, 0, ~0, ~0,	/* 1 bit per pixel */
-	1, ~0, ~0, ~0,	/* 4 bits per pixel */
-	2, ~0, ~0, ~0,	/* 8 bits per pixel */
-	~0,~0, ~0, ~0,
-	3, ~0, ~0, ~0,	/* 16 bits per pixel */
-	~0,~0, ~0, ~0,
-	4, ~0, ~0, ~0,	/* 24 bits per pixel */
-	~0,~0, ~0, ~0,
-	5		/* 32 bits per pixel */
-};
-
-/*
- * This array gives the bytesperPixel value for cases where the number
- * of bits per pixel is a multiple of 8 but not a power of 2.
- */
-static int answerBytesPerPixel[ 33 ] = {
-	~0, 0, ~0, ~0,	/* 1 bit per pixel */
-	0, ~0, ~0, ~0,	/* 4 bits per pixel */
-	0, ~0, ~0, ~0,	/* 8 bits per pixel */
-	~0,~0, ~0, ~0,
-	0, ~0, ~0, ~0,	/* 16 bits per pixel */
-	~0,~0, ~0, ~0,
-	3, ~0, ~0, ~0,	/* 24 bits per pixel */
-	~0,~0, ~0, ~0,
-	0		/* 32 bits per pixel */
-};
-
-/*
- * This array gives the answer to the question "what is the second index for
- * the answer array above given the number of bits per scanline pad unit?"
- * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
- */
-static int indexForScanlinePad[ 65 ] = {
-	~0, ~0, ~0, ~0,
-	~0, ~0, ~0, ~0,
-	 0, ~0, ~0, ~0,	/* 8 bits per scanline pad unit */
-	~0, ~0, ~0, ~0,
-	 1, ~0, ~0, ~0,	/* 16 bits per scanline pad unit */
-	~0, ~0, ~0, ~0,
-	~0, ~0, ~0, ~0,
-	~0, ~0, ~0, ~0,
-	 2, ~0, ~0, ~0,	/* 32 bits per scanline pad unit */
-	~0, ~0, ~0, ~0,
-	~0, ~0, ~0, ~0,
-	~0, ~0, ~0, ~0,
-	~0, ~0, ~0, ~0,
-	~0, ~0, ~0, ~0,
-	~0, ~0, ~0, ~0,
-	~0, ~0, ~0, ~0,
-	 3		/* 64 bits per scanline pad unit */
-};
-
-#ifndef MIN
-#define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#endif
 
 #ifdef XQUARTZ
 #include <pthread.h>
@@ -456,258 +343,3 @@ int main(int argc, char *argv[], char *envp[])
     return(0);
 }
 
-static int  VendorRelease = VENDOR_RELEASE;
-static char *VendorString = VENDOR_NAME;
-
-void
-SetVendorRelease(int release)
-{
-    VendorRelease = release;
-}
-
-void
-SetVendorString(char *string)
-{
-    VendorString = string;
-}
-
-static const int padlength[4] = {0, 3, 2, 1};
-
-#ifndef PANORAMIX
-static
-#endif
-Bool
-CreateConnectionBlock(void)
-{
-    xConnSetup setup;
-    xWindowRoot root;
-    xDepth	depth;
-    xVisualType visual;
-    xPixmapFormat format;
-    unsigned long vid;
-    int i, j, k,
-        lenofblock,
-        sizesofar = 0;
-    char *pBuf;
-
-
-    memset(&setup, 0, sizeof(xConnSetup));
-    /* Leave off the ridBase and ridMask, these must be sent with
-       connection */
-
-    setup.release = VendorRelease;
-    /*
-     * per-server image and bitmap parameters are defined in Xmd.h
-     */
-    setup.imageByteOrder = screenInfo.imageByteOrder;
-
-    setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
-    setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
-
-    setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
-    setup.motionBufferSize = NumMotionEvents();
-    setup.numRoots = screenInfo.numScreens;
-    setup.nbytesVendor = strlen(VendorString); 
-    setup.numFormats = screenInfo.numPixmapFormats;
-    setup.maxRequestSize = MAX_REQUEST_SIZE;
-    QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
-    
-    lenofblock = sizeof(xConnSetup) + 
-            ((setup.nbytesVendor + 3) & ~3) +
-	    (setup.numFormats * sizeof(xPixmapFormat)) +
-            (setup.numRoots * sizeof(xWindowRoot));
-    ConnectionInfo = xalloc(lenofblock);
-    if (!ConnectionInfo)
-	return FALSE;
-
-    memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
-    sizesofar = sizeof(xConnSetup);
-    pBuf = ConnectionInfo + sizeof(xConnSetup);
-
-    memmove(pBuf, VendorString, (int)setup.nbytesVendor);
-    sizesofar += setup.nbytesVendor;
-    pBuf += setup.nbytesVendor;
-    i = padlength[setup.nbytesVendor & 3];
-    sizesofar += i;
-    while (--i >= 0)
-	*pBuf++ = 0;
-
-    memset(&format, 0, sizeof(xPixmapFormat));
-    for (i=0; i<screenInfo.numPixmapFormats; i++)
-    {
-	format.depth = screenInfo.formats[i].depth;
-	format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
-	format.scanLinePad = screenInfo.formats[i].scanlinePad;
-	memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
-	pBuf += sizeof(xPixmapFormat);
-	sizesofar += sizeof(xPixmapFormat);
-    }
-
-    connBlockScreenStart = sizesofar;
-    memset(&depth, 0, sizeof(xDepth));
-    memset(&visual, 0, sizeof(xVisualType));
-    for (i=0; i<screenInfo.numScreens; i++)
-    {
-	ScreenPtr	pScreen;
-	DepthPtr	pDepth;
-	VisualPtr	pVisual;
-
-	pScreen = screenInfo.screens[i];
-	root.windowId = WindowTable[i]->drawable.id;
-	root.defaultColormap = pScreen->defColormap;
-	root.whitePixel = pScreen->whitePixel;
-	root.blackPixel = pScreen->blackPixel;
-	root.currentInputMask = 0;    /* filled in when sent */
-	root.pixWidth = pScreen->width;
-	root.pixHeight = pScreen->height;
-	root.mmWidth = pScreen->mmWidth;
-	root.mmHeight = pScreen->mmHeight;
-	root.minInstalledMaps = pScreen->minInstalledCmaps;
-	root.maxInstalledMaps = pScreen->maxInstalledCmaps; 
-	root.rootVisualID = pScreen->rootVisual;		
-	root.backingStore = pScreen->backingStoreSupport;
-	root.saveUnders = FALSE;
-	root.rootDepth = pScreen->rootDepth;
-	root.nDepths = pScreen->numDepths;
-	memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
-	sizesofar += sizeof(xWindowRoot);
-	pBuf += sizeof(xWindowRoot);
-
-	pDepth = pScreen->allowedDepths;
-	for(j = 0; j < pScreen->numDepths; j++, pDepth++)
-	{
-	    lenofblock += sizeof(xDepth) + 
-		    (pDepth->numVids * sizeof(xVisualType));
-	    pBuf = (char *)xrealloc(ConnectionInfo, lenofblock);
-	    if (!pBuf)
-	    {
-		xfree(ConnectionInfo);
-		return FALSE;
-	    }
-	    ConnectionInfo = pBuf;
-	    pBuf += sizesofar;            
-	    depth.depth = pDepth->depth;
-	    depth.nVisuals = pDepth->numVids;
-	    memmove(pBuf, (char *)&depth, sizeof(xDepth));
-	    pBuf += sizeof(xDepth);
-	    sizesofar += sizeof(xDepth);
-	    for(k = 0; k < pDepth->numVids; k++)
-	    {
-		vid = pDepth->vids[k];
-		for (pVisual = pScreen->visuals;
-		     pVisual->vid != vid;
-		     pVisual++)
-		    ;
-		visual.visualID = vid;
-		visual.class = pVisual->class;
-		visual.bitsPerRGB = pVisual->bitsPerRGBValue;
-		visual.colormapEntries = pVisual->ColormapEntries;
-		visual.redMask = pVisual->redMask;
-		visual.greenMask = pVisual->greenMask;
-		visual.blueMask = pVisual->blueMask;
-		memmove(pBuf, (char *)&visual, sizeof(xVisualType));
-		pBuf += sizeof(xVisualType);
-		sizesofar += sizeof(xVisualType);
-	    }
-	}
-    }
-    connSetupPrefix.success = xTrue;
-    connSetupPrefix.length = lenofblock/4;
-    connSetupPrefix.majorVersion = X_PROTOCOL;
-    connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
-    return TRUE;
-}
-
-/*
-	grow the array of screenRecs if necessary.
-	call the device-supplied initialization procedure 
-with its screen number, a pointer to its ScreenRec, argc, and argv.
-	return the number of successfully installed screens.
-
-*/
-
-int
-AddScreen(
-    Bool	(* pfnInit)(
-	int /*index*/,
-	ScreenPtr /*pScreen*/,
-	int /*argc*/,
-	char ** /*argv*/
-		),
-    int argc,
-    char **argv)
-{
-
-    int i;
-    int scanlinepad, format, depth, bitsPerPixel, j, k;
-    ScreenPtr pScreen;
-
-    i = screenInfo.numScreens;
-    if (i == MAXSCREENS)
-	return -1;
-
-    pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec));
-    if (!pScreen)
-	return -1;
-
-    pScreen->devPrivates = NULL;
-    pScreen->myNum = i;
-    pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8);
-    pScreen->ClipNotify = 0;	/* for R4 ddx compatibility */
-    pScreen->CreateScreenResources = 0;
-    
-    /*
-     * This loop gets run once for every Screen that gets added,
-     * but thats ok.  If the ddx layer initializes the formats
-     * one at a time calling AddScreen() after each, then each
-     * iteration will make it a little more accurate.  Worst case
-     * we do this loop N * numPixmapFormats where N is # of screens.
-     * Anyway, this must be called after InitOutput and before the
-     * screen init routine is called.
-     */
-    for (format=0; format<screenInfo.numPixmapFormats; format++)
-    {
- 	depth = screenInfo.formats[format].depth;
- 	bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
-  	scanlinepad = screenInfo.formats[format].scanlinePad;
- 	j = indexForBitsPerPixel[ bitsPerPixel ];
-  	k = indexForScanlinePad[ scanlinepad ];
- 	PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
- 	PixmapWidthPaddingInfo[ depth ].padRoundUp =
- 	    (scanlinepad/bitsPerPixel) - 1;
- 	j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
- 	PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
-	PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
-	if (answerBytesPerPixel[bitsPerPixel])
-	{
-	    PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
-	    PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
-		answerBytesPerPixel[bitsPerPixel];
-	}
-	else
-	{
-	    PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
-	}
-    }
-  
-    /* This is where screen specific stuff gets initialized.  Load the
-       screen structure, call the hardware, whatever.
-       This is also where the default colormap should be allocated and
-       also pixel values for blackPixel, whitePixel, and the cursor
-       Note that InitScreen is NOT allowed to modify argc, argv, or
-       any of the strings pointed to by argv.  They may be passed to
-       multiple screens. 
-    */ 
-    pScreen->rgf = ~0L;  /* there are no scratch GCs yet*/
-    WindowTable[i] = NullWindow;
-    screenInfo.screens[i] = pScreen;
-    screenInfo.numScreens++;
-    if (!(*pfnInit)(i, pScreen, argc, argv))
-    {
-	dixFreePrivates(pScreen->devPrivates);
-	xfree(pScreen);
-	screenInfo.numScreens--;
-	return -1;
-    }
-    return i;
-}
diff --git a/dix/swaprep.c b/dix/swaprep.c
index 9eb6765..8624216 100644
--- a/dix/swaprep.c
+++ b/dix/swaprep.c
@@ -1291,3 +1291,18 @@ WriteSConnSetupPrefix(ClientPtr pClient, xConnSetupPrefix *pcsp)
     SwapConnSetupPrefix(pcsp, &cspT);
     (void)WriteToClient(pClient, sizeof(cspT), (char *) &cspT);
 }
+
+/*
+ * Dummy entry for ReplySwapVector[]
+ */
+
+void
+ReplyNotSwappd(
+	ClientPtr pClient ,
+	int size ,
+	void * pbuf
+	)
+{
+    FatalError("Not implemented");
+}
+
diff --git a/hw/dmx/Makefile.am b/hw/dmx/Makefile.am
index 9d2778a..9e9b39a 100644
--- a/hw/dmx/Makefile.am
+++ b/hw/dmx/Makefile.am
@@ -85,6 +85,7 @@ XDMX_LIBS = \
 	$(GLX_LIBS) \
         input/libdmxinput.a \
         config/libdmxconfig.a \
+	$(MAIN_LIB) \
 	$(XSERVER_LIBS)
 
 Xdmx_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
diff --git a/hw/vfb/Makefile.am b/hw/vfb/Makefile.am
index a4a120a..c5b49a3 100644
--- a/hw/vfb/Makefile.am
+++ b/hw/vfb/Makefile.am
@@ -22,6 +22,7 @@ Xvfb_SOURCES = $(SRCS)
 XVFB_LIBS = \
         @XVFB_LIBS@ \
 	libfbcmap.a \
+	$(MAIN_LIB) \
 	$(XSERVER_LIBS)
 
 Xvfb_LDADD = $(XVFB_LIBS) $(XVFB_SYS_LIBS) $(XSERVER_SYS_LIBS)
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index b6a534b..3b9ff9c 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -56,7 +56,7 @@ libxorg.c xorg.c:
 DISTCLEANFILES = libxorg.c xorg.c
 
 Xorg_DEPENDENCIES = libxorg.la
-Xorg_LDADD = libxorg.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS)
+Xorg_LDADD = $(MAIN_LIB) libxorg.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS)
 
 Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
 
diff --git a/hw/xquartz/mach-startup/Makefile.am b/hw/xquartz/mach-startup/Makefile.am
index b011294..0c609e3 100644
--- a/hw/xquartz/mach-startup/Makefile.am
+++ b/hw/xquartz/mach-startup/Makefile.am
@@ -19,7 +19,7 @@ X11_bin_LDADD = \
 	$(top_builddir)/dix/dixfonts.lo \
 	$(top_builddir)/miext/rootless/librootless.la \
 	$(top_builddir)/hw/xquartz/pbproxy/libxpbproxy.la \
-	$(DARWIN_LIBS) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) -lXplugin
+	$(DARWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) -lXplugin
 
 X11_bin_LDFLAGS =  \
 	-XCClinker -Objc \
diff --git a/include/dix.h b/include/dix.h
index 97dc9cc..7811982 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -170,6 +170,7 @@ extern _X_EXPORT void SendErrorToClient(
 extern _X_EXPORT void MarkClientException(
     ClientPtr /*client*/);
 
+extern _X_HIDDEN Bool CreateConnectionBlock(void);
 /* dixutils.c */
 
 extern _X_EXPORT void CopyISOLatin1Lowered(
commit 48573e7ea13e279593249036e6d30f1d7507882f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 26 21:32:37 2009 +1000

    Xi: swap stuff->cursor in SProcXIGrabDevice

diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c
index 0e86aa3..11c7679 100644
--- a/Xi/xigrabdev.c
+++ b/Xi/xigrabdev.c
@@ -51,6 +51,7 @@ SProcXIGrabDevice(ClientPtr client)
     swaps(&stuff->length, n);
     swaps(&stuff->deviceid, n);
     swapl(&stuff->grab_window, n);
+    swapl(&stuff->cursor, n);
     swapl(&stuff->time, n);
     swaps(&stuff->mask_len, n);
 
commit 057fc9a4f89282e440b5e11458f1dd8655879dd8
Merge: 95628b7... 932d6bc...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 24 16:15:47 2009 +1000

    Merge branch 'master' into xi2
    
    Conflicts:
    	Xi/chdevhier.c
    	include/input.h

diff --cc Xi/chdevhier.c
index 2b107e7,6c70bd9..746f4a5
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@@ -54,49 -52,8 +54,51 @@@
  
  #include "chdevhier.h"
  
+ extern DevPrivateKey XTstDevicePrivateKey;
+ 
 +/**
 + * Send the current state of the device hierarchy to all clients.
 + */
 +void XISendDeviceHierarchyEvent(int flags)
 +{
 +    xXIDeviceHierarchyEvent *ev;
 +    xXIHierarchyInfo *info;
 +    DeviceIntRec dummyDev;
 +    DeviceIntPtr dev;
 +
 +    if (!flags)
 +        return;
 +
 +    ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) + inputInfo.numDevices *
 +            sizeof(xXIHierarchyInfo));
 +    ev->type = GenericEvent;
 +    ev->extension = IReqCode;
 +    ev->evtype = XI_HierarchyChanged;
 +    ev->time = GetTimeInMillis();
 +    ev->flags = flags;
 +    ev->num_devices = inputInfo.numDevices;
 +    ev->length = (ev->num_devices * sizeof(xXIHierarchyInfo))/4;
 +
 +    info = (xXIHierarchyInfo*)&ev[1];
 +    for (dev = inputInfo.devices; dev; dev = dev->next)
 +    {
 +        info->deviceid = dev->id;
 +        info->enabled = dev->enabled;
 +        info->use = GetDeviceUse(dev, &info->attachment);
 +        info++;
 +    }
 +    for (dev = inputInfo.off_devices; dev; dev = dev->next)
 +    {
 +        info->deviceid = dev->id;
 +        info->enabled = dev->enabled;
 +        info->use = GetDeviceUse(dev, &info->attachment);
 +        info++;
 +    }
 +
 +    dummyDev.id = AllDevices;
 +    SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1);
 +}
 +
  
  /***********************************************************************
   *
@@@ -117,22 -74,21 +119,22 @@@ int SProcXIChangeDeviceHierarchy(Client
  #define SWAPIF(cmd) if (client->swapped) { cmd; }
  
  int
 -ProcXChangeDeviceHierarchy(ClientPtr client)
 +ProcXIChangeDeviceHierarchy(ClientPtr client)
  {
-     DeviceIntPtr ptr, keybd;
+     DeviceIntPtr ptr, keybd, xtstptr, xtstkeybd;
 -    DeviceIntRec dummyDev;
 -    xAnyHierarchyChangeInfo *any;
 -    int required_len = sizeof(xChangeDeviceHierarchyReq);
 +    xXIAnyHierarchyChangeInfo *any;
 +    int required_len = sizeof(xXIChangeDeviceHierarchyReq);
      char n;
      int rc = Success;
 -    int nchanges = 0;
 -    deviceHierarchyChangedEvent ev;
 +    int flags = 0;
 +
 +    REQUEST(xXIChangeDeviceHierarchyReq);
 +    REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq);
  
 -    REQUEST(xChangeDeviceHierarchyReq);
 -    REQUEST_AT_LEAST_SIZE(xChangeDeviceHierarchyReq);
 +    if (!stuff->num_changes)
 +        return rc;
  
 -    any = (xAnyHierarchyChangeInfo*)&stuff[1];
 +    any = (xXIAnyHierarchyChangeInfo*)&stuff[1];
      while(stuff->num_changes--)
      {
          SWAPIF(swapl(&any->type, n));
@@@ -146,42 -102,62 +148,62 @@@
          {
              case CH_CreateMasterDevice:
                  {
 -                    xCreateMasterInfo* c = (xCreateMasterInfo*)any;
 +                    xXICreateMasterInfo* c = (xXICreateMasterInfo*)any;
                      char* name;
  
 -                    SWAPIF(swaps(&c->namelen, n));
 -                    name = xcalloc(c->namelen + 1, sizeof(char));
 -                    strncpy(name, (char*)&c[1], c->namelen);
 +                    SWAPIF(swaps(&c->name_len, n));
 +                    name = xcalloc(c->name_len + 1, sizeof(char));
 +                    strncpy(name, (char*)&c[1], c->name_len);
  
  
-                     rc = AllocMasterDevice(client, name, &ptr, &keybd);
+                     rc = AllocDevicePair(client, name, &ptr, &keybd, TRUE);
                      if (rc != Success)
                      {
                          xfree(name);
                          goto unwind;
                      }
  
 -                    if (!c->sendCore)
 +                    if (!c->send_core)
                          ptr->coreEvents = keybd->coreEvents =  FALSE;
  
+ 		    /* Allocate virtual slave devices for xtest events */
+                     rc = AllocXtstDevice(client, name, &xtstptr, &xtstkeybd);
+                     if (rc != Success)
+                     {
+ 
+                         xfree(name);
+                         goto unwind;
+                     }
+ 
                      ActivateDevice(ptr);
                      ActivateDevice(keybd);
+                     ActivateDevice(xtstptr);
+                     ActivateDevice(xtstkeybd);
  
                      if (c->enable)
                      {
                          EnableDevice(ptr);
                          EnableDevice(keybd);
+                         EnableDevice(xtstptr);
+                         EnableDevice(xtstkeybd);
                      }
+ 
+                     /* Attach the XTest virtual devices to the newly
+                        created master device */
+                     AttachDevice(NULL, xtstptr, ptr);
+                     AttachDevice(NULL, xtstkeybd, keybd);
+ 
                      xfree(name);
 -                    nchanges++;
 +                    flags |= HF_MasterAdded;
                  }
                  break;
              case CH_RemoveMasterDevice:
                  {
 -                    xRemoveMasterInfo* r = (xRemoveMasterInfo*)any;
 +                    xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)any;
+                     DeviceIntPtr xtstdevice;
  
 -                    if (r->returnMode != AttachToMaster &&
 -                            r->returnMode != Floating)
 +                    if (r->return_mode != AttachToMaster &&
 +                            r->return_mode != Floating)
                          return BadValue;
  
                      rc = dixLookupDevice(&ptr, r->deviceid, client,
@@@ -277,35 -310,18 +356,50 @@@
                      DisableDevice(keybd);
                      DisableDevice(ptr);
  
+                     RemoveDevice(xtstptr);
+                     RemoveDevice(xtstkeybd);
                      RemoveDevice(keybd);
                      RemoveDevice(ptr);
 -                    nchanges++;
 +                    flags |= HF_MasterRemoved;
                  }
                  break;
 -            case CH_ChangeAttachment:
 +            case CH_DetachSlave:
                  {
 +                    xXIDetachSlaveInfo* c = (xXIDetachSlaveInfo*)any;
+                     DeviceIntPtr *xtstdevice;
  
 -                    xChangeAttachmentInfo* c = (xChangeAttachmentInfo*)any;
 +                    rc = dixLookupDevice(&ptr, c->deviceid, client,
 +                                          DixWriteAccess);
 +                    if (rc != Success)
 +                       goto unwind;
 +
 +                    if (ptr->isMaster)
 +                    {
 +                        client->errorValue = c->deviceid;
 +                        rc = BadDevice;
 +                        goto unwind;
 +                    }
 +
++                    xtstdevice = dixLookupPrivate( &ptr->devPrivates,
++                                                   XTstDevicePrivateKey );
++
++                    /* Don't allow changes to Xtst Devices, these are fixed */
++                    if( xtstdevice )
++                    {
++                        client->errorValue = c->deviceid;
++                        rc = BadDevice;
++                        goto unwind;
++                    }
++
 +                    AttachDevice(client, ptr, NULL);
 +                    flags |= HF_SlaveDetached;
 +                }
 +                break;
 +            case CH_AttachSlave:
 +                {
 +                    xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)any;
 +                    DeviceIntPtr newmaster;
++                    DeviceIntPtr *xtstdevice;
  
                      rc = dixLookupDevice(&ptr, c->deviceid, client,
                                            DixWriteAccess);
@@@ -319,18 -335,34 +413,29 @@@
                          goto unwind;
                      }
  
+                     xtstdevice = dixLookupPrivate( &ptr->devPrivates,
+                                                    XTstDevicePrivateKey );
+ 
+                     /* Don't allow changes to Xtst Devices, these are fixed */
+                     if( xtstdevice )
+                     {
+                         client->errorValue = c->deviceid;
+                         rc = BadDevice;
+                         goto unwind;
+                     }
+ 
 -                    if (c->changeMode == Floating)
 -                        AttachDevice(client, ptr, NULL);
 -                    else
 +                    rc = dixLookupDevice(&newmaster, c->new_master,
 +                            client, DixWriteAccess);
 +                    if (rc != Success)
 +                        goto unwind;
 +                    if (!newmaster->isMaster)
                      {
 -                        DeviceIntPtr newmaster;
 -                        rc = dixLookupDevice(&newmaster, c->newMaster,
 -                                             client, DixWriteAccess);
 -                        if (rc != Success)
 -                            goto unwind;
 -                        if (!newmaster->isMaster)
 -                        {
 -                            client->errorValue = c->newMaster;
 -                            rc = BadDevice;
 -                            goto unwind;
 -                        }
 +                        client->errorValue = c->new_master;
 +                        rc = BadDevice;
 +                        goto unwind;
 +                    }
  
 -                        if (!((IsPointerDevice(newmaster) &&
 +                    if (!((IsPointerDevice(newmaster) &&
                                      IsPointerDevice(ptr)) ||
                                  (IsKeyboardDevice(newmaster) &&
                                   IsKeyboardDevice(ptr))))
diff --cc include/input.h
index bc9c5be,56c3d29..e3509a9
--- a/include/input.h
+++ b/include/input.h
@@@ -469,11 -468,12 +469,12 @@@ extern int AttachDevice(ClientPtr clien
  
  extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
  
- extern int AllocMasterDevice(ClientPtr client,
 -extern _X_EXPORT int AllocDevicePair(ClientPtr client,
++extern int AllocDevicePair(ClientPtr client,
                               char* name,
                               DeviceIntPtr* ptr,
-                              DeviceIntPtr* keybd);
+                              DeviceIntPtr* keybd,
+                              Bool master);
 -extern _X_EXPORT void DeepCopyDeviceClasses(DeviceIntPtr from,
 +extern void DeepCopyDeviceClasses(DeviceIntPtr from,
                                    DeviceIntPtr to);
  
  /* Helper functions. */
@@@ -481,16 -481,11 +482,20 @@@ extern int generate_modkeymap(ClientPt
                                KeyCode **modkeymap, int *max_keys_per_mod);
  extern int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *map,
                           int max_keys_per_mod);
+ extern int AllocXtstDevice(ClientPtr client,
+                              char* name,
+                              DeviceIntPtr* ptr,
+                              DeviceIntPtr* keybd);
  
 +/* misc event helpers */
 +extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
 +extern Mask GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev);
 +void FixUpEventFromWindow(DeviceIntPtr pDev,
 +                          xEvent *xE,
 +                          WindowPtr pWin,
 +                          Window child,
 +                          Bool calcChild);
 +
  /* Implemented by the DDX. */
  extern _X_EXPORT int NewInputDeviceRequest(
      InputOption *options,
commit 95628b797e2b326ae15406df4f736e25f5d2f12f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Apr 20 14:04:54 2009 +1000

    Xi: use the XI2 defines for AsyncPair, SyncDevice, etc, not the XI ones.
    
    And don't allow some values on SDs either.

diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c
index 5712557..a8cf1b6 100644
--- a/Xi/xiallowev.c
+++ b/Xi/xiallowev.c
@@ -72,23 +72,26 @@ ProcXIAllowEvents(ClientPtr client)
     time = ClientTimeToServerTime(stuff->time);
 
     switch (stuff->mode) {
-    case ReplayThisDevice:
+    case ReplayDevice:
 	AllowSome(client, time, dev, NOT_GRABBED);
 	break;
-    case SyncThisDevice:
+    case SyncDevice:
 	AllowSome(client, time, dev, FREEZE_NEXT_EVENT);
 	break;
-    case AsyncThisDevice:
+    case AsyncDevice:
 	AllowSome(client, time, dev, THAWED);
 	break;
-    case AsyncOtherDevices:
-	AllowSome(client, time, dev, THAW_OTHERS);
+    case AsyncPairedDevice:
+        if (dev->isMaster)
+            AllowSome(client, time, dev, THAW_OTHERS);
 	break;
-    case SyncAll:
-	AllowSome(client, time, dev, FREEZE_BOTH_NEXT_EVENT);
+    case SyncPair:
+        if (dev->isMaster)
+            AllowSome(client, time, dev, FREEZE_BOTH_NEXT_EVENT);
 	break;
-    case AsyncAll:
-	AllowSome(client, time, dev, THAWED_BOTH);
+    case AsyncPair:
+        if (dev->isMaster)
+            AllowSome(client, time, dev, THAWED_BOTH);
 	break;
     default:
 	client->errorValue = stuff->mode;
commit d5ad14c8ed4d8360e1df8cd0bacf6a7c9c31df91
Merge: 54716fd... 0e0642e...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 19 22:28:22 2009 +1000

    Merge branch 'master' into xi2

commit 54716fd3dbc251db9d251d1d0435942efaa63259
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 19 22:12:11 2009 +1000

    Convert to using int32_t fixed point values on the wire.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 6d85b1b..af14431 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1220,8 +1220,8 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     xi2event->deviceid     = dev->id;
     xi2event->sourceid     = 0; /*XXX */
     xi2event->mode         = mode;
-    xi2event->root_x.integral      = mouse->spriteInfo->sprite->hot.x;
-    xi2event->root_y.integral      = mouse->spriteInfo->sprite->hot.y;
+    xi2event->root_x       = FP1616(mouse->spriteInfo->sprite->hot.x, 0);
+    xi2event->root_y       = FP1616(mouse->spriteInfo->sprite->hot.y, 0);
 
     for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
         if (BitIsOn(mouse->button->down, i))
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 9628dff..fa7031e 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -628,14 +628,10 @@ SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to)
     swapl(&to->root, n);
     swapl(&to->event, n);
     swapl(&to->child, n);
-    swaps(&to->root_x.integral, n);
-    swaps(&to->root_x.frac, n);
-    swaps(&to->root_y.integral, n);
-    swaps(&to->root_y.frac, n);
-    swaps(&to->event_x.integral, n);
-    swaps(&to->event_x.frac, n);
-    swaps(&to->event_y.integral, n);
-    swaps(&to->event_y.frac, n);
+    swapl(&to->root_x, n);
+    swapl(&to->root_y, n);
+    swapl(&to->event_x, n);
+    swapl(&to->event_y, n);
     swaps(&to->sourceid, n);
     swaps(&to->buttons_len, n);
     swapl(&to->mods.base_mods, n);
@@ -721,14 +717,10 @@ static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to)
     swapl(&to->root, n);
     swapl(&to->event, n);
     swapl(&to->child, n);
-    swapl(&to->root_x.integral, n);
-    swapl(&to->root_x.frac, n);
-    swapl(&to->root_y.integral, n);
-    swapl(&to->root_y.frac, n);
-    swapl(&to->event_x.integral, n);
-    swapl(&to->event_x.frac, n);
-    swapl(&to->event_y.integral, n);
-    swapl(&to->event_y.frac, n);
+    swapl(&to->root_x, n);
+    swapl(&to->root_y, n);
+    swapl(&to->event_x, n);
+    swapl(&to->event_y, n);
     swaps(&to->buttons_len, n);
     swaps(&to->valuators_len, n);
     swaps(&to->sourceid, n);
diff --git a/Xi/querydp.c b/Xi/querydp.c
index 5be0cea..1b45ae2 100644
--- a/Xi/querydp.c
+++ b/Xi/querydp.c
@@ -42,6 +42,7 @@
 #include "extnsionst.h"
 #include "exevents.h"
 #include "exglobals.h"
+#include "eventconvert.h"
 #include "xkbsrv.h"
 
 #ifdef PANORAMIX
@@ -110,16 +111,16 @@ ProcXIQueryDevicePointer(ClientPtr client)
     if (kbd && kbd->key)
         rep.mask |= XkbStateFieldFromRec(&kbd->key->xkbInfo->state);
     rep.root = (GetCurrentRootWindow(pDev))->drawable.id;
-    rep.root_x.integral = pSprite->hot.x;
-    rep.root_y.integral = pSprite->hot.y;
+    rep.root_x = FP1616(pSprite->hot.x, 0);
+    rep.root_y = FP1616(pSprite->hot.y, 0);
     rep.child = None;
     rep.deviceid = pDev->id;
 
     if (pSprite->hot.pScreen == pWin->drawable.pScreen)
     {
         rep.same_screen = xTrue;
-        rep.win_x.integral = pSprite->hot.x - pWin->drawable.x;
-        rep.win_y.integral = pSprite->hot.y - pWin->drawable.y;
+        rep.win_x = FP1616(pSprite->hot.x - pWin->drawable.x, 0);
+        rep.win_y = FP1616(pSprite->hot.y - pWin->drawable.y, 0);
         for (t = pSprite->win; t; t = t->parent)
             if (t->parent == pWin)
             {
@@ -129,18 +130,18 @@ ProcXIQueryDevicePointer(ClientPtr client)
     } else
     {
         rep.same_screen = xFalse;
-        rep.win_x.integral = 0;
-        rep.win_y.integral = 0;
+        rep.win_x = 0;
+        rep.win_y = 0;
     }
 
 #ifdef PANORAMIX
     if(!noPanoramiXExtension) {
-        rep.root_x.integral += panoramiXdataPtr[0].x;
-        rep.root_y.integral += panoramiXdataPtr[0].y;
+        rep.root_x += FP1616(panoramiXdataPtr[0].x, 0);
+        rep.root_y += FP1616(panoramiXdataPtr[0].y, 0);
         if (stuff->win == rep.root)
         {
-            rep.win_x.integral += panoramiXdataPtr[0].x;
-            rep.win_y.integral += panoramiXdataPtr[0].y;
+            rep.win_x += FP1616(panoramiXdataPtr[0].x, 0);
+            rep.win_y += FP1616(panoramiXdataPtr[0].y, 0);
         }
     }
 #endif
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index b69d9d3..d97ed81 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -47,6 +47,7 @@
 #include "eventconvert.h"
 #include "querydev.h"
 
+
 static int countValuators(DeviceEvent *ev, int *first);
 static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
 static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
@@ -384,8 +385,8 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
     xde->valuators_len  = vallen;
     xde->deviceid       = ev->deviceid;
     xde->sourceid       = ev->sourceid;
-    xde->root_x.integral = ev->root_x;
-    xde->root_y.integral = ev->root_y;
+    xde->root_x         = FP1616(ev->root_x, 0);
+    xde->root_y         = FP1616(ev->root_y, 0);
 
     xde->mods.base_mods         = ev->mods.base;
     xde->mods.latched_mods      = ev->mods.latched;
diff --git a/dix/events.c b/dix/events.c
index a308422..1057eb4 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2226,13 +2226,13 @@ FixUpEventFromWindow(
         event->event = pWin->drawable.id;
         if (pSprite->hot.pScreen == pWin->drawable.pScreen)
         {
-            event->event_x.integral = event->root_x.integral - pWin->drawable.x;
-            event->event_y.integral = event->root_y.integral - pWin->drawable.y;
+            event->event_x = FP1616(event->root_x - pWin->drawable.x, 0);
+            event->event_y = FP1616(event->root_y - pWin->drawable.y, 0);
             event->child = child;
         } else
         {
-            event->event_x.integral = 0;
-            event->event_y.integral = 0;
+            event->event_x = 0;
+            event->event_y = 0;
             event->child = None;
         }
 
@@ -4161,8 +4161,8 @@ DeviceEnterLeaveEvent(
     event->deviceid     = mouse->id;
     event->sourceid     = 0; /*XXX */
     event->mode         = mode;
-    event->root_x.integral      = mouse->spriteInfo->sprite->hot.x;
-    event->root_y.integral      = mouse->spriteInfo->sprite->hot.y;
+    event->root_x       = FP1616(mouse->spriteInfo->sprite->hot.x, 0);
+    event->root_y       = FP1616(mouse->spriteInfo->sprite->hot.y, 0);
 
     for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
         if (BitIsOn(mouse->button->down, i))
diff --git a/include/eventconvert.h b/include/eventconvert.h
index f458af7..dc3fd73 100644
--- a/include/eventconvert.h
+++ b/include/eventconvert.h
@@ -28,6 +28,8 @@
 #include "input.h"
 #include "events.h"
 
+#define FP1616(integral, frac) (integral * (1 << 16) + frac * (1 << 16))
+
 _X_INTERNAL int EventToCore(InternalEvent *event, xEvent *core);
 _X_INTERNAL int EventToXI(InternalEvent *ev, xEvent **xi, int *count);
 _X_INTERNAL int EventToXI2(InternalEvent *ev, xEvent **xi);
commit 129ac9a9145323e3f126590b491e718f976f80ce
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 19 21:31:56 2009 +1000

    dix: set root_x/y for device events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 8b973a5..b69d9d3 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -384,6 +384,8 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
     xde->valuators_len  = vallen;
     xde->deviceid       = ev->deviceid;
     xde->sourceid       = ev->sourceid;
+    xde->root_x.integral = ev->root_x;
+    xde->root_y.integral = ev->root_y;
 
     xde->mods.base_mods         = ev->mods.base;
     xde->mods.latched_mods      = ev->mods.latched;
commit eeb1e4cd254c047539933c3b886037e67ef30762
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 15 22:17:15 2009 +1000

    Xi: add support for XIAllowEvents.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 32510f2..1fa7b9a 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -92,6 +92,8 @@ libXi_la_SOURCES =	\
 	ungrdevk.h \
 	warpdevp.c \
 	warpdevp.h \
+	xiallowev.c \
+	xiallowev.h \
 	xigrabdev.c \
 	xigrabdev.h \
 	xiproperty.c \
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 9d3b5e6..9628dff 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -119,6 +119,7 @@ SOFTWARE.
 #include "ungrdevb.h"
 #include "ungrdevk.h"
 #include "warpdevp.h"
+#include "xiallowev.h"
 #include "xiselectev.h"
 #include "xigrabdev.h"
 #include "xisetdevfocus.h"
@@ -245,7 +246,8 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXISetDeviceFocus,                   /* 49 */
         ProcXIGetDeviceFocus,                   /* 50 */
         ProcXIGrabDevice,                       /* 51 */
-        ProcXIUngrabDevice                      /* 52 */
+        ProcXIUngrabDevice,                     /* 52 */
+        ProcXIAllowEvents                       /* 53 */
 };
 
 /* For swapped clients */
@@ -302,7 +304,8 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXISetDeviceFocus,                   /* 49 */
         SProcXIGetDeviceFocus,                   /* 50 */
         SProcXIGrabDevice,                       /* 51 */
-        SProcXIUngrabDevice                      /* 52 */
+        SProcXIUngrabDevice,                     /* 52 */
+        SProcXIAllowEvents                       /* 53 */
 };
 
 /*****************************************************************
diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c
new file mode 100644
index 0000000..5712557
--- /dev/null
+++ b/Xi/xiallowev.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+/***********************************************************************
+ *
+ * Request to allow some device events.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h"	/* DeviceIntPtr      */
+#include "windowstr.h"	/* window structure  */
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XI2proto.h>
+
+#include "exglobals.h" /* BadDevice */
+#include "xiallowev.h"
+
+int
+SProcXIAllowEvents(ClientPtr client)
+{
+    char n;
+
+    REQUEST(xXIAllowEventsReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->time, n);
+
+    return ProcXIAllowEvents(client);
+}
+
+int
+ProcXIAllowEvents(ClientPtr client)
+{
+    TimeStamp time;
+    DeviceIntPtr dev;
+    int ret = Success;
+
+    REQUEST(xXIAllowEventsReq);
+    REQUEST_SIZE_MATCH(xXIAllowEventsReq);
+
+    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
+    if (ret != Success)
+	return ret;
+
+    time = ClientTimeToServerTime(stuff->time);
+
+    switch (stuff->mode) {
+    case ReplayThisDevice:
+	AllowSome(client, time, dev, NOT_GRABBED);
+	break;
+    case SyncThisDevice:
+	AllowSome(client, time, dev, FREEZE_NEXT_EVENT);
+	break;
+    case AsyncThisDevice:
+	AllowSome(client, time, dev, THAWED);
+	break;
+    case AsyncOtherDevices:
+	AllowSome(client, time, dev, THAW_OTHERS);
+	break;
+    case SyncAll:
+	AllowSome(client, time, dev, FREEZE_BOTH_NEXT_EVENT);
+	break;
+    case AsyncAll:
+	AllowSome(client, time, dev, THAWED_BOTH);
+	break;
+    default:
+	client->errorValue = stuff->mode;
+	ret = BadValue;
+    }
+
+    return ret;
+}
+
diff --git a/Xi/xiallowev.h b/Xi/xiallowev.h
new file mode 100644
index 0000000..97a0f25
--- /dev/null
+++ b/Xi/xiallowev.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifndef XIALLOWEV_H
+#define XIALLOWEV_H
+
+int ProcXIAllowEvents(ClientPtr client);
+int SProcXIAllowEvents(ClientPtr client);
+
+#endif
commit 74d0fc3aee05bc4f505274d81dd44c0d2b4368ff
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 16 11:06:52 2009 +1000

    dix: don't allow more than MAX_VALUATORS on one device.
    
    Some keyboards (?) advertise more than MAX_VALUATORS axes. Parts of the
    internal event delivery relies on not having more than MAX_VALUATOR axes, so
    let's cap it down.
    If there's real devices that require more than the current 36, I'm sure we can
    bump this up.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 991beca..6d85b1b 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1119,6 +1119,8 @@ InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval,
 
     if (!dev || !dev->valuator || minval > maxval)
         return;
+    if (axnum >= dev->valuator->numAxes)
+        return;
 
     ax = dev->valuator->axes + axnum;
 
diff --git a/dix/devices.c b/dix/devices.c
index ed6e6bd..1c702dc 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1088,6 +1088,14 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
     if (!dev)
         return FALSE;
 
+    if (numAxes >= MAX_VALUATORS)
+    {
+        LogMessage(X_WARNING,
+                   "Device '%s' has %d axes, only using first %d.\n",
+                   dev->name, numAxes, MAX_VALUATORS);
+        numAxes = MAX_VALUATORS;
+    }
+
     valc = (ValuatorClassPtr)xcalloc(1, sizeof(ValuatorClassRec) +
 				    numAxes * sizeof(AxisInfo) +
 				    numAxes * sizeof(unsigned int));
commit edb70caf21fa5da3c336c47c62218a3f05c635b8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Apr 15 22:16:49 2009 +1000

    dix: remove un-used parameter "core" from AllowSome
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/allowev.c b/Xi/allowev.c
index 5f0753d..96f3b54 100644
--- a/Xi/allowev.c
+++ b/Xi/allowev.c
@@ -104,22 +104,22 @@ ProcXAllowDeviceEvents(ClientPtr client)
 
     switch (stuff->mode) {
     case ReplayThisDevice:
-	AllowSome(client, time, thisdev, NOT_GRABBED, FALSE);
+	AllowSome(client, time, thisdev, NOT_GRABBED);
 	break;
     case SyncThisDevice:
-	AllowSome(client, time, thisdev, FREEZE_NEXT_EVENT, FALSE);
+	AllowSome(client, time, thisdev, FREEZE_NEXT_EVENT);
 	break;
     case AsyncThisDevice:
-	AllowSome(client, time, thisdev, THAWED, FALSE);
+	AllowSome(client, time, thisdev, THAWED);
 	break;
     case AsyncOtherDevices:
-	AllowSome(client, time, thisdev, THAW_OTHERS, FALSE);
+	AllowSome(client, time, thisdev, THAW_OTHERS);
 	break;
     case SyncAll:
-	AllowSome(client, time, thisdev, FREEZE_BOTH_NEXT_EVENT, FALSE);
+	AllowSome(client, time, thisdev, FREEZE_BOTH_NEXT_EVENT);
 	break;
     case AsyncAll:
-	AllowSome(client, time, thisdev, THAWED_BOTH, FALSE);
+	AllowSome(client, time, thisdev, THAWED_BOTH);
 	break;
     default:
 	client->errorValue = stuff->mode;
diff --git a/dix/events.c b/dix/events.c
index 96f3579..a308422 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1627,8 +1627,7 @@ void
 AllowSome(ClientPtr client,
           TimeStamp time,
           DeviceIntPtr thisDev,
-          int newState,
-          Bool core)
+          int newState)
 {
     Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
     TimeStamp grabTime;
@@ -1770,28 +1769,28 @@ ProcAllowEvents(ClientPtr client)
     switch (stuff->mode)
     {
 	case ReplayPointer:
-	    AllowSome(client, time, mouse, NOT_GRABBED, True);
+	    AllowSome(client, time, mouse, NOT_GRABBED);
 	    break;
 	case SyncPointer:
-	    AllowSome(client, time, mouse, FREEZE_NEXT_EVENT, True);
+	    AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
 	    break;
 	case AsyncPointer:
-	    AllowSome(client, time, mouse, THAWED, True);
+	    AllowSome(client, time, mouse, THAWED);
 	    break;
 	case ReplayKeyboard:
-	    AllowSome(client, time, keybd, NOT_GRABBED, True);
+	    AllowSome(client, time, keybd, NOT_GRABBED);
 	    break;
 	case SyncKeyboard:
-	    AllowSome(client, time, keybd, FREEZE_NEXT_EVENT, True);
+	    AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
 	    break;
 	case AsyncKeyboard:
-	    AllowSome(client, time, keybd, THAWED, True);
+	    AllowSome(client, time, keybd, THAWED);
 	    break;
 	case SyncBoth:
-	    AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT, True);
+	    AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
 	    break;
 	case AsyncBoth:
-	    AllowSome(client, time, keybd, THAWED_BOTH, True);
+	    AllowSome(client, time, keybd, THAWED_BOTH);
 	    break;
 	default:
 	    client->errorValue = stuff->mode;
diff --git a/include/dix.h b/include/dix.h
index d4e5039..97dc9cc 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -353,8 +353,7 @@ extern void AllowSome(
     ClientPtr	/* client */,
     TimeStamp /* time */,
     DeviceIntPtr /* thisDev */,
-    int /* newState */,
-    Bool /* core */);
+    int /* newState */);
 
 extern void ReleaseActiveGrabs(
     ClientPtr client);
commit bb5418d4901017c657031181d3839f58b387a2a3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 12 22:22:21 2009 +1000

    Xi: Add support for XI2 active grabs and ungrabs.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index 9b1310b..9d3b5e6 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -120,6 +120,7 @@ SOFTWARE.
 #include "ungrdevk.h"
 #include "warpdevp.h"
 #include "xiselectev.h"
+#include "xigrabdev.h"
 #include "xisetdevfocus.h"
 #include "xiproperty.h"
 
@@ -242,7 +243,9 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXIQueryVersion,                     /* 47 */
         ProcXIQueryDevice,                      /* 48 */
         ProcXISetDeviceFocus,                   /* 49 */
-        ProcXIGetDeviceFocus                    /* 50 */
+        ProcXIGetDeviceFocus,                   /* 50 */
+        ProcXIGrabDevice,                       /* 51 */
+        ProcXIUngrabDevice                      /* 52 */
 };
 
 /* For swapped clients */
@@ -297,7 +300,9 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXIQueryVersion,                     /* 47 */
         SProcXIQueryDevice,                      /* 48 */
         SProcXISetDeviceFocus,                   /* 49 */
-        SProcXIGetDeviceFocus                    /* 50 */
+        SProcXIGetDeviceFocus,                   /* 50 */
+        SProcXIGrabDevice,                       /* 51 */
+        SProcXIUngrabDevice                      /* 52 */
 };
 
 /*****************************************************************
@@ -488,6 +493,8 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
         SRepXIGetClientPointer(client, len, (xXIGetClientPointerReply*) rep);
     else if (rep->RepType == X_XIQueryDevice)
         SRepXIQueryDevice(client, len, (xXIQueryDeviceReply*)rep);
+    else if (rep->RepType == X_XIGrabDevice)
+	SRepXIGrabDevice(client, len, (xXIGrabDeviceReply *) rep);
     else {
 	FatalError("XINPUT confused sending swapped reply");
     }
diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c
index ef055f5..0e86aa3 100644
--- a/Xi/xigrabdev.c
+++ b/Xi/xigrabdev.c
@@ -63,7 +63,8 @@ ProcXIGrabDevice(ClientPtr client)
     DeviceIntPtr dev;
     xXIGrabDeviceReply rep;
     int ret = Success;
-    int status;
+    uint8_t status;
+    GrabMask mask;
 
     REQUEST(xXIGrabDeviceReq);
     REQUEST_AT_LEAST_SIZE(xXIGetDeviceFocusReq);
@@ -75,14 +76,17 @@ ProcXIGrabDevice(ClientPtr client)
     if (!dev->isMaster)
         stuff->paired_device_mode = GrabModeAsync;
 
+    memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
+    memcpy(mask.xi2mask, (char*)&stuff[1], stuff->mask_len * 4);
+
     ret = GrabDevice(client, dev, stuff->grab_mode,
                      stuff->paired_device_mode,
                      stuff->grab_window,
                      stuff->owner_events,
                      stuff->time,
-                     0 /* mask */,
+                     &mask,
                      GRABTYPE_XI2,
-                     None /* cursor */,
+                     stuff->cursor,
                      None /* confineTo */,
                      &status);
 
@@ -100,3 +104,50 @@ ProcXIGrabDevice(ClientPtr client)
     return ret;
 }
 
+int
+SProcXIUngrabDevice(ClientPtr client)
+{
+    char n;
+
+    REQUEST(xXIUngrabDeviceReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->time, n);
+
+    return ProcXIUngrabDevice(client);
+}
+
+int
+ProcXIUngrabDevice(ClientPtr client)
+{
+    DeviceIntPtr dev;
+    GrabPtr grab;
+    int ret = Success;
+    TimeStamp time;
+
+    REQUEST(xXIUngrabDeviceReq);
+
+    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
+    if (ret != Success)
+	return ret;
+
+    grab = dev->deviceGrab.grab;
+
+    time = ClientTimeToServerTime(stuff->time);
+    if ((CompareTimeStamps(time, currentTime) != LATER) &&
+	(CompareTimeStamps(time, dev->deviceGrab.grabTime) != EARLIER) &&
+	(grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_XI2)
+	(*dev->deviceGrab.DeactivateGrab) (dev);
+
+    return Success;
+}
+
+void SRepXIGrabDevice(ClientPtr client, int size, xXIGrabDeviceReply * rep)
+{
+    char n;
+
+    swaps(&rep->sequenceNumber, n);
+    swapl(&rep->length, n);
+    WriteToClient(client, size, (char *)rep);
+}
diff --git a/Xi/xigrabdev.h b/Xi/xigrabdev.h
index 327d4d5..6136997 100644
--- a/Xi/xigrabdev.h
+++ b/Xi/xigrabdev.h
@@ -29,4 +29,9 @@
 int ProcXIGrabDevice(ClientPtr client);
 int SProcXIGrabDevice(ClientPtr client);
 
+int ProcXIUngrabDevice(ClientPtr client);
+int SProcXIUngrabDevice(ClientPtr client);
+
+void SRepXIGrabDevice(ClientPtr client, int size, xXIGrabDeviceReply * rep);
+
 #endif
commit c11ef87931f920ba782ba4e9b47d9c31ad7c1cf7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 12 22:16:14 2009 +1000

    Xi: take XI2 requests into account when checking opcodes.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/extinit.c b/Xi/extinit.c
index bedd750..9b1310b 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -391,7 +391,7 @@ static int
 ProcIDispatch(ClientPtr client)
 {
     REQUEST(xReq);
-    if (stuff->data > IREQUESTS || !ProcIVector[stuff->data])
+    if (stuff->data > (IREQUESTS + XI2REQUESTS) || !ProcIVector[stuff->data])
         return BadRequest;
 
     return (*ProcIVector[stuff->data])(client);
commit c94ea5bc055e4efc323e84b7a8266e8b8a4af48e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 12 17:38:28 2009 +1000

    input: use a GrabMask union in GrabDevice to allow for XI2 masks.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/grabdev.c b/Xi/grabdev.c
index 65997ac..6827fd1 100644
--- a/Xi/grabdev.c
+++ b/Xi/grabdev.c
@@ -104,6 +104,7 @@ ProcXGrabDevice(ClientPtr client)
     int rc;
     xGrabDeviceReply rep;
     DeviceIntPtr dev;
+    GrabMask mask;
     struct tmask tmp[EMASKSIZE];
 
     REQUEST(xGrabDeviceReq);
@@ -126,10 +127,12 @@ ProcXGrabDevice(ClientPtr client)
 				 X_GrabDevice)) != Success)
 	return rc;
 
+    mask.xi = tmp[stuff->deviceid].mask;
+
     rc = GrabDevice(client, dev, stuff->other_devices_mode,
                     stuff->this_device_mode, stuff->grabWindow,
 		    stuff->ownerEvents, stuff->time,
-		    tmp[stuff->deviceid].mask, FALSE, None, None,
+		    &mask, FALSE, None, None,
 		    &rep.status);
 
     if (rc != Success)
diff --git a/dix/events.c b/dix/events.c
index dfbc496..96f3579 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4395,6 +4395,7 @@ ProcGrabPointer(ClientPtr client)
     xGrabPointerReply rep;
     DeviceIntPtr device = PickPointer(client);
     GrabPtr grab;
+    GrabMask mask;
     WindowPtr confineTo;
     CursorPtr oldCursor;
     REQUEST(xGrabPointerReq);
@@ -4431,9 +4432,11 @@ ProcGrabPointer(ClientPtr client)
         oldCursor = grab->cursor;
     }
 
+    mask.core = stuff->eventMask;
+
     rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode,
                     stuff->grabWindow, stuff->ownerEvents, stuff->time,
-                    stuff->eventMask, GRABTYPE_CORE, stuff->cursor,
+                    &mask, GRABTYPE_CORE, stuff->cursor,
                     stuff->confineTo, &rep.status);
     if (rc != Success)
         return rc;
@@ -4551,7 +4554,7 @@ ProcUngrabPointer(ClientPtr client)
 int
 GrabDevice(ClientPtr client, DeviceIntPtr dev,
            unsigned pointer_mode, unsigned keyboard_mode, Window grabWindow,
-           unsigned ownerEvents, Time ctime, Mask mask,
+           unsigned ownerEvents, Time ctime, GrabMask *mask,
            int grabtype, Cursor curs, Window confineToWin, CARD8 *status)
 {
     WindowPtr pWin, confineTo;
@@ -4643,7 +4646,12 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
 	tempGrab.ownerEvents = ownerEvents;
 	tempGrab.keyboardMode = keyboard_mode;
 	tempGrab.pointerMode = pointer_mode;
-	tempGrab.eventMask = mask;
+	if (grabtype == GRABTYPE_CORE)
+	    tempGrab.eventMask = mask->core;
+	else if (grabtype == GRABTYPE_XI)
+	    tempGrab.eventMask = mask->xi;
+	else
+	    memcpy(tempGrab.xi2mask, mask->xi2mask, sizeof(tempGrab.xi2mask));
 	tempGrab.device = dev;
 	tempGrab.cursor = cursor;
 	tempGrab.confineTo = confineTo;
@@ -4666,13 +4674,16 @@ ProcGrabKeyboard(ClientPtr client)
     REQUEST(xGrabKeyboardReq);
     int result;
     DeviceIntPtr keyboard = PickKeyboard(client);
+    GrabMask mask;
 
     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
 
     memset(&rep, 0, sizeof(xGrabKeyboardReply));
+    mask.core = KeyPressMask | KeyReleaseMask;
+
     result = GrabDevice(client, keyboard, stuff->pointerMode,
             stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents,
-            stuff->time, KeyPressMask | KeyReleaseMask, GRABTYPE_CORE, None, None,
+            stuff->time, &mask, GRABTYPE_CORE, None, None,
             &rep.status);
 
     if (result != Success)
diff --git a/include/dix.h b/include/dix.h
index 8da2189..d4e5039 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -433,7 +433,7 @@ extern int GrabDevice(
     Window /* grabWindow */,
     unsigned /* ownerEvents */,
     Time /* ctime */,
-    Mask /* mask */,
+    GrabMask* /* mask */,
     int /* grabtype */,
     Cursor /* curs */,
     Window /* confineToWin */,
diff --git a/include/input.h b/include/input.h
index baac054..bc9c5be 100644
--- a/include/input.h
+++ b/include/input.h
@@ -103,6 +103,7 @@ typedef struct _OtherClients *OtherClientsPtr;
 typedef struct _InputClients *InputClientsPtr;
 typedef struct _DeviceIntRec *DeviceIntPtr;
 typedef struct _ClassesRec *ClassesPtr;
+typedef union _GrabMask GrabMask;
 
 typedef struct _EventList {
     xEvent* event;
diff --git a/include/inputstr.h b/include/inputstr.h
index 7d666c1..e562c0a 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -156,6 +156,12 @@ typedef enum {
     GRABTYPE_XI2
 } GrabType;
 
+union _GrabMask {
+    Mask core;
+    Mask xi;
+    char xi2mask[EMASKSIZE][XI2MASKSIZE];
+};
+
 /**
  * Central struct for device grabs. 
  * The same struct is used for both core grabs and device grabs, with
commit 6bb4b5b93701535402f65ea828348ed7747c7dbf
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 12 16:20:10 2009 +1000

    Xi: add XI2 grab protocol request handling.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index cbec13e..32510f2 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -92,6 +92,8 @@ libXi_la_SOURCES =	\
 	ungrdevk.h \
 	warpdevp.c \
 	warpdevp.h \
+	xigrabdev.c \
+	xigrabdev.h \
 	xiproperty.c \
 	xiproperty.h \
 	xiselectev.c \
diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c
new file mode 100644
index 0000000..ef055f5
--- /dev/null
+++ b/Xi/xigrabdev.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+/***********************************************************************
+ *
+ * Request to grab or ungrab input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h"	/* DeviceIntPtr      */
+#include "windowstr.h"	/* window structure  */
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XI2proto.h>
+
+#include "exglobals.h" /* BadDevice */
+#include "xigrabdev.h"
+
+int
+SProcXIGrabDevice(ClientPtr client)
+{
+    char n;
+
+    REQUEST(xXIGrabDeviceReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->grab_window, n);
+    swapl(&stuff->time, n);
+    swaps(&stuff->mask_len, n);
+
+    return ProcXIGrabDevice(client);
+}
+
+int
+ProcXIGrabDevice(ClientPtr client)
+{
+    DeviceIntPtr dev;
+    xXIGrabDeviceReply rep;
+    int ret = Success;
+    int status;
+
+    REQUEST(xXIGrabDeviceReq);
+    REQUEST_AT_LEAST_SIZE(xXIGetDeviceFocusReq);
+
+    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
+    if (ret != Success)
+	return ret;
+
+    if (!dev->isMaster)
+        stuff->paired_device_mode = GrabModeAsync;
+
+    ret = GrabDevice(client, dev, stuff->grab_mode,
+                     stuff->paired_device_mode,
+                     stuff->grab_window,
+                     stuff->owner_events,
+                     stuff->time,
+                     0 /* mask */,
+                     GRABTYPE_XI2,
+                     None /* cursor */,
+                     None /* confineTo */,
+                     &status);
+
+    if (ret != Success)
+        return ret;
+
+    rep.repType = X_Reply;
+    rep.RepType = X_XIGrabDevice;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.status = status;
+
+
+    WriteReplyToClient(client, sizeof(rep), &rep);
+    return ret;
+}
+
diff --git a/Xi/xigrabdev.h b/Xi/xigrabdev.h
new file mode 100644
index 0000000..327d4d5
--- /dev/null
+++ b/Xi/xigrabdev.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifndef XIGRABDEV_H
+#define XIGRABDEV_H
+
+int ProcXIGrabDevice(ClientPtr client);
+int SProcXIGrabDevice(ClientPtr client);
+
+#endif
commit 09f9a86077f0058ce88ee9b3df5d1ab854eeca43
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Apr 12 16:19:45 2009 +1000

    input: replace GrabRec's coreGrab field with grabtype.
    
    Don't allow grabs of different types to override each other.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 3be5c46..991beca 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1415,7 +1415,7 @@ GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
     grab = CreateGrab(client->index, dev, pWin, eventMask,
 		      (Bool) ownerEvents, (Bool) this_device_mode,
 		      (Bool) other_devices_mode, modifier_device, modifiers,
-		      DeviceButtonPress, button, confineTo, cursor);
+		      DeviceButtonPress, GRABTYPE_XI, button, confineTo, cursor);
     if (!grab)
 	return BadAlloc;
     return AddPassiveGrabToList(client, grab);
@@ -1470,8 +1470,8 @@ GrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
 
     grab = CreateGrab(client->index, dev, pWin,
 		      mask, ownerEvents, this_device_mode, other_devices_mode,
-		      modifier_device, modifiers, DeviceKeyPress, key,
-		      NullWindow, NullCursor);
+		      modifier_device, modifiers, DeviceKeyPress, GRABTYPE_XI,
+		      key, NullWindow, NullCursor);
     if (!grab)
 	return BadAlloc;
     return AddPassiveGrabToList(client, grab);
diff --git a/Xi/ungrdev.c b/Xi/ungrdev.c
index b5b572a..a09c3d0 100644
--- a/Xi/ungrdev.c
+++ b/Xi/ungrdev.c
@@ -104,7 +104,7 @@ ProcXUngrabDevice(ClientPtr client)
     time = ClientTimeToServerTime(stuff->time);
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	(CompareTimeStamps(time, dev->deviceGrab.grabTime) != EARLIER) &&
-	(grab) && SameClient(grab, client) && !grab->coreGrab)
+	(grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_XI)
 	(*dev->deviceGrab.DeactivateGrab) (dev);
     return Success;
 }
diff --git a/dix/events.c b/dix/events.c
index 34ea414..dfbc496 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2057,7 +2057,12 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
 	tempGrab.pointerMode = GrabModeAsync;
 	tempGrab.confineTo = NullWindow;
 	tempGrab.cursor = NullCursor;
-        tempGrab.coreGrab = (type == ButtonPress);
+        if (type == ButtonPress)
+            tempGrab.grabtype = GRABTYPE_CORE;
+        else if (type == DeviceButtonPress)
+            tempGrab.grabtype = GRABTYPE_XI;
+        else
+            tempGrab.grabtype = GRABTYPE_XI2;
 
         /* get the XI and XI2 device mask */
         inputMasks = wOtherInputMasks(pWin);
@@ -3298,7 +3303,7 @@ CheckPassiveGrabsOnWindow(
 	XkbSrvInfoPtr	xkbi = NULL;
 
 	gdev= grab->modifierDevice;
-        if (grab->coreGrab)
+        if (grab->grabtype == GRABTYPE_CORE)
         {
             if (IsPointerDevice(device))
                 gdev = GetPairedDevice(device);
@@ -3351,14 +3356,14 @@ CheckPassiveGrabsOnWindow(
              * device.
              */
 
-            if (grab->coreGrab)
+            if (grab->grabtype == GRABTYPE_CORE)
             {
                 DeviceIntPtr other;
                 BOOL interfering = FALSE;
                 for (other = inputInfo.devices; other; other = other->next)
                 {
                     GrabPtr othergrab = other->deviceGrab.grab;
-                    if (othergrab && othergrab->coreGrab &&
+                    if (othergrab && othergrab->grabtype == GRABTYPE_CORE &&
                         SameClient(grab, rClient(othergrab)) &&
                         ((IsPointerDevice(grab->device) &&
                          IsPointerDevice(othergrab->device)) ||
@@ -3679,7 +3684,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 
         sendCore = (thisDev->isMaster && thisDev->coreEvents);
         /* try core event */
-        if (sendCore && grab->coreGrab)
+        if (sendCore && grab->grabtype == GRABTYPE_CORE)
         {
             xEvent core;
 
@@ -4428,7 +4433,7 @@ ProcGrabPointer(ClientPtr client)
 
     rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode,
                     stuff->grabWindow, stuff->ownerEvents, stuff->time,
-                    stuff->eventMask, TRUE, stuff->cursor,
+                    stuff->eventMask, GRABTYPE_CORE, stuff->cursor,
                     stuff->confineTo, &rep.status);
     if (rc != Success)
         return rc;
@@ -4547,7 +4552,7 @@ int
 GrabDevice(ClientPtr client, DeviceIntPtr dev,
            unsigned pointer_mode, unsigned keyboard_mode, Window grabWindow,
            unsigned ownerEvents, Time ctime, Mask mask,
-           Bool coreGrab, Cursor curs, Window confineToWin, CARD8 *status)
+           int grabtype, Cursor curs, Window confineToWin, CARD8 *status)
 {
     WindowPtr pWin, confineTo;
     GrabPtr grab;
@@ -4610,6 +4615,8 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
 
     time = ClientTimeToServerTime(ctime);
     grab = grabInfo->grab;
+    if (grab && grab->grabtype != grabtype)
+        *status = AlreadyGrabbed;
     if (grab && !SameClient(grab, client))
 	*status = AlreadyGrabbed;
     else if ((!pWin->realized) ||
@@ -4640,7 +4647,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
 	tempGrab.device = dev;
 	tempGrab.cursor = cursor;
 	tempGrab.confineTo = confineTo;
-	tempGrab.coreGrab = coreGrab;
+	tempGrab.grabtype = grabtype;
 	(*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE);
 	*status = GrabSuccess;
     }
@@ -4665,7 +4672,7 @@ ProcGrabKeyboard(ClientPtr client)
     memset(&rep, 0, sizeof(xGrabKeyboardReply));
     result = GrabDevice(client, keyboard, stuff->pointerMode,
             stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents,
-            stuff->time, KeyPressMask | KeyReleaseMask, TRUE, None, None,
+            stuff->time, KeyPressMask | KeyReleaseMask, GRABTYPE_CORE, None, None,
             &rep.status);
 
     if (result != Success)
@@ -4698,7 +4705,7 @@ ProcUngrabKeyboard(ClientPtr client)
     time = ClientTimeToServerTime(stuff->id);
     if ((CompareTimeStamps(time, currentTime) != LATER) &&
 	(CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) &&
-	(grab) && SameClient(grab, client) && grab->coreGrab)
+	(grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_CORE)
 	(*device->deviceGrab.DeactivateGrab)(device);
     return Success;
 }
@@ -5038,7 +5045,7 @@ ProcGrabKey(ClientPtr client)
     grab = CreateGrab(client->index, keybd, pWin,
 	(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
 	(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
-	keybd, stuff->modifiers, KeyPress, stuff->key,
+	keybd, stuff->modifiers, KeyPress, GRABTYPE_CORE, stuff->key,
 	NullWindow, NullCursor);
     if (!grab)
 	return BadAlloc;
@@ -5130,7 +5137,7 @@ ProcGrabButton(ClientPtr client)
     grab = CreateGrab(client->index, ptr, pWin,
         (Mask)stuff->eventMask, (Bool)stuff->ownerEvents,
         (Bool) stuff->keyboardMode, (Bool)stuff->pointerMode,
-        modifierDevice, stuff->modifiers, ButtonPress,
+        modifierDevice, stuff->modifiers, ButtonPress, GRABTYPE_CORE,
         stuff->button, confineTo, cursor);
     if (!grab)
 	return BadAlloc;
@@ -5564,7 +5571,7 @@ PickPointer(ClientPtr client)
     for(it = inputInfo.devices; it; it = it->next)
     {
         GrabPtr grab = it->deviceGrab.grab;
-        if (grab && grab->coreGrab && SameClient(grab, client))
+        if (grab && grab->grabtype == GRABTYPE_CORE && SameClient(grab, client))
         {
             if (!IsPointerDevice(it))
                 it = GetPairedDevice(it);
diff --git a/dix/grabs.c b/dix/grabs.c
index 2d3327c..cd34f7e 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -76,6 +76,7 @@ CreateGrab(
     DeviceIntPtr modDevice,
     unsigned short modifiers,
     int type,
+    int grabtype,
     KeyCode keybut,	/* key or button */
     WindowPtr confineTo,
     CursorPtr cursor)
@@ -87,7 +88,6 @@ CreateGrab(
 	return (GrabPtr)NULL;
     grab->resource = FakeClientID(client);
     grab->device = device;
-    grab->coreGrab = (type < LASTEvent);
     grab->window = window;
     grab->eventMask = eventMask;
     grab->deviceMask = 0;
@@ -98,6 +98,7 @@ CreateGrab(
     grab->modifiersDetail.pMask = NULL;
     grab->modifierDevice = modDevice;
     grab->type = type;
+    grab->grabtype = grabtype;
     grab->detail.exact = keybut;
     grab->detail.pMask = NULL;
     grab->confineTo = confineTo;
@@ -411,7 +412,8 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
 	 grab = grab->next)
     {
 	if ((CLIENT_BITS(grab->resource) != CLIENT_BITS(pMinuendGrab->resource)) ||
-	    !GrabMatchesSecond(grab, pMinuendGrab, (grab->coreGrab)))
+	    !GrabMatchesSecond(grab, pMinuendGrab,
+                               (grab->grabtype == GRABTYPE_CORE)))
 	    continue;
 	if (GrabSupersedesSecond(pMinuendGrab, grab))
 	{
@@ -442,6 +444,7 @@ DeletePassiveGrabFromList(GrabPtr pMinuendGrab)
 				  (Bool)grab->pointerMode,
 				  grab->modifierDevice,
 				  AnyModifier, (int)grab->type,
+                                  grab->grabtype,
 				  pMinuendGrab->detail.exact,
 				  grab->confineTo, grab->cursor);
 	    if (!pNewGrab)
diff --git a/include/dix.h b/include/dix.h
index 14d6843..8da2189 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -434,7 +434,7 @@ extern int GrabDevice(
     unsigned /* ownerEvents */,
     Time /* ctime */,
     Mask /* mask */,
-    Bool /* coreGrab */,
+    int /* grabtype */,
     Cursor /* curs */,
     Window /* confineToWin */,
     CARD8 * /* status */);
diff --git a/include/dixgrabs.h b/include/dixgrabs.h
index 36ab2b9..5127239 100644
--- a/include/dixgrabs.h
+++ b/include/dixgrabs.h
@@ -37,6 +37,7 @@ extern _X_EXPORT GrabPtr CreateGrab(
 	DeviceIntPtr /* modDevice */,
 	unsigned short /* modifiers */,
 	int /* type */,
+	int /* grabtype */,
 	KeyCode /* keybut */,
 	WindowPtr /* confineTo */,
 	CursorPtr /* cursor */);
diff --git a/include/inputstr.h b/include/inputstr.h
index 14941b1..7d666c1 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -150,6 +150,12 @@ typedef struct _DetailRec {		/* Grab details may be bit masks */
     Mask                *pMask;
 } DetailRec;
 
+typedef enum {
+    GRABTYPE_CORE,
+    GRABTYPE_XI,
+    GRABTYPE_XI2
+} GrabType;
+
 /**
  * Central struct for device grabs. 
  * The same struct is used for both core grabs and device grabs, with
@@ -171,7 +177,7 @@ typedef struct _GrabRec {
     unsigned		ownerEvents:1;
     unsigned		keyboardMode:1;
     unsigned		pointerMode:1;
-    unsigned		coreGrab:1;	/* grab is on core device */
+    GrabType		grabtype;
     CARD8		type;		/* event type */
     DetailRec		modifiersDetail;
     DeviceIntPtr	modifierDevice;
commit 7fbe1b7d63c94b344e8ff9d09c0bb162ca104909
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Apr 11 13:10:31 2009 +1000

    Xi: remove the GetExtensionVersion hack.
    
    Squashing data into a request that's defined to be padding is probably not the
    best idea.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/getvers.c b/Xi/getvers.c
index 2ca3bb3..c8eacc1 100644
--- a/Xi/getvers.c
+++ b/Xi/getvers.c
@@ -92,7 +92,6 @@ int
 ProcXGetExtensionVersion(ClientPtr client)
 {
     xGetExtensionVersionReply rep;
-    XIClientPtr pXIClient;
 
     REQUEST(xGetExtensionVersionReq);
     REQUEST_AT_LEAST_SIZE(xGetExtensionVersionReq);
@@ -101,21 +100,6 @@ ProcXGetExtensionVersion(ClientPtr client)
 			  stuff->nbytes + 3) >> 2)
 	return BadLength;
 
-    pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
-
-    /* GetExtensionVersionReq before XI 2 didn't supply the client's
-     * major/minor. So we don't actually have a clue what they support.
-     * {major|minor}Version was added as part of XI, so if they are set, we
-     * know we can trust it. In this case the client must set nbytes to 0
-     * though, otherwise we have to assume that the version are padding
-     * garbage.
-     */
-    if (!stuff->nbytes) /* Client using XQueryInputVersion(). */
-    {
-        pXIClient->major_version = stuff->majorVersion;
-        pXIClient->minor_version = stuff->minorVersion;
-    } /* else version unknown, leave it at 0.0 */
-
     memset(&rep, 0, sizeof(xGetExtensionVersionReply));
     rep.repType = X_Reply;
     rep.RepType = X_GetExtensionVersion;
commit 73e1055b1275470dcc2d53b15898c866d9721d3e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Apr 11 11:19:29 2009 +1000

    Xi: fix a typo in a #ifdef
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xiproperty.h b/Xi/xiproperty.h
index bf562b1..e66b447 100644
--- a/Xi/xiproperty.h
+++ b/Xi/xiproperty.h
@@ -23,8 +23,8 @@
  * Author: Peter Hutterer
  */
 
-#ifndef XIPROPERTY_C
-#define XIPROPERTY_C
+#ifndef XIPROPERTY_H
+#define XIPROPERTY_H
 
 int ProcXListDeviceProperties     (ClientPtr client);
 int ProcXChangeDeviceProperty     (ClientPtr client);
@@ -43,4 +43,4 @@ void SRepXListDeviceProperties(ClientPtr client, int size,
 void SRepXGetDeviceProperty(ClientPtr client, int size,
                             xGetDevicePropertyReply *rep);
 
-#endif /* XIPROPERTY_C */
+#endif /* XIPROPERTY_H */
commit cbbc7fed994448852961a987a8b0eadf718b24bf
Author: Simon Thum <simon.thum at gmx.de>
Date:   Wed Apr 1 10:53:10 2009 +0200

    dix: correctly utilize tracker buffer and protect from timer overruns
    
    two small related fixes hard to split up
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 92dc589..1590cfd 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -98,7 +98,7 @@ InitVelocityData(DeviceVelocityPtr s)
     s->min_acceleration = 1.0; /* don't decelerate */
     s->max_rel_diff = 0.2;
     s->max_diff = 1.0;
-    s->initial_range = 1;
+    s->initial_range = 2;
     s->average_accel = TRUE;
     SetAccelerationProfile(s, AccelProfileClassic);
     InitTrackers(s, 16);
@@ -445,8 +445,8 @@ FeedTrackers(DeviceVelocityPtr s, int dx, int dy, int cur_t)
 	s->tracker[n].dy += dy;
     }
     n = (s->cur_tracker + 1) % s->num_tracker;
-    s->tracker[n].dx = dx;
-    s->tracker[n].dy = dy;
+    s->tracker[n].dx = 0;
+    s->tracker[n].dy = 0;
     s->tracker[n].time = cur_t;
     s->tracker[n].dir = GetDirection(dx, dy);
     DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
@@ -465,7 +465,7 @@ CalcTracker(DeviceVelocityPtr s, int offset, int cur_t){
     int index = TRACKER_INDEX(s, offset);
     float dist = sqrt(  s->tracker[index].dx * s->tracker[index].dx
                       + s->tracker[index].dy * s->tracker[index].dy);
-    int dtime = cur_t - s->tracker[TRACKER_INDEX(s, offset+1)].time;
+    int dtime = cur_t - s->tracker[index].time;
     if(dtime > 0)
 	return (dist / dtime);
     else
@@ -476,20 +476,22 @@ CalcTracker(DeviceVelocityPtr s, int offset, int cur_t){
  * (in time) tracker which isn't too old, beyond a linear partition,
  * or simply too much off initial velocity.
  *
- * min_t should be (now - ~100-600 ms). May return 0.
+ * May return 0.
  */
 static float
-QueryTrackers(DeviceVelocityPtr s, int min_t, int cur_t){
-    int n, offset, dir = 255, i = -1;
+QueryTrackers(DeviceVelocityPtr s, int cur_t){
+    int n, offset, dir = 255, i = -1, age_ms;
     /* initial velocity: a low-offset, valid velocity */
     float iveloc = 0, res = 0, tmp, vdiff;
     float vfac =  s->corr_mul * s->const_acceleration; /* premultiply */
     /* loop from current to older data */
-    for(offset = 0; offset < s->num_tracker-1; offset++){
+    for(offset = 1; offset < s->num_tracker; offset++){
 	n = TRACKER_INDEX(s, offset);
 
-	/* bail out if data is too old */
-	if(s->tracker[TRACKER_INDEX(s, offset+1)].time < min_t){
+	age_ms = cur_t - s->tracker[n].time;
+
+	/* bail out if data is too old and protect from overrun */
+	if (age_ms >= s->reset_time || age_ms < 0) {
 	    DebugAccelF("(dix prtacc) query: tracker too old\n");
 	    break;
 	}
@@ -566,7 +568,7 @@ ProcessVelocityData2D(
 
     FeedTrackers(s, dx, dy, time);
 
-    velocity = QueryTrackers(s, time - s->reset_time, time);
+    velocity = QueryTrackers(s, time);
 
     s->velocity = velocity;
     return velocity == 0;
commit ca4918ac2ff003142aefbd8ac7ec2bc398ccc6eb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 9 19:31:04 2009 +1000

    Xi: remove fail from SProcXISelectEvent.
    
    Leftover from rebasing once too often, I guess.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index cdb9c6f..607b9b4 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -42,7 +42,6 @@ SProcXISelectEvent(ClientPtr client)
     char n;
     int i;
     xXIDeviceEventMask* evmask;
-    uint16_t *evtype;
 
     REQUEST(xXISelectEventsReq);
     swaps(&stuff->length, n);
@@ -55,7 +54,7 @@ SProcXISelectEvent(ClientPtr client)
     {
         swaps(&evmask->deviceid, n);
         swaps(&evmask->mask_len, n);
-        evmask = (xXIDeviceEventMask*)(((char*)evtype) + evmask->mask_len * 4);
+        evmask = (xXIDeviceEventMask*)(((char*)evmask) + evmask->mask_len * 4);
     }
 
     return (ProcXISelectEvent(client));
commit 463676f016a105a790cbb386d20eb5b188c04652
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 9 19:11:59 2009 +1000

    Xi: remove un-used variable pXIClient
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/opendev.c b/Xi/opendev.c
index 833ecbb..4ad5af2 100644
--- a/Xi/opendev.c
+++ b/Xi/opendev.c
@@ -97,7 +97,6 @@ ProcXOpenDevice(ClientPtr client)
     int status = Success;
     xOpenDeviceReply rep;
     DeviceIntPtr dev;
-    XIClientPtr pXIClient;
 
     REQUEST(xOpenDeviceReq);
     REQUEST_SIZE_MATCH(xOpenDeviceReq);
commit 32b13ec4cd42842a133aa6428f49638b0448efc9
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 9 19:11:27 2009 +1000

    Xi: silence compiler warnings about "wrong" event types.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 4aa5fbf..3be5c46 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -919,7 +919,7 @@ ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
     GrabPtr grab = device->deviceGrab.grab;
 
     if (grab)
-        DeliverGrabbedEvent(ev, device, FALSE);
+        DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE);
     else { /* deliver to all root windows */
         xEvent *xi;
         int i;
@@ -1077,12 +1077,13 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
 
 
     if (grab)
-        DeliverGrabbedEvent(event, device, deactivateDeviceGrab);
+        DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab);
     else if (device->focus && !IsPointerEvent((InternalEvent*)ev))
-	DeliverFocusedEvent(device, event, GetSpriteWindow(device));
+        DeliverFocusedEvent(device, (InternalEvent*)event,
+                            GetSpriteWindow(device));
     else
-	DeliverDeviceEvents(GetSpriteWindow(device), event, NullGrab,
-                            NullWindow, device);
+        DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event,
+                            NullGrab, NullWindow, device);
 
     if (deactivateDeviceGrab == TRUE)
 	(*device->deviceGrab.DeactivateGrab) (device);
commit f2e957c5342aefc8329e9fe282b7072f767fcd28
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 9 19:07:36 2009 +1000

    mi: add prototype for CopyGetMasterEvent.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mi.h b/mi/mi.h
index 076cea7..182cea5 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -221,6 +221,13 @@ extern _X_EXPORT void mieqProcessInputEvents(
     void
 );
 
+extern void CopyGetMasterEvent(
+    DeviceIntPtr /* mdev */,
+    DeviceIntPtr /* sdev */,
+    InternalEvent* /* original */,
+    EventListPtr /* master */
+);
+
 /**
  * Custom input event handler. If you need to process input events in some
  * other way than the default path, register an input event handler for the
commit d80798ba2ae018086aaf230fcd8bc71d3bf06b11
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 9 20:27:00 2009 +1000

    mi: fix wrong (*EnqueueEvent) declaration in miPointerScreenFuncRec.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mipointer.h b/mi/mipointer.h
index 259ac14..f385b7e 100644
--- a/mi/mipointer.h
+++ b/mi/mipointer.h
@@ -82,7 +82,7 @@ typedef struct _miPointerScreenFuncRec {
                     );
     void	(*EnqueueEvent)(
                     DeviceIntPtr /* pDev */,
-                    xEventPtr /* event */
+                    InternalEvent* /* event */
                     );
     void	(*NewEventScreen)(
 		    DeviceIntPtr /* pDev */,
commit 4dedb900f4fbd3bdc9538b1e82cab2044438a770
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 9 08:42:06 2009 +1000

    xfree86: shut up compiler warnings - typecast to InternalEvent
    
    Reported-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 4f84a4c..19120ce 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -428,7 +428,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
             sigstate = xf86BlockSIGIO ();
             nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i);
             for (j = 0; j < nevents; j++)
-                mieqEnqueue(pDev, (xf86Events + j)->event);
+                mieqEnqueue(pDev, (InternalEvent*)(xf86Events + j)->event);
             xf86UnblockSIGIO(sigstate);
         }
     }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 3a56b49..96aff15 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -792,7 +792,7 @@ xf86PostMotionEventP(DeviceIntPtr	device,
         /* Don't post core motion events for devices not registered to send
          * drag events. */
         if (xE->u.u.type != MotionNotify || drag) {
-            mieqEnqueue(device, (xf86Events + i)->event);
+            mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
         }
     }
 }
@@ -825,7 +825,7 @@ xf86PostProximityEvent(DeviceIntPtr	device,
                                  is_in ? ProximityIn : ProximityOut, 
                                  first_valuator, num_valuators, valuators);
     for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (xf86Events + i)->event);
+        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
 
 }
 
@@ -868,7 +868,7 @@ xf86PostButtonEvent(DeviceIntPtr	device,
                                first_valuator, num_valuators, valuators);
 
     for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (xf86Events + i)->event);
+        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
 
 }
 
@@ -915,7 +915,7 @@ xf86PostKeyEvent(DeviceIntPtr	device,
     }
 
     for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (xf86Events + i)->event);
+        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
 }
 
 void
@@ -944,7 +944,7 @@ xf86PostKeyboardEvent(DeviceIntPtr      device,
                                 is_down ? KeyPress : KeyRelease, key_code);
 
     for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (xf86Events + i)->event);
+        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
 }
 
 LocalDevicePtr
commit 4fa7fcf610d2ab91c1158f8034bbc0531060a86f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 9 08:40:20 2009 +1000

    mi: fix compiler warning - explicitly typecast to InternalEvent.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/mi/mipointer.c b/mi/mipointer.c
index 857a8ca..e87fe79 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -581,7 +581,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
     darwinEvents_lock();
 #endif
     for (i = 0; i < nevents; i++)
-        mieqEnqueue(pDev, events[i].event);
+        mieqEnqueue(pDev, (InternalEvent*)events[i].event);
 #ifdef XQUARTZ
     darwinEvents_unlock();
 #endif
commit 8bf2f562678107c346e8664f18c10f315c2768f5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 9 08:14:39 2009 +1000

    dix: fix dev/keybd variable mixup.
    
    Reported-by: Eric Anhold <eric at anholt.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/devices.c b/dix/devices.c
index 27148d6..ed6e6bd 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1930,14 +1930,14 @@ ProcBell(ClientPtr client)
     else
 	newpercent = base - newpercent + stuff->percent;
 
-    for (keybd = inputInfo.devices; keybd; keybd = keybd->next) {
+    for (dev = inputInfo.devices; dev; dev = dev->next) {
         if ((dev == keybd || (!dev->isMaster && dev->u.master == keybd)) &&
-            keybd->kbdfeed && keybd->kbdfeed->BellProc) {
+            dev->kbdfeed && dev->kbdfeed->BellProc) {
 
 	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess);
 	    if (rc != Success)
 		return rc;
-            XkbHandleBell(FALSE, FALSE, keybd, newpercent,
+            XkbHandleBell(FALSE, FALSE, dev, newpercent,
                           &dev->kbdfeed->ctrl, 0, None, NULL, client);
         }
     }
commit 012cb1956a69f6cf2a878c5331e792fb12c73e9d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Apr 9 08:06:32 2009 +1000

    xfree86: fix use of uninitialized variable in DGAProcessPointerEvent.
    
    Reported-by: Eric Anholt <eric at anholt.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index 4cc530a..f83bcd5 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1088,7 +1088,6 @@ static void
 DGAProcessPointerEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr mouse)
 {
     ButtonClassPtr  butc = mouse->button;
-    int		    coreEquiv;
     DGAScreenPtr    pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
     DeviceEvent     ev;
 
@@ -1107,7 +1106,11 @@ DGAProcessPointerEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr mouse)
     if (pScreenPriv->client)
     {
         dgaEvent        de;
-        de.u.u.type = *XDGAEventBase + GetCoreType((InternalEvent*)&ev);
+        int		coreEquiv;
+
+        coreEquiv = GetCoreType((InternalEvent*)&ev);
+
+        de.u.u.type = *XDGAEventBase + coreEquiv;
         de.u.u.detail = event->detail;
         de.u.event.time = event->time;
         de.u.event.dx = 0;
commit 73b01a9aac5fde46ccd90c08a070e9d2496092b9
Author: Simon Thum <simon.thum at gmx.de>
Date:   Wed Apr 8 14:35:01 2009 +0200

    dix: fix pointer accelerations remainder handling
    
    This didn't really work as intended, but did amazingly well thanks
    to roundf() hiding the defect. Cheers!
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index 2d6763e..92dc589 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -950,7 +950,7 @@ acceleratePointerPredictable(
     int *px = NULL, *py = NULL;
     DeviceVelocityPtr velocitydata =
 	(DeviceVelocityPtr) pDev->valuator->accelScheme.accelData;
-    float fdx, fdy; /* no need to init */
+    float fdx, fdy, tmp; /* no need to init */
     Bool soften = TRUE;
 
     if (!num_valuators || !valuators || !velocitydata)
@@ -985,14 +985,14 @@ acceleratePointerPredictable(
 						       (mult > 1.0) && soften);
 
                 if (dx) {
-                    pDev->last.remainder[0] = roundf(mult * fdx + pDev->last.remainder[0]);
-                    *px = (int)pDev->last.remainder[0];
-                    pDev->last.remainder[0] = pDev->last.remainder[0] - (float)*px;
+                    tmp = mult * fdx + pDev->last.remainder[0];
+                    *px = (int)roundf(tmp);
+                    pDev->last.remainder[0] = tmp - (float)*px;
                 }
                 if (dy) {
-                    pDev->last.remainder[1] = roundf(mult * fdy + pDev->last.remainder[1]);
-                    *py = (int)pDev->last.remainder[1];
-                    pDev->last.remainder[1] = pDev->last.remainder[1] - (float)*py;
+                    tmp = mult * fdy + pDev->last.remainder[1];
+                    *py = (int)roundf(tmp);
+                    pDev->last.remainder[1] = tmp - (float)*py;
                 }
             }
         }
commit 4318075140cc287871d3c3b9f777289ea4ffa23a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 7 21:51:02 2009 +1000

    dix: store subpixel precision and send it down the wire to the client.
    
    For the valuator data, not yet for root x/y and event x/y.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 4cd5567..8b973a5 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -357,7 +357,7 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
     xXIDeviceEvent *xde;
     int i, btlen, vallen;
     char *ptr;
-    int32_t *axisval;
+    FP3232 *axisval;
 
     /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
      * with MAX_VALUATORS below */
@@ -401,15 +401,15 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
     }
 
     ptr += xde->buttons_len * 4;
-    axisval = (int32_t*)(ptr + xde->valuators_len * 4);
+    axisval = (FP3232*)(ptr + xde->valuators_len * 4);
     for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
     {
         if (BitIsOn(ev->valuators.mask, i))
         {
             SetBit(ptr, i);
-            *axisval = ev->valuators.data[i];
+            axisval->integral = ev->valuators.data[i];
+            axisval->frac = ev->valuators.data_frac[i];
             axisval++;
-            axisval++; /* FIXME: this should be the frac. part */
         }
     }
 
@@ -451,9 +451,10 @@ eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
         {
             SetBit(ptr, i);
             axisval->integral = ev->valuators.data[i];
+            axisval->frac = ev->valuators.data_frac[i];
             (axisval + nvals)->integral = ev->valuators.data_raw[i];
+            (axisval + nvals)->frac = ev->valuators.data_raw_frac[i];
             axisval++;
-            /* FIXME: frac part */
         }
     }
 
diff --git a/dix/getevents.c b/dix/getevents.c
index b0bacbd..7aafc98 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -174,10 +174,13 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator,
         SetBit(event->valuators.mask, i);
         if (dev->valuator->mode == Absolute)
             SetBit(event->valuators.mode, i);
+        event->valuators.data_frac[first_valuator + i] =
+            dev->last.remainder[first_valuator + i] * (1 << 16) * (1 << 16);
     }
 
     memcpy(&event->valuators.data[first_valuator],
            valuators, num_valuators * sizeof(uint32_t));
+
 }
 
 void
diff --git a/include/events.h b/include/events.h
index a289662..da8f58a 100644
--- a/include/events.h
+++ b/include/events.h
@@ -93,6 +93,7 @@ typedef struct
         uint8_t  mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
         uint8_t  mode[(MAX_VALUATORS + 7)/8]; /**< Valuator mode (Abs or Rel)*/
         uint32_t data[MAX_VALUATORS];         /**< Valuator data */
+        int32_t  data_frac[MAX_VALUATORS];    /**< Fractional part for data */
     } valuators;
     struct {
         uint32_t base;    /**< XKB base modifiers */
@@ -191,7 +192,9 @@ typedef struct
     struct {
         uint8_t  mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
         int32_t  data[MAX_VALUATORS];         /**< Valuator data */
+        int32_t  data_frac[MAX_VALUATORS];    /**< Fractional part for data */
         int32_t  data_raw[MAX_VALUATORS];     /**< Valuator data as posted */
+        int32_t  data_raw_frac[MAX_VALUATORS];/**< Fractional part for data_raw */
     } valuators;
 } RawDeviceEvent;
 
commit 9212948461c5e053abb61fff73ced4a00f138544
Author: Simon Thum <simon.thum at gmx.de>
Date:   Sat Mar 21 18:19:19 2009 +0100

    dix: allow relative motion buffer to accumulate in a natural way
    
    Since with XI2 we pass sub-pixel motion, anything else is broken.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/ptrveloc.c b/dix/ptrveloc.c
index a3a0451..2d6763e 100644
--- a/dix/ptrveloc.c
+++ b/dix/ptrveloc.c
@@ -968,12 +968,6 @@ acceleratePointerPredictable(
     if (dx || dy){
         /* reset non-visible state? */
         if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) {
-            /* if nv-reset: set to center of pixel.
-             * makes sense as long as there are no means of passing on
-             * sub-pixel values to apps(XI2?). If you remove it, make
-             * sure suitable rounding is applied below.
-             */
-            pDev->last.remainder[0] = pDev->last.remainder[1] = 0;
             soften = FALSE;
         }
 
commit 6c3b633299f12051fcf37fb8439f358de876cf03
Merge: adf21db... 0cfd481...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Apr 7 19:36:27 2009 +1000

    Merge branch 'master' into xi2

commit adf21dba7617542f08309415e315d4b2699c10e0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 19 20:40:43 2009 +1000

    include: un-export a bunch of server-only functions.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/dix.h b/include/dix.h
index 87f49e8..14d6843 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -327,36 +327,36 @@ extern _X_EXPORT WindowPtr GetSpriteWindow(DeviceIntPtr pDev);
 
 extern _X_EXPORT void NoticeEventTime(InternalEvent *ev);
 
-extern _X_EXPORT void EnqueueEvent(
+extern void EnqueueEvent(
     InternalEvent * /* ev */,
     DeviceIntPtr  /* device */);
 
-extern _X_EXPORT void ActivatePointerGrab(
+extern void ActivatePointerGrab(
     DeviceIntPtr /* mouse */,
     GrabPtr /* grab */,
     TimeStamp /* time */,
     Bool /* autoGrab */);
 
-extern _X_EXPORT void DeactivatePointerGrab(
+extern void DeactivatePointerGrab(
     DeviceIntPtr /* mouse */);
 
-extern _X_EXPORT void ActivateKeyboardGrab(
+extern void ActivateKeyboardGrab(
     DeviceIntPtr /* keybd */,
     GrabPtr /* grab */,
     TimeStamp /* time */,
     Bool /* passive */);
 
-extern _X_EXPORT void DeactivateKeyboardGrab(
+extern void DeactivateKeyboardGrab(
     DeviceIntPtr /* keybd */);
 
-extern _X_EXPORT void AllowSome(
+extern void AllowSome(
     ClientPtr	/* client */,
     TimeStamp /* time */,
     DeviceIntPtr /* thisDev */,
     int /* newState */,
     Bool /* core */);
 
-extern _X_EXPORT void ReleaseActiveGrabs(
+extern void ReleaseActiveGrabs(
     ClientPtr client);
 
 extern _X_EXPORT int DeliverEventsToWindow(
@@ -367,57 +367,57 @@ extern _X_EXPORT int DeliverEventsToWindow(
     Mask /* filter */,
     GrabPtr /* grab */);
 
-extern _X_EXPORT int DeliverDeviceEvents(
+extern int DeliverDeviceEvents(
     WindowPtr /* pWin */,
     InternalEvent* /* event */,
     GrabPtr /* grab */,
     WindowPtr /* stopAt */,
     DeviceIntPtr /* dev */);
 
-extern _X_EXPORT void InitializeSprite(
+extern void InitializeSprite(
     DeviceIntPtr /* pDev */,
     WindowPtr    /* pWin */);
 
-extern _X_EXPORT void UpdateSpriteForScreen(
+extern void UpdateSpriteForScreen(
     DeviceIntPtr /* pDev */,
     ScreenPtr /* pScreen */);
 
 extern _X_EXPORT void WindowHasNewCursor(
     WindowPtr /* pWin */);
 
-extern _X_EXPORT Bool CheckDeviceGrabs(
+extern Bool CheckDeviceGrabs(
     DeviceIntPtr /* device */,
     DeviceEvent* /* event */,
     int /* checkFirst */);
 
-extern _X_EXPORT void DeliverFocusedEvent(
+extern void DeliverFocusedEvent(
     DeviceIntPtr /* keybd */,
     InternalEvent* /* event */,
     WindowPtr /* window */);
 
-extern _X_EXPORT void DeliverGrabbedEvent(
+extern void DeliverGrabbedEvent(
     InternalEvent* /* event */,
     DeviceIntPtr /* thisDev */,
     Bool /* deactivateGrab */);
 
-extern _X_EXPORT void FixKeyState(
+extern void FixKeyState(
     DeviceEvent* /* event */,
     DeviceIntPtr /* keybd */);
 
-extern _X_EXPORT void RecalculateDeliverableEvents(
+extern void RecalculateDeliverableEvents(
     WindowPtr /* pWin */);
 
 extern _X_EXPORT int OtherClientGone(
     pointer /* value */,
     XID /* id */);
 
-extern _X_EXPORT void DoFocusEvents(
+extern void DoFocusEvents(
     DeviceIntPtr /* dev */,
     WindowPtr /* fromWin */,
     WindowPtr /* toWin */,
     int /* mode */);
 
-extern _X_EXPORT int SetInputFocus(
+extern int SetInputFocus(
     ClientPtr /* client */,
     DeviceIntPtr /* dev */,
     Window /* focusID */,
@@ -425,7 +425,7 @@ extern _X_EXPORT int SetInputFocus(
     Time /* ctime */,
     Bool /* followOK */);
 
-extern _X_EXPORT int GrabDevice(
+extern int GrabDevice(
     ClientPtr /* client */,
     DeviceIntPtr /* dev */,
     unsigned /* this_mode */,
@@ -439,16 +439,16 @@ extern _X_EXPORT int GrabDevice(
     Window /* confineToWin */,
     CARD8 * /* status */);
 
-extern _X_EXPORT void InitEvents(void);
+extern void InitEvents(void);
 
-extern _X_EXPORT void CloseDownEvents(void);
+extern void CloseDownEvents(void);
 
-extern _X_EXPORT void DeleteWindowFromAnyEvents(
+extern void DeleteWindowFromAnyEvents(
     WindowPtr	/* pWin */,
     Bool /* freeResources */);
 
 
-extern _X_EXPORT Mask EventMaskForClient(
+extern Mask EventMaskForClient(
     WindowPtr /* pWin */,
     ClientPtr /* client */);
 
@@ -460,8 +460,7 @@ extern _X_EXPORT int DeliverEvents(
     int /*count*/,
     WindowPtr /*otherParent*/);
 
-extern _X_EXPORT Bool
-CheckMotion(
+extern Bool CheckMotion(
     DeviceEvent* /* ev */,
     DeviceIntPtr /* pDev */);
 
@@ -481,7 +480,7 @@ extern _X_EXPORT int TryClientEvents(
 
 extern _X_EXPORT void WindowsRestructured(void);
 
-extern _X_EXPORT Bool SetClientPointer(
+extern Bool SetClientPointer(
         ClientPtr /* client */, 
         ClientPtr /* setter */, 
         DeviceIntPtr /* device */);
@@ -492,7 +491,7 @@ extern _X_EXPORT DeviceIntPtr PickPointer(
 extern _X_EXPORT DeviceIntPtr PickKeyboard(
     ClientPtr /* client */);
 
-extern _X_EXPORT Bool IsInterferingGrab(
+extern Bool IsInterferingGrab(
         ClientPtr /* client */,
         DeviceIntPtr /* dev */,
         xEvent* /* events */);
@@ -576,11 +575,11 @@ typedef struct {
     int count;
 } DeviceEventInfoRec;
 
-extern _X_EXPORT int XItoCoreType(int xi_type);
-extern _X_EXPORT Bool DevHasCursor(DeviceIntPtr pDev);
-extern _X_EXPORT Bool IsPointerDevice( DeviceIntPtr dev);
-extern _X_EXPORT Bool IsKeyboardDevice(DeviceIntPtr dev);
-extern _X_EXPORT Bool IsPointerEvent(InternalEvent* event);
+extern int XItoCoreType(int xi_type);
+extern Bool DevHasCursor(DeviceIntPtr pDev);
+extern Bool IsPointerDevice( DeviceIntPtr dev);
+extern Bool IsKeyboardDevice(DeviceIntPtr dev);
+extern Bool IsPointerEvent(InternalEvent *event);
 
 /*
  * These are deprecated compatibility functions and will be removed soon!
diff --git a/include/input.h b/include/input.h
index 3140c3f..baac054 100644
--- a/include/input.h
+++ b/include/input.h
@@ -115,8 +115,8 @@ typedef struct _EventList {
 } EventList, *EventListPtr;
 
 /* The DIX stores incoming input events in this list */
-extern _X_EXPORT EventListPtr InputEventList;
-extern _X_EXPORT int InputEventListLen;
+extern EventListPtr InputEventList;
+extern int InputEventListLen;
 
 typedef int (*DeviceProc)(
     DeviceIntPtr /*device*/,
@@ -219,7 +219,7 @@ extern void set_key_down(DeviceIntPtr pDev, int key_code, int type);
 extern void set_key_up(DeviceIntPtr pDev, int key_code, int type);
 extern int key_is_down(DeviceIntPtr pDev, int key_code, int type);
 
-extern _X_EXPORT void InitCoreDevices(void);
+extern void InitCoreDevices(void);
 
 extern _X_EXPORT DeviceIntPtr AddInputDevice(
     ClientPtr /*client*/,
@@ -235,21 +235,21 @@ extern _X_EXPORT Bool ActivateDevice(
 extern _X_EXPORT Bool DisableDevice(
     DeviceIntPtr /*device*/);
 
-extern _X_EXPORT int InitAndStartDevices(void);
+extern int InitAndStartDevices(void);
 
-extern _X_EXPORT void CloseDownDevices(void);
+extern void CloseDownDevices(void);
 
-extern _X_EXPORT void UndisplayDevices(void);
+extern void UndisplayDevices(void);
 
 extern _X_EXPORT int RemoveDevice(
     DeviceIntPtr /*dev*/);
 
 extern _X_EXPORT int NumMotionEvents(void);
 
-extern _X_EXPORT void RegisterPointerDevice(
+extern void RegisterPointerDevice(
     DeviceIntPtr /*device*/);
 
-extern _X_EXPORT void RegisterKeyboardDevice(
+extern void RegisterKeyboardDevice(
     DeviceIntPtr /*device*/);
 
 extern _X_EXPORT int dixLookupDevice(
@@ -362,31 +362,31 @@ extern _X_EXPORT int ApplyPointerMapping(
     int          /* len */,
     ClientPtr	/* client */);
 
-extern _X_EXPORT Bool BadDeviceMap(
+extern Bool BadDeviceMap(
     BYTE* /*buff*/,
     int /*length*/,
     unsigned /*low*/,
     unsigned /*high*/,
     XID* /*errval*/);
 
-extern _X_EXPORT void NoteLedState(
+extern void NoteLedState(
     DeviceIntPtr /*keybd*/,
     int /*led*/,
     Bool /*on*/);
 
-extern _X_EXPORT void MaybeStopHint(
+extern void MaybeStopHint(
     DeviceIntPtr /*device*/,
     ClientPtr /*client*/);
 
-extern _X_EXPORT void ProcessPointerEvent(
+extern void ProcessPointerEvent(
     InternalEvent* /* ev */,
     DeviceIntPtr /*mouse*/);
 
-extern _X_EXPORT void ProcessKeyboardEvent(
+extern void ProcessKeyboardEvent(
     InternalEvent* /*ev*/,
     DeviceIntPtr   /*keybd*/);
 
-extern _X_EXPORT Bool LegalModifier(
+extern Bool LegalModifier(
     unsigned int /*key*/, 
     DeviceIntPtr /*pDev*/);
 
@@ -405,10 +405,10 @@ extern _X_EXPORT void SetMinimumEventSize(EventListPtr list,
                                 int min_size);
 extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events);
 
-extern _X_EXPORT void CreateClassesChangedEvent(EventListPtr event,
+extern void CreateClassesChangedEvent(EventListPtr event,
                                       DeviceIntPtr master,
                                       DeviceIntPtr slave);
-extern _X_EXPORT int GetPointerEvents(
+extern int GetPointerEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
@@ -418,13 +418,13 @@ extern _X_EXPORT int GetPointerEvents(
     int num_valuators,
     int *valuators);
 
-extern _X_EXPORT int GetKeyboardEvents(
+extern int GetKeyboardEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
     int key_code);
 
-extern _X_EXPORT int GetKeyboardValuatorEvents(
+extern int GetKeyboardValuatorEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
@@ -433,7 +433,7 @@ extern _X_EXPORT int GetKeyboardValuatorEvents(
     int num_valuator,
     int *valuators);
 
-extern _X_EXPORT int GetProximityEvents(
+extern int GetProximityEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
@@ -441,7 +441,7 @@ extern _X_EXPORT int GetProximityEvents(
     int num_valuators,
     int *valuators);
 
-extern _X_EXPORT void PostSyntheticMotion(
+extern void PostSyntheticMotion(
     DeviceIntPtr pDev,
     int x,
     int y,
@@ -462,17 +462,17 @@ extern _X_EXPORT int GetMotionHistory(
     ScreenPtr pScreen,
     BOOL core);
 
-extern _X_EXPORT int AttachDevice(ClientPtr client,
+extern int AttachDevice(ClientPtr client,
                         DeviceIntPtr slave,
                         DeviceIntPtr master);
 
 extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
 
-extern _X_EXPORT int AllocMasterDevice(ClientPtr client,
+extern int AllocMasterDevice(ClientPtr client,
                              char* name,
                              DeviceIntPtr* ptr,
                              DeviceIntPtr* keybd);
-extern _X_EXPORT void DeepCopyDeviceClasses(DeviceIntPtr from,
+extern void DeepCopyDeviceClasses(DeviceIntPtr from,
                                   DeviceIntPtr to);
 
 /* Helper functions. */
commit 111ef10375204a6981a5be5c045860854c4da4e6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 19 09:33:02 2009 +1000

    dix: move ProcGrabPointer guts into GrabDevice.
    
    Yes, this means we have even more arguments to GrabDevice. But it beats having
    a copy of most but not all of GrabDevice in ProcGrabPointer.
    Also, reshuffle the order of parameters, the CARD* status is a return value
    and should be last.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/grabdev.c b/Xi/grabdev.c
index f032b4a..65997ac 100644
--- a/Xi/grabdev.c
+++ b/Xi/grabdev.c
@@ -126,10 +126,11 @@ ProcXGrabDevice(ClientPtr client)
 				 X_GrabDevice)) != Success)
 	return rc;
 
-    rc = GrabDevice(client, dev, stuff->this_device_mode,
-		    stuff->other_devices_mode, stuff->grabWindow,
+    rc = GrabDevice(client, dev, stuff->other_devices_mode,
+                    stuff->this_device_mode, stuff->grabWindow,
 		    stuff->ownerEvents, stuff->time,
-		    tmp[stuff->deviceid].mask, &rep.status, FALSE);
+		    tmp[stuff->deviceid].mask, FALSE, None, None,
+		    &rep.status);
 
     if (rc != Success)
 	return rc;
diff --git a/dix/events.c b/dix/events.c
index ef4bc94..b41074a 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4390,40 +4390,21 @@ ProcGrabPointer(ClientPtr client)
     xGrabPointerReply rep;
     DeviceIntPtr device = PickPointer(client);
     GrabPtr grab;
-    WindowPtr pWin, confineTo;
-    CursorPtr cursor, oldCursor;
+    WindowPtr confineTo;
+    CursorPtr oldCursor;
     REQUEST(xGrabPointerReq);
     TimeStamp time;
-    Mask access_mode = DixGrabAccess;
     int rc;
 
     REQUEST_SIZE_MATCH(xGrabPointerReq);
     UpdateCurrentTime();
-    if ((stuff->pointerMode != GrabModeSync) &&
-	(stuff->pointerMode != GrabModeAsync))
-    {
-	client->errorValue = stuff->pointerMode;
-        return BadValue;
-    }
-    if ((stuff->keyboardMode != GrabModeSync) &&
-	(stuff->keyboardMode != GrabModeAsync))
-    {
-	client->errorValue = stuff->keyboardMode;
-        return BadValue;
-    }
-    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
-    {
-	client->errorValue = stuff->ownerEvents;
-        return BadValue;
-    }
+
     if (stuff->eventMask & ~PointerGrabMask)
     {
 	client->errorValue = stuff->eventMask;
         return BadValue;
     }
-    rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess);
-    if (rc != Success)
-	return rc;
+
     if (stuff->confineTo == None)
 	confineTo = NullWindow;
     else
@@ -4433,81 +4414,32 @@ ProcGrabPointer(ClientPtr client)
 	if (rc != Success)
 	    return rc;
     }
-    if (stuff->cursor == None)
-	cursor = NullCursor;
-    else
+
+    memset(&rep, 0, sizeof(xGrabPointerReply));
+    oldCursor = NullCursor;
+    grab = device->deviceGrab.grab;
+
+    if (grab)
     {
-	rc = dixLookupResourceByType((pointer *)&cursor, stuff->cursor, RT_CURSOR,
-			       client, DixUseAccess);
-	if (rc != Success)
-	{
-	    client->errorValue = stuff->cursor;
-	    return (rc == BadValue) ? BadCursor : rc;
-	}
-	access_mode |= DixForceAccess;
+        if (grab->confineTo && !confineTo)
+            ConfineCursorToWindow(device, RootWindow(device), FALSE, FALSE);
+        oldCursor = grab->cursor;
     }
-    if (stuff->pointerMode == GrabModeSync ||
-	stuff->keyboardMode == GrabModeSync)
-	access_mode |= DixFreezeAccess;
-    rc = XaceHook(XACE_DEVICE_ACCESS, client, device, access_mode);
+
+    rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode,
+                    stuff->grabWindow, stuff->ownerEvents, stuff->time,
+                    stuff->eventMask, TRUE, stuff->cursor,
+                    stuff->confineTo, &rep.status);
     if (rc != Success)
-	return rc;
+        return rc;
+
+    if (oldCursor)
+        FreeCursor (oldCursor, (Cursor)0);
 
-	/* at this point, some sort of reply is guaranteed. */
     time = ClientTimeToServerTime(stuff->time);
-    memset(&rep, 0, sizeof(xGrabPointerReply));
     rep.type = X_Reply;
     rep.sequenceNumber = client->sequence;
     rep.length = 0;
-
-    grab = device->deviceGrab.grab;
-    /* check for
-       1. other client has a grab on the device already.
-       2. window is viewable
-       3. other client has this device as frozen "other" device
-       4. times are screwed.
-     */
-    if ((grab) && !SameClient(grab, client))
-	rep.status = AlreadyGrabbed;
-    else if ((!pWin->realized) ||
-             (confineTo &&
-                !(confineTo->realized
-                    && BorderSizeNotEmpty(device, confineTo))))
-	rep.status = GrabNotViewable;
-    else if (device->deviceGrab.sync.frozen &&
-	     device->deviceGrab.sync.other &&
-             !SameClient(device->deviceGrab.sync.other, client))
-	rep.status = GrabFrozen;
-    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
-	     (CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
-	rep.status = GrabInvalidTime;
-    else
-    {
-	GrabRec tempGrab;
-
-	oldCursor = NullCursor;
-	if (grab)
-	{
-	    if (grab->confineTo && !confineTo)
-		ConfineCursorToWindow(device, RootWindow(device), FALSE, FALSE);
-	    oldCursor = grab->cursor;
-	}
-        tempGrab.next = NULL;
-	tempGrab.cursor = cursor;
-	tempGrab.resource = client->clientAsMask;
-	tempGrab.ownerEvents = stuff->ownerEvents;
-	tempGrab.eventMask = stuff->eventMask;
-	tempGrab.confineTo = confineTo;
-	tempGrab.window = pWin;
-	tempGrab.keyboardMode = stuff->keyboardMode;
-	tempGrab.pointerMode = stuff->pointerMode;
-	tempGrab.device = device;
-        tempGrab.coreGrab = True;
-	(*device->deviceGrab.ActivateGrab)(device, &tempGrab, time, FALSE);
-	if (oldCursor)
-	    FreeCursor (oldCursor, (Cursor)0);
-	rep.status = GrabSuccess;
-    }
     WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
     return Success;
 }
@@ -4613,26 +4545,27 @@ ProcUngrabPointer(ClientPtr client)
  */
 int
 GrabDevice(ClientPtr client, DeviceIntPtr dev,
-           unsigned this_mode, unsigned other_mode, Window grabWindow,
-           unsigned ownerEvents, Time ctime, Mask mask, CARD8 *status,
-           Bool coreGrab)
+           unsigned pointer_mode, unsigned keyboard_mode, Window grabWindow,
+           unsigned ownerEvents, Time ctime, Mask mask,
+           Bool coreGrab, Cursor curs, Window confineToWin, CARD8 *status)
 {
-    WindowPtr pWin;
+    WindowPtr pWin, confineTo;
     GrabPtr grab;
     TimeStamp time;
     Mask access_mode = DixGrabAccess;
     int rc;
     GrabInfoPtr grabInfo = &dev->deviceGrab;
+    CursorPtr cursor;
 
     UpdateCurrentTime();
-    if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
+    if ((keyboard_mode != GrabModeSync) && (keyboard_mode != GrabModeAsync))
     {
-	client->errorValue = this_mode;
+	client->errorValue = keyboard_mode;
         return BadValue;
     }
-    if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
+    if ((pointer_mode != GrabModeSync) && (pointer_mode != GrabModeAsync))
     {
-	client->errorValue = other_mode;
+	client->errorValue = pointer_mode;
         return BadValue;
     }
     if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
@@ -4644,7 +4577,32 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
     rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
     if (rc != Success)
 	return rc;
-    if (this_mode == GrabModeSync || other_mode == GrabModeSync)
+
+    if (confineToWin == None)
+	confineTo = NullWindow;
+    else
+    {
+	rc = dixLookupWindow(&confineTo, confineToWin, client,
+			     DixSetAttrAccess);
+	if (rc != Success)
+	    return rc;
+    }
+
+    if (curs == None)
+	cursor = NullCursor;
+    else
+    {
+	rc = dixLookupResourceByType((pointer *)&cursor, curs, RT_CURSOR,
+			       client, DixUseAccess);
+	if (rc != Success)
+	{
+	    client->errorValue = curs;
+	    return (rc == BadValue) ? BadCursor : rc;
+	}
+	access_mode |= DixForceAccess;
+    }
+
+    if (keyboard_mode == GrabModeSync || pointer_mode == GrabModeSync)
 	access_mode |= DixFreezeAccess;
     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
     if (rc != Success)
@@ -4654,7 +4612,10 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
     grab = grabInfo->grab;
     if (grab && !SameClient(grab, client))
 	*status = AlreadyGrabbed;
-    else if (!pWin->realized)
+    else if ((!pWin->realized) ||
+             (confineTo &&
+                !(confineTo->realized
+                    && BorderSizeNotEmpty(dev, confineTo))))
 	*status = GrabNotViewable;
     else if ((CompareTimeStamps(time, currentTime) == LATER) ||
 	     (CompareTimeStamps(time, grabInfo->grabTime) == EARLIER))
@@ -4673,13 +4634,13 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
 	tempGrab.window = pWin;
 	tempGrab.resource = client->clientAsMask;
 	tempGrab.ownerEvents = ownerEvents;
-	tempGrab.keyboardMode = this_mode;
-	tempGrab.pointerMode = other_mode;
+	tempGrab.keyboardMode = keyboard_mode;
+	tempGrab.pointerMode = pointer_mode;
 	tempGrab.eventMask = mask;
 	tempGrab.device = dev;
-        tempGrab.cursor = NULL;
-        tempGrab.coreGrab = coreGrab;
-
+	tempGrab.cursor = cursor;
+	tempGrab.confineTo = confineTo;
+	tempGrab.coreGrab = coreGrab;
 	(*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE);
 	*status = GrabSuccess;
     }
@@ -4702,10 +4663,10 @@ ProcGrabKeyboard(ClientPtr client)
     REQUEST_SIZE_MATCH(xGrabKeyboardReq);
 
     memset(&rep, 0, sizeof(xGrabKeyboardReply));
-    result = GrabDevice(client, keyboard, stuff->keyboardMode,
-            stuff->pointerMode, stuff->grabWindow,
-            stuff->ownerEvents, stuff->time,
-            KeyPressMask | KeyReleaseMask, &rep.status, TRUE);
+    result = GrabDevice(client, keyboard, stuff->pointerMode,
+            stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents,
+            stuff->time, KeyPressMask | KeyReleaseMask, TRUE, None, None,
+            &rep.status);
 
     if (result != Success)
 	return result;
diff --git a/include/dix.h b/include/dix.h
index a19b901..87f49e8 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -434,8 +434,10 @@ extern _X_EXPORT int GrabDevice(
     unsigned /* ownerEvents */,
     Time /* ctime */,
     Mask /* mask */,
-    CARD8 * /* status */,
-    Bool /* coreGrab */);
+    Bool /* coreGrab */,
+    Cursor /* curs */,
+    Window /* confineToWin */,
+    CARD8 * /* status */);
 
 extern _X_EXPORT void InitEvents(void);
 
commit dc153271b6458cacd63a4bc0208594011c6460b0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 18 15:13:00 2009 +1000

    Xi: purge old device enter/leave masks.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index b5413f9..4aa5fbf 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -146,8 +146,6 @@ XIGetDevice(xEvent* xE)
     if (xE->u.u.type == DeviceButtonPress ||
         xE->u.u.type == DeviceButtonRelease ||
         xE->u.u.type == DeviceMotionNotify ||
-        xE->u.u.type == DeviceEnterNotify ||
-        xE->u.u.type == DeviceLeaveNotify ||
         xE->u.u.type == ProximityIn ||
         xE->u.u.type == ProximityOut ||
         xE->u.u.type == DevicePropertyNotify)
diff --git a/Xi/exglobals.h b/Xi/exglobals.h
index 1828073..2d2d25c 100644
--- a/Xi/exglobals.h
+++ b/Xi/exglobals.h
@@ -75,8 +75,6 @@ extern int DeviceMappingNotify;
 extern int ChangeDeviceNotify;
 extern int DevicePresenceNotify;
 extern int DevicePropertyNotify;
-extern int DeviceEnterNotify;
-extern int DeviceLeaveNotify;
 
 extern int RT_INPUTCLIENT;
 
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 23e41ca..bedd750 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -331,8 +331,6 @@ int DeviceMappingNotify;
 int ChangeDeviceNotify;
 int DevicePresenceNotify;
 int DevicePropertyNotify;
-int DeviceEnterNotify;
-int DeviceLeaveNotify;
 
 int RT_INPUTCLIENT;
 
@@ -893,8 +891,6 @@ FixExtensionEvents(ExtensionEntry * extEntry)
     DeviceButtonStateNotify = DeviceKeyStateNotify + 1;
     DevicePresenceNotify = DeviceButtonStateNotify + 1;
     DevicePropertyNotify = DevicePresenceNotify + 1;
-    DeviceEnterNotify = DevicePropertyNotify + 1;
-    DeviceLeaveNotify = DeviceEnterNotify + 1;
 
     event_base[KeyClass] = DeviceKeyPress;
     event_base[ButtonClass] = DeviceButtonPress;
@@ -950,12 +946,6 @@ FixExtensionEvents(ExtensionEntry * extEntry)
     SetEventInfo(DevicePresenceNotifyMask, _devicePresence);
     SetMaskForExtEvent(DevicePropertyNotifyMask, DevicePropertyNotify);
 
-    SetMaskForExtEvent(DeviceEnterWindowMask, DeviceEnterNotify);
-    AllowPropagateSuppress(DeviceEnterWindowMask);
-
-    SetMaskForExtEvent(DeviceLeaveWindowMask, DeviceLeaveNotify);
-    AllowPropagateSuppress(DeviceLeaveWindowMask);
-
     SetEventInfo(0, _noExtensionEvent);
 }
 
@@ -1001,8 +991,6 @@ RestoreExtensionEvents(void)
     DeviceButtonStateNotify = 13;
     DevicePresenceNotify = 14;
     DevicePropertyNotify = 15;
-    DeviceEnterNotify = 16;
-    DeviceLeaveNotify = 17;
 
     BadDevice = 0;
     BadEvent = 1;
@@ -1042,8 +1030,6 @@ IResetProc(ExtensionEntry * unused)
     EventSwapVector[ChangeDeviceNotify] = NotImplemented;
     EventSwapVector[DevicePresenceNotify] = NotImplemented;
     EventSwapVector[DevicePropertyNotify] = NotImplemented;
-    EventSwapVector[DeviceEnterNotify] = NotImplemented;
-    EventSwapVector[DeviceLeaveNotify] = NotImplemented;
     RestoreExtensionEvents();
 }
 
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 8a81431..d1c079b 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -318,7 +318,6 @@ extern _X_EXPORT CARD32	xkbDebugFlags;
 
 extern	_X_EXPORT int	DeviceKeyPress,DeviceKeyRelease,DeviceMotionNotify;
 extern	_X_EXPORT int	DeviceButtonPress,DeviceButtonRelease;
-extern	_X_EXPORT int	DeviceEnterNotify,DeviceLeaveNotify;
 
 #define	_XkbIsPressEvent(t)	(((t)==KeyPress)||((t)==DeviceKeyPress))
 #define	_XkbIsReleaseEvent(t)	(((t)==KeyRelease)||((t)==DeviceKeyRelease))
commit 15a969c0fcd4f19f3c560a7037c1a6a58bce51f0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 18 10:21:59 2009 +1000

    dix: remove now obsolete mskidx parameter from DeliverEventsToWindow.
    
    mskidx would always be dev->id anyway, so if we're already passing in the
    device, mskidx is superfluous.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 6970809..b5413f9 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -936,8 +936,7 @@ ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
 
         for (i = 0; i < screenInfo.numScreens; i++)
             DeliverEventsToWindow(device, WindowTable[i], xi, 1,
-                                  GetEventFilter(device, xi), NULL,
-                                  device->id);
+                                  GetEventFilter(device, xi), NULL);
         xfree(xi);
     }
 }
@@ -1241,8 +1240,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE);
 
     DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1,
-                          GetEventFilter(dev, (xEvent*)xi2event), NullGrab,
-                          dev->id);
+                          GetEventFilter(dev, (xEvent*)xi2event), NullGrab);
 
     xfree(xi2event);
 
@@ -1255,7 +1253,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     event.time = currentTime.milliseconds;
 
     DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
-				DeviceFocusChangeMask, NullGrab, dev->id);
+				DeviceFocusChangeMask, NullGrab);
 
     if ((type == DeviceFocusIn) &&
 	(wOtherInputMasks(pWin)) &&
@@ -1352,7 +1350,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
 	}
 
 	DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount,
-				    DeviceStateNotifyMask, NullGrab, dev->id);
+				    DeviceStateNotifyMask, NullGrab);
 	xfree(sev);
     }
 }
@@ -1697,7 +1695,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate,
     ev->u.u.type |= 0x80;
     if (propagate) {
 	for (; pWin; pWin = pWin->parent) {
-	    if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id))
+	    if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab))
 		return Success;
 	    if (pWin == effectiveFocus)
 		return Success;
@@ -1707,7 +1705,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate,
 		break;
 	}
     } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count))
-	DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id);
+	DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab);
     return Success;
 }
 
@@ -2009,7 +2007,7 @@ FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask,
 
     while (p1) {
         p2 = p1->firstChild;
-        DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab, dev->id);
+        DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab);
         FindInterestedChildren(dev, p2, mask, ev, count);
         p1 = p1->nextSib;
     }
@@ -2031,7 +2029,7 @@ SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count)
         pWin = WindowTable[i];
         if (!pWin)
             continue;
-        DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab, dev->id);
+        DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab);
         p1 = pWin->firstChild;
         FindInterestedChildren(dev, p1, mask, ev, count);
     }
diff --git a/dix/events.c b/dix/events.c
index c618c8c..ef4bc94 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1945,13 +1945,12 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
  * @param count Number of elements in pEvents.
  * @param filter Mask based on event type.
  * @param grab Possible grab on the device that caused the event.
- * @param mskidx Mask index, depending on device that caused event.
  *
  * @return Number of events delivered to various clients.
  */
 int
 DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
-        *pEvents, int count, Mask filter, GrabPtr grab, int mskidx)
+        *pEvents, int count, Mask filter, GrabPtr grab)
 {
     int deliveries = 0, nondeliveries = 0;
     int attempt;
@@ -2005,7 +2004,7 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
             OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
             /* Has any client selected for the event? */
             if (!inputMasks ||
-                !(inputMasks->inputEvents[mskidx] & filter))
+                !(inputMasks->inputEvents[pDev->id] & filter))
                 return 0;
 
             other = inputMasks->inputClients;
@@ -2403,7 +2402,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                 filter = GetEventFilter(dev, xi2);
                 FixUpEventFromWindow(dev, xi2, pWin, child, FALSE);
                 deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1,
-                                                   filter, grab, dev->id);
+                                                   filter, grab);
                 xfree(xi2);
                 if (deliveries > 0)
                     goto unwind;
@@ -2415,7 +2414,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                 filter = GetEventFilter(dev, xE);
                 FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
                 deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
-                                                   filter, grab, dev->id);
+                                                   filter, grab);
                 if (deliveries > 0)
                     goto unwind;
             }
@@ -2435,7 +2434,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                 filter = GetEventFilter(dev, &core);
                 FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
                 deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
-                                                   filter, grab, dev->id);
+                                                   filter, grab);
                 if (deliveries > 0)
                     goto unwind;
             }
@@ -2495,21 +2494,20 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
     if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
 	xE->u.destroyNotify.event = pWin->drawable.id;
     if (filter != StructureAndSubMask)
-	return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, NullGrab, dummy.id);
-    deliveries = DeliverEventsToWindow(&dummy, pWin, xE, count, StructureNotifyMask,
-				       NullGrab, dummy.id);
+	return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, NullGrab);
+    deliveries = DeliverEventsToWindow(&dummy, pWin, xE, count,
+                                       StructureNotifyMask, NullGrab);
     if (pWin->parent)
     {
 	xE->u.destroyNotify.event = pWin->parent->drawable.id;
 	deliveries += DeliverEventsToWindow(&dummy, pWin->parent, xE, count,
-					    SubstructureNotifyMask, NullGrab,
-					    dummy.id);
+					    SubstructureNotifyMask, NullGrab);
 	if (xE->u.u.type == ReparentNotify)
 	{
 	    xE->u.destroyNotify.event = otherParent->drawable.id;
             deliveries += DeliverEventsToWindow(&dummy,
                     otherParent, xE, count, SubstructureNotifyMask,
-						NullGrab, dummy.id);
+						NullGrab);
 	}
     }
     return deliveries;
@@ -3559,7 +3557,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
         /* just deliver it to the focus window */
         FixUpEventFromWindow(ptr, xi2, focus, None, FALSE);
         deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1,
-                                           filter, NullGrab, keybd->id);
+                                           filter, NullGrab);
         if (deliveries > 0)
             goto unwind;
     }
@@ -3568,7 +3566,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     FixUpEventFromWindow(ptr, xE, focus, None, FALSE);
     deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
                                        GetEventFilter(keybd, xE),
-                                       NullGrab, keybd->id);
+                                       NullGrab);
 
     if (deliveries > 0)
         goto unwind;
@@ -3586,7 +3584,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
         FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
         deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
                                            GetEventFilter(keybd, &core),
-                                           NullGrab, keybd->id);
+                                           NullGrab);
     }
 
 unwind:
@@ -4105,7 +4103,7 @@ CoreEnterLeaveEvent(
         else
             DeliverEventsToWindow(mouse, pWin, &event, 1,
                                   GetEventFilter(mouse, &event),
-                                  NullGrab, mouse->id);
+                                  NullGrab);
     }
 
     if ((type == EnterNotify) && (mask & KeymapStateMask))
@@ -4124,7 +4122,7 @@ CoreEnterLeaveEvent(
                             mask, KeymapStateMask, grab);
         else
             DeliverEventsToWindow(mouse, pWin, (xEvent *)&ke, 1,
-                                  KeymapStateMask, NullGrab, mouse->id);
+                                  KeymapStateMask, NullGrab);
     }
 }
 
@@ -4192,7 +4190,7 @@ DeviceEnterLeaveEvent(
                         filter, grab);
     else
         DeliverEventsToWindow(mouse, pWin, (xEvent*)event, 1, filter,
-                              NullGrab, mouse->id);
+                              NullGrab);
     xfree(event);
 }
 
@@ -4208,7 +4206,7 @@ CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
     event.u.focus.window = pWin->drawable.id;
 
     DeliverEventsToWindow(dev, pWin, &event, 1,
-                          GetEventFilter(dev, &event), NullGrab, dev->id);
+                          GetEventFilter(dev, &event), NullGrab);
     if ((type == FocusIn) &&
             ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
     {
@@ -4221,7 +4219,7 @@ CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
 
         ke.type = KeymapNotify;
         DeliverEventsToWindow(dev, pWin, (xEvent *)&ke, 1,
-                KeymapStateMask, NullGrab, dev->id);
+                KeymapStateMask, NullGrab);
     }
 }
 
@@ -4962,7 +4960,7 @@ ProcSendEvent(ClientPtr client)
 			 &stuff->event, 1))
 		return Success;
             if (DeliverEventsToWindow(dev, pWin,
-                        &stuff->event, 1, stuff->eventMask, NullGrab, dev->id))
+                        &stuff->event, 1, stuff->eventMask, NullGrab))
 		return Success;
 	    if (pWin == effectiveFocus)
 		return Success;
@@ -4973,7 +4971,7 @@ ProcSendEvent(ClientPtr client)
     }
     else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, &stuff->event, 1))
         DeliverEventsToWindow(dev, pWin, &stuff->event,
-                                    1, stuff->eventMask, NullGrab, dev->id);
+                                    1, stuff->eventMask, NullGrab);
     return Success;
 }
 
diff --git a/include/dix.h b/include/dix.h
index ebd8f2f..a19b901 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -365,8 +365,7 @@ extern _X_EXPORT int DeliverEventsToWindow(
     xEventPtr /* pEvents */,
     int /* count */,
     Mask /* filter */,
-    GrabPtr /* grab */,
-    int /* mskidx */);
+    GrabPtr /* grab */);
 
 extern _X_EXPORT int DeliverDeviceEvents(
     WindowPtr /* pWin */,
commit f5409aa026b2cb501170867d04c6e220f3fe0a44
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 13 15:51:50 2009 +1000

    mi: remove deprecated miPointerAbsoluteCursor
    
    Functions that don't specify the device are so last year.

diff --git a/mi/mipointer.c b/mi/mipointer.c
index e3a4656..857a8ca 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -457,15 +457,6 @@ miPointerGetScreen(DeviceIntPtr pDev)
     return (pPointer) ? pPointer->pScreen : NULL;
 }
 
-/* Move the pointer to x, y on the current screen, update the sprite, and
- * the motion history.  Generates no events.  Does not return changed x
- * and y if they are clipped; use miPointerSetPosition instead. */
-void
-miPointerAbsoluteCursor (int x, int y, unsigned long time)
-{
-    miPointerSetPosition(inputInfo.pointer, &x, &y);
-}
-
 /* Move the pointer on the current screen,  and update the sprite. */
 static void
 miPointerMoved (DeviceIntPtr pDev, ScreenPtr pScreen,
diff --git a/mi/mipointer.h b/mi/mipointer.h
index 83277e4..259ac14 100644
--- a/mi/mipointer.h
+++ b/mi/mipointer.h
@@ -110,13 +110,6 @@ extern _X_EXPORT void miPointerWarpCursor(
     int /*y*/
 ) _X_DEPRECATED;
 
-/* Deprecated in favour of miPointerSetPosition. */
-extern _X_EXPORT void miPointerAbsoluteCursor(
-    int /*x*/,
-    int /*y*/,
-    unsigned long /*time*/
-) _X_DEPRECATED;
-
 /* Deprecated in favour of miPointerGetScreen. */
 extern _X_EXPORT ScreenPtr miPointerCurrentScreen(
     void
commit 46145a9312eaf5dcd0e8b6788ed8219e086f790e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 13 15:12:55 2009 +1000

    dix: remove coreMods field from GrabRec.
    
    Nobody uses it anyway, and it's taking up a whole bit!

diff --git a/dix/grabs.c b/dix/grabs.c
index 156574e..2d3327c 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -97,8 +97,6 @@ CreateGrab(
     grab->modifiersDetail.exact = modifiers;
     grab->modifiersDetail.pMask = NULL;
     grab->modifierDevice = modDevice;
-    grab->coreMods = ((modDevice == inputInfo.keyboard) ||
-		      (modDevice == inputInfo.pointer));
     grab->type = type;
     grab->detail.exact = keybut;
     grab->detail.pMask = NULL;
diff --git a/include/inputstr.h b/include/inputstr.h
index 59fb29b..14941b1 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -172,7 +172,6 @@ typedef struct _GrabRec {
     unsigned		keyboardMode:1;
     unsigned		pointerMode:1;
     unsigned		coreGrab:1;	/* grab is on core device */
-    unsigned		coreMods:1;	/* modifiers are on core keyboard */
     CARD8		type;		/* event type */
     DetailRec		modifiersDetail;
     DeviceIntPtr	modifierDevice;
commit 40e2a61e37109cd9c2ab57954ee40dcf4a062e31
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 12 16:53:56 2009 +1000

    Add Get/SetDeviceFocus handling.

diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 5483000..cbec13e 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -95,6 +95,8 @@ libXi_la_SOURCES =	\
 	xiproperty.c \
 	xiproperty.h \
 	xiselectev.c \
-	xiselectev.h
+	xiselectev.h \
+	xisetdevfocus.c \
+	xisetdevfocus.h
 
 EXTRA_DIST = stubs.c
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 5dae990..6970809 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1241,7 +1241,7 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
     FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE);
 
     DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1,
-                          GetWindowXI2Mask(dev, pWin, xi2event), NullGrab,
+                          GetEventFilter(dev, (xEvent*)xi2event), NullGrab,
                           dev->id);
 
     xfree(xi2event);
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 8c9f9e1..23e41ca 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -120,6 +120,7 @@ SOFTWARE.
 #include "ungrdevk.h"
 #include "warpdevp.h"
 #include "xiselectev.h"
+#include "xisetdevfocus.h"
 #include "xiproperty.h"
 
 
@@ -239,7 +240,9 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXIGetClientPointer,                 /* 45 */
         ProcXISelectEvent,                      /* 46 */
         ProcXIQueryVersion,                     /* 47 */
-        ProcXIQueryDevice                       /* 48 */
+        ProcXIQueryDevice,                      /* 48 */
+        ProcXISetDeviceFocus,                   /* 49 */
+        ProcXIGetDeviceFocus                    /* 50 */
 };
 
 /* For swapped clients */
@@ -292,7 +295,9 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXIGetClientPointer,                 /* 45 */
         SProcXISelectEvent,                      /* 46 */
         SProcXIQueryVersion,                     /* 47 */
-        SProcXIQueryDevice                       /* 48 */
+        SProcXIQueryDevice,                      /* 48 */
+        SProcXISetDeviceFocus,                   /* 49 */
+        SProcXIGetDeviceFocus                    /* 50 */
 };
 
 /*****************************************************************
diff --git a/Xi/xisetdevfocus.c b/Xi/xisetdevfocus.c
new file mode 100644
index 0000000..5945abd
--- /dev/null
+++ b/Xi/xisetdevfocus.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2008 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.
+ *
+ * Author: Peter Hutterer
+ */
+/***********************************************************************
+ *
+ * Request to set and get an input device's focus.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h"	/* DeviceIntPtr      */
+#include "windowstr.h"	/* window structure  */
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XI2proto.h>
+
+#include "exglobals.h" /* BadDevice */
+#include "xisetdevfocus.h"
+
+int
+SProcXISetDeviceFocus(ClientPtr client)
+{
+    char n;
+
+    REQUEST(xXISetDeviceFocusReq);
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->focus, n);
+    swapl(&stuff->time, n);
+
+    return ProcXISetDeviceFocus(client);
+}
+
+int
+SProcXIGetDeviceFocus(ClientPtr client)
+{
+    char n;
+
+    REQUEST(xXIGetDeviceFocusReq);
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+
+    return ProcXIGetDeviceFocus(client);
+}
+
+int
+ProcXISetDeviceFocus(ClientPtr client)
+{
+    DeviceIntPtr dev;
+    int ret;
+
+    REQUEST(xXISetDeviceFocusReq);
+    REQUEST_AT_LEAST_SIZE(xXISetDeviceFocusReq);
+
+    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
+    if (ret != Success)
+	return ret;
+    if (!dev->focus)
+	return BadDevice;
+
+    return SetInputFocus(client, dev, stuff->focus, RevertToParent,
+                        stuff->time, TRUE);
+}
+
+int
+ProcXIGetDeviceFocus(ClientPtr client)
+{
+    xXIGetDeviceFocusReply rep;
+    DeviceIntPtr dev;
+    int ret;
+
+    REQUEST(xXIGetDeviceFocusReq);
+    REQUEST_AT_LEAST_SIZE(xXIGetDeviceFocusReq);
+
+    ret = dixLookupDevice(&dev, stuff->deviceid, client, DixSetFocusAccess);
+    if (ret != Success)
+	return ret;
+    if (!dev->focus)
+	return BadDevice;
+
+    rep.repType = X_Reply;
+    rep.RepType = X_XIGetDeviceFocus;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+
+    if (dev->focus->win == NoneWin)
+	rep.focus = None;
+    else if (dev->focus->win == PointerRootWin)
+	rep.focus = PointerRoot;
+    else if (dev->focus->win == FollowKeyboardWin)
+	rep.focus = FollowKeyboard;
+    else
+	rep.focus = dev->focus->win->drawable.id;
+
+    WriteReplyToClient(client, sizeof(xXIGetDeviceFocusReply), &rep);
+    return Success;
+}
diff --git a/Xi/xisetdevfocus.h b/Xi/xisetdevfocus.h
new file mode 100644
index 0000000..9bdeb77
--- /dev/null
+++ b/Xi/xisetdevfocus.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifndef XISETDEVFOCUS_H
+#define XISETDEVFOCUS_H 1
+
+int SProcXISetDeviceFocus(ClientPtr client);
+int ProcXISetDeviceFocus(ClientPtr client);
+
+int SProcXIGetDeviceFocus(ClientPtr client);
+int ProcXIGetDeviceFocus(ClientPtr client);
+
+#endif /* XISETDEVFOCUS_H */
commit d9b7343eac1157490442cc0fb3b5b6d7d6e9a705
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 12 12:56:18 2009 +1000

    dix: even if we don't get a XI1 event, continue processing.

diff --git a/dix/events.c b/dix/events.c
index 447732d..c618c8c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2377,11 +2377,14 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
         ErrorF("[dix] %s: XI conversion failed in DDE (%d, %d). Skipping delivery.\n",
                dev->name, event->u.any.type, rc);
         goto unwind;
-    } else if (count == 0) /* no XI/Core event for you */
-        goto unwind;
+    } else if (count > 0)
+    {
+        if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count))
+            goto unwind;
+        /* if count is 0, we might still have XI2 events, don't have XACE for
+         * that yet */
+    }
 
-    if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count))
-	goto unwind;
 
     while (pWin)
     {
commit e11dc10f01603b181e224c90d1dd4abe940f2ce7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 12 10:21:00 2009 +1000

    dix: Send HierarchyEvents when devices are added/removed/enabled/disabled.

diff --git a/dix/devices.c b/dix/devices.c
index 64af57f..8c8a215 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -82,6 +82,7 @@ SOFTWARE.
 #include "xiproperty.h"
 #include "enterleave.h" /* for EnterWindow() */
 #include "xserver-properties.h"
+#include "chdevhier.h" /* For XISendDeviceHierarchyEvent */
 
 /** @file
  * This file handles input device-related stuff.
@@ -343,6 +344,7 @@ EnableDevice(DeviceIntPtr dev)
                            TRUE);
 
     SendDevicePresenceEvent(dev->id, DeviceEnabled);
+    XISendDeviceHierarchyEvent(HF_DeviceEnabled);
 
     return TRUE;
 }
@@ -413,6 +415,7 @@ DisableDevice(DeviceIntPtr dev)
                            TRUE);
 
     SendDevicePresenceEvent(dev->id, DeviceDisabled);
+    XISendDeviceHierarchyEvent(HF_DeviceDisabled);
     return TRUE;
 }
 
@@ -444,6 +447,7 @@ ActivateDevice(DeviceIntPtr dev)
         pScreen->DeviceCursorInitialize(dev, pScreen);
 
     SendDevicePresenceEvent(dev->id, DeviceAdded);
+    XISendDeviceHierarchyEvent(HF_SlaveAdded);
     return ret;
 }
 
@@ -941,6 +945,7 @@ RemoveDevice(DeviceIntPtr dev)
     if (ret == Success && initialized) {
         inputInfo.numDevices--;
         SendDevicePresenceEvent(deviceid, DeviceRemoved);
+        XISendDeviceHierarchyEvent(HF_SlaveRemoved);
     }
 
     return ret;
commit 8634e1bcbae9317fc22132f7c9bde1a4a881b9a7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 12 10:42:05 2009 +1000

    dix: send presence events when floating and unfloating SDs

diff --git a/dix/devices.c b/dix/devices.c
index 0795d30..64af57f 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2198,11 +2198,23 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
         dev->spriteInfo->spriteOwner = FALSE;
         dev->spriteInfo->paired = dev;
 
+        /* Floating an SD makes it appear to XI 1 clients */
+        SendDevicePresenceEvent(dev->id, DeviceAdded);
+        if (dev->enabled)
+            SendDevicePresenceEvent(dev->id, DeviceEnabled);
     } else
     {
         dev->spriteInfo->sprite = master->spriteInfo->sprite;
         dev->spriteInfo->paired = master;
         dev->spriteInfo->spriteOwner = FALSE;
+
+        if (!oldmaster)
+        {
+            /* Attaching a floating SD makes it disappear to XI 1 clients */
+            if (dev->enabled)
+                SendDevicePresenceEvent(dev->id, DeviceDisabled);
+            SendDevicePresenceEvent(dev->id, DeviceRemoved);
+        }
     }
 
     /* If we were connected to master device before, this MD may need to
commit c9483a53bea1f721d2902ac11467f67317e7de14
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 11 16:20:22 2009 +1000

    include: add a few prototypes to silence compiler warnings.

diff --git a/include/input.h b/include/input.h
index 7651919..3140c3f 100644
--- a/include/input.h
+++ b/include/input.h
@@ -481,6 +481,15 @@ extern int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
 extern int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *map,
                          int max_keys_per_mod);
 
+/* misc event helpers */
+extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
+extern Mask GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev);
+void FixUpEventFromWindow(DeviceIntPtr pDev,
+                          xEvent *xE,
+                          WindowPtr pWin,
+                          Window child,
+                          Bool calcChild);
+
 /* Implemented by the DDX. */
 extern _X_EXPORT int NewInputDeviceRequest(
     InputOption *options,
commit a4b61cfc78d81de02a71fa6ad8a44a06616f6794
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 11 16:08:24 2009 +1000

    dix: un-static FixUpEventFromWindow and deal with focus events too.

diff --git a/dix/events.c b/dix/events.c
index adc180b..447732d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2233,7 +2233,8 @@ FixUpEventFromWindow(
             event->child = None;
         }
 
-        if (event->evtype == XI_Enter || event->evtype == XI_Leave)
+        if (event->evtype == XI_Enter || event->evtype == XI_Leave ||
+            event->evtype == XI_FocusIn || event->evtype == XI_FocusOut)
             ((xXIEnterEvent*)event)->same_screen =
                 (pSprite->hot.pScreen == pWin->drawable.pScreen);
 
commit 4cc6a96d7171e567a9bd5a10f552bb953077aafb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Mar 10 16:08:14 2009 +1000

    input: add support for RawDeviceEvents.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 8404335..5dae990 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -75,6 +75,7 @@ SOFTWARE.
 #include "listdev.h" /* for CopySwapXXXClass */
 #include "xace.h"
 #include "querydev.h" /* For List*Info */
+#include "eventconvert.h"
 
 #include <X11/extensions/XKBproto.h>
 #include "xkbsrv.h"
@@ -914,6 +915,33 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
     return DEFAULT;
 }
 
+static void
+ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
+{
+    GrabPtr grab = device->deviceGrab.grab;
+
+    if (grab)
+        DeliverGrabbedEvent(ev, device, FALSE);
+    else { /* deliver to all root windows */
+        xEvent *xi;
+        int i;
+
+        i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
+        if (i != Success)
+        {
+            ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n",
+                    device->name, i);
+            return;
+        }
+
+        for (i = 0; i < screenInfo.numScreens; i++)
+            DeliverEventsToWindow(device, WindowTable[i], xi, 1,
+                                  GetEventFilter(device, xi), NULL,
+                                  device->id);
+        xfree(xi);
+    }
+}
+
 /**
  * Main device event processing function.
  * Called from when processing the events from the event queue.
@@ -935,6 +963,12 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
 
     CHECKEVENT(ev);
 
+    if (ev->u.any.type == ET_Raw)
+    {
+        ProcessRawEvent((RawDeviceEvent*)ev, device);
+        return;
+    }
+
     if (IsPointerDevice(device))
     {
         kbd = GetPairedDevice(device);
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 553d953..4cd5567 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -52,6 +52,7 @@ static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
 static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
 static int eventToClassesChanged(DeviceChangedEvent *ev, xEvent **dcce);
 static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
+static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
 /**
  * Convert the given event to the respective core event.
  *
@@ -126,6 +127,7 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
         case ET_ProximityOut:
             return eventToKeyButtonPointer((DeviceEvent*)ev, xi, count);
         case ET_DeviceChanged:
+        case ET_Raw:
             *count = 0;
             *xi = NULL;
             return Success;
@@ -164,6 +166,8 @@ EventToXI2(InternalEvent *ev, xEvent **xi)
             return Success;
         case ET_DeviceChanged:
             return eventToClassesChanged((DeviceChangedEvent*)ev, xi);
+        case ET_Raw:
+            return eventToRawEvent((RawDeviceEvent*)ev, xi);
 
     }
 
@@ -412,6 +416,50 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
     return Success;
 }
 
+static int
+eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
+{
+    xXIRawDeviceEvent* raw;
+    int vallen, nvals;
+    int i, len = sizeof(xXIRawDeviceEvent);
+    char *ptr;
+    FP3232 *axisval;
+
+    nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
+    len += nvals * (2 * sizeof(uint32_t)) * 2; /* 8 byte per valuator, once
+                                                   raw, once processed */
+    vallen = (((MAX_VALUATORS + 7)/8) + 3)/4;
+    len += vallen * 4; /* valuators mask */
+
+    *xi = xcalloc(1, len);
+    raw = (xXIRawDeviceEvent*)*xi;
+    raw->type           = GenericEvent;
+    raw->extension      = IReqCode;
+    raw->evtype         = GetXI2Type((InternalEvent*)ev);
+    raw->time           = ev->time;
+    raw->length         = (len - sizeof(xEvent) + 3)/4;
+    raw->eventtype      = ev->subtype;
+    raw->detail         = ev->detail.button;
+    raw->deviceid       = ev->deviceid;
+    raw->valuators_len  = vallen;
+
+    ptr = (char*)&raw[1];
+    axisval = (FP3232*)(ptr + raw->valuators_len * 4);
+    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    {
+        if (BitIsOn(ev->valuators.mask, i))
+        {
+            SetBit(ptr, i);
+            axisval->integral = ev->valuators.data[i];
+            (axisval + nvals)->integral = ev->valuators.data_raw[i];
+            axisval++;
+            /* FIXME: frac part */
+        }
+    }
+
+    return Success;
+}
+
 /**
  * Return the corresponding core type for the given event or 0 if no core
  * equivalent exists.
@@ -472,6 +520,7 @@ GetXI2Type(InternalEvent *event)
         case ET_Leave:          xi2type = XI_Leave;            break;
         case ET_Hierarchy:      xi2type = XI_HierarchyChanged; break;
         case ET_DeviceChanged:  xi2type = XI_DeviceChanged;    break;
+        case ET_Raw:            xi2type = XI_RawEvent;         break;
         default:
             break;
     }
diff --git a/dix/events.c b/dix/events.c
index d4eea2c..adc180b 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -420,7 +420,7 @@ static Mask filters[MAXDEVICES][128] = {
  *
  * @see GetEventMask
  */
-static Mask
+Mask
 GetEventFilter(DeviceIntPtr dev, xEvent *event)
 {
     if (event->u.u.type != GenericEvent)
@@ -2215,6 +2215,10 @@ FixUpEventFromWindow(
     if (XI2_EVENT(xE))
     {
         xXIDeviceEvent* event = (xXIDeviceEvent*)xE;
+
+        if (event->evtype == XI_RawEvent)
+            return;
+
         event->root = RootWindow(pDev)->drawable.id;
         event->event = pWin->drawable.id;
         if (pSprite->hot.pScreen == pWin->drawable.pScreen)
diff --git a/dix/getevents.c b/dix/getevents.c
index 01a9864..b0bacbd 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -137,6 +137,33 @@ init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms)
 }
 
 static void
+init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int subtype,
+         int detail)
+{
+    memset(event, 0, sizeof(RawDeviceEvent));
+    event->header = ET_Internal;
+    event->length = sizeof(RawDeviceEvent);
+    event->type = ET_Raw;
+    event->subtype = subtype;
+    event->time = ms;
+    event->deviceid = dev->id;
+    event->sourceid = dev->id;
+    event->detail.button = detail;
+}
+
+static void
+set_raw_valuators(RawDeviceEvent *event, int first, int num, int *valuators, int32_t* data)
+{
+    int i;
+    for (i = first; i < first + num; i++)
+    {
+        SetBit(event->valuators.mask, i);
+        data[i] = valuators[i - first];
+    }
+}
+
+
+static void
 set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator,
               int num_valuators, int *valuators)
 {
@@ -802,6 +829,7 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
     int num_events = 0;
     CARD32 ms = 0;
     DeviceEvent *event;
+    RawDeviceEvent *raw;
 
     if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
        (type != KeyPress && type != KeyRelease) ||
@@ -822,10 +850,21 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
             return 0;
     }
 
+    ms = GetTimeInMillis();
+
+    raw = (RawDeviceEvent*)events->event;
+    events++;
+    num_events++;
+
+    init_raw(pDev, raw, ms, type, key_code);
+    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
+                      raw->valuators.data_raw);
+
     if (num_valuators)
         clipValuators(pDev, first_valuator, num_valuators, valuators);
 
-    ms = GetTimeInMillis();
+    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
+                      raw->valuators.data);
 
     event = (DeviceEvent*) events->event;
     init_event(pDev, event, ms);
@@ -949,6 +988,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     int num_events = 1;
     CARD32 ms;
     DeviceEvent *event;
+    RawDeviceEvent    *raw;
     int x, y, /* switches between device and screen coords */
         cx, cy; /* only screen coordinates */
     ScreenPtr scr = miPointerGetScreen(pDev);
@@ -965,6 +1005,14 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     events = updateFromMaster(events, pDev, &num_events);
 
+    raw = (RawDeviceEvent*)events->event;
+    events++;
+    num_events++;
+
+    init_raw(pDev, raw, ms, type, buttons);
+    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
+                      raw->valuators.data_raw);
+
     if (flags & POINTER_ABSOLUTE)
     {
         if (flags & POINTER_SCREEN) /* valuators are in screen coords */
@@ -985,10 +1033,12 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators);
     }
 
+    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
+                      raw->valuators.data);
+
     positionSprite(pDev, &x, &y, scr, &cx, &cy);
     updateHistory(pDev, first_valuator, num_valuators, ms);
 
-
     /* Update the valuators with the true value sent to the client*/
     if (num_valuators >= 1 && first_valuator == 0)
         valuators[0] = x;
@@ -1023,7 +1073,6 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     set_valuators(pDev, event, first_valuator, num_valuators, valuators);
 
-
     return num_events;
 }
 
diff --git a/include/events.h b/include/events.h
index c6eeae4..a289662 100644
--- a/include/events.h
+++ b/include/events.h
@@ -59,6 +59,7 @@ enum {
 #if XFreeXDGA
     ET_DGAEvent,
 #endif
+    ET_Raw,
     ET_Internal = 0xFF /* First byte */
 } EventType;
 
@@ -171,6 +172,30 @@ typedef struct
 #endif
 
 /**
+ * Raw event, contains the data as posted by the device.
+ */
+typedef struct
+{
+    unsigned char header; /**<  Always ET_Internal */
+    int type;             /**<  ET_Raw */
+    int length;           /**<  Length in bytes */
+    Time time;            /**<  Time in ms */
+    int subtype;          /**<  KeyPress, KeyRelease, ButtonPress,
+                                ButtonRelease, MotionNotify */
+    int deviceid;         /**< Device to post this event for */
+    int sourceid;         /**< The physical source device */
+    union {
+        uint32_t button;  /**< Button number */
+        uint32_t key;     /**< Key code */
+    } detail;
+    struct {
+        uint8_t  mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
+        int32_t  data[MAX_VALUATORS];         /**< Valuator data */
+        int32_t  data_raw[MAX_VALUATORS];     /**< Valuator data as posted */
+    } valuators;
+} RawDeviceEvent;
+
+/**
  * Event type used inside the X server for input event
  * processing.
  */
@@ -188,6 +213,7 @@ typedef struct
 #if XFreeXDGA
         DGAEvent dga;
 #endif
+        RawDeviceEvent raw;
     } u;
 } InternalEvent;
 
diff --git a/mi/mieq.c b/mi/mieq.c
index efec55a..0dedbee 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -277,6 +277,9 @@ ChangeDeviceID(DeviceIntPtr dev, InternalEvent* event)
         case ET_DeviceChanged:
             event->u.device.deviceid = dev->id;
             break;
+        case ET_Raw:
+            event->u.raw.deviceid = dev->id;
+            break;
         default:
             ErrorF("[mi] Unknown event type (%d), cannot change id.\n",
                    event->u.any.type);
commit a668d91e28d5a3042a8ce0d087474883b046869a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Mar 9 16:36:07 2009 +1000

    dix: store the xi2mask on grabs and pass it around as needed.
    
    This enables passive and implicit passive grabs for XI2 events, except that we
    don't have the protocol spec yet to request them.

diff --git a/dix/events.c b/dix/events.c
index 52729ca..d4eea2c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2040,7 +2040,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)
+    if ((type == DeviceButtonPress || type == ButtonPress ||
+        ((XI2_EVENT(pEvents) && ((xGenericEvent*)pEvents)->evtype == XI_ButtonPress)))
             && deliveries
             && (!grab))
     {
@@ -2059,10 +2060,14 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
 	tempGrab.cursor = NullCursor;
         tempGrab.coreGrab = (type == ButtonPress);
 
-        /* get the XI device mask */
+        /* 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);
     }
@@ -3697,6 +3702,19 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 
         if (!deliveries)
         {
+            int evtype = ((xGenericEvent*)xi2)->evtype;
+            mask = grab->xi2mask[AllDevices][evtype/8] |
+                   grab->xi2mask[AllMasterDevices][evtype/8] |
+                   grab->xi2mask[thisDev->id][evtype/8];
+            /* try XI2 event */
+            FixUpEventFromWindow(thisDev, xi2, grab->window, None, TRUE);
+            /* XXX: XACE */
+            deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask,
+                                         GetEventFilter(thisDev, xi2), grab);
+        }
+
+        if (!deliveries)
+        {
             /* try XI event */
             if (grabinfo->fromPassiveGrab  &&
                     grabinfo->implicitGrab)
diff --git a/dix/grabs.c b/dix/grabs.c
index 164e200..156574e 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -82,7 +82,7 @@ CreateGrab(
 {
     GrabPtr grab;
 
-    grab = xalloc(sizeof(GrabRec));
+    grab = xcalloc(1, sizeof(GrabRec));
     if (!grab)
 	return (GrabPtr)NULL;
     grab->resource = FakeClientID(client);
diff --git a/include/inputstr.h b/include/inputstr.h
index 678c171..59fb29b 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -181,6 +181,8 @@ typedef struct _GrabRec {
     CursorPtr		cursor;		/* always NULL for keyboards */
     Mask		eventMask;
     Mask                deviceMask;     
+    /* XI2 event masks. One per device, each bit is a mask of (1 << type) */
+    unsigned char       xi2mask[EMASKSIZE][XI2MASKSIZE];
 } GrabRec;
 
 typedef struct _KeyClassRec {
commit 32f338263ff7de1a2e76d570c98f5be979c18d4e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Mar 8 21:32:31 2009 +1000

    Xi: Deliver XI2 HierarchyEvents when the hierarchy changes.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
index 3df9c87..2b107e7 100644
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2007-2008 Peter Hutterer
+ * Copyright 2009 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"),
@@ -47,11 +48,55 @@
 #include "exglobals.h"
 #include "geext.h"
 #include "xace.h"
+#include "querydev.h" /* for GetDeviceUse */
 
 #include "xkbsrv.h"
 
 #include "chdevhier.h"
 
+/**
+ * Send the current state of the device hierarchy to all clients.
+ */
+void XISendDeviceHierarchyEvent(int flags)
+{
+    xXIDeviceHierarchyEvent *ev;
+    xXIHierarchyInfo *info;
+    DeviceIntRec dummyDev;
+    DeviceIntPtr dev;
+
+    if (!flags)
+        return;
+
+    ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) + inputInfo.numDevices *
+            sizeof(xXIHierarchyInfo));
+    ev->type = GenericEvent;
+    ev->extension = IReqCode;
+    ev->evtype = XI_HierarchyChanged;
+    ev->time = GetTimeInMillis();
+    ev->flags = flags;
+    ev->num_devices = inputInfo.numDevices;
+    ev->length = (ev->num_devices * sizeof(xXIHierarchyInfo))/4;
+
+    info = (xXIHierarchyInfo*)&ev[1];
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+        info->deviceid = dev->id;
+        info->enabled = dev->enabled;
+        info->use = GetDeviceUse(dev, &info->attachment);
+        info++;
+    }
+    for (dev = inputInfo.off_devices; dev; dev = dev->next)
+    {
+        info->deviceid = dev->id;
+        info->enabled = dev->enabled;
+        info->use = GetDeviceUse(dev, &info->attachment);
+        info++;
+    }
+
+    dummyDev.id = AllDevices;
+    SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1);
+}
+
 
 /***********************************************************************
  *
@@ -75,17 +120,18 @@ int
 ProcXIChangeDeviceHierarchy(ClientPtr client)
 {
     DeviceIntPtr ptr, keybd;
-    DeviceIntRec dummyDev;
     xXIAnyHierarchyChangeInfo *any;
     int required_len = sizeof(xXIChangeDeviceHierarchyReq);
     char n;
     int rc = Success;
-    int nchanges = 0;
-    xXIDeviceHierarchyEvent ev;
+    int flags = 0;
 
     REQUEST(xXIChangeDeviceHierarchyReq);
     REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq);
 
+    if (!stuff->num_changes)
+        return rc;
+
     any = (xXIAnyHierarchyChangeInfo*)&stuff[1];
     while(stuff->num_changes--)
     {
@@ -127,7 +173,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                         EnableDevice(keybd);
                     }
                     xfree(name);
-                    nchanges++;
+                    flags |= HF_MasterAdded;
                 }
                 break;
             case CH_RemoveMasterDevice:
@@ -233,7 +279,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
 
                     RemoveDevice(keybd);
                     RemoveDevice(ptr);
-                    nchanges++;
+                    flags |= HF_MasterRemoved;
                 }
                 break;
             case CH_DetachSlave:
@@ -253,7 +299,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                     }
 
                     AttachDevice(client, ptr, NULL);
-                    nchanges++;
+                    flags |= HF_SlaveDetached;
                 }
                 break;
             case CH_AttachSlave:
@@ -293,7 +339,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
                         goto unwind;
                     }
                     AttachDevice(client, ptr, newmaster);
-                    nchanges++;
+                    flags |= HF_SlaveAttached;
                 }
                 break;
         }
@@ -303,18 +349,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
 
 unwind:
 
-    if (nchanges > 0) /* even if an error occured, we need to send an event if
-                       we changed anything in the hierarchy. */
-    {
-        ev.type = GenericEvent;
-        ev.extension = IReqCode;
-        ev.length = 0;
-        ev.evtype = XI_HierarchyChanged;
-        ev.time = GetTimeInMillis();
-
-        SendEventToAllWindows(&dummyDev, XI_DeviceHierarchyChangedMask,
-                (xEvent*)&ev, 1);
-    }
+    XISendDeviceHierarchyEvent(flags);
     return rc;
 }
 
diff --git a/Xi/chdevhier.h b/Xi/chdevhier.h
index 4190538..d2d1001 100644
--- a/Xi/chdevhier.h
+++ b/Xi/chdevhier.h
@@ -39,4 +39,6 @@
 int SProcXIChangeDeviceHierarchy(ClientPtr /* client */);
 int ProcXIChangeDeviceHierarchy(ClientPtr /* client */);
 
+void XISendDeviceHierarchyEvent(int flags);
+
 #endif
diff --git a/Xi/extinit.c b/Xi/extinit.c
index f0aa9f6..8c9f9e1 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -739,6 +739,32 @@ static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to)
     }
 }
 
+static void SDeviceHierarchyEvent(xXIDeviceHierarchyEvent *from,
+                                  xXIDeviceHierarchyEvent *to)
+{
+    int i;
+    char n;
+    xXIHierarchyInfo *info;
+
+    *to = *from;
+    memcpy(&to[1], &from[1], from->length * 4);
+    swaps(&to->sequenceNumber, n);
+    swapl(&to->length, n);
+    swaps(&to->evtype, n);
+    swaps(&to->deviceid, n);
+    swapl(&to->time, n);
+    swapl(&to->flags, n);
+    swaps(&to->num_devices, n);
+
+    info = (xXIHierarchyInfo*)&to[1];
+    for (i = 0; i< from->num_devices; i++)
+    {
+        swaps(&info->deviceid, n);
+        swaps(&info->attachment, n);
+        info++;
+    }
+}
+
 /** Event swapping function for XI2 events. */
 static void
 XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
@@ -753,6 +779,9 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
             SDeviceChangedEvent((xXIDeviceChangedEvent*)from,
                                 (xXIDeviceChangedEvent*)to);
             break;
+        case XI_HierarchyChanged:
+            SDeviceHierarchyEvent((xXIDeviceHierarchyEvent*)from,
+                                  (xXIDeviceHierarchyEvent*)to);
         default:
             SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to);
             break;
commit 97e89a59572a4be6757510a317c142ec1d82e8f8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 6 23:22:00 2009 +1000

    Allow XI2 event selection for AllDevices and AllMasterDevices.

diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
index 87811dc..cdb9c6f 100644
--- a/Xi/xiselectev.c
+++ b/Xi/xiselectev.c
@@ -67,6 +67,7 @@ ProcXISelectEvent(ClientPtr client)
     int rc, num_masks, i;
     WindowPtr win;
     DeviceIntPtr dev;
+    DeviceIntRec dummy;
     xXIDeviceEventMask *evmask;
     int *types = NULL;
 
@@ -109,7 +110,13 @@ ProcXISelectEvent(ClientPtr client)
     num_masks = stuff->num_masks;
     while(num_masks--)
     {
-        dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess);
+        if (evmask->deviceid == AllDevices ||
+            evmask->deviceid == AllMasterDevices)
+        {
+            dummy.id = evmask->deviceid;
+            dev = &dummy;
+        } else
+            dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess);
         XISetEventMask(dev, win, client, evmask->mask_len * 4, (unsigned char*)&evmask[1]);
         evmask = (xXIDeviceEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
     }
diff --git a/dix/events.c b/dix/events.c
index 177fa05..52729ca 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -459,7 +459,9 @@ GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other)
     if (XI2_EVENT(event))
     {
         int byte = ((xGenericEvent*)event)->evtype / 8;
-        return other->xi2mask[dev->id][byte];
+        return (other->xi2mask[dev->id][byte] |
+                other->xi2mask[AllDevices][byte] |
+                (dev->isMaster? other->xi2mask[AllMasterDevices][byte] : 0));
     } else if (CORE_EVENT(event))
         return other->mask[AllDevices];
     else
@@ -1995,10 +1997,8 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
         else if (XI2_EVENT(pEvents))
         {
             OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
-            int evtype = ((xGenericEvent*)pEvents)->evtype;
             /* Has any client selected for the event? */
-            if (!inputMasks ||
-                !(inputMasks->xi2mask[mskidx][evtype/8] & filter))
+            if (!GetWindowXI2Mask(pDev, pWin, pEvents))
                 return 0;
             other = inputMasks->inputClients;
         } else {
@@ -2291,7 +2291,9 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
     ((xGenericEvent*)&ev)->evtype = type;
     filter = GetEventFilter(dev, &ev);
     if (type && (inputMasks = wOtherInputMasks(win)) &&
-        inputMasks->xi2mask[dev->id][type / 8] & filter)
+        ((inputMasks->xi2mask[AllDevices][type/8] & filter) ||
+         ((inputMasks->xi2mask[AllMasterDevices][type/8] & filter) && dev->isMaster) ||
+         (inputMasks->xi2mask[dev->id][type/8] & filter)))
         rc |= XI2_MASK;
 
     type = GetXIType(event);
commit 808a158182b0a3b985385899252c190947b4dbbd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 6 14:45:26 2009 +1000

    dix: Enable XI2 delivery for events and focused events.
    
    No support for grabbed events yet.

diff --git a/dix/events.c b/dix/events.c
index 72b077b..177fa05 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -409,16 +409,24 @@ static Mask filters[MAXDEVICES][128] = {
  * For the given event, return the matching event filter. This filter may then
  * be AND'ed with the selected event mask.
  *
+ * For XI2 events, the returned filter is simply the byte containing the event
+ * mask we're interested in. E.g. for a mask of (1 << 13), this would be
+ * byte[1].
+ *
  * @param[in] dev The device the event belongs to, may be NULL.
  * @param[in] event The event to get the filter for. Only the type of the
  *                  event matters, or the extension + evtype for GenericEvents.
  * @return The filter mask for the given event.
+ *
+ * @see GetEventMask
  */
 static Mask
 GetEventFilter(DeviceIntPtr dev, xEvent *event)
 {
     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));
     ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type);
     return 0;
 }
@@ -444,6 +452,21 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
             (inputMasks->xi2mask[AllMasterDevices][evtype/8] && dev->isMaster));
 }
 
+static Mask
+GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other)
+{
+    /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */
+    if (XI2_EVENT(event))
+    {
+        int byte = ((xGenericEvent*)event)->evtype / 8;
+        return other->xi2mask[dev->id][byte];
+    } else if (CORE_EVENT(event))
+        return other->mask[AllDevices];
+    else
+        return other->mask[dev->id];
+}
+
+
 static CARD8 criticalEvents[32] =
 {
     0x7c, 0x30, 0x40			/* key, button, expose, and configure events */
@@ -1969,7 +1992,16 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
     {
         if (CORE_EVENT(pEvents))
             other = (InputClients *)wOtherClients(pWin);
-        else {
+        else if (XI2_EVENT(pEvents))
+        {
+            OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
+            int evtype = ((xGenericEvent*)pEvents)->evtype;
+            /* Has any client selected for the event? */
+            if (!inputMasks ||
+                !(inputMasks->xi2mask[mskidx][evtype/8] & filter))
+                return 0;
+            other = inputMasks->inputClients;
+        } else {
             OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
             /* Has any client selected for the event? */
             if (!inputMasks ||
@@ -1981,22 +2013,24 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
 
         for (; other; other = other->next)
         {
+            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,
-                            other->mask[mskidx],
-                            filter, grab)) )
+                            mask, filter, grab)) )
             {
                 if (attempt > 0)
                 {
                     deliveries++;
                     client = rClient(other);
-                    deliveryMask = other->mask[mskidx];
+                    deliveryMask = mask;
                 } else
                     nondeliveries--;
             }
@@ -2225,6 +2259,7 @@ FixUpEventFromWindow(
 #define XI_MASK                 (1 << 0) /**< XI mask set on window */
 #define CORE_MASK               (1 << 1) /**< Core mask set on window */
 #define DONT_PROPAGATE_MASK     (1 << 2) /**< DontPropagate mask set on window */
+#define XI2_MASK                (1 << 3) /**< XI2 mask set on window */
 /* @} */
 
 /**
@@ -2236,13 +2271,12 @@ FixUpEventFromWindow(
  * @param[in] dev The device this event is being sent for.
  * @param[in] event The event that is to be sent.
  * @param[in] win The current event window.
- * @param[out] filter_out The event filter for this event.
  *
- * @return Bitmask of ::XI_MASK, ::CORE_MASK, and ::DONT_PROPAGATE_MASK.
+ * @return Bitmask of ::XI2_MASK, ::XI_MASK, ::CORE_MASK, and
+ * ::DONT_PROPAGATE_MASK.
  */
 static int
-EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win,
-                   Mask *filter_out)
+EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
 {
     int rc = 0;
     int filter = 0;
@@ -2250,12 +2284,22 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win,
     OtherInputMasks *inputMasks;
     xEvent ev;
 
+    /* XXX: this makes me gag */
+    type = GetXI2Type(event);
+    ev.u.u.type = GenericEvent; /* GetEventFilter only cares about type and evtype*/
+    ((xGenericEvent*)&ev)->extension = IReqCode;
+    ((xGenericEvent*)&ev)->evtype = type;
+    filter = GetEventFilter(dev, &ev);
+    if (type && (inputMasks = wOtherInputMasks(win)) &&
+        inputMasks->xi2mask[dev->id][type / 8] & filter)
+        rc |= XI2_MASK;
+
     type = GetXIType(event);
-    ev.u.u.type = type; /* GetEventFilter only cares about type */
+    ev.u.u.type = type;
     filter = GetEventFilter(dev, &ev);
 
     /* Check for XI mask */
-    if (type && (inputMasks = wOtherInputMasks(win)) &&
+    if (type && inputMasks &&
         (inputMasks->deliverableEvents[dev->id] & filter) &&
         (inputMasks->inputEvents[dev->id] & filter))
         rc |= XI_MASK;
@@ -2275,7 +2319,6 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win,
     if (type && (filter & wDontPropagateMask(win)))
         rc |= DONT_PROPAGATE_MASK;
 
-    *filter_out = filter;
     return rc;
 }
 
@@ -2330,11 +2373,31 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
 
     while (pWin)
     {
-        if ((mask = EventIsDeliverable(dev, event, pWin, &filter)))
+        if ((mask = EventIsDeliverable(dev, event, pWin)))
         {
+            if (mask & XI2_MASK)
+            {
+                xEvent *xi2 = NULL;
+                rc = EventToXI2(event, &xi2);
+                if (rc != Success)
+                {
+                    ErrorF("[dix] %s: XI2 conversion failed in DDE (%d).\n",
+                            dev->name, rc);
+                    goto unwind;
+                }
+                filter = GetEventFilter(dev, xi2);
+                FixUpEventFromWindow(dev, xi2, pWin, child, FALSE);
+                deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1,
+                                                   filter, grab, dev->id);
+                xfree(xi2);
+                if (deliveries > 0)
+                    goto unwind;
+            }
+
             /* XI events first */
             if (mask & XI_MASK)
             {
+                filter = GetEventFilter(dev, xE);
                 FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
                 deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
                                                    filter, grab, dev->id);
@@ -2354,6 +2417,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                     goto unwind;
                 }
 
+                filter = GetEventFilter(dev, &core);
                 FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
                 deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
                                                    filter, grab, dev->id);
@@ -3232,6 +3296,7 @@ CheckPassiveGrabsOnWindow(
             xkbi= gdev->key->xkbInfo;
 	tempGrab.modifierDevice = grab->modifierDevice;
         tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
+        /* FIXME: check for xi2 grabs */
 
         /* Check for XI grabs first */
         tempGrab.type = GetXIType((InternalEvent*)event);
@@ -3435,7 +3500,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     WindowPtr focus = keybd->focus->win;
     BOOL sendCore = (keybd->isMaster && keybd->coreEvents);
     xEvent core;
-    xEvent *xE = NULL;
+    xEvent *xE = NULL, *xi2 = NULL;
     int count, rc;
     int deliveries = 0;
 
@@ -3455,7 +3520,6 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     }
     ptr = GetPairedDevice(keybd);
 
-
     rc = EventToXI(event, &xE, &count);
     if (rc != Success)
     {
@@ -3468,6 +3532,23 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count))
 	goto unwind;
 
+    rc = EventToXI2(event, &xi2);
+    if (rc != Success)
+    {
+        ErrorF("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n",
+               keybd->name, event->u.any.type, rc);
+        goto unwind;
+    } else if (xi2)
+    {
+        int filter = GetEventFilter(keybd, xi2);
+        /* just deliver it to the focus window */
+        FixUpEventFromWindow(ptr, xi2, focus, None, FALSE);
+        deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1,
+                                           filter, NullGrab, keybd->id);
+        if (deliveries > 0)
+            goto unwind;
+    }
+
     /* just deliver it to the focus window */
     FixUpEventFromWindow(ptr, xE, focus, None, FALSE);
     deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
@@ -3496,6 +3577,8 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
 unwind:
     if (xE)
         xfree(xE);
+    if (xi2)
+        xfree(xi2);
     return;
 }
 
@@ -3518,6 +3601,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
     BOOL sendCore = FALSE;
     int rc, count = 0;
     xEvent *xi = NULL;
+    xEvent *xi2 = NULL;
 
     grabinfo = &thisDev->deviceGrab;
     grab = grabinfo->grab;
@@ -3554,12 +3638,21 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
     if (!deliveries)
     {
         Mask mask;
+
         /* XXX: In theory, we could pass the internal events through to
          * everything and only convert just before hitting the wire. We can't
          * do that yet, so DGE is the last stop for internal events. From here
          * onwards, we deal with core/XI events.
          */
 
+        rc = EventToXI2(event, &xi2);
+        if (rc != Success)
+        {
+            ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n",
+                    thisDev->name, event->u.any.type, rc);
+            goto unwind;
+        }
+
         rc = EventToXI(event, &xi, &count);
         if (rc != Success)
         {
@@ -3660,6 +3753,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 unwind:
     if (xi)
         xfree(xi);
+    if (xi2)
+        xfree(xi2);
 }
 
 /* This function is used to set the key pressed or key released state -
commit 87ff1159b497c66554a4036ae619f92d5631f00f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 11 09:01:23 2009 +1000

    dix: deliver device enter/leave events.

diff --git a/Xi/extinit.c b/Xi/extinit.c
index a83a20e..f0aa9f6 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -624,6 +624,10 @@ SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to)
     swaps(&to->event_y.integral, n);
     swaps(&to->event_y.frac, n);
     swaps(&to->sourceid, n);
+    swaps(&to->buttons_len, n);
+    swapl(&to->mods.base_mods, n);
+    swapl(&to->mods.latched_mods, n);
+    swapl(&to->mods.locked_mods, n);
 }
 
 static void
diff --git a/dix/events.c b/dix/events.c
index 43af7c7..72b077b 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -4015,57 +4015,62 @@ DeviceEnterLeaveEvent(
     Window child)
 {
     GrabPtr             grab = mouse->deviceGrab.grab;
-    xXIEnterEvent       event;
-    int                 mskidx;
-    OtherInputMasks     *inputMasks;
+    xXIEnterEvent       *event;
     Mask                mask;
-    xEvent              dummy;
+    int                 filter;
+    int                 btlen, len, i;
+    DeviceIntPtr        kbd;
 
-    if (grab) {
-        mask = (pWin == grab->window) ? grab->eventMask : 0;
-        if (grab->ownerEvents)
-            mask |= EventMaskForClient(pWin, rClient(grab));
-    } else {
-        mask = pWin->eventMask | wOtherEventMasks(pWin);
-    }
-
-    memset(&event, 0, sizeof(event));
-    event.type        = GenericEvent;
-    event.extension   = IReqCode;
-    event.evtype      = type;
-    event.detail      = detail;
-    event.time        = currentTime.milliseconds;
-    event.deviceid    = mouse->id;
-    event.sourceid    = 0; /*XXX */
-    event.mode        = mode;
-    event.root_x.integral      = mouse->spriteInfo->sprite->hot.x;
-    event.root_y.integral      = mouse->spriteInfo->sprite->hot.y;
-
-    /* We use FUEFW to fill in dummy, then copy the values */
-    FixUpEventFromWindow(mouse, &dummy, pWin, None, FALSE);
-
-    event.same_screen = dummy.u.keyButtonPointer.sameScreen;
-    event.child       = dummy.u.keyButtonPointer.child;
-    event.event_x.integral     = dummy.u.keyButtonPointer.eventX;
-    event.event_y.integral     = dummy.u.keyButtonPointer.eventY;
-
-    mskidx = mouse->id;
-    inputMasks = wOtherInputMasks(pWin);
-    if (inputMasks &&
-       (GetEventFilter(mouse, (xEvent*)&event) &
-            inputMasks->deliverableEvents[mskidx]))
+    btlen = (mouse->button) ? (mouse->button->numButtons + 7)/8 : 0;
+    btlen = (btlen + 3)/4;
+    len = sizeof(xXIEnterEvent) + btlen * 4;
+
+    event = xcalloc(1, len);
+    event->type         = GenericEvent;
+    event->extension    = IReqCode;
+    event->evtype       = type;
+    event->length       = (len - sizeof(xEvent))/4;
+    event->buttons_len  = btlen;
+    event->detail       = detail;
+    event->time         = currentTime.milliseconds;
+    event->deviceid     = mouse->id;
+    event->sourceid     = 0; /*XXX */
+    event->mode         = mode;
+    event->root_x.integral      = mouse->spriteInfo->sprite->hot.x;
+    event->root_y.integral      = mouse->spriteInfo->sprite->hot.y;
+
+    for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+        if (BitIsOn(mouse->button->down, i))
+            SetBit(&event[1], i);
+
+    kbd = (mouse->isMaster || mouse->u.master) ? GetPairedDevice(mouse) : NULL;
+    if (kbd && kbd->key)
     {
-        if (grab)
-            TryClientEvents(rClient(grab), mouse,
-                            (xEvent*)&event, 1, mask,
-                            GetEventFilter(mouse, (xEvent*)&event),
-                            grab);
-        else
-            DeliverEventsToWindow(mouse, pWin, (xEvent*)&event, 1,
-                                  GetEventFilter(mouse, (xEvent*)&event),
-                                  NullGrab, mouse->id);
+        event->mods.base_mods = kbd->key->xkbInfo->state.base_mods;
+        event->mods.latched_mods = kbd->key->xkbInfo->state.latched_mods;
+        event->mods.locked_mods = kbd->key->xkbInfo->state.locked_mods;
+
+        event->group.base_group = kbd->key->xkbInfo->state.base_group;
+        event->group.latched_group = kbd->key->xkbInfo->state.latched_group;
+        event->group.locked_group = kbd->key->xkbInfo->state.locked_group;
     }
 
+    FixUpEventFromWindow(mouse, (xEvent*)event, pWin, None, FALSE);
+
+
+    if (!GetWindowXI2Mask(mouse, pWin, (xEvent*)event))
+        return;
+
+    filter = GetEventFilter(mouse, (xEvent*)event);
+    mask = 0x0; /* FIXME: we should handle grabs, once we can */
+
+    if (grab)
+        TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask,
+                        filter, grab);
+    else
+        DeliverEventsToWindow(mouse, pWin, (xEvent*)event, 1, filter,
+                              NullGrab, mouse->id);
+    xfree(event);
 }
 
 void
commit 04ed0bcb2530866f7248b412974ecd15f0fbf6ac
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 23 17:07:55 2009 +1000

    xkb: remove Device/Enter leave handling - XI2 enter/leave don't have compat state.

diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c
index 9293c60..d7a186b 100644
--- a/xkb/xkbEvents.c
+++ b/xkb/xkbEvents.c
@@ -1037,10 +1037,6 @@ XkbSrvInfoPtr	xkbi;
 		     new|= xkbi->state.compat_lookup_mods;
 		else new|= xkbi->state.compat_grab_mods;
                 kbp->state= new;
-            } else if ((type==DeviceEnterNotify)||(type==DeviceLeaveNotify)) {
-                deviceEnterNotify *del = (deviceEnterNotify*)&xE[i];
-                del->state&=0x1F00;
-                del->state|= xkbi->state.compat_grab_mods;
             }
 	    button_mask = 1 << xE[i].u.u.detail;
 	    if (type == ButtonPress &&
commit 3f37923a727d5fc4b1880a53dac1145884ba7140
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 23 16:12:25 2009 +1000

    Xi: send XI2 focus events.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index cee6823..8404335 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1164,15 +1164,58 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
 		 WindowPtr pWin)
 {
     deviceFocus event;
+    xXIFocusInEvent *xi2event;
+    DeviceIntPtr mouse;
+    int btlen, len, i;
+
+    mouse = (dev->isMaster || dev->u.master) ? GetPairedDevice(dev) : NULL;
+
+    /* XI 2 event */
+    btlen = (mouse->button) ? (mouse->button->numButtons + 7)/8 : 0;
+    btlen = (btlen + 3)/4;
+    len = sizeof(xXIFocusInEvent) + btlen * 4;
+
+    xi2event = xcalloc(1, len);
+    xi2event->type         = GenericEvent;
+    xi2event->extension    = IReqCode;
+    xi2event->evtype       = type;
+    xi2event->length       = (len - sizeof(xEvent))/4;
+    xi2event->buttons_len  = btlen;
+    xi2event->detail       = detail;
+    xi2event->time         = currentTime.milliseconds;
+    xi2event->deviceid     = dev->id;
+    xi2event->sourceid     = 0; /*XXX */
+    xi2event->mode         = mode;
+    xi2event->root_x.integral      = mouse->spriteInfo->sprite->hot.x;
+    xi2event->root_y.integral      = mouse->spriteInfo->sprite->hot.y;
 
-    if (type == FocusIn)
-	type = DeviceFocusIn;
-    else
-	type = DeviceFocusOut;
+    for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+        if (BitIsOn(mouse->button->down, i))
+            SetBit(&xi2event[1], i);
+
+    if (dev->key)
+    {
+        xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods;
+        xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods;
+        xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods;
+
+        xi2event->group.base_group = dev->key->xkbInfo->state.base_group;
+        xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group;
+        xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group;
+    }
+
+    FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE);
+
+    DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1,
+                          GetWindowXI2Mask(dev, pWin, xi2event), NullGrab,
+                          dev->id);
+
+    xfree(xi2event);
 
+    /* XI 1.x event */
     event.deviceid = dev->id;
     event.mode = mode;
-    event.type = type;
+    event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut;
     event.detail = detail;
     event.window = pWin->drawable.id;
     event.time = currentTime.milliseconds;
diff --git a/dix/enterleave.c b/dix/enterleave.c
index 3f5d06f..e45d061 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -629,7 +629,7 @@ DeviceFocusOutEvents(DeviceIntPtr dev,
     if (ancestor == child)
 	return;
     for (win = child->parent; win != ancestor; win = win->parent)
-        DeviceFocusEvent(dev, DeviceFocusOut, mode, detail, win);
+        DeviceFocusEvent(dev, XI_FocusOut, mode, detail, win);
 }
 
 
@@ -650,7 +650,7 @@ DeviceFocusInEvents(DeviceIntPtr dev,
     if (ancestor == parent || !parent)
 	return;
     DeviceFocusInEvents(dev, ancestor, parent, mode, detail);
-    DeviceFocusEvent(dev, DeviceFocusIn, mode, detail, parent);
+    DeviceFocusEvent(dev, XI_FocusIn, mode, detail, parent);
 }
 
 /**
@@ -1275,21 +1275,21 @@ DeviceFocusEvents(DeviceIntPtr dev,
                         NotifyPointer);
             /* Notify all the roots */
             for (i = 0; i < nscreens; i++)
-                DeviceFocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+                DeviceFocusEvent(dev, XI_FocusOut, mode, out, WindowTable[i]);
         }
         else
         {
             if (IsParent(from, sprite->win))
                 DeviceFocusOutEvents(dev, sprite->win, from, mode,
                         NotifyPointer);
-            DeviceFocusEvent(dev, FocusOut, mode, NotifyNonlinear, from);
+            DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from);
             /* next call catches the root too, if the screen changed */
             DeviceFocusOutEvents(dev, from->parent, NullWindow, mode,
                     NotifyNonlinearVirtual);
         }
         /* Notify all the roots */
         for (i = 0; i < nscreens; i++)
-            DeviceFocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
+            DeviceFocusEvent(dev, XI_FocusIn, mode, in, WindowTable[i]);
         if (to == PointerRootWin)
             DeviceFocusInEvents(dev, RootWindow(dev), sprite->win, mode, NotifyPointer);
     }
@@ -1301,10 +1301,10 @@ DeviceFocusEvents(DeviceIntPtr dev,
                 DeviceFocusOutEvents(dev, sprite->win, RootWindow(dev), mode,
                         NotifyPointer);
             for (i = 0; i < nscreens; i++)
-                DeviceFocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
+                DeviceFocusEvent(dev, XI_FocusOut, mode, out, WindowTable[i]);
             if (to->parent != NullWindow)
                 DeviceFocusInEvents(dev, RootWindow(dev), to, mode, NotifyNonlinearVirtual);
-            DeviceFocusEvent(dev, FocusIn, mode, NotifyNonlinear, to);
+            DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyNonlinear, to);
             if (IsParent(to, sprite->win))
                 DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer);
         }
@@ -1312,10 +1312,10 @@ DeviceFocusEvents(DeviceIntPtr dev,
         {
             if (IsParent(to, from))
             {
-                DeviceFocusEvent(dev, FocusOut, mode, NotifyAncestor, from);
+                DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyAncestor, from);
                 DeviceFocusOutEvents(dev, from->parent, to, mode,
                         NotifyVirtual);
-                DeviceFocusEvent(dev, FocusIn, mode, NotifyInferior, to);
+                DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyInferior, to);
                 if ((IsParent(to, sprite->win)) &&
                         (sprite->win != from) &&
                         (!IsParent(from, sprite->win)) &&
@@ -1331,9 +1331,9 @@ DeviceFocusEvents(DeviceIntPtr dev,
                             (!IsParent(sprite->win, to)))
                         DeviceFocusOutEvents(dev, sprite->win, from, mode,
                                 NotifyPointer);
-                    DeviceFocusEvent(dev, FocusOut, mode, NotifyInferior, from);
+                    DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyInferior, from);
                     DeviceFocusInEvents(dev, from, to, mode, NotifyVirtual);
-                    DeviceFocusEvent(dev, FocusIn, mode, NotifyAncestor, to);
+                    DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyAncestor, to);
                 }
                 else
                 {
@@ -1343,13 +1343,13 @@ DeviceFocusEvents(DeviceIntPtr dev,
                     if (IsParent(from, sprite->win))
                         DeviceFocusOutEvents(dev, sprite->win, from, mode,
                                 NotifyPointer);
-                    DeviceFocusEvent(dev, FocusOut, mode, NotifyNonlinear, from);
+                    DeviceFocusEvent(dev, XI_FocusOut, mode, NotifyNonlinear, from);
                     if (from->parent != NullWindow)
                         DeviceFocusOutEvents(dev, from->parent, common, mode,
                                 NotifyNonlinearVirtual);
                     if (to->parent != NullWindow)
                         DeviceFocusInEvents(dev, common, to, mode, NotifyNonlinearVirtual);
-                    DeviceFocusEvent(dev, FocusIn, mode, NotifyNonlinear, to);
+                    DeviceFocusEvent(dev, XI_FocusIn, mode, NotifyNonlinear, to);
                     if (IsParent(to, sprite->win))
                         DeviceFocusInEvents(dev, to, sprite->win, mode, NotifyPointer);
                 }
diff --git a/dix/events.c b/dix/events.c
index 0b704ca..43af7c7 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2160,7 +2160,7 @@ static Window FindChildForEvent(DeviceIntPtr dev, WindowPtr event)
  * @param child Child window setting for event (if applicable)
  * @param calcChild If True, calculate the child window.
  */
-static void
+void
 FixUpEventFromWindow(
     DeviceIntPtr pDev,
     xEvent *xE,
commit daf7dd3bfecc9029bdd10c7a4ea5d2c875a89c41
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 11 09:01:12 2009 +1000

    dix: Add GetWindowXI2Mask helper

diff --git a/dix/events.c b/dix/events.c
index 6277941..0b704ca 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -423,6 +423,26 @@ GetEventFilter(DeviceIntPtr dev, xEvent *event)
     return 0;
 }
 
+/**
+ * Return the windows complete XI2 mask for the given XI2 event type.
+ */
+Mask
+GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
+{
+    OtherInputMasks *inputMasks = wOtherInputMasks(win);
+    int filter;
+    int evtype;
+
+    if (!inputMasks || !XI2_EVENT(ev))
+        return 0;
+
+    evtype = ((xGenericEvent*)ev)->evtype;
+    filter = GetEventFilter(dev, ev);
+
+    return ((inputMasks->xi2mask[dev->id][evtype/8] & filter) ||
+            inputMasks->xi2mask[AllDevices][evtype/8] ||
+            (inputMasks->xi2mask[AllMasterDevices][evtype/8] && dev->isMaster));
+}
 
 static CARD8 criticalEvents[32] =
 {
commit 8b6a370058ad5a20e0a0e49ec9443daf03775de8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 23 15:58:07 2009 +1000

    Add XI2 masks and XISelectEvent() request handling.
    
    XI2 event masks are simply stored in the OtherEventMasks as a separate field.
    This replaces the XiSelectEvent code.

diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 10521fd..5483000 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -94,7 +94,7 @@ libXi_la_SOURCES =	\
 	warpdevp.h \
 	xiproperty.c \
 	xiproperty.h \
-	xiselev.c \
-	xiselev.h
+	xiselectev.c \
+	xiselectev.h
 
 EXTRA_DIST = stubs.c
diff --git a/Xi/exevents.c b/Xi/exevents.c
index fe11694..cee6823 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1499,15 +1499,20 @@ RecalculateDeviceDeliverableEvents(WindowPtr pWin)
     InputClientsPtr others;
     struct _OtherInputMasks *inputMasks;	/* default: NULL */
     WindowPtr pChild, tmp;
-    int i;
+    int i, j;
 
     pChild = pWin;
     while (1) {
 	if ((inputMasks = wOtherInputMasks(pChild)) != 0) {
+            for (i = 0; i < EMASKSIZE; i++)
+                memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i]));
 	    for (others = inputMasks->inputClients; others;
 		 others = others->next) {
 		for (i = 0; i < EMASKSIZE; i++)
 		    inputMasks->inputEvents[i] |= others->mask[i];
+                for (i = 0; i < EMASKSIZE; i++)
+                    for (j = 0; j < XI2MASKSIZE; j++)
+                        inputMasks->xi2mask[i][j] |= others->xi2mask[i][j];
 	    }
 	    for (i = 0; i < EMASKSIZE; i++)
 		inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
@@ -1955,3 +1960,41 @@ SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count)
     }
 }
 
+/**
+ * Set the XI2 mask for the given client on the given window.
+ * @param dev The device to set the mask for.
+ * @param win The window to set the mask on.
+ * @param client The client setting the mask.
+ * @param len Number of bytes in mask.
+ * @param mask Event mask in the form of (1 << eventtype)
+ */
+void
+XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
+               unsigned int len, unsigned char* mask)
+{
+    OtherInputMasks *masks;
+    InputClientsPtr others = NULL;
+
+    masks = wOtherInputMasks(win);
+    if (masks)
+    {
+	for (others = wOtherInputMasks(win)->inputClients; others;
+	     others = others->next) {
+	    if (SameClient(others, client)) {
+                memset(others->xi2mask[dev->id], 0,
+                       sizeof(others->xi2mask[dev->id]));
+                break;
+            }
+        }
+    }
+
+    if (!others && len)
+    {
+        AddExtensionClient(win, client, 0, 0);
+        others= wOtherInputMasks(win)->inputClients;
+    }
+
+    memcpy(others->xi2mask[dev->id], mask, len);
+
+    RecalculateDeviceDeliverableEvents(win);
+}
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 5e87451..a83a20e 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -119,7 +119,7 @@ SOFTWARE.
 #include "ungrdevb.h"
 #include "ungrdevk.h"
 #include "warpdevp.h"
-#include "xiselev.h"
+#include "xiselectev.h"
 #include "xiproperty.h"
 
 
@@ -237,7 +237,7 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXIChangeDeviceHierarchy,            /* 43 */
         ProcXISetClientPointer,                 /* 44 */
         ProcXIGetClientPointer,                 /* 45 */
-        ProcXiSelectEvent,                      /* 46 */
+        ProcXISelectEvent,                      /* 46 */
         ProcXIQueryVersion,                     /* 47 */
         ProcXIQueryDevice                       /* 48 */
 };
@@ -290,7 +290,7 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXIChangeDeviceHierarchy,            /* 43 */
         SProcXISetClientPointer,                 /* 44 */
         SProcXIGetClientPointer,                 /* 45 */
-        SProcXiSelectEvent,                      /* 46 */
+        SProcXISelectEvent,                      /* 46 */
         SProcXIQueryVersion,                     /* 47 */
         SProcXIQueryDevice                       /* 48 */
 };
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
new file mode 100644
index 0000000..87811dc
--- /dev/null
+++ b/Xi/xiselectev.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2008 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+
+#include "dixstruct.h"
+#include "windowstr.h"
+#include "exglobals.h"
+#include "exevents.h"
+#include <X11/extensions/XI2proto.h>
+
+#include "xiselectev.h"
+
+int
+SProcXISelectEvent(ClientPtr client)
+{
+    char n;
+    int i;
+    xXIDeviceEventMask* evmask;
+    uint16_t *evtype;
+
+    REQUEST(xXISelectEventsReq);
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xXISelectEventsReq);
+    swapl(&stuff->window, n);
+    swaps(&stuff->num_masks, n);
+
+    evmask = (xXIDeviceEventMask*)&stuff[1];
+    for (i = 0; i < stuff->num_masks; i++)
+    {
+        swaps(&evmask->deviceid, n);
+        swaps(&evmask->mask_len, n);
+        evmask = (xXIDeviceEventMask*)(((char*)evtype) + evmask->mask_len * 4);
+    }
+
+    return (ProcXISelectEvent(client));
+}
+
+int
+ProcXISelectEvent(ClientPtr client)
+{
+    int rc, num_masks, i;
+    WindowPtr win;
+    DeviceIntPtr dev;
+    xXIDeviceEventMask *evmask;
+    int *types = NULL;
+
+    REQUEST(xXISelectEventsReq);
+    REQUEST_AT_LEAST_SIZE(xXISelectEventsReq);
+
+    rc = dixLookupWindow(&win, stuff->window, client, DixReceiveAccess);
+    if (rc != Success)
+        return rc;
+
+    /* check request validity */
+    evmask = (xXIDeviceEventMask*)&stuff[1];
+    num_masks = stuff->num_masks;
+    while(num_masks--)
+    {
+        if (evmask->deviceid != AllDevices && evmask->deviceid != AllMasterDevices)
+            rc = dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess);
+        else {
+            /* XXX: XACE here? */
+        }
+        if (rc != Success)
+            return rc;
+
+
+        if ((evmask->mask_len * 4) > XI_LASTEVENT)
+        {
+            unsigned char *bits = (unsigned char*)&evmask[1];
+            for (i = XI_LASTEVENT; i < evmask->mask_len * 4; i++)
+            {
+                if (BitIsOn(bits, i))
+                    return BadValue;
+            }
+        }
+
+        evmask = (xXIDeviceEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+    }
+
+    /* Set masks on window */
+    evmask = (xXIDeviceEventMask*)&stuff[1];
+    num_masks = stuff->num_masks;
+    while(num_masks--)
+    {
+        dixLookupDevice(&dev, evmask->deviceid, client, DixReadAccess);
+        XISetEventMask(dev, win, client, evmask->mask_len * 4, (unsigned char*)&evmask[1]);
+        evmask = (xXIDeviceEventMask*)(((unsigned char*)evmask) + evmask->mask_len * 4);
+    }
+
+    RecalculateDeliverableEvents(win);
+
+    xfree(types);
+    return Success;
+}
diff --git a/Xi/xiselectev.h b/Xi/xiselectev.h
new file mode 100644
index 0000000..dc52712
--- /dev/null
+++ b/Xi/xiselectev.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2008 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.
+ *
+ * Author: Peter Hutterer
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+int SProcXISelectEvent(ClientPtr client);
+int ProcXISelectEvent(ClientPtr client);
diff --git a/Xi/xiselev.c b/Xi/xiselev.c
deleted file mode 100644
index 229f2d1..0000000
--- a/Xi/xiselev.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2007-2008 Peter Hutterer
- *
- * 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.
- *
- * Author: Peter Hutterer, University of South Australia, NICTA
- */
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/extensions/XIproto.h>
-
-#include "dixstruct.h"
-#include "windowstr.h"
-
-#include "exglobals.h"
-#include "xiselev.h"
-#include "geext.h"
-
-int
-SProcXiSelectEvent(ClientPtr client)
-{
-    char n;
-
-    REQUEST(xXiSelectEventReq);
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xXiSelectEventReq);
-    swapl(&stuff->window, n);
-    swapl(&stuff->mask, n);
-    return (ProcXiSelectEvent(client));
-}
-
-
-int
-ProcXiSelectEvent(ClientPtr client)
-{
-    int rc;
-    WindowPtr pWin;
-    DeviceIntPtr pDev;
-    REQUEST(xXiSelectEventReq);
-    REQUEST_SIZE_MATCH(xXiSelectEventReq);
-
-    rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
-    if (rc != Success)
-        return rc;
-
-    if (stuff->deviceid & (0x1 << 7)) /* all devices */
-        pDev = NULL;
-    else {
-        rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess);
-        if (rc != Success)
-            return rc;
-    }
-
-    /* XXX: THIS FUNCTION IS NOW DYSFUNCTIONAL */
-
-    return Success;
-}
-
diff --git a/Xi/xiselev.h b/Xi/xiselev.h
deleted file mode 100644
index b751c5d..0000000
--- a/Xi/xiselev.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2007-2008 Peter Hutterer
- *
- * 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.
- *
- * Author: Peter Hutterer, University of South Australia, NICTA
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef XISELEV_H
-#define XISELEV_H 1
-
-int SProcXiSelectEvent(ClientPtr /* client */
-    );
-
-int ProcXiSelectEvent(ClientPtr	/* client */
-    );
-
-#endif /* XISELEV_H */
-
diff --git a/include/exevents.h b/include/exevents.h
index 4ee7084..fc1c23f 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -254,4 +254,7 @@ extern void
 XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master,
                          DeviceChangedEvent *dce);
 
+extern void XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
+                           unsigned int len, unsigned char* mask);
+
 #endif /* EXEVENTS_H */
diff --git a/include/inputstr.h b/include/inputstr.h
index 3edd33f..678c171 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -55,6 +55,7 @@ SOFTWARE.
 #include "cursorstr.h"
 #include "geext.h"
 #include "privates.h"
+#include <X11/extensions/XI2proto.h>
 
 #define BitIsOn(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))
 #define SetBit(ptr, bit)  (((BYTE *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7)))
@@ -63,7 +64,8 @@ SOFTWARE.
 #define SameClient(obj,client) \
 	(CLIENT_BITS((obj)->resource) == (client)->clientAsMask)
 
-#define EMASKSIZE	MAXDEVICES + 1
+#define EMASKSIZE	MAXDEVICES + 2
+#define XI2MASKSIZE     ((XI_LASTEVENT + 7)/8) /* no of bits for masks */
 
 /**
  * This struct stores the core event mask for each client except the client
@@ -98,6 +100,8 @@ typedef struct _InputClients {
     InputClientsPtr	next; /**< Pointer to the next mask */
     XID			resource; /**< id for putting into resource manager */
     Mask		mask[EMASKSIZE]; /**< Actual XI event mask, deviceid is index */
+    /** XI2 event masks. One per device, each bit is a mask of (1 << type) */
+    unsigned char       xi2mask[EMASKSIZE][XI2MASKSIZE];
 } InputClients;
 
 /**
@@ -126,6 +130,8 @@ typedef struct _OtherInputMasks {
     Mask		dontPropagateMask[EMASKSIZE];
     /** The clients that selected for events */
     InputClientsPtr	inputClients;
+    /* XI2 event masks. One per device, each bit is a mask of (1 << type) */
+    unsigned char       xi2mask[EMASKSIZE][XI2MASKSIZE];
 } OtherInputMasks;
 
 /*
commit 38bba0c1b75b84e8bbdfa7975cf701a9414a3afd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 20 16:07:33 2009 +1000

    Xi: Change ChangeMasterDeviceClasses to new XI2 events.
    
    Split ChangeMasterDeviceClasses into an extra XISendDeviceChangedEvent that
    assembles the XI2 wire event for the DeviceChanged event. Re-use this when
    detaching the last SD.
    
    Not quite perfect yet, we still copy the device classes from the slave now
    rather than from the data we had when the event occured. But it's a start.
    
    (We can now unexport SizeDeviceInfo and CopySwapDevices, not needed anymore)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 8851487..fe11694 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -56,12 +56,13 @@ SOFTWARE.
 #include <dix-config.h>
 #endif
 
+#include "inputstr.h"
 #include <X11/X.h>
 #include <X11/Xproto.h>
 #include <X11/extensions/XI.h>
 #include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include <X11/extensions/geproto.h>
-#include "inputstr.h"
 #include "windowstr.h"
 #include "miscstruct.h"
 #include "region.h"
@@ -73,6 +74,7 @@ SOFTWARE.
 #include "scrnintstr.h"
 #include "listdev.h" /* for CopySwapXXXClass */
 #include "xace.h"
+#include "querydev.h" /* For List*Info */
 
 #include <X11/extensions/XKBproto.h>
 #include "xkbsrv.h"
@@ -654,50 +656,90 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
  * @param device The slave device
  * @param dcce Pointer to the event struct.
  */
-static void
-ChangeMasterDeviceClasses(DeviceIntPtr device,
-                          DeviceChangedEvent *dce)
+void
+XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce)
 {
-    DeviceIntPtr master = device->u.master;
-    deviceClassesChangedEvent *dcce;
-    char* classbuff;
-    int len = sizeof(xEvent);
-    int namelen = 0; /* dummy */
+    xXIDeviceChangedEvent *dcce;
+    int len = sizeof(xXIDeviceChangedEvent);
+    int nkeys;
+    char *ptr;
 
-    if (device->isMaster)
-        return;
+    if (dce->buttons.num_buttons)
+    {
+        len += sizeof(xXIButtonInfo);
+        len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
+    }
+    if (dce->num_valuators)
+        len += sizeof(xXIValuatorInfo) * dce->num_valuators;
 
-    if (!master) /* if device was set floating between SIGIO and now */
-        return;
+    nkeys = (dce->keys.max_keycode > 0) ?
+                dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
+    if (nkeys > 0)
+    {
+        len += sizeof(xXIKeyInfo);
+        len += sizeof(CARD32) * nkeys; /* keycodes */
+    }
 
-    SizeDeviceInfo(device, &namelen, &len);
     dcce = xalloc(len);
     if (!dcce)
     {
-        ErrorF("[Xi] BadAlloc in ChangeMasterDeviceClasses\n");
+        ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
         return;
     }
 
     dcce->type         = GenericEvent;
     dcce->extension    = IReqCode;
-    dcce->evtype       = XI_DeviceClassesChangedNotify;
+    dcce->evtype       = XI_DeviceChanged;
     dcce->time         = GetTimeInMillis();
-    dcce->new_slave    = device->id;
     dcce->deviceid     = master->id;
+    dcce->sourceid     = device->id;
+    dcce->reason       = SlaveSwitch;
     dcce->num_classes  = 0;
-
     dcce->length = (len - sizeof(xEvent))/4;
 
-    master->public.devicePrivate = device->public.devicePrivate;
+    ptr = (char*)&dcce[1];
+    if (dce->buttons.num_buttons)
+    {
+        dcce->num_classes++;
+        ptr += ListButtonInfo(device, (xXIButtonInfo*)ptr);
+    }
 
-    DeepCopyDeviceClasses(device, master);
+    if (nkeys)
+    {
+        dcce->num_classes++;
+        ptr += ListKeyInfo(device, (xXIKeyInfo*)ptr);
+    }
+
+    if (dce->num_valuators)
+    {
+        int i;
+
+        dcce->num_classes += dce->num_valuators;
+        for (i = 0; i < dce->num_valuators; i++)
+            ptr += ListValuatorInfo(device, (xXIValuatorInfo*)ptr, i);
+    }
 
-    classbuff = (char*)&dcce[1];
     /* we don't actually swap if there's a NullClient, swapping is done
      * later when event is delivered. */
-    CopySwapClasses(NullClient, master, &dcce->num_classes, &classbuff);
-    SendEventToAllWindows(master, XI_DeviceClassesChangedMask,
-                          (xEvent*)dcce, 1);
+    SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1);
+}
+
+static void
+ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
+{
+    DeviceIntPtr master = device->u.master;
+
+    if (device->isMaster)
+        return;
+
+    if (!master) /* if device was set floating between SIGIO and now */
+        return;
+
+    master->public.devicePrivate = device->public.devicePrivate;
+
+    /* FIXME: the classes may have changed since we generated the event. */
+    DeepCopyDeviceClasses(device, master);
+    XISendDeviceChangedEvent(device, master, dce);
 }
 
 /**
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 8452186..5e87451 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -627,49 +627,111 @@ SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to)
 }
 
 static void
-SDeviceClassesChangedEvent(deviceClassesChangedEvent* from,
-                           deviceClassesChangedEvent* to)
+SDeviceChangedEvent(xXIDeviceChangedEvent* from, xXIDeviceChangedEvent* to)
 {
     char n;
     int i, j;
-    xAnyClassPtr any;
+    xXIAnyInfo *any;
 
     *to = *from;
     memcpy(&to[1], &from[1], from->length * 4);
 
     swaps(&to->sequenceNumber, n);
     swapl(&to->length, n);
+    swaps(&to->evtype, n);
+    swaps(&to->deviceid, n);
     swapl(&to->time, n);
-   
+    swaps(&to->num_classes, n);
+    swaps(&to->sourceid, n);
+
     /* now swap the actual classes */
-    any = (xAnyClassPtr)&to[1];
+    any = (xXIAnyInfo*)&to[1];
     for (i = 0; i < to->num_classes; i++)
     {
-        switch(any->class)
+        swaps(&any->type, n);
+        swaps(&any->length, n);
+        switch(any->type)
         {
             case KeyClass:
-                swaps(&((xKeyInfoPtr)any)->num_keys, n);
+                {
+                    xXIKeyInfo *ki = (xXIKeyInfo*)any;
+                    uint32_t *key = (uint32_t*)&ki[1];
+                    for (j = 0; j < ki->num_keycodes; j++, key++)
+                        swapl(key, n);
+                    swaps(&ki->num_keycodes, n);
+                }
                 break;
             case ButtonClass:
-                swaps(&((xButtonInfoPtr)any)->num_buttons, n);
+                {
+                    xXIButtonInfo *bi = (xXIButtonInfo*)any;
+                    for (j = 0; j < bi->num_buttons; j++)
+                        swapl(&bi[1 + j], n);
+                    swaps(&bi->num_buttons, n);
+                }
                 break;
             case ValuatorClass:
                 {
-                    xValuatorInfoPtr v = (xValuatorInfoPtr)any;
-                    xAxisInfoPtr a = (xAxisInfoPtr)&v[1];
-
-                    swapl(&v->motion_buffer_size, n);
-                    for (j = 0; j < v->num_axes; j++)
-                    {
-                        swapl(&a->min_value, n);
-                        swapl(&a->max_value, n);
-                        swapl(&a->resolution, n);
-                        a++;
-                    }
+                    xXIValuatorInfo* ai = (xXIValuatorInfo*)any;
+                    swapl(&ai->name, n);
+                    swapl(&ai->min.integral, n);
+                    swapl(&ai->min.frac, n);
+                    swapl(&ai->max.integral, n);
+                    swapl(&ai->max.frac, n);
+                    swapl(&ai->resolution, n);
+                    swaps(&ai->number, n);
                 }
                 break;
         }
-        any = (xAnyClassPtr)((char*)any + any->length);
+        any = (xXIAnyInfo*)((char*)any + any->length * 4);
+    }
+}
+
+static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to)
+{
+    int i;
+    char n;
+    char *ptr;
+    char *vmask;
+
+    *to = *from;
+    memcpy(&to[1], &from[1], from->length * 4);
+
+    swaps(&to->sequenceNumber, n);
+    swapl(&to->length, n);
+    swaps(&to->evtype, n);
+    swaps(&to->deviceid, n);
+    swapl(&to->time, n);
+    swapl(&to->root, n);
+    swapl(&to->event, n);
+    swapl(&to->child, n);
+    swapl(&to->root_x.integral, n);
+    swapl(&to->root_x.frac, n);
+    swapl(&to->root_y.integral, n);
+    swapl(&to->root_y.frac, n);
+    swapl(&to->event_x.integral, n);
+    swapl(&to->event_x.frac, n);
+    swapl(&to->event_y.integral, n);
+    swapl(&to->event_y.frac, n);
+    swaps(&to->buttons_len, n);
+    swaps(&to->valuators_len, n);
+    swaps(&to->sourceid, n);
+    swapl(&to->mods.base_mods, n);
+    swapl(&to->mods.latched_mods, n);
+    swapl(&to->mods.locked_mods, n);
+
+    ptr = (char*)(&to[1]);
+    ptr += from->buttons_len;
+    vmask = ptr; /* valuator mask */
+    ptr += from->valuators_len;
+    for (i = 0; i < from->valuators_len * 32; i++)
+    {
+        if (BitIsOn(vmask, i))
+        {
+            swapl(((uint32_t*)ptr), n);
+            ptr += 4;
+            swapl(((uint32_t*)ptr), n);
+            ptr += 4;
+        }
     }
 }
 
@@ -683,6 +745,13 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
         case XI_Leave:
             SDeviceLeaveNotifyEvent((xXILeaveEvent*)from, (xXILeaveEvent*)to);
             break;
+        case XI_DeviceChanged:
+            SDeviceChangedEvent((xXIDeviceChangedEvent*)from,
+                                (xXIDeviceChangedEvent*)to);
+            break;
+        default:
+            SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to);
+            break;
     }
 }
 
diff --git a/Xi/listdev.c b/Xi/listdev.c
index 925d0ec..e7d0a9d 100644
--- a/Xi/listdev.c
+++ b/Xi/listdev.c
@@ -93,7 +93,7 @@ SProcXListInputDevices(ClientPtr client)
  *
  */
 
-void
+static void
 SizeDeviceInfo(DeviceIntPtr d, int *namesize, int *size)
 {
     int chunks;
@@ -273,22 +273,7 @@ CopySwapValuatorClass(ClientPtr client, ValuatorClassPtr v, char **buf)
     return (i);
 }
 
-/***********************************************************************
- *
- * This procedure lists information to be returned for an input device.
- *
- */
-
 static void
-ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev,
-	       char **devbuf, char **classbuf, char **namebuf)
-{
-    CopyDeviceName(namebuf, d->name);
-    CopySwapDevice(client, d, 0, devbuf);
-    CopySwapClasses(client, d, &dev->num_classes, classbuf);
-}
-
-void
 CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes,
                 char** classbuf)
 {
@@ -308,6 +293,22 @@ CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes,
 
 /***********************************************************************
  *
+ * This procedure lists information to be returned for an input device.
+ *
+ */
+
+static void
+ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev,
+	       char **devbuf, char **classbuf, char **namebuf)
+{
+    CopyDeviceName(namebuf, d->name);
+    CopySwapDevice(client, d, 0, devbuf);
+    CopySwapClasses(client, d, &dev->num_classes, classbuf);
+}
+
+
+/***********************************************************************
+ *
  * This procedure lists the input devices available to the server.
  *
  * If this request is called by a client that has not issued a
diff --git a/Xi/listdev.h b/Xi/listdev.h
index 39ea2d6..b0d2dd5 100644
--- a/Xi/listdev.h
+++ b/Xi/listdev.h
@@ -43,15 +43,4 @@ void SRepXListInputDevices(ClientPtr /* client */ ,
 			   xListInputDevicesReply *	/* rep */
     );
 
-void
-CopySwapClasses(ClientPtr /* client */,
-                DeviceIntPtr /* dev */,
-                CARD8* /* num_classes */,
-                char** /* classbuf */);
-
-void
-SizeDeviceInfo(DeviceIntPtr /* dev */,
-               int* /* namesize */,
-               int* /* size */);
-
 #endif /* LISTDEV_H */
diff --git a/Xi/querydev.c b/Xi/querydev.c
index 0d90fa9..c7ee0e1 100644
--- a/Xi/querydev.c
+++ b/Xi/querydev.c
@@ -219,7 +219,7 @@ SizeDeviceClasses(DeviceIntPtr dev)
  * Write button information into info.
  * @return Number of bytes written into info.
  */
-static int
+int
 ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
 {
     info->type = ButtonClass;
@@ -250,7 +250,7 @@ SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
  * Write key information into info.
  * @return Number of bytes written into info.
  */
-static int
+int
 ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
 {
     int i;
@@ -288,7 +288,7 @@ SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
  *
  * @return The number of bytes written into info.
  */
-static int
+int
 ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber)
 {
     ValuatorClassPtr v = dev->valuator;
diff --git a/Xi/querydev.h b/Xi/querydev.h
index 92ab2bd..34e87bd 100644
--- a/Xi/querydev.h
+++ b/Xi/querydev.h
@@ -39,4 +39,7 @@ void SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep);
 int SizeDeviceClasses(DeviceIntPtr dev);
 int ListDeviceClasses(DeviceIntPtr dev, char* any, uint16_t* nclasses);
 int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment);
+int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info);
+int ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info);
+int ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber);
 #endif /* QUERYDEV_H */
diff --git a/dix/devices.c b/dix/devices.c
index ca0da07..0795d30 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2217,28 +2217,14 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
 
         if (!it)  /* no dev is paired with old master */
         {
-            /* XXX: reset to defaults */
             EventListPtr event = NULL;
-            char* classbuf;
-            int namelen = 0; /* dummy */
-            int len = sizeof(xEvent);
-            deviceClassesChangedEvent *dcce;
 
+            /* XXX: reset master back to defaults */
             event = InitEventList(1);
-            SizeDeviceInfo(oldmaster, &namelen, &len);
-            SetMinimumEventSize(event, 1, len);
-
-            /* Send event to clients */
+            SetMinimumEventSize(event, 1, sizeof(DeviceChangedEvent));
             CreateClassesChangedEvent(event, oldmaster, oldmaster);
-            dcce = (deviceClassesChangedEvent*)event->event;
-            dcce->deviceid = oldmaster->id;
-            dcce->num_classes = 0;
-            dcce->length = (len - sizeof(xEvent))/4;
-            classbuf = (char*)&event->event[1];
-            CopySwapClasses(NullClient, oldmaster,
-                    &dcce->num_classes, &classbuf);
-            SendEventToAllWindows(oldmaster, XI_DeviceClassesChangedMask,
-                    event->event, 1);
+            XISendDeviceChangedEvent(oldmaster, oldmaster,
+                                     (DeviceChangedEvent*)event->event);
             FreeEventList(event, 1);
         }
     }
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index c3328d6..553d953 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -45,13 +45,12 @@
 #include "events.h"
 #include "exglobals.h"
 #include "eventconvert.h"
-#include "listdev.h"
+#include "querydev.h"
 
 static int countValuators(DeviceEvent *ev, int *first);
 static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
 static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
-static int eventToClassesChanged(DeviceChangedEvent *ev, xEvent **dcce,
-                                 int *count);
+static int eventToClassesChanged(DeviceChangedEvent *ev, xEvent **dcce);
 static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
 /**
  * Convert the given event to the respective core event.
@@ -127,8 +126,9 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
         case ET_ProximityOut:
             return eventToKeyButtonPointer((DeviceEvent*)ev, xi, count);
         case ET_DeviceChanged:
-            return eventToClassesChanged((DeviceChangedEvent*)ev, xi, count);
-            break;
+            *count = 0;
+            *xi = NULL;
+            return Success;
     }
 
     ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->u.any.type);
@@ -162,6 +162,9 @@ EventToXI2(InternalEvent *ev, xEvent **xi)
         case ET_ProximityOut:
             *xi = NULL;
             return Success;
+        case ET_DeviceChanged:
+            return eventToClassesChanged((DeviceChangedEvent*)ev, xi);
+
     }
 
     ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->u.any.type);
@@ -290,14 +293,12 @@ getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
 }
 
 static int
-eventToClassesChanged(DeviceChangedEvent *ev, xEvent **xi, int *count)
+eventToClassesChanged(DeviceChangedEvent *ev, xEvent **xi)
 {
     int len = sizeof(xEvent);
-    int namelen = 0; /* dummy */
     DeviceIntPtr slave;
     int rc;
-    deviceClassesChangedEvent *dcce;
-
+    xXIDeviceChangedEvent *dce;
 
     rc = dixLookupDevice(&slave, ev->new_slaveid,
                          serverClient, DixReadAccess);
@@ -305,21 +306,25 @@ eventToClassesChanged(DeviceChangedEvent *ev, xEvent **xi, int *count)
     if (rc != Success)
         return rc;
 
-    SizeDeviceInfo(slave, &namelen, &len);
+    len += SizeDeviceClasses(slave);
 
     *xi = xcalloc(1, len);
     if (!(*xi))
         return BadAlloc;
 
-    dcce = (deviceClassesChangedEvent*)(*xi);
-    dcce->type = GenericEvent;
-    dcce->extension = IReqCode;
-    dcce->evtype = XI_DeviceClassesChangedNotify;
-    dcce->time = GetTimeInMillis();
-    dcce->new_slave = slave->id;
-    dcce->length = (len - sizeof(xEvent))/4;
+    dce = (xXIDeviceChangedEvent*)(*xi);
+    dce->type = GenericEvent;
+    dce->extension = IReqCode;
+    dce->evtype = XI_DeviceChanged;
+    dce->time = GetTimeInMillis();
+    dce->sourceid = slave->id;
+    dce->reason = SlaveSwitch;
+    dce->length = (len - sizeof(xEvent))/4;
+
+    /* FIXME: this should come from the event, not from the device. See
+     * CreateClassesChangedEvent */
+    ListDeviceClasses(slave, (char*)&dce[1], &dce->num_classes);
 
-    *count = 1;
     return Success;
 }
 
@@ -350,7 +355,6 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
     char *ptr;
     int32_t *axisval;
 
-
     /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
      * with MAX_VALUATORS below */
     /* btlen is in 4 byte units */
diff --git a/include/exevents.h b/include/exevents.h
index d09ad3c..4ee7084 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -250,4 +250,8 @@ extern _X_EXPORT int XIPropToFloat(
  * would it merely be irrelevant and confusing? */
 extern _X_EXPORT int XIShouldNotify(ClientPtr client, DeviceIntPtr dev);
 
+extern void
+XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master,
+                         DeviceChangedEvent *dce);
+
 #endif /* EXEVENTS_H */
commit 181e41511d5772962b8bc998a1940d2a9ba62d5e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 23 16:14:51 2009 +1000

    dix: fix up device enter/leave for XI_Enter/XI_Leave.

diff --git a/Xi/extinit.c b/Xi/extinit.c
index 9acbdfe..8452186 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -602,20 +602,28 @@ SDevicePropertyNotifyEvent (devicePropertyNotify *from, devicePropertyNotify *to
 }
 
 static void
-SDeviceLeaveNotifyEvent (deviceLeaveNotify *from, deviceLeaveNotify *to)
+SDeviceLeaveNotifyEvent (xXILeaveEvent *from, xXILeaveEvent *to)
 {
     char n;
 
     *to = *from;
     swaps(&to->sequenceNumber,n);
+    swapl(&to->length, n);
+    swaps(&to->evtype, n);
+    swaps(&to->deviceid, n);
     swapl(&to->time, n);
     swapl(&to->root, n);
     swapl(&to->event, n);
     swapl(&to->child, n);
-    swaps(&to->rootX, n);
-    swaps(&to->rootY, n);
-    swaps(&to->eventX, n);
-    swaps(&to->eventY, n);
+    swaps(&to->root_x.integral, n);
+    swaps(&to->root_x.frac, n);
+    swaps(&to->root_y.integral, n);
+    swaps(&to->root_y.frac, n);
+    swaps(&to->event_x.integral, n);
+    swaps(&to->event_x.frac, n);
+    swaps(&to->event_y.integral, n);
+    swaps(&to->event_y.frac, n);
+    swaps(&to->sourceid, n);
 }
 
 static void
@@ -669,6 +677,13 @@ SDeviceClassesChangedEvent(deviceClassesChangedEvent* from,
 static void
 XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
 {
+    switch(from->evtype)
+    {
+        case XI_Enter:
+        case XI_Leave:
+            SDeviceLeaveNotifyEvent((xXILeaveEvent*)from, (xXILeaveEvent*)to);
+            break;
+    }
 }
 
 /**************************************************************************
@@ -1025,10 +1040,6 @@ SEventIDispatch(xEvent * from, xEvent * to)
 	DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify);
     else if (type == DevicePropertyNotify)
 	DO_SWAP(SDevicePropertyNotifyEvent, devicePropertyNotify);
-    else if (type == DeviceEnterNotify)
-        DO_SWAP(SDeviceLeaveNotifyEvent, deviceEnterNotify);
-    else if (type == DeviceLeaveNotify)
-        DO_SWAP(SDeviceLeaveNotifyEvent, deviceLeaveNotify);
     else {
 	FatalError("XInputExtension: Impossible event!\n");
     }
@@ -1084,8 +1095,6 @@ XInputExtensionInit(void)
 	EventSwapVector[DeviceMappingNotify] = SEventIDispatch;
 	EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
 	EventSwapVector[DevicePresenceNotify] = SEventIDispatch;
-	EventSwapVector[DeviceEnterNotify] = SEventIDispatch;
-	EventSwapVector[DeviceLeaveNotify] = SEventIDispatch;
 
 	GERegisterExtension(IReqCode, XI2EventSwap);
     } else {
diff --git a/dix/enterleave.c b/dix/enterleave.c
index 2f2cff4..3f5d06f 100644
--- a/dix/enterleave.c
+++ b/dix/enterleave.c
@@ -29,6 +29,7 @@
 #endif
 
 #include <X11/X.h>
+#include <X11/extensions/XI2.h>
 #include "windowstr.h"
 #include "scrnintstr.h"
 #include "exglobals.h"
@@ -228,7 +229,7 @@ DeviceEnterNotifies(DeviceIntPtr dev,
     if (ancestor == parent)
 	return;
     DeviceEnterNotifies(dev, ancestor, parent, mode, detail);
-    DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, detail, parent,
+    DeviceEnterLeaveEvent(dev, XI_Enter, mode, detail, parent,
                           child->drawable.id);
 }
 
@@ -334,7 +335,7 @@ DeviceLeaveNotifies(DeviceIntPtr dev,
 	return;
     for (win = child->parent; win != ancestor; win = win->parent)
     {
-        DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, detail, win,
+        DeviceEnterLeaveEvent(dev, XI_Leave, mode, detail, win,
                                   child->drawable.id);
         child = win;
     }
@@ -568,24 +569,24 @@ DeviceEnterLeaveEvents(DeviceIntPtr dev,
 {
     if (IsParent(from, to))
     {
-        DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyInferior, from, None);
+        DeviceEnterLeaveEvent(dev, XI_Leave, mode, NotifyInferior, from, None);
         DeviceEnterNotifies(dev, from, to, mode, NotifyVirtual);
-        DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyAncestor, to, None);
+        DeviceEnterLeaveEvent(dev, XI_Enter, mode, NotifyAncestor, to, None);
     }
     else if (IsParent(to, from))
     {
-	DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyAncestor, from, None);
+	DeviceEnterLeaveEvent(dev, XI_Leave, mode, NotifyAncestor, from, None);
 	DeviceLeaveNotifies(dev, from, to, mode, NotifyVirtual);
-	DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyInferior, to, None);
+	DeviceEnterLeaveEvent(dev, XI_Enter, mode, NotifyInferior, to, None);
     }
     else
     { /* neither from nor to is descendent of the other */
 	WindowPtr common = CommonAncestor(to, from);
 	/* common == NullWindow ==> different screens */
-        DeviceEnterLeaveEvent(dev, DeviceLeaveNotify, mode, NotifyNonlinear, from, None);
+        DeviceEnterLeaveEvent(dev, XI_Leave, mode, NotifyNonlinear, from, None);
         DeviceLeaveNotifies(dev, from, common, mode, NotifyNonlinearVirtual);
         DeviceEnterNotifies(dev, common, to, mode, NotifyNonlinearVirtual);
-        DeviceEnterLeaveEvent(dev, DeviceEnterNotify, mode, NotifyNonlinear, to, None);
+        DeviceEnterLeaveEvent(dev, XI_Enter, mode, NotifyNonlinear, to, None);
     }
 }
 
diff --git a/dix/events.c b/dix/events.c
index b27c8e1..6277941 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3994,14 +3994,12 @@ DeviceEnterLeaveEvent(
     WindowPtr pWin,
     Window child)
 {
-    xEvent              event;
     GrabPtr             grab = mouse->deviceGrab.grab;
-    deviceEnterNotify   *devEnterLeave;
+    xXIEnterEvent       event;
     int                 mskidx;
     OtherInputMasks     *inputMasks;
     Mask                mask;
-    DeviceIntPtr        keybd = GetPairedDevice(mouse);
-    BOOL                sameScreen;
+    xEvent              dummy;
 
     if (grab) {
         mask = (pWin == grab->window) ? grab->eventMask : 0;
@@ -4011,41 +4009,40 @@ DeviceEnterLeaveEvent(
         mask = pWin->eventMask | wOtherEventMasks(pWin);
     }
 
-    /* we don't have enough bytes, so we squash flags and mode into
-       one byte, and use the last byte for the deviceid. */
-    memset(&event, 0, sizeof(xEvent));
-    devEnterLeave           = (deviceEnterNotify*)&event;
-    devEnterLeave->type     = type;
-    devEnterLeave->detail   = detail;
-    devEnterLeave->time     = currentTime.milliseconds;
-    devEnterLeave->rootX    = mouse->spriteInfo->sprite->hot.x;
-    devEnterLeave->rootY    = mouse->spriteInfo->sprite->hot.y;
-    FixUpEventFromWindow(mouse, &event, pWin, None, FALSE);
-    sameScreen = event.u.keyButtonPointer.sameScreen;
+    memset(&event, 0, sizeof(event));
+    event.type        = GenericEvent;
+    event.extension   = IReqCode;
+    event.evtype      = type;
+    event.detail      = detail;
+    event.time        = currentTime.milliseconds;
+    event.deviceid    = mouse->id;
+    event.sourceid    = 0; /*XXX */
+    event.mode        = mode;
+    event.root_x.integral      = mouse->spriteInfo->sprite->hot.x;
+    event.root_y.integral      = mouse->spriteInfo->sprite->hot.y;
 
-    devEnterLeave->child    = child;
-    devEnterLeave->deviceid = mouse->id;
-    devEnterLeave->mode     = mode;
-    devEnterLeave->mode    |= (sameScreen ?  (ELFlagSameScreen << 4) : 0);
+    /* We use FUEFW to fill in dummy, then copy the values */
+    FixUpEventFromWindow(mouse, &dummy, pWin, None, FALSE);
 
-    devEnterLeave->state = mouse->button->state & 0x1f00;
-    if (keybd && keybd->key)
-        devEnterLeave->state |= XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+    event.same_screen = dummy.u.keyButtonPointer.sameScreen;
+    event.child       = dummy.u.keyButtonPointer.child;
+    event.event_x.integral     = dummy.u.keyButtonPointer.eventX;
+    event.event_y.integral     = dummy.u.keyButtonPointer.eventY;
 
     mskidx = mouse->id;
     inputMasks = wOtherInputMasks(pWin);
     if (inputMasks &&
-       (GetEventFilter(mouse, (xEvent*)devEnterLeave) &
+       (GetEventFilter(mouse, (xEvent*)&event) &
             inputMasks->deliverableEvents[mskidx]))
     {
         if (grab)
             TryClientEvents(rClient(grab), mouse,
-                            (xEvent*)devEnterLeave, 1, mask,
-                            GetEventFilter(mouse, (xEvent*)devEnterLeave),
+                            (xEvent*)&event, 1, mask,
+                            GetEventFilter(mouse, (xEvent*)&event),
                             grab);
         else
-            DeliverEventsToWindow(mouse, pWin, (xEvent*)devEnterLeave, 1,
-                                  GetEventFilter(mouse, (xEvent*)devEnterLeave),
+            DeliverEventsToWindow(mouse, pWin, (xEvent*)&event, 1,
+                                  GetEventFilter(mouse, (xEvent*)&event),
                                   NullGrab, mouse->id);
     }
 
commit 0befeb36c175b14eac8d5416851f1556af90dd86
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Feb 24 15:27:07 2009 +1000

    dix: Add device info to DeviceChangedEvent, and fill in CCCE.
    
    We need to fill the info here, as the device may change until we get a chance
    to process it.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index a3e11f7..01a9864 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -158,6 +158,7 @@ CreateClassesChangedEvent(EventList* event,
                           DeviceIntPtr master,
                           DeviceIntPtr slave)
 {
+    int i;
     DeviceChangedEvent *dce;
     CARD32 ms = GetTimeInMillis();
 
@@ -175,11 +176,30 @@ CreateClassesChangedEvent(EventList* event,
     dce->flags |= HAS_NEW_SLAVE;
     dce->new_slaveid = slave->id;
 
-    /* FIXME: fill in new information about the device. We need to do this
-     * here to avoid race conditions if the device changes while the event
-     * slumbers in the EQ.
-     */
-
+    if (slave->button)
+    {
+        dce->buttons.num_buttons = slave->button->numButtons;
+        for (i = 0; i < dce->buttons.num_buttons; i++)
+            dce->buttons.names[i] = 0; /* FIXME */
+    }
+    if (slave->valuator)
+    {
+        dce->num_valuators = slave->valuator->numAxes;
+        for (i = 0; i < dce->num_valuators; i++)
+        {
+            dce->valuators[i].min = slave->valuator->axes[i].min_value;
+            dce->valuators[i].max = slave->valuator->axes[i].max_value;
+            dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
+            /* This should, eventually, be a per-axis mode */
+            dce->valuators[i].mode = slave->valuator->mode;
+            dce->valuators[i].name = 0; /* FIXME: */
+        }
+    }
+    if (slave->key)
+    {
+        dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code;
+        dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code;
+    }
 }
 
 /**
diff --git a/include/events.h b/include/events.h
index 7bc83a6..c6eeae4 100644
--- a/include/events.h
+++ b/include/events.h
@@ -128,7 +128,26 @@ typedef struct
     /** If flags & HAS_OLD_SLAVE is set, old_slaveid specifies device now
      * attached to this device. */
     int new_slaveid;
-    /* FIXME: add the new capabilities here */
+
+    struct {
+        int num_buttons;        /**< Number of buttons */
+        Atom names[MAX_BUTTONS];/**< Button names */
+    } buttons;
+
+    int num_valuators;          /**< Number of axes */
+    struct {
+        uint32_t min;           /**< Minimum value */
+        uint32_t max;           /**< Maximum value */
+        /* FIXME: frac parts of min/max */
+        uint32_t resolution;    /**< Resolution counts/m */
+        uint8_t mode;           /**< Relative or Absolute */
+        Atom name;              /**< Axis name */
+    } valuators[MAX_VALUATORS];
+
+    struct {
+        int min_keycode;
+        int max_keycode;
+    } keys;
 } DeviceChangedEvent;
 
 #if XFreeXDGA
commit b2ba77bac4fc3edab39372dfdc529e745ae74f77
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 5 14:23:47 2009 +1000

    dix: add EventToXI2 and GetXI2Type.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index db7178c..c3328d6 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -32,9 +32,12 @@
 #include <dix-config.h>
 #endif
 
+#include <stdint.h>
 #include <X11/X.h>
 #include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
 
 #include "dix.h"
 #include "inputstr.h"
@@ -49,7 +52,7 @@ static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
 static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
 static int eventToClassesChanged(DeviceChangedEvent *ev, xEvent **dcce,
                                  int *count);
-
+static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
 /**
  * Convert the given event to the respective core event.
  *
@@ -132,6 +135,39 @@ EventToXI(InternalEvent *ev, xEvent **xi, int *count)
     return BadImplementation;
 }
 
+/**
+ * Convert the given event to the respective XI 2.x event and store it in xi.
+ * xi is allocated on demand and must be freed by the caller.
+ *
+ * If the event cannot be converted into an XI event because of protocol
+ * restrictions, xi is NULL and Success is returned.
+ *
+ * @param[in] ev The event to convert into an XI2 event
+ * @param[out] xi Future memory location for the XI2 event.
+ *
+ * @return Success or the error code.
+ */
+int
+EventToXI2(InternalEvent *ev, xEvent **xi)
+{
+    switch (ev->u.any.type)
+    {
+        case ET_Motion:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+            return eventToDeviceEvent((DeviceEvent*)ev, xi);
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            *xi = NULL;
+            return Success;
+    }
+
+    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->u.any.type);
+    return BadImplementation;
+}
+
 static int
 eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
 {
@@ -287,6 +323,91 @@ eventToClassesChanged(DeviceChangedEvent *ev, xEvent **xi, int *count)
     return Success;
 }
 
+static int count_bits(unsigned char* ptr, int len)
+{
+    int bits = 0;
+    unsigned int i;
+    unsigned char x;
+
+    for (i = 0; i < len; i++)
+    {
+        x = ptr[i];
+        while(x > 0)
+        {
+            bits += (x & 0x1);
+            x >>= 1;
+        }
+    }
+    return bits;
+}
+
+static int
+eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
+{
+    int len = sizeof(xXIDeviceEvent);
+    xXIDeviceEvent *xde;
+    int i, btlen, vallen;
+    char *ptr;
+    int32_t *axisval;
+
+
+    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
+     * with MAX_VALUATORS below */
+    /* btlen is in 4 byte units */
+    btlen = (((MAX_BUTTONS + 7)/8) + 3)/4;
+    len += btlen * 4; /* buttonmask len */
+
+
+    vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
+    len += vallen * 2 * sizeof(uint32_t); /* axisvalues */
+    vallen = (((MAX_VALUATORS + 7)/8) + 3)/4;
+    len += vallen * 4; /* valuators mask */
+
+    *xi = xcalloc(1, len);
+    xde = (xXIDeviceEvent*)*xi;
+    xde->type           = GenericEvent;
+    xde->extension      = IReqCode;
+    xde->evtype         = GetXI2Type((InternalEvent*)ev);
+    xde->time           = ev->time;
+    xde->length         = (len - sizeof(xEvent) + 3)/4;
+    xde->detail         = ev->detail.button;
+    xde->root           = ev->root;
+    xde->buttons_len    = btlen;
+    xde->valuators_len  = vallen;
+    xde->deviceid       = ev->deviceid;
+    xde->sourceid       = ev->sourceid;
+
+    xde->mods.base_mods         = ev->mods.base;
+    xde->mods.latched_mods      = ev->mods.latched;
+    xde->mods.locked_mods       = ev->mods.locked;
+
+    xde->group.base_group       = ev->group.base;
+    xde->group.latched_group    = ev->group.latched;
+    xde->group.locked_group     = ev->group.locked;
+
+    ptr = (char*)&xde[1];
+    for (i = 0; i < sizeof(ev->buttons) * 8; i++)
+    {
+        if (BitIsOn(ev->buttons, i))
+            SetBit(ptr, i);
+    }
+
+    ptr += xde->buttons_len * 4;
+    axisval = (int32_t*)(ptr + xde->valuators_len * 4);
+    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    {
+        if (BitIsOn(ev->valuators.mask, i))
+        {
+            SetBit(ptr, i);
+            *axisval = ev->valuators.data[i];
+            axisval++;
+            axisval++; /* FIXME: this should be the frac. part */
+        }
+    }
+
+    return Success;
+}
+
 /**
  * Return the corresponding core type for the given event or 0 if no core
  * equivalent exists.
@@ -327,3 +448,28 @@ GetXIType(InternalEvent *event)
     return xitype;
 }
 
+/**
+ * Return the corresponding XI 2.x type for the given event or 0 if no
+ * equivalent exists.
+ */
+int
+GetXI2Type(InternalEvent *event)
+{
+    int xi2type = 0;
+
+    switch(event->u.any.type)
+    {
+        case ET_Motion:         xi2type = XI_Motion;           break;
+        case ET_ButtonPress:    xi2type = XI_ButtonPress;      break;
+        case ET_ButtonRelease:  xi2type = XI_ButtonRelease;    break;
+        case ET_KeyPress:       xi2type = XI_KeyPress;         break;
+        case ET_KeyRelease:     xi2type = XI_KeyRelease;       break;
+        case ET_Enter:          xi2type = XI_Enter;            break;
+        case ET_Leave:          xi2type = XI_Leave;            break;
+        case ET_Hierarchy:      xi2type = XI_HierarchyChanged; break;
+        case ET_DeviceChanged:  xi2type = XI_DeviceChanged;    break;
+        default:
+            break;
+    }
+    return xi2type;
+}
diff --git a/include/eventconvert.h b/include/eventconvert.h
index 1ff6495..f458af7 100644
--- a/include/eventconvert.h
+++ b/include/eventconvert.h
@@ -30,7 +30,9 @@
 
 _X_INTERNAL int EventToCore(InternalEvent *event, xEvent *core);
 _X_INTERNAL int EventToXI(InternalEvent *ev, xEvent **xi, int *count);
+_X_INTERNAL int EventToXI2(InternalEvent *ev, xEvent **xi);
 _X_INTERNAL int GetCoreType(InternalEvent* ev);
 _X_INTERNAL int GetXIType(InternalEvent* ev);
+_X_INTERNAL int GetXI2Type(InternalEvent* ev);
 
 #endif /* _EVENTCONVERT_H_ */
commit dfa2e8e966b699f9d292628119d5a9cbd2dbdf5a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 23 15:12:32 2009 +1000

    Xi: add XIQueryDevice request handling.

diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 316fd29..10521fd 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -60,6 +60,8 @@ libXi_la_SOURCES =	\
 	listdev.h \
 	opendev.c \
 	opendev.h \
+	querydev.c \
+	querydev.h \
 	queryversion.h \
 	queryversion.c \
 	querydp.c \
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 988ed0b..9acbdfe 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -104,6 +104,7 @@ SOFTWARE.
 #include "opendev.h"
 #include "querydp.h"
 #include "queryst.h"
+#include "querydev.h"
 #include "queryversion.h"
 #include "selectev.h"
 #include "sendexev.h"
@@ -237,7 +238,8 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXISetClientPointer,                 /* 44 */
         ProcXIGetClientPointer,                 /* 45 */
         ProcXiSelectEvent,                      /* 46 */
-        ProcXIQueryVersion                      /* 47 */
+        ProcXIQueryVersion,                     /* 47 */
+        ProcXIQueryDevice                       /* 48 */
 };
 
 /* For swapped clients */
@@ -289,7 +291,8 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXISetClientPointer,                 /* 44 */
         SProcXIGetClientPointer,                 /* 45 */
         SProcXiSelectEvent,                      /* 46 */
-        SProcXIQueryVersion                      /* 47 */
+        SProcXIQueryVersion,                     /* 47 */
+        SProcXIQueryDevice                       /* 48 */
 };
 
 /*****************************************************************
@@ -480,6 +483,8 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
 				(xXIQueryDevicePointerReply *) rep);
     else if (rep->RepType == X_XIGetClientPointer)
         SRepXIGetClientPointer(client, len, (xXIGetClientPointerReply*) rep);
+    else if (rep->RepType == X_XIQueryDevice)
+        SRepXIQueryDevice(client, len, (xXIQueryDeviceReply*)rep);
     else {
 	FatalError("XINPUT confused sending swapped reply");
     }
diff --git a/Xi/querydev.c b/Xi/querydev.c
new file mode 100644
index 0000000..0d90fa9
--- /dev/null
+++ b/Xi/querydev.c
@@ -0,0 +1,443 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Authors: Peter Hutterer
+ *
+ */
+
+/**
+ * @file Protocol handling for the XIQueryDevice request/reply.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h"
+#include <X11/X.h>
+#include <X11/extensions/XI2proto.h>
+#include "xkbstr.h"
+#include "xkbsrv.h"
+#include "xserver-properties.h"
+#include "exevents.h"
+
+#include "querydev.h"
+
+static int ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info);
+static int SizeDeviceInfo(DeviceIntPtr dev);
+static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info);
+int
+SProcXIQueryDevice(ClientPtr client)
+{
+    char n;
+
+    REQUEST(xXIQueryDeviceReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+
+    return ProcXIQueryDevice(client);
+}
+
+int
+ProcXIQueryDevice(ClientPtr client)
+{
+    xXIQueryDeviceReply rep;
+    DeviceIntPtr dev = NULL;
+    int rc = Success;
+    int len = 0;
+    char *info, *ptr;
+
+    REQUEST(xXIQueryDeviceReq);
+    REQUEST_SIZE_MATCH(xXIQueryDeviceReq);
+
+    if (stuff->deviceid != AllDevices && stuff->deviceid != AllMasterDevices)
+    {
+        rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
+        if (rc != Success)
+        {
+            client->errorValue = stuff->deviceid;
+            return rc;
+        }
+    }
+
+    if (dev)
+        len += SizeDeviceInfo(dev);
+    else
+    {
+        len = 0;
+        for (dev = inputInfo.devices; dev; dev = dev->next)
+        {
+            if (stuff->deviceid == AllDevices ||
+                (stuff->deviceid == AllMasterDevices && dev->isMaster))
+                len += SizeDeviceInfo(dev);
+        }
+
+        for (dev = inputInfo.off_devices; dev; dev = dev->next)
+        {
+            if (stuff->deviceid == AllDevices ||
+                (stuff->deviceid == AllMasterDevices && dev->isMaster))
+                len += SizeDeviceInfo(dev);
+        }
+
+        dev = NULL;
+    }
+
+    info = xcalloc(1, len);
+    if (!info)
+        return BadAlloc;
+
+    memset(&rep, 0, sizeof(xXIQueryDeviceReply));
+    rep.repType = X_Reply;
+    rep.RepType = X_XIQueryDevice;
+    rep.sequenceNumber = client->sequence;
+    rep.length = len/4;
+    rep.num_devices = 0;
+
+    ptr = info;
+    if (dev)
+    {
+        len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
+        if (client->swapped)
+            SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
+        info += len;
+        rep.num_devices = 1;
+    } else
+    {
+        for (dev = inputInfo.devices; dev; dev = dev->next)
+        {
+            if (stuff->deviceid == AllDevices ||
+                    (stuff->deviceid == AllMasterDevices && dev->isMaster))
+            {
+                len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
+                if (client->swapped)
+                    SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
+                info += len;
+                rep.num_devices++;
+            }
+        }
+
+        for (dev = inputInfo.off_devices; dev; dev = dev->next)
+        {
+            if (stuff->deviceid == AllDevices ||
+                    (stuff->deviceid == AllMasterDevices && dev->isMaster))
+            {
+                len = ListDeviceInfo(dev, (xXIDeviceInfo*)info);
+                if (client->swapped)
+                    SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
+                info += len;
+                rep.num_devices++;
+            }
+        }
+    }
+
+    WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep);
+    WriteToClient(client, rep.length * 4, ptr);
+    return rc;
+}
+
+void
+SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep)
+{
+    char n;
+
+    swaps(&rep->sequenceNumber, n);
+    swapl(&rep->length, n);
+    swaps(&rep->num_devices, n);
+
+    /* Device info is already swapped, see ProcXIQueryDevice */
+
+    WriteToClient(client, size, (char *)rep);
+}
+
+
+
+/**
+ * @return The number of bytes needed to store this device's xXIDeviceInfo
+ * (and its classes).
+ */
+static int
+SizeDeviceInfo(DeviceIntPtr dev)
+{
+    int len = sizeof(xXIDeviceInfo);
+
+    /* 4-padded name */
+    len += (((strlen(dev->name) + 3)/4)*4);
+
+    return len + SizeDeviceClasses(dev);
+
+}
+
+/*
+ * @return The number of bytes needed to store this device's classes.
+ */
+int
+SizeDeviceClasses(DeviceIntPtr dev)
+{
+    int len = 0;
+
+    if (dev->button)
+    {
+        len += sizeof(xXIButtonInfo);
+        len += dev->button->numButtons * sizeof(Atom);
+    }
+
+    if (dev->key)
+    {
+        XkbDescPtr xkb = dev->key->xkbInfo->desc;
+        len += sizeof(xXIKeyInfo);
+        len += (xkb->max_key_code - xkb->min_key_code + 1) * sizeof(uint32_t);
+    }
+
+    if (dev->valuator)
+        len += sizeof(xXIValuatorInfo) * dev->valuator->numAxes;
+
+    return len;
+}
+
+
+/**
+ * Write button information into info.
+ * @return Number of bytes written into info.
+ */
+static int
+ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
+{
+    info->type = ButtonClass;
+    info->num_buttons = dev->button->numButtons;
+    info->length = 2 + info->num_buttons;
+
+    /** XXX: button labels */
+
+    return info->length * 4;
+}
+
+static void
+SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo* info)
+{
+    char n;
+    Atom *btn;
+    int i;
+    swaps(&info->type, n);
+    swaps(&info->length, n);
+
+    for (i = 0, btn = (Atom*)&info[1]; i < info->num_buttons; i++, btn++)
+        swaps(btn, n);
+
+    swaps(&info->num_buttons, n);
+}
+
+/**
+ * Write key information into info.
+ * @return Number of bytes written into info.
+ */
+static int
+ListKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
+{
+    int i;
+    XkbDescPtr xkb = dev->key->xkbInfo->desc;
+    uint32_t *kc;
+
+    info->type = KeyClass;
+    info->num_keycodes = xkb->max_key_code - xkb->min_key_code + 1;
+    info->length = 2 + info->num_keycodes;
+
+    kc = (uint32_t*)&info[1];
+    for (i = xkb->min_key_code; i <= xkb->max_key_code; i++, kc++)
+        *kc = i;
+
+    return info->length * 4;
+}
+
+static void
+SwapKeyInfo(DeviceIntPtr dev, xXIKeyInfo* info)
+{
+    char n;
+    uint32_t *key;
+    int i;
+    swaps(&info->type, n);
+    swaps(&info->length, n);
+
+    for (i = 0, key = (uint32_t*)&info[1]; i < info->num_keycodes; i++, key++)
+        swaps(key, n);
+
+    swaps(&info->num_keycodes, n);
+}
+
+/**
+ * List axis information for the given axis.
+ *
+ * @return The number of bytes written into info.
+ */
+static int
+ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber)
+{
+    ValuatorClassPtr v = dev->valuator;
+
+    info->type = ValuatorClass;
+    info->length = sizeof(xXIValuatorInfo)/4;
+    info->name = XIGetKnownProperty(AXIS_LABEL_PROP_REL_MISC); /* XXX */
+    info->min.integral = v->axes[axisnumber].min_value;
+    info->min.frac = 0;
+    info->max.integral = v->axes[axisnumber].max_value;
+    info->max.frac = 0;
+    info->resolution = v->axes[axisnumber].resolution;
+    info->number = axisnumber;
+    info->mode = v->mode; /* Server doesn't have per-axis mode yet */
+
+    return info->length * 4;
+}
+
+static void
+SwapValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info)
+{
+    char n;
+    swaps(&info->type, n);
+    swaps(&info->length, n);
+    swapl(&info->name, n);
+    swapl(&info->min.integral, n);
+    swapl(&info->min.frac, n);
+    swapl(&info->max.integral, n);
+    swapl(&info->max.frac, n);
+    swaps(&info->number, n);
+}
+
+int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment)
+{
+    DeviceIntPtr master = dev->u.master;
+    int use;
+
+    if (dev->isMaster)
+    {
+        DeviceIntPtr paired = GetPairedDevice(dev);
+        use = IsPointerDevice(dev) ? MasterPointer : MasterKeyboard;
+        *attachment = (paired ? paired->id : 0);
+    } else if (master)
+    {
+        use = IsPointerDevice(master) ? SlavePointer : SlaveKeyboard;
+        *attachment = master->id;
+    } else
+        use = FloatingSlave;
+
+    return use;
+}
+
+/**
+ * Write the info for device dev into the buffer pointed to by info.
+ *
+ * @return The number of bytes used.
+ */
+static int
+ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
+{
+    char *any = (char*)&info[1];
+    int len = 0, total_len = 0;
+
+    info->deviceid = dev->id;
+    info->use = GetDeviceUse(dev, &info->attachment);
+    info->num_classes = 0;
+    info->name_len = strlen(dev->name);
+    info->enabled = dev->enabled;
+    total_len = sizeof(xXIDeviceInfo);
+
+    strncpy(any, dev->name, info->name_len);
+    len = ((info->name_len + 3)/4) * 4;
+    any += len;
+    total_len += len;
+
+    return total_len + ListDeviceClasses(dev, any, &info->num_classes);
+}
+
+/**
+ * Write the class info of the device into the memory pointed to by any, set
+ * nclasses to the number of classes in total and return the number of bytes
+ * written.
+ */
+int
+ListDeviceClasses(DeviceIntPtr dev, char *any, uint16_t *nclasses)
+{
+    int total_len = 0;
+    int len;
+    int i;
+
+    if (dev->button)
+    {
+        (*nclasses)++;
+        len = ListButtonInfo(dev, (xXIButtonInfo*)any);
+        any += len;
+        total_len += len;
+    }
+
+    if (dev->key)
+    {
+        (*nclasses)++;
+        len = ListKeyInfo(dev, (xXIKeyInfo*)any);
+        any += len;
+        total_len += len;
+    }
+
+    for (i = 0; dev->valuator && i < dev->valuator->numAxes; i++)
+    {
+        (*nclasses)++;
+        len = ListValuatorInfo(dev, (xXIValuatorInfo*)any, i);
+        any += len;
+        total_len += len;
+    }
+
+    return total_len;
+}
+
+static void
+SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info)
+{
+    char n;
+    char *any = (char*)&info[1];
+    int i;
+
+    /* Skip over name */
+    any += (((info->name_len + 3)/4) * 4);
+
+    for (i = 0; i < info->num_classes; i++)
+    {
+        switch(((xXIAnyInfo*)any)->type)
+        {
+            case ButtonClass:
+                SwapButtonInfo(dev, (xXIButtonInfo*)any);
+                break;
+            case KeyClass:
+                SwapKeyInfo(dev, (xXIKeyInfo*)any);
+                break;
+            case ValuatorClass:
+                SwapValuatorInfo(dev, (xXIValuatorInfo*)any);
+                break;
+        }
+
+        any += (((xXIAnyInfo*)any)->length * 4);
+    }
+
+    swaps(&info->deviceid, n);
+    swaps(&info->use, n);
+    swaps(&info->attachment, n);
+    swaps(&info->num_classes, n);
+    swaps(&info->name_len, n);
+
+}
diff --git a/Xi/querydev.h b/Xi/querydev.h
new file mode 100644
index 0000000..92ab2bd
--- /dev/null
+++ b/Xi/querydev.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Authors: Peter Hutterer
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef QUERYDEV_H
+#define QUERYDEV_H 1
+
+#include <X11/extensions/XI2proto.h>
+
+int SProcXIQueryDevice(ClientPtr client);
+int ProcXIQueryDevice(ClientPtr client);
+void SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep);
+int SizeDeviceClasses(DeviceIntPtr dev);
+int ListDeviceClasses(DeviceIntPtr dev, char* any, uint16_t* nclasses);
+int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment);
+#endif /* QUERYDEV_H */
diff --git a/dix/devices.c b/dix/devices.c
index 97b47bc..ca0da07 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -78,7 +78,7 @@ SOFTWARE.
 #include <X11/extensions/XIproto.h>
 #include "exglobals.h"
 #include "exevents.h"
-#include "listdev.h" /* for CopySwapXXXClass */
+#include "querydev.h" /* for SizeDeviceClasses */
 #include "xiproperty.h"
 #include "enterleave.h" /* for EnterWindow() */
 #include "xserver-properties.h"
@@ -274,7 +274,6 @@ EnableDevice(DeviceIntPtr dev)
     DeviceIntPtr *prev;
     int ret;
     DeviceIntPtr other;
-    int namelen = 0; /* dummy */
     int evsize  = sizeof(xEvent);
     int listlen;
     EventListPtr evlist;
@@ -316,7 +315,7 @@ EnableDevice(DeviceIntPtr dev)
      * device
      */
 
-    SizeDeviceInfo(dev, &namelen, &evsize);
+    evsize += SizeDeviceClasses(dev);
 
     listlen = GetEventList(&evlist);
     OsBlockSignals();
commit 560c58b53e4e60ebd26e0c66dd00399c438bd619
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 20 15:17:52 2009 +1000

    Xi: name-space and fix XI2 requests
    
    All XI2 requests have XI prefixes.
    Requests affected:
        ChangeDeviceCursor
        QueryDevicePointer
        WarpDevicePointer
        SetClientPointer
        GetClientPointer
        XIChangeDeviceHierarchy.

diff --git a/Xi/chdevcur.c b/Xi/chdevcur.c
index b0d3ce3..ed1570b 100644
--- a/Xi/chdevcur.c
+++ b/Xi/chdevcur.c
@@ -39,7 +39,7 @@
 #include "windowstr.h"	/* window structure  */
 #include "scrnintstr.h"	/* screen structure  */
 #include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include "extnsionst.h"
 #include "exevents.h"
 #include "exglobals.h"
@@ -54,25 +54,25 @@
  */
 
 int
-SProcXChangeDeviceCursor(ClientPtr client)
+SProcXIChangeDeviceCursor(ClientPtr client)
 {
     char n;
 
-    REQUEST(xChangeDeviceCursorReq);
+    REQUEST(xXIChangeDeviceCursorReq);
     swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xChangeDeviceCursorReq);
-    return (ProcXChangeDeviceCursor(client));
+    REQUEST_SIZE_MATCH(xXIChangeDeviceCursorReq);
+    return (ProcXIChangeDeviceCursor(client));
 }
 
-int ProcXChangeDeviceCursor(ClientPtr client)
+int ProcXIChangeDeviceCursor(ClientPtr client)
 {
     int rc;
     WindowPtr pWin    = NULL;
     DeviceIntPtr pDev = NULL;
     CursorPtr pCursor = NULL;
 
-    REQUEST(xChangeDeviceCursorReq);
-    REQUEST_SIZE_MATCH(xChangeDeviceCursorReq);
+    REQUEST(xXIChangeDeviceCursorReq);
+    REQUEST_SIZE_MATCH(xXIChangeDeviceCursorReq);
 
     rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixSetAttrAccess);
     if (rc != Success)
diff --git a/Xi/chdevcur.h b/Xi/chdevcur.h
index e6df9eb..4f7f44b 100644
--- a/Xi/chdevcur.h
+++ b/Xi/chdevcur.h
@@ -30,10 +30,7 @@
 #ifndef CHDEVCUR_H
 #define CHDEVCUR_H 1
 
-int SProcXChangeDeviceCursor(ClientPtr	/* client */
-    );
-
-int ProcXChangeDeviceCursor(ClientPtr	/* client */
-    );
+int SProcXIChangeDeviceCursor(ClientPtr	/* client */);
+int ProcXIChangeDeviceCursor(ClientPtr	/* client */);
 
 #endif /* CHDEVCUR_H */
diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
index 9a85829..3df9c87 100644
--- a/Xi/chdevhier.c
+++ b/Xi/chdevhier.c
@@ -40,7 +40,7 @@
 #include "windowstr.h"	/* window structure  */
 #include "scrnintstr.h"	/* screen structure  */
 #include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include <X11/extensions/geproto.h>
 #include "extnsionst.h"
 #include "exevents.h"
@@ -60,33 +60,33 @@
  *
  */
 
-int SProcXChangeDeviceHierarchy(ClientPtr client)
+int SProcXIChangeDeviceHierarchy(ClientPtr client)
 {
     char n;
 
-    REQUEST(xChangeDeviceHierarchyReq);
+    REQUEST(xXIChangeDeviceHierarchyReq);
     swaps(&stuff->length, n);
-    return (ProcXChangeDeviceHierarchy(client));
+    return (ProcXIChangeDeviceHierarchy(client));
 }
 
 #define SWAPIF(cmd) if (client->swapped) { cmd; }
 
 int
-ProcXChangeDeviceHierarchy(ClientPtr client)
+ProcXIChangeDeviceHierarchy(ClientPtr client)
 {
     DeviceIntPtr ptr, keybd;
     DeviceIntRec dummyDev;
-    xAnyHierarchyChangeInfo *any;
-    int required_len = sizeof(xChangeDeviceHierarchyReq);
+    xXIAnyHierarchyChangeInfo *any;
+    int required_len = sizeof(xXIChangeDeviceHierarchyReq);
     char n;
     int rc = Success;
     int nchanges = 0;
-    deviceHierarchyChangedEvent ev;
+    xXIDeviceHierarchyEvent ev;
 
-    REQUEST(xChangeDeviceHierarchyReq);
-    REQUEST_AT_LEAST_SIZE(xChangeDeviceHierarchyReq);
+    REQUEST(xXIChangeDeviceHierarchyReq);
+    REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq);
 
-    any = (xAnyHierarchyChangeInfo*)&stuff[1];
+    any = (xXIAnyHierarchyChangeInfo*)&stuff[1];
     while(stuff->num_changes--)
     {
         SWAPIF(swapl(&any->type, n));
@@ -100,12 +100,12 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
         {
             case CH_CreateMasterDevice:
                 {
-                    xCreateMasterInfo* c = (xCreateMasterInfo*)any;
+                    xXICreateMasterInfo* c = (xXICreateMasterInfo*)any;
                     char* name;
 
-                    SWAPIF(swaps(&c->namelen, n));
-                    name = xcalloc(c->namelen + 1, sizeof(char));
-                    strncpy(name, (char*)&c[1], c->namelen);
+                    SWAPIF(swaps(&c->name_len, n));
+                    name = xcalloc(c->name_len + 1, sizeof(char));
+                    strncpy(name, (char*)&c[1], c->name_len);
 
 
                     rc = AllocMasterDevice(client, name, &ptr, &keybd);
@@ -115,7 +115,7 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                         goto unwind;
                     }
 
-                    if (!c->sendCore)
+                    if (!c->send_core)
                         ptr->coreEvents = keybd->coreEvents =  FALSE;
 
                     ActivateDevice(ptr);
@@ -132,10 +132,10 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                 break;
             case CH_RemoveMasterDevice:
                 {
-                    xRemoveMasterInfo* r = (xRemoveMasterInfo*)any;
+                    xXIRemoveMasterInfo* r = (xXIRemoveMasterInfo*)any;
 
-                    if (r->returnMode != AttachToMaster &&
-                            r->returnMode != Floating)
+                    if (r->return_mode != AttachToMaster &&
+                            r->return_mode != Floating)
                         return BadValue;
 
                     rc = dixLookupDevice(&ptr, r->deviceid, client,
@@ -182,32 +182,32 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
 
                     /* Disabling sends the devices floating, reattach them if
                      * desired. */
-                    if (r->returnMode == AttachToMaster)
+                    if (r->return_mode == AttachToMaster)
                     {
                         DeviceIntPtr attached,
                                      newptr,
                                      newkeybd;
 
-                        rc = dixLookupDevice(&newptr, r->returnPointer,
+                        rc = dixLookupDevice(&newptr, r->return_pointer,
                                              client, DixWriteAccess);
                         if (rc != Success)
                             goto unwind;
 
                         if (!newptr->isMaster)
                         {
-                            client->errorValue = r->returnPointer;
+                            client->errorValue = r->return_pointer;
                             rc = BadDevice;
                             goto unwind;
                         }
 
-                        rc = dixLookupDevice(&newkeybd, r->returnKeyboard,
+                        rc = dixLookupDevice(&newkeybd, r->return_keyboard,
                                              client, DixWriteAccess);
                         if (rc != Success)
                             goto unwind;
 
                         if (!newkeybd->isMaster)
                         {
-                            client->errorValue = r->returnKeyboard;
+                            client->errorValue = r->return_keyboard;
                             rc = BadDevice;
                             goto unwind;
                         }
@@ -236,9 +236,9 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                     nchanges++;
                 }
                 break;
-            case CH_ChangeAttachment:
+            case CH_DetachSlave:
                 {
-                    xChangeAttachmentInfo* c = (xChangeAttachmentInfo*)any;
+                    xXIDetachSlaveInfo* c = (xXIDetachSlaveInfo*)any;
 
                     rc = dixLookupDevice(&ptr, c->deviceid, client,
                                           DixWriteAccess);
@@ -252,38 +252,53 @@ ProcXChangeDeviceHierarchy(ClientPtr client)
                         goto unwind;
                     }
 
-                    if (c->changeMode == Floating)
-                        AttachDevice(client, ptr, NULL);
-                    else
+                    AttachDevice(client, ptr, NULL);
+                    nchanges++;
+                }
+                break;
+            case CH_AttachSlave:
+                {
+                    xXIAttachSlaveInfo* c = (xXIAttachSlaveInfo*)any;
+                    DeviceIntPtr newmaster;
+
+                    rc = dixLookupDevice(&ptr, c->deviceid, client,
+                                          DixWriteAccess);
+                    if (rc != Success)
+                       goto unwind;
+
+                    if (ptr->isMaster)
                     {
-                        DeviceIntPtr newmaster;
-                        rc = dixLookupDevice(&newmaster, c->newMaster,
-                                             client, DixWriteAccess);
-                        if (rc != Success)
-                            goto unwind;
-                        if (!newmaster->isMaster)
-                        {
-                            client->errorValue = c->newMaster;
-                            rc = BadDevice;
-                            goto unwind;
-                        }
+                        client->errorValue = c->deviceid;
+                        rc = BadDevice;
+                        goto unwind;
+                    }
+
+                    rc = dixLookupDevice(&newmaster, c->new_master,
+                            client, DixWriteAccess);
+                    if (rc != Success)
+                        goto unwind;
+                    if (!newmaster->isMaster)
+                    {
+                        client->errorValue = c->new_master;
+                        rc = BadDevice;
+                        goto unwind;
+                    }
 
-                        if (!((IsPointerDevice(newmaster) &&
+                    if (!((IsPointerDevice(newmaster) &&
                                     IsPointerDevice(ptr)) ||
                                 (IsKeyboardDevice(newmaster) &&
                                  IsKeyboardDevice(ptr))))
-                        {
-                            rc = BadDevice;
-                            goto unwind;
-                        }
-                        AttachDevice(client, ptr, newmaster);
+                    {
+                        rc = BadDevice;
+                        goto unwind;
                     }
+                    AttachDevice(client, ptr, newmaster);
                     nchanges++;
                 }
                 break;
         }
 
-        any = (xAnyHierarchyChangeInfo*)((char*)any + any->length);
+        any = (xXIAnyHierarchyChangeInfo*)((char*)any + any->length * 4);
     }
 
 unwind:
@@ -294,7 +309,7 @@ unwind:
         ev.type = GenericEvent;
         ev.extension = IReqCode;
         ev.length = 0;
-        ev.evtype = XI_DeviceHierarchyChangedNotify;
+        ev.evtype = XI_HierarchyChanged;
         ev.time = GetTimeInMillis();
 
         SendEventToAllWindows(&dummyDev, XI_DeviceHierarchyChangedMask,
diff --git a/Xi/chdevhier.h b/Xi/chdevhier.h
index 07afd53..4190538 100644
--- a/Xi/chdevhier.h
+++ b/Xi/chdevhier.h
@@ -36,7 +36,7 @@
 #ifndef CHDEVHIER_H
 #define CHDEVHIER_H 1
 
-int SProcXChangeDeviceHierarchy(ClientPtr /* client */);
-int ProcXChangeDeviceHierarchy(ClientPtr /* client */);
+int SProcXIChangeDeviceHierarchy(ClientPtr /* client */);
+int ProcXIChangeDeviceHierarchy(ClientPtr /* client */);
 
 #endif
diff --git a/Xi/extinit.c b/Xi/extinit.c
index e083184..988ed0b 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -61,6 +61,7 @@ SOFTWARE.
 #include "extnsionst.h"	/* extension entry   */
 #include <X11/extensions/XI.h>
 #include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include <X11/extensions/geproto.h>
 #include "geext.h" /* extension interfaces for ge */
 
@@ -229,12 +230,12 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXDeleteDeviceProperty,              /* 38 */
         ProcXGetDeviceProperty,                 /* 39 */
         /* XI 2 */
-        ProcXQueryDevicePointer,                /* 40 */
-        ProcXWarpDevicePointer,                 /* 41 */
-        ProcXChangeDeviceCursor,                /* 42 */
-        ProcXChangeDeviceHierarchy,             /* 43 */
-        ProcXSetClientPointer,                  /* 44 */
-        ProcXGetClientPointer,                  /* 45 */
+        ProcXIQueryDevicePointer,               /* 40 */
+        ProcXIWarpDevicePointer,                /* 41 */
+        ProcXIChangeDeviceCursor,               /* 42 */
+        ProcXIChangeDeviceHierarchy,            /* 43 */
+        ProcXISetClientPointer,                 /* 44 */
+        ProcXIGetClientPointer,                 /* 45 */
         ProcXiSelectEvent,                      /* 46 */
         ProcXIQueryVersion                      /* 47 */
 };
@@ -281,12 +282,12 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXChangeDeviceProperty,              /* 37 */
         SProcXDeleteDeviceProperty,              /* 38 */
         SProcXGetDeviceProperty,                 /* 39 */
-        SProcXQueryDevicePointer,                /* 40 */
-        SProcXWarpDevicePointer,                 /* 41 */
-        SProcXChangeDeviceCursor,                /* 42 */
-        SProcXChangeDeviceHierarchy,             /* 43 */
-        SProcXSetClientPointer,                  /* 44 */
-        SProcXGetClientPointer,                  /* 45 */
+        SProcXIQueryDevicePointer,               /* 40 */
+        SProcXIWarpDevicePointer,                /* 41 */
+        SProcXIChangeDeviceCursor,               /* 42 */
+        SProcXIChangeDeviceHierarchy,            /* 43 */
+        SProcXISetClientPointer,                 /* 44 */
+        SProcXIGetClientPointer,                 /* 45 */
         SProcXiSelectEvent,                      /* 46 */
         SProcXIQueryVersion                      /* 47 */
 };
@@ -474,11 +475,11 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
         SRepXListDeviceProperties(client, len, (xListDevicePropertiesReply*)rep);
     else if (rep->RepType == X_GetDeviceProperty)
 	SRepXGetDeviceProperty(client, len, (xGetDevicePropertyReply *) rep);
-    else if (rep->RepType == X_QueryDevicePointer)
-	SRepXQueryDevicePointer(client, len,
-				(xQueryDevicePointerReply *) rep);
-    else if (rep->RepType == X_GetClientPointer)
-        SRepXGetClientPointer(client, len, (xGetClientPointerReply*) rep);
+    else if (rep->RepType == X_XIQueryDevicePointer)
+	SRepXIQueryDevicePointer(client, len,
+				(xXIQueryDevicePointerReply *) rep);
+    else if (rep->RepType == X_XIGetClientPointer)
+        SRepXIGetClientPointer(client, len, (xXIGetClientPointerReply*) rep);
     else {
 	FatalError("XINPUT confused sending swapped reply");
     }
diff --git a/Xi/getcptr.c b/Xi/getcptr.c
index c696afe..5c69942 100644
--- a/Xi/getcptr.c
+++ b/Xi/getcptr.c
@@ -33,7 +33,7 @@
 #include "windowstr.h"	/* window structure  */
 #include "scrnintstr.h"	/* screen structure  */
 #include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include "extnsionst.h"
 #include "extinit.h"	/* LookupDeviceIntRec */
 #include "exevents.h"
@@ -47,29 +47,29 @@
  */
 
 int
-SProcXGetClientPointer(ClientPtr client)
+SProcXIGetClientPointer(ClientPtr client)
 {
     char n;
-    REQUEST(xGetClientPointerReq);
+    REQUEST(xXIGetClientPointerReq);
 
     swaps(&stuff->length, n);
     swapl(&stuff->win, n);
-    return ProcXGetClientPointer(client);
+    return ProcXIGetClientPointer(client);
 }
 
-int ProcXGetClientPointer(ClientPtr client)
+int ProcXIGetClientPointer(ClientPtr client)
 {
     int err;
     WindowPtr win;
     ClientPtr winclient;
-    xGetClientPointerReply rep;
-    REQUEST(xGetClientPointerReq);
-    REQUEST_SIZE_MATCH(xGetClientPointerReq);
+    xXIGetClientPointerReply rep;
+    REQUEST(xXIGetClientPointerReq);
+    REQUEST_SIZE_MATCH(xXIGetClientPointerReq);
 
     err = dixLookupWindow(&win, stuff->win, client, DixReadAccess);
     if (err != Success)
     {
-        SendErrorToClient(client, IReqCode, X_GetClientPointer,
+        SendErrorToClient(client, IReqCode, X_XIGetClientPointer,
                 stuff->win, err);
         return Success;
     }
@@ -77,13 +77,13 @@ int ProcXGetClientPointer(ClientPtr client)
     winclient = wClient(win);
 
     rep.repType = X_Reply;
-    rep.RepType = X_GetClientPointer;
+    rep.RepType = X_XIGetClientPointer;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
     rep.set = (winclient->clientPtr != NULL);
     rep.deviceid = (winclient->clientPtr) ? winclient->clientPtr->id : 0;
 
-    WriteReplyToClient(client, sizeof(xGetClientPointerReply), &rep);
+    WriteReplyToClient(client, sizeof(xXIGetClientPointerReply), &rep);
     return Success;
 }
 
@@ -95,8 +95,8 @@ int ProcXGetClientPointer(ClientPtr client)
  */
 
 void
-SRepXGetClientPointer(ClientPtr client, int size,
-        xGetClientPointerReply* rep)
+SRepXIGetClientPointer(ClientPtr client, int size,
+        xXIGetClientPointerReply* rep)
 {
     char n;
     swaps(&rep->sequenceNumber, n);
diff --git a/Xi/getcptr.h b/Xi/getcptr.h
index 2745833..1539aa8 100644
--- a/Xi/getcptr.h
+++ b/Xi/getcptr.h
@@ -29,15 +29,10 @@
 
 #ifndef GETCPTR_H
 #define GETCPTR_H 1
-int SProcXGetClientPointer(ClientPtr /* client */
-        );
-
-int ProcXGetClientPointer(ClientPtr /* client */
-        );
-
-void SRepXGetClientPointer(ClientPtr /* client */,
+int SProcXIGetClientPointer(ClientPtr /* client */);
+int ProcXIGetClientPointer(ClientPtr /* client */);
+void SRepXIGetClientPointer(ClientPtr /* client */,
         int /* size */,
-        xGetClientPointerReply* /* rep */
-        );
+        xXIGetClientPointerReply* /* rep */);
 
 #endif /* GETCPTR_H */
diff --git a/Xi/querydp.c b/Xi/querydp.c
index ab59e66..5be0cea 100644
--- a/Xi/querydp.c
+++ b/Xi/querydp.c
@@ -38,7 +38,7 @@
 #include "inputstr.h"	/* DeviceIntPtr      */
 #include "windowstr.h"	/* window structure  */
 #include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include "extnsionst.h"
 #include "exevents.h"
 #include "exglobals.h"
@@ -57,26 +57,26 @@
  */
 
 int
-SProcXQueryDevicePointer(ClientPtr client)
+SProcXIQueryDevicePointer(ClientPtr client)
 {
     char n;
 
-    REQUEST(xQueryDevicePointerReq);
+    REQUEST(xXIQueryDevicePointerReq);
     swaps(&stuff->length, n);
-    return (ProcXQueryDevicePointer(client));
+    return (ProcXIQueryDevicePointer(client));
 }
 
 int
-ProcXQueryDevicePointer(ClientPtr client)
+ProcXIQueryDevicePointer(ClientPtr client)
 {
     int rc;
-    xQueryDevicePointerReply rep;
+    xXIQueryDevicePointerReply rep;
     DeviceIntPtr pDev, kbd;
     WindowPtr pWin, t;
     SpritePtr pSprite;
 
-    REQUEST(xQueryDevicePointerReq);
-    REQUEST_SIZE_MATCH(xQueryDevicePointerReq);
+    REQUEST(xXIQueryDevicePointerReq);
+    REQUEST_SIZE_MATCH(xXIQueryDevicePointerReq);
 
     rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess);
     if (rc != Success)
@@ -91,7 +91,7 @@ ProcXQueryDevicePointer(ClientPtr client)
     rc = dixLookupWindow(&pWin, stuff->win, client, DixReadAccess);
     if (rc != Success)
     {
-        SendErrorToClient(client, IReqCode, X_QueryDevicePointer,
+        SendErrorToClient(client, IReqCode, X_XIQueryDevicePointer,
                 stuff->win, rc);
         return Success;
     }
@@ -103,23 +103,23 @@ ProcXQueryDevicePointer(ClientPtr client)
 
     pSprite = pDev->spriteInfo->sprite;
     rep.repType = X_Reply;
-    rep.RepType = X_QueryDevicePointer;
+    rep.RepType = X_XIQueryDevicePointer;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
     rep.mask = pDev->button->state;
     if (kbd && kbd->key)
         rep.mask |= XkbStateFieldFromRec(&kbd->key->xkbInfo->state);
     rep.root = (GetCurrentRootWindow(pDev))->drawable.id;
-    rep.rootX = pSprite->hot.x;
-    rep.rootY = pSprite->hot.y;
+    rep.root_x.integral = pSprite->hot.x;
+    rep.root_y.integral = pSprite->hot.y;
     rep.child = None;
     rep.deviceid = pDev->id;
 
     if (pSprite->hot.pScreen == pWin->drawable.pScreen)
     {
-        rep.sameScreen = xTrue;
-        rep.winX = pSprite->hot.x - pWin->drawable.x;
-        rep.winY = pSprite->hot.y - pWin->drawable.y;
+        rep.same_screen = xTrue;
+        rep.win_x.integral = pSprite->hot.x - pWin->drawable.x;
+        rep.win_y.integral = pSprite->hot.y - pWin->drawable.y;
         for (t = pSprite->win; t; t = t->parent)
             if (t->parent == pWin)
             {
@@ -128,37 +128,37 @@ ProcXQueryDevicePointer(ClientPtr client)
             }
     } else
     {
-        rep.sameScreen = xFalse;
-        rep.winX = 0;
-        rep.winY = 0;
+        rep.same_screen = xFalse;
+        rep.win_x.integral = 0;
+        rep.win_y.integral = 0;
     }
 
 #ifdef PANORAMIX
     if(!noPanoramiXExtension) {
-        rep.rootX += panoramiXdataPtr[0].x;
-        rep.rootY += panoramiXdataPtr[0].y;
+        rep.root_x.integral += panoramiXdataPtr[0].x;
+        rep.root_y.integral += panoramiXdataPtr[0].y;
         if (stuff->win == rep.root)
         {
-            rep.winX += panoramiXdataPtr[0].x;
-            rep.winY += panoramiXdataPtr[0].y;
+            rep.win_x.integral += panoramiXdataPtr[0].x;
+            rep.win_y.integral += panoramiXdataPtr[0].y;
         }
     }
 #endif
 
-    WriteReplyToClient(client, sizeof(xQueryDevicePointerReply), &rep);
+    WriteReplyToClient(client, sizeof(xXIQueryDevicePointerReply), &rep);
     return Success;
 }
 
 /***********************************************************************
  *
- * This procedure writes the reply for the XQueryDevicePointer function,
+ * This procedure writes the reply for the XIQueryDevicePointer function,
  * if the client and server have a different byte ordering.
  *
  */
 
 void
-SRepXQueryDevicePointer(ClientPtr client, int size,
-        xQueryDevicePointerReply * rep)
+SRepXIQueryDevicePointer(ClientPtr client, int size,
+        xXIQueryDevicePointerReply * rep)
 {
     char n;
 
diff --git a/Xi/querydp.h b/Xi/querydp.h
index 5370ed4..48b6217 100644
--- a/Xi/querydp.h
+++ b/Xi/querydp.h
@@ -30,15 +30,10 @@
 #ifndef QUERYDP_H
 #define QUERYDP_H 1
 
-int SProcXQueryDevicePointer(ClientPtr	/* client */
-    );
-
-int ProcXQueryDevicePointer(ClientPtr	/* client */
-    );
-
-void SRepXQueryDevicePointer(ClientPtr /* client */ ,
+int SProcXIQueryDevicePointer(ClientPtr	/* client */);
+int ProcXIQueryDevicePointer(ClientPtr	/* client */);
+void SRepXIQueryDevicePointer(ClientPtr /* client */ ,
 			   int /* size */ ,
-			   xQueryDevicePointerReply *	/* rep */
-    );
+			   xXIQueryDevicePointerReply *	/* rep */);
 
 #endif /* QUERYDP_H */
diff --git a/Xi/setcptr.c b/Xi/setcptr.c
index 1e8281d..46b88bf 100644
--- a/Xi/setcptr.c
+++ b/Xi/setcptr.c
@@ -41,7 +41,7 @@
 #include "windowstr.h"	/* window structure  */
 #include "scrnintstr.h"	/* screen structure  */
 #include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include "extnsionst.h"
 #include "exevents.h"
 #include "exglobals.h"
@@ -49,25 +49,25 @@
 #include "setcptr.h"
 
 int
-SProcXSetClientPointer(ClientPtr client)
+SProcXISetClientPointer(ClientPtr client)
 {
     char n;
 
-    REQUEST(xSetClientPointerReq);
+    REQUEST(xXISetClientPointerReq);
     swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xSetClientPointerReq);
-    return (ProcXSetClientPointer(client));
+    REQUEST_SIZE_MATCH(xXISetClientPointerReq);
+    return (ProcXISetClientPointer(client));
 }
 
 int
-ProcXSetClientPointer(ClientPtr client)
+ProcXISetClientPointer(ClientPtr client)
 {
     DeviceIntPtr pDev;
     ClientPtr targetClient;
     int rc;
 
-    REQUEST(xSetClientPointerReq);
-    REQUEST_SIZE_MATCH(xSetClientPointerReq);
+    REQUEST(xXISetClientPointerReq);
+    REQUEST_SIZE_MATCH(xXISetClientPointerReq);
 
 
     rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixWriteAccess);
diff --git a/Xi/setcptr.h b/Xi/setcptr.h
index df38add..5968d98 100644
--- a/Xi/setcptr.h
+++ b/Xi/setcptr.h
@@ -30,7 +30,7 @@
 #ifndef SETCPTR_H
 #define SETCPTR_H 1
 
-int SProcXSetClientPointer(ClientPtr /* client */);
-int ProcXSetClientPointer(ClientPtr /* client */);
+int SProcXISetClientPointer(ClientPtr /* client */);
+int ProcXISetClientPointer(ClientPtr /* client */);
 
 #endif /* SETCPTR_H */
diff --git a/Xi/warpdevp.c b/Xi/warpdevp.c
index b40a12c..2317c86 100644
--- a/Xi/warpdevp.c
+++ b/Xi/warpdevp.c
@@ -39,7 +39,7 @@
 #include "windowstr.h"	/* window structure  */
 #include "scrnintstr.h"	/* screen structure  */
 #include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include "extnsionst.h"
 #include "exevents.h"
 #include "exglobals.h"
@@ -54,17 +54,17 @@
  */
 
 int
-SProcXWarpDevicePointer(ClientPtr client)
+SProcXIWarpDevicePointer(ClientPtr client)
 {
     char n;
 
-    REQUEST(xWarpDevicePointerReq);
+    REQUEST(xXIWarpDevicePointerReq);
     swaps(&stuff->length, n);
-    return (ProcXWarpDevicePointer(client));
+    return (ProcXIWarpDevicePointer(client));
 }
 
 int
-ProcXWarpDevicePointer(ClientPtr client)
+ProcXIWarpDevicePointer(ClientPtr client)
 {
     int rc;
     int x, y;
@@ -73,8 +73,8 @@ ProcXWarpDevicePointer(ClientPtr client)
     SpritePtr pSprite;
     ScreenPtr newScreen;
 
-    REQUEST(xWarpDevicePointerReq);
-    REQUEST_SIZE_MATCH(xWarpDevicePointerReq);
+    REQUEST(xXIWarpDevicePointerReq);
+    REQUEST_SIZE_MATCH(xXIWarpDevicePointerReq);
 
     /* FIXME: panoramix stuff is missing, look at ProcWarpPointer */
 
diff --git a/Xi/warpdevp.h b/Xi/warpdevp.h
index 00a4dff..edf95c0 100644
--- a/Xi/warpdevp.h
+++ b/Xi/warpdevp.h
@@ -30,10 +30,7 @@
 #ifndef WARPDEVP_H
 #define WARPDEVP_H 1
 
-int SProcXWarpDevicePointer(ClientPtr	/* client */
-    );
-
-int ProcXWarpDevicePointer(ClientPtr	/* client */
-    );
+int SProcXIWarpDevicePointer(ClientPtr	/* client */);
+int ProcXIWarpDevicePointer(ClientPtr	/* client */);
 
 #endif /* WARPDEVP_H */
commit 903449615b1a1188955c0287a552aec8ac5b3fbb
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 20 15:03:35 2009 +1000

    Xi: add XIQueryVersion request handling.

diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 7fd593c..316fd29 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -60,6 +60,8 @@ libXi_la_SOURCES =	\
 	listdev.h \
 	opendev.c \
 	opendev.h \
+	queryversion.h \
+	queryversion.c \
 	querydp.c \
 	querydp.h \
 	queryst.c \
diff --git a/Xi/extinit.c b/Xi/extinit.c
index f99b555..e083184 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -103,6 +103,7 @@ SOFTWARE.
 #include "opendev.h"
 #include "querydp.h"
 #include "queryst.h"
+#include "queryversion.h"
 #include "selectev.h"
 #include "sendexev.h"
 #include "chgkmap.h"
@@ -234,7 +235,8 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXChangeDeviceHierarchy,             /* 43 */
         ProcXSetClientPointer,                  /* 44 */
         ProcXGetClientPointer,                  /* 45 */
-        ProcXiSelectEvent                       /* 46 */
+        ProcXiSelectEvent,                      /* 46 */
+        ProcXIQueryVersion                      /* 47 */
 };
 
 /* For swapped clients */
@@ -285,7 +287,8 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXChangeDeviceHierarchy,             /* 43 */
         SProcXSetClientPointer,                  /* 44 */
         SProcXGetClientPointer,                  /* 45 */
-        SProcXiSelectEvent                       /* 46 */
+        SProcXiSelectEvent,                      /* 46 */
+        SProcXIQueryVersion                      /* 47 */
 };
 
 /*****************************************************************
diff --git a/Xi/queryversion.c b/Xi/queryversion.c
new file mode 100644
index 0000000..3e0644b
--- /dev/null
+++ b/Xi/queryversion.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Authors: Peter Hutterer
+ *
+ */
+
+/**
+ * @file queryversion.c
+ * Protocol handling for the XIQueryVersion request/reply.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+
+#include "inputstr.h"
+
+#include <X11/Xmd.h>
+#include <X11/X.h>
+#include <X11/extensions/XI2proto.h>
+
+#include "exglobals.h"
+#include "exevents.h"
+#include "queryversion.h"
+
+extern XExtensionVersion XIVersion; /* defined in getvers.c */
+/**
+ * Return the supported XI version.
+ *
+ * Saves the version the client claims to support as well, for future
+ * reference.
+ */
+int
+ProcXIQueryVersion(ClientPtr client)
+{
+    xXIQueryVersionReply rep;
+    XIClientPtr pXIClient;
+
+    REQUEST(xXIQueryVersionReq);
+    REQUEST_SIZE_MATCH(xXIQueryVersionReq);
+
+    pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
+
+    pXIClient->major_version = stuff->major_version;
+    pXIClient->minor_version = stuff->minor_version;
+
+    memset(&rep, 0, sizeof(xXIQueryVersionReply));
+    rep.repType = X_Reply;
+    rep.RepType = X_XIQueryVersion;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.major_version = XIVersion.major_version;
+    rep.minor_version = XIVersion.minor_version;
+
+    WriteReplyToClient(client, sizeof(xXIQueryVersionReply), &rep);
+
+    return Success;
+}
+
+/* Swapping routines */
+
+int
+SProcXIQueryVersion(ClientPtr client)
+{
+    char n;
+
+    REQUEST(xXIQueryVersionReq);
+    swaps(&stuff->length, n);
+    REQUEST_AT_LEAST_SIZE(xXIQueryVersionReq);
+    swaps(&stuff->major_version, n);
+    swaps(&stuff->major_version, n);
+    return (ProcXIQueryVersion(client));
+}
+
+void
+SRepXIQueryVersion(ClientPtr client, int size, xXIQueryVersionReply *rep)
+{
+    char n;
+    swaps(&rep->sequenceNumber, n);
+    swapl(&rep->length, n);
+    swaps(&rep->major_version, n);
+    swaps(&rep->minor_version, n);
+    WriteToClient(client, size, (char *)rep);
+}
diff --git a/Xi/queryversion.h b/Xi/queryversion.h
new file mode 100644
index 0000000..06bb729
--- /dev/null
+++ b/Xi/queryversion.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2009 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.
+ *
+ * Authors: Peter Hutterer
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/extensions/XI2proto.h>
+
+#ifndef QUERYVERSION_H
+#define QUERYVERSION_H 1
+
+int SProcXIQueryVersion(ClientPtr client);
+int ProcXIQueryVersion(ClientPtr client);
+void SRepXIQueryVersion(ClientPtr client, int size, xXIQueryVersionReply* rep);
+
+#endif /* QUERYVERSION_H */
commit 77d51b94bd264be5a8625a2bdd98f2bfb2aa33d3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Mar 8 11:47:26 2009 +1000

    dix: FixUpEventForWindow needs to handle XI2 events.

diff --git a/dix/events.c b/dix/events.c
index 316703e..b27c8e1 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2101,6 +2101,37 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
     return 2;
 }
 
+static Window FindChildForEvent(DeviceIntPtr dev, WindowPtr event)
+{
+    SpritePtr pSprite = dev->spriteInfo->sprite;
+    WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1];
+    Window child;
+
+    /* If the search ends up past the root should the child field be
+       set to none or should the value in the argument be passed
+       through. It probably doesn't matter since everyone calls
+       this function with child == None anyway. */
+    while (w)
+    {
+        /* If the source window is same as event window, child should be
+           none.  Don't bother going all all the way back to the root. */
+
+        if (w == event)
+        {
+            child = None;
+            break;
+        }
+
+        if (w->parent == event)
+        {
+            child = w->drawable.id;
+            break;
+        }
+        w = w->parent;
+    }
+    return child;
+}
+
 /**
  * Adjust event fields to comply with the window properties.
  *
@@ -2119,53 +2150,50 @@ FixUpEventFromWindow(
 {
     SpritePtr pSprite = pDev->spriteInfo->sprite;
 
-    if (xE->u.u.type == GenericEvent) /* just a safety barrier */
-        return;
-
     if (calcChild)
-    {
-        WindowPtr w= pSprite->spriteTrace[pSprite->spriteTraceGood-1];
-	/* If the search ends up past the root should the child field be
-		set to none or should the value in the argument be passed
-		through. It probably doesn't matter since everyone calls
-		this function with child == None anyway. */
+        child = FindChildForEvent(pDev, pWin);
 
-        while (w)
+    if (XI2_EVENT(xE))
+    {
+        xXIDeviceEvent* event = (xXIDeviceEvent*)xE;
+        event->root = RootWindow(pDev)->drawable.id;
+        event->event = pWin->drawable.id;
+        if (pSprite->hot.pScreen == pWin->drawable.pScreen)
+        {
+            event->event_x.integral = event->root_x.integral - pWin->drawable.x;
+            event->event_y.integral = event->root_y.integral - pWin->drawable.y;
+            event->child = child;
+        } else
         {
-            /* If the source window is same as event window, child should be
-		none.  Don't bother going all all the way back to the root. */
+            event->event_x.integral = 0;
+            event->event_y.integral = 0;
+            event->child = None;
+        }
 
-	    if (w == pWin)
-	    {
-		child = None;
-		break;
-	    }
+        if (event->evtype == XI_Enter || event->evtype == XI_Leave)
+            ((xXIEnterEvent*)event)->same_screen =
+                (pSprite->hot.pScreen == pWin->drawable.pScreen);
 
-	    if (w->parent == pWin)
-	    {
-		child = w->drawable.id;
-		break;
-            }
-	    w = w->parent;
-        }
-    }
-    XE_KBPTR.root = RootWindow(pDev)->drawable.id;
-    XE_KBPTR.event = pWin->drawable.id;
-    if (pSprite->hot.pScreen == pWin->drawable.pScreen)
-    {
-	XE_KBPTR.sameScreen = xTrue;
-	XE_KBPTR.child = child;
-	XE_KBPTR.eventX =
-	XE_KBPTR.rootX - pWin->drawable.x;
-	XE_KBPTR.eventY =
-	XE_KBPTR.rootY - pWin->drawable.y;
-    }
-    else
+    } else
     {
-	XE_KBPTR.sameScreen = xFalse;
-	XE_KBPTR.child = None;
-	XE_KBPTR.eventX = 0;
-	XE_KBPTR.eventY = 0;
+        XE_KBPTR.root = RootWindow(pDev)->drawable.id;
+        XE_KBPTR.event = pWin->drawable.id;
+        if (pSprite->hot.pScreen == pWin->drawable.pScreen)
+        {
+            XE_KBPTR.sameScreen = xTrue;
+            XE_KBPTR.child = child;
+            XE_KBPTR.eventX =
+                XE_KBPTR.rootX - pWin->drawable.x;
+            XE_KBPTR.eventY =
+                XE_KBPTR.rootY - pWin->drawable.y;
+        }
+        else
+        {
+            XE_KBPTR.sameScreen = xFalse;
+            XE_KBPTR.child = None;
+            XE_KBPTR.eventX = 0;
+            XE_KBPTR.eventY = 0;
+        }
     }
 }
 
commit 95ed2ab715fa881d36d508adf4ae5dadd92ae7b2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 12 11:46:07 2009 +1000

    Add XI2_EVENT check.

diff --git a/dix/events.c b/dix/events.c
index c38cc34..316703e 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -147,6 +147,7 @@ typedef const char *string;
 #endif
 
 #include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
 #include <X11/extensions/XI.h>
 #include <X11/extensions/XI2.h>
 #include "exglobals.h"
@@ -192,6 +193,10 @@ typedef const char *string;
 #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)
+
 /**
  * Used to indicate a implicit passive grab created by a ButtonPress event.
  * See DeliverEventsToWindow().
commit 92e0a324b5c738166ed4046cb00fe85ab8aea5a0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Mar 12 14:15:02 2009 +1000

    require inputproto 1.9.99.7

diff --git a/configure.ac b/configure.ac
index f4e1dbb..4725c9f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -689,7 +689,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la'
 XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
 
 dnl Core modules for most extensions, et al.
-REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.9.3] [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto [xextproto >= 7.0.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] bigreqsproto resourceproto fontsproto [inputproto >= 1.9.99.6] [kbproto >= 1.0.3]"
+REQUIRED_MODULES="[randrproto >= 1.2.99.3] [renderproto >= 0.9.3] [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto [xextproto >= 7.0.3] [xproto >= 7.0.13] [xtrans >= 1.2.2] bigreqsproto resourceproto fontsproto [inputproto >= 1.9.99.7] [kbproto >= 1.0.3]"
 REQUIRED_LIBS="xfont xau fontenc [pixman-1 >= 0.13.2]"
 
 dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
commit 906fe9547957917ac463d646935473ceca10a72b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 20 09:36:09 2009 +1000

    Xi: don't allow OpenDevice on any MD.
    
    This restores the original behaviour of XI 1. Any slave device may be opened,
    but none of the MDs.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/opendev.c b/Xi/opendev.c
index 502bdfc..833ecbb 100644
--- a/Xi/opendev.c
+++ b/Xi/opendev.c
@@ -113,14 +113,8 @@ ProcXOpenDevice(ClientPtr client)
     } else if (status != Success)
 	return status;
 
-    /* Don't let XI 1.x clients open devices other than floating SDs. */
-    pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
-    if (pXIClient->major_version < XI_2_Major)
-    {
-        if (dev->isMaster || (!dev->isMaster && dev->u.master))
+    if (dev->isMaster)
             return BadDevice;
-    }
-
 
     OpenInputDevice(dev, client, &status);
     if (status != Success)
commit c7eb27f3927ba9a36f9904938996f346cca33021
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Mar 4 18:45:09 2009 +1000

    Xi: always only list VCP/VCK and the SD's in XListInputDevices.
    
    If a client wants other MDs, it should use XI2's XQueryDevice() instead.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/listdev.c b/Xi/listdev.c
index 28554f3..925d0ec 100644
--- a/Xi/listdev.c
+++ b/Xi/listdev.c
@@ -320,7 +320,6 @@ int
 ProcXListInputDevices(ClientPtr client)
 {
     xListInputDevicesReply rep;
-    XIClientPtr pXIClient;
     int numdevs = 0;
     int namesize = 1;	/* need 1 extra byte for strcpy */
     int rc, size = 0;
@@ -340,21 +339,15 @@ ProcXListInputDevices(ClientPtr client)
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
-    pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
 
     AddOtherInputDevices();
 
     for (d = inputInfo.devices; d; d = d->next) {
-        if (pXIClient->major_version < XI_2_Major)
-        {
-            if (d->isMaster &&
+        if (d->isMaster &&
                 d != inputInfo.pointer &&
                 d != inputInfo.keyboard)
-                continue; /* don't send master devices other than VCP/VCK */
+            continue; /* don't send master devices other than VCP/VCK */
 
-            if (!d->isMaster && d->u.master)
-                continue; /* don't send attached SDs */
-        }
         rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess);
         if (rc != Success)
             return rc;
@@ -363,10 +356,10 @@ ProcXListInputDevices(ClientPtr client)
     }
 
     for (d = inputInfo.off_devices; d; d = d->next) {
-        if (pXIClient->major_version < XI_2_Major &&
-            !d->isMaster &&
-            d->u.master) /* XXX can off_devices be attached? */
-                continue; /* don't send attached SDs */
+        if (d->isMaster &&
+                d != inputInfo.pointer &&
+                d != inputInfo.keyboard)
+            continue; /* don't send master devices other than VCP/VCK */
 
         rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess);
         if (rc != Success)
@@ -384,25 +377,20 @@ ProcXListInputDevices(ClientPtr client)
     dev = (xDeviceInfoPtr) devbuf;
     for (d = inputInfo.devices; d; d = d->next)
     {
-        if (pXIClient->major_version < XI_2_Major)
-        {
-            if (d->isMaster &&
-                    d != inputInfo.pointer &&
-                    d != inputInfo.keyboard)
-                continue; /* don't count master devices other than VCP/VCK */
-
-            if (!d->isMaster && d->u.master)
-                continue; /* don't count attached SDs */
-        }
+        if (d->isMaster &&
+                d != inputInfo.pointer &&
+                d != inputInfo.keyboard)
+            continue; /* don't count master devices other than VCP/VCK */
+
         ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf);
     }
 
     for (d = inputInfo.off_devices; d; d = d->next)
     {
-        if (pXIClient->major_version < XI_2_Major &&
-                !d->isMaster &&
-                d->u.master) /* XXX can off_devices be attached? */
-            continue; /* don't send attached SDs */
+        if (d->isMaster &&
+                d != inputInfo.pointer &&
+                d != inputInfo.keyboard)
+            continue; /* don't count master devices other than VCP/VCK */
 
         ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf);
     }
commit 801f14d4b742e506201b619d472087a7e82bd018
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Mar 3 17:04:08 2009 +1000

    Xi: don't send attachment info down with ListInputDevices.

diff --git a/Xi/listdev.c b/Xi/listdev.c
index 48c1e05..28554f3 100644
--- a/Xi/listdev.c
+++ b/Xi/listdev.c
@@ -187,10 +187,6 @@ CopySwapDevice(ClientPtr client, DeviceIntPtr d, int num_classes,
         dev->use = IsXExtensionPointer;
     else
 	dev->use = IsXExtensionDevice;
-    if (!d->isMaster)
-        dev->attached = (d->u.master) ? d->u.master->id : IsFloating;
-    else
-        dev->attached = GetPairedDevice(d)->id;
 
     if (client->swapped) {
 	swapl(&dev->type, n);	/* macro - braces are required */
commit 66dd8879b3527f30309fb747cad4a161d0709d91
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 20 15:01:05 2009 +1000

    Xi: purge ExtendedGrabDevice request handling.

diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 09dd41d..7fd593c 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -27,8 +27,6 @@ libXi_la_SOURCES =	\
 	devbell.h \
 	exevents.c \
 	exglobals.h \
-        extgrbdev.c \
-        extgrbdev.h \
 	extinit.c \
 	getbmap.c \
 	getbmap.h \
diff --git a/Xi/extgrbdev.c b/Xi/extgrbdev.c
deleted file mode 100644
index da4e618..0000000
--- a/Xi/extgrbdev.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 2007-2008 Peter Hutterer
- *
- * 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.
- *
- * Author: Peter Hutterer, University of South Australia, NICTA
- */
-
-/***********************************************************************
- *
- * Request to fake data for a given device.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>	/* for inputstr.h    */
-#include <X11/Xproto.h>	/* Request macro     */
-#include "inputstr.h"	/* DeviceIntPtr      */
-#include "windowstr.h"	/* window structure  */
-#include "scrnintstr.h"	/* screen structure  */
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include <X11/extensions/Xge.h>
-#include "extnsionst.h"
-#include "exevents.h"
-#include "exglobals.h"
-
-#include "grabdev.h"    /* CreateMaskFromList */
-
-#include "extgrbdev.h"
-
-int
-SProcXExtendedGrabDevice(ClientPtr client)
-{
-    char        n;
-    int         i;
-    long*       p;
-
-    REQUEST(xExtendedGrabDeviceReq);
-    swaps(&stuff->length, n);
-    REQUEST_AT_LEAST_SIZE(xExtendedGrabDeviceReq);
-
-    swapl(&stuff->grab_window, n);
-    swapl(&stuff->time, n);
-    swapl(&stuff->confine_to, n);
-    swapl(&stuff->cursor, n);
-    swaps(&stuff->event_count, n);
-    swaps(&stuff->generic_event_count, n);
-
-    p = (long *)&stuff[1];
-    for (i = 0; i < stuff->event_count; i++) {
-	swapl(p, n);
-	p++;
-    }
-
-    for (i = 0; i < stuff->generic_event_count; i++) {
-        p++; /* first 4 bytes are extension type and padding */
-        swapl(p, n);
-        p++;
-    }
-
-    return ProcXExtendedGrabDevice(client);
-}
-
-
-int
-ProcXExtendedGrabDevice(ClientPtr client)
-{
-    return BadRequest;
-}
-
-void
-SRepXExtendedGrabDevice(ClientPtr client, int size,
-                        xExtendedGrabDeviceReply* rep)
-{
-    char n;
-    swaps(&rep->sequenceNumber, n);
-    swaps(&rep->length, n);
-    WriteToClient(client, size, (char*)rep);
-}
diff --git a/Xi/extgrbdev.h b/Xi/extgrbdev.h
deleted file mode 100644
index 6e3e371..0000000
--- a/Xi/extgrbdev.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2007-2008 Peter Hutterer
- *
- * 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.
- *
- * Author: Peter Hutterer, University of South Australia, NICTA
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef EXTGRBDEV_H
-#define EXTGRBDEV_H 1
-
-int SProcXExtendedGrabDevice(ClientPtr	/* client */
-    );
-
-int ProcXExtendedGrabDevice(ClientPtr	/* client */
-    );
-
-void SRepXExtendedGrabDevice(ClientPtr   client, 
-                            int         size, 
-                            xExtendedGrabDeviceReply* rep);
-
-#endif /* EXTGRBDEV_H */
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 6779dc1..f99b555 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -82,7 +82,6 @@ SOFTWARE.
 #include "chgprop.h"
 #include "chgptr.h"
 #include "closedev.h"
-#include "extgrbdev.h"
 #include "devbell.h"
 #include "getbmap.h"
 #include "getbmap.h"
@@ -235,8 +234,7 @@ static int (*ProcIVector[])(ClientPtr) = {
         ProcXChangeDeviceHierarchy,             /* 43 */
         ProcXSetClientPointer,                  /* 44 */
         ProcXGetClientPointer,                  /* 45 */
-        ProcXiSelectEvent,                      /* 46 */
-        ProcXExtendedGrabDevice                 /* 47 */
+        ProcXiSelectEvent                       /* 46 */
 };
 
 /* For swapped clients */
@@ -287,8 +285,7 @@ static int (*SProcIVector[])(ClientPtr) = {
         SProcXChangeDeviceHierarchy,             /* 43 */
         SProcXSetClientPointer,                  /* 44 */
         SProcXGetClientPointer,                  /* 45 */
-        SProcXiSelectEvent,                      /* 46 */
-        SProcXExtendedGrabDevice                 /* 47 */
+        SProcXiSelectEvent                       /* 46 */
 };
 
 /*****************************************************************
@@ -479,8 +476,6 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
 				(xQueryDevicePointerReply *) rep);
     else if (rep->RepType == X_GetClientPointer)
         SRepXGetClientPointer(client, len, (xGetClientPointerReply*) rep);
-    else if (rep->RepType == X_ExtendedGrabDevice)
-        SRepXExtendedGrabDevice(client, len, (xExtendedGrabDeviceReply*) rep);
     else {
 	FatalError("XINPUT confused sending swapped reply");
     }
commit 43e48900fccd245e98d6d697e4cdbb6fa866a0dd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Mar 6 22:27:54 2009 +1000

    dix: Force deviced ids of 2 and higher for actual devices.
    
    0 is now reserved for the "AllDevices" virtual device.
    1 is now reserved for the "AllMasterDevices" virtual device.
    
    This also means that wherever we passed in (mskidx = 0), we now need to pass
    in the deviceid.

diff --git a/Xi/selectev.c b/Xi/selectev.c
index b785a8e..45bf68b 100644
--- a/Xi/selectev.c
+++ b/Xi/selectev.c
@@ -58,6 +58,7 @@ SOFTWARE.
 #include "inputstr.h"	/* DeviceIntPtr      */
 #include "windowstr.h"	/* window structure  */
 #include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
 #include <X11/extensions/XIproto.h>
 #include "exevents.h"
 #include "exglobals.h"
@@ -103,10 +104,9 @@ HandleDevicePresenceMask(ClientPtr client, WindowPtr win,
     if (mask == 0)
         return Success;
 
-    /* We always only use mksidx = MAXDEVICES for events not bound to
+    /* We always only use mksidx = AllDevices for events not bound to
      * devices */
-
-    if (AddExtensionClient (win, client, mask, MAXDEVICES) != Success)
+    if (AddExtensionClient (win, client, mask, AllDevices) != Success)
         return BadAlloc;
 
     RecalculateDeviceDeliverableEvents(win);
diff --git a/Xi/setmmap.c b/Xi/setmmap.c
index 8a0ab3e..ffcc7f3 100644
--- a/Xi/setmmap.c
+++ b/Xi/setmmap.c
@@ -56,6 +56,7 @@ SOFTWARE.
 
 #include "inputstr.h"	/* DeviceIntPtr      */
 #include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
 #include <X11/extensions/XIproto.h>
 #include "exevents.h"
 #include "exglobals.h"
diff --git a/dix/devices.c b/dix/devices.c
index 3388dac..97b47bc 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -74,6 +74,7 @@ SOFTWARE.
 #include "mipointer.h"
 
 #include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
 #include <X11/extensions/XIproto.h>
 #include "exglobals.h"
 #include "exevents.h"
@@ -186,13 +187,13 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
     char devind[MAXDEVICES];
     BOOL enabled;
 
-    /* Find next available id */
+    /* Find next available id, 0 and 1 are reserved */
     memset(devind, 0, sizeof(char)*MAXDEVICES);
     for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
 	devind[devtmp->id]++;
     for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
 	devind[devtmp->id]++;
-    for (devid = 0; devid < MAXDEVICES && devind[devid]; devid++)
+    for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++)
 	;
 
     if (devid >= MAXDEVICES)
@@ -250,7 +251,7 @@ SendDevicePresenceEvent(int deviceid, int type)
     ev.time = currentTime.milliseconds;
     ev.devchange = type;
     ev.deviceid = deviceid;
-    dummyDev.id = MAXDEVICES;
+    dummyDev.id = AllDevices;
     SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
                           (xEvent*)&ev, 1);
 }
diff --git a/dix/events.c b/dix/events.c
index 0bd6a86..c38cc34 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -148,6 +148,7 @@ typedef const char *string;
 
 #include <X11/extensions/XIproto.h>
 #include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
 #include "exglobals.h"
 #include "exevents.h"
 #include "exglobals.h"
@@ -2347,6 +2348,7 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
 {
     Mask filter;
     int     deliveries;
+    DeviceIntRec dummy;
 
 #ifdef PANORAMIX
     if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
@@ -2355,27 +2357,27 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
 
     if (!count)
 	return 0;
-    /* We don't know a device here. However, this should only ever be called
-       for a non-device event so we are safe to use 0*/
-    filter = GetEventFilter(NULL, xE);
+
+    dummy.id = AllDevices;
+    filter = GetEventFilter(&dummy, xE);
     if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
 	xE->u.destroyNotify.event = pWin->drawable.id;
     if (filter != StructureAndSubMask)
-	return DeliverEventsToWindow(inputInfo.pointer, pWin, xE, count, filter, NullGrab, 0);
-    deliveries = DeliverEventsToWindow(inputInfo.pointer, pWin, xE, count, StructureNotifyMask,
-				       NullGrab, 0);
+	return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, NullGrab, dummy.id);
+    deliveries = DeliverEventsToWindow(&dummy, pWin, xE, count, StructureNotifyMask,
+				       NullGrab, dummy.id);
     if (pWin->parent)
     {
 	xE->u.destroyNotify.event = pWin->parent->drawable.id;
-	deliveries += DeliverEventsToWindow(inputInfo.pointer, pWin->parent, xE, count,
+	deliveries += DeliverEventsToWindow(&dummy, pWin->parent, xE, count,
 					    SubstructureNotifyMask, NullGrab,
-					    0);
+					    dummy.id);
 	if (xE->u.u.type == ReparentNotify)
 	{
 	    xE->u.destroyNotify.event = otherParent->drawable.id;
-            deliveries += DeliverEventsToWindow(inputInfo.pointer,
+            deliveries += DeliverEventsToWindow(&dummy,
                     otherParent, xE, count, SubstructureNotifyMask,
-						NullGrab, 0);
+						NullGrab, dummy.id);
 	}
     }
     return deliveries;
@@ -3435,7 +3437,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
         FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
         deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
                                            GetEventFilter(keybd, &core),
-                                           NullGrab, 0);
+                                           NullGrab, keybd->id);
     }
 
 unwind:
@@ -3927,7 +3929,7 @@ CoreEnterLeaveEvent(
         else
             DeliverEventsToWindow(mouse, pWin, &event, 1,
                                   GetEventFilter(mouse, &event),
-                                  NullGrab, 0);
+                                  NullGrab, mouse->id);
     }
 
     if ((type == EnterNotify) && (mask & KeymapStateMask))
@@ -3946,7 +3948,7 @@ CoreEnterLeaveEvent(
                             mask, KeymapStateMask, grab);
         else
             DeliverEventsToWindow(mouse, pWin, (xEvent *)&ke, 1,
-                                  KeymapStateMask, NullGrab, 0);
+                                  KeymapStateMask, NullGrab, mouse->id);
     }
 }
 
@@ -4028,7 +4030,7 @@ CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
     event.u.focus.window = pWin->drawable.id;
 
     DeliverEventsToWindow(dev, pWin, &event, 1,
-                          GetEventFilter(dev, &event), NullGrab, 0);
+                          GetEventFilter(dev, &event), NullGrab, dev->id);
     if ((type == FocusIn) &&
             ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
     {
@@ -4041,7 +4043,7 @@ CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
 
         ke.type = KeymapNotify;
         DeliverEventsToWindow(dev, pWin, (xEvent *)&ke, 1,
-                KeymapStateMask, NullGrab, 0);
+                KeymapStateMask, NullGrab, dev->id);
     }
 }
 
@@ -4781,8 +4783,8 @@ ProcSendEvent(ClientPtr client)
 	    if (XaceHook(XACE_SEND_ACCESS, client, NULL, pWin,
 			 &stuff->event, 1))
 		return Success;
-            if (DeliverEventsToWindow(PickPointer(client), pWin,
-                        &stuff->event, 1, stuff->eventMask, NullGrab, 0))
+            if (DeliverEventsToWindow(dev, pWin,
+                        &stuff->event, 1, stuff->eventMask, NullGrab, dev->id))
 		return Success;
 	    if (pWin == effectiveFocus)
 		return Success;
@@ -4792,8 +4794,8 @@ ProcSendEvent(ClientPtr client)
 	}
     }
     else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, &stuff->event, 1))
-        DeliverEventsToWindow(PickPointer(client), pWin, &stuff->event,
-                                    1, stuff->eventMask, NullGrab, 0);
+        DeliverEventsToWindow(dev, pWin, &stuff->event,
+                                    1, stuff->eventMask, NullGrab, dev->id);
     return Success;
 }
 
commit 70896f6127e2c12c13479a027fdd6e67853d1f8b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 13 16:42:02 2009 +1000

    dix: abstract event filters through GetEventFilters.
    
    Don't let everyone acces the filters[] array directly. This is necessary once
    we start dealing with GenericEvents, where the filters are a bit more
    complicated.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 5f8f24e..0bd6a86 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -399,6 +399,24 @@ static Mask filters[MAXDEVICES][128] = {
 	CantBeFiltered		       /* MappingNotify */
 }};
 
+/**
+ * For the given event, return the matching event filter. This filter may then
+ * be AND'ed with the selected event mask.
+ *
+ * @param[in] dev The device the event belongs to, may be NULL.
+ * @param[in] event The event to get the filter for. Only the type of the
+ *                  event matters, or the extension + evtype for GenericEvents.
+ * @return The filter mask for the given event.
+ */
+static Mask
+GetEventFilter(DeviceIntPtr dev, xEvent *event)
+{
+    if (event->u.u.type != GenericEvent)
+        return filters[dev ? dev->id : 0][event->u.u.type];
+    ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type);
+    return 0;
+}
+
 
 static CARD8 criticalEvents[32] =
 {
@@ -2176,9 +2194,11 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win,
     int filter = 0;
     int type;
     OtherInputMasks *inputMasks;
+    xEvent ev;
 
     type = GetXIType(event);
-    filter = filters[dev->id][type];
+    ev.u.u.type = type; /* GetEventFilter only cares about type */
+    filter = GetEventFilter(dev, &ev);
 
     /* Check for XI mask */
     if (type && (inputMasks = wOtherInputMasks(win)) &&
@@ -2337,7 +2357,7 @@ DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
 	return 0;
     /* We don't know a device here. However, this should only ever be called
        for a non-device event so we are safe to use 0*/
-    filter = filters[0][xE->u.u.type];
+    filter = GetEventFilter(NULL, xE);
     if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
 	xE->u.destroyNotify.event = pWin->drawable.id;
     if (filter != StructureAndSubMask)
@@ -3249,8 +3269,8 @@ CheckPassiveGrabsOnWindow(
 	    FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
 
 	    TryClientEvents(rClient(grab), device, xE, count,
-				   filters[device->id][xE->u.u.type],
-				   filters[device->id][xE->u.u.type],  grab);
+                                   GetEventFilter(device, xE),
+                                   GetEventFilter(device, xE), grab);
 
 	    if (grabinfo->sync.state == FROZEN_NO_EVENT)
 	    {
@@ -3396,7 +3416,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
     /* just deliver it to the focus window */
     FixUpEventFromWindow(ptr, xE, focus, None, FALSE);
     deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
-                                       filters[keybd->id][xE->u.u.type],
+                                       GetEventFilter(keybd, xE),
                                        NullGrab, keybd->id);
 
     if (deliveries > 0)
@@ -3414,7 +3434,7 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
 
         FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
         deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
-                                           filters[keybd->id][core.u.u.type],
+                                           GetEventFilter(keybd, &core),
                                            NullGrab, 0);
     }
 
@@ -3520,7 +3540,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
             {
                 deliveries = TryClientEvents(rClient(grab), thisDev,
                         &core, 1, mask,
-                        filters[thisDev->id][core.u.u.type],
+                        GetEventFilter(thisDev, &core),
                         grab);
             }
         }
@@ -3545,7 +3565,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
                     TryClientEvents(rClient(grab), thisDev,
                             xi, count,
                             mask,
-                            filters[thisDev->id][xi->u.u.type],
+                            GetEventFilter(thisDev, xi),
                             grab);
             }
 
@@ -3899,14 +3919,15 @@ CoreEnterLeaveEvent(
              IsParent(focus, pWin)))
         event.u.enterLeave.flags |= ELFlagFocus;
 
-    if ((mask & filters[mouse->id][type]))
+    if ((mask & GetEventFilter(mouse, &event)))
     {
         if (grab)
             TryClientEvents(rClient(grab), mouse, &event, 1, mask,
-                                  filters[mouse->id][type], grab);
+                            GetEventFilter(mouse, &event), grab);
         else
             DeliverEventsToWindow(mouse, pWin, &event, 1,
-                                  filters[mouse->id][type], NullGrab, 0);
+                                  GetEventFilter(mouse, &event),
+                                  NullGrab, 0);
     }
 
     if ((type == EnterNotify) && (mask & KeymapStateMask))
@@ -3979,16 +4000,17 @@ DeviceEnterLeaveEvent(
     mskidx = mouse->id;
     inputMasks = wOtherInputMasks(pWin);
     if (inputMasks &&
-       (filters[mouse->id][devEnterLeave->type] &
+       (GetEventFilter(mouse, (xEvent*)devEnterLeave) &
             inputMasks->deliverableEvents[mskidx]))
     {
         if (grab)
             TryClientEvents(rClient(grab), mouse,
                             (xEvent*)devEnterLeave, 1, mask,
-                            filters[mouse->id][devEnterLeave->type], grab);
+                            GetEventFilter(mouse, (xEvent*)devEnterLeave),
+                            grab);
         else
             DeliverEventsToWindow(mouse, pWin, (xEvent*)devEnterLeave, 1,
-                                  filters[mouse->id][devEnterLeave->type],
+                                  GetEventFilter(mouse, (xEvent*)devEnterLeave),
                                   NullGrab, mouse->id);
     }
 
@@ -4004,8 +4026,9 @@ CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
     event.u.u.type = type;
     event.u.u.detail = detail;
     event.u.focus.window = pWin->drawable.id;
-    (void)DeliverEventsToWindow(dev, pWin, &event, 1,
-            filters[dev->id][type], NullGrab, 0);
+
+    DeliverEventsToWindow(dev, pWin, &event, 1,
+                          GetEventFilter(dev, &event), NullGrab, 0);
     if ((type == FocusIn) &&
             ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
     {
@@ -5492,3 +5515,4 @@ IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event)
 
     return FALSE;
 }
+
commit 8a8763f1502c9ddd1961f96f2cc7c73fbc0b49b5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 12 16:07:15 2009 +1000

    dix: restructure DeliverEventsToWindow, a little bit anyway.
    
    Desperate attempt of making the code easy to read and understand. A failed
    desparate attempt, possibly.

diff --git a/dix/events.c b/dix/events.c
index 9a19335..5f8f24e 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -187,6 +187,10 @@ typedef const char *string;
 #define LastEventMask OwnerGrabButtonMask
 #define AllEventMasks (LastEventMask|(LastEventMask-1))
 
+
+#define CORE_EVENT(event) \
+    (!((event)->u.u.type & EXTENSION_EVENT_BASE) && \
+      (event)->u.u.type != GenericEvent)
 /**
  * Used to indicate a implicit passive grab created by a ButtonPress event.
  * See DeliverEventsToWindow().
@@ -1888,17 +1892,16 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
 		              this mask is the mask of the grab. */
     int type = pEvents->u.u.type;
 
-    /* CantBeFiltered means only window owner gets the event */
-    if ((filter == CantBeFiltered) ||
-            (!(type & EXTENSION_EVENT_BASE) && type != GenericEvent))
+
+    /* 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;
 
-        if (!(type & EXTENSION_EVENT_BASE) &&
-            IsInterferingGrab(wClient(pWin), pDev, pEvents))
+        if (IsInterferingGrab(wClient(pWin), pDev, pEvents))
                 return 0;
 
 	if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
@@ -1916,44 +1919,44 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
 		nondeliveries--;
 	}
     }
+
+    /* CantBeFiltered means only window owner gets the event */
     if (filter != CantBeFiltered)
     {
-            if (type & EXTENSION_EVENT_BASE)
-            {
-                OtherInputMasks *inputMasks;
+        if (CORE_EVENT(pEvents))
+            other = (InputClients *)wOtherClients(pWin);
+        else {
+            OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
+            /* Has any client selected for the event? */
+            if (!inputMasks ||
+                !(inputMasks->inputEvents[mskidx] & filter))
+                return 0;
 
-                inputMasks = wOtherInputMasks(pWin);
-                if (!inputMasks ||
-                        !(inputMasks->inputEvents[mskidx] & filter))
-                    return 0;
-                other = inputMasks->inputClients;
-            }
-            else
-                other = (InputClients *)wOtherClients(pWin);
-            for (; other; other = other->next)
-            {
-                /* core event? check for grab interference */
-                if (!(type & EXTENSION_EVENT_BASE) &&
-                        IsInterferingGrab(rClient(other), pDev, pEvents))
-                    continue;
+            other = inputMasks->inputClients;
+        }
 
-                if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
-                             pEvents, count))
-                    /* do nothing */;
-                else if ( (attempt = TryClientEvents(rClient(other), pDev,
-                                                     pEvents, count,
-                                                     other->mask[mskidx],
-                                                     filter, grab)) )
+        for (; other; other = other->next)
+        {
+            if (IsInterferingGrab(rClient(other), pDev, pEvents))
+                continue;
+
+            if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
+                        pEvents, count))
+                /* do nothing */;
+            else if ( (attempt = TryClientEvents(rClient(other), pDev,
+                            pEvents, count,
+                            other->mask[mskidx],
+                            filter, grab)) )
+            {
+                if (attempt > 0)
                 {
-                    if (attempt > 0)
-                    {
-                        deliveries++;
-                        client = rClient(other);
-                        deliveryMask = other->mask[mskidx];
-                    } else
-                        nondeliveries--;
-                }
+                    deliveries++;
+                    client = rClient(other);
+                    deliveryMask = other->mask[mskidx];
+                } else
+                    nondeliveries--;
             }
+        }
     }
     /*
      * Note that since core events are delivered first, an implicit grab may
@@ -5455,9 +5458,6 @@ IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event)
 {
     DeviceIntPtr it = inputInfo.devices;
 
-    if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client))
-        return FALSE;
-
     switch(event->u.u.type)
     {
         case KeyPress:
@@ -5472,6 +5472,9 @@ IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event)
             return FALSE;
     }
 
+    if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client))
+        return FALSE;
+
     while(it)
     {
         if (it != dev)
commit 891cfc802028c3e008ee6c2d3e2438a31f57f39f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Feb 12 10:12:45 2009 +1000

    dix: clean up DeliverDeviceEvents.
    
    Move mask checking into external function and streamline the code.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 2969adb..9a19335 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2143,6 +2143,66 @@ FixUpEventFromWindow(
 }
 
 /**
+ * Return masks for EventIsDeliverable.
+ * @defgroup EventIsDeliverable return flags
+ * @{
+ */
+#define XI_MASK                 (1 << 0) /**< XI mask set on window */
+#define CORE_MASK               (1 << 1) /**< Core mask set on window */
+#define DONT_PROPAGATE_MASK     (1 << 2) /**< DontPropagate mask set on window */
+/* @} */
+
+/**
+ * Check if a given event is deliverable at all on a given window.
+ *
+ * This function only checks if any client wants it, not for a specific
+ * client.
+ *
+ * @param[in] dev The device this event is being sent for.
+ * @param[in] event The event that is to be sent.
+ * @param[in] win The current event window.
+ * @param[out] filter_out The event filter for this event.
+ *
+ * @return Bitmask of ::XI_MASK, ::CORE_MASK, and ::DONT_PROPAGATE_MASK.
+ */
+static int
+EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win,
+                   Mask *filter_out)
+{
+    int rc = 0;
+    int filter = 0;
+    int type;
+    OtherInputMasks *inputMasks;
+
+    type = GetXIType(event);
+    filter = filters[dev->id][type];
+
+    /* Check for XI mask */
+    if (type && (inputMasks = wOtherInputMasks(win)) &&
+        (inputMasks->deliverableEvents[dev->id] & filter) &&
+        (inputMasks->inputEvents[dev->id] & filter))
+        rc |= XI_MASK;
+
+    /* Check for XI DontPropagate mask */
+    if (type && inputMasks &&
+        (inputMasks->dontPropagateMask[dev->id] & filter))
+        rc |= DONT_PROPAGATE_MASK;
+
+    /* Check for core mask */
+    type = GetCoreType(event);
+    if (type && (win->deliverableEvents & filter) &&
+        ((wOtherEventMasks(win) | win->eventMask) & filter))
+        rc |= CORE_MASK;
+
+    /* Check for core DontPropagate mask */
+    if (type && (filter & wDontPropagateMask(win)))
+        rc |= DONT_PROPAGATE_MASK;
+
+    *filter_out = filter;
+    return rc;
+}
+
+/**
  * Deliver events caused by input devices.
  *
  * For events from a non-grabbed, non-focus device, DeliverDeviceEvents is
@@ -2166,14 +2226,11 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                     WindowPtr stopAt, DeviceIntPtr dev)
 {
     Window child = None;
-    int type;
     Mask filter;
     int deliveries = 0;
-    OtherInputMasks *inputMasks;
-    int mskidx = dev->id;
     xEvent core;
     xEvent *xE = NULL;
-    int rc, count = 0;
+    int rc, mask, count = 0;
 
     CHECKEVENT(event);
 
@@ -2194,59 +2251,41 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
     if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count))
 	goto unwind;
 
-    type = xE->u.u.type;
-    filter = filters[dev->id][type];
-
-    while (pWin && type != GenericEvent)
+    while (pWin)
     {
-        /* First try XI event delivery */
-        inputMasks = wOtherInputMasks(pWin);
-        if (inputMasks && (filter & inputMasks->deliverableEvents[mskidx]))
+        if ((mask = EventIsDeliverable(dev, event, pWin, &filter)))
         {
-
-            if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
+            /* XI events first */
+            if (mask & XI_MASK)
             {
                 FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
                 deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
-                                                   filter, grab, mskidx);
+                                                   filter, grab, dev->id);
                 if (deliveries > 0)
                     goto unwind;
             }
-        }
 
-        if ((deliveries < 0) || (pWin == stopAt) ||
-            (inputMasks && (filter & inputMasks->dontPropagateMask[mskidx])))
-        {
-            deliveries = 0;
-            goto unwind;
-        }
-
-        if (dev->isMaster && dev->coreEvents)
-        {
-            /* no XI event delivered. Try core event */
-            rc = EventToCore(event, &core);
-            if (rc != Success)
+            /* Core event */
+            if ((mask & CORE_MASK) && dev->isMaster && dev->coreEvents)
             {
-                if (rc != BadMatch)
-                    ErrorF("[dix] %s: Core conversion failed in DDE (%d, %d).\n",
-                            dev->name, event->u.any.type, rc);
-                goto unwind;
-            }
-
-            if (filter & pWin->deliverableEvents)
-            {
-                if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
+                rc = EventToCore(event, &core);
+                if (rc != Success)
                 {
-                    FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
-                    deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
-                            filter, grab, 0);
-                    if (deliveries > 0)
-                        goto unwind;
+                    if (rc != BadMatch)
+                        ErrorF("[dix] %s: Core conversion failed in DDE (%d, %d).\n",
+                                dev->name, event->u.any.type, rc);
+                    goto unwind;
                 }
+
+                FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
+                deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
+                                                   filter, grab, dev->id);
+                if (deliveries > 0)
+                    goto unwind;
             }
 
             if ((deliveries < 0) || (pWin == stopAt) ||
-                (filter & wDontPropagateMask(pWin)))
+                (mask & DONT_PROPAGATE_MASK))
             {
                 deliveries = 0;
                 goto unwind;
@@ -2262,6 +2301,10 @@ unwind:
     return deliveries;
 }
 
+#undef XI_MASK
+#undef CORE_MASK
+#undef DONT_PROPAGATE_MASK
+
 /**
  * Deliver event to a window and it's immediate parent. Used for most window
  * events (CreateNotify, ConfigureNotify, etc.). Not useful for events that
commit 6b6b660c3633af75a94302725137549df0dbe446
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Mar 10 10:15:45 2009 +1000

    Xext: remove ev_fill from GEExtensions.

diff --git a/Xext/geext.c b/Xext/geext.c
index be2bac3..1ddcbb1 100644
--- a/Xext/geext.c
+++ b/Xext/geext.c
@@ -261,16 +261,13 @@ GEExtensionInit(void)
  */
 void
 GERegisterExtension(int extension,
-                    void (*ev_swap)(xGenericEvent* from, xGenericEvent* to),
-                    void (*ev_fill)(xGenericEvent* ev, DeviceIntPtr pDev,
-                                    WindowPtr pWin, GrabPtr pGrab))
+                    void (*ev_swap)(xGenericEvent* from, xGenericEvent* to))
 {
     if ((extension & 0x7F) >=  MAXEXTENSIONS)
         FatalError("GE: extension > MAXEXTENSIONS. This should not happen.\n");
 
     /* extension opcodes are > 128, might as well save some space here */
     GEExtensions[extension & 0x7f].evswap = ev_swap;
-    GEExtensions[extension & 0x7f].evfill = ev_fill;
 }
 
 
diff --git a/Xext/geext.h b/Xext/geext.h
index fbf29cc..8e6dbeb 100644
--- a/Xext/geext.h
+++ b/Xext/geext.h
@@ -34,18 +34,10 @@ from the author.
 #define _GEEXT_H_
 #include <X11/extensions/geproto.h>
 
-/* Struct to keep information about registered extensions
- *
- * evswap ... use to swap event fields for different byte ordered clients.
- * evfill ... use to fill various event fields from the given parameters.
- */
+/** Struct to keep information about registered extensions */
 typedef struct _GEExtension {
+    /** Event swapping routine */
     void (*evswap)(xGenericEvent* from, xGenericEvent* to);
-    void (*evfill)(xGenericEvent* ev,
-                    DeviceIntPtr pDev,  /* device */
-                    WindowPtr pWin,     /* event window */
-                    GrabPtr pGrab       /* current grab, may be NULL */
-                    );
 } GEExtension, *GEExtensionPtr;
 
 
@@ -82,10 +74,7 @@ extern _X_EXPORT GEExtension GEExtensions[MAXEXTENSIONS];
 /* Interface for other extensions */
 extern _X_EXPORT void GERegisterExtension(
         int extension,
-        void (*ev_dispatch)(xGenericEvent* from, xGenericEvent* to),
-        void (*ev_fill)(xGenericEvent* ev, DeviceIntPtr pDev,
-                        WindowPtr pWin, GrabPtr pGrab)
-        );
+        void (*ev_dispatch)(xGenericEvent* from, xGenericEvent* to));
 
 extern _X_EXPORT void GEInitEvent(xGenericEvent* ev, int extension);
 
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 4d35c48..6779dc1 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -1083,7 +1083,7 @@ XInputExtensionInit(void)
 	EventSwapVector[DeviceEnterNotify] = SEventIDispatch;
 	EventSwapVector[DeviceLeaveNotify] = SEventIDispatch;
 
-	GERegisterExtension(IReqCode, XI2EventSwap, NULL);
+	GERegisterExtension(IReqCode, XI2EventSwap);
     } else {
 	FatalError("IExtensionInit: AddExtensions failed\n");
     }
commit 445daa62e720fe58fa2d6c3cdc26663671b2bc48
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 15 17:16:22 2009 +1000

    Xext: purge XGE event masks.
    
    The masks were originally designed to generically handle event masks for
    extensions. Since all that is in-server anyway, it's much better writing
    custom event masks for those extensions that need it and not providing a
    unified mechanism.
    XI2 needs more than the current implementation, which is already too complex
    for most other extensions. good riddance.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/geext.c b/Xext/geext.c
index a58db03..be2bac3 100644
--- a/Xext/geext.c
+++ b/Xext/geext.c
@@ -58,7 +58,6 @@ static const int version_requests[] = {
 
 /* Forward declarations */
 static void SGEGenericEvent(xEvent* from, xEvent* to);
-static void GERecalculateWinMask(WindowPtr pWin);
 
 #define NUM_VERSION_REQUESTS	(sizeof (version_requests) / sizeof (version_requests[0]))
 
@@ -217,43 +216,6 @@ SGEGenericEvent(xEvent* from, xEvent* to)
         GEExtensions[gefrom->extension & 0x7F].evswap(gefrom, geto);
 }
 
-/**
- * Resource callback, invoked when the client disconnects and the associated
- * GE masks must be destroyed.
- */
-static int
-GEClientGone(WindowPtr pWin, XID id)
-{
-    GenericClientMasksPtr gclmask;
-    GenericMaskPtr        gmask, prev = NULL;
-
-    if (!pWin || !pWin->optional)
-        return Success;
-
-    gclmask = pWin->optional->geMasks;
-    for (gmask = gclmask->geClients; gmask; gmask = gmask->next)
-    {
-        if (gmask->resource == id)
-        {
-            if (prev)
-            {
-                prev->next = gmask->next;
-                xfree(gmask);
-            } else {
-                gclmask->geClients = NULL;
-                CheckWindowOptionalNeed(pWin);
-                GERecalculateWinMask(pWin);
-                xfree(gmask);
-            }
-            return Success;
-        }
-        prev = gmask;
-    }
-
-    FatalError("Client not a GE client");
-    return BadImplementation;
-}
-
 /* Init extension, register at server.
  * Since other extensions may rely on XGE (XInput does already), it is a good
  * idea to init XGE first, before any other extension.
@@ -277,9 +239,6 @@ GEExtensionInit(void)
         GEErrorBase = extEntry->errorBase;
         GEEventType = GEEventBase;
 
-        RT_GECLIENT = CreateNewResourceType((DeleteType)GEClientGone);
-        RegisterResourceName(RT_GECLIENT, "GECLIENT");
-
         memset(GEExtensions, 0, sizeof(GEExtensions));
 
         EventSwapVector[GenericEvent] = (EventSwapPtr) SGEGenericEvent;
@@ -326,149 +285,3 @@ GEInitEvent(xGenericEvent* ev, int extension)
     ev->length = 0;
 }
 
-/* Recalculates the summary mask for the window. */
-static void
-GERecalculateWinMask(WindowPtr pWin)
-{
-    int i;
-    GenericMaskPtr it;
-    GenericClientMasksPtr evmasks;
-
-    if (!pWin->optional)
-        return;
-
-    evmasks = pWin->optional->geMasks;
-
-    for (i = 0; i < MAXEXTENSIONS; i++)
-    {
-        evmasks->eventMasks[i] = 0;
-    }
-
-    it = pWin->optional->geMasks->geClients;
-    while(it)
-    {
-        for (i = 0; i < MAXEXTENSIONS; i++)
-        {
-            evmasks->eventMasks[i] |= it->eventMask[i];
-        }
-        it = it->next;
-    }
-}
-
-/* Set generic event mask for given window. */
-void
-GEWindowSetMask(ClientPtr pClient, DeviceIntPtr pDev,
-                WindowPtr pWin, int extension, Mask mask)
-{
-    GenericMaskPtr cli;
-
-    extension = (extension & 0x7F);
-
-    if (extension > MAXEXTENSIONS)
-    {
-        ErrorF("Invalid extension number.\n");
-        return;
-    }
-
-    if (!pWin->optional && !MakeWindowOptional(pWin))
-    {
-        ErrorF("GE: Could not make window optional.\n");
-        return;
-    }
-
-    if (mask)
-    {
-        GenericClientMasksPtr evmasks = pWin->optional->geMasks;
-
-        /* check for existing client */
-        cli = evmasks->geClients;
-        while(cli)
-        {
-            if (rClient(cli) == pClient && cli->dev == pDev)
-                break;
-            cli = cli->next;
-        }
-        if (!cli)
-        {
-            /* new client and/or new device */
-            cli  = (GenericMaskPtr)xcalloc(1, sizeof(GenericMaskRec));
-            if (!cli)
-            {
-                ErrorF("GE: Insufficient memory to alloc client.\n");
-                return;
-            }
-            cli->next = evmasks->geClients;
-            cli->resource = FakeClientID(pClient->index);
-            cli->dev = pDev;
-            evmasks->geClients = cli;
-            AddResource(cli->resource, RT_GECLIENT, (pointer)pWin);
-        }
-        cli->eventMask[extension] = mask;
-    } else
-    {
-        /* remove client. */
-        cli = pWin->optional->geMasks->geClients;
-        if (rClient(cli) == pClient && cli->dev == pDev)
-        {
-            pWin->optional->geMasks->geClients = cli->next;
-            xfree(cli);
-        } else
-        {
-            GenericMaskPtr prev = cli;
-            cli = cli->next;
-
-            while(cli)
-            {
-                if (rClient(cli) == pClient && cli->dev == pDev)
-                {
-                    prev->next = cli->next;
-                    xfree(cli);
-                    break;
-                }
-                prev = cli;
-                cli = cli->next;
-            }
-        }
-        if (!cli)
-            return;
-    }
-
-    GERecalculateWinMask(pWin);
-}
-
-/**
- * Return TRUE if the mask for the given device is set.
- * @param pWin Window the event may be delivered to.
- * @param pDev Device the device originating the event. May be NULL.
- * @param extension Extension ID
- * @param mask Event mask
- */
-BOOL
-GEDeviceMaskIsSet(WindowPtr pWin, DeviceIntPtr pDev,
-                  int extension, Mask mask)
-{
-    GenericMaskPtr gemask;
-
-    if (!pWin->optional || !pWin->optional->geMasks)
-        return FALSE;
-
-    extension &= 0x7F;
-
-    if (!pWin->optional->geMasks->eventMasks[extension] & mask)
-        return FALSE;
-
-
-    gemask = pWin->optional->geMasks->geClients;
-
-    while(gemask)
-    {
-        if ((!gemask->dev || gemask->dev == pDev) &&
-                (gemask->eventMask[extension] & mask))
-            return TRUE;
-
-        gemask = gemask->next;
-    }
-
-    return FALSE;
-}
-
diff --git a/Xext/geext.h b/Xext/geext.h
index e37d507..fbf29cc 100644
--- a/Xext/geext.h
+++ b/Xext/geext.h
@@ -34,22 +34,6 @@ from the author.
 #define _GEEXT_H_
 #include <X11/extensions/geproto.h>
 
-
-/**
- * This struct is used both in the window and by grabs to determine the event
- * mask for a client.
- * A window will have a linked list of these structs, with one entry per
- * client per device, null-terminated.
- * A grab has only one instance of this struct.
- */
-typedef struct _GenericMaskRec {
-    struct _GenericMaskRec* next;
-    XID             resource;                 /* id for the resource manager */
-    DeviceIntPtr    dev;
-    Mask            eventMask[MAXEXTENSIONS]; /* one mask per extension */
-} GenericMaskRec, *GenericMaskPtr;
-
-
 /* Struct to keep information about registered extensions
  *
  * evswap ... use to swap event fields for different byte ordered clients.
@@ -96,9 +80,6 @@ extern _X_EXPORT GEExtension GEExtensions[MAXEXTENSIONS];
 
 
 /* Interface for other extensions */
-extern _X_EXPORT void GEWindowSetMask(ClientPtr pClient, DeviceIntPtr pDev,
-                     WindowPtr pWin, int extension, Mask mask);
-
 extern _X_EXPORT void GERegisterExtension(
         int extension,
         void (*ev_dispatch)(xGenericEvent* from, xGenericEvent* to),
@@ -107,8 +88,6 @@ extern _X_EXPORT void GERegisterExtension(
         );
 
 extern _X_EXPORT void GEInitEvent(xGenericEvent* ev, int extension);
-extern _X_EXPORT BOOL GEDeviceMaskIsSet(WindowPtr pWin, DeviceIntPtr pDev,
-                       int extension, Mask mask);
 
 extern _X_EXPORT void GEExtensionInit(void);
 
diff --git a/Xi/exevents.c b/Xi/exevents.c
index 89adf4f..8851487 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1787,7 +1787,6 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
 	tempGrab.pointerMode = GrabModeAsync;
 	tempGrab.confineTo = NullWindow;
 	tempGrab.cursor = NullCursor;
-        tempGrab.genericMasks = NULL;
         tempGrab.next = NULL;
 	(*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE);
     }
diff --git a/Xi/extgrbdev.c b/Xi/extgrbdev.c
index af87063..da4e618 100644
--- a/Xi/extgrbdev.c
+++ b/Xi/extgrbdev.c
@@ -86,121 +86,7 @@ SProcXExtendedGrabDevice(ClientPtr client)
 int
 ProcXExtendedGrabDevice(ClientPtr client)
 {
-    xExtendedGrabDeviceReply rep;
-    DeviceIntPtr             dev;
-    int                      rc = Success,
-                             errval = 0,
-                             i;
-    WindowPtr                grab_window,
-                             confineTo = 0;
-    CursorPtr                cursor = NULL;
-    struct tmask             tmp[EMASKSIZE];
-    TimeStamp                time;
-    XGenericEventMask*       xgeMask;
-    GenericMaskPtr           gemasks = NULL;
-
-    REQUEST(xExtendedGrabDeviceReq);
-    REQUEST_AT_LEAST_SIZE(xExtendedGrabDeviceReq);
-
-    rep.repType         = X_Reply;
-    rep.RepType         = X_ExtendedGrabDevice;
-    rep.sequenceNumber  = client->sequence;
-    rep.length          = 0;
-
-    if (stuff->length != (sizeof(xExtendedGrabDeviceReq) >> 2) +
-            stuff->event_count + 2 * stuff->generic_event_count)
-    {
-        errval = 0;
-        rc = BadLength;
-        goto cleanup;
-    }
-
-    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
-    if (rc != Success) {
-	goto cleanup;
-    }
-
-    rc = dixLookupWindow(&grab_window,
-                          stuff->grab_window,
-                          client,
-                          DixReadAccess);
-    if (rc != Success)
-    {
-        errval = stuff->grab_window;
-        goto cleanup;
-    }
-
-    if (stuff->confine_to)
-    {
-        rc = dixLookupWindow(&confineTo,
-                              stuff->confine_to,
-                              client,
-                              DixReadAccess);
-        if (rc != Success)
-        {
-            errval = stuff->confine_to;
-            goto cleanup;
-        }
-    }
-
-    if (stuff->cursor)
-    {
-        cursor = (CursorPtr)SecurityLookupIDByType(client,
-                                                    stuff->cursor,
-                                                    RT_CURSOR,
-                                                    DixReadAccess);
-        if (!cursor)
-        {
-            errval = stuff->cursor;
-            rc = BadCursor;
-            goto cleanup;
-        }
-    }
-
-    if (CreateMaskFromList(client,
-                           (XEventClass*)&stuff[1],
-                           stuff->event_count,
-                           tmp,
-                           dev,
-                           X_GrabDevice) != Success)
-        return Success;
-
-    time = ClientTimeToServerTime(stuff->time);
-
-    if (stuff->generic_event_count)
-    {
-        xgeMask =
-            (XGenericEventMask*)(((XEventClass*)&stuff[1]) + stuff->event_count);
-
-        gemasks = xcalloc(1, sizeof(GenericMaskRec));
-        gemasks->resource = FakeClientID(client->index);
-        gemasks->next = NULL;
-        gemasks->eventMask[xgeMask->extension & 0x7F] = xgeMask->evmask;
-
-        xgeMask++;
-        for (i = 1; i < stuff->generic_event_count; i++, xgeMask++)
-            gemasks->eventMask[xgeMask->extension & 0x7F]= xgeMask->evmask;
-    }
-
-    rep.status = ExtGrabDevice(client, dev, stuff->device_mode,
-                               grab_window, confineTo, time,
-                               stuff->owner_events, cursor,
-                               tmp[stuff->deviceid].mask,
-                               gemasks);
-cleanup:
-
-    if (gemasks)
-        xfree(gemasks);
-
-    if (rc == Success)
-    {
-        WriteReplyToClient(client, sizeof(xGrabDeviceReply), &rep);
-    }
-    else
-    {
-        return rc;
-    }
-    return Success;
+    return BadRequest;
 }
 
 void
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 9a20bfd..4d35c48 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -154,16 +154,6 @@ const Mask XIAllMasks                     = (1L << 21) - 1;
 int ExtEventIndex;
 Mask ExtExclusiveMasks[EMASKSIZE];
 
-
-/**
- * Filters for various generic events.
- * Evtype is index, mask is value at index.
- */
-static Mask xi_filters[] = {
-    XI_DeviceHierarchyChangedMask,
-    XI_DeviceClassesChangedMask,
-};
-
 static struct dev_type
 {
     Atom type;
@@ -671,6 +661,12 @@ SDeviceClassesChangedEvent(deviceClassesChangedEvent* from,
     }
 }
 
+/** Event swapping function for XI2 events. */
+static void
+XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
+{
+}
+
 /**************************************************************************
  *
  * Allow the specified event to have its propagation suppressed.
@@ -1034,36 +1030,6 @@ SEventIDispatch(xEvent * from, xEvent * to)
     }
 }
 
-/****************************************************************
- *
- * EventSwap for generic events coming from the GE extension.
- */
-
-static void
-XIGEEventSwap(xGenericEvent* from, xGenericEvent* to)
-{
-    int n;
-
-    swaps(&from->sequenceNumber, n);
-    switch(from->evtype)
-    {
-        case XI_DeviceClassesChangedNotify:
-            SDeviceClassesChangedEvent((deviceClassesChangedEvent*)from,
-                                       (deviceClassesChangedEvent*)to);
-            break;
-    }
-}
-
-/**
- * EventFill to fill various fields for events before they are delivered to
- * the client.
- */
-static void
-XIGEEventFill(xGenericEvent* ev, DeviceIntPtr pDev,
-              WindowPtr pWin, GrabPtr grab)
-{
-}
-
 /**********************************************************************
  *
  * IExtensionInit - initialize the input extension.
@@ -1117,10 +1083,9 @@ XInputExtensionInit(void)
 	EventSwapVector[DeviceEnterNotify] = SEventIDispatch;
 	EventSwapVector[DeviceLeaveNotify] = SEventIDispatch;
 
-        /* init GE events */
-        GERegisterExtension(IReqCode, XIGEEventSwap, XIGEEventFill);
-        SetGenericFilter(IReqCode, xi_filters);
+	GERegisterExtension(IReqCode, XI2EventSwap, NULL);
     } else {
 	FatalError("IExtensionInit: AddExtensions failed\n");
     }
 }
+
diff --git a/Xi/xiselev.c b/Xi/xiselev.c
index 0431939..229f2d1 100644
--- a/Xi/xiselev.c
+++ b/Xi/xiselev.c
@@ -72,7 +72,7 @@ ProcXiSelectEvent(ClientPtr client)
             return rc;
     }
 
-    GEWindowSetMask(client, pDev, pWin, IReqCode, stuff->mask);
+    /* XXX: THIS FUNCTION IS NOW DYSFUNCTIONAL */
 
     return Success;
 }
diff --git a/dix/events.c b/dix/events.c
index c21e57e..2969adb 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -396,13 +396,6 @@ static Mask filters[MAXDEVICES][128] = {
 }};
 
 
-/**
- * same principle as filters, but one set of filters for each extension.
- * The extension is responsible for setting the filters by calling
- * SetGenericFilter().
- */
-static Mask* generic_filters[MAXEXTENSIONS];
-
 static CARD8 criticalEvents[32] =
 {
     0x7c, 0x30, 0x40			/* key, button, expose, and configure events */
@@ -1466,13 +1459,6 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
     mouse->deviceGrab.sync.state = NOT_GRABBED;
     mouse->deviceGrab.fromPassiveGrab = FALSE;
 
-    /* make sure the potential XGE event mask is freed too*/
-    if (grab->genericMasks)
-    {
-        xfree(grab->genericMasks);
-        grab->genericMasks = NULL;
-    }
-
     for (dev = inputInfo.devices; dev; dev = dev->next)
     {
 	if (dev->deviceGrab.sync.other == grab)
@@ -1550,11 +1536,6 @@ DeactivateKeyboardGrab(DeviceIntPtr keybd)
     keybd->deviceGrab.grab = NullGrab;
     keybd->deviceGrab.sync.state = NOT_GRABBED;
     keybd->deviceGrab.fromPassiveGrab = FALSE;
-    if (grab->genericMasks)
-    {
-        xfree(grab->genericMasks);
-        grab->genericMasks = NULL;
-    }
 
     for (dev = inputInfo.devices; dev; dev = dev->next)
     {
@@ -1937,43 +1918,6 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
     }
     if (filter != CantBeFiltered)
     {
-        /* Handle generic events */
-        if (type == GenericEvent)
-        {
-            GenericMaskPtr gmask;
-            /* We don't do more than one GenericEvent at a time. */
-            if (count > 1)
-            {
-                ErrorF("[dix] Do not send more than one GenericEvent at a time!\n");
-                return 0;
-            }
-
-            /* if we get here, filter should be set to the GE specific mask.
-               check if any client wants it */
-            if (!GEDeviceMaskIsSet(pWin, pDev, GEEXT(pEvents), filter))
-                return 0;
-
-            /* run through all clients, deliver event */
-            for (gmask = GECLIENT(pWin); gmask; gmask = gmask->next)
-            {
-                if (gmask->eventMask[GEEXTIDX(pEvents)] & filter)
-                {
-                    if (XaceHook(XACE_RECEIVE_ACCESS, rClient(gmask), pWin,
-                                pEvents, count))
-                        /* do nothing */;
-                    else if (TryClientEvents(rClient(gmask), pDev,
-                             pEvents, count,
-                             gmask->eventMask[GEEXTIDX(pEvents)],
-                             filter, grab) > 0)
-                    {
-                        deliveries++;
-                    } else
-                        nondeliveries--;
-                }
-            }
-        }
-        else {
-            /* Traditional event */
             if (type & EXTENSION_EVENT_BASE)
             {
                 OtherInputMasks *inputMasks;
@@ -2010,7 +1954,6 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
                         nondeliveries--;
                 }
             }
-        }
     }
     /*
      * Note that since core events are delivered first, an implicit grab may
@@ -2039,21 +1982,6 @@ DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
         inputMasks = wOtherInputMasks(pWin);
         tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0;
 
-        /* get the XGE event mask. */
-        tempGrab.genericMasks = NULL;
-        if (pWin->optional && pWin->optional->geMasks)
-        {
-            GenericClientMasksPtr gemasks = pWin->optional->geMasks;
-            GenericMaskPtr geclient = gemasks->geClients;
-            while(geclient && rClient(geclient) != client)
-                geclient = geclient->next;
-            if (geclient)
-            {
-                tempGrab.genericMasks = xcalloc(1, sizeof(GenericMaskRec));
-                *tempGrab.genericMasks = *geclient;
-                tempGrab.genericMasks->next = NULL;
-            }
-        }
 	(*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab,
                                         currentTime, TRUE | ImplicitGrabMask);
     }
@@ -2269,39 +2197,6 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
     type = xE->u.u.type;
     filter = filters[dev->id][type];
 
-    /* handle generic events */
-    /* XXX: Generic events aren't quite handled correctly yet. They should
-     * eventually fit in with the rest of the stuff
-     */
-    if (type == GenericEvent)
-    {
-        WindowPtr win = pWin;
-        xGenericEvent* ge = (xGenericEvent*)xE;
-
-        if (count > 1)
-        {
-            ErrorF("[dix] Do not send more than one GenericEvent at a time!\n");
-            deliveries = 0;
-            goto unwind;
-        }
-        filter = generic_filters[GEEXTIDX(xE)][ge->evtype];
-
-        while(win)
-        {
-            if (GEDeviceMaskIsSet(win, dev, GEEXT(xE), filter))
-            {
-                if (GEExtensions[GEEXTIDX(xE)].evfill)
-                    GEExtensions[GEEXTIDX(xE)].evfill(ge, dev, win, grab);
-                deliveries = DeliverEventsToWindow(dev, win, xE, count,
-                        filter, grab, 0);
-                if (deliveries > 0)
-                    goto unwind;
-            }
-
-            win = win->parent;
-        }
-    }
-
     while (pWin && type != GenericEvent)
     {
         /* First try XI event delivery */
@@ -3537,6 +3432,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
     }
     if (!deliveries)
     {
+        Mask mask;
         /* XXX: In theory, we could pass the internal events through to
          * everything and only convert just before hitting the wire. We can't
          * do that yet, so DGE is the last stop for internal events. From here
@@ -3552,80 +3448,63 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
         } else if (count == 0) /* no XI/Core event for you */
             goto unwind;
 
-        if (xi->u.u.type == GenericEvent)
-        {
-            /* find evmask for event's extension */
-            xGenericEvent* ge = ((xGenericEvent*)xi);
-            GenericMaskPtr    gemask = grab->genericMasks;
-
-            if (!gemask || !gemask->eventMask[GEEXTIDX(ge)])
-                goto unwind;
+        mask = grab->eventMask;
 
-            if (GEEventFill(xi))
-                GEEventFill(xi)(ge, thisDev, grab->window, grab);
-            deliveries = TryClientEvents(rClient(grab), thisDev, xi,
-                    count, gemask->eventMask[GEEXTIDX(ge)],
-                    generic_filters[GEEXTIDX(ge)][ge->evtype],
-                    grab);
-        } else
+        sendCore = (thisDev->isMaster && thisDev->coreEvents);
+        /* try core event */
+        if (sendCore && grab->coreGrab)
         {
-            Mask mask = grab->eventMask;
+            xEvent core;
 
-            sendCore = (thisDev->isMaster && thisDev->coreEvents);
-            /* try core event */
-            if (sendCore && grab->coreGrab)
+            rc = EventToCore(event, &core);
+            if (rc != Success && rc != BadMatch)
             {
-                xEvent core;
-
-                rc = EventToCore(event, &core);
-                if (rc != Success && rc != BadMatch)
-                {
-                    ErrorF("[dix] DeliverGrabbedEvent. Core conversion failed.\n");
-                    goto unwind;
-                }
-
-                FixUpEventFromWindow(thisDev, &core, grab->window,
-                        None, TRUE);
-                if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
-                            grab->window, &core, 1) ||
-                        XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
-                            grab->window, &core, 1))
-                    deliveries = 1; /* don't send, but pretend we did */
-                else if (!IsInterferingGrab(rClient(grab), thisDev, &core))
-                {
-                    deliveries = TryClientEvents(rClient(grab), thisDev,
-                            &core, 1, mask,
-                            filters[thisDev->id][core.u.u.type],
-                            grab);
-                }
+                ErrorF("[dix] DeliverGrabbedEvent. Core conversion failed.\n");
+                goto unwind;
             }
 
-            if (!deliveries)
+            FixUpEventFromWindow(thisDev, &core, grab->window,
+                    None, TRUE);
+            if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+                        grab->window, &core, 1) ||
+                    XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+                        grab->window, &core, 1))
+                deliveries = 1; /* don't send, but pretend we did */
+            else if (!IsInterferingGrab(rClient(grab), thisDev, &core))
             {
-                /* try XI event */
-                if (grabinfo->fromPassiveGrab  &&
-                        grabinfo->implicitGrab)
-                    mask = grab->deviceMask;
-                FixUpEventFromWindow(thisDev, xi, grab->window,
-                        None, TRUE);
-
-                if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
-                            grab->window, xi, count) ||
-                        XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
-                            grab->window, xi, count))
-                    deliveries = 1; /* don't send, but pretend we did */
-                else
-                {
-                    deliveries =
-                        TryClientEvents(rClient(grab), thisDev,
-                                xi, count,
-                                mask,
-                                filters[thisDev->id][xi->u.u.type],
-                                grab);
-                }
+                deliveries = TryClientEvents(rClient(grab), thisDev,
+                        &core, 1, mask,
+                        filters[thisDev->id][core.u.u.type],
+                        grab);
+            }
+        }
 
+        if (!deliveries)
+        {
+            /* try XI event */
+            if (grabinfo->fromPassiveGrab  &&
+                    grabinfo->implicitGrab)
+                mask = grab->deviceMask;
+            FixUpEventFromWindow(thisDev, xi, grab->window,
+                    None, TRUE);
+
+            if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+                        grab->window, xi, count) ||
+                    XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+                        grab->window, xi, count))
+                deliveries = 1; /* don't send, but pretend we did */
+            else
+            {
+                deliveries =
+                    TryClientEvents(rClient(grab), thisDev,
+                            xi, count,
+                            mask,
+                            filters[thisDev->id][xi->u.u.type],
+                            grab);
             }
+
         }
+
         if (deliveries && (event->u.any.type == ET_Motion))
             thisDev->valuator->motionHintWindow = grab->window;
     }
@@ -4377,7 +4256,6 @@ ProcGrabPointer(ClientPtr client)
 	tempGrab.pointerMode = stuff->pointerMode;
 	tempGrab.device = device;
         tempGrab.coreGrab = True;
-        tempGrab.genericMasks = NULL;
 	(*device->deviceGrab.ActivateGrab)(device, &tempGrab, time, FALSE);
 	if (oldCursor)
 	    FreeCursor (oldCursor, (Cursor)0);
@@ -4554,7 +4432,6 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
 	tempGrab.device = dev;
         tempGrab.cursor = NULL;
         tempGrab.coreGrab = coreGrab;
-        tempGrab.genericMasks = NULL;
 
 	(*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE);
 	*status = GrabSuccess;
@@ -5569,87 +5446,3 @@ IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event)
 
     return FALSE;
 }
-
-/**
- * Set the filters for a extension.
- * The filters array needs to contain the Masks that are applicable for each
- * event type for the given extension.
- * e.g. if generic event type 2 should be let through for windows with
- * MyExampleMask set, make sure that filters[2] == MyExampleMask.
- */
-void
-SetGenericFilter(int extension, Mask* filters)
-{
-    generic_filters[extension & 0x7f] = filters;
-}
-
-
-/**
- * Grab a device for XI events and XGE events.
- * grabmode is used to ungrab a device.
- */
-int
-ExtGrabDevice(ClientPtr client,
-              DeviceIntPtr dev,
-              int device_mode,
-              WindowPtr grabWindow,
-              WindowPtr confineTo,
-              TimeStamp ctime,
-              Bool ownerEvents,
-              CursorPtr cursor,
-              Mask xi_mask,
-              GenericMaskPtr ge_masks)
-{
-    GrabInfoPtr grabinfo;
-    GrabRec     newGrab;
-
-    UpdateCurrentTime();
-
-    grabinfo = &dev->deviceGrab;
-
-    if (grabinfo->grab && !SameClient(grabinfo->grab, client))
-        return AlreadyGrabbed;
-
-    if (!grabWindow->realized)
-        return GrabNotViewable;
-
-    if ((CompareTimeStamps(ctime, currentTime) == LATER) ||
-            (CompareTimeStamps(ctime, grabinfo->grabTime) == EARLIER))
-        return GrabInvalidTime;
-
-    if (grabinfo->sync.frozen && grabinfo->sync.other &&
-            !SameClient(grabinfo->sync.other, client))
-        return GrabFrozen;
-
-    memset(&newGrab, 0, sizeof(GrabRec));
-    newGrab.window         = grabWindow;
-    newGrab.resource       = client->clientAsMask;
-    newGrab.ownerEvents    = ownerEvents;
-    newGrab.device         = dev;
-    newGrab.cursor         = cursor;
-    newGrab.confineTo      = confineTo;
-    newGrab.eventMask      = xi_mask;
-    newGrab.genericMasks   = NULL;
-    newGrab.next           = NULL;
-
-    if (ge_masks)
-    {
-        newGrab.genericMasks  = xcalloc(1, sizeof(GenericMaskRec));
-        *newGrab.genericMasks = *ge_masks;
-        newGrab.genericMasks->next = NULL;
-    }
-
-    if (IsPointerDevice(dev))
-    {
-        newGrab.keyboardMode = GrabModeAsync;
-        newGrab.pointerMode  = device_mode;
-    } else
-    {
-        newGrab.keyboardMode = device_mode;
-        newGrab.pointerMode  = GrabModeAsync;
-    }
-
-    (*grabinfo->ActivateGrab)(dev, &newGrab, ctime, FALSE);
-    return GrabSuccess;
-}
-
diff --git a/dix/grabs.c b/dix/grabs.c
index 142fc4a..164e200 100644
--- a/dix/grabs.c
+++ b/dix/grabs.c
@@ -104,7 +104,6 @@ CreateGrab(
     grab->detail.pMask = NULL;
     grab->confineTo = confineTo;
     grab->cursor = cursor;
-    grab->genericMasks = NULL;
     grab->next = NULL;
     if (cursor)
 	cursor->refcnt++;
diff --git a/dix/window.c b/dix/window.c
index e2669f0..55faaf0 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -403,13 +403,6 @@ CreateRootWindow(ScreenPtr pScreen)
     pWin->optional->inputShape = NULL;
     pWin->optional->inputMasks = NULL;
     pWin->optional->deviceCursors = NULL;
-    pWin->optional->geMasks = (GenericClientMasksPtr)xcalloc(1, sizeof(GenericClientMasksRec));
-    if (!pWin->optional->geMasks)
-    {
-        xfree(pWin->optional);
-        return FALSE;
-    }
-
     pWin->optional->colormap = pScreen->defColormap;
     pWin->optional->visual = pScreen->rootVisual;
 
@@ -792,8 +785,6 @@ CreateWindow(Window wid, WindowPtr pParent, int x, int y, unsigned w,
 static void
 DisposeWindowOptional (WindowPtr pWin)
 {
-    GenericMaskPtr gmask = NULL, next = NULL;
-
     if (!pWin->optional)
 	return;
     /*
@@ -824,17 +815,6 @@ DisposeWindowOptional (WindowPtr pWin)
         pWin->optional->deviceCursors = NULL;
     }
 
-    /* Remove generic event mask allocations */
-    if (pWin->optional->geMasks)
-        gmask = pWin->optional->geMasks->geClients;
-    while(gmask)
-    {
-        next = gmask->next;
-        xfree(gmask);
-        gmask = next;
-    }
-    xfree (pWin->optional->geMasks);
-
     xfree (pWin->optional);
     pWin->optional = NULL;
 }
@@ -3443,9 +3423,6 @@ CheckWindowOptionalNeed (WindowPtr w)
         }
     }
 
-    if (optional->geMasks != NULL)
-        return;
-
     parentOptional = FindWindowWithOptional(w)->optional;
     if (optional->visual != parentOptional->visual)
 	return;
@@ -3489,18 +3466,6 @@ MakeWindowOptional (WindowPtr pWin)
     optional->inputMasks = NULL;
     optional->deviceCursors = NULL;
 
-    optional->geMasks = xalloc(sizeof(GenericClientMasksRec));
-    if (!optional->geMasks)
-    {
-        xfree(optional);
-        return FALSE;
-    } else {
-        int i;
-        optional->geMasks->geClients = 0;
-        for (i = 0; i < MAXEXTENSIONS; i++)
-            optional->geMasks->eventMasks[i] = 0;
-    }
-
     parentOptional = FindWindowWithOptional(pWin)->optional;
     optional->visual = parentOptional->visual;
     if (!pWin->cursorIsNone)
diff --git a/include/dix.h b/include/dix.h
index 552a2d0..ebd8f2f 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -611,16 +611,4 @@ extern _X_EXPORT ClientPtr LookupClient(
     XID id,
     ClientPtr client);
 
-/* GE stuff */
-extern _X_EXPORT void SetGenericFilter(int extension, Mask* filters);
-extern _X_EXPORT int ExtGrabDevice(ClientPtr client,
-                         DeviceIntPtr dev,
-                         int device_mode,
-                         WindowPtr grabWindow,
-                         WindowPtr confineTo,
-                         TimeStamp ctime,
-                         Bool ownerEvents,
-                         CursorPtr cursor, 
-                         Mask xi_mask,
-                         GenericMaskPtr ge_masks);
 #endif /* DIX_H */
diff --git a/include/inputstr.h b/include/inputstr.h
index c9faaec..3edd33f 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -175,7 +175,6 @@ typedef struct _GrabRec {
     CursorPtr		cursor;		/* always NULL for keyboards */
     Mask		eventMask;
     Mask                deviceMask;     
-    GenericMaskPtr      genericMasks;
 } GrabRec;
 
 typedef struct _KeyClassRec {
diff --git a/include/windowstr.h b/include/windowstr.h
index 720803a..be909b5 100644
--- a/include/windowstr.h
+++ b/include/windowstr.h
@@ -79,16 +79,6 @@ typedef struct _DevCursorNode {
     struct _DevCursorNode*      next;
 } DevCursNodeRec, *DevCursNodePtr, *DevCursorList;
 
-/* Mask structure for GE extension as stored on the window.
- * Allows one mask per extension.
- *   .eventMask - Summary mask for all clients, used for quick checking.
- *   .geClients - list of clients with their specific mask.
- */
-typedef struct _GenericClientMasks {
-    Mask                eventMasks[MAXEXTENSIONS];
-    GenericMaskPtr      geClients;
-} GenericClientMasksRec, *GenericClientMasksPtr;
-
 typedef struct _WindowOpt {
     VisualID		visual;		   /* default: same as parent */
     CursorPtr		cursor;		   /* default: window.cursorNone */
@@ -105,7 +95,6 @@ typedef struct _WindowOpt {
     RegionPtr		inputShape;	   /* default: NULL */
     struct _OtherInputMasks *inputMasks;   /* default: NULL */
     DevCursorList       deviceCursors;     /* default: NULL */
-    struct _GenericClientMasks *geMasks;   /* default: NULL */
 } WindowOptRec, *WindowOptPtr;
 
 #define BackgroundPixel	    2L
commit 6fe4c28bf4f3a9f7c341b9403213470e9ded5cb3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 16 16:34:05 2009 +1000

    Add agressive event type checking.
    
    Best to FatalError if a wrong event comes in. At least that forces me to fix
    it really quickly.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 29dceca..89adf4f 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -891,6 +891,8 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
     DeviceIntPtr mouse = NULL, kbd = NULL;
     DeviceEvent *event = (DeviceEvent*)ev;
 
+    CHECKEVENT(ev);
+
     if (IsPointerDevice(device))
     {
         kbd = GetPairedDevice(device);
diff --git a/dix/events.c b/dix/events.c
index 5702d2f..c21e57e 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2247,6 +2247,8 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
     xEvent *xE = NULL;
     int rc, count = 0;
 
+    CHECKEVENT(event);
+
     /* XXX: In theory, we could pass the internal events through to everything
      * and only convert just before hitting the wire. We can't do that yet, so
      * DDE is the last stop for internal events. From here onwards, we deal
@@ -2527,6 +2529,8 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
     WindowPtr prevSpriteWin;
     SpritePtr pSprite = pDev->spriteInfo->sprite;
 
+    CHECKEVENT(ev);
+
     prevSpriteWin = pSprite->win;
 
     if (ev && !syncEvents.playingEvents)
diff --git a/include/events.h b/include/events.h
index b091167..7bc83a6 100644
--- a/include/events.h
+++ b/include/events.h
@@ -62,6 +62,10 @@ enum {
     ET_Internal = 0xFF /* First byte */
 } EventType;
 
+#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->u.any.header != 0xFF) \
+                          FatalError("Wrong event type %d.\n", \
+                                     ((InternalEvent*)(ev))->u.any.header);
+
 /**
  * Used for ALL input device events internal in the server until
  * copied into the matching protocol event.
diff --git a/mi/mieq.c b/mi/mieq.c
index 0846602..efec55a 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -162,6 +162,8 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
     pthread_mutex_lock(&miEventQueueMutex);
 #endif
 
+    CHECKEVENT(e);
+
     /* avoid merging events from different devices */
     if (e->u.any.type == ET_Motion)
         isMotion = pDev->id;
@@ -285,6 +287,8 @@ static void
 FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev,
                     InternalEvent* original, InternalEvent *master)
 {
+    CHECKEVENT(original);
+    CHECKEVENT(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->u.any.type == ET_ButtonPress ||
@@ -312,6 +316,8 @@ CopyGetMasterEvent(DeviceIntPtr mdev, DeviceIntPtr sdev,
     int len = original->u.any.length;
     InternalEvent *mevent;
 
+    CHECKEVENT(original);
+
     if (master->evlen < len)
         SetMinimumEventSize(master, 1, len);
 
@@ -337,6 +343,8 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
     int x = 0, y = 0;
     DeviceIntPtr master;
 
+    CHECKEVENT(event);
+
     /* Custom event handler */
     handler = miEventQueue.handlers[event->u.any.type];
 


More information about the xorg-commit mailing list