xserver: Branch 'master' - 25 commits

Peter Hutterer whot at kemper.freedesktop.org
Mon Feb 23 00:55:15 PST 2009


 Xext/xtest.c                |    4 
 Xi/exevents.c               |  291 +++++++++-----------
 dix/Makefile.am             |    2 
 dix/eventconvert.c          |  346 ++++++++++++++++++++++++
 dix/events.c                |  611 ++++++++++++++++++++++++--------------------
 dix/getevents.c             |  222 ++++++---------
 hw/xfree86/common/xf86DGA.c |  205 +++++++-------
 include/Makefile.am         |    2 
 include/dix.h               |   34 +-
 include/eventconvert.h      |   36 ++
 include/events.h            |  215 +++++++++++++++
 include/exevents.h          |    8 
 include/input.h             |   21 -
 include/inputstr.h          |    8 
 include/xkbsrv.h            |   19 -
 mi/mi.h                     |   16 +
 mi/mieq.c                   |  248 +++++++----------
 xkb/ddxDevBtn.c             |    4 
 xkb/xkbAccessX.c            |   72 ++---
 xkb/xkbActions.c            |   42 +--
 xkb/xkbPrKeyEv.c            |   76 ++---
 21 files changed, 1539 insertions(+), 943 deletions(-)

New commits:
commit 36583a49965c0bb40a84284939b1539b3cb9fc9c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Feb 10 12:45:49 2009 +1000

    mi: split EQ popping and event processing into two functions.
    
    mieqProcessInputEvents() - pop an event off the EQ and pass it to
    mieqProcessDeviceEvent() - process the event according to the MD/SD hierarchy.
    
    This way, we can use mieqPDE() from Xtest, xkb, and others to post an event.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index 7e95c86..6f0d1ac 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -392,10 +392,8 @@ ProcXTestFakeInput(ClientPtr client)
             break;
     }
 
-    OsBlockSignals();
     for (i = 0; i < nevents; i++)
-        mieqEnqueue(dev, (events+i)->event);
-    OsReleaseSignals();
+        mieqProcessDeviceEvent(dev, (events+i)->event, NULL);
 
     return client->noClientException;
 }
diff --git a/mi/mi.h b/mi/mi.h
index 9ecf40b..076cea7 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -211,6 +211,12 @@ extern _X_EXPORT void mieqSwitchScreen(
     Bool /*fromDIX*/
 );
 
+extern _X_EXPORT void mieqProcessDeviceEvent(
+    DeviceIntPtr /* dev*/,
+    InternalEvent* /* event */,
+    ScreenPtr /* screen*/
+);
+
 extern _X_EXPORT void mieqProcessInputEvents(
     void
 );
diff --git a/mi/mieq.c b/mi/mieq.c
index e7b7ff0..7cda080 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -322,14 +322,64 @@ CopyGetMasterEvent(DeviceIntPtr mdev, DeviceIntPtr sdev,
     FixUpEventForMaster(mdev, sdev, original, mevent);
 }
 
+
+/**
+ * Post the given @event through the device hierarchy, as appropriate.
+ * Use this function if an event must be posted for a given device during the
+ * usual event processing cycle.
+ */
+void
+mieqProcessDeviceEvent(DeviceIntPtr dev,
+                       InternalEvent *event,
+                       ScreenPtr screen)
+{
+    mieqHandler handler;
+    int x = 0, y = 0;
+    DeviceIntPtr master;
+
+    /* Custom event handler */
+    handler = miEventQueue.handlers[event->u.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;
+        NewCurrentScreen (dev, DequeueScreen(dev), x, y);
+    }
+    else {
+        master  = (!dev->isMaster && dev->u.master) ? dev->u.master : NULL;
+
+        if (master)
+            CopyGetMasterEvent(master, dev, event, masterEvents);
+
+        /* If someone's registered a custom event handler, let them
+         * steal it. */
+        if (handler)
+        {
+            handler(DequeueScreen(dev)->myNum, event, dev);
+            if (master)
+                handler(DequeueScreen(master)->myNum,
+                        (InternalEvent*)masterEvents->event, master);
+        } else
+        {
+            /* process slave first, then master */
+            dev->public.processInputProc(event, dev);
+
+            if (master)
+                master->public.processInputProc(
+                        (InternalEvent*)masterEvents->event,
+                        master);
+        }
+    }
+}
+
 /* Call this from ProcessInputEvents(). */
 void
 mieqProcessInputEvents(void)
 {
-    mieqHandler handler;
     EventRec *e = NULL;
-    int x = 0, y = 0;
-    int type, evlen, i;
+    int evlen;
     ScreenPtr screen;
     static InternalEvent *event = NULL;
     static size_t event_size = 0;
@@ -361,8 +411,7 @@ mieqProcessInputEvents(void)
 #ifdef XQUARTZ
         pthread_mutex_unlock(&miEventQueueMutex);
 #endif
-        
-        type    = event->u.any.type;
+
         master  = (!dev->isMaster && dev->u.master) ? dev->u.master : NULL;
 
         if (screenIsSaved == SCREEN_SAVER_ON)
@@ -375,39 +424,7 @@ mieqProcessInputEvents(void)
             DPMSSet(serverClient, DPMSModeOn);
 #endif
 
-        /* Custom event handler */
-        handler = miEventQueue.handlers[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;
-            NewCurrentScreen (dev, DequeueScreen(dev), x, y);
-        }
-        else {
-            if (master)
-                CopyGetMasterEvent(master, dev, event, masterEvents);
-
-            /* If someone's registered a custom event handler, let them
-             * steal it. */
-            if (handler)
-            {
-                handler(DequeueScreen(dev)->myNum, event, dev);
-                if (master)
-                    handler(DequeueScreen(master)->myNum,
-                            (InternalEvent*)masterEvents->event, master);
-            } else
-            {
-                /* process slave first, then master */
-                dev->public.processInputProc(event, dev);
-
-                if (master)
-                    master->public.processInputProc(
-                            (InternalEvent*)masterEvents->event,
-                            master);
-            }
-        }
+        mieqProcessDeviceEvent(dev, event, screen);
 
         /* Update the sprite now. Next event may be from different device. */
         if (event->u.any.type == ET_Motion && (master || dev->isMaster))
commit 47f136ed6fd80310f715a2555501d1b271dd084c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Feb 6 12:08:43 2009 +1000

    mi: change custom handlers to internal events
    
    This should re-enable DGA, but XQuartz needs to be changed to internal events
    too now.
    
    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 e630b55..4cc530a 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -46,6 +46,8 @@
 #include "xf86Xinput.h"
 #include "exglobals.h"
 #include "exevents.h"
+#include "events.h"
+#include "eventconvert.h"
 
 #include "mi.h"
 
@@ -57,8 +59,8 @@ static Bool DGACloseScreen(int i, ScreenPtr pScreen);
 static void DGADestroyColormap(ColormapPtr pmap);
 static void DGAInstallColormap(ColormapPtr pmap);
 static void DGAUninstallColormap(ColormapPtr pmap);
-static void DGAHandleEvent(int screen_num, xEvent *event,
-                           DeviceIntPtr device, int nevents);
+static void DGAHandleEvent(int screen_num, InternalEvent *event,
+                           DeviceIntPtr device);
 
 static void
 DGACopyModeInfo(
@@ -245,11 +247,7 @@ DGACloseScreen(int i, ScreenPtr pScreen)
    DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
 
    if (XDGAEventBase) {
-       mieqSetHandler(*XDGAEventBase + MotionNotify, NULL);
-       mieqSetHandler(*XDGAEventBase + ButtonPress, NULL);
-       mieqSetHandler(*XDGAEventBase + ButtonRelease, NULL);
-       mieqSetHandler(*XDGAEventBase + KeyPress, NULL);
-       mieqSetHandler(*XDGAEventBase + KeyRelease, NULL);
+       mieqSetHandler(ET_DGAEvent, NULL);
     }
 
    FreeMarkedVisuals(pScreen);
@@ -463,11 +461,7 @@ DGASetInputMode(int index, Bool keyboard, Bool mouse)
       pScreenPriv->grabKeyboard = keyboard;
 
       if (!mieq_installed) {
-          mieqSetHandler(*XDGAEventBase + MotionNotify, DGAHandleEvent);
-          mieqSetHandler(*XDGAEventBase + ButtonPress, DGAHandleEvent);
-          mieqSetHandler(*XDGAEventBase + ButtonRelease, DGAHandleEvent);
-          mieqSetHandler(*XDGAEventBase + KeyPress, DGAHandleEvent);
-          mieqSetHandler(*XDGAEventBase + KeyRelease, DGAHandleEvent);
+          mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
           mieq_installed = 1;
       }
    }
@@ -916,8 +910,8 @@ Bool
 DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
 {
    DGAScreenPtr pScreenPriv;
-   dgaEvent    de;
-    
+   DGAEvent     event;
+
    if(DGAScreenKey == NULL) /* no DGA */
         return FALSE;
 
@@ -929,10 +923,16 @@ DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
    if(!pScreenPriv || !pScreenPriv->grabKeyboard) /* no direct mode */
         return FALSE; 
 
-    de.u.u.type = *XDGAEventBase + (is_down ? KeyPress : KeyRelease);
-    de.u.u.detail = key_code;
-    de.u.event.time = GetTimeInMillis();
-    mieqEnqueue (dev, (xEvent *) &de);
+    memset(&event, 0, sizeof(event));
+    event.header = ET_Internal;
+    event.type = ET_DGAEvent;
+    event.length = sizeof(event);
+    event.time = GetTimeInMillis();
+    event.subtype = (is_down ? ET_KeyPress : ET_KeyRelease);
+    event.detail = key_code;
+    event.dx = 0;
+    event.dy = 0;
+    mieqEnqueue (dev, (InternalEvent*)&event);
 
    return TRUE;
 }  
@@ -943,7 +943,7 @@ Bool
 DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
 {
    DGAScreenPtr pScreenPriv;
-    dgaEvent    de;
+   DGAEvent event;
 
    if(DGAScreenKey == NULL) /* no DGA */
         return FALSE;
@@ -963,14 +963,17 @@ DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
         DGAMouseY = 0;
     else if (DGAMouseY > screenInfo.screens[index]->height)
         DGAMouseY = screenInfo.screens[index]->height;
-    de.u.u.type = *XDGAEventBase + MotionNotify;
-    de.u.u.detail = 0;
-    de.u.event.time = GetTimeInMillis();
-    de.u.event.dx = dx;
-    de.u.event.dy = dy;
-    de.u.event.pad1 = DGAMouseX;
-    de.u.event.pad2 = DGAMouseY;
-    mieqEnqueue (dev, (xEvent *) &de);
+
+    memset(&event, 0, sizeof(event));
+    event.header = ET_Internal;
+    event.type = ET_DGAEvent;
+    event.length = sizeof(event);
+    event.time = GetTimeInMillis();
+    event.subtype = ET_Motion;
+    event.detail = 0;
+    event.dx = dx;
+    event.dy = dy;
+    mieqEnqueue (dev, (InternalEvent*)&event);
     return TRUE;
 }
 
@@ -978,7 +981,7 @@ Bool
 DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
 {
     DGAScreenPtr pScreenPriv;
-    dgaEvent de;
+    DGAEvent event;
 
     if (DGAScreenKey == NULL)
         return FALSE;
@@ -988,14 +991,16 @@ DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
     if (!pScreenPriv || !pScreenPriv->grabMouse)
         return FALSE;
 
-    de.u.u.type = *XDGAEventBase + (is_down ? ButtonPress : ButtonRelease);
-    de.u.u.detail = button;
-    de.u.event.time = GetTimeInMillis();
-    de.u.event.dx = 0;
-    de.u.event.dy = 0;
-    de.u.event.pad1 = DGAMouseX;
-    de.u.event.pad2 = DGAMouseY;
-    mieqEnqueue (dev, (xEvent *) &de);
+    memset(&event, 0, sizeof(event));
+    event.header = ET_Internal;
+    event.type = ET_DGAEvent;
+    event.length = sizeof(event);
+    event.time = GetTimeInMillis();
+    event.subtype = (is_down ? ET_ButtonPress : ET_ButtonRelease);
+    event.detail = button;
+    event.dx = 0;
+    event.dy = 0;
+    mieqEnqueue (dev, (InternalEvent*)&event);
 
     return TRUE;
 }
@@ -1027,93 +1032,91 @@ static Mask filters[] =
 };
 
 static void
-DGAProcessKeyboardEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr keybd)
+DGAProcessKeyboardEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr keybd)
 {
-    int		    coreEquiv;
-    xEvent	    xi;
     KeyClassPtr	    keyc = keybd->key;
     DGAScreenPtr    pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
     DeviceIntPtr    pointer = GetPairedDevice(keybd);
+    DeviceEvent     ev;
 
-    coreEquiv = de->u.u.type - *XDGAEventBase;
+    memset(&ev, 0, sizeof(ev));
+    ev.length = sizeof(ev);
+    ev.detail.key = event->detail;
+    ev.type = event->subtype;
+    ev.root_x = 0;
+    ev.root_y = 0;
+    ev.corestate = XkbStateFieldFromRec(&keyc->xkbInfo->state);
+    ev.corestate |= pointer->button->state;
 
-    /*
-     * Fill in remaining event state
-     */
-    de->u.event.dx = 0;
-    de->u.event.dy = 0;
-    de->u.event.screen = pScreen->myNum;
-    de->u.event.state = XkbStateFieldFromRec(&keyc->xkbInfo->state);
-    de->u.event.state |= pointer->button->state;
-
-    de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */
-#if 0
-    /* FIXME: Hello. I am broken. Please fix me. Thanks. */
-    UpdateDeviceState(keybd, (xEvent*)de, 1);
-#endif
-    de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */
+    UpdateDeviceState(keybd, &ev);
 
     /*
      * Deliver the DGA event
      */
     if (pScreenPriv->client)
     {
+        dgaEvent de;
+        de.u.u.type = *XDGAEventBase + GetCoreType((InternalEvent*)&ev);
+        de.u.u.detail = event->detail;
+        de.u.event.time = event->time;
+        de.u.event.dx = 0;
+        de.u.event.dy = 0;
+        de.u.event.screen = pScreen->myNum;
+        de.u.event.state = ev.corestate;
+
 	/* If the DGA client has selected input, then deliver based on the usual filter */
-	TryClientEvents (pScreenPriv->client, keybd, (xEvent *) de, 1,
-			 filters[coreEquiv], pScreenPriv->input, 0);
+	TryClientEvents (pScreenPriv->client, keybd, (xEvent *)&de, 1,
+			 filters[ev.type], pScreenPriv->input, 0);
     }
     else
     {
 	/* If the keyboard is actively grabbed, deliver a grabbed core event */
 	if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab)
 	{
-#if 0
-            /* FIXME: Hello. I am broken. Please fix me. Thanks. */
-	    xi.u.u.type                  = (IEventBase - 1) + coreEquiv;
-	    xi.u.u.detail                = de->u.u.detail;
-	    xi.u.keyButtonPointer.time   = de->u.event.time;
-	    xi.u.keyButtonPointer.eventX = de->u.event.dx;
-	    xi.u.keyButtonPointer.eventY = de->u.event.dy;
-	    xi.u.keyButtonPointer.rootX  = de->u.event.dx;
-	    xi.u.keyButtonPointer.rootY  = de->u.event.dy;
-	    xi.u.keyButtonPointer.state  = de->u.event.state;
-	    ((deviceKeyButtonPointer*)&xi)->deviceid = keybd->id;
-	    DeliverGrabbedEvent (&xi, keybd, FALSE, 1);
-#endif
+            ev.detail.key = event->detail;
+            ev.time       = event->time;
+            ev.root_x     = event->dx;
+            ev.root_y     = event->dy;
+            ev.corestate  = event->state;
+            ev.deviceid   = keybd->id;
+	    DeliverGrabbedEvent ((InternalEvent*)&ev, keybd, FALSE);
 	}
     }
 }
 
 static void
-DGAProcessPointerEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr mouse)
+DGAProcessPointerEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr mouse)
 {
     ButtonClassPtr  butc = mouse->button;
     int		    coreEquiv;
     DGAScreenPtr    pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-    xEvent	    xi;
+    DeviceEvent     ev;
 
-    coreEquiv = de->u.u.type - *XDGAEventBase;
-    /*
-     * Fill in remaining event state
-     */
-    de->u.event.screen = pScreen->myNum;
-    de->u.event.state = butc->state;
-    de->u.event.state |= XkbStateFieldFromRec(&GetPairedDevice(mouse)->key->xkbInfo->state);
-
-    de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */
-#if 0
-    /* FIXME: Hello. I am broken. Please fix me. Thanks. */
-    UpdateDeviceState(mouse, (xEvent*)de, 1);
-#endif
-    de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */
+    memset(&ev, 0, sizeof(ev));
+    ev.header = ET_Internal;
+    ev.length = sizeof(ev);
+    ev.type = event->subtype;
+    ev.corestate  = butc->state;
+    ev.corestate |= XkbStateFieldFromRec(&GetPairedDevice(mouse)->key->xkbInfo->state);
+
+    UpdateDeviceState(mouse, &ev);
 
     /*
      * Deliver the DGA event
      */
     if (pScreenPriv->client)
     {
+        dgaEvent        de;
+        de.u.u.type = *XDGAEventBase + GetCoreType((InternalEvent*)&ev);
+        de.u.u.detail = event->detail;
+        de.u.event.time = event->time;
+        de.u.event.dx = 0;
+        de.u.event.dy = 0;
+        de.u.event.screen = pScreen->myNum;
+        de.u.event.state = ev.corestate;
+
 	/* If the DGA client has selected input, then deliver based on the usual filter */
-	TryClientEvents (pScreenPriv->client, mouse, (xEvent *) de, 1,
+	TryClientEvents (pScreenPriv->client, mouse, (xEvent *)&de, 1,
 			 filters[coreEquiv], pScreenPriv->input, 0);
     }
     else
@@ -1121,18 +1124,12 @@ DGAProcessPointerEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr mouse)
 	/* If the pointer is actively grabbed, deliver a grabbed core event */
 	if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab)
 	{
-#if 0
-            /* FIXME: Hello. I am broken. Please fix me. Thanks. */
-	    xi.u.u.type                   = (IEventBase - 1 ) + coreEquiv;
-	    xi.u.u.detail                 = de->u.u.detail;
-	    xi.u.keyButtonPointer.time    = de->u.event.time;
-	    xi.u.keyButtonPointer.eventX  = de->u.event.dx;
-	    xi.u.keyButtonPointer.eventY  = de->u.event.dy;
-	    xi.u.keyButtonPointer.rootX   = de->u.event.dx;
-	    xi.u.keyButtonPointer.rootY   = de->u.event.dy;
-	    xi.u.keyButtonPointer.state   = de->u.event.state;
-	    DeliverGrabbedEvent (&xi, mouse, FALSE, 1);
-#endif
+            ev.detail.button    = event->detail;
+            ev.time             = event->time;
+            ev.root_x           = event->dx;
+            ev.root_y           = event->dy;
+            ev.corestate        = event->state;
+	    DeliverGrabbedEvent ((InternalEvent*)&ev, mouse, FALSE);
 	}
     }
 }
@@ -1196,34 +1193,32 @@ DGAGetOldDGAMode(int index)
 }
 
 static void
-DGAHandleEvent(int screen_num, xEvent *event, DeviceIntPtr device, int nevents)
+DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
 {
-    dgaEvent	    *de = (dgaEvent *) event;
+    DGAEvent	    *event= (DGAEvent*)ev;
     ScreenPtr       pScreen = screenInfo.screens[screen_num];
     DGAScreenPtr    pScreenPriv;
-    int		    coreEquiv;
 
     /* no DGA */
     if (DGAScreenKey == NULL || XDGAEventBase == 0)
 	return;
     pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-    
+
     /* DGA not initialized on this screen */
     if (!pScreenPriv)
 	return;
-    
-    coreEquiv = de->u.u.type - *XDGAEventBase;
-    /* Not a DGA event; shouldn't happen, but you never know. */
-    if (coreEquiv < KeyPress || coreEquiv > MotionNotify)
-	return;
-    
-    switch (coreEquiv) {
+
+    switch (event->subtype) {
     case KeyPress:
     case KeyRelease:
-	DGAProcessKeyboardEvent (pScreen, de, device);
+	DGAProcessKeyboardEvent (pScreen, event, device);
 	break;
+    case MotionNotify:
+    case ButtonPress:
+    case ButtonRelease:
+	DGAProcessPointerEvent (pScreen, event, device);
+        break;
     default:
-	DGAProcessPointerEvent (pScreen, de, device);
 	break;
     }
 }
diff --git a/include/events.h b/include/events.h
index 4b69246..4b98dee 100644
--- a/include/events.h
+++ b/include/events.h
@@ -55,6 +55,9 @@ enum {
     ET_ProximityOut,
     ET_DeviceChanged,
     ET_Hierarchy,
+#if XFreeXDGA
+    ET_DGAEvent,
+#endif
     ET_Internal = 0xFF /* First byte */
 } EventType;
 
@@ -153,6 +156,36 @@ typedef struct
     /* FIXME: add the new capabilities here */
 } DeviceChangedEvent;
 
+#if XFreeXDGA
+/**
+ * DGAEvent, used by DGA to intercept and emulate input events.
+ *
+ * @header:     Always ET_Internal
+ * @type:       ET_DGAEvent
+ * @length:     Length in bytes
+ * @time:       Time in ms
+ * @subtype:    KeyPress, KeyRelease, ButtonPress, ButtonRelease, MotionNotify
+ * @detail:     Key code or button number.
+ * @dx:         Relative x coordinate
+ * @dy:         Relative y coordinate
+ * @screen:     Screen number this event applies to
+ * @state:      Core modifier/button state
+ */
+typedef struct
+{
+    unsigned char header;
+    int type;
+    int length;
+    Time time;
+    int subtype;
+    int detail;
+    int dx;
+    int dy;
+    int screen;
+    uint16_t state;
+} DGAEvent;
+#endif
+
 /**
  * InternalEvent, event type used inside the X server for input event
  * processing.
@@ -173,6 +206,9 @@ typedef struct
         } any;
         DeviceEvent device;
         DeviceChangedEvent changed;
+#if XFreeXDGA
+        DGAEvent dga;
+#endif
     } u;
 } InternalEvent;
 
diff --git a/mi/mi.h b/mi/mi.h
index 570aa60..9ecf40b 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -215,7 +215,12 @@ extern _X_EXPORT void mieqProcessInputEvents(
     void
 );
 
-typedef void (*mieqHandler)(int, xEventPtr, DeviceIntPtr, int);
+/**
+ * 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
+ * given internal event type.
+ */
+typedef void (*mieqHandler)(int screen, InternalEvent* event, DeviceIntPtr dev);
 void _X_EXPORT mieqSetHandler(int event, mieqHandler handler);
 
 /* miexpose.c */
diff --git a/mi/mieq.c b/mi/mieq.c
index cca565a..e7b7ff0 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -391,16 +391,13 @@ mieqProcessInputEvents(void)
 
             /* If someone's registered a custom event handler, let them
              * steal it. */
-#if 0
             if (handler)
             {
-                /* FIXME: this is broken now, InternalEvents! */
-                handler(DequeueScreen(dev)->myNum, event, dev, 1);
+                handler(DequeueScreen(dev)->myNum, event, dev);
                 if (master)
                     handler(DequeueScreen(master)->myNum,
-                            masterEvents->event, master, 1);
+                            (InternalEvent*)masterEvents->event, master);
             } else
-#endif
             {
                 /* process slave first, then master */
                 dev->public.processInputProc(event, dev);
commit bdc262701a37a0c12ead810d63fa99a26cbb82ec
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 2 22:39:37 2009 +1000

    dix: remove un-used getValuatorEvents and countValuatorEvents from getevents.c
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 68f14aa..6d7d47e 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -544,45 +544,6 @@ clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
         clipAxis(pDev, i + first_valuator, &(valuators[i]));
 }
 
-
-/**
- * Fills events with valuator events for pDev, as given by the other
- * parameters.
- */
-static EventList *
-getValuatorEvents(EventList *events, DeviceIntPtr pDev,
-        int first_valuator, int num_valuators, int *valuators) {
-    deviceValuator *xv;
-    int i;
-
-    for (i = 0; i < num_valuators; i += 6, events++) {
-        xv = (deviceValuator*)events->event;
-        xv->type = DeviceValuator;
-        xv->first_valuator = first_valuator + i;
-        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
-        xv->deviceid = pDev->id;
-        switch (num_valuators - i) {
-        case 6:
-            xv->valuator5 = valuators[i + 5];
-        case 5:
-            xv->valuator4 = valuators[i + 4];
-        case 4:
-            xv->valuator3 = valuators[i + 3];
-        case 3:
-            xv->valuator2 = valuators[i + 2];
-        case 2:
-            xv->valuator1 = valuators[i + 1];
-        case 1:
-            xv->valuator0 = valuators[i + 0];
-        }
-
-        if (i + 6 < num_valuators)
-            xv->deviceid |= MORE_EVENTS;
-    }
-
-    return events;
-}
-
 /**
  * Create the DCCE event (does not update the master's device state yet, this
  * is done in the event processing).
@@ -783,23 +744,6 @@ updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms)
 }
 
 /**
- * Calculate how many DeviceValuator events are needed given a number of
- * valuators.
- * @param num_valuators Number of valuators to attach to event.
- * @return the number of DeviceValuator events needed.
- */
-static int
-countValuatorEvents(int num_valuators)
-{
-    if (num_valuators) {
-        if (((num_valuators - 1) / 6) + 1 > MAX_VALUATOR_EVENTS)
-            num_valuators = MAX_VALUATOR_EVENTS * 6;
-        return ((num_valuators - 1)/ 6) + 1;
-    } else
-        return 0;
-}
-
-/**
  * Convenience wrapper around GetKeyboardValuatorEvents, that takes no
  * valuators.
  */
commit 763848d3ab84b4e33a0254120c44b5a1877c819d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 2 17:20:17 2009 +1000

    Input: change processing API to InternalEvents.
    
    Don't pass xEvent* and count through to processing, pass a single
    InternalEvent.
    
    Custom handlers are disabled for the time being. And for extra fun,
    XKB's pointer motion emulation is disabled. But stick an error in there so
    that we get reminded should we forget about it.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 1ce3688..1915e3f 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -876,7 +876,7 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
  *
  */
 void
-ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
+ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
 {
     GrabPtr grab = device->deviceGrab.grab;
     Bool deactivateDeviceGrab = FALSE;
diff --git a/dix/events.c b/dix/events.c
index 5579ef2..881e4c5 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1028,7 +1028,7 @@ NoticeEventTime(InternalEvent *ev)
  * linked list for later delivery.
  */
 void
-EnqueueEvent(xEvent *ev, DeviceIntPtr device, int count)
+EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
 {
     QdEventPtr	tail = *syncEvents.pendtail;
     QdEventPtr	qe;
@@ -1163,7 +1163,7 @@ PlayReleasedEvents(void)
 
 	    }
 #endif
-	    (*qe->device->public.processInputProc)(qe->event, qe->device, 1);
+	    (*qe->device->public.processInputProc)(qe->event, qe->device);
 	    xfree(qe);
 	    for (dev = inputInfo.devices; dev && dev->deviceGrab.sync.frozen; dev = dev->next)
 		;
diff --git a/include/dix.h b/include/dix.h
index d48d83a..552a2d0 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -328,9 +328,8 @@ extern _X_EXPORT WindowPtr GetSpriteWindow(DeviceIntPtr pDev);
 extern _X_EXPORT void NoticeEventTime(InternalEvent *ev);
 
 extern _X_EXPORT void EnqueueEvent(
-    xEventPtr /* xE */,
-    DeviceIntPtr /* device */,
-    int	/* count */);
+    InternalEvent * /* ev */,
+    DeviceIntPtr  /* device */);
 
 extern _X_EXPORT void ActivatePointerGrab(
     DeviceIntPtr /* mouse */,
diff --git a/include/exevents.h b/include/exevents.h
index 51af9b4..d09ad3c 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -51,9 +51,8 @@ UpdateDeviceState (
 	DeviceEvent*           /*  xE    */);
 
 extern _X_EXPORT void ProcessOtherEvent (
-	xEventPtr /* FIXME deviceKeyButtonPointer * xE */,
-	DeviceIntPtr           /* other */,
-	int                    /* count */);
+	InternalEvent*         /* ev */,
+	DeviceIntPtr           /* other */);
 
 extern _X_EXPORT int InitProximityClassDeviceStruct(
 	DeviceIntPtr           /* dev */);
diff --git a/include/input.h b/include/input.h
index faa8d52..7651919 100644
--- a/include/input.h
+++ b/include/input.h
@@ -96,6 +96,7 @@ SOFTWARE.
 #define RevertToFollowKeyboard	3
 #endif
 
+#include "events.h"
 
 typedef unsigned long Leds;
 typedef struct _OtherClients *OtherClientsPtr;
@@ -122,9 +123,8 @@ typedef int (*DeviceProc)(
     int /*what*/);
 
 typedef void (*ProcessInputProc)(
-    xEventPtr /*events*/,
-    DeviceIntPtr /*device*/,
-    int /*count*/);
+    InternalEvent * /*event*/,
+    DeviceIntPtr /*device*/);
 
 typedef Bool (*DeviceHandleProc)(
     DeviceIntPtr /*device*/,
@@ -379,14 +379,12 @@ extern _X_EXPORT void MaybeStopHint(
     ClientPtr /*client*/);
 
 extern _X_EXPORT void ProcessPointerEvent(
-    xEventPtr /*xE*/,
-    DeviceIntPtr /*mouse*/,
-    int /*count*/);
+    InternalEvent* /* ev */,
+    DeviceIntPtr /*mouse*/);
 
 extern _X_EXPORT void ProcessKeyboardEvent(
-    xEventPtr /*xE*/,
-    DeviceIntPtr /*keybd*/,
-    int /*count*/);
+    InternalEvent* /*ev*/,
+    DeviceIntPtr   /*keybd*/);
 
 extern _X_EXPORT Bool LegalModifier(
     unsigned int /*key*/, 
diff --git a/mi/mieq.c b/mi/mieq.c
index a3e58a3..cca565a 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -391,6 +391,7 @@ mieqProcessInputEvents(void)
 
             /* If someone's registered a custom event handler, let them
              * steal it. */
+#if 0
             if (handler)
             {
                 /* FIXME: this is broken now, InternalEvents! */
@@ -399,12 +400,15 @@ mieqProcessInputEvents(void)
                     handler(DequeueScreen(master)->myNum,
                             masterEvents->event, master, 1);
             } else
+#endif
             {
                 /* process slave first, then master */
-                dev->public.processInputProc(event, dev, 1);
+                dev->public.processInputProc(event, dev);
 
                 if (master)
-                    master->public.processInputProc(masterEvents->event, master, 1);
+                    master->public.processInputProc(
+                            (InternalEvent*)masterEvents->event,
+                            master);
             }
         }
 
diff --git a/xkb/ddxDevBtn.c b/xkb/ddxDevBtn.c
index aad9661..e735fde 100644
--- a/xkb/ddxDevBtn.c
+++ b/xkb/ddxDevBtn.c
@@ -58,6 +58,9 @@ DeviceIntPtr		master = NULL;
     if (dev == inputInfo.pointer || !dev->public.on)
 	return;
 
+    ErrorF("[xkb] XkbDDXFakeDeviceButton. If you read this message in your "
+           "log file, Please file a bug on bugs.freedesktop.org.\n");
+#if 0
     nAxes = (dev->valuator?dev->valuator->numAxes:0);
     if (nAxes > 6)
 	nAxes = 6;
@@ -125,4 +128,5 @@ DeviceIntPtr		master = NULL;
         (*master->public.processInputProc)(masterEvents->event, master, count);
     }
     return;
+#endif
 }
diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index 618a18c..524bb53 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -684,16 +684,15 @@ Bool		ignoreKeyEvent = FALSE;
 extern int xkbDevicePrivateIndex;
 extern void xkbUnwrapProc(DeviceIntPtr, DeviceHandleProc, pointer);
 void
-ProcessPointerEvent(	register xEvent  *	xE, 
-			register DeviceIntPtr	mouse, 
-			int		        count)
+ProcessPointerEvent(	InternalEvent   *ev,
+			DeviceIntPtr    mouse)
 {
 DeviceIntPtr	dev = GetPairedDevice(mouse);
 XkbSrvInfoPtr	xkbi = dev->key->xkbInfo;
 unsigned 	changed = 0;
 ProcessInputProc backupproc;
 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(mouse);
-DeviceEvent     *event = (DeviceEvent*)xE;
+DeviceEvent     *event = (DeviceEvent*)ev;
 
     xkbi->shiftKeyCount = 0;
     xkbi->lastPtrEventTime= event->time;
@@ -723,7 +722,7 @@ DeviceEvent     *event = (DeviceEvent*)xE;
      */
 
     UNWRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr, backupproc);
-    mouse->public.processInputProc(xE, mouse, count);
+    mouse->public.processInputProc(ev, mouse);
     COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr,
 				     backupproc, xkbUnwrapProc);
 
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 3a2c517..7d17ad4 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -853,7 +853,7 @@ ProcessInputProc backupproc;
 	}
 
 	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
-	xkbi->device->public.processInputProc(&ev,xkbi->device,1);
+	xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
 	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
 				     backupproc,xkbUnwrapProc);
 	
@@ -884,7 +884,7 @@ ProcessInputProc backupproc;
 	}
 
 	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
-	xkbi->device->public.processInputProc(&ev,xkbi->device,1);
+	xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
 	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
 				     backupproc,xkbUnwrapProc);
 
@@ -1212,7 +1212,7 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
             tmpdev = GetPairedDevice(dev);
 
         UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
-        dev->public.processInputProc((xEvent*)event, tmpdev, 1);
+        dev->public.processInputProc((InternalEvent*)event, tmpdev);
         COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
                                      backupproc,xkbUnwrapProc);
     }
diff --git a/xkb/xkbPrKeyEv.c b/xkb/xkbPrKeyEv.c
index 86e9674..effb0ea 100644
--- a/xkb/xkbPrKeyEv.c
+++ b/xkb/xkbPrKeyEv.c
@@ -161,14 +161,14 @@ unsigned        ndx;
 }
 
 void
-ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
+ProcessKeyboardEvent(InternalEvent *ev, DeviceIntPtr keybd)
 {
 
     KeyClassPtr keyc = keybd->key;
     XkbSrvInfoPtr xkbi = NULL;
     ProcessInputProc backup_proc;
     xkbDeviceInfoPtr xkb_priv = XKBDEVICEINFO(keybd);
-    DeviceEvent *event = (DeviceEvent*)xE;
+    DeviceEvent *event = (DeviceEvent*)ev;
     int is_press = (event->type == ET_KeyPress);
     int is_release = (event->type == ET_KeyRelease);
 
@@ -178,7 +178,7 @@ ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
     /* We're only interested in key events. */
     if (!is_press && !is_release) {
         UNWRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc);
-        keybd->public.processInputProc(xE, keybd, count);
+        keybd->public.processInputProc(ev, keybd);
         COND_WRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc,
                                      xkbUnwrapProc);
         return;
commit 0b4066c116e07918a13dc6b4159df7ac9eb92b4b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 2 17:18:16 2009 +1000

    xkb: _XkbFilterRedirectKey needs to pass InternalEvents down.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index afc42f3..3a2c517 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -798,7 +798,7 @@ _XkbFilterRedirectKey(	XkbSrvInfoPtr	xkbi,
 			unsigned	keycode,
 			XkbAction *	pAction)
 {
-xEvent 		ev;
+DeviceEvent	ev;
 int		x,y;
 XkbStateRec	old;
 unsigned	mods,mask;
@@ -813,9 +813,11 @@ ProcessInputProc backupproc;
 	return 1;
 
     GetSpritePosition(inputInfo.pointer, &x,&y);
-    ev.u.keyButtonPointer.time = GetTimeInMillis();
-    ev.u.keyButtonPointer.rootX = x;
-    ev.u.keyButtonPointer.rootY = y;
+    ev.header = ET_Internal;
+    ev.length = sizeof(DeviceEvent);
+    ev.time = GetTimeInMillis();
+    ev.root_x = x;
+    ev.root_y = y;
 
     if (filter->keycode==0) {		/* initial press */
 	if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
@@ -829,9 +831,8 @@ ProcessInputProc backupproc;
 	filter->filter = _XkbFilterRedirectKey;
 	filter->upAction = *pAction;
 
-        /* XXX: what about DeviceKeyPress */
-	ev.u.u.type = KeyPress;
-	ev.u.u.detail = pAction->redirect.new_key;
+        ev.type = ET_KeyPress;
+        ev.detail.key = pAction->redirect.new_key;
 
         mask= pAction->redirect.vmods_mask;
         mods= pAction->redirect.vmods;
@@ -861,9 +862,8 @@ ProcessInputProc backupproc;
     }
     else if (filter->keycode==keycode) {
 
-        /* XXX: what about DeviceKeyRelease */
-	ev.u.u.type = KeyRelease;
-	ev.u.u.detail = filter->upAction.redirect.new_key;
+        ev.type = ET_KeyRelease;
+        ev.detail.key = filter->upAction.redirect.new_key;
 
         mask= filter->upAction.redirect.vmods_mask;
         mods= filter->upAction.redirect.vmods;
commit 085d50360863ccc8280cd3eccea2bcb4f3dd9a14
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 2 16:56:52 2009 +1000

    dix: Fix PostSyntheticMotion to use a DeviceEvent for posting.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index c992c20..68f14aa 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1123,7 +1123,7 @@ PostSyntheticMotion(DeviceIntPtr pDev,
                     int screen,
                     unsigned long time)
 {
-    xEvent xE;
+    DeviceEvent ev;
 
 #ifdef PANORAMIX
     /* Translate back to the sprite screen since processInputProc
@@ -1135,11 +1135,12 @@ PostSyntheticMotion(DeviceIntPtr pDev,
     }
 #endif
 
-    memset(&xE, 0, sizeof(xEvent));
-    xE.u.u.type = MotionNotify;
-    xE.u.keyButtonPointer.rootX = x;
-    xE.u.keyButtonPointer.rootY = y;
-    xE.u.keyButtonPointer.time = time;
+    memset(&ev, 0, sizeof(DeviceEvent));
+    init_event(pDev, &ev, time);
+    ev.root_x = x;
+    ev.root_y = y;
+    ev.type = time;
 
-    (*pDev->public.processInputProc)(&xE, pDev, 1);
+    /* FIXME: MD/SD considerations? */
+    (*pDev->public.processInputProc)((InternalEvent*)&ev, pDev);
 }
commit 155986a93dc78d6aa060ca3038d5fafa3d8753c2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 2 16:06:15 2009 +1000

    dix: CheckPassiveGrabsOnWindow moved to internal events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 6b59fb3..5579ef2 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3185,10 +3185,6 @@ CheckPassiveGrabsOnWindow(
 #define XI_MATCH        0x2
     int match = 0;
 
-    /* FIXME: temporary solution only. */
-    static int count;
-    static xEvent xE[1000]; /* enough bytes for the events we have atm */
-
     if (!grab)
 	return FALSE;
     /* Fill out the grab details, but leave the type for later before
@@ -3231,6 +3227,10 @@ CheckPassiveGrabsOnWindow(
 	     (grab->confineTo->realized &&
 				BorderSizeNotEmpty(device, grab->confineTo))))
 	{
+            int rc, count = 0;
+            xEvent *xE = NULL;
+            xEvent core;
+
             event->corestate &= 0x1f00;
             event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
             grabinfo = &device->deviceGrab;
@@ -3276,10 +3276,28 @@ CheckPassiveGrabsOnWindow(
             }
 
 
-            /* FIXME: temporary only */
-            count = ConvertBackToXI((InternalEvent*)event, xE);
             if (match & CORE_MATCH)
-                xE->u.u.type = GetCoreType(event);
+            {
+                rc = EventToCore((InternalEvent*)event, &core);
+                if (rc != Success && rc != BadMatch)
+                {
+                    ErrorF("[dix] %s: core conversion failed in CPGFW "
+                           "(%d, %d).\n", device->name, event->type, rc);
+                    continue;
+                }
+                xE = &core;
+                count = 1;
+            } else
+            {
+                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);
+                    continue;
+                }
+
+            }
 
 	    (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
 
@@ -3296,6 +3314,9 @@ CheckPassiveGrabsOnWindow(
                 *grabinfo->sync.event = *event;
 		grabinfo->sync.state = FROZEN_WITH_EVENT;
             }
+
+            if (match & XI_MATCH)
+                xfree(xE); /* on core match xE == &core */
 	    return TRUE;
 	}
     }
commit 1c38abd4b136301008ba77d4e68aea34508f4c22
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 2 14:54:34 2009 +1000

    dix: switch DeliverGrabbedEvent to internal events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 396dba9..6b59fb3 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3475,6 +3475,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
     DeviceIntPtr dev;
     SpritePtr pSprite = thisDev->spriteInfo->sprite;
     BOOL sendCore = FALSE;
+    int rc, count = 0;
+    xEvent *xi = NULL;
 
     grabinfo = &thisDev->deviceGrab;
     grab = grabinfo->grab;
@@ -3510,12 +3512,20 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
     }
     if (!deliveries)
     {
-        /* FIXME: temporary solution only. The event masks need a rework,
-         * especially for generic events. */
-        static int count;
-        static xEvent xi[1000]; /* enough bytes for the events we have atm */
+        /* 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.
+         */
 
-        count = ConvertBackToXI((InternalEvent*)event, xi);
+        rc = EventToXI(event, &xi, &count);
+        if (rc != Success)
+        {
+            ErrorF("[dix] %s: XI conversion failed in DGE (%d, %d). Skipping delivery.\n",
+                    thisDev->name, event->u.any.type, rc);
+            goto unwind;
+        } else if (count == 0) /* no XI/Core event for you */
+            goto unwind;
 
         if (xi->u.u.type == GenericEvent)
         {
@@ -3524,7 +3534,7 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
             GenericMaskPtr    gemask = grab->genericMasks;
 
             if (!gemask || !gemask->eventMask[GEEXTIDX(ge)])
-                return;
+                goto unwind;
 
             if (GEEventFill(xi))
                 GEEventFill(xi)(ge, thisDev, grab->window, grab);
@@ -3541,13 +3551,12 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
             if (sendCore && grab->coreGrab)
             {
                 xEvent core;
-                int rc;
 
                 rc = EventToCore(event, &core);
                 if (rc != Success && rc != BadMatch)
                 {
                     ErrorF("[dix] DeliverGrabbedEvent. Core conversion failed.\n");
-                    return;
+                    goto unwind;
                 }
 
                 FixUpEventFromWindow(thisDev, &core, grab->window,
@@ -3622,6 +3631,10 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
 	    break;
 	}
     }
+
+unwind:
+    if (xi)
+        xfree(xi);
 }
 
 /* This function is used to set the key pressed or key released state -
commit fb858774b80eb75c2f8e81fe893bbbdd37065fbd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 2 14:44:13 2009 +1000

    dix: switch DeliverDeviceEvents to internal events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 44670bc..396dba9 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2215,8 +2215,8 @@ FixUpEventFromWindow(
 }
 
 /**
- * Deliver events caused by input devices. Called for both core input events
- * and XI events.
+ * Deliver events caused by input devices.
+ *
  * For events from a non-grabbed, non-focus device, DeliverDeviceEvents is
  * called directly from the processInputProc.
  * For grabbed devices, DeliverGrabbedEvent is called first, and _may_ call
@@ -2225,11 +2225,10 @@ FixUpEventFromWindow(
  * DeliverDeviceEvents.
  *
  * @param pWin Window to deliver event to.
- * @param xE Events to deliver.
+ * @param event The events to deliver, not yet in wire format.
  * @param grab Possible grab on a device.
  * @param stopAt Don't recurse up to the root window.
  * @param dev The device that is responsible for the event.
- * @param count number of events in xE.
  *
  * @see DeliverGrabbedEvent
  * @see DeliverFocusedEvent
@@ -2245,17 +2244,28 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
     OtherInputMasks *inputMasks;
     int mskidx = dev->id;
     xEvent core;
-    /* FIXME: temporary solution only. */
-    static int count;
-    static xEvent xE[1000]; /* enough bytes for the events we have atm */
+    xEvent *xE = NULL;
+    int rc, count = 0;
 
-    /* FIXME: temporary only */
-    count = ConvertBackToXI((InternalEvent*)event, xE);
-    type = xE->u.u.type;
-    filter = filters[dev->id][type];
+    /* 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->u.any.type, rc);
+        goto unwind;
+    } else if (count == 0) /* no XI/Core event for you */
+        goto unwind;
 
     if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count))
-	return 0;
+	goto unwind;
+
+    type = xE->u.u.type;
+    filter = filters[dev->id][type];
 
     /* handle generic events */
     /* XXX: Generic events aren't quite handled correctly yet. They should
@@ -2269,7 +2279,8 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
         if (count > 1)
         {
             ErrorF("[dix] Do not send more than one GenericEvent at a time!\n");
-            return 0;
+            deliveries = 0;
+            goto unwind;
         }
         filter = generic_filters[GEEXTIDX(xE)][ge->evtype];
 
@@ -2282,7 +2293,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                 deliveries = DeliverEventsToWindow(dev, win, xE, count,
                         filter, grab, 0);
                 if (deliveries > 0)
-                    return deliveries;
+                    goto unwind;
             }
 
             win = win->parent;
@@ -2302,23 +2313,30 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                 deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
                                                    filter, grab, mskidx);
                 if (deliveries > 0)
-                    return deliveries;
+                    goto unwind;
             }
         }
 
         if ((deliveries < 0) || (pWin == stopAt) ||
             (inputMasks && (filter & inputMasks->dontPropagateMask[mskidx])))
-            return 0;
+        {
+            deliveries = 0;
+            goto unwind;
+        }
 
         if (dev->isMaster && dev->coreEvents)
         {
-
             /* no XI event delivered. Try core event */
-	    memset(&core, 0, sizeof(xEvent));
-            core = *xE;
-            core.u.u.type = XItoCoreType(xE->u.u.type);
+            rc = EventToCore(event, &core);
+            if (rc != Success)
+            {
+                if (rc != BadMatch)
+                    ErrorF("[dix] %s: Core conversion failed in DDE (%d, %d).\n",
+                            dev->name, event->u.any.type, rc);
+                goto unwind;
+            }
 
-            if (core.u.u.type && filter & pWin->deliverableEvents)
+            if (filter & pWin->deliverableEvents)
             {
                 if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
                 {
@@ -2326,20 +2344,25 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                     deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
                             filter, grab, 0);
                     if (deliveries > 0)
-                        return deliveries;
+                        goto unwind;
                 }
             }
 
             if ((deliveries < 0) || (pWin == stopAt) ||
                 (filter & wDontPropagateMask(pWin)))
-                return 0;
+            {
+                deliveries = 0;
+                goto unwind;
+            }
         }
 
         child = pWin->drawable.id;
         pWin = pWin->parent;
     }
 
-    return 0;
+unwind:
+    xfree(xE);
+    return deliveries;
 }
 
 /**
commit 3aa9404fcd161e94a80b057a77ef47afe428a56d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 2 14:00:41 2009 +1000

    dix: switch DeliverFocusedEvent to internal events.
    
    And because of xfree() macro hilarity, rename "pointer" to "ptr". Oh, how we
    laughed.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index f9c05d7..44670bc 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3355,30 +3355,26 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, int checkFirst)
 
 /**
  * Called for keyboard events to deliver event to whatever client owns the
- * focus. Event is delivered to the keyboard's focus window, the root window
- * or to the window owning the input focus.
+ * focus.
+ *
+ * The event is delivered to the keyboard's focus window, the root window or
+ * to the window owning the input focus.
  *
  * @param keybd The keyboard originating the event.
- * @param xE The event list.
+ * @param event The event, not yet in wire format.
  * @param window Window underneath the sprite.
- * @param count number of events in xE.
  */
 void
 DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
 {
-    DeviceIntPtr pointer;
+    DeviceIntPtr ptr;
     WindowPtr focus = keybd->focus->win;
     BOOL sendCore = (keybd->isMaster && keybd->coreEvents);
     xEvent core;
+    xEvent *xE = NULL;
+    int count, rc;
     int deliveries = 0;
 
-    /* FIXME: temporary solution only. */
-    static int count;
-    static xEvent xE[1000]; /* enough bytes for the events we have atm */
-
-    /* FIXME: temporary only */
-    count = ConvertBackToXI((InternalEvent*)event, xE);
-
     if (focus == FollowKeyboardWin)
 	focus = inputInfo.keyboard->focus->win;
     if (!focus)
@@ -3393,33 +3389,50 @@ DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
 	if (DeliverDeviceEvents(window, event, NullGrab, focus, keybd))
 	    return;
     }
-    pointer = GetPairedDevice(keybd);
-    if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count))
-	return;
+    ptr = GetPairedDevice(keybd);
 
-    if (sendCore)
+
+    rc = EventToXI(event, &xE, &count);
+    if (rc != Success)
     {
-	memset(&core, 0, sizeof(xEvent));
-        core = *xE;
-        core.u.u.type = XItoCoreType(xE->u.u.type);
-    }
+        ErrorF("[dix] %s: XI conversion failed in DFE (%d, %d). Skipping delivery.\n",
+               keybd->name, event->u.any.type, rc);
+        goto unwind;
+    } else if (count == 0) /* no XI/Core event for you */
+        return;
+
+    if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count))
+	goto unwind;
 
     /* just deliver it to the focus window */
-    FixUpEventFromWindow(pointer, xE, focus, None, FALSE);
+    FixUpEventFromWindow(ptr, xE, focus, None, FALSE);
     deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
                                        filters[keybd->id][xE->u.u.type],
                                        NullGrab, keybd->id);
 
     if (deliveries > 0)
-        return;
+        goto unwind;
 
-    if (sendCore && core.u.u.type)
+    if (sendCore)
     {
+        rc = EventToCore(event, &core);
+        if (rc != Success)
+        {
+            ErrorF("[dix] %s: core conversion failed DFE (%d, %d). Skipping delivery.\n",
+                    keybd->name, event->u.any.type, rc);
+            goto unwind;
+        }
+
         FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
         deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
                                            filters[keybd->id][core.u.u.type],
                                            NullGrab, 0);
     }
+
+unwind:
+    if (xE)
+        xfree(xE);
+    return;
 }
 
 /**
commit 8c873e7f514844d1056f2b20e653f1dd75f4c327
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Feb 1 20:41:16 2009 +1000

    dix: Switch DeliverGrabbedEvents to use internal events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 83f7b8d..f9c05d7 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3437,17 +3437,9 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
     GrabInfoPtr grabinfo;
     int deliveries = 0;
     DeviceIntPtr dev;
-    xEvent core;
     SpritePtr pSprite = thisDev->spriteInfo->sprite;
     BOOL sendCore = FALSE;
 
-    /* FIXME: temporary solution only. */
-    static int count;
-    static xEvent xE[1000]; /* enough bytes for the events we have atm */
-
-    /* FIXME: temporary only */
-    count = ConvertBackToXI((InternalEvent*)event, xE);
-
     grabinfo = &thisDev->deviceGrab;
     grab = grabinfo->grab;
 
@@ -3482,18 +3474,25 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
     }
     if (!deliveries)
     {
-        if (xE->u.u.type == GenericEvent)
+        /* FIXME: temporary solution only. The event masks need a rework,
+         * especially for generic events. */
+        static int count;
+        static xEvent xi[1000]; /* enough bytes for the events we have atm */
+
+        count = ConvertBackToXI((InternalEvent*)event, xi);
+
+        if (xi->u.u.type == GenericEvent)
         {
             /* find evmask for event's extension */
-            xGenericEvent* ge = ((xGenericEvent*)xE);
+            xGenericEvent* ge = ((xGenericEvent*)xi);
             GenericMaskPtr    gemask = grab->genericMasks;
 
             if (!gemask || !gemask->eventMask[GEEXTIDX(ge)])
                 return;
 
-            if (GEEventFill(xE))
-                GEEventFill(xE)(ge, thisDev, grab->window, grab);
-            deliveries = TryClientEvents(rClient(grab), thisDev, xE,
+            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);
@@ -3505,25 +3504,29 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
             /* try core event */
             if (sendCore && grab->coreGrab)
             {
-		memset(&core, 0, sizeof(xEvent));
-                core = *xE;
-                core.u.u.type = XItoCoreType(xE->u.u.type);
-                if(core.u.u.type) {
-                    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);
-                    }
+                xEvent core;
+                int rc;
+
+                rc = EventToCore(event, &core);
+                if (rc != Success && rc != BadMatch)
+                {
+                    ErrorF("[dix] DeliverGrabbedEvent. Core conversion failed.\n");
+                    return;
+                }
+
+                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);
                 }
             }
 
@@ -3531,24 +3534,23 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
             {
                 /* try XI event */
                 if (grabinfo->fromPassiveGrab  &&
-                        grabinfo->implicitGrab &&
-                        (xE->u.u.type & EXTENSION_EVENT_BASE))
+                        grabinfo->implicitGrab)
                     mask = grab->deviceMask;
-                FixUpEventFromWindow(thisDev, xE, grab->window,
+                FixUpEventFromWindow(thisDev, xi, grab->window,
                         None, TRUE);
 
                 if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
-                            grab->window, xE, count) ||
+                            grab->window, xi, count) ||
                         XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
-                            grab->window, xE, count))
+                            grab->window, xi, count))
                     deliveries = 1; /* don't send, but pretend we did */
                 else
                 {
                     deliveries =
                         TryClientEvents(rClient(grab), thisDev,
-                                xE, count,
+                                xi, count,
                                 mask,
-                                filters[thisDev->id][xE->u.u.type],
+                                filters[thisDev->id][xi->u.u.type],
                                 grab);
                 }
 
commit a3718536989fa7d3358e0b2d859c25fde0a2d93e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Feb 1 20:18:33 2009 +1000

    dix: Deliver{Grabbed|Focused|Device}Events API changed to InternalEvents.
    
    With the API change, we can now purge the XI conversion from POE.
    
    Note: this commit breaks DGA even more.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index bb5fe61..1ce3688 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -889,11 +889,6 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
     DeviceIntPtr mouse = NULL, kbd = NULL;
     DeviceEvent *event = (DeviceEvent*)ev;
 
-    /* FIXME: temporary solution only. */
-    static int nevents;
-    static xEvent xE[1000]; /* enough bytes for the events we have atm */
-
-
     if (IsPointerDevice(device))
     {
         kbd = GetPairedDevice(device);
@@ -989,15 +984,14 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
                 deactivateDeviceGrab = TRUE;
     }
 
-    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
 
     if (grab)
-        DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count);
-    else if (device->focus && !IsPointerEvent(xE))
-	DeliverFocusedEvent(device, xE, GetSpriteWindow(device), count);
+        DeliverGrabbedEvent(event, device, deactivateDeviceGrab);
+    else if (device->focus && !IsPointerEvent((InternalEvent*)ev))
+	DeliverFocusedEvent(device, event, GetSpriteWindow(device));
     else
-	DeliverDeviceEvents(GetSpriteWindow(device), xE, NullGrab, NullWindow,
-			    device, count);
+	DeliverDeviceEvents(GetSpriteWindow(device), event, NullGrab,
+                            NullWindow, device);
 
     if (deactivateDeviceGrab == TRUE)
 	(*device->deviceGrab.DeactivateGrab) (device);
diff --git a/dix/events.c b/dix/events.c
index 514c7a1..83f7b8d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1213,10 +1213,6 @@ ComputeFreezes(void)
     GrabPtr grab;
     DeviceIntPtr dev;
 
-    /* FIXME: temporary solution only. */
-    static int count;
-    static xEvent xE[1000]; /* enough bytes for the events we have atm */
-
     for (dev = inputInfo.devices; dev; dev = dev->next)
 	FreezeThaw(dev, dev->deviceGrab.sync.other ||
                 (dev->deviceGrab.sync.state >= FROZEN));
@@ -1227,9 +1223,6 @@ ComputeFreezes(void)
     {
         DeviceEvent* event = replayDev->deviceGrab.sync.event;
 
-        /* FIXME: temporary */
-        count = ConvertBackToXI(replayDev->deviceGrab.sync.event);
-
 	syncEvents.replayDev = (DeviceIntPtr)NULL;
 
         w = XYToWindow(replayDev, event->root_x, event->root_y);
@@ -1240,19 +1233,20 @@ ComputeFreezes(void)
 	    {
 		if (!CheckDeviceGrabs(replayDev, event, i+1)) {
 		    if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
-			DeliverFocusedEvent(replayDev, xE, w, count);
+			DeliverFocusedEvent(replayDev, (InternalEvent*)event, w);
 		    else
-			DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
-					        replayDev, count);
+			DeliverDeviceEvents(w, (InternalEvent*)event, NullGrab,
+                                            NullWindow, replayDev);
 		}
 		goto playmore;
 	    }
 	}
 	/* must not still be in the same stack */
 	if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
-	    DeliverFocusedEvent(replayDev, xE, w, count);
+	    DeliverFocusedEvent(replayDev, (InternalEvent*)event, w);
 	else
-	    DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
+	    DeliverDeviceEvents(w, (InternalEvent*)event, NullGrab,
+                                NullWindow, replayDev);
     }
 playmore:
     for (dev = inputInfo.devices; dev; dev = dev->next)
@@ -2241,16 +2235,24 @@ FixUpEventFromWindow(
  * @see DeliverFocusedEvent
  */
 int
-DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
-                    WindowPtr stopAt, DeviceIntPtr dev, int count)
+DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
+                    WindowPtr stopAt, DeviceIntPtr dev)
 {
     Window child = None;
-    int type = xE->u.u.type;
-    Mask filter = filters[dev->id][type];
+    int type;
+    Mask filter;
     int deliveries = 0;
     OtherInputMasks *inputMasks;
     int mskidx = dev->id;
     xEvent core;
+    /* FIXME: temporary solution only. */
+    static int count;
+    static xEvent xE[1000]; /* enough bytes for the events we have atm */
+
+    /* FIXME: temporary only */
+    count = ConvertBackToXI((InternalEvent*)event, xE);
+    type = xE->u.u.type;
+    filter = filters[dev->id][type];
 
     if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count))
 	return 0;
@@ -3362,7 +3364,7 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, int checkFirst)
  * @param count number of events in xE.
  */
 void
-DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
+DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
 {
     DeviceIntPtr pointer;
     WindowPtr focus = keybd->focus->win;
@@ -3370,18 +3372,25 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
     xEvent core;
     int deliveries = 0;
 
+    /* FIXME: temporary solution only. */
+    static int count;
+    static xEvent xE[1000]; /* enough bytes for the events we have atm */
+
+    /* FIXME: temporary only */
+    count = ConvertBackToXI((InternalEvent*)event, xE);
+
     if (focus == FollowKeyboardWin)
 	focus = inputInfo.keyboard->focus->win;
     if (!focus)
 	return;
     if (focus == PointerRootWin)
     {
-	DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
+	DeliverDeviceEvents(window, event, NullGrab, NullWindow, keybd);
 	return;
     }
     if ((focus == window) || IsParent(focus, window))
     {
-	if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
+	if (DeliverDeviceEvents(window, event, NullGrab, focus, keybd))
 	    return;
     }
     pointer = GetPairedDevice(keybd);
@@ -3421,17 +3430,24 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
  * @param deactivateGrab True if the device's grab should be deactivated.
  */
 void
-DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
-                    Bool deactivateGrab, int count)
+DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
+                    Bool deactivateGrab)
 {
     GrabPtr grab;
     GrabInfoPtr grabinfo;
     int deliveries = 0;
     DeviceIntPtr dev;
-    xEvent *dxE, core;
+    xEvent core;
     SpritePtr pSprite = thisDev->spriteInfo->sprite;
     BOOL sendCore = FALSE;
 
+    /* FIXME: temporary solution only. */
+    static int count;
+    static xEvent xE[1000]; /* enough bytes for the events we have atm */
+
+    /* FIXME: temporary only */
+    count = ConvertBackToXI((InternalEvent*)event, xE);
+
     grabinfo = &thisDev->deviceGrab;
     grab = grabinfo->grab;
 
@@ -3443,7 +3459,7 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
          * for the type of event, to see if we really want to deliver it to
          * the focus window. For pointer events, the answer is no.
          */
-        if (IsPointerEvent(xE))
+        if (IsPointerEvent(event))
             focus = PointerRootWin;
         else if (thisDev->focus)
 	{
@@ -3454,15 +3470,15 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
 	else
 	    focus = PointerRootWin;
 	if (focus == PointerRootWin)
-	    deliveries = DeliverDeviceEvents(pSprite->win, xE, grab,
-                                             NullWindow, thisDev, count);
+	    deliveries = DeliverDeviceEvents(pSprite->win, event, grab,
+                                             NullWindow, thisDev);
 	else if (focus && (focus == pSprite->win ||
                     IsParent(focus, pSprite->win)))
-	    deliveries = DeliverDeviceEvents(pSprite->win, xE, grab, focus,
-					     thisDev, count);
+	    deliveries = DeliverDeviceEvents(pSprite->win, event, grab, focus,
+					     thisDev);
 	else if (focus)
-	    deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
-					     thisDev, count);
+	    deliveries = DeliverDeviceEvents(focus, event, grab, focus,
+					     thisDev);
     }
     if (!deliveries)
     {
@@ -3538,12 +3554,10 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
 
             }
         }
-        if (deliveries && (xE->u.u.type == MotionNotify
-                    || xE->u.u.type == DeviceMotionNotify))
+        if (deliveries && (event->u.any.type == ET_Motion))
             thisDev->valuator->motionHintWindow = grab->window;
     }
-    if (deliveries && !deactivateGrab &&
-       (xE->u.u.type != MotionNotify && xE->u.u.type != DeviceMotionNotify))
+    if (deliveries && !deactivateGrab && event->u.any.type != ET_Motion)
     {
 	switch (grabinfo->sync.state)
 	{
@@ -3564,17 +3578,9 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
 	case FREEZE_NEXT_EVENT:
 	    grabinfo->sync.state = FROZEN_WITH_EVENT;
 	    FreezeThaw(thisDev, TRUE);
-#if 0
-            /* FIXME: Sorry, frozen grabs are broken ATM */
-	    if (grabinfo->sync.evcount < count)
-	    {
-		grabinfo->sync.event = xrealloc(grabinfo->sync.event,
-						count * sizeof(xEvent));
-	    }
-	    grabinfo->sync.evcount = count;
-	    for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++)
-		*dxE = *xE;
-#endif
+	    if (!grabinfo->sync.event)
+		grabinfo->sync.event = xcalloc(1, sizeof(InternalEvent));
+	    *grabinfo->sync.event = *(DeviceEvent*)event;
 	    break;
 	}
     }
diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index a974333..e630b55 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1067,6 +1067,8 @@ DGAProcessKeyboardEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr keybd)
 	/* If the keyboard is actively grabbed, deliver a grabbed core event */
 	if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab)
 	{
+#if 0
+            /* FIXME: Hello. I am broken. Please fix me. Thanks. */
 	    xi.u.u.type                  = (IEventBase - 1) + coreEquiv;
 	    xi.u.u.detail                = de->u.u.detail;
 	    xi.u.keyButtonPointer.time   = de->u.event.time;
@@ -1077,6 +1079,7 @@ DGAProcessKeyboardEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr keybd)
 	    xi.u.keyButtonPointer.state  = de->u.event.state;
 	    ((deviceKeyButtonPointer*)&xi)->deviceid = keybd->id;
 	    DeliverGrabbedEvent (&xi, keybd, FALSE, 1);
+#endif
 	}
     }
 }
@@ -1118,6 +1121,8 @@ DGAProcessPointerEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr mouse)
 	/* If the pointer is actively grabbed, deliver a grabbed core event */
 	if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab)
 	{
+#if 0
+            /* FIXME: Hello. I am broken. Please fix me. Thanks. */
 	    xi.u.u.type                   = (IEventBase - 1 ) + coreEquiv;
 	    xi.u.u.detail                 = de->u.u.detail;
 	    xi.u.keyButtonPointer.time    = de->u.event.time;
@@ -1127,6 +1132,7 @@ DGAProcessPointerEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr mouse)
 	    xi.u.keyButtonPointer.rootY   = de->u.event.dy;
 	    xi.u.keyButtonPointer.state   = de->u.event.state;
 	    DeliverGrabbedEvent (&xi, mouse, FALSE, 1);
+#endif
 	}
     }
 }
diff --git a/include/dix.h b/include/dix.h
index e61808a..d48d83a 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -371,11 +371,10 @@ extern _X_EXPORT int DeliverEventsToWindow(
 
 extern _X_EXPORT int DeliverDeviceEvents(
     WindowPtr /* pWin */,
-    xEventPtr /* xE */,
+    InternalEvent* /* event */,
     GrabPtr /* grab */,
     WindowPtr /* stopAt */,
-    DeviceIntPtr /* dev */,
-    int /* count */);
+    DeviceIntPtr /* dev */);
 
 extern _X_EXPORT void InitializeSprite(
     DeviceIntPtr /* pDev */,
@@ -395,15 +394,13 @@ extern _X_EXPORT Bool CheckDeviceGrabs(
 
 extern _X_EXPORT void DeliverFocusedEvent(
     DeviceIntPtr /* keybd */,
-    xEventPtr /* xE */,
-    WindowPtr /* window */,
-    int /* count */);
+    InternalEvent* /* event */,
+    WindowPtr /* window */);
 
 extern _X_EXPORT void DeliverGrabbedEvent(
-    xEventPtr /* xE */,
+    InternalEvent* /* event */,
     DeviceIntPtr /* thisDev */,
-    Bool /* deactivateGrab */,
-    int /* count */);
+    Bool /* deactivateGrab */);
 
 extern _X_EXPORT void FixKeyState(
     DeviceEvent* /* event */,
commit 8f94ec6f788565474931cc7d5e3d4672f0f31670
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Feb 1 09:58:15 2009 +1000

    dix: convert passive grabs to use internal events.
    
    deviceGrab.sync.event is now an internal event, and CheckDeviceGrabs and
    friends is changed over.
    
    Note that this currently breaks some frozen grabs. See towards the end of
    ComputeFreezes().
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 9996a04..bb5fe61 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -118,27 +118,15 @@ RegisterOtherDevice(DeviceIntPtr device)
 }
 
 Bool
-IsPointerEvent(xEvent* xE)
+IsPointerEvent(InternalEvent* event)
 {
-    switch(xE->u.u.type)
+    switch(event->u.any.type)
     {
-        case ButtonPress:
-        case ButtonRelease:
-        case MotionNotify:
-        case EnterNotify:
-        case LeaveNotify:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_Motion:
+            /* XXX: enter/leave ?? */
             return TRUE;
-        default:
-            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)
-            {
-                return TRUE;
-            }
     }
     return FALSE;
 }
@@ -955,8 +943,8 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
             break;
     }
 
-    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
-
+#if 0
+    /* FIXME: I'm broken. Please fix me. Thanks */
     if (DeviceEventCallback) {
 	DeviceEventInfoRec eventinfo;
 
@@ -964,11 +952,12 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
 	eventinfo.count = count;
 	CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
     }
+#endif
 
     switch(event->type)
     {
         case ET_KeyPress:
-            if (!grab && CheckDeviceGrabs(device, xE, 0, nevents)) {
+            if (!grab && CheckDeviceGrabs(device, event, 0)) {
                 device->deviceGrab.activatingKey = key;
                 return;
             }
@@ -982,10 +971,9 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
             event->detail.button = b->map[key];
             if (!event->detail.button) { /* there's no button 0 */
                 event->detail.button = key;
-                xE->u.u.detail = key; /* XXX: temporary */
                 return;
             }
-            if (!grab && CheckDeviceGrabs(device, xE, 0, nevents))
+            if (!grab && CheckDeviceGrabs(device, event, 0))
             {
                 /* if a passive grab was activated, the event has been sent
                  * already */
@@ -995,13 +983,14 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
             event->detail.button = b->map[key];
             if (!event->detail.button) { /* there's no button 0 */
                 event->detail.button = key;
-                xE->u.u.detail = key; /* XXX: temporary */
                 return;
             }
             if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab)
                 deactivateDeviceGrab = TRUE;
     }
 
+    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
+
     if (grab)
         DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count);
     else if (device->focus && !IsPointerEvent(xE))
diff --git a/dix/events.c b/dix/events.c
index ad2a591..514c7a1 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -162,6 +162,7 @@ typedef const char *string;
 #include "geint.h"
 
 #include "enterleave.h"
+#include "eventconvert.h"
 
 /* Extension events type numbering starts at EXTENSION_EVENT_BASE.  */
 #define NoSuchEvent 0x80000000	/* so doesn't match NoEventMask */
@@ -1202,9 +1203,6 @@ FreezeThaw(DeviceIntPtr dev, Bool frozen)
  * runs up the sprite tree (spriteTrace) and searches for the window to replay
  * the events from. If it is found, it checks for passive grabs one down from
  * the window or delivers the events.
- *
- * Since the events in the EQ are always XI events, we need to emulate core
- * events here.
  */
 static void
 ComputeFreezes(void)
@@ -1212,11 +1210,13 @@ ComputeFreezes(void)
     DeviceIntPtr replayDev = syncEvents.replayDev;
     int i;
     WindowPtr w;
-    xEvent *xE;
-    int count;
     GrabPtr grab;
     DeviceIntPtr dev;
 
+    /* FIXME: temporary solution only. */
+    static int count;
+    static xEvent xE[1000]; /* enough bytes for the events we have atm */
+
     for (dev = inputInfo.devices; dev; dev = dev->next)
 	FreezeThaw(dev, dev->deviceGrab.sync.other ||
                 (dev->deviceGrab.sync.state >= FROZEN));
@@ -1225,18 +1225,21 @@ ComputeFreezes(void)
     syncEvents.playingEvents = TRUE;
     if (replayDev)
     {
-	xE = replayDev->deviceGrab.sync.event;
-	count = replayDev->deviceGrab.sync.evcount;
+        DeviceEvent* event = replayDev->deviceGrab.sync.event;
+
+        /* FIXME: temporary */
+        count = ConvertBackToXI(replayDev->deviceGrab.sync.event);
+
 	syncEvents.replayDev = (DeviceIntPtr)NULL;
 
-        w = XYToWindow(replayDev, XE_KBPTR.rootX, XE_KBPTR.rootY);
+        w = XYToWindow(replayDev, event->root_x, event->root_y);
 	for (i = 0; i < replayDev->spriteInfo->sprite->spriteTraceGood; i++)
 	{
 	    if (syncEvents.replayWin ==
 		replayDev->spriteInfo->sprite->spriteTrace[i])
 	    {
-		if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
-		    if (replayDev->focus && !IsPointerEvent(xE))
+		if (!CheckDeviceGrabs(replayDev, event, i+1)) {
+		    if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
 			DeliverFocusedEvent(replayDev, xE, w, count);
 		    else
 			DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
@@ -1246,7 +1249,7 @@ ComputeFreezes(void)
 	    }
 	}
 	/* must not still be in the same stack */
-	if (replayDev->focus && !IsPointerEvent(xE))
+	if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
 	    DeliverFocusedEvent(replayDev, xE, w, count);
 	else
 	    DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
@@ -3139,32 +3142,35 @@ BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin)
  *
  * @param pWin The window that may be subject to a passive grab.
  * @param device Device that caused the event.
- * @param xE List of events (multiple ones for DeviceMotionNotify)
- * @param count number of elements in xE.
- * @param store The event that will be stored on the device (always XI)
- * @param scount number of elements in store.
+ * @param event The current device event.
+ * @param checkCore Check for core grabs too.
  */
 
 static Bool
 CheckPassiveGrabsOnWindow(
     WindowPtr pWin,
     DeviceIntPtr device,
-    xEvent *xE,
-    int count,
-    xEvent *store,
-    int scount)
+    DeviceEvent *event,
+    BOOL checkCore)
 {
     GrabPtr grab = wPassiveGrabs(pWin);
     GrabRec tempGrab;
     GrabInfoPtr grabinfo;
-    xEvent *dxE;
+#define CORE_MATCH      0x1
+#define XI_MATCH        0x2
+    int match = 0;
+
+    /* FIXME: temporary solution only. */
+    static int count;
+    static xEvent xE[1000]; /* enough bytes for the events we have atm */
 
     if (!grab)
 	return FALSE;
+    /* Fill out the grab details, but leave the type for later before
+     * comparing */
     tempGrab.window = pWin;
     tempGrab.device = device;
-    tempGrab.type = xE->u.u.type;
-    tempGrab.detail.exact = xE->u.u.detail;
+    tempGrab.detail.exact = event->detail.key;
     tempGrab.detail.pMask = NULL;
     tempGrab.modifiersDetail.pMask = NULL;
     tempGrab.next = NULL;
@@ -3185,14 +3191,23 @@ CheckPassiveGrabsOnWindow(
             xkbi= gdev->key->xkbInfo;
 	tempGrab.modifierDevice = grab->modifierDevice;
         tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
-        /* ignore the device for core events when comparing grabs */
-	if (GrabMatchesSecond(&tempGrab, grab, (xE->u.u.type < GenericEvent)) &&
-	    (!grab->confineTo ||
+
+        /* Check for XI grabs first */
+        tempGrab.type = GetXIType((InternalEvent*)event);
+	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)))
+                match = CORE_MATCH;
+
+        if (match && (!grab->confineTo ||
 	     (grab->confineTo->realized &&
 				BorderSizeNotEmpty(device, grab->confineTo))))
 	{
-            XE_KBPTR.state &= 0x1f00;
-            XE_KBPTR.state |= tempGrab.modifiersDetail.exact&(~0x1f00);
+            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.
@@ -3201,7 +3216,7 @@ CheckPassiveGrabsOnWindow(
                Since XGrabDeviceButton requires to specify the
                modifierDevice explicitly, we don't override this choice.
              */
-            if (xE->u.u.type < GenericEvent)
+            if (tempGrab.type < GenericEvent)
             {
                 grab->device = device;
                 grab->modifierDevice = GetPairedDevice(device);
@@ -3236,6 +3251,11 @@ CheckPassiveGrabsOnWindow(
             }
 
 
+            /* FIXME: temporary only */
+            count = ConvertBackToXI((InternalEvent*)event, xE);
+            if (match & CORE_MATCH)
+                xE->u.u.type = GetCoreType(event);
+
 	    (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
 
 	    FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
@@ -3246,21 +3266,17 @@ CheckPassiveGrabsOnWindow(
 
 	    if (grabinfo->sync.state == FROZEN_NO_EVENT)
 	    {
-		if (grabinfo->sync.evcount < scount)
-		{
-		    grabinfo->sync.event = xrealloc(grabinfo->sync.event,
-						    scount * sizeof(xEvent));
-		}
-		grabinfo->sync.evcount = scount;
-                /* we always store the XI event, never the core event */
-		for (dxE = grabinfo->sync.event; --scount >= 0; dxE++, store++)
-		    *dxE = *store;
+                if (!grabinfo->sync.event)
+                    grabinfo->sync.event = xcalloc(1, sizeof(InternalEvent));
+                *grabinfo->sync.event = *event;
 		grabinfo->sync.state = FROZEN_WITH_EVENT;
             }
 	    return TRUE;
 	}
     }
     return FALSE;
+#undef CORE_MATCH
+#undef XI_MATCH
 }
 
 /**
@@ -3290,33 +3306,20 @@ CheckPassiveGrabsOnWindow(
 */
 
 Bool
-CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
-                 int checkFirst, int count)
+CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, int checkFirst)
 {
     int i;
     WindowPtr pWin = NULL;
-    FocusClassPtr focus = IsPointerEvent(xE) ? NULL : device->focus;
-    xEvent core;
+    FocusClassPtr focus = IsPointerEvent((InternalEvent*)event) ? NULL : device->focus;
     BOOL sendCore = (device->isMaster && device->coreEvents);
 
-    if ((xE->u.u.type == DeviceButtonPress)
-            && (device->button->buttonsDown != 1))
-	return FALSE;
-
-    if (xE->u.u.type < EXTENSION_EVENT_BASE)
-    {
-        ErrorF("[dix] Core event passed into CheckDeviceGrabs.\n");
+    if (event->type != ET_ButtonPress &&
+        event->type != ET_KeyPress)
         return FALSE;
-    }
-
 
-    if (sendCore)
-    {
-        core = *xE;
-        core.u.u.type = XItoCoreType(xE->u.u.type);
-        if(!core.u.u.type) /* probably a Proximity event, can't grab for those */
-            return FALSE;
-    }
+    if (event->type == ET_ButtonPress
+        && (device->button->buttonsDown != 1))
+	return FALSE;
 
     i = checkFirst;
 
@@ -3325,11 +3328,8 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
 	for (; i < focus->traceGood; i++)
 	{
 	    pWin = focus->trace[i];
-            /* XI grabs have precendence */
 	    if (pWin->optional &&
-	       (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count)
-                || (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core,
-                        1, xE, count))))
+	        CheckPassiveGrabsOnWindow(pWin, device, event, sendCore))
 		return TRUE;
 	}
 
@@ -3344,9 +3344,7 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
     {
 	pWin = device->spriteInfo->sprite->spriteTrace[i];
 	if (pWin->optional &&
-	    (CheckPassiveGrabsOnWindow(pWin, device, xE, count, xE, count) ||
-             (sendCore && CheckPassiveGrabsOnWindow(pWin, device, &core, 1,
-                                                    xE, count))))
+	    CheckPassiveGrabsOnWindow(pWin, device, event, sendCore))
 	    return TRUE;
     }
 
@@ -3566,6 +3564,8 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
 	case FREEZE_NEXT_EVENT:
 	    grabinfo->sync.state = FROZEN_WITH_EVENT;
 	    FreezeThaw(thisDev, TRUE);
+#if 0
+            /* FIXME: Sorry, frozen grabs are broken ATM */
 	    if (grabinfo->sync.evcount < count)
 	    {
 		grabinfo->sync.event = xrealloc(grabinfo->sync.event,
@@ -3574,6 +3574,7 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
 	    grabinfo->sync.evcount = count;
 	    for (dxE = grabinfo->sync.event; --count >= 0; dxE++, xE++)
 		*dxE = *xE;
+#endif
 	    break;
 	}
     }
diff --git a/include/dix.h b/include/dix.h
index 700fe9b..e61808a 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -390,9 +390,8 @@ extern _X_EXPORT void WindowHasNewCursor(
 
 extern _X_EXPORT Bool CheckDeviceGrabs(
     DeviceIntPtr /* device */,
-    xEventPtr /* xE */,
-    int /* checkFirst */,
-    int /* count */);
+    DeviceEvent* /* event */,
+    int /* checkFirst */);
 
 extern _X_EXPORT void DeliverFocusedEvent(
     DeviceIntPtr /* keybd */,
@@ -584,7 +583,7 @@ 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(xEvent* xE);
+extern _X_EXPORT Bool IsPointerEvent(InternalEvent* event);
 
 /*
  * These are deprecated compatibility functions and will be removed soon!
diff --git a/include/inputstr.h b/include/inputstr.h
index b3b15d2..6d3fc52 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -426,8 +426,7 @@ typedef struct _GrabInfoRec {
 	Bool		frozen;
 	int		state;
 	GrabPtr		other;		/* if other grab has this frozen */
-	xEvent		*event;		/* saved to be replayed */
-	int		evcount;
+	DeviceEvent	*event;		/* saved to be replayed */
     } sync;
 } GrabInfoRec, *GrabInfoPtr;
 
commit daa3245c479b19d445a070b5b76ee005915b5335
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sat Jan 31 08:46:43 2009 +1000

    dix: fix EnqueueEvent to work with internal events.
    
    Note that we're only partially switched to internal events. The event in the
    devices' event queue (dev->deviceGrab.sync.event) is still an XI event. The
    events in syncEvents are InternalEvents only now.
    This also implies fixing CheckVirtualMotion to work with internal events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index a09085b..ad2a591 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -708,13 +708,28 @@ CheckVirtualMotion(
 {
     SpritePtr pSprite = pDev->spriteInfo->sprite;
     RegionPtr reg = NULL;
+    DeviceEvent *ev = NULL;
 
     if (qe)
     {
-	pSprite->hot.pScreen = qe->pScreen;
-	pSprite->hot.x = qe->event->u.keyButtonPointer.rootX;
-	pSprite->hot.y = qe->event->u.keyButtonPointer.rootY;
-	pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab->confineTo : NullWindow;
+        ev = (DeviceEvent*)qe->event;
+        switch(ev->type)
+        {
+            case ET_Motion:
+            case ET_ButtonPress:
+            case ET_ButtonRelease:
+            case ET_KeyPress:
+            case ET_KeyRelease:
+            case ET_ProximityIn:
+            case ET_ProximityOut:
+                pSprite->hot.pScreen = qe->pScreen;
+                pSprite->hot.x = ev->root_x;
+                pSprite->hot.y = ev->root_y;
+                pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab->confineTo : NullWindow;
+                break;
+            default:
+                break;
+        }
     }
     if (pWin)
     {
@@ -783,11 +798,11 @@ CheckVirtualMotion(
         if (reg)
             ConfineToShape(pDev, reg, &pSprite->hot.x, &pSprite->hot.y);
 
-	if (qe)
+	if (qe && ev)
 	{
 	    qe->pScreen = pSprite->hot.pScreen;
-	    qe->event->u.keyButtonPointer.rootX = pSprite->hot.x;
-	    qe->event->u.keyButtonPointer.rootY = pSprite->hot.y;
+	    ev->root_x = pSprite->hot.x;
+	    ev->root_y = pSprite->hot.y;
 	}
     }
 #ifdef PANORAMIX
@@ -1020,21 +1035,15 @@ EnqueueEvent(xEvent *ev, DeviceIntPtr device, int count)
     int		eventlen;
     DeviceEvent *event = (DeviceEvent*)ev;
 
-    /* FIXME: temporary solution only. */
-    static int nevents;
-    static xEvent xi[1000]; /* enough bytes for the events we have atm */
-    xEvent *xE = xi;
-
-
     NoticeTime((InternalEvent*)event);
 
-    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
-
     /* Fix for key repeating bug. */
     if (device->key != NULL && device->key->xkbInfo != NULL &&
-	xE->u.u.type == KeyRelease)
-	AccessXCancelRepeatKey(device->key->xkbInfo, xE->u.u.detail);
+        event->type == ET_KeyRelease)
+	AccessXCancelRepeatKey(device->key->xkbInfo, event->detail.key);
 
+#if 0
+        /* FIXME: I'm broken now. Please fix me. */
     if (DeviceEventCallback)
     {
 	DeviceEventInfoRec eventinfo;
@@ -1054,35 +1063,35 @@ EnqueueEvent(xEvent *ev, DeviceIntPtr device, int count)
 	eventinfo.count = nevents;
 	CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
     }
-    if (xE->u.u.type == DeviceMotionNotify)
+#endif
+    if (event->type == ET_Motion)
     {
 #ifdef PANORAMIX
 	if(!noPanoramiXExtension) {
-	    XE_KBPTR.rootX += panoramiXdataPtr[pSprite->screen->myNum].x -
+            event->root_x += panoramiXdataPtr[pSprite->screen->myNum].x -
 			      panoramiXdataPtr[0].x;
-	    XE_KBPTR.rootY += panoramiXdataPtr[pSprite->screen->myNum].y -
+	    event->root_y += panoramiXdataPtr[pSprite->screen->myNum].y -
 			      panoramiXdataPtr[0].y;
 	}
 #endif
-	pSprite->hotPhys.x = XE_KBPTR.rootX;
-	pSprite->hotPhys.y = XE_KBPTR.rootY;
+	pSprite->hotPhys.x = event->root_x;
+	pSprite->hotPhys.y = event->root_y;
 	/* do motion compression, but not if from different devices */
 	if (tail &&
-	    (tail->event->u.u.type == DeviceMotionNotify) &&
+	    (tail->event->u.any.type == ET_Motion) &&
             (tail->device == device) &&
 	    (tail->pScreen == pSprite->hotPhys.pScreen))
 	{
-	    tail->event->u.keyButtonPointer.rootX = pSprite->hotPhys.x;
-	    tail->event->u.keyButtonPointer.rootY = pSprite->hotPhys.y;
-	    tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
+            DeviceEvent *tailev = (DeviceEvent*)tail->event;
+	    tailev->root_x = pSprite->hotPhys.x;
+	    tailev->root_y = pSprite->hotPhys.y;
+	    tailev->time = event->time;
 	    tail->months = currentTime.months;
 	    return;
 	}
     }
 
-    eventlen = nevents * sizeof(xEvent);
-    if (xE->u.u.type == GenericEvent) /* count is 1 for GenericEvents */
-	eventlen += ((xGenericEvent*)xE)->length * 4;
+    eventlen = event->length;
 
     qe = xalloc(sizeof(QdEventRec) + eventlen);
     if (!qe)
@@ -1091,19 +1100,8 @@ EnqueueEvent(xEvent *ev, DeviceIntPtr device, int count)
     qe->device = device;
     qe->pScreen = pSprite->hotPhys.pScreen;
     qe->months = currentTime.months;
-    qe->event = (xEvent *)(qe + 1);
-    qe->evcount = nevents;
-    if (xE->u.u.type == GenericEvent)
-    {
-	memcpy(qe->event, xE, eventlen);
-    } else
-    {
-	xEvent	*qxE;
-	for (qxE = qe->event; --nevents >= 0; qxE++, xE++)
-	{
-	    *qxE = *xE;
-	}
-    }
+    qe->event = (InternalEvent *)(qe + 1);
+    memcpy(qe->event, event, eventlen);
     if (tail)
 	syncEvents.pendtail = &tail->next;
     *syncEvents.pendtail = qe;
@@ -1124,7 +1122,6 @@ PlayReleasedEvents(void)
     QdEventPtr *prev, qe;
     DeviceIntPtr dev;
     DeviceIntPtr pDev;
-    static CARD32 lastKnownMillis = 0; /* Hack, see comment below */
 
     prev = &syncEvents.pending;
     while ( (qe = *prev) )
@@ -1135,36 +1132,37 @@ PlayReleasedEvents(void)
             pDev = qe->device;
 	    if (*syncEvents.pendtail == *prev)
 		syncEvents.pendtail = prev;
-	    if (qe->event->u.u.type == DeviceMotionNotify)
+	    if (qe->event->u.any.type == ET_Motion)
 		CheckVirtualMotion(pDev, qe, NullWindow);
 	    syncEvents.time.months = qe->months;
-            /* XXX: Hack! We can't reliably get the time from GenericEvents,
-               since we don't know which struct it may be. So we store the time
-               when we know it, and re-use it when we can't get it. */
-            if (qe->event->u.u.type == GenericEvent)
-            {
-                syncEvents.time.milliseconds = lastKnownMillis;
-            } else
-            {
-                syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
-                lastKnownMillis = syncEvents.time.milliseconds;
-            }
+            syncEvents.time.milliseconds = qe->event->u.any.time;
 #ifdef PANORAMIX
 	   /* Translate back to the sprite screen since processInputProc
 	      will translate from sprite screen to screen 0 upon reentry
 	      to the DIX layer */
-            /* XXX: we can't do that for generic events */
 	    if(!noPanoramiXExtension) {
-		qe->event->u.keyButtonPointer.rootX +=
-			panoramiXdataPtr[0].x -
-			panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].x;
-		qe->event->u.keyButtonPointer.rootY +=
-			panoramiXdataPtr[0].y -
-			panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].y;
+                DeviceEvent *ev = (DeviceEvent*)(qe->event);
+                switch(ev->type)
+                {
+                    case ET_Motion:
+                    case ET_ButtonPress:
+                    case ET_ButtonRelease:
+                    case ET_KeyPress:
+                    case ET_KeyRelease:
+                    case ET_ProximityIn:
+                    case ET_ProximityOut:
+                        ev->root_x += panoramiXdataPtr[0].x -
+                            panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].x;
+                        ev->root_y += panoramiXdataPtr[0].y -
+                            panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].y;
+                        break;
+                    default:
+                        break;
+                }
+
 	    }
 #endif
-	    (*qe->device->public.processInputProc)(qe->event, qe->device,
-						   qe->evcount);
+	    (*qe->device->public.processInputProc)(qe->event, qe->device, 1);
 	    xfree(qe);
 	    for (dev = inputInfo.devices; dev && dev->deviceGrab.sync.frozen; dev = dev->next)
 		;
diff --git a/include/inputstr.h b/include/inputstr.h
index bed71be..b3b15d2 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -516,8 +516,7 @@ typedef struct _QdEvent {
     DeviceIntPtr	device;
     ScreenPtr		pScreen;	/* what screen the pointer was on */
     unsigned long	months;		/* milliseconds is in the event */
-    xEvent		*event;
-    int			evcount;
-} QdEventRec;    
+    InternalEvent	*event;
+} QdEventRec;
 
 #endif /* INPUTSTRUCT_H */
commit 75595ba4aa9c3823ffe3b3388ce088929824816f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 30 15:14:46 2009 +1000

    Xi: make ProcessOtherEvents more InternalEvent aware.
    
    Get rid of the deviceValuator processing and a few other things, but still
    drop back into XI before checking device grabs or doing anything else.
    
    NoticeEventTime now needs to take InternalEvents, and while we're at it,
    change NoticeTime from a macro to a function.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index bedafe3..9996a04 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -890,14 +890,12 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
 void
 ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
 {
-    int i;
     GrabPtr grab = device->deviceGrab.grab;
     Bool deactivateDeviceGrab = FALSE;
     int key = 0, rootX, rootY;
     ButtonClassPtr b;
     KeyClassPtr k;
     ValuatorClassPtr v;
-    deviceValuator *xV;
     int ret = 0;
     int state;
     DeviceIntPtr mouse = NULL, kbd = NULL;
@@ -938,18 +936,27 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
     if (device->isMaster || !device->u.master)
         CheckMotion(event, device);
 
-    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
 
-    if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) {
-	GetSpritePosition(device, &rootX, &rootY);
-	xE->u.keyButtonPointer.rootX = rootX;
-	xE->u.keyButtonPointer.rootY = rootY;
-	NoticeEventTime(xE);
+    switch (event->type)
+    {
+        case ET_Motion:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            GetSpritePosition(device, &rootX, &rootY);
+            event->root_x = rootX;
+            event->root_y = rootY;
+            NoticeEventTime((InternalEvent*)event);
+            event->corestate = state;
+            key = event->detail.key;
+            break;
+    }
 
-        xE->u.keyButtonPointer.state = state;
+    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
 
-        key = xE->u.u.detail;
-    }
     if (DeviceEventCallback) {
 	DeviceEventInfoRec eventinfo;
 
@@ -958,43 +965,41 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
 	CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
     }
 
-    /* Valuator event handling */
-    xV = (deviceValuator*)xE;
-    for (i = 1; i < count; i++) {
-	if ((++xV)->type == DeviceValuator)
-	    xV->device_state = state;
-    }
-
-    if (xE->u.u.type == DeviceKeyPress) {
-	if (!grab && CheckDeviceGrabs(device, xE, 0, count)) {
-	    device->deviceGrab.activatingKey = key;
-	    return;
-	}
-    } else if (xE->u.u.type == DeviceKeyRelease) {
-	if (device->deviceGrab.fromPassiveGrab &&
-            (key == device->deviceGrab.activatingKey))
-	    deactivateDeviceGrab = TRUE;
-    } else if (xE->u.u.type == DeviceButtonPress) {
-	xE->u.u.detail = b->map[key];
-	if (xE->u.u.detail == 0) {
-	    xE->u.u.detail = key;
-	    return;
-	}
-        if (!grab && CheckDeviceGrabs(device, xE, 0, count))
-        {
-            /* if a passive grab was activated, the event has been sent
-             * already */
-            return;
-        }
-
-    } else if (xE->u.u.type == DeviceButtonRelease) {
-	xE->u.u.detail = b->map[key];
-	if (xE->u.u.detail == 0) {
-	    xE->u.u.detail = key;
-	    return;
-	}
-        if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab)
-            deactivateDeviceGrab = TRUE;
+    switch(event->type)
+    {
+        case ET_KeyPress:
+            if (!grab && CheckDeviceGrabs(device, xE, 0, nevents)) {
+                device->deviceGrab.activatingKey = key;
+                return;
+            }
+            break;
+        case ET_KeyRelease:
+            if (device->deviceGrab.fromPassiveGrab &&
+                    (key == device->deviceGrab.activatingKey))
+                deactivateDeviceGrab = TRUE;
+            break;
+        case ET_ButtonPress:
+            event->detail.button = b->map[key];
+            if (!event->detail.button) { /* there's no button 0 */
+                event->detail.button = key;
+                xE->u.u.detail = key; /* XXX: temporary */
+                return;
+            }
+            if (!grab && CheckDeviceGrabs(device, xE, 0, nevents))
+            {
+                /* if a passive grab was activated, the event has been sent
+                 * already */
+                return;
+            }
+        case ET_ButtonRelease:
+            event->detail.button = b->map[key];
+            if (!event->detail.button) { /* there's no button 0 */
+                event->detail.button = key;
+                xE->u.u.detail = key; /* XXX: temporary */
+                return;
+            }
+            if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab)
+                deactivateDeviceGrab = TRUE;
     }
 
     if (grab)
@@ -1007,7 +1012,7 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
 
     if (deactivateDeviceGrab == TRUE)
 	(*device->deviceGrab.DeactivateGrab) (device);
-    xE->u.u.detail = key;
+    event->detail.key = key;
 }
 
 int
diff --git a/dix/events.c b/dix/events.c
index 8d53490..a09085b 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -974,29 +974,32 @@ XineramaGetCursorScreen(DeviceIntPtr pDev)
 #define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
 
 static void
-MonthChangedOrBadTime(xEvent *xE)
+MonthChangedOrBadTime(InternalEvent *ev)
 {
     /* If the ddx/OS is careless about not processing timestamped events from
      * 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 - XE_KBPTR.time) > TIMESLOP)
+    if ((currentTime.milliseconds - ev->u.any.time) > TIMESLOP)
 	currentTime.months++;
     else
-	XE_KBPTR.time = currentTime.milliseconds;
+        ev->u.any.time = currentTime.milliseconds;
 }
 
-#define NoticeTime(xE) { \
-    if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
-	MonthChangedOrBadTime(xE); \
-    currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
-    lastDeviceEventTime = currentTime; }
+static void
+NoticeTime(InternalEvent *ev)
+{
+    if (ev->u.any.time < currentTime.milliseconds)
+        MonthChangedOrBadTime(ev);
+    currentTime.milliseconds = ev->u.any.time;
+    lastDeviceEventTime = currentTime;
+}
 
 void
-NoticeEventTime(xEvent *xE)
+NoticeEventTime(InternalEvent *ev)
 {
     if (!syncEvents.playingEvents)
-	NoticeTime(xE);
+	NoticeTime(ev);
 }
 
 /**************************************************************************
@@ -1022,10 +1025,10 @@ EnqueueEvent(xEvent *ev, DeviceIntPtr device, int count)
     static xEvent xi[1000]; /* enough bytes for the events we have atm */
     xEvent *xE = xi;
 
-    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
 
-    NoticeTime(xE);
+    NoticeTime((InternalEvent*)event);
 
+    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
 
     /* Fix for key repeating bug. */
     if (device->key != NULL && device->key->xkbInfo != NULL &&
diff --git a/include/dix.h b/include/dix.h
index 2aaa4fa..700fe9b 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -325,7 +325,7 @@ extern _X_EXPORT WindowPtr GetCurrentRootWindow(DeviceIntPtr pDev);
 extern _X_EXPORT WindowPtr GetSpriteWindow(DeviceIntPtr pDev);
 
 
-extern _X_EXPORT void NoticeEventTime(xEventPtr /* xE */);
+extern _X_EXPORT void NoticeEventTime(InternalEvent *ev);
 
 extern _X_EXPORT void EnqueueEvent(
     xEventPtr /* xE */,
commit 3a02e538dbdb3cd482e01baeaf2aba2ddb7731df
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 30 14:59:22 2009 +1000

    dix: update CheckMotion to deal with DeviceEvents.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index caee698..bedafe3 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -930,14 +930,15 @@ ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
     if (ret == DONT_PROCESS)
         return;
 
-    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
 
     v = device->valuator;
     b = device->button;
     k = device->key;
 
     if (device->isMaster || !device->u.master)
-        CheckMotion(xE, device);
+        CheckMotion(event, device);
+
+    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
 
     if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) {
 	GetSpritePosition(device, &rootX, &rootY);
diff --git a/dix/events.c b/dix/events.c
index a6d601d..8d53490 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2493,35 +2493,24 @@ XYToWindow(DeviceIntPtr pDev, int x, int y)
  * @return TRUE if the sprite has moved or FALSE otherwise.
  */
 Bool
-CheckMotion(xEvent *xE, DeviceIntPtr pDev)
+CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
 {
-    INT16     *rootX, *rootY;
     WindowPtr prevSpriteWin;
     SpritePtr pSprite = pDev->spriteInfo->sprite;
 
     prevSpriteWin = pSprite->win;
 
-    if (xE && !syncEvents.playingEvents)
+    if (ev && !syncEvents.playingEvents)
     {
         /* GetPointerEvents() guarantees that pointer events have the correct
            rootX/Y set already. */
-        switch(xE->u.u.type)
+        switch (ev->type)
         {
-            case ButtonPress:
-            case ButtonRelease:
-            case MotionNotify:
-                rootX = &XE_KBPTR.rootX;
-                rootY = &XE_KBPTR.rootY;
+            case ET_ButtonPress:
+            case ET_ButtonRelease:
+            case ET_Motion:
                 break;
             default:
-                if (xE->u.u.type == DeviceButtonPress ||
-                        xE->u.u.type == DeviceButtonRelease ||
-                        xE->u.u.type == DeviceMotionNotify)
-                {
-                    rootX = &((deviceKeyButtonPointer*)xE)->root_x;
-                    rootY = &((deviceKeyButtonPointer*)xE)->root_y;
-                    break;
-                }
                 /* all other events return FALSE */
                 return FALSE;
         }
@@ -2533,9 +2522,9 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev)
             /* Motion events entering DIX get translated to Screen 0
                coordinates.  Replayed events have already been
                translated since they've entered DIX before */
-            *rootX += panoramiXdataPtr[pSprite->screen->myNum].x -
+            ev->root_x += panoramiXdataPtr[pSprite->screen->myNum].x -
                                        panoramiXdataPtr[0].x;
-            *rootY += panoramiXdataPtr[pSprite->screen->myNum].y -
+            ev->root_y += panoramiXdataPtr[pSprite->screen->myNum].y -
                                        panoramiXdataPtr[0].y;
         } else
 #endif
@@ -2547,8 +2536,8 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev)
             }
         }
 
-        pSprite->hot.x = *rootX;
-        pSprite->hot.y = *rootY;
+        pSprite->hot.x = ev->root_x;
+        pSprite->hot.y = ev->root_y;
         if (pSprite->hot.x < pSprite->physLimits.x1)
             pSprite->hot.x = pSprite->physLimits.x1;
         else if (pSprite->hot.x >= pSprite->physLimits.x2)
@@ -2561,8 +2550,8 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev)
 	    ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y);
 	pSprite->hotPhys = pSprite->hot;
 
-	if ((pSprite->hotPhys.x != *rootX) ||
-	    (pSprite->hotPhys.y != *rootY))
+	if ((pSprite->hotPhys.x != ev->root_x) ||
+	    (pSprite->hotPhys.y != ev->root_y))
 	{
 #ifdef PANORAMIX
             if (!noPanoramiXExtension)
@@ -2578,8 +2567,8 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev)
             }
 	}
 
-	*rootX = pSprite->hot.x;
-	*rootY = pSprite->hot.y;
+	ev->root_x = pSprite->hot.x;
+	ev->root_y = pSprite->hot.y;
     }
 
     pSprite->win = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y);
@@ -2587,7 +2576,7 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev)
     if (pSprite->win != prevSpriteWin)
     {
 	if (prevSpriteWin != NullWindow) {
-	    if (!xE)
+	    if (!ev)
 		UpdateCurrentTimeIf();
             DoEnterLeaveEvents(pDev, prevSpriteWin, pSprite->win,
                                NotifyNormal);
@@ -2609,7 +2598,7 @@ WindowsRestructured(void)
     while(pDev)
     {
         if (DevHasCursor(pDev))
-            CheckMotion((xEvent *)NULL, pDev);
+            CheckMotion(NULL, pDev);
         pDev = pDev->next;
     }
 }
diff --git a/include/dix.h b/include/dix.h
index 0afd766..2aaa4fa 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -466,7 +466,7 @@ extern _X_EXPORT int DeliverEvents(
 
 extern _X_EXPORT Bool
 CheckMotion(
-    xEvent* /* xE */, 
+    DeviceEvent* /* ev */,
     DeviceIntPtr /* pDev */);
 
 extern _X_EXPORT void WriteEventsToClient(
commit 8829d966a6bacb05d322b60531c59366b58f4514
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 30 13:33:55 2009 +1000

    Xi: support InternalEvents in UpdateDeviceState, parts of POE and EnqueueEvent
    
    Note that this breaks DGA. Life is tough.
    
    EnqueueEvent is a somewhat half-baked solution, we immediately drop back into
    XI and store them. But it should in theory work.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    
    Don't let the dcce be random data.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index af98bac..caee698 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -668,9 +668,10 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
  */
 static void
 ChangeMasterDeviceClasses(DeviceIntPtr device,
-                          deviceClassesChangedEvent *dcce)
+                          DeviceChangedEvent *dce)
 {
     DeviceIntPtr master = device->u.master;
+    deviceClassesChangedEvent *dcce;
     char* classbuff;
     int len = sizeof(xEvent);
     int namelen = 0; /* dummy */
@@ -681,19 +682,29 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
     if (!master) /* if device was set floating between SIGIO and now */
         return;
 
+    SizeDeviceInfo(device, &namelen, &len);
+    dcce = xalloc(len);
+    if (!dcce)
+    {
+        ErrorF("[Xi] BadAlloc in ChangeMasterDeviceClasses\n");
+        return;
+    }
+
+    dcce->type         = GenericEvent;
+    dcce->extension    = IReqCode;
+    dcce->evtype       = XI_DeviceClassesChangedNotify;
+    dcce->time         = GetTimeInMillis();
+    dcce->new_slave    = device->id;
     dcce->deviceid     = master->id;
     dcce->num_classes  = 0;
 
-    SizeDeviceInfo(device, &namelen, &len);
     dcce->length = (len - sizeof(xEvent))/4;
 
     master->public.devicePrivate = device->public.devicePrivate;
 
     DeepCopyDeviceClasses(device, master);
 
-    /* event is already correct size, see SetMinimumEventSize */
     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);
@@ -711,105 +722,78 @@ ChangeMasterDeviceClasses(DeviceIntPtr device,
 #define DEFAULT 0
 #define DONT_PROCESS 1
 int
-UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
+UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
 {
     int i;
     int key = 0,
-        bit = 0;
+        bit = 0,
+        last_valuator;
 
     KeyClassPtr k       = NULL;
     ButtonClassPtr b    = NULL;
     ValuatorClassPtr v  = NULL;
-    deviceValuator *xV  = (deviceValuator *) xE;
     BYTE *kptr          = NULL;
 
     /* This event is always the first we get, before the actual events with
      * the data. However, the way how the DDX is set up, "device" will
      * actually be the slave device that caused the event.
      */
-    if (GEIsType(xE, IReqCode, XI_DeviceClassesChangedNotify))
+    switch(event->type)
     {
-        ChangeMasterDeviceClasses(device, (deviceClassesChangedEvent*)xE);
-        return DONT_PROCESS; /* event has been sent already */
+        case ET_DeviceChanged:
+            ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event);
+            return DONT_PROCESS; /* event has been sent already */
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            break;
+        default:
+            /* other events don't update the device */
+            return DEFAULT;
     }
 
-    /* currently no other generic event modifies the device */
-    if (xE->u.u.type == GenericEvent)
-        return DEFAULT;
-
     k = device->key;
     v = device->valuator;
     b = device->button;
 
+    key = event->detail.key;
+    bit = 1 << (key & 7);
 
-    if (xE->u.u.type != DeviceValuator)
+    /* Update device axis */
+    /* Check valuators first */
+    last_valuator = 0;
+    for (i = 0; i < MAX_VALUATORS; i++)
     {
-        key = xE->u.u.detail;
-        bit = 1 << (key & 7);
+        if (BitIsOn(&event->valuators.mask, i))
+        {
+            if (!v)
+            {
+                ErrorF("[Xi] Valuators reported for non-valuator device '%s'. "
+                        "Ignoring event.\n", device->name);
+                return DONT_PROCESS;
+            } else if (v->numAxes < i)
+            {
+                ErrorF("[Xi] Too many valuators reported for device '%s'. "
+                        "Ignoring event.\n", device->name);
+                return DONT_PROCESS;
+            }
+            last_valuator = i;
+        }
     }
 
-    /* Update device axis */
-    for (i = 1; i < count; i++) {
-	if ((++xV)->type == DeviceValuator) {
-	    int *axisvals;
-            int first = xV->first_valuator;
-            BOOL change = FALSE;
-
-	    if (xV->num_valuators && !v)
-                FatalError("Valuators reported for non-valuator device '%s'\n",
-                           device->name);
-            if (first + xV->num_valuators > v->numAxes)
-		FatalError("Too many valuators reported for device '%s'\n",
-			   device->name);
-	    if (v && v->axisVal) {
-                /* v->axisVal is always in absolute coordinates. Only the
-                 * delivery mode changes.
-                 * If device is mode Absolute
-                 *     dev = event
-                 * If device is mode Relative
-                 *      swap = (event - device)
-                 *      dev = event
-                 *      event = delta
-                 */
-                int delta;
-                axisvals = v->axisVal;
-                if (v->mode == Relative) /* device reports relative */
-                    change = TRUE;
-
-                switch (xV->num_valuators) {
-                    case 6:
-                        if (change) delta = xV->valuator5 - *(axisvals + first + 5);
-                        *(axisvals + first + 5) = xV->valuator5;
-                        if (change) xV->valuator5 = delta;
-                    case 5:
-                        if (change) delta = xV->valuator4 - *(axisvals + first + 4);
-                        *(axisvals + first + 4) = xV->valuator4;
-                        if (change) xV->valuator4 = delta;
-                    case 4:
-                        if (change) delta = xV->valuator3 - *(axisvals + first + 3);
-                        *(axisvals + first + 3) = xV->valuator3;
-                        if (change) xV->valuator3 = delta;
-                    case 3:
-                        if (change) delta = xV->valuator2 - *(axisvals + first + 2);
-                        *(axisvals + first + 2) = xV->valuator2;
-                        if (change) xV->valuator2 = delta;
-                    case 2:
-                        if (change) delta = xV->valuator1 - *(axisvals + first + 1);
-                        *(axisvals + first + 1) = xV->valuator1;
-                        if (change) xV->valuator1 = delta;
-                    case 1:
-                        if (change) delta = xV->valuator0 - *(axisvals + first);
-                        *(axisvals + first) = xV->valuator0;
-                        if (change) xV->valuator0 = delta;
-                    case 0:
-                    default:
-                        break;
-                }
-	    }
-	}
+    for (i = 0; i < last_valuator && i < v->numAxes; i++)
+    {
+        if (BitIsOn(&event->valuators.mask, i))
+        {
+            /* XXX: Relative/Absolute mode */
+            v->axisVal[i] = event->valuators.data[i];
+        }
     }
 
-    if (xE->u.u.type == DeviceKeyPress) {
+    if (event->type == ET_KeyPress) {
         if (!k)
             return DONT_PROCESS;
 
@@ -819,7 +803,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
 	if (device->valuator)
 	    device->valuator->motionHintWindow = NullWindow;
 	*kptr |= bit;
-    } else if (xE->u.u.type == DeviceKeyRelease) {
+    } else if (event->type == ET_KeyRelease) {
         if (!k)
             return DONT_PROCESS;
 
@@ -829,7 +813,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
 	if (device->valuator)
 	    device->valuator->motionHintWindow = NullWindow;
 	*kptr &= ~bit;
-    } else if (xE->u.u.type == DeviceButtonPress) {
+    } else if (event->type == ET_ButtonPress) {
         Mask mask;
         if (!b)
             return DONT_PROCESS;
@@ -852,9 +836,8 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
         SetMaskForEvent(device->id, mask, DeviceMotionNotify);
         mask = PointerMotionMask | b->state | b->motionMask;
         SetMaskForEvent(device->id, mask, MotionNotify);
-    } else if (xE->u.u.type == DeviceButtonRelease) {
+    } else if (event->type == ET_ButtonRelease) {
         Mask mask;
-
         if (!b)
             return DONT_PROCESS;
 
@@ -891,9 +874,9 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
         SetMaskForEvent(device->id, mask, DeviceMotionNotify);
         mask = PointerMotionMask | b->state | b->motionMask;
         SetMaskForEvent(device->id, mask, MotionNotify);
-    } else if (xE->u.u.type == ProximityIn)
+    } else if (event->type == ET_ProximityIn)
 	device->valuator->mode &= ~OutOfProximity;
-    else if (xE->u.u.type == ProximityOut)
+    else if (event->type == ET_ProximityOut)
 	device->valuator->mode |= OutOfProximity;
 
     return DEFAULT;
@@ -905,7 +888,7 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
  *
  */
 void
-ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
+ProcessOtherEvent(xEventPtr ev, DeviceIntPtr device, int count)
 {
     int i;
     GrabPtr grab = device->deviceGrab.grab;
@@ -914,10 +897,16 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
     ButtonClassPtr b;
     KeyClassPtr k;
     ValuatorClassPtr v;
-    deviceValuator *xV  = (deviceValuator *) xE;
+    deviceValuator *xV;
     int ret = 0;
     int state;
     DeviceIntPtr mouse = NULL, kbd = NULL;
+    DeviceEvent *event = (DeviceEvent*)ev;
+
+    /* FIXME: temporary solution only. */
+    static int nevents;
+    static xEvent xE[1000]; /* enough bytes for the events we have atm */
+
 
     if (IsPointerDevice(device))
     {
@@ -937,10 +926,12 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
     state = (kbd) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
     state |= (mouse) ? (mouse->button->state) : 0;
 
-    ret = UpdateDeviceState(device, xE, count);
+    ret = UpdateDeviceState(device, event);
     if (ret == DONT_PROCESS)
         return;
 
+    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
+
     v = device->valuator;
     b = device->button;
     k = device->key;
@@ -967,6 +958,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
     }
 
     /* Valuator event handling */
+    xV = (deviceValuator*)xE;
     for (i = 1; i < count; i++) {
 	if ((++xV)->type == DeviceValuator)
 	    xV->device_state = state;
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index db496ee..d3dda53 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -322,11 +322,9 @@ GetXIType(InternalEvent *event)
 }
 
 /*
- * FIXME: A temporary solution to make the server bisectable. This code
- * allocates during SIGIO and makes a number of assumptions about what's in
- * events. Will be removed soon.
+ * FIXME: A temporary solution to make the server bisectable. Take the event
+ * @event and copy it into @ev, returning the number of events in @ev.
  */
-
 int
 ConvertBackToXI(InternalEvent *event, xEvent *ev)
 {
diff --git a/dix/events.c b/dix/events.c
index 43d336a..a6d601d 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1009,16 +1009,24 @@ NoticeEventTime(xEvent *xE)
  * linked list for later delivery.
  */
 void
-EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
+EnqueueEvent(xEvent *ev, DeviceIntPtr device, int count)
 {
     QdEventPtr	tail = *syncEvents.pendtail;
     QdEventPtr	qe;
     SpritePtr	pSprite = device->spriteInfo->sprite;
     int		eventlen;
+    DeviceEvent *event = (DeviceEvent*)ev;
 
+    /* FIXME: temporary solution only. */
+    static int nevents;
+    static xEvent xi[1000]; /* enough bytes for the events we have atm */
+    xEvent *xE = xi;
+
+    nevents = ConvertBackToXI((InternalEvent*)ev, xE);
 
     NoticeTime(xE);
 
+
     /* Fix for key repeating bug. */
     if (device->key != NULL && device->key->xkbInfo != NULL &&
 	xE->u.u.type == KeyRelease)
@@ -1040,7 +1048,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
 	    XE_KBPTR.root =
 		WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id;
 	eventinfo.events = xE;
-	eventinfo.count = count;
+	eventinfo.count = nevents;
 	CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
     }
     if (xE->u.u.type == DeviceMotionNotify)
@@ -1069,7 +1077,7 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
 	}
     }
 
-    eventlen = count * sizeof(xEvent);
+    eventlen = nevents * sizeof(xEvent);
     if (xE->u.u.type == GenericEvent) /* count is 1 for GenericEvents */
 	eventlen += ((xGenericEvent*)xE)->length * 4;
 
@@ -1081,14 +1089,14 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
     qe->pScreen = pSprite->hotPhys.pScreen;
     qe->months = currentTime.months;
     qe->event = (xEvent *)(qe + 1);
-    qe->evcount = count;
+    qe->evcount = nevents;
     if (xE->u.u.type == GenericEvent)
     {
 	memcpy(qe->event, xE, eventlen);
     } else
     {
 	xEvent	*qxE;
-	for (qxE = qe->event; --count >= 0; qxE++, xE++)
+	for (qxE = qe->event; --nevents >= 0; qxE++, xE++)
 	{
 	    *qxE = *xE;
 	}
diff --git a/hw/xfree86/common/xf86DGA.c b/hw/xfree86/common/xf86DGA.c
index 2f8c689..a974333 100644
--- a/hw/xfree86/common/xf86DGA.c
+++ b/hw/xfree86/common/xf86DGA.c
@@ -1047,7 +1047,10 @@ DGAProcessKeyboardEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr keybd)
     de->u.event.state |= pointer->button->state;
 
     de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */
+#if 0
+    /* FIXME: Hello. I am broken. Please fix me. Thanks. */
     UpdateDeviceState(keybd, (xEvent*)de, 1);
+#endif
     de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */
 
     /*
@@ -1095,7 +1098,10 @@ DGAProcessPointerEvent (ScreenPtr pScreen, dgaEvent *de, DeviceIntPtr mouse)
     de->u.event.state |= XkbStateFieldFromRec(&GetPairedDevice(mouse)->key->xkbInfo->state);
 
     de->u.u.type = (IEventBase - 1) + coreEquiv; /* change to XI event */
+#if 0
+    /* FIXME: Hello. I am broken. Please fix me. Thanks. */
     UpdateDeviceState(mouse, (xEvent*)de, 1);
+#endif
     de->u.u.type = *XDGAEventBase + coreEquiv; /* change back */
 
     /*
diff --git a/include/exevents.h b/include/exevents.h
index ab96902..51af9b4 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -48,8 +48,7 @@ extern _X_EXPORT void RegisterOtherDevice (
 extern _X_EXPORT int
 UpdateDeviceState (
 	DeviceIntPtr           /* device */,
-	xEventPtr              /*  xE    */,
-        int                    /* count  */);
+	DeviceEvent*           /*  xE    */);
 
 extern _X_EXPORT void ProcessOtherEvent (
 	xEventPtr /* FIXME deviceKeyButtonPointer * xE */,
diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index 8a520c6..618a18c 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -722,19 +722,10 @@ DeviceEvent     *event = (DeviceEvent*)xE;
      *          see. it's still steaming. told you. (whot)
      */
 
-    {
-        /* FIXME: temporary solution only. */
-        static int nevents;
-        static xEvent ev[1000]; /* enough bytes for the events we have atm */
-
-        nevents = ConvertBackToXI((InternalEvent*)xE, ev);
-
-
     UNWRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr, backupproc);
-    mouse->public.processInputProc(ev, mouse, nevents);
+    mouse->public.processInputProc(xE, mouse, count);
     COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr,
 				     backupproc, xkbUnwrapProc);
-    }
 
     xkbi->state.ptr_buttons = mouse->button->state;
     
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 6f5c6bc..afc42f3 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1211,20 +1211,10 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
         else
             tmpdev = GetPairedDevice(dev);
 
-        {
-
-
-        /* FIXME: temporary solution only. */
-        static int nevents;
-        static xEvent ev[1000]; /* enough bytes for the events we have atm */
-        nevents = ConvertBackToXI((InternalEvent*)event, ev);
-
         UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
-        dev->public.processInputProc(ev, tmpdev, nevents);
+        dev->public.processInputProc((xEvent*)event, tmpdev, 1);
         COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
                                      backupproc,xkbUnwrapProc);
-
-        }
     }
     else if (keyEvent) {
 	FixKeyState(event, dev);
diff --git a/xkb/xkbPrKeyEv.c b/xkb/xkbPrKeyEv.c
index 33fd098..86e9674 100644
--- a/xkb/xkbPrKeyEv.c
+++ b/xkb/xkbPrKeyEv.c
@@ -177,14 +177,8 @@ ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
 
     /* We're only interested in key events. */
     if (!is_press && !is_release) {
-        /* FIXME: temporary solution only. */
-        static int nevents;
-        static xEvent ev[1000]; /* enough bytes for the events we have atm */
-
-        nevents = ConvertBackToXI((InternalEvent*)xE, ev);
-
         UNWRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc);
-        keybd->public.processInputProc(ev, keybd, nevents);
+        keybd->public.processInputProc(xE, keybd, count);
         COND_WRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc,
                                      xkbUnwrapProc);
         return;
commit 007e93c869325cafcc29d975b356dbb8e7cd2ac1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 30 14:35:22 2009 +1000

    xkb: Switch the xkb event processing path over to InternalEvents.
    
    Before dropping down into the DIX, convert back into XI events. This is a
    temporary solution only, until the DIX is capable of handling InternalEvents
    anyway.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index 928c2f0..43d336a 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3586,26 +3586,24 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
    the device's processInputProc to be called, as in for example Mouse Keys.
 */
 void
-FixKeyState (xEvent *xE, DeviceIntPtr keybd)
+FixKeyState (DeviceEvent *event, DeviceIntPtr keybd)
 {
     int             key, bit;
     BYTE   *kptr;
     KeyClassPtr keyc = keybd->key;
 
-    key = xE->u.u.detail;
+    key = event->detail.key;
     kptr = &keyc->down[key >> 3];
     bit = 1 << (key & 7);
 
-    if (((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease)||
-         (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease))
-            ) {
+    if ((event->type == ET_KeyPress)||(event->type == ET_KeyRelease)) {
 	DebugF("FixKeyState: Key %d %s\n",key,
-               (((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress))?"down":"up"));
+               (((event->type == ET_KeyPress)||(event->type == ET_DeviceKeyPress)) ? "down" : "up"));
     }
 
-    if (xE->u.u.type == KeyPress || xE->u.u.type == DeviceKeyPress)
+    if (event->type == ET_KeyPress)
 	    *kptr |= bit;
-    else if (xE->u.u.type == KeyRelease || xE->u.u.type == DeviceKeyRelease)
+    else if (event->type == ET_KeyRelease)
 	    *kptr &= ~bit;
     else
         FatalError("Impossible keyboard event");
diff --git a/include/dix.h b/include/dix.h
index 204dcf2..0afd766 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -53,6 +53,7 @@ SOFTWARE.
 #include "input.h"
 #include "cursor.h"
 #include "geext.h"
+#include "events.h"
 #include <X11/extensions/XI.h>
 
 #define EARLIER -1
@@ -406,7 +407,7 @@ extern _X_EXPORT void DeliverGrabbedEvent(
     int /* count */);
 
 extern _X_EXPORT void FixKeyState(
-    xEvent * /* xE */,
+    DeviceEvent* /* event */,
     DeviceIntPtr /* keybd */);
 
 extern _X_EXPORT void RecalculateDeliverableEvents(
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 4497220..8a81431 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -56,6 +56,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "xkbstr.h"
 #include "xkbrules.h"
 #include "inputstr.h"
+#include "events.h"
 
 typedef struct _XkbInterest {
 	DeviceIntPtr		dev;
@@ -709,16 +710,14 @@ extern _X_EXPORT void XkbSendNotification(
 );
 
 extern _X_EXPORT void XkbProcessKeyboardEvent(
-    struct _xEvent * 		/* xE */,
-    DeviceIntPtr		/* keybd */,
-    int 			/* count */
+    DeviceEvent*		/* event */,
+    DeviceIntPtr		/* keybd */
 );
 
 extern _X_EXPORT void XkbHandleActions(
     DeviceIntPtr		/* dev */,
     DeviceIntPtr		/* kbd */,
-    struct _xEvent * 		/* xE */,
-    int 			/* count */
+    DeviceEvent*		/* event */
 );
 
 extern _X_EXPORT Bool XkbEnableDisableControls(
@@ -734,15 +733,13 @@ extern _X_EXPORT void AccessXInit(
 );
 
 extern _X_EXPORT Bool AccessXFilterPressEvent(
-    struct _xEvent *	/* xE */,
-    DeviceIntPtr	/* keybd */,
-    int				/* count */
+    DeviceEvent*	/* event */,
+    DeviceIntPtr	/* keybd */
 );
 
 extern _X_EXPORT Bool AccessXFilterReleaseEvent(
-    struct _xEvent *	/* xE */,
-    DeviceIntPtr	/* keybd */,
-    int				/* count */
+    DeviceEvent*	/* event */,
+    DeviceIntPtr	/* keybd */
 );
 
 extern _X_EXPORT void AccessXCancelRepeatKey(
diff --git a/mi/mieq.c b/mi/mieq.c
index 7744b9a..a3e58a3 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -400,20 +400,11 @@ mieqProcessInputEvents(void)
                             masterEvents->event, master, 1);
             } else
             {
-                /* FIXME: temporary solution only. */
-                static int nevents;
-                static xEvent xE[1000]; /* enough bytes for the events we have atm */
-
-                nevents = ConvertBackToXI(event, xE);
-
                 /* process slave first, then master */
-                dev->public.processInputProc(xE, dev, nevents);
+                dev->public.processInputProc(event, dev, 1);
 
                 if (master)
-                {
-                    nevents = ConvertBackToXI((InternalEvent*)masterEvents->event, xE);
-                    master->public.processInputProc(xE, master, nevents);
-                }
+                    master->public.processInputProc(masterEvents->event, master, 1);
             }
         }
 
diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index c7f7439..8a520c6 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -119,22 +119,26 @@ XkbControlsPtr	ctrls = xkbi->desc->ctrls;
 /************************************************************************/
 static void 
 AccessXKeyboardEvent(DeviceIntPtr	keybd,
-				 BYTE		type,
+				 int		type,
 				 BYTE		keyCode,
 				 Bool		isRepeat)
 {
-xEvent		xE;
-    
-    xE.u.u.type = type;
-    xE.u.u.detail = keyCode;
-    xE.u.keyButtonPointer.time = GetTimeInMillis();	    
+    DeviceEvent event;
+    memset(&event, 0, sizeof(DeviceEvent));
+    event.header = ET_Internal;
+    event.type = type;
+    event.detail.key = keyCode;
+    event.time = GetTimeInMillis();
+    event.length = sizeof(DeviceEvent);
+
     if (xkbDebugFlags&0x8) {
-	DebugF("[xkb] AXKE: Key %d %s\n",keyCode,(xE.u.u.type==KeyPress?"down":"up"));
+	DebugF("[xkb] AXKE: Key %d %s\n", keyCode,
+               (event->type == ET_KeyPress ? "down" : "up"));
     }
 
     if (!_XkbIsPressEvent(type) && isRepeat)
-	XkbLastRepeatEvent=	(pointer)&xE;
-    XkbProcessKeyboardEvent(&xE,keybd,1L);
+	XkbLastRepeatEvent=	(pointer)&event;
+    XkbProcessKeyboardEvent(&event, keybd);
     XkbLastRepeatEvent= NULL;
     return;
     
@@ -310,8 +314,8 @@ KeyCode		key;
 	return 0;
 
     key = xkbi->repeatKey;
-    AccessXKeyboardEvent(dev, DeviceKeyRelease, key, True);
-    AccessXKeyboardEvent(dev, DeviceKeyPress, key, True);
+    AccessXKeyboardEvent(dev, ET_KeyRelease, key, True);
+    AccessXKeyboardEvent(dev, ET_KeyPress, key, True);
 
     return xkbi->desc->ctrls->repeat_interval;
 }
@@ -346,7 +350,7 @@ XkbControlsPtr	ctrls;
 	XkbSendAccessXNotify(keybd,&ev);
 	if (XkbAX_NeedFeedback(ctrls,XkbAX_SKAcceptFBMask))
 	    XkbDDXAccessXBeep(keybd,_BEEP_SLOW_ACCEPT,XkbSlowKeysMask);
-	AccessXKeyboardEvent(keybd,DeviceKeyPress,xkbi->slowKey,False);
+	AccessXKeyboardEvent(keybd, ET_KeyPress,xkbi->slowKey,False);
 	/* check for magic sequences */
 	if ((ctrls->enabled_ctrls&XkbAccessXKeysMask) &&
 	    ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L)))
@@ -442,14 +446,13 @@ XkbSrvLedInfoPtr	sli;
 /*									*/
 /************************************************************************/
 Bool
-AccessXFilterPressEvent(	register xEvent *	xE, 
-				register DeviceIntPtr	keybd, 
-				int			count)
+AccessXFilterPressEvent(	DeviceEvent*	event,
+				DeviceIntPtr	keybd)
 {
 XkbSrvInfoPtr	xkbi = keybd->key->xkbInfo;
 XkbControlsPtr	ctrls = xkbi->desc->ctrls;
 Bool		ignoreKeyEvent = FALSE;
-KeyCode		key = xE->u.u.detail;
+KeyCode		key = event->detail.key;
 KeySym *	sym = XkbKeySymsPtr(xkbi->desc,key);
 
     if (ctrls->enabled_ctrls&XkbAccessXKeysMask) {
@@ -555,7 +558,7 @@ KeySym *	sym = XkbKeySymsPtr(xkbi->desc,key);
     }
     
     if (!ignoreKeyEvent)
-	XkbProcessKeyboardEvent(xE,keybd,count);
+	XkbProcessKeyboardEvent(event, keybd);
     return ignoreKeyEvent;
 } /* AccessXFilterPressEvent */
 
@@ -572,13 +575,12 @@ KeySym *	sym = XkbKeySymsPtr(xkbi->desc,key);
 /*									*/
 /************************************************************************/
 Bool
-AccessXFilterReleaseEvent(	register xEvent *	xE, 
-				register DeviceIntPtr	keybd, 
-				int			count)
+AccessXFilterReleaseEvent(	DeviceEvent*	event,
+				DeviceIntPtr	keybd)
 {
 XkbSrvInfoPtr	xkbi = keybd->key->xkbInfo;
 XkbControlsPtr	ctrls = xkbi->desc->ctrls;
-KeyCode		key = xE->u.u.detail;
+KeyCode		key = event->detail.key;
 Bool		ignoreKeyEvent = FALSE;
     
     /* Don't transmit the KeyRelease if BounceKeys is on and
@@ -664,7 +666,7 @@ Bool		ignoreKeyEvent = FALSE;
     }
     
     if (!ignoreKeyEvent)
-	XkbProcessKeyboardEvent(xE,keybd,count);
+	XkbProcessKeyboardEvent(event, keybd);
     return ignoreKeyEvent;
     
 } /* AccessXFilterReleaseEvent */
@@ -691,16 +693,16 @@ XkbSrvInfoPtr	xkbi = dev->key->xkbInfo;
 unsigned 	changed = 0;
 ProcessInputProc backupproc;
 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(mouse);
-deviceKeyButtonPointer *kbp = xE;
+DeviceEvent     *event = (DeviceEvent*)xE;
 
     xkbi->shiftKeyCount = 0;
-    xkbi->lastPtrEventTime= kbp->time;
+    xkbi->lastPtrEventTime= event->time;
 
-    if (xE->u.u.type==DeviceButtonPress) {
+    if (event->type == ET_ButtonPress) {
 	    changed |= XkbPointerButtonMask;
     }
-    else if (xE->u.u.type==DeviceButtonRelease) {
-	xkbi->lockedPtrButtons&= ~(1<<(kbp->detail&0x7));
+    else if (event->type == ET_ButtonRelease) {
+	xkbi->lockedPtrButtons&= ~(1 << (event->detail.key & 0x7));
 	changed |= XkbPointerButtonMask;
     }
 
@@ -719,15 +721,25 @@ deviceKeyButtonPointer *kbp = xE;
      *
      *          see. it's still steaming. told you. (whot)
      */
+
+    {
+        /* FIXME: temporary solution only. */
+        static int nevents;
+        static xEvent ev[1000]; /* enough bytes for the events we have atm */
+
+        nevents = ConvertBackToXI((InternalEvent*)xE, ev);
+
+
     UNWRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr, backupproc);
-    mouse->public.processInputProc(xE, mouse, count);
+    mouse->public.processInputProc(ev, mouse, nevents);
     COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr,
 				     backupproc, xkbUnwrapProc);
+    }
 
     xkbi->state.ptr_buttons = mouse->button->state;
     
     /* clear any latched modifiers */
-    if ( xkbi->state.latched_mods && (kbp->type==DeviceButtonRelease) ) {
+    if ( xkbi->state.latched_mods && (event->type == ET_ButtonRelease) ) {
 	unsigned 		changed_leds;
 	XkbStateRec		oldState;
 	XkbSrvLedInfoPtr	sli;
@@ -742,7 +754,7 @@ deviceKeyButtonPointer *kbp = xE;
 	    changed_leds= XkbIndicatorsToUpdate(dev,changed,False);
 	    if (changed_leds) {
 		XkbEventCauseRec	cause;
-		XkbSetCauseKey(&cause,(kbp->detail&0x7),kbp->type);
+		XkbSetCauseKey(&cause,(event->detail.key & 0x7), event->type);
 		XkbUpdateIndicators(dev,changed_leds,True,NULL,&cause);
 	    }
 	}
@@ -750,8 +762,8 @@ deviceKeyButtonPointer *kbp = xE;
 
     if (((xkbi->flags&_XkbStateNotifyInProgress)==0)&&(changed!=0)) {
 	xkbStateNotify	sn;
-	sn.keycode= kbp->detail;
-	sn.eventType= kbp->type;
+	sn.keycode= event->detail.key;
+	sn.eventType= event->type;
 	sn.requestMajor = sn.requestMinor = 0;
 	sn.changed= changed;
 	XkbSendStateNotify(dev,&sn);
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 9a138b0..6f5c6bc 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1068,7 +1068,7 @@ register int	i,send;
 }
 
 void
-XkbHandleActions(DeviceIntPtr dev,DeviceIntPtr kbd,xEvent *xE,int count)
+XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event)
 {
 int		key,bit,i;
 XkbSrvInfoPtr	xkbi;
@@ -1086,7 +1086,7 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
 
     keyc= kbd->key;
     xkbi= keyc->xkbInfo;
-    key= xE->u.u.detail;
+    key= event->detail.key;
     /* 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) {
@@ -1100,10 +1100,8 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
     xkbi->groupChange = 0;
 
     sendEvent = 1;
-    keyEvent= ((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
-		(xE->u.u.type==KeyRelease)||(xE->u.u.type==DeviceKeyRelease));
-    pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
-		 (xE->u.u.type==ButtonPress)||(xE->u.u.type==DeviceButtonPress);
+    keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
+    pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress));
 
     if (pressEvent) {
 	if (keyEvent)	
@@ -1213,13 +1211,23 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
         else
             tmpdev = GetPairedDevice(dev);
 
+        {
+
+
+        /* FIXME: temporary solution only. */
+        static int nevents;
+        static xEvent ev[1000]; /* enough bytes for the events we have atm */
+        nevents = ConvertBackToXI((InternalEvent*)event, ev);
+
         UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
-        dev->public.processInputProc(xE,tmpdev,count);
+        dev->public.processInputProc(ev, tmpdev, nevents);
         COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
                                      backupproc,xkbUnwrapProc);
+
+        }
     }
     else if (keyEvent) {
-	FixKeyState(xE,dev);
+	FixKeyState(event, dev);
     }
 
     xkbi->prev_state= oldState;
@@ -1229,7 +1237,7 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
 	if (changed) {
 	    xkbStateNotify	sn;
 	    sn.keycode= key;
-	    sn.eventType= xE->u.u.type;
+	    sn.eventType= event->type;
 	    sn.requestMajor = sn.requestMinor = 0;
 	    sn.changed= changed;
 	    XkbSendStateNotify(dev,&sn);
@@ -1239,7 +1247,7 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
     changed= XkbIndicatorsToUpdate(dev,changed,False);
     if (changed) {
 	XkbEventCauseRec	cause;
-	XkbSetCauseKey(&cause,key,xE->u.u.type);
+	XkbSetCauseKey(&cause, key, event->type);
 	XkbUpdateIndicators(dev,changed,False,NULL,&cause);
     }
     return;
diff --git a/xkb/xkbPrKeyEv.c b/xkb/xkbPrKeyEv.c
index badfb14..33fd098 100644
--- a/xkb/xkbPrKeyEv.c
+++ b/xkb/xkbPrKeyEv.c
@@ -38,11 +38,12 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "exevents.h"
 #include <xkbsrv.h>
 #include <ctype.h>
+#include "events.h"
 
 /***====================================================================***/
 
 void
-XkbProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
+XkbProcessKeyboardEvent(DeviceEvent *event, DeviceIntPtr keybd)
 {
 KeyClassPtr	keyc = keybd->key;
 XkbSrvInfoPtr	xkbi;
@@ -51,12 +52,12 @@ XkbBehavior	behavior;
 unsigned        ndx;
 
     xkbi= keyc->xkbInfo;
-    key= xE->u.u.detail;
+    key= event->detail.key;
     if (xkbDebugFlags&0x8) {
-	DebugF("[xkb] XkbPKE: Key %d %s\n",key,(xE->u.u.type==DeviceKeyPress?"down":"up"));
+	DebugF("[xkb] XkbPKE: Key %d %s\n",key,(event->type == ET_KeyPress?"down":"up"));
     }
 
-    if ( (xkbi->repeatKey==key) && (xE->u.u.type==DeviceKeyRelease) &&
+    if ( (xkbi->repeatKey==key) && (event->type== ET_KeyRelease) &&
 	 ((xkbi->desc->ctrls->enabled_ctrls&XkbRepeatKeysMask)==0) ) {
 	AccessXCancelRepeatKey(xkbi,key);
     }
@@ -70,37 +71,37 @@ unsigned        ndx;
     if ((behavior.type&XkbKB_Permanent)==0) {
 	switch (behavior.type) {
 	    case XkbKB_Default:
-		if (xE->u.u.type == DeviceKeyPress && 
+		if (event->type == ET_KeyPress &&
 		    (keyc->down[key>>3] & (1<<(key&7)))) {
-		    XkbLastRepeatEvent=	(pointer)xE;
+		    XkbLastRepeatEvent=	(pointer)event;
 
-                    xE->u.u.type = DeviceKeyRelease;
-		    XkbHandleActions(keybd,keybd,xE,count);
+		    event->type = ET_KeyRelease;
+		    XkbHandleActions(keybd, keybd, event);
 
-                    xE->u.u.type = DeviceKeyPress;
-		    XkbHandleActions(keybd,keybd,xE,count);
+		    event->type = ET_KeyPress;
+		    XkbHandleActions(keybd, keybd, event);
 		    XkbLastRepeatEvent= NULL;
 		    return;
 		}
-		else if (xE->u.u.type==DeviceKeyRelease &&
+		else if (event->type == ET_KeyRelease &&
 			(!(keyc->down[key>>3]&(1<<(key&7))))) {
-		    XkbLastRepeatEvent=	(pointer)&xE;
-                    xE->u.u.type = DeviceKeyPress;
-		    XkbHandleActions(keybd,keybd,xE,count);
-                    xE->u.u.type = DeviceKeyRelease;
-		    XkbHandleActions(keybd,keybd,xE,count);
+		    XkbLastRepeatEvent=	(pointer)event;
+		    event->type = ET_KeyPress;
+		    XkbHandleActions(keybd, keybd, event);
+		    event->type = ET_KeyRelease;
+		    XkbHandleActions(keybd, keybd, event);
 		    XkbLastRepeatEvent= NULL;
 		    return;
 		}
 		break;
 	    case XkbKB_Lock:
-		if (xE->u.u.type == DeviceKeyRelease) {
+		if (event->type == ET_KeyRelease) {
 		    return;
                 }
 		else {
 		    int	bit= 1<<(key&7);
 		    if ( keyc->down[key>>3]&bit ) {
-                        xE->u.u.type = DeviceKeyRelease;
+			event->type = ET_KeyRelease;
                     }
                 }
 		break;
@@ -109,25 +110,25 @@ unsigned        ndx;
 		if ( ndx<xkbi->nRadioGroups ) {
 		    XkbRadioGroupPtr	rg;
 
-		    if (xE->u.u.type == DeviceKeyRelease)
+		    if (event->type == ET_KeyRelease)
 		        return;
 
 		    rg = &xkbi->radioGroups[ndx];
-		    if ( rg->currentDown == xE->u.u.detail ) {
+		    if ( rg->currentDown == event->detail.key) {
 		        if (behavior.data&XkbKB_RGAllowNone) {
-		            xE->u.u.type = DeviceKeyRelease;
-			    XkbHandleActions(keybd,keybd,xE,count);
+		            event->type = ET_KeyRelease;
+			    XkbHandleActions(keybd, keybd, event);
 			    rg->currentDown= 0;
 		        }
 		        return;
 		    }
 		    if ( rg->currentDown!=0 ) {
-			int key = xE->u.u.detail;
-                        xE->u.u.type = DeviceKeyRelease;
-			xE->u.u.detail= rg->currentDown;
-		        XkbHandleActions(keybd,keybd,xE,count);
-                        xE->u.u.type = DeviceKeyPress;
-		        xE->u.u.detail= key;
+			int key = event->detail.key;
+			event->type = ET_KeyRelease;
+			event->detail.key = rg->currentDown;
+			XkbHandleActions(keybd, keybd, event);
+			event->type = ET_KeyPress;
+			event->detail.key = key;
 		    }
 		    rg->currentDown= key;
 		}
@@ -142,7 +143,7 @@ unsigned        ndx;
 			break;
 		    if ((behavior.data>=xkbi->desc->min_key_code)&&
 			(behavior.data<=xkbi->desc->max_key_code)) {
-			xE->u.u.detail= behavior.data;
+                        event->detail.key = behavior.data;
 			/* 9/11/94 (ef) -- XXX! need to match release with */
 			/*                 press even if the state of the  */
 			/*                 corresponding overlay control   */
@@ -155,7 +156,7 @@ unsigned        ndx;
 		break;
 	}
     }
-    XkbHandleActions(keybd,keybd,xE,count);
+    XkbHandleActions(keybd, keybd, event);
     return;
 }
 
@@ -167,16 +168,23 @@ ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
     XkbSrvInfoPtr xkbi = NULL;
     ProcessInputProc backup_proc;
     xkbDeviceInfoPtr xkb_priv = XKBDEVICEINFO(keybd);
-    int is_press = (xE->u.u.type == DeviceKeyPress);
-    int is_release = (xE->u.u.type == DeviceKeyRelease);
+    DeviceEvent *event = (DeviceEvent*)xE;
+    int is_press = (event->type == ET_KeyPress);
+    int is_release = (event->type == ET_KeyRelease);
 
     if (keyc)
         xkbi = keyc->xkbInfo;
 
     /* We're only interested in key events. */
     if (!is_press && !is_release) {
+        /* FIXME: temporary solution only. */
+        static int nevents;
+        static xEvent ev[1000]; /* enough bytes for the events we have atm */
+
+        nevents = ConvertBackToXI((InternalEvent*)xE, ev);
+
         UNWRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc);
-        keybd->public.processInputProc(xE, keybd, count);
+        keybd->public.processInputProc(ev, keybd, nevents);
         COND_WRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc,
                                      xkbUnwrapProc);
         return;
@@ -190,12 +198,12 @@ ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
      * they'll punt through XPKE anyway. */
     if ((xkbi->desc->ctrls->enabled_ctrls & XkbAllFilteredEventsMask)) {
         if (is_press)
-            AccessXFilterPressEvent(xE, keybd, count);
+            AccessXFilterPressEvent(event, keybd);
         else if (is_release)
-            AccessXFilterReleaseEvent(xE, keybd, count);
+            AccessXFilterReleaseEvent(event, keybd);
 
     } else {
-        XkbProcessKeyboardEvent(xE, keybd, count);
+        XkbProcessKeyboardEvent(event, keybd);
     }
 
     return;
commit 64ea6078105f73d1b727619fc123920bc7e4a06c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Feb 2 14:15:52 2009 +1000

    dix: change eventconvert to always return an array of xEvents
    
    Just alloc the memory on demand rather than doing things with EventListPtrs
    etc.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 439d264..db496ee 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -44,9 +44,9 @@
 #include "listdev.h"
 
 static int countValuators(DeviceEvent *ev, int *first);
-static int getValuatorEvents(DeviceEvent *ev, EventListPtr xi);
-static int eventToKeyButtonPointer(DeviceEvent *ev, EventListPtr xi, int *count);
-static int eventToClassesChanged(DeviceChangedEvent *ev, EventListPtr dcce,
+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);
 
 /**
@@ -97,24 +97,15 @@ EventToCore(InternalEvent *event, xEvent *core)
 
 /**
  * Convert the given event @ev to the respective XI 1.x event and store it in
- * @xi. @xi must be allocated by the caller, @count specifies the number of
- * events in @xi.
- *
- *
- * If less than @count events are needed, @count is set to the events stored
- * in @xi and Success is returned.
- *
- * If more than @count events are needed, @count is set to the number of
- * events required, and BadAlloc is returned. @xi is untouched.
- *
- * If necessary, @xi is realloced using SetMinimumEventSize() to fit the
- * largest event being returned.
+ * @xi. @xi is allocated on demand and must be freed by the caller.
+ * @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.
  */
 int
-EventToXI(InternalEvent *ev, EventListPtr xi, int *count)
+EventToXI(InternalEvent *ev, xEvent **xi, int *count)
 {
     switch (ev->u.any.type)
     {
@@ -136,7 +127,7 @@ EventToXI(InternalEvent *ev, EventListPtr xi, int *count)
 }
 
 static int
-eventToKeyButtonPointer(DeviceEvent *ev, EventListPtr xi, int *count)
+eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
 {
     int num_events;
     int first; /* dummy */
@@ -152,15 +143,13 @@ eventToKeyButtonPointer(DeviceEvent *ev, EventListPtr xi, int *count)
     num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
     num_events++; /* the actual event event */
 
-    if (*count < num_events)
+    *xi = xcalloc(num_events, sizeof(xEvent));
+    if (!(*xi))
     {
-        *count = num_events;
         return BadAlloc;
     }
 
-    SetMinimumEventSize(xi, *count, 32);
-
-    kbp = (deviceKeyButtonPointer*)xi->event;
+    kbp           = (deviceKeyButtonPointer*)(*xi);
     kbp->detail   = ev->detail.button;
     kbp->time     = ev->time;
     kbp->root     = ev->root;
@@ -183,10 +172,9 @@ eventToKeyButtonPointer(DeviceEvent *ev, EventListPtr xi, int *count)
         case ET_ProximityOut:  kbp->type = ProximityOut;        break;
     }
 
-
     if (num_events > 1)
     {
-        getValuatorEvents(ev, xi + 1);
+        getValuatorEvents(ev, (deviceValuator*)(kbp + 1));
     }
 
     *count = num_events;
@@ -224,17 +212,15 @@ countValuators(DeviceEvent *ev, int *first)
 }
 
 static int
-getValuatorEvents(DeviceEvent *ev, EventListPtr events)
+getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
 {
     int i;
-    deviceValuator *xv;
     int first_valuator, num_valuators;
 
     num_valuators = countValuators(ev, &first_valuator);
 
     /* FIXME: non-continuous valuator data in internal events*/
-    for (i = 0; i < num_valuators; i += 6, events++) {
-        xv = (deviceValuator*)events->event;
+    for (i = 0; i < num_valuators; i += 6, xv++) {
         xv->type = DeviceValuator;
         xv->first_valuator = first_valuator + i;
         xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
@@ -262,13 +248,14 @@ getValuatorEvents(DeviceEvent *ev, EventListPtr events)
 }
 
 static int
-eventToClassesChanged(DeviceChangedEvent *ev, EventListPtr events, int *count)
+eventToClassesChanged(DeviceChangedEvent *ev, xEvent **xi, int *count)
 {
     int len = sizeof(xEvent);
     int namelen = 0; /* dummy */
     DeviceIntPtr slave;
     int rc;
-    deviceClassesChangedEvent *dcce = (deviceClassesChangedEvent*)events->event;
+    deviceClassesChangedEvent *dcce;
+
 
     rc = dixLookupDevice(&slave, ev->new_slaveid,
                          serverClient, DixReadAccess);
@@ -278,6 +265,11 @@ eventToClassesChanged(DeviceChangedEvent *ev, EventListPtr events, int *count)
 
     SizeDeviceInfo(slave, &namelen, &len);
 
+    *xi = xcalloc(1, len);
+    if (!(*xi))
+        return BadAlloc;
+
+    dcce = (deviceClassesChangedEvent*)(*xi);
     dcce->type = GenericEvent;
     dcce->extension = IReqCode;
     dcce->evtype = XI_DeviceClassesChangedNotify;
@@ -338,21 +330,19 @@ GetXIType(InternalEvent *event)
 int
 ConvertBackToXI(InternalEvent *event, xEvent *ev)
 {
-    int count = GetMaximumEventsNum();
+    int count = 0;
     int evlen, i;
+    xEvent *xi =  NULL;
 
-    EventListPtr tmp_list = InitEventList(count);
-
-    SetMinimumEventSize(tmp_list, count, 1000); /* just to be sure */
 
-    if (EventToXI(event, tmp_list, &count))
+    if (EventToXI(event, &xi, &count))
         ErrorF("[dix] conversion to XI failed\n");
 
-    if (tmp_list->event->u.u.type == GenericEvent)
-        evlen = (GEV(tmp_list->event))->length * 4 + 32;
+    if (xi->u.u.type == GenericEvent)
+        evlen = (GEV(xi))->length * 4 + 32;
     else
         evlen = count *  32;
     for (i = 0; i < count; i++)
-        memcpy(&ev[i], (tmp_list + i)->event, evlen);
+        memcpy(&ev[i], &xi[i], evlen);
     return count;
 }
diff --git a/include/eventconvert.h b/include/eventconvert.h
index 8463831..1ff6495 100644
--- a/include/eventconvert.h
+++ b/include/eventconvert.h
@@ -29,7 +29,7 @@
 #include "events.h"
 
 _X_INTERNAL int EventToCore(InternalEvent *event, xEvent *core);
-_X_INTERNAL int EventToXI(InternalEvent *ev, EventListPtr xi, int *count);
+_X_INTERNAL int EventToXI(InternalEvent *ev, xEvent **xi, int *count);
 _X_INTERNAL int GetCoreType(InternalEvent* ev);
 _X_INTERNAL int GetXIType(InternalEvent* ev);
 
commit 4026c63e4eb16481bafc1a41ad67cd2556728d40
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 30 14:34:02 2009 +1000

    mi: switch the EQ to contain InternalEvents only.
    
    This gets rid of the nevents parameter, InternalEvents are always a single
    item per event. Also remove the special DeviceValuator handling in both
    enqueueing and dequeueing.
    
    Custom callback handlers are now broken until fixed.
    
    For bisectability, we copy the InternalEvent back into the XI required during
    POE and friends. Consider this a temporary solution.
    
    Note: Because of misc linker bonghits, Xvfb won't link in this revision.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 31fb47b..439d264 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -334,28 +334,25 @@ GetXIType(InternalEvent *event)
  * allocates during SIGIO and makes a number of assumptions about what's in
  * events. Will be removed soon.
  */
-static int
-ConvertBackToXI(EventListPtr events, int num_events)
+
+int
+ConvertBackToXI(InternalEvent *event, xEvent *ev)
 {
     int count = GetMaximumEventsNum();
-    int num = (num_events == 2) ? 1 : 0;
-    int i;
+    int evlen, i;
+
     EventListPtr tmp_list = InitEventList(count);
 
     SetMinimumEventSize(tmp_list, count, 1000); /* just to be sure */
 
-    if (num_events == 2) /* DCCE Event? */
-    {
-        if (EventToXI(events->event, tmp_list, &count))
-            ErrorF("[dix] conversion to XI failed\n");
-        memcpy(events->event, tmp_list->event, events->evlen);
-        events++;
-    }
-
-    if (EventToXI(events->event, tmp_list, &count))
+    if (EventToXI(event, tmp_list, &count))
         ErrorF("[dix] conversion to XI failed\n");
 
+    if (tmp_list->event->u.u.type == GenericEvent)
+        evlen = (GEV(tmp_list->event))->length * 4 + 32;
+    else
+        evlen = count *  32;
     for (i = 0; i < count; i++)
-        memcpy((events + i)->event, (tmp_list + i)->event, events->evlen);
-    return (count + num);
+        memcpy(&ev[i], (tmp_list + i)->event, evlen);
+    return count;
 }
diff --git a/dix/getevents.c b/dix/getevents.c
index 61cea28..c992c20 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -879,9 +879,6 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     set_valuators(pDev, event, first_valuator, num_valuators, valuators);
 
-    /* XXX: temporary only */
-    numEvents = ConvertBackToXI(events - (numEvents - 1), numEvents);
-
     return numEvents;
 }
 
@@ -1060,8 +1057,6 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     set_valuators(pDev, event, first_valuator, num_valuators, valuators);
 
-    /* XXX: temporary only */
-    num_events = ConvertBackToXI(events - (num_events - 1), num_events);
 
     return num_events;
 }
@@ -1112,9 +1107,6 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     set_valuators(pDev, event, first_valuator, num_valuators, valuators);
 
-    /* XXX: temporary only */
-    num_events = ConvertBackToXI(events - (num_events - 1), num_events);
-
     return num_events;
 }
 
diff --git a/include/input.h b/include/input.h
index 1804235..faa8d52 100644
--- a/include/input.h
+++ b/include/input.h
@@ -108,7 +108,9 @@ typedef struct _EventList {
     int evlen; /* length of allocated memory for event in bytes.  This is not
                   the actual length of the event. The event's actual length is
                   32 for standard events or 32 +
-                  ((xGenericEvent*)event)->length * 4 for GenericEvents */
+                  ((xGenericEvent*)event)->length * 4 for GenericEvents.
+                  For events in the EQ, the length is
+                  ((InternalEvent*)event)->u.any.length */
 } EventList, *EventListPtr;
 
 /* The DIX stores incoming input events in this list */
diff --git a/mi/mi.h b/mi/mi.h
index c44ff06..570aa60 100644
--- a/mi/mi.h
+++ b/mi/mi.h
@@ -57,6 +57,7 @@ SOFTWARE.
 #include "cursor.h"
 #include "privates.h"
 #include "colormap.h"
+#include "events.h"
 
 #define MiBits	CARD32
 
@@ -201,7 +202,7 @@ extern _X_EXPORT void mieqResizeEvents(
 
 extern _X_EXPORT void mieqEnqueue(
     DeviceIntPtr /*pDev*/,
-    xEventPtr /*e*/
+    InternalEvent* /*e*/
 );
 
 extern _X_EXPORT void mieqSwitchScreen(
diff --git a/mi/mieq.c b/mi/mieq.c
index 8a329f5..7744b9a 100644
--- a/mi/mieq.c
+++ b/mi/mieq.c
@@ -65,7 +65,6 @@ in this Software without prior written authorization from The Open Group.
 
 typedef struct _Event {
     EventListPtr    events;
-    int             nevents;
     ScreenPtr	    pScreen;
     DeviceIntPtr    pDev; /* device this event _originated_ from */
 } EventRec, *EventPtr;
@@ -112,7 +111,7 @@ mieqInit(void)
         miEventQueue.handlers[i] = NULL;
     for (i = 0; i < QUEUE_SIZE; i++)
     {
-        EventListPtr evlist = InitEventList(1 + MAX_VALUATOR_EVENTS);
+        EventListPtr evlist = InitEventList(1);
         if (!evlist)
             FatalError("Could not allocate event queue.\n");
         miEventQueue.events[i].events = evlist;
@@ -139,7 +138,7 @@ mieqResizeEvents(int min_size)
     int i;
 
     for (i = 0; i < QUEUE_SIZE; i++)
-        SetMinimumEventSize(miEventQueue.events[i].events, 7, min_size);
+        SetMinimumEventSize(miEventQueue.events[i].events, 1, min_size);
 }
 
 /*
@@ -150,12 +149,13 @@ mieqResizeEvents(int min_size)
  */
 
 void
-mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
+mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
 {
     unsigned int           oldtail = miEventQueue.tail;
     EventListPtr           evt;
     int                    isMotion = 0;
     int                    evlen;
+    Time                   time;
 
 #ifdef XQUARTZ
     wait_for_server_init();
@@ -163,50 +163,8 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
 #endif
 
     /* avoid merging events from different devices */
-    if (e->u.u.type == MotionNotify)
+    if (e->u.any.type == ET_Motion)
         isMotion = pDev->id;
-    else if (e->u.u.type == DeviceMotionNotify)
-        isMotion = pDev->id | (1 << 8); /* flag to indicate DeviceMotion */
-
-    /* We silently steal valuator events: just tack them on to the last
-     * motion event they need to be attached to.  Sigh. */
-    if (e->u.u.type == DeviceValuator) {
-        deviceValuator         *v = (deviceValuator *) e;
-        EventPtr               laste;
-        deviceKeyButtonPointer *lastkbp;
-
-        laste = &miEventQueue.events[(oldtail - 1) % QUEUE_SIZE];
-        lastkbp = (deviceKeyButtonPointer *) laste->events->event;
-
-        if (laste->nevents > 6) {
-#ifdef XQUARTZ
-            pthread_mutex_unlock(&miEventQueueMutex);
-#endif
-            
-            ErrorF("[mi] mieqEnqueue: more than six valuator events; dropping.\n");
-            return;
-        }
-        if (oldtail == miEventQueue.head ||
-            !(lastkbp->type == DeviceMotionNotify ||
-              lastkbp->type == DeviceButtonPress ||
-              lastkbp->type == DeviceButtonRelease ||
-              lastkbp->type == ProximityIn ||
-              lastkbp->type == ProximityOut) ||
-            ((lastkbp->deviceid & DEVICE_BITS) !=
-             (v->deviceid & DEVICE_BITS))) {
-#ifdef XQUARTZ
-            pthread_mutex_unlock(&miEventQueueMutex);
-#endif
-            ErrorF("[mi] mieqEnequeue: out-of-order valuator event; dropping.\n");
-            return;
-        }
-
-        memcpy((laste->events[laste->nevents++].event), e, sizeof(xEvent));
-#ifdef XQUARTZ
-        pthread_mutex_unlock(&miEventQueueMutex);
-#endif
-        return;
-    }
 
     if (isMotion && isMotion == miEventQueue.lastMotion &&
         oldtail != miEventQueue.head) {
@@ -232,10 +190,7 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
 	stuck = 0;
     }
 
-    evlen = sizeof(xEvent);
-    if (e->u.u.type == GenericEvent)
-        evlen += ((xGenericEvent*)e)->length * 4;
-
+    evlen = e->u.any.length;
     evt = miEventQueue.events[oldtail].events;
     if (evt->evlen < evlen)
     {
@@ -252,16 +207,15 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
     }
 
     memcpy(evt->event, e, evlen);
-    miEventQueue.events[oldtail].nevents = 1;
 
+    time = e->u.any.time;
     /* Make sure that event times don't go backwards - this
      * is "unnecessary", but very useful. */
-    if (e->u.u.type != GenericEvent &&
-        e->u.keyButtonPointer.time < miEventQueue.lastEventTime &&
-            miEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000)
-        evt->event->u.keyButtonPointer.time = miEventQueue.lastEventTime;
+    if (time < miEventQueue.lastEventTime &&
+        miEventQueue.lastEventTime - time < 10000)
+        e->u.any.time = miEventQueue.lastEventTime;
 
-    miEventQueue.lastEventTime = evt->event->u.keyButtonPointer.time;
+    miEventQueue.lastEventTime = ((InternalEvent*)evt->event)->u.any.time;
     miEventQueue.events[oldtail].pScreen = EnqueueScreen(pDev);
     miEventQueue.events[oldtail].pDev = pDev;
 
@@ -306,44 +260,41 @@ mieqSetHandler(int event, mieqHandler handler)
  * Change the device id of the given event to the given device's id.
  */
 static void
-ChangeDeviceID(DeviceIntPtr dev, xEvent* event)
+ChangeDeviceID(DeviceIntPtr dev, InternalEvent* event)
 {
-    int type = event->u.u.type;
-
-    if (type == DeviceKeyPress || type == DeviceKeyRelease ||
-            type == DeviceButtonPress || type == DeviceButtonRelease ||
-            type == DeviceMotionNotify || type == ProximityIn ||
-            type == ProximityOut)
-        ((deviceKeyButtonPointer*)event)->deviceid = dev->id;
-    else if (type == DeviceValuator)
-        ((deviceValuator*)event)->deviceid = dev->id;
-    else if (type == GenericEvent)
+    switch(event->u.any.type)
     {
-        /* FIXME: need to put something into XGE to make this saner */
-        if (GEIsType(event, IReqCode, XI_DeviceClassesChangedNotify))
-        {
-            // do nothing or drink a beer. your choice.
-        } else
-            DebugF("[mi] Unknown generic event (%d/%d), cannot change id.\n",
-                    ((xGenericEvent*)event)->extension,
-                    ((xGenericEvent*)event)->evtype);
-    } else
-        DebugF("[mi] Unknown event type (%d), cannot change id.\n", type);
+        case ET_Motion:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+        case ET_Hierarchy:
+        case ET_DeviceChanged:
+            event->u.device.deviceid = dev->id;
+            break;
+        default:
+            ErrorF("[mi] Unknown event type (%d), cannot change id.\n",
+                   event->u.any.type);
+    }
 }
 
 static void
-FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev, xEvent* original,
-                    EventListPtr master, int count)
+FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev,
+                    InternalEvent* original, InternalEvent *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.u.type == DeviceButtonPress || original->u.u.type == DeviceButtonRelease)
+    if (original->u.any.type == ET_ButtonPress ||
+        original->u.any.type == ET_ButtonRelease)
     {
-        int btn = original->u.u.detail;
+        int btn = original->u.device.detail.button;
         if (!sdev->button)
             return; /* Should never happen */
 
-        master->event->u.u.detail = sdev->button->map[btn];
+        master->u.device.detail.button = sdev->button->map[btn];
     }
 }
 
@@ -353,31 +304,23 @@ FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev, xEvent* original,
  * @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
- * @param count Number of events in original.
  */
 void
-CopyGetMasterEvent(DeviceIntPtr mdev, DeviceIntPtr sdev, xEvent* original,
-                   EventListPtr master, int count)
+CopyGetMasterEvent(DeviceIntPtr mdev, DeviceIntPtr sdev,
+                   InternalEvent* original, EventListPtr master)
 {
-    int len = count * sizeof(xEvent);
-
-    /* Assumption: GenericEvents always have count 1 */
-
-    if (GEV(original)->type == GenericEvent)
-        len += GEV(original)->length * 4;
+    int len = original->u.any.length;
+    InternalEvent *mevent;
 
     if (master->evlen < len)
         SetMinimumEventSize(master, 1, len);
 
-    memcpy(master->event, original, len);
-    while (count--)
-    {
-        ChangeDeviceID(mdev, &master->event[count]);
-        FixUpEventForMaster(mdev, sdev, original, master, count);
-    }
-}
-
+    mevent = (InternalEvent*)master->event;
 
+    memcpy(mevent, original, len);
+    ChangeDeviceID(mdev, mevent);
+    FixUpEventForMaster(mdev, sdev, original, mevent);
+}
 
 /* Call this from ProcessInputEvents(). */
 void
@@ -386,9 +329,9 @@ mieqProcessInputEvents(void)
     mieqHandler handler;
     EventRec *e = NULL;
     int x = 0, y = 0;
-    int type, nevents, evlen, i;
+    int type, evlen, i;
     ScreenPtr screen;
-    static xEvent *event = NULL;
+    static InternalEvent *event = NULL;
     static size_t event_size = 0;
     DeviceIntPtr dev = NULL,
                  master = NULL;
@@ -400,19 +343,14 @@ mieqProcessInputEvents(void)
     while (miEventQueue.head != miEventQueue.tail) {
         e = &miEventQueue.events[miEventQueue.head];
 
-        /* GenericEvents always have nevents == 1 */
-        nevents = e->nevents;
-        evlen   = (nevents > 1) ? sizeof(xEvent) : e->events->evlen;
-        if((nevents * evlen) > event_size) {
-            event_size = nevents * evlen;
-            event = (xEvent *)xrealloc(event, event_size);
-        }
+        evlen   = e->events->evlen;
+        if(evlen > event_size)
+            event = xrealloc(event, evlen);
 
         if (!event)
             FatalError("[mi] No memory left for event processing.\n");
 
-        for (i = 0; i < nevents; i++)
-            memcpy(&event[i], e->events[i].event, evlen);
+        memcpy(event, e->events->event, evlen);
 
 
         dev     = e->pDev;
@@ -424,7 +362,7 @@ mieqProcessInputEvents(void)
         pthread_mutex_unlock(&miEventQueueMutex);
 #endif
         
-        type    = event->u.u.type;
+        type    = event->u.any.type;
         master  = (!dev->isMaster && dev->u.master) ? dev->u.master : NULL;
 
         if (screenIsSaved == SCREEN_SAVER_ON)
@@ -443,35 +381,44 @@ mieqProcessInputEvents(void)
         if (screen && screen != DequeueScreen(dev) && !handler) {
             /* Assumption - screen switching can only occur on motion events. */
             DequeueScreen(dev) = screen;
-            x = event->u.keyButtonPointer.rootX;
-            y = event->u.keyButtonPointer.rootY;
+            x = event->u.device.root_x;
+            y = event->u.device.root_y;
             NewCurrentScreen (dev, DequeueScreen(dev), x, y);
         }
         else {
             if (master)
-                CopyGetMasterEvent(master, dev, event, masterEvents, nevents);
+                CopyGetMasterEvent(master, dev, event, masterEvents);
 
             /* If someone's registered a custom event handler, let them
              * steal it. */
             if (handler)
             {
-                handler(DequeueScreen(dev)->myNum, event, dev, nevents);
+                /* FIXME: this is broken now, InternalEvents! */
+                handler(DequeueScreen(dev)->myNum, event, dev, 1);
                 if (master)
                     handler(DequeueScreen(master)->myNum,
-                            masterEvents->event, master, nevents);
+                            masterEvents->event, master, 1);
             } else
             {
+                /* FIXME: temporary solution only. */
+                static int nevents;
+                static xEvent xE[1000]; /* enough bytes for the events we have atm */
+
+                nevents = ConvertBackToXI(event, xE);
+
                 /* process slave first, then master */
-                dev->public.processInputProc(event, dev, nevents);
+                dev->public.processInputProc(xE, dev, nevents);
 
                 if (master)
-                    master->public.processInputProc(masterEvents->event, master,
-                                                    nevents);
+                {
+                    nevents = ConvertBackToXI((InternalEvent*)masterEvents->event, xE);
+                    master->public.processInputProc(xE, master, nevents);
+                }
             }
         }
 
         /* Update the sprite now. Next event may be from different device. */
-        if (type == DeviceMotionNotify && (master || dev->isMaster))
+        if (event->u.any.type == ET_Motion && (master || dev->isMaster))
             miPointerUpdateSprite(dev);
 
 #ifdef XQUARTZ
commit 5a827593f9517fd5593751dd8bd90c611de06c5d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jan 29 15:26:57 2009 +1000

    dix: switch event generation to InternalEvents.
    
    GPE, GKVE, GProxE generate InternalEvents now.
    DeviceClassesChangedEvents generates an InternalEvent now, but incomplete! We
    need to tack on the information about the new SD in the ClassesChanged events.
    
    Note: To make the progress bisectable, we drop back into XI events at the end of the
    Get*Events functions. So the rest of the server still uses XI events.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/getevents.c b/dix/getevents.c
index 8af97c6..61cea28 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1,6 +1,7 @@
 /*
  * Copyright © 2006 Nokia Corporation
  * Copyright © 2006-2007 Daniel Stone
+ * 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"),
@@ -21,7 +22,8 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  *
- * Author: Daniel Stone <daniel at fooishbar.org>
+ * Authors: Daniel Stone <daniel at fooishbar.org>
+ *          Peter Hutterer <peter.hutterer at who-t.net>
  */
 
 #ifdef HAVE_DIX_CONFIG_H
@@ -41,6 +43,7 @@
 #include "globals.h"
 #include "dixevents.h"
 #include "mipointer.h"
+#include "events.h"
 
 #include <X11/extensions/XKBproto.h>
 #include "xkbsrv.h"
@@ -122,24 +125,59 @@ key_autorepeats(DeviceIntPtr pDev, int key_code)
               (1 << (key_code & 7)));
 }
 
+static void
+init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms)
+{
+    memset(event, 0, sizeof(DeviceEvent));
+    event->header = ET_Internal;
+    event->length = sizeof(DeviceEvent);
+    event->time = ms;
+    event->deviceid = dev->id;
+    event->sourceid = dev->id;
+}
+
+static void
+set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator,
+              int num_valuators, int *valuators)
+{
+    int i;
+
+    for (i = first_valuator; i < num_valuators; i++)
+        SetBit(event->valuators.mask, i);
+
+    /* FIXME: Set the current mode */
+
+    memcpy(&event->valuators.data[first_valuator],
+           valuators, num_valuators * sizeof(uint32_t));
+}
+
 void
 CreateClassesChangedEvent(EventList* event,
                           DeviceIntPtr master,
                           DeviceIntPtr slave)
 {
-    deviceClassesChangedEvent *dcce;
-    int len = sizeof(xEvent);
+    DeviceChangedEvent *dce;
     CARD32 ms = GetTimeInMillis();
-    int namelen = 0; /* dummy */
-
-    dcce = (deviceClassesChangedEvent*)event->event;
-    dcce->type = GenericEvent;
-    dcce->extension = IReqCode;
-    dcce->evtype = XI_DeviceClassesChangedNotify;
-    dcce->time = ms;
-    dcce->new_slave = slave->id;
-    SizeDeviceInfo(slave, &namelen, &len);
-    dcce->length = (len - sizeof(xEvent))/4;
+
+    dce = (DeviceChangedEvent*)event->event;
+    memset(dce, 0, sizeof(DeviceChangedEvent));
+    dce->header = ET_Internal;
+    dce->length = sizeof(DeviceChangedEvent);
+    dce->type = ET_DeviceChanged;
+    dce->time = ms;
+    if (master->u.lastSlave)
+    {
+        dce->flags |= HAS_OLD_SLAVE;
+        dce->old_slaveid = master->u.lastSlave->id;
+    }
+    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.
+     */
+
 }
 
 /**
@@ -797,7 +835,7 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
                           int num_valuators, int *valuators) {
     int numEvents = 0;
     CARD32 ms = 0;
-    deviceKeyButtonPointer *kbp = NULL;
+    DeviceEvent *event;
 
     if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
        (type != KeyPress && type != KeyRelease) ||
@@ -808,8 +846,6 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     events = updateFromMaster(events, pDev, &numEvents);
 
-    numEvents += countValuatorEvents(num_valuators);
-
     /* Handle core repeating, via press/release/press/release. */
     if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
         /* If autorepeating is disabled either globally or just for that key,
@@ -820,28 +856,31 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
             return 0;
     }
 
+    if (num_valuators)
+        clipValuators(pDev, first_valuator, num_valuators, valuators);
+
     ms = GetTimeInMillis();
 
-    kbp = (deviceKeyButtonPointer *) events->event;
-    kbp->time = ms;
-    kbp->deviceid = pDev->id;
-    kbp->detail = key_code;
+    event = (DeviceEvent*) events->event;
+    init_event(pDev, event, ms);
+    event->detail.key = key_code;
+
     if (type == KeyPress) {
-        kbp->type = DeviceKeyPress;
+        event->type = ET_KeyPress;
 	set_key_down(pDev, key_code, KEY_POSTED);
     }
     else if (type == KeyRelease) {
-        kbp->type = DeviceKeyRelease;
+        event->type = ET_KeyRelease;
 	set_key_up(pDev, key_code, KEY_POSTED);
     }
 
-    events++;
-    if (num_valuators) {
-        kbp->deviceid |= MORE_EVENTS;
+    if (num_valuators)
         clipValuators(pDev, first_valuator, num_valuators, valuators);
-        events = getValuatorEvents(events, pDev, first_valuator,
-                                   num_valuators, valuators);
-    }
+
+    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+
+    /* XXX: temporary only */
+    numEvents = ConvertBackToXI(events - (numEvents - 1), numEvents);
 
     return numEvents;
 }
@@ -865,8 +904,8 @@ InitEventList(int num_events)
 
     for (i = 0; i < num_events; i++)
     {
-        events[i].evlen = sizeof(xEvent);
-        events[i].event = xcalloc(1, sizeof(xEvent));
+        events[i].evlen = sizeof(InternalEvent);
+        events[i].event = xcalloc(1, sizeof(InternalEvent));
         if (!events[i].event)
         {
             /* rollback */
@@ -946,7 +985,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
                  int *valuators) {
     int num_events = 1;
     CARD32 ms;
-    deviceKeyButtonPointer *kbp = NULL;
+    DeviceEvent *event;
     int x, y, /* switches between device and screen coords */
         cx, cy; /* only screen coordinates */
     ScreenPtr scr = miPointerGetScreen(pDev);
@@ -961,8 +1000,6 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         (type == MotionNotify && num_valuators <= 0))
         return 0;
 
-    num_events += countValuatorEvents(num_valuators);
-
     events = updateFromMaster(events, pDev, &num_events);
 
     if (flags & POINTER_ABSOLUTE)
@@ -995,36 +1032,36 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
         valuators[1 - first_valuator] = y;
 
-    kbp = (deviceKeyButtonPointer *) events->event;
-    kbp->time = ms;
-    kbp->deviceid = pDev->id;
+    if (num_valuators)
+        clipValuators(pDev, first_valuator, num_valuators, valuators);
+
+    event = (DeviceEvent*) events->event;
+    init_event(pDev, event, ms);
 
     if (type == MotionNotify) {
-        kbp->type = DeviceMotionNotify;
+        event->type = ET_Motion;
+        event->detail.button = 0;
     }
     else {
         if (type == ButtonPress) {
-            kbp->type = DeviceButtonPress;
+            event->type = ET_ButtonPress;
             pDev->button->postdown[buttons >> 3] |= (1 << (buttons & 7));
         }
         else if (type == ButtonRelease) {
-            kbp->type = DeviceButtonRelease;
+            event->type = ET_ButtonRelease;
             pDev->button->postdown[buttons >> 3] &= ~(1 << (buttons & 7));
         }
-        kbp->detail = buttons;
+        event->detail.button = buttons;
     }
 
-    kbp->root_x = cx; /* root_x/y always in screen coords */
-    kbp->root_y = cy;
+    /* XXX: this should be 16.16 fixed point */
+    event->root_x = cx; /* root_x/y always in screen coords */
+    event->root_y = cy;
 
-    events++;
-    if (num_valuators) {
-        kbp->deviceid |= MORE_EVENTS;
-        if (flags & POINTER_ABSOLUTE)
-            clipValuators(pDev, first_valuator, num_valuators, valuators);
-        events = getValuatorEvents(events, pDev, first_valuator,
-                                   num_valuators, valuators);
-    }
+    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+
+    /* XXX: temporary only */
+    num_events = ConvertBackToXI(events - (num_events - 1), num_events);
 
     return num_events;
 }
@@ -1042,7 +1079,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
                    int first_valuator, int num_valuators, int *valuators)
 {
     int num_events = 1;
-    deviceKeyButtonPointer *kbp;
+    DeviceEvent *event;
 
     /* Sanity checks. */
     if (type != ProximityIn && type != ProximityOut)
@@ -1066,19 +1103,17 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     events = updateFromMaster(events, pDev, &num_events);
 
-    kbp = (deviceKeyButtonPointer *) events->event;
-    kbp->type = type;
-    kbp->deviceid = pDev->id;
-    kbp->detail = 0;
-    kbp->time = GetTimeInMillis();
+    event = (DeviceEvent *) events->event;
+    init_event(pDev, event, GetTimeInMillis());
+    event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
 
-    if (num_valuators) {
-        kbp->deviceid |= MORE_EVENTS;
-        events++;
+    if (num_valuators)
         clipValuators(pDev, first_valuator, num_valuators, valuators);
-        events = getValuatorEvents(events, pDev, first_valuator,
-                                   num_valuators, valuators);
-    }
+
+    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+
+    /* XXX: temporary only */
+    num_events = ConvertBackToXI(events - (num_events - 1), num_events);
 
     return num_events;
 }
commit 00b03683d0e5cda40fa23b9fe6a83d7227f86f5d
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 30 14:31:08 2009 +1000

    dix: Add temporary conversion function ConvertBackToXI.
    
    Until the InternalEvents are used throughout the server, we can use this one
    to drop us back into XI la-la land where every event is the wire format.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 2ade378..31fb47b 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -328,3 +328,34 @@ GetXIType(InternalEvent *event)
     }
     return xitype;
 }
+
+/*
+ * FIXME: A temporary solution to make the server bisectable. This code
+ * allocates during SIGIO and makes a number of assumptions about what's in
+ * events. Will be removed soon.
+ */
+static int
+ConvertBackToXI(EventListPtr events, int num_events)
+{
+    int count = GetMaximumEventsNum();
+    int num = (num_events == 2) ? 1 : 0;
+    int i;
+    EventListPtr tmp_list = InitEventList(count);
+
+    SetMinimumEventSize(tmp_list, count, 1000); /* just to be sure */
+
+    if (num_events == 2) /* DCCE Event? */
+    {
+        if (EventToXI(events->event, tmp_list, &count))
+            ErrorF("[dix] conversion to XI failed\n");
+        memcpy(events->event, tmp_list->event, events->evlen);
+        events++;
+    }
+
+    if (EventToXI(events->event, tmp_list, &count))
+        ErrorF("[dix] conversion to XI failed\n");
+
+    for (i = 0; i < count; i++)
+        memcpy((events + i)->event, (tmp_list + i)->event, events->evlen);
+    return (count + num);
+}
commit 269d4d9f2e86fde8c6a28ef0293fb0e44b577886
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Sun Feb 1 09:57:27 2009 +1000

    dix: add GetCoreType and GetXIType.
    
    Convert from an InternalEvent type to the matching core/XI type. Currently
    only for a few events, those we actually need in the server.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index c365811..2ade378 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -288,3 +288,43 @@ eventToClassesChanged(DeviceChangedEvent *ev, EventListPtr events, int *count)
     *count = 1;
     return Success;
 }
+
+/**
+ * Return the corresponding core type for the given @event or 0 if no core
+ * equivalent exists.
+ */
+int
+GetCoreType(InternalEvent *event)
+{
+    int coretype = 0;
+    switch(event->u.any.type)
+    {
+        case ET_Motion:         coretype = MotionNotify;  break;
+        case ET_ButtonPress:    coretype = ButtonPress;   break;
+        case ET_ButtonRelease:  coretype = ButtonRelease; break;
+        case ET_KeyPress:       coretype = KeyPress;      break;
+        case ET_KeyRelease:     coretype = KeyRelease;    break;
+    }
+    return coretype;
+}
+
+/**
+ * Return the corresponding XI 1.x type for the given @event or 0 if no
+ * equivalent exists.
+ */
+int
+GetXIType(InternalEvent *event)
+{
+    int xitype = 0;
+    switch(event->u.any.type)
+    {
+        case ET_Motion:         xitype = DeviceMotionNotify;  break;
+        case ET_ButtonPress:    xitype = DeviceButtonPress;   break;
+        case ET_ButtonRelease:  xitype = DeviceButtonRelease; break;
+        case ET_KeyPress:       xitype = DeviceKeyPress;      break;
+        case ET_KeyRelease:     xitype = DeviceKeyRelease;    break;
+        case ET_ProximityIn:    xitype = ProximityIn;         break;
+        case ET_ProximityOut:   xitype = ProximityOut;        break;
+    }
+    return xitype;
+}
diff --git a/include/eventconvert.h b/include/eventconvert.h
index 2443582..8463831 100644
--- a/include/eventconvert.h
+++ b/include/eventconvert.h
@@ -30,5 +30,7 @@
 
 _X_INTERNAL int EventToCore(InternalEvent *event, xEvent *core);
 _X_INTERNAL int EventToXI(InternalEvent *ev, EventListPtr xi, int *count);
+_X_INTERNAL int GetCoreType(InternalEvent* ev);
+_X_INTERNAL int GetXIType(InternalEvent* ev);
 
 #endif /* _EVENTCONVERT_H_ */
commit 656491921e17b2371057041f4551ad6165067551
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jan 28 15:27:38 2009 +1000

    dix: add InternalEvent -> core/xi event conversion routines.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/Makefile.am b/dix/Makefile.am
index 34eeb6d..8c5f3c0 100644
--- a/dix/Makefile.am
+++ b/dix/Makefile.am
@@ -17,6 +17,8 @@ libdix_la_SOURCES = 	\
 	enterleave.c	\
 	enterleave.h	\
 	events.c	\
+	eventconvert.h  \
+	eventconvert.c  \
 	extension.c	\
 	ffs.c		\
 	gc.c		\
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
new file mode 100644
index 0000000..c365811
--- /dev/null
+++ b/dix/eventconvert.c
@@ -0,0 +1,290 @@
+/*
+ * 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.
+ *
+ */
+
+/**
+ * @file This file contains event conversion routines from InternalEvent to
+ * the matching protocol events.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI.h>
+
+#include "dix.h"
+#include "inputstr.h"
+#include "misc.h"
+#include "events.h"
+#include "exglobals.h"
+#include "eventconvert.h"
+#include "listdev.h"
+
+static int countValuators(DeviceEvent *ev, int *first);
+static int getValuatorEvents(DeviceEvent *ev, EventListPtr xi);
+static int eventToKeyButtonPointer(DeviceEvent *ev, EventListPtr xi, int *count);
+static int eventToClassesChanged(DeviceChangedEvent *ev, EventListPtr dcce,
+                                 int *count);
+
+/**
+ * Convert the given event @ev to the respective core event and store it in
+ * @core.
+ *
+ * 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 core equivalent.
+ *
+ * @return Success or the matching error code.
+ */
+int
+EventToCore(InternalEvent *event, xEvent *core)
+{
+    switch(event->u.any.type)
+    {
+        case ET_Motion:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            {
+                DeviceEvent *e = (DeviceEvent*)event;
+
+                if (e->detail.key > 0xFF)
+                    return BadMatch;
+
+                memset(core, 0, sizeof(xEvent));
+                core->u.u.type = e->type - ET_KeyPress + KeyPress;
+                core->u.u.detail = e->detail.key & 0xFF;
+                core->u.keyButtonPointer.time = e->time;
+                core->u.keyButtonPointer.rootX = e->root_x;
+                core->u.keyButtonPointer.rootY = e->root_y;
+                core->u.keyButtonPointer.state = e->corestate;
+            }
+            break;
+        default:
+            /* XXX: */
+            ErrorF("[dix] EventToCore: Not implemented yet \n");
+            return BadImplementation;
+    }
+    return Success;
+}
+
+/**
+ * Convert the given event @ev to the respective XI 1.x event and store it in
+ * @xi. @xi must be allocated by the caller, @count specifies the number of
+ * events in @xi.
+ *
+ *
+ * If less than @count events are needed, @count is set to the events stored
+ * in @xi and Success is returned.
+ *
+ * If more than @count events are needed, @count is set to the number of
+ * events required, and BadAlloc is returned. @xi is untouched.
+ *
+ * If necessary, @xi is realloced using SetMinimumEventSize() to fit the
+ * largest event being returned.
+ *
+ * If the event cannot be converted into an XI event because of protocol
+ * restrictions, @count is 0 and Success is returned.
+ */
+int
+EventToXI(InternalEvent *ev, EventListPtr xi, int *count)
+{
+    switch (ev->u.any.type)
+    {
+        case ET_Motion:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            return eventToKeyButtonPointer((DeviceEvent*)ev, xi, count);
+        case ET_DeviceChanged:
+            return eventToClassesChanged((DeviceChangedEvent*)ev, xi, count);
+            break;
+    }
+
+    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->u.any.type);
+    return BadImplementation;
+}
+
+static int
+eventToKeyButtonPointer(DeviceEvent *ev, EventListPtr xi, int *count)
+{
+    int num_events;
+    int first; /* dummy */
+    deviceKeyButtonPointer *kbp;
+
+    /* Sorry, XI 1.x protocol restrictions. */
+    if (ev->detail.button > 0xFF || ev->deviceid >= 0x80)
+    {
+        *count = 0;
+        return Success;
+    }
+
+    num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
+    num_events++; /* the actual event event */
+
+    if (*count < num_events)
+    {
+        *count = num_events;
+        return BadAlloc;
+    }
+
+    SetMinimumEventSize(xi, *count, 32);
+
+    kbp = (deviceKeyButtonPointer*)xi->event;
+    kbp->detail   = ev->detail.button;
+    kbp->time     = ev->time;
+    kbp->root     = ev->root;
+    kbp->root_x   = ev->root_x;
+    kbp->root_y   = ev->root_y;
+    kbp->deviceid = ev->deviceid;
+    kbp->state    = ev->corestate;
+
+    if (num_events > 1)
+        kbp->deviceid |= MORE_EVENTS;
+
+    switch(ev->type)
+    {
+        case ET_Motion:        kbp->type = DeviceMotionNotify;  break;
+        case ET_ButtonPress:   kbp->type = DeviceButtonPress;   break;
+        case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break;
+        case ET_KeyPress:      kbp->type = DeviceKeyPress;      break;
+        case ET_KeyRelease:    kbp->type = DeviceKeyRelease;    break;
+        case ET_ProximityIn:   kbp->type = ProximityIn;         break;
+        case ET_ProximityOut:  kbp->type = ProximityOut;        break;
+    }
+
+
+    if (num_events > 1)
+    {
+        getValuatorEvents(ev, xi + 1);
+    }
+
+    *count = num_events;
+    return Success;
+}
+
+
+/**
+ * Set @first to the first valuator in the event @ev and return the number of
+ * valuators from @first to the last set valuator.
+ */
+static int
+countValuators(DeviceEvent *ev, int *first)
+{
+    int first_valuator = -1, last_valuator = -1, num_valuators = 0;
+    int i;
+
+    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    {
+        if (BitIsOn(ev->valuators.mask, i))
+        {
+            if (first_valuator == -1)
+                first_valuator = i;
+            last_valuator = i;
+        }
+    }
+
+    if (first_valuator != -1)
+    {
+        num_valuators = last_valuator - first_valuator + 1;
+        *first = first_valuator;
+    }
+
+    return num_valuators;
+}
+
+static int
+getValuatorEvents(DeviceEvent *ev, EventListPtr events)
+{
+    int i;
+    deviceValuator *xv;
+    int first_valuator, num_valuators;
+
+    num_valuators = countValuators(ev, &first_valuator);
+
+    /* FIXME: non-continuous valuator data in internal events*/
+    for (i = 0; i < num_valuators; i += 6, events++) {
+        xv = (deviceValuator*)events->event;
+        xv->type = DeviceValuator;
+        xv->first_valuator = first_valuator + i;
+        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
+        xv->deviceid = ev->deviceid;
+        switch (xv->num_valuators) {
+        case 6:
+            xv->valuator5 = ev->valuators.data[i + 5];
+        case 5:
+            xv->valuator4 = ev->valuators.data[i + 4];
+        case 4:
+            xv->valuator3 = ev->valuators.data[i + 3];
+        case 3:
+            xv->valuator2 = ev->valuators.data[i + 2];
+        case 2:
+            xv->valuator1 = ev->valuators.data[i + 1];
+        case 1:
+            xv->valuator0 = ev->valuators.data[i + 0];
+        }
+
+        if (i + 6 < num_valuators)
+            xv->deviceid |= MORE_EVENTS;
+    }
+
+    return (num_valuators + 5) / 6;
+}
+
+static int
+eventToClassesChanged(DeviceChangedEvent *ev, EventListPtr events, int *count)
+{
+    int len = sizeof(xEvent);
+    int namelen = 0; /* dummy */
+    DeviceIntPtr slave;
+    int rc;
+    deviceClassesChangedEvent *dcce = (deviceClassesChangedEvent*)events->event;
+
+    rc = dixLookupDevice(&slave, ev->new_slaveid,
+                         serverClient, DixReadAccess);
+
+    if (rc != Success)
+        return rc;
+
+    SizeDeviceInfo(slave, &namelen, &len);
+
+    dcce->type = GenericEvent;
+    dcce->extension = IReqCode;
+    dcce->evtype = XI_DeviceClassesChangedNotify;
+    dcce->time = GetTimeInMillis();
+    dcce->new_slave = slave->id;
+    dcce->length = (len - sizeof(xEvent))/4;
+
+    *count = 1;
+    return Success;
+}
diff --git a/include/Makefile.am b/include/Makefile.am
index 09300fe..fda4b70 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -57,7 +57,7 @@ sdk_HEADERS =		\
 	xkbrules.h      \
 	xserver-properties.h
 
-nodist_sdk_HEADERS = xorg-server.h events.h
+nodist_sdk_HEADERS = xorg-server.h events.h eventconvert.h
 endif
 
 AM_CFLAGS = $(DIX_CFLAGS)
diff --git a/include/eventconvert.h b/include/eventconvert.h
new file mode 100644
index 0000000..2443582
--- /dev/null
+++ b/include/eventconvert.h
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef _EVENTCONVERT_H_
+#include <X11/X.h>
+#include <X11/extensions/XIproto.h>
+#include "input.h"
+#include "events.h"
+
+_X_INTERNAL int EventToCore(InternalEvent *event, xEvent *core);
+_X_INTERNAL int EventToXI(InternalEvent *ev, EventListPtr xi, int *count);
+
+#endif /* _EVENTCONVERT_H_ */
commit e7867d12541ef9683d5d7fc766e918c13a742981
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jan 23 15:37:23 2009 +1100

    include: add XInternalEvent.
    
    This is the event we want to feed into the EQ and process on the way through.
    Only applies for input events for now.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/Makefile.am b/include/Makefile.am
index cb0b293..09300fe 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -57,7 +57,7 @@ sdk_HEADERS =		\
 	xkbrules.h      \
 	xserver-properties.h
 
-nodist_sdk_HEADERS = xorg-server.h
+nodist_sdk_HEADERS = xorg-server.h events.h
 endif
 
 AM_CFLAGS = $(DIX_CFLAGS)
diff --git a/include/events.h b/include/events.h
new file mode 100644
index 0000000..4b69246
--- /dev/null
+++ b/include/events.h
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef EVENTS_H
+#define EVENTS_H
+
+/**
+ * @file This file describes the event structures used internally by the X
+ * server during event generation and event processing.
+ *
+ * When are internal events used?
+ * Events from input devices are stored as internal events in the EQ and
+ * processed as internal events until late in the processing cycle. Only then
+ * do they switch to their respective wire events.
+ */
+
+/**
+ * Event types. Used exclusively internal to the server, not visible on the
+ * protocol.
+ *
+ * Note: Keep KeyPress to Motion aligned with the core events.
+ */
+enum {
+    ET_KeyPress = 2,
+    ET_KeyRelease,
+    ET_ButtonPress,
+    ET_ButtonRelease,
+    ET_Motion,
+    ET_Enter,
+    ET_Leave,
+    ET_FocusIn,
+    ET_FocusOut,
+    ET_ProximityIn,
+    ET_ProximityOut,
+    ET_DeviceChanged,
+    ET_Hierarchy,
+    ET_Internal = 0xFF /* First byte */
+} EventType;
+
+/**
+ * Device event, used for ALL input device events internal in the server until
+ * copied into the matching protocol event.
+ *
+ * Note: We only use the device id because the DeviceIntPtr may become invalid while
+ * the event is in the EQ.
+ *
+ * @header:     Always ET_Internal
+ * @type:       One of EventType.
+ * @length:     Length in bytes.
+ * @time:       Time in ms.
+ * @deviceid:   Device to post this event for.
+ * @sourceid:   The physical source device.
+ * @key:        Keycode of the event
+ * @button:     Button number of the event.
+ * @root_x:     Position relative to root window in 16.16 fixed point
+ *              screen coordinates
+ * @root_y:     Position relative to root window in 16.16 fixed point
+ *              screen coordinates
+ * @buttons:    Button mask.
+ * @valuators.mask:  Valuator mask.
+ * @valuators.mode:  Valuator mode. Bit set for Absolute mode, unset for relative.
+ * @valuators.data:  Valuator data. Only set for valuators listed in @mask.
+ * @mods.base:       XKB Base modifiers
+ * @mods.latched:    XKB latched modifiers.
+ * @mods.locked:     XKB locked modifiers.
+ * @group.base:      XKB Base modifiers
+ * @group.latched:   XKB latched modifiers.
+ * @group.locked:    XKB locked modifiers.
+ * @root:       Root window of the event.
+ * @corestate:  Core key/button state BEFORE this event applied.
+ */
+typedef struct
+{
+    unsigned char header;
+    int type;
+    int length;
+    Time time;
+    int deviceid;
+    int sourceid;
+    union {
+        uint32_t button;
+        uint32_t key;
+    } detail;
+    uint32_t root_x;
+    uint32_t root_y;
+    uint8_t    buttons[(MAX_BUTTONS + 7)/8];
+    struct {
+        uint8_t  mask[(MAX_VALUATORS + 7)/8];
+        uint8_t  mode[(MAX_VALUATORS + 7)/8];
+        uint32_t data[MAX_VALUATORS];
+    } valuators;
+    struct {
+        uint32_t base;
+        uint32_t latched;
+        uint32_t locked;
+    } mods;
+    struct {
+        uint8_t base;
+        uint8_t latched;
+        uint8_t locked;
+    } group;
+    Window      root;
+    int corestate;
+} DeviceEvent;
+
+
+/* Flags used in DeviceChangedEvent to signal if new/old slave is present */
+#define HAS_OLD_SLAVE 0x1
+#define HAS_NEW_SLAVE 0x2
+
+/**
+ * DeviceChangedEvent, sent whenever a device's capabilities have changed.
+ *
+ * @header:     Always ET_Internal
+ * @type:       ET_DeviceChanged
+ * @length:     Length in bytes
+ * @time:       Time in ms.
+ * @flags:      Mask of HAS_OLD_SLAVE (if @old_slaveid specifies the previous
+ *              SD) and HAS_NEW_SLAVE (if @new_slaveid specifies the new SD).
+ * @old_slaveid: Specifies the device previously attached to the MD.
+ * @new_slaveid: Specifies the device now attached to the SD.
+ */
+typedef struct
+{
+    unsigned char header;
+    int type;
+    int length;
+    Time time;
+    int flags;
+    int old_slaveid;
+    int new_slaveid;
+    /* FIXME: add the new capabilities here */
+} DeviceChangedEvent;
+
+/**
+ * InternalEvent, event type used inside the X server for input event
+ * processing.
+ *
+ * @header:     Always ET_Internal
+ * @type:       One of ET_*
+ * @length:     Length in bytes
+ * @time:       Time in ms.
+ */
+typedef struct
+{
+    union {
+        struct {
+            unsigned char header;
+            int type;
+            int length;
+            Time time;
+        } any;
+        DeviceEvent device;
+        DeviceChangedEvent changed;
+    } u;
+} InternalEvent;
+
+#endif
diff --git a/include/input.h b/include/input.h
index 3b7a173..1804235 100644
--- a/include/input.h
+++ b/include/input.h
@@ -75,6 +75,7 @@ SOFTWARE.
 /* Maximum number of valuators, divided by six, rounded up, to get number
  * of events. */
 #define MAX_VALUATOR_EVENTS 6
+#define MAX_BUTTONS 256 /* completely arbitrarily chosen */
 
 #define NO_AXIS_LIMITS -1
 


More information about the xorg-commit mailing list