xserver: Branch 'master' - 63 commits

Keith Packard keithp at kemper.freedesktop.org
Wed Nov 10 22:39:12 PST 2010


 Xext/xtest.c                           |   10 
 Xi/closedev.c                          |    1 
 Xi/exevents.c                          |   21 -
 Xi/listdev.c                           |   10 
 Xi/opendev.c                           |    1 
 Xi/queryst.c                           |    3 
 Xi/setmode.c                           |    2 
 Xi/stubs.c                             |   90 -----
 Xi/xiquerydevice.c                     |    2 
 config/hal.c                           |    6 
 config/udev.c                          |    7 
 dix/devices.c                          |   50 +-
 dix/eventconvert.c                     |   14 
 dix/getevents.c                        |  312 ++++++++++--------
 dix/inpututils.c                       |  130 +++++++
 doc/xml/Xserver-spec.xml               |   25 -
 hw/dmx/doc/dmx.xml                     |   14 
 hw/dmx/input/dmxevents.c               |   53 +--
 hw/dmx/input/dmxinputinit.c            |   16 
 hw/dmx/input/dmxmotion.c               |    7 
 hw/dmx/input/dmxxinput.c               |   17 -
 hw/kdrive/src/kinput.c                 |   39 --
 hw/vfb/InitInput.c                     |    2 
 hw/xfree86/common/xf86.h               |    1 
 hw/xfree86/common/xf86Config.c         |   98 ++---
 hw/xfree86/common/xf86Events.c         |   20 +
 hw/xfree86/common/xf86Globals.c        |    1 
 hw/xfree86/common/xf86Helper.c         |  107 ++----
 hw/xfree86/common/xf86InPriv.h         |    3 
 hw/xfree86/common/xf86Init.c           |    2 
 hw/xfree86/common/xf86Module.h         |    2 
 hw/xfree86/common/xf86Opt.h            |    1 
 hw/xfree86/common/xf86Option.c         |   61 +--
 hw/xfree86/common/xf86Privstr.h        |    1 
 hw/xfree86/common/xf86Xinput.c         |  553 +++++++++++++++++----------------
 hw/xfree86/common/xf86Xinput.h         |  122 ++-----
 hw/xfree86/common/xf86str.h            |   12 
 hw/xfree86/doc/devel/Registry          |    1 
 hw/xfree86/doc/man/xorg.conf.man.pre   |    3 
 hw/xfree86/os-support/linux/lnx_init.c |    4 
 hw/xnest/Events.c                      |   14 
 hw/xquartz/darwin.c                    |   19 -
 hw/xquartz/darwinEvents.c              |    9 
 hw/xquartz/darwinXinput.c              |   72 ----
 hw/xwin/InitInput.c                    |    4 
 hw/xwin/winmouse.c                     |    8 
 include/Makefile.am                    |    2 
 include/XIstubs.h                      |   14 
 include/exevents.h                     |    7 
 include/input.h                        |   34 +-
 include/inputstr.h                     |    5 
 include/inpututils.h                   |   48 ++
 mi/mipointer.c                         |    6 
 test/input.c                           |  112 ++++++
 xkb/xkbActions.c                       |   13 
 55 files changed, 1104 insertions(+), 1087 deletions(-)

New commits:
commit 88cb61e1e55c54982b90e2a77465faaac6a0ba89
Merge: 19f4383... 4ed4915...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Nov 11 12:54:46 2010 +1000

    Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/xserver into input-api
    
    Conflicts:
    	dix/getevents.c
    	hw/xfree86/common/xf86Xinput.h
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --cc hw/xfree86/common/xf86Config.c
index 51b9375,88e2e8d..568b2d6
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@@ -2368,10 -2349,10 +2325,10 @@@ checkInput(serverLayoutPtr layout, Boo
                  strcmp((*dev)->driver, "mouse") == 0 ||
                  strcmp((*dev)->driver, "vmmouse") == 0)
              {
 -                IDevPtr *current;
 +                InputInfoPtr *current;
                  if (!warned)
                  {
-                     xf86Msg(X_WARNING, "AllowEmptyInput is on, devices using "
+                     xf86Msg(X_WARNING, "Hotplugging is on, devices using "
                              "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
                      warned = TRUE;
                  }
diff --cc hw/xfree86/common/xf86Xinput.h
index b310eaf,1d013aa..3a17116
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@@ -134,16 -177,15 +134,16 @@@ extern _X_EXPORT void xf86PostButtonEve
  extern _X_EXPORT void xf86PostKeyEvent(DeviceIntPtr device, unsigned int key_code, int is_down,
  		      int is_absolute, int first_valuator, int num_valuators,
  		      ...);
 +extern _X_EXPORT void xf86PostKeyEventM(DeviceIntPtr device, unsigned int key_code, int is_down,
 +		       int is_absolute, const ValuatorMask *mask);
  extern _X_EXPORT void xf86PostKeyEventP(DeviceIntPtr device, unsigned int key_code, int is_down,
  		       int is_absolute, int first_valuator, int num_valuators,
 -		       int *valuators);
 +		       const int *valuators);
  extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int key_code,
                             int is_down);
 -extern _X_EXPORT int xf86ActivateDevice(LocalDevicePtr local);
 -extern _X_EXPORT LocalDevicePtr xf86FirstLocalDevice(void);
 +extern _X_EXPORT InputInfoPtr xf86FirstLocalDevice(void);
- extern _X_EXPORT int xf86ScaleAxis(int Cx, int Sxhigh, int Sxlow, int Rxhigh, int Rxlow);
+ extern _X_EXPORT int xf86ScaleAxis(int Cx, int to_max, int to_min, int from_max, int from_min);
 -extern _X_EXPORT void xf86XInputSetScreen(LocalDevicePtr local, int screen_number, int x, int y);
 +extern _X_EXPORT void xf86XInputSetScreen(InputInfoPtr pInfo, int screen_number, int x, int y);
  extern _X_EXPORT void xf86ProcessCommonOptions(InputInfoPtr pInfo, pointer options);
  extern _X_EXPORT void xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval,
  				int maxval, int resolution, int min_res,
diff --cc hw/xwin/winmouse.c
index e645d7e,af499d9..da1d5a9
--- a/hw/xwin/winmouse.c
+++ b/hw/xwin/winmouse.c
@@@ -240,20 -235,16 +235,18 @@@ winMouseButtonsSendEvent (int iEventTyp
  {
    EventListPtr events;
    int i, nevents;
 +  ValuatorMask mask;
  
- #if defined(XFree86Server)
    if (g_winMouseButtonMap)
      iButton = g_winMouseButtonMap[iButton];
- #endif
  
 +  valuator_mask_zero(&mask);
    GetEventList(&events);
    nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton,
 -			     POINTER_RELATIVE, 0, 0, NULL);
 +			     POINTER_RELATIVE, &mask);
  
    for (i = 0; i < nevents; i++)
-     mieqEnqueue(g_pwinPointer, events[i].event);
+     mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event);
  
  #if CYGDEBUG
    ErrorF("winMouseButtonsSendEvent: iEventType: %d, iButton: %d, nEvents %d\n",
@@@ -382,11 -372,10 +375,11 @@@ void winEnqueueMotion(int x, int y
    valuators[0] = x;
    valuators[1] = y;
  
 +  valuator_mask_set_range(&mask, 0, 2, valuators);
    GetEventList(&events);
    nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0,
 -			     POINTER_ABSOLUTE | POINTER_SCREEN, 0, 2, valuators);
 +			     POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
  
    for (i = 0; i < nevents; i++)
-     mieqEnqueue(g_pwinPointer, events[i].event);
+     mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event);
  }
commit 19f43836d1006d253391926e880b14ed2e7a0cf8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Oct 25 15:10:19 2010 +1000

    Re-export xf86CollectInputOptions.
    
    Some drivers, most notably the mouse driver need this and reimplementing on
    the driver side doesn't make sense.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 8ee0c68..b310eaf 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -176,6 +176,6 @@ extern _X_EXPORT void xf86VIDrvMsgVerb(InputInfoPtr dev,
 				       va_list args);
 
 /* xf86Option.c */
-extern void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts);
+extern _X_EXPORT void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts);
 
 #endif /* _xf86Xinput_h */
commit 4613ce3f78a32f2a6f422e719150d55b035c758e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 22 15:17:50 2010 +1000

    test: valuator_mode tests.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/test/input.c b/test/input.c
index daadbea..2aa76de 100644
--- a/test/input.c
+++ b/test/input.c
@@ -978,6 +978,38 @@ static void dix_input_valuator_masks(void)
     free(mask);
 }
 
+static void dix_valuator_mode(void)
+{
+    DeviceIntRec dev;
+    const int num_axes = MAX_VALUATORS;
+    int i;
+    Atom atoms[MAX_VALUATORS] = { 0 };
+
+    memset(&dev, 0, sizeof(DeviceIntRec));
+    dev.type = MASTER_POINTER; /* claim it's a master to stop ptracccel */
+
+    g_assert(InitValuatorClassDeviceStruct(NULL, 0, atoms, 0, 0) == FALSE);
+    g_assert(InitValuatorClassDeviceStruct(&dev, num_axes, atoms, 0, Absolute));
+
+    for (i = 0; i < num_axes; i++)
+    {
+        g_assert(valuator_get_mode(&dev, i) == Absolute);
+        valuator_set_mode(&dev, i, Relative);
+        g_assert(dev.valuator->axes[i].mode == Relative);
+        g_assert(valuator_get_mode(&dev, i) == Relative);
+    }
+
+    valuator_set_mode(&dev, VALUATOR_MODE_ALL_AXES, Absolute);
+    for (i = 0; i < num_axes; i++)
+        g_assert(valuator_get_mode(&dev, i) == Absolute);
+
+    valuator_set_mode(&dev, VALUATOR_MODE_ALL_AXES, Relative);
+    for (i = 0; i < num_axes; i++)
+        g_assert(valuator_get_mode(&dev, i) == Relative);
+}
+
+
+
 int main(int argc, char** argv)
 {
     g_test_init(&argc, &argv,NULL);
@@ -990,6 +1022,7 @@ int main(int argc, char** argv)
     g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
     g_test_add_func("/dix/input/xi2-struct-sizes", xi2_struct_sizes);
     g_test_add_func("/dix/input/grab_matching", dix_grab_matching);
+    g_test_add_func("/dix/input/valuator_mode", dix_valuator_mode);
     g_test_add_func("/include/byte_padding_macros", include_byte_padding_macros);
     g_test_add_func("/Xi/xiproperty/register-unregister", xi_unregister_handlers);
 
commit 58554f1c6429535e7ab432c920aabca71a77edb8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 22 15:10:32 2010 +1000

    Convert some leftover axes->mode access to valuator_get_mode()
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
index c8b3d7e..fdd2c05 100644
--- a/Xi/xiquerydevice.c
+++ b/Xi/xiquerydevice.c
@@ -349,7 +349,7 @@ ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber,
     info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16));
     info->resolution = v->axes[axisnumber].resolution;
     info->number = axisnumber;
-    info->mode = v->axes[axisnumber].mode;
+    info->mode = valuator_get_mode(dev, axisnumber);
     info->sourceid = v->sourceid;
 
     if (!reportState)
diff --git a/dix/getevents.c b/dix/getevents.c
index 6bec39c..9b5e6df 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -780,7 +780,7 @@ moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
         if (valuator_mask_isset(mask, i))
         {
             dev->last.valuators[i] += valuator_mask_get(mask, i);
-            if (dev->valuator->axes[i].mode == Absolute)
+            if (valuator_get_mode(dev, i) == Absolute)
                 clipAxis(dev, i, &dev->last.valuators[i]);
             valuator_mask_set(mask, i, dev->last.valuators[i]);
         }
@@ -1252,7 +1252,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const Valuato
     for (i = 0; i < valuator_mask_num_valuators(&mask); i++)
     {
         if (valuator_mask_isset(&mask, i) &&
-            pDev->valuator->axes[i].mode == Relative)
+            valuator_get_mode(pDev, i) == Relative)
             valuator_mask_unset(&mask, i);
     }
 
commit dd11f734a9a73bf34357c149d2809842938d57b5
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 22 16:11:24 2010 +1000

    input: remove "mode" field from ValuatorClassRec.
    
    We have per-axis mode now. For those bits that still need it (XI 1.x),
    assume that the first axis holds the device's mode.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 9bff2b3..d57265e 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -556,7 +556,6 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
 
         v->axisVal = (double*)(v->axes + from->valuator->numAxes);
         v->sourceid = from->id;
-        v->mode = from->valuator->mode;
     } else if (to->valuator && !from->valuator)
     {
         ClassesPtr classes;
@@ -1177,7 +1176,7 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
 	int nval = v->numAxes - first;
 
 	ev->classes_reported |= (1 << ValuatorClass);
-	ev->classes_reported |= (dev->valuator->mode << ModeBitsShift);
+	ev->classes_reported |= valuator_get_mode(dev, 0) << ModeBitsShift;
 	ev->num_valuators = nval < 3 ? nval : 3;
 	switch (ev->num_valuators) {
 	case 3:
diff --git a/Xi/listdev.c b/Xi/listdev.c
index 3e5f3d9..2b2f294 100644
--- a/Xi/listdev.c
+++ b/Xi/listdev.c
@@ -230,10 +230,11 @@ CopySwapKeyClass(ClientPtr client, KeyClassPtr k, char **buf)
  */
 
 static int
-CopySwapValuatorClass(ClientPtr client, ValuatorClassPtr v, char **buf)
+CopySwapValuatorClass(ClientPtr client, DeviceIntPtr dev, char **buf)
 {
     int i, j, axes, t_axes;
     char n;
+    ValuatorClassPtr v = dev->valuator;
     xValuatorInfoPtr v2;
     AxisInfo *a;
     xAxisInfoPtr a2;
@@ -247,7 +248,7 @@ CopySwapValuatorClass(ClientPtr client, ValuatorClassPtr v, char **buf)
 	v2->class = ValuatorClass;
 	v2->length = sizeof(xValuatorInfo) + t_axes * sizeof(xAxisInfo);
 	v2->num_axes = t_axes;
-	v2->mode = v->mode & DeviceMode;
+	v2->mode = valuator_get_mode(dev, 0);
 	v2->motion_buffer_size = v->numMotionEvents;
 	if (client && client->swapped) {
 	    swapl(&v2->motion_buffer_size, n);
@@ -286,7 +287,7 @@ CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes,
     }
     if (dev->valuator != NULL) {
 	(*num_classes) +=
-	    CopySwapValuatorClass(client, dev->valuator, classbuf);
+	    CopySwapValuatorClass(client, dev, classbuf);
     }
 }
 
diff --git a/Xi/queryst.c b/Xi/queryst.c
index 9c9e4e0..73af76d 100644
--- a/Xi/queryst.c
+++ b/Xi/queryst.c
@@ -151,6 +151,7 @@ ProcXQueryDeviceState(ClientPtr client)
 	tv->class = ValuatorClass;
 	tv->length = sizeof(xValuatorState) + v->numAxes * 4;
 	tv->num_valuators = v->numAxes;
+	tv->mode = valuator_get_mode(dev, 0);
 	tv->mode |= (dev->proximity && !dev->proximity->in_proximity) ? OutOfProximity : 0;
 	buf += sizeof(xValuatorState);
 	for (i = 0, values = v->axisVal; i < v->numAxes; i++) {
diff --git a/Xi/setmode.c b/Xi/setmode.c
index ce2ad47..42e90f7 100644
--- a/Xi/setmode.c
+++ b/Xi/setmode.c
@@ -110,7 +110,7 @@ ProcXSetDeviceMode(ClientPtr client)
 	rep.status = SetDeviceMode(client, dev, stuff->mode);
 
     if (rep.status == Success)
-	dev->valuator->mode = stuff->mode;
+        valuator_set_mode(dev, VALUATOR_MODE_ALL_AXES, stuff->mode);
     else if (rep.status != AlreadyGrabbed)
     {
 	switch(rep.status) {
diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index 9925e16..0360517 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -301,7 +301,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
 
     if (axesCount > DMX_MAX_AXES) axesCount = DMX_MAX_AXES;
 
-    if ((pDevice->valuator->mode == Relative) && axesCount == 2) {
+    if ((valuator_get_mode(pDevice,0) == Relative) && axesCount == 2) {
                                 /* The dmx console is a relative mode
                                  * device that sometimes reports
                                  * absolute motion.  It only has two
diff --git a/include/inputstr.h b/include/inputstr.h
index cd66876..d4c253e 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -240,7 +240,6 @@ typedef struct _ValuatorClassRec {
     AxisInfoPtr 	  axes;
     unsigned short	  numAxes;
     double		  *axisVal; /* always absolute, but device-coord system */
-    CARD8	 	  mode;
     ValuatorAccelerationRec	accelScheme;
 } ValuatorClassRec, *ValuatorClassPtr;
 
diff --git a/test/input.c b/test/input.c
index f94a4d4..daadbea 100644
--- a/test/input.c
+++ b/test/input.c
@@ -66,7 +66,6 @@ static void dix_init_valuators(void)
     g_assert(val);
     g_assert(val->numAxes == num_axes);
     g_assert(val->numMotionEvents == 0);
-    g_assert(val->mode == Absolute);
     g_assert(val->axisVal);
 
     for (i = 0; i < num_axes; i++)
@@ -74,6 +73,7 @@ static void dix_init_valuators(void)
         g_assert(val->axisVal[i] == 0);
         g_assert(val->axes->min_value == NO_AXIS_LIMITS);
         g_assert(val->axes->max_value == NO_AXIS_LIMITS);
+        g_assert(val->axes->mode == Absolute);
     }
 
     g_assert(dev.last.numValuators == num_axes);
commit 5cf3b654fccf09de63a3f983c85096cda78fb693
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 22 15:49:40 2010 +1000

    input: move proximity state into ProximityClassRec.
    
    Previously the OutOfProximity bit in the valuator mode.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 1f59001..9bff2b3 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -891,9 +891,9 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
         mask = PointerMotionMask | b->state | b->motionMask;
         SetMaskForEvent(device->id, mask, MotionNotify);
     } else if (event->type == ET_ProximityIn)
-	device->valuator->mode &= ~OutOfProximity;
+	device->proximity->in_proximity = TRUE;
     else if (event->type == ET_ProximityOut)
-	device->valuator->mode |= OutOfProximity;
+	device->proximity->in_proximity = FALSE;
 
     return DEFAULT;
 }
@@ -1112,6 +1112,7 @@ InitProximityClassDeviceStruct(DeviceIntPtr dev)
     if (!proxc)
 	return FALSE;
     proxc->sourceid = dev->id;
+    proxc->in_proximity = TRUE;
     dev->proximity = proxc;
     return TRUE;
 }
@@ -1145,6 +1146,9 @@ InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int
     ax->max_resolution = max_res;
     ax->label = label;
     ax->mode = mode;
+
+    if (mode & OutOfProximity)
+        dev->proximity->in_proximity = FALSE;
 }
 
 static void
diff --git a/Xi/queryst.c b/Xi/queryst.c
index 65a43d1..9c9e4e0 100644
--- a/Xi/queryst.c
+++ b/Xi/queryst.c
@@ -151,7 +151,7 @@ ProcXQueryDeviceState(ClientPtr client)
 	tv->class = ValuatorClass;
 	tv->length = sizeof(xValuatorState) + v->numAxes * 4;
 	tv->num_valuators = v->numAxes;
-	tv->mode = v->mode;
+	tv->mode |= (dev->proximity && !dev->proximity->in_proximity) ? OutOfProximity : 0;
 	buf += sizeof(xValuatorState);
 	for (i = 0, values = v->axisVal; i < v->numAxes; i++) {
 	    if (rc != BadAccess)
diff --git a/dix/devices.c b/dix/devices.c
index 45edd37..a4c8e76 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1251,9 +1251,12 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
     valc->numMotionEvents = numMotionEvents;
     valc->motionHintWindow = NullWindow;
     valc->numAxes = numAxes;
-    valc->mode = mode;
     valc->axes = (AxisInfoPtr)(valc + 1);
     valc->axisVal = (double *)(valc->axes + numAxes);
+
+    if (mode & OutOfProximity)
+        InitProximityClassDeviceStruct(dev);
+
     dev->valuator = valc;
 
     AllocateMotionHistory(dev);
diff --git a/include/inputstr.h b/include/inputstr.h
index dfab791..cd66876 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -273,7 +273,7 @@ typedef struct _FocusClassRec {
 
 typedef struct _ProximityClassRec {
     int		sourceid;
-    char	pad;
+    char	in_proximity;
 } ProximityClassRec, *ProximityClassPtr;
 
 typedef struct _AbsoluteClassRec {
commit e909af88bf17dbadcc00d50c13a5bdb6001367be
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 22 14:22:44 2010 +1000

    dmx: clarify a valuator mode condition.
    
    Relative is defined as 0, so change the condition to be more obvious.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index d22cf06..9925e16 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -301,7 +301,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
 
     if (axesCount > DMX_MAX_AXES) axesCount = DMX_MAX_AXES;
 
-    if (!pDevice->valuator->mode && axesCount == 2) {
+    if ((pDevice->valuator->mode == Relative) && axesCount == 2) {
                                 /* The dmx console is a relative mode
                                  * device that sometimes reports
                                  * absolute motion.  It only has two
commit b5ef88c911f697530ddc2c7302fce15ba2ead4b2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 22 14:02:17 2010 +1000

    dix: clip absolute axes depending on their mode.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index bbad692..6bec39c 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -767,9 +767,11 @@ moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
     /* if attached, clip both x and y to the defined limits (usually
      * co-ord space limit). If it is attached, we need x/y to go over the
      * limits to be able to change screens. */
-    if(dev->u.master && dev->valuator->mode == Absolute) {
-        clipAxis(dev, 0, x);
-        clipAxis(dev, 1, y);
+    if(dev->u.master) {
+        if (valuator_get_mode(dev, 0) == Absolute)
+            clipAxis(dev, 0, x);
+        if (valuator_get_mode(dev, 1) == Absolute)
+            clipAxis(dev, 1, y);
     }
 
     /* calc other axes, clip, drop back into valuators */
commit ea567b675f814ac41e75f1ed8ded0ac3e9d552a8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 22 14:01:11 2010 +1000

    dix: populate motion history only if the mode matches the first axis.
    
    XI1 doesn't cater for mixed mode devices, so bail out on the first valuator
    that has a different mode.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index 1d41fb7..bbad692 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -378,8 +378,7 @@ AllocateMotionHistory(DeviceIntPtr pDev)
         int numAxes;
         /* XI1 doesn't understand mixed mode devices */
         for (numAxes = 0; numAxes < v->numAxes; numAxes++)
-            if ((v->axes[numAxes].mode & DeviceMode) !=
-                (v->mode & DeviceMode))
+            if (valuator_get_mode(pDev, numAxes) != valuator_get_mode(pDev, 0))
                 break;
         size = sizeof(INT32) * numAxes;
     }
@@ -564,8 +563,7 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
         for (i = 0; i < v->numAxes; i++)
         {
             /* XI1 doesn't support mixed mode devices */
-            if ((pDev->valuator->axes[i].mode & DeviceMode) !=
-                (pDev->valuator->mode & DeviceMode))
+            if (valuator_get_mode(pDev, i) != valuator_get_mode(pDev, 0))
                 break;
             if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i))
             {
commit 4381b70f5aa293400735e9b4e5a792408afa25a2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 22 13:57:27 2010 +1000

    input: add valuator_get_mode() helper.
    
    Returns the mode of the specified valuator.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/devices.c b/dix/devices.c
index 3548be4..45edd37 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2570,3 +2570,25 @@ AllocDevicePair (ClientPtr client, char* name,
     return Success;
 }
 
+/**
+ * Return Relative or Absolute for the device.
+ */
+int valuator_get_mode(DeviceIntPtr dev, int axis)
+{
+    return (dev->valuator->axes[axis].mode & DeviceMode);
+}
+
+/**
+ * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then
+ * set the mode for all axes.
+ */
+void valuator_set_mode(DeviceIntPtr dev, int axis, int mode)
+{
+    if (axis != VALUATOR_MODE_ALL_AXES)
+        dev->valuator->axes[axis].mode = mode;
+    else {
+        int i;
+        for (i = 0; i < dev->valuator->numAxes; i++)
+            dev->valuator->axes[axis].mode = mode;
+    }
+}
diff --git a/include/input.h b/include/input.h
index 76df4ff..8feac28 100644
--- a/include/input.h
+++ b/include/input.h
@@ -546,6 +546,10 @@ extern _X_EXPORT void DDXRingBell(
     int pitch,
     int duration);
 
+#define VALUATOR_MODE_ALL_AXES -1
+extern _X_HIDDEN int valuator_get_mode(DeviceIntPtr dev, int axis);
+extern _X_HIDDEN void valuator_set_mode(DeviceIntPtr dev, int axis, int mode);
+
 /* Set to TRUE by default - os/utils.c sets it to FALSE on user request,
    xfixes/cursor.c uses it to determine if the cursor is enabled */
 extern Bool EnableCursor;
commit 6f6f460c2485d16d126a1ab5d939083c322dc3dd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 22 13:48:06 2010 +1000

    dix: send proximity events if one or more axes are Absolute.
    
    We only skip relative events for proximity, not absolute ones. Now with
    mixed mode, just unset those axes that are relative.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index 0b6d6d3..1d41fb7 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1232,7 +1232,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 int
 GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in)
 {
-    int num_events = 1;
+    int num_events = 1, i;
     DeviceEvent *event;
     ValuatorMask mask;
 
@@ -1248,9 +1248,13 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const Valuato
 
     valuator_mask_copy(&mask, mask_in);
 
-    /* Do we need to send a DeviceValuator event? */
-    if ((pDev->valuator->mode & 1) == Relative)
-        valuator_mask_zero(&mask);
+    /* ignore relative axes for proximity. */
+    for (i = 0; i < valuator_mask_num_valuators(&mask); i++)
+    {
+        if (valuator_mask_isset(&mask, i) &&
+            pDev->valuator->axes[i].mode == Relative)
+            valuator_mask_unset(&mask, i);
+    }
 
     events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
commit 65c0fc81eb920085e650b8c9e874c9dd26c7ec98
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Fri Jul 16 09:21:19 2010 -0400

    Add support for per-axis valuator modes (Relative/Absolute)
    
    The XI2 protocol supports per-axis modes, but the server so far does
    not. This change adds support in the server.
    
    A complication is the fact that XI1 does not support per-axis modes.
    The solution provided here is to set a per-device mode that defines the
    mode of at least the first two valuators (X and Y). Note that initializing
    the first two axes to a different mode than the device mode will fail.
    
    For XI1 events, any axes following the first two that have the same mode
    will be sent to clients, up to the first axis that has a different mode.
    Thus, if a device has relative, then absolute, then relative mode axes,
    only the first block of relative axes will be sent over XI1.
    
    Since the XI2 protocol supports per-axis modes, all axes are sent to the
    client.
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 9689ef8..1f59001 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -1127,7 +1127,7 @@ InitProximityClassDeviceStruct(DeviceIntPtr dev)
  */
 void
 InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
-		       int resolution, int min_res, int max_res)
+		       int resolution, int min_res, int max_res, int mode)
 {
     AxisInfoPtr ax;
 
@@ -1144,6 +1144,7 @@ InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int
     ax->min_resolution = min_res;
     ax->max_resolution = max_res;
     ax->label = label;
+    ax->mode = mode;
 }
 
 static void
diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
index 303c8b2..c8b3d7e 100644
--- a/Xi/xiquerydevice.c
+++ b/Xi/xiquerydevice.c
@@ -349,7 +349,7 @@ ListValuatorInfo(DeviceIntPtr dev, xXIValuatorInfo* info, int axisnumber,
     info->value.frac = (int)(v->axisVal[axisnumber] * (1 << 16) * (1 << 16));
     info->resolution = v->axes[axisnumber].resolution;
     info->number = axisnumber;
-    info->mode = v->mode; /* Server doesn't have per-axis mode yet */
+    info->mode = v->axes[axisnumber].mode;
     info->sourceid = v->sourceid;
 
     if (!reportState)
diff --git a/dix/devices.c b/dix/devices.c
index 6f6f0fa..3548be4 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1260,7 +1260,7 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
 
     for (i=0; i<numAxes; i++) {
         InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS,
-                               0, 0, 0);
+                               0, 0, 0, mode);
 	valc->axisVal[i]=0;
     }
 
@@ -2357,8 +2357,7 @@ RecalculateMasterButtons(DeviceIntPtr slave)
                 event.valuators[i].min = master->valuator->axes[i].min_value;
                 event.valuators[i].max = master->valuator->axes[i].max_value;
                 event.valuators[i].resolution = master->valuator->axes[i].resolution;
-                /* This should, eventually, be a per-axis mode */
-                event.valuators[i].mode = master->valuator->mode;
+                event.valuators[i].mode = master->valuator->axes[i].mode;
                 event.valuators[i].name = master->valuator->axes[i].label;
             }
         }
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 0f747c1..46eb4ff 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -261,6 +261,12 @@ eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
     }
 
     num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
+    if (num_events <= 0)
+    {
+        *count = 0;
+        return BadMatch;
+    }
+
     num_events++; /* the actual event event */
 
     *xi = calloc(num_events, sizeof(xEvent));
@@ -318,6 +324,12 @@ countValuators(DeviceEvent *ev, int *first)
 
     for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
     {
+        /* Assume mode of 0th valuator matches XI1 device mode. Stop when the
+         * event mode changes since XI1 can't handle mixed mode devices.
+         */
+        if (ev->valuators.mode[i] != ev->valuators.mode[0])
+            break;
+
         if (BitIsOn(ev->valuators.mask, i))
         {
             if (first_valuator == -1)
@@ -440,7 +452,7 @@ appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumbe
     info->value.frac = 0;
     info->resolution = dce->valuators[axisnumber].resolution;
     info->number = axisnumber;
-    info->mode = dce->valuators[axisnumber].mode; /* Server doesn't have per-axis mode yet */
+    info->mode = dce->valuators[axisnumber].mode;
     info->sourceid = dce->sourceid;
 
     return info->length * 4;
diff --git a/dix/getevents.c b/dix/getevents.c
index 6a44356..0b6d6d3 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -210,7 +210,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask)
         if (valuator_mask_isset(mask, i))
         {
             SetBit(event->valuators.mask, i);
-            if (dev->valuator->mode == Absolute)
+            if (dev->valuator->axes[i].mode == Absolute)
                 SetBit(event->valuators.mode, i);
             event->valuators.data[i] = valuator_mask_get(mask, i);
             event->valuators.data_frac[i] =
@@ -255,8 +255,7 @@ CreateClassesChangedEvent(EventList* event,
             dce->valuators[i].min = slave->valuator->axes[i].min_value;
             dce->valuators[i].max = slave->valuator->axes[i].max_value;
             dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
-            /* This should, eventually, be a per-axis mode */
-            dce->valuators[i].mode = slave->valuator->mode;
+            dce->valuators[i].mode = slave->valuator->axes[i].mode;
             dce->valuators[i].name = slave->valuator->axes[i].label;
         }
     }
@@ -374,8 +373,16 @@ AllocateMotionHistory(DeviceIntPtr pDev)
      */
     if (IsMaster(pDev))
         size = sizeof(INT32) * 3 * MAX_VALUATORS;
-    else
-        size = sizeof(INT32) * pDev->valuator->numAxes;
+    else {
+        ValuatorClassPtr v = pDev->valuator;
+        int numAxes;
+        /* XI1 doesn't understand mixed mode devices */
+        for (numAxes = 0; numAxes < v->numAxes; numAxes++)
+            if ((v->axes[numAxes].mode & DeviceMode) !=
+                (v->mode & DeviceMode))
+                break;
+        size = sizeof(INT32) * numAxes;
+    }
 
     size += sizeof(Time);
 
@@ -556,6 +563,10 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
 
         for (i = 0; i < v->numAxes; i++)
         {
+            /* XI1 doesn't support mixed mode devices */
+            if ((pDev->valuator->axes[i].mode & DeviceMode) !=
+                (pDev->valuator->mode & DeviceMode))
+                break;
             if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i))
             {
                 buff += 3 * sizeof(INT32);
@@ -769,7 +780,7 @@ moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
         if (valuator_mask_isset(mask, i))
         {
             dev->last.valuators[i] += valuator_mask_get(mask, i);
-            if (dev->valuator->mode == Absolute)
+            if (dev->valuator->axes[i].mode == Absolute)
                 clipAxis(dev, i, &dev->last.valuators[i]);
             valuator_mask_set(mask, i, dev->last.valuators[i]);
         }
diff --git a/hw/dmx/input/dmxinputinit.c b/hw/dmx/input/dmxinputinit.c
index 829a289..7cac86f 100644
--- a/hw/dmx/input/dmxinputinit.c
+++ b/hw/dmx/input/dmxinputinit.c
@@ -476,7 +476,8 @@ static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
                     InitValuatorAxisStruct(pDevice, i, axis_labels[i],
                                            info.minval[i], info.maxval[i],
                                            info.res[i],
-                                           info.minres[i], info.maxres[i]);
+                                           info.minres[i], info.maxres[i],
+                                           Relative);
             } else if (info.numRelAxes) {
                 InitValuatorClassDeviceStruct(pDevice, info.numRelAxes,
                                               axis_labels,
@@ -486,7 +487,8 @@ static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
                     InitValuatorAxisStruct(pDevice, i, axis_labels[i],
                                            info.minval[i],
                                            info.maxval[i], info.res[i],
-                                           info.minres[i], info.maxres[i]);
+                                           info.minres[i], info.maxres[i],
+                                           Relative);
             } else if (info.numAbsAxes) {
                 InitValuatorClassDeviceStruct(pDevice, info.numAbsAxes,
                                               axis_labels,
@@ -497,7 +499,7 @@ static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
                                            axis_labels[i],
                                            info.minval[i], info.maxval[i],
                                            info.res[i], info.minres[i],
-                                           info.maxres[i]);
+                                           info.maxres[i], Absolute);
             }
         }
         if (info.focusClass)       InitFocusClassDeviceStruct(pDevice);
diff --git a/hw/dmx/input/dmxmotion.c b/hw/dmx/input/dmxmotion.c
index a86b62e..1aae5fe 100644
--- a/hw/dmx/input/dmxmotion.c
+++ b/hw/dmx/input/dmxmotion.c
@@ -125,12 +125,11 @@ void dmxPointerPutMotionEvent(DeviceIntPtr pDevice,
                                 /* Initialize the data from the known
                                  * values (if Absolute) or to zero (if
                                  * Relative) */
-    if (pDevice->valuator->mode == Absolute) {
-        for (i = 0; i < numAxes; i++) 
+    for (i = 0; i < numAxes; i++) {
+        if (pDevice->valuator->axes[i].mode == Absolute)
             dmxLocal->history[OFFSET(dmxLocal->tail,i+1)]
                 = dmxLocal->valuators[i];
-    } else {
-        for (i = 0; i < numAxes; i++) 
+        else
             dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] = 0;
     }
     
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 72c9322..b910cf8 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -1325,13 +1325,13 @@ xf86XInputSetScreen(InputInfoPtr	pInfo,
 
 void
 xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
-			   int resolution, int min_res, int max_res)
+			   int resolution, int min_res, int max_res, int mode)
 {
     if (!dev || !dev->valuator)
         return;
 
     InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
-			   max_res);
+			   max_res, mode);
 }
 
 /*
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 829bf78..8ee0c68 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -147,7 +147,7 @@ extern _X_EXPORT void xf86XInputSetScreen(InputInfoPtr pInfo, int screen_number,
 extern _X_EXPORT void xf86ProcessCommonOptions(InputInfoPtr pInfo, pointer options);
 extern _X_EXPORT void xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval,
 				int maxval, int resolution, int min_res,
-				int max_res);
+				int max_res, int mode);
 extern _X_EXPORT void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum);
 extern _X_EXPORT void xf86AddEnabledDevice(InputInfoPtr pInfo);
 extern _X_EXPORT void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c
index 2362fac..018ce78 100644
--- a/hw/xquartz/darwin.c
+++ b/hw/xquartz/darwin.c
@@ -316,8 +316,8 @@ static int DarwinMouseProc(DeviceIntPtr pPointer, int what) {
                                     axes_labels);
             pPointer->valuator->mode = Absolute; // Relative
             InitAbsoluteClassDeviceStruct(pPointer);
-//            InitValuatorAxisStruct(pPointer, 0, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
-//            InitValuatorAxisStruct(pPointer, 1, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+//            InitValuatorAxisStruct(pPointer, 0, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+//            InitValuatorAxisStruct(pPointer, 1, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
             break;
         case DEVICE_ON:
             pPointer->public.on = TRUE;
@@ -366,11 +366,11 @@ static int DarwinTabletProc(DeviceIntPtr pPointer, int what) {
             InitProximityClassDeviceStruct(pPointer);
 			InitAbsoluteClassDeviceStruct(pPointer);
 
-            InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
-            InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
-            InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
-            InitValuatorAxisStruct(pPointer, 3, axes_labels[3], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
-            InitValuatorAxisStruct(pPointer, 4, axes_labels[4], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+            InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+            InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+            InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+            InitValuatorAxisStruct(pPointer, 3, axes_labels[3], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
+            InitValuatorAxisStruct(pPointer, 4, axes_labels[4], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1, Absolute);
 //          pPointer->use = IsXExtensionDevice;
             break;
         case DEVICE_ON:
diff --git a/include/exevents.h b/include/exevents.h
index b64252f..bfee385 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -48,7 +48,8 @@ extern _X_EXPORT void InitValuatorAxisStruct(
 	int                    /* maxval */,
 	int                    /* resolution */,
 	int                    /* min_res */,
-	int                    /* max_res */);
+	int                    /* max_res */,
+	int                    /* mode */);
 
 /* Input device properties */
 extern _X_EXPORT void XIDeleteAllDeviceProperties(
diff --git a/include/inputstr.h b/include/inputstr.h
index ec9749e..dfab791 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -218,6 +218,7 @@ typedef struct _AxisInfo {
     int		min_value;
     int		max_value;
     Atom	label;
+    CARD8	mode;
 } AxisInfo, *AxisInfoPtr;
 
 typedef struct _ValuatorAccelerationRec {
commit 9696c782c8cb86b06d12949899582533a2e04cfe
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Oct 19 12:52:57 2010 +1000

    test: valuator_mask tests.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/test/input.c b/test/input.c
index b90d3b4..f94a4d4 100644
--- a/test/input.c
+++ b/test/input.c
@@ -38,6 +38,7 @@
 #include "exevents.h"
 #include "dixgrabs.h"
 #include "eventstr.h"
+#include "inpututils.h"
 #include <glib.h>
 
 /**
@@ -901,12 +902,88 @@ static void dix_input_attributes(void)
     FreeInputAttributes(new);
 }
 
+static void dix_input_valuator_masks(void)
+{
+    ValuatorMask *mask = NULL, *copy;
+    int nvaluators = MAX_VALUATORS;
+    int valuators[nvaluators];
+    int i;
+    int first_val, num_vals;
+
+    for (i = 0; i < nvaluators; i++)
+        valuators[i] = i;
+
+    mask = valuator_mask_new(nvaluators);
+    g_assert(mask != NULL);
+    g_assert(valuator_mask_size(mask) == 0);
+    g_assert(valuator_mask_num_valuators(mask) == 0);
+
+    for (i = 0; i < nvaluators; i++)
+    {
+        g_assert(!valuator_mask_isset(mask, i));
+        valuator_mask_set(mask, i, valuators[i]);
+        g_assert(valuator_mask_isset(mask, i));
+        g_assert(valuator_mask_get(mask, i) == valuators[i]);
+        g_assert(valuator_mask_size(mask) == i + 1);
+        g_assert(valuator_mask_num_valuators(mask) == i + 1);
+    }
+
+    for (i = 0; i < nvaluators; i++)
+    {
+        g_assert(valuator_mask_isset(mask, i));
+        valuator_mask_unset(mask, i);
+        /* we're removing valuators from the front, so size should stay the
+         * same until the last bit is removed */
+        if (i < nvaluators - 1)
+            g_assert(valuator_mask_size(mask) == nvaluators);
+        g_assert(!valuator_mask_isset(mask, i));
+    }
+
+    g_assert(valuator_mask_size(mask) == 0);
+    valuator_mask_zero(mask);
+    g_assert(valuator_mask_size(mask) == 0);
+    g_assert(valuator_mask_num_valuators(mask) == 0);
+    for (i = 0; i < nvaluators; i++)
+        g_assert(!valuator_mask_isset(mask, i));
+
+    first_val = 5;
+    num_vals = 6;
+
+    valuator_mask_set_range(mask, first_val, num_vals, valuators);
+    g_assert(valuator_mask_size(mask) == first_val + num_vals);
+    g_assert(valuator_mask_num_valuators(mask) == num_vals);
+    for (i = 0; i < nvaluators; i++)
+    {
+        if (i < first_val || i >= first_val + num_vals)
+            g_assert(!valuator_mask_isset(mask, i));
+        else
+        {
+            g_assert(valuator_mask_isset(mask, i));
+            g_assert(valuator_mask_get(mask, i) == valuators[i - first_val]);
+        }
+    }
+
+    copy = valuator_mask_new(nvaluators);
+    valuator_mask_copy(copy, mask);
+    g_assert(mask != copy);
+    g_assert(valuator_mask_size(mask) == valuator_mask_size(copy));
+    g_assert(valuator_mask_num_valuators(mask) == valuator_mask_num_valuators(copy));
+
+    for (i = 0; i < nvaluators; i++)
+    {
+        g_assert(valuator_mask_isset(mask, i) == valuator_mask_isset(copy, i));
+        g_assert(valuator_mask_get(mask, i) == valuator_mask_get(copy, i));
+    }
+
+    free(mask);
+}
 
 int main(int argc, char** argv)
 {
     g_test_init(&argc, &argv,NULL);
     g_test_bug_base("https://bugzilla.freedesktop.org/show_bug.cgi?id=");
 
+    g_test_add_func("/dix/input/valuator-masks", dix_input_valuator_masks);
     g_test_add_func("/dix/input/attributes", dix_input_attributes);
     g_test_add_func("/dix/input/init-valuators", dix_init_valuators);
     g_test_add_func("/dix/input/event-core-conversion", dix_event_to_core_conversion);
commit 2362adc2da9745e01c79ed4905aa81926355c4e2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Oct 19 10:59:09 2010 +1000

    dix: remove valuator_mask_copy_valuators, not needed anymore.
    
    With the switch to masks internally, this isn't needed anymore.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/inpututils.c b/dix/inpututils.c
index 9b4f108..2877804 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -527,31 +527,6 @@ valuator_mask_unset(ValuatorMask *mask, int valuator)
     }
 }
 
-
-/**
- * Copy the valuator data from the given mask and return it as one closed
- * array (i.e., with holes where the masks are unset.
- * If valuators_in is not NULL, the valuator data will be copied into
- * valuators_in. The caller is responsible to allocate enough memory.
- *
- * Otherwise, memory is allocated and returned.
- */
-int*
-valuator_mask_copy_valuators(const ValuatorMask *mask, int *valuators_in)
-{
-    int *valuators;
-
-    if (!valuators_in)
-        valuators = calloc(valuator_mask_size(mask), sizeof(int));
-    else
-        valuators = valuators_in;
-
-    memcpy(valuators, mask->valuators,
-           valuator_mask_size(mask) * sizeof(int));
-
-    return valuators;
-}
-
 void
 valuator_mask_copy(ValuatorMask *dest, const ValuatorMask *src)
 {
diff --git a/include/inpututils.h b/include/inpututils.h
index 56bb75d..54b5764 100644
--- a/include/inpututils.h
+++ b/include/inpututils.h
@@ -41,7 +41,6 @@ struct _ValuatorMask {
 extern _X_HIDDEN int valuator_mask_size(const ValuatorMask *mask);
 extern _X_HIDDEN int valuator_mask_isset(const ValuatorMask *mask, int bit);
 extern _X_HIDDEN void valuator_mask_unset(ValuatorMask *mask, int bit);
-extern _X_HIDDEN int* valuator_mask_copy_valuators(const ValuatorMask *mask, int *valuators_in);
 extern _X_HIDDEN int valuator_mask_num_valuators(const ValuatorMask *mask);
 extern _X_HIDDEN void valuator_mask_copy(ValuatorMask *dest, const ValuatorMask *src);
 extern _X_HIDDEN int valuator_mask_get(const ValuatorMask *mask, int valnum);
commit 2b04a3ef739a7ba5708400999e5d81418236a0a4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Oct 19 09:58:58 2010 +1000

    xfree86: convert xf86Post{Motion|Key|Button|Proximity}Event to masks
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index cf54fd2..72c9322 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -972,16 +972,17 @@ xf86PostMotionEvent(DeviceIntPtr	device,
 {
     va_list var;
     int i = 0;
-    static int valuators[MAX_VALUATORS];
+    ValuatorMask mask;
 
     XI_VERIFY_VALUATORS(num_valuators);
 
+    valuator_mask_zero(&mask);
     va_start(var, num_valuators);
     for (i = 0; i < num_valuators; i++)
-        valuators[i] = va_arg(var, int);
+        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
     va_end(var);
 
-    xf86PostMotionEventP(device, is_absolute, first_valuator, num_valuators, valuators);
+    xf86PostMotionEventM(device, is_absolute, &mask);
 }
 
 void
@@ -1060,18 +1061,17 @@ xf86PostProximityEvent(DeviceIntPtr	device,
 {
     va_list var;
     int i;
-    int valuators[MAX_VALUATORS];
+    ValuatorMask mask;
 
     XI_VERIFY_VALUATORS(num_valuators);
 
+    valuator_mask_zero(&mask);
     va_start(var, num_valuators);
     for (i = 0; i < num_valuators; i++)
-        valuators[i] = va_arg(var, int);
+        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
     va_end(var);
 
-    xf86PostProximityEventP(device, is_in, first_valuator, num_valuators,
-			    valuators);
-
+    xf86PostProximityEventM(device, is_in, &mask);
 }
 
 void
@@ -1113,19 +1113,19 @@ xf86PostButtonEvent(DeviceIntPtr	device,
                     ...)
 {
     va_list var;
-    int valuators[MAX_VALUATORS];
+    ValuatorMask mask;
     int i = 0;
 
     XI_VERIFY_VALUATORS(num_valuators);
 
+    valuator_mask_zero(&mask);
+
     va_start(var, num_valuators);
     for (i = 0; i < num_valuators; i++)
-        valuators[i] = va_arg(var, int);
+        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
     va_end(var);
 
-    xf86PostButtonEventP(device, is_absolute, button, is_down, first_valuator,
-			 num_valuators, valuators);
-
+    xf86PostButtonEventM(device, is_absolute, button, is_down, &mask);
 }
 
 void
@@ -1192,18 +1192,18 @@ xf86PostKeyEvent(DeviceIntPtr	device,
 {
     va_list var;
     int i = 0;
-    static int valuators[MAX_VALUATORS];
+    ValuatorMask mask;
 
     XI_VERIFY_VALUATORS(num_valuators);
 
+    valuator_mask_zero(&mask);
+
     va_start(var, num_valuators);
     for (i = 0; i < num_valuators; i++)
-      valuators[i] = va_arg(var, int);
+        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
     va_end(var);
 
-    xf86PostKeyEventP(device, key_code, is_down, is_absolute, first_valuator,
-		      num_valuators, valuators);
-
+    xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
 }
 
 void
commit 0418a39e71e50b88e050b0d8a758265b17c4bf0e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Oct 18 15:55:53 2010 +1000

    dix: get rid of the now-superfluous valuator arrays in GPE and friends.
    
    The valuators are stored inside the mask, use it from there. are stored
    inside the mask, use it from there. are stored inside the mask, use it from
    there. are stored inside the mask, use it from there.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index d04feed..6a44356 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -185,8 +185,7 @@ init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
 }
 
 static void
-set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, int *valuators,
-                  int32_t* data)
+set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, int32_t* data)
 {
     int i;
 
@@ -195,15 +194,14 @@ set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, int *valuators,
         if (valuator_mask_isset(mask, i))
         {
             SetBit(event->valuators.mask, i);
-            data[i] = valuators[i];
+            data[i] = valuator_mask_get(mask, i);
         }
     }
 }
 
 
 static void
-set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask,
-              int *valuators)
+set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask)
 {
     int i;
 
@@ -214,7 +212,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask,
             SetBit(event->valuators.mask, i);
             if (dev->valuator->mode == Absolute)
                 SetBit(event->valuators.mode, i);
-            event->valuators.data[i] = valuators[i];
+            event->valuators.data[i] = valuator_mask_get(mask, i);
             event->valuators.data_frac[i] =
                 dev->last.remainder[i] * (1 << 16) * (1 << 16);
         }
@@ -648,13 +646,17 @@ clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
  * Clip every axis in the list of valuators to its bounds.
  */
 static void
-clipValuators(DeviceIntPtr pDev, ValuatorMask *mask, int *valuators)
+clipValuators(DeviceIntPtr pDev, ValuatorMask *mask)
 {
     int i;
 
     for (i = 0; i < valuator_mask_size(mask); i++)
         if (valuator_mask_isset(mask, i))
-            clipAxis(pDev, i, &(valuators[i]));
+        {
+            int val = valuator_mask_get(mask, i);
+            clipAxis(pDev, i, &val);
+            valuator_mask_set(mask, i, val);
+        }
 }
 
 /**
@@ -702,18 +704,17 @@ UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_event
  *        @first+ at num.
  */
 static void
-moveAbsolute(DeviceIntPtr dev, int *x, int *y,
-             const ValuatorMask *mask, int *valuators)
+moveAbsolute(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
 {
     int i;
 
     if (valuator_mask_isset(mask, 0))
-        *x = *(valuators + 0);
+        *x = valuator_mask_get(mask, 0);
     else
         *x = dev->last.valuators[0];
 
     if (valuator_mask_isset(mask, 1))
-        *y = *(valuators + 1);
+        *y = valuator_mask_get(mask, 1);
     else
         *y = dev->last.valuators[1];
 
@@ -724,7 +725,7 @@ moveAbsolute(DeviceIntPtr dev, int *x, int *y,
     {
         if (valuator_mask_isset(mask, i))
         {
-            dev->last.valuators[i] = valuators[i];
+            dev->last.valuators[i] = valuator_mask_get(mask, i);
             clipAxis(dev, i, &dev->last.valuators[i]);
         }
     }
@@ -741,8 +742,7 @@ moveAbsolute(DeviceIntPtr dev, int *x, int *y,
  *        @first+ at num.
  */
 static void
-moveRelative(DeviceIntPtr dev, int *x, int *y,
-             ValuatorMask *mask, int *valuators)
+moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
 {
     int i;
 
@@ -750,10 +750,10 @@ moveRelative(DeviceIntPtr dev, int *x, int *y,
     *y = dev->last.valuators[1];
 
     if (valuator_mask_isset(mask, 0))
-        *x += *(valuators +0);
+        *x += valuator_mask_get(mask, 0);
 
-    if (valuator_mask_bit_isset(mask, 1))
-        *y += *(valuators + 1);
+    if (valuator_mask_isset(mask, 1))
+        *y += valuator_mask_get(mask, 1);
 
     /* if attached, clip both x and y to the defined limits (usually
      * co-ord space limit). If it is attached, we need x/y to go over the
@@ -768,10 +768,10 @@ moveRelative(DeviceIntPtr dev, int *x, int *y,
     {
         if (valuator_mask_isset(mask, i))
         {
-            dev->last.valuators[i] += valuators[i];
+            dev->last.valuators[i] += valuator_mask_get(mask, i);
             if (dev->valuator->mode == Absolute)
                 clipAxis(dev, i, &dev->last.valuators[i]);
-            valuators[i] = dev->last.valuators[i];
+            valuator_mask_set(mask, i, dev->last.valuators[i]);
         }
     }
 }
@@ -938,7 +938,6 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
     DeviceEvent *event;
     RawDeviceEvent *raw;
     ValuatorMask mask;
-    int valuators[MAX_VALUATORS];
 
     /* refuse events from disabled devices */
     if (!pDev->enabled)
@@ -971,15 +970,12 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 
     valuator_mask_copy(&mask, mask_in);
 
-    if (valuator_mask_size(&mask) > 0)
-        valuator_mask_copy_valuators(&mask, valuators);
-
     init_raw(pDev, raw, ms, type, key_code);
-    set_raw_valuators(raw, &mask, valuators, raw->valuators.data_raw);
+    set_raw_valuators(raw, &mask, raw->valuators.data_raw);
 
-    clipValuators(pDev, &mask, valuators);
+    clipValuators(pDev, &mask);
 
-    set_raw_valuators(raw, &mask, valuators, raw->valuators.data);
+    set_raw_valuators(raw, &mask, raw->valuators.data);
 
     event = (DeviceEvent*) events->event;
     init_event(pDev, event, ms);
@@ -994,9 +990,9 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 	set_key_up(pDev, key_code, KEY_POSTED);
     }
 
-    clipValuators(pDev, &mask, valuators);
+    clipValuators(pDev, &mask);
 
-    set_valuators(pDev, event, &mask, valuators);
+    set_valuators(pDev, event, &mask);
 
     return num_events;
 }
@@ -1053,19 +1049,19 @@ FreeEventList(EventListPtr list, int num_events)
 }
 
 static void
-transformAbsolute(DeviceIntPtr dev, int v[MAX_VALUATORS])
+transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
 {
     struct pixman_f_vector p;
 
     /* p' = M * p in homogeneous coordinates */
-    p.v[0] = v[0];
-    p.v[1] = v[1];
+    p.v[0] = valuator_mask_get(mask, 0);
+    p.v[1] = valuator_mask_get(mask, 1);
     p.v[2] = 1.0;
 
     pixman_f_transform_point(&dev->transform, &p);
 
-    v[0] = lround(p.v[0]);
-    v[1] = lround(p.v[1]);
+    valuator_mask_set(mask, 0, lround(p.v[0]));
+    valuator_mask_set(mask, 1, lround(p.v[1]));
 }
 
 /**
@@ -1099,7 +1095,6 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac;
     ScreenPtr scr = miPointerGetScreen(pDev);
     ValuatorMask mask;
-    int valuators[MAX_VALUATORS];
 
     /* refuse events from disabled devices */
     if (!pDev->enabled)
@@ -1125,38 +1120,44 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     valuator_mask_copy(&mask, mask_in);
 
-    if (valuator_mask_size(&mask) > 1)
-        valuator_mask_copy_valuators(&mask, valuators);
-
     init_raw(pDev, raw, ms, type, buttons);
-    set_raw_valuators(raw, &mask, valuators, raw->valuators.data_raw);
+    set_raw_valuators(raw, &mask, raw->valuators.data_raw);
 
     if (flags & POINTER_ABSOLUTE)
     {
         if (flags & POINTER_SCREEN) /* valuators are in screen coords */
         {
+            int scaled;
 
             if (valuator_mask_isset(&mask, 0))
-                valuators[0] = rescaleValuatorAxis(valuators[0], 0.0, &x_frac, NULL,
-                        pDev->valuator->axes + 0,
-                        scr->width);
+            {
+                scaled = rescaleValuatorAxis(valuator_mask_get(&mask, 0),
+                                             0.0, &x_frac, NULL,
+                                             pDev->valuator->axes + 0,
+                                             scr->width);
+                valuator_mask_set(&mask, 0, scaled);
+            }
             if (valuator_mask_isset(&mask, 1))
-                valuators[1] = rescaleValuatorAxis(valuators[1], 0.0, &y_frac, NULL,
-                        pDev->valuator->axes + 1,
-                        scr->height);
+            {
+                scaled = rescaleValuatorAxis(valuator_mask_get(&mask, 0),
+                                             0.0, &y_frac, NULL,
+                                             pDev->valuator->axes + 1,
+                                             scr->height);
+                valuator_mask_set(&mask, 1, scaled);
+            }
         }
 
-        transformAbsolute(pDev, valuators);
-        moveAbsolute(pDev, &x, &y, &mask, valuators);
+        transformAbsolute(pDev, &mask);
+        moveAbsolute(pDev, &x, &y, &mask);
     } else {
         if (flags & POINTER_ACCELERATE) {
             /* FIXME: Pointer acceleration only requires X and Y values. This
              * should be converted to masked valuators. */
             int vals[2];
             vals[0] = valuator_mask_isset(&mask, 0) ?
-                      valuators[0] : pDev->last.valuators[0];
+                      valuator_mask_get(&mask, 0) : pDev->last.valuators[0];
             vals[1] = valuator_mask_isset(&mask, 1) ?
-                      valuators[1] : pDev->last.valuators[1];
+                      valuator_mask_get(&mask, 1) : pDev->last.valuators[1];
             accelPointer(pDev, 0, 2, vals, ms);
 
             /* The pointer acceleration code modifies the fractional part
@@ -1164,21 +1165,21 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
             x_frac = pDev->last.remainder[0];
             y_frac = pDev->last.remainder[1];
         }
-        moveRelative(pDev, &x, &y, &mask, valuators);
+        moveRelative(pDev, &x, &y, &mask);
     }
 
-    set_raw_valuators(raw, &mask, valuators, raw->valuators.data);
+    set_raw_valuators(raw, &mask, raw->valuators.data);
 
     positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
     updateHistory(pDev, &mask, ms);
 
     /* Update the valuators with the true value sent to the client*/
     if (valuator_mask_isset(&mask, 0))
-        valuators[0] = x;
+        valuator_mask_set(&mask, 0, x);
     if (valuator_mask_isset(&mask, 1))
-        valuators[1] = y;
+        valuator_mask_set(&mask, 0, y);
 
-    clipValuators(pDev, &mask, valuators);
+    clipValuators(pDev, &mask);
 
     event = (DeviceEvent*) events->event;
     init_event(pDev, event, ms);
@@ -1204,7 +1205,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     event->root_x_frac = cx_frac;
     event->root_y_frac = cy_frac;
 
-    set_valuators(pDev, event, &mask, valuators);
+    set_valuators(pDev, event, &mask);
 
     return num_events;
 }
@@ -1223,7 +1224,6 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const Valuato
     int num_events = 1;
     DeviceEvent *event;
     ValuatorMask mask;
-    int valuators[MAX_VALUATORS];
 
     /* refuse events from disabled devices */
     if (!pDev->enabled)
@@ -1247,11 +1247,9 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const Valuato
     init_event(pDev, event, GetTimeInMillis());
     event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
 
-    if (valuator_mask_size(&mask) > 0)
-        valuator_mask_copy_valuators(&mask, valuators);
-    clipValuators(pDev, &mask, valuators);
+    clipValuators(pDev, &mask);
 
-    set_valuators(pDev, event, &mask, valuators);
+    set_valuators(pDev, event, &mask);
 
     return num_events;
 }
commit 675f4a8525d29ebad783351e17be785b2f32b2e8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Oct 19 13:37:46 2010 +1000

    Abstract valuator masks through a set of APIs.
    
    This commit introduces an abstraction API for handling masked valuators. The
    intent is that drivers just allocate a mask, set the data and pass the mask
    to the server. The actual storage type of the mask is hidden from the
    drivers.
    
    The new calls for drivers are:
        valuator_mask_new()     /* to allocate a valuator mask */
        valuator_mask_zero()    /* to reset a mask to zero */
        valuator_mask_set()     /* to set a valuator value */
    
    The new interface to the server is
        xf86PostMotionEventM()
        xf86PostButtonEventM()
        xf86PostKeyboardEventM()
        xf86PostProximityEventM()
    
    all taking a mask instead of the valuator array.
    
    The ValuatorMask is currently defined for MAX_VALUATORS fixed size due to
    memory allocation restrictions in SIGIO handlers.
    
    For easier review, a lot of the code still uses separate valuator arrays.
    This will be fixed in a later patch.
    
    This patch was initially written by Chase Douglas.
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/Xext/xtest.c b/Xext/xtest.c
index d7d254c..b26bc33 100644
--- a/Xext/xtest.c
+++ b/Xext/xtest.c
@@ -52,6 +52,7 @@
 #include "mipointer.h"
 #include "xserver-properties.h"
 #include "exevents.h"
+#include "inpututils.h"
 
 #include "modinit.h"
 
@@ -153,6 +154,7 @@ ProcXTestFakeInput(ClientPtr client)
     WindowPtr root;
     Bool extension = FALSE;
     deviceValuator *dv = NULL;
+    ValuatorMask mask;
     int valuators[MAX_VALUATORS] = {0};
     int numValuators = 0;
     int firstValuator = 0;
@@ -413,14 +415,14 @@ ProcXTestFakeInput(ClientPtr client)
 
     switch(type) {
         case MotionNotify:
-            nevents = GetPointerEvents(xtest_evlist, dev, type, 0, flags,
-                            firstValuator, numValuators, valuators);
+            valuator_mask_set_range(&mask, firstValuator, numValuators, valuators);
+            nevents = GetPointerEvents(xtest_evlist, dev, type, 0, flags, &mask);
             break;
         case ButtonPress:
         case ButtonRelease:
+            valuator_mask_set_range(&mask, firstValuator, numValuators, valuators);
             nevents = GetPointerEvents(xtest_evlist, dev, type, ev->u.u.detail,
-                                       flags, firstValuator,
-                                       numValuators, valuators);
+                                       flags, &mask);
             break;
         case KeyPress:
         case KeyRelease:
diff --git a/dix/getevents.c b/dix/getevents.c
index 4d32ed3..d04feed 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -46,6 +46,7 @@
 #include "mipointer.h"
 #include "eventstr.h"
 #include "eventconvert.h"
+#include "inpututils.h"
 
 #include <X11/extensions/XKBproto.h>
 #include "xkbsrv.h"
@@ -184,34 +185,40 @@ init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
 }
 
 static void
-set_raw_valuators(RawDeviceEvent *event, int first, int num, int *valuators, int32_t* data)
+set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, int *valuators,
+                  int32_t* data)
 {
     int i;
-    for (i = first; i < first + num; i++)
-        SetBit(event->valuators.mask, i);
 
-    memcpy(&data[first], valuators, num * sizeof(uint32_t));
+    for (i = 0; i < valuator_mask_size(mask); i++)
+    {
+        if (valuator_mask_isset(mask, i))
+        {
+            SetBit(event->valuators.mask, i);
+            data[i] = valuators[i];
+        }
+    }
 }
 
 
 static void
-set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator,
-              int num_valuators, int *valuators)
+set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask,
+              int *valuators)
 {
     int i;
 
-    for (i = first_valuator; i < first_valuator + num_valuators; i++)
+    for (i = 0; i < valuator_mask_size(mask); i++)
     {
-        SetBit(event->valuators.mask, i);
-        if (dev->valuator->mode == Absolute)
-            SetBit(event->valuators.mode, i);
-        event->valuators.data_frac[i] =
-            dev->last.remainder[i] * (1 << 16) * (1 << 16);
+        if (valuator_mask_isset(mask, i))
+        {
+            SetBit(event->valuators.mask, i);
+            if (dev->valuator->mode == Absolute)
+                SetBit(event->valuators.mode, i);
+            event->valuators.data[i] = valuators[i];
+            event->valuators.data_frac[i] =
+                dev->last.remainder[i] * (1 << 16) * (1 << 16);
+        }
     }
-
-    memcpy(&event->valuators.data[first_valuator],
-           valuators, num_valuators * sizeof(uint32_t));
-
 }
 
 void
@@ -524,12 +531,12 @@ GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
  *   for SDs: [time] [val0] [val1] ... [valn]
  *   for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
  *
- * For events that have some valuators unset (first_valuator > 0):
+ * For events that have some valuators unset:
  *      min_val == max_val == val == 0.
  */
 static void
-updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
-                    int num_valuators, int *valuators)
+updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
+                    int *valuators)
 {
     char *buff = (char *) pDev->valuator->motion;
     ValuatorClassPtr v;
@@ -548,17 +555,19 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
         buff += sizeof(Time);
 
         memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS);
-        buff += 3 * sizeof(INT32) * first_valuator;
 
-        for (i = first_valuator; i < first_valuator + num_valuators; i++)
+        for (i = 0; i < v->numAxes; i++)
         {
-            if (i >= v->numAxes)
-                break;
+            if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i))
+            {
+                buff += 3 * sizeof(INT32);
+                continue;
+            }
             memcpy(buff, &v->axes[i].min_value, sizeof(INT32));
             buff += sizeof(INT32);
             memcpy(buff, &v->axes[i].max_value, sizeof(INT32));
             buff += sizeof(INT32);
-            memcpy(buff, &valuators[i - first_valuator], sizeof(INT32));
+            memcpy(buff, &valuators[i], sizeof(INT32));
             buff += sizeof(INT32);
         }
     } else
@@ -571,9 +580,17 @@ updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
         buff += sizeof(Time);
 
         memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes);
-        buff += sizeof(INT32) * first_valuator;
 
-        memcpy(buff, valuators, sizeof(INT32) * num_valuators);
+        for (i = 0; i < MAX_VALUATORS; i++)
+        {
+            if (valuator_mask_size(mask) <= i || !valuator_mask_isset(mask, i))
+            {
+                buff += sizeof(INT32);
+                continue;
+            }
+            memcpy(buff, &valuators[i], sizeof(INT32));
+            buff += sizeof(INT32);
+        }
     }
 
     pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
@@ -631,13 +648,13 @@ clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
  * Clip every axis in the list of valuators to its bounds.
  */
 static void
-clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
-              int *valuators)
+clipValuators(DeviceIntPtr pDev, ValuatorMask *mask, int *valuators)
 {
     int i;
 
-    for (i = 0; i < num_valuators; i++)
-        clipAxis(pDev, i + first_valuator, &(valuators[i]));
+    for (i = 0; i < valuator_mask_size(mask); i++)
+        if (valuator_mask_isset(mask, i))
+            clipAxis(pDev, i, &(valuators[i]));
 }
 
 /**
@@ -680,36 +697,36 @@ UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_event
  * @param dev The device which's pointer is to be moved.
  * @param x Returns the x position of the pointer after the move.
  * @param y Returns the y position of the pointer after the move.
- * @param first The first valuator in @valuators
- * @param num Total number of valuators in @valuators.
+ * @param mask Bit mask of valid valuators.
  * @param valuators Valuator data for each axis between @first and
  *        @first+ at num.
  */
 static void
 moveAbsolute(DeviceIntPtr dev, int *x, int *y,
-             int first, int num, int *valuators)
+             const ValuatorMask *mask, int *valuators)
 {
     int i;
 
-
-    if (num >= 1 && first == 0)
+    if (valuator_mask_isset(mask, 0))
         *x = *(valuators + 0);
     else
         *x = dev->last.valuators[0];
 
-    if (first <= 1 && num >= (2 - first))
-        *y = *(valuators + 1 - first);
+    if (valuator_mask_isset(mask, 1))
+        *y = *(valuators + 1);
     else
         *y = dev->last.valuators[1];
 
     clipAxis(dev, 0, x);
     clipAxis(dev, 1, y);
 
-    i = (first > 2) ? 0 : 2;
-    for (; i < num; i++)
+    for (i = 2; i < valuator_mask_size(mask); i++)
     {
-        dev->last.valuators[i + first] = valuators[i];
-        clipAxis(dev, i, &dev->last.valuators[i + first]);
+        if (valuator_mask_isset(mask, i))
+        {
+            dev->last.valuators[i] = valuators[i];
+            clipAxis(dev, i, &dev->last.valuators[i]);
+        }
     }
 }
 
@@ -719,25 +736,24 @@ moveAbsolute(DeviceIntPtr dev, int *x, int *y,
  * @param dev The device which's pointer is to be moved.
  * @param x Returns the x position of the pointer after the move.
  * @param y Returns the y position of the pointer after the move.
- * @param first The first valuator in @valuators
- * @param num Total number of valuators in @valuators.
+ * @param mask Bit mask of valid valuators.
  * @param valuators Valuator data for each axis between @first and
  *        @first+ at num.
  */
 static void
 moveRelative(DeviceIntPtr dev, int *x, int *y,
-             int first, int num, int *valuators)
+             ValuatorMask *mask, int *valuators)
 {
     int i;
 
     *x = dev->last.valuators[0];
     *y = dev->last.valuators[1];
 
-    if (num >= 1 && first == 0)
+    if (valuator_mask_isset(mask, 0))
         *x += *(valuators +0);
 
-    if (first <= 1 && num >= (2 - first))
-        *y += *(valuators + 1 - first);
+    if (valuator_mask_bit_isset(mask, 1))
+        *y += *(valuators + 1);
 
     /* if attached, clip both x and y to the defined limits (usually
      * co-ord space limit). If it is attached, we need x/y to go over the
@@ -748,13 +764,15 @@ moveRelative(DeviceIntPtr dev, int *x, int *y,
     }
 
     /* calc other axes, clip, drop back into valuators */
-    i = (first > 2) ? 0 : 2;
-    for (; i < num; i++)
+    for (i = 2; i < valuator_mask_size(mask); i++)
     {
-        dev->last.valuators[i + first] += valuators[i];
-        if (dev->valuator->mode == Absolute)
-            clipAxis(dev, i, &dev->last.valuators[i + first]);
-        valuators[i] = dev->last.valuators[i + first];
+        if (valuator_mask_isset(mask, i))
+        {
+            dev->last.valuators[i] += valuators[i];
+            if (dev->valuator->mode == Absolute)
+                clipAxis(dev, i, &dev->last.valuators[i]);
+            valuators[i] = dev->last.valuators[i];
+        }
     }
 }
 
@@ -868,18 +886,18 @@ positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
  * Update the motion history for the device and (if appropriate) for its
  * master device.
  * @param dev Slave device to update.
- * @param first First valuator to append to history.
+ * @param mask Bit mask of valid valuators to append to history.
  * @param num Total number of valuators to append to history.
  * @param ms Current time
  */
 static void
-updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms)
+updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms)
 {
-    updateMotionHistory(dev, ms, first, num, &dev->last.valuators[first]);
+    updateMotionHistory(dev, ms, mask, dev->last.valuators);
     if (dev->u.master)
     {
         DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
-        updateMotionHistory(master, ms, first, num, &dev->last.valuators[first]);
+        updateMotionHistory(master, ms, mask, dev->last.valuators);
     }
 }
 
@@ -889,7 +907,10 @@ updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms)
  */
 int
 GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) {
-    return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL);
+    ValuatorMask mask;
+
+    valuator_mask_zero(&mask);
+    return GetKeyboardValuatorEvents(events, pDev, type, key_code, &mask);
 }
 
 
@@ -911,12 +932,12 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code)
  */
 int
 GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
-                          int key_code, int first_valuator,
-                          int num_valuators, const int *valuators_in) {
+                          int key_code, const ValuatorMask *mask_in) {
     int num_events = 0;
     CARD32 ms = 0;
     DeviceEvent *event;
     RawDeviceEvent *raw;
+    ValuatorMask mask;
     int valuators[MAX_VALUATORS];
 
     /* refuse events from disabled devices */
@@ -924,7 +945,6 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
         return 0;
 
     if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
-        num_valuators > MAX_VALUATORS ||
        (type != KeyPress && type != KeyRelease) ||
        (key_code < 8 || key_code > 255))
         return 0;
@@ -949,17 +969,17 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
     events++;
     num_events++;
 
-    memcpy(valuators, valuators_in, num_valuators * sizeof(int));
+    valuator_mask_copy(&mask, mask_in);
+
+    if (valuator_mask_size(&mask) > 0)
+        valuator_mask_copy_valuators(&mask, valuators);
 
     init_raw(pDev, raw, ms, type, key_code);
-    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
-                      raw->valuators.data_raw);
+    set_raw_valuators(raw, &mask, valuators, raw->valuators.data_raw);
 
-    if (num_valuators)
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
+    clipValuators(pDev, &mask, valuators);
 
-    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
-                      raw->valuators.data);
+    set_raw_valuators(raw, &mask, valuators, raw->valuators.data);
 
     event = (DeviceEvent*) events->event;
     init_event(pDev, event, ms);
@@ -974,10 +994,9 @@ GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
 	set_key_up(pDev, key_code, KEY_POSTED);
     }
 
-    if (num_valuators)
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
+    clipValuators(pDev, &mask, valuators);
 
-    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+    set_valuators(pDev, event, &mask, valuators);
 
     return num_events;
 }
@@ -1070,8 +1089,7 @@ transformAbsolute(DeviceIntPtr dev, int v[MAX_VALUATORS])
  */
 int
 GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
-                 int flags, int first_valuator, int num_valuators,
-                 const int *valuators_in) {
+                 int flags, const ValuatorMask *mask_in) {
     int num_events = 1;
     CARD32 ms;
     DeviceEvent *event;
@@ -1080,6 +1098,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
         cx, cy; /* only screen coordinates */
     float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac;
     ScreenPtr scr = miPointerGetScreen(pDev);
+    ValuatorMask mask;
     int valuators[MAX_VALUATORS];
 
     /* refuse events from disabled devices */
@@ -1088,13 +1107,14 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
 
     ms = GetTimeInMillis(); /* before pointer update to help precision */
 
-    if (!scr || !pDev->valuator || first_valuator < 0 ||
-        num_valuators > MAX_VALUATORS ||
-        ((num_valuators + first_valuator) > pDev->valuator->numAxes) ||
+    if (!scr || !pDev->valuator ||
         (type != MotionNotify && type != ButtonPress && type != ButtonRelease) ||
         (type != MotionNotify && !pDev->button) ||
-        ((type == ButtonPress || type == ButtonRelease) && !buttons) ||
-        (type == MotionNotify && num_valuators <= 0))
+        ((type == ButtonPress || type == ButtonRelease) && !buttons))
+        return 0;
+
+    if (type == MotionNotify &&
+        (!mask_in || valuator_mask_num_valuators(mask_in) <= 0))
         return 0;
 
     events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
@@ -1103,54 +1123,62 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     events++;
     num_events++;
 
-    memcpy(valuators, valuators_in, num_valuators * sizeof(int));
+    valuator_mask_copy(&mask, mask_in);
+
+    if (valuator_mask_size(&mask) > 1)
+        valuator_mask_copy_valuators(&mask, valuators);
 
     init_raw(pDev, raw, ms, type, buttons);
-    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
-                      raw->valuators.data_raw);
+    set_raw_valuators(raw, &mask, valuators, raw->valuators.data_raw);
 
     if (flags & POINTER_ABSOLUTE)
     {
         if (flags & POINTER_SCREEN) /* valuators are in screen coords */
         {
 
-            if (num_valuators >= 1 && first_valuator == 0)
+            if (valuator_mask_isset(&mask, 0))
                 valuators[0] = rescaleValuatorAxis(valuators[0], 0.0, &x_frac, NULL,
                         pDev->valuator->axes + 0,
                         scr->width);
-            if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-                valuators[1 - first_valuator] = rescaleValuatorAxis(valuators[1 - first_valuator], 0.0, &y_frac, NULL,
+            if (valuator_mask_isset(&mask, 1))
+                valuators[1] = rescaleValuatorAxis(valuators[1], 0.0, &y_frac, NULL,
                         pDev->valuator->axes + 1,
                         scr->height);
         }
 
         transformAbsolute(pDev, valuators);
-        moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators);
+        moveAbsolute(pDev, &x, &y, &mask, valuators);
     } else {
         if (flags & POINTER_ACCELERATE) {
-            accelPointer(pDev, first_valuator, num_valuators, valuators, ms);
+            /* FIXME: Pointer acceleration only requires X and Y values. This
+             * should be converted to masked valuators. */
+            int vals[2];
+            vals[0] = valuator_mask_isset(&mask, 0) ?
+                      valuators[0] : pDev->last.valuators[0];
+            vals[1] = valuator_mask_isset(&mask, 1) ?
+                      valuators[1] : pDev->last.valuators[1];
+            accelPointer(pDev, 0, 2, vals, ms);
+
             /* The pointer acceleration code modifies the fractional part
              * in-place, so we need to extract this information first */
             x_frac = pDev->last.remainder[0];
             y_frac = pDev->last.remainder[1];
         }
-        moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators);
+        moveRelative(pDev, &x, &y, &mask, valuators);
     }
 
-    set_raw_valuators(raw, first_valuator, num_valuators, valuators,
-            raw->valuators.data);
+    set_raw_valuators(raw, &mask, valuators, raw->valuators.data);
 
     positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
-    updateHistory(pDev, first_valuator, num_valuators, ms);
+    updateHistory(pDev, &mask, ms);
 
     /* Update the valuators with the true value sent to the client*/
-    if (num_valuators >= 1 && first_valuator == 0)
+    if (valuator_mask_isset(&mask, 0))
         valuators[0] = x;
-    if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
-        valuators[1 - first_valuator] = y;
+    if (valuator_mask_isset(&mask, 1))
+        valuators[1] = y;
 
-    if (num_valuators)
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
+    clipValuators(pDev, &mask, valuators);
 
     event = (DeviceEvent*) events->event;
     init_event(pDev, event, ms);
@@ -1176,7 +1204,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
     event->root_x_frac = cx_frac;
     event->root_y_frac = cy_frac;
 
-    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+    set_valuators(pDev, event, &mask, valuators);
 
     return num_events;
 }
@@ -1190,11 +1218,11 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
  * place via GetMaximumEventsNum(), and for freeing it.
  */
 int
-GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
-                   int first_valuator, int num_valuators, const int *valuators_in)
+GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in)
 {
     int num_events = 1;
     DeviceEvent *event;
+    ValuatorMask mask;
     int valuators[MAX_VALUATORS];
 
     /* refuse events from disabled devices */
@@ -1202,18 +1230,16 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
         return 0;
 
     /* Sanity checks. */
-    if (type != ProximityIn && type != ProximityOut)
+    if ((type != ProximityIn && type != ProximityOut) || !mask_in)
         return 0;
     if (!pDev->valuator)
         return 0;
+
+    valuator_mask_copy(&mask, mask_in);
+
     /* Do we need to send a DeviceValuator event? */
     if ((pDev->valuator->mode & 1) == Relative)
-        num_valuators = 0;
-
-    /* You fail. */
-    if (first_valuator < 0 || num_valuators > MAX_VALUATORS ||
-        (num_valuators + first_valuator) > pDev->valuator->numAxes)
-        return 0;
+        valuator_mask_zero(&mask);
 
     events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
 
@@ -1221,12 +1247,11 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
     init_event(pDev, event, GetTimeInMillis());
     event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
 
-    if (num_valuators) {
-        memcpy(valuators, valuators_in, num_valuators * sizeof(int));
-        clipValuators(pDev, first_valuator, num_valuators, valuators);
-    }
+    if (valuator_mask_size(&mask) > 0)
+        valuator_mask_copy_valuators(&mask, valuators);
+    clipValuators(pDev, &mask, valuators);
 
-    set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+    set_valuators(pDev, event, &mask, valuators);
 
     return num_events;
 }
diff --git a/dix/inpututils.c b/dix/inpututils.c
index 9738033..9b4f108 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -35,6 +35,7 @@
 #include "xace.h"
 #include "xkbsrv.h"
 #include "xkbstr.h"
+#include "inpututils.h"
 
 /* Check if a button map change is okay with the device.
  * Returns -1 for BadValue, as it collides with MappingBusy. */
@@ -418,6 +419,147 @@ FreeInputAttributes(InputAttributes *attrs)
     free(attrs);
 }
 
+/**
+ * Alloc a valuator mask large enough for num_valuators.
+ */
+ValuatorMask*
+valuator_mask_new(int num_valuators)
+{
+    /* alloc a fixed size mask for now and ignore num_valuators. in the
+     * flying-car future, when we can dynamically alloc the masks and are
+     * not constrained by signals, we can start using num_valuators */
+    ValuatorMask *mask = calloc(1, sizeof(ValuatorMask));
+    mask->last_bit = -1;
+    return mask;
+}
+
+/**
+ * Sets a range of valuators between first_valuator and num_valuators with
+ * the data in the valuators array. All other values are set to 0.
+ */
+void
+valuator_mask_set_range(ValuatorMask *mask, int first_valuator, int num_valuators,
+                        const int* valuators)
+{
+    int i;
+
+    valuator_mask_zero(mask);
+
+    for (i = first_valuator; i < min(first_valuator + num_valuators, MAX_VALUATORS); i++)
+        valuator_mask_set(mask, i, valuators[i - first_valuator]);
+}
+
+/**
+ * Reset mask to zero.
+ */
+void
+valuator_mask_zero(ValuatorMask *mask)
+{
+    memset(mask, 0, sizeof(*mask));
+    mask->last_bit = -1;
+}
+
+/**
+ * Returns the current size of the mask (i.e. the highest number of
+ * valuators currently set + 1).
+ */
+int
+valuator_mask_size(const ValuatorMask *mask)
+{
+    return mask->last_bit + 1;
+}
+
+/**
+ * Returns the number of valuators set in the given mask.
+ */
+int
+valuator_mask_num_valuators(const ValuatorMask *mask)
+{
+    return CountBits(mask->mask, min(mask->last_bit + 1, MAX_VALUATORS));
+}
+
+/**
+ * Return true if the valuator is set in the mask, or false otherwise.
+ */
+int
+valuator_mask_isset(const ValuatorMask *mask, int valuator)
+{
+    return mask->last_bit >= valuator && BitIsOn(mask->mask, valuator);
+}
+
+/**
+ * Set the valuator to the given data.
+ */
+void
+valuator_mask_set(ValuatorMask *mask, int valuator, int data)
+{
+    mask->last_bit = max(valuator, mask->last_bit);
+    SetBit(mask->mask, valuator);
+    mask->valuators[valuator] = data;
+}
+
+/**
+ * Return the requested valuator value. If the mask bit is not set for the
+ * given valuator, the returned value is undefined.
+ */
+int
+valuator_mask_get(const ValuatorMask *mask, int valuator)
+{
+    return mask->valuators[valuator];
+}
+
+/**
+ * Remove the valuator from the mask.
+ */
+void
+valuator_mask_unset(ValuatorMask *mask, int valuator)
+{
+    if (mask->last_bit >= valuator) {
+        int i, lastbit = -1;
+
+        ClearBit(mask->mask, valuator);
+        mask->valuators[valuator] = 0;
+
+        for (i = 0; i <= mask->last_bit; i++)
+            if (valuator_mask_isset(mask, i))
+                lastbit = max(lastbit, i);
+        mask->last_bit = lastbit;
+    }
+}
+
+
+/**
+ * Copy the valuator data from the given mask and return it as one closed
+ * array (i.e., with holes where the masks are unset.
+ * If valuators_in is not NULL, the valuator data will be copied into
+ * valuators_in. The caller is responsible to allocate enough memory.
+ *
+ * Otherwise, memory is allocated and returned.
+ */
+int*
+valuator_mask_copy_valuators(const ValuatorMask *mask, int *valuators_in)
+{
+    int *valuators;
+
+    if (!valuators_in)
+        valuators = calloc(valuator_mask_size(mask), sizeof(int));
+    else
+        valuators = valuators_in;
+
+    memcpy(valuators, mask->valuators,
+           valuator_mask_size(mask) * sizeof(int));
+
+    return valuators;
+}
+
+void
+valuator_mask_copy(ValuatorMask *dest, const ValuatorMask *src)
+{
+    if (src)
+        memcpy(dest, src, sizeof(*dest));
+    else
+        valuator_mask_zero(dest);
+}
 
 int
 CountBits(const uint8_t *mask, int len)
diff --git a/hw/dmx/input/dmxevents.c b/hw/dmx/input/dmxevents.c
index dfa6bda..d22cf06 100644
--- a/hw/dmx/input/dmxevents.c
+++ b/hw/dmx/input/dmxevents.c
@@ -53,6 +53,7 @@
 #include <X11/keysym.h>
 #include "opaque.h"
 #include "inputstr.h"
+#include "inpututils.h"
 #include "mipointer.h"
 #include "mi.h"
 #include "exglobals.h"
@@ -178,12 +179,14 @@ static void enqueueMotion(DevicePtr pDev, int x, int y)
     int i, nevents, valuators[3];
     EventListPtr events;
     int detail = 0;  /* XXX should this be mask of pressed buttons? */
+    ValuatorMask mask;
     valuators[0] = x;
     valuators[1] = y;
 
+    valuator_mask_set_range(&mask, 0, 2, valuators);
     GetEventList(&events);
     nevents = GetPointerEvents(events, p, MotionNotify, detail,
-                               POINTER_ABSOLUTE | POINTER_SCREEN, 0, 2, valuators);
+                               POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
     for (i = 0; i < nevents; i++)
        mieqEnqueue(p, (InternalEvent*)(events + i)->event);
     return;
@@ -292,6 +295,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
     int                    count;
     EventListPtr           events;
     int                    nevents;
+    ValuatorMask           mask;
 
     memset(xE, 0, sizeof(xE));
 
@@ -370,9 +374,10 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
 
     if (block)
         dmxSigioBlock();
+    valuator_mask_set_range(&mask, firstAxis, axesCount, v);
     GetEventList(&events);
-    nevents = GetPointerEvents(events, pDevice, MotionNotify, 0, POINTER_ABSOLUTE,
-                               firstAxis, axesCount, v);
+    nevents = GetPointerEvents(events, pDevice, MotionNotify, 0,
+                               POINTER_ABSOLUTE, &mask);
     for (i = 0; i < nevents; i++)
         mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -388,13 +393,14 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     XDeviceKeyEvent        *ke     = (XDeviceKeyEvent *)e;
     XDeviceMotionEvent     *me     = (XDeviceMotionEvent *)e;
     DeviceIntPtr           pDevice = dmxLocal->pDevice;
-    int                    valuators[6];
+    int                    valuators[MAX_VALUATORS];
     EventListPtr           events;
     int                    nevents, i;
+    ValuatorMask           mask;
 
     if (!e)
         return -1;          /* No extended event passed, cannot handle */
-    
+
     if ((XID)dmxLocal->deviceId != ke->deviceid) {
                                 /* Search for the correct dmxLocal,
                                  * since backend and console events are
@@ -432,23 +438,23 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     }
 
 #define EXTRACT_VALUATORS(ke, valuators) \
-        valuators[0]       = ke->axis_data[0]; \
-        valuators[1]       = ke->axis_data[1]; \
-        valuators[2]       = ke->axis_data[2]; \
-        valuators[3]       = ke->axis_data[3]; \
-        valuators[4]       = ke->axis_data[4]; \
-        valuators[5]       = ke->axis_data[5]; \
+        valuators[0] = ke->axis_data[0]; \
+        valuators[1] = ke->axis_data[1]; \
+        valuators[2] = ke->axis_data[2]; \
+        valuators[3] = ke->axis_data[3]; \
+        valuators[4] = ke->axis_data[4]; \
+        valuators[5] = ke->axis_data[5]; \
 
     switch (type) {
     case XI_DeviceKeyPress:
     case XI_DeviceKeyRelease:
         EXTRACT_VALUATORS(ke, valuators);
+        valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
         if (block)
             dmxSigioBlock();
         GetEventList(&events);
         nevents = GetKeyboardValuatorEvents(events, pDevice, event,
-                                            ke->keycode, ke->first_axis,
-                                            ke->axes_count, valuators);
+                                            ke->keycode, &mask);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -458,12 +464,12 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     case XI_DeviceButtonPress:
     case XI_DeviceButtonRelease:
         EXTRACT_VALUATORS(ke, valuators);
+        valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
         if (block)
             dmxSigioBlock();
         GetEventList(&events);
         nevents = GetPointerEvents(events, pDevice, event, ke->keycode,
-                                   POINTER_ABSOLUTE, ke->first_axis,
-                                   ke->axes_count, valuators);
+                                   POINTER_ABSOLUTE, &mask);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -473,12 +479,11 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
     case XI_ProximityIn:
     case XI_ProximityOut:
         EXTRACT_VALUATORS(ke, valuators);
+        valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
         if (block)
             dmxSigioBlock();
         GetEventList(&events);
-        nevents = GetProximityEvents(events, pDevice, event,
-                                     ke->first_axis, ke->axes_count,
-                                     valuators);
+        nevents = GetProximityEvents(events, pDevice, event, &mask);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
 
@@ -664,6 +669,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
     DeviceIntPtr p = dmxLocal->pDevice;
     int i, nevents, valuators[3];
     EventListPtr events;
+    ValuatorMask mask;
 
     DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail);
 
@@ -687,12 +693,10 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
     case ButtonPress:
     case ButtonRelease:
         detail = dmxGetButtonMapping(dmxLocal, detail);
+        valuator_mask_zero(&mask);
         GetEventList(&events);
         nevents = GetPointerEvents(events, p, type, detail,
-                                   POINTER_ABSOLUTE | POINTER_SCREEN,
-                                   0,   /* first_valuator = 0 */
-                                   0,   /* num_valuators = 0 */
-                                   valuators);
+                                   POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(p, (InternalEvent*)(events + i)->event);
         return;
@@ -702,8 +706,9 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
         valuators[0] = e->xmotion.x;
         valuators[1] = e->xmotion.y;
         valuators[2] = e->xmotion.state; /* FIXME: WTF?? */
+        valuator_mask_set_range(&mask, 0, 3, valuators);
         nevents = GetPointerEvents(events, p, type, detail, 
-                                   POINTER_ABSOLUTE | POINTER_SCREEN, 0, 3, valuators);
+                                   POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
         for (i = 0; i < nevents; i++)
             mieqEnqueue(p, (InternalEvent*)(events + i)->event);
         return;
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 61ee163..608f3a7 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -48,6 +48,7 @@
 #include "exglobals.h"
 #include "eventstr.h"
 #include "xserver-properties.h"
+#include "inpututils.h"
 
 #define AtomFromName(x) MakeAtom(x, strlen(x), 1)
 
@@ -1967,14 +1968,16 @@ _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z,
 {
     int nEvents = 0, i = 0;
     int valuators[3] = { x, y, z };
+    ValuatorMask mask;
 
     /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */
     if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel))
         return;
 
+    valuator_mask_set_range(&mask, 0, 3, valuators);
+
     GetEventList(&kdEvents);
-    nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel,
-                               0, 3, valuators);
+    nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask);
     for (i = 0; i < nEvents; i++)
         KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event));
 }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 67587ca..cf54fd2 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -67,6 +67,7 @@
 #include "exevents.h"	/* AddInputDevice */
 #include "exglobals.h"
 #include "eventstr.h"
+#include "inpututils.h"
 
 #include <string.h>     /* InputClassMatches */
 #ifdef HAVE_FNMATCH_H
@@ -98,7 +99,6 @@
 		return;								\
 	}
 
-
 EventListPtr xf86Events = NULL;
 
 static int
@@ -991,6 +991,19 @@ xf86PostMotionEventP(DeviceIntPtr	device,
                     int			num_valuators,
                     const int		*valuators)
 {
+    ValuatorMask mask;
+
+    XI_VERIFY_VALUATORS(num_valuators);
+
+    valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
+    xf86PostMotionEventM(device, is_absolute, &mask);
+}
+
+void
+xf86PostMotionEventM(DeviceIntPtr	device,
+                     int		is_absolute,
+                     const ValuatorMask	*mask)
+{
     int i = 0, nevents = 0;
     DeviceEvent *event;
     int flags = 0;
@@ -1000,8 +1013,6 @@ xf86PostMotionEventP(DeviceIntPtr	device,
     int dx = 0, dy = 0;
 #endif
 
-    XI_VERIFY_VALUATORS(num_valuators);
-
     if (is_absolute)
         flags = POINTER_ABSOLUTE;
     else
@@ -1009,19 +1020,20 @@ xf86PostMotionEventP(DeviceIntPtr	device,
 
 #if XFreeXDGA
     /* The evdev driver may not always send all axes across. */
-    if (num_valuators >= 1 && first_valuator <= 1) {
+    if (valuator_mask_isset(mask, 0) ||
+        valuator_mask_isset(mask, 1))
         if (miPointerGetScreen(device)) {
             index = miPointerGetScreen(device)->myNum;
-            if (first_valuator == 0)
+            if (valuator_mask_isset(mask, 0))
             {
-                dx = valuators[0];
+                dx = valuator_mask_get(mask, 0);
                 if (is_absolute)
                     dx -= device->last.valuators[0];
             }
 
-            if (first_valuator == 1 || num_valuators >= 2)
+            if (valuator_mask_isset(mask, 1))
             {
-                dy = valuators[1 - first_valuator];
+                dy = valuator_mask_get(mask, 1);
                 if (is_absolute)
                     dy -= device->last.valuators[1];
             }
@@ -1029,12 +1041,9 @@ xf86PostMotionEventP(DeviceIntPtr	device,
             if (DGAStealMotionEvent(device, index, dx, dy))
                 return;
         }
-    }
 #endif
 
-    nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0,
-                               flags, first_valuator, num_valuators,
-                               valuators);
+    nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
 
     for (i = 0; i < nevents; i++) {
         event = (DeviceEvent*)((xf86Events + i)->event);
@@ -1072,13 +1081,23 @@ xf86PostProximityEventP(DeviceIntPtr	device,
                         int		num_valuators,
                         const int	*valuators)
 {
-    int i, nevents;
+    ValuatorMask mask;
 
     XI_VERIFY_VALUATORS(num_valuators);
 
+    valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
+    xf86PostProximityEventM(device, is_in, &mask);
+}
+
+void
+xf86PostProximityEventM(DeviceIntPtr	device,
+                        int		is_in,
+                        const ValuatorMask *mask)
+{
+    int i, nevents;
+
     nevents = GetProximityEvents(xf86Events, device,
-                                 is_in ? ProximityIn : ProximityOut, 
-                                 first_valuator, num_valuators, valuators);
+                                 is_in ? ProximityIn : ProximityOut, mask);
     for (i = 0; i < nevents; i++)
         mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
 
@@ -1118,6 +1137,21 @@ xf86PostButtonEventP(DeviceIntPtr	device,
                      int		num_valuators,
                      const int		*valuators)
 {
+    ValuatorMask mask;
+
+    XI_VERIFY_VALUATORS(num_valuators);
+
+    valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
+    xf86PostButtonEventM(device, is_absolute, button, is_down, &mask);
+}
+
+void
+xf86PostButtonEventM(DeviceIntPtr	device,
+                     int		is_absolute,
+                     int		button,
+                     int		is_down,
+                     const ValuatorMask	*mask)
+{
     int i = 0, nevents = 0;
     int flags = 0;
 
@@ -1125,8 +1159,6 @@ xf86PostButtonEventP(DeviceIntPtr	device,
     int index;
 #endif
 
-    XI_VERIFY_VALUATORS(num_valuators);
-
     if (is_absolute)
         flags = POINTER_ABSOLUTE;
     else
@@ -1142,7 +1174,7 @@ xf86PostButtonEventP(DeviceIntPtr	device,
 
     nevents = GetPointerEvents(xf86Events, device,
                                is_down ? ButtonPress : ButtonRelease, button,
-                               flags, first_valuator, num_valuators, valuators);
+                               flags, mask);
 
     for (i = 0; i < nevents; i++)
         mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
@@ -1183,15 +1215,27 @@ xf86PostKeyEventP(DeviceIntPtr	device,
                   int		num_valuators,
                   const int	*valuators)
 {
-    int i = 0, nevents = 0;
+    ValuatorMask mask;
 
     XI_VERIFY_VALUATORS(num_valuators);
 
+    valuator_mask_set_range(&mask, first_valuator, num_valuators, valuators);
+    xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
+}
+
+void
+xf86PostKeyEventM(DeviceIntPtr	device,
+                  unsigned int	key_code,
+                  int		is_down,
+                  int		is_absolute,
+                  const ValuatorMask *mask)
+{
+    int i = 0, nevents = 0;
+
     if (is_absolute) {
         nevents = GetKeyboardValuatorEvents(xf86Events, device,
                                             is_down ? KeyPress : KeyRelease,
-                                            key_code, first_valuator,
-                                            num_valuators, valuators);
+                                            key_code, mask);
     }
     else {
         nevents = GetKeyboardEvents(xf86Events, device,
@@ -1208,7 +1252,10 @@ xf86PostKeyboardEvent(DeviceIntPtr      device,
                       unsigned int      key_code,
                       int               is_down)
 {
-    xf86PostKeyEventP(device, key_code, is_down, 0, 0, 0, NULL);
+    ValuatorMask mask;
+
+    valuator_mask_zero(&mask);
+    xf86PostKeyEventM(device, key_code, is_down, 0, &mask);
 }
 
 InputInfoPtr
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 5aa4509..829bf78 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -115,19 +115,27 @@ extern _X_EXPORT void xf86PostMotionEvent(DeviceIntPtr device, int is_absolute,
 			 int first_valuator, int num_valuators, ...);
 extern _X_EXPORT void xf86PostMotionEventP(DeviceIntPtr device, int is_absolute,
 			 int first_valuator, int num_valuators, const int *valuators);
+extern _X_EXPORT void xf86PostMotionEventM(DeviceIntPtr device, int is_absolute,
+			 const ValuatorMask *mask);
 extern _X_EXPORT void xf86PostProximityEvent(DeviceIntPtr device, int is_in,
 			    int first_valuator, int num_valuators, ...);
 extern _X_EXPORT void xf86PostProximityEventP(DeviceIntPtr device, int is_in, int first_valuator,
 			     int num_valuators, const int *valuators);
+extern _X_EXPORT void xf86PostProximityEventM(DeviceIntPtr device, int is_in,
+			 const ValuatorMask *mask);
 extern _X_EXPORT void xf86PostButtonEvent(DeviceIntPtr device, int is_absolute, int button,
 		    	 int is_down, int first_valuator, int num_valuators,
 			 ...);
 extern _X_EXPORT void xf86PostButtonEventP(DeviceIntPtr device, int is_absolute, int button,
 			  int is_down, int first_valuator, int num_valuators,
 			  const int *valuators);
+extern _X_EXPORT void xf86PostButtonEventM(DeviceIntPtr device, int is_absolute, int button,
+			  int is_down, const ValuatorMask *mask);
 extern _X_EXPORT void xf86PostKeyEvent(DeviceIntPtr device, unsigned int key_code, int is_down,
 		      int is_absolute, int first_valuator, int num_valuators,
 		      ...);
+extern _X_EXPORT void xf86PostKeyEventM(DeviceIntPtr device, unsigned int key_code, int is_down,
+		       int is_absolute, const ValuatorMask *mask);
 extern _X_EXPORT void xf86PostKeyEventP(DeviceIntPtr device, unsigned int key_code, int is_down,
 		       int is_absolute, int first_valuator, int num_valuators,
 		       const int *valuators);
diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c
index 62e17cb..5ff6d21 100644
--- a/hw/xnest/Events.c
+++ b/hw/xnest/Events.c
@@ -25,6 +25,7 @@ is" without express or implied warranty.
 #include "windowstr.h"
 #include "servermd.h"
 #include "inputstr.h"
+#include "inpututils.h"
 
 #include "mi.h"
 
@@ -117,6 +118,7 @@ xnestCollectEvents(void)
 {
   XEvent X;
   int i, n, valuators[2];
+  ValuatorMask mask;
   ScreenPtr pScreen;
   GetEventList(&xnestEvents);
 
@@ -133,19 +135,21 @@ xnestCollectEvents(void)
       break;
       
     case ButtonPress:
+      valuator_mask_set_range(&mask, 0, 0, NULL);
       xnestUpdateModifierState(X.xkey.state);
       lastEventTime = GetTimeInMillis();
       n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
-                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
+                           X.xbutton.button, POINTER_RELATIVE, &mask);
       for (i = 0; i < n; i++)
         mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
       break;
       
     case ButtonRelease:
+      valuator_mask_set_range(&mask, 0, 0, NULL);
       xnestUpdateModifierState(X.xkey.state);
       lastEventTime = GetTimeInMillis();
       n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
-                           X.xbutton.button, POINTER_RELATIVE, 0, 0, NULL);
+                           X.xbutton.button, POINTER_RELATIVE, &mask);
       for (i = 0; i < n; i++)
         mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
       break;
@@ -153,9 +157,10 @@ xnestCollectEvents(void)
     case MotionNotify:
       valuators[0] = X.xmotion.x;
       valuators[1] = X.xmotion.y;
+      valuator_mask_set_range(&mask, 0, 2, valuators);
       lastEventTime = GetTimeInMillis();
       n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
-                           0, POINTER_ABSOLUTE, 0, 2, valuators);
+                           0, POINTER_ABSOLUTE, &mask);
       for (i = 0; i < n; i++)
         mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
       break;
@@ -186,9 +191,10 @@ xnestCollectEvents(void)
 	  NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x, X.xcrossing.y);
           valuators[0] = X.xcrossing.x;
           valuators[1] = X.xcrossing.y;
+          valuator_mask_set_range(&mask, 0, 2, valuators);
           lastEventTime = GetTimeInMillis();
           n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
-                               0, POINTER_ABSOLUTE, 0, 2, valuators);
+                               0, POINTER_ABSOLUTE, &mask);
           for (i = 0; i < n; i++)
             mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
 	  xnestDirectInstallColormaps(pScreen);
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 74fadf4..672d768 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -414,6 +414,7 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa
 			     float pressure, float tilt_x, float tilt_y) {
 	static int darwinFakeMouseButtonDown = 0;
 	int i, num_events;
+    ValuatorMask mask;
     ScreenPtr screen;
     int valuators[5];
 	
@@ -464,8 +465,9 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa
 
     DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, pressure, tilt_x, tilt_y);
     darwinEvents_lock(); {
+        valuator_mask_set_range(&mask, 0, (pDev == darwinTabletCurrent) ? 5 : 2, valuators);
         num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button, 
-                                      POINTER_ABSOLUTE, 0, pDev==darwinTabletCurrent?5:2, valuators);
+                                      POINTER_ABSOLUTE, 0, &mask);
         for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event);
         if(num_events > 0) DarwinPokeEQ();
     } darwinEvents_unlock();
@@ -491,6 +493,7 @@ void DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y) {
     ScreenPtr screen;
     DeviceIntPtr pDev = darwinTabletCurrent;
     int valuators[5];
+    ValuatorMask mask;
 
 	DEBUG_LOG("DarwinSendProximityEvents(%d, %f, %f)\n", ev_type, pointer_x, pointer_y);
 
@@ -507,8 +510,8 @@ void DarwinSendProximityEvents(int ev_type, float pointer_x, float pointer_y) {
 
     DarwinPrepareValuators(pDev, valuators, screen, pointer_x, pointer_y, 0.0f, 0.0f, 0.0f);
     darwinEvents_lock(); {
-        num_events = GetProximityEvents(darwinEvents, pDev, ev_type,
-                                        0, 5, valuators);
+        valuator_mask_set_range(&mask, 0, 5, valuators);
+        num_events = GetProximityEvents(darwinEvents, pDev, ev_type, &mask);
         for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event);
         if(num_events > 0) DarwinPokeEQ();
     } darwinEvents_unlock();
diff --git a/hw/xwin/winmouse.c b/hw/xwin/winmouse.c
index 342f20d..e645d7e 100644
--- a/hw/xwin/winmouse.c
+++ b/hw/xwin/winmouse.c
@@ -240,15 +240,17 @@ winMouseButtonsSendEvent (int iEventType, int iButton)
 {
   EventListPtr events;
   int i, nevents;
+  ValuatorMask mask;
 
 #if defined(XFree86Server)
   if (g_winMouseButtonMap)
     iButton = g_winMouseButtonMap[iButton];
 #endif
 
+  valuator_mask_zero(&mask);
   GetEventList(&events);
   nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton,
-			     POINTER_RELATIVE, 0, 0, NULL);
+			     POINTER_RELATIVE, &mask);
 
   for (i = 0; i < nevents; i++)
     mieqEnqueue(g_pwinPointer, events[i].event);
@@ -373,15 +375,17 @@ void winEnqueueMotion(int x, int y)
 {
   int i, nevents;
   int valuators[2];
+  ValuatorMask mask;
   EventListPtr events;
 
   miPointerSetPosition(g_pwinPointer, &x, &y);
   valuators[0] = x;
   valuators[1] = y;
 
+  valuator_mask_set_range(&mask, 0, 2, valuators);
   GetEventList(&events);
   nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0,
-			     POINTER_ABSOLUTE | POINTER_SCREEN, 0, 2, valuators);
+			     POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
 
   for (i = 0; i < nevents; i++)
     mieqEnqueue(g_pwinPointer, events[i].event);
diff --git a/include/Makefile.am b/include/Makefile.am
index e76de05..eb0e3a7 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -67,6 +67,6 @@ AM_CFLAGS = $(DIX_CFLAGS)
 
 EXTRA_DIST = 	\
 	dix-config-apple-verbatim.h \
-	eventconvert.h eventstr.h \
+	eventconvert.h eventstr.h inpututils.h \
 	protocol-versions.h \
 	xsha1.h
diff --git a/include/input.h b/include/input.h
index 36ce4c9..76df4ff 100644
--- a/include/input.h
+++ b/include/input.h
@@ -157,6 +157,8 @@ typedef struct _DeviceRec {
     Bool	on;			/* used by DDX to keep state */
 } DeviceRec, *DevicePtr;
 
+typedef struct _ValuatorMask ValuatorMask;
+
 typedef struct {
     int			click, bell, bell_pitch, bell_duration;
     Bool		autoRepeat;
@@ -445,9 +447,7 @@ extern _X_EXPORT int GetPointerEvents(
     int type,
     int buttons,
     int flags,
-    int first_valuator,
-    int num_valuators,
-    const int *valuators);
+    const ValuatorMask *mask);
 
 extern _X_EXPORT int GetKeyboardEvents(
     EventListPtr events,
@@ -460,17 +460,13 @@ extern int GetKeyboardValuatorEvents(
     DeviceIntPtr pDev,
     int type,
     int key_code,
-    int first_valuator,
-    int num_valuator,
-    const int *valuators);
+    const ValuatorMask *mask);
 
 extern int GetProximityEvents(
     EventListPtr events,
     DeviceIntPtr pDev,
     int type,
-    int first_valuator,
-    int num_valuators,
-    const int *valuators);
+    const ValuatorMask *mask);
 
 extern void PostSyntheticMotion(
     DeviceIntPtr pDev,
@@ -554,4 +550,14 @@ extern _X_EXPORT void DDXRingBell(
    xfixes/cursor.c uses it to determine if the cursor is enabled */
 extern Bool EnableCursor;
 
+/* For server-internal functions, see inpututil.h */
+extern _X_EXPORT ValuatorMask  *valuator_mask_new(int num_valuators);
+extern _X_EXPORT void valuator_mask_set_range(ValuatorMask *mask,
+                                       int first_valuator, int num_valuators,
+                                       const int* valuators);
+extern _X_EXPORT void valuator_mask_set(ValuatorMask *mask,
+                                        int valuator,
+                                        int data);
+extern _X_EXPORT void valuator_mask_zero(ValuatorMask *mask);
+
 #endif /* INPUT_H */
diff --git a/include/inpututils.h b/include/inpututils.h
new file mode 100644
index 0000000..56bb75d
--- /dev/null
+++ b/include/inpututils.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2010 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include "dix-config.h"
+#endif
+
+#ifndef INPUTUTILS_H
+#define INPUTUTILS_H
+
+#include "input.h"
+
+struct _ValuatorMask {
+    int8_t      last_bit; /* highest bit set in mask */
+    uint8_t     mask[(MAX_VALUATORS + 7)/8];
+    int         valuators[MAX_VALUATORS]; /* valuator data */
+};
+
+/* server-internal */
+extern _X_HIDDEN int valuator_mask_size(const ValuatorMask *mask);
+extern _X_HIDDEN int valuator_mask_isset(const ValuatorMask *mask, int bit);
+extern _X_HIDDEN void valuator_mask_unset(ValuatorMask *mask, int bit);
+extern _X_HIDDEN int* valuator_mask_copy_valuators(const ValuatorMask *mask, int *valuators_in);
+extern _X_HIDDEN int valuator_mask_num_valuators(const ValuatorMask *mask);
+extern _X_HIDDEN void valuator_mask_copy(ValuatorMask *dest, const ValuatorMask *src);
+extern _X_HIDDEN int valuator_mask_get(const ValuatorMask *mask, int valnum);
+
+#endif
diff --git a/mi/mipointer.c b/mi/mipointer.c
index d8aaf8c..554397a 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -39,6 +39,7 @@ in this Software without prior written authorization from The Open Group.
 # include   "cursorstr.h"
 # include   "dixstruct.h"
 # include   "inputstr.h"
+# include   "inpututils.h"
 
 DevPrivateKeyRec miPointerScreenKeyRec;
 
@@ -553,6 +554,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
 {
     int i, nevents;
     int valuators[2];
+    ValuatorMask mask;
 
     miPointerMoveNoEvent(pDev, pScreen, x, y);
 
@@ -571,7 +573,9 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
         }
     }
 
-    nevents = GetPointerEvents(events, pDev, MotionNotify, 0, POINTER_SCREEN | POINTER_ABSOLUTE, 0, 2, valuators);
+    valuator_mask_set_range(&mask, 0, 2, valuators);
+    nevents = GetPointerEvents(events, pDev, MotionNotify, 0,
+                               POINTER_SCREEN | POINTER_ABSOLUTE, &mask);
 
     OsBlockSignals();
 #ifdef XQUARTZ
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index c020444..8d7c124 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -42,6 +42,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <ctype.h>
 #include "mi.h"
 #include "mipointer.h"
+#include "inpututils.h"
 #define EXTENSION_EVENT_BASE 64
 
 DevPrivateKeyRec xkbDevicePrivateKeyRec;
@@ -1354,7 +1355,7 @@ xkbStateNotify	sn;
  * First one on drinking island wins!
  */
 static void
-InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int num_valuators, int *valuators)
+InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask)
 {
     ScreenPtr           pScreen;
     EventListPtr        events;
@@ -1376,8 +1377,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int nu
     OsBlockSignals();
     pScreen = miPointerGetScreen(ptr);
     saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
-    nevents = GetPointerEvents(events, ptr, type, button, flags, 0,
-                               num_valuators, valuators);
+    nevents = GetPointerEvents(events, ptr, type, button, flags, mask);
     if (IsMaster(dev) && (lastSlave && lastSlave != ptr))
         UpdateFromMaster(&events[nevents], lastSlave, DEVCHANGE_POINTER_EVENT, &nevents);
     miPointerSetWaitForUpdate(pScreen, saveWait);
@@ -1393,6 +1393,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, int nu
 static void
 XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
 {
+    ValuatorMask        mask;
     int                 gpe_flags = 0;
 
     /* ignore attached SDs */
@@ -1404,7 +1405,9 @@ XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
     else
         gpe_flags = POINTER_RELATIVE;
 
-    InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, 2, (int[]){x, y});
+    valuator_mask_set_range(&mask, 0, 2, (int[]){x, y});
+
+    InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
 }
 
 void
@@ -1434,5 +1437,5 @@ XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
         return;
 
     InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
-                           button, 0, 0, NULL);
+                           button, 0, NULL);
 }
commit fc48a8f9f5f66e591b3e39211d44ce68267303f8
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Tue Oct 19 13:37:38 2010 +1000

    Add CountBits() to the server.
    
    Function to count the number of bits set in the given array.
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/inpututils.c b/dix/inpututils.c
index 6693c67..9738033 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -418,3 +418,16 @@ FreeInputAttributes(InputAttributes *attrs)
     free(attrs);
 }
 
+
+int
+CountBits(const uint8_t *mask, int len)
+{
+    int i;
+    int ret = 0;
+
+    for (i = 0; i < len; i++)
+        if (BitIsOn(mask, i))
+            ret++;
+
+    return ret;
+}
diff --git a/include/inputstr.h b/include/inputstr.h
index 1b504e9..ec9749e 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -60,6 +60,7 @@ SOFTWARE.
 #define BitIsOn(ptr, bit) (((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7)))
 #define SetBit(ptr, bit)  (((BYTE *) (ptr))[(bit)>>3] |= (1 << ((bit) & 7)))
 #define ClearBit(ptr, bit) (((BYTE *)(ptr))[(bit)>>3] &= ~(1 << ((bit) & 7)))
+extern _X_EXPORT int CountBits(const uint8_t *mask, int len);
 
 #define SameClient(obj,client) \
 	(CLIENT_BITS((obj)->resource) == (client)->clientAsMask)
commit eaf0b6a4d83d49930d21d5191f335fcac962632e
Merge: 693e92d... 23229c7...
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Oct 15 13:46:59 2010 +1000

    Merge branch 'master' into input-api
    
    Conflicts:
    	config/udev.c
    	hw/xfree86/common/xf86Helper.c
    	hw/xfree86/common/xf86Module.h
    	hw/xfree86/common/xf86Xinput.h
    	hw/xfree86/os-support/linux/lnx_init.c
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --cc config/udev.c
index cd46eec,b7717c9..31f4f80
--- a/config/udev.c
+++ b/config/udev.c
@@@ -179,18 -181,6 +181,8 @@@ device_added(struct udev_device *udev_d
          }
      }
  
-     /* construct USB ID in lowercase hex - "0000:ffff" */
-     if (usb_vendor && usb_model) {
-         attrs.usb_id = Xprintf("%s:%s", usb_vendor, usb_model);
-         if (attrs.usb_id) {
-             char *cur;
-             for (cur = attrs.usb_id; *cur; cur++)
-                 *cur = tolower(*cur);
-         }
-     }
- 
 +    add_option(&options, "config_info", config_info);
 +
      LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n",
                 name, path);
      rc = NewInputDeviceRequest(options, &attrs, &dev);
diff --cc hw/xfree86/common/xf86Config.c
index 0ebee9e,6743b10..51b9375
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@@ -60,9 -60,10 +60,9 @@@
  #include "configProcs.h"
  #include "globals.h"
  #include "extension.h"
- #include "Pci.h"
+ #include "xf86pciBus.h"
  
  #include "xf86Xinput.h"
 -extern DeviceAssocRec mouse_assoc;
  
  #include "xkbsrv.h"
  
diff --cc hw/xfree86/common/xf86Module.h
index aed2edc,7a8f62f..72f6cf0
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@@ -82,8 -82,8 +82,8 @@@ typedef enum 
   * mask is 0xFFFF0000.
   */
  #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
- #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(8, 0)
+ #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(9, 0)
 -#define ABI_XINPUT_VERSION	SET_ABI_VERSION(11, 0)
 +#define ABI_XINPUT_VERSION	SET_ABI_VERSION(12, 0)
  #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(4, 0)
  #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
  
diff --cc hw/xfree86/common/xf86Xinput.c
index 4de6c78,877eb03..67587ca
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@@ -59,10 -59,20 +59,11 @@@
  #include "xf86Priv.h"
  #include "xf86Config.h"
  #include "xf86Xinput.h"
 -#include "XIstubs.h"
  #include "xf86Optrec.h"
 -#include "xf86Parser.h"
  #include "mipointer.h"
 -#include "xf86InPriv.h"
 -#include "compiler.h"
  #include "extinit.h"
+ #include "loaderProcs.h"
  
 -#ifdef DPMSExtension
 -#include <X11/extensions/dpmsconst.h>
 -#include "dpmsproc.h"
 -#endif
 -
  #include "exevents.h"	/* AddInputDevice */
  #include "exglobals.h"
  #include "eventstr.h"
@@@ -651,95 -731,6 +652,91 @@@ IgnoreInputClass(const InputInfoPtr ide
      return ignore;
  }
  
 +static InputInfoPtr
 +xf86AllocateInput(void)
 +{
 +    InputInfoPtr pInfo;
 +
 +    pInfo = calloc(sizeof(*pInfo), 1);
 +    if (!pInfo)
 +        return NULL;
 +
 +    pInfo->fd = -1;
 +    pInfo->type_name = "UNKNOWN";
 +
 +    return pInfo;
 +}
 +
 +/* Append InputInfoRec to the tail of xf86InputDevs. */
 +static void
 +xf86AddInput(InputDriverPtr drv, InputInfoPtr pInfo)
 +{
 +    InputInfoPtr *prev = NULL;
 +
 +    pInfo->drv = drv;
-     drv->refCount++;
 +    pInfo->module = DuplicateModule(drv->module, NULL);
 +
 +    for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
 +        ;
 +
 +    *prev = pInfo;
 +    pInfo->next = NULL;
 +
 +    xf86CollectInputOptions(pInfo, (const char**)drv->default_options);
 +    xf86ProcessCommonOptions(pInfo, pInfo->options);
 +}
 +
 +/*
 + * Remove an entry from xf86InputDevs and free all the device's information.
 + */
 +void
 +xf86DeleteInput(InputInfoPtr pInp, int flags)
 +{
 +    /* First check if the inputdev is valid. */
 +    if (pInp == NULL)
 +	return;
 +
 +    if (pInp->module)
 +	UnloadModule(pInp->module);
 +
-     if (pInp->drv)
- 	pInp->drv->refCount--;
- 
 +    /* This should *really* be handled in drv->UnInit(dev) call instead, but
 +     * if the driver forgets about it make sure we free it or at least crash
 +     * with flying colors */
 +    free(pInp->private);
 +
 +    FreeInputAttributes(pInp->attrs);
 +
 +    /* Remove the entry from the list. */
 +    if (pInp == xf86InputDevs)
 +	xf86InputDevs = pInp->next;
 +    else {
 +	InputInfoPtr p = xf86InputDevs;
 +	while (p && p->next != pInp)
 +	    p = p->next;
 +	if (p)
 +	    p->next = pInp->next;
 +	/* Else the entry wasn't in the xf86InputDevs list (ignore this). */
 +    }
 +
 +    free(pInp->driver);
 +    free(pInp->name);
 +    xf86optionListFree(pInp->options);
 +    free(pInp);
 +}
 +
 +/*
 + * Apply backend-specific initialization. Invoked after ActiveteDevice(),
 + * i.e. after the driver successfully completed DEVICE_INIT and the device
 + * is advertised.
 + * @param dev the device
 + * @return Success or an error code
 + */
 +static int
 +xf86InputDevicePostInit(DeviceIntPtr dev) {
 +    ApplyAccelerationSettings(dev);
 +    return Success;
 +}
 +
  /**
   * Create a new input device, activate and enable it.
   *
diff --cc hw/xfree86/common/xf86Xinput.h
index af7e8c1,7b60cdf..5aa4509
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@@ -68,14 -97,12 +68,13 @@@ typedef struct _InputDriverRec 
      int			    driverVersion;
      char *		    driverName;
      void		    (*Identify)(int flags);
 -    struct _LocalDeviceRec *(*PreInit)(struct _InputDriverRec *drv,
 -				       IDevPtr dev, int flags);
 +    int			    (*PreInit)(struct _InputDriverRec *drv,
 +				       struct _InputInfoRec* pInfo, int flags);
      void		    (*UnInit)(struct _InputDriverRec *drv,
 -				      struct _LocalDeviceRec *pInfo,
 +				      struct _InputInfoRec *pInfo,
  				      int flags);
      pointer		    module;
-     int			    refCount;
 +    char **		    default_options;
  } InputDriverRec, *InputDriverPtr;
  
  /* This is to input devices what the ScrnInfoRec is to screens. */
commit 693e92d4049ee76d074737480f3fc1bb236f4278
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Sep 10 09:54:33 2010 +1000

    xfree86: add xf86OptionListDuplicate()
    
    Does what it says on the box.
    
    Some drivers need to duplicate option lists from the original device to
    ensure that devices created by the driver (driver-internal hotplugging) have
    the same list of options as the original device.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86Opt.h b/hw/xfree86/common/xf86Opt.h
index d75d3bf..9453f2a 100644
--- a/hw/xfree86/common/xf86Opt.h
+++ b/hw/xfree86/common/xf86Opt.h
@@ -84,6 +84,7 @@ extern _X_EXPORT pointer xf86NewOption(char *name, char *value );
 extern _X_EXPORT pointer xf86NextOption(pointer list );
 extern _X_EXPORT pointer xf86OptionListCreate(const char **options, int count, int used);
 extern _X_EXPORT pointer xf86OptionListMerge(pointer head, pointer tail);
+extern _X_EXPORT pointer xf86OptionListDuplicate(pointer list);
 extern _X_EXPORT void xf86OptionListFree(pointer opt);
 extern _X_EXPORT char *xf86OptionName(pointer opt);
 extern _X_EXPORT char *xf86OptionValue(pointer opt);
diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index 7ca2fdd..af39b2b 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -136,6 +136,25 @@ xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts)
     }
 }
 
+/**
+ * Duplicate the option list passed in. The returned pointer will be a newly
+ * allocated option list and must be freed by the caller.
+ */
+pointer
+xf86OptionListDuplicate(pointer options)
+{
+    pointer o = NULL;
+
+    while (options)
+    {
+        o = xf86AddNewOption(o, xf86OptionName(options), xf86OptionValue(options));
+        options = xf86nextOption(options);
+    }
+
+    return o;
+}
+
+
 /* Created for new XInput stuff -- essentially extensions to the parser	*/
 
 static int
commit 9dca441670d261a9a9fb6108960ed48f3d58fb7f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Sep 6 11:32:38 2010 +1000

    xfree86: add a hook to replace the new console handler.
    
    This hook is only necessary for the keyboard driver to remove the race
    condition between drain_console() and the driver's ReadInput (Bug 29969).
    
    The idea is that a driver that needs to handle events from the console
    calls xf86ReplaceConsoleHandler() with it's own ReadInput (or NULL) and thus
    removes the drain_console call. It's the driver's responsibility to restore
    the previous behaviour when the driver is unloaded.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    CC: Thomas Hellstrom <thellstrom at vmware.com>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>

diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h
index 886c25b..9f0dda9 100644
--- a/hw/xfree86/common/xf86.h
+++ b/hw/xfree86/common/xf86.h
@@ -203,6 +203,7 @@ extern _X_EXPORT pointer xf86AddGeneralHandler(int fd, InputHandlerProc proc, po
 extern _X_EXPORT int xf86RemoveGeneralHandler(pointer handler);
 extern _X_EXPORT void xf86DisableGeneralHandler(pointer handler);
 extern _X_EXPORT void xf86EnableGeneralHandler(pointer handler);
+extern _X_EXPORT InputHandlerProc xf86SetConsoleHandler(InputHandlerProc handler, pointer data);
 extern _X_EXPORT void xf86InterceptSignals(int *signo);
 extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler)(void));
 extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new);
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 2e82848..fdd908a 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -600,6 +600,26 @@ xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data)
     return ih;
 }
 
+/**
+ * Set the handler for the console's fd. Replaces (and returns) the previous
+ * handler or NULL, whichever appropriate.
+ * proc may be NULL if the server should not handle events on the console.
+ */
+InputHandlerProc
+xf86SetConsoleHandler(InputHandlerProc proc, pointer data)
+{
+    static InputHandlerProc handler = NULL;
+    InputHandlerProc old_handler = handler;
+
+    if (old_handler)
+        xf86RemoveGeneralHandler(old_handler);
+
+    xf86AddGeneralHandler(xf86Info.consoleFd, proc, data);
+    handler = proc;
+
+    return old_handler;
+}
+
 static void
 removeInputHandler(IHPtr ih)
 {
diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
index 92bfde4..bf61ceb 100644
--- a/hw/xfree86/os-support/linux/lnx_init.c
+++ b/hw/xfree86/os-support/linux/lnx_init.c
@@ -277,9 +277,7 @@ xf86OpenConsole(void)
             tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
 
             /* need to keep the buffer clean, else the kernel gets angry */
-	    if (xf86Info.allowEmptyInput)
-		console_handler = xf86AddGeneralHandler(xf86Info.consoleFd,
-							drain_console, NULL);
+	    xf86SetConsoleHandler(drain_console, NULL);
 
 	    /* we really should have a InitOSInputDevices() function instead
 	     * of Init?$#*&Device(). So I just place it here */
commit da31ca747f8e3993b2aca5d31b7d09b9907ad1d9
Author: Thomas Hellstrom <thellstrom at vmware.com>
Date:   Thu Sep 2 10:53:28 2010 +0200

    linux: Don't lose console events on non-evdev drivers (#29969)
    
    The drain_console() function will race with new keyboard events being added
    by the hardware causing the server to lose keyboard events if the console fd
    is used for input.
    
    Only use the drain_console() when AllowEmptyInput is off which is the best
    indicator we have for whether the keyboard driver will be used. This patch
    will only fix the bug when hotplugging is disabled.
    What we really need is a way to figure out either whether we're _not_ using
    the keyboard driver (not predictable) or a way for the keyboard driver to
    disable drain_console().
    
    X.Org Bug 29969 <http://bugs.freedesktop.org/show_bug.cgi?id=29969>
    
    Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 71972c2534d490284d3d42b456c2f34b964b2894)

diff --git a/hw/xfree86/os-support/linux/lnx_init.c b/hw/xfree86/os-support/linux/lnx_init.c
index c8cec2e..92bfde4 100644
--- a/hw/xfree86/os-support/linux/lnx_init.c
+++ b/hw/xfree86/os-support/linux/lnx_init.c
@@ -277,8 +277,9 @@ xf86OpenConsole(void)
             tcsetattr(xf86Info.consoleFd, TCSANOW, &nTty);
 
             /* need to keep the buffer clean, else the kernel gets angry */
-            console_handler = xf86AddGeneralHandler(xf86Info.consoleFd,
-                    drain_console, NULL);
+	    if (xf86Info.allowEmptyInput)
+		console_handler = xf86AddGeneralHandler(xf86Info.consoleFd,
+							drain_console, NULL);
 
 	    /* we really should have a InitOSInputDevices() function instead
 	     * of Init?$#*&Device(). So I just place it here */
commit 52df92a563980a7af0fb61248da3654bd90e8232
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 15:08:01 2010 +1000

    xfree86: move XI_VERIFY_VALUATORS to the source file it's used in.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index e225caa..4de6c78 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -89,6 +89,14 @@
 
 #include "xkbsrv.h"
 
+/* Valuator verification macro */
+#define XI_VERIFY_VALUATORS(num_valuators)					\
+	if (num_valuators > MAX_VALUATORS) {					\
+		xf86Msg(X_ERROR, "%s: num_valuator %d is greater than"		\
+			" MAX_VALUATORS\n", __FUNCTION__, num_valuators);	\
+		return;								\
+	}
+
 
 EventListPtr xf86Events = NULL;
 
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 7d3f3e2..af7e8c1 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -63,14 +63,6 @@
 /* the device sends Xinput and core pointer events */
 #define XI86_SEND_CORE_EVENTS	XI86_ALWAYS_CORE
 
-/* Valuator verification macro */
-#define XI_VERIFY_VALUATORS(num_valuators)					\
-	if (num_valuators > MAX_VALUATORS) {					\
-		xf86Msg(X_ERROR, "%s: num_valuator %d is greater than"		\
-			" MAX_VALUATORS\n", __FUNCTION__, num_valuators);	\
-		return;								\
-	}
-
 /* This holds the input driver entry and module information. */
 typedef struct _InputDriverRec {
     int			    driverVersion;
commit 824e970c5cc94fc7d5fe5f78a24d0d3057d87a84
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 15:03:39 2010 +1000

    xfree86: remove TS_Raw and TS_Scaled defines.
    
    There are no references to it other than the commit that added them. But
    since we're re-doing the API anyway, now is a good time to break things.
    
    commit 9398d62f27ee1b287e4458fd8b011c10f7b59efd
    Author: Daniel Stone <daniel at fooishbar.org>
    Date:   Wed Mar 21 00:18:24 2007 +0200
    
        XFree86 input: Add backwards compatibility for motion history
        Add the old motion history API back, as a shim around the new mi
        API.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 955d2aa..7d3f3e2 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -71,10 +71,6 @@
 		return;								\
 	}
 
-/* Stupid API backwards-compatibility. */
-#define TS_Raw 60
-#define TS_Scaled 61
-
 /* This holds the input driver entry and module information. */
 typedef struct _InputDriverRec {
     int			    driverVersion;
commit ac3f88e604212fc3668d623798d50aa218c13995
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 15:01:26 2010 +1000

    xfree86: remove {Dont}SendCoreEvents defines
    
    The input drivers that use it only do so with ABI 0 and we're long past this
    one now. Input driver don't have a say in whether they send core events now
    anyway.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 34f433f..955d2aa 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -183,9 +183,4 @@ extern _X_EXPORT void xf86VIDrvMsgVerb(InputInfoPtr dev,
 /* xf86Option.c */
 extern void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts);
 
-
-/* Legacy hatred */
-#define SendCoreEvents 59
-#define DontSendCoreEvents 60
-
 #endif /* _xf86Xinput_h */
commit 3f264149ff226d7c0bfcfcfc2c8845fa6326d0bd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 14:52:30 2010 +1000

    xfree86: don't export xf86InputDevs.
    
    Use xf86FirstLocalDevice() instead (but don't get me started on the naming
    of that one...)
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>

diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index a797c90..34f433f 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -121,7 +121,7 @@ typedef struct _InputInfoRec {
 } *InputInfoPtr;
 
 /* xf86Globals.c */
-extern _X_EXPORT InputInfoPtr xf86InputDevs;
+extern InputInfoPtr xf86InputDevs;
 
 /* xf86Xinput.c */
 extern _X_EXPORT void xf86PostMotionEvent(DeviceIntPtr device, int is_absolute,
commit 8f0531bddac8e774aa25b51155445309219da0f6
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 14:46:59 2010 +1000

    xfree86: remove XI_PRIVATE macro, unused.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>

diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 2826b1c..a797c90 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -63,9 +63,6 @@
 /* the device sends Xinput and core pointer events */
 #define XI86_SEND_CORE_EVENTS	XI86_ALWAYS_CORE
 
-#define XI_PRIVATE(dev) \
-	(((InputInfoPtr)((dev)->public.devicePrivate))->private)
-
 /* Valuator verification macro */
 #define XI_VERIFY_VALUATORS(num_valuators)					\
 	if (num_valuators > MAX_VALUATORS) {					\
commit c08f7afdbcf16d2ba30b67e27162c5aaa1ed3f61
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 14:45:03 2010 +1000

    xfree86: update comment for xf86DeleteInput
    
    We have a driver hook - it's UnInit.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 4c5a9bc..e225caa 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -679,10 +679,8 @@ xf86AddInput(InputDriverPtr drv, InputInfoPtr pInfo)
 }
 
 /*
- * Remove an entry from xf86InputDevs.  Ideally it should free all allocated
- * data.  To do this properly may require a driver hook.
+ * Remove an entry from xf86InputDevs and free all the device's information.
  */
-
 void
 xf86DeleteInput(InputInfoPtr pInp, int flags)
 {
commit b8d9c5ff0003f15720737949e65e3159c4f4576e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 14:30:11 2010 +1000

    xfree86: remove IDevRec, replace with InputInfoRec.
    
    This struct is superfluous, maintaining the same info as the InputInfoRec
    (with the exception of the driver name).
    
    This is a rather large commit with the majority of changes being a rename
    from the fields of the IDevRec (idev, commonOptions) to the InputInfoRec
    (pInfo, options).
    
    The actual changes affect the initialization process of the input device:
    In NewInputDeviceRequest, the InputInfoRec is now always allocated and just
    added to the internal list in xf86NewInputDevice() if the init process
    succeeded.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 5d69c22..0ebee9e 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -135,7 +135,7 @@ static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
 static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
 static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
 			 Bool active);
-static Bool configInput(IDevPtr inputp, XF86ConfInputPtr conf_input,
+static Bool configInput(InputInfoPtr pInfo, XF86ConfInputPtr conf_input,
 			MessageType from);
 static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
 static Bool addDefaultModes(MonPtr monitorp);
@@ -444,8 +444,8 @@ xf86InputDriverlistFromConfig(void)
 {
     int count = 0;
     char **modulearray;
-    IDevPtr* idp;
-    
+    InputInfoPtr *idp;
+
     /*
      * make sure the config file has been parsed and that we have a
      * ModulePath set; if no ModulePath was given, use the default
@@ -1110,12 +1110,12 @@ Bool xf86DRI2Enabled(void)
 static Bool
 checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
 {
-    IDevPtr corePointer = NULL, coreKeyboard = NULL;
+    InputInfoPtr corePointer = NULL, coreKeyboard = NULL;
     Bool foundPointer = FALSE, foundKeyboard = FALSE;
     const char *pointerMsg = NULL, *keyboardMsg = NULL;
-    IDevPtr *devs, /* iterator */
+    InputInfoPtr *devs, /* iterator */
             indp;
-    IDevRec Pointer, Keyboard;
+    InputInfoRec Pointer, Keyboard;
     XF86ConfInputPtr confInput;
     XF86ConfInputRec defPtr, defKbd;
     int count = 0;
@@ -1131,26 +1131,26 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
      */
     for (devs = servlayoutp->inputs; devs && *devs; devs++) {
         indp = *devs;
-	if (indp->commonOptions &&
-	    xf86CheckBoolOption(indp->commonOptions, "CorePointer", FALSE)) {
+	if (indp->options &&
+	    xf86CheckBoolOption(indp->options, "CorePointer", FALSE)) {
 	    if (!corePointer) {
 		corePointer = indp;
 	    } else {
-		    xf86ReplaceBoolOption(indp->commonOptions, "CorePointer", FALSE);
+		    xf86ReplaceBoolOption(indp->options, "CorePointer", FALSE);
 		xf86Msg(X_WARNING, "Duplicate core pointer devices.  "
 			"Removing core pointer attribute from \"%s\"\n",
-			indp->identifier);
+			indp->name);
 	    }
 	}
-	if (indp->commonOptions &&
-	    xf86CheckBoolOption(indp->commonOptions, "CoreKeyboard", FALSE)) {
+	if (indp->options &&
+	    xf86CheckBoolOption(indp->options, "CoreKeyboard", FALSE)) {
 	    if (!coreKeyboard) {
 		coreKeyboard = indp;
 	    } else {
-		    xf86ReplaceBoolOption(indp->commonOptions, "CoreKeyboard", FALSE);
+		    xf86ReplaceBoolOption(indp->options, "CoreKeyboard", FALSE);
 		xf86Msg(X_WARNING, "Duplicate core keyboard devices.  "
 			"Removing core keyboard attribute from \"%s\"\n",
-			indp->identifier);
+			indp->name);
 	    }
 	}
 	count++;
@@ -1177,7 +1177,7 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
 		if (*devs == corePointer)
                 {
                     free(*devs);
-                    *devs = (IDevPtr)0x1; /* ensure we dont skip next loop*/
+                    *devs = (InputInfoPtr)0x1; /* ensure we dont skip next loop*/
 		    break;
                 }
 	    for (; devs && *devs; devs++)
@@ -1244,10 +1244,10 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
         if (foundPointer) {
 	    count++;
 	    devs = xnfrealloc(servlayoutp->inputs,
-			      (count + 1) * sizeof(IDevPtr));
-            devs[count - 1] = xnfalloc(sizeof(IDevRec));
+			      (count + 1) * sizeof(InputInfoPtr));
+            devs[count - 1] = xnfalloc(sizeof(InputInfoRec));
 	    *devs[count - 1] = Pointer;
-	    devs[count - 1]->commonOptions =
+	    devs[count - 1]->options =
 				xf86addNewOption(NULL, xnfstrdup("CorePointer"), NULL);
 	    devs[count] = NULL;
 	    servlayoutp->inputs = devs;
@@ -1288,10 +1288,10 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
         if (foundPointer) {
 	    count++;
 	    devs = xnfrealloc(servlayoutp->inputs,
-			      (count + 1) * sizeof(IDevPtr));
-            devs[count - 1] = xnfalloc(sizeof(IDevRec));
+			      (count + 1) * sizeof(InputInfoPtr));
+            devs[count - 1] = xnfalloc(sizeof(InputInfoRec));
 	    *devs[count - 1] = Pointer;
-	    devs[count - 1]->commonOptions =
+	    devs[count - 1]->options =
 				xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
 	    devs[count] = NULL;
 	    servlayoutp->inputs = devs;
@@ -1319,7 +1319,7 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
 		if (*devs == coreKeyboard)
                 {
                     free(*devs);
-                    *devs = (IDevPtr)0x1; /* ensure we dont skip next loop */
+                    *devs = (InputInfoPtr)0x1; /* ensure we dont skip next loop */
 		    break;
                 }
 	    for (; devs && *devs; devs++)
@@ -1384,10 +1384,10 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
         if (foundKeyboard) {
 	    count++;
 	    devs = xnfrealloc(servlayoutp->inputs,
-			      (count + 1) * sizeof(IDevPtr));
-            devs[count - 1] = xnfalloc(sizeof(IDevRec));
+			      (count + 1) * sizeof(InputInfoPtr));
+            devs[count - 1] = xnfalloc(sizeof(InputInfoRec));
 	    *devs[count - 1] = Keyboard;
-	    devs[count - 1]->commonOptions =
+	    devs[count - 1]->options =
 				xf86addNewOption(NULL, xnfstrdup("CoreKeyboard"), NULL);
 	    devs[count] = NULL;
 	    servlayoutp->inputs = devs;
@@ -1459,7 +1459,7 @@ static Bool
 configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
 {
     XF86ConfInputrefPtr irp;
-    IDevPtr *indp;
+    InputInfoPtr *indp;
     int count = 0;
 
     /*
@@ -1472,19 +1472,19 @@ configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
     }
     DebugF("Found %d input devices in the layout section %s\n",
 	    count, layout->lay_identifier);
-    indp = xnfcalloc((count + 1), sizeof(IDevPtr));
+    indp = xnfcalloc((count + 1), sizeof(InputInfoPtr));
     indp[count] = NULL;
     irp = layout->lay_input_lst;
     count = 0;
     while (irp) {
-	indp[count] = xnfalloc(sizeof(IDevRec));
+	indp[count] = xnfalloc(sizeof(InputInfoRec));
 	if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
 	    while(count--)
 		free(indp[count]);
 	    free(indp);
 	    return FALSE;
 	}
-	indp[count]->commonOptions = irp->iref_option_lst;
+	indp[count]->options = irp->iref_option_lst;
 	count++;
 	irp = (XF86ConfInputrefPtr)irp->list.next;
     }
@@ -1707,7 +1707,7 @@ configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
     MessageType from;
     XF86ConfScreenPtr s;
     screenLayoutPtr slp;
-    IDevPtr *indp;
+    InputInfoPtr *indp;
     XF86ConfLayoutRec layout;
 
     if (!servlayoutp)
@@ -1753,7 +1753,7 @@ configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
 	from = X_DEFAULT;
     } else {
 	/* Set up an empty input device list, then look for some core devices. */
-	indp = xnfalloc(sizeof(IDevPtr));
+	indp = xnfalloc(sizeof(InputInfoPtr));
 	*indp = NULL;
 	servlayoutp->inputs = indp;
     }
@@ -2300,12 +2300,12 @@ configExtensions(XF86ConfExtensionsPtr conf_ext)
 }
 
 static Bool
-configInput(IDevPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
+configInput(InputInfoPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
 {
     xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
-    inputp->identifier = conf_input->inp_identifier;
+    inputp->name = conf_input->inp_identifier;
     inputp->driver = conf_input->inp_driver;
-    inputp->commonOptions = conf_input->inp_option_lst;
+    inputp->options = conf_input->inp_option_lst;
     inputp->attrs = NULL;
 
     return TRUE;
@@ -2359,7 +2359,7 @@ checkInput(serverLayoutPtr layout, Bool implicit_layout) {
      */
     if (xf86Info.allowEmptyInput && layout->inputs)
     {
-        IDevPtr *dev = layout->inputs;
+        InputInfoPtr *dev = layout->inputs;
         BOOL warned = FALSE;
 
         while(*dev)
@@ -2368,7 +2368,7 @@ checkInput(serverLayoutPtr layout, Bool implicit_layout) {
                 strcmp((*dev)->driver, "mouse") == 0 ||
                 strcmp((*dev)->driver, "vmmouse") == 0)
             {
-                IDevPtr *current;
+                InputInfoPtr *current;
                 if (!warned)
                 {
                     xf86Msg(X_WARNING, "AllowEmptyInput is on, devices using "
@@ -2376,7 +2376,7 @@ checkInput(serverLayoutPtr layout, Bool implicit_layout) {
                     warned = TRUE;
                 }
 
-                xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->identifier);
+                xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->name);
 
                 current = dev;
                 free(*dev);
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index ca532ee..f93933d 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -822,7 +822,7 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
 void
 InitInput(int argc, char **argv)
 {
-    IDevPtr* pDev;
+    InputInfoPtr* pDev;
     DeviceIntPtr dev;
 
     xf86Info.vtRequestsPending = FALSE;
diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index 5920deb..7ca2fdd 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -118,38 +118,22 @@ xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)
 }
 
 /*
- * xf86CollectInputOptions collects the options for an InputDevice.
- * This function requires that the following has been initialised:
- *
- *	pInfo->conf_idev
- *
- * The extraOpts parameter may optionally contain a list of additional options
- * to include.
- *
- * The order of precedence for options is:
- *
- *   extraOpts, pInfo->conf_idev->extraOptions,
- *   pInfo->conf_idev->commonOptions, defaultOpts
+ * xf86CollectInputOptions collects extra options for an InputDevice (other
+ * than those added by the config backend).
+ * The options are merged into the existing ones and thus take precedence
+ * over the others.
  */
 
 void
 xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts)
 {
-    XF86OptionPtr tmp;
-    pInfo->options = NULL;
     if (defaultOpts) {
-	pInfo->options = xf86OptionListCreate(defaultOpts, -1, 0);
-    }
-    if (pInfo->conf_idev && pInfo->conf_idev->commonOptions) {
-	tmp = xf86optionListDup(pInfo->conf_idev->commonOptions);
+	XF86OptionPtr tmp =xf86optionListCreate(defaultOpts, -1, 0);
 	if (pInfo->options)
 	    pInfo->options = xf86optionListMerge(pInfo->options, tmp);
 	else
 	    pInfo->options = tmp;
     }
-    if (pInfo->conf_idev && pInfo->conf_idev->attrs) {
-        pInfo->attrs = pInfo->conf_idev->attrs;
-    }
 }
 
 /* Created for new XInput stuff -- essentially extensions to the parser	*/
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 0aa9c42..4c5a9bc 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -505,7 +505,7 @@ MatchAttrToken(const char *attr, struct list *patterns,
  * statements must match.
  */
 static Bool
-InputClassMatches(const XF86ConfInputClassPtr iclass, const IDevPtr idev,
+InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
                   const InputAttributes *attrs)
 {
     /* MatchProduct substring */
@@ -585,7 +585,7 @@ InputClassMatches(const XF86ConfInputClassPtr iclass, const IDevPtr idev,
  * well as any previous InputClass sections.
  */
 static int
-MergeInputClasses(const IDevPtr idev, const InputAttributes *attrs)
+MergeInputClasses(const InputInfoPtr idev, const InputAttributes *attrs)
 {
     XF86ConfInputClassPtr cl;
     XF86OptionPtr classopts;
@@ -610,9 +610,8 @@ MergeInputClasses(const IDevPtr idev, const InputAttributes *attrs)
 
         /* Apply options to device with InputClass settings preferred. */
         xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
-                idev->identifier, cl->identifier);
-        idev->commonOptions = xf86optionListMerge(idev->commonOptions,
-                                                  classopts);
+                idev->name, cl->identifier);
+        idev->options = xf86optionListMerge(idev->options, classopts);
     }
 
     return Success;
@@ -623,7 +622,7 @@ MergeInputClasses(const IDevPtr idev, const InputAttributes *attrs)
  * value of the last matching class and holler when returning TRUE.
  */
 static Bool
-IgnoreInputClass(const IDevPtr idev, const InputAttributes *attrs)
+IgnoreInputClass(const InputInfoPtr idev, const InputAttributes *attrs)
 {
     XF86ConfInputClassPtr cl;
     Bool ignore = FALSE;
@@ -640,38 +639,43 @@ IgnoreInputClass(const IDevPtr idev, const InputAttributes *attrs)
 
     if (ignore)
         xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n",
-                idev->identifier, ignore_class);
+                idev->name, ignore_class);
     return ignore;
 }
 
-/* Allocate a new InputInfoRec and append it to the tail of xf86InputDevs. */
 static InputInfoPtr
-xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
+xf86AllocateInput(void)
 {
-    InputInfoPtr new, *prev = NULL;
+    InputInfoPtr pInfo;
 
-    if (!(new = calloc(sizeof(InputInfoRec), 1)))
-	return NULL;
+    pInfo = calloc(sizeof(*pInfo), 1);
+    if (!pInfo)
+        return NULL;
+
+    pInfo->fd = -1;
+    pInfo->type_name = "UNKNOWN";
+
+    return pInfo;
+}
+
+/* Append InputInfoRec to the tail of xf86InputDevs. */
+static void
+xf86AddInput(InputDriverPtr drv, InputInfoPtr pInfo)
+{
+    InputInfoPtr *prev = NULL;
 
-    new->drv = drv;
+    pInfo->drv = drv;
     drv->refCount++;
-    new->module = DuplicateModule(drv->module, NULL);
+    pInfo->module = DuplicateModule(drv->module, NULL);
 
     for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
         ;
 
-    *prev = new;
-    new->next = NULL;
+    *prev = pInfo;
+    pInfo->next = NULL;
 
-    new->fd = -1;
-    new->name = idev->identifier;
-    new->type_name = "UNKNOWN";
-    new->conf_idev = idev;
-
-    xf86CollectInputOptions(new, (const char**)drv->default_options);
-    xf86ProcessCommonOptions(new, new->options);
-
-    return new;
+    xf86CollectInputOptions(pInfo, (const char**)drv->default_options);
+    xf86ProcessCommonOptions(pInfo, pInfo->options);
 }
 
 /*
@@ -710,6 +714,10 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
 	    p->next = pInp->next;
 	/* Else the entry wasn't in the xf86InputDevs list (ignore this). */
     }
+
+    free(pInp->driver);
+    free(pInp->name);
+    xf86optionListFree(pInp->options);
     free(pInp);
 }
 
@@ -744,21 +752,20 @@ xf86InputDevicePostInit(DeviceIntPtr dev) {
  * @return Success or an error code
  */
 _X_INTERNAL int
-xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
+xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
 {
     InputDriverPtr drv = NULL;
-    InputInfoPtr pInfo = NULL;
     DeviceIntPtr dev = NULL;
     int rval;
 
     /* Memory leak for every attached device if we don't
      * test if the module is already loaded first */
-    drv = xf86LookupInputDriver(idev->driver);
+    drv = xf86LookupInputDriver(pInfo->driver);
     if (!drv)
-        if (xf86LoadOneModule(idev->driver, NULL))
-            drv = xf86LookupInputDriver(idev->driver);
+        if (xf86LoadOneModule(pInfo->driver, NULL))
+            drv = xf86LookupInputDriver(pInfo->driver);
     if (!drv) {
-        xf86Msg(X_ERROR, "No input driver matching `%s'\n", idev->driver);
+        xf86Msg(X_ERROR, "No input driver matching `%s'\n", pInfo->driver);
         rval = BadName;
         goto unwind;
     }
@@ -771,13 +778,12 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
         goto unwind;
     }
 
-    if (!(pInfo = xf86AllocateInput(drv, idev)))
-	goto unwind;
+    xf86AddInput(drv, pInfo);
 
     rval = drv->PreInit(drv, pInfo, 0);
 
     if (rval != Success) {
-        xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, idev->identifier);
+        xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, pInfo->name);
         goto unwind;
     }
 
@@ -790,7 +796,7 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
     rval = ActivateDevice(dev, TRUE);
     if (rval != Success)
     {
-        xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
+        xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
         RemoveDevice(dev, TRUE);
         goto unwind;
     }
@@ -798,7 +804,7 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
     rval = xf86InputDevicePostInit(dev);
     if (rval != Success)
     {
-	xf86Msg(X_ERROR, "Couldn't post-init device \"%s\"\n", idev->identifier);
+	xf86Msg(X_ERROR, "Couldn't post-init device \"%s\"\n", pInfo->name);
 	RemoveDevice(dev, TRUE);
 	goto unwind;
     }
@@ -809,7 +815,7 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
         EnableDevice(dev, TRUE);
         if (!dev->enabled)
         {
-            xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
+            xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
             rval = BadMatch;
             goto unwind;
         }
@@ -822,7 +828,7 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
 
 unwind:
     if(pInfo) {
-        if(drv->UnInit)
+        if(drv && drv->UnInit)
             drv->UnInit(drv, pInfo, 0);
         else
             xf86DeleteInput(pInfo, 0);
@@ -834,23 +840,23 @@ int
 NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
                        DeviceIntPtr *pdev)
 {
-    IDevRec *idev = NULL;
+    InputInfoPtr pInfo = NULL;
     InputOption *option = NULL;
     int rval = Success;
     int is_auto = 0;
 
-    idev = calloc(sizeof(*idev), 1);
-    if (!idev)
+    pInfo = xf86AllocateInput();
+    if (!pInfo)
         return BadAlloc;
 
     for (option = options; option; option = option->next) {
         if (strcasecmp(option->key, "driver") == 0) {
-            if (idev->driver) {
+            if (pInfo->driver) {
                 rval = BadRequest;
                 goto unwind;
             }
-            idev->driver = xstrdup(option->value);
-            if (!idev->driver) {
+            pInfo->driver = xstrdup(option->value);
+            if (!pInfo->driver) {
                 rval = BadAlloc;
                 goto unwind;
             }
@@ -858,12 +864,12 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
 
         if (strcasecmp(option->key, "name") == 0 ||
             strcasecmp(option->key, "identifier") == 0) {
-            if (idev->identifier) {
+            if (pInfo->name) {
                 rval = BadRequest;
                 goto unwind;
             }
-            idev->identifier = xstrdup(option->value);
-            if (!idev->identifier) {
+            pInfo->name = xstrdup(option->value);
+            if (!pInfo->name) {
                 rval = BadAlloc;
                 goto unwind;
             }
@@ -883,7 +889,7 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
     for (option = options; option; option = option->next) {
         /* Steal option key/value strings from the provided list.
          * We need those strings, the InputOption list doesn't. */
-        idev->commonOptions = xf86addNewOption(idev->commonOptions,
+        pInfo->options = xf86addNewOption(pInfo->options,
                                                option->key, option->value);
         option->key = NULL;
         option->value = NULL;
@@ -891,42 +897,39 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
 
     /* Apply InputClass settings */
     if (attrs) {
-        if (IgnoreInputClass(idev, attrs)) {
+        if (IgnoreInputClass(pInfo, attrs)) {
             rval = BadIDChoice;
             goto unwind;
         }
 
-        rval = MergeInputClasses(idev, attrs);
+        rval = MergeInputClasses(pInfo, attrs);
         if (rval != Success)
             goto unwind;
 
-        idev->attrs = DuplicateInputAttributes(attrs);
+        pInfo->attrs = DuplicateInputAttributes(attrs);
     }
 
-    if (!idev->driver || !idev->identifier) {
+    if (!pInfo->driver || !pInfo->name) {
         xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
         rval = BadRequest;
         goto unwind;
     }
 
-    if (!idev->identifier) {
+    if (!pInfo->name) {
         xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
         rval = BadMatch;
         goto unwind;
     }
 
-    rval = xf86NewInputDevice(idev, pdev,
+    rval = xf86NewInputDevice(pInfo, pdev,
                 (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
-    if (rval == Success)
-        return Success;
+
+    return rval;
 
 unwind:
     if (is_auto && !xf86Info.autoAddDevices)
         xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
-    free(idev->driver);
-    free(idev->identifier);
-    xf86optionListFree(idev->commonOptions);
-    free(idev);
+    xf86DeleteInput(pInfo, 0);
     return rval;
 }
 
@@ -935,15 +938,10 @@ DeleteInputDeviceRequest(DeviceIntPtr pDev)
 {
     InputInfoPtr pInfo = (InputInfoPtr) pDev->public.devicePrivate;
     InputDriverPtr drv = NULL;
-    IDevRec *idev = NULL;
-    IDevPtr *it;
     Bool isMaster = IsMaster(pDev);
 
     if (pInfo) /* need to get these before RemoveDevice */
-    {
         drv = pInfo->drv;
-        idev = pInfo->conf_idev;
-    }
 
     OsBlockSignals();
     RemoveDevice(pDev, TRUE);
@@ -954,19 +952,6 @@ DeleteInputDeviceRequest(DeviceIntPtr pDev)
             drv->UnInit(drv, pInfo, 0);
         else
             xf86DeleteInput(pInfo, 0);
-
-        /* devices added by the config backend aren't in the config layout */
-        it = xf86ConfigLayout.inputs;
-        while(*it && *it != idev)
-            it++;
-
-        if (!(*it)) /* end of list, not in the layout */
-        {
-            free(idev->driver);
-            free(idev->identifier);
-            xf86optionListFree(idev->commonOptions);
-            free(idev);
-        }
     }
     OsReleaseSignals();
 }
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 9211810..2826b1c 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -78,8 +78,6 @@
 #define TS_Raw 60
 #define TS_Scaled 61
 
-struct _InputInfoRec;
-
 /* This holds the input driver entry and module information. */
 typedef struct _InputDriverRec {
     int			    driverVersion;
@@ -100,6 +98,8 @@ typedef struct _InputDriverRec {
 typedef struct _InputInfoRec {
     struct _InputInfoRec *next;
     char *		    name;
+    char *		    driver;
+
     int			    flags;
 
     Bool		    (*device_control)(DeviceIntPtr device, int what);
@@ -117,12 +117,11 @@ typedef struct _InputInfoRec {
     DeviceIntPtr	    dev;
     pointer		    private;
     char *		    type_name;
-    IDevPtr		    conf_idev;
     InputDriverPtr	    drv;
     pointer		    module;
     pointer		    options;
     InputAttributes         *attrs;
-} InputInfoRec, *InputInfoPtr;
+} *InputInfoPtr;
 
 /* xf86Globals.c */
 extern _X_EXPORT InputInfoPtr xf86InputDevs;
@@ -163,7 +162,7 @@ extern _X_EXPORT void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
 extern _X_EXPORT void xf86DisableDevice(DeviceIntPtr dev, Bool panic);
 extern _X_EXPORT void xf86EnableDevice(DeviceIntPtr dev);
 /* not exported */
-int xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL is_auto);
+int xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL is_auto);
 
 /* xf86Helper.c */
 extern _X_EXPORT void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags);
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 4659661..709c0f8 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -402,13 +402,6 @@ typedef struct {
 } GDevRec, *GDevPtr;
 
 typedef struct {
-   char *			identifier;
-   char *			driver;
-   pointer		 	commonOptions;
-   InputAttributes              *attrs;
-} IDevRec, *IDevPtr;
-
-typedef struct {
     int			frameX0;
     int			frameY0;
     int			virtualX;
@@ -477,11 +470,13 @@ typedef struct _screenlayoutrec {
     confScreenPtr	refscreen;
 } screenLayoutRec, *screenLayoutPtr;
 
+typedef struct _InputInfoRec InputInfoRec;
+
 typedef struct _serverlayoutrec {
     char *		id;
     screenLayoutPtr	screens;
     GDevPtr		inactives;
-    IDevPtr*            inputs; /* NULL terminated */
+    InputInfoRec**      inputs; /* NULL terminated */
     pointer		options;
 } serverLayoutRec, *serverLayoutPtr;
 
commit c5da32a6105b3cf57b5996971149c39103cd64b3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 14:26:20 2010 +1000

    xfree86: plug minor memory leak.
    
    When no identifier for the device was specified, the allocated IDevRec (and
    its associated fields) need to be freed.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index a34ecc1..0aa9c42 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -911,7 +911,8 @@ NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
 
     if (!idev->identifier) {
         xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
-        return BadMatch;
+        rval = BadMatch;
+        goto unwind;
     }
 
     rval = xf86NewInputDevice(idev, pdev,
commit 34ade08174bfd652cc79bf26d2ad6a10ca73d2c4
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 14:04:50 2010 +1000

    xfree86: Remove extraOptions parameter from xf86CollectInputOptions.
    
    And unexport it, drivers don't need to call this in the new init process.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index 99b533b..5920deb 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -133,12 +133,9 @@ xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)
  */
 
 void
-xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
-			pointer extraOpts)
+xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts)
 {
     XF86OptionPtr tmp;
-    XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
-
     pInfo->options = NULL;
     if (defaultOpts) {
 	pInfo->options = xf86OptionListCreate(defaultOpts, -1, 0);
@@ -150,14 +147,6 @@ xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
 	else
 	    pInfo->options = tmp;
     }
-    if (extras) {
-	tmp = xf86optionListDup(extras);
-	if (pInfo->options)
-	    pInfo->options = xf86optionListMerge(pInfo->options, tmp);
-	else
-	    pInfo->options = tmp;
-    }
-
     if (pInfo->conf_idev && pInfo->conf_idev->attrs) {
         pInfo->attrs = pInfo->conf_idev->attrs;
     }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index ee6d785..a34ecc1 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -668,7 +668,7 @@ xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
     new->type_name = "UNKNOWN";
     new->conf_idev = idev;
 
-    xf86CollectInputOptions(new, (const char**)drv->default_options, NULL);
+    xf86CollectInputOptions(new, (const char**)drv->default_options);
     xf86ProcessCommonOptions(new, new->options);
 
     return new;
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 74cc8f4..9211810 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -185,8 +185,7 @@ extern _X_EXPORT void xf86VIDrvMsgVerb(InputInfoPtr dev,
 				       va_list args);
 
 /* xf86Option.c */
-extern _X_EXPORT void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
-			     pointer extraOpts);
+extern void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts);
 
 
 /* Legacy hatred */
commit 2199842ed50b3eb40d54146827fc58cae7e873ec
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 10:52:54 2010 +1000

    xfree86: remove extraOptions field from IDevRec.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 76d820b..5d69c22 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -1130,46 +1130,24 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
      * remove the core attribute from the later ones.
      */
     for (devs = servlayoutp->inputs; devs && *devs; devs++) {
-	pointer opt1 = NULL, opt2 = NULL;
         indp = *devs;
 	if (indp->commonOptions &&
 	    xf86CheckBoolOption(indp->commonOptions, "CorePointer", FALSE)) {
-	    opt1 = indp->commonOptions;
-	}
-	if (indp->extraOptions &&
-	    xf86CheckBoolOption(indp->extraOptions, "CorePointer", FALSE)) {
-	    opt2 = indp->extraOptions;
-	}
-	if (opt1 || opt2) {
 	    if (!corePointer) {
 		corePointer = indp;
 	    } else {
-		if (opt1)
-		    xf86ReplaceBoolOption(opt1, "CorePointer", FALSE);
-		if (opt2)
-		    xf86ReplaceBoolOption(opt2, "CorePointer", FALSE);
+		    xf86ReplaceBoolOption(indp->commonOptions, "CorePointer", FALSE);
 		xf86Msg(X_WARNING, "Duplicate core pointer devices.  "
 			"Removing core pointer attribute from \"%s\"\n",
 			indp->identifier);
 	    }
 	}
-	opt1 = opt2 = NULL;
 	if (indp->commonOptions &&
 	    xf86CheckBoolOption(indp->commonOptions, "CoreKeyboard", FALSE)) {
-	    opt1 = indp->commonOptions;
-	}
-	if (indp->extraOptions &&
-	    xf86CheckBoolOption(indp->extraOptions, "CoreKeyboard", FALSE)) {
-	    opt2 = indp->extraOptions;
-	}
-	if (opt1 || opt2) {
 	    if (!coreKeyboard) {
 		coreKeyboard = indp;
 	    } else {
-		if (opt1)
-		    xf86ReplaceBoolOption(opt1, "CoreKeyboard", FALSE);
-		if (opt2)
-		    xf86ReplaceBoolOption(opt2, "CoreKeyboard", FALSE);
+		    xf86ReplaceBoolOption(indp->commonOptions, "CoreKeyboard", FALSE);
 		xf86Msg(X_WARNING, "Duplicate core keyboard devices.  "
 			"Removing core keyboard attribute from \"%s\"\n",
 			indp->identifier);
@@ -1269,7 +1247,7 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
 			      (count + 1) * sizeof(IDevPtr));
             devs[count - 1] = xnfalloc(sizeof(IDevRec));
 	    *devs[count - 1] = Pointer;
-	    devs[count - 1]->extraOptions =
+	    devs[count - 1]->commonOptions =
 				xf86addNewOption(NULL, xnfstrdup("CorePointer"), NULL);
 	    devs[count] = NULL;
 	    servlayoutp->inputs = devs;
@@ -1313,7 +1291,7 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
 			      (count + 1) * sizeof(IDevPtr));
             devs[count - 1] = xnfalloc(sizeof(IDevRec));
 	    *devs[count - 1] = Pointer;
-	    devs[count - 1]->extraOptions =
+	    devs[count - 1]->commonOptions =
 				xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
 	    devs[count] = NULL;
 	    servlayoutp->inputs = devs;
@@ -1409,7 +1387,7 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
 			      (count + 1) * sizeof(IDevPtr));
             devs[count - 1] = xnfalloc(sizeof(IDevRec));
 	    *devs[count - 1] = Keyboard;
-	    devs[count - 1]->extraOptions =
+	    devs[count - 1]->commonOptions =
 				xf86addNewOption(NULL, xnfstrdup("CoreKeyboard"), NULL);
 	    devs[count] = NULL;
 	    servlayoutp->inputs = devs;
@@ -1506,7 +1484,7 @@ configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
 	    free(indp);
 	    return FALSE;
 	}
-	indp[count]->extraOptions = irp->iref_option_lst;
+	indp[count]->commonOptions = irp->iref_option_lst;
 	count++;
 	irp = (XF86ConfInputrefPtr)irp->list.next;
     }
@@ -2328,7 +2306,6 @@ configInput(IDevPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
     inputp->identifier = conf_input->inp_identifier;
     inputp->driver = conf_input->inp_driver;
     inputp->commonOptions = conf_input->inp_option_lst;
-    inputp->extraOptions = NULL;
     inputp->attrs = NULL;
 
     return TRUE;
diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c
index aa6ea30..99b533b 100644
--- a/hw/xfree86/common/xf86Option.c
+++ b/hw/xfree86/common/xf86Option.c
@@ -150,13 +150,6 @@ xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
 	else
 	    pInfo->options = tmp;
     }
-    if (pInfo->conf_idev && pInfo->conf_idev->extraOptions) {
-	tmp = xf86optionListDup(pInfo->conf_idev->extraOptions);
-	if (pInfo->options)
-	    pInfo->options = xf86optionListMerge(pInfo->options, tmp);
-	else
-	    pInfo->options = tmp;
-    }
     if (extras) {
 	tmp = xf86optionListDup(extras);
 	if (pInfo->options)
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index c9b261d..4659661 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -405,7 +405,6 @@ typedef struct {
    char *			identifier;
    char *			driver;
    pointer		 	commonOptions;
-   pointer			extraOptions;
    InputAttributes              *attrs;
 } IDevRec, *IDevPtr;
 
commit 5ab8ca0807f9d2f8c8de2f9a1421e59e2a8e976c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 10:41:27 2010 +1000

    xfree86: remove some ifdef 0 code.
    
    InputInfoRec hasn't had a free function pointer since the git import.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index b277986..ee6d785 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -686,12 +686,6 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
     if (pInp == NULL)
 	return;
 
-#if 0
-    /* If a free function is defined, call it here. */
-    if (pInp->free)
-	pInp->free(pInp, 0);
-#endif
-
     if (pInp->module)
 	UnloadModule(pInp->module);
 
commit b0da1bc509446a714eb2b29cbd35d43b1e5187ed
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 10:39:24 2010 +1000

    xfree86: move a declaration down to the block it is used in.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 1b986e3..b277986 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -682,8 +682,6 @@ xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
 void
 xf86DeleteInput(InputInfoPtr pInp, int flags)
 {
-    InputInfoPtr p;
-
     /* First check if the inputdev is valid. */
     if (pInp == NULL)
 	return;
@@ -711,7 +709,7 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
     if (pInp == xf86InputDevs)
 	xf86InputDevs = pInp->next;
     else {
-	p = xf86InputDevs;
+	InputInfoPtr p = xf86InputDevs;
 	while (p && p->next != pInp)
 	    p = p->next;
 	if (p)
commit cd7059db4a766bc9d03d7968aebeba8542e6c6c0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 10:36:47 2010 +1000

    xfree86: minor comment fix. HAL → config backend
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index d5d03e9..1b986e3 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -962,7 +962,7 @@ DeleteInputDeviceRequest(DeviceIntPtr pDev)
         else
             xf86DeleteInput(pInfo, 0);
 
-        /* devices added through HAL aren't in the config layout */
+        /* devices added by the config backend aren't in the config layout */
         it = xf86ConfigLayout.inputs;
         while(*it && *it != idev)
             it++;
commit f3861522fe7d148fd4b0802f2f9ea5d98ab2db93
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 2 11:47:30 2010 +1000

     xfree86: skip a few NULL initialization, calloc does it for us.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 538a98b..d5d03e9 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -666,12 +666,6 @@ xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
     new->fd = -1;
     new->name = idev->identifier;
     new->type_name = "UNKNOWN";
-    new->device_control = NULL;
-    new->read_input = NULL;
-    new->control_proc = NULL;
-    new->switch_mode = NULL;
-    new->dev = NULL;
-    new->private = NULL;
     new->conf_idev = idev;
 
     xf86CollectInputOptions(new, (const char**)drv->default_options, NULL);
commit 12170978617c6862fb6aa286b18aaacd0a4e2737
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 1 15:44:44 2010 +1000

    xfree86: remove conversion procs and close proc from InputInfoRec.
    
    None of them are called by the server.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Fernando Carrijo <fcarrijo at freedesktop.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index bbaffd0..538a98b 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -669,10 +669,7 @@ xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
     new->device_control = NULL;
     new->read_input = NULL;
     new->control_proc = NULL;
-    new->close_proc = NULL;
     new->switch_mode = NULL;
-    new->conversion_proc = NULL;
-    new->reverse_conversion_proc = NULL;
     new->dev = NULL;
     new->private = NULL;
     new->conf_idev = idev;
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 9a3d223..74cc8f4 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -106,16 +106,8 @@ typedef struct _InputInfoRec {
     void		    (*read_input)(struct _InputInfoRec *local);
     int			    (*control_proc)(struct _InputInfoRec *local,
 					   xDeviceCtl *control);
-    void		    (*close_proc)(struct _InputInfoRec *local);
     int			    (*switch_mode)(ClientPtr client, DeviceIntPtr dev,
 					  int mode);
-    Bool		    (*conversion_proc)(struct _InputInfoRec *local,
-					      int first, int num, int v0,
-					      int v1, int v2, int v3, int v4,
-					      int v5, int *x, int *y);
-    Bool		    (*reverse_conversion_proc)(
-					struct _InputInfoRec *local,
-					int x, int y, int *valuators);
     int                     (*set_device_valuators)
 				(struct _InputInfoRec *local,
 				 int *valuators, int first_valuator,
commit 9802cca816884e7f055f054ac1ba9194e0eba10b
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 1 15:42:44 2010 +1000

    Remove atom field from InputInfoRec.
    
    This field was only used in one location where we can use a local variable.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 6673b1e..bbaffd0 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -295,6 +295,7 @@ static DeviceIntPtr
 xf86ActivateDevice(InputInfoPtr pInfo)
 {
     DeviceIntPtr	dev;
+    Atom		atom;
 
     dev = AddInputDevice(serverClient, pInfo->device_control, TRUE);
 
@@ -306,8 +307,8 @@ xf86ActivateDevice(InputInfoPtr pInfo)
         return NULL;
     }
 
-    pInfo->atom = MakeAtom(pInfo->type_name, strlen(pInfo->type_name), TRUE);
-    AssignTypeAndName(dev, pInfo->atom, pInfo->name);
+    atom = MakeAtom(pInfo->type_name, strlen(pInfo->type_name), TRUE);
+    AssignTypeAndName(dev, atom, pInfo->name);
     dev->public.devicePrivate = pInfo;
     pInfo->dev = dev;
 
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index edc447c..9a3d223 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -122,7 +122,6 @@ typedef struct _InputInfoRec {
 				 int num_valuators);
 
     int			    fd;
-    Atom		    atom;
     DeviceIntPtr	    dev;
     pointer		    private;
     char *		    type_name;
commit 79ea9ef39971d008d199b18f34d1aef2bab6e33f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Tue Aug 10 15:19:20 2010 +1000

    input: constify valuators passed in by input drivers.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index e5134d3..4d32ed3 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -912,7 +912,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code)
 int
 GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
                           int key_code, int first_valuator,
-                          int num_valuators, int *valuators_in) {
+                          int num_valuators, const int *valuators_in) {
     int num_events = 0;
     CARD32 ms = 0;
     DeviceEvent *event;
@@ -1071,7 +1071,7 @@ transformAbsolute(DeviceIntPtr dev, int v[MAX_VALUATORS])
 int
 GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
                  int flags, int first_valuator, int num_valuators,
-                 int *valuators_in) {
+                 const int *valuators_in) {
     int num_events = 1;
     CARD32 ms;
     DeviceEvent *event;
@@ -1191,7 +1191,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
  */
 int
 GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
-                   int first_valuator, int num_valuators, int *valuators_in)
+                   int first_valuator, int num_valuators, const int *valuators_in)
 {
     int num_events = 1;
     DeviceEvent *event;
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 1654103..6673b1e 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -1016,7 +1016,7 @@ xf86PostMotionEventP(DeviceIntPtr	device,
                     int			is_absolute,
                     int			first_valuator,
                     int			num_valuators,
-                    int			*valuators)
+                    const int		*valuators)
 {
     int i = 0, nevents = 0;
     DeviceEvent *event;
@@ -1097,7 +1097,7 @@ xf86PostProximityEventP(DeviceIntPtr	device,
                         int		is_in,
                         int		first_valuator,
                         int		num_valuators,
-                        int		*valuators)
+                        const int	*valuators)
 {
     int i, nevents;
 
@@ -1143,7 +1143,7 @@ xf86PostButtonEventP(DeviceIntPtr	device,
                      int		is_down,
                      int		first_valuator,
                      int		num_valuators,
-                     int		*valuators)
+                     const int		*valuators)
 {
     int i = 0, nevents = 0;
     int flags = 0;
@@ -1208,7 +1208,7 @@ xf86PostKeyEventP(DeviceIntPtr	device,
                   int		is_absolute,
                   int		first_valuator,
                   int		num_valuators,
-                  int		*valuators)
+                  const int	*valuators)
 {
     int i = 0, nevents = 0;
 
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 0ddfe70..edc447c 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -140,23 +140,23 @@ extern _X_EXPORT InputInfoPtr xf86InputDevs;
 extern _X_EXPORT void xf86PostMotionEvent(DeviceIntPtr device, int is_absolute,
 			 int first_valuator, int num_valuators, ...);
 extern _X_EXPORT void xf86PostMotionEventP(DeviceIntPtr device, int is_absolute,
-			 int first_valuator, int num_valuators, int *valuators);
+			 int first_valuator, int num_valuators, const int *valuators);
 extern _X_EXPORT void xf86PostProximityEvent(DeviceIntPtr device, int is_in,
 			    int first_valuator, int num_valuators, ...);
 extern _X_EXPORT void xf86PostProximityEventP(DeviceIntPtr device, int is_in, int first_valuator,
-			     int num_valuators, int *valuators);
+			     int num_valuators, const int *valuators);
 extern _X_EXPORT void xf86PostButtonEvent(DeviceIntPtr device, int is_absolute, int button,
 		    	 int is_down, int first_valuator, int num_valuators,
 			 ...);
 extern _X_EXPORT void xf86PostButtonEventP(DeviceIntPtr device, int is_absolute, int button,
 			  int is_down, int first_valuator, int num_valuators,
-			  int *valuators);
+			  const int *valuators);
 extern _X_EXPORT void xf86PostKeyEvent(DeviceIntPtr device, unsigned int key_code, int is_down,
 		      int is_absolute, int first_valuator, int num_valuators,
 		      ...);
 extern _X_EXPORT void xf86PostKeyEventP(DeviceIntPtr device, unsigned int key_code, int is_down,
 		       int is_absolute, int first_valuator, int num_valuators,
-		       int *valuators);
+		       const int *valuators);
 extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int key_code,
                            int is_down);
 extern _X_EXPORT InputInfoPtr xf86FirstLocalDevice(void);
diff --git a/include/input.h b/include/input.h
index 388ef21..36ce4c9 100644
--- a/include/input.h
+++ b/include/input.h
@@ -447,7 +447,7 @@ extern _X_EXPORT int GetPointerEvents(
     int flags,
     int first_valuator,
     int num_valuators,
-    int *valuators);
+    const int *valuators);
 
 extern _X_EXPORT int GetKeyboardEvents(
     EventListPtr events,
@@ -462,7 +462,7 @@ extern int GetKeyboardValuatorEvents(
     int key_code,
     int first_valuator,
     int num_valuator,
-    int *valuators);
+    const int *valuators);
 
 extern int GetProximityEvents(
     EventListPtr events,
@@ -470,7 +470,7 @@ extern int GetProximityEvents(
     int type,
     int first_valuator,
     int num_valuators,
-    int *valuators);
+    const int *valuators);
 
 extern void PostSyntheticMotion(
     DeviceIntPtr pDev,
commit be978c7fc97e98ef1bc7b20c6c0740d8a81b609a
Author: Jesse Adkins <jesserayadkins at gmail.com>
Date:   Tue Aug 3 18:21:28 2010 -0700

    xfree86: Purge kbdCustomKeycodes from xf86Info.
    
    This was obsolete after 3eeb62e8f587732e6b433c2b9c6879eb26a3f1b4 "bug #890: completely remove deprecated keyboard driver".
    
    Signed-off-by: Jesse Adkins <jesserayadkins at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
index 43665d1..2a3b978 100644
--- a/hw/xfree86/common/xf86Globals.c
+++ b/hw/xfree86/common/xf86Globals.c
@@ -125,7 +125,6 @@ xf86InfoRec xf86Info = {
 #endif
     .pmFlag                     = TRUE,
     .log                        = LogNone,
-    .kbdCustomKeycodes          = FALSE,
     .disableRandR               = FALSE,
     .randRFrom                  = X_DEFAULT,
 #if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
diff --git a/hw/xfree86/common/xf86Privstr.h b/hw/xfree86/common/xf86Privstr.h
index 39cd230..efe19e2 100644
--- a/hw/xfree86/common/xf86Privstr.h
+++ b/hw/xfree86/common/xf86Privstr.h
@@ -96,7 +96,6 @@ typedef struct {
 #endif
     Bool		pmFlag;
     Log			log;
-    Bool		kbdCustomKeycodes;
     Bool		disableRandR;
     MessageType		randRFrom;
     Bool		aiglx;
commit 6922b31a136b2b0ac185d61785969a11f84c7943
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 1 14:35:40 2010 +1000

    xfree86: remove history_size
    
    For a couple of ABIs now the history size was essentially static anyway.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 0e094d2..1654103 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -280,9 +280,6 @@ xf86ProcessCommonOptions(InputInfoPtr pInfo,
         pInfo->flags |= XI86_ALWAYS_CORE;
         xf86Msg(X_CONFIG, "%s: always reports core events\n", pInfo->name);
     }
-
-    /* Backwards compatibility. */
-    pInfo->history_size = GetMotionHistorySize();
 }
 
 /***********************************************************************
@@ -670,7 +667,6 @@ xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
     new->type_name = "UNKNOWN";
     new->device_control = NULL;
     new->read_input = NULL;
-    new->history_size = 0;
     new->control_proc = NULL;
     new->close_proc = NULL;
     new->switch_mode = NULL;
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index ad59339..0ddfe70 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -130,7 +130,6 @@ typedef struct _InputInfoRec {
     InputDriverPtr	    drv;
     pointer		    module;
     pointer		    options;
-    unsigned int            history_size;
     InputAttributes         *attrs;
 } InputInfoRec, *InputInfoPtr;
 
commit 892e39025b45109ba38c0b5d0b5f4535e092f58c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 1 14:33:52 2010 +1000

    xfree86: remove always_core_feedback from InputInfoRec.
    
    Unused
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index ae8c4e1..0e094d2 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -677,7 +677,6 @@ xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
     new->conversion_proc = NULL;
     new->reverse_conversion_proc = NULL;
     new->dev = NULL;
-    new->always_core_feedback = NULL;
     new->private = NULL;
     new->conf_idev = idev;
 
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index b1a2ac6..ad59339 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -126,7 +126,6 @@ typedef struct _InputInfoRec {
     DeviceIntPtr	    dev;
     pointer		    private;
     char *		    type_name;
-    IntegerFeedbackPtr	    always_core_feedback;
     IDevPtr		    conf_idev;
     InputDriverPtr	    drv;
     pointer		    module;
commit 5e2912bd1d2bc8ff1508e5f726e77aa5f8677cbd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 1 14:33:26 2010 +1000

    xfree86: remove first/last from InputInfoRec.
    
    Unused.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index e738649..b1a2ac6 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -125,8 +125,6 @@ typedef struct _InputInfoRec {
     Atom		    atom;
     DeviceIntPtr	    dev;
     pointer		    private;
-    unsigned int	    first;
-    unsigned int	    last;
     char *		    type_name;
     IntegerFeedbackPtr	    always_core_feedback;
     IDevPtr		    conf_idev;
commit 974bc2322b3667db38d28063786fbc76fb303d00
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 1 14:32:51 2010 +1000

    xfree86: remove private_flags from InputInfoRec.
    
    Unused field.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index f924ec8..ae8c4e1 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -677,7 +677,6 @@ xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
     new->conversion_proc = NULL;
     new->reverse_conversion_proc = NULL;
     new->dev = NULL;
-    new->private_flags = 0;
     new->always_core_feedback = NULL;
     new->private = NULL;
     new->conf_idev = idev;
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index bb7a4aa..e738649 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -125,7 +125,6 @@ typedef struct _InputInfoRec {
     Atom		    atom;
     DeviceIntPtr	    dev;
     pointer		    private;
-    int			    private_flags;
     unsigned int	    first;
     unsigned int	    last;
     char *		    type_name;
commit 23b361b25b7b48a820a4ef851fb89706f7ec2cd0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Sep 1 14:14:20 2010 +1000

    xfree86: Purge old_x/old_y from InputInfoRec.
    
    Unused field.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index dab76c0..bb7a4aa 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -128,8 +128,6 @@ typedef struct _InputInfoRec {
     int			    private_flags;
     unsigned int	    first;
     unsigned int	    last;
-    int			    old_x;
-    int			    old_y;
     char *		    type_name;
     IntegerFeedbackPtr	    always_core_feedback;
     IDevPtr		    conf_idev;
commit 4ac3be29bc1af19f15e84ee0ea609de5c54ca0e0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 30 14:26:06 2010 +1000

    input: Purge AddOtherInputDevices DDX hook.
    
    This hook wasn't used by any DDX. Device addition and removal is handled by
    the config backend, so we don't need to do anything special that during the
    ListInputDevices request processing.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/Xi/listdev.c b/Xi/listdev.c
index 3b2272b..3e5f3d9 100644
--- a/Xi/listdev.c
+++ b/Xi/listdev.c
@@ -356,9 +356,6 @@ ProcXListInputDevices(ClientPtr client)
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
 
-
-    AddOtherInputDevices();
-
     /* allocate space for saving skip value */
     skip = calloc(sizeof(Bool), inputInfo.numDevices);
     if (!skip)
diff --git a/Xi/stubs.c b/Xi/stubs.c
index 4c9795a..d9e8eec 100644
--- a/Xi/stubs.c
+++ b/Xi/stubs.c
@@ -66,49 +66,6 @@ SOFTWARE.
 #include "XIstubs.h"
 #include "xace.h"
 
-/***********************************************************************
- *
- * Caller:	ProcXListInputDevices
- *
- * This is the implementation-dependent routine to initialize an input
- * device to the point that information about it can be listed.
- * Some implementations open all input devices when the server is first
- * initialized, and never close them.  Other implementations open only
- * the X pointer and keyboard devices during server initialization,
- * and only open other input devices when some client makes an
- * XOpenDevice request.  If some other process has the device open, the
- * server may not be able to get information about the device to list it.
- *
- * This procedure should be used by implementations that do not initialize
- * all input devices at server startup.  It should do device-dependent
- * initialization for any devices not previously initialized, and call
- * AddInputDevice for each of those devices so that a DeviceIntRec will be
- * created for them.
- *
- * The default implementation is to do nothing (assume all input devices
- * are initialized during X server initialization and kept open).
- * The commented-out sample code shows what you might do if you don't want
- * the default.
- *
- */
-
-void
-AddOtherInputDevices(void)
-{
-    /**********************************************************************
-     for each uninitialized device, do something like:
-
-    DeviceIntPtr dev;
-    DeviceProc deviceProc;
-    pointer private;
-
-    dev = (DeviceIntPtr) AddInputDevice(deviceProc, TRUE);
-    dev->public.devicePrivate = private;
-    dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
-    ************************************************************************/
-
-}
-
 /****************************************************************************
  *
  * Caller:	ProcXSetDeviceMode
diff --git a/hw/dmx/input/dmxxinput.c b/hw/dmx/input/dmxxinput.c
index a5c28a9..54381b2 100644
--- a/hw/dmx/input/dmxxinput.c
+++ b/hw/dmx/input/dmxxinput.c
@@ -51,11 +51,6 @@
 #include "dmxinputinit.h"
 #include "exevents.h"
 
-/** This is not required by the XINPUT model that DMX uses. */
-void AddOtherInputDevices(void)
-{
-}
-
 /** Set device mode to \a mode.  This is not implemented. */
 int SetDeviceMode(ClientPtr client, DeviceIntPtr dev, int mode)
 {
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 2ab6dc2..61ee163 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -2176,13 +2176,6 @@ ProcessInputEvents (void)
     KdCheckLock ();
 }
 
-/* We initialise all input devices at startup. */
-void
-AddOtherInputDevices(void)
-{
-    return;
-}
-
 /* At the moment, absolute/relative is up to the client. */
 int
 SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode)
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 4a6adbc..f924ec8 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -412,11 +412,6 @@ ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
   }
 }
 
-void
-AddOtherInputDevices(void)
-{
-}
-
 /*
  * Get the operating system name from uname and store it statically to avoid
  * repeating the system call each time MatchOS is checked.
diff --git a/hw/xquartz/darwinXinput.c b/hw/xquartz/darwinXinput.c
index 64d9b23..15d9c52 100644
--- a/hw/xquartz/darwinXinput.c
+++ b/hw/xquartz/darwinXinput.c
@@ -82,49 +82,6 @@ CloseInputDevice(DeviceIntPtr d, ClientPtr client)
   DEBUG_LOG("CloseInputDevice(%p, %p)\n", d, client);
 }
 
-/***********************************************************************
- *
- * Caller:	ProcXListInputDevices
- *
- * This is the implementation-dependent routine to initialize an input 
- * device to the point that information about it can be listed.
- * Some implementations open all input devices when the server is first
- * initialized, and never close them.  Other implementations open only
- * the X pointer and keyboard devices during server initialization,
- * and only open other input devices when some client makes an
- * XOpenDevice request.  If some other process has the device open, the
- * server may not be able to get information about the device to list it.
- *
- * This procedure should be used by implementations that do not initialize
- * all input devices at server startup.  It should do device-dependent
- * initialization for any devices not previously initialized, and call
- * AddInputDevice for each of those devices so that a DeviceIntRec will be 
- * created for them.
- *
- * The default implementation is to do nothing (assume all input devices
- * are initialized during X server initialization and kept open).
- * The commented-out sample code shows what you might do if you don't want 
- * the default.
- *
- */
-
-void
-AddOtherInputDevices(void)
-{
-    /**********************************************************************
-     for each uninitialized device, do something like: 
-
-    DeviceIntPtr dev;
-    DeviceProc deviceProc;
-    pointer private;
-
-    dev = (DeviceIntPtr) AddInputDevice(deviceProc, TRUE);
-    dev->public.devicePrivate = private;
-    dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
-    ************************************************************************/
-  DEBUG_LOG("AddOtherInputDevices\n");
-}
-
 /****************************************************************************
  *
  * Caller:	ProcXSetDeviceMode
diff --git a/include/XIstubs.h b/include/XIstubs.h
index 0bb773e..6ab82df 100644
--- a/include/XIstubs.h
+++ b/include/XIstubs.h
@@ -26,9 +26,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #ifndef XI_STUBS_H
 #define XI_STUBS_H 1
 
-extern _X_EXPORT void
-AddOtherInputDevices (void);
-
 extern _X_EXPORT int
 SetDeviceMode (
 	ClientPtr              /* client */,
commit cb672a461cc6cd668ab7e61994b94e9ff46b3ef1
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 30 14:21:14 2010 +1000

    input: remove OpenInputDevice and CloseInputDevice DDX hooks.
    
    In theory, these hooks were to be used for DDX-specific device enablement.
    None of the DDXs however did anything here. Now we call DEVICE_INIT on all
    devices when they are added, so the xfree86 DDX as the only one with real
    code didn't do anything here.
    
    kdrive checked for device validity but that's already handled in
    ProcXOpenDevice.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/Xi/closedev.c b/Xi/closedev.c
index e319c73..1064be6 100644
--- a/Xi/closedev.c
+++ b/Xi/closedev.c
@@ -162,6 +162,5 @@ ProcXCloseDevice(ClientPtr client)
 	DeleteEventsFromChildren(d, p1, client);
     }
 
-    CloseInputDevice(d, client);
     return Success;
 }
diff --git a/Xi/opendev.c b/Xi/opendev.c
index e4c02d3..13841dc 100644
--- a/Xi/opendev.c
+++ b/Xi/opendev.c
@@ -115,7 +115,6 @@ ProcXOpenDevice(ClientPtr client)
     if (IsMaster(dev))
             return BadDevice;
 
-    OpenInputDevice(dev, client, &status);
     if (status != Success)
 	return status;
 
diff --git a/Xi/stubs.c b/Xi/stubs.c
index de80042..4c9795a 100644
--- a/Xi/stubs.c
+++ b/Xi/stubs.c
@@ -68,24 +68,6 @@ SOFTWARE.
 
 /***********************************************************************
  *
- * Caller:	ProcXCloseDevice
- *
- * Take care of implementation-dependent details of closing a device.
- * Some implementations may actually close the device, others may just
- * remove this clients interest in that device.
- *
- * The default implementation is to do nothing (assume all input devices
- * are initialized during X server initialization and kept open).
- *
- */
-
-void
-CloseInputDevice(DeviceIntPtr d, ClientPtr client)
-{
-}
-
-/***********************************************************************
- *
  * Caller:	ProcXListInputDevices
  *
  * This is the implementation-dependent routine to initialize an input
@@ -127,34 +109,6 @@ AddOtherInputDevices(void)
 
 }
 
-/***********************************************************************
- *
- * Caller:	ProcXOpenDevice
- *
- * This is the implementation-dependent routine to open an input device.
- * Some implementations open all input devices when the server is first
- * initialized, and never close them.  Other implementations open only
- * the X pointer and keyboard devices during server initialization,
- * and only open other input devices when some client makes an
- * XOpenDevice request.  This entry point is for the latter type of
- * implementation.
- *
- * If the physical device is not already open, do it here.  In this case,
- * you need to keep track of the fact that one or more clients has the
- * device open, and physically close it when the last client that has
- * it open does an XCloseDevice.
- *
- * The default implementation is to do nothing (assume all input devices
- * are opened during X server initialization and kept open).
- *
- */
-
-void
-OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int *status)
-{
-    *status = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixUseAccess);
-}
-
 /****************************************************************************
  *
  * Caller:	ProcXSetDeviceMode
diff --git a/hw/dmx/input/dmxxinput.c b/hw/dmx/input/dmxxinput.c
index 8b58eeb..a5c28a9 100644
--- a/hw/dmx/input/dmxxinput.c
+++ b/hw/dmx/input/dmxxinput.c
@@ -51,23 +51,11 @@
 #include "dmxinputinit.h"
 #include "exevents.h"
 
-/** Close the input device.  This is not required by the XINPUT model
- * that DMX uses. */
-void CloseInputDevice (DeviceIntPtr d, ClientPtr client)
-{
-}
-
 /** This is not required by the XINPUT model that DMX uses. */
 void AddOtherInputDevices(void)
 {
 }
 
-/** Open an input device.  This is not required by the XINPUT model that
- * DMX uses. */
-void OpenInputDevice (DeviceIntPtr dev, ClientPtr client, int *status)
-{
-}
-
 /** Set device mode to \a mode.  This is not implemented. */
 int SetDeviceMode(ClientPtr client, DeviceIntPtr dev, int mode)
 {
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index a4691df..2ab6dc2 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -2176,23 +2176,6 @@ ProcessInputEvents (void)
     KdCheckLock ();
 }
 
-/* FIXME use XSECURITY to work out whether the client should be allowed to
- * open and close. */
-void
-OpenInputDevice(DeviceIntPtr pDev, ClientPtr client, int *status)
-{
-    if (!pDev)
-        *status = BadDevice;
-    else
-        *status = Success;
-}
-
-void
-CloseInputDevice(DeviceIntPtr pDev, ClientPtr client)
-{
-    return;
-}
-
 /* We initialise all input devices at startup. */
 void
 AddOtherInputDevices(void)
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 1bd0082..4a6adbc 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -327,47 +327,6 @@ xf86ActivateDevice(InputInfoPtr pInfo)
     return dev;
 }
 
-
-/***********************************************************************
- *
- * Caller:	ProcXOpenDevice
- *
- * This is the implementation-dependent routine to open an input device.
- * Some implementations open all input devices when the server is first
- * initialized, and never close them.  Other implementations open only
- * the X pointer and keyboard devices during server initialization,
- * and only open other input devices when some client makes an
- * XOpenDevice request.  This entry point is for the latter type of 
- * implementation.
- *
- * If the physical device is not already open, do it here.  In this case,
- * you need to keep track of the fact that one or more clients has the
- * device open, and physically close it when the last client that has
- * it open does an XCloseDevice.
- *
- * The default implementation is to do nothing (assume all input devices
- * are opened during X server initialization and kept open).
- *
- ***********************************************************************
- */
-
-void
-OpenInputDevice(DeviceIntPtr	dev,
-                ClientPtr	client,
-                int		*status)
-{
-    if (!dev->inited)
-        ActivateDevice(dev, TRUE);
-
-    *status = Success;
-}
-
-void
-CloseInputDevice(DeviceIntPtr dev,
-                 ClientPtr client)
-{
-}
-
 /****************************************************************************
  *
  * Caller:	ProcXSetDeviceMode
diff --git a/hw/xquartz/darwinXinput.c b/hw/xquartz/darwinXinput.c
index 966aaf3..64d9b23 100644
--- a/hw/xquartz/darwinXinput.c
+++ b/hw/xquartz/darwinXinput.c
@@ -125,34 +125,6 @@ AddOtherInputDevices(void)
   DEBUG_LOG("AddOtherInputDevices\n");
 }
 
-/***********************************************************************
- *
- * Caller:	ProcXOpenDevice
- *
- * This is the implementation-dependent routine to open an input device.
- * Some implementations open all input devices when the server is first
- * initialized, and never close them.  Other implementations open only
- * the X pointer and keyboard devices during server initialization,
- * and only open other input devices when some client makes an
- * XOpenDevice request.  This entry point is for the latter type of 
- * implementation.
- *
- * If the physical device is not already open, do it here.  In this case,
- * you need to keep track of the fact that one or more clients has the
- * device open, and physically close it when the last client that has
- * it open does an XCloseDevice.
- *
- * The default implementation is to do nothing (assume all input devices
- * are opened during X server initialization and kept open).
- *
- */
-
-void
-OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int *status)
-{
-  DEBUG_LOG("OpenInputDevice(%p, %p, %p)\n", dev, client, status);
-}
-
 /****************************************************************************
  *
  * Caller:	ProcXSetDeviceMode
diff --git a/include/XIstubs.h b/include/XIstubs.h
index ba2f861..0bb773e 100644
--- a/include/XIstubs.h
+++ b/include/XIstubs.h
@@ -27,19 +27,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #define XI_STUBS_H 1
 
 extern _X_EXPORT void
-CloseInputDevice (
-	DeviceIntPtr           /* d */,
-	ClientPtr              /* client */);
-
-extern _X_EXPORT void
 AddOtherInputDevices (void);
 
-extern _X_EXPORT void
-OpenInputDevice (
-	DeviceIntPtr           /* dev */,
-	ClientPtr              /* client */,
-	int *                  /* status */);
-
 extern _X_EXPORT int
 SetDeviceMode (
 	ClientPtr              /* client */,
commit a46d2bb344e822bbd9d69cb59829b85f9d8f0213
Author: Simon Thum <simon.thum at gmx.de>
Date:   Sun Jul 18 12:31:26 2010 +0200

    xfree86: Fix xf86 backend-specific input initialization
    
    Instead of shoving it in rather unrelated places, move acceleration init
    into xf86NewInputDevice.
    
    Caveat: It's not clear atm how relevant other callers of ActivateDevice
    (like OpenDevice) actually are.
    
    Signed-off-by: Simon Thum <simon.thum at gmx.de>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index aae9fe2..1bd0082 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -92,6 +92,9 @@
 
 EventListPtr xf86Events = NULL;
 
+static int
+xf86InputDevicePostInit(DeviceIntPtr dev);
+
 /**
  * Eval config and modify DeviceVelocityRec accordingly
  */
@@ -778,6 +781,19 @@ xf86DeleteInput(InputInfoPtr pInp, int flags)
     free(pInp);
 }
 
+/*
+ * Apply backend-specific initialization. Invoked after ActiveteDevice(),
+ * i.e. after the driver successfully completed DEVICE_INIT and the device
+ * is advertised.
+ * @param dev the device
+ * @return Success or an error code
+ */
+static int
+xf86InputDevicePostInit(DeviceIntPtr dev) {
+    ApplyAccelerationSettings(dev);
+    return Success;
+}
+
 /**
  * Create a new input device, activate and enable it.
  *
@@ -847,6 +863,14 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
         goto unwind;
     }
 
+    rval = xf86InputDevicePostInit(dev);
+    if (rval != Success)
+    {
+	xf86Msg(X_ERROR, "Couldn't post-init device \"%s\"\n", idev->identifier);
+	RemoveDevice(dev, TRUE);
+	goto unwind;
+    }
+
     /* Enable it if it's properly initialised and we're currently in the VT */
     if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema)
     {
@@ -1357,9 +1381,6 @@ xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
 	dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
         dev->last.valuators[1] = dev->valuator->axisVal[1];
     }
-
-    if(axnum == 0)  /* to prevent double invocation */
-	ApplyAccelerationSettings(dev);
 }
 
 
commit e930710ae5579752785d6b96ace4b44bf0199a6e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 30 13:59:29 2010 +1000

    xfree86: purge superfluous includes from xf86Xinput.c
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 002c2af..aae9fe2 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -59,19 +59,10 @@
 #include "xf86Priv.h"
 #include "xf86Config.h"
 #include "xf86Xinput.h"
-#include "XIstubs.h"
 #include "xf86Optrec.h"
-#include "xf86Parser.h"
 #include "mipointer.h"
-#include "xf86InPriv.h"
-#include "compiler.h"
 #include "extinit.h"
 
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-
 #include "exevents.h"	/* AddInputDevice */
 #include "exglobals.h"
 #include "eventstr.h"
@@ -84,15 +75,9 @@
 #include <sys/utsname.h>
 #endif
 
-#include "extnsionst.h"
-
-#include "windowstr.h"	/* screenIsSaved */
-
 #include <stdarg.h>
 #include <stdint.h>          /* for int64_t */
 
-#include <X11/Xpoll.h>
-
 #include "mi.h"
 
 #include <ptrveloc.h>          /* dix pointer acceleration */
@@ -104,7 +89,6 @@
 
 #include "xkbsrv.h"
 
-#include "os.h"
 
 EventListPtr xf86Events = NULL;
 
commit 2b7840b63da6bc00aa40e8a427d9fd719ba5e6d0
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 30 13:44:20 2010 +1000

    xfree86: remove unused DeviceAssocRec struct.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index 28786ba..76d820b 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -63,7 +63,6 @@
 #include "Pci.h"
 
 #include "xf86Xinput.h"
-extern DeviceAssocRec mouse_assoc;
 
 #include "xkbsrv.h"
 
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 6f003cc..dab76c0 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -140,12 +140,6 @@ typedef struct _InputInfoRec {
     InputAttributes         *attrs;
 } InputInfoRec, *InputInfoPtr;
 
-typedef struct _DeviceAssocRec 
-{
-    char *		    config_section_name;
-    InputInfoPtr	    (*device_allocate)(void);
-} DeviceAssocRec, *DeviceAssocPtr;
-
 /* xf86Globals.c */
 extern _X_EXPORT InputInfoPtr xf86InputDevs;
 
commit cdb5863c9f68548afa0c69e08c697c83f9a5e671
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Jul 23 14:16:38 2010 +1000

    xfree86: remove LocalDeviceRec/Ptr definition.
    
    Two names pointing to the same struct for over 7 years now. Remove the
    define, if drivers don't want to change they can always do the typedef
    themselves.
    
    Rename all "LocalDevicePtr local" to "InputInfoPtr pInfo".
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index 8f5ca45..bdc4986 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -1193,7 +1193,7 @@ xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
 /* Print input driver messages in the standard format of
    <driver>: <device name>: <message> */
 void
-xf86VIDrvMsgVerb(LocalDevicePtr dev, MessageType type, int verb, const char *format,
+xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
 		 va_list args)
 {
     char *msg;
@@ -1205,7 +1205,7 @@ xf86VIDrvMsgVerb(LocalDevicePtr dev, MessageType type, int verb, const char *for
 
 /* Print input driver message, with verbose level specified directly */
 void
-xf86IDrvMsgVerb(LocalDevicePtr dev, MessageType type, int verb, const char *format,
+xf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
 	       ...)
 {
     va_list ap;
@@ -1217,7 +1217,7 @@ xf86IDrvMsgVerb(LocalDevicePtr dev, MessageType type, int verb, const char *form
 
 /* Print input driver messages, with verbose level of 1 (default) */
 void
-xf86IDrvMsg(LocalDevicePtr dev, MessageType type, const char *format, ...)
+xf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...)
 {
     va_list ap;
 
@@ -2050,7 +2050,7 @@ xf86IsUnblank(int mode)
 }
 
 void
-xf86MotionHistoryAllocate(LocalDevicePtr local)
+xf86MotionHistoryAllocate(InputInfoPtr pInfo)
 {
-    AllocateMotionHistory(local->dev);
+    AllocateMotionHistory(pInfo->dev);
 }
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 90f0b5d..002c2af 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -202,11 +202,11 @@ static void
 ApplyAccelerationSettings(DeviceIntPtr dev){
     int scheme, i;
     DeviceVelocityPtr pVel;
-    LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+    InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate;
     char* schemeStr;
 
     if (dev->valuator && dev->ptrfeed) {
-	schemeStr = xf86SetStrOption(local->options, "AccelerationScheme", "");
+	schemeStr = xf86SetStrOption(pInfo->options, "AccelerationScheme", "");
 
 	scheme = dev->valuator->accelScheme.number;
 
@@ -227,15 +227,15 @@ ApplyAccelerationSettings(DeviceIntPtr dev){
 
             if (InitPointerAccelerationScheme(dev, scheme)) {
 		xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
-		        local->name, schemeStr, scheme);
+		        pInfo->name, schemeStr, scheme);
 	    } else {
         	xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
-        	        local->name, schemeStr);
+		        pInfo->name, schemeStr);
         	scheme = dev->valuator->accelScheme.number;
             }
         } else {
             xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
-                    local->name, scheme);
+                    pInfo->name, scheme);
         }
 
         free(schemeStr);
@@ -244,31 +244,31 @@ ApplyAccelerationSettings(DeviceIntPtr dev){
         switch (scheme) {
             case PtrAccelPredictable:
                 pVel = GetDevicePredictableAccelData(dev);
-                ProcessVelocityConfiguration (dev, local->name, local->options,
+                ProcessVelocityConfiguration (dev, pInfo->name, pInfo->options,
                                               pVel);
                 break;
         }
 
-        i = xf86SetIntOption(local->options, "AccelerationNumerator",
+        i = xf86SetIntOption(pInfo->options, "AccelerationNumerator",
                              dev->ptrfeed->ctrl.num);
         if (i >= 0)
             dev->ptrfeed->ctrl.num = i;
 
-        i = xf86SetIntOption(local->options, "AccelerationDenominator",
+        i = xf86SetIntOption(pInfo->options, "AccelerationDenominator",
                              dev->ptrfeed->ctrl.den);
         if (i > 0)
             dev->ptrfeed->ctrl.den = i;
 
-        i = xf86SetIntOption(local->options, "AccelerationThreshold",
+        i = xf86SetIntOption(pInfo->options, "AccelerationThreshold",
                              dev->ptrfeed->ctrl.threshold);
         if (i >= 0)
             dev->ptrfeed->ctrl.threshold = i;
 
         xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
-                            local->name, ((float)dev->ptrfeed->ctrl.num)/
+                            pInfo->name, ((float)dev->ptrfeed->ctrl.num)/
                                          ((float)dev->ptrfeed->ctrl.den));
         xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
-                local->name, dev->ptrfeed->ctrl.threshold);
+                pInfo->name, dev->ptrfeed->ctrl.threshold);
     }
 }
 
@@ -281,21 +281,21 @@ ApplyAccelerationSettings(DeviceIntPtr dev){
  ***********************************************************************
  */
 void
-xf86ProcessCommonOptions(LocalDevicePtr local,
+xf86ProcessCommonOptions(InputInfoPtr pInfo,
                          pointer	list)
 {
     if (!xf86SetBoolOption(list, "AlwaysCore", 1) ||
         !xf86SetBoolOption(list, "SendCoreEvents", 1) ||
         !xf86SetBoolOption(list, "CorePointer", 1) ||
         !xf86SetBoolOption(list, "CoreKeyboard", 1)) {
-        xf86Msg(X_CONFIG, "%s: doesn't report core events\n", local->name);
+        xf86Msg(X_CONFIG, "%s: doesn't report core events\n", pInfo->name);
     } else {
-        local->flags |= XI86_ALWAYS_CORE;
-        xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name);
+        pInfo->flags |= XI86_ALWAYS_CORE;
+        xf86Msg(X_CONFIG, "%s: always reports core events\n", pInfo->name);
     }
 
     /* Backwards compatibility. */
-    local->history_size = GetMotionHistorySize();
+    pInfo->history_size = GetMotionHistorySize();
 }
 
 /***********************************************************************
@@ -308,34 +308,34 @@ xf86ProcessCommonOptions(LocalDevicePtr local,
  ***********************************************************************
  */
 static DeviceIntPtr
-xf86ActivateDevice(LocalDevicePtr local)
+xf86ActivateDevice(InputInfoPtr pInfo)
 {
     DeviceIntPtr	dev;
 
-    dev = AddInputDevice(serverClient, local->device_control, TRUE);
+    dev = AddInputDevice(serverClient, pInfo->device_control, TRUE);
 
     if (dev == NULL)
     {
         xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
-                local->name);
-        local->dev = NULL;
+                pInfo->name);
+        pInfo->dev = NULL;
         return NULL;
     }
 
-    local->atom = MakeAtom(local->type_name, strlen(local->type_name), TRUE);
-    AssignTypeAndName(dev, local->atom, local->name);
-    dev->public.devicePrivate = local;
-    local->dev = dev;
+    pInfo->atom = MakeAtom(pInfo->type_name, strlen(pInfo->type_name), TRUE);
+    AssignTypeAndName(dev, pInfo->atom, pInfo->name);
+    dev->public.devicePrivate = pInfo;
+    pInfo->dev = dev;
 
-    dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
+    dev->coreEvents = pInfo->flags & XI86_ALWAYS_CORE;
     dev->type = SLAVE;
     dev->spriteInfo->spriteOwner = FALSE;
 
-    dev->config_info = xf86SetStrOption(local->options, "config_info", NULL);
+    dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL);
 
     if (serverGeneration == 1)
         xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
-                local->name, local->type_name);
+                pInfo->name, pInfo->type_name);
 
     return dev;
 }
@@ -397,10 +397,10 @@ CloseInputDevice(DeviceIntPtr dev,
 int
 SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
 {
-  LocalDevicePtr        local = (LocalDevicePtr)dev->public.devicePrivate;
+  InputInfoPtr        pInfo = (InputInfoPtr)dev->public.devicePrivate;
 
-  if (local->switch_mode) {
-    return (*local->switch_mode)(client, dev, mode);
+  if (pInfo->switch_mode) {
+    return (*pInfo->switch_mode)(client, dev, mode);
   }
   else
     return BadMatch;
@@ -424,10 +424,10 @@ int
 SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
                     int first_valuator, int num_valuators)
 {
-    LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+    InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate;
 
-    if (local->set_device_valuators)
-	return (*local->set_device_valuators)(local, valuators, first_valuator,
+    if (pInfo->set_device_valuators)
+	return (*pInfo->set_device_valuators)(pInfo, valuators, first_valuator,
 					      num_valuators);
 
     return BadMatch;
@@ -446,9 +446,9 @@ SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
 int
 ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
 {
-  LocalDevicePtr        local = (LocalDevicePtr)dev->public.devicePrivate;
+  InputInfoPtr        pInfo = (InputInfoPtr)dev->public.devicePrivate;
 
-  if (!local->control_proc) {
+  if (!pInfo->control_proc) {
       switch (control->control) {
       case DEVICE_CORE:
           return BadMatch;
@@ -462,7 +462,7 @@ ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
       }
   }
   else {
-      return (*local->control_proc)(local, control);
+      return (*pInfo->control_proc)(pInfo, control);
   }
 }
 
@@ -992,7 +992,7 @@ unwind:
 void
 DeleteInputDeviceRequest(DeviceIntPtr pDev)
 {
-    LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate;
+    InputInfoPtr pInfo = (InputInfoPtr) pDev->public.devicePrivate;
     InputDriverPtr drv = NULL;
     IDevRec *idev = NULL;
     IDevPtr *it;
@@ -1282,7 +1282,7 @@ xf86PostKeyboardEvent(DeviceIntPtr      device,
     xf86PostKeyEventP(device, key_code, is_down, 0, 0, 0, NULL);
 }
 
-LocalDevicePtr
+InputInfoPtr
 xf86FirstLocalDevice(void)
 {
     return xf86InputDevs;
@@ -1335,14 +1335,14 @@ xf86ScaleAxis(int	Cx,
  * specific like a touch screen.
  */
 void
-xf86XInputSetScreen(LocalDevicePtr	local,
+xf86XInputSetScreen(InputInfoPtr	pInfo,
 		    int			screen_number,
 		    int			x,
 		    int			y)
 {
-    if (miPointerGetScreen(local->dev) !=
+    if (miPointerGetScreen(pInfo->dev) !=
           screenInfo.screens[screen_number]) {
-	miPointerSetScreen(local->dev, screen_number, x, y);
+	miPointerSetScreen(pInfo->dev, screen_number, x, y);
     }
 }
 
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 943e181..6f003cc 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -64,7 +64,7 @@
 #define XI86_SEND_CORE_EVENTS	XI86_ALWAYS_CORE
 
 #define XI_PRIVATE(dev) \
-	(((LocalDevicePtr)((dev)->public.devicePrivate))->private)
+	(((InputInfoPtr)((dev)->public.devicePrivate))->private)
 
 /* Valuator verification macro */
 #define XI_VERIFY_VALUATORS(num_valuators)					\
@@ -78,15 +78,17 @@
 #define TS_Raw 60
 #define TS_Scaled 61
 
+struct _InputInfoRec;
+
 /* This holds the input driver entry and module information. */
 typedef struct _InputDriverRec {
     int			    driverVersion;
     char *		    driverName;
     void		    (*Identify)(int flags);
     int			    (*PreInit)(struct _InputDriverRec *drv,
-				       struct _LocalDeviceRec* pInfo, int flags);
+				       struct _InputInfoRec* pInfo, int flags);
     void		    (*UnInit)(struct _InputDriverRec *drv,
-				      struct _LocalDeviceRec *pInfo,
+				      struct _InputInfoRec *pInfo,
 				      int flags);
     pointer		    module;
     int			    refCount;
@@ -95,27 +97,27 @@ typedef struct _InputDriverRec {
 
 /* This is to input devices what the ScrnInfoRec is to screens. */
 
-typedef struct _LocalDeviceRec {
-    struct _LocalDeviceRec *next;
+typedef struct _InputInfoRec {
+    struct _InputInfoRec *next;
     char *		    name;
     int			    flags;
 
     Bool		    (*device_control)(DeviceIntPtr device, int what);
-    void		    (*read_input)(struct _LocalDeviceRec *local);
-    int			    (*control_proc)(struct _LocalDeviceRec *local,
+    void		    (*read_input)(struct _InputInfoRec *local);
+    int			    (*control_proc)(struct _InputInfoRec *local,
 					   xDeviceCtl *control);
-    void		    (*close_proc)(struct _LocalDeviceRec *local);
+    void		    (*close_proc)(struct _InputInfoRec *local);
     int			    (*switch_mode)(ClientPtr client, DeviceIntPtr dev,
 					  int mode);
-    Bool		    (*conversion_proc)(struct _LocalDeviceRec *local,
+    Bool		    (*conversion_proc)(struct _InputInfoRec *local,
 					      int first, int num, int v0,
 					      int v1, int v2, int v3, int v4,
 					      int v5, int *x, int *y);
     Bool		    (*reverse_conversion_proc)(
-					struct _LocalDeviceRec *local,
+					struct _InputInfoRec *local,
 					int x, int y, int *valuators);
     int                     (*set_device_valuators)
-				(struct _LocalDeviceRec *local,
+				(struct _InputInfoRec *local,
 				 int *valuators, int first_valuator,
 				 int num_valuators);
 
@@ -136,12 +138,12 @@ typedef struct _LocalDeviceRec {
     pointer		    options;
     unsigned int            history_size;
     InputAttributes         *attrs;
-} LocalDeviceRec, *LocalDevicePtr, InputInfoRec, *InputInfoPtr;
+} InputInfoRec, *InputInfoPtr;
 
 typedef struct _DeviceAssocRec 
 {
     char *		    config_section_name;
-    LocalDevicePtr	    (*device_allocate)(void);
+    InputInfoPtr	    (*device_allocate)(void);
 } DeviceAssocRec, *DeviceAssocPtr;
 
 /* xf86Globals.c */
@@ -170,9 +172,9 @@ extern _X_EXPORT void xf86PostKeyEventP(DeviceIntPtr device, unsigned int key_co
 		       int *valuators);
 extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int key_code,
                            int is_down);
-extern _X_EXPORT LocalDevicePtr xf86FirstLocalDevice(void);
+extern _X_EXPORT InputInfoPtr xf86FirstLocalDevice(void);
 extern _X_EXPORT int xf86ScaleAxis(int Cx, int Sxhigh, int Sxlow, int Rxhigh, int Rxlow);
-extern _X_EXPORT void xf86XInputSetScreen(LocalDevicePtr local, int screen_number, int x, int y);
+extern _X_EXPORT void xf86XInputSetScreen(InputInfoPtr pInfo, int screen_number, int x, int y);
 extern _X_EXPORT void xf86ProcessCommonOptions(InputInfoPtr pInfo, pointer options);
 extern _X_EXPORT void xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval,
 				int maxval, int resolution, int min_res,
@@ -191,14 +193,14 @@ extern _X_EXPORT void xf86DeleteInputDriver(int drvIndex);
 extern _X_EXPORT InputDriverPtr xf86LookupInputDriver(const char *name);
 extern _X_EXPORT InputInfoPtr xf86LookupInput(const char *name);
 extern _X_EXPORT void xf86DeleteInput(InputInfoPtr pInp, int flags);
-extern _X_EXPORT void xf86MotionHistoryAllocate(LocalDevicePtr local);
-extern _X_EXPORT void xf86IDrvMsgVerb(LocalDevicePtr dev,
+extern _X_EXPORT void xf86MotionHistoryAllocate(InputInfoPtr pInfo);
+extern _X_EXPORT void xf86IDrvMsgVerb(InputInfoPtr dev,
 				      MessageType type, int verb,
 				      const char *format, ...) _X_ATTRIBUTE_PRINTF(4,5);
-extern _X_EXPORT void xf86IDrvMsg(LocalDevicePtr dev,
+extern _X_EXPORT void xf86IDrvMsg(InputInfoPtr dev,
 				  MessageType type,
 				  const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4);
-extern _X_EXPORT void xf86VIDrvMsgVerb(LocalDevicePtr dev,
+extern _X_EXPORT void xf86VIDrvMsgVerb(InputInfoPtr dev,
 				       MessageType type,
 				       int verb,
 				       const char *format,
commit 8764782f6de56a9dc5e9d5a8e9fb616a8ddb2f7c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Jun 7 11:17:10 2010 +1000

    xfree86: add xf86IDrvMsg and friends for input driver logging.
    
    Input driver messages are only standardised by convention, with the drivers
    prefixing the device name to most messages. This makes it rather hard to
    grep on "evdev" for example when looking for the evdev ouput.
    
    This patch adds three new logging functions, modeled after xf86DrvMsg(), the
    logging function for output drivers. New functions are
       xf86IDrvMsg()        - input driver log message in default verbosity.
       xf86IDrvMsgVerb()    - input driver log message in specified verbosity.
       xf86VIDrvMsgVerb()   - same as xf86IDrvMsgVerb() but takes a varargs
                              argument.
    
    Default log format is <driver name>: <device name>: <message>.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index 8eccb22..8f5ca45 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -1190,6 +1190,43 @@ xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
     va_end(ap);
 }
 
+/* Print input driver messages in the standard format of
+   <driver>: <device name>: <message> */
+void
+xf86VIDrvMsgVerb(LocalDevicePtr dev, MessageType type, int verb, const char *format,
+		 va_list args)
+{
+    char *msg;
+
+    msg = Xprintf("%s: %s: %s", dev->drv->driverName, dev->name, format);
+    LogVMessageVerb(type, verb, "%s", msg);
+    free(msg);
+}
+
+/* Print input driver message, with verbose level specified directly */
+void
+xf86IDrvMsgVerb(LocalDevicePtr dev, MessageType type, int verb, const char *format,
+	       ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    xf86VIDrvMsgVerb(dev, type, verb, format, ap);
+    va_end(ap);
+}
+
+/* Print input driver messages, with verbose level of 1 (default) */
+void
+xf86IDrvMsg(LocalDevicePtr dev, MessageType type, const char *format, ...)
+{
+    va_list ap;
+
+    va_start(ap, format);
+    xf86VIDrvMsgVerb(dev, type, 1, format, ap);
+    va_end(ap);
+}
+
+
 /* Print non-driver messages with verbose level specified directly */
 void
 xf86MsgVerb(MessageType type, int verb, const char *format, ...)
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 4851f8b..943e181 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -192,6 +192,17 @@ extern _X_EXPORT InputDriverPtr xf86LookupInputDriver(const char *name);
 extern _X_EXPORT InputInfoPtr xf86LookupInput(const char *name);
 extern _X_EXPORT void xf86DeleteInput(InputInfoPtr pInp, int flags);
 extern _X_EXPORT void xf86MotionHistoryAllocate(LocalDevicePtr local);
+extern _X_EXPORT void xf86IDrvMsgVerb(LocalDevicePtr dev,
+				      MessageType type, int verb,
+				      const char *format, ...) _X_ATTRIBUTE_PRINTF(4,5);
+extern _X_EXPORT void xf86IDrvMsg(LocalDevicePtr dev,
+				  MessageType type,
+				  const char *format, ...) _X_ATTRIBUTE_PRINTF(3,4);
+extern _X_EXPORT void xf86VIDrvMsgVerb(LocalDevicePtr dev,
+				       MessageType type,
+				       int verb,
+				       const char *format,
+				       va_list args);
 
 /* xf86Option.c */
 extern _X_EXPORT void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
commit b55ac354afa0f16f71bb4f2d3d4277c887082520
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 12:00:07 2010 +1000

    xfree86: move xf86AllocateInput and xf86DeleteInput to xf86Xinput.c
    
    Make xf86AllocateInput static in the process, this function is only called
    from one location.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index 897aaf3..8eccb22 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -274,96 +274,6 @@ xf86AllocateScrnInfoPrivateIndex(void)
     return idx;
 }
 
-/* Allocate a new InputInfoRec and append it to the tail of xf86InputDevs. */
-InputInfoPtr
-xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
-{
-    InputInfoPtr new, *prev = NULL;
-
-    if (!(new = calloc(sizeof(InputInfoRec), 1)))
-	return NULL;
-
-    new->drv = drv;
-    drv->refCount++;
-    new->module = DuplicateModule(drv->module, NULL);
-
-    for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
-        ;
-
-    *prev = new;
-    new->next = NULL;
-
-    new->fd = -1;
-    new->name = idev->identifier;
-    new->type_name = "UNKNOWN";
-    new->device_control = NULL;
-    new->read_input = NULL;
-    new->history_size = 0;
-    new->control_proc = NULL;
-    new->close_proc = NULL;
-    new->switch_mode = NULL;
-    new->conversion_proc = NULL;
-    new->reverse_conversion_proc = NULL;
-    new->dev = NULL;
-    new->private_flags = 0;
-    new->always_core_feedback = NULL;
-    new->private = NULL;
-    new->conf_idev = idev;
-
-    xf86CollectInputOptions(new, (const char**)drv->default_options, NULL);
-    xf86ProcessCommonOptions(new, new->options);
-
-    return new;
-}
-
-
-/*
- * Remove an entry from xf86InputDevs.  Ideally it should free all allocated
- * data.  To do this properly may require a driver hook.
- */
-
-void
-xf86DeleteInput(InputInfoPtr pInp, int flags)
-{
-    InputInfoPtr p;
-
-    /* First check if the inputdev is valid. */
-    if (pInp == NULL)
-	return;
-
-#if 0
-    /* If a free function is defined, call it here. */
-    if (pInp->free)
-	pInp->free(pInp, 0);
-#endif
-
-    if (pInp->module)
-	UnloadModule(pInp->module);
-
-    if (pInp->drv)
-	pInp->drv->refCount--;
-
-    /* This should *really* be handled in drv->UnInit(dev) call instead, but
-     * if the driver forgets about it make sure we free it or at least crash
-     * with flying colors */
-    free(pInp->private);
-
-    FreeInputAttributes(pInp->attrs);
-
-    /* Remove the entry from the list. */
-    if (pInp == xf86InputDevs)
-	xf86InputDevs = pInp->next;
-    else {
-	p = xf86InputDevs;
-	while (p && p->next != pInp)
-	    p = p->next;
-	if (p)
-	    p->next = pInp->next;
-	/* Else the entry wasn't in the xf86InputDevs list (ignore this). */
-    }
-    free(pInp);
-}
-
 Bool
 xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
 {
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 4513b99..90f0b5d 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -705,6 +705,95 @@ IgnoreInputClass(const IDevPtr idev, const InputAttributes *attrs)
     return ignore;
 }
 
+/* Allocate a new InputInfoRec and append it to the tail of xf86InputDevs. */
+static InputInfoPtr
+xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
+{
+    InputInfoPtr new, *prev = NULL;
+
+    if (!(new = calloc(sizeof(InputInfoRec), 1)))
+	return NULL;
+
+    new->drv = drv;
+    drv->refCount++;
+    new->module = DuplicateModule(drv->module, NULL);
+
+    for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
+        ;
+
+    *prev = new;
+    new->next = NULL;
+
+    new->fd = -1;
+    new->name = idev->identifier;
+    new->type_name = "UNKNOWN";
+    new->device_control = NULL;
+    new->read_input = NULL;
+    new->history_size = 0;
+    new->control_proc = NULL;
+    new->close_proc = NULL;
+    new->switch_mode = NULL;
+    new->conversion_proc = NULL;
+    new->reverse_conversion_proc = NULL;
+    new->dev = NULL;
+    new->private_flags = 0;
+    new->always_core_feedback = NULL;
+    new->private = NULL;
+    new->conf_idev = idev;
+
+    xf86CollectInputOptions(new, (const char**)drv->default_options, NULL);
+    xf86ProcessCommonOptions(new, new->options);
+
+    return new;
+}
+
+/*
+ * Remove an entry from xf86InputDevs.  Ideally it should free all allocated
+ * data.  To do this properly may require a driver hook.
+ */
+
+void
+xf86DeleteInput(InputInfoPtr pInp, int flags)
+{
+    InputInfoPtr p;
+
+    /* First check if the inputdev is valid. */
+    if (pInp == NULL)
+	return;
+
+#if 0
+    /* If a free function is defined, call it here. */
+    if (pInp->free)
+	pInp->free(pInp, 0);
+#endif
+
+    if (pInp->module)
+	UnloadModule(pInp->module);
+
+    if (pInp->drv)
+	pInp->drv->refCount--;
+
+    /* This should *really* be handled in drv->UnInit(dev) call instead, but
+     * if the driver forgets about it make sure we free it or at least crash
+     * with flying colors */
+    free(pInp->private);
+
+    FreeInputAttributes(pInp->attrs);
+
+    /* Remove the entry from the list. */
+    if (pInp == xf86InputDevs)
+	xf86InputDevs = pInp->next;
+    else {
+	p = xf86InputDevs;
+	while (p && p->next != pInp)
+	    p = p->next;
+	if (p)
+	    p->next = pInp->next;
+	/* Else the entry wasn't in the xf86InputDevs list (ignore this). */
+    }
+    free(pInp);
+}
+
 /**
  * Create a new input device, activate and enable it.
  *
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 8ca912e..4851f8b 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -188,7 +188,6 @@ int xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL is_auto);
 /* xf86Helper.c */
 extern _X_EXPORT void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags);
 extern _X_EXPORT void xf86DeleteInputDriver(int drvIndex);
-extern _X_INTERNAL InputInfoPtr xf86AllocateInput(InputDriverPtr drv, IDevPtr idev);
 extern _X_EXPORT InputDriverPtr xf86LookupInputDriver(const char *name);
 extern _X_EXPORT InputInfoPtr xf86LookupInput(const char *name);
 extern _X_EXPORT void xf86DeleteInput(InputInfoPtr pInp, int flags);
commit d2a5f4166417b9d4a02a219b28470e41b6cfe012
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 10:30:56 2010 +1000

    xfree86: return the device from xf86ActivateDevice.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index c0b216a..4513b99 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -307,7 +307,7 @@ xf86ProcessCommonOptions(LocalDevicePtr local,
  * Returns TRUE on success, or FALSE otherwise.
  ***********************************************************************
  */
-static int
+static DeviceIntPtr
 xf86ActivateDevice(LocalDevicePtr local)
 {
     DeviceIntPtr	dev;
@@ -319,7 +319,7 @@ xf86ActivateDevice(LocalDevicePtr local)
         xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
                 local->name);
         local->dev = NULL;
-        return FALSE;
+        return NULL;
     }
 
     local->atom = MakeAtom(local->type_name, strlen(local->type_name), TRUE);
@@ -337,7 +337,7 @@ xf86ActivateDevice(LocalDevicePtr local)
         xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
                 local->name, local->type_name);
 
-    return TRUE;
+    return dev;
 }
 
 
@@ -760,13 +760,12 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
         goto unwind;
     }
 
-    if (!xf86ActivateDevice(pInfo))
+    if (!(dev = xf86ActivateDevice(pInfo)))
     {
         rval = BadAlloc;
         goto unwind;
     }
 
-    dev = pInfo->dev;
     rval = ActivateDevice(dev, TRUE);
     if (rval != Success)
     {
commit fbf35e27f3005cf009f2dd1e112260bb294342c7
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 10:28:14 2010 +1000

    input: set XKB extension for all new devices, not just xfree86 ones.
    
    Right now, Xephyr and others don't get to use XKB on the slave devices.
    Which works given that no-one cares about SDs just yet but event processing
    is different if the ProcessInputProc isn't wrapped properly.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/dix/devices.c b/dix/devices.c
index 0f00f24..6a934cf 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -272,6 +272,7 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
     dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
     dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
 
+    XkbSetExtension(dev, ProcessKeyboardEvent);
 
     dev->coreEvents = TRUE;
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 9ede70f..c0b216a 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -333,8 +333,6 @@ xf86ActivateDevice(LocalDevicePtr local)
 
     dev->config_info = xf86SetStrOption(local->options, "config_info", NULL);
 
-    XkbSetExtension(dev, ProcessKeyboardEvent);
-
     if (serverGeneration == 1)
         xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
                 local->name, local->type_name);
commit 11ed32b62c8793ecc1c68e1e4ba91e2eb45eef3e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 10:24:02 2010 +1000

    xfree86: purge SendDragEvents support.
    
    From the documentation:
    "This is mainly to allow a touch screen to be used with netscape and other
    browsers which do strange things if the mouse moves between button down and
    button up."
    
    CLOSED - NOTOURBUG
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index c30efb8..9ede70f 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -272,17 +272,6 @@ ApplyAccelerationSettings(DeviceIntPtr dev){
     }
 }
 
-static Bool
-xf86SendDragEvents(DeviceIntPtr	device)
-{
-    LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate;
-    
-    if (device->button && device->button->buttonsDown > 0)
-        return local->flags & XI86_SEND_DRAG_EVENTS;
-    else
-        return TRUE;
-}
-
 /***********************************************************************
  *
  * xf86ProcessCommonOptions --
@@ -305,12 +294,6 @@ xf86ProcessCommonOptions(LocalDevicePtr local,
         xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name);
     }
 
-    if (xf86SetBoolOption(list, "SendDragEvents", 1)) {
-        local->flags |= XI86_SEND_DRAG_EVENTS;
-    } else {
-        xf86Msg(X_CONFIG, "%s: doesn't report drag events\n", local->name);
-    }
-
     /* Backwards compatibility. */
     local->history_size = GetMotionHistorySize();
 }
@@ -994,7 +977,6 @@ xf86PostMotionEventP(DeviceIntPtr	device,
                     int			*valuators)
 {
     int i = 0, nevents = 0;
-    Bool drag = xf86SendDragEvents(device);
     DeviceEvent *event;
     int flags = 0;
 
@@ -1041,12 +1023,7 @@ xf86PostMotionEventP(DeviceIntPtr	device,
 
     for (i = 0; i < nevents; i++) {
         event = (DeviceEvent*)((xf86Events + i)->event);
-        /* Don't post core motion events for devices not registered to send
-         * drag events. */
-        if (event->header == ET_Internal &&
-            (event->type != ET_Motion || drag)) {
-            mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-        }
+        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
     }
 }
 
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 7528a51..8ca912e 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -62,14 +62,6 @@
 #define XI86_ALWAYS_CORE	0x04 /* device always controls the pointer */
 /* the device sends Xinput and core pointer events */
 #define XI86_SEND_CORE_EVENTS	XI86_ALWAYS_CORE
-/* if the device is the core pointer or is sending core events, and
- * SEND_DRAG_EVENTS is false, and a buttons is done, then no motion events
- * (mouse drag action) are sent. This is mainly to allow a touch screen to be
- * used with netscape and other browsers which do strange things if the mouse
- * moves between button down and button up. With a touch screen, this motion
- * is common due to the user's finger moving slightly.
- */
-#define XI86_SEND_DRAG_EVENTS	0x08
 
 #define XI_PRIVATE(dev) \
 	(((LocalDevicePtr)((dev)->public.devicePrivate))->private)
diff --git a/hw/xfree86/doc/devel/Registry b/hw/xfree86/doc/devel/Registry
index 1fec230..e09228b 100644
--- a/hw/xfree86/doc/devel/Registry
+++ b/hw/xfree86/doc/devel/Registry
@@ -253,7 +253,6 @@ ReportDelay               I     I    ??
 ReportingMode             S     I    may be "raw" or "scaled"
 ScreenNumber              I     I    Screen number (for touch screen)
 SendCoreEvents            B     I    Send core events
-SendDragEvents            B     I    Send drag events
 StopBits                  I     I    Serial port stop bits
 SwapXY                    B     I    Swap the X and Y axes
 UntouchDelay              I     I    ??
diff --git a/hw/xfree86/doc/man/xorg.conf.man.pre b/hw/xfree86/doc/man/xorg.conf.man.pre
index 6b3636f..7c7a101 100644
--- a/hw/xfree86/doc/man/xorg.conf.man.pre
+++ b/hw/xfree86/doc/man/xorg.conf.man.pre
@@ -944,9 +944,6 @@ default. Devices with
 disabled will be \*qfloating\*q and only accessible by clients employing the
 X Input extension. This option controls the startup behavior only, a device
 may be reattached or set floating at runtime.
-.TP 7
-.BI "Option \*qSendDragEvents\*q  \*q" boolean \*q
-Send core events while dragging. Enabled by default.
 .PP
 For pointing devices, the following options control how the pointer
 is accelerated or decelerated with respect to physical device motion. Most of
commit 7defd282beb57e8880980416ed579f62d561d1ac
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 10:16:15 2010 +1000

    xfree86: remove XI86_CONFIGURED flag.
    
    PreInit returns a status code. Let's use that instead of having it report
    Success in some cases but not set the XI86_CONFIGURED flag and thus signal
    an init failure.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 0428673..c30efb8 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -329,36 +329,32 @@ xf86ActivateDevice(LocalDevicePtr local)
 {
     DeviceIntPtr	dev;
 
-    if (local->flags & XI86_CONFIGURED) {
-        dev = AddInputDevice(serverClient, local->device_control, TRUE);
+    dev = AddInputDevice(serverClient, local->device_control, TRUE);
 
-        if (dev == NULL)
-        {
-            xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
-                    local->name);
-            local->dev = NULL;
-            return FALSE;
-        }
+    if (dev == NULL)
+    {
+        xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
+                local->name);
+        local->dev = NULL;
+        return FALSE;
+    }
 
-        local->atom = MakeAtom(local->type_name,
-                               strlen(local->type_name),
-                               TRUE);
-        AssignTypeAndName(dev, local->atom, local->name);
-        dev->public.devicePrivate = (pointer) local;
-        local->dev = dev;      
-        
-        dev->coreEvents = local->flags & XI86_ALWAYS_CORE; 
-        dev->type = SLAVE;
-        dev->spriteInfo->spriteOwner = FALSE;
+    local->atom = MakeAtom(local->type_name, strlen(local->type_name), TRUE);
+    AssignTypeAndName(dev, local->atom, local->name);
+    dev->public.devicePrivate = local;
+    local->dev = dev;
 
-        dev->config_info = xf86SetStrOption(local->options, "config_info", NULL);
+    dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
+    dev->type = SLAVE;
+    dev->spriteInfo->spriteOwner = FALSE;
 
-        XkbSetExtension(dev, ProcessKeyboardEvent);
+    dev->config_info = xf86SetStrOption(local->options, "config_info", NULL);
 
-        if (serverGeneration == 1) 
-            xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
-                    local->name, local->type_name);
-    }
+    XkbSetExtension(dev, ProcessKeyboardEvent);
+
+    if (serverGeneration == 1)
+        xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
+                local->name, local->type_name);
 
     return TRUE;
 }
@@ -782,12 +778,6 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
         xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, idev->identifier);
         goto unwind;
     }
-    else if (!(pInfo->flags & XI86_CONFIGURED)) {
-        xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n",
-                idev->identifier);
-        rval = BadMatch;
-        goto unwind;
-    }
 
     if (!xf86ActivateDevice(pInfo))
     {
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 1b71c64..7528a51 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -59,7 +59,6 @@
 #include "XIstubs.h"
 
 /* Input device flags */
-#define XI86_CONFIGURED         0x02 /* the device has been configured */
 #define XI86_ALWAYS_CORE	0x04 /* device always controls the pointer */
 /* the device sends Xinput and core pointer events */
 #define XI86_SEND_CORE_EVENTS	XI86_ALWAYS_CORE
commit 97a4acdac23b8ff33da43917c10b65d2fee5c07f
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 10:04:53 2010 +1000

    xfree86: purge some unused defines.
    
    These defines have been write-only for a while now.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 3c1a147..1b71c64 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -59,7 +59,6 @@
 #include "XIstubs.h"
 
 /* Input device flags */
-#define XI86_OPEN_ON_INIT       0x01 /* open the device at startup time */
 #define XI86_CONFIGURED         0x02 /* the device has been configured */
 #define XI86_ALWAYS_CORE	0x04 /* device always controls the pointer */
 /* the device sends Xinput and core pointer events */
@@ -72,10 +71,6 @@
  * is common due to the user's finger moving slightly.
  */
 #define XI86_SEND_DRAG_EVENTS	0x08
-#define XI86_CORE_POINTER	0x10 /* device is the core pointer */
-#define XI86_CORE_KEYBOARD	0x20 /* device is the core keyboard */
-#define XI86_POINTER_CAPABLE	0x40 /* capable of being a core pointer */
-#define XI86_KEYBOARD_CAPABLE	0x80 /* capable of being a core keyboard */
 
 #define XI_PRIVATE(dev) \
 	(((LocalDevicePtr)((dev)->public.devicePrivate))->private)
commit 0fb7a5c261aa0d87d6596d72b70696bffe0c0aff
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 09:53:35 2010 +1000

    input: Purge Register*Device() functions.
    
    RegisterPointerDevice() and RegisterKeyboardDevice() were already mapped to
    RegisterOtherDevice() and obsolete.
    
    RegisterOtherDevice() was called for all devices and the two assignments can
    simply be moved into AddInputDevice(). Purge RegisterOtherDevice() and
    pretend it never happened.
    
    *lalalalala*
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index e19e207..9689ef8 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -111,13 +111,6 @@ XIShouldNotify(ClientPtr client, DeviceIntPtr dev)
     return 0;
 }
 
-void
-RegisterOtherDevice(DeviceIntPtr device)
-{
-    device->public.processInputProc = ProcessOtherEvent;
-    device->public.realInputProc = ProcessOtherEvent;
-}
-
 Bool
 IsPointerEvent(InternalEvent* event)
 {
diff --git a/Xi/stubs.c b/Xi/stubs.c
index 296a8c4..de80042 100644
--- a/Xi/stubs.c
+++ b/Xi/stubs.c
@@ -122,7 +122,6 @@ AddOtherInputDevices(void)
 
     dev = (DeviceIntPtr) AddInputDevice(deviceProc, TRUE);
     dev->public.devicePrivate = private;
-    RegisterOtherDevice(dev);
     dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
     ************************************************************************/
 
diff --git a/dix/devices.c b/dix/devices.c
index 2e65a04..0f00f24 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -261,8 +261,8 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
     if (!dev)
 	return (DeviceIntPtr)NULL;
     dev->id = devid;
-    dev->public.processInputProc = (ProcessInputProc)NoopDDA;
-    dev->public.realInputProc = (ProcessInputProc)NoopDDA;
+    dev->public.processInputProc = ProcessOtherEvent;
+    dev->public.realInputProc = ProcessOtherEvent;
     dev->public.enqueueInputProc = EnqueueEvent;
     dev->deviceProc = deviceProc;
     dev->startup = autoStart;
@@ -272,6 +272,7 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
     dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
     dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
 
+
     dev->coreEvents = TRUE;
 
     /* sprite defaults */
@@ -1106,18 +1107,6 @@ NumMotionEvents(void)
     return inputInfo.pointer->valuator->numMotionEvents;
 }
 
-void
-RegisterPointerDevice(DeviceIntPtr device)
-{
-    RegisterOtherDevice(device);
-}
-
-void
-RegisterKeyboardDevice(DeviceIntPtr device)
-{
-    RegisterOtherDevice(device);
-}
-
 int
 dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode)
 {
diff --git a/doc/xml/Xserver-spec.xml b/doc/xml/Xserver-spec.xml
index 563705f..ec7f1b7 100644
--- a/doc/xml/Xserver-spec.xml
+++ b/doc/xml/Xserver-spec.xml
@@ -1710,8 +1710,6 @@ Input initialization is a bit complicated.
 It all starts with InitInput(), a routine that you write to call
 AddInputDevice() twice
 (once for pointing device and once for keyboard.)
-You also want to call RegisterKeyboardDevice() and RegisterPointerDevice()
-on them.
 </para>
 <para>
 When you Add the devices, a routine you supply for each device
@@ -1731,8 +1729,6 @@ the pointer is the pointer.
 InitInput is a DDX routine you must write to initialize the
 input subsystem in DDX.
 It must call AddInputDevice() for each device that might generate events.
-In addition, you must register the main keyboard and pointing devices by
-calling RegisterPointerDevice() and RegisterKeyboardDevice().
 </para>
 <para>
 <blockquote><programlisting>
@@ -1755,25 +1751,6 @@ Note also that except for the main keyboard and pointing device,
 an extension is needed to provide for a client interface to a device.
 </para>
 <para>
-<blockquote><programlisting>
-
-	void RegisterPointerDevice(device)
-		DevicePtr device;
-</programlisting></blockquote>
-RegisterPointerDevice is a DIX routine that your DDX code calls that
-makes that device the main pointing device.
-This routine is called once upon initialization and cannot be called again.
-</para>
-<para>
-<blockquote><programlisting>
-
-	void RegisterKeyboardDevice(device)
-		DevicePtr device;
-</programlisting></blockquote>
-RegisterKeyboardDevice makes the given device the main keyboard.
-This routine is called once upon initialization and cannot be called again.
-</para>
-<para>
 The following DIX
 procedures return the specified DevicePtr. They may or may not be useful
 to DDX implementors.
@@ -5163,8 +5140,6 @@ mi and fb implementations.</para>
 	      </row>
 	    </thead>
 	    <tbody>
-<row><entry><function>RegisterKeyboardDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
-<row><entry><function>RegisterPointerDevice</function></entry><entry><literal>dix</literal></entry><entry><para></para></entry></row>
 <row><entry><function>RemoveEnabledDevice</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
 <row><entry><function>ResetCurrentRequest</function></entry><entry><literal>os</literal></entry><entry><para></para></entry></row>
 <row><entry><function>SaveScreen</function></entry><entry><literal>ddx</literal></entry><entry><para>Screen</para></entry></row>
diff --git a/hw/dmx/doc/dmx.xml b/hw/dmx/doc/dmx.xml
index c6dc0cc..8dbb7d8 100644
--- a/hw/dmx/doc/dmx.xml
+++ b/hw/dmx/doc/dmx.xml
@@ -817,22 +817,10 @@ is called once for each input device.
 </para>
 
 <para>Once input handles for core keyboard and core pointer devices have
-been obtained from AddInputDevice(), they are registered as core devices
-by calling RegisterPointerDevice() and RegisterKeyboardDevice().  Each
-of these should be called once.  If both core devices are not
+been obtained from AddInputDevice().  If both core devices are not
 registered, then the X server will exit with a fatal error when it
 attempts to start the input devices in InitAndStartDevices(), which is
 called directly after InitInput() (see below).
-
-<variablelist>
-<varlistentry>
-<term>Register{Pointer,Keyboard}Device()</term>
-<listitem><para>These DIX functions take a
-handle returned from AddInputDevice() and initialize the core input
-device fields in inputInfo, and initialize the input processing and grab
-functions for each core input device.
-</para></listitem></varlistentry>
-</variablelist>
 </para>
 
 <para>The core pointer device is then registered with the miPointer code
diff --git a/hw/dmx/input/dmxinputinit.c b/hw/dmx/input/dmxinputinit.c
index 83a2abb..829a289 100644
--- a/hw/dmx/input/dmxinputinit.c
+++ b/hw/dmx/input/dmxinputinit.c
@@ -693,7 +693,6 @@ static DeviceIntPtr dmxAddDevice(DMXLocalInputInfoPtr dmxLocal)
     DeviceIntPtr pDevice;
     Atom         atom;
     const char   *name = NULL;
-    void         (*registerProcPtr)(DeviceIntPtr)   = NULL;
     char         *devname;
     DMXInputInfo *dmxInput;
 
@@ -706,22 +705,19 @@ static DeviceIntPtr dmxAddDevice(DMXLocalInputInfoPtr dmxLocal)
             dmxLocal->isCore     = 1;
             dmxLocalCoreKeyboard = dmxLocal;
             name                 = "keyboard";
-            registerProcPtr      = RegisterKeyboardDevice;
         }
         if (dmxLocal->type == DMX_LOCAL_MOUSE && !dmxLocalCorePointer) {
             dmxLocal->isCore     = 1;
             dmxLocalCorePointer  = dmxLocal;
             name                 = "pointer";
-            registerProcPtr      = RegisterPointerDevice;
         }
     }
 
     if (!name) {
         name            = "extension";
-        registerProcPtr = RegisterOtherDevice;
     }
 
-    if (!name || !registerProcPtr)
+    if (!name)
         dmxLog(dmxFatal, "Cannot add device %s\n", dmxLocal->name);
 
     pDevice                       = AddInputDevice(serverClient, dmxDeviceOnOff, TRUE);
@@ -738,8 +734,6 @@ static DeviceIntPtr dmxAddDevice(DMXLocalInputInfoPtr dmxLocal)
     pDevice->type = atom;
     pDevice->name = devname;
 
-    registerProcPtr(pDevice);
-
     if (dmxLocal->isCore && dmxLocal->type == DMX_LOCAL_MOUSE) {
 #if 00 /*BP*/
         miRegisterPointerDevice(screenInfo.screens[0], pDevice);
diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index fcb02b5..a4691df 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -943,8 +943,6 @@ KdAddKeyboard (KdKeyboardInfo *ki)
         return !Success;
     }
 
-    RegisterOtherDevice(ki->dixdev);
-
 #ifdef DEBUG
     ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id);
 #endif
@@ -1012,8 +1010,6 @@ KdAddPointer (KdPointerInfo *pi)
         return BadDevice;
     }
 
-    RegisterOtherDevice(pi->dixdev);
-
     for (prev = &kdPointers; *prev; prev = &(*prev)->next);
     *prev = pi;
 
diff --git a/hw/vfb/InitInput.c b/hw/vfb/InitInput.c
index 801aaa0..60b59c1 100644
--- a/hw/vfb/InitInput.c
+++ b/hw/vfb/InitInput.c
@@ -138,10 +138,8 @@ InitInput(int argc, char *argv[])
     Atom xiclass;
     p = AddInputDevice(serverClient, vfbMouseProc, TRUE);
     k = AddInputDevice(serverClient, vfbKeybdProc, TRUE);
-    RegisterPointerDevice(p);
     xiclass = MakeAtom(XI_MOUSE, sizeof(XI_MOUSE) - 1, TRUE);
     AssignTypeAndName(p, xiclass, "Xvfb mouse");
-    RegisterKeyboardDevice(k);
     xiclass = MakeAtom(XI_KEYBOARD, sizeof(XI_KEYBOARD) - 1, TRUE);
     AssignTypeAndName(k, xiclass, "Xvfb keyboard");
     (void)mieqInit();
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index f773ac2..0428673 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -353,7 +353,6 @@ xf86ActivateDevice(LocalDevicePtr local)
 
         dev->config_info = xf86SetStrOption(local->options, "config_info", NULL);
 
-        RegisterOtherDevice(dev);
         XkbSetExtension(dev, ProcessKeyboardEvent);
 
         if (serverGeneration == 1) 
diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c
index a99c0f1..2362fac 100644
--- a/hw/xquartz/darwin.c
+++ b/hw/xquartz/darwin.c
@@ -468,7 +468,6 @@ void InitInput( int argc, char **argv )
     XkbSetRulesDflts(&rmlvo);
 
     darwinKeyboard = AddInputDevice(serverClient, DarwinKeybdProc, TRUE);
-    RegisterKeyboardDevice( darwinKeyboard );
     darwinKeyboard->name = strdup("keyboard");
 
     /* here's the snippet from the current gdk sources:
@@ -486,19 +485,15 @@ void InitInput( int argc, char **argv )
     */
 
     darwinPointer = AddInputDevice(serverClient, DarwinMouseProc, TRUE);
-    RegisterPointerDevice( darwinPointer );
     darwinPointer->name = strdup("pointer");
 
     darwinTabletStylus = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
-    RegisterPointerDevice( darwinTabletStylus );
     darwinTabletStylus->name = strdup("pen");
 
     darwinTabletCursor = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
-    RegisterPointerDevice( darwinTabletCursor );
     darwinTabletCursor->name = strdup("cursor");
 
     darwinTabletEraser = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
-    RegisterPointerDevice( darwinTabletEraser );
     darwinTabletEraser->name = strdup("eraser");
 
     darwinTabletCurrent = darwinTabletStylus;
diff --git a/hw/xquartz/darwinXinput.c b/hw/xquartz/darwinXinput.c
index 19aefb1..966aaf3 100644
--- a/hw/xquartz/darwinXinput.c
+++ b/hw/xquartz/darwinXinput.c
@@ -120,7 +120,6 @@ AddOtherInputDevices(void)
 
     dev = (DeviceIntPtr) AddInputDevice(deviceProc, TRUE);
     dev->public.devicePrivate = private;
-    RegisterOtherDevice(dev);
     dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success);
     ************************************************************************/
   DEBUG_LOG("AddOtherInputDevices\n");
diff --git a/hw/xwin/InitInput.c b/hw/xwin/InitInput.c
index 705e618..563adb6 100644
--- a/hw/xwin/InitInput.c
+++ b/hw/xwin/InitInput.c
@@ -137,10 +137,6 @@ InitInput (int argc, char *argv[])
 
   g_pwinPointer = AddInputDevice (serverClient, winMouseProc, TRUE);
   g_pwinKeyboard = AddInputDevice (serverClient, winKeybdProc, TRUE);
-  
-  RegisterPointerDevice (g_pwinPointer);
-  RegisterKeyboardDevice (g_pwinKeyboard);
-
   g_pwinPointer->name = strdup("Windows mouse");
   g_pwinKeyboard->name = strdup("Windows keyboard");
 
diff --git a/include/exevents.h b/include/exevents.h
index 39e1c70..b64252f 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -146,10 +146,6 @@ typedef struct _GrabParameters {
 } GrabParameters;
 
 
-extern void
-RegisterOtherDevice (
-	DeviceIntPtr           /* device */);
-
 extern int
 UpdateDeviceState (
 	DeviceIntPtr           /* device */,
diff --git a/include/input.h b/include/input.h
index ffb1c33..388ef21 100644
--- a/include/input.h
+++ b/include/input.h
@@ -274,12 +274,6 @@ extern _X_EXPORT int RemoveDevice(
 
 extern _X_EXPORT int NumMotionEvents(void);
 
-extern void RegisterPointerDevice(
-    DeviceIntPtr /*device*/);
-
-extern void RegisterKeyboardDevice(
-    DeviceIntPtr /*device*/);
-
 extern _X_EXPORT int dixLookupDevice(
     DeviceIntPtr *         /* dev */,
     int                    /* id */,
commit 67ffbcc14cbc61474520d4531599edca24965543
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 09:24:08 2010 +1000

    xfree86: remove superflous assignments.
    
    ActivateGrab and DeactivateGrab are set in AddInputDevice() already.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c
index 80a1458..fcb02b5 100644
--- a/hw/kdrive/src/kinput.c
+++ b/hw/kdrive/src/kinput.c
@@ -943,8 +943,6 @@ KdAddKeyboard (KdKeyboardInfo *ki)
         return !Success;
     }
 
-    ki->dixdev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
-    ki->dixdev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
     RegisterOtherDevice(ki->dixdev);
 
 #ifdef DEBUG
@@ -1014,8 +1012,6 @@ KdAddPointer (KdPointerInfo *pi)
         return BadDevice;
     }
 
-    pi->dixdev->deviceGrab.ActivateGrab = ActivatePointerGrab;
-    pi->dixdev->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
     RegisterOtherDevice(pi->dixdev);
 
     for (prev = &kdPointers; *prev; prev = &(*prev)->next);
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index dcfbcde..f773ac2 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -351,8 +351,6 @@ xf86ActivateDevice(LocalDevicePtr local)
         dev->type = SLAVE;
         dev->spriteInfo->spriteOwner = FALSE;
 
-        dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
-        dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
         dev->config_info = xf86SetStrOption(local->options, "config_info", NULL);
 
         RegisterOtherDevice(dev);
commit 4cd54d9ed9e87074734789a9a7708c2218f87f1e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 09:22:05 2010 +1000

    xfree86: make xf86ActivateDevice static.
    
    No-one but the joystick driver uses it and that one should be using NIDR
    instead.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86InPriv.h b/hw/xfree86/common/xf86InPriv.h
index 3838d69..1b9b502 100644
--- a/hw/xfree86/common/xf86InPriv.h
+++ b/hw/xfree86/common/xf86InPriv.h
@@ -37,9 +37,6 @@
 extern InputDriverPtr *xf86InputDriverList;
 extern int xf86NumInputDrivers;
 
-/* xf86Xinput.c */
-int xf86ActivateDevice(InputInfoPtr pInfo);
-
 /* xf86Helper.c */
 InputDriverPtr xf86LookupInputDriver(const char *name);
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 8fd35e6..dcfbcde 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -324,7 +324,7 @@ xf86ProcessCommonOptions(LocalDevicePtr local,
  * Returns TRUE on success, or FALSE otherwise.
  ***********************************************************************
  */
-int
+static int
 xf86ActivateDevice(LocalDevicePtr local)
 {
     DeviceIntPtr	dev;
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 6789df6..3c1a147 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -184,7 +184,6 @@ extern _X_EXPORT void xf86PostKeyEventP(DeviceIntPtr device, unsigned int key_co
 		       int *valuators);
 extern _X_EXPORT void xf86PostKeyboardEvent(DeviceIntPtr device, unsigned int key_code,
                            int is_down);
-extern _X_EXPORT int xf86ActivateDevice(LocalDevicePtr local);
 extern _X_EXPORT LocalDevicePtr xf86FirstLocalDevice(void);
 extern _X_EXPORT int xf86ScaleAxis(int Cx, int Sxhigh, int Sxlow, int Rxhigh, int Rxlow);
 extern _X_EXPORT void xf86XInputSetScreen(LocalDevicePtr local, int screen_number, int x, int y);
commit 31c71425ac13a7f554316356691a79175ea82a67
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Jul 22 09:09:10 2010 +1000

    config: expose config_info as an input option.
    
    config_info is the only reliable indicator we have in the server for
    duplicate devices (drivers can test for maj/min on fds as well). Don't set
    this after the device has been initialized but assume it's important enough
    to set during NIDR.
    
    This makes the option "config_info" available to the drivers as well.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/config/hal.c b/config/hal.c
index b70488b..6e2850c 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -376,6 +376,7 @@ device_added(LibHalContext *hal_ctx, const char *udi)
         add_option(&options, "xkb_model", xkb_opts.model);
     if (xkb_opts.options)
         add_option(&options, "xkb_options", xkb_opts.options);
+    add_option(&options, "config_info", config_info);
 
     /* this isn't an error, but how else do you output something that the user can see? */
     LogMessage(X_INFO, "config/hal: Adding input device %s\n", name);
@@ -385,11 +386,6 @@ device_added(LibHalContext *hal_ctx, const char *udi)
         goto unwind;
     }
 
-    for (; dev; dev = dev->next){
-        free(dev->config_info);
-        dev->config_info = strdup(config_info);
-    }
-
 unwind:
     if (set)
         libhal_free_property_set(set);
diff --git a/config/udev.c b/config/udev.c
index 9934490..cd46eec 100644
--- a/config/udev.c
+++ b/config/udev.c
@@ -189,17 +189,14 @@ device_added(struct udev_device *udev_device)
         }
     }
 
+    add_option(&options, "config_info", config_info);
+
     LogMessage(X_INFO, "config/udev: Adding input device %s (%s)\n",
                name, path);
     rc = NewInputDeviceRequest(options, &attrs, &dev);
     if (rc != Success)
         goto unwind;
 
-    for (; dev; dev = dev->next) {
-        free(dev->config_info);
-        dev->config_info = strdup(config_info);
-    }
-
  unwind:
     free(config_info);
     while (!dev && (tmpo = options)) {
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index cc8b968..8fd35e6 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -353,6 +353,7 @@ xf86ActivateDevice(LocalDevicePtr local)
 
         dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
         dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+        dev->config_info = xf86SetStrOption(local->options, "config_info", NULL);
 
         RegisterOtherDevice(dev);
         XkbSetExtension(dev, ProcessKeyboardEvent);
commit de0cc5a72deb7c477e368aa4fe9a713788d7ae4c
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed Jul 21 16:00:26 2010 +1000

    xfree86: rework driver PreInit API - XInput ABI 12
    
    The main change introduced in this patch is the removal of the
    back-and-forth between DDX and the driver.
    The DDX now allocates the InputInfoRec and fills it with default values. The
    DDX processes common options (and module-specific default options, if
    appropriate) before passing the initialised struct to the driver.
    
    The driver may do module-specific initializations and return Success or an
    error code in the case of a failure.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Daniel Stone <daniel at fooishbar.org>

diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index 07f9f0a..897aaf3 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -276,7 +276,7 @@ xf86AllocateScrnInfoPrivateIndex(void)
 
 /* Allocate a new InputInfoRec and append it to the tail of xf86InputDevs. */
 InputInfoPtr
-xf86AllocateInput(InputDriverPtr drv, int flags)
+xf86AllocateInput(InputDriverPtr drv, IDevPtr idev)
 {
     InputInfoPtr new, *prev = NULL;
 
@@ -293,6 +293,26 @@ xf86AllocateInput(InputDriverPtr drv, int flags)
     *prev = new;
     new->next = NULL;
 
+    new->fd = -1;
+    new->name = idev->identifier;
+    new->type_name = "UNKNOWN";
+    new->device_control = NULL;
+    new->read_input = NULL;
+    new->history_size = 0;
+    new->control_proc = NULL;
+    new->close_proc = NULL;
+    new->switch_mode = NULL;
+    new->conversion_proc = NULL;
+    new->reverse_conversion_proc = NULL;
+    new->dev = NULL;
+    new->private_flags = 0;
+    new->always_core_feedback = NULL;
+    new->private = NULL;
+    new->conf_idev = idev;
+
+    xf86CollectInputOptions(new, (const char**)drv->default_options, NULL);
+    xf86ProcessCommonOptions(new, new->options);
+
     return new;
 }
 
diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h
index 51b9b16..aed2edc 100644
--- a/hw/xfree86/common/xf86Module.h
+++ b/hw/xfree86/common/xf86Module.h
@@ -83,7 +83,7 @@ typedef enum {
  */
 #define ABI_ANSIC_VERSION	SET_ABI_VERSION(0, 4)
 #define ABI_VIDEODRV_VERSION	SET_ABI_VERSION(8, 0)
-#define ABI_XINPUT_VERSION	SET_ABI_VERSION(11, 0)
+#define ABI_XINPUT_VERSION	SET_ABI_VERSION(12, 0)
 #define ABI_EXTENSION_VERSION	SET_ABI_VERSION(4, 0)
 #define ABI_FONT_VERSION	SET_ABI_VERSION(0, 6)
 
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index bd77fe6..cc8b968 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -775,11 +775,13 @@ xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
         goto unwind;
     }
 
-    pInfo = drv->PreInit(drv, idev, 0);
+    if (!(pInfo = xf86AllocateInput(drv, idev)))
+	goto unwind;
 
-    if (!pInfo) {
-        xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier);
-        rval = BadMatch;
+    rval = drv->PreInit(drv, pInfo, 0);
+
+    if (rval != Success) {
+        xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, idev->identifier);
         goto unwind;
     }
     else if (!(pInfo->flags & XI86_CONFIGURED)) {
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 20a3f1b..6789df6 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -97,13 +97,14 @@ typedef struct _InputDriverRec {
     int			    driverVersion;
     char *		    driverName;
     void		    (*Identify)(int flags);
-    struct _LocalDeviceRec *(*PreInit)(struct _InputDriverRec *drv,
-				       IDevPtr dev, int flags);
+    int			    (*PreInit)(struct _InputDriverRec *drv,
+				       struct _LocalDeviceRec* pInfo, int flags);
     void		    (*UnInit)(struct _InputDriverRec *drv,
 				      struct _LocalDeviceRec *pInfo,
 				      int flags);
     pointer		    module;
     int			    refCount;
+    char **		    default_options;
 } InputDriverRec, *InputDriverPtr;
 
 /* This is to input devices what the ScrnInfoRec is to screens. */
@@ -202,7 +203,7 @@ int xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL is_auto);
 /* xf86Helper.c */
 extern _X_EXPORT void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags);
 extern _X_EXPORT void xf86DeleteInputDriver(int drvIndex);
-extern _X_EXPORT InputInfoPtr xf86AllocateInput(InputDriverPtr drv, int flags);
+extern _X_INTERNAL InputInfoPtr xf86AllocateInput(InputDriverPtr drv, IDevPtr idev);
 extern _X_EXPORT InputDriverPtr xf86LookupInputDriver(const char *name);
 extern _X_EXPORT InputInfoPtr xf86LookupInput(const char *name);
 extern _X_EXPORT void xf86DeleteInput(InputInfoPtr pInp, int flags);


More information about the xorg-commit mailing list