From 5e633abcca598289d0423d89bb400b41e6417259 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Tue, 15 Mar 2011 21:35:41 +0000
Subject: xserver libX11 libxcb mesa git update 15 Mar 2011

---
 xorg-server/Xi/xipassivegrab.c                 |  614 +--
 xorg-server/Xi/xiproperty.c                    |    4 +-
 xorg-server/config/hal.c                       |    6 +-
 xorg-server/config/udev.c                      |    6 +-
 xorg-server/configure.ac                       | 4542 ++++++++---------
 xorg-server/dix/devices.c                      | 5258 +++++++++----------
 xorg-server/dix/eventconvert.c                 | 1537 +++---
 xorg-server/dix/getevents.c                    | 2638 +++++-----
 xorg-server/dix/ptrveloc.c                     | 2413 ++++-----
 xorg-server/fb/fbpict.c                        |  746 +--
 xorg-server/glx/glxdri.c                       |   44 +-
 xorg-server/glx/glxdri2.c                      |   39 +-
 xorg-server/glx/glxdricommon.c                 |   57 +
 xorg-server/glx/glxdricommon.h                 |   87 +-
 xorg-server/glx/glxdriswrast.c                 |   50 +-
 xorg-server/hw/dmx/dmx.h                       |    2 -
 xorg-server/hw/dmx/dmxpict.c                   |   87 -
 xorg-server/hw/dmx/dmxpict.h                   |   10 -
 xorg-server/hw/dmx/doc/Makefile.am             |  557 +-
 xorg-server/hw/xfree86/Makefile.am             |  238 +-
 xorg-server/hw/xfree86/common/xf86Configure.c  | 1527 +++---
 xorg-server/hw/xfree86/common/xf86Xinput.c     | 2815 +++++-----
 xorg-server/hw/xfree86/doc/Makefile.am         |    8 +-
 xorg-server/hw/xfree86/doc/man/Makefile.am     |    3 -
 xorg-server/hw/xfree86/doc/man/Xorg.man        |  689 ---
 xorg-server/hw/xfree86/doc/man/xorg.conf.d.man |    1 -
 xorg-server/hw/xfree86/doc/man/xorg.conf.man   | 2478 ---------
 xorg-server/hw/xfree86/man/Makefile.am         |    3 +
 xorg-server/hw/xfree86/man/Xorg.man            |  689 +++
 xorg-server/hw/xfree86/man/xorg.conf.d.man     |    1 +
 xorg-server/hw/xfree86/man/xorg.conf.man       | 2478 +++++++++
 xorg-server/hw/xfree86/modes/xf86Crtc.c        | 6479 ++++++++++++------------
 xorg-server/hw/xfree86/os-support/xf86_OSlib.h |  833 ++-
 xorg-server/hw/xfree86/parser/scan.c           |   11 +-
 xorg-server/include/input.h                    | 1188 +++--
 xorg-server/include/misc.h                     |  592 +--
 xorg-server/include/propertyst.h               |  136 +-
 xorg-server/include/ptrveloc.h                 |  282 +-
 xorg-server/include/resource.h                 |  510 +-
 xorg-server/mi/mipointer.c                     | 1386 ++---
 xorg-server/mi/mipointer.h                     |    1 +
 xorg-server/mi/misprite.c                      | 2087 ++++----
 xorg-server/miext/cw/cw.h                      |    2 -
 xorg-server/miext/cw/cw_render.c               |   64 -
 xorg-server/os/access.c                        |   19 -
 xorg-server/os/osinit.c                        |  623 ++-
 xorg-server/os/utils.c                         |   11 -
 xorg-server/os/xdmcp.c                         |    2 +-
 xorg-server/randr/randr.c                      | 1006 ++--
 xorg-server/randr/randrstr.h                   | 1944 +++----
 xorg-server/randr/rrcrtc.c                     | 2857 ++++++-----
 xorg-server/record/record.c                    | 5873 +++++++++++----------
 xorg-server/render/mipict.c                    | 1254 +++--
 xorg-server/render/mipict.h                    |  353 +-
 xorg-server/render/mitri.c                     |  200 +-
 xorg-server/render/picture.c                   |   45 +-
 xorg-server/render/picturestr.h                |    2 -
 xorg-server/test/Makefile.am                   |    3 +-
 xorg-server/test/list.c                        |  176 +
 xorg-server/xkb/xkbActions.c                   | 2875 ++++++-----
 60 files changed, 30234 insertions(+), 30207 deletions(-)
 delete mode 100644 xorg-server/hw/xfree86/doc/man/Makefile.am
 delete mode 100644 xorg-server/hw/xfree86/doc/man/Xorg.man
 delete mode 100644 xorg-server/hw/xfree86/doc/man/xorg.conf.d.man
 delete mode 100644 xorg-server/hw/xfree86/doc/man/xorg.conf.man
 create mode 100644 xorg-server/hw/xfree86/man/Makefile.am
 create mode 100644 xorg-server/hw/xfree86/man/Xorg.man
 create mode 100644 xorg-server/hw/xfree86/man/xorg.conf.d.man
 create mode 100644 xorg-server/hw/xfree86/man/xorg.conf.man
 create mode 100644 xorg-server/test/list.c

(limited to 'xorg-server')

diff --git a/xorg-server/Xi/xipassivegrab.c b/xorg-server/Xi/xipassivegrab.c
index 8663d12a1..487c2721b 100644
--- a/xorg-server/Xi/xipassivegrab.c
+++ b/xorg-server/Xi/xipassivegrab.c
@@ -1,307 +1,307 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Author: Peter Hutterer
- */
-
-/***********************************************************************
- *
- * Request to grab or ungrab input device.
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "inputstr.h"	/* DeviceIntPtr      */
-#include "windowstr.h"	/* window structure  */
-#include <X11/extensions/XI2.h>
-#include <X11/extensions/XI2proto.h>
-#include "swaprep.h"
-
-#include "exglobals.h" /* BadDevice */
-#include "exevents.h"
-#include "xipassivegrab.h"
-#include "dixgrabs.h"
-
-int
-SProcXIPassiveGrabDevice(ClientPtr client)
-{
-    int i;
-    char n;
-    xXIModifierInfo *mods;
-
-    REQUEST(xXIPassiveGrabDeviceReq);
-
-    swaps(&stuff->length, n);
-    swaps(&stuff->deviceid, n);
-    swapl(&stuff->grab_window, n);
-    swapl(&stuff->cursor, n);
-    swapl(&stuff->time, n);
-    swapl(&stuff->detail, n);
-    swaps(&stuff->mask_len, n);
-    swaps(&stuff->num_modifiers, n);
-
-    mods = (xXIModifierInfo*)&stuff[1];
-
-    for (i = 0; i < stuff->num_modifiers; i++, mods++)
-    {
-        swapl(&mods->base_mods, n);
-        swapl(&mods->latched_mods, n);
-        swapl(&mods->locked_mods, n);
-    }
-
-    return ProcXIPassiveGrabDevice(client);
-}
-
-int
-ProcXIPassiveGrabDevice(ClientPtr client)
-{
-    DeviceIntPtr dev, mod_dev;
-    xXIPassiveGrabDeviceReply rep;
-    int i, ret = Success;
-    uint8_t status;
-    uint32_t *modifiers;
-    xXIGrabModifierInfo *modifiers_failed;
-    GrabMask mask;
-    GrabParameters param;
-    void *tmp;
-    int mask_len;
-
-    REQUEST(xXIPassiveGrabDeviceReq);
-    REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
-
-    if (stuff->deviceid == XIAllDevices)
-        dev = inputInfo.all_devices;
-    else if (stuff->deviceid == XIAllMasterDevices)
-        dev = inputInfo.all_master_devices;
-    else
-    {
-        ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
-        if (ret != Success)
-            return ret;
-    }
-
-    if (stuff->grab_type != XIGrabtypeButton &&
-        stuff->grab_type != XIGrabtypeKeycode &&
-        stuff->grab_type != XIGrabtypeEnter &&
-        stuff->grab_type != XIGrabtypeFocusIn)
-    {
-        client->errorValue = stuff->grab_type;
-        return BadValue;
-    }
-
-    if ((stuff->grab_type == XIGrabtypeEnter ||
-         stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
-    {
-        client->errorValue = stuff->detail;
-        return BadValue;
-    }
-
-    if (XICheckInvalidMaskBits(client, (unsigned char*)&stuff[1],
-                               stuff->mask_len * 4) != Success)
-        return BadValue;
-
-    mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
-    memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
-    memcpy(mask.xi2mask[stuff->deviceid], &stuff[1], mask_len * 4);
-
-    rep.repType = X_Reply;
-    rep.RepType = X_XIPassiveGrabDevice;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.num_modifiers = 0;
-
-    memset(&param, 0, sizeof(param));
-    param.grabtype = GRABTYPE_XI2;
-    param.ownerEvents = stuff->owner_events;
-    param.this_device_mode = stuff->grab_mode;
-    param.other_devices_mode = stuff->paired_device_mode;
-    param.grabWindow = stuff->grab_window;
-    param.cursor = stuff->cursor;
-
-    if (stuff->cursor != None)
-    {
-        status = dixLookupResourceByType(&tmp, stuff->cursor,
-                                         RT_CURSOR, client, DixUseAccess);
-	if (status != Success)
-	{
-	    client->errorValue = stuff->cursor;
-	    return status;
-	}
-    }
-
-    status = dixLookupWindow((WindowPtr*)&tmp, stuff->grab_window, client, DixSetAttrAccess);
-    if (status != Success)
-	return status;
-
-    status = CheckGrabValues(client, &param);
-
-    modifiers = (uint32_t*)&stuff[1] + stuff->mask_len;
-    modifiers_failed = calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
-    if (!modifiers_failed)
-        return BadAlloc;
-
-    mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
-
-    for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
-    {
-        param.modifiers = *modifiers;
-        switch(stuff->grab_type)
-        {
-            case XIGrabtypeButton:
-                status = GrabButton(client, dev, mod_dev, stuff->detail,
-                                    &param, GRABTYPE_XI2, &mask);
-                break;
-            case XIGrabtypeKeycode:
-                status = GrabKey(client, dev, mod_dev, stuff->detail,
-                                 &param, GRABTYPE_XI2, &mask);
-                break;
-            case XIGrabtypeEnter:
-            case XIGrabtypeFocusIn:
-                status = GrabWindow(client, dev, stuff->grab_type,
-                                    &param, &mask);
-                break;
-        }
-
-        if (status != GrabSuccess)
-        {
-            xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
-
-            info->status = status;
-            info->modifiers = *modifiers;
-            rep.num_modifiers++;
-            rep.length++;
-        }
-    }
-
-    WriteReplyToClient(client, sizeof(rep), &rep);
-    if (rep.num_modifiers)
-    {
-	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
-        WriteSwappedDataToClient(client, rep.num_modifiers * 4, (char*)modifiers_failed);
-    }
-    free(modifiers_failed);
-    return ret;
-}
-
-void
-SRepXIPassiveGrabDevice(ClientPtr client, int size,
-                        xXIPassiveGrabDeviceReply * rep)
-{
-    char n;
-
-    swaps(&rep->sequenceNumber, n);
-    swapl(&rep->length, n);
-    swaps(&rep->num_modifiers, n);
-
-    WriteToClient(client, size, (char *)rep);
-}
-
-int
-SProcXIPassiveUngrabDevice(ClientPtr client)
-{
-    char n;
-    int i;
-    uint32_t *modifiers;
-
-    REQUEST(xXIPassiveUngrabDeviceReq);
-
-    swaps(&stuff->length, n);
-    swapl(&stuff->grab_window, n);
-    swaps(&stuff->deviceid, n);
-    swapl(&stuff->detail, n);
-    swaps(&stuff->num_modifiers, n);
-
-    modifiers = (uint32_t*)&stuff[1];
-
-    for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
-        swapl(modifiers, n);
-
-    return ProcXIPassiveUngrabDevice(client);
-}
-
-int
-ProcXIPassiveUngrabDevice(ClientPtr client)
-{
-    DeviceIntPtr dev, mod_dev;
-    WindowPtr win;
-    GrabRec tempGrab;
-    uint32_t* modifiers;
-    int i, rc;
-
-    REQUEST(xXIPassiveUngrabDeviceReq);
-    REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
-
-    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
-    if (rc != Success)
-	return rc;
-
-    if (stuff->grab_type != XIGrabtypeButton &&
-        stuff->grab_type != XIGrabtypeKeycode &&
-        stuff->grab_type != XIGrabtypeEnter &&
-        stuff->grab_type != XIGrabtypeFocusIn)
-    {
-        client->errorValue = stuff->grab_type;
-        return BadValue;
-    }
-
-    if ((stuff->grab_type == XIGrabtypeEnter ||
-         stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
-    {
-        client->errorValue = stuff->detail;
-        return BadValue;
-    }
-
-    rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
-    if (rc != Success)
-        return rc;
-
-    mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
-
-    tempGrab.resource = client->clientAsMask;
-    tempGrab.device = dev;
-    tempGrab.window = win;
-    switch(stuff->grab_type)
-    {
-        case XIGrabtypeButton:  tempGrab.type = XI_ButtonPress; break;
-        case XIGrabtypeKeycode:  tempGrab.type = XI_KeyPress;    break;
-        case XIGrabtypeEnter:   tempGrab.type = XI_Enter;       break;
-        case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn;     break;
-    }
-    tempGrab.grabtype = GRABTYPE_XI2;
-    tempGrab.modifierDevice = mod_dev;
-    tempGrab.modifiersDetail.pMask = NULL;
-    tempGrab.detail.exact = stuff->detail;
-    tempGrab.detail.pMask = NULL;
-
-    modifiers = (uint32_t*)&stuff[1];
-
-    for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
-    {
-        tempGrab.modifiersDetail.exact = *modifiers;
-        DeletePassiveGrabFromList(&tempGrab);
-    }
-
-    return Success;
-}
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Peter Hutterer
+ */
+
+/***********************************************************************
+ *
+ * Request to grab or ungrab input device.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "inputstr.h"	/* DeviceIntPtr      */
+#include "windowstr.h"	/* window structure  */
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XI2proto.h>
+#include "swaprep.h"
+
+#include "exglobals.h" /* BadDevice */
+#include "exevents.h"
+#include "xipassivegrab.h"
+#include "dixgrabs.h"
+
+int
+SProcXIPassiveGrabDevice(ClientPtr client)
+{
+    int i;
+    char n;
+    xXIModifierInfo *mods;
+
+    REQUEST(xXIPassiveGrabDeviceReq);
+
+    swaps(&stuff->length, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->grab_window, n);
+    swapl(&stuff->cursor, n);
+    swapl(&stuff->time, n);
+    swapl(&stuff->detail, n);
+    swaps(&stuff->mask_len, n);
+    swaps(&stuff->num_modifiers, n);
+
+    mods = (xXIModifierInfo*)&stuff[1];
+
+    for (i = 0; i < stuff->num_modifiers; i++, mods++)
+    {
+        swapl(&mods->base_mods, n);
+        swapl(&mods->latched_mods, n);
+        swapl(&mods->locked_mods, n);
+    }
+
+    return ProcXIPassiveGrabDevice(client);
+}
+
+int
+ProcXIPassiveGrabDevice(ClientPtr client)
+{
+    DeviceIntPtr dev, mod_dev;
+    xXIPassiveGrabDeviceReply rep;
+    int i, ret = Success;
+    uint8_t status;
+    uint32_t *modifiers;
+    xXIGrabModifierInfo *modifiers_failed;
+    GrabMask mask;
+    GrabParameters param;
+    void *tmp;
+    int mask_len;
+
+    REQUEST(xXIPassiveGrabDeviceReq);
+    REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq);
+
+    if (stuff->deviceid == XIAllDevices)
+        dev = inputInfo.all_devices;
+    else if (stuff->deviceid == XIAllMasterDevices)
+        dev = inputInfo.all_master_devices;
+    else
+    {
+        ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
+        if (ret != Success)
+            return ret;
+    }
+
+    if (stuff->grab_type != XIGrabtypeButton &&
+        stuff->grab_type != XIGrabtypeKeycode &&
+        stuff->grab_type != XIGrabtypeEnter &&
+        stuff->grab_type != XIGrabtypeFocusIn)
+    {
+        client->errorValue = stuff->grab_type;
+        return BadValue;
+    }
+
+    if ((stuff->grab_type == XIGrabtypeEnter ||
+         stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
+    {
+        client->errorValue = stuff->detail;
+        return BadValue;
+    }
+
+    if (XICheckInvalidMaskBits(client, (unsigned char*)&stuff[1],
+                               stuff->mask_len * 4) != Success)
+        return BadValue;
+
+    mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
+    memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
+    memcpy(mask.xi2mask[stuff->deviceid], &stuff[1], mask_len * 4);
+
+    rep.repType = X_Reply;
+    rep.RepType = X_XIPassiveGrabDevice;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.num_modifiers = 0;
+
+    memset(&param, 0, sizeof(param));
+    param.grabtype = GRABTYPE_XI2;
+    param.ownerEvents = stuff->owner_events;
+    param.this_device_mode = stuff->grab_mode;
+    param.other_devices_mode = stuff->paired_device_mode;
+    param.grabWindow = stuff->grab_window;
+    param.cursor = stuff->cursor;
+
+    if (stuff->cursor != None)
+    {
+        status = dixLookupResourceByType(&tmp, stuff->cursor,
+                                         RT_CURSOR, client, DixUseAccess);
+	if (status != Success)
+	{
+	    client->errorValue = stuff->cursor;
+	    return status;
+	}
+    }
+
+    status = dixLookupWindow((WindowPtr*)&tmp, stuff->grab_window, client, DixSetAttrAccess);
+    if (status != Success)
+	return status;
+
+    status = CheckGrabValues(client, &param);
+
+    modifiers = (uint32_t*)&stuff[1] + stuff->mask_len;
+    modifiers_failed = calloc(stuff->num_modifiers, sizeof(xXIGrabModifierInfo));
+    if (!modifiers_failed)
+        return BadAlloc;
+
+    mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
+
+    for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
+    {
+        param.modifiers = *modifiers;
+        switch(stuff->grab_type)
+        {
+            case XIGrabtypeButton:
+                status = GrabButton(client, dev, mod_dev, stuff->detail,
+                                    &param, GRABTYPE_XI2, &mask);
+                break;
+            case XIGrabtypeKeycode:
+                status = GrabKey(client, dev, mod_dev, stuff->detail,
+                                 &param, GRABTYPE_XI2, &mask);
+                break;
+            case XIGrabtypeEnter:
+            case XIGrabtypeFocusIn:
+                status = GrabWindow(client, dev, stuff->grab_type,
+                                    &param, &mask);
+                break;
+        }
+
+        if (status != GrabSuccess)
+        {
+            xXIGrabModifierInfo *info = modifiers_failed + rep.num_modifiers;
+
+            info->status = status;
+            info->modifiers = *modifiers;
+            rep.num_modifiers++;
+            rep.length += bytes_to_int32(sizeof(xXIGrabModifierInfo));
+        }
+    }
+
+    WriteReplyToClient(client, sizeof(rep), &rep);
+    if (rep.num_modifiers)
+    {
+	client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+        WriteSwappedDataToClient(client, rep.length * 4, (char*)modifiers_failed);
+    }
+    free(modifiers_failed);
+    return ret;
+}
+
+void
+SRepXIPassiveGrabDevice(ClientPtr client, int size,
+                        xXIPassiveGrabDeviceReply * rep)
+{
+    char n;
+
+    swaps(&rep->sequenceNumber, n);
+    swapl(&rep->length, n);
+    swaps(&rep->num_modifiers, n);
+
+    WriteToClient(client, size, (char *)rep);
+}
+
+int
+SProcXIPassiveUngrabDevice(ClientPtr client)
+{
+    char n;
+    int i;
+    uint32_t *modifiers;
+
+    REQUEST(xXIPassiveUngrabDeviceReq);
+
+    swaps(&stuff->length, n);
+    swapl(&stuff->grab_window, n);
+    swaps(&stuff->deviceid, n);
+    swapl(&stuff->detail, n);
+    swaps(&stuff->num_modifiers, n);
+
+    modifiers = (uint32_t*)&stuff[1];
+
+    for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
+        swapl(modifiers, n);
+
+    return ProcXIPassiveUngrabDevice(client);
+}
+
+int
+ProcXIPassiveUngrabDevice(ClientPtr client)
+{
+    DeviceIntPtr dev, mod_dev;
+    WindowPtr win;
+    GrabRec tempGrab;
+    uint32_t* modifiers;
+    int i, rc;
+
+    REQUEST(xXIPassiveUngrabDeviceReq);
+    REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq);
+
+    rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess);
+    if (rc != Success)
+	return rc;
+
+    if (stuff->grab_type != XIGrabtypeButton &&
+        stuff->grab_type != XIGrabtypeKeycode &&
+        stuff->grab_type != XIGrabtypeEnter &&
+        stuff->grab_type != XIGrabtypeFocusIn)
+    {
+        client->errorValue = stuff->grab_type;
+        return BadValue;
+    }
+
+    if ((stuff->grab_type == XIGrabtypeEnter ||
+         stuff->grab_type == XIGrabtypeFocusIn) && stuff->detail != 0)
+    {
+        client->errorValue = stuff->detail;
+        return BadValue;
+    }
+
+    rc = dixLookupWindow(&win, stuff->grab_window, client, DixSetAttrAccess);
+    if (rc != Success)
+        return rc;
+
+    mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
+
+    tempGrab.resource = client->clientAsMask;
+    tempGrab.device = dev;
+    tempGrab.window = win;
+    switch(stuff->grab_type)
+    {
+        case XIGrabtypeButton:  tempGrab.type = XI_ButtonPress; break;
+        case XIGrabtypeKeycode:  tempGrab.type = XI_KeyPress;    break;
+        case XIGrabtypeEnter:   tempGrab.type = XI_Enter;       break;
+        case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn;     break;
+    }
+    tempGrab.grabtype = GRABTYPE_XI2;
+    tempGrab.modifierDevice = mod_dev;
+    tempGrab.modifiersDetail.pMask = NULL;
+    tempGrab.detail.exact = stuff->detail;
+    tempGrab.detail.pMask = NULL;
+
+    modifiers = (uint32_t*)&stuff[1];
+
+    for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
+    {
+        tempGrab.modifiersDetail.exact = *modifiers;
+        DeletePassiveGrabFromList(&tempGrab);
+    }
+
+    return Success;
+}
diff --git a/xorg-server/Xi/xiproperty.c b/xorg-server/Xi/xiproperty.c
index c1a25bbf7..b10891d1c 100644
--- a/xorg-server/Xi/xiproperty.c
+++ b/xorg-server/Xi/xiproperty.c
@@ -1051,11 +1051,11 @@ SProcXChangeDeviceProperty (ClientPtr client)
     char n;
     REQUEST(xChangeDevicePropertyReq);
 
+    REQUEST_AT_LEAST_SIZE(xChangeDevicePropertyReq);
     swaps(&stuff->length, n);
     swapl(&stuff->property, n);
     swapl(&stuff->type, n);
     swapl(&stuff->nUnits, n);
-    REQUEST_SIZE_MATCH(xChangeDevicePropertyReq);
     return (ProcXChangeDeviceProperty(client));
 }
 
@@ -1295,12 +1295,12 @@ SProcXIChangeProperty(ClientPtr client)
     char n;
     REQUEST(xXIChangePropertyReq);
 
+    REQUEST_AT_LEAST_SIZE(xXIChangePropertyReq);
     swaps(&stuff->length, n);
     swaps(&stuff->deviceid, n);
     swapl(&stuff->property, n);
     swapl(&stuff->type, n);
     swapl(&stuff->num_items, n);
-    REQUEST_SIZE_MATCH(xXIChangePropertyReq);
     return (ProcXIChangeProperty(client));
 }
 
diff --git a/xorg-server/config/hal.c b/xorg-server/config/hal.c
index 2aff6f9fd..929643653 100644
--- a/xorg-server/config/hal.c
+++ b/xorg-server/config/hal.c
@@ -392,10 +392,10 @@ unwind:
     free(driver);
     free(name);
     free(config_info);
-    while (!dev && (tmpo = options)) {
+    while ((tmpo = options)) {
         options = tmpo->next;
-        free(tmpo->key);
-        free(tmpo->value);
+        free(tmpo->key);        /* NULL if dev != NULL */
+        free(tmpo->value);      /* NULL if dev != NULL */
         free(tmpo);
     }
 
diff --git a/xorg-server/config/udev.c b/xorg-server/config/udev.c
index eeacff162..44319e4db 100644
--- a/xorg-server/config/udev.c
+++ b/xorg-server/config/udev.c
@@ -197,10 +197,10 @@ device_added(struct udev_device *udev_device)
 
  unwind:
     free(config_info);
-    while (!dev && (tmpo = options)) {
+    while ((tmpo = options)) {
         options = tmpo->next;
-        free(tmpo->key);
-        free(tmpo->value);
+        free(tmpo->key);        /* NULL if dev != NULL */
+        free(tmpo->value);      /* NULL if dev != NULL */
         free(tmpo);
     }
 
diff --git a/xorg-server/configure.ac b/xorg-server/configure.ac
index 681f9d9c5..83ec3f9d0 100644
--- a/xorg-server/configure.ac
+++ b/xorg-server/configure.ac
@@ -1,2271 +1,2271 @@
-dnl Copyright © 2003-2007 Keith Packard, Daniel Stone
-dnl
-dnl Permission is hereby granted, free of charge, to any person obtaining a
-dnl copy of this software and associated documentation files (the "Software"),
-dnl to deal in the Software without restriction, including without limitation
-dnl the rights to use, copy, modify, merge, publish, distribute, sublicense,
-dnl and/or sell copies of the Software, and to permit persons to whom the
-dnl Software is furnished to do so, subject to the following conditions:
-dnl
-dnl The above copyright notice and this permission notice (including the next
-dnl paragraph) shall be included in all copies or substantial portions of the
-dnl Software.
-dnl
-dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
-dnl THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-dnl DEALINGS IN THE SOFTWARE.
-dnl
-dnl Authors: Keith Packard <keithp@keithp.com>
-dnl          Daniel Stone <daniel@fooishbar.org>
-dnl          an unwitting cast of miscellaneous others
-dnl
-dnl Process this file with autoconf to create configure.
-
-AC_PREREQ(2.57)
-AC_INIT([xorg-server], 1.10.99.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
-RELEASE_DATE="unreleased"
-AC_CONFIG_SRCDIR([Makefile.am])
-AM_INIT_AUTOMAKE([foreign dist-bzip2])
-AM_MAINTAINER_MODE
-
-# Require xorg-macros minimum of 1.10 for XORG_CHECK_SGML_DOCTOOLS
-m4_ifndef([XORG_MACROS_VERSION],
-          [m4_fatal([must install xorg-macros 1.10 or later before running autoconf/autogen])])
-XORG_MACROS_VERSION(1.10)
-XORG_DEFAULT_OPTIONS
-XORG_WITH_DOXYGEN(1.6.1)
-XORG_CHECK_SGML_DOCTOOLS(1.5)
-
-m4_ifndef([XORG_FONT_MACROS_VERSION], [m4_fatal([must install fontutil 1.1 or later before running autoconf/autogen])])
-XORG_FONT_MACROS_VERSION(1.1)
-
-dnl this gets generated by autoheader, and thus contains all the defines.  we
-dnl don't ever actually use it, internally.
-AC_CONFIG_HEADERS(include/do-not-use-config.h)
-dnl xorg-server.h is an external header, designed to be included by loadable
-dnl drivers.
-AC_CONFIG_HEADERS(include/xorg-server.h)
-dnl dix-config.h covers most of the DIX (i.e. everything but the DDX, not just
-dnl dix/).
-AC_CONFIG_HEADERS(include/dix-config.h)
-dnl xorg-config.h covers the Xorg DDX.
-AC_CONFIG_HEADERS(include/xorg-config.h)
-dnl xkb-config.h covers XKB for the Xorg and Xnest DDXs.
-AC_CONFIG_HEADERS(include/xkb-config.h)
-dnl xwin-config.h covers the XWin DDX.
-AC_CONFIG_HEADERS(include/xwin-config.h)
-dnl kdrive-config.h covers the kdrive DDX
-AC_CONFIG_HEADERS(include/kdrive-config.h)
-dnl version-config.h covers the version numbers so they can be bumped without
-dnl forcing an entire recompile.x
-AC_CONFIG_HEADERS(include/version-config.h)
-
-AM_PROG_AS
-AC_PROG_LN_S
-AC_LIBTOOL_WIN32_DLL
-AC_DISABLE_STATIC
-AC_PROG_LIBTOOL
-AC_PROG_MAKE_SET
-PKG_PROG_PKG_CONFIG
-AC_PROG_LEX
-AC_PROG_YACC
-AC_SYS_LARGEFILE
-XORG_PROG_RAWCPP
-
-# Quoted so that make will expand $(CWARNFLAGS) in makefiles to allow
-# easier overrides at build time.
-XSERVER_CFLAGS='$(CWARNFLAGS)'
-
-dnl Check for dtrace program (needed to build Xserver dtrace probes)
-dnl Also checks for <sys/sdt.h>, since some Linux distros have an 
-dnl ISDN trace program named dtrace
-AC_ARG_WITH(dtrace, AS_HELP_STRING([--with-dtrace=PATH],
-	     [Enable dtrace probes (default: enabled if dtrace found)]),
-	     [WDTRACE=$withval], [WDTRACE=auto])
-if test "x$WDTRACE" = "xyes" -o "x$WDTRACE" = "xauto" ; then
-	AC_PATH_PROG(DTRACE, [dtrace], [not_found], [$PATH:/usr/sbin])
-	if test "x$DTRACE" = "xnot_found" ; then
-		if test "x$WDTRACE" = "xyes" ; then
-			AC_MSG_FAILURE([dtrace requested but not found])
-		fi
-		WDTRACE="no"
-	else
-		AC_CHECK_HEADER(sys/sdt.h, [HAS_SDT_H="yes"], [HAS_SDT_H="no"])
-		if test "x$WDTRACE" = "xauto" -a "x$HAS_SDT_H" = "xno" ; then
-			WDTRACE="no"
-		fi
-	fi
-fi
-if test "x$WDTRACE" != "xno" ; then
-  AC_DEFINE(XSERVER_DTRACE, 1, 
-      [Define to 1 if the DTrace Xserver provider probes should be built in.])
-
-# Solaris/OpenSolaris require dtrace -G to build dtrace probe information into
-# object files, and require linking with those as relocatable objects, not .a
-# archives. MacOS X handles all this in the normal compiler toolchain, and on
-# some releases (like Tiger), will error out on dtrace -G.  For now, other
-# platforms with Dtrace ports are assumed to support -G (the FreeBSD and Linux
-# ports appear to, based on my web searches, but have not yet been tested).
-	case $host_os in
-		darwin*)	SPECIAL_DTRACE_OBJECTS=no ;;
-		*)		SPECIAL_DTRACE_OBJECTS=yes ;;
-	esac
-fi
-AM_CONDITIONAL(XSERVER_DTRACE, [test "x$WDTRACE" != "xno"])
-AM_CONDITIONAL(SPECIAL_DTRACE_OBJECTS, [test "x$SPECIAL_DTRACE_OBJECTS" = "xyes"])
-
-AC_HEADER_DIRENT
-AC_HEADER_STDC
-AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h fnmatch.h sys/utsname.h])
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-AC_C_CONST
-AC_C_BIGENDIAN([ENDIAN="X_BIG_ENDIAN"], [ENDIAN="X_LITTLE_ENDIAN"])
-
-AC_CHECK_SIZEOF([unsigned long])
-if test "$ac_cv_sizeof_unsigned_long" = 8; then
-	AC_DEFINE(_XSERVER64, 1, [Define to 1 if unsigned long is 64 bits.])
-fi
-
-AC_TYPE_PID_T
-
-# Checks for headers/macros for byte swapping
-# Known variants:
-#	<byteswap.h> bswap_16, bswap_32, bswap_64  (glibc)
-#	<sys/endian.h> __swap16, __swap32, __swap64 (OpenBSD)
-#	<sys/endian.h> bswap16, bswap32, bswap64 (other BSD's)
-#	and a fallback to local macros if none of the above are found
-
-# if <byteswap.h> is found, assume it's the correct version
-AC_CHECK_HEADERS([byteswap.h])
-
-# if <sys/endian.h> is found, have to check which version
-AC_CHECK_HEADER([sys/endian.h], [HAVE_SYS_ENDIAN_H="yes"], [HAVE_SYS_ENDIAN_H="no"])
-
-if test "x$HAVE_SYS_ENDIAN_H" = "xyes" ; then
-	AC_MSG_CHECKING([for __swap16 variant of <sys/endian.h> byteswapping macros])
-	AC_LINK_IFELSE([AC_LANG_PROGRAM([
-#include <sys/types.h>
-#include <sys/endian.h>
- ], [
-int a = 1, b;
-b = __swap16(a);
- ])
-], [SYS_ENDIAN__SWAP='yes'], [SYS_ENDIAN__SWAP='no'])
-	AC_MSG_RESULT([$SYS_ENDIAN__SWAP])
-
-	AC_MSG_CHECKING([for bswap16 variant of <sys/endian.h> byteswapping macros])
-	AC_LINK_IFELSE([AC_LANG_PROGRAM([
-#include <sys/types.h>
-#include <sys/endian.h>
- ], [
-int a = 1, b;
-b = bswap16(a);
- ])
-], [SYS_ENDIAN_BSWAP='yes'], [SYS_ENDIAN_BSWAP='no'])
-	AC_MSG_RESULT([$SYS_ENDIAN_BSWAP])
-
-    	if test "$SYS_ENDIAN_BSWAP" = "yes" ; then
-		USE_SYS_ENDIAN_H=yes
-		BSWAP=bswap
-	else	
-	    	if test "$SYS_ENDIAN__SWAP" = "yes" ; then
-			USE_SYS_ENDIAN_H=yes
-			BSWAP=__swap
-		else
-			USE_SYS_ENDIAN_H=no
-		fi
-	fi
-
-	if test "$USE_SYS_ENDIAN_H" = "yes" ; then
-	    AC_DEFINE([USE_SYS_ENDIAN_H], 1, 
-		[Define to use byteswap macros from <sys/endian.h>])
-	    AC_DEFINE_UNQUOTED([bswap_16], ${BSWAP}16, 
-			[Define to 16-bit byteswap macro])
-	    AC_DEFINE_UNQUOTED([bswap_32], ${BSWAP}32, 
-			[Define to 32-bit byteswap macro])
-	    AC_DEFINE_UNQUOTED([bswap_64], ${BSWAP}64, 
-			[Define to 64-bit byteswap macro])
-	fi
-fi
-
-dnl Check to see if dlopen is in default libraries (like Solaris, which
-dnl has it in libc), or if libdl is needed to get it.
-AC_CHECK_FUNC([dlopen], [],
-	AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl"))
-AC_SUBST(DLOPEN_LIBS)
-
-dnl Checks for library functions.
-AC_FUNC_VPRINTF
-AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
-		strtol getopt getopt_long vsnprintf walkcontext backtrace \
-		getisax getzoneid shmctl64 strcasestr ffs vasprintf])
-AC_FUNC_ALLOCA
-dnl Old HAS_* names used in os/*.c.
-AC_CHECK_FUNC([getdtablesize],
-	AC_DEFINE(HAS_GETDTABLESIZE, 1, [Have the 'getdtablesize' function.]))
-AC_CHECK_FUNC([getifaddrs],
-	AC_DEFINE(HAS_GETIFADDRS, 1, [Have the 'getifaddrs' function.]))
-AC_CHECK_FUNC([getpeereid],
-	AC_DEFINE(HAS_GETPEEREID, 1, [Have the 'getpeereid' function.]))
-AC_CHECK_FUNC([getpeerucred],
-	AC_DEFINE(HAS_GETPEERUCRED, 1, [Have the 'getpeerucred' function.]))
-AC_CHECK_FUNC([strlcat], HAVE_STRLCAT=yes, HAVE_STRLCAT=no)
-AM_CONDITIONAL(NEED_STRLCAT, [test x$HAVE_STRLCAT = xno])	
-AC_CHECK_FUNC([strlcpy], AC_DEFINE(HAS_STRLCPY, 1, [Have the 'strlcpy' function]))
-
-AM_CONDITIONAL(NEED_VSNPRINTF, [test x$HAVE_VSNPRINTF = xno])
-
-dnl Check for mmap support for Xvfb
-AC_CHECK_FUNC([mmap], AC_DEFINE(HAS_MMAP, 1, [Have the 'mmap' function.]))
-
-dnl Find the math libary
-AC_CHECK_LIB(m, sqrt)
-AC_CHECK_LIB(m, cbrt, AC_DEFINE(HAVE_CBRT, 1, [Have the 'cbrt' function]))
-
-AC_CHECK_HEADERS([ndbm.h dbm.h rpcsvc/dbm.h])
-
-dnl AGPGART headers
-AC_CHECK_HEADERS([linux/agpgart.h sys/agpio.h sys/agpgart.h], AGP=yes)
-AM_CONDITIONAL(AGP, [test "x$AGP" = xyes])
-
-dnl APM header
-AC_CHECK_HEADERS([linux/apm_bios.h], LNXAPM=yes)
-AM_CONDITIONAL(LNXAPM, [test "x$LNXAPM" = xyes])
-
-dnl fbdev header
-AC_CHECK_HEADERS([linux/fb.h], FBDEV=yes)
-AM_CONDITIONAL(FBDEVHW, [test "x$FBDEV" = xyes])
-
-dnl MTRR header
-AC_CHECK_HEADERS([asm/mtrr.h], ac_cv_asm_mtrr_h=yes)
-if test "x$ac_cv_asm_mtrr_h" = xyes; then
-	HAVE_MTRR=yes
-fi
-
-dnl BSD MTRR header
-AC_CHECK_HEADERS([sys/memrange.h], ac_cv_memrange_h=yes)
-if test "x$ac_cv_memrange_h" = xyes; then
-	HAVE_MTRR=yes
-fi
-
-if test "x$HAVE_MTRR" = xyes; then
-	AC_DEFINE(HAS_MTRR_SUPPORT, 1, [MTRR support available])
-fi
-
-dnl A NetBSD MTRR header
-AC_CHECK_HEADERS([machine/mtrr.h], ac_cv_machine_mtrr_h=yes)
-if test "x$ac_cv_machine_mtrr_h" = xyes; then
-	AC_DEFINE(HAS_MTRR_BUILTIN, 1, [Define to 1 if NetBSD built-in MTRR
-		support is available])
-fi
-
-dnl FreeBSD kldload support (sys/linker.h)
-AC_CHECK_HEADERS([sys/linker.h],
-	[ac_cv_sys_linker_h=yes],
-	[ac_cv_sys_linker_h=no],
-	[#include <sys/param.h>])
-AM_CONDITIONAL(FREEBSD_KLDLOAD, [test "x$ac_cv_sys_linker_h" = xyes])
-
-AC_CACHE_CHECK([for SYSV IPC],
-		ac_cv_sysv_ipc,
-		[AC_TRY_LINK([
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-],[
-{ 
-    int id;
-    id = shmget(IPC_PRIVATE, 512, SHM_W | SHM_R);
-    if (id < 0) return -1;
-    return shmctl(id, IPC_RMID, 0);
-}],
-	[ac_cv_sysv_ipc=yes],
-	[ac_cv_sysv_ipc=no])])
-if test "x$ac_cv_sysv_ipc" = xyes; then
-	AC_DEFINE(HAVE_SYSV_IPC, 1, [Define to 1 if SYSV IPC is available])
-fi
-
-dnl OpenBSD /dev/xf86 aperture driver 
-if test -c /dev/xf86 ; then
-	AC_DEFINE(HAS_APERTURE_DRV, 1, [System has /dev/xf86 aperture driver])
-fi
-
-dnl BSD APM support 
-AC_CHECK_HEADER([machine/apmvar.h],[
-	AC_CHECK_HEADER([sys/event.h],
-		ac_cv_BSD_KQUEUE_APM=yes,
-		ac_cv_BSD_APM=yes)])
-
-AM_CONDITIONAL(BSD_APM, [test "x$ac_cv_BSD_APM" = xyes])
-AM_CONDITIONAL(BSD_KQUEUE_APM, [test "x$ac_cv_BSD_KQUEUE_APM" = xyes])
-	
-dnl glibc backtrace support check (hw/xfree86/common/xf86Events.c)
-AC_CHECK_HEADER([execinfo.h],[
-    AC_CHECK_LIB(c, backtrace, [
-        AC_DEFINE(HAVE_BACKTRACE, 1, [Has backtrace support])
-        AC_DEFINE(HAVE_EXECINFO_H, 1, [Have execinfo.h])
-    ])]
-)
-
-dnl ---------------------------------------------------------------------------
-dnl Bus options and CPU capabilities.  Replaces logic in
-dnl hw/xfree86/os-support/bus/Makefile.am, among others.
-dnl ---------------------------------------------------------------------------
-DEFAULT_INT10="x86emu"
-
-dnl Override defaults as needed for specific platforms:
-
-case $host_cpu in
-  alpha*)
-	ALPHA_VIDEO=yes
-	case $host_os in
-	        *freebsd*)	SYS_LIBS=-lio ;;
-		*netbsd*)	AC_DEFINE(USE_ALPHA_PIO, 1, [NetBSD PIO alpha IO]) ;;
-	esac
-	GLX_ARCH_DEFINES="-D__GLX_ALIGN64 -mieee"
-	;;
-  arm*)
-	ARM_VIDEO=yes
-	;;
-  i*86)
-	I386_VIDEO=yes
-	case $host_os in
-		*freebsd*)	AC_DEFINE(USE_DEV_IO) ;;
-		*dragonfly*)	AC_DEFINE(USE_DEV_IO) ;;
-		*netbsd*)	AC_DEFINE(USE_I386_IOPL)
-				SYS_LIBS=-li386
-				;;
-		*openbsd*)	AC_DEFINE(USE_I386_IOPL) 
-				SYS_LIBS=-li386
-				;;
-	esac
-        ;;
-  powerpc*)
-	PPC_VIDEO=yes
-	case $host_os in
-		*freebsd*)	DEFAULT_INT10=stub ;;
-	esac
-	;;
-  sparc*)
-	SPARC64_VIDEO=yes
-	BSD_ARCH_SOURCES="sparc64_video.c ioperm_noop.c"
-	GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
-	;;
-  x86_64*|amd64*)
-	I386_VIDEO=yes
-	case $host_os in
-		*freebsd*)	AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;;
-		*dragonfly*)	AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;;
-		*netbsd*)	AC_DEFINE(USE_I386_IOPL, 1, [BSD i386 iopl])
-				SYS_LIBS=-lx86_64
-				;;
-		*openbsd*)	AC_DEFINE(USE_AMD64_IOPL, 1, [BSD AMD64 iopl])
-				SYS_LIBS=-lamd64
-				;;
-	esac
-	GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
-	;;
-  ia64*)
-  	GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
-	;;
-  s390*)
-  	GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
-	;;
-esac
-AC_SUBST(GLX_ARCH_DEFINES)
-
-dnl BSD *_video.c selection
-AM_CONDITIONAL(ALPHA_VIDEO, [test "x$ALPHA_VIDEO" = xyes])
-AM_CONDITIONAL(ARM_VIDEO, [test "x$ARM_VIDEO" = xyes])
-AM_CONDITIONAL(I386_VIDEO, [test "x$I386_VIDEO" = xyes])
-AM_CONDITIONAL(PPC_VIDEO, [test "x$PPC_VIDEO" = xyes])
-AM_CONDITIONAL(SPARC64_VIDEO, [test "x$SPARC64_VIDEO" = xyes])
-
-DRI=no
-USE_SIGIO_BY_DEFAULT="yes"
-dnl it would be nice to autodetect these *CONS_SUPPORTs
-case $host_os in
-  *freebsd* | *dragonfly*)
-	case $host_os in
-		kfreebsd*-gnu) ;;
-		*) AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) ;;
-	esac
-	AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console])
-	AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console])
-	AC_DEFINE(SYSCONS_SUPPORT, 1, [System has syscons console])
-	DRI=yes
-	;;
-  *netbsd*)
-	AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
-	AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console])
-	AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console])
-	AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console])
-	DRI=yes
-	;;
-  *openbsd*)
-	AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
-	AC_DEFINE(PCVT_SUPPORT, 1, [System has PC console])
-	AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console])
-	;;
-  *linux*)
-	DRI=yes
-	;;
-  *solaris*)
-	PKG_CHECK_EXISTS(libdrm, DRI=yes, DRI=no)
-	# Disable use of SIGIO by default until some system bugs are
-	# fixed - see Sun/OpenSolaris bug id 6879897
-	USE_SIGIO_BY_DEFAULT="no"
-	;;
-  darwin*)
-	AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
-	;;
-  cygwin*)
-	CFLAGS="$CFLAGS -DFD_SETSIZE=256"
-	;;
-esac
-
-dnl augment XORG_RELEASE_VERSION for our snapshot number and to expose the
-dnl major number
-PVMAJOR=`echo $PACKAGE_VERSION | cut -d . -f 1`
-PVS=`echo $PACKAGE_VERSION | cut -d . -f 4 | cut -d - -f 1`
-if test "x$PVS" = "x"; then
-	PVS="0"
-fi
-
-VENDOR_RELEASE="((($PVMAJOR) * 10000000) + (($PVM) * 100000) + (($PVP) * 1000) + $PVS)"
-VENDOR_MAN_VERSION="Version ${PACKAGE_VERSION}"
-
-VENDOR_NAME="The X.Org Foundation"
-VENDOR_NAME_SHORT="X.Org"
-VENDOR_WEB="http://wiki.x.org"
-
-m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))])
-
-dnl Build options.
-AC_ARG_ENABLE(werror,        AS_HELP_STRING([--enable-werror],
-		  [Obsolete - use --enable-strict-compilation instead]),
-  AC_MSG_ERROR([--enable-werror has been replaced by --enable-strict-compilation]))
-
-AC_ARG_ENABLE(debug,         AS_HELP_STRING([--enable-debug],
-				  [Enable debugging (default: disabled)]),
-			        [DEBUGGING=$enableval], [DEBUGGING=no])
-AC_ARG_ENABLE(unit-tests,    AS_HELP_STRING([--enable-unit-tests],
-                                  [Enable unit-tests (default: auto)]),
-                                [UNITTESTS=$enableval], [UNITTESTS=auto])
-AC_ARG_ENABLE(use-sigio-by-default, AS_HELP_STRING([--enable-use-sigio-by-default]
-  [Enable SIGIO input handlers by default (default: $USE_SIGIO_BY_DEFAULT)]),
-                                [USE_SIGIO_BY_DEFAULT=$enableval], [])
-AC_ARG_WITH(int10,           AS_HELP_STRING([--with-int10=BACKEND], [int10 backend: vm86, x86emu or stub]),
-				[INT10="$withval"],
-				[INT10="$DEFAULT_INT10"])
-AC_ARG_WITH(vendor-name,     AS_HELP_STRING([--with-vendor-name=VENDOR],
-				  [Vendor string reported by the server]),
-				[ VENDOR_NAME="$withval" ], [])
-AC_ARG_WITH(vendor-name-short, AS_HELP_STRING([--with-vendor-name-short=VENDOR],
-				  [Short version of vendor string reported by the server]),
-				[ VENDOR_NAME_SHORT="$withval" ], [])
-AC_ARG_WITH(vendor-web,      AS_HELP_STRING([--with-vendor-web=URL],
-				  [Vendor web address reported by the server]),
-				[ VENDOR_WEB="$withval" ], [])
-AC_ARG_WITH(module-dir,      AS_HELP_STRING([--with-module-dir=DIR],
-				  [Directory where modules are installed (default: $libdir/xorg/modules)]),
-				[ moduledir="$withval" ],
-				[ moduledir="${libdir}/xorg/modules" ])
-AC_ARG_WITH(log-dir,         AS_HELP_STRING([--with-log-dir=DIR],
-				  [Directory where log files are kept (default: $localstatedir/log)]),
-				[ logdir="$withval" ],
-				[ logdir="$localstatedir/log" ])
-AC_ARG_WITH(builder-addr,    AS_HELP_STRING([--with-builder-addr=ADDRESS],
-				  [Builder address (default: xorg@lists.freedesktop.org)]),
-				[ BUILDERADDR="$withval" ],
-				[ BUILDERADDR="xorg@lists.freedesktop.org" ])
-AC_ARG_WITH(os-name,         AS_HELP_STRING([--with-os-name=OSNAME], [Name of OS (default: output of "uname -srm")]),
-				[ OSNAME="$withval" ],
-				[ OSNAME=`uname -srm` ])
-AC_ARG_WITH(os-vendor,       AS_HELP_STRING([--with-os-vendor=OSVENDOR], [Name of OS vendor]),
-				[ OSVENDOR="$withval" ],
-				[ OSVENDOR="" ])
-AC_ARG_WITH(builderstring,   AS_HELP_STRING([--with-builderstring=BUILDERSTRING], [Additional builder string]),
-				[ BUILDERSTRING="$withval" ]
-				[ ])
-
-dnl Determine font path
-XORG_FONTROOTDIR
-XORG_FONTSUBDIR(FONTMISCDIR, fontmiscdir, misc)
-XORG_FONTSUBDIR(FONTOTFDIR, fontotfdir, OTF)
-XORG_FONTSUBDIR(FONTTTFDIR, fontttfdir, TTF)
-XORG_FONTSUBDIR(FONTTYPE1DIR, fonttype1dir, Type1)
-XORG_FONTSUBDIR(FONT75DPIDIR, font75dpidir, 75dpi)
-XORG_FONTSUBDIR(FONT100DPIDIR, font100dpidir, 100dpi)
-
-dnl Uses --default-font-path if set, otherwise checks for /etc/X11/fontpath.d,
-dnl otherwise uses standard subdirectories of FONTROOTDIR. When cross
-dnl compiling, assume default font path uses standard FONTROOTDIR directories.
-DEFAULT_FONT_PATH="${FONTMISCDIR}/,${FONTTTFDIR}/,${FONTOTFDIR}/,${FONTTYPE1DIR}/,${FONT100DPIDIR}/,${FONT75DPIDIR}/"
-if test "$cross_compiling" != yes; then
-	AC_CHECK_FILE([${sysconfdir}/X11/fontpath.d],
-		[DEFAULT_FONT_PATH='catalogue:${sysconfdir}/X11/fontpath.d'],
-		[case $host_os in
-			darwin*) DEFAULT_FONT_PATH="${DEFAULT_FONT_PATH},/Library/Fonts,/System/Library/Fonts" ;;
-		esac])
-fi
-AC_ARG_WITH(default-font-path, AS_HELP_STRING([--with-default-font-path=PATH], [Comma separated list of font dirs]),
-				[ FONTPATH="$withval" ],
-				[ FONTPATH="${DEFAULT_FONT_PATH}" ])
-
-AC_MSG_CHECKING([for default font path])
-AC_MSG_RESULT([$FONTPATH])
-
-AC_ARG_WITH(xkb-path,         AS_HELP_STRING([--with-xkb-path=PATH], [Path to XKB base dir (default: ${datadir}/X11/xkb)]),
-				[ XKBPATH="$withval" ],
-				[ XKBPATH="${datadir}/X11/xkb" ])
-AC_ARG_WITH(xkb-output,       AS_HELP_STRING([--with-xkb-output=PATH], [Path to XKB output dir (default: ${datadir}/X11/xkb/compiled)]),
-				[ XKBOUTPUT="$withval" ],
-				[ XKBOUTPUT="compiled" ])
-AC_ARG_WITH(default-xkb-rules, AS_HELP_STRING([--with-default-xkb-rules=RULES],
-                                   [Keyboard ruleset (default: base/evdev)]),
-                                [ XKB_DFLT_RULES="$withval" ],
-                                [ XKB_DFLT_RULES="" ])
-AC_ARG_WITH(default-xkb-model, AS_HELP_STRING([--with-default-xkb-model=MODEL],
-                                   [Keyboard model (default: pc105)]),
-                                [ XKB_DFLT_MODEL="$withval" ],
-                                [ XKB_DFLT_MODEL="pc105" ])
-AC_ARG_WITH(default-xkb-layout, AS_HELP_STRING([--with-default-xkb-layout=LAYOUT],
-                                   [Keyboard layout (default: us)]),
-                                [ XKB_DFLT_LAYOUT="$withval" ],
-                                [ XKB_DFLT_LAYOUT="us" ])
-AC_ARG_WITH(default-xkb-variant, AS_HELP_STRING([--with-default-xkb-variant=VARIANT],
-                                   [Keyboard variant (default: (none))]),
-                                [ XKB_DFLT_VARIANT="$withval" ],
-                                [ XKB_DFLT_VARIANT="" ])
-AC_ARG_WITH(default-xkb-options, AS_HELP_STRING([--with-default-xkb-options=OPTIONS],
-                                   [Keyboard layout options (default: (none))]),
-                                [ XKB_DFLT_OPTIONS="$withval" ],
-                                [ XKB_DFLT_OPTIONS="" ])
-AC_ARG_WITH(serverconfig-path, AS_HELP_STRING([--with-serverconfig-path=PATH],
-				   [Directory where ancillary server config files are installed (default: ${libdir}/xorg)]),
-				[ SERVERCONFIG="$withval" ],
-				[ SERVERCONFIG="${libdir}/xorg" ])
-AC_ARG_WITH(apple-applications-dir,AS_HELP_STRING([--with-apple-applications-dir=PATH], [Path to the Applications directory (default: /Applications/Utilities)]),
-				[ APPLE_APPLICATIONS_DIR="${withval}" ],
-				[ APPLE_APPLICATIONS_DIR="/Applications/Utilities" ])
-AC_SUBST([APPLE_APPLICATIONS_DIR])
-AC_ARG_WITH(apple-application-name,AS_HELP_STRING([--with-apple-application-name=NAME], [Name for the .app (default: X11)]),
-				[ APPLE_APPLICATION_NAME="${withval}" ],
-				[ APPLE_APPLICATION_NAME="X11" ])
-AC_SUBST([APPLE_APPLICATION_NAME])
-AC_ARG_WITH(launchd-id-prefix,  AS_HELP_STRING([--with-launchd-id-prefix=PATH], [Prefix to use for launchd identifiers (default: org.x)]),
-                                [ LAUNCHD_ID_PREFIX="${withval}" ],
-                                [ LAUNCHD_ID_PREFIX="org.x" ])
-AC_SUBST([LAUNCHD_ID_PREFIX])
-AC_DEFINE_UNQUOTED(LAUNCHD_ID_PREFIX, "$LAUNCHD_ID_PREFIX", [Prefix to use for launchd identifiers])
-AC_ARG_ENABLE(sparkle,AS_HELP_STRING([--enable-sparkle], [Enable updating of X11.app using the Sparkle Framework (default: disabled)]),
-				[ XQUARTZ_SPARKLE="${enableval}" ],
-				[ XQUARTZ_SPARKLE="no" ])
-AC_SUBST([XQUARTZ_SPARKLE])
-AC_ARG_ENABLE(install-libxf86config,
-				AS_HELP_STRING([--enable-install-libxf86config],
-				[Install libxf86config (default: disabled)]),
-				[INSTALL_LIBXF86CONFIG=$enableval],
-				[INSTALL_LIBXF86CONFIG=no])
-AC_ARG_ENABLE(visibility,     AC_HELP_STRING([--enable-visibility], [Enable symbol visibility (default: auto)]),
-				[SYMBOL_VISIBILITY=$enableval],
-				[SYMBOL_VISIBILITY=auto])
-AC_ARG_ENABLE(pc98,     	AC_HELP_STRING([--enable-pc98], [Enable PC98 support in Xorg (default: auto)]),
-				[SUPPORT_PC98=$enableval],
-				[SUPPORT_PC98=auto])
-
-dnl GLX build options
-AC_ARG_ENABLE(aiglx,          AS_HELP_STRING([--enable-aiglx], [Build accelerated indirect GLX (default: enabled)]),
-                                [AIGLX=$enableval],
-                                [AIGLX=yes])
-AX_TLS
-AC_ARG_ENABLE(glx-tls,        AS_HELP_STRING([--enable-glx-tls], [Build GLX with TLS support (default: auto)]),
-                                [GLX_USE_TLS=$enableval],
-                                [GLX_USE_TLS=no
-                                 if test "${ac_cv_tls}" != "none" ; then
-                                   GLX_USE_TLS=yes
-                                 fi])
-AC_SUBST(GLX_TLS, ${GLX_USE_TLS})
-
-dnl Extensions.
-AC_ARG_ENABLE(registry,       AS_HELP_STRING([--disable-registry], [Build string registry module (default: enabled)]), [XREGISTRY=$enableval], [XREGISTRY=yes])
-AC_ARG_ENABLE(composite,      AS_HELP_STRING([--disable-composite], [Build Composite extension (default: enabled)]), [COMPOSITE=$enableval], [COMPOSITE=yes])
-AC_ARG_ENABLE(mitshm,         AS_HELP_STRING([--disable-shm], [Build SHM extension (default: enabled)]), [MITSHM=$enableval], [MITSHM=yes])
-AC_ARG_ENABLE(xres,           AS_HELP_STRING([--disable-xres], [Build XRes extension (default: enabled)]), [RES=$enableval], [RES=yes])
-AC_ARG_ENABLE(record,         AS_HELP_STRING([--disable-record], [Build Record extension (default: enabled)]), [RECORD=$enableval], [RECORD=yes])
-AC_ARG_ENABLE(xv,             AS_HELP_STRING([--disable-xv], [Build Xv extension (default: enabled)]), [XV=$enableval], [XV=yes])
-AC_ARG_ENABLE(xvmc,           AS_HELP_STRING([--disable-xvmc], [Build XvMC extension (default: enabled)]), [XVMC=$enableval], [XVMC=yes])
-AC_ARG_ENABLE(dga,            AS_HELP_STRING([--disable-dga], [Build DGA extension (default: auto)]), [DGA=$enableval], [DGA=auto])
-AC_ARG_ENABLE(screensaver,    AS_HELP_STRING([--disable-screensaver], [Build ScreenSaver extension (default: enabled)]), [SCREENSAVER=$enableval], [SCREENSAVER=yes])
-AC_ARG_ENABLE(xdmcp,          AS_HELP_STRING([--disable-xdmcp], [Build XDMCP extension (default: auto)]), [XDMCP=$enableval], [XDMCP=auto])
-AC_ARG_ENABLE(xdm-auth-1,     AS_HELP_STRING([--disable-xdm-auth-1], [Build XDM-Auth-1 extension (default: auto)]), [XDMAUTH=$enableval], [XDMAUTH=auto])
-AC_ARG_ENABLE(glx,            AS_HELP_STRING([--disable-glx], [Build GLX extension (default: enabled)]), [GLX=$enableval], [GLX=yes])
-AC_ARG_ENABLE(dri,            AS_HELP_STRING([--enable-dri], [Build DRI extension (default: auto)]), [DRI=$enableval])
-AC_ARG_ENABLE(dri2,           AS_HELP_STRING([--enable-dri2], [Build DRI2 extension (default: auto)]), [DRI2=$enableval], [DRI2=auto])
-AC_ARG_ENABLE(xinerama,	      AS_HELP_STRING([--disable-xinerama], [Build Xinerama extension (default: enabled)]), [XINERAMA=$enableval], [XINERAMA=yes])
-AC_ARG_ENABLE(xf86vidmode,    AS_HELP_STRING([--disable-xf86vidmode], [Build XF86VidMode extension (default: auto)]), [XF86VIDMODE=$enableval], [XF86VIDMODE=auto])
-AC_ARG_ENABLE(xace,           AS_HELP_STRING([--disable-xace], [Build X-ACE extension (default: enabled)]), [XACE=$enableval], [XACE=yes])
-AC_ARG_ENABLE(xselinux,       AS_HELP_STRING([--enable-xselinux], [Build SELinux extension (default: disabled)]), [XSELINUX=$enableval], [XSELINUX=no])
-AC_ARG_ENABLE(xcsecurity,     AS_HELP_STRING([--enable-xcsecurity], [Build Security extension (default: disabled)]), [XCSECURITY=$enableval], [XCSECURITY=no])
-AC_ARG_ENABLE(tslib,          AS_HELP_STRING([--enable-tslib], [Build kdrive tslib touchscreen support (default: disabled)]), [TSLIB=$enableval], [TSLIB=no])
-AC_ARG_ENABLE(dbe,            AS_HELP_STRING([--disable-dbe], [Build DBE extension (default: enabled)]), [DBE=$enableval], [DBE=yes])
-AC_ARG_ENABLE(xf86bigfont,    AS_HELP_STRING([--enable-xf86bigfont], [Build XF86 Big Font extension (default: disabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=no])
-AC_ARG_ENABLE(dpms,           AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
-AC_ARG_ENABLE(config-udev,    AS_HELP_STRING([--enable-config-udev], [Build udev support (default: auto)]), [CONFIG_UDEV=$enableval], [CONFIG_UDEV=auto])
-AC_ARG_ENABLE(config-dbus,    AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no])
-AC_ARG_ENABLE(config-hal,     AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto])
-AC_ARG_ENABLE(xfree86-utils,     AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes])
-AC_ARG_ENABLE(xaa,               AS_HELP_STRING([--enable-xaa], [Build XAA (default: enabled)]), [XAA=$enableval], [XAA=yes])
-AC_ARG_ENABLE(vgahw,          AS_HELP_STRING([--enable-vgahw], [Build Xorg with vga access (default: enabled)]), [VGAHW=$enableval], [VGAHW=yes])
-AC_ARG_ENABLE(vbe,            AS_HELP_STRING([--enable-vbe], [Build Xorg with VBE module (default: enabled)]), [VBE=$enableval], [VBE=yes])
-AC_ARG_ENABLE(int10-module,     AS_HELP_STRING([--enable-int10-module], [Build Xorg with int10 module (default: enabled)]), [INT10MODULE=$enableval], [INT10MODULE=yes])
-AC_ARG_ENABLE(windowswm,      AS_HELP_STRING([--enable-windowswm], [Build XWin with WindowsWM extension (default: no)]), [WINDOWSWM=$enableval], [WINDOWSWM=no])
-AC_ARG_ENABLE(libdrm,         AS_HELP_STRING([--enable-libdrm], [Build Xorg with libdrm support (default: enabled)]), [DRM=$enableval],[DRM=yes])
-AC_ARG_ENABLE(clientids,      AS_HELP_STRING([--disable-clientids], [Build Xorg with client ID tracking (default: enabled)]), [CLIENTIDS=$enableval], [CLIENTIDS=yes])
-
-dnl DDXes.
-AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
-AC_ARG_ENABLE(dmx,    	      AS_HELP_STRING([--enable-dmx], [Build DMX server (default: auto)]), [DMX=$enableval], [DMX=auto])
-AC_ARG_ENABLE(xvfb,    	      AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes])
-AC_ARG_ENABLE(xnest,   	      AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
-AC_ARG_ENABLE(xquartz,        AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
-AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
-AC_ARG_ENABLE(xwin,    	      AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
-dnl kdrive and its subsystems
-AC_ARG_ENABLE(kdrive,         AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no])
-AC_ARG_ENABLE(xephyr,         AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto])
-AC_ARG_ENABLE(xfake,          AS_HELP_STRING([--enable-xfake], [Build the kdrive 'fake' server (default: auto)]), [XFAKE=$enableval], [XFAKE=auto])
-AC_ARG_ENABLE(xfbdev,         AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto])
-dnl kdrive options
-AC_ARG_ENABLE(kdrive-kbd,     AS_HELP_STRING([--enable-kdrive-kbd], [Build kbd driver for kdrive (default: auto)]), [KDRIVE_KBD=$enableval], [KDRIVE_KBD=auto])
-AC_ARG_ENABLE(kdrive-mouse,   AC_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto])
-AC_ARG_ENABLE(kdrive-evdev,   AC_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto])
-
-
-dnl chown/chmod to be setuid root as part of build
-dnl Replaces InstallXserverSetUID in imake
-AC_ARG_ENABLE(install-setuid, 
-    AS_HELP_STRING([--enable-install-setuid],
-       [Install Xorg server as owned by root with setuid bit (default: auto)]),
-    [SETUID=$enableval], [SETUID=auto])
-AC_MSG_CHECKING([to see if we can install the Xorg server as root])
-if test "x$SETUID" = "xauto" ; then
-	case $host_os in
-	    cygwin*)		SETUID="no"  ;;
-	    darwin*)		SETUID="no"  ;;
-	    *)
-	   	case $host_cpu in
-		    sparc)	SETUID="no"  ;;
-		    *)		SETUID="yes" ;;
-		esac
-	esac
-	if test "x$SETUID" = xyes; then
-		touch testfile
-		chown root testfile > /dev/null 2>&1 || SETUID="no"
-		rm -f testfile
-	fi
-fi
-AC_MSG_RESULT([$SETUID])
-AM_CONDITIONAL(INSTALL_SETUID, [test "x$SETUID" = "xyes"])
-
-dnl Issue an error if xtrans.m4 was not found and XTRANS_CONNECTION_FLAGS macro
-dnl was not expanded, since xorg-server with no transport types is rather useless.
-dnl
-dnl If you're seeing an error here, be sure you installed the lib/xtrans module
-dnl first and if it's not in the default location, that you set the ACLOCAL
-dnl environment variable to find it, such as:
-dnl	ACLOCAL="aclocal -I ${PREFIX}/share/aclocal"
-m4_pattern_forbid([^XTRANS_CONNECTION_FLAGS$])
-
-# Transport selection macro from xtrans.m4
-XTRANS_CONNECTION_FLAGS
-
-# Secure RPC detection macro from xtrans.m4
-XTRANS_SECURE_RPC_FLAGS
-AM_CONDITIONAL(SECURE_RPC, [test "x$SECURE_RPC" = xyes])
-
-AM_CONDITIONAL(INT10_VM86, [test "x$INT10" = xvm86])
-AM_CONDITIONAL(INT10_X86EMU, [test "x$INT10" = xx86emu])
-AM_CONDITIONAL(INT10_STUB, [test "x$INT10" = xstub])
-if test "x$INT10" = xyes; then
-	dnl VM86 headers
-	AC_CHECK_HEADERS([sys/vm86.h sys/io.h])
-fi
-
-XORG_ENABLE_DOCS
-XORG_ENABLE_DEVEL_DOCS
-XORG_WITH_XMLTO(0.0.20)
-XORG_WITH_FOP
-
-dnl Handle installing libxf86config
-AM_CONDITIONAL(INSTALL_LIBXF86CONFIG, [test "x$INSTALL_LIBXF86CONFIG" = xyes])
-
-dnl DDX Detection... Yes, it's ugly to have it here... but we need to
-dnl handle this early on so that we don't require unsupported extensions
-case $host_os in
-	cygwin*)
-		DGA=no
-		DRI2=no
-		XF86VIDMODE=no
-		XSELINUX=no
-		XV=no
-		;;
-	darwin*)
-		DRI2=no
-
-		if test x$XQUARTZ = xauto; then
-			AC_CACHE_CHECK([whether to build Xquartz],xorg_cv_Carbon_framework,[
-		 		save_LDFLAGS=$LDFLAGS
-				LDFLAGS="$LDFLAGS -framework Carbon"
-				AC_LINK_IFELSE([char FSFindFolder(); int main() { FSFindFolder(); return 0;}],
-				[xorg_cv_Carbon_framework=yes],
-				[xorg_cv_Carbon_framework=no])
-			LDFLAGS=$save_LDFLAGS])
-                
-			if test "X$xorg_cv_Carbon_framework" = Xyes; then
-				XQUARTZ=yes
-			else
-				XQUARTZ=no
-			fi
-		fi
-
-		if test "x$XQUARTZ" = xyes ; then
-			XQUARTZ=yes
-			XVFB=no
-			XNEST=no
-
-			COMPOSITE=no
-			DGA=no
-			DPMSExtension=no
-			XF86VIDMODE=no
-		fi
-		;;
-	*) XQUARTZ=no ;;
-esac
-
-dnl ---------------------------------------------------------------------------
-dnl Extension section
-dnl ---------------------------------------------------------------------------
-XEXT_INC='-I$(top_srcdir)/Xext'
-XEXT_LIB='$(top_builddir)/Xext/libXext.la'
-XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
-
-dnl Optional modules
-VIDEOPROTO="videoproto"
-COMPOSITEPROTO="compositeproto >= 0.4"
-RECORDPROTO="recordproto >= 1.13.99.1"
-SCRNSAVERPROTO="scrnsaverproto >= 1.1"
-RESOURCEPROTO="resourceproto"
-DRIPROTO="xf86driproto >= 2.1.0"
-DRI2PROTO="dri2proto >= 2.3"
-XINERAMAPROTO="xineramaproto"
-BIGFONTPROTO="xf86bigfontproto >= 1.2.0"
-DGAPROTO="xf86dgaproto >= 2.0.99.1"
-GLPROTO="glproto >= 1.4.10"
-DMXPROTO="dmxproto >= 2.2.99.1"
-VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1"
-WINDOWSWMPROTO="windowswmproto"
-APPLEWMPROTO="applewmproto >= 1.4"
-
-dnl Core modules for most extensions, et al.
-SDK_REQUIRED_MODULES="[xproto >= 7.0.17] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto"
-# Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc
-AC_SUBST(SDK_REQUIRED_MODULES)
-
-dnl List of libraries that require a specific version
-LIBAPPLEWM="applewm >= 1.4"
-LIBDMX="dmx >= 1.0.99.1"
-LIBDRI="dri >= 7.8.0"
-LIBDRM="libdrm >= 2.3.0"
-LIBGL="gl >= 7.1.0"
-LIBXEXT="xext >= 1.0.99.4"
-LIBXFONT="xfont >= 1.4.2"
-LIBXI="xi >= 1.2.99.1"
-LIBXTST="xtst >= 1.0.99.2"
-LIBPCIACCESS="pciaccess >= 0.8.0"
-LIBGLIB="glib-2.0 >= 2.16"
-LIBUDEV="libudev >= 143"
-LIBSELINUX="libselinux >= 2.0.86"
-LIBDBUS="dbus-1 >= 1.0"
-LIBPIXMAN="pixman-1 >= 0.21.6"
-
-dnl Pixman is always required, but we separate it out so we can link
-dnl specific modules against it
-PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
-REQUIRED_LIBS="$REQUIRED_LIBS $LIBPIXMAN $LIBXFONT xau"
-
-REQUIRED_MODULES="[fixesproto >= 4.1] [damageproto >= 1.1] [xcmiscproto >= 1.2.0] [xtrans >= 1.2.2] [bigreqsproto >= 1.1.0] $SDK_REQUIRED_MODULES"
-
-if test "x$CONFIG_UDEV" = xyes &&
- { test "x$CONFIG_DBUS_API" = xyes || test "x$CONFIG_HAL" = xyes; }; then
-	AC_MSG_ERROR([Hotplugging through both libudev and dbus/hal not allowed])
-fi
-
-PKG_CHECK_MODULES(UDEV, $LIBUDEV, [HAVE_LIBUDEV=yes], [HAVE_LIBUDEV=no])
-if test "x$CONFIG_UDEV" = xauto; then
-	CONFIG_UDEV="$HAVE_LIBUDEV"
-fi
-AM_CONDITIONAL(CONFIG_UDEV, [test "x$CONFIG_UDEV" = xyes])
-if test "x$CONFIG_UDEV" = xyes; then
-	CONFIG_DBUS_API=no
-	CONFIG_HAL=no
-	if ! test "x$HAVE_LIBUDEV" = xyes; then
-		AC_MSG_ERROR([udev configuration API requested, but libudev is not installed])
-	fi
-	AC_DEFINE(CONFIG_UDEV, 1, [Use libudev for input hotplug])
-fi
-
-dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
-dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
-dnl API.
-PKG_CHECK_MODULES(DBUS, $LIBDBUS, [HAVE_DBUS=yes], [HAVE_DBUS=no])
-if test "x$HAVE_DBUS" = xyes; then
-	AC_DEFINE(HAVE_DBUS, 1, [Have D-Bus support])
-fi
-AM_CONDITIONAL(HAVE_DBUS, [test "x$HAVE_DBUS" = xyes])
-
-if test "x$CONFIG_DBUS_API" = xauto; then
-	CONFIG_DBUS_API="$HAVE_DBUS"
-fi
-if test "x$CONFIG_DBUS_API" = xyes; then
-	if ! test "x$HAVE_DBUS" = xyes; then
-		AC_MSG_ERROR([D-Bus configuration API requested, but D-Bus is not installed.])
-	fi
-
-	AC_DEFINE(CONFIG_DBUS_API, 1, [Use the D-Bus input configuration API])
-	CONFIG_NEED_DBUS="yes"
-fi
-AM_CONDITIONAL(CONFIG_DBUS_API, [test "x$CONFIG_DBUS_API" = xyes])
-
-PKG_CHECK_MODULES(HAL, hal, [HAVE_HAL=yes], [HAVE_HAL=no])
-if test "x$CONFIG_HAL" = xauto; then
-	CONFIG_HAL="$HAVE_HAL"
-fi
-if test "x$CONFIG_HAL" = xyes; then
-	if ! test "x$HAVE_HAL" = xyes; then
-		AC_MSG_ERROR([HAL hotplug API requested, but HAL is not installed.])
-	fi
-
-	AC_DEFINE(CONFIG_HAL, 1, [Use the HAL hotplug API])
-	CONFIG_NEED_DBUS="yes"
-fi
-AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes])
-
-if test "x$CONFIG_NEED_DBUS" = xyes; then
-        AC_DEFINE(CONFIG_NEED_DBUS, 1, [Use D-Bus for input hotplug])
-fi
-AM_CONDITIONAL(CONFIG_NEED_DBUS, [test "x$CONFIG_NEED_DBUS" = xyes])
-
-if test "x$USE_SIGIO_BY_DEFAULT" = xyes; then
-	USE_SIGIO_BY_DEFAULT_VALUE=TRUE
-else
-	USE_SIGIO_BY_DEFAULT_VALUE=FALSE
-fi
-AC_DEFINE_UNQUOTED([USE_SIGIO_BY_DEFAULT], [$USE_SIGIO_BY_DEFAULT_VALUE],
-		   [Use SIGIO handlers for input device events by default])
-
-AC_MSG_CHECKING([for glibc...])
-AC_PREPROC_IFELSE([
-#include <features.h>
-#ifndef __GLIBC__
-#error
-#endif
-], glibc=yes, glibc=no)
-AC_MSG_RESULT([$glibc])
-
-AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes],
-               [AC_CHECK_LIB([rt], [clock_gettime], [have_clock_gettime=-lrt],
-                             [have_clock_gettime=no])])
-
-AC_MSG_CHECKING([for a useful monotonic clock ...])
-
-if ! test "x$have_clock_gettime" = xno; then
-    if ! test "x$have_clock_gettime" = xyes; then
-        CLOCK_LIBS="$have_clock_gettime"
-    else
-        CLOCK_LIBS=""
-    fi
-
-    LIBS_SAVE="$LIBS"
-    LIBS="$CLOCK_LIBS"
-    CPPFLAGS_SAVE="$CPPFLAGS"
-
-    if test x"$glibc" = xyes; then
-        CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=200112L"
-    fi
-
-    AC_RUN_IFELSE([
-#include <time.h>
-
-int main(int argc, char *argv[[]]) {
-    struct timespec tp;
-
-    if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
-        return 0;
-    else
-        return 1;
-}
-    ], [MONOTONIC_CLOCK=yes], [MONOTONIC_CLOCK=no],
-       [MONOTONIC_CLOCK="cross compiling"])
-
-    LIBS="$LIBS_SAVE"
-    CPPFLAGS="$CPPFLAGS_SAVE"
-else
-    MONOTONIC_CLOCK=no
-fi
-
-AC_MSG_RESULT([$MONOTONIC_CLOCK])
-
-if test "x$MONOTONIC_CLOCK" = xyes; then
-    AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()])
-    LIBS="$LIBS $CLOCK_LIBS"
-fi
-
-AM_CONDITIONAL(XV, [test "x$XV" = xyes])
-if test "x$XV" = xyes; then
-	AC_DEFINE(XV, 1, [Support Xv extension])
-	AC_DEFINE(XvExtension, 1, [Build Xv extension])
-	REQUIRED_MODULES="$REQUIRED_MODULES $VIDEOPROTO"
-	SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $VIDEOPROTO"
-else
-	XVMC=no
-fi
-
-AM_CONDITIONAL(XVMC, [test "x$XVMC" = xyes])
-if test "x$XVMC" = xyes; then
-	AC_DEFINE(XvMCExtension, 1, [Build XvMC extension])
-fi
-
-AM_CONDITIONAL(XREGISTRY, [test "x$XREGISTRY" = xyes])
-if test "x$XREGISTRY" = xyes; then
-	AC_DEFINE(XREGISTRY, 1, [Build registry module])
-fi
-
-AM_CONDITIONAL(COMPOSITE, [test "x$COMPOSITE" = xyes])
-if test "x$COMPOSITE" = xyes; then
-	AC_DEFINE(COMPOSITE, 1, [Support Composite Extension])
-	REQUIRED_MODULES="$REQUIRED_MODULES $COMPOSITEPROTO"
-	COMPOSITE_LIB='$(top_builddir)/composite/libcomposite.la'
-	COMPOSITE_INC='-I$(top_srcdir)/composite'
-fi
-
-AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes])
-if test "x$MITSHM" = xyes; then
-	AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension])
-	AC_DEFINE(HAS_SHM, 1, [Support SHM])
-fi
-
-AM_CONDITIONAL(RECORD, [test "x$RECORD" = xyes])
-if test "x$RECORD" = xyes; then
-	AC_DEFINE(XRECORD, 1, [Support Record extension])
-	REQUIRED_MODULES="$REQUIRED_MODULES $RECORDPROTO"
-	RECORD_LIB='$(top_builddir)/record/librecord.la'
-fi
-
-AM_CONDITIONAL(SCREENSAVER, [test "x$SCREENSAVER" = xyes])
-if test "x$SCREENSAVER" = xyes; then
-	AC_DEFINE(SCREENSAVER, 1, [Support MIT-SCREEN-SAVER extension])
-	REQUIRED_MODULES="$REQUIRED_MODULES $SCRNSAVERPROTO"
-fi
-
-AM_CONDITIONAL(RES, [test "x$RES" = xyes])
-if test "x$RES" = xyes; then
-	AC_DEFINE(RES, 1, [Support X resource extension])
-	REQUIRED_MODULES="$REQUIRED_MODULES $RESOURCEPROTO"
-fi
-
-# The XRes extension may support client ID tracking only if it has
-# been specifically enabled. Client ID tracking is implicitly not
-# supported if XRes extension is disabled.
-AC_MSG_CHECKING([whether to track client ids])
-if test "x$RES" = xyes && test "x$CLIENTIDS" = xyes; then
-	AC_DEFINE(CLIENTIDS, 1, [Support client ID tracking])
-else
-	CLIENTIDS=no
-fi
-AC_MSG_RESULT([$CLIENTIDS])
-AM_CONDITIONAL(CLIENTIDS, [test "x$CLIENTIDS" = xyes])
-
-if test "x$GLX" = xyes; then
-	PKG_CHECK_MODULES([XLIB], [x11])
-	PKG_CHECK_MODULES([GL], $GLPROTO $LIBGL)
-	AC_SUBST(XLIB_CFLAGS)
-	AC_DEFINE(GLXEXT, 1, [Build GLX extension])
-	GLX_LIBS='$(top_builddir)/glx/libglx.la'
-	GLX_SYS_LIBS="$GLX_SYS_LIBS"
-else
-        GLX=no
-fi
-AM_CONDITIONAL(GLX, test "x$GLX" = xyes)
-
-if test "x$AIGLX" = xyes -a "x$GLX" = xyes -a "x$DRI" = xyes; then
-	AC_DEFINE(AIGLX, 1, [Build AIGLX loader])
-else
-	AIGLX=no
-fi
-AM_CONDITIONAL(AIGLX, test "x$AIGLX" = xyes)
-
-if test "x$GLX_USE_TLS" = xyes ; then
-	GLX_DEFINES="-DGLX_USE_TLS -DPTHREADS"
-	GLX_SYS_LIBS="$GLX_SYS_LIBS -lpthread"
-fi
-AC_SUBST([GLX_DEFINES])
-
-AM_CONDITIONAL(DRI, test "x$DRI" = xyes)
-if test "x$DRI" = xyes; then
-	AC_DEFINE(XF86DRI, 1, [Build DRI extension])
-	PKG_CHECK_MODULES([DRIPROTO], [$DRIPROTO])
-	PKG_CHECK_MODULES([DRI], $GLPROTO $LIBDRI)
-	AC_SUBST(DRIPROTO_CFLAGS)
-fi
-
-PKG_CHECK_MODULES([DRI2PROTO], $DRI2PROTO,
-                  [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no])
-case "$DRI2,$HAVE_DRI2PROTO" in
-	yes,no)
-		AC_MSG_ERROR([DRI2 requested, but dri2proto not found.])
-		;;
-	yes,yes | auto,yes)
-		AC_DEFINE(DRI2, 1, [Build DRI2 extension])
-		DRI2=yes
-		SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $DRI2PROTO"
-		;;
-esac
-AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
-
-if test "x$DRI" = xyes || test "x$DRI2" = xyes; then
-	if test "x$DRM" = xyes; then
-		AC_DEFINE(WITH_LIBDRM, 1, [Building with libdrm support])
-		PKG_CHECK_MODULES([LIBDRM], $LIBDRM)
-	fi
-fi
-
-if test "x$DRI2" = xyes; then
-	save_CFLAGS=$CFLAGS
-	CFLAGS="$GL_CFLAGS $LIBDRM_CFLAGS"
-	AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <GL/gl.h>
-#include <GL/internal/dri_interface.h>
-#ifndef __DRI_DRI2
-#error DRI2 extension not available.
-#endif]])],
-			  [HAVE_DRI2EXTENSION=yes],
-			  [HAVE_DRI2EXTENSION=no])
-	CFLAGS=$save_CFLAGS
-	if test "x$HAVE_DRI2EXTENSION" = xyes; then
-		AC_DEFINE(DRI2_AIGLX, 1, [Build DRI2 AIGLX loader])
-		DRI2_AIGLX=yes
-	else
-		AC_MSG_NOTICE([DRI2 AIGLX disabled, __DRI_DRI2 not defined in dri_interface.h.])
-		DRI2_AIGLX=no
-	fi
-fi
-AM_CONDITIONAL(DRI2_AIGLX, test "x$DRI2_AIGLX" = xyes)
-
-
-AM_CONDITIONAL(XINERAMA, [test "x$XINERAMA" = xyes])
-if test "x$XINERAMA" = xyes; then
-	AC_DEFINE(XINERAMA, 1, [Support Xinerama extension])
-	AC_DEFINE(PANORAMIX, 1, [Internal define for Xinerama])
-	REQUIRED_MODULES="$REQUIRED_MODULES $XINERAMAPROTO"
-	SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $XINERAMAPROTO"
-fi
-
-AM_CONDITIONAL(XACE, [test "x$XACE" = xyes])
-if test "x$XACE" = xyes; then
-	AC_DEFINE(XACE, 1, [Build X-ACE extension])
-fi
-
-AM_CONDITIONAL(XSELINUX, [test "x$XSELINUX" = xyes])
-if test "x$XSELINUX" = xyes; then
-	if test "x$XACE" != xyes; then
-		AC_MSG_ERROR([cannot build SELinux extension without X-ACE])
-	fi
-	AC_CHECK_HEADERS([libaudit.h], [], AC_MSG_ERROR([SELinux extension requires audit system headers]))
-	AC_CHECK_LIB(audit, audit_open, [], AC_MSG_ERROR([SELinux extension requires audit system library]))
-	PKG_CHECK_MODULES([SELINUX], $LIBSELINUX)
-	SELINUX_LIBS="$SELINUX_LIBS -laudit"
-	AC_DEFINE(XSELINUX, 1, [Build SELinux extension])
-fi
-
-AM_CONDITIONAL(XCSECURITY, [test "x$XCSECURITY" = xyes])
-if test "x$XCSECURITY" = xyes; then
-	if test "x$XACE" != xyes; then
-		AC_MSG_ERROR([cannot build Security extension without X-ACE])
-	fi
-	AC_DEFINE(XCSECURITY, 1, [Build Security extension])
-fi
-
-AM_CONDITIONAL(DBE, [test "x$DBE" = xyes])
-if test "x$DBE" = xyes; then
-	AC_DEFINE(DBE, 1, [Support DBE extension])
-	DBE_LIB='$(top_builddir)/dbe/libdbe.la'
-fi
-
-AM_CONDITIONAL(XF86BIGFONT, [test "x$XF86BIGFONT" = xyes])
-if test "x$XF86BIGFONT" = xyes; then
-	AC_DEFINE(XF86BIGFONT, 1, [Support XF86 Big font extension])
-	REQUIRED_MODULES="$REQUIRED_MODULES $BIGFONTPROTO"
-fi
-
-AM_CONDITIONAL(DPMSExtension, [test "x$DPMSExtension" = xyes])
-if test "x$DPMSExtension" = xyes; then
-	AC_DEFINE(DPMSExtension, 1, [Support DPMS extension])
-fi
-
-AC_DEFINE(RENDER, 1, [Support RENDER extension])
-RENDER_LIB='$(top_builddir)/render/librender.la'
-RENDER_INC='-I$(top_srcdir)/render'
-
-AC_DEFINE(RANDR, 1, [Support RANDR extension])
-RANDR_LIB='$(top_builddir)/randr/librandr.la'
-RANDR_INC='-I$(top_srcdir)/randr'
-
-AC_DEFINE(XFIXES,1,[Support XFixes extension])
-FIXES_LIB='$(top_builddir)/xfixes/libxfixes.la'
-FIXES_INC='-I$(top_srcdir)/xfixes'
-
-AC_DEFINE(DAMAGE,1,[Support Damage extension])
-DAMAGE_LIB='$(top_builddir)/damageext/libdamageext.la'
-DAMAGE_INC='-I$(top_srcdir)/damageext'
-MIEXT_DAMAGE_LIB='$(top_builddir)/miext/damage/libdamage.la'
-MIEXT_DAMAGE_INC='-I$(top_srcdir)/miext/damage'
-
-# XINPUT extension is integral part of the server
-AC_DEFINE(XINPUT, 1, [Support X Input extension])
-XI_LIB='$(top_builddir)/Xi/libXi.la'
-XI_INC='-I$(top_srcdir)/Xi'
-
-AM_CONDITIONAL(XF86UTILS, test "x$XF86UTILS" = xyes)
-AM_CONDITIONAL(XAA, test "x$XAA" = xyes)
-AM_CONDITIONAL(VGAHW, test "x$VGAHW" = xyes)
-AM_CONDITIONAL(VBE, test "x$VBE" = xyes)
-AM_CONDITIONAL(INT10MODULE, test "x$INT10MODULE" = xyes)
-
-AC_DEFINE(SHAPE, 1, [Support SHAPE extension])
-
-AC_DEFINE_DIR(XKB_BASE_DIRECTORY, XKBPATH, [Path to XKB data])
-AC_ARG_WITH(xkb-bin-directory,
-				AS_HELP_STRING([--with-xkb-bin-directory=DIR], [Directory containing xkbcomp program]),
-				[XKB_BIN_DIRECTORY="$withval"],
-				[XKB_BIN_DIRECTORY="$bindir"])
-
-AC_DEFINE_DIR(XKB_BIN_DIRECTORY, XKB_BIN_DIRECTORY, [Path to XKB bin dir])
-
-dnl Make sure XKM_OUTPUT_DIR is an absolute path
-XKBOUTPUT_FIRSTCHAR=`echo $XKBOUTPUT | cut -b 1`
-if [[ x$XKBOUTPUT_FIRSTCHAR != x/ -a x$XKBOUTPUT_FIRSTCHAR != 'x$' ]] ; then
-   XKBOUTPUT="$XKB_BASE_DIRECTORY/$XKBOUTPUT"
-fi
-
-dnl XKM_OUTPUT_DIR (used in code) must end in / or file names get hosed
-dnl XKB_COMPILED_DIR (used in Makefiles) must not or install-sh gets confused
-
-XKBOUTPUT=`echo $XKBOUTPUT/ | $SED 's|/*$|/|'`
-XKB_COMPILED_DIR=`echo $XKBOUTPUT | $SED 's|/*$||'`
-AC_DEFINE_DIR(XKM_OUTPUT_DIR, XKBOUTPUT, [Path to XKB output dir])
-AC_SUBST(XKB_COMPILED_DIR)
-
-if test "x$XKB_DFLT_RULES" = x; then
-    case $host_os in
-    linux*)
-        dnl doesn't take AutoAddDevices into account, but whatever.
-        if test "x$CONFIG_HAL" = xyes; then
-            XKB_DFLT_RULES="evdev"
-        else
-            XKB_DFLT_RULES="base"
-        fi
-        ;;
-    *)
-        XKB_DFLT_RULES="base"
-        ;;
-    esac
-fi
-AC_DEFINE_UNQUOTED(XKB_DFLT_RULES, ["$XKB_DFLT_RULES"], [Default XKB ruleset])
-AC_DEFINE_UNQUOTED(XKB_DFLT_MODEL, ["$XKB_DFLT_MODEL"], [Default XKB model])
-AC_DEFINE_UNQUOTED(XKB_DFLT_LAYOUT, ["$XKB_DFLT_LAYOUT"], [Default XKB layout])
-AC_DEFINE_UNQUOTED(XKB_DFLT_VARIANT, ["$XKB_DFLT_VARIANT"], [Default XKB variant])
-AC_DEFINE_UNQUOTED(XKB_DFLT_OPTIONS, ["$XKB_DFLT_OPTIONS"], [Default XKB options])
-
-XKB_LIB='$(top_builddir)/xkb/libxkb.la'
-XKB_STUB_LIB='$(top_builddir)/xkb/libxkbstubs.la'
-REQUIRED_MODULES="$REQUIRED_MODULES xkbfile"
-
-AC_CHECK_FUNC(strcasecmp, [], AC_DEFINE([NEED_STRCASECMP], 1,
-                                        [Do not have 'strcasecmp'.]))
-AC_CHECK_FUNC(strncasecmp, [], AC_DEFINE([NEED_STRNCASECMP], 1,
-                                        [Do not have 'strncasecmp'.]))
-AC_CHECK_FUNC(strcasestr, [], AC_DEFINE([NEED_STRCASESTR], 1,
-                                       [Do not have 'strcasestr'.]))
-
-PKG_CHECK_MODULES([XDMCP], [xdmcp], [have_libxdmcp="yes"], [have_libxdmcp="no"])
-if test "x$have_libxdmcp" = xyes; then
-	AC_CHECK_LIB(Xdmcp, XdmcpWrap, [have_xdmcpwrap="yes"], [have_xdmcpwrap="no"], [$XDMCP_LIBS])
-fi
-if test "x$XDMCP" = xauto; then
-	if test "x$have_libxdmcp" = xyes; then
-		XDMCP=yes
-	else
-		XDMCP=no
-	fi
-fi
-if test "x$XDMAUTH" = xauto; then
-	if test "x$have_libxdmcp" = xyes && test "x$have_xdmcpwrap" = xyes; then
-		XDMAUTH=yes
-	else
-		XDMAUTH=no
-	fi
-fi
-
-AM_CONDITIONAL(XDMCP, [test "x$XDMCP" = xyes])
-if test "x$XDMCP" = xyes; then
-	AC_DEFINE(XDMCP, 1, [Support XDM Control Protocol])
-	REQUIRED_LIBS="$REQUIRED_LIBS xdmcp"
-	XDMCP_MODULES="xdmcp"
-fi
-
-AM_CONDITIONAL(XDMAUTH, [test "x$XDMAUTH" = xyes])
-if test "x$XDMAUTH" = xyes; then
-	AC_DEFINE(HASXDMAUTH,1,[Support XDM-AUTH*-1])
-	if ! test "x$XDMCP" = xyes; then
-		REQUIRED_LIBS="$REQUIRED_LIBS xdmcp"
-		XDMCP_MODULES="xdmcp"
-	fi
-fi
-
-AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path])
-AC_DEFINE_DIR(PCI_TXT_IDS_PATH, PCI_TXT_IDS_DIR, [Default PCI text file ID path])
-AC_DEFINE_DIR(SERVER_MISC_CONFIG_PATH, SERVERCONFIG, [Server miscellaneous config path])
-AC_DEFINE_DIR(BASE_FONT_PATH, FONTROOTDIR, [Default base font path])
-dridriverdir=`$PKG_CONFIG --variable=dridriverdir dri`
-AC_DEFINE_DIR(DRI_DRIVER_PATH, dridriverdir, [Default DRI driver path])
-AC_DEFINE_UNQUOTED(XVENDORNAME, ["$VENDOR_NAME"], [Vendor name])
-AC_DEFINE_UNQUOTED(XVENDORNAMESHORT, ["$VENDOR_NAME_SHORT"], [Short vendor name])
-AC_DEFINE_UNQUOTED(XORG_DATE, ["$RELEASE_DATE"], [Vendor release])
-AC_DEFINE_UNQUOTED(XORG_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version])
-AC_DEFINE_UNQUOTED(BUILDERADDR, ["$BUILDERADDR"], [Builder address])
-
-if test -z "$OSNAME"; then
-    OSNAME="UNKNOWN"
-fi
-
-AC_DEFINE_UNQUOTED(OSNAME, ["$OSNAME"], [Operating System Name])
-AC_DEFINE_UNQUOTED(OSVENDOR, ["$OSVENDOR"], [Operating System Vendor])
-AC_DEFINE_UNQUOTED(BUILDERSTRING, ["$BUILDERSTRING"], [Builder string])
-
-AC_SUBST([VENDOR_NAME_SHORT])
-AC_DEFINE_UNQUOTED(VENDOR_NAME, ["$VENDOR_NAME"], [Vendor name])
-AC_DEFINE_UNQUOTED(VENDOR_NAME_SHORT, ["$VENDOR_NAME_SHORT"], [Vendor name])
-AC_DEFINE_UNQUOTED(VENDOR_RELEASE, [$VENDOR_RELEASE], [Vendor release])
-AC_DEFINE_UNQUOTED(VENDOR_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version])
-
-AC_DEFINE(NO_LIBCWRAPPER, 1, [Define to 1 if modules should avoid the libcwrapper])
-
-if test "x$DEBUGGING" = xyes; then
-       AC_DEFINE(DEBUG, 1, [Enable debugging code])
-fi
-AM_CONDITIONAL(DEBUG, [test "x$DEBUGGING" = xyes])
-
-# If unittests aren't explicitly disabled, check for required support
-if test "x$UNITTESTS" != xno ; then
-       PKG_CHECK_MODULES([GLIB], $LIBGLIB,
-                         [HAVE_GLIB=yes], [HAVE_GLIB=no])
-
-       # Check if linker supports -wrap, passed via compiler flags
-       # When cross-compiling, reports no, since unit tests run from
-       # "make check", so would be running on build machine,  not target
-       AC_MSG_CHECKING([whether the linker supports -wrap])
-       save_LDFLAGS="$LDFLAGS"
-       LDFLAGS="$LDFLAGS -Wl,-wrap,exit"
-       AC_RUN_IFELSE([AC_LANG_PROGRAM([[
-	void __wrap_exit (int s)
-	{
-	    __real_exit (0);
-	}]],
-	[[exit (1);]])],
-                     [linker_can_wrap="yes"],
-                     [linker_can_wrap="no"],
-                     [linker_can_wrap="no"])
-       AC_MSG_RESULT([$linker_can_wrap])
-       LDFLAGS="$save_LDFLAGS"
-fi
-
-if test "x$UNITTESTS" = xauto; then
-       if test "x$HAVE_GLIB" = xyes && test "x$linker_can_wrap" = xyes; then
-           UNITTESTS=yes
-       else
-           UNITTESTS=no
-       fi
-fi
-if test "x$UNITTESTS" = xyes; then
-       if test "x$HAVE_GLIB" = xno; then
-           AC_MSG_ERROR([glib required to build unit tests])
-       fi
-       if test "x$linker_can_wrap" = xno; then
-           AC_MSG_ERROR([ld -wrap support required to build unit tests])
-       fi
-       AC_DEFINE(UNITTESTS, 1, [Enable unit tests])
-       AC_SUBST([GLIB_LIBS])
-       AC_SUBST([GLIB_CFLAGS])
-fi
-AM_CONDITIONAL(UNITTESTS, [test "x$UNITTESTS" = xyes])
-
-AC_DEFINE(XTEST, 1, [Support XTest extension])
-AC_DEFINE(XSYNC, 1, [Support XSync extension])
-AC_DEFINE(XCMISC, 1, [Support XCMisc extension])
-AC_DEFINE(BIGREQS, 1, [Support BigRequests extension])
-
-if test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" ; then
-  DIX_LIB='$(top_builddir)/dix/dix.O'
-  OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS)'
-else
-  DIX_LIB='$(top_builddir)/dix/libdix.la'
-  OS_LIB='$(top_builddir)/os/libos.la'
-fi
-AC_SUBST([DIX_LIB])
-AC_SUBST([OS_LIB])
-
-MAIN_LIB='$(top_builddir)/dix/libmain.la'
-AC_SUBST([MAIN_LIB])
-
-MI_LIB='$(top_builddir)/mi/libmi.la'
-MI_EXT_LIB='$(top_builddir)/mi/libmiext.la'
-MI_INC='-I$(top_srcdir)/mi'
-FB_LIB='$(top_builddir)/fb/libfb.la'
-FB_INC='-I$(top_srcdir)/fb'
-MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow'
-MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la'
-MIEXT_SYNC_INC='-I$(top_srcdir)/miext/sync'
-MIEXT_SYNC_LIB='$(top_builddir)/miext/sync/libsync.la'
-CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include'
-
-# SHA1 hashing
-AC_ARG_WITH([sha1],
-            [AS_HELP_STRING([--with-sha1=libc|libmd|libgcrypt|libcrypto|libsha1|CommonCrypto],
-                            [choose SHA1 implementation])])
-AC_CHECK_FUNC([SHA1Init], [HAVE_SHA1_IN_LIBC=yes])
-if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_LIBC" = xyes; then
-	with_sha1=libc
-fi
-if test "x$with_sha1" = xlibc && test "x$HAVE_SHA1_IN_LIBC" != xyes; then
-	AC_MSG_ERROR([libc requested but not found])
-fi
-if test "x$with_sha1" = xlibc; then
-	AC_DEFINE([HAVE_SHA1_IN_LIBC], [1],
-		[Use libc SHA1 functions])
-	SHA1_LIBS=""
-fi
-AC_CHECK_FUNC([CC_SHA1_Init], [HAVE_SHA1_IN_COMMONCRYPTO=yes])
-if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_COMMONCRYPTO" = xyes; then
-	with_sha1=CommonCrypto
-fi
-if test "x$with_sha1" = xCommonCrypto && test "x$HAVE_SHA1_IN_COMMONCRYPTO" != xyes; then
-	AC_MSG_ERROR([CommonCrypto requested but not found])
-fi
-if test "x$with_sha1" = xCommonCrypto; then
-	AC_DEFINE([HAVE_SHA1_IN_COMMONCRYPTO], [1],
-		[Use CommonCrypto SHA1 functions])
-	SHA1_LIBS=""
-fi
-AC_CHECK_LIB([md], [SHA1Init], [HAVE_LIBMD=yes])
-if test "x$with_sha1" = x && test "x$HAVE_LIBMD" = xyes; then
-	with_sha1=libmd
-fi
-if test "x$with_sha1" = xlibmd && test "x$HAVE_LIBMD" != xyes; then
-	AC_MSG_ERROR([libmd requested but not found])
-fi
-if test "x$with_sha1" = xlibmd; then
-	AC_DEFINE([HAVE_SHA1_IN_LIBMD], [1],
-	          [Use libmd SHA1 functions])
-	SHA1_LIBS=-lmd
-fi
-PKG_CHECK_MODULES([LIBSHA1], [libsha1], [HAVE_LIBSHA1=yes], [HAVE_LIBSHA1=no])
-if test "x$with_sha1" = x && test "x$HAVE_LIBSHA1" = xyes; then
-   with_sha1=libsha1
-fi
-if test "x$with_sha1" = xlibsha1 && test "x$HAVE_LIBSHA1" != xyes; then
-	AC_MSG_ERROR([libsha1 requested but not found])
-fi
-if test "x$with_sha1" = xlibsha1; then
-	AC_DEFINE([HAVE_SHA1_IN_LIBSHA1], [1],
-	          [Use libsha1 for SHA1])
-	SHA1_LIBS=-lsha1
-fi
-AC_CHECK_LIB([gcrypt], [gcry_md_open], [HAVE_LIBGCRYPT=yes])
-if test "x$with_sha1" = x && test "x$HAVE_LIBGCRYPT" = xyes; then
-	with_sha1=libgcrypt
-fi
-if test "x$with_sha1" = xlibgcrypt && test "x$HAVE_LIBGCRYPT" != xyes; then
-	AC_MSG_ERROR([libgcrypt requested but not found])
-fi
-if test "x$with_sha1" = xlibgcrypt; then
-	AC_DEFINE([HAVE_SHA1_IN_LIBGCRYPT], [1],
-	          [Use libgcrypt SHA1 functions])
-	SHA1_LIBS=-lgcrypt
-fi
-# We don't need all of the OpenSSL libraries, just libcrypto
-AC_CHECK_LIB([crypto], [SHA1_Init], [HAVE_LIBCRYPTO=yes])
-PKG_CHECK_MODULES([OPENSSL], [openssl], [HAVE_OPENSSL_PKC=yes],
-                  [HAVE_OPENSSL_PKC=no])
-if test "x$HAVE_LIBCRYPTO" = xyes || test "x$HAVE_OPENSSL_PKC" = xyes; then
-	if test "x$with_sha1" = x; then
-		with_sha1=libcrypto
-	fi
-else
-	if test "x$with_sha1" = xlibcrypto; then
-		AC_MSG_ERROR([OpenSSL libcrypto requested but not found])
-	fi
-fi
-if test "x$with_sha1" = xlibcrypto; then
-	if test "x$HAVE_LIBCRYPTO" = xyes; then
-		SHA1_LIBS=-lcrypto
-	else
-		SHA1_LIBS="$OPENSSL_LIBS"
-		SHA1_CFLAGS="$OPENSSL_CFLAGS"
-	fi
-fi
-AC_MSG_CHECKING([for SHA1 implementation])
-if test "x$with_sha1" = x; then
-	AC_MSG_ERROR([No suitable SHA1 implementation found])
-fi
-AC_MSG_RESULT([$with_sha1])
-AC_SUBST(SHA1_LIBS)
-AC_SUBST(SHA1_CFLAGS)
-
-PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS])
-PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
-
-# Autotools has some unfortunate issues with library handling.  In order to
-# get a server to rebuild when a dependency in the tree is changed, it must
-# be listed in SERVERNAME_DEPENDENCIES.  However, no system libraries may be
-# listed there, or some versions of autotools will break (especially if a -L
-# is required to find the library).  So, we keep two sets of libraries
-# detected: NAMESPACE_LIBS for in-tree libraries to be linked against, which
-# will go into the _DEPENDENCIES and _LDADD of the server, and
-# NAMESPACE_SYS_LIBS which will go into only the _LDADD.  The
-# NAMESPACEMODULES_LIBS detected from pkgconfig should always go in
-# NAMESPACE_SYS_LIBS.
-#
-# XSERVER_LIBS is the set of in-tree libraries which all servers require.
-# XSERVER_SYS_LIBS is the set of out-of-tree libraries which all servers
-# require.
-#
-XSERVER_CFLAGS="${XSERVER_CFLAGS} ${XSERVERCFLAGS_CFLAGS}"
-XSERVER_LIBS="$DIX_LIB $MI_LIB $OS_LIB"
-XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
-AC_SUBST([XSERVER_LIBS])
-AC_SUBST([XSERVER_SYS_LIBS])
-
-UTILS_SYS_LIBS="${SYS_LIBS}"
-AC_SUBST([UTILS_SYS_LIBS])
-
-# The Xorg binary needs to export symbols so that they can be used from modules
-# Some platforms require extra flags to do this.   libtool should set the
-# necessary flags for each platform when -export-dynamic is passed to it.
-LD_EXPORT_SYMBOLS_FLAG="-export-dynamic"
-AC_SUBST([LD_EXPORT_SYMBOLS_FLAG])
-
-dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so
-dnl we need to replicate that here until those can all be fixed
-AC_MSG_CHECKING([if SVR4 needs to be defined])
-AC_EGREP_CPP([I_AM_SVR4],[
-#if defined(SVR4) || defined(__svr4__) || defined(__SVR4)
- I_AM_SVR4
-#endif
-],[
-AC_DEFINE([SVR4],1,[Define to 1 on systems derived from System V Release 4])
-AC_MSG_RESULT([yes])], AC_MSG_RESULT([no]))
-
-XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SYNC_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC"
-
-dnl ---------------------------------------------------------------------------
-dnl DDX section.
-dnl ---------------------------------------------------------------------------
-
-dnl Xvfb DDX
-
-AC_MSG_CHECKING([whether to build Xvfb DDX])
-AC_MSG_RESULT([$XVFB])
-AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes])
-
-if test "x$XVFB" = xyes; then
-	XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB"
-	XVFB_SYS_LIBS="$XVFBMODULES_LIBS $GLX_SYS_LIBS"
-	AC_SUBST([XVFB_LIBS])
-	AC_SUBST([XVFB_SYS_LIBS])
-fi
-
-
-dnl Xnest DDX
-
-PKG_CHECK_MODULES(XNESTMODULES, [$LIBXEXT x11 xau $XDMCP_MODULES], [have_xnest=yes], [have_xnest=no])
-AC_MSG_CHECKING([whether to build Xnest DDX])
-if test "x$XNEST" = xauto; then
-	XNEST="$have_xnest"
-fi
-AC_MSG_RESULT([$XNEST])
-AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
-
-if test "x$XNEST" = xyes; then
-	if test "x$have_xnest" = xno; then
-		AC_MSG_ERROR([Xnest build explicitly requested, but required modules not found.])
-	fi
-	XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB"
-	XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS"
-	AC_SUBST([XNEST_LIBS])
-	AC_SUBST([XNEST_SYS_LIBS])
-fi
-
-
-dnl Xorg DDX
-
-AC_MSG_CHECKING([whether to build Xorg DDX])
-if test "x$XORG" = xauto; then
-	XORG="yes"
-	case $host_os in
-		cygwin*) XORG="no" ;;
-		darwin*) XORG="no" ;;
-	esac
-fi
-AC_MSG_RESULT([$XORG])
-
-xorg_bus_linuxpci=no
-xorg_bus_bsdpci=no
-xorg_bus_sparc=no
-
-if test "x$XORG" = xyes; then
-	XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
-	XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
-	XORG_INCS="$XORG_DDXINCS $XORG_OSINCS"
-	XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H"
-	XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB"
-
-	dnl ==================================================================
-	dnl symbol visibility
-	symbol_visibility=
-	have_visibility=disabled
-	if test x$SYMBOL_VISIBILITY != xno; then
-	    AC_MSG_CHECKING(for symbol visibility support)
-	    if test x$GCC = xyes; then
-		VISIBILITY_CFLAGS="-fvisibility=hidden"
-	    else
-		AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
-		if test x$SUNCC = xyes; then
-		    VISIBILITY_CFLAGS="-xldscope=hidden"
-		else
-		    have_visibility=no
-		fi
-	    fi
-	    if test x$have_visibility != xno; then
-		save_CFLAGS="$CFLAGS"
-		CFLAGS="$CFLAGS $VISIBILITY_CFLAGS"
-		AC_TRY_COMPILE(
-		    [#include <X11/Xfuncproto.h>
-		     extern _X_HIDDEN int hidden_int;
-		     extern _X_EXPORT int public_int;
-		     extern _X_HIDDEN int hidden_int_func(void);
-		     extern _X_EXPORT int public_int_func(void);],
-		    [],
-		    have_visibility=yes,
-		    have_visibility=no)
-		CFLAGS=$save_CFLAGS
-	    fi
-	    AC_MSG_RESULT([$have_visibility])
-	    if test x$have_visibility != xno; then
-		symbol_visibility=$VISIBILITY_CFLAGS
-		XORG_CFLAGS="$XORG_CFLAGS $VISIBILITY_CFLAGS"
-		XSERVER_CFLAGS="$XSERVER_CFLAGS $VISIBILITY_CFLAGS"
-	    fi
-	fi
-	dnl added to xorg-server.pc
-	AC_SUBST([symbol_visibility])
-	dnl ===================================================================
-
-	PKG_CHECK_MODULES([PCIACCESS], $LIBPCIACCESS)
-	SAVE_LIBS=$LIBS
-	SAVE_CFLAGS=$CFLAGS
-	CFLAGS=$PCIACCESS_CFLAGS
-	LIBS=$PCIACCESS_LIBS
-	AC_CHECK_FUNCS([pci_system_init_dev_mem])
-	AC_CHECK_FUNCS([pci_device_enable])
-	AC_CHECK_FUNCS([pci_device_is_boot_vga])
-	AC_CHECK_FUNCS([pci_device_vgaarb_init])
-	LIBS=$SAVE_LIBS
-	CFLAGS=$SAVE_CFLAGS
-	XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $GLX_SYS_LIBS"
-	XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS"
-
-	case $host_os in
-	  linux*)
-		if test "x$LNXAPM" = xyes; then
-			XORG_CFLAGS="$XORG_CFLAGS -DXF86PM"
-		fi
-	  	XORG_OS="linux"
-		XORG_OS_SUBDIR="linux"
-		xorg_bus_linuxpci="yes"
-		linux_acpi="no"
-		case $host_cpu in
-		  ia64*)
-			linux_ia64=yes
-			linux_acpi="yes"
-			;;
-		  alpha*)
-		  	linux_alpha=yes
-			;;
-		  i*86|amd64*|x86_64*)
-			linux_acpi="yes"
-			;;
-		  *)
-			;;
-		esac
-		;;
-	  freebsd* | kfreebsd*-gnu | dragonfly*)
-	  	XORG_OS="freebsd"
-		XORG_OS_SUBDIR="bsd"
-		xorg_bus_bsdpci="yes"
-		;;
-	  netbsd*)
-	  	XORG_OS="netbsd"
-		XORG_OS_SUBDIR="bsd"
-		xorg_bus_bsdpci="yes"
-		;;
-	  openbsd*)
-		if test "x$ac_cv_BSD_APM" = xyes \
-			-o "x$ac_cv_BSD_KQUEUE_APM" = xyes; then
-			XORG_CFLAGS="$XORG_CFLAGS -DXF86PM"
-		fi
-	  	XORG_OS="openbsd"
-		XORG_OS_SUBDIR="bsd"
-		xorg_bus_bsdpci="yes"
-		;;
-	  solaris*)
-	  	XORG_OS="solaris"
-		XORG_OS_SUBDIR="solaris"
-		XORG_CFLAGS="$XORG_CFLAGS -DXF86PM"
-		# Use the same stubs as BSD for old functions, since we now
-		# use libpciaccess for PCI
-		xorg_bus_bsdpci="yes"
-		AC_CHECK_HEADERS([sys/kd.h])
-		AC_CHECK_HEADERS([sys/vt.h], [solaris_vt=yes], [solaris_vt=no])
-		# Check for minimum supported release
-		AC_MSG_CHECKING([Solaris version])
-	        OS_MINOR=`echo ${host_os}|$SED -e 's/^.*solaris2\.//' -e s'/\..*$//'`
-		if test "${OS_MINOR}" -ge 7 ; then
-	        	AC_MSG_RESULT(Solaris ${OS_MINOR})
-		else
-			AC_MSG_RESULT(Solaris `echo ${host_os}|$SED -e 's/^.*solaris//`)
-		fi
-		if test "${OS_MINOR}" -lt 8 ; then
-			AC_MSG_ERROR([This release no longer supports Solaris versions older than Solaris 8.])
-		fi
-		AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
-		if test "x$SUNCC" = "xyes"; then
-			solaris_asm_inline="yes"
-		fi
-		AC_CHECK_DECL([_LP64], [SOLARIS_64="yes"], [SOLARIS_64="no"])
-			
-		case $host_cpu in
-		  sparc*)	
-			SOLARIS_INOUT_ARCH="sparcv8plus"
-			;;
-		  i*86)	
-			if test x$SOLARIS_64 = xyes ; then
-				SOLARIS_INOUT_ARCH="amd64"
-			else
-				SOLARIS_INOUT_ARCH="ia32"
-			fi
-			;;
-		  *)
-			AC_MSG_ERROR([Unsupported Solaris platform. Only SPARC & x86 \
-			are supported on Solaris in this release.   If you are \
-			interested in porting Xorg to your platform, please email \
-			xorg@lists.freedesktop.org.]) ;;
-		esac
-		AC_SUBST([SOLARIS_INOUT_ARCH])
-		if test x$solaris_asm_inline = xyes ; then
-			SOLARIS_ASM_CFLAGS='$(top_srcdir)/hw/xfree86/os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il'
-			XORG_CFLAGS="${XORG_CFLAGS} "'$(SOLARIS_ASM_CFLAGS)'
-		fi
-		AC_SUBST([SOLARIS_ASM_CFLAGS])
-		if test "x$SUPPORT_PC98" = xauto; then
-			SUPPORT_PC98="no"
-		fi
-		;;
-	  gnu*)
-	  	XORG_OS="gnu"
-		XORG_OS_SUBDIR="hurd"
-		# Use the same stubs as BSD for old functions, since we now
-		# use libpciaccess for PCI
-		xorg_bus_bsdpci="yes"
-		;;
-	  *)
-	  	XORG_OS="unknown"
-		XORG_OS_SUBDIR="unknown"
-		AC_MSG_ERROR([m4_text_wrap(m4_join([ ],
-		[Your OS is unknown. Xorg currently only supports Linux,],
-		[Free/Open/Net/DragonFlyBSD, Solaris/OpenSolaris, & GNU Hurd.],
-		[If you are interested in porting Xorg to your platform,],
-		[please email xorg@lists.freedesktop.org.]))])
-		;;
-	esac
-
-	case $host_cpu in
-	  sparc*)
-		xorg_bus_sparc="yes"
-		;;
-	  i*86)
-		if test "x$SUPPORT_PC98" = xauto; then
-			SUPPORT_PC98="yes"
-		fi
-		;;
-	esac
-
-	if test "x$SUPPORT_PC98" = xauto; then
-		SUPPORT_PC98="no"
-	fi
-	if test "x$SUPPORT_PC98" = xyes; then
-		AC_DEFINE(SUPPORT_PC98, 1, [Support PC98])
-	fi
-	if test "x$XORG_OS_PCI" = x ; then
-		XORG_OS_PCI=$XORG_OS
-	fi
-	if test "x$DGA" = xauto; then
-		PKG_CHECK_MODULES(DGA, $DGAPROTO, [DGA=yes], [DGA=no])
-	fi
-	if test "x$DGA" = xyes; then
-		XORG_MODULES="$XORG_MODULES $DGAPROTO"
-		PKG_CHECK_MODULES(DGA, $DGAPROTO)
-		AC_DEFINE(DGA, 1, [Support DGA extension])
-		AC_DEFINE(XFreeXDGA, 1, [Build XDGA support])
-	fi
-
-	if test "x$XF86VIDMODE" = xauto; then
-		PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO, [XF86VIDMODE=yes], [XF86VIDMODE=no])
-	fi
-	if test "x$XF86VIDMODE" = xyes; then
-		XORG_MODULES="$XORG_MODULES $VIDMODEPROTO"
-		PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO)
-		AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension])
-	fi
-
-	if test -n "$XORG_MODULES"; then
-	        PKG_CHECK_MODULES(XORG_MODULES, [$XORG_MODULES])
-	        XORG_CFLAGS="$XORG_CFLAGS $XORG_MODULES_CFLAGS"
-	        XORG_SYS_LIBS="$XORG_SYS_LIBS $XORG_MODULES_LIBS"
-	fi
-
-	AC_SUBST([XORG_LIBS])
-	AC_SUBST([XORG_SYS_LIBS])
-	AC_SUBST([XORG_INCS])
-	AC_SUBST([XORG_OS])
-	AC_SUBST([XORG_OS_SUBDIR])
-
-	AC_PATH_PROG(PERL, perl, no)
-	dnl unlikely as this may be ...
-	if test "x$PERL" = xno; then
-		AC_MSG_ERROR([Perl is required to build the XFree86/Xorg DDX.])
-	fi
-	AC_SUBST(PERL)
-
-	AC_SUBST([XORG_CFLAGS])
-
-	dnl these only go in xorg-config.h
-	XF86CONFIGFILE="xorg.conf"
-	XF86CONFIGDIR="xorg.conf.d"
-	AC_SUBST(XF86CONFIGDIR)
-	CONFIGFILE="$sysconfdir/$XF86CONFIGFILE"
-	LOGPREFIX="$logdir/Xorg."
-	AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
-	AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
-	AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
-	AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
-	AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
-	AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
-	AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
-	AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
-	AC_DEFINE_DIR(__XCONFIGFILE__, XF86CONFIGFILE, [Name of configuration file])
-	AC_DEFINE_DIR(XF86CONFIGFILE, XF86CONFIGFILE, [Name of configuration file])
-	AC_DEFINE_DIR(__XCONFIGDIR__, XF86CONFIGDIR, [Name of configuration directory])
-	AC_DEFINE_DIR(DEFAULT_MODULE_PATH, moduledir, [Default module search path])
-	AC_DEFINE_DIR(DEFAULT_LIBRARY_PATH, libdir, [Default library install path])
-	AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location])
-	AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
-	AC_DEFINE(XSERVER_LIBPCIACCESS, 1, [Use libpciaccess for all pci manipulation])
-	if test "x$VGAHW" = xyes; then
-		AC_DEFINE(WITH_VGAHW, 1, [Building vgahw module])
-	fi
-
-	driverdir="$moduledir/drivers"
-	AC_SUBST([moduledir])
-	AC_SUBST([driverdir])
-	sdkdir="$includedir/xorg"
-	extdir="$includedir/X11/extensions"
-	sysconfigdir="$datadir/X11/$XF86CONFIGDIR"
-	AC_SUBST([sdkdir])
-	AC_SUBST([extdir])
-	AC_SUBST([sysconfigdir])
-	AC_SUBST([logdir])
-
-	# stuff the ABI versions into the pc file too
-	extract_abi() {
-	    grep ^.define.*${1}_VERSION ${srcdir}/hw/xfree86/common/xf86Module.h | tr '(),' '  .' | awk '{ print $4$5 }'
-	}
-	abi_ansic=`extract_abi ANSIC`
-	abi_videodrv=`extract_abi VIDEODRV`
-	abi_xinput=`extract_abi XINPUT`
-	abi_extension=`extract_abi EXTENSION`
-	AC_SUBST([abi_ansic])
-	AC_SUBST([abi_videodrv])
-	AC_SUBST([abi_xinput])
-	AC_SUBST([abi_extension])
-fi
-AM_CONDITIONAL([XORG], [test "x$XORG" = xyes])
-AM_CONDITIONAL([XORG_BUS_LINUXPCI], [test "x$xorg_bus_linuxpci" = xyes])
-AM_CONDITIONAL([XORG_BUS_BSDPCI], [test "x$xorg_bus_bsdpci" = xyes])
-AM_CONDITIONAL([XORG_BUS_SPARC], [test "x$xorg_bus_sparc" = xyes])
-AM_CONDITIONAL([LINUX_IA64], [test "x$linux_ia64" = xyes])
-AM_CONDITIONAL([LINUX_ALPHA], [test "x$linux_alpha" = xyes])
-AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes])
-AM_CONDITIONAL([SOLARIS_ASM_INLINE], [test "x$solaris_asm_inline" = xyes])
-AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])
-AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
-AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
-
-dnl XWin DDX
-
-AC_MSG_CHECKING([whether to build XWin DDX])
-if test "x$XWIN" = xauto; then
-	case $host_os in
-		cygwin*) XWIN="yes" ;;
-		mingw*) XWIN="yes" ;;
-		*) XWIN="no" ;;
-	esac
-fi
-AC_MSG_RESULT([$XWIN])
-
-if test "x$XWIN" = xyes; then
-	AC_DEFINE_DIR(SYSCONFDIR, sysconfdir, [Location of system.XWinrc])
-	AC_DEFINE_DIR(DEFAULT_LOGDIR, logdir, [Default log location])
-	AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
-	AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
-	AC_CHECK_TOOL(WINDRES, windres)
-
-	PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau])
-
-	if test "x$WINDOWSWM" = xauto; then
-		PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no])
-	fi
-	if test "x$WINDOWSWM" = xyes ; then
-		PKG_CHECK_MODULES(WINDOWSWM, $WINDOWSWMPROTO)
-		XWINMODULES_CFLAGS="$XWINMODULES_CFLAGS $WINDOWSWM_CFLAGS"
-		AC_DEFINE(ROOTLESS,1,[Build Rootless code])
-	fi
-
-	case $host_os in
-		cygwin*)
-			XWIN_SERVER_NAME=XWin
-			AC_DEFINE(HAS_DEVWINDOWS,1,[Cygwin has /dev/windows for signaling new win32 messages])
-			;;
-		mingw*)
-			XWIN_SERVER_NAME=Xming
-			AC_DEFINE(RELOCATE_PROJECTROOT,1,[Make PROJECT_ROOT relative to the xserver location])
-			AC_DEFINE(HAS_WINSOCK,1,[Use Windows sockets])
-			XWIN_SYS_LIBS=-lwinsock2
-			;;
-	esac
-	XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $RANDR_LIB $RENDER_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB"
-	XWIN_SYS_LIBS="$XWIN_SYS_LIBS $XWINMODULES_LIBS"
-	AC_SUBST(XWIN_LIBS)
-	AC_SUBST(XWIN_SERVER_NAME)
-	AC_SUBST(XWIN_SYS_LIBS)
-
-	if test "x$DEBUGGING" = xyes; then
-		AC_DEFINE(CYGDEBUG, 1, [Simple debug messages])
-		AC_DEFINE(CYGWINDOWING_DEBUG, 1, [Debug messages for window handling])
-		AC_DEFINE(CYGMULTIWINDOW_DEBUG, 1, [Debug window manager])
-	fi
-
-	AC_DEFINE(DDXOSVERRORF, 1, [Use OsVendorVErrorF])
-	AC_DEFINE(DDXBEFORERESET, 1, [Use ddxBeforeReset ])
-fi
-AM_CONDITIONAL(XWIN, [test "x$XWIN" = xyes])
-AM_CONDITIONAL(XWIN_MULTIWINDOW, [test "x$XWIN" = xyes])
-AM_CONDITIONAL(XWIN_MULTIWINDOWEXTWM, [test "x$XWIN" = xyes && test "x$WINDOWSWM" = xyes])
-AM_CONDITIONAL(XWIN_CLIPBOARD, [test "x$XWIN" = xyes])
-AM_CONDITIONAL(XWIN_GLX_WINDOWS, [test "x$XWIN" = xyes && false])
-AM_CONDITIONAL(XWIN_NATIVEGDI, [test "x$XWIN" = xyes])
-AM_CONDITIONAL(XWIN_PRIMARYFB, [test "x$XWIN" = xyes])
-AM_CONDITIONAL(XWIN_RANDR, [test "x$XWIN" = xyes])
-AM_CONDITIONAL(XWIN_XV, [test "x$XWIN" = xyes && test "x$XV" = xyes])
-
-dnl Darwin / OS X DDX
-if test "x$XQUARTZ" = xyes; then
-	AC_DEFINE(XQUARTZ,1,[Have Quartz])
-	AC_DEFINE(ROOTLESS,1,[Build Rootless code])
-
-	DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB"
-	AC_SUBST([DARWIN_LIBS])
-
-	AC_CHECK_LIB([Xplugin],[xp_init],[:])
-
-	CFLAGS="${CFLAGS} -DROOTLESS_WORKAROUND -DROOTLESS_SAFEALPHA -DNO_ALLOCA"
-
-	PKG_CHECK_MODULES(XPBPROXY, $APPLEWMPROTO $LIBAPPLEWM xfixes x11)
-
-        if test "x$XQUARTZ_SPARKLE" = xyes ; then
-                AC_DEFINE(XQUARTZ_SPARKLE,1,[Support application updating through sparkle.])
-        fi
-
-	if test "x$STANDALONE_XPBPROXY" = xyes ; then
-		AC_DEFINE(STANDALONE_XPBPROXY,1,[Build a standalone xpbproxy])
-	fi
-fi
-
-# Support for objc in autotools is minimal and not documented.
-OBJC='$(CC)'
-OBJCLD='$(CCLD)'
-OBJCLINK='$(LINK)'
-OBJCFLAGS='$(CFLAGS)'
-AC_SUBST([OBJC])
-AC_SUBST([OBJCCLD])
-AC_SUBST([OBJCLINK])
-AC_SUBST([OBJCFLAGS])
-# internal, undocumented automake func follows :(
-_AM_DEPENDENCIES([OBJC])
-AM_CONDITIONAL(XQUARTZ, [test "x$XQUARTZ" = xyes])
-AM_CONDITIONAL(XQUARTZ_SPARKLE, [test "x$XQUARTZ_SPARKLE" != "xno"])
-AM_CONDITIONAL(STANDALONE_XPBPROXY, [test "x$STANDALONE_XPBPROXY" = xyes])
-
-dnl DMX DDX
-PKG_CHECK_MODULES(
-	[DMXMODULES],
-	[xmuu $LIBXEXT x11 xrender xfixes $LIBXI $DMXPROTO xau $XDMCP_MODULES],
-	[PKG_CHECK_MODULES(
-		[XDMXCONFIG_DEP],
-		[xaw7 xmu xt xpm x11],
-		[have_dmx=yes],
-		[have_dmx=no])],
-	[have_dmx=no])
-AC_MSG_CHECKING([whether to build Xdmx DDX])
-if test "x$DMX" = xauto; then
-	DMX="$have_dmx"
-	case $host_os in
-		cygwin*) DMX="no" ;;
-		darwin*) DMX="no" ;;
-	esac
-fi
-AC_MSG_RESULT([$DMX])
-AM_CONDITIONAL(DMX, [test "x$DMX" = xyes])
-
-if test "x$DMX" = xyes; then
-	if test "x$have_dmx" = xno; then
-		AC_MSG_ERROR([Xdmx build explicitly requested, but required
-		              modules not found.])
-	fi
-	DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC"
-	XDMX_CFLAGS="$DMXMODULES_CFLAGS"
-	XDMX_LIBS="$FB_LIB $MI_LIB $XEXT_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SYNC_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $COMPOSITE_LIB $DAMAGE_LIB $MAIN_LIB $DIX_LIB $CONFIG_LIB $OS_LIB $FIXES_LIB"
-	XDMX_SYS_LIBS="$DMXMODULES_LIBS"
-	AC_SUBST([XDMX_CFLAGS])
-	AC_SUBST([XDMX_LIBS])
-	AC_SUBST([XDMX_SYS_LIBS])
-
-dnl USB sources in DMX require <linux/input.h>
-	AC_CHECK_HEADER([linux/input.h], DMX_BUILD_USB="yes",
-			DMX_BUILD_USB="no")
-dnl Linux sources in DMX require <linux/keyboard.h>
-	AC_CHECK_HEADER([linux/keyboard.h], DMX_BUILD_LNX="yes",
-			DMX_BUILD_LNX="no")
-	AC_SUBST(XDMXCONFIG_DEP_CFLAGS)
-	AC_SUBST(XDMXCONFIG_DEP_LIBS)
-	PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [$LIBDMX $LIBXEXT x11])
-	AC_SUBST(DMXEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([DMXXMUEXAMPLES_DEP], [$LIBDMX xmu $LIBXEXT x11])
-	AC_SUBST(DMXXMUEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([DMXXIEXAMPLES_DEP], [$LIBDMX $LIBXI $LIBXEXT x11])
-	AC_SUBST(DMXXIEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([XTSTEXAMPLES_DEP], [$LIBXTST $LIBXEXT x11])
-	AC_SUBST(XTSTEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([XRESEXAMPLES_DEP], [xres $LIBXEXT x11])
-	AC_SUBST(XRESEXAMPLES_DEP_LIBS)
-	PKG_CHECK_MODULES([X11EXAMPLES_DEP], [$LIBXEXT x11])
-	AC_SUBST(X11EXAMPLES_DEP_LIBS)
-
-fi
-AM_CONDITIONAL([DMX_BUILD_LNX], [test "x$DMX_BUILD_LNX" = xyes])
-AM_CONDITIONAL([DMX_BUILD_USB], [test "x$DMX_BUILD_USB" = xyes])
-
-dnl kdrive DDX
-
-XEPHYR_LIBS=
-XEPHYR_INCS=
-
-AM_CONDITIONAL(KDRIVE, [test x$KDRIVE = xyes])
-
-if test "$KDRIVE" = yes; then
-    AC_DEFINE(KDRIVESERVER,1,[Build Kdrive X server])
-    AC_DEFINE(KDRIVEDDXACTIONS,,[Build kdrive ddx])
-
-    AC_CHECK_HEADERS([linux/fb.h])
-    if test "$ac_cv_header_linux_fb_h" = yes && test "x$XFBDEV" = xauto; then
-        XFBDEV=yes
-    fi
-
-    if test "x$XFBDEV" = xyes; then
-        KDRIVEFBDEVLIB=yes
-        AC_DEFINE(KDRIVEFBDEV, 1, [Build fbdev-based kdrive server])
-    fi
-
-
-    PKG_CHECK_MODULES([TSLIB], [tslib-0.0], [HAVE_TSLIB="yes"], [HAVE_TSLIB="no"])
-    if test "x$HAVE_TSLIB" = xno; then
-        AC_CHECK_LIB(ts, ts_open, [
-			HAVE_TSLIB="yes"
-			TSLIB_LIBS="-lts"
-		])
-    fi
-
-    if test "xTSLIB" = xauto; then
-        TSLIB="$HAVE_TSLIB"
-    fi
-
-    if test "x$TSLIB" = xyes; then
-        if ! test "x$HAVE_TSLIB" = xyes; then
-            AC_MSG_ERROR([tslib must be installed to build the tslib driver. See http://tslib.berlios.de/])
-        else
-            AC_DEFINE(TSLIB, 1, [Have tslib support])
-        fi
-    fi
-
-    if test "x$KDRIVE_KBD" = xyes; then
-       AC_DEFINE(KDRIVE_KBD, 1, [Enable KDrive kbd driver])
-    fi
-    if test "x$KDRIVE_EVDEV" = xyes; then
-       AC_DEFINE(KDRIVE_EVDEV, 1, [Enable KDrive evdev driver])
-    fi
-    if test "x$KDRIVE_MOUSE" = xyes; then
-       AC_DEFINE(KDRIVE_MOUSE, 1, [Enable KDrive mouse driver])
-    fi
-
-    XEPHYR_REQUIRED_LIBS="x11 $LIBXEXT xau xdmcp"
-    if test "x$XV" = xyes; then
-        XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xv"
-    fi
-    if test "x$DRI" = xyes && test "x$GLX" = xyes; then
-        XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm"
-    fi
-
-    PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"])
-    if test "x$XEPHYR" = xauto; then
-        XEPHYR=$xephyr
-    fi
-    if test "x$XEPHYR" = xyes && test "x$xephyr" = xno; then	
-        AC_MSG_ERROR([Xephyr dependencies missing])
-    fi
-
-    # Xephyr needs nanosleep() which is in librt on Solaris
-    AC_CHECK_FUNC([nanosleep], [],
-        AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt"))
-    
-    # damage shadow extension glx (NOTYET) fb mi
-    KDRIVE_INC='-I$(top_srcdir)/hw/kdrive/src'
-    KDRIVE_PURE_INCS="$KDRIVE_INC $MIEXT_SYNC_INC $MIEXT_DAMAGE_INC $MIEXT_SHADOW_INC $XEXT_INC $FB_INC $MI_INC"
-    KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux'
-    KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC"
-    
-    KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS"
-
-    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB"
-    KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.la'
-    case $host_os in
-	*linux*)
-	    KDRIVE_OS_LIB='$(top_builddir)/hw/kdrive/linux/liblinux.la'
-            KDRIVELINUX=yes
-	    if test "x$KDRIVE_EVDEV" = xauto; then
-		KDRIVE_EVDEV=yes
-	    fi
-	    if test "x$KDRIVE_KBD" = xauto; then
-		KDRIVE_KBD=yes
-	    fi
-	    if test "x$KDRIVE_MOUSE" = xauto; then
-		KDRIVE_MOUSE=yes
-	    fi
-	    ;;
-	*)
-	    if test "x$KDRIVE_EVDEV" = xauto; then
-		KDRIVE_EVDEV=no
-	    fi
-	    if test "x$KDRIVE_KBD" = xauto; then
-		KDRIVE_KBD=no
-	    fi
-	    if test "x$KDRIVE_MOUSE" = xauto; then
-		KDRIVE_MOUSE=no
-	    fi
-	    ;;
-    esac
-    KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.la'
-    KDRIVE_LOCAL_LIBS="$MAIN_LIB $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB"
-    KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
-    KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB"
-    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $GLX_SYS_LIBS $DLOPEN_LIBS $TSLIB_LIBS"
-
-    AC_SUBST([XEPHYR_LIBS])
-    AC_SUBST([XEPHYR_INCS])
-fi
-AC_SUBST([KDRIVE_INCS])
-AC_SUBST([KDRIVE_PURE_INCS])
-AC_SUBST([KDRIVE_CFLAGS])
-AC_SUBST([KDRIVE_PURE_LIBS])
-AC_SUBST([KDRIVE_LOCAL_LIBS])
-AC_SUBST([KDRIVE_LIBS])
-AM_CONDITIONAL(KDRIVELINUX, [test "x$KDRIVELINUX" = xyes])
-AM_CONDITIONAL(KDRIVE_EVDEV, [test "x$KDRIVE_EVDEV" = xyes])
-AM_CONDITIONAL(KDRIVE_KBD,   [test "x$KDRIVE_KBD" = xyes])
-AM_CONDITIONAL(KDRIVE_MOUSE, [test "x$KDRIVE_MOUSE" = xyes])
-AM_CONDITIONAL(TSLIB, [test "x$HAVE_TSLIB" = xyes])
-AM_CONDITIONAL(KDRIVEFBDEV, [test "x$XFBDEV" = xyes])
-AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])
-AM_CONDITIONAL(BUILD_KDRIVEFBDEVLIB, [test "x$KDRIVE" = xyes && test "x$KDRIVEFBDEVLIB" = xyes])
-AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes])
-
-dnl and the rest of these are generic, so they're in config.h
-dnl 
-dnl though, thanks to the passing of some significant amount of time, the
-dnl above is probably a complete fallacy, and you should not rely on it.
-dnl but this is still actually better than imake, honest. -daniels
-
-AC_TRY_COMPILE([
-#include <features.h>
-#ifndef __GLIBC__
-#error not glibc
-#endif
-], [], [AC_DEFINE(_GNU_SOURCE, 1,
-	[ Enable GNU and other extensions to the C environment for glibc])])
-
-AC_DEFINE_DIR(PROJECTROOT, prefix, [Overall prefix])
-
-AC_SUBST([RELEASE_DATE])
-BUILD_DATE="`date +'%Y%m%d'`"
-AC_SUBST([BUILD_DATE])
-BUILD_TIME="`date +'1%H%M%S'`"
-AC_SUBST([BUILD_TIME])
-
-DIX_CFLAGS="-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"
-
-AC_SUBST([DIX_CFLAGS])
-
-AC_SUBST([libdir])
-AC_SUBST([exec_prefix])
-AC_SUBST([prefix])
-
-AC_CONFIG_COMMANDS([sdksyms], [touch hw/xfree86/loader/sdksyms.dep])
-
-AC_OUTPUT([
-Makefile
-glx/Makefile
-include/Makefile
-composite/Makefile
-damageext/Makefile
-dbe/Makefile
-dix/Makefile
-doc/Makefile
-doc/man/Makefile
-doc/xml/Makefile
-doc/xml/dtrace/Makefile
-doc/xml/xserver.ent
-fb/Makefile
-record/Makefile
-config/Makefile
-mi/Makefile
-miext/Makefile
-miext/sync/Makefile
-miext/damage/Makefile
-miext/shadow/Makefile
-miext/cw/Makefile
-miext/rootless/Makefile
-os/Makefile
-randr/Makefile
-render/Makefile
-xkb/Makefile
-Xext/Makefile
-Xi/Makefile
-xfixes/Makefile
-exa/Makefile
-hw/Makefile
-hw/xfree86/Makefile
-hw/xfree86/common/Makefile
-hw/xfree86/common/xf86Build.h
-hw/xfree86/ddc/Makefile
-hw/xfree86/dixmods/Makefile
-hw/xfree86/dixmods/extmod/Makefile
-hw/xfree86/doc/Makefile
-hw/xfree86/doc/devel/Makefile
-hw/xfree86/doc/man/Makefile
-hw/xfree86/doc/sgml/Makefile
-hw/xfree86/dri/Makefile
-hw/xfree86/dri2/Makefile
-hw/xfree86/exa/Makefile
-hw/xfree86/exa/man/Makefile
-hw/xfree86/fbdevhw/Makefile
-hw/xfree86/fbdevhw/man/Makefile
-hw/xfree86/i2c/Makefile
-hw/xfree86/int10/Makefile
-hw/xfree86/loader/Makefile
-hw/xfree86/modes/Makefile
-hw/xfree86/os-support/Makefile
-hw/xfree86/os-support/bsd/Makefile
-hw/xfree86/os-support/bus/Makefile
-hw/xfree86/os-support/hurd/Makefile
-hw/xfree86/os-support/misc/Makefile
-hw/xfree86/os-support/linux/Makefile
-hw/xfree86/os-support/solaris/Makefile
-hw/xfree86/parser/Makefile
-hw/xfree86/ramdac/Makefile
-hw/xfree86/shadowfb/Makefile
-hw/xfree86/vbe/Makefile
-hw/xfree86/vgahw/Makefile
-hw/xfree86/x86emu/Makefile
-hw/xfree86/xaa/Makefile
-hw/xfree86/utils/Makefile
-hw/xfree86/utils/man/Makefile
-hw/xfree86/utils/cvt/Makefile
-hw/xfree86/utils/gtf/Makefile
-hw/dmx/config/Makefile
-hw/dmx/config/man/Makefile
-hw/dmx/doc/Makefile
-hw/dmx/doc/doxygen.conf
-hw/dmx/examples/Makefile
-hw/dmx/input/Makefile
-hw/dmx/glxProxy/Makefile
-hw/dmx/Makefile
-hw/dmx/man/Makefile
-hw/vfb/Makefile
-hw/vfb/man/Makefile
-hw/xnest/Makefile
-hw/xnest/man/Makefile
-hw/xwin/Makefile
-hw/xwin/glx/Makefile
-hw/xwin/man/Makefile
-hw/xquartz/Makefile
-hw/xquartz/GL/Makefile
-hw/xquartz/bundle/Makefile
-hw/xquartz/man/Makefile
-hw/xquartz/mach-startup/Makefile
-hw/xquartz/pbproxy/Makefile
-hw/xquartz/xpr/Makefile
-hw/kdrive/Makefile
-hw/kdrive/ephyr/Makefile
-hw/kdrive/ephyr/man/Makefile
-hw/kdrive/fake/Makefile
-hw/kdrive/fbdev/Makefile
-hw/kdrive/linux/Makefile
-hw/kdrive/src/Makefile
-test/Makefile
-test/xi2/Makefile
-xorg-server.pc
-])
+dnl Copyright © 2003-2007 Keith Packard, Daniel Stone
+dnl
+dnl Permission is hereby granted, free of charge, to any person obtaining a
+dnl copy of this software and associated documentation files (the "Software"),
+dnl to deal in the Software without restriction, including without limitation
+dnl the rights to use, copy, modify, merge, publish, distribute, sublicense,
+dnl and/or sell copies of the Software, and to permit persons to whom the
+dnl Software is furnished to do so, subject to the following conditions:
+dnl
+dnl The above copyright notice and this permission notice (including the next
+dnl paragraph) shall be included in all copies or substantial portions of the
+dnl Software.
+dnl
+dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+dnl IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+dnl THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+dnl DEALINGS IN THE SOFTWARE.
+dnl
+dnl Authors: Keith Packard <keithp@keithp.com>
+dnl          Daniel Stone <daniel@fooishbar.org>
+dnl          an unwitting cast of miscellaneous others
+dnl
+dnl Process this file with autoconf to create configure.
+
+AC_PREREQ(2.57)
+AC_INIT([xorg-server], 1.10.99.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+RELEASE_DATE="unreleased"
+AC_CONFIG_SRCDIR([Makefile.am])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_MAINTAINER_MODE
+
+# Require xorg-macros minimum of 1.10 for XORG_CHECK_SGML_DOCTOOLS
+m4_ifndef([XORG_MACROS_VERSION],
+          [m4_fatal([must install xorg-macros 1.10 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.10)
+XORG_DEFAULT_OPTIONS
+XORG_WITH_DOXYGEN(1.6.1)
+XORG_CHECK_SGML_DOCTOOLS(1.5)
+
+m4_ifndef([XORG_FONT_MACROS_VERSION], [m4_fatal([must install fontutil 1.1 or later before running autoconf/autogen])])
+XORG_FONT_MACROS_VERSION(1.1)
+
+dnl this gets generated by autoheader, and thus contains all the defines.  we
+dnl don't ever actually use it, internally.
+AC_CONFIG_HEADERS(include/do-not-use-config.h)
+dnl xorg-server.h is an external header, designed to be included by loadable
+dnl drivers.
+AC_CONFIG_HEADERS(include/xorg-server.h)
+dnl dix-config.h covers most of the DIX (i.e. everything but the DDX, not just
+dnl dix/).
+AC_CONFIG_HEADERS(include/dix-config.h)
+dnl xorg-config.h covers the Xorg DDX.
+AC_CONFIG_HEADERS(include/xorg-config.h)
+dnl xkb-config.h covers XKB for the Xorg and Xnest DDXs.
+AC_CONFIG_HEADERS(include/xkb-config.h)
+dnl xwin-config.h covers the XWin DDX.
+AC_CONFIG_HEADERS(include/xwin-config.h)
+dnl kdrive-config.h covers the kdrive DDX
+AC_CONFIG_HEADERS(include/kdrive-config.h)
+dnl version-config.h covers the version numbers so they can be bumped without
+dnl forcing an entire recompile.x
+AC_CONFIG_HEADERS(include/version-config.h)
+
+AM_PROG_AS
+AC_PROG_LN_S
+AC_LIBTOOL_WIN32_DLL
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_PROG_MAKE_SET
+PKG_PROG_PKG_CONFIG
+AC_PROG_LEX
+AC_PROG_YACC
+AC_SYS_LARGEFILE
+XORG_PROG_RAWCPP
+
+# Quoted so that make will expand $(CWARNFLAGS) in makefiles to allow
+# easier overrides at build time.
+XSERVER_CFLAGS='$(CWARNFLAGS)'
+
+dnl Check for dtrace program (needed to build Xserver dtrace probes)
+dnl Also checks for <sys/sdt.h>, since some Linux distros have an 
+dnl ISDN trace program named dtrace
+AC_ARG_WITH(dtrace, AS_HELP_STRING([--with-dtrace=PATH],
+	     [Enable dtrace probes (default: enabled if dtrace found)]),
+	     [WDTRACE=$withval], [WDTRACE=auto])
+if test "x$WDTRACE" = "xyes" -o "x$WDTRACE" = "xauto" ; then
+	AC_PATH_PROG(DTRACE, [dtrace], [not_found], [$PATH:/usr/sbin])
+	if test "x$DTRACE" = "xnot_found" ; then
+		if test "x$WDTRACE" = "xyes" ; then
+			AC_MSG_FAILURE([dtrace requested but not found])
+		fi
+		WDTRACE="no"
+	else
+		AC_CHECK_HEADER(sys/sdt.h, [HAS_SDT_H="yes"], [HAS_SDT_H="no"])
+		if test "x$WDTRACE" = "xauto" -a "x$HAS_SDT_H" = "xno" ; then
+			WDTRACE="no"
+		fi
+	fi
+fi
+if test "x$WDTRACE" != "xno" ; then
+  AC_DEFINE(XSERVER_DTRACE, 1, 
+      [Define to 1 if the DTrace Xserver provider probes should be built in.])
+
+# Solaris/OpenSolaris require dtrace -G to build dtrace probe information into
+# object files, and require linking with those as relocatable objects, not .a
+# archives. MacOS X handles all this in the normal compiler toolchain, and on
+# some releases (like Tiger), will error out on dtrace -G.  For now, other
+# platforms with Dtrace ports are assumed to support -G (the FreeBSD and Linux
+# ports appear to, based on my web searches, but have not yet been tested).
+	case $host_os in
+		darwin*)	SPECIAL_DTRACE_OBJECTS=no ;;
+		*)		SPECIAL_DTRACE_OBJECTS=yes ;;
+	esac
+fi
+AM_CONDITIONAL(XSERVER_DTRACE, [test "x$WDTRACE" != "xno"])
+AM_CONDITIONAL(SPECIAL_DTRACE_OBJECTS, [test "x$SPECIAL_DTRACE_OBJECTS" = "xyes"])
+
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h stropts.h fnmatch.h sys/utsname.h])
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_BIGENDIAN([ENDIAN="X_BIG_ENDIAN"], [ENDIAN="X_LITTLE_ENDIAN"])
+
+AC_CHECK_SIZEOF([unsigned long])
+if test "$ac_cv_sizeof_unsigned_long" = 8; then
+	AC_DEFINE(_XSERVER64, 1, [Define to 1 if unsigned long is 64 bits.])
+fi
+
+AC_TYPE_PID_T
+
+# Checks for headers/macros for byte swapping
+# Known variants:
+#	<byteswap.h> bswap_16, bswap_32, bswap_64  (glibc)
+#	<sys/endian.h> __swap16, __swap32, __swap64 (OpenBSD)
+#	<sys/endian.h> bswap16, bswap32, bswap64 (other BSD's)
+#	and a fallback to local macros if none of the above are found
+
+# if <byteswap.h> is found, assume it's the correct version
+AC_CHECK_HEADERS([byteswap.h])
+
+# if <sys/endian.h> is found, have to check which version
+AC_CHECK_HEADER([sys/endian.h], [HAVE_SYS_ENDIAN_H="yes"], [HAVE_SYS_ENDIAN_H="no"])
+
+if test "x$HAVE_SYS_ENDIAN_H" = "xyes" ; then
+	AC_MSG_CHECKING([for __swap16 variant of <sys/endian.h> byteswapping macros])
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([
+#include <sys/types.h>
+#include <sys/endian.h>
+ ], [
+int a = 1, b;
+b = __swap16(a);
+ ])
+], [SYS_ENDIAN__SWAP='yes'], [SYS_ENDIAN__SWAP='no'])
+	AC_MSG_RESULT([$SYS_ENDIAN__SWAP])
+
+	AC_MSG_CHECKING([for bswap16 variant of <sys/endian.h> byteswapping macros])
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([
+#include <sys/types.h>
+#include <sys/endian.h>
+ ], [
+int a = 1, b;
+b = bswap16(a);
+ ])
+], [SYS_ENDIAN_BSWAP='yes'], [SYS_ENDIAN_BSWAP='no'])
+	AC_MSG_RESULT([$SYS_ENDIAN_BSWAP])
+
+    	if test "$SYS_ENDIAN_BSWAP" = "yes" ; then
+		USE_SYS_ENDIAN_H=yes
+		BSWAP=bswap
+	else	
+	    	if test "$SYS_ENDIAN__SWAP" = "yes" ; then
+			USE_SYS_ENDIAN_H=yes
+			BSWAP=__swap
+		else
+			USE_SYS_ENDIAN_H=no
+		fi
+	fi
+
+	if test "$USE_SYS_ENDIAN_H" = "yes" ; then
+	    AC_DEFINE([USE_SYS_ENDIAN_H], 1, 
+		[Define to use byteswap macros from <sys/endian.h>])
+	    AC_DEFINE_UNQUOTED([bswap_16], ${BSWAP}16, 
+			[Define to 16-bit byteswap macro])
+	    AC_DEFINE_UNQUOTED([bswap_32], ${BSWAP}32, 
+			[Define to 32-bit byteswap macro])
+	    AC_DEFINE_UNQUOTED([bswap_64], ${BSWAP}64, 
+			[Define to 64-bit byteswap macro])
+	fi
+fi
+
+dnl Check to see if dlopen is in default libraries (like Solaris, which
+dnl has it in libc), or if libdl is needed to get it.
+AC_CHECK_FUNC([dlopen], [],
+	AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl"))
+AC_SUBST(DLOPEN_LIBS)
+
+dnl Checks for library functions.
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
+		strtol getopt getopt_long vsnprintf walkcontext backtrace \
+		getisax getzoneid shmctl64 strcasestr ffs vasprintf])
+AC_FUNC_ALLOCA
+dnl Old HAS_* names used in os/*.c.
+AC_CHECK_FUNC([getdtablesize],
+	AC_DEFINE(HAS_GETDTABLESIZE, 1, [Have the 'getdtablesize' function.]))
+AC_CHECK_FUNC([getifaddrs],
+	AC_DEFINE(HAS_GETIFADDRS, 1, [Have the 'getifaddrs' function.]))
+AC_CHECK_FUNC([getpeereid],
+	AC_DEFINE(HAS_GETPEEREID, 1, [Have the 'getpeereid' function.]))
+AC_CHECK_FUNC([getpeerucred],
+	AC_DEFINE(HAS_GETPEERUCRED, 1, [Have the 'getpeerucred' function.]))
+AC_CHECK_FUNC([strlcat], HAVE_STRLCAT=yes, HAVE_STRLCAT=no)
+AM_CONDITIONAL(NEED_STRLCAT, [test x$HAVE_STRLCAT = xno])	
+AC_CHECK_FUNC([strlcpy], AC_DEFINE(HAS_STRLCPY, 1, [Have the 'strlcpy' function]))
+
+AM_CONDITIONAL(NEED_VSNPRINTF, [test x$HAVE_VSNPRINTF = xno])
+
+dnl Check for mmap support for Xvfb
+AC_CHECK_FUNC([mmap], AC_DEFINE(HAS_MMAP, 1, [Have the 'mmap' function.]))
+
+dnl Find the math libary
+AC_CHECK_LIB(m, sqrt)
+AC_CHECK_LIB(m, cbrt, AC_DEFINE(HAVE_CBRT, 1, [Have the 'cbrt' function]))
+
+AC_CHECK_HEADERS([ndbm.h dbm.h rpcsvc/dbm.h])
+
+dnl AGPGART headers
+AC_CHECK_HEADERS([linux/agpgart.h sys/agpio.h sys/agpgart.h], AGP=yes)
+AM_CONDITIONAL(AGP, [test "x$AGP" = xyes])
+
+dnl APM header
+AC_CHECK_HEADERS([linux/apm_bios.h], LNXAPM=yes)
+AM_CONDITIONAL(LNXAPM, [test "x$LNXAPM" = xyes])
+
+dnl fbdev header
+AC_CHECK_HEADERS([linux/fb.h], FBDEV=yes)
+AM_CONDITIONAL(FBDEVHW, [test "x$FBDEV" = xyes])
+
+dnl MTRR header
+AC_CHECK_HEADERS([asm/mtrr.h], ac_cv_asm_mtrr_h=yes)
+if test "x$ac_cv_asm_mtrr_h" = xyes; then
+	HAVE_MTRR=yes
+fi
+
+dnl BSD MTRR header
+AC_CHECK_HEADERS([sys/memrange.h], ac_cv_memrange_h=yes)
+if test "x$ac_cv_memrange_h" = xyes; then
+	HAVE_MTRR=yes
+fi
+
+if test "x$HAVE_MTRR" = xyes; then
+	AC_DEFINE(HAS_MTRR_SUPPORT, 1, [MTRR support available])
+fi
+
+dnl A NetBSD MTRR header
+AC_CHECK_HEADERS([machine/mtrr.h], ac_cv_machine_mtrr_h=yes)
+if test "x$ac_cv_machine_mtrr_h" = xyes; then
+	AC_DEFINE(HAS_MTRR_BUILTIN, 1, [Define to 1 if NetBSD built-in MTRR
+		support is available])
+fi
+
+dnl FreeBSD kldload support (sys/linker.h)
+AC_CHECK_HEADERS([sys/linker.h],
+	[ac_cv_sys_linker_h=yes],
+	[ac_cv_sys_linker_h=no],
+	[#include <sys/param.h>])
+AM_CONDITIONAL(FREEBSD_KLDLOAD, [test "x$ac_cv_sys_linker_h" = xyes])
+
+AC_CACHE_CHECK([for SYSV IPC],
+		ac_cv_sysv_ipc,
+		[AC_TRY_LINK([
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+],[
+{ 
+    int id;
+    id = shmget(IPC_PRIVATE, 512, SHM_W | SHM_R);
+    if (id < 0) return -1;
+    return shmctl(id, IPC_RMID, 0);
+}],
+	[ac_cv_sysv_ipc=yes],
+	[ac_cv_sysv_ipc=no])])
+if test "x$ac_cv_sysv_ipc" = xyes; then
+	AC_DEFINE(HAVE_SYSV_IPC, 1, [Define to 1 if SYSV IPC is available])
+fi
+
+dnl OpenBSD /dev/xf86 aperture driver 
+if test -c /dev/xf86 ; then
+	AC_DEFINE(HAS_APERTURE_DRV, 1, [System has /dev/xf86 aperture driver])
+fi
+
+dnl BSD APM support 
+AC_CHECK_HEADER([machine/apmvar.h],[
+	AC_CHECK_HEADER([sys/event.h],
+		ac_cv_BSD_KQUEUE_APM=yes,
+		ac_cv_BSD_APM=yes)])
+
+AM_CONDITIONAL(BSD_APM, [test "x$ac_cv_BSD_APM" = xyes])
+AM_CONDITIONAL(BSD_KQUEUE_APM, [test "x$ac_cv_BSD_KQUEUE_APM" = xyes])
+	
+dnl glibc backtrace support check (hw/xfree86/common/xf86Events.c)
+AC_CHECK_HEADER([execinfo.h],[
+    AC_CHECK_LIB(c, backtrace, [
+        AC_DEFINE(HAVE_BACKTRACE, 1, [Has backtrace support])
+        AC_DEFINE(HAVE_EXECINFO_H, 1, [Have execinfo.h])
+    ])]
+)
+
+dnl ---------------------------------------------------------------------------
+dnl Bus options and CPU capabilities.  Replaces logic in
+dnl hw/xfree86/os-support/bus/Makefile.am, among others.
+dnl ---------------------------------------------------------------------------
+DEFAULT_INT10="x86emu"
+
+dnl Override defaults as needed for specific platforms:
+
+case $host_cpu in
+  alpha*)
+	ALPHA_VIDEO=yes
+	case $host_os in
+	        *freebsd*)	SYS_LIBS=-lio ;;
+		*netbsd*)	AC_DEFINE(USE_ALPHA_PIO, 1, [NetBSD PIO alpha IO]) ;;
+	esac
+	GLX_ARCH_DEFINES="-D__GLX_ALIGN64 -mieee"
+	;;
+  arm*)
+	ARM_VIDEO=yes
+	;;
+  i*86)
+	I386_VIDEO=yes
+	case $host_os in
+		*freebsd*)	AC_DEFINE(USE_DEV_IO) ;;
+		*dragonfly*)	AC_DEFINE(USE_DEV_IO) ;;
+		*netbsd*)	AC_DEFINE(USE_I386_IOPL)
+				SYS_LIBS=-li386
+				;;
+		*openbsd*)	AC_DEFINE(USE_I386_IOPL) 
+				SYS_LIBS=-li386
+				;;
+	esac
+        ;;
+  powerpc*)
+	PPC_VIDEO=yes
+	case $host_os in
+		*freebsd*)	DEFAULT_INT10=stub ;;
+	esac
+	;;
+  sparc*)
+	SPARC64_VIDEO=yes
+	BSD_ARCH_SOURCES="sparc64_video.c ioperm_noop.c"
+	GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
+	;;
+  x86_64*|amd64*)
+	I386_VIDEO=yes
+	case $host_os in
+		*freebsd*)	AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;;
+		*dragonfly*)	AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;;
+		*netbsd*)	AC_DEFINE(USE_I386_IOPL, 1, [BSD i386 iopl])
+				SYS_LIBS=-lx86_64
+				;;
+		*openbsd*)	AC_DEFINE(USE_AMD64_IOPL, 1, [BSD AMD64 iopl])
+				SYS_LIBS=-lamd64
+				;;
+	esac
+	GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
+	;;
+  ia64*)
+  	GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
+	;;
+  s390*)
+  	GLX_ARCH_DEFINES="-D__GLX_ALIGN64"
+	;;
+esac
+AC_SUBST(GLX_ARCH_DEFINES)
+
+dnl BSD *_video.c selection
+AM_CONDITIONAL(ALPHA_VIDEO, [test "x$ALPHA_VIDEO" = xyes])
+AM_CONDITIONAL(ARM_VIDEO, [test "x$ARM_VIDEO" = xyes])
+AM_CONDITIONAL(I386_VIDEO, [test "x$I386_VIDEO" = xyes])
+AM_CONDITIONAL(PPC_VIDEO, [test "x$PPC_VIDEO" = xyes])
+AM_CONDITIONAL(SPARC64_VIDEO, [test "x$SPARC64_VIDEO" = xyes])
+
+DRI=no
+USE_SIGIO_BY_DEFAULT="yes"
+dnl it would be nice to autodetect these *CONS_SUPPORTs
+case $host_os in
+  *freebsd* | *dragonfly*)
+	case $host_os in
+		kfreebsd*-gnu) ;;
+		*) AC_DEFINE(CSRG_BASED, 1, [System is BSD-like]) ;;
+	esac
+	AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console])
+	AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console])
+	AC_DEFINE(SYSCONS_SUPPORT, 1, [System has syscons console])
+	DRI=yes
+	;;
+  *netbsd*)
+	AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
+	AC_DEFINE(PCCONS_SUPPORT, 1, [System has PC console])
+	AC_DEFINE(PCVT_SUPPORT, 1, [System has PCVT console])
+	AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console])
+	DRI=yes
+	;;
+  *openbsd*)
+	AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
+	AC_DEFINE(PCVT_SUPPORT, 1, [System has PC console])
+	AC_DEFINE(WSCONS_SUPPORT, 1, [System has wscons console])
+	;;
+  *linux*)
+	DRI=yes
+	;;
+  *solaris*)
+	PKG_CHECK_EXISTS(libdrm, DRI=yes, DRI=no)
+	# Disable use of SIGIO by default until some system bugs are
+	# fixed - see Sun/OpenSolaris bug id 6879897
+	USE_SIGIO_BY_DEFAULT="no"
+	;;
+  darwin*)
+	AC_DEFINE(CSRG_BASED, 1, [System is BSD-like])
+	;;
+  cygwin*)
+	CFLAGS="$CFLAGS -DFD_SETSIZE=256"
+	;;
+esac
+
+dnl augment XORG_RELEASE_VERSION for our snapshot number and to expose the
+dnl major number
+PVMAJOR=`echo $PACKAGE_VERSION | cut -d . -f 1`
+PVS=`echo $PACKAGE_VERSION | cut -d . -f 4 | cut -d - -f 1`
+if test "x$PVS" = "x"; then
+	PVS="0"
+fi
+
+VENDOR_RELEASE="((($PVMAJOR) * 10000000) + (($PVM) * 100000) + (($PVP) * 1000) + $PVS)"
+VENDOR_MAN_VERSION="Version ${PACKAGE_VERSION}"
+
+VENDOR_NAME="The X.Org Foundation"
+VENDOR_NAME_SHORT="X.Org"
+VENDOR_WEB="http://wiki.x.org"
+
+m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))])
+
+dnl Build options.
+AC_ARG_ENABLE(werror,        AS_HELP_STRING([--enable-werror],
+		  [Obsolete - use --enable-strict-compilation instead]),
+  AC_MSG_ERROR([--enable-werror has been replaced by --enable-strict-compilation]))
+
+AC_ARG_ENABLE(debug,         AS_HELP_STRING([--enable-debug],
+				  [Enable debugging (default: disabled)]),
+			        [DEBUGGING=$enableval], [DEBUGGING=no])
+AC_ARG_ENABLE(unit-tests,    AS_HELP_STRING([--enable-unit-tests],
+                                  [Enable unit-tests (default: auto)]),
+                                [UNITTESTS=$enableval], [UNITTESTS=auto])
+AC_ARG_ENABLE(use-sigio-by-default, AS_HELP_STRING([--enable-use-sigio-by-default]
+  [Enable SIGIO input handlers by default (default: $USE_SIGIO_BY_DEFAULT)]),
+                                [USE_SIGIO_BY_DEFAULT=$enableval], [])
+AC_ARG_WITH(int10,           AS_HELP_STRING([--with-int10=BACKEND], [int10 backend: vm86, x86emu or stub]),
+				[INT10="$withval"],
+				[INT10="$DEFAULT_INT10"])
+AC_ARG_WITH(vendor-name,     AS_HELP_STRING([--with-vendor-name=VENDOR],
+				  [Vendor string reported by the server]),
+				[ VENDOR_NAME="$withval" ], [])
+AC_ARG_WITH(vendor-name-short, AS_HELP_STRING([--with-vendor-name-short=VENDOR],
+				  [Short version of vendor string reported by the server]),
+				[ VENDOR_NAME_SHORT="$withval" ], [])
+AC_ARG_WITH(vendor-web,      AS_HELP_STRING([--with-vendor-web=URL],
+				  [Vendor web address reported by the server]),
+				[ VENDOR_WEB="$withval" ], [])
+AC_ARG_WITH(module-dir,      AS_HELP_STRING([--with-module-dir=DIR],
+				  [Directory where modules are installed (default: $libdir/xorg/modules)]),
+				[ moduledir="$withval" ],
+				[ moduledir="${libdir}/xorg/modules" ])
+AC_ARG_WITH(log-dir,         AS_HELP_STRING([--with-log-dir=DIR],
+				  [Directory where log files are kept (default: $localstatedir/log)]),
+				[ logdir="$withval" ],
+				[ logdir="$localstatedir/log" ])
+AC_ARG_WITH(builder-addr,    AS_HELP_STRING([--with-builder-addr=ADDRESS],
+				  [Builder address (default: xorg@lists.freedesktop.org)]),
+				[ BUILDERADDR="$withval" ],
+				[ BUILDERADDR="xorg@lists.freedesktop.org" ])
+AC_ARG_WITH(os-name,         AS_HELP_STRING([--with-os-name=OSNAME], [Name of OS (default: output of "uname -srm")]),
+				[ OSNAME="$withval" ],
+				[ OSNAME=`uname -srm` ])
+AC_ARG_WITH(os-vendor,       AS_HELP_STRING([--with-os-vendor=OSVENDOR], [Name of OS vendor]),
+				[ OSVENDOR="$withval" ],
+				[ OSVENDOR="" ])
+AC_ARG_WITH(builderstring,   AS_HELP_STRING([--with-builderstring=BUILDERSTRING], [Additional builder string]),
+				[ BUILDERSTRING="$withval" ]
+				[ ])
+
+dnl Determine font path
+XORG_FONTROOTDIR
+XORG_FONTSUBDIR(FONTMISCDIR, fontmiscdir, misc)
+XORG_FONTSUBDIR(FONTOTFDIR, fontotfdir, OTF)
+XORG_FONTSUBDIR(FONTTTFDIR, fontttfdir, TTF)
+XORG_FONTSUBDIR(FONTTYPE1DIR, fonttype1dir, Type1)
+XORG_FONTSUBDIR(FONT75DPIDIR, font75dpidir, 75dpi)
+XORG_FONTSUBDIR(FONT100DPIDIR, font100dpidir, 100dpi)
+
+dnl Uses --default-font-path if set, otherwise checks for /etc/X11/fontpath.d,
+dnl otherwise uses standard subdirectories of FONTROOTDIR. When cross
+dnl compiling, assume default font path uses standard FONTROOTDIR directories.
+DEFAULT_FONT_PATH="${FONTMISCDIR}/,${FONTTTFDIR}/,${FONTOTFDIR}/,${FONTTYPE1DIR}/,${FONT100DPIDIR}/,${FONT75DPIDIR}/"
+if test "$cross_compiling" != yes; then
+	AC_CHECK_FILE([${sysconfdir}/X11/fontpath.d],
+		[DEFAULT_FONT_PATH='catalogue:${sysconfdir}/X11/fontpath.d'],
+		[case $host_os in
+			darwin*) DEFAULT_FONT_PATH="${DEFAULT_FONT_PATH},/Library/Fonts,/System/Library/Fonts" ;;
+		esac])
+fi
+AC_ARG_WITH(default-font-path, AS_HELP_STRING([--with-default-font-path=PATH], [Comma separated list of font dirs]),
+				[ FONTPATH="$withval" ],
+				[ FONTPATH="${DEFAULT_FONT_PATH}" ])
+
+AC_MSG_CHECKING([for default font path])
+AC_MSG_RESULT([$FONTPATH])
+
+AC_ARG_WITH(xkb-path,         AS_HELP_STRING([--with-xkb-path=PATH], [Path to XKB base dir (default: ${datadir}/X11/xkb)]),
+				[ XKBPATH="$withval" ],
+				[ XKBPATH="${datadir}/X11/xkb" ])
+AC_ARG_WITH(xkb-output,       AS_HELP_STRING([--with-xkb-output=PATH], [Path to XKB output dir (default: ${datadir}/X11/xkb/compiled)]),
+				[ XKBOUTPUT="$withval" ],
+				[ XKBOUTPUT="compiled" ])
+AC_ARG_WITH(default-xkb-rules, AS_HELP_STRING([--with-default-xkb-rules=RULES],
+                                   [Keyboard ruleset (default: base/evdev)]),
+                                [ XKB_DFLT_RULES="$withval" ],
+                                [ XKB_DFLT_RULES="" ])
+AC_ARG_WITH(default-xkb-model, AS_HELP_STRING([--with-default-xkb-model=MODEL],
+                                   [Keyboard model (default: pc105)]),
+                                [ XKB_DFLT_MODEL="$withval" ],
+                                [ XKB_DFLT_MODEL="pc105" ])
+AC_ARG_WITH(default-xkb-layout, AS_HELP_STRING([--with-default-xkb-layout=LAYOUT],
+                                   [Keyboard layout (default: us)]),
+                                [ XKB_DFLT_LAYOUT="$withval" ],
+                                [ XKB_DFLT_LAYOUT="us" ])
+AC_ARG_WITH(default-xkb-variant, AS_HELP_STRING([--with-default-xkb-variant=VARIANT],
+                                   [Keyboard variant (default: (none))]),
+                                [ XKB_DFLT_VARIANT="$withval" ],
+                                [ XKB_DFLT_VARIANT="" ])
+AC_ARG_WITH(default-xkb-options, AS_HELP_STRING([--with-default-xkb-options=OPTIONS],
+                                   [Keyboard layout options (default: (none))]),
+                                [ XKB_DFLT_OPTIONS="$withval" ],
+                                [ XKB_DFLT_OPTIONS="" ])
+AC_ARG_WITH(serverconfig-path, AS_HELP_STRING([--with-serverconfig-path=PATH],
+				   [Directory where ancillary server config files are installed (default: ${libdir}/xorg)]),
+				[ SERVERCONFIG="$withval" ],
+				[ SERVERCONFIG="${libdir}/xorg" ])
+AC_ARG_WITH(apple-applications-dir,AS_HELP_STRING([--with-apple-applications-dir=PATH], [Path to the Applications directory (default: /Applications/Utilities)]),
+				[ APPLE_APPLICATIONS_DIR="${withval}" ],
+				[ APPLE_APPLICATIONS_DIR="/Applications/Utilities" ])
+AC_SUBST([APPLE_APPLICATIONS_DIR])
+AC_ARG_WITH(apple-application-name,AS_HELP_STRING([--with-apple-application-name=NAME], [Name for the .app (default: X11)]),
+				[ APPLE_APPLICATION_NAME="${withval}" ],
+				[ APPLE_APPLICATION_NAME="X11" ])
+AC_SUBST([APPLE_APPLICATION_NAME])
+AC_ARG_WITH(launchd-id-prefix,  AS_HELP_STRING([--with-launchd-id-prefix=PATH], [Prefix to use for launchd identifiers (default: org.x)]),
+                                [ LAUNCHD_ID_PREFIX="${withval}" ],
+                                [ LAUNCHD_ID_PREFIX="org.x" ])
+AC_SUBST([LAUNCHD_ID_PREFIX])
+AC_DEFINE_UNQUOTED(LAUNCHD_ID_PREFIX, "$LAUNCHD_ID_PREFIX", [Prefix to use for launchd identifiers])
+AC_ARG_ENABLE(sparkle,AS_HELP_STRING([--enable-sparkle], [Enable updating of X11.app using the Sparkle Framework (default: disabled)]),
+				[ XQUARTZ_SPARKLE="${enableval}" ],
+				[ XQUARTZ_SPARKLE="no" ])
+AC_SUBST([XQUARTZ_SPARKLE])
+AC_ARG_ENABLE(install-libxf86config,
+				AS_HELP_STRING([--enable-install-libxf86config],
+				[Install libxf86config (default: disabled)]),
+				[INSTALL_LIBXF86CONFIG=$enableval],
+				[INSTALL_LIBXF86CONFIG=no])
+AC_ARG_ENABLE(visibility,     AC_HELP_STRING([--enable-visibility], [Enable symbol visibility (default: auto)]),
+				[SYMBOL_VISIBILITY=$enableval],
+				[SYMBOL_VISIBILITY=auto])
+AC_ARG_ENABLE(pc98,     	AC_HELP_STRING([--enable-pc98], [Enable PC98 support in Xorg (default: auto)]),
+				[SUPPORT_PC98=$enableval],
+				[SUPPORT_PC98=auto])
+
+dnl GLX build options
+AC_ARG_ENABLE(aiglx,          AS_HELP_STRING([--enable-aiglx], [Build accelerated indirect GLX (default: enabled)]),
+                                [AIGLX=$enableval],
+                                [AIGLX=yes])
+AX_TLS
+AC_ARG_ENABLE(glx-tls,        AS_HELP_STRING([--enable-glx-tls], [Build GLX with TLS support (default: auto)]),
+                                [GLX_USE_TLS=$enableval],
+                                [GLX_USE_TLS=no
+                                 if test "${ac_cv_tls}" != "none" ; then
+                                   GLX_USE_TLS=yes
+                                 fi])
+AC_SUBST(GLX_TLS, ${GLX_USE_TLS})
+
+dnl Extensions.
+AC_ARG_ENABLE(registry,       AS_HELP_STRING([--disable-registry], [Build string registry module (default: enabled)]), [XREGISTRY=$enableval], [XREGISTRY=yes])
+AC_ARG_ENABLE(composite,      AS_HELP_STRING([--disable-composite], [Build Composite extension (default: enabled)]), [COMPOSITE=$enableval], [COMPOSITE=yes])
+AC_ARG_ENABLE(mitshm,         AS_HELP_STRING([--disable-shm], [Build SHM extension (default: enabled)]), [MITSHM=$enableval], [MITSHM=yes])
+AC_ARG_ENABLE(xres,           AS_HELP_STRING([--disable-xres], [Build XRes extension (default: enabled)]), [RES=$enableval], [RES=yes])
+AC_ARG_ENABLE(record,         AS_HELP_STRING([--disable-record], [Build Record extension (default: enabled)]), [RECORD=$enableval], [RECORD=yes])
+AC_ARG_ENABLE(xv,             AS_HELP_STRING([--disable-xv], [Build Xv extension (default: enabled)]), [XV=$enableval], [XV=yes])
+AC_ARG_ENABLE(xvmc,           AS_HELP_STRING([--disable-xvmc], [Build XvMC extension (default: enabled)]), [XVMC=$enableval], [XVMC=yes])
+AC_ARG_ENABLE(dga,            AS_HELP_STRING([--disable-dga], [Build DGA extension (default: auto)]), [DGA=$enableval], [DGA=auto])
+AC_ARG_ENABLE(screensaver,    AS_HELP_STRING([--disable-screensaver], [Build ScreenSaver extension (default: enabled)]), [SCREENSAVER=$enableval], [SCREENSAVER=yes])
+AC_ARG_ENABLE(xdmcp,          AS_HELP_STRING([--disable-xdmcp], [Build XDMCP extension (default: auto)]), [XDMCP=$enableval], [XDMCP=auto])
+AC_ARG_ENABLE(xdm-auth-1,     AS_HELP_STRING([--disable-xdm-auth-1], [Build XDM-Auth-1 extension (default: auto)]), [XDMAUTH=$enableval], [XDMAUTH=auto])
+AC_ARG_ENABLE(glx,            AS_HELP_STRING([--disable-glx], [Build GLX extension (default: enabled)]), [GLX=$enableval], [GLX=yes])
+AC_ARG_ENABLE(dri,            AS_HELP_STRING([--enable-dri], [Build DRI extension (default: auto)]), [DRI=$enableval])
+AC_ARG_ENABLE(dri2,           AS_HELP_STRING([--enable-dri2], [Build DRI2 extension (default: auto)]), [DRI2=$enableval], [DRI2=auto])
+AC_ARG_ENABLE(xinerama,	      AS_HELP_STRING([--disable-xinerama], [Build Xinerama extension (default: enabled)]), [XINERAMA=$enableval], [XINERAMA=yes])
+AC_ARG_ENABLE(xf86vidmode,    AS_HELP_STRING([--disable-xf86vidmode], [Build XF86VidMode extension (default: auto)]), [XF86VIDMODE=$enableval], [XF86VIDMODE=auto])
+AC_ARG_ENABLE(xace,           AS_HELP_STRING([--disable-xace], [Build X-ACE extension (default: enabled)]), [XACE=$enableval], [XACE=yes])
+AC_ARG_ENABLE(xselinux,       AS_HELP_STRING([--enable-xselinux], [Build SELinux extension (default: disabled)]), [XSELINUX=$enableval], [XSELINUX=no])
+AC_ARG_ENABLE(xcsecurity,     AS_HELP_STRING([--enable-xcsecurity], [Build Security extension (default: disabled)]), [XCSECURITY=$enableval], [XCSECURITY=no])
+AC_ARG_ENABLE(tslib,          AS_HELP_STRING([--enable-tslib], [Build kdrive tslib touchscreen support (default: disabled)]), [TSLIB=$enableval], [TSLIB=no])
+AC_ARG_ENABLE(dbe,            AS_HELP_STRING([--disable-dbe], [Build DBE extension (default: enabled)]), [DBE=$enableval], [DBE=yes])
+AC_ARG_ENABLE(xf86bigfont,    AS_HELP_STRING([--enable-xf86bigfont], [Build XF86 Big Font extension (default: disabled)]), [XF86BIGFONT=$enableval], [XF86BIGFONT=no])
+AC_ARG_ENABLE(dpms,           AS_HELP_STRING([--disable-dpms], [Build DPMS extension (default: enabled)]), [DPMSExtension=$enableval], [DPMSExtension=yes])
+AC_ARG_ENABLE(config-udev,    AS_HELP_STRING([--enable-config-udev], [Build udev support (default: auto)]), [CONFIG_UDEV=$enableval], [CONFIG_UDEV=auto])
+AC_ARG_ENABLE(config-dbus,    AS_HELP_STRING([--enable-config-dbus], [Build D-BUS API support (default: no)]), [CONFIG_DBUS_API=$enableval], [CONFIG_DBUS_API=no])
+AC_ARG_ENABLE(config-hal,     AS_HELP_STRING([--disable-config-hal], [Build HAL support (default: auto)]), [CONFIG_HAL=$enableval], [CONFIG_HAL=auto])
+AC_ARG_ENABLE(xfree86-utils,     AS_HELP_STRING([--enable-xfree86-utils], [Build xfree86 DDX utilities (default: enabled)]), [XF86UTILS=$enableval], [XF86UTILS=yes])
+AC_ARG_ENABLE(xaa,               AS_HELP_STRING([--enable-xaa], [Build XAA (default: enabled)]), [XAA=$enableval], [XAA=yes])
+AC_ARG_ENABLE(vgahw,          AS_HELP_STRING([--enable-vgahw], [Build Xorg with vga access (default: enabled)]), [VGAHW=$enableval], [VGAHW=yes])
+AC_ARG_ENABLE(vbe,            AS_HELP_STRING([--enable-vbe], [Build Xorg with VBE module (default: enabled)]), [VBE=$enableval], [VBE=yes])
+AC_ARG_ENABLE(int10-module,     AS_HELP_STRING([--enable-int10-module], [Build Xorg with int10 module (default: enabled)]), [INT10MODULE=$enableval], [INT10MODULE=yes])
+AC_ARG_ENABLE(windowswm,      AS_HELP_STRING([--enable-windowswm], [Build XWin with WindowsWM extension (default: no)]), [WINDOWSWM=$enableval], [WINDOWSWM=no])
+AC_ARG_ENABLE(libdrm,         AS_HELP_STRING([--enable-libdrm], [Build Xorg with libdrm support (default: enabled)]), [DRM=$enableval],[DRM=yes])
+AC_ARG_ENABLE(clientids,      AS_HELP_STRING([--disable-clientids], [Build Xorg with client ID tracking (default: enabled)]), [CLIENTIDS=$enableval], [CLIENTIDS=yes])
+
+dnl DDXes.
+AC_ARG_ENABLE(xorg,    	      AS_HELP_STRING([--enable-xorg], [Build Xorg server (default: auto)]), [XORG=$enableval], [XORG=auto])
+AC_ARG_ENABLE(dmx,    	      AS_HELP_STRING([--enable-dmx], [Build DMX server (default: auto)]), [DMX=$enableval], [DMX=auto])
+AC_ARG_ENABLE(xvfb,    	      AS_HELP_STRING([--enable-xvfb], [Build Xvfb server (default: yes)]), [XVFB=$enableval], [XVFB=yes])
+AC_ARG_ENABLE(xnest,   	      AS_HELP_STRING([--enable-xnest], [Build Xnest server (default: auto)]), [XNEST=$enableval], [XNEST=auto])
+AC_ARG_ENABLE(xquartz,        AS_HELP_STRING([--enable-xquartz], [Build Xquartz server for OS-X (default: auto)]), [XQUARTZ=$enableval], [XQUARTZ=auto])
+AC_ARG_ENABLE(standalone-xpbproxy, AS_HELP_STRING([--enable-standalone-xpbproxy], [Build a standalone xpbproxy (in addition to the one integrated into Xquartz as a separate thread) (default: no)]), [STANDALONE_XPBPROXY=$enableval], [STANDALONE_XPBPROXY=no])
+AC_ARG_ENABLE(xwin,    	      AS_HELP_STRING([--enable-xwin], [Build XWin server (default: auto)]), [XWIN=$enableval], [XWIN=auto])
+dnl kdrive and its subsystems
+AC_ARG_ENABLE(kdrive,         AS_HELP_STRING([--enable-kdrive], [Build kdrive servers (default: no)]), [KDRIVE=$enableval], [KDRIVE=no])
+AC_ARG_ENABLE(xephyr,         AS_HELP_STRING([--enable-xephyr], [Build the kdrive Xephyr server (default: auto)]), [XEPHYR=$enableval], [XEPHYR=auto])
+AC_ARG_ENABLE(xfake,          AS_HELP_STRING([--enable-xfake], [Build the kdrive 'fake' server (default: auto)]), [XFAKE=$enableval], [XFAKE=auto])
+AC_ARG_ENABLE(xfbdev,         AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto])
+dnl kdrive options
+AC_ARG_ENABLE(kdrive-kbd,     AS_HELP_STRING([--enable-kdrive-kbd], [Build kbd driver for kdrive (default: auto)]), [KDRIVE_KBD=$enableval], [KDRIVE_KBD=auto])
+AC_ARG_ENABLE(kdrive-mouse,   AC_HELP_STRING([--enable-kdrive-mouse], [Build mouse driver for kdrive (default: auto)]), [KDRIVE_MOUSE=$enableval], [KDRIVE_MOUSE=auto])
+AC_ARG_ENABLE(kdrive-evdev,   AC_HELP_STRING([--enable-kdrive-evdev], [Build evdev driver for kdrive (default: auto)]), [KDRIVE_EVDEV=$enableval], [KDRIVE_EVDEV=auto])
+
+
+dnl chown/chmod to be setuid root as part of build
+dnl Replaces InstallXserverSetUID in imake
+AC_ARG_ENABLE(install-setuid, 
+    AS_HELP_STRING([--enable-install-setuid],
+       [Install Xorg server as owned by root with setuid bit (default: auto)]),
+    [SETUID=$enableval], [SETUID=auto])
+AC_MSG_CHECKING([to see if we can install the Xorg server as root])
+if test "x$SETUID" = "xauto" ; then
+	case $host_os in
+	    cygwin*)		SETUID="no"  ;;
+	    darwin*)		SETUID="no"  ;;
+	    *)
+	   	case $host_cpu in
+		    sparc)	SETUID="no"  ;;
+		    *)		SETUID="yes" ;;
+		esac
+	esac
+	if test "x$SETUID" = xyes; then
+		touch testfile
+		chown root testfile > /dev/null 2>&1 || SETUID="no"
+		rm -f testfile
+	fi
+fi
+AC_MSG_RESULT([$SETUID])
+AM_CONDITIONAL(INSTALL_SETUID, [test "x$SETUID" = "xyes"])
+
+dnl Issue an error if xtrans.m4 was not found and XTRANS_CONNECTION_FLAGS macro
+dnl was not expanded, since xorg-server with no transport types is rather useless.
+dnl
+dnl If you're seeing an error here, be sure you installed the lib/xtrans module
+dnl first and if it's not in the default location, that you set the ACLOCAL
+dnl environment variable to find it, such as:
+dnl	ACLOCAL="aclocal -I ${PREFIX}/share/aclocal"
+m4_pattern_forbid([^XTRANS_CONNECTION_FLAGS$])
+
+# Transport selection macro from xtrans.m4
+XTRANS_CONNECTION_FLAGS
+
+# Secure RPC detection macro from xtrans.m4
+XTRANS_SECURE_RPC_FLAGS
+AM_CONDITIONAL(SECURE_RPC, [test "x$SECURE_RPC" = xyes])
+
+AM_CONDITIONAL(INT10_VM86, [test "x$INT10" = xvm86])
+AM_CONDITIONAL(INT10_X86EMU, [test "x$INT10" = xx86emu])
+AM_CONDITIONAL(INT10_STUB, [test "x$INT10" = xstub])
+if test "x$INT10" = xyes; then
+	dnl VM86 headers
+	AC_CHECK_HEADERS([sys/vm86.h sys/io.h])
+fi
+
+XORG_ENABLE_DOCS
+XORG_ENABLE_DEVEL_DOCS
+XORG_WITH_XMLTO(0.0.20)
+XORG_WITH_FOP
+
+dnl Handle installing libxf86config
+AM_CONDITIONAL(INSTALL_LIBXF86CONFIG, [test "x$INSTALL_LIBXF86CONFIG" = xyes])
+
+dnl DDX Detection... Yes, it's ugly to have it here... but we need to
+dnl handle this early on so that we don't require unsupported extensions
+case $host_os in
+	cygwin*)
+		DGA=no
+		DRI2=no
+		XF86VIDMODE=no
+		XSELINUX=no
+		XV=no
+		;;
+	darwin*)
+		DRI2=no
+
+		if test x$XQUARTZ = xauto; then
+			AC_CACHE_CHECK([whether to build Xquartz],xorg_cv_Carbon_framework,[
+		 		save_LDFLAGS=$LDFLAGS
+				LDFLAGS="$LDFLAGS -framework Carbon"
+				AC_LINK_IFELSE([char FSFindFolder(); int main() { FSFindFolder(); return 0;}],
+				[xorg_cv_Carbon_framework=yes],
+				[xorg_cv_Carbon_framework=no])
+			LDFLAGS=$save_LDFLAGS])
+                
+			if test "X$xorg_cv_Carbon_framework" = Xyes; then
+				XQUARTZ=yes
+			else
+				XQUARTZ=no
+			fi
+		fi
+
+		if test "x$XQUARTZ" = xyes ; then
+			XQUARTZ=yes
+			XVFB=no
+			XNEST=no
+
+			COMPOSITE=no
+			DGA=no
+			DPMSExtension=no
+			XF86VIDMODE=no
+		fi
+		;;
+	*) XQUARTZ=no ;;
+esac
+
+dnl ---------------------------------------------------------------------------
+dnl Extension section
+dnl ---------------------------------------------------------------------------
+XEXT_INC='-I$(top_srcdir)/Xext'
+XEXT_LIB='$(top_builddir)/Xext/libXext.la'
+XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
+
+dnl Optional modules
+VIDEOPROTO="videoproto"
+COMPOSITEPROTO="compositeproto >= 0.4"
+RECORDPROTO="recordproto >= 1.13.99.1"
+SCRNSAVERPROTO="scrnsaverproto >= 1.1"
+RESOURCEPROTO="resourceproto"
+DRIPROTO="xf86driproto >= 2.1.0"
+DRI2PROTO="dri2proto >= 2.3"
+XINERAMAPROTO="xineramaproto"
+BIGFONTPROTO="xf86bigfontproto >= 1.2.0"
+DGAPROTO="xf86dgaproto >= 2.0.99.1"
+GLPROTO="glproto >= 1.4.10"
+DMXPROTO="dmxproto >= 2.2.99.1"
+VIDMODEPROTO="xf86vidmodeproto >= 2.2.99.1"
+WINDOWSWMPROTO="windowswmproto"
+APPLEWMPROTO="applewmproto >= 1.4"
+
+dnl Core modules for most extensions, et al.
+SDK_REQUIRED_MODULES="[xproto >= 7.0.17] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto"
+# Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc
+AC_SUBST(SDK_REQUIRED_MODULES)
+
+dnl List of libraries that require a specific version
+LIBAPPLEWM="applewm >= 1.4"
+LIBDMX="dmx >= 1.0.99.1"
+LIBDRI="dri >= 7.8.0"
+LIBDRM="libdrm >= 2.3.0"
+LIBGL="gl >= 7.1.0"
+LIBXEXT="xext >= 1.0.99.4"
+LIBXFONT="xfont >= 1.4.2"
+LIBXI="xi >= 1.2.99.1"
+LIBXTST="xtst >= 1.0.99.2"
+LIBPCIACCESS="pciaccess >= 0.8.0"
+LIBGLIB="glib-2.0 >= 2.16"
+LIBUDEV="libudev >= 143"
+LIBSELINUX="libselinux >= 2.0.86"
+LIBDBUS="dbus-1 >= 1.0"
+LIBPIXMAN="pixman-1 >= 0.21.6"
+
+dnl Pixman is always required, but we separate it out so we can link
+dnl specific modules against it
+PKG_CHECK_MODULES(PIXMAN, $LIBPIXMAN)
+REQUIRED_LIBS="$REQUIRED_LIBS $LIBPIXMAN $LIBXFONT xau"
+
+REQUIRED_MODULES="[fixesproto >= 4.1] [damageproto >= 1.1] [xcmiscproto >= 1.2.0] [xtrans >= 1.2.2] [bigreqsproto >= 1.1.0] $SDK_REQUIRED_MODULES"
+
+if test "x$CONFIG_UDEV" = xyes &&
+ { test "x$CONFIG_DBUS_API" = xyes || test "x$CONFIG_HAL" = xyes; }; then
+	AC_MSG_ERROR([Hotplugging through both libudev and dbus/hal not allowed])
+fi
+
+PKG_CHECK_MODULES(UDEV, $LIBUDEV, [HAVE_LIBUDEV=yes], [HAVE_LIBUDEV=no])
+if test "x$CONFIG_UDEV" = xauto; then
+	CONFIG_UDEV="$HAVE_LIBUDEV"
+fi
+AM_CONDITIONAL(CONFIG_UDEV, [test "x$CONFIG_UDEV" = xyes])
+if test "x$CONFIG_UDEV" = xyes; then
+	CONFIG_DBUS_API=no
+	CONFIG_HAL=no
+	if ! test "x$HAVE_LIBUDEV" = xyes; then
+		AC_MSG_ERROR([udev configuration API requested, but libudev is not installed])
+	fi
+	AC_DEFINE(CONFIG_UDEV, 1, [Use libudev for input hotplug])
+fi
+
+dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
+dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config
+dnl API.
+PKG_CHECK_MODULES(DBUS, $LIBDBUS, [HAVE_DBUS=yes], [HAVE_DBUS=no])
+if test "x$HAVE_DBUS" = xyes; then
+	AC_DEFINE(HAVE_DBUS, 1, [Have D-Bus support])
+fi
+AM_CONDITIONAL(HAVE_DBUS, [test "x$HAVE_DBUS" = xyes])
+
+if test "x$CONFIG_DBUS_API" = xauto; then
+	CONFIG_DBUS_API="$HAVE_DBUS"
+fi
+if test "x$CONFIG_DBUS_API" = xyes; then
+	if ! test "x$HAVE_DBUS" = xyes; then
+		AC_MSG_ERROR([D-Bus configuration API requested, but D-Bus is not installed.])
+	fi
+
+	AC_DEFINE(CONFIG_DBUS_API, 1, [Use the D-Bus input configuration API])
+	CONFIG_NEED_DBUS="yes"
+fi
+AM_CONDITIONAL(CONFIG_DBUS_API, [test "x$CONFIG_DBUS_API" = xyes])
+
+PKG_CHECK_MODULES(HAL, hal, [HAVE_HAL=yes], [HAVE_HAL=no])
+if test "x$CONFIG_HAL" = xauto; then
+	CONFIG_HAL="$HAVE_HAL"
+fi
+if test "x$CONFIG_HAL" = xyes; then
+	if ! test "x$HAVE_HAL" = xyes; then
+		AC_MSG_ERROR([HAL hotplug API requested, but HAL is not installed.])
+	fi
+
+	AC_DEFINE(CONFIG_HAL, 1, [Use the HAL hotplug API])
+	CONFIG_NEED_DBUS="yes"
+fi
+AM_CONDITIONAL(CONFIG_HAL, [test "x$CONFIG_HAL" = xyes])
+
+if test "x$CONFIG_NEED_DBUS" = xyes; then
+        AC_DEFINE(CONFIG_NEED_DBUS, 1, [Use D-Bus for input hotplug])
+fi
+AM_CONDITIONAL(CONFIG_NEED_DBUS, [test "x$CONFIG_NEED_DBUS" = xyes])
+
+if test "x$USE_SIGIO_BY_DEFAULT" = xyes; then
+	USE_SIGIO_BY_DEFAULT_VALUE=TRUE
+else
+	USE_SIGIO_BY_DEFAULT_VALUE=FALSE
+fi
+AC_DEFINE_UNQUOTED([USE_SIGIO_BY_DEFAULT], [$USE_SIGIO_BY_DEFAULT_VALUE],
+		   [Use SIGIO handlers for input device events by default])
+
+AC_MSG_CHECKING([for glibc...])
+AC_PREPROC_IFELSE([
+#include <features.h>
+#ifndef __GLIBC__
+#error
+#endif
+], glibc=yes, glibc=no)
+AC_MSG_RESULT([$glibc])
+
+AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes],
+               [AC_CHECK_LIB([rt], [clock_gettime], [have_clock_gettime=-lrt],
+                             [have_clock_gettime=no])])
+
+AC_MSG_CHECKING([for a useful monotonic clock ...])
+
+if ! test "x$have_clock_gettime" = xno; then
+    if ! test "x$have_clock_gettime" = xyes; then
+        CLOCK_LIBS="$have_clock_gettime"
+    else
+        CLOCK_LIBS=""
+    fi
+
+    LIBS_SAVE="$LIBS"
+    LIBS="$CLOCK_LIBS"
+    CPPFLAGS_SAVE="$CPPFLAGS"
+
+    if test x"$glibc" = xyes; then
+        CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=200112L"
+    fi
+
+    AC_RUN_IFELSE([
+#include <time.h>
+
+int main(int argc, char *argv[[]]) {
+    struct timespec tp;
+
+    if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0)
+        return 0;
+    else
+        return 1;
+}
+    ], [MONOTONIC_CLOCK=yes], [MONOTONIC_CLOCK=no],
+       [MONOTONIC_CLOCK="cross compiling"])
+
+    LIBS="$LIBS_SAVE"
+    CPPFLAGS="$CPPFLAGS_SAVE"
+else
+    MONOTONIC_CLOCK=no
+fi
+
+AC_MSG_RESULT([$MONOTONIC_CLOCK])
+
+if test "x$MONOTONIC_CLOCK" = xyes; then
+    AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()])
+    LIBS="$LIBS $CLOCK_LIBS"
+fi
+
+AM_CONDITIONAL(XV, [test "x$XV" = xyes])
+if test "x$XV" = xyes; then
+	AC_DEFINE(XV, 1, [Support Xv extension])
+	AC_DEFINE(XvExtension, 1, [Build Xv extension])
+	REQUIRED_MODULES="$REQUIRED_MODULES $VIDEOPROTO"
+	SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $VIDEOPROTO"
+else
+	XVMC=no
+fi
+
+AM_CONDITIONAL(XVMC, [test "x$XVMC" = xyes])
+if test "x$XVMC" = xyes; then
+	AC_DEFINE(XvMCExtension, 1, [Build XvMC extension])
+fi
+
+AM_CONDITIONAL(XREGISTRY, [test "x$XREGISTRY" = xyes])
+if test "x$XREGISTRY" = xyes; then
+	AC_DEFINE(XREGISTRY, 1, [Build registry module])
+fi
+
+AM_CONDITIONAL(COMPOSITE, [test "x$COMPOSITE" = xyes])
+if test "x$COMPOSITE" = xyes; then
+	AC_DEFINE(COMPOSITE, 1, [Support Composite Extension])
+	REQUIRED_MODULES="$REQUIRED_MODULES $COMPOSITEPROTO"
+	COMPOSITE_LIB='$(top_builddir)/composite/libcomposite.la'
+	COMPOSITE_INC='-I$(top_srcdir)/composite'
+fi
+
+AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes])
+if test "x$MITSHM" = xyes; then
+	AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension])
+	AC_DEFINE(HAS_SHM, 1, [Support SHM])
+fi
+
+AM_CONDITIONAL(RECORD, [test "x$RECORD" = xyes])
+if test "x$RECORD" = xyes; then
+	AC_DEFINE(XRECORD, 1, [Support Record extension])
+	REQUIRED_MODULES="$REQUIRED_MODULES $RECORDPROTO"
+	RECORD_LIB='$(top_builddir)/record/librecord.la'
+fi
+
+AM_CONDITIONAL(SCREENSAVER, [test "x$SCREENSAVER" = xyes])
+if test "x$SCREENSAVER" = xyes; then
+	AC_DEFINE(SCREENSAVER, 1, [Support MIT-SCREEN-SAVER extension])
+	REQUIRED_MODULES="$REQUIRED_MODULES $SCRNSAVERPROTO"
+fi
+
+AM_CONDITIONAL(RES, [test "x$RES" = xyes])
+if test "x$RES" = xyes; then
+	AC_DEFINE(RES, 1, [Support X resource extension])
+	REQUIRED_MODULES="$REQUIRED_MODULES $RESOURCEPROTO"
+fi
+
+# The XRes extension may support client ID tracking only if it has
+# been specifically enabled. Client ID tracking is implicitly not
+# supported if XRes extension is disabled.
+AC_MSG_CHECKING([whether to track client ids])
+if test "x$RES" = xyes && test "x$CLIENTIDS" = xyes; then
+	AC_DEFINE(CLIENTIDS, 1, [Support client ID tracking])
+else
+	CLIENTIDS=no
+fi
+AC_MSG_RESULT([$CLIENTIDS])
+AM_CONDITIONAL(CLIENTIDS, [test "x$CLIENTIDS" = xyes])
+
+if test "x$GLX" = xyes; then
+	PKG_CHECK_MODULES([XLIB], [x11])
+	PKG_CHECK_MODULES([GL], $GLPROTO $LIBGL)
+	AC_SUBST(XLIB_CFLAGS)
+	AC_DEFINE(GLXEXT, 1, [Build GLX extension])
+	GLX_LIBS='$(top_builddir)/glx/libglx.la'
+	GLX_SYS_LIBS="$GLX_SYS_LIBS"
+else
+        GLX=no
+fi
+AM_CONDITIONAL(GLX, test "x$GLX" = xyes)
+
+if test "x$AIGLX" = xyes -a "x$GLX" = xyes -a "x$DRI" = xyes; then
+	AC_DEFINE(AIGLX, 1, [Build AIGLX loader])
+else
+	AIGLX=no
+fi
+AM_CONDITIONAL(AIGLX, test "x$AIGLX" = xyes)
+
+if test "x$GLX_USE_TLS" = xyes ; then
+	GLX_DEFINES="-DGLX_USE_TLS -DPTHREADS"
+	GLX_SYS_LIBS="$GLX_SYS_LIBS -lpthread"
+fi
+AC_SUBST([GLX_DEFINES])
+
+AM_CONDITIONAL(DRI, test "x$DRI" = xyes)
+if test "x$DRI" = xyes; then
+	AC_DEFINE(XF86DRI, 1, [Build DRI extension])
+	PKG_CHECK_MODULES([DRIPROTO], [$DRIPROTO])
+	PKG_CHECK_MODULES([DRI], $GLPROTO $LIBDRI)
+	AC_SUBST(DRIPROTO_CFLAGS)
+fi
+
+PKG_CHECK_MODULES([DRI2PROTO], $DRI2PROTO,
+                  [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no])
+case "$DRI2,$HAVE_DRI2PROTO" in
+	yes,no)
+		AC_MSG_ERROR([DRI2 requested, but dri2proto not found.])
+		;;
+	yes,yes | auto,yes)
+		AC_DEFINE(DRI2, 1, [Build DRI2 extension])
+		DRI2=yes
+		SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $DRI2PROTO"
+		;;
+esac
+AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
+
+if test "x$DRI" = xyes || test "x$DRI2" = xyes; then
+	if test "x$DRM" = xyes; then
+		AC_DEFINE(WITH_LIBDRM, 1, [Building with libdrm support])
+		PKG_CHECK_MODULES([LIBDRM], $LIBDRM)
+	fi
+fi
+
+if test "x$DRI2" = xyes; then
+	save_CFLAGS=$CFLAGS
+	CFLAGS="$GL_CFLAGS $LIBDRM_CFLAGS"
+	AC_COMPILE_IFELSE([AC_LANG_SOURCE([[#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#ifndef __DRI_DRI2
+#error DRI2 extension not available.
+#endif]])],
+			  [HAVE_DRI2EXTENSION=yes],
+			  [HAVE_DRI2EXTENSION=no])
+	CFLAGS=$save_CFLAGS
+	if test "x$HAVE_DRI2EXTENSION" = xyes; then
+		AC_DEFINE(DRI2_AIGLX, 1, [Build DRI2 AIGLX loader])
+		DRI2_AIGLX=yes
+	else
+		AC_MSG_NOTICE([DRI2 AIGLX disabled, __DRI_DRI2 not defined in dri_interface.h.])
+		DRI2_AIGLX=no
+	fi
+fi
+AM_CONDITIONAL(DRI2_AIGLX, test "x$DRI2_AIGLX" = xyes)
+
+
+AM_CONDITIONAL(XINERAMA, [test "x$XINERAMA" = xyes])
+if test "x$XINERAMA" = xyes; then
+	AC_DEFINE(XINERAMA, 1, [Support Xinerama extension])
+	AC_DEFINE(PANORAMIX, 1, [Internal define for Xinerama])
+	REQUIRED_MODULES="$REQUIRED_MODULES $XINERAMAPROTO"
+	SDK_REQUIRED_MODULES="$SDK_REQUIRED_MODULES $XINERAMAPROTO"
+fi
+
+AM_CONDITIONAL(XACE, [test "x$XACE" = xyes])
+if test "x$XACE" = xyes; then
+	AC_DEFINE(XACE, 1, [Build X-ACE extension])
+fi
+
+AM_CONDITIONAL(XSELINUX, [test "x$XSELINUX" = xyes])
+if test "x$XSELINUX" = xyes; then
+	if test "x$XACE" != xyes; then
+		AC_MSG_ERROR([cannot build SELinux extension without X-ACE])
+	fi
+	AC_CHECK_HEADERS([libaudit.h], [], AC_MSG_ERROR([SELinux extension requires audit system headers]))
+	AC_CHECK_LIB(audit, audit_open, [], AC_MSG_ERROR([SELinux extension requires audit system library]))
+	PKG_CHECK_MODULES([SELINUX], $LIBSELINUX)
+	SELINUX_LIBS="$SELINUX_LIBS -laudit"
+	AC_DEFINE(XSELINUX, 1, [Build SELinux extension])
+fi
+
+AM_CONDITIONAL(XCSECURITY, [test "x$XCSECURITY" = xyes])
+if test "x$XCSECURITY" = xyes; then
+	if test "x$XACE" != xyes; then
+		AC_MSG_ERROR([cannot build Security extension without X-ACE])
+	fi
+	AC_DEFINE(XCSECURITY, 1, [Build Security extension])
+fi
+
+AM_CONDITIONAL(DBE, [test "x$DBE" = xyes])
+if test "x$DBE" = xyes; then
+	AC_DEFINE(DBE, 1, [Support DBE extension])
+	DBE_LIB='$(top_builddir)/dbe/libdbe.la'
+fi
+
+AM_CONDITIONAL(XF86BIGFONT, [test "x$XF86BIGFONT" = xyes])
+if test "x$XF86BIGFONT" = xyes; then
+	AC_DEFINE(XF86BIGFONT, 1, [Support XF86 Big font extension])
+	REQUIRED_MODULES="$REQUIRED_MODULES $BIGFONTPROTO"
+fi
+
+AM_CONDITIONAL(DPMSExtension, [test "x$DPMSExtension" = xyes])
+if test "x$DPMSExtension" = xyes; then
+	AC_DEFINE(DPMSExtension, 1, [Support DPMS extension])
+fi
+
+AC_DEFINE(RENDER, 1, [Support RENDER extension])
+RENDER_LIB='$(top_builddir)/render/librender.la'
+RENDER_INC='-I$(top_srcdir)/render'
+
+AC_DEFINE(RANDR, 1, [Support RANDR extension])
+RANDR_LIB='$(top_builddir)/randr/librandr.la'
+RANDR_INC='-I$(top_srcdir)/randr'
+
+AC_DEFINE(XFIXES,1,[Support XFixes extension])
+FIXES_LIB='$(top_builddir)/xfixes/libxfixes.la'
+FIXES_INC='-I$(top_srcdir)/xfixes'
+
+AC_DEFINE(DAMAGE,1,[Support Damage extension])
+DAMAGE_LIB='$(top_builddir)/damageext/libdamageext.la'
+DAMAGE_INC='-I$(top_srcdir)/damageext'
+MIEXT_DAMAGE_LIB='$(top_builddir)/miext/damage/libdamage.la'
+MIEXT_DAMAGE_INC='-I$(top_srcdir)/miext/damage'
+
+# XINPUT extension is integral part of the server
+AC_DEFINE(XINPUT, 1, [Support X Input extension])
+XI_LIB='$(top_builddir)/Xi/libXi.la'
+XI_INC='-I$(top_srcdir)/Xi'
+
+AM_CONDITIONAL(XF86UTILS, test "x$XF86UTILS" = xyes)
+AM_CONDITIONAL(XAA, test "x$XAA" = xyes)
+AM_CONDITIONAL(VGAHW, test "x$VGAHW" = xyes)
+AM_CONDITIONAL(VBE, test "x$VBE" = xyes)
+AM_CONDITIONAL(INT10MODULE, test "x$INT10MODULE" = xyes)
+
+AC_DEFINE(SHAPE, 1, [Support SHAPE extension])
+
+AC_DEFINE_DIR(XKB_BASE_DIRECTORY, XKBPATH, [Path to XKB data])
+AC_ARG_WITH(xkb-bin-directory,
+				AS_HELP_STRING([--with-xkb-bin-directory=DIR], [Directory containing xkbcomp program]),
+				[XKB_BIN_DIRECTORY="$withval"],
+				[XKB_BIN_DIRECTORY="$bindir"])
+
+AC_DEFINE_DIR(XKB_BIN_DIRECTORY, XKB_BIN_DIRECTORY, [Path to XKB bin dir])
+
+dnl Make sure XKM_OUTPUT_DIR is an absolute path
+XKBOUTPUT_FIRSTCHAR=`echo $XKBOUTPUT | cut -b 1`
+if [[ x$XKBOUTPUT_FIRSTCHAR != x/ -a x$XKBOUTPUT_FIRSTCHAR != 'x$' ]] ; then
+   XKBOUTPUT="$XKB_BASE_DIRECTORY/$XKBOUTPUT"
+fi
+
+dnl XKM_OUTPUT_DIR (used in code) must end in / or file names get hosed
+dnl XKB_COMPILED_DIR (used in Makefiles) must not or install-sh gets confused
+
+XKBOUTPUT=`echo $XKBOUTPUT/ | $SED 's|/*$|/|'`
+XKB_COMPILED_DIR=`echo $XKBOUTPUT | $SED 's|/*$||'`
+AC_DEFINE_DIR(XKM_OUTPUT_DIR, XKBOUTPUT, [Path to XKB output dir])
+AC_SUBST(XKB_COMPILED_DIR)
+
+if test "x$XKB_DFLT_RULES" = x; then
+    case $host_os in
+    linux*)
+        dnl doesn't take AutoAddDevices into account, but whatever.
+        if test "x$CONFIG_HAL" = xyes; then
+            XKB_DFLT_RULES="evdev"
+        else
+            XKB_DFLT_RULES="base"
+        fi
+        ;;
+    *)
+        XKB_DFLT_RULES="base"
+        ;;
+    esac
+fi
+AC_DEFINE_UNQUOTED(XKB_DFLT_RULES, ["$XKB_DFLT_RULES"], [Default XKB ruleset])
+AC_DEFINE_UNQUOTED(XKB_DFLT_MODEL, ["$XKB_DFLT_MODEL"], [Default XKB model])
+AC_DEFINE_UNQUOTED(XKB_DFLT_LAYOUT, ["$XKB_DFLT_LAYOUT"], [Default XKB layout])
+AC_DEFINE_UNQUOTED(XKB_DFLT_VARIANT, ["$XKB_DFLT_VARIANT"], [Default XKB variant])
+AC_DEFINE_UNQUOTED(XKB_DFLT_OPTIONS, ["$XKB_DFLT_OPTIONS"], [Default XKB options])
+
+XKB_LIB='$(top_builddir)/xkb/libxkb.la'
+XKB_STUB_LIB='$(top_builddir)/xkb/libxkbstubs.la'
+REQUIRED_MODULES="$REQUIRED_MODULES xkbfile"
+
+AC_CHECK_FUNC(strcasecmp, [], AC_DEFINE([NEED_STRCASECMP], 1,
+                                        [Do not have 'strcasecmp'.]))
+AC_CHECK_FUNC(strncasecmp, [], AC_DEFINE([NEED_STRNCASECMP], 1,
+                                        [Do not have 'strncasecmp'.]))
+AC_CHECK_FUNC(strcasestr, [], AC_DEFINE([NEED_STRCASESTR], 1,
+                                       [Do not have 'strcasestr'.]))
+
+PKG_CHECK_MODULES([XDMCP], [xdmcp], [have_libxdmcp="yes"], [have_libxdmcp="no"])
+if test "x$have_libxdmcp" = xyes; then
+	AC_CHECK_LIB(Xdmcp, XdmcpWrap, [have_xdmcpwrap="yes"], [have_xdmcpwrap="no"], [$XDMCP_LIBS])
+fi
+if test "x$XDMCP" = xauto; then
+	if test "x$have_libxdmcp" = xyes; then
+		XDMCP=yes
+	else
+		XDMCP=no
+	fi
+fi
+if test "x$XDMAUTH" = xauto; then
+	if test "x$have_libxdmcp" = xyes && test "x$have_xdmcpwrap" = xyes; then
+		XDMAUTH=yes
+	else
+		XDMAUTH=no
+	fi
+fi
+
+AM_CONDITIONAL(XDMCP, [test "x$XDMCP" = xyes])
+if test "x$XDMCP" = xyes; then
+	AC_DEFINE(XDMCP, 1, [Support XDM Control Protocol])
+	REQUIRED_LIBS="$REQUIRED_LIBS xdmcp"
+	XDMCP_MODULES="xdmcp"
+fi
+
+AM_CONDITIONAL(XDMAUTH, [test "x$XDMAUTH" = xyes])
+if test "x$XDMAUTH" = xyes; then
+	AC_DEFINE(HASXDMAUTH,1,[Support XDM-AUTH*-1])
+	if ! test "x$XDMCP" = xyes; then
+		REQUIRED_LIBS="$REQUIRED_LIBS xdmcp"
+		XDMCP_MODULES="xdmcp"
+	fi
+fi
+
+AC_DEFINE_DIR(COMPILEDDEFAULTFONTPATH, FONTPATH, [Default font path])
+AC_DEFINE_DIR(PCI_TXT_IDS_PATH, PCI_TXT_IDS_DIR, [Default PCI text file ID path])
+AC_DEFINE_DIR(SERVER_MISC_CONFIG_PATH, SERVERCONFIG, [Server miscellaneous config path])
+AC_DEFINE_DIR(BASE_FONT_PATH, FONTROOTDIR, [Default base font path])
+dridriverdir=`$PKG_CONFIG --variable=dridriverdir dri`
+AC_DEFINE_DIR(DRI_DRIVER_PATH, dridriverdir, [Default DRI driver path])
+AC_DEFINE_UNQUOTED(XVENDORNAME, ["$VENDOR_NAME"], [Vendor name])
+AC_DEFINE_UNQUOTED(XVENDORNAMESHORT, ["$VENDOR_NAME_SHORT"], [Short vendor name])
+AC_DEFINE_UNQUOTED(XORG_DATE, ["$RELEASE_DATE"], [Vendor release])
+AC_DEFINE_UNQUOTED(XORG_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version])
+AC_DEFINE_UNQUOTED(BUILDERADDR, ["$BUILDERADDR"], [Builder address])
+
+if test -z "$OSNAME"; then
+    OSNAME="UNKNOWN"
+fi
+
+AC_DEFINE_UNQUOTED(OSNAME, ["$OSNAME"], [Operating System Name])
+AC_DEFINE_UNQUOTED(OSVENDOR, ["$OSVENDOR"], [Operating System Vendor])
+AC_DEFINE_UNQUOTED(BUILDERSTRING, ["$BUILDERSTRING"], [Builder string])
+
+AC_SUBST([VENDOR_NAME_SHORT])
+AC_DEFINE_UNQUOTED(VENDOR_NAME, ["$VENDOR_NAME"], [Vendor name])
+AC_DEFINE_UNQUOTED(VENDOR_NAME_SHORT, ["$VENDOR_NAME_SHORT"], [Vendor name])
+AC_DEFINE_UNQUOTED(VENDOR_RELEASE, [$VENDOR_RELEASE], [Vendor release])
+AC_DEFINE_UNQUOTED(VENDOR_MAN_VERSION, ["$VENDOR_MAN_VERSION"], [Vendor man version])
+
+AC_DEFINE(NO_LIBCWRAPPER, 1, [Define to 1 if modules should avoid the libcwrapper])
+
+if test "x$DEBUGGING" = xyes; then
+       AC_DEFINE(DEBUG, 1, [Enable debugging code])
+fi
+AM_CONDITIONAL(DEBUG, [test "x$DEBUGGING" = xyes])
+
+# If unittests aren't explicitly disabled, check for required support
+if test "x$UNITTESTS" != xno ; then
+       PKG_CHECK_MODULES([GLIB], $LIBGLIB,
+                         [HAVE_GLIB=yes], [HAVE_GLIB=no])
+
+       # Check if linker supports -wrap, passed via compiler flags
+       # When cross-compiling, reports no, since unit tests run from
+       # "make check", so would be running on build machine,  not target
+       AC_MSG_CHECKING([whether the linker supports -wrap])
+       save_LDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -Wl,-wrap,exit"
+       AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+	void __wrap_exit (int s)
+	{
+	    __real_exit (0);
+	}]],
+	[[exit (1);]])],
+                     [linker_can_wrap="yes"],
+                     [linker_can_wrap="no"],
+                     [linker_can_wrap="no"])
+       AC_MSG_RESULT([$linker_can_wrap])
+       LDFLAGS="$save_LDFLAGS"
+fi
+
+if test "x$UNITTESTS" = xauto; then
+       if test "x$HAVE_GLIB" = xyes && test "x$linker_can_wrap" = xyes; then
+           UNITTESTS=yes
+       else
+           UNITTESTS=no
+       fi
+fi
+if test "x$UNITTESTS" = xyes; then
+       if test "x$HAVE_GLIB" = xno; then
+           AC_MSG_ERROR([glib required to build unit tests])
+       fi
+       if test "x$linker_can_wrap" = xno; then
+           AC_MSG_ERROR([ld -wrap support required to build unit tests])
+       fi
+       AC_DEFINE(UNITTESTS, 1, [Enable unit tests])
+       AC_SUBST([GLIB_LIBS])
+       AC_SUBST([GLIB_CFLAGS])
+fi
+AM_CONDITIONAL(UNITTESTS, [test "x$UNITTESTS" = xyes])
+
+AC_DEFINE(XTEST, 1, [Support XTest extension])
+AC_DEFINE(XSYNC, 1, [Support XSync extension])
+AC_DEFINE(XCMISC, 1, [Support XCMisc extension])
+AC_DEFINE(BIGREQS, 1, [Support BigRequests extension])
+
+if test "x$SPECIAL_DTRACE_OBJECTS" = "xyes" ; then
+  DIX_LIB='$(top_builddir)/dix/dix.O'
+  OS_LIB='$(top_builddir)/os/os.O $(SHA1_LIBS) $(DLOPEN_LIBS)'
+else
+  DIX_LIB='$(top_builddir)/dix/libdix.la'
+  OS_LIB='$(top_builddir)/os/libos.la'
+fi
+AC_SUBST([DIX_LIB])
+AC_SUBST([OS_LIB])
+
+MAIN_LIB='$(top_builddir)/dix/libmain.la'
+AC_SUBST([MAIN_LIB])
+
+MI_LIB='$(top_builddir)/mi/libmi.la'
+MI_EXT_LIB='$(top_builddir)/mi/libmiext.la'
+MI_INC='-I$(top_srcdir)/mi'
+FB_LIB='$(top_builddir)/fb/libfb.la'
+FB_INC='-I$(top_srcdir)/fb'
+MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow'
+MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la'
+MIEXT_SYNC_INC='-I$(top_srcdir)/miext/sync'
+MIEXT_SYNC_LIB='$(top_builddir)/miext/sync/libsync.la'
+CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include'
+
+# SHA1 hashing
+AC_ARG_WITH([sha1],
+            [AS_HELP_STRING([--with-sha1=libc|libmd|libgcrypt|libcrypto|libsha1|CommonCrypto],
+                            [choose SHA1 implementation])])
+AC_CHECK_FUNC([SHA1Init], [HAVE_SHA1_IN_LIBC=yes])
+if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_LIBC" = xyes; then
+	with_sha1=libc
+fi
+if test "x$with_sha1" = xlibc && test "x$HAVE_SHA1_IN_LIBC" != xyes; then
+	AC_MSG_ERROR([libc requested but not found])
+fi
+if test "x$with_sha1" = xlibc; then
+	AC_DEFINE([HAVE_SHA1_IN_LIBC], [1],
+		[Use libc SHA1 functions])
+	SHA1_LIBS=""
+fi
+AC_CHECK_FUNC([CC_SHA1_Init], [HAVE_SHA1_IN_COMMONCRYPTO=yes])
+if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_COMMONCRYPTO" = xyes; then
+	with_sha1=CommonCrypto
+fi
+if test "x$with_sha1" = xCommonCrypto && test "x$HAVE_SHA1_IN_COMMONCRYPTO" != xyes; then
+	AC_MSG_ERROR([CommonCrypto requested but not found])
+fi
+if test "x$with_sha1" = xCommonCrypto; then
+	AC_DEFINE([HAVE_SHA1_IN_COMMONCRYPTO], [1],
+		[Use CommonCrypto SHA1 functions])
+	SHA1_LIBS=""
+fi
+AC_CHECK_LIB([md], [SHA1Init], [HAVE_LIBMD=yes])
+if test "x$with_sha1" = x && test "x$HAVE_LIBMD" = xyes; then
+	with_sha1=libmd
+fi
+if test "x$with_sha1" = xlibmd && test "x$HAVE_LIBMD" != xyes; then
+	AC_MSG_ERROR([libmd requested but not found])
+fi
+if test "x$with_sha1" = xlibmd; then
+	AC_DEFINE([HAVE_SHA1_IN_LIBMD], [1],
+	          [Use libmd SHA1 functions])
+	SHA1_LIBS=-lmd
+fi
+PKG_CHECK_MODULES([LIBSHA1], [libsha1], [HAVE_LIBSHA1=yes], [HAVE_LIBSHA1=no])
+if test "x$with_sha1" = x && test "x$HAVE_LIBSHA1" = xyes; then
+   with_sha1=libsha1
+fi
+if test "x$with_sha1" = xlibsha1 && test "x$HAVE_LIBSHA1" != xyes; then
+	AC_MSG_ERROR([libsha1 requested but not found])
+fi
+if test "x$with_sha1" = xlibsha1; then
+	AC_DEFINE([HAVE_SHA1_IN_LIBSHA1], [1],
+	          [Use libsha1 for SHA1])
+	SHA1_LIBS=-lsha1
+fi
+AC_CHECK_LIB([gcrypt], [gcry_md_open], [HAVE_LIBGCRYPT=yes])
+if test "x$with_sha1" = x && test "x$HAVE_LIBGCRYPT" = xyes; then
+	with_sha1=libgcrypt
+fi
+if test "x$with_sha1" = xlibgcrypt && test "x$HAVE_LIBGCRYPT" != xyes; then
+	AC_MSG_ERROR([libgcrypt requested but not found])
+fi
+if test "x$with_sha1" = xlibgcrypt; then
+	AC_DEFINE([HAVE_SHA1_IN_LIBGCRYPT], [1],
+	          [Use libgcrypt SHA1 functions])
+	SHA1_LIBS=-lgcrypt
+fi
+# We don't need all of the OpenSSL libraries, just libcrypto
+AC_CHECK_LIB([crypto], [SHA1_Init], [HAVE_LIBCRYPTO=yes])
+PKG_CHECK_MODULES([OPENSSL], [openssl], [HAVE_OPENSSL_PKC=yes],
+                  [HAVE_OPENSSL_PKC=no])
+if test "x$HAVE_LIBCRYPTO" = xyes || test "x$HAVE_OPENSSL_PKC" = xyes; then
+	if test "x$with_sha1" = x; then
+		with_sha1=libcrypto
+	fi
+else
+	if test "x$with_sha1" = xlibcrypto; then
+		AC_MSG_ERROR([OpenSSL libcrypto requested but not found])
+	fi
+fi
+if test "x$with_sha1" = xlibcrypto; then
+	if test "x$HAVE_LIBCRYPTO" = xyes; then
+		SHA1_LIBS=-lcrypto
+	else
+		SHA1_LIBS="$OPENSSL_LIBS"
+		SHA1_CFLAGS="$OPENSSL_CFLAGS"
+	fi
+fi
+AC_MSG_CHECKING([for SHA1 implementation])
+if test "x$with_sha1" = x; then
+	AC_MSG_ERROR([No suitable SHA1 implementation found])
+fi
+AC_MSG_RESULT([$with_sha1])
+AC_SUBST(SHA1_LIBS)
+AC_SUBST(SHA1_CFLAGS)
+
+PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS])
+PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
+
+# Autotools has some unfortunate issues with library handling.  In order to
+# get a server to rebuild when a dependency in the tree is changed, it must
+# be listed in SERVERNAME_DEPENDENCIES.  However, no system libraries may be
+# listed there, or some versions of autotools will break (especially if a -L
+# is required to find the library).  So, we keep two sets of libraries
+# detected: NAMESPACE_LIBS for in-tree libraries to be linked against, which
+# will go into the _DEPENDENCIES and _LDADD of the server, and
+# NAMESPACE_SYS_LIBS which will go into only the _LDADD.  The
+# NAMESPACEMODULES_LIBS detected from pkgconfig should always go in
+# NAMESPACE_SYS_LIBS.
+#
+# XSERVER_LIBS is the set of in-tree libraries which all servers require.
+# XSERVER_SYS_LIBS is the set of out-of-tree libraries which all servers
+# require.
+#
+XSERVER_CFLAGS="${XSERVER_CFLAGS} ${XSERVERCFLAGS_CFLAGS}"
+XSERVER_LIBS="$DIX_LIB $MI_LIB $OS_LIB"
+XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
+AC_SUBST([XSERVER_LIBS])
+AC_SUBST([XSERVER_SYS_LIBS])
+
+UTILS_SYS_LIBS="${SYS_LIBS}"
+AC_SUBST([UTILS_SYS_LIBS])
+
+# The Xorg binary needs to export symbols so that they can be used from modules
+# Some platforms require extra flags to do this.   libtool should set the
+# necessary flags for each platform when -export-dynamic is passed to it.
+LD_EXPORT_SYMBOLS_FLAG="-export-dynamic"
+AC_SUBST([LD_EXPORT_SYMBOLS_FLAG])
+
+dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so
+dnl we need to replicate that here until those can all be fixed
+AC_MSG_CHECKING([if SVR4 needs to be defined])
+AC_EGREP_CPP([I_AM_SVR4],[
+#if defined(SVR4) || defined(__svr4__) || defined(__SVR4)
+ I_AM_SVR4
+#endif
+],[
+AC_DEFINE([SVR4],1,[Define to 1 on systems derived from System V Release 4])
+AC_MSG_RESULT([yes])], AC_MSG_RESULT([no]))
+
+XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SYNC_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC"
+
+dnl ---------------------------------------------------------------------------
+dnl DDX section.
+dnl ---------------------------------------------------------------------------
+
+dnl Xvfb DDX
+
+AC_MSG_CHECKING([whether to build Xvfb DDX])
+AC_MSG_RESULT([$XVFB])
+AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes])
+
+if test "x$XVFB" = xyes; then
+	XVFB_LIBS="$FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB"
+	XVFB_SYS_LIBS="$XVFBMODULES_LIBS $GLX_SYS_LIBS"
+	AC_SUBST([XVFB_LIBS])
+	AC_SUBST([XVFB_SYS_LIBS])
+fi
+
+
+dnl Xnest DDX
+
+PKG_CHECK_MODULES(XNESTMODULES, [$LIBXEXT x11 xau $XDMCP_MODULES], [have_xnest=yes], [have_xnest=no])
+AC_MSG_CHECKING([whether to build Xnest DDX])
+if test "x$XNEST" = xauto; then
+	XNEST="$have_xnest"
+fi
+AC_MSG_RESULT([$XNEST])
+AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
+
+if test "x$XNEST" = xyes; then
+	if test "x$have_xnest" = xno; then
+		AC_MSG_ERROR([Xnest build explicitly requested, but required modules not found.])
+	fi
+	XNEST_LIBS="$FB_LIB $FIXES_LIB $MI_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $MAIN_LIB $DIX_LIB $OS_LIB"
+	XNEST_SYS_LIBS="$XNESTMODULES_LIBS $GLX_SYS_LIBS"
+	AC_SUBST([XNEST_LIBS])
+	AC_SUBST([XNEST_SYS_LIBS])
+fi
+
+
+dnl Xorg DDX
+
+AC_MSG_CHECKING([whether to build Xorg DDX])
+if test "x$XORG" = xauto; then
+	XORG="yes"
+	case $host_os in
+		cygwin*) XORG="no" ;;
+		darwin*) XORG="no" ;;
+	esac
+fi
+AC_MSG_RESULT([$XORG])
+
+xorg_bus_linuxpci=no
+xorg_bus_bsdpci=no
+xorg_bus_sparc=no
+
+if test "x$XORG" = xyes; then
+	XORG_DDXINCS='-I$(top_srcdir)/hw/xfree86 -I$(top_srcdir)/hw/xfree86/include -I$(top_srcdir)/hw/xfree86/common'
+	XORG_OSINCS='-I$(top_srcdir)/hw/xfree86/os-support -I$(top_srcdir)/hw/xfree86/os-support/bus -I$(top_srcdir)/os'
+	XORG_INCS="$XORG_DDXINCS $XORG_OSINCS"
+	XORG_CFLAGS="$XORGSERVER_CFLAGS -DHAVE_XORG_CONFIG_H"
+	XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB"
+
+	dnl ==================================================================
+	dnl symbol visibility
+	symbol_visibility=
+	have_visibility=disabled
+	if test x$SYMBOL_VISIBILITY != xno; then
+	    AC_MSG_CHECKING(for symbol visibility support)
+	    if test x$GCC = xyes; then
+		VISIBILITY_CFLAGS="-fvisibility=hidden"
+	    else
+		AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
+		if test x$SUNCC = xyes; then
+		    VISIBILITY_CFLAGS="-xldscope=hidden"
+		else
+		    have_visibility=no
+		fi
+	    fi
+	    if test x$have_visibility != xno; then
+		save_CFLAGS="$CFLAGS"
+		CFLAGS="$CFLAGS $VISIBILITY_CFLAGS"
+		AC_TRY_COMPILE(
+		    [#include <X11/Xfuncproto.h>
+		     extern _X_HIDDEN int hidden_int;
+		     extern _X_EXPORT int public_int;
+		     extern _X_HIDDEN int hidden_int_func(void);
+		     extern _X_EXPORT int public_int_func(void);],
+		    [],
+		    have_visibility=yes,
+		    have_visibility=no)
+		CFLAGS=$save_CFLAGS
+	    fi
+	    AC_MSG_RESULT([$have_visibility])
+	    if test x$have_visibility != xno; then
+		symbol_visibility=$VISIBILITY_CFLAGS
+		XORG_CFLAGS="$XORG_CFLAGS $VISIBILITY_CFLAGS"
+		XSERVER_CFLAGS="$XSERVER_CFLAGS $VISIBILITY_CFLAGS"
+	    fi
+	fi
+	dnl added to xorg-server.pc
+	AC_SUBST([symbol_visibility])
+	dnl ===================================================================
+
+	PKG_CHECK_MODULES([PCIACCESS], $LIBPCIACCESS)
+	SAVE_LIBS=$LIBS
+	SAVE_CFLAGS=$CFLAGS
+	CFLAGS=$PCIACCESS_CFLAGS
+	LIBS=$PCIACCESS_LIBS
+	AC_CHECK_FUNCS([pci_system_init_dev_mem])
+	AC_CHECK_FUNCS([pci_device_enable])
+	AC_CHECK_FUNCS([pci_device_is_boot_vga])
+	AC_CHECK_FUNCS([pci_device_vgaarb_init])
+	LIBS=$SAVE_LIBS
+	CFLAGS=$SAVE_CFLAGS
+	XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $GLX_SYS_LIBS"
+	XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS"
+
+	case $host_os in
+	  linux*)
+		if test "x$LNXAPM" = xyes; then
+			XORG_CFLAGS="$XORG_CFLAGS -DXF86PM"
+		fi
+	  	XORG_OS="linux"
+		XORG_OS_SUBDIR="linux"
+		xorg_bus_linuxpci="yes"
+		linux_acpi="no"
+		case $host_cpu in
+		  ia64*)
+			linux_ia64=yes
+			linux_acpi="yes"
+			;;
+		  alpha*)
+		  	linux_alpha=yes
+			;;
+		  i*86|amd64*|x86_64*)
+			linux_acpi="yes"
+			;;
+		  *)
+			;;
+		esac
+		;;
+	  freebsd* | kfreebsd*-gnu | dragonfly*)
+	  	XORG_OS="freebsd"
+		XORG_OS_SUBDIR="bsd"
+		xorg_bus_bsdpci="yes"
+		;;
+	  netbsd*)
+	  	XORG_OS="netbsd"
+		XORG_OS_SUBDIR="bsd"
+		xorg_bus_bsdpci="yes"
+		;;
+	  openbsd*)
+		if test "x$ac_cv_BSD_APM" = xyes \
+			-o "x$ac_cv_BSD_KQUEUE_APM" = xyes; then
+			XORG_CFLAGS="$XORG_CFLAGS -DXF86PM"
+		fi
+	  	XORG_OS="openbsd"
+		XORG_OS_SUBDIR="bsd"
+		xorg_bus_bsdpci="yes"
+		;;
+	  solaris*)
+	  	XORG_OS="solaris"
+		XORG_OS_SUBDIR="solaris"
+		XORG_CFLAGS="$XORG_CFLAGS -DXF86PM"
+		# Use the same stubs as BSD for old functions, since we now
+		# use libpciaccess for PCI
+		xorg_bus_bsdpci="yes"
+		AC_CHECK_HEADERS([sys/kd.h])
+		AC_CHECK_HEADERS([sys/vt.h], [solaris_vt=yes], [solaris_vt=no])
+		# Check for minimum supported release
+		AC_MSG_CHECKING([Solaris version])
+	        OS_MINOR=`echo ${host_os}|$SED -e 's/^.*solaris2\.//' -e s'/\..*$//'`
+		if test "${OS_MINOR}" -ge 7 ; then
+	        	AC_MSG_RESULT(Solaris ${OS_MINOR})
+		else
+			AC_MSG_RESULT(Solaris `echo ${host_os}|$SED -e 's/^.*solaris//`)
+		fi
+		if test "${OS_MINOR}" -lt 8 ; then
+			AC_MSG_ERROR([This release no longer supports Solaris versions older than Solaris 8.])
+		fi
+		AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
+		if test "x$SUNCC" = "xyes"; then
+			solaris_asm_inline="yes"
+		fi
+		AC_CHECK_DECL([_LP64], [SOLARIS_64="yes"], [SOLARIS_64="no"])
+			
+		case $host_cpu in
+		  sparc*)	
+			SOLARIS_INOUT_ARCH="sparcv8plus"
+			;;
+		  i*86)	
+			if test x$SOLARIS_64 = xyes ; then
+				SOLARIS_INOUT_ARCH="amd64"
+			else
+				SOLARIS_INOUT_ARCH="ia32"
+			fi
+			;;
+		  *)
+			AC_MSG_ERROR([Unsupported Solaris platform. Only SPARC & x86 \
+			are supported on Solaris in this release.   If you are \
+			interested in porting Xorg to your platform, please email \
+			xorg@lists.freedesktop.org.]) ;;
+		esac
+		AC_SUBST([SOLARIS_INOUT_ARCH])
+		if test x$solaris_asm_inline = xyes ; then
+			SOLARIS_ASM_CFLAGS='$(top_srcdir)/hw/xfree86/os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il'
+			XORG_CFLAGS="${XORG_CFLAGS} "'$(SOLARIS_ASM_CFLAGS)'
+		fi
+		AC_SUBST([SOLARIS_ASM_CFLAGS])
+		if test "x$SUPPORT_PC98" = xauto; then
+			SUPPORT_PC98="no"
+		fi
+		;;
+	  gnu*)
+	  	XORG_OS="gnu"
+		XORG_OS_SUBDIR="hurd"
+		# Use the same stubs as BSD for old functions, since we now
+		# use libpciaccess for PCI
+		xorg_bus_bsdpci="yes"
+		;;
+	  *)
+	  	XORG_OS="unknown"
+		XORG_OS_SUBDIR="unknown"
+		AC_MSG_ERROR([m4_text_wrap(m4_join([ ],
+		[Your OS is unknown. Xorg currently only supports Linux,],
+		[Free/Open/Net/DragonFlyBSD, Solaris/OpenSolaris, & GNU Hurd.],
+		[If you are interested in porting Xorg to your platform,],
+		[please email xorg@lists.freedesktop.org.]))])
+		;;
+	esac
+
+	case $host_cpu in
+	  sparc*)
+		xorg_bus_sparc="yes"
+		;;
+	  i*86)
+		if test "x$SUPPORT_PC98" = xauto; then
+			SUPPORT_PC98="yes"
+		fi
+		;;
+	esac
+
+	if test "x$SUPPORT_PC98" = xauto; then
+		SUPPORT_PC98="no"
+	fi
+	if test "x$SUPPORT_PC98" = xyes; then
+		AC_DEFINE(SUPPORT_PC98, 1, [Support PC98])
+	fi
+	if test "x$XORG_OS_PCI" = x ; then
+		XORG_OS_PCI=$XORG_OS
+	fi
+	if test "x$DGA" = xauto; then
+		PKG_CHECK_MODULES(DGA, $DGAPROTO, [DGA=yes], [DGA=no])
+	fi
+	if test "x$DGA" = xyes; then
+		XORG_MODULES="$XORG_MODULES $DGAPROTO"
+		PKG_CHECK_MODULES(DGA, $DGAPROTO)
+		AC_DEFINE(DGA, 1, [Support DGA extension])
+		AC_DEFINE(XFreeXDGA, 1, [Build XDGA support])
+	fi
+
+	if test "x$XF86VIDMODE" = xauto; then
+		PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO, [XF86VIDMODE=yes], [XF86VIDMODE=no])
+	fi
+	if test "x$XF86VIDMODE" = xyes; then
+		XORG_MODULES="$XORG_MODULES $VIDMODEPROTO"
+		PKG_CHECK_MODULES(XF86VIDMODE, $VIDMODEPROTO)
+		AC_DEFINE(XF86VIDMODE, 1, [Support XFree86 Video Mode extension])
+	fi
+
+	if test -n "$XORG_MODULES"; then
+	        PKG_CHECK_MODULES(XORG_MODULES, [$XORG_MODULES])
+	        XORG_CFLAGS="$XORG_CFLAGS $XORG_MODULES_CFLAGS"
+	        XORG_SYS_LIBS="$XORG_SYS_LIBS $XORG_MODULES_LIBS"
+	fi
+
+	AC_SUBST([XORG_LIBS])
+	AC_SUBST([XORG_SYS_LIBS])
+	AC_SUBST([XORG_INCS])
+	AC_SUBST([XORG_OS])
+	AC_SUBST([XORG_OS_SUBDIR])
+
+	AC_PATH_PROG(PERL, perl, no)
+	dnl unlikely as this may be ...
+	if test "x$PERL" = xno; then
+		AC_MSG_ERROR([Perl is required to build the XFree86/Xorg DDX.])
+	fi
+	AC_SUBST(PERL)
+
+	AC_SUBST([XORG_CFLAGS])
+
+	dnl these only go in xorg-config.h
+	XF86CONFIGFILE="xorg.conf"
+	XF86CONFIGDIR="xorg.conf.d"
+	AC_SUBST(XF86CONFIGDIR)
+	CONFIGFILE="$sysconfdir/$XF86CONFIGFILE"
+	LOGPREFIX="$logdir/Xorg."
+	AC_DEFINE(XORG_SERVER, 1, [Building Xorg server])
+	AC_DEFINE(XORGSERVER, 1, [Building Xorg server])
+	AC_DEFINE(XFree86Server, 1, [Building XFree86 server])
+	AC_DEFINE(XFree86LOADER, 1, [Building loadable XFree86 server])
+	AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+	AC_DEFINE(NEED_XF86_TYPES, 1, [Need XFree86 typedefs])
+	AC_DEFINE(NEED_XF86_PROTOTYPES, 1, [Need XFree86 helper functions])
+	AC_DEFINE(__XSERVERNAME__, "Xorg", [Name of X server])
+	AC_DEFINE_DIR(__XCONFIGFILE__, XF86CONFIGFILE, [Name of configuration file])
+	AC_DEFINE_DIR(XF86CONFIGFILE, XF86CONFIGFILE, [Name of configuration file])
+	AC_DEFINE_DIR(__XCONFIGDIR__, XF86CONFIGDIR, [Name of configuration directory])
+	AC_DEFINE_DIR(DEFAULT_MODULE_PATH, moduledir, [Default module search path])
+	AC_DEFINE_DIR(DEFAULT_LIBRARY_PATH, libdir, [Default library install path])
+	AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location])
+	AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
+	AC_DEFINE(XSERVER_LIBPCIACCESS, 1, [Use libpciaccess for all pci manipulation])
+	if test "x$VGAHW" = xyes; then
+		AC_DEFINE(WITH_VGAHW, 1, [Building vgahw module])
+	fi
+
+	driverdir="$moduledir/drivers"
+	AC_SUBST([moduledir])
+	AC_SUBST([driverdir])
+	sdkdir="$includedir/xorg"
+	extdir="$includedir/X11/extensions"
+	sysconfigdir="$datadir/X11/$XF86CONFIGDIR"
+	AC_SUBST([sdkdir])
+	AC_SUBST([extdir])
+	AC_SUBST([sysconfigdir])
+	AC_SUBST([logdir])
+
+	# stuff the ABI versions into the pc file too
+	extract_abi() {
+	    grep ^.define.*${1}_VERSION ${srcdir}/hw/xfree86/common/xf86Module.h | tr '(),' '  .' | awk '{ print $4$5 }'
+	}
+	abi_ansic=`extract_abi ANSIC`
+	abi_videodrv=`extract_abi VIDEODRV`
+	abi_xinput=`extract_abi XINPUT`
+	abi_extension=`extract_abi EXTENSION`
+	AC_SUBST([abi_ansic])
+	AC_SUBST([abi_videodrv])
+	AC_SUBST([abi_xinput])
+	AC_SUBST([abi_extension])
+fi
+AM_CONDITIONAL([XORG], [test "x$XORG" = xyes])
+AM_CONDITIONAL([XORG_BUS_LINUXPCI], [test "x$xorg_bus_linuxpci" = xyes])
+AM_CONDITIONAL([XORG_BUS_BSDPCI], [test "x$xorg_bus_bsdpci" = xyes])
+AM_CONDITIONAL([XORG_BUS_SPARC], [test "x$xorg_bus_sparc" = xyes])
+AM_CONDITIONAL([LINUX_IA64], [test "x$linux_ia64" = xyes])
+AM_CONDITIONAL([LINUX_ALPHA], [test "x$linux_alpha" = xyes])
+AM_CONDITIONAL([LNXACPI], [test "x$linux_acpi" = xyes])
+AM_CONDITIONAL([SOLARIS_ASM_INLINE], [test "x$solaris_asm_inline" = xyes])
+AM_CONDITIONAL([SOLARIS_VT], [test "x$solaris_vt" = xyes])
+AM_CONDITIONAL([DGA], [test "x$DGA" = xyes])
+AM_CONDITIONAL([XF86VIDMODE], [test "x$XF86VIDMODE" = xyes])
+
+dnl XWin DDX
+
+AC_MSG_CHECKING([whether to build XWin DDX])
+if test "x$XWIN" = xauto; then
+	case $host_os in
+		cygwin*) XWIN="yes" ;;
+		mingw*) XWIN="yes" ;;
+		*) XWIN="no" ;;
+	esac
+fi
+AC_MSG_RESULT([$XWIN])
+
+if test "x$XWIN" = xyes; then
+	AC_DEFINE_DIR(SYSCONFDIR, sysconfdir, [Location of system.XWinrc])
+	AC_DEFINE_DIR(DEFAULT_LOGDIR, logdir, [Default log location])
+	AC_DEFINE_UNQUOTED(XORG_VERSION_CURRENT, [$VENDOR_RELEASE], [Current Xorg version])
+	AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
+	AC_CHECK_TOOL(WINDRES, windres)
+
+	PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau])
+
+	if test "x$WINDOWSWM" = xauto; then
+		PKG_CHECK_EXISTS($WINDOWSWMPROTO, [WINDOWSWM=yes], [WINDOWSWM=no])
+	fi
+	if test "x$WINDOWSWM" = xyes ; then
+		PKG_CHECK_MODULES(WINDOWSWM, $WINDOWSWMPROTO)
+		XWINMODULES_CFLAGS="$XWINMODULES_CFLAGS $WINDOWSWM_CFLAGS"
+		AC_DEFINE(ROOTLESS,1,[Build Rootless code])
+	fi
+
+	case $host_os in
+		cygwin*)
+			XWIN_SERVER_NAME=XWin
+			AC_DEFINE(HAS_DEVWINDOWS,1,[Cygwin has /dev/windows for signaling new win32 messages])
+			;;
+		mingw*)
+			XWIN_SERVER_NAME=Xming
+			AC_DEFINE(RELOCATE_PROJECTROOT,1,[Make PROJECT_ROOT relative to the xserver location])
+			AC_DEFINE(HAS_WINSOCK,1,[Use Windows sockets])
+			XWIN_SYS_LIBS=-lwinsock2
+			;;
+	esac
+	XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $RANDR_LIB $RENDER_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB"
+	XWIN_SYS_LIBS="$XWIN_SYS_LIBS $XWINMODULES_LIBS"
+	AC_SUBST(XWIN_LIBS)
+	AC_SUBST(XWIN_SERVER_NAME)
+	AC_SUBST(XWIN_SYS_LIBS)
+
+	if test "x$DEBUGGING" = xyes; then
+		AC_DEFINE(CYGDEBUG, 1, [Simple debug messages])
+		AC_DEFINE(CYGWINDOWING_DEBUG, 1, [Debug messages for window handling])
+		AC_DEFINE(CYGMULTIWINDOW_DEBUG, 1, [Debug window manager])
+	fi
+
+	AC_DEFINE(DDXOSVERRORF, 1, [Use OsVendorVErrorF])
+	AC_DEFINE(DDXBEFORERESET, 1, [Use ddxBeforeReset ])
+fi
+AM_CONDITIONAL(XWIN, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_MULTIWINDOW, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_MULTIWINDOWEXTWM, [test "x$XWIN" = xyes && test "x$WINDOWSWM" = xyes])
+AM_CONDITIONAL(XWIN_CLIPBOARD, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_GLX_WINDOWS, [test "x$XWIN" = xyes && false])
+AM_CONDITIONAL(XWIN_NATIVEGDI, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_PRIMARYFB, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_RANDR, [test "x$XWIN" = xyes])
+AM_CONDITIONAL(XWIN_XV, [test "x$XWIN" = xyes && test "x$XV" = xyes])
+
+dnl Darwin / OS X DDX
+if test "x$XQUARTZ" = xyes; then
+	AC_DEFINE(XQUARTZ,1,[Have Quartz])
+	AC_DEFINE(ROOTLESS,1,[Build Rootless code])
+
+	DARWIN_LIBS="$MI_LIB $OS_LIB $DIX_LIB $MAIN_LIB $FB_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $XPSTUBS_LIB"
+	AC_SUBST([DARWIN_LIBS])
+
+	AC_CHECK_LIB([Xplugin],[xp_init],[:])
+
+	CFLAGS="${CFLAGS} -DROOTLESS_WORKAROUND -DROOTLESS_SAFEALPHA -DNO_ALLOCA"
+
+	PKG_CHECK_MODULES(XPBPROXY, $APPLEWMPROTO $LIBAPPLEWM xfixes x11)
+
+        if test "x$XQUARTZ_SPARKLE" = xyes ; then
+                AC_DEFINE(XQUARTZ_SPARKLE,1,[Support application updating through sparkle.])
+        fi
+
+	if test "x$STANDALONE_XPBPROXY" = xyes ; then
+		AC_DEFINE(STANDALONE_XPBPROXY,1,[Build a standalone xpbproxy])
+	fi
+fi
+
+# Support for objc in autotools is minimal and not documented.
+OBJC='$(CC)'
+OBJCLD='$(CCLD)'
+OBJCLINK='$(LINK)'
+OBJCFLAGS='$(CFLAGS)'
+AC_SUBST([OBJC])
+AC_SUBST([OBJCCLD])
+AC_SUBST([OBJCLINK])
+AC_SUBST([OBJCFLAGS])
+# internal, undocumented automake func follows :(
+_AM_DEPENDENCIES([OBJC])
+AM_CONDITIONAL(XQUARTZ, [test "x$XQUARTZ" = xyes])
+AM_CONDITIONAL(XQUARTZ_SPARKLE, [test "x$XQUARTZ_SPARKLE" != "xno"])
+AM_CONDITIONAL(STANDALONE_XPBPROXY, [test "x$STANDALONE_XPBPROXY" = xyes])
+
+dnl DMX DDX
+PKG_CHECK_MODULES(
+	[DMXMODULES],
+	[xmuu $LIBXEXT x11 xrender xfixes $LIBXI $DMXPROTO xau $XDMCP_MODULES],
+	[PKG_CHECK_MODULES(
+		[XDMXCONFIG_DEP],
+		[xaw7 xmu xt xpm x11],
+		[have_dmx=yes],
+		[have_dmx=no])],
+	[have_dmx=no])
+AC_MSG_CHECKING([whether to build Xdmx DDX])
+if test "x$DMX" = xauto; then
+	DMX="$have_dmx"
+	case $host_os in
+		cygwin*) DMX="no" ;;
+		darwin*) DMX="no" ;;
+	esac
+fi
+AC_MSG_RESULT([$DMX])
+AM_CONDITIONAL(DMX, [test "x$DMX" = xyes])
+
+if test "x$DMX" = xyes; then
+	if test "x$have_dmx" = xno; then
+		AC_MSG_ERROR([Xdmx build explicitly requested, but required
+		              modules not found.])
+	fi
+	DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC"
+	XDMX_CFLAGS="$DMXMODULES_CFLAGS"
+	XDMX_LIBS="$FB_LIB $MI_LIB $XEXT_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SYNC_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $COMPOSITE_LIB $DAMAGE_LIB $MAIN_LIB $DIX_LIB $CONFIG_LIB $OS_LIB $FIXES_LIB"
+	XDMX_SYS_LIBS="$DMXMODULES_LIBS"
+	AC_SUBST([XDMX_CFLAGS])
+	AC_SUBST([XDMX_LIBS])
+	AC_SUBST([XDMX_SYS_LIBS])
+
+dnl USB sources in DMX require <linux/input.h>
+	AC_CHECK_HEADER([linux/input.h], DMX_BUILD_USB="yes",
+			DMX_BUILD_USB="no")
+dnl Linux sources in DMX require <linux/keyboard.h>
+	AC_CHECK_HEADER([linux/keyboard.h], DMX_BUILD_LNX="yes",
+			DMX_BUILD_LNX="no")
+	AC_SUBST(XDMXCONFIG_DEP_CFLAGS)
+	AC_SUBST(XDMXCONFIG_DEP_LIBS)
+	PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [$LIBDMX $LIBXEXT x11])
+	AC_SUBST(DMXEXAMPLES_DEP_LIBS)
+	PKG_CHECK_MODULES([DMXXMUEXAMPLES_DEP], [$LIBDMX xmu $LIBXEXT x11])
+	AC_SUBST(DMXXMUEXAMPLES_DEP_LIBS)
+	PKG_CHECK_MODULES([DMXXIEXAMPLES_DEP], [$LIBDMX $LIBXI $LIBXEXT x11])
+	AC_SUBST(DMXXIEXAMPLES_DEP_LIBS)
+	PKG_CHECK_MODULES([XTSTEXAMPLES_DEP], [$LIBXTST $LIBXEXT x11])
+	AC_SUBST(XTSTEXAMPLES_DEP_LIBS)
+	PKG_CHECK_MODULES([XRESEXAMPLES_DEP], [xres $LIBXEXT x11])
+	AC_SUBST(XRESEXAMPLES_DEP_LIBS)
+	PKG_CHECK_MODULES([X11EXAMPLES_DEP], [$LIBXEXT x11])
+	AC_SUBST(X11EXAMPLES_DEP_LIBS)
+
+fi
+AM_CONDITIONAL([DMX_BUILD_LNX], [test "x$DMX_BUILD_LNX" = xyes])
+AM_CONDITIONAL([DMX_BUILD_USB], [test "x$DMX_BUILD_USB" = xyes])
+
+dnl kdrive DDX
+
+XEPHYR_LIBS=
+XEPHYR_INCS=
+
+AM_CONDITIONAL(KDRIVE, [test x$KDRIVE = xyes])
+
+if test "$KDRIVE" = yes; then
+    AC_DEFINE(KDRIVESERVER,1,[Build Kdrive X server])
+    AC_DEFINE(KDRIVEDDXACTIONS,,[Build kdrive ddx])
+
+    AC_CHECK_HEADERS([linux/fb.h])
+    if test "$ac_cv_header_linux_fb_h" = yes && test "x$XFBDEV" = xauto; then
+        XFBDEV=yes
+    fi
+
+    if test "x$XFBDEV" = xyes; then
+        KDRIVEFBDEVLIB=yes
+        AC_DEFINE(KDRIVEFBDEV, 1, [Build fbdev-based kdrive server])
+    fi
+
+
+    PKG_CHECK_MODULES([TSLIB], [tslib-0.0], [HAVE_TSLIB="yes"], [HAVE_TSLIB="no"])
+    if test "x$HAVE_TSLIB" = xno; then
+        AC_CHECK_LIB(ts, ts_open, [
+			HAVE_TSLIB="yes"
+			TSLIB_LIBS="-lts"
+		])
+    fi
+
+    if test "xTSLIB" = xauto; then
+        TSLIB="$HAVE_TSLIB"
+    fi
+
+    if test "x$TSLIB" = xyes; then
+        if ! test "x$HAVE_TSLIB" = xyes; then
+            AC_MSG_ERROR([tslib must be installed to build the tslib driver. See http://tslib.berlios.de/])
+        else
+            AC_DEFINE(TSLIB, 1, [Have tslib support])
+        fi
+    fi
+
+    if test "x$KDRIVE_KBD" = xyes; then
+       AC_DEFINE(KDRIVE_KBD, 1, [Enable KDrive kbd driver])
+    fi
+    if test "x$KDRIVE_EVDEV" = xyes; then
+       AC_DEFINE(KDRIVE_EVDEV, 1, [Enable KDrive evdev driver])
+    fi
+    if test "x$KDRIVE_MOUSE" = xyes; then
+       AC_DEFINE(KDRIVE_MOUSE, 1, [Enable KDrive mouse driver])
+    fi
+
+    XEPHYR_REQUIRED_LIBS="x11 $LIBXEXT xau xdmcp"
+    if test "x$XV" = xyes; then
+        XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xv"
+    fi
+    if test "x$DRI" = xyes && test "x$GLX" = xyes; then
+        XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm"
+    fi
+
+    PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"])
+    if test "x$XEPHYR" = xauto; then
+        XEPHYR=$xephyr
+    fi
+    if test "x$XEPHYR" = xyes && test "x$xephyr" = xno; then	
+        AC_MSG_ERROR([Xephyr dependencies missing])
+    fi
+
+    # Xephyr needs nanosleep() which is in librt on Solaris
+    AC_CHECK_FUNC([nanosleep], [],
+        AC_CHECK_LIB([rt], [nanosleep], XEPHYR_LIBS="$XEPHYR_LIBS -lrt"))
+    
+    # damage shadow extension glx (NOTYET) fb mi
+    KDRIVE_INC='-I$(top_srcdir)/hw/kdrive/src'
+    KDRIVE_PURE_INCS="$KDRIVE_INC $MIEXT_SYNC_INC $MIEXT_DAMAGE_INC $MIEXT_SHADOW_INC $XEXT_INC $FB_INC $MI_INC"
+    KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux'
+    KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC"
+    
+    KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS"
+
+    KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $RANDR_LIB $RENDER_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $OS_LIB"
+    KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.la'
+    case $host_os in
+	*linux*)
+	    KDRIVE_OS_LIB='$(top_builddir)/hw/kdrive/linux/liblinux.la'
+            KDRIVELINUX=yes
+	    if test "x$KDRIVE_EVDEV" = xauto; then
+		KDRIVE_EVDEV=yes
+	    fi
+	    if test "x$KDRIVE_KBD" = xauto; then
+		KDRIVE_KBD=yes
+	    fi
+	    if test "x$KDRIVE_MOUSE" = xauto; then
+		KDRIVE_MOUSE=yes
+	    fi
+	    ;;
+	*)
+	    if test "x$KDRIVE_EVDEV" = xauto; then
+		KDRIVE_EVDEV=no
+	    fi
+	    if test "x$KDRIVE_KBD" = xauto; then
+		KDRIVE_KBD=no
+	    fi
+	    if test "x$KDRIVE_MOUSE" = xauto; then
+		KDRIVE_MOUSE=no
+	    fi
+	    ;;
+    esac
+    KDRIVE_STUB_LIB='$(top_builddir)/hw/kdrive/src/libkdrivestubs.la'
+    KDRIVE_LOCAL_LIBS="$MAIN_LIB $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB"
+    KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS"
+    KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB"
+    KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $GLX_SYS_LIBS $DLOPEN_LIBS $TSLIB_LIBS"
+
+    AC_SUBST([XEPHYR_LIBS])
+    AC_SUBST([XEPHYR_INCS])
+fi
+AC_SUBST([KDRIVE_INCS])
+AC_SUBST([KDRIVE_PURE_INCS])
+AC_SUBST([KDRIVE_CFLAGS])
+AC_SUBST([KDRIVE_PURE_LIBS])
+AC_SUBST([KDRIVE_LOCAL_LIBS])
+AC_SUBST([KDRIVE_LIBS])
+AM_CONDITIONAL(KDRIVELINUX, [test "x$KDRIVELINUX" = xyes])
+AM_CONDITIONAL(KDRIVE_EVDEV, [test "x$KDRIVE_EVDEV" = xyes])
+AM_CONDITIONAL(KDRIVE_KBD,   [test "x$KDRIVE_KBD" = xyes])
+AM_CONDITIONAL(KDRIVE_MOUSE, [test "x$KDRIVE_MOUSE" = xyes])
+AM_CONDITIONAL(TSLIB, [test "x$HAVE_TSLIB" = xyes])
+AM_CONDITIONAL(KDRIVEFBDEV, [test "x$XFBDEV" = xyes])
+AM_CONDITIONAL(XEPHYR, [test "x$KDRIVE" = xyes && test "x$XEPHYR" = xyes])
+AM_CONDITIONAL(BUILD_KDRIVEFBDEVLIB, [test "x$KDRIVE" = xyes && test "x$KDRIVEFBDEVLIB" = xyes])
+AM_CONDITIONAL(XFAKESERVER, [test "x$KDRIVE" = xyes && test "x$XFAKE" = xyes])
+
+dnl and the rest of these are generic, so they're in config.h
+dnl 
+dnl though, thanks to the passing of some significant amount of time, the
+dnl above is probably a complete fallacy, and you should not rely on it.
+dnl but this is still actually better than imake, honest. -daniels
+
+AC_TRY_COMPILE([
+#include <features.h>
+#ifndef __GLIBC__
+#error not glibc
+#endif
+], [], [AC_DEFINE(_GNU_SOURCE, 1,
+	[ Enable GNU and other extensions to the C environment for glibc])])
+
+AC_DEFINE_DIR(PROJECTROOT, prefix, [Overall prefix])
+
+AC_SUBST([RELEASE_DATE])
+BUILD_DATE="`date +'%Y%m%d'`"
+AC_SUBST([BUILD_DATE])
+BUILD_TIME="`date +'1%H%M%S'`"
+AC_SUBST([BUILD_TIME])
+
+DIX_CFLAGS="-DHAVE_DIX_CONFIG_H $XSERVER_CFLAGS"
+
+AC_SUBST([DIX_CFLAGS])
+
+AC_SUBST([libdir])
+AC_SUBST([exec_prefix])
+AC_SUBST([prefix])
+
+AC_CONFIG_COMMANDS([sdksyms], [touch hw/xfree86/loader/sdksyms.dep])
+
+AC_OUTPUT([
+Makefile
+glx/Makefile
+include/Makefile
+composite/Makefile
+damageext/Makefile
+dbe/Makefile
+dix/Makefile
+doc/Makefile
+doc/man/Makefile
+doc/xml/Makefile
+doc/xml/dtrace/Makefile
+doc/xml/xserver.ent
+fb/Makefile
+record/Makefile
+config/Makefile
+mi/Makefile
+miext/Makefile
+miext/sync/Makefile
+miext/damage/Makefile
+miext/shadow/Makefile
+miext/cw/Makefile
+miext/rootless/Makefile
+os/Makefile
+randr/Makefile
+render/Makefile
+xkb/Makefile
+Xext/Makefile
+Xi/Makefile
+xfixes/Makefile
+exa/Makefile
+hw/Makefile
+hw/xfree86/Makefile
+hw/xfree86/common/Makefile
+hw/xfree86/common/xf86Build.h
+hw/xfree86/ddc/Makefile
+hw/xfree86/dixmods/Makefile
+hw/xfree86/dixmods/extmod/Makefile
+hw/xfree86/doc/Makefile
+hw/xfree86/doc/devel/Makefile
+hw/xfree86/doc/sgml/Makefile
+hw/xfree86/dri/Makefile
+hw/xfree86/dri2/Makefile
+hw/xfree86/exa/Makefile
+hw/xfree86/exa/man/Makefile
+hw/xfree86/fbdevhw/Makefile
+hw/xfree86/fbdevhw/man/Makefile
+hw/xfree86/i2c/Makefile
+hw/xfree86/int10/Makefile
+hw/xfree86/loader/Makefile
+hw/xfree86/man/Makefile
+hw/xfree86/modes/Makefile
+hw/xfree86/os-support/Makefile
+hw/xfree86/os-support/bsd/Makefile
+hw/xfree86/os-support/bus/Makefile
+hw/xfree86/os-support/hurd/Makefile
+hw/xfree86/os-support/misc/Makefile
+hw/xfree86/os-support/linux/Makefile
+hw/xfree86/os-support/solaris/Makefile
+hw/xfree86/parser/Makefile
+hw/xfree86/ramdac/Makefile
+hw/xfree86/shadowfb/Makefile
+hw/xfree86/vbe/Makefile
+hw/xfree86/vgahw/Makefile
+hw/xfree86/x86emu/Makefile
+hw/xfree86/xaa/Makefile
+hw/xfree86/utils/Makefile
+hw/xfree86/utils/man/Makefile
+hw/xfree86/utils/cvt/Makefile
+hw/xfree86/utils/gtf/Makefile
+hw/dmx/config/Makefile
+hw/dmx/config/man/Makefile
+hw/dmx/doc/Makefile
+hw/dmx/doc/doxygen.conf
+hw/dmx/examples/Makefile
+hw/dmx/input/Makefile
+hw/dmx/glxProxy/Makefile
+hw/dmx/Makefile
+hw/dmx/man/Makefile
+hw/vfb/Makefile
+hw/vfb/man/Makefile
+hw/xnest/Makefile
+hw/xnest/man/Makefile
+hw/xwin/Makefile
+hw/xwin/glx/Makefile
+hw/xwin/man/Makefile
+hw/xquartz/Makefile
+hw/xquartz/GL/Makefile
+hw/xquartz/bundle/Makefile
+hw/xquartz/man/Makefile
+hw/xquartz/mach-startup/Makefile
+hw/xquartz/pbproxy/Makefile
+hw/xquartz/xpr/Makefile
+hw/kdrive/Makefile
+hw/kdrive/ephyr/Makefile
+hw/kdrive/ephyr/man/Makefile
+hw/kdrive/fake/Makefile
+hw/kdrive/fbdev/Makefile
+hw/kdrive/linux/Makefile
+hw/kdrive/src/Makefile
+test/Makefile
+test/xi2/Makefile
+xorg-server.pc
+])
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c
index e57c27b00..7f500d63d 100644
--- a/xorg-server/dix/devices.c
+++ b/xorg-server/dix/devices.c
@@ -1,2628 +1,2630 @@
-/************************************************************
-
-Copyright 1987, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose and without fee is hereby granted,
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-********************************************************/
-
-
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include "misc.h"
-#include "resource.h"
-#include <X11/Xproto.h>
-#include <X11/Xatom.h>
-#include "windowstr.h"
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "cursorstr.h"
-#include "dixstruct.h"
-#include "ptrveloc.h"
-#include "site.h"
-#include "xkbsrv.h"
-#include "privates.h"
-#include "xace.h"
-#include "mi.h"
-
-#include "dispatch.h"
-#include "swaprep.h"
-#include "dixevents.h"
-#include "mipointer.h"
-#include "eventstr.h"
-
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XI2.h>
-#include <X11/extensions/XIproto.h>
-#include <math.h>
-#include <pixman.h>
-#include "exglobals.h"
-#include "exevents.h"
-#include "xiquerydevice.h" /* for SizeDeviceClasses */
-#include "xiproperty.h"
-#include "enterleave.h" /* for EnterWindow() */
-#include "xserver-properties.h"
-#include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */
-
-/** @file
- * This file handles input device-related stuff.
- */
-
-static void RecalculateMasterButtons(DeviceIntPtr slave);
-
-static void
-DeviceSetTransform(DeviceIntPtr dev, float *transform)
-{
-    struct pixman_f_transform scale;
-    double sx, sy;
-    int x, y;
-
-    /**
-     * calculate combined transformation matrix:
-     *
-     * M = InvScale * Transform * Scale
-     *
-     * So we can later transform points using M * p
-     *
-     * Where:
-     *  Scale scales coordinates into 0..1 range
-     *  Transform is the user supplied (affine) transform
-     *  InvScale scales coordinates back up into their native range
-     */
-    sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value;
-    sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value;
-
-    /* invscale */
-    pixman_f_transform_init_scale(&scale, sx, sy);
-    scale.m[0][2] = dev->valuator->axes[0].min_value;
-    scale.m[1][2] = dev->valuator->axes[1].min_value;
-
-    /* transform */
-    for (y=0; y<3; y++)
-        for (x=0; x<3; x++)
-            dev->transform.m[y][x] = *transform++;
-
-    pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
-
-    /* scale */
-    pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
-    scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
-    scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
-
-    pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
-}
-
-/**
- * DIX property handler.
- */
-static int
-DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
-                  BOOL checkonly)
-{
-    if (property == XIGetKnownProperty(XI_PROP_ENABLED))
-    {
-        if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
-            return BadValue;
-
-        /* Don't allow disabling of VCP/VCK */
-        if ((dev == inputInfo.pointer || dev == inputInfo.keyboard) &&
-            !(*(CARD8*)prop->data))
-            return BadAccess;
-
-        if (!checkonly)
-        {
-            if ((*((CARD8*)prop->data)) && !dev->enabled)
-                EnableDevice(dev, TRUE);
-            else if (!(*((CARD8*)prop->data)) && dev->enabled)
-                DisableDevice(dev, TRUE);
-        }
-    } else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM))
-    {
-        float *f = (float*)prop->data;
-        int i;
-
-        if (prop->format != 32 || prop->size != 9 ||
-            prop->type != XIGetKnownProperty(XATOM_FLOAT))
-            return BadValue;
-
-        for (i=0; i<9; i++)
-            if (!isfinite(f[i]))
-                return BadValue;
-
-        if (!checkonly)
-            DeviceSetTransform(dev, f);
-    }
-
-    return Success;
-}
-
-/* Pair the keyboard to the pointer device. Keyboard events will follow the
- * pointer sprite. Only applicable for master devices.
- * If the client is set, the request to pair comes from some client. In this
- * case, we need to check for access. If the client is NULL, it's from an
- * internal automatic pairing, we must always permit this.
- */
-static int
-PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd)
-{
-    if (!ptr)
-        return BadDevice;
-
-    /* Don't allow pairing for slave devices */
-    if (!IsMaster(ptr) || !IsMaster(kbd))
-        return BadDevice;
-
-    if (ptr->spriteInfo->paired)
-        return BadDevice;
-
-    if (kbd->spriteInfo->spriteOwner)
-    {
-        free(kbd->spriteInfo->sprite);
-        kbd->spriteInfo->sprite = NULL;
-        kbd->spriteInfo->spriteOwner = FALSE;
-    }
-
-    kbd->spriteInfo->sprite = ptr->spriteInfo->sprite;
-    kbd->spriteInfo->paired = ptr;
-    ptr->spriteInfo->paired = kbd;
-    return Success;
-}
-
-
-/**
- * Find and return the next unpaired MD pointer device.
- */
-static DeviceIntPtr
-NextFreePointerDevice(void)
-{
-    DeviceIntPtr dev;
-    for (dev = inputInfo.devices; dev; dev = dev->next)
-        if (IsMaster(dev) &&
-                dev->spriteInfo->spriteOwner &&
-                !dev->spriteInfo->paired)
-            return dev;
-    return NULL;
-}
-
-/**
- * Create a new input device and init it to sane values. The device is added
- * to the server's off_devices list.
- *
- * @param deviceProc Callback for device control function (switch dev on/off).
- * @return The newly created device.
- */
-DeviceIntPtr
-AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
-{
-    DeviceIntPtr dev, *prev; /* not a typo */
-    DeviceIntPtr devtmp;
-    int devid;
-    char devind[MAXDEVICES];
-    BOOL enabled;
-    float transform[9];
-
-    /* Find next available id, 0 and 1 are reserved */
-    memset(devind, 0, sizeof(char)*MAXDEVICES);
-    for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
-	devind[devtmp->id]++;
-    for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
-	devind[devtmp->id]++;
-    for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++)
-	;
-
-    if (devid >= MAXDEVICES)
-	return (DeviceIntPtr)NULL;
-    dev =  _dixAllocateObjectWithPrivates(sizeof(DeviceIntRec) + sizeof(SpriteInfoRec),
-					  sizeof(DeviceIntRec) + sizeof(SpriteInfoRec),
-					  offsetof(DeviceIntRec, devPrivates), PRIVATE_DEVICE);
-    if (!dev)
-	return (DeviceIntPtr)NULL;
-    dev->id = devid;
-    dev->public.processInputProc = ProcessOtherEvent;
-    dev->public.realInputProc = ProcessOtherEvent;
-    dev->public.enqueueInputProc = EnqueueEvent;
-    dev->deviceProc = deviceProc;
-    dev->startup = autoStart;
-
-    /* device grab defaults */
-    dev->deviceGrab.grabTime = currentTime;
-    dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
-    dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
-
-    XkbSetExtension(dev, ProcessKeyboardEvent);
-
-    dev->coreEvents = TRUE;
-
-    /* sprite defaults */
-    dev->spriteInfo = (SpriteInfoPtr)&dev[1];
-
-    /*  security creation/labeling check
-     */
-    if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
-	free(dev);
-	return NULL;
-    }
-
-    inputInfo.numDevices++;
-
-    for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next)
-        ;
-    *prev = dev;
-    dev->next = NULL;
-
-    enabled = FALSE;
-    XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
-                           XA_INTEGER, 8, PropModeReplace, 1, &enabled,
-                           FALSE);
-    XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE);
-
-    /* unity matrix */
-    memset(transform, 0, sizeof(transform));
-    transform[0] = transform[4] = transform[8] = 1.0f;
-
-    XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
-                           XIGetKnownProperty(XATOM_FLOAT), 32,
-                           PropModeReplace, 9, transform, FALSE);
-    XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
-                                 FALSE);
-
-    XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL);
-
-    return dev;
-}
-
-void
-SendDevicePresenceEvent(int deviceid, int type)
-{
-    DeviceIntRec dummyDev;
-    devicePresenceNotify ev;
-
-    memset(&dummyDev, 0, sizeof(DeviceIntRec));
-    ev.type = DevicePresenceNotify;
-    ev.time = currentTime.milliseconds;
-    ev.devchange = type;
-    ev.deviceid = deviceid;
-    dummyDev.id = XIAllDevices;
-    SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
-                          (xEvent*)&ev, 1);
-}
-
-/**
- * Enable the device through the driver, add the device to the device list.
- * Switch device ON through the driver and push it onto the global device
- * list. Initialize the DIX sprite or pair the device. All clients are
- * notified about the device being enabled.
- *
- * A master pointer device needs to be enabled before a master keyboard
- * device.
- *
- * @param The device to be enabled.
- * @param sendevent True if an XI2 event should be sent.
- * @return TRUE on success or FALSE otherwise.
- */
-Bool
-EnableDevice(DeviceIntPtr dev, BOOL sendevent)
-{
-    DeviceIntPtr *prev;
-    int ret;
-    DeviceIntPtr other;
-    BOOL enabled;
-    int flags[MAXDEVICES] = {0};
-
-    for (prev = &inputInfo.off_devices;
-	 *prev && (*prev != dev);
-	 prev = &(*prev)->next)
-	;
-
-    if (!dev->spriteInfo->sprite)
-    {
-        if (IsMaster(dev))
-        {
-            /* Sprites appear on first root window, so we can hardcode it */
-            if (dev->spriteInfo->spriteOwner)
-            {
-                InitializeSprite(dev, screenInfo.screens[0]->root);
-                                                 /* mode doesn't matter */
-                EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor);
-            }
-            else if ((other = NextFreePointerDevice()) == NULL)
-            {
-                ErrorF("[dix] cannot find pointer to pair with. "
-                       "This is a bug.\n");
-                return FALSE;
-            } else
-                PairDevices(NULL, other, dev);
-        } else
-        {
-            if (dev->coreEvents)
-                other = (IsPointerDevice(dev)) ? inputInfo.pointer :
-                    inputInfo.keyboard;
-            else
-                other = NULL; /* auto-float non-core devices */
-            AttachDevice(NULL, dev, other);
-        }
-    }
-
-    if ((*prev != dev) || !dev->inited ||
-	((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
-        ErrorF("[dix] couldn't enable device %d\n", dev->id);
-	return FALSE;
-    }
-    dev->enabled = TRUE;
-    *prev = dev->next;
-
-    for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next)
-        ;
-    *prev = dev;
-    dev->next = NULL;
-
-    enabled = TRUE;
-    XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
-                           XA_INTEGER, 8, PropModeReplace, 1, &enabled,
-                           TRUE);
-
-    SendDevicePresenceEvent(dev->id, DeviceEnabled);
-    if (sendevent)
-    {
-        flags[dev->id] |= XIDeviceEnabled;
-        XISendDeviceHierarchyEvent(flags);
-    }
-
-    RecalculateMasterButtons(dev);
-
-    return TRUE;
-}
-
-/**
- * Switch a device off through the driver and push it onto the off_devices
- * list. A device will not send events while disabled. All clients are
- * notified about the device being disabled.
- *
- * Master keyboard devices have to be disabled before master pointer devices
- * otherwise things turn bad.
- *
- * @param sendevent True if an XI2 event should be sent.
- * @return TRUE on success or FALSE otherwise.
- */
-Bool
-DisableDevice(DeviceIntPtr dev, BOOL sendevent)
-{
-    DeviceIntPtr *prev, other;
-    BOOL enabled;
-    int flags[MAXDEVICES] = {0};
-
-    for (prev = &inputInfo.devices;
-	 *prev && (*prev != dev);
-	 prev = &(*prev)->next)
-	;
-    if (*prev != dev)
-	return FALSE;
-
-    /* float attached devices */
-    if (IsMaster(dev))
-    {
-        for (other = inputInfo.devices; other; other = other->next)
-        {
-            if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev)
-            {
-                AttachDevice(NULL, other, NULL);
-                flags[other->id] |= XISlaveDetached;
-            }
-        }
-    }
-    else
-    {
-        for (other = inputInfo.devices; other; other = other->next)
-        {
-	    if (IsMaster(other) && other->lastSlave == dev)
-		other->lastSlave = NULL;
-	}
-    }
-
-    if (IsMaster(dev) && dev->spriteInfo->sprite)
-    {
-        for (other = inputInfo.devices; other; other = other->next)
-        {
-            if (other->spriteInfo->paired == dev)
-            {
-                ErrorF("[dix] cannot disable device, still paired. "
-                        "This is a bug. \n");
-                return FALSE;
-            }
-        }
-    }
-
-    (void)(*dev->deviceProc)(dev, DEVICE_OFF);
-    dev->enabled = FALSE;
-
-    /* now that the device is disabled, we can reset the signal handler's
-     * last.slave */
-    OsBlockSignals();
-    for (other = inputInfo.devices; other; other = other->next)
-    {
-        if (other->last.slave == dev)
-            other->last.slave = NULL;
-    }
-    OsReleaseSignals();
-
-    LeaveWindow(dev);
-    SetFocusOut(dev);
-
-    *prev = dev->next;
-    dev->next = inputInfo.off_devices;
-    inputInfo.off_devices = dev;
-
-    enabled = FALSE;
-    XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
-                           XA_INTEGER, 8, PropModeReplace, 1, &enabled,
-                           TRUE);
-
-    SendDevicePresenceEvent(dev->id, DeviceDisabled);
-    if (sendevent)
-    {
-        flags[dev->id] = XIDeviceDisabled;
-        XISendDeviceHierarchyEvent(flags);
-    }
-
-    RecalculateMasterButtons(dev);
-
-    return TRUE;
-}
-
-/**
- * Initialise a new device through the driver and tell all clients about the
- * new device.
- *
- * Must be called before EnableDevice.
- * The device will NOT send events until it is enabled!
- *
- * @param sendevent True if an XI2 event should be sent.
- * @return Success or an error code on failure.
- */
-int
-ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
-{
-    int ret = Success;
-    ScreenPtr pScreen = screenInfo.screens[0];
-
-    if (!dev || !dev->deviceProc)
-        return BadImplementation;
-
-    ret = (*dev->deviceProc) (dev, DEVICE_INIT);
-    dev->inited = (ret == Success);
-    if (!dev->inited)
-        return ret;
-
-    /* Initialize memory for sprites. */
-    if (IsMaster(dev) && dev->spriteInfo->spriteOwner)
-        if (!pScreen->DeviceCursorInitialize(dev, pScreen))
-            ret = BadAlloc;
-
-    SendDevicePresenceEvent(dev->id, DeviceAdded);
-    if (sendevent)
-    {
-        int flags[MAXDEVICES] = {0};
-        flags[dev->id] = XISlaveAdded;
-        XISendDeviceHierarchyEvent(flags);
-    }
-    return ret;
-}
-
-/**
- * Ring the bell.
- * The actual task of ringing the bell is the job of the DDX.
- */
-static void
-CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
-{
-    KeybdCtrl *ctrl = arg;
-
-    DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
-}
-
-static void
-CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
-{
-    return;
-}
-
-/**
- * Device control function for the Virtual Core Keyboard.
- */
-int
-CoreKeyboardProc(DeviceIntPtr pDev, int what)
-{
-
-    switch (what) {
-    case DEVICE_INIT:
-        if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell,
-                                      CoreKeyboardCtl))
-        {
-            ErrorF("Keyboard initialization failed. This could be a missing "
-                   "or incorrect setup of xkeyboard-config.\n");
-            return BadValue;
-        }
-        return Success;
-
-    case DEVICE_ON:
-    case DEVICE_OFF:
-        return Success;
-
-    case DEVICE_CLOSE:
-        return Success;
-    }
-
-    return BadMatch;
-}
-
-/**
- * Device control function for the Virtual Core Pointer.
- */
-int
-CorePointerProc(DeviceIntPtr pDev, int what)
-{
-#define NBUTTONS 10
-#define NAXES 2
-    BYTE map[NBUTTONS + 1];
-    int i = 0;
-    Atom btn_labels[NBUTTONS] = {0};
-    Atom axes_labels[NAXES] = {0};
-
-    switch (what) {
-    case DEVICE_INIT:
-        for (i = 1; i <= NBUTTONS; i++)
-            map[i] = i;
-
-	btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
-	btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
-	btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
-	btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
-	btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
-	btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
-	btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
-	/* don't know about the rest */
-
-	axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
-	axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
-
-        if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels,
-                                (PtrCtrlProcPtr)NoopDDA,
-                                GetMotionHistorySize(), NAXES, axes_labels))
-        {
-            ErrorF("Could not initialize device '%s'. Out of memory.\n",
-                   pDev->name);
-            return BadAlloc; /* IPDS only fails on allocs */
-        }
-        pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
-        pDev->last.valuators[0] = pDev->valuator->axisVal[0];
-        pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
-        pDev->last.valuators[1] = pDev->valuator->axisVal[1];
-        break;
-
-    case DEVICE_CLOSE:
-        break;
-
-    default:
-        break;
-    }
-
-    return Success;
-
-#undef NBUTTONS
-#undef NAXES
-}
-
-/**
- * Initialise the two core devices, VCP and VCK (see events.c).
- * Both devices are not tied to physical devices, but guarantee that there is
- * always a keyboard and a pointer present and keep the protocol semantics.
- *
- * Note that the server MUST have two core devices at all times, even if there
- * is no physical device connected.
- */
-void
-InitCoreDevices(void)
-{
-    if (AllocDevicePair(serverClient, "Virtual core",
-                        &inputInfo.pointer, &inputInfo.keyboard,
-                        CorePointerProc, CoreKeyboardProc,
-                        TRUE) != Success)
-        FatalError("Failed to allocate core devices");
-
-    if (ActivateDevice(inputInfo.pointer, TRUE) != Success ||
-        ActivateDevice(inputInfo.keyboard, TRUE) != Success)
-        FatalError("Failed to activate core devices.");
-    if (!EnableDevice(inputInfo.pointer, TRUE) ||
-        !EnableDevice(inputInfo.keyboard, TRUE))
-        FatalError("Failed to enable core devices.");
-
-    InitXTestDevices();
-}
-
-/**
- * Activate all switched-off devices and then enable all those devices.
- *
- * Will return an error if no core keyboard or core pointer is present.
- * In theory this should never happen if you call InitCoreDevices() first.
- *
- * InitAndStartDevices needs to be called AFTER the windows are initialized.
- * Devices will start sending events after InitAndStartDevices() has
- * completed.
- *
- * @return Success or error code on failure.
- */
-int
-InitAndStartDevices(void)
-{
-    DeviceIntPtr dev, next;
-
-    for (dev = inputInfo.off_devices; dev; dev = dev->next) {
-        DebugF("(dix) initialising device %d\n", dev->id);
-        if (!dev->inited)
-            ActivateDevice(dev, TRUE);
-    }
-
-    /* enable real devices */
-    for (dev = inputInfo.off_devices; dev; dev = next)
-    {
-        DebugF("(dix) enabling device %d\n", dev->id);
-	next = dev->next;
-	if (dev->inited && dev->startup)
-	    EnableDevice(dev, TRUE);
-    }
-
-    return Success;
-}
-
-/**
- * Free the given device class and reset the pointer to NULL.
- */
-static void
-FreeDeviceClass(int type, pointer *class)
-{
-    if (!(*class))
-        return;
-
-    switch(type)
-    {
-        case KeyClass:
-            {
-                KeyClassPtr* k = (KeyClassPtr*)class;
-                if ((*k)->xkbInfo)
-                {
-                    XkbFreeInfo((*k)->xkbInfo);
-                    (*k)->xkbInfo = NULL;
-                }
-                free((*k));
-                break;
-            }
-        case ButtonClass:
-            {
-                ButtonClassPtr *b = (ButtonClassPtr*)class;
-                free((*b)->xkb_acts);
-                free((*b));
-                break;
-            }
-        case ValuatorClass:
-            {
-                ValuatorClassPtr *v = (ValuatorClassPtr*)class;
-
-                free((*v)->motion);
-                free((*v));
-                break;
-            }
-        case FocusClass:
-            {
-                FocusClassPtr *f = (FocusClassPtr*)class;
-                free((*f)->trace);
-                free((*f));
-                break;
-            }
-        case ProximityClass:
-            {
-                ProximityClassPtr *p = (ProximityClassPtr*)class;
-                free((*p));
-                break;
-            }
-    }
-    *class = NULL;
-}
-
-static void
-FreeFeedbackClass(int type, pointer *class)
-{
-    if (!(*class))
-        return;
-
-    switch(type)
-    {
-        case KbdFeedbackClass:
-            {
-                KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr*)class;
-                KbdFeedbackPtr k, knext;
-                for (k = (*kbdfeed); k; k = knext) {
-                    knext = k->next;
-                    if (k->xkb_sli)
-                        XkbFreeSrvLedInfo(k->xkb_sli);
-                    free(k);
-                }
-                break;
-            }
-        case PtrFeedbackClass:
-            {
-                PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr*)class;
-                PtrFeedbackPtr p, pnext;
-
-                for (p = (*ptrfeed); p; p = pnext) {
-                    pnext = p->next;
-                    free(p);
-                }
-                break;
-            }
-        case IntegerFeedbackClass:
-            {
-                IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr*)class;
-                IntegerFeedbackPtr i, inext;
-
-                for (i = (*intfeed); i; i = inext) {
-                    inext = i->next;
-                    free(i);
-                }
-                break;
-            }
-        case StringFeedbackClass:
-            {
-                StringFeedbackPtr *stringfeed = (StringFeedbackPtr*)class;
-                StringFeedbackPtr s, snext;
-
-                for (s = (*stringfeed); s; s = snext) {
-                    snext = s->next;
-                    free(s->ctrl.symbols_supported);
-                    free(s->ctrl.symbols_displayed);
-                    free(s);
-                }
-                break;
-            }
-        case BellFeedbackClass:
-            {
-                BellFeedbackPtr *bell = (BellFeedbackPtr*)class;
-                BellFeedbackPtr b, bnext;
-
-                for (b = (*bell); b; b = bnext) {
-                    bnext = b->next;
-                    free(b);
-                }
-                break;
-            }
-        case LedFeedbackClass:
-            {
-                LedFeedbackPtr *leds = (LedFeedbackPtr*)class;
-                LedFeedbackPtr l, lnext;
-
-                for (l = (*leds); l; l = lnext) {
-                    lnext = l->next;
-                    if (l->xkb_sli)
-                        XkbFreeSrvLedInfo(l->xkb_sli);
-                    free(l);
-                }
-                break;
-            }
-    }
-    *class = NULL;
-}
-
-static void
-FreeAllDeviceClasses(ClassesPtr classes)
-{
-    if (!classes)
-        return;
-
-    FreeDeviceClass(KeyClass, (pointer)&classes->key);
-    FreeDeviceClass(ValuatorClass, (pointer)&classes->valuator);
-    FreeDeviceClass(ButtonClass, (pointer)&classes->button);
-    FreeDeviceClass(FocusClass, (pointer)&classes->focus);
-    FreeDeviceClass(ProximityClass, (pointer)&classes->proximity);
-
-    FreeFeedbackClass(KbdFeedbackClass, (pointer)&classes->kbdfeed);
-    FreeFeedbackClass(PtrFeedbackClass, (pointer)&classes->ptrfeed);
-    FreeFeedbackClass(IntegerFeedbackClass, (pointer)&classes->intfeed);
-    FreeFeedbackClass(StringFeedbackClass, (pointer)&classes->stringfeed);
-    FreeFeedbackClass(BellFeedbackClass, (pointer)&classes->bell);
-    FreeFeedbackClass(LedFeedbackClass, (pointer)&classes->leds);
-
-}
-
-/**
- * Close down a device and free all resources.
- * Once closed down, the driver will probably not expect you that you'll ever
- * enable it again and free associated structs. If you want the device to just
- * be disabled, DisableDevice().
- * Don't call this function directly, use RemoveDevice() instead.
- */
-static void
-CloseDevice(DeviceIntPtr dev)
-{
-    ScreenPtr screen = screenInfo.screens[0];
-    ClassesPtr classes;
-    int j;
-
-    if (!dev)
-        return;
-
-    XIDeleteAllDeviceProperties(dev);
-
-    if (dev->inited)
-	(void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
-
-    /* free sprite memory */
-    if (IsMaster(dev) && dev->spriteInfo->sprite)
-        screen->DeviceCursorCleanup(dev, screen);
-
-    /* free acceleration info */
-    if(dev->valuator && dev->valuator->accelScheme.AccelCleanupProc)
-	dev->valuator->accelScheme.AccelCleanupProc(dev);
-
-    while (dev->xkb_interest)
-	XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
-
-    free(dev->name);
-
-    classes = (ClassesPtr)&dev->key;
-    FreeAllDeviceClasses(classes);
-
-    if (IsMaster(dev))
-    {
-        classes = dev->unused_classes;
-        FreeAllDeviceClasses(classes);
-	free(classes);
-    }
-
-    if (DevHasCursor(dev) && dev->spriteInfo->sprite) {
-	if (dev->spriteInfo->sprite->current)
-	    FreeCursor(dev->spriteInfo->sprite->current, None);
-        free(dev->spriteInfo->sprite->spriteTrace);
-        free(dev->spriteInfo->sprite);
-    }
-
-    /* a client may have the device set as client pointer */
-    for (j = 0; j < currentMaxClients; j++)
-    {
-        if (clients[j] && clients[j]->clientPtr == dev)
-        {
-            clients[j]->clientPtr = NULL;
-            clients[j]->clientPtr = PickPointer(clients[j]);
-        }
-    }
-
-    free(dev->deviceGrab.sync.event);
-    dixFreeObjectWithPrivates(dev, PRIVATE_DEVICE);
-}
-
-/**
- * Shut down all devices of one list and free all resources.
- */
-static
-void
-CloseDeviceList(DeviceIntPtr *listHead)
-{
-    /* Used to mark devices that we tried to free */
-    Bool freedIds[MAXDEVICES];
-    DeviceIntPtr dev;
-    int i;
-
-    if (listHead == NULL)
-        return;
-
-    for (i = 0; i < MAXDEVICES; i++)
-        freedIds[i] = FALSE;
-
-    dev = *listHead;
-    while (dev != NULL)
-    {
-        freedIds[dev->id] = TRUE;
-        DeleteInputDeviceRequest(dev);
-
-        dev = *listHead;
-        while (dev != NULL && freedIds[dev->id])
-            dev = dev->next;
-    }
-}
-
-/**
- * Shut down all devices, free all resources, etc.
- * Only useful if you're shutting down the server!
- */
-void
-CloseDownDevices(void)
-{
-    DeviceIntPtr dev;
-
-    /* Float all SDs before closing them. Note that at this point resources
-     * (e.g. cursors) have been freed already, so we can't just call
-     * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
-     * to NULL and pretend nothing happened.
-     */
-    for (dev = inputInfo.devices; dev; dev = dev->next)
-    {
-        if (!IsMaster(dev) && !IsFloating(dev))
-            dev->master = NULL;
-    }
-
-    CloseDeviceList(&inputInfo.devices);
-    CloseDeviceList(&inputInfo.off_devices);
-
-    CloseDevice(inputInfo.pointer);
-    CloseDevice(inputInfo.keyboard);
-
-    inputInfo.devices = NULL;
-    inputInfo.off_devices = NULL;
-    inputInfo.keyboard = NULL;
-    inputInfo.pointer = NULL;
-    XkbDeleteRulesDflts();
-}
-
-/**
- * Remove the cursor sprite for all devices. This needs to be done before any
- * resources are freed or any device is deleted.
- */
-void
-UndisplayDevices(void)
-{
-    DeviceIntPtr dev;
-    ScreenPtr screen = screenInfo.screens[0];
-
-    for (dev = inputInfo.devices; dev; dev = dev->next)
-        screen->DisplayCursor(dev, screen, NullCursor);
-}
-
-/**
- * Remove a device from the device list, closes it and thus frees all
- * resources.
- * Removes both enabled and disabled devices and notifies all devices about
- * the removal of the device.
- *
- * No PresenceNotify is sent for device that the client never saw. This can
- * happen if a malloc fails during the addition of master devices. If
- * dev->init is FALSE it means the client never received a DeviceAdded event,
- * so let's not send a DeviceRemoved event either.
- *
- * @param sendevent True if an XI2 event should be sent.
- */
-int
-RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
-{
-    DeviceIntPtr prev,tmp,next;
-    int ret = BadMatch;
-    ScreenPtr screen = screenInfo.screens[0];
-    int deviceid;
-    int initialized;
-    int flags[MAXDEVICES] = {0};
-
-    DebugF("(dix) removing device %d\n", dev->id);
-
-    if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
-        return BadImplementation;
-
-    initialized = dev->inited;
-    deviceid = dev->id;
-
-    if (initialized)
-    {
-        if (DevHasCursor(dev))
-            screen->DisplayCursor(dev, screen, NullCursor);
-
-        DisableDevice(dev, sendevent);
-        flags[dev->id] = XIDeviceDisabled;
-    }
-
-    prev = NULL;
-    for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
-	next = tmp->next;
-	if (tmp == dev) {
-
-	    if (prev==NULL)
-		inputInfo.devices = next;
-	    else
-		prev->next = next;
-
-	    flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
-	    CloseDevice(tmp);
-	    ret = Success;
-	}
-    }
-
-    prev = NULL;
-    for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
-	next = tmp->next;
-	if (tmp == dev) {
-	    flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
-	    CloseDevice(tmp);
-
-	    if (prev == NULL)
-		inputInfo.off_devices = next;
-	    else
-		prev->next = next;
-
-            ret = Success;
-	}
-    }
-
-    if (ret == Success && initialized) {
-        inputInfo.numDevices--;
-        SendDevicePresenceEvent(deviceid, DeviceRemoved);
-        if (sendevent)
-            XISendDeviceHierarchyEvent(flags);
-    }
-
-    return ret;
-}
-
-int
-NumMotionEvents(void)
-{
-    /* only called to fill data in initial connection reply.
-     * VCP is ok here, it is the only fixed device we have. */
-    return inputInfo.pointer->valuator->numMotionEvents;
-}
-
-int
-dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode)
-{
-    DeviceIntPtr dev;
-    int rc;
-    *pDev = NULL;
-
-    for (dev=inputInfo.devices; dev; dev=dev->next) {
-        if (dev->id == id)
-            goto found;
-    }
-    for (dev=inputInfo.off_devices; dev; dev=dev->next) {
-        if (dev->id == id)
-	    goto found;
-    }
-    return BadDevice;
-
-found:
-    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
-    if (rc == Success)
-	*pDev = dev;
-    return rc;
-}
-
-void
-QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
-{
-    if (inputInfo.keyboard) {
-	*minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code;
-	*maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code;
-    }
-}
-
-/* Notably, this function does not expand the destination's keycode range, or
- * notify clients. */
-Bool
-SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
-{
-    int i, j;
-    KeySym *tmp;
-    int rowDif = src->minKeyCode - dst->minKeyCode;
-
-    /* if keysym map size changes, grow map first */
-    if (src->mapWidth < dst->mapWidth) {
-        for (i = src->minKeyCode; i <= src->maxKeyCode; i++) {
-#define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c))
-#define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c))
-	    for (j = 0; j < src->mapWidth; j++)
-		dst->map[DI(i, j)] = src->map[SI(i, j)];
-	    for (j = src->mapWidth; j < dst->mapWidth; j++)
-		dst->map[DI(i, j)] = NoSymbol;
-#undef SI
-#undef DI
-	}
-	return TRUE;
-    }
-    else if (src->mapWidth > dst->mapWidth) {
-        i = sizeof(KeySym) * src->mapWidth *
-             (dst->maxKeyCode - dst->minKeyCode + 1);
-        tmp = calloc(sizeof(KeySym), i);
-        if (!tmp)
-            return FALSE;
-
-        if (dst->map) {
-            for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
-                memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth],
-                        dst->mapWidth * sizeof(KeySym));
-            free(dst->map);
-        }
-        dst->mapWidth = src->mapWidth;
-        dst->map = tmp;
-    }
-    else if (!dst->map) {
-        i = sizeof(KeySym) * src->mapWidth *
-             (dst->maxKeyCode - dst->minKeyCode + 1);
-        tmp = calloc(sizeof(KeySym), i);
-        if (!tmp)
-            return FALSE;
-
-        dst->map = tmp;
-        dst->mapWidth = src->mapWidth;
-    }
-
-    memmove(&dst->map[rowDif * dst->mapWidth], src->map,
-            (src->maxKeyCode - src->minKeyCode + 1) *
-            dst->mapWidth * sizeof(KeySym));
-
-    return TRUE;
-}
-
-Bool
-InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels,
-                            CARD8 *map)
-{
-    ButtonClassPtr butc;
-    int i;
-
-    butc = calloc(1, sizeof(ButtonClassRec));
-    if (!butc)
-	return FALSE;
-    butc->numButtons = numButtons;
-    butc->sourceid = dev->id;
-    for (i = 1; i <= numButtons; i++)
-	butc->map[i] = map[i];
-    for (i = numButtons + 1; i < MAP_LENGTH; i++)
-        butc->map[i] = i;
-    memcpy(butc->labels, labels, numButtons * sizeof(Atom));
-    dev->button = butc;
-    return TRUE;
-}
-
-Bool
-InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
-                              int numMotionEvents, int mode)
-{
-    int i;
-    ValuatorClassPtr valc;
-    union align_u { ValuatorClassRec valc; double d; } *align;
-
-    if (!dev)
-        return FALSE;
-
-    if (numAxes > MAX_VALUATORS)
-    {
-        LogMessage(X_WARNING,
-                   "Device '%s' has %d axes, only using first %d.\n",
-                   dev->name, numAxes, MAX_VALUATORS);
-        numAxes = MAX_VALUATORS;
-    }
-
-    align = (union align_u *) calloc(1, sizeof(union align_u) +
-				     numAxes * sizeof(double) +
-				     numAxes * sizeof(AxisInfo));
-    if (!align)
-	return FALSE;
-
-    valc = &align->valc;
-    valc->sourceid = dev->id;
-    valc->motion = NULL;
-    valc->first_motion = 0;
-    valc->last_motion = 0;
-
-    valc->numMotionEvents = numMotionEvents;
-    valc->motionHintWindow = NullWindow;
-    valc->numAxes = numAxes;
-    valc->axisVal = (double *)(align + 1);
-    valc->axes = (AxisInfoPtr)(valc->axisVal + numAxes);
-
-    if (mode & OutOfProximity)
-        InitProximityClassDeviceStruct(dev);
-
-    dev->valuator = valc;
-
-    AllocateMotionHistory(dev);
-
-    for (i=0; i<numAxes; i++) {
-        InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS,
-                               0, 0, 0, mode);
-	valc->axisVal[i]=0;
-    }
-
-    dev->last.numValuators = numAxes;
-
-    if (IsMaster(dev) || /* do not accelerate master or xtest devices */
-        IsXTestDevice(dev, NULL))
-	InitPointerAccelerationScheme(dev, PtrAccelNoOp);
-    else
-	InitPointerAccelerationScheme(dev, PtrAccelDefault);
-    return TRUE;
-}
-
-/* global list of acceleration schemes */
-ValuatorAccelerationRec pointerAccelerationScheme[] = {
-    {PtrAccelNoOp, NULL, NULL, NULL, NULL},
-    {PtrAccelPredictable, acceleratePointerPredictable, NULL,
-        InitPredictableAccelerationScheme, AccelerationDefaultCleanup},
-    {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL},
-    {-1, NULL, NULL, NULL, NULL} /* terminator */
-};
-
-/**
- * install an acceleration scheme. returns TRUE on success, and should not
- * change anything if unsuccessful.
- */
-Bool
-InitPointerAccelerationScheme(DeviceIntPtr dev,
-                              int scheme)
-{
-    int x, i = -1;
-    ValuatorClassPtr val;
-
-    val = dev->valuator;
-
-    if (!val)
-        return FALSE;
-
-    if (IsMaster(dev) && scheme != PtrAccelNoOp)
-        return FALSE;
-
-    for (x = 0; pointerAccelerationScheme[x].number >= 0; x++) {
-        if(pointerAccelerationScheme[x].number == scheme){
-            i = x;
-            break;
-        }
-    }
-
-    if (-1 == i)
-        return FALSE;
-
-    if (val->accelScheme.AccelCleanupProc)
-        val->accelScheme.AccelCleanupProc(dev);
-
-    if (pointerAccelerationScheme[i].AccelInitProc) {
-        if (!pointerAccelerationScheme[i].AccelInitProc(dev,
-                                            &pointerAccelerationScheme[i])) {
-            return FALSE;
-        }
-    } else {
-        val->accelScheme = pointerAccelerationScheme[i];
-    }
-    return TRUE;
-}
-
-Bool
-InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
-{
-    AbsoluteClassPtr abs;
-
-    abs = malloc(sizeof(AbsoluteClassRec));
-    if (!abs)
-        return FALSE;
-
-    /* we don't do anything sensible with these, but should */
-    abs->min_x = NO_AXIS_LIMITS;
-    abs->min_y = NO_AXIS_LIMITS;
-    abs->max_x = NO_AXIS_LIMITS;
-    abs->max_y = NO_AXIS_LIMITS;
-    abs->flip_x = 0;
-    abs->flip_y = 0;
-    abs->rotation = 0;
-    abs->button_threshold = 0;
-
-    abs->offset_x = 0;
-    abs->offset_y = 0;
-    abs->width = NO_AXIS_LIMITS;
-    abs->height = NO_AXIS_LIMITS;
-    abs->following = 0;
-    abs->screen = 0;
-
-    abs->sourceid = dev->id;
-
-    dev->absolute = abs;
-
-    return TRUE;
-}
-
-Bool
-InitFocusClassDeviceStruct(DeviceIntPtr dev)
-{
-    FocusClassPtr focc;
-
-    focc = malloc(sizeof(FocusClassRec));
-    if (!focc)
-	return FALSE;
-    focc->win = PointerRootWin;
-    focc->revert = None;
-    focc->time = currentTime;
-    focc->trace = (WindowPtr *)NULL;
-    focc->traceSize = 0;
-    focc->traceGood = 0;
-    focc->sourceid = dev->id;
-    dev->focus = focc;
-    return TRUE;
-}
-
-Bool
-InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
-{
-    PtrFeedbackPtr feedc;
-
-    feedc = malloc(sizeof(PtrFeedbackClassRec));
-    if (!feedc)
-	return FALSE;
-    feedc->CtrlProc = controlProc;
-    feedc->ctrl = defaultPointerControl;
-    feedc->ctrl.id = 0;
-    if ( (feedc->next = dev->ptrfeed) )
-        feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
-    dev->ptrfeed = feedc;
-    (*controlProc)(dev, &feedc->ctrl);
-    return TRUE;
-}
-
-
-static LedCtrl defaultLedControl = {
-	DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
-
-static BellCtrl defaultBellControl = {
-	DEFAULT_BELL,
-	DEFAULT_BELL_PITCH,
-	DEFAULT_BELL_DURATION,
-	0};
-
-static IntegerCtrl defaultIntegerControl = {
-	DEFAULT_INT_RESOLUTION,
-	DEFAULT_INT_MIN_VALUE,
-	DEFAULT_INT_MAX_VALUE,
-	DEFAULT_INT_DISPLAYED,
-	0};
-
-Bool
-InitStringFeedbackClassDeviceStruct (
-      DeviceIntPtr dev, StringCtrlProcPtr controlProc,
-      int max_symbols, int num_symbols_supported, KeySym *symbols)
-{
-    int i;
-    StringFeedbackPtr feedc;
-
-    feedc = malloc(sizeof(StringFeedbackClassRec));
-    if (!feedc)
-	return FALSE;
-    feedc->CtrlProc = controlProc;
-    feedc->ctrl.num_symbols_supported = num_symbols_supported;
-    feedc->ctrl.num_symbols_displayed = 0;
-    feedc->ctrl.max_symbols = max_symbols;
-    feedc->ctrl.symbols_supported = malloc(sizeof (KeySym) * num_symbols_supported);
-    feedc->ctrl.symbols_displayed = malloc(sizeof (KeySym) * max_symbols);
-    if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
-    {
-	free(feedc->ctrl.symbols_supported);
-	free(feedc->ctrl.symbols_displayed);
-	free(feedc);
-	return FALSE;
-    }
-    for (i=0; i<num_symbols_supported; i++)
-	*(feedc->ctrl.symbols_supported+i) = *symbols++;
-    for (i=0; i<max_symbols; i++)
-	*(feedc->ctrl.symbols_displayed+i) = (KeySym) 0;
-    feedc->ctrl.id = 0;
-    if ( (feedc->next = dev->stringfeed) )
-	feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
-    dev->stringfeed = feedc;
-    (*controlProc)(dev, &feedc->ctrl);
-    return TRUE;
-}
-
-Bool
-InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
-                                   BellCtrlProcPtr controlProc)
-{
-    BellFeedbackPtr feedc;
-
-    feedc = malloc(sizeof(BellFeedbackClassRec));
-    if (!feedc)
-	return FALSE;
-    feedc->CtrlProc = controlProc;
-    feedc->BellProc = bellProc;
-    feedc->ctrl = defaultBellControl;
-    feedc->ctrl.id = 0;
-    if ( (feedc->next = dev->bell) )
-	feedc->ctrl.id = dev->bell->ctrl.id + 1;
-    dev->bell = feedc;
-    (*controlProc)(dev, &feedc->ctrl);
-    return TRUE;
-}
-
-Bool
-InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
-{
-    LedFeedbackPtr feedc;
-
-    feedc = malloc(sizeof(LedFeedbackClassRec));
-    if (!feedc)
-	return FALSE;
-    feedc->CtrlProc = controlProc;
-    feedc->ctrl = defaultLedControl;
-    feedc->ctrl.id = 0;
-    if ( (feedc->next = dev->leds) )
-	feedc->ctrl.id = dev->leds->ctrl.id + 1;
-    feedc->xkb_sli= NULL;
-    dev->leds = feedc;
-    (*controlProc)(dev, &feedc->ctrl);
-    return TRUE;
-}
-
-Bool
-InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc)
-{
-    IntegerFeedbackPtr feedc;
-
-    feedc = malloc(sizeof(IntegerFeedbackClassRec));
-    if (!feedc)
-	return FALSE;
-    feedc->CtrlProc = controlProc;
-    feedc->ctrl = defaultIntegerControl;
-    feedc->ctrl.id = 0;
-    if ( (feedc->next = dev->intfeed) )
-	feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
-    dev->intfeed = feedc;
-    (*controlProc)(dev, &feedc->ctrl);
-    return TRUE;
-}
-
-Bool
-InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom* btn_labels,
-                        PtrCtrlProcPtr controlProc, int numMotionEvents,
-                        int numAxes, Atom *axes_labels)
-{
-    DeviceIntPtr dev = (DeviceIntPtr)device;
-
-    return(InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) &&
-	   InitValuatorClassDeviceStruct(dev, numAxes, axes_labels,
-					 numMotionEvents, Relative) &&
-	   InitPtrFeedbackClassDeviceStruct(dev, controlProc));
-}
-
-/*
- * Check if the given buffer contains elements between low (inclusive) and
- * high (inclusive) only.
- *
- * @return TRUE if the device map is invalid, FALSE otherwise.
- */
-Bool
-BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
-{
-    int i;
-
-    for (i = 0; i < length; i++)
-	if (buff[i])		       /* only check non-zero elements */
-	{
-	    if ((low > buff[i]) || (high < buff[i]))
-	    {
-		*errval = buff[i];
-		return TRUE;
-	    }
-	}
-    return FALSE;
-}
-
-int
-ProcSetModifierMapping(ClientPtr client)
-{
-    xSetModifierMappingReply rep;
-    int rc;
-    REQUEST(xSetModifierMappingReq);
-    REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
-
-    if (client->req_len != ((stuff->numKeyPerModifier << 1) +
-                bytes_to_int32(sizeof(xSetModifierMappingReq))))
-	return BadLength;
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-
-    rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1],
-                       stuff->numKeyPerModifier);
-    if (rc == MappingFailed || rc == -1)
-        return BadValue;
-    if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
-        rc != MappingBusy)
-	return rc;
-
-    rep.success = rc;
-
-    WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
-    return Success;
-}
-
-int
-ProcGetModifierMapping(ClientPtr client)
-{
-    xGetModifierMappingReply rep;
-    int max_keys_per_mod = 0;
-    KeyCode *modkeymap = NULL;
-    REQUEST_SIZE_MATCH(xReq);
-
-    generate_modkeymap(client, PickKeyboard(client), &modkeymap,
-                       &max_keys_per_mod);
-
-    memset(&rep, 0, sizeof(xGetModifierMappingReply));
-    rep.type = X_Reply;
-    rep.numKeyPerModifier = max_keys_per_mod;
-    rep.sequenceNumber = client->sequence;
-    /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
-    rep.length = max_keys_per_mod << 1;
-
-    WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
-    (void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap);
-
-    free(modkeymap);
-
-    return Success;
-}
-
-int
-ProcChangeKeyboardMapping(ClientPtr client)
-{
-    REQUEST(xChangeKeyboardMappingReq);
-    unsigned len;
-    KeySymsRec keysyms;
-    DeviceIntPtr pDev, tmp;
-    int rc;
-    REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
-
-    len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq));
-    if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
-            return BadLength;
-
-    pDev = PickKeyboard(client);
-
-    if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) ||
-	(stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) {
-	    client->errorValue = stuff->firstKeyCode;
-	    return BadValue;
-
-    }
-    if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
-          pDev->key->xkbInfo->desc->max_key_code) ||
-        (stuff->keySymsPerKeyCode == 0)) {
-	    client->errorValue = stuff->keySymsPerKeyCode;
-	    return BadValue;
-    }
-
-    keysyms.minKeyCode = stuff->firstKeyCode;
-    keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
-    keysyms.mapWidth = stuff->keySymsPerKeyCode;
-    keysyms.map = (KeySym *) &stuff[1];
-
-    rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
-    if (rc != Success)
-        return rc;
-
-    XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode,
-                          stuff->keyCodes, NULL, client);
-
-    for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
-        if (IsMaster(tmp) || GetMaster(tmp, MASTER_KEYBOARD) != pDev)
-            continue;
-        if (!tmp->key)
-            continue;
-
-        rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
-        if (rc != Success)
-            continue;
-
-        XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode,
-                              stuff->keyCodes, NULL, client);
-    }
-
-    return Success;
-}
-
-int
-ProcSetPointerMapping(ClientPtr client)
-{
-    BYTE *map;
-    int ret;
-    int i, j;
-    DeviceIntPtr ptr = PickPointer(client);
-    xSetPointerMappingReply rep;
-    REQUEST(xSetPointerMappingReq);
-    REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
-
-    if (client->req_len !=
-            bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts))
-	return BadLength;
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.success = MappingSuccess;
-    map = (BYTE *)&stuff[1];
-
-    /* So we're bounded here by the number of core buttons.  This check
-     * probably wants disabling through XFixes. */
-    /* MPX: With ClientPointer, we can return the right number of buttons.
-     * Let's just hope nobody changed ClientPointer between GetPointerMapping
-     * and SetPointerMapping
-     */
-    if (stuff->nElts != ptr->button->numButtons) {
-	client->errorValue = stuff->nElts;
-	return BadValue;
-    }
-
-    /* Core protocol specs don't allow for duplicate mappings; this check
-     * almost certainly wants disabling through XFixes too. */
-    for (i = 0; i < stuff->nElts; i++) {
-        for (j = i + 1; j < stuff->nElts; j++) {
-            if (map[i] && map[i] == map[j]) {
-                client->errorValue = map[i];
-                return BadValue;
-            }
-        }
-    }
-
-    ret = ApplyPointerMapping(ptr, map, stuff->nElts, client);
-    if (ret == MappingBusy)
-        rep.success = ret;
-    else if (ret == -1)
-        return BadValue;
-    else if (ret != Success)
-        return ret;
-
-    WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
-    return Success;
-}
-
-int
-ProcGetKeyboardMapping(ClientPtr client)
-{
-    xGetKeyboardMappingReply rep;
-    DeviceIntPtr kbd = PickKeyboard(client);
-    XkbDescPtr xkb;
-    KeySymsPtr syms;
-    int rc;
-    REQUEST(xGetKeyboardMappingReq);
-    REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
-
-    rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
-    if (rc != Success)
-	return rc;
-
-    xkb = kbd->key->xkbInfo->desc;
-
-    if ((stuff->firstKeyCode < xkb->min_key_code) ||
-        (stuff->firstKeyCode > xkb->max_key_code)) {
-	client->errorValue = stuff->firstKeyCode;
-	return BadValue;
-    }
-    if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) {
-	client->errorValue = stuff->count;
-        return BadValue;
-    }
-
-    syms = XkbGetCoreMap(kbd);
-    if (!syms)
-        return BadAlloc;
-
-    memset(&rep, 0, sizeof(xGetKeyboardMappingReply));
-    rep.type = X_Reply;
-    rep.sequenceNumber = client->sequence;
-    rep.keySymsPerKeyCode = syms->mapWidth;
-    /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
-    rep.length = syms->mapWidth * stuff->count;
-    WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
-    client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
-    WriteSwappedDataToClient(client,
-                             syms->mapWidth * stuff->count * sizeof(KeySym),
-                             &syms->map[syms->mapWidth * (stuff->firstKeyCode -
-                                                          syms->minKeyCode)]);
-    free(syms->map);
-    free(syms);
-
-    return Success;
-}
-
-int
-ProcGetPointerMapping(ClientPtr client)
-{
-    xGetPointerMappingReply rep;
-    /* Apps may get different values each time they call GetPointerMapping as
-     * the ClientPointer could change. */
-    DeviceIntPtr ptr = PickPointer(client);
-    ButtonClassPtr butc = ptr->button;
-    int rc;
-    REQUEST_SIZE_MATCH(xReq);
-
-    rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
-    if (rc != Success)
-	return rc;
-
-    rep.type = X_Reply;
-    rep.sequenceNumber = client->sequence;
-    rep.nElts = (butc) ? butc->numButtons : 0;
-    rep.length = ((unsigned)rep.nElts + (4-1))/4;
-    WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
-    if (butc)
-        WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]);
-    return Success;
-}
-
-void
-NoteLedState(DeviceIntPtr keybd, int led, Bool on)
-{
-    KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
-    if (on)
-	ctrl->leds |= ((Leds)1 << (led - 1));
-    else
-	ctrl->leds &= ~((Leds)1 << (led - 1));
-}
-
-int
-Ones(unsigned long mask)             /* HACKMEM 169 */
-{
-    unsigned long y;
-
-    y = (mask >> 1) &033333333333;
-    y = mask - y - ((y >>1) & 033333333333);
-    return (((y + (y >> 3)) & 030707070707) % 077);
-}
-
-static int
-DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
-                         BITS32 vmask)
-{
-#define DO_ALL    (-1)
-    KeybdCtrl ctrl;
-    int t;
-    int led = DO_ALL;
-    int key = DO_ALL;
-    BITS32 index2;
-    int mask = vmask, i;
-    XkbEventCauseRec cause;
-
-    ctrl = keybd->kbdfeed->ctrl;
-    while (vmask) {
-	index2 = (BITS32) lowbit (vmask);
-	vmask &= ~index2;
-	switch (index2) {
-	case KBKeyClickPercent:
-	    t = (INT8)*vlist;
-	    vlist++;
-	    if (t == -1) {
-		t = defaultKeyboardControl.click;
-            }
-	    else if (t < 0 || t > 100) {
-		client->errorValue = t;
-		return BadValue;
-	    }
-	    ctrl.click = t;
-	    break;
-	case KBBellPercent:
-	    t = (INT8)*vlist;
-	    vlist++;
-	    if (t == -1) {
-		t = defaultKeyboardControl.bell;
-            }
-	    else if (t < 0 || t > 100) {
-		client->errorValue = t;
-		return BadValue;
-	    }
-	    ctrl.bell = t;
-	    break;
-	case KBBellPitch:
-	    t = (INT16)*vlist;
-	    vlist++;
-	    if (t == -1) {
-		t = defaultKeyboardControl.bell_pitch;
-            }
-	    else if (t < 0) {
-		client->errorValue = t;
-		return BadValue;
-	    }
-	    ctrl.bell_pitch = t;
-	    break;
-	case KBBellDuration:
-	    t = (INT16)*vlist;
-	    vlist++;
-	    if (t == -1)
-		t = defaultKeyboardControl.bell_duration;
-	    else if (t < 0) {
-		client->errorValue = t;
-		return BadValue;
-	    }
-	    ctrl.bell_duration = t;
-	    break;
-	case KBLed:
-	    led = (CARD8)*vlist;
-	    vlist++;
-	    if (led < 1 || led > 32) {
-		client->errorValue = led;
-		return BadValue;
-	    }
-	    if (!(mask & KBLedMode))
-		return BadMatch;
-	    break;
-	case KBLedMode:
-	    t = (CARD8)*vlist;
-	    vlist++;
-	    if (t == LedModeOff) {
-		if (led == DO_ALL)
-		    ctrl.leds = 0x0;
-		else
-		    ctrl.leds &= ~(((Leds)(1)) << (led - 1));
-	    }
-	    else if (t == LedModeOn) {
-		if (led == DO_ALL)
-		    ctrl.leds = ~0L;
-		else
-		    ctrl.leds |= (((Leds)(1)) << (led - 1));
-	    }
-	    else {
-		client->errorValue = t;
-		return BadValue;
-	    }
-
-            XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
-            XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
- 			     ctrl.leds, &cause);
-            ctrl.leds = keybd->kbdfeed->ctrl.leds;
-
-	    break;
-	case KBKey:
-	    key = (KeyCode)*vlist;
-	    vlist++;
-	    if ((KeyCode)key < keybd->key->xkbInfo->desc->min_key_code ||
-		(KeyCode)key > keybd->key->xkbInfo->desc->max_key_code) {
-		client->errorValue = key;
-		return BadValue;
-	    }
-	    if (!(mask & KBAutoRepeatMode))
-		return BadMatch;
-	    break;
-	case KBAutoRepeatMode:
-	    i = (key >> 3);
-	    mask = (1 << (key & 7));
-	    t = (CARD8)*vlist;
-	    vlist++;
-            if (key != DO_ALL)
-                XkbDisableComputedAutoRepeats(keybd,key);
-	    if (t == AutoRepeatModeOff) {
-		if (key == DO_ALL)
-		    ctrl.autoRepeat = FALSE;
-		else
-		    ctrl.autoRepeats[i] &= ~mask;
-	    }
-	    else if (t == AutoRepeatModeOn) {
-		if (key == DO_ALL)
-		    ctrl.autoRepeat = TRUE;
-		else
-		    ctrl.autoRepeats[i] |= mask;
-	    }
-	    else if (t == AutoRepeatModeDefault) {
-		if (key == DO_ALL)
-		    ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
-		else
-		    ctrl.autoRepeats[i] =
-			    (ctrl.autoRepeats[i] & ~mask) |
-			    (defaultKeyboardControl.autoRepeats[i] & mask);
-	    }
-	    else {
-		client->errorValue = t;
-		return BadValue;
-	    }
-	    break;
-	default:
-	    client->errorValue = mask;
-	    return BadValue;
-	}
-    }
-    keybd->kbdfeed->ctrl = ctrl;
-
-    /* The XKB RepeatKeys control and core protocol global autorepeat */
-    /* value are linked	*/
-    XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
-
-    return Success;
-
-#undef DO_ALL
-}
-
-/**
- * Changes kbd control on the ClientPointer and all attached SDs.
- */
-int
-ProcChangeKeyboardControl (ClientPtr client)
-{
-    XID *vlist;
-    BITS32 vmask;
-    int ret = Success, error = Success;
-    DeviceIntPtr pDev = NULL, keyboard;
-    REQUEST(xChangeKeyboardControlReq);
-
-    REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
-
-    vmask = stuff->mask;
-    vlist = (XID *)&stuff[1];
-
-    if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
-	return BadLength;
-
-    keyboard = PickKeyboard(client);
-
-    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
-        if ((pDev == keyboard ||
-	     (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
-	    && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
-            ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
-	    if (ret != Success)
-                return ret;
-        }
-    }
-
-    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
-        if ((pDev == keyboard ||
-	     (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
-	    && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
-            ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
-            if (ret != Success)
-                error = ret;
-        }
-    }
-
-    return error;
-}
-
-int
-ProcGetKeyboardControl (ClientPtr client)
-{
-    int rc, i;
-    DeviceIntPtr kbd = PickKeyboard(client);
-    KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl;
-    xGetKeyboardControlReply rep;
-    REQUEST_SIZE_MATCH(xReq);
-
-    rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
-    if (rc != Success)
-	return rc;
-
-    rep.type = X_Reply;
-    rep.length = 5;
-    rep.sequenceNumber = client->sequence;
-    rep.globalAutoRepeat = ctrl->autoRepeat;
-    rep.keyClickPercent = ctrl->click;
-    rep.bellPercent = ctrl->bell;
-    rep.bellPitch = ctrl->bell_pitch;
-    rep.bellDuration = ctrl->bell_duration;
-    rep.ledMask = ctrl->leds;
-    for (i = 0; i < 32; i++)
-	rep.map[i] = ctrl->autoRepeats[i];
-    WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
-    return Success;
-}
-
-int
-ProcBell(ClientPtr client)
-{
-    DeviceIntPtr dev, keybd = PickKeyboard(client);
-    int base = keybd->kbdfeed->ctrl.bell;
-    int newpercent;
-    int rc;
-    REQUEST(xBellReq);
-    REQUEST_SIZE_MATCH(xBellReq);
-
-    if (stuff->percent < -100 || stuff->percent > 100) {
-	client->errorValue = stuff->percent;
-	return BadValue;
-    }
-
-    newpercent = (base * stuff->percent) / 100;
-    if (stuff->percent < 0)
-        newpercent = base + newpercent;
-    else
-	newpercent = base - newpercent + stuff->percent;
-
-    for (dev = inputInfo.devices; dev; dev = dev->next) {
-        if ((dev == keybd ||
-	     (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) &&
-            dev->kbdfeed && dev->kbdfeed->BellProc) {
-
-	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess);
-	    if (rc != Success)
-		return rc;
-            XkbHandleBell(FALSE, FALSE, dev, newpercent,
-                          &dev->kbdfeed->ctrl, 0, None, NULL, client);
-        }
-    }
-
-    return Success;
-}
-
-int
-ProcChangePointerControl(ClientPtr client)
-{
-    DeviceIntPtr dev, mouse = PickPointer(client);
-    PtrCtrl ctrl;		/* might get BadValue part way through */
-    int rc;
-    REQUEST(xChangePointerControlReq);
-    REQUEST_SIZE_MATCH(xChangePointerControlReq);
-
-    ctrl = mouse->ptrfeed->ctrl;
-    if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
-	client->errorValue = stuff->doAccel;
-	return BadValue;
-    }
-    if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
-	client->errorValue = stuff->doThresh;
-	return BadValue;
-    }
-    if (stuff->doAccel) {
-	if (stuff->accelNum == -1) {
-	    ctrl.num = defaultPointerControl.num;
-        }
-	else if (stuff->accelNum < 0) {
-	    client->errorValue = stuff->accelNum;
-	    return BadValue;
-	}
-	else {
-            ctrl.num = stuff->accelNum;
-        }
-
-	if (stuff->accelDenum == -1) {
-	    ctrl.den = defaultPointerControl.den;
-        }
-	else if (stuff->accelDenum <= 0) {
-	    client->errorValue = stuff->accelDenum;
-	    return BadValue;
-	}
-	else {
-            ctrl.den = stuff->accelDenum;
-        }
-    }
-    if (stuff->doThresh) {
-	if (stuff->threshold == -1) {
-	    ctrl.threshold = defaultPointerControl.threshold;
-        }
-	else if (stuff->threshold < 0) {
-	    client->errorValue = stuff->threshold;
-	    return BadValue;
-	}
-	else {
-            ctrl.threshold = stuff->threshold;
-        }
-    }
-
-    for (dev = inputInfo.devices; dev; dev = dev->next) {
-        if ((dev == mouse ||
-	     (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
-            dev->ptrfeed) {
-	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
-	    if (rc != Success)
-		return rc;
-	}
-    }
-
-    for (dev = inputInfo.devices; dev; dev = dev->next) {
-        if ((dev == mouse ||
-	     (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
-            dev->ptrfeed) {
-            dev->ptrfeed->ctrl = ctrl;
-        }
-    }
-
-    return Success;
-}
-
-int
-ProcGetPointerControl(ClientPtr client)
-{
-    DeviceIntPtr ptr = PickPointer(client);
-    PtrCtrl *ctrl = &ptr->ptrfeed->ctrl;
-    xGetPointerControlReply rep;
-    int rc;
-    REQUEST_SIZE_MATCH(xReq);
-
-    rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
-    if (rc != Success)
-	return rc;
-
-    rep.type = X_Reply;
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.threshold = ctrl->threshold;
-    rep.accelNumerator = ctrl->num;
-    rep.accelDenominator = ctrl->den;
-    WriteReplyToClient(client, sizeof(xGenericReply), &rep);
-    return Success;
-}
-
-void
-MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
-{
-    GrabPtr grab = dev->deviceGrab.grab;
-
-    if ((grab && SameClient(grab, client) &&
-	 ((grab->eventMask & PointerMotionHintMask) ||
-	  (grab->ownerEvents &&
-	   (EventMaskForClient(dev->valuator->motionHintWindow, client) &
-	    PointerMotionHintMask)))) ||
-	(!grab &&
-	 (EventMaskForClient(dev->valuator->motionHintWindow, client) &
-	  PointerMotionHintMask)))
-	dev->valuator->motionHintWindow = NullWindow;
-}
-
-int
-ProcGetMotionEvents(ClientPtr client)
-{
-    WindowPtr pWin;
-    xTimecoord * coords = (xTimecoord *) NULL;
-    xGetMotionEventsReply rep;
-    int i, count, xmin, xmax, ymin, ymax, rc;
-    unsigned long nEvents;
-    DeviceIntPtr mouse = PickPointer(client);
-    TimeStamp start, stop;
-    REQUEST(xGetMotionEventsReq);
-    REQUEST_SIZE_MATCH(xGetMotionEventsReq);
-
-    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
-    if (rc != Success)
-	return rc;
-    rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
-    if (rc != Success)
-	return rc;
-
-    if (mouse->valuator->motionHintWindow)
-	MaybeStopHint(mouse, client);
-    rep.type = X_Reply;
-    rep.sequenceNumber = client->sequence;
-    nEvents = 0;
-    start = ClientTimeToServerTime(stuff->start);
-    stop = ClientTimeToServerTime(stuff->stop);
-    if ((CompareTimeStamps(start, stop) != LATER) &&
-	(CompareTimeStamps(start, currentTime) != LATER) &&
-	mouse->valuator->numMotionEvents)
-    {
-	if (CompareTimeStamps(stop, currentTime) == LATER)
-	    stop = currentTime;
-	count = GetMotionHistory(mouse, &coords, start.milliseconds,
-				 stop.milliseconds, pWin->drawable.pScreen,
-                                 TRUE);
-	xmin = pWin->drawable.x - wBorderWidth (pWin);
-	xmax = pWin->drawable.x + (int)pWin->drawable.width +
-		wBorderWidth (pWin);
-	ymin = pWin->drawable.y - wBorderWidth (pWin);
-	ymax = pWin->drawable.y + (int)pWin->drawable.height +
-		wBorderWidth (pWin);
-	for (i = 0; i < count; i++)
-	    if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
-		    (ymin <= coords[i].y) && (coords[i].y < ymax))
-	    {
-		coords[nEvents].time = coords[i].time;
-		coords[nEvents].x = coords[i].x - pWin->drawable.x;
-		coords[nEvents].y = coords[i].y - pWin->drawable.y;
-		nEvents++;
-	    }
-    }
-    rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord));
-    rep.nEvents = nEvents;
-    WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
-    if (nEvents)
-    {
-	client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
-	WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
-				 (char *)coords);
-    }
-    free(coords);
-    return Success;
-}
-
-int
-ProcQueryKeymap(ClientPtr client)
-{
-    xQueryKeymapReply rep;
-    int rc, i;
-    DeviceIntPtr keybd = PickKeyboard(client);
-    CARD8 *down = keybd->key->down;
-
-    REQUEST_SIZE_MATCH(xReq);
-    rep.type = X_Reply;
-    rep.sequenceNumber = client->sequence;
-    rep.length = 2;
-
-    rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
-    if (rc != Success && rc != BadAccess)
-	return rc;
-
-    for (i = 0; i<32; i++)
-	rep.map[i] = down[i];
-
-    if (rc == BadAccess)
-	memset(rep.map, 0, 32);
-
-    WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
-
-   return Success;
-}
-
-
-/**
- * Recalculate the number of buttons for the master device. The number of
- * buttons on the master device is equal to the number of buttons on the
- * slave device with the highest number of buttons.
- */
-static void
-RecalculateMasterButtons(DeviceIntPtr slave)
-{
-    DeviceIntPtr dev, master;
-    int maxbuttons = 0;
-
-    if (!slave->button || IsMaster(slave))
-        return;
-
-    master = GetMaster(slave, MASTER_POINTER);
-    if (!master)
-        return;
-
-    for (dev = inputInfo.devices; dev; dev = dev->next)
-    {
-        if (IsMaster(dev) ||
-            GetMaster(dev, MASTER_ATTACHED) != master ||
-            !dev->button)
-            continue;
-
-        maxbuttons = max(maxbuttons, dev->button->numButtons);
-    }
-
-    if (master->button && master->button->numButtons != maxbuttons)
-    {
-        int i;
-        DeviceChangedEvent event;
-
-        memset(&event, 0, sizeof(event));
-
-        master->button->numButtons = maxbuttons;
-
-        event.header = ET_Internal;
-        event.type = ET_DeviceChanged;
-        event.time = GetTimeInMillis();
-        event.deviceid = master->id;
-        event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE;
-        event.buttons.num_buttons = maxbuttons;
-        memcpy(&event.buttons.names, master->button->labels, maxbuttons *
-                sizeof(Atom));
-
-        if (master->valuator)
-        {
-            event.num_valuators = master->valuator->numAxes;
-            for (i = 0; i < event.num_valuators; i++)
-            {
-                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;
-                event.valuators[i].mode = master->valuator->axes[i].mode;
-                event.valuators[i].name = master->valuator->axes[i].label;
-            }
-        }
-
-        if (master->key)
-        {
-            event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code;
-            event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code;
-        }
-
-        XISendDeviceChangedEvent(master, master, &event);
-    }
-}
-
-/**
- * Generate release events for all keys/button currently down on this
- * device.
- */
-static void
-ReleaseButtonsAndKeys(DeviceIntPtr dev)
-{
-    EventListPtr        eventlist = InitEventList(GetMaximumEventsNum());
-    ButtonClassPtr      b = dev->button;
-    KeyClassPtr         k = dev->key;
-    int                 i, j, nevents;
-
-    if (!eventlist) /* no release events for you */
-        return;
-
-    /* Release all buttons */
-    for (i = 0; b && i < b->numButtons; i++)
-    {
-        if (BitIsOn(b->down, i))
-        {
-            nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL);
-            for (j = 0; j < nevents; j++)
-                mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL);
-        }
-    }
-
-    /* Release all keys */
-    for (i = 0; k && i < MAP_LENGTH; i++)
-    {
-        if (BitIsOn(k->down, i))
-        {
-            nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i);
-            for (j = 0; j < nevents; j++)
-                mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL);
-        }
-    }
-
-    FreeEventList(eventlist, GetMaximumEventsNum());
-}
-
-/**
- * Attach device 'dev' to device 'master'.
- * Client is set to the client that issued the request, or NULL if it comes
- * from some internal automatic pairing.
- *
- * Master may be NULL to set the device floating.
- *
- * We don't allow multi-layer hierarchies right now. You can't attach a slave
- * to another slave.
- */
-int
-AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
-{
-    ScreenPtr screen;
-    DeviceIntPtr oldmaster;
-    if (!dev || IsMaster(dev))
-        return BadDevice;
-
-    if (master && !IsMaster(master)) /* can't attach to slaves */
-        return BadDevice;
-
-    /* set from floating to floating? */
-    if (IsFloating(dev) && !master && dev->enabled)
-        return Success;
-
-    /* free the existing sprite. */
-    if (IsFloating(dev) && dev->spriteInfo->paired == dev)
-    {
-        screen = miPointerGetScreen(dev);
-        screen->DeviceCursorCleanup(dev, screen);
-        free(dev->spriteInfo->sprite);
-    }
-
-    ReleaseButtonsAndKeys(dev);
-
-    oldmaster = GetMaster(dev, MASTER_ATTACHED);
-    dev->master = master;
-
-    /* If device is set to floating, we need to create a sprite for it,
-     * otherwise things go bad. However, we don't want to render the cursor,
-     * so we reset spriteOwner.
-     * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
-     * alloc new memory but overwrite the previous one.
-     */
-    if (!master)
-    {
-        WindowPtr currentRoot;
-
-        if (dev->spriteInfo->sprite)
-            currentRoot = GetCurrentRootWindow(dev);
-        else /* new device auto-set to floating */
-            currentRoot = screenInfo.screens[0]->root;
-
-        /* we need to init a fake sprite */
-        screen = currentRoot->drawable.pScreen;
-        screen->DeviceCursorInitialize(dev, screen);
-        dev->spriteInfo->sprite = NULL;
-        InitializeSprite(dev, currentRoot);
-        dev->spriteInfo->spriteOwner = FALSE;
-        dev->spriteInfo->paired = dev;
-    } else
-    {
-        dev->spriteInfo->sprite = master->spriteInfo->sprite;
-        dev->spriteInfo->paired = master;
-        dev->spriteInfo->spriteOwner = FALSE;
-
-        RecalculateMasterButtons(master);
-    }
-
-    /* XXX: in theory, the MD should change back to its old, original
-     * classes when the last SD is detached. Thanks to the XTEST devices,
-     * we'll always have an SD attached until the MD is removed.
-     * So let's not worry about that.
-     */
-
-    return Success;
-}
-
-/**
- * Return the device paired with the given device or NULL.
- * Returns the device paired with the parent master if the given device is a
- * slave device.
- */
-DeviceIntPtr
-GetPairedDevice(DeviceIntPtr dev)
-{
-    if (!IsMaster(dev) && !IsFloating(dev))
-        dev = GetMaster(dev, MASTER_ATTACHED);
-
-    return dev->spriteInfo->paired;
-}
-
-
-/**
- * Returns the right master for the type of event needed. If the event is a
- * keyboard event.
- * This function may be called with a master device as argument. If so, the
- * returned master is either the device itself or the paired master device.
- * If dev is a floating slave device, NULL is returned.
- *
- * @type ::MASTER_KEYBOARD or ::MASTER_POINTER or ::MASTER_ATTACHED
- * @return The requested master device. In the case of MASTER_ATTACHED, this
- * is the directly attached master to this device, regardless of the type.
- * Otherwise, it is either the master keyboard or pointer for this device.
- */
-DeviceIntPtr
-GetMaster(DeviceIntPtr dev, int which)
-{
-    DeviceIntPtr master;
-
-    if (IsMaster(dev))
-        master = dev;
-    else
-        master = dev->master;
-
-    if (master && which != MASTER_ATTACHED)
-    {
-        if (which == MASTER_KEYBOARD)
-        {
-            if (master->type != MASTER_KEYBOARD)
-                master = GetPairedDevice(master);
-        } else
-        {
-            if (master->type != MASTER_POINTER)
-                master = GetPairedDevice(master);
-        }
-    }
-
-    return master;
-}
-
-/**
- * Create a new device pair (== one pointer, one keyboard device).
- * Only allocates the devices, you will need to call ActivateDevice() and
- * EnableDevice() manually.
- * Either a master or a slave device can be created depending on
- * the value for master.
- */
-int
-AllocDevicePair (ClientPtr client, char* name,
-                 DeviceIntPtr* ptr,
-                 DeviceIntPtr* keybd,
-                 DeviceProc ptr_proc,
-                 DeviceProc keybd_proc,
-                 Bool master)
-{
-    DeviceIntPtr pointer;
-    DeviceIntPtr keyboard;
-    *ptr = *keybd = NULL;
-
-    pointer = AddInputDevice(client, ptr_proc, TRUE);
-    if (!pointer)
-        return BadAlloc;
-
-    if (asprintf(&pointer->name, "%s pointer", name) == -1) {
-        pointer->name = NULL;
-        RemoveDevice(pointer, FALSE);
-        return BadAlloc;
-    }
-
-    pointer->public.processInputProc = ProcessOtherEvent;
-    pointer->public.realInputProc = ProcessOtherEvent;
-    XkbSetExtension(pointer, ProcessPointerEvent);
-    pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
-    pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
-    pointer->coreEvents = TRUE;
-    pointer->spriteInfo->spriteOwner = TRUE;
-
-    pointer->lastSlave = NULL;
-    pointer->last.slave = NULL;
-    pointer->type = (master) ? MASTER_POINTER : SLAVE;
-
-    keyboard = AddInputDevice(client, keybd_proc, TRUE);
-    if (!keyboard)
-    {
-        RemoveDevice(pointer, FALSE);
-        return BadAlloc;
-    }
-
-    if (asprintf(&keyboard->name, "%s keyboard", name) == -1) {
-        keyboard->name = NULL;
-        RemoveDevice(keyboard, FALSE);
-        RemoveDevice(pointer, FALSE);
-        return BadAlloc;
-    }
-
-    keyboard->public.processInputProc = ProcessOtherEvent;
-    keyboard->public.realInputProc = ProcessOtherEvent;
-    XkbSetExtension(keyboard, ProcessKeyboardEvent);
-    keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
-    keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
-    keyboard->coreEvents = TRUE;
-    keyboard->spriteInfo->spriteOwner = FALSE;
-
-    keyboard->lastSlave = NULL;
-    keyboard->last.slave = NULL;
-    keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
-
-    /* The ClassesRec stores the device classes currently not used. */
-    pointer->unused_classes = calloc(1, sizeof(ClassesRec));
-    keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
-
-    *ptr = pointer;
-    *keybd = keyboard;
-
-    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[i].mode = mode;
-    }
-}
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+********************************************************/
+
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "ptrveloc.h"
+#include "site.h"
+#include "xkbsrv.h"
+#include "privates.h"
+#include "xace.h"
+#include "mi.h"
+
+#include "dispatch.h"
+#include "swaprep.h"
+#include "dixevents.h"
+#include "mipointer.h"
+#include "eventstr.h"
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
+#include <X11/extensions/XIproto.h>
+#include <math.h>
+#include <pixman.h>
+#include "exglobals.h"
+#include "exevents.h"
+#include "xiquerydevice.h" /* for SizeDeviceClasses */
+#include "xiproperty.h"
+#include "enterleave.h" /* for EnterWindow() */
+#include "xserver-properties.h"
+#include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */
+
+/** @file
+ * This file handles input device-related stuff.
+ */
+
+static void RecalculateMasterButtons(DeviceIntPtr slave);
+
+static void
+DeviceSetTransform(DeviceIntPtr dev, float *transform)
+{
+    struct pixman_f_transform scale;
+    double sx, sy;
+    int x, y;
+
+    /**
+     * calculate combined transformation matrix:
+     *
+     * M = InvScale * Transform * Scale
+     *
+     * So we can later transform points using M * p
+     *
+     * Where:
+     *  Scale scales coordinates into 0..1 range
+     *  Transform is the user supplied (affine) transform
+     *  InvScale scales coordinates back up into their native range
+     */
+    sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value;
+    sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value;
+
+    /* invscale */
+    pixman_f_transform_init_scale(&scale, sx, sy);
+    scale.m[0][2] = dev->valuator->axes[0].min_value;
+    scale.m[1][2] = dev->valuator->axes[1].min_value;
+
+    /* transform */
+    for (y=0; y<3; y++)
+        for (x=0; x<3; x++)
+            dev->transform.m[y][x] = *transform++;
+
+    pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
+
+    /* scale */
+    pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
+    scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
+    scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
+
+    pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
+}
+
+/**
+ * DIX property handler.
+ */
+static int
+DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
+                  BOOL checkonly)
+{
+    if (property == XIGetKnownProperty(XI_PROP_ENABLED))
+    {
+        if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
+            return BadValue;
+
+        /* Don't allow disabling of VCP/VCK */
+        if ((dev == inputInfo.pointer || dev == inputInfo.keyboard) &&
+            !(*(CARD8*)prop->data))
+            return BadAccess;
+
+        if (!checkonly)
+        {
+            if ((*((CARD8*)prop->data)) && !dev->enabled)
+                EnableDevice(dev, TRUE);
+            else if (!(*((CARD8*)prop->data)) && dev->enabled)
+                DisableDevice(dev, TRUE);
+        }
+    } else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM))
+    {
+        float *f = (float*)prop->data;
+        int i;
+
+        if (prop->format != 32 || prop->size != 9 ||
+            prop->type != XIGetKnownProperty(XATOM_FLOAT))
+            return BadValue;
+
+        for (i=0; i<9; i++)
+            if (!isfinite(f[i]))
+                return BadValue;
+
+        if (!checkonly)
+            DeviceSetTransform(dev, f);
+    }
+
+    return Success;
+}
+
+/* Pair the keyboard to the pointer device. Keyboard events will follow the
+ * pointer sprite. Only applicable for master devices.
+ * If the client is set, the request to pair comes from some client. In this
+ * case, we need to check for access. If the client is NULL, it's from an
+ * internal automatic pairing, we must always permit this.
+ */
+static int
+PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd)
+{
+    if (!ptr)
+        return BadDevice;
+
+    /* Don't allow pairing for slave devices */
+    if (!IsMaster(ptr) || !IsMaster(kbd))
+        return BadDevice;
+
+    if (ptr->spriteInfo->paired)
+        return BadDevice;
+
+    if (kbd->spriteInfo->spriteOwner)
+    {
+        free(kbd->spriteInfo->sprite);
+        kbd->spriteInfo->sprite = NULL;
+        kbd->spriteInfo->spriteOwner = FALSE;
+    }
+
+    kbd->spriteInfo->sprite = ptr->spriteInfo->sprite;
+    kbd->spriteInfo->paired = ptr;
+    ptr->spriteInfo->paired = kbd;
+    return Success;
+}
+
+
+/**
+ * Find and return the next unpaired MD pointer device.
+ */
+static DeviceIntPtr
+NextFreePointerDevice(void)
+{
+    DeviceIntPtr dev;
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+        if (IsMaster(dev) &&
+                dev->spriteInfo->spriteOwner &&
+                !dev->spriteInfo->paired)
+            return dev;
+    return NULL;
+}
+
+/**
+ * Create a new input device and init it to sane values. The device is added
+ * to the server's off_devices list.
+ *
+ * @param deviceProc Callback for device control function (switch dev on/off).
+ * @return The newly created device.
+ */
+DeviceIntPtr
+AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
+{
+    DeviceIntPtr dev, *prev; /* not a typo */
+    DeviceIntPtr devtmp;
+    int devid;
+    char devind[MAXDEVICES];
+    BOOL enabled;
+    float transform[9];
+
+    /* Find next available id, 0 and 1 are reserved */
+    memset(devind, 0, sizeof(char)*MAXDEVICES);
+    for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
+	devind[devtmp->id]++;
+    for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
+	devind[devtmp->id]++;
+    for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++)
+	;
+
+    if (devid >= MAXDEVICES)
+	return (DeviceIntPtr)NULL;
+    dev =  _dixAllocateObjectWithPrivates(sizeof(DeviceIntRec) + sizeof(SpriteInfoRec),
+					  sizeof(DeviceIntRec) + sizeof(SpriteInfoRec),
+					  offsetof(DeviceIntRec, devPrivates), PRIVATE_DEVICE);
+    if (!dev)
+	return (DeviceIntPtr)NULL;
+    dev->id = devid;
+    dev->public.processInputProc = ProcessOtherEvent;
+    dev->public.realInputProc = ProcessOtherEvent;
+    dev->public.enqueueInputProc = EnqueueEvent;
+    dev->deviceProc = deviceProc;
+    dev->startup = autoStart;
+
+    /* device grab defaults */
+    dev->deviceGrab.grabTime = currentTime;
+    dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+    dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+
+    XkbSetExtension(dev, ProcessKeyboardEvent);
+
+    dev->coreEvents = TRUE;
+
+    /* sprite defaults */
+    dev->spriteInfo = (SpriteInfoPtr)&dev[1];
+
+    /*  security creation/labeling check
+     */
+    if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
+	free(dev);
+	return NULL;
+    }
+
+    inputInfo.numDevices++;
+
+    for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next)
+        ;
+    *prev = dev;
+    dev->next = NULL;
+
+    enabled = FALSE;
+    XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
+                           XA_INTEGER, 8, PropModeReplace, 1, &enabled,
+                           FALSE);
+    XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE);
+
+    /* unity matrix */
+    memset(transform, 0, sizeof(transform));
+    transform[0] = transform[4] = transform[8] = 1.0f;
+
+    XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
+                           XIGetKnownProperty(XATOM_FLOAT), 32,
+                           PropModeReplace, 9, transform, FALSE);
+    XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
+                                 FALSE);
+
+    XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL);
+
+    return dev;
+}
+
+void
+SendDevicePresenceEvent(int deviceid, int type)
+{
+    DeviceIntRec dummyDev;
+    devicePresenceNotify ev;
+
+    memset(&dummyDev, 0, sizeof(DeviceIntRec));
+    ev.type = DevicePresenceNotify;
+    ev.time = currentTime.milliseconds;
+    ev.devchange = type;
+    ev.deviceid = deviceid;
+    dummyDev.id = XIAllDevices;
+    SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
+                          (xEvent*)&ev, 1);
+}
+
+/**
+ * Enable the device through the driver, add the device to the device list.
+ * Switch device ON through the driver and push it onto the global device
+ * list. Initialize the DIX sprite or pair the device. All clients are
+ * notified about the device being enabled.
+ *
+ * A master pointer device needs to be enabled before a master keyboard
+ * device.
+ *
+ * @param The device to be enabled.
+ * @param sendevent True if an XI2 event should be sent.
+ * @return TRUE on success or FALSE otherwise.
+ */
+Bool
+EnableDevice(DeviceIntPtr dev, BOOL sendevent)
+{
+    DeviceIntPtr *prev;
+    int ret;
+    DeviceIntPtr other;
+    BOOL enabled;
+    int flags[MAXDEVICES] = {0};
+
+    for (prev = &inputInfo.off_devices;
+	 *prev && (*prev != dev);
+	 prev = &(*prev)->next)
+	;
+
+    if (!dev->spriteInfo->sprite)
+    {
+        if (IsMaster(dev))
+        {
+            /* Sprites appear on first root window, so we can hardcode it */
+            if (dev->spriteInfo->spriteOwner)
+            {
+                InitializeSprite(dev, screenInfo.screens[0]->root);
+                                                 /* mode doesn't matter */
+                EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor);
+            }
+            else if ((other = NextFreePointerDevice()) == NULL)
+            {
+                ErrorF("[dix] cannot find pointer to pair with. "
+                       "This is a bug.\n");
+                return FALSE;
+            } else
+                PairDevices(NULL, other, dev);
+        } else
+        {
+            if (dev->coreEvents)
+                other = (IsPointerDevice(dev)) ? inputInfo.pointer :
+                    inputInfo.keyboard;
+            else
+                other = NULL; /* auto-float non-core devices */
+            AttachDevice(NULL, dev, other);
+        }
+    }
+
+    if ((*prev != dev) || !dev->inited ||
+	((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
+        ErrorF("[dix] couldn't enable device %d\n", dev->id);
+	return FALSE;
+    }
+    dev->enabled = TRUE;
+    *prev = dev->next;
+
+    for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next)
+        ;
+    *prev = dev;
+    dev->next = NULL;
+
+    enabled = TRUE;
+    XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
+                           XA_INTEGER, 8, PropModeReplace, 1, &enabled,
+                           TRUE);
+
+    SendDevicePresenceEvent(dev->id, DeviceEnabled);
+    if (sendevent)
+    {
+        flags[dev->id] |= XIDeviceEnabled;
+        XISendDeviceHierarchyEvent(flags);
+    }
+
+    RecalculateMasterButtons(dev);
+
+    return TRUE;
+}
+
+/**
+ * Switch a device off through the driver and push it onto the off_devices
+ * list. A device will not send events while disabled. All clients are
+ * notified about the device being disabled.
+ *
+ * Master keyboard devices have to be disabled before master pointer devices
+ * otherwise things turn bad.
+ *
+ * @param sendevent True if an XI2 event should be sent.
+ * @return TRUE on success or FALSE otherwise.
+ */
+Bool
+DisableDevice(DeviceIntPtr dev, BOOL sendevent)
+{
+    DeviceIntPtr *prev, other;
+    BOOL enabled;
+    int flags[MAXDEVICES] = {0};
+
+    for (prev = &inputInfo.devices;
+	 *prev && (*prev != dev);
+	 prev = &(*prev)->next)
+	;
+    if (*prev != dev)
+	return FALSE;
+
+    /* float attached devices */
+    if (IsMaster(dev))
+    {
+        for (other = inputInfo.devices; other; other = other->next)
+        {
+            if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev)
+            {
+                AttachDevice(NULL, other, NULL);
+                flags[other->id] |= XISlaveDetached;
+            }
+        }
+    }
+    else
+    {
+        for (other = inputInfo.devices; other; other = other->next)
+        {
+	    if (IsMaster(other) && other->lastSlave == dev)
+		other->lastSlave = NULL;
+	}
+    }
+
+    if (IsMaster(dev) && dev->spriteInfo->sprite)
+    {
+        for (other = inputInfo.devices; other; other = other->next)
+        {
+            if (other->spriteInfo->paired == dev)
+            {
+                ErrorF("[dix] cannot disable device, still paired. "
+                        "This is a bug. \n");
+                return FALSE;
+            }
+        }
+    }
+
+    (void)(*dev->deviceProc)(dev, DEVICE_OFF);
+    dev->enabled = FALSE;
+
+    /* now that the device is disabled, we can reset the signal handler's
+     * last.slave */
+    OsBlockSignals();
+    for (other = inputInfo.devices; other; other = other->next)
+    {
+        if (other->last.slave == dev)
+            other->last.slave = NULL;
+    }
+    OsReleaseSignals();
+
+    LeaveWindow(dev);
+    SetFocusOut(dev);
+
+    *prev = dev->next;
+    dev->next = inputInfo.off_devices;
+    inputInfo.off_devices = dev;
+
+    enabled = FALSE;
+    XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
+                           XA_INTEGER, 8, PropModeReplace, 1, &enabled,
+                           TRUE);
+
+    SendDevicePresenceEvent(dev->id, DeviceDisabled);
+    if (sendevent)
+    {
+        flags[dev->id] = XIDeviceDisabled;
+        XISendDeviceHierarchyEvent(flags);
+    }
+
+    RecalculateMasterButtons(dev);
+
+    return TRUE;
+}
+
+/**
+ * Initialise a new device through the driver and tell all clients about the
+ * new device.
+ *
+ * Must be called before EnableDevice.
+ * The device will NOT send events until it is enabled!
+ *
+ * @param sendevent True if an XI2 event should be sent.
+ * @return Success or an error code on failure.
+ */
+int
+ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
+{
+    int ret = Success;
+    ScreenPtr pScreen = screenInfo.screens[0];
+
+    if (!dev || !dev->deviceProc)
+        return BadImplementation;
+
+    ret = (*dev->deviceProc) (dev, DEVICE_INIT);
+    dev->inited = (ret == Success);
+    if (!dev->inited)
+        return ret;
+
+    /* Initialize memory for sprites. */
+    if (IsMaster(dev) && dev->spriteInfo->spriteOwner)
+        if (!pScreen->DeviceCursorInitialize(dev, pScreen))
+            ret = BadAlloc;
+
+    SendDevicePresenceEvent(dev->id, DeviceAdded);
+    if (sendevent)
+    {
+        int flags[MAXDEVICES] = {0};
+        flags[dev->id] = XISlaveAdded;
+        XISendDeviceHierarchyEvent(flags);
+    }
+    return ret;
+}
+
+/**
+ * Ring the bell.
+ * The actual task of ringing the bell is the job of the DDX.
+ */
+static void
+CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
+{
+    KeybdCtrl *ctrl = arg;
+
+    DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
+}
+
+static void
+CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
+{
+    return;
+}
+
+/**
+ * Device control function for the Virtual Core Keyboard.
+ */
+int
+CoreKeyboardProc(DeviceIntPtr pDev, int what)
+{
+
+    switch (what) {
+    case DEVICE_INIT:
+        if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell,
+                                      CoreKeyboardCtl))
+        {
+            ErrorF("Keyboard initialization failed. This could be a missing "
+                   "or incorrect setup of xkeyboard-config.\n");
+            return BadValue;
+        }
+        return Success;
+
+    case DEVICE_ON:
+    case DEVICE_OFF:
+        return Success;
+
+    case DEVICE_CLOSE:
+        return Success;
+    }
+
+    return BadMatch;
+}
+
+/**
+ * Device control function for the Virtual Core Pointer.
+ */
+int
+CorePointerProc(DeviceIntPtr pDev, int what)
+{
+#define NBUTTONS 10
+#define NAXES 2
+    BYTE map[NBUTTONS + 1];
+    int i = 0;
+    Atom btn_labels[NBUTTONS] = {0};
+    Atom axes_labels[NAXES] = {0};
+
+    switch (what) {
+    case DEVICE_INIT:
+        for (i = 1; i <= NBUTTONS; i++)
+            map[i] = i;
+
+	btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+	btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+	btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+	btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
+	btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
+	btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
+	btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
+	/* don't know about the rest */
+
+	axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+	axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+
+        if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels,
+                                (PtrCtrlProcPtr)NoopDDA,
+                                GetMotionHistorySize(), NAXES, axes_labels))
+        {
+            ErrorF("Could not initialize device '%s'. Out of memory.\n",
+                   pDev->name);
+            return BadAlloc; /* IPDS only fails on allocs */
+        }
+        pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
+        pDev->last.valuators[0] = pDev->valuator->axisVal[0];
+        pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
+        pDev->last.valuators[1] = pDev->valuator->axisVal[1];
+        break;
+
+    case DEVICE_CLOSE:
+        break;
+
+    default:
+        break;
+    }
+
+    return Success;
+
+#undef NBUTTONS
+#undef NAXES
+}
+
+/**
+ * Initialise the two core devices, VCP and VCK (see events.c).
+ * Both devices are not tied to physical devices, but guarantee that there is
+ * always a keyboard and a pointer present and keep the protocol semantics.
+ *
+ * Note that the server MUST have two core devices at all times, even if there
+ * is no physical device connected.
+ */
+void
+InitCoreDevices(void)
+{
+    if (AllocDevicePair(serverClient, "Virtual core",
+                        &inputInfo.pointer, &inputInfo.keyboard,
+                        CorePointerProc, CoreKeyboardProc,
+                        TRUE) != Success)
+        FatalError("Failed to allocate core devices");
+
+    if (ActivateDevice(inputInfo.pointer, TRUE) != Success ||
+        ActivateDevice(inputInfo.keyboard, TRUE) != Success)
+        FatalError("Failed to activate core devices.");
+    if (!EnableDevice(inputInfo.pointer, TRUE) ||
+        !EnableDevice(inputInfo.keyboard, TRUE))
+        FatalError("Failed to enable core devices.");
+
+    InitXTestDevices();
+}
+
+/**
+ * Activate all switched-off devices and then enable all those devices.
+ *
+ * Will return an error if no core keyboard or core pointer is present.
+ * In theory this should never happen if you call InitCoreDevices() first.
+ *
+ * InitAndStartDevices needs to be called AFTER the windows are initialized.
+ * Devices will start sending events after InitAndStartDevices() has
+ * completed.
+ *
+ * @return Success or error code on failure.
+ */
+int
+InitAndStartDevices(void)
+{
+    DeviceIntPtr dev, next;
+
+    for (dev = inputInfo.off_devices; dev; dev = dev->next) {
+        DebugF("(dix) initialising device %d\n", dev->id);
+        if (!dev->inited)
+            ActivateDevice(dev, TRUE);
+    }
+
+    /* enable real devices */
+    for (dev = inputInfo.off_devices; dev; dev = next)
+    {
+        DebugF("(dix) enabling device %d\n", dev->id);
+	next = dev->next;
+	if (dev->inited && dev->startup)
+	    EnableDevice(dev, TRUE);
+    }
+
+    return Success;
+}
+
+/**
+ * Free the given device class and reset the pointer to NULL.
+ */
+static void
+FreeDeviceClass(int type, pointer *class)
+{
+    if (!(*class))
+        return;
+
+    switch(type)
+    {
+        case KeyClass:
+            {
+                KeyClassPtr* k = (KeyClassPtr*)class;
+                if ((*k)->xkbInfo)
+                {
+                    XkbFreeInfo((*k)->xkbInfo);
+                    (*k)->xkbInfo = NULL;
+                }
+                free((*k));
+                break;
+            }
+        case ButtonClass:
+            {
+                ButtonClassPtr *b = (ButtonClassPtr*)class;
+                free((*b)->xkb_acts);
+                free((*b));
+                break;
+            }
+        case ValuatorClass:
+            {
+                ValuatorClassPtr *v = (ValuatorClassPtr*)class;
+
+                free((*v)->motion);
+                free((*v));
+                break;
+            }
+        case FocusClass:
+            {
+                FocusClassPtr *f = (FocusClassPtr*)class;
+                free((*f)->trace);
+                free((*f));
+                break;
+            }
+        case ProximityClass:
+            {
+                ProximityClassPtr *p = (ProximityClassPtr*)class;
+                free((*p));
+                break;
+            }
+    }
+    *class = NULL;
+}
+
+static void
+FreeFeedbackClass(int type, pointer *class)
+{
+    if (!(*class))
+        return;
+
+    switch(type)
+    {
+        case KbdFeedbackClass:
+            {
+                KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr*)class;
+                KbdFeedbackPtr k, knext;
+                for (k = (*kbdfeed); k; k = knext) {
+                    knext = k->next;
+                    if (k->xkb_sli)
+                        XkbFreeSrvLedInfo(k->xkb_sli);
+                    free(k);
+                }
+                break;
+            }
+        case PtrFeedbackClass:
+            {
+                PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr*)class;
+                PtrFeedbackPtr p, pnext;
+
+                for (p = (*ptrfeed); p; p = pnext) {
+                    pnext = p->next;
+                    free(p);
+                }
+                break;
+            }
+        case IntegerFeedbackClass:
+            {
+                IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr*)class;
+                IntegerFeedbackPtr i, inext;
+
+                for (i = (*intfeed); i; i = inext) {
+                    inext = i->next;
+                    free(i);
+                }
+                break;
+            }
+        case StringFeedbackClass:
+            {
+                StringFeedbackPtr *stringfeed = (StringFeedbackPtr*)class;
+                StringFeedbackPtr s, snext;
+
+                for (s = (*stringfeed); s; s = snext) {
+                    snext = s->next;
+                    free(s->ctrl.symbols_supported);
+                    free(s->ctrl.symbols_displayed);
+                    free(s);
+                }
+                break;
+            }
+        case BellFeedbackClass:
+            {
+                BellFeedbackPtr *bell = (BellFeedbackPtr*)class;
+                BellFeedbackPtr b, bnext;
+
+                for (b = (*bell); b; b = bnext) {
+                    bnext = b->next;
+                    free(b);
+                }
+                break;
+            }
+        case LedFeedbackClass:
+            {
+                LedFeedbackPtr *leds = (LedFeedbackPtr*)class;
+                LedFeedbackPtr l, lnext;
+
+                for (l = (*leds); l; l = lnext) {
+                    lnext = l->next;
+                    if (l->xkb_sli)
+                        XkbFreeSrvLedInfo(l->xkb_sli);
+                    free(l);
+                }
+                break;
+            }
+    }
+    *class = NULL;
+}
+
+static void
+FreeAllDeviceClasses(ClassesPtr classes)
+{
+    if (!classes)
+        return;
+
+    FreeDeviceClass(KeyClass, (pointer)&classes->key);
+    FreeDeviceClass(ValuatorClass, (pointer)&classes->valuator);
+    FreeDeviceClass(ButtonClass, (pointer)&classes->button);
+    FreeDeviceClass(FocusClass, (pointer)&classes->focus);
+    FreeDeviceClass(ProximityClass, (pointer)&classes->proximity);
+
+    FreeFeedbackClass(KbdFeedbackClass, (pointer)&classes->kbdfeed);
+    FreeFeedbackClass(PtrFeedbackClass, (pointer)&classes->ptrfeed);
+    FreeFeedbackClass(IntegerFeedbackClass, (pointer)&classes->intfeed);
+    FreeFeedbackClass(StringFeedbackClass, (pointer)&classes->stringfeed);
+    FreeFeedbackClass(BellFeedbackClass, (pointer)&classes->bell);
+    FreeFeedbackClass(LedFeedbackClass, (pointer)&classes->leds);
+
+}
+
+/**
+ * Close down a device and free all resources.
+ * Once closed down, the driver will probably not expect you that you'll ever
+ * enable it again and free associated structs. If you want the device to just
+ * be disabled, DisableDevice().
+ * Don't call this function directly, use RemoveDevice() instead.
+ */
+static void
+CloseDevice(DeviceIntPtr dev)
+{
+    ScreenPtr screen = screenInfo.screens[0];
+    ClassesPtr classes;
+    int j;
+
+    if (!dev)
+        return;
+
+    XIDeleteAllDeviceProperties(dev);
+
+    if (dev->inited)
+	(void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
+
+    /* free sprite memory */
+    if (IsMaster(dev) && dev->spriteInfo->sprite)
+        screen->DeviceCursorCleanup(dev, screen);
+
+    /* free acceleration info */
+    if(dev->valuator && dev->valuator->accelScheme.AccelCleanupProc)
+	dev->valuator->accelScheme.AccelCleanupProc(dev);
+
+    while (dev->xkb_interest)
+	XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
+
+    free(dev->name);
+
+    classes = (ClassesPtr)&dev->key;
+    FreeAllDeviceClasses(classes);
+
+    if (IsMaster(dev))
+    {
+        classes = dev->unused_classes;
+        FreeAllDeviceClasses(classes);
+	free(classes);
+    }
+
+    if (DevHasCursor(dev) && dev->spriteInfo->sprite) {
+	if (dev->spriteInfo->sprite->current)
+	    FreeCursor(dev->spriteInfo->sprite->current, None);
+        free(dev->spriteInfo->sprite->spriteTrace);
+        free(dev->spriteInfo->sprite);
+    }
+
+    /* a client may have the device set as client pointer */
+    for (j = 0; j < currentMaxClients; j++)
+    {
+        if (clients[j] && clients[j]->clientPtr == dev)
+        {
+            clients[j]->clientPtr = NULL;
+            clients[j]->clientPtr = PickPointer(clients[j]);
+        }
+    }
+
+    free(dev->deviceGrab.sync.event);
+    free(dev->config_info);     /* Allocated in xf86ActivateDevice. */
+    dev->config_info = NULL;
+    dixFreeObjectWithPrivates(dev, PRIVATE_DEVICE);
+}
+
+/**
+ * Shut down all devices of one list and free all resources.
+ */
+static
+void
+CloseDeviceList(DeviceIntPtr *listHead)
+{
+    /* Used to mark devices that we tried to free */
+    Bool freedIds[MAXDEVICES];
+    DeviceIntPtr dev;
+    int i;
+
+    if (listHead == NULL)
+        return;
+
+    for (i = 0; i < MAXDEVICES; i++)
+        freedIds[i] = FALSE;
+
+    dev = *listHead;
+    while (dev != NULL)
+    {
+        freedIds[dev->id] = TRUE;
+        DeleteInputDeviceRequest(dev);
+
+        dev = *listHead;
+        while (dev != NULL && freedIds[dev->id])
+            dev = dev->next;
+    }
+}
+
+/**
+ * Shut down all devices, free all resources, etc.
+ * Only useful if you're shutting down the server!
+ */
+void
+CloseDownDevices(void)
+{
+    DeviceIntPtr dev;
+
+    /* Float all SDs before closing them. Note that at this point resources
+     * (e.g. cursors) have been freed already, so we can't just call
+     * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
+     * to NULL and pretend nothing happened.
+     */
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+        if (!IsMaster(dev) && !IsFloating(dev))
+            dev->master = NULL;
+    }
+
+    CloseDeviceList(&inputInfo.devices);
+    CloseDeviceList(&inputInfo.off_devices);
+
+    CloseDevice(inputInfo.pointer);
+    CloseDevice(inputInfo.keyboard);
+
+    inputInfo.devices = NULL;
+    inputInfo.off_devices = NULL;
+    inputInfo.keyboard = NULL;
+    inputInfo.pointer = NULL;
+    XkbDeleteRulesDflts();
+}
+
+/**
+ * Remove the cursor sprite for all devices. This needs to be done before any
+ * resources are freed or any device is deleted.
+ */
+void
+UndisplayDevices(void)
+{
+    DeviceIntPtr dev;
+    ScreenPtr screen = screenInfo.screens[0];
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+        screen->DisplayCursor(dev, screen, NullCursor);
+}
+
+/**
+ * Remove a device from the device list, closes it and thus frees all
+ * resources.
+ * Removes both enabled and disabled devices and notifies all devices about
+ * the removal of the device.
+ *
+ * No PresenceNotify is sent for device that the client never saw. This can
+ * happen if a malloc fails during the addition of master devices. If
+ * dev->init is FALSE it means the client never received a DeviceAdded event,
+ * so let's not send a DeviceRemoved event either.
+ *
+ * @param sendevent True if an XI2 event should be sent.
+ */
+int
+RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
+{
+    DeviceIntPtr prev,tmp,next;
+    int ret = BadMatch;
+    ScreenPtr screen = screenInfo.screens[0];
+    int deviceid;
+    int initialized;
+    int flags[MAXDEVICES] = {0};
+
+    DebugF("(dix) removing device %d\n", dev->id);
+
+    if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
+        return BadImplementation;
+
+    initialized = dev->inited;
+    deviceid = dev->id;
+
+    if (initialized)
+    {
+        if (DevHasCursor(dev))
+            screen->DisplayCursor(dev, screen, NullCursor);
+
+        DisableDevice(dev, sendevent);
+        flags[dev->id] = XIDeviceDisabled;
+    }
+
+    prev = NULL;
+    for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
+	next = tmp->next;
+	if (tmp == dev) {
+
+	    if (prev==NULL)
+		inputInfo.devices = next;
+	    else
+		prev->next = next;
+
+	    flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
+	    CloseDevice(tmp);
+	    ret = Success;
+	}
+    }
+
+    prev = NULL;
+    for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
+	next = tmp->next;
+	if (tmp == dev) {
+	    flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
+	    CloseDevice(tmp);
+
+	    if (prev == NULL)
+		inputInfo.off_devices = next;
+	    else
+		prev->next = next;
+
+            ret = Success;
+	}
+    }
+
+    if (ret == Success && initialized) {
+        inputInfo.numDevices--;
+        SendDevicePresenceEvent(deviceid, DeviceRemoved);
+        if (sendevent)
+            XISendDeviceHierarchyEvent(flags);
+    }
+
+    return ret;
+}
+
+int
+NumMotionEvents(void)
+{
+    /* only called to fill data in initial connection reply.
+     * VCP is ok here, it is the only fixed device we have. */
+    return inputInfo.pointer->valuator->numMotionEvents;
+}
+
+int
+dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode)
+{
+    DeviceIntPtr dev;
+    int rc;
+    *pDev = NULL;
+
+    for (dev=inputInfo.devices; dev; dev=dev->next) {
+        if (dev->id == id)
+            goto found;
+    }
+    for (dev=inputInfo.off_devices; dev; dev=dev->next) {
+        if (dev->id == id)
+	    goto found;
+    }
+    return BadDevice;
+
+found:
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
+    if (rc == Success)
+	*pDev = dev;
+    return rc;
+}
+
+void
+QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
+{
+    if (inputInfo.keyboard) {
+	*minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code;
+	*maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code;
+    }
+}
+
+/* Notably, this function does not expand the destination's keycode range, or
+ * notify clients. */
+Bool
+SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
+{
+    int i, j;
+    KeySym *tmp;
+    int rowDif = src->minKeyCode - dst->minKeyCode;
+
+    /* if keysym map size changes, grow map first */
+    if (src->mapWidth < dst->mapWidth) {
+        for (i = src->minKeyCode; i <= src->maxKeyCode; i++) {
+#define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c))
+#define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c))
+	    for (j = 0; j < src->mapWidth; j++)
+		dst->map[DI(i, j)] = src->map[SI(i, j)];
+	    for (j = src->mapWidth; j < dst->mapWidth; j++)
+		dst->map[DI(i, j)] = NoSymbol;
+#undef SI
+#undef DI
+	}
+	return TRUE;
+    }
+    else if (src->mapWidth > dst->mapWidth) {
+        i = sizeof(KeySym) * src->mapWidth *
+             (dst->maxKeyCode - dst->minKeyCode + 1);
+        tmp = calloc(sizeof(KeySym), i);
+        if (!tmp)
+            return FALSE;
+
+        if (dst->map) {
+            for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
+                memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth],
+                        dst->mapWidth * sizeof(KeySym));
+            free(dst->map);
+        }
+        dst->mapWidth = src->mapWidth;
+        dst->map = tmp;
+    }
+    else if (!dst->map) {
+        i = sizeof(KeySym) * src->mapWidth *
+             (dst->maxKeyCode - dst->minKeyCode + 1);
+        tmp = calloc(sizeof(KeySym), i);
+        if (!tmp)
+            return FALSE;
+
+        dst->map = tmp;
+        dst->mapWidth = src->mapWidth;
+    }
+
+    memmove(&dst->map[rowDif * dst->mapWidth], src->map,
+            (src->maxKeyCode - src->minKeyCode + 1) *
+            dst->mapWidth * sizeof(KeySym));
+
+    return TRUE;
+}
+
+Bool
+InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels,
+                            CARD8 *map)
+{
+    ButtonClassPtr butc;
+    int i;
+
+    butc = calloc(1, sizeof(ButtonClassRec));
+    if (!butc)
+	return FALSE;
+    butc->numButtons = numButtons;
+    butc->sourceid = dev->id;
+    for (i = 1; i <= numButtons; i++)
+	butc->map[i] = map[i];
+    for (i = numButtons + 1; i < MAP_LENGTH; i++)
+        butc->map[i] = i;
+    memcpy(butc->labels, labels, numButtons * sizeof(Atom));
+    dev->button = butc;
+    return TRUE;
+}
+
+Bool
+InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
+                              int numMotionEvents, int mode)
+{
+    int i;
+    ValuatorClassPtr valc;
+    union align_u { ValuatorClassRec valc; double d; } *align;
+
+    if (!dev)
+        return FALSE;
+
+    if (numAxes > MAX_VALUATORS)
+    {
+        LogMessage(X_WARNING,
+                   "Device '%s' has %d axes, only using first %d.\n",
+                   dev->name, numAxes, MAX_VALUATORS);
+        numAxes = MAX_VALUATORS;
+    }
+
+    align = (union align_u *) calloc(1, sizeof(union align_u) +
+				     numAxes * sizeof(double) +
+				     numAxes * sizeof(AxisInfo));
+    if (!align)
+	return FALSE;
+
+    valc = &align->valc;
+    valc->sourceid = dev->id;
+    valc->motion = NULL;
+    valc->first_motion = 0;
+    valc->last_motion = 0;
+
+    valc->numMotionEvents = numMotionEvents;
+    valc->motionHintWindow = NullWindow;
+    valc->numAxes = numAxes;
+    valc->axisVal = (double *)(align + 1);
+    valc->axes = (AxisInfoPtr)(valc->axisVal + numAxes);
+
+    if (mode & OutOfProximity)
+        InitProximityClassDeviceStruct(dev);
+
+    dev->valuator = valc;
+
+    AllocateMotionHistory(dev);
+
+    for (i=0; i<numAxes; i++) {
+        InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS,
+                               0, 0, 0, mode);
+	valc->axisVal[i]=0;
+    }
+
+    dev->last.numValuators = numAxes;
+
+    if (IsMaster(dev) || /* do not accelerate master or xtest devices */
+        IsXTestDevice(dev, NULL))
+	InitPointerAccelerationScheme(dev, PtrAccelNoOp);
+    else
+	InitPointerAccelerationScheme(dev, PtrAccelDefault);
+    return TRUE;
+}
+
+/* global list of acceleration schemes */
+ValuatorAccelerationRec pointerAccelerationScheme[] = {
+    {PtrAccelNoOp, NULL, NULL, NULL, NULL},
+    {PtrAccelPredictable, acceleratePointerPredictable, NULL,
+        InitPredictableAccelerationScheme, AccelerationDefaultCleanup},
+    {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL},
+    {-1, NULL, NULL, NULL, NULL} /* terminator */
+};
+
+/**
+ * install an acceleration scheme. returns TRUE on success, and should not
+ * change anything if unsuccessful.
+ */
+Bool
+InitPointerAccelerationScheme(DeviceIntPtr dev,
+                              int scheme)
+{
+    int x, i = -1;
+    ValuatorClassPtr val;
+
+    val = dev->valuator;
+
+    if (!val)
+        return FALSE;
+
+    if (IsMaster(dev) && scheme != PtrAccelNoOp)
+        return FALSE;
+
+    for (x = 0; pointerAccelerationScheme[x].number >= 0; x++) {
+        if(pointerAccelerationScheme[x].number == scheme){
+            i = x;
+            break;
+        }
+    }
+
+    if (-1 == i)
+        return FALSE;
+
+    if (val->accelScheme.AccelCleanupProc)
+        val->accelScheme.AccelCleanupProc(dev);
+
+    if (pointerAccelerationScheme[i].AccelInitProc) {
+        if (!pointerAccelerationScheme[i].AccelInitProc(dev,
+                                            &pointerAccelerationScheme[i])) {
+            return FALSE;
+        }
+    } else {
+        val->accelScheme = pointerAccelerationScheme[i];
+    }
+    return TRUE;
+}
+
+Bool
+InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
+{
+    AbsoluteClassPtr abs;
+
+    abs = malloc(sizeof(AbsoluteClassRec));
+    if (!abs)
+        return FALSE;
+
+    /* we don't do anything sensible with these, but should */
+    abs->min_x = NO_AXIS_LIMITS;
+    abs->min_y = NO_AXIS_LIMITS;
+    abs->max_x = NO_AXIS_LIMITS;
+    abs->max_y = NO_AXIS_LIMITS;
+    abs->flip_x = 0;
+    abs->flip_y = 0;
+    abs->rotation = 0;
+    abs->button_threshold = 0;
+
+    abs->offset_x = 0;
+    abs->offset_y = 0;
+    abs->width = NO_AXIS_LIMITS;
+    abs->height = NO_AXIS_LIMITS;
+    abs->following = 0;
+    abs->screen = 0;
+
+    abs->sourceid = dev->id;
+
+    dev->absolute = abs;
+
+    return TRUE;
+}
+
+Bool
+InitFocusClassDeviceStruct(DeviceIntPtr dev)
+{
+    FocusClassPtr focc;
+
+    focc = malloc(sizeof(FocusClassRec));
+    if (!focc)
+	return FALSE;
+    focc->win = PointerRootWin;
+    focc->revert = None;
+    focc->time = currentTime;
+    focc->trace = (WindowPtr *)NULL;
+    focc->traceSize = 0;
+    focc->traceGood = 0;
+    focc->sourceid = dev->id;
+    dev->focus = focc;
+    return TRUE;
+}
+
+Bool
+InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
+{
+    PtrFeedbackPtr feedc;
+
+    feedc = malloc(sizeof(PtrFeedbackClassRec));
+    if (!feedc)
+	return FALSE;
+    feedc->CtrlProc = controlProc;
+    feedc->ctrl = defaultPointerControl;
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->ptrfeed) )
+        feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
+    dev->ptrfeed = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+
+static LedCtrl defaultLedControl = {
+	DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
+
+static BellCtrl defaultBellControl = {
+	DEFAULT_BELL,
+	DEFAULT_BELL_PITCH,
+	DEFAULT_BELL_DURATION,
+	0};
+
+static IntegerCtrl defaultIntegerControl = {
+	DEFAULT_INT_RESOLUTION,
+	DEFAULT_INT_MIN_VALUE,
+	DEFAULT_INT_MAX_VALUE,
+	DEFAULT_INT_DISPLAYED,
+	0};
+
+Bool
+InitStringFeedbackClassDeviceStruct (
+      DeviceIntPtr dev, StringCtrlProcPtr controlProc,
+      int max_symbols, int num_symbols_supported, KeySym *symbols)
+{
+    int i;
+    StringFeedbackPtr feedc;
+
+    feedc = malloc(sizeof(StringFeedbackClassRec));
+    if (!feedc)
+	return FALSE;
+    feedc->CtrlProc = controlProc;
+    feedc->ctrl.num_symbols_supported = num_symbols_supported;
+    feedc->ctrl.num_symbols_displayed = 0;
+    feedc->ctrl.max_symbols = max_symbols;
+    feedc->ctrl.symbols_supported = malloc(sizeof (KeySym) * num_symbols_supported);
+    feedc->ctrl.symbols_displayed = malloc(sizeof (KeySym) * max_symbols);
+    if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
+    {
+	free(feedc->ctrl.symbols_supported);
+	free(feedc->ctrl.symbols_displayed);
+	free(feedc);
+	return FALSE;
+    }
+    for (i=0; i<num_symbols_supported; i++)
+	*(feedc->ctrl.symbols_supported+i) = *symbols++;
+    for (i=0; i<max_symbols; i++)
+	*(feedc->ctrl.symbols_displayed+i) = (KeySym) 0;
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->stringfeed) )
+	feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
+    dev->stringfeed = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+Bool
+InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
+                                   BellCtrlProcPtr controlProc)
+{
+    BellFeedbackPtr feedc;
+
+    feedc = malloc(sizeof(BellFeedbackClassRec));
+    if (!feedc)
+	return FALSE;
+    feedc->CtrlProc = controlProc;
+    feedc->BellProc = bellProc;
+    feedc->ctrl = defaultBellControl;
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->bell) )
+	feedc->ctrl.id = dev->bell->ctrl.id + 1;
+    dev->bell = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+Bool
+InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
+{
+    LedFeedbackPtr feedc;
+
+    feedc = malloc(sizeof(LedFeedbackClassRec));
+    if (!feedc)
+	return FALSE;
+    feedc->CtrlProc = controlProc;
+    feedc->ctrl = defaultLedControl;
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->leds) )
+	feedc->ctrl.id = dev->leds->ctrl.id + 1;
+    feedc->xkb_sli= NULL;
+    dev->leds = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+Bool
+InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc)
+{
+    IntegerFeedbackPtr feedc;
+
+    feedc = malloc(sizeof(IntegerFeedbackClassRec));
+    if (!feedc)
+	return FALSE;
+    feedc->CtrlProc = controlProc;
+    feedc->ctrl = defaultIntegerControl;
+    feedc->ctrl.id = 0;
+    if ( (feedc->next = dev->intfeed) )
+	feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
+    dev->intfeed = feedc;
+    (*controlProc)(dev, &feedc->ctrl);
+    return TRUE;
+}
+
+Bool
+InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom* btn_labels,
+                        PtrCtrlProcPtr controlProc, int numMotionEvents,
+                        int numAxes, Atom *axes_labels)
+{
+    DeviceIntPtr dev = (DeviceIntPtr)device;
+
+    return(InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) &&
+	   InitValuatorClassDeviceStruct(dev, numAxes, axes_labels,
+					 numMotionEvents, Relative) &&
+	   InitPtrFeedbackClassDeviceStruct(dev, controlProc));
+}
+
+/*
+ * Check if the given buffer contains elements between low (inclusive) and
+ * high (inclusive) only.
+ *
+ * @return TRUE if the device map is invalid, FALSE otherwise.
+ */
+Bool
+BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
+{
+    int i;
+
+    for (i = 0; i < length; i++)
+	if (buff[i])		       /* only check non-zero elements */
+	{
+	    if ((low > buff[i]) || (high < buff[i]))
+	    {
+		*errval = buff[i];
+		return TRUE;
+	    }
+	}
+    return FALSE;
+}
+
+int
+ProcSetModifierMapping(ClientPtr client)
+{
+    xSetModifierMappingReply rep;
+    int rc;
+    REQUEST(xSetModifierMappingReq);
+    REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
+
+    if (client->req_len != ((stuff->numKeyPerModifier << 1) +
+                bytes_to_int32(sizeof(xSetModifierMappingReq))))
+	return BadLength;
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+
+    rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1],
+                       stuff->numKeyPerModifier);
+    if (rc == MappingFailed || rc == -1)
+        return BadValue;
+    if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
+        rc != MappingBusy)
+	return rc;
+
+    rep.success = rc;
+
+    WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
+    return Success;
+}
+
+int
+ProcGetModifierMapping(ClientPtr client)
+{
+    xGetModifierMappingReply rep;
+    int max_keys_per_mod = 0;
+    KeyCode *modkeymap = NULL;
+    REQUEST_SIZE_MATCH(xReq);
+
+    generate_modkeymap(client, PickKeyboard(client), &modkeymap,
+                       &max_keys_per_mod);
+
+    memset(&rep, 0, sizeof(xGetModifierMappingReply));
+    rep.type = X_Reply;
+    rep.numKeyPerModifier = max_keys_per_mod;
+    rep.sequenceNumber = client->sequence;
+    /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
+    rep.length = max_keys_per_mod << 1;
+
+    WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
+    (void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap);
+
+    free(modkeymap);
+
+    return Success;
+}
+
+int
+ProcChangeKeyboardMapping(ClientPtr client)
+{
+    REQUEST(xChangeKeyboardMappingReq);
+    unsigned len;
+    KeySymsRec keysyms;
+    DeviceIntPtr pDev, tmp;
+    int rc;
+    REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
+
+    len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq));
+    if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
+            return BadLength;
+
+    pDev = PickKeyboard(client);
+
+    if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) ||
+	(stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) {
+	    client->errorValue = stuff->firstKeyCode;
+	    return BadValue;
+
+    }
+    if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
+          pDev->key->xkbInfo->desc->max_key_code) ||
+        (stuff->keySymsPerKeyCode == 0)) {
+	    client->errorValue = stuff->keySymsPerKeyCode;
+	    return BadValue;
+    }
+
+    keysyms.minKeyCode = stuff->firstKeyCode;
+    keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
+    keysyms.mapWidth = stuff->keySymsPerKeyCode;
+    keysyms.map = (KeySym *) &stuff[1];
+
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
+    if (rc != Success)
+        return rc;
+
+    XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode,
+                          stuff->keyCodes, NULL, client);
+
+    for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
+        if (IsMaster(tmp) || GetMaster(tmp, MASTER_KEYBOARD) != pDev)
+            continue;
+        if (!tmp->key)
+            continue;
+
+        rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
+        if (rc != Success)
+            continue;
+
+        XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode,
+                              stuff->keyCodes, NULL, client);
+    }
+
+    return Success;
+}
+
+int
+ProcSetPointerMapping(ClientPtr client)
+{
+    BYTE *map;
+    int ret;
+    int i, j;
+    DeviceIntPtr ptr = PickPointer(client);
+    xSetPointerMappingReply rep;
+    REQUEST(xSetPointerMappingReq);
+    REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
+
+    if (client->req_len !=
+            bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts))
+	return BadLength;
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.success = MappingSuccess;
+    map = (BYTE *)&stuff[1];
+
+    /* So we're bounded here by the number of core buttons.  This check
+     * probably wants disabling through XFixes. */
+    /* MPX: With ClientPointer, we can return the right number of buttons.
+     * Let's just hope nobody changed ClientPointer between GetPointerMapping
+     * and SetPointerMapping
+     */
+    if (stuff->nElts != ptr->button->numButtons) {
+	client->errorValue = stuff->nElts;
+	return BadValue;
+    }
+
+    /* Core protocol specs don't allow for duplicate mappings; this check
+     * almost certainly wants disabling through XFixes too. */
+    for (i = 0; i < stuff->nElts; i++) {
+        for (j = i + 1; j < stuff->nElts; j++) {
+            if (map[i] && map[i] == map[j]) {
+                client->errorValue = map[i];
+                return BadValue;
+            }
+        }
+    }
+
+    ret = ApplyPointerMapping(ptr, map, stuff->nElts, client);
+    if (ret == MappingBusy)
+        rep.success = ret;
+    else if (ret == -1)
+        return BadValue;
+    else if (ret != Success)
+        return ret;
+
+    WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
+    return Success;
+}
+
+int
+ProcGetKeyboardMapping(ClientPtr client)
+{
+    xGetKeyboardMappingReply rep;
+    DeviceIntPtr kbd = PickKeyboard(client);
+    XkbDescPtr xkb;
+    KeySymsPtr syms;
+    int rc;
+    REQUEST(xGetKeyboardMappingReq);
+    REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
+
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+
+    xkb = kbd->key->xkbInfo->desc;
+
+    if ((stuff->firstKeyCode < xkb->min_key_code) ||
+        (stuff->firstKeyCode > xkb->max_key_code)) {
+	client->errorValue = stuff->firstKeyCode;
+	return BadValue;
+    }
+    if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) {
+	client->errorValue = stuff->count;
+        return BadValue;
+    }
+
+    syms = XkbGetCoreMap(kbd);
+    if (!syms)
+        return BadAlloc;
+
+    memset(&rep, 0, sizeof(xGetKeyboardMappingReply));
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.keySymsPerKeyCode = syms->mapWidth;
+    /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
+    rep.length = syms->mapWidth * stuff->count;
+    WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
+    client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
+    WriteSwappedDataToClient(client,
+                             syms->mapWidth * stuff->count * sizeof(KeySym),
+                             &syms->map[syms->mapWidth * (stuff->firstKeyCode -
+                                                          syms->minKeyCode)]);
+    free(syms->map);
+    free(syms);
+
+    return Success;
+}
+
+int
+ProcGetPointerMapping(ClientPtr client)
+{
+    xGetPointerMappingReply rep;
+    /* Apps may get different values each time they call GetPointerMapping as
+     * the ClientPointer could change. */
+    DeviceIntPtr ptr = PickPointer(client);
+    ButtonClassPtr butc = ptr->button;
+    int rc;
+    REQUEST_SIZE_MATCH(xReq);
+
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.nElts = (butc) ? butc->numButtons : 0;
+    rep.length = ((unsigned)rep.nElts + (4-1))/4;
+    WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
+    if (butc)
+        WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]);
+    return Success;
+}
+
+void
+NoteLedState(DeviceIntPtr keybd, int led, Bool on)
+{
+    KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
+    if (on)
+	ctrl->leds |= ((Leds)1 << (led - 1));
+    else
+	ctrl->leds &= ~((Leds)1 << (led - 1));
+}
+
+int
+Ones(unsigned long mask)             /* HACKMEM 169 */
+{
+    unsigned long y;
+
+    y = (mask >> 1) &033333333333;
+    y = mask - y - ((y >>1) & 033333333333);
+    return (((y + (y >> 3)) & 030707070707) % 077);
+}
+
+static int
+DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
+                         BITS32 vmask)
+{
+#define DO_ALL    (-1)
+    KeybdCtrl ctrl;
+    int t;
+    int led = DO_ALL;
+    int key = DO_ALL;
+    BITS32 index2;
+    int mask = vmask, i;
+    XkbEventCauseRec cause;
+
+    ctrl = keybd->kbdfeed->ctrl;
+    while (vmask) {
+	index2 = (BITS32) lowbit (vmask);
+	vmask &= ~index2;
+	switch (index2) {
+	case KBKeyClickPercent:
+	    t = (INT8)*vlist;
+	    vlist++;
+	    if (t == -1) {
+		t = defaultKeyboardControl.click;
+            }
+	    else if (t < 0 || t > 100) {
+		client->errorValue = t;
+		return BadValue;
+	    }
+	    ctrl.click = t;
+	    break;
+	case KBBellPercent:
+	    t = (INT8)*vlist;
+	    vlist++;
+	    if (t == -1) {
+		t = defaultKeyboardControl.bell;
+            }
+	    else if (t < 0 || t > 100) {
+		client->errorValue = t;
+		return BadValue;
+	    }
+	    ctrl.bell = t;
+	    break;
+	case KBBellPitch:
+	    t = (INT16)*vlist;
+	    vlist++;
+	    if (t == -1) {
+		t = defaultKeyboardControl.bell_pitch;
+            }
+	    else if (t < 0) {
+		client->errorValue = t;
+		return BadValue;
+	    }
+	    ctrl.bell_pitch = t;
+	    break;
+	case KBBellDuration:
+	    t = (INT16)*vlist;
+	    vlist++;
+	    if (t == -1)
+		t = defaultKeyboardControl.bell_duration;
+	    else if (t < 0) {
+		client->errorValue = t;
+		return BadValue;
+	    }
+	    ctrl.bell_duration = t;
+	    break;
+	case KBLed:
+	    led = (CARD8)*vlist;
+	    vlist++;
+	    if (led < 1 || led > 32) {
+		client->errorValue = led;
+		return BadValue;
+	    }
+	    if (!(mask & KBLedMode))
+		return BadMatch;
+	    break;
+	case KBLedMode:
+	    t = (CARD8)*vlist;
+	    vlist++;
+	    if (t == LedModeOff) {
+		if (led == DO_ALL)
+		    ctrl.leds = 0x0;
+		else
+		    ctrl.leds &= ~(((Leds)(1)) << (led - 1));
+	    }
+	    else if (t == LedModeOn) {
+		if (led == DO_ALL)
+		    ctrl.leds = ~0L;
+		else
+		    ctrl.leds |= (((Leds)(1)) << (led - 1));
+	    }
+	    else {
+		client->errorValue = t;
+		return BadValue;
+	    }
+
+            XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
+            XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
+ 			     ctrl.leds, &cause);
+            ctrl.leds = keybd->kbdfeed->ctrl.leds;
+
+	    break;
+	case KBKey:
+	    key = (KeyCode)*vlist;
+	    vlist++;
+	    if ((KeyCode)key < keybd->key->xkbInfo->desc->min_key_code ||
+		(KeyCode)key > keybd->key->xkbInfo->desc->max_key_code) {
+		client->errorValue = key;
+		return BadValue;
+	    }
+	    if (!(mask & KBAutoRepeatMode))
+		return BadMatch;
+	    break;
+	case KBAutoRepeatMode:
+	    i = (key >> 3);
+	    mask = (1 << (key & 7));
+	    t = (CARD8)*vlist;
+	    vlist++;
+            if (key != DO_ALL)
+                XkbDisableComputedAutoRepeats(keybd,key);
+	    if (t == AutoRepeatModeOff) {
+		if (key == DO_ALL)
+		    ctrl.autoRepeat = FALSE;
+		else
+		    ctrl.autoRepeats[i] &= ~mask;
+	    }
+	    else if (t == AutoRepeatModeOn) {
+		if (key == DO_ALL)
+		    ctrl.autoRepeat = TRUE;
+		else
+		    ctrl.autoRepeats[i] |= mask;
+	    }
+	    else if (t == AutoRepeatModeDefault) {
+		if (key == DO_ALL)
+		    ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
+		else
+		    ctrl.autoRepeats[i] =
+			    (ctrl.autoRepeats[i] & ~mask) |
+			    (defaultKeyboardControl.autoRepeats[i] & mask);
+	    }
+	    else {
+		client->errorValue = t;
+		return BadValue;
+	    }
+	    break;
+	default:
+	    client->errorValue = mask;
+	    return BadValue;
+	}
+    }
+    keybd->kbdfeed->ctrl = ctrl;
+
+    /* The XKB RepeatKeys control and core protocol global autorepeat */
+    /* value are linked	*/
+    XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
+
+    return Success;
+
+#undef DO_ALL
+}
+
+/**
+ * Changes kbd control on the ClientPointer and all attached SDs.
+ */
+int
+ProcChangeKeyboardControl (ClientPtr client)
+{
+    XID *vlist;
+    BITS32 vmask;
+    int ret = Success, error = Success;
+    DeviceIntPtr pDev = NULL, keyboard;
+    REQUEST(xChangeKeyboardControlReq);
+
+    REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
+
+    vmask = stuff->mask;
+    vlist = (XID *)&stuff[1];
+
+    if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
+	return BadLength;
+
+    keyboard = PickKeyboard(client);
+
+    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
+        if ((pDev == keyboard ||
+	     (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
+	    && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
+            ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
+	    if (ret != Success)
+                return ret;
+        }
+    }
+
+    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
+        if ((pDev == keyboard ||
+	     (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
+	    && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
+            ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
+            if (ret != Success)
+                error = ret;
+        }
+    }
+
+    return error;
+}
+
+int
+ProcGetKeyboardControl (ClientPtr client)
+{
+    int rc, i;
+    DeviceIntPtr kbd = PickKeyboard(client);
+    KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl;
+    xGetKeyboardControlReply rep;
+    REQUEST_SIZE_MATCH(xReq);
+
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+
+    rep.type = X_Reply;
+    rep.length = 5;
+    rep.sequenceNumber = client->sequence;
+    rep.globalAutoRepeat = ctrl->autoRepeat;
+    rep.keyClickPercent = ctrl->click;
+    rep.bellPercent = ctrl->bell;
+    rep.bellPitch = ctrl->bell_pitch;
+    rep.bellDuration = ctrl->bell_duration;
+    rep.ledMask = ctrl->leds;
+    for (i = 0; i < 32; i++)
+	rep.map[i] = ctrl->autoRepeats[i];
+    WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
+    return Success;
+}
+
+int
+ProcBell(ClientPtr client)
+{
+    DeviceIntPtr dev, keybd = PickKeyboard(client);
+    int base = keybd->kbdfeed->ctrl.bell;
+    int newpercent;
+    int rc;
+    REQUEST(xBellReq);
+    REQUEST_SIZE_MATCH(xBellReq);
+
+    if (stuff->percent < -100 || stuff->percent > 100) {
+	client->errorValue = stuff->percent;
+	return BadValue;
+    }
+
+    newpercent = (base * stuff->percent) / 100;
+    if (stuff->percent < 0)
+        newpercent = base + newpercent;
+    else
+	newpercent = base - newpercent + stuff->percent;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next) {
+        if ((dev == keybd ||
+	     (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) &&
+            dev->kbdfeed && dev->kbdfeed->BellProc) {
+
+	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess);
+	    if (rc != Success)
+		return rc;
+            XkbHandleBell(FALSE, FALSE, dev, newpercent,
+                          &dev->kbdfeed->ctrl, 0, None, NULL, client);
+        }
+    }
+
+    return Success;
+}
+
+int
+ProcChangePointerControl(ClientPtr client)
+{
+    DeviceIntPtr dev, mouse = PickPointer(client);
+    PtrCtrl ctrl;		/* might get BadValue part way through */
+    int rc;
+    REQUEST(xChangePointerControlReq);
+    REQUEST_SIZE_MATCH(xChangePointerControlReq);
+
+    ctrl = mouse->ptrfeed->ctrl;
+    if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
+	client->errorValue = stuff->doAccel;
+	return BadValue;
+    }
+    if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
+	client->errorValue = stuff->doThresh;
+	return BadValue;
+    }
+    if (stuff->doAccel) {
+	if (stuff->accelNum == -1) {
+	    ctrl.num = defaultPointerControl.num;
+        }
+	else if (stuff->accelNum < 0) {
+	    client->errorValue = stuff->accelNum;
+	    return BadValue;
+	}
+	else {
+            ctrl.num = stuff->accelNum;
+        }
+
+	if (stuff->accelDenum == -1) {
+	    ctrl.den = defaultPointerControl.den;
+        }
+	else if (stuff->accelDenum <= 0) {
+	    client->errorValue = stuff->accelDenum;
+	    return BadValue;
+	}
+	else {
+            ctrl.den = stuff->accelDenum;
+        }
+    }
+    if (stuff->doThresh) {
+	if (stuff->threshold == -1) {
+	    ctrl.threshold = defaultPointerControl.threshold;
+        }
+	else if (stuff->threshold < 0) {
+	    client->errorValue = stuff->threshold;
+	    return BadValue;
+	}
+	else {
+            ctrl.threshold = stuff->threshold;
+        }
+    }
+
+    for (dev = inputInfo.devices; dev; dev = dev->next) {
+        if ((dev == mouse ||
+	     (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
+            dev->ptrfeed) {
+	    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
+	    if (rc != Success)
+		return rc;
+	}
+    }
+
+    for (dev = inputInfo.devices; dev; dev = dev->next) {
+        if ((dev == mouse ||
+	     (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
+            dev->ptrfeed) {
+            dev->ptrfeed->ctrl = ctrl;
+        }
+    }
+
+    return Success;
+}
+
+int
+ProcGetPointerControl(ClientPtr client)
+{
+    DeviceIntPtr ptr = PickPointer(client);
+    PtrCtrl *ctrl = &ptr->ptrfeed->ctrl;
+    xGetPointerControlReply rep;
+    int rc;
+    REQUEST_SIZE_MATCH(xReq);
+
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+
+    rep.type = X_Reply;
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.threshold = ctrl->threshold;
+    rep.accelNumerator = ctrl->num;
+    rep.accelDenominator = ctrl->den;
+    WriteReplyToClient(client, sizeof(xGenericReply), &rep);
+    return Success;
+}
+
+void
+MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
+{
+    GrabPtr grab = dev->deviceGrab.grab;
+
+    if ((grab && SameClient(grab, client) &&
+	 ((grab->eventMask & PointerMotionHintMask) ||
+	  (grab->ownerEvents &&
+	   (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+	    PointerMotionHintMask)))) ||
+	(!grab &&
+	 (EventMaskForClient(dev->valuator->motionHintWindow, client) &
+	  PointerMotionHintMask)))
+	dev->valuator->motionHintWindow = NullWindow;
+}
+
+int
+ProcGetMotionEvents(ClientPtr client)
+{
+    WindowPtr pWin;
+    xTimecoord * coords = (xTimecoord *) NULL;
+    xGetMotionEventsReply rep;
+    int i, count, xmin, xmax, ymin, ymax, rc;
+    unsigned long nEvents;
+    DeviceIntPtr mouse = PickPointer(client);
+    TimeStamp start, stop;
+    REQUEST(xGetMotionEventsReq);
+    REQUEST_SIZE_MATCH(xGetMotionEventsReq);
+
+    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
+    if (rc != Success)
+	return rc;
+
+    if (mouse->valuator->motionHintWindow)
+	MaybeStopHint(mouse, client);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    nEvents = 0;
+    start = ClientTimeToServerTime(stuff->start);
+    stop = ClientTimeToServerTime(stuff->stop);
+    if ((CompareTimeStamps(start, stop) != LATER) &&
+	(CompareTimeStamps(start, currentTime) != LATER) &&
+	mouse->valuator->numMotionEvents)
+    {
+	if (CompareTimeStamps(stop, currentTime) == LATER)
+	    stop = currentTime;
+	count = GetMotionHistory(mouse, &coords, start.milliseconds,
+				 stop.milliseconds, pWin->drawable.pScreen,
+                                 TRUE);
+	xmin = pWin->drawable.x - wBorderWidth (pWin);
+	xmax = pWin->drawable.x + (int)pWin->drawable.width +
+		wBorderWidth (pWin);
+	ymin = pWin->drawable.y - wBorderWidth (pWin);
+	ymax = pWin->drawable.y + (int)pWin->drawable.height +
+		wBorderWidth (pWin);
+	for (i = 0; i < count; i++)
+	    if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
+		    (ymin <= coords[i].y) && (coords[i].y < ymax))
+	    {
+		coords[nEvents].time = coords[i].time;
+		coords[nEvents].x = coords[i].x - pWin->drawable.x;
+		coords[nEvents].y = coords[i].y - pWin->drawable.y;
+		nEvents++;
+	    }
+    }
+    rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord));
+    rep.nEvents = nEvents;
+    WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
+    if (nEvents)
+    {
+	client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
+	WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
+				 (char *)coords);
+    }
+    free(coords);
+    return Success;
+}
+
+int
+ProcQueryKeymap(ClientPtr client)
+{
+    xQueryKeymapReply rep;
+    int rc, i;
+    DeviceIntPtr keybd = PickKeyboard(client);
+    CARD8 *down = keybd->key->down;
+
+    REQUEST_SIZE_MATCH(xReq);
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 2;
+
+    rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
+    if (rc != Success && rc != BadAccess)
+	return rc;
+
+    for (i = 0; i<32; i++)
+	rep.map[i] = down[i];
+
+    if (rc == BadAccess)
+	memset(rep.map, 0, 32);
+
+    WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
+
+   return Success;
+}
+
+
+/**
+ * Recalculate the number of buttons for the master device. The number of
+ * buttons on the master device is equal to the number of buttons on the
+ * slave device with the highest number of buttons.
+ */
+static void
+RecalculateMasterButtons(DeviceIntPtr slave)
+{
+    DeviceIntPtr dev, master;
+    int maxbuttons = 0;
+
+    if (!slave->button || IsMaster(slave))
+        return;
+
+    master = GetMaster(slave, MASTER_POINTER);
+    if (!master)
+        return;
+
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+    {
+        if (IsMaster(dev) ||
+            GetMaster(dev, MASTER_ATTACHED) != master ||
+            !dev->button)
+            continue;
+
+        maxbuttons = max(maxbuttons, dev->button->numButtons);
+    }
+
+    if (master->button && master->button->numButtons != maxbuttons)
+    {
+        int i;
+        DeviceChangedEvent event;
+
+        memset(&event, 0, sizeof(event));
+
+        master->button->numButtons = maxbuttons;
+
+        event.header = ET_Internal;
+        event.type = ET_DeviceChanged;
+        event.time = GetTimeInMillis();
+        event.deviceid = master->id;
+        event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE;
+        event.buttons.num_buttons = maxbuttons;
+        memcpy(&event.buttons.names, master->button->labels, maxbuttons *
+                sizeof(Atom));
+
+        if (master->valuator)
+        {
+            event.num_valuators = master->valuator->numAxes;
+            for (i = 0; i < event.num_valuators; i++)
+            {
+                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;
+                event.valuators[i].mode = master->valuator->axes[i].mode;
+                event.valuators[i].name = master->valuator->axes[i].label;
+            }
+        }
+
+        if (master->key)
+        {
+            event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code;
+            event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code;
+        }
+
+        XISendDeviceChangedEvent(master, master, &event);
+    }
+}
+
+/**
+ * Generate release events for all keys/button currently down on this
+ * device.
+ */
+static void
+ReleaseButtonsAndKeys(DeviceIntPtr dev)
+{
+    EventListPtr        eventlist = InitEventList(GetMaximumEventsNum());
+    ButtonClassPtr      b = dev->button;
+    KeyClassPtr         k = dev->key;
+    int                 i, j, nevents;
+
+    if (!eventlist) /* no release events for you */
+        return;
+
+    /* Release all buttons */
+    for (i = 0; b && i < b->numButtons; i++)
+    {
+        if (BitIsOn(b->down, i))
+        {
+            nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL);
+            for (j = 0; j < nevents; j++)
+                mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL);
+        }
+    }
+
+    /* Release all keys */
+    for (i = 0; k && i < MAP_LENGTH; i++)
+    {
+        if (BitIsOn(k->down, i))
+        {
+            nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i);
+            for (j = 0; j < nevents; j++)
+                mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL);
+        }
+    }
+
+    FreeEventList(eventlist, GetMaximumEventsNum());
+}
+
+/**
+ * Attach device 'dev' to device 'master'.
+ * Client is set to the client that issued the request, or NULL if it comes
+ * from some internal automatic pairing.
+ *
+ * Master may be NULL to set the device floating.
+ *
+ * We don't allow multi-layer hierarchies right now. You can't attach a slave
+ * to another slave.
+ */
+int
+AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
+{
+    ScreenPtr screen;
+    DeviceIntPtr oldmaster;
+    if (!dev || IsMaster(dev))
+        return BadDevice;
+
+    if (master && !IsMaster(master)) /* can't attach to slaves */
+        return BadDevice;
+
+    /* set from floating to floating? */
+    if (IsFloating(dev) && !master && dev->enabled)
+        return Success;
+
+    /* free the existing sprite. */
+    if (IsFloating(dev) && dev->spriteInfo->paired == dev)
+    {
+        screen = miPointerGetScreen(dev);
+        screen->DeviceCursorCleanup(dev, screen);
+        free(dev->spriteInfo->sprite);
+    }
+
+    ReleaseButtonsAndKeys(dev);
+
+    oldmaster = GetMaster(dev, MASTER_ATTACHED);
+    dev->master = master;
+
+    /* If device is set to floating, we need to create a sprite for it,
+     * otherwise things go bad. However, we don't want to render the cursor,
+     * so we reset spriteOwner.
+     * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
+     * alloc new memory but overwrite the previous one.
+     */
+    if (!master)
+    {
+        WindowPtr currentRoot;
+
+        if (dev->spriteInfo->sprite)
+            currentRoot = GetCurrentRootWindow(dev);
+        else /* new device auto-set to floating */
+            currentRoot = screenInfo.screens[0]->root;
+
+        /* we need to init a fake sprite */
+        screen = currentRoot->drawable.pScreen;
+        screen->DeviceCursorInitialize(dev, screen);
+        dev->spriteInfo->sprite = NULL;
+        InitializeSprite(dev, currentRoot);
+        dev->spriteInfo->spriteOwner = FALSE;
+        dev->spriteInfo->paired = dev;
+    } else
+    {
+        dev->spriteInfo->sprite = master->spriteInfo->sprite;
+        dev->spriteInfo->paired = master;
+        dev->spriteInfo->spriteOwner = FALSE;
+
+        RecalculateMasterButtons(master);
+    }
+
+    /* XXX: in theory, the MD should change back to its old, original
+     * classes when the last SD is detached. Thanks to the XTEST devices,
+     * we'll always have an SD attached until the MD is removed.
+     * So let's not worry about that.
+     */
+
+    return Success;
+}
+
+/**
+ * Return the device paired with the given device or NULL.
+ * Returns the device paired with the parent master if the given device is a
+ * slave device.
+ */
+DeviceIntPtr
+GetPairedDevice(DeviceIntPtr dev)
+{
+    if (!IsMaster(dev) && !IsFloating(dev))
+        dev = GetMaster(dev, MASTER_ATTACHED);
+
+    return dev->spriteInfo->paired;
+}
+
+
+/**
+ * Returns the right master for the type of event needed. If the event is a
+ * keyboard event.
+ * This function may be called with a master device as argument. If so, the
+ * returned master is either the device itself or the paired master device.
+ * If dev is a floating slave device, NULL is returned.
+ *
+ * @type ::MASTER_KEYBOARD or ::MASTER_POINTER or ::MASTER_ATTACHED
+ * @return The requested master device. In the case of MASTER_ATTACHED, this
+ * is the directly attached master to this device, regardless of the type.
+ * Otherwise, it is either the master keyboard or pointer for this device.
+ */
+DeviceIntPtr
+GetMaster(DeviceIntPtr dev, int which)
+{
+    DeviceIntPtr master;
+
+    if (IsMaster(dev))
+        master = dev;
+    else
+        master = dev->master;
+
+    if (master && which != MASTER_ATTACHED)
+    {
+        if (which == MASTER_KEYBOARD)
+        {
+            if (master->type != MASTER_KEYBOARD)
+                master = GetPairedDevice(master);
+        } else
+        {
+            if (master->type != MASTER_POINTER)
+                master = GetPairedDevice(master);
+        }
+    }
+
+    return master;
+}
+
+/**
+ * Create a new device pair (== one pointer, one keyboard device).
+ * Only allocates the devices, you will need to call ActivateDevice() and
+ * EnableDevice() manually.
+ * Either a master or a slave device can be created depending on
+ * the value for master.
+ */
+int
+AllocDevicePair (ClientPtr client, char* name,
+                 DeviceIntPtr* ptr,
+                 DeviceIntPtr* keybd,
+                 DeviceProc ptr_proc,
+                 DeviceProc keybd_proc,
+                 Bool master)
+{
+    DeviceIntPtr pointer;
+    DeviceIntPtr keyboard;
+    *ptr = *keybd = NULL;
+
+    pointer = AddInputDevice(client, ptr_proc, TRUE);
+    if (!pointer)
+        return BadAlloc;
+
+    if (asprintf(&pointer->name, "%s pointer", name) == -1) {
+        pointer->name = NULL;
+        RemoveDevice(pointer, FALSE);
+        return BadAlloc;
+    }
+
+    pointer->public.processInputProc = ProcessOtherEvent;
+    pointer->public.realInputProc = ProcessOtherEvent;
+    XkbSetExtension(pointer, ProcessPointerEvent);
+    pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
+    pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
+    pointer->coreEvents = TRUE;
+    pointer->spriteInfo->spriteOwner = TRUE;
+
+    pointer->lastSlave = NULL;
+    pointer->last.slave = NULL;
+    pointer->type = (master) ? MASTER_POINTER : SLAVE;
+
+    keyboard = AddInputDevice(client, keybd_proc, TRUE);
+    if (!keyboard)
+    {
+        RemoveDevice(pointer, FALSE);
+        return BadAlloc;
+    }
+
+    if (asprintf(&keyboard->name, "%s keyboard", name) == -1) {
+        keyboard->name = NULL;
+        RemoveDevice(keyboard, FALSE);
+        RemoveDevice(pointer, FALSE);
+        return BadAlloc;
+    }
+
+    keyboard->public.processInputProc = ProcessOtherEvent;
+    keyboard->public.realInputProc = ProcessOtherEvent;
+    XkbSetExtension(keyboard, ProcessKeyboardEvent);
+    keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+    keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+    keyboard->coreEvents = TRUE;
+    keyboard->spriteInfo->spriteOwner = FALSE;
+
+    keyboard->lastSlave = NULL;
+    keyboard->last.slave = NULL;
+    keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
+
+    /* The ClassesRec stores the device classes currently not used. */
+    pointer->unused_classes = calloc(1, sizeof(ClassesRec));
+    keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
+
+    *ptr = pointer;
+    *keybd = keyboard;
+
+    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[i].mode = mode;
+    }
+}
diff --git a/xorg-server/dix/eventconvert.c b/xorg-server/dix/eventconvert.c
index 760729beb..d5ac54796 100644
--- a/xorg-server/dix/eventconvert.c
+++ b/xorg-server/dix/eventconvert.c
@@ -1,767 +1,770 @@
-/*
- * Copyright © 2009 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-
-/**
- * @file eventconvert.c
- * This file contains event conversion routines from InternalEvent to the
- * matching protocol events.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdint.h>
-#include <X11/X.h>
-#include <X11/extensions/XIproto.h>
-#include <X11/extensions/XI2proto.h>
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XI2.h>
-
-#include "dix.h"
-#include "inputstr.h"
-#include "misc.h"
-#include "eventstr.h"
-#include "exglobals.h"
-#include "eventconvert.h"
-#include "xiquerydevice.h"
-#include "xkbsrv.h"
-
-
-static int countValuators(DeviceEvent *ev, int *first);
-static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
-static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
-static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
-static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
-static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
-
-/* Do not use, read comments below */
-BOOL EventIsKeyRepeat(xEvent *event);
-
-/**
- * Hack to allow detectable autorepeat for core and XI1 events.
- * The sequence number is unused until we send to the client and can be
- * misused to store data. More or less, anyway.
- *
- * Do not use this. It may change any time without warning, eat your babies
- * and piss on your cat.
- */
-static void
-EventSetKeyRepeatFlag(xEvent *event, BOOL on)
-{
-    event->u.u.sequenceNumber = on;
-}
-
-/**
- * Check if the event was marked as a repeat event before.
- * NOTE: This is a nasty hack and should NOT be used by anyone else but
- * TryClientEvents.
- */
-BOOL
-EventIsKeyRepeat(xEvent *event)
-{
-    return !!event->u.u.sequenceNumber;
-}
-
-/**
- * Convert the given event to the respective core event.
- *
- * Return values:
- * Success ... core contains the matching core event.
- * BadValue .. One or more values in the internal event are invalid.
- * BadMatch .. The event has no core equivalent.
- *
- * @param[in] event The event to convert into a core event.
- * @param[in] core The memory location to store the core event at.
- * @return Success or the matching error code.
- */
-int
-EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
-{
-    xEvent *core = NULL;
-    int count = 0;
-    int ret = BadImplementation;
-
-    switch(event->any.type)
-    {
-        case ET_Motion:
-            {
-                DeviceEvent *e = &event->device_event;
-                /* Don't create core motion event if neither x nor y are
-                 * present */
-                if (!BitIsOn(e->valuators.mask, 0) &&
-                    !BitIsOn(e->valuators.mask, 1))
-                {
-                    ret = BadMatch;
-                    goto out;
-                }
-            }
-            /* fallthrough */
-        case ET_ButtonPress:
-        case ET_ButtonRelease:
-        case ET_KeyPress:
-        case ET_KeyRelease:
-            {
-                DeviceEvent *e = &event->device_event;
-
-                if (e->detail.key > 0xFF)
-                {
-                    ret = BadMatch;
-                    goto out;
-                }
-
-                core = calloc(1, sizeof(*core));
-                if (!core)
-                    return BadAlloc;
-                count = 1;
-                core->u.u.type = e->type - ET_KeyPress + KeyPress;
-                core->u.u.detail = e->detail.key & 0xFF;
-                core->u.keyButtonPointer.time = e->time;
-                core->u.keyButtonPointer.rootX = e->root_x;
-                core->u.keyButtonPointer.rootY = e->root_y;
-                core->u.keyButtonPointer.state = e->corestate;
-                core->u.keyButtonPointer.root = e->root;
-                EventSetKeyRepeatFlag(core,
-                                      (e->type == ET_KeyPress &&
-                                       e->key_repeat));
-                ret = Success;
-            }
-            break;
-        case ET_ProximityIn:
-        case ET_ProximityOut:
-        case ET_RawKeyPress:
-        case ET_RawKeyRelease:
-        case ET_RawButtonPress:
-        case ET_RawButtonRelease:
-        case ET_RawMotion:
-            ret = BadMatch;
-            goto out;
-        default:
-            /* XXX: */
-            ErrorF("[dix] EventToCore: Not implemented yet \n");
-            ret = BadImplementation;
-    }
-
-out:
-    *core_out = core;
-    *count_out = count;
-    return ret;
-}
-
-/**
- * Convert the given event to the respective XI 1.x event and store it in
- * xi. xi is allocated on demand and must be freed by the caller.
- * count returns the number of events in xi. If count is 1, and the type of
- * xi is GenericEvent, then xi may be larger than 32 bytes.
- *
- * Return values:
- * Success ... core contains the matching core event.
- * BadValue .. One or more values in the internal event are invalid.
- * BadMatch .. The event has no XI equivalent.
- *
- * @param[in] ev The event to convert into an XI 1 event.
- * @param[out] xi Future memory location for the XI event.
- * @param[out] count Number of elements in xi.
- *
- * @return Success or the error code.
- */
-int
-EventToXI(InternalEvent *ev, xEvent **xi, int *count)
-{
-    switch (ev->any.type)
-    {
-        case ET_Motion:
-        case ET_ButtonPress:
-        case ET_ButtonRelease:
-        case ET_KeyPress:
-        case ET_KeyRelease:
-        case ET_ProximityIn:
-        case ET_ProximityOut:
-            return eventToKeyButtonPointer(&ev->device_event, xi, count);
-        case ET_DeviceChanged:
-        case ET_RawKeyPress:
-        case ET_RawKeyRelease:
-        case ET_RawButtonPress:
-        case ET_RawButtonRelease:
-        case ET_RawMotion:
-            *count = 0;
-            *xi = NULL;
-            return BadMatch;
-        default:
-            break;
-    }
-
-    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
-    return BadImplementation;
-}
-
-/**
- * Convert the given event to the respective XI 2.x event and store it in xi.
- * xi is allocated on demand and must be freed by the caller.
- *
- * Return values:
- * Success ... core contains the matching core event.
- * BadValue .. One or more values in the internal event are invalid.
- * BadMatch .. The event has no XI2 equivalent.
- *
- * @param[in] ev The event to convert into an XI2 event
- * @param[out] xi Future memory location for the XI2 event.
- *
- * @return Success or the error code.
- */
-int
-EventToXI2(InternalEvent *ev, xEvent **xi)
-{
-    switch (ev->any.type)
-    {
-        /* Enter/FocusIn are for grabs. We don't need an actual event, since
-         * the real events delivered are triggered elsewhere */
-        case ET_Enter:
-        case ET_FocusIn:
-            *xi = NULL;
-            return Success;
-        case ET_Motion:
-        case ET_ButtonPress:
-        case ET_ButtonRelease:
-        case ET_KeyPress:
-        case ET_KeyRelease:
-            return eventToDeviceEvent(&ev->device_event, xi);
-        case ET_ProximityIn:
-        case ET_ProximityOut:
-            *xi = NULL;
-            return BadMatch;
-        case ET_DeviceChanged:
-            return eventToDeviceChanged(&ev->changed_event, xi);
-        case ET_RawKeyPress:
-        case ET_RawKeyRelease:
-        case ET_RawButtonPress:
-        case ET_RawButtonRelease:
-        case ET_RawMotion:
-            return eventToRawEvent(&ev->raw_event, xi);
-        default:
-            break;
-    }
-
-    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
-    return BadImplementation;
-}
-
-static int
-eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
-{
-    int num_events;
-    int first; /* dummy */
-    deviceKeyButtonPointer *kbp;
-
-    /* Sorry, XI 1.x protocol restrictions. */
-    if (ev->detail.button > 0xFF || ev->deviceid >= 0x80)
-    {
-        *count = 0;
-        return Success;
-    }
-
-    num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
-    if (num_events <= 0)
-    {
-        switch (ev->type)
-        {
-            case ET_KeyPress:
-            case ET_KeyRelease:
-            case ET_ButtonPress:
-            case ET_ButtonRelease:
-                /* no axes is ok */
-                break;
-            case ET_Motion:
-            case ET_ProximityIn:
-            case ET_ProximityOut:
-                *count = 0;
-                return BadMatch;
-        }
-    }
-
-    num_events++; /* the actual event event */
-
-    *xi = calloc(num_events, sizeof(xEvent));
-    if (!(*xi))
-    {
-        return BadAlloc;
-    }
-
-    kbp           = (deviceKeyButtonPointer*)(*xi);
-    kbp->detail   = ev->detail.button;
-    kbp->time     = ev->time;
-    kbp->root     = ev->root;
-    kbp->root_x   = ev->root_x;
-    kbp->root_y   = ev->root_y;
-    kbp->deviceid = ev->deviceid;
-    kbp->state    = ev->corestate;
-    EventSetKeyRepeatFlag((xEvent*)kbp,
-                          (ev->type == ET_KeyPress && ev->key_repeat));
-
-    if (num_events > 1)
-        kbp->deviceid |= MORE_EVENTS;
-
-    switch(ev->type)
-    {
-        case ET_Motion:        kbp->type = DeviceMotionNotify;  break;
-        case ET_ButtonPress:   kbp->type = DeviceButtonPress;   break;
-        case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break;
-        case ET_KeyPress:      kbp->type = DeviceKeyPress;      break;
-        case ET_KeyRelease:    kbp->type = DeviceKeyRelease;    break;
-        case ET_ProximityIn:   kbp->type = ProximityIn;         break;
-        case ET_ProximityOut:  kbp->type = ProximityOut;        break;
-        default:
-            break;
-    }
-
-    if (num_events > 1)
-    {
-        getValuatorEvents(ev, (deviceValuator*)(kbp + 1));
-    }
-
-    *count = num_events;
-    return Success;
-}
-
-
-/**
- * Set first to the first valuator in the event ev and return the number of
- * valuators from first to the last set valuator.
- */
-static int
-countValuators(DeviceEvent *ev, int *first)
-{
-    int first_valuator = -1, last_valuator = -1, num_valuators = 0;
-    int i;
-
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
-    {
-        if (BitIsOn(ev->valuators.mask, i))
-        {
-            if (first_valuator == -1)
-                first_valuator = i;
-            last_valuator = i;
-        }
-    }
-
-    if (first_valuator != -1)
-    {
-        num_valuators = last_valuator - first_valuator + 1;
-        *first = first_valuator;
-    }
-
-    return num_valuators;
-}
-
-static int
-getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
-{
-    int i;
-    int state = 0;
-    int first_valuator, num_valuators;
-
-
-    num_valuators = countValuators(ev, &first_valuator);
-    if (num_valuators > 0)
-    {
-        DeviceIntPtr dev = NULL;
-        dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
-        /* State needs to be assembled BEFORE the device is updated. */
-        state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0;
-        state |= (dev && dev->button) ? (dev->button->state) : 0;
-    }
-
-    /* FIXME: non-continuous valuator data in internal events*/
-    for (i = 0; i < num_valuators; i += 6, xv++) {
-        xv->type = DeviceValuator;
-        xv->first_valuator = first_valuator + i;
-        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
-        xv->deviceid = ev->deviceid;
-        xv->device_state = state;
-        switch (xv->num_valuators) {
-        case 6:
-            xv->valuator5 = ev->valuators.data[xv->first_valuator + 5];
-        case 5:
-            xv->valuator4 = ev->valuators.data[xv->first_valuator + 4];
-        case 4:
-            xv->valuator3 = ev->valuators.data[xv->first_valuator + 3];
-        case 3:
-            xv->valuator2 = ev->valuators.data[xv->first_valuator + 2];
-        case 2:
-            xv->valuator1 = ev->valuators.data[xv->first_valuator + 1];
-        case 1:
-            xv->valuator0 = ev->valuators.data[xv->first_valuator + 0];
-        }
-
-        if (i + 6 < num_valuators)
-            xv->deviceid |= MORE_EVENTS;
-    }
-
-    return (num_valuators + 5) / 6;
-}
-
-
-static int
-appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info)
-{
-    uint32_t *kc;
-    int i;
-
-    info->type = XIKeyClass;
-    info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
-    info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
-    info->sourceid = dce->sourceid;
-
-    kc = (uint32_t*)&info[1];
-    for (i = 0; i < info->num_keycodes; i++)
-        *kc++ = i + dce->keys.min_keycode;
-
-    return info->length * 4;
-}
-
-static int
-appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info)
-{
-    unsigned char *bits;
-    int mask_len;
-
-    mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
-
-    info->type = XIButtonClass;
-    info->num_buttons = dce->buttons.num_buttons;
-    info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
-                   info->num_buttons + mask_len;
-    info->sourceid = dce->sourceid;
-
-    bits = (unsigned char*)&info[1];
-    memset(bits, 0, mask_len * 4);
-    /* FIXME: is_down? */
-
-    bits += mask_len * 4;
-    memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
-
-    return info->length * 4;
-}
-
-static int
-appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber)
-{
-    info->type = XIValuatorClass;
-    info->length = sizeof(xXIValuatorInfo)/4;
-    info->label = dce->valuators[axisnumber].name;
-    info->min.integral = dce->valuators[axisnumber].min;
-    info->min.frac = 0;
-    info->max.integral = dce->valuators[axisnumber].max;
-    info->max.frac = 0;
-    /* FIXME: value */
-    info->value.integral = 0;
-    info->value.frac = 0;
-    info->resolution = dce->valuators[axisnumber].resolution;
-    info->number = axisnumber;
-    info->mode = dce->valuators[axisnumber].mode;
-    info->sourceid = dce->sourceid;
-
-    return info->length * 4;
-}
-
-static int
-eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
-{
-    xXIDeviceChangedEvent *dcce;
-    int len = sizeof(xXIDeviceChangedEvent);
-    int nkeys;
-    char *ptr;
-
-    if (dce->buttons.num_buttons)
-    {
-        len += sizeof(xXIButtonInfo);
-        len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
-        len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
-    }
-    if (dce->num_valuators)
-        len += sizeof(xXIValuatorInfo) * dce->num_valuators;
-
-    nkeys = (dce->keys.max_keycode > 0) ?
-                dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
-    if (nkeys > 0)
-    {
-        len += sizeof(xXIKeyInfo);
-        len += sizeof(CARD32) * nkeys; /* keycodes */
-    }
-
-    dcce = calloc(1, len);
-    if (!dcce)
-    {
-        ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
-        return BadAlloc;
-    }
-
-    dcce->type         = GenericEvent;
-    dcce->extension    = IReqCode;
-    dcce->evtype       = XI_DeviceChanged;
-    dcce->time         = dce->time;
-    dcce->deviceid     = dce->deviceid;
-    dcce->sourceid     = dce->sourceid;
-    dcce->reason       = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
-    dcce->num_classes  = 0;
-    dcce->length = bytes_to_int32(len - sizeof(xEvent));
-
-    ptr = (char*)&dcce[1];
-    if (dce->buttons.num_buttons)
-    {
-        dcce->num_classes++;
-        ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr);
-    }
-
-    if (nkeys)
-    {
-        dcce->num_classes++;
-        ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr);
-    }
-
-    if (dce->num_valuators)
-    {
-        int i;
-
-        dcce->num_classes += dce->num_valuators;
-        for (i = 0; i < dce->num_valuators; i++)
-            ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i);
-    }
-
-    *xi = (xEvent*)dcce;
-
-    return Success;
-}
-
-static int count_bits(unsigned char* ptr, int len)
-{
-    int bits = 0;
-    unsigned int i;
-    unsigned char x;
-
-    for (i = 0; i < len; i++)
-    {
-        x = ptr[i];
-        while(x > 0)
-        {
-            bits += (x & 0x1);
-            x >>= 1;
-        }
-    }
-    return bits;
-}
-
-static int
-eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
-{
-    int len = sizeof(xXIDeviceEvent);
-    xXIDeviceEvent *xde;
-    int i, btlen, vallen;
-    char *ptr;
-    FP3232 *axisval;
-
-    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
-     * with MAX_VALUATORS below */
-    /* btlen is in 4 byte units */
-    btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
-    len += btlen * 4; /* buttonmask len */
-
-
-    vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
-    len += vallen * 2 * sizeof(uint32_t); /* axisvalues */
-    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
-    len += vallen * 4; /* valuators mask */
-
-    *xi = calloc(1, len);
-    xde = (xXIDeviceEvent*)*xi;
-    xde->type           = GenericEvent;
-    xde->extension      = IReqCode;
-    xde->evtype         = GetXI2Type((InternalEvent*)ev);
-    xde->time           = ev->time;
-    xde->length         = bytes_to_int32(len - sizeof(xEvent));
-    xde->detail         = ev->detail.button;
-    xde->root           = ev->root;
-    xde->buttons_len    = btlen;
-    xde->valuators_len  = vallen;
-    xde->deviceid       = ev->deviceid;
-    xde->sourceid       = ev->sourceid;
-    xde->root_x         = FP1616(ev->root_x, ev->root_x_frac);
-    xde->root_y         = FP1616(ev->root_y, ev->root_y_frac);
-
-    if (ev->key_repeat)
-        xde->flags      |= XIKeyRepeat;
-
-    xde->mods.base_mods         = ev->mods.base;
-    xde->mods.latched_mods      = ev->mods.latched;
-    xde->mods.locked_mods       = ev->mods.locked;
-    xde->mods.effective_mods    = ev->mods.effective;
-
-    xde->group.base_group       = ev->group.base;
-    xde->group.latched_group    = ev->group.latched;
-    xde->group.locked_group     = ev->group.locked;
-    xde->group.effective_group  = ev->group.effective;
-
-    ptr = (char*)&xde[1];
-    for (i = 0; i < sizeof(ev->buttons) * 8; i++)
-    {
-        if (BitIsOn(ev->buttons, i))
-            SetBit(ptr, i);
-    }
-
-    ptr += xde->buttons_len * 4;
-    axisval = (FP3232*)(ptr + xde->valuators_len * 4);
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
-    {
-        if (BitIsOn(ev->valuators.mask, i))
-        {
-            SetBit(ptr, i);
-            axisval->integral = ev->valuators.data[i];
-            axisval->frac = ev->valuators.data_frac[i];
-            axisval++;
-        }
-    }
-
-    return Success;
-}
-
-static int
-eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
-{
-    xXIRawEvent* raw;
-    int vallen, nvals;
-    int i, len = sizeof(xXIRawEvent);
-    char *ptr;
-    FP3232 *axisval;
-
-    nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
-    len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once
-                                    raw, once processed */
-    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
-    len += vallen * 4; /* valuators mask */
-
-    *xi = calloc(1, len);
-    raw = (xXIRawEvent*)*xi;
-    raw->type           = GenericEvent;
-    raw->extension      = IReqCode;
-    raw->evtype         = GetXI2Type((InternalEvent*)ev);
-    raw->time           = ev->time;
-    raw->length         = bytes_to_int32(len - sizeof(xEvent));
-    raw->detail         = ev->detail.button;
-    raw->deviceid       = ev->deviceid;
-    raw->valuators_len  = vallen;
-
-    ptr = (char*)&raw[1];
-    axisval = (FP3232*)(ptr + raw->valuators_len * 4);
-    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
-    {
-        if (BitIsOn(ev->valuators.mask, i))
-        {
-            SetBit(ptr, i);
-            axisval->integral = ev->valuators.data[i];
-            axisval->frac = ev->valuators.data_frac[i];
-            (axisval + nvals)->integral = ev->valuators.data_raw[i];
-            (axisval + nvals)->frac = ev->valuators.data_raw_frac[i];
-            axisval++;
-        }
-    }
-
-    return Success;
-}
-
-/**
- * Return the corresponding core type for the given event or 0 if no core
- * equivalent exists.
- */
-int
-GetCoreType(InternalEvent *event)
-{
-    int coretype = 0;
-    switch(event->any.type)
-    {
-        case ET_Motion:         coretype = MotionNotify;  break;
-        case ET_ButtonPress:    coretype = ButtonPress;   break;
-        case ET_ButtonRelease:  coretype = ButtonRelease; break;
-        case ET_KeyPress:       coretype = KeyPress;      break;
-        case ET_KeyRelease:     coretype = KeyRelease;    break;
-        default:
-            break;
-    }
-    return coretype;
-}
-
-/**
- * Return the corresponding XI 1.x type for the given event or 0 if no
- * equivalent exists.
- */
-int
-GetXIType(InternalEvent *event)
-{
-    int xitype = 0;
-    switch(event->any.type)
-    {
-        case ET_Motion:         xitype = DeviceMotionNotify;  break;
-        case ET_ButtonPress:    xitype = DeviceButtonPress;   break;
-        case ET_ButtonRelease:  xitype = DeviceButtonRelease; break;
-        case ET_KeyPress:       xitype = DeviceKeyPress;      break;
-        case ET_KeyRelease:     xitype = DeviceKeyRelease;    break;
-        case ET_ProximityIn:    xitype = ProximityIn;         break;
-        case ET_ProximityOut:   xitype = ProximityOut;        break;
-        default:
-            break;
-    }
-    return xitype;
-}
-
-/**
- * Return the corresponding XI 2.x type for the given event or 0 if no
- * equivalent exists.
- */
-int
-GetXI2Type(InternalEvent *event)
-{
-    int xi2type = 0;
-
-    switch(event->any.type)
-    {
-        case ET_Motion:         xi2type = XI_Motion;           break;
-        case ET_ButtonPress:    xi2type = XI_ButtonPress;      break;
-        case ET_ButtonRelease:  xi2type = XI_ButtonRelease;    break;
-        case ET_KeyPress:       xi2type = XI_KeyPress;         break;
-        case ET_KeyRelease:     xi2type = XI_KeyRelease;       break;
-        case ET_Enter:          xi2type = XI_Enter;            break;
-        case ET_Leave:          xi2type = XI_Leave;            break;
-        case ET_Hierarchy:      xi2type = XI_HierarchyChanged; break;
-        case ET_DeviceChanged:  xi2type = XI_DeviceChanged;    break;
-        case ET_RawKeyPress:    xi2type = XI_RawKeyPress;      break;
-        case ET_RawKeyRelease:  xi2type = XI_RawKeyRelease;    break;
-        case ET_RawButtonPress: xi2type = XI_RawButtonPress;   break;
-        case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break;
-        case ET_RawMotion:      xi2type = XI_RawMotion;        break;
-        case ET_FocusIn:        xi2type = XI_FocusIn;          break;
-        case ET_FocusOut:       xi2type = XI_FocusOut;         break;
-        default:
-            break;
-    }
-    return xi2type;
-}
+/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/**
+ * @file eventconvert.c
+ * This file contains event conversion routines from InternalEvent to the
+ * matching protocol events.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdint.h>
+#include <X11/X.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
+
+#include "dix.h"
+#include "inputstr.h"
+#include "misc.h"
+#include "eventstr.h"
+#include "exglobals.h"
+#include "eventconvert.h"
+#include "xiquerydevice.h"
+#include "xkbsrv.h"
+
+
+static int countValuators(DeviceEvent *ev, int *first);
+static int getValuatorEvents(DeviceEvent *ev, deviceValuator *xv);
+static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
+static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
+static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
+static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
+
+/* Do not use, read comments below */
+BOOL EventIsKeyRepeat(xEvent *event);
+
+/**
+ * Hack to allow detectable autorepeat for core and XI1 events.
+ * The sequence number is unused until we send to the client and can be
+ * misused to store data. More or less, anyway.
+ *
+ * Do not use this. It may change any time without warning, eat your babies
+ * and piss on your cat.
+ */
+static void
+EventSetKeyRepeatFlag(xEvent *event, BOOL on)
+{
+    event->u.u.sequenceNumber = on;
+}
+
+/**
+ * Check if the event was marked as a repeat event before.
+ * NOTE: This is a nasty hack and should NOT be used by anyone else but
+ * TryClientEvents.
+ */
+BOOL
+EventIsKeyRepeat(xEvent *event)
+{
+    return !!event->u.u.sequenceNumber;
+}
+
+/**
+ * Convert the given event to the respective core event.
+ *
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no core equivalent.
+ *
+ * @param[in] event The event to convert into a core event.
+ * @param[in] core The memory location to store the core event at.
+ * @return Success or the matching error code.
+ */
+int
+EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
+{
+    xEvent *core = NULL;
+    int count = 0;
+    int ret = BadImplementation;
+
+    switch(event->any.type)
+    {
+        case ET_Motion:
+            {
+                DeviceEvent *e = &event->device_event;
+                /* Don't create core motion event if neither x nor y are
+                 * present */
+                if (!BitIsOn(e->valuators.mask, 0) &&
+                    !BitIsOn(e->valuators.mask, 1))
+                {
+                    ret = BadMatch;
+                    goto out;
+                }
+            }
+            /* fallthrough */
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+            {
+                DeviceEvent *e = &event->device_event;
+
+                if (e->detail.key > 0xFF)
+                {
+                    ret = BadMatch;
+                    goto out;
+                }
+
+                core = calloc(1, sizeof(*core));
+                if (!core)
+                    return BadAlloc;
+                count = 1;
+                core->u.u.type = e->type - ET_KeyPress + KeyPress;
+                core->u.u.detail = e->detail.key & 0xFF;
+                core->u.keyButtonPointer.time = e->time;
+                core->u.keyButtonPointer.rootX = e->root_x;
+                core->u.keyButtonPointer.rootY = e->root_y;
+                core->u.keyButtonPointer.state = e->corestate;
+                core->u.keyButtonPointer.root = e->root;
+                EventSetKeyRepeatFlag(core,
+                                      (e->type == ET_KeyPress &&
+                                       e->key_repeat));
+                ret = Success;
+            }
+            break;
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+        case ET_RawKeyPress:
+        case ET_RawKeyRelease:
+        case ET_RawButtonPress:
+        case ET_RawButtonRelease:
+        case ET_RawMotion:
+            ret = BadMatch;
+            goto out;
+        default:
+            /* XXX: */
+            ErrorF("[dix] EventToCore: Not implemented yet \n");
+            ret = BadImplementation;
+    }
+
+out:
+    *core_out = core;
+    *count_out = count;
+    return ret;
+}
+
+/**
+ * Convert the given event to the respective XI 1.x event and store it in
+ * xi. xi is allocated on demand and must be freed by the caller.
+ * count returns the number of events in xi. If count is 1, and the type of
+ * xi is GenericEvent, then xi may be larger than 32 bytes.
+ *
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no XI equivalent.
+ *
+ * @param[in] ev The event to convert into an XI 1 event.
+ * @param[out] xi Future memory location for the XI event.
+ * @param[out] count Number of elements in xi.
+ *
+ * @return Success or the error code.
+ */
+int
+EventToXI(InternalEvent *ev, xEvent **xi, int *count)
+{
+    switch (ev->any.type)
+    {
+        case ET_Motion:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            return eventToKeyButtonPointer(&ev->device_event, xi, count);
+        case ET_DeviceChanged:
+        case ET_RawKeyPress:
+        case ET_RawKeyRelease:
+        case ET_RawButtonPress:
+        case ET_RawButtonRelease:
+        case ET_RawMotion:
+            *count = 0;
+            *xi = NULL;
+            return BadMatch;
+        default:
+            break;
+    }
+
+    ErrorF("[dix] EventToXI: Not implemented for %d \n", ev->any.type);
+    return BadImplementation;
+}
+
+/**
+ * Convert the given event to the respective XI 2.x event and store it in xi.
+ * xi is allocated on demand and must be freed by the caller.
+ *
+ * Return values:
+ * Success ... core contains the matching core event.
+ * BadValue .. One or more values in the internal event are invalid.
+ * BadMatch .. The event has no XI2 equivalent.
+ *
+ * @param[in] ev The event to convert into an XI2 event
+ * @param[out] xi Future memory location for the XI2 event.
+ *
+ * @return Success or the error code.
+ */
+int
+EventToXI2(InternalEvent *ev, xEvent **xi)
+{
+    switch (ev->any.type)
+    {
+        /* Enter/FocusIn are for grabs. We don't need an actual event, since
+         * the real events delivered are triggered elsewhere */
+        case ET_Enter:
+        case ET_FocusIn:
+            *xi = NULL;
+            return Success;
+        case ET_Motion:
+        case ET_ButtonPress:
+        case ET_ButtonRelease:
+        case ET_KeyPress:
+        case ET_KeyRelease:
+            return eventToDeviceEvent(&ev->device_event, xi);
+        case ET_ProximityIn:
+        case ET_ProximityOut:
+            *xi = NULL;
+            return BadMatch;
+        case ET_DeviceChanged:
+            return eventToDeviceChanged(&ev->changed_event, xi);
+        case ET_RawKeyPress:
+        case ET_RawKeyRelease:
+        case ET_RawButtonPress:
+        case ET_RawButtonRelease:
+        case ET_RawMotion:
+            return eventToRawEvent(&ev->raw_event, xi);
+        default:
+            break;
+    }
+
+    ErrorF("[dix] EventToXI2: Not implemented for %d \n", ev->any.type);
+    return BadImplementation;
+}
+
+static int
+eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
+{
+    int num_events;
+    int first; /* dummy */
+    deviceKeyButtonPointer *kbp;
+
+    /* Sorry, XI 1.x protocol restrictions. */
+    if (ev->detail.button > 0xFF || ev->deviceid >= 0x80)
+    {
+        *count = 0;
+        return Success;
+    }
+
+    num_events = (countValuators(ev, &first) + 5)/6; /* valuator ev */
+    if (num_events <= 0)
+    {
+        switch (ev->type)
+        {
+            case ET_KeyPress:
+            case ET_KeyRelease:
+            case ET_ButtonPress:
+            case ET_ButtonRelease:
+                /* no axes is ok */
+                break;
+            case ET_Motion:
+            case ET_ProximityIn:
+            case ET_ProximityOut:
+                *count = 0;
+                return BadMatch;
+	    default:
+		*count = 0;
+		return BadImplementation;
+        }
+    }
+
+    num_events++; /* the actual event event */
+
+    *xi = calloc(num_events, sizeof(xEvent));
+    if (!(*xi))
+    {
+        return BadAlloc;
+    }
+
+    kbp           = (deviceKeyButtonPointer*)(*xi);
+    kbp->detail   = ev->detail.button;
+    kbp->time     = ev->time;
+    kbp->root     = ev->root;
+    kbp->root_x   = ev->root_x;
+    kbp->root_y   = ev->root_y;
+    kbp->deviceid = ev->deviceid;
+    kbp->state    = ev->corestate;
+    EventSetKeyRepeatFlag((xEvent*)kbp,
+                          (ev->type == ET_KeyPress && ev->key_repeat));
+
+    if (num_events > 1)
+        kbp->deviceid |= MORE_EVENTS;
+
+    switch(ev->type)
+    {
+        case ET_Motion:        kbp->type = DeviceMotionNotify;  break;
+        case ET_ButtonPress:   kbp->type = DeviceButtonPress;   break;
+        case ET_ButtonRelease: kbp->type = DeviceButtonRelease; break;
+        case ET_KeyPress:      kbp->type = DeviceKeyPress;      break;
+        case ET_KeyRelease:    kbp->type = DeviceKeyRelease;    break;
+        case ET_ProximityIn:   kbp->type = ProximityIn;         break;
+        case ET_ProximityOut:  kbp->type = ProximityOut;        break;
+        default:
+            break;
+    }
+
+    if (num_events > 1)
+    {
+        getValuatorEvents(ev, (deviceValuator*)(kbp + 1));
+    }
+
+    *count = num_events;
+    return Success;
+}
+
+
+/**
+ * Set first to the first valuator in the event ev and return the number of
+ * valuators from first to the last set valuator.
+ */
+static int
+countValuators(DeviceEvent *ev, int *first)
+{
+    int first_valuator = -1, last_valuator = -1, num_valuators = 0;
+    int i;
+
+    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    {
+        if (BitIsOn(ev->valuators.mask, i))
+        {
+            if (first_valuator == -1)
+                first_valuator = i;
+            last_valuator = i;
+        }
+    }
+
+    if (first_valuator != -1)
+    {
+        num_valuators = last_valuator - first_valuator + 1;
+        *first = first_valuator;
+    }
+
+    return num_valuators;
+}
+
+static int
+getValuatorEvents(DeviceEvent *ev, deviceValuator *xv)
+{
+    int i;
+    int state = 0;
+    int first_valuator, num_valuators;
+
+
+    num_valuators = countValuators(ev, &first_valuator);
+    if (num_valuators > 0)
+    {
+        DeviceIntPtr dev = NULL;
+        dixLookupDevice(&dev, ev->deviceid, serverClient, DixUseAccess);
+        /* State needs to be assembled BEFORE the device is updated. */
+        state = (dev && dev->key) ? XkbStateFieldFromRec(&dev->key->xkbInfo->state) : 0;
+        state |= (dev && dev->button) ? (dev->button->state) : 0;
+    }
+
+    /* FIXME: non-continuous valuator data in internal events*/
+    for (i = 0; i < num_valuators; i += 6, xv++) {
+        xv->type = DeviceValuator;
+        xv->first_valuator = first_valuator + i;
+        xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i);
+        xv->deviceid = ev->deviceid;
+        xv->device_state = state;
+        switch (xv->num_valuators) {
+        case 6:
+            xv->valuator5 = ev->valuators.data[xv->first_valuator + 5];
+        case 5:
+            xv->valuator4 = ev->valuators.data[xv->first_valuator + 4];
+        case 4:
+            xv->valuator3 = ev->valuators.data[xv->first_valuator + 3];
+        case 3:
+            xv->valuator2 = ev->valuators.data[xv->first_valuator + 2];
+        case 2:
+            xv->valuator1 = ev->valuators.data[xv->first_valuator + 1];
+        case 1:
+            xv->valuator0 = ev->valuators.data[xv->first_valuator + 0];
+        }
+
+        if (i + 6 < num_valuators)
+            xv->deviceid |= MORE_EVENTS;
+    }
+
+    return (num_valuators + 5) / 6;
+}
+
+
+static int
+appendKeyInfo(DeviceChangedEvent *dce, xXIKeyInfo* info)
+{
+    uint32_t *kc;
+    int i;
+
+    info->type = XIKeyClass;
+    info->num_keycodes = dce->keys.max_keycode - dce->keys.min_keycode + 1;
+    info->length = sizeof(xXIKeyInfo)/4 + info->num_keycodes;
+    info->sourceid = dce->sourceid;
+
+    kc = (uint32_t*)&info[1];
+    for (i = 0; i < info->num_keycodes; i++)
+        *kc++ = i + dce->keys.min_keycode;
+
+    return info->length * 4;
+}
+
+static int
+appendButtonInfo(DeviceChangedEvent *dce, xXIButtonInfo *info)
+{
+    unsigned char *bits;
+    int mask_len;
+
+    mask_len = bytes_to_int32(bits_to_bytes(dce->buttons.num_buttons));
+
+    info->type = XIButtonClass;
+    info->num_buttons = dce->buttons.num_buttons;
+    info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
+                   info->num_buttons + mask_len;
+    info->sourceid = dce->sourceid;
+
+    bits = (unsigned char*)&info[1];
+    memset(bits, 0, mask_len * 4);
+    /* FIXME: is_down? */
+
+    bits += mask_len * 4;
+    memcpy(bits, dce->buttons.names, dce->buttons.num_buttons * sizeof(Atom));
+
+    return info->length * 4;
+}
+
+static int
+appendValuatorInfo(DeviceChangedEvent *dce, xXIValuatorInfo *info, int axisnumber)
+{
+    info->type = XIValuatorClass;
+    info->length = sizeof(xXIValuatorInfo)/4;
+    info->label = dce->valuators[axisnumber].name;
+    info->min.integral = dce->valuators[axisnumber].min;
+    info->min.frac = 0;
+    info->max.integral = dce->valuators[axisnumber].max;
+    info->max.frac = 0;
+    /* FIXME: value */
+    info->value.integral = 0;
+    info->value.frac = 0;
+    info->resolution = dce->valuators[axisnumber].resolution;
+    info->number = axisnumber;
+    info->mode = dce->valuators[axisnumber].mode;
+    info->sourceid = dce->sourceid;
+
+    return info->length * 4;
+}
+
+static int
+eventToDeviceChanged(DeviceChangedEvent *dce, xEvent **xi)
+{
+    xXIDeviceChangedEvent *dcce;
+    int len = sizeof(xXIDeviceChangedEvent);
+    int nkeys;
+    char *ptr;
+
+    if (dce->buttons.num_buttons)
+    {
+        len += sizeof(xXIButtonInfo);
+        len += dce->buttons.num_buttons * sizeof(Atom); /* button names */
+        len += pad_to_int32(bits_to_bytes(dce->buttons.num_buttons));
+    }
+    if (dce->num_valuators)
+        len += sizeof(xXIValuatorInfo) * dce->num_valuators;
+
+    nkeys = (dce->keys.max_keycode > 0) ?
+                dce->keys.max_keycode - dce->keys.min_keycode + 1 : 0;
+    if (nkeys > 0)
+    {
+        len += sizeof(xXIKeyInfo);
+        len += sizeof(CARD32) * nkeys; /* keycodes */
+    }
+
+    dcce = calloc(1, len);
+    if (!dcce)
+    {
+        ErrorF("[Xi] BadAlloc in SendDeviceChangedEvent.\n");
+        return BadAlloc;
+    }
+
+    dcce->type         = GenericEvent;
+    dcce->extension    = IReqCode;
+    dcce->evtype       = XI_DeviceChanged;
+    dcce->time         = dce->time;
+    dcce->deviceid     = dce->deviceid;
+    dcce->sourceid     = dce->sourceid;
+    dcce->reason       = (dce->flags & DEVCHANGE_DEVICE_CHANGE) ? XIDeviceChange : XISlaveSwitch;
+    dcce->num_classes  = 0;
+    dcce->length = bytes_to_int32(len - sizeof(xEvent));
+
+    ptr = (char*)&dcce[1];
+    if (dce->buttons.num_buttons)
+    {
+        dcce->num_classes++;
+        ptr += appendButtonInfo(dce, (xXIButtonInfo*)ptr);
+    }
+
+    if (nkeys)
+    {
+        dcce->num_classes++;
+        ptr += appendKeyInfo(dce, (xXIKeyInfo*)ptr);
+    }
+
+    if (dce->num_valuators)
+    {
+        int i;
+
+        dcce->num_classes += dce->num_valuators;
+        for (i = 0; i < dce->num_valuators; i++)
+            ptr += appendValuatorInfo(dce, (xXIValuatorInfo*)ptr, i);
+    }
+
+    *xi = (xEvent*)dcce;
+
+    return Success;
+}
+
+static int count_bits(unsigned char* ptr, int len)
+{
+    int bits = 0;
+    unsigned int i;
+    unsigned char x;
+
+    for (i = 0; i < len; i++)
+    {
+        x = ptr[i];
+        while(x > 0)
+        {
+            bits += (x & 0x1);
+            x >>= 1;
+        }
+    }
+    return bits;
+}
+
+static int
+eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
+{
+    int len = sizeof(xXIDeviceEvent);
+    xXIDeviceEvent *xde;
+    int i, btlen, vallen;
+    char *ptr;
+    FP3232 *axisval;
+
+    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
+     * with MAX_VALUATORS below */
+    /* btlen is in 4 byte units */
+    btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
+    len += btlen * 4; /* buttonmask len */
+
+
+    vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
+    len += vallen * 2 * sizeof(uint32_t); /* axisvalues */
+    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
+    len += vallen * 4; /* valuators mask */
+
+    *xi = calloc(1, len);
+    xde = (xXIDeviceEvent*)*xi;
+    xde->type           = GenericEvent;
+    xde->extension      = IReqCode;
+    xde->evtype         = GetXI2Type((InternalEvent*)ev);
+    xde->time           = ev->time;
+    xde->length         = bytes_to_int32(len - sizeof(xEvent));
+    xde->detail         = ev->detail.button;
+    xde->root           = ev->root;
+    xde->buttons_len    = btlen;
+    xde->valuators_len  = vallen;
+    xde->deviceid       = ev->deviceid;
+    xde->sourceid       = ev->sourceid;
+    xde->root_x         = FP1616(ev->root_x, ev->root_x_frac);
+    xde->root_y         = FP1616(ev->root_y, ev->root_y_frac);
+
+    if (ev->key_repeat)
+        xde->flags      |= XIKeyRepeat;
+
+    xde->mods.base_mods         = ev->mods.base;
+    xde->mods.latched_mods      = ev->mods.latched;
+    xde->mods.locked_mods       = ev->mods.locked;
+    xde->mods.effective_mods    = ev->mods.effective;
+
+    xde->group.base_group       = ev->group.base;
+    xde->group.latched_group    = ev->group.latched;
+    xde->group.locked_group     = ev->group.locked;
+    xde->group.effective_group  = ev->group.effective;
+
+    ptr = (char*)&xde[1];
+    for (i = 0; i < sizeof(ev->buttons) * 8; i++)
+    {
+        if (BitIsOn(ev->buttons, i))
+            SetBit(ptr, i);
+    }
+
+    ptr += xde->buttons_len * 4;
+    axisval = (FP3232*)(ptr + xde->valuators_len * 4);
+    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    {
+        if (BitIsOn(ev->valuators.mask, i))
+        {
+            SetBit(ptr, i);
+            axisval->integral = ev->valuators.data[i];
+            axisval->frac = ev->valuators.data_frac[i];
+            axisval++;
+        }
+    }
+
+    return Success;
+}
+
+static int
+eventToRawEvent(RawDeviceEvent *ev, xEvent **xi)
+{
+    xXIRawEvent* raw;
+    int vallen, nvals;
+    int i, len = sizeof(xXIRawEvent);
+    char *ptr;
+    FP3232 *axisval;
+
+    nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask));
+    len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once
+                                    raw, once processed */
+    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
+    len += vallen * 4; /* valuators mask */
+
+    *xi = calloc(1, len);
+    raw = (xXIRawEvent*)*xi;
+    raw->type           = GenericEvent;
+    raw->extension      = IReqCode;
+    raw->evtype         = GetXI2Type((InternalEvent*)ev);
+    raw->time           = ev->time;
+    raw->length         = bytes_to_int32(len - sizeof(xEvent));
+    raw->detail         = ev->detail.button;
+    raw->deviceid       = ev->deviceid;
+    raw->valuators_len  = vallen;
+
+    ptr = (char*)&raw[1];
+    axisval = (FP3232*)(ptr + raw->valuators_len * 4);
+    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
+    {
+        if (BitIsOn(ev->valuators.mask, i))
+        {
+            SetBit(ptr, i);
+            axisval->integral = ev->valuators.data[i];
+            axisval->frac = ev->valuators.data_frac[i];
+            (axisval + nvals)->integral = ev->valuators.data_raw[i];
+            (axisval + nvals)->frac = ev->valuators.data_raw_frac[i];
+            axisval++;
+        }
+    }
+
+    return Success;
+}
+
+/**
+ * Return the corresponding core type for the given event or 0 if no core
+ * equivalent exists.
+ */
+int
+GetCoreType(InternalEvent *event)
+{
+    int coretype = 0;
+    switch(event->any.type)
+    {
+        case ET_Motion:         coretype = MotionNotify;  break;
+        case ET_ButtonPress:    coretype = ButtonPress;   break;
+        case ET_ButtonRelease:  coretype = ButtonRelease; break;
+        case ET_KeyPress:       coretype = KeyPress;      break;
+        case ET_KeyRelease:     coretype = KeyRelease;    break;
+        default:
+            break;
+    }
+    return coretype;
+}
+
+/**
+ * Return the corresponding XI 1.x type for the given event or 0 if no
+ * equivalent exists.
+ */
+int
+GetXIType(InternalEvent *event)
+{
+    int xitype = 0;
+    switch(event->any.type)
+    {
+        case ET_Motion:         xitype = DeviceMotionNotify;  break;
+        case ET_ButtonPress:    xitype = DeviceButtonPress;   break;
+        case ET_ButtonRelease:  xitype = DeviceButtonRelease; break;
+        case ET_KeyPress:       xitype = DeviceKeyPress;      break;
+        case ET_KeyRelease:     xitype = DeviceKeyRelease;    break;
+        case ET_ProximityIn:    xitype = ProximityIn;         break;
+        case ET_ProximityOut:   xitype = ProximityOut;        break;
+        default:
+            break;
+    }
+    return xitype;
+}
+
+/**
+ * Return the corresponding XI 2.x type for the given event or 0 if no
+ * equivalent exists.
+ */
+int
+GetXI2Type(InternalEvent *event)
+{
+    int xi2type = 0;
+
+    switch(event->any.type)
+    {
+        case ET_Motion:         xi2type = XI_Motion;           break;
+        case ET_ButtonPress:    xi2type = XI_ButtonPress;      break;
+        case ET_ButtonRelease:  xi2type = XI_ButtonRelease;    break;
+        case ET_KeyPress:       xi2type = XI_KeyPress;         break;
+        case ET_KeyRelease:     xi2type = XI_KeyRelease;       break;
+        case ET_Enter:          xi2type = XI_Enter;            break;
+        case ET_Leave:          xi2type = XI_Leave;            break;
+        case ET_Hierarchy:      xi2type = XI_HierarchyChanged; break;
+        case ET_DeviceChanged:  xi2type = XI_DeviceChanged;    break;
+        case ET_RawKeyPress:    xi2type = XI_RawKeyPress;      break;
+        case ET_RawKeyRelease:  xi2type = XI_RawKeyRelease;    break;
+        case ET_RawButtonPress: xi2type = XI_RawButtonPress;   break;
+        case ET_RawButtonRelease: xi2type = XI_RawButtonRelease; break;
+        case ET_RawMotion:      xi2type = XI_RawMotion;        break;
+        case ET_FocusIn:        xi2type = XI_FocusIn;          break;
+        case ET_FocusOut:       xi2type = XI_FocusOut;         break;
+        default:
+            break;
+    }
+    return xi2type;
+}
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c
index 5b8e3798d..2361810a0 100644
--- a/xorg-server/dix/getevents.c
+++ b/xorg-server/dix/getevents.c
@@ -1,1324 +1,1314 @@
-/*
- * Copyright © 2006 Nokia Corporation
- * Copyright © 2006-2007 Daniel Stone
- * Copyright © 2008 Red Hat, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors: Daniel Stone <daniel@fooishbar.org>
- *          Peter Hutterer <peter.hutterer@who-t.net>
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/keysym.h>
-#include <X11/Xproto.h>
-#include <math.h>
-
-#include "misc.h"
-#include "resource.h"
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "cursorstr.h"
-#include "dixstruct.h"
-#include "globals.h"
-#include "dixevents.h"
-#include "mipointer.h"
-#include "eventstr.h"
-#include "eventconvert.h"
-#include "inpututils.h"
-
-#include <X11/extensions/XKBproto.h>
-#include "xkbsrv.h"
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include <pixman.h>
-#include "exglobals.h"
-#include "exevents.h"
-#include "exglobals.h"
-#include "extnsionst.h"
-#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */
-
-/* Number of motion history events to store. */
-#define MOTION_HISTORY_SIZE 256
-
-/* InputEventList is the container list for all input events generated by the
- * DDX. The DDX is expected to call GetEventList() and then pass the list into
- * Get{Pointer|Keyboard}Events.
- */
-EventListPtr InputEventList = NULL;
-int InputEventListLen = 0;
-
-int
-GetEventList(EventListPtr* list)
-{
-    *list = InputEventList;
-    return InputEventListLen;
-}
-
-/**
- * Pick some arbitrary size for Xi motion history.
- */
-int
-GetMotionHistorySize(void)
-{
-    return MOTION_HISTORY_SIZE;
-}
-
-void
-set_button_down(DeviceIntPtr pDev, int button, int type)
-{
-    if (type == BUTTON_PROCESSED)
-        SetBit(pDev->button->down, button);
-    else
-        SetBit(pDev->button->postdown, button);
-}
-
-void
-set_button_up(DeviceIntPtr pDev, int button, int type)
-{
-    if (type == BUTTON_PROCESSED)
-        ClearBit(pDev->button->down, button);
-    else
-        ClearBit(pDev->button->postdown, button);
-}
-
-Bool
-button_is_down(DeviceIntPtr pDev, int button, int type)
-{
-    Bool ret = FALSE;
-
-    if (type & BUTTON_PROCESSED)
-        ret = ret || BitIsOn(pDev->button->down, button);
-    if (type & BUTTON_POSTED)
-        ret = ret || BitIsOn(pDev->button->postdown, button);
-
-    return ret;
-}
-
-void
-set_key_down(DeviceIntPtr pDev, int key_code, int type)
-{
-    if (type == KEY_PROCESSED)
-        SetBit(pDev->key->down, key_code);
-    else
-        SetBit(pDev->key->postdown, key_code);
-}
-
-void
-set_key_up(DeviceIntPtr pDev, int key_code, int type)
-{
-    if (type == KEY_PROCESSED)
-        ClearBit(pDev->key->down, key_code);
-    else
-        ClearBit(pDev->key->postdown, key_code);
-}
-
-Bool
-key_is_down(DeviceIntPtr pDev, int key_code, int type)
-{
-    Bool ret = FALSE;
-
-    if (type & KEY_PROCESSED)
-        ret = ret || BitIsOn(pDev->key->down, key_code);
-    if (type & KEY_POSTED)
-        ret = ret || BitIsOn(pDev->key->postdown, key_code);
-
-    return ret;
-}
-
-static Bool
-key_autorepeats(DeviceIntPtr pDev, int key_code)
-{
-    return !!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] &
-              (1 << (key_code & 7)));
-}
-
-static void
-init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms)
-{
-    memset(event, 0, sizeof(DeviceEvent));
-    event->header = ET_Internal;
-    event->length = sizeof(DeviceEvent);
-    event->time = ms;
-    event->deviceid = dev->id;
-    event->sourceid = dev->id;
-}
-
-static void
-init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
-{
-    memset(event, 0, sizeof(RawDeviceEvent));
-    event->header = ET_Internal;
-    event->length = sizeof(RawDeviceEvent);
-    event->type = ET_RawKeyPress - ET_KeyPress + type;
-    event->time = ms;
-    event->deviceid = dev->id;
-    event->sourceid = dev->id;
-    event->detail.button = detail;
-}
-
-static void
-set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, int32_t* data)
-{
-    int i;
-
-    for (i = 0; i < valuator_mask_size(mask); i++)
-    {
-        if (valuator_mask_isset(mask, i))
-        {
-            SetBit(event->valuators.mask, i);
-            data[i] = valuator_mask_get(mask, i);
-        }
-    }
-}
-
-
-static void
-set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask)
-{
-    int i;
-
-    for (i = 0; i < valuator_mask_size(mask); i++)
-    {
-        if (valuator_mask_isset(mask, i))
-        {
-            SetBit(event->valuators.mask, i);
-            if (valuator_get_mode(dev, i) == Absolute)
-                SetBit(event->valuators.mode, i);
-            event->valuators.data[i] = valuator_mask_get(mask, i);
-            event->valuators.data_frac[i] =
-                dev->last.remainder[i] * (1 << 16) * (1 << 16);
-        }
-    }
-}
-
-void
-CreateClassesChangedEvent(EventList* event,
-                          DeviceIntPtr master,
-                          DeviceIntPtr slave,
-                          int type)
-{
-    int i;
-    DeviceChangedEvent *dce;
-    CARD32 ms = GetTimeInMillis();
-
-    dce = (DeviceChangedEvent*)event->event;
-    memset(dce, 0, sizeof(DeviceChangedEvent));
-    dce->deviceid = slave->id;
-    dce->masterid = master->id;
-    dce->header = ET_Internal;
-    dce->length = sizeof(DeviceChangedEvent);
-    dce->type = ET_DeviceChanged;
-    dce->time = ms;
-    dce->flags = type;
-    dce->flags |= DEVCHANGE_SLAVE_SWITCH;
-    dce->sourceid = slave->id;
-
-    if (slave->button)
-    {
-        dce->buttons.num_buttons = slave->button->numButtons;
-        for (i = 0; i < dce->buttons.num_buttons; i++)
-            dce->buttons.names[i] = slave->button->labels[i];
-    }
-    if (slave->valuator)
-    {
-        dce->num_valuators = slave->valuator->numAxes;
-        for (i = 0; i < dce->num_valuators; i++)
-        {
-            dce->valuators[i].min = slave->valuator->axes[i].min_value;
-            dce->valuators[i].max = slave->valuator->axes[i].max_value;
-            dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
-            dce->valuators[i].mode = slave->valuator->axes[i].mode;
-            dce->valuators[i].name = slave->valuator->axes[i].label;
-        }
-    }
-    if (slave->key)
-    {
-        dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code;
-        dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code;
-    }
-}
-
-/**
- * Rescale the coord between the two axis ranges.
- */
-static int
-rescaleValuatorAxis(int coord, float remainder, float *remainder_return, AxisInfoPtr from, AxisInfoPtr to,
-                    int defmax)
-{
-    int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax, coord_return;
-    float value;
-
-    if(from && from->min_value < from->max_value) {
-        fmin = from->min_value;
-        fmax = from->max_value;
-    }
-    if(to && to->min_value < to->max_value) {
-        tmin = to->min_value;
-        tmax = to->max_value;
-    }
-
-    if(fmin == tmin && fmax == tmax) {
-        if (remainder_return)
-            *remainder_return = remainder;
-        return coord;
-    }
-
-    if(fmax == fmin) { /* avoid division by 0 */
-        if (remainder_return)
-            *remainder_return = 0.0;
-        return 0;
-    }
-
-    value = (coord + remainder - fmin) * (tmax - tmin) / (fmax - fmin) + tmin;
-    coord_return = lroundf(value);
-    if (remainder_return)
-        *remainder_return = value - coord_return;
-    return coord_return;
-}
-
-/**
- * Update all coordinates when changing to a different SD
- * to ensure that relative reporting will work as expected
- * without loss of precision.
- *
- * pDev->last.valuators will be in absolute device coordinates after this
- * function.
- */
-static void
-updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
-{
-    ScreenPtr scr = miPointerGetScreen(pDev);
-    int i;
-    DeviceIntPtr lastSlave;
-
-    /* master->last.valuators[0]/[1] is in screen coords and the actual
-     * position of the pointer */
-    pDev->last.valuators[0] = master->last.valuators[0];
-    pDev->last.valuators[1] = master->last.valuators[1];
-
-    if (!pDev->valuator)
-        return;
-
-    /* scale back to device coordinates */
-    if(pDev->valuator->numAxes > 0)
-        pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], pDev->last.remainder[0],
-                        &pDev->last.remainder[0], NULL, pDev->valuator->axes + 0, scr->width);
-    if(pDev->valuator->numAxes > 1)
-        pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], pDev->last.remainder[1],
-                        &pDev->last.remainder[1], NULL, pDev->valuator->axes + 1, scr->height);
-
-    /* calculate the other axis as well based on info from the old
-     * slave-device. If the old slave had less axes than this one,
-     * last.valuators is reset to 0.
-     */
-    if ((lastSlave = master->last.slave) && lastSlave->valuator) {
-        for (i = 2; i < pDev->valuator->numAxes; i++) {
-            if (i >= lastSlave->valuator->numAxes)
-                pDev->last.valuators[i] = 0;
-            else
-                pDev->last.valuators[i] =
-                    rescaleValuatorAxis(pDev->last.valuators[i],
-                            pDev->last.remainder[i],
-                            &pDev->last.remainder[i],
-                            lastSlave->valuator->axes + i,
-                            pDev->valuator->axes + i, 0);
-        }
-    }
-
-}
-
-/**
- * Allocate the motion history buffer.
- */
-void
-AllocateMotionHistory(DeviceIntPtr pDev)
-{
-    int size;
-    free(pDev->valuator->motion);
-
-    if (pDev->valuator->numMotionEvents < 1)
-        return;
-
-    /* An MD must have a motion history size large enough to keep all
-     * potential valuators, plus the respective range of the valuators.
-     * 3 * INT32 for (min_val, max_val, curr_val))
-     */
-    if (IsMaster(pDev))
-        size = sizeof(INT32) * 3 * MAX_VALUATORS;
-    else {
-        ValuatorClassPtr v = pDev->valuator;
-        int numAxes;
-        /* XI1 doesn't understand mixed mode devices */
-        for (numAxes = 0; numAxes < v->numAxes; numAxes++)
-            if (valuator_get_mode(pDev, numAxes) != valuator_get_mode(pDev, 0))
-                break;
-        size = sizeof(INT32) * numAxes;
-    }
-
-    size += sizeof(Time);
-
-    pDev->valuator->motion = calloc(pDev->valuator->numMotionEvents, size);
-    pDev->valuator->first_motion = 0;
-    pDev->valuator->last_motion = 0;
-    if (!pDev->valuator->motion)
-        ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n",
-                pDev->name, size * pDev->valuator->numMotionEvents);
-}
-
-/**
- * Dump the motion history between start and stop into the supplied buffer.
- * Only records the event for a given screen in theory, but in practice, we
- * sort of ignore this.
- *
- * If core is set, we only generate x/y, in INT16, scaled to screen coords.
- */
-int
-GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
-                 unsigned long stop, ScreenPtr pScreen, BOOL core)
-{
-    char *ibuff = NULL, *obuff;
-    int i = 0, ret = 0;
-    int j, coord;
-    Time current;
-    /* The size of a single motion event. */
-    int size;
-    int dflt;
-    AxisInfo from, *to; /* for scaling */
-    INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */
-    INT16 *corebuf;
-    AxisInfo core_axis = {0};
-
-    if (!pDev->valuator || !pDev->valuator->numMotionEvents)
-        return 0;
-
-    if (core && !pScreen)
-        return 0;
-
-    if (IsMaster(pDev))
-        size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time);
-    else
-        size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
-
-    *buff = malloc(size * pDev->valuator->numMotionEvents);
-    if (!(*buff))
-        return 0;
-    obuff = (char *)*buff;
-
-    for (i = pDev->valuator->first_motion;
-         i != pDev->valuator->last_motion;
-         i = (i + 1) % pDev->valuator->numMotionEvents) {
-        /* We index the input buffer by which element we're accessing, which
-         * is not monotonic, and the output buffer by how many events we've
-         * written so far. */
-        ibuff = (char *) pDev->valuator->motion + (i * size);
-        memcpy(&current, ibuff, sizeof(Time));
-
-        if (current > stop) {
-            return ret;
-        }
-        else if (current >= start) {
-            if (core)
-            {
-                memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
-
-                icbuf = (INT32*)(ibuff + sizeof(Time));
-                corebuf = (INT16*)(obuff + sizeof(Time));
-
-                /* fetch x coordinate + range */
-                memcpy(&from.min_value, icbuf++, sizeof(INT32));
-                memcpy(&from.max_value, icbuf++, sizeof(INT32));
-                memcpy(&coord, icbuf++, sizeof(INT32));
-
-                /* scale to screen coords */
-                to = &core_axis;
-                to->max_value = pScreen->width;
-                coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->width);
-
-                memcpy(corebuf, &coord, sizeof(INT16));
-                corebuf++;
-
-                /* fetch y coordinate + range */
-                memcpy(&from.min_value, icbuf++, sizeof(INT32));
-                memcpy(&from.max_value, icbuf++, sizeof(INT32));
-                memcpy(&coord, icbuf++, sizeof(INT32));
-
-                to->max_value = pScreen->height;
-                coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->height);
-                memcpy(corebuf, &coord, sizeof(INT16));
-
-            } else if (IsMaster(pDev))
-            {
-                memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
-
-                ocbuf = (INT32*)(obuff + sizeof(Time));
-                icbuf = (INT32*)(ibuff + sizeof(Time));
-                for (j = 0; j < MAX_VALUATORS; j++)
-                {
-                    if (j >= pDev->valuator->numAxes)
-                        break;
-
-                    /* fetch min/max/coordinate */
-                    memcpy(&from.min_value, icbuf++, sizeof(INT32));
-                    memcpy(&from.max_value, icbuf++, sizeof(INT32));
-                    memcpy(&coord, icbuf++, sizeof(INT32));
-
-                    to = (j < pDev->valuator->numAxes) ? &pDev->valuator->axes[j] : NULL;
-
-                    /* x/y scaled to screen if no range is present */
-                    if (j == 0 && (from.max_value < from.min_value))
-                        from.max_value = pScreen->width;
-                    else if (j == 1 && (from.max_value < from.min_value))
-                        from.max_value = pScreen->height;
-
-                    if (j == 0 && (to->max_value < to->min_value))
-                        dflt = pScreen->width;
-                    else if (j == 1 && (to->max_value < to->min_value))
-                        dflt = pScreen->height;
-                    else
-                        dflt = 0;
-
-                    /* scale from stored range into current range */
-                    coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0);
-                    memcpy(ocbuf, &coord, sizeof(INT32));
-                    ocbuf++;
-                }
-            } else
-                memcpy(obuff, ibuff, size);
-
-            /* don't advance by size here. size may be different to the
-             * actually written size if the MD has less valuators than MAX */
-            if (core)
-                obuff += sizeof(INT32) + sizeof(Time);
-            else
-                obuff += (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
-            ret++;
-        }
-    }
-
-    return ret;
-}
-
-
-/**
- * Update the motion history for a specific device, with the list of
- * valuators.
- *
- * Layout of the history buffer:
- *   for SDs: [time] [val0] [val1] ... [valn]
- *   for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
- *
- * For events that have some valuators unset:
- *      min_val == max_val == val == 0.
- */
-static void
-updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
-                    int *valuators)
-{
-    char *buff = (char *) pDev->valuator->motion;
-    ValuatorClassPtr v;
-    int i;
-
-    if (!pDev->valuator->numMotionEvents)
-        return;
-
-    v = pDev->valuator;
-    if (IsMaster(pDev))
-    {
-        buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) *
-                v->last_motion;
-
-        memcpy(buff, &ms, sizeof(Time));
-        buff += sizeof(Time);
-
-        memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS);
-
-        for (i = 0; i < v->numAxes; i++)
-        {
-            /* XI1 doesn't support mixed mode devices */
-            if (valuator_get_mode(pDev, i) != valuator_get_mode(pDev, 0))
-                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], sizeof(INT32));
-            buff += sizeof(INT32);
-        }
-    } else
-    {
-
-        buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
-            pDev->valuator->last_motion;
-
-        memcpy(buff, &ms, sizeof(Time));
-        buff += sizeof(Time);
-
-        memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes);
-
-        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) %
-        pDev->valuator->numMotionEvents;
-    /* If we're wrapping around, just keep the circular buffer going. */
-    if (pDev->valuator->first_motion == pDev->valuator->last_motion)
-        pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) %
-                                       pDev->valuator->numMotionEvents;
-
-    return;
-}
-
-
-/**
- * Returns the maximum number of events GetKeyboardEvents,
- * GetKeyboardValuatorEvents, and GetPointerEvents will ever return.
- *
- * This MUST be absolutely constant, from init until exit.
- */
-int
-GetMaximumEventsNum(void) {
-    /* One raw event
-     * One device event
-     * One possible device changed event
-     */
-    return 3;
-}
-
-
-/**
- * Clip an axis to its bounds, which are declared in the call to
- * InitValuatorAxisClassStruct.
- */
-static void
-clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
-{
-    AxisInfoPtr axis;
-
-    if (axisNum >= pDev->valuator->numAxes)
-        return;
-
-    axis = pDev->valuator->axes + axisNum;
-
-    /* If a value range is defined, clip. If not, do nothing */
-    if (axis->max_value <= axis->min_value)
-        return;
-
-    if (*val < axis->min_value)
-        *val = axis->min_value;
-    if (*val > axis->max_value)
-        *val = axis->max_value;
-}
-
-/**
- * Clip every axis in the list of valuators to its bounds.
- */
-static void
-clipValuators(DeviceIntPtr pDev, ValuatorMask *mask)
-{
-    int i;
-
-    for (i = 0; i < valuator_mask_size(mask); i++)
-        if (valuator_mask_isset(mask, i))
-        {
-            int val = valuator_mask_get(mask, i);
-            clipAxis(pDev, i, &val);
-            valuator_mask_set(mask, i, val);
-        }
-}
-
-/**
- * Create the DCCE event (does not update the master's device state yet, this
- * is done in the event processing).
- * Pull in the coordinates from the MD if necessary.
- *
- * @param events Pointer to a pre-allocated event list.
- * @param dev The slave device that generated an event.
- * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT
- * @param num_events The current number of events, returns the number of
- *        events if a DCCE was generated.
- * @return The updated @events pointer.
- */
-EventListPtr
-UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
-{
-    DeviceIntPtr master;
-
-    master = GetMaster(dev, (type & DEVCHANGE_POINTER_EVENT) ?  MASTER_POINTER : MASTER_KEYBOARD);
-
-    if (master && master->last.slave != dev)
-    {
-        CreateClassesChangedEvent(events, master, dev, type);
-        if (IsPointerDevice(master))
-        {
-            updateSlaveDeviceCoords(master, dev);
-            master->last.numValuators = dev->last.numValuators;
-        }
-        master->last.slave = dev;
-        (*num_events)++;
-        events++;
-    }
-    return events;
-}
-
-/**
- * Move the device's pointer to the position given in the valuators.
- *
- * @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 mask Bit mask of valid valuators.
- * @param valuators Valuator data for each axis between @first and
- *        @first+@num.
- */
-static void
-moveAbsolute(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
-{
-    int i;
-
-    if (valuator_mask_isset(mask, 0))
-        *x = valuator_mask_get(mask, 0);
-    else
-        *x = dev->last.valuators[0];
-
-    if (valuator_mask_isset(mask, 1))
-        *y = valuator_mask_get(mask, 1);
-    else
-        *y = dev->last.valuators[1];
-
-    clipAxis(dev, 0, x);
-    clipAxis(dev, 1, y);
-
-    for (i = 2; i < valuator_mask_size(mask); i++)
-    {
-        if (valuator_mask_isset(mask, i))
-        {
-            dev->last.valuators[i] = valuator_mask_get(mask, i);
-            clipAxis(dev, i, &dev->last.valuators[i]);
-        }
-    }
-}
-
-/**
- * Move the device's pointer by the values given in @valuators.
- *
- * @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 mask Bit mask of valid valuators.
- * @param valuators Valuator data for each axis between @first and
- *        @first+@num.
- */
-static void
-moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
-{
-    int i;
-
-    *x = dev->last.valuators[0];
-    *y = dev->last.valuators[1];
-
-    if (valuator_mask_isset(mask, 0))
-        *x += valuator_mask_get(mask, 0);
-
-    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
-     * limits to be able to change screens. */
-    if(dev->valuator && IsMaster(dev) || !IsFloating(dev)) {
-        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 */
-    for (i = 2; i < valuator_mask_size(mask); i++)
-    {
-        if (valuator_mask_isset(mask, i))
-        {
-            dev->last.valuators[i] += valuator_mask_get(mask, i);
-            if (valuator_get_mode(dev, i) == Absolute)
-                clipAxis(dev, i, &dev->last.valuators[i]);
-            valuator_mask_set(mask, i, dev->last.valuators[i]);
-        }
-    }
-}
-
-/**
- * Accelerate the data in valuators based on the device's acceleration scheme.
- *
- * @param dev The device which's pointer is to be moved.
- * @param first The first valuator in @valuators
- * @param num Total number of valuators in @valuators.
- * @param valuators Valuator data for each axis between @first and
- *        @first+@num.
- * @param ms Current time.
- */
-static void
-accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms)
-{
-    if (dev->valuator->accelScheme.AccelSchemeProc)
-        dev->valuator->accelScheme.AccelSchemeProc(dev, first, num, valuators, ms);
-}
-
-/**
- * If we have HW cursors, this actually moves the visible sprite. If not, we
- * just do all the screen crossing, etc.
- *
- * We scale from device to screen coordinates here, call
- * miPointerSetPosition() and then scale back into device coordinates (if
- * needed). miPSP will change x/y if the screen was crossed.
- *
- * @param dev The device to be moved.
- * @param x Pointer to current x-axis value, may be modified.
- * @param y Pointer to current y-axis value, may be modified.
- * @param x_frac Fractional part of current x-axis value, may be modified.
- * @param y_frac Fractional part of current y-axis value, may be modified.
- * @param scr Screen the device's sprite is currently on.
- * @param screenx Screen x coordinate the sprite is on after the update.
- * @param screeny Screen y coordinate the sprite is on after the update.
- * @param screenx_frac Fractional part of screen x coordinate, as above.
- * @param screeny_frac Fractional part of screen y coordinate, as above.
- */
-static void
-positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
-               ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac)
-{
-    int old_screenx, old_screeny;
-
-    /* scale x&y to screen */
-    if (dev->valuator && dev->valuator->numAxes > 0) {
-        *screenx = rescaleValuatorAxis(*x, x_frac, screenx_frac,
-                dev->valuator->axes + 0, NULL, scr->width);
-    } else {
-        *screenx = dev->last.valuators[0];
-        *screenx_frac = dev->last.remainder[0];
-    }
-
-    if (dev->valuator && dev->valuator->numAxes > 1) {
-        *screeny = rescaleValuatorAxis(*y, y_frac, screeny_frac,
-                dev->valuator->axes + 1, NULL, scr->height);
-    } else {
-        *screeny = dev->last.valuators[1];
-        *screeny_frac = dev->last.remainder[1];
-    }
-
-    /* Hit the left screen edge? */
-    if (*screenx <= 0 && *screenx_frac < 0.0f)
-    {
-        *screenx_frac = 0.0f;
-        x_frac = 0.0f;
-    }
-    if (*screeny <= 0 && *screeny_frac < 0.0f)
-    {
-        *screeny_frac = 0.0f;
-        y_frac = 0.0f;
-    }
-
-
-    old_screenx = *screenx;
-    old_screeny = *screeny;
-    /* This takes care of crossing screens for us, as well as clipping
-     * to the current screen. */
-    miPointerSetPosition(dev, screenx, screeny);
-
-    if(!IsMaster(dev) || !IsFloating(dev)) {
-        DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
-        master->last.valuators[0] = *screenx;
-        master->last.valuators[1] = *screeny;
-        master->last.remainder[0] = *screenx_frac;
-        master->last.remainder[1] = *screeny_frac;
-    }
-
-    if (dev->valuator)
-    {
-        /* Crossed screen? Scale back to device coordiantes */
-        if(*screenx != old_screenx)
-        {
-            scr = miPointerGetScreen(dev);
-            *x = rescaleValuatorAxis(*screenx, *screenx_frac, &x_frac, NULL,
-                                    dev->valuator->axes + 0, scr->width);
-        }
-        if(*screeny != old_screeny)
-        {
-            scr = miPointerGetScreen(dev);
-            *y = rescaleValuatorAxis(*screeny, *screeny_frac, &y_frac, NULL,
-                                     dev->valuator->axes + 1, scr->height);
-        }
-    }
-
-    /* dropy x/y (device coordinates) back into valuators for next event */
-    dev->last.valuators[0] = *x;
-    dev->last.valuators[1] = *y;
-    dev->last.remainder[0] = x_frac;
-    dev->last.remainder[1] = y_frac;
-}
-
-/**
- * Update the motion history for the device and (if appropriate) for its
- * master device.
- * @param dev Slave device to update.
- * @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, ValuatorMask *mask, CARD32 ms)
-{
-    if (!dev->valuator)
-        return;
-
-    updateMotionHistory(dev, ms, mask, dev->last.valuators);
-    if(!IsMaster(dev) || !IsFloating(dev))
-    {
-        DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
-        updateMotionHistory(master, ms, mask, dev->last.valuators);
-    }
-}
-
-/**
- * Convenience wrapper around GetKeyboardValuatorEvents, that takes no
- * valuators.
- */
-int
-GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) {
-    ValuatorMask mask;
-
-    valuator_mask_zero(&mask);
-    return GetKeyboardValuatorEvents(events, pDev, type, key_code, &mask);
-}
-
-
-/**
- * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally
- * also with valuator events.
- *
- * events is not NULL-terminated; the return value is the number of events.
- * The DDX is responsible for allocating the event structure in the first
- * place via GetMaximumEventsNum(), and for freeing it.
- */
-int
-GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
-                          int key_code, const ValuatorMask *mask_in) {
-    int num_events = 0;
-    CARD32 ms = 0;
-    DeviceEvent *event;
-    RawDeviceEvent *raw;
-    ValuatorMask mask;
-
-    /* refuse events from disabled devices */
-    if (!pDev->enabled)
-        return 0;
-
-    if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
-       (type != KeyPress && type != KeyRelease) ||
-       (key_code < 8 || key_code > 255))
-        return 0;
-
-    num_events = 1;
-
-    events = UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
-
-    /* Handle core repeating, via press/release/press/release. */
-    if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
-        /* If autorepeating is disabled either globally or just for that key,
-         * or we have a modifier, don't generate a repeat event. */
-        if (!pDev->kbdfeed->ctrl.autoRepeat ||
-            !key_autorepeats(pDev, key_code) ||
-            pDev->key->xkbInfo->desc->map->modmap[key_code])
-            return 0;
-    }
-
-    ms = GetTimeInMillis();
-
-    raw = (RawDeviceEvent*)events->event;
-    events++;
-    num_events++;
-
-    valuator_mask_copy(&mask, mask_in);
-
-    init_raw(pDev, raw, ms, type, key_code);
-    set_raw_valuators(raw, &mask, raw->valuators.data_raw);
-
-    clipValuators(pDev, &mask);
-
-    set_raw_valuators(raw, &mask, raw->valuators.data);
-
-    event = (DeviceEvent*) events->event;
-    init_event(pDev, event, ms);
-    event->detail.key = key_code;
-
-    if (type == KeyPress) {
-        event->type = ET_KeyPress;
-	set_key_down(pDev, key_code, KEY_POSTED);
-    }
-    else if (type == KeyRelease) {
-        event->type = ET_KeyRelease;
-	set_key_up(pDev, key_code, KEY_POSTED);
-    }
-
-    clipValuators(pDev, &mask);
-
-    set_valuators(pDev, event, &mask);
-
-    return num_events;
-}
-
-/**
- * Initialize an event list and fill with 32 byte sized events.
- * This event list is to be passed into GetPointerEvents() and
- * GetKeyboardEvents().
- *
- * @param num_events Number of elements in list.
- */
-EventListPtr
-InitEventList(int num_events)
-{
-    EventListPtr events;
-    int i;
-
-    events = (EventListPtr)calloc(num_events, sizeof(EventList));
-    if (!events)
-        return NULL;
-
-    for (i = 0; i < num_events; i++)
-    {
-        events[i].evlen = sizeof(InternalEvent);
-        events[i].event = calloc(1, sizeof(InternalEvent));
-        if (!events[i].event)
-        {
-            /* rollback */
-            while(i--)
-                free(events[i].event);
-            free(events);
-            events = NULL;
-            break;
-        }
-    }
-
-    return events;
-}
-
-/**
- * Free an event list.
- *
- * @param list The list to be freed.
- * @param num_events Number of elements in list.
- */
-void
-FreeEventList(EventListPtr list, int num_events)
-{
-    if (!list)
-        return;
-    while(num_events--)
-        free(list[num_events].event);
-    free(list);
-}
-
-static void
-transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
-{
-    struct pixman_f_vector p;
-
-    /* p' = M * p in homogeneous coordinates */
-    p.v[0] = (valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) :
-              dev->last.valuators[0]);
-    p.v[1] = (valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) :
-              dev->last.valuators[1]);
-    p.v[2] = 1.0;
-
-    pixman_f_transform_point(&dev->transform, &p);
-
-    if (lround(p.v[0]) != dev->last.valuators[0])
-        valuator_mask_set(mask, 0, lround(p.v[0]));
-    if (lround(p.v[1]) != dev->last.valuators[1])
-        valuator_mask_set(mask, 1, lround(p.v[1]));
-}
-
-/**
- * Generate a series of InternalEvents (filled into the EventList)
- * representing pointer motion, or button presses.
- *
- * events is not NULL-terminated; the return value is the number of events.
- * The DDX is responsible for allocating the event structure in the first
- * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
- *
- * In the generated events rootX/Y will be in absolute screen coords and
- * the valuator information in the absolute or relative device coords.
- *
- * last.valuators[x] of the device is always in absolute device coords.
- * last.valuators[x] of the master device is in absolute screen coords.
- *
- * master->last.valuators[x] for x > 2 is undefined.
- */
-int
-GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
-                 int flags, const ValuatorMask *mask_in) {
-    int num_events = 1;
-    CARD32 ms;
-    DeviceEvent *event;
-    RawDeviceEvent    *raw;
-    int x = 0, y = 0, /* device coords */
-        cx, cy; /* only screen coordinates */
-    float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac;
-    ScreenPtr scr = miPointerGetScreen(pDev);
-    ValuatorMask mask;
-
-    /* refuse events from disabled devices */
-    if (!pDev->enabled)
-        return 0;
-
-    if (!scr)
-        return 0;
-
-    switch (type)
-    {
-        case MotionNotify:
-            if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0)
-                return 0;
-            break;
-        case ButtonPress:
-        case ButtonRelease:
-            if (!pDev->button || !buttons)
-                return 0;
-            break;
-        default:
-            return 0;
-    }
-
-    ms = GetTimeInMillis(); /* before pointer update to help precision */
-
-    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
-
-    raw = (RawDeviceEvent*)events->event;
-    events++;
-    num_events++;
-
-    valuator_mask_copy(&mask, mask_in);
-
-    init_raw(pDev, raw, ms, type, buttons);
-    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))
-            {
-                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))
-            {
-                scaled = rescaleValuatorAxis(valuator_mask_get(&mask, 1),
-                                             0.0, &y_frac, NULL,
-                                             pDev->valuator->axes + 1,
-                                             scr->height);
-                valuator_mask_set(&mask, 1, scaled);
-            }
-        }
-
-        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) ?
-                      valuator_mask_get(&mask, 0) : 0;
-            vals[1] = valuator_mask_isset(&mask, 1) ?
-                      valuator_mask_get(&mask, 1) : 0;
-            accelPointer(pDev, 0, 2, vals, ms);
-
-            if (valuator_mask_isset(&mask, 0))
-                valuator_mask_set(&mask, 0, vals[0]);
-            if (valuator_mask_isset(&mask, 1))
-                valuator_mask_set(&mask, 1, vals[1]);
-
-            /* 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, &mask);
-    }
-
-    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))
-        valuator_mask_set(&mask, 0, x);
-    if (valuator_mask_isset(&mask, 1))
-        valuator_mask_set(&mask, 1, y);
-
-    clipValuators(pDev, &mask);
-
-    event = (DeviceEvent*) events->event;
-    init_event(pDev, event, ms);
-
-    if (type == MotionNotify) {
-        event->type = ET_Motion;
-        event->detail.button = 0;
-    }
-    else {
-        if (type == ButtonPress) {
-            event->type = ET_ButtonPress;
-            set_button_down(pDev, buttons, BUTTON_POSTED);
-        }
-        else if (type == ButtonRelease) {
-            event->type = ET_ButtonRelease;
-            set_button_up(pDev, buttons, BUTTON_POSTED);
-        }
-        event->detail.button = buttons;
-    }
-
-    event->root_x = cx; /* root_x/y always in screen coords */
-    event->root_y = cy;
-    event->root_x_frac = cx_frac;
-    event->root_y_frac = cy_frac;
-
-    set_valuators(pDev, event, &mask);
-
-    return num_events;
-}
-
-
-/**
- * Generate ProximityIn/ProximityOut InternalEvents, accompanied by
- * valuators.
- *
- * events is not NULL-terminated; the return value is the number of events.
- * The DDX is responsible for allocating the event structure in the first
- * place via GetMaximumEventsNum(), and for freeing it.
- */
-int
-GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in)
-{
-    int num_events = 1, i;
-    DeviceEvent *event;
-    ValuatorMask mask;
-
-    /* refuse events from disabled devices */
-    if (!pDev->enabled)
-        return 0;
-
-    /* Sanity checks. */
-    if ((type != ProximityIn && type != ProximityOut) || !mask_in)
-        return 0;
-    if (!pDev->valuator)
-        return 0;
-
-    valuator_mask_copy(&mask, mask_in);
-
-    /* ignore relative axes for proximity. */
-    for (i = 0; i < valuator_mask_size(&mask); i++)
-    {
-        if (valuator_mask_isset(&mask, i) &&
-            valuator_get_mode(pDev, i) == Relative)
-            valuator_mask_unset(&mask, i);
-    }
-
-    /* FIXME: posting proximity events with relative valuators only results
-     * in an empty event, EventToXI() will fail to convert → no event sent
-     * to client. */
-
-    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
-
-    event = (DeviceEvent *) events->event;
-    init_event(pDev, event, GetTimeInMillis());
-    event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
-
-    clipValuators(pDev, &mask);
-
-    set_valuators(pDev, event, &mask);
-
-    return num_events;
-}
-
-/**
- * Synthesize a single motion event for the core pointer.
- *
- * Used in cursor functions, e.g. when cursor confinement changes, and we need
- * to shift the pointer to get it inside the new bounds.
- */
-void
-PostSyntheticMotion(DeviceIntPtr pDev,
-                    int x,
-                    int y,
-                    int screen,
-                    unsigned long time)
-{
-    DeviceEvent ev;
-
-#ifdef PANORAMIX
-    /* Translate back to the sprite screen since processInputProc
-       will translate from sprite screen to screen 0 upon reentry
-       to the DIX layer. */
-    if (!noPanoramiXExtension) {
-        x += screenInfo.screens[0]->x - screenInfo.screens[screen]->x;
-        y += screenInfo.screens[0]->y - screenInfo.screens[screen]->y;
-    }
-#endif
-
-    memset(&ev, 0, sizeof(DeviceEvent));
-    init_event(pDev, &ev, time);
-    ev.root_x = x;
-    ev.root_y = y;
-    ev.type = ET_Motion;
-    ev.time = time;
-
-    /* FIXME: MD/SD considerations? */
-    (*pDev->public.processInputProc)((InternalEvent*)&ev, pDev);
-}
+/*
+ * Copyright © 2006 Nokia Corporation
+ * Copyright © 2006-2007 Daniel Stone
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Daniel Stone <daniel@fooishbar.org>
+ *          Peter Hutterer <peter.hutterer@who-t.net>
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/keysym.h>
+#include <X11/Xproto.h>
+#include <math.h>
+
+#include "misc.h"
+#include "resource.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "globals.h"
+#include "dixevents.h"
+#include "mipointer.h"
+#include "eventstr.h"
+#include "eventconvert.h"
+#include "inpututils.h"
+
+#include <X11/extensions/XKBproto.h>
+#include "xkbsrv.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include <pixman.h>
+#include "exglobals.h"
+#include "exevents.h"
+#include "exglobals.h"
+#include "extnsionst.h"
+#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */
+
+/* Number of motion history events to store. */
+#define MOTION_HISTORY_SIZE 256
+
+/* InputEventList is the container list for all input events generated by the
+ * DDX. The DDX is expected to call GetEventList() and then pass the list into
+ * Get{Pointer|Keyboard}Events.
+ */
+EventListPtr InputEventList = NULL;
+int InputEventListLen = 0;
+
+int
+GetEventList(EventListPtr* list)
+{
+    *list = InputEventList;
+    return InputEventListLen;
+}
+
+/**
+ * Pick some arbitrary size for Xi motion history.
+ */
+int
+GetMotionHistorySize(void)
+{
+    return MOTION_HISTORY_SIZE;
+}
+
+void
+set_button_down(DeviceIntPtr pDev, int button, int type)
+{
+    if (type == BUTTON_PROCESSED)
+        SetBit(pDev->button->down, button);
+    else
+        SetBit(pDev->button->postdown, button);
+}
+
+void
+set_button_up(DeviceIntPtr pDev, int button, int type)
+{
+    if (type == BUTTON_PROCESSED)
+        ClearBit(pDev->button->down, button);
+    else
+        ClearBit(pDev->button->postdown, button);
+}
+
+Bool
+button_is_down(DeviceIntPtr pDev, int button, int type)
+{
+    Bool ret = FALSE;
+
+    if (type & BUTTON_PROCESSED)
+        ret = ret || BitIsOn(pDev->button->down, button);
+    if (type & BUTTON_POSTED)
+        ret = ret || BitIsOn(pDev->button->postdown, button);
+
+    return ret;
+}
+
+void
+set_key_down(DeviceIntPtr pDev, int key_code, int type)
+{
+    if (type == KEY_PROCESSED)
+        SetBit(pDev->key->down, key_code);
+    else
+        SetBit(pDev->key->postdown, key_code);
+}
+
+void
+set_key_up(DeviceIntPtr pDev, int key_code, int type)
+{
+    if (type == KEY_PROCESSED)
+        ClearBit(pDev->key->down, key_code);
+    else
+        ClearBit(pDev->key->postdown, key_code);
+}
+
+Bool
+key_is_down(DeviceIntPtr pDev, int key_code, int type)
+{
+    Bool ret = FALSE;
+
+    if (type & KEY_PROCESSED)
+        ret = ret || BitIsOn(pDev->key->down, key_code);
+    if (type & KEY_POSTED)
+        ret = ret || BitIsOn(pDev->key->postdown, key_code);
+
+    return ret;
+}
+
+static Bool
+key_autorepeats(DeviceIntPtr pDev, int key_code)
+{
+    return !!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] &
+              (1 << (key_code & 7)));
+}
+
+static void
+init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms)
+{
+    memset(event, 0, sizeof(DeviceEvent));
+    event->header = ET_Internal;
+    event->length = sizeof(DeviceEvent);
+    event->time = ms;
+    event->deviceid = dev->id;
+    event->sourceid = dev->id;
+}
+
+static void
+init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
+{
+    memset(event, 0, sizeof(RawDeviceEvent));
+    event->header = ET_Internal;
+    event->length = sizeof(RawDeviceEvent);
+    event->type = ET_RawKeyPress - ET_KeyPress + type;
+    event->time = ms;
+    event->deviceid = dev->id;
+    event->sourceid = dev->id;
+    event->detail.button = detail;
+}
+
+static void
+set_raw_valuators(RawDeviceEvent *event, ValuatorMask *mask, int32_t* data)
+{
+    int i;
+
+    for (i = 0; i < valuator_mask_size(mask); i++)
+    {
+        if (valuator_mask_isset(mask, i))
+        {
+            SetBit(event->valuators.mask, i);
+            data[i] = valuator_mask_get(mask, i);
+        }
+    }
+}
+
+
+static void
+set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask)
+{
+    int i;
+
+    for (i = 0; i < valuator_mask_size(mask); i++)
+    {
+        if (valuator_mask_isset(mask, i))
+        {
+            SetBit(event->valuators.mask, i);
+            if (valuator_get_mode(dev, i) == Absolute)
+                SetBit(event->valuators.mode, i);
+            event->valuators.data[i] = valuator_mask_get(mask, i);
+            event->valuators.data_frac[i] =
+                dev->last.remainder[i] * (1 << 16) * (1 << 16);
+        }
+    }
+}
+
+void
+CreateClassesChangedEvent(EventList* event,
+                          DeviceIntPtr master,
+                          DeviceIntPtr slave,
+                          int type)
+{
+    int i;
+    DeviceChangedEvent *dce;
+    CARD32 ms = GetTimeInMillis();
+
+    dce = (DeviceChangedEvent*)event->event;
+    memset(dce, 0, sizeof(DeviceChangedEvent));
+    dce->deviceid = slave->id;
+    dce->masterid = master->id;
+    dce->header = ET_Internal;
+    dce->length = sizeof(DeviceChangedEvent);
+    dce->type = ET_DeviceChanged;
+    dce->time = ms;
+    dce->flags = type;
+    dce->flags |= DEVCHANGE_SLAVE_SWITCH;
+    dce->sourceid = slave->id;
+
+    if (slave->button)
+    {
+        dce->buttons.num_buttons = slave->button->numButtons;
+        for (i = 0; i < dce->buttons.num_buttons; i++)
+            dce->buttons.names[i] = slave->button->labels[i];
+    }
+    if (slave->valuator)
+    {
+        dce->num_valuators = slave->valuator->numAxes;
+        for (i = 0; i < dce->num_valuators; i++)
+        {
+            dce->valuators[i].min = slave->valuator->axes[i].min_value;
+            dce->valuators[i].max = slave->valuator->axes[i].max_value;
+            dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
+            dce->valuators[i].mode = slave->valuator->axes[i].mode;
+            dce->valuators[i].name = slave->valuator->axes[i].label;
+        }
+    }
+    if (slave->key)
+    {
+        dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code;
+        dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code;
+    }
+}
+
+/**
+ * Rescale the coord between the two axis ranges.
+ */
+static int
+rescaleValuatorAxis(int coord, float remainder, float *remainder_return, AxisInfoPtr from, AxisInfoPtr to,
+                    int defmax)
+{
+    int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax, coord_return;
+    float value;
+
+    if(from && from->min_value < from->max_value) {
+        fmin = from->min_value;
+        fmax = from->max_value;
+    }
+    if(to && to->min_value < to->max_value) {
+        tmin = to->min_value;
+        tmax = to->max_value;
+    }
+
+    if(fmin == tmin && fmax == tmax) {
+        if (remainder_return)
+            *remainder_return = remainder;
+        return coord;
+    }
+
+    if(fmax == fmin) { /* avoid division by 0 */
+        if (remainder_return)
+            *remainder_return = 0.0;
+        return 0;
+    }
+
+    value = (coord + remainder - fmin) * (tmax - tmin) / (fmax - fmin) + tmin;
+    coord_return = lroundf(value);
+    if (remainder_return)
+        *remainder_return = value - coord_return;
+    return coord_return;
+}
+
+/**
+ * Update all coordinates when changing to a different SD
+ * to ensure that relative reporting will work as expected
+ * without loss of precision.
+ *
+ * pDev->last.valuators will be in absolute device coordinates after this
+ * function.
+ */
+static void
+updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
+{
+    ScreenPtr scr = miPointerGetScreen(pDev);
+    int i;
+    DeviceIntPtr lastSlave;
+
+    /* master->last.valuators[0]/[1] is in screen coords and the actual
+     * position of the pointer */
+    pDev->last.valuators[0] = master->last.valuators[0];
+    pDev->last.valuators[1] = master->last.valuators[1];
+
+    if (!pDev->valuator)
+        return;
+
+    /* scale back to device coordinates */
+    if(pDev->valuator->numAxes > 0)
+        pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], pDev->last.remainder[0],
+                        &pDev->last.remainder[0], NULL, pDev->valuator->axes + 0, scr->width);
+    if(pDev->valuator->numAxes > 1)
+        pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], pDev->last.remainder[1],
+                        &pDev->last.remainder[1], NULL, pDev->valuator->axes + 1, scr->height);
+
+    /* calculate the other axis as well based on info from the old
+     * slave-device. If the old slave had less axes than this one,
+     * last.valuators is reset to 0.
+     */
+    if ((lastSlave = master->last.slave) && lastSlave->valuator) {
+        for (i = 2; i < pDev->valuator->numAxes; i++) {
+            if (i >= lastSlave->valuator->numAxes)
+                pDev->last.valuators[i] = 0;
+            else
+                pDev->last.valuators[i] =
+                    rescaleValuatorAxis(pDev->last.valuators[i],
+                            pDev->last.remainder[i],
+                            &pDev->last.remainder[i],
+                            lastSlave->valuator->axes + i,
+                            pDev->valuator->axes + i, 0);
+        }
+    }
+
+}
+
+/**
+ * Allocate the motion history buffer.
+ */
+void
+AllocateMotionHistory(DeviceIntPtr pDev)
+{
+    int size;
+    free(pDev->valuator->motion);
+
+    if (pDev->valuator->numMotionEvents < 1)
+        return;
+
+    /* An MD must have a motion history size large enough to keep all
+     * potential valuators, plus the respective range of the valuators.
+     * 3 * INT32 for (min_val, max_val, curr_val))
+     */
+    if (IsMaster(pDev))
+        size = sizeof(INT32) * 3 * MAX_VALUATORS;
+    else {
+        ValuatorClassPtr v = pDev->valuator;
+        int numAxes;
+        /* XI1 doesn't understand mixed mode devices */
+        for (numAxes = 0; numAxes < v->numAxes; numAxes++)
+            if (valuator_get_mode(pDev, numAxes) != valuator_get_mode(pDev, 0))
+                break;
+        size = sizeof(INT32) * numAxes;
+    }
+
+    size += sizeof(Time);
+
+    pDev->valuator->motion = calloc(pDev->valuator->numMotionEvents, size);
+    pDev->valuator->first_motion = 0;
+    pDev->valuator->last_motion = 0;
+    if (!pDev->valuator->motion)
+        ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n",
+                pDev->name, size * pDev->valuator->numMotionEvents);
+}
+
+/**
+ * Dump the motion history between start and stop into the supplied buffer.
+ * Only records the event for a given screen in theory, but in practice, we
+ * sort of ignore this.
+ *
+ * If core is set, we only generate x/y, in INT16, scaled to screen coords.
+ */
+int
+GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
+                 unsigned long stop, ScreenPtr pScreen, BOOL core)
+{
+    char *ibuff = NULL, *obuff;
+    int i = 0, ret = 0;
+    int j, coord;
+    Time current;
+    /* The size of a single motion event. */
+    int size;
+    int dflt;
+    AxisInfo from, *to; /* for scaling */
+    INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */
+    INT16 *corebuf;
+    AxisInfo core_axis = {0};
+
+    if (!pDev->valuator || !pDev->valuator->numMotionEvents)
+        return 0;
+
+    if (core && !pScreen)
+        return 0;
+
+    if (IsMaster(pDev))
+        size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time);
+    else
+        size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
+
+    *buff = malloc(size * pDev->valuator->numMotionEvents);
+    if (!(*buff))
+        return 0;
+    obuff = (char *)*buff;
+
+    for (i = pDev->valuator->first_motion;
+         i != pDev->valuator->last_motion;
+         i = (i + 1) % pDev->valuator->numMotionEvents) {
+        /* We index the input buffer by which element we're accessing, which
+         * is not monotonic, and the output buffer by how many events we've
+         * written so far. */
+        ibuff = (char *) pDev->valuator->motion + (i * size);
+        memcpy(&current, ibuff, sizeof(Time));
+
+        if (current > stop) {
+            return ret;
+        }
+        else if (current >= start) {
+            if (core)
+            {
+                memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
+
+                icbuf = (INT32*)(ibuff + sizeof(Time));
+                corebuf = (INT16*)(obuff + sizeof(Time));
+
+                /* fetch x coordinate + range */
+                memcpy(&from.min_value, icbuf++, sizeof(INT32));
+                memcpy(&from.max_value, icbuf++, sizeof(INT32));
+                memcpy(&coord, icbuf++, sizeof(INT32));
+
+                /* scale to screen coords */
+                to = &core_axis;
+                to->max_value = pScreen->width;
+                coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->width);
+
+                memcpy(corebuf, &coord, sizeof(INT16));
+                corebuf++;
+
+                /* fetch y coordinate + range */
+                memcpy(&from.min_value, icbuf++, sizeof(INT32));
+                memcpy(&from.max_value, icbuf++, sizeof(INT32));
+                memcpy(&coord, icbuf++, sizeof(INT32));
+
+                to->max_value = pScreen->height;
+                coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->height);
+                memcpy(corebuf, &coord, sizeof(INT16));
+
+            } else if (IsMaster(pDev))
+            {
+                memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
+
+                ocbuf = (INT32*)(obuff + sizeof(Time));
+                icbuf = (INT32*)(ibuff + sizeof(Time));
+                for (j = 0; j < MAX_VALUATORS; j++)
+                {
+                    if (j >= pDev->valuator->numAxes)
+                        break;
+
+                    /* fetch min/max/coordinate */
+                    memcpy(&from.min_value, icbuf++, sizeof(INT32));
+                    memcpy(&from.max_value, icbuf++, sizeof(INT32));
+                    memcpy(&coord, icbuf++, sizeof(INT32));
+
+                    to = (j < pDev->valuator->numAxes) ? &pDev->valuator->axes[j] : NULL;
+
+                    /* x/y scaled to screen if no range is present */
+                    if (j == 0 && (from.max_value < from.min_value))
+                        from.max_value = pScreen->width;
+                    else if (j == 1 && (from.max_value < from.min_value))
+                        from.max_value = pScreen->height;
+
+                    if (j == 0 && (to->max_value < to->min_value))
+                        dflt = pScreen->width;
+                    else if (j == 1 && (to->max_value < to->min_value))
+                        dflt = pScreen->height;
+                    else
+                        dflt = 0;
+
+                    /* scale from stored range into current range */
+                    coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0);
+                    memcpy(ocbuf, &coord, sizeof(INT32));
+                    ocbuf++;
+                }
+            } else
+                memcpy(obuff, ibuff, size);
+
+            /* don't advance by size here. size may be different to the
+             * actually written size if the MD has less valuators than MAX */
+            if (core)
+                obuff += sizeof(INT32) + sizeof(Time);
+            else
+                obuff += (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
+            ret++;
+        }
+    }
+
+    return ret;
+}
+
+
+/**
+ * Update the motion history for a specific device, with the list of
+ * valuators.
+ *
+ * Layout of the history buffer:
+ *   for SDs: [time] [val0] [val1] ... [valn]
+ *   for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
+ *
+ * For events that have some valuators unset:
+ *      min_val == max_val == val == 0.
+ */
+static void
+updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, ValuatorMask *mask,
+                    int *valuators)
+{
+    char *buff = (char *) pDev->valuator->motion;
+    ValuatorClassPtr v;
+    int i;
+
+    if (!pDev->valuator->numMotionEvents)
+        return;
+
+    v = pDev->valuator;
+    if (IsMaster(pDev))
+    {
+        buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) *
+                v->last_motion;
+
+        memcpy(buff, &ms, sizeof(Time));
+        buff += sizeof(Time);
+
+        memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS);
+
+        for (i = 0; i < v->numAxes; i++)
+        {
+            /* XI1 doesn't support mixed mode devices */
+            if (valuator_get_mode(pDev, i) != valuator_get_mode(pDev, 0))
+                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], sizeof(INT32));
+            buff += sizeof(INT32);
+        }
+    } else
+    {
+
+        buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
+            pDev->valuator->last_motion;
+
+        memcpy(buff, &ms, sizeof(Time));
+        buff += sizeof(Time);
+
+        memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes);
+
+        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) %
+        pDev->valuator->numMotionEvents;
+    /* If we're wrapping around, just keep the circular buffer going. */
+    if (pDev->valuator->first_motion == pDev->valuator->last_motion)
+        pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) %
+                                       pDev->valuator->numMotionEvents;
+
+    return;
+}
+
+
+/**
+ * Returns the maximum number of events GetKeyboardEvents,
+ * GetKeyboardValuatorEvents, and GetPointerEvents will ever return.
+ *
+ * This MUST be absolutely constant, from init until exit.
+ */
+int
+GetMaximumEventsNum(void) {
+    /* One raw event
+     * One device event
+     * One possible device changed event
+     */
+    return 3;
+}
+
+
+/**
+ * Clip an axis to its bounds, which are declared in the call to
+ * InitValuatorAxisClassStruct.
+ */
+static void
+clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
+{
+    AxisInfoPtr axis;
+
+    if (axisNum >= pDev->valuator->numAxes)
+        return;
+
+    axis = pDev->valuator->axes + axisNum;
+
+    /* If a value range is defined, clip. If not, do nothing */
+    if (axis->max_value <= axis->min_value)
+        return;
+
+    if (*val < axis->min_value)
+        *val = axis->min_value;
+    if (*val > axis->max_value)
+        *val = axis->max_value;
+}
+
+/**
+ * Clip every axis in the list of valuators to its bounds.
+ */
+static void
+clipValuators(DeviceIntPtr pDev, ValuatorMask *mask)
+{
+    int i;
+
+    for (i = 0; i < valuator_mask_size(mask); i++)
+        if (valuator_mask_isset(mask, i))
+        {
+            int val = valuator_mask_get(mask, i);
+            clipAxis(pDev, i, &val);
+            valuator_mask_set(mask, i, val);
+        }
+}
+
+/**
+ * Create the DCCE event (does not update the master's device state yet, this
+ * is done in the event processing).
+ * Pull in the coordinates from the MD if necessary.
+ *
+ * @param events Pointer to a pre-allocated event list.
+ * @param dev The slave device that generated an event.
+ * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT
+ * @param num_events The current number of events, returns the number of
+ *        events if a DCCE was generated.
+ * @return The updated @events pointer.
+ */
+EventListPtr
+UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
+{
+    DeviceIntPtr master;
+
+    master = GetMaster(dev, (type & DEVCHANGE_POINTER_EVENT) ?  MASTER_POINTER : MASTER_KEYBOARD);
+
+    if (master && master->last.slave != dev)
+    {
+        CreateClassesChangedEvent(events, master, dev, type);
+        if (IsPointerDevice(master))
+        {
+            updateSlaveDeviceCoords(master, dev);
+            master->last.numValuators = dev->last.numValuators;
+        }
+        master->last.slave = dev;
+        (*num_events)++;
+        events++;
+    }
+    return events;
+}
+
+/**
+ * Move the device's pointer to the position given in the valuators.
+ *
+ * @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 mask Bit mask of valid valuators.
+ * @param valuators Valuator data for each axis between @first and
+ *        @first+@num.
+ */
+static void
+moveAbsolute(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
+{
+    int i;
+
+    if (valuator_mask_isset(mask, 0))
+        *x = valuator_mask_get(mask, 0);
+    else
+        *x = dev->last.valuators[0];
+
+    if (valuator_mask_isset(mask, 1))
+        *y = valuator_mask_get(mask, 1);
+    else
+        *y = dev->last.valuators[1];
+
+    clipAxis(dev, 0, x);
+    clipAxis(dev, 1, y);
+
+    for (i = 2; i < valuator_mask_size(mask); i++)
+    {
+        if (valuator_mask_isset(mask, i))
+        {
+            dev->last.valuators[i] = valuator_mask_get(mask, i);
+            clipAxis(dev, i, &dev->last.valuators[i]);
+        }
+    }
+}
+
+/**
+ * Move the device's pointer by the values given in @valuators.
+ *
+ * @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 mask Bit mask of valid valuators.
+ * @param valuators Valuator data for each axis between @first and
+ *        @first+@num.
+ */
+static void
+moveRelative(DeviceIntPtr dev, int *x, int *y, ValuatorMask *mask)
+{
+    int i;
+
+    *x = dev->last.valuators[0];
+    *y = dev->last.valuators[1];
+
+    if (valuator_mask_isset(mask, 0))
+        *x += valuator_mask_get(mask, 0);
+
+    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
+     * limits to be able to change screens. */
+    if (dev->valuator && (IsMaster(dev) || !IsFloating(dev))) {
+        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 */
+    for (i = 2; i < valuator_mask_size(mask); i++)
+    {
+        if (valuator_mask_isset(mask, i))
+        {
+            dev->last.valuators[i] += valuator_mask_get(mask, i);
+            if (valuator_get_mode(dev, i) == Absolute)
+                clipAxis(dev, i, &dev->last.valuators[i]);
+            valuator_mask_set(mask, i, dev->last.valuators[i]);
+        }
+    }
+}
+
+/**
+ * Accelerate the data in valuators based on the device's acceleration scheme.
+ *
+ * @param dev The device which's pointer is to be moved.
+ * @param valuators Valuator mask
+ * @param ms Current time.
+ */
+static void
+accelPointer(DeviceIntPtr dev, ValuatorMask* valuators, CARD32 ms)
+{
+    if (dev->valuator->accelScheme.AccelSchemeProc)
+        dev->valuator->accelScheme.AccelSchemeProc(dev, valuators, ms);
+}
+
+/**
+ * If we have HW cursors, this actually moves the visible sprite. If not, we
+ * just do all the screen crossing, etc.
+ *
+ * We scale from device to screen coordinates here, call
+ * miPointerSetPosition() and then scale back into device coordinates (if
+ * needed). miPSP will change x/y if the screen was crossed.
+ *
+ * The coordinates provided are always absolute. The parameter mode whether
+ * it was relative or absolute movement that landed us at those coordinates.
+ *
+ * @param dev The device to be moved.
+ * @param mode Movement mode (Absolute or Relative)
+ * @param x Pointer to current x-axis value, may be modified.
+ * @param y Pointer to current y-axis value, may be modified.
+ * @param x_frac Fractional part of current x-axis value, may be modified.
+ * @param y_frac Fractional part of current y-axis value, may be modified.
+ * @param scr Screen the device's sprite is currently on.
+ * @param screenx Screen x coordinate the sprite is on after the update.
+ * @param screeny Screen y coordinate the sprite is on after the update.
+ * @param screenx_frac Fractional part of screen x coordinate, as above.
+ * @param screeny_frac Fractional part of screen y coordinate, as above.
+ */
+static void
+positionSprite(DeviceIntPtr dev, int mode,
+               int *x, int *y, float x_frac, float y_frac,
+               ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac)
+{
+    int old_screenx, old_screeny;
+
+    /* scale x&y to screen */
+    if (dev->valuator && dev->valuator->numAxes > 0) {
+        *screenx = rescaleValuatorAxis(*x, x_frac, screenx_frac,
+                dev->valuator->axes + 0, NULL, scr->width);
+    } else {
+        *screenx = dev->last.valuators[0];
+        *screenx_frac = dev->last.remainder[0];
+    }
+
+    if (dev->valuator && dev->valuator->numAxes > 1) {
+        *screeny = rescaleValuatorAxis(*y, y_frac, screeny_frac,
+                dev->valuator->axes + 1, NULL, scr->height);
+    } else {
+        *screeny = dev->last.valuators[1];
+        *screeny_frac = dev->last.remainder[1];
+    }
+
+    /* Hit the left screen edge? */
+    if (*screenx <= 0 && *screenx_frac < 0.0f)
+    {
+        *screenx_frac = 0.0f;
+        x_frac = 0.0f;
+    }
+    if (*screeny <= 0 && *screeny_frac < 0.0f)
+    {
+        *screeny_frac = 0.0f;
+        y_frac = 0.0f;
+    }
+
+
+    old_screenx = *screenx;
+    old_screeny = *screeny;
+    /* This takes care of crossing screens for us, as well as clipping
+     * to the current screen. */
+    miPointerSetPosition(dev, mode, screenx, screeny);
+
+    if(!IsMaster(dev) || !IsFloating(dev)) {
+        DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
+        master->last.valuators[0] = *screenx;
+        master->last.valuators[1] = *screeny;
+        master->last.remainder[0] = *screenx_frac;
+        master->last.remainder[1] = *screeny_frac;
+    }
+
+    if (dev->valuator)
+    {
+        /* Crossed screen? Scale back to device coordiantes */
+        if(*screenx != old_screenx)
+        {
+            scr = miPointerGetScreen(dev);
+            *x = rescaleValuatorAxis(*screenx, *screenx_frac, &x_frac, NULL,
+                                    dev->valuator->axes + 0, scr->width);
+        }
+        if(*screeny != old_screeny)
+        {
+            scr = miPointerGetScreen(dev);
+            *y = rescaleValuatorAxis(*screeny, *screeny_frac, &y_frac, NULL,
+                                     dev->valuator->axes + 1, scr->height);
+        }
+    }
+
+    /* dropy x/y (device coordinates) back into valuators for next event */
+    dev->last.valuators[0] = *x;
+    dev->last.valuators[1] = *y;
+    dev->last.remainder[0] = x_frac;
+    dev->last.remainder[1] = y_frac;
+}
+
+/**
+ * Update the motion history for the device and (if appropriate) for its
+ * master device.
+ * @param dev Slave device to update.
+ * @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, ValuatorMask *mask, CARD32 ms)
+{
+    if (!dev->valuator)
+        return;
+
+    updateMotionHistory(dev, ms, mask, dev->last.valuators);
+    if(!IsMaster(dev) || !IsFloating(dev))
+    {
+        DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
+        updateMotionHistory(master, ms, mask, dev->last.valuators);
+    }
+}
+
+/**
+ * Convenience wrapper around GetKeyboardValuatorEvents, that takes no
+ * valuators.
+ */
+int
+GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) {
+    ValuatorMask mask;
+
+    valuator_mask_zero(&mask);
+    return GetKeyboardValuatorEvents(events, pDev, type, key_code, &mask);
+}
+
+
+/**
+ * Returns a set of InternalEvents for KeyPress/KeyRelease, optionally
+ * also with valuator events.
+ *
+ * events is not NULL-terminated; the return value is the number of events.
+ * The DDX is responsible for allocating the event structure in the first
+ * place via GetMaximumEventsNum(), and for freeing it.
+ */
+int
+GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
+                          int key_code, const ValuatorMask *mask_in) {
+    int num_events = 0;
+    CARD32 ms = 0;
+    DeviceEvent *event;
+    RawDeviceEvent *raw;
+    ValuatorMask mask;
+
+    /* refuse events from disabled devices */
+    if (!pDev->enabled)
+        return 0;
+
+    if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
+       (type != KeyPress && type != KeyRelease) ||
+       (key_code < 8 || key_code > 255))
+        return 0;
+
+    num_events = 1;
+
+    events = UpdateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
+
+    /* Handle core repeating, via press/release/press/release. */
+    if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
+        /* If autorepeating is disabled either globally or just for that key,
+         * or we have a modifier, don't generate a repeat event. */
+        if (!pDev->kbdfeed->ctrl.autoRepeat ||
+            !key_autorepeats(pDev, key_code) ||
+            pDev->key->xkbInfo->desc->map->modmap[key_code])
+            return 0;
+    }
+
+    ms = GetTimeInMillis();
+
+    raw = (RawDeviceEvent*)events->event;
+    events++;
+    num_events++;
+
+    valuator_mask_copy(&mask, mask_in);
+
+    init_raw(pDev, raw, ms, type, key_code);
+    set_raw_valuators(raw, &mask, raw->valuators.data_raw);
+
+    clipValuators(pDev, &mask);
+
+    set_raw_valuators(raw, &mask, raw->valuators.data);
+
+    event = (DeviceEvent*) events->event;
+    init_event(pDev, event, ms);
+    event->detail.key = key_code;
+
+    if (type == KeyPress) {
+        event->type = ET_KeyPress;
+	set_key_down(pDev, key_code, KEY_POSTED);
+    }
+    else if (type == KeyRelease) {
+        event->type = ET_KeyRelease;
+	set_key_up(pDev, key_code, KEY_POSTED);
+    }
+
+    clipValuators(pDev, &mask);
+
+    set_valuators(pDev, event, &mask);
+
+    return num_events;
+}
+
+/**
+ * Initialize an event list and fill with 32 byte sized events.
+ * This event list is to be passed into GetPointerEvents() and
+ * GetKeyboardEvents().
+ *
+ * @param num_events Number of elements in list.
+ */
+EventListPtr
+InitEventList(int num_events)
+{
+    EventListPtr events;
+    int i;
+
+    events = (EventListPtr)calloc(num_events, sizeof(EventList));
+    if (!events)
+        return NULL;
+
+    for (i = 0; i < num_events; i++)
+    {
+        events[i].evlen = sizeof(InternalEvent);
+        events[i].event = calloc(1, sizeof(InternalEvent));
+        if (!events[i].event)
+        {
+            /* rollback */
+            while(i--)
+                free(events[i].event);
+            free(events);
+            events = NULL;
+            break;
+        }
+    }
+
+    return events;
+}
+
+/**
+ * Free an event list.
+ *
+ * @param list The list to be freed.
+ * @param num_events Number of elements in list.
+ */
+void
+FreeEventList(EventListPtr list, int num_events)
+{
+    if (!list)
+        return;
+    while(num_events--)
+        free(list[num_events].event);
+    free(list);
+}
+
+static void
+transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
+{
+    struct pixman_f_vector p;
+
+    /* p' = M * p in homogeneous coordinates */
+    p.v[0] = (valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) :
+              dev->last.valuators[0]);
+    p.v[1] = (valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) :
+              dev->last.valuators[1]);
+    p.v[2] = 1.0;
+
+    pixman_f_transform_point(&dev->transform, &p);
+
+    if (lround(p.v[0]) != dev->last.valuators[0])
+        valuator_mask_set(mask, 0, lround(p.v[0]));
+    if (lround(p.v[1]) != dev->last.valuators[1])
+        valuator_mask_set(mask, 1, lround(p.v[1]));
+}
+
+/**
+ * Generate a series of InternalEvents (filled into the EventList)
+ * representing pointer motion, or button presses.
+ *
+ * events is not NULL-terminated; the return value is the number of events.
+ * The DDX is responsible for allocating the event structure in the first
+ * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
+ *
+ * In the generated events rootX/Y will be in absolute screen coords and
+ * the valuator information in the absolute or relative device coords.
+ *
+ * last.valuators[x] of the device is always in absolute device coords.
+ * last.valuators[x] of the master device is in absolute screen coords.
+ *
+ * master->last.valuators[x] for x > 2 is undefined.
+ */
+int
+GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
+                 int flags, const ValuatorMask *mask_in) {
+    int num_events = 1;
+    CARD32 ms;
+    DeviceEvent *event;
+    RawDeviceEvent    *raw;
+    int x = 0, y = 0, /* device coords */
+        cx, cy; /* only screen coordinates */
+    float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac;
+    ScreenPtr scr = miPointerGetScreen(pDev);
+    ValuatorMask mask;
+
+    /* refuse events from disabled devices */
+    if (!pDev->enabled)
+        return 0;
+
+    if (!scr)
+        return 0;
+
+    switch (type)
+    {
+        case MotionNotify:
+            if (!mask_in || valuator_mask_num_valuators(mask_in) <= 0)
+                return 0;
+            break;
+        case ButtonPress:
+        case ButtonRelease:
+            if (!pDev->button || !buttons)
+                return 0;
+            break;
+        default:
+            return 0;
+    }
+
+    ms = GetTimeInMillis(); /* before pointer update to help precision */
+
+    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
+
+    raw = (RawDeviceEvent*)events->event;
+    events++;
+    num_events++;
+
+    valuator_mask_copy(&mask, mask_in);
+
+    init_raw(pDev, raw, ms, type, buttons);
+    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))
+            {
+                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))
+            {
+                scaled = rescaleValuatorAxis(valuator_mask_get(&mask, 1),
+                                             0.0, &y_frac, NULL,
+                                             pDev->valuator->axes + 1,
+                                             scr->height);
+                valuator_mask_set(&mask, 1, scaled);
+            }
+        }
+
+        transformAbsolute(pDev, &mask);
+        moveAbsolute(pDev, &x, &y, &mask);
+    } else {
+        if (flags & POINTER_ACCELERATE) {
+            accelPointer(pDev, &mask, 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, &mask);
+    }
+
+    set_raw_valuators(raw, &mask, raw->valuators.data);
+
+    positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
+                   &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))
+        valuator_mask_set(&mask, 0, x);
+    if (valuator_mask_isset(&mask, 1))
+        valuator_mask_set(&mask, 1, y);
+
+    clipValuators(pDev, &mask);
+
+    event = (DeviceEvent*) events->event;
+    init_event(pDev, event, ms);
+
+    if (type == MotionNotify) {
+        event->type = ET_Motion;
+        event->detail.button = 0;
+    }
+    else {
+        if (type == ButtonPress) {
+            event->type = ET_ButtonPress;
+            set_button_down(pDev, buttons, BUTTON_POSTED);
+        }
+        else if (type == ButtonRelease) {
+            event->type = ET_ButtonRelease;
+            set_button_up(pDev, buttons, BUTTON_POSTED);
+        }
+        event->detail.button = buttons;
+    }
+
+    event->root_x = cx; /* root_x/y always in screen coords */
+    event->root_y = cy;
+    event->root_x_frac = cx_frac;
+    event->root_y_frac = cy_frac;
+
+    set_valuators(pDev, event, &mask);
+
+    return num_events;
+}
+
+
+/**
+ * Generate ProximityIn/ProximityOut InternalEvents, accompanied by
+ * valuators.
+ *
+ * events is not NULL-terminated; the return value is the number of events.
+ * The DDX is responsible for allocating the event structure in the first
+ * place via GetMaximumEventsNum(), and for freeing it.
+ */
+int
+GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in)
+{
+    int num_events = 1, i;
+    DeviceEvent *event;
+    ValuatorMask mask;
+
+    /* refuse events from disabled devices */
+    if (!pDev->enabled)
+        return 0;
+
+    /* Sanity checks. */
+    if ((type != ProximityIn && type != ProximityOut) || !mask_in)
+        return 0;
+    if (!pDev->valuator)
+        return 0;
+
+    valuator_mask_copy(&mask, mask_in);
+
+    /* ignore relative axes for proximity. */
+    for (i = 0; i < valuator_mask_size(&mask); i++)
+    {
+        if (valuator_mask_isset(&mask, i) &&
+            valuator_get_mode(pDev, i) == Relative)
+            valuator_mask_unset(&mask, i);
+    }
+
+    /* FIXME: posting proximity events with relative valuators only results
+     * in an empty event, EventToXI() will fail to convert → no event sent
+     * to client. */
+
+    events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
+
+    event = (DeviceEvent *) events->event;
+    init_event(pDev, event, GetTimeInMillis());
+    event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
+
+    clipValuators(pDev, &mask);
+
+    set_valuators(pDev, event, &mask);
+
+    return num_events;
+}
+
+/**
+ * Synthesize a single motion event for the core pointer.
+ *
+ * Used in cursor functions, e.g. when cursor confinement changes, and we need
+ * to shift the pointer to get it inside the new bounds.
+ */
+void
+PostSyntheticMotion(DeviceIntPtr pDev,
+                    int x,
+                    int y,
+                    int screen,
+                    unsigned long time)
+{
+    DeviceEvent ev;
+
+#ifdef PANORAMIX
+    /* Translate back to the sprite screen since processInputProc
+       will translate from sprite screen to screen 0 upon reentry
+       to the DIX layer. */
+    if (!noPanoramiXExtension) {
+        x += screenInfo.screens[0]->x - screenInfo.screens[screen]->x;
+        y += screenInfo.screens[0]->y - screenInfo.screens[screen]->y;
+    }
+#endif
+
+    memset(&ev, 0, sizeof(DeviceEvent));
+    init_event(pDev, &ev, time);
+    ev.root_x = x;
+    ev.root_y = y;
+    ev.type = ET_Motion;
+    ev.time = time;
+
+    /* FIXME: MD/SD considerations? */
+    (*pDev->public.processInputProc)((InternalEvent*)&ev, pDev);
+}
diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c
index e6ac2ed14..e95d804c2 100644
--- a/xorg-server/dix/ptrveloc.c
+++ b/xorg-server/dix/ptrveloc.c
@@ -1,1197 +1,1216 @@
-/*
- *
- * Copyright © 2006-2009 Simon Thum             simon dot thum at gmx dot de
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <math.h>
-#include <ptrveloc.h>
-#include <exevents.h>
-#include <X11/Xatom.h>
-
-#include <xserver-properties.h>
-
-/*****************************************************************************
- * Predictable pointer acceleration
- *
- * 2006-2009 by Simon Thum (simon [dot] thum [at] gmx de)
- *
- * Serves 3 complementary functions:
- * 1) provide a sophisticated ballistic velocity estimate to improve
- *    the relation between velocity (of the device) and acceleration
- * 2) make arbitrary acceleration profiles possible
- * 3) decelerate by two means (constant and adaptive) if enabled
- *
- * Important concepts are the
- *
- * - Scheme
- *      which selects the basic algorithm
- *      (see devices.c/InitPointerAccelerationScheme)
- * - Profile
- *      which returns an acceleration
- *      for a given velocity
- *
- *  The profile can be selected by the user at runtime.
- *  The classic profile is intended to cleanly perform old-style
- *  function selection (threshold =/!= 0)
- *
- ****************************************************************************/
-
-/* fwds */
-int
-SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
-static float
-SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, float velocity,
-                    float threshold, float acc);
-static PointerAccelerationProfileFunc
-GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
-static BOOL
-InitializePredictableAccelerationProperties(DeviceIntPtr dev);
-static BOOL
-DeletePredictableAccelerationProperties(DeviceIntPtr dev);
-
-/*#define PTRACCEL_DEBUGGING*/
-
-#ifdef PTRACCEL_DEBUGGING
-#define DebugAccelF ErrorF
-#else
-#define DebugAccelF(...) /* */
-#endif
-
-/********************************
- *  Init/Uninit
- *******************************/
-
-/* some int which is not a profile number */
-#define PROFILE_UNINITIALIZE (-100)
-
-
-/**
- * Init DeviceVelocity struct so it should match the average case
- */
-void
-InitVelocityData(DeviceVelocityPtr vel)
-{
-    memset(vel, 0, sizeof(DeviceVelocityRec));
-
-    vel->corr_mul = 10.0;      /* dots per 10 milisecond should be usable */
-    vel->const_acceleration = 1.0;   /* no acceleration/deceleration  */
-    vel->reset_time = 300;
-    vel->use_softening = 1;
-    vel->min_acceleration = 1.0; /* don't decelerate */
-    vel->max_rel_diff = 0.2;
-    vel->max_diff = 1.0;
-    vel->initial_range = 2;
-    vel->average_accel = TRUE;
-    SetAccelerationProfile(vel, AccelProfileClassic);
-    InitTrackers(vel, 16);
-}
-
-
-/**
- * Clean up DeviceVelocityRec
- */
-void
-FreeVelocityData(DeviceVelocityPtr vel){
-    free(vel->tracker);
-    SetAccelerationProfile(vel, PROFILE_UNINITIALIZE);
-}
-
-
-/**
- * Init predictable scheme
- */
-Bool
-InitPredictableAccelerationScheme(DeviceIntPtr dev,
-				  ValuatorAccelerationPtr protoScheme) {
-    DeviceVelocityPtr vel;
-    ValuatorAccelerationRec scheme;
-    scheme = *protoScheme;
-    vel = calloc(1, sizeof(DeviceVelocityRec));
-    if (!vel)
-	return FALSE;
-    InitVelocityData(vel);
-    scheme.accelData = vel;
-    dev->valuator->accelScheme = scheme;
-    InitializePredictableAccelerationProperties(dev);
-    return TRUE;
-}
-
-
-/**
- *  Uninit scheme
- */
-void
-AccelerationDefaultCleanup(DeviceIntPtr dev)
-{
-    /*sanity check*/
-    if( dev->valuator->accelScheme.AccelSchemeProc == acceleratePointerPredictable
-            && dev->valuator->accelScheme.accelData != NULL){
-        dev->valuator->accelScheme.AccelSchemeProc = NULL;
-        FreeVelocityData(dev->valuator->accelScheme.accelData);
-        free(dev->valuator->accelScheme.accelData);
-        dev->valuator->accelScheme.accelData = NULL;
-        DeletePredictableAccelerationProperties(dev);
-    }
-}
-
-
-/*************************
- * Input property support
- ************************/
-
-/**
- * choose profile
- */
-static int
-AccelSetProfileProperty(DeviceIntPtr dev, Atom atom,
-                        XIPropertyValuePtr val, BOOL checkOnly)
-{
-    DeviceVelocityPtr vel;
-    int profile, *ptr = &profile;
-    int rc;
-    int nelem = 1;
-
-    if (atom != XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER))
-        return Success;
-
-    vel = GetDevicePredictableAccelData(dev);
-    if (!vel)
-        return BadValue;
-    rc = XIPropToInt(val, &nelem, &ptr);
-
-    if(checkOnly)
-    {
-        if (rc)
-            return rc;
-
-        if (GetAccelerationProfile(vel, profile) == NULL)
-            return BadValue;
-    } else
-	SetAccelerationProfile(vel, profile);
-
-    return Success;
-}
-
-static long
-AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
-{
-    int profile = vel->statistics.profile_number;
-    Atom prop_profile_number = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
-
-    XIChangeDeviceProperty(dev, prop_profile_number, XA_INTEGER, 32,
-                           PropModeReplace, 1, &profile, FALSE);
-    XISetDevicePropertyDeletable(dev, prop_profile_number, FALSE);
-    return XIRegisterPropertyHandler(dev, AccelSetProfileProperty, NULL, NULL);
-}
-
-/**
- * constant deceleration
- */
-static int
-AccelSetDecelProperty(DeviceIntPtr dev, Atom atom,
-                      XIPropertyValuePtr val, BOOL checkOnly)
-{
-    DeviceVelocityPtr vel;
-    float v, *ptr = &v;
-    int rc;
-    int nelem = 1;
-
-    if (atom != XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION))
-        return Success;
-
-    vel = GetDevicePredictableAccelData(dev);
-    if (!vel)
-        return BadValue;
-    rc = XIPropToFloat(val, &nelem, &ptr);
-
-    if(checkOnly)
-    {
-        if (rc)
-            return rc;
-	return (v >= 1.0f) ? Success : BadValue;
-    }
-
-    if(v >= 1.0f)
-	vel->const_acceleration = 1/v;
-
-    return Success;
-}
-
-static long
-AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
-{
-    float fval = 1.0/vel->const_acceleration;
-    Atom prop_const_decel = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
-    XIChangeDeviceProperty(dev, prop_const_decel,
-                           XIGetKnownProperty(XATOM_FLOAT), 32,
-                           PropModeReplace, 1, &fval, FALSE);
-    XISetDevicePropertyDeletable(dev, prop_const_decel, FALSE);
-    return XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL);
-}
-
-
-/**
- * adaptive deceleration
- */
-static int
-AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom,
-                           XIPropertyValuePtr val, BOOL checkOnly)
-{
-    DeviceVelocityPtr veloc;
-    float v, *ptr = &v;
-    int rc;
-    int nelem = 1;
-
-    if (atom != XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION))
-        return Success;
-
-    veloc = GetDevicePredictableAccelData(dev);
-    if (!veloc)
-        return BadValue;
-    rc = XIPropToFloat(val, &nelem, &ptr);
-
-    if(checkOnly)
-    {
-        if (rc)
-            return rc;
-	return (v >= 1.0f) ? Success : BadValue;
-    }
-
-    if(v >= 1.0f)
-	veloc->min_acceleration = 1/v;
-
-    return Success;
-}
-
-static long
-AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
-{
-    float fval = 1.0/vel->min_acceleration;
-    Atom prop_adapt_decel = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
-
-    XIChangeDeviceProperty(dev, prop_adapt_decel, XIGetKnownProperty(XATOM_FLOAT), 32,
-                           PropModeReplace, 1, &fval, FALSE);
-    XISetDevicePropertyDeletable(dev, prop_adapt_decel, FALSE);
-    return XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL);
-}
-
-
-/**
- * velocity scaling
- */
-static int
-AccelSetScaleProperty(DeviceIntPtr dev, Atom atom,
-                      XIPropertyValuePtr val, BOOL checkOnly)
-{
-    DeviceVelocityPtr vel;
-    float v, *ptr = &v;
-    int rc;
-    int nelem = 1;
-
-    if (atom != XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING))
-        return Success;
-
-    vel = GetDevicePredictableAccelData(dev);
-    if (!vel)
-        return BadValue;
-    rc = XIPropToFloat(val, &nelem, &ptr);
-
-    if (checkOnly)
-    {
-        if (rc)
-            return rc;
-
-        return (v > 0) ? Success : BadValue;
-    }
-
-    if(v > 0)
-	vel->corr_mul = v;
-
-    return Success;
-}
-
-static long
-AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
-{
-    float fval = vel->corr_mul;
-    Atom prop_velo_scale = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
-
-    XIChangeDeviceProperty(dev, prop_velo_scale, XIGetKnownProperty(XATOM_FLOAT), 32,
-                           PropModeReplace, 1, &fval, FALSE);
-    XISetDevicePropertyDeletable(dev, prop_velo_scale, FALSE);
-    return XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL);
-}
-
-BOOL
-InitializePredictableAccelerationProperties(DeviceIntPtr dev)
-{
-    DeviceVelocityPtr  vel = GetDevicePredictableAccelData(dev);
-
-    if(!vel)
-	return FALSE;
-
-    vel->prop_handlers[0] = AccelInitProfileProperty(dev, vel);
-    vel->prop_handlers[1] = AccelInitDecelProperty(dev, vel);
-    vel->prop_handlers[2] = AccelInitAdaptDecelProperty(dev, vel);
-    vel->prop_handlers[3] = AccelInitScaleProperty(dev, vel);
-
-    return TRUE;
-}
-
-BOOL
-DeletePredictableAccelerationProperties(DeviceIntPtr dev)
-{
-    DeviceVelocityPtr  vel;
-    Atom prop;
-    int i;
-
-    prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
-    XIDeleteDeviceProperty(dev, prop, FALSE);
-    prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
-    XIDeleteDeviceProperty(dev, prop, FALSE);
-    prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
-    XIDeleteDeviceProperty(dev, prop, FALSE);
-    prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
-    XIDeleteDeviceProperty(dev, prop, FALSE);
-
-    vel = GetDevicePredictableAccelData(dev);
-    for (i = 0; vel && i < NPROPS_PREDICTABLE_ACCEL; i++)
-	if (vel->prop_handlers[i])
-	    XIUnregisterPropertyHandler(dev, vel->prop_handlers[i]);
-
-    return TRUE;
-}
-
-/*********************
- * Tracking logic
- ********************/
-
-void
-InitTrackers(DeviceVelocityPtr vel, int ntracker)
-{
-    if(ntracker < 1){
-	ErrorF("(dix ptracc) invalid number of trackers\n");
-	return;
-    }
-    free(vel->tracker);
-    vel->tracker = (MotionTrackerPtr)malloc(ntracker * sizeof(MotionTracker));
-    memset(vel->tracker, 0, ntracker * sizeof(MotionTracker));
-    vel->num_tracker = ntracker;
-}
-
-/**
- * return a bit field of possible directions.
- * 0 = N, 2 = E, 4 = S, 6 = W, in-between is as you guess.
- * There's no reason against widening to more precise directions (<45 degrees),
- * should it not perform well. All this is needed for is sort out non-linear
- * motion, so precision isn't paramount. However, one should not flag direction
- * too narrow, since it would then cut the linear segment to zero size way too
- * often.
- */
-static int
-DoGetDirection(int dx, int dy){
-    float r;
-    int i1, i2;
-    /* on insignificant mickeys, flag 135 degrees */
-    if(abs(dx) < 2 && abs(dy < 2)){
-	/* first check diagonal cases */
-	if(dx > 0 && dy > 0)
-	    return 4+8+16;
-	if(dx > 0 && dy < 0)
-	    return 1+2+4;
-	if(dx < 0 && dy < 0)
-	    return 1+128+64;
-	if(dx < 0 && dy > 0)
-	    return 16+32+64;
-        /* check axis-aligned directions */
-	if(dx > 0)
-            return 2+4+8; /*E*/
-        if(dx < 0)
-            return 128+64+32; /*W*/
-        if(dy > 0)
-            return 32+16+8; /*S*/
-        if(dy < 0)
-            return 128+1+2; /*N*/
-        return 255; /* shouldn't happen */
-    }
-    /* else, compute angle and set appropriate flags */
-#ifdef _ISOC99_SOURCE
-    r = atan2f(dy, dx);
-#else
-    r = atan2(dy, dx);
-#endif
-    /* find direction. We avoid r to become negative,
-     * since C has no well-defined modulo for such cases. */
-    r = (r+(M_PI*2.5))/(M_PI/4);
-    /* this intends to flag 2 directions (90 degrees),
-     * except on very well-aligned mickeys. */
-    i1 = (int)(r+0.1) % 8;
-    i2 = (int)(r+0.9) % 8;
-    if(i1 < 0 || i1 > 7 || i2 < 0 || i2 > 7)
-	return 255; /* shouldn't happen */
-    return 1 << i1 | 1 << i2;
-}
-
-#define DIRECTION_CACHE_RANGE 5
-#define DIRECTION_CACHE_SIZE (DIRECTION_CACHE_RANGE*2+1)
-
-/* cache DoGetDirection(). */
-static int
-GetDirection(int dx, int dy){
-    static int cache[DIRECTION_CACHE_SIZE][DIRECTION_CACHE_SIZE];
-    int i;
-    if (abs(dx) <= DIRECTION_CACHE_RANGE &&
-	abs(dy) <= DIRECTION_CACHE_RANGE) {
-	/* cacheable */
-	i = cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy];
-	if(i != 0){
-	    return i;
-	}else{
-	    i = DoGetDirection(dx, dy);
-	    cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy] = i;
-	    return i;
-	}
-    }else{
-	/* non-cacheable */
-	return DoGetDirection(dx, dy);
-    }
-}
-
-#undef DIRECTION_CACHE_RANGE
-#undef DIRECTION_CACHE_SIZE
-
-
-/* convert offset (age) to array index */
-#define TRACKER_INDEX(s, d) (((s)->num_tracker + (s)->cur_tracker - (d)) % (s)->num_tracker)
-
-static inline void
-FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
-{
-    int n;
-    for(n = 0; n < vel->num_tracker; n++){
-	vel->tracker[n].dx += dx;
-	vel->tracker[n].dy += dy;
-    }
-    n = (vel->cur_tracker + 1) % vel->num_tracker;
-    vel->tracker[n].dx = 0;
-    vel->tracker[n].dy = 0;
-    vel->tracker[n].time = cur_t;
-    vel->tracker[n].dir = GetDirection(dx, dy);
-    DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
-                dx, dy, vel->tracker[n].dir,
-                cur_t - vel->tracker[vel->cur_tracker].time);
-    vel->cur_tracker = n;
-}
-
-/**
- * calc velocity for given tracker, with
- * velocity scaling.
- * This assumes linear motion.
- */
-static float
-CalcTracker(DeviceVelocityPtr vel, int offset, int cur_t){
-    int index = TRACKER_INDEX(vel, offset);
-    float dist = sqrt(  vel->tracker[index].dx * vel->tracker[index].dx
-                      + vel->tracker[index].dy * vel->tracker[index].dy);
-    int dtime = cur_t - vel->tracker[index].time;
-    if(dtime > 0)
-	return dist / dtime;
-    else
-	return 0;/* synonymous for NaN, since we're not C99 */
-}
-
-/* find the most plausible velocity. That is, the most distant
- * (in time) tracker which isn't too old, beyond a linear partition,
- * or simply too much off initial velocity.
- *
- * May return 0.
- */
-static float
-QueryTrackers(DeviceVelocityPtr vel, int cur_t){
-    int n, offset, dir = 255, i = -1, age_ms;
-    /* initial velocity: a low-offset, valid velocity */
-    float iveloc = 0, res = 0, tmp, vdiff;
-    float vfac =  vel->corr_mul * vel->const_acceleration; /* premultiply */
-    /* loop from current to older data */
-    for(offset = 1; offset < vel->num_tracker; offset++){
-	n = TRACKER_INDEX(vel, offset);
-
-	age_ms = cur_t - vel->tracker[n].time;
-
-	/* bail out if data is too old and protect from overrun */
-	if (age_ms >= vel->reset_time || age_ms < 0) {
-	    DebugAccelF("(dix prtacc) query: tracker too old\n");
-	    break;
-	}
-
-	/*
-	 * this heuristic avoids using the linear-motion velocity formula
-	 * in CalcTracker() on motion that isn't exactly linear. So to get
-	 * even more precision we could subdivide as a final step, so possible
-	 * non-linearities are accounted for.
-	 */
-	dir &= vel->tracker[n].dir;
-	if(dir == 0){
-	    DebugAccelF("(dix prtacc) query: no longer linear\n");
-	    /* instead of breaking it we might also inspect the partition after,
-	     * but actual improvement with this is probably rare. */
-	    break;
-	}
-
-	tmp = CalcTracker(vel, offset, cur_t) * vfac;
-
-	if ((iveloc == 0 || offset <= vel->initial_range) && tmp != 0) {
-	    /* set initial velocity and result */
-	    res = iveloc = tmp;
-	    i = offset;
-	} else if (iveloc != 0 && tmp != 0) {
-	    vdiff = fabs(iveloc - tmp);
-	    if (vdiff <= vel->max_diff ||
-		vdiff/(iveloc + tmp) < vel->max_rel_diff) {
-		/* we're in range with the initial velocity,
-		 * so this result is likely better
-		 * (it contains more information). */
-		res = tmp;
-		i = offset;
-	    }else{
-		/* we're not in range, quit - it won't get better. */
-		DebugAccelF("(dix prtacc) query: tracker too different:"
-		            " old %2.2f initial %2.2f diff: %2.2f\n",
-		            tmp, iveloc, vdiff);
-		break;
-	    }
-	}
-    }
-    if(offset == vel->num_tracker){
-	DebugAccelF("(dix prtacc) query: last tracker in effect\n");
-	i = vel->num_tracker-1;
-    }
-    if(i>=0){
-        n = TRACKER_INDEX(vel, i);
-	DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
-	            i,
-	            vel->tracker[n].dx,
-	            vel->tracker[n].dy,
-	            cur_t - vel->tracker[n].time);
-    }
-    return res;
-}
-
-#undef TRACKER_INDEX
-
-/**
- * Perform velocity approximation based on 2D 'mickeys' (mouse motion delta).
- * return true if non-visible state reset is suggested
- */
-short
-ProcessVelocityData2D(
-    DeviceVelocityPtr vel,
-    int dx,
-    int dy,
-    int time)
-{
-    float velocity;
-
-    vel->last_velocity = vel->velocity;
-
-    FeedTrackers(vel, dx, dy, time);
-
-    velocity = QueryTrackers(vel, time);
-
-    vel->velocity = velocity;
-    return velocity == 0;
-}
-
-/**
- * this flattens significant ( > 1) mickeys a little bit for more steady
- * constant-velocity response
- */
-static inline float
-ApplySimpleSoftening(int od, int d)
-{
-    float res = d;
-    if (d <= 1 && d >= -1)
-        return res;
-    if (d > od)
-        res -= 0.5;
-    else if (d < od)
-        res += 0.5;
-    return res;
-}
-
-
-static void
-ApplySofteningAndConstantDeceleration(
-        DeviceVelocityPtr vel,
-        int dx,
-        int dy,
-        float* fdx,
-        float* fdy,
-        short do_soften)
-{
-    if (do_soften && vel->use_softening) {
-        *fdx = ApplySimpleSoftening(vel->last_dx, dx);
-        *fdy = ApplySimpleSoftening(vel->last_dy, dy);
-    } else {
-        *fdx = dx;
-        *fdy = dy;
-    }
-
-    *fdx *= vel->const_acceleration;
-    *fdy *= vel->const_acceleration;
-}
-
-/*
- * compute the acceleration for given velocity and enforce min_acceleartion
- */
-float
-BasicComputeAcceleration(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc){
-
-    float result;
-    result = vel->Profile(dev, vel, velocity, threshold, acc);
-
-    /* enforce min_acceleration */
-    if (result < vel->min_acceleration)
-	result = vel->min_acceleration;
-    return result;
-}
-
-/**
- * Compute acceleration. Takes into account averaging, nv-reset, etc.
- */
-static float
-ComputeAcceleration(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float threshold,
-    float acc){
-    float res;
-
-    if(vel->velocity <= 0){
-	DebugAccelF("(dix ptracc) profile skipped\n");
-        /*
-         * If we have no idea about device velocity, don't pretend it.
-         */
-	return 1;
-    }
-
-    if(vel->average_accel && vel->velocity != vel->last_velocity){
-	/* use simpson's rule to average acceleration between
-	 * current and previous velocity.
-	 * Though being the more natural choice, it causes a minor delay
-	 * in comparison, so it can be disabled. */
-	res = BasicComputeAcceleration(
-	          dev, vel, vel->velocity, threshold, acc);
-	res += BasicComputeAcceleration(
-	          dev, vel, vel->last_velocity, threshold, acc);
-	res += 4.0f * BasicComputeAcceleration(dev, vel,
-	                   (vel->last_velocity + vel->velocity) / 2,
-	                   threshold, acc);
-	res /= 6.0f;
-	DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
-	            vel->velocity, vel->last_velocity, res);
-        return res;
-    }else{
-	res = BasicComputeAcceleration(dev, vel,
-	                               vel->velocity, threshold, acc);
-	DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
-               vel->velocity, res);
-	return res;
-    }
-}
-
-
-/*****************************************
- *  Acceleration functions and profiles
- ****************************************/
-
-/**
- * Polynomial function similar previous one, but with f(1) = 1
- */
-static float
-PolynomialAccelerationProfile(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float velocity,
-    float ignored,
-    float acc)
-{
-   return pow(velocity, (acc - 1.0) * 0.5);
-}
-
-
-/**
- * returns acceleration for velocity.
- * This profile selects the two functions like the old scheme did
- */
-static float
-ClassicProfile(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
-{
-    if (threshold > 0) {
-	return SimpleSmoothProfile (dev,
-	                            vel,
-	                            velocity,
-                                    threshold,
-                                    acc);
-    } else {
-	return PolynomialAccelerationProfile (dev,
-	                                      vel,
-	                                      velocity,
-                                              0,
-                                              acc);
-    }
-}
-
-
-/**
- * Power profile
- * This has a completely smooth transition curve, i.e. no jumps in the
- * derivatives.
- *
- * This has the expense of overall response dependency on min-acceleration.
- * In effect, min_acceleration mimics const_acceleration in this profile.
- */
-static float
-PowerProfile(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
-{
-    float vel_dist;
-
-    acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */
-
-    if (velocity <= threshold)
-        return vel->min_acceleration;
-    vel_dist = velocity - threshold;
-    return (pow(acc, vel_dist)) * vel->min_acceleration;
-}
-
-
-/**
- * just a smooth function in [0..1] -> [0..1]
- *  - point symmetry at 0.5
- *  - f'(0) = f'(1) = 0
- *  - starts faster than a sinoid
- *  - smoothness C1 (Cinf if you dare to ignore endpoints)
- */
-static inline float
-CalcPenumbralGradient(float x){
-    x *= 2.0f;
-    x -= 1.0f;
-    return 0.5f + (x * sqrt(1.0f - x*x) + asin(x))/M_PI;
-}
-
-
-/**
- * acceleration function similar to classic accelerated/unaccelerated,
- * but with smooth transition in between (and towards zero for adaptive dec.).
- */
-static float
-SimpleSmoothProfile(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
-{
-    if(velocity < 1.0f)
-        return CalcPenumbralGradient(0.5 + velocity*0.5) * 2.0f - 1.0f;
-    if(threshold < 1.0f)
-        threshold = 1.0f;
-    if (velocity <= threshold)
-        return 1;
-    velocity /= threshold;
-    if (velocity >= acc)
-        return acc;
-    else
-        return 1.0f + (CalcPenumbralGradient(velocity/acc) * (acc - 1.0f));
-}
-
-
-/**
- * This profile uses the first half of the penumbral gradient as a start
- * and then scales linearly.
- */
-static float
-SmoothLinearProfile(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
-{
-    float res, nv;
-
-    if(acc > 1.0f)
-        acc -= 1.0f; /*this is so acc = 1 is no acceleration */
-    else
-        return 1.0f;
-
-    nv = (velocity - threshold) * acc * 0.5f;
-
-    if(nv < 0){
-        res = 0;
-    }else if(nv < 2){
-        res = CalcPenumbralGradient(nv*0.25f)*2.0f;
-    }else{
-        nv -= 2.0f;
-        res = nv * 2.0f / M_PI  /* steepness of gradient at 0.5 */
-              + 1.0f; /* gradient crosses 2|1 */
-    }
-    res += vel->min_acceleration;
-    return res;
-}
-
-
-/**
- * From 0 to threshold, the response graduates smoothly from min_accel to
- * acceleration. Beyond threshold it is exactly the specified acceleration.
- */
-static float
-SmoothLimitedProfile(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
-{
-    float res;
-
-    if(velocity >= threshold || threshold == 0.0f)
-	return acc;
-
-    velocity /= threshold; /* should be [0..1[ now */
-
-    res = CalcPenumbralGradient(velocity) * (acc - vel->min_acceleration);
-
-    return vel->min_acceleration + res;
-}
-
-
-static float
-LinearProfile(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
-{
-    return acc * velocity;
-}
-
-static float
-NoProfile(
-    DeviceIntPtr dev,
-    DeviceVelocityPtr vel,
-    float velocity,
-    float threshold,
-    float acc)
-{
-    return 1.0f;
-}
-
-static PointerAccelerationProfileFunc
-GetAccelerationProfile(
-    DeviceVelocityPtr vel,
-    int profile_num)
-{
-    switch(profile_num){
-        case AccelProfileClassic:
-            return ClassicProfile;
-        case AccelProfileDeviceSpecific:
-            return vel->deviceSpecificProfile;
-        case AccelProfilePolynomial:
-            return PolynomialAccelerationProfile;
-        case AccelProfileSmoothLinear:
-            return SmoothLinearProfile;
-        case AccelProfileSimple:
-            return SimpleSmoothProfile;
-        case AccelProfilePower:
-            return PowerProfile;
-        case AccelProfileLinear:
-            return LinearProfile;
-        case AccelProfileSmoothLimited:
-            return SmoothLimitedProfile;
-        case AccelProfileNone:
-            return NoProfile;
-        default:
-            return NULL;
-    }
-}
-
-/**
- * Set the profile by number.
- * Intended to make profiles exchangeable at runtime.
- * If you created a profile, give it a number here and in the header to
- * make it selectable. In case some profile-specific init is needed, here
- * would be a good place, since FreeVelocityData() also calls this with
- * PROFILE_UNINITIALIZE.
- *
- * returns FALSE if profile number is unavailable, TRUE otherwise.
- */
-int
-SetAccelerationProfile(
-    DeviceVelocityPtr vel,
-    int profile_num)
-{
-    PointerAccelerationProfileFunc profile;
-    profile = GetAccelerationProfile(vel, profile_num);
-
-    if(profile == NULL && profile_num != PROFILE_UNINITIALIZE)
-	return FALSE;
-
-    /* Here one could free old profile-private data */
-    free(vel->profile_private);
-    vel->profile_private = NULL;
-    /* Here one could init profile-private data */
-    vel->Profile = profile;
-    vel->statistics.profile_number = profile_num;
-    return TRUE;
-}
-
-/**********************************************
- * driver interaction
- **********************************************/
-
-
-/**
- * device-specific profile
- *
- * The device-specific profile is intended as a hook for a driver
- * which may want to provide an own acceleration profile.
- * It should not rely on profile-private data, instead
- * it should do init/uninit in the driver (ie. with DEVICE_INIT and friends).
- * Users may override or choose it.
- */
-void
-SetDeviceSpecificAccelerationProfile(
-        DeviceVelocityPtr vel,
-        PointerAccelerationProfileFunc profile)
-{
-    if(vel)
-	vel->deviceSpecificProfile = profile;
-}
-
-/**
- * Use this function to obtain a DeviceVelocityPtr for a device. Will return NULL if
- * the predictable acceleration scheme is not in effect.
- */
-DeviceVelocityPtr
-GetDevicePredictableAccelData(
-	DeviceIntPtr dev)
-{
-    /*sanity check*/
-    if(!dev){
-	ErrorF("[dix] accel: DeviceIntPtr was NULL");
-	return NULL;
-    }
-    if( dev->valuator &&
-	dev->valuator->accelScheme.AccelSchemeProc ==
-	    acceleratePointerPredictable &&
-	dev->valuator->accelScheme.accelData != NULL){
-
-	return (DeviceVelocityPtr)dev->valuator->accelScheme.accelData;
-    }
-    return NULL;
-}
-
-/********************************
- *  acceleration schemes
- *******************************/
-
-/**
- * Modifies valuators in-place.
- * This version employs a velocity approximation algorithm to
- * enable fine-grained predictable acceleration profiles.
- */
-void
-acceleratePointerPredictable(
-    DeviceIntPtr dev,
-    int first_valuator,
-    int num_valuators,
-    int *valuators,
-    int evtime)
-{
-    float fdx, fdy, tmp, mult; /* no need to init */
-    int dx = 0, dy = 0;
-    int *px = NULL, *py = NULL;
-    DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev);
-    Bool soften = TRUE;
-
-    if (!num_valuators || !valuators || !velocitydata)
-        return;
-
-    if (velocitydata->statistics.profile_number == AccelProfileNone &&
-	velocitydata->const_acceleration == 1.0f) {
-	return; /*we're inactive anyway, so skip the whole thing.*/
-    }
-
-    if (first_valuator == 0) {
-        dx = valuators[0];
-        px = &valuators[0];
-    }
-    if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
-        dy = valuators[1 - first_valuator];
-        py = &valuators[1 - first_valuator];
-    }
-
-    if (dx || dy){
-        /* reset non-visible state? */
-        if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) {
-            soften = FALSE;
-        }
-
-        if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
-            /* invoke acceleration profile to determine acceleration */
-            mult = ComputeAcceleration (dev, velocitydata,
-					dev->ptrfeed->ctrl.threshold,
-					(float)dev->ptrfeed->ctrl.num /
-					(float)dev->ptrfeed->ctrl.den);
-
-            if(mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
-                ApplySofteningAndConstantDeceleration( velocitydata,
-						       dx, dy,
-						       &fdx, &fdy,
-						       (mult > 1.0f) && soften);
-
-                if (dx) {
-                    tmp = mult * fdx + dev->last.remainder[0];
-                    /* Since it may not be apparent: lrintf() does not offer
-                     * strong statements about rounding; however because we
-                     * process each axis conditionally, there's no danger
-                     * of a toggling remainder. Its lack of guarantees likely
-                     * makes it faster on the average target. */
-                    *px = lrintf(tmp);
-                    dev->last.remainder[0] = tmp - (float)*px;
-                }
-                if (dy) {
-                    tmp = mult * fdy + dev->last.remainder[1];
-                    *py = lrintf(tmp);
-                    dev->last.remainder[1] = tmp - (float)*py;
-                }
-                DebugAccelF("pos (%i | %i) remainders x: %.3f y: %.3f delta x:%.3f y:%.3f\n",
-                            *px, *py, dev->last.remainder[0], dev->last.remainder[1], fdx, fdy);
-            }
-        }
-    }
-    /* remember last motion delta (for softening/slow movement treatment) */
-    velocitydata->last_dx = dx;
-    velocitydata->last_dy = dy;
-}
-
-
-
-/**
- * Originally a part of xf86PostMotionEvent; modifies valuators
- * in-place. Retained mostly for embedded scenarios.
- */
-void
-acceleratePointerLightweight(
-    DeviceIntPtr dev,
-    int first_valuator,
-    int num_valuators,
-    int *valuators,
-    int ignored)
-{
-    float mult = 0.0;
-    int dx = 0, dy = 0;
-    int *px = NULL, *py = NULL;
-
-    if (!num_valuators || !valuators)
-        return;
-
-    if (first_valuator == 0) {
-        dx = valuators[0];
-        px = &valuators[0];
-    }
-    if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
-        dy = valuators[1 - first_valuator];
-        py = &valuators[1 - first_valuator];
-    }
-
-    if (!dx && !dy)
-        return;
-
-    if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
-        /* modeled from xf86Events.c */
-        if (dev->ptrfeed->ctrl.threshold) {
-            if ((abs(dx) + abs(dy)) >= dev->ptrfeed->ctrl.threshold) {
-                dev->last.remainder[0] = ((float)dx *
-                                             (float)(dev->ptrfeed->ctrl.num)) /
-                                             (float)(dev->ptrfeed->ctrl.den) +
-                                            dev->last.remainder[0];
-                if (px) {
-                    *px = (int)dev->last.remainder[0];
-                    dev->last.remainder[0] = dev->last.remainder[0] -
-                                                (float)(*px);
-                }
-
-                dev->last.remainder[1] = ((float)dy *
-                                             (float)(dev->ptrfeed->ctrl.num)) /
-                                             (float)(dev->ptrfeed->ctrl.den) +
-                                            dev->last.remainder[1];
-                if (py) {
-                    *py = (int)dev->last.remainder[1];
-                    dev->last.remainder[1] = dev->last.remainder[1] -
-                                                (float)(*py);
-                }
-            }
-        }
-        else {
-	    mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
-                       ((float)(dev->ptrfeed->ctrl.num) /
-                        (float)(dev->ptrfeed->ctrl.den) - 1.0) /
-                       2.0) / 2.0;
-            if (dx) {
-                dev->last.remainder[0] = mult * (float)dx +
-                                            dev->last.remainder[0];
-                *px = (int)dev->last.remainder[0];
-                dev->last.remainder[0] = dev->last.remainder[0] -
-                                            (float)(*px);
-            }
-            if (dy) {
-                dev->last.remainder[1] = mult * (float)dy +
-                                            dev->last.remainder[1];
-                *py = (int)dev->last.remainder[1];
-                dev->last.remainder[1] = dev->last.remainder[1] -
-                                            (float)(*py);
-            }
-        }
-    }
-}
+/*
+ *
+ * Copyright © 2006-2009 Simon Thum             simon dot thum at gmx dot de
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <math.h>
+#include <ptrveloc.h>
+#include <exevents.h>
+#include <X11/Xatom.h>
+#include <os.h>
+
+#include <xserver-properties.h>
+
+/*****************************************************************************
+ * Predictable pointer acceleration
+ *
+ * 2006-2009 by Simon Thum (simon [dot] thum [at] gmx de)
+ *
+ * Serves 3 complementary functions:
+ * 1) provide a sophisticated ballistic velocity estimate to improve
+ *    the relation between velocity (of the device) and acceleration
+ * 2) make arbitrary acceleration profiles possible
+ * 3) decelerate by two means (constant and adaptive) if enabled
+ *
+ * Important concepts are the
+ *
+ * - Scheme
+ *      which selects the basic algorithm
+ *      (see devices.c/InitPointerAccelerationScheme)
+ * - Profile
+ *      which returns an acceleration
+ *      for a given velocity
+ *
+ *  The profile can be selected by the user at runtime.
+ *  The classic profile is intended to cleanly perform old-style
+ *  function selection (threshold =/!= 0)
+ *
+ ****************************************************************************/
+
+/* fwds */
+int
+SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
+static float
+SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, float velocity,
+                    float threshold, float acc);
+static PointerAccelerationProfileFunc
+GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
+static BOOL
+InitializePredictableAccelerationProperties(DeviceIntPtr,
+                                            DeviceVelocityPtr,
+                                            PredictableAccelSchemePtr);
+static BOOL
+DeletePredictableAccelerationProperties(DeviceIntPtr,
+                                        PredictableAccelSchemePtr);
+
+/*#define PTRACCEL_DEBUGGING*/
+
+#ifdef PTRACCEL_DEBUGGING
+#define DebugAccelF ErrorF
+#else
+#define DebugAccelF(...) /* */
+#endif
+
+/********************************
+ *  Init/Uninit
+ *******************************/
+
+/* some int which is not a profile number */
+#define PROFILE_UNINITIALIZE (-100)
+
+/**
+ * Init DeviceVelocity struct so it should match the average case
+ */
+void
+InitVelocityData(DeviceVelocityPtr vel)
+{
+    memset(vel, 0, sizeof(DeviceVelocityRec));
+
+    vel->corr_mul = 10.0;      /* dots per 10 milisecond should be usable */
+    vel->const_acceleration = 1.0;   /* no acceleration/deceleration  */
+    vel->reset_time = 300;
+    vel->use_softening = 1;
+    vel->min_acceleration = 1.0; /* don't decelerate */
+    vel->max_rel_diff = 0.2;
+    vel->max_diff = 1.0;
+    vel->initial_range = 2;
+    vel->average_accel = TRUE;
+    SetAccelerationProfile(vel, AccelProfileClassic);
+    InitTrackers(vel, 16);
+}
+
+
+/**
+ * Clean up DeviceVelocityRec
+ */
+void
+FreeVelocityData(DeviceVelocityPtr vel){
+    free(vel->tracker);
+    SetAccelerationProfile(vel, PROFILE_UNINITIALIZE);
+}
+
+
+/**
+ * Init predictable scheme
+ */
+Bool
+InitPredictableAccelerationScheme(DeviceIntPtr dev,
+                                  ValuatorAccelerationPtr protoScheme) {
+    DeviceVelocityPtr vel;
+    ValuatorAccelerationRec scheme;
+    PredictableAccelSchemePtr schemeData;
+    scheme = *protoScheme;
+    vel = calloc(1, sizeof(DeviceVelocityRec));
+    schemeData = calloc(1, sizeof(PredictableAccelSchemeRec));
+    if (!vel || !schemeData)
+        return FALSE;
+    InitVelocityData(vel);
+    schemeData->vel = vel;
+    scheme.accelData = schemeData;
+    if (!InitializePredictableAccelerationProperties(dev, vel, schemeData))
+        return FALSE;
+    /* all fine, assign scheme to device */
+    dev->valuator->accelScheme = scheme;
+    return TRUE;
+}
+
+
+/**
+ *  Uninit scheme
+ */
+void
+AccelerationDefaultCleanup(DeviceIntPtr dev)
+{
+    DeviceVelocityPtr vel = GetDevicePredictableAccelData(dev);
+    if (vel) {
+        /* the proper guarantee would be that we're not inside of
+         * AccelSchemeProc(), but that seems impossible. Schemes don't get
+         * switched often anyway.
+         */
+        OsBlockSignals();
+        dev->valuator->accelScheme.AccelSchemeProc = NULL;
+        FreeVelocityData(vel);
+        free(vel);
+        DeletePredictableAccelerationProperties(dev,
+            (PredictableAccelSchemePtr) dev->valuator->accelScheme.accelData);
+        free(dev->valuator->accelScheme.accelData);
+        dev->valuator->accelScheme.accelData = NULL;
+        OsReleaseSignals();
+    }
+}
+
+
+/*************************
+ * Input property support
+ ************************/
+
+/**
+ * choose profile
+ */
+static int
+AccelSetProfileProperty(DeviceIntPtr dev, Atom atom,
+                        XIPropertyValuePtr val, BOOL checkOnly)
+{
+    DeviceVelocityPtr vel;
+    int profile, *ptr = &profile;
+    int rc;
+    int nelem = 1;
+
+    if (atom != XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER))
+        return Success;
+
+    vel = GetDevicePredictableAccelData(dev);
+    if (!vel)
+        return BadValue;
+    rc = XIPropToInt(val, &nelem, &ptr);
+
+    if(checkOnly)
+    {
+        if (rc)
+            return rc;
+
+        if (GetAccelerationProfile(vel, profile) == NULL)
+            return BadValue;
+    } else
+	SetAccelerationProfile(vel, profile);
+
+    return Success;
+}
+
+static long
+AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
+{
+    int profile = vel->statistics.profile_number;
+    Atom prop_profile_number = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+
+    XIChangeDeviceProperty(dev, prop_profile_number, XA_INTEGER, 32,
+                           PropModeReplace, 1, &profile, FALSE);
+    XISetDevicePropertyDeletable(dev, prop_profile_number, FALSE);
+    return XIRegisterPropertyHandler(dev, AccelSetProfileProperty, NULL, NULL);
+}
+
+/**
+ * constant deceleration
+ */
+static int
+AccelSetDecelProperty(DeviceIntPtr dev, Atom atom,
+                      XIPropertyValuePtr val, BOOL checkOnly)
+{
+    DeviceVelocityPtr vel;
+    float v, *ptr = &v;
+    int rc;
+    int nelem = 1;
+
+    if (atom != XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION))
+        return Success;
+
+    vel = GetDevicePredictableAccelData(dev);
+    if (!vel)
+        return BadValue;
+    rc = XIPropToFloat(val, &nelem, &ptr);
+
+    if(checkOnly)
+    {
+        if (rc)
+            return rc;
+	return (v >= 1.0f) ? Success : BadValue;
+    }
+
+    if(v >= 1.0f)
+	vel->const_acceleration = 1/v;
+
+    return Success;
+}
+
+static long
+AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
+{
+    float fval = 1.0/vel->const_acceleration;
+    Atom prop_const_decel = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+    XIChangeDeviceProperty(dev, prop_const_decel,
+                           XIGetKnownProperty(XATOM_FLOAT), 32,
+                           PropModeReplace, 1, &fval, FALSE);
+    XISetDevicePropertyDeletable(dev, prop_const_decel, FALSE);
+    return XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL);
+}
+
+
+/**
+ * adaptive deceleration
+ */
+static int
+AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom,
+                           XIPropertyValuePtr val, BOOL checkOnly)
+{
+    DeviceVelocityPtr veloc;
+    float v, *ptr = &v;
+    int rc;
+    int nelem = 1;
+
+    if (atom != XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION))
+        return Success;
+
+    veloc = GetDevicePredictableAccelData(dev);
+    if (!veloc)
+        return BadValue;
+    rc = XIPropToFloat(val, &nelem, &ptr);
+
+    if(checkOnly)
+    {
+        if (rc)
+            return rc;
+	return (v >= 1.0f) ? Success : BadValue;
+    }
+
+    if(v >= 1.0f)
+	veloc->min_acceleration = 1/v;
+
+    return Success;
+}
+
+static long
+AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
+{
+    float fval = 1.0/vel->min_acceleration;
+    Atom prop_adapt_decel = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+
+    XIChangeDeviceProperty(dev, prop_adapt_decel, XIGetKnownProperty(XATOM_FLOAT), 32,
+                           PropModeReplace, 1, &fval, FALSE);
+    XISetDevicePropertyDeletable(dev, prop_adapt_decel, FALSE);
+    return XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL);
+}
+
+
+/**
+ * velocity scaling
+ */
+static int
+AccelSetScaleProperty(DeviceIntPtr dev, Atom atom,
+                      XIPropertyValuePtr val, BOOL checkOnly)
+{
+    DeviceVelocityPtr vel;
+    float v, *ptr = &v;
+    int rc;
+    int nelem = 1;
+
+    if (atom != XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING))
+        return Success;
+
+    vel = GetDevicePredictableAccelData(dev);
+    if (!vel)
+        return BadValue;
+    rc = XIPropToFloat(val, &nelem, &ptr);
+
+    if (checkOnly)
+    {
+        if (rc)
+            return rc;
+
+        return (v > 0) ? Success : BadValue;
+    }
+
+    if(v > 0)
+	vel->corr_mul = v;
+
+    return Success;
+}
+
+static long
+AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
+{
+    float fval = vel->corr_mul;
+    Atom prop_velo_scale = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
+
+    XIChangeDeviceProperty(dev, prop_velo_scale, XIGetKnownProperty(XATOM_FLOAT), 32,
+                           PropModeReplace, 1, &fval, FALSE);
+    XISetDevicePropertyDeletable(dev, prop_velo_scale, FALSE);
+    return XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL);
+}
+
+static BOOL
+InitializePredictableAccelerationProperties(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr  vel,
+    PredictableAccelSchemePtr schemeData)
+{
+    int num_handlers = 4;
+    if(!vel)
+        return FALSE;
+
+    schemeData->prop_handlers = calloc(num_handlers, sizeof(long));
+    if (!schemeData->prop_handlers)
+        return FALSE;
+    schemeData->num_prop_handlers = num_handlers;
+    schemeData->prop_handlers[0] = AccelInitProfileProperty(dev, vel);
+    schemeData->prop_handlers[1] = AccelInitDecelProperty(dev, vel);
+    schemeData->prop_handlers[2] = AccelInitAdaptDecelProperty(dev, vel);
+    schemeData->prop_handlers[3] = AccelInitScaleProperty(dev, vel);
+
+    return TRUE;
+}
+
+BOOL
+DeletePredictableAccelerationProperties(
+    DeviceIntPtr dev,
+    PredictableAccelSchemePtr scheme)
+{
+    DeviceVelocityPtr vel;
+    Atom prop;
+    int i;
+
+    prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
+    XIDeleteDeviceProperty(dev, prop, FALSE);
+    prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+    XIDeleteDeviceProperty(dev, prop, FALSE);
+    prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+    XIDeleteDeviceProperty(dev, prop, FALSE);
+    prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+    XIDeleteDeviceProperty(dev, prop, FALSE);
+
+    vel = GetDevicePredictableAccelData(dev);
+    if (vel) {
+        for (i = 0; i < scheme->num_prop_handlers; i++)
+            if (scheme->prop_handlers[i])
+                XIUnregisterPropertyHandler(dev, scheme->prop_handlers[i]);
+    }
+
+    free(scheme->prop_handlers);
+    scheme->prop_handlers = NULL;
+    scheme->num_prop_handlers = 0;
+    return TRUE;
+}
+
+/*********************
+ * Tracking logic
+ ********************/
+
+void
+InitTrackers(DeviceVelocityPtr vel, int ntracker)
+{
+    if(ntracker < 1){
+	ErrorF("(dix ptracc) invalid number of trackers\n");
+	return;
+    }
+    free(vel->tracker);
+    vel->tracker = (MotionTrackerPtr)calloc(ntracker, sizeof(MotionTracker));
+    vel->num_tracker = ntracker;
+}
+
+/**
+ * return a bit field of possible directions.
+ * 0 = N, 2 = E, 4 = S, 6 = W, in-between is as you guess.
+ * There's no reason against widening to more precise directions (<45 degrees),
+ * should it not perform well. All this is needed for is sort out non-linear
+ * motion, so precision isn't paramount. However, one should not flag direction
+ * too narrow, since it would then cut the linear segment to zero size way too
+ * often.
+ */
+static int
+DoGetDirection(int dx, int dy){
+    float r;
+    int i1, i2;
+    /* on insignificant mickeys, flag 135 degrees */
+    if(abs(dx) < 2 && abs(dy < 2)){
+	/* first check diagonal cases */
+	if(dx > 0 && dy > 0)
+	    return 4+8+16;
+	if(dx > 0 && dy < 0)
+	    return 1+2+4;
+	if(dx < 0 && dy < 0)
+	    return 1+128+64;
+	if(dx < 0 && dy > 0)
+	    return 16+32+64;
+        /* check axis-aligned directions */
+	if(dx > 0)
+            return 2+4+8; /*E*/
+        if(dx < 0)
+            return 128+64+32; /*W*/
+        if(dy > 0)
+            return 32+16+8; /*S*/
+        if(dy < 0)
+            return 128+1+2; /*N*/
+        return 255; /* shouldn't happen */
+    }
+    /* else, compute angle and set appropriate flags */
+#ifdef _ISOC99_SOURCE
+    r = atan2f(dy, dx);
+#else
+    r = atan2(dy, dx);
+#endif
+    /* find direction. We avoid r to become negative,
+     * since C has no well-defined modulo for such cases. */
+    r = (r+(M_PI*2.5))/(M_PI/4);
+    /* this intends to flag 2 directions (90 degrees),
+     * except on very well-aligned mickeys. */
+    i1 = (int)(r+0.1) % 8;
+    i2 = (int)(r+0.9) % 8;
+    if(i1 < 0 || i1 > 7 || i2 < 0 || i2 > 7)
+	return 255; /* shouldn't happen */
+    return 1 << i1 | 1 << i2;
+}
+
+#define DIRECTION_CACHE_RANGE 5
+#define DIRECTION_CACHE_SIZE (DIRECTION_CACHE_RANGE*2+1)
+
+/* cache DoGetDirection(). */
+static int
+GetDirection(int dx, int dy){
+    static int cache[DIRECTION_CACHE_SIZE][DIRECTION_CACHE_SIZE];
+    int i;
+    if (abs(dx) <= DIRECTION_CACHE_RANGE &&
+	abs(dy) <= DIRECTION_CACHE_RANGE) {
+	/* cacheable */
+	i = cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy];
+	if(i != 0){
+	    return i;
+	}else{
+	    i = DoGetDirection(dx, dy);
+	    cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy] = i;
+	    return i;
+	}
+    }else{
+	/* non-cacheable */
+	return DoGetDirection(dx, dy);
+    }
+}
+
+#undef DIRECTION_CACHE_RANGE
+#undef DIRECTION_CACHE_SIZE
+
+
+/* convert offset (age) to array index */
+#define TRACKER_INDEX(s, d) (((s)->num_tracker + (s)->cur_tracker - (d)) % (s)->num_tracker)
+
+static inline void
+FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
+{
+    int n;
+    for(n = 0; n < vel->num_tracker; n++){
+	vel->tracker[n].dx += dx;
+	vel->tracker[n].dy += dy;
+    }
+    n = (vel->cur_tracker + 1) % vel->num_tracker;
+    vel->tracker[n].dx = 0;
+    vel->tracker[n].dy = 0;
+    vel->tracker[n].time = cur_t;
+    vel->tracker[n].dir = GetDirection(dx, dy);
+    DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
+                dx, dy, vel->tracker[n].dir,
+                cur_t - vel->tracker[vel->cur_tracker].time);
+    vel->cur_tracker = n;
+}
+
+/**
+ * calc velocity for given tracker, with
+ * velocity scaling.
+ * This assumes linear motion.
+ */
+static float
+CalcTracker(DeviceVelocityPtr vel, int offset, int cur_t){
+    int index = TRACKER_INDEX(vel, offset);
+    float dist = sqrt(  vel->tracker[index].dx * vel->tracker[index].dx
+                      + vel->tracker[index].dy * vel->tracker[index].dy);
+    int dtime = cur_t - vel->tracker[index].time;
+    if(dtime > 0)
+	return dist / dtime;
+    else
+	return 0;/* synonymous for NaN, since we're not C99 */
+}
+
+/* find the most plausible velocity. That is, the most distant
+ * (in time) tracker which isn't too old, beyond a linear partition,
+ * or simply too much off initial velocity.
+ *
+ * May return 0.
+ */
+static float
+QueryTrackers(DeviceVelocityPtr vel, int cur_t){
+    int n, offset, dir = 255, i = -1, age_ms;
+    /* initial velocity: a low-offset, valid velocity */
+    float iveloc = 0, res = 0, tmp, vdiff;
+    float vfac =  vel->corr_mul * vel->const_acceleration; /* premultiply */
+    /* loop from current to older data */
+    for(offset = 1; offset < vel->num_tracker; offset++){
+	n = TRACKER_INDEX(vel, offset);
+
+	age_ms = cur_t - vel->tracker[n].time;
+
+	/* bail out if data is too old and protect from overrun */
+	if (age_ms >= vel->reset_time || age_ms < 0) {
+	    DebugAccelF("(dix prtacc) query: tracker too old\n");
+	    break;
+	}
+
+	/*
+	 * this heuristic avoids using the linear-motion velocity formula
+	 * in CalcTracker() on motion that isn't exactly linear. So to get
+	 * even more precision we could subdivide as a final step, so possible
+	 * non-linearities are accounted for.
+	 */
+	dir &= vel->tracker[n].dir;
+	if(dir == 0){
+	    DebugAccelF("(dix prtacc) query: no longer linear\n");
+	    /* instead of breaking it we might also inspect the partition after,
+	     * but actual improvement with this is probably rare. */
+	    break;
+	}
+
+	tmp = CalcTracker(vel, offset, cur_t) * vfac;
+
+	if ((iveloc == 0 || offset <= vel->initial_range) && tmp != 0) {
+	    /* set initial velocity and result */
+	    res = iveloc = tmp;
+	    i = offset;
+	} else if (iveloc != 0 && tmp != 0) {
+	    vdiff = fabs(iveloc - tmp);
+	    if (vdiff <= vel->max_diff ||
+		vdiff/(iveloc + tmp) < vel->max_rel_diff) {
+		/* we're in range with the initial velocity,
+		 * so this result is likely better
+		 * (it contains more information). */
+		res = tmp;
+		i = offset;
+	    }else{
+		/* we're not in range, quit - it won't get better. */
+		DebugAccelF("(dix prtacc) query: tracker too different:"
+		            " old %2.2f initial %2.2f diff: %2.2f\n",
+		            tmp, iveloc, vdiff);
+		break;
+	    }
+	}
+    }
+    if(offset == vel->num_tracker){
+	DebugAccelF("(dix prtacc) query: last tracker in effect\n");
+	i = vel->num_tracker-1;
+    }
+    if(i>=0){
+        n = TRACKER_INDEX(vel, i);
+	DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
+	            i,
+	            vel->tracker[n].dx,
+	            vel->tracker[n].dy,
+	            cur_t - vel->tracker[n].time);
+    }
+    return res;
+}
+
+#undef TRACKER_INDEX
+
+/**
+ * Perform velocity approximation based on 2D 'mickeys' (mouse motion delta).
+ * return true if non-visible state reset is suggested
+ */
+short
+ProcessVelocityData2D(
+    DeviceVelocityPtr vel,
+    int dx,
+    int dy,
+    int time)
+{
+    float velocity;
+
+    vel->last_velocity = vel->velocity;
+
+    FeedTrackers(vel, dx, dy, time);
+
+    velocity = QueryTrackers(vel, time);
+
+    vel->velocity = velocity;
+    return velocity == 0;
+}
+
+/**
+ * this flattens significant ( > 1) mickeys a little bit for more steady
+ * constant-velocity response
+ */
+static inline float
+ApplySimpleSoftening(int od, int d)
+{
+    float res = d;
+    if (d <= 1 && d >= -1)
+        return res;
+    if (d > od)
+        res -= 0.5;
+    else if (d < od)
+        res += 0.5;
+    return res;
+}
+
+
+static void
+ApplySofteningAndConstantDeceleration(
+        DeviceVelocityPtr vel,
+        int dx,
+        int dy,
+        float* fdx,
+        float* fdy,
+        short do_soften)
+{
+    if (do_soften && vel->use_softening) {
+        *fdx = ApplySimpleSoftening(vel->last_dx, dx);
+        *fdy = ApplySimpleSoftening(vel->last_dy, dy);
+    } else {
+        *fdx = dx;
+        *fdy = dy;
+    }
+
+    *fdx *= vel->const_acceleration;
+    *fdy *= vel->const_acceleration;
+}
+
+/*
+ * compute the acceleration for given velocity and enforce min_acceleartion
+ */
+float
+BasicComputeAcceleration(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float velocity,
+    float threshold,
+    float acc){
+
+    float result;
+    result = vel->Profile(dev, vel, velocity, threshold, acc);
+
+    /* enforce min_acceleration */
+    if (result < vel->min_acceleration)
+	result = vel->min_acceleration;
+    return result;
+}
+
+/**
+ * Compute acceleration. Takes into account averaging, nv-reset, etc.
+ */
+static float
+ComputeAcceleration(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float threshold,
+    float acc){
+    float res;
+
+    if(vel->velocity <= 0){
+	DebugAccelF("(dix ptracc) profile skipped\n");
+        /*
+         * If we have no idea about device velocity, don't pretend it.
+         */
+	return 1;
+    }
+
+    if(vel->average_accel && vel->velocity != vel->last_velocity){
+	/* use simpson's rule to average acceleration between
+	 * current and previous velocity.
+	 * Though being the more natural choice, it causes a minor delay
+	 * in comparison, so it can be disabled. */
+	res = BasicComputeAcceleration(
+	          dev, vel, vel->velocity, threshold, acc);
+	res += BasicComputeAcceleration(
+	          dev, vel, vel->last_velocity, threshold, acc);
+	res += 4.0f * BasicComputeAcceleration(dev, vel,
+	                   (vel->last_velocity + vel->velocity) / 2,
+	                   threshold, acc);
+	res /= 6.0f;
+	DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
+	            vel->velocity, vel->last_velocity, res);
+        return res;
+    }else{
+	res = BasicComputeAcceleration(dev, vel,
+	                               vel->velocity, threshold, acc);
+	DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
+               vel->velocity, res);
+	return res;
+    }
+}
+
+
+/*****************************************
+ *  Acceleration functions and profiles
+ ****************************************/
+
+/**
+ * Polynomial function similar previous one, but with f(1) = 1
+ */
+static float
+PolynomialAccelerationProfile(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float velocity,
+    float ignored,
+    float acc)
+{
+   return pow(velocity, (acc - 1.0) * 0.5);
+}
+
+
+/**
+ * returns acceleration for velocity.
+ * This profile selects the two functions like the old scheme did
+ */
+static float
+ClassicProfile(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float velocity,
+    float threshold,
+    float acc)
+{
+    if (threshold > 0) {
+	return SimpleSmoothProfile (dev,
+	                            vel,
+	                            velocity,
+                                    threshold,
+                                    acc);
+    } else {
+	return PolynomialAccelerationProfile (dev,
+	                                      vel,
+	                                      velocity,
+                                              0,
+                                              acc);
+    }
+}
+
+
+/**
+ * Power profile
+ * This has a completely smooth transition curve, i.e. no jumps in the
+ * derivatives.
+ *
+ * This has the expense of overall response dependency on min-acceleration.
+ * In effect, min_acceleration mimics const_acceleration in this profile.
+ */
+static float
+PowerProfile(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float velocity,
+    float threshold,
+    float acc)
+{
+    float vel_dist;
+
+    acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */
+
+    if (velocity <= threshold)
+        return vel->min_acceleration;
+    vel_dist = velocity - threshold;
+    return (pow(acc, vel_dist)) * vel->min_acceleration;
+}
+
+
+/**
+ * just a smooth function in [0..1] -> [0..1]
+ *  - point symmetry at 0.5
+ *  - f'(0) = f'(1) = 0
+ *  - starts faster than a sinoid
+ *  - smoothness C1 (Cinf if you dare to ignore endpoints)
+ */
+static inline float
+CalcPenumbralGradient(float x){
+    x *= 2.0f;
+    x -= 1.0f;
+    return 0.5f + (x * sqrt(1.0f - x*x) + asin(x))/M_PI;
+}
+
+
+/**
+ * acceleration function similar to classic accelerated/unaccelerated,
+ * but with smooth transition in between (and towards zero for adaptive dec.).
+ */
+static float
+SimpleSmoothProfile(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float velocity,
+    float threshold,
+    float acc)
+{
+    if(velocity < 1.0f)
+        return CalcPenumbralGradient(0.5 + velocity*0.5) * 2.0f - 1.0f;
+    if(threshold < 1.0f)
+        threshold = 1.0f;
+    if (velocity <= threshold)
+        return 1;
+    velocity /= threshold;
+    if (velocity >= acc)
+        return acc;
+    else
+        return 1.0f + (CalcPenumbralGradient(velocity/acc) * (acc - 1.0f));
+}
+
+
+/**
+ * This profile uses the first half of the penumbral gradient as a start
+ * and then scales linearly.
+ */
+static float
+SmoothLinearProfile(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float velocity,
+    float threshold,
+    float acc)
+{
+    float res, nv;
+
+    if(acc > 1.0f)
+        acc -= 1.0f; /*this is so acc = 1 is no acceleration */
+    else
+        return 1.0f;
+
+    nv = (velocity - threshold) * acc * 0.5f;
+
+    if(nv < 0){
+        res = 0;
+    }else if(nv < 2){
+        res = CalcPenumbralGradient(nv*0.25f)*2.0f;
+    }else{
+        nv -= 2.0f;
+        res = nv * 2.0f / M_PI  /* steepness of gradient at 0.5 */
+              + 1.0f; /* gradient crosses 2|1 */
+    }
+    res += vel->min_acceleration;
+    return res;
+}
+
+
+/**
+ * From 0 to threshold, the response graduates smoothly from min_accel to
+ * acceleration. Beyond threshold it is exactly the specified acceleration.
+ */
+static float
+SmoothLimitedProfile(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float velocity,
+    float threshold,
+    float acc)
+{
+    float res;
+
+    if(velocity >= threshold || threshold == 0.0f)
+	return acc;
+
+    velocity /= threshold; /* should be [0..1[ now */
+
+    res = CalcPenumbralGradient(velocity) * (acc - vel->min_acceleration);
+
+    return vel->min_acceleration + res;
+}
+
+
+static float
+LinearProfile(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float velocity,
+    float threshold,
+    float acc)
+{
+    return acc * velocity;
+}
+
+static float
+NoProfile(
+    DeviceIntPtr dev,
+    DeviceVelocityPtr vel,
+    float velocity,
+    float threshold,
+    float acc)
+{
+    return 1.0f;
+}
+
+static PointerAccelerationProfileFunc
+GetAccelerationProfile(
+    DeviceVelocityPtr vel,
+    int profile_num)
+{
+    switch(profile_num){
+        case AccelProfileClassic:
+            return ClassicProfile;
+        case AccelProfileDeviceSpecific:
+            return vel->deviceSpecificProfile;
+        case AccelProfilePolynomial:
+            return PolynomialAccelerationProfile;
+        case AccelProfileSmoothLinear:
+            return SmoothLinearProfile;
+        case AccelProfileSimple:
+            return SimpleSmoothProfile;
+        case AccelProfilePower:
+            return PowerProfile;
+        case AccelProfileLinear:
+            return LinearProfile;
+        case AccelProfileSmoothLimited:
+            return SmoothLimitedProfile;
+        case AccelProfileNone:
+            return NoProfile;
+        default:
+            return NULL;
+    }
+}
+
+/**
+ * Set the profile by number.
+ * Intended to make profiles exchangeable at runtime.
+ * If you created a profile, give it a number here and in the header to
+ * make it selectable. In case some profile-specific init is needed, here
+ * would be a good place, since FreeVelocityData() also calls this with
+ * PROFILE_UNINITIALIZE.
+ *
+ * returns FALSE if profile number is unavailable, TRUE otherwise.
+ */
+int
+SetAccelerationProfile(
+    DeviceVelocityPtr vel,
+    int profile_num)
+{
+    PointerAccelerationProfileFunc profile;
+    profile = GetAccelerationProfile(vel, profile_num);
+
+    if(profile == NULL && profile_num != PROFILE_UNINITIALIZE)
+	return FALSE;
+
+    /* Here one could free old profile-private data */
+    free(vel->profile_private);
+    vel->profile_private = NULL;
+    /* Here one could init profile-private data */
+    vel->Profile = profile;
+    vel->statistics.profile_number = profile_num;
+    return TRUE;
+}
+
+/**********************************************
+ * driver interaction
+ **********************************************/
+
+
+/**
+ * device-specific profile
+ *
+ * The device-specific profile is intended as a hook for a driver
+ * which may want to provide an own acceleration profile.
+ * It should not rely on profile-private data, instead
+ * it should do init/uninit in the driver (ie. with DEVICE_INIT and friends).
+ * Users may override or choose it.
+ */
+void
+SetDeviceSpecificAccelerationProfile(
+        DeviceVelocityPtr vel,
+        PointerAccelerationProfileFunc profile)
+{
+    if(vel)
+	vel->deviceSpecificProfile = profile;
+}
+
+/**
+ * Use this function to obtain a DeviceVelocityPtr for a device. Will return NULL if
+ * the predictable acceleration scheme is not in effect.
+ */
+DeviceVelocityPtr
+GetDevicePredictableAccelData(
+	DeviceIntPtr dev)
+{
+    /*sanity check*/
+    if(!dev){
+	ErrorF("[dix] accel: DeviceIntPtr was NULL");
+	return NULL;
+    }
+    if( dev->valuator &&
+	dev->valuator->accelScheme.AccelSchemeProc ==
+	    acceleratePointerPredictable &&
+	dev->valuator->accelScheme.accelData != NULL){
+
+	return ((PredictableAccelSchemePtr)
+		dev->valuator->accelScheme.accelData)->vel;
+    }
+    return NULL;
+}
+
+/********************************
+ *  acceleration schemes
+ *******************************/
+
+/**
+ * Modifies valuators in-place.
+ * This version employs a velocity approximation algorithm to
+ * enable fine-grained predictable acceleration profiles.
+ */
+void
+acceleratePointerPredictable(
+    DeviceIntPtr dev,
+    ValuatorMask* val,
+    CARD32 evtime)
+{
+    float fdx, fdy, tmp, mult; /* no need to init */
+    int dx = 0, dy = 0, tmpi;
+    DeviceVelocityPtr velocitydata = GetDevicePredictableAccelData(dev);
+    Bool soften = TRUE;
+
+    if (!velocitydata)
+        return;
+
+    if (velocitydata->statistics.profile_number == AccelProfileNone &&
+        velocitydata->const_acceleration == 1.0f) {
+        return; /*we're inactive anyway, so skip the whole thing.*/
+    }
+
+    if (valuator_mask_isset(val, 0)) {
+        dx = valuator_mask_get(val, 0);
+    }
+
+    if (valuator_mask_isset(val, 1)) {
+        dy = valuator_mask_get(val, 1);
+    }
+
+    if (dx || dy){
+        /* reset non-visible state? */
+        if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) {
+            soften = FALSE;
+        }
+
+        if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
+            /* invoke acceleration profile to determine acceleration */
+            mult = ComputeAcceleration (dev, velocitydata,
+                                        dev->ptrfeed->ctrl.threshold,
+                                        (float)dev->ptrfeed->ctrl.num /
+                                            (float)dev->ptrfeed->ctrl.den);
+
+            if(mult != 1.0f || velocitydata->const_acceleration != 1.0f) {
+                ApplySofteningAndConstantDeceleration(velocitydata,
+                                                      dx, dy,
+                                                      &fdx, &fdy,
+                                                      (mult > 1.0f) && soften);
+
+                if (dx) {
+                    tmp = mult * fdx + dev->last.remainder[0];
+                    /* Since it may not be apparent: lrintf() does not offer
+                     * strong statements about rounding; however because we
+                     * process each axis conditionally, there's no danger
+                     * of a toggling remainder. Its lack of guarantees likely
+                     * makes it faster on the average target. */
+                    tmpi = lrintf(tmp);
+                    valuator_mask_set(val, 0, tmpi);
+                    dev->last.remainder[0] = tmp - (float)tmpi;
+                }
+                if (dy) {
+                    tmp = mult * fdy + dev->last.remainder[1];
+                    tmpi = lrintf(tmp);
+                    valuator_mask_set(val, 1, tmpi);
+                    dev->last.remainder[1] = tmp - (float)tmpi;
+                }
+                DebugAccelF("pos (%i | %i) remainders x: %.3f y: %.3f delta x:%.3f y:%.3f\n",
+                            *px, *py, dev->last.remainder[0], dev->last.remainder[1], fdx, fdy);
+            }
+        }
+    }
+    /* remember last motion delta (for softening/slow movement treatment) */
+    velocitydata->last_dx = dx;
+    velocitydata->last_dy = dy;
+}
+
+
+
+/**
+ * Originally a part of xf86PostMotionEvent; modifies valuators
+ * in-place. Retained mostly for embedded scenarios.
+ */
+void
+acceleratePointerLightweight(
+    DeviceIntPtr dev,
+    ValuatorMask* val,
+    CARD32 ignored)
+{
+    float mult = 0.0, tmpf;
+    int dx = 0, dy = 0, tmpi;
+
+    if (valuator_mask_isset(val, 0)) {
+        dx = valuator_mask_get(val, 0);
+    }
+
+    if (valuator_mask_isset(val, 1)) {
+        dy = valuator_mask_get(val, 1);
+    }
+
+    if (!dx && !dy)
+        return;
+
+    if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
+        /* modeled from xf86Events.c */
+        if (dev->ptrfeed->ctrl.threshold) {
+            if ((abs(dx) + abs(dy)) >= dev->ptrfeed->ctrl.threshold) {
+                tmpf = ((float)dx *
+                        (float)(dev->ptrfeed->ctrl.num)) /
+                       (float)(dev->ptrfeed->ctrl.den) +
+                       dev->last.remainder[0];
+                if (dx) {
+                    tmpi = (int) tmpf;
+                    valuator_mask_set(val, 0, tmpi);
+                    dev->last.remainder[0] = tmpf - (float)tmpi;
+                }
+
+                tmpf = ((float)dy *
+                        (float)(dev->ptrfeed->ctrl.num)) /
+                       (float)(dev->ptrfeed->ctrl.den) +
+                       dev->last.remainder[1];
+                if (dy) {
+                    tmpi = (int) tmpf;
+                    valuator_mask_set(val, 1, tmpi);
+                    dev->last.remainder[1] = tmpf - (float)tmpi;
+                }
+            }
+        }
+        else {
+            mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
+                       ((float)(dev->ptrfeed->ctrl.num) /
+                        (float)(dev->ptrfeed->ctrl.den) - 1.0) /
+                       2.0) / 2.0;
+            if (dx) {
+                tmpf = mult * (float)dx +
+                       dev->last.remainder[0];
+                tmpi = (int) tmpf;
+                valuator_mask_set(val, 0, tmpi);
+                dev->last.remainder[0] = tmpf - (float)tmpi;
+            }
+            if (dy) {
+                tmpf = mult * (float)dy +
+                       dev->last.remainder[1];
+                tmpi = (int)tmpf;
+                valuator_mask_set(val, 1, tmpi);
+                dev->last.remainder[1] = tmpf - (float)tmpi;
+            }
+        }
+    }
+}
diff --git a/xorg-server/fb/fbpict.c b/xorg-server/fb/fbpict.c
index 312f3df21..fb26632bd 100644
--- a/xorg-server/fb/fbpict.c
+++ b/xorg-server/fb/fbpict.c
@@ -1,373 +1,373 @@
-/*
- *
- * Copyright © 2000 SuSE, Inc.
- * Copyright © 2007 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  SuSE makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author:  Keith Packard, SuSE, Inc.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <string.h>
-
-#include "fb.h"
-
-#include "picturestr.h"
-#include "mipict.h"
-#include "fbpict.h"
-
-void
-fbComposite (CARD8      op,
-	     PicturePtr pSrc,
-	     PicturePtr pMask,
-	     PicturePtr pDst,
-	     INT16      xSrc,
-	     INT16      ySrc,
-	     INT16      xMask,
-	     INT16      yMask,
-	     INT16      xDst,
-	     INT16      yDst,
-	     CARD16     width,
-	     CARD16     height)
-{
-    pixman_image_t *src, *mask, *dest;
-    int src_xoff, src_yoff;
-    int msk_xoff, msk_yoff;
-    int dst_xoff, dst_yoff;
-    
-    miCompositeSourceValidate (pSrc, xSrc - xDst, ySrc - yDst, width, height);
-    if (pMask)
-	miCompositeSourceValidate (pMask, xMask - xDst, yMask - yDst, width, height);
-    
-    src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff);
-    mask = image_from_pict (pMask, FALSE, &msk_xoff, &msk_yoff);
-    dest = image_from_pict (pDst, TRUE, &dst_xoff, &dst_yoff);
-
-    if (src && dest && !(pMask && !mask))
-    {
-	pixman_image_composite (op, src, mask, dest,
-				xSrc + src_xoff, ySrc + src_yoff,
-				xMask + msk_xoff, yMask + msk_yoff,
-				xDst + dst_xoff, yDst + dst_yoff,
-				width, height);
-    }
-
-    free_pixman_pict (pSrc, src);
-    free_pixman_pict (pMask, mask);
-    free_pixman_pict (pDst, dest);
-}
-
-static pixman_image_t *
-create_solid_fill_image (PicturePtr pict)
-{
-    PictSolidFill *solid = &pict->pSourcePict->solidFill;
-    pixman_color_t color;
-    CARD32 a, r, g, b;
-    
-    a = (solid->color & 0xff000000) >> 24;
-    r = (solid->color & 0x00ff0000) >> 16;
-    g = (solid->color & 0x0000ff00) >>  8;
-    b = (solid->color & 0x000000ff) >>  0;
-    
-    color.alpha = (a << 8) | a;
-    color.red =   (r << 8) | r;
-    color.green = (g << 8) | g;
-    color.blue =  (b << 8) | b;
-    
-    return pixman_image_create_solid_fill (&color);
-}
-
-static pixman_image_t *
-create_linear_gradient_image (PictGradient *gradient)
-{
-    PictLinearGradient *linear = (PictLinearGradient *)gradient;
-    pixman_point_fixed_t p1;
-    pixman_point_fixed_t p2;
-    
-    p1.x = linear->p1.x;
-    p1.y = linear->p1.y;
-    p2.x = linear->p2.x;
-    p2.y = linear->p2.y;
-    
-    return pixman_image_create_linear_gradient (
-	&p1, &p2, (pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
-}
-
-static pixman_image_t *
-create_radial_gradient_image (PictGradient *gradient)
-{
-    PictRadialGradient *radial = (PictRadialGradient *)gradient;
-    pixman_point_fixed_t c1;
-    pixman_point_fixed_t c2;
-    
-    c1.x = radial->c1.x;
-    c1.y = radial->c1.y;
-    c2.x = radial->c2.x;
-    c2.y = radial->c2.y;
-    
-    return pixman_image_create_radial_gradient (
-	&c1, &c2, radial->c1.radius,
-	radial->c2.radius,
-	(pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
-}
-
-static pixman_image_t *
-create_conical_gradient_image (PictGradient *gradient)
-{
-    PictConicalGradient *conical = (PictConicalGradient *)gradient;
-    pixman_point_fixed_t center;
-    
-    center.x = conical->center.x;
-    center.y = conical->center.y;
-    
-    return pixman_image_create_conical_gradient (
-	&center, conical->angle, (pixman_gradient_stop_t *)gradient->stops,
-	gradient->nstops);
-}
-
-static pixman_image_t *
-create_bits_picture (PicturePtr pict,
-		     Bool       has_clip,
-		     int	*xoff,
-		     int	*yoff)
-{
-    PixmapPtr pixmap;
-    FbBits *bits;
-    FbStride stride;
-    int bpp;
-    pixman_image_t *image;
-    
-    fbGetDrawablePixmap (pict->pDrawable, pixmap, *xoff, *yoff);
-    fbGetPixmapBitsData(pixmap, bits, stride, bpp);
-
-    image = pixman_image_create_bits (
-	pict->format,
-	pixmap->drawable.width, pixmap->drawable.height,
-	(uint32_t *)bits, stride * sizeof (FbStride));
-    
-    
-#ifdef FB_ACCESS_WRAPPER
-#if FB_SHIFT==5
-    
-    pixman_image_set_accessors (image,
-				(pixman_read_memory_func_t)wfbReadMemory,
-				(pixman_write_memory_func_t)wfbWriteMemory);
-    
-#else
-    
-#error The pixman library only works when FbBits is 32 bits wide
-    
-#endif
-#endif
-    
-    /* pCompositeClip is undefined for source pictures, so
-     * only set the clip region for pictures with drawables
-     */
-    if (has_clip)
-    {
-	if (pict->clientClipType != CT_NONE)
-	    pixman_image_set_has_client_clip (image, TRUE);
-
-	if (*xoff || *yoff)
-	    pixman_region_translate (pict->pCompositeClip, *xoff, *yoff);
-
-	pixman_image_set_clip_region (image, pict->pCompositeClip);
-
-	if (*xoff || *yoff)
-	    pixman_region_translate (pict->pCompositeClip, -*xoff, -*yoff);
-    }
-    
-    /* Indexed table */
-    if (pict->pFormat->index.devPrivate)
-	pixman_image_set_indexed (image, pict->pFormat->index.devPrivate);
-
-    /* Add in drawable origin to position within the image */
-    *xoff += pict->pDrawable->x;
-    *yoff += pict->pDrawable->y;
-
-    return image;
-}
-
-static pixman_image_t *
-image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map);
-
-static void
-set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map)
-{
-    pixman_repeat_t repeat;
-    pixman_filter_t filter;
-    
-    if (pict->transform)
-    {
-	/* For source images, adjust the transform to account
-	 * for the drawable offset within the pixman image,
-	 * then set the offset to 0 as it will be used
-	 * to compute positions within the transformed image.
-	 */
-	if (!has_clip) {
-	    struct pixman_transform	adjusted;
-
-	    adjusted = *pict->transform;
-	    pixman_transform_translate(&adjusted,
-				       NULL,
-				       pixman_int_to_fixed(*xoff),
-				       pixman_int_to_fixed(*yoff));
-	    pixman_image_set_transform (image, &adjusted);
-	    *xoff = 0;
-	    *yoff = 0;
-	} else
-	    pixman_image_set_transform (image, pict->transform);
-    }
-    
-    switch (pict->repeatType)
-    {
-    default:
-    case RepeatNone:
-	repeat = PIXMAN_REPEAT_NONE;
-	break;
-	
-    case RepeatPad:
-	repeat = PIXMAN_REPEAT_PAD;
-	break;
-	
-    case RepeatNormal:
-	repeat = PIXMAN_REPEAT_NORMAL;
-	break;
-	
-    case RepeatReflect:
-	repeat = PIXMAN_REPEAT_REFLECT;
-	break;
-    }
-    
-    pixman_image_set_repeat (image, repeat);
-    
-    /* Fetch alpha map unless 'pict' is being used
-     * as the alpha map for this operation
-     */
-    if (pict->alphaMap && !is_alpha_map)
-    {
-	int alpha_xoff, alpha_yoff;
-	pixman_image_t *alpha_map = image_from_pict_internal (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff, TRUE);
-	
-	pixman_image_set_alpha_map (
-	    image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
-	
-	free_pixman_pict (pict->alphaMap, alpha_map);
-    }
-    
-    pixman_image_set_component_alpha (image, pict->componentAlpha);
-
-    switch (pict->filter)
-    {
-    default:
-    case PictFilterNearest:
-    case PictFilterFast:
-	filter = PIXMAN_FILTER_NEAREST;
-	break;
-	
-    case PictFilterBilinear:
-    case PictFilterGood:
-	filter = PIXMAN_FILTER_BILINEAR;
-	break;
-	
-    case PictFilterConvolution:
-	filter = PIXMAN_FILTER_CONVOLUTION;
-	break;
-    }
-    
-    pixman_image_set_filter (image, filter, (pixman_fixed_t *)pict->filter_params, pict->filter_nparams);
-    pixman_image_set_source_clipping (image, TRUE);
-}
-
-static pixman_image_t *
-image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map)
-{
-    pixman_image_t *image = NULL;
-
-    if (!pict)
-	return NULL;
-
-    if (pict->pDrawable)
-    {
-	image = create_bits_picture (pict, has_clip, xoff, yoff);
-    }
-    else if (pict->pSourcePict)
-    {
-	SourcePict *sp = pict->pSourcePict;
-	
-	if (sp->type == SourcePictTypeSolidFill)
-	{
-	    image = create_solid_fill_image (pict);
-	}
-	else
-	{
-	    PictGradient *gradient = &pict->pSourcePict->gradient;
-	    
-	    if (sp->type == SourcePictTypeLinear)
-		image = create_linear_gradient_image (gradient);
-	    else if (sp->type == SourcePictTypeRadial)
-		image = create_radial_gradient_image (gradient);
-	    else if (sp->type == SourcePictTypeConical)
-		image = create_conical_gradient_image (gradient);
-	}
-	*xoff = *yoff = 0;
-    }
-    
-    if (image)
-	set_image_properties (image, pict, has_clip, xoff, yoff, is_alpha_map);
-    
-    return image;
-}
-
-pixman_image_t *
-image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
-{
-    return image_from_pict_internal (pict, has_clip, xoff, yoff, FALSE);
-}
-
-void
-free_pixman_pict (PicturePtr pict, pixman_image_t *image)
-{
-    if (image && pixman_image_unref (image) && pict->pDrawable)
-	fbFinishAccess (pict->pDrawable);
-}
-
-Bool
-fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
-{
-
-    PictureScreenPtr    ps;
-
-    if (!miPictureInit (pScreen, formats, nformats))
-	return FALSE;
-    ps = GetPictureScreen(pScreen);
-    ps->Composite = fbComposite;
-    ps->Glyphs = miGlyphs;
-    ps->CompositeRects = miCompositeRects;
-    ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
-    ps->Trapezoids = fbTrapezoids;
-    ps->AddTraps = fbAddTraps;
-    ps->AddTriangles = fbAddTriangles;
-    ps->Triangles = fbTriangles;
-
-    return TRUE;
-}
+/*
+ *
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Keith Packard, SuSE, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include "fb.h"
+
+#include "picturestr.h"
+#include "mipict.h"
+#include "fbpict.h"
+
+void
+fbComposite (CARD8      op,
+	     PicturePtr pSrc,
+	     PicturePtr pMask,
+	     PicturePtr pDst,
+	     INT16      xSrc,
+	     INT16      ySrc,
+	     INT16      xMask,
+	     INT16      yMask,
+	     INT16      xDst,
+	     INT16      yDst,
+	     CARD16     width,
+	     CARD16     height)
+{
+    pixman_image_t *src, *mask, *dest;
+    int src_xoff, src_yoff;
+    int msk_xoff, msk_yoff;
+    int dst_xoff, dst_yoff;
+    
+    miCompositeSourceValidate (pSrc);
+    if (pMask)
+	miCompositeSourceValidate (pMask);
+    
+    src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff);
+    mask = image_from_pict (pMask, FALSE, &msk_xoff, &msk_yoff);
+    dest = image_from_pict (pDst, TRUE, &dst_xoff, &dst_yoff);
+
+    if (src && dest && !(pMask && !mask))
+    {
+	pixman_image_composite (op, src, mask, dest,
+				xSrc + src_xoff, ySrc + src_yoff,
+				xMask + msk_xoff, yMask + msk_yoff,
+				xDst + dst_xoff, yDst + dst_yoff,
+				width, height);
+    }
+
+    free_pixman_pict (pSrc, src);
+    free_pixman_pict (pMask, mask);
+    free_pixman_pict (pDst, dest);
+}
+
+static pixman_image_t *
+create_solid_fill_image (PicturePtr pict)
+{
+    PictSolidFill *solid = &pict->pSourcePict->solidFill;
+    pixman_color_t color;
+    CARD32 a, r, g, b;
+    
+    a = (solid->color & 0xff000000) >> 24;
+    r = (solid->color & 0x00ff0000) >> 16;
+    g = (solid->color & 0x0000ff00) >>  8;
+    b = (solid->color & 0x000000ff) >>  0;
+    
+    color.alpha = (a << 8) | a;
+    color.red =   (r << 8) | r;
+    color.green = (g << 8) | g;
+    color.blue =  (b << 8) | b;
+    
+    return pixman_image_create_solid_fill (&color);
+}
+
+static pixman_image_t *
+create_linear_gradient_image (PictGradient *gradient)
+{
+    PictLinearGradient *linear = (PictLinearGradient *)gradient;
+    pixman_point_fixed_t p1;
+    pixman_point_fixed_t p2;
+    
+    p1.x = linear->p1.x;
+    p1.y = linear->p1.y;
+    p2.x = linear->p2.x;
+    p2.y = linear->p2.y;
+    
+    return pixman_image_create_linear_gradient (
+	&p1, &p2, (pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
+}
+
+static pixman_image_t *
+create_radial_gradient_image (PictGradient *gradient)
+{
+    PictRadialGradient *radial = (PictRadialGradient *)gradient;
+    pixman_point_fixed_t c1;
+    pixman_point_fixed_t c2;
+    
+    c1.x = radial->c1.x;
+    c1.y = radial->c1.y;
+    c2.x = radial->c2.x;
+    c2.y = radial->c2.y;
+    
+    return pixman_image_create_radial_gradient (
+	&c1, &c2, radial->c1.radius,
+	radial->c2.radius,
+	(pixman_gradient_stop_t *)gradient->stops, gradient->nstops);
+}
+
+static pixman_image_t *
+create_conical_gradient_image (PictGradient *gradient)
+{
+    PictConicalGradient *conical = (PictConicalGradient *)gradient;
+    pixman_point_fixed_t center;
+    
+    center.x = conical->center.x;
+    center.y = conical->center.y;
+    
+    return pixman_image_create_conical_gradient (
+	&center, conical->angle, (pixman_gradient_stop_t *)gradient->stops,
+	gradient->nstops);
+}
+
+static pixman_image_t *
+create_bits_picture (PicturePtr pict,
+		     Bool       has_clip,
+		     int	*xoff,
+		     int	*yoff)
+{
+    PixmapPtr pixmap;
+    FbBits *bits;
+    FbStride stride;
+    int bpp;
+    pixman_image_t *image;
+    
+    fbGetDrawablePixmap (pict->pDrawable, pixmap, *xoff, *yoff);
+    fbGetPixmapBitsData(pixmap, bits, stride, bpp);
+
+    image = pixman_image_create_bits (
+	pict->format,
+	pixmap->drawable.width, pixmap->drawable.height,
+	(uint32_t *)bits, stride * sizeof (FbStride));
+    
+    
+#ifdef FB_ACCESS_WRAPPER
+#if FB_SHIFT==5
+    
+    pixman_image_set_accessors (image,
+				(pixman_read_memory_func_t)wfbReadMemory,
+				(pixman_write_memory_func_t)wfbWriteMemory);
+    
+#else
+    
+#error The pixman library only works when FbBits is 32 bits wide
+    
+#endif
+#endif
+    
+    /* pCompositeClip is undefined for source pictures, so
+     * only set the clip region for pictures with drawables
+     */
+    if (has_clip)
+    {
+	if (pict->clientClipType != CT_NONE)
+	    pixman_image_set_has_client_clip (image, TRUE);
+
+	if (*xoff || *yoff)
+	    pixman_region_translate (pict->pCompositeClip, *xoff, *yoff);
+
+	pixman_image_set_clip_region (image, pict->pCompositeClip);
+
+	if (*xoff || *yoff)
+	    pixman_region_translate (pict->pCompositeClip, -*xoff, -*yoff);
+    }
+    
+    /* Indexed table */
+    if (pict->pFormat->index.devPrivate)
+	pixman_image_set_indexed (image, pict->pFormat->index.devPrivate);
+
+    /* Add in drawable origin to position within the image */
+    *xoff += pict->pDrawable->x;
+    *yoff += pict->pDrawable->y;
+
+    return image;
+}
+
+static pixman_image_t *
+image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map);
+
+static void
+set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map)
+{
+    pixman_repeat_t repeat;
+    pixman_filter_t filter;
+    
+    if (pict->transform)
+    {
+	/* For source images, adjust the transform to account
+	 * for the drawable offset within the pixman image,
+	 * then set the offset to 0 as it will be used
+	 * to compute positions within the transformed image.
+	 */
+	if (!has_clip) {
+	    struct pixman_transform	adjusted;
+
+	    adjusted = *pict->transform;
+	    pixman_transform_translate(&adjusted,
+				       NULL,
+				       pixman_int_to_fixed(*xoff),
+				       pixman_int_to_fixed(*yoff));
+	    pixman_image_set_transform (image, &adjusted);
+	    *xoff = 0;
+	    *yoff = 0;
+	} else
+	    pixman_image_set_transform (image, pict->transform);
+    }
+    
+    switch (pict->repeatType)
+    {
+    default:
+    case RepeatNone:
+	repeat = PIXMAN_REPEAT_NONE;
+	break;
+	
+    case RepeatPad:
+	repeat = PIXMAN_REPEAT_PAD;
+	break;
+	
+    case RepeatNormal:
+	repeat = PIXMAN_REPEAT_NORMAL;
+	break;
+	
+    case RepeatReflect:
+	repeat = PIXMAN_REPEAT_REFLECT;
+	break;
+    }
+    
+    pixman_image_set_repeat (image, repeat);
+    
+    /* Fetch alpha map unless 'pict' is being used
+     * as the alpha map for this operation
+     */
+    if (pict->alphaMap && !is_alpha_map)
+    {
+	int alpha_xoff, alpha_yoff;
+	pixman_image_t *alpha_map = image_from_pict_internal (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff, TRUE);
+	
+	pixman_image_set_alpha_map (
+	    image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
+	
+	free_pixman_pict (pict->alphaMap, alpha_map);
+    }
+    
+    pixman_image_set_component_alpha (image, pict->componentAlpha);
+
+    switch (pict->filter)
+    {
+    default:
+    case PictFilterNearest:
+    case PictFilterFast:
+	filter = PIXMAN_FILTER_NEAREST;
+	break;
+	
+    case PictFilterBilinear:
+    case PictFilterGood:
+	filter = PIXMAN_FILTER_BILINEAR;
+	break;
+	
+    case PictFilterConvolution:
+	filter = PIXMAN_FILTER_CONVOLUTION;
+	break;
+    }
+    
+    pixman_image_set_filter (image, filter, (pixman_fixed_t *)pict->filter_params, pict->filter_nparams);
+    pixman_image_set_source_clipping (image, TRUE);
+}
+
+static pixman_image_t *
+image_from_pict_internal (PicturePtr pict, Bool has_clip, int *xoff, int *yoff, Bool is_alpha_map)
+{
+    pixman_image_t *image = NULL;
+
+    if (!pict)
+	return NULL;
+
+    if (pict->pDrawable)
+    {
+	image = create_bits_picture (pict, has_clip, xoff, yoff);
+    }
+    else if (pict->pSourcePict)
+    {
+	SourcePict *sp = pict->pSourcePict;
+	
+	if (sp->type == SourcePictTypeSolidFill)
+	{
+	    image = create_solid_fill_image (pict);
+	}
+	else
+	{
+	    PictGradient *gradient = &pict->pSourcePict->gradient;
+	    
+	    if (sp->type == SourcePictTypeLinear)
+		image = create_linear_gradient_image (gradient);
+	    else if (sp->type == SourcePictTypeRadial)
+		image = create_radial_gradient_image (gradient);
+	    else if (sp->type == SourcePictTypeConical)
+		image = create_conical_gradient_image (gradient);
+	}
+	*xoff = *yoff = 0;
+    }
+    
+    if (image)
+	set_image_properties (image, pict, has_clip, xoff, yoff, is_alpha_map);
+    
+    return image;
+}
+
+pixman_image_t *
+image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
+{
+    return image_from_pict_internal (pict, has_clip, xoff, yoff, FALSE);
+}
+
+void
+free_pixman_pict (PicturePtr pict, pixman_image_t *image)
+{
+    if (image && pixman_image_unref (image) && pict->pDrawable)
+	fbFinishAccess (pict->pDrawable);
+}
+
+Bool
+fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+
+    PictureScreenPtr    ps;
+
+    if (!miPictureInit (pScreen, formats, nformats))
+	return FALSE;
+    ps = GetPictureScreen(pScreen);
+    ps->Composite = fbComposite;
+    ps->Glyphs = miGlyphs;
+    ps->CompositeRects = miCompositeRects;
+    ps->RasterizeTrapezoid = fbRasterizeTrapezoid;
+    ps->Trapezoids = fbTrapezoids;
+    ps->AddTraps = fbAddTraps;
+    ps->AddTriangles = fbAddTriangles;
+    ps->Triangles = fbTriangles;
+
+    return TRUE;
+}
diff --git a/xorg-server/glx/glxdri.c b/xorg-server/glx/glxdri.c
index e0713b8a1..b394cdedc 100644
--- a/xorg-server/glx/glxdri.c
+++ b/xorg-server/glx/glxdri.c
@@ -858,8 +858,6 @@ static const __DRIextension *loader_extensions[] = {
 
 
 
-static const char dri_driver_path[] = DRI_DRIVER_PATH;
-
 static Bool
 glxDRIEnterVT (int index, int flags)
 {
@@ -971,13 +969,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     drm_handle_t  hFB;
     int        junk;
     __GLXDRIscreen *screen;
-    char filename[128];
     Bool isCapable;
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     const __DRIconfig **driConfigs;
-    const __DRIextension **extensions;
-    int i;
 
     if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
 	!DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
@@ -1052,42 +1047,15 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 	goto handle_error;
     }
 
-    snprintf(filename, sizeof filename, "%s/%s_dri.so",
-             dri_driver_path, driverName);
-
-    screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+    screen->driver = glxProbeDriver(driverName,
+				    (void **)&screen->core,
+				    __DRI_CORE, __DRI_CORE_VERSION,
+				    (void **)&screen->legacy,
+				    __DRI_LEGACY, __DRI_LEGACY_VERSION);
     if (screen->driver == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
-		   filename, dlerror());
         goto handle_error;
     }
-
-    extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
-    if (extensions == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
-		   driverName, dlerror());
-	goto handle_error;
-    }
     
-    for (i = 0; extensions[i]; i++) {
-	if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
-	    extensions[i]->version >= __DRI_CORE_VERSION) {
-		screen->core = (__DRIcoreExtension *) extensions[i];
-	}
-
-	if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0 &&
-	    extensions[i]->version >= __DRI_LEGACY_VERSION) {
-		screen->legacy = (__DRIlegacyExtension *) extensions[i];
-	}
-    }
-
-    if (screen->core == NULL || screen->legacy == NULL) {
-	LogMessage(X_ERROR,
-		   "AIGLX error: %s does not export required DRI extension\n",
-		   driverName);
-	goto handle_error;
-    }
-
     /*
      * Get device-specific info.  pDevPriv will point to a struct
      * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
@@ -1172,7 +1140,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     pScrn->LeaveVT = glxDRILeaveVT;
 
     LogMessage(X_INFO,
-	       "AIGLX: Loaded and initialized %s\n", filename);
+	       "AIGLX: Loaded and initialized %s\n", driverName);
 
     return &screen->base;
 
diff --git a/xorg-server/glx/glxdri2.c b/xorg-server/glx/glxdri2.c
index c9c316be5..9d4aeab23 100644
--- a/xorg-server/glx/glxdri2.c
+++ b/xorg-server/glx/glxdri2.c
@@ -599,8 +599,6 @@ static const __DRIextension *loader_extensions[] = {
     NULL
 };
 
-static const char dri_driver_path[] = DRI_DRIVER_PATH;
-
 static Bool
 glxDRIEnterVT (int index, int flags)
 {
@@ -702,12 +700,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 {
     const char *driverName, *deviceName;
     __GLXDRIscreen *screen;
-    char filename[128];
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    const __DRIextension **extensions;
     const __DRIconfig **driConfigs;
-    int i;
 
     screen = calloc(1, sizeof *screen);
     if (screen == NULL)
@@ -729,40 +724,12 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
 
     __glXInitExtensionEnableBits(screen->glx_enable_bits);
 
-    snprintf(filename, sizeof filename,
-	     "%s/%s_dri.so", dri_driver_path, driverName);
-
-    screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+    screen->driver = glxProbeDriver(driverName, (void **)&screen->core, __DRI_CORE, 1,
+				    (void **)&screen->dri2, __DRI_DRI2, 1);
     if (screen->driver == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
-		   filename, dlerror());
         goto handle_error;
     }
-
-    extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
-    if (extensions == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
-		   driverName, dlerror());
-	goto handle_error;
-    }
     
-    for (i = 0; extensions[i]; i++) {
-        if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
-	    extensions[i]->version >= 1) {
-		screen->core = (const __DRIcoreExtension *) extensions[i];
-	}
-        if (strcmp(extensions[i]->name, __DRI_DRI2) == 0 &&
-	    extensions[i]->version >= 1) {
-		screen->dri2 = (const __DRIdri2Extension *) extensions[i];
-	}
-    }
-
-    if (screen->core == NULL || screen->dri2 == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n",
-		   driverName);
-	goto handle_error;
-    }
-
     screen->driScreen =
 	(*screen->dri2->createNewScreen)(pScreen->myNum,
 					 screen->fd,
@@ -816,7 +783,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     pScrn->LeaveVT = glxDRILeaveVT;
 
     LogMessage(X_INFO,
-	       "AIGLX: Loaded and initialized %s\n", filename);
+	       "AIGLX: Loaded and initialized %s\n", driverName);
 
     return &screen->base;
 
diff --git a/xorg-server/glx/glxdricommon.c b/xorg-server/glx/glxdricommon.c
index 44078fb41..2fcda8fb8 100644
--- a/xorg-server/glx/glxdricommon.c
+++ b/xorg-server/glx/glxdricommon.c
@@ -29,6 +29,7 @@
 
 #include <stdint.h>
 #include <errno.h>
+#include <dlfcn.h>
 #include <sys/time.h>
 #include <GL/gl.h>
 #include <GL/glxtokens.h>
@@ -204,3 +205,59 @@ glxConvertConfigs(const __DRIcoreExtension *core,
 
     return head.next;
 }
+
+static const char dri_driver_path[] = DRI_DRIVER_PATH;
+
+void *
+glxProbeDriver(const char *driverName,
+	       void **coreExt, const char *coreName, int coreVersion,
+	       void **renderExt, const char *renderName, int renderVersion)
+{
+    int i;
+    void *driver;
+    char filename[PATH_MAX];
+    const __DRIextension **extensions;
+
+    snprintf(filename, sizeof filename, "%s/%s_dri.so",
+             dri_driver_path, driverName);
+
+    driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+    if (driver == NULL) {
+	LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
+		   filename, dlerror());
+	goto cleanup_failure;
+    }
+
+    extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
+    if (extensions == NULL) {
+	LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
+		   driverName, dlerror());
+	goto cleanup_failure;
+    }
+
+    for (i = 0; extensions[i]; i++) {
+	if (strcmp(extensions[i]->name, coreName) == 0 &&
+	    extensions[i]->version >= coreVersion) {
+		*coreExt = (void *)extensions[i];
+	}
+
+	if (strcmp(extensions[i]->name, renderName) == 0 &&
+	    extensions[i]->version >= renderVersion) {
+		*renderExt = (void *)extensions[i];
+	}
+    }
+
+    if (*coreExt == NULL || *renderExt == NULL) {
+	LogMessage(X_ERROR,
+		   "AIGLX error: %s does not export required DRI extension\n",
+		   driverName);
+	goto cleanup_failure;
+    }
+    return driver;
+
+cleanup_failure:
+    if (driver)
+	dlclose(driver);
+    *coreExt = *renderExt = NULL;
+    return NULL;
+}
diff --git a/xorg-server/glx/glxdricommon.h b/xorg-server/glx/glxdricommon.h
index 41e2d2770..ef7b531f6 100644
--- a/xorg-server/glx/glxdricommon.h
+++ b/xorg-server/glx/glxdricommon.h
@@ -1,41 +1,46 @@
-/*
- * Copyright © 2008 Red Hat, Inc
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without
- * fee, provided that the above copyright notice appear in all copies
- * and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the name of the
- * copyright holders not be used in advertising or publicity
- * pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no
- * representations about the suitability of this software for any
- * purpose.  It is provided "as is" without express or implied
- * warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-#ifndef _GLX_dri_common_h
-#define _GLX_dri_common_h
-
-typedef struct __GLXDRIconfig	__GLXDRIconfig;
-struct __GLXDRIconfig {
-    __GLXconfig config;
-    const __DRIconfig *driConfig;
-};
-
-__GLXconfig *
-glxConvertConfigs(const __DRIcoreExtension *core,
-		  const __DRIconfig **configs, unsigned int drawableType);
-
-extern const __DRIsystemTimeExtension systemTimeExtension;
-
-#endif
+/*
+ * Copyright © 2008 Red Hat, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifndef _GLX_dri_common_h
+#define _GLX_dri_common_h
+
+typedef struct __GLXDRIconfig	__GLXDRIconfig;
+struct __GLXDRIconfig {
+    __GLXconfig config;
+    const __DRIconfig *driConfig;
+};
+
+__GLXconfig *
+glxConvertConfigs(const __DRIcoreExtension *core,
+		  const __DRIconfig **configs, unsigned int drawableType);
+
+extern const __DRIsystemTimeExtension systemTimeExtension;
+
+void *
+glxProbeDriver(const char *name,
+	       void **coreExt, const char *coreName, int coreVersion,
+	       void **renderExt, const char *renderName, int renderVersion);
+
+#endif
diff --git a/xorg-server/glx/glxdriswrast.c b/xorg-server/glx/glxdriswrast.c
index 30ce19ed1..fb2316a62 100644
--- a/xorg-server/glx/glxdriswrast.c
+++ b/xorg-server/glx/glxdriswrast.c
@@ -201,6 +201,14 @@ __glXDRIbindTexImage(__GLXcontext *baseContext,
     if (texBuffer == NULL)
         return Success;
 
+#if __DRI_TEX_BUFFER_VERSION >= 2
+    if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) {
+	(*texBuffer->setTexBuffer2)(context->driContext,
+				    glxPixmap->target,
+				    glxPixmap->format,
+				    drawable->driDrawable);
+    } else
+#endif
     texBuffer->setTexBuffer(context->driContext,
 			    glxPixmap->target,
 			    drawable->driDrawable);
@@ -427,17 +435,12 @@ initializeExtensions(__GLXDRIscreen *screen)
     }
 }
 
-static const char dri_driver_path[] = DRI_DRIVER_PATH;
-
 static __GLXscreen *
 __glXDRIscreenProbe(ScreenPtr pScreen)
 {
     const char *driverName = "swrast";
     __GLXDRIscreen *screen;
-    char filename[128];
-    const __DRIextension **extensions;
     const __DRIconfig **driConfigs;
-    int i;
 
     screen = calloc(1, sizeof *screen);
     if (screen == NULL)
@@ -449,40 +452,15 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     screen->base.swapInterval   = NULL;
     screen->base.pScreen       = pScreen;
 
-    snprintf(filename, sizeof filename,
-	     "%s/%s_dri.so", dri_driver_path, driverName);
-
-    screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+    screen->driver = glxProbeDriver(driverName,
+				    (void **)&screen->core,
+				    __DRI_CORE, __DRI_CORE_VERSION,
+				    (void **)&screen->swrast,
+				    __DRI_SWRAST, __DRI_SWRAST_VERSION);
     if (screen->driver == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
-		   filename, dlerror());
         goto handle_error;
     }
 
-    extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
-    if (extensions == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
-		   driverName, dlerror());
-	goto handle_error;
-    }
-
-    for (i = 0; extensions[i]; i++) {
-        if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
-	    extensions[i]->version >= __DRI_CORE_VERSION) {
-		screen->core = (const __DRIcoreExtension *) extensions[i];
-	}
-        if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0 &&
-	    extensions[i]->version >= __DRI_SWRAST_VERSION) {
-		screen->swrast = (const __DRIswrastExtension *) extensions[i];
-	}
-    }
-
-    if (screen->core == NULL || screen->swrast == NULL) {
-	LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n",
-		   driverName);
-	goto handle_error;
-    }
-
     screen->driScreen =
 	(*screen->swrast->createNewScreen)(pScreen->myNum,
 					   loader_extensions,
@@ -508,7 +486,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     screen->base.GLXminor = 4;
 
     LogMessage(X_INFO,
-	       "AIGLX: Loaded and initialized %s\n", filename);
+	       "AIGLX: Loaded and initialized %s\n", driverName);
 
     return &screen->base;
 
diff --git a/xorg-server/hw/dmx/dmx.h b/xorg-server/hw/dmx/dmx.h
index ddc11e368..dc5d25e16 100644
--- a/xorg-server/hw/dmx/dmx.h
+++ b/xorg-server/hw/dmx/dmx.h
@@ -249,8 +249,6 @@ typedef struct _DMXScreenInfo {
 
     TrapezoidsProcPtr              Trapezoids;
     TrianglesProcPtr               Triangles;
-    TriStripProcPtr                TriStrip;
-    TriFanProcPtr                  TriFan;
 } DMXScreenInfo;
 
 /* Global variables available to all Xserver/hw/dmx routines. */
diff --git a/xorg-server/hw/dmx/dmxpict.c b/xorg-server/hw/dmx/dmxpict.c
index 3f5cd4a50..1ea6543e0 100644
--- a/xorg-server/hw/dmx/dmxpict.c
+++ b/xorg-server/hw/dmx/dmxpict.c
@@ -165,8 +165,6 @@ Bool dmxPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
 
     DMX_WRAP(Trapezoids,         dmxTrapezoids,         dmxScreen, ps);
     DMX_WRAP(Triangles,          dmxTriangles,          dmxScreen, ps);
-    DMX_WRAP(TriStrip,           dmxTriStrip,           dmxScreen, ps);
-    DMX_WRAP(TriFan,             dmxTriFan,             dmxScreen, ps);
 
     return TRUE;
 }
@@ -1237,88 +1235,3 @@ void dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
 
     DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps);
 }
-
-/** Composite a triangle strip on the appropriate screen.  For a
- *  complete description see the protocol document of the RENDER
- *  library. */
-void dmxTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
-		 PictFormatPtr maskFormat,
-		 INT16 xSrc, INT16 ySrc,
-		 int npoint, xPointFixed *points)
-{
-    ScreenPtr         pScreen   = pDst->pDrawable->pScreen;
-    DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
-    PictureScreenPtr  ps        = GetPictureScreen(pScreen);
-    dmxPictPrivPtr    pSrcPriv  = DMX_GET_PICT_PRIV(pSrc);
-    dmxPictPrivPtr    pDstPriv  = DMX_GET_PICT_PRIV(pDst);
-
-    DMX_UNWRAP(TriStrip, dmxScreen, ps);
-#if 0
-    if (ps->TriStrip)
-	ps->TriStrip(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points);
-#endif
-
-    /* Draw trapezoids on back-end server */
-    if (pDstPriv->pict) {
-	XRenderPictFormat *pFormat;
-
-	pFormat = dmxFindFormat(dmxScreen, maskFormat);
-	if (!pFormat) {
-	    /* FIXME: Error! */
-	}
-
-	XRenderCompositeTriStrip(dmxScreen->beDisplay,
-				 op,
-				 pSrcPriv->pict,
-				 pDstPriv->pict,
-				 pFormat,
-				 xSrc, ySrc,
-				 (XPointFixed *)points,
-				 npoint);
-	dmxSync(dmxScreen, FALSE);
-    }
-
-    DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps);
-}
-
-/** Composite a triangle fan on the appropriate screen.  For a complete
- *  description see the protocol document of the RENDER library. */
-void dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
-	       PictFormatPtr maskFormat,
-	       INT16 xSrc, INT16 ySrc,
-	       int npoint, xPointFixed *points)
-{
-    ScreenPtr         pScreen   = pDst->pDrawable->pScreen;
-    DMXScreenInfo    *dmxScreen = &dmxScreens[pScreen->myNum];
-    PictureScreenPtr  ps        = GetPictureScreen(pScreen);
-    dmxPictPrivPtr    pSrcPriv  = DMX_GET_PICT_PRIV(pSrc);
-    dmxPictPrivPtr    pDstPriv  = DMX_GET_PICT_PRIV(pDst);
-
-    DMX_UNWRAP(TriFan, dmxScreen, ps);
-#if 0
-    if (ps->TriFan)
-	ps->TriFan(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points);
-#endif
-
-    /* Draw trapezoids on back-end server */
-    if (pDstPriv->pict) {
-	XRenderPictFormat *pFormat;
-
-	pFormat = dmxFindFormat(dmxScreen, maskFormat);
-	if (!pFormat) {
-	    /* FIXME: Error! */
-	}
-
-	XRenderCompositeTriFan(dmxScreen->beDisplay,
-			       op,
-			       pSrcPriv->pict,
-			       pDstPriv->pict,
-			       pFormat,
-			       xSrc, ySrc,
-			       (XPointFixed *)points,
-			       npoint);
-	dmxSync(dmxScreen, FALSE);
-    }
-
-    DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps);
-}
diff --git a/xorg-server/hw/dmx/dmxpict.h b/xorg-server/hw/dmx/dmxpict.h
index d196f639a..f1d8c1f52 100644
--- a/xorg-server/hw/dmx/dmxpict.h
+++ b/xorg-server/hw/dmx/dmxpict.h
@@ -100,16 +100,6 @@ extern void dmxTriangles(CARD8 op,
 			 PictFormatPtr maskFormat,
 			 INT16 xSrc, INT16 ySrc,
 			 int ntri, xTriangle *tris);
-extern void dmxTriStrip(CARD8 op,
-			PicturePtr pSrc, PicturePtr pDst,
-			PictFormatPtr maskFormat,
-			INT16 xSrc, INT16 ySrc,
-			int npoint, xPointFixed *points);
-extern void dmxTriFan(CARD8 op,
-		      PicturePtr pSrc, PicturePtr pDst,
-		      PictFormatPtr maskFormat,
-		      INT16 xSrc, INT16 ySrc,
-		      int npoint, xPointFixed *points);
 
 extern int dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet);
 extern Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet);
diff --git a/xorg-server/hw/dmx/doc/Makefile.am b/xorg-server/hw/dmx/doc/Makefile.am
index 8e7360288..d3acf23b7 100644
--- a/xorg-server/hw/dmx/doc/Makefile.am
+++ b/xorg-server/hw/dmx/doc/Makefile.am
@@ -1,280 +1,277 @@
-#  Copyright 2005 Red Hat, Inc.
-#
-#  Permission to use, copy, modify, distribute, and sell this software
-#  and its documentation for any purpose is hereby granted without
-#  fee, provided that the above copyright notice appear in all copies
-#  and that both that copyright notice and this permission notice
-#  appear in supporting documentation, and that the name of Red Hat
-#  not be used in advertising or publicity pertaining to distribution
-#  of the software without specific, written prior permission.  Red
-#  Hat makes no representations about the suitability of this software
-#  for any purpose.  It is provided "as is" without express or implied
-#  warranty.
-#
-#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
-#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
-#  NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
-#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-#  OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-#  NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
-#  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-doc_sources = dmx.xml scaled.xml
-
-# Developer's documentation is not installed
-if ENABLE_DEVEL_DOCS
-include $(top_srcdir)/doc/xml/xmlrules-noinst.in
-endif ENABLE_DEVEL_DOCS
-
-DOXYGEN_HEAD=\
-	html/annotated.html
-
-DOXYGEN_REST= \
-	dmx.txt \
-	scaled.txt \
-	html/ChkNotMaskEv_8c.html \
-	html/ChkNotMaskEv_8h.html \
-	html/ChkNotMaskEv_8h_source.html \
-	html/classes.html \
-	html/dmx_8h.html \
-	html/dmx_8h_source.html \
-	html/dmxarg_8c.html \
-	html/dmxarg_8h.html \
-	html/dmxarg_8h_source.html \
-	html/dmxbackend_8c.html \
-	html/dmxbackend_8h.html \
-	html/dmxbackend_8h_source.html \
-	html/dmxcb_8c.html \
-	html/dmxcb_8h.html \
-	html/dmxcb_8h_source.html \
-	html/dmxclient_8h.html \
-	html/dmxclient_8h_source.html \
-	html/dmxcmap_8c.html \
-	html/dmxcmap_8h.html \
-	html/dmxcmap_8h_source.html \
-	html/dmxcommon_8c.html \
-	html/dmxcommon_8h.html \
-	html/dmxcommon_8h_source.html \
-	html/dmxcompat_8c.html \
-	html/dmxcompat_8h.html \
-	html/dmxcompat_8h_source.html \
-	html/dmxconfig_8c.html \
-	html/dmxconfig_8h.html \
-	html/dmxconfig_8h_source.html \
-	html/dmxconsole_8c.html \
-	html/dmxconsole_8h.html \
-	html/dmxconsole_8h_source.html \
-	html/dmxcursor_8c.html \
-	html/dmxcursor_8h.html \
-	html/dmxcursor_8h_source.html \
-	html/dmxdetach_8c.html \
-	html/dmxdpms_8c.html \
-	html/dmxdpms_8h.html \
-	html/dmxdpms_8h_source.html \
-	html/dmxdummy_8c.html \
-	html/dmxdummy_8h.html \
-	html/dmxdummy_8h_source.html \
-	html/dmxevents_8c.html \
-	html/dmxevents_8h.html \
-	html/dmxevents_8h_source.html \
-	html/dmxextension_8c.html \
-	html/dmxextension_8h.html \
-	html/dmxextension_8h_source.html \
-	html/dmxfont_8c.html \
-	html/dmxfont_8h.html \
-	html/dmxfont_8h_source.html \
-	html/dmxgc_8c.html \
-	html/dmxgc_8h.html \
-	html/dmxgc_8h_source.html \
-	html/dmxgcops_8c.html \
-	html/dmxgcops_8h.html \
-	html/dmxgcops_8h_source.html \
-	html/dmx__glxvisuals_8h_source.html \
-	html/dmxinit_8c.html \
-	html/dmxinit_8h.html \
-	html/dmxinit_8h_source.html \
-	html/dmxinput_8c.html \
-	html/dmxinput_8h.html \
-	html/dmxinput_8h_source.html \
-	html/dmxinputinit_8c.html \
-	html/dmxinputinit_8h.html \
-	html/dmxinputinit_8h_source.html \
-	html/dmxlog_8c.html \
-	html/dmxlog_8h.html \
-	html/dmxlog_8h_source.html \
-	html/dmxmap_8c.html \
-	html/dmxmap_8h.html \
-	html/dmxmap_8h_source.html \
-	html/dmxmotion_8c.html \
-	html/dmxmotion_8h.html \
-	html/dmxmotion_8h_source.html \
-	html/dmxparse_8c.html \
-	html/dmxparse_8h.html \
-	html/dmxparse_8h_source.html \
-	html/dmxpict_8c.html \
-	html/dmxpict_8h.html \
-	html/dmxpict_8h_source.html \
-	html/dmxpixmap_8c.html \
-	html/dmxpixmap_8h.html \
-	html/dmxpixmap_8h_source.html \
-	html/dmxprint_8c.html \
-	html/dmxprint_8h.html \
-	html/dmxprint_8h_source.html \
-	html/dmxprop_8c.html \
-	html/dmxprop_8h.html \
-	html/dmxprop_8h_source.html \
-	html/dmxscrinit_8c.html \
-	html/dmxscrinit_8h.html \
-	html/dmxscrinit_8h_source.html \
-	html/dmxshadow_8c.html \
-	html/dmxshadow_8h.html \
-	html/dmxshadow_8h_source.html \
-	html/dmxsigio_8c.html \
-	html/dmxsigio_8h.html \
-	html/dmxsigio_8h_source.html \
-	html/dmxstat_8c.html \
-	html/dmxstat_8h.html \
-	html/dmxstat_8h_source.html \
-	html/dmxsync_8c.html \
-	html/dmxsync_8h.html \
-	html/dmxsync_8h_source.html \
-	html/dmxvisual_8c.html \
-	html/dmxvisual_8h.html \
-	html/dmxvisual_8h_source.html \
-	html/dmxwindow_8c.html \
-	html/dmxwindow_8h.html \
-	html/dmxwindow_8h_source.html \
-	html/dmxxinput_8c.html \
-	html/doxygen.css \
-	html/doxygen.png \
-	html/files.html \
-	html/ftv2blank.png \
-	html/ftv2doc.png \
-	html/ftv2folderclosed.png \
-	html/ftv2folderopen.png \
-	html/ftv2lastnode.png \
-	html/ftv2link.png \
-	html/ftv2mlastnode.png \
-	html/ftv2mnode.png \
-	html/ftv2node.png \
-	html/ftv2plastnode.png \
-	html/ftv2pnode.png \
-	html/ftv2vertline.png \
-	html/functions.html \
-	html/functions_vars.html \
-	html/globals_defs.html \
-	html/globals_enum.html \
-	html/globals_eval.html \
-	html/globals_func.html \
-	html/globals.html \
-	html/globals_type.html \
-	html/globals_vars.html \
-	html/index.html \
-	html/lnx-keyboard_8c.html \
-	html/lnx-keyboard_8h.html \
-	html/lnx-keyboard_8h_source.html \
-	html/lnx-ms_8c.html \
-	html/lnx-ms_8h.html \
-	html/lnx-ms_8h_source.html \
-	html/lnx-ps2_8c.html \
-	html/lnx-ps2_8h.html \
-	html/lnx-ps2_8h_source.html \
-	html/main.html \
-	html/struct__dmxArg.html \
-	html/struct__dmxColormapPriv.html \
-	html/structDMXConfigCmdStruct.html \
-	html/struct__DMXConfigComment.html \
-	html/struct__DMXConfigDisplay.html \
-	html/struct__DMXConfigEntry.html \
-	html/struct__DMXConfigFullDim.html \
-	html/structDMXConfigListStruct.html \
-	html/struct__DMXConfigNumber.html \
-	html/struct__DMXConfigOption.html \
-	html/struct__DMXConfigPair.html \
-	html/struct__DMXConfigParam.html \
-	html/struct__DMXConfigPartDim.html \
-	html/struct__DMXConfigString.html \
-	html/struct__DMXConfigSub.html \
-	html/struct__DMXConfigToken.html \
-	html/struct__DMXConfigVirtual.html \
-	html/struct__DMXConfigWall.html \
-	html/struct__dmxCursorPriv.html \
-	html/structDMXDesktopAttributesRec.html \
-	html/struct__DMXEventMap.html \
-	html/struct__dmxFontPriv.html \
-	html/struct__dmxGCPriv.html \
-	html/structdmxGlxVisualPrivate.html \
-	html/struct__dmxGlyphPriv.html \
-	html/structDMXInputAttributesRec.html \
-	html/struct__DMXInputInfo.html \
-	html/struct__DMXLocalInitInfo.html \
-	html/struct__DMXLocalInputInfo.html \
-	html/struct__dmxPictPriv.html \
-	html/struct__dmxPixPriv.html \
-	html/structDMXScreenAttributesRec.html \
-	html/struct__DMXScreenInfo.html \
-	html/struct__DMXStatAvg.html \
-	html/struct__DMXStatInfo.html \
-	html/structDMXWindowAttributesRec.html \
-	html/struct__dmxWinPriv.html \
-	html/struct__myPrivate.html \
-	html/tree.html \
-	html/usb-common_8c.html \
-	html/usb-common_8h.html \
-	html/usb-common_8h_source.html \
-	html/usb-keyboard_8c.html \
-	html/usb-keyboard_8h.html \
-	html/usb-keyboard_8h_source.html \
-	html/usb-mouse_8c.html \
-	html/usb-mouse_8h.html \
-	html/usb-mouse_8h_source.html \
-	html/usb-other_8c.html \
-	html/usb-other_8h.html \
-	html/usb-other_8h_source.html \
-	html/usb-private_8h.html \
-	html/usb-private_8h_source.html
-
-DOXYGEN_FILES=$(DOXYGEN_HEAD) $(DOXYGEN_REST)
-
-EXTRA_DIST = \
-	$(XML_FILES) \
-	DMXSpec.txt \
-	DMXSpec-v1.txt \
-	doxygen.conf \
-	doxygen.css \
-	doxygen.foot \
-	doxygen.head \
-	$(DOXYGEN_FILES)
-
-if ENABLE_DEVEL_DOCS
-if HAVE_DOXYGEN
-
-DOXYGEN_SRC=doxygen.head doxygen.foot doxygen.css doxygen.conf
-
-all-local: $(DOXYGEN_FILES)
-
-dist-local: $(DOXYGEN_FILES)
-
-$(DOXYGEN_HEAD): $(DOXYGEN_SRC)
-	$(DOXYGEN) doxygen.conf
-
-$(DOXYGEN_REST): $(DOXYGEN_HEAD)
-
-maintainer-clean-local:
-	rm -rf html/ scaled.txt dmx.txt
-
-distclean-local:
-	rm -rf html/ scaled.txt dmx.txt
-
-endif HAVE_DOXYGEN
-endif ENABLE_DEVEL_DOCS
-
-$(builddir)/doxygen.head:
-	$(LN_S) $(srcdir)/doxygen.head $@
-
-$(builddir)/doxygen.foot:
-	$(LN_S) $(srcdir)/doxygen.foot $@
-
-$(builddir)doxygen.css:
-	$(LN_S) $(srcdir)/doxygen.css $@
-
+#  Copyright 2005 Red Hat, Inc.
+#
+#  Permission to use, copy, modify, distribute, and sell this software
+#  and its documentation for any purpose is hereby granted without
+#  fee, provided that the above copyright notice appear in all copies
+#  and that both that copyright notice and this permission notice
+#  appear in supporting documentation, and that the name of Red Hat
+#  not be used in advertising or publicity pertaining to distribution
+#  of the software without specific, written prior permission.  Red
+#  Hat makes no representations about the suitability of this software
+#  for any purpose.  It is provided "as is" without express or implied
+#  warranty.
+#
+#  RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+#  NO EVENT SHALL RED HAT BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+#  OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+#  NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+#  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+doc_sources = dmx.xml scaled.xml
+
+# Developer's documentation is not installed
+if ENABLE_DEVEL_DOCS
+include $(top_srcdir)/doc/xml/xmlrules-noinst.in
+endif ENABLE_DEVEL_DOCS
+
+DOXYGEN_HEAD=\
+	html/annotated.html
+
+DOXYGEN_REST= \
+	html/ChkNotMaskEv_8c.html \
+	html/ChkNotMaskEv_8h.html \
+	html/ChkNotMaskEv_8h_source.html \
+	html/classes.html \
+	html/dmx_8h.html \
+	html/dmx_8h_source.html \
+	html/dmxarg_8c.html \
+	html/dmxarg_8h.html \
+	html/dmxarg_8h_source.html \
+	html/dmxbackend_8c.html \
+	html/dmxbackend_8h.html \
+	html/dmxbackend_8h_source.html \
+	html/dmxcb_8c.html \
+	html/dmxcb_8h.html \
+	html/dmxcb_8h_source.html \
+	html/dmxclient_8h.html \
+	html/dmxclient_8h_source.html \
+	html/dmxcmap_8c.html \
+	html/dmxcmap_8h.html \
+	html/dmxcmap_8h_source.html \
+	html/dmxcommon_8c.html \
+	html/dmxcommon_8h.html \
+	html/dmxcommon_8h_source.html \
+	html/dmxcompat_8c.html \
+	html/dmxcompat_8h.html \
+	html/dmxcompat_8h_source.html \
+	html/dmxconfig_8c.html \
+	html/dmxconfig_8h.html \
+	html/dmxconfig_8h_source.html \
+	html/dmxconsole_8c.html \
+	html/dmxconsole_8h.html \
+	html/dmxconsole_8h_source.html \
+	html/dmxcursor_8c.html \
+	html/dmxcursor_8h.html \
+	html/dmxcursor_8h_source.html \
+	html/dmxdetach_8c.html \
+	html/dmxdpms_8c.html \
+	html/dmxdpms_8h.html \
+	html/dmxdpms_8h_source.html \
+	html/dmxdummy_8c.html \
+	html/dmxdummy_8h.html \
+	html/dmxdummy_8h_source.html \
+	html/dmxevents_8c.html \
+	html/dmxevents_8h.html \
+	html/dmxevents_8h_source.html \
+	html/dmxextension_8c.html \
+	html/dmxextension_8h.html \
+	html/dmxextension_8h_source.html \
+	html/dmxfont_8c.html \
+	html/dmxfont_8h.html \
+	html/dmxfont_8h_source.html \
+	html/dmxgc_8c.html \
+	html/dmxgc_8h.html \
+	html/dmxgc_8h_source.html \
+	html/dmxgcops_8c.html \
+	html/dmxgcops_8h.html \
+	html/dmxgcops_8h_source.html \
+	html/dmx__glxvisuals_8h_source.html \
+	html/dmxinit_8c.html \
+	html/dmxinit_8h.html \
+	html/dmxinit_8h_source.html \
+	html/dmxinput_8c.html \
+	html/dmxinput_8h.html \
+	html/dmxinput_8h_source.html \
+	html/dmxinputinit_8c.html \
+	html/dmxinputinit_8h.html \
+	html/dmxinputinit_8h_source.html \
+	html/dmxlog_8c.html \
+	html/dmxlog_8h.html \
+	html/dmxlog_8h_source.html \
+	html/dmxmap_8c.html \
+	html/dmxmap_8h.html \
+	html/dmxmap_8h_source.html \
+	html/dmxmotion_8c.html \
+	html/dmxmotion_8h.html \
+	html/dmxmotion_8h_source.html \
+	html/dmxparse_8c.html \
+	html/dmxparse_8h.html \
+	html/dmxparse_8h_source.html \
+	html/dmxpict_8c.html \
+	html/dmxpict_8h.html \
+	html/dmxpict_8h_source.html \
+	html/dmxpixmap_8c.html \
+	html/dmxpixmap_8h.html \
+	html/dmxpixmap_8h_source.html \
+	html/dmxprint_8c.html \
+	html/dmxprint_8h.html \
+	html/dmxprint_8h_source.html \
+	html/dmxprop_8c.html \
+	html/dmxprop_8h.html \
+	html/dmxprop_8h_source.html \
+	html/dmxscrinit_8c.html \
+	html/dmxscrinit_8h.html \
+	html/dmxscrinit_8h_source.html \
+	html/dmxshadow_8c.html \
+	html/dmxshadow_8h.html \
+	html/dmxshadow_8h_source.html \
+	html/dmxsigio_8c.html \
+	html/dmxsigio_8h.html \
+	html/dmxsigio_8h_source.html \
+	html/dmxstat_8c.html \
+	html/dmxstat_8h.html \
+	html/dmxstat_8h_source.html \
+	html/dmxsync_8c.html \
+	html/dmxsync_8h.html \
+	html/dmxsync_8h_source.html \
+	html/dmxvisual_8c.html \
+	html/dmxvisual_8h.html \
+	html/dmxvisual_8h_source.html \
+	html/dmxwindow_8c.html \
+	html/dmxwindow_8h.html \
+	html/dmxwindow_8h_source.html \
+	html/dmxxinput_8c.html \
+	html/doxygen.css \
+	html/doxygen.png \
+	html/files.html \
+	html/ftv2blank.png \
+	html/ftv2doc.png \
+	html/ftv2folderclosed.png \
+	html/ftv2folderopen.png \
+	html/ftv2lastnode.png \
+	html/ftv2link.png \
+	html/ftv2mlastnode.png \
+	html/ftv2mnode.png \
+	html/ftv2node.png \
+	html/ftv2plastnode.png \
+	html/ftv2pnode.png \
+	html/ftv2vertline.png \
+	html/functions.html \
+	html/functions_vars.html \
+	html/globals_defs.html \
+	html/globals_enum.html \
+	html/globals_eval.html \
+	html/globals_func.html \
+	html/globals.html \
+	html/globals_type.html \
+	html/globals_vars.html \
+	html/index.html \
+	html/lnx-keyboard_8c.html \
+	html/lnx-keyboard_8h.html \
+	html/lnx-keyboard_8h_source.html \
+	html/lnx-ms_8c.html \
+	html/lnx-ms_8h.html \
+	html/lnx-ms_8h_source.html \
+	html/lnx-ps2_8c.html \
+	html/lnx-ps2_8h.html \
+	html/lnx-ps2_8h_source.html \
+	html/main.html \
+	html/struct__dmxArg.html \
+	html/struct__dmxColormapPriv.html \
+	html/structDMXConfigCmdStruct.html \
+	html/struct__DMXConfigComment.html \
+	html/struct__DMXConfigDisplay.html \
+	html/struct__DMXConfigEntry.html \
+	html/struct__DMXConfigFullDim.html \
+	html/structDMXConfigListStruct.html \
+	html/struct__DMXConfigNumber.html \
+	html/struct__DMXConfigOption.html \
+	html/struct__DMXConfigPair.html \
+	html/struct__DMXConfigParam.html \
+	html/struct__DMXConfigPartDim.html \
+	html/struct__DMXConfigString.html \
+	html/struct__DMXConfigSub.html \
+	html/struct__DMXConfigToken.html \
+	html/struct__DMXConfigVirtual.html \
+	html/struct__DMXConfigWall.html \
+	html/struct__dmxCursorPriv.html \
+	html/structDMXDesktopAttributesRec.html \
+	html/struct__DMXEventMap.html \
+	html/struct__dmxFontPriv.html \
+	html/struct__dmxGCPriv.html \
+	html/structdmxGlxVisualPrivate.html \
+	html/struct__dmxGlyphPriv.html \
+	html/structDMXInputAttributesRec.html \
+	html/struct__DMXInputInfo.html \
+	html/struct__DMXLocalInitInfo.html \
+	html/struct__DMXLocalInputInfo.html \
+	html/struct__dmxPictPriv.html \
+	html/struct__dmxPixPriv.html \
+	html/structDMXScreenAttributesRec.html \
+	html/struct__DMXScreenInfo.html \
+	html/struct__DMXStatAvg.html \
+	html/struct__DMXStatInfo.html \
+	html/structDMXWindowAttributesRec.html \
+	html/struct__dmxWinPriv.html \
+	html/struct__myPrivate.html \
+	html/tree.html \
+	html/usb-common_8c.html \
+	html/usb-common_8h.html \
+	html/usb-common_8h_source.html \
+	html/usb-keyboard_8c.html \
+	html/usb-keyboard_8h.html \
+	html/usb-keyboard_8h_source.html \
+	html/usb-mouse_8c.html \
+	html/usb-mouse_8h.html \
+	html/usb-mouse_8h_source.html \
+	html/usb-other_8c.html \
+	html/usb-other_8h.html \
+	html/usb-other_8h_source.html \
+	html/usb-private_8h.html \
+	html/usb-private_8h_source.html
+
+DOXYGEN_FILES=$(DOXYGEN_HEAD) $(DOXYGEN_REST)
+
+EXTRA_DIST = \
+	DMXSpec.txt \
+	DMXSpec-v1.txt \
+	doxygen.conf \
+	doxygen.css \
+	doxygen.foot \
+	doxygen.head \
+	$(DOXYGEN_FILES)
+
+if ENABLE_DEVEL_DOCS
+if HAVE_DOXYGEN
+
+DOXYGEN_SRC=doxygen.head doxygen.foot doxygen.css doxygen.conf
+
+all-local: $(DOXYGEN_FILES)
+
+dist-local: $(DOXYGEN_FILES)
+
+$(DOXYGEN_HEAD): $(DOXYGEN_SRC)
+	$(DOXYGEN) doxygen.conf
+
+$(DOXYGEN_REST): $(DOXYGEN_HEAD)
+
+maintainer-clean-local:
+	rm -rf html/
+
+distclean-local:
+	rm -rf html/
+
+endif HAVE_DOXYGEN
+endif ENABLE_DEVEL_DOCS
+
+$(builddir)/doxygen.head:
+	$(LN_S) $(srcdir)/doxygen.head $@
+
+$(builddir)/doxygen.foot:
+	$(LN_S) $(srcdir)/doxygen.foot $@
+
+$(builddir)doxygen.css:
+	$(LN_S) $(srcdir)/doxygen.css $@
+
diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am
index c23b1fd6c..94ef966e2 100644
--- a/xorg-server/hw/xfree86/Makefile.am
+++ b/xorg-server/hw/xfree86/Makefile.am
@@ -1,120 +1,118 @@
-
-if DRI
-DRI_SUBDIR = dri
-endif
-
-if DRI2
-DRI2_SUBDIR = dri2
-endif
-
-if XF86UTILS
-XF86UTILS_SUBDIR = utils
-endif
-
-if XAA
-XAA_SUBDIR = xaa
-endif
-
-if VGAHW
-VGAHW_SUBDIR = vgahw
-endif
-
-if VBE
-VBE_SUBDIR = vbe
-endif
-
-if INT10MODULE
-INT10_SUBDIR = int10
-endif
-
-DOC_SUBDIR = doc
-
-SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \
-	  ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \
-	  loader dixmods exa modes \
-	  $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) $(DOC_SUBDIR)
-
-DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
-               parser ramdac shadowfb vbe vgahw xaa \
-               loader dixmods dri dri2 exa modes \
-	       utils doc
-
-bin_PROGRAMS = Xorg
-Xorg_SOURCES = xorg.c
-
-AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
-INCLUDES = @XORG_INCS@ 
-
-noinst_LTLIBRARIES = libxorg.la
-libxorg_la_SOURCES = libxorg.c
-libxorg_la_LIBADD = \
-            $(XSERVER_LIBS) \
-            loader/libloader.la \
-            os-support/libxorgos.la \
-            common/libcommon.la \
-            parser/libxf86config_internal.la \
-            dixmods/libdixmods.la \
-            modes/libxf86modes.la \
-            ramdac/libramdac.la \
-            ddc/libddc.la \
-            i2c/libi2c.la \
-            dixmods/libxorgxkb.la \
-            $(top_builddir)/mi/libmi.la \
-            $(top_builddir)/os/libos.la \
-            @XORG_LIBS@
-
-libxorg_la_DEPENDENCIES = $(libxorg_la_LIBADD)
-
-libxorg.c xorg.c:
-	touch $@
-
-DISTCLEANFILES = libxorg.c xorg.c
-
-Xorg_DEPENDENCIES = libxorg.la
-Xorg_LDADD = $(MAIN_LIB) libxorg.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS)
-
-Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
-
-BUILT_SOURCES = xorg.conf.example
-DISTCLEANFILES += xorg.conf.example
-EXTRA_DIST = xorgconf.cpp
-
-if SPECIAL_DTRACE_OBJECTS
-# Re-add dtrace object code that gets lost when building static libraries
-Xorg_LDADD += $(XSERVER_LIBS)
-endif
-
-if SOLARIS_ASM_INLINE
-# Needs to be built before any files are compiled when using Sun compilers
-# so in*/out* inline definitions are properly processed.
-
-BUILT_SOURCES += os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il
-
-os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il:
-	cd os-support/solaris ; \
-	 $(MAKE) $(AM_MAKEFLAGS) solaris-@SOLARIS_INOUT_ARCH@.il
-endif
-
-# do not use $(mkdir_p) if you want automake 1.7 to work
-install-data-local:
-	mkdir -p $(DESTDIR)$(logdir)
-
-
-install-exec-local: install-binPROGRAMS
-	(cd $(DESTDIR)$(bindir) && rm -f X && ln -s Xorg X)
-if INSTALL_SETUID
-	chown root $(DESTDIR)$(bindir)/Xorg
-	chmod u+s $(DESTDIR)$(bindir)/Xorg
-endif
-
-# Use variables from XORG_MANPAGE_SECTIONS and X Server configuration
-# Do not include manpages.am as values are not appropriate for rc files
-CONF_SUBSTS =	-e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' \
-		-e 's|MODULEPATH|$(DEFAULT_MODULE_PATH)|g' \
-		-e 's|DEFAULTFONTPATH|$(COMPILEDDEFAULTFONTPATH)|g'
-
-xorg.conf.example: xorgconf.cpp
-	$(AM_V_GEN)$(SED) $(CONF_SUBSTS) < $< > $@
-
-relink:
-	$(AM_V_at)rm -f Xorg && $(MAKE) Xorg
+
+if DRI
+DRI_SUBDIR = dri
+endif
+
+if DRI2
+DRI2_SUBDIR = dri2
+endif
+
+if XF86UTILS
+XF86UTILS_SUBDIR = utils
+endif
+
+if XAA
+XAA_SUBDIR = xaa
+endif
+
+if VGAHW
+VGAHW_SUBDIR = vgahw
+endif
+
+if VBE
+VBE_SUBDIR = vbe
+endif
+
+if INT10MODULE
+INT10_SUBDIR = int10
+endif
+
+SUBDIRS = common ddc i2c x86emu $(INT10_SUBDIR) fbdevhw os-support parser \
+	  ramdac shadowfb $(VBE_SUBDIR) $(VGAHW_SUBDIR) $(XAA_SUBDIR) \
+	  loader dixmods exa modes \
+	  $(DRI_SUBDIR) $(DRI2_SUBDIR) $(XF86UTILS_SUBDIR) doc man
+
+DIST_SUBDIRS = common ddc i2c x86emu int10 fbdevhw os-support \
+               parser ramdac shadowfb vbe vgahw xaa \
+               loader dixmods dri dri2 exa modes \
+	       utils doc man
+
+bin_PROGRAMS = Xorg
+Xorg_SOURCES = xorg.c
+
+AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@
+INCLUDES = @XORG_INCS@ 
+
+noinst_LTLIBRARIES = libxorg.la
+libxorg_la_SOURCES = libxorg.c
+libxorg_la_LIBADD = \
+            $(XSERVER_LIBS) \
+            loader/libloader.la \
+            os-support/libxorgos.la \
+            common/libcommon.la \
+            parser/libxf86config_internal.la \
+            dixmods/libdixmods.la \
+            modes/libxf86modes.la \
+            ramdac/libramdac.la \
+            ddc/libddc.la \
+            i2c/libi2c.la \
+            dixmods/libxorgxkb.la \
+            $(top_builddir)/mi/libmi.la \
+            $(top_builddir)/os/libos.la \
+            @XORG_LIBS@
+
+libxorg_la_DEPENDENCIES = $(libxorg_la_LIBADD)
+
+libxorg.c xorg.c:
+	touch $@
+
+DISTCLEANFILES = libxorg.c xorg.c
+
+Xorg_DEPENDENCIES = libxorg.la
+Xorg_LDADD = $(MAIN_LIB) libxorg.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS)
+
+Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
+
+BUILT_SOURCES = xorg.conf.example
+DISTCLEANFILES += xorg.conf.example
+EXTRA_DIST = xorgconf.cpp
+
+if SPECIAL_DTRACE_OBJECTS
+# Re-add dtrace object code that gets lost when building static libraries
+Xorg_LDADD += $(XSERVER_LIBS)
+endif
+
+if SOLARIS_ASM_INLINE
+# Needs to be built before any files are compiled when using Sun compilers
+# so in*/out* inline definitions are properly processed.
+
+BUILT_SOURCES += os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il
+
+os-support/solaris/solaris-@SOLARIS_INOUT_ARCH@.il:
+	cd os-support/solaris ; \
+	 $(MAKE) $(AM_MAKEFLAGS) solaris-@SOLARIS_INOUT_ARCH@.il
+endif
+
+# do not use $(mkdir_p) if you want automake 1.7 to work
+install-data-local:
+	mkdir -p $(DESTDIR)$(logdir)
+
+
+install-exec-local: install-binPROGRAMS
+	(cd $(DESTDIR)$(bindir) && rm -f X && ln -s Xorg X)
+if INSTALL_SETUID
+	chown root $(DESTDIR)$(bindir)/Xorg
+	chmod u+s $(DESTDIR)$(bindir)/Xorg
+endif
+
+# Use variables from XORG_MANPAGE_SECTIONS and X Server configuration
+# Do not include manpages.am as values are not appropriate for rc files
+CONF_SUBSTS =	-e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g' \
+		-e 's|MODULEPATH|$(DEFAULT_MODULE_PATH)|g' \
+		-e 's|DEFAULTFONTPATH|$(COMPILEDDEFAULTFONTPATH)|g'
+
+xorg.conf.example: xorgconf.cpp
+	$(AM_V_GEN)$(SED) $(CONF_SUBSTS) < $< > $@
+
+relink:
+	$(AM_V_at)rm -f Xorg && $(MAKE) Xorg
diff --git a/xorg-server/hw/xfree86/common/xf86Configure.c b/xorg-server/hw/xfree86/common/xf86Configure.c
index 883c48cc0..bccdd403c 100644
--- a/xorg-server/hw/xfree86/common/xf86Configure.c
+++ b/xorg-server/hw/xfree86/common/xf86Configure.c
@@ -1,765 +1,762 @@
-/*
- * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Alan Hourihane not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Alan Hourihane makes no representations
- * about the suitability of this software for any purpose.  It is provided
- * "as is" without express or implied warranty.
- *
- * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Author:  Alan Hourihane, alanh@fairlite.demon.co.uk
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xf86Priv.h"
-#define IN_XSERVER
-#include "Configint.h"
-#include "xf86DDC.h"
-#include "xf86pciBus.h"
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
-#include "xf86Bus.h"
-#include "xf86Sbus.h"
-#endif
-
-typedef struct _DevToConfig {
-    GDevRec GDev;
-    struct pci_device * pVideo;
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
-    sbusDevicePtr sVideo;
-#endif
-    int iDriver;
-} DevToConfigRec, *DevToConfigPtr;
-
-static DevToConfigPtr DevToConfig = NULL;
-static int nDevToConfig = 0, CurrentDriver;
-
-xf86MonPtr ConfiguredMonitor;
-Bool xf86DoConfigurePass1 = TRUE;
-static Bool foundMouse = FALSE;
-
-#if   defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
-static char *DFLT_MOUSE_PROTO = "auto";
-#elif defined(linux)
-static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
-static char DFLT_MOUSE_PROTO[] = "auto";
-#else
-static char *DFLT_MOUSE_DEV = "/dev/mouse";
-static char *DFLT_MOUSE_PROTO = "auto";
-#endif
-
-/*
- * This is called by the driver, either through xf86Match???Instances() or
- * directly.  We allocate a GDevRec and fill it in as much as we can, letting
- * the caller fill in the rest and/or change it as it sees fit.
- */
-GDevPtr
-xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
-{
-    int ret, i, j;
-
-    if (!xf86DoConfigure || !xf86DoConfigurePass1)
-	return NULL;
-
-    /* Check for duplicates */
-    for (i = 0;  i < nDevToConfig;  i++) {
-        switch (bus) {
-            case BUS_PCI:
-                ret = xf86PciConfigure(busData, DevToConfig[i].pVideo);
-                break;
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
-            case BUS_SBUS:
-                ret = xf86SbusConfigure(busData, DevToConfig[i].sVideo);
-                break;
-#endif
-            default:
-                return NULL;
-        }
-        if (ret == 0)
-            goto out;
-    }
-
-    /* Allocate new structure occurrence */
-    i = nDevToConfig++;
-    DevToConfig =
-	xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
-    memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
-
-    DevToConfig[i].GDev.chipID =
-            DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
-
-    DevToConfig[i].iDriver = CurrentDriver;
-
-    /* Fill in what we know, converting the driver name to lower case */
-    DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
-    for (j = 0;  (DevToConfig[i].GDev.driver[j] = tolower(driver[j]));  j++);
-
-    switch (bus) {
-        case BUS_PCI:
-            xf86PciConfigureNewDev(busData, DevToConfig[i].pVideo,
-                                   &DevToConfig[i].GDev, &chipset);
-	        break;
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
-        case BUS_SBUS:
-            xf86SbusConfigureNewDev(busData, DevToConfig[i].sVideo,
-                                    &DevToConfig[i].GDev);
-	        break;
-#endif
-        default:
-	        break;
-    }
-
-    /* Get driver's available options */
-    if (xf86DriverList[CurrentDriver]->AvailableOptions)
-	DevToConfig[i].GDev.options = (OptionInfoPtr)
-	    (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
-							       bus);
-
-    return &DevToConfig[i].GDev;
-
-out:
-    return NULL;
-}
-
-static XF86ConfInputPtr
-configureInputSection (void)
-{
-    XF86ConfInputPtr mouse = NULL;
-    parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
-
-    ptr->inp_identifier = "Keyboard0";
-    ptr->inp_driver = "kbd";
-    ptr->list.next = NULL;
-
-    /* Crude mechanism to auto-detect mouse (os dependent) */
-    { 
-	int fd;
-#ifdef WSCONS_SUPPORT
-	fd = open("/dev/wsmouse", 0);
-	if (fd >= 0) {
-	    DFLT_MOUSE_DEV = "/dev/wsmouse";
-	    DFLT_MOUSE_PROTO = "wsmouse";
-	    close(fd);
-	} else {
-	    ErrorF("cannot open /dev/wsmouse\n");
-	}
-#endif
-
-	fd = open(DFLT_MOUSE_DEV, 0);
-	if (fd != -1) {
-	    foundMouse = TRUE;
-	    close(fd);
-	}
-    }
-
-    mouse = calloc(1, sizeof(XF86ConfInputRec));
-    mouse->inp_identifier = "Mouse0";
-    mouse->inp_driver = "mouse";
-    mouse->inp_option_lst = 
-		xf86addNewOption(mouse->inp_option_lst, strdup("Protocol"),
-				strdup(DFLT_MOUSE_PROTO));
-    mouse->inp_option_lst = 
-		xf86addNewOption(mouse->inp_option_lst, strdup("Device"),
-				strdup(DFLT_MOUSE_DEV));
-    mouse->inp_option_lst = 
-		xf86addNewOption(mouse->inp_option_lst, strdup("ZAxisMapping"),
-				strdup("4 5 6 7"));
-    ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
-    return ptr;
-}
-
-static XF86ConfScreenPtr
-configureScreenSection (int screennum)
-{
-    int i;
-    int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
-    parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
-
-    XNFasprintf(&ptr->scrn_identifier, "Screen%d", screennum);
-    XNFasprintf(&ptr->scrn_monitor_str, "Monitor%d", screennum);
-    XNFasprintf(&ptr->scrn_device_str, "Card%d", screennum);
-
-    for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
-    {
-	XF86ConfDisplayPtr display;
-
-	display = calloc(1, sizeof(XF86ConfDisplayRec));
-	display->disp_depth = depths[i];
-	display->disp_black.red = display->disp_white.red = -1;
-	display->disp_black.green = display->disp_white.green = -1;
-	display->disp_black.blue = display->disp_white.blue = -1;
-	ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
-				     (glp)ptr->scrn_display_lst, (glp)display);
-    }
-
-    return ptr;
-}
-
-static const char* 
-optionTypeToString(OptionValueType type)
-{
-    switch (type) {
-    case OPTV_NONE:
-        return "";
-    case OPTV_INTEGER:
-        return "<i>";
-    case OPTV_STRING:
-        return "<str>";
-    case OPTV_ANYSTR:
-       return "[<str>]";
-    case OPTV_REAL:
-        return "<f>";
-    case OPTV_BOOLEAN:
-        return "[<bool>]";
-    case OPTV_FREQ:
-        return "<freq>";
-    case OPTV_PERCENT:
-        return "<percent>";
-    default:
-        return "";
-    }
-}
-
-static XF86ConfDevicePtr
-configureDeviceSection (int screennum)
-{
-    OptionInfoPtr p;
-    int i = 0;
-    parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
-
-    /* Move device info to parser structure */
-    if (asprintf(&ptr->dev_identifier, "Card%d", screennum) == -1)
-        ptr->dev_identifier = NULL;
-    ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
-    ptr->dev_busid = DevToConfig[screennum].GDev.busID;
-    ptr->dev_driver = DevToConfig[screennum].GDev.driver;
-    ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
-    for (i = 0;  (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS);  i++)
-        ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
-    ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
-    ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
-    ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
-    ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
-    ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
-    ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
-    for (i = 0;  (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks);  i++)
-        ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
-    ptr->dev_clocks = i;
-    ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
-    ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
-    ptr->dev_irq = DevToConfig[screennum].GDev.irq;
-
-    /* Make sure older drivers don't segv */
-    if (DevToConfig[screennum].GDev.options) {
-    	/* Fill in the available driver options for people to use */
-	const char *descrip =
-	    "        ### Available Driver options are:-\n"
-	    "        ### Values: <i>: integer, <f>: float, "
-			"<bool>: \"True\"/\"False\",\n"
-	    "        ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n"
-	    "        ### <percent>: \"<f>%\"\n"
-	    "        ### [arg]: arg optional\n";
-	ptr->dev_comment = strdup(descrip);
-	if (ptr->dev_comment) {
-    	    for (p = DevToConfig[screennum].GDev.options;
-		 p->name != NULL; p++) {
-		char *p_e;
-		const char *prefix = "        #Option     ";
-		const char *middle = " \t# ";
-		const char *suffix = "\n";
-		const char *opttype = optionTypeToString(p->type);
-		char *optname;
-		int len = strlen(ptr->dev_comment) + strlen(prefix) +
-			  strlen(middle) + strlen(suffix) + 1;
-		
-		if (asprintf(&optname, "\"%s\"", p->name) == -1)
-		    break;
-
-		len += max(20, strlen(optname));
-		len += strlen(opttype);
-
-		ptr->dev_comment = realloc(ptr->dev_comment, len);
-		if (!ptr->dev_comment)
-		    break;
-		p_e = ptr->dev_comment + strlen(ptr->dev_comment);
-		sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
-			opttype, suffix);
-		free(optname);
-	    }
-    	}
-    }
-
-    return ptr;
-}
-
-static XF86ConfLayoutPtr
-configureLayoutSection (void)
-{
-    int scrnum = 0;
-    parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
-
-    ptr->lay_identifier = "X.org Configured";
-
-    {
-	XF86ConfInputrefPtr iptr;
-
-	iptr = malloc (sizeof (XF86ConfInputrefRec));
-	iptr->list.next = NULL;
-	iptr->iref_option_lst = NULL;
-	iptr->iref_inputdev_str = "Mouse0";
-	iptr->iref_option_lst =
-		xf86addNewOption (iptr->iref_option_lst, strdup("CorePointer"), NULL);
-	ptr->lay_input_lst = (XF86ConfInputrefPtr)
-		xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
-    }
-
-    {
-	XF86ConfInputrefPtr iptr;
-
-	iptr = malloc (sizeof (XF86ConfInputrefRec));
-	iptr->list.next = NULL;
-	iptr->iref_option_lst = NULL;
-	iptr->iref_inputdev_str = "Keyboard0";
-	iptr->iref_option_lst =
-		xf86addNewOption (iptr->iref_option_lst, strdup("CoreKeyboard"), NULL);
-	ptr->lay_input_lst = (XF86ConfInputrefPtr)
-		xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
-    }
-
-    for (scrnum = 0;  scrnum < nDevToConfig;  scrnum++) {
-	XF86ConfAdjacencyPtr aptr;
-
-	aptr = malloc (sizeof (XF86ConfAdjacencyRec));
-	aptr->list.next = NULL;
-	aptr->adj_x = 0;
-	aptr->adj_y = 0;
-	aptr->adj_scrnum = scrnum;
-	XNFasprintf(&aptr->adj_screen_str, "Screen%d", scrnum);
-	if (scrnum == 0) {
-	    aptr->adj_where = CONF_ADJ_ABSOLUTE;
-	    aptr->adj_refscreen = NULL;
-	}
-	else {
-	    aptr->adj_where = CONF_ADJ_RIGHTOF;
-	    XNFasprintf(&aptr->adj_refscreen, "Screen%d", scrnum - 1);
-	}
-    	ptr->lay_adjacency_lst =
-	    (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
-					      (glp)aptr);
-    }
-
-    return ptr;
-}
-
-static XF86ConfFlagsPtr
-configureFlagsSection (void)
-{
-    parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
-
-    return ptr;
-}
-
-static XF86ConfModulePtr
-configureModuleSection (void)
-{
-    char **elist, **el;
-    /* Find the list of extension & font modules. */
-    const char *esubdirs[] = {
-	"extensions",
-	"fonts",
-	NULL
-    };
-    parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
-
-    elist = LoaderListDirs(esubdirs, NULL);
-    if (elist) {
-	for (el = elist; *el; el++) {
-	    XF86LoadPtr module;
-
-    	    module = calloc(1, sizeof(XF86LoadRec));
-    	    module->load_name = *el;
-            ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
-                                (glp)ptr->mod_load_lst, (glp)module);
-    	}
-	free(elist);
-    }
-
-    return ptr;
-}
-
-static XF86ConfFilesPtr
-configureFilesSection (void)
-{
-    parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
-
-   if (xf86ModulePath)
-       ptr->file_modulepath = strdup(xf86ModulePath);
-   if (defaultFontPath)
-       ptr->file_fontpath = strdup(defaultFontPath);
-   
-    return ptr;
-}
-
-static XF86ConfMonitorPtr
-configureMonitorSection (int screennum)
-{
-    parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
-
-    XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
-    ptr->mon_vendor = strdup("Monitor Vendor");
-    ptr->mon_modelname = strdup("Monitor Model");
-
-    return ptr;
-}
-
-/* Initialize Configure Monitor from Detailed Timing Block */
-static void handle_detailed_input(struct detailed_monitor_section *det_mon,
-                                  void *data)
-{
-    XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
-
-    switch (det_mon->type) {
-    case DS_NAME:
-        ptr->mon_modelname = realloc(ptr->mon_modelname,
-                                     strlen((char*)(det_mon->section.name)) +
-                                     1);
-        strcpy(ptr->mon_modelname,
-	      (char*)(det_mon->section.name));
-        break;
-    case DS_RANGES:
-        ptr->mon_hsync[ptr->mon_n_hsync].lo =
-            det_mon->section.ranges.min_h;
-        ptr->mon_hsync[ptr->mon_n_hsync].hi =
-            det_mon->section.ranges.max_h;
-        ptr->mon_n_vrefresh = 1;
-        ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
-            det_mon->section.ranges.min_v;
-        ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
-            det_mon->section.ranges.max_v;
-        ptr->mon_n_hsync++;
-    default:
-        break;
-    }
-}
-
-static XF86ConfMonitorPtr
-configureDDCMonitorSection (int screennum)
-{
-    int len, mon_width, mon_height;
-#define displaySizeMaxLen 80
-    char displaySize_string[displaySizeMaxLen];
-    int displaySizeLen;
-
-    parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
-
-    XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
-    ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
-    XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
-
-    /* features in centimetres, we want millimetres */
-    mon_width  = 10 * ConfiguredMonitor->features.hsize ;
-    mon_height = 10 * ConfiguredMonitor->features.vsize ;
-
-#ifdef CONFIGURE_DISPLAYSIZE
-    ptr->mon_width  = mon_width;
-    ptr->mon_height = mon_height;
-#else
-    if (mon_width && mon_height) {
-      /* when values available add DisplaySize option AS A COMMENT */
-
-      displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
-				"\t#DisplaySize\t%5d %5d\t# mm\n",
-				mon_width, mon_height);
-
-      if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
-	if (ptr->mon_comment) {
-	  len = strlen(ptr->mon_comment);
-	} else {
-	  len = 0;
-	}
-	if ((ptr->mon_comment =
-	     realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) {
-	  strcpy(ptr->mon_comment + len, displaySize_string);
-	}
-      }
-    }
-#endif /* def CONFIGURE_DISPLAYSIZE */
-
-    xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input,
-                             ptr);
-
-    if (ConfiguredMonitor->features.dpms) {
-      ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, strdup("DPMS"), NULL);
-    }
-
-    return ptr;
-}
-
-#if !defined(PATH_MAX)
-# define PATH_MAX 1024
-#endif
-
-void
-DoConfigure(void)
-{
-    int i,j, screennum = -1;
-    char *home = NULL;
-    char filename[PATH_MAX];
-    char *addslash = "";
-    XF86ConfigPtr xf86config = NULL;
-    char **vlist, **vl;
-    int *dev2screen;
-
-    vlist = xf86DriverlistFromCompile();
-
-    if (!vlist) {
-	ErrorF("Missing output drivers.  Configuration failed.\n");
-	goto bail;
-    }
-
-    ErrorF("List of video drivers:\n");
-    for (vl = vlist; *vl; vl++)
-	ErrorF("\t%s\n", *vl);
-
-    /* Load all the drivers that were found. */
-    xf86LoadModules(vlist, NULL);
-
-    free(vlist);
-
-    for (i = 0; i < xf86NumDrivers; i++) {
-	xorgHWFlags flags;
-	if (!xf86DriverList[i]->driverFunc
-	    || !xf86DriverList[i]->driverFunc(NULL,
-					      GET_REQUIRED_HW_INTERFACES,
-					      &flags)
-	    || NEED_IO_ENABLED(flags)) {
-	    xorgHWAccess = TRUE;
-	    break;
-	}
-    }
-    /* Enable full I/O access */
-    if (xorgHWAccess) {
-	if(!xf86EnableIO())
-	    /* oops, we have failed */
-	    xorgHWAccess = FALSE;
-    }
-
-    /* Create XF86Config file structure */
-    xf86config = calloc(1, sizeof(XF86ConfigRec));
-
-    /* Call all of the probe functions, reporting the results. */
-    for (CurrentDriver = 0;  CurrentDriver < xf86NumDrivers;  CurrentDriver++) {
-	xorgHWFlags flags;
-	Bool found_screen;
-	DriverRec * const drv = xf86DriverList[CurrentDriver];
-
-	if (!xorgHWAccess) {
-	    if (!drv->driverFunc
-		|| !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags )
-		|| NEED_IO_ENABLED(flags)) 
-		continue;
-	}
-	
-	found_screen = xf86CallDriverProbe( drv, TRUE );
-	if ( found_screen && drv->Identify ) {
-	    (*drv->Identify)(0);
-	}
-    }
-
-    if (nDevToConfig <= 0) {
-	ErrorF("No devices to configure.  Configuration failed.\n");
-	goto bail;
-    }
-
-    /* Add device, monitor and screen sections for detected devices */
-    for (screennum = 0;  screennum < nDevToConfig;  screennum++) {
-    	XF86ConfDevicePtr DevicePtr;
-	XF86ConfMonitorPtr MonitorPtr;
-	XF86ConfScreenPtr ScreenPtr;
-
-	DevicePtr = configureDeviceSection(screennum);
-    	xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
-			    (glp)xf86config->conf_device_lst, (glp)DevicePtr);
-	MonitorPtr = configureMonitorSection(screennum);
-    	xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
-			    (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
-	ScreenPtr = configureScreenSection(screennum);
-    	xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
-			    (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
-    }
-
-    xf86config->conf_files = configureFilesSection();
-    xf86config->conf_modules = configureModuleSection();
-    xf86config->conf_flags = configureFlagsSection();
-    xf86config->conf_videoadaptor_lst = NULL;
-    xf86config->conf_modes_lst = NULL;
-    xf86config->conf_vendor_lst = NULL;
-    xf86config->conf_dri = NULL;
-    xf86config->conf_input_lst = configureInputSection();
-    xf86config->conf_layout_lst = configureLayoutSection();
-
-    home = getenv("HOME");
-    if ((home == NULL) || (home[0] == '\0')) {
-    	home = "/";
-    } else {
-	/* Determine if trailing slash is present or needed */
-	int l = strlen(home);
-
-	if (home[l-1] != '/') {
-	    addslash = "/";
-	}
-    }
-
-    snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
-	     home, addslash);
-
-    if (xf86writeConfigFile(filename, xf86config) == 0) {
-	xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
-		filename, strerror(errno));
-	goto bail;
-    }
-
-    xf86DoConfigurePass1 = FALSE;
-    /* Try to get DDC information filled in */
-    xf86ConfigFile = filename;
-    if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
-	goto bail;
-    }
-
-    xf86DoConfigurePass1 = FALSE;
-    
-    dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
-
-    {
-	Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
-	for (screennum = 0;  screennum < nDevToConfig;  screennum++) {
-	    int k,l,n,oldNumScreens;
-
-	    i = DevToConfig[screennum].iDriver;
-
-	    if (driverProbed[i]) continue;
-	    driverProbed[i] = TRUE;
-	    
-	    oldNumScreens = xf86NumScreens;
-
-	    xf86CallDriverProbe( xf86DriverList[i], FALSE );
-
-	    /* reorder */
-	    k = screennum > 0 ? screennum : 1;
-	    for (l = oldNumScreens; l < xf86NumScreens; l++) {
-	        /* is screen primary? */
-	        Bool primary = FALSE;
-		for (n = 0; n<xf86Screens[l]->numEntities; n++) {
-	            if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
-		        dev2screen[0] = l;
-			primary = TRUE;
-			break;
-		    }
-		}
-		if (primary) continue;
-		/* not primary: assign it to next device of same driver */
-		/* 
-		 * NOTE: we assume that devices in DevToConfig 
-		 * and xf86Screens[] have the same order except
-		 * for the primary device which always comes first.
-		 */
-		for (; k < nDevToConfig; k++) {
-		    if (DevToConfig[k].iDriver == i) {
-		        dev2screen[k++] = l;
-			break;
-		    }
-		}
-	    }
-	}
-	free(driverProbed);
-    }
-    
-
-    if (nDevToConfig != xf86NumScreens) {
-	ErrorF("Number of created screens does not match number of detected"
-	       " devices.\n  Configuration failed.\n");
-	goto bail;
-    }
-
-    xf86PostProbe();
-
-    for (j = 0; j < xf86NumScreens; j++) {
-	xf86Screens[j]->scrnIndex = j;
-    }
-
-    xf86freeMonitorList(xf86config->conf_monitor_lst);
-    xf86config->conf_monitor_lst = NULL;
-    xf86freeScreenList(xf86config->conf_screen_lst);
-    xf86config->conf_screen_lst = NULL;
-    for (j = 0; j < xf86NumScreens; j++) {
-	XF86ConfMonitorPtr MonitorPtr;
-	XF86ConfScreenPtr ScreenPtr;
-
-	ConfiguredMonitor = NULL;
-
-	if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]], 
-						   PROBE_DETECT) &&
-	    ConfiguredMonitor) {
-	    MonitorPtr = configureDDCMonitorSection(j);
-	} else {
-	    MonitorPtr = configureMonitorSection(j);
-	}
-	ScreenPtr = configureScreenSection(j);
-	xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
-		(glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
-	xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
-		(glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
-    }
-
-    if (xf86writeConfigFile(filename, xf86config) == 0) {
-	xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
-		filename, strerror(errno));
-	goto bail;
-    }
-
-    ErrorF("\n");
-
-    if (!foundMouse) {
-	ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
-		"Edit the file and correct the Device.\n");
-    } else {
-	ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
-		"Please check your config if the mouse is still not\n"
-		"operational, as by default "__XSERVERNAME__
-	       " tries to autodetect\n"
-		"the protocol.\n",DFLT_MOUSE_DEV);
-    }
-
-    if (xf86NumScreens > 1) {
-	ErrorF("\n"__XSERVERNAME__
-	       " has configured a multihead system, please check your config.\n");
-    }
-
-    ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
-    ErrorF("To test the server, run 'X -config %s'\n\n", filename);
-
-bail:
-    OsCleanup(TRUE);
-    AbortDDX();
-    fflush(stderr);
-    exit(0);
-}
+/*
+ * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Alan Hourihane, alanh@fairlite.demon.co.uk
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xf86Priv.h"
+#define IN_XSERVER
+#include "Configint.h"
+#include "xf86DDC.h"
+#include "xf86pciBus.h"
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+#include "xf86Bus.h"
+#include "xf86Sbus.h"
+#endif
+#include "misc.h"
+
+typedef struct _DevToConfig {
+    GDevRec GDev;
+    struct pci_device * pVideo;
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+    sbusDevicePtr sVideo;
+#endif
+    int iDriver;
+} DevToConfigRec, *DevToConfigPtr;
+
+static DevToConfigPtr DevToConfig = NULL;
+static int nDevToConfig = 0, CurrentDriver;
+
+xf86MonPtr ConfiguredMonitor;
+Bool xf86DoConfigurePass1 = TRUE;
+static Bool foundMouse = FALSE;
+
+#if   defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
+static char *DFLT_MOUSE_PROTO = "auto";
+#elif defined(linux)
+static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
+static char DFLT_MOUSE_PROTO[] = "auto";
+#else
+static char *DFLT_MOUSE_DEV = "/dev/mouse";
+static char *DFLT_MOUSE_PROTO = "auto";
+#endif
+
+/*
+ * This is called by the driver, either through xf86Match???Instances() or
+ * directly.  We allocate a GDevRec and fill it in as much as we can, letting
+ * the caller fill in the rest and/or change it as it sees fit.
+ */
+GDevPtr
+xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
+{
+    int ret, i, j;
+
+    if (!xf86DoConfigure || !xf86DoConfigurePass1)
+	return NULL;
+
+    /* Check for duplicates */
+    for (i = 0;  i < nDevToConfig;  i++) {
+        switch (bus) {
+            case BUS_PCI:
+                ret = xf86PciConfigure(busData, DevToConfig[i].pVideo);
+                break;
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+            case BUS_SBUS:
+                ret = xf86SbusConfigure(busData, DevToConfig[i].sVideo);
+                break;
+#endif
+            default:
+                return NULL;
+        }
+        if (ret == 0)
+            goto out;
+    }
+
+    /* Allocate new structure occurrence */
+    i = nDevToConfig++;
+    DevToConfig =
+	xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
+    memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
+
+    DevToConfig[i].GDev.chipID =
+            DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
+
+    DevToConfig[i].iDriver = CurrentDriver;
+
+    /* Fill in what we know, converting the driver name to lower case */
+    DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
+    for (j = 0;  (DevToConfig[i].GDev.driver[j] = tolower(driver[j]));  j++);
+
+    switch (bus) {
+        case BUS_PCI:
+            xf86PciConfigureNewDev(busData, DevToConfig[i].pVideo,
+                                   &DevToConfig[i].GDev, &chipset);
+	        break;
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+        case BUS_SBUS:
+            xf86SbusConfigureNewDev(busData, DevToConfig[i].sVideo,
+                                    &DevToConfig[i].GDev);
+	        break;
+#endif
+        default:
+	        break;
+    }
+
+    /* Get driver's available options */
+    if (xf86DriverList[CurrentDriver]->AvailableOptions)
+	DevToConfig[i].GDev.options = (OptionInfoPtr)
+	    (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
+							       bus);
+
+    return &DevToConfig[i].GDev;
+
+out:
+    return NULL;
+}
+
+static XF86ConfInputPtr
+configureInputSection (void)
+{
+    XF86ConfInputPtr mouse = NULL;
+    parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
+
+    ptr->inp_identifier = "Keyboard0";
+    ptr->inp_driver = "kbd";
+    ptr->list.next = NULL;
+
+    /* Crude mechanism to auto-detect mouse (os dependent) */
+    { 
+	int fd;
+#ifdef WSCONS_SUPPORT
+	fd = open("/dev/wsmouse", 0);
+	if (fd >= 0) {
+	    DFLT_MOUSE_DEV = "/dev/wsmouse";
+	    DFLT_MOUSE_PROTO = "wsmouse";
+	    close(fd);
+	} else {
+	    ErrorF("cannot open /dev/wsmouse\n");
+	}
+#endif
+
+	fd = open(DFLT_MOUSE_DEV, 0);
+	if (fd != -1) {
+	    foundMouse = TRUE;
+	    close(fd);
+	}
+    }
+
+    mouse = calloc(1, sizeof(XF86ConfInputRec));
+    mouse->inp_identifier = "Mouse0";
+    mouse->inp_driver = "mouse";
+    mouse->inp_option_lst = 
+		xf86addNewOption(mouse->inp_option_lst, strdup("Protocol"),
+				strdup(DFLT_MOUSE_PROTO));
+    mouse->inp_option_lst = 
+		xf86addNewOption(mouse->inp_option_lst, strdup("Device"),
+				strdup(DFLT_MOUSE_DEV));
+    mouse->inp_option_lst = 
+		xf86addNewOption(mouse->inp_option_lst, strdup("ZAxisMapping"),
+				strdup("4 5 6 7"));
+    ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
+    return ptr;
+}
+
+static XF86ConfScreenPtr
+configureScreenSection (int screennum)
+{
+    int i;
+    int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
+    parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
+
+    XNFasprintf(&ptr->scrn_identifier, "Screen%d", screennum);
+    XNFasprintf(&ptr->scrn_monitor_str, "Monitor%d", screennum);
+    XNFasprintf(&ptr->scrn_device_str, "Card%d", screennum);
+
+    for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
+    {
+	XF86ConfDisplayPtr display;
+
+	display = calloc(1, sizeof(XF86ConfDisplayRec));
+	display->disp_depth = depths[i];
+	display->disp_black.red = display->disp_white.red = -1;
+	display->disp_black.green = display->disp_white.green = -1;
+	display->disp_black.blue = display->disp_white.blue = -1;
+	ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
+				     (glp)ptr->scrn_display_lst, (glp)display);
+    }
+
+    return ptr;
+}
+
+static const char* 
+optionTypeToString(OptionValueType type)
+{
+    switch (type) {
+    case OPTV_NONE:
+        return "";
+    case OPTV_INTEGER:
+        return "<i>";
+    case OPTV_STRING:
+        return "<str>";
+    case OPTV_ANYSTR:
+       return "[<str>]";
+    case OPTV_REAL:
+        return "<f>";
+    case OPTV_BOOLEAN:
+        return "[<bool>]";
+    case OPTV_FREQ:
+        return "<freq>";
+    case OPTV_PERCENT:
+        return "<percent>";
+    default:
+        return "";
+    }
+}
+
+static XF86ConfDevicePtr
+configureDeviceSection (int screennum)
+{
+    OptionInfoPtr p;
+    int i = 0;
+    parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
+
+    /* Move device info to parser structure */
+    if (asprintf(&ptr->dev_identifier, "Card%d", screennum) == -1)
+        ptr->dev_identifier = NULL;
+    ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
+    ptr->dev_busid = DevToConfig[screennum].GDev.busID;
+    ptr->dev_driver = DevToConfig[screennum].GDev.driver;
+    ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
+    for (i = 0;  (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS);  i++)
+        ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
+    ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
+    ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
+    ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
+    ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
+    ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
+    ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
+    for (i = 0;  (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks);  i++)
+        ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
+    ptr->dev_clocks = i;
+    ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
+    ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
+    ptr->dev_irq = DevToConfig[screennum].GDev.irq;
+
+    /* Make sure older drivers don't segv */
+    if (DevToConfig[screennum].GDev.options) {
+    	/* Fill in the available driver options for people to use */
+	const char *descrip =
+	    "        ### Available Driver options are:-\n"
+	    "        ### Values: <i>: integer, <f>: float, "
+			"<bool>: \"True\"/\"False\",\n"
+	    "        ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\",\n"
+	    "        ### <percent>: \"<f>%\"\n"
+	    "        ### [arg]: arg optional\n";
+	ptr->dev_comment = strdup(descrip);
+	if (ptr->dev_comment) {
+    	    for (p = DevToConfig[screennum].GDev.options;
+		 p->name != NULL; p++) {
+		char *p_e;
+		const char *prefix = "        #Option     ";
+		const char *middle = " \t# ";
+		const char *suffix = "\n";
+		const char *opttype = optionTypeToString(p->type);
+		char *optname;
+		int len = strlen(ptr->dev_comment) + strlen(prefix) +
+			  strlen(middle) + strlen(suffix) + 1;
+		
+		if (asprintf(&optname, "\"%s\"", p->name) == -1)
+		    break;
+
+		len += max(20, strlen(optname));
+		len += strlen(opttype);
+
+		ptr->dev_comment = realloc(ptr->dev_comment, len);
+		if (!ptr->dev_comment)
+		    break;
+		p_e = ptr->dev_comment + strlen(ptr->dev_comment);
+		sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
+			opttype, suffix);
+		free(optname);
+	    }
+    	}
+    }
+
+    return ptr;
+}
+
+static XF86ConfLayoutPtr
+configureLayoutSection (void)
+{
+    int scrnum = 0;
+    parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
+
+    ptr->lay_identifier = "X.org Configured";
+
+    {
+	XF86ConfInputrefPtr iptr;
+
+	iptr = malloc (sizeof (XF86ConfInputrefRec));
+	iptr->list.next = NULL;
+	iptr->iref_option_lst = NULL;
+	iptr->iref_inputdev_str = "Mouse0";
+	iptr->iref_option_lst =
+		xf86addNewOption (iptr->iref_option_lst, strdup("CorePointer"), NULL);
+	ptr->lay_input_lst = (XF86ConfInputrefPtr)
+		xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+    }
+
+    {
+	XF86ConfInputrefPtr iptr;
+
+	iptr = malloc (sizeof (XF86ConfInputrefRec));
+	iptr->list.next = NULL;
+	iptr->iref_option_lst = NULL;
+	iptr->iref_inputdev_str = "Keyboard0";
+	iptr->iref_option_lst =
+		xf86addNewOption (iptr->iref_option_lst, strdup("CoreKeyboard"), NULL);
+	ptr->lay_input_lst = (XF86ConfInputrefPtr)
+		xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+    }
+
+    for (scrnum = 0;  scrnum < nDevToConfig;  scrnum++) {
+	XF86ConfAdjacencyPtr aptr;
+
+	aptr = malloc (sizeof (XF86ConfAdjacencyRec));
+	aptr->list.next = NULL;
+	aptr->adj_x = 0;
+	aptr->adj_y = 0;
+	aptr->adj_scrnum = scrnum;
+	XNFasprintf(&aptr->adj_screen_str, "Screen%d", scrnum);
+	if (scrnum == 0) {
+	    aptr->adj_where = CONF_ADJ_ABSOLUTE;
+	    aptr->adj_refscreen = NULL;
+	}
+	else {
+	    aptr->adj_where = CONF_ADJ_RIGHTOF;
+	    XNFasprintf(&aptr->adj_refscreen, "Screen%d", scrnum - 1);
+	}
+    	ptr->lay_adjacency_lst =
+	    (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
+					      (glp)aptr);
+    }
+
+    return ptr;
+}
+
+static XF86ConfFlagsPtr
+configureFlagsSection (void)
+{
+    parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
+
+    return ptr;
+}
+
+static XF86ConfModulePtr
+configureModuleSection (void)
+{
+    char **elist, **el;
+    /* Find the list of extension & font modules. */
+    const char *esubdirs[] = {
+	"extensions",
+	"fonts",
+	NULL
+    };
+    parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
+
+    elist = LoaderListDirs(esubdirs, NULL);
+    if (elist) {
+	for (el = elist; *el; el++) {
+	    XF86LoadPtr module;
+
+    	    module = calloc(1, sizeof(XF86LoadRec));
+    	    module->load_name = *el;
+            ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
+                                (glp)ptr->mod_load_lst, (glp)module);
+    	}
+	free(elist);
+    }
+
+    return ptr;
+}
+
+static XF86ConfFilesPtr
+configureFilesSection (void)
+{
+    parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
+
+   if (xf86ModulePath)
+       ptr->file_modulepath = strdup(xf86ModulePath);
+   if (defaultFontPath)
+       ptr->file_fontpath = strdup(defaultFontPath);
+   
+    return ptr;
+}
+
+static XF86ConfMonitorPtr
+configureMonitorSection (int screennum)
+{
+    parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
+
+    XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
+    ptr->mon_vendor = strdup("Monitor Vendor");
+    ptr->mon_modelname = strdup("Monitor Model");
+
+    return ptr;
+}
+
+/* Initialize Configure Monitor from Detailed Timing Block */
+static void handle_detailed_input(struct detailed_monitor_section *det_mon,
+                                  void *data)
+{
+    XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
+
+    switch (det_mon->type) {
+    case DS_NAME:
+        ptr->mon_modelname = realloc(ptr->mon_modelname,
+                                     strlen((char*)(det_mon->section.name)) +
+                                     1);
+        strcpy(ptr->mon_modelname,
+	      (char*)(det_mon->section.name));
+        break;
+    case DS_RANGES:
+        ptr->mon_hsync[ptr->mon_n_hsync].lo =
+            det_mon->section.ranges.min_h;
+        ptr->mon_hsync[ptr->mon_n_hsync].hi =
+            det_mon->section.ranges.max_h;
+        ptr->mon_n_vrefresh = 1;
+        ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
+            det_mon->section.ranges.min_v;
+        ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
+            det_mon->section.ranges.max_v;
+        ptr->mon_n_hsync++;
+    default:
+        break;
+    }
+}
+
+static XF86ConfMonitorPtr
+configureDDCMonitorSection (int screennum)
+{
+    int len, mon_width, mon_height;
+#define displaySizeMaxLen 80
+    char displaySize_string[displaySizeMaxLen];
+    int displaySizeLen;
+
+    parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
+
+    XNFasprintf(&ptr->mon_identifier, "Monitor%d", screennum);
+    ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
+    XNFasprintf(&ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
+
+    /* features in centimetres, we want millimetres */
+    mon_width  = 10 * ConfiguredMonitor->features.hsize ;
+    mon_height = 10 * ConfiguredMonitor->features.vsize ;
+
+#ifdef CONFIGURE_DISPLAYSIZE
+    ptr->mon_width  = mon_width;
+    ptr->mon_height = mon_height;
+#else
+    if (mon_width && mon_height) {
+      /* when values available add DisplaySize option AS A COMMENT */
+
+      displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
+				"\t#DisplaySize\t%5d %5d\t# mm\n",
+				mon_width, mon_height);
+
+      if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
+	if (ptr->mon_comment) {
+	  len = strlen(ptr->mon_comment);
+	} else {
+	  len = 0;
+	}
+	if ((ptr->mon_comment =
+	     realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) {
+	  strcpy(ptr->mon_comment + len, displaySize_string);
+	}
+      }
+    }
+#endif /* def CONFIGURE_DISPLAYSIZE */
+
+    xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input,
+                             ptr);
+
+    if (ConfiguredMonitor->features.dpms) {
+      ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, strdup("DPMS"), NULL);
+    }
+
+    return ptr;
+}
+
+void
+DoConfigure(void)
+{
+    int i,j, screennum = -1;
+    char *home = NULL;
+    char filename[PATH_MAX];
+    char *addslash = "";
+    XF86ConfigPtr xf86config = NULL;
+    char **vlist, **vl;
+    int *dev2screen;
+
+    vlist = xf86DriverlistFromCompile();
+
+    if (!vlist) {
+	ErrorF("Missing output drivers.  Configuration failed.\n");
+	goto bail;
+    }
+
+    ErrorF("List of video drivers:\n");
+    for (vl = vlist; *vl; vl++)
+	ErrorF("\t%s\n", *vl);
+
+    /* Load all the drivers that were found. */
+    xf86LoadModules(vlist, NULL);
+
+    free(vlist);
+
+    for (i = 0; i < xf86NumDrivers; i++) {
+	xorgHWFlags flags;
+	if (!xf86DriverList[i]->driverFunc
+	    || !xf86DriverList[i]->driverFunc(NULL,
+					      GET_REQUIRED_HW_INTERFACES,
+					      &flags)
+	    || NEED_IO_ENABLED(flags)) {
+	    xorgHWAccess = TRUE;
+	    break;
+	}
+    }
+    /* Enable full I/O access */
+    if (xorgHWAccess) {
+	if(!xf86EnableIO())
+	    /* oops, we have failed */
+	    xorgHWAccess = FALSE;
+    }
+
+    /* Create XF86Config file structure */
+    xf86config = calloc(1, sizeof(XF86ConfigRec));
+
+    /* Call all of the probe functions, reporting the results. */
+    for (CurrentDriver = 0;  CurrentDriver < xf86NumDrivers;  CurrentDriver++) {
+	xorgHWFlags flags;
+	Bool found_screen;
+	DriverRec * const drv = xf86DriverList[CurrentDriver];
+
+	if (!xorgHWAccess) {
+	    if (!drv->driverFunc
+		|| !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags )
+		|| NEED_IO_ENABLED(flags)) 
+		continue;
+	}
+	
+	found_screen = xf86CallDriverProbe( drv, TRUE );
+	if ( found_screen && drv->Identify ) {
+	    (*drv->Identify)(0);
+	}
+    }
+
+    if (nDevToConfig <= 0) {
+	ErrorF("No devices to configure.  Configuration failed.\n");
+	goto bail;
+    }
+
+    /* Add device, monitor and screen sections for detected devices */
+    for (screennum = 0;  screennum < nDevToConfig;  screennum++) {
+    	XF86ConfDevicePtr DevicePtr;
+	XF86ConfMonitorPtr MonitorPtr;
+	XF86ConfScreenPtr ScreenPtr;
+
+	DevicePtr = configureDeviceSection(screennum);
+    	xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
+			    (glp)xf86config->conf_device_lst, (glp)DevicePtr);
+	MonitorPtr = configureMonitorSection(screennum);
+    	xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
+			    (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
+	ScreenPtr = configureScreenSection(screennum);
+    	xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
+			    (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
+    }
+
+    xf86config->conf_files = configureFilesSection();
+    xf86config->conf_modules = configureModuleSection();
+    xf86config->conf_flags = configureFlagsSection();
+    xf86config->conf_videoadaptor_lst = NULL;
+    xf86config->conf_modes_lst = NULL;
+    xf86config->conf_vendor_lst = NULL;
+    xf86config->conf_dri = NULL;
+    xf86config->conf_input_lst = configureInputSection();
+    xf86config->conf_layout_lst = configureLayoutSection();
+
+    home = getenv("HOME");
+    if ((home == NULL) || (home[0] == '\0')) {
+    	home = "/";
+    } else {
+	/* Determine if trailing slash is present or needed */
+	int l = strlen(home);
+
+	if (home[l-1] != '/') {
+	    addslash = "/";
+	}
+    }
+
+    snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
+	     home, addslash);
+
+    if (xf86writeConfigFile(filename, xf86config) == 0) {
+	xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
+		filename, strerror(errno));
+	goto bail;
+    }
+
+    xf86DoConfigurePass1 = FALSE;
+    /* Try to get DDC information filled in */
+    xf86ConfigFile = filename;
+    if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
+	goto bail;
+    }
+
+    xf86DoConfigurePass1 = FALSE;
+    
+    dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
+
+    {
+	Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
+	for (screennum = 0;  screennum < nDevToConfig;  screennum++) {
+	    int k,l,n,oldNumScreens;
+
+	    i = DevToConfig[screennum].iDriver;
+
+	    if (driverProbed[i]) continue;
+	    driverProbed[i] = TRUE;
+	    
+	    oldNumScreens = xf86NumScreens;
+
+	    xf86CallDriverProbe( xf86DriverList[i], FALSE );
+
+	    /* reorder */
+	    k = screennum > 0 ? screennum : 1;
+	    for (l = oldNumScreens; l < xf86NumScreens; l++) {
+	        /* is screen primary? */
+	        Bool primary = FALSE;
+		for (n = 0; n<xf86Screens[l]->numEntities; n++) {
+	            if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
+		        dev2screen[0] = l;
+			primary = TRUE;
+			break;
+		    }
+		}
+		if (primary) continue;
+		/* not primary: assign it to next device of same driver */
+		/* 
+		 * NOTE: we assume that devices in DevToConfig 
+		 * and xf86Screens[] have the same order except
+		 * for the primary device which always comes first.
+		 */
+		for (; k < nDevToConfig; k++) {
+		    if (DevToConfig[k].iDriver == i) {
+		        dev2screen[k++] = l;
+			break;
+		    }
+		}
+	    }
+	}
+	free(driverProbed);
+    }
+    
+
+    if (nDevToConfig != xf86NumScreens) {
+	ErrorF("Number of created screens does not match number of detected"
+	       " devices.\n  Configuration failed.\n");
+	goto bail;
+    }
+
+    xf86PostProbe();
+
+    for (j = 0; j < xf86NumScreens; j++) {
+	xf86Screens[j]->scrnIndex = j;
+    }
+
+    xf86freeMonitorList(xf86config->conf_monitor_lst);
+    xf86config->conf_monitor_lst = NULL;
+    xf86freeScreenList(xf86config->conf_screen_lst);
+    xf86config->conf_screen_lst = NULL;
+    for (j = 0; j < xf86NumScreens; j++) {
+	XF86ConfMonitorPtr MonitorPtr;
+	XF86ConfScreenPtr ScreenPtr;
+
+	ConfiguredMonitor = NULL;
+
+	if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]], 
+						   PROBE_DETECT) &&
+	    ConfiguredMonitor) {
+	    MonitorPtr = configureDDCMonitorSection(j);
+	} else {
+	    MonitorPtr = configureMonitorSection(j);
+	}
+	ScreenPtr = configureScreenSection(j);
+	xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
+		(glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
+	xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
+		(glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
+    }
+
+    if (xf86writeConfigFile(filename, xf86config) == 0) {
+	xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
+		filename, strerror(errno));
+	goto bail;
+    }
+
+    ErrorF("\n");
+
+    if (!foundMouse) {
+	ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
+		"Edit the file and correct the Device.\n");
+    } else {
+	ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
+		"Please check your config if the mouse is still not\n"
+		"operational, as by default "__XSERVERNAME__
+	       " tries to autodetect\n"
+		"the protocol.\n",DFLT_MOUSE_DEV);
+    }
+
+    if (xf86NumScreens > 1) {
+	ErrorF("\n"__XSERVERNAME__
+	       " has configured a multihead system, please check your config.\n");
+    }
+
+    ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
+    ErrorF("To test the server, run 'X -config %s'\n\n", filename);
+
+bail:
+    OsCleanup(TRUE);
+    AbortDDX();
+    fflush(stderr);
+    exit(0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c
index 74365e10b..4166a1c38 100644
--- a/xorg-server/hw/xfree86/common/xf86Xinput.c
+++ b/xorg-server/hw/xfree86/common/xf86Xinput.c
@@ -1,1406 +1,1409 @@
-/*
- * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
- *                                                                            
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is  hereby granted without fee, provided that
- * the  above copyright   notice appear  in   all  copies and  that both  that
- * copyright  notice   and   this  permission   notice  appear  in  supporting
- * documentation, and that   the  name of  Frederic   Lepied not  be  used  in
- * advertising or publicity pertaining to distribution of the software without
- * specific,  written      prior  permission.     Frederic  Lepied   makes  no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.                   
- *                                                                            
- * FREDERIC  LEPIED DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
- * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
- * EVENT  SHALL FREDERIC  LEPIED BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
- * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * Copyright (c) 2000-2002 by The XFree86 Project, 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/Xfuncproto.h>
-#include <X11/Xmd.h>
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include <X11/Xatom.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Config.h"
-#include "xf86Xinput.h"
-#include "xf86Optrec.h"
-#include "mipointer.h"
-#include "extinit.h"
-#include "loaderProcs.h"
-
-#include "exevents.h"	/* AddInputDevice */
-#include "exglobals.h"
-#include "eventstr.h"
-#include "inpututils.h"
-
-#include <string.h>     /* InputClassMatches */
-#ifdef HAVE_FNMATCH_H
-#include <fnmatch.h>
-#endif
-#ifdef HAVE_SYS_UTSNAME_H
-#include <sys/utsname.h>
-#endif
-
-#include <stdarg.h>
-#include <stdint.h>          /* for int64_t */
-
-#include "mi.h"
-
-#include <ptrveloc.h>          /* dix pointer acceleration */
-#include <xserver-properties.h>
-
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-#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;
-
-static int
-xf86InputDevicePostInit(DeviceIntPtr dev);
-
-/**
- * Eval config and modify DeviceVelocityRec accordingly
- */
-static void
-ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
-                             DeviceVelocityPtr s)
-{
-    int tempi;
-    float tempf;
-    Atom float_prop = XIGetKnownProperty(XATOM_FLOAT);
-    Atom prop;
-
-    if(!s)
-        return;
-
-    /* common settings (available via device properties) */
-    tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0);
-    if (tempf > 1.0) {
-        xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n",
-                devname, tempf);
-        prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
-        XIChangeDeviceProperty(pDev, prop, float_prop, 32,
-                               PropModeReplace, 1, &tempf, FALSE);
-    }
-
-    tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0);
-    if (tempf > 1.0) {
-        xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n",
-                devname, tempf);
-        prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
-        XIChangeDeviceProperty(pDev, prop, float_prop, 32,
-                               PropModeReplace, 1, &tempf, FALSE);
-    }
-
-    /* select profile by number */
-    tempi = xf86SetIntOption(list, "AccelerationProfile",
-            s->statistics.profile_number);
-
-    prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
-    if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32,
-                               PropModeReplace, 1, &tempi, FALSE) == Success) {
-        xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname,
-                tempi);
-    } else {
-        xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n",
-                devname, tempi);
-    }
-
-    /* set scaling */
-    tempf = xf86SetRealOption(list, "ExpectedRate", 0);
-    prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
-    if (tempf > 0) {
-        tempf = 1000.0 / tempf;
-        XIChangeDeviceProperty(pDev, prop, float_prop, 32,
-                               PropModeReplace, 1, &tempf, FALSE);
-    } else {
-        tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul);
-        XIChangeDeviceProperty(pDev, prop, float_prop, 32,
-                               PropModeReplace, 1, &tempf, FALSE);
-    }
-
-    tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1);
-    if (tempi > 1)
-	InitTrackers(s, tempi);
-
-    s->initial_range = xf86SetIntOption(list, "VelocityInitialRange",
-                                        s->initial_range);
-
-    s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff);
-
-    tempf = xf86SetRealOption(list, "VelocityRelDiff", -1);
-    if (tempf >= 0) {
-	xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n",
-	        devname, tempf*100.0);
-	s->max_rel_diff = tempf;
-    }
-
-    /*  Configure softening. If const deceleration is used, this is expected
-     *  to provide better subpixel information so we enable
-     *  softening by default only if ConstantDeceleration is not used
-     */
-    s->use_softening = xf86SetBoolOption(list, "Softening",
-                                         s->const_acceleration == 1.0);
-
-    s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging",
-                                         s->average_accel);
-
-    s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time);
-}
-
-static void
-ApplyAccelerationSettings(DeviceIntPtr dev){
-    int scheme, i;
-    DeviceVelocityPtr pVel;
-    InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate;
-    char* schemeStr;
-
-    if (dev->valuator && dev->ptrfeed) {
-	schemeStr = xf86SetStrOption(pInfo->options, "AccelerationScheme", "");
-
-	scheme = dev->valuator->accelScheme.number;
-
-	if (!xf86NameCmp(schemeStr, "predictable"))
-	    scheme = PtrAccelPredictable;
-
-	if (!xf86NameCmp(schemeStr, "lightweight"))
-	    scheme = PtrAccelLightweight;
-
-	if (!xf86NameCmp(schemeStr, "none"))
-	    scheme = PtrAccelNoOp;
-
-        /* reinit scheme if needed */
-        if (dev->valuator->accelScheme.number != scheme) {
-            if (dev->valuator->accelScheme.AccelCleanupProc) {
-                dev->valuator->accelScheme.AccelCleanupProc(dev);
-            }
-
-            if (InitPointerAccelerationScheme(dev, scheme)) {
-		xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
-		        pInfo->name, schemeStr, scheme);
-	    } else {
-        	xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
-		        pInfo->name, schemeStr);
-        	scheme = dev->valuator->accelScheme.number;
-            }
-        } else {
-            xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
-                    pInfo->name, scheme);
-        }
-
-        free(schemeStr);
-
-        /* process special configuration */
-        switch (scheme) {
-            case PtrAccelPredictable:
-                pVel = GetDevicePredictableAccelData(dev);
-                ProcessVelocityConfiguration (dev, pInfo->name, pInfo->options,
-                                              pVel);
-                break;
-        }
-
-        i = xf86SetIntOption(pInfo->options, "AccelerationNumerator",
-                             dev->ptrfeed->ctrl.num);
-        if (i >= 0)
-            dev->ptrfeed->ctrl.num = i;
-
-        i = xf86SetIntOption(pInfo->options, "AccelerationDenominator",
-                             dev->ptrfeed->ctrl.den);
-        if (i > 0)
-            dev->ptrfeed->ctrl.den = i;
-
-        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",
-                            pInfo->name, ((float)dev->ptrfeed->ctrl.num)/
-                                         ((float)dev->ptrfeed->ctrl.den));
-        xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
-                pInfo->name, dev->ptrfeed->ctrl.threshold);
-    }
-}
-
-/***********************************************************************
- *
- * xf86ProcessCommonOptions --
- * 
- *	Process global options.
- *
- ***********************************************************************
- */
-void
-xf86ProcessCommonOptions(InputInfoPtr pInfo,
-                         pointer	list)
-{
-    if (xf86SetBoolOption(list, "Floating", 0) ||
-        !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", pInfo->name);
-    } else {
-        pInfo->flags |= XI86_ALWAYS_CORE;
-        xf86Msg(X_CONFIG, "%s: always reports core events\n", pInfo->name);
-    }
-}
-
-/***********************************************************************
- *
- * xf86ActivateDevice --
- *
- *	Initialize an input device.
- *
- * Returns TRUE on success, or FALSE otherwise.
- ***********************************************************************
- */
-static DeviceIntPtr
-xf86ActivateDevice(InputInfoPtr pInfo)
-{
-    DeviceIntPtr	dev;
-    Atom		atom;
-
-    dev = AddInputDevice(serverClient, pInfo->device_control, TRUE);
-
-    if (dev == NULL)
-    {
-        xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
-                pInfo->name);
-        pInfo->dev = NULL;
-        return NULL;
-    }
-
-    atom = MakeAtom(pInfo->type_name, strlen(pInfo->type_name), TRUE);
-    AssignTypeAndName(dev, atom, pInfo->name);
-    dev->public.devicePrivate = pInfo;
-    pInfo->dev = dev;
-
-    dev->coreEvents = pInfo->flags & XI86_ALWAYS_CORE;
-    dev->type = SLAVE;
-    dev->spriteInfo->spriteOwner = FALSE;
-
-    dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL);
-
-    if (serverGeneration == 1)
-        xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
-                pInfo->name, pInfo->type_name);
-
-    return dev;
-}
-
-/****************************************************************************
- *
- * Caller:	ProcXSetDeviceMode
- *
- * Change the mode of an extension device.
- * This function is used to change the mode of a device from reporting
- * relative motion to reporting absolute positional information, and
- * vice versa.
- * The default implementation below is that no such devices are supported.
- *
- ***********************************************************************
- */
-
-int
-SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
-{
-  InputInfoPtr        pInfo = (InputInfoPtr)dev->public.devicePrivate;
-
-  if (pInfo->switch_mode) {
-    return (*pInfo->switch_mode)(client, dev, mode);
-  }
-  else
-    return BadMatch;
-}
-
-
-/***********************************************************************
- *
- * Caller:	ProcXSetDeviceValuators
- *
- * Set the value of valuators on an extension input device.
- * This function is used to set the initial value of valuators on
- * those input devices that are capable of reporting either relative
- * motion or an absolute position, and allow an initial position to be set.
- * The default implementation below is that no such devices are supported.
- *
- ***********************************************************************
- */
-
-int
-SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
-                    int first_valuator, int num_valuators)
-{
-    InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate;
-
-    if (pInfo->set_device_valuators)
-	return (*pInfo->set_device_valuators)(pInfo, valuators, first_valuator,
-					      num_valuators);
-
-    return BadMatch;
-}
-
-
-/***********************************************************************
- *
- * Caller:	ProcXChangeDeviceControl
- *
- * Change the specified device controls on an extension input device.
- *
- ***********************************************************************
- */
-
-int
-ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
-{
-  InputInfoPtr        pInfo = (InputInfoPtr)dev->public.devicePrivate;
-
-  if (!pInfo->control_proc) {
-      switch (control->control) {
-      case DEVICE_CORE:
-          return BadMatch;
-      case DEVICE_RESOLUTION:
-      case DEVICE_ABS_CALIB:
-      case DEVICE_ABS_AREA:
-      case DEVICE_ENABLE:
-        return Success;
-      default:
-        return BadMatch;
-      }
-  }
-  else {
-      return (*pInfo->control_proc)(pInfo, control);
-  }
-}
-
-/*
- * Get the operating system name from uname and store it statically to avoid
- * repeating the system call each time MatchOS is checked.
- */
-static const char *
-HostOS(void)
-{
-#ifdef HAVE_SYS_UTSNAME_H
-    struct utsname name;
-    static char host_os[sizeof(name.sysname)] = "";
-
-    if (*host_os == '\0') {
-        if (uname(&name) >= 0)
-            strcpy(host_os, name.sysname);
-        else {
-            strncpy(host_os, "unknown", sizeof(host_os));
-            host_os[sizeof(host_os)-1] = '\0';
-        }
-    }
-    return host_os;
-#else
-    return "";
-#endif
-}
-
-static int
-match_substring(const char *attr, const char *pattern)
-{
-    return (strstr(attr, pattern)) ? 0 : -1;
-}
-
-#ifdef HAVE_FNMATCH_H
-static int
-match_pattern(const char *attr, const char *pattern)
-{
-    return fnmatch(pattern, attr, 0);
-}
-#else
-#define match_pattern match_substring
-#endif
-
-#ifdef HAVE_FNMATCH_H
-static int
-match_path_pattern(const char *attr, const char *pattern)
-{
-    return fnmatch(pattern, attr, FNM_PATHNAME);
-}
-#else
-#define match_path_pattern match_substring
-#endif
-
-/*
- * Match an attribute against a list of NULL terminated arrays of patterns.
- * If a pattern in each list entry is matched, return TRUE.
- */
-static Bool
-MatchAttrToken(const char *attr, struct list *patterns,
-               int (*compare)(const char *attr, const char *pattern))
-{
-    const xf86MatchGroup *group;
-
-    /* If there are no patterns, accept the match */
-    if (list_is_empty(patterns))
-        return TRUE;
-
-    /* If there are patterns but no attribute, reject the match */
-    if (!attr)
-        return FALSE;
-
-    /*
-     * Otherwise, iterate the list of patterns ensuring each entry has a
-     * match. Each list entry is a separate Match line of the same type.
-     */
-    list_for_each_entry(group, patterns, entry) {
-        char * const *cur;
-        Bool match = FALSE;
-
-        for (cur = group->values; *cur; cur++)
-            if ((*compare)(attr, *cur) == 0) {
-                match = TRUE;
-                break;
-            }
-        if (!match)
-            return FALSE;
-    }
-
-    /* All the entries in the list matched the attribute */
-    return TRUE;
-}
-
-/*
- * Classes without any Match statements match all devices. Otherwise, all
- * statements must match.
- */
-static Bool
-InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
-                  const InputAttributes *attrs)
-{
-    /* MatchProduct substring */
-    if (!MatchAttrToken(attrs->product, &iclass->match_product, match_substring))
-        return FALSE;
-
-    /* MatchVendor substring */
-    if (!MatchAttrToken(attrs->vendor, &iclass->match_vendor, match_substring))
-        return FALSE;
-
-    /* MatchDevicePath pattern */
-    if (!MatchAttrToken(attrs->device, &iclass->match_device, match_path_pattern))
-        return FALSE;
-
-    /* MatchOS case-insensitive string */
-    if (!MatchAttrToken(HostOS(), &iclass->match_os, strcasecmp))
-        return FALSE;
-
-    /* MatchPnPID pattern */
-    if (!MatchAttrToken(attrs->pnp_id, &iclass->match_pnpid, match_pattern))
-        return FALSE;
-
-    /* MatchUSBID pattern */
-    if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern))
-        return FALSE;
-
-    /* MatchDriver string */
-    if (!MatchAttrToken(idev->driver, &iclass->match_driver, strcmp))
-        return FALSE;
-
-    /*
-     * MatchTag string
-     * See if any of the device's tags match any of the MatchTag tokens.
-     */
-    if (!list_is_empty(&iclass->match_tag)) {
-        char * const *tag;
-        Bool match;
-
-        if (!attrs->tags)
-            return FALSE;
-        for (tag = attrs->tags, match = FALSE; *tag; tag++) {
-            if (MatchAttrToken(*tag, &iclass->match_tag, strcmp)) {
-                match = TRUE;
-                break;
-            }
-        }
-        if (!match)
-            return FALSE;
-    }
-
-    /* MatchIs* booleans */
-    if (iclass->is_keyboard.set &&
-        iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
-        return FALSE;
-    if (iclass->is_pointer.set &&
-        iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER))
-        return FALSE;
-    if (iclass->is_joystick.set &&
-        iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK))
-        return FALSE;
-    if (iclass->is_tablet.set &&
-        iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET))
-        return FALSE;
-    if (iclass->is_touchpad.set &&
-        iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD))
-        return FALSE;
-    if (iclass->is_touchscreen.set &&
-        iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
-        return FALSE;
-
-    return TRUE;
-}
-
-/*
- * Merge in any InputClass configurations. Options in each InputClass
- * section have more priority than the original device configuration as
- * well as any previous InputClass sections.
- */
-static int
-MergeInputClasses(const InputInfoPtr idev, const InputAttributes *attrs)
-{
-    XF86ConfInputClassPtr cl;
-    XF86OptionPtr classopts;
-
-    for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
-        if (!InputClassMatches(cl, idev, attrs))
-            continue;
-
-        /* Collect class options and driver settings */
-        classopts = xf86optionListDup(cl->option_lst);
-        if (cl->driver) {
-            free(idev->driver);
-            idev->driver = xstrdup(cl->driver);
-            if (!idev->driver) {
-                xf86Msg(X_ERROR, "Failed to allocate memory while merging "
-                        "InputClass configuration");
-                return BadAlloc;
-            }
-            classopts = xf86ReplaceStrOption(classopts, "driver",
-                                             idev->driver);
-        }
-
-        /* Apply options to device with InputClass settings preferred. */
-        xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
-                idev->name, cl->identifier);
-        idev->options = xf86optionListMerge(idev->options, classopts);
-    }
-
-    return Success;
-}
-
-/*
- * Iterate the list of classes and look for Option "Ignore". Return the
- * value of the last matching class and holler when returning TRUE.
- */
-static Bool
-IgnoreInputClass(const InputInfoPtr idev, const InputAttributes *attrs)
-{
-    XF86ConfInputClassPtr cl;
-    Bool ignore = FALSE;
-    const char *ignore_class;
-
-    for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
-        if (!InputClassMatches(cl, idev, attrs))
-            continue;
-        if (xf86findOption(cl->option_lst, "Ignore")) {
-            ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
-            ignore_class = cl->identifier;
-        }
-    }
-
-    if (ignore)
-        xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n",
-                idev->name, ignore_class);
-    return ignore;
-}
-
-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;
-    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);
-    xf86OptionListReport(pInfo->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);
-
-    /* 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.
- *
- * Possible return codes:
- *    BadName .. a bad driver name was supplied.
- *    BadImplementation ... The driver does not have a PreInit function. This
- *                          is a driver bug.
- *    BadMatch .. device initialization failed.
- *    BadAlloc .. too many input devices
- *
- * @param idev The device, already set up with identifier, driver, and the
- * options.
- * @param pdev Pointer to the new device, if Success was reported.
- * @param enable Enable the device after activating it.
- *
- * @return Success or an error code
- */
-_X_INTERNAL int
-xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
-{
-    InputDriverPtr drv = 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(pInfo->driver);
-    if (!drv)
-        if (xf86LoadOneModule(pInfo->driver, NULL))
-            drv = xf86LookupInputDriver(pInfo->driver);
-    if (!drv) {
-        xf86Msg(X_ERROR, "No input driver matching `%s'\n", pInfo->driver);
-        rval = BadName;
-        goto unwind;
-    }
-
-    if (!drv->PreInit) {
-        xf86Msg(X_ERROR,
-                "Input driver `%s' has no PreInit function (ignoring)\n",
-                drv->driverName);
-        rval = BadImplementation;
-        goto unwind;
-    }
-
-    xf86AddInput(drv, pInfo);
-
-    rval = drv->PreInit(drv, pInfo, 0);
-
-    if (rval != Success) {
-        xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, pInfo->name);
-        goto unwind;
-    }
-
-    if (!(dev = xf86ActivateDevice(pInfo)))
-    {
-        rval = BadAlloc;
-        goto unwind;
-    }
-
-    rval = ActivateDevice(dev, TRUE);
-    if (rval != Success)
-    {
-        xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
-        RemoveDevice(dev, TRUE);
-        goto unwind;
-    }
-
-    rval = xf86InputDevicePostInit(dev);
-    if (rval != Success)
-    {
-	xf86Msg(X_ERROR, "Couldn't post-init device \"%s\"\n", pInfo->name);
-	RemoveDevice(dev, TRUE);
-	goto unwind;
-    }
-
-    /* Enable it if it's properly initialised and we're currently in the VT */
-    if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema)
-    {
-        EnableDevice(dev, TRUE);
-        if (!dev->enabled)
-        {
-            xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
-            rval = BadMatch;
-            goto unwind;
-        }
-        /* send enter/leave event, update sprite window */
-        CheckMotion(NULL, dev);
-    }
-
-    *pdev = dev;
-    return Success;
-
-unwind:
-    if(pInfo) {
-        if(drv && drv->UnInit)
-            drv->UnInit(drv, pInfo, 0);
-        else
-            xf86DeleteInput(pInfo, 0);
-    }
-    return rval;
-}
-
-int
-NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
-                       DeviceIntPtr *pdev)
-{
-    InputInfoPtr pInfo = NULL;
-    InputOption *option = NULL;
-    int rval = Success;
-    int is_auto = 0;
-
-    pInfo = xf86AllocateInput();
-    if (!pInfo)
-        return BadAlloc;
-
-    for (option = options; option; option = option->next) {
-        if (strcasecmp(option->key, "driver") == 0) {
-            if (pInfo->driver) {
-                rval = BadRequest;
-                goto unwind;
-            }
-            pInfo->driver = xstrdup(option->value);
-            if (!pInfo->driver) {
-                rval = BadAlloc;
-                goto unwind;
-            }
-        }
-
-        if (strcasecmp(option->key, "name") == 0 ||
-            strcasecmp(option->key, "identifier") == 0) {
-            if (pInfo->name) {
-                rval = BadRequest;
-                goto unwind;
-            }
-            pInfo->name = xstrdup(option->value);
-            if (!pInfo->name) {
-                rval = BadAlloc;
-                goto unwind;
-            }
-        }
-
-        if (strcmp(option->key, "_source") == 0 &&
-            (strcmp(option->value, "server/hal") == 0 ||
-             strcmp(option->value, "server/udev") == 0)) {
-            is_auto = 1;
-            if (!xf86Info.autoAddDevices) {
-                rval = BadMatch;
-                goto unwind;
-            }
-        }
-    }
-
-    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. */
-        pInfo->options = xf86addNewOption(pInfo->options,
-                                               option->key, option->value);
-        option->key = NULL;
-        option->value = NULL;
-    }
-
-    /* Apply InputClass settings */
-    if (attrs) {
-        if (IgnoreInputClass(pInfo, attrs)) {
-            rval = BadIDChoice;
-            goto unwind;
-        }
-
-        rval = MergeInputClasses(pInfo, attrs);
-        if (rval != Success)
-            goto unwind;
-
-        pInfo->attrs = DuplicateInputAttributes(attrs);
-    }
-
-    if (!pInfo->driver || !pInfo->name) {
-        xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
-        rval = BadRequest;
-        goto unwind;
-    }
-
-    if (!pInfo->name) {
-        xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
-        rval = BadMatch;
-        goto unwind;
-    }
-
-    rval = xf86NewInputDevice(pInfo, pdev,
-                (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
-
-    return rval;
-
-unwind:
-    if (is_auto && !xf86Info.autoAddDevices)
-        xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
-    xf86DeleteInput(pInfo, 0);
-    return rval;
-}
-
-void
-DeleteInputDeviceRequest(DeviceIntPtr pDev)
-{
-    InputInfoPtr pInfo = (InputInfoPtr) pDev->public.devicePrivate;
-    InputDriverPtr drv = NULL;
-    Bool isMaster = IsMaster(pDev);
-
-    if (pInfo) /* need to get these before RemoveDevice */
-        drv = pInfo->drv;
-
-    OsBlockSignals();
-    RemoveDevice(pDev, TRUE);
-
-    if (!isMaster && pInfo != NULL)
-    {
-        if(drv->UnInit)
-            drv->UnInit(drv, pInfo, 0);
-        else
-            xf86DeleteInput(pInfo, 0);
-    }
-    OsReleaseSignals();
-}
-
-/* 
- * convenient functions to post events
- */
-
-void
-xf86PostMotionEvent(DeviceIntPtr	device,
-                    int			is_absolute,
-                    int			first_valuator,
-                    int			num_valuators,
-                    ...)
-{
-    va_list var;
-    int i = 0;
-    ValuatorMask mask;
-
-    XI_VERIFY_VALUATORS(num_valuators);
-
-    valuator_mask_zero(&mask);
-    va_start(var, num_valuators);
-    for (i = 0; i < num_valuators; i++)
-        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
-    va_end(var);
-
-    xf86PostMotionEventM(device, is_absolute, &mask);
-}
-
-void
-xf86PostMotionEventP(DeviceIntPtr	device,
-                    int			is_absolute,
-                    int			first_valuator,
-                    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;
-
-    if (valuator_mask_num_valuators(mask) > 0)
-    {
-        if (is_absolute)
-            flags = POINTER_ABSOLUTE;
-        else
-            flags = POINTER_RELATIVE | POINTER_ACCELERATE;
-    }
-
-#if XFreeXDGA
-    /* The evdev driver may not always send all axes across. */
-    if (valuator_mask_isset(mask, 0) ||
-        valuator_mask_isset(mask, 1))
-        if (miPointerGetScreen(device)) {
-            int index = miPointerGetScreen(device)->myNum;
-            int dx = 0, dy = 0;
-
-            if (valuator_mask_isset(mask, 0))
-            {
-                dx = valuator_mask_get(mask, 0);
-                if (is_absolute)
-                    dx -= device->last.valuators[0];
-            }
-
-            if (valuator_mask_isset(mask, 1))
-            {
-                dy = valuator_mask_get(mask, 1);
-                if (is_absolute)
-                    dy -= device->last.valuators[1];
-            }
-
-            if (DGAStealMotionEvent(device, index, dx, dy))
-                return;
-        }
-#endif
-
-    nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
-
-    for (i = 0; i < nevents; i++) {
-        event = (DeviceEvent*)((xf86Events + i)->event);
-        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-    }
-}
-
-void
-xf86PostProximityEvent(DeviceIntPtr	device,
-                       int		is_in,
-                       int		first_valuator,
-                       int		num_valuators,
-                       ...)
-{
-    va_list var;
-    int i;
-    ValuatorMask mask;
-
-    XI_VERIFY_VALUATORS(num_valuators);
-
-    valuator_mask_zero(&mask);
-    va_start(var, num_valuators);
-    for (i = 0; i < num_valuators; i++)
-        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
-    va_end(var);
-
-    xf86PostProximityEventM(device, is_in, &mask);
-}
-
-void
-xf86PostProximityEventP(DeviceIntPtr	device,
-                        int		is_in,
-                        int		first_valuator,
-                        int		num_valuators,
-                        const int	*valuators)
-{
-    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, mask);
-    for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
-}
-
-void
-xf86PostButtonEvent(DeviceIntPtr	device,
-                    int			is_absolute,
-                    int			button,
-                    int			is_down,
-                    int			first_valuator,
-                    int			num_valuators,
-                    ...)
-{
-    va_list var;
-    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++)
-        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
-    va_end(var);
-
-    xf86PostButtonEventM(device, is_absolute, button, is_down, &mask);
-}
-
-void
-xf86PostButtonEventP(DeviceIntPtr	device,
-                     int		is_absolute,
-                     int		button,
-                     int		is_down,
-                     int		first_valuator,
-                     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;
-
-    if (valuator_mask_num_valuators(mask) > 0)
-    {
-        if (is_absolute)
-            flags = POINTER_ABSOLUTE;
-        else
-            flags = POINTER_RELATIVE | POINTER_ACCELERATE;
-    }
-
-#if XFreeXDGA
-    if (miPointerGetScreen(device)) {
-        int index = miPointerGetScreen(device)->myNum;
-
-        if (DGAStealButtonEvent(device, index, button, is_down))
-            return;
-    }
-#endif
-
-    nevents = GetPointerEvents(xf86Events, device,
-                               is_down ? ButtonPress : ButtonRelease, button,
-                               flags, mask);
-
-    for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
-}
-
-void
-xf86PostKeyEvent(DeviceIntPtr	device,
-                 unsigned int	key_code,
-                 int		is_down,
-                 int		is_absolute,
-                 int		first_valuator,
-                 int		num_valuators,
-                 ...)
-{
-    va_list var;
-    int i = 0;
-    ValuatorMask mask;
-
-    XI_VERIFY_VALUATORS(num_valuators);
-
-    valuator_mask_zero(&mask);
-
-    va_start(var, num_valuators);
-    for (i = 0; i < num_valuators; i++)
-        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
-    va_end(var);
-
-    xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
-}
-
-void
-xf86PostKeyEventP(DeviceIntPtr	device,
-                  unsigned int	key_code,
-                  int		is_down,
-                  int		is_absolute,
-                  int		first_valuator,
-                  int		num_valuators,
-                  const int	*valuators)
-{
-    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 XFreeXDGA
-    DeviceIntPtr pointer;
-
-    /* Some pointers send key events, paired device is wrong then. */
-    pointer = IsPointerDevice(device) ? device : GetPairedDevice(device);
-    if (miPointerGetScreen(pointer)) {
-        int index = miPointerGetScreen(pointer)->myNum;
-
-        if (DGAStealKeyEvent(device, index, key_code, is_down))
-            return;
-    }
-#endif
-
-    if (is_absolute) {
-        nevents = GetKeyboardValuatorEvents(xf86Events, device,
-                                            is_down ? KeyPress : KeyRelease,
-                                            key_code, mask);
-    }
-    else {
-        nevents = GetKeyboardEvents(xf86Events, device,
-                                    is_down ? KeyPress : KeyRelease,
-                                    key_code);
-    }
-
-    for (i = 0; i < nevents; i++)
-        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-}
-
-void
-xf86PostKeyboardEvent(DeviceIntPtr      device,
-                      unsigned int      key_code,
-                      int               is_down)
-{
-    ValuatorMask mask;
-
-    valuator_mask_zero(&mask);
-    xf86PostKeyEventM(device, key_code, is_down, 0, &mask);
-}
-
-InputInfoPtr
-xf86FirstLocalDevice(void)
-{
-    return xf86InputDevs;
-}
-
-/* 
- * Cx     - raw data from touch screen
- * to_max - scaled highest dimension
- *          (remember, this is of rows - 1 because of 0 origin)
- * to_min  - scaled lowest dimension
- * from_max - highest raw value from touch screen calibration
- * from_min  - lowest raw value from touch screen calibration
- *
- * This function is the same for X or Y coordinates.
- * You may have to reverse the high and low values to compensate for
- * different orgins on the touch screen vs X.
- *
- * e.g. to scale from device coordinates into screen coordinates, call
- * xf86ScaleAxis(x, 0, screen_width, dev_min, dev_max);
- */
-
-int
-xf86ScaleAxis(int	Cx,
-              int	to_max,
-              int	to_min,
-              int	from_max,
-              int	from_min )
-{
-    int X;
-    int64_t to_width = to_max - to_min;
-    int64_t from_width = from_max - from_min;
-
-    if (from_width) {
-	X = (int)(((to_width * (Cx - from_min)) / from_width) + to_min);
-    }
-    else {
-	X = 0;
-	ErrorF ("Divide by Zero in xf86ScaleAxis\n");
-    }
-    
-    if (X > to_max)
-	X = to_max;
-    if (X < to_min)
-	X = to_min;
-    
-    return X;
-}
-
-/*
- * This function checks the given screen against the current screen and
- * makes changes if appropriate. It should be called from an XInput driver's
- * ReadInput function before any events are posted, if the device is screen
- * specific like a touch screen.
- */
-void
-xf86XInputSetScreen(InputInfoPtr	pInfo,
-		    int			screen_number,
-		    int			x,
-		    int			y)
-{
-    if (miPointerGetScreen(pInfo->dev) !=
-          screenInfo.screens[screen_number]) {
-	miPointerSetScreen(pInfo->dev, screen_number, x, y);
-    }
-}
-
-
-void
-xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
-			   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, mode);
-}
-
-/*
- * Set the valuator values to be in synch with dix/event.c
- * DefineInitialRootWindow().
- */
-void
-xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
-{
-    if (axnum == 0) {
-	dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
-        dev->last.valuators[0] = dev->valuator->axisVal[0];
-    }
-    else if (axnum == 1) {
-	dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
-        dev->last.valuators[1] = dev->valuator->axisVal[1];
-    }
-}
-
-
-/**
- * Deactivate a device. Call this function from the driver if you receive a
- * read error or something else that spoils your day.
- * Device will be moved to the off_devices list, but it will still be there
- * until you really clean up after it.
- * Notifies the client about an inactive device.
- * 
- * @param panic True if device is unrecoverable and needs to be removed.
- */
-void
-xf86DisableDevice(DeviceIntPtr dev, Bool panic)
-{
-    if(!panic)
-    {
-        DisableDevice(dev, TRUE);
-    } else
-    {
-        SendDevicePresenceEvent(dev->id, DeviceUnrecoverable);
-        DeleteInputDeviceRequest(dev);
-    }
-}
-
-/**
- * Reactivate a device. Call this function from the driver if you just found
- * out that the read error wasn't quite that bad after all.
- * Device will be re-activated, and an event sent to the client. 
- */
-void
-xf86EnableDevice(DeviceIntPtr dev)
-{
-    EnableDevice(dev, TRUE);
-}
-
-/* end of xf86Xinput.c */
+/*
+ * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
+ *                                                                            
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is  hereby granted without fee, provided that
+ * the  above copyright   notice appear  in   all  copies and  that both  that
+ * copyright  notice   and   this  permission   notice  appear  in  supporting
+ * documentation, and that   the  name of  Frederic   Lepied not  be  used  in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific,  written      prior  permission.     Frederic  Lepied   makes  no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.                   
+ *                                                                            
+ * FREDERIC  LEPIED DISCLAIMS ALL   WARRANTIES WITH REGARD  TO  THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED   WARRANTIES OF MERCHANTABILITY  AND   FITNESS, IN NO
+ * EVENT  SHALL FREDERIC  LEPIED BE   LIABLE   FOR ANY  SPECIAL, INDIRECT   OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA  OR PROFITS, WHETHER  IN  AN ACTION OF  CONTRACT,  NEGLIGENCE OR OTHER
+ * TORTIOUS  ACTION, ARISING    OUT OF OR   IN  CONNECTION  WITH THE USE    OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * Copyright (c) 2000-2002 by The XFree86 Project, 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 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/Xfuncproto.h>
+#include <X11/Xmd.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/Xatom.h>
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Config.h"
+#include "xf86Xinput.h"
+#include "xf86Optrec.h"
+#include "mipointer.h"
+#include "extinit.h"
+#include "loaderProcs.h"
+
+#include "exevents.h"	/* AddInputDevice */
+#include "exglobals.h"
+#include "eventstr.h"
+#include "inpututils.h"
+
+#include <string.h>     /* InputClassMatches */
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif
+#ifdef HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif
+
+#include <stdarg.h>
+#include <stdint.h>          /* for int64_t */
+
+#include "mi.h"
+
+#include <ptrveloc.h>          /* dix pointer acceleration */
+#include <xserver-properties.h>
+
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#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;
+
+static int
+xf86InputDevicePostInit(DeviceIntPtr dev);
+
+/**
+ * Eval config and modify DeviceVelocityRec accordingly
+ */
+static void
+ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
+                             DeviceVelocityPtr s)
+{
+    int tempi;
+    float tempf;
+    Atom float_prop = XIGetKnownProperty(XATOM_FLOAT);
+    Atom prop;
+
+    if(!s)
+        return;
+
+    /* common settings (available via device properties) */
+    tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0);
+    if (tempf > 1.0) {
+        xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n",
+                devname, tempf);
+        prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+        XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+                               PropModeReplace, 1, &tempf, FALSE);
+    }
+
+    tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0);
+    if (tempf > 1.0) {
+        xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n",
+                devname, tempf);
+        prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+        XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+                               PropModeReplace, 1, &tempf, FALSE);
+    }
+
+    /* select profile by number */
+    tempi = xf86SetIntOption(list, "AccelerationProfile",
+            s->statistics.profile_number);
+
+    prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+    if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32,
+                               PropModeReplace, 1, &tempi, FALSE) == Success) {
+        xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname,
+                tempi);
+    } else {
+        xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n",
+                devname, tempi);
+    }
+
+    /* set scaling */
+    tempf = xf86SetRealOption(list, "ExpectedRate", 0);
+    prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
+    if (tempf > 0) {
+        tempf = 1000.0 / tempf;
+        XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+                               PropModeReplace, 1, &tempf, FALSE);
+    } else {
+        tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul);
+        XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+                               PropModeReplace, 1, &tempf, FALSE);
+    }
+
+    tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1);
+    if (tempi > 1)
+	InitTrackers(s, tempi);
+
+    s->initial_range = xf86SetIntOption(list, "VelocityInitialRange",
+                                        s->initial_range);
+
+    s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff);
+
+    tempf = xf86SetRealOption(list, "VelocityRelDiff", -1);
+    if (tempf >= 0) {
+	xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n",
+	        devname, tempf*100.0);
+	s->max_rel_diff = tempf;
+    }
+
+    /*  Configure softening. If const deceleration is used, this is expected
+     *  to provide better subpixel information so we enable
+     *  softening by default only if ConstantDeceleration is not used
+     */
+    s->use_softening = xf86SetBoolOption(list, "Softening",
+                                         s->const_acceleration == 1.0);
+
+    s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging",
+                                         s->average_accel);
+
+    s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time);
+}
+
+static void
+ApplyAccelerationSettings(DeviceIntPtr dev){
+    int scheme, i;
+    DeviceVelocityPtr pVel;
+    InputInfoPtr pInfo = (InputInfoPtr)dev->public.devicePrivate;
+    char* schemeStr;
+
+    if (dev->valuator && dev->ptrfeed) {
+	schemeStr = xf86SetStrOption(pInfo->options, "AccelerationScheme", "");
+
+	scheme = dev->valuator->accelScheme.number;
+
+	if (!xf86NameCmp(schemeStr, "predictable"))
+	    scheme = PtrAccelPredictable;
+
+	if (!xf86NameCmp(schemeStr, "lightweight"))
+	    scheme = PtrAccelLightweight;
+
+	if (!xf86NameCmp(schemeStr, "none"))
+	    scheme = PtrAccelNoOp;
+
+        /* reinit scheme if needed */
+        if (dev->valuator->accelScheme.number != scheme) {
+            if (dev->valuator->accelScheme.AccelCleanupProc) {
+                dev->valuator->accelScheme.AccelCleanupProc(dev);
+            }
+
+            if (InitPointerAccelerationScheme(dev, scheme)) {
+		xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
+		        pInfo->name, schemeStr, scheme);
+	    } else {
+        	xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
+		        pInfo->name, schemeStr);
+        	scheme = dev->valuator->accelScheme.number;
+            }
+        } else {
+            xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
+                    pInfo->name, scheme);
+        }
+
+        free(schemeStr);
+
+        /* process special configuration */
+        switch (scheme) {
+            case PtrAccelPredictable:
+                pVel = GetDevicePredictableAccelData(dev);
+                ProcessVelocityConfiguration (dev, pInfo->name, pInfo->options,
+                                              pVel);
+                break;
+        }
+
+        i = xf86SetIntOption(pInfo->options, "AccelerationNumerator",
+                             dev->ptrfeed->ctrl.num);
+        if (i >= 0)
+            dev->ptrfeed->ctrl.num = i;
+
+        i = xf86SetIntOption(pInfo->options, "AccelerationDenominator",
+                             dev->ptrfeed->ctrl.den);
+        if (i > 0)
+            dev->ptrfeed->ctrl.den = i;
+
+        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",
+                            pInfo->name, ((float)dev->ptrfeed->ctrl.num)/
+                                         ((float)dev->ptrfeed->ctrl.den));
+        xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
+                pInfo->name, dev->ptrfeed->ctrl.threshold);
+    }
+}
+
+/***********************************************************************
+ *
+ * xf86ProcessCommonOptions --
+ * 
+ *	Process global options.
+ *
+ ***********************************************************************
+ */
+void
+xf86ProcessCommonOptions(InputInfoPtr pInfo,
+                         pointer	list)
+{
+    if (xf86SetBoolOption(list, "Floating", 0) ||
+        !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", pInfo->name);
+    } else {
+        pInfo->flags |= XI86_ALWAYS_CORE;
+        xf86Msg(X_CONFIG, "%s: always reports core events\n", pInfo->name);
+    }
+}
+
+/***********************************************************************
+ *
+ * xf86ActivateDevice --
+ *
+ *	Initialize an input device.
+ *
+ * Returns TRUE on success, or FALSE otherwise.
+ ***********************************************************************
+ */
+static DeviceIntPtr
+xf86ActivateDevice(InputInfoPtr pInfo)
+{
+    DeviceIntPtr	dev;
+    Atom		atom;
+
+    dev = AddInputDevice(serverClient, pInfo->device_control, TRUE);
+
+    if (dev == NULL)
+    {
+        xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
+                pInfo->name);
+        pInfo->dev = NULL;
+        return NULL;
+    }
+
+    atom = MakeAtom(pInfo->type_name, strlen(pInfo->type_name), TRUE);
+    AssignTypeAndName(dev, atom, pInfo->name);
+    dev->public.devicePrivate = pInfo;
+    pInfo->dev = dev;
+
+    dev->coreEvents = pInfo->flags & XI86_ALWAYS_CORE;
+    dev->type = SLAVE;
+    dev->spriteInfo->spriteOwner = FALSE;
+
+    dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL);
+
+    if (serverGeneration == 1)
+        xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
+                pInfo->name, pInfo->type_name);
+
+    return dev;
+}
+
+/****************************************************************************
+ *
+ * Caller:	ProcXSetDeviceMode
+ *
+ * Change the mode of an extension device.
+ * This function is used to change the mode of a device from reporting
+ * relative motion to reporting absolute positional information, and
+ * vice versa.
+ * The default implementation below is that no such devices are supported.
+ *
+ ***********************************************************************
+ */
+
+int
+SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+  InputInfoPtr        pInfo = (InputInfoPtr)dev->public.devicePrivate;
+
+  if (pInfo->switch_mode) {
+    return (*pInfo->switch_mode)(client, dev, mode);
+  }
+  else
+    return BadMatch;
+}
+
+
+/***********************************************************************
+ *
+ * Caller:	ProcXSetDeviceValuators
+ *
+ * Set the value of valuators on an extension input device.
+ * This function is used to set the initial value of valuators on
+ * those input devices that are capable of reporting either relative
+ * motion or an absolute position, and allow an initial position to be set.
+ * The default implementation below is that no such devices are supported.
+ *
+ ***********************************************************************
+ */
+
+int
+SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
+                    int first_valuator, int num_valuators)
+{
+    InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate;
+
+    if (pInfo->set_device_valuators)
+	return (*pInfo->set_device_valuators)(pInfo, valuators, first_valuator,
+					      num_valuators);
+
+    return BadMatch;
+}
+
+
+/***********************************************************************
+ *
+ * Caller:	ProcXChangeDeviceControl
+ *
+ * Change the specified device controls on an extension input device.
+ *
+ ***********************************************************************
+ */
+
+int
+ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
+{
+  InputInfoPtr        pInfo = (InputInfoPtr)dev->public.devicePrivate;
+
+  if (!pInfo->control_proc) {
+      switch (control->control) {
+      case DEVICE_CORE:
+          return BadMatch;
+      case DEVICE_RESOLUTION:
+      case DEVICE_ABS_CALIB:
+      case DEVICE_ABS_AREA:
+      case DEVICE_ENABLE:
+        return Success;
+      default:
+        return BadMatch;
+      }
+  }
+  else {
+      return (*pInfo->control_proc)(pInfo, control);
+  }
+}
+
+/*
+ * Get the operating system name from uname and store it statically to avoid
+ * repeating the system call each time MatchOS is checked.
+ */
+static const char *
+HostOS(void)
+{
+#ifdef HAVE_SYS_UTSNAME_H
+    struct utsname name;
+    static char host_os[sizeof(name.sysname)] = "";
+
+    if (*host_os == '\0') {
+        if (uname(&name) >= 0)
+            strcpy(host_os, name.sysname);
+        else {
+            strncpy(host_os, "unknown", sizeof(host_os));
+            host_os[sizeof(host_os)-1] = '\0';
+        }
+    }
+    return host_os;
+#else
+    return "";
+#endif
+}
+
+static int
+match_substring(const char *attr, const char *pattern)
+{
+    return (strstr(attr, pattern)) ? 0 : -1;
+}
+
+#ifdef HAVE_FNMATCH_H
+static int
+match_pattern(const char *attr, const char *pattern)
+{
+    return fnmatch(pattern, attr, 0);
+}
+#else
+#define match_pattern match_substring
+#endif
+
+#ifdef HAVE_FNMATCH_H
+static int
+match_path_pattern(const char *attr, const char *pattern)
+{
+    return fnmatch(pattern, attr, FNM_PATHNAME);
+}
+#else
+#define match_path_pattern match_substring
+#endif
+
+/*
+ * Match an attribute against a list of NULL terminated arrays of patterns.
+ * If a pattern in each list entry is matched, return TRUE.
+ */
+static Bool
+MatchAttrToken(const char *attr, struct list *patterns,
+               int (*compare)(const char *attr, const char *pattern))
+{
+    const xf86MatchGroup *group;
+
+    /* If there are no patterns, accept the match */
+    if (list_is_empty(patterns))
+        return TRUE;
+
+    /* If there are patterns but no attribute, reject the match */
+    if (!attr)
+        return FALSE;
+
+    /*
+     * Otherwise, iterate the list of patterns ensuring each entry has a
+     * match. Each list entry is a separate Match line of the same type.
+     */
+    list_for_each_entry(group, patterns, entry) {
+        char * const *cur;
+        Bool match = FALSE;
+
+        for (cur = group->values; *cur; cur++)
+            if ((*compare)(attr, *cur) == 0) {
+                match = TRUE;
+                break;
+            }
+        if (!match)
+            return FALSE;
+    }
+
+    /* All the entries in the list matched the attribute */
+    return TRUE;
+}
+
+/*
+ * Classes without any Match statements match all devices. Otherwise, all
+ * statements must match.
+ */
+static Bool
+InputClassMatches(const XF86ConfInputClassPtr iclass, const InputInfoPtr idev,
+                  const InputAttributes *attrs)
+{
+    /* MatchProduct substring */
+    if (!MatchAttrToken(attrs->product, &iclass->match_product, match_substring))
+        return FALSE;
+
+    /* MatchVendor substring */
+    if (!MatchAttrToken(attrs->vendor, &iclass->match_vendor, match_substring))
+        return FALSE;
+
+    /* MatchDevicePath pattern */
+    if (!MatchAttrToken(attrs->device, &iclass->match_device, match_path_pattern))
+        return FALSE;
+
+    /* MatchOS case-insensitive string */
+    if (!MatchAttrToken(HostOS(), &iclass->match_os, strcasecmp))
+        return FALSE;
+
+    /* MatchPnPID pattern */
+    if (!MatchAttrToken(attrs->pnp_id, &iclass->match_pnpid, match_pattern))
+        return FALSE;
+
+    /* MatchUSBID pattern */
+    if (!MatchAttrToken(attrs->usb_id, &iclass->match_usbid, match_pattern))
+        return FALSE;
+
+    /* MatchDriver string */
+    if (!MatchAttrToken(idev->driver, &iclass->match_driver, strcmp))
+        return FALSE;
+
+    /*
+     * MatchTag string
+     * See if any of the device's tags match any of the MatchTag tokens.
+     */
+    if (!list_is_empty(&iclass->match_tag)) {
+        char * const *tag;
+        Bool match;
+
+        if (!attrs->tags)
+            return FALSE;
+        for (tag = attrs->tags, match = FALSE; *tag; tag++) {
+            if (MatchAttrToken(*tag, &iclass->match_tag, strcmp)) {
+                match = TRUE;
+                break;
+            }
+        }
+        if (!match)
+            return FALSE;
+    }
+
+    /* MatchIs* booleans */
+    if (iclass->is_keyboard.set &&
+        iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
+        return FALSE;
+    if (iclass->is_pointer.set &&
+        iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER))
+        return FALSE;
+    if (iclass->is_joystick.set &&
+        iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK))
+        return FALSE;
+    if (iclass->is_tablet.set &&
+        iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET))
+        return FALSE;
+    if (iclass->is_touchpad.set &&
+        iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD))
+        return FALSE;
+    if (iclass->is_touchscreen.set &&
+        iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
+        return FALSE;
+
+    return TRUE;
+}
+
+/*
+ * Merge in any InputClass configurations. Options in each InputClass
+ * section have more priority than the original device configuration as
+ * well as any previous InputClass sections.
+ */
+static int
+MergeInputClasses(const InputInfoPtr idev, const InputAttributes *attrs)
+{
+    XF86ConfInputClassPtr cl;
+    XF86OptionPtr classopts;
+
+    for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
+        if (!InputClassMatches(cl, idev, attrs))
+            continue;
+
+        /* Collect class options and driver settings */
+        classopts = xf86optionListDup(cl->option_lst);
+        if (cl->driver) {
+            free(idev->driver);
+            idev->driver = xstrdup(cl->driver);
+            if (!idev->driver) {
+                xf86Msg(X_ERROR, "Failed to allocate memory while merging "
+                        "InputClass configuration");
+                return BadAlloc;
+            }
+            classopts = xf86ReplaceStrOption(classopts, "driver",
+                                             idev->driver);
+        }
+
+        /* Apply options to device with InputClass settings preferred. */
+        xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
+                idev->name, cl->identifier);
+        idev->options = xf86optionListMerge(idev->options, classopts);
+    }
+
+    return Success;
+}
+
+/*
+ * Iterate the list of classes and look for Option "Ignore". Return the
+ * value of the last matching class and holler when returning TRUE.
+ */
+static Bool
+IgnoreInputClass(const InputInfoPtr idev, const InputAttributes *attrs)
+{
+    XF86ConfInputClassPtr cl;
+    Bool ignore = FALSE;
+    const char *ignore_class;
+
+    for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
+        if (!InputClassMatches(cl, idev, attrs))
+            continue;
+        if (xf86findOption(cl->option_lst, "Ignore")) {
+            ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
+            ignore_class = cl->identifier;
+        }
+    }
+
+    if (ignore)
+        xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n",
+                idev->name, ignore_class);
+    return ignore;
+}
+
+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;
+    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);
+    xf86OptionListReport(pInfo->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);
+
+    /* 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.
+ *
+ * Possible return codes:
+ *    BadName .. a bad driver name was supplied.
+ *    BadImplementation ... The driver does not have a PreInit function. This
+ *                          is a driver bug.
+ *    BadMatch .. device initialization failed.
+ *    BadAlloc .. too many input devices
+ *
+ * @param idev The device, already set up with identifier, driver, and the
+ * options.
+ * @param pdev Pointer to the new device, if Success was reported.
+ * @param enable Enable the device after activating it.
+ *
+ * @return Success or an error code
+ */
+_X_INTERNAL int
+xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable)
+{
+    InputDriverPtr drv = 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(pInfo->driver);
+    if (!drv)
+        if (xf86LoadOneModule(pInfo->driver, NULL))
+            drv = xf86LookupInputDriver(pInfo->driver);
+    if (!drv) {
+        xf86Msg(X_ERROR, "No input driver matching `%s'\n", pInfo->driver);
+        rval = BadName;
+        goto unwind;
+    }
+
+    if (!drv->PreInit) {
+        xf86Msg(X_ERROR,
+                "Input driver `%s' has no PreInit function (ignoring)\n",
+                drv->driverName);
+        rval = BadImplementation;
+        goto unwind;
+    }
+
+    xf86AddInput(drv, pInfo);
+
+    rval = drv->PreInit(drv, pInfo, 0);
+
+    if (rval != Success) {
+        xf86Msg(X_ERROR, "PreInit returned %d for \"%s\"\n", rval, pInfo->name);
+        goto unwind;
+    }
+
+    if (!(dev = xf86ActivateDevice(pInfo)))
+    {
+        rval = BadAlloc;
+        goto unwind;
+    }
+
+    rval = ActivateDevice(dev, TRUE);
+    if (rval != Success)
+    {
+        xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
+        RemoveDevice(dev, TRUE);
+        goto unwind;
+    }
+
+    rval = xf86InputDevicePostInit(dev);
+    if (rval != Success)
+    {
+	xf86Msg(X_ERROR, "Couldn't post-init device \"%s\"\n", pInfo->name);
+	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)
+    {
+        OsBlockSignals();
+        EnableDevice(dev, TRUE);
+        if (!dev->enabled)
+        {
+            OsReleaseSignals();
+            xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name);
+            rval = BadMatch;
+            goto unwind;
+        }
+        /* send enter/leave event, update sprite window */
+        CheckMotion(NULL, dev);
+        OsReleaseSignals();
+    }
+
+    *pdev = dev;
+    return Success;
+
+unwind:
+    if(pInfo) {
+        if(drv && drv->UnInit)
+            drv->UnInit(drv, pInfo, 0);
+        else
+            xf86DeleteInput(pInfo, 0);
+    }
+    return rval;
+}
+
+int
+NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
+                       DeviceIntPtr *pdev)
+{
+    InputInfoPtr pInfo = NULL;
+    InputOption *option = NULL;
+    int rval = Success;
+    int is_auto = 0;
+
+    pInfo = xf86AllocateInput();
+    if (!pInfo)
+        return BadAlloc;
+
+    for (option = options; option; option = option->next) {
+        if (strcasecmp(option->key, "driver") == 0) {
+            if (pInfo->driver) {
+                rval = BadRequest;
+                goto unwind;
+            }
+            pInfo->driver = xstrdup(option->value);
+            if (!pInfo->driver) {
+                rval = BadAlloc;
+                goto unwind;
+            }
+        }
+
+        if (strcasecmp(option->key, "name") == 0 ||
+            strcasecmp(option->key, "identifier") == 0) {
+            if (pInfo->name) {
+                rval = BadRequest;
+                goto unwind;
+            }
+            pInfo->name = xstrdup(option->value);
+            if (!pInfo->name) {
+                rval = BadAlloc;
+                goto unwind;
+            }
+        }
+
+        if (strcmp(option->key, "_source") == 0 &&
+            (strcmp(option->value, "server/hal") == 0 ||
+             strcmp(option->value, "server/udev") == 0)) {
+            is_auto = 1;
+            if (!xf86Info.autoAddDevices) {
+                rval = BadMatch;
+                goto unwind;
+            }
+        }
+    }
+
+    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. */
+        pInfo->options = xf86addNewOption(pInfo->options,
+                                               option->key, option->value);
+        option->key = NULL;
+        option->value = NULL;
+    }
+
+    /* Apply InputClass settings */
+    if (attrs) {
+        if (IgnoreInputClass(pInfo, attrs)) {
+            rval = BadIDChoice;
+            goto unwind;
+        }
+
+        rval = MergeInputClasses(pInfo, attrs);
+        if (rval != Success)
+            goto unwind;
+
+        pInfo->attrs = DuplicateInputAttributes(attrs);
+    }
+
+    if (!pInfo->driver || !pInfo->name) {
+        xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
+        rval = BadRequest;
+        goto unwind;
+    }
+
+    if (!pInfo->name) {
+        xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
+        rval = BadMatch;
+        goto unwind;
+    }
+
+    rval = xf86NewInputDevice(pInfo, pdev,
+                (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
+
+    return rval;
+
+unwind:
+    if (is_auto && !xf86Info.autoAddDevices)
+        xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
+    xf86DeleteInput(pInfo, 0);
+    return rval;
+}
+
+void
+DeleteInputDeviceRequest(DeviceIntPtr pDev)
+{
+    InputInfoPtr pInfo = (InputInfoPtr) pDev->public.devicePrivate;
+    InputDriverPtr drv = NULL;
+    Bool isMaster = IsMaster(pDev);
+
+    if (pInfo) /* need to get these before RemoveDevice */
+        drv = pInfo->drv;
+
+    OsBlockSignals();
+    RemoveDevice(pDev, TRUE);
+
+    if (!isMaster && pInfo != NULL)
+    {
+        if(drv->UnInit)
+            drv->UnInit(drv, pInfo, 0);
+        else
+            xf86DeleteInput(pInfo, 0);
+    }
+    OsReleaseSignals();
+}
+
+/* 
+ * convenient functions to post events
+ */
+
+void
+xf86PostMotionEvent(DeviceIntPtr	device,
+                    int			is_absolute,
+                    int			first_valuator,
+                    int			num_valuators,
+                    ...)
+{
+    va_list var;
+    int i = 0;
+    ValuatorMask mask;
+
+    XI_VERIFY_VALUATORS(num_valuators);
+
+    valuator_mask_zero(&mask);
+    va_start(var, num_valuators);
+    for (i = 0; i < num_valuators; i++)
+        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
+    va_end(var);
+
+    xf86PostMotionEventM(device, is_absolute, &mask);
+}
+
+void
+xf86PostMotionEventP(DeviceIntPtr	device,
+                    int			is_absolute,
+                    int			first_valuator,
+                    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;
+
+    if (valuator_mask_num_valuators(mask) > 0)
+    {
+        if (is_absolute)
+            flags = POINTER_ABSOLUTE;
+        else
+            flags = POINTER_RELATIVE | POINTER_ACCELERATE;
+    }
+
+#if XFreeXDGA
+    /* The evdev driver may not always send all axes across. */
+    if (valuator_mask_isset(mask, 0) ||
+        valuator_mask_isset(mask, 1))
+        if (miPointerGetScreen(device)) {
+            int index = miPointerGetScreen(device)->myNum;
+            int dx = 0, dy = 0;
+
+            if (valuator_mask_isset(mask, 0))
+            {
+                dx = valuator_mask_get(mask, 0);
+                if (is_absolute)
+                    dx -= device->last.valuators[0];
+            }
+
+            if (valuator_mask_isset(mask, 1))
+            {
+                dy = valuator_mask_get(mask, 1);
+                if (is_absolute)
+                    dy -= device->last.valuators[1];
+            }
+
+            if (DGAStealMotionEvent(device, index, dx, dy))
+                return;
+        }
+#endif
+
+    nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
+
+    for (i = 0; i < nevents; i++) {
+        event = (DeviceEvent*)((xf86Events + i)->event);
+        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+    }
+}
+
+void
+xf86PostProximityEvent(DeviceIntPtr	device,
+                       int		is_in,
+                       int		first_valuator,
+                       int		num_valuators,
+                       ...)
+{
+    va_list var;
+    int i;
+    ValuatorMask mask;
+
+    XI_VERIFY_VALUATORS(num_valuators);
+
+    valuator_mask_zero(&mask);
+    va_start(var, num_valuators);
+    for (i = 0; i < num_valuators; i++)
+        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
+    va_end(var);
+
+    xf86PostProximityEventM(device, is_in, &mask);
+}
+
+void
+xf86PostProximityEventP(DeviceIntPtr	device,
+                        int		is_in,
+                        int		first_valuator,
+                        int		num_valuators,
+                        const int	*valuators)
+{
+    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, mask);
+    for (i = 0; i < nevents; i++)
+        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+
+}
+
+void
+xf86PostButtonEvent(DeviceIntPtr	device,
+                    int			is_absolute,
+                    int			button,
+                    int			is_down,
+                    int			first_valuator,
+                    int			num_valuators,
+                    ...)
+{
+    va_list var;
+    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++)
+        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
+    va_end(var);
+
+    xf86PostButtonEventM(device, is_absolute, button, is_down, &mask);
+}
+
+void
+xf86PostButtonEventP(DeviceIntPtr	device,
+                     int		is_absolute,
+                     int		button,
+                     int		is_down,
+                     int		first_valuator,
+                     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;
+
+    if (valuator_mask_num_valuators(mask) > 0)
+    {
+        if (is_absolute)
+            flags = POINTER_ABSOLUTE;
+        else
+            flags = POINTER_RELATIVE | POINTER_ACCELERATE;
+    }
+
+#if XFreeXDGA
+    if (miPointerGetScreen(device)) {
+        int index = miPointerGetScreen(device)->myNum;
+
+        if (DGAStealButtonEvent(device, index, button, is_down))
+            return;
+    }
+#endif
+
+    nevents = GetPointerEvents(xf86Events, device,
+                               is_down ? ButtonPress : ButtonRelease, button,
+                               flags, mask);
+
+    for (i = 0; i < nevents; i++)
+        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+
+}
+
+void
+xf86PostKeyEvent(DeviceIntPtr	device,
+                 unsigned int	key_code,
+                 int		is_down,
+                 int		is_absolute,
+                 int		first_valuator,
+                 int		num_valuators,
+                 ...)
+{
+    va_list var;
+    int i = 0;
+    ValuatorMask mask;
+
+    XI_VERIFY_VALUATORS(num_valuators);
+
+    valuator_mask_zero(&mask);
+
+    va_start(var, num_valuators);
+    for (i = 0; i < num_valuators; i++)
+        valuator_mask_set(&mask, first_valuator + i, va_arg(var, int));
+    va_end(var);
+
+    xf86PostKeyEventM(device, key_code, is_down, is_absolute, &mask);
+}
+
+void
+xf86PostKeyEventP(DeviceIntPtr	device,
+                  unsigned int	key_code,
+                  int		is_down,
+                  int		is_absolute,
+                  int		first_valuator,
+                  int		num_valuators,
+                  const int	*valuators)
+{
+    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 XFreeXDGA
+    DeviceIntPtr pointer;
+
+    /* Some pointers send key events, paired device is wrong then. */
+    pointer = IsPointerDevice(device) ? device : GetPairedDevice(device);
+    if (miPointerGetScreen(pointer)) {
+        int index = miPointerGetScreen(pointer)->myNum;
+
+        if (DGAStealKeyEvent(device, index, key_code, is_down))
+            return;
+    }
+#endif
+
+    if (is_absolute) {
+        nevents = GetKeyboardValuatorEvents(xf86Events, device,
+                                            is_down ? KeyPress : KeyRelease,
+                                            key_code, mask);
+    }
+    else {
+        nevents = GetKeyboardEvents(xf86Events, device,
+                                    is_down ? KeyPress : KeyRelease,
+                                    key_code);
+    }
+
+    for (i = 0; i < nevents; i++)
+        mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+}
+
+void
+xf86PostKeyboardEvent(DeviceIntPtr      device,
+                      unsigned int      key_code,
+                      int               is_down)
+{
+    ValuatorMask mask;
+
+    valuator_mask_zero(&mask);
+    xf86PostKeyEventM(device, key_code, is_down, 0, &mask);
+}
+
+InputInfoPtr
+xf86FirstLocalDevice(void)
+{
+    return xf86InputDevs;
+}
+
+/* 
+ * Cx     - raw data from touch screen
+ * to_max - scaled highest dimension
+ *          (remember, this is of rows - 1 because of 0 origin)
+ * to_min  - scaled lowest dimension
+ * from_max - highest raw value from touch screen calibration
+ * from_min  - lowest raw value from touch screen calibration
+ *
+ * This function is the same for X or Y coordinates.
+ * You may have to reverse the high and low values to compensate for
+ * different orgins on the touch screen vs X.
+ *
+ * e.g. to scale from device coordinates into screen coordinates, call
+ * xf86ScaleAxis(x, 0, screen_width, dev_min, dev_max);
+ */
+
+int
+xf86ScaleAxis(int	Cx,
+              int	to_max,
+              int	to_min,
+              int	from_max,
+              int	from_min )
+{
+    int X;
+    int64_t to_width = to_max - to_min;
+    int64_t from_width = from_max - from_min;
+
+    if (from_width) {
+	X = (int)(((to_width * (Cx - from_min)) / from_width) + to_min);
+    }
+    else {
+	X = 0;
+	ErrorF ("Divide by Zero in xf86ScaleAxis\n");
+    }
+    
+    if (X > to_max)
+	X = to_max;
+    if (X < to_min)
+	X = to_min;
+    
+    return X;
+}
+
+/*
+ * This function checks the given screen against the current screen and
+ * makes changes if appropriate. It should be called from an XInput driver's
+ * ReadInput function before any events are posted, if the device is screen
+ * specific like a touch screen.
+ */
+void
+xf86XInputSetScreen(InputInfoPtr	pInfo,
+		    int			screen_number,
+		    int			x,
+		    int			y)
+{
+    if (miPointerGetScreen(pInfo->dev) !=
+          screenInfo.screens[screen_number]) {
+	miPointerSetScreen(pInfo->dev, screen_number, x, y);
+    }
+}
+
+
+void
+xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
+			   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, mode);
+}
+
+/*
+ * Set the valuator values to be in synch with dix/event.c
+ * DefineInitialRootWindow().
+ */
+void
+xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
+{
+    if (axnum == 0) {
+	dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
+        dev->last.valuators[0] = dev->valuator->axisVal[0];
+    }
+    else if (axnum == 1) {
+	dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
+        dev->last.valuators[1] = dev->valuator->axisVal[1];
+    }
+}
+
+
+/**
+ * Deactivate a device. Call this function from the driver if you receive a
+ * read error or something else that spoils your day.
+ * Device will be moved to the off_devices list, but it will still be there
+ * until you really clean up after it.
+ * Notifies the client about an inactive device.
+ * 
+ * @param panic True if device is unrecoverable and needs to be removed.
+ */
+void
+xf86DisableDevice(DeviceIntPtr dev, Bool panic)
+{
+    if(!panic)
+    {
+        DisableDevice(dev, TRUE);
+    } else
+    {
+        SendDevicePresenceEvent(dev->id, DeviceUnrecoverable);
+        DeleteInputDeviceRequest(dev);
+    }
+}
+
+/**
+ * Reactivate a device. Call this function from the driver if you just found
+ * out that the read error wasn't quite that bad after all.
+ * Device will be re-activated, and an event sent to the client. 
+ */
+void
+xf86EnableDevice(DeviceIntPtr dev)
+{
+    EnableDevice(dev, TRUE);
+}
+
+/* end of xf86Xinput.c */
diff --git a/xorg-server/hw/xfree86/doc/Makefile.am b/xorg-server/hw/xfree86/doc/Makefile.am
index 80217365d..acb8937f0 100644
--- a/xorg-server/hw/xfree86/doc/Makefile.am
+++ b/xorg-server/hw/xfree86/doc/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = devel man sgml
-
-EXTRA_DIST = \
-	README.modes
+SUBDIRS = devel sgml
+
+EXTRA_DIST = \
+	README.modes
diff --git a/xorg-server/hw/xfree86/doc/man/Makefile.am b/xorg-server/hw/xfree86/doc/man/Makefile.am
deleted file mode 100644
index 80e22cbab..000000000
--- a/xorg-server/hw/xfree86/doc/man/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-include $(top_srcdir)/manpages.am
-appman_PRE = Xorg.man
-fileman_PRE = xorg.conf.man xorg.conf.d.man
diff --git a/xorg-server/hw/xfree86/doc/man/Xorg.man b/xorg-server/hw/xfree86/doc/man/Xorg.man
deleted file mode 100644
index 6fa334cc3..000000000
--- a/xorg-server/hw/xfree86/doc/man/Xorg.man
+++ /dev/null
@@ -1,689 +0,0 @@
-.\" $XdotOrg: xserver/xorg/hw/xfree86/doc/man/Xorg.man.pre,v 1.3 2005/07/04 18:41:01 ajax Exp $
-.\" shorthand for double quote that works everywhere.
-.ds q \N'34'
-.TH __xservername__ __appmansuffix__ __vendorversion__
-.SH NAME
-__xservername__ - X11R7 X server
-.SH SYNOPSIS
-.B __xservername__
-.RI [\fB:\fP display ]
-.RI [ option
-.IR ... ]
-.SH DESCRIPTION
-.B __xservername__
-is a full featured X server that was originally designed for UNIX and
-UNIX-like operating systems running on Intel x86 hardware.  It now runs
-on a wider range of hardware and OS platforms.
-.PP
-This work was derived by the X.Org Foundation from the XFree86 Project's
-.I "XFree86\ 4.4rc2"
-release.
-The XFree86 release was originally derived from
-.I "X386\ 1.2"
-by Thomas Roell which was contributed to X11R5 by Snitily Graphics
-Consulting Service.
-.SH PLATFORMS
-.PP
-.B __xservername__
-operates under a wide range of operating systems and hardware platforms.
-The Intel x86 (IA32) architecture is the most widely supported hardware
-platform.  Other hardware platforms include Compaq Alpha, Intel IA64, AMD64,
-SPARC and PowerPC.  The most widely supported operating systems are the
-free/OpenSource UNIX-like systems such as Linux, FreeBSD, NetBSD,
-OpenBSD, and Solaris.  Commercial UNIX operating systems such as
-UnixWare are also supported.  Other supported operating systems include
-GNU Hurd.  Mac OS X is supported with the
-Xquartz(__appmansuffix__) X server.  Win32/Cygwin is supported with the
-XWin(__appmansuffix__) X server.
-.PP
-.SH "NETWORK CONNECTIONS"
-.B __xservername__
-supports connections made using the following reliable
-byte-streams:
-.TP 4
-.I "Local"
-On most platforms, the "Local" connection type is a UNIX-domain socket.
-On some System V platforms, the "local" connection types also include
-STREAMS pipes, named pipes, and some other mechanisms.
-.TP 4
-.I TCP\/IP
-.B __xservername__
-listens on port
-.RI 6000+ n ,
-where
-.I n
-is the display number.  This connection type can be disabled with the
-.B \-nolisten
-option (see the Xserver(1) man page for details).
-.SH "ENVIRONMENT VARIABLES"
-For operating systems that support local connections other than Unix
-Domain sockets (SVR3 and SVR4), there is a compiled-in list specifying
-the order in which local connections should be attempted.  This list
-can be overridden by the
-.I XLOCAL
-environment variable described below.  If the display name indicates a
-best-choice connection should be made (e.g.
-.BR :0.0 ),
-each connection mechanism is tried until a connection succeeds or no
-more mechanisms are available.  Note: for these OSs, the Unix Domain
-socket connection is treated differently from the other local connection
-types.  To use it the connection must be made to
-.BR unix:0.0 .
-.PP
-The
-.I XLOCAL
-environment variable should contain a list of one more
-more of the following:
-.PP
-.RS 8
-.nf
-NAMED
-PTS
-SCO
-ISC
-.fi
-.RE
-.PP
-which represent SVR4 Named Streams pipe, Old-style USL Streams pipe,
-SCO XSight Streams pipe, and ISC Streams pipe, respectively.  You can
-select a single mechanism (e.g.
-.IR XLOCAL=NAMED ),
-or an ordered list (e.g. \fIXLOCAL="NAMED:PTS:SCO"\fP).
-his variable overrides the compiled-in defaults.  For SVR4 it is
-recommended that
-.I NAMED
-be the first preference connection.  The default setting is
-.IR PTS:NAMED:ISC:SCO .
-.PP
-To globally override the compiled-in defaults, you should define (and
-export if using
-.B sh
-or
-.BR ksh )
-.I XLOCAL
-globally.  If you use startx(1) or xinit(1), the definition should be
-at the top of your
-.I .xinitrc
-file.  If you use xdm(1), the definitions should be early on in the
-.I __projectroot__/lib/X11/xdm/Xsession
-script.
-.SH OPTIONS
-.B __xservername__
-supports several mechanisms for supplying/obtaining configuration and
-run-time parameters: command line options, environment variables, the
-__xconfigfile__(__filemansuffix__) configuration files, auto-detection, and
-fallback defaults.  When the same information is supplied in more than
-one way, the highest precedence mechanism is used.  The list of mechanisms
-is ordered from highest precedence to lowest.  Note that not all parameters
-can be supplied via all methods.  The available command line options
-and environment variables (and some defaults) are described here and in
-the Xserver(__appmansuffix__) manual page.  Most configuration file
-parameters, with their defaults, are described in the
-__xconfigfile__(__filemansuffix__) manual page.  Driver and module specific
-configuration parameters are described in the relevant driver or module
-manual page.
-.PP
-In addition to the normal server options described in the
-Xserver(__appmansuffix__) manual page,
-.B __xservername__
-accepts the following command line switches:
-.TP 8
-.BI vt XX
-.I XX
-specifies the Virtual Terminal device number which
-.B __xservername__
-will use.  Without this option,
-.B __xservername__
-will pick the first available Virtual Terminal that it can locate.  This
-option applies only to platforms that have virtual terminal support, such
-as Linux, BSD, OpenSolaris, SVR3, and SVR4.
-.TP
-.B \-allowMouseOpenFail
-Allow the server to start up even if the mouse device can't be opened
-or initialised.  This is equivalent to the
-.B AllowMouseOpenFail
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B \-allowNonLocalXvidtune
-Make the VidMode extension available to remote clients.  This allows
-the xvidtune client to connect from another host.  This is equivalent
-to the
-.B AllowNonLocalXvidtune
-__xconfigfile__(__filemansuffix__) file option.  By default non-local
-connections are not allowed.
-.TP 8
-.BI \-bgamma " value"
-Set the blue gamma correction.
-.I value
-must be between 0.1 and 10.
-The default is 1.0.  Not all drivers support this.  See also the
-.BR \-gamma ,
-.BR \-rgamma ,
-and
-.B \-ggamma
-options.
-.TP 8
-.BI \-bpp " n"
-No longer supported.  Use
-.B \-depth
-to set the color depth, and use
-.B \-fbbpp
-if you really need to force a non-default framebuffer (hardware) pixel
-format.
-.TP 8
-.BI \-config " file"
-Read the server configuration from
-.IR file .
-This option will work for any file when the server is run as root (i.e,
-with real-uid 0), or for files relative to a directory in the config
-search path for all other users.
-.TP 8
-.BI \-configdir " directory"
-Read the server configuration files from
-.IR directory .
-This option will work for any directory when the server is run as root
-(i.e, with real-uid 0), or for directories relative to a directory in the
-config directory search path for all other users.
-.TP 8
-.B \-configure
-When this option is specified, the
-.B __xservername__
-server loads all video driver modules, probes for available hardware,
-and writes out an initial __xconfigfile__(__filemansuffix__) file based on
-what was detected.  This option currently has some problems on some
-platforms, but in most cases it is a good way to bootstrap the
-configuration process.  This option is only available when the server
-is run as root (i.e, with real-uid 0).
-.TP 8
-.BI "\-crt /dev/tty" XX
-SCO only.  This is the same as the
-.B vt
-option, and is provided for compatibility with the native SCO X server.
-.TP 8
-.BI \-depth " n"
-Sets the default color depth.  Legal values are 1, 4, 8, 15, 16, and
-24.  Not all drivers support all values.
-.TP 8
-.B \-disableVidMode
-Disable the parts of the VidMode extension (used by the xvidtune
-client) that can be used to change the video modes.  This is equivalent
-to the
-.B DisableVidModeExtension
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B \-fbbpp \fIn\fP
-Sets the number of framebuffer bits per pixel.  You should only set this
-if you're sure it's necessary; normally the server can deduce the correct
-value from
-.B \-depth
-above.  Useful if you want to run a depth 24 configuration with a 24
-bpp framebuffer rather than the (possibly default) 32 bpp framebuffer
-(or vice versa).  Legal values are 1, 8, 16, 24, 32.  Not all drivers
-support all values.
-.TP 8
-.B \-flipPixels
-Swap the default values for the black and white pixels.
-.TP 8
-.BI \-gamma " value"
-Set the gamma correction.
-.I value
-must be between 0.1 and 10.  The default is 1.0.  This value is applied
-equally to the R, G and B values.  Those values can be set independently
-with the
-.BR \-rgamma ,
-.BR \-bgamma ,
-and
-.B \-ggamma
-options.  Not all drivers support this.
-.TP 8
-.BI \-ggamma " value"
-Set the green gamma correction.
-.I value
-must be between 0.1 and 10.  The default is 1.0.  Not all drivers support
-this.  See also the
-.BR \-gamma ,
-.BR \-rgamma ,
-and
-.B \-bgamma
-options.
-.TP 8
-.B \-ignoreABI
-The
-.B __xservername__
-server checks the ABI revision levels of each module that it loads.  It
-will normally refuse to load modules with ABI revisions that are newer
-than the server's.  This is because such modules might use interfaces
-that the server does not have.  When this option is specified, mismatches
-like this are downgraded from fatal errors to warnings.  This option
-should be used with care.
-.TP 8
-.B \-isolateDevice \fIbus\-id\fP
-Restrict device resets to the device at
-.IR bus\-id .
-The
-.I bus\-id
-string has the form
-.IB bustype : bus : device : function
-(e.g., \(oqPCI:1:0:0\(cq).
-At present, only isolation of PCI devices is supported; i.e., this option
-is ignored if
-.I bustype
-is anything other than \(oqPCI\(cq.
-.TP 8
-.B \-keeptty
-Prevent the server from detaching its initial controlling terminal.
-This option is only useful when debugging the server.  Not all platforms
-support (or can use) this option.
-.TP 8
-.BI \-keyboard " keyboard-name"
-Use the __xconfigfile__(__filemansuffix__) file
-.B InputDevice
-section called
-.I keyboard-name
-as the core keyboard.  This option is ignored when the
-.B Layout
-section specifies a core keyboard.  In the absence of both a Layout
-section and this option, the first relevant
-.B InputDevice
-section is used for the core keyboard.
-.TP 8
-.BI \-layout " layout-name"
-Use the __xconfigfile__(__filemansuffix__) file
-.B Layout
-section called
-.IR layout-name .
-By default the first
-.B Layout
-section is used.
-.TP 8
-.BI \-logfile " filename"
-Use the file called
-.I filename
-as the
-.B __xservername__
-server log file.  The default log file is
-.BI __logdir__/__xservername__. n .log
-on most platforms, where
-.I n
-is the display number of the
-.B __xservername__
-server.  The default may be in a different directory on some platforms.
-This option is only available when the server is run as root (i.e, with
-real-uid 0).
-.TP 8
-.BR \-logverbose " [\fIn\fP]"
-Sets the verbosity level for information printed to the
-.B __xservername__
-server log file.  If the
-.I n
-value isn't supplied, each occurrence of this option increments the log
-file verbosity level.  When the
-.I n
-value is supplied, the log file verbosity level is set to that value.
-The default log file verbosity level is 3.
-.TP 8
-.BI \-modulepath " searchpath"
-Set the module search path to
-.IR searchpath .
-.I searchpath
-is a comma separated list of directories to search for
-.B __xservername__
-server modules.  This option is only available when the server is run
-as root (i.e, with real-uid 0).
-.TP 8
-.B \-nosilk
-Disable Silken Mouse support.
-.TP 8
-.B \-pixmap24
-Set the internal pixmap format for depth 24 pixmaps to 24 bits per pixel.
-The default is usually 32 bits per pixel.  There is normally little
-reason to use this option.  Some client applications don't like this
-pixmap format, even though it is a perfectly legal format.  This is
-equivalent to the
-.B Pixmap
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B \-pixmap32
-Set the internal pixmap format for depth 24 pixmaps to 32 bits per pixel.
-This is usually the default.  This is equivalent to the
-.B Pixmap
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.BI \-pointer " pointer-name"
-Use the __xconfigfile__(__filemansuffix__) file
-.B InputDevice
-section called
-.I pointer-name
-as the core pointer.  This option is ignored when the
-.B Layout
-section specifies a core pointer.  In the absence of both a Layout
-section and this option, the first relevant
-.B InputDevice
-section is used for the core pointer.
-.TP 8
-.B \-quiet
-Suppress most informational messages at startup.  The verbosity level
-is set to zero.
-.TP 8
-.BI \-rgamma " value"
-Set the red gamma correction.
-.I value
-must be between 0.1 and 10.  The default is 1.0.  Not all drivers support
-this.  See also the
-.BR \-gamma ,
-.BR \-bgamma ,
-and
-.B \-ggamma
-options.
-.TP 8
-.BI \-screen " screen-name"
-Use the __xconfigfile__(__filemansuffix__) file
-.B Screen
-section called
-.IR screen-name .
-By default the screens referenced by the default
-.B Layout
-section are used, or the first
-.B Screen
-section when there are no
-.B Layout
-sections.
-.TP 8
-.B \-showconfig
-This is the same as the
-.B \-version
-option, and is included for compatibility reasons.  It may be removed
-in a future release, so the
-.B \-version
-option should be used instead.
-.TP 8
-.B \-showDefaultModulePath
-Print out the default module path the server was compiled with.
-.TP 8
-.B \-showDefaultLibPath
-Print out the path libraries should be installed to.
-.TP 8
-.B \-showopts
-For each driver module installed, print out the list of options and their
-argument types.
-.TP 8
-.BI \-weight " nnn"
-Set RGB weighting at 16 bpp.  The default is 565.  This applies only to
-those drivers which support 16 bpp.
-.TP 8
-.BR \-verbose " [\fIn\fP]"
-Sets the verbosity level for information printed on stderr.  If the
-.I n
-value isn't supplied, each occurrence of this option increments the
-verbosity level.  When the
-.I n
-value is supplied, the verbosity level is set to that value.  The default
-verbosity level is 0.
-.TP 8
-.B \-version
-Print out the server version, patchlevel, release date, the operating
-system/platform it was built on, and whether it includes module loader
-support.
-.SH "KEYBOARD"
-.PP
-The
-.B __xservername__
-server is normally configured to recognize various special combinations
-of key presses that instruct the server to perform some action, rather
-than just sending the key press event to a client application. These actions
-depend on the XKB keymap loaded by a particular keyboard device and may or
-may not be available on a given configuration.
-.PP
-The following key combinations are commonly part of the default XKEYBOARD
-keymap.
-.TP 8
-.B Ctrl+Alt+Backspace
-Immediately kills the server -- no questions asked. It can be disabled by
-setting the
-.B DontZap
-__xconfigfile__(__filemansuffix__) file option to a TRUE value.
-.PP
-.RS 8
-It should be noted that zapping is triggered by the
-.B Terminate_Server
-action in the keyboard map. This action is not part of the default keymaps
-but can be enabled with the XKB option
-.B \*qterminate:ctrl_alt_bksp\*q.
-.RE
-.TP 8
-.B Ctrl+Alt+Keypad-Plus
-Change video mode to next one specified in the configuration file.
-This can be disabled with the
-.B DontZoom
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B Ctrl+Alt+Keypad-Minus
-Change video mode to previous one specified in the configuration file.
-This can be disabled with the
-.B DontZoom
-__xconfigfile__(__filemansuffix__) file option.
-.TP 8
-.B Ctrl+Alt+F1...F12
-For systems with virtual terminal support, these keystroke
-combinations are used to switch to virtual terminals 1 through 12,
-respectively.  This can be disabled with the
-.B DontVTSwitch
-__xconfigfile__(__filemansuffix__) file option.
-.SH CONFIGURATION
-.B __xservername__
-typically uses a configuration file called
-.B __xconfigfile__
-and configuration files with the suffix
-.I .conf
-in a directory called
-.B __xconfigdir__
-for its initial setup.
-Refer to the __xconfigfile__(__filemansuffix__) manual page for information
-about the format of this file.
-.PP
-.B __xservername__
-has a mechanism for automatically generating a built-in configuration
-at run-time when no
-.B __xconfigfile__
-file or
-.B __xconfigdir__
-files are present.  The current version of this automatic configuration
-mechanism works in two ways.
-.PP
-The first is via enhancements that have made many components of the
-.B __xconfigfile__
-file optional.  This means that information that can be probed or
-reasonably deduced doesn't need to be specified explicitly, greatly
-reducing the amount of built-in configuration information that needs to
-be generated at run-time.
-.PP
-The second is to have "safe" fallbacks for most configuration information.
-This maximises the likelihood that the
-.B __xservername__
-server will start up in some usable configuration even when information
-about the specific hardware is not available.
-.PP
-The automatic configuration support for __xservername__ is work in progress.
-It is currently aimed at the most popular hardware and software platforms
-supported by __xservername__.  Enhancements are planned for future releases.
-.SH FILES
-The
-.B __xservername__
-server config files can be found in a range of locations.  These are
-documented fully in the __xconfigfile__(__filemansuffix__) manual page.  The
-most commonly used locations are shown here.
-.TP 30
-.B /etc/X11/__xconfigfile__
-Server configuration file.
-.TP 30
-.B /etc/X11/__xconfigfile__-4
-Server configuration file.
-.TP 30
-.B /etc/__xconfigfile__
-Server configuration file.
-.TP 30
-.B __projectroot__/etc/__xconfigfile__
-Server configuration file.
-.TP 30
-.B __projectroot__/lib/X11/__xconfigfile__
-Server configuration file.
-.TP 30
-.B /etc/X11/__xconfigdir__
-Server configuration directory.
-.TP 30
-.B /etc/X11/__xconfigdir__-4
-Server configuration directory.
-.TP 30
-.B /etc/__xconfigdir__
-Server configuration directory.
-.TP 30
-.B __projectroot__/etc/__xconfigdir__
-Server configuration directory.
-.TP 30
-.B __projectroot__/lib/X11/__xconfigdir__
-Server configuration directory.
-.TP 30
-.BI __logdir__/__xservername__. n .log
-Server log file for display
-.IR n .
-.TP 30
-.B __projectroot__/bin/\(**
-Client binaries.
-.TP 30
-.B __projectroot__/include/\(**
-Header files.
-.TP 30
-.B __projectroot__/lib/\(**
-Libraries.
-.TP 30
-.B __datadir__/fonts/X11/\(**
-Fonts.
-.TP 30
-.B __projectroot__/share/X11/XErrorDB
-Client error message database.
-.TP 30
-.B __projectroot__/lib/X11/app-defaults/\(**
-Client resource specifications.
-.TP 30
-.B __mandir__/man?/\(**
-Manual pages.
-.TP 30
-.BI /etc/X n .hosts
-Initial access control list for display
-.IR n .
-.SH "SEE ALSO"
-X(__miscmansuffix__), Xserver(__appmansuffix__), xdm(__appmansuffix__), xinit(__appmansuffix__),
-__xconfigfile__(__filemansuffix__), xvidtune(__appmansuffix__),
-apm(__drivermansuffix__),
-ati(__drivermansuffix__),
-chips(__drivermansuffix__),
-cirrus(__drivermansuffix__),
-cyrix(__drivermansuffix__),
-fbdev(__drivermansuffix__),
-glide(__drivermansuffix__),
-glint(__drivermansuffix__),
-i128(__drivermansuffix__),
-i740(__drivermansuffix__),
-imstt(__drivermansuffix__),
-intel(__drivermansuffix__),
-mga(__drivermansuffix__),
-neomagic(__drivermansuffix__),
-nsc(__drivermansuffix__),
-nv(__drivermansuffix__),
-openchrome (__drivermansuffix__),
-r128(__drivermansuffix__),
-rendition(__drivermansuffix__),
-s3virge(__drivermansuffix__),
-siliconmotion(__drivermansuffix__),
-sis(__drivermansuffix__),
-sunbw2(__drivermansuffix__),
-suncg14(__drivermansuffix__),
-suncg3(__drivermansuffix__),
-suncg6(__drivermansuffix__),
-sunffb(__drivermansuffix__),
-sunleo(__drivermansuffix__),
-suntcx(__drivermansuffix__),
-tdfx(__drivermansuffix__),
-tga(__drivermansuffix__),
-trident(__drivermansuffix__),
-tseng(__drivermansuffix__),
-v4l(__drivermansuffix__),
-vesa(__drivermansuffix__),
-vmware(__drivermansuffix__),
-.br
-Web site
-.IR <http://www.x.org> .
-
-.SH AUTHORS
-__xservername__ has many contributors world wide.  The names of most of them
-can be found in the documentation, ChangeLog files in the source tree,
-and in the actual source code.
-.PP
-__xservername__ was originally based on XFree86 4.4rc2.
-That was originally based on \fIX386 1.2\fP by Thomas Roell, which
-was contributed to the then X Consortium's X11R5 distribution by SGCS.
-.PP
-__xservername__ is released by the X.Org Foundation.
-.PP
-The project that became XFree86 was originally founded in 1992 by
-David Dawes, Glenn Lai, Jim Tsillas and David Wexelblat.
-.PP
-XFree86 was later integrated in the then X Consortium's X11R6 release
-by a group of dedicated XFree86 developers, including the following:
-.PP
-.RS 4
-.nf
-Stuart Anderson    \fIanderson@metrolink.com\fP
-Doug Anson         \fIdanson@lgc.com\fP
-Gertjan Akkerman   \fIakkerman@dutiba.twi.tudelft.nl\fP
-Mike Bernson       \fImike@mbsun.mlb.org\fP
-Robin Cutshaw      \fIrobin@XFree86.org\fP
-David Dawes        \fIdawes@XFree86.org\fP
-Marc Evans         \fImarc@XFree86.org\fP
-Pascal Haible      \fIhaible@izfm.uni-stuttgart.de\fP
-Matthieu Herrb     \fIMatthieu.Herrb@laas.fr\fP
-Dirk Hohndel       \fIhohndel@XFree86.org\fP
-David Holland      \fIdavidh@use.com\fP
-Alan Hourihane     \fIalanh@fairlite.demon.co.uk\fP
-Jeffrey Hsu        \fIhsu@soda.berkeley.edu\fP
-Glenn Lai          \fIglenn@cs.utexas.edu\fP
-Ted Lemon          \fImellon@ncd.com\fP
-Rich Murphey       \fIrich@XFree86.org\fP
-Hans Nasten        \fInasten@everyware.se\fP
-Mark Snitily       \fImark@sgcs.com\fP
-Randy Terbush      \fIrandyt@cse.unl.edu\fP
-Jon Tombs          \fItombs@XFree86.org\fP
-Kees Verstoep      \fIversto@cs.vu.nl\fP
-Paul Vixie         \fIpaul@vix.com\fP
-Mark Weaver        \fIMark_Weaver@brown.edu\fP
-David Wexelblat    \fIdwex@XFree86.org\fP
-Philip Wheatley    \fIPhilip.Wheatley@ColumbiaSC.NCR.COM\fP
-Thomas Wolfram     \fIwolf@prz.tu-berlin.de\fP
-Orest Zborowski    \fIorestz@eskimo.com\fP
-.fi
-.RE
-.PP
-__xservername__ source is available from the FTP server
-\fI<ftp://ftp.x.org/>\fP, and from the X.Org
-server \fI<http://gitweb.freedesktop.org/>\fP.  Documentation and other
-information can be found from the X.Org web site
-\fI<http://www.x.org/>\fP.
-
-.SH LEGAL
-.PP
-.B __xservername__
-is copyright software, provided under licenses that permit modification
-and redistribution in source and binary form without fee.
-.B __xservername__ is copyright by numerous authors and
-contributors from around the world.  Licensing information can be found
-at
-.IR <http://www.x.org> .
-Refer to the source code for specific copyright notices.
-.PP
-.B XFree86(TM)
-is a trademark of The XFree86 Project, Inc.
-.PP
-.B X11(TM)
-and
-.B X Window System(TM)
-are trademarks of The Open Group.
diff --git a/xorg-server/hw/xfree86/doc/man/xorg.conf.d.man b/xorg-server/hw/xfree86/doc/man/xorg.conf.d.man
deleted file mode 100644
index 6b3379ece..000000000
--- a/xorg-server/hw/xfree86/doc/man/xorg.conf.d.man
+++ /dev/null
@@ -1 +0,0 @@
-.so man__filemansuffix__/xorg.conf.__filemansuffix__
diff --git a/xorg-server/hw/xfree86/doc/man/xorg.conf.man b/xorg-server/hw/xfree86/doc/man/xorg.conf.man
deleted file mode 100644
index e3fd0eadf..000000000
--- a/xorg-server/hw/xfree86/doc/man/xorg.conf.man
+++ /dev/null
@@ -1,2478 +0,0 @@
-.\" shorthand for double quote that works everywhere.
-.ds q \N'34'
-.TH __xconfigfile__ __filemansuffix__ __vendorversion__
-.SH NAME
-__xconfigfile__ and __xconfigdir__ \- configuration files for
-__xservername__ X server
-.SH INTRODUCTION
-.B __xservername__
-supports several mechanisms for supplying/obtaining configuration and
-run-time parameters: command line options, environment variables, the
-__xconfigfile__ and __xconfigdir__ configuration files, auto-detection,
-and fallback defaults. When the same information is supplied in more
-than one way, the highest precedence mechanism is used. The list of
-mechanisms is ordered from highest precedence to lowest. Note that not
-all parameters can be supplied via all methods. The available command
-line options and environment variables (and some defaults) are
-described in the Xserver(__appmansuffix__) and
-__xservername__(__appmansuffix__) manual pages. Most configuration file
-parameters, with their defaults, are described below. Driver and module
-specific configuration parameters are described in the relevant driver
-or module manual page.
-.SH DESCRIPTION
-.B __xservername__
-uses a configuration file called
-.I __xconfigfile__
-and files ending in the suffix
-.I .conf
-from the directory
-.I __xconfigdir__
-for its initial setup.
-The
-.I __xconfigfile__
-configuration file is searched for in the following places when the
-server is started as a normal user:
-.PP
-.RS 4
-.nf
-.IR /etc/X11/ <cmdline>
-.IR __projectroot__/etc/X11/ <cmdline>
-.IB /etc/X11/ $XORGCONFIG
-.IB __projectroot__/etc/X11/ $XORGCONFIG
-.I /etc/X11/__xconfigfile__
-.I /etc/__xconfigfile__
-.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
-.I __projectroot__/etc/X11/__xconfigfile__
-.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
-.I __projectroot__/lib/X11/__xconfigfile__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is a relative path (with no \(lq..\(rq components) specified with the
-.B \-config
-command line option,
-.B $XORGCONFIG
-is the relative path (with no \(lq..\(rq components) specified by that
-environment variable, and
-.I <hostname>
-is the machine's hostname as reported by
-.BR gethostname (__libmansuffix__).
-.PP
-When the __xservername__ server is started by the \(lqroot\(rq user, the config file
-search locations are as follows:
-.PP
-.RS 4
-.nf
-<cmdline>
-.IR /etc/X11/ <cmdline>
-.IR __projectroot__/etc/X11/ <cmdline>
-.B $XORGCONFIG
-.IB /etc/X11/ $XORGCONFIG
-.IB __projectroot__/etc/X11/ $XORGCONFIG
-.I /etc/X11/__xconfigfile__
-.I /etc/__xconfigfile__
-.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
-.I __projectroot__/etc/X11/__xconfigfile__
-.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
-.I __projectroot__/lib/X11/__xconfigfile__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is the path specified with the
-.B \-config
-command line option (which may be absolute or relative),
-.B $XORGCONFIG
-is the path specified by that
-environment variable (absolute or relative),
-.B $HOME
-is the path specified by that environment variable (usually the home
-directory), and
-.I <hostname>
-is the machine's hostname as reported by
-.BR gethostname (__libmansuffix__).
-.PP
-Additional configuration files are searched for in the following
-directories when the server is started as a normal user:
-.PP
-.RS 4
-.nf
-.IR /etc/X11/ <cmdline>
-.IR __sysconfdir__/X11/ <cmdline>
-.I /etc/X11/__xconfigdir__
-.I __sysconfdir__/X11/__xconfigdir__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is a relative path (with no \(lq..\(rq components) specified with the
-.B \-configdir
-command line option.
-.PP
-When the __xservername__ server is started by the \(lqroot\(rq user, the
-config directory search locations are as follows:
-.PP
-.RS 4
-.nf
-<cmdline>
-.IR /etc/X11/ <cmdline>
-.IR __sysconfdir__/X11/ <cmdline>
-.I /etc/X11/__xconfigdir__
-.I __sysconfdir__/X11/__xconfigdir__
-.fi
-.RE
-.PP
-where
-.I <cmdline>
-is the path specified with the
-.B \-configdir
-command line option (which may be absolute or relative).
-.PP
-Finally, configuration files will also be searched for in directories
-reserved for system use. These are to separate configuration files from
-the vendor or 3rd party packages from those of local administration.
-These files are found in the following directories:
-.PP
-.RS 4
-.nf
-.I /usr/share/X11/__xconfigdir__
-.I __datadir__/X11/__xconfigdir__
-.fi
-.RE
-.PP
-The
-.I __xconfigfile__
-and
-.I __xconfigdir__
-files are composed of a number of sections which may be present in any order,
-or omitted to use default configuration values.
-Each section has the form:
-.PP
-.RS 4
-.nf
-.BI "Section  \*q" SectionName \*q
-.RI "    " SectionEntry
-    ...
-.B EndSection
-.fi
-.RE
-.PP
-The section names are:
-.PP
-.RS 4
-.nf
-.BR "Files          " "File pathnames"
-.BR "ServerFlags    " "Server flags"
-.BR "Module         " "Dynamic module loading"
-.BR "Extensions     " "Extension enabling"
-.BR "InputDevice    " "Input device description"
-.BR "InputClass     " "Input class description"
-.BR "Device         " "Graphics device description"
-.BR "VideoAdaptor   " "Xv video adaptor description"
-.BR "Monitor        " "Monitor description"
-.BR "Modes          " "Video modes descriptions"
-.BR "Screen         " "Screen configuration"
-.BR "ServerLayout   " "Overall layout"
-.BR "DRI            " "DRI\-specific configuration"
-.BR "Vendor         " "Vendor\-specific configuration"
-.fi
-.RE
-.PP
-The following obsolete section names are still recognised for compatibility
-purposes.
-In new config files, the
-.B InputDevice
-section should be used instead.
-.PP
-.RS 4
-.nf
-.BR "Keyboard       " "Keyboard configuration"
-.BR "Pointer        " "Pointer/mouse configuration"
-.fi
-.RE
-.PP
-The old
-.B XInput
-section is no longer recognised.
-.PP
-The
-.B ServerLayout
-sections are at the highest level.
-They bind together the input and output devices that will be used in a session.
-The input devices are described in the
-.B InputDevice
-sections.
-Output devices usually consist of multiple independent components (e.g.,
-a graphics board and a monitor).
-These multiple components are bound together in the
-.B Screen
-sections, and it is these that are referenced by the
-.B ServerLayout
-section.
-Each
-.B Screen
-section binds together a graphics board and a monitor.
-The graphics boards are described in the
-.B Device
-sections, and the monitors are described in the
-.B Monitor
-sections.
-.PP
-Config file keywords are case\-insensitive, and \(lq_\(rq characters are
-ignored.
-Most strings (including
-.B Option
-names) are also case-insensitive, and insensitive to white space and
-\(lq_\(rq characters.
-.PP
-Each config file entry usually takes up a single line in the file.  They
-consist of a keyword, which is possibly followed by one or more arguments,
-with the number and types of the arguments depending on the keyword.
-The argument types are:
-.PP
-.RS 4
-.nf
-.BR "Integer     " "an integer number in decimal, hex or octal"
-.BR "Real        " "a floating point number"
-.BR "String      " "a string enclosed in double quote marks (\*q)"
-.fi
-.RE
-.PP
-Note: hex integer values must be prefixed with \(lq0x\(rq, and octal values
-with \(lq0\(rq.
-.PP
-A special keyword called
-.B Option
-may be used to provide free\-form data to various components of the server.
-The
-.B Option
-keyword takes either one or two string arguments.
-The first is the option name, and the optional second argument is the
-option value.
-Some commonly used option value types include:
-.PP
-.RS 4
-.nf
-.BR "Integer     " "an integer number in decimal, hex or octal"
-.BR "Real        " "a floating point number"
-.BR "String      " "a sequence of characters"
-.BR "Boolean     " "a boolean value (see below)"
-.BR "Frequency   " "a frequency value (see below)"
-.fi
-.RE
-.PP
-Note that
-.I all
-.B Option
-values, not just strings, must be enclosed in quotes.
-.PP
-Boolean options may optionally have a value specified.
-When no value is specified, the option's value is
-.BR TRUE .
-The following boolean option values are recognised as
-.BR TRUE :
-.PP
-.RS 4
-.BR 1 ,
-.BR on ,
-.BR true ,
-.B yes
-.RE
-.PP
-and the following boolean option values are recognised as
-.BR FALSE :
-.PP
-.RS 4
-.BR 0 ,
-.BR off ,
-.BR false ,
-.B no
-.RE
-.PP
-If an option name is prefixed with
-.RB \*q No \*q,
-then the option value is negated.
-.PP
-Example: the following option entries are equivalent:
-.PP
-.RS 4
-.nf
-.B "Option \*qAccel\*q   \*qOff\*q"
-.B "Option \*qNoAccel\*q"
-.B "Option \*qNoAccel\*q \*qOn\*q"
-.B "Option \*qAccel\*q   \*qfalse\*q"
-.B "Option \*qAccel\*q   \*qno\*q"
-.fi
-.RE
-.PP
-Frequency option values consist of a real number that is optionally
-followed by one of the following frequency units:
-.PP
-.RS 4
-.BR Hz ,
-.BR k ,
-.BR kHz ,
-.BR M ,
-.B MHz
-.RE
-.PP
-When the unit name is omitted, the correct units will be determined from
-the value and the expectations of the appropriate range of the value.
-It is recommended that the units always be specified when using frequency
-option values to avoid any errors in determining the value.
-.SH "FILES SECTION"
-The
-.B Files
-section is used to specify some path names required by the server.
-Some of these paths can also be set from the command line (see
-.BR Xserver (__appmansuffix__)
-and
-.BR __xservername__ (__appmansuffix__)).
-The command line settings override the values specified in the config
-file.
-The
-.B Files
-section is optional, as are all of the entries that may appear in it.
-.PP
-The entries that can appear in this section are:
-.TP 7
-.BI "FontPath \*q" path \*q
-sets the search path for fonts.
-This path is a comma separated list of font path elements which the __xservername__
-server searches for font databases.
-Multiple
-.B FontPath
-entries may be specified, and they will be concatenated to build up the
-fontpath used by the server.  Font path elements can be absolute
-directory paths, catalogue directories or a font server identifier. The
-formats of the later two are explained below:
-.PP
-.RS 7
-Catalogue directories:
-.PP
-.RS 4
-Catalogue directories can be specified using the prefix \fBcatalogue:\fR
-before the directory name. The directory can then be populated with
-symlinks pointing to the real font directories, using the following
-syntax in the symlink name:
-.PP
-.RS 4
-.IR <identifier> : [attribute]: pri= <priority>
-.RE
-.PP
-where
-.I <identifier>
-is an alphanumeric identifier,
-.I [attribute]
-is an attribute which will be passed to the underlying FPE and
-.I <priority>
-is a number used to order the fontfile FPEs. Examples:
-.PP
-.RS 4
-.nf
-.I 75dpi:unscaled:pri=20  -> /usr/share/X11/fonts/75dpi
-.I gscript:pri=60 -> /usr/share/fonts/default/ghostscript
-.I misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc
-.fi
-.PP
-.RE .RE .RE
-.PP
-.RS 7
-Font server identifiers:
-.PP
-.RS 4
-Font server identifiers have the form:
-.RS 4
-.PP
-.IR <trans> / <hostname> : <port\-number>
-.RE
-.PP
-where
-.I <trans>
-is the transport type to use to connect to the font server (e.g.,
-.B unix
-for UNIX\-domain sockets or
-.B tcp
-for a TCP/IP connection),
-.I <hostname>
-is the hostname of the machine running the font server, and
-.I <port\-number>
-is the port number that the font server is listening on (usually 7100).
-.RE
-.PP
-When this entry is not specified in the config file, the server falls back
-to the compiled\-in default font path, which contains the following
-font path elements (which can be set inside a catalogue directory):
-.PP
-.RS 4
-.nf
-.I __datadir__/fonts/X11/misc/
-.I __datadir__/fonts/X11/TTF/
-.I __datadir__/fonts/X11/OTF/
-.I __datadir__/fonts/X11/Type1/
-.I __datadir__/fonts/X11/100dpi/
-.I __datadir__/fonts/X11/75dpi/
-.fi
-.RE
-.PP
-Font path elements that are found to be invalid are removed from the
-font path when the server starts up.
-.RE
-.TP 7
-.BI "ModulePath \*q" path \*q
-sets the search path for loadable __xservername__ server modules.
-This path is a comma separated list of directories which the __xservername__ server
-searches for loadable modules loading in the order specified.
-Multiple
-.B ModulePath
-entries may be specified, and they will be concatenated to build the
-module search path used by the server.  The default module path is
-.PP
-.RS 11
-__modulepath__
-.RE
-.\" The LogFile keyword is not currently implemented
-.ig
-.TP 7
-.BI "LogFile \*q" path \*q
-sets the name of the __xservername__ server log file.
-The default log file name is
-.PP
-.RS 11
-.RI __logdir__/__xservername__. <n> .log
-.RE
-.PP
-.RS 7
-where
-.I <n>
-is the display number for the __xservername__ server.
-..
-.TP 7
-.BI "XkbDir \*q" path \*q
-sets the base directory for keyboard layout files.  The
-.B \-xkbdir
-command line option can be used to override this.  The default directory is
-.PP
-.RS 11
-__xkbdir__
-.RE
-.SH "SERVERFLAGS SECTION"
-In addition to options specific to this section (described below), the
-.B ServerFlags
-section is used to specify some global
-__xservername__ server options.
-All of the entries in this section are
-.BR Options ,
-although for compatibility purposes some of the old style entries are
-still recognised.
-Those old style entries are not documented here, and using them is
-discouraged.
-The
-.B ServerFlags
-section is optional, as are the entries that may be specified in it.
-.PP
-.B Options
-specified in this section (with the exception of the
-.B \*qDefaultServerLayout\*q
-.BR Option )
-may be overridden by
-.B Options
-specified in the active
-.B ServerLayout
-section.
-Options with command line equivalents are overridden when their command
-line equivalent is used.
-The options recognised by this section are:
-.TP 7
-.BI "Option \*qDefaultServerLayout\*q  \*q" layout\-id \*q
-This specifies the default
-.B ServerLayout
-section to use in the absence of the
-.B \-layout
-command line option.
-.TP 7
-.BI "Option \*qNoTrapSignals\*q  \*q" boolean \*q
-This prevents the __xservername__ server from trapping a range of unexpected fatal
-signals and exiting cleanly.
-Instead, the __xservername__ server will die and drop core where the fault occurred.
-The default behaviour is for the __xservername__ server to exit cleanly, but still drop a
-core file.
-In general you never want to use this option unless you are debugging an __xservername__
-server problem and know how to deal with the consequences.
-.TP 7
-.BI "Option \*qUseSIGIO\*q  \*q" boolean \*q
-This controls whether the __xservername__ server requests that events from
-input devices be reported via a SIGIO signal handler (also known as SIGPOLL
-on some platforms), or only reported via the standard select(3) loop.
-The default behaviour is platform specific.   In general you do not want to
-use this option unless you are debugging the __xservername__ server, or
-working around a specific bug until it is fixed, and understand the
-consequences.
-.TP 7
-.BI "Option \*qDontVTSwitch\*q  \*q" boolean \*q
-This disallows the use of the
-.BI Ctrl+Alt+F n
-sequence (where
-.RI F n
-refers to one of the numbered function keys).
-That sequence is normally used to switch to another \*qvirtual terminal\*q
-on operating systems that have this feature.
-When this option is enabled, that key sequence has no special meaning and
-is passed to clients.
-Default: off.
-.TP 7
-.BI "Option \*qDontZap\*q  \*q" boolean \*q
-This disallows the use of the
-.B Terminate_Server
-XKB action (usually on Ctrl+Alt+Backspace, depending on XKB options).
-This action is normally used to terminate the __xservername__ server.
-When this option is enabled, the action has no effect.
-Default: off.
-.TP 7
-.BI "Option \*qDontZoom\*q  \*q" boolean \*q
-This disallows the use of the
-.B Ctrl+Alt+Keypad\-Plus
-and
-.B Ctrl+Alt+Keypad\-Minus
-sequences.
-These sequences allows you to switch between video modes.
-When this option is enabled, those key sequences have no special meaning
-and are passed to clients.
-Default: off.
-.TP 7
-.BI "Option \*qDisableVidModeExtension\*q  \*q" boolean \*q
-This disables the parts of the VidMode extension used by the xvidtune client
-that can be used to change the video modes.
-Default: the VidMode extension is enabled.
-.TP 7
-.BI "Option \*qAllowNonLocalXvidtune\*q  \*q" boolean \*q
-This allows the xvidtune client (and other clients that use the VidMode
-extension) to connect from another host.
-Default: off.
-.TP 7
-.BI "Option \*qAllowMouseOpenFail\*q  \*q" boolean \*q
-This tells the mousedrv(__drivermansuffix__) and vmmouse(__drivermansuffix__)
-drivers to not report failure if the mouse device can't be opened/initialised.
-It has no effect on the evdev(__drivermansuffix__) or other drivers.
-Default: false.
-.TP 7
-.BI "Option \*qVTSysReq\*q  \*q" boolean \*q
-enables the SYSV\-style VT switch sequence for non\-SYSV systems
-which support VT switching.
-This sequence is
-.B Alt\-SysRq
-followed by a function key
-.RB ( Fn ).
-This prevents the __xservername__ server trapping the
-keys used for the default VT switch sequence, which means that clients can
-access them.
-Default: off.
-.TP 7
-.BI "Option \*qBlankTime\*q  \*q" time \*q
-sets the inactivity timeout for the
-.B blank
-phase of the screensaver.
-.I time
-is in minutes.
-This is equivalent to the __xservername__ server's
-.B \-s
-flag, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-.TP 7
-.BI "Option \*qStandbyTime\*q  \*q" time \*q
-sets the inactivity timeout for the
-.B standby
-phase of DPMS mode.
-.I time
-is in minutes, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-This is only suitable for VESA DPMS compatible monitors, and may not be
-supported by all video drivers.
-It is only enabled for screens that have the
-.B \*qDPMS\*q
-option set (see the MONITOR section below).
-.TP 7
-.BI "Option \*qSuspendTime\*q  \*q" time \*q
-sets the inactivity timeout for the
-.B suspend
-phase of DPMS mode.
-.I time
-is in minutes, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-This is only suitable for VESA DPMS compatible monitors, and may not be
-supported by all video drivers.
-It is only enabled for screens that have the
-.B \*qDPMS\*q
-option set (see the MONITOR section below).
-.TP 7
-.BI "Option \*qOffTime\*q  \*q" time \*q
-sets the inactivity timeout for the
-.B off
-phase of DPMS mode.
-.I time
-is in minutes, and the value can be changed at run\-time with
-.BR xset(__appmansuffix__).
-Default: 10 minutes.
-This is only suitable for VESA DPMS compatible monitors, and may not be
-supported by all video drivers.
-It is only enabled for screens that have the
-.B \*qDPMS\*q
-option set (see the MONITOR section below).
-.TP 7
-.BI "Option \*qPixmap\*q  \*q" bpp \*q
-This sets the pixmap format to use for depth 24.
-Allowed values for
-.I bpp
-are 24 and 32.
-Default: 32 unless driver constraints don't allow this (which is rare).
-Note: some clients don't behave well when this value is set to 24.
-.TP 7
-.BI "Option \*qPC98\*q  \*q" boolean \*q
-Specify that the machine is a Japanese PC\-98 machine.
-This should not be enabled for anything other than the Japanese\-specific
-PC\-98 architecture.
-Default: auto\-detected.
-.TP 7
-.BI "Option \*qNoPM\*q  \*q" boolean \*q
-Disables something to do with power management events.
-Default: PM enabled on platforms that support it.
-.TP 7
-.BI "Option \*qXinerama\*q  \*q" boolean \*q
-enable or disable XINERAMA extension.
-Default is disabled.
-.TP 7
-.BI "Option \*qAIGLX\*q \*q" boolean \*q
-enable or disable AIGLX. AIGLX is enabled by default.
-.TP 7
-.BI "Option \*qDRI2\*q \*q" boolean \*q
-enable or disable DRI2. DRI2 is disabled by default.
-.TP 7
-.BI "Option \*qGlxVisuals\*q \*q" string \*q
-This option controls how many GLX visuals the GLX modules sets up.
-The default value is
-.BR "typical" ,
-which will setup up a typical subset of
-the GLXFBConfigs provided by the driver as GLX visuals.  Other options are
-.BR "minimal" ,
-which will set up the minimal set allowed by the GLX specification and
-.BR "all"
-which will setup GLX visuals for all GLXFBConfigs.
-.TP 7
-.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q
-Include the default font path even if other paths are specified in
-xorg.conf. If enabled, other font paths are included as well. Enabled by
-default.
-.TP 7
-.BI "Option \*qIgnoreABI\*q \*q" boolean \*q
-Allow modules built for a different, potentially incompatible version of
-the X server to load. Disabled by default.
-.TP 7
-.BI "Option \*qAutoAddDevices\*q \*q" boolean \*q
-If this option is disabled, then no devices will be added from HAL events.
-Enabled by default.
-.TP 7
-.BI "Option \*qAutoEnableDevices\*q \*q" boolean \*q
-If this option is disabled, then the devices will be added (and the
-DevicePresenceNotify event sent), but not enabled, thus leaving policy up
-to the client.
-Enabled by default.
-.TP 7
-.BI "Option \*qLog\*q \*q" string \*q
-This option controls whether the log is flushed and/or synced to disk after
-each message.
-Possible values are
-.B flush
-or
-.BR sync .
-Unset by default.
-.SH "MODULE SECTION"
-The
-.B Module
-section is used to specify which __xservername__ server modules should be loaded.
-This section is ignored when the __xservername__ server is built in static form.
-The type of modules normally loaded in this section are __xservername__ server
-extension modules.
-Most other module types are loaded automatically when they are needed via
-other mechanisms.
-The
-.B Module
-section is optional, as are all of the entries that may be specified in
-it.
-.PP
-Entries in this section may be in two forms.
-The first and most commonly used form is an entry that uses the
-.B Load
-keyword, as described here:
-.TP 7
-.BI "Load  \*q" modulename \*q
-This instructs the server to load the module called
-.IR modulename .
-The module name given should be the module's standard name, not the
-module file name.
-The standard name is case\-sensitive, and does not include the \(lqlib\(rq
-prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes.
-.PP
-.RS 7
-Example: the DRI extension module can be loaded with the following entry:
-.PP
-.RS 4
-.B "Load \*qdri\*q"
-.RE
-.RE
-.TP 7
-.BI "Disable  \*q" modulename \*q
-This instructs the server to not load the module called
-.IR modulename .
-Some modules are loaded by default in the server, and this overrides that
-default. If a
-.B Load
-instruction is given for the same module, it overrides the
-.B Disable
-instruction and the module is loaded. The module name given should be the
-module's standard name, not the module file name. As with the
-.B Load
-instruction, the standard name is case-sensitive, and does not include the
-"lib" prefix, or the ".a", ".o", or ".so" suffixes.
-.PP
-The second form of entry is a
-.BR SubSection,
-with the subsection name being the module name, and the contents of the
-.B SubSection
-being
-.B Options
-that are passed to the module when it is loaded.
-.PP
-Example: the extmod module (which contains a miscellaneous group of
-server extensions) can be loaded, with the XFree86\-DGA extension
-disabled by using the following entry:
-.PP
-.RS 4
-.nf
-.B "SubSection \*qextmod\*q"
-.B "   Option  \*qomit XFree86\-DGA\*q"
-.B EndSubSection
-.fi
-.RE
-.PP
-Modules are searched for in each directory specified in the
-.B ModulePath
-search path, and in the drivers, extensions, input, internal, and
-multimedia subdirectories of each of those directories.
-In addition to this, operating system specific subdirectories of all
-the above are searched first if they exist.
-.PP
-To see what extension modules are available, check the extensions
-subdirectory under:
-.PP
-.RS 4
-.nf
-__modulepath__
-.fi
-.RE
-.PP
-The \(lqextmod\(rq, \(lqdbe\(rq, \(lqdri\(rq, \(lqdri2\(rq, \(lqglx\(rq,
-and \(lqrecord\(rq extension modules are loaded automatically, if they
-are present, unless disabled with \*qDisable\*q entries.
-It is recommended
-that at very least the \(lqextmod\(rq extension module be loaded.
-If it isn't, some commonly used server extensions (like the SHAPE
-extension) will not be available.
-.SH "EXTENSIONS SECTION"
-The
-.B Extensions
-section is used to specify which X11 protocol extensions should be enabled
-or disabled.
-The
-.B Extensions
-section is optional, as are all of the entries that may be specified in
-it.
-.PP
-Entries in this section are listed as Option statements with the name of
-the extension as the first argument, and a boolean value as the second.
-The extension name is case\-sensitive, and matches the form shown in the output
-of \*qXorg -extension ?\*q.
-.PP
-.RS 7
-Example: the MIT-SHM extension can be disabled with the following entry:
-.PP
-.RS 4
-.nf
-.B "Section \*qExtensions\*q"
-.B "    Option \*qMIT-SHM\*q \*qDisable\*q"
-.B "EndSection"
-.fi
-.RE
-.RE
-.SH "INPUTDEVICE SECTION"
-The config file may have multiple
-.B InputDevice
-sections.
-Recent X servers employ input hotplugging to add input devices, with the HAL
-backend being the default backend for X servers since 1.4. It is usually not
-necessary to provide
-.B InputDevice
-sections in the xorg.conf if hotplugging is enabled.
-.PP
-If hotplugging is disabled, there will normally
-be at least two: one for the core (primary) keyboard
-and one for the core pointer.
-If either of these two is missing, a default configuration for the missing
-ones will be used. In the absence of an explicitly specified core input
-device, the first
-.B InputDevice
-marked as
-.B CorePointer
-(or
-.BR CoreKeyboard )
-is used.
-If there is no match there, the first
-.B InputDevice
-that uses the \(lqmouse\(rq (or \(lqkbd\(rq) driver is used.
-The final fallback is to use built\-in default configurations.
-Currently the default configuration may not work as expected on all platforms.
-.PP
-.B InputDevice
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B  "Section \*qInputDevice\*q"
-.BI "    Identifier \*q" name \*q
-.BI "    Driver     \*q" inputdriver \*q
-.I  "    options"
-.I  "    ..."
-.B  "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-and
-.B Driver
-entries are required in all
-.B InputDevice
-sections.
-All other entries are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this input device.
-The
-.B Driver
-entry specifies the name of the driver to use for this input device.
-When using the loadable server, the input driver module
-.RI \*q inputdriver \*q
-will be loaded for each active
-.B InputDevice
-section.
-An
-.B InputDevice
-section is considered active if it is referenced by an active
-.B ServerLayout
-section, if it is referenced by the
-.B \-keyboard
-or
-.B \-pointer
-command line options, or if it is selected implicitly as the core pointer
-or keyboard device in the absence of such explicit references.
-The most commonly used input drivers are
-.BR evdev (__drivermansuffix__)
-on Linux systems, and
-.BR kbd (__drivermansuffix__)
-and
-.BR mousedrv (__drivermansuffix__)
-on other platforms.
-.PP
-.PP
-.B InputDevice
-sections recognise some driver\-independent
-.BR Options ,
-which are described here.
-See the individual input driver manual pages for a description of the
-device\-specific options.
-.TP 7
-.BI "Option \*qAutoServerLayout\*q  \*q" boolean \*q
-Always add the device to the ServerLayout section used by this instance of
-the server. This affects implied layouts as well as explicit layouts
-specified in the configuration and/or on the command line.
-.TP 7
-.BI "Option \*qCorePointer\*q"
-Deprecated, see
-.B Floating
-.TP 7
-.BI "Option \*qCoreKeyboard\*q"
-Deprecated, see
-.B Floating
-.TP 7
-.BI "Option \*qAlwaysCore\*q  \*q" boolean \*q
-Deprecated, see
-.B Floating
-.TP 7
-.BI "Option \*qSendCoreEvents\*q  \*q" boolean \*q
-Deprecated, see
-.B Floating
-
-.TP 7
-.BI "Option \*qFloating\*q  \*q" boolean \*q
-When enabled, the input device is set up floating and does not
-report events through any master device or control a cursor. The device is
-only available to clients using the X Input Extension API. This option is
-disabled by default.
-The options
-.B CorePointer,
-.B CoreKeyboard,
-.B AlwaysCore,
-and
-.B SendCoreEvents,
-are the inverse of option
-.B Floating
-(i.e.
-.B SendCoreEvents \*qon\*q
-is equivalent to
-.B Floating \*qoff\*q
-).
-
-This option controls the startup behavior only, a device
-may be reattached or set floating at runtime.
-.PP
-For pointing devices, the following options control how the pointer
-is accelerated or decelerated with respect to physical device motion. Most of
-these can be adjusted at runtime, see the xinput(1) man page for details. Only
-the most important acceleration options are discussed here.
-.TP 7
-.BI "Option \*qAccelerationProfile\*q  \*q" integer \*q
-Select the profile. In layman's terms, the profile constitutes the "feeling" of
-the acceleration. More formally, it defines how the transfer function (actual
-acceleration as a function of current device velocity and acceleration controls)
-is constructed. This is mainly a matter of personal preference.
-.PP
-.RS 6
-.nf
-.B  " 0      classic (mostly compatible)"
-.B  "-1      none (only constant deceleration is applied)"
-.B  " 1      device-dependent"
-.B  " 2      polynomial (polynomial function)"
-.B  " 3      smooth linear (soft knee, then linear)"
-.B  " 4      simple (normal when slow, otherwise accelerated)"
-.B  " 5      power (power function)"
-.B  " 6      linear (more speed, more acceleration)"
-.B  " 7      limited (like linear, but maxes out at threshold)"
-.fi
-.RE
-.TP 7
-.BI "Option \*qConstantDeceleration\*q  \*q" real \*q
-Makes the pointer go
-.B deceleration
-times slower than normal. Most useful for high-resolution devices.
-.TP 7
-.BI "Option \*qAdaptiveDeceleration\*q  \*q" real \*q
-Allows to actually decelerate the pointer when going slow. At most, it will be
-.B adaptive deceleration
-times slower. Enables precise pointer placement without sacrificing speed.
-.TP 7
-.BI "Option \*qAccelerationScheme\*q  \*q" string \*q
-Selects the scheme, which is the underlying algorithm.
-.PP
-.RS 7
-.nf
-.B  "predictable   default algorithm (behaving more predictable)"
-.B  "lightweight   old acceleration code (as specified in the X protocol spec)"
-.B  "none          no acceleration or deceleration"
-.fi
-.RE
-.TP 7
-.BI "Option \*qAccelerationNumerator\*q  \*q" integer \*q
-.TP 7
-.BI "Option \*qAccelerationDenominator\*q  \*q" integer \*q
-Set numerator and denominator of the acceleration factor. The acceleration
-factor is a rational which, together with threshold, can be used to tweak
-profiles to suit the users needs. The
-.B simple
-and
-.B limited
-profiles use it directly (i.e. they accelerate by the factor), for other
-profiles it should hold that a higher acceleration factor leads to a faster
-pointer. Typically, 1 is unaccelerated and values up to 5 are sensible.
-.TP 7
-.BI "Option \*qAccelerationThreshold\*q  \*q" integer \*q
-Set the threshold, which is roughly the velocity (usually device units per 10
-ms) required for acceleration to become effective. The precise effect varies
-with the profile however.
-
-.SH "INPUTCLASS SECTION"
-The config file may have multiple
-.B InputClass
-sections.
-These sections are optional and are used to provide configuration for a
-class of input devices as they are automatically added. An input device can
-match more than one
-.B InputClass
-section. Each class can override settings from a previous class, so it is
-best to arrange the sections with the most generic matches first.
-.PP
-.B InputClass
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B  "Section \*qInputClass\*q"
-.BI "    Identifier  \*q" name \*q
-.I  "    entries"
-.I  "    ..."
-.I  "    options"
-.I  "    ..."
-.B  "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-entry is required in all
-.B InputClass
-sections.
-All other entries are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this input class.
-The
-.B Driver
-entry specifies the name of the driver to use for this input device.
-After all classes have been examined, the
-.RI \*q inputdriver \*q
-module from the first
-.B Driver
-entry will be enabled when using the loadable server.
-.PP
-When an input device is automatically added, its characteristics are
-checked against all
-.B InputClass
-sections. Each section can contain optional entries to narrow the match
-of the class. If none of the optional entries appear, the
-.B InputClass
-section is generic and will match any input device. If more than one of
-these entries appear, they all must match for the configuration to apply.
-.PP
-There are two types of match entries used in
-.B InputClass
-sections. The first allows various tokens to be matched against attributes
-of the device. An entry can be constructed to match attributes from different
-devices by separating arguments with a '|' character. Multiple entries of the
-same type may be supplied to add multiple matching conditions on the same
-attribute. For example:
-.PP
-.RS 4
-.nf
-.B  "Section \*qInputClass\*q"
-.B  "    Identifier   \*qMy Class\*q"
-.B  "    # product string must contain example and
-.B  "    # either gizmo or gadget
-.B  "    MatchProduct \*qexample\*q
-.B  "    MatchProduct \*qgizmo|gadget\*q
-.I  "    ..."
-.B  "EndSection"
-.fi
-.RE
-.TP 7
-.BI "MatchProduct  \*q" matchproduct \*q
-This entry can be used to check if the substring
-.RI \*q matchproduct \*q
-occurs in the device's product name.
-.TP 7
-.BI "MatchVendor  \*q" matchvendor \*q
-This entry can be used to check if the substring
-.RI \*q matchvendor \*q
-occurs in the device's vendor name.
-.TP 7
-.BI "MatchDevicePath \*q" matchdevice \*q
-This entry can be used to check if the device file matches the
-.RI \*q matchdevice \*q
-pathname pattern.
-.TP 7
-.BI "MatchOS \*q" matchos \*q
-This entry can be used to check if the operating system matches the
-case-insensitive
-.RI \*q matchos \*q
-string. This entry is only supported on platforms providing the
-.BR uname (2)
-system call.
-.TP 7
-.BI "MatchPnPID \*q" matchpnp \*q
-The device's Plug and Play (PnP) ID can be checked against the
-.RI \*q matchpnp \*q
-shell wildcard pattern.
-.TP 7
-.BI "MatchUSBID \*q" matchusb \*q
-The device's USB ID can be checked against the
-.RI \*q matchusb \*q
-shell wildcard pattern. The ID is constructed as lowercase hexadecimal numbers
-separated by a ':'. This is the same format as the
-.BR lsusb (8)
-program.
-.TP 7
-.BI "MatchDriver \*q" matchdriver \*q
-Check the case-sensitive string
-.RI \*q matchdriver \*q
-against the currently configured driver of the device. Ordering of sections
-using this entry is important since it will not match unless the driver has
-been set by the config backend or a previous
-.B InputClass
-section.
-.TP 7
-.BI "MatchTag \*q" matchtag \*q
-This entry can be used to check if tags assigned by the config backend
-matches the
-.RI \*q matchtag \*q
-pattern. A match is found if at least one of the tags given in
-.RI \*q matchtag \*q
-matches at least one of the tags assigned by the backend.
-.PP
-The second type of entry is used to match device types. These entries take a
-boolean argument similar to
-.B Option
-entries.
-.TP 7
-.BI "MatchIsKeyboard     \*q" bool \*q
-.TP 7
-.BI "MatchIsPointer      \*q" bool \*q
-.TP 7
-.BI "MatchIsJoystick     \*q" bool \*q
-.TP 7
-.BI "MatchIsTablet       \*q" bool \*q
-.TP 7
-.BI "MatchIsTouchpad     \*q" bool \*q
-.TP 7
-.BI "MatchIsTouchscreen  \*q" bool \*q
-.PP
-When an input device has been matched to the
-.B InputClass
-section, any
-.B Option
-entries are applied to the device. One
-.B InputClass
-specific
-.B Option
-is recognized. See the
-.B InputDevice
-section above for a description of the remaining
-.B Option
-entries.
-.TP 7
-.BI "Option \*qIgnore\*q \*q" boolean \*q
-This optional entry specifies that the device should be ignored entirely,
-and not added to the server. This can be useful when the device is handled
-by another program and no X events should be generated.
-.SH "DEVICE SECTION"
-The config file may have multiple
-.B Device
-sections.
-There must be at least one, for the video card being used.
-.PP
-.B Device
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B  "Section \*qDevice\*q"
-.BI "    Identifier \*q" name \*q
-.BI "    Driver     \*q" driver \*q
-.I  "    entries"
-.I  "    ..."
-.B  "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-and
-.B Driver
-entries are required in all
-.B Device
-sections.  All other entries are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this graphics device.
-The
-.B Driver
-entry specifies the name of the driver to use for this graphics device.
-When using the loadable server, the driver module
-.RI \*q driver \*q
-will be loaded for each active
-.B Device
-section.
-A
-.B Device
-section is considered active if it is referenced by an active
-.B Screen
-section.
-.PP
-.B Device
-sections recognise some driver\-independent entries and
-.BR Options ,
-which are described here.
-Not all drivers make use of these
-driver\-independent entries, and many of those that do don't require them
-to be specified because the information is auto\-detected.
-See the individual graphics driver manual pages for further information
-about this, and for a description of the device\-specific options.
-Note that most of the
-.B Options
-listed here (but not the other entries) may be specified in the
-.B Screen
-section instead of here in the
-.B Device
-section.
-.TP 7
-.BI "BusID  \*q" bus\-id \*q
-This specifies the bus location of the graphics card.
-For PCI/AGP cards,
-the
-.I bus\-id
-string has the form
-.BI PCI: bus : device : function
-(e.g., \(lqPCI:1:0:0\(rq might be appropriate for an AGP card).
-This field is usually optional in single-head configurations when using
-the primary graphics card.
-In multi-head configurations, or when using a secondary graphics card in a
-single-head configuration, this entry is mandatory.
-Its main purpose is to make an unambiguous connection between the device
-section and the hardware it is representing.
-This information can usually be found by running the pciaccess tool
-scanpci.
-.TP 7
-.BI "Screen  " number
-This option is mandatory for cards where a single PCI entity can drive more
-than one display (i.e., multiple CRTCs sharing a single graphics accelerator
-and video memory).
-One
-.B Device
-section is required for each head, and this
-parameter determines which head each of the
-.B Device
-sections applies to.
-The legal values of
-.I number
-range from 0 to one less than the total number of heads per entity.
-Most drivers require that the primary screen (0) be present.
-.TP 7
-.BI "Chipset  \*q" chipset \*q
-This usually optional entry specifies the chipset used on the graphics
-board.
-In most cases this entry is not required because the drivers will probe the
-hardware to determine the chipset type.
-Don't specify it unless the driver-specific documentation recommends that you
-do.
-.TP 7
-.BI "Ramdac  \*q" ramdac\-type \*q
-This optional entry specifies the type of RAMDAC used on the graphics
-board.
-This is only used by a few of the drivers, and in most cases it is not
-required because the drivers will probe the hardware to determine the
-RAMDAC type where possible.
-Don't specify it unless the driver-specific documentation recommends that you
-do.
-.TP 7
-.BI "DacSpeed  " speed
-.TP 7
-.BI "DacSpeed  " "speed\-8 speed\-16 speed\-24 speed\-32"
-This optional entry specifies the RAMDAC speed rating (which is usually
-printed on the RAMDAC chip).
-The speed is in MHz.
-When one value is given, it applies to all framebuffer pixel sizes.
-When multiple values are given, they apply to the framebuffer pixel sizes
-8, 16, 24 and 32 respectively.
-This is not used by many drivers, and only needs to be specified when the
-speed rating of the RAMDAC is different from the defaults built in to
-driver, or when the driver can't auto-detect the correct defaults.
-Don't specify it unless the driver-specific documentation recommends that you
-do.
-.TP 7
-.BI "Clocks  " "clock ..."
-specifies the pixel that are on your graphics board.
-The clocks are in MHz, and may be specified as a floating point number.
-The value is stored internally to the nearest kHz.
-The ordering of the clocks is important.
-It must match the order in which they are selected on the graphics board.
-Multiple
-.B Clocks
-lines may be specified, and each is concatenated to form the list.
-Most drivers do not use this entry, and it is only required for some older
-boards with non-programmable clocks.
-Don't specify this entry unless the driver-specific documentation explicitly
-recommends that you do.
-.TP
-.BI "ClockChip  \*q" clockchip\-type \*q
-This optional entry is used to specify the clock chip type on graphics
-boards which have a programmable clock generator.
-Only a few __xservername__ drivers support programmable clock chips.
-For details, see the appropriate driver manual page.
-.TP 7
-.BI "VideoRam  " "mem"
-This optional entry specifies the amount of video ram that is installed
-on the graphics board.
-This is measured in kBytes.
-In most cases this is not required because the __xservername__ server probes
-the graphics board to determine this quantity.
-The driver-specific documentation should indicate when it might be needed.
-.TP 7
-.BI "BiosBase  " "baseaddress"
-This optional entry specifies the base address of the video BIOS for
-the VGA board.
-This address is normally auto-detected, and should only be specified if the
-driver-specific documentation recommends it.
-.TP 7
-.BI "MemBase  " "baseaddress"
-This optional entry specifies the memory base address of a graphics
-board's linear frame buffer.
-This entry is not used by many drivers, and it should only be specified if
-the driver-specific documentation recommends it.
-.TP 7
-.BI "IOBase  " "baseaddress"
-This optional entry specifies the IO base address.
-This entry is not used by many drivers, and it should only be specified if
-the driver-specific documentation recommends it.
-.TP 7
-.BI "ChipID  " "id"
-This optional entry specifies a numerical ID representing the chip type.
-For PCI cards, it is usually the device ID.
-This can be used to override the auto-detection, but that should only be done
-when the driver-specific documentation recommends it.
-.TP 7
-.BI "ChipRev  " "rev"
-This optional entry specifies the chip revision number.
-This can be used to override the auto-detection, but that should only be done
-when the driver-specific documentation recommends it.
-.TP 7
-.BI "TextClockFreq  " "freq"
-This optional entry specifies the pixel clock frequency that is used
-for the regular text mode.
-The frequency is specified in MHz.
-This is rarely used.
-.TP 7
-.BI "Option \*qModeDebug\*q \*q" boolean \*q
-Enable printing of additional debugging information about modesetting to
-the server log.
-.ig
-.TP 7
-This optional entry allows an IRQ number to be specified.
-..
-.TP 7
-.B Options
-Option flags may be specified in the
-.B Device
-sections.
-These include driver\-specific options and driver\-independent options.
-The former are described in the driver\-specific documentation.
-Some of the latter are described below in the section about the
-.B Screen
-section, and they may also be included here.
-
-.SH "VIDEOADAPTOR SECTION"
-Nobody wants to say how this works.
-Maybe nobody knows ...
-
-.SH "MONITOR SECTION"
-The config file may have multiple
-.B Monitor
-sections.
-There should normally be at least one, for the monitor being used,
-but a default configuration will be created when one isn't specified.
-.PP
-.B Monitor
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B  "Section \*qMonitor\*q"
-.BI "    Identifier \*q" name \*q
-.I  "    entries"
-.I  "    ..."
-.B  "EndSection"
-.fi
-.RE
-.PP
-The only mandatory entry in a
-.B Monitor
-section is the
-.B Identifier
-entry.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this monitor.
-The
-.B Monitor
-section may be used to provide information about the specifications of the
-monitor, monitor-specific
-.BR Options ,
-and information about the video modes to use with the monitor.
-.PP
-With RandR 1.2-enabled drivers, monitor sections may be tied to specific
-outputs of the video card.  Using the name of the output defined by the video
-driver plus the identifier of a monitor section, one associates a monitor
-section with an output by adding an option to the Device section in the
-following format:
-
-.B Option \*qMonitor-outputname\*q \*qmonitorsection\*q
-
-(for example,
-.B Option \*qMonitor-VGA\*q \*qVGA monitor\*q
-for a VGA output)
-.PP
-In the absence of specific association of monitor sections to outputs, if a
-monitor section is present the server will associate it with an output to
-preserve compatibility for previous single-head configurations.
-.PP
-Specifying video modes is optional because the server will use the DDC or other
-information provided by the monitor to automatically configure the list of
-modes available.
-When modes are specified explicitly in the
-.B Monitor
-section (with the
-.BR Modes ,
-.BR ModeLine ,
-or
-.B UseModes
-keywords), built-in modes with the same names are not included.
-Built-in modes with different names are, however, still implicitly included,
-when they meet the requirements of the monitor.
-.PP
-The entries that may be used in
-.B Monitor
-sections are described below.
-.TP 7
-.BI "VendorName  \*q" vendor \*q
-This optional entry specifies the monitor's manufacturer.
-.TP 7
-.BI "ModelName  \*q" model \*q
-This optional entry specifies the monitor's model.
-.TP 7
-.BI "HorizSync  " "horizsync\-range"
-gives the range(s) of horizontal sync frequencies supported by the
-monitor.
-.I horizsync\-range
-may be a comma separated list of either discrete values or ranges of
-values.
-A range of values is two values separated by a dash.
-By default the values are in units of kHz.
-They may be specified in MHz or Hz
-if
-.B MHz
-or
-.B Hz
-is added to the end of the line.
-The data given here is used by the __xservername__ server to determine if video
-modes are within the specifications of the monitor.
-This information should be available in the monitor's handbook.
-If this entry is omitted, a default range of 28\-33kHz is used.
-.TP 7
-.BI "VertRefresh  " "vertrefresh\-range"
-gives the range(s) of vertical refresh frequencies supported by the
-monitor.
-.I vertrefresh\-range
-may be a comma separated list of either discrete values or ranges of
-values.
-A range of values is two values separated by a dash.
-By default the values are in units of Hz.
-They may be specified in MHz or kHz
-if
-.B MHz
-or
-.B kHz
-is added to the end of the line.
-The data given here is used by the __xservername__ server to determine if video
-modes are within the specifications of the monitor.
-This information should be available in the monitor's handbook.
-If this entry is omitted, a default range of 43\-72Hz is used.
-.TP 7
-.BI "DisplaySize  " "width height"
-This optional entry gives the width and height, in millimetres, of the
-picture area of the monitor.
-If given this is used to calculate the horizontal and vertical pitch (DPI) of
-the screen.
-.TP 7
-.BI "Gamma  " "gamma\-value"
-.TP 7
-.BI "Gamma  " "red\-gamma green\-gamma blue\-gamma"
-This is an optional entry that can be used to specify the gamma correction
-for the monitor.
-It may be specified as either a single value or as three separate RGB values.
-The values should be in the range 0.1 to 10.0, and the default is 1.0.
-Not all drivers are capable of using this information.
-.TP 7
-.BI "UseModes  \*q" modesection\-id \*q
-Include the set of modes listed in the
-.B Modes
-section called
-.IR modesection\-id.
-This makes all of the modes defined in that section available for use by
-this monitor.
-.TP 7
-.BI "Mode  \*q" name \*q
-This is an optional multi-line entry that can be used to provide
-definitions for video modes for the monitor.
-In most cases this isn't necessary because the built-in set of VESA standard
-modes will be sufficient.
-The
-.B Mode
-keyword indicates the start of a multi-line video mode description.
-The mode description is terminated with the
-.B EndMode
-keyword.
-The mode description consists of the following entries:
-.RS 7
-.TP 4
-.BI "DotClock  " clock
-is the dot (pixel) clock rate to be used for the mode.
-.TP 4
-.BI "HTimings  " "hdisp hsyncstart hsyncend htotal"
-specifies the horizontal timings for the mode.
-.TP 4
-.BI "VTimings  " "vdisp vsyncstart vsyncend vtotal"
-specifies the vertical timings for the mode.
-.TP 4
-.BI "Flags  \*q" flag \*q " ..."
-specifies an optional set of mode flags, each of which is a separate
-string in double quotes.
-.B \*qInterlace\*q
-indicates that the mode is interlaced.
-.B \*qDoubleScan\*q
-indicates a mode where each scanline is doubled.
-.B \*q+HSync\*q
-and
-.B \*q\-HSync\*q
-can be used to select the polarity of the HSync signal.
-.B \*q+VSync\*q
-and
-.B \*q\-VSync\*q
-can be used to select the polarity of the VSync signal.
-.B \*qComposite\*q
-can be used to specify composite sync on hardware where this is supported.
-Additionally, on some hardware,
-.B \*q+CSync\*q
-and
-.B \*q\-CSync\*q
-may be used to select the composite sync polarity.
-.TP 4
-.BI "HSkew  " hskew
-specifies the number of pixels (towards the right edge of the screen) by
-which the display enable signal is to be skewed.
-Not all drivers use this information.
-This option might become necessary to override the default value supplied
-by the server (if any).
-\(lqRoving\(rq horizontal lines indicate this value needs to be increased.
-If the last few pixels on a scan line appear on the left of the screen,
-this value should be decreased.
-.TP 4
-.BI "VScan  " vscan
-specifies the number of times each scanline is painted on the screen.
-Not all drivers use this information.
-Values less than 1 are treated as 1, which is the default.
-Generally, the
-.B \*qDoubleScan\*q
-.B Flag
-mentioned above doubles this value.
-.RE
-.TP 7
-.BI "ModeLine  \*q" name \*q " mode\-description"
-This entry is a more compact version of the
-.B Mode
-entry, and it also can be used to specify video modes for the monitor.
-is a single line format for specifying video modes.
-In most cases this isn't necessary because the built\-in set of VESA
-standard modes will be sufficient.
-.PP
-.RS 7
-The
-.I mode\-description
-is in four sections, the first three of which are mandatory.
-The first is the dot (pixel) clock.
-This is a single number specifying the pixel clock rate for the mode in
-MHz.
-The second section is a list of four numbers specifying the horizontal
-timings.
-These numbers are the
-.IR hdisp ,
-.IR hsyncstart ,
-.IR hsyncend ,
-and
-.I htotal
-values.
-The third section is a list of four numbers specifying the vertical
-timings.
-These numbers are the
-.IR vdisp ,
-.IR vsyncstart ,
-.IR vsyncend ,
-and
-.I vtotal
-values.
-The final section is a list of flags specifying other characteristics of
-the mode.
-.B Interlace
-indicates that the mode is interlaced.
-.B DoubleScan
-indicates a mode where each scanline is doubled.
-.B +HSync
-and
-.B \-HSync
-can be used to select the polarity of the HSync signal.
-.B +VSync
-and
-.B \-VSync
-can be used to select the polarity of the VSync signal.
-.B Composite
-can be used to specify composite sync on hardware where this is supported.
-Additionally, on some hardware,
-.B +CSync
-and
-.B \-CSync
-may be used to select the composite sync polarity.
-The
-.B HSkew
-and
-.B VScan
-options mentioned above in the
-.B Modes
-entry description can also be used here.
-.RE
-.TP 7
-.BI "Option " "\*qDPMS\*q  " \*qbool\*q
-This option controls whether the server should enable the DPMS extension
-for power management for this screen.  The default is to enable the
-extension.
-.TP 7
-.BI "Option " "\*qSyncOnGreen\*q  " \*qbool\*q
-This option controls whether the video card should drive the sync signal
-on the green color pin.  Not all cards support this option, and most
-monitors do not require it.  The default is off.
-.TP 7
-.BI "Option " "\*qPrimary\*q  " \*qbool\*q
-This optional entry specifies that the monitor should be treated as the primary
-monitor. (RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qPreferredMode\*q  " \*qstring\*q
-This optional entry specifies a mode to be marked as the preferred initial mode
-of the monitor.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qPosition\*q  " "\*qx y\*q"
-This optional entry specifies the position of the monitor within the X
-screen.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qLeftOf\*q  " \*qoutput\*q
-This optional entry specifies that the monitor should be positioned to the
-left of the output (not monitor) of the given name.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qRightOf\*q  " \*qoutput\*q
-This optional entry specifies that the monitor should be positioned to the
-right of the output (not monitor) of the given name.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qAbove\*q  " \*qoutput\*q
-This optional entry specifies that the monitor should be positioned above the
-output (not monitor) of the given name.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qBelow\*q  " \*qoutput\*q
-This optional entry specifies that the monitor should be positioned below the
-output (not monitor) of the given name.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qEnable\*q  " \*qbool\*q
-This optional entry specifies whether the monitor should be turned on
-at startup.  By default, the server will attempt to enable all connected
-monitors.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qDefaultModes\*q  " \*qbool\*q
-This optional entry specifies whether the server should add supported default
-modes to the list of modes offered on this monitor. By default, the server
-will add default modes; you should only disable this if you can guarantee
-that EDID will be available at all times, or if you have added custom modelines
-which the server can use.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qMinClock\*q  " \*qfrequency\*q
-This optional entry specifies the minimum dot clock, in kHz, that is supported
-by the monitor.
-.TP 7
-.BI "Option " "\*qMaxClock\*q  " \*qfrequency\*q
-This optional entry specifies the maximum dot clock, in kHz, that is supported
-by the monitor.
-.TP 7
-.BI "Option " "\*qIgnore\*q  " \*qbool\*q
-This optional entry specifies that the monitor should be ignored entirely,
-and not reported through RandR.  This is useful if the hardware reports the
-presence of outputs that don't exist.
-(RandR 1.2-supporting drivers only)
-.TP 7
-.BI "Option " "\*qRotate\*q  " \*qrotation\*q
-This optional entry specifies the initial rotation of the given monitor.
-Valid values for rotation are \*qnormal\*q, \*qleft\*q, \*qright\*q, and
-\*qinverted\*q.
-(RandR 1.2-supporting drivers only)
-
-.SH "MODES SECTION"
-The config file may have multiple
-.B Modes
-sections, or none.
-These sections provide a way of defining sets of video modes independently
-of the
-.B Monitor
-sections.
-.B Monitor
-sections may include the definitions provided in these sections by
-using the
-.B UseModes
-keyword.
-In most cases the
-.B Modes
-sections are not necessary because the built\-in set of VESA standard modes
-will be sufficient.
-.PP
-.B Modes
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B  "Section \*qModes\*q"
-.BI "    Identifier \*q" name \*q
-.I  "    entries"
-.I  "    ..."
-.B  "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-entry specifies the unique name for this set of mode descriptions.
-The other entries permitted in
-.B Modes
-sections are the
-.B Mode
-and
-.B ModeLine
-entries that are described above in the
-.B Monitor
-section.
-.SH "SCREEN SECTION"
-The config file may have multiple
-.B Screen
-sections.
-There must be at least one, for the \(lqscreen\(rq being used.
-A \(lqscreen\(rq represents the binding of a graphics device
-.RB ( Device
-section) and a monitor
-.RB ( Monitor
-section).
-A
-.B Screen
-section is considered \(lqactive\(rq if it is referenced by an active
-.B ServerLayout
-section or by the
-.B \-screen
-command line option.
-If neither of those is present, the first
-.B Screen
-section found in the config file is considered the active one.
-.PP
-.B Screen
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B  "Section \*qScreen\*q"
-.BI "    Identifier \*q" name \*q
-.BI "    Device     \*q" devid \*q
-.BI "    Monitor    \*q" monid \*q
-.I  "    entries"
-.I  "    ..."
-.BI "    SubSection \*qDisplay\*q"
-.I  "       entries"
-.I  "       ...
-.B  "    EndSubSection"
-.I  "    ..."
-.B  "EndSection"
-.fi
-.RE
-.PP
-The
-.B Identifier
-and
-.B Device
-entries are mandatory.
-All others are optional.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this screen.
-The
-.B Screen
-section provides information specific to the whole screen, including
-screen\-specific
-.BR Options .
-In multi\-head configurations, there will be multiple active
-.B Screen
-sections, one for each head.
-The entries available
-for this section are:
-.TP 7
-.BI "Device  \*q" device\-id \*q
-This mandatory entry specifies the
-.B Device
-section to be used for this screen.
-This is what ties a specific graphics card to a screen.
-The
-.I device\-id
-must match the
-.B Identifier
-of a
-.B Device
-section in the config file.
-.TP 7
-.BI "Monitor  \*q" monitor\-id \*q
-specifies which monitor description is to be used for this screen.
-If a
-.B Monitor
-name is not specified, a default configuration is used.
-Currently the default configuration may not function as expected on all
-platforms.
-.TP 7
-.BI "VideoAdaptor  \*q" xv\-id \*q
-specifies an optional Xv video adaptor description to be used with this
-screen.
-.TP 7
-.BI "DefaultDepth  " depth
-specifies which color depth the server should use by default.
-The
-.B \-depth
-command line option can be used to override this.
-If neither is specified, the default depth is driver\-specific, but in most
-cases is 8.
-.TP 7
-.BI "DefaultFbBpp  " bpp
-specifies which framebuffer layout to use by default.
-The
-.B \-fbbpp
-command line option can be used to override this.
-In most cases the driver will chose the best default value for this.
-The only case where there is even a choice in this value is for depth 24,
-where some hardware supports both a packed 24 bit framebuffer layout and a
-sparse 32 bit framebuffer layout.
-.TP 7
-.B Options
-Various
-.B Option
-flags may be specified in the
-.B Screen
-section.
-Some are driver\-specific and are described in the driver documentation.
-Others are driver\-independent, and will eventually be described here.
-.\" XXX These should really be in an xaa man page.
-.TP 7
-.BI "Option \*qAccel\*q"
-Enables XAA (X Acceleration Architecture), a mechanism that makes video cards'
-2D hardware acceleration available to the  __xservername__ server.
-This option is on by default, but it may be necessary to turn it off if
-there are bugs in the driver.
-There are many options to disable specific accelerated operations, listed
-below.
-Note that disabling an operation will have no effect if the operation is
-not accelerated (whether due to lack of support in the hardware or in the
-driver).
-.TP 7
-.BI "Option \*qInitPrimary\*q \*q" boolean \*q
-Use the Int10 module to initialize the primary graphics card.
-Normally, only secondary cards are soft-booted using the Int10 module, as the
-primary card has already been initialized by the BIOS at boot time.
-Default: false.
-.TP 7
-.BI "Option \*qNoInt10\*q \*q" boolean \*q
-Disables the Int10 module, a module that uses the int10 call to the BIOS
-of the graphics card to initialize it.
-Default: false.
-.TP 7
-.BI "Option \*qNoMTRR\*q"
-Disables MTRR (Memory Type Range Register) support, a feature of modern
-processors which can improve video performance by a factor of up to 2.5.
-Some hardware has buggy MTRR support, and some video drivers have been
-known to exhibit problems when MTRR's are used.
-.TP 7
-.BI "Option \*qXaaNoCPUToScreenColorExpandFill\*q"
-Disables accelerated rectangular expansion blits from source patterns
-stored in system memory (using a memory\-mapped aperture).
-.TP 7
-.BI "Option \*qXaaNoColor8x8PatternFillRect\*q"
-Disables accelerated fills of a rectangular region with a full\-color
-pattern.
-.TP 7
-.BI "Option \*qXaaNoColor8x8PatternFillTrap\*q"
-Disables accelerated fills of a trapezoidal region with a full\-color
-pattern.
-.TP 7
-.BI "Option \*qXaaNoDashedBresenhamLine\*q"
-Disables accelerated dashed Bresenham line draws.
-.TP 7
-.BI "Option \*qXaaNoDashedTwoPointLine\*q"
-Disables accelerated dashed line draws between two arbitrary points.
-.TP 7
-.BI "Option \*qXaaNoImageWriteRect\*q"
-Disables accelerated transfers of full\-color rectangular patterns from
-system memory to video memory (using a memory\-mapped aperture).
-.TP 7
-.BI "Option \*qXaaNoMono8x8PatternFillRect\*q"
-Disables accelerated fills of a rectangular region with a monochrome
-pattern.
-.TP 7
-.BI "Option \*qXaaNoMono8x8PatternFillTrap\*q"
-Disables accelerated fills of a trapezoidal region with a monochrome
-pattern.
-.TP 7
-.BI "Option \*qXaaNoOffscreenPixmaps\*q"
-Disables accelerated draws into pixmaps stored in offscreen video memory.
-.TP 7
-.BI "Option \*qXaaNoPixmapCache\*q"
-Disables caching of patterns in offscreen video memory.
-.TP 7
-.BI "Option \*qXaaNoScanlineCPUToScreenColorExpandFill\*q"
-Disables accelerated rectangular expansion blits from source patterns
-stored in system memory (one scan line at a time).
-.TP 7
-.BI "Option \*qXaaNoScanlineImageWriteRect\*q"
-Disables accelerated transfers of full\-color rectangular patterns from
-system memory to video memory (one scan line at a time).
-.TP 7
-.BI "Option \*qXaaNoScreenToScreenColorExpandFill\*q"
-Disables accelerated rectangular expansion blits from source patterns
-stored in offscreen video memory.
-.TP 7
-.BI "Option \*qXaaNoScreenToScreenCopy\*q"
-Disables accelerated copies of rectangular regions from one part of
-video memory to another part of video memory.
-.TP 7
-.BI "Option \*qXaaNoSolidBresenhamLine\*q"
-Disables accelerated solid Bresenham line draws.
-.TP 7
-.BI "Option \*qXaaNoSolidFillRect\*q"
-Disables accelerated solid\-color fills of rectangles.
-.TP 7
-.BI "Option \*qXaaNoSolidFillTrap\*q"
-Disables accelerated solid\-color fills of Bresenham trapezoids.
-.TP 7
-.BI "Option \*qXaaNoSolidHorVertLine\*q"
-Disables accelerated solid horizontal and vertical line draws.
-.TP 7
-.BI "Option \*qXaaNoSolidTwoPointLine\*q"
-Disables accelerated solid line draws between two arbitrary points.
-.PP
-Each
-.B Screen
-section may optionally contain one or more
-.B Display
-subsections.
-Those subsections provide depth/fbbpp specific configuration information,
-and the one chosen depends on the depth and/or fbbpp that is being used for
-the screen.
-The
-.B Display
-subsection format is described in the section below.
-
-.SH "DISPLAY SUBSECTION"
-Each
-.B Screen
-section may have multiple
-.B Display
-subsections.
-The \(lqactive\(rq
-.B Display
-subsection is the first that matches the depth and/or fbbpp values being
-used, or failing that, the first that has neither a depth or fbbpp value
-specified.
-The
-.B Display
-subsections are optional.
-When there isn't one that matches the depth and/or fbbpp values being used,
-all the parameters that can be specified here fall back to their defaults.
-.PP
-.B Display
-subsections have the following format:
-.PP
-.RS 4
-.nf
-.B  "    SubSection \*qDisplay\*q"
-.BI "        Depth  " depth
-.I  "        entries"
-.I  "        ..."
-.B  "    EndSubSection"
-.fi
-.RE
-.TP 7
-.BI "Depth  " depth
-This entry specifies what colour depth the
-.B Display
-subsection is to be used for.
-This entry is usually specified, but it may be omitted to create a match\-all
-.B Display
-subsection or when wishing to match only against the
-.B FbBpp
-parameter.
-The range of
-.I depth
-values that are allowed depends on the driver.
-Most drivers support 8, 15, 16 and 24.
-Some also support 1 and/or 4, and some may support other values (like 30).
-Note:
-.I depth
-means the number of bits in a pixel that are actually used to determine
-the pixel colour.
-32 is not a valid
-.I depth
-value.
-Most hardware that uses 32 bits per pixel only uses 24 of them to hold the
-colour information, which means that the colour depth is 24, not 32.
-.TP 7
-.BI "FbBpp  " bpp
-This entry specifies the framebuffer format this
-.B Display
-subsection is to be used for.
-This entry is only needed when providing depth 24 configurations that allow
-a choice between a 24 bpp packed framebuffer format and a 32bpp sparse
-framebuffer format.
-In most cases this entry should not be used.
-.TP 7
-.BI "Weight  " "red\-weight green\-weight blue\-weight"
-This optional entry specifies the relative RGB weighting to be used
-for a screen is being used at depth 16 for drivers that allow multiple
-formats.
-This may also be specified from the command line with the
-.B \-weight
-option (see
-.BR __xservername__(__appmansuffix__)).
-.TP 7
-.BI "Virtual  " "xdim ydim"
-This optional entry specifies the virtual screen resolution to be used.
-.I xdim
-must be a multiple of either 8 or 16 for most drivers, and a multiple
-of 32 when running in monochrome mode.
-The given value will be rounded down if this is not the case.
-Video modes which are too large for the specified virtual size will be
-rejected.
-If this entry is not present, the virtual screen resolution will be set to
-accommodate all the valid video modes given in the
-.B Modes
-entry.
-Some drivers/hardware combinations do not support virtual screens.
-Refer to the appropriate driver\-specific documentation for details.
-.TP 7
-.BI "ViewPort  " "x0 y0"
-This optional entry sets the upper left corner of the initial display.
-This is only relevant when the virtual screen resolution is different
-from the resolution of the initial video mode.
-If this entry is not given, then the initial display will be centered in
-the virtual display area.
-.TP 7
-.BI "Modes  \*q" mode\-name \*q " ..."
-This optional entry specifies the list of video modes to use.
-Each
-.I mode\-name
-specified must be in double quotes.
-They must correspond to those specified or referenced in the appropriate
-.B Monitor
-section (including implicitly referenced built\-in VESA standard modes).
-The server will delete modes from this list which don't satisfy various
-requirements.
-The first valid mode in this list will be the default display mode for
-startup.
-The list of valid modes is converted internally into a circular list.
-It is possible to switch to the next mode with
-.B Ctrl+Alt+Keypad\-Plus
-and to the previous mode with
-.BR Ctrl+Alt+Keypad\-Minus .
-When this entry is omitted, the valid modes referenced by the appropriate
-.B Monitor
-section will be used.  If the
-.B Monitor
-section contains no modes, then the selection will be taken from the
-built-in VESA standard modes.
-.TP 7
-.BI "Visual  \*q" visual\-name \*q
-This optional entry sets the default root visual type.
-This may also be specified from the command line (see the
-.BR Xserver(__appmansuffix__)
-man page).
-The visual types available for depth 8 are (default is
-.BR PseudoColor ):
-.PP
-.RS 11
-.nf
-.B StaticGray
-.B GrayScale
-.B StaticColor
-.B PseudoColor
-.B TrueColor
-.B DirectColor
-.fi
-.RE
-.PP
-.RS 7
-The visual type available for the depths 15, 16 and 24 are (default is
-.BR TrueColor ):
-.PP
-.RS 4
-.nf
-.B TrueColor
-.B DirectColor
-.fi
-.RE
-.PP
-Not all drivers support
-.B DirectColor
-at these depths.
-.PP
-The visual types available for the depth 4 are (default is
-.BR StaticColor ):
-.PP
-.RS 4
-.nf
-.B StaticGray
-.B GrayScale
-.B StaticColor
-.B PseudoColor
-.fi
-.RE
-.PP
-The visual type available for the depth 1 (monochrome) is
-.BR StaticGray .
-.RE
-.TP 7
-.BI "Black  " "red green blue"
-This optional entry allows the \(lqblack\(rq colour to be specified.
-This is only supported at depth 1.
-The default is black.
-.TP 7
-.BI "White  " "red green blue"
-This optional entry allows the \(lqwhite\(rq colour to be specified.
-This is only supported at depth 1.
-The default is white.
-.TP 7
-.B Options
-Option flags may be specified in the
-.B Display
-subsections.
-These may include driver\-specific options and driver\-independent options.
-The former are described in the driver\-specific documentation.
-Some of the latter are described above in the section about the
-.B Screen
-section, and they may also be included here.
-.SH "SERVERLAYOUT SECTION"
-The config file may have multiple
-.B ServerLayout
-sections.
-A \(lqserver layout\(rq represents the binding of one or more screens
-.RB ( Screen
-sections) and one or more input devices
-.RB ( InputDevice
-sections) to form a complete configuration.
-In multi\-head configurations, it also specifies the relative layout of the
-heads.
-A
-.B ServerLayout
-section is considered \(lqactive\(rq if it is referenced by the
-.B \-layout
-command line option or by an
-.B "Option \*qDefaultServerLayout\*q"
-entry in the
-.B ServerFlags
-section (the former takes precedence over the latter).
-If those options are not used, the first
-.B ServerLayout
-section found in the config file is considered the active one.
-If no
-.B ServerLayout
-sections are present, the single active screen and two active (core)
-input devices are selected as described in the relevant sections above.
-.PP
-.B ServerLayout
-sections have the following format:
-.PP
-.RS 4
-.nf
-.B  "Section \*qServerLayout\*q"
-.BI "    Identifier   \*q" name \*q
-.BI "    Screen       \*q" screen\-id \*q
-.I  "    ..."
-.BI "    InputDevice  \*q" idev\-id \*q
-.I  "    ..."
-.I  "    options"
-.I  "    ..."
-.B  "EndSection"
-.fi
-.RE
-.PP
-Each
-.B ServerLayout
-section must have an
-.B Identifier
-entry and at least one
-.B Screen
-entry.
-.PP
-The
-.B Identifier
-entry specifies the unique name for this server layout.
-The
-.B ServerLayout
-section provides information specific to the whole session, including
-session\-specific
-.BR Options .
-The
-.B ServerFlags
-options (described above) may be specified here, and ones given here
-override those given in the
-.B ServerFlags
-section.
-.PP
-The entries that may be used in this section are described here.
-.TP 7
-.BI "Screen  " "screen\-num" " \*qscreen\-id\*q " "position\-information"
-One of these entries must be given for each screen being used in
-a session.
-The
-.I screen\-id
-field is mandatory, and specifies the
-.B Screen
-section being referenced.
-The
-.I screen\-num
-field is optional, and may be used to specify the screen number
-in multi\-head configurations.
-When this field is omitted, the screens will be numbered in the order that
-they are listed in.
-The numbering starts from 0, and must be consecutive.
-The
-.I position\-information
-field describes the way multiple screens are positioned.
-There are a number of different ways that this information can be provided:
-.RS 7
-.TP 4
-.I  "x y"
-.TP 4
-.BI "Absolute  " "x y"
-These both specify that the upper left corner's coordinates are
-.RI ( x , y ).
-The
-.B Absolute
-keyword is optional.
-Some older versions of XFree86 (4.2 and earlier) don't recognise the
-.B Absolute
-keyword, so it's safest to just specify the coordinates without it.
-.TP 4
-.BI "RightOf   \*q" screen\-id \*q
-.TP 4
-.BI "LeftOf    \*q" screen\-id \*q
-.TP 4
-.BI "Above     \*q" screen\-id \*q
-.TP 4
-.BI "Below     \*q" screen\-id \*q
-.TP 4
-.BI "Relative  \*q" screen\-id \*q " x y"
-These give the screen's location relative to another screen.
-The first four position the screen immediately to the right, left, above or
-below the other screen.
-When positioning to the right or left, the top edges are aligned.
-When positioning above or below, the left edges are aligned.
-The
-.B Relative
-form specifies the offset of the screen's origin (upper left corner)
-relative to the origin of another screen.
-.RE
-.TP 7
-.BI "InputDevice  \*q" idev\-id "\*q \*q" option \*q " ..."
-One of these entries should be given for each input device being used in
-a session.
-Normally at least two are required, one each for the core pointer and
-keyboard devices.
-If either of those is missing, suitable
-.B InputDevice
-entries are searched for using the method described above in the
-.B INPUTDEVICE
-section.  The
-.I idev\-id
-field is mandatory, and specifies the name of the
-.B InputDevice
-section being referenced.
-Multiple
-.I option
-fields may be specified, each in double quotes.
-The options permitted here are any that may also be given in the
-.B InputDevice
-sections.
-Normally only session\-specific input device options would be used here.
-The most commonly used options are:
-.PP
-.RS 11
-.nf
-.B \*qCorePointer\*q
-.B \*qCoreKeyboard\*q
-.B \*qSendCoreEvents\*q
-.fi
-.RE
-.PP
-.RS 7
-and the first two should normally be used to indicate the core pointer
-and core keyboard devices respectively.
-.RE
-.TP 7
-.B Options
-In addition to the following, any option permitted in the
-.B ServerFlags
-section may also be specified here.
-When the same option appears in both places, the value given here overrides
-the one given in the
-.B ServerFlags
-section.
-.TP 7
-.BI "Option \*qIsolateDevice\*q  \*q" bus\-id \*q
-Restrict device resets to the specified
-.IR bus\-id .
-See the
-.B BusID
-option (described in
-.BR "DEVICE SECTION" ,
-above) for the format of the
-.I bus\-id
-parameter.
-This option overrides
-.BR SingleCard ,
-if specified.
-At present, only PCI devices can be isolated in this manner.
-.TP 7
-.BI "Option \*qSingleCard\*q  \*q" boolean \*q
-As
-.BR IsolateDevice ,
-except that the bus ID of the first device in the layout is used.
-.PP
-Here is an example of a
-.B ServerLayout
-section for a dual headed configuration with two mice:
-.PP
-.RS 4
-.nf
-.B "Section \*qServerLayout\*q"
-.B "    Identifier  \*qLayout 1\*q"
-.B "    Screen      \*qMGA 1\*q"
-.B "    Screen      \*qMGA 2\*q RightOf \*qMGA 1\*q"
-.B "    InputDevice \*qKeyboard 1\*q \*qCoreKeyboard\*q"
-.B "    InputDevice \*qMouse 1\*q    \*qCorePointer\*q"
-.B "    InputDevice \*qMouse 2\*q    \*qSendCoreEvents\*q"
-.B "    Option      \*qBlankTime\*q  \*q5\*q"
-.B "EndSection"
-.fi
-.RE
-.SH "DRI SECTION"
-This optional section is used to provide some information for the
-Direct Rendering Infrastructure.
-Details about the format of this section can be found on-line at
-.IR <http://dri.freedesktop.org/> .
-.SH "VENDOR SECTION"
-The optional
-.B Vendor
-section may be used to provide vendor\-specific configuration information.
-Multiple
-.B Vendor
-sections may be present, and they may contain an
-.B Identifier
-entry and multiple
-.B Option
-flags.
-The data therein is not used in this release.
-.PP
-.SH "SEE ALSO"
-General:
-.BR X (__miscmansuffix__),
-.BR Xserver (__appmansuffix__),
-.BR __xservername__ (__appmansuffix__),
-.BR cvt (__appmansuffix__),
-.BR gtf (__appmansuffix__).
-.PP
-.B "Not all modules or interfaces are available on all platforms."
-.PP
-Display drivers:
-.BR apm (__drivermansuffix__),
-.BR ati (__drivermansuffix__),
-.BR chips (__drivermansuffix__),
-.BR cirrus (__drivermansuffix__),
-.BR cyrix (__drivermansuffix__),
-.BR fbdev (__drivermansuffix__),
-.BR glide (__drivermansuffix__),
-.BR glint (__drivermansuffix__),
-.BR i128 (__drivermansuffix__),
-.BR i740 (__drivermansuffix__),
-.BR imstt (__drivermansuffix__),
-.BR intel (__drivermansuffix__),
-.BR mga (__drivermansuffix__),
-.BR neomagic (__drivermansuffix__),
-.BR nv (__drivermansuffix__),
-.BR openchrome (__drivermansuffix__),
-.BR r128 (__drivermansuffix__),
-.BR radeon (__drivermansuffix__),
-.BR rendition (__drivermansuffix__),
-.BR savage (__drivermansuffix__),
-.BR s3virge (__drivermansuffix__),
-.BR siliconmotion (__drivermansuffix__),
-.BR sis (__drivermansuffix__),
-.BR sisusb (__drivermansuffix__),
-.BR sunbw2 (__drivermansuffix__),
-.BR suncg14 (__drivermansuffix__),
-.BR suncg3 (__drivermansuffix__),
-.BR suncg6 (__drivermansuffix__),
-.BR sunffb (__drivermansuffix__),
-.BR sunleo (__drivermansuffix__),
-.BR suntcx (__drivermansuffix__),
-.BR tdfx (__drivermansuffix__),
-.\" .BR tga (__drivermansuffix__),
-.BR trident (__drivermansuffix__),
-.BR tseng (__drivermansuffix__),
-.BR vesa (__drivermansuffix__),
-.BR vmware (__drivermansuffix__),
-.BR voodoo (__drivermansuffix__),
-.BR wsfb (__drivermansuffix__),
-.BR xgi (__drivermansuffix__),
-.BR xgixp (__drivermansuffix__).
-.PP
-Input drivers:
-.BR acecad (__drivermansuffix__),
-.BR citron (__drivermansuffix__),
-.BR elographics (__drivermansuffix__),
-.BR evdev (__drivermansuffix__),
-.BR fpit (__drivermansuffix__),
-.BR joystick (__drivermansuffix__),
-.BR kbd (__drivermansuffix__),
-.BR mousedrv (__drivermansuffix__),
-.BR mutouch (__drivermansuffix__),
-.BR penmount (__drivermansuffix__),
-.BR synaptics (__drivermansuffix__),
-.BR vmmouse (__drivermansuffix__),
-.BR void (__drivermansuffix__),
-.BR wacom (__drivermansuffix__).
-.PP
-Other modules and interfaces:
-.BR exa (__drivermansuffix__),
-.BR fbdevhw (__drivermansuffix__),
-.\" .BR shadowfb (__drivermansuffix__),
-.BR v4l (__drivermansuffix__).
-.br
-.SH AUTHORS
-This manual page was largely rewritten by David Dawes
-.IR <dawes@xfree86.org> .
diff --git a/xorg-server/hw/xfree86/man/Makefile.am b/xorg-server/hw/xfree86/man/Makefile.am
new file mode 100644
index 000000000..80e22cbab
--- /dev/null
+++ b/xorg-server/hw/xfree86/man/Makefile.am
@@ -0,0 +1,3 @@
+include $(top_srcdir)/manpages.am
+appman_PRE = Xorg.man
+fileman_PRE = xorg.conf.man xorg.conf.d.man
diff --git a/xorg-server/hw/xfree86/man/Xorg.man b/xorg-server/hw/xfree86/man/Xorg.man
new file mode 100644
index 000000000..6fa334cc3
--- /dev/null
+++ b/xorg-server/hw/xfree86/man/Xorg.man
@@ -0,0 +1,689 @@
+.\" $XdotOrg: xserver/xorg/hw/xfree86/doc/man/Xorg.man.pre,v 1.3 2005/07/04 18:41:01 ajax Exp $
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH __xservername__ __appmansuffix__ __vendorversion__
+.SH NAME
+__xservername__ - X11R7 X server
+.SH SYNOPSIS
+.B __xservername__
+.RI [\fB:\fP display ]
+.RI [ option
+.IR ... ]
+.SH DESCRIPTION
+.B __xservername__
+is a full featured X server that was originally designed for UNIX and
+UNIX-like operating systems running on Intel x86 hardware.  It now runs
+on a wider range of hardware and OS platforms.
+.PP
+This work was derived by the X.Org Foundation from the XFree86 Project's
+.I "XFree86\ 4.4rc2"
+release.
+The XFree86 release was originally derived from
+.I "X386\ 1.2"
+by Thomas Roell which was contributed to X11R5 by Snitily Graphics
+Consulting Service.
+.SH PLATFORMS
+.PP
+.B __xservername__
+operates under a wide range of operating systems and hardware platforms.
+The Intel x86 (IA32) architecture is the most widely supported hardware
+platform.  Other hardware platforms include Compaq Alpha, Intel IA64, AMD64,
+SPARC and PowerPC.  The most widely supported operating systems are the
+free/OpenSource UNIX-like systems such as Linux, FreeBSD, NetBSD,
+OpenBSD, and Solaris.  Commercial UNIX operating systems such as
+UnixWare are also supported.  Other supported operating systems include
+GNU Hurd.  Mac OS X is supported with the
+Xquartz(__appmansuffix__) X server.  Win32/Cygwin is supported with the
+XWin(__appmansuffix__) X server.
+.PP
+.SH "NETWORK CONNECTIONS"
+.B __xservername__
+supports connections made using the following reliable
+byte-streams:
+.TP 4
+.I "Local"
+On most platforms, the "Local" connection type is a UNIX-domain socket.
+On some System V platforms, the "local" connection types also include
+STREAMS pipes, named pipes, and some other mechanisms.
+.TP 4
+.I TCP\/IP
+.B __xservername__
+listens on port
+.RI 6000+ n ,
+where
+.I n
+is the display number.  This connection type can be disabled with the
+.B \-nolisten
+option (see the Xserver(1) man page for details).
+.SH "ENVIRONMENT VARIABLES"
+For operating systems that support local connections other than Unix
+Domain sockets (SVR3 and SVR4), there is a compiled-in list specifying
+the order in which local connections should be attempted.  This list
+can be overridden by the
+.I XLOCAL
+environment variable described below.  If the display name indicates a
+best-choice connection should be made (e.g.
+.BR :0.0 ),
+each connection mechanism is tried until a connection succeeds or no
+more mechanisms are available.  Note: for these OSs, the Unix Domain
+socket connection is treated differently from the other local connection
+types.  To use it the connection must be made to
+.BR unix:0.0 .
+.PP
+The
+.I XLOCAL
+environment variable should contain a list of one more
+more of the following:
+.PP
+.RS 8
+.nf
+NAMED
+PTS
+SCO
+ISC
+.fi
+.RE
+.PP
+which represent SVR4 Named Streams pipe, Old-style USL Streams pipe,
+SCO XSight Streams pipe, and ISC Streams pipe, respectively.  You can
+select a single mechanism (e.g.
+.IR XLOCAL=NAMED ),
+or an ordered list (e.g. \fIXLOCAL="NAMED:PTS:SCO"\fP).
+his variable overrides the compiled-in defaults.  For SVR4 it is
+recommended that
+.I NAMED
+be the first preference connection.  The default setting is
+.IR PTS:NAMED:ISC:SCO .
+.PP
+To globally override the compiled-in defaults, you should define (and
+export if using
+.B sh
+or
+.BR ksh )
+.I XLOCAL
+globally.  If you use startx(1) or xinit(1), the definition should be
+at the top of your
+.I .xinitrc
+file.  If you use xdm(1), the definitions should be early on in the
+.I __projectroot__/lib/X11/xdm/Xsession
+script.
+.SH OPTIONS
+.B __xservername__
+supports several mechanisms for supplying/obtaining configuration and
+run-time parameters: command line options, environment variables, the
+__xconfigfile__(__filemansuffix__) configuration files, auto-detection, and
+fallback defaults.  When the same information is supplied in more than
+one way, the highest precedence mechanism is used.  The list of mechanisms
+is ordered from highest precedence to lowest.  Note that not all parameters
+can be supplied via all methods.  The available command line options
+and environment variables (and some defaults) are described here and in
+the Xserver(__appmansuffix__) manual page.  Most configuration file
+parameters, with their defaults, are described in the
+__xconfigfile__(__filemansuffix__) manual page.  Driver and module specific
+configuration parameters are described in the relevant driver or module
+manual page.
+.PP
+In addition to the normal server options described in the
+Xserver(__appmansuffix__) manual page,
+.B __xservername__
+accepts the following command line switches:
+.TP 8
+.BI vt XX
+.I XX
+specifies the Virtual Terminal device number which
+.B __xservername__
+will use.  Without this option,
+.B __xservername__
+will pick the first available Virtual Terminal that it can locate.  This
+option applies only to platforms that have virtual terminal support, such
+as Linux, BSD, OpenSolaris, SVR3, and SVR4.
+.TP
+.B \-allowMouseOpenFail
+Allow the server to start up even if the mouse device can't be opened
+or initialised.  This is equivalent to the
+.B AllowMouseOpenFail
+__xconfigfile__(__filemansuffix__) file option.
+.TP 8
+.B \-allowNonLocalXvidtune
+Make the VidMode extension available to remote clients.  This allows
+the xvidtune client to connect from another host.  This is equivalent
+to the
+.B AllowNonLocalXvidtune
+__xconfigfile__(__filemansuffix__) file option.  By default non-local
+connections are not allowed.
+.TP 8
+.BI \-bgamma " value"
+Set the blue gamma correction.
+.I value
+must be between 0.1 and 10.
+The default is 1.0.  Not all drivers support this.  See also the
+.BR \-gamma ,
+.BR \-rgamma ,
+and
+.B \-ggamma
+options.
+.TP 8
+.BI \-bpp " n"
+No longer supported.  Use
+.B \-depth
+to set the color depth, and use
+.B \-fbbpp
+if you really need to force a non-default framebuffer (hardware) pixel
+format.
+.TP 8
+.BI \-config " file"
+Read the server configuration from
+.IR file .
+This option will work for any file when the server is run as root (i.e,
+with real-uid 0), or for files relative to a directory in the config
+search path for all other users.
+.TP 8
+.BI \-configdir " directory"
+Read the server configuration files from
+.IR directory .
+This option will work for any directory when the server is run as root
+(i.e, with real-uid 0), or for directories relative to a directory in the
+config directory search path for all other users.
+.TP 8
+.B \-configure
+When this option is specified, the
+.B __xservername__
+server loads all video driver modules, probes for available hardware,
+and writes out an initial __xconfigfile__(__filemansuffix__) file based on
+what was detected.  This option currently has some problems on some
+platforms, but in most cases it is a good way to bootstrap the
+configuration process.  This option is only available when the server
+is run as root (i.e, with real-uid 0).
+.TP 8
+.BI "\-crt /dev/tty" XX
+SCO only.  This is the same as the
+.B vt
+option, and is provided for compatibility with the native SCO X server.
+.TP 8
+.BI \-depth " n"
+Sets the default color depth.  Legal values are 1, 4, 8, 15, 16, and
+24.  Not all drivers support all values.
+.TP 8
+.B \-disableVidMode
+Disable the parts of the VidMode extension (used by the xvidtune
+client) that can be used to change the video modes.  This is equivalent
+to the
+.B DisableVidModeExtension
+__xconfigfile__(__filemansuffix__) file option.
+.TP 8
+.B \-fbbpp \fIn\fP
+Sets the number of framebuffer bits per pixel.  You should only set this
+if you're sure it's necessary; normally the server can deduce the correct
+value from
+.B \-depth
+above.  Useful if you want to run a depth 24 configuration with a 24
+bpp framebuffer rather than the (possibly default) 32 bpp framebuffer
+(or vice versa).  Legal values are 1, 8, 16, 24, 32.  Not all drivers
+support all values.
+.TP 8
+.B \-flipPixels
+Swap the default values for the black and white pixels.
+.TP 8
+.BI \-gamma " value"
+Set the gamma correction.
+.I value
+must be between 0.1 and 10.  The default is 1.0.  This value is applied
+equally to the R, G and B values.  Those values can be set independently
+with the
+.BR \-rgamma ,
+.BR \-bgamma ,
+and
+.B \-ggamma
+options.  Not all drivers support this.
+.TP 8
+.BI \-ggamma " value"
+Set the green gamma correction.
+.I value
+must be between 0.1 and 10.  The default is 1.0.  Not all drivers support
+this.  See also the
+.BR \-gamma ,
+.BR \-rgamma ,
+and
+.B \-bgamma
+options.
+.TP 8
+.B \-ignoreABI
+The
+.B __xservername__
+server checks the ABI revision levels of each module that it loads.  It
+will normally refuse to load modules with ABI revisions that are newer
+than the server's.  This is because such modules might use interfaces
+that the server does not have.  When this option is specified, mismatches
+like this are downgraded from fatal errors to warnings.  This option
+should be used with care.
+.TP 8
+.B \-isolateDevice \fIbus\-id\fP
+Restrict device resets to the device at
+.IR bus\-id .
+The
+.I bus\-id
+string has the form
+.IB bustype : bus : device : function
+(e.g., \(oqPCI:1:0:0\(cq).
+At present, only isolation of PCI devices is supported; i.e., this option
+is ignored if
+.I bustype
+is anything other than \(oqPCI\(cq.
+.TP 8
+.B \-keeptty
+Prevent the server from detaching its initial controlling terminal.
+This option is only useful when debugging the server.  Not all platforms
+support (or can use) this option.
+.TP 8
+.BI \-keyboard " keyboard-name"
+Use the __xconfigfile__(__filemansuffix__) file
+.B InputDevice
+section called
+.I keyboard-name
+as the core keyboard.  This option is ignored when the
+.B Layout
+section specifies a core keyboard.  In the absence of both a Layout
+section and this option, the first relevant
+.B InputDevice
+section is used for the core keyboard.
+.TP 8
+.BI \-layout " layout-name"
+Use the __xconfigfile__(__filemansuffix__) file
+.B Layout
+section called
+.IR layout-name .
+By default the first
+.B Layout
+section is used.
+.TP 8
+.BI \-logfile " filename"
+Use the file called
+.I filename
+as the
+.B __xservername__
+server log file.  The default log file is
+.BI __logdir__/__xservername__. n .log
+on most platforms, where
+.I n
+is the display number of the
+.B __xservername__
+server.  The default may be in a different directory on some platforms.
+This option is only available when the server is run as root (i.e, with
+real-uid 0).
+.TP 8
+.BR \-logverbose " [\fIn\fP]"
+Sets the verbosity level for information printed to the
+.B __xservername__
+server log file.  If the
+.I n
+value isn't supplied, each occurrence of this option increments the log
+file verbosity level.  When the
+.I n
+value is supplied, the log file verbosity level is set to that value.
+The default log file verbosity level is 3.
+.TP 8
+.BI \-modulepath " searchpath"
+Set the module search path to
+.IR searchpath .
+.I searchpath
+is a comma separated list of directories to search for
+.B __xservername__
+server modules.  This option is only available when the server is run
+as root (i.e, with real-uid 0).
+.TP 8
+.B \-nosilk
+Disable Silken Mouse support.
+.TP 8
+.B \-pixmap24
+Set the internal pixmap format for depth 24 pixmaps to 24 bits per pixel.
+The default is usually 32 bits per pixel.  There is normally little
+reason to use this option.  Some client applications don't like this
+pixmap format, even though it is a perfectly legal format.  This is
+equivalent to the
+.B Pixmap
+__xconfigfile__(__filemansuffix__) file option.
+.TP 8
+.B \-pixmap32
+Set the internal pixmap format for depth 24 pixmaps to 32 bits per pixel.
+This is usually the default.  This is equivalent to the
+.B Pixmap
+__xconfigfile__(__filemansuffix__) file option.
+.TP 8
+.BI \-pointer " pointer-name"
+Use the __xconfigfile__(__filemansuffix__) file
+.B InputDevice
+section called
+.I pointer-name
+as the core pointer.  This option is ignored when the
+.B Layout
+section specifies a core pointer.  In the absence of both a Layout
+section and this option, the first relevant
+.B InputDevice
+section is used for the core pointer.
+.TP 8
+.B \-quiet
+Suppress most informational messages at startup.  The verbosity level
+is set to zero.
+.TP 8
+.BI \-rgamma " value"
+Set the red gamma correction.
+.I value
+must be between 0.1 and 10.  The default is 1.0.  Not all drivers support
+this.  See also the
+.BR \-gamma ,
+.BR \-bgamma ,
+and
+.B \-ggamma
+options.
+.TP 8
+.BI \-screen " screen-name"
+Use the __xconfigfile__(__filemansuffix__) file
+.B Screen
+section called
+.IR screen-name .
+By default the screens referenced by the default
+.B Layout
+section are used, or the first
+.B Screen
+section when there are no
+.B Layout
+sections.
+.TP 8
+.B \-showconfig
+This is the same as the
+.B \-version
+option, and is included for compatibility reasons.  It may be removed
+in a future release, so the
+.B \-version
+option should be used instead.
+.TP 8
+.B \-showDefaultModulePath
+Print out the default module path the server was compiled with.
+.TP 8
+.B \-showDefaultLibPath
+Print out the path libraries should be installed to.
+.TP 8
+.B \-showopts
+For each driver module installed, print out the list of options and their
+argument types.
+.TP 8
+.BI \-weight " nnn"
+Set RGB weighting at 16 bpp.  The default is 565.  This applies only to
+those drivers which support 16 bpp.
+.TP 8
+.BR \-verbose " [\fIn\fP]"
+Sets the verbosity level for information printed on stderr.  If the
+.I n
+value isn't supplied, each occurrence of this option increments the
+verbosity level.  When the
+.I n
+value is supplied, the verbosity level is set to that value.  The default
+verbosity level is 0.
+.TP 8
+.B \-version
+Print out the server version, patchlevel, release date, the operating
+system/platform it was built on, and whether it includes module loader
+support.
+.SH "KEYBOARD"
+.PP
+The
+.B __xservername__
+server is normally configured to recognize various special combinations
+of key presses that instruct the server to perform some action, rather
+than just sending the key press event to a client application. These actions
+depend on the XKB keymap loaded by a particular keyboard device and may or
+may not be available on a given configuration.
+.PP
+The following key combinations are commonly part of the default XKEYBOARD
+keymap.
+.TP 8
+.B Ctrl+Alt+Backspace
+Immediately kills the server -- no questions asked. It can be disabled by
+setting the
+.B DontZap
+__xconfigfile__(__filemansuffix__) file option to a TRUE value.
+.PP
+.RS 8
+It should be noted that zapping is triggered by the
+.B Terminate_Server
+action in the keyboard map. This action is not part of the default keymaps
+but can be enabled with the XKB option
+.B \*qterminate:ctrl_alt_bksp\*q.
+.RE
+.TP 8
+.B Ctrl+Alt+Keypad-Plus
+Change video mode to next one specified in the configuration file.
+This can be disabled with the
+.B DontZoom
+__xconfigfile__(__filemansuffix__) file option.
+.TP 8
+.B Ctrl+Alt+Keypad-Minus
+Change video mode to previous one specified in the configuration file.
+This can be disabled with the
+.B DontZoom
+__xconfigfile__(__filemansuffix__) file option.
+.TP 8
+.B Ctrl+Alt+F1...F12
+For systems with virtual terminal support, these keystroke
+combinations are used to switch to virtual terminals 1 through 12,
+respectively.  This can be disabled with the
+.B DontVTSwitch
+__xconfigfile__(__filemansuffix__) file option.
+.SH CONFIGURATION
+.B __xservername__
+typically uses a configuration file called
+.B __xconfigfile__
+and configuration files with the suffix
+.I .conf
+in a directory called
+.B __xconfigdir__
+for its initial setup.
+Refer to the __xconfigfile__(__filemansuffix__) manual page for information
+about the format of this file.
+.PP
+.B __xservername__
+has a mechanism for automatically generating a built-in configuration
+at run-time when no
+.B __xconfigfile__
+file or
+.B __xconfigdir__
+files are present.  The current version of this automatic configuration
+mechanism works in two ways.
+.PP
+The first is via enhancements that have made many components of the
+.B __xconfigfile__
+file optional.  This means that information that can be probed or
+reasonably deduced doesn't need to be specified explicitly, greatly
+reducing the amount of built-in configuration information that needs to
+be generated at run-time.
+.PP
+The second is to have "safe" fallbacks for most configuration information.
+This maximises the likelihood that the
+.B __xservername__
+server will start up in some usable configuration even when information
+about the specific hardware is not available.
+.PP
+The automatic configuration support for __xservername__ is work in progress.
+It is currently aimed at the most popular hardware and software platforms
+supported by __xservername__.  Enhancements are planned for future releases.
+.SH FILES
+The
+.B __xservername__
+server config files can be found in a range of locations.  These are
+documented fully in the __xconfigfile__(__filemansuffix__) manual page.  The
+most commonly used locations are shown here.
+.TP 30
+.B /etc/X11/__xconfigfile__
+Server configuration file.
+.TP 30
+.B /etc/X11/__xconfigfile__-4
+Server configuration file.
+.TP 30
+.B /etc/__xconfigfile__
+Server configuration file.
+.TP 30
+.B __projectroot__/etc/__xconfigfile__
+Server configuration file.
+.TP 30
+.B __projectroot__/lib/X11/__xconfigfile__
+Server configuration file.
+.TP 30
+.B /etc/X11/__xconfigdir__
+Server configuration directory.
+.TP 30
+.B /etc/X11/__xconfigdir__-4
+Server configuration directory.
+.TP 30
+.B /etc/__xconfigdir__
+Server configuration directory.
+.TP 30
+.B __projectroot__/etc/__xconfigdir__
+Server configuration directory.
+.TP 30
+.B __projectroot__/lib/X11/__xconfigdir__
+Server configuration directory.
+.TP 30
+.BI __logdir__/__xservername__. n .log
+Server log file for display
+.IR n .
+.TP 30
+.B __projectroot__/bin/\(**
+Client binaries.
+.TP 30
+.B __projectroot__/include/\(**
+Header files.
+.TP 30
+.B __projectroot__/lib/\(**
+Libraries.
+.TP 30
+.B __datadir__/fonts/X11/\(**
+Fonts.
+.TP 30
+.B __projectroot__/share/X11/XErrorDB
+Client error message database.
+.TP 30
+.B __projectroot__/lib/X11/app-defaults/\(**
+Client resource specifications.
+.TP 30
+.B __mandir__/man?/\(**
+Manual pages.
+.TP 30
+.BI /etc/X n .hosts
+Initial access control list for display
+.IR n .
+.SH "SEE ALSO"
+X(__miscmansuffix__), Xserver(__appmansuffix__), xdm(__appmansuffix__), xinit(__appmansuffix__),
+__xconfigfile__(__filemansuffix__), xvidtune(__appmansuffix__),
+apm(__drivermansuffix__),
+ati(__drivermansuffix__),
+chips(__drivermansuffix__),
+cirrus(__drivermansuffix__),
+cyrix(__drivermansuffix__),
+fbdev(__drivermansuffix__),
+glide(__drivermansuffix__),
+glint(__drivermansuffix__),
+i128(__drivermansuffix__),
+i740(__drivermansuffix__),
+imstt(__drivermansuffix__),
+intel(__drivermansuffix__),
+mga(__drivermansuffix__),
+neomagic(__drivermansuffix__),
+nsc(__drivermansuffix__),
+nv(__drivermansuffix__),
+openchrome (__drivermansuffix__),
+r128(__drivermansuffix__),
+rendition(__drivermansuffix__),
+s3virge(__drivermansuffix__),
+siliconmotion(__drivermansuffix__),
+sis(__drivermansuffix__),
+sunbw2(__drivermansuffix__),
+suncg14(__drivermansuffix__),
+suncg3(__drivermansuffix__),
+suncg6(__drivermansuffix__),
+sunffb(__drivermansuffix__),
+sunleo(__drivermansuffix__),
+suntcx(__drivermansuffix__),
+tdfx(__drivermansuffix__),
+tga(__drivermansuffix__),
+trident(__drivermansuffix__),
+tseng(__drivermansuffix__),
+v4l(__drivermansuffix__),
+vesa(__drivermansuffix__),
+vmware(__drivermansuffix__),
+.br
+Web site
+.IR <http://www.x.org> .
+
+.SH AUTHORS
+__xservername__ has many contributors world wide.  The names of most of them
+can be found in the documentation, ChangeLog files in the source tree,
+and in the actual source code.
+.PP
+__xservername__ was originally based on XFree86 4.4rc2.
+That was originally based on \fIX386 1.2\fP by Thomas Roell, which
+was contributed to the then X Consortium's X11R5 distribution by SGCS.
+.PP
+__xservername__ is released by the X.Org Foundation.
+.PP
+The project that became XFree86 was originally founded in 1992 by
+David Dawes, Glenn Lai, Jim Tsillas and David Wexelblat.
+.PP
+XFree86 was later integrated in the then X Consortium's X11R6 release
+by a group of dedicated XFree86 developers, including the following:
+.PP
+.RS 4
+.nf
+Stuart Anderson    \fIanderson@metrolink.com\fP
+Doug Anson         \fIdanson@lgc.com\fP
+Gertjan Akkerman   \fIakkerman@dutiba.twi.tudelft.nl\fP
+Mike Bernson       \fImike@mbsun.mlb.org\fP
+Robin Cutshaw      \fIrobin@XFree86.org\fP
+David Dawes        \fIdawes@XFree86.org\fP
+Marc Evans         \fImarc@XFree86.org\fP
+Pascal Haible      \fIhaible@izfm.uni-stuttgart.de\fP
+Matthieu Herrb     \fIMatthieu.Herrb@laas.fr\fP
+Dirk Hohndel       \fIhohndel@XFree86.org\fP
+David Holland      \fIdavidh@use.com\fP
+Alan Hourihane     \fIalanh@fairlite.demon.co.uk\fP
+Jeffrey Hsu        \fIhsu@soda.berkeley.edu\fP
+Glenn Lai          \fIglenn@cs.utexas.edu\fP
+Ted Lemon          \fImellon@ncd.com\fP
+Rich Murphey       \fIrich@XFree86.org\fP
+Hans Nasten        \fInasten@everyware.se\fP
+Mark Snitily       \fImark@sgcs.com\fP
+Randy Terbush      \fIrandyt@cse.unl.edu\fP
+Jon Tombs          \fItombs@XFree86.org\fP
+Kees Verstoep      \fIversto@cs.vu.nl\fP
+Paul Vixie         \fIpaul@vix.com\fP
+Mark Weaver        \fIMark_Weaver@brown.edu\fP
+David Wexelblat    \fIdwex@XFree86.org\fP
+Philip Wheatley    \fIPhilip.Wheatley@ColumbiaSC.NCR.COM\fP
+Thomas Wolfram     \fIwolf@prz.tu-berlin.de\fP
+Orest Zborowski    \fIorestz@eskimo.com\fP
+.fi
+.RE
+.PP
+__xservername__ source is available from the FTP server
+\fI<ftp://ftp.x.org/>\fP, and from the X.Org
+server \fI<http://gitweb.freedesktop.org/>\fP.  Documentation and other
+information can be found from the X.Org web site
+\fI<http://www.x.org/>\fP.
+
+.SH LEGAL
+.PP
+.B __xservername__
+is copyright software, provided under licenses that permit modification
+and redistribution in source and binary form without fee.
+.B __xservername__ is copyright by numerous authors and
+contributors from around the world.  Licensing information can be found
+at
+.IR <http://www.x.org> .
+Refer to the source code for specific copyright notices.
+.PP
+.B XFree86(TM)
+is a trademark of The XFree86 Project, Inc.
+.PP
+.B X11(TM)
+and
+.B X Window System(TM)
+are trademarks of The Open Group.
diff --git a/xorg-server/hw/xfree86/man/xorg.conf.d.man b/xorg-server/hw/xfree86/man/xorg.conf.d.man
new file mode 100644
index 000000000..6b3379ece
--- /dev/null
+++ b/xorg-server/hw/xfree86/man/xorg.conf.d.man
@@ -0,0 +1 @@
+.so man__filemansuffix__/xorg.conf.__filemansuffix__
diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man
new file mode 100644
index 000000000..e3fd0eadf
--- /dev/null
+++ b/xorg-server/hw/xfree86/man/xorg.conf.man
@@ -0,0 +1,2478 @@
+.\" shorthand for double quote that works everywhere.
+.ds q \N'34'
+.TH __xconfigfile__ __filemansuffix__ __vendorversion__
+.SH NAME
+__xconfigfile__ and __xconfigdir__ \- configuration files for
+__xservername__ X server
+.SH INTRODUCTION
+.B __xservername__
+supports several mechanisms for supplying/obtaining configuration and
+run-time parameters: command line options, environment variables, the
+__xconfigfile__ and __xconfigdir__ configuration files, auto-detection,
+and fallback defaults. When the same information is supplied in more
+than one way, the highest precedence mechanism is used. The list of
+mechanisms is ordered from highest precedence to lowest. Note that not
+all parameters can be supplied via all methods. The available command
+line options and environment variables (and some defaults) are
+described in the Xserver(__appmansuffix__) and
+__xservername__(__appmansuffix__) manual pages. Most configuration file
+parameters, with their defaults, are described below. Driver and module
+specific configuration parameters are described in the relevant driver
+or module manual page.
+.SH DESCRIPTION
+.B __xservername__
+uses a configuration file called
+.I __xconfigfile__
+and files ending in the suffix
+.I .conf
+from the directory
+.I __xconfigdir__
+for its initial setup.
+The
+.I __xconfigfile__
+configuration file is searched for in the following places when the
+server is started as a normal user:
+.PP
+.RS 4
+.nf
+.IR /etc/X11/ <cmdline>
+.IR __projectroot__/etc/X11/ <cmdline>
+.IB /etc/X11/ $XORGCONFIG
+.IB __projectroot__/etc/X11/ $XORGCONFIG
+.I /etc/X11/__xconfigfile__
+.I /etc/__xconfigfile__
+.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
+.I __projectroot__/etc/X11/__xconfigfile__
+.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
+.I __projectroot__/lib/X11/__xconfigfile__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is a relative path (with no \(lq..\(rq components) specified with the
+.B \-config
+command line option,
+.B $XORGCONFIG
+is the relative path (with no \(lq..\(rq components) specified by that
+environment variable, and
+.I <hostname>
+is the machine's hostname as reported by
+.BR gethostname (__libmansuffix__).
+.PP
+When the __xservername__ server is started by the \(lqroot\(rq user, the config file
+search locations are as follows:
+.PP
+.RS 4
+.nf
+<cmdline>
+.IR /etc/X11/ <cmdline>
+.IR __projectroot__/etc/X11/ <cmdline>
+.B $XORGCONFIG
+.IB /etc/X11/ $XORGCONFIG
+.IB __projectroot__/etc/X11/ $XORGCONFIG
+.I /etc/X11/__xconfigfile__
+.I /etc/__xconfigfile__
+.IR __projectroot__/etc/X11/__xconfigfile__. <hostname>
+.I __projectroot__/etc/X11/__xconfigfile__
+.IR __projectroot__/lib/X11/__xconfigfile__. <hostname>
+.I __projectroot__/lib/X11/__xconfigfile__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is the path specified with the
+.B \-config
+command line option (which may be absolute or relative),
+.B $XORGCONFIG
+is the path specified by that
+environment variable (absolute or relative),
+.B $HOME
+is the path specified by that environment variable (usually the home
+directory), and
+.I <hostname>
+is the machine's hostname as reported by
+.BR gethostname (__libmansuffix__).
+.PP
+Additional configuration files are searched for in the following
+directories when the server is started as a normal user:
+.PP
+.RS 4
+.nf
+.IR /etc/X11/ <cmdline>
+.IR __sysconfdir__/X11/ <cmdline>
+.I /etc/X11/__xconfigdir__
+.I __sysconfdir__/X11/__xconfigdir__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is a relative path (with no \(lq..\(rq components) specified with the
+.B \-configdir
+command line option.
+.PP
+When the __xservername__ server is started by the \(lqroot\(rq user, the
+config directory search locations are as follows:
+.PP
+.RS 4
+.nf
+<cmdline>
+.IR /etc/X11/ <cmdline>
+.IR __sysconfdir__/X11/ <cmdline>
+.I /etc/X11/__xconfigdir__
+.I __sysconfdir__/X11/__xconfigdir__
+.fi
+.RE
+.PP
+where
+.I <cmdline>
+is the path specified with the
+.B \-configdir
+command line option (which may be absolute or relative).
+.PP
+Finally, configuration files will also be searched for in directories
+reserved for system use. These are to separate configuration files from
+the vendor or 3rd party packages from those of local administration.
+These files are found in the following directories:
+.PP
+.RS 4
+.nf
+.I /usr/share/X11/__xconfigdir__
+.I __datadir__/X11/__xconfigdir__
+.fi
+.RE
+.PP
+The
+.I __xconfigfile__
+and
+.I __xconfigdir__
+files are composed of a number of sections which may be present in any order,
+or omitted to use default configuration values.
+Each section has the form:
+.PP
+.RS 4
+.nf
+.BI "Section  \*q" SectionName \*q
+.RI "    " SectionEntry
+    ...
+.B EndSection
+.fi
+.RE
+.PP
+The section names are:
+.PP
+.RS 4
+.nf
+.BR "Files          " "File pathnames"
+.BR "ServerFlags    " "Server flags"
+.BR "Module         " "Dynamic module loading"
+.BR "Extensions     " "Extension enabling"
+.BR "InputDevice    " "Input device description"
+.BR "InputClass     " "Input class description"
+.BR "Device         " "Graphics device description"
+.BR "VideoAdaptor   " "Xv video adaptor description"
+.BR "Monitor        " "Monitor description"
+.BR "Modes          " "Video modes descriptions"
+.BR "Screen         " "Screen configuration"
+.BR "ServerLayout   " "Overall layout"
+.BR "DRI            " "DRI\-specific configuration"
+.BR "Vendor         " "Vendor\-specific configuration"
+.fi
+.RE
+.PP
+The following obsolete section names are still recognised for compatibility
+purposes.
+In new config files, the
+.B InputDevice
+section should be used instead.
+.PP
+.RS 4
+.nf
+.BR "Keyboard       " "Keyboard configuration"
+.BR "Pointer        " "Pointer/mouse configuration"
+.fi
+.RE
+.PP
+The old
+.B XInput
+section is no longer recognised.
+.PP
+The
+.B ServerLayout
+sections are at the highest level.
+They bind together the input and output devices that will be used in a session.
+The input devices are described in the
+.B InputDevice
+sections.
+Output devices usually consist of multiple independent components (e.g.,
+a graphics board and a monitor).
+These multiple components are bound together in the
+.B Screen
+sections, and it is these that are referenced by the
+.B ServerLayout
+section.
+Each
+.B Screen
+section binds together a graphics board and a monitor.
+The graphics boards are described in the
+.B Device
+sections, and the monitors are described in the
+.B Monitor
+sections.
+.PP
+Config file keywords are case\-insensitive, and \(lq_\(rq characters are
+ignored.
+Most strings (including
+.B Option
+names) are also case-insensitive, and insensitive to white space and
+\(lq_\(rq characters.
+.PP
+Each config file entry usually takes up a single line in the file.  They
+consist of a keyword, which is possibly followed by one or more arguments,
+with the number and types of the arguments depending on the keyword.
+The argument types are:
+.PP
+.RS 4
+.nf
+.BR "Integer     " "an integer number in decimal, hex or octal"
+.BR "Real        " "a floating point number"
+.BR "String      " "a string enclosed in double quote marks (\*q)"
+.fi
+.RE
+.PP
+Note: hex integer values must be prefixed with \(lq0x\(rq, and octal values
+with \(lq0\(rq.
+.PP
+A special keyword called
+.B Option
+may be used to provide free\-form data to various components of the server.
+The
+.B Option
+keyword takes either one or two string arguments.
+The first is the option name, and the optional second argument is the
+option value.
+Some commonly used option value types include:
+.PP
+.RS 4
+.nf
+.BR "Integer     " "an integer number in decimal, hex or octal"
+.BR "Real        " "a floating point number"
+.BR "String      " "a sequence of characters"
+.BR "Boolean     " "a boolean value (see below)"
+.BR "Frequency   " "a frequency value (see below)"
+.fi
+.RE
+.PP
+Note that
+.I all
+.B Option
+values, not just strings, must be enclosed in quotes.
+.PP
+Boolean options may optionally have a value specified.
+When no value is specified, the option's value is
+.BR TRUE .
+The following boolean option values are recognised as
+.BR TRUE :
+.PP
+.RS 4
+.BR 1 ,
+.BR on ,
+.BR true ,
+.B yes
+.RE
+.PP
+and the following boolean option values are recognised as
+.BR FALSE :
+.PP
+.RS 4
+.BR 0 ,
+.BR off ,
+.BR false ,
+.B no
+.RE
+.PP
+If an option name is prefixed with
+.RB \*q No \*q,
+then the option value is negated.
+.PP
+Example: the following option entries are equivalent:
+.PP
+.RS 4
+.nf
+.B "Option \*qAccel\*q   \*qOff\*q"
+.B "Option \*qNoAccel\*q"
+.B "Option \*qNoAccel\*q \*qOn\*q"
+.B "Option \*qAccel\*q   \*qfalse\*q"
+.B "Option \*qAccel\*q   \*qno\*q"
+.fi
+.RE
+.PP
+Frequency option values consist of a real number that is optionally
+followed by one of the following frequency units:
+.PP
+.RS 4
+.BR Hz ,
+.BR k ,
+.BR kHz ,
+.BR M ,
+.B MHz
+.RE
+.PP
+When the unit name is omitted, the correct units will be determined from
+the value and the expectations of the appropriate range of the value.
+It is recommended that the units always be specified when using frequency
+option values to avoid any errors in determining the value.
+.SH "FILES SECTION"
+The
+.B Files
+section is used to specify some path names required by the server.
+Some of these paths can also be set from the command line (see
+.BR Xserver (__appmansuffix__)
+and
+.BR __xservername__ (__appmansuffix__)).
+The command line settings override the values specified in the config
+file.
+The
+.B Files
+section is optional, as are all of the entries that may appear in it.
+.PP
+The entries that can appear in this section are:
+.TP 7
+.BI "FontPath \*q" path \*q
+sets the search path for fonts.
+This path is a comma separated list of font path elements which the __xservername__
+server searches for font databases.
+Multiple
+.B FontPath
+entries may be specified, and they will be concatenated to build up the
+fontpath used by the server.  Font path elements can be absolute
+directory paths, catalogue directories or a font server identifier. The
+formats of the later two are explained below:
+.PP
+.RS 7
+Catalogue directories:
+.PP
+.RS 4
+Catalogue directories can be specified using the prefix \fBcatalogue:\fR
+before the directory name. The directory can then be populated with
+symlinks pointing to the real font directories, using the following
+syntax in the symlink name:
+.PP
+.RS 4
+.IR <identifier> : [attribute]: pri= <priority>
+.RE
+.PP
+where
+.I <identifier>
+is an alphanumeric identifier,
+.I [attribute]
+is an attribute which will be passed to the underlying FPE and
+.I <priority>
+is a number used to order the fontfile FPEs. Examples:
+.PP
+.RS 4
+.nf
+.I 75dpi:unscaled:pri=20  -> /usr/share/X11/fonts/75dpi
+.I gscript:pri=60 -> /usr/share/fonts/default/ghostscript
+.I misc:unscaled:pri=10 \-> /usr/share/X11/fonts/misc
+.fi
+.PP
+.RE .RE .RE
+.PP
+.RS 7
+Font server identifiers:
+.PP
+.RS 4
+Font server identifiers have the form:
+.RS 4
+.PP
+.IR <trans> / <hostname> : <port\-number>
+.RE
+.PP
+where
+.I <trans>
+is the transport type to use to connect to the font server (e.g.,
+.B unix
+for UNIX\-domain sockets or
+.B tcp
+for a TCP/IP connection),
+.I <hostname>
+is the hostname of the machine running the font server, and
+.I <port\-number>
+is the port number that the font server is listening on (usually 7100).
+.RE
+.PP
+When this entry is not specified in the config file, the server falls back
+to the compiled\-in default font path, which contains the following
+font path elements (which can be set inside a catalogue directory):
+.PP
+.RS 4
+.nf
+.I __datadir__/fonts/X11/misc/
+.I __datadir__/fonts/X11/TTF/
+.I __datadir__/fonts/X11/OTF/
+.I __datadir__/fonts/X11/Type1/
+.I __datadir__/fonts/X11/100dpi/
+.I __datadir__/fonts/X11/75dpi/
+.fi
+.RE
+.PP
+Font path elements that are found to be invalid are removed from the
+font path when the server starts up.
+.RE
+.TP 7
+.BI "ModulePath \*q" path \*q
+sets the search path for loadable __xservername__ server modules.
+This path is a comma separated list of directories which the __xservername__ server
+searches for loadable modules loading in the order specified.
+Multiple
+.B ModulePath
+entries may be specified, and they will be concatenated to build the
+module search path used by the server.  The default module path is
+.PP
+.RS 11
+__modulepath__
+.RE
+.\" The LogFile keyword is not currently implemented
+.ig
+.TP 7
+.BI "LogFile \*q" path \*q
+sets the name of the __xservername__ server log file.
+The default log file name is
+.PP
+.RS 11
+.RI __logdir__/__xservername__. <n> .log
+.RE
+.PP
+.RS 7
+where
+.I <n>
+is the display number for the __xservername__ server.
+..
+.TP 7
+.BI "XkbDir \*q" path \*q
+sets the base directory for keyboard layout files.  The
+.B \-xkbdir
+command line option can be used to override this.  The default directory is
+.PP
+.RS 11
+__xkbdir__
+.RE
+.SH "SERVERFLAGS SECTION"
+In addition to options specific to this section (described below), the
+.B ServerFlags
+section is used to specify some global
+__xservername__ server options.
+All of the entries in this section are
+.BR Options ,
+although for compatibility purposes some of the old style entries are
+still recognised.
+Those old style entries are not documented here, and using them is
+discouraged.
+The
+.B ServerFlags
+section is optional, as are the entries that may be specified in it.
+.PP
+.B Options
+specified in this section (with the exception of the
+.B \*qDefaultServerLayout\*q
+.BR Option )
+may be overridden by
+.B Options
+specified in the active
+.B ServerLayout
+section.
+Options with command line equivalents are overridden when their command
+line equivalent is used.
+The options recognised by this section are:
+.TP 7
+.BI "Option \*qDefaultServerLayout\*q  \*q" layout\-id \*q
+This specifies the default
+.B ServerLayout
+section to use in the absence of the
+.B \-layout
+command line option.
+.TP 7
+.BI "Option \*qNoTrapSignals\*q  \*q" boolean \*q
+This prevents the __xservername__ server from trapping a range of unexpected fatal
+signals and exiting cleanly.
+Instead, the __xservername__ server will die and drop core where the fault occurred.
+The default behaviour is for the __xservername__ server to exit cleanly, but still drop a
+core file.
+In general you never want to use this option unless you are debugging an __xservername__
+server problem and know how to deal with the consequences.
+.TP 7
+.BI "Option \*qUseSIGIO\*q  \*q" boolean \*q
+This controls whether the __xservername__ server requests that events from
+input devices be reported via a SIGIO signal handler (also known as SIGPOLL
+on some platforms), or only reported via the standard select(3) loop.
+The default behaviour is platform specific.   In general you do not want to
+use this option unless you are debugging the __xservername__ server, or
+working around a specific bug until it is fixed, and understand the
+consequences.
+.TP 7
+.BI "Option \*qDontVTSwitch\*q  \*q" boolean \*q
+This disallows the use of the
+.BI Ctrl+Alt+F n
+sequence (where
+.RI F n
+refers to one of the numbered function keys).
+That sequence is normally used to switch to another \*qvirtual terminal\*q
+on operating systems that have this feature.
+When this option is enabled, that key sequence has no special meaning and
+is passed to clients.
+Default: off.
+.TP 7
+.BI "Option \*qDontZap\*q  \*q" boolean \*q
+This disallows the use of the
+.B Terminate_Server
+XKB action (usually on Ctrl+Alt+Backspace, depending on XKB options).
+This action is normally used to terminate the __xservername__ server.
+When this option is enabled, the action has no effect.
+Default: off.
+.TP 7
+.BI "Option \*qDontZoom\*q  \*q" boolean \*q
+This disallows the use of the
+.B Ctrl+Alt+Keypad\-Plus
+and
+.B Ctrl+Alt+Keypad\-Minus
+sequences.
+These sequences allows you to switch between video modes.
+When this option is enabled, those key sequences have no special meaning
+and are passed to clients.
+Default: off.
+.TP 7
+.BI "Option \*qDisableVidModeExtension\*q  \*q" boolean \*q
+This disables the parts of the VidMode extension used by the xvidtune client
+that can be used to change the video modes.
+Default: the VidMode extension is enabled.
+.TP 7
+.BI "Option \*qAllowNonLocalXvidtune\*q  \*q" boolean \*q
+This allows the xvidtune client (and other clients that use the VidMode
+extension) to connect from another host.
+Default: off.
+.TP 7
+.BI "Option \*qAllowMouseOpenFail\*q  \*q" boolean \*q
+This tells the mousedrv(__drivermansuffix__) and vmmouse(__drivermansuffix__)
+drivers to not report failure if the mouse device can't be opened/initialised.
+It has no effect on the evdev(__drivermansuffix__) or other drivers.
+Default: false.
+.TP 7
+.BI "Option \*qVTSysReq\*q  \*q" boolean \*q
+enables the SYSV\-style VT switch sequence for non\-SYSV systems
+which support VT switching.
+This sequence is
+.B Alt\-SysRq
+followed by a function key
+.RB ( Fn ).
+This prevents the __xservername__ server trapping the
+keys used for the default VT switch sequence, which means that clients can
+access them.
+Default: off.
+.TP 7
+.BI "Option \*qBlankTime\*q  \*q" time \*q
+sets the inactivity timeout for the
+.B blank
+phase of the screensaver.
+.I time
+is in minutes.
+This is equivalent to the __xservername__ server's
+.B \-s
+flag, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+.TP 7
+.BI "Option \*qStandbyTime\*q  \*q" time \*q
+sets the inactivity timeout for the
+.B standby
+phase of DPMS mode.
+.I time
+is in minutes, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+This is only suitable for VESA DPMS compatible monitors, and may not be
+supported by all video drivers.
+It is only enabled for screens that have the
+.B \*qDPMS\*q
+option set (see the MONITOR section below).
+.TP 7
+.BI "Option \*qSuspendTime\*q  \*q" time \*q
+sets the inactivity timeout for the
+.B suspend
+phase of DPMS mode.
+.I time
+is in minutes, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+This is only suitable for VESA DPMS compatible monitors, and may not be
+supported by all video drivers.
+It is only enabled for screens that have the
+.B \*qDPMS\*q
+option set (see the MONITOR section below).
+.TP 7
+.BI "Option \*qOffTime\*q  \*q" time \*q
+sets the inactivity timeout for the
+.B off
+phase of DPMS mode.
+.I time
+is in minutes, and the value can be changed at run\-time with
+.BR xset(__appmansuffix__).
+Default: 10 minutes.
+This is only suitable for VESA DPMS compatible monitors, and may not be
+supported by all video drivers.
+It is only enabled for screens that have the
+.B \*qDPMS\*q
+option set (see the MONITOR section below).
+.TP 7
+.BI "Option \*qPixmap\*q  \*q" bpp \*q
+This sets the pixmap format to use for depth 24.
+Allowed values for
+.I bpp
+are 24 and 32.
+Default: 32 unless driver constraints don't allow this (which is rare).
+Note: some clients don't behave well when this value is set to 24.
+.TP 7
+.BI "Option \*qPC98\*q  \*q" boolean \*q
+Specify that the machine is a Japanese PC\-98 machine.
+This should not be enabled for anything other than the Japanese\-specific
+PC\-98 architecture.
+Default: auto\-detected.
+.TP 7
+.BI "Option \*qNoPM\*q  \*q" boolean \*q
+Disables something to do with power management events.
+Default: PM enabled on platforms that support it.
+.TP 7
+.BI "Option \*qXinerama\*q  \*q" boolean \*q
+enable or disable XINERAMA extension.
+Default is disabled.
+.TP 7
+.BI "Option \*qAIGLX\*q \*q" boolean \*q
+enable or disable AIGLX. AIGLX is enabled by default.
+.TP 7
+.BI "Option \*qDRI2\*q \*q" boolean \*q
+enable or disable DRI2. DRI2 is disabled by default.
+.TP 7
+.BI "Option \*qGlxVisuals\*q \*q" string \*q
+This option controls how many GLX visuals the GLX modules sets up.
+The default value is
+.BR "typical" ,
+which will setup up a typical subset of
+the GLXFBConfigs provided by the driver as GLX visuals.  Other options are
+.BR "minimal" ,
+which will set up the minimal set allowed by the GLX specification and
+.BR "all"
+which will setup GLX visuals for all GLXFBConfigs.
+.TP 7
+.BI "Option \*qUseDefaultFontPath\*q \*q" boolean \*q
+Include the default font path even if other paths are specified in
+xorg.conf. If enabled, other font paths are included as well. Enabled by
+default.
+.TP 7
+.BI "Option \*qIgnoreABI\*q \*q" boolean \*q
+Allow modules built for a different, potentially incompatible version of
+the X server to load. Disabled by default.
+.TP 7
+.BI "Option \*qAutoAddDevices\*q \*q" boolean \*q
+If this option is disabled, then no devices will be added from HAL events.
+Enabled by default.
+.TP 7
+.BI "Option \*qAutoEnableDevices\*q \*q" boolean \*q
+If this option is disabled, then the devices will be added (and the
+DevicePresenceNotify event sent), but not enabled, thus leaving policy up
+to the client.
+Enabled by default.
+.TP 7
+.BI "Option \*qLog\*q \*q" string \*q
+This option controls whether the log is flushed and/or synced to disk after
+each message.
+Possible values are
+.B flush
+or
+.BR sync .
+Unset by default.
+.SH "MODULE SECTION"
+The
+.B Module
+section is used to specify which __xservername__ server modules should be loaded.
+This section is ignored when the __xservername__ server is built in static form.
+The type of modules normally loaded in this section are __xservername__ server
+extension modules.
+Most other module types are loaded automatically when they are needed via
+other mechanisms.
+The
+.B Module
+section is optional, as are all of the entries that may be specified in
+it.
+.PP
+Entries in this section may be in two forms.
+The first and most commonly used form is an entry that uses the
+.B Load
+keyword, as described here:
+.TP 7
+.BI "Load  \*q" modulename \*q
+This instructs the server to load the module called
+.IR modulename .
+The module name given should be the module's standard name, not the
+module file name.
+The standard name is case\-sensitive, and does not include the \(lqlib\(rq
+prefix, or the \(lq.a\(rq, \(lq.o\(rq, or \(lq.so\(rq suffixes.
+.PP
+.RS 7
+Example: the DRI extension module can be loaded with the following entry:
+.PP
+.RS 4
+.B "Load \*qdri\*q"
+.RE
+.RE
+.TP 7
+.BI "Disable  \*q" modulename \*q
+This instructs the server to not load the module called
+.IR modulename .
+Some modules are loaded by default in the server, and this overrides that
+default. If a
+.B Load
+instruction is given for the same module, it overrides the
+.B Disable
+instruction and the module is loaded. The module name given should be the
+module's standard name, not the module file name. As with the
+.B Load
+instruction, the standard name is case-sensitive, and does not include the
+"lib" prefix, or the ".a", ".o", or ".so" suffixes.
+.PP
+The second form of entry is a
+.BR SubSection,
+with the subsection name being the module name, and the contents of the
+.B SubSection
+being
+.B Options
+that are passed to the module when it is loaded.
+.PP
+Example: the extmod module (which contains a miscellaneous group of
+server extensions) can be loaded, with the XFree86\-DGA extension
+disabled by using the following entry:
+.PP
+.RS 4
+.nf
+.B "SubSection \*qextmod\*q"
+.B "   Option  \*qomit XFree86\-DGA\*q"
+.B EndSubSection
+.fi
+.RE
+.PP
+Modules are searched for in each directory specified in the
+.B ModulePath
+search path, and in the drivers, extensions, input, internal, and
+multimedia subdirectories of each of those directories.
+In addition to this, operating system specific subdirectories of all
+the above are searched first if they exist.
+.PP
+To see what extension modules are available, check the extensions
+subdirectory under:
+.PP
+.RS 4
+.nf
+__modulepath__
+.fi
+.RE
+.PP
+The \(lqextmod\(rq, \(lqdbe\(rq, \(lqdri\(rq, \(lqdri2\(rq, \(lqglx\(rq,
+and \(lqrecord\(rq extension modules are loaded automatically, if they
+are present, unless disabled with \*qDisable\*q entries.
+It is recommended
+that at very least the \(lqextmod\(rq extension module be loaded.
+If it isn't, some commonly used server extensions (like the SHAPE
+extension) will not be available.
+.SH "EXTENSIONS SECTION"
+The
+.B Extensions
+section is used to specify which X11 protocol extensions should be enabled
+or disabled.
+The
+.B Extensions
+section is optional, as are all of the entries that may be specified in
+it.
+.PP
+Entries in this section are listed as Option statements with the name of
+the extension as the first argument, and a boolean value as the second.
+The extension name is case\-sensitive, and matches the form shown in the output
+of \*qXorg -extension ?\*q.
+.PP
+.RS 7
+Example: the MIT-SHM extension can be disabled with the following entry:
+.PP
+.RS 4
+.nf
+.B "Section \*qExtensions\*q"
+.B "    Option \*qMIT-SHM\*q \*qDisable\*q"
+.B "EndSection"
+.fi
+.RE
+.RE
+.SH "INPUTDEVICE SECTION"
+The config file may have multiple
+.B InputDevice
+sections.
+Recent X servers employ input hotplugging to add input devices, with the HAL
+backend being the default backend for X servers since 1.4. It is usually not
+necessary to provide
+.B InputDevice
+sections in the xorg.conf if hotplugging is enabled.
+.PP
+If hotplugging is disabled, there will normally
+be at least two: one for the core (primary) keyboard
+and one for the core pointer.
+If either of these two is missing, a default configuration for the missing
+ones will be used. In the absence of an explicitly specified core input
+device, the first
+.B InputDevice
+marked as
+.B CorePointer
+(or
+.BR CoreKeyboard )
+is used.
+If there is no match there, the first
+.B InputDevice
+that uses the \(lqmouse\(rq (or \(lqkbd\(rq) driver is used.
+The final fallback is to use built\-in default configurations.
+Currently the default configuration may not work as expected on all platforms.
+.PP
+.B InputDevice
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B  "Section \*qInputDevice\*q"
+.BI "    Identifier \*q" name \*q
+.BI "    Driver     \*q" inputdriver \*q
+.I  "    options"
+.I  "    ..."
+.B  "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+and
+.B Driver
+entries are required in all
+.B InputDevice
+sections.
+All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this input device.
+The
+.B Driver
+entry specifies the name of the driver to use for this input device.
+When using the loadable server, the input driver module
+.RI \*q inputdriver \*q
+will be loaded for each active
+.B InputDevice
+section.
+An
+.B InputDevice
+section is considered active if it is referenced by an active
+.B ServerLayout
+section, if it is referenced by the
+.B \-keyboard
+or
+.B \-pointer
+command line options, or if it is selected implicitly as the core pointer
+or keyboard device in the absence of such explicit references.
+The most commonly used input drivers are
+.BR evdev (__drivermansuffix__)
+on Linux systems, and
+.BR kbd (__drivermansuffix__)
+and
+.BR mousedrv (__drivermansuffix__)
+on other platforms.
+.PP
+.PP
+.B InputDevice
+sections recognise some driver\-independent
+.BR Options ,
+which are described here.
+See the individual input driver manual pages for a description of the
+device\-specific options.
+.TP 7
+.BI "Option \*qAutoServerLayout\*q  \*q" boolean \*q
+Always add the device to the ServerLayout section used by this instance of
+the server. This affects implied layouts as well as explicit layouts
+specified in the configuration and/or on the command line.
+.TP 7
+.BI "Option \*qCorePointer\*q"
+Deprecated, see
+.B Floating
+.TP 7
+.BI "Option \*qCoreKeyboard\*q"
+Deprecated, see
+.B Floating
+.TP 7
+.BI "Option \*qAlwaysCore\*q  \*q" boolean \*q
+Deprecated, see
+.B Floating
+.TP 7
+.BI "Option \*qSendCoreEvents\*q  \*q" boolean \*q
+Deprecated, see
+.B Floating
+
+.TP 7
+.BI "Option \*qFloating\*q  \*q" boolean \*q
+When enabled, the input device is set up floating and does not
+report events through any master device or control a cursor. The device is
+only available to clients using the X Input Extension API. This option is
+disabled by default.
+The options
+.B CorePointer,
+.B CoreKeyboard,
+.B AlwaysCore,
+and
+.B SendCoreEvents,
+are the inverse of option
+.B Floating
+(i.e.
+.B SendCoreEvents \*qon\*q
+is equivalent to
+.B Floating \*qoff\*q
+).
+
+This option controls the startup behavior only, a device
+may be reattached or set floating at runtime.
+.PP
+For pointing devices, the following options control how the pointer
+is accelerated or decelerated with respect to physical device motion. Most of
+these can be adjusted at runtime, see the xinput(1) man page for details. Only
+the most important acceleration options are discussed here.
+.TP 7
+.BI "Option \*qAccelerationProfile\*q  \*q" integer \*q
+Select the profile. In layman's terms, the profile constitutes the "feeling" of
+the acceleration. More formally, it defines how the transfer function (actual
+acceleration as a function of current device velocity and acceleration controls)
+is constructed. This is mainly a matter of personal preference.
+.PP
+.RS 6
+.nf
+.B  " 0      classic (mostly compatible)"
+.B  "-1      none (only constant deceleration is applied)"
+.B  " 1      device-dependent"
+.B  " 2      polynomial (polynomial function)"
+.B  " 3      smooth linear (soft knee, then linear)"
+.B  " 4      simple (normal when slow, otherwise accelerated)"
+.B  " 5      power (power function)"
+.B  " 6      linear (more speed, more acceleration)"
+.B  " 7      limited (like linear, but maxes out at threshold)"
+.fi
+.RE
+.TP 7
+.BI "Option \*qConstantDeceleration\*q  \*q" real \*q
+Makes the pointer go
+.B deceleration
+times slower than normal. Most useful for high-resolution devices.
+.TP 7
+.BI "Option \*qAdaptiveDeceleration\*q  \*q" real \*q
+Allows to actually decelerate the pointer when going slow. At most, it will be
+.B adaptive deceleration
+times slower. Enables precise pointer placement without sacrificing speed.
+.TP 7
+.BI "Option \*qAccelerationScheme\*q  \*q" string \*q
+Selects the scheme, which is the underlying algorithm.
+.PP
+.RS 7
+.nf
+.B  "predictable   default algorithm (behaving more predictable)"
+.B  "lightweight   old acceleration code (as specified in the X protocol spec)"
+.B  "none          no acceleration or deceleration"
+.fi
+.RE
+.TP 7
+.BI "Option \*qAccelerationNumerator\*q  \*q" integer \*q
+.TP 7
+.BI "Option \*qAccelerationDenominator\*q  \*q" integer \*q
+Set numerator and denominator of the acceleration factor. The acceleration
+factor is a rational which, together with threshold, can be used to tweak
+profiles to suit the users needs. The
+.B simple
+and
+.B limited
+profiles use it directly (i.e. they accelerate by the factor), for other
+profiles it should hold that a higher acceleration factor leads to a faster
+pointer. Typically, 1 is unaccelerated and values up to 5 are sensible.
+.TP 7
+.BI "Option \*qAccelerationThreshold\*q  \*q" integer \*q
+Set the threshold, which is roughly the velocity (usually device units per 10
+ms) required for acceleration to become effective. The precise effect varies
+with the profile however.
+
+.SH "INPUTCLASS SECTION"
+The config file may have multiple
+.B InputClass
+sections.
+These sections are optional and are used to provide configuration for a
+class of input devices as they are automatically added. An input device can
+match more than one
+.B InputClass
+section. Each class can override settings from a previous class, so it is
+best to arrange the sections with the most generic matches first.
+.PP
+.B InputClass
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B  "Section \*qInputClass\*q"
+.BI "    Identifier  \*q" name \*q
+.I  "    entries"
+.I  "    ..."
+.I  "    options"
+.I  "    ..."
+.B  "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+entry is required in all
+.B InputClass
+sections.
+All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this input class.
+The
+.B Driver
+entry specifies the name of the driver to use for this input device.
+After all classes have been examined, the
+.RI \*q inputdriver \*q
+module from the first
+.B Driver
+entry will be enabled when using the loadable server.
+.PP
+When an input device is automatically added, its characteristics are
+checked against all
+.B InputClass
+sections. Each section can contain optional entries to narrow the match
+of the class. If none of the optional entries appear, the
+.B InputClass
+section is generic and will match any input device. If more than one of
+these entries appear, they all must match for the configuration to apply.
+.PP
+There are two types of match entries used in
+.B InputClass
+sections. The first allows various tokens to be matched against attributes
+of the device. An entry can be constructed to match attributes from different
+devices by separating arguments with a '|' character. Multiple entries of the
+same type may be supplied to add multiple matching conditions on the same
+attribute. For example:
+.PP
+.RS 4
+.nf
+.B  "Section \*qInputClass\*q"
+.B  "    Identifier   \*qMy Class\*q"
+.B  "    # product string must contain example and
+.B  "    # either gizmo or gadget
+.B  "    MatchProduct \*qexample\*q
+.B  "    MatchProduct \*qgizmo|gadget\*q
+.I  "    ..."
+.B  "EndSection"
+.fi
+.RE
+.TP 7
+.BI "MatchProduct  \*q" matchproduct \*q
+This entry can be used to check if the substring
+.RI \*q matchproduct \*q
+occurs in the device's product name.
+.TP 7
+.BI "MatchVendor  \*q" matchvendor \*q
+This entry can be used to check if the substring
+.RI \*q matchvendor \*q
+occurs in the device's vendor name.
+.TP 7
+.BI "MatchDevicePath \*q" matchdevice \*q
+This entry can be used to check if the device file matches the
+.RI \*q matchdevice \*q
+pathname pattern.
+.TP 7
+.BI "MatchOS \*q" matchos \*q
+This entry can be used to check if the operating system matches the
+case-insensitive
+.RI \*q matchos \*q
+string. This entry is only supported on platforms providing the
+.BR uname (2)
+system call.
+.TP 7
+.BI "MatchPnPID \*q" matchpnp \*q
+The device's Plug and Play (PnP) ID can be checked against the
+.RI \*q matchpnp \*q
+shell wildcard pattern.
+.TP 7
+.BI "MatchUSBID \*q" matchusb \*q
+The device's USB ID can be checked against the
+.RI \*q matchusb \*q
+shell wildcard pattern. The ID is constructed as lowercase hexadecimal numbers
+separated by a ':'. This is the same format as the
+.BR lsusb (8)
+program.
+.TP 7
+.BI "MatchDriver \*q" matchdriver \*q
+Check the case-sensitive string
+.RI \*q matchdriver \*q
+against the currently configured driver of the device. Ordering of sections
+using this entry is important since it will not match unless the driver has
+been set by the config backend or a previous
+.B InputClass
+section.
+.TP 7
+.BI "MatchTag \*q" matchtag \*q
+This entry can be used to check if tags assigned by the config backend
+matches the
+.RI \*q matchtag \*q
+pattern. A match is found if at least one of the tags given in
+.RI \*q matchtag \*q
+matches at least one of the tags assigned by the backend.
+.PP
+The second type of entry is used to match device types. These entries take a
+boolean argument similar to
+.B Option
+entries.
+.TP 7
+.BI "MatchIsKeyboard     \*q" bool \*q
+.TP 7
+.BI "MatchIsPointer      \*q" bool \*q
+.TP 7
+.BI "MatchIsJoystick     \*q" bool \*q
+.TP 7
+.BI "MatchIsTablet       \*q" bool \*q
+.TP 7
+.BI "MatchIsTouchpad     \*q" bool \*q
+.TP 7
+.BI "MatchIsTouchscreen  \*q" bool \*q
+.PP
+When an input device has been matched to the
+.B InputClass
+section, any
+.B Option
+entries are applied to the device. One
+.B InputClass
+specific
+.B Option
+is recognized. See the
+.B InputDevice
+section above for a description of the remaining
+.B Option
+entries.
+.TP 7
+.BI "Option \*qIgnore\*q \*q" boolean \*q
+This optional entry specifies that the device should be ignored entirely,
+and not added to the server. This can be useful when the device is handled
+by another program and no X events should be generated.
+.SH "DEVICE SECTION"
+The config file may have multiple
+.B Device
+sections.
+There must be at least one, for the video card being used.
+.PP
+.B Device
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B  "Section \*qDevice\*q"
+.BI "    Identifier \*q" name \*q
+.BI "    Driver     \*q" driver \*q
+.I  "    entries"
+.I  "    ..."
+.B  "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+and
+.B Driver
+entries are required in all
+.B Device
+sections.  All other entries are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this graphics device.
+The
+.B Driver
+entry specifies the name of the driver to use for this graphics device.
+When using the loadable server, the driver module
+.RI \*q driver \*q
+will be loaded for each active
+.B Device
+section.
+A
+.B Device
+section is considered active if it is referenced by an active
+.B Screen
+section.
+.PP
+.B Device
+sections recognise some driver\-independent entries and
+.BR Options ,
+which are described here.
+Not all drivers make use of these
+driver\-independent entries, and many of those that do don't require them
+to be specified because the information is auto\-detected.
+See the individual graphics driver manual pages for further information
+about this, and for a description of the device\-specific options.
+Note that most of the
+.B Options
+listed here (but not the other entries) may be specified in the
+.B Screen
+section instead of here in the
+.B Device
+section.
+.TP 7
+.BI "BusID  \*q" bus\-id \*q
+This specifies the bus location of the graphics card.
+For PCI/AGP cards,
+the
+.I bus\-id
+string has the form
+.BI PCI: bus : device : function
+(e.g., \(lqPCI:1:0:0\(rq might be appropriate for an AGP card).
+This field is usually optional in single-head configurations when using
+the primary graphics card.
+In multi-head configurations, or when using a secondary graphics card in a
+single-head configuration, this entry is mandatory.
+Its main purpose is to make an unambiguous connection between the device
+section and the hardware it is representing.
+This information can usually be found by running the pciaccess tool
+scanpci.
+.TP 7
+.BI "Screen  " number
+This option is mandatory for cards where a single PCI entity can drive more
+than one display (i.e., multiple CRTCs sharing a single graphics accelerator
+and video memory).
+One
+.B Device
+section is required for each head, and this
+parameter determines which head each of the
+.B Device
+sections applies to.
+The legal values of
+.I number
+range from 0 to one less than the total number of heads per entity.
+Most drivers require that the primary screen (0) be present.
+.TP 7
+.BI "Chipset  \*q" chipset \*q
+This usually optional entry specifies the chipset used on the graphics
+board.
+In most cases this entry is not required because the drivers will probe the
+hardware to determine the chipset type.
+Don't specify it unless the driver-specific documentation recommends that you
+do.
+.TP 7
+.BI "Ramdac  \*q" ramdac\-type \*q
+This optional entry specifies the type of RAMDAC used on the graphics
+board.
+This is only used by a few of the drivers, and in most cases it is not
+required because the drivers will probe the hardware to determine the
+RAMDAC type where possible.
+Don't specify it unless the driver-specific documentation recommends that you
+do.
+.TP 7
+.BI "DacSpeed  " speed
+.TP 7
+.BI "DacSpeed  " "speed\-8 speed\-16 speed\-24 speed\-32"
+This optional entry specifies the RAMDAC speed rating (which is usually
+printed on the RAMDAC chip).
+The speed is in MHz.
+When one value is given, it applies to all framebuffer pixel sizes.
+When multiple values are given, they apply to the framebuffer pixel sizes
+8, 16, 24 and 32 respectively.
+This is not used by many drivers, and only needs to be specified when the
+speed rating of the RAMDAC is different from the defaults built in to
+driver, or when the driver can't auto-detect the correct defaults.
+Don't specify it unless the driver-specific documentation recommends that you
+do.
+.TP 7
+.BI "Clocks  " "clock ..."
+specifies the pixel that are on your graphics board.
+The clocks are in MHz, and may be specified as a floating point number.
+The value is stored internally to the nearest kHz.
+The ordering of the clocks is important.
+It must match the order in which they are selected on the graphics board.
+Multiple
+.B Clocks
+lines may be specified, and each is concatenated to form the list.
+Most drivers do not use this entry, and it is only required for some older
+boards with non-programmable clocks.
+Don't specify this entry unless the driver-specific documentation explicitly
+recommends that you do.
+.TP
+.BI "ClockChip  \*q" clockchip\-type \*q
+This optional entry is used to specify the clock chip type on graphics
+boards which have a programmable clock generator.
+Only a few __xservername__ drivers support programmable clock chips.
+For details, see the appropriate driver manual page.
+.TP 7
+.BI "VideoRam  " "mem"
+This optional entry specifies the amount of video ram that is installed
+on the graphics board.
+This is measured in kBytes.
+In most cases this is not required because the __xservername__ server probes
+the graphics board to determine this quantity.
+The driver-specific documentation should indicate when it might be needed.
+.TP 7
+.BI "BiosBase  " "baseaddress"
+This optional entry specifies the base address of the video BIOS for
+the VGA board.
+This address is normally auto-detected, and should only be specified if the
+driver-specific documentation recommends it.
+.TP 7
+.BI "MemBase  " "baseaddress"
+This optional entry specifies the memory base address of a graphics
+board's linear frame buffer.
+This entry is not used by many drivers, and it should only be specified if
+the driver-specific documentation recommends it.
+.TP 7
+.BI "IOBase  " "baseaddress"
+This optional entry specifies the IO base address.
+This entry is not used by many drivers, and it should only be specified if
+the driver-specific documentation recommends it.
+.TP 7
+.BI "ChipID  " "id"
+This optional entry specifies a numerical ID representing the chip type.
+For PCI cards, it is usually the device ID.
+This can be used to override the auto-detection, but that should only be done
+when the driver-specific documentation recommends it.
+.TP 7
+.BI "ChipRev  " "rev"
+This optional entry specifies the chip revision number.
+This can be used to override the auto-detection, but that should only be done
+when the driver-specific documentation recommends it.
+.TP 7
+.BI "TextClockFreq  " "freq"
+This optional entry specifies the pixel clock frequency that is used
+for the regular text mode.
+The frequency is specified in MHz.
+This is rarely used.
+.TP 7
+.BI "Option \*qModeDebug\*q \*q" boolean \*q
+Enable printing of additional debugging information about modesetting to
+the server log.
+.ig
+.TP 7
+This optional entry allows an IRQ number to be specified.
+..
+.TP 7
+.B Options
+Option flags may be specified in the
+.B Device
+sections.
+These include driver\-specific options and driver\-independent options.
+The former are described in the driver\-specific documentation.
+Some of the latter are described below in the section about the
+.B Screen
+section, and they may also be included here.
+
+.SH "VIDEOADAPTOR SECTION"
+Nobody wants to say how this works.
+Maybe nobody knows ...
+
+.SH "MONITOR SECTION"
+The config file may have multiple
+.B Monitor
+sections.
+There should normally be at least one, for the monitor being used,
+but a default configuration will be created when one isn't specified.
+.PP
+.B Monitor
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B  "Section \*qMonitor\*q"
+.BI "    Identifier \*q" name \*q
+.I  "    entries"
+.I  "    ..."
+.B  "EndSection"
+.fi
+.RE
+.PP
+The only mandatory entry in a
+.B Monitor
+section is the
+.B Identifier
+entry.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this monitor.
+The
+.B Monitor
+section may be used to provide information about the specifications of the
+monitor, monitor-specific
+.BR Options ,
+and information about the video modes to use with the monitor.
+.PP
+With RandR 1.2-enabled drivers, monitor sections may be tied to specific
+outputs of the video card.  Using the name of the output defined by the video
+driver plus the identifier of a monitor section, one associates a monitor
+section with an output by adding an option to the Device section in the
+following format:
+
+.B Option \*qMonitor-outputname\*q \*qmonitorsection\*q
+
+(for example,
+.B Option \*qMonitor-VGA\*q \*qVGA monitor\*q
+for a VGA output)
+.PP
+In the absence of specific association of monitor sections to outputs, if a
+monitor section is present the server will associate it with an output to
+preserve compatibility for previous single-head configurations.
+.PP
+Specifying video modes is optional because the server will use the DDC or other
+information provided by the monitor to automatically configure the list of
+modes available.
+When modes are specified explicitly in the
+.B Monitor
+section (with the
+.BR Modes ,
+.BR ModeLine ,
+or
+.B UseModes
+keywords), built-in modes with the same names are not included.
+Built-in modes with different names are, however, still implicitly included,
+when they meet the requirements of the monitor.
+.PP
+The entries that may be used in
+.B Monitor
+sections are described below.
+.TP 7
+.BI "VendorName  \*q" vendor \*q
+This optional entry specifies the monitor's manufacturer.
+.TP 7
+.BI "ModelName  \*q" model \*q
+This optional entry specifies the monitor's model.
+.TP 7
+.BI "HorizSync  " "horizsync\-range"
+gives the range(s) of horizontal sync frequencies supported by the
+monitor.
+.I horizsync\-range
+may be a comma separated list of either discrete values or ranges of
+values.
+A range of values is two values separated by a dash.
+By default the values are in units of kHz.
+They may be specified in MHz or Hz
+if
+.B MHz
+or
+.B Hz
+is added to the end of the line.
+The data given here is used by the __xservername__ server to determine if video
+modes are within the specifications of the monitor.
+This information should be available in the monitor's handbook.
+If this entry is omitted, a default range of 28\-33kHz is used.
+.TP 7
+.BI "VertRefresh  " "vertrefresh\-range"
+gives the range(s) of vertical refresh frequencies supported by the
+monitor.
+.I vertrefresh\-range
+may be a comma separated list of either discrete values or ranges of
+values.
+A range of values is two values separated by a dash.
+By default the values are in units of Hz.
+They may be specified in MHz or kHz
+if
+.B MHz
+or
+.B kHz
+is added to the end of the line.
+The data given here is used by the __xservername__ server to determine if video
+modes are within the specifications of the monitor.
+This information should be available in the monitor's handbook.
+If this entry is omitted, a default range of 43\-72Hz is used.
+.TP 7
+.BI "DisplaySize  " "width height"
+This optional entry gives the width and height, in millimetres, of the
+picture area of the monitor.
+If given this is used to calculate the horizontal and vertical pitch (DPI) of
+the screen.
+.TP 7
+.BI "Gamma  " "gamma\-value"
+.TP 7
+.BI "Gamma  " "red\-gamma green\-gamma blue\-gamma"
+This is an optional entry that can be used to specify the gamma correction
+for the monitor.
+It may be specified as either a single value or as three separate RGB values.
+The values should be in the range 0.1 to 10.0, and the default is 1.0.
+Not all drivers are capable of using this information.
+.TP 7
+.BI "UseModes  \*q" modesection\-id \*q
+Include the set of modes listed in the
+.B Modes
+section called
+.IR modesection\-id.
+This makes all of the modes defined in that section available for use by
+this monitor.
+.TP 7
+.BI "Mode  \*q" name \*q
+This is an optional multi-line entry that can be used to provide
+definitions for video modes for the monitor.
+In most cases this isn't necessary because the built-in set of VESA standard
+modes will be sufficient.
+The
+.B Mode
+keyword indicates the start of a multi-line video mode description.
+The mode description is terminated with the
+.B EndMode
+keyword.
+The mode description consists of the following entries:
+.RS 7
+.TP 4
+.BI "DotClock  " clock
+is the dot (pixel) clock rate to be used for the mode.
+.TP 4
+.BI "HTimings  " "hdisp hsyncstart hsyncend htotal"
+specifies the horizontal timings for the mode.
+.TP 4
+.BI "VTimings  " "vdisp vsyncstart vsyncend vtotal"
+specifies the vertical timings for the mode.
+.TP 4
+.BI "Flags  \*q" flag \*q " ..."
+specifies an optional set of mode flags, each of which is a separate
+string in double quotes.
+.B \*qInterlace\*q
+indicates that the mode is interlaced.
+.B \*qDoubleScan\*q
+indicates a mode where each scanline is doubled.
+.B \*q+HSync\*q
+and
+.B \*q\-HSync\*q
+can be used to select the polarity of the HSync signal.
+.B \*q+VSync\*q
+and
+.B \*q\-VSync\*q
+can be used to select the polarity of the VSync signal.
+.B \*qComposite\*q
+can be used to specify composite sync on hardware where this is supported.
+Additionally, on some hardware,
+.B \*q+CSync\*q
+and
+.B \*q\-CSync\*q
+may be used to select the composite sync polarity.
+.TP 4
+.BI "HSkew  " hskew
+specifies the number of pixels (towards the right edge of the screen) by
+which the display enable signal is to be skewed.
+Not all drivers use this information.
+This option might become necessary to override the default value supplied
+by the server (if any).
+\(lqRoving\(rq horizontal lines indicate this value needs to be increased.
+If the last few pixels on a scan line appear on the left of the screen,
+this value should be decreased.
+.TP 4
+.BI "VScan  " vscan
+specifies the number of times each scanline is painted on the screen.
+Not all drivers use this information.
+Values less than 1 are treated as 1, which is the default.
+Generally, the
+.B \*qDoubleScan\*q
+.B Flag
+mentioned above doubles this value.
+.RE
+.TP 7
+.BI "ModeLine  \*q" name \*q " mode\-description"
+This entry is a more compact version of the
+.B Mode
+entry, and it also can be used to specify video modes for the monitor.
+is a single line format for specifying video modes.
+In most cases this isn't necessary because the built\-in set of VESA
+standard modes will be sufficient.
+.PP
+.RS 7
+The
+.I mode\-description
+is in four sections, the first three of which are mandatory.
+The first is the dot (pixel) clock.
+This is a single number specifying the pixel clock rate for the mode in
+MHz.
+The second section is a list of four numbers specifying the horizontal
+timings.
+These numbers are the
+.IR hdisp ,
+.IR hsyncstart ,
+.IR hsyncend ,
+and
+.I htotal
+values.
+The third section is a list of four numbers specifying the vertical
+timings.
+These numbers are the
+.IR vdisp ,
+.IR vsyncstart ,
+.IR vsyncend ,
+and
+.I vtotal
+values.
+The final section is a list of flags specifying other characteristics of
+the mode.
+.B Interlace
+indicates that the mode is interlaced.
+.B DoubleScan
+indicates a mode where each scanline is doubled.
+.B +HSync
+and
+.B \-HSync
+can be used to select the polarity of the HSync signal.
+.B +VSync
+and
+.B \-VSync
+can be used to select the polarity of the VSync signal.
+.B Composite
+can be used to specify composite sync on hardware where this is supported.
+Additionally, on some hardware,
+.B +CSync
+and
+.B \-CSync
+may be used to select the composite sync polarity.
+The
+.B HSkew
+and
+.B VScan
+options mentioned above in the
+.B Modes
+entry description can also be used here.
+.RE
+.TP 7
+.BI "Option " "\*qDPMS\*q  " \*qbool\*q
+This option controls whether the server should enable the DPMS extension
+for power management for this screen.  The default is to enable the
+extension.
+.TP 7
+.BI "Option " "\*qSyncOnGreen\*q  " \*qbool\*q
+This option controls whether the video card should drive the sync signal
+on the green color pin.  Not all cards support this option, and most
+monitors do not require it.  The default is off.
+.TP 7
+.BI "Option " "\*qPrimary\*q  " \*qbool\*q
+This optional entry specifies that the monitor should be treated as the primary
+monitor. (RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qPreferredMode\*q  " \*qstring\*q
+This optional entry specifies a mode to be marked as the preferred initial mode
+of the monitor.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qPosition\*q  " "\*qx y\*q"
+This optional entry specifies the position of the monitor within the X
+screen.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qLeftOf\*q  " \*qoutput\*q
+This optional entry specifies that the monitor should be positioned to the
+left of the output (not monitor) of the given name.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qRightOf\*q  " \*qoutput\*q
+This optional entry specifies that the monitor should be positioned to the
+right of the output (not monitor) of the given name.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qAbove\*q  " \*qoutput\*q
+This optional entry specifies that the monitor should be positioned above the
+output (not monitor) of the given name.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qBelow\*q  " \*qoutput\*q
+This optional entry specifies that the monitor should be positioned below the
+output (not monitor) of the given name.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qEnable\*q  " \*qbool\*q
+This optional entry specifies whether the monitor should be turned on
+at startup.  By default, the server will attempt to enable all connected
+monitors.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qDefaultModes\*q  " \*qbool\*q
+This optional entry specifies whether the server should add supported default
+modes to the list of modes offered on this monitor. By default, the server
+will add default modes; you should only disable this if you can guarantee
+that EDID will be available at all times, or if you have added custom modelines
+which the server can use.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qMinClock\*q  " \*qfrequency\*q
+This optional entry specifies the minimum dot clock, in kHz, that is supported
+by the monitor.
+.TP 7
+.BI "Option " "\*qMaxClock\*q  " \*qfrequency\*q
+This optional entry specifies the maximum dot clock, in kHz, that is supported
+by the monitor.
+.TP 7
+.BI "Option " "\*qIgnore\*q  " \*qbool\*q
+This optional entry specifies that the monitor should be ignored entirely,
+and not reported through RandR.  This is useful if the hardware reports the
+presence of outputs that don't exist.
+(RandR 1.2-supporting drivers only)
+.TP 7
+.BI "Option " "\*qRotate\*q  " \*qrotation\*q
+This optional entry specifies the initial rotation of the given monitor.
+Valid values for rotation are \*qnormal\*q, \*qleft\*q, \*qright\*q, and
+\*qinverted\*q.
+(RandR 1.2-supporting drivers only)
+
+.SH "MODES SECTION"
+The config file may have multiple
+.B Modes
+sections, or none.
+These sections provide a way of defining sets of video modes independently
+of the
+.B Monitor
+sections.
+.B Monitor
+sections may include the definitions provided in these sections by
+using the
+.B UseModes
+keyword.
+In most cases the
+.B Modes
+sections are not necessary because the built\-in set of VESA standard modes
+will be sufficient.
+.PP
+.B Modes
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B  "Section \*qModes\*q"
+.BI "    Identifier \*q" name \*q
+.I  "    entries"
+.I  "    ..."
+.B  "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+entry specifies the unique name for this set of mode descriptions.
+The other entries permitted in
+.B Modes
+sections are the
+.B Mode
+and
+.B ModeLine
+entries that are described above in the
+.B Monitor
+section.
+.SH "SCREEN SECTION"
+The config file may have multiple
+.B Screen
+sections.
+There must be at least one, for the \(lqscreen\(rq being used.
+A \(lqscreen\(rq represents the binding of a graphics device
+.RB ( Device
+section) and a monitor
+.RB ( Monitor
+section).
+A
+.B Screen
+section is considered \(lqactive\(rq if it is referenced by an active
+.B ServerLayout
+section or by the
+.B \-screen
+command line option.
+If neither of those is present, the first
+.B Screen
+section found in the config file is considered the active one.
+.PP
+.B Screen
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B  "Section \*qScreen\*q"
+.BI "    Identifier \*q" name \*q
+.BI "    Device     \*q" devid \*q
+.BI "    Monitor    \*q" monid \*q
+.I  "    entries"
+.I  "    ..."
+.BI "    SubSection \*qDisplay\*q"
+.I  "       entries"
+.I  "       ...
+.B  "    EndSubSection"
+.I  "    ..."
+.B  "EndSection"
+.fi
+.RE
+.PP
+The
+.B Identifier
+and
+.B Device
+entries are mandatory.
+All others are optional.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this screen.
+The
+.B Screen
+section provides information specific to the whole screen, including
+screen\-specific
+.BR Options .
+In multi\-head configurations, there will be multiple active
+.B Screen
+sections, one for each head.
+The entries available
+for this section are:
+.TP 7
+.BI "Device  \*q" device\-id \*q
+This mandatory entry specifies the
+.B Device
+section to be used for this screen.
+This is what ties a specific graphics card to a screen.
+The
+.I device\-id
+must match the
+.B Identifier
+of a
+.B Device
+section in the config file.
+.TP 7
+.BI "Monitor  \*q" monitor\-id \*q
+specifies which monitor description is to be used for this screen.
+If a
+.B Monitor
+name is not specified, a default configuration is used.
+Currently the default configuration may not function as expected on all
+platforms.
+.TP 7
+.BI "VideoAdaptor  \*q" xv\-id \*q
+specifies an optional Xv video adaptor description to be used with this
+screen.
+.TP 7
+.BI "DefaultDepth  " depth
+specifies which color depth the server should use by default.
+The
+.B \-depth
+command line option can be used to override this.
+If neither is specified, the default depth is driver\-specific, but in most
+cases is 8.
+.TP 7
+.BI "DefaultFbBpp  " bpp
+specifies which framebuffer layout to use by default.
+The
+.B \-fbbpp
+command line option can be used to override this.
+In most cases the driver will chose the best default value for this.
+The only case where there is even a choice in this value is for depth 24,
+where some hardware supports both a packed 24 bit framebuffer layout and a
+sparse 32 bit framebuffer layout.
+.TP 7
+.B Options
+Various
+.B Option
+flags may be specified in the
+.B Screen
+section.
+Some are driver\-specific and are described in the driver documentation.
+Others are driver\-independent, and will eventually be described here.
+.\" XXX These should really be in an xaa man page.
+.TP 7
+.BI "Option \*qAccel\*q"
+Enables XAA (X Acceleration Architecture), a mechanism that makes video cards'
+2D hardware acceleration available to the  __xservername__ server.
+This option is on by default, but it may be necessary to turn it off if
+there are bugs in the driver.
+There are many options to disable specific accelerated operations, listed
+below.
+Note that disabling an operation will have no effect if the operation is
+not accelerated (whether due to lack of support in the hardware or in the
+driver).
+.TP 7
+.BI "Option \*qInitPrimary\*q \*q" boolean \*q
+Use the Int10 module to initialize the primary graphics card.
+Normally, only secondary cards are soft-booted using the Int10 module, as the
+primary card has already been initialized by the BIOS at boot time.
+Default: false.
+.TP 7
+.BI "Option \*qNoInt10\*q \*q" boolean \*q
+Disables the Int10 module, a module that uses the int10 call to the BIOS
+of the graphics card to initialize it.
+Default: false.
+.TP 7
+.BI "Option \*qNoMTRR\*q"
+Disables MTRR (Memory Type Range Register) support, a feature of modern
+processors which can improve video performance by a factor of up to 2.5.
+Some hardware has buggy MTRR support, and some video drivers have been
+known to exhibit problems when MTRR's are used.
+.TP 7
+.BI "Option \*qXaaNoCPUToScreenColorExpandFill\*q"
+Disables accelerated rectangular expansion blits from source patterns
+stored in system memory (using a memory\-mapped aperture).
+.TP 7
+.BI "Option \*qXaaNoColor8x8PatternFillRect\*q"
+Disables accelerated fills of a rectangular region with a full\-color
+pattern.
+.TP 7
+.BI "Option \*qXaaNoColor8x8PatternFillTrap\*q"
+Disables accelerated fills of a trapezoidal region with a full\-color
+pattern.
+.TP 7
+.BI "Option \*qXaaNoDashedBresenhamLine\*q"
+Disables accelerated dashed Bresenham line draws.
+.TP 7
+.BI "Option \*qXaaNoDashedTwoPointLine\*q"
+Disables accelerated dashed line draws between two arbitrary points.
+.TP 7
+.BI "Option \*qXaaNoImageWriteRect\*q"
+Disables accelerated transfers of full\-color rectangular patterns from
+system memory to video memory (using a memory\-mapped aperture).
+.TP 7
+.BI "Option \*qXaaNoMono8x8PatternFillRect\*q"
+Disables accelerated fills of a rectangular region with a monochrome
+pattern.
+.TP 7
+.BI "Option \*qXaaNoMono8x8PatternFillTrap\*q"
+Disables accelerated fills of a trapezoidal region with a monochrome
+pattern.
+.TP 7
+.BI "Option \*qXaaNoOffscreenPixmaps\*q"
+Disables accelerated draws into pixmaps stored in offscreen video memory.
+.TP 7
+.BI "Option \*qXaaNoPixmapCache\*q"
+Disables caching of patterns in offscreen video memory.
+.TP 7
+.BI "Option \*qXaaNoScanlineCPUToScreenColorExpandFill\*q"
+Disables accelerated rectangular expansion blits from source patterns
+stored in system memory (one scan line at a time).
+.TP 7
+.BI "Option \*qXaaNoScanlineImageWriteRect\*q"
+Disables accelerated transfers of full\-color rectangular patterns from
+system memory to video memory (one scan line at a time).
+.TP 7
+.BI "Option \*qXaaNoScreenToScreenColorExpandFill\*q"
+Disables accelerated rectangular expansion blits from source patterns
+stored in offscreen video memory.
+.TP 7
+.BI "Option \*qXaaNoScreenToScreenCopy\*q"
+Disables accelerated copies of rectangular regions from one part of
+video memory to another part of video memory.
+.TP 7
+.BI "Option \*qXaaNoSolidBresenhamLine\*q"
+Disables accelerated solid Bresenham line draws.
+.TP 7
+.BI "Option \*qXaaNoSolidFillRect\*q"
+Disables accelerated solid\-color fills of rectangles.
+.TP 7
+.BI "Option \*qXaaNoSolidFillTrap\*q"
+Disables accelerated solid\-color fills of Bresenham trapezoids.
+.TP 7
+.BI "Option \*qXaaNoSolidHorVertLine\*q"
+Disables accelerated solid horizontal and vertical line draws.
+.TP 7
+.BI "Option \*qXaaNoSolidTwoPointLine\*q"
+Disables accelerated solid line draws between two arbitrary points.
+.PP
+Each
+.B Screen
+section may optionally contain one or more
+.B Display
+subsections.
+Those subsections provide depth/fbbpp specific configuration information,
+and the one chosen depends on the depth and/or fbbpp that is being used for
+the screen.
+The
+.B Display
+subsection format is described in the section below.
+
+.SH "DISPLAY SUBSECTION"
+Each
+.B Screen
+section may have multiple
+.B Display
+subsections.
+The \(lqactive\(rq
+.B Display
+subsection is the first that matches the depth and/or fbbpp values being
+used, or failing that, the first that has neither a depth or fbbpp value
+specified.
+The
+.B Display
+subsections are optional.
+When there isn't one that matches the depth and/or fbbpp values being used,
+all the parameters that can be specified here fall back to their defaults.
+.PP
+.B Display
+subsections have the following format:
+.PP
+.RS 4
+.nf
+.B  "    SubSection \*qDisplay\*q"
+.BI "        Depth  " depth
+.I  "        entries"
+.I  "        ..."
+.B  "    EndSubSection"
+.fi
+.RE
+.TP 7
+.BI "Depth  " depth
+This entry specifies what colour depth the
+.B Display
+subsection is to be used for.
+This entry is usually specified, but it may be omitted to create a match\-all
+.B Display
+subsection or when wishing to match only against the
+.B FbBpp
+parameter.
+The range of
+.I depth
+values that are allowed depends on the driver.
+Most drivers support 8, 15, 16 and 24.
+Some also support 1 and/or 4, and some may support other values (like 30).
+Note:
+.I depth
+means the number of bits in a pixel that are actually used to determine
+the pixel colour.
+32 is not a valid
+.I depth
+value.
+Most hardware that uses 32 bits per pixel only uses 24 of them to hold the
+colour information, which means that the colour depth is 24, not 32.
+.TP 7
+.BI "FbBpp  " bpp
+This entry specifies the framebuffer format this
+.B Display
+subsection is to be used for.
+This entry is only needed when providing depth 24 configurations that allow
+a choice between a 24 bpp packed framebuffer format and a 32bpp sparse
+framebuffer format.
+In most cases this entry should not be used.
+.TP 7
+.BI "Weight  " "red\-weight green\-weight blue\-weight"
+This optional entry specifies the relative RGB weighting to be used
+for a screen is being used at depth 16 for drivers that allow multiple
+formats.
+This may also be specified from the command line with the
+.B \-weight
+option (see
+.BR __xservername__(__appmansuffix__)).
+.TP 7
+.BI "Virtual  " "xdim ydim"
+This optional entry specifies the virtual screen resolution to be used.
+.I xdim
+must be a multiple of either 8 or 16 for most drivers, and a multiple
+of 32 when running in monochrome mode.
+The given value will be rounded down if this is not the case.
+Video modes which are too large for the specified virtual size will be
+rejected.
+If this entry is not present, the virtual screen resolution will be set to
+accommodate all the valid video modes given in the
+.B Modes
+entry.
+Some drivers/hardware combinations do not support virtual screens.
+Refer to the appropriate driver\-specific documentation for details.
+.TP 7
+.BI "ViewPort  " "x0 y0"
+This optional entry sets the upper left corner of the initial display.
+This is only relevant when the virtual screen resolution is different
+from the resolution of the initial video mode.
+If this entry is not given, then the initial display will be centered in
+the virtual display area.
+.TP 7
+.BI "Modes  \*q" mode\-name \*q " ..."
+This optional entry specifies the list of video modes to use.
+Each
+.I mode\-name
+specified must be in double quotes.
+They must correspond to those specified or referenced in the appropriate
+.B Monitor
+section (including implicitly referenced built\-in VESA standard modes).
+The server will delete modes from this list which don't satisfy various
+requirements.
+The first valid mode in this list will be the default display mode for
+startup.
+The list of valid modes is converted internally into a circular list.
+It is possible to switch to the next mode with
+.B Ctrl+Alt+Keypad\-Plus
+and to the previous mode with
+.BR Ctrl+Alt+Keypad\-Minus .
+When this entry is omitted, the valid modes referenced by the appropriate
+.B Monitor
+section will be used.  If the
+.B Monitor
+section contains no modes, then the selection will be taken from the
+built-in VESA standard modes.
+.TP 7
+.BI "Visual  \*q" visual\-name \*q
+This optional entry sets the default root visual type.
+This may also be specified from the command line (see the
+.BR Xserver(__appmansuffix__)
+man page).
+The visual types available for depth 8 are (default is
+.BR PseudoColor ):
+.PP
+.RS 11
+.nf
+.B StaticGray
+.B GrayScale
+.B StaticColor
+.B PseudoColor
+.B TrueColor
+.B DirectColor
+.fi
+.RE
+.PP
+.RS 7
+The visual type available for the depths 15, 16 and 24 are (default is
+.BR TrueColor ):
+.PP
+.RS 4
+.nf
+.B TrueColor
+.B DirectColor
+.fi
+.RE
+.PP
+Not all drivers support
+.B DirectColor
+at these depths.
+.PP
+The visual types available for the depth 4 are (default is
+.BR StaticColor ):
+.PP
+.RS 4
+.nf
+.B StaticGray
+.B GrayScale
+.B StaticColor
+.B PseudoColor
+.fi
+.RE
+.PP
+The visual type available for the depth 1 (monochrome) is
+.BR StaticGray .
+.RE
+.TP 7
+.BI "Black  " "red green blue"
+This optional entry allows the \(lqblack\(rq colour to be specified.
+This is only supported at depth 1.
+The default is black.
+.TP 7
+.BI "White  " "red green blue"
+This optional entry allows the \(lqwhite\(rq colour to be specified.
+This is only supported at depth 1.
+The default is white.
+.TP 7
+.B Options
+Option flags may be specified in the
+.B Display
+subsections.
+These may include driver\-specific options and driver\-independent options.
+The former are described in the driver\-specific documentation.
+Some of the latter are described above in the section about the
+.B Screen
+section, and they may also be included here.
+.SH "SERVERLAYOUT SECTION"
+The config file may have multiple
+.B ServerLayout
+sections.
+A \(lqserver layout\(rq represents the binding of one or more screens
+.RB ( Screen
+sections) and one or more input devices
+.RB ( InputDevice
+sections) to form a complete configuration.
+In multi\-head configurations, it also specifies the relative layout of the
+heads.
+A
+.B ServerLayout
+section is considered \(lqactive\(rq if it is referenced by the
+.B \-layout
+command line option or by an
+.B "Option \*qDefaultServerLayout\*q"
+entry in the
+.B ServerFlags
+section (the former takes precedence over the latter).
+If those options are not used, the first
+.B ServerLayout
+section found in the config file is considered the active one.
+If no
+.B ServerLayout
+sections are present, the single active screen and two active (core)
+input devices are selected as described in the relevant sections above.
+.PP
+.B ServerLayout
+sections have the following format:
+.PP
+.RS 4
+.nf
+.B  "Section \*qServerLayout\*q"
+.BI "    Identifier   \*q" name \*q
+.BI "    Screen       \*q" screen\-id \*q
+.I  "    ..."
+.BI "    InputDevice  \*q" idev\-id \*q
+.I  "    ..."
+.I  "    options"
+.I  "    ..."
+.B  "EndSection"
+.fi
+.RE
+.PP
+Each
+.B ServerLayout
+section must have an
+.B Identifier
+entry and at least one
+.B Screen
+entry.
+.PP
+The
+.B Identifier
+entry specifies the unique name for this server layout.
+The
+.B ServerLayout
+section provides information specific to the whole session, including
+session\-specific
+.BR Options .
+The
+.B ServerFlags
+options (described above) may be specified here, and ones given here
+override those given in the
+.B ServerFlags
+section.
+.PP
+The entries that may be used in this section are described here.
+.TP 7
+.BI "Screen  " "screen\-num" " \*qscreen\-id\*q " "position\-information"
+One of these entries must be given for each screen being used in
+a session.
+The
+.I screen\-id
+field is mandatory, and specifies the
+.B Screen
+section being referenced.
+The
+.I screen\-num
+field is optional, and may be used to specify the screen number
+in multi\-head configurations.
+When this field is omitted, the screens will be numbered in the order that
+they are listed in.
+The numbering starts from 0, and must be consecutive.
+The
+.I position\-information
+field describes the way multiple screens are positioned.
+There are a number of different ways that this information can be provided:
+.RS 7
+.TP 4
+.I  "x y"
+.TP 4
+.BI "Absolute  " "x y"
+These both specify that the upper left corner's coordinates are
+.RI ( x , y ).
+The
+.B Absolute
+keyword is optional.
+Some older versions of XFree86 (4.2 and earlier) don't recognise the
+.B Absolute
+keyword, so it's safest to just specify the coordinates without it.
+.TP 4
+.BI "RightOf   \*q" screen\-id \*q
+.TP 4
+.BI "LeftOf    \*q" screen\-id \*q
+.TP 4
+.BI "Above     \*q" screen\-id \*q
+.TP 4
+.BI "Below     \*q" screen\-id \*q
+.TP 4
+.BI "Relative  \*q" screen\-id \*q " x y"
+These give the screen's location relative to another screen.
+The first four position the screen immediately to the right, left, above or
+below the other screen.
+When positioning to the right or left, the top edges are aligned.
+When positioning above or below, the left edges are aligned.
+The
+.B Relative
+form specifies the offset of the screen's origin (upper left corner)
+relative to the origin of another screen.
+.RE
+.TP 7
+.BI "InputDevice  \*q" idev\-id "\*q \*q" option \*q " ..."
+One of these entries should be given for each input device being used in
+a session.
+Normally at least two are required, one each for the core pointer and
+keyboard devices.
+If either of those is missing, suitable
+.B InputDevice
+entries are searched for using the method described above in the
+.B INPUTDEVICE
+section.  The
+.I idev\-id
+field is mandatory, and specifies the name of the
+.B InputDevice
+section being referenced.
+Multiple
+.I option
+fields may be specified, each in double quotes.
+The options permitted here are any that may also be given in the
+.B InputDevice
+sections.
+Normally only session\-specific input device options would be used here.
+The most commonly used options are:
+.PP
+.RS 11
+.nf
+.B \*qCorePointer\*q
+.B \*qCoreKeyboard\*q
+.B \*qSendCoreEvents\*q
+.fi
+.RE
+.PP
+.RS 7
+and the first two should normally be used to indicate the core pointer
+and core keyboard devices respectively.
+.RE
+.TP 7
+.B Options
+In addition to the following, any option permitted in the
+.B ServerFlags
+section may also be specified here.
+When the same option appears in both places, the value given here overrides
+the one given in the
+.B ServerFlags
+section.
+.TP 7
+.BI "Option \*qIsolateDevice\*q  \*q" bus\-id \*q
+Restrict device resets to the specified
+.IR bus\-id .
+See the
+.B BusID
+option (described in
+.BR "DEVICE SECTION" ,
+above) for the format of the
+.I bus\-id
+parameter.
+This option overrides
+.BR SingleCard ,
+if specified.
+At present, only PCI devices can be isolated in this manner.
+.TP 7
+.BI "Option \*qSingleCard\*q  \*q" boolean \*q
+As
+.BR IsolateDevice ,
+except that the bus ID of the first device in the layout is used.
+.PP
+Here is an example of a
+.B ServerLayout
+section for a dual headed configuration with two mice:
+.PP
+.RS 4
+.nf
+.B "Section \*qServerLayout\*q"
+.B "    Identifier  \*qLayout 1\*q"
+.B "    Screen      \*qMGA 1\*q"
+.B "    Screen      \*qMGA 2\*q RightOf \*qMGA 1\*q"
+.B "    InputDevice \*qKeyboard 1\*q \*qCoreKeyboard\*q"
+.B "    InputDevice \*qMouse 1\*q    \*qCorePointer\*q"
+.B "    InputDevice \*qMouse 2\*q    \*qSendCoreEvents\*q"
+.B "    Option      \*qBlankTime\*q  \*q5\*q"
+.B "EndSection"
+.fi
+.RE
+.SH "DRI SECTION"
+This optional section is used to provide some information for the
+Direct Rendering Infrastructure.
+Details about the format of this section can be found on-line at
+.IR <http://dri.freedesktop.org/> .
+.SH "VENDOR SECTION"
+The optional
+.B Vendor
+section may be used to provide vendor\-specific configuration information.
+Multiple
+.B Vendor
+sections may be present, and they may contain an
+.B Identifier
+entry and multiple
+.B Option
+flags.
+The data therein is not used in this release.
+.PP
+.SH "SEE ALSO"
+General:
+.BR X (__miscmansuffix__),
+.BR Xserver (__appmansuffix__),
+.BR __xservername__ (__appmansuffix__),
+.BR cvt (__appmansuffix__),
+.BR gtf (__appmansuffix__).
+.PP
+.B "Not all modules or interfaces are available on all platforms."
+.PP
+Display drivers:
+.BR apm (__drivermansuffix__),
+.BR ati (__drivermansuffix__),
+.BR chips (__drivermansuffix__),
+.BR cirrus (__drivermansuffix__),
+.BR cyrix (__drivermansuffix__),
+.BR fbdev (__drivermansuffix__),
+.BR glide (__drivermansuffix__),
+.BR glint (__drivermansuffix__),
+.BR i128 (__drivermansuffix__),
+.BR i740 (__drivermansuffix__),
+.BR imstt (__drivermansuffix__),
+.BR intel (__drivermansuffix__),
+.BR mga (__drivermansuffix__),
+.BR neomagic (__drivermansuffix__),
+.BR nv (__drivermansuffix__),
+.BR openchrome (__drivermansuffix__),
+.BR r128 (__drivermansuffix__),
+.BR radeon (__drivermansuffix__),
+.BR rendition (__drivermansuffix__),
+.BR savage (__drivermansuffix__),
+.BR s3virge (__drivermansuffix__),
+.BR siliconmotion (__drivermansuffix__),
+.BR sis (__drivermansuffix__),
+.BR sisusb (__drivermansuffix__),
+.BR sunbw2 (__drivermansuffix__),
+.BR suncg14 (__drivermansuffix__),
+.BR suncg3 (__drivermansuffix__),
+.BR suncg6 (__drivermansuffix__),
+.BR sunffb (__drivermansuffix__),
+.BR sunleo (__drivermansuffix__),
+.BR suntcx (__drivermansuffix__),
+.BR tdfx (__drivermansuffix__),
+.\" .BR tga (__drivermansuffix__),
+.BR trident (__drivermansuffix__),
+.BR tseng (__drivermansuffix__),
+.BR vesa (__drivermansuffix__),
+.BR vmware (__drivermansuffix__),
+.BR voodoo (__drivermansuffix__),
+.BR wsfb (__drivermansuffix__),
+.BR xgi (__drivermansuffix__),
+.BR xgixp (__drivermansuffix__).
+.PP
+Input drivers:
+.BR acecad (__drivermansuffix__),
+.BR citron (__drivermansuffix__),
+.BR elographics (__drivermansuffix__),
+.BR evdev (__drivermansuffix__),
+.BR fpit (__drivermansuffix__),
+.BR joystick (__drivermansuffix__),
+.BR kbd (__drivermansuffix__),
+.BR mousedrv (__drivermansuffix__),
+.BR mutouch (__drivermansuffix__),
+.BR penmount (__drivermansuffix__),
+.BR synaptics (__drivermansuffix__),
+.BR vmmouse (__drivermansuffix__),
+.BR void (__drivermansuffix__),
+.BR wacom (__drivermansuffix__).
+.PP
+Other modules and interfaces:
+.BR exa (__drivermansuffix__),
+.BR fbdevhw (__drivermansuffix__),
+.\" .BR shadowfb (__drivermansuffix__),
+.BR v4l (__drivermansuffix__).
+.br
+.SH AUTHORS
+This manual page was largely rewritten by David Dawes
+.IR <dawes@xfree86.org> .
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c
index 86f038aa1..1f43ab9a6 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.c
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c
@@ -1,3242 +1,3237 @@
-/*
- * Copyright © 2006 Keith Packard
- * Copyright © 2008 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include "xf86Crtc.h"
-#include "xf86Modes.h"
-#include "xf86Priv.h"
-#include "xf86RandR12.h"
-#include "X11/extensions/render.h"
-#include "X11/extensions/dpmsconst.h"
-#include "X11/Xatom.h"
-#include "picturestr.h"
-
-#include "xf86xv.h"
-
-#define NO_OUTPUT_DEFAULT_WIDTH 1024
-#define NO_OUTPUT_DEFAULT_HEIGHT 768
-/*
- * Initialize xf86CrtcConfig structure
- */
-
-int xf86CrtcConfigPrivateIndex = -1;
-
-void
-xf86CrtcConfigInit (ScrnInfoPtr scrn,
-		    const xf86CrtcConfigFuncsRec *funcs)
-{
-    xf86CrtcConfigPtr	config;
-    
-    if (xf86CrtcConfigPrivateIndex == -1)
-	xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
-    config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
-
-    config->funcs = funcs;
-
-    scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
-}
- 
-void
-xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
-		      int minWidth, int minHeight,
-		      int maxWidth, int maxHeight)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-
-    config->minWidth = minWidth;
-    config->minHeight = minHeight;
-    config->maxWidth = maxWidth;
-    config->maxHeight = maxHeight;
-}
-
-/*
- * Crtc functions
- */
-xf86CrtcPtr
-xf86CrtcCreate (ScrnInfoPtr		scrn,
-		const xf86CrtcFuncsRec	*funcs)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86CrtcPtr		crtc, *crtcs;
-
-    crtc = calloc(sizeof (xf86CrtcRec), 1);
-    if (!crtc)
-	return NULL;
-    crtc->version = XF86_CRTC_VERSION;
-    crtc->scrn = scrn;
-    crtc->funcs = funcs;
-#ifdef RANDR_12_INTERFACE
-    crtc->randr_crtc = NULL;
-#endif
-    crtc->rotation = RR_Rotate_0;
-    crtc->desiredRotation = RR_Rotate_0;
-    pixman_transform_init_identity (&crtc->crtc_to_framebuffer);
-    pixman_f_transform_init_identity (&crtc->f_crtc_to_framebuffer);
-    pixman_f_transform_init_identity (&crtc->f_framebuffer_to_crtc);
-    crtc->filter = NULL;
-    crtc->params = NULL;
-    crtc->nparams = 0;
-    crtc->filter_width = 0;
-    crtc->filter_height = 0;
-    crtc->transform_in_use = FALSE;
-    crtc->transformPresent = FALSE;
-    crtc->desiredTransformPresent = FALSE;
-    memset (&crtc->bounds, '\0', sizeof (crtc->bounds));
-
-    /* Preallocate gamma at a sensible size. */
-    crtc->gamma_size = 256;
-    crtc->gamma_red = malloc(3 * crtc->gamma_size * sizeof (CARD16));
-    if (!crtc->gamma_red) {
-	free(crtc);
-	return NULL;
-    }
-    crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
-    crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
-
-    if (xf86_config->crtc)
-	crtcs = realloc(xf86_config->crtc,
-			  (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
-    else
-	crtcs = malloc((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
-    if (!crtcs)
-    {
-	free(crtc);
-	return NULL;
-    }
-    xf86_config->crtc = crtcs;
-    xf86_config->crtc[xf86_config->num_crtc++] = crtc;
-    return crtc;
-}
-
-void
-xf86CrtcDestroy (xf86CrtcPtr crtc)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
-    int			c;
-    
-    (*crtc->funcs->destroy) (crtc);
-    for (c = 0; c < xf86_config->num_crtc; c++)
-	if (xf86_config->crtc[c] == crtc)
-	{
-	    memmove (&xf86_config->crtc[c],
-		     &xf86_config->crtc[c+1],
-		     ((xf86_config->num_crtc - (c + 1)) * sizeof(void*)));
-	    xf86_config->num_crtc--;
-	    break;
-	}
-    free(crtc->params);
-    free(crtc->gamma_red);
-    free(crtc);
-}
-
-
-/**
- * Return whether any outputs are connected to the specified pipe
- */
-
-Bool
-xf86CrtcInUse (xf86CrtcPtr crtc)
-{
-    ScrnInfoPtr		pScrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int			o;
-    
-    for (o = 0; o < xf86_config->num_output; o++)
-	if (xf86_config->output[o]->crtc == crtc)
-	    return TRUE;
-    return FALSE;
-}
-
-void
-xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen)
-{
-    int			subpixel_order = SubPixelUnknown;
-    Bool		has_none = FALSE;
-    ScrnInfoPtr		scrn = xf86Screens[pScreen->myNum];
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			c, o;
-
-    for (c = 0; c < xf86_config->num_crtc; c++)
-    {
-	xf86CrtcPtr crtc = xf86_config->crtc[c];
-	
-	for (o = 0; o < xf86_config->num_output; o++)
-	{
-	    xf86OutputPtr   output = xf86_config->output[o];
-
-	    if (output->crtc == crtc)
-	    {
-		switch (output->subpixel_order) {
-		case SubPixelNone:
-		    has_none = TRUE;
-		    break;
-		case SubPixelUnknown:
-		    break;
-		default:
-		    subpixel_order = output->subpixel_order;
-		    break;
-		}
-	    }
-	    if (subpixel_order != SubPixelUnknown)
-		break;
-	}
-	if (subpixel_order != SubPixelUnknown)
-	{
-	    static const int circle[4] = {
-		SubPixelHorizontalRGB,
-		SubPixelVerticalRGB,
-		SubPixelHorizontalBGR,
-		SubPixelVerticalBGR,
-	    };
-	    int	rotate;
-	    int c;
-	    for (rotate = 0; rotate < 4; rotate++)
-		if (crtc->rotation & (1 << rotate))
-		    break;
-	    for (c = 0; c < 4; c++)
-		if (circle[c] == subpixel_order)
-		    break;
-	    c = (c + rotate) & 0x3;
-	    if ((crtc->rotation & RR_Reflect_X) && !(c & 1))
-		c ^= 2;
-	    if ((crtc->rotation & RR_Reflect_Y) && (c & 1))
-		c ^= 2;
-	    subpixel_order = circle[c];
-	    break;
-	}
-    }
-    if (subpixel_order == SubPixelUnknown && has_none)
-	subpixel_order = SubPixelNone;
-    PictureSetSubpixelOrder (pScreen, subpixel_order);
-}
-
-/**
- * Sets the given video mode on the given crtc
- */
-Bool
-xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
-			  RRTransformPtr transform, int x, int y)
-{
-    ScrnInfoPtr		scrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			i;
-    Bool		ret = FALSE;
-    Bool		didLock = FALSE;
-    DisplayModePtr	adjusted_mode;
-    DisplayModeRec	saved_mode;
-    int			saved_x, saved_y;
-    Rotation		saved_rotation;
-    RRTransformRec	saved_transform;
-    Bool		saved_transform_present;
-
-    crtc->enabled = xf86CrtcInUse (crtc);
-
-    /* We only hit this if someone explicitly sends a "disabled" modeset. */
-    if (!crtc->enabled)
-    {
-	/* Check everything for stuff that should be off. */
-	xf86DisableUnusedFunctions(scrn);
-	return TRUE;
-    }
-
-    adjusted_mode = xf86DuplicateMode(mode);
-
-
-    saved_mode = crtc->mode;
-    saved_x = crtc->x;
-    saved_y = crtc->y;
-    saved_rotation = crtc->rotation;
-    if (crtc->transformPresent) {
-	RRTransformInit (&saved_transform);
-	RRTransformCopy (&saved_transform, &crtc->transform);
-    }
-    saved_transform_present = crtc->transformPresent;
-
-    /* Update crtc values up front so the driver can rely on them for mode
-     * setting.
-     */
-    crtc->mode = *mode;
-    crtc->x = x;
-    crtc->y = y;
-    crtc->rotation = rotation;
-    if (transform) {
-	RRTransformCopy (&crtc->transform, transform);
-	crtc->transformPresent = TRUE;
-    } else
-	crtc->transformPresent = FALSE;
-
-    if (crtc->funcs->set_mode_major) {
-	ret = crtc->funcs->set_mode_major(crtc, mode, rotation, x, y);
-	goto done;
-    }
-
-    didLock = crtc->funcs->lock (crtc);
-    /* Pass our mode to the outputs and the CRTC to give them a chance to
-     * adjust it according to limitations or output properties, and also
-     * a chance to reject the mode entirely.
-     */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-
-	if (output->crtc != crtc)
-	    continue;
-
-	if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
-	    goto done;
-	}
-    }
-
-    if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
-	goto done;
-    }
-
-    if (!xf86CrtcRotate (crtc))
-	goto done;
-
-    /* Prepare the outputs and CRTCs before setting the mode. */
-    for (i = 0; i < xf86_config->num_output; i++) {
-	xf86OutputPtr output = xf86_config->output[i];
-
-	if (output->crtc != crtc)
-	    continue;
-
-	/* Disable the output as the first thing we do. */
-	output->funcs->prepare(output);
-    }
-
-    crtc->funcs->prepare(crtc);
-
-    /* Set up the DPLL and any output state that needs to adjust or depend
-     * on the DPLL.
-     */
-    crtc->funcs->mode_set(crtc, mode, adjusted_mode, crtc->x, crtc->y);
-    for (i = 0; i < xf86_config->num_output; i++) 
-    {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc)
-	    output->funcs->mode_set(output, mode, adjusted_mode);
-    }
-
-    /* Only upload when needed, to avoid unneeded delays. */
-    if (!crtc->active && crtc->funcs->gamma_set)
-	crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
-                                            crtc->gamma_blue, crtc->gamma_size);
-
-    /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
-    crtc->funcs->commit(crtc);
-    for (i = 0; i < xf86_config->num_output; i++) 
-    {
-	xf86OutputPtr output = xf86_config->output[i];
-	if (output->crtc == crtc)
-	    output->funcs->commit(output);
-    }
-
-    ret = TRUE;
-
-done:
-    if (ret) {
-	crtc->active = TRUE;
-	if (scrn->pScreen)
-	    xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
-	if (scrn->ModeSet)
-	    scrn->ModeSet(scrn);
-    } else {
-	crtc->x = saved_x;
-	crtc->y = saved_y;
-	crtc->rotation = saved_rotation;
-	crtc->mode = saved_mode;
-	if (saved_transform_present)
-	    RRTransformCopy (&crtc->transform, &saved_transform);
-	crtc->transformPresent = saved_transform_present;
-    }
-
-    free(adjusted_mode->name);
-    free(adjusted_mode);
-
-    if (didLock)
-	crtc->funcs->unlock (crtc);
-
-    return ret;
-}
-
-/**
- * Sets the given video mode on the given crtc, but without providing
- * a transform
- */
-Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
-		 int x, int y)
-{
-    return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y);
-}
-
-/**
- * Pans the screen, does not change the mode
- */
-void
-xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
-{
-    ScrnInfoPtr scrn = crtc->scrn;
-
-    crtc->x = x;
-    crtc->y = y;
-    if (crtc->funcs->set_origin) {
-	if (!xf86CrtcRotate (crtc))
-	    return;
-	crtc->funcs->set_origin (crtc, x, y);
-	if (scrn->ModeSet)
-	    scrn->ModeSet(scrn);
-    }
-    else
-	xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y);
-}
-
-/*
- * Output functions
- */
-
-extern XF86ConfigPtr xf86configptr;
-
-typedef enum {
-    OPTION_PREFERRED_MODE,
-    OPTION_POSITION,
-    OPTION_BELOW,
-    OPTION_RIGHT_OF,
-    OPTION_ABOVE,
-    OPTION_LEFT_OF,
-    OPTION_ENABLE,
-    OPTION_DISABLE,
-    OPTION_MIN_CLOCK,
-    OPTION_MAX_CLOCK,
-    OPTION_IGNORE,
-    OPTION_ROTATE,
-    OPTION_PANNING,
-    OPTION_PRIMARY,
-    OPTION_DEFAULT_MODES,
-} OutputOpts;
-
-static OptionInfoRec xf86OutputOptions[] = {
-    {OPTION_PREFERRED_MODE, "PreferredMode",	OPTV_STRING,  {0}, FALSE },
-    {OPTION_POSITION,	    "Position",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_BELOW,	    "Below",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_RIGHT_OF,	    "RightOf",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_ABOVE,	    "Above",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_LEFT_OF,	    "LeftOf",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_ENABLE,	    "Enable",		OPTV_BOOLEAN, {0}, FALSE },
-    {OPTION_DISABLE,	    "Disable",		OPTV_BOOLEAN, {0}, FALSE },
-    {OPTION_MIN_CLOCK,	    "MinClock",		OPTV_FREQ,    {0}, FALSE },
-    {OPTION_MAX_CLOCK,	    "MaxClock",		OPTV_FREQ,    {0}, FALSE },
-    {OPTION_IGNORE,	    "Ignore",		OPTV_BOOLEAN, {0}, FALSE },
-    {OPTION_ROTATE,	    "Rotate",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_PANNING,	    "Panning",		OPTV_STRING,  {0}, FALSE },
-    {OPTION_PRIMARY,	    "Primary",		OPTV_BOOLEAN, {0}, FALSE },
-    {OPTION_DEFAULT_MODES,  "DefaultModes",	OPTV_BOOLEAN, {0}, FALSE },
-    {-1,		    NULL,		OPTV_NONE,    {0}, FALSE },
-};
-
-enum {
-    OPTION_MODEDEBUG,
-};
-
-static OptionInfoRec xf86DeviceOptions[] = {
-    {OPTION_MODEDEBUG,	    "ModeDebug",	OPTV_BOOLEAN,  {0}, FALSE },
-    {-1,		    NULL,		OPTV_NONE,    {0}, FALSE },
-};
-
-static void
-xf86OutputSetMonitor (xf86OutputPtr output)
-{
-    char    *option_name;
-    char    *monitor;
-
-    if (!output->name)
-	return;
-
-    free(output->options);
-
-    output->options = xnfalloc (sizeof (xf86OutputOptions));
-    memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions));
-
-    XNFasprintf(&option_name, "monitor-%s", output->name);
-    monitor = xf86findOptionValue (output->scrn->options, option_name);
-    if (!monitor)
-	monitor = output->name;
-    else
-	xf86MarkOptionUsedByName (output->scrn->options, option_name);
-    free(option_name);
-    output->conf_monitor = xf86findMonitor (monitor,
-					    xf86configptr->conf_monitor_lst);
-    /*
-     * Find the monitor section of the screen and use that
-     */
-    if (!output->conf_monitor && output->use_screen_monitor)
-	output->conf_monitor = xf86findMonitor (output->scrn->monitor->id,
-						xf86configptr->conf_monitor_lst);
-    if (output->conf_monitor)
-    {
-	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
-		    "Output %s using monitor section %s\n",
-		    output->name, output->conf_monitor->mon_identifier);
-	xf86ProcessOptions (output->scrn->scrnIndex,
-			    output->conf_monitor->mon_option_lst,
-			    output->options);
-    }
-    else
-	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
-		    "Output %s has no monitor section\n",
-		    output->name);
-}
-
-static Bool
-xf86OutputEnabled (xf86OutputPtr output, Bool strict)
-{
-    Bool    enable, disable;
-
-    /* check to see if this output was enabled in the config file */
-    if (xf86GetOptValBool (output->options, OPTION_ENABLE, &enable) && enable)
-    {
-	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
-		    "Output %s enabled by config file\n", output->name);
-	return TRUE;
-    }
-    /* or if this output was disabled in the config file */
-    if (xf86GetOptValBool (output->options, OPTION_DISABLE, &disable) && disable)
-    {
-	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
-		    "Output %s disabled by config file\n", output->name);
-	return FALSE;
-    }
-
-    /* If not, try to only light up the ones we know are connected */
-    if (strict) {
-	enable = output->status == XF86OutputStatusConnected;
-    }
-    /* But if that fails, try to light up even outputs we're unsure of */
-    else {
-	enable = output->status != XF86OutputStatusDisconnected;
-    }
-
-    xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
-    	    "Output %s %sconnected\n", output->name, enable ? "" : "dis");
-    return enable;
-}
-
-static Bool
-xf86OutputIgnored (xf86OutputPtr    output)
-{
-    return xf86ReturnOptValBool (output->options, OPTION_IGNORE, FALSE);
-}
-
-static char *direction[4] = {
-    "normal", 
-    "left", 
-    "inverted", 
-    "right"
-};
-
-static Rotation
-xf86OutputInitialRotation (xf86OutputPtr output)
-{
-    char    *rotate_name = xf86GetOptValString (output->options, 
-						OPTION_ROTATE);
-    int	    i;
-
-    if (!rotate_name) {
-	if (output->initial_rotation)
-	    return output->initial_rotation;
-	return RR_Rotate_0;
-    }
-    
-    for (i = 0; i < 4; i++)
-	if (xf86nameCompare (direction[i], rotate_name) == 0)
-	    return 1 << i;
-    return RR_Rotate_0;
-}
-
-xf86OutputPtr
-xf86OutputCreate (ScrnInfoPtr		    scrn,
-		  const xf86OutputFuncsRec  *funcs,
-		  const char		    *name)
-{
-    xf86OutputPtr	output, *outputs;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			len;
-    Bool		primary;
-
-    if (name)
-	len = strlen (name) + 1;
-    else
-	len = 0;
-
-    output = calloc(sizeof (xf86OutputRec) + len, 1);
-    if (!output)
-	return NULL;
-    output->scrn = scrn;
-    output->funcs = funcs;
-    if (name)
-    {
-	output->name = (char *) (output + 1);
-	strcpy (output->name, name);
-    }
-    output->subpixel_order = SubPixelUnknown;
-    /*
-     * Use the old per-screen monitor section for the first output
-     */
-    output->use_screen_monitor = (xf86_config->num_output == 0);
-#ifdef RANDR_12_INTERFACE
-    output->randr_output = NULL;
-#endif
-    if (name)
-    {
-	xf86OutputSetMonitor (output);
-	if (xf86OutputIgnored (output))
-	{
-	    free(output);
-	    return FALSE;
-	}
-    }
-    
-    
-    if (xf86_config->output)
-	outputs = realloc(xf86_config->output,
-			  (xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
-    else
-	outputs = malloc((xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
-    if (!outputs)
-    {
-	free(output);
-	return NULL;
-    }
-
-    xf86_config->output = outputs;
-
-    if (xf86GetOptValBool (output->options, OPTION_PRIMARY, &primary) && primary)
-    {
-	memmove(xf86_config->output + 1, xf86_config->output,
-		xf86_config->num_output * sizeof (xf86OutputPtr));
-	xf86_config->output[0] = output;
-    }
-    else
-    {
-	xf86_config->output[xf86_config->num_output] = output;
-    }
-
-    xf86_config->num_output++;
-
-    return output;
-}
-
-Bool
-xf86OutputRename (xf86OutputPtr output, const char *name)
-{
-    char    *newname = strdup(name);
-    
-    if (!newname)
-	return FALSE;	/* so sorry... */
-    
-    if (output->name && output->name != (char *) (output + 1))
-	free(output->name);
-    output->name = newname;
-    xf86OutputSetMonitor (output);
-    if (xf86OutputIgnored (output))
-	return FALSE;
-    return TRUE;
-}
-
-void
-xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor)
-{
-    if (use_screen_monitor != output->use_screen_monitor)
-    {
-	output->use_screen_monitor = use_screen_monitor;
-	xf86OutputSetMonitor (output);
-    }
-}
-
-void
-xf86OutputDestroy (xf86OutputPtr output)
-{
-    ScrnInfoPtr		scrn = output->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-    
-    (*output->funcs->destroy) (output);
-    while (output->probed_modes)
-	xf86DeleteMode (&output->probed_modes, output->probed_modes);
-    for (o = 0; o < xf86_config->num_output; o++)
-	if (xf86_config->output[o] == output)
-	{
-	    memmove (&xf86_config->output[o],
-		     &xf86_config->output[o+1],
-		     ((xf86_config->num_output - (o + 1)) * sizeof(void*)));
-	    xf86_config->num_output--;
-	    break;
-	}
-    if (output->name && output->name != (char *) (output + 1))
-	free(output->name);
-    free(output);
-}
-
-/*
- * Called during CreateScreenResources to hook up RandR
- */
-static Bool
-xf86CrtcCreateScreenResources (ScreenPtr screen)
-{
-    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-
-    screen->CreateScreenResources = config->CreateScreenResources;
-    
-    if (!(*screen->CreateScreenResources)(screen))
-	return FALSE;
-
-    if (!xf86RandR12CreateScreenResources (screen))
-	return FALSE;
-
-    return TRUE;
-}
-
-/*
- * Clean up config on server reset
- */
-static Bool
-xf86CrtcCloseScreen (int index, ScreenPtr screen)
-{
-    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o, c;
-    
-    screen->CloseScreen = config->CloseScreen;
-
-    xf86RotateCloseScreen (screen);
-
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	output->randr_output = NULL;
-    }
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	xf86CrtcPtr	crtc = config->crtc[c];
-
-	crtc->randr_crtc = NULL;
-    }
-    xf86RandR12CloseScreen (screen);
-
-    return screen->CloseScreen (index, screen);
-}
-
-/*
- * Called at ScreenInit time to set up
- */
-#ifdef RANDR_13_INTERFACE
-int
-#else
-Bool
-#endif
-xf86CrtcScreenInit (ScreenPtr screen)
-{
-    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			c;
-
-    /* Rotation */
-    xf86DrvMsg(scrn->scrnIndex, X_INFO, "RandR 1.2 enabled, ignore the following RandR disabled message.\n");
-    xf86DisableRandR(); /* Disable old RandR extension support */
-    xf86RandR12Init (screen);
-
-    /* support all rotations if every crtc has the shadow alloc funcs */
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	xf86CrtcPtr crtc = config->crtc[c];
-	if (!crtc->funcs->shadow_allocate || !crtc->funcs->shadow_create)
-	    break;
-    }
-    if (c == config->num_crtc)
-    {
-	xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 |
-				 RR_Rotate_180 | RR_Rotate_270 |
-				 RR_Reflect_X | RR_Reflect_Y);
-	xf86RandR12SetTransformSupport (screen, TRUE);
-    }
-    else
-    {
-	xf86RandR12SetRotations (screen, RR_Rotate_0);
-	xf86RandR12SetTransformSupport (screen, FALSE);
-    }
-    
-    /* Wrap CreateScreenResources so we can initialize the RandR code */
-    config->CreateScreenResources = screen->CreateScreenResources;
-    screen->CreateScreenResources = xf86CrtcCreateScreenResources;
-
-    config->CloseScreen = screen->CloseScreen;
-    screen->CloseScreen = xf86CrtcCloseScreen;
-    
-#ifdef XFreeXDGA
-    _xf86_di_dga_init_internal(screen);
-#endif
-#ifdef RANDR_13_INTERFACE
-    return RANDR_INTERFACE_VERSION;
-#else
-    return TRUE;
-#endif
-}
-
-static DisplayModePtr
-xf86DefaultMode (xf86OutputPtr output, int width, int height)
-{
-    DisplayModePtr  target_mode = NULL;
-    DisplayModePtr  mode;
-    int		    target_diff = 0;
-    int		    target_preferred = 0;
-    int		    mm_height;
-    
-    mm_height = output->mm_height;
-    if (!mm_height)
-	mm_height = (768 * 25.4) / DEFAULT_DPI;
-    /*
-     * Pick a mode closest to DEFAULT_DPI
-     */
-    for (mode = output->probed_modes; mode; mode = mode->next)
-    {
-	int	    dpi;
-	int	    preferred = (((mode->type & M_T_PREFERRED) != 0) +
-				 ((mode->type & M_T_USERPREF) != 0));
-	int	    diff;
-
-	if (xf86ModeWidth (mode, output->initial_rotation) > width ||
-	    xf86ModeHeight (mode, output->initial_rotation) > height)
-	    continue;
-	
-	/* yes, use VDisplay here, not xf86ModeHeight */
-	dpi = (mode->VDisplay * 254) / (mm_height * 10);
-	diff = dpi - DEFAULT_DPI;
-	diff = diff < 0 ? -diff : diff;
-	if (target_mode == NULL || (preferred > target_preferred) ||
-	    (preferred == target_preferred && diff < target_diff))
-	{
-	    target_mode = mode;
-	    target_diff = diff;
-	    target_preferred = preferred;
-	}
-    }
-    return target_mode;
-}
-
-static DisplayModePtr
-xf86ClosestMode (xf86OutputPtr output, 
-		 DisplayModePtr match, Rotation match_rotation,
-		 int width, int height)
-{
-    DisplayModePtr  target_mode = NULL;
-    DisplayModePtr  mode;
-    int		    target_diff = 0;
-    
-    /*
-     * Pick a mode closest to the specified mode
-     */
-    for (mode = output->probed_modes; mode; mode = mode->next)
-    {
-	int	    dx, dy;
-	int	    diff;
-
-	if (xf86ModeWidth (mode, output->initial_rotation) > width ||
-	    xf86ModeHeight (mode, output->initial_rotation) > height)
-	    continue;
-	
-	/* exact matches are preferred */
-	if (output->initial_rotation == match_rotation &&
-	    xf86ModesEqual (mode, match))
-	    return mode;
-	
-	dx = xf86ModeWidth (match, match_rotation) - xf86ModeWidth (mode, output->initial_rotation);
-	dy = xf86ModeHeight (match, match_rotation) - xf86ModeHeight (mode, output->initial_rotation);
-	diff = dx * dx + dy * dy;
-	if (target_mode == NULL || diff < target_diff)
-	{
-	    target_mode = mode;
-	    target_diff = diff;
-	}
-    }
-    return target_mode;
-}
-
-static DisplayModePtr
-xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
-{
-    DisplayModePtr  mode;
-
-    for (mode = output->probed_modes; mode; mode = mode->next)
-    {
-	if (xf86ModeWidth (mode, output->initial_rotation) > width ||
-	    xf86ModeHeight (mode, output->initial_rotation) > height)
-	    continue;
-
-	if (mode->type & M_T_PREFERRED)
-	    return mode;
-    }
-    return NULL;
-}
-
-static DisplayModePtr
-xf86OutputHasUserPreferredMode (xf86OutputPtr output)
-{
-    DisplayModePtr mode, first = output->probed_modes;
-
-    for (mode = first; mode && mode->next != first; mode = mode->next)
-	if (mode->type & M_T_USERPREF)
-	    return mode;
-
-    return NULL;
-}
-
-static int
-xf86PickCrtcs (ScrnInfoPtr	scrn,
-	       xf86CrtcPtr	*best_crtcs,
-	       DisplayModePtr	*modes,
-	       int		n,
-	       int		width,
-	       int		height)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int		    c, o;
-    xf86OutputPtr   output;
-    xf86CrtcPtr	    crtc;
-    xf86CrtcPtr	    *crtcs;
-    xf86CrtcPtr	    best_crtc;
-    int		    best_score;
-    int		    score;
-    int		    my_score;
-    
-    if (n == config->num_output)
-	return 0;
-    output = config->output[n];
-    
-    /*
-     * Compute score with this output disabled
-     */
-    best_crtcs[n] = NULL;
-    best_crtc = NULL;
-    best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height);
-    if (modes[n] == NULL)
-	return best_score;
-    
-    crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr));
-    if (!crtcs)
-	return best_score;
-
-    my_score = 1;
-    /* Score outputs that are known to be connected higher */
-    if (output->status == XF86OutputStatusConnected)
-	my_score++;
-    /* Score outputs with preferred modes higher */
-    if (xf86OutputHasPreferredMode (output, width, height))
-	my_score++;
-    /*
-     * Select a crtc for this output and
-     * then attempt to configure the remaining
-     * outputs
-     */
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	if ((output->possible_crtcs & (1 << c)) == 0)
-	    continue;
-	
-	crtc = config->crtc[c];
-	/*
-	 * Check to see if some other output is
-	 * using this crtc
-	 */
-	for (o = 0; o < n; o++)
-	    if (best_crtcs[o] == crtc)
-		break;
-	if (o < n)
-	{
-	    /*
-	     * If the two outputs desire the same mode,
-	     * see if they can be cloned
-	     */
-	    if (xf86ModesEqual (modes[o], modes[n]) &&
-		config->output[o]->initial_rotation == config->output[n]->initial_rotation &&
-		config->output[o]->initial_x == config->output[n]->initial_x &&
-		config->output[o]->initial_y == config->output[n]->initial_y)
-	    {
-		if ((output->possible_clones & (1 << o)) == 0)
-		    continue;		/* nope, try next CRTC */
-	    }
-	    else
-		continue;		/* different modes, can't clone */
-	}
-	crtcs[n] = crtc;
-	memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
-	score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height);
-	if (score > best_score)
-	{
-	    best_crtc = crtc;
-	    best_score = score;
-	    memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr));
-	}
-    }
-    free(crtcs);
-    return best_score;
-}
-
-
-/*
- * Compute the virtual size necessary to place all of the available
- * crtcs in the specified configuration.
- *
- * canGrow indicates that the driver can make the screen larger than its initial
- * configuration.  If FALSE, this function will enlarge the screen to include
- * the largest available mode.
- */
-
-static void
-xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp,
-			 Bool canGrow)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int	    width = 0, height = 0;
-    int	    o;
-    int	    c;
-    int	    s;
-
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	int	    crtc_width = 0, crtc_height = 0;
-	xf86CrtcPtr crtc = config->crtc[c];
-
-	if (crtc->enabled)
-	{
-	    crtc_width = crtc->desiredX + xf86ModeWidth (&crtc->desiredMode, crtc->desiredRotation);
-	    crtc_height = crtc->desiredY + xf86ModeHeight (&crtc->desiredMode, crtc->desiredRotation);
-	}
-	if (!canGrow) {
-	    for (o = 0; o < config->num_output; o++)
-	    {
-		xf86OutputPtr   output = config->output[o];
-
-		for (s = 0; s < config->num_crtc; s++)
-		    if (output->possible_crtcs & (1 << s))
-		    {
-			DisplayModePtr  mode;
-			for (mode = output->probed_modes; mode; mode = mode->next)
-			{
-			    if (mode->HDisplay > crtc_width)
-				crtc_width = mode->HDisplay;
-			    if (mode->VDisplay > crtc_width)
-				crtc_width = mode->VDisplay;
-			    if (mode->VDisplay > crtc_height)
-				crtc_height = mode->VDisplay;
-			    if (mode->HDisplay > crtc_height)
-				crtc_height = mode->HDisplay;
-			}
-		    }
-	    }
-	}
-	if (crtc_width > width)
-	    width = crtc_width;
-	if (crtc_height > height)
-	    height = crtc_height;
-    }
-    if (config->maxWidth && width > config->maxWidth) width = config->maxWidth;
-    if (config->maxHeight && height > config->maxHeight) height = config->maxHeight;
-    if (config->minWidth && width < config->minWidth) width = config->minWidth;
-    if (config->minHeight && height < config->minHeight) height = config->minHeight;
-    *widthp = width;
-    *heightp = height;
-}
-
-#define POSITION_UNSET	-100000
-
-/*
- * check if the user configured any outputs at all 
- * with either a position or a relative setting or a mode.
- */
-static Bool
-xf86UserConfiguredOutputs(ScrnInfoPtr scrn, DisplayModePtr *modes)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int o;
-    Bool user_conf = FALSE;
-
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr output = config->output[o];
-	char	    *position;
-	char	    *relative_name;
-	OutputOpts	    relation;
-	int r;
-	static const OutputOpts	relations[] = {
-	    OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
-	};
-
-	position = xf86GetOptValString (output->options,
-					OPTION_POSITION);
-	if (position)
-	    user_conf = TRUE;
-
-	relation = 0;
-	relative_name = NULL;
-	for (r = 0; r < 4; r++)
-	{
-	    relation = relations[r];
-	    relative_name = xf86GetOptValString (output->options,
-						     relation);
-	    if (relative_name)
-		break;
-	}
-	if (relative_name)
-	    user_conf = TRUE;
-
-	modes[o] = xf86OutputHasUserPreferredMode(output);
-	if (modes[o])
-	    user_conf = TRUE;
-    }
-
-    return user_conf;
-}
-
-static Bool
-xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-    int			min_x, min_y;
-    
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	output->initial_x = output->initial_y = POSITION_UNSET;
-    }
-    
-    /*
-     * Loop until all outputs are set
-     */
-    for (;;)
-    {
-	Bool	any_set = FALSE;
-	Bool	keep_going = FALSE;
-
-	for (o = 0; o < config->num_output; o++)	
-	{
-	    static const OutputOpts	relations[] = {
-		OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
-	    };
-	    xf86OutputPtr   output = config->output[o];
-	    xf86OutputPtr   relative;
-	    char	    *relative_name;
-	    char	    *position;
-	    OutputOpts	    relation;
-	    int		    r;
-
-	    if (output->initial_x != POSITION_UNSET)
-		continue;
-	    position = xf86GetOptValString (output->options,
-					    OPTION_POSITION);
-	    /*
-	     * Absolute position wins
-	     */
-	    if (position)
-	    {
-		int		    x, y;
-		if (sscanf (position, "%d %d", &x, &y) == 2)
-		{
-		    output->initial_x = x;
-		    output->initial_y = y;
-		}
-		else
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Output %s position not of form \"x y\"\n",
-				output->name);
-		    output->initial_x = output->initial_y = 0;
-		}
-		any_set = TRUE;
-		continue;
-	    }
-	    /*
-	     * Next comes relative positions
-	     */
-	    relation = 0;
-	    relative_name = NULL;
-	    for (r = 0; r < 4; r++)
-	    {
-		relation = relations[r];
-		relative_name = xf86GetOptValString (output->options,
-						     relation);
-		if (relative_name)
-		    break;
-	    }
-	    if (relative_name)
-	    {
-		int or;
-		relative = NULL;
-		for (or = 0; or < config->num_output; or++)
-		{
-		    xf86OutputPtr	out_rel = config->output[or];
-		    XF86ConfMonitorPtr	rel_mon = out_rel->conf_monitor;
-
-		    if (rel_mon)
-		    {
-			if (xf86nameCompare (rel_mon->mon_identifier,
-					      relative_name) == 0)
-			{
-			    relative = config->output[or];
-			    break;
-			}
-		    }
-		    if (strcmp (out_rel->name, relative_name) == 0)
-		    {
-			relative = config->output[or];
-			break;
-		    }
-		}
-		if (!relative)
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Cannot position output %s relative to unknown output %s\n",
-				output->name, relative_name);
-		    output->initial_x = 0;
-		    output->initial_y = 0;
-		    any_set = TRUE;
-		    continue;
-		}
-		if (!modes[or])
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Cannot position output %s relative to output %s without modes\n",
-				output->name, relative_name);
-		    output->initial_x = 0;
-		    output->initial_y = 0;
-		    any_set = TRUE;
-		    continue;
-		}
-		if (relative->initial_x == POSITION_UNSET)
-		{
-		    keep_going = TRUE;
-		    continue;
-		}
-		output->initial_x = relative->initial_x;
-		output->initial_y = relative->initial_y;
-		switch (relation) {
-		case OPTION_BELOW:
-		    output->initial_y += xf86ModeHeight (modes[or], relative->initial_rotation);
-		    break;
-		case OPTION_RIGHT_OF:
-		    output->initial_x += xf86ModeWidth (modes[or], relative->initial_rotation);
-		    break;
-		case OPTION_ABOVE:
-		    if (modes[o])
-			output->initial_y -= xf86ModeHeight (modes[o], output->initial_rotation);
-		    break;
-		case OPTION_LEFT_OF:
-		    if (modes[o])
-			output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation);
-		    break;
-		default:
-		    break;
-		}
-		any_set = TRUE;
-		continue;
-	    }
-	    
-	    /* Nothing set, just stick them at 0,0 */
-	    output->initial_x = 0;
-	    output->initial_y = 0;
-	    any_set = TRUE;
-	}
-	if (!keep_going)
-	    break;
-	if (!any_set) 
-	{
-	    for (o = 0; o < config->num_output; o++)
-	    {
-		xf86OutputPtr   output = config->output[o];
-		if (output->initial_x == POSITION_UNSET)
-		{
-		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-				"Output position loop. Moving %s to 0,0\n",
-				output->name);
-		    output->initial_x = output->initial_y = 0;
-		    break;
-		}
-	    }
-	}
-    }
-
-    /*
-     * normalize positions
-     */
-    min_x = 1000000;
-    min_y = 1000000;
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	if (output->initial_x < min_x)
-	    min_x = output->initial_x;
-	if (output->initial_y < min_y)
-	    min_y = output->initial_y;
-    }
-    
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-
-	output->initial_x -= min_x;
-	output->initial_y -= min_y;
-    }
-    return TRUE;
-}
-
-static void
-xf86InitialPanning (ScrnInfoPtr scrn)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-    
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-	char	       *panning = xf86GetOptValString (output->options, OPTION_PANNING);
-	int		width, height, left, top;
-	int		track_width, track_height, track_left, track_top;
-	int		brdr[4];
-
-	memset (&output->initialTotalArea,    0, sizeof(BoxRec));
-	memset (&output->initialTrackingArea, 0, sizeof(BoxRec));
-	memset (output->initialBorder,        0, 4*sizeof(INT16));
-
-	if (! panning)
-	    continue;
-
-	switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d",
-			&width, &height, &left, &top,
-			&track_width, &track_height, &track_left, &track_top,
-			&brdr[0], &brdr[1], &brdr[2], &brdr[3])) {
-	case 12:
-	    output->initialBorder[0] = brdr[0];
-	    output->initialBorder[1] = brdr[1];
-	    output->initialBorder[2] = brdr[2];
-	    output->initialBorder[3] = brdr[3];
-	    /* fall through */
-	case 8:
-	    output->initialTrackingArea.x1 = track_left;
-	    output->initialTrackingArea.y1 = track_top;
-	    output->initialTrackingArea.x2 = track_left + track_width;
-	    output->initialTrackingArea.y2 = track_top  + track_height;
-	    /* fall through */
-	case 4:
-	    output->initialTotalArea.x1 = left;
-	    output->initialTotalArea.y1 = top;
-	    /* fall through */
-	case 2:
-	    output->initialTotalArea.x2 = output->initialTotalArea.x1 + width;
-	    output->initialTotalArea.y2 = output->initialTotalArea.y1 + height;
-	    break;
-	default:
-	    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-			"Broken panning specification '%s' for output %s in config file\n",
-			panning, output->name);
-	}
-    }
-}
-
-/** Return - 0 + if a should be earlier, same or later than b in list
- */
-static int
-xf86ModeCompare (DisplayModePtr a, DisplayModePtr b)
-{
-    int	diff;
-
-    diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0);
-    if (diff)
-	return diff;
-    diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay;
-    if (diff)
-	return diff;
-    diff = b->Clock - a->Clock;
-    return diff;
-}
-
-/**
- * Insertion sort input in-place and return the resulting head
- */
-static DisplayModePtr
-xf86SortModes (DisplayModePtr input)
-{
-    DisplayModePtr  output = NULL, i, o, n, *op, prev;
-
-    /* sort by preferred status and pixel area */
-    while (input)
-    {
-	i = input;
-	input = input->next;
-	for (op = &output; (o = *op); op = &o->next)
-	    if (xf86ModeCompare (o, i) > 0)
-		break;
-	i->next = *op;
-	*op = i;
-    }
-    /* prune identical modes */
-    for (o = output; o && (n = o->next); o = n)
-    {
-	if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n))
-	{
-	    o->next = n->next;
-	    free(n->name);
-	    free(n);
-	    n = o;
-	}
-    }
-    /* hook up backward links */
-    prev = NULL;
-    for (o = output; o; o = o->next)
-    {
-	o->prev = prev;
-	prev = o;
-    }
-    return output;
-}
-
-static char *
-preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output)
-{
-    char *preferred_mode = NULL;
-
-    /* Check for a configured preference for a particular mode */
-    preferred_mode = xf86GetOptValString (output->options,
-					  OPTION_PREFERRED_MODE);
-    if (preferred_mode)
-	return preferred_mode;
-
-    if (pScrn->display->modes && *pScrn->display->modes)
-	preferred_mode = *pScrn->display->modes;
-
-    return preferred_mode;
-}
-
-static void
-GuessRangeFromModes(MonPtr mon, DisplayModePtr mode)
-{
-    if (!mon || !mode)
-       return;
-
-    mon->nHsync = 1;
-    mon->hsync[0].lo = 1024.0;
-    mon->hsync[0].hi = 0.0;
-
-    mon->nVrefresh = 1;
-    mon->vrefresh[0].lo = 1024.0;
-    mon->vrefresh[0].hi = 0.0;
-
-    while (mode) {
-	if (!mode->HSync)
-	    mode->HSync = ((float) mode->Clock ) / ((float) mode->HTotal);
-
-	if (!mode->VRefresh)
-	    mode->VRefresh = (1000.0 * ((float) mode->Clock)) / 
-		((float) (mode->HTotal * mode->VTotal));
-
-	if (mode->HSync < mon->hsync[0].lo)
-	    mon->hsync[0].lo = mode->HSync;
-
-	if (mode->HSync > mon->hsync[0].hi)
-	    mon->hsync[0].hi = mode->HSync;
-
-	if (mode->VRefresh < mon->vrefresh[0].lo)
-	    mon->vrefresh[0].lo = mode->VRefresh;
-
-	if (mode->VRefresh > mon->vrefresh[0].hi)
-	    mon->vrefresh[0].hi = mode->VRefresh;
-
-	mode = mode->next;
-    }
-
-    /* stretch out the bottom to fit 640x480@60 */
-    if (mon->hsync[0].lo > 31.0)
-       mon->hsync[0].lo = 31.0;
-    if (mon->vrefresh[0].lo > 58.0)
-       mon->vrefresh[0].lo = 58.0;
-}
-
-enum det_monrec_source {
-    sync_config, sync_edid, sync_default
-};
-
-struct det_monrec_parameter {
-    MonRec *mon_rec;
-    int *max_clock;
-    Bool set_hsync;
-    Bool set_vrefresh;
-    enum det_monrec_source *sync_source;
-};
-
-static void handle_detailed_monrec(struct detailed_monitor_section *det_mon,
-                                   void *data)
-{
-    struct det_monrec_parameter *p;
-    p = (struct det_monrec_parameter *)data;
-
-    if (det_mon->type == DS_RANGES) {
-        struct monitor_ranges *ranges = &det_mon->section.ranges;
-        if (p->set_hsync && ranges->max_h) {
-            p->mon_rec->hsync[p->mon_rec->nHsync].lo = ranges->min_h;
-            p->mon_rec->hsync[p->mon_rec->nHsync].hi = ranges->max_h;
-            p->mon_rec->nHsync++;
-            if (*p->sync_source == sync_default)
-                *p->sync_source = sync_edid;
-        }
-        if (p->set_vrefresh && ranges->max_v) {
-            p->mon_rec->vrefresh[p->mon_rec->nVrefresh].lo = ranges->min_v;
-            p->mon_rec->vrefresh[p->mon_rec->nVrefresh].hi = ranges->max_v;
-            p->mon_rec->nVrefresh++;
-            if (*p->sync_source == sync_default)
-                *p->sync_source = sync_edid;
-        }
-        if (ranges->max_clock * 1000 > *p->max_clock)
-            *p->max_clock = ranges->max_clock * 1000;
-    }
-}
-
-void
-xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-
-    /* When canGrow was TRUE in the initial configuration we have to
-     * compare against the maximum values so that we don't drop modes.
-     * When canGrow was FALSE, the maximum values would have been clamped
-     * anyway.
-     */
-    if (maxX == 0 || maxY == 0) {
-	maxX = config->maxWidth;
-	maxY = config->maxHeight;
-    }
-
-    /* Probe the list of modes for each output. */
-    for (o = 0; o < config->num_output; o++) 
-    {
-	xf86OutputPtr	    output = config->output[o];
-	DisplayModePtr	    mode;
-	DisplayModePtr	    config_modes = NULL, output_modes, default_modes = NULL;
-	char		    *preferred_mode;
-	xf86MonPtr	    edid_monitor;
-	XF86ConfMonitorPtr  conf_monitor;
-	MonRec		    mon_rec;
-	int		    min_clock = 0;
-	int		    max_clock = 0;
-	double		    clock;
-	Bool		    add_default_modes;
-	Bool		    debug_modes = config->debug_modes ||
-					  xf86Initialising;
-	enum det_monrec_source sync_source = sync_default;
-	
-	while (output->probed_modes != NULL)
-	    xf86DeleteMode(&output->probed_modes, output->probed_modes);
-
-	/*
-	 * Check connection status
-	 */
-	output->status = (*output->funcs->detect)(output);
-
-	if (output->status == XF86OutputStatusDisconnected &&
-		!xf86ReturnOptValBool(output->options, OPTION_ENABLE, FALSE))
-	{
-	    xf86OutputSetEDID (output, NULL);
-	    continue;
-	}
-
-	memset (&mon_rec, '\0', sizeof (mon_rec));
-	
-	conf_monitor = output->conf_monitor;
-	
-	if (conf_monitor)
-	{
-	    int	i;
-	    
-	    for (i = 0; i < conf_monitor->mon_n_hsync; i++)
-	    {
-		mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
-		mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
-		mon_rec.nHsync++;
-		sync_source = sync_config;
-	    }
-	    for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
-	    {
-		mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
-		mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
-		mon_rec.nVrefresh++;
-		sync_source = sync_config;
-	    }
-	    config_modes = xf86GetMonitorModes (scrn, conf_monitor);
-	}
-	
-	output_modes = (*output->funcs->get_modes) (output);
-
-	/*
-	 * If the user has a preference, respect it.
-	 * Otherwise, don't second-guess the driver.
-	 */
-	if (!xf86GetOptValBool(output->options, OPTION_DEFAULT_MODES,
-			       &add_default_modes))
-	    add_default_modes = (output_modes == NULL);
-	
-	edid_monitor = output->MonInfo;
-	
-        if (edid_monitor)
-        {
-            struct det_monrec_parameter p;
-            struct disp_features    *features = &edid_monitor->features;
-
-	    /* if display is not continuous-frequency, don't add default modes */
-	    if (!GTF_SUPPORTED(features->msc))
-		add_default_modes = FALSE;
-
-	    p.mon_rec = &mon_rec;
-	    p.max_clock = &max_clock;
-	    p.set_hsync = mon_rec.nHsync == 0;
-	    p.set_vrefresh = mon_rec.nVrefresh == 0;
-	    p.sync_source = &sync_source;
-
-	    xf86ForEachDetailedBlock(edid_monitor,
-			             handle_detailed_monrec,
-			             &p);
-	}
-
-	if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
-			       OPTUNITS_KHZ, &clock))
-	    min_clock = (int) clock;
-	if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK,
-			       OPTUNITS_KHZ, &clock))
-	    max_clock = (int) clock;
-
-	/* If we still don't have a sync range, guess wildly */
-	if (!mon_rec.nHsync || !mon_rec.nVrefresh)
-	    GuessRangeFromModes(&mon_rec, output_modes);
-
-	/*
-	 * These limits will end up setting a 1024x768@60Hz mode by default,
-	 * which seems like a fairly good mode to use when nothing else is
-	 * specified
-	 */
-	if (mon_rec.nHsync == 0)
-	{
-	    mon_rec.hsync[0].lo = 31.0;
-	    mon_rec.hsync[0].hi = 55.0;
-	    mon_rec.nHsync = 1;
-	}
-	if (mon_rec.nVrefresh == 0)
-	{
-	    mon_rec.vrefresh[0].lo = 58.0;
-	    mon_rec.vrefresh[0].hi = 62.0;
-	    mon_rec.nVrefresh = 1;
-	}
-
-	if (add_default_modes)
-	    default_modes = xf86GetDefaultModes ();
-
-	/*
-	 * If this is not an RB monitor, remove RB modes from the default
-	 * pool.  RB modes from the config or the monitor itself are fine.
-	 */
-	if (!mon_rec.reducedblanking)
-	    xf86ValidateModesReducedBlanking (scrn, default_modes);
-
-	if (sync_source == sync_config)
-	{
-	    /* 
-	     * Check output and config modes against sync range from config file
-	     */
-	    xf86ValidateModesSync (scrn, output_modes, &mon_rec);
-	    xf86ValidateModesSync (scrn, config_modes, &mon_rec);
-	}
-	/*
-	 * Check default modes against sync range
-	 */
-        xf86ValidateModesSync (scrn, default_modes, &mon_rec);
-	/*
-	 * Check default modes against monitor max clock
-	 */
-	if (max_clock) {
-	    xf86ValidateModesClocks(scrn, default_modes,
-				    &min_clock, &max_clock, 1);
-	    xf86ValidateModesClocks(scrn, output_modes,
-				    &min_clock, &max_clock, 1);
-	}
-	
-	output->probed_modes = NULL;
-	output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
-	output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
-	output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
-	
-	/*
-	 * Check all modes against max size, interlace, and doublescan
-	 */
-	if (maxX && maxY)
-	    xf86ValidateModesSize (scrn, output->probed_modes,
-				       maxX, maxY, 0);
-
-	{
-	    int flags = (output->interlaceAllowed ? V_INTERLACE : 0) |
-			(output->doubleScanAllowed ? V_DBLSCAN : 0);
-	    xf86ValidateModesFlags (scrn, output->probed_modes, flags);
-	}
-	 
-	/*
-	 * Check all modes against output
-	 */
-	for (mode = output->probed_modes; mode != NULL; mode = mode->next) 
-	    if (mode->status == MODE_OK)
-		mode->status = (*output->funcs->mode_valid)(output, mode);
-	
-	xf86PruneInvalidModes(scrn, &output->probed_modes, debug_modes);
-	
-	output->probed_modes = xf86SortModes (output->probed_modes);
-	
-	/* Check for a configured preference for a particular mode */
-	preferred_mode = preferredMode(scrn, output);
-
-	if (preferred_mode)
-	{
-	    for (mode = output->probed_modes; mode; mode = mode->next)
-	    {
-		if (!strcmp (preferred_mode, mode->name))
-		{
-		    if (mode != output->probed_modes)
-		    {
-			if (mode->prev)
-			    mode->prev->next = mode->next;
-			if (mode->next)
-			    mode->next->prev = mode->prev;
-			mode->next = output->probed_modes;
-			output->probed_modes->prev = mode;
-			mode->prev = NULL;
-			output->probed_modes = mode;
-		    }
-		    mode->type |= (M_T_PREFERRED|M_T_USERPREF);
-		    break;
-		}
-	    }
-	}
-	
-	output->initial_rotation = xf86OutputInitialRotation (output);
-
-	if (debug_modes) {
-	    if (output->probed_modes != NULL) {
-		xf86DrvMsg(scrn->scrnIndex, X_INFO,
-			   "Printing probed modes for output %s\n",
-			   output->name);
-	    } else {
-		xf86DrvMsg(scrn->scrnIndex, X_INFO,
-			   "No remaining probed modes for output %s\n",
-			   output->name);
-	    }
-	}
-	for (mode = output->probed_modes; mode != NULL; mode = mode->next)
-	{
-	    /* The code to choose the best mode per pipe later on will require
-	     * VRefresh to be set.
-	     */
-	    mode->VRefresh = xf86ModeVRefresh(mode);
-	    xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
-
-	    if (debug_modes)
-		xf86PrintModeline(scrn->scrnIndex, mode);
-	}
-    }
-}
-
-
-/**
- * Copy one of the output mode lists to the ScrnInfo record
- */
-
-/* XXX where does this function belong? Here? */
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
-
-static DisplayModePtr
-biggestMode(DisplayModePtr a, DisplayModePtr b)
-{
-    int A, B;
-
-    if (!a)
-	return b;
-    if (!b)
-	return a;
-
-    A = a->HDisplay * a->VDisplay;
-    B = b->HDisplay * b->VDisplay;
-
-    if (A > B)
-	return a;
-
-    return b;
-}
-
-static xf86OutputPtr
-SetCompatOutput(xf86CrtcConfigPtr config)
-{
-    xf86OutputPtr output = NULL, test = NULL;
-    DisplayModePtr maxmode = NULL, testmode, mode;
-    int o, compat = -1, count, mincount = 0;
-
-    /* Look for one that's definitely connected */
-    for (o = 0; o < config->num_output; o++)
-    {
-	test = config->output[o];
-	if (!test->crtc)
-	    continue;
-	if (test->status != XF86OutputStatusConnected)
-	    continue;
-	if (!test->probed_modes)
-	    continue;
-
-	testmode = mode = test->probed_modes;
-	for (count = 0; mode; mode = mode->next, count++)
-	    testmode = biggestMode(testmode, mode);
-
-	if (!output) {
-	    output = test;
-	    compat = o;
-	    maxmode = testmode;
-	    mincount = count;
-	} else if (maxmode == biggestMode(maxmode, testmode)) {
-	    output = test;
-	    compat = o;
-	    maxmode = testmode;
-	    mincount = count;
-	} else if ((maxmode->HDisplay == testmode->HDisplay) && 
-		(maxmode->VDisplay == testmode->VDisplay) &&
-		count <= mincount) {
-	    output = test;
-	    compat = o;
-	    maxmode = testmode;
-	    mincount = count;
-	}
-    }
-
-    /* If we didn't find one, take anything we can get */
-    if (!output)
-    {
-	for (o = 0; o < config->num_output; o++)
-	{
-	    test = config->output[o];
-	    if (!test->crtc)
-		continue;
-	    if (!test->probed_modes)
-		continue;
-
-	    if (!output) {
-		output = test;
-		compat = o;
-	    } else if (test->probed_modes->HDisplay < output->probed_modes->HDisplay) {
-		output = test;
-		compat = o;
-	    }
-	}
-    }
-
-    if (compat >= 0) {
-	config->compat_output = compat;
-    } else {
-	/* Don't change the compat output when no valid outputs found */
-	output = config->output[config->compat_output];
-    }
-
-    return output;
-}
-
-void
-xf86SetScrnInfoModes (ScrnInfoPtr scrn)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86OutputPtr	output;
-    xf86CrtcPtr		crtc;
-    DisplayModePtr	last, mode = NULL;
-
-    output = SetCompatOutput(config);
-
-    if (!output)
-	return; /* punt */
-
-    crtc = output->crtc;
-
-    /* Clear any existing modes from scrn->modes */
-    while (scrn->modes != NULL)
-	xf86DeleteMode(&scrn->modes, scrn->modes);
-
-    /* Set scrn->modes to the mode list for the 'compat' output */
-    scrn->modes = xf86DuplicateModes(scrn, output->probed_modes);
-
-    if (crtc) {
-	for (mode = scrn->modes; mode; mode = mode->next)
-	    if (xf86ModesEqual (mode, &crtc->desiredMode))
-		break;
-    }
-
-    if (scrn->modes != NULL) {
-	/* For some reason, scrn->modes is circular, unlike the other mode
-	 * lists.  How great is that?
-	 */
-	for (last = scrn->modes; last && last->next; last = last->next)
-	    ;
-	last->next = scrn->modes;
-	scrn->modes->prev = last;
-	if (mode) {
-	    while (scrn->modes != mode)
-		scrn->modes = scrn->modes->next;
-	}
-    }
-    scrn->currentMode = scrn->modes;
-#ifdef XFreeXDGA
-    if (scrn->pScreen)
-	    _xf86_di_dga_reinit_internal(scrn->pScreen);
-#endif
-}
-
-static Bool
-xf86CollectEnabledOutputs(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
-			  Bool *enabled)
-{
-    Bool any_enabled = FALSE;
-    int o;
-
-    for (o = 0; o < config->num_output; o++)
-	any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], TRUE);
-    
-    if (!any_enabled) {
-	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
-		   "No outputs definitely connected, trying again...\n");
-
-	for (o = 0; o < config->num_output; o++)
-	    any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], FALSE);
-    }
-
-    return any_enabled;
-}
-
-static Bool
-nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index)
-{
-    int o = *index;
-
-    for (o++; o < config->num_output; o++) {
-	if (enabled[o]) {
-	    *index = o;
-	    return TRUE;
-	}
-    }
-    
-    return FALSE;
-}
-
-static Bool
-aspectMatch(float a, float b)
-{
-    return fabs(1 - (a / b)) < 0.05;
-}
-
-static DisplayModePtr
-nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
-{
-    DisplayModePtr m = NULL;
-
-    if (!o)
-	return NULL;
-
-    if (!last)
-	m = o->probed_modes;
-    else
-	m = last->next;
-
-    for (; m; m = m->next)
-	if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
-	    return m;
-
-    return NULL;
-}
-
-static DisplayModePtr
-bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
-{
-    int o = -1, p;
-    DisplayModePtr mode = NULL, test = NULL, match = NULL;
-
-    if (!nextEnabledOutput(config, enabled, &o))
-	return NULL;
-    while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
-	test = mode;
-	for (p = o; nextEnabledOutput(config, enabled, &p); ) {
-	    test = xf86OutputFindClosestMode(config->output[p], mode);
-	    if (!test)
-		break;
-	    if (test->HDisplay != mode->HDisplay ||
-		    test->VDisplay != mode->VDisplay) {
-		test = NULL;
-		break;
-	    }
-	}
-
-	/* if we didn't match it on all outputs, try the next one */
-	if (!test)
-	    continue;
-
-	/* if it's bigger than the last one, save it */
-	if (!match || (test->HDisplay > match->HDisplay))
-	    match = test;
-    }
-
-    /* return the biggest one found */
-    return match;
-}
-
-static Bool
-xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
-		    DisplayModePtr *modes, Bool *enabled,
-		    int width, int height)
-{
-    int o, p;
-    int max_pref_width = 0, max_pref_height = 0;
-    DisplayModePtr *preferred, *preferred_match;
-    Bool ret = FALSE;
-
-    preferred = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
-    preferred_match = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
-
-    /* Check if the preferred mode is available on all outputs */
-    for (p = -1; nextEnabledOutput(config, enabled, &p); ) {
-	Rotation r = config->output[p]->initial_rotation;
-	DisplayModePtr mode;
-	if ((preferred[p] = xf86OutputHasPreferredMode(config->output[p],
-			width, height))) {
-	    int pref_width = xf86ModeWidth(preferred[p], r);
-	    int pref_height = xf86ModeHeight(preferred[p], r);
-	    Bool all_match = TRUE;
-
-	    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
-		Bool match = FALSE;
-		xf86OutputPtr output = config->output[o];
-		if (o == p)
-		    continue;
-
-		for (mode = output->probed_modes; mode; mode = mode->next) {
-		    Rotation r = output->initial_rotation;
-		    if (xf86ModeWidth(mode, r) == pref_width &&
-			    xf86ModeHeight(mode, r) == pref_height) {
-			preferred[o] = mode;
-			match = TRUE;
-		    }
-		}
-
-		all_match &= match;
-	    }
-
-	    if (all_match &&
-		    (pref_width*pref_height > max_pref_width*max_pref_height)) {
-		for (o = -1; nextEnabledOutput(config, enabled, &o); )
-		    preferred_match[o] = preferred[o];
-		max_pref_width = pref_width;
-		max_pref_height = pref_height;
-		ret = TRUE;
-	    }
-	}
-    }
-
-    /*
-     * If there's no preferred mode, but only one monitor, pick the
-     * biggest mode for its aspect ratio, assuming one exists.
-     */
-    if (!ret) do {
-	int i = 0;
-	float aspect = 0.0;
-
-	/* count the number of enabled outputs */
-	for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
-
-	if (i != 1)
-	    break;
-
-	p = -1;
-	nextEnabledOutput(config, enabled, &p);
-	if (config->output[p]->mm_height)
-	    aspect = (float)config->output[p]->mm_width /
-		     (float)config->output[p]->mm_height;
-
-	if (aspect)
-	    preferred_match[p] = bestModeForAspect(config, enabled, aspect);
-
-	if (preferred_match[p])
-	    ret = TRUE;
-
-    } while (0);
-
-    if (ret) {
-	/* oh good, there is a match.  stash the selected modes and return. */
-	memcpy(modes, preferred_match,
-		config->num_output * sizeof(DisplayModePtr));
-    }
-
-    free(preferred);
-    free(preferred_match);
-    return ret;
-}
-
-static Bool
-xf86TargetAspect(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
-		 DisplayModePtr *modes, Bool *enabled,
-		 int width, int height)
-{
-    int o;
-    float aspect = 0.0, *aspects;
-    xf86OutputPtr output;
-    Bool ret = FALSE;
-    DisplayModePtr guess = NULL, aspect_guess = NULL, base_guess = NULL;
-
-    aspects = xnfcalloc(config->num_output, sizeof(float));
-
-    /* collect the aspect ratios */
-    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
-	output = config->output[o];
-	if (output->mm_height)
-	    aspects[o] = (float)output->mm_width / (float)output->mm_height;
-	else
-	    aspects[o] = 4.0 / 3.0;
-    }
-
-    /* check that they're all the same */
-    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
-	output = config->output[o];
-	if (!aspect) {
-	    aspect = aspects[o];
-	} else if (!aspectMatch(aspect, aspects[o])) {
-	    goto no_aspect_match;
-	}
-    }
-
-    /* if they're all 4:3, just skip ahead and save effort */
-    if (!aspectMatch(aspect, 4.0/3.0))
-	aspect_guess = bestModeForAspect(config, enabled, aspect);
-
-no_aspect_match:
-    base_guess = bestModeForAspect(config, enabled, 4.0/3.0);
-
-    guess = biggestMode(base_guess, aspect_guess);
-
-    if (!guess)
-	goto out;
-
-    /* found a mode that works everywhere, now apply it */
-    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
-	modes[o] = xf86OutputFindClosestMode(config->output[o], guess);
-    }
-    ret = TRUE;
-
-out:
-    free(aspects);
-    return ret;
-}
-
-static Bool
-xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
-		   DisplayModePtr *modes, Bool *enabled,
-		   int width, int height)
-{
-    DisplayModePtr target_mode = NULL;
-    Rotation target_rotation = RR_Rotate_0;
-    DisplayModePtr default_mode;
-    int default_preferred, target_preferred = 0, o;
-
-    /* User preferred > preferred > other modes */
-    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
-	default_mode = xf86DefaultMode (config->output[o], width, height);
-	if (!default_mode)
-	    continue;
-
-	default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) +
-		((default_mode->type & M_T_USERPREF) != 0));
-
-	if (default_preferred > target_preferred || !target_mode) {
-	    target_mode = default_mode;
-	    target_preferred = default_preferred;
-	    target_rotation = config->output[o]->initial_rotation;
-	    config->compat_output = o;
-	}
-    }
-
-    if (target_mode)
-	modes[config->compat_output] = target_mode;
-
-    /* Fill in other output modes */
-    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
-	if (!modes[o])
-	    modes[o] = xf86ClosestMode(config->output[o], target_mode,
-				       target_rotation, width, height);
-    }
-
-    return target_mode != NULL;
-}
-
-static Bool
-xf86TargetUserpref(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
-		   DisplayModePtr *modes, Bool *enabled,
-		   int width, int height)
-{
-    int o;
-
-    if (xf86UserConfiguredOutputs(scrn, modes))
-	return xf86TargetFallback(scrn, config, modes, enabled, width, height);
-    
-    for (o = -1; nextEnabledOutput(config, enabled, &o); )
-	if (xf86OutputHasUserPreferredMode(config->output[o]))
-	    return 
-		xf86TargetFallback(scrn, config, modes, enabled, width, height);
-
-    return FALSE;
-}
-
-static Bool
-xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
-        float gamma_blue)
-{
-    int i, size = 256;
-    CARD16 *red, *green, *blue;
-
-    red = malloc(3 * size * sizeof(CARD16));
-    green = red + size;
-    blue = green + size;
-
-     /* Only cause warning if user wanted gamma to be set. */
-    if (!crtc->funcs->gamma_set && (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0)) {
-        free(red);
-        return FALSE;
-    } else if (!crtc->funcs->gamma_set) {
-        free(red);
-        return TRUE;
-      }
-
-    /* At this early stage none of the randr-interface stuff is up.
-     * So take the default gamma size for lack of something better.
-     */
-    for (i = 0; i < size; i++) {
-        if (gamma_red == 1.0)
-            red[i] = i << 8;
-        else
-            red[i] = (CARD16)(pow((double)i/(double)(size - 1),
-			1. / (double)gamma_red) * (double)(size - 1) * 256);
-
-        if (gamma_green == 1.0)
-            green[i] = i << 8;
-        else
-            green[i] = (CARD16)(pow((double)i/(double)(size - 1),
-			1. / (double)gamma_green) * (double)(size - 1) * 256);
-
-        if (gamma_blue == 1.0)
-            blue[i] = i << 8;
-        else
-            blue[i] = (CARD16)(pow((double)i/(double)(size - 1),
-			1. / (double)gamma_blue) * (double)(size - 1) * 256);
-    }
-
-    /* Default size is 256, so anything else is failure. */
-    if (size != crtc->gamma_size) {
-        free(red);
-        return FALSE;
-      }
-
-    crtc->gamma_size = size;
-    memcpy (crtc->gamma_red, red, crtc->gamma_size * sizeof (CARD16));
-    memcpy (crtc->gamma_green, green, crtc->gamma_size * sizeof (CARD16));
-    memcpy (crtc->gamma_blue, blue, crtc->gamma_size * sizeof (CARD16));
-
-    /* Do not set gamma now, delay until the crtc is activated. */
-
-    free(red);
-
-    return TRUE;
-}
-
-static Bool
-xf86OutputSetInitialGamma(xf86OutputPtr output)
-{
-    XF86ConfMonitorPtr mon = output->conf_monitor;
-    float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0;
-    
-    if (!mon)
-        return TRUE;
-
-    if (!output->crtc)
-        return FALSE;
-
-    /* Get configured values, where they exist. */
-    if (mon->mon_gamma_red >= GAMMA_MIN &&
-        mon->mon_gamma_red <= GAMMA_MAX)
-            gamma_red = mon->mon_gamma_red;
-
-    if (mon->mon_gamma_green >= GAMMA_MIN &&
-        mon->mon_gamma_green <= GAMMA_MAX)
-            gamma_green = mon->mon_gamma_green;
-
-    if (mon->mon_gamma_blue >= GAMMA_MIN &&
-        mon->mon_gamma_blue <= GAMMA_MAX)
-            gamma_blue = mon->mon_gamma_blue;
-
-    /* This avoids setting gamma 1.0 in case another cloned output on this crtc has a specific gamma. */
-    if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
-	xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n", output->name, gamma_red, gamma_green, gamma_blue);
-	return xf86CrtcSetInitialGamma(output->crtc, gamma_red, gamma_green, gamma_blue);
-    }else
-	return TRUE;
-}
-
-/**
- * Construct default screen configuration
- *
- * Given auto-detected (and, eventually, configured) values,
- * construct a usable configuration for the system
- *
- * canGrow indicates that the driver can resize the screen to larger than its
- * initially configured size via the config->funcs->resize hook.  If TRUE, this
- * function will set virtualX and virtualY to match the initial configuration
- * and leave config->max{Width,Height} alone.  If FALSE, it will bloat
- * virtual[XY] to include the largest modes and set config->max{Width,Height}
- * accordingly.
- */
-
-Bool
-xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o, c;
-    xf86CrtcPtr		*crtcs;
-    DisplayModePtr	*modes;
-    Bool		*enabled;
-    int			width, height;
-    int			i = scrn->scrnIndex;
-    Bool have_outputs = TRUE;
-    Bool ret;
-
-    /* Set up the device options */
-    config->options = xnfalloc (sizeof (xf86DeviceOptions));
-    memcpy (config->options, xf86DeviceOptions, sizeof (xf86DeviceOptions));
-    xf86ProcessOptions (scrn->scrnIndex,
-			scrn->options,
-			config->options);
-    config->debug_modes = xf86ReturnOptValBool (config->options,
-						OPTION_MODEDEBUG, FALSE);
-
-    if (scrn->display->virtualX)
-	width = scrn->display->virtualX;
-    else
-	width = config->maxWidth;
-    if (scrn->display->virtualY)
-	height = scrn->display->virtualY;
-    else
-	height = config->maxHeight;
-
-    xf86ProbeOutputModes (scrn, width, height);
-
-    crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
-    modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
-    enabled = xnfcalloc (config->num_output, sizeof (Bool));
-    
-    ret = xf86CollectEnabledOutputs(scrn, config, enabled);
-    if (ret == FALSE && canGrow) {
-	xf86DrvMsg(i, X_WARNING, "Unable to find connected outputs - setting %dx%d initial framebuffer\n",
-		   NO_OUTPUT_DEFAULT_WIDTH, NO_OUTPUT_DEFAULT_HEIGHT);
-	have_outputs = FALSE;
-    } else {
-	if (xf86TargetUserpref(scrn, config, modes, enabled, width, height))
-	    xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n");
-	else if (xf86TargetPreferred(scrn, config, modes, enabled, width, height))
-	    xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n");
-	else if (xf86TargetAspect(scrn, config, modes, enabled, width, height))
-	    xf86DrvMsg(i, X_INFO, "Using fuzzy aspect match for initial modes\n");
-	else if (xf86TargetFallback(scrn, config, modes, enabled, width, height))
-	    xf86DrvMsg(i, X_INFO, "Using sloppy heuristic for initial modes\n");
-	else
-	    xf86DrvMsg(i, X_WARNING, "Unable to find initial modes\n");
-    }
-
-    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
-	if (!modes[o])
-	    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
-			"Output %s enabled but has no modes\n",
-			config->output[o]->name);
-	else
-	    xf86DrvMsg (scrn->scrnIndex, X_INFO,
-			"Output %s using initial mode %s\n",
-			config->output[o]->name, modes[o]->name);
-    }
-
-    /*
-     * Set the position of each output
-     */
-    if (!xf86InitialOutputPositions (scrn, modes))
-    {
-	free(crtcs);
-	free(modes);
-	return FALSE;
-    }
-
-    /*
-     * Set initial panning of each output
-     */
-    xf86InitialPanning (scrn);
-	
-    /*
-     * Assign CRTCs to fit output configuration
-     */
-    if (have_outputs && !xf86PickCrtcs (scrn, crtcs, modes, 0, width, height))
-    {
-	free(crtcs);
-	free(modes);
-	return FALSE;
-    }
-    
-    /* XXX override xf86 common frame computation code */
-    
-    scrn->display->frameX0 = 0;
-    scrn->display->frameY0 = 0;
-    
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	xf86CrtcPtr	crtc = config->crtc[c];
-
-	crtc->enabled = FALSE;
-	memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
-	/* Set default gamma for all crtc's. */
-	/* This is done to avoid problems later on with cloned outputs. */
-	xf86CrtcSetInitialGamma(crtc, 1.0, 1.0, 1.0);
-    }
-
-    if (xf86_crtc_supports_gamma(scrn))
-	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated.\n");
-
-    /*
-     * Set initial configuration
-     */
-    for (o = 0; o < config->num_output; o++)
-    {
-	xf86OutputPtr	output = config->output[o];
-	DisplayModePtr	mode = modes[o];
-        xf86CrtcPtr	crtc = crtcs[o];
-
-	if (mode && crtc)
-	{
-	    crtc->desiredMode = *mode;
-	    crtc->desiredRotation = output->initial_rotation;
-	    crtc->desiredX = output->initial_x;
-	    crtc->desiredY = output->initial_y;
-	    crtc->desiredTransformPresent = FALSE;
-	    crtc->enabled = TRUE;
-	    memcpy (&crtc->panningTotalArea,    &output->initialTotalArea,    sizeof(BoxRec));
-	    memcpy (&crtc->panningTrackingArea, &output->initialTrackingArea, sizeof(BoxRec));
-	    memcpy (crtc->panningBorder,        output->initialBorder,        4*sizeof(INT16));
-	    output->crtc = crtc;
-	    if (!xf86OutputSetInitialGamma(output))
-		xf86DrvMsg (scrn->scrnIndex, X_WARNING, "Initial gamma correction for output %s: failed.\n", output->name);
-	} else {
-	    output->crtc = NULL;
-	}
-    }
-
-    if (scrn->display->virtualX == 0)
-    {
-	/*
-	 * Expand virtual size to cover the current config and potential mode
-	 * switches, if the driver can't enlarge the screen later.
-	 */
-	xf86DefaultScreenLimits (scrn, &width, &height, canGrow);
-    
-	if (have_outputs == FALSE) {
-	    if (width < NO_OUTPUT_DEFAULT_WIDTH && height < NO_OUTPUT_DEFAULT_HEIGHT) {
-		width = NO_OUTPUT_DEFAULT_WIDTH;
-		height = NO_OUTPUT_DEFAULT_HEIGHT;
-	    }
-	}
-
-	scrn->display->virtualX = width;
-	scrn->display->virtualY = height;
-    }
-
-    if (width > scrn->virtualX)
-	scrn->virtualX = width;
-    if (height > scrn->virtualY)
-	scrn->virtualY = height;
-
-    /*
-     * Make sure the configuration isn't too small.
-     */
-    if (width < config->minWidth || height < config->minHeight)
-	return FALSE;
-
-    /*
-     * Limit the crtc config to virtual[XY] if the driver can't grow the
-     * desktop.
-     */
-    if (!canGrow)
-    {
-	xf86CrtcSetSizeRange (scrn, config->minWidth, config->minHeight,
-			      width, height);
-    }
-
-    if (have_outputs) {
-	/* Mirror output modes to scrn mode list */
-	xf86SetScrnInfoModes (scrn);
-    } else {
-	/* Clear any existing modes from scrn->modes */
-	while (scrn->modes != NULL)
-	    xf86DeleteMode(&scrn->modes, scrn->modes);
-	scrn->modes = xf86ModesAdd(scrn->modes,
-				   xf86CVTMode(width, height, 60, 0, 0));
-    }
-
-    
-    free(crtcs);
-    free(modes);
-    return TRUE;
-}
-
-/*
- * Check the CRTC we're going to map each output to vs. it's current
- * CRTC.  If they don't match, we have to disable the output and the CRTC
- * since the driver will have to re-route things.
- */
-static void
-xf86PrepareOutputs (ScrnInfoPtr scrn)
-{
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			o;
-
-    for (o = 0; o < config->num_output; o++) {
-	xf86OutputPtr output = config->output[o];
-#if RANDR_GET_CRTC_INTERFACE
-	/* Disable outputs that are unused or will be re-routed */
-	if (!output->funcs->get_crtc ||
-	    output->crtc != (*output->funcs->get_crtc)(output) ||
-	    output->crtc == NULL)
-#endif
-	    (*output->funcs->dpms)(output, DPMSModeOff);
-    }
-}
-
-static void
-xf86PrepareCrtcs (ScrnInfoPtr scrn)
-{
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			c;
-
-    for (c = 0; c < config->num_crtc; c++) {
-#if RANDR_GET_CRTC_INTERFACE
-	xf86CrtcPtr	crtc = config->crtc[c];
-	xf86OutputPtr	output = NULL;
-	uint32_t	desired_outputs = 0, current_outputs = 0;
-	int		o;
-
-	for (o = 0; o < config->num_output; o++) {
-	    output = config->output[o];
-	    if (output->crtc == crtc)
-		desired_outputs |= (1<<o);
-	    /* If we can't tell where it's mapped, force it off */
-	    if (!output->funcs->get_crtc) {
-		desired_outputs = 0;
-		break;
-	    }
-	    if ((*output->funcs->get_crtc)(output) == crtc)
-		current_outputs |= (1<<o);
-	}
-
-	/*
-	 * If mappings are different or the CRTC is unused,
-	 * we need to disable it
-	 */
-	if (desired_outputs != current_outputs ||
-	    !desired_outputs)
-	    (*crtc->funcs->dpms)(crtc, DPMSModeOff);
-#else
-	(*crtc->funcs->dpms)(crtc, DPMSModeOff);
-#endif
-    }
-}
-
-/*
- * Using the desired mode information in each crtc, set
- * modes (used in EnterVT functions, or at server startup)
- */
-
-Bool
-xf86SetDesiredModes (ScrnInfoPtr scrn)
-{
-    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
-    xf86CrtcPtr         crtc = config->crtc[0];
-    int			c;
-
-    /* A driver with this hook will take care of this */
-    if (!crtc->funcs->set_mode_major) {
-	xf86PrepareOutputs(scrn);
-	xf86PrepareCrtcs(scrn);
-    }
-
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	xf86OutputPtr	output = NULL;
-	int		o;
-	RRTransformPtr	transform;
-
-	crtc = config->crtc[c];
-
-	/* Skip disabled CRTCs */
-	if (!crtc->enabled)
-	    continue;
-
-	if (xf86CompatOutput(scrn) && xf86CompatCrtc(scrn) == crtc)
-	    output = xf86CompatOutput(scrn);
-	else
-	{
-	    for (o = 0; o < config->num_output; o++)
-		if (config->output[o]->crtc == crtc)
-		{
-		    output = config->output[o];
-		    break;
-		}
-	}
-	/* paranoia */
-	if (!output)
-	    continue;
-
-	/* Mark that we'll need to re-set the mode for sure */
-	memset(&crtc->mode, 0, sizeof(crtc->mode));
-	if (!crtc->desiredMode.CrtcHDisplay)
-	{
-	    DisplayModePtr  mode = xf86OutputFindClosestMode (output, scrn->currentMode);
-
-	    if (!mode)
-		return FALSE;
-	    crtc->desiredMode = *mode;
-	    crtc->desiredRotation = RR_Rotate_0;
-	    crtc->desiredTransformPresent = FALSE;
-	    crtc->desiredX = 0;
-	    crtc->desiredY = 0;
-	}
-
-	if (crtc->desiredTransformPresent)
-	    transform = &crtc->desiredTransform;
-	else
-	    transform = NULL;
-	if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, crtc->desiredRotation,
-				       transform, crtc->desiredX, crtc->desiredY))
-	    return FALSE;
-    }
-
-    xf86DisableUnusedFunctions(scrn);
-    return TRUE;
-}
-
-/**
- * In the current world order, there are lists of modes per output, which may
- * or may not include the mode that was asked to be set by XFree86's mode
- * selection.  Find the closest one, in the following preference order:
- *
- * - Equality
- * - Closer in size to the requested mode, but no larger
- * - Closer in refresh rate to the requested mode.
- */
-
-DisplayModePtr
-xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired)
-{
-    DisplayModePtr	best = NULL, scan = NULL;
-
-    for (scan = output->probed_modes; scan != NULL; scan = scan->next) 
-    {
-	/* If there's an exact match, we're done. */
-	if (xf86ModesEqual(scan, desired)) {
-	    best = desired;
-	    break;
-	}
-
-	/* Reject if it's larger than the desired mode. */
-	if (scan->HDisplay > desired->HDisplay || 
-	    scan->VDisplay > desired->VDisplay)
-	{
-	    continue;
-	}
-
-	/*
-	 * If we haven't picked a best mode yet, use the first
-	 * one in the size range
-	 */
-	if (best == NULL) 
-	{
-	    best = scan;
-	    continue;
-	}
-
-	/* Find if it's closer to the right size than the current best
-	 * option.
-	 */
-	if ((scan->HDisplay > best->HDisplay &&
-	     scan->VDisplay >= best->VDisplay) ||
-	    (scan->HDisplay >= best->HDisplay &&
-	     scan->VDisplay > best->VDisplay))
-	{
-	    best = scan;
-	    continue;
-	}
-
-	/* Find if it's still closer to the right refresh than the current
-	 * best resolution.
-	 */
-	if (scan->HDisplay == best->HDisplay &&
-	    scan->VDisplay == best->VDisplay &&
-	    (fabs(scan->VRefresh - desired->VRefresh) <
-	     fabs(best->VRefresh - desired->VRefresh))) {
-	    best = scan;
-	}
-    }
-    return best;
-}
-
-/**
- * When setting a mode through XFree86-VidModeExtension or XFree86-DGA,
- * take the specified mode and apply it to the crtc connected to the compat
- * output. Then, find similar modes for the other outputs, as with the
- * InitialConfiguration code above. The goal is to clone the desired
- * mode across all outputs that are currently active.
- */
-
-Bool
-xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
-    Bool		ok = TRUE;
-    xf86OutputPtr	compat_output;
-    DisplayModePtr	compat_mode = NULL;
-    int			c;
-
-    /*
-     * Let the compat output drive the final mode selection
-     */
-    compat_output = xf86CompatOutput(pScrn);
-    if (compat_output)
-	compat_mode = xf86OutputFindClosestMode (compat_output, desired);
-    if (compat_mode)
-	desired = compat_mode;
-    
-    for (c = 0; c < config->num_crtc; c++)
-    {
-	xf86CrtcPtr	crtc = config->crtc[c];
-	DisplayModePtr	crtc_mode = NULL;
-	int		o;
-
-	if (!crtc->enabled)
-	    continue;
-	
-	for (o = 0; o < config->num_output; o++)
-	{
-	    xf86OutputPtr   output = config->output[o];
-	    DisplayModePtr  output_mode;
-
-	    /* skip outputs not on this crtc */
-	    if (output->crtc != crtc)
-		continue;
-	    
-	    if (crtc_mode)
-	    {
-		output_mode = xf86OutputFindClosestMode (output, crtc_mode);
-		if (output_mode != crtc_mode)
-		    output->crtc = NULL;
-	    }
-	    else
-		crtc_mode = xf86OutputFindClosestMode (output, desired);
-	}
-	if (!crtc_mode)
-	{
-	    crtc->enabled = FALSE;
-	    continue;
-	}
-	if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0))
-	    ok = FALSE;
-	else
-	{
-	    crtc->desiredMode = *crtc_mode;
-	    crtc->desiredRotation = rotation;
-	    crtc->desiredTransformPresent = FALSE;
-	    crtc->desiredX = 0;
-	    crtc->desiredY = 0;
-	}
-    }
-    xf86DisableUnusedFunctions(pScrn);
-#ifdef RANDR_12_INTERFACE
-    xf86RandR12TellChanged (pScrn->pScreen);
-#endif
-    return ok;
-}
-
-
-/**
- * Set the DPMS power mode of all outputs and CRTCs.
- *
- * If the new mode is off, it will turn off outputs and then CRTCs.
- * Otherwise, it will affect CRTCs before outputs.
- */
-void
-xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			i;
-
-    if (!scrn->vtSema)
-	return;
-
-    if (mode == DPMSModeOff) {
-	for (i = 0; i < config->num_output; i++) {
-	    xf86OutputPtr output = config->output[i];
-	    if (output->crtc != NULL)
-		(*output->funcs->dpms) (output, mode);
-	}
-    }
-
-    for (i = 0; i < config->num_crtc; i++) {
-	xf86CrtcPtr crtc = config->crtc[i];
-	if (crtc->enabled)
-	    (*crtc->funcs->dpms) (crtc, mode);
-    }
-
-    if (mode != DPMSModeOff) {
-	for (i = 0; i < config->num_output; i++) {
-	    xf86OutputPtr output = config->output[i];
-	    if (output->crtc != NULL)
-		(*output->funcs->dpms) (output, mode);
-	}
-    }
-}
-
-/**
- * Implement the screensaver by just calling down into the driver DPMS hooks.
- *
- * Even for monitors with no DPMS support, by the definition of our DPMS hooks,
- * the outputs will still get disabled (blanked).
- */
-Bool
-xf86SaveScreen(ScreenPtr pScreen, int mode)
-{
-    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
-    if (xf86IsUnblank(mode))
-	xf86DPMSSet(pScrn, DPMSModeOn, 0);
-    else
-	xf86DPMSSet(pScrn, DPMSModeOff, 0);
-
-    return TRUE;
-}
-
-/**
- * Disable all inactive crtcs and outputs
- */
-void
-xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    int			o, c;
-
-    for (o = 0; o < xf86_config->num_output; o++) 
-    {
-	xf86OutputPtr  output = xf86_config->output[o];
-	if (!output->crtc) 
-	    (*output->funcs->dpms)(output, DPMSModeOff);
-    }
-
-    for (c = 0; c < xf86_config->num_crtc; c++) 
-    {
-	xf86CrtcPtr crtc = xf86_config->crtc[c];
-
-	if (!crtc->enabled) 
-	{
-	    crtc->funcs->dpms(crtc, DPMSModeOff);
-	    memset(&crtc->mode, 0, sizeof(crtc->mode));
-	    xf86RotateDestroy(crtc);
-	    crtc->active = FALSE;
-	}
-    }
-    if (pScrn->pScreen)
-	xf86_crtc_notify(pScrn->pScreen);
-    if (pScrn->ModeSet)
-	pScrn->ModeSet(pScrn);
-}
-
-#ifdef RANDR_12_INTERFACE
-
-#define EDID_ATOM_NAME		"EDID"
-
-/**
- * Set the RandR EDID property
- */
-static void
-xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
-{
-    Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME) - 1, TRUE);
-
-    /* This may get called before the RandR resources have been created */
-    if (output->randr_output == NULL)
-	return;
-
-    if (data_len != 0) {
-	RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
-			       PropModeReplace, data_len, data, FALSE, TRUE);
-    } else {
-	RRDeleteOutputProperty(output->randr_output, edid_atom);
-    }
-}
-
-#endif
-
-/* Pull out a phyiscal size from a detailed timing if available. */
-struct det_phySize_parameter {
-    xf86OutputPtr output;
-    ddc_quirk_t quirks;
-    Bool ret;
-};
-
-static void  handle_detailed_physical_size(struct detailed_monitor_section
-		                          *det_mon, void *data)
-{
-    struct det_phySize_parameter *p;
-    p = (struct det_phySize_parameter *)data;
-
-    if (p->ret == TRUE )
-        return ;
-
-    xf86DetTimingApplyQuirks(det_mon, p->quirks,
-                             p->output->MonInfo->features.hsize,
-                             p->output->MonInfo->features.vsize);
-    if (det_mon->type == DT &&
-        det_mon->section.d_timings.h_size != 0 &&
-        det_mon->section.d_timings.v_size != 0) {
-
-        p->output->mm_width = det_mon->section.d_timings.h_size;
-        p->output->mm_height = det_mon->section.d_timings.v_size;
-        p->ret = TRUE;
-    }
-}
-
-/**
- * Set the EDID information for the specified output
- */
-void
-xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
-{
-    ScrnInfoPtr		scrn = output->scrn;
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    Bool		debug_modes = config->debug_modes || xf86Initialising;
-#ifdef RANDR_12_INTERFACE
-    int			size;
-#endif
-    
-    free(output->MonInfo);
-    
-    output->MonInfo = edid_mon;
-    output->mm_width = 0;
-    output->mm_height = 0;
-
-    if (debug_modes) {
-	xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n",
-		   output->name);
-	xf86PrintEDID(edid_mon);
-    }
-
-    /* Set the DDC properties for the 'compat' output */
-    if (output == xf86CompatOutput(scrn))
-        xf86SetDDCproperties(scrn, edid_mon);
-
-#ifdef RANDR_12_INTERFACE
-    /* Set the RandR output properties */
-    size = 0;
-    if (edid_mon)
-    {
-	if (edid_mon->ver.version == 1) {
-	    size = 128;
-	    if (edid_mon->flags & EDID_COMPLETE_RAWDATA)
-		size += edid_mon->no_sections * 128;
-	} else if (edid_mon->ver.version == 2)
-	    size = 256;
-    }
-    xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size);
-#endif
-
-    if (edid_mon) {
-
-        struct det_phySize_parameter p;
-        p.output = output;
-        p.quirks = xf86DDCDetectQuirks(scrn->scrnIndex,edid_mon, FALSE);
-        p.ret = FALSE;
-        xf86ForEachDetailedBlock(edid_mon,
-                                 handle_detailed_physical_size, &p);
-
-	/* if no mm size is available from a detailed timing, check the max size field */
-	if ((!output->mm_width || !output->mm_height) &&
-	    (edid_mon->features.hsize && edid_mon->features.vsize))
-	{
-	    output->mm_width = edid_mon->features.hsize * 10;
-	    output->mm_height = edid_mon->features.vsize * 10;
-	}
-    }
-}
-
-/**
- * Return the list of modes supported by the EDID information
- * stored in 'output'
- */
-DisplayModePtr
-xf86OutputGetEDIDModes (xf86OutputPtr output)
-{
-    ScrnInfoPtr	scrn = output->scrn;
-    xf86MonPtr	edid_mon = output->MonInfo;
-
-    if (!edid_mon)
-	return NULL;
-    return xf86DDCGetModes(scrn->scrnIndex, edid_mon);
-}
-
-/* maybe we should care about DDC1?  meh. */
-xf86MonPtr
-xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
-{
-    ScrnInfoPtr	scrn = output->scrn;
-    xf86MonPtr mon;
-
-    mon = xf86DoEEDID(scrn->scrnIndex, pDDCBus, TRUE);
-    if (mon)
-        xf86DDCApplyQuirks(scrn->scrnIndex, mon);
-
-    return mon;
-}
-
-static char *_xf86ConnectorNames[] = {
-					"None", "VGA", "DVI-I", "DVI-D",
-					"DVI-A", "Composite", "S-Video",
-					"Component", "LFP", "Proprietary",
-					"HDMI", "DisplayPort",
-				     };
-char *
-xf86ConnectorGetName(xf86ConnectorType connector)
-{
-    return _xf86ConnectorNames[connector];
-}
-
-static void
-x86_crtc_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
-{
-    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
-    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
-    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
-    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
-
-    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
-	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
-}
-
-static void
-x86_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
-{
-    if (crtc->enabled) {
-	crtc_box->x1 = crtc->x;
-	crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
-	crtc_box->y1 = crtc->y;
-	crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
-    } else
-	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
-}
-
-static int
-xf86_crtc_box_area(BoxPtr box)
-{
-    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
-}
-
-/*
- * Return the crtc covering 'box'. If two crtcs cover a portion of
- * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
- * with greater coverage
- */
-
-static xf86CrtcPtr
-xf86_covering_crtc(ScrnInfoPtr pScrn,
-		   BoxPtr      box,
-		   xf86CrtcPtr desired,
-		   BoxPtr      crtc_box_ret)
-{
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    xf86CrtcPtr		crtc, best_crtc;
-    int			coverage, best_coverage;
-    int			c;
-    BoxRec		crtc_box, cover_box;
-
-    best_crtc = NULL;
-    best_coverage = 0;
-    crtc_box_ret->x1 = 0;
-    crtc_box_ret->x2 = 0;
-    crtc_box_ret->y1 = 0;
-    crtc_box_ret->y2 = 0;
-    for (c = 0; c < xf86_config->num_crtc; c++) {
-	crtc = xf86_config->crtc[c];
-	x86_crtc_box(crtc, &crtc_box);
-	x86_crtc_box_intersect(&cover_box, &crtc_box, box);
-	coverage = xf86_crtc_box_area(&cover_box);
-	if (coverage && crtc == desired) {
-	    *crtc_box_ret = crtc_box;
-	    return crtc;
-	} else if (coverage > best_coverage) {
-	    *crtc_box_ret = crtc_box;
-	    best_crtc = crtc;
-	    best_coverage = coverage;
-	}
-    }
-    return best_crtc;
-}
-
-/*
- * For overlay video, compute the relevant CRTC and
- * clip video to that.
- *
- * returning FALSE means there was a memory failure of some kind,
- * not that the video shouldn't be displayed
- */
-
-Bool
-xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
-			    xf86CrtcPtr *crtc_ret,
-			    xf86CrtcPtr desired_crtc,
-			    BoxPtr      dst,
-			    INT32	*xa,
-			    INT32	*xb,
-			    INT32	*ya,
-			    INT32	*yb,
-			    RegionPtr   reg,
-			    INT32	width,
-			    INT32	height)
-{
-    Bool	ret;
-    RegionRec	crtc_region_local;
-    RegionPtr	crtc_region = reg;
-    
-    if (crtc_ret) {
-	BoxRec		crtc_box;
-	xf86CrtcPtr	crtc = xf86_covering_crtc(pScrn, dst,
-						  desired_crtc,
-						  &crtc_box);
-
-	if (crtc) {
-	    RegionInit(&crtc_region_local, &crtc_box, 1);
-	    crtc_region = &crtc_region_local;
-	    RegionIntersect(crtc_region, crtc_region, reg);
-	}
-	*crtc_ret = crtc;
-    }
-
-    ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb, 
-				crtc_region, width, height);
-
-    if (crtc_region != reg)
-	RegionUninit(&crtc_region_local);
-
-    return ret;
-}
-
-xf86_crtc_notify_proc_ptr
-xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new)
-{
-    if (xf86CrtcConfigPrivateIndex != -1)
-    {
-	ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
-	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-	xf86_crtc_notify_proc_ptr	old;
-	
-	old = config->xf86_crtc_notify;
-	config->xf86_crtc_notify = new;
-	return old;
-    }
-    return NULL;
-}
-
-void
-xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old)
-{
-    if (xf86CrtcConfigPrivateIndex != -1)
-    {
-	ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
-	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    
-	config->xf86_crtc_notify = old;
-    }
-}
-
-void
-xf86_crtc_notify(ScreenPtr screen)
-{
-    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-    
-    if (config->xf86_crtc_notify)
-	config->xf86_crtc_notify(screen);
-}
-
-Bool
-xf86_crtc_supports_gamma(ScrnInfoPtr pScrn)
-{
-    if (xf86CrtcConfigPrivateIndex != -1) {
-	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-	xf86CrtcPtr crtc;
-
-	/* for multiple drivers loaded we need this */
-	if (!xf86_config)
-		return FALSE;
-	if (xf86_config->num_crtc == 0)
-	    return FALSE;
-	crtc = xf86_config->crtc[0];
-
-	return crtc->funcs->gamma_set != NULL;
-    }
-
-    return FALSE;
-}
+/*
+ * Copyright © 2006 Keith Packard
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include "xf86Crtc.h"
+#include "xf86Modes.h"
+#include "xf86Priv.h"
+#include "xf86RandR12.h"
+#include "X11/extensions/render.h"
+#include "X11/extensions/dpmsconst.h"
+#include "X11/Xatom.h"
+#include "picturestr.h"
+
+#include "xf86xv.h"
+
+#define NO_OUTPUT_DEFAULT_WIDTH 1024
+#define NO_OUTPUT_DEFAULT_HEIGHT 768
+/*
+ * Initialize xf86CrtcConfig structure
+ */
+
+int xf86CrtcConfigPrivateIndex = -1;
+
+void
+xf86CrtcConfigInit (ScrnInfoPtr scrn,
+		    const xf86CrtcConfigFuncsRec *funcs)
+{
+    xf86CrtcConfigPtr	config;
+    
+    if (xf86CrtcConfigPrivateIndex == -1)
+	xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+    config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
+
+    config->funcs = funcs;
+
+    scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
+}
+ 
+void
+xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
+		      int minWidth, int minHeight,
+		      int maxWidth, int maxHeight)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+
+    config->minWidth = minWidth;
+    config->minHeight = minHeight;
+    config->maxWidth = maxWidth;
+    config->maxHeight = maxHeight;
+}
+
+/*
+ * Crtc functions
+ */
+xf86CrtcPtr
+xf86CrtcCreate (ScrnInfoPtr		scrn,
+		const xf86CrtcFuncsRec	*funcs)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CrtcPtr		crtc, *crtcs;
+
+    crtc = calloc(sizeof (xf86CrtcRec), 1);
+    if (!crtc)
+	return NULL;
+    crtc->version = XF86_CRTC_VERSION;
+    crtc->scrn = scrn;
+    crtc->funcs = funcs;
+#ifdef RANDR_12_INTERFACE
+    crtc->randr_crtc = NULL;
+#endif
+    crtc->rotation = RR_Rotate_0;
+    crtc->desiredRotation = RR_Rotate_0;
+    pixman_transform_init_identity (&crtc->crtc_to_framebuffer);
+    pixman_f_transform_init_identity (&crtc->f_crtc_to_framebuffer);
+    pixman_f_transform_init_identity (&crtc->f_framebuffer_to_crtc);
+    crtc->filter = NULL;
+    crtc->params = NULL;
+    crtc->nparams = 0;
+    crtc->filter_width = 0;
+    crtc->filter_height = 0;
+    crtc->transform_in_use = FALSE;
+    crtc->transformPresent = FALSE;
+    crtc->desiredTransformPresent = FALSE;
+    memset (&crtc->bounds, '\0', sizeof (crtc->bounds));
+
+    /* Preallocate gamma at a sensible size. */
+    crtc->gamma_size = 256;
+    crtc->gamma_red = malloc(3 * crtc->gamma_size * sizeof (CARD16));
+    if (!crtc->gamma_red) {
+	free(crtc);
+	return NULL;
+    }
+    crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
+    crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
+
+    if (xf86_config->crtc)
+	crtcs = realloc(xf86_config->crtc,
+			  (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
+    else
+	crtcs = malloc((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
+    if (!crtcs)
+    {
+	free(crtc);
+	return NULL;
+    }
+    xf86_config->crtc = crtcs;
+    xf86_config->crtc[xf86_config->num_crtc++] = crtc;
+    return crtc;
+}
+
+void
+xf86CrtcDestroy (xf86CrtcPtr crtc)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+    int			c;
+    
+    (*crtc->funcs->destroy) (crtc);
+    for (c = 0; c < xf86_config->num_crtc; c++)
+	if (xf86_config->crtc[c] == crtc)
+	{
+	    memmove (&xf86_config->crtc[c],
+		     &xf86_config->crtc[c+1],
+		     ((xf86_config->num_crtc - (c + 1)) * sizeof(void*)));
+	    xf86_config->num_crtc--;
+	    break;
+	}
+    free(crtc->params);
+    free(crtc->gamma_red);
+    free(crtc);
+}
+
+
+/**
+ * Return whether any outputs are connected to the specified pipe
+ */
+
+Bool
+xf86CrtcInUse (xf86CrtcPtr crtc)
+{
+    ScrnInfoPtr		pScrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			o;
+    
+    for (o = 0; o < xf86_config->num_output; o++)
+	if (xf86_config->output[o]->crtc == crtc)
+	    return TRUE;
+    return FALSE;
+}
+
+void
+xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen)
+{
+    int			subpixel_order = SubPixelUnknown;
+    Bool		has_none = FALSE;
+    ScrnInfoPtr		scrn = xf86Screens[pScreen->myNum];
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c, o;
+
+    for (c = 0; c < xf86_config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+	
+	for (o = 0; o < xf86_config->num_output; o++)
+	{
+	    xf86OutputPtr   output = xf86_config->output[o];
+
+	    if (output->crtc == crtc)
+	    {
+		switch (output->subpixel_order) {
+		case SubPixelNone:
+		    has_none = TRUE;
+		    break;
+		case SubPixelUnknown:
+		    break;
+		default:
+		    subpixel_order = output->subpixel_order;
+		    break;
+		}
+	    }
+	    if (subpixel_order != SubPixelUnknown)
+		break;
+	}
+	if (subpixel_order != SubPixelUnknown)
+	{
+	    static const int circle[4] = {
+		SubPixelHorizontalRGB,
+		SubPixelVerticalRGB,
+		SubPixelHorizontalBGR,
+		SubPixelVerticalBGR,
+	    };
+	    int	rotate;
+	    int c;
+	    for (rotate = 0; rotate < 4; rotate++)
+		if (crtc->rotation & (1 << rotate))
+		    break;
+	    for (c = 0; c < 4; c++)
+		if (circle[c] == subpixel_order)
+		    break;
+	    c = (c + rotate) & 0x3;
+	    if ((crtc->rotation & RR_Reflect_X) && !(c & 1))
+		c ^= 2;
+	    if ((crtc->rotation & RR_Reflect_Y) && (c & 1))
+		c ^= 2;
+	    subpixel_order = circle[c];
+	    break;
+	}
+    }
+    if (subpixel_order == SubPixelUnknown && has_none)
+	subpixel_order = SubPixelNone;
+    PictureSetSubpixelOrder (pScreen, subpixel_order);
+}
+
+/**
+ * Sets the given video mode on the given crtc
+ */
+Bool
+xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+			  RRTransformPtr transform, int x, int y)
+{
+    ScrnInfoPtr		scrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			i;
+    Bool		ret = FALSE;
+    Bool		didLock = FALSE;
+    DisplayModePtr	adjusted_mode;
+    DisplayModeRec	saved_mode;
+    int			saved_x, saved_y;
+    Rotation		saved_rotation;
+    RRTransformRec	saved_transform;
+    Bool		saved_transform_present;
+
+    crtc->enabled = xf86CrtcInUse (crtc);
+
+    /* We only hit this if someone explicitly sends a "disabled" modeset. */
+    if (!crtc->enabled)
+    {
+	/* Check everything for stuff that should be off. */
+	xf86DisableUnusedFunctions(scrn);
+	return TRUE;
+    }
+
+    adjusted_mode = xf86DuplicateMode(mode);
+
+
+    saved_mode = crtc->mode;
+    saved_x = crtc->x;
+    saved_y = crtc->y;
+    saved_rotation = crtc->rotation;
+    if (crtc->transformPresent) {
+	RRTransformInit (&saved_transform);
+	RRTransformCopy (&saved_transform, &crtc->transform);
+    }
+    saved_transform_present = crtc->transformPresent;
+
+    /* Update crtc values up front so the driver can rely on them for mode
+     * setting.
+     */
+    crtc->mode = *mode;
+    crtc->x = x;
+    crtc->y = y;
+    crtc->rotation = rotation;
+    if (transform) {
+	RRTransformCopy (&crtc->transform, transform);
+	crtc->transformPresent = TRUE;
+    } else
+	crtc->transformPresent = FALSE;
+
+    if (crtc->funcs->set_mode_major) {
+	ret = crtc->funcs->set_mode_major(crtc, mode, rotation, x, y);
+	goto done;
+    }
+
+    didLock = crtc->funcs->lock (crtc);
+    /* Pass our mode to the outputs and the CRTC to give them a chance to
+     * adjust it according to limitations or output properties, and also
+     * a chance to reject the mode entirely.
+     */
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+
+	if (output->crtc != crtc)
+	    continue;
+
+	if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
+	    goto done;
+	}
+    }
+
+    if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
+	goto done;
+    }
+
+    if (!xf86CrtcRotate (crtc))
+	goto done;
+
+    /* Prepare the outputs and CRTCs before setting the mode. */
+    for (i = 0; i < xf86_config->num_output; i++) {
+	xf86OutputPtr output = xf86_config->output[i];
+
+	if (output->crtc != crtc)
+	    continue;
+
+	/* Disable the output as the first thing we do. */
+	output->funcs->prepare(output);
+    }
+
+    crtc->funcs->prepare(crtc);
+
+    /* Set up the DPLL and any output state that needs to adjust or depend
+     * on the DPLL.
+     */
+    crtc->funcs->mode_set(crtc, mode, adjusted_mode, crtc->x, crtc->y);
+    for (i = 0; i < xf86_config->num_output; i++) 
+    {
+	xf86OutputPtr output = xf86_config->output[i];
+	if (output->crtc == crtc)
+	    output->funcs->mode_set(output, mode, adjusted_mode);
+    }
+
+    /* Only upload when needed, to avoid unneeded delays. */
+    if (!crtc->active && crtc->funcs->gamma_set)
+	crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
+                                            crtc->gamma_blue, crtc->gamma_size);
+
+    /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
+    crtc->funcs->commit(crtc);
+    for (i = 0; i < xf86_config->num_output; i++) 
+    {
+	xf86OutputPtr output = xf86_config->output[i];
+	if (output->crtc == crtc)
+	    output->funcs->commit(output);
+    }
+
+    ret = TRUE;
+
+done:
+    if (ret) {
+	crtc->active = TRUE;
+	if (scrn->pScreen)
+	    xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
+	if (scrn->ModeSet)
+	    scrn->ModeSet(scrn);
+    } else {
+	crtc->x = saved_x;
+	crtc->y = saved_y;
+	crtc->rotation = saved_rotation;
+	crtc->mode = saved_mode;
+	if (saved_transform_present)
+	    RRTransformCopy (&crtc->transform, &saved_transform);
+	crtc->transformPresent = saved_transform_present;
+    }
+
+    free(adjusted_mode->name);
+    free(adjusted_mode);
+
+    if (didLock)
+	crtc->funcs->unlock (crtc);
+
+    return ret;
+}
+
+/**
+ * Sets the given video mode on the given crtc, but without providing
+ * a transform
+ */
+Bool
+xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+		 int x, int y)
+{
+    return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y);
+}
+
+/**
+ * Pans the screen, does not change the mode
+ */
+void
+xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
+{
+    ScrnInfoPtr scrn = crtc->scrn;
+
+    crtc->x = x;
+    crtc->y = y;
+    if (crtc->funcs->set_origin) {
+	if (!xf86CrtcRotate (crtc))
+	    return;
+	crtc->funcs->set_origin (crtc, x, y);
+	if (scrn->ModeSet)
+	    scrn->ModeSet(scrn);
+    }
+    else
+	xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y);
+}
+
+/*
+ * Output functions
+ */
+
+extern XF86ConfigPtr xf86configptr;
+
+typedef enum {
+    OPTION_PREFERRED_MODE,
+    OPTION_POSITION,
+    OPTION_BELOW,
+    OPTION_RIGHT_OF,
+    OPTION_ABOVE,
+    OPTION_LEFT_OF,
+    OPTION_ENABLE,
+    OPTION_DISABLE,
+    OPTION_MIN_CLOCK,
+    OPTION_MAX_CLOCK,
+    OPTION_IGNORE,
+    OPTION_ROTATE,
+    OPTION_PANNING,
+    OPTION_PRIMARY,
+    OPTION_DEFAULT_MODES,
+} OutputOpts;
+
+static OptionInfoRec xf86OutputOptions[] = {
+    {OPTION_PREFERRED_MODE, "PreferredMode",	OPTV_STRING,  {0}, FALSE },
+    {OPTION_POSITION,	    "Position",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_BELOW,	    "Below",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_RIGHT_OF,	    "RightOf",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_ABOVE,	    "Above",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_LEFT_OF,	    "LeftOf",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_ENABLE,	    "Enable",		OPTV_BOOLEAN, {0}, FALSE },
+    {OPTION_DISABLE,	    "Disable",		OPTV_BOOLEAN, {0}, FALSE },
+    {OPTION_MIN_CLOCK,	    "MinClock",		OPTV_FREQ,    {0}, FALSE },
+    {OPTION_MAX_CLOCK,	    "MaxClock",		OPTV_FREQ,    {0}, FALSE },
+    {OPTION_IGNORE,	    "Ignore",		OPTV_BOOLEAN, {0}, FALSE },
+    {OPTION_ROTATE,	    "Rotate",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_PANNING,	    "Panning",		OPTV_STRING,  {0}, FALSE },
+    {OPTION_PRIMARY,	    "Primary",		OPTV_BOOLEAN, {0}, FALSE },
+    {OPTION_DEFAULT_MODES,  "DefaultModes",	OPTV_BOOLEAN, {0}, FALSE },
+    {-1,		    NULL,		OPTV_NONE,    {0}, FALSE },
+};
+
+enum {
+    OPTION_MODEDEBUG,
+};
+
+static OptionInfoRec xf86DeviceOptions[] = {
+    {OPTION_MODEDEBUG,	    "ModeDebug",	OPTV_BOOLEAN,  {0}, FALSE },
+    {-1,		    NULL,		OPTV_NONE,    {0}, FALSE },
+};
+
+static void
+xf86OutputSetMonitor (xf86OutputPtr output)
+{
+    char    *option_name;
+    char    *monitor;
+
+    if (!output->name)
+	return;
+
+    free(output->options);
+
+    output->options = xnfalloc (sizeof (xf86OutputOptions));
+    memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions));
+
+    XNFasprintf(&option_name, "monitor-%s", output->name);
+    monitor = xf86findOptionValue (output->scrn->options, option_name);
+    if (!monitor)
+	monitor = output->name;
+    else
+	xf86MarkOptionUsedByName (output->scrn->options, option_name);
+    free(option_name);
+    output->conf_monitor = xf86findMonitor (monitor,
+					    xf86configptr->conf_monitor_lst);
+    /*
+     * Find the monitor section of the screen and use that
+     */
+    if (!output->conf_monitor && output->use_screen_monitor)
+	output->conf_monitor = xf86findMonitor (output->scrn->monitor->id,
+						xf86configptr->conf_monitor_lst);
+    if (output->conf_monitor)
+    {
+	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+		    "Output %s using monitor section %s\n",
+		    output->name, output->conf_monitor->mon_identifier);
+	xf86ProcessOptions (output->scrn->scrnIndex,
+			    output->conf_monitor->mon_option_lst,
+			    output->options);
+    }
+    else
+	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+		    "Output %s has no monitor section\n",
+		    output->name);
+}
+
+static Bool
+xf86OutputEnabled (xf86OutputPtr output, Bool strict)
+{
+    Bool    enable, disable;
+
+    /* check to see if this output was enabled in the config file */
+    if (xf86GetOptValBool (output->options, OPTION_ENABLE, &enable) && enable)
+    {
+	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+		    "Output %s enabled by config file\n", output->name);
+	return TRUE;
+    }
+    /* or if this output was disabled in the config file */
+    if (xf86GetOptValBool (output->options, OPTION_DISABLE, &disable) && disable)
+    {
+	xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+		    "Output %s disabled by config file\n", output->name);
+	return FALSE;
+    }
+
+    /* If not, try to only light up the ones we know are connected */
+    if (strict) {
+	enable = output->status == XF86OutputStatusConnected;
+    }
+    /* But if that fails, try to light up even outputs we're unsure of */
+    else {
+	enable = output->status != XF86OutputStatusDisconnected;
+    }
+
+    xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+    	    "Output %s %sconnected\n", output->name, enable ? "" : "dis");
+    return enable;
+}
+
+static Bool
+xf86OutputIgnored (xf86OutputPtr    output)
+{
+    return xf86ReturnOptValBool (output->options, OPTION_IGNORE, FALSE);
+}
+
+static char *direction[4] = {
+    "normal", 
+    "left", 
+    "inverted", 
+    "right"
+};
+
+static Rotation
+xf86OutputInitialRotation (xf86OutputPtr output)
+{
+    char    *rotate_name = xf86GetOptValString (output->options, 
+						OPTION_ROTATE);
+    int	    i;
+
+    if (!rotate_name) {
+	if (output->initial_rotation)
+	    return output->initial_rotation;
+	return RR_Rotate_0;
+    }
+    
+    for (i = 0; i < 4; i++)
+	if (xf86nameCompare (direction[i], rotate_name) == 0)
+	    return 1 << i;
+    return RR_Rotate_0;
+}
+
+xf86OutputPtr
+xf86OutputCreate (ScrnInfoPtr		    scrn,
+		  const xf86OutputFuncsRec  *funcs,
+		  const char		    *name)
+{
+    xf86OutputPtr	output, *outputs;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			len;
+    Bool		primary;
+
+    if (name)
+	len = strlen (name) + 1;
+    else
+	len = 0;
+
+    output = calloc(sizeof (xf86OutputRec) + len, 1);
+    if (!output)
+	return NULL;
+    output->scrn = scrn;
+    output->funcs = funcs;
+    if (name)
+    {
+	output->name = (char *) (output + 1);
+	strcpy (output->name, name);
+    }
+    output->subpixel_order = SubPixelUnknown;
+    /*
+     * Use the old per-screen monitor section for the first output
+     */
+    output->use_screen_monitor = (xf86_config->num_output == 0);
+#ifdef RANDR_12_INTERFACE
+    output->randr_output = NULL;
+#endif
+    if (name)
+    {
+	xf86OutputSetMonitor (output);
+	if (xf86OutputIgnored (output))
+	{
+	    free(output);
+	    return FALSE;
+	}
+    }
+    
+    
+    if (xf86_config->output)
+	outputs = realloc(xf86_config->output,
+			  (xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
+    else
+	outputs = malloc((xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
+    if (!outputs)
+    {
+	free(output);
+	return NULL;
+    }
+
+    xf86_config->output = outputs;
+
+    if (xf86GetOptValBool (output->options, OPTION_PRIMARY, &primary) && primary)
+    {
+	memmove(xf86_config->output + 1, xf86_config->output,
+		xf86_config->num_output * sizeof (xf86OutputPtr));
+	xf86_config->output[0] = output;
+    }
+    else
+    {
+	xf86_config->output[xf86_config->num_output] = output;
+    }
+
+    xf86_config->num_output++;
+
+    return output;
+}
+
+Bool
+xf86OutputRename (xf86OutputPtr output, const char *name)
+{
+    char    *newname = strdup(name);
+    
+    if (!newname)
+	return FALSE;	/* so sorry... */
+    
+    if (output->name && output->name != (char *) (output + 1))
+	free(output->name);
+    output->name = newname;
+    xf86OutputSetMonitor (output);
+    if (xf86OutputIgnored (output))
+	return FALSE;
+    return TRUE;
+}
+
+void
+xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor)
+{
+    if (use_screen_monitor != output->use_screen_monitor)
+    {
+	output->use_screen_monitor = use_screen_monitor;
+	xf86OutputSetMonitor (output);
+    }
+}
+
+void
+xf86OutputDestroy (xf86OutputPtr output)
+{
+    ScrnInfoPtr		scrn = output->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o;
+    
+    (*output->funcs->destroy) (output);
+    while (output->probed_modes)
+	xf86DeleteMode (&output->probed_modes, output->probed_modes);
+    for (o = 0; o < xf86_config->num_output; o++)
+	if (xf86_config->output[o] == output)
+	{
+	    memmove (&xf86_config->output[o],
+		     &xf86_config->output[o+1],
+		     ((xf86_config->num_output - (o + 1)) * sizeof(void*)));
+	    xf86_config->num_output--;
+	    break;
+	}
+    if (output->name && output->name != (char *) (output + 1))
+	free(output->name);
+    free(output);
+}
+
+/*
+ * Called during CreateScreenResources to hook up RandR
+ */
+static Bool
+xf86CrtcCreateScreenResources (ScreenPtr screen)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+
+    screen->CreateScreenResources = config->CreateScreenResources;
+    
+    if (!(*screen->CreateScreenResources)(screen))
+	return FALSE;
+
+    if (!xf86RandR12CreateScreenResources (screen))
+	return FALSE;
+
+    return TRUE;
+}
+
+/*
+ * Clean up config on server reset
+ */
+static Bool
+xf86CrtcCloseScreen (int index, ScreenPtr screen)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o, c;
+    
+    screen->CloseScreen = config->CloseScreen;
+
+    xf86RotateCloseScreen (screen);
+
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	output->randr_output = NULL;
+    }
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	xf86CrtcPtr	crtc = config->crtc[c];
+
+	crtc->randr_crtc = NULL;
+    }
+    xf86RandR12CloseScreen (screen);
+
+    return screen->CloseScreen (index, screen);
+}
+
+/*
+ * Called at ScreenInit time to set up
+ */
+#ifdef RANDR_13_INTERFACE
+int
+#else
+Bool
+#endif
+xf86CrtcScreenInit (ScreenPtr screen)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    /* Rotation */
+    xf86DrvMsg(scrn->scrnIndex, X_INFO, "RandR 1.2 enabled, ignore the following RandR disabled message.\n");
+    xf86DisableRandR(); /* Disable old RandR extension support */
+    xf86RandR12Init (screen);
+
+    /* support all rotations if every crtc has the shadow alloc funcs */
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	xf86CrtcPtr crtc = config->crtc[c];
+	if (!crtc->funcs->shadow_allocate || !crtc->funcs->shadow_create)
+	    break;
+    }
+    if (c == config->num_crtc)
+    {
+	xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 |
+				 RR_Rotate_180 | RR_Rotate_270 |
+				 RR_Reflect_X | RR_Reflect_Y);
+	xf86RandR12SetTransformSupport (screen, TRUE);
+    }
+    else
+    {
+	xf86RandR12SetRotations (screen, RR_Rotate_0);
+	xf86RandR12SetTransformSupport (screen, FALSE);
+    }
+    
+    /* Wrap CreateScreenResources so we can initialize the RandR code */
+    config->CreateScreenResources = screen->CreateScreenResources;
+    screen->CreateScreenResources = xf86CrtcCreateScreenResources;
+
+    config->CloseScreen = screen->CloseScreen;
+    screen->CloseScreen = xf86CrtcCloseScreen;
+    
+#ifdef XFreeXDGA
+    _xf86_di_dga_init_internal(screen);
+#endif
+#ifdef RANDR_13_INTERFACE
+    return RANDR_INTERFACE_VERSION;
+#else
+    return TRUE;
+#endif
+}
+
+static DisplayModePtr
+xf86DefaultMode (xf86OutputPtr output, int width, int height)
+{
+    DisplayModePtr  target_mode = NULL;
+    DisplayModePtr  mode;
+    int		    target_diff = 0;
+    int		    target_preferred = 0;
+    int		    mm_height;
+    
+    mm_height = output->mm_height;
+    if (!mm_height)
+	mm_height = (768 * 25.4) / DEFAULT_DPI;
+    /*
+     * Pick a mode closest to DEFAULT_DPI
+     */
+    for (mode = output->probed_modes; mode; mode = mode->next)
+    {
+	int	    dpi;
+	int	    preferred = (((mode->type & M_T_PREFERRED) != 0) +
+				 ((mode->type & M_T_USERPREF) != 0));
+	int	    diff;
+
+	if (xf86ModeWidth (mode, output->initial_rotation) > width ||
+	    xf86ModeHeight (mode, output->initial_rotation) > height)
+	    continue;
+	
+	/* yes, use VDisplay here, not xf86ModeHeight */
+	dpi = (mode->VDisplay * 254) / (mm_height * 10);
+	diff = dpi - DEFAULT_DPI;
+	diff = diff < 0 ? -diff : diff;
+	if (target_mode == NULL || (preferred > target_preferred) ||
+	    (preferred == target_preferred && diff < target_diff))
+	{
+	    target_mode = mode;
+	    target_diff = diff;
+	    target_preferred = preferred;
+	}
+    }
+    return target_mode;
+}
+
+static DisplayModePtr
+xf86ClosestMode (xf86OutputPtr output, 
+		 DisplayModePtr match, Rotation match_rotation,
+		 int width, int height)
+{
+    DisplayModePtr  target_mode = NULL;
+    DisplayModePtr  mode;
+    int		    target_diff = 0;
+    
+    /*
+     * Pick a mode closest to the specified mode
+     */
+    for (mode = output->probed_modes; mode; mode = mode->next)
+    {
+	int	    dx, dy;
+	int	    diff;
+
+	if (xf86ModeWidth (mode, output->initial_rotation) > width ||
+	    xf86ModeHeight (mode, output->initial_rotation) > height)
+	    continue;
+	
+	/* exact matches are preferred */
+	if (output->initial_rotation == match_rotation &&
+	    xf86ModesEqual (mode, match))
+	    return mode;
+	
+	dx = xf86ModeWidth (match, match_rotation) - xf86ModeWidth (mode, output->initial_rotation);
+	dy = xf86ModeHeight (match, match_rotation) - xf86ModeHeight (mode, output->initial_rotation);
+	diff = dx * dx + dy * dy;
+	if (target_mode == NULL || diff < target_diff)
+	{
+	    target_mode = mode;
+	    target_diff = diff;
+	}
+    }
+    return target_mode;
+}
+
+static DisplayModePtr
+xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
+{
+    DisplayModePtr  mode;
+
+    for (mode = output->probed_modes; mode; mode = mode->next)
+    {
+	if (xf86ModeWidth (mode, output->initial_rotation) > width ||
+	    xf86ModeHeight (mode, output->initial_rotation) > height)
+	    continue;
+
+	if (mode->type & M_T_PREFERRED)
+	    return mode;
+    }
+    return NULL;
+}
+
+static DisplayModePtr
+xf86OutputHasUserPreferredMode (xf86OutputPtr output)
+{
+    DisplayModePtr mode, first = output->probed_modes;
+
+    for (mode = first; mode && mode->next != first; mode = mode->next)
+	if (mode->type & M_T_USERPREF)
+	    return mode;
+
+    return NULL;
+}
+
+static int
+xf86PickCrtcs (ScrnInfoPtr	scrn,
+	       xf86CrtcPtr	*best_crtcs,
+	       DisplayModePtr	*modes,
+	       int		n,
+	       int		width,
+	       int		height)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int		    c, o;
+    xf86OutputPtr   output;
+    xf86CrtcPtr	    crtc;
+    xf86CrtcPtr	    *crtcs;
+    xf86CrtcPtr	    best_crtc;
+    int		    best_score;
+    int		    score;
+    int		    my_score;
+    
+    if (n == config->num_output)
+	return 0;
+    output = config->output[n];
+    
+    /*
+     * Compute score with this output disabled
+     */
+    best_crtcs[n] = NULL;
+    best_crtc = NULL;
+    best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height);
+    if (modes[n] == NULL)
+	return best_score;
+    
+    crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr));
+    if (!crtcs)
+	return best_score;
+
+    my_score = 1;
+    /* Score outputs that are known to be connected higher */
+    if (output->status == XF86OutputStatusConnected)
+	my_score++;
+    /* Score outputs with preferred modes higher */
+    if (xf86OutputHasPreferredMode (output, width, height))
+	my_score++;
+    /*
+     * Select a crtc for this output and
+     * then attempt to configure the remaining
+     * outputs
+     */
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	if ((output->possible_crtcs & (1 << c)) == 0)
+	    continue;
+	
+	crtc = config->crtc[c];
+	/*
+	 * Check to see if some other output is
+	 * using this crtc
+	 */
+	for (o = 0; o < n; o++)
+	    if (best_crtcs[o] == crtc)
+		break;
+	if (o < n)
+	{
+	    /*
+	     * If the two outputs desire the same mode,
+	     * see if they can be cloned
+	     */
+	    if (xf86ModesEqual (modes[o], modes[n]) &&
+		config->output[o]->initial_rotation == config->output[n]->initial_rotation &&
+		config->output[o]->initial_x == config->output[n]->initial_x &&
+		config->output[o]->initial_y == config->output[n]->initial_y)
+	    {
+		if ((output->possible_clones & (1 << o)) == 0)
+		    continue;		/* nope, try next CRTC */
+	    }
+	    else
+		continue;		/* different modes, can't clone */
+	}
+	crtcs[n] = crtc;
+	memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
+	score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height);
+	if (score > best_score)
+	{
+	    best_crtc = crtc;
+	    best_score = score;
+	    memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr));
+	}
+    }
+    free(crtcs);
+    return best_score;
+}
+
+
+/*
+ * Compute the virtual size necessary to place all of the available
+ * crtcs in the specified configuration.
+ *
+ * canGrow indicates that the driver can make the screen larger than its initial
+ * configuration.  If FALSE, this function will enlarge the screen to include
+ * the largest available mode.
+ */
+
+static void
+xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp,
+			 Bool canGrow)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int	    width = 0, height = 0;
+    int	    o;
+    int	    c;
+    int	    s;
+
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	int	    crtc_width = 0, crtc_height = 0;
+	xf86CrtcPtr crtc = config->crtc[c];
+
+	if (crtc->enabled)
+	{
+	    crtc_width = crtc->desiredX + xf86ModeWidth (&crtc->desiredMode, crtc->desiredRotation);
+	    crtc_height = crtc->desiredY + xf86ModeHeight (&crtc->desiredMode, crtc->desiredRotation);
+	}
+	if (!canGrow) {
+	    for (o = 0; o < config->num_output; o++)
+	    {
+		xf86OutputPtr   output = config->output[o];
+
+		for (s = 0; s < config->num_crtc; s++)
+		    if (output->possible_crtcs & (1 << s))
+		    {
+			DisplayModePtr  mode;
+			for (mode = output->probed_modes; mode; mode = mode->next)
+			{
+			    if (mode->HDisplay > crtc_width)
+				crtc_width = mode->HDisplay;
+			    if (mode->VDisplay > crtc_width)
+				crtc_width = mode->VDisplay;
+			    if (mode->VDisplay > crtc_height)
+				crtc_height = mode->VDisplay;
+			    if (mode->HDisplay > crtc_height)
+				crtc_height = mode->HDisplay;
+			}
+		    }
+	    }
+	}
+	if (crtc_width > width)
+	    width = crtc_width;
+	if (crtc_height > height)
+	    height = crtc_height;
+    }
+    if (config->maxWidth && width > config->maxWidth) width = config->maxWidth;
+    if (config->maxHeight && height > config->maxHeight) height = config->maxHeight;
+    if (config->minWidth && width < config->minWidth) width = config->minWidth;
+    if (config->minHeight && height < config->minHeight) height = config->minHeight;
+    *widthp = width;
+    *heightp = height;
+}
+
+#define POSITION_UNSET	-100000
+
+/*
+ * check if the user configured any outputs at all 
+ * with either a position or a relative setting or a mode.
+ */
+static Bool
+xf86UserConfiguredOutputs(ScrnInfoPtr scrn, DisplayModePtr *modes)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int o;
+    Bool user_conf = FALSE;
+
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr output = config->output[o];
+	char	    *position;
+	char	    *relative_name;
+	OutputOpts	    relation;
+	int r;
+	static const OutputOpts	relations[] = {
+	    OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
+	};
+
+	position = xf86GetOptValString (output->options,
+					OPTION_POSITION);
+	if (position)
+	    user_conf = TRUE;
+
+	relation = 0;
+	relative_name = NULL;
+	for (r = 0; r < 4; r++)
+	{
+	    relation = relations[r];
+	    relative_name = xf86GetOptValString (output->options,
+						     relation);
+	    if (relative_name)
+		break;
+	}
+	if (relative_name)
+	    user_conf = TRUE;
+
+	modes[o] = xf86OutputHasUserPreferredMode(output);
+	if (modes[o])
+	    user_conf = TRUE;
+    }
+
+    return user_conf;
+}
+
+static Bool
+xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o;
+    int			min_x, min_y;
+    
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	output->initial_x = output->initial_y = POSITION_UNSET;
+    }
+    
+    /*
+     * Loop until all outputs are set
+     */
+    for (;;)
+    {
+	Bool	any_set = FALSE;
+	Bool	keep_going = FALSE;
+
+	for (o = 0; o < config->num_output; o++)	
+	{
+	    static const OutputOpts	relations[] = {
+		OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
+	    };
+	    xf86OutputPtr   output = config->output[o];
+	    xf86OutputPtr   relative;
+	    char	    *relative_name;
+	    char	    *position;
+	    OutputOpts	    relation;
+	    int		    r;
+
+	    if (output->initial_x != POSITION_UNSET)
+		continue;
+	    position = xf86GetOptValString (output->options,
+					    OPTION_POSITION);
+	    /*
+	     * Absolute position wins
+	     */
+	    if (position)
+	    {
+		int		    x, y;
+		if (sscanf (position, "%d %d", &x, &y) == 2)
+		{
+		    output->initial_x = x;
+		    output->initial_y = y;
+		}
+		else
+		{
+		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+				"Output %s position not of form \"x y\"\n",
+				output->name);
+		    output->initial_x = output->initial_y = 0;
+		}
+		any_set = TRUE;
+		continue;
+	    }
+	    /*
+	     * Next comes relative positions
+	     */
+	    relation = 0;
+	    relative_name = NULL;
+	    for (r = 0; r < 4; r++)
+	    {
+		relation = relations[r];
+		relative_name = xf86GetOptValString (output->options,
+						     relation);
+		if (relative_name)
+		    break;
+	    }
+	    if (relative_name)
+	    {
+		int or;
+		relative = NULL;
+		for (or = 0; or < config->num_output; or++)
+		{
+		    xf86OutputPtr	out_rel = config->output[or];
+		    XF86ConfMonitorPtr	rel_mon = out_rel->conf_monitor;
+
+		    if (rel_mon)
+		    {
+			if (xf86nameCompare (rel_mon->mon_identifier,
+					      relative_name) == 0)
+			{
+			    relative = config->output[or];
+			    break;
+			}
+		    }
+		    if (strcmp (out_rel->name, relative_name) == 0)
+		    {
+			relative = config->output[or];
+			break;
+		    }
+		}
+		if (!relative)
+		{
+		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+				"Cannot position output %s relative to unknown output %s\n",
+				output->name, relative_name);
+		    output->initial_x = 0;
+		    output->initial_y = 0;
+		    any_set = TRUE;
+		    continue;
+		}
+		if (!modes[or])
+		{
+		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+				"Cannot position output %s relative to output %s without modes\n",
+				output->name, relative_name);
+		    output->initial_x = 0;
+		    output->initial_y = 0;
+		    any_set = TRUE;
+		    continue;
+		}
+		if (relative->initial_x == POSITION_UNSET)
+		{
+		    keep_going = TRUE;
+		    continue;
+		}
+		output->initial_x = relative->initial_x;
+		output->initial_y = relative->initial_y;
+		switch (relation) {
+		case OPTION_BELOW:
+		    output->initial_y += xf86ModeHeight (modes[or], relative->initial_rotation);
+		    break;
+		case OPTION_RIGHT_OF:
+		    output->initial_x += xf86ModeWidth (modes[or], relative->initial_rotation);
+		    break;
+		case OPTION_ABOVE:
+		    if (modes[o])
+			output->initial_y -= xf86ModeHeight (modes[o], output->initial_rotation);
+		    break;
+		case OPTION_LEFT_OF:
+		    if (modes[o])
+			output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation);
+		    break;
+		default:
+		    break;
+		}
+		any_set = TRUE;
+		continue;
+	    }
+	    
+	    /* Nothing set, just stick them at 0,0 */
+	    output->initial_x = 0;
+	    output->initial_y = 0;
+	    any_set = TRUE;
+	}
+	if (!keep_going)
+	    break;
+	if (!any_set) 
+	{
+	    for (o = 0; o < config->num_output; o++)
+	    {
+		xf86OutputPtr   output = config->output[o];
+		if (output->initial_x == POSITION_UNSET)
+		{
+		    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+				"Output position loop. Moving %s to 0,0\n",
+				output->name);
+		    output->initial_x = output->initial_y = 0;
+		    break;
+		}
+	    }
+	}
+    }
+
+    /*
+     * normalize positions
+     */
+    min_x = 1000000;
+    min_y = 1000000;
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	if (output->initial_x < min_x)
+	    min_x = output->initial_x;
+	if (output->initial_y < min_y)
+	    min_y = output->initial_y;
+    }
+    
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+
+	output->initial_x -= min_x;
+	output->initial_y -= min_y;
+    }
+    return TRUE;
+}
+
+static void
+xf86InitialPanning (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o;
+    
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+	char	       *panning = xf86GetOptValString (output->options, OPTION_PANNING);
+	int		width, height, left, top;
+	int		track_width, track_height, track_left, track_top;
+	int		brdr[4];
+
+	memset (&output->initialTotalArea,    0, sizeof(BoxRec));
+	memset (&output->initialTrackingArea, 0, sizeof(BoxRec));
+	memset (output->initialBorder,        0, 4*sizeof(INT16));
+
+	if (! panning)
+	    continue;
+
+	switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d",
+			&width, &height, &left, &top,
+			&track_width, &track_height, &track_left, &track_top,
+			&brdr[0], &brdr[1], &brdr[2], &brdr[3])) {
+	case 12:
+	    output->initialBorder[0] = brdr[0];
+	    output->initialBorder[1] = brdr[1];
+	    output->initialBorder[2] = brdr[2];
+	    output->initialBorder[3] = brdr[3];
+	    /* fall through */
+	case 8:
+	    output->initialTrackingArea.x1 = track_left;
+	    output->initialTrackingArea.y1 = track_top;
+	    output->initialTrackingArea.x2 = track_left + track_width;
+	    output->initialTrackingArea.y2 = track_top  + track_height;
+	    /* fall through */
+	case 4:
+	    output->initialTotalArea.x1 = left;
+	    output->initialTotalArea.y1 = top;
+	    /* fall through */
+	case 2:
+	    output->initialTotalArea.x2 = output->initialTotalArea.x1 + width;
+	    output->initialTotalArea.y2 = output->initialTotalArea.y1 + height;
+	    break;
+	default:
+	    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+			"Broken panning specification '%s' for output %s in config file\n",
+			panning, output->name);
+	}
+    }
+}
+
+/** Return - 0 + if a should be earlier, same or later than b in list
+ */
+static int
+xf86ModeCompare (DisplayModePtr a, DisplayModePtr b)
+{
+    int	diff;
+
+    diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0);
+    if (diff)
+	return diff;
+    diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay;
+    if (diff)
+	return diff;
+    diff = b->Clock - a->Clock;
+    return diff;
+}
+
+/**
+ * Insertion sort input in-place and return the resulting head
+ */
+static DisplayModePtr
+xf86SortModes (DisplayModePtr input)
+{
+    DisplayModePtr  output = NULL, i, o, n, *op, prev;
+
+    /* sort by preferred status and pixel area */
+    while (input)
+    {
+	i = input;
+	input = input->next;
+	for (op = &output; (o = *op); op = &o->next)
+	    if (xf86ModeCompare (o, i) > 0)
+		break;
+	i->next = *op;
+	*op = i;
+    }
+    /* prune identical modes */
+    for (o = output; o && (n = o->next); o = n)
+    {
+	if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n))
+	{
+	    o->next = n->next;
+	    free(n->name);
+	    free(n);
+	    n = o;
+	}
+    }
+    /* hook up backward links */
+    prev = NULL;
+    for (o = output; o; o = o->next)
+    {
+	o->prev = prev;
+	prev = o;
+    }
+    return output;
+}
+
+static char *
+preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+    char *preferred_mode = NULL;
+
+    /* Check for a configured preference for a particular mode */
+    preferred_mode = xf86GetOptValString (output->options,
+					  OPTION_PREFERRED_MODE);
+    if (preferred_mode)
+	return preferred_mode;
+
+    if (pScrn->display->modes && *pScrn->display->modes)
+	preferred_mode = *pScrn->display->modes;
+
+    return preferred_mode;
+}
+
+static void
+GuessRangeFromModes(MonPtr mon, DisplayModePtr mode)
+{
+    if (!mon || !mode)
+       return;
+
+    mon->nHsync = 1;
+    mon->hsync[0].lo = 1024.0;
+    mon->hsync[0].hi = 0.0;
+
+    mon->nVrefresh = 1;
+    mon->vrefresh[0].lo = 1024.0;
+    mon->vrefresh[0].hi = 0.0;
+
+    while (mode) {
+	if (!mode->HSync)
+	    mode->HSync = ((float) mode->Clock ) / ((float) mode->HTotal);
+
+	if (!mode->VRefresh)
+	    mode->VRefresh = (1000.0 * ((float) mode->Clock)) / 
+		((float) (mode->HTotal * mode->VTotal));
+
+	if (mode->HSync < mon->hsync[0].lo)
+	    mon->hsync[0].lo = mode->HSync;
+
+	if (mode->HSync > mon->hsync[0].hi)
+	    mon->hsync[0].hi = mode->HSync;
+
+	if (mode->VRefresh < mon->vrefresh[0].lo)
+	    mon->vrefresh[0].lo = mode->VRefresh;
+
+	if (mode->VRefresh > mon->vrefresh[0].hi)
+	    mon->vrefresh[0].hi = mode->VRefresh;
+
+	mode = mode->next;
+    }
+
+    /* stretch out the bottom to fit 640x480@60 */
+    if (mon->hsync[0].lo > 31.0)
+       mon->hsync[0].lo = 31.0;
+    if (mon->vrefresh[0].lo > 58.0)
+       mon->vrefresh[0].lo = 58.0;
+}
+
+enum det_monrec_source {
+    sync_config, sync_edid, sync_default
+};
+
+struct det_monrec_parameter {
+    MonRec *mon_rec;
+    int *max_clock;
+    Bool set_hsync;
+    Bool set_vrefresh;
+    enum det_monrec_source *sync_source;
+};
+
+static void handle_detailed_monrec(struct detailed_monitor_section *det_mon,
+                                   void *data)
+{
+    struct det_monrec_parameter *p;
+    p = (struct det_monrec_parameter *)data;
+
+    if (det_mon->type == DS_RANGES) {
+        struct monitor_ranges *ranges = &det_mon->section.ranges;
+        if (p->set_hsync && ranges->max_h) {
+            p->mon_rec->hsync[p->mon_rec->nHsync].lo = ranges->min_h;
+            p->mon_rec->hsync[p->mon_rec->nHsync].hi = ranges->max_h;
+            p->mon_rec->nHsync++;
+            if (*p->sync_source == sync_default)
+                *p->sync_source = sync_edid;
+        }
+        if (p->set_vrefresh && ranges->max_v) {
+            p->mon_rec->vrefresh[p->mon_rec->nVrefresh].lo = ranges->min_v;
+            p->mon_rec->vrefresh[p->mon_rec->nVrefresh].hi = ranges->max_v;
+            p->mon_rec->nVrefresh++;
+            if (*p->sync_source == sync_default)
+                *p->sync_source = sync_edid;
+        }
+        if (ranges->max_clock * 1000 > *p->max_clock)
+            *p->max_clock = ranges->max_clock * 1000;
+    }
+}
+
+void
+xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o;
+
+    /* When canGrow was TRUE in the initial configuration we have to
+     * compare against the maximum values so that we don't drop modes.
+     * When canGrow was FALSE, the maximum values would have been clamped
+     * anyway.
+     */
+    if (maxX == 0 || maxY == 0) {
+	maxX = config->maxWidth;
+	maxY = config->maxHeight;
+    }
+
+    /* Probe the list of modes for each output. */
+    for (o = 0; o < config->num_output; o++) 
+    {
+	xf86OutputPtr	    output = config->output[o];
+	DisplayModePtr	    mode;
+	DisplayModePtr	    config_modes = NULL, output_modes, default_modes = NULL;
+	char		    *preferred_mode;
+	xf86MonPtr	    edid_monitor;
+	XF86ConfMonitorPtr  conf_monitor;
+	MonRec		    mon_rec;
+	int		    min_clock = 0;
+	int		    max_clock = 0;
+	double		    clock;
+	Bool		    add_default_modes;
+	Bool		    debug_modes = config->debug_modes ||
+					  xf86Initialising;
+	enum det_monrec_source sync_source = sync_default;
+	
+	while (output->probed_modes != NULL)
+	    xf86DeleteMode(&output->probed_modes, output->probed_modes);
+
+	/*
+	 * Check connection status
+	 */
+	output->status = (*output->funcs->detect)(output);
+
+	if (output->status == XF86OutputStatusDisconnected &&
+		!xf86ReturnOptValBool(output->options, OPTION_ENABLE, FALSE))
+	{
+	    xf86OutputSetEDID (output, NULL);
+	    continue;
+	}
+
+	memset (&mon_rec, '\0', sizeof (mon_rec));
+	
+	conf_monitor = output->conf_monitor;
+	
+	if (conf_monitor)
+	{
+	    int	i;
+	    
+	    for (i = 0; i < conf_monitor->mon_n_hsync; i++)
+	    {
+		mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
+		mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
+		mon_rec.nHsync++;
+		sync_source = sync_config;
+	    }
+	    for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
+	    {
+		mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
+		mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
+		mon_rec.nVrefresh++;
+		sync_source = sync_config;
+	    }
+	    config_modes = xf86GetMonitorModes (scrn, conf_monitor);
+	}
+	
+	output_modes = (*output->funcs->get_modes) (output);
+
+	/*
+	 * If the user has a preference, respect it.
+	 * Otherwise, don't second-guess the driver.
+	 */
+	if (!xf86GetOptValBool(output->options, OPTION_DEFAULT_MODES,
+			       &add_default_modes))
+	    add_default_modes = (output_modes == NULL);
+	
+	edid_monitor = output->MonInfo;
+	
+        if (edid_monitor)
+        {
+            struct det_monrec_parameter p;
+            struct disp_features    *features = &edid_monitor->features;
+
+	    /* if display is not continuous-frequency, don't add default modes */
+	    if (!GTF_SUPPORTED(features->msc))
+		add_default_modes = FALSE;
+
+	    p.mon_rec = &mon_rec;
+	    p.max_clock = &max_clock;
+	    p.set_hsync = mon_rec.nHsync == 0;
+	    p.set_vrefresh = mon_rec.nVrefresh == 0;
+	    p.sync_source = &sync_source;
+
+	    xf86ForEachDetailedBlock(edid_monitor,
+			             handle_detailed_monrec,
+			             &p);
+	}
+
+	if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
+			       OPTUNITS_KHZ, &clock))
+	    min_clock = (int) clock;
+	if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK,
+			       OPTUNITS_KHZ, &clock))
+	    max_clock = (int) clock;
+
+	/* If we still don't have a sync range, guess wildly */
+	if (!mon_rec.nHsync || !mon_rec.nVrefresh)
+	    GuessRangeFromModes(&mon_rec, output_modes);
+
+	/*
+	 * These limits will end up setting a 1024x768@60Hz mode by default,
+	 * which seems like a fairly good mode to use when nothing else is
+	 * specified
+	 */
+	if (mon_rec.nHsync == 0)
+	{
+	    mon_rec.hsync[0].lo = 31.0;
+	    mon_rec.hsync[0].hi = 55.0;
+	    mon_rec.nHsync = 1;
+	}
+	if (mon_rec.nVrefresh == 0)
+	{
+	    mon_rec.vrefresh[0].lo = 58.0;
+	    mon_rec.vrefresh[0].hi = 62.0;
+	    mon_rec.nVrefresh = 1;
+	}
+
+	if (add_default_modes)
+	    default_modes = xf86GetDefaultModes ();
+
+	/*
+	 * If this is not an RB monitor, remove RB modes from the default
+	 * pool.  RB modes from the config or the monitor itself are fine.
+	 */
+	if (!mon_rec.reducedblanking)
+	    xf86ValidateModesReducedBlanking (scrn, default_modes);
+
+	if (sync_source == sync_config)
+	{
+	    /* 
+	     * Check output and config modes against sync range from config file
+	     */
+	    xf86ValidateModesSync (scrn, output_modes, &mon_rec);
+	    xf86ValidateModesSync (scrn, config_modes, &mon_rec);
+	}
+	/*
+	 * Check default modes against sync range
+	 */
+        xf86ValidateModesSync (scrn, default_modes, &mon_rec);
+	/*
+	 * Check default modes against monitor max clock
+	 */
+	if (max_clock) {
+	    xf86ValidateModesClocks(scrn, default_modes,
+				    &min_clock, &max_clock, 1);
+	    xf86ValidateModesClocks(scrn, output_modes,
+				    &min_clock, &max_clock, 1);
+	}
+	
+	output->probed_modes = NULL;
+	output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
+	output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
+	output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
+	
+	/*
+	 * Check all modes against max size, interlace, and doublescan
+	 */
+	if (maxX && maxY)
+	    xf86ValidateModesSize (scrn, output->probed_modes,
+				       maxX, maxY, 0);
+
+	{
+	    int flags = (output->interlaceAllowed ? V_INTERLACE : 0) |
+			(output->doubleScanAllowed ? V_DBLSCAN : 0);
+	    xf86ValidateModesFlags (scrn, output->probed_modes, flags);
+	}
+	 
+	/*
+	 * Check all modes against output
+	 */
+	for (mode = output->probed_modes; mode != NULL; mode = mode->next) 
+	    if (mode->status == MODE_OK)
+		mode->status = (*output->funcs->mode_valid)(output, mode);
+	
+	xf86PruneInvalidModes(scrn, &output->probed_modes, debug_modes);
+	
+	output->probed_modes = xf86SortModes (output->probed_modes);
+	
+	/* Check for a configured preference for a particular mode */
+	preferred_mode = preferredMode(scrn, output);
+
+	if (preferred_mode)
+	{
+	    for (mode = output->probed_modes; mode; mode = mode->next)
+	    {
+		if (!strcmp (preferred_mode, mode->name))
+		{
+		    if (mode != output->probed_modes)
+		    {
+			if (mode->prev)
+			    mode->prev->next = mode->next;
+			if (mode->next)
+			    mode->next->prev = mode->prev;
+			mode->next = output->probed_modes;
+			output->probed_modes->prev = mode;
+			mode->prev = NULL;
+			output->probed_modes = mode;
+		    }
+		    mode->type |= (M_T_PREFERRED|M_T_USERPREF);
+		    break;
+		}
+	    }
+	}
+	
+	output->initial_rotation = xf86OutputInitialRotation (output);
+
+	if (debug_modes) {
+	    if (output->probed_modes != NULL) {
+		xf86DrvMsg(scrn->scrnIndex, X_INFO,
+			   "Printing probed modes for output %s\n",
+			   output->name);
+	    } else {
+		xf86DrvMsg(scrn->scrnIndex, X_INFO,
+			   "No remaining probed modes for output %s\n",
+			   output->name);
+	    }
+	}
+	for (mode = output->probed_modes; mode != NULL; mode = mode->next)
+	{
+	    /* The code to choose the best mode per pipe later on will require
+	     * VRefresh to be set.
+	     */
+	    mode->VRefresh = xf86ModeVRefresh(mode);
+	    xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
+
+	    if (debug_modes)
+		xf86PrintModeline(scrn->scrnIndex, mode);
+	}
+    }
+}
+
+
+/**
+ * Copy one of the output mode lists to the ScrnInfo record
+ */
+
+/* XXX where does this function belong? Here? */
+void
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
+
+static DisplayModePtr
+biggestMode(DisplayModePtr a, DisplayModePtr b)
+{
+    int A, B;
+
+    if (!a)
+	return b;
+    if (!b)
+	return a;
+
+    A = a->HDisplay * a->VDisplay;
+    B = b->HDisplay * b->VDisplay;
+
+    if (A > B)
+	return a;
+
+    return b;
+}
+
+static xf86OutputPtr
+SetCompatOutput(xf86CrtcConfigPtr config)
+{
+    xf86OutputPtr output = NULL, test = NULL;
+    DisplayModePtr maxmode = NULL, testmode, mode;
+    int o, compat = -1, count, mincount = 0;
+
+    /* Look for one that's definitely connected */
+    for (o = 0; o < config->num_output; o++)
+    {
+	test = config->output[o];
+	if (!test->crtc)
+	    continue;
+	if (test->status != XF86OutputStatusConnected)
+	    continue;
+	if (!test->probed_modes)
+	    continue;
+
+	testmode = mode = test->probed_modes;
+	for (count = 0; mode; mode = mode->next, count++)
+	    testmode = biggestMode(testmode, mode);
+
+	if (!output) {
+	    output = test;
+	    compat = o;
+	    maxmode = testmode;
+	    mincount = count;
+	} else if (maxmode == biggestMode(maxmode, testmode)) {
+	    output = test;
+	    compat = o;
+	    maxmode = testmode;
+	    mincount = count;
+	} else if ((maxmode->HDisplay == testmode->HDisplay) && 
+		(maxmode->VDisplay == testmode->VDisplay) &&
+		count <= mincount) {
+	    output = test;
+	    compat = o;
+	    maxmode = testmode;
+	    mincount = count;
+	}
+    }
+
+    /* If we didn't find one, take anything we can get */
+    if (!output)
+    {
+	for (o = 0; o < config->num_output; o++)
+	{
+	    test = config->output[o];
+	    if (!test->crtc)
+		continue;
+	    if (!test->probed_modes)
+		continue;
+
+	    if (!output) {
+		output = test;
+		compat = o;
+	    } else if (test->probed_modes->HDisplay < output->probed_modes->HDisplay) {
+		output = test;
+		compat = o;
+	    }
+	}
+    }
+
+    if (compat >= 0) {
+	config->compat_output = compat;
+    } else {
+	/* Don't change the compat output when no valid outputs found */
+	output = config->output[config->compat_output];
+    }
+
+    return output;
+}
+
+void
+xf86SetScrnInfoModes (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86OutputPtr	output;
+    xf86CrtcPtr		crtc;
+    DisplayModePtr	last, mode = NULL;
+
+    output = SetCompatOutput(config);
+
+    if (!output)
+	return; /* punt */
+
+    crtc = output->crtc;
+
+    /* Clear any existing modes from scrn->modes */
+    while (scrn->modes != NULL)
+	xf86DeleteMode(&scrn->modes, scrn->modes);
+
+    /* Set scrn->modes to the mode list for the 'compat' output */
+    scrn->modes = xf86DuplicateModes(scrn, output->probed_modes);
+
+    if (crtc) {
+	for (mode = scrn->modes; mode; mode = mode->next)
+	    if (xf86ModesEqual (mode, &crtc->desiredMode))
+		break;
+    }
+
+    if (scrn->modes != NULL) {
+	/* For some reason, scrn->modes is circular, unlike the other mode
+	 * lists.  How great is that?
+	 */
+	for (last = scrn->modes; last && last->next; last = last->next)
+	    ;
+	last->next = scrn->modes;
+	scrn->modes->prev = last;
+	if (mode) {
+	    while (scrn->modes != mode)
+		scrn->modes = scrn->modes->next;
+	}
+    }
+    scrn->currentMode = scrn->modes;
+#ifdef XFreeXDGA
+    if (scrn->pScreen)
+	    _xf86_di_dga_reinit_internal(scrn->pScreen);
+#endif
+}
+
+static Bool
+xf86CollectEnabledOutputs(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+			  Bool *enabled)
+{
+    Bool any_enabled = FALSE;
+    int o;
+
+    for (o = 0; o < config->num_output; o++)
+	any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], TRUE);
+    
+    if (!any_enabled) {
+	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+		   "No outputs definitely connected, trying again...\n");
+
+	for (o = 0; o < config->num_output; o++)
+	    any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], FALSE);
+    }
+
+    return any_enabled;
+}
+
+static Bool
+nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index)
+{
+    int o = *index;
+
+    for (o++; o < config->num_output; o++) {
+	if (enabled[o]) {
+	    *index = o;
+	    return TRUE;
+	}
+    }
+    
+    return FALSE;
+}
+
+static Bool
+aspectMatch(float a, float b)
+{
+    return fabs(1 - (a / b)) < 0.05;
+}
+
+static DisplayModePtr
+nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
+{
+    DisplayModePtr m = NULL;
+
+    if (!o)
+	return NULL;
+
+    if (!last)
+	m = o->probed_modes;
+    else
+	m = last->next;
+
+    for (; m; m = m->next)
+	if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
+	    return m;
+
+    return NULL;
+}
+
+static DisplayModePtr
+bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
+{
+    int o = -1, p;
+    DisplayModePtr mode = NULL, test = NULL, match = NULL;
+
+    if (!nextEnabledOutput(config, enabled, &o))
+	return NULL;
+    while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
+	test = mode;
+	for (p = o; nextEnabledOutput(config, enabled, &p); ) {
+	    test = xf86OutputFindClosestMode(config->output[p], mode);
+	    if (!test)
+		break;
+	    if (test->HDisplay != mode->HDisplay ||
+		    test->VDisplay != mode->VDisplay) {
+		test = NULL;
+		break;
+	    }
+	}
+
+	/* if we didn't match it on all outputs, try the next one */
+	if (!test)
+	    continue;
+
+	/* if it's bigger than the last one, save it */
+	if (!match || (test->HDisplay > match->HDisplay))
+	    match = test;
+    }
+
+    /* return the biggest one found */
+    return match;
+}
+
+static Bool
+xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+		    DisplayModePtr *modes, Bool *enabled,
+		    int width, int height)
+{
+    int o, p;
+    int max_pref_width = 0, max_pref_height = 0;
+    DisplayModePtr *preferred, *preferred_match;
+    Bool ret = FALSE;
+
+    preferred = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
+    preferred_match = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
+
+    /* Check if the preferred mode is available on all outputs */
+    for (p = -1; nextEnabledOutput(config, enabled, &p); ) {
+	Rotation r = config->output[p]->initial_rotation;
+	DisplayModePtr mode;
+	if ((preferred[p] = xf86OutputHasPreferredMode(config->output[p],
+			width, height))) {
+	    int pref_width = xf86ModeWidth(preferred[p], r);
+	    int pref_height = xf86ModeHeight(preferred[p], r);
+	    Bool all_match = TRUE;
+
+	    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+		Bool match = FALSE;
+		xf86OutputPtr output = config->output[o];
+		if (o == p)
+		    continue;
+
+		for (mode = output->probed_modes; mode; mode = mode->next) {
+		    Rotation r = output->initial_rotation;
+		    if (xf86ModeWidth(mode, r) == pref_width &&
+			    xf86ModeHeight(mode, r) == pref_height) {
+			preferred[o] = mode;
+			match = TRUE;
+		    }
+		}
+
+		all_match &= match;
+	    }
+
+	    if (all_match &&
+		    (pref_width*pref_height > max_pref_width*max_pref_height)) {
+		for (o = -1; nextEnabledOutput(config, enabled, &o); )
+		    preferred_match[o] = preferred[o];
+		max_pref_width = pref_width;
+		max_pref_height = pref_height;
+		ret = TRUE;
+	    }
+	}
+    }
+
+    /*
+     * If there's no preferred mode, but only one monitor, pick the
+     * biggest mode for its aspect ratio, assuming one exists.
+     */
+    if (!ret) do {
+	int i = 0;
+	float aspect = 0.0;
+
+	/* count the number of enabled outputs */
+	for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
+
+	if (i != 1)
+	    break;
+
+	p = -1;
+	nextEnabledOutput(config, enabled, &p);
+	if (config->output[p]->mm_height)
+	    aspect = (float)config->output[p]->mm_width /
+		     (float)config->output[p]->mm_height;
+
+	if (aspect)
+	    preferred_match[p] = bestModeForAspect(config, enabled, aspect);
+
+	if (preferred_match[p])
+	    ret = TRUE;
+
+    } while (0);
+
+    if (ret) {
+	/* oh good, there is a match.  stash the selected modes and return. */
+	memcpy(modes, preferred_match,
+		config->num_output * sizeof(DisplayModePtr));
+    }
+
+    free(preferred);
+    free(preferred_match);
+    return ret;
+}
+
+static Bool
+xf86TargetAspect(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+		 DisplayModePtr *modes, Bool *enabled,
+		 int width, int height)
+{
+    int o;
+    float aspect = 0.0, *aspects;
+    xf86OutputPtr output;
+    Bool ret = FALSE;
+    DisplayModePtr guess = NULL, aspect_guess = NULL, base_guess = NULL;
+
+    aspects = xnfcalloc(config->num_output, sizeof(float));
+
+    /* collect the aspect ratios */
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+	output = config->output[o];
+	if (output->mm_height)
+	    aspects[o] = (float)output->mm_width / (float)output->mm_height;
+	else
+	    aspects[o] = 4.0 / 3.0;
+    }
+
+    /* check that they're all the same */
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+	output = config->output[o];
+	if (!aspect) {
+	    aspect = aspects[o];
+	} else if (!aspectMatch(aspect, aspects[o])) {
+	    goto no_aspect_match;
+	}
+    }
+
+    /* if they're all 4:3, just skip ahead and save effort */
+    if (!aspectMatch(aspect, 4.0/3.0))
+	aspect_guess = bestModeForAspect(config, enabled, aspect);
+
+no_aspect_match:
+    base_guess = bestModeForAspect(config, enabled, 4.0/3.0);
+
+    guess = biggestMode(base_guess, aspect_guess);
+
+    if (!guess)
+	goto out;
+
+    /* found a mode that works everywhere, now apply it */
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+	modes[o] = xf86OutputFindClosestMode(config->output[o], guess);
+    }
+    ret = TRUE;
+
+out:
+    free(aspects);
+    return ret;
+}
+
+static Bool
+xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+		   DisplayModePtr *modes, Bool *enabled,
+		   int width, int height)
+{
+    DisplayModePtr target_mode = NULL;
+    Rotation target_rotation = RR_Rotate_0;
+    DisplayModePtr default_mode;
+    int default_preferred, target_preferred = 0, o;
+
+    /* User preferred > preferred > other modes */
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+	default_mode = xf86DefaultMode (config->output[o], width, height);
+	if (!default_mode)
+	    continue;
+
+	default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) +
+		((default_mode->type & M_T_USERPREF) != 0));
+
+	if (default_preferred > target_preferred || !target_mode) {
+	    target_mode = default_mode;
+	    target_preferred = default_preferred;
+	    target_rotation = config->output[o]->initial_rotation;
+	    config->compat_output = o;
+	}
+    }
+
+    if (target_mode)
+	modes[config->compat_output] = target_mode;
+
+    /* Fill in other output modes */
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+	if (!modes[o])
+	    modes[o] = xf86ClosestMode(config->output[o], target_mode,
+				       target_rotation, width, height);
+    }
+
+    return target_mode != NULL;
+}
+
+static Bool
+xf86TargetUserpref(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+		   DisplayModePtr *modes, Bool *enabled,
+		   int width, int height)
+{
+    int o;
+
+    if (xf86UserConfiguredOutputs(scrn, modes))
+	return xf86TargetFallback(scrn, config, modes, enabled, width, height);
+    
+    for (o = -1; nextEnabledOutput(config, enabled, &o); )
+	if (xf86OutputHasUserPreferredMode(config->output[o]))
+	    return 
+		xf86TargetFallback(scrn, config, modes, enabled, width, height);
+
+    return FALSE;
+}
+
+static Bool
+xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
+        float gamma_blue)
+{
+    int i, size = 256;
+    CARD16 *red, *green, *blue;
+
+    red = malloc(3 * size * sizeof(CARD16));
+    green = red + size;
+    blue = green + size;
+
+     /* Only cause warning if user wanted gamma to be set. */
+    if (!crtc->funcs->gamma_set && (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0)) {
+        free(red);
+        return FALSE;
+    } else if (!crtc->funcs->gamma_set) {
+        free(red);
+        return TRUE;
+      }
+
+    /* At this early stage none of the randr-interface stuff is up.
+     * So take the default gamma size for lack of something better.
+     */
+    for (i = 0; i < size; i++) {
+        if (gamma_red == 1.0)
+            red[i] = i << 8;
+        else
+            red[i] = (CARD16)(pow((double)i/(double)(size - 1),
+			1. / (double)gamma_red) * (double)(size - 1) * 256);
+
+        if (gamma_green == 1.0)
+            green[i] = i << 8;
+        else
+            green[i] = (CARD16)(pow((double)i/(double)(size - 1),
+			1. / (double)gamma_green) * (double)(size - 1) * 256);
+
+        if (gamma_blue == 1.0)
+            blue[i] = i << 8;
+        else
+            blue[i] = (CARD16)(pow((double)i/(double)(size - 1),
+			1. / (double)gamma_blue) * (double)(size - 1) * 256);
+    }
+
+    /* Default size is 256, so anything else is failure. */
+    if (size != crtc->gamma_size) {
+        free(red);
+        return FALSE;
+      }
+
+    crtc->gamma_size = size;
+    memcpy (crtc->gamma_red, red, crtc->gamma_size * sizeof (CARD16));
+    memcpy (crtc->gamma_green, green, crtc->gamma_size * sizeof (CARD16));
+    memcpy (crtc->gamma_blue, blue, crtc->gamma_size * sizeof (CARD16));
+
+    /* Do not set gamma now, delay until the crtc is activated. */
+
+    free(red);
+
+    return TRUE;
+}
+
+static Bool
+xf86OutputSetInitialGamma(xf86OutputPtr output)
+{
+    XF86ConfMonitorPtr mon = output->conf_monitor;
+    float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0;
+    
+    if (!mon)
+        return TRUE;
+
+    if (!output->crtc)
+        return FALSE;
+
+    /* Get configured values, where they exist. */
+    if (mon->mon_gamma_red >= GAMMA_MIN &&
+        mon->mon_gamma_red <= GAMMA_MAX)
+            gamma_red = mon->mon_gamma_red;
+
+    if (mon->mon_gamma_green >= GAMMA_MIN &&
+        mon->mon_gamma_green <= GAMMA_MAX)
+            gamma_green = mon->mon_gamma_green;
+
+    if (mon->mon_gamma_blue >= GAMMA_MIN &&
+        mon->mon_gamma_blue <= GAMMA_MAX)
+            gamma_blue = mon->mon_gamma_blue;
+
+    /* This avoids setting gamma 1.0 in case another cloned output on this crtc has a specific gamma. */
+    if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
+	xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n", output->name, gamma_red, gamma_green, gamma_blue);
+	return xf86CrtcSetInitialGamma(output->crtc, gamma_red, gamma_green, gamma_blue);
+    }else
+	return TRUE;
+}
+
+/**
+ * Construct default screen configuration
+ *
+ * Given auto-detected (and, eventually, configured) values,
+ * construct a usable configuration for the system
+ *
+ * canGrow indicates that the driver can resize the screen to larger than its
+ * initially configured size via the config->funcs->resize hook.  If TRUE, this
+ * function will set virtualX and virtualY to match the initial configuration
+ * and leave config->max{Width,Height} alone.  If FALSE, it will bloat
+ * virtual[XY] to include the largest modes and set config->max{Width,Height}
+ * accordingly.
+ */
+
+Bool
+xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o, c;
+    xf86CrtcPtr		*crtcs;
+    DisplayModePtr	*modes;
+    Bool		*enabled;
+    int			width, height;
+    int			i = scrn->scrnIndex;
+    Bool have_outputs = TRUE;
+    Bool ret;
+    Bool success = FALSE;
+
+    /* Set up the device options */
+    config->options = xnfalloc (sizeof (xf86DeviceOptions));
+    memcpy (config->options, xf86DeviceOptions, sizeof (xf86DeviceOptions));
+    xf86ProcessOptions (scrn->scrnIndex,
+			scrn->options,
+			config->options);
+    config->debug_modes = xf86ReturnOptValBool (config->options,
+						OPTION_MODEDEBUG, FALSE);
+
+    if (scrn->display->virtualX)
+	width = scrn->display->virtualX;
+    else
+	width = config->maxWidth;
+    if (scrn->display->virtualY)
+	height = scrn->display->virtualY;
+    else
+	height = config->maxHeight;
+
+    xf86ProbeOutputModes (scrn, width, height);
+
+    crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
+    modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
+    enabled = xnfcalloc (config->num_output, sizeof (Bool));
+    
+    ret = xf86CollectEnabledOutputs(scrn, config, enabled);
+    if (ret == FALSE && canGrow) {
+	xf86DrvMsg(i, X_WARNING, "Unable to find connected outputs - setting %dx%d initial framebuffer\n",
+		   NO_OUTPUT_DEFAULT_WIDTH, NO_OUTPUT_DEFAULT_HEIGHT);
+	have_outputs = FALSE;
+    } else {
+	if (xf86TargetUserpref(scrn, config, modes, enabled, width, height))
+	    xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n");
+	else if (xf86TargetPreferred(scrn, config, modes, enabled, width, height))
+	    xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n");
+	else if (xf86TargetAspect(scrn, config, modes, enabled, width, height))
+	    xf86DrvMsg(i, X_INFO, "Using fuzzy aspect match for initial modes\n");
+	else if (xf86TargetFallback(scrn, config, modes, enabled, width, height))
+	    xf86DrvMsg(i, X_INFO, "Using sloppy heuristic for initial modes\n");
+	else
+	    xf86DrvMsg(i, X_WARNING, "Unable to find initial modes\n");
+    }
+
+    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+	if (!modes[o])
+	    xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+			"Output %s enabled but has no modes\n",
+			config->output[o]->name);
+	else
+	    xf86DrvMsg (scrn->scrnIndex, X_INFO,
+			"Output %s using initial mode %s\n",
+			config->output[o]->name, modes[o]->name);
+    }
+
+    /*
+     * Set the position of each output
+     */
+    if (!xf86InitialOutputPositions (scrn, modes))
+	goto bailout;
+
+    /*
+     * Set initial panning of each output
+     */
+    xf86InitialPanning (scrn);
+	
+    /*
+     * Assign CRTCs to fit output configuration
+     */
+    if (have_outputs && !xf86PickCrtcs (scrn, crtcs, modes, 0, width, height))
+	goto bailout;
+    
+    /* XXX override xf86 common frame computation code */
+    
+    scrn->display->frameX0 = 0;
+    scrn->display->frameY0 = 0;
+    
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	xf86CrtcPtr	crtc = config->crtc[c];
+
+	crtc->enabled = FALSE;
+	memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
+	/* Set default gamma for all crtc's. */
+	/* This is done to avoid problems later on with cloned outputs. */
+	xf86CrtcSetInitialGamma(crtc, 1.0, 1.0, 1.0);
+    }
+
+    if (xf86_crtc_supports_gamma(scrn))
+	xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated.\n");
+
+    /*
+     * Set initial configuration
+     */
+    for (o = 0; o < config->num_output; o++)
+    {
+	xf86OutputPtr	output = config->output[o];
+	DisplayModePtr	mode = modes[o];
+        xf86CrtcPtr	crtc = crtcs[o];
+
+	if (mode && crtc)
+	{
+	    crtc->desiredMode = *mode;
+	    crtc->desiredRotation = output->initial_rotation;
+	    crtc->desiredX = output->initial_x;
+	    crtc->desiredY = output->initial_y;
+	    crtc->desiredTransformPresent = FALSE;
+	    crtc->enabled = TRUE;
+	    memcpy (&crtc->panningTotalArea,    &output->initialTotalArea,    sizeof(BoxRec));
+	    memcpy (&crtc->panningTrackingArea, &output->initialTrackingArea, sizeof(BoxRec));
+	    memcpy (crtc->panningBorder,        output->initialBorder,        4*sizeof(INT16));
+	    output->crtc = crtc;
+	    if (!xf86OutputSetInitialGamma(output))
+		xf86DrvMsg (scrn->scrnIndex, X_WARNING, "Initial gamma correction for output %s: failed.\n", output->name);
+	} else {
+	    output->crtc = NULL;
+	}
+    }
+
+    if (scrn->display->virtualX == 0)
+    {
+	/*
+	 * Expand virtual size to cover the current config and potential mode
+	 * switches, if the driver can't enlarge the screen later.
+	 */
+	xf86DefaultScreenLimits (scrn, &width, &height, canGrow);
+    
+	if (have_outputs == FALSE) {
+	    if (width < NO_OUTPUT_DEFAULT_WIDTH && height < NO_OUTPUT_DEFAULT_HEIGHT) {
+		width = NO_OUTPUT_DEFAULT_WIDTH;
+		height = NO_OUTPUT_DEFAULT_HEIGHT;
+	    }
+	}
+
+	scrn->display->virtualX = width;
+	scrn->display->virtualY = height;
+    }
+
+    if (width > scrn->virtualX)
+	scrn->virtualX = width;
+    if (height > scrn->virtualY)
+	scrn->virtualY = height;
+
+    /*
+     * Make sure the configuration isn't too small.
+     */
+    if (width < config->minWidth || height < config->minHeight)
+	goto bailout;
+
+    /*
+     * Limit the crtc config to virtual[XY] if the driver can't grow the
+     * desktop.
+     */
+    if (!canGrow)
+    {
+	xf86CrtcSetSizeRange (scrn, config->minWidth, config->minHeight,
+			      width, height);
+    }
+
+    if (have_outputs) {
+	/* Mirror output modes to scrn mode list */
+	xf86SetScrnInfoModes (scrn);
+    } else {
+	/* Clear any existing modes from scrn->modes */
+	while (scrn->modes != NULL)
+	    xf86DeleteMode(&scrn->modes, scrn->modes);
+	scrn->modes = xf86ModesAdd(scrn->modes,
+				   xf86CVTMode(width, height, 60, 0, 0));
+    }
+
+    success = TRUE;
+ bailout:
+    free(crtcs);
+    free(modes);
+    free(enabled);
+    return success;
+}
+
+/*
+ * Check the CRTC we're going to map each output to vs. it's current
+ * CRTC.  If they don't match, we have to disable the output and the CRTC
+ * since the driver will have to re-route things.
+ */
+static void
+xf86PrepareOutputs (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			o;
+
+    for (o = 0; o < config->num_output; o++) {
+	xf86OutputPtr output = config->output[o];
+#if RANDR_GET_CRTC_INTERFACE
+	/* Disable outputs that are unused or will be re-routed */
+	if (!output->funcs->get_crtc ||
+	    output->crtc != (*output->funcs->get_crtc)(output) ||
+	    output->crtc == NULL)
+#endif
+	    (*output->funcs->dpms)(output, DPMSModeOff);
+    }
+}
+
+static void
+xf86PrepareCrtcs (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			c;
+
+    for (c = 0; c < config->num_crtc; c++) {
+#if RANDR_GET_CRTC_INTERFACE
+	xf86CrtcPtr	crtc = config->crtc[c];
+	xf86OutputPtr	output = NULL;
+	uint32_t	desired_outputs = 0, current_outputs = 0;
+	int		o;
+
+	for (o = 0; o < config->num_output; o++) {
+	    output = config->output[o];
+	    if (output->crtc == crtc)
+		desired_outputs |= (1<<o);
+	    /* If we can't tell where it's mapped, force it off */
+	    if (!output->funcs->get_crtc) {
+		desired_outputs = 0;
+		break;
+	    }
+	    if ((*output->funcs->get_crtc)(output) == crtc)
+		current_outputs |= (1<<o);
+	}
+
+	/*
+	 * If mappings are different or the CRTC is unused,
+	 * we need to disable it
+	 */
+	if (desired_outputs != current_outputs ||
+	    !desired_outputs)
+	    (*crtc->funcs->dpms)(crtc, DPMSModeOff);
+#else
+	(*crtc->funcs->dpms)(crtc, DPMSModeOff);
+#endif
+    }
+}
+
+/*
+ * Using the desired mode information in each crtc, set
+ * modes (used in EnterVT functions, or at server startup)
+ */
+
+Bool
+xf86SetDesiredModes (ScrnInfoPtr scrn)
+{
+    xf86CrtcConfigPtr   config = XF86_CRTC_CONFIG_PTR(scrn);
+    xf86CrtcPtr         crtc = config->crtc[0];
+    int			c;
+
+    /* A driver with this hook will take care of this */
+    if (!crtc->funcs->set_mode_major) {
+	xf86PrepareOutputs(scrn);
+	xf86PrepareCrtcs(scrn);
+    }
+
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	xf86OutputPtr	output = NULL;
+	int		o;
+	RRTransformPtr	transform;
+
+	crtc = config->crtc[c];
+
+	/* Skip disabled CRTCs */
+	if (!crtc->enabled)
+	    continue;
+
+	if (xf86CompatOutput(scrn) && xf86CompatCrtc(scrn) == crtc)
+	    output = xf86CompatOutput(scrn);
+	else
+	{
+	    for (o = 0; o < config->num_output; o++)
+		if (config->output[o]->crtc == crtc)
+		{
+		    output = config->output[o];
+		    break;
+		}
+	}
+	/* paranoia */
+	if (!output)
+	    continue;
+
+	/* Mark that we'll need to re-set the mode for sure */
+	memset(&crtc->mode, 0, sizeof(crtc->mode));
+	if (!crtc->desiredMode.CrtcHDisplay)
+	{
+	    DisplayModePtr  mode = xf86OutputFindClosestMode (output, scrn->currentMode);
+
+	    if (!mode)
+		return FALSE;
+	    crtc->desiredMode = *mode;
+	    crtc->desiredRotation = RR_Rotate_0;
+	    crtc->desiredTransformPresent = FALSE;
+	    crtc->desiredX = 0;
+	    crtc->desiredY = 0;
+	}
+
+	if (crtc->desiredTransformPresent)
+	    transform = &crtc->desiredTransform;
+	else
+	    transform = NULL;
+	if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, crtc->desiredRotation,
+				       transform, crtc->desiredX, crtc->desiredY))
+	    return FALSE;
+    }
+
+    xf86DisableUnusedFunctions(scrn);
+    return TRUE;
+}
+
+/**
+ * In the current world order, there are lists of modes per output, which may
+ * or may not include the mode that was asked to be set by XFree86's mode
+ * selection.  Find the closest one, in the following preference order:
+ *
+ * - Equality
+ * - Closer in size to the requested mode, but no larger
+ * - Closer in refresh rate to the requested mode.
+ */
+
+DisplayModePtr
+xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired)
+{
+    DisplayModePtr	best = NULL, scan = NULL;
+
+    for (scan = output->probed_modes; scan != NULL; scan = scan->next) 
+    {
+	/* If there's an exact match, we're done. */
+	if (xf86ModesEqual(scan, desired)) {
+	    best = desired;
+	    break;
+	}
+
+	/* Reject if it's larger than the desired mode. */
+	if (scan->HDisplay > desired->HDisplay || 
+	    scan->VDisplay > desired->VDisplay)
+	{
+	    continue;
+	}
+
+	/*
+	 * If we haven't picked a best mode yet, use the first
+	 * one in the size range
+	 */
+	if (best == NULL) 
+	{
+	    best = scan;
+	    continue;
+	}
+
+	/* Find if it's closer to the right size than the current best
+	 * option.
+	 */
+	if ((scan->HDisplay > best->HDisplay &&
+	     scan->VDisplay >= best->VDisplay) ||
+	    (scan->HDisplay >= best->HDisplay &&
+	     scan->VDisplay > best->VDisplay))
+	{
+	    best = scan;
+	    continue;
+	}
+
+	/* Find if it's still closer to the right refresh than the current
+	 * best resolution.
+	 */
+	if (scan->HDisplay == best->HDisplay &&
+	    scan->VDisplay == best->VDisplay &&
+	    (fabs(scan->VRefresh - desired->VRefresh) <
+	     fabs(best->VRefresh - desired->VRefresh))) {
+	    best = scan;
+	}
+    }
+    return best;
+}
+
+/**
+ * When setting a mode through XFree86-VidModeExtension or XFree86-DGA,
+ * take the specified mode and apply it to the crtc connected to the compat
+ * output. Then, find similar modes for the other outputs, as with the
+ * InitialConfiguration code above. The goal is to clone the desired
+ * mode across all outputs that are currently active.
+ */
+
+Bool
+xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(pScrn);
+    Bool		ok = TRUE;
+    xf86OutputPtr	compat_output;
+    DisplayModePtr	compat_mode = NULL;
+    int			c;
+
+    /*
+     * Let the compat output drive the final mode selection
+     */
+    compat_output = xf86CompatOutput(pScrn);
+    if (compat_output)
+	compat_mode = xf86OutputFindClosestMode (compat_output, desired);
+    if (compat_mode)
+	desired = compat_mode;
+    
+    for (c = 0; c < config->num_crtc; c++)
+    {
+	xf86CrtcPtr	crtc = config->crtc[c];
+	DisplayModePtr	crtc_mode = NULL;
+	int		o;
+
+	if (!crtc->enabled)
+	    continue;
+	
+	for (o = 0; o < config->num_output; o++)
+	{
+	    xf86OutputPtr   output = config->output[o];
+	    DisplayModePtr  output_mode;
+
+	    /* skip outputs not on this crtc */
+	    if (output->crtc != crtc)
+		continue;
+	    
+	    if (crtc_mode)
+	    {
+		output_mode = xf86OutputFindClosestMode (output, crtc_mode);
+		if (output_mode != crtc_mode)
+		    output->crtc = NULL;
+	    }
+	    else
+		crtc_mode = xf86OutputFindClosestMode (output, desired);
+	}
+	if (!crtc_mode)
+	{
+	    crtc->enabled = FALSE;
+	    continue;
+	}
+	if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0))
+	    ok = FALSE;
+	else
+	{
+	    crtc->desiredMode = *crtc_mode;
+	    crtc->desiredRotation = rotation;
+	    crtc->desiredTransformPresent = FALSE;
+	    crtc->desiredX = 0;
+	    crtc->desiredY = 0;
+	}
+    }
+    xf86DisableUnusedFunctions(pScrn);
+#ifdef RANDR_12_INTERFACE
+    xf86RandR12TellChanged (pScrn->pScreen);
+#endif
+    return ok;
+}
+
+
+/**
+ * Set the DPMS power mode of all outputs and CRTCs.
+ *
+ * If the new mode is off, it will turn off outputs and then CRTCs.
+ * Otherwise, it will affect CRTCs before outputs.
+ */
+void
+xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			i;
+
+    if (!scrn->vtSema)
+	return;
+
+    if (mode == DPMSModeOff) {
+	for (i = 0; i < config->num_output; i++) {
+	    xf86OutputPtr output = config->output[i];
+	    if (output->crtc != NULL)
+		(*output->funcs->dpms) (output, mode);
+	}
+    }
+
+    for (i = 0; i < config->num_crtc; i++) {
+	xf86CrtcPtr crtc = config->crtc[i];
+	if (crtc->enabled)
+	    (*crtc->funcs->dpms) (crtc, mode);
+    }
+
+    if (mode != DPMSModeOff) {
+	for (i = 0; i < config->num_output; i++) {
+	    xf86OutputPtr output = config->output[i];
+	    if (output->crtc != NULL)
+		(*output->funcs->dpms) (output, mode);
+	}
+    }
+}
+
+/**
+ * Implement the screensaver by just calling down into the driver DPMS hooks.
+ *
+ * Even for monitors with no DPMS support, by the definition of our DPMS hooks,
+ * the outputs will still get disabled (blanked).
+ */
+Bool
+xf86SaveScreen(ScreenPtr pScreen, int mode)
+{
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+    if (xf86IsUnblank(mode))
+	xf86DPMSSet(pScrn, DPMSModeOn, 0);
+    else
+	xf86DPMSSet(pScrn, DPMSModeOff, 0);
+
+    return TRUE;
+}
+
+/**
+ * Disable all inactive crtcs and outputs
+ */
+void
+xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    int			o, c;
+
+    for (o = 0; o < xf86_config->num_output; o++) 
+    {
+	xf86OutputPtr  output = xf86_config->output[o];
+	if (!output->crtc) 
+	    (*output->funcs->dpms)(output, DPMSModeOff);
+    }
+
+    for (c = 0; c < xf86_config->num_crtc; c++) 
+    {
+	xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+	if (!crtc->enabled) 
+	{
+	    crtc->funcs->dpms(crtc, DPMSModeOff);
+	    memset(&crtc->mode, 0, sizeof(crtc->mode));
+	    xf86RotateDestroy(crtc);
+	    crtc->active = FALSE;
+	}
+    }
+    if (pScrn->pScreen)
+	xf86_crtc_notify(pScrn->pScreen);
+    if (pScrn->ModeSet)
+	pScrn->ModeSet(pScrn);
+}
+
+#ifdef RANDR_12_INTERFACE
+
+#define EDID_ATOM_NAME		"EDID"
+
+/**
+ * Set the RandR EDID property
+ */
+static void
+xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
+{
+    Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME) - 1, TRUE);
+
+    /* This may get called before the RandR resources have been created */
+    if (output->randr_output == NULL)
+	return;
+
+    if (data_len != 0) {
+	RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
+			       PropModeReplace, data_len, data, FALSE, TRUE);
+    } else {
+	RRDeleteOutputProperty(output->randr_output, edid_atom);
+    }
+}
+
+#endif
+
+/* Pull out a phyiscal size from a detailed timing if available. */
+struct det_phySize_parameter {
+    xf86OutputPtr output;
+    ddc_quirk_t quirks;
+    Bool ret;
+};
+
+static void  handle_detailed_physical_size(struct detailed_monitor_section
+		                          *det_mon, void *data)
+{
+    struct det_phySize_parameter *p;
+    p = (struct det_phySize_parameter *)data;
+
+    if (p->ret == TRUE )
+        return ;
+
+    xf86DetTimingApplyQuirks(det_mon, p->quirks,
+                             p->output->MonInfo->features.hsize,
+                             p->output->MonInfo->features.vsize);
+    if (det_mon->type == DT &&
+        det_mon->section.d_timings.h_size != 0 &&
+        det_mon->section.d_timings.v_size != 0) {
+
+        p->output->mm_width = det_mon->section.d_timings.h_size;
+        p->output->mm_height = det_mon->section.d_timings.v_size;
+        p->ret = TRUE;
+    }
+}
+
+/**
+ * Set the EDID information for the specified output
+ */
+void
+xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
+{
+    ScrnInfoPtr		scrn = output->scrn;
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    Bool		debug_modes = config->debug_modes || xf86Initialising;
+#ifdef RANDR_12_INTERFACE
+    int			size;
+#endif
+    
+    free(output->MonInfo);
+    
+    output->MonInfo = edid_mon;
+    output->mm_width = 0;
+    output->mm_height = 0;
+
+    if (debug_modes) {
+	xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n",
+		   output->name);
+	xf86PrintEDID(edid_mon);
+    }
+
+    /* Set the DDC properties for the 'compat' output */
+    if (output == xf86CompatOutput(scrn))
+        xf86SetDDCproperties(scrn, edid_mon);
+
+#ifdef RANDR_12_INTERFACE
+    /* Set the RandR output properties */
+    size = 0;
+    if (edid_mon)
+    {
+	if (edid_mon->ver.version == 1) {
+	    size = 128;
+	    if (edid_mon->flags & EDID_COMPLETE_RAWDATA)
+		size += edid_mon->no_sections * 128;
+	} else if (edid_mon->ver.version == 2)
+	    size = 256;
+    }
+    xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size);
+#endif
+
+    if (edid_mon) {
+
+        struct det_phySize_parameter p;
+        p.output = output;
+        p.quirks = xf86DDCDetectQuirks(scrn->scrnIndex,edid_mon, FALSE);
+        p.ret = FALSE;
+        xf86ForEachDetailedBlock(edid_mon,
+                                 handle_detailed_physical_size, &p);
+
+	/* if no mm size is available from a detailed timing, check the max size field */
+	if ((!output->mm_width || !output->mm_height) &&
+	    (edid_mon->features.hsize && edid_mon->features.vsize))
+	{
+	    output->mm_width = edid_mon->features.hsize * 10;
+	    output->mm_height = edid_mon->features.vsize * 10;
+	}
+    }
+}
+
+/**
+ * Return the list of modes supported by the EDID information
+ * stored in 'output'
+ */
+DisplayModePtr
+xf86OutputGetEDIDModes (xf86OutputPtr output)
+{
+    ScrnInfoPtr	scrn = output->scrn;
+    xf86MonPtr	edid_mon = output->MonInfo;
+
+    if (!edid_mon)
+	return NULL;
+    return xf86DDCGetModes(scrn->scrnIndex, edid_mon);
+}
+
+/* maybe we should care about DDC1?  meh. */
+xf86MonPtr
+xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
+{
+    ScrnInfoPtr	scrn = output->scrn;
+    xf86MonPtr mon;
+
+    mon = xf86DoEEDID(scrn->scrnIndex, pDDCBus, TRUE);
+    if (mon)
+        xf86DDCApplyQuirks(scrn->scrnIndex, mon);
+
+    return mon;
+}
+
+static char *_xf86ConnectorNames[] = {
+					"None", "VGA", "DVI-I", "DVI-D",
+					"DVI-A", "Composite", "S-Video",
+					"Component", "LFP", "Proprietary",
+					"HDMI", "DisplayPort",
+				     };
+char *
+xf86ConnectorGetName(xf86ConnectorType connector)
+{
+    return _xf86ConnectorNames[connector];
+}
+
+static void
+x86_crtc_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
+{
+    dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
+    dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
+    dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
+    dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
+
+    if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
+	dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
+}
+
+static void
+x86_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
+{
+    if (crtc->enabled) {
+	crtc_box->x1 = crtc->x;
+	crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
+	crtc_box->y1 = crtc->y;
+	crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
+    } else
+	crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
+}
+
+static int
+xf86_crtc_box_area(BoxPtr box)
+{
+    return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
+}
+
+/*
+ * Return the crtc covering 'box'. If two crtcs cover a portion of
+ * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
+ * with greater coverage
+ */
+
+static xf86CrtcPtr
+xf86_covering_crtc(ScrnInfoPtr pScrn,
+		   BoxPtr      box,
+		   xf86CrtcPtr desired,
+		   BoxPtr      crtc_box_ret)
+{
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    xf86CrtcPtr		crtc, best_crtc;
+    int			coverage, best_coverage;
+    int			c;
+    BoxRec		crtc_box, cover_box;
+
+    best_crtc = NULL;
+    best_coverage = 0;
+    crtc_box_ret->x1 = 0;
+    crtc_box_ret->x2 = 0;
+    crtc_box_ret->y1 = 0;
+    crtc_box_ret->y2 = 0;
+    for (c = 0; c < xf86_config->num_crtc; c++) {
+	crtc = xf86_config->crtc[c];
+	x86_crtc_box(crtc, &crtc_box);
+	x86_crtc_box_intersect(&cover_box, &crtc_box, box);
+	coverage = xf86_crtc_box_area(&cover_box);
+	if (coverage && crtc == desired) {
+	    *crtc_box_ret = crtc_box;
+	    return crtc;
+	} else if (coverage > best_coverage) {
+	    *crtc_box_ret = crtc_box;
+	    best_crtc = crtc;
+	    best_coverage = coverage;
+	}
+    }
+    return best_crtc;
+}
+
+/*
+ * For overlay video, compute the relevant CRTC and
+ * clip video to that.
+ *
+ * returning FALSE means there was a memory failure of some kind,
+ * not that the video shouldn't be displayed
+ */
+
+Bool
+xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
+			    xf86CrtcPtr *crtc_ret,
+			    xf86CrtcPtr desired_crtc,
+			    BoxPtr      dst,
+			    INT32	*xa,
+			    INT32	*xb,
+			    INT32	*ya,
+			    INT32	*yb,
+			    RegionPtr   reg,
+			    INT32	width,
+			    INT32	height)
+{
+    Bool	ret;
+    RegionRec	crtc_region_local;
+    RegionPtr	crtc_region = reg;
+    
+    if (crtc_ret) {
+	BoxRec		crtc_box;
+	xf86CrtcPtr	crtc = xf86_covering_crtc(pScrn, dst,
+						  desired_crtc,
+						  &crtc_box);
+
+	if (crtc) {
+	    RegionInit(&crtc_region_local, &crtc_box, 1);
+	    crtc_region = &crtc_region_local;
+	    RegionIntersect(crtc_region, crtc_region, reg);
+	}
+	*crtc_ret = crtc;
+    }
+
+    ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb, 
+				crtc_region, width, height);
+
+    if (crtc_region != reg)
+	RegionUninit(&crtc_region_local);
+
+    return ret;
+}
+
+xf86_crtc_notify_proc_ptr
+xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new)
+{
+    if (xf86CrtcConfigPrivateIndex != -1)
+    {
+	ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+	xf86_crtc_notify_proc_ptr	old;
+	
+	old = config->xf86_crtc_notify;
+	config->xf86_crtc_notify = new;
+	return old;
+    }
+    return NULL;
+}
+
+void
+xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old)
+{
+    if (xf86CrtcConfigPrivateIndex != -1)
+    {
+	ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+	xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    
+	config->xf86_crtc_notify = old;
+    }
+}
+
+void
+xf86_crtc_notify(ScreenPtr screen)
+{
+    ScrnInfoPtr		scrn = xf86Screens[screen->myNum];
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+    
+    if (config->xf86_crtc_notify)
+	config->xf86_crtc_notify(screen);
+}
+
+Bool
+xf86_crtc_supports_gamma(ScrnInfoPtr pScrn)
+{
+    if (xf86CrtcConfigPrivateIndex != -1) {
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	xf86CrtcPtr crtc;
+
+	/* for multiple drivers loaded we need this */
+	if (!xf86_config)
+		return FALSE;
+	if (xf86_config->num_crtc == 0)
+	    return FALSE;
+	crtc = xf86_config->crtc[0];
+
+	return crtc->funcs->gamma_set != NULL;
+    }
+
+    return FALSE;
+}
diff --git a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h
index 147a201ee..6374ccab3 100644
--- a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h
+++ b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h
@@ -1,419 +1,414 @@
-/*
- * Copyright 1990, 1991 by Thomas Roell, Dinkelscherben, Germany
- * Copyright 1992 by David Dawes <dawes@XFree86.org>
- * Copyright 1992 by Jim Tsillas <jtsilla@damon.ccs.northeastern.edu>
- * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
- * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
- * Copyright 1992 by Orest Zborowski <obz@eskimo.com>
- * Copyright 1993 by Vrije Universiteit, The Netherlands
- * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
- * Copyright 1994, 1996 by Holger Veit <Holger.Veit@gmd.de>
- * Copyright 1997 by Takis Psarogiannakopoulos <takis@dpmms.cam.ac.uk>
- * Copyright 1994-2003 by The XFree86 Project, Inc
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the names of the above listed copyright holders 
- * not be used in advertising or publicity pertaining to distribution of 
- * the software without specific, written prior permission.  The above listed
- * copyright holders make no representations about the suitability of this 
- * software for any purpose.  It is provided "as is" without express or 
- * implied warranty.
- *
- * THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD 
- * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
- * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS BE 
- * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-/*
- * The ARM32 code here carries the following copyright:
- *
- * Copyright 1997
- * Digital Equipment Corporation. All rights reserved.
- * This software is furnished under license and may be used and copied only in 
- * accordance with the following terms and conditions.  Subject to these
- * conditions, you may download, copy, install, use, modify and distribute
- * this software in source and/or binary form. No title or ownership is
- * transferred hereby.
- *
- * 1) Any source code used, modified or distributed must reproduce and retain
- *    this copyright notice and list of conditions as they appear in the
- *    source file.
- *
- * 2) No right is granted to use any trade name, trademark, or logo of Digital 
- *    Equipment Corporation. Neither the "Digital Equipment Corporation"
- *    name nor any trademark or logo of Digital Equipment Corporation may be
- *    used to endorse or promote products derived from this software without
- *    the prior written permission of Digital Equipment Corporation.
- *
- * 3) This software is provided "AS-IS" and any express or implied warranties,
- *    including but not limited to, any implied warranties of merchantability,
- *    fitness for a particular purpose, or non-infringement are disclaimed.
- *    In no event shall DIGITAL be liable for any damages whatsoever, and in
- *    particular, DIGITAL shall not be liable for special, indirect,
- *    consequential, or incidental damages or damages for lost profits, loss
- *    of revenue or loss of use, whether such damages arise in contract, 
- *    negligence, tort, under statute, in equity, at law or otherwise, even
- *    if advised of the possibility of such damage. 
- *
- */
-
-/*
- * This is private, and should not be included by any drivers.  Drivers
- * may include xf86_OSproc.h to get prototypes for public interfaces.
- */
-
-#ifndef _XF86_OSLIB_H
-#define _XF86_OSLIB_H
-
-#include <X11/Xos.h>
-#include <X11/Xfuncproto.h>
-
-#include <stdio.h>
-#include <ctype.h>
-#include <stddef.h>
-
-/**************************************************************************/
-/* SYSV386 (SVR3, SVR4), including Solaris                                */
-/**************************************************************************/
-#if (defined(SYSV) || defined(SVR4)) && \
-    (defined(sun) || defined(__i386__))
-# include <sys/ioctl.h>
-# include <signal.h>
-# include <termio.h>
-# include <sys/stat.h>
-# include <sys/types.h>
-
-
-# include <errno.h>
-
-# if defined(_NEED_SYSI86)
-#  if !(defined (sun) && defined (SVR4))
-#    include <sys/immu.h>
-#    include <sys/region.h>
-#  endif
-#  include <sys/proc.h>
-#  include <sys/tss.h>
-#  include <sys/sysi86.h>
-#  if defined(SVR4) && !defined(sun)
-#   include <sys/seg.h>
-#  endif /* SVR4 && !sun */
-/* V86SC_IOPL was moved to <sys/sysi86.h> on Solaris 7 and later */
-#  if !defined(V86SC_IOPL)			/* Solaris 7 or later? */
-#   include <sys/v86.h>				/* Nope */
-#  endif
-#  if defined(sun) && (defined (__i386__) || defined(__i386) || defined(__x86))  && defined (SVR4)
-#    include <sys/psw.h>
-#  endif
-# endif /* _NEED_SYSI86 */
-
-# if defined(HAS_SVR3_MMAPDRV)
-#  include <sys/sysmacros.h>
-#  if !defined(_NEED_SYSI86)
-#   include <sys/immu.h>
-#   include <sys/region.h>
-#  endif
-#  include <sys/mmap.h>		/* MMAP driver header */
-# endif
-
-# if !defined(sun) || defined(HAVE_SYS_VT_H)
-#  define HAS_USL_VTS
-# endif
-# if !defined(sun)
-#  include <sys/emap.h>
-# endif
-# if   defined(HAS_USL_VTS)
-#  if !defined(sun)
-#   include <sys/at_ansi.h>
-#  endif
-#  include <sys/kd.h>
-#  include <sys/vt.h>
-# endif
-
-# if defined(sun)
-#  include <sys/fbio.h>
-#  include <sys/kbd.h> 
-#  include <sys/kbio.h>
-
-/* undefine symbols from <sys/kbd.h> we don't need that conflict with enum
-   definitions in parser/xf86tokens.h */
-#  undef STRING
-#  undef LEFTALT
-#  undef RIGHTALT
-
-#  define LED_CAP LED_CAPS_LOCK
-#  define LED_NUM LED_NUM_LOCK
-#  define LED_SCR LED_SCROLL_LOCK
-#  define LED_COMP LED_COMPOSE
-# endif /* sun */
-
-# if !defined(VT_ACKACQ)
-#  define VT_ACKACQ 2
-# endif /* !VT_ACKACQ */
-
-
-# if defined(SVR4) 
-#  include <sys/mman.h>
-#  if !(defined(sun) && defined (SVR4))
-#    define DEV_MEM "/dev/pmem"
-#  endif
-#  define CLEARDTR_SUPPORT
-#  define POSIX_TTY
-# endif /* SVR4 */
-
-
-# if defined(sun) && defined(HAS_USL_VTS)
-#  define USE_VT_SYSREQ
-# endif
-
-#endif /* (SYSV || SVR4) */
-
-/**************************************************************************/
-/* Linux or Glibc-based system                                            */
-/**************************************************************************/
-#if defined(__linux__) || defined(__GLIBC__)
-# include <sys/ioctl.h>
-# include <signal.h>
-# include <stdlib.h>
-# include <sys/types.h>
-# include <assert.h>
-
-# ifdef __linux__
-#  include <termio.h>
-# else /* __GLIBC__ */
-#  include <termios.h>
-# endif
-# ifdef __sparc__
-#  include <sys/param.h>
-# endif
-
-# include <errno.h>
-
-# include <sys/stat.h>
-
-# include <sys/mman.h>
-# ifdef __linux__
-#  define HAS_USL_VTS
-#  include <sys/kd.h>
-#  include <sys/vt.h>
-#  define LDGMAP GIO_SCRNMAP
-#  define LDSMAP PIO_SCRNMAP
-#  define LDNMAP LDSMAP
-#  define CLEARDTR_SUPPORT
-#  define USE_VT_SYSREQ
-# endif
-
-# define POSIX_TTY
-
-#endif /* __linux__ || __GLIBC__ */
-
-/**************************************************************************/
-/* 386BSD and derivatives,  BSD/386                                       */
-/**************************************************************************/
-
-#if defined(__386BSD__) && (defined(__FreeBSD__) || defined(__NetBSD__))
-# undef __386BSD__
-#endif
-
-#ifdef CSRG_BASED
-# include <sys/ioctl.h>
-# include <signal.h>
-
-# include <termios.h>
-# define termio termios
-# define POSIX_TTY
-
-# include <errno.h>
-
-# include <sys/types.h>
-# include <sys/mman.h>
-# include <sys/stat.h>
-
-# if defined(__bsdi__)
-#  include <sys/param.h>
-# if (_BSDI_VERSION < 199510)
-#  include <i386/isa/vgaioctl.h>
-# endif
-# endif /* __bsdi__ */
-
-#endif /* CSRG_BASED */
-
-/**************************************************************************/
-/* Kernel of *BSD                                                         */
-/**************************************************************************/
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
- defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
-
-# include <sys/param.h>
-# if defined(__FreeBSD_version) && !defined(__FreeBSD_kernel_version)
-#  define __FreeBSD_kernel_version __FreeBSD_version
-# endif
-
-# if !defined(LINKKIT)
-  /* Don't need this stuff for the Link Kit */
-#  if defined(__bsdi__)
-#   include <i386/isa/pcconsioctl.h>
-#   define CONSOLE_X_MODE_ON PCCONIOCRAW
-#   define CONSOLE_X_MODE_OFF PCCONIOCCOOK
-#   define CONSOLE_X_BELL PCCONIOCBEEP
-#  else /* __bsdi__ */
-#   ifdef SYSCONS_SUPPORT
-#    define COMPAT_SYSCONS
-#    if defined(__NetBSD__) || defined(__OpenBSD__)
-#     include <machine/console.h>
-#    else
-#     if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-#        if defined(__DragonFly__)  || (__FreeBSD_kernel_version >= 410000)
-#          include <sys/consio.h>
-#          include <sys/kbio.h>
-#        else
-#          include <machine/console.h>
-#        endif /* FreeBSD 4.1 RELEASE or lator */
-#     else
-#      include <sys/console.h>
-#     endif
-#    endif
-#   endif /* SYSCONS_SUPPORT */
-#   if defined(PCVT_SUPPORT)
-#    if !defined(SYSCONS_SUPPORT)
-      /* no syscons, so include pcvt specific header file */
-#     if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#      include <machine/pcvt_ioctl.h>
-#     else
-#      if defined(__NetBSD__) || defined(__OpenBSD__)
-#       if !defined(WSCONS_SUPPORT)
-#        include <machine/pcvt_ioctl.h>
-#       endif /* WSCONS_SUPPORT */
-#      else
-#       include <sys/pcvt_ioctl.h>
-#      endif /* __NetBSD__ */
-#     endif /* __FreeBSD_kernel__ || __OpenBSD__ */
-#    else /* pcvt and syscons: hard-code the ID magic */
-#     define VGAPCVTID _IOWR('V',113, struct pcvtid)
-      struct pcvtid {
-	char name[16];
-	int rmajor, rminor;
-      };
-#    endif /* PCVT_SUPPORT && SYSCONS_SUPPORT */
-#   endif /* PCVT_SUPPORT */
-#   ifdef WSCONS_SUPPORT
-#    include <dev/wscons/wsconsio.h>
-#    include <dev/wscons/wsdisplay_usl_io.h>
-#   endif /* WSCONS_SUPPORT */
-#   if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-#    if defined(__FreeBSD_kernel_version) && (__FreeBSD_kernel_version >= 500013)
-#     include <sys/mouse.h>
-#    else
-#     undef MOUSE_GETINFO
-#     include <machine/mouse.h>
-#    endif
-#   endif
-    /* Include these definitions in case ioctl_pc.h didn't get included */
-#   ifndef CONSOLE_X_MODE_ON
-#    define CONSOLE_X_MODE_ON _IO('t',121)
-#   endif
-#   ifndef CONSOLE_X_MODE_OFF
-#    define CONSOLE_X_MODE_OFF _IO('t',122)
-#   endif
-#   ifndef CONSOLE_X_BELL
-#    define CONSOLE_X_BELL _IOW('t',123,int[2])
-#   endif
-#   ifndef CONSOLE_X_TV_ON
-#    define CONSOLE_X_TV_ON _IOW('t',155,int)
-#    define XMODE_RGB   0
-#    define XMODE_NTSC  1
-#    define XMODE_PAL   2
-#    define XMODE_SECAM 3
-#   endif
-#   ifndef CONSOLE_X_TV_OFF
-#    define CONSOLE_X_TV_OFF _IO('t',156)
-#   endif
-#ifndef CONSOLE_GET_LINEAR_INFO
-#    define CONSOLE_GET_LINEAR_INFO         _IOR('t',157,struct map_info)
-#endif
-#ifndef CONSOLE_GET_IO_INFO 
-#    define CONSOLE_GET_IO_INFO             _IOR('t',158,struct map_info)
-#endif
-#ifndef CONSOLE_GET_MEM_INFO 
-#    define CONSOLE_GET_MEM_INFO            _IOR('t',159,struct map_info)
-#endif
-#  endif /* __bsdi__ */
-# endif /* !LINKKIT */
-
-#if defined(USE_I386_IOPL) || defined(USE_AMD64_IOPL)
-#include <machine/sysarch.h>
-#endif
-
-# define CLEARDTR_SUPPORT
-
-# if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) || defined(WSCONS_SUPPORT)
-#  define USE_VT_SYSREQ
-# endif
-
-#endif
-/* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ || __bsdi__ */
-
-/**************************************************************************/
-/* IRIX                                                                   */
-/**************************************************************************/
-
-/**************************************************************************/
-/* Generic                                                                */
-/**************************************************************************/
-
-#include <sys/wait.h>	/* May need to adjust this for other OSs */
-
-/* 
- * Hack originally for ISC 2.2 POSIX headers, but may apply elsewhere,
- * and it's safe, so just do it.
- */
-#if !defined(O_NDELAY) && defined(O_NONBLOCK)
-# define O_NDELAY O_NONBLOCK
-#endif /* !O_NDELAY && O_NONBLOCK */
-
-#if !defined(MAXHOSTNAMELEN)
-# define MAXHOSTNAMELEN 32
-#endif /* !MAXHOSTNAMELEN */
-
-#if defined(_POSIX_SOURCE)
-# include <limits.h>
-#else
-# define _POSIX_SOURCE
-# include <limits.h>
-# undef _POSIX_SOURCE
-#endif /* _POSIX_SOURCE */
-
-#if !defined(PATH_MAX)
-# if defined(MAXPATHLEN)
-#  define PATH_MAX MAXPATHLEN
-# else
-#  define PATH_MAX 1024
-# endif /* MAXPATHLEN */
-#endif /* !PATH_MAX */
-
-
-#ifndef DEV_MEM
-#define DEV_MEM "/dev/mem"
-#endif
-
-#ifndef VT_SYSREQ_DEFAULT
-#define VT_SYSREQ_DEFAULT FALSE
-#endif
-
-#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
-
-#define XF86_OS_PRIVS
-#include "xf86_OSproc.h"
-
-#ifndef NO_COMPILER_H
-#include "compiler.h"
-#endif
-
-#endif /* _XF86_OSLIB_H */
+/*
+ * Copyright 1990, 1991 by Thomas Roell, Dinkelscherben, Germany
+ * Copyright 1992 by David Dawes <dawes@XFree86.org>
+ * Copyright 1992 by Jim Tsillas <jtsilla@damon.ccs.northeastern.edu>
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * Copyright 1992 by Robert Baron <Robert.Baron@ernst.mach.cs.cmu.edu>
+ * Copyright 1992 by Orest Zborowski <obz@eskimo.com>
+ * Copyright 1993 by Vrije Universiteit, The Netherlands
+ * Copyright 1993 by David Wexelblat <dwex@XFree86.org>
+ * Copyright 1994, 1996 by Holger Veit <Holger.Veit@gmd.de>
+ * Copyright 1997 by Takis Psarogiannakopoulos <takis@dpmms.cam.ac.uk>
+ * Copyright 1994-2003 by The XFree86 Project, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of the above listed copyright holders 
+ * not be used in advertising or publicity pertaining to distribution of 
+ * the software without specific, written prior permission.  The above listed
+ * copyright holders make no representations about the suitability of this 
+ * software for any purpose.  It is provided "as is" without express or 
+ * implied warranty.
+ *
+ * THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD 
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
+ * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS BE 
+ * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 
+ * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * The ARM32 code here carries the following copyright:
+ *
+ * Copyright 1997
+ * Digital Equipment Corporation. All rights reserved.
+ * This software is furnished under license and may be used and copied only in 
+ * accordance with the following terms and conditions.  Subject to these
+ * conditions, you may download, copy, install, use, modify and distribute
+ * this software in source and/or binary form. No title or ownership is
+ * transferred hereby.
+ *
+ * 1) Any source code used, modified or distributed must reproduce and retain
+ *    this copyright notice and list of conditions as they appear in the
+ *    source file.
+ *
+ * 2) No right is granted to use any trade name, trademark, or logo of Digital 
+ *    Equipment Corporation. Neither the "Digital Equipment Corporation"
+ *    name nor any trademark or logo of Digital Equipment Corporation may be
+ *    used to endorse or promote products derived from this software without
+ *    the prior written permission of Digital Equipment Corporation.
+ *
+ * 3) This software is provided "AS-IS" and any express or implied warranties,
+ *    including but not limited to, any implied warranties of merchantability,
+ *    fitness for a particular purpose, or non-infringement are disclaimed.
+ *    In no event shall DIGITAL be liable for any damages whatsoever, and in
+ *    particular, DIGITAL shall not be liable for special, indirect,
+ *    consequential, or incidental damages or damages for lost profits, loss
+ *    of revenue or loss of use, whether such damages arise in contract, 
+ *    negligence, tort, under statute, in equity, at law or otherwise, even
+ *    if advised of the possibility of such damage. 
+ *
+ */
+
+/*
+ * This is private, and should not be included by any drivers.  Drivers
+ * may include xf86_OSproc.h to get prototypes for public interfaces.
+ */
+
+#ifndef _XF86_OSLIB_H
+#define _XF86_OSLIB_H
+
+#include <X11/Xos.h>
+#include <X11/Xfuncproto.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stddef.h>
+
+/**************************************************************************/
+/* SYSV386 (SVR3, SVR4), including Solaris                                */
+/**************************************************************************/
+#if (defined(SYSV) || defined(SVR4)) && \
+    (defined(sun) || defined(__i386__))
+# include <sys/ioctl.h>
+# include <signal.h>
+# include <termio.h>
+# include <sys/stat.h>
+# include <sys/types.h>
+
+
+# include <errno.h>
+
+# if defined(_NEED_SYSI86)
+#  if !(defined (sun) && defined (SVR4))
+#    include <sys/immu.h>
+#    include <sys/region.h>
+#  endif
+#  include <sys/proc.h>
+#  include <sys/tss.h>
+#  include <sys/sysi86.h>
+#  if defined(SVR4) && !defined(sun)
+#   include <sys/seg.h>
+#  endif /* SVR4 && !sun */
+/* V86SC_IOPL was moved to <sys/sysi86.h> on Solaris 7 and later */
+#  if !defined(V86SC_IOPL)			/* Solaris 7 or later? */
+#   include <sys/v86.h>				/* Nope */
+#  endif
+#  if defined(sun) && (defined (__i386__) || defined(__i386) || defined(__x86))  && defined (SVR4)
+#    include <sys/psw.h>
+#  endif
+# endif /* _NEED_SYSI86 */
+
+# if defined(HAS_SVR3_MMAPDRV)
+#  include <sys/sysmacros.h>
+#  if !defined(_NEED_SYSI86)
+#   include <sys/immu.h>
+#   include <sys/region.h>
+#  endif
+#  include <sys/mmap.h>		/* MMAP driver header */
+# endif
+
+# if !defined(sun) || defined(HAVE_SYS_VT_H)
+#  define HAS_USL_VTS
+# endif
+# if !defined(sun)
+#  include <sys/emap.h>
+# endif
+# if   defined(HAS_USL_VTS)
+#  if !defined(sun)
+#   include <sys/at_ansi.h>
+#  endif
+#  include <sys/kd.h>
+#  include <sys/vt.h>
+# endif
+
+# if defined(sun)
+#  include <sys/fbio.h>
+#  include <sys/kbd.h> 
+#  include <sys/kbio.h>
+
+/* undefine symbols from <sys/kbd.h> we don't need that conflict with enum
+   definitions in parser/xf86tokens.h */
+#  undef STRING
+#  undef LEFTALT
+#  undef RIGHTALT
+
+#  define LED_CAP LED_CAPS_LOCK
+#  define LED_NUM LED_NUM_LOCK
+#  define LED_SCR LED_SCROLL_LOCK
+#  define LED_COMP LED_COMPOSE
+# endif /* sun */
+
+# if !defined(VT_ACKACQ)
+#  define VT_ACKACQ 2
+# endif /* !VT_ACKACQ */
+
+
+# if defined(SVR4) 
+#  include <sys/mman.h>
+#  if !(defined(sun) && defined (SVR4))
+#    define DEV_MEM "/dev/pmem"
+#  endif
+#  define CLEARDTR_SUPPORT
+#  define POSIX_TTY
+# endif /* SVR4 */
+
+
+# if defined(sun) && defined(HAS_USL_VTS)
+#  define USE_VT_SYSREQ
+# endif
+
+#endif /* (SYSV || SVR4) */
+
+/**************************************************************************/
+/* Linux or Glibc-based system                                            */
+/**************************************************************************/
+#if defined(__linux__) || defined(__GLIBC__)
+# include <sys/ioctl.h>
+# include <signal.h>
+# include <stdlib.h>
+# include <sys/types.h>
+# include <assert.h>
+
+# ifdef __linux__
+#  include <termio.h>
+# else /* __GLIBC__ */
+#  include <termios.h>
+# endif
+# ifdef __sparc__
+#  include <sys/param.h>
+# endif
+
+# include <errno.h>
+
+# include <sys/stat.h>
+
+# include <sys/mman.h>
+# ifdef __linux__
+#  define HAS_USL_VTS
+#  include <sys/kd.h>
+#  include <sys/vt.h>
+#  define LDGMAP GIO_SCRNMAP
+#  define LDSMAP PIO_SCRNMAP
+#  define LDNMAP LDSMAP
+#  define CLEARDTR_SUPPORT
+#  define USE_VT_SYSREQ
+# endif
+
+# define POSIX_TTY
+
+#endif /* __linux__ || __GLIBC__ */
+
+/**************************************************************************/
+/* 386BSD and derivatives,  BSD/386                                       */
+/**************************************************************************/
+
+#if defined(__386BSD__) && (defined(__FreeBSD__) || defined(__NetBSD__))
+# undef __386BSD__
+#endif
+
+#ifdef CSRG_BASED
+# include <sys/ioctl.h>
+# include <signal.h>
+
+# include <termios.h>
+# define termio termios
+# define POSIX_TTY
+
+# include <errno.h>
+
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+
+# if defined(__bsdi__)
+#  include <sys/param.h>
+# if (_BSDI_VERSION < 199510)
+#  include <i386/isa/vgaioctl.h>
+# endif
+# endif /* __bsdi__ */
+
+#endif /* CSRG_BASED */
+
+/**************************************************************************/
+/* Kernel of *BSD                                                         */
+/**************************************************************************/
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
+ defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__)
+
+# include <sys/param.h>
+# if defined(__FreeBSD_version) && !defined(__FreeBSD_kernel_version)
+#  define __FreeBSD_kernel_version __FreeBSD_version
+# endif
+
+# if !defined(LINKKIT)
+  /* Don't need this stuff for the Link Kit */
+#  if defined(__bsdi__)
+#   include <i386/isa/pcconsioctl.h>
+#   define CONSOLE_X_MODE_ON PCCONIOCRAW
+#   define CONSOLE_X_MODE_OFF PCCONIOCCOOK
+#   define CONSOLE_X_BELL PCCONIOCBEEP
+#  else /* __bsdi__ */
+#   ifdef SYSCONS_SUPPORT
+#    define COMPAT_SYSCONS
+#    if defined(__NetBSD__) || defined(__OpenBSD__)
+#     include <machine/console.h>
+#    else
+#     if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+#        if defined(__DragonFly__)  || (__FreeBSD_kernel_version >= 410000)
+#          include <sys/consio.h>
+#          include <sys/kbio.h>
+#        else
+#          include <machine/console.h>
+#        endif /* FreeBSD 4.1 RELEASE or lator */
+#     else
+#      include <sys/console.h>
+#     endif
+#    endif
+#   endif /* SYSCONS_SUPPORT */
+#   if defined(PCVT_SUPPORT)
+#    if !defined(SYSCONS_SUPPORT)
+      /* no syscons, so include pcvt specific header file */
+#     if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+#      include <machine/pcvt_ioctl.h>
+#     else
+#      if defined(__NetBSD__) || defined(__OpenBSD__)
+#       if !defined(WSCONS_SUPPORT)
+#        include <machine/pcvt_ioctl.h>
+#       endif /* WSCONS_SUPPORT */
+#      else
+#       include <sys/pcvt_ioctl.h>
+#      endif /* __NetBSD__ */
+#     endif /* __FreeBSD_kernel__ || __OpenBSD__ */
+#    else /* pcvt and syscons: hard-code the ID magic */
+#     define VGAPCVTID _IOWR('V',113, struct pcvtid)
+      struct pcvtid {
+	char name[16];
+	int rmajor, rminor;
+      };
+#    endif /* PCVT_SUPPORT && SYSCONS_SUPPORT */
+#   endif /* PCVT_SUPPORT */
+#   ifdef WSCONS_SUPPORT
+#    include <dev/wscons/wsconsio.h>
+#    include <dev/wscons/wsdisplay_usl_io.h>
+#   endif /* WSCONS_SUPPORT */
+#   if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+#    if defined(__FreeBSD_kernel_version) && (__FreeBSD_kernel_version >= 500013)
+#     include <sys/mouse.h>
+#    else
+#     undef MOUSE_GETINFO
+#     include <machine/mouse.h>
+#    endif
+#   endif
+    /* Include these definitions in case ioctl_pc.h didn't get included */
+#   ifndef CONSOLE_X_MODE_ON
+#    define CONSOLE_X_MODE_ON _IO('t',121)
+#   endif
+#   ifndef CONSOLE_X_MODE_OFF
+#    define CONSOLE_X_MODE_OFF _IO('t',122)
+#   endif
+#   ifndef CONSOLE_X_BELL
+#    define CONSOLE_X_BELL _IOW('t',123,int[2])
+#   endif
+#   ifndef CONSOLE_X_TV_ON
+#    define CONSOLE_X_TV_ON _IOW('t',155,int)
+#    define XMODE_RGB   0
+#    define XMODE_NTSC  1
+#    define XMODE_PAL   2
+#    define XMODE_SECAM 3
+#   endif
+#   ifndef CONSOLE_X_TV_OFF
+#    define CONSOLE_X_TV_OFF _IO('t',156)
+#   endif
+#ifndef CONSOLE_GET_LINEAR_INFO
+#    define CONSOLE_GET_LINEAR_INFO         _IOR('t',157,struct map_info)
+#endif
+#ifndef CONSOLE_GET_IO_INFO 
+#    define CONSOLE_GET_IO_INFO             _IOR('t',158,struct map_info)
+#endif
+#ifndef CONSOLE_GET_MEM_INFO 
+#    define CONSOLE_GET_MEM_INFO            _IOR('t',159,struct map_info)
+#endif
+#  endif /* __bsdi__ */
+# endif /* !LINKKIT */
+
+#if defined(USE_I386_IOPL) || defined(USE_AMD64_IOPL)
+#include <machine/sysarch.h>
+#endif
+
+# define CLEARDTR_SUPPORT
+
+# if defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT) || defined(WSCONS_SUPPORT)
+#  define USE_VT_SYSREQ
+# endif
+
+#endif
+/* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ || __bsdi__ */
+
+/**************************************************************************/
+/* IRIX                                                                   */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Generic                                                                */
+/**************************************************************************/
+
+#include <sys/wait.h>	/* May need to adjust this for other OSs */
+
+/* For PATH_MAX */
+#include "misc.h"
+
+/* 
+ * Hack originally for ISC 2.2 POSIX headers, but may apply elsewhere,
+ * and it's safe, so just do it.
+ */
+#if !defined(O_NDELAY) && defined(O_NONBLOCK)
+# define O_NDELAY O_NONBLOCK
+#endif /* !O_NDELAY && O_NONBLOCK */
+
+#if !defined(MAXHOSTNAMELEN)
+# define MAXHOSTNAMELEN 32
+#endif /* !MAXHOSTNAMELEN */
+
+#if defined(_POSIX_SOURCE)
+# include <limits.h>
+#else
+# define _POSIX_SOURCE
+# include <limits.h>
+# undef _POSIX_SOURCE
+#endif /* _POSIX_SOURCE */
+
+
+#ifndef DEV_MEM
+#define DEV_MEM "/dev/mem"
+#endif
+
+#ifndef VT_SYSREQ_DEFAULT
+#define VT_SYSREQ_DEFAULT FALSE
+#endif
+
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+#define XF86_OS_PRIVS
+#include "xf86_OSproc.h"
+
+#ifndef NO_COMPILER_H
+#include "compiler.h"
+#endif
+
+#endif /* _XF86_OSLIB_H */
diff --git a/xorg-server/hw/xfree86/parser/scan.c b/xorg-server/hw/xfree86/parser/scan.c
index b829868f7..b36e58e0f 100644
--- a/xorg-server/hw/xfree86/parser/scan.c
+++ b/xorg-server/hw/xfree86/parser/scan.c
@@ -77,18 +77,13 @@
 #undef _POSIX_SOURCE
 #endif /* _POSIX_SOURCE */
 
-#if !defined(PATH_MAX)
-#if defined(MAXPATHLEN)
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 1024
-#endif /* MAXPATHLEN */
-#endif /* !PATH_MAX */
-
 #if !defined(MAXHOSTNAMELEN)
 #define MAXHOSTNAMELEN 32
 #endif /* !MAXHOSTNAMELEN */
 
+/* For PATH_MAX */
+#include "misc.h"
+
 #include "Configint.h"
 #include "xf86tokens.h"
 
diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h
index 643866f98..ec915b37e 100644
--- a/xorg-server/include/input.h
+++ b/xorg-server/include/input.h
@@ -1,595 +1,593 @@
-/************************************************************
-
-Copyright 1987, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-********************************************************/
-
-#ifndef INPUT_H
-#define INPUT_H
-
-#include "misc.h"
-#include "screenint.h"
-#include <X11/Xmd.h>
-#include <X11/Xproto.h>
-#include <stdint.h>
-#include "window.h"     /* for WindowPtr */
-#include "xkbrules.h"
-#include "events.h"
-
-#define DEVICE_INIT	0
-#define DEVICE_ON	1
-#define DEVICE_OFF	2
-#define DEVICE_CLOSE	3
-
-#define POINTER_RELATIVE (1 << 1)
-#define POINTER_ABSOLUTE (1 << 2)
-#define POINTER_ACCELERATE (1 << 3)
-#define POINTER_SCREEN (1 << 4) /* Data in screen coordinates */
-
-/*int constants for pointer acceleration schemes*/
-#define PtrAccelNoOp            0
-#define PtrAccelPredictable     1
-#define PtrAccelLightweight     2
-#define PtrAccelDefault         PtrAccelPredictable
-
-#define MAX_VALUATORS 36
-/* Maximum number of valuators, divided by six, rounded up, to get number
- * of events. */
-#define MAX_VALUATOR_EVENTS 6
-#define MAX_BUTTONS 256 /* completely arbitrarily chosen */
-
-#define NO_AXIS_LIMITS -1
-
-#define MAP_LENGTH	256
-#define DOWN_LENGTH	32	/* 256/8 => number of bytes to hold 256 bits */
-#define NullGrab ((GrabPtr)NULL)
-#define PointerRootWin ((WindowPtr)PointerRoot)
-#define NoneWin ((WindowPtr)None)
-#define NullDevice ((DevicePtr)NULL)
-
-#ifndef FollowKeyboard
-#define FollowKeyboard 		3
-#endif
-#ifndef FollowKeyboardWin
-#define FollowKeyboardWin  ((WindowPtr) FollowKeyboard)
-#endif
-#ifndef RevertToFollowKeyboard
-#define RevertToFollowKeyboard	3
-#endif
-
-typedef unsigned long Leds;
-typedef struct _OtherClients *OtherClientsPtr;
-typedef struct _InputClients *InputClientsPtr;
-typedef struct _DeviceIntRec *DeviceIntPtr;
-typedef struct _ClassesRec *ClassesPtr;
-typedef struct _SpriteRec *SpritePtr;
-typedef union _GrabMask GrabMask;
-
-typedef struct _EventList {
-    xEvent* event;
-    int evlen; /* length of allocated memory for event in bytes.  This is not
-                  the actual length of the event. The event's actual length is
-                  32 for standard events or 32 +
-                  ((xGenericEvent*)event)->length * 4 for GenericEvents.
-                  For events in the EQ, the length is
-                  ((InternalEvent*)event)->u.any.length */
-} EventList, *EventListPtr;
-
-/* The DIX stores incoming input events in this list */
-extern EventListPtr InputEventList;
-extern int InputEventListLen;
-
-typedef int (*DeviceProc)(
-    DeviceIntPtr /*device*/,
-    int /*what*/);
-
-typedef void (*ProcessInputProc)(
-    InternalEvent * /*event*/,
-    DeviceIntPtr /*device*/);
-
-typedef Bool (*DeviceHandleProc)(
-    DeviceIntPtr /*device*/,
-    void* /*data*/
-    );
-
-typedef void (*DeviceUnwrapProc)(
-    DeviceIntPtr /*device*/,
-    DeviceHandleProc /*proc*/,
-    void* /*data*/
-    );
-
-/* pointer acceleration handling */
-typedef void (*PointerAccelSchemeProc)(
-    DeviceIntPtr /*pDev*/,
-    int /*first_valuator*/,
-    int /*num_valuators*/,
-    int* /*valuators*/,
-    int /*evtime*/);
-
-typedef void (*DeviceCallbackProc)(
-              DeviceIntPtr /*pDev*/);
-
-struct _ValuatorAccelerationRec;
-typedef Bool (*PointerAccelSchemeInitProc)(
-              DeviceIntPtr /*dev*/,
-              struct _ValuatorAccelerationRec* /*protoScheme*/);
-
-typedef struct _DeviceRec {
-    pointer	devicePrivate;
-    ProcessInputProc processInputProc;	/* current */
-    ProcessInputProc realInputProc;	/* deliver */
-    ProcessInputProc enqueueInputProc;	/* enqueue */
-    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;
-    unsigned char	autoRepeats[32];
-    Leds		leds;
-    unsigned char	id;
-} KeybdCtrl;
-
-typedef struct {
-    KeySym  *map;
-    KeyCode minKeyCode,
-	    maxKeyCode;
-    int     mapWidth;
-} KeySymsRec, *KeySymsPtr;
-
-typedef struct {
-    int		num, den, threshold;
-    unsigned char id;
-} PtrCtrl;
-
-typedef struct {
-    int         resolution, min_value, max_value;
-    int         integer_displayed;
-    unsigned char id;
-} IntegerCtrl;
-
-typedef struct {
-    int         max_symbols, num_symbols_supported;
-    int         num_symbols_displayed;
-    KeySym      *symbols_supported;
-    KeySym      *symbols_displayed;
-    unsigned char id;
-} StringCtrl;
-
-typedef struct {
-    int         percent, pitch, duration;
-    unsigned char id;
-} BellCtrl;
-
-typedef struct {
-    Leds        led_values;
-    Mask        led_mask;
-    unsigned char id;
-} LedCtrl;
-
-extern _X_EXPORT KeybdCtrl	defaultKeyboardControl;
-extern _X_EXPORT PtrCtrl	defaultPointerControl;
-
-typedef struct _InputOption {
-    char                *key;
-    char                *value;
-    struct _InputOption *next;
-} InputOption;
-
-typedef struct _InputAttributes {
-    char                *product;
-    char                *vendor;
-    char                *device;
-    char                *pnp_id;
-    char                *usb_id;
-    char                **tags; /* null-terminated */
-    uint32_t            flags;
-} InputAttributes;
-
-#define ATTR_KEYBOARD (1<<0)
-#define ATTR_POINTER (1<<1)
-#define ATTR_JOYSTICK (1<<2)
-#define ATTR_TABLET (1<<3)
-#define ATTR_TOUCHPAD (1<<4)
-#define ATTR_TOUCHSCREEN (1<<5)
-
-/* Key/Button has been run through all input processing and events sent to clients. */
-#define KEY_PROCESSED 1
-#define BUTTON_PROCESSED 1
-/* Key/Button has not been fully processed, no events have been sent. */
-#define KEY_POSTED 2
-#define BUTTON_POSTED 2
-
-extern void set_key_down(DeviceIntPtr pDev, int key_code, int type);
-extern void set_key_up(DeviceIntPtr pDev, int key_code, int type);
-extern int key_is_down(DeviceIntPtr pDev, int key_code, int type);
-extern void set_button_down(DeviceIntPtr pDev, int button, int type);
-extern void set_button_up(DeviceIntPtr pDev, int button, int type);
-extern int button_is_down(DeviceIntPtr pDev, int button, int type);
-
-extern void InitCoreDevices(void);
-extern void InitXTestDevices(void);
-
-extern _X_EXPORT DeviceIntPtr AddInputDevice(
-    ClientPtr /*client*/,
-    DeviceProc /*deviceProc*/,
-    Bool /*autoStart*/);
-
-extern _X_EXPORT Bool EnableDevice(
-    DeviceIntPtr /*device*/,
-    BOOL /* sendevent */);
-
-extern _X_EXPORT Bool ActivateDevice(
-    DeviceIntPtr /*device*/,
-    BOOL /* sendevent */);
-
-extern _X_EXPORT Bool DisableDevice(
-    DeviceIntPtr /*device*/,
-    BOOL /* sendevent */);
-
-extern int InitAndStartDevices(void);
-
-extern void CloseDownDevices(void);
-
-extern void UndisplayDevices(void);
-
-extern _X_EXPORT int RemoveDevice(
-    DeviceIntPtr /*dev*/,
-    BOOL /* sendevent */);
-
-extern _X_EXPORT int NumMotionEvents(void);
-
-extern _X_EXPORT int dixLookupDevice(
-    DeviceIntPtr *         /* dev */,
-    int                    /* id */,
-    ClientPtr              /* client */,
-    Mask                   /* access_mode */);
-
-extern _X_EXPORT void QueryMinMaxKeyCodes(
-    KeyCode* /*minCode*/,
-    KeyCode* /*maxCode*/);
-
-extern _X_EXPORT Bool SetKeySymsMap(
-    KeySymsPtr /*dst*/,
-    KeySymsPtr /*src*/);
-
-extern _X_EXPORT Bool InitButtonClassDeviceStruct(
-    DeviceIntPtr /*device*/,
-    int /*numButtons*/,
-    Atom* /* labels */,
-    CARD8* /*map*/);
-
-extern _X_EXPORT Bool InitValuatorClassDeviceStruct(
-    DeviceIntPtr /*device*/,
-    int /*numAxes*/,
-    Atom* /* labels */,
-    int /*numMotionEvents*/,
-    int /*mode*/);
-
-extern _X_EXPORT Bool InitPointerAccelerationScheme(
-    DeviceIntPtr /*dev*/,
-    int /*scheme*/);
-
-extern _X_EXPORT Bool InitAbsoluteClassDeviceStruct(
-    DeviceIntPtr /*device*/);
-
-extern _X_EXPORT Bool InitFocusClassDeviceStruct(
-    DeviceIntPtr /*device*/);
-
-typedef void (*BellProcPtr)(
-    int /*percent*/,
-    DeviceIntPtr /*device*/,
-    pointer /*ctrl*/,
-    int);
-
-typedef void (*KbdCtrlProcPtr)(
-    DeviceIntPtr /*device*/,
-    KeybdCtrl * /*ctrl*/);
-
-typedef void (*PtrCtrlProcPtr)(
-    DeviceIntPtr /*device*/,
-    PtrCtrl * /*ctrl*/);
-
-extern _X_EXPORT Bool InitPtrFeedbackClassDeviceStruct(
-    DeviceIntPtr /*device*/,
-    PtrCtrlProcPtr /*controlProc*/);
-
-typedef void (*StringCtrlProcPtr)(
-    DeviceIntPtr /*device*/,
-    StringCtrl * /*ctrl*/);
-
-extern _X_EXPORT Bool InitStringFeedbackClassDeviceStruct(
-    DeviceIntPtr /*device*/,
-    StringCtrlProcPtr /*controlProc*/,
-    int /*max_symbols*/,
-    int /*num_symbols_supported*/,
-    KeySym* /*symbols*/);
-
-typedef void (*BellCtrlProcPtr)(
-    DeviceIntPtr /*device*/,
-    BellCtrl * /*ctrl*/);
-
-extern _X_EXPORT Bool InitBellFeedbackClassDeviceStruct(
-    DeviceIntPtr /*device*/,
-    BellProcPtr /*bellProc*/,
-    BellCtrlProcPtr /*controlProc*/);
-
-typedef void (*LedCtrlProcPtr)(
-    DeviceIntPtr /*device*/,
-    LedCtrl * /*ctrl*/);
-
-extern _X_EXPORT Bool InitLedFeedbackClassDeviceStruct(
-    DeviceIntPtr /*device*/,
-    LedCtrlProcPtr /*controlProc*/);
-
-typedef void (*IntegerCtrlProcPtr)(
-    DeviceIntPtr /*device*/,
-    IntegerCtrl * /*ctrl*/);
-
-
-extern _X_EXPORT Bool InitIntegerFeedbackClassDeviceStruct(
-    DeviceIntPtr /*device*/,
-    IntegerCtrlProcPtr /*controlProc*/);
-
-extern _X_EXPORT Bool InitPointerDeviceStruct(
-    DevicePtr /*device*/,
-    CARD8* /*map*/,
-    int /*numButtons*/,
-    Atom* /* btn_labels */,
-    PtrCtrlProcPtr /*controlProc*/,
-    int /*numMotionEvents*/,
-    int /*numAxes*/,
-    Atom* /* axes_labels */);
-
-extern _X_EXPORT Bool InitKeyboardDeviceStruct(
-    DeviceIntPtr /*device*/,
-    XkbRMLVOSet * /*rmlvo*/,
-    BellProcPtr /*bellProc*/,
-    KbdCtrlProcPtr /*controlProc*/);
-
-extern int ApplyPointerMapping(
-    DeviceIntPtr /* pDev */,
-    CARD8 *      /* map */,
-    int          /* len */,
-    ClientPtr	/* client */);
-
-extern Bool BadDeviceMap(
-    BYTE* /*buff*/,
-    int /*length*/,
-    unsigned /*low*/,
-    unsigned /*high*/,
-    XID* /*errval*/);
-
-extern void NoteLedState(
-    DeviceIntPtr /*keybd*/,
-    int /*led*/,
-    Bool /*on*/);
-
-extern void MaybeStopHint(
-    DeviceIntPtr /*device*/,
-    ClientPtr /*client*/);
-
-extern void ProcessPointerEvent(
-    InternalEvent* /* ev */,
-    DeviceIntPtr /*mouse*/);
-
-extern void ProcessKeyboardEvent(
-    InternalEvent* /*ev*/,
-    DeviceIntPtr   /*keybd*/);
-
-extern Bool LegalModifier(
-    unsigned int /*key*/, 
-    DeviceIntPtr /*pDev*/);
-
-extern _X_EXPORT void ProcessInputEvents(void);
-
-extern _X_EXPORT void InitInput(
-    int  /*argc*/,
-    char ** /*argv*/);
-extern _X_EXPORT void CloseInput(void);
-
-extern _X_EXPORT int GetMaximumEventsNum(void);
-
-extern _X_EXPORT int GetEventList(EventListPtr* list);
-extern _X_EXPORT EventListPtr InitEventList(int num_events);
-extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events);
-
-extern void CreateClassesChangedEvent(EventListPtr event,
-                                      DeviceIntPtr master,
-                                      DeviceIntPtr slave,
-                                      int type);
-extern EventListPtr UpdateFromMaster(
-    EventListPtr events,
-    DeviceIntPtr pDev,
-    int type,
-    int *num_events);
-
-extern _X_EXPORT int GetPointerEvents(
-    EventListPtr events,
-    DeviceIntPtr pDev,
-    int type,
-    int buttons,
-    int flags,
-    const ValuatorMask *mask);
-
-extern _X_EXPORT int GetKeyboardEvents(
-    EventListPtr events,
-    DeviceIntPtr pDev,
-    int type,
-    int key_code);
-
-extern int GetKeyboardValuatorEvents(
-    EventListPtr events,
-    DeviceIntPtr pDev,
-    int type,
-    int key_code,
-    const ValuatorMask *mask);
-
-extern int GetProximityEvents(
-    EventListPtr events,
-    DeviceIntPtr pDev,
-    int type,
-    const ValuatorMask *mask);
-
-extern void PostSyntheticMotion(
-    DeviceIntPtr pDev,
-    int x,
-    int y,
-    int screen,
-    unsigned long time);
-
-extern _X_EXPORT int GetMotionHistorySize(
-    void);
-
-extern _X_EXPORT void AllocateMotionHistory(
-    DeviceIntPtr pDev);
-
-extern _X_EXPORT int GetMotionHistory(
-    DeviceIntPtr pDev,
-    xTimecoord **buff,
-    unsigned long start,
-    unsigned long stop,
-    ScreenPtr pScreen,
-    BOOL core);
-
-extern int AttachDevice(ClientPtr client,
-                        DeviceIntPtr slave,
-                        DeviceIntPtr master);
-
-extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
-extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
-
-extern _X_EXPORT int AllocDevicePair(ClientPtr client,
-                             char* name,
-                             DeviceIntPtr* ptr,
-                             DeviceIntPtr* keybd,
-                             DeviceProc ptr_proc,
-                             DeviceProc keybd_proc,
-                             Bool master);
-extern void DeepCopyDeviceClasses(DeviceIntPtr from,
-                                  DeviceIntPtr to,
-                                  DeviceChangedEvent *dce);
-
-/* Helper functions. */
-extern _X_EXPORT int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
-                              KeyCode **modkeymap, int *max_keys_per_mod);
-extern int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *map,
-                         int max_keys_per_mod);
-extern int AllocXTestDevice(ClientPtr client,
-                             char* name,
-                             DeviceIntPtr* ptr,
-                             DeviceIntPtr* keybd,
-                             DeviceIntPtr master_ptr,
-                             DeviceIntPtr master_keybd);
-extern BOOL IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master);
-extern DeviceIntPtr GetXTestDevice(DeviceIntPtr master);
-extern void SendDevicePresenceEvent(int deviceid, int type);
-extern _X_EXPORT InputAttributes *DuplicateInputAttributes(InputAttributes *attrs);
-extern _X_EXPORT void FreeInputAttributes(InputAttributes *attrs);
-
-/* misc event helpers */
-extern Mask GetEventMask(DeviceIntPtr dev, xEvent* ev, InputClientsPtr clients);
-extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
-extern Mask GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev);
-void FixUpEventFromWindow(SpritePtr pSprite,
-                          xEvent *xE,
-                          WindowPtr pWin,
-                          Window child,
-                          Bool calcChild);
-extern WindowPtr XYToWindow(SpritePtr pSprite, int x, int y);
-extern int EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event,
-                              WindowPtr win);
-/**
- * Masks specifying the type of event to deliver for an InternalEvent; used
- * by EventIsDeliverable.
- * @defgroup EventIsDeliverable return flags
- * @{
- */
-#define EVENT_XI1_MASK                (1 << 0) /**< XI1.x event */
-#define EVENT_CORE_MASK               (1 << 1) /**< Core event */
-#define EVENT_DONT_PROPAGATE_MASK     (1 << 2) /**< DontPropagate mask set */
-#define EVENT_XI2_MASK                (1 << 3) /**< XI2 mask set on window */
-/* @} */
-
-/* Implemented by the DDX. */
-extern _X_EXPORT int NewInputDeviceRequest(
-    InputOption *options,
-    InputAttributes *attrs,
-    DeviceIntPtr *dev);
-extern  _X_EXPORT void DeleteInputDeviceRequest(
-    DeviceIntPtr dev);
-
-extern _X_EXPORT void DDXRingBell(
-    int volume,
-    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;
-
-extern _X_EXPORT ValuatorMask  *valuator_mask_new(int num_valuators);
-extern _X_EXPORT void valuator_mask_free(ValuatorMask **mask);
-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);
-extern _X_EXPORT int valuator_mask_size(const ValuatorMask *mask);
-extern _X_EXPORT int valuator_mask_isset(const ValuatorMask *mask, int bit);
-extern _X_EXPORT void valuator_mask_unset(ValuatorMask *mask, int bit);
-extern _X_EXPORT int valuator_mask_num_valuators(const ValuatorMask *mask);
-extern _X_EXPORT void valuator_mask_copy(ValuatorMask *dest,
-                                         const ValuatorMask *src);
-extern _X_EXPORT int valuator_mask_get(const ValuatorMask *mask, int valnum);
-
-#endif /* INPUT_H */
+/************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+********************************************************/
+
+#ifndef INPUT_H
+#define INPUT_H
+
+#include "misc.h"
+#include "screenint.h"
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include <stdint.h>
+#include "window.h"     /* for WindowPtr */
+#include "xkbrules.h"
+#include "events.h"
+
+#define DEVICE_INIT	0
+#define DEVICE_ON	1
+#define DEVICE_OFF	2
+#define DEVICE_CLOSE	3
+
+#define POINTER_RELATIVE (1 << 1)
+#define POINTER_ABSOLUTE (1 << 2)
+#define POINTER_ACCELERATE (1 << 3)
+#define POINTER_SCREEN (1 << 4) /* Data in screen coordinates */
+
+/*int constants for pointer acceleration schemes*/
+#define PtrAccelNoOp            0
+#define PtrAccelPredictable     1
+#define PtrAccelLightweight     2
+#define PtrAccelDefault         PtrAccelPredictable
+
+#define MAX_VALUATORS 36
+/* Maximum number of valuators, divided by six, rounded up, to get number
+ * of events. */
+#define MAX_VALUATOR_EVENTS 6
+#define MAX_BUTTONS 256 /* completely arbitrarily chosen */
+
+#define NO_AXIS_LIMITS -1
+
+#define MAP_LENGTH	256
+#define DOWN_LENGTH	32	/* 256/8 => number of bytes to hold 256 bits */
+#define NullGrab ((GrabPtr)NULL)
+#define PointerRootWin ((WindowPtr)PointerRoot)
+#define NoneWin ((WindowPtr)None)
+#define NullDevice ((DevicePtr)NULL)
+
+#ifndef FollowKeyboard
+#define FollowKeyboard 		3
+#endif
+#ifndef FollowKeyboardWin
+#define FollowKeyboardWin  ((WindowPtr) FollowKeyboard)
+#endif
+#ifndef RevertToFollowKeyboard
+#define RevertToFollowKeyboard	3
+#endif
+
+typedef unsigned long Leds;
+typedef struct _OtherClients *OtherClientsPtr;
+typedef struct _InputClients *InputClientsPtr;
+typedef struct _DeviceIntRec *DeviceIntPtr;
+typedef struct _ClassesRec *ClassesPtr;
+typedef struct _SpriteRec *SpritePtr;
+typedef union _GrabMask GrabMask;
+
+typedef struct _ValuatorMask ValuatorMask;
+
+typedef struct _EventList {
+    xEvent* event;
+    int evlen; /* length of allocated memory for event in bytes.  This is not
+                  the actual length of the event. The event's actual length is
+                  32 for standard events or 32 +
+                  ((xGenericEvent*)event)->length * 4 for GenericEvents.
+                  For events in the EQ, the length is
+                  ((InternalEvent*)event)->u.any.length */
+} EventList, *EventListPtr;
+
+/* The DIX stores incoming input events in this list */
+extern EventListPtr InputEventList;
+extern int InputEventListLen;
+
+typedef int (*DeviceProc)(
+    DeviceIntPtr /*device*/,
+    int /*what*/);
+
+typedef void (*ProcessInputProc)(
+    InternalEvent * /*event*/,
+    DeviceIntPtr /*device*/);
+
+typedef Bool (*DeviceHandleProc)(
+    DeviceIntPtr /*device*/,
+    void* /*data*/
+    );
+
+typedef void (*DeviceUnwrapProc)(
+    DeviceIntPtr /*device*/,
+    DeviceHandleProc /*proc*/,
+    void* /*data*/
+    );
+
+/* pointer acceleration handling */
+typedef void (*PointerAccelSchemeProc)(
+    DeviceIntPtr /*device*/,
+    ValuatorMask* /*valuators*/,
+    CARD32 /*evtime*/);
+
+typedef void (*DeviceCallbackProc)(
+              DeviceIntPtr /*pDev*/);
+
+struct _ValuatorAccelerationRec;
+typedef Bool (*PointerAccelSchemeInitProc)(
+              DeviceIntPtr /*dev*/,
+              struct _ValuatorAccelerationRec* /*protoScheme*/);
+
+typedef struct _DeviceRec {
+    pointer	devicePrivate;
+    ProcessInputProc processInputProc;	/* current */
+    ProcessInputProc realInputProc;	/* deliver */
+    ProcessInputProc enqueueInputProc;	/* enqueue */
+    Bool	on;			/* used by DDX to keep state */
+} DeviceRec, *DevicePtr;
+
+typedef struct {
+    int			click, bell, bell_pitch, bell_duration;
+    Bool		autoRepeat;
+    unsigned char	autoRepeats[32];
+    Leds		leds;
+    unsigned char	id;
+} KeybdCtrl;
+
+typedef struct {
+    KeySym  *map;
+    KeyCode minKeyCode,
+	    maxKeyCode;
+    int     mapWidth;
+} KeySymsRec, *KeySymsPtr;
+
+typedef struct {
+    int		num, den, threshold;
+    unsigned char id;
+} PtrCtrl;
+
+typedef struct {
+    int         resolution, min_value, max_value;
+    int         integer_displayed;
+    unsigned char id;
+} IntegerCtrl;
+
+typedef struct {
+    int         max_symbols, num_symbols_supported;
+    int         num_symbols_displayed;
+    KeySym      *symbols_supported;
+    KeySym      *symbols_displayed;
+    unsigned char id;
+} StringCtrl;
+
+typedef struct {
+    int         percent, pitch, duration;
+    unsigned char id;
+} BellCtrl;
+
+typedef struct {
+    Leds        led_values;
+    Mask        led_mask;
+    unsigned char id;
+} LedCtrl;
+
+extern _X_EXPORT KeybdCtrl	defaultKeyboardControl;
+extern _X_EXPORT PtrCtrl	defaultPointerControl;
+
+typedef struct _InputOption {
+    char                *key;
+    char                *value;
+    struct _InputOption *next;
+} InputOption;
+
+typedef struct _InputAttributes {
+    char                *product;
+    char                *vendor;
+    char                *device;
+    char                *pnp_id;
+    char                *usb_id;
+    char                **tags; /* null-terminated */
+    uint32_t            flags;
+} InputAttributes;
+
+#define ATTR_KEYBOARD (1<<0)
+#define ATTR_POINTER (1<<1)
+#define ATTR_JOYSTICK (1<<2)
+#define ATTR_TABLET (1<<3)
+#define ATTR_TOUCHPAD (1<<4)
+#define ATTR_TOUCHSCREEN (1<<5)
+
+/* Key/Button has been run through all input processing and events sent to clients. */
+#define KEY_PROCESSED 1
+#define BUTTON_PROCESSED 1
+/* Key/Button has not been fully processed, no events have been sent. */
+#define KEY_POSTED 2
+#define BUTTON_POSTED 2
+
+extern void set_key_down(DeviceIntPtr pDev, int key_code, int type);
+extern void set_key_up(DeviceIntPtr pDev, int key_code, int type);
+extern int key_is_down(DeviceIntPtr pDev, int key_code, int type);
+extern void set_button_down(DeviceIntPtr pDev, int button, int type);
+extern void set_button_up(DeviceIntPtr pDev, int button, int type);
+extern int button_is_down(DeviceIntPtr pDev, int button, int type);
+
+extern void InitCoreDevices(void);
+extern void InitXTestDevices(void);
+
+extern _X_EXPORT DeviceIntPtr AddInputDevice(
+    ClientPtr /*client*/,
+    DeviceProc /*deviceProc*/,
+    Bool /*autoStart*/);
+
+extern _X_EXPORT Bool EnableDevice(
+    DeviceIntPtr /*device*/,
+    BOOL /* sendevent */);
+
+extern _X_EXPORT Bool ActivateDevice(
+    DeviceIntPtr /*device*/,
+    BOOL /* sendevent */);
+
+extern _X_EXPORT Bool DisableDevice(
+    DeviceIntPtr /*device*/,
+    BOOL /* sendevent */);
+
+extern int InitAndStartDevices(void);
+
+extern void CloseDownDevices(void);
+
+extern void UndisplayDevices(void);
+
+extern _X_EXPORT int RemoveDevice(
+    DeviceIntPtr /*dev*/,
+    BOOL /* sendevent */);
+
+extern _X_EXPORT int NumMotionEvents(void);
+
+extern _X_EXPORT int dixLookupDevice(
+    DeviceIntPtr *         /* dev */,
+    int                    /* id */,
+    ClientPtr              /* client */,
+    Mask                   /* access_mode */);
+
+extern _X_EXPORT void QueryMinMaxKeyCodes(
+    KeyCode* /*minCode*/,
+    KeyCode* /*maxCode*/);
+
+extern _X_EXPORT Bool SetKeySymsMap(
+    KeySymsPtr /*dst*/,
+    KeySymsPtr /*src*/);
+
+extern _X_EXPORT Bool InitButtonClassDeviceStruct(
+    DeviceIntPtr /*device*/,
+    int /*numButtons*/,
+    Atom* /* labels */,
+    CARD8* /*map*/);
+
+extern _X_EXPORT Bool InitValuatorClassDeviceStruct(
+    DeviceIntPtr /*device*/,
+    int /*numAxes*/,
+    Atom* /* labels */,
+    int /*numMotionEvents*/,
+    int /*mode*/);
+
+extern _X_EXPORT Bool InitPointerAccelerationScheme(
+    DeviceIntPtr /*dev*/,
+    int /*scheme*/);
+
+extern _X_EXPORT Bool InitAbsoluteClassDeviceStruct(
+    DeviceIntPtr /*device*/);
+
+extern _X_EXPORT Bool InitFocusClassDeviceStruct(
+    DeviceIntPtr /*device*/);
+
+typedef void (*BellProcPtr)(
+    int /*percent*/,
+    DeviceIntPtr /*device*/,
+    pointer /*ctrl*/,
+    int);
+
+typedef void (*KbdCtrlProcPtr)(
+    DeviceIntPtr /*device*/,
+    KeybdCtrl * /*ctrl*/);
+
+typedef void (*PtrCtrlProcPtr)(
+    DeviceIntPtr /*device*/,
+    PtrCtrl * /*ctrl*/);
+
+extern _X_EXPORT Bool InitPtrFeedbackClassDeviceStruct(
+    DeviceIntPtr /*device*/,
+    PtrCtrlProcPtr /*controlProc*/);
+
+typedef void (*StringCtrlProcPtr)(
+    DeviceIntPtr /*device*/,
+    StringCtrl * /*ctrl*/);
+
+extern _X_EXPORT Bool InitStringFeedbackClassDeviceStruct(
+    DeviceIntPtr /*device*/,
+    StringCtrlProcPtr /*controlProc*/,
+    int /*max_symbols*/,
+    int /*num_symbols_supported*/,
+    KeySym* /*symbols*/);
+
+typedef void (*BellCtrlProcPtr)(
+    DeviceIntPtr /*device*/,
+    BellCtrl * /*ctrl*/);
+
+extern _X_EXPORT Bool InitBellFeedbackClassDeviceStruct(
+    DeviceIntPtr /*device*/,
+    BellProcPtr /*bellProc*/,
+    BellCtrlProcPtr /*controlProc*/);
+
+typedef void (*LedCtrlProcPtr)(
+    DeviceIntPtr /*device*/,
+    LedCtrl * /*ctrl*/);
+
+extern _X_EXPORT Bool InitLedFeedbackClassDeviceStruct(
+    DeviceIntPtr /*device*/,
+    LedCtrlProcPtr /*controlProc*/);
+
+typedef void (*IntegerCtrlProcPtr)(
+    DeviceIntPtr /*device*/,
+    IntegerCtrl * /*ctrl*/);
+
+
+extern _X_EXPORT Bool InitIntegerFeedbackClassDeviceStruct(
+    DeviceIntPtr /*device*/,
+    IntegerCtrlProcPtr /*controlProc*/);
+
+extern _X_EXPORT Bool InitPointerDeviceStruct(
+    DevicePtr /*device*/,
+    CARD8* /*map*/,
+    int /*numButtons*/,
+    Atom* /* btn_labels */,
+    PtrCtrlProcPtr /*controlProc*/,
+    int /*numMotionEvents*/,
+    int /*numAxes*/,
+    Atom* /* axes_labels */);
+
+extern _X_EXPORT Bool InitKeyboardDeviceStruct(
+    DeviceIntPtr /*device*/,
+    XkbRMLVOSet * /*rmlvo*/,
+    BellProcPtr /*bellProc*/,
+    KbdCtrlProcPtr /*controlProc*/);
+
+extern int ApplyPointerMapping(
+    DeviceIntPtr /* pDev */,
+    CARD8 *      /* map */,
+    int          /* len */,
+    ClientPtr	/* client */);
+
+extern Bool BadDeviceMap(
+    BYTE* /*buff*/,
+    int /*length*/,
+    unsigned /*low*/,
+    unsigned /*high*/,
+    XID* /*errval*/);
+
+extern void NoteLedState(
+    DeviceIntPtr /*keybd*/,
+    int /*led*/,
+    Bool /*on*/);
+
+extern void MaybeStopHint(
+    DeviceIntPtr /*device*/,
+    ClientPtr /*client*/);
+
+extern void ProcessPointerEvent(
+    InternalEvent* /* ev */,
+    DeviceIntPtr /*mouse*/);
+
+extern void ProcessKeyboardEvent(
+    InternalEvent* /*ev*/,
+    DeviceIntPtr   /*keybd*/);
+
+extern Bool LegalModifier(
+    unsigned int /*key*/, 
+    DeviceIntPtr /*pDev*/);
+
+extern _X_EXPORT void ProcessInputEvents(void);
+
+extern _X_EXPORT void InitInput(
+    int  /*argc*/,
+    char ** /*argv*/);
+extern _X_EXPORT void CloseInput(void);
+
+extern _X_EXPORT int GetMaximumEventsNum(void);
+
+extern _X_EXPORT int GetEventList(EventListPtr* list);
+extern _X_EXPORT EventListPtr InitEventList(int num_events);
+extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events);
+
+extern void CreateClassesChangedEvent(EventListPtr event,
+                                      DeviceIntPtr master,
+                                      DeviceIntPtr slave,
+                                      int type);
+extern EventListPtr UpdateFromMaster(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    int *num_events);
+
+extern _X_EXPORT int GetPointerEvents(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    int buttons,
+    int flags,
+    const ValuatorMask *mask);
+
+extern _X_EXPORT int GetKeyboardEvents(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    int key_code);
+
+extern int GetKeyboardValuatorEvents(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    int key_code,
+    const ValuatorMask *mask);
+
+extern int GetProximityEvents(
+    EventListPtr events,
+    DeviceIntPtr pDev,
+    int type,
+    const ValuatorMask *mask);
+
+extern void PostSyntheticMotion(
+    DeviceIntPtr pDev,
+    int x,
+    int y,
+    int screen,
+    unsigned long time);
+
+extern _X_EXPORT int GetMotionHistorySize(
+    void);
+
+extern _X_EXPORT void AllocateMotionHistory(
+    DeviceIntPtr pDev);
+
+extern _X_EXPORT int GetMotionHistory(
+    DeviceIntPtr pDev,
+    xTimecoord **buff,
+    unsigned long start,
+    unsigned long stop,
+    ScreenPtr pScreen,
+    BOOL core);
+
+extern int AttachDevice(ClientPtr client,
+                        DeviceIntPtr slave,
+                        DeviceIntPtr master);
+
+extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
+extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
+
+extern _X_EXPORT int AllocDevicePair(ClientPtr client,
+                             char* name,
+                             DeviceIntPtr* ptr,
+                             DeviceIntPtr* keybd,
+                             DeviceProc ptr_proc,
+                             DeviceProc keybd_proc,
+                             Bool master);
+extern void DeepCopyDeviceClasses(DeviceIntPtr from,
+                                  DeviceIntPtr to,
+                                  DeviceChangedEvent *dce);
+
+/* Helper functions. */
+extern _X_EXPORT int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
+                              KeyCode **modkeymap, int *max_keys_per_mod);
+extern int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *map,
+                         int max_keys_per_mod);
+extern int AllocXTestDevice(ClientPtr client,
+                             char* name,
+                             DeviceIntPtr* ptr,
+                             DeviceIntPtr* keybd,
+                             DeviceIntPtr master_ptr,
+                             DeviceIntPtr master_keybd);
+extern BOOL IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master);
+extern DeviceIntPtr GetXTestDevice(DeviceIntPtr master);
+extern void SendDevicePresenceEvent(int deviceid, int type);
+extern _X_EXPORT InputAttributes *DuplicateInputAttributes(InputAttributes *attrs);
+extern _X_EXPORT void FreeInputAttributes(InputAttributes *attrs);
+
+/* misc event helpers */
+extern Mask GetEventMask(DeviceIntPtr dev, xEvent* ev, InputClientsPtr clients);
+extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
+extern Mask GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev);
+void FixUpEventFromWindow(SpritePtr pSprite,
+                          xEvent *xE,
+                          WindowPtr pWin,
+                          Window child,
+                          Bool calcChild);
+extern WindowPtr XYToWindow(SpritePtr pSprite, int x, int y);
+extern int EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event,
+                              WindowPtr win);
+/**
+ * Masks specifying the type of event to deliver for an InternalEvent; used
+ * by EventIsDeliverable.
+ * @defgroup EventIsDeliverable return flags
+ * @{
+ */
+#define EVENT_XI1_MASK                (1 << 0) /**< XI1.x event */
+#define EVENT_CORE_MASK               (1 << 1) /**< Core event */
+#define EVENT_DONT_PROPAGATE_MASK     (1 << 2) /**< DontPropagate mask set */
+#define EVENT_XI2_MASK                (1 << 3) /**< XI2 mask set on window */
+/* @} */
+
+/* Implemented by the DDX. */
+extern _X_EXPORT int NewInputDeviceRequest(
+    InputOption *options,
+    InputAttributes *attrs,
+    DeviceIntPtr *dev);
+extern  _X_EXPORT void DeleteInputDeviceRequest(
+    DeviceIntPtr dev);
+
+extern _X_EXPORT void DDXRingBell(
+    int volume,
+    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;
+
+extern _X_EXPORT ValuatorMask  *valuator_mask_new(int num_valuators);
+extern _X_EXPORT void valuator_mask_free(ValuatorMask **mask);
+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);
+extern _X_EXPORT int valuator_mask_size(const ValuatorMask *mask);
+extern _X_EXPORT int valuator_mask_isset(const ValuatorMask *mask, int bit);
+extern _X_EXPORT void valuator_mask_unset(ValuatorMask *mask, int bit);
+extern _X_EXPORT int valuator_mask_num_valuators(const ValuatorMask *mask);
+extern _X_EXPORT void valuator_mask_copy(ValuatorMask *dest,
+                                         const ValuatorMask *src);
+extern _X_EXPORT int valuator_mask_get(const ValuatorMask *mask, int valnum);
+
+#endif /* INPUT_H */
diff --git a/xorg-server/include/misc.h b/xorg-server/include/misc.h
index 0717db64d..42f225b17 100644
--- a/xorg-server/include/misc.h
+++ b/xorg-server/include/misc.h
@@ -1,290 +1,302 @@
-/***********************************************************
-
-Copyright 1987, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-Copyright 1992, 1993 Data General Corporation;
-Copyright 1992, 1993 OMRON Corporation  
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that the
-above copyright notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting documentation, and that
-neither the name OMRON or DATA GENERAL be used in advertising or publicity
-pertaining to distribution of the software without specific, written prior
-permission of the party whose name is to be used.  Neither OMRON or 
-DATA GENERAL make any representation about the suitability of this software
-for any purpose.  It is provided "as is" without express or implied warranty.  
-
-OMRON AND DATA GENERAL EACH DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
-IN NO EVENT SHALL OMRON OR DATA GENERAL BE LIABLE FOR ANY SPECIAL, INDIRECT
-OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-OF THIS SOFTWARE.
-
-******************************************************************/
-#ifndef MISC_H
-#define MISC_H 1
-/*
- *  X internal definitions 
- *
- */
-
-#include <X11/Xosdefs.h>
-#include <X11/Xfuncproto.h>
-#include <X11/Xmd.h>
-#include <X11/X.h>
-#include <X11/Xdefs.h>
-
-#include <stddef.h>
-
-#ifndef MAXSCREENS
-#define MAXSCREENS	16
-#endif
-#define MAXCLIENTS	256
-#define MAXEXTENSIONS   128
-#define MAXFORMATS	8
-#define MAXDEVICES	40 /* input devices */
-
-#define EXTENSION_EVENT_BASE 64
-#define EXTENSION_BASE 128
-
-typedef unsigned long ATOM;
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-
-#ifndef _XTYPEDEF_CALLBACKLISTPTR
-typedef struct _CallbackList *CallbackListPtr; /* also in dix.h */
-#define _XTYPEDEF_CALLBACKLISTPTR
-#endif
-
-typedef struct _xReq *xReqPtr;
-
-#include "os.h" 	/* for ALLOCATE_LOCAL and DEALLOCATE_LOCAL */
-#include <X11/Xfuncs.h> /* for bcopy, bzero, and bcmp */
-
-#define NullBox ((BoxPtr)0)
-#define MILLI_PER_MIN (1000 * 60)
-#define MILLI_PER_SECOND (1000)
-
-    /* this next is used with None and ParentRelative to tell
-       PaintWin() what to use to paint the background. Also used
-       in the macro IS_VALID_PIXMAP */
-
-#define USE_BACKGROUND_PIXEL 3
-#define USE_BORDER_PIXEL 3
-
-
-/* byte swap a 32-bit literal */
-#define lswapl(x) ((((x) & 0xff) << 24) |\
-		   (((x) & 0xff00) << 8) |\
-		   (((x) & 0xff0000) >> 8) |\
-		   (((x) >> 24) & 0xff))
-
-/* byte swap a short literal */
-#define lswaps(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
-
-#undef min
-#undef max
-
-#define min(a, b) (((a) < (b)) ? (a) : (b))
-#define max(a, b) (((a) > (b)) ? (a) : (b))
-/* abs() is a function, not a macro; include the file declaring
- * it in case we haven't done that yet.
- */
-#include <stdlib.h>
-#ifndef Fabs
-#define Fabs(a) ((a) > 0.0 ? (a) : -(a))	/* floating absolute value */
-#endif
-#define sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
-/* this assumes b > 0 */
-#define modulus(a, b, d)    if (((d) = (a) % (b)) < 0) (d) += (b)
-/*
- * return the least significant bit in x which is set
- *
- * This works on 1's complement and 2's complement machines.
- * If you care about the extra instruction on 2's complement
- * machines, change to ((x) & (-(x)))
- */
-#define lowbit(x) ((x) & (~(x) + 1))
-
-/* XXX Not for modules */
-#include <limits.h>
-#if !defined(MAXSHORT) || !defined(MINSHORT) || \
-    !defined(MAXINT) || !defined(MININT)
-/*
- * Some implementations #define these through <math.h>, so preclude
- * #include'ing it later.
- */
-
-#include <math.h>
-#undef MAXSHORT
-#define MAXSHORT SHRT_MAX
-#undef MINSHORT
-#define MINSHORT SHRT_MIN
-#undef MAXINT
-#define MAXINT INT_MAX
-#undef MININT
-#define MININT INT_MIN
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>     /* for fopen, etc... */
-
-#endif
-
-/**
- * Calculate the number of bytes needed to hold bits.
- * @param bits The minimum number of bits needed.
- * @return The number of bytes needed to hold bits.
- */
-static inline int
-bits_to_bytes(const int bits) {
-    return ((bits + 7) >> 3);
-}
-/**
- * Calculate the number of 4-byte units needed to hold the given number of
- * bytes.
- * @param bytes The minimum number of bytes needed.
- * @return The number of 4-byte units needed to hold bytes.
- */
-static inline int
-bytes_to_int32(const int bytes) {
-    return (((bytes) + 3) >> 2);
-}
-
-/**
- * Calculate the number of bytes (in multiples of 4) needed to hold bytes.
- * @param bytes The minimum number of bytes needed.
- * @return The closest multiple of 4 that is equal or higher than bytes.
- */
-static inline int
-pad_to_int32(const int bytes) {
-    return (((bytes) + 3) & ~3);
-}
-
-extern char**
-xstrtokenize(const char *str, const char* separators);
-
-/* some macros to help swap requests, replies, and events */
-
-#define LengthRestB(stuff) \
-    ((client->req_len << 2) - sizeof(*stuff))
-
-#define LengthRestS(stuff) \
-    ((client->req_len << 1) - (sizeof(*stuff) >> 1))
-
-#define LengthRestL(stuff) \
-    (client->req_len - (sizeof(*stuff) >> 2))
-
-#define SwapRestS(stuff) \
-    SwapShorts((short *)(stuff + 1), LengthRestS(stuff))
-
-#define SwapRestL(stuff) \
-    SwapLongs((CARD32 *)(stuff + 1), LengthRestL(stuff))
-
-/* byte swap a 32-bit value */
-#define swapl(x, n) { \
-		 n = ((char *) (x))[0];\
-		 ((char *) (x))[0] = ((char *) (x))[3];\
-		 ((char *) (x))[3] = n;\
-		 n = ((char *) (x))[1];\
-		 ((char *) (x))[1] = ((char *) (x))[2];\
-		 ((char *) (x))[2] = n; }
-
-/* byte swap a short */
-#define swaps(x, n) { \
-		 n = ((char *) (x))[0];\
-		 ((char *) (x))[0] = ((char *) (x))[1];\
-		 ((char *) (x))[1] = n; }
-
-/* copy 32-bit value from src to dst byteswapping on the way */
-#define cpswapl(src, dst) { \
-                 ((char *)&(dst))[0] = ((char *) &(src))[3];\
-                 ((char *)&(dst))[1] = ((char *) &(src))[2];\
-                 ((char *)&(dst))[2] = ((char *) &(src))[1];\
-                 ((char *)&(dst))[3] = ((char *) &(src))[0]; }
-
-/* copy short from src to dst byteswapping on the way */
-#define cpswaps(src, dst) { \
-		 ((char *) &(dst))[0] = ((char *) &(src))[1];\
-		 ((char *) &(dst))[1] = ((char *) &(src))[0]; }
-
-extern _X_EXPORT void SwapLongs(
-    CARD32 *list,
-    unsigned long count);
-
-extern _X_EXPORT void SwapShorts(
-    short *list,
-    unsigned long count);
-
-extern _X_EXPORT void MakePredeclaredAtoms(void);
-
-extern _X_EXPORT int Ones(
-    unsigned long /*mask*/);
-
-typedef struct _xPoint *DDXPointPtr;
-typedef struct pixman_box16 *BoxPtr;
-typedef struct _xEvent *xEventPtr;
-typedef struct _xRectangle *xRectanglePtr;
-typedef struct _GrabRec *GrabPtr;
-
-/*  typedefs from other places - duplicated here to minimize the amount
- *  of unnecessary junk that one would normally have to include to get
- *  these symbols defined
- */
-
-#ifndef _XTYPEDEF_CHARINFOPTR
-typedef struct _CharInfo *CharInfoPtr; /* also in fonts/include/font.h */
-#define _XTYPEDEF_CHARINFOPTR
-#endif
-
-extern _X_EXPORT unsigned long globalSerialNumber;
-extern _X_EXPORT unsigned long serverGeneration;
-
-#endif /* MISC_H */
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+Copyright 1992, 1993 Data General Corporation;
+Copyright 1992, 1993 OMRON Corporation  
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that the
+above copyright notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting documentation, and that
+neither the name OMRON or DATA GENERAL be used in advertising or publicity
+pertaining to distribution of the software without specific, written prior
+permission of the party whose name is to be used.  Neither OMRON or 
+DATA GENERAL make any representation about the suitability of this software
+for any purpose.  It is provided "as is" without express or implied warranty.  
+
+OMRON AND DATA GENERAL EACH DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+IN NO EVENT SHALL OMRON OR DATA GENERAL BE LIABLE FOR ANY SPECIAL, INDIRECT
+OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+OF THIS SOFTWARE.
+
+******************************************************************/
+#ifndef MISC_H
+#define MISC_H 1
+/*
+ *  X internal definitions 
+ *
+ */
+
+#include <X11/Xosdefs.h>
+#include <X11/Xfuncproto.h>
+#include <X11/Xmd.h>
+#include <X11/X.h>
+#include <X11/Xdefs.h>
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifndef MAXSCREENS
+#define MAXSCREENS	16
+#endif
+#define MAXCLIENTS	256
+#define MAXEXTENSIONS   128
+#define MAXFORMATS	8
+#define MAXDEVICES	40 /* input devices */
+
+#define EXTENSION_EVENT_BASE 64
+#define EXTENSION_BASE 128
+
+typedef uint32_t ATOM;
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#ifndef _XTYPEDEF_CALLBACKLISTPTR
+typedef struct _CallbackList *CallbackListPtr; /* also in dix.h */
+#define _XTYPEDEF_CALLBACKLISTPTR
+#endif
+
+typedef struct _xReq *xReqPtr;
+
+#include "os.h" 	/* for ALLOCATE_LOCAL and DEALLOCATE_LOCAL */
+#include <X11/Xfuncs.h> /* for bcopy, bzero, and bcmp */
+
+#define NullBox ((BoxPtr)0)
+#define MILLI_PER_MIN (1000 * 60)
+#define MILLI_PER_SECOND (1000)
+
+    /* this next is used with None and ParentRelative to tell
+       PaintWin() what to use to paint the background. Also used
+       in the macro IS_VALID_PIXMAP */
+
+#define USE_BACKGROUND_PIXEL 3
+#define USE_BORDER_PIXEL 3
+
+
+/* byte swap a 32-bit literal */
+#define lswapl(x) ((((x) & 0xff) << 24) |\
+		   (((x) & 0xff00) << 8) |\
+		   (((x) & 0xff0000) >> 8) |\
+		   (((x) >> 24) & 0xff))
+
+/* byte swap a short literal */
+#define lswaps(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff))
+
+#undef min
+#undef max
+
+#define min(a, b) (((a) < (b)) ? (a) : (b))
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+/* abs() is a function, not a macro; include the file declaring
+ * it in case we haven't done that yet.
+ */
+#include <stdlib.h>
+#ifndef Fabs
+#define Fabs(a) ((a) > 0.0 ? (a) : -(a))	/* floating absolute value */
+#endif
+#define sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
+/* this assumes b > 0 */
+#define modulus(a, b, d)    if (((d) = (a) % (b)) < 0) (d) += (b)
+/*
+ * return the least significant bit in x which is set
+ *
+ * This works on 1's complement and 2's complement machines.
+ * If you care about the extra instruction on 2's complement
+ * machines, change to ((x) & (-(x)))
+ */
+#define lowbit(x) ((x) & (~(x) + 1))
+
+/* XXX Not for modules */
+#include <limits.h>
+#if !defined(MAXSHORT) || !defined(MINSHORT) || \
+    !defined(MAXINT) || !defined(MININT)
+/*
+ * Some implementations #define these through <math.h>, so preclude
+ * #include'ing it later.
+ */
+
+#include <math.h>
+#undef MAXSHORT
+#define MAXSHORT SHRT_MAX
+#undef MINSHORT
+#define MINSHORT SHRT_MIN
+#undef MAXINT
+#define MAXINT INT_MAX
+#undef MININT
+#define MININT INT_MIN
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>     /* for fopen, etc... */
+
+#endif
+
+#ifndef PATH_MAX
+#include <sys/param.h>
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif
+
+/**
+ * Calculate the number of bytes needed to hold bits.
+ * @param bits The minimum number of bits needed.
+ * @return The number of bytes needed to hold bits.
+ */
+static inline int
+bits_to_bytes(const int bits) {
+    return ((bits + 7) >> 3);
+}
+/**
+ * Calculate the number of 4-byte units needed to hold the given number of
+ * bytes.
+ * @param bytes The minimum number of bytes needed.
+ * @return The number of 4-byte units needed to hold bytes.
+ */
+static inline int
+bytes_to_int32(const int bytes) {
+    return (((bytes) + 3) >> 2);
+}
+
+/**
+ * Calculate the number of bytes (in multiples of 4) needed to hold bytes.
+ * @param bytes The minimum number of bytes needed.
+ * @return The closest multiple of 4 that is equal or higher than bytes.
+ */
+static inline int
+pad_to_int32(const int bytes) {
+    return (((bytes) + 3) & ~3);
+}
+
+extern char**
+xstrtokenize(const char *str, const char* separators);
+
+/* some macros to help swap requests, replies, and events */
+
+#define LengthRestB(stuff) \
+    ((client->req_len << 2) - sizeof(*stuff))
+
+#define LengthRestS(stuff) \
+    ((client->req_len << 1) - (sizeof(*stuff) >> 1))
+
+#define LengthRestL(stuff) \
+    (client->req_len - (sizeof(*stuff) >> 2))
+
+#define SwapRestS(stuff) \
+    SwapShorts((short *)(stuff + 1), LengthRestS(stuff))
+
+#define SwapRestL(stuff) \
+    SwapLongs((CARD32 *)(stuff + 1), LengthRestL(stuff))
+
+/* byte swap a 32-bit value */
+#define swapl(x, n) { \
+		 n = ((char *) (x))[0];\
+		 ((char *) (x))[0] = ((char *) (x))[3];\
+		 ((char *) (x))[3] = n;\
+		 n = ((char *) (x))[1];\
+		 ((char *) (x))[1] = ((char *) (x))[2];\
+		 ((char *) (x))[2] = n; }
+
+/* byte swap a short */
+#define swaps(x, n) { \
+		 n = ((char *) (x))[0];\
+		 ((char *) (x))[0] = ((char *) (x))[1];\
+		 ((char *) (x))[1] = n; }
+
+/* copy 32-bit value from src to dst byteswapping on the way */
+#define cpswapl(src, dst) { \
+                 ((char *)&(dst))[0] = ((char *) &(src))[3];\
+                 ((char *)&(dst))[1] = ((char *) &(src))[2];\
+                 ((char *)&(dst))[2] = ((char *) &(src))[1];\
+                 ((char *)&(dst))[3] = ((char *) &(src))[0]; }
+
+/* copy short from src to dst byteswapping on the way */
+#define cpswaps(src, dst) { \
+		 ((char *) &(dst))[0] = ((char *) &(src))[1];\
+		 ((char *) &(dst))[1] = ((char *) &(src))[0]; }
+
+extern _X_EXPORT void SwapLongs(
+    CARD32 *list,
+    unsigned long count);
+
+extern _X_EXPORT void SwapShorts(
+    short *list,
+    unsigned long count);
+
+extern _X_EXPORT void MakePredeclaredAtoms(void);
+
+extern _X_EXPORT int Ones(
+    unsigned long /*mask*/);
+
+typedef struct _xPoint *DDXPointPtr;
+typedef struct pixman_box16 *BoxPtr;
+typedef struct _xEvent *xEventPtr;
+typedef struct _xRectangle *xRectanglePtr;
+typedef struct _GrabRec *GrabPtr;
+
+/*  typedefs from other places - duplicated here to minimize the amount
+ *  of unnecessary junk that one would normally have to include to get
+ *  these symbols defined
+ */
+
+#ifndef _XTYPEDEF_CHARINFOPTR
+typedef struct _CharInfo *CharInfoPtr; /* also in fonts/include/font.h */
+#define _XTYPEDEF_CHARINFOPTR
+#endif
+
+extern _X_EXPORT unsigned long globalSerialNumber;
+extern _X_EXPORT unsigned long serverGeneration;
+
+#endif /* MISC_H */
diff --git a/xorg-server/include/propertyst.h b/xorg-server/include/propertyst.h
index fd1148eb7..fd3e0118d 100644
--- a/xorg-server/include/propertyst.h
+++ b/xorg-server/include/propertyst.h
@@ -1,68 +1,68 @@
-/***********************************************************
-
-Copyright 1987, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifndef PROPERTYSTRUCT_H
-#define PROPERTYSTRUCT_H 
-#include "misc.h"
-#include "property.h"
-#include "privates.h"
-/* 
- *   PROPERTY -- property element
- */
-
-typedef struct _Property {
-        struct _Property       *next;
-	ATOM 		propertyName;
-	ATOM		type;       /* ignored by server */
-	short		format;     /* format of data for swapping - 8,16,32 */
-	long		size;       /* size of data in (format/8) bytes */
-	pointer         data;       /* private to client */
-	PrivateRec	*devPrivates;
-} PropertyRec;
-
-#endif /* PROPERTYSTRUCT_H */
-
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifndef PROPERTYSTRUCT_H
+#define PROPERTYSTRUCT_H 
+#include "misc.h"
+#include "property.h"
+#include "privates.h"
+/* 
+ *   PROPERTY -- property element
+ */
+
+typedef struct _Property {
+        struct _Property       *next;
+	ATOM 		propertyName;
+	ATOM		type;       /* ignored by server */
+	uint32_t	format;     /* format of data for swapping - 8,16,32 */
+	uint32_t	size;       /* size of data in (format/8) bytes */
+	pointer         data;       /* private to client */
+	PrivateRec	*devPrivates;
+} PropertyRec;
+
+#endif /* PROPERTYSTRUCT_H */
+
diff --git a/xorg-server/include/ptrveloc.h b/xorg-server/include/ptrveloc.h
index 8c59c0361..1198146f1 100644
--- a/xorg-server/include/ptrveloc.h
+++ b/xorg-server/include/ptrveloc.h
@@ -1,138 +1,144 @@
-/*
- *
- * Copyright © 2006-2009 Simon Thum             simon dot thum at gmx dot de
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef POINTERVELOCITY_H
-#define POINTERVELOCITY_H
-
-#include <input.h> /* DeviceIntPtr */
-
-/* constants for acceleration profiles */
-
-#define AccelProfileNone -1
-#define AccelProfileClassic  0
-#define AccelProfileDeviceSpecific 1
-#define AccelProfilePolynomial 2
-#define AccelProfileSmoothLinear 3
-#define AccelProfileSimple 4
-#define AccelProfilePower 5
-#define AccelProfileLinear 6
-#define AccelProfileSmoothLimited 7
-#define AccelProfileLAST AccelProfileSmoothLimited
-
-/* fwd */
-struct _DeviceVelocityRec;
-
-/**
- * profile
- * returns actual acceleration depending on velocity, acceleration control,...
- */
-typedef float (*PointerAccelerationProfileFunc)
-              (DeviceIntPtr dev, struct _DeviceVelocityRec* vel,
-               float velocity, float threshold, float accelCoeff);
-
-/**
- * a motion history, with just enough information to
- * calc mean velocity and decide which motion was along
- * a more or less straight line
- */
-typedef struct _MotionTracker {
-    int dx, dy;     /* accumulated delta for each axis */
-    int time;         /* time of creation */
-    int dir;        /* initial direction bitfield */
-} MotionTracker, *MotionTrackerPtr;
-
-/* number of properties for predictable acceleration */
-#define NPROPS_PREDICTABLE_ACCEL 4
-
-/**
- * Contains all data needed to implement mouse ballistics
- */
-typedef struct _DeviceVelocityRec {
-    MotionTrackerPtr tracker;
-    int num_tracker;
-    int cur_tracker;        /* current index */
-    float   velocity;       /* velocity as guessed by algorithm */
-    float   last_velocity;  /* previous velocity estimate */
-    int     last_dx;      /* last time-difference */
-    int     last_dy ;     /* phase of last/current estimate */
-    float   corr_mul;       /* config: multiply this into velocity */
-    float   const_acceleration;  /* config: (recipr.) const deceleration */
-    float   min_acceleration;    /* config: minimum acceleration */
-    short   reset_time;     /* config: reset non-visible state after # ms */
-    short   use_softening;  /* config: use softening of mouse values */
-    float   max_rel_diff;   /* config: max. relative difference */
-    float   max_diff;       /* config: max. difference */
-    int     initial_range;  /* config: max. offset used as initial velocity */
-    Bool    average_accel;  /* config: average acceleration over velocity */
-    PointerAccelerationProfileFunc Profile;
-    PointerAccelerationProfileFunc deviceSpecificProfile;
-    void*   profile_private;/* extended data, see  SetAccelerationProfile() */
-    struct {   /* to be able to query this information */
-        int     profile_number;
-    } statistics;
-    long    prop_handlers[NPROPS_PREDICTABLE_ACCEL];
-} DeviceVelocityRec, *DeviceVelocityPtr;
-
-extern _X_EXPORT void
-InitVelocityData(DeviceVelocityPtr vel);
-
-extern _X_EXPORT void
-InitTrackers(DeviceVelocityPtr vel, int ntracker);
-
-extern _X_EXPORT short
-ProcessVelocityData2D(DeviceVelocityPtr vel, int dx, int dy, int time);
-
-extern _X_EXPORT float
-BasicComputeAcceleration(DeviceIntPtr dev, DeviceVelocityPtr vel,
-    float velocity, float threshold, float acc);
-
-extern _X_EXPORT void
-FreeVelocityData(DeviceVelocityPtr vel);
-
-extern _X_EXPORT int
-SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
-
-extern _X_EXPORT DeviceVelocityPtr
-GetDevicePredictableAccelData(DeviceIntPtr dev);
-
-extern _X_EXPORT void
-SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel,
-                                     PointerAccelerationProfileFunc profile);
-
-extern _X_INTERNAL void
-AccelerationDefaultCleanup(DeviceIntPtr dev);
-
-extern _X_INTERNAL Bool
-InitPredictableAccelerationScheme(DeviceIntPtr dev,
-				  struct _ValuatorAccelerationRec* protoScheme);
-
-extern _X_INTERNAL void
-acceleratePointerPredictable(DeviceIntPtr dev, int first_valuator,
-                             int num_valuators, int *valuators, int evtime);
-
-extern _X_INTERNAL void
-acceleratePointerLightweight(DeviceIntPtr dev, int first_valuator,
-                             int num_valuators, int *valuators, int ignored);
-
-#endif  /* POINTERVELOCITY_H */
+/*
+ *
+ * Copyright © 2006-2011 Simon Thum             simon dot thum at gmx dot de
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef POINTERVELOCITY_H
+#define POINTERVELOCITY_H
+
+#include <input.h>
+
+/* constants for acceleration profiles */
+
+#define AccelProfileNone -1
+#define AccelProfileClassic  0
+#define AccelProfileDeviceSpecific 1
+#define AccelProfilePolynomial 2
+#define AccelProfileSmoothLinear 3
+#define AccelProfileSimple 4
+#define AccelProfilePower 5
+#define AccelProfileLinear 6
+#define AccelProfileSmoothLimited 7
+#define AccelProfileLAST AccelProfileSmoothLimited
+
+/* fwd */
+struct _DeviceVelocityRec;
+
+/**
+ * profile
+ * returns actual acceleration depending on velocity, acceleration control,...
+ */
+typedef float (*PointerAccelerationProfileFunc)
+              (DeviceIntPtr dev, struct _DeviceVelocityRec* vel,
+               float velocity, float threshold, float accelCoeff);
+
+/**
+ * a motion history, with just enough information to
+ * calc mean velocity and decide which motion was along
+ * a more or less straight line
+ */
+typedef struct _MotionTracker {
+    int dx, dy;     /* accumulated delta for each axis */
+    int time;         /* time of creation */
+    int dir;        /* initial direction bitfield */
+} MotionTracker, *MotionTrackerPtr;
+
+/**
+ * Contains all data needed to implement mouse ballistics
+ */
+typedef struct _DeviceVelocityRec {
+    MotionTrackerPtr tracker;
+    int num_tracker;
+    int cur_tracker;        /* current index */
+    float   velocity;       /* velocity as guessed by algorithm */
+    float   last_velocity;  /* previous velocity estimate */
+    int     last_dx;      /* last time-difference */
+    int     last_dy ;     /* phase of last/current estimate */
+    float   corr_mul;       /* config: multiply this into velocity */
+    float   const_acceleration;  /* config: (recipr.) const deceleration */
+    float   min_acceleration;    /* config: minimum acceleration */
+    short   reset_time;     /* config: reset non-visible state after # ms */
+    short   use_softening;  /* config: use softening of mouse values */
+    float   max_rel_diff;   /* config: max. relative difference */
+    float   max_diff;       /* config: max. difference */
+    int     initial_range;  /* config: max. offset used as initial velocity */
+    Bool    average_accel;  /* config: average acceleration over velocity */
+    PointerAccelerationProfileFunc Profile;
+    PointerAccelerationProfileFunc deviceSpecificProfile;
+    void*   profile_private;/* extended data, see  SetAccelerationProfile() */
+    struct {   /* to be able to query this information */
+        int     profile_number;
+    } statistics;
+} DeviceVelocityRec, *DeviceVelocityPtr;
+
+/**
+ * contains the run-time data for the predictable scheme, that is, a
+ * DeviceVelocityPtr and the property handlers.
+ */
+typedef struct _PredictableAccelSchemeRec {
+    DeviceVelocityPtr vel;
+    long* prop_handlers;
+    int num_prop_handlers;
+} PredictableAccelSchemeRec, *PredictableAccelSchemePtr;
+
+extern _X_EXPORT void
+InitVelocityData(DeviceVelocityPtr vel);
+
+extern _X_EXPORT void
+InitTrackers(DeviceVelocityPtr vel, int ntracker);
+
+extern _X_EXPORT short
+ProcessVelocityData2D(DeviceVelocityPtr vel, int dx, int dy, int time);
+
+extern _X_EXPORT float
+BasicComputeAcceleration(DeviceIntPtr dev, DeviceVelocityPtr vel,
+    float velocity, float threshold, float acc);
+
+extern _X_EXPORT void
+FreeVelocityData(DeviceVelocityPtr vel);
+
+extern _X_EXPORT int
+SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
+
+extern _X_EXPORT DeviceVelocityPtr
+GetDevicePredictableAccelData(DeviceIntPtr dev);
+
+extern _X_EXPORT void
+SetDeviceSpecificAccelerationProfile(DeviceVelocityPtr vel,
+                                     PointerAccelerationProfileFunc profile);
+
+extern _X_INTERNAL void
+AccelerationDefaultCleanup(DeviceIntPtr dev);
+
+extern _X_INTERNAL Bool
+InitPredictableAccelerationScheme(DeviceIntPtr dev,
+				  struct _ValuatorAccelerationRec* protoScheme);
+
+extern _X_INTERNAL void
+acceleratePointerPredictable(DeviceIntPtr dev, ValuatorMask* val,
+                             CARD32 evtime);
+
+extern _X_INTERNAL void
+acceleratePointerLightweight(DeviceIntPtr dev, ValuatorMask* val,
+                             CARD32 evtime);
+
+#endif  /* POINTERVELOCITY_H */
diff --git a/xorg-server/include/resource.h b/xorg-server/include/resource.h
index 763aa99d9..17bebe7d4 100644
--- a/xorg-server/include/resource.h
+++ b/xorg-server/include/resource.h
@@ -1,255 +1,255 @@
-/***********************************************************
-
-Copyright 1987, 1989, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifndef RESOURCE_H
-#define RESOURCE_H 1
-#include "misc.h"
-#include "dixaccess.h"
-
-/*****************************************************************
- * STUFF FOR RESOURCES 
- *****************************************************************/
-
-/* classes for Resource routines */
-
-typedef unsigned long RESTYPE;
-
-#define RC_VANILLA	((RESTYPE)0)
-#define RC_CACHED	((RESTYPE)1<<31)
-#define RC_DRAWABLE	((RESTYPE)1<<30)
-/*  Use class RC_NEVERRETAIN for resources that should not be retained
- *  regardless of the close down mode when the client dies.  (A client's
- *  event selections on objects that it doesn't own are good candidates.)
- *  Extensions can use this too!
- */
-#define RC_NEVERRETAIN	((RESTYPE)1<<29)
-#define RC_LASTPREDEF	RC_NEVERRETAIN
-#define RC_ANY		(~(RESTYPE)0)
-
-/* types for Resource routines */
-
-#define RT_WINDOW	((RESTYPE)1|RC_DRAWABLE)
-#define RT_PIXMAP	((RESTYPE)2|RC_DRAWABLE)
-#define RT_GC		((RESTYPE)3)
-#undef RT_FONT
-#undef RT_CURSOR
-#define RT_FONT		((RESTYPE)4)
-#define RT_CURSOR	((RESTYPE)5)
-#define RT_COLORMAP	((RESTYPE)6)
-#define RT_CMAPENTRY	((RESTYPE)7)
-#define RT_OTHERCLIENT	((RESTYPE)8|RC_NEVERRETAIN)
-#define RT_PASSIVEGRAB	((RESTYPE)9|RC_NEVERRETAIN)
-#define RT_LASTPREDEF	((RESTYPE)9)
-#define RT_NONE		((RESTYPE)0)
-
-/* bits and fields within a resource id */
-#define RESOURCE_AND_CLIENT_COUNT   29			/* 29 bits for XIDs */
-#if MAXCLIENTS == 64
-#define RESOURCE_CLIENT_BITS	6
-#endif
-#if MAXCLIENTS == 128
-#define RESOURCE_CLIENT_BITS	7
-#endif
-#if MAXCLIENTS == 256
-#define RESOURCE_CLIENT_BITS	8
-#endif
-#if MAXCLIENTS == 512
-#define RESOURCE_CLIENT_BITS	9
-#endif
-/* client field offset */
-#define CLIENTOFFSET	    (RESOURCE_AND_CLIENT_COUNT - RESOURCE_CLIENT_BITS)
-/* resource field */
-#define RESOURCE_ID_MASK	((1 << CLIENTOFFSET) - 1)
-/* client field */
-#define RESOURCE_CLIENT_MASK	(((1 << RESOURCE_CLIENT_BITS) - 1) << CLIENTOFFSET)
-/* extract the client mask from an XID */
-#define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK)
-/* extract the client id from an XID */
-#define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
-#define SERVER_BIT		(Mask)0x40000000	/* use illegal bit */
-
-#ifdef INVALID
-#undef INVALID	/* needed on HP/UX */
-#endif
-
-/* Invalid resource id */
-#define INVALID	(0)
-
-#define BAD_RESOURCE 0xe0000000
-
-#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
-
-/* Resource state callback */
-extern _X_EXPORT CallbackListPtr ResourceStateCallback;
-
-typedef enum {ResourceStateAdding,
-	      ResourceStateFreeing} ResourceState;
-
-typedef struct {
-    ResourceState state;
-    XID id;
-    RESTYPE type;
-    pointer value;
-} ResourceStateInfoRec;
-
-typedef int (*DeleteType)(
-    pointer /*value*/,
-    XID /*id*/);
-
-typedef void (*FindResType)(
-    pointer /*value*/,
-    XID /*id*/,
-    pointer /*cdata*/);
-
-typedef void (*FindAllRes)(
-    pointer /*value*/,
-    XID /*id*/,
-    RESTYPE /*type*/,
-    pointer /*cdata*/);
-
-typedef Bool (*FindComplexResType)(
-    pointer /*value*/,
-    XID /*id*/,
-    pointer /*cdata*/);
-
-extern _X_EXPORT RESTYPE CreateNewResourceType(
-    DeleteType /*deleteFunc*/, char * /*name*/);
-
-extern _X_EXPORT void SetResourceTypeErrorValue(
-    RESTYPE /*type*/, int /*errorValue*/);
-
-extern _X_EXPORT RESTYPE CreateNewResourceClass(void);
-
-extern _X_EXPORT Bool InitClientResources(
-    ClientPtr /*client*/);
-
-extern _X_EXPORT XID FakeClientID(
-    int /*client*/);
-
-/* Quartz support on Mac OS X uses the CarbonCore
-   framework whose AddResource function conflicts here. */
-#ifdef __APPLE__
-#define AddResource Darwin_X_AddResource
-#endif
-extern _X_EXPORT Bool AddResource(
-    XID /*id*/,
-    RESTYPE /*type*/,
-    pointer /*value*/);
-
-extern _X_EXPORT void FreeResource(
-    XID /*id*/,
-    RESTYPE /*skipDeleteFuncType*/);
-
-extern _X_EXPORT void FreeResourceByType(
-    XID /*id*/,
-    RESTYPE /*type*/,
-    Bool /*skipFree*/);
-
-extern _X_EXPORT Bool ChangeResourceValue(
-    XID /*id*/,
-    RESTYPE /*rtype*/,
-    pointer /*value*/);
-
-extern _X_EXPORT void FindClientResourcesByType(
-    ClientPtr /*client*/,
-    RESTYPE /*type*/,
-    FindResType /*func*/,
-    pointer /*cdata*/);
-
-extern _X_EXPORT void FindAllClientResources(
-    ClientPtr /*client*/,
-    FindAllRes /*func*/,
-    pointer /*cdata*/);
-
-extern _X_EXPORT void FreeClientNeverRetainResources(
-    ClientPtr /*client*/);
-
-extern _X_EXPORT void FreeClientResources(
-    ClientPtr /*client*/);
-
-extern _X_EXPORT void FreeAllResources(void);
-
-extern _X_EXPORT Bool LegalNewID(
-    XID /*id*/,
-    ClientPtr /*client*/);
-
-extern _X_EXPORT pointer LookupClientResourceComplex(
-    ClientPtr client,
-    RESTYPE type,
-    FindComplexResType func,
-    pointer cdata);
-
-extern _X_EXPORT int dixLookupResourceByType(
-    pointer *result,
-    XID id,
-    RESTYPE rtype,
-    ClientPtr client,
-    Mask access_mode);
-
-extern _X_EXPORT int dixLookupResourceByClass(
-    pointer *result,
-    XID id,
-    RESTYPE rclass,
-    ClientPtr client,
-    Mask access_mode);
-
-extern _X_EXPORT void GetXIDRange(
-    int /*client*/,
-    Bool /*server*/,
-    XID * /*minp*/,
-    XID * /*maxp*/);
-
-extern _X_EXPORT unsigned int GetXIDList(
-    ClientPtr /*client*/,
-    unsigned int /*count*/,
-    XID * /*pids*/);
-
-extern _X_EXPORT RESTYPE lastResourceType;
-extern _X_EXPORT RESTYPE TypeMask;
-
-#endif /* RESOURCE_H */
-
+/***********************************************************
+
+Copyright 1987, 1989, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifndef RESOURCE_H
+#define RESOURCE_H 1
+#include "misc.h"
+#include "dixaccess.h"
+
+/*****************************************************************
+ * STUFF FOR RESOURCES 
+ *****************************************************************/
+
+/* classes for Resource routines */
+
+typedef uint32_t RESTYPE;
+
+#define RC_VANILLA	((RESTYPE)0)
+#define RC_CACHED	((RESTYPE)1<<31)
+#define RC_DRAWABLE	((RESTYPE)1<<30)
+/*  Use class RC_NEVERRETAIN for resources that should not be retained
+ *  regardless of the close down mode when the client dies.  (A client's
+ *  event selections on objects that it doesn't own are good candidates.)
+ *  Extensions can use this too!
+ */
+#define RC_NEVERRETAIN	((RESTYPE)1<<29)
+#define RC_LASTPREDEF	RC_NEVERRETAIN
+#define RC_ANY		(~(RESTYPE)0)
+
+/* types for Resource routines */
+
+#define RT_WINDOW	((RESTYPE)1|RC_DRAWABLE)
+#define RT_PIXMAP	((RESTYPE)2|RC_DRAWABLE)
+#define RT_GC		((RESTYPE)3)
+#undef RT_FONT
+#undef RT_CURSOR
+#define RT_FONT		((RESTYPE)4)
+#define RT_CURSOR	((RESTYPE)5)
+#define RT_COLORMAP	((RESTYPE)6)
+#define RT_CMAPENTRY	((RESTYPE)7)
+#define RT_OTHERCLIENT	((RESTYPE)8|RC_NEVERRETAIN)
+#define RT_PASSIVEGRAB	((RESTYPE)9|RC_NEVERRETAIN)
+#define RT_LASTPREDEF	((RESTYPE)9)
+#define RT_NONE		((RESTYPE)0)
+
+/* bits and fields within a resource id */
+#define RESOURCE_AND_CLIENT_COUNT   29			/* 29 bits for XIDs */
+#if MAXCLIENTS == 64
+#define RESOURCE_CLIENT_BITS	6
+#endif
+#if MAXCLIENTS == 128
+#define RESOURCE_CLIENT_BITS	7
+#endif
+#if MAXCLIENTS == 256
+#define RESOURCE_CLIENT_BITS	8
+#endif
+#if MAXCLIENTS == 512
+#define RESOURCE_CLIENT_BITS	9
+#endif
+/* client field offset */
+#define CLIENTOFFSET	    (RESOURCE_AND_CLIENT_COUNT - RESOURCE_CLIENT_BITS)
+/* resource field */
+#define RESOURCE_ID_MASK	((1 << CLIENTOFFSET) - 1)
+/* client field */
+#define RESOURCE_CLIENT_MASK	(((1 << RESOURCE_CLIENT_BITS) - 1) << CLIENTOFFSET)
+/* extract the client mask from an XID */
+#define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK)
+/* extract the client id from an XID */
+#define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
+#define SERVER_BIT		(Mask)0x40000000	/* use illegal bit */
+
+#ifdef INVALID
+#undef INVALID	/* needed on HP/UX */
+#endif
+
+/* Invalid resource id */
+#define INVALID	(0)
+
+#define BAD_RESOURCE 0xe0000000
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+/* Resource state callback */
+extern _X_EXPORT CallbackListPtr ResourceStateCallback;
+
+typedef enum {ResourceStateAdding,
+	      ResourceStateFreeing} ResourceState;
+
+typedef struct {
+    ResourceState state;
+    XID id;
+    RESTYPE type;
+    pointer value;
+} ResourceStateInfoRec;
+
+typedef int (*DeleteType)(
+    pointer /*value*/,
+    XID /*id*/);
+
+typedef void (*FindResType)(
+    pointer /*value*/,
+    XID /*id*/,
+    pointer /*cdata*/);
+
+typedef void (*FindAllRes)(
+    pointer /*value*/,
+    XID /*id*/,
+    RESTYPE /*type*/,
+    pointer /*cdata*/);
+
+typedef Bool (*FindComplexResType)(
+    pointer /*value*/,
+    XID /*id*/,
+    pointer /*cdata*/);
+
+extern _X_EXPORT RESTYPE CreateNewResourceType(
+    DeleteType /*deleteFunc*/, char * /*name*/);
+
+extern _X_EXPORT void SetResourceTypeErrorValue(
+    RESTYPE /*type*/, int /*errorValue*/);
+
+extern _X_EXPORT RESTYPE CreateNewResourceClass(void);
+
+extern _X_EXPORT Bool InitClientResources(
+    ClientPtr /*client*/);
+
+extern _X_EXPORT XID FakeClientID(
+    int /*client*/);
+
+/* Quartz support on Mac OS X uses the CarbonCore
+   framework whose AddResource function conflicts here. */
+#ifdef __APPLE__
+#define AddResource Darwin_X_AddResource
+#endif
+extern _X_EXPORT Bool AddResource(
+    XID /*id*/,
+    RESTYPE /*type*/,
+    pointer /*value*/);
+
+extern _X_EXPORT void FreeResource(
+    XID /*id*/,
+    RESTYPE /*skipDeleteFuncType*/);
+
+extern _X_EXPORT void FreeResourceByType(
+    XID /*id*/,
+    RESTYPE /*type*/,
+    Bool /*skipFree*/);
+
+extern _X_EXPORT Bool ChangeResourceValue(
+    XID /*id*/,
+    RESTYPE /*rtype*/,
+    pointer /*value*/);
+
+extern _X_EXPORT void FindClientResourcesByType(
+    ClientPtr /*client*/,
+    RESTYPE /*type*/,
+    FindResType /*func*/,
+    pointer /*cdata*/);
+
+extern _X_EXPORT void FindAllClientResources(
+    ClientPtr /*client*/,
+    FindAllRes /*func*/,
+    pointer /*cdata*/);
+
+extern _X_EXPORT void FreeClientNeverRetainResources(
+    ClientPtr /*client*/);
+
+extern _X_EXPORT void FreeClientResources(
+    ClientPtr /*client*/);
+
+extern _X_EXPORT void FreeAllResources(void);
+
+extern _X_EXPORT Bool LegalNewID(
+    XID /*id*/,
+    ClientPtr /*client*/);
+
+extern _X_EXPORT pointer LookupClientResourceComplex(
+    ClientPtr client,
+    RESTYPE type,
+    FindComplexResType func,
+    pointer cdata);
+
+extern _X_EXPORT int dixLookupResourceByType(
+    pointer *result,
+    XID id,
+    RESTYPE rtype,
+    ClientPtr client,
+    Mask access_mode);
+
+extern _X_EXPORT int dixLookupResourceByClass(
+    pointer *result,
+    XID id,
+    RESTYPE rclass,
+    ClientPtr client,
+    Mask access_mode);
+
+extern _X_EXPORT void GetXIDRange(
+    int /*client*/,
+    Bool /*server*/,
+    XID * /*minp*/,
+    XID * /*maxp*/);
+
+extern _X_EXPORT unsigned int GetXIDList(
+    ClientPtr /*client*/,
+    unsigned int /*count*/,
+    XID * /*pids*/);
+
+extern _X_EXPORT RESTYPE lastResourceType;
+extern _X_EXPORT RESTYPE TypeMask;
+
+#endif /* RESOURCE_H */
+
diff --git a/xorg-server/mi/mipointer.c b/xorg-server/mi/mipointer.c
index 209ea06be..e8ed106ea 100644
--- a/xorg-server/mi/mipointer.c
+++ b/xorg-server/mi/mipointer.c
@@ -1,688 +1,698 @@
-/*
-
-Copyright 1989, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-*/
-
-/**
- * @file
- * This file contains functions to move the pointer on the screen and/or
- * restrict its movement. These functions are divided into two sets:
- * Screen-specific functions that are used as function pointers from other
- * parts of the server (and end up heavily wrapped by e.g. animcur and
- * xfixes):
- *      miPointerConstrainCursor
- *      miPointerCursorLimits
- *      miPointerDisplayCursor
- *      miPointerRealizeCursor
- *      miPointerUnrealizeCursor
- *      miPointerSetCursorPosition
- *      miRecolorCursor
- *      miPointerDeviceInitialize
- *      miPointerDeviceCleanup
- * If wrapped, these are the last element in the wrapping chain. They may
- * call into sprite-specific code through further function pointers though.
- *
- * The second type of functions are those that are directly called by the
- * DIX, DDX and some drivers.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-# include   <X11/X.h>
-# include   <X11/Xmd.h>
-# include   <X11/Xproto.h>
-# include   "misc.h"
-# include   "windowstr.h"
-# include   "pixmapstr.h"
-# include   "mi.h"
-# include   "scrnintstr.h"
-# include   "mipointrst.h"
-# include   "cursorstr.h"
-# include   "dixstruct.h"
-# include   "inputstr.h"
-# include   "inpututils.h"
-
-DevPrivateKeyRec miPointerScreenKeyRec;
-
-#define GetScreenPrivate(s) ((miPointerScreenPtr) \
-    dixLookupPrivate(&(s)->devPrivates, miPointerScreenKey))
-#define SetupScreen(s)	miPointerScreenPtr  pScreenPriv = GetScreenPrivate(s)
-
-DevPrivateKeyRec miPointerPrivKeyRec;
-
-#define MIPOINTER(dev) \
-    (IsFloating(dev) ? \
-        (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \
-        (miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey))
-
-static Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
-                                   CursorPtr pCursor);
-static Bool miPointerUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
-                                     CursorPtr pCursor);
-static Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
-                                   CursorPtr pCursor);
-static void miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
-                                     BoxPtr pBox); 
-static void miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen,
-                                  CursorPtr pCursor, BoxPtr pHotBox, 
-                                  BoxPtr pTopLeftBox);
-static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, 
-                                       int x, int y,
-				       Bool generateEvent);
-static Bool miPointerCloseScreen(int index, ScreenPtr pScreen);
-static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, 
-                          int x, int y);
-static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
-static void miPointerDeviceCleanup(DeviceIntPtr pDev,
-                                   ScreenPtr pScreen);
-static void miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
-
-static EventList* events; /* for WarpPointer MotionNotifies */
-
-Bool
-miPointerInitialize (ScreenPtr                  pScreen,
-                     miPointerSpriteFuncPtr     spriteFuncs,
-                     miPointerScreenFuncPtr     screenFuncs,
-                     Bool                       waitForUpdate)
-{
-    miPointerScreenPtr	pScreenPriv;
-
-    if (!dixRegisterPrivateKey(&miPointerScreenKeyRec, PRIVATE_SCREEN, 0))
-	return FALSE;
-
-    if (!dixRegisterPrivateKey(&miPointerPrivKeyRec, PRIVATE_DEVICE, 0))
-	return FALSE;
-
-    pScreenPriv = malloc(sizeof (miPointerScreenRec));
-    if (!pScreenPriv)
-	return FALSE;
-    pScreenPriv->spriteFuncs = spriteFuncs;
-    pScreenPriv->screenFuncs = screenFuncs;
-    /*
-     * check for uninitialized methods
-     */
-    if (!screenFuncs->EnqueueEvent)
-	screenFuncs->EnqueueEvent = mieqEnqueue;
-    if (!screenFuncs->NewEventScreen)
-	screenFuncs->NewEventScreen = mieqSwitchScreen;
-    pScreenPriv->waitForUpdate = waitForUpdate;
-    pScreenPriv->showTransparent = FALSE;
-    pScreenPriv->CloseScreen = pScreen->CloseScreen;
-    pScreen->CloseScreen = miPointerCloseScreen;
-    dixSetPrivate(&pScreen->devPrivates, miPointerScreenKey, pScreenPriv);
-    /*
-     * set up screen cursor method table
-     */
-    pScreen->ConstrainCursor = miPointerConstrainCursor;
-    pScreen->CursorLimits = miPointerCursorLimits;
-    pScreen->DisplayCursor = miPointerDisplayCursor;
-    pScreen->RealizeCursor = miPointerRealizeCursor;
-    pScreen->UnrealizeCursor = miPointerUnrealizeCursor;
-    pScreen->SetCursorPosition = miPointerSetCursorPosition;
-    pScreen->RecolorCursor = miRecolorCursor;
-    pScreen->DeviceCursorInitialize = miPointerDeviceInitialize;
-    pScreen->DeviceCursorCleanup = miPointerDeviceCleanup;
-
-    events = NULL;
-    return TRUE;
-}
-
-/**
- * Destroy screen-specific information.
- *
- * @param index Screen index of the screen in screenInfo.screens[]
- * @param pScreen The actual screen pointer
- */
-static Bool
-miPointerCloseScreen (int index, ScreenPtr pScreen)
-{
-    SetupScreen(pScreen);
-
-    pScreen->CloseScreen = pScreenPriv->CloseScreen;
-    free((pointer) pScreenPriv);
-    FreeEventList(events, GetMaximumEventsNum());
-    events = NULL;
-    return (*pScreen->CloseScreen) (index, pScreen);
-}
-
-/*
- * DIX/DDX interface routines
- */
-
-static Bool
-miPointerRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
-    SetupScreen(pScreen);
-    return (*pScreenPriv->spriteFuncs->RealizeCursor) (pDev, pScreen, pCursor);
-}
-
-static Bool
-miPointerUnrealizeCursor (DeviceIntPtr  pDev,
-                          ScreenPtr     pScreen,
-                          CursorPtr     pCursor)
-{
-    SetupScreen(pScreen);
-    return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pDev, pScreen, pCursor);
-}
-
-static Bool
-miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
-    miPointerPtr pPointer;
-
-    /* return for keyboards */
-    if (!IsPointerDevice(pDev))
-            return FALSE;
-
-    pPointer = MIPOINTER(pDev);
-
-    pPointer->pCursor = pCursor;
-    pPointer->pScreen = pScreen;
-    miPointerUpdateSprite(pDev);
-    return TRUE;
-}
-
-/**
- * Set up the constraints for the given device. This function does not
- * actually constrain the cursor but merely copies the given box to the
- * internal constraint storage.
- *
- * @param pDev The device to constrain to the box
- * @param pBox The rectangle to constrain the cursor to
- * @param pScreen Used for copying screen confinement
- */
-static void
-miPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox)
-{
-    miPointerPtr pPointer;
-
-    pPointer = MIPOINTER(pDev);
-
-    pPointer->limits = *pBox;
-    pPointer->confined = PointerConfinedToScreen(pDev);
-}
-
-/**
- * Should calculate the box for the given cursor, based on screen and the
- * confinement given. But we assume that whatever box is passed in is valid
- * anyway.
- *
- * @param pDev The device to calculate the cursor limits for
- * @param pScreen The screen the confinement happens on
- * @param pCursor The screen the confinement happens on
- * @param pHotBox The confinement box for the cursor
- * @param[out] pTopLeftBox The new confinement box, always *pHotBox.
- */
-static void
-miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
-                      BoxPtr pHotBox, BoxPtr pTopLeftBox)
-{
-    *pTopLeftBox = *pHotBox;
-}
-
-/**
- * Set the device's cursor position to the x/y position on the given screen.
- * Generates and event if required.
- *
- * This function is called from:
- *    - sprite init code to place onto initial position
- *    - the various WarpPointer implementations (core, XI, Xinerama, dmx,…)
- *    - during the cursor update path in CheckMotion
- *    - in the Xinerama part of NewCurrentScreen
- *    - when a RandR/RandR1.2 mode was applied (it may have moved the pointer, so
- *      it's set back to the original pos)
- *
- * @param pDev The device to move
- * @param pScreen The screen the device is on
- * @param x The x coordinate in per-screen coordinates
- * @param y The y coordinate in per-screen coordinates
- * @param generateEvent True if the pointer movement should generate an
- * event.
- *
- * @return TRUE in all cases
- */
-static Bool
-miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen,
-                           int x, int y, Bool generateEvent)
-{
-    SetupScreen (pScreen);
-    miPointerPtr pPointer = MIPOINTER(pDev);
-
-    pPointer->generateEvent = generateEvent;
-
-    /* device dependent - must pend signal and call miPointerWarpCursor */
-    (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y);
-    if (!generateEvent)
-	miPointerUpdateSprite(pDev);
-    return TRUE;
-}
-
-/**
- * Set up sprite information for the device.
- * This function will be called once for each device after it is initialized
- * in the DIX.
- *
- * @param pDev The newly created device
- * @param pScreen The initial sprite scree.
- */
-static Bool
-miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
-    miPointerPtr pPointer;
-    SetupScreen (pScreen);
-
-    pPointer = malloc(sizeof(miPointerRec));
-    if (!pPointer)
-        return FALSE;
-
-    pPointer->pScreen = NULL;
-    pPointer->pSpriteScreen = NULL;
-    pPointer->pCursor = NULL;
-    pPointer->pSpriteCursor = NULL;
-    pPointer->limits.x1 = 0;
-    pPointer->limits.x2 = 32767;
-    pPointer->limits.y1 = 0;
-    pPointer->limits.y2 = 32767;
-    pPointer->confined = FALSE;
-    pPointer->x = 0;
-    pPointer->y = 0;
-    pPointer->generateEvent = FALSE;
-
-    if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen)))
-    {
-        free(pPointer);
-        return FALSE;
-    }
-
-    dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, pPointer);
-    return TRUE;
-}
-
-/**
- * Clean up after device.
- * This function will be called once before the device is freed in the DIX
- *
- * @param pDev The device to be removed from the server
- * @param pScreen Current screen of the device
- */
-static void
-miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
-    SetupScreen(pScreen);
-
-    if (!IsMaster(pDev) && !IsFloating(pDev))
-        return;
-
-    (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
-    free(dixLookupPrivate(&pDev->devPrivates, miPointerPrivKey));
-    dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, NULL);
-}
-
-
-/**
- * Warp the pointer to the given position on the given screen. May generate
- * an event, depending on whether we're coming from miPointerSetPosition.
- *
- * Once signals are ignored, the WarpCursor function can call this
- *
- * @param pDev The device to warp
- * @param pScreen Screen to warp on
- * @param x The x coordinate in per-screen coordinates
- * @param y The y coordinate in per-screen coordinates
- */
-
-void
-miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
-    miPointerPtr pPointer;
-    BOOL changedScreen = FALSE;
-
-    SetupScreen (pScreen);
-    pPointer = MIPOINTER(pDev);
-
-    if (pPointer->pScreen != pScreen)
-    {
-	(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE);
-        changedScreen = TRUE;
-    }
-
-    if (pPointer->generateEvent)
-	miPointerMove (pDev, pScreen, x, y);
-    else
-        miPointerMoveNoEvent(pDev, pScreen, x, y);
-
-    /* Don't call USFS if we use Xinerama, otherwise the root window is
-     * updated to the second screen, and we never receive any events.
-     * (FDO bug #18668) */
-    if (changedScreen
-#ifdef PANORAMIX
-            && noPanoramiXExtension
-#endif
-       )
-        UpdateSpriteForScreen (pDev, pScreen) ;
-}
-
-/**
- * Syncronize the sprite with the cursor.
- *
- * @param pDev The device to sync
- */
-void
-miPointerUpdateSprite (DeviceIntPtr pDev)
-{
-    ScreenPtr		pScreen;
-    miPointerScreenPtr	pScreenPriv;
-    CursorPtr		pCursor;
-    int			x, y, devx, devy;
-    miPointerPtr        pPointer;
-
-    if (!pDev || !pDev->coreEvents)
-        return;
-
-    pPointer = MIPOINTER(pDev);
-
-    if (!pPointer)
-        return;
-
-    pScreen = pPointer->pScreen;
-    if (!pScreen)
-	return;
-
-    x = pPointer->x;
-    y = pPointer->y;
-    devx = pPointer->devx;
-    devy = pPointer->devy;
-
-    pScreenPriv = GetScreenPrivate (pScreen);
-    /*
-     * if the cursor has switched screens, disable the sprite
-     * on the old screen
-     */
-    if (pScreen != pPointer->pSpriteScreen)
-    {
-	if (pPointer->pSpriteScreen)
-	{
-	    miPointerScreenPtr  pOldPriv;
-    	
-	    pOldPriv = GetScreenPrivate (pPointer->pSpriteScreen);
-	    if (pPointer->pCursor)
-	    {
-	    	(*pOldPriv->spriteFuncs->SetCursor)
-			    	(pDev, pPointer->pSpriteScreen, NullCursor, 0, 0);
-	    }
-	    (*pOldPriv->screenFuncs->CrossScreen) (pPointer->pSpriteScreen, FALSE);
-	}
-	(*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE);
-	(*pScreenPriv->spriteFuncs->SetCursor)
-				(pDev, pScreen, pPointer->pCursor, x, y);
-	pPointer->devx = x;
-	pPointer->devy = y;
-	pPointer->pSpriteCursor = pPointer->pCursor;
-	pPointer->pSpriteScreen = pScreen;
-    }
-    /*
-     * if the cursor has changed, display the new one
-     */
-    else if (pPointer->pCursor != pPointer->pSpriteCursor)
-    {
-	pCursor = pPointer->pCursor;
-	if (!pCursor || (pCursor->bits->emptyMask && !pScreenPriv->showTransparent))
-	    pCursor = NullCursor;
-	(*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCursor, x, y);
-
-	pPointer->devx = x;
-	pPointer->devy = y;
-	pPointer->pSpriteCursor = pPointer->pCursor;
-    }
-    else if (x != devx || y != devy)
-    {
-	pPointer->devx = x;
-	pPointer->devy = y;
-	if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask)
-	    (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y);
-    }
-}
-
-/**
- * Set the device to the coordinates on the given screen.
- *
- * @param pDev The device to move
- * @param screen_no Index of the screen to move to
- * @param x The x coordinate in per-screen coordinates
- * @param y The y coordinate in per-screen coordinates
- */
-void
-miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y)
-{
-	miPointerScreenPtr pScreenPriv;
-	ScreenPtr pScreen;
-        miPointerPtr pPointer;
-
-        pPointer = MIPOINTER(pDev);
-
-	pScreen = screenInfo.screens[screen_no];
-	pScreenPriv = GetScreenPrivate (pScreen);
-	(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE);
-	NewCurrentScreen (pDev, pScreen, x, y);
-
-        pPointer->limits.x2 = pScreen->width;
-        pPointer->limits.y2 = pScreen->height;
-}
-
-/**
- * @return The current screen of the VCP
- */
-ScreenPtr
-miPointerCurrentScreen (void)
-{
-    return miPointerGetScreen(inputInfo.pointer);
-}
-
-/**
- * @return The current screen of the given device or NULL.
- */
-ScreenPtr
-miPointerGetScreen(DeviceIntPtr pDev)
-{
-    miPointerPtr pPointer = MIPOINTER(pDev);
-    return (pPointer) ? pPointer->pScreen : NULL;
-}
-
-/* Controls whether the cursor image should be updated immediately when
-   moved (FALSE) or if something else will be responsible for updating
-   it later (TRUE).  Returns current setting.
-   Caller is responsible for calling OsBlockSignal first.
-*/
-Bool
-miPointerSetWaitForUpdate(ScreenPtr pScreen, Bool wait)
-{
-    SetupScreen(pScreen);
-    Bool prevWait = pScreenPriv->waitForUpdate;
-
-    pScreenPriv->waitForUpdate = wait;
-    return prevWait;
-}
-
-
-/* Move the pointer on the current screen,  and update the sprite. */
-static void
-miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen,
-                int x, int y)
-{
-    miPointerPtr pPointer;
-    SetupScreen(pScreen);
-
-    pPointer = MIPOINTER(pDev);
-
-    /* Hack: We mustn't call into ->MoveCursor for anything but the
-     * VCP, as this may cause a non-HW rendered cursor to be rendered during
-     * SIGIO. This again leads to allocs during SIGIO which leads to SIGABRT.
-     */
-    if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer
-        && !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen)
-    {
-	pPointer->devx = x;
-	pPointer->devy = y;
-	if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask)
-	    (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y);
-    }
-
-    pPointer->x = x;
-    pPointer->y = y;
-    pPointer->pScreen = pScreen;
-}
-
-/**
- * Set the devices' cursor position to the given x/y position.
- *
- * This function is called during the pointer update path in
- * GetPointerEvents and friends (and the same in the xwin DDX).
- *
- * @param pDev The device to move
- * @param[in,out] x The x coordiante in screen coordinates (in regards to total
- * desktop size)
- * @param[in,out] y The y coordiante in screen coordinates (in regards to total
- * desktop size)
- */
-void
-miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
-{
-    miPointerScreenPtr	pScreenPriv;
-    ScreenPtr		pScreen;
-    ScreenPtr		newScreen;
-
-    miPointerPtr        pPointer; 
-
-    if (!pDev || !pDev->coreEvents)
-        return;
-
-    pPointer = MIPOINTER(pDev);
-    pScreen = pPointer->pScreen;
-    if (!pScreen)
-	return;	    /* called before ready */
-
-    if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height)
-    {
-	pScreenPriv = GetScreenPrivate (pScreen);
-	if (!pPointer->confined)
-	{
-	    newScreen = pScreen;
-	    (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, x, y);
-	    if (newScreen != pScreen)
-	    {
-		pScreen = newScreen;
-		(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen,
-							     FALSE);
-		pScreenPriv = GetScreenPrivate (pScreen);
-	    	/* Smash the confine to the new screen */
-                pPointer->limits.x2 = pScreen->width;
-                pPointer->limits.y2 = pScreen->height;
-	    }
-	}
-    }
-    /* Constrain the sprite to the current limits. */
-    if (*x < pPointer->limits.x1)
-	*x = pPointer->limits.x1;
-    if (*x >= pPointer->limits.x2)
-	*x = pPointer->limits.x2 - 1;
-    if (*y < pPointer->limits.y1)
-	*y = pPointer->limits.y1;
-    if (*y >= pPointer->limits.y2)
-	*y = pPointer->limits.y2 - 1;
-
-    if (pPointer->x == *x && pPointer->y == *y && 
-            pPointer->pScreen == pScreen) 
-        return;
-
-    miPointerMoveNoEvent(pDev, pScreen, *x, *y);
-}
-
-/**
- * Get the current position of the device in desktop coordinates.
- *
- * @param x Return value for the current x coordinate in desktop coordiates.
- * @param y Return value for the current y coordinate in desktop coordiates.
- */
-void
-miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)
-{
-    *x = MIPOINTER(pDev)->x;
-    *y = MIPOINTER(pDev)->y;
-}
-
-#ifdef XQUARTZ
-#include <pthread.h>
-void darwinEvents_lock(void);
-void darwinEvents_unlock(void);
-#endif
-
-/**
- * Move the device's pointer to the x/y coordinates on the given screen.
- * This function generates and enqueues pointer events.
- *
- * @param pDev The device to move
- * @param pScreen The screen the device is on
- * @param x The x coordinate in per-screen coordinates
- * @param y The y coordinate in per-screen coordinates
- */
-void
-miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
-    int i, nevents;
-    int valuators[2];
-    ValuatorMask mask;
-
-    miPointerMoveNoEvent(pDev, pScreen, x, y);
-
-    /* generate motion notify */
-    valuators[0] = x;
-    valuators[1] = y;
-
-    if (!events)
-    {
-        events = InitEventList(GetMaximumEventsNum());
-
-        if (!events)
-        {
-            FatalError("Could not allocate event store.\n");
-            return;
-        }
-    }
-
-    valuator_mask_set_range(&mask, 0, 2, valuators);
-    nevents = GetPointerEvents(events, pDev, MotionNotify, 0,
-                               POINTER_SCREEN | POINTER_ABSOLUTE, &mask);
-
-    OsBlockSignals();
-#ifdef XQUARTZ
-    darwinEvents_lock();
-#endif
-    for (i = 0; i < nevents; i++)
-        mieqEnqueue(pDev, (InternalEvent*)events[i].event);
-#ifdef XQUARTZ
-    darwinEvents_unlock();
-#endif
-    OsReleaseSignals();
-}
+/*
+
+Copyright 1989, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+*/
+
+/**
+ * @file
+ * This file contains functions to move the pointer on the screen and/or
+ * restrict its movement. These functions are divided into two sets:
+ * Screen-specific functions that are used as function pointers from other
+ * parts of the server (and end up heavily wrapped by e.g. animcur and
+ * xfixes):
+ *      miPointerConstrainCursor
+ *      miPointerCursorLimits
+ *      miPointerDisplayCursor
+ *      miPointerRealizeCursor
+ *      miPointerUnrealizeCursor
+ *      miPointerSetCursorPosition
+ *      miRecolorCursor
+ *      miPointerDeviceInitialize
+ *      miPointerDeviceCleanup
+ * If wrapped, these are the last element in the wrapping chain. They may
+ * call into sprite-specific code through further function pointers though.
+ *
+ * The second type of functions are those that are directly called by the
+ * DIX, DDX and some drivers.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+# include   <X11/X.h>
+# include   <X11/Xmd.h>
+# include   <X11/Xproto.h>
+# include   "misc.h"
+# include   "windowstr.h"
+# include   "pixmapstr.h"
+# include   "mi.h"
+# include   "scrnintstr.h"
+# include   "mipointrst.h"
+# include   "cursorstr.h"
+# include   "dixstruct.h"
+# include   "inputstr.h"
+# include   "inpututils.h"
+
+DevPrivateKeyRec miPointerScreenKeyRec;
+
+#define GetScreenPrivate(s) ((miPointerScreenPtr) \
+    dixLookupPrivate(&(s)->devPrivates, miPointerScreenKey))
+#define SetupScreen(s)	miPointerScreenPtr  pScreenPriv = GetScreenPrivate(s)
+
+DevPrivateKeyRec miPointerPrivKeyRec;
+
+#define MIPOINTER(dev) \
+    (IsFloating(dev) ? \
+        (miPointerPtr)dixLookupPrivate(&(dev)->devPrivates, miPointerPrivKey): \
+        (miPointerPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miPointerPrivKey))
+
+static Bool miPointerRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
+                                   CursorPtr pCursor);
+static Bool miPointerUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
+                                     CursorPtr pCursor);
+static Bool miPointerDisplayCursor(DeviceIntPtr pDev, ScreenPtr pScreen, 
+                                   CursorPtr pCursor);
+static void miPointerConstrainCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+                                     BoxPtr pBox); 
+static void miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen,
+                                  CursorPtr pCursor, BoxPtr pHotBox, 
+                                  BoxPtr pTopLeftBox);
+static Bool miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen, 
+                                       int x, int y,
+				       Bool generateEvent);
+static Bool miPointerCloseScreen(int index, ScreenPtr pScreen);
+static void miPointerMove(DeviceIntPtr pDev, ScreenPtr pScreen, 
+                          int x, int y);
+static Bool miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
+static void miPointerDeviceCleanup(DeviceIntPtr pDev,
+                                   ScreenPtr pScreen);
+static void miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
+
+static EventList* events; /* for WarpPointer MotionNotifies */
+
+Bool
+miPointerInitialize (ScreenPtr                  pScreen,
+                     miPointerSpriteFuncPtr     spriteFuncs,
+                     miPointerScreenFuncPtr     screenFuncs,
+                     Bool                       waitForUpdate)
+{
+    miPointerScreenPtr	pScreenPriv;
+
+    if (!dixRegisterPrivateKey(&miPointerScreenKeyRec, PRIVATE_SCREEN, 0))
+	return FALSE;
+
+    if (!dixRegisterPrivateKey(&miPointerPrivKeyRec, PRIVATE_DEVICE, 0))
+	return FALSE;
+
+    pScreenPriv = malloc(sizeof (miPointerScreenRec));
+    if (!pScreenPriv)
+	return FALSE;
+    pScreenPriv->spriteFuncs = spriteFuncs;
+    pScreenPriv->screenFuncs = screenFuncs;
+    /*
+     * check for uninitialized methods
+     */
+    if (!screenFuncs->EnqueueEvent)
+	screenFuncs->EnqueueEvent = mieqEnqueue;
+    if (!screenFuncs->NewEventScreen)
+	screenFuncs->NewEventScreen = mieqSwitchScreen;
+    pScreenPriv->waitForUpdate = waitForUpdate;
+    pScreenPriv->showTransparent = FALSE;
+    pScreenPriv->CloseScreen = pScreen->CloseScreen;
+    pScreen->CloseScreen = miPointerCloseScreen;
+    dixSetPrivate(&pScreen->devPrivates, miPointerScreenKey, pScreenPriv);
+    /*
+     * set up screen cursor method table
+     */
+    pScreen->ConstrainCursor = miPointerConstrainCursor;
+    pScreen->CursorLimits = miPointerCursorLimits;
+    pScreen->DisplayCursor = miPointerDisplayCursor;
+    pScreen->RealizeCursor = miPointerRealizeCursor;
+    pScreen->UnrealizeCursor = miPointerUnrealizeCursor;
+    pScreen->SetCursorPosition = miPointerSetCursorPosition;
+    pScreen->RecolorCursor = miRecolorCursor;
+    pScreen->DeviceCursorInitialize = miPointerDeviceInitialize;
+    pScreen->DeviceCursorCleanup = miPointerDeviceCleanup;
+
+    events = NULL;
+    return TRUE;
+}
+
+/**
+ * Destroy screen-specific information.
+ *
+ * @param index Screen index of the screen in screenInfo.screens[]
+ * @param pScreen The actual screen pointer
+ */
+static Bool
+miPointerCloseScreen (int index, ScreenPtr pScreen)
+{
+    SetupScreen(pScreen);
+
+    pScreen->CloseScreen = pScreenPriv->CloseScreen;
+    free((pointer) pScreenPriv);
+    FreeEventList(events, GetMaximumEventsNum());
+    events = NULL;
+    return (*pScreen->CloseScreen) (index, pScreen);
+}
+
+/*
+ * DIX/DDX interface routines
+ */
+
+static Bool
+miPointerRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+    SetupScreen(pScreen);
+    return (*pScreenPriv->spriteFuncs->RealizeCursor) (pDev, pScreen, pCursor);
+}
+
+static Bool
+miPointerUnrealizeCursor (DeviceIntPtr  pDev,
+                          ScreenPtr     pScreen,
+                          CursorPtr     pCursor)
+{
+    SetupScreen(pScreen);
+    return (*pScreenPriv->spriteFuncs->UnrealizeCursor) (pDev, pScreen, pCursor);
+}
+
+static Bool
+miPointerDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+    miPointerPtr pPointer;
+
+    /* return for keyboards */
+    if (!IsPointerDevice(pDev))
+            return FALSE;
+
+    pPointer = MIPOINTER(pDev);
+
+    pPointer->pCursor = pCursor;
+    pPointer->pScreen = pScreen;
+    miPointerUpdateSprite(pDev);
+    return TRUE;
+}
+
+/**
+ * Set up the constraints for the given device. This function does not
+ * actually constrain the cursor but merely copies the given box to the
+ * internal constraint storage.
+ *
+ * @param pDev The device to constrain to the box
+ * @param pBox The rectangle to constrain the cursor to
+ * @param pScreen Used for copying screen confinement
+ */
+static void
+miPointerConstrainCursor (DeviceIntPtr pDev, ScreenPtr pScreen, BoxPtr pBox)
+{
+    miPointerPtr pPointer;
+
+    pPointer = MIPOINTER(pDev);
+
+    pPointer->limits = *pBox;
+    pPointer->confined = PointerConfinedToScreen(pDev);
+}
+
+/**
+ * Should calculate the box for the given cursor, based on screen and the
+ * confinement given. But we assume that whatever box is passed in is valid
+ * anyway.
+ *
+ * @param pDev The device to calculate the cursor limits for
+ * @param pScreen The screen the confinement happens on
+ * @param pCursor The screen the confinement happens on
+ * @param pHotBox The confinement box for the cursor
+ * @param[out] pTopLeftBox The new confinement box, always *pHotBox.
+ */
+static void
+miPointerCursorLimits(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor,
+                      BoxPtr pHotBox, BoxPtr pTopLeftBox)
+{
+    *pTopLeftBox = *pHotBox;
+}
+
+/**
+ * Set the device's cursor position to the x/y position on the given screen.
+ * Generates and event if required.
+ *
+ * This function is called from:
+ *    - sprite init code to place onto initial position
+ *    - the various WarpPointer implementations (core, XI, Xinerama, dmx,…)
+ *    - during the cursor update path in CheckMotion
+ *    - in the Xinerama part of NewCurrentScreen
+ *    - when a RandR/RandR1.2 mode was applied (it may have moved the pointer, so
+ *      it's set back to the original pos)
+ *
+ * @param pDev The device to move
+ * @param pScreen The screen the device is on
+ * @param x The x coordinate in per-screen coordinates
+ * @param y The y coordinate in per-screen coordinates
+ * @param generateEvent True if the pointer movement should generate an
+ * event.
+ *
+ * @return TRUE in all cases
+ */
+static Bool
+miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen,
+                           int x, int y, Bool generateEvent)
+{
+    SetupScreen (pScreen);
+    miPointerPtr pPointer = MIPOINTER(pDev);
+
+    pPointer->generateEvent = generateEvent;
+
+    if (pScreen->ConstrainCursorHarder)
+	pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y);
+
+    /* device dependent - must pend signal and call miPointerWarpCursor */
+    (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y);
+    if (!generateEvent)
+	miPointerUpdateSprite(pDev);
+    return TRUE;
+}
+
+/**
+ * Set up sprite information for the device.
+ * This function will be called once for each device after it is initialized
+ * in the DIX.
+ *
+ * @param pDev The newly created device
+ * @param pScreen The initial sprite scree.
+ */
+static Bool
+miPointerDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    miPointerPtr pPointer;
+    SetupScreen (pScreen);
+
+    pPointer = malloc(sizeof(miPointerRec));
+    if (!pPointer)
+        return FALSE;
+
+    pPointer->pScreen = NULL;
+    pPointer->pSpriteScreen = NULL;
+    pPointer->pCursor = NULL;
+    pPointer->pSpriteCursor = NULL;
+    pPointer->limits.x1 = 0;
+    pPointer->limits.x2 = 32767;
+    pPointer->limits.y1 = 0;
+    pPointer->limits.y2 = 32767;
+    pPointer->confined = FALSE;
+    pPointer->x = 0;
+    pPointer->y = 0;
+    pPointer->generateEvent = FALSE;
+
+    if (!((*pScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen)))
+    {
+        free(pPointer);
+        return FALSE;
+    }
+
+    dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, pPointer);
+    return TRUE;
+}
+
+/**
+ * Clean up after device.
+ * This function will be called once before the device is freed in the DIX
+ *
+ * @param pDev The device to be removed from the server
+ * @param pScreen Current screen of the device
+ */
+static void
+miPointerDeviceCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    SetupScreen(pScreen);
+
+    if (!IsMaster(pDev) && !IsFloating(pDev))
+        return;
+
+    (*pScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
+    free(dixLookupPrivate(&pDev->devPrivates, miPointerPrivKey));
+    dixSetPrivate(&pDev->devPrivates, miPointerPrivKey, NULL);
+}
+
+
+/**
+ * Warp the pointer to the given position on the given screen. May generate
+ * an event, depending on whether we're coming from miPointerSetPosition.
+ *
+ * Once signals are ignored, the WarpCursor function can call this
+ *
+ * @param pDev The device to warp
+ * @param pScreen Screen to warp on
+ * @param x The x coordinate in per-screen coordinates
+ * @param y The y coordinate in per-screen coordinates
+ */
+
+void
+miPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+    miPointerPtr pPointer;
+    BOOL changedScreen = FALSE;
+
+    SetupScreen (pScreen);
+    pPointer = MIPOINTER(pDev);
+
+    if (pPointer->pScreen != pScreen)
+    {
+	(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE);
+        changedScreen = TRUE;
+    }
+
+    if (pPointer->generateEvent)
+	miPointerMove (pDev, pScreen, x, y);
+    else
+        miPointerMoveNoEvent(pDev, pScreen, x, y);
+
+    /* Don't call USFS if we use Xinerama, otherwise the root window is
+     * updated to the second screen, and we never receive any events.
+     * (FDO bug #18668) */
+    if (changedScreen
+#ifdef PANORAMIX
+            && noPanoramiXExtension
+#endif
+       )
+        UpdateSpriteForScreen (pDev, pScreen) ;
+}
+
+/**
+ * Syncronize the sprite with the cursor.
+ *
+ * @param pDev The device to sync
+ */
+void
+miPointerUpdateSprite (DeviceIntPtr pDev)
+{
+    ScreenPtr		pScreen;
+    miPointerScreenPtr	pScreenPriv;
+    CursorPtr		pCursor;
+    int			x, y, devx, devy;
+    miPointerPtr        pPointer;
+
+    if (!pDev || !pDev->coreEvents)
+        return;
+
+    pPointer = MIPOINTER(pDev);
+
+    if (!pPointer)
+        return;
+
+    pScreen = pPointer->pScreen;
+    if (!pScreen)
+	return;
+
+    x = pPointer->x;
+    y = pPointer->y;
+    devx = pPointer->devx;
+    devy = pPointer->devy;
+
+    pScreenPriv = GetScreenPrivate (pScreen);
+    /*
+     * if the cursor has switched screens, disable the sprite
+     * on the old screen
+     */
+    if (pScreen != pPointer->pSpriteScreen)
+    {
+	if (pPointer->pSpriteScreen)
+	{
+	    miPointerScreenPtr  pOldPriv;
+    	
+	    pOldPriv = GetScreenPrivate (pPointer->pSpriteScreen);
+	    if (pPointer->pCursor)
+	    {
+	    	(*pOldPriv->spriteFuncs->SetCursor)
+			    	(pDev, pPointer->pSpriteScreen, NullCursor, 0, 0);
+	    }
+	    (*pOldPriv->screenFuncs->CrossScreen) (pPointer->pSpriteScreen, FALSE);
+	}
+	(*pScreenPriv->screenFuncs->CrossScreen) (pScreen, TRUE);
+	(*pScreenPriv->spriteFuncs->SetCursor)
+				(pDev, pScreen, pPointer->pCursor, x, y);
+	pPointer->devx = x;
+	pPointer->devy = y;
+	pPointer->pSpriteCursor = pPointer->pCursor;
+	pPointer->pSpriteScreen = pScreen;
+    }
+    /*
+     * if the cursor has changed, display the new one
+     */
+    else if (pPointer->pCursor != pPointer->pSpriteCursor)
+    {
+	pCursor = pPointer->pCursor;
+	if (!pCursor || (pCursor->bits->emptyMask && !pScreenPriv->showTransparent))
+	    pCursor = NullCursor;
+	(*pScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, pCursor, x, y);
+
+	pPointer->devx = x;
+	pPointer->devy = y;
+	pPointer->pSpriteCursor = pPointer->pCursor;
+    }
+    else if (x != devx || y != devy)
+    {
+	pPointer->devx = x;
+	pPointer->devy = y;
+	if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask)
+	    (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y);
+    }
+}
+
+/**
+ * Set the device to the coordinates on the given screen.
+ *
+ * @param pDev The device to move
+ * @param screen_no Index of the screen to move to
+ * @param x The x coordinate in per-screen coordinates
+ * @param y The y coordinate in per-screen coordinates
+ */
+void
+miPointerSetScreen(DeviceIntPtr pDev, int screen_no, int x, int y)
+{
+	miPointerScreenPtr pScreenPriv;
+	ScreenPtr pScreen;
+        miPointerPtr pPointer;
+
+        pPointer = MIPOINTER(pDev);
+
+	pScreen = screenInfo.screens[screen_no];
+	pScreenPriv = GetScreenPrivate (pScreen);
+	(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, FALSE);
+	NewCurrentScreen (pDev, pScreen, x, y);
+
+        pPointer->limits.x2 = pScreen->width;
+        pPointer->limits.y2 = pScreen->height;
+}
+
+/**
+ * @return The current screen of the VCP
+ */
+ScreenPtr
+miPointerCurrentScreen (void)
+{
+    return miPointerGetScreen(inputInfo.pointer);
+}
+
+/**
+ * @return The current screen of the given device or NULL.
+ */
+ScreenPtr
+miPointerGetScreen(DeviceIntPtr pDev)
+{
+    miPointerPtr pPointer = MIPOINTER(pDev);
+    return (pPointer) ? pPointer->pScreen : NULL;
+}
+
+/* Controls whether the cursor image should be updated immediately when
+   moved (FALSE) or if something else will be responsible for updating
+   it later (TRUE).  Returns current setting.
+   Caller is responsible for calling OsBlockSignal first.
+*/
+Bool
+miPointerSetWaitForUpdate(ScreenPtr pScreen, Bool wait)
+{
+    SetupScreen(pScreen);
+    Bool prevWait = pScreenPriv->waitForUpdate;
+
+    pScreenPriv->waitForUpdate = wait;
+    return prevWait;
+}
+
+
+/* Move the pointer on the current screen,  and update the sprite. */
+static void
+miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen,
+                int x, int y)
+{
+    miPointerPtr pPointer;
+    SetupScreen(pScreen);
+
+    pPointer = MIPOINTER(pDev);
+
+    /* Hack: We mustn't call into ->MoveCursor for anything but the
+     * VCP, as this may cause a non-HW rendered cursor to be rendered during
+     * SIGIO. This again leads to allocs during SIGIO which leads to SIGABRT.
+     */
+    if (GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer
+        && !pScreenPriv->waitForUpdate && pScreen == pPointer->pSpriteScreen)
+    {
+	pPointer->devx = x;
+	pPointer->devy = y;
+	if(pPointer->pCursor && !pPointer->pCursor->bits->emptyMask)
+	    (*pScreenPriv->spriteFuncs->MoveCursor) (pDev, pScreen, x, y);
+    }
+
+    pPointer->x = x;
+    pPointer->y = y;
+    pPointer->pScreen = pScreen;
+}
+
+/**
+ * Set the devices' cursor position to the given x/y position.
+ *
+ * This function is called during the pointer update path in
+ * GetPointerEvents and friends (and the same in the xwin DDX).
+ *
+ * The coordinates provided are always absolute. The parameter mode whether
+ * it was relative or absolute movement that landed us at those coordinates.
+ *
+ * @param pDev The device to move
+ * @param mode Movement mode (Absolute or Relative)
+ * @param[in,out] x The x coordiante in screen coordinates (in regards to total
+ * desktop size)
+ * @param[in,out] y The y coordiante in screen coordinates (in regards to total
+ * desktop size)
+ */
+void
+miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y)
+{
+    miPointerScreenPtr	pScreenPriv;
+    ScreenPtr		pScreen;
+    ScreenPtr		newScreen;
+
+    miPointerPtr        pPointer; 
+
+    if (!pDev || !pDev->coreEvents)
+        return;
+
+    pPointer = MIPOINTER(pDev);
+    pScreen = pPointer->pScreen;
+    if (!pScreen)
+	return;	    /* called before ready */
+
+    if (*x < 0 || *x >= pScreen->width || *y < 0 || *y >= pScreen->height)
+    {
+	pScreenPriv = GetScreenPrivate (pScreen);
+	if (!pPointer->confined)
+	{
+	    newScreen = pScreen;
+	    (*pScreenPriv->screenFuncs->CursorOffScreen) (&newScreen, x, y);
+	    if (newScreen != pScreen)
+	    {
+		pScreen = newScreen;
+		(*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen,
+							     FALSE);
+		pScreenPriv = GetScreenPrivate (pScreen);
+	    	/* Smash the confine to the new screen */
+                pPointer->limits.x2 = pScreen->width;
+                pPointer->limits.y2 = pScreen->height;
+	    }
+	}
+    }
+    /* Constrain the sprite to the current limits. */
+    if (*x < pPointer->limits.x1)
+	*x = pPointer->limits.x1;
+    if (*x >= pPointer->limits.x2)
+	*x = pPointer->limits.x2 - 1;
+    if (*y < pPointer->limits.y1)
+	*y = pPointer->limits.y1;
+    if (*y >= pPointer->limits.y2)
+	*y = pPointer->limits.y2 - 1;
+
+    if (pScreen->ConstrainCursorHarder)
+       pScreen->ConstrainCursorHarder(pDev, pScreen, mode, x, y);
+
+    if (pPointer->x == *x && pPointer->y == *y && 
+            pPointer->pScreen == pScreen) 
+        return;
+
+    miPointerMoveNoEvent(pDev, pScreen, *x, *y);
+}
+
+/**
+ * Get the current position of the device in desktop coordinates.
+ *
+ * @param x Return value for the current x coordinate in desktop coordiates.
+ * @param y Return value for the current y coordinate in desktop coordiates.
+ */
+void
+miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)
+{
+    *x = MIPOINTER(pDev)->x;
+    *y = MIPOINTER(pDev)->y;
+}
+
+#ifdef XQUARTZ
+#include <pthread.h>
+void darwinEvents_lock(void);
+void darwinEvents_unlock(void);
+#endif
+
+/**
+ * Move the device's pointer to the x/y coordinates on the given screen.
+ * This function generates and enqueues pointer events.
+ *
+ * @param pDev The device to move
+ * @param pScreen The screen the device is on
+ * @param x The x coordinate in per-screen coordinates
+ * @param y The y coordinate in per-screen coordinates
+ */
+void
+miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+    int i, nevents;
+    int valuators[2];
+    ValuatorMask mask;
+
+    miPointerMoveNoEvent(pDev, pScreen, x, y);
+
+    /* generate motion notify */
+    valuators[0] = x;
+    valuators[1] = y;
+
+    if (!events)
+    {
+        events = InitEventList(GetMaximumEventsNum());
+
+        if (!events)
+        {
+            FatalError("Could not allocate event store.\n");
+            return;
+        }
+    }
+
+    valuator_mask_set_range(&mask, 0, 2, valuators);
+    nevents = GetPointerEvents(events, pDev, MotionNotify, 0,
+                               POINTER_SCREEN | POINTER_ABSOLUTE, &mask);
+
+    OsBlockSignals();
+#ifdef XQUARTZ
+    darwinEvents_lock();
+#endif
+    for (i = 0; i < nevents; i++)
+        mieqEnqueue(pDev, (InternalEvent*)events[i].event);
+#ifdef XQUARTZ
+    darwinEvents_unlock();
+#endif
+    OsReleaseSignals();
+}
diff --git a/xorg-server/mi/mipointer.h b/xorg-server/mi/mipointer.h
index caf505019..426ef1650 100644
--- a/xorg-server/mi/mipointer.h
+++ b/xorg-server/mi/mipointer.h
@@ -133,6 +133,7 @@ extern _X_EXPORT void miPointerGetPosition(
  * x and y are modified in-place. */
 extern _X_EXPORT void miPointerSetPosition(
     DeviceIntPtr pDev,
+    int mode,
     int *x,
     int *y);
 
diff --git a/xorg-server/mi/misprite.c b/xorg-server/mi/misprite.c
index b0290af29..0b47592f0 100644
--- a/xorg-server/mi/misprite.c
+++ b/xorg-server/mi/misprite.c
@@ -1,1045 +1,1042 @@
-/*
- * misprite.c
- *
- * machine independent software sprite routines
- */
-
-/*
-
-Copyright 1989, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-*/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include   <X11/X.h>
-#include   <X11/Xproto.h>
-#include   "misc.h"
-#include   "pixmapstr.h"
-#include   "input.h"
-#include   "mi.h"
-#include   "cursorstr.h"
-#include   <X11/fonts/font.h>
-#include   "scrnintstr.h"
-#include   "colormapst.h"
-#include   "windowstr.h"
-#include   "gcstruct.h"
-#include   "mipointer.h"
-#include   "misprite.h"
-#include   "dixfontstr.h"
-#include   <X11/fonts/fontstruct.h>
-#include   "inputstr.h"
-#include   "damage.h"
-
-typedef struct {
-    CursorPtr	    pCursor;
-    int		    x;			/* cursor hotspot */
-    int		    y;
-    BoxRec	    saved;		/* saved area from the screen */
-    Bool	    isUp;		/* cursor in frame buffer */
-    Bool	    shouldBeUp;		/* cursor should be displayed */
-    WindowPtr	    pCacheWin;		/* window the cursor last seen in */
-    Bool	    isInCacheWin;
-    Bool	    checkPixels;	/* check colormap collision */
-    ScreenPtr       pScreen;
-} miCursorInfoRec, *miCursorInfoPtr;
-
-/*
- * per screen information
- */
-
-typedef struct {
-    /* screen procedures */
-    CloseScreenProcPtr			CloseScreen;
-    GetImageProcPtr			GetImage;
-    GetSpansProcPtr			GetSpans;
-    SourceValidateProcPtr		SourceValidate;
-    
-    /* window procedures */
-    CopyWindowProcPtr			CopyWindow;
-    
-    /* colormap procedures */
-    InstallColormapProcPtr		InstallColormap;
-    StoreColorsProcPtr			StoreColors;
-    
-    /* os layer procedures */
-    ScreenBlockHandlerProcPtr		BlockHandler;
-    
-    /* device cursor procedures */
-    DeviceCursorInitializeProcPtr       DeviceCursorInitialize;
-    DeviceCursorCleanupProcPtr          DeviceCursorCleanup;
-
-    xColorItem	    colors[2];
-    ColormapPtr     pInstalledMap;
-    ColormapPtr     pColormap;
-    VisualPtr	    pVisual;
-    DamagePtr	    pDamage;		/* damage tracking structure */
-    Bool            damageRegistered;
-    int             numberOfCursors;
-} miSpriteScreenRec, *miSpriteScreenPtr;
-
-#define SOURCE_COLOR	0
-#define MASK_COLOR	1
-
-/*
- * Overlap BoxPtr and Box elements
- */
-#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \
- 	(((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \
-	 ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2))
-
-/*
- * Overlap BoxPtr, origins, and rectangle
- */
-#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \
-    BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h))
-
-/*
- * Overlap BoxPtr, origins and RectPtr
- */
-#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \
-    ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \
-		(int)((pRect)->width), (int)((pRect)->height))
-/*
- * Overlap BoxPtr and horizontal span
- */
-#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
-
-#define LINE_SORT(x1,y1,x2,y2) \
-{ int _t; \
-  if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \
-  if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } }
-
-#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \
-    BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2))
-
-
-#define SPRITE_DEBUG_ENABLE 0
-#if SPRITE_DEBUG_ENABLE
-#define SPRITE_DEBUG(x)	ErrorF x
-#else
-#define SPRITE_DEBUG(x)
-#endif
-
-#define MISPRITE(dev) \
-    (IsFloating(dev) ? \
-       (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \
-       (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey))
-
-static void
-miSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
-{
-    if (pScreenPriv->damageRegistered) {
-	DamageUnregister (&(pScreen->GetScreenPixmap(pScreen)->drawable),
-			  pScreenPriv->pDamage);
-	pScreenPriv->damageRegistered = 0;
-    }
-}
-
-static void
-miSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
-{
-    if (!pScreenPriv->damageRegistered) {
-	pScreenPriv->damageRegistered = 1;
-	DamageRegister (&(pScreen->GetScreenPixmap(pScreen)->drawable),
-			pScreenPriv->pDamage);
-    }
-}
-
-static void
-miSpriteIsUp(miCursorInfoPtr pDevCursor)
-{
-    pDevCursor->isUp = TRUE;
-}
-
-static void
-miSpriteIsDown(miCursorInfoPtr pDevCursor)
-{
-    pDevCursor->isUp = FALSE;
-}
-
-/*
- * screen wrappers
- */
-
-static DevPrivateKeyRec miSpriteScreenKeyRec;
-#define miSpriteScreenKey (&miSpriteScreenKeyRec)
-#define GetSpriteScreen(pScreen) \
-	(dixLookupPrivate(&(pScreen)->devPrivates, miSpriteScreenKey))
-static DevPrivateKeyRec miSpriteDevPrivatesKeyRec;
-#define miSpriteDevPrivatesKey (&miSpriteDevPrivatesKeyRec)
-
-static Bool	    miSpriteCloseScreen(int i, ScreenPtr pScreen);
-static void	    miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy,
-				     int w, int h, unsigned int format,
-				     unsigned long planemask, char *pdstLine);
-static void	    miSpriteGetSpans(DrawablePtr pDrawable, int wMax,
-				     DDXPointPtr ppt, int *pwidth, int nspans,
-				     char *pdstStart);
-static void	    miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
-					   int width, int height,
-					   unsigned int subWindowMode);
-static void	    miSpriteCopyWindow (WindowPtr pWindow,
-					DDXPointRec ptOldOrg,
-					RegionPtr prgnSrc);
-static void	    miSpriteBlockHandler(int i, pointer blockData,
-					 pointer pTimeout,
-					 pointer pReadMask);
-static void	    miSpriteInstallColormap(ColormapPtr pMap);
-static void	    miSpriteStoreColors(ColormapPtr pMap, int ndef,
-					xColorItem *pdef);
-
-static void	    miSpriteComputeSaved(DeviceIntPtr pDev,
-                                         ScreenPtr pScreen);
-
-static Bool         miSpriteDeviceCursorInitialize(DeviceIntPtr pDev,
-                                                   ScreenPtr pScreen);
-static void         miSpriteDeviceCursorCleanup(DeviceIntPtr pDev,
-                                                ScreenPtr pScreen);
-
-#define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \
-   (pPriv)->field)
-#define SCREEN_EPILOGUE(pPriv, pScreen, field)\
-    ((pPriv)->field = (pScreen)->field, (pScreen)->field = miSprite##field)
-
-/*
- * pointer-sprite method table
- */
-
-static Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
-                                  CursorPtr pCursor);
-static Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
-                                    CursorPtr pCursor);
-static void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
-                              CursorPtr pCursor, int x, int y);
-static void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
-                               int x, int y);
-
-miPointerSpriteFuncRec miSpritePointerFuncs = {
-    miSpriteRealizeCursor,
-    miSpriteUnrealizeCursor,
-    miSpriteSetCursor,
-    miSpriteMoveCursor,
-    miSpriteDeviceCursorInitialize,
-    miSpriteDeviceCursorCleanup,
-};
-
-/*
- * other misc functions
- */
-
-static void miSpriteRemoveCursor(DeviceIntPtr pDev,
-                                 ScreenPtr pScreen);
-static void miSpriteSaveUnderCursor(DeviceIntPtr pDev,
-                                 ScreenPtr pScreen);
-static void miSpriteRestoreCursor(DeviceIntPtr pDev,
-                                 ScreenPtr pScreen);
-
-static void
-miSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
-{
-    if (!pScreenPriv->BlockHandler) {
-        pScreenPriv->BlockHandler = pScreen->BlockHandler;
-        pScreen->BlockHandler = miSpriteBlockHandler;
-    }
-}
-
-static void
-miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
-{
-    ScreenPtr		    pScreen = closure;
-    miCursorInfoPtr         pCursorInfo;
-    DeviceIntPtr            pDev;
-
-    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
-    {
-        if (DevHasCursor(pDev))
-        {
-            pCursorInfo = MISPRITE(pDev);
-
-            if (pCursorInfo->isUp &&
-                pCursorInfo->pScreen == pScreen &&
-                RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT)
-            {
-                SPRITE_DEBUG(("Damage remove\n"));
-                miSpriteRemoveCursor (pDev, pScreen);
-            }
-        }
-    }
-}
-
-/*
- * miSpriteInitialize -- called from device-dependent screen
- * initialization proc after all of the function pointers have
- * been stored in the screen structure.
- */
-
-Bool
-miSpriteInitialize (ScreenPtr               pScreen,
-                    miPointerScreenFuncPtr  screenFuncs)
-{
-    miSpriteScreenPtr	pScreenPriv;
-    VisualPtr		pVisual;
-
-    if (!DamageSetup (pScreen))
-	return FALSE;
-
-    if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0))
-	return FALSE;
-
-    if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, 0))
-	return FALSE;
-
-    pScreenPriv = malloc(sizeof (miSpriteScreenRec));
-    if (!pScreenPriv)
-	return FALSE;
-
-    pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage,
-					 NULL,
-					 DamageReportRawRegion,
-					 TRUE,
-					 pScreen,
-					 pScreen);
-
-    if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
-    {
-	free(pScreenPriv);
-	return FALSE;
-    }
-    for (pVisual = pScreen->visuals;
-	 pVisual->vid != pScreen->rootVisual;
-	 pVisual++)
-	;
-    pScreenPriv->pVisual = pVisual;
-    pScreenPriv->CloseScreen = pScreen->CloseScreen;
-    pScreenPriv->GetImage = pScreen->GetImage;
-    pScreenPriv->GetSpans = pScreen->GetSpans;
-    pScreenPriv->SourceValidate = pScreen->SourceValidate;
-
-    pScreenPriv->CopyWindow = pScreen->CopyWindow;
-
-    pScreenPriv->InstallColormap = pScreen->InstallColormap;
-    pScreenPriv->StoreColors = pScreen->StoreColors;
-
-    pScreenPriv->BlockHandler = NULL;
-
-    pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize;
-    pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup;
-
-    pScreenPriv->pInstalledMap = NULL;
-    pScreenPriv->pColormap = NULL;
-    pScreenPriv->colors[SOURCE_COLOR].red = 0;
-    pScreenPriv->colors[SOURCE_COLOR].green = 0;
-    pScreenPriv->colors[SOURCE_COLOR].blue = 0;
-    pScreenPriv->colors[MASK_COLOR].red = 0;
-    pScreenPriv->colors[MASK_COLOR].green = 0;
-    pScreenPriv->colors[MASK_COLOR].blue = 0;
-    pScreenPriv->damageRegistered = 0;
-    pScreenPriv->numberOfCursors = 0;
-
-    dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv);
-
-    pScreen->CloseScreen = miSpriteCloseScreen;
-    pScreen->GetImage = miSpriteGetImage;
-    pScreen->GetSpans = miSpriteGetSpans;
-    pScreen->SourceValidate = miSpriteSourceValidate;
-
-    pScreen->CopyWindow = miSpriteCopyWindow;
-    pScreen->InstallColormap = miSpriteInstallColormap;
-    pScreen->StoreColors = miSpriteStoreColors;
-
-    return TRUE;
-}
-
-/*
- * Screen wrappers
- */
-
-/*
- * CloseScreen wrapper -- unwrap everything, free the private data
- * and call the wrapped function
- */
-
-static Bool
-miSpriteCloseScreen (int i, ScreenPtr pScreen)
-{
-    miSpriteScreenPtr   pScreenPriv = GetSpriteScreen(pScreen);
-
-    pScreen->CloseScreen = pScreenPriv->CloseScreen;
-    pScreen->GetImage = pScreenPriv->GetImage;
-    pScreen->GetSpans = pScreenPriv->GetSpans;
-    pScreen->SourceValidate = pScreenPriv->SourceValidate;
-    pScreen->InstallColormap = pScreenPriv->InstallColormap;
-    pScreen->StoreColors = pScreenPriv->StoreColors;
-
-    DamageDestroy (pScreenPriv->pDamage);
-
-    free(pScreenPriv);
-
-    return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static void
-miSpriteGetImage (DrawablePtr pDrawable, int sx, int sy, int w, int h,
-                  unsigned int format, unsigned long planemask,
-                  char *pdstLine)
-{
-    ScreenPtr           pScreen = pDrawable->pScreen;
-    DeviceIntPtr        pDev;
-    miCursorInfoPtr     pCursorInfo;
-    miSpriteScreenPtr   pPriv = GetSpriteScreen(pScreen);
-
-    SCREEN_PROLOGUE (pPriv, pScreen, GetImage);
-
-    if (pDrawable->type == DRAWABLE_WINDOW)
-    {
-        for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
-        {
-            if (DevHasCursor(pDev))
-            {
-                 pCursorInfo = MISPRITE(pDev);
-                 if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
-                      ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y,
-                                  sx, sy, w, h))
-                 {
-                     SPRITE_DEBUG (("GetImage remove\n"));
-                     miSpriteRemoveCursor (pDev, pScreen);
-                 }
-            }
-        }
-    }
-
-    (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
-			  format, planemask, pdstLine);
-
-    SCREEN_EPILOGUE (pPriv, pScreen, GetImage);
-}
-
-static void
-miSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
-                  int *pwidth, int nspans, char *pdstStart)
-{
-    ScreenPtr		    pScreen = pDrawable->pScreen;
-    DeviceIntPtr            pDev;
-    miCursorInfoPtr         pCursorInfo;
-    miSpriteScreenPtr       pPriv = GetSpriteScreen(pScreen);
-
-    SCREEN_PROLOGUE (pPriv, pScreen, GetSpans);
-
-    if (pDrawable->type == DRAWABLE_WINDOW)
-    {
-        for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
-        {
-            if (DevHasCursor(pDev))
-            {
-                pCursorInfo = MISPRITE(pDev);
-
-                if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
-                {
-                    DDXPointPtr    pts;
-                    int    	       *widths;
-                    int    	       nPts;
-                    int    	       xorg,
-                                   yorg;
-
-                    xorg = pDrawable->x;
-                    yorg = pDrawable->y;
-
-                    for (pts = ppt, widths = pwidth, nPts = nspans;
-                            nPts--;
-                            pts++, widths++)
-                    {
-                        if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg,
-                                    pts->x+xorg,*widths))
-                        {
-                            SPRITE_DEBUG (("GetSpans remove\n"));
-                            miSpriteRemoveCursor (pDev, pScreen);
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
-
-    SCREEN_EPILOGUE (pPriv, pScreen, GetSpans);
-}
-
-static void
-miSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width,
-                        int height, unsigned int subWindowMode)
-{
-    ScreenPtr		    pScreen = pDrawable->pScreen;
-    DeviceIntPtr            pDev;
-    miCursorInfoPtr         pCursorInfo;
-    miSpriteScreenPtr       pPriv = GetSpriteScreen(pScreen);
-
-    SCREEN_PROLOGUE (pPriv, pScreen, SourceValidate);
-
-    if (pDrawable->type == DRAWABLE_WINDOW)
-    {
-	for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
-	{
-	    if (DevHasCursor(pDev))
-	    {
-		pCursorInfo = MISPRITE(pDev);
-		if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
-		    ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y,
-				x, y, width, height))
-		{
-		    SPRITE_DEBUG (("SourceValidate remove\n"));
-		    miSpriteRemoveCursor (pDev, pScreen);
-		}
-	    }
-	}
-    }
-
-    if (pScreen->SourceValidate)
-	(*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode);
-
-    SCREEN_EPILOGUE (pPriv, pScreen, SourceValidate);
-}
-
-static void
-miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
-    ScreenPtr	pScreen = pWindow->drawable.pScreen;
-    DeviceIntPtr            pDev;
-    miCursorInfoPtr         pCursorInfo;
-    miSpriteScreenPtr       pPriv = GetSpriteScreen(pScreen);
-
-    SCREEN_PROLOGUE (pPriv, pScreen, CopyWindow);
-
-    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
-    {
-        if (DevHasCursor(pDev))
-        {
-            pCursorInfo = MISPRITE(pDev);
-            /*
-             * Damage will take care of destination check
-             */
-            if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
-                    RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT)
-            {
-                SPRITE_DEBUG (("CopyWindow remove\n"));
-                miSpriteRemoveCursor (pDev, pScreen);
-            }
-        }
-    }
-
-    (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
-    SCREEN_EPILOGUE (pPriv, pScreen, CopyWindow);
-}
-
-static void
-miSpriteBlockHandler (int i, pointer blockData, pointer pTimeout,
-                      pointer pReadmask)
-{
-    ScreenPtr		pScreen = screenInfo.screens[i];
-    miSpriteScreenPtr	pPriv = GetSpriteScreen(pScreen);
-    DeviceIntPtr            pDev;
-    miCursorInfoPtr         pCursorInfo;
-    Bool                WorkToDo = FALSE;
-
-    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
-    {
-        if (DevHasCursor(pDev))
-        {
-            pCursorInfo = MISPRITE(pDev);
-            if (pCursorInfo && !pCursorInfo->isUp
-                    && pCursorInfo->pScreen == pScreen
-                    && pCursorInfo->shouldBeUp)
-            {
-                SPRITE_DEBUG (("BlockHandler save"));
-                miSpriteSaveUnderCursor (pDev, pScreen);
-            }
-        }
-    }
-    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
-    {
-        if (DevHasCursor(pDev))
-        {
-            pCursorInfo = MISPRITE(pDev);
-            if (pCursorInfo && !pCursorInfo->isUp &&
-                    pCursorInfo->pScreen == pScreen &&
-                    pCursorInfo->shouldBeUp)
-            {
-                SPRITE_DEBUG (("BlockHandler restore\n"));
-                miSpriteRestoreCursor (pDev, pScreen);
-                if (!pCursorInfo->isUp)
-                    WorkToDo = TRUE;
-            }
-        }
-    }
-
-    SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler);
-
-    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
-
-    if (WorkToDo)
-        SCREEN_EPILOGUE(pPriv, pScreen, BlockHandler);
-    else
-        pPriv->BlockHandler = NULL;
-}
-
-static void
-miSpriteInstallColormap (ColormapPtr pMap)
-{
-    ScreenPtr		pScreen = pMap->pScreen;
-    miSpriteScreenPtr	pPriv = GetSpriteScreen(pScreen);
-
-    SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap);
-
-    (*pScreen->InstallColormap) (pMap);
-
-    SCREEN_EPILOGUE(pPriv, pScreen, InstallColormap);
-
-    /* InstallColormap can be called before devices are initialized. */
-    pPriv->pInstalledMap = pMap;
-    if (pPriv->pColormap != pMap)
-    {
-        DeviceIntPtr pDev;
-        miCursorInfoPtr     pCursorInfo;
-        for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
-        {
-            if (DevHasCursor(pDev))
-            {
-                pCursorInfo = MISPRITE(pDev);
-                pCursorInfo->checkPixels = TRUE;
-                if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
-                    miSpriteRemoveCursor(pDev, pScreen);
-            }
-        }
-
-    }
-}
-
-static void
-miSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef)
-{
-    ScreenPtr		pScreen = pMap->pScreen;
-    miSpriteScreenPtr	pPriv = GetSpriteScreen(pScreen);
-    int			i;
-    int			updated;
-    VisualPtr		pVisual;
-    DeviceIntPtr        pDev;
-    miCursorInfoPtr     pCursorInfo;
-
-    SCREEN_PROLOGUE(pPriv, pScreen, StoreColors);
-
-    (*pScreen->StoreColors) (pMap, ndef, pdef);
-
-    SCREEN_EPILOGUE(pPriv, pScreen, StoreColors);
-
-    if (pPriv->pColormap == pMap)
-    {
-        updated = 0;
-        pVisual = pMap->pVisual;
-        if (pVisual->class == DirectColor)
-        {
-            /* Direct color - match on any of the subfields */
-
-#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
-
-#define UpdateDAC(dev, plane,dac,mask) {\
-    if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\
-	dev->colors[plane].dac = pdef[i].dac; \
-	updated = 1; \
-    } \
-}
-
-#define CheckDirect(dev, plane) \
-	    UpdateDAC(dev, plane,red,redMask) \
-	    UpdateDAC(dev, plane,green,greenMask) \
-	    UpdateDAC(dev, plane,blue,blueMask)
-
-            for (i = 0; i < ndef; i++)
-            {
-                CheckDirect (pPriv, SOURCE_COLOR)
-                CheckDirect (pPriv, MASK_COLOR)
-            }
-        }
-        else
-        {
-            /* PseudoColor/GrayScale - match on exact pixel */
-            for (i = 0; i < ndef; i++)
-            {
-                if (pdef[i].pixel ==
-                        pPriv->colors[SOURCE_COLOR].pixel)
-                {
-                    pPriv->colors[SOURCE_COLOR] = pdef[i];
-                    if (++updated == 2)
-                        break;
-                }
-                if (pdef[i].pixel ==
-                        pPriv->colors[MASK_COLOR].pixel)
-                {
-                    pPriv->colors[MASK_COLOR] = pdef[i];
-                    if (++updated == 2)
-                        break;
-                }
-            }
-        }
-        if (updated)
-        {
-            for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
-            {
-                if (DevHasCursor(pDev))
-                {
-                    pCursorInfo = MISPRITE(pDev);
-                    pCursorInfo->checkPixels = TRUE;
-                    if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
-                        miSpriteRemoveCursor (pDev, pScreen);
-                }
-            }
-        }
-    }
-}
-
-static void
-miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen)
-{
-    miSpriteScreenPtr	pScreenPriv = GetSpriteScreen(pScreen);
-    CursorPtr		pCursor;
-    xColorItem		*sourceColor, *maskColor;
-
-    pCursor = pDevCursor->pCursor;
-    sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
-    maskColor = &pScreenPriv->colors[MASK_COLOR];
-    if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
-	!(pCursor->foreRed == sourceColor->red &&
-	  pCursor->foreGreen == sourceColor->green &&
-          pCursor->foreBlue == sourceColor->blue &&
-	  pCursor->backRed == maskColor->red &&
-	  pCursor->backGreen == maskColor->green &&
-	  pCursor->backBlue == maskColor->blue))
-    {
-	pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
-	sourceColor->red = pCursor->foreRed;
-	sourceColor->green = pCursor->foreGreen;
-	sourceColor->blue = pCursor->foreBlue;
-	FakeAllocColor (pScreenPriv->pColormap, sourceColor);
-	maskColor->red = pCursor->backRed;
-	maskColor->green = pCursor->backGreen;
-	maskColor->blue = pCursor->backBlue;
-	FakeAllocColor (pScreenPriv->pColormap, maskColor);
-	/* "free" the pixels right away, don't let this confuse you */
-	FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
-	FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
-    }
-
-    pDevCursor->checkPixels = FALSE;
-
-}
-
-/*
- * miPointer interface routines
- */
-
-#define SPRITE_PAD  8
-
-static Bool
-miSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
-    miCursorInfoPtr pCursorInfo;
-
-    if (IsFloating(pDev))
-        return FALSE;
-
-    pCursorInfo = MISPRITE(pDev);
-
-    if (pCursor == pCursorInfo->pCursor)
-	pCursorInfo->checkPixels = TRUE;
-
-    return miDCRealizeCursor(pScreen, pCursor);
-}
-
-static Bool
-miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
-    return miDCUnrealizeCursor(pScreen, pCursor);
-}
-
-static void
-miSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
-                   CursorPtr pCursor, int x, int y)
-{
-    miCursorInfoPtr     pPointer;
-    miSpriteScreenPtr   pScreenPriv;
-
-    if (IsFloating(pDev))
-        return;
-
-    pPointer = MISPRITE(pDev);
-    pScreenPriv = GetSpriteScreen(pScreen);
-
-    if (!pCursor)
-    {
-	if (pPointer->shouldBeUp)
-	    --pScreenPriv->numberOfCursors;
-    	pPointer->shouldBeUp = FALSE;
-    	if (pPointer->isUp)
-	    miSpriteRemoveCursor (pDev, pScreen);
-	if (pScreenPriv->numberOfCursors == 0)
-	    miSpriteDisableDamage(pScreen, pScreenPriv);
-	pPointer->pCursor = 0;
-	return;
-    }
-    if (!pPointer->shouldBeUp)
-	pScreenPriv->numberOfCursors++;
-    pPointer->shouldBeUp = TRUE;
-    if (!pPointer->isUp)
-	miSpriteRegisterBlockHandler(pScreen, pScreenPriv);
-    if (pPointer->x == x &&
-	pPointer->y == y &&
-	pPointer->pCursor == pCursor &&
-	!pPointer->checkPixels)
-    {
-	return;
-    }
-    pPointer->x = x;
-    pPointer->y = y;
-    pPointer->pCacheWin = NullWindow;
-    if (pPointer->checkPixels || pPointer->pCursor != pCursor)
-    {
-	pPointer->pCursor = pCursor;
-	miSpriteFindColors (pPointer, pScreen);
-    }
-    if (pPointer->isUp) {
-	/* TODO: reimplement flicker-free MoveCursor */
-	SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id));
-	miSpriteRemoveCursor (pDev, pScreen);
-    }
-
-    if (!pPointer->isUp && pPointer->pCursor)
-    {
-	SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id));
-        miSpriteSaveUnderCursor(pDev, pScreen);
-	miSpriteRestoreCursor (pDev, pScreen);
-    }
-
-}
-
-static void
-miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
-    CursorPtr pCursor;
-
-    if (IsFloating(pDev))
-        return;
-
-    pCursor = MISPRITE(pDev)->pCursor;
-
-    miSpriteSetCursor (pDev, pScreen, pCursor, x, y);
-}
-
-
-static Bool
-miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
-    miCursorInfoPtr pCursorInfo;
-    int ret = FALSE;
-
-    pCursorInfo = malloc(sizeof(miCursorInfoRec));
-    if (!pCursorInfo)
-        return FALSE;
-
-    pCursorInfo->pCursor = NULL;
-    pCursorInfo->x = 0;
-    pCursorInfo->y = 0;
-    pCursorInfo->isUp = FALSE;
-    pCursorInfo->shouldBeUp = FALSE;
-    pCursorInfo->pCacheWin = NullWindow;
-    pCursorInfo->isInCacheWin = FALSE;
-    pCursorInfo->checkPixels = TRUE;
-    pCursorInfo->pScreen = FALSE;
-
-    ret = miDCDeviceInitialize(pDev, pScreen);
-    if (!ret)
-    {
-        free(pCursorInfo);
-        pCursorInfo = NULL;
-    }
-    dixSetPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey, pCursorInfo);
-    return ret;
-}
-
-static void
-miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
-    if (DevHasCursor(pDev))
-        miDCDeviceCleanup(pDev, pScreen);
-}
-
-/*
- * undraw/draw cursor
- */
-
-static void
-miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
-{
-    miSpriteScreenPtr   pScreenPriv;
-    miCursorInfoPtr     pCursorInfo;
-
-
-    if (IsFloating(pDev))
-        return;
-
-    DamageDrawInternal (pScreen, TRUE);
-    pScreenPriv = GetSpriteScreen(pScreen);
-    pCursorInfo = MISPRITE(pDev);
-
-    miSpriteIsDown(pCursorInfo);
-    miSpriteRegisterBlockHandler(pScreen, pScreenPriv);
-    pCursorInfo->pCacheWin = NullWindow;
-    miSpriteDisableDamage(pScreen, pScreenPriv);
-    if (!miDCRestoreUnderCursor(pDev,
-                                pScreen,
-                                pCursorInfo->saved.x1,
-                                pCursorInfo->saved.y1,
-                                pCursorInfo->saved.x2 -
-                                pCursorInfo->saved.x1,
-                                pCursorInfo->saved.y2 -
-                                pCursorInfo->saved.y1))
-    {
-        miSpriteIsUp(pCursorInfo);
-    }
-    miSpriteEnableDamage(pScreen, pScreenPriv);
-    DamageDrawInternal (pScreen, FALSE);
-}
-
-/*
- * Called from the block handler, saves area under cursor
- * before waiting for something to do.
- */
-
-static void
-miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
-    miSpriteScreenPtr   pScreenPriv;
-    int			x, y;
-    CursorPtr		pCursor;
-    miCursorInfoPtr     pCursorInfo;
-
-    if (IsFloating(pDev))
-        return;
-
-    DamageDrawInternal (pScreen, TRUE);
-    pScreenPriv = GetSpriteScreen(pScreen);
-    pCursorInfo = MISPRITE(pDev);
-
-    miSpriteComputeSaved (pDev, pScreen);
-    pCursor = pCursorInfo->pCursor;
-
-    x = pCursorInfo->x - (int)pCursor->bits->xhot;
-    y = pCursorInfo->y - (int)pCursor->bits->yhot;
-    miSpriteDisableDamage(pScreen, pScreenPriv);
-
-    miDCSaveUnderCursor(pDev,
-                        pScreen,
-                        pCursorInfo->saved.x1,
-                        pCursorInfo->saved.y1,
-                        pCursorInfo->saved.x2 -
-                        pCursorInfo->saved.x1,
-                        pCursorInfo->saved.y2 -
-                        pCursorInfo->saved.y1);
-    SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id));
-    miSpriteEnableDamage(pScreen, pScreenPriv);
-    DamageDrawInternal (pScreen, FALSE);
-}
-
-
-/*
- * Called from the block handler, restores the cursor
- * before waiting for something to do.
- */
-
-static void
-miSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
-{
-    miSpriteScreenPtr   pScreenPriv;
-    int			x, y;
-    CursorPtr		pCursor;
-    miCursorInfoPtr     pCursorInfo;
-
-    if (IsFloating(pDev))
-        return;
-
-    DamageDrawInternal (pScreen, TRUE);
-    pScreenPriv = GetSpriteScreen(pScreen);
-    pCursorInfo = MISPRITE(pDev);
-
-    miSpriteComputeSaved (pDev, pScreen);
-    pCursor = pCursorInfo->pCursor;
-
-    x = pCursorInfo->x - (int)pCursor->bits->xhot;
-    y = pCursorInfo->y - (int)pCursor->bits->yhot;
-    miSpriteDisableDamage(pScreen, pScreenPriv);
-    SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id));
-    if (pCursorInfo->checkPixels)
-        miSpriteFindColors (pCursorInfo, pScreen);
-    if (miDCPutUpCursor(pDev, pScreen,
-                pCursor, x, y,
-                pScreenPriv->colors[SOURCE_COLOR].pixel,
-                pScreenPriv->colors[MASK_COLOR].pixel))
-    {
-        miSpriteIsUp(pCursorInfo);
-        pCursorInfo->pScreen = pScreen;
-    }
-    miSpriteEnableDamage(pScreen, pScreenPriv);
-    DamageDrawInternal (pScreen, FALSE);
-}
-
-/*
- * compute the desired area of the screen to save
- */
-
-static void
-miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen)
-{
-    int		    x, y, w, h;
-    int		    wpad, hpad;
-    CursorPtr	    pCursor;
-    miCursorInfoPtr pCursorInfo;
-
-    if (IsFloating(pDev))
-        return;
-
-    pCursorInfo = MISPRITE(pDev);
-
-    pCursor = pCursorInfo->pCursor;
-    x = pCursorInfo->x - (int)pCursor->bits->xhot;
-    y = pCursorInfo->y - (int)pCursor->bits->yhot;
-    w = pCursor->bits->width;
-    h = pCursor->bits->height;
-    wpad = SPRITE_PAD;
-    hpad = SPRITE_PAD;
-    pCursorInfo->saved.x1 = x - wpad;
-    pCursorInfo->saved.y1 = y - hpad;
-    pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2;
-    pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2;
-}
-
+/*
+ * misprite.c
+ *
+ * machine independent software sprite routines
+ */
+
+/*
+
+Copyright 1989, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include   <X11/X.h>
+#include   <X11/Xproto.h>
+#include   "misc.h"
+#include   "pixmapstr.h"
+#include   "input.h"
+#include   "mi.h"
+#include   "cursorstr.h"
+#include   <X11/fonts/font.h>
+#include   "scrnintstr.h"
+#include   "colormapst.h"
+#include   "windowstr.h"
+#include   "gcstruct.h"
+#include   "mipointer.h"
+#include   "misprite.h"
+#include   "dixfontstr.h"
+#include   <X11/fonts/fontstruct.h>
+#include   "inputstr.h"
+#include   "damage.h"
+
+typedef struct {
+    CursorPtr	    pCursor;
+    int		    x;			/* cursor hotspot */
+    int		    y;
+    BoxRec	    saved;		/* saved area from the screen */
+    Bool	    isUp;		/* cursor in frame buffer */
+    Bool	    shouldBeUp;		/* cursor should be displayed */
+    WindowPtr	    pCacheWin;		/* window the cursor last seen in */
+    Bool	    isInCacheWin;
+    Bool	    checkPixels;	/* check colormap collision */
+    ScreenPtr       pScreen;
+} miCursorInfoRec, *miCursorInfoPtr;
+
+/*
+ * per screen information
+ */
+
+typedef struct {
+    /* screen procedures */
+    CloseScreenProcPtr			CloseScreen;
+    GetImageProcPtr			GetImage;
+    GetSpansProcPtr			GetSpans;
+    SourceValidateProcPtr		SourceValidate;
+    
+    /* window procedures */
+    CopyWindowProcPtr			CopyWindow;
+    
+    /* colormap procedures */
+    InstallColormapProcPtr		InstallColormap;
+    StoreColorsProcPtr			StoreColors;
+    
+    /* os layer procedures */
+    ScreenBlockHandlerProcPtr		BlockHandler;
+    
+    /* device cursor procedures */
+    DeviceCursorInitializeProcPtr       DeviceCursorInitialize;
+    DeviceCursorCleanupProcPtr          DeviceCursorCleanup;
+
+    xColorItem	    colors[2];
+    ColormapPtr     pInstalledMap;
+    ColormapPtr     pColormap;
+    VisualPtr	    pVisual;
+    DamagePtr	    pDamage;		/* damage tracking structure */
+    Bool            damageRegistered;
+    int             numberOfCursors;
+} miSpriteScreenRec, *miSpriteScreenPtr;
+
+#define SOURCE_COLOR	0
+#define MASK_COLOR	1
+
+/*
+ * Overlap BoxPtr and Box elements
+ */
+#define BOX_OVERLAP(pCbox,X1,Y1,X2,Y2) \
+ 	(((pCbox)->x1 <= (X2)) && ((X1) <= (pCbox)->x2) && \
+	 ((pCbox)->y1 <= (Y2)) && ((Y1) <= (pCbox)->y2))
+
+/*
+ * Overlap BoxPtr, origins, and rectangle
+ */
+#define ORG_OVERLAP(pCbox,xorg,yorg,x,y,w,h) \
+    BOX_OVERLAP((pCbox),(x)+(xorg),(y)+(yorg),(x)+(xorg)+(w),(y)+(yorg)+(h))
+
+/*
+ * Overlap BoxPtr, origins and RectPtr
+ */
+#define ORGRECT_OVERLAP(pCbox,xorg,yorg,pRect) \
+    ORG_OVERLAP((pCbox),(xorg),(yorg),(pRect)->x,(pRect)->y, \
+		(int)((pRect)->width), (int)((pRect)->height))
+/*
+ * Overlap BoxPtr and horizontal span
+ */
+#define SPN_OVERLAP(pCbox,y,x,w) BOX_OVERLAP((pCbox),(x),(y),(x)+(w),(y))
+
+#define LINE_SORT(x1,y1,x2,y2) \
+{ int _t; \
+  if (x1 > x2) { _t = x1; x1 = x2; x2 = _t; } \
+  if (y1 > y2) { _t = y1; y1 = y2; y2 = _t; } }
+
+#define LINE_OVERLAP(pCbox,x1,y1,x2,y2,lw2) \
+    BOX_OVERLAP((pCbox), (x1)-(lw2), (y1)-(lw2), (x2)+(lw2), (y2)+(lw2))
+
+
+#define SPRITE_DEBUG_ENABLE 0
+#if SPRITE_DEBUG_ENABLE
+#define SPRITE_DEBUG(x)	ErrorF x
+#else
+#define SPRITE_DEBUG(x)
+#endif
+
+#define MISPRITE(dev) \
+    (IsFloating(dev) ? \
+       (miCursorInfoPtr)dixLookupPrivate(&dev->devPrivates, miSpriteDevPrivatesKey) : \
+       (miCursorInfoPtr)dixLookupPrivate(&(GetMaster(dev, MASTER_POINTER))->devPrivates, miSpriteDevPrivatesKey))
+
+static void
+miSpriteDisableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
+{
+    if (pScreenPriv->damageRegistered) {
+	DamageUnregister (&(pScreen->GetScreenPixmap(pScreen)->drawable),
+			  pScreenPriv->pDamage);
+	pScreenPriv->damageRegistered = 0;
+    }
+}
+
+static void
+miSpriteEnableDamage(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
+{
+    if (!pScreenPriv->damageRegistered) {
+	pScreenPriv->damageRegistered = 1;
+	DamageRegister (&(pScreen->GetScreenPixmap(pScreen)->drawable),
+			pScreenPriv->pDamage);
+    }
+}
+
+static void
+miSpriteIsUp(miCursorInfoPtr pDevCursor)
+{
+    pDevCursor->isUp = TRUE;
+}
+
+static void
+miSpriteIsDown(miCursorInfoPtr pDevCursor)
+{
+    pDevCursor->isUp = FALSE;
+}
+
+/*
+ * screen wrappers
+ */
+
+static DevPrivateKeyRec miSpriteScreenKeyRec;
+#define miSpriteScreenKey (&miSpriteScreenKeyRec)
+#define GetSpriteScreen(pScreen) \
+	(dixLookupPrivate(&(pScreen)->devPrivates, miSpriteScreenKey))
+static DevPrivateKeyRec miSpriteDevPrivatesKeyRec;
+#define miSpriteDevPrivatesKey (&miSpriteDevPrivatesKeyRec)
+
+static Bool	    miSpriteCloseScreen(int i, ScreenPtr pScreen);
+static void	    miSpriteGetImage(DrawablePtr pDrawable, int sx, int sy,
+				     int w, int h, unsigned int format,
+				     unsigned long planemask, char *pdstLine);
+static void	    miSpriteGetSpans(DrawablePtr pDrawable, int wMax,
+				     DDXPointPtr ppt, int *pwidth, int nspans,
+				     char *pdstStart);
+static void	    miSpriteSourceValidate(DrawablePtr pDrawable, int x, int y,
+					   int width, int height,
+					   unsigned int subWindowMode);
+static void	    miSpriteCopyWindow (WindowPtr pWindow,
+					DDXPointRec ptOldOrg,
+					RegionPtr prgnSrc);
+static void	    miSpriteBlockHandler(int i, pointer blockData,
+					 pointer pTimeout,
+					 pointer pReadMask);
+static void	    miSpriteInstallColormap(ColormapPtr pMap);
+static void	    miSpriteStoreColors(ColormapPtr pMap, int ndef,
+					xColorItem *pdef);
+
+static void	    miSpriteComputeSaved(DeviceIntPtr pDev,
+                                         ScreenPtr pScreen);
+
+static Bool         miSpriteDeviceCursorInitialize(DeviceIntPtr pDev,
+                                                   ScreenPtr pScreen);
+static void         miSpriteDeviceCursorCleanup(DeviceIntPtr pDev,
+                                                ScreenPtr pScreen);
+
+#define SCREEN_PROLOGUE(pPriv, pScreen, field) ((pScreen)->field = \
+   (pPriv)->field)
+#define SCREEN_EPILOGUE(pPriv, pScreen, field)\
+    ((pPriv)->field = (pScreen)->field, (pScreen)->field = miSprite##field)
+
+/*
+ * pointer-sprite method table
+ */
+
+static Bool miSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+                                  CursorPtr pCursor);
+static Bool miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+                                    CursorPtr pCursor);
+static void miSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+                              CursorPtr pCursor, int x, int y);
+static void miSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+                               int x, int y);
+
+miPointerSpriteFuncRec miSpritePointerFuncs = {
+    miSpriteRealizeCursor,
+    miSpriteUnrealizeCursor,
+    miSpriteSetCursor,
+    miSpriteMoveCursor,
+    miSpriteDeviceCursorInitialize,
+    miSpriteDeviceCursorCleanup,
+};
+
+/*
+ * other misc functions
+ */
+
+static void miSpriteRemoveCursor(DeviceIntPtr pDev,
+                                 ScreenPtr pScreen);
+static void miSpriteSaveUnderCursor(DeviceIntPtr pDev,
+                                 ScreenPtr pScreen);
+static void miSpriteRestoreCursor(DeviceIntPtr pDev,
+                                 ScreenPtr pScreen);
+
+static void
+miSpriteRegisterBlockHandler(ScreenPtr pScreen, miSpriteScreenPtr pScreenPriv)
+{
+    if (!pScreenPriv->BlockHandler) {
+        pScreenPriv->BlockHandler = pScreen->BlockHandler;
+        pScreen->BlockHandler = miSpriteBlockHandler;
+    }
+}
+
+static void
+miSpriteReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+    ScreenPtr		    pScreen = closure;
+    miCursorInfoPtr         pCursorInfo;
+    DeviceIntPtr            pDev;
+
+    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+    {
+        if (DevHasCursor(pDev))
+        {
+            pCursorInfo = MISPRITE(pDev);
+
+            if (pCursorInfo->isUp &&
+                pCursorInfo->pScreen == pScreen &&
+                RegionContainsRect(pRegion, &pCursorInfo->saved) != rgnOUT)
+            {
+                SPRITE_DEBUG(("Damage remove\n"));
+                miSpriteRemoveCursor (pDev, pScreen);
+            }
+        }
+    }
+}
+
+/*
+ * miSpriteInitialize -- called from device-dependent screen
+ * initialization proc after all of the function pointers have
+ * been stored in the screen structure.
+ */
+
+Bool
+miSpriteInitialize (ScreenPtr               pScreen,
+                    miPointerScreenFuncPtr  screenFuncs)
+{
+    miSpriteScreenPtr	pScreenPriv;
+    VisualPtr		pVisual;
+
+    if (!DamageSetup (pScreen))
+	return FALSE;
+
+    if (!dixRegisterPrivateKey(&miSpriteScreenKeyRec, PRIVATE_SCREEN, 0))
+	return FALSE;
+
+    if (!dixRegisterPrivateKey(&miSpriteDevPrivatesKeyRec, PRIVATE_DEVICE, sizeof(miCursorInfoRec)))
+	return FALSE;
+
+    pScreenPriv = malloc(sizeof (miSpriteScreenRec));
+    if (!pScreenPriv)
+	return FALSE;
+
+    pScreenPriv->pDamage = DamageCreate (miSpriteReportDamage,
+					 NULL,
+					 DamageReportRawRegion,
+					 TRUE,
+					 pScreen,
+					 pScreen);
+
+    if (!miPointerInitialize (pScreen, &miSpritePointerFuncs, screenFuncs,TRUE))
+    {
+	free(pScreenPriv);
+	return FALSE;
+    }
+    for (pVisual = pScreen->visuals;
+	 pVisual->vid != pScreen->rootVisual;
+	 pVisual++)
+	;
+    pScreenPriv->pVisual = pVisual;
+    pScreenPriv->CloseScreen = pScreen->CloseScreen;
+    pScreenPriv->GetImage = pScreen->GetImage;
+    pScreenPriv->GetSpans = pScreen->GetSpans;
+    pScreenPriv->SourceValidate = pScreen->SourceValidate;
+
+    pScreenPriv->CopyWindow = pScreen->CopyWindow;
+
+    pScreenPriv->InstallColormap = pScreen->InstallColormap;
+    pScreenPriv->StoreColors = pScreen->StoreColors;
+
+    pScreenPriv->BlockHandler = NULL;
+
+    pScreenPriv->DeviceCursorInitialize = pScreen->DeviceCursorInitialize;
+    pScreenPriv->DeviceCursorCleanup = pScreen->DeviceCursorCleanup;
+
+    pScreenPriv->pInstalledMap = NULL;
+    pScreenPriv->pColormap = NULL;
+    pScreenPriv->colors[SOURCE_COLOR].red = 0;
+    pScreenPriv->colors[SOURCE_COLOR].green = 0;
+    pScreenPriv->colors[SOURCE_COLOR].blue = 0;
+    pScreenPriv->colors[MASK_COLOR].red = 0;
+    pScreenPriv->colors[MASK_COLOR].green = 0;
+    pScreenPriv->colors[MASK_COLOR].blue = 0;
+    pScreenPriv->damageRegistered = 0;
+    pScreenPriv->numberOfCursors = 0;
+
+    dixSetPrivate(&pScreen->devPrivates, miSpriteScreenKey, pScreenPriv);
+
+    pScreen->CloseScreen = miSpriteCloseScreen;
+    pScreen->GetImage = miSpriteGetImage;
+    pScreen->GetSpans = miSpriteGetSpans;
+    pScreen->SourceValidate = miSpriteSourceValidate;
+
+    pScreen->CopyWindow = miSpriteCopyWindow;
+    pScreen->InstallColormap = miSpriteInstallColormap;
+    pScreen->StoreColors = miSpriteStoreColors;
+
+    return TRUE;
+}
+
+/*
+ * Screen wrappers
+ */
+
+/*
+ * CloseScreen wrapper -- unwrap everything, free the private data
+ * and call the wrapped function
+ */
+
+static Bool
+miSpriteCloseScreen (int i, ScreenPtr pScreen)
+{
+    miSpriteScreenPtr   pScreenPriv = GetSpriteScreen(pScreen);
+
+    pScreen->CloseScreen = pScreenPriv->CloseScreen;
+    pScreen->GetImage = pScreenPriv->GetImage;
+    pScreen->GetSpans = pScreenPriv->GetSpans;
+    pScreen->SourceValidate = pScreenPriv->SourceValidate;
+    pScreen->InstallColormap = pScreenPriv->InstallColormap;
+    pScreen->StoreColors = pScreenPriv->StoreColors;
+
+    DamageDestroy (pScreenPriv->pDamage);
+
+    free(pScreenPriv);
+
+    return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+miSpriteGetImage (DrawablePtr pDrawable, int sx, int sy, int w, int h,
+                  unsigned int format, unsigned long planemask,
+                  char *pdstLine)
+{
+    ScreenPtr           pScreen = pDrawable->pScreen;
+    DeviceIntPtr        pDev;
+    miCursorInfoPtr     pCursorInfo;
+    miSpriteScreenPtr   pPriv = GetSpriteScreen(pScreen);
+
+    SCREEN_PROLOGUE (pPriv, pScreen, GetImage);
+
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+        for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+        {
+            if (DevHasCursor(pDev))
+            {
+                 pCursorInfo = MISPRITE(pDev);
+                 if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
+                      ORG_OVERLAP(&pCursorInfo->saved,pDrawable->x,pDrawable->y,
+                                  sx, sy, w, h))
+                 {
+                     SPRITE_DEBUG (("GetImage remove\n"));
+                     miSpriteRemoveCursor (pDev, pScreen);
+                 }
+            }
+        }
+    }
+
+    (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
+			  format, planemask, pdstLine);
+
+    SCREEN_EPILOGUE (pPriv, pScreen, GetImage);
+}
+
+static void
+miSpriteGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
+                  int *pwidth, int nspans, char *pdstStart)
+{
+    ScreenPtr		    pScreen = pDrawable->pScreen;
+    DeviceIntPtr            pDev;
+    miCursorInfoPtr         pCursorInfo;
+    miSpriteScreenPtr       pPriv = GetSpriteScreen(pScreen);
+
+    SCREEN_PROLOGUE (pPriv, pScreen, GetSpans);
+
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+        for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+        {
+            if (DevHasCursor(pDev))
+            {
+                pCursorInfo = MISPRITE(pDev);
+
+                if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
+                {
+                    DDXPointPtr    pts;
+                    int    	       *widths;
+                    int    	       nPts;
+                    int    	       xorg,
+                                   yorg;
+
+                    xorg = pDrawable->x;
+                    yorg = pDrawable->y;
+
+                    for (pts = ppt, widths = pwidth, nPts = nspans;
+                            nPts--;
+                            pts++, widths++)
+                    {
+                        if (SPN_OVERLAP(&pCursorInfo->saved,pts->y+yorg,
+                                    pts->x+xorg,*widths))
+                        {
+                            SPRITE_DEBUG (("GetSpans remove\n"));
+                            miSpriteRemoveCursor (pDev, pScreen);
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+
+    SCREEN_EPILOGUE (pPriv, pScreen, GetSpans);
+}
+
+static void
+miSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width,
+                        int height, unsigned int subWindowMode)
+{
+    ScreenPtr		    pScreen = pDrawable->pScreen;
+    DeviceIntPtr            pDev;
+    miCursorInfoPtr         pCursorInfo;
+    miSpriteScreenPtr       pPriv = GetSpriteScreen(pScreen);
+
+    SCREEN_PROLOGUE (pPriv, pScreen, SourceValidate);
+
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+	{
+	    if (DevHasCursor(pDev))
+	    {
+		pCursorInfo = MISPRITE(pDev);
+		if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
+		    ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y,
+				x, y, width, height))
+		{
+		    SPRITE_DEBUG (("SourceValidate remove\n"));
+		    miSpriteRemoveCursor (pDev, pScreen);
+		}
+	    }
+	}
+    }
+
+    if (pScreen->SourceValidate)
+	(*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode);
+
+    SCREEN_EPILOGUE (pPriv, pScreen, SourceValidate);
+}
+
+static void
+miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+    ScreenPtr	pScreen = pWindow->drawable.pScreen;
+    DeviceIntPtr            pDev;
+    miCursorInfoPtr         pCursorInfo;
+    miSpriteScreenPtr       pPriv = GetSpriteScreen(pScreen);
+
+    SCREEN_PROLOGUE (pPriv, pScreen, CopyWindow);
+
+    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+    {
+        if (DevHasCursor(pDev))
+        {
+            pCursorInfo = MISPRITE(pDev);
+            /*
+             * Damage will take care of destination check
+             */
+            if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen &&
+                    RegionContainsRect(prgnSrc, &pCursorInfo->saved) != rgnOUT)
+            {
+                SPRITE_DEBUG (("CopyWindow remove\n"));
+                miSpriteRemoveCursor (pDev, pScreen);
+            }
+        }
+    }
+
+    (*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+    SCREEN_EPILOGUE (pPriv, pScreen, CopyWindow);
+}
+
+static void
+miSpriteBlockHandler (int i, pointer blockData, pointer pTimeout,
+                      pointer pReadmask)
+{
+    ScreenPtr		pScreen = screenInfo.screens[i];
+    miSpriteScreenPtr	pPriv = GetSpriteScreen(pScreen);
+    DeviceIntPtr            pDev;
+    miCursorInfoPtr         pCursorInfo;
+    Bool                WorkToDo = FALSE;
+
+    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+    {
+        if (DevHasCursor(pDev))
+        {
+            pCursorInfo = MISPRITE(pDev);
+            if (pCursorInfo && !pCursorInfo->isUp
+                    && pCursorInfo->pScreen == pScreen
+                    && pCursorInfo->shouldBeUp)
+            {
+                SPRITE_DEBUG (("BlockHandler save"));
+                miSpriteSaveUnderCursor (pDev, pScreen);
+            }
+        }
+    }
+    for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+    {
+        if (DevHasCursor(pDev))
+        {
+            pCursorInfo = MISPRITE(pDev);
+            if (pCursorInfo && !pCursorInfo->isUp &&
+                    pCursorInfo->pScreen == pScreen &&
+                    pCursorInfo->shouldBeUp)
+            {
+                SPRITE_DEBUG (("BlockHandler restore\n"));
+                miSpriteRestoreCursor (pDev, pScreen);
+                if (!pCursorInfo->isUp)
+                    WorkToDo = TRUE;
+            }
+        }
+    }
+
+    SCREEN_PROLOGUE(pPriv, pScreen, BlockHandler);
+
+    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
+
+    if (WorkToDo)
+        SCREEN_EPILOGUE(pPriv, pScreen, BlockHandler);
+    else
+        pPriv->BlockHandler = NULL;
+}
+
+static void
+miSpriteInstallColormap (ColormapPtr pMap)
+{
+    ScreenPtr		pScreen = pMap->pScreen;
+    miSpriteScreenPtr	pPriv = GetSpriteScreen(pScreen);
+
+    SCREEN_PROLOGUE(pPriv, pScreen, InstallColormap);
+
+    (*pScreen->InstallColormap) (pMap);
+
+    SCREEN_EPILOGUE(pPriv, pScreen, InstallColormap);
+
+    /* InstallColormap can be called before devices are initialized. */
+    pPriv->pInstalledMap = pMap;
+    if (pPriv->pColormap != pMap)
+    {
+        DeviceIntPtr pDev;
+        miCursorInfoPtr     pCursorInfo;
+        for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+        {
+            if (DevHasCursor(pDev))
+            {
+                pCursorInfo = MISPRITE(pDev);
+                pCursorInfo->checkPixels = TRUE;
+                if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
+                    miSpriteRemoveCursor(pDev, pScreen);
+            }
+        }
+
+    }
+}
+
+static void
+miSpriteStoreColors (ColormapPtr pMap, int ndef, xColorItem *pdef)
+{
+    ScreenPtr		pScreen = pMap->pScreen;
+    miSpriteScreenPtr	pPriv = GetSpriteScreen(pScreen);
+    int			i;
+    int			updated;
+    VisualPtr		pVisual;
+    DeviceIntPtr        pDev;
+    miCursorInfoPtr     pCursorInfo;
+
+    SCREEN_PROLOGUE(pPriv, pScreen, StoreColors);
+
+    (*pScreen->StoreColors) (pMap, ndef, pdef);
+
+    SCREEN_EPILOGUE(pPriv, pScreen, StoreColors);
+
+    if (pPriv->pColormap == pMap)
+    {
+        updated = 0;
+        pVisual = pMap->pVisual;
+        if (pVisual->class == DirectColor)
+        {
+            /* Direct color - match on any of the subfields */
+
+#define MaskMatch(a,b,mask) (((a) & (pVisual->mask)) == ((b) & (pVisual->mask)))
+
+#define UpdateDAC(dev, plane,dac,mask) {\
+    if (MaskMatch (dev->colors[plane].pixel,pdef[i].pixel,mask)) {\
+	dev->colors[plane].dac = pdef[i].dac; \
+	updated = 1; \
+    } \
+}
+
+#define CheckDirect(dev, plane) \
+	    UpdateDAC(dev, plane,red,redMask) \
+	    UpdateDAC(dev, plane,green,greenMask) \
+	    UpdateDAC(dev, plane,blue,blueMask)
+
+            for (i = 0; i < ndef; i++)
+            {
+                CheckDirect (pPriv, SOURCE_COLOR)
+                CheckDirect (pPriv, MASK_COLOR)
+            }
+        }
+        else
+        {
+            /* PseudoColor/GrayScale - match on exact pixel */
+            for (i = 0; i < ndef; i++)
+            {
+                if (pdef[i].pixel ==
+                        pPriv->colors[SOURCE_COLOR].pixel)
+                {
+                    pPriv->colors[SOURCE_COLOR] = pdef[i];
+                    if (++updated == 2)
+                        break;
+                }
+                if (pdef[i].pixel ==
+                        pPriv->colors[MASK_COLOR].pixel)
+                {
+                    pPriv->colors[MASK_COLOR] = pdef[i];
+                    if (++updated == 2)
+                        break;
+                }
+            }
+        }
+        if (updated)
+        {
+            for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+            {
+                if (DevHasCursor(pDev))
+                {
+                    pCursorInfo = MISPRITE(pDev);
+                    pCursorInfo->checkPixels = TRUE;
+                    if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen)
+                        miSpriteRemoveCursor (pDev, pScreen);
+                }
+            }
+        }
+    }
+}
+
+static void
+miSpriteFindColors (miCursorInfoPtr pDevCursor, ScreenPtr pScreen)
+{
+    miSpriteScreenPtr	pScreenPriv = GetSpriteScreen(pScreen);
+    CursorPtr		pCursor;
+    xColorItem		*sourceColor, *maskColor;
+
+    pCursor = pDevCursor->pCursor;
+    sourceColor = &pScreenPriv->colors[SOURCE_COLOR];
+    maskColor = &pScreenPriv->colors[MASK_COLOR];
+    if (pScreenPriv->pColormap != pScreenPriv->pInstalledMap ||
+	!(pCursor->foreRed == sourceColor->red &&
+	  pCursor->foreGreen == sourceColor->green &&
+          pCursor->foreBlue == sourceColor->blue &&
+	  pCursor->backRed == maskColor->red &&
+	  pCursor->backGreen == maskColor->green &&
+	  pCursor->backBlue == maskColor->blue))
+    {
+	pScreenPriv->pColormap = pScreenPriv->pInstalledMap;
+	sourceColor->red = pCursor->foreRed;
+	sourceColor->green = pCursor->foreGreen;
+	sourceColor->blue = pCursor->foreBlue;
+	FakeAllocColor (pScreenPriv->pColormap, sourceColor);
+	maskColor->red = pCursor->backRed;
+	maskColor->green = pCursor->backGreen;
+	maskColor->blue = pCursor->backBlue;
+	FakeAllocColor (pScreenPriv->pColormap, maskColor);
+	/* "free" the pixels right away, don't let this confuse you */
+	FakeFreeColor(pScreenPriv->pColormap, sourceColor->pixel);
+	FakeFreeColor(pScreenPriv->pColormap, maskColor->pixel);
+    }
+
+    pDevCursor->checkPixels = FALSE;
+
+}
+
+/*
+ * miPointer interface routines
+ */
+
+#define SPRITE_PAD  8
+
+static Bool
+miSpriteRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+    miCursorInfoPtr pCursorInfo;
+
+    if (IsFloating(pDev))
+        return FALSE;
+
+    pCursorInfo = MISPRITE(pDev);
+
+    if (pCursor == pCursorInfo->pCursor)
+	pCursorInfo->checkPixels = TRUE;
+
+    return miDCRealizeCursor(pScreen, pCursor);
+}
+
+static Bool
+miSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+    return miDCUnrealizeCursor(pScreen, pCursor);
+}
+
+static void
+miSpriteSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
+                   CursorPtr pCursor, int x, int y)
+{
+    miCursorInfoPtr     pPointer;
+    miSpriteScreenPtr   pScreenPriv;
+
+    if (IsFloating(pDev))
+        return;
+
+    pPointer = MISPRITE(pDev);
+    pScreenPriv = GetSpriteScreen(pScreen);
+
+    if (!pCursor)
+    {
+	if (pPointer->shouldBeUp)
+	    --pScreenPriv->numberOfCursors;
+    	pPointer->shouldBeUp = FALSE;
+    	if (pPointer->isUp)
+	    miSpriteRemoveCursor (pDev, pScreen);
+	if (pScreenPriv->numberOfCursors == 0)
+	    miSpriteDisableDamage(pScreen, pScreenPriv);
+	pPointer->pCursor = 0;
+	return;
+    }
+    if (!pPointer->shouldBeUp)
+	pScreenPriv->numberOfCursors++;
+    pPointer->shouldBeUp = TRUE;
+    if (!pPointer->isUp)
+	miSpriteRegisterBlockHandler(pScreen, pScreenPriv);
+    if (pPointer->x == x &&
+	pPointer->y == y &&
+	pPointer->pCursor == pCursor &&
+	!pPointer->checkPixels)
+    {
+	return;
+    }
+    pPointer->x = x;
+    pPointer->y = y;
+    pPointer->pCacheWin = NullWindow;
+    if (pPointer->checkPixels || pPointer->pCursor != pCursor)
+    {
+	pPointer->pCursor = pCursor;
+	miSpriteFindColors (pPointer, pScreen);
+    }
+    if (pPointer->isUp) {
+	/* TODO: reimplement flicker-free MoveCursor */
+	SPRITE_DEBUG (("SetCursor remove %d\n", pDev->id));
+	miSpriteRemoveCursor (pDev, pScreen);
+    }
+
+    if (!pPointer->isUp && pPointer->pCursor)
+    {
+	SPRITE_DEBUG (("SetCursor restore %d\n", pDev->id));
+        miSpriteSaveUnderCursor(pDev, pScreen);
+	miSpriteRestoreCursor (pDev, pScreen);
+    }
+
+}
+
+static void
+miSpriteMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+    CursorPtr pCursor;
+
+    if (IsFloating(pDev))
+        return;
+
+    pCursor = MISPRITE(pDev)->pCursor;
+
+    miSpriteSetCursor (pDev, pScreen, pCursor, x, y);
+}
+
+
+static Bool
+miSpriteDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    int ret = miDCDeviceInitialize(pDev, pScreen);
+
+    if (ret)
+    {
+        miCursorInfoPtr pCursorInfo;
+        pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey);
+        pCursorInfo->pCursor = NULL;
+        pCursorInfo->x = 0;
+        pCursorInfo->y = 0;
+        pCursorInfo->isUp = FALSE;
+        pCursorInfo->shouldBeUp = FALSE;
+        pCursorInfo->pCacheWin = NullWindow;
+        pCursorInfo->isInCacheWin = FALSE;
+        pCursorInfo->checkPixels = TRUE;
+        pCursorInfo->pScreen = FALSE;
+    }
+
+    return ret;
+}
+
+static void
+miSpriteDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    miCursorInfoPtr pCursorInfo = dixLookupPrivate(&pDev->devPrivates, miSpriteDevPrivatesKey);
+
+    if (DevHasCursor(pDev))
+        miDCDeviceCleanup(pDev, pScreen);
+
+    memset(pCursorInfo, 0, sizeof(miCursorInfoRec));
+}
+
+/*
+ * undraw/draw cursor
+ */
+
+static void
+miSpriteRemoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    miSpriteScreenPtr   pScreenPriv;
+    miCursorInfoPtr     pCursorInfo;
+
+
+    if (IsFloating(pDev))
+        return;
+
+    DamageDrawInternal (pScreen, TRUE);
+    pScreenPriv = GetSpriteScreen(pScreen);
+    pCursorInfo = MISPRITE(pDev);
+
+    miSpriteIsDown(pCursorInfo);
+    miSpriteRegisterBlockHandler(pScreen, pScreenPriv);
+    pCursorInfo->pCacheWin = NullWindow;
+    miSpriteDisableDamage(pScreen, pScreenPriv);
+    if (!miDCRestoreUnderCursor(pDev,
+                                pScreen,
+                                pCursorInfo->saved.x1,
+                                pCursorInfo->saved.y1,
+                                pCursorInfo->saved.x2 -
+                                pCursorInfo->saved.x1,
+                                pCursorInfo->saved.y2 -
+                                pCursorInfo->saved.y1))
+    {
+        miSpriteIsUp(pCursorInfo);
+    }
+    miSpriteEnableDamage(pScreen, pScreenPriv);
+    DamageDrawInternal (pScreen, FALSE);
+}
+
+/*
+ * Called from the block handler, saves area under cursor
+ * before waiting for something to do.
+ */
+
+static void
+miSpriteSaveUnderCursor(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    miSpriteScreenPtr   pScreenPriv;
+    int			x, y;
+    CursorPtr		pCursor;
+    miCursorInfoPtr     pCursorInfo;
+
+    if (IsFloating(pDev))
+        return;
+
+    DamageDrawInternal (pScreen, TRUE);
+    pScreenPriv = GetSpriteScreen(pScreen);
+    pCursorInfo = MISPRITE(pDev);
+
+    miSpriteComputeSaved (pDev, pScreen);
+    pCursor = pCursorInfo->pCursor;
+
+    x = pCursorInfo->x - (int)pCursor->bits->xhot;
+    y = pCursorInfo->y - (int)pCursor->bits->yhot;
+    miSpriteDisableDamage(pScreen, pScreenPriv);
+
+    miDCSaveUnderCursor(pDev,
+                        pScreen,
+                        pCursorInfo->saved.x1,
+                        pCursorInfo->saved.y1,
+                        pCursorInfo->saved.x2 -
+                        pCursorInfo->saved.x1,
+                        pCursorInfo->saved.y2 -
+                        pCursorInfo->saved.y1);
+    SPRITE_DEBUG(("SaveUnderCursor %d\n", pDev->id));
+    miSpriteEnableDamage(pScreen, pScreenPriv);
+    DamageDrawInternal (pScreen, FALSE);
+}
+
+
+/*
+ * Called from the block handler, restores the cursor
+ * before waiting for something to do.
+ */
+
+static void
+miSpriteRestoreCursor (DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    miSpriteScreenPtr   pScreenPriv;
+    int			x, y;
+    CursorPtr		pCursor;
+    miCursorInfoPtr     pCursorInfo;
+
+    if (IsFloating(pDev))
+        return;
+
+    DamageDrawInternal (pScreen, TRUE);
+    pScreenPriv = GetSpriteScreen(pScreen);
+    pCursorInfo = MISPRITE(pDev);
+
+    miSpriteComputeSaved (pDev, pScreen);
+    pCursor = pCursorInfo->pCursor;
+
+    x = pCursorInfo->x - (int)pCursor->bits->xhot;
+    y = pCursorInfo->y - (int)pCursor->bits->yhot;
+    miSpriteDisableDamage(pScreen, pScreenPriv);
+    SPRITE_DEBUG(("RestoreCursor %d\n", pDev->id));
+    if (pCursorInfo->checkPixels)
+        miSpriteFindColors (pCursorInfo, pScreen);
+    if (miDCPutUpCursor(pDev, pScreen,
+                pCursor, x, y,
+                pScreenPriv->colors[SOURCE_COLOR].pixel,
+                pScreenPriv->colors[MASK_COLOR].pixel))
+    {
+        miSpriteIsUp(pCursorInfo);
+        pCursorInfo->pScreen = pScreen;
+    }
+    miSpriteEnableDamage(pScreen, pScreenPriv);
+    DamageDrawInternal (pScreen, FALSE);
+}
+
+/*
+ * compute the desired area of the screen to save
+ */
+
+static void
+miSpriteComputeSaved (DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    int		    x, y, w, h;
+    int		    wpad, hpad;
+    CursorPtr	    pCursor;
+    miCursorInfoPtr pCursorInfo;
+
+    if (IsFloating(pDev))
+        return;
+
+    pCursorInfo = MISPRITE(pDev);
+
+    pCursor = pCursorInfo->pCursor;
+    x = pCursorInfo->x - (int)pCursor->bits->xhot;
+    y = pCursorInfo->y - (int)pCursor->bits->yhot;
+    w = pCursor->bits->width;
+    h = pCursor->bits->height;
+    wpad = SPRITE_PAD;
+    hpad = SPRITE_PAD;
+    pCursorInfo->saved.x1 = x - wpad;
+    pCursorInfo->saved.y1 = y - hpad;
+    pCursorInfo->saved.x2 = pCursorInfo->saved.x1 + w + wpad * 2;
+    pCursorInfo->saved.y2 = pCursorInfo->saved.y1 + h + hpad * 2;
+}
+
diff --git a/xorg-server/miext/cw/cw.h b/xorg-server/miext/cw/cw.h
index 555111c67..10d088ad2 100644
--- a/xorg-server/miext/cw/cw.h
+++ b/xorg-server/miext/cw/cw.h
@@ -106,8 +106,6 @@ typedef struct {
 
     TrapezoidsProcPtr		Trapezoids;
     TrianglesProcPtr		Triangles;
-    TriStripProcPtr		TriStrip;
-    TriFanProcPtr		TriFan;
 
     RasterizeTrapezoidProcPtr	RasterizeTrapezoid;
 } cwScreenRec, *cwScreenPtr;
diff --git a/xorg-server/miext/cw/cw_render.c b/xorg-server/miext/cw/cw_render.c
index 260509ce0..25601f3e2 100644
--- a/xorg-server/miext/cw/cw_render.c
+++ b/xorg-server/miext/cw/cw_render.c
@@ -371,66 +371,6 @@ cwTriangles (CARD8	    op,
     cwPsWrap(Triangles, cwTriangles);
 }
 
-static void
-cwTriStrip (CARD8	    op,
-	    PicturePtr	    pSrcPicture,
-	    PicturePtr	    pDstPicture,
-	    PictFormatPtr   maskFormat,
-	    INT16	    xSrc,
-	    INT16	    ySrc,
-	    int		    npoint,
-	    xPointFixed    *points)
-{
-    ScreenPtr	pScreen = pDstPicture->pDrawable->pScreen;
-    cwPsDecl(pScreen);
-    cwSrcPictureDecl;
-    cwDstPictureDecl;
-    int i;
-
-    cwPsUnwrap(TriStrip);
-    if (dst_picture_x_off || dst_picture_y_off) {
-	for (i = 0; i < npoint; i++)
-	{
-	    points[i].x += dst_picture_x_off << 16;
-	    points[i].y += dst_picture_y_off << 16;
-	}
-    }
-    (*ps->TriStrip) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
-		     xSrc + src_picture_x_off, ySrc + src_picture_y_off,
-		     npoint, points);
-    cwPsWrap(TriStrip, cwTriStrip);
-}
-
-static void
-cwTriFan (CARD8		 op,
-	  PicturePtr	 pSrcPicture,
-	  PicturePtr	 pDstPicture,
-	  PictFormatPtr  maskFormat,
-	  INT16		 xSrc,
-	  INT16		 ySrc,
-	  int		 npoint,
-	  xPointFixed   *points)
-{
-    ScreenPtr	pScreen = pDstPicture->pDrawable->pScreen;
-    cwPsDecl(pScreen);
-    cwSrcPictureDecl;
-    cwDstPictureDecl;
-    int i;
-
-    cwPsUnwrap(TriFan);
-    if (dst_picture_x_off || dst_picture_y_off) {
-	for (i = 0; i < npoint; i++)
-	{
-	    points[i].x += dst_picture_x_off << 16;
-	    points[i].y += dst_picture_y_off << 16;
-	}
-    }
-    (*ps->TriFan) (op, pBackingSrcPicture, pBackingDstPicture, maskFormat,
-		   xSrc + src_picture_x_off, ySrc + src_picture_y_off,
-		   npoint, points);
-    cwPsWrap(TriFan, cwTriFan);
-}
-
 void
 cwInitializeRender (ScreenPtr pScreen)
 {
@@ -443,8 +383,6 @@ cwInitializeRender (ScreenPtr pScreen)
     cwPsWrap(CompositeRects, cwCompositeRects);
     cwPsWrap(Trapezoids, cwTrapezoids);
     cwPsWrap(Triangles, cwTriangles);
-    cwPsWrap(TriStrip, cwTriStrip);
-    cwPsWrap(TriFan, cwTriFan);
     /* There is no need to wrap AddTraps as far as we can tell.  AddTraps can
      * only be done on alpha-only pictures, and we won't be getting
      * alpha-only window pictures, so there's no need to translate.
@@ -463,7 +401,5 @@ cwFiniRender (ScreenPtr pScreen)
     cwPsUnwrap(CompositeRects);
     cwPsUnwrap(Trapezoids);
     cwPsUnwrap(Triangles);
-    cwPsUnwrap(TriStrip);
-    cwPsUnwrap(TriFan);
 }
 
diff --git a/xorg-server/os/access.c b/xorg-server/os/access.c
index b7e698c3b..7ba4274ce 100644
--- a/xorg-server/os/access.c
+++ b/xorg-server/os/access.c
@@ -165,17 +165,6 @@ SOFTWARE.
 
 #endif /* WIN32 */
 
-#ifndef PATH_MAX
-#include <sys/param.h>
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 1024
-#endif
-#endif
-#endif 
-
 
 #define X_INCLUDE_NETDB_H
 #include <X11/Xos_r.h>
@@ -185,14 +174,6 @@ SOFTWARE.
 
 #include "xace.h"
 
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 1024
-#endif
-#endif
-
 Bool defeatAccessControl = FALSE;
 
 #define acmp(a1, a2, len) memcmp((char *)(a1), (char *)(a2), len)
diff --git a/xorg-server/os/osinit.c b/xorg-server/os/osinit.c
index 018e4047d..69e4933e6 100644
--- a/xorg-server/os/osinit.c
+++ b/xorg-server/os/osinit.c
@@ -1,315 +1,308 @@
-/***********************************************************
-
-Copyright 1987, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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
-OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-
-Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
-
-                        All Rights Reserved
-
-Permission to use, copy, modify, and distribute this software and its 
-documentation for any purpose and without fee is hereby granted, 
-provided that the above copyright notice appear in all copies and that
-both that copyright notice and this permission notice appear in 
-supporting documentation, and that the name of Digital not be
-used in advertising or publicity pertaining to distribution of the
-software without specific, written prior permission.  
-
-DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
-ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
-DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
-ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
-ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-SOFTWARE.
-
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <X11/X.h>
-#include "os.h"
-#include "osdep.h"
-#include <X11/Xos.h>
-#include <signal.h>
-#include <errno.h>
-#ifdef HAVE_DLFCN_H
-# include <dlfcn.h>
-#endif
-#ifdef HAVE_BACKTRACE
-#include <execinfo.h>
-#endif
-
-
-#include "dixstruct.h"
-
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 1024
-#endif
-#endif
-
-
-#if !defined(SYSV) && !defined(WIN32) 
-#include <sys/resource.h>
-#endif
-
-#ifndef ADMPATH
-#define ADMPATH "/usr/adm/X%smsgs"
-#endif
-
-extern char *display;
-#ifdef RLIMIT_DATA
-int limitDataSpace = -1;
-#endif
-#ifdef RLIMIT_STACK
-int limitStackSpace = -1;
-#endif
-#ifdef RLIMIT_NOFILE
-int limitNoFile = -1;
-#endif
-
-static OsSigWrapperPtr OsSigWrapper = NULL;
-
-OsSigWrapperPtr
-OsRegisterSigWrapper(OsSigWrapperPtr newSigWrapper)
-{
-    OsSigWrapperPtr oldSigWrapper = OsSigWrapper;
-
-    OsSigWrapper = newSigWrapper;
-
-    return oldSigWrapper;
-}
-
-/*
- * OsSigHandler --
- *    Catch unexpected signals and exit or continue cleanly.
- */
-static void
-#ifdef SA_SIGINFO
-OsSigHandler(int signo, siginfo_t *sip, void *unused)
-#else
-OsSigHandler(int signo)
-#endif
-{
-#ifdef RTLD_DI_SETSIGNAL
-  const char *dlerr = dlerror();
-
-  if (dlerr) {
-      LogMessage(X_ERROR, "Dynamic loader error: %s\n", dlerr);
-  }
-#endif /* RTLD_DI_SETSIGNAL */
-
-  if (OsSigWrapper != NULL) {
-      if (OsSigWrapper(signo) == 0) {
-	  /* ddx handled signal and wants us to continue */
-	  return;
-      }
-  }
-
-  /* log, cleanup, and abort */
-  xorg_backtrace();
-
-#ifdef SA_SIGINFO
-  if (sip->si_code == SI_USER) {
-      ErrorF("Recieved signal %d sent by process %ld, uid %ld\n",
-	     signo, (long) sip->si_pid, (long) sip->si_uid);
-  } else {
-      switch (signo) {
-          case SIGSEGV:
-          case SIGBUS:
-          case SIGILL:
-          case SIGFPE:
-	      ErrorF("%s at address %p\n", strsignal(signo), sip->si_addr);
-      }
-  }
-#endif
-
-  FatalError("Caught signal %d (%s). Server aborting\n",
-	     signo, strsignal(signo));
-}
-
-void
-OsInit(void)
-{
-    static Bool been_here = FALSE;
-    static char* devnull = "/dev/null";
-    char fname[PATH_MAX];
-
-    if (!been_here) {
-	struct sigaction act, oact;
-	int i;
-	int siglist[] = { SIGSEGV, SIGQUIT, SIGILL, SIGFPE, SIGBUS,
-			  SIGSYS,
-			  SIGXCPU,
-			  SIGXFSZ,
-#ifdef SIGEMT
-			  SIGEMT,
-#endif
-			  0 /* must be last */ };
-	sigemptyset(&act.sa_mask);
-#ifdef SA_SIGINFO
-	act.sa_sigaction = OsSigHandler;
-	act.sa_flags = SA_SIGINFO;
-#else
-        act.sa_handler = OsSigHandler;
-        act.sa_flags = 0;
-#endif
-	for (i = 0; siglist[i] != 0; i++) {
-	    if (sigaction(siglist[i], &act, &oact)) {
-		ErrorF("failed to install signal handler for signal %d: %s\n",
-		       siglist[i], strerror(errno));
-	    }
-	}
-#ifdef HAVE_BACKTRACE
-	/*
-	 * initialize the backtracer, since the ctor calls dlopen(), which
-	 * calls malloc(), which isn't signal-safe.
-	 */
-	do {
-	    void *array;
-	    backtrace(&array, 1);
-	} while (0);
-#endif
-
-#ifdef RTLD_DI_SETSIGNAL
-	/* Tell runtime linker to send a signal we can catch instead of SIGKILL
-	 * for failures to load libraries/modules at runtime so we can clean up
-	 * after ourselves.
-	 */
-	int failure_signal = SIGQUIT;
-	dlinfo(RTLD_SELF, RTLD_DI_SETSIGNAL, &failure_signal);
-#endif
-
-#if !defined(__CYGWIN__) 
-	fclose(stdin);
-	fclose(stdout);
-#endif
-	/* 
-	 * If a write of zero bytes to stderr returns non-zero, i.e. -1, 
-	 * then writing to stderr failed, and we'll write somewhere else 
-	 * instead. (Apparently this never happens in the Real World.)
-	 */
-	if (write (2, fname, 0) == -1) 
-	{
-	    FILE *err;
-
-	    if (strlen (display) + strlen (ADMPATH) + 1 < sizeof fname)
-		sprintf (fname, ADMPATH, display);
-	    else
-		strcpy (fname, devnull);
-	    /*
-	     * uses stdio to avoid os dependencies here,
-	     * a real os would use
- 	     *  open (fname, O_WRONLY|O_APPEND|O_CREAT, 0666)
-	     */
-	    if (!(err = fopen (fname, "a+")))
-		err = fopen (devnull, "w");
-	    if (err && (fileno(err) != 2)) {
-		dup2 (fileno (err), 2);
-		fclose (err);
-	    }
-#if defined(SYSV) || defined(SVR4) || defined(WIN32) || defined(__CYGWIN__)
-	    {
-	    static char buf[BUFSIZ];
-	    setvbuf (stderr, buf, _IOLBF, BUFSIZ);
-	    }
-#else
-	    setlinebuf(stderr);
-#endif
-	}
-
-	if (getpgrp () == 0)
-	    setpgid (0, 0);
-
-#ifdef RLIMIT_DATA
-	if (limitDataSpace >= 0)
-	{
-	    struct rlimit	rlim;
-
-	    if (!getrlimit(RLIMIT_DATA, &rlim))
-	    {
-		if ((limitDataSpace > 0) && (limitDataSpace < rlim.rlim_max))
-		    rlim.rlim_cur = limitDataSpace;
-		else
-		    rlim.rlim_cur = rlim.rlim_max;
-		(void)setrlimit(RLIMIT_DATA, &rlim);
-	    }
-	}
-#endif
-#ifdef RLIMIT_STACK
-	if (limitStackSpace >= 0)
-	{
-	    struct rlimit	rlim;
-
-	    if (!getrlimit(RLIMIT_STACK, &rlim))
-	    {
-		if ((limitStackSpace > 0) && (limitStackSpace < rlim.rlim_max))
-		    rlim.rlim_cur = limitStackSpace;
-		else
-		    rlim.rlim_cur = rlim.rlim_max;
-		(void)setrlimit(RLIMIT_STACK, &rlim);
-	    }
-	}
-#endif
-#ifdef RLIMIT_NOFILE
-	if (limitNoFile >= 0)
-	{
-	    struct rlimit	rlim;
-
-	    if (!getrlimit(RLIMIT_NOFILE, &rlim))
-	    {
-		if ((limitNoFile > 0) && (limitNoFile < rlim.rlim_max))
-		    rlim.rlim_cur = limitNoFile;
-		else
-		    rlim.rlim_cur = rlim.rlim_max;
-		(void)setrlimit(RLIMIT_NOFILE, &rlim);
-	    }
-	}
-#endif
-	LockServer();
-	been_here = TRUE;
-    }
-    TimerInit();
-    OsVendorInit();
-    /*
-     * No log file by default.  OsVendorInit() should call LogInit() with the
-     * log file name if logging to a file is desired.
-     */
-    LogInit(NULL, NULL);
-    SmartScheduleInit ();
-}
-
-void
-OsCleanup(Bool terminating)
-{
-    if (terminating)
-    {
-	UnlockServer();
-    }
-}
+/***********************************************************
+
+Copyright 1987, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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
+OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include "os.h"
+#include "osdep.h"
+#include <X11/Xos.h>
+#include <signal.h>
+#include <errno.h>
+#ifdef HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+#ifdef HAVE_BACKTRACE
+#include <execinfo.h>
+#endif
+
+#include "misc.h"
+
+#include "dixstruct.h"
+
+
+#if !defined(SYSV) && !defined(WIN32) 
+#include <sys/resource.h>
+#endif
+
+#ifndef ADMPATH
+#define ADMPATH "/usr/adm/X%smsgs"
+#endif
+
+extern char *display;
+#ifdef RLIMIT_DATA
+int limitDataSpace = -1;
+#endif
+#ifdef RLIMIT_STACK
+int limitStackSpace = -1;
+#endif
+#ifdef RLIMIT_NOFILE
+int limitNoFile = -1;
+#endif
+
+static OsSigWrapperPtr OsSigWrapper = NULL;
+
+OsSigWrapperPtr
+OsRegisterSigWrapper(OsSigWrapperPtr newSigWrapper)
+{
+    OsSigWrapperPtr oldSigWrapper = OsSigWrapper;
+
+    OsSigWrapper = newSigWrapper;
+
+    return oldSigWrapper;
+}
+
+/*
+ * OsSigHandler --
+ *    Catch unexpected signals and exit or continue cleanly.
+ */
+static void
+#ifdef SA_SIGINFO
+OsSigHandler(int signo, siginfo_t *sip, void *unused)
+#else
+OsSigHandler(int signo)
+#endif
+{
+#ifdef RTLD_DI_SETSIGNAL
+  const char *dlerr = dlerror();
+
+  if (dlerr) {
+      LogMessage(X_ERROR, "Dynamic loader error: %s\n", dlerr);
+  }
+#endif /* RTLD_DI_SETSIGNAL */
+
+  if (OsSigWrapper != NULL) {
+      if (OsSigWrapper(signo) == 0) {
+	  /* ddx handled signal and wants us to continue */
+	  return;
+      }
+  }
+
+  /* log, cleanup, and abort */
+  xorg_backtrace();
+
+#ifdef SA_SIGINFO
+  if (sip->si_code == SI_USER) {
+      ErrorF("Recieved signal %d sent by process %ld, uid %ld\n",
+	     signo, (long) sip->si_pid, (long) sip->si_uid);
+  } else {
+      switch (signo) {
+          case SIGSEGV:
+          case SIGBUS:
+          case SIGILL:
+          case SIGFPE:
+	      ErrorF("%s at address %p\n", strsignal(signo), sip->si_addr);
+      }
+  }
+#endif
+
+  FatalError("Caught signal %d (%s). Server aborting\n",
+	     signo, strsignal(signo));
+}
+
+void
+OsInit(void)
+{
+    static Bool been_here = FALSE;
+    static char* devnull = "/dev/null";
+    char fname[PATH_MAX];
+
+    if (!been_here) {
+	struct sigaction act, oact;
+	int i;
+	int siglist[] = { SIGSEGV, SIGQUIT, SIGILL, SIGFPE, SIGBUS,
+			  SIGSYS,
+			  SIGXCPU,
+			  SIGXFSZ,
+#ifdef SIGEMT
+			  SIGEMT,
+#endif
+			  0 /* must be last */ };
+	sigemptyset(&act.sa_mask);
+#ifdef SA_SIGINFO
+	act.sa_sigaction = OsSigHandler;
+	act.sa_flags = SA_SIGINFO;
+#else
+        act.sa_handler = OsSigHandler;
+        act.sa_flags = 0;
+#endif
+	for (i = 0; siglist[i] != 0; i++) {
+	    if (sigaction(siglist[i], &act, &oact)) {
+		ErrorF("failed to install signal handler for signal %d: %s\n",
+		       siglist[i], strerror(errno));
+	    }
+	}
+#ifdef HAVE_BACKTRACE
+	/*
+	 * initialize the backtracer, since the ctor calls dlopen(), which
+	 * calls malloc(), which isn't signal-safe.
+	 */
+	do {
+	    void *array;
+	    backtrace(&array, 1);
+	} while (0);
+#endif
+
+#ifdef RTLD_DI_SETSIGNAL
+	/* Tell runtime linker to send a signal we can catch instead of SIGKILL
+	 * for failures to load libraries/modules at runtime so we can clean up
+	 * after ourselves.
+	 */
+	int failure_signal = SIGQUIT;
+	dlinfo(RTLD_SELF, RTLD_DI_SETSIGNAL, &failure_signal);
+#endif
+
+#if !defined(__CYGWIN__) 
+	fclose(stdin);
+	fclose(stdout);
+#endif
+	/* 
+	 * If a write of zero bytes to stderr returns non-zero, i.e. -1, 
+	 * then writing to stderr failed, and we'll write somewhere else 
+	 * instead. (Apparently this never happens in the Real World.)
+	 */
+	if (write (2, fname, 0) == -1) 
+	{
+	    FILE *err;
+
+	    if (strlen (display) + strlen (ADMPATH) + 1 < sizeof fname)
+		sprintf (fname, ADMPATH, display);
+	    else
+		strcpy (fname, devnull);
+	    /*
+	     * uses stdio to avoid os dependencies here,
+	     * a real os would use
+ 	     *  open (fname, O_WRONLY|O_APPEND|O_CREAT, 0666)
+	     */
+	    if (!(err = fopen (fname, "a+")))
+		err = fopen (devnull, "w");
+	    if (err && (fileno(err) != 2)) {
+		dup2 (fileno (err), 2);
+		fclose (err);
+	    }
+#if defined(SYSV) || defined(SVR4) || defined(WIN32) || defined(__CYGWIN__)
+	    {
+	    static char buf[BUFSIZ];
+	    setvbuf (stderr, buf, _IOLBF, BUFSIZ);
+	    }
+#else
+	    setlinebuf(stderr);
+#endif
+	}
+
+	if (getpgrp () == 0)
+	    setpgid (0, 0);
+
+#ifdef RLIMIT_DATA
+	if (limitDataSpace >= 0)
+	{
+	    struct rlimit	rlim;
+
+	    if (!getrlimit(RLIMIT_DATA, &rlim))
+	    {
+		if ((limitDataSpace > 0) && (limitDataSpace < rlim.rlim_max))
+		    rlim.rlim_cur = limitDataSpace;
+		else
+		    rlim.rlim_cur = rlim.rlim_max;
+		(void)setrlimit(RLIMIT_DATA, &rlim);
+	    }
+	}
+#endif
+#ifdef RLIMIT_STACK
+	if (limitStackSpace >= 0)
+	{
+	    struct rlimit	rlim;
+
+	    if (!getrlimit(RLIMIT_STACK, &rlim))
+	    {
+		if ((limitStackSpace > 0) && (limitStackSpace < rlim.rlim_max))
+		    rlim.rlim_cur = limitStackSpace;
+		else
+		    rlim.rlim_cur = rlim.rlim_max;
+		(void)setrlimit(RLIMIT_STACK, &rlim);
+	    }
+	}
+#endif
+#ifdef RLIMIT_NOFILE
+	if (limitNoFile >= 0)
+	{
+	    struct rlimit	rlim;
+
+	    if (!getrlimit(RLIMIT_NOFILE, &rlim))
+	    {
+		if ((limitNoFile > 0) && (limitNoFile < rlim.rlim_max))
+		    rlim.rlim_cur = limitNoFile;
+		else
+		    rlim.rlim_cur = rlim.rlim_max;
+		(void)setrlimit(RLIMIT_NOFILE, &rlim);
+	    }
+	}
+#endif
+	LockServer();
+	been_here = TRUE;
+    }
+    TimerInit();
+    OsVendorInit();
+    /*
+     * No log file by default.  OsVendorInit() should call LogInit() with the
+     * log file name if logging to a file is desired.
+     */
+    LogInit(NULL, NULL);
+    SmartScheduleInit ();
+}
+
+void
+OsCleanup(Bool terminating)
+{
+    if (terminating)
+    {
+	UnlockServer();
+    }
+}
diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c
index eb3ba91bb..30d14460a 100644
--- a/xorg-server/os/utils.c
+++ b/xorg-server/os/utils.c
@@ -231,17 +231,6 @@ OsSignal(int sig, OsSigHandlerPtr handler)
 #define LOCK_PREFIX "/.X"
 #define LOCK_SUFFIX "-lock"
 
-#ifndef PATH_MAX
-#include <sys/param.h>
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 1024
-#endif
-#endif
-#endif
-
 static Bool StillLocking = FALSE;
 static char LockFile[PATH_MAX];
 static Bool nolock = FALSE;
diff --git a/xorg-server/os/xdmcp.c b/xorg-server/os/xdmcp.c
index 3a6a3bb7d..8da2cb05c 100644
--- a/xorg-server/os/xdmcp.c
+++ b/xorg-server/os/xdmcp.c
@@ -486,7 +486,7 @@ XdmcpRegisterConnection (
 	    }
 	}
 #endif
-	if (fromAddr && memcmp(regAddr, fromAddr, regAddrlen) != 0) {
+	if (!fromAddr || memcmp(regAddr, fromAddr, regAddrlen) != 0) {
 	    return;
 	}
     }
diff --git a/xorg-server/randr/randr.c b/xorg-server/randr/randr.c
index 607770520..1551c63b1 100644
--- a/xorg-server/randr/randr.c
+++ b/xorg-server/randr/randr.c
@@ -1,502 +1,504 @@
-/*
- * Copyright © 2000 Compaq Computer Corporation
- * Copyright © 2002 Hewlett-Packard Company
- * Copyright © 2006 Intel Corporation
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- *
- * Author:  Jim Gettys, Hewlett-Packard Company, Inc.
- *	    Keith Packard, Intel Corporation
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "randrstr.h"
-
-/* From render.h */
-#ifndef SubPixelUnknown
-#define SubPixelUnknown 0
-#endif
-
-#define RR_VALIDATE
-static int	RRNScreens;
-
-#define wrap(priv,real,mem,func) {\
-    priv->mem = real->mem; \
-    real->mem = func; \
-}
-
-#define unwrap(priv,real,mem) {\
-    real->mem = priv->mem; \
-}
-
-static int ProcRRDispatch (ClientPtr pClient);
-static int SProcRRDispatch (ClientPtr pClient);
-
-int	RREventBase;
-int	RRErrorBase;
-RESTYPE RRClientType, RREventType; /* resource types for event masks */
-DevPrivateKeyRec RRClientPrivateKeyRec;
-
-DevPrivateKeyRec rrPrivKeyRec;
-
-static void
-RRClientCallback (CallbackListPtr	*list,
-		  pointer		closure,
-		  pointer		data)
-{
-    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
-    ClientPtr		pClient = clientinfo->client;
-    rrClientPriv(pClient);
-    RRTimesPtr		pTimes = (RRTimesPtr) (pRRClient + 1);
-    int			i;
-
-    pRRClient->major_version = 0;
-    pRRClient->minor_version = 0;
-    for (i = 0; i < screenInfo.numScreens; i++)
-    {
-	ScreenPtr   pScreen = screenInfo.screens[i];
-	rrScrPriv(pScreen);
-
-	if (pScrPriv)
-	{
-	    pTimes[i].setTime = pScrPriv->lastSetTime;
-	    pTimes[i].configTime = pScrPriv->lastConfigTime;
-	}
-    }
-}
-
-static Bool
-RRCloseScreen (int i, ScreenPtr pScreen)
-{
-    rrScrPriv(pScreen);
-    int		    j;
-
-    unwrap (pScrPriv, pScreen, CloseScreen);
-    for (j = pScrPriv->numCrtcs - 1; j >= 0; j--)
-	RRCrtcDestroy (pScrPriv->crtcs[j]);
-    for (j = pScrPriv->numOutputs - 1; j >= 0; j--)
-	RROutputDestroy (pScrPriv->outputs[j]);
-    
-    free(pScrPriv->crtcs);
-    free(pScrPriv->outputs);
-    free(pScrPriv);
-    RRNScreens -= 1;	/* ok, one fewer screen with RandR running */
-    return (*pScreen->CloseScreen) (i, pScreen);    
-}
-
-static void
-SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
-			   xRRScreenChangeNotifyEvent *to)
-{
-    to->type = from->type;
-    to->rotation = from->rotation;
-    cpswaps(from->sequenceNumber, to->sequenceNumber);
-    cpswapl(from->timestamp, to->timestamp);
-    cpswapl(from->configTimestamp, to->configTimestamp);
-    cpswapl(from->root, to->root);
-    cpswapl(from->window, to->window);
-    cpswaps(from->sizeID, to->sizeID);
-    cpswaps(from->subpixelOrder, to->subpixelOrder);
-    cpswaps(from->widthInPixels, to->widthInPixels);
-    cpswaps(from->heightInPixels, to->heightInPixels);
-    cpswaps(from->widthInMillimeters, to->widthInMillimeters);
-    cpswaps(from->heightInMillimeters, to->heightInMillimeters);
-}
-
-static void
-SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from,
-			 xRRCrtcChangeNotifyEvent *to)
-{
-    to->type = from->type;
-    to->subCode = from->subCode;
-    cpswaps(from->sequenceNumber, to->sequenceNumber);
-    cpswapl(from->timestamp, to->timestamp);
-    cpswapl(from->window, to->window);
-    cpswapl(from->crtc, to->crtc);
-    cpswapl(from->mode, to->mode);
-    cpswaps(from->rotation, to->rotation);
-    /* pad1 */
-    cpswaps(from->x, to->x);
-    cpswaps(from->y, to->y);
-    cpswaps(from->width, to->width);
-    cpswaps(from->height, to->height);
-}
-
-static void
-SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from,
-			   xRROutputChangeNotifyEvent *to)
-{
-    to->type = from->type;
-    to->subCode = from->subCode;
-    cpswaps(from->sequenceNumber, to->sequenceNumber);
-    cpswapl(from->timestamp, to->timestamp);
-    cpswapl(from->configTimestamp, to->configTimestamp);
-    cpswapl(from->window, to->window);
-    cpswapl(from->output, to->output);
-    cpswapl(from->crtc, to->crtc);
-    cpswapl(from->mode, to->mode);
-    cpswaps(from->rotation, to->rotation);
-    to->connection = from->connection;
-    to->subpixelOrder = from->subpixelOrder;
-}
-
-static void
-SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from,
-			     xRROutputPropertyNotifyEvent *to)
-{
-    to->type = from->type;
-    to->subCode = from->subCode;
-    cpswaps(from->sequenceNumber, to->sequenceNumber);
-    cpswapl(from->window, to->window);
-    cpswapl(from->output, to->output);
-    cpswapl(from->atom, to->atom);
-    cpswapl(from->timestamp, to->timestamp);
-    to->state = from->state;
-    /* pad1 */
-    /* pad2 */
-    /* pad3 */
-    /* pad4 */
-}
-
-static void
-SRRNotifyEvent (xEvent *from,
-		xEvent *to)
-{
-    switch (from->u.u.detail) {
-    case RRNotify_CrtcChange:
-	SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from,
-				  (xRRCrtcChangeNotifyEvent *) to);
-	break;
-    case RRNotify_OutputChange:
-	SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from,
-				    (xRROutputChangeNotifyEvent *) to);
-	break;
-    case RRNotify_OutputProperty:
-	SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from,
-				      (xRROutputPropertyNotifyEvent *) to);
-	break;
-    default:
-	break;
-    }
-}
-
-static int RRGeneration;
-
-Bool RRInit (void)
-{
-    if (RRGeneration != serverGeneration)
-    {
-	if (!RRModeInit ())
-	    return FALSE;
-	if (!RRCrtcInit ())
-	    return FALSE;
-	if (!RROutputInit ())
-	    return FALSE;
-	RRGeneration = serverGeneration;
-    }
-    if (!dixRegisterPrivateKey(&rrPrivKeyRec, PRIVATE_SCREEN, 0))
-	return FALSE;
-
-    return TRUE;
-}
-
-Bool RRScreenInit(ScreenPtr pScreen)
-{
-    rrScrPrivPtr   pScrPriv;
-
-    if (!RRInit ())
-	return FALSE;
-
-    pScrPriv = (rrScrPrivPtr) calloc(1, sizeof (rrScrPrivRec));
-    if (!pScrPriv)
-	return FALSE;
-
-    SetRRScreen(pScreen, pScrPriv);
-
-    /*
-     * Calling function best set these function vectors
-     */
-    pScrPriv->rrGetInfo = 0;
-    pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width;
-    pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height;
-    
-    pScrPriv->width = pScreen->width;
-    pScrPriv->height = pScreen->height;
-    pScrPriv->mmWidth = pScreen->mmWidth;
-    pScrPriv->mmHeight = pScreen->mmHeight;
-#if RANDR_12_INTERFACE
-    pScrPriv->rrScreenSetSize = NULL;
-    pScrPriv->rrCrtcSet = NULL;
-    pScrPriv->rrCrtcSetGamma = NULL;
-#endif
-#if RANDR_10_INTERFACE    
-    pScrPriv->rrSetConfig = 0;
-    pScrPriv->rotations = RR_Rotate_0;
-    pScrPriv->reqWidth = pScreen->width;
-    pScrPriv->reqHeight = pScreen->height;
-    pScrPriv->nSizes = 0;
-    pScrPriv->pSizes = NULL;
-    pScrPriv->rotation = RR_Rotate_0;
-    pScrPriv->rate = 0;
-    pScrPriv->size = 0;
-#endif
-    
-    /*
-     * This value doesn't really matter -- any client must call
-     * GetScreenInfo before reading it which will automatically update
-     * the time
-     */
-    pScrPriv->lastSetTime = currentTime;
-    pScrPriv->lastConfigTime = currentTime;
-    
-    wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
-
-    pScrPriv->numOutputs = 0;
-    pScrPriv->outputs = NULL;
-    pScrPriv->numCrtcs = 0;
-    pScrPriv->crtcs = NULL;
-    
-    RRNScreens += 1;	/* keep count of screens that implement randr */
-    return TRUE;
-}
-
-/*ARGSUSED*/
-static int
-RRFreeClient (pointer data, XID id)
-{
-    RREventPtr   pRREvent;
-    WindowPtr	    pWin;
-    RREventPtr   *pHead, pCur, pPrev;
-
-    pRREvent = (RREventPtr) data;
-    pWin = pRREvent->window;
-    dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id,
-			    RREventType, serverClient, DixDestroyAccess);
-    if (pHead) {
-	pPrev = 0;
-	for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
-	    pPrev = pCur;
-	if (pCur)
-	{
-	    if (pPrev)
-	    	pPrev->next = pRREvent->next;
-	    else
-	    	*pHead = pRREvent->next;
-	}
-    }
-    free((pointer) pRREvent);
-    return 1;
-}
-
-/*ARGSUSED*/
-static int
-RRFreeEvents (pointer data, XID id)
-{
-    RREventPtr   *pHead, pCur, pNext;
-
-    pHead = (RREventPtr *) data;
-    for (pCur = *pHead; pCur; pCur = pNext) {
-	pNext = pCur->next;
-	FreeResource (pCur->clientResource, RRClientType);
-	free((pointer) pCur);
-    }
-    free((pointer) pHead);
-    return 1;
-}
-
-void
-RRExtensionInit (void)
-{
-    ExtensionEntry *extEntry;
-
-    if (RRNScreens == 0) return;
-
-    if (!dixRegisterPrivateKey(&RRClientPrivateKeyRec, PRIVATE_CLIENT,
-			       sizeof (RRClientRec) +
-			       screenInfo.numScreens * sizeof (RRTimesRec)))
-	return;
-    if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
-	return;
-
-    RRClientType = CreateNewResourceType(RRFreeClient, "RandRClient");
-    if (!RRClientType)
-	return;
-    RREventType = CreateNewResourceType(RRFreeEvents, "RandREvent");
-    if (!RREventType)
-	return;
-    extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
-			     ProcRRDispatch, SProcRRDispatch,
-			     NULL, StandardMinorOpcode);
-    if (!extEntry)
-	return;
-    RRErrorBase = extEntry->errorBase;
-    RREventBase = extEntry->eventBase;
-    EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) 
-	SRRScreenChangeNotifyEvent;
-    EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr)
-	SRRNotifyEvent;
-
-    RRModeInitErrorValue();
-    RRCrtcInitErrorValue();
-    RROutputInitErrorValue();
-
-#ifdef PANORAMIX
-    RRXineramaExtensionInit();
-#endif
-}
-
-static int
-TellChanged (WindowPtr pWin, pointer value)
-{
-    RREventPtr			*pHead, pRREvent;
-    ClientPtr			client;
-    ScreenPtr			pScreen = pWin->drawable.pScreen;
-    rrScrPriv(pScreen);
-    int				i;
-
-    dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id,
-			    RREventType, serverClient, DixReadAccess);
-    if (!pHead)
-	return WT_WALKCHILDREN;
-
-    for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) 
-    {
-	client = pRREvent->client;
-	if (client == serverClient || client->clientGone)
-	    continue;
-
-	if (pRREvent->mask & RRScreenChangeNotifyMask)
-	    RRDeliverScreenEvent (client, pWin, pScreen);
-	
-	if (pRREvent->mask & RRCrtcChangeNotifyMask)
-	{
-	    for (i = 0; i < pScrPriv->numCrtcs; i++)
-	    {
-		RRCrtcPtr   crtc = pScrPriv->crtcs[i];
-		if (crtc->changed)
-		    RRDeliverCrtcEvent (client, pWin, crtc);
-	    }
-	}
-	
-	if (pRREvent->mask & RROutputChangeNotifyMask)
-	{
-	    for (i = 0; i < pScrPriv->numOutputs; i++)
-	    {
-		RROutputPtr   output = pScrPriv->outputs[i];
-		if (output->changed)
-		    RRDeliverOutputEvent (client, pWin, output);
-	    }
-	}
-    }
-    return WT_WALKCHILDREN;
-}
-
-/*
- * Something changed; send events and adjust pointer position
- */
-void
-RRTellChanged (ScreenPtr pScreen)
-{
-    rrScrPriv (pScreen);
-    int i;
-    
-    if (pScrPriv->changed)
-    {
-	UpdateCurrentTime ();
-	if (pScrPriv->configChanged)
-	{
-	    pScrPriv->lastConfigTime = currentTime;
-	    pScrPriv->configChanged = FALSE;
-	}
-	pScrPriv->changed = FALSE;
-	WalkTree (pScreen, TellChanged, (pointer) pScreen);
-	for (i = 0; i < pScrPriv->numOutputs; i++)
-	    pScrPriv->outputs[i]->changed = FALSE;
-	for (i = 0; i < pScrPriv->numCrtcs; i++)
-	    pScrPriv->crtcs[i]->changed = FALSE;
-	if (pScrPriv->layoutChanged)
-	{
-	    pScrPriv->layoutChanged = FALSE;
-	    RRPointerScreenConfigured (pScreen);
-	    RRSendConfigNotify (pScreen);
-	}
-    }
-}
-
-/*
- * Return the first output which is connected to an active CRTC
- * Used in emulating 1.0 behaviour
- */
-RROutputPtr
-RRFirstOutput (ScreenPtr pScreen)
-{
-    rrScrPriv(pScreen);
-    RROutputPtr		    output;
-    int	i, j;
-    
-    if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc)
-	return pScrPriv->primaryOutput;
-
-    for (i = 0; i < pScrPriv->numCrtcs; i++)
-    {
-	RRCrtcPtr   crtc = pScrPriv->crtcs[i];
-	for (j = 0; j < pScrPriv->numOutputs; j++)
-	{
-	    output = pScrPriv->outputs[j];
-	    if (output->crtc == crtc)
-		return output;
-	}
-    }
-    return NULL;
-}
-
-CARD16
-RRVerticalRefresh (xRRModeInfo *mode)
-{
-    CARD32  refresh;
-    CARD32  dots = mode->hTotal * mode->vTotal;
-    if (!dots)
-	return 0;
-    refresh = (mode->dotClock + dots/2) / dots;
-    if (refresh > 0xffff)
-	refresh = 0xffff;
-    return (CARD16) refresh;
-}
-
-static int
-ProcRRDispatch (ClientPtr client)
-{
-    REQUEST(xReq);
-    if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
-	return BadRequest;
-    return (*ProcRandrVector[stuff->data]) (client);
-}
-
-static int
-SProcRRDispatch (ClientPtr client)
-{
-    REQUEST(xReq);
-    if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
-	return BadRequest;
-    return (*SProcRandrVector[stuff->data]) (client);
-}
-
+/*
+ * Copyright © 2000 Compaq Computer Corporation
+ * Copyright © 2002 Hewlett-Packard Company
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author:  Jim Gettys, Hewlett-Packard Company, Inc.
+ *	    Keith Packard, Intel Corporation
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "randrstr.h"
+
+/* From render.h */
+#ifndef SubPixelUnknown
+#define SubPixelUnknown 0
+#endif
+
+#define RR_VALIDATE
+static int	RRNScreens;
+
+#define wrap(priv,real,mem,func) {\
+    priv->mem = real->mem; \
+    real->mem = func; \
+}
+
+#define unwrap(priv,real,mem) {\
+    real->mem = priv->mem; \
+}
+
+static int ProcRRDispatch (ClientPtr pClient);
+static int SProcRRDispatch (ClientPtr pClient);
+
+int	RREventBase;
+int	RRErrorBase;
+RESTYPE RRClientType, RREventType; /* resource types for event masks */
+DevPrivateKeyRec RRClientPrivateKeyRec;
+
+DevPrivateKeyRec rrPrivKeyRec;
+
+static void
+RRClientCallback (CallbackListPtr	*list,
+		  pointer		closure,
+		  pointer		data)
+{
+    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
+    ClientPtr		pClient = clientinfo->client;
+    rrClientPriv(pClient);
+    RRTimesPtr		pTimes = (RRTimesPtr) (pRRClient + 1);
+    int			i;
+
+    pRRClient->major_version = 0;
+    pRRClient->minor_version = 0;
+    for (i = 0; i < screenInfo.numScreens; i++)
+    {
+	ScreenPtr   pScreen = screenInfo.screens[i];
+	rrScrPriv(pScreen);
+
+	if (pScrPriv)
+	{
+	    pTimes[i].setTime = pScrPriv->lastSetTime;
+	    pTimes[i].configTime = pScrPriv->lastConfigTime;
+	}
+    }
+}
+
+static Bool
+RRCloseScreen (int i, ScreenPtr pScreen)
+{
+    rrScrPriv(pScreen);
+    int		    j;
+
+    unwrap (pScrPriv, pScreen, CloseScreen);
+    for (j = pScrPriv->numCrtcs - 1; j >= 0; j--)
+	RRCrtcDestroy (pScrPriv->crtcs[j]);
+    for (j = pScrPriv->numOutputs - 1; j >= 0; j--)
+	RROutputDestroy (pScrPriv->outputs[j]);
+    
+    free(pScrPriv->crtcs);
+    free(pScrPriv->outputs);
+    free(pScrPriv);
+    RRNScreens -= 1;	/* ok, one fewer screen with RandR running */
+    return (*pScreen->CloseScreen) (i, pScreen);    
+}
+
+static void
+SRRScreenChangeNotifyEvent(xRRScreenChangeNotifyEvent *from,
+			   xRRScreenChangeNotifyEvent *to)
+{
+    to->type = from->type;
+    to->rotation = from->rotation;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->timestamp, to->timestamp);
+    cpswapl(from->configTimestamp, to->configTimestamp);
+    cpswapl(from->root, to->root);
+    cpswapl(from->window, to->window);
+    cpswaps(from->sizeID, to->sizeID);
+    cpswaps(from->subpixelOrder, to->subpixelOrder);
+    cpswaps(from->widthInPixels, to->widthInPixels);
+    cpswaps(from->heightInPixels, to->heightInPixels);
+    cpswaps(from->widthInMillimeters, to->widthInMillimeters);
+    cpswaps(from->heightInMillimeters, to->heightInMillimeters);
+}
+
+static void
+SRRCrtcChangeNotifyEvent(xRRCrtcChangeNotifyEvent *from,
+			 xRRCrtcChangeNotifyEvent *to)
+{
+    to->type = from->type;
+    to->subCode = from->subCode;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->timestamp, to->timestamp);
+    cpswapl(from->window, to->window);
+    cpswapl(from->crtc, to->crtc);
+    cpswapl(from->mode, to->mode);
+    cpswaps(from->rotation, to->rotation);
+    /* pad1 */
+    cpswaps(from->x, to->x);
+    cpswaps(from->y, to->y);
+    cpswaps(from->width, to->width);
+    cpswaps(from->height, to->height);
+}
+
+static void
+SRROutputChangeNotifyEvent(xRROutputChangeNotifyEvent *from,
+			   xRROutputChangeNotifyEvent *to)
+{
+    to->type = from->type;
+    to->subCode = from->subCode;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->timestamp, to->timestamp);
+    cpswapl(from->configTimestamp, to->configTimestamp);
+    cpswapl(from->window, to->window);
+    cpswapl(from->output, to->output);
+    cpswapl(from->crtc, to->crtc);
+    cpswapl(from->mode, to->mode);
+    cpswaps(from->rotation, to->rotation);
+    to->connection = from->connection;
+    to->subpixelOrder = from->subpixelOrder;
+}
+
+static void
+SRROutputPropertyNotifyEvent(xRROutputPropertyNotifyEvent *from,
+			     xRROutputPropertyNotifyEvent *to)
+{
+    to->type = from->type;
+    to->subCode = from->subCode;
+    cpswaps(from->sequenceNumber, to->sequenceNumber);
+    cpswapl(from->window, to->window);
+    cpswapl(from->output, to->output);
+    cpswapl(from->atom, to->atom);
+    cpswapl(from->timestamp, to->timestamp);
+    to->state = from->state;
+    /* pad1 */
+    /* pad2 */
+    /* pad3 */
+    /* pad4 */
+}
+
+static void
+SRRNotifyEvent (xEvent *from,
+		xEvent *to)
+{
+    switch (from->u.u.detail) {
+    case RRNotify_CrtcChange:
+	SRRCrtcChangeNotifyEvent ((xRRCrtcChangeNotifyEvent *) from,
+				  (xRRCrtcChangeNotifyEvent *) to);
+	break;
+    case RRNotify_OutputChange:
+	SRROutputChangeNotifyEvent ((xRROutputChangeNotifyEvent *) from,
+				    (xRROutputChangeNotifyEvent *) to);
+	break;
+    case RRNotify_OutputProperty:
+	SRROutputPropertyNotifyEvent ((xRROutputPropertyNotifyEvent *) from,
+				      (xRROutputPropertyNotifyEvent *) to);
+	break;
+    default:
+	break;
+    }
+}
+
+static int RRGeneration;
+
+Bool RRInit (void)
+{
+    if (RRGeneration != serverGeneration)
+    {
+	if (!RRModeInit ())
+	    return FALSE;
+	if (!RRCrtcInit ())
+	    return FALSE;
+	if (!RROutputInit ())
+	    return FALSE;
+	RRGeneration = serverGeneration;
+    }
+    if (!dixRegisterPrivateKey(&rrPrivKeyRec, PRIVATE_SCREEN, 0))
+	return FALSE;
+
+    return TRUE;
+}
+
+Bool RRScreenInit(ScreenPtr pScreen)
+{
+    rrScrPrivPtr   pScrPriv;
+
+    if (!RRInit ())
+	return FALSE;
+
+    pScrPriv = (rrScrPrivPtr) calloc(1, sizeof (rrScrPrivRec));
+    if (!pScrPriv)
+	return FALSE;
+
+    SetRRScreen(pScreen, pScrPriv);
+
+    /*
+     * Calling function best set these function vectors
+     */
+    pScrPriv->rrGetInfo = 0;
+    pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width;
+    pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height;
+    
+    pScrPriv->width = pScreen->width;
+    pScrPriv->height = pScreen->height;
+    pScrPriv->mmWidth = pScreen->mmWidth;
+    pScrPriv->mmHeight = pScreen->mmHeight;
+#if RANDR_12_INTERFACE
+    pScrPriv->rrScreenSetSize = NULL;
+    pScrPriv->rrCrtcSet = NULL;
+    pScrPriv->rrCrtcSetGamma = NULL;
+#endif
+#if RANDR_10_INTERFACE    
+    pScrPriv->rrSetConfig = 0;
+    pScrPriv->rotations = RR_Rotate_0;
+    pScrPriv->reqWidth = pScreen->width;
+    pScrPriv->reqHeight = pScreen->height;
+    pScrPriv->nSizes = 0;
+    pScrPriv->pSizes = NULL;
+    pScrPriv->rotation = RR_Rotate_0;
+    pScrPriv->rate = 0;
+    pScrPriv->size = 0;
+#endif
+    
+    /*
+     * This value doesn't really matter -- any client must call
+     * GetScreenInfo before reading it which will automatically update
+     * the time
+     */
+    pScrPriv->lastSetTime = currentTime;
+    pScrPriv->lastConfigTime = currentTime;
+    
+    wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
+
+    pScreen->ConstrainCursorHarder = RRConstrainCursorHarder;
+
+    pScrPriv->numOutputs = 0;
+    pScrPriv->outputs = NULL;
+    pScrPriv->numCrtcs = 0;
+    pScrPriv->crtcs = NULL;
+    
+    RRNScreens += 1;	/* keep count of screens that implement randr */
+    return TRUE;
+}
+
+/*ARGSUSED*/
+static int
+RRFreeClient (pointer data, XID id)
+{
+    RREventPtr   pRREvent;
+    WindowPtr	    pWin;
+    RREventPtr   *pHead, pCur, pPrev;
+
+    pRREvent = (RREventPtr) data;
+    pWin = pRREvent->window;
+    dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id,
+			    RREventType, serverClient, DixDestroyAccess);
+    if (pHead) {
+	pPrev = 0;
+	for (pCur = *pHead; pCur && pCur != pRREvent; pCur=pCur->next)
+	    pPrev = pCur;
+	if (pCur)
+	{
+	    if (pPrev)
+	    	pPrev->next = pRREvent->next;
+	    else
+	    	*pHead = pRREvent->next;
+	}
+    }
+    free((pointer) pRREvent);
+    return 1;
+}
+
+/*ARGSUSED*/
+static int
+RRFreeEvents (pointer data, XID id)
+{
+    RREventPtr   *pHead, pCur, pNext;
+
+    pHead = (RREventPtr *) data;
+    for (pCur = *pHead; pCur; pCur = pNext) {
+	pNext = pCur->next;
+	FreeResource (pCur->clientResource, RRClientType);
+	free((pointer) pCur);
+    }
+    free((pointer) pHead);
+    return 1;
+}
+
+void
+RRExtensionInit (void)
+{
+    ExtensionEntry *extEntry;
+
+    if (RRNScreens == 0) return;
+
+    if (!dixRegisterPrivateKey(&RRClientPrivateKeyRec, PRIVATE_CLIENT,
+			       sizeof (RRClientRec) +
+			       screenInfo.numScreens * sizeof (RRTimesRec)))
+	return;
+    if (!AddCallback (&ClientStateCallback, RRClientCallback, 0))
+	return;
+
+    RRClientType = CreateNewResourceType(RRFreeClient, "RandRClient");
+    if (!RRClientType)
+	return;
+    RREventType = CreateNewResourceType(RRFreeEvents, "RandREvent");
+    if (!RREventType)
+	return;
+    extEntry = AddExtension (RANDR_NAME, RRNumberEvents, RRNumberErrors,
+			     ProcRRDispatch, SProcRRDispatch,
+			     NULL, StandardMinorOpcode);
+    if (!extEntry)
+	return;
+    RRErrorBase = extEntry->errorBase;
+    RREventBase = extEntry->eventBase;
+    EventSwapVector[RREventBase + RRScreenChangeNotify] = (EventSwapPtr) 
+	SRRScreenChangeNotifyEvent;
+    EventSwapVector[RREventBase + RRNotify] = (EventSwapPtr)
+	SRRNotifyEvent;
+
+    RRModeInitErrorValue();
+    RRCrtcInitErrorValue();
+    RROutputInitErrorValue();
+
+#ifdef PANORAMIX
+    RRXineramaExtensionInit();
+#endif
+}
+
+static int
+TellChanged (WindowPtr pWin, pointer value)
+{
+    RREventPtr			*pHead, pRREvent;
+    ClientPtr			client;
+    ScreenPtr			pScreen = pWin->drawable.pScreen;
+    rrScrPriv(pScreen);
+    int				i;
+
+    dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id,
+			    RREventType, serverClient, DixReadAccess);
+    if (!pHead)
+	return WT_WALKCHILDREN;
+
+    for (pRREvent = *pHead; pRREvent; pRREvent = pRREvent->next) 
+    {
+	client = pRREvent->client;
+	if (client == serverClient || client->clientGone)
+	    continue;
+
+	if (pRREvent->mask & RRScreenChangeNotifyMask)
+	    RRDeliverScreenEvent (client, pWin, pScreen);
+	
+	if (pRREvent->mask & RRCrtcChangeNotifyMask)
+	{
+	    for (i = 0; i < pScrPriv->numCrtcs; i++)
+	    {
+		RRCrtcPtr   crtc = pScrPriv->crtcs[i];
+		if (crtc->changed)
+		    RRDeliverCrtcEvent (client, pWin, crtc);
+	    }
+	}
+	
+	if (pRREvent->mask & RROutputChangeNotifyMask)
+	{
+	    for (i = 0; i < pScrPriv->numOutputs; i++)
+	    {
+		RROutputPtr   output = pScrPriv->outputs[i];
+		if (output->changed)
+		    RRDeliverOutputEvent (client, pWin, output);
+	    }
+	}
+    }
+    return WT_WALKCHILDREN;
+}
+
+/*
+ * Something changed; send events and adjust pointer position
+ */
+void
+RRTellChanged (ScreenPtr pScreen)
+{
+    rrScrPriv (pScreen);
+    int i;
+    
+    if (pScrPriv->changed)
+    {
+	UpdateCurrentTime ();
+	if (pScrPriv->configChanged)
+	{
+	    pScrPriv->lastConfigTime = currentTime;
+	    pScrPriv->configChanged = FALSE;
+	}
+	pScrPriv->changed = FALSE;
+	WalkTree (pScreen, TellChanged, (pointer) pScreen);
+	for (i = 0; i < pScrPriv->numOutputs; i++)
+	    pScrPriv->outputs[i]->changed = FALSE;
+	for (i = 0; i < pScrPriv->numCrtcs; i++)
+	    pScrPriv->crtcs[i]->changed = FALSE;
+	if (pScrPriv->layoutChanged)
+	{
+	    pScrPriv->layoutChanged = FALSE;
+	    RRPointerScreenConfigured (pScreen);
+	    RRSendConfigNotify (pScreen);
+	}
+    }
+}
+
+/*
+ * Return the first output which is connected to an active CRTC
+ * Used in emulating 1.0 behaviour
+ */
+RROutputPtr
+RRFirstOutput (ScreenPtr pScreen)
+{
+    rrScrPriv(pScreen);
+    RROutputPtr		    output;
+    int	i, j;
+    
+    if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc)
+	return pScrPriv->primaryOutput;
+
+    for (i = 0; i < pScrPriv->numCrtcs; i++)
+    {
+	RRCrtcPtr   crtc = pScrPriv->crtcs[i];
+	for (j = 0; j < pScrPriv->numOutputs; j++)
+	{
+	    output = pScrPriv->outputs[j];
+	    if (output->crtc == crtc)
+		return output;
+	}
+    }
+    return NULL;
+}
+
+CARD16
+RRVerticalRefresh (xRRModeInfo *mode)
+{
+    CARD32  refresh;
+    CARD32  dots = mode->hTotal * mode->vTotal;
+    if (!dots)
+	return 0;
+    refresh = (mode->dotClock + dots/2) / dots;
+    if (refresh > 0xffff)
+	refresh = 0xffff;
+    return (CARD16) refresh;
+}
+
+static int
+ProcRRDispatch (ClientPtr client)
+{
+    REQUEST(xReq);
+    if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
+	return BadRequest;
+    return (*ProcRandrVector[stuff->data]) (client);
+}
+
+static int
+SProcRRDispatch (ClientPtr client)
+{
+    REQUEST(xReq);
+    if (stuff->data >= RRNumberRequests || !ProcRandrVector[stuff->data])
+	return BadRequest;
+    return (*SProcRandrVector[stuff->data]) (client);
+}
+
diff --git a/xorg-server/randr/randrstr.h b/xorg-server/randr/randrstr.h
index 7ea608003..262a16420 100644
--- a/xorg-server/randr/randrstr.h
+++ b/xorg-server/randr/randrstr.h
@@ -1,970 +1,974 @@
-/*
- * Copyright © 2000 Compaq Computer Corporation
- * Copyright © 2002 Hewlett-Packard Company
- * Copyright © 2006 Intel Corporation
- * Copyright © 2008 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- *
- * Author:  Jim Gettys, Hewlett-Packard Company, Inc.
- *	    Keith Packard, Intel Corporation
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifndef _RANDRSTR_H_
-#define _RANDRSTR_H_
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "os.h"
-#include "dixstruct.h"
-#include "resource.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "extnsionst.h"
-#include "servermd.h"
-#include "rrtransform.h"
-#include <X11/extensions/randr.h>
-#include <X11/extensions/randrproto.h>
-#include <X11/extensions/render.h> 	/* we share subpixel order information */
-#include "picturestr.h"
-#include <X11/Xfuncproto.h>
-
-/* required for ABI compatibility for now */
-#define RANDR_10_INTERFACE 1
-#define RANDR_12_INTERFACE 1
-#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
-#define RANDR_GET_CRTC_INTERFACE 1
-
-#define RANDR_INTERFACE_VERSION 0x0103
-
-typedef XID	RRMode;
-typedef XID	RROutput;
-typedef XID	RRCrtc;
-
-extern _X_EXPORT int	RREventBase, RRErrorBase;
-
-extern _X_EXPORT int (*ProcRandrVector[RRNumberRequests])(ClientPtr);
-extern _X_EXPORT int (*SProcRandrVector[RRNumberRequests])(ClientPtr);
-    
-/*
- * Modeline for a monitor. Name follows directly after this struct
- */
-
-#define RRModeName(pMode) ((char *) (pMode + 1))
-typedef struct _rrMode		RRModeRec, *RRModePtr;
-typedef struct _rrPropertyValue	RRPropertyValueRec, *RRPropertyValuePtr;
-typedef struct _rrProperty	RRPropertyRec, *RRPropertyPtr;
-typedef struct _rrCrtc		RRCrtcRec, *RRCrtcPtr;
-typedef struct _rrOutput	RROutputRec, *RROutputPtr;
-
-struct _rrMode {
-    int		    refcnt;
-    xRRModeInfo	    mode;
-    char	    *name;
-    ScreenPtr	    userScreen;
-};
-
-struct _rrPropertyValue {
-    Atom	    type;       /* ignored by server */
-    short	    format;     /* format of data for swapping - 8,16,32 */
-    long	    size;	/* size of data in (format/8) bytes */
-    pointer         data;	/* private to client */
-};
-
-struct _rrProperty {
-    RRPropertyPtr   next;
-    ATOM 	    propertyName;
-    Bool	    is_pending;
-    Bool	    range;
-    Bool	    immutable;
-    int		    num_valid;
-    INT32	    *valid_values;
-    RRPropertyValueRec	current, pending;
-};
-
-struct _rrCrtc {
-    RRCrtc	    id;
-    ScreenPtr	    pScreen;
-    RRModePtr	    mode;
-    int		    x, y;
-    Rotation	    rotation;
-    Rotation	    rotations;
-    Bool	    changed;
-    int		    numOutputs;
-    RROutputPtr	    *outputs;
-    int		    gammaSize;
-    CARD16	    *gammaRed;
-    CARD16	    *gammaBlue;
-    CARD16	    *gammaGreen;
-    void	    *devPrivate;
-    Bool	    transforms;
-    RRTransformRec  client_pending_transform;
-    RRTransformRec  client_current_transform;
-    PictTransform   transform;
-    struct pict_f_transform f_transform;
-    struct pict_f_transform f_inverse;
-};
-
-struct _rrOutput {
-    RROutput	    id;
-    ScreenPtr	    pScreen;
-    char	    *name;
-    int		    nameLength;
-    CARD8	    connection;
-    CARD8	    subpixelOrder;
-    int		    mmWidth;
-    int		    mmHeight;
-    RRCrtcPtr	    crtc;
-    int		    numCrtcs;
-    RRCrtcPtr	    *crtcs;
-    int		    numClones;
-    RROutputPtr	    *clones;
-    int		    numModes;
-    int		    numPreferred;
-    RRModePtr	    *modes;
-    int		    numUserModes;
-    RRModePtr	    *userModes;
-    Bool	    changed;
-    RRPropertyPtr   properties;
-    Bool	    pendingProperties;
-    void	    *devPrivate;
-};
-
-#if RANDR_12_INTERFACE
-typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr	pScreen,
-					CARD16		width,
-					CARD16		height,
-					CARD32		mmWidth,
-					CARD32		mmHeight);
-					
-typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr		pScreen,
-				  RRCrtcPtr		crtc,
-				  RRModePtr		mode,
-				  int			x,
-				  int			y,
-				  Rotation		rotation,
-				  int			numOutputs,
-				  RROutputPtr		*outputs);
-
-typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr	pScreen,
-				       RRCrtcPtr	crtc);
-
-typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr	pScreen,
-				       RRCrtcPtr	crtc);
-
-typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr		pScreen,
-					    RROutputPtr		output,
-					    Atom		property,
-					    RRPropertyValuePtr	value);
-
-typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr		pScreen,
-					     RROutputPtr	output,
-					     RRModePtr		mode);
-
-typedef void (*RRModeDestroyProcPtr) (ScreenPtr	    pScreen,
-				      RRModePtr	    mode);
-
-#endif
-
-#if RANDR_13_INTERFACE
-typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr		pScreen,
-					    RROutputPtr		output,
-					    Atom		property);
-typedef Bool (*RRGetPanningProcPtr)    (ScreenPtr		pScrn,
-					RRCrtcPtr		crtc,
-					BoxPtr		totalArea,
-					BoxPtr		trackingArea,
-					INT16		*border);
-typedef Bool (*RRSetPanningProcPtr)    (ScreenPtr		pScrn,
-					RRCrtcPtr		crtc,
-					BoxPtr		totalArea,
-					BoxPtr		trackingArea,
-					INT16		*border);
-
-#endif /* RANDR_13_INTERFACE */
-
-typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
-typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen);
-
-/* These are for 1.0 compatibility */
- 
-typedef struct _rrRefresh {
-    CARD16	    rate;
-    RRModePtr	    mode;
-} RRScreenRate, *RRScreenRatePtr;
-
-typedef struct _rrScreenSize {
-    int		    id;
-    short	    width, height;
-    short	    mmWidth, mmHeight;
-    int		    nRates;
-    RRScreenRatePtr pRates;
-} RRScreenSize, *RRScreenSizePtr;
-
-#ifdef RANDR_10_INTERFACE
-
-typedef Bool (*RRSetConfigProcPtr) (ScreenPtr		pScreen,
-				    Rotation		rotation,
-				    int			rate,
-				    RRScreenSizePtr	pSize);
-
-#endif
-	
-
-typedef struct _rrScrPriv {
-    /*
-     * 'public' part of the structure; DDXen fill this in
-     * as they initialize
-     */
-#if RANDR_10_INTERFACE
-    RRSetConfigProcPtr	    rrSetConfig;
-#endif
-    RRGetInfoProcPtr	    rrGetInfo;
-#if RANDR_12_INTERFACE
-    RRScreenSetSizeProcPtr  rrScreenSetSize;
-    RRCrtcSetProcPtr	    rrCrtcSet;
-    RRCrtcSetGammaProcPtr   rrCrtcSetGamma;
-    RRCrtcGetGammaProcPtr   rrCrtcGetGamma;
-    RROutputSetPropertyProcPtr	rrOutputSetProperty;
-    RROutputValidateModeProcPtr	rrOutputValidateMode;
-    RRModeDestroyProcPtr	rrModeDestroy;
-#endif
-#if RANDR_13_INTERFACE
-    RROutputGetPropertyProcPtr	rrOutputGetProperty;
-    RRGetPanningProcPtr	rrGetPanning;
-    RRSetPanningProcPtr	rrSetPanning;
-#endif
-    
-    /*
-     * Private part of the structure; not considered part of the ABI
-     */
-    TimeStamp		    lastSetTime;	/* last changed by client */
-    TimeStamp		    lastConfigTime;	/* possible configs changed */
-    RRCloseScreenProcPtr    CloseScreen;
-
-    Bool		    changed;		/* some config changed */
-    Bool		    configChanged;	/* configuration changed */
-    Bool		    layoutChanged;	/* screen layout changed */
-
-    CARD16		    minWidth, minHeight;
-    CARD16		    maxWidth, maxHeight;
-    CARD16		    width, height;	/* last known screen size */
-    CARD16		    mmWidth, mmHeight;	/* last known screen size */
-
-    int			    numOutputs;
-    RROutputPtr		    *outputs;
-    RROutputPtr		    primaryOutput;
-
-    int			    numCrtcs;
-    RRCrtcPtr		    *crtcs;
-
-    /* Last known pointer position */
-    RRCrtcPtr		    pointerCrtc;
-
-#ifdef RANDR_10_INTERFACE
-    /*
-     * Configuration information
-     */
-    Rotation		    rotations;
-    CARD16		    reqWidth, reqHeight;
-    
-    int			    nSizes;
-    RRScreenSizePtr	    pSizes;
-    
-    Rotation		    rotation;
-    int			    rate;
-    int			    size;
-#endif
-} rrScrPrivRec, *rrScrPrivPtr;
-
-extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
-#define rrPrivKey (&rrPrivKeyRec)
-
-#define rrGetScrPriv(pScr)  ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey))
-#define rrScrPriv(pScr)	rrScrPrivPtr    pScrPriv = rrGetScrPriv(pScr)
-#define SetRRScreen(s,p) dixSetPrivate(&(s)->devPrivates, rrPrivKey, p)
-
-/*
- * each window has a list of clients requesting
- * RRNotify events.  Each client has a resource
- * for each window it selects RRNotify input for,
- * this resource is used to delete the RRNotifyRec
- * entry from the per-window queue.
- */
-
-typedef struct _RREvent *RREventPtr;
-
-typedef struct _RREvent {
-    RREventPtr  next;
-    ClientPtr	client;
-    WindowPtr	window;
-    XID		clientResource;
-    int		mask;
-} RREventRec;
-
-typedef struct _RRTimes {
-    TimeStamp	setTime;
-    TimeStamp	configTime;
-} RRTimesRec, *RRTimesPtr;
-
-typedef struct _RRClient {
-    int		major_version;
-    int		minor_version;
-/*  RRTimesRec	times[0]; */
-} RRClientRec, *RRClientPtr;
-
-extern _X_EXPORT RESTYPE RRClientType, RREventType; /* resource types for event masks */
-extern _X_EXPORT DevPrivateKeyRec RRClientPrivateKeyRec;
-#define RRClientPrivateKey (&RRClientPrivateKeyRec)
-extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType;
-
-#define VERIFY_RR_OUTPUT(id, ptr, a)\
-    {\
-	int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
-	                                 RROutputType, client, a);\
-	if (rc != Success) {\
-	    client->errorValue = id;\
-	    return rc;\
-	}\
-    }
-
-#define VERIFY_RR_CRTC(id, ptr, a)\
-    {\
-	int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
-	                                 RRCrtcType, client, a);\
-	if (rc != Success) {\
-	    client->errorValue = id;\
-	    return rc;\
-	}\
-    }
-
-#define VERIFY_RR_MODE(id, ptr, a)\
-    {\
-	int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
-	                                 RRModeType, client, a);\
-	if (rc != Success) {\
-	    client->errorValue = id;\
-	    return rc;\
-	}\
-    }
-
-#define GetRRClient(pClient)    ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey))
-#define rrClientPriv(pClient)	RRClientPtr pRRClient = GetRRClient(pClient)
-
-/* Initialize the extension */
-extern _X_EXPORT void
-RRExtensionInit (void);
-
-#ifdef RANDR_12_INTERFACE
-/*
- * Set the range of sizes for the screen
- */
-extern _X_EXPORT void
-RRScreenSetSizeRange (ScreenPtr	pScreen,
-		      CARD16	minWidth,
-		      CARD16	minHeight,
-		      CARD16	maxWidth,
-		      CARD16	maxHeight);
-#endif
-
-/* rrscreen.c */
-/*
- * Notify the extension that the screen size has been changed.
- * The driver is responsible for calling this whenever it has changed
- * the size of the screen
- */
-extern _X_EXPORT void
-RRScreenSizeNotify (ScreenPtr	pScreen);
-
-/*
- * Request that the screen be resized
- */
-extern _X_EXPORT Bool
-RRScreenSizeSet (ScreenPtr  pScreen,
-		 CARD16	    width,
-		 CARD16	    height,
-		 CARD32	    mmWidth,
-		 CARD32	    mmHeight);
-
-/*
- * Send ConfigureNotify event to root window when 'something' happens
- */
-extern _X_EXPORT void
-RRSendConfigNotify (ScreenPtr pScreen);
-    
-/*
- * screen dispatch
- */
-extern _X_EXPORT int
-ProcRRGetScreenSizeRange (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRSetScreenSize (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRGetScreenResources (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRGetScreenResourcesCurrent (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRSetScreenConfig (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRGetScreenInfo (ClientPtr client);
-
-/*
- * Deliver a ScreenNotify event
- */
-extern _X_EXPORT void
-RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen);
-    
-/* randr.c */
-/*
- * Send all pending events
- */
-extern _X_EXPORT void
-RRTellChanged (ScreenPtr pScreen);
-
-/*
- * Poll the driver for changed information
- */
-extern _X_EXPORT Bool
-RRGetInfo (ScreenPtr pScreen, Bool force_query);
-
-extern _X_EXPORT Bool RRInit (void);
-
-extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen);
-
-extern _X_EXPORT RROutputPtr
-RRFirstOutput (ScreenPtr pScreen);
-
-extern _X_EXPORT Rotation
-RRGetRotation (ScreenPtr pScreen);
-
-extern _X_EXPORT CARD16
-RRVerticalRefresh (xRRModeInfo *mode);
-
-#ifdef RANDR_10_INTERFACE					
-/*
- * This is the old interface, deprecated but left
- * around for compatibility
- */
-
-/*
- * Then, register the specific size with the screen
- */
-
-extern _X_EXPORT RRScreenSizePtr
-RRRegisterSize (ScreenPtr		pScreen,
-		short			width, 
-		short			height,
-		short			mmWidth,
-		short			mmHeight);
-
-extern _X_EXPORT Bool
-RRRegisterRate (ScreenPtr		pScreen,
-		     RRScreenSizePtr	pSize,
-		     int		rate);
-
-/*
- * Finally, set the current configuration of the screen
- */
-
-extern _X_EXPORT void
-RRSetCurrentConfig (ScreenPtr		pScreen,
-		    Rotation		rotation,
-		    int			rate,
-		    RRScreenSizePtr	pSize);
-
-extern _X_EXPORT Bool RRScreenInit (ScreenPtr pScreen);
-
-extern _X_EXPORT Rotation
-RRGetRotation (ScreenPtr pScreen);
-
-#endif					
-
-/* rrcrtc.c */
-
-/*
- * Notify the CRTC of some change; layoutChanged indicates that
- * some position or size element changed
- */
-extern _X_EXPORT void
-RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged);
-
-/*
- * Create a CRTC
- */
-extern _X_EXPORT RRCrtcPtr
-RRCrtcCreate (ScreenPtr pScreen, void	*devPrivate);
-
-/*
- * Set the allowed rotations on a CRTC
- */
-extern _X_EXPORT void
-RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations);
-
-/*
- * Set whether transforms are allowed on a CRTC
- */
-extern _X_EXPORT void
-RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms);
-
-/*
- * Notify the extension that the Crtc has been reconfigured,
- * the driver calls this whenever it has updated the mode
- */
-extern _X_EXPORT Bool
-RRCrtcNotify (RRCrtcPtr	    crtc,
-	      RRModePtr	    mode,
-	      int	    x,
-	      int	    y,
-	      Rotation	    rotation,
-	      RRTransformPtr transform,
-	      int	    numOutputs,
-	      RROutputPtr   *outputs);
-
-extern _X_EXPORT void
-RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
-    
-/*
- * Request that the Crtc be reconfigured
- */
-extern _X_EXPORT Bool
-RRCrtcSet (RRCrtcPtr    crtc,
-	   RRModePtr	mode,
-	   int		x,
-	   int		y,
-	   Rotation	rotation,
-	   int		numOutput,
-	   RROutputPtr  *outputs);
-
-/*
- * Request that the Crtc gamma be changed
- */
-
-extern _X_EXPORT Bool
-RRCrtcGammaSet (RRCrtcPtr   crtc,
-		CARD16	    *red,
-		CARD16	    *green,
-		CARD16	    *blue);
-
-/*
- * Request current gamma back from the DDX (if possible).
- * This includes gamma size.
- */
- 
-extern _X_EXPORT Bool
-RRCrtcGammaGet(RRCrtcPtr crtc);
-
-/*
- * Notify the extension that the Crtc gamma has been changed
- * The driver calls this whenever it has changed the gamma values
- * in the RRCrtcRec
- */
-
-extern _X_EXPORT Bool
-RRCrtcGammaNotify (RRCrtcPtr	crtc);
-
-/*
- * Set the size of the gamma table at server startup time
- */
-
-extern _X_EXPORT Bool
-RRCrtcGammaSetSize (RRCrtcPtr	crtc,
-		    int		size);
-
-/*
- * Return the area of the frame buffer scanned out by the crtc,
- * taking into account the current mode and rotation
- */
-
-extern _X_EXPORT void
-RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
-
-/*
- * Compute the complete transformation matrix including
- * client-specified transform, rotation/reflection values and the crtc 
- * offset.
- *
- * Return TRUE if the resulting transform is not a simple translation.
- */
-extern _X_EXPORT Bool
-RRTransformCompute (int			    x,
-		    int			    y,
-		    int			    width,
-		    int			    height,
-		    Rotation		    rotation,
-		    RRTransformPtr	    rr_transform,
-
-		    PictTransformPtr	    transform,
-		    struct pict_f_transform *f_transform,
-		    struct pict_f_transform *f_inverse);
-
-/*
- * Return crtc transform
- */
-extern _X_EXPORT RRTransformPtr
-RRCrtcGetTransform (RRCrtcPtr crtc);
-
-/*
- * Check whether the pending and current transforms are the same
- */
-extern _X_EXPORT Bool
-RRCrtcPendingTransform (RRCrtcPtr crtc);
-
-/*
- * Destroy a Crtc at shutdown
- */
-extern _X_EXPORT void
-RRCrtcDestroy (RRCrtcPtr crtc);
-
-
-/*
- * Set the pending CRTC transformation
- */
-
-extern _X_EXPORT int
-RRCrtcTransformSet (RRCrtcPtr		crtc,
-		    PictTransformPtr	transform,
-		    struct pict_f_transform *f_transform,
-		    struct pict_f_transform *f_inverse,
-		    char		*filter,
-		    int			filter_len,
-		    xFixed		*params,
-		    int			nparams);
-
-/*
- * Initialize crtc type
- */
-extern _X_EXPORT Bool
-RRCrtcInit (void);
-
-/*
- * Initialize crtc type error value
- */
-extern _X_EXPORT void
-RRCrtcInitErrorValue (void);
-
-/*
- * Crtc dispatch
- */
-
-extern _X_EXPORT int
-ProcRRGetCrtcInfo (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRSetCrtcConfig (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRGetCrtcGammaSize (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRGetCrtcGamma (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRSetCrtcGamma (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRSetCrtcTransform (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRGetCrtcTransform (ClientPtr client);
-
-int
-ProcRRGetPanning (ClientPtr client);
-
-int
-ProcRRSetPanning (ClientPtr client);
-
-/* rrdispatch.c */
-extern _X_EXPORT Bool
-RRClientKnowsRates (ClientPtr	pClient);
-
-/* rrmode.c */
-/*
- * Find, and if necessary, create a mode
- */
-
-extern _X_EXPORT RRModePtr
-RRModeGet (xRRModeInfo	*modeInfo,
-	   const char	*name);
-
-/*
- * Destroy a mode.
- */
-
-extern _X_EXPORT void
-RRModeDestroy (RRModePtr mode);
-
-/*
- * Return a list of modes that are valid for some output in pScreen
- */
-extern _X_EXPORT RRModePtr *
-RRModesForScreen (ScreenPtr pScreen, int *num_ret);
-    
-/*
- * Initialize mode type
- */
-extern _X_EXPORT Bool
-RRModeInit (void);
-
-/*
- * Initialize mode type error value
- */
-extern _X_EXPORT void
-RRModeInitErrorValue (void);
-    
-extern _X_EXPORT int
-ProcRRCreateMode (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRDestroyMode (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRAddOutputMode (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRDeleteOutputMode (ClientPtr client);
-
-/* rroutput.c */
-
-/*
- * Notify the output of some change. configChanged indicates whether
- * any external configuration (mode list, clones, connected status)
- * has changed, or whether the change was strictly internal
- * (which crtc is in use)
- */
-extern _X_EXPORT void
-RROutputChanged (RROutputPtr output, Bool configChanged);
-
-/*
- * Create an output
- */
-
-extern _X_EXPORT RROutputPtr
-RROutputCreate (ScreenPtr   pScreen,
-		const char  *name,
-		int	    nameLength,
-		void	    *devPrivate);
-
-/*
- * Notify extension that output parameters have been changed
- */
-extern _X_EXPORT Bool
-RROutputSetClones (RROutputPtr  output,
-		   RROutputPtr  *clones,
-		   int		numClones);
-
-extern _X_EXPORT Bool
-RROutputSetModes (RROutputPtr	output,
-		  RRModePtr	*modes,
-		  int		numModes,
-		  int		numPreferred);
-
-extern _X_EXPORT int
-RROutputAddUserMode (RROutputPtr    output,
-		     RRModePtr	    mode);
-
-extern _X_EXPORT int
-RROutputDeleteUserMode (RROutputPtr output,
-			RRModePtr   mode);
-
-extern _X_EXPORT Bool
-RROutputSetCrtcs (RROutputPtr	output,
-		  RRCrtcPtr	*crtcs,
-		  int		numCrtcs);
-
-extern _X_EXPORT Bool
-RROutputSetConnection (RROutputPtr  output,
-		       CARD8	    connection);
-
-extern _X_EXPORT Bool
-RROutputSetSubpixelOrder (RROutputPtr output,
-			  int	      subpixelOrder);
-
-extern _X_EXPORT Bool
-RROutputSetPhysicalSize (RROutputPtr	output,
-			 int		mmWidth,
-			 int		mmHeight);
-
-extern _X_EXPORT void
-RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output);
-
-extern _X_EXPORT void
-RROutputDestroy (RROutputPtr	output);
-
-extern _X_EXPORT int
-ProcRRGetOutputInfo (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRSetOutputPrimary (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRGetOutputPrimary (ClientPtr client);
-
-/*
- * Initialize output type
- */
-extern _X_EXPORT Bool
-RROutputInit (void);
-
-/*
- * Initialize output type error value
- */
-extern _X_EXPORT void
-RROutputInitErrorValue (void);
-    
-/* rrpointer.c */
-extern _X_EXPORT void
-RRPointerMoved (ScreenPtr pScreen, int x, int y);
-
-extern _X_EXPORT void
-RRPointerScreenConfigured (ScreenPtr pScreen);
-
-/* rrproperty.c */
-
-extern _X_EXPORT void
-RRDeleteAllOutputProperties (RROutputPtr output);
-
-extern _X_EXPORT RRPropertyValuePtr
-RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending);
-
-extern _X_EXPORT RRPropertyPtr
-RRQueryOutputProperty (RROutputPtr output, Atom property);
-		       
-extern _X_EXPORT void
-RRDeleteOutputProperty (RROutputPtr output, Atom property);
-
-extern _X_EXPORT Bool
-RRPostPendingProperties (RROutputPtr output);
-    
-extern _X_EXPORT int
-RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
-			int format, int mode, unsigned long len,
-			pointer value, Bool sendevent, Bool pending);
-
-extern _X_EXPORT int
-RRConfigureOutputProperty (RROutputPtr output, Atom property,
-			   Bool pending, Bool range, Bool immutable,
-			   int num_values, INT32 *values);
-extern _X_EXPORT int
-ProcRRChangeOutputProperty (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRGetOutputProperty (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRListOutputProperties (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRQueryOutputProperty (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRConfigureOutputProperty (ClientPtr client);
-
-extern _X_EXPORT int
-ProcRRDeleteOutputProperty (ClientPtr client);
-
-/* rrxinerama.c */
-#ifdef XINERAMA
-extern _X_EXPORT void
-RRXineramaExtensionInit(void);
-#endif
-
-#endif /* _RANDRSTR_H_ */
-
-/*
- 
-randr extension implementation structure
-
-Query state:
-    ProcRRGetScreenInfo/ProcRRGetScreenResources
-	RRGetInfo
- 
-	    • Request configuration from driver, either 1.0 or 1.2 style
-	    • These functions only record state changes, all
-	      other actions are pended until RRTellChanged is called
- 
-	    ->rrGetInfo
-	    1.0:
-		RRRegisterSize
-		RRRegisterRate
-		RRSetCurrentConfig
-	    1.2:
-		RRScreenSetSizeRange
-		RROutputSetCrtcs
-		RRModeGet
-		RROutputSetModes
-		RROutputSetConnection
-		RROutputSetSubpixelOrder
-		RROutputSetClones
-		RRCrtcNotify
- 
-	• Must delay scanning configuration until after ->rrGetInfo returns
-	  because some drivers will call SetCurrentConfig in the middle
-	  of the ->rrGetInfo operation.
- 
-	1.0:
-
-	    • Scan old configuration, mirror to new structures
- 
-	    RRScanOldConfig
-		RRCrtcCreate
-		RROutputCreate
-		RROutputSetCrtcs
-		RROutputSetConnection
-		RROutputSetSubpixelOrder
-		RROldModeAdd	• This adds modes one-at-a-time
-		    RRModeGet
-		RRCrtcNotify
- 
-	• send events, reset pointer if necessary
- 
-	RRTellChanged
-	    WalkTree (sending events)
- 
-	    • when layout has changed:
-		RRPointerScreenConfigured
-		RRSendConfigNotify
- 
-Asynchronous state setting (1.2 only)
-    When setting state asynchronously, the driver invokes the
-    ->rrGetInfo function and then calls RRTellChanged to flush
-    the changes to the clients and reset pointer if necessary
-
-Set state
-
-    ProcRRSetScreenConfig
-	RRCrtcSet
-	    1.2:
-		->rrCrtcSet
-		    RRCrtcNotify
-	    1.0:
-		->rrSetConfig
-		RRCrtcNotify
-	    RRTellChanged
- */
+/*
+ * Copyright © 2000 Compaq Computer Corporation
+ * Copyright © 2002 Hewlett-Packard Company
+ * Copyright © 2006 Intel Corporation
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Author:  Jim Gettys, Hewlett-Packard Company, Inc.
+ *	    Keith Packard, Intel Corporation
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _RANDRSTR_H_
+#define _RANDRSTR_H_
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include "rrtransform.h"
+#include <X11/extensions/randr.h>
+#include <X11/extensions/randrproto.h>
+#include <X11/extensions/render.h> 	/* we share subpixel order information */
+#include "picturestr.h"
+#include <X11/Xfuncproto.h>
+
+/* required for ABI compatibility for now */
+#define RANDR_10_INTERFACE 1
+#define RANDR_12_INTERFACE 1
+#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
+#define RANDR_GET_CRTC_INTERFACE 1
+
+#define RANDR_INTERFACE_VERSION 0x0103
+
+typedef XID	RRMode;
+typedef XID	RROutput;
+typedef XID	RRCrtc;
+
+extern _X_EXPORT int	RREventBase, RRErrorBase;
+
+extern _X_EXPORT int (*ProcRandrVector[RRNumberRequests])(ClientPtr);
+extern _X_EXPORT int (*SProcRandrVector[RRNumberRequests])(ClientPtr);
+    
+/*
+ * Modeline for a monitor. Name follows directly after this struct
+ */
+
+#define RRModeName(pMode) ((char *) (pMode + 1))
+typedef struct _rrMode		RRModeRec, *RRModePtr;
+typedef struct _rrPropertyValue	RRPropertyValueRec, *RRPropertyValuePtr;
+typedef struct _rrProperty	RRPropertyRec, *RRPropertyPtr;
+typedef struct _rrCrtc		RRCrtcRec, *RRCrtcPtr;
+typedef struct _rrOutput	RROutputRec, *RROutputPtr;
+
+struct _rrMode {
+    int		    refcnt;
+    xRRModeInfo	    mode;
+    char	    *name;
+    ScreenPtr	    userScreen;
+};
+
+struct _rrPropertyValue {
+    Atom	    type;       /* ignored by server */
+    short	    format;     /* format of data for swapping - 8,16,32 */
+    long	    size;	/* size of data in (format/8) bytes */
+    pointer         data;	/* private to client */
+};
+
+struct _rrProperty {
+    RRPropertyPtr   next;
+    ATOM 	    propertyName;
+    Bool	    is_pending;
+    Bool	    range;
+    Bool	    immutable;
+    int		    num_valid;
+    INT32	    *valid_values;
+    RRPropertyValueRec	current, pending;
+};
+
+struct _rrCrtc {
+    RRCrtc	    id;
+    ScreenPtr	    pScreen;
+    RRModePtr	    mode;
+    int		    x, y;
+    Rotation	    rotation;
+    Rotation	    rotations;
+    Bool	    changed;
+    int		    numOutputs;
+    RROutputPtr	    *outputs;
+    int		    gammaSize;
+    CARD16	    *gammaRed;
+    CARD16	    *gammaBlue;
+    CARD16	    *gammaGreen;
+    void	    *devPrivate;
+    Bool	    transforms;
+    RRTransformRec  client_pending_transform;
+    RRTransformRec  client_current_transform;
+    PictTransform   transform;
+    struct pict_f_transform f_transform;
+    struct pict_f_transform f_inverse;
+};
+
+struct _rrOutput {
+    RROutput	    id;
+    ScreenPtr	    pScreen;
+    char	    *name;
+    int		    nameLength;
+    CARD8	    connection;
+    CARD8	    subpixelOrder;
+    int		    mmWidth;
+    int		    mmHeight;
+    RRCrtcPtr	    crtc;
+    int		    numCrtcs;
+    RRCrtcPtr	    *crtcs;
+    int		    numClones;
+    RROutputPtr	    *clones;
+    int		    numModes;
+    int		    numPreferred;
+    RRModePtr	    *modes;
+    int		    numUserModes;
+    RRModePtr	    *userModes;
+    Bool	    changed;
+    RRPropertyPtr   properties;
+    Bool	    pendingProperties;
+    void	    *devPrivate;
+};
+
+#if RANDR_12_INTERFACE
+typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr	pScreen,
+					CARD16		width,
+					CARD16		height,
+					CARD32		mmWidth,
+					CARD32		mmHeight);
+					
+typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr		pScreen,
+				  RRCrtcPtr		crtc,
+				  RRModePtr		mode,
+				  int			x,
+				  int			y,
+				  Rotation		rotation,
+				  int			numOutputs,
+				  RROutputPtr		*outputs);
+
+typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr	pScreen,
+				       RRCrtcPtr	crtc);
+
+typedef Bool (*RRCrtcGetGammaProcPtr) (ScreenPtr	pScreen,
+				       RRCrtcPtr	crtc);
+
+typedef Bool (*RROutputSetPropertyProcPtr) (ScreenPtr		pScreen,
+					    RROutputPtr		output,
+					    Atom		property,
+					    RRPropertyValuePtr	value);
+
+typedef Bool (*RROutputValidateModeProcPtr) (ScreenPtr		pScreen,
+					     RROutputPtr	output,
+					     RRModePtr		mode);
+
+typedef void (*RRModeDestroyProcPtr) (ScreenPtr	    pScreen,
+				      RRModePtr	    mode);
+
+#endif
+
+#if RANDR_13_INTERFACE
+typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr		pScreen,
+					    RROutputPtr		output,
+					    Atom		property);
+typedef Bool (*RRGetPanningProcPtr)    (ScreenPtr		pScrn,
+					RRCrtcPtr		crtc,
+					BoxPtr		totalArea,
+					BoxPtr		trackingArea,
+					INT16		*border);
+typedef Bool (*RRSetPanningProcPtr)    (ScreenPtr		pScrn,
+					RRCrtcPtr		crtc,
+					BoxPtr		totalArea,
+					BoxPtr		trackingArea,
+					INT16		*border);
+
+#endif /* RANDR_13_INTERFACE */
+
+typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations);
+typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen);
+
+/* These are for 1.0 compatibility */
+ 
+typedef struct _rrRefresh {
+    CARD16	    rate;
+    RRModePtr	    mode;
+} RRScreenRate, *RRScreenRatePtr;
+
+typedef struct _rrScreenSize {
+    int		    id;
+    short	    width, height;
+    short	    mmWidth, mmHeight;
+    int		    nRates;
+    RRScreenRatePtr pRates;
+} RRScreenSize, *RRScreenSizePtr;
+
+#ifdef RANDR_10_INTERFACE
+
+typedef Bool (*RRSetConfigProcPtr) (ScreenPtr		pScreen,
+				    Rotation		rotation,
+				    int			rate,
+				    RRScreenSizePtr	pSize);
+
+#endif
+	
+
+typedef struct _rrScrPriv {
+    /*
+     * 'public' part of the structure; DDXen fill this in
+     * as they initialize
+     */
+#if RANDR_10_INTERFACE
+    RRSetConfigProcPtr	    rrSetConfig;
+#endif
+    RRGetInfoProcPtr	    rrGetInfo;
+#if RANDR_12_INTERFACE
+    RRScreenSetSizeProcPtr  rrScreenSetSize;
+    RRCrtcSetProcPtr	    rrCrtcSet;
+    RRCrtcSetGammaProcPtr   rrCrtcSetGamma;
+    RRCrtcGetGammaProcPtr   rrCrtcGetGamma;
+    RROutputSetPropertyProcPtr	rrOutputSetProperty;
+    RROutputValidateModeProcPtr	rrOutputValidateMode;
+    RRModeDestroyProcPtr	rrModeDestroy;
+#endif
+#if RANDR_13_INTERFACE
+    RROutputGetPropertyProcPtr	rrOutputGetProperty;
+    RRGetPanningProcPtr	rrGetPanning;
+    RRSetPanningProcPtr	rrSetPanning;
+#endif
+    
+    /*
+     * Private part of the structure; not considered part of the ABI
+     */
+    TimeStamp		    lastSetTime;	/* last changed by client */
+    TimeStamp		    lastConfigTime;	/* possible configs changed */
+    RRCloseScreenProcPtr    CloseScreen;
+
+    Bool		    changed;		/* some config changed */
+    Bool		    configChanged;	/* configuration changed */
+    Bool		    layoutChanged;	/* screen layout changed */
+
+    CARD16		    minWidth, minHeight;
+    CARD16		    maxWidth, maxHeight;
+    CARD16		    width, height;	/* last known screen size */
+    CARD16		    mmWidth, mmHeight;	/* last known screen size */
+
+    int			    numOutputs;
+    RROutputPtr		    *outputs;
+    RROutputPtr		    primaryOutput;
+
+    int			    numCrtcs;
+    RRCrtcPtr		    *crtcs;
+
+    /* Last known pointer position */
+    RRCrtcPtr		    pointerCrtc;
+
+#ifdef RANDR_10_INTERFACE
+    /*
+     * Configuration information
+     */
+    Rotation		    rotations;
+    CARD16		    reqWidth, reqHeight;
+    
+    int			    nSizes;
+    RRScreenSizePtr	    pSizes;
+    
+    Rotation		    rotation;
+    int			    rate;
+    int			    size;
+#endif
+    Bool                   discontiguous;
+} rrScrPrivRec, *rrScrPrivPtr;
+
+extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
+#define rrPrivKey (&rrPrivKeyRec)
+
+#define rrGetScrPriv(pScr)  ((rrScrPrivPtr)dixLookupPrivate(&(pScr)->devPrivates, rrPrivKey))
+#define rrScrPriv(pScr)	rrScrPrivPtr    pScrPriv = rrGetScrPriv(pScr)
+#define SetRRScreen(s,p) dixSetPrivate(&(s)->devPrivates, rrPrivKey, p)
+
+/*
+ * each window has a list of clients requesting
+ * RRNotify events.  Each client has a resource
+ * for each window it selects RRNotify input for,
+ * this resource is used to delete the RRNotifyRec
+ * entry from the per-window queue.
+ */
+
+typedef struct _RREvent *RREventPtr;
+
+typedef struct _RREvent {
+    RREventPtr  next;
+    ClientPtr	client;
+    WindowPtr	window;
+    XID		clientResource;
+    int		mask;
+} RREventRec;
+
+typedef struct _RRTimes {
+    TimeStamp	setTime;
+    TimeStamp	configTime;
+} RRTimesRec, *RRTimesPtr;
+
+typedef struct _RRClient {
+    int		major_version;
+    int		minor_version;
+/*  RRTimesRec	times[0]; */
+} RRClientRec, *RRClientPtr;
+
+extern _X_EXPORT RESTYPE RRClientType, RREventType; /* resource types for event masks */
+extern _X_EXPORT DevPrivateKeyRec RRClientPrivateKeyRec;
+#define RRClientPrivateKey (&RRClientPrivateKeyRec)
+extern _X_EXPORT RESTYPE RRCrtcType, RRModeType, RROutputType;
+
+#define VERIFY_RR_OUTPUT(id, ptr, a)\
+    {\
+	int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
+	                                 RROutputType, client, a);\
+	if (rc != Success) {\
+	    client->errorValue = id;\
+	    return rc;\
+	}\
+    }
+
+#define VERIFY_RR_CRTC(id, ptr, a)\
+    {\
+	int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
+	                                 RRCrtcType, client, a);\
+	if (rc != Success) {\
+	    client->errorValue = id;\
+	    return rc;\
+	}\
+    }
+
+#define VERIFY_RR_MODE(id, ptr, a)\
+    {\
+	int rc = dixLookupResourceByType((pointer *)&(ptr), id,\
+	                                 RRModeType, client, a);\
+	if (rc != Success) {\
+	    client->errorValue = id;\
+	    return rc;\
+	}\
+    }
+
+#define GetRRClient(pClient)    ((RRClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RRClientPrivateKey))
+#define rrClientPriv(pClient)	RRClientPtr pRRClient = GetRRClient(pClient)
+
+/* Initialize the extension */
+extern _X_EXPORT void
+RRExtensionInit (void);
+
+#ifdef RANDR_12_INTERFACE
+/*
+ * Set the range of sizes for the screen
+ */
+extern _X_EXPORT void
+RRScreenSetSizeRange (ScreenPtr	pScreen,
+		      CARD16	minWidth,
+		      CARD16	minHeight,
+		      CARD16	maxWidth,
+		      CARD16	maxHeight);
+#endif
+
+/* rrscreen.c */
+/*
+ * Notify the extension that the screen size has been changed.
+ * The driver is responsible for calling this whenever it has changed
+ * the size of the screen
+ */
+extern _X_EXPORT void
+RRScreenSizeNotify (ScreenPtr	pScreen);
+
+/*
+ * Request that the screen be resized
+ */
+extern _X_EXPORT Bool
+RRScreenSizeSet (ScreenPtr  pScreen,
+		 CARD16	    width,
+		 CARD16	    height,
+		 CARD32	    mmWidth,
+		 CARD32	    mmHeight);
+
+/*
+ * Send ConfigureNotify event to root window when 'something' happens
+ */
+extern _X_EXPORT void
+RRSendConfigNotify (ScreenPtr pScreen);
+    
+/*
+ * screen dispatch
+ */
+extern _X_EXPORT int
+ProcRRGetScreenSizeRange (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRSetScreenSize (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetScreenResources (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetScreenResourcesCurrent (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRSetScreenConfig (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetScreenInfo (ClientPtr client);
+
+/*
+ * Deliver a ScreenNotify event
+ */
+extern _X_EXPORT void
+RRDeliverScreenEvent (ClientPtr client, WindowPtr pWin, ScreenPtr pScreen);
+    
+/* randr.c */
+/*
+ * Send all pending events
+ */
+extern _X_EXPORT void
+RRTellChanged (ScreenPtr pScreen);
+
+/*
+ * Poll the driver for changed information
+ */
+extern _X_EXPORT Bool
+RRGetInfo (ScreenPtr pScreen, Bool force_query);
+
+extern _X_EXPORT Bool RRInit (void);
+
+extern _X_EXPORT Bool RRScreenInit(ScreenPtr pScreen);
+
+extern _X_EXPORT RROutputPtr
+RRFirstOutput (ScreenPtr pScreen);
+
+extern _X_EXPORT Rotation
+RRGetRotation (ScreenPtr pScreen);
+
+extern _X_EXPORT CARD16
+RRVerticalRefresh (xRRModeInfo *mode);
+
+#ifdef RANDR_10_INTERFACE					
+/*
+ * This is the old interface, deprecated but left
+ * around for compatibility
+ */
+
+/*
+ * Then, register the specific size with the screen
+ */
+
+extern _X_EXPORT RRScreenSizePtr
+RRRegisterSize (ScreenPtr		pScreen,
+		short			width, 
+		short			height,
+		short			mmWidth,
+		short			mmHeight);
+
+extern _X_EXPORT Bool
+RRRegisterRate (ScreenPtr		pScreen,
+		     RRScreenSizePtr	pSize,
+		     int		rate);
+
+/*
+ * Finally, set the current configuration of the screen
+ */
+
+extern _X_EXPORT void
+RRSetCurrentConfig (ScreenPtr		pScreen,
+		    Rotation		rotation,
+		    int			rate,
+		    RRScreenSizePtr	pSize);
+
+extern _X_EXPORT Bool RRScreenInit (ScreenPtr pScreen);
+
+extern _X_EXPORT Rotation
+RRGetRotation (ScreenPtr pScreen);
+
+#endif					
+
+/* rrcrtc.c */
+
+/*
+ * Notify the CRTC of some change; layoutChanged indicates that
+ * some position or size element changed
+ */
+extern _X_EXPORT void
+RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged);
+
+/*
+ * Create a CRTC
+ */
+extern _X_EXPORT RRCrtcPtr
+RRCrtcCreate (ScreenPtr pScreen, void	*devPrivate);
+
+/*
+ * Set the allowed rotations on a CRTC
+ */
+extern _X_EXPORT void
+RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations);
+
+/*
+ * Set whether transforms are allowed on a CRTC
+ */
+extern _X_EXPORT void
+RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms);
+
+/*
+ * Notify the extension that the Crtc has been reconfigured,
+ * the driver calls this whenever it has updated the mode
+ */
+extern _X_EXPORT Bool
+RRCrtcNotify (RRCrtcPtr	    crtc,
+	      RRModePtr	    mode,
+	      int	    x,
+	      int	    y,
+	      Rotation	    rotation,
+	      RRTransformPtr transform,
+	      int	    numOutputs,
+	      RROutputPtr   *outputs);
+
+extern _X_EXPORT void
+RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
+    
+/*
+ * Request that the Crtc be reconfigured
+ */
+extern _X_EXPORT Bool
+RRCrtcSet (RRCrtcPtr    crtc,
+	   RRModePtr	mode,
+	   int		x,
+	   int		y,
+	   Rotation	rotation,
+	   int		numOutput,
+	   RROutputPtr  *outputs);
+
+/*
+ * Request that the Crtc gamma be changed
+ */
+
+extern _X_EXPORT Bool
+RRCrtcGammaSet (RRCrtcPtr   crtc,
+		CARD16	    *red,
+		CARD16	    *green,
+		CARD16	    *blue);
+
+/*
+ * Request current gamma back from the DDX (if possible).
+ * This includes gamma size.
+ */
+ 
+extern _X_EXPORT Bool
+RRCrtcGammaGet(RRCrtcPtr crtc);
+
+/*
+ * Notify the extension that the Crtc gamma has been changed
+ * The driver calls this whenever it has changed the gamma values
+ * in the RRCrtcRec
+ */
+
+extern _X_EXPORT Bool
+RRCrtcGammaNotify (RRCrtcPtr	crtc);
+
+/*
+ * Set the size of the gamma table at server startup time
+ */
+
+extern _X_EXPORT Bool
+RRCrtcGammaSetSize (RRCrtcPtr	crtc,
+		    int		size);
+
+/*
+ * Return the area of the frame buffer scanned out by the crtc,
+ * taking into account the current mode and rotation
+ */
+
+extern _X_EXPORT void
+RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
+
+/*
+ * Compute the complete transformation matrix including
+ * client-specified transform, rotation/reflection values and the crtc 
+ * offset.
+ *
+ * Return TRUE if the resulting transform is not a simple translation.
+ */
+extern _X_EXPORT Bool
+RRTransformCompute (int			    x,
+		    int			    y,
+		    int			    width,
+		    int			    height,
+		    Rotation		    rotation,
+		    RRTransformPtr	    rr_transform,
+
+		    PictTransformPtr	    transform,
+		    struct pict_f_transform *f_transform,
+		    struct pict_f_transform *f_inverse);
+
+/*
+ * Return crtc transform
+ */
+extern _X_EXPORT RRTransformPtr
+RRCrtcGetTransform (RRCrtcPtr crtc);
+
+/*
+ * Check whether the pending and current transforms are the same
+ */
+extern _X_EXPORT Bool
+RRCrtcPendingTransform (RRCrtcPtr crtc);
+
+/*
+ * Destroy a Crtc at shutdown
+ */
+extern _X_EXPORT void
+RRCrtcDestroy (RRCrtcPtr crtc);
+
+
+/*
+ * Set the pending CRTC transformation
+ */
+
+extern _X_EXPORT int
+RRCrtcTransformSet (RRCrtcPtr		crtc,
+		    PictTransformPtr	transform,
+		    struct pict_f_transform *f_transform,
+		    struct pict_f_transform *f_inverse,
+		    char		*filter,
+		    int			filter_len,
+		    xFixed		*params,
+		    int			nparams);
+
+/*
+ * Initialize crtc type
+ */
+extern _X_EXPORT Bool
+RRCrtcInit (void);
+
+/*
+ * Initialize crtc type error value
+ */
+extern _X_EXPORT void
+RRCrtcInitErrorValue (void);
+
+/*
+ * Crtc dispatch
+ */
+
+extern _X_EXPORT int
+ProcRRGetCrtcInfo (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRSetCrtcConfig (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetCrtcGammaSize (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetCrtcGamma (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRSetCrtcGamma (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRSetCrtcTransform (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetCrtcTransform (ClientPtr client);
+
+int
+ProcRRGetPanning (ClientPtr client);
+
+int
+ProcRRSetPanning (ClientPtr client);
+
+void
+RRConstrainCursorHarder (DeviceIntPtr, ScreenPtr, int, int *, int *);
+
+/* rrdispatch.c */
+extern _X_EXPORT Bool
+RRClientKnowsRates (ClientPtr	pClient);
+
+/* rrmode.c */
+/*
+ * Find, and if necessary, create a mode
+ */
+
+extern _X_EXPORT RRModePtr
+RRModeGet (xRRModeInfo	*modeInfo,
+	   const char	*name);
+
+/*
+ * Destroy a mode.
+ */
+
+extern _X_EXPORT void
+RRModeDestroy (RRModePtr mode);
+
+/*
+ * Return a list of modes that are valid for some output in pScreen
+ */
+extern _X_EXPORT RRModePtr *
+RRModesForScreen (ScreenPtr pScreen, int *num_ret);
+    
+/*
+ * Initialize mode type
+ */
+extern _X_EXPORT Bool
+RRModeInit (void);
+
+/*
+ * Initialize mode type error value
+ */
+extern _X_EXPORT void
+RRModeInitErrorValue (void);
+    
+extern _X_EXPORT int
+ProcRRCreateMode (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRDestroyMode (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRAddOutputMode (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRDeleteOutputMode (ClientPtr client);
+
+/* rroutput.c */
+
+/*
+ * Notify the output of some change. configChanged indicates whether
+ * any external configuration (mode list, clones, connected status)
+ * has changed, or whether the change was strictly internal
+ * (which crtc is in use)
+ */
+extern _X_EXPORT void
+RROutputChanged (RROutputPtr output, Bool configChanged);
+
+/*
+ * Create an output
+ */
+
+extern _X_EXPORT RROutputPtr
+RROutputCreate (ScreenPtr   pScreen,
+		const char  *name,
+		int	    nameLength,
+		void	    *devPrivate);
+
+/*
+ * Notify extension that output parameters have been changed
+ */
+extern _X_EXPORT Bool
+RROutputSetClones (RROutputPtr  output,
+		   RROutputPtr  *clones,
+		   int		numClones);
+
+extern _X_EXPORT Bool
+RROutputSetModes (RROutputPtr	output,
+		  RRModePtr	*modes,
+		  int		numModes,
+		  int		numPreferred);
+
+extern _X_EXPORT int
+RROutputAddUserMode (RROutputPtr    output,
+		     RRModePtr	    mode);
+
+extern _X_EXPORT int
+RROutputDeleteUserMode (RROutputPtr output,
+			RRModePtr   mode);
+
+extern _X_EXPORT Bool
+RROutputSetCrtcs (RROutputPtr	output,
+		  RRCrtcPtr	*crtcs,
+		  int		numCrtcs);
+
+extern _X_EXPORT Bool
+RROutputSetConnection (RROutputPtr  output,
+		       CARD8	    connection);
+
+extern _X_EXPORT Bool
+RROutputSetSubpixelOrder (RROutputPtr output,
+			  int	      subpixelOrder);
+
+extern _X_EXPORT Bool
+RROutputSetPhysicalSize (RROutputPtr	output,
+			 int		mmWidth,
+			 int		mmHeight);
+
+extern _X_EXPORT void
+RRDeliverOutputEvent(ClientPtr client, WindowPtr pWin, RROutputPtr output);
+
+extern _X_EXPORT void
+RROutputDestroy (RROutputPtr	output);
+
+extern _X_EXPORT int
+ProcRRGetOutputInfo (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRSetOutputPrimary (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetOutputPrimary (ClientPtr client);
+
+/*
+ * Initialize output type
+ */
+extern _X_EXPORT Bool
+RROutputInit (void);
+
+/*
+ * Initialize output type error value
+ */
+extern _X_EXPORT void
+RROutputInitErrorValue (void);
+    
+/* rrpointer.c */
+extern _X_EXPORT void
+RRPointerMoved (ScreenPtr pScreen, int x, int y);
+
+extern _X_EXPORT void
+RRPointerScreenConfigured (ScreenPtr pScreen);
+
+/* rrproperty.c */
+
+extern _X_EXPORT void
+RRDeleteAllOutputProperties (RROutputPtr output);
+
+extern _X_EXPORT RRPropertyValuePtr
+RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending);
+
+extern _X_EXPORT RRPropertyPtr
+RRQueryOutputProperty (RROutputPtr output, Atom property);
+		       
+extern _X_EXPORT void
+RRDeleteOutputProperty (RROutputPtr output, Atom property);
+
+extern _X_EXPORT Bool
+RRPostPendingProperties (RROutputPtr output);
+    
+extern _X_EXPORT int
+RRChangeOutputProperty (RROutputPtr output, Atom property, Atom type,
+			int format, int mode, unsigned long len,
+			pointer value, Bool sendevent, Bool pending);
+
+extern _X_EXPORT int
+RRConfigureOutputProperty (RROutputPtr output, Atom property,
+			   Bool pending, Bool range, Bool immutable,
+			   int num_values, INT32 *values);
+extern _X_EXPORT int
+ProcRRChangeOutputProperty (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetOutputProperty (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRListOutputProperties (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRQueryOutputProperty (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRConfigureOutputProperty (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRDeleteOutputProperty (ClientPtr client);
+
+/* rrxinerama.c */
+#ifdef XINERAMA
+extern _X_EXPORT void
+RRXineramaExtensionInit(void);
+#endif
+
+#endif /* _RANDRSTR_H_ */
+
+/*
+ 
+randr extension implementation structure
+
+Query state:
+    ProcRRGetScreenInfo/ProcRRGetScreenResources
+	RRGetInfo
+ 
+	    • Request configuration from driver, either 1.0 or 1.2 style
+	    • These functions only record state changes, all
+	      other actions are pended until RRTellChanged is called
+ 
+	    ->rrGetInfo
+	    1.0:
+		RRRegisterSize
+		RRRegisterRate
+		RRSetCurrentConfig
+	    1.2:
+		RRScreenSetSizeRange
+		RROutputSetCrtcs
+		RRModeGet
+		RROutputSetModes
+		RROutputSetConnection
+		RROutputSetSubpixelOrder
+		RROutputSetClones
+		RRCrtcNotify
+ 
+	• Must delay scanning configuration until after ->rrGetInfo returns
+	  because some drivers will call SetCurrentConfig in the middle
+	  of the ->rrGetInfo operation.
+ 
+	1.0:
+
+	    • Scan old configuration, mirror to new structures
+ 
+	    RRScanOldConfig
+		RRCrtcCreate
+		RROutputCreate
+		RROutputSetCrtcs
+		RROutputSetConnection
+		RROutputSetSubpixelOrder
+		RROldModeAdd	• This adds modes one-at-a-time
+		    RRModeGet
+		RRCrtcNotify
+ 
+	• send events, reset pointer if necessary
+ 
+	RRTellChanged
+	    WalkTree (sending events)
+ 
+	    • when layout has changed:
+		RRPointerScreenConfigured
+		RRSendConfigNotify
+ 
+Asynchronous state setting (1.2 only)
+    When setting state asynchronously, the driver invokes the
+    ->rrGetInfo function and then calls RRTellChanged to flush
+    the changes to the clients and reset pointer if necessary
+
+Set state
+
+    ProcRRSetScreenConfig
+	RRCrtcSet
+	    1.2:
+		->rrCrtcSet
+		    RRCrtcNotify
+	    1.0:
+		->rrSetConfig
+		RRCrtcNotify
+	    RRTellChanged
+ */
diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c
index 98206a2b9..a846ad3d1 100644
--- a/xorg-server/randr/rrcrtc.c
+++ b/xorg-server/randr/rrcrtc.c
@@ -1,1351 +1,1506 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#include "randrstr.h"
-#include "swaprep.h"
-
-RESTYPE	RRCrtcType;
-
-/*
- * Notify the CRTC of some change
- */
-void
-RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
-{
-    ScreenPtr	pScreen = crtc->pScreen;
-
-    crtc->changed = TRUE;
-    if (pScreen)
-    {
-	rrScrPriv(pScreen);
-    
-	pScrPriv->changed = TRUE;
-	/*
-	 * Send ConfigureNotify on any layout change
-	 */
-	if (layoutChanged)
-	    pScrPriv->layoutChanged = TRUE;
-    }
-}
-
-/*
- * Create a CRTC
- */
-RRCrtcPtr
-RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
-{
-    RRCrtcPtr	    crtc;
-    RRCrtcPtr	    *crtcs;
-    rrScrPrivPtr    pScrPriv;
-
-    if (!RRInit())
-	return NULL;
-    
-    pScrPriv = rrGetScrPriv(pScreen);
-
-    /* make space for the crtc pointer */
-    if (pScrPriv->numCrtcs)
-	crtcs = realloc(pScrPriv->crtcs, 
-			  (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
-    else
-	crtcs = malloc(sizeof (RRCrtcPtr));
-    if (!crtcs)
-	return FALSE;
-    pScrPriv->crtcs = crtcs;
-    
-    crtc = calloc(1, sizeof (RRCrtcRec));
-    if (!crtc)
-	return NULL;
-    crtc->id = FakeClientID (0);
-    crtc->pScreen = pScreen;
-    crtc->mode = NULL;
-    crtc->x = 0;
-    crtc->y = 0;
-    crtc->rotation = RR_Rotate_0;
-    crtc->rotations = RR_Rotate_0;
-    crtc->outputs = NULL;
-    crtc->numOutputs = 0;
-    crtc->gammaSize = 0;
-    crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
-    crtc->changed = FALSE;
-    crtc->devPrivate = devPrivate;
-    RRTransformInit (&crtc->client_pending_transform);
-    RRTransformInit (&crtc->client_current_transform);
-    pixman_transform_init_identity (&crtc->transform);
-    pixman_f_transform_init_identity (&crtc->f_transform);
-    pixman_f_transform_init_identity (&crtc->f_inverse);
-
-    if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
-	return NULL;
-
-    /* attach the screen and crtc together */
-    crtc->pScreen = pScreen;
-    pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
-    
-    return crtc;
-}
-
-/*
- * Set the allowed rotations on a CRTC
- */
-void
-RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations)
-{
-    crtc->rotations = rotations;
-}
-
-/*
- * Set whether transforms are allowed on a CRTC
- */
-void
-RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms)
-{
-    crtc->transforms = transforms;
-}
-
-/*
- * Notify the extension that the Crtc has been reconfigured,
- * the driver calls this whenever it has updated the mode
- */
-Bool
-RRCrtcNotify (RRCrtcPtr	    crtc,
-	      RRModePtr	    mode,
-	      int	    x,
-	      int	    y,
-	      Rotation	    rotation,
-	      RRTransformPtr transform,
-	      int	    numOutputs,
-	      RROutputPtr   *outputs)
-{
-    int	    i, j;
-    
-    /*
-     * Check to see if any of the new outputs were
-     * not in the old list and mark them as changed
-     */
-    for (i = 0; i < numOutputs; i++)
-    {
-	for (j = 0; j < crtc->numOutputs; j++)
-	    if (outputs[i] == crtc->outputs[j])
-		break;
-	if (j == crtc->numOutputs)
-	{
-	    outputs[i]->crtc = crtc;
-	    RROutputChanged (outputs[i], FALSE);
-	    RRCrtcChanged (crtc, FALSE);
-	}
-    }
-    /*
-     * Check to see if any of the old outputs are
-     * not in the new list and mark them as changed
-     */
-    for (j = 0; j < crtc->numOutputs; j++)
-    {
-	for (i = 0; i < numOutputs; i++)
-	    if (outputs[i] == crtc->outputs[j])
-		break;
-	if (i == numOutputs)
-	{
-	    if (crtc->outputs[j]->crtc == crtc)
-		crtc->outputs[j]->crtc = NULL;
-	    RROutputChanged (crtc->outputs[j], FALSE);
-	    RRCrtcChanged (crtc, FALSE);
-	}
-    }
-    /*
-     * Reallocate the crtc output array if necessary
-     */
-    if (numOutputs != crtc->numOutputs)
-    {
-	RROutputPtr *newoutputs;
-	
-	if (numOutputs)
-	{
-	    if (crtc->numOutputs)
-		newoutputs = realloc(crtc->outputs,
-				    numOutputs * sizeof (RROutputPtr));
-	    else
-		newoutputs = malloc(numOutputs * sizeof (RROutputPtr));
-	    if (!newoutputs)
-		return FALSE;
-	}
-	else
-	{
-	    free(crtc->outputs);
-	    newoutputs = NULL;
-	}
-	crtc->outputs = newoutputs;
-	crtc->numOutputs = numOutputs;
-    }
-    /*
-     * Copy the new list of outputs into the crtc
-     */
-    memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr));
-    /*
-     * Update remaining crtc fields
-     */
-    if (mode != crtc->mode)
-    {
-	if (crtc->mode)
-	    RRModeDestroy (crtc->mode);
-	crtc->mode = mode;
-	if (mode != NULL)
-	    mode->refcnt++;
-	RRCrtcChanged (crtc, TRUE);
-    }
-    if (x != crtc->x)
-    {
-	crtc->x = x;
-	RRCrtcChanged (crtc, TRUE);
-    }
-    if (y != crtc->y)
-    {
-	crtc->y = y;
-	RRCrtcChanged (crtc, TRUE);
-    }
-    if (rotation != crtc->rotation)
-    {
-	crtc->rotation = rotation;
-	RRCrtcChanged (crtc, TRUE);
-    }
-    if (!RRTransformEqual (transform, &crtc->client_current_transform)) {
-	RRTransformCopy (&crtc->client_current_transform, transform);
-	RRCrtcChanged (crtc, TRUE);
-    }
-    if (crtc->changed && mode)
-    {
-	RRTransformCompute (x, y,
-			    mode->mode.width, mode->mode.height,
-			    rotation,
-			    &crtc->client_current_transform,
-			    &crtc->transform, &crtc->f_transform,
-			    &crtc->f_inverse);
-    }
-    return TRUE;
-}
-
-void
-RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
-{
-    ScreenPtr pScreen = pWin->drawable.pScreen;
-    rrScrPriv (pScreen);
-    xRRCrtcChangeNotifyEvent	ce;
-    RRModePtr	mode = crtc->mode;
-    
-    ce.type = RRNotify + RREventBase;
-    ce.subCode = RRNotify_CrtcChange;
-    ce.timestamp = pScrPriv->lastSetTime.milliseconds;
-    ce.window = pWin->drawable.id;
-    ce.crtc = crtc->id;
-    ce.rotation = crtc->rotation;
-    if (mode)
-    {
-	ce.mode = mode->mode.id;
-	ce.x = crtc->x;
-	ce.y = crtc->y;
-	ce.width = mode->mode.width;
-	ce.height = mode->mode.height;
-    }
-    else
-    {
-	ce.mode = None;
-	ce.x = 0;
-	ce.y = 0;
-	ce.width = 0;
-	ce.height = 0;
-    }
-    WriteEventsToClient (client, 1, (xEvent *) &ce);
-}
-
-static Bool
-RRCrtcPendingProperties (RRCrtcPtr crtc)
-{
-    ScreenPtr	pScreen = crtc->pScreen;
-    rrScrPriv(pScreen);
-    int		o;
-
-    for (o = 0; o < pScrPriv->numOutputs; o++)
-    {
-	RROutputPtr output = pScrPriv->outputs[o];
-	if (output->crtc == crtc && output->pendingProperties)
-	    return TRUE;
-    }
-    return FALSE;
-}
-
-/*
- * Request that the Crtc be reconfigured
- */
-Bool
-RRCrtcSet (RRCrtcPtr    crtc,
-	   RRModePtr	mode,
-	   int		x,
-	   int		y,
-	   Rotation	rotation,
-	   int		numOutputs,
-	   RROutputPtr  *outputs)
-{
-    ScreenPtr	pScreen = crtc->pScreen;
-    Bool	ret = FALSE;
-    rrScrPriv(pScreen);
-
-    /* See if nothing changed */
-    if (crtc->mode == mode &&
-	crtc->x == x &&
-	crtc->y == y &&
-	crtc->rotation == rotation &&
-	crtc->numOutputs == numOutputs &&
-	!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
-	!RRCrtcPendingProperties (crtc) &&
-	!RRCrtcPendingTransform (crtc))
-    {
-	ret = TRUE;
-    }
-    else
-    {
-#if RANDR_12_INTERFACE
-	if (pScrPriv->rrCrtcSet)
-	{
-	    ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, 
-					  rotation, numOutputs, outputs);
-	}
-	else
-#endif
-	{
-#if RANDR_10_INTERFACE
-	    if (pScrPriv->rrSetConfig)
-	    {
-		RRScreenSize	    size;
-		RRScreenRate	    rate;
-
-		if (!mode)
-		{
-		    RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL);
-		    ret = TRUE;
-		}
-		else
-		{
-		    size.width = mode->mode.width;
-		    size.height = mode->mode.height;
-		    if (outputs[0]->mmWidth && outputs[0]->mmHeight)
-		    {
-			size.mmWidth = outputs[0]->mmWidth;
-			size.mmHeight = outputs[0]->mmHeight;
-		    }
-		    else
-		    {
-			size.mmWidth = pScreen->mmWidth;
-			size.mmHeight = pScreen->mmHeight;
-		    }
-		    size.nRates = 1;
-		    rate.rate = RRVerticalRefresh (&mode->mode);
-		    size.pRates = &rate;
-		    ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
-		    /*
-		     * Old 1.0 interface tied screen size to mode size
-		     */
-		    if (ret)
-		    {
-			RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs);
-			RRScreenSizeNotify (pScreen);
-		    }
-		}
-	    }
-#endif
-	}
-	if (ret)
-	{
-	    int	o;
-	    RRTellChanged (pScreen);
-
-	    for (o = 0; o < numOutputs; o++)
-		RRPostPendingProperties (outputs[o]);
-	}
-    }
-    return ret;
-}
-
-/*
- * Return crtc transform
- */
-RRTransformPtr
-RRCrtcGetTransform (RRCrtcPtr crtc)
-{
-    RRTransformPtr  transform = &crtc->client_pending_transform;
-
-    if (pixman_transform_is_identity (&transform->transform))
-	return NULL;
-    return transform;
-}
-
-/*
- * Check whether the pending and current transforms are the same
- */
-Bool
-RRCrtcPendingTransform (RRCrtcPtr crtc)
-{
-    return memcmp (&crtc->client_current_transform.transform,
-		   &crtc->client_pending_transform.transform,
-		   sizeof (PictTransform)) != 0;
-}
-
-/*
- * Destroy a Crtc at shutdown
- */
-void
-RRCrtcDestroy (RRCrtcPtr crtc)
-{
-    FreeResource (crtc->id, 0);
-}
-
-static int
-RRCrtcDestroyResource (pointer value, XID pid)
-{
-    RRCrtcPtr	crtc = (RRCrtcPtr) value;
-    ScreenPtr	pScreen = crtc->pScreen;
-
-    if (pScreen)
-    {
-	rrScrPriv(pScreen);
-	int		i;
-    
-	for (i = 0; i < pScrPriv->numCrtcs; i++)
-	{
-	    if (pScrPriv->crtcs[i] == crtc)
-	    {
-		memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
-			 (pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr));
-		--pScrPriv->numCrtcs;
-		break;
-	    }
-	}
-    }
-    free(crtc->gammaRed);
-    if (crtc->mode)
-	RRModeDestroy (crtc->mode);
-    free(crtc);
-    return 1;
-}
-
-/*
- * Request that the Crtc gamma be changed
- */
-
-Bool
-RRCrtcGammaSet (RRCrtcPtr   crtc,
-		CARD16	    *red,
-		CARD16	    *green,
-		CARD16	    *blue)
-{
-    Bool	ret = TRUE;
-#if RANDR_12_INTERFACE
-    ScreenPtr	pScreen = crtc->pScreen;
-#endif
-    
-    memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16));
-    memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16));
-    memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16));
-#if RANDR_12_INTERFACE
-    if (pScreen)
-    {
-	rrScrPriv(pScreen);
-	if (pScrPriv->rrCrtcSetGamma)
-	    ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc);
-    }
-#endif
-    return ret;
-}
-
-/*
- * Request current gamma back from the DDX (if possible).
- * This includes gamma size.
- */
-Bool
-RRCrtcGammaGet(RRCrtcPtr crtc)
-{
-    Bool ret = TRUE;
-#if RANDR_12_INTERFACE
-    ScreenPtr	pScreen = crtc->pScreen;
-#endif
-
-#if RANDR_12_INTERFACE
-    if (pScreen)
-    {
-        rrScrPriv(pScreen);
-        if (pScrPriv->rrCrtcGetGamma)
-            ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc);
-    }
-#endif
-    return ret;
-}
-
-/*
- * Notify the extension that the Crtc gamma has been changed
- * The driver calls this whenever it has changed the gamma values
- * in the RRCrtcRec
- */
-
-Bool
-RRCrtcGammaNotify (RRCrtcPtr	crtc)
-{
-    return TRUE;    /* not much going on here */
-}
-
-static void
-RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform,
-		      int *width, int *height)
-{
-    BoxRec  box;
-
-    if (mode == NULL) {
-	*width = 0;
-	*height = 0;
-	return;
-    }
-
-    box.x1 = 0;
-    box.y1 = 0;
-    box.x2 = mode->mode.width;
-    box.y2 = mode->mode.height;
-
-    pixman_transform_bounds (transform, &box);
-    *width = box.x2 - box.x1;
-    *height = box.y2 - box.y1;
-}
-
-/**
- * Returns the width/height that the crtc scans out from the framebuffer
- */
-void
-RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
-{
-    return RRModeGetScanoutSize (crtc->mode, &crtc->transform, width, height);
-}
-
-/*
- * Set the size of the gamma table at server startup time
- */
-
-Bool
-RRCrtcGammaSetSize (RRCrtcPtr	crtc,
-		    int		size)
-{
-    CARD16  *gamma;
-
-    if (size == crtc->gammaSize)
-	return TRUE;
-    if (size)
-    {
-	gamma = malloc(size * 3 * sizeof (CARD16));
-	if (!gamma)
-	    return FALSE;
-    }
-    else
-	gamma = NULL;
-    free(crtc->gammaRed);
-    crtc->gammaRed = gamma;
-    crtc->gammaGreen = gamma + size;
-    crtc->gammaBlue = gamma + size*2;
-    crtc->gammaSize = size;
-    return TRUE;
-}
-
-/*
- * Set the pending CRTC transformation
- */
-
-int
-RRCrtcTransformSet (RRCrtcPtr		crtc,
-		    PictTransformPtr	transform,
-		    struct pixman_f_transform *f_transform,
-		    struct pixman_f_transform *f_inverse,
-		    char		*filter_name,
-		    int			filter_len,
-		    xFixed		*params,
-		    int			nparams)
-{
-    PictFilterPtr   filter = NULL;
-    int		    width = 0, height = 0;
-
-    if (!crtc->transforms)
-	return BadValue;
-
-    if (filter_len)
-    {
-	filter = PictureFindFilter (crtc->pScreen,
-				    filter_name,
-				    filter_len);
-	if (!filter)
-	    return BadName;
-	if (filter->ValidateParams)
-	{
-	    if (!filter->ValidateParams (crtc->pScreen, filter->id,
-					 params, nparams, &width, &height))
-		return BadMatch;
-	}
-	else {
-	    width = filter->width;
-	    height = filter->height;
-	}
-    }
-    else
-    {
-	if (nparams)
-	    return BadMatch;
-    }
-    if (!RRTransformSetFilter (&crtc->client_pending_transform,
-			       filter, params, nparams, width, height))
-	return BadAlloc;
-
-    crtc->client_pending_transform.transform = *transform;
-    crtc->client_pending_transform.f_transform = *f_transform;
-    crtc->client_pending_transform.f_inverse = *f_inverse;
-    return Success;
-}
-
-/*
- * Initialize crtc type
- */
-Bool
-RRCrtcInit (void)
-{
-    RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource, "CRTC");
-    if (!RRCrtcType)
-	return FALSE;
-    
-    return TRUE;
-}
-
-/*
- * Initialize crtc type error value
- */
-void
-RRCrtcInitErrorValue(void)
-{
-    SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc);
-}
-
-int
-ProcRRGetCrtcInfo (ClientPtr client)
-{
-    REQUEST(xRRGetCrtcInfoReq);
-    xRRGetCrtcInfoReply	rep;
-    RRCrtcPtr			crtc;
-    CARD8			*extra;
-    unsigned long		extraLen;
-    ScreenPtr			pScreen;
-    rrScrPrivPtr		pScrPriv;
-    RRModePtr			mode;
-    RROutput			*outputs;
-    RROutput			*possible;
-    int				i, j, k, n;
-    int				width, height;
-    BoxRec			panned_area;
-    
-    REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
-    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-
-    /* All crtcs must be associated with screens before client
-     * requests are processed
-     */
-    pScreen = crtc->pScreen;
-    pScrPriv = rrGetScrPriv(pScreen);
-
-    mode = crtc->mode;
-    
-    rep.type = X_Reply;
-    rep.status = RRSetConfigSuccess;
-    rep.sequenceNumber = client->sequence;
-    rep.length = 0;
-    rep.timestamp = pScrPriv->lastSetTime.milliseconds;
-    if (pScrPriv->rrGetPanning &&
-	pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) &&
-	(panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1))
-    {
- 	rep.x = panned_area.x1;
-	rep.y = panned_area.y1;
-	rep.width = panned_area.x2 - panned_area.x1;
-	rep.height = panned_area.y2 - panned_area.y1;
-    }
-    else
-    {
-	RRCrtcGetScanoutSize (crtc, &width, &height);
-	rep.x = crtc->x;
-	rep.y = crtc->y;
-	rep.width = width;
-	rep.height = height;
-    }
-    rep.mode = mode ? mode->mode.id : 0;
-    rep.rotation = crtc->rotation;
-    rep.rotations = crtc->rotations;
-    rep.nOutput = crtc->numOutputs;
-    k = 0;
-    for (i = 0; i < pScrPriv->numOutputs; i++)
-	for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
-	    if (pScrPriv->outputs[i]->crtcs[j] == crtc)
-		k++;
-    rep.nPossibleOutput = k;
-    
-    rep.length = rep.nOutput + rep.nPossibleOutput;
-
-    extraLen = rep.length << 2;
-    if (extraLen)
-    {
-	extra = malloc(extraLen);
-	if (!extra)
-	    return BadAlloc;
-    }
-    else
-	extra = NULL;
-
-    outputs = (RROutput *) extra;
-    possible = (RROutput *) (outputs + rep.nOutput);
-    
-    for (i = 0; i < crtc->numOutputs; i++)
-    {
-	outputs[i] = crtc->outputs[i]->id;
-	if (client->swapped)
-	    swapl (&outputs[i], n);
-    }
-    k = 0;
-    for (i = 0; i < pScrPriv->numOutputs; i++)
-	for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
-	    if (pScrPriv->outputs[i]->crtcs[j] == crtc)
-	    {
-		possible[k] = pScrPriv->outputs[i]->id;
-		if (client->swapped)
-		    swapl (&possible[k], n);
-		k++;
-	    }
-    
-    if (client->swapped) {
-	swaps(&rep.sequenceNumber, n);
-	swapl(&rep.length, n);
-	swapl(&rep.timestamp, n);
-	swaps(&rep.x, n);
-	swaps(&rep.y, n);
-	swaps(&rep.width, n);
-	swaps(&rep.height, n);
-	swapl(&rep.mode, n);
-	swaps(&rep.rotation, n);
-	swaps(&rep.rotations, n);
-	swaps(&rep.nOutput, n);
-	swaps(&rep.nPossibleOutput, n);
-    }
-    WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep);
-    if (extraLen)
-    {
-	WriteToClient (client, extraLen, (char *) extra);
-	free(extra);
-    }
-    
-    return Success;
-}
-
-int
-ProcRRSetCrtcConfig (ClientPtr client)
-{
-    REQUEST(xRRSetCrtcConfigReq);
-    xRRSetCrtcConfigReply   rep;
-    ScreenPtr		    pScreen;
-    rrScrPrivPtr	    pScrPriv;
-    RRCrtcPtr		    crtc;
-    RRModePtr		    mode;
-    int			    numOutputs;
-    RROutputPtr		    *outputs = NULL;
-    RROutput		    *outputIds;
-    TimeStamp		    configTime;
-    TimeStamp		    time;
-    Rotation		    rotation;
-    int			    rc, i, j;
-    
-    REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
-    numOutputs = (stuff->length - bytes_to_int32(SIZEOF (xRRSetCrtcConfigReq)));
-    
-    VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);
-
-    if (stuff->mode == None)
-    {
-	mode = NULL;
-	if (numOutputs > 0)
-	    return BadMatch;
-    }
-    else
-    {
-	VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess);
-	if (numOutputs == 0)
-	    return BadMatch;
-    }
-    if (numOutputs)
-    {
-	outputs = malloc(numOutputs * sizeof (RROutputPtr));
-	if (!outputs)
-	    return BadAlloc;
-    }
-    else
-	outputs = NULL;
-    
-    outputIds = (RROutput *) (stuff + 1);
-    for (i = 0; i < numOutputs; i++)
-    {
-	rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i],
-				     RROutputType, client, DixSetAttrAccess);
-	if (rc != Success)
-	{
-	    free(outputs);
-	    return rc;
-	}
-	/* validate crtc for this output */
-	for (j = 0; j < outputs[i]->numCrtcs; j++)
-	    if (outputs[i]->crtcs[j] == crtc)
-		break;
-	if (j == outputs[i]->numCrtcs)
-	{
-	    free(outputs);
-	    return BadMatch;
-	}
-	/* validate mode for this output */
-	for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
-	{
-	    RRModePtr	m = (j < outputs[i]->numModes ? 
-			     outputs[i]->modes[j] :
-			     outputs[i]->userModes[j - outputs[i]->numModes]);
-	    if (m == mode)
-		break;
-	}
-	if (j == outputs[i]->numModes + outputs[i]->numUserModes)
-	{
-	    free(outputs);
-	    return BadMatch;
-	}
-    }
-    /* validate clones */
-    for (i = 0; i < numOutputs; i++)
-    {
-	for (j = 0; j < numOutputs; j++)
-	{
-	    int k;
-	    if (i == j)
-		continue;
-	    for (k = 0; k < outputs[i]->numClones; k++)
-	    {
-		if (outputs[i]->clones[k] == outputs[j])
-		    break;
-	    }
-	    if (k == outputs[i]->numClones)
-	    {
-		free(outputs);
-		return BadMatch;
-	    }
-	}
-    }
-
-    pScreen = crtc->pScreen;
-    pScrPriv = rrGetScrPriv(pScreen);
-    
-    time = ClientTimeToServerTime(stuff->timestamp);
-    configTime = ClientTimeToServerTime(stuff->configTimestamp);
-    
-    if (!pScrPriv)
-    {
-	time = currentTime;
-	rep.status = RRSetConfigFailed;
-	goto sendReply;
-    }
-    
-    /*
-     * Validate requested rotation
-     */
-    rotation = (Rotation) stuff->rotation;
-
-    /* test the rotation bits only! */
-    switch (rotation & 0xf) {
-    case RR_Rotate_0:
-    case RR_Rotate_90:
-    case RR_Rotate_180:
-    case RR_Rotate_270:
-	break;
-    default:
-	/*
-	 * Invalid rotation
-	 */
-	client->errorValue = stuff->rotation;
-	free(outputs);
-	return BadValue;
-    }
-
-    if (mode)
-    {
-	if ((~crtc->rotations) & rotation)
-	{
-	    /*
-	     * requested rotation or reflection not supported by screen
-	     */
-	    client->errorValue = stuff->rotation;
-	    free(outputs);
-	    return BadMatch;
-	}
-    
-#ifdef RANDR_12_INTERFACE
-	/*
-	 * Check screen size bounds if the DDX provides a 1.2 interface
-	 * for setting screen size. Else, assume the CrtcSet sets
-	 * the size along with the mode. If the driver supports transforms,
-	 * then it must allow crtcs to display a subset of the screen, so
-	 * only do this check for drivers without transform support.
-	 */
-	if (pScrPriv->rrScreenSetSize && !crtc->transforms)
-	{
-	    int source_width;
-	    int	source_height;
-	    PictTransform transform;
-	    struct pixman_f_transform f_transform, f_inverse;
-
-	    RRTransformCompute (stuff->x, stuff->y,
-				mode->mode.width, mode->mode.height,
-				rotation,
-				&crtc->client_pending_transform,
-				&transform, &f_transform, &f_inverse);
-
-	    RRModeGetScanoutSize (mode, &transform, &source_width, &source_height);
-	    if (stuff->x + source_width > pScreen->width)
-	    {
-		client->errorValue = stuff->x;
-		free(outputs);
-		return BadValue;
-	    }
-	    
-	    if (stuff->y + source_height > pScreen->height)
-	    {
-		client->errorValue = stuff->y;
-		free(outputs);
-		return BadValue;
-	    }
-	}
-#endif
-    }
-    
-    if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y,
-		   rotation, numOutputs, outputs))
-    {
-	rep.status = RRSetConfigFailed;
-	goto sendReply;
-    }
-    rep.status = RRSetConfigSuccess;
-    pScrPriv->lastSetTime = time;
-    
-sendReply:
-    free(outputs);
-    
-    rep.type = X_Reply;
-    /* rep.status has already been filled in */
-    rep.length = 0;
-    rep.sequenceNumber = client->sequence;
-    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
-
-    if (client->swapped) 
-    {
-	int n;
-    	swaps(&rep.sequenceNumber, n);
-    	swapl(&rep.length, n);
-	swapl(&rep.newTimestamp, n);
-    }
-    WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep);
-    
-    return Success;
-}
-
-int
-ProcRRGetPanning (ClientPtr client)
-{
-    REQUEST(xRRGetPanningReq);
-    xRRGetPanningReply	rep;
-    RRCrtcPtr		crtc;
-    ScreenPtr		pScreen;
-    rrScrPrivPtr	pScrPriv;
-    BoxRec		total;
-    BoxRec		tracking;
-    INT16		border[4];
-    int			n;
-    
-    REQUEST_SIZE_MATCH(xRRGetPanningReq);
-    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-
-    /* All crtcs must be associated with screens before client
-     * requests are processed
-     */
-    pScreen = crtc->pScreen;
-    pScrPriv = rrGetScrPriv(pScreen);
-
-    if (!pScrPriv)
-	return RRErrorBase + BadRRCrtc;
-
-    memset(&rep, 0, sizeof(rep));
-    rep.type = X_Reply;
-    rep.status = RRSetConfigSuccess;
-    rep.sequenceNumber = client->sequence;
-    rep.length = 1;
-    rep.timestamp = pScrPriv->lastSetTime.milliseconds;
-
-    if (pScrPriv->rrGetPanning &&
-	pScrPriv->rrGetPanning (pScreen, crtc, &total, &tracking, border)) {
-	rep.left          = total.x1;
-	rep.top           = total.y1;
-	rep.width         = total.x2 - total.x1;
-	rep.height        = total.y2 - total.y1;
-	rep.track_left    = tracking.x1;
-	rep.track_top     = tracking.y1;
-	rep.track_width   = tracking.x2 - tracking.x1;
-	rep.track_height  = tracking.y2 - tracking.y1;
-	rep.border_left   = border[0];
-	rep.border_top    = border[1];
-	rep.border_right  = border[2];
-	rep.border_bottom = border[3];
-    }
-
-    if (client->swapped) {
-	swaps(&rep.sequenceNumber, n);
-	swapl(&rep.length, n);
-	swaps(&rep.timestamp, n);
-	swaps(&rep.left, n);
-	swaps(&rep.top, n);
-	swaps(&rep.width, n);
-	swaps(&rep.height, n);
-	swaps(&rep.track_left, n);
-	swaps(&rep.track_top, n);
-	swaps(&rep.track_width, n);
-	swaps(&rep.track_height, n);
-	swaps(&rep.border_left, n);
-	swaps(&rep.border_top, n);
-	swaps(&rep.border_right, n);
-	swaps(&rep.border_bottom, n);
-    }
-    WriteToClient(client, sizeof(xRRGetPanningReply), (char *)&rep);
-    return Success;
-}
-
-int
-ProcRRSetPanning (ClientPtr client)
-{
-    REQUEST(xRRSetPanningReq);
-    xRRSetPanningReply	rep;
-    RRCrtcPtr		crtc;
-    ScreenPtr		pScreen;
-    rrScrPrivPtr	pScrPriv;
-    TimeStamp		time;
-    BoxRec		total;
-    BoxRec		tracking;
-    INT16		border[4];
-    int			n;
-    
-    REQUEST_SIZE_MATCH(xRRSetPanningReq);
-    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-
-    /* All crtcs must be associated with screens before client
-     * requests are processed
-     */
-    pScreen = crtc->pScreen;
-    pScrPriv = rrGetScrPriv(pScreen);
-
-    if (!pScrPriv) {
-	time = currentTime;
-	rep.status = RRSetConfigFailed;
-	goto sendReply;
-    }
-    
-    time = ClientTimeToServerTime(stuff->timestamp);
-    
-    if (!pScrPriv->rrGetPanning)
-	return RRErrorBase + BadRRCrtc;
-
-    total.x1    = stuff->left;
-    total.y1    = stuff->top;
-    total.x2    = total.x1 + stuff->width;
-    total.y2    = total.y1 + stuff->height;
-    tracking.x1 = stuff->track_left;
-    tracking.y1 = stuff->track_top;
-    tracking.x2 = tracking.x1 + stuff->track_width;
-    tracking.y2 = tracking.y1 + stuff->track_height;
-    border[0]   = stuff->border_left;
-    border[1]   = stuff->border_top;
-    border[2]   = stuff->border_right;
-    border[3]   = stuff->border_bottom;
-
-    if (! pScrPriv->rrSetPanning (pScreen, crtc, &total, &tracking, border))
-	return BadMatch;
-
-    pScrPriv->lastSetTime = time;
-
-    rep.status = RRSetConfigSuccess;
-
-sendReply:
-    rep.type = X_Reply;
-    rep.sequenceNumber = client->sequence;
-    rep.length = 0;
-    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
-
-    if (client->swapped) {
-	swaps(&rep.sequenceNumber, n);
-	swapl(&rep.length, n);
-	swaps(&rep.newTimestamp, n);
-    }
-    WriteToClient(client, sizeof(xRRSetPanningReply), (char *)&rep);
-    return Success;
-}
-
-int
-ProcRRGetCrtcGammaSize (ClientPtr client)
-{
-    REQUEST(xRRGetCrtcGammaSizeReq);
-    xRRGetCrtcGammaSizeReply	reply;
-    RRCrtcPtr			crtc;
-    int				n;
-
-    REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
-    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-
-    /* Gamma retrieval failed, any better error? */
-    if (!RRCrtcGammaGet(crtc))
-        return RRErrorBase + BadRRCrtc;
-
-    reply.type = X_Reply;
-    reply.sequenceNumber = client->sequence;
-    reply.length = 0;
-    reply.size = crtc->gammaSize;
-    if (client->swapped) {
-	swaps (&reply.sequenceNumber, n);
-	swapl (&reply.length, n);
-	swaps (&reply.size, n);
-    }
-    WriteToClient (client, sizeof (xRRGetCrtcGammaSizeReply), (char *) &reply);
-    return Success;
-}
-
-int
-ProcRRGetCrtcGamma (ClientPtr client)
-{
-    REQUEST(xRRGetCrtcGammaReq);
-    xRRGetCrtcGammaReply	reply;
-    RRCrtcPtr			crtc;
-    int				n;
-    unsigned long		len;
-    char			*extra = NULL;
-    
-    REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
-    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-
-    /* Gamma retrieval failed, any better error? */
-    if (!RRCrtcGammaGet(crtc))
-        return RRErrorBase + BadRRCrtc;
-
-    len = crtc->gammaSize * 3 * 2;
-    
-    if (crtc->gammaSize) {
-	extra = malloc(len);
-	if (!extra)
-	    return BadAlloc;
-    }
-
-    reply.type = X_Reply;
-    reply.sequenceNumber = client->sequence;
-    reply.length = bytes_to_int32(len);
-    reply.size = crtc->gammaSize;
-    if (client->swapped) {
-	swaps (&reply.sequenceNumber, n);
-	swapl (&reply.length, n);
-	swaps (&reply.size, n);
-    }
-    WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply);
-    if (crtc->gammaSize)
-    {
-	memcpy(extra, crtc->gammaRed, len);
-	client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write;
-	WriteSwappedDataToClient (client, len, extra);
-	free(extra);
-    }
-    return Success;
-}
-
-int
-ProcRRSetCrtcGamma (ClientPtr client)
-{
-    REQUEST(xRRSetCrtcGammaReq);
-    RRCrtcPtr			crtc;
-    unsigned long		len;
-    CARD16			*red, *green, *blue;
-    
-    REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
-    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-    
-    len = client->req_len - bytes_to_int32(sizeof (xRRSetCrtcGammaReq));
-    if (len < (stuff->size * 3 + 1) >> 1)
-	return BadLength;
-
-    if (stuff->size != crtc->gammaSize)
-	return BadMatch;
-    
-    red = (CARD16 *) (stuff + 1);
-    green = red + crtc->gammaSize;
-    blue = green + crtc->gammaSize;
-    
-    RRCrtcGammaSet (crtc, red, green, blue);
-
-    return Success;
-}
-
-/* Version 1.3 additions */
-
-int
-ProcRRSetCrtcTransform (ClientPtr client)
-{
-    REQUEST(xRRSetCrtcTransformReq);
-    RRCrtcPtr		    crtc;
-    PictTransform	    transform;
-    struct pixman_f_transform f_transform, f_inverse;
-    char		    *filter;
-    int			    nbytes;
-    xFixed		    *params;
-    int			    nparams;
-
-    REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
-    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-
-    PictTransform_from_xRenderTransform (&transform, &stuff->transform);
-    pixman_f_transform_from_pixman_transform (&f_transform, &transform);
-    if (!pixman_f_transform_invert (&f_inverse, &f_transform))
-	return BadMatch;
-
-    filter = (char *) (stuff + 1);
-    nbytes = stuff->nbytesFilter;
-    params = (xFixed *) (filter + pad_to_int32(nbytes));
-    nparams = ((xFixed *) stuff + client->req_len) - params;
-    if (nparams < 0)
-	return BadLength;
-
-    return RRCrtcTransformSet (crtc, &transform, &f_transform, &f_inverse,
-			       filter, nbytes, params, nparams);
-}
-
-
-#define CrtcTransformExtra	(SIZEOF(xRRGetCrtcTransformReply) - 32)
-				
-static int
-transform_filter_length (RRTransformPtr transform)
-{
-    int	nbytes, nparams;
-
-    if (transform->filter == NULL)
-	return 0;
-    nbytes = strlen (transform->filter->name);
-    nparams = transform->nparams;
-    return pad_to_int32(nbytes) + (nparams * sizeof (xFixed));
-}
-
-static int
-transform_filter_encode (ClientPtr client, char *output,
-			 CARD16	*nbytesFilter,
-			 CARD16	*nparamsFilter,
-			 RRTransformPtr transform)
-{
-    int	    nbytes, nparams;
-    int	    n;
-
-    if (transform->filter == NULL) {
-	*nbytesFilter = 0;
-	*nparamsFilter = 0;
-	return 0;
-    }
-    nbytes = strlen (transform->filter->name);
-    nparams = transform->nparams;
-    *nbytesFilter = nbytes;
-    *nparamsFilter = nparams;
-    memcpy (output, transform->filter->name, nbytes);
-    while ((nbytes & 3) != 0)
-	output[nbytes++] = 0;
-    memcpy (output + nbytes, transform->params, nparams * sizeof (xFixed));
-    if (client->swapped) {
-	swaps (nbytesFilter, n);
-	swaps (nparamsFilter, n);
-	SwapLongs ((CARD32 *) (output + nbytes), nparams);
-    }
-    nbytes += nparams * sizeof (xFixed);
-    return nbytes;
-}
-
-static void
-transform_encode (ClientPtr client, xRenderTransform *wire, PictTransform *pict)
-{
-    xRenderTransform_from_PictTransform (wire, pict);
-    if (client->swapped)
-	SwapLongs ((CARD32 *) wire, bytes_to_int32(sizeof(xRenderTransform)));
-}
-
-int
-ProcRRGetCrtcTransform (ClientPtr client)
-{
-    REQUEST(xRRGetCrtcTransformReq);
-    xRRGetCrtcTransformReply	*reply;
-    RRCrtcPtr			crtc;
-    int				n, nextra;
-    RRTransformPtr		current, pending;
-    char			*extra;
-
-    REQUEST_SIZE_MATCH (xRRGetCrtcTransformReq);
-    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-
-    pending = &crtc->client_pending_transform;
-    current = &crtc->client_current_transform;
-
-    nextra = (transform_filter_length (pending) +
-	      transform_filter_length (current));
-
-    reply = malloc(sizeof (xRRGetCrtcTransformReply) + nextra);
-    if (!reply)
-	return BadAlloc;
-
-    extra = (char *) (reply + 1);
-    reply->type = X_Reply;
-    reply->sequenceNumber = client->sequence;
-    reply->length = bytes_to_int32(CrtcTransformExtra + nextra);
-
-    reply->hasTransforms = crtc->transforms;
-
-    transform_encode (client, &reply->pendingTransform, &pending->transform);
-    extra += transform_filter_encode (client, extra,
-				      &reply->pendingNbytesFilter,
-				      &reply->pendingNparamsFilter,
-				      pending);
-
-    transform_encode (client, &reply->currentTransform, &current->transform);
-    extra += transform_filter_encode (client, extra,
-				      &reply->currentNbytesFilter,
-				      &reply->currentNparamsFilter,
-				      current);
-
-    if (client->swapped) {
-	swaps (&reply->sequenceNumber, n);
-	swapl (&reply->length, n);
-    }
-    WriteToClient (client, sizeof (xRRGetCrtcTransformReply) + nextra, (char *) reply);
-    free(reply);
-    return Success;
-}
+/*
+ * Copyright © 2006 Keith Packard
+ * Copyright 2010 Red Hat, Inc
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+#include "mipointer.h"
+
+RESTYPE	RRCrtcType;
+
+/*
+ * Notify the CRTC of some change
+ */
+void
+RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
+{
+    ScreenPtr	pScreen = crtc->pScreen;
+
+    crtc->changed = TRUE;
+    if (pScreen)
+    {
+	rrScrPriv(pScreen);
+    
+	pScrPriv->changed = TRUE;
+	/*
+	 * Send ConfigureNotify on any layout change
+	 */
+	if (layoutChanged)
+	    pScrPriv->layoutChanged = TRUE;
+    }
+}
+
+/*
+ * Create a CRTC
+ */
+RRCrtcPtr
+RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
+{
+    RRCrtcPtr	    crtc;
+    RRCrtcPtr	    *crtcs;
+    rrScrPrivPtr    pScrPriv;
+
+    if (!RRInit())
+	return NULL;
+    
+    pScrPriv = rrGetScrPriv(pScreen);
+
+    /* make space for the crtc pointer */
+    if (pScrPriv->numCrtcs)
+	crtcs = realloc(pScrPriv->crtcs, 
+			  (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
+    else
+	crtcs = malloc(sizeof (RRCrtcPtr));
+    if (!crtcs)
+	return FALSE;
+    pScrPriv->crtcs = crtcs;
+    
+    crtc = calloc(1, sizeof (RRCrtcRec));
+    if (!crtc)
+	return NULL;
+    crtc->id = FakeClientID (0);
+    crtc->pScreen = pScreen;
+    crtc->mode = NULL;
+    crtc->x = 0;
+    crtc->y = 0;
+    crtc->rotation = RR_Rotate_0;
+    crtc->rotations = RR_Rotate_0;
+    crtc->outputs = NULL;
+    crtc->numOutputs = 0;
+    crtc->gammaSize = 0;
+    crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
+    crtc->changed = FALSE;
+    crtc->devPrivate = devPrivate;
+    RRTransformInit (&crtc->client_pending_transform);
+    RRTransformInit (&crtc->client_current_transform);
+    pixman_transform_init_identity (&crtc->transform);
+    pixman_f_transform_init_identity (&crtc->f_transform);
+    pixman_f_transform_init_identity (&crtc->f_inverse);
+
+    if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
+	return NULL;
+
+    /* attach the screen and crtc together */
+    crtc->pScreen = pScreen;
+    pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
+    
+    return crtc;
+}
+
+/*
+ * Set the allowed rotations on a CRTC
+ */
+void
+RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations)
+{
+    crtc->rotations = rotations;
+}
+
+/*
+ * Set whether transforms are allowed on a CRTC
+ */
+void
+RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms)
+{
+    crtc->transforms = transforms;
+}
+
+/*
+ * Notify the extension that the Crtc has been reconfigured,
+ * the driver calls this whenever it has updated the mode
+ */
+Bool
+RRCrtcNotify (RRCrtcPtr	    crtc,
+	      RRModePtr	    mode,
+	      int	    x,
+	      int	    y,
+	      Rotation	    rotation,
+	      RRTransformPtr transform,
+	      int	    numOutputs,
+	      RROutputPtr   *outputs)
+{
+    int	    i, j;
+    
+    /*
+     * Check to see if any of the new outputs were
+     * not in the old list and mark them as changed
+     */
+    for (i = 0; i < numOutputs; i++)
+    {
+	for (j = 0; j < crtc->numOutputs; j++)
+	    if (outputs[i] == crtc->outputs[j])
+		break;
+	if (j == crtc->numOutputs)
+	{
+	    outputs[i]->crtc = crtc;
+	    RROutputChanged (outputs[i], FALSE);
+	    RRCrtcChanged (crtc, FALSE);
+	}
+    }
+    /*
+     * Check to see if any of the old outputs are
+     * not in the new list and mark them as changed
+     */
+    for (j = 0; j < crtc->numOutputs; j++)
+    {
+	for (i = 0; i < numOutputs; i++)
+	    if (outputs[i] == crtc->outputs[j])
+		break;
+	if (i == numOutputs)
+	{
+	    if (crtc->outputs[j]->crtc == crtc)
+		crtc->outputs[j]->crtc = NULL;
+	    RROutputChanged (crtc->outputs[j], FALSE);
+	    RRCrtcChanged (crtc, FALSE);
+	}
+    }
+    /*
+     * Reallocate the crtc output array if necessary
+     */
+    if (numOutputs != crtc->numOutputs)
+    {
+	RROutputPtr *newoutputs;
+	
+	if (numOutputs)
+	{
+	    if (crtc->numOutputs)
+		newoutputs = realloc(crtc->outputs,
+				    numOutputs * sizeof (RROutputPtr));
+	    else
+		newoutputs = malloc(numOutputs * sizeof (RROutputPtr));
+	    if (!newoutputs)
+		return FALSE;
+	}
+	else
+	{
+	    free(crtc->outputs);
+	    newoutputs = NULL;
+	}
+	crtc->outputs = newoutputs;
+	crtc->numOutputs = numOutputs;
+    }
+    /*
+     * Copy the new list of outputs into the crtc
+     */
+    memcpy (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr));
+    /*
+     * Update remaining crtc fields
+     */
+    if (mode != crtc->mode)
+    {
+	if (crtc->mode)
+	    RRModeDestroy (crtc->mode);
+	crtc->mode = mode;
+	if (mode != NULL)
+	    mode->refcnt++;
+	RRCrtcChanged (crtc, TRUE);
+    }
+    if (x != crtc->x)
+    {
+	crtc->x = x;
+	RRCrtcChanged (crtc, TRUE);
+    }
+    if (y != crtc->y)
+    {
+	crtc->y = y;
+	RRCrtcChanged (crtc, TRUE);
+    }
+    if (rotation != crtc->rotation)
+    {
+	crtc->rotation = rotation;
+	RRCrtcChanged (crtc, TRUE);
+    }
+    if (!RRTransformEqual (transform, &crtc->client_current_transform)) {
+	RRTransformCopy (&crtc->client_current_transform, transform);
+	RRCrtcChanged (crtc, TRUE);
+    }
+    if (crtc->changed && mode)
+    {
+	RRTransformCompute (x, y,
+			    mode->mode.width, mode->mode.height,
+			    rotation,
+			    &crtc->client_current_transform,
+			    &crtc->transform, &crtc->f_transform,
+			    &crtc->f_inverse);
+    }
+    return TRUE;
+}
+
+void
+RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    rrScrPriv (pScreen);
+    xRRCrtcChangeNotifyEvent	ce;
+    RRModePtr	mode = crtc->mode;
+    
+    ce.type = RRNotify + RREventBase;
+    ce.subCode = RRNotify_CrtcChange;
+    ce.timestamp = pScrPriv->lastSetTime.milliseconds;
+    ce.window = pWin->drawable.id;
+    ce.crtc = crtc->id;
+    ce.rotation = crtc->rotation;
+    if (mode)
+    {
+	ce.mode = mode->mode.id;
+	ce.x = crtc->x;
+	ce.y = crtc->y;
+	ce.width = mode->mode.width;
+	ce.height = mode->mode.height;
+    }
+    else
+    {
+	ce.mode = None;
+	ce.x = 0;
+	ce.y = 0;
+	ce.width = 0;
+	ce.height = 0;
+    }
+    WriteEventsToClient (client, 1, (xEvent *) &ce);
+}
+
+static Bool
+RRCrtcPendingProperties (RRCrtcPtr crtc)
+{
+    ScreenPtr	pScreen = crtc->pScreen;
+    rrScrPriv(pScreen);
+    int		o;
+
+    for (o = 0; o < pScrPriv->numOutputs; o++)
+    {
+	RROutputPtr output = pScrPriv->outputs[o];
+	if (output->crtc == crtc && output->pendingProperties)
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+static void
+crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
+{
+    *left = crtc->x;
+    *top = crtc->y;
+
+    switch (crtc->rotation) {
+    case RR_Rotate_0:
+    case RR_Rotate_180:
+    default:
+       *right = crtc->x + crtc->mode->mode.width;
+       *bottom = crtc->y + crtc->mode->mode.height;
+       return;
+    case RR_Rotate_90:
+    case RR_Rotate_270:
+       *right = crtc->x + crtc->mode->mode.height;
+       *bottom = crtc->y + crtc->mode->mode.width;
+       return;
+    }
+}
+
+/* overlapping counts as adjacent */
+static Bool
+crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b)
+{
+    /* left, right, top, bottom... */
+    int al, ar, at, ab;
+    int bl, br, bt, bb;
+    int cl, cr, ct, cb; /* the overlap, if any */
+
+    crtc_bounds(a, &al, &ar, &at, &ab);
+    crtc_bounds(b, &bl, &br, &bt, &bb);
+
+    cl = max(al, bl);
+    cr = min(ar, br);
+    ct = max(at, bt);
+    cb = min(ab, bb);
+
+    return (cl <= cr) && (ct <= cb);
+}
+
+/* Depth-first search and mark all CRTCs reachable from cur */
+static void
+mark_crtcs (rrScrPrivPtr pScrPriv, int *reachable, int cur)
+{
+    int i;
+    reachable[cur] = TRUE;
+    for (i = 0; i < pScrPriv->numCrtcs; ++i) {
+        if (reachable[i] || !pScrPriv->crtcs[i]->mode)
+            continue;
+        if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i]))
+            mark_crtcs(pScrPriv, reachable, i);
+    }
+}
+
+static void
+RRComputeContiguity (ScreenPtr pScreen)
+{
+    rrScrPriv(pScreen);
+    Bool discontiguous = TRUE;
+    int i, n = pScrPriv->numCrtcs;
+
+    int *reachable = calloc(n, sizeof(int));
+    if (!reachable)
+        goto out;
+
+    /* Find first enabled CRTC and start search for reachable CRTCs from it */
+    for (i = 0; i < n; ++i) {
+        if (pScrPriv->crtcs[i]->mode) {
+            mark_crtcs(pScrPriv, reachable, i);
+            break;
+        }
+    }
+
+    /* Check that all enabled CRTCs were marked as reachable */
+    for (i = 0; i < n; ++i)
+        if (pScrPriv->crtcs[i]->mode && !reachable[i])
+            goto out;
+
+    discontiguous = FALSE;
+
+out:
+    free(reachable);
+    pScrPriv->discontiguous = discontiguous;
+}
+
+/*
+ * Request that the Crtc be reconfigured
+ */
+Bool
+RRCrtcSet (RRCrtcPtr    crtc,
+	   RRModePtr	mode,
+	   int		x,
+	   int		y,
+	   Rotation	rotation,
+	   int		numOutputs,
+	   RROutputPtr  *outputs)
+{
+    ScreenPtr	pScreen = crtc->pScreen;
+    Bool	ret = FALSE;
+    Bool	recompute = TRUE;
+    rrScrPriv(pScreen);
+
+    /* See if nothing changed */
+    if (crtc->mode == mode &&
+	crtc->x == x &&
+	crtc->y == y &&
+	crtc->rotation == rotation &&
+	crtc->numOutputs == numOutputs &&
+	!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
+	!RRCrtcPendingProperties (crtc) &&
+	!RRCrtcPendingTransform (crtc))
+    {
+	recompute = FALSE;
+	ret = TRUE;
+    }
+    else
+    {
+#if RANDR_12_INTERFACE
+	if (pScrPriv->rrCrtcSet)
+	{
+	    ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, 
+					  rotation, numOutputs, outputs);
+	}
+	else
+#endif
+	{
+#if RANDR_10_INTERFACE
+	    if (pScrPriv->rrSetConfig)
+	    {
+		RRScreenSize	    size;
+		RRScreenRate	    rate;
+
+		if (!mode)
+		{
+		    RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL);
+		    ret = TRUE;
+		}
+		else
+		{
+		    size.width = mode->mode.width;
+		    size.height = mode->mode.height;
+		    if (outputs[0]->mmWidth && outputs[0]->mmHeight)
+		    {
+			size.mmWidth = outputs[0]->mmWidth;
+			size.mmHeight = outputs[0]->mmHeight;
+		    }
+		    else
+		    {
+			size.mmWidth = pScreen->mmWidth;
+			size.mmHeight = pScreen->mmHeight;
+		    }
+		    size.nRates = 1;
+		    rate.rate = RRVerticalRefresh (&mode->mode);
+		    size.pRates = &rate;
+		    ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size);
+		    /*
+		     * Old 1.0 interface tied screen size to mode size
+		     */
+		    if (ret)
+		    {
+			RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs);
+			RRScreenSizeNotify (pScreen);
+		    }
+		}
+	    }
+#endif
+	}
+	if (ret)
+	{
+	    int	o;
+	    RRTellChanged (pScreen);
+
+	    for (o = 0; o < numOutputs; o++)
+		RRPostPendingProperties (outputs[o]);
+	}
+    }
+
+    if (recompute)
+       RRComputeContiguity(pScreen);
+
+    return ret;
+}
+
+/*
+ * Return crtc transform
+ */
+RRTransformPtr
+RRCrtcGetTransform (RRCrtcPtr crtc)
+{
+    RRTransformPtr  transform = &crtc->client_pending_transform;
+
+    if (pixman_transform_is_identity (&transform->transform))
+	return NULL;
+    return transform;
+}
+
+/*
+ * Check whether the pending and current transforms are the same
+ */
+Bool
+RRCrtcPendingTransform (RRCrtcPtr crtc)
+{
+    return memcmp (&crtc->client_current_transform.transform,
+		   &crtc->client_pending_transform.transform,
+		   sizeof (PictTransform)) != 0;
+}
+
+/*
+ * Destroy a Crtc at shutdown
+ */
+void
+RRCrtcDestroy (RRCrtcPtr crtc)
+{
+    FreeResource (crtc->id, 0);
+}
+
+static int
+RRCrtcDestroyResource (pointer value, XID pid)
+{
+    RRCrtcPtr	crtc = (RRCrtcPtr) value;
+    ScreenPtr	pScreen = crtc->pScreen;
+
+    if (pScreen)
+    {
+	rrScrPriv(pScreen);
+	int		i;
+    
+	for (i = 0; i < pScrPriv->numCrtcs; i++)
+	{
+	    if (pScrPriv->crtcs[i] == crtc)
+	    {
+		memmove (pScrPriv->crtcs + i, pScrPriv->crtcs + i + 1,
+			 (pScrPriv->numCrtcs - (i + 1)) * sizeof (RRCrtcPtr));
+		--pScrPriv->numCrtcs;
+		break;
+	    }
+	}
+    }
+    free(crtc->gammaRed);
+    if (crtc->mode)
+	RRModeDestroy (crtc->mode);
+    free(crtc);
+    return 1;
+}
+
+/*
+ * Request that the Crtc gamma be changed
+ */
+
+Bool
+RRCrtcGammaSet (RRCrtcPtr   crtc,
+		CARD16	    *red,
+		CARD16	    *green,
+		CARD16	    *blue)
+{
+    Bool	ret = TRUE;
+#if RANDR_12_INTERFACE
+    ScreenPtr	pScreen = crtc->pScreen;
+#endif
+    
+    memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16));
+    memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16));
+    memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16));
+#if RANDR_12_INTERFACE
+    if (pScreen)
+    {
+	rrScrPriv(pScreen);
+	if (pScrPriv->rrCrtcSetGamma)
+	    ret = (*pScrPriv->rrCrtcSetGamma) (pScreen, crtc);
+    }
+#endif
+    return ret;
+}
+
+/*
+ * Request current gamma back from the DDX (if possible).
+ * This includes gamma size.
+ */
+Bool
+RRCrtcGammaGet(RRCrtcPtr crtc)
+{
+    Bool ret = TRUE;
+#if RANDR_12_INTERFACE
+    ScreenPtr	pScreen = crtc->pScreen;
+#endif
+
+#if RANDR_12_INTERFACE
+    if (pScreen)
+    {
+        rrScrPriv(pScreen);
+        if (pScrPriv->rrCrtcGetGamma)
+            ret = (*pScrPriv->rrCrtcGetGamma) (pScreen, crtc);
+    }
+#endif
+    return ret;
+}
+
+/*
+ * Notify the extension that the Crtc gamma has been changed
+ * The driver calls this whenever it has changed the gamma values
+ * in the RRCrtcRec
+ */
+
+Bool
+RRCrtcGammaNotify (RRCrtcPtr	crtc)
+{
+    return TRUE;    /* not much going on here */
+}
+
+static void
+RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform,
+		      int *width, int *height)
+{
+    BoxRec  box;
+
+    if (mode == NULL) {
+	*width = 0;
+	*height = 0;
+	return;
+    }
+
+    box.x1 = 0;
+    box.y1 = 0;
+    box.x2 = mode->mode.width;
+    box.y2 = mode->mode.height;
+
+    pixman_transform_bounds (transform, &box);
+    *width = box.x2 - box.x1;
+    *height = box.y2 - box.y1;
+}
+
+/**
+ * Returns the width/height that the crtc scans out from the framebuffer
+ */
+void
+RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
+{
+    return RRModeGetScanoutSize (crtc->mode, &crtc->transform, width, height);
+}
+
+/*
+ * Set the size of the gamma table at server startup time
+ */
+
+Bool
+RRCrtcGammaSetSize (RRCrtcPtr	crtc,
+		    int		size)
+{
+    CARD16  *gamma;
+
+    if (size == crtc->gammaSize)
+	return TRUE;
+    if (size)
+    {
+	gamma = malloc(size * 3 * sizeof (CARD16));
+	if (!gamma)
+	    return FALSE;
+    }
+    else
+	gamma = NULL;
+    free(crtc->gammaRed);
+    crtc->gammaRed = gamma;
+    crtc->gammaGreen = gamma + size;
+    crtc->gammaBlue = gamma + size*2;
+    crtc->gammaSize = size;
+    return TRUE;
+}
+
+/*
+ * Set the pending CRTC transformation
+ */
+
+int
+RRCrtcTransformSet (RRCrtcPtr		crtc,
+		    PictTransformPtr	transform,
+		    struct pixman_f_transform *f_transform,
+		    struct pixman_f_transform *f_inverse,
+		    char		*filter_name,
+		    int			filter_len,
+		    xFixed		*params,
+		    int			nparams)
+{
+    PictFilterPtr   filter = NULL;
+    int		    width = 0, height = 0;
+
+    if (!crtc->transforms)
+	return BadValue;
+
+    if (filter_len)
+    {
+	filter = PictureFindFilter (crtc->pScreen,
+				    filter_name,
+				    filter_len);
+	if (!filter)
+	    return BadName;
+	if (filter->ValidateParams)
+	{
+	    if (!filter->ValidateParams (crtc->pScreen, filter->id,
+					 params, nparams, &width, &height))
+		return BadMatch;
+	}
+	else {
+	    width = filter->width;
+	    height = filter->height;
+	}
+    }
+    else
+    {
+	if (nparams)
+	    return BadMatch;
+    }
+    if (!RRTransformSetFilter (&crtc->client_pending_transform,
+			       filter, params, nparams, width, height))
+	return BadAlloc;
+
+    crtc->client_pending_transform.transform = *transform;
+    crtc->client_pending_transform.f_transform = *f_transform;
+    crtc->client_pending_transform.f_inverse = *f_inverse;
+    return Success;
+}
+
+/*
+ * Initialize crtc type
+ */
+Bool
+RRCrtcInit (void)
+{
+    RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource, "CRTC");
+    if (!RRCrtcType)
+	return FALSE;
+    
+    return TRUE;
+}
+
+/*
+ * Initialize crtc type error value
+ */
+void
+RRCrtcInitErrorValue(void)
+{
+    SetResourceTypeErrorValue(RRCrtcType, RRErrorBase + BadRRCrtc);
+}
+
+int
+ProcRRGetCrtcInfo (ClientPtr client)
+{
+    REQUEST(xRRGetCrtcInfoReq);
+    xRRGetCrtcInfoReply	rep;
+    RRCrtcPtr			crtc;
+    CARD8			*extra;
+    unsigned long		extraLen;
+    ScreenPtr			pScreen;
+    rrScrPrivPtr		pScrPriv;
+    RRModePtr			mode;
+    RROutput			*outputs;
+    RROutput			*possible;
+    int				i, j, k, n;
+    int				width, height;
+    BoxRec			panned_area;
+    
+    REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+    /* All crtcs must be associated with screens before client
+     * requests are processed
+     */
+    pScreen = crtc->pScreen;
+    pScrPriv = rrGetScrPriv(pScreen);
+
+    mode = crtc->mode;
+    
+    rep.type = X_Reply;
+    rep.status = RRSetConfigSuccess;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+    if (pScrPriv->rrGetPanning &&
+	pScrPriv->rrGetPanning (pScreen, crtc, &panned_area, NULL, NULL) &&
+	(panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1))
+    {
+ 	rep.x = panned_area.x1;
+	rep.y = panned_area.y1;
+	rep.width = panned_area.x2 - panned_area.x1;
+	rep.height = panned_area.y2 - panned_area.y1;
+    }
+    else
+    {
+	RRCrtcGetScanoutSize (crtc, &width, &height);
+	rep.x = crtc->x;
+	rep.y = crtc->y;
+	rep.width = width;
+	rep.height = height;
+    }
+    rep.mode = mode ? mode->mode.id : 0;
+    rep.rotation = crtc->rotation;
+    rep.rotations = crtc->rotations;
+    rep.nOutput = crtc->numOutputs;
+    k = 0;
+    for (i = 0; i < pScrPriv->numOutputs; i++)
+	for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
+	    if (pScrPriv->outputs[i]->crtcs[j] == crtc)
+		k++;
+    rep.nPossibleOutput = k;
+    
+    rep.length = rep.nOutput + rep.nPossibleOutput;
+
+    extraLen = rep.length << 2;
+    if (extraLen)
+    {
+	extra = malloc(extraLen);
+	if (!extra)
+	    return BadAlloc;
+    }
+    else
+	extra = NULL;
+
+    outputs = (RROutput *) extra;
+    possible = (RROutput *) (outputs + rep.nOutput);
+    
+    for (i = 0; i < crtc->numOutputs; i++)
+    {
+	outputs[i] = crtc->outputs[i]->id;
+	if (client->swapped)
+	    swapl (&outputs[i], n);
+    }
+    k = 0;
+    for (i = 0; i < pScrPriv->numOutputs; i++)
+	for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
+	    if (pScrPriv->outputs[i]->crtcs[j] == crtc)
+	    {
+		possible[k] = pScrPriv->outputs[i]->id;
+		if (client->swapped)
+		    swapl (&possible[k], n);
+		k++;
+	    }
+    
+    if (client->swapped) {
+	swaps(&rep.sequenceNumber, n);
+	swapl(&rep.length, n);
+	swapl(&rep.timestamp, n);
+	swaps(&rep.x, n);
+	swaps(&rep.y, n);
+	swaps(&rep.width, n);
+	swaps(&rep.height, n);
+	swapl(&rep.mode, n);
+	swaps(&rep.rotation, n);
+	swaps(&rep.rotations, n);
+	swaps(&rep.nOutput, n);
+	swaps(&rep.nPossibleOutput, n);
+    }
+    WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *)&rep);
+    if (extraLen)
+    {
+	WriteToClient (client, extraLen, (char *) extra);
+	free(extra);
+    }
+    
+    return Success;
+}
+
+int
+ProcRRSetCrtcConfig (ClientPtr client)
+{
+    REQUEST(xRRSetCrtcConfigReq);
+    xRRSetCrtcConfigReply   rep;
+    ScreenPtr		    pScreen;
+    rrScrPrivPtr	    pScrPriv;
+    RRCrtcPtr		    crtc;
+    RRModePtr		    mode;
+    int			    numOutputs;
+    RROutputPtr		    *outputs = NULL;
+    RROutput		    *outputIds;
+    TimeStamp		    configTime;
+    TimeStamp		    time;
+    Rotation		    rotation;
+    int			    rc, i, j;
+    
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
+    numOutputs = (stuff->length - bytes_to_int32(SIZEOF (xRRSetCrtcConfigReq)));
+    
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);
+
+    if (stuff->mode == None)
+    {
+	mode = NULL;
+	if (numOutputs > 0)
+	    return BadMatch;
+    }
+    else
+    {
+	VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess);
+	if (numOutputs == 0)
+	    return BadMatch;
+    }
+    if (numOutputs)
+    {
+	outputs = malloc(numOutputs * sizeof (RROutputPtr));
+	if (!outputs)
+	    return BadAlloc;
+    }
+    else
+	outputs = NULL;
+    
+    outputIds = (RROutput *) (stuff + 1);
+    for (i = 0; i < numOutputs; i++)
+    {
+	rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i],
+				     RROutputType, client, DixSetAttrAccess);
+	if (rc != Success)
+	{
+	    free(outputs);
+	    return rc;
+	}
+	/* validate crtc for this output */
+	for (j = 0; j < outputs[i]->numCrtcs; j++)
+	    if (outputs[i]->crtcs[j] == crtc)
+		break;
+	if (j == outputs[i]->numCrtcs)
+	{
+	    free(outputs);
+	    return BadMatch;
+	}
+	/* validate mode for this output */
+	for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
+	{
+	    RRModePtr	m = (j < outputs[i]->numModes ? 
+			     outputs[i]->modes[j] :
+			     outputs[i]->userModes[j - outputs[i]->numModes]);
+	    if (m == mode)
+		break;
+	}
+	if (j == outputs[i]->numModes + outputs[i]->numUserModes)
+	{
+	    free(outputs);
+	    return BadMatch;
+	}
+    }
+    /* validate clones */
+    for (i = 0; i < numOutputs; i++)
+    {
+	for (j = 0; j < numOutputs; j++)
+	{
+	    int k;
+	    if (i == j)
+		continue;
+	    for (k = 0; k < outputs[i]->numClones; k++)
+	    {
+		if (outputs[i]->clones[k] == outputs[j])
+		    break;
+	    }
+	    if (k == outputs[i]->numClones)
+	    {
+		free(outputs);
+		return BadMatch;
+	    }
+	}
+    }
+
+    pScreen = crtc->pScreen;
+    pScrPriv = rrGetScrPriv(pScreen);
+    
+    time = ClientTimeToServerTime(stuff->timestamp);
+    configTime = ClientTimeToServerTime(stuff->configTimestamp);
+    
+    if (!pScrPriv)
+    {
+	time = currentTime;
+	rep.status = RRSetConfigFailed;
+	goto sendReply;
+    }
+    
+    /*
+     * Validate requested rotation
+     */
+    rotation = (Rotation) stuff->rotation;
+
+    /* test the rotation bits only! */
+    switch (rotation & 0xf) {
+    case RR_Rotate_0:
+    case RR_Rotate_90:
+    case RR_Rotate_180:
+    case RR_Rotate_270:
+	break;
+    default:
+	/*
+	 * Invalid rotation
+	 */
+	client->errorValue = stuff->rotation;
+	free(outputs);
+	return BadValue;
+    }
+
+    if (mode)
+    {
+	if ((~crtc->rotations) & rotation)
+	{
+	    /*
+	     * requested rotation or reflection not supported by screen
+	     */
+	    client->errorValue = stuff->rotation;
+	    free(outputs);
+	    return BadMatch;
+	}
+    
+#ifdef RANDR_12_INTERFACE
+	/*
+	 * Check screen size bounds if the DDX provides a 1.2 interface
+	 * for setting screen size. Else, assume the CrtcSet sets
+	 * the size along with the mode. If the driver supports transforms,
+	 * then it must allow crtcs to display a subset of the screen, so
+	 * only do this check for drivers without transform support.
+	 */
+	if (pScrPriv->rrScreenSetSize && !crtc->transforms)
+	{
+	    int source_width;
+	    int	source_height;
+	    PictTransform transform;
+	    struct pixman_f_transform f_transform, f_inverse;
+
+	    RRTransformCompute (stuff->x, stuff->y,
+				mode->mode.width, mode->mode.height,
+				rotation,
+				&crtc->client_pending_transform,
+				&transform, &f_transform, &f_inverse);
+
+	    RRModeGetScanoutSize (mode, &transform, &source_width, &source_height);
+	    if (stuff->x + source_width > pScreen->width)
+	    {
+		client->errorValue = stuff->x;
+		free(outputs);
+		return BadValue;
+	    }
+	    
+	    if (stuff->y + source_height > pScreen->height)
+	    {
+		client->errorValue = stuff->y;
+		free(outputs);
+		return BadValue;
+	    }
+	}
+#endif
+    }
+    
+    if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y,
+		   rotation, numOutputs, outputs))
+    {
+	rep.status = RRSetConfigFailed;
+	goto sendReply;
+    }
+    rep.status = RRSetConfigSuccess;
+    pScrPriv->lastSetTime = time;
+    
+sendReply:
+    free(outputs);
+    
+    rep.type = X_Reply;
+    /* rep.status has already been filled in */
+    rep.length = 0;
+    rep.sequenceNumber = client->sequence;
+    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
+
+    if (client->swapped) 
+    {
+	int n;
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+	swapl(&rep.newTimestamp, n);
+    }
+    WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep);
+    
+    return Success;
+}
+
+int
+ProcRRGetPanning (ClientPtr client)
+{
+    REQUEST(xRRGetPanningReq);
+    xRRGetPanningReply	rep;
+    RRCrtcPtr		crtc;
+    ScreenPtr		pScreen;
+    rrScrPrivPtr	pScrPriv;
+    BoxRec		total;
+    BoxRec		tracking;
+    INT16		border[4];
+    int			n;
+    
+    REQUEST_SIZE_MATCH(xRRGetPanningReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+    /* All crtcs must be associated with screens before client
+     * requests are processed
+     */
+    pScreen = crtc->pScreen;
+    pScrPriv = rrGetScrPriv(pScreen);
+
+    if (!pScrPriv)
+	return RRErrorBase + BadRRCrtc;
+
+    memset(&rep, 0, sizeof(rep));
+    rep.type = X_Reply;
+    rep.status = RRSetConfigSuccess;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 1;
+    rep.timestamp = pScrPriv->lastSetTime.milliseconds;
+
+    if (pScrPriv->rrGetPanning &&
+	pScrPriv->rrGetPanning (pScreen, crtc, &total, &tracking, border)) {
+	rep.left          = total.x1;
+	rep.top           = total.y1;
+	rep.width         = total.x2 - total.x1;
+	rep.height        = total.y2 - total.y1;
+	rep.track_left    = tracking.x1;
+	rep.track_top     = tracking.y1;
+	rep.track_width   = tracking.x2 - tracking.x1;
+	rep.track_height  = tracking.y2 - tracking.y1;
+	rep.border_left   = border[0];
+	rep.border_top    = border[1];
+	rep.border_right  = border[2];
+	rep.border_bottom = border[3];
+    }
+
+    if (client->swapped) {
+	swaps(&rep.sequenceNumber, n);
+	swapl(&rep.length, n);
+	swaps(&rep.timestamp, n);
+	swaps(&rep.left, n);
+	swaps(&rep.top, n);
+	swaps(&rep.width, n);
+	swaps(&rep.height, n);
+	swaps(&rep.track_left, n);
+	swaps(&rep.track_top, n);
+	swaps(&rep.track_width, n);
+	swaps(&rep.track_height, n);
+	swaps(&rep.border_left, n);
+	swaps(&rep.border_top, n);
+	swaps(&rep.border_right, n);
+	swaps(&rep.border_bottom, n);
+    }
+    WriteToClient(client, sizeof(xRRGetPanningReply), (char *)&rep);
+    return Success;
+}
+
+int
+ProcRRSetPanning (ClientPtr client)
+{
+    REQUEST(xRRSetPanningReq);
+    xRRSetPanningReply	rep;
+    RRCrtcPtr		crtc;
+    ScreenPtr		pScreen;
+    rrScrPrivPtr	pScrPriv;
+    TimeStamp		time;
+    BoxRec		total;
+    BoxRec		tracking;
+    INT16		border[4];
+    int			n;
+    
+    REQUEST_SIZE_MATCH(xRRSetPanningReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+    /* All crtcs must be associated with screens before client
+     * requests are processed
+     */
+    pScreen = crtc->pScreen;
+    pScrPriv = rrGetScrPriv(pScreen);
+
+    if (!pScrPriv) {
+	time = currentTime;
+	rep.status = RRSetConfigFailed;
+	goto sendReply;
+    }
+    
+    time = ClientTimeToServerTime(stuff->timestamp);
+    
+    if (!pScrPriv->rrGetPanning)
+	return RRErrorBase + BadRRCrtc;
+
+    total.x1    = stuff->left;
+    total.y1    = stuff->top;
+    total.x2    = total.x1 + stuff->width;
+    total.y2    = total.y1 + stuff->height;
+    tracking.x1 = stuff->track_left;
+    tracking.y1 = stuff->track_top;
+    tracking.x2 = tracking.x1 + stuff->track_width;
+    tracking.y2 = tracking.y1 + stuff->track_height;
+    border[0]   = stuff->border_left;
+    border[1]   = stuff->border_top;
+    border[2]   = stuff->border_right;
+    border[3]   = stuff->border_bottom;
+
+    if (! pScrPriv->rrSetPanning (pScreen, crtc, &total, &tracking, border))
+	return BadMatch;
+
+    pScrPriv->lastSetTime = time;
+
+    rep.status = RRSetConfigSuccess;
+
+sendReply:
+    rep.type = X_Reply;
+    rep.sequenceNumber = client->sequence;
+    rep.length = 0;
+    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
+
+    if (client->swapped) {
+	swaps(&rep.sequenceNumber, n);
+	swapl(&rep.length, n);
+	swaps(&rep.newTimestamp, n);
+    }
+    WriteToClient(client, sizeof(xRRSetPanningReply), (char *)&rep);
+    return Success;
+}
+
+int
+ProcRRGetCrtcGammaSize (ClientPtr client)
+{
+    REQUEST(xRRGetCrtcGammaSizeReq);
+    xRRGetCrtcGammaSizeReply	reply;
+    RRCrtcPtr			crtc;
+    int				n;
+
+    REQUEST_SIZE_MATCH(xRRGetCrtcGammaSizeReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+    /* Gamma retrieval failed, any better error? */
+    if (!RRCrtcGammaGet(crtc))
+        return RRErrorBase + BadRRCrtc;
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.length = 0;
+    reply.size = crtc->gammaSize;
+    if (client->swapped) {
+	swaps (&reply.sequenceNumber, n);
+	swapl (&reply.length, n);
+	swaps (&reply.size, n);
+    }
+    WriteToClient (client, sizeof (xRRGetCrtcGammaSizeReply), (char *) &reply);
+    return Success;
+}
+
+int
+ProcRRGetCrtcGamma (ClientPtr client)
+{
+    REQUEST(xRRGetCrtcGammaReq);
+    xRRGetCrtcGammaReply	reply;
+    RRCrtcPtr			crtc;
+    int				n;
+    unsigned long		len;
+    char			*extra = NULL;
+    
+    REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+    /* Gamma retrieval failed, any better error? */
+    if (!RRCrtcGammaGet(crtc))
+        return RRErrorBase + BadRRCrtc;
+
+    len = crtc->gammaSize * 3 * 2;
+    
+    if (crtc->gammaSize) {
+	extra = malloc(len);
+	if (!extra)
+	    return BadAlloc;
+    }
+
+    reply.type = X_Reply;
+    reply.sequenceNumber = client->sequence;
+    reply.length = bytes_to_int32(len);
+    reply.size = crtc->gammaSize;
+    if (client->swapped) {
+	swaps (&reply.sequenceNumber, n);
+	swapl (&reply.length, n);
+	swaps (&reply.size, n);
+    }
+    WriteToClient (client, sizeof (xRRGetCrtcGammaReply), (char *) &reply);
+    if (crtc->gammaSize)
+    {
+	memcpy(extra, crtc->gammaRed, len);
+	client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write;
+	WriteSwappedDataToClient (client, len, extra);
+	free(extra);
+    }
+    return Success;
+}
+
+int
+ProcRRSetCrtcGamma (ClientPtr client)
+{
+    REQUEST(xRRSetCrtcGammaReq);
+    RRCrtcPtr			crtc;
+    unsigned long		len;
+    CARD16			*red, *green, *blue;
+    
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+    
+    len = client->req_len - bytes_to_int32(sizeof (xRRSetCrtcGammaReq));
+    if (len < (stuff->size * 3 + 1) >> 1)
+	return BadLength;
+
+    if (stuff->size != crtc->gammaSize)
+	return BadMatch;
+    
+    red = (CARD16 *) (stuff + 1);
+    green = red + crtc->gammaSize;
+    blue = green + crtc->gammaSize;
+    
+    RRCrtcGammaSet (crtc, red, green, blue);
+
+    return Success;
+}
+
+/* Version 1.3 additions */
+
+int
+ProcRRSetCrtcTransform (ClientPtr client)
+{
+    REQUEST(xRRSetCrtcTransformReq);
+    RRCrtcPtr		    crtc;
+    PictTransform	    transform;
+    struct pixman_f_transform f_transform, f_inverse;
+    char		    *filter;
+    int			    nbytes;
+    xFixed		    *params;
+    int			    nparams;
+
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+    PictTransform_from_xRenderTransform (&transform, &stuff->transform);
+    pixman_f_transform_from_pixman_transform (&f_transform, &transform);
+    if (!pixman_f_transform_invert (&f_inverse, &f_transform))
+	return BadMatch;
+
+    filter = (char *) (stuff + 1);
+    nbytes = stuff->nbytesFilter;
+    params = (xFixed *) (filter + pad_to_int32(nbytes));
+    nparams = ((xFixed *) stuff + client->req_len) - params;
+    if (nparams < 0)
+	return BadLength;
+
+    return RRCrtcTransformSet (crtc, &transform, &f_transform, &f_inverse,
+			       filter, nbytes, params, nparams);
+}
+
+
+#define CrtcTransformExtra	(SIZEOF(xRRGetCrtcTransformReply) - 32)
+				
+static int
+transform_filter_length (RRTransformPtr transform)
+{
+    int	nbytes, nparams;
+
+    if (transform->filter == NULL)
+	return 0;
+    nbytes = strlen (transform->filter->name);
+    nparams = transform->nparams;
+    return pad_to_int32(nbytes) + (nparams * sizeof (xFixed));
+}
+
+static int
+transform_filter_encode (ClientPtr client, char *output,
+			 CARD16	*nbytesFilter,
+			 CARD16	*nparamsFilter,
+			 RRTransformPtr transform)
+{
+    int	    nbytes, nparams;
+    int	    n;
+
+    if (transform->filter == NULL) {
+	*nbytesFilter = 0;
+	*nparamsFilter = 0;
+	return 0;
+    }
+    nbytes = strlen (transform->filter->name);
+    nparams = transform->nparams;
+    *nbytesFilter = nbytes;
+    *nparamsFilter = nparams;
+    memcpy (output, transform->filter->name, nbytes);
+    while ((nbytes & 3) != 0)
+	output[nbytes++] = 0;
+    memcpy (output + nbytes, transform->params, nparams * sizeof (xFixed));
+    if (client->swapped) {
+	swaps (nbytesFilter, n);
+	swaps (nparamsFilter, n);
+	SwapLongs ((CARD32 *) (output + nbytes), nparams);
+    }
+    nbytes += nparams * sizeof (xFixed);
+    return nbytes;
+}
+
+static void
+transform_encode (ClientPtr client, xRenderTransform *wire, PictTransform *pict)
+{
+    xRenderTransform_from_PictTransform (wire, pict);
+    if (client->swapped)
+	SwapLongs ((CARD32 *) wire, bytes_to_int32(sizeof(xRenderTransform)));
+}
+
+int
+ProcRRGetCrtcTransform (ClientPtr client)
+{
+    REQUEST(xRRGetCrtcTransformReq);
+    xRRGetCrtcTransformReply	*reply;
+    RRCrtcPtr			crtc;
+    int				n, nextra;
+    RRTransformPtr		current, pending;
+    char			*extra;
+
+    REQUEST_SIZE_MATCH (xRRGetCrtcTransformReq);
+    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+    pending = &crtc->client_pending_transform;
+    current = &crtc->client_current_transform;
+
+    nextra = (transform_filter_length (pending) +
+	      transform_filter_length (current));
+
+    reply = malloc(sizeof (xRRGetCrtcTransformReply) + nextra);
+    if (!reply)
+	return BadAlloc;
+
+    extra = (char *) (reply + 1);
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = bytes_to_int32(CrtcTransformExtra + nextra);
+
+    reply->hasTransforms = crtc->transforms;
+
+    transform_encode (client, &reply->pendingTransform, &pending->transform);
+    extra += transform_filter_encode (client, extra,
+				      &reply->pendingNbytesFilter,
+				      &reply->pendingNparamsFilter,
+				      pending);
+
+    transform_encode (client, &reply->currentTransform, &current->transform);
+    extra += transform_filter_encode (client, extra,
+				      &reply->currentNbytesFilter,
+				      &reply->currentNparamsFilter,
+				      current);
+
+    if (client->swapped) {
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
+    }
+    WriteToClient (client, sizeof (xRRGetCrtcTransformReply) + nextra, (char *) reply);
+    free(reply);
+    return Success;
+}
+
+void
+RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x, int *y)
+{
+    rrScrPriv (pScreen);
+    int i;
+
+    /* intentional dead space -> let it float */
+    if (pScrPriv->discontiguous)
+       return;
+
+    /* if we're moving inside a crtc, we're fine */
+    for (i = 0; i < pScrPriv->numCrtcs; i++) {
+       RRCrtcPtr crtc = pScrPriv->crtcs[i];
+
+       int left, right, top, bottom;
+
+       if (!crtc->mode)
+           continue;
+
+       crtc_bounds(crtc, &left, &right, &top, &bottom);
+
+       if ((*x >= left) && (*x <= right) && (*y >= top) && (*y <= bottom))
+           return;
+    }
+
+    /* if we're trying to escape, clamp to the CRTC we're coming from */
+    for (i = 0; i < pScrPriv->numCrtcs; i++) {
+       RRCrtcPtr crtc = pScrPriv->crtcs[i];
+       int nx, ny;
+       int left, right, top, bottom;
+
+       if (!crtc->mode)
+           continue;
+
+       crtc_bounds(crtc, &left, &right, &top, &bottom);
+       miPointerGetPosition(pDev, &nx, &ny);
+
+       if ((nx >= left) && (nx <= right) && (ny >= top) && (ny <= bottom)) {
+           if ((*x <= left) || (*x >= right)) {
+               int dx = *x - nx;
+
+               if (dx > 0)
+                   *x = right;
+               else if (dx < 0)
+                   *x = left;
+           }
+
+           if ((*y <= top) || (*y >= bottom)) {
+               int dy = *y - ny;
+
+               if (dy > 0)
+                   *y = bottom;
+               else if (dy < 0)
+                   *y = top;
+           }
+
+           return;
+       }
+    }
+}
diff --git a/xorg-server/record/record.c b/xorg-server/record/record.c
index df3f9c6ec..cafe02168 100644
--- a/xorg-server/record/record.c
+++ b/xorg-server/record/record.c
@@ -1,2937 +1,2936 @@
-
-/*
-
-Copyright 1995, 1998  The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice 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 OPEN GROUP 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.
-
-Except as contained in this notice, the name of The Open Group shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from The Open Group.
-
-Author: David P. Wiggins, The Open Group
-
-This work benefited from earlier work done by Martha Zimet of NCD
-and Jim Haggerty of Metheus.
-
-*/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include <X11/extensions/recordproto.h>
-#include "set.h"
-#include "swaprep.h"
-#include "inputstr.h"
-#include "eventconvert.h"
-#include "scrnintstr.h"
-
-
-#include <stdio.h>
-#include <assert.h>
-
-#ifdef PANORAMIX
-#include "globals.h"
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#include "cursor.h"
-#endif
-
-#include "protocol-versions.h"
-
-static RESTYPE RTContext;   /* internal resource type for Record contexts */
-
-/* How many bytes of protocol data to buffer in a context. Don't set to less
- * than 32.
- */
-#define REPLY_BUF_SIZE 1024
-
-/* Record Context structure */
-
-typedef struct {
-    XID		id;		   /* resource id of context */
-    ClientPtr	pRecordingClient;  /* client that has context enabled */
-    struct _RecordClientsAndProtocolRec *pListOfRCAP; /* all registered info */
-    ClientPtr	pBufClient;	   /* client whose protocol is in replyBuffer*/
-    unsigned int continuedReply:1; /* recording a reply that is split up? */
-    char	elemHeaders;	   /* element header flags (time/seq no.) */
-    char	bufCategory;	   /* category of protocol in replyBuffer */
-    int		numBufBytes;	   /* number of bytes in replyBuffer */
-    char	replyBuffer[REPLY_BUF_SIZE]; /* buffered recorded protocol */
-    int		inFlush;           /*  are we inside RecordFlushReplyBuffer */
-} RecordContextRec, *RecordContextPtr;
-
-/*  RecordMinorOpRec - to hold minor opcode selections for extension requests
- *  and replies
- */
-
-typedef union {
-    int count; /* first element of array: how many "major" structs to follow */
-    struct {   /* rest of array elements are this */
-	short first;		/* first major opcode */
-	short last;		/* last major opcode */
-	RecordSetPtr pMinOpSet; /*  minor opcode set for above major range */
-    } major;
-} RecordMinorOpRec, *RecordMinorOpPtr;
-
-
-/*  RecordClientsAndProtocolRec, nicknamed RCAP - holds all the client and 
- *  protocol selections passed in a single CreateContext or RegisterClients.
- *  Generally, a context will have one of these from the create and an
- *  additional one for each RegisterClients.  RCAPs are freed when all their
- *  clients are unregistered.
- */
-
-typedef struct _RecordClientsAndProtocolRec {
-    RecordContextPtr pContext;		 /* context that owns this RCAP */
-    struct _RecordClientsAndProtocolRec *pNextRCAP; /* next RCAP on context */
-    RecordSetPtr     pRequestMajorOpSet; /* requests to record */
-    RecordMinorOpPtr pRequestMinOpInfo;  /* extension requests to record */
-    RecordSetPtr     pReplyMajorOpSet;   /* replies to record */
-    RecordMinorOpPtr pReplyMinOpInfo;    /* extension replies to record */
-    RecordSetPtr     pDeviceEventSet;    /* device events to record */
-    RecordSetPtr     pDeliveredEventSet; /* delivered events to record */
-    RecordSetPtr     pErrorSet;          /* errors to record */
-    XID *	     pClientIDs;	 /* array of clients to record */
-    short 	     numClients;	 /* number of clients in pClientIDs */
-    short	     sizeClients;	 /* size of pClientIDs array */
-    unsigned int     clientStarted:1;	 /* record new client connections? */
-    unsigned int     clientDied:1;	 /* record client disconnections? */
-    unsigned int     clientIDsSeparatelyAllocated:1; /* pClientIDs malloced? */
-} RecordClientsAndProtocolRec, *RecordClientsAndProtocolPtr;
-
-/* how much bigger to make pRCAP->pClientIDs when reallocing */
-#define CLIENT_ARRAY_GROWTH_INCREMENT 4
-
-/* counts the total number of RCAPs belonging to enabled contexts. */
-static int numEnabledRCAPs;
-
-/*  void VERIFY_CONTEXT(RecordContextPtr, XID, ClientPtr)
- *  In the spirit of the VERIFY_* macros in dix.h, this macro fills in
- *  the context pointer if the given ID is a valid Record Context, else it
- *  returns an error.
- */
-#define VERIFY_CONTEXT(_pContext, _contextid, _client) { \
-    int rc = dixLookupResourceByType((pointer *)&(_pContext), _contextid, \
-                                     RTContext, _client, DixUseAccess); \
-    if (rc != Success) \
-	return rc; \
-}
-
-static int RecordDeleteContext(
-    pointer /*value*/,
-    XID /*id*/
-);
-
-void RecordExtensionInit(void);
-
-/***************************************************************************/
-
-/* client private stuff */
-
-/*  To make declarations less obfuscated, have a typedef for a pointer to a
- *  Proc function.
- */
-typedef int (*ProcFunctionPtr)(
-    ClientPtr /*pClient*/
-);
-
-/* Record client private.  Generally a client only has one of these if
- * any of its requests are being recorded.
- */
-typedef struct {
-/* ptr to client's proc vector before Record stuck its nose in */
-    ProcFunctionPtr *originalVector;   
-					
-/* proc vector with pointers for recorded requests redirected to the
- * function RecordARequest
- */
-    ProcFunctionPtr recordVector[256]; 
-} RecordClientPrivateRec, *RecordClientPrivatePtr;
-
-static DevPrivateKeyRec RecordClientPrivateKeyRec;
-#define RecordClientPrivateKey (&RecordClientPrivateKeyRec)
-
-/*  RecordClientPrivatePtr RecordClientPrivate(ClientPtr)
- *  gets the client private of the given client.  Syntactic sugar.
- */
-#define RecordClientPrivate(_pClient) (RecordClientPrivatePtr) \
-    dixLookupPrivate(&(_pClient)->devPrivates, RecordClientPrivateKey)
-
-
-/***************************************************************************/
-
-/* global list of all contexts */
-
-static RecordContextPtr *ppAllContexts;
-
-static int numContexts;/* number of contexts in ppAllContexts */
-
-/* number of currently enabled contexts.  All enabled contexts are bunched
- * up at the front of the ppAllContexts array, from ppAllContexts[0] to
- * ppAllContexts[numEnabledContexts-1], to eliminate time spent skipping
- * past disabled contexts.
- */
-static int numEnabledContexts;
-
-/* RecordFindContextOnAllContexts
- *
- * Arguments:
- *	pContext is the context to search for.
- *
- * Returns:
- *	The index into the array ppAllContexts at which pContext is stored.
- *	If pContext is not found in ppAllContexts, returns -1.
- *
- * Side Effects: none.
- */
-static int
-RecordFindContextOnAllContexts(RecordContextPtr pContext)
-{
-    int i;
-
-    assert(numContexts >= numEnabledContexts);
-    for (i = 0; i < numContexts; i++)
-    {
-	if (ppAllContexts[i] == pContext)
-	    return i;
-    }
-    return -1;
-} /* RecordFindContextOnAllContexts */
-
-
-/***************************************************************************/
-
-/* RecordFlushReplyBuffer
- *
- * Arguments:
- *	pContext is the context to flush.
- *	data1 is a pointer to additional data, and len1 is its length in bytes.
- *	data2 is a pointer to additional data, and len2 is its length in bytes.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	If the context is enabled, any buffered (recorded) protocol is written
- *	to the recording client, and the number of buffered bytes is set to
- *	zero.  If len1 is not zero, data1/len1 are then written to the
- *	recording client, and similarly for data2/len2 (written after
- *	data1/len1).
- */
-static void
-RecordFlushReplyBuffer(
-    RecordContextPtr pContext,
-    pointer data1,
-    int len1,
-    pointer data2,
-    int len2
-)
-{
-    if (!pContext->pRecordingClient || pContext->pRecordingClient->clientGone || pContext->inFlush)
-	return;
-    ++pContext->inFlush;
-    if (pContext->numBufBytes)
-	WriteToClient(pContext->pRecordingClient, pContext->numBufBytes,
-		      (char *)pContext->replyBuffer);
-    pContext->numBufBytes = 0;
-    if (len1)
-	WriteToClient(pContext->pRecordingClient, len1, (char *)data1);
-    if (len2)
-	WriteToClient(pContext->pRecordingClient, len2, (char *)data2);
-    --pContext->inFlush;
-} /* RecordFlushReplyBuffer */
-
-
-/* RecordAProtocolElement
- *
- * Arguments:
- *	pContext is the context that is recording a protocol element.
- *	pClient is the client whose protocol is being recorded.  For
- *	  device events and EndOfData, pClient is NULL.
- *	category is the category of the protocol element, as defined
- *	  by the RECORD spec.
- *	data is a pointer to the protocol data, and datalen is its length
- *	  in bytes.
- *	futurelen is the number of bytes that will be sent in subsequent
- *	  calls to this function to complete this protocol element.  
- *	  In those subsequent calls, futurelen will be -1 to indicate
- *	  that the current data is a continuation of the same protocol
- *	  element.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	The context may be flushed.  The new protocol element will be
- *	added to the context's protocol buffer with appropriate element
- *	headers prepended (sequence number and timestamp).  If the data
- *	is continuation data (futurelen == -1), element headers won't
- *	be added.  If the protocol element and headers won't fit in
- *	the context's buffer, it is sent directly to the recording
- *	client (after any buffered data).
- */
-static void
-RecordAProtocolElement(RecordContextPtr pContext, ClientPtr pClient,
-		       int category, pointer data, int datalen, int futurelen)
-{
-    CARD32 elemHeaderData[2];
-    int numElemHeaders = 0;
-    Bool recordingClientSwapped = pContext->pRecordingClient->swapped;
-    int n;
-    CARD32 serverTime = 0;
-    Bool gotServerTime = FALSE;
-    int replylen;
-
-    if (futurelen >= 0)
-    { /* start of new protocol element */
-	xRecordEnableContextReply *pRep = (xRecordEnableContextReply *)
-							pContext->replyBuffer;
-	if (pContext->pBufClient != pClient ||
-	    pContext->bufCategory != category)
-	{
-	    RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
-	    pContext->pBufClient = pClient;
-	    pContext->bufCategory = category;
-	}
-
-	if (!pContext->numBufBytes)
-	{
-	    serverTime = GetTimeInMillis();
-	    gotServerTime = TRUE;
-	    pRep->type          = X_Reply;
-	    pRep->category      = category;
-	    pRep->sequenceNumber = pContext->pRecordingClient->sequence;
-	    pRep->length        = 0;
-	    pRep->elementHeader = pContext->elemHeaders;
-	    pRep->serverTime    = serverTime;
-	    if (pClient)
-	    {
-		pRep->clientSwapped =
-				(pClient->swapped != recordingClientSwapped);
-		pRep->idBase = pClient->clientAsMask;
-		pRep->recordedSequenceNumber = pClient->sequence;
-	    }
-	    else /* it's a device event, StartOfData, or EndOfData */
-	    {
-		pRep->clientSwapped = (category != XRecordFromServer) && 
-						recordingClientSwapped;
-		pRep->idBase = 0;
-		pRep->recordedSequenceNumber = 0;
-	    }
-
-	    if (recordingClientSwapped)
-	    {
-		swaps(&pRep->sequenceNumber, n);
-		swapl(&pRep->length, n);
-		swapl(&pRep->idBase, n);
-		swapl(&pRep->serverTime, n);
-		swapl(&pRep->recordedSequenceNumber, n);
-	    }
-	    pContext->numBufBytes = SIZEOF(xRecordEnableContextReply);
-	}
-
-	/* generate element headers if needed */
-
-	if ( ( (pContext->elemHeaders & XRecordFromClientTime)
-	      && category == XRecordFromClient)
-	    ||
-	    ( (pContext->elemHeaders & XRecordFromServerTime)
-	     && category == XRecordFromServer))
-	{
-	    if (gotServerTime)
-		elemHeaderData[numElemHeaders] = serverTime;
-	    else
-		elemHeaderData[numElemHeaders] = GetTimeInMillis();
-	    if (recordingClientSwapped)
-		swapl(&elemHeaderData[numElemHeaders], n);
-	    numElemHeaders++;
-	}
-
-	if ( (pContext->elemHeaders & XRecordFromClientSequence)
-	    &&
-	    (category == XRecordFromClient || category == XRecordClientDied))
-	{
-	    elemHeaderData[numElemHeaders] = pClient->sequence;
-	    if (recordingClientSwapped)
-		swapl(&elemHeaderData[numElemHeaders], n);
-	    numElemHeaders++;
-	}
-
-	/* adjust reply length */
-
-	replylen = pRep->length;
-	if (recordingClientSwapped) swapl(&replylen, n);
-	replylen += numElemHeaders + bytes_to_int32(datalen) +
-            bytes_to_int32(futurelen);
-	if (recordingClientSwapped) swapl(&replylen, n);
-	pRep->length = replylen;
-    } /* end if not continued reply */
-
-    numElemHeaders *= 4;
-
-    /* if space available >= space needed, buffer the data */
-
-    if (REPLY_BUF_SIZE - pContext->numBufBytes >= datalen + numElemHeaders)
-    {
-	if (numElemHeaders)
-	{
-	    memcpy(pContext->replyBuffer + pContext->numBufBytes,
-		   elemHeaderData, numElemHeaders);
-	    pContext->numBufBytes += numElemHeaders;
-	}
-	if (datalen)
-	{
-	    memcpy(pContext->replyBuffer + pContext->numBufBytes,
-		   data, datalen);
-	    pContext->numBufBytes += datalen;
-	}
-    }
-    else
-	RecordFlushReplyBuffer(pContext, (pointer)elemHeaderData,
-			       numElemHeaders, (pointer)data, datalen);
-
-} /* RecordAProtocolElement */
-
-
-/* RecordFindClientOnContext
- *
- * Arguments:
- *	pContext is the context to search.
- *	clientspec is the resource ID mask identifying the client to search
- *	  for, or XRecordFutureClients.
- *	pposition is a pointer to an int, or NULL.  See Returns.
- *
- * Returns:
- *	The RCAP on which clientspec was found, or NULL if not found on
- *	any RCAP on the given context.
- *	If pposition was not NULL and the returned RCAP is not NULL,
- *	*pposition will be set to the index into the returned the RCAP's
- *	pClientIDs array that holds clientspec.
- *
- * Side Effects: none.
- */
-static RecordClientsAndProtocolPtr
-RecordFindClientOnContext(
-    RecordContextPtr pContext,
-    XID clientspec,
-    int *pposition
-)
-{
-    RecordClientsAndProtocolPtr pRCAP;
-
-    for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
-    {
-	int i;
-	for (i = 0; i < pRCAP->numClients; i++)
-	{
-	    if (pRCAP->pClientIDs[i] == clientspec)
-	    {
-		if (pposition)
-		    *pposition = i;
-		return pRCAP;
-	    }
-	}
-    }
-    return NULL;
-} /* RecordFindClientOnContext */
-
-
-/* RecordABigRequest
- *
- * Arguments:
- *	pContext is the recording context.
- *	client is the client being recorded.
- *	stuff is a pointer to the big request of client (see the Big Requests
- *	extension for details.)
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	The big request is recorded with the correct length field re-inserted.
- *	
- * Note: this function exists mainly to make RecordARequest smaller.
- */
-static void
-RecordABigRequest(RecordContextPtr pContext, ClientPtr client, xReq *stuff)
-{
-    CARD32 bigLength;
-    char n;
-    int bytesLeft;
-
-    /* note: client->req_len has been frobbed by ReadRequestFromClient
-     * (os/io.c) to discount the extra 4 bytes taken by the extended length
-     * field in a big request.  The actual request length to record is
-     * client->req_len + 1 (measured in CARD32s).
-     */
-
-    /* record the request header */
-    bytesLeft = client->req_len << 2;
-    RecordAProtocolElement(pContext, client, XRecordFromClient,
-			   (pointer)stuff, SIZEOF(xReq), bytesLeft);
-
-    /* reinsert the extended length field that was squished out */
-    bigLength = client->req_len + bytes_to_int32(sizeof(bigLength));
-    if (client->swapped)
-	swapl(&bigLength, n);
-    RecordAProtocolElement(pContext, client, XRecordFromClient,
-		(pointer)&bigLength, sizeof(bigLength), /* continuation */ -1);
-    bytesLeft -= sizeof(bigLength);
-
-    /* record the rest of the request after the length */
-    RecordAProtocolElement(pContext, client, XRecordFromClient,
-		(pointer)(stuff + 1), bytesLeft, /* continuation */ -1);
-} /* RecordABigRequest */
-
-
-/* RecordARequest
- *
- * Arguments:
- *	client is a client that the server has dispatched a request to by
- *	calling client->requestVector[request opcode] .
- *	The request is in client->requestBuffer.
- *
- * Returns:
- *	Whatever is returned by the "real" Proc function for this request.
- *	The "real" Proc function is the function that was in
- *	client->requestVector[request opcode]  before it was replaced by
- *	RecordARequest.  (See the function RecordInstallHooks.)
- *
- * Side Effects:
- *	The request is recorded by all contexts that have registered this
- *	request for this client.  The real Proc function is called.
- */
-static int
-RecordARequest(ClientPtr client)
-{
-    RecordContextPtr pContext;
-    RecordClientsAndProtocolPtr pRCAP;
-    int i;
-    RecordClientPrivatePtr pClientPriv;
-    REQUEST(xReq);
-    int majorop;
-
-    majorop = stuff->reqType;
-    for (i = 0; i < numEnabledContexts; i++)
-    {
-	pContext = ppAllContexts[i];
-	pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
-					  NULL);
-	if (pRCAP && pRCAP->pRequestMajorOpSet &&
-	    RecordIsMemberOfSet(pRCAP->pRequestMajorOpSet, majorop))
-	{
-	    if (majorop <= 127)
-	    { /* core request */
-
-		if (stuff->length == 0)
-		    RecordABigRequest(pContext, client, stuff);
-		else
-		    RecordAProtocolElement(pContext, client, XRecordFromClient,
-				(pointer)stuff, client->req_len << 2, 0);
-	    }
-	    else /* extension, check minor opcode */
-	    {
-		int minorop = MinorOpcodeOfRequest(client);
-		int numMinOpInfo;
-		RecordMinorOpPtr pMinorOpInfo = pRCAP->pRequestMinOpInfo;
-
-		assert (pMinorOpInfo);
-		numMinOpInfo = pMinorOpInfo->count;
-		pMinorOpInfo++;
-		assert (numMinOpInfo);
-		for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
-		{
-		    if (majorop >= pMinorOpInfo->major.first &&
-			majorop <= pMinorOpInfo->major.last &&
-			RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
-					    minorop))
-		    {
-			if (stuff->length == 0)
-			    RecordABigRequest(pContext, client, stuff);
-			else
-			    RecordAProtocolElement(pContext, client, 
-					XRecordFromClient, (pointer)stuff,
-					client->req_len << 2, 0);
-			break;
-		    }			    
-		} /* end for each minor op info */
-	    } /* end extension request */
-	} /* end this RCAP wants this major opcode */
-    } /* end for each context */
-    pClientPriv = RecordClientPrivate(client);
-    assert(pClientPriv);
-    return (* pClientPriv->originalVector[majorop])(client);
-} /* RecordARequest */
-
-/* RecordAReply
- *
- * Arguments:
- *	pcbl is &ReplyCallback.
- *	nulldata is NULL.
- *	calldata is a pointer to a ReplyInfoRec (include/os.h)
- *	  which provides information about replies that are being sent
- *	  to clients.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	The reply is recorded by all contexts that have registered this
- *	reply type for this client.  If more data belonging to the same
- *	reply is expected, and if the reply is being recorded by any
- *	context, pContext->continuedReply is set to 1.
- *	If pContext->continuedReply was already 1 and this is the last
- *	chunk of data belonging to this reply, it is set to 0.
- */
-static void
-RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
-{
-    RecordContextPtr pContext;
-    RecordClientsAndProtocolPtr pRCAP;
-    int eci;
-    int majorop;
-    ReplyInfoRec *pri = (ReplyInfoRec *)calldata;
-    ClientPtr client = pri->client;
-    REQUEST(xReq);
-
-    majorop = stuff->reqType;
-    for (eci = 0; eci < numEnabledContexts; eci++)
-    {
-	pContext = ppAllContexts[eci];
-	pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
-					  NULL);
-	if (pRCAP)
-	{
-	    if (pContext->continuedReply)
-	    {
-		RecordAProtocolElement(pContext, client, XRecordFromServer,
-		   (pointer)pri->replyData, pri->dataLenBytes, /* continuation */ -1);
-		if (!pri->bytesRemaining)
-		    pContext->continuedReply = 0;
-	    }
-	    else if (pri->startOfReply && pRCAP->pReplyMajorOpSet &&
-		     RecordIsMemberOfSet(pRCAP->pReplyMajorOpSet, majorop))
-	    {
-		if (majorop <= 127)
-		{ /* core reply */
-		    RecordAProtocolElement(pContext, client, XRecordFromServer,
-		       (pointer)pri->replyData, pri->dataLenBytes, pri->bytesRemaining);
-		    if (pri->bytesRemaining)
-			pContext->continuedReply = 1;
-		}
-		else /* extension, check minor opcode */
-		{
-		    int minorop = MinorOpcodeOfRequest(client);
-		    int numMinOpInfo;
-		    RecordMinorOpPtr pMinorOpInfo = pRCAP->pReplyMinOpInfo;
-		    		    assert (pMinorOpInfo);
-		    numMinOpInfo = pMinorOpInfo->count;
-		    pMinorOpInfo++;
-		    assert (numMinOpInfo);
-		    for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
-		    {
-			if (majorop >= pMinorOpInfo->major.first &&
-			    majorop <= pMinorOpInfo->major.last &&
-			    RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
-						minorop))
-			{
-			    RecordAProtocolElement(pContext, client, 
-				XRecordFromServer, (pointer)pri->replyData,
-				pri->dataLenBytes, pri->bytesRemaining);
-			    if (pri->bytesRemaining)
-				pContext->continuedReply = 1;
-			    break;
-			}			    
-		    } /* end for each minor op info */
-		} /* end extension reply */
-	    } /* end continued reply vs. start of reply */
-	} /* end client is registered on this context */
-    } /* end for each context */
-} /* RecordAReply */
-
-
-/* RecordADeliveredEventOrError
- *
- * Arguments:
- *	pcbl is &EventCallback.
- *	nulldata is NULL.
- *	calldata is a pointer to a EventInfoRec (include/dix.h)
- *	  which provides information about events that are being sent
- *	  to clients.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	The event or error is recorded by all contexts that have registered
- *	it for this client.
- */
-static void
-RecordADeliveredEventOrError(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
-{
-    EventInfoRec *pei = (EventInfoRec *)calldata;
-    RecordContextPtr pContext;
-    RecordClientsAndProtocolPtr pRCAP;
-    int eci; /* enabled context index */
-    ClientPtr pClient = pei->client;
-
-    for (eci = 0; eci < numEnabledContexts; eci++)
-    {
-	pContext = ppAllContexts[eci];
-	pRCAP = RecordFindClientOnContext(pContext, pClient->clientAsMask,
-					  NULL);
-	if (pRCAP && (pRCAP->pDeliveredEventSet || pRCAP->pErrorSet))
-	{
-	    int ev; /* event index */
-	    xEvent *pev = pei->events;
-	    for (ev = 0; ev < pei->count; ev++, pev++)
-	    {
-		int recordit = 0;
-		if (pRCAP->pErrorSet)
-		{
-		    recordit = RecordIsMemberOfSet(pRCAP->pErrorSet,
-						((xError *)(pev))->errorCode);
-		}
-		else if (pRCAP->pDeliveredEventSet)
-		{
-		    recordit = RecordIsMemberOfSet(pRCAP->pDeliveredEventSet,
-						   pev->u.u.type & 0177);
-		}
-		if (recordit)
-		{
-		    xEvent swappedEvent;
-		    xEvent *pEvToRecord = pev;
-
-		    if (pClient->swapped)
-		    {
-			(*EventSwapVector[pev->u.u.type & 0177])
-			    (pev, &swappedEvent);
-			pEvToRecord = &swappedEvent;
-			
-		    }
-		    RecordAProtocolElement(pContext, pClient,
-			XRecordFromServer, pEvToRecord, SIZEOF(xEvent), 0);
-		}
-	    } /* end for each event */
-	} /* end this client is on this context */
-    } /* end for each enabled context */
-} /* RecordADeliveredEventOrError */
-
-
-static void
-RecordSendProtocolEvents(RecordClientsAndProtocolPtr pRCAP,
-			RecordContextPtr pContext,
-			xEvent* pev, int count)
-{
-    int ev; /* event index */
-
-    for (ev = 0; ev < count; ev++, pev++)
-    {
-	if (RecordIsMemberOfSet(pRCAP->pDeviceEventSet,
-		    pev->u.u.type & 0177))
-	{
-	    xEvent swappedEvent;
-	    xEvent *pEvToRecord = pev;
-#ifdef PANORAMIX
-	    xEvent shiftedEvent;
-
-	    if (!noPanoramiXExtension &&
-		    (pev->u.u.type == MotionNotify ||
-		     pev->u.u.type == ButtonPress ||
-		     pev->u.u.type == ButtonRelease ||
-		     pev->u.u.type == KeyPress ||
-		     pev->u.u.type == KeyRelease)) {
-		int scr = XineramaGetCursorScreen(inputInfo.pointer);
-		memcpy(&shiftedEvent, pev, sizeof(xEvent));
-		shiftedEvent.u.keyButtonPointer.rootX +=
-		    screenInfo.screens[scr]->x -
-		    screenInfo.screens[0]->x;
-		shiftedEvent.u.keyButtonPointer.rootY +=
-		    screenInfo.screens[scr]->y -
-		    screenInfo.screens[0]->y;
-		pEvToRecord = &shiftedEvent;
-	    }
-#endif /* PANORAMIX */
-
-	    if (pContext->pRecordingClient->swapped)
-	    {
-		(*EventSwapVector[pEvToRecord->u.u.type & 0177])
-		    (pEvToRecord, &swappedEvent);
-		pEvToRecord = &swappedEvent;
-	    }
-
-	    RecordAProtocolElement(pContext, NULL,
-		    XRecordFromServer,  pEvToRecord, SIZEOF(xEvent), 0);
-	    /* make sure device events get flushed in the absence
-	     * of other client activity
-	     */
-	    SetCriticalOutputPending();
-	}
-    } /* end for each event */
-
-} /* RecordADeviceEvent */
-
-/* RecordADeviceEvent
- *
- * Arguments:
- *	pcbl is &DeviceEventCallback.
- *	nulldata is NULL.
- *	calldata is a pointer to a DeviceEventInfoRec (include/dix.h)
- *	  which provides information about device events that occur.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	The device event is recorded by all contexts that have registered
- *	it for this client.
- */
-static void
-RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
-{
-    DeviceEventInfoRec *pei = (DeviceEventInfoRec *)calldata;
-    RecordContextPtr pContext;
-    RecordClientsAndProtocolPtr pRCAP;
-    int eci; /* enabled context index */
-    int count;
-
-    for (eci = 0; eci < numEnabledContexts; eci++)
-    {
-	pContext = ppAllContexts[eci];
-	for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
-	{
-	    if (pRCAP->pDeviceEventSet)
-	    {
-		int count;
-		xEvent *xi_events = NULL;
-
-		/* TODO check return values */
-		if (IsMaster(pei->device))
-		{
-		    xEvent *core_events;
-		    EventToCore(pei->event, &core_events, &count);
-		    RecordSendProtocolEvents(pRCAP, pContext, core_events,
-                                             count);
-		    free(core_events);
-		}
-
-		EventToXI(pei->event, &xi_events, &count);
-		RecordSendProtocolEvents(pRCAP, pContext, xi_events, count);
-		free(xi_events);
-	    } /* end this RCAP selects device events */
-	} /* end for each RCAP on this context */
-    } /* end for each enabled context */
-}
-
-
-/* RecordFlushAllContexts
- *
- * Arguments:
- *	pcbl is &FlushCallback.
- *	nulldata and calldata are NULL.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	All buffered reply data of all enabled contexts is written to
- *	the recording clients.
- */
-static void
-RecordFlushAllContexts(
-    CallbackListPtr *pcbl,
-    pointer nulldata,
-    pointer calldata
-)
-{
-    int eci; /* enabled context index */
-    RecordContextPtr pContext;
-
-    for (eci = 0; eci < numEnabledContexts; eci++)
-    {
-	pContext = ppAllContexts[eci];
-
-	/* In most cases we leave it to RecordFlushReplyBuffer to make
-	 * this check, but this function could be called very often, so we
-	 * check before calling hoping to save the function call cost
-	 * most of the time.
-	 */
-	if (pContext->numBufBytes)
-	    RecordFlushReplyBuffer(ppAllContexts[eci], NULL, 0, NULL, 0);
-    }
-} /* RecordFlushAllContexts */
-
-
-/* RecordInstallHooks
- *
- * Arguments:
- *	pRCAP is an RCAP on an enabled or being-enabled context.
- *	oneclient can be zero or the resource ID mask identifying a client.
- *
- * Returns: BadAlloc if a memory allocation error occurred, else Success.
- *
- * Side Effects:
- *	Recording hooks needed by RCAP are installed.
- *	If oneclient is zero, recording hooks needed for all clients and
- *	protocol on the RCAP are installed.  If oneclient is non-zero,
- *	only those hooks needed for the specified client are installed.
- *	
- *	Client requestVectors may be altered.  numEnabledRCAPs will be
- *	incremented if oneclient == 0.  Callbacks may be added to
- *	various callback lists.
- */
-static int
-RecordInstallHooks(RecordClientsAndProtocolPtr pRCAP, XID oneclient)
-{
-    int i = 0;
-    XID client;
-
-    if (oneclient)
-	client = oneclient;
-    else
-	client = pRCAP->numClients ? pRCAP->pClientIDs[i++] : 0;
-
-    while (client)
-    {
-	if (client != XRecordFutureClients)
-	{
-	    if (pRCAP->pRequestMajorOpSet)
-	    {
-		RecordSetIteratePtr pIter = NULL;
-		RecordSetInterval interval;
-		ClientPtr pClient = clients[CLIENT_ID(client)];
-
-		if (pClient && !RecordClientPrivate(pClient))
-		{
-		    RecordClientPrivatePtr pClientPriv;
-		    /* no Record proc vector; allocate one */
-		    pClientPriv = (RecordClientPrivatePtr)
-				malloc(sizeof(RecordClientPrivateRec));
-		    if (!pClientPriv)
-			return BadAlloc;
-		    /* copy old proc vector to new */
-		    memcpy(pClientPriv->recordVector, pClient->requestVector, 
-			   sizeof (pClientPriv->recordVector));
-		    pClientPriv->originalVector = pClient->requestVector;
-		    dixSetPrivate(&pClient->devPrivates,
-				  RecordClientPrivateKey, pClientPriv);
-		    pClient->requestVector = pClientPriv->recordVector;
-		}
-		while ((pIter = RecordIterateSet(pRCAP->pRequestMajorOpSet,
-						pIter, &interval)))
-		{
-		    unsigned int j;
-		    for (j = interval.first; j <= interval.last; j++)
-			pClient->requestVector[j] = RecordARequest;
-		}
-	    }
-	}
-	if (oneclient)
-	    client = 0;
-	else
-	    client = (i < pRCAP->numClients) ? pRCAP->pClientIDs[i++] : 0;
-    }
-
-    assert(numEnabledRCAPs >= 0);
-    if (!oneclient && ++numEnabledRCAPs == 1)
-    { /* we're enabling the first context */
-	if (!AddCallback(&EventCallback, RecordADeliveredEventOrError, NULL))
-	    return BadAlloc;
-	if (!AddCallback(&DeviceEventCallback, RecordADeviceEvent, NULL))
-	    return BadAlloc;
-	if (!AddCallback(&ReplyCallback, RecordAReply, NULL))
-	    return BadAlloc;
-	if (!AddCallback(&FlushCallback, RecordFlushAllContexts, NULL))
-	    return BadAlloc;
-	/* Alternate context flushing scheme: delete the line above
-	 * and call RegisterBlockAndWakeupHandlers here passing
-	 * RecordFlushAllContexts.  Is this any better?
-	 */
-    }
-    return Success;
-} /* RecordInstallHooks */
-
-
-/* RecordUninstallHooks
- *
- * Arguments:
- *	pRCAP is an RCAP on an enabled or being-disabled context.
- *	oneclient can be zero or the resource ID mask identifying a client.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	Recording hooks needed by RCAP may be uninstalled.
- *	If oneclient is zero, recording hooks needed for all clients and
- *	protocol on the RCAP may be uninstalled.  If oneclient is non-zero,
- *	only those hooks needed for the specified client may be uninstalled.
- *	
- *	Client requestVectors may be altered.  numEnabledRCAPs will be
- *	decremented if oneclient == 0.  Callbacks may be deleted from
- *	various callback lists.
- */
-static void
-RecordUninstallHooks(RecordClientsAndProtocolPtr pRCAP, XID oneclient)
-{
-    int i = 0;
-    XID client;
-
-    if (oneclient)
-	client = oneclient;
-    else
-	client = pRCAP->numClients ? pRCAP->pClientIDs[i++] : 0;
-
-    while (client)
-    {
-	if (client != XRecordFutureClients)
-	{
-	    if (pRCAP->pRequestMajorOpSet)
-	    {
-		ClientPtr pClient = clients[CLIENT_ID(client)];
-		int c;
-		Bool otherRCAPwantsProcVector = FALSE;
-		RecordClientPrivatePtr pClientPriv = NULL;
-
-		assert (pClient);
-		pClientPriv = RecordClientPrivate(pClient);
-		assert (pClientPriv);
-		memcpy(pClientPriv->recordVector, pClientPriv->originalVector,
-		       sizeof (pClientPriv->recordVector));
-
-		for (c = 0; c < numEnabledContexts; c++)
-		{
-		    RecordClientsAndProtocolPtr pOtherRCAP;
-		    RecordContextPtr pContext = ppAllContexts[c];
-
-		    if (pContext == pRCAP->pContext) continue;
-		    pOtherRCAP = RecordFindClientOnContext(pContext, client,
-							   NULL);
-		    if (pOtherRCAP && pOtherRCAP->pRequestMajorOpSet)
-		    {
-			RecordSetIteratePtr pIter = NULL;
-			RecordSetInterval interval;
-
-			otherRCAPwantsProcVector = TRUE;
-			while ((pIter = RecordIterateSet(
-						pOtherRCAP->pRequestMajorOpSet,
-						pIter, &interval)))
-			{
-			    unsigned int j;
-			    for (j = interval.first; j <= interval.last; j++)
-				pClient->requestVector[j] = RecordARequest;
-			}
-		    }
-		}
-		if (!otherRCAPwantsProcVector)
-		{ /* nobody needs it, so free it */
-		    pClient->requestVector = pClientPriv->originalVector;
-		    dixSetPrivate(&pClient->devPrivates,
-				  RecordClientPrivateKey, NULL);
-		    free(pClientPriv);
-		}
-	    } /* end if this RCAP specifies any requests */
-	} /* end if not future clients */
-	if (oneclient)
-	    client = 0;
-	else
-	    client = (i < pRCAP->numClients) ? pRCAP->pClientIDs[i++] : 0;
-    }
-
-    assert(numEnabledRCAPs >= 1);
-    if (!oneclient && --numEnabledRCAPs == 0)
-    { /* we're disabling the last context */
-	DeleteCallback(&EventCallback, RecordADeliveredEventOrError, NULL);
-	DeleteCallback(&DeviceEventCallback, RecordADeviceEvent, NULL);
-	DeleteCallback(&ReplyCallback, RecordAReply, NULL);
-	DeleteCallback(&FlushCallback, RecordFlushAllContexts, NULL);
-	/* Alternate context flushing scheme: delete the line above
-	 * and call RemoveBlockAndWakeupHandlers here passing
-	 * RecordFlushAllContexts.  Is this any better?
-	 */
-	/* Having deleted the callback, call it one last time. -gildea */
-	RecordFlushAllContexts(&FlushCallback, NULL, NULL);
-    }
-} /* RecordUninstallHooks */
-
-
-/* RecordDeleteClientFromRCAP
- *
- * Arguments:
- *	pRCAP is an RCAP to delete the client from.
- *	position is the index into the array pRCAP->pClientIDs of the
- *	client to delete.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	Recording hooks needed by client will be uninstalled if the context
- *	is enabled.  The designated client will be removed from the 
- *	pRCAP->pClientIDs array.  If it was the only client on the RCAP, 
- *	the RCAP is removed from the context and freed.  (Invariant: RCAPs
- *	have at least one client.)
- */
-static void
-RecordDeleteClientFromRCAP(RecordClientsAndProtocolPtr pRCAP, int position)
-{
-    if (pRCAP->pContext->pRecordingClient)
-	RecordUninstallHooks(pRCAP, pRCAP->pClientIDs[position]);
-    if (position != pRCAP->numClients - 1)
-	pRCAP->pClientIDs[position] = pRCAP->pClientIDs[pRCAP->numClients - 1];
-    if (--pRCAP->numClients == 0)
-    {	/* no more clients; remove RCAP from context's list */
-	RecordContextPtr pContext = pRCAP->pContext;
-	if (pContext->pRecordingClient)
-	    RecordUninstallHooks(pRCAP, 0);
-	if (pContext->pListOfRCAP == pRCAP)
-	    pContext->pListOfRCAP = pRCAP->pNextRCAP;
-	else
-	{
-	    RecordClientsAndProtocolPtr prevRCAP;
-	    for (prevRCAP = pContext->pListOfRCAP;
-		 prevRCAP->pNextRCAP != pRCAP;
-		 prevRCAP = prevRCAP->pNextRCAP)
-		;
-	    prevRCAP->pNextRCAP = pRCAP->pNextRCAP;
-	}
-	/* free the RCAP */
-	if (pRCAP->clientIDsSeparatelyAllocated)
-	    free(pRCAP->pClientIDs);
-	free(pRCAP);
-    }
-} /* RecordDeleteClientFromRCAP */
-
-
-/* RecordAddClientToRCAP
- *
- * Arguments:
- *	pRCAP is an RCAP to add the client to.
- *	clientspec is the resource ID mask identifying a client, or
- *	  XRecordFutureClients.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	Recording hooks needed by client will be installed if the context
- *	is enabled.  The designated client will be added to the 
- *	pRCAP->pClientIDs array, which may be realloced.
- *	pRCAP->clientIDsSeparatelyAllocated may be set to 1 if there
- *	is no more room to hold clients internal to the RCAP.
- */
-static void
-RecordAddClientToRCAP(RecordClientsAndProtocolPtr pRCAP, XID clientspec)
-{
-    if (pRCAP->numClients == pRCAP->sizeClients)
-    {
-	if (pRCAP->clientIDsSeparatelyAllocated)
-	{
-	    XID *pNewIDs = (XID *)realloc(pRCAP->pClientIDs,
-			(pRCAP->sizeClients + CLIENT_ARRAY_GROWTH_INCREMENT) *
-								sizeof(XID));
-	    if (!pNewIDs)
-		return;
-	    pRCAP->pClientIDs = pNewIDs;
-	    pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT;
-	}
-	else
-	{
-	    XID *pNewIDs = (XID *)malloc((pRCAP->sizeClients +
-				CLIENT_ARRAY_GROWTH_INCREMENT) * sizeof(XID));
-	    if (!pNewIDs)
-		return;
-	    memcpy(pNewIDs, pRCAP->pClientIDs, pRCAP->numClients *sizeof(XID));
-	    pRCAP->pClientIDs = pNewIDs;
-	    pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT;
-	    pRCAP->clientIDsSeparatelyAllocated = 1;
-	}
-    }
-    pRCAP->pClientIDs[pRCAP->numClients++] = clientspec;
-    if (pRCAP->pContext->pRecordingClient)
-	RecordInstallHooks(pRCAP, clientspec);
-} /* RecordDeleteClientFromRCAP */
-
-
-/* RecordDeleteClientFromContext
- *
- * Arguments:
- *	pContext is the context to delete from.
- *	clientspec is the resource ID mask identifying a client, or
- *	  XRecordFutureClients.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	If clientspec is on any RCAP of the context, it is deleted from that
- *	RCAP.  (A given clientspec can only be on one RCAP of a context.)
- */
-static void
-RecordDeleteClientFromContext(RecordContextPtr pContext, XID clientspec)
-{
-    RecordClientsAndProtocolPtr pRCAP;
-    int position;
-
-    if ((pRCAP = RecordFindClientOnContext(pContext, clientspec, &position)))
-	RecordDeleteClientFromRCAP(pRCAP, position);
-} /* RecordDeleteClientFromContext */
-
-
-/* RecordSanityCheckClientSpecifiers
- *
- * Arguments:
- *	clientspecs is an array of alleged CLIENTSPECs passed by the client.
- *	nspecs is the number of elements in clientspecs.
- *	errorspec, if non-zero, is the resource id base of a client that
- *	  must not appear in clienspecs.
- *
- * Returns: BadMatch if any of the clientspecs are invalid, else Success.
- *
- * Side Effects: none.
- */
-static int
-RecordSanityCheckClientSpecifiers(ClientPtr client, XID *clientspecs, int nspecs, XID errorspec)
-{
-    int i;
-    int clientIndex;
-    int rc;
-    pointer value;
-
-    for (i = 0; i < nspecs; i++)
-    {
-	if (clientspecs[i] == XRecordCurrentClients ||
-	    clientspecs[i] == XRecordFutureClients ||
-	    clientspecs[i] == XRecordAllClients)
-	    continue;
-	if (errorspec && (CLIENT_BITS(clientspecs[i]) == errorspec) )
-	    return BadMatch;
-	clientIndex = CLIENT_ID(clientspecs[i]);
-	if (clientIndex && clients[clientIndex] &&
-	    clients[clientIndex]->clientState == ClientStateRunning)
-	{
-	    if (clientspecs[i] == clients[clientIndex]->clientAsMask)
-		continue;
-            rc = dixLookupResourceByClass(&value, clientspecs[i], RC_ANY,
-                                          client, DixGetAttrAccess);
-            if (rc != Success)
-                return rc;
-	}
-	else
-	    return BadMatch;
-    }
-    return Success;
-} /* RecordSanityCheckClientSpecifiers */
-
-
-/* RecordCanonicalizeClientSpecifiers
- *
- * Arguments:
- *	pClientspecs is an array of CLIENTSPECs that have been sanity
- *	  checked.
- *	pNumClientspecs is a pointer to the number of elements in pClientspecs.
- *	excludespec, if non-zero, is the resource id base of a client that 
- *	  should not be included in the expansion of XRecordAllClients or 
- *	  XRecordCurrentClients.
- *
- * Returns:
- *	A pointer to an array of CLIENTSPECs that is the same as the
- *	passed array with the following modifications:
- *	  - all but the client id bits of resource IDs are stripped off.
- *	  - duplicates removed.
- *	  - XRecordAllClients expanded to a list of all currently connected
- *	    clients + XRecordFutureClients - excludespec (if non-zero)
- *	  - XRecordCurrentClients expanded to a list of all currently
- *	    connected clients - excludespec (if non-zero)
- *	The returned array may be the passed array modified in place, or
- *	it may be an malloc'ed array.  The caller should keep a pointer to the
- *	original array and free the returned array if it is different.
- *
- *	*pNumClientspecs is set to the number of elements in the returned
- *	array.
- *
- * Side Effects:
- *	pClientspecs may be modified in place.
- */
-static XID *
-RecordCanonicalizeClientSpecifiers(XID *pClientspecs, int *pNumClientspecs, XID excludespec)
-{
-    int i;
-    int numClients = *pNumClientspecs;
-
-    /*  first pass strips off the resource index bits, leaving just the
-     *  client id bits.  This makes searching for a particular client simpler
-     *  (and faster.)
-     */
-    for (i = 0; i < numClients; i++)
-    {
-	XID cs = pClientspecs[i];
-	if (cs > XRecordAllClients)
-	    pClientspecs[i] = CLIENT_BITS(cs);
-    }
-
-    for (i = 0; i < numClients; i++)
-    {
-	if (pClientspecs[i] == XRecordAllClients ||
-	    pClientspecs[i] == XRecordCurrentClients)
-	{ /* expand All/Current */
-	    int j, nc;
-	    XID *pCanon = (XID *)malloc(sizeof(XID) * (currentMaxClients + 1));
-	    if (!pCanon) return NULL;
-	    for (nc = 0, j = 1; j < currentMaxClients; j++)
-	    {
-		ClientPtr client = clients[j];
-		if (client != NullClient &&
-		    client->clientState == ClientStateRunning &&
-		    client->clientAsMask != excludespec)
-		{
-		    pCanon[nc++] = client->clientAsMask;
-		}
-	    }
-	    if (pClientspecs[i] == XRecordAllClients)
-		pCanon[nc++] = XRecordFutureClients;
-	    *pNumClientspecs = nc;
-	    return pCanon;
-	}
-	else /* not All or Current */
-	{
-	    int j;
-	    for (j = i + 1; j < numClients; )
-	    {
-		if (pClientspecs[i] == pClientspecs[j])
-		{
-		    pClientspecs[j] = pClientspecs[--numClients];
-		}
-		else
-		    j++;
-	    }
-	}
-    } /* end for each clientspec */
-    *pNumClientspecs = numClients;
-    return pClientspecs;
-} /* RecordCanonicalizeClientSpecifiers */
-
-
-/****************************************************************************/
-
-/* stuff for RegisterClients */
-
-/* RecordPadAlign
- *
- * Arguments:
- *	size is the number of bytes taken by an object.
- *	align is a byte boundary (e.g. 4, 8)
- *
- * Returns:
- *	the number of pad bytes to add at the end of an object of the
- *	given size so that an object placed immediately behind it will
- *	begin on an <align>-byte boundary.
- *
- * Side Effects: none.
- */
-static int
-RecordPadAlign(int size, int align)
-{
-    return (align - (size & (align - 1))) & (align - 1);
-} /* RecordPadAlign */
-
-
-/* RecordSanityCheckRegisterClients
- *
- * Arguments:
- *	pContext is the context being registered on.
- *	client is the client that issued a RecordCreateContext or
- *	  RecordRegisterClients request.
- *	stuff is a pointer to the request.
- *
- * Returns:
- *	Any one of several possible error values if any of the request
- *	arguments are invalid.  Success if everything is OK.
- *
- * Side Effects: none.
- */
-static int
-RecordSanityCheckRegisterClients(RecordContextPtr pContext, ClientPtr client, xRecordRegisterClientsReq *stuff)
-{
-    int err;
-    xRecordRange *pRange;
-    int i;
-    XID recordingClient;
-
-    if (((client->req_len << 2) - SIZEOF(xRecordRegisterClientsReq)) !=
-	4 * stuff->nClients + SIZEOF(xRecordRange) * stuff->nRanges)
-	return BadLength;
-
-    if (stuff->elementHeader &
-     ~(XRecordFromClientSequence|XRecordFromClientTime|XRecordFromServerTime))
-    {
-	client->errorValue = stuff->elementHeader;
-	return BadValue;
-    }
-
-    recordingClient = pContext->pRecordingClient ?
-		      pContext->pRecordingClient->clientAsMask : 0;
-    err = RecordSanityCheckClientSpecifiers(client, (XID *)&stuff[1],
-					    stuff->nClients, recordingClient);
-    if (err != Success) return err;
-
-    pRange = (xRecordRange *)(((XID *)&stuff[1]) + stuff->nClients);
-    for (i = 0; i < stuff->nRanges; i++, pRange++)
-    {
-	if (pRange->coreRequestsFirst > pRange->coreRequestsLast)
-	{
-	    client->errorValue = pRange->coreRequestsFirst;
-	    return BadValue;
-	}
-	if (pRange->coreRepliesFirst > pRange->coreRepliesLast)
-	{
-	    client->errorValue = pRange->coreRepliesFirst;
-	    return BadValue;
-	}
-	if ((pRange->extRequestsMajorFirst || pRange->extRequestsMajorLast) &&
-	    (pRange->extRequestsMajorFirst < 128 ||
-	     pRange->extRequestsMajorLast < 128 ||
-	     pRange->extRequestsMajorFirst > pRange->extRequestsMajorLast))
-	{
-	    client->errorValue = pRange->extRequestsMajorFirst;
-	    return BadValue;
-	}
-	if (pRange->extRequestsMinorFirst > pRange->extRequestsMinorLast)
-	{
-	    client->errorValue = pRange->extRequestsMinorFirst;
-	    return BadValue;
-	}
-	if ((pRange->extRepliesMajorFirst || pRange->extRepliesMajorLast) &&
-	    (pRange->extRepliesMajorFirst < 128 ||
-	     pRange->extRepliesMajorLast < 128 ||
-	     pRange->extRepliesMajorFirst > pRange->extRepliesMajorLast))
-	{
-	    client->errorValue = pRange->extRepliesMajorFirst;
-	    return BadValue;
-	}
-	if (pRange->extRepliesMinorFirst > pRange->extRepliesMinorLast)
-	{
-	    client->errorValue = pRange->extRepliesMinorFirst;
-	    return BadValue;
-	}
-	if ((pRange->deliveredEventsFirst || pRange->deliveredEventsLast) &&
-	    (pRange->deliveredEventsFirst < 2 ||
-	     pRange->deliveredEventsLast < 2 ||
-	     pRange->deliveredEventsFirst > pRange->deliveredEventsLast))
-	{
-	    client->errorValue = pRange->deliveredEventsFirst;
-	    return BadValue;
-	}
-	if ((pRange->deviceEventsFirst || pRange->deviceEventsLast) &&
-	    (pRange->deviceEventsFirst < 2 ||
-	     pRange->deviceEventsLast < 2 ||
-	     pRange->deviceEventsFirst > pRange->deviceEventsLast))
-	{
-	    client->errorValue = pRange->deviceEventsFirst;
-	    return BadValue;
-	}
-	if (pRange->errorsFirst > pRange->errorsLast)
-	{
-	    client->errorValue = pRange->errorsFirst;
-	    return BadValue;
-	}
-	if (pRange->clientStarted != xFalse && pRange->clientStarted != xTrue)
-	{
-	    client->errorValue = pRange->clientStarted;
-	    return BadValue;
-	}
-	if (pRange->clientDied != xFalse && pRange->clientDied != xTrue)
-	{
-	    client->errorValue = pRange->clientDied;
-	    return BadValue;
-	}
-    } /* end for each range */
-    return Success;
-} /* end RecordSanityCheckRegisterClients */
-
-/* This is a tactical structure used to gather information about all the sets
- * (RecordSetPtr) that need to be created for an RCAP in the process of 
- * digesting a list of RECORDRANGEs (converting it to the internal
- * representation).
- */
-typedef struct
-{
-    int nintervals;	/* number of intervals in following array */
-    RecordSetInterval *intervals;  /* array of intervals for this set */
-    int size;		/* size of intevals array; >= nintervals */
-    int align;		/* alignment restriction for set */
-    int offset;		/* where to store set pointer rel. to start of RCAP */
-    short first, last;	/* if for extension, major opcode interval */
-} SetInfoRec, *SetInfoPtr;
-
-/* These constant are used to index into an array of SetInfoRec. */
-enum {REQ,	/* set info for requests */
-      REP,	/* set info for replies */
-      ERR,	/* set info for errors */
-      DEV,	/* set info for device events */
-      DLEV,	/* set info for delivered events */
-      PREDEFSETS};  /* number of predefined array entries */
-
-
-/* RecordAllocIntervals
- *
- * Arguments:
- *	psi is a pointer to a SetInfoRec whose intervals pointer is NULL.
- *	nIntervals is the desired size of the intervals array.
- *
- * Returns: BadAlloc if a memory allocation error occurred, else Success.
- *
- * Side Effects:
- *	If Success is returned, psi->intervals is a pointer to size
- *	RecordSetIntervals, all zeroed, and psi->size is set to size.
- */
-static int
-RecordAllocIntervals(SetInfoPtr psi, int nIntervals)
-{
-    assert(!psi->intervals);
-    psi->intervals = (RecordSetInterval *)
-			malloc(nIntervals * sizeof(RecordSetInterval));
-    if (!psi->intervals)
-	return BadAlloc;
-    memset(psi->intervals, 0, nIntervals * sizeof(RecordSetInterval));
-    psi->size = nIntervals;
-    return Success;
-} /* end RecordAllocIntervals */
-
-
-/* RecordConvertRangesToIntervals
- *
- * Arguments:
- *	psi is a pointer to the SetInfoRec we are building.
- *	pRanges is an array of xRecordRanges.
- *	nRanges is the number of elements in pRanges.
- *	byteoffset is the offset from the start of an xRecordRange of the
- *	  two bytes (1 for first, 1 for last) we are interested in.
- *	pExtSetInfo, if non-NULL, indicates that the two bytes mentioned
- *	  above are followed by four bytes (2 for first, 2 for last)
- *	  representing a minor opcode range, and this information should be
- *	  stored in one of the SetInfoRecs starting at pExtSetInfo.
- *	pnExtSetInfo is the number of elements in the pExtSetInfo array.
- *
- * Returns:  BadAlloc if a memory allocation error occurred, else Success.
- *
- * Side Effects:
- *	The slice of pRanges indicated by byteoffset is stored in psi.  
- *	If pExtSetInfo is non-NULL, minor opcode intervals are stored
- *	in an existing SetInfoRec if the major opcode interval matches, else
- *	they are stored in a new SetInfoRec, and *pnExtSetInfo is
- *	increased accordingly.
- */
-static int
-RecordConvertRangesToIntervals(
-    SetInfoPtr psi,
-    xRecordRange *pRanges,
-    int nRanges,
-    int byteoffset,
-    SetInfoPtr pExtSetInfo,
-    int *pnExtSetInfo
-)
-{
-    int i;
-    CARD8 *pCARD8;
-    int first, last;
-    int err;
-
-    for (i = 0; i < nRanges; i++, pRanges++)
-    {
-	pCARD8 = ((CARD8 *)pRanges) + byteoffset;
-	first = pCARD8[0];
-	last  = pCARD8[1];
-	if (first || last)
-	{
-	    if (!psi->intervals)
-	    {
-		err = RecordAllocIntervals(psi, 2 * (nRanges - i));
-		if (err != Success)
-		    return err;
-	    }
-	    psi->intervals[psi->nintervals].first = first;
-	    psi->intervals[psi->nintervals].last  = last;
-	    psi->nintervals++;
-	    assert(psi->nintervals <= psi->size);
-	    if (pExtSetInfo)
-	    {
-		SetInfoPtr pesi = pExtSetInfo;
-		CARD16 *pCARD16 = (CARD16 *)(pCARD8 + 2);
-		int j;
-
-		for (j = 0; j < *pnExtSetInfo; j++, pesi++)
-		{
-		    if ( (first == pesi->first) && (last == pesi->last) )
-			break;
-		}
-		if (j == *pnExtSetInfo)
-		{
-		    err = RecordAllocIntervals(pesi, 2 * (nRanges - i));
-		    if (err != Success)
-			return err;
-		    pesi->first = first;
-		    pesi->last  = last;
-		    (*pnExtSetInfo)++;
-		}
-		pesi->intervals[pesi->nintervals].first = pCARD16[0];
-		pesi->intervals[pesi->nintervals].last  = pCARD16[1];
-		pesi->nintervals++;
-		assert(pesi->nintervals <= pesi->size);
-	    }
-	}
-    }
-    return Success;
-}  /* end RecordConvertRangesToIntervals */
-
-#define offset_of(_structure, _field) \
-    ((char *)(& (_structure . _field)) - (char *)(&_structure))
-
-/* RecordRegisterClients
- *
- * Arguments:
- *	pContext is the context on which to register the clients.
- *	client is the client that issued the RecordCreateContext or
- *	  RecordRegisterClients request.
- *	stuff is a pointer to the request.
- *
- * Returns:
- *	Any one of several possible error values defined by the protocol.
- *	Success if everything is OK.
- *
- * Side Effects:
- *	If different element headers are specified, the context is flushed.
- *	If any of the specified clients are already registered on the
- *	context, they are first unregistered.  A new RCAP is created to
- *	hold the specified protocol and clients, and it is linked onto the
- *	context.  If the context is enabled, appropriate hooks are installed
- *	to record the new clients and protocol.
- */
-static int
-RecordRegisterClients(RecordContextPtr pContext, ClientPtr client, xRecordRegisterClientsReq *stuff)
-{
-    int err;
-    int i;
-    SetInfoPtr si;
-    int maxSets;
-    int nExtReqSets = 0;
-    int nExtRepSets = 0;
-    int extReqSetsOffset = 0;
-    int extRepSetsOffset = 0;
-    SetInfoPtr pExtReqSets, pExtRepSets;
-    int clientListOffset;
-    XID *pCanonClients;
-    int clientStarted = 0, clientDied = 0;
-    xRecordRange *pRanges, rr;
-    int nClients;
-    int sizeClients;
-    int totRCAPsize;
-    RecordClientsAndProtocolPtr pRCAP;
-    int pad;
-    XID recordingClient;
-
-    /* do all sanity checking up front */
-
-    err = RecordSanityCheckRegisterClients(pContext, client, stuff);
-    if (err != Success)
-	return err;
-
-    /* if element headers changed, flush buffer */
-	
-    if (pContext->elemHeaders != stuff->elementHeader)
-    {
-	RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
-	pContext->elemHeaders = stuff->elementHeader;
-    }
-
-    nClients = stuff->nClients;
-    if (!nClients)
-	/* if empty clients list, we're done. */
-	return Success;
-
-    recordingClient = pContext->pRecordingClient ?
-		      pContext->pRecordingClient->clientAsMask : 0;
-    pCanonClients = RecordCanonicalizeClientSpecifiers((XID *)&stuff[1],
-						 &nClients, recordingClient);
-    if (!pCanonClients)
-	return BadAlloc;
-
-    /* We may have to create as many as one set for each "predefined"
-     * protocol types, plus one per range for extension reuests, plus one per
-     * range for extension replies.
-     */
-    maxSets = PREDEFSETS + 2 * stuff->nRanges;
-    si = (SetInfoPtr)malloc(sizeof(SetInfoRec) * maxSets);
-    if (!si)
-    {
-	err = BadAlloc;
-	goto bailout;
-    }
-    memset(si, 0, sizeof(SetInfoRec) * maxSets);
-
-    /* theoretically you must do this because NULL may not be all-bits-zero */
-    for (i = 0; i < maxSets; i++)
-	si[i].intervals = NULL;
-
-    pExtReqSets = si + PREDEFSETS;
-    pExtRepSets = pExtReqSets + stuff->nRanges;
-
-    pRanges = (xRecordRange *)(((XID *)&stuff[1]) + stuff->nClients);
-
-    err = RecordConvertRangesToIntervals(&si[REQ], pRanges, stuff->nRanges,
-			offset_of(rr, coreRequestsFirst), NULL, NULL);
-    if (err != Success) goto bailout;
-
-    err = RecordConvertRangesToIntervals(&si[REQ], pRanges, stuff->nRanges,
-	   offset_of(rr, extRequestsMajorFirst), pExtReqSets, &nExtReqSets);
-    if (err != Success) goto bailout;
-
-    err = RecordConvertRangesToIntervals(&si[REP], pRanges, stuff->nRanges,
-			offset_of(rr, coreRepliesFirst), NULL, NULL);
-    if (err != Success) goto bailout;
-
-    err = RecordConvertRangesToIntervals(&si[REP], pRanges, stuff->nRanges,
-	   offset_of(rr, extRepliesMajorFirst), pExtRepSets, &nExtRepSets);
-    if (err != Success) goto bailout;
-
-    err = RecordConvertRangesToIntervals(&si[ERR], pRanges, stuff->nRanges,
-			offset_of(rr, errorsFirst), NULL, NULL);
-    if (err != Success) goto bailout;
-
-    err = RecordConvertRangesToIntervals(&si[DLEV], pRanges, stuff->nRanges,
-			offset_of(rr, deliveredEventsFirst), NULL, NULL);
-    if (err != Success) goto bailout;
-
-    err = RecordConvertRangesToIntervals(&si[DEV], pRanges, stuff->nRanges,
-			offset_of(rr, deviceEventsFirst), NULL, NULL);
-    if (err != Success) goto bailout;
-
-    /* collect client-started and client-died */
-
-    for (i = 0; i < stuff->nRanges; i++)
-    {
-	if (pRanges[i].clientStarted) clientStarted = TRUE;
-	if (pRanges[i].clientDied)    clientDied    = TRUE;
-    }
-
-    /*  We now have all the information collected to create all the sets,
-     * and we can compute the total memory required for the RCAP.
-     */
-
-    totRCAPsize = sizeof(RecordClientsAndProtocolRec);
-
-    /* leave a little room to grow before forcing a separate allocation */
-    sizeClients = nClients + CLIENT_ARRAY_GROWTH_INCREMENT;
-    pad = RecordPadAlign(totRCAPsize, sizeof(XID));
-    clientListOffset = totRCAPsize + pad;
-    totRCAPsize += pad + sizeClients * sizeof(XID);
-
-    if (nExtReqSets)
-    {
-	pad = RecordPadAlign(totRCAPsize, sizeof(RecordSetPtr));
-	extReqSetsOffset = totRCAPsize + pad;
-	totRCAPsize += pad + (nExtReqSets + 1) * sizeof(RecordMinorOpRec);
-    }
-    if (nExtRepSets)
-    {
-	pad = RecordPadAlign(totRCAPsize, sizeof(RecordSetPtr));
-	extRepSetsOffset = totRCAPsize + pad;
-	totRCAPsize += pad + (nExtRepSets + 1) * sizeof(RecordMinorOpRec);
-    }
-
-    for (i = 0; i < maxSets; i++)
-    {
-	if (si[i].nintervals)
-	{
-	    si[i].size = RecordSetMemoryRequirements(
-				si[i].intervals, si[i].nintervals, &si[i].align);
-	    pad = RecordPadAlign(totRCAPsize, si[i].align);
-	    si[i].offset = pad + totRCAPsize;
-	    totRCAPsize += pad + si[i].size;
-	}
-    }
-
-    /* allocate memory for the whole RCAP */
-
-    pRCAP = (RecordClientsAndProtocolPtr)malloc(totRCAPsize);
-    if (!pRCAP) 
-    {
-	err = BadAlloc;
-	goto bailout;
-    }
-
-    /* fill in the RCAP */
-
-    pRCAP->pContext = pContext;
-    pRCAP->pClientIDs = (XID *)((char *)pRCAP + clientListOffset);
-    pRCAP->numClients  = nClients;
-    pRCAP->sizeClients = sizeClients;
-    pRCAP->clientIDsSeparatelyAllocated = 0;
-    for (i = 0; i < nClients; i++)
-    {
-	RecordDeleteClientFromContext(pContext, pCanonClients[i]);
-	pRCAP->pClientIDs[i] = pCanonClients[i];
-    }
-
-    /* create all the sets */
-
-    if (si[REQ].intervals)
-    {
-	pRCAP->pRequestMajorOpSet =
-	    RecordCreateSet(si[REQ].intervals, si[REQ].nintervals,
-		(RecordSetPtr)((char *)pRCAP + si[REQ].offset), si[REQ].size);
-    }
-    else pRCAP->pRequestMajorOpSet = NULL;
-
-    if (si[REP].intervals)
-    {
-	pRCAP->pReplyMajorOpSet =
-	    RecordCreateSet(si[REP].intervals, si[REP].nintervals,
-		(RecordSetPtr)((char *)pRCAP + si[REP].offset), si[REP].size);
-    }
-    else pRCAP->pReplyMajorOpSet = NULL;
-
-    if (si[ERR].intervals)
-    {
-	pRCAP->pErrorSet =
-	    RecordCreateSet(si[ERR].intervals, si[ERR].nintervals,
-		(RecordSetPtr)((char *)pRCAP + si[ERR].offset), si[ERR].size);
-    }
-    else pRCAP->pErrorSet = NULL;
-
-    if (si[DEV].intervals)
-    {
-	pRCAP->pDeviceEventSet =
-	    RecordCreateSet(si[DEV].intervals, si[DEV].nintervals,
-		(RecordSetPtr)((char *)pRCAP + si[DEV].offset), si[DEV].size);
-    }
-    else pRCAP->pDeviceEventSet = NULL;
-
-    if (si[DLEV].intervals)
-    {
-	pRCAP->pDeliveredEventSet =
-	    RecordCreateSet(si[DLEV].intervals, si[DLEV].nintervals,
-	      (RecordSetPtr)((char *)pRCAP + si[DLEV].offset), si[DLEV].size);
-    }
-    else pRCAP->pDeliveredEventSet = NULL;
-
-    if (nExtReqSets)
-    {
-	pRCAP->pRequestMinOpInfo = (RecordMinorOpPtr)
-					((char *)pRCAP + extReqSetsOffset);
-	pRCAP->pRequestMinOpInfo[0].count = nExtReqSets;
-	for (i = 0; i < nExtReqSets; i++, pExtReqSets++)
-	{
-	    pRCAP->pRequestMinOpInfo[i+1].major.first = pExtReqSets->first;
-	    pRCAP->pRequestMinOpInfo[i+1].major.last  = pExtReqSets->last;
-	    pRCAP->pRequestMinOpInfo[i+1].major.pMinOpSet =
-		RecordCreateSet(pExtReqSets->intervals,
-				pExtReqSets->nintervals, 
-		  (RecordSetPtr)((char *)pRCAP + pExtReqSets->offset),
-				pExtReqSets->size);
-	}
-    }
-    else pRCAP->pRequestMinOpInfo = NULL;
-
-    if (nExtRepSets)
-    {
-	pRCAP->pReplyMinOpInfo = (RecordMinorOpPtr)
-					((char *)pRCAP + extRepSetsOffset);
-	pRCAP->pReplyMinOpInfo[0].count = nExtRepSets;
-	for (i = 0; i < nExtRepSets; i++, pExtRepSets++)
-	{
-	    pRCAP->pReplyMinOpInfo[i+1].major.first = pExtRepSets->first;
-	    pRCAP->pReplyMinOpInfo[i+1].major.last  = pExtRepSets->last;
-	    pRCAP->pReplyMinOpInfo[i+1].major.pMinOpSet =
-		RecordCreateSet(pExtRepSets->intervals,
-				pExtRepSets->nintervals, 
-		  (RecordSetPtr)((char *)pRCAP + pExtRepSets->offset),
-				pExtRepSets->size);
-	}
-    }
-    else pRCAP->pReplyMinOpInfo = NULL;
-
-    pRCAP->clientStarted = clientStarted;
-    pRCAP->clientDied    = clientDied;
-
-    /* link the RCAP onto the context */
-
-    pRCAP->pNextRCAP = pContext->pListOfRCAP;
-    pContext->pListOfRCAP = pRCAP;
-
-    if (pContext->pRecordingClient) /* context enabled */
-	RecordInstallHooks(pRCAP, 0);
-
-bailout:
-    if (si)
-    {
-	for (i = 0; i < maxSets; i++)
-	    free(si[i].intervals);
-	free(si);
-    }
-    if (pCanonClients && pCanonClients != (XID *)&stuff[1])
-	free(pCanonClients);
-    return err;
-} /* RecordRegisterClients */
-
-
-/* Proc functions all take a client argument, execute the request in
- * client->requestBuffer, and return a protocol error status.
- */
-
-static int
-ProcRecordQueryVersion(ClientPtr client)
-{
-    /* REQUEST(xRecordQueryVersionReq); */
-    xRecordQueryVersionReply 	rep;
-    int 		n;
-
-    REQUEST_SIZE_MATCH(xRecordQueryVersionReq);
-    rep.type        	= X_Reply;
-    rep.sequenceNumber 	= client->sequence;
-    rep.length         	= 0;
-    rep.majorVersion  	= SERVER_RECORD_MAJOR_VERSION;
-    rep.minorVersion  	= SERVER_RECORD_MINOR_VERSION;
-    if(client->swapped)
-    {
-    	swaps(&rep.sequenceNumber, n);
-	swaps(&rep.majorVersion, n);
-	swaps(&rep.minorVersion, n);
-    }
-    (void)WriteToClient(client, sizeof(xRecordQueryVersionReply),
-			(char *)&rep);
-    return Success;
-} /* ProcRecordQueryVersion */
-
-
-static int
-ProcRecordCreateContext(ClientPtr client)
-{
-    REQUEST(xRecordCreateContextReq);
-    RecordContextPtr pContext;
-    RecordContextPtr *ppNewAllContexts = NULL;
-    int err = BadAlloc;
-
-    REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq);
-    LEGAL_NEW_RESOURCE(stuff->context, client);
-
-    pContext = (RecordContextPtr)malloc(sizeof(RecordContextRec));
-    if (!pContext)
-	goto bailout;
-
-    /* make sure there is room in ppAllContexts to store the new context */
-
-    ppNewAllContexts = (RecordContextPtr *)
-	realloc(ppAllContexts, sizeof(RecordContextPtr) * (numContexts + 1));
-    if (!ppNewAllContexts)
-	goto bailout;
-    ppAllContexts = ppNewAllContexts;
-
-    pContext->id = stuff->context;
-    pContext->pRecordingClient = NULL;
-    pContext->pListOfRCAP = NULL;
-    pContext->elemHeaders = 0;
-    pContext->bufCategory = 0;
-    pContext->numBufBytes = 0;
-    pContext->pBufClient = NULL;
-    pContext->continuedReply = 0;
-    pContext->inFlush = 0;
-
-    err = RecordRegisterClients(pContext, client,
-				(xRecordRegisterClientsReq *)stuff);
-    if (err != Success)
-	goto bailout;
-
-    if (AddResource(pContext->id, RTContext, pContext))
-    {
-	ppAllContexts[numContexts++] = pContext;
-	return Success;
-    }
-    else
-    {
-	RecordDeleteContext((pointer)pContext, pContext->id);
-	err = BadAlloc;
-    }
-bailout:
-    free(pContext);
-    return err;
-} /* ProcRecordCreateContext */
-
-
-static int
-ProcRecordRegisterClients(ClientPtr client)
-{
-    RecordContextPtr pContext;
-    REQUEST(xRecordRegisterClientsReq);
-
-    REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq);
-    VERIFY_CONTEXT(pContext, stuff->context, client);
-
-    return RecordRegisterClients(pContext, client, stuff);
-} /* ProcRecordRegisterClients */
-
-
-static int
-ProcRecordUnregisterClients(ClientPtr client)
-{
-    RecordContextPtr pContext;
-    int err;
-    REQUEST(xRecordUnregisterClientsReq);
-    XID *pCanonClients;
-    int nClients;
-    int i;
-
-    REQUEST_AT_LEAST_SIZE(xRecordUnregisterClientsReq);
-    if ((client->req_len << 2) - SIZEOF(xRecordUnregisterClientsReq) !=
-	4 * stuff->nClients)
-	return BadLength;
-    VERIFY_CONTEXT(pContext, stuff->context, client);
-    err = RecordSanityCheckClientSpecifiers(client, (XID *)&stuff[1],
-					    stuff->nClients, 0);
-    if (err != Success)
-	return err;
-
-    nClients = stuff->nClients;
-    pCanonClients = RecordCanonicalizeClientSpecifiers((XID *)&stuff[1],
-						 &nClients, 0);
-    if (!pCanonClients)
-	return BadAlloc;
-
-    for (i = 0; i < nClients; i++)
-    {
-	RecordDeleteClientFromContext(pContext, pCanonClients[i]);
-    }
-    if (pCanonClients != (XID *)&stuff[1])
-	free(pCanonClients);
-    return Success;
-} /* ProcRecordUnregisterClients */
-
-
-/****************************************************************************/
-
-/* stuff for GetContext */
-
-/* This is a tactical structure used to hold the xRecordRanges as they are
- * being reconstituted from the sets in the RCAPs.
- */
-
-typedef struct {
-    xRecordRange *pRanges;  /* array of xRecordRanges for one RCAP */
-    int size;		/* number of elements in pRanges, >= nRanges */
-    int nRanges;	/* number of occupied element of pRanges */
-} GetContextRangeInfoRec, *GetContextRangeInfoPtr;
-
-
-/* RecordAllocRanges
- *
- * Arguments:
- *	pri is a pointer to a GetContextRangeInfoRec to allocate for.
- *	nRanges is the number of xRecordRanges desired for pri.
- *
- * Returns: BadAlloc if a memory allocation error occurred, else Success.
- *
- * Side Effects:
- *	If Success is returned, pri->pRanges points to at least nRanges
- *	ranges.  pri->nRanges is set to nRanges.  pri->size is the actual
- *	number of ranges.  Newly allocated ranges are zeroed.
- */
-static int
-RecordAllocRanges(GetContextRangeInfoPtr pri, int nRanges)
-{
-    int newsize;
-    xRecordRange *pNewRange;
-#define SZINCR 8
-
-    newsize = max(pri->size + SZINCR, nRanges);
-    pNewRange = (xRecordRange *)realloc(pri->pRanges,
-			 newsize * sizeof(xRecordRange));
-    if (!pNewRange)
-	return BadAlloc;
-
-    pri->pRanges = pNewRange;
-    pri->size = newsize;
-    memset(&pri->pRanges[pri->size - SZINCR], 0, SZINCR * sizeof(xRecordRange));
-    if (pri->nRanges < nRanges)
-	pri->nRanges = nRanges;
-    return Success;
-} /* RecordAllocRanges */
-
-
-/* RecordConvertSetToRanges
- *
- * Arguments:
- *	pSet is the set to be converted.
- *	pri is where the result should be stored.
- *	byteoffset is the offset from the start of an xRecordRange of the
- *	  two vales (first, last) we are interested in.
- *	card8 is TRUE if the vales are one byte each and FALSE if two bytes
- *	  each.
- *	imax is the largest set value to store in pri->pRanges.
- *	pStartIndex, if non-NULL, is the index of the first range in
- *	  pri->pRanges that should be stored to.  If NULL,
- *	  start at index 0.
- *
- * Returns: BadAlloc if a memory allocation error occurred, else Success.
- *
- * Side Effects:
- *	If Success is returned, the slice of pri->pRanges indicated by
- *	byteoffset and card8 is filled in with the intervals from pSet.
- *	if pStartIndex was non-NULL, *pStartIndex is filled in with one
- *	more than the index of the last xRecordRange that was touched.
- */
-static int
-RecordConvertSetToRanges(
-    RecordSetPtr pSet,
-    GetContextRangeInfoPtr pri,
-    int byteoffset,
-    Bool card8,
-    unsigned int imax,
-    int *pStartIndex
-)
-{
-    int nRanges;
-    RecordSetIteratePtr pIter = NULL;
-    RecordSetInterval interval;
-    CARD8 *pCARD8;
-    CARD16 *pCARD16;
-    int err;
-
-    if (!pSet)
-	return Success;
-
-    nRanges = pStartIndex ? *pStartIndex : 0;
-    while ((pIter = RecordIterateSet(pSet, pIter, &interval)))
-    {
-	if (interval.first > imax) break;
-	if (interval.last  > imax) interval.last = imax;
-	nRanges++;
-	if (nRanges > pri->size)
-	{
-	    err = RecordAllocRanges(pri, nRanges);
-	    if (err != Success)
-		return err;
-	}
-	else
-	    pri->nRanges = max(pri->nRanges, nRanges);
-	if (card8)
-	{
-	    pCARD8 = ((CARD8 *)&pri->pRanges[nRanges-1]) + byteoffset;
-	    *pCARD8++ = interval.first;
-	    *pCARD8   = interval.last;
-	}
-	else
-	{
-	    pCARD16 = (CARD16 *)
-			(((char *)&pri->pRanges[nRanges-1]) + byteoffset);
-	    *pCARD16++ = interval.first;
-	    *pCARD16   = interval.last;
-	}
-    }
-    if (pStartIndex)
-	*pStartIndex = nRanges;
-    return Success;
-} /* RecordConvertSetToRanges */
-
-
-/* RecordConvertMinorOpInfoToRanges
- *
- * Arguments:
- *	pMinOpInfo is the minor opcode info to convert to xRecordRanges.
- *	pri is where the result should be stored.
- *	byteoffset is the offset from the start of an xRecordRange of the
- *	  four vales (CARD8 major_first, CARD8 major_last,
- *	  CARD16 minor_first, CARD16 minor_last) we are going to store.
- *
- * Returns: BadAlloc if a memory allocation error occurred, else Success.
- *
- * Side Effects:
- *	If Success is returned, the slice of pri->pRanges indicated by
- *	byteoffset is filled in with the information from pMinOpInfo.
- */
-static int
-RecordConvertMinorOpInfoToRanges(
-    RecordMinorOpPtr pMinOpInfo,
-    GetContextRangeInfoPtr pri,
-    int byteoffset
-)
-{
-    int nsets;
-    int start;
-    int i;
-    int err;
-
-    if (!pMinOpInfo)
-	return Success;
-
-    nsets = pMinOpInfo->count;
-    pMinOpInfo++;
-    start = 0;
-    for (i = 0; i < nsets; i++)
-    {
-	int j, s;
-	s = start;
-	err = RecordConvertSetToRanges(pMinOpInfo[i].major.pMinOpSet, pri,
-				byteoffset + 2, FALSE, 65535, &start);
-	if (err != Success) return err;
-	for (j = s; j < start; j++)
-	{
-	    CARD8 *pCARD8 = ((CARD8 *)&pri->pRanges[j]) + byteoffset;
-	    *pCARD8++ = pMinOpInfo[i].major.first;
-	    *pCARD8   = pMinOpInfo[i].major.last;
-	}
-    }
-    return Success;
-} /* RecordConvertMinorOpInfoToRanges */
-
-
-/* RecordSwapRanges
- *
- * Arguments:
- *	pRanges is an array of xRecordRanges.
- *	nRanges is the number of elements in pRanges.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	The 16 bit fields of each xRecordRange are byte swapped.
- */
-static void
-RecordSwapRanges(xRecordRange *pRanges, int nRanges)
-{
-    int i;
-    register char n;
-    for (i = 0; i < nRanges; i++, pRanges++)
-    {
-	swaps(&pRanges->extRequestsMinorFirst, n);
-	swaps(&pRanges->extRequestsMinorLast, n);
-	swaps(&pRanges->extRepliesMinorFirst, n);
-	swaps(&pRanges->extRepliesMinorLast, n);
-    }
-} /* RecordSwapRanges */
-
-
-static int
-ProcRecordGetContext(ClientPtr client)
-{
-    RecordContextPtr pContext;
-    REQUEST(xRecordGetContextReq);
-    xRecordGetContextReply rep;
-    int n;
-    RecordClientsAndProtocolPtr pRCAP;
-    int nRCAPs = 0;
-    GetContextRangeInfoPtr pRangeInfo;
-    GetContextRangeInfoPtr pri;
-    int i;
-    int err;
-
-    REQUEST_SIZE_MATCH(xRecordGetContextReq);
-    VERIFY_CONTEXT(pContext, stuff->context, client);
-
-    /* how many RCAPs are there on this context? */
-
-    for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
-	nRCAPs++;
-
-    /* allocate and initialize space for record range info */
-
-    pRangeInfo = (GetContextRangeInfoPtr)malloc(
-				nRCAPs * sizeof(GetContextRangeInfoRec));
-    if (!pRangeInfo && nRCAPs > 0)
-	return BadAlloc;
-    for (i = 0; i < nRCAPs; i++)
-    {
-	pRangeInfo[i].pRanges = NULL;
-	pRangeInfo[i].size = 0;
-	pRangeInfo[i].nRanges = 0;
-    }
-
-    /* convert the RCAP (internal) representation of the recorded protocol
-     * to the wire protocol (external) representation, storing the information
-     * for the ith RCAP in pri[i]
-     */
-
-    for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
-	 pRCAP;
-	 pRCAP = pRCAP->pNextRCAP, pri++)
-    {
-	xRecordRange rr;
-
-	err = RecordConvertSetToRanges(pRCAP->pRequestMajorOpSet, pri,
-			offset_of(rr, coreRequestsFirst), TRUE, 127, NULL);
-	if (err != Success) goto bailout;
-
-	err = RecordConvertSetToRanges(pRCAP->pReplyMajorOpSet, pri,
-			offset_of(rr, coreRepliesFirst), TRUE, 127, NULL);
-	if (err != Success) goto bailout;
-
-	err = RecordConvertSetToRanges(pRCAP->pDeliveredEventSet, pri,
-			offset_of(rr, deliveredEventsFirst), TRUE, 255, NULL);
-	if (err != Success) goto bailout;
-
-	err = RecordConvertSetToRanges(pRCAP->pDeviceEventSet, pri,
-			offset_of(rr, deviceEventsFirst), TRUE, 255, NULL);
-	if (err != Success) goto bailout;
-
-	err = RecordConvertSetToRanges(pRCAP->pErrorSet, pri,
-			      offset_of(rr, errorsFirst), TRUE, 255, NULL);
-	if (err != Success) goto bailout;
-
-	err = RecordConvertMinorOpInfoToRanges(pRCAP->pRequestMinOpInfo,
-				pri, offset_of(rr, extRequestsMajorFirst));
-	if (err != Success) goto bailout;
-
-	err = RecordConvertMinorOpInfoToRanges(pRCAP->pReplyMinOpInfo,
-				pri, offset_of(rr, extRepliesMajorFirst));
-	if (err != Success) goto bailout;
-
-	if (pRCAP->clientStarted || pRCAP->clientDied)
-	{
-	    if (pri->nRanges == 0)
-		RecordAllocRanges(pri, 1);
-	    pri->pRanges[0].clientStarted = pRCAP->clientStarted;
-	    pri->pRanges[0].clientDied    = pRCAP->clientDied;
-	}
-    }
-
-    /* calculate number of clients and reply length */
-
-    rep.nClients = 0;
-    rep.length = 0;
-    for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
-	 pRCAP;
-	 pRCAP = pRCAP->pNextRCAP, pri++)
-    {
-	rep.nClients += pRCAP->numClients;
-	rep.length += pRCAP->numClients *
-		( bytes_to_int32(sizeof(xRecordClientInfo)) +
-		  pri->nRanges * bytes_to_int32(sizeof(xRecordRange)));
-    }
-
-    /* write the reply header */
-
-    rep.type = X_Reply;
-    rep.sequenceNumber 	= client->sequence;
-    rep.enabled = pContext->pRecordingClient != NULL;
-    rep.elementHeader = pContext->elemHeaders;
-    if(client->swapped)
-    {
-    	swaps(&rep.sequenceNumber, n);
-    	swapl(&rep.length, n);
-    	swapl(&rep.nClients, n);
-    }
-    (void)WriteToClient(client, sizeof(xRecordGetContextReply),
-			(char *)&rep);
-
-    /* write all the CLIENT_INFOs */
-
-    for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
-	 pRCAP;
-	 pRCAP = pRCAP->pNextRCAP, pri++)
-    {
-	xRecordClientInfo rci;
-	rci.nRanges = pri->nRanges;
-	if (client->swapped)
-	{
-	    swapl(&rci.nRanges, n);
-	    RecordSwapRanges(pri->pRanges, pri->nRanges);
-	}
-	for (i = 0; i < pRCAP->numClients; i++)
-	{
-	    rci.clientResource = pRCAP->pClientIDs[i];
-	    if (client->swapped) swapl(&rci.clientResource, n);
-	    WriteToClient(client, sizeof(xRecordClientInfo), (char *)&rci);
-	    WriteToClient(client, sizeof(xRecordRange) * pri->nRanges,
-			  (char *)pri->pRanges);
-	}
-    }
-    err = Success;
-
-bailout:
-    for (i = 0; i < nRCAPs; i++)
-    {
-	free(pRangeInfo[i].pRanges);
-    }
-    free(pRangeInfo);
-    return err;
-} /* ProcRecordGetContext */
-
-
-static int
-ProcRecordEnableContext(ClientPtr client)
-{
-    RecordContextPtr pContext;
-    REQUEST(xRecordEnableContextReq);
-    int i;
-    RecordClientsAndProtocolPtr pRCAP;
-
-    REQUEST_SIZE_MATCH(xRecordGetContextReq);
-    VERIFY_CONTEXT(pContext, stuff->context, client);
-    if (pContext->pRecordingClient)
-	return BadMatch; /* already enabled */
-
-    /* install record hooks for each RCAP */
-
-    for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
-    {
-	int err = RecordInstallHooks(pRCAP, 0);
-	if (err != Success)
-	{ /* undo the previous installs */
-	    RecordClientsAndProtocolPtr pUninstallRCAP;
-	    for (pUninstallRCAP = pContext->pListOfRCAP;
-		 pUninstallRCAP != pRCAP;
-		 pUninstallRCAP = pUninstallRCAP->pNextRCAP)
-	    {
-		RecordUninstallHooks(pUninstallRCAP, 0);
-	    }
-	    return err;
-	}
-    }
-
-    /* Disallow further request processing on this connection until
-     * the context is disabled.
-     */
-    IgnoreClient(client);
-    pContext->pRecordingClient = client;
-
-    /* Don't allow the data connection to record itself; unregister it. */
-    RecordDeleteClientFromContext(pContext,
-				  pContext->pRecordingClient->clientAsMask);
-
-    /* move the newly enabled context to the front part of ppAllContexts,
-     * where all the enabled contexts are
-     */
-    i = RecordFindContextOnAllContexts(pContext);
-    assert(i >= numEnabledContexts);
-    if (i != numEnabledContexts)
-    {
-	ppAllContexts[i] = ppAllContexts[numEnabledContexts];
-	ppAllContexts[numEnabledContexts] = pContext;
-    }
-
-    ++numEnabledContexts;
-    assert(numEnabledContexts > 0);
-
-    /* send StartOfData */
-    RecordAProtocolElement(pContext, NULL, XRecordStartOfData, NULL, 0, 0);
-    RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
-    return Success;
-} /* ProcRecordEnableContext */
-
-
-/* RecordDisableContext
- *
- * Arguments:
- *	pContext is the context to disable.
- *	nRanges is the number of elements in pRanges.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	If the context was enabled, it is disabled.  An EndOfData
- *	message is sent to the recording client.  Recording hooks for
- *	this context are uninstalled.  The context is moved to the
- *	rear part of the ppAllContexts array.  numEnabledContexts is
- *	decremented.  Request processing for the formerly recording client
- *	is resumed.
- */
-static void
-RecordDisableContext(RecordContextPtr pContext)
-{
-    RecordClientsAndProtocolPtr pRCAP;
-    int i;
-
-    if (!pContext->pRecordingClient) return;
-    if (!pContext->pRecordingClient->clientGone)
-    {
-	RecordAProtocolElement(pContext, NULL, XRecordEndOfData, NULL, 0, 0);
-	RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
-	/* Re-enable request processing on this connection. */
-	AttendClient(pContext->pRecordingClient);
-    }
-
-    for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
-    {
-	RecordUninstallHooks(pRCAP, 0);
-    }
-
-    pContext->pRecordingClient = NULL;
-
-    /* move the newly disabled context to the rear part of ppAllContexts,
-     * where all the disabled contexts are
-     */
-    i = RecordFindContextOnAllContexts(pContext);
-    assert( (i != -1) && (i < numEnabledContexts) );
-    if (i != (numEnabledContexts - 1) )
-    {
-	ppAllContexts[i] = ppAllContexts[numEnabledContexts-1];
-	ppAllContexts[numEnabledContexts-1] = pContext;
-    }
-    --numEnabledContexts;
-    assert(numEnabledContexts >= 0);
-} /* RecordDisableContext */
-
-
-static int
-ProcRecordDisableContext(ClientPtr client)
-{
-    RecordContextPtr pContext;
-    REQUEST(xRecordDisableContextReq);
-
-    REQUEST_SIZE_MATCH(xRecordDisableContextReq);
-    VERIFY_CONTEXT(pContext, stuff->context, client);
-    RecordDisableContext(pContext);
-    return Success;
-} /* ProcRecordDisableContext */
-
-
-/* RecordDeleteContext
- *
- * Arguments:
- *	value is the context to delete.
- *	id is its resource ID.
- *
- * Returns: Success.
- *
- * Side Effects:
- *	Disables the context, frees all associated memory, and removes
- *	it from the ppAllContexts array.
- */
-static int
-RecordDeleteContext(pointer value, XID id)
-{
-    int i;
-    RecordContextPtr pContext = (RecordContextPtr)value;
-    RecordClientsAndProtocolPtr pRCAP;
-
-    RecordDisableContext(pContext);
-
-    /*  Remove all the clients from all the RCAPs.
-     *  As a result, the RCAPs will be freed.
-     */
-
-    while ((pRCAP = pContext->pListOfRCAP))
-    {
-	int numClients = pRCAP->numClients;
-	/* when the last client is deleted, the RCAP will go away. */
-	while(numClients--)
-	{
-	    RecordDeleteClientFromRCAP(pRCAP, numClients);
-	}
-    }
-
-    /* remove context from AllContexts list */
-
-    if (-1 != (i = RecordFindContextOnAllContexts(pContext)))
-    {
-	ppAllContexts[i] = ppAllContexts[numContexts - 1];
-	if (--numContexts == 0)
-	{
-	    free(ppAllContexts);
-	    ppAllContexts = NULL;
-	}
-    }
-    free(pContext);
-
-    return Success;
-} /* RecordDeleteContext */
-
-
-static int
-ProcRecordFreeContext(ClientPtr client)
-{
-    RecordContextPtr pContext;
-    REQUEST(xRecordFreeContextReq);
-
-    REQUEST_SIZE_MATCH(xRecordFreeContextReq);
-    VERIFY_CONTEXT(pContext, stuff->context, client);
-    FreeResource(stuff->context, RT_NONE);
-    return Success;
-} /* ProcRecordFreeContext */
-
-
-static int
-ProcRecordDispatch(ClientPtr client)
-{
-    REQUEST(xReq);
-
-    switch (stuff->data)
-    {
-	case X_RecordQueryVersion:
-	    return ProcRecordQueryVersion(client);
-	case X_RecordCreateContext:
-	    return ProcRecordCreateContext(client);
-	case X_RecordRegisterClients:
-	    return ProcRecordRegisterClients(client);
-	case X_RecordUnregisterClients:
-	    return ProcRecordUnregisterClients(client);
-	case X_RecordGetContext:
-	    return ProcRecordGetContext(client);
-	case X_RecordEnableContext:
-	    return ProcRecordEnableContext(client);
-	case X_RecordDisableContext:
-	    return ProcRecordDisableContext(client);
-	case X_RecordFreeContext:
-	    return ProcRecordFreeContext(client);
-       default:
-	    return BadRequest;
-    }
-} /* ProcRecordDispatch */
-
-
-static int
-SProcRecordQueryVersion(ClientPtr client)
-{
-    REQUEST(xRecordQueryVersionReq);
-    register char 	n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xRecordQueryVersionReq);
-    swaps(&stuff->majorVersion, n);
-    swaps(&stuff->minorVersion,n);
-    return ProcRecordQueryVersion(client);
-} /* SProcRecordQueryVersion */
-
-
-static int
-SwapCreateRegister(xRecordRegisterClientsReq *stuff)
-{
-    register char n;
-    int i;
-    XID *pClientID;
-
-    swapl(&stuff->context, n);
-    swapl(&stuff->nClients, n);
-    swapl(&stuff->nRanges, n);
-    pClientID = (XID *)&stuff[1];
-    if (stuff->nClients > stuff->length - bytes_to_int32(sz_xRecordRegisterClientsReq))
-	return BadLength;
-    for (i = 0; i < stuff->nClients; i++, pClientID++)
-    {
-	swapl(pClientID, n);
-    }
-    if (stuff->nRanges > stuff->length - bytes_to_int32(sz_xRecordRegisterClientsReq)
-	- stuff->nClients)
-	return BadLength;
-    RecordSwapRanges((xRecordRange *)pClientID, stuff->nRanges);
-    return Success;
-} /* SwapCreateRegister */
-
-
-static int
-SProcRecordCreateContext(ClientPtr client)
-{
-    REQUEST(xRecordCreateContextReq);
-    int			status;
-    register char 	n;
-
-    swaps(&stuff->length, n);
-    REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq);
-    if ((status = SwapCreateRegister((pointer)stuff)) != Success)
-	return status;
-    return ProcRecordCreateContext(client);
-} /* SProcRecordCreateContext */
-
-
-static int
-SProcRecordRegisterClients(ClientPtr client)
-{
-    REQUEST(xRecordRegisterClientsReq);
-    int			status;
-    register char 	n;
-
-    swaps(&stuff->length, n);
-    REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq);
-    if ((status = SwapCreateRegister((pointer)stuff)) != Success)
-	return status;
-    return ProcRecordRegisterClients(client);
-} /* SProcRecordRegisterClients */
-
-
-static int
-SProcRecordUnregisterClients(ClientPtr client)
-{
-    REQUEST(xRecordUnregisterClientsReq);
-    register char 	n;
-
-    swaps(&stuff->length, n);
-    REQUEST_AT_LEAST_SIZE(xRecordUnregisterClientsReq);
-    swapl(&stuff->context, n);
-    swapl(&stuff->nClients, n);
-    SwapRestL(stuff);
-    return ProcRecordUnregisterClients(client);
-} /* SProcRecordUnregisterClients */
-
-
-static int
-SProcRecordGetContext(ClientPtr client)
-{
-    REQUEST(xRecordGetContextReq);
-    register char 	n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xRecordGetContextReq);
-    swapl(&stuff->context, n);
-    return ProcRecordGetContext(client);
-} /* SProcRecordGetContext */
-
-static int
-SProcRecordEnableContext(ClientPtr client)
-{
-    REQUEST(xRecordEnableContextReq);
-    register char 	n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xRecordEnableContextReq);
-    swapl(&stuff->context, n);
-    return ProcRecordEnableContext(client);
-} /* SProcRecordEnableContext */
-
-
-static int
-SProcRecordDisableContext(ClientPtr client)
-{
-    REQUEST(xRecordDisableContextReq);
-    register char 	n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xRecordDisableContextReq);
-    swapl(&stuff->context, n);
-    return ProcRecordDisableContext(client);
-} /* SProcRecordDisableContext */
-
-
-static int
-SProcRecordFreeContext(ClientPtr client)
-{
-    REQUEST(xRecordFreeContextReq);
-    register char 	n;
-
-    swaps(&stuff->length, n);
-    REQUEST_SIZE_MATCH(xRecordFreeContextReq);
-    swapl(&stuff->context, n);
-    return ProcRecordFreeContext(client);
-} /* SProcRecordFreeContext */
-
-
-static int
-SProcRecordDispatch(ClientPtr client)
-{
-    REQUEST(xReq);
-
-    switch (stuff->data)
-    {
-	case X_RecordQueryVersion:
-	    return SProcRecordQueryVersion(client);
-	case X_RecordCreateContext:
-	    return SProcRecordCreateContext(client);
-	case X_RecordRegisterClients:
-	    return SProcRecordRegisterClients(client);
-	case X_RecordUnregisterClients:
-	    return SProcRecordUnregisterClients(client);
-	case X_RecordGetContext:
-	    return SProcRecordGetContext(client);
-	case X_RecordEnableContext:
-	    return SProcRecordEnableContext(client);
-	case X_RecordDisableContext:
-	    return SProcRecordDisableContext(client);
-	case X_RecordFreeContext:
-	    return SProcRecordFreeContext(client);
-       default:
-	    return BadRequest;
-    }
-} /* SProcRecordDispatch */
-
-/* RecordConnectionSetupInfo
- *
- * Arguments:
- *	pContext is an enabled context that specifies recording of 
- *	  connection setup info.
- *	pci holds the connection setup info.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	The connection setup info is sent to the recording client.
- */
-static void
-RecordConnectionSetupInfo(RecordContextPtr pContext, NewClientInfoRec *pci)
-{
-    int prefixsize = SIZEOF(xConnSetupPrefix);
-    int restsize = pci->prefix->length * 4;
-
-    if (pci->client->swapped)
-    {
-	char *pConnSetup = (char *)malloc(prefixsize + restsize);
-	if (!pConnSetup)
-	    return;
-	SwapConnSetupPrefix(pci->prefix, (xConnSetupPrefix*)pConnSetup);
-	SwapConnSetupInfo((char*)pci->setup, (char*)(pConnSetup + prefixsize));
-	RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
-			       (pointer)pConnSetup, prefixsize + restsize, 0);
-	free(pConnSetup);
-    }
-    else
-    {
-	/* don't alloc and copy as in the swapped case; just send the
-	 * data in two pieces
-	 */
-	RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
-			(pointer)pci->prefix, prefixsize, restsize);
-	RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
-			(pointer)pci->setup, restsize, /* continuation */ -1);
-    }
-} /* RecordConnectionSetupInfo */
-
-
-/* RecordDeleteContext
- *
- * Arguments:
- *	pcbl is &ClientStateCallback.
- *	nullata is NULL.
- *	calldata is a pointer to a NewClientInfoRec (include/dixstruct.h)
- *	which contains information about client state changes.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	If a new client has connected and any contexts have specified
- *	XRecordFutureClients, the new client is registered on those contexts.
- *	If any of those contexts specify recording of the connection setup
- *	info, it is recorded.
- *
- *	If an existing client has disconnected, it is deleted from any
- *	contexts that it was registered on.  If any of those contexts
- *	specified XRecordClientDied, they record a ClientDied protocol element.
- *	If the disconnectiong client happened to be the data connection of an
- *	enabled context, the context is disabled.
- */
-
-static void
-RecordAClientStateChange(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
-{
-    NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
-    int i;
-    ClientPtr pClient = pci->client;
-    RecordContextPtr *ppAllContextsCopy = NULL;
-    int numContextsCopy = 0;
-
-    switch (pClient->clientState)
-    {
-    case ClientStateRunning: /* new client */
-	for (i = 0; i < numContexts; i++)
-	{
-	    RecordClientsAndProtocolPtr pRCAP;
-	    RecordContextPtr pContext = ppAllContexts[i];
-
-	    if ((pRCAP = RecordFindClientOnContext(pContext,
-					    XRecordFutureClients, NULL)))
-	    {
-		RecordAddClientToRCAP(pRCAP, pClient->clientAsMask);
-		if (pContext->pRecordingClient && pRCAP->clientStarted)
-		    RecordConnectionSetupInfo(pContext, pci);
-	    }
-	}
-    break;
-
-    case ClientStateGone:
-    case ClientStateRetained: /* client disconnected */
-
-        /* RecordDisableContext modifies contents of ppAllContexts. */
-	numContextsCopy = numContexts;
-	ppAllContextsCopy = malloc(numContextsCopy * sizeof(RecordContextPtr));
-	assert(ppAllContextsCopy);
-	memcpy(ppAllContextsCopy, ppAllContexts, numContextsCopy * sizeof(RecordContextPtr));
-
-	for (i = 0; i < numContextsCopy; i++)
-	{
-	    RecordClientsAndProtocolPtr pRCAP;
-	    RecordContextPtr pContext = ppAllContextsCopy[i];
-	    int pos;
-
-	    if (pContext->pRecordingClient == pClient)
-		RecordDisableContext(pContext);
-	    if ((pRCAP = RecordFindClientOnContext(pContext,
-				    pClient->clientAsMask, &pos)))
-	    {
-		if (pContext->pRecordingClient && pRCAP->clientDied)
-		    RecordAProtocolElement(pContext, pClient,
-					   XRecordClientDied, NULL, 0, 0);
-		RecordDeleteClientFromRCAP(pRCAP, pos);
-	    }
-	}
-
-	free(ppAllContextsCopy);
-    break;
-
-    default:
-    break;
-    } /* end switch on client state */
-} /* RecordAClientStateChange */
-
-
-/* RecordCloseDown
- *
- * Arguments:
- *	extEntry is the extension information for RECORD.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	Performs any cleanup needed by RECORD at server shutdown time.
- *	
- */
-static void
-RecordCloseDown(ExtensionEntry *extEntry)
-{
-    DeleteCallback(&ClientStateCallback, RecordAClientStateChange, NULL);
-} /* RecordCloseDown */
-
-
-/* RecordExtensionInit
- *
- * Arguments: none.
- *
- * Returns: nothing.
- *
- * Side Effects:
- *	Enables the RECORD extension if possible.
- */
-void 
-RecordExtensionInit(void)
-{
-    ExtensionEntry *extentry;
-
-    RTContext = CreateNewResourceType(RecordDeleteContext, "RecordContext");
-    if (!RTContext)
-	return;
-
-    if (!dixRegisterPrivateKey(RecordClientPrivateKey, PRIVATE_CLIENT, 0))
-        return;
-
-    ppAllContexts = NULL;
-    numContexts = numEnabledContexts = numEnabledRCAPs = 0;
-
-    if (!AddCallback(&ClientStateCallback, RecordAClientStateChange, NULL))
-	return;
-
-    extentry = AddExtension(RECORD_NAME, RecordNumEvents, RecordNumErrors,
-			    ProcRecordDispatch, SProcRecordDispatch,
-			    RecordCloseDown, StandardMinorOpcode);
-    if (!extentry)
-    {
-	DeleteCallback(&ClientStateCallback, RecordAClientStateChange, NULL);
-	return;
-    }
-    SetResourceTypeErrorValue(RTContext, extentry->errorBase + XRecordBadContext);
-
-} /* RecordExtensionInit */
-
+
+/*
+
+Copyright 1995, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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 OPEN GROUP 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.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+Author: David P. Wiggins, The Open Group
+
+This work benefited from earlier work done by Martha Zimet of NCD
+and Jim Haggerty of Metheus.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include <X11/extensions/recordproto.h>
+#include "set.h"
+#include "swaprep.h"
+#include "inputstr.h"
+#include "eventconvert.h"
+#include "scrnintstr.h"
+
+
+#include <stdio.h>
+#include <assert.h>
+
+#ifdef PANORAMIX
+#include "globals.h"
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#include "cursor.h"
+#endif
+
+#include "protocol-versions.h"
+
+static RESTYPE RTContext;   /* internal resource type for Record contexts */
+
+/* How many bytes of protocol data to buffer in a context. Don't set to less
+ * than 32.
+ */
+#define REPLY_BUF_SIZE 1024
+
+/* Record Context structure */
+
+typedef struct {
+    XID		id;		   /* resource id of context */
+    ClientPtr	pRecordingClient;  /* client that has context enabled */
+    struct _RecordClientsAndProtocolRec *pListOfRCAP; /* all registered info */
+    ClientPtr	pBufClient;	   /* client whose protocol is in replyBuffer*/
+    unsigned int continuedReply:1; /* recording a reply that is split up? */
+    char	elemHeaders;	   /* element header flags (time/seq no.) */
+    char	bufCategory;	   /* category of protocol in replyBuffer */
+    int		numBufBytes;	   /* number of bytes in replyBuffer */
+    char	replyBuffer[REPLY_BUF_SIZE]; /* buffered recorded protocol */
+    int		inFlush;           /*  are we inside RecordFlushReplyBuffer */
+} RecordContextRec, *RecordContextPtr;
+
+/*  RecordMinorOpRec - to hold minor opcode selections for extension requests
+ *  and replies
+ */
+
+typedef union {
+    int count; /* first element of array: how many "major" structs to follow */
+    struct {   /* rest of array elements are this */
+	short first;		/* first major opcode */
+	short last;		/* last major opcode */
+	RecordSetPtr pMinOpSet; /*  minor opcode set for above major range */
+    } major;
+} RecordMinorOpRec, *RecordMinorOpPtr;
+
+
+/*  RecordClientsAndProtocolRec, nicknamed RCAP - holds all the client and 
+ *  protocol selections passed in a single CreateContext or RegisterClients.
+ *  Generally, a context will have one of these from the create and an
+ *  additional one for each RegisterClients.  RCAPs are freed when all their
+ *  clients are unregistered.
+ */
+
+typedef struct _RecordClientsAndProtocolRec {
+    RecordContextPtr pContext;		 /* context that owns this RCAP */
+    struct _RecordClientsAndProtocolRec *pNextRCAP; /* next RCAP on context */
+    RecordSetPtr     pRequestMajorOpSet; /* requests to record */
+    RecordMinorOpPtr pRequestMinOpInfo;  /* extension requests to record */
+    RecordSetPtr     pReplyMajorOpSet;   /* replies to record */
+    RecordMinorOpPtr pReplyMinOpInfo;    /* extension replies to record */
+    RecordSetPtr     pDeviceEventSet;    /* device events to record */
+    RecordSetPtr     pDeliveredEventSet; /* delivered events to record */
+    RecordSetPtr     pErrorSet;          /* errors to record */
+    XID *	     pClientIDs;	 /* array of clients to record */
+    short 	     numClients;	 /* number of clients in pClientIDs */
+    short	     sizeClients;	 /* size of pClientIDs array */
+    unsigned int     clientStarted:1;	 /* record new client connections? */
+    unsigned int     clientDied:1;	 /* record client disconnections? */
+    unsigned int     clientIDsSeparatelyAllocated:1; /* pClientIDs malloced? */
+} RecordClientsAndProtocolRec, *RecordClientsAndProtocolPtr;
+
+/* how much bigger to make pRCAP->pClientIDs when reallocing */
+#define CLIENT_ARRAY_GROWTH_INCREMENT 4
+
+/* counts the total number of RCAPs belonging to enabled contexts. */
+static int numEnabledRCAPs;
+
+/*  void VERIFY_CONTEXT(RecordContextPtr, XID, ClientPtr)
+ *  In the spirit of the VERIFY_* macros in dix.h, this macro fills in
+ *  the context pointer if the given ID is a valid Record Context, else it
+ *  returns an error.
+ */
+#define VERIFY_CONTEXT(_pContext, _contextid, _client) { \
+    int rc = dixLookupResourceByType((pointer *)&(_pContext), _contextid, \
+                                     RTContext, _client, DixUseAccess); \
+    if (rc != Success) \
+	return rc; \
+}
+
+static int RecordDeleteContext(
+    pointer /*value*/,
+    XID /*id*/
+);
+
+void RecordExtensionInit(void);
+
+/***************************************************************************/
+
+/* client private stuff */
+
+/*  To make declarations less obfuscated, have a typedef for a pointer to a
+ *  Proc function.
+ */
+typedef int (*ProcFunctionPtr)(
+    ClientPtr /*pClient*/
+);
+
+/* Record client private.  Generally a client only has one of these if
+ * any of its requests are being recorded.
+ */
+typedef struct {
+/* ptr to client's proc vector before Record stuck its nose in */
+    ProcFunctionPtr *originalVector;   
+					
+/* proc vector with pointers for recorded requests redirected to the
+ * function RecordARequest
+ */
+    ProcFunctionPtr recordVector[256]; 
+} RecordClientPrivateRec, *RecordClientPrivatePtr;
+
+static DevPrivateKeyRec RecordClientPrivateKeyRec;
+#define RecordClientPrivateKey (&RecordClientPrivateKeyRec)
+
+/*  RecordClientPrivatePtr RecordClientPrivate(ClientPtr)
+ *  gets the client private of the given client.  Syntactic sugar.
+ */
+#define RecordClientPrivate(_pClient) (RecordClientPrivatePtr) \
+    dixLookupPrivate(&(_pClient)->devPrivates, RecordClientPrivateKey)
+
+
+/***************************************************************************/
+
+/* global list of all contexts */
+
+static RecordContextPtr *ppAllContexts;
+
+static int numContexts;/* number of contexts in ppAllContexts */
+
+/* number of currently enabled contexts.  All enabled contexts are bunched
+ * up at the front of the ppAllContexts array, from ppAllContexts[0] to
+ * ppAllContexts[numEnabledContexts-1], to eliminate time spent skipping
+ * past disabled contexts.
+ */
+static int numEnabledContexts;
+
+/* RecordFindContextOnAllContexts
+ *
+ * Arguments:
+ *	pContext is the context to search for.
+ *
+ * Returns:
+ *	The index into the array ppAllContexts at which pContext is stored.
+ *	If pContext is not found in ppAllContexts, returns -1.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordFindContextOnAllContexts(RecordContextPtr pContext)
+{
+    int i;
+
+    assert(numContexts >= numEnabledContexts);
+    for (i = 0; i < numContexts; i++)
+    {
+	if (ppAllContexts[i] == pContext)
+	    return i;
+    }
+    return -1;
+} /* RecordFindContextOnAllContexts */
+
+
+/***************************************************************************/
+
+/* RecordFlushReplyBuffer
+ *
+ * Arguments:
+ *	pContext is the context to flush.
+ *	data1 is a pointer to additional data, and len1 is its length in bytes.
+ *	data2 is a pointer to additional data, and len2 is its length in bytes.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	If the context is enabled, any buffered (recorded) protocol is written
+ *	to the recording client, and the number of buffered bytes is set to
+ *	zero.  If len1 is not zero, data1/len1 are then written to the
+ *	recording client, and similarly for data2/len2 (written after
+ *	data1/len1).
+ */
+static void
+RecordFlushReplyBuffer(
+    RecordContextPtr pContext,
+    pointer data1,
+    int len1,
+    pointer data2,
+    int len2
+)
+{
+    if (!pContext->pRecordingClient || pContext->pRecordingClient->clientGone || pContext->inFlush)
+	return;
+    ++pContext->inFlush;
+    if (pContext->numBufBytes)
+	WriteToClient(pContext->pRecordingClient, pContext->numBufBytes,
+		      (char *)pContext->replyBuffer);
+    pContext->numBufBytes = 0;
+    if (len1)
+	WriteToClient(pContext->pRecordingClient, len1, (char *)data1);
+    if (len2)
+	WriteToClient(pContext->pRecordingClient, len2, (char *)data2);
+    --pContext->inFlush;
+} /* RecordFlushReplyBuffer */
+
+
+/* RecordAProtocolElement
+ *
+ * Arguments:
+ *	pContext is the context that is recording a protocol element.
+ *	pClient is the client whose protocol is being recorded.  For
+ *	  device events and EndOfData, pClient is NULL.
+ *	category is the category of the protocol element, as defined
+ *	  by the RECORD spec.
+ *	data is a pointer to the protocol data, and datalen is its length
+ *	  in bytes.
+ *	futurelen is the number of bytes that will be sent in subsequent
+ *	  calls to this function to complete this protocol element.  
+ *	  In those subsequent calls, futurelen will be -1 to indicate
+ *	  that the current data is a continuation of the same protocol
+ *	  element.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	The context may be flushed.  The new protocol element will be
+ *	added to the context's protocol buffer with appropriate element
+ *	headers prepended (sequence number and timestamp).  If the data
+ *	is continuation data (futurelen == -1), element headers won't
+ *	be added.  If the protocol element and headers won't fit in
+ *	the context's buffer, it is sent directly to the recording
+ *	client (after any buffered data).
+ */
+static void
+RecordAProtocolElement(RecordContextPtr pContext, ClientPtr pClient,
+		       int category, pointer data, int datalen, int futurelen)
+{
+    CARD32 elemHeaderData[2];
+    int numElemHeaders = 0;
+    Bool recordingClientSwapped = pContext->pRecordingClient->swapped;
+    int n;
+    CARD32 serverTime = 0;
+    Bool gotServerTime = FALSE;
+    int replylen;
+
+    if (futurelen >= 0)
+    { /* start of new protocol element */
+	xRecordEnableContextReply *pRep = (xRecordEnableContextReply *)
+							pContext->replyBuffer;
+	if (pContext->pBufClient != pClient ||
+	    pContext->bufCategory != category)
+	{
+	    RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+	    pContext->pBufClient = pClient;
+	    pContext->bufCategory = category;
+	}
+
+	if (!pContext->numBufBytes)
+	{
+	    serverTime = GetTimeInMillis();
+	    gotServerTime = TRUE;
+	    pRep->type          = X_Reply;
+	    pRep->category      = category;
+	    pRep->sequenceNumber = pContext->pRecordingClient->sequence;
+	    pRep->length        = 0;
+	    pRep->elementHeader = pContext->elemHeaders;
+	    pRep->serverTime    = serverTime;
+	    if (pClient)
+	    {
+		pRep->clientSwapped =
+				(pClient->swapped != recordingClientSwapped);
+		pRep->idBase = pClient->clientAsMask;
+		pRep->recordedSequenceNumber = pClient->sequence;
+	    }
+	    else /* it's a device event, StartOfData, or EndOfData */
+	    {
+		pRep->clientSwapped = (category != XRecordFromServer) && 
+						recordingClientSwapped;
+		pRep->idBase = 0;
+		pRep->recordedSequenceNumber = 0;
+	    }
+
+	    if (recordingClientSwapped)
+	    {
+		swaps(&pRep->sequenceNumber, n);
+		swapl(&pRep->length, n);
+		swapl(&pRep->idBase, n);
+		swapl(&pRep->serverTime, n);
+		swapl(&pRep->recordedSequenceNumber, n);
+	    }
+	    pContext->numBufBytes = SIZEOF(xRecordEnableContextReply);
+	}
+
+	/* generate element headers if needed */
+
+	if ( ( (pContext->elemHeaders & XRecordFromClientTime)
+	      && category == XRecordFromClient)
+	    ||
+	    ( (pContext->elemHeaders & XRecordFromServerTime)
+	     && category == XRecordFromServer))
+	{
+	    if (gotServerTime)
+		elemHeaderData[numElemHeaders] = serverTime;
+	    else
+		elemHeaderData[numElemHeaders] = GetTimeInMillis();
+	    if (recordingClientSwapped)
+		swapl(&elemHeaderData[numElemHeaders], n);
+	    numElemHeaders++;
+	}
+
+	if ( (pContext->elemHeaders & XRecordFromClientSequence)
+	    &&
+	    (category == XRecordFromClient || category == XRecordClientDied))
+	{
+	    elemHeaderData[numElemHeaders] = pClient->sequence;
+	    if (recordingClientSwapped)
+		swapl(&elemHeaderData[numElemHeaders], n);
+	    numElemHeaders++;
+	}
+
+	/* adjust reply length */
+
+	replylen = pRep->length;
+	if (recordingClientSwapped) swapl(&replylen, n);
+	replylen += numElemHeaders + bytes_to_int32(datalen) +
+            bytes_to_int32(futurelen);
+	if (recordingClientSwapped) swapl(&replylen, n);
+	pRep->length = replylen;
+    } /* end if not continued reply */
+
+    numElemHeaders *= 4;
+
+    /* if space available >= space needed, buffer the data */
+
+    if (REPLY_BUF_SIZE - pContext->numBufBytes >= datalen + numElemHeaders)
+    {
+	if (numElemHeaders)
+	{
+	    memcpy(pContext->replyBuffer + pContext->numBufBytes,
+		   elemHeaderData, numElemHeaders);
+	    pContext->numBufBytes += numElemHeaders;
+	}
+	if (datalen)
+	{
+	    memcpy(pContext->replyBuffer + pContext->numBufBytes,
+		   data, datalen);
+	    pContext->numBufBytes += datalen;
+	}
+    }
+    else
+	RecordFlushReplyBuffer(pContext, (pointer)elemHeaderData,
+			       numElemHeaders, (pointer)data, datalen);
+
+} /* RecordAProtocolElement */
+
+
+/* RecordFindClientOnContext
+ *
+ * Arguments:
+ *	pContext is the context to search.
+ *	clientspec is the resource ID mask identifying the client to search
+ *	  for, or XRecordFutureClients.
+ *	pposition is a pointer to an int, or NULL.  See Returns.
+ *
+ * Returns:
+ *	The RCAP on which clientspec was found, or NULL if not found on
+ *	any RCAP on the given context.
+ *	If pposition was not NULL and the returned RCAP is not NULL,
+ *	*pposition will be set to the index into the returned the RCAP's
+ *	pClientIDs array that holds clientspec.
+ *
+ * Side Effects: none.
+ */
+static RecordClientsAndProtocolPtr
+RecordFindClientOnContext(
+    RecordContextPtr pContext,
+    XID clientspec,
+    int *pposition
+)
+{
+    RecordClientsAndProtocolPtr pRCAP;
+
+    for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+    {
+	int i;
+	for (i = 0; i < pRCAP->numClients; i++)
+	{
+	    if (pRCAP->pClientIDs[i] == clientspec)
+	    {
+		if (pposition)
+		    *pposition = i;
+		return pRCAP;
+	    }
+	}
+    }
+    return NULL;
+} /* RecordFindClientOnContext */
+
+
+/* RecordABigRequest
+ *
+ * Arguments:
+ *	pContext is the recording context.
+ *	client is the client being recorded.
+ *	stuff is a pointer to the big request of client (see the Big Requests
+ *	extension for details.)
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	The big request is recorded with the correct length field re-inserted.
+ *	
+ * Note: this function exists mainly to make RecordARequest smaller.
+ */
+static void
+RecordABigRequest(RecordContextPtr pContext, ClientPtr client, xReq *stuff)
+{
+    CARD32 bigLength;
+    char n;
+    int bytesLeft;
+
+    /* note: client->req_len has been frobbed by ReadRequestFromClient
+     * (os/io.c) to discount the extra 4 bytes taken by the extended length
+     * field in a big request.  The actual request length to record is
+     * client->req_len + 1 (measured in CARD32s).
+     */
+
+    /* record the request header */
+    bytesLeft = client->req_len << 2;
+    RecordAProtocolElement(pContext, client, XRecordFromClient,
+			   (pointer)stuff, SIZEOF(xReq), bytesLeft);
+
+    /* reinsert the extended length field that was squished out */
+    bigLength = client->req_len + bytes_to_int32(sizeof(bigLength));
+    if (client->swapped)
+	swapl(&bigLength, n);
+    RecordAProtocolElement(pContext, client, XRecordFromClient,
+		(pointer)&bigLength, sizeof(bigLength), /* continuation */ -1);
+    bytesLeft -= sizeof(bigLength);
+
+    /* record the rest of the request after the length */
+    RecordAProtocolElement(pContext, client, XRecordFromClient,
+		(pointer)(stuff + 1), bytesLeft, /* continuation */ -1);
+} /* RecordABigRequest */
+
+
+/* RecordARequest
+ *
+ * Arguments:
+ *	client is a client that the server has dispatched a request to by
+ *	calling client->requestVector[request opcode] .
+ *	The request is in client->requestBuffer.
+ *
+ * Returns:
+ *	Whatever is returned by the "real" Proc function for this request.
+ *	The "real" Proc function is the function that was in
+ *	client->requestVector[request opcode]  before it was replaced by
+ *	RecordARequest.  (See the function RecordInstallHooks.)
+ *
+ * Side Effects:
+ *	The request is recorded by all contexts that have registered this
+ *	request for this client.  The real Proc function is called.
+ */
+static int
+RecordARequest(ClientPtr client)
+{
+    RecordContextPtr pContext;
+    RecordClientsAndProtocolPtr pRCAP;
+    int i;
+    RecordClientPrivatePtr pClientPriv;
+    REQUEST(xReq);
+    int majorop;
+
+    majorop = stuff->reqType;
+    for (i = 0; i < numEnabledContexts; i++)
+    {
+	pContext = ppAllContexts[i];
+	pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
+					  NULL);
+	if (pRCAP && pRCAP->pRequestMajorOpSet &&
+	    RecordIsMemberOfSet(pRCAP->pRequestMajorOpSet, majorop))
+	{
+	    if (majorop <= 127)
+	    { /* core request */
+
+		if (stuff->length == 0)
+		    RecordABigRequest(pContext, client, stuff);
+		else
+		    RecordAProtocolElement(pContext, client, XRecordFromClient,
+				(pointer)stuff, client->req_len << 2, 0);
+	    }
+	    else /* extension, check minor opcode */
+	    {
+		int minorop = MinorOpcodeOfRequest(client);
+		int numMinOpInfo;
+		RecordMinorOpPtr pMinorOpInfo = pRCAP->pRequestMinOpInfo;
+
+		assert (pMinorOpInfo);
+		numMinOpInfo = pMinorOpInfo->count;
+		pMinorOpInfo++;
+		assert (numMinOpInfo);
+		for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
+		{
+		    if (majorop >= pMinorOpInfo->major.first &&
+			majorop <= pMinorOpInfo->major.last &&
+			RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
+					    minorop))
+		    {
+			if (stuff->length == 0)
+			    RecordABigRequest(pContext, client, stuff);
+			else
+			    RecordAProtocolElement(pContext, client, 
+					XRecordFromClient, (pointer)stuff,
+					client->req_len << 2, 0);
+			break;
+		    }			    
+		} /* end for each minor op info */
+	    } /* end extension request */
+	} /* end this RCAP wants this major opcode */
+    } /* end for each context */
+    pClientPriv = RecordClientPrivate(client);
+    assert(pClientPriv);
+    return (* pClientPriv->originalVector[majorop])(client);
+} /* RecordARequest */
+
+/* RecordAReply
+ *
+ * Arguments:
+ *	pcbl is &ReplyCallback.
+ *	nulldata is NULL.
+ *	calldata is a pointer to a ReplyInfoRec (include/os.h)
+ *	  which provides information about replies that are being sent
+ *	  to clients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	The reply is recorded by all contexts that have registered this
+ *	reply type for this client.  If more data belonging to the same
+ *	reply is expected, and if the reply is being recorded by any
+ *	context, pContext->continuedReply is set to 1.
+ *	If pContext->continuedReply was already 1 and this is the last
+ *	chunk of data belonging to this reply, it is set to 0.
+ */
+static void
+RecordAReply(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+{
+    RecordContextPtr pContext;
+    RecordClientsAndProtocolPtr pRCAP;
+    int eci;
+    int majorop;
+    ReplyInfoRec *pri = (ReplyInfoRec *)calldata;
+    ClientPtr client = pri->client;
+    REQUEST(xReq);
+
+    majorop = stuff->reqType;
+    for (eci = 0; eci < numEnabledContexts; eci++)
+    {
+	pContext = ppAllContexts[eci];
+	pRCAP = RecordFindClientOnContext(pContext, client->clientAsMask,
+					  NULL);
+	if (pRCAP)
+	{
+	    if (pContext->continuedReply)
+	    {
+		RecordAProtocolElement(pContext, client, XRecordFromServer,
+		   (pointer)pri->replyData, pri->dataLenBytes, /* continuation */ -1);
+		if (!pri->bytesRemaining)
+		    pContext->continuedReply = 0;
+	    }
+	    else if (pri->startOfReply && pRCAP->pReplyMajorOpSet &&
+		     RecordIsMemberOfSet(pRCAP->pReplyMajorOpSet, majorop))
+	    {
+		if (majorop <= 127)
+		{ /* core reply */
+		    RecordAProtocolElement(pContext, client, XRecordFromServer,
+		       (pointer)pri->replyData, pri->dataLenBytes, pri->bytesRemaining);
+		    if (pri->bytesRemaining)
+			pContext->continuedReply = 1;
+		}
+		else /* extension, check minor opcode */
+		{
+		    int minorop = MinorOpcodeOfRequest(client);
+		    int numMinOpInfo;
+		    RecordMinorOpPtr pMinorOpInfo = pRCAP->pReplyMinOpInfo;
+		    		    assert (pMinorOpInfo);
+		    numMinOpInfo = pMinorOpInfo->count;
+		    pMinorOpInfo++;
+		    assert (numMinOpInfo);
+		    for ( ; numMinOpInfo; numMinOpInfo--, pMinorOpInfo++)
+		    {
+			if (majorop >= pMinorOpInfo->major.first &&
+			    majorop <= pMinorOpInfo->major.last &&
+			    RecordIsMemberOfSet(pMinorOpInfo->major.pMinOpSet,
+						minorop))
+			{
+			    RecordAProtocolElement(pContext, client, 
+				XRecordFromServer, (pointer)pri->replyData,
+				pri->dataLenBytes, pri->bytesRemaining);
+			    if (pri->bytesRemaining)
+				pContext->continuedReply = 1;
+			    break;
+			}			    
+		    } /* end for each minor op info */
+		} /* end extension reply */
+	    } /* end continued reply vs. start of reply */
+	} /* end client is registered on this context */
+    } /* end for each context */
+} /* RecordAReply */
+
+
+/* RecordADeliveredEventOrError
+ *
+ * Arguments:
+ *	pcbl is &EventCallback.
+ *	nulldata is NULL.
+ *	calldata is a pointer to a EventInfoRec (include/dix.h)
+ *	  which provides information about events that are being sent
+ *	  to clients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	The event or error is recorded by all contexts that have registered
+ *	it for this client.
+ */
+static void
+RecordADeliveredEventOrError(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+{
+    EventInfoRec *pei = (EventInfoRec *)calldata;
+    RecordContextPtr pContext;
+    RecordClientsAndProtocolPtr pRCAP;
+    int eci; /* enabled context index */
+    ClientPtr pClient = pei->client;
+
+    for (eci = 0; eci < numEnabledContexts; eci++)
+    {
+	pContext = ppAllContexts[eci];
+	pRCAP = RecordFindClientOnContext(pContext, pClient->clientAsMask,
+					  NULL);
+	if (pRCAP && (pRCAP->pDeliveredEventSet || pRCAP->pErrorSet))
+	{
+	    int ev; /* event index */
+	    xEvent *pev = pei->events;
+	    for (ev = 0; ev < pei->count; ev++, pev++)
+	    {
+		int recordit = 0;
+		if (pRCAP->pErrorSet)
+		{
+		    recordit = RecordIsMemberOfSet(pRCAP->pErrorSet,
+						((xError *)(pev))->errorCode);
+		}
+		else if (pRCAP->pDeliveredEventSet)
+		{
+		    recordit = RecordIsMemberOfSet(pRCAP->pDeliveredEventSet,
+						   pev->u.u.type & 0177);
+		}
+		if (recordit)
+		{
+		    xEvent swappedEvent;
+		    xEvent *pEvToRecord = pev;
+
+		    if (pClient->swapped)
+		    {
+			(*EventSwapVector[pev->u.u.type & 0177])
+			    (pev, &swappedEvent);
+			pEvToRecord = &swappedEvent;
+			
+		    }
+		    RecordAProtocolElement(pContext, pClient,
+			XRecordFromServer, pEvToRecord, SIZEOF(xEvent), 0);
+		}
+	    } /* end for each event */
+	} /* end this client is on this context */
+    } /* end for each enabled context */
+} /* RecordADeliveredEventOrError */
+
+
+static void
+RecordSendProtocolEvents(RecordClientsAndProtocolPtr pRCAP,
+			RecordContextPtr pContext,
+			xEvent* pev, int count)
+{
+    int ev; /* event index */
+
+    for (ev = 0; ev < count; ev++, pev++)
+    {
+	if (RecordIsMemberOfSet(pRCAP->pDeviceEventSet,
+		    pev->u.u.type & 0177))
+	{
+	    xEvent swappedEvent;
+	    xEvent *pEvToRecord = pev;
+#ifdef PANORAMIX
+	    xEvent shiftedEvent;
+
+	    if (!noPanoramiXExtension &&
+		    (pev->u.u.type == MotionNotify ||
+		     pev->u.u.type == ButtonPress ||
+		     pev->u.u.type == ButtonRelease ||
+		     pev->u.u.type == KeyPress ||
+		     pev->u.u.type == KeyRelease)) {
+		int scr = XineramaGetCursorScreen(inputInfo.pointer);
+		memcpy(&shiftedEvent, pev, sizeof(xEvent));
+		shiftedEvent.u.keyButtonPointer.rootX +=
+		    screenInfo.screens[scr]->x -
+		    screenInfo.screens[0]->x;
+		shiftedEvent.u.keyButtonPointer.rootY +=
+		    screenInfo.screens[scr]->y -
+		    screenInfo.screens[0]->y;
+		pEvToRecord = &shiftedEvent;
+	    }
+#endif /* PANORAMIX */
+
+	    if (pContext->pRecordingClient->swapped)
+	    {
+		(*EventSwapVector[pEvToRecord->u.u.type & 0177])
+		    (pEvToRecord, &swappedEvent);
+		pEvToRecord = &swappedEvent;
+	    }
+
+	    RecordAProtocolElement(pContext, NULL,
+		    XRecordFromServer,  pEvToRecord, SIZEOF(xEvent), 0);
+	    /* make sure device events get flushed in the absence
+	     * of other client activity
+	     */
+	    SetCriticalOutputPending();
+	}
+    } /* end for each event */
+
+} /* RecordADeviceEvent */
+
+/* RecordADeviceEvent
+ *
+ * Arguments:
+ *	pcbl is &DeviceEventCallback.
+ *	nulldata is NULL.
+ *	calldata is a pointer to a DeviceEventInfoRec (include/dix.h)
+ *	  which provides information about device events that occur.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	The device event is recorded by all contexts that have registered
+ *	it for this client.
+ */
+static void
+RecordADeviceEvent(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+{
+    DeviceEventInfoRec *pei = (DeviceEventInfoRec *)calldata;
+    RecordContextPtr pContext;
+    RecordClientsAndProtocolPtr pRCAP;
+    int eci; /* enabled context index */
+
+    for (eci = 0; eci < numEnabledContexts; eci++)
+    {
+	pContext = ppAllContexts[eci];
+	for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+	{
+	    if (pRCAP->pDeviceEventSet)
+	    {
+		int count;
+		xEvent *xi_events = NULL;
+
+		/* TODO check return values */
+		if (IsMaster(pei->device))
+		{
+		    xEvent *core_events;
+		    EventToCore(pei->event, &core_events, &count);
+		    RecordSendProtocolEvents(pRCAP, pContext, core_events,
+                                             count);
+		    free(core_events);
+		}
+
+		EventToXI(pei->event, &xi_events, &count);
+		RecordSendProtocolEvents(pRCAP, pContext, xi_events, count);
+		free(xi_events);
+	    } /* end this RCAP selects device events */
+	} /* end for each RCAP on this context */
+    } /* end for each enabled context */
+}
+
+
+/* RecordFlushAllContexts
+ *
+ * Arguments:
+ *	pcbl is &FlushCallback.
+ *	nulldata and calldata are NULL.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	All buffered reply data of all enabled contexts is written to
+ *	the recording clients.
+ */
+static void
+RecordFlushAllContexts(
+    CallbackListPtr *pcbl,
+    pointer nulldata,
+    pointer calldata
+)
+{
+    int eci; /* enabled context index */
+    RecordContextPtr pContext;
+
+    for (eci = 0; eci < numEnabledContexts; eci++)
+    {
+	pContext = ppAllContexts[eci];
+
+	/* In most cases we leave it to RecordFlushReplyBuffer to make
+	 * this check, but this function could be called very often, so we
+	 * check before calling hoping to save the function call cost
+	 * most of the time.
+	 */
+	if (pContext->numBufBytes)
+	    RecordFlushReplyBuffer(ppAllContexts[eci], NULL, 0, NULL, 0);
+    }
+} /* RecordFlushAllContexts */
+
+
+/* RecordInstallHooks
+ *
+ * Arguments:
+ *	pRCAP is an RCAP on an enabled or being-enabled context.
+ *	oneclient can be zero or the resource ID mask identifying a client.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ *	Recording hooks needed by RCAP are installed.
+ *	If oneclient is zero, recording hooks needed for all clients and
+ *	protocol on the RCAP are installed.  If oneclient is non-zero,
+ *	only those hooks needed for the specified client are installed.
+ *	
+ *	Client requestVectors may be altered.  numEnabledRCAPs will be
+ *	incremented if oneclient == 0.  Callbacks may be added to
+ *	various callback lists.
+ */
+static int
+RecordInstallHooks(RecordClientsAndProtocolPtr pRCAP, XID oneclient)
+{
+    int i = 0;
+    XID client;
+
+    if (oneclient)
+	client = oneclient;
+    else
+	client = pRCAP->numClients ? pRCAP->pClientIDs[i++] : 0;
+
+    while (client)
+    {
+	if (client != XRecordFutureClients)
+	{
+	    if (pRCAP->pRequestMajorOpSet)
+	    {
+		RecordSetIteratePtr pIter = NULL;
+		RecordSetInterval interval;
+		ClientPtr pClient = clients[CLIENT_ID(client)];
+
+		if (pClient && !RecordClientPrivate(pClient))
+		{
+		    RecordClientPrivatePtr pClientPriv;
+		    /* no Record proc vector; allocate one */
+		    pClientPriv = (RecordClientPrivatePtr)
+				malloc(sizeof(RecordClientPrivateRec));
+		    if (!pClientPriv)
+			return BadAlloc;
+		    /* copy old proc vector to new */
+		    memcpy(pClientPriv->recordVector, pClient->requestVector, 
+			   sizeof (pClientPriv->recordVector));
+		    pClientPriv->originalVector = pClient->requestVector;
+		    dixSetPrivate(&pClient->devPrivates,
+				  RecordClientPrivateKey, pClientPriv);
+		    pClient->requestVector = pClientPriv->recordVector;
+		}
+		while ((pIter = RecordIterateSet(pRCAP->pRequestMajorOpSet,
+						pIter, &interval)))
+		{
+		    unsigned int j;
+		    for (j = interval.first; j <= interval.last; j++)
+			pClient->requestVector[j] = RecordARequest;
+		}
+	    }
+	}
+	if (oneclient)
+	    client = 0;
+	else
+	    client = (i < pRCAP->numClients) ? pRCAP->pClientIDs[i++] : 0;
+    }
+
+    assert(numEnabledRCAPs >= 0);
+    if (!oneclient && ++numEnabledRCAPs == 1)
+    { /* we're enabling the first context */
+	if (!AddCallback(&EventCallback, RecordADeliveredEventOrError, NULL))
+	    return BadAlloc;
+	if (!AddCallback(&DeviceEventCallback, RecordADeviceEvent, NULL))
+	    return BadAlloc;
+	if (!AddCallback(&ReplyCallback, RecordAReply, NULL))
+	    return BadAlloc;
+	if (!AddCallback(&FlushCallback, RecordFlushAllContexts, NULL))
+	    return BadAlloc;
+	/* Alternate context flushing scheme: delete the line above
+	 * and call RegisterBlockAndWakeupHandlers here passing
+	 * RecordFlushAllContexts.  Is this any better?
+	 */
+    }
+    return Success;
+} /* RecordInstallHooks */
+
+
+/* RecordUninstallHooks
+ *
+ * Arguments:
+ *	pRCAP is an RCAP on an enabled or being-disabled context.
+ *	oneclient can be zero or the resource ID mask identifying a client.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	Recording hooks needed by RCAP may be uninstalled.
+ *	If oneclient is zero, recording hooks needed for all clients and
+ *	protocol on the RCAP may be uninstalled.  If oneclient is non-zero,
+ *	only those hooks needed for the specified client may be uninstalled.
+ *	
+ *	Client requestVectors may be altered.  numEnabledRCAPs will be
+ *	decremented if oneclient == 0.  Callbacks may be deleted from
+ *	various callback lists.
+ */
+static void
+RecordUninstallHooks(RecordClientsAndProtocolPtr pRCAP, XID oneclient)
+{
+    int i = 0;
+    XID client;
+
+    if (oneclient)
+	client = oneclient;
+    else
+	client = pRCAP->numClients ? pRCAP->pClientIDs[i++] : 0;
+
+    while (client)
+    {
+	if (client != XRecordFutureClients)
+	{
+	    if (pRCAP->pRequestMajorOpSet)
+	    {
+		ClientPtr pClient = clients[CLIENT_ID(client)];
+		int c;
+		Bool otherRCAPwantsProcVector = FALSE;
+		RecordClientPrivatePtr pClientPriv = NULL;
+
+		assert (pClient);
+		pClientPriv = RecordClientPrivate(pClient);
+		assert (pClientPriv);
+		memcpy(pClientPriv->recordVector, pClientPriv->originalVector,
+		       sizeof (pClientPriv->recordVector));
+
+		for (c = 0; c < numEnabledContexts; c++)
+		{
+		    RecordClientsAndProtocolPtr pOtherRCAP;
+		    RecordContextPtr pContext = ppAllContexts[c];
+
+		    if (pContext == pRCAP->pContext) continue;
+		    pOtherRCAP = RecordFindClientOnContext(pContext, client,
+							   NULL);
+		    if (pOtherRCAP && pOtherRCAP->pRequestMajorOpSet)
+		    {
+			RecordSetIteratePtr pIter = NULL;
+			RecordSetInterval interval;
+
+			otherRCAPwantsProcVector = TRUE;
+			while ((pIter = RecordIterateSet(
+						pOtherRCAP->pRequestMajorOpSet,
+						pIter, &interval)))
+			{
+			    unsigned int j;
+			    for (j = interval.first; j <= interval.last; j++)
+				pClient->requestVector[j] = RecordARequest;
+			}
+		    }
+		}
+		if (!otherRCAPwantsProcVector)
+		{ /* nobody needs it, so free it */
+		    pClient->requestVector = pClientPriv->originalVector;
+		    dixSetPrivate(&pClient->devPrivates,
+				  RecordClientPrivateKey, NULL);
+		    free(pClientPriv);
+		}
+	    } /* end if this RCAP specifies any requests */
+	} /* end if not future clients */
+	if (oneclient)
+	    client = 0;
+	else
+	    client = (i < pRCAP->numClients) ? pRCAP->pClientIDs[i++] : 0;
+    }
+
+    assert(numEnabledRCAPs >= 1);
+    if (!oneclient && --numEnabledRCAPs == 0)
+    { /* we're disabling the last context */
+	DeleteCallback(&EventCallback, RecordADeliveredEventOrError, NULL);
+	DeleteCallback(&DeviceEventCallback, RecordADeviceEvent, NULL);
+	DeleteCallback(&ReplyCallback, RecordAReply, NULL);
+	DeleteCallback(&FlushCallback, RecordFlushAllContexts, NULL);
+	/* Alternate context flushing scheme: delete the line above
+	 * and call RemoveBlockAndWakeupHandlers here passing
+	 * RecordFlushAllContexts.  Is this any better?
+	 */
+	/* Having deleted the callback, call it one last time. -gildea */
+	RecordFlushAllContexts(&FlushCallback, NULL, NULL);
+    }
+} /* RecordUninstallHooks */
+
+
+/* RecordDeleteClientFromRCAP
+ *
+ * Arguments:
+ *	pRCAP is an RCAP to delete the client from.
+ *	position is the index into the array pRCAP->pClientIDs of the
+ *	client to delete.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	Recording hooks needed by client will be uninstalled if the context
+ *	is enabled.  The designated client will be removed from the 
+ *	pRCAP->pClientIDs array.  If it was the only client on the RCAP, 
+ *	the RCAP is removed from the context and freed.  (Invariant: RCAPs
+ *	have at least one client.)
+ */
+static void
+RecordDeleteClientFromRCAP(RecordClientsAndProtocolPtr pRCAP, int position)
+{
+    if (pRCAP->pContext->pRecordingClient)
+	RecordUninstallHooks(pRCAP, pRCAP->pClientIDs[position]);
+    if (position != pRCAP->numClients - 1)
+	pRCAP->pClientIDs[position] = pRCAP->pClientIDs[pRCAP->numClients - 1];
+    if (--pRCAP->numClients == 0)
+    {	/* no more clients; remove RCAP from context's list */
+	RecordContextPtr pContext = pRCAP->pContext;
+	if (pContext->pRecordingClient)
+	    RecordUninstallHooks(pRCAP, 0);
+	if (pContext->pListOfRCAP == pRCAP)
+	    pContext->pListOfRCAP = pRCAP->pNextRCAP;
+	else
+	{
+	    RecordClientsAndProtocolPtr prevRCAP;
+	    for (prevRCAP = pContext->pListOfRCAP;
+		 prevRCAP->pNextRCAP != pRCAP;
+		 prevRCAP = prevRCAP->pNextRCAP)
+		;
+	    prevRCAP->pNextRCAP = pRCAP->pNextRCAP;
+	}
+	/* free the RCAP */
+	if (pRCAP->clientIDsSeparatelyAllocated)
+	    free(pRCAP->pClientIDs);
+	free(pRCAP);
+    }
+} /* RecordDeleteClientFromRCAP */
+
+
+/* RecordAddClientToRCAP
+ *
+ * Arguments:
+ *	pRCAP is an RCAP to add the client to.
+ *	clientspec is the resource ID mask identifying a client, or
+ *	  XRecordFutureClients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	Recording hooks needed by client will be installed if the context
+ *	is enabled.  The designated client will be added to the 
+ *	pRCAP->pClientIDs array, which may be realloced.
+ *	pRCAP->clientIDsSeparatelyAllocated may be set to 1 if there
+ *	is no more room to hold clients internal to the RCAP.
+ */
+static void
+RecordAddClientToRCAP(RecordClientsAndProtocolPtr pRCAP, XID clientspec)
+{
+    if (pRCAP->numClients == pRCAP->sizeClients)
+    {
+	if (pRCAP->clientIDsSeparatelyAllocated)
+	{
+	    XID *pNewIDs = (XID *)realloc(pRCAP->pClientIDs,
+			(pRCAP->sizeClients + CLIENT_ARRAY_GROWTH_INCREMENT) *
+								sizeof(XID));
+	    if (!pNewIDs)
+		return;
+	    pRCAP->pClientIDs = pNewIDs;
+	    pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT;
+	}
+	else
+	{
+	    XID *pNewIDs = (XID *)malloc((pRCAP->sizeClients +
+				CLIENT_ARRAY_GROWTH_INCREMENT) * sizeof(XID));
+	    if (!pNewIDs)
+		return;
+	    memcpy(pNewIDs, pRCAP->pClientIDs, pRCAP->numClients *sizeof(XID));
+	    pRCAP->pClientIDs = pNewIDs;
+	    pRCAP->sizeClients += CLIENT_ARRAY_GROWTH_INCREMENT;
+	    pRCAP->clientIDsSeparatelyAllocated = 1;
+	}
+    }
+    pRCAP->pClientIDs[pRCAP->numClients++] = clientspec;
+    if (pRCAP->pContext->pRecordingClient)
+	RecordInstallHooks(pRCAP, clientspec);
+} /* RecordDeleteClientFromRCAP */
+
+
+/* RecordDeleteClientFromContext
+ *
+ * Arguments:
+ *	pContext is the context to delete from.
+ *	clientspec is the resource ID mask identifying a client, or
+ *	  XRecordFutureClients.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	If clientspec is on any RCAP of the context, it is deleted from that
+ *	RCAP.  (A given clientspec can only be on one RCAP of a context.)
+ */
+static void
+RecordDeleteClientFromContext(RecordContextPtr pContext, XID clientspec)
+{
+    RecordClientsAndProtocolPtr pRCAP;
+    int position;
+
+    if ((pRCAP = RecordFindClientOnContext(pContext, clientspec, &position)))
+	RecordDeleteClientFromRCAP(pRCAP, position);
+} /* RecordDeleteClientFromContext */
+
+
+/* RecordSanityCheckClientSpecifiers
+ *
+ * Arguments:
+ *	clientspecs is an array of alleged CLIENTSPECs passed by the client.
+ *	nspecs is the number of elements in clientspecs.
+ *	errorspec, if non-zero, is the resource id base of a client that
+ *	  must not appear in clienspecs.
+ *
+ * Returns: BadMatch if any of the clientspecs are invalid, else Success.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordSanityCheckClientSpecifiers(ClientPtr client, XID *clientspecs, int nspecs, XID errorspec)
+{
+    int i;
+    int clientIndex;
+    int rc;
+    pointer value;
+
+    for (i = 0; i < nspecs; i++)
+    {
+	if (clientspecs[i] == XRecordCurrentClients ||
+	    clientspecs[i] == XRecordFutureClients ||
+	    clientspecs[i] == XRecordAllClients)
+	    continue;
+	if (errorspec && (CLIENT_BITS(clientspecs[i]) == errorspec) )
+	    return BadMatch;
+	clientIndex = CLIENT_ID(clientspecs[i]);
+	if (clientIndex && clients[clientIndex] &&
+	    clients[clientIndex]->clientState == ClientStateRunning)
+	{
+	    if (clientspecs[i] == clients[clientIndex]->clientAsMask)
+		continue;
+            rc = dixLookupResourceByClass(&value, clientspecs[i], RC_ANY,
+                                          client, DixGetAttrAccess);
+            if (rc != Success)
+                return rc;
+	}
+	else
+	    return BadMatch;
+    }
+    return Success;
+} /* RecordSanityCheckClientSpecifiers */
+
+
+/* RecordCanonicalizeClientSpecifiers
+ *
+ * Arguments:
+ *	pClientspecs is an array of CLIENTSPECs that have been sanity
+ *	  checked.
+ *	pNumClientspecs is a pointer to the number of elements in pClientspecs.
+ *	excludespec, if non-zero, is the resource id base of a client that 
+ *	  should not be included in the expansion of XRecordAllClients or 
+ *	  XRecordCurrentClients.
+ *
+ * Returns:
+ *	A pointer to an array of CLIENTSPECs that is the same as the
+ *	passed array with the following modifications:
+ *	  - all but the client id bits of resource IDs are stripped off.
+ *	  - duplicates removed.
+ *	  - XRecordAllClients expanded to a list of all currently connected
+ *	    clients + XRecordFutureClients - excludespec (if non-zero)
+ *	  - XRecordCurrentClients expanded to a list of all currently
+ *	    connected clients - excludespec (if non-zero)
+ *	The returned array may be the passed array modified in place, or
+ *	it may be an malloc'ed array.  The caller should keep a pointer to the
+ *	original array and free the returned array if it is different.
+ *
+ *	*pNumClientspecs is set to the number of elements in the returned
+ *	array.
+ *
+ * Side Effects:
+ *	pClientspecs may be modified in place.
+ */
+static XID *
+RecordCanonicalizeClientSpecifiers(XID *pClientspecs, int *pNumClientspecs, XID excludespec)
+{
+    int i;
+    int numClients = *pNumClientspecs;
+
+    /*  first pass strips off the resource index bits, leaving just the
+     *  client id bits.  This makes searching for a particular client simpler
+     *  (and faster.)
+     */
+    for (i = 0; i < numClients; i++)
+    {
+	XID cs = pClientspecs[i];
+	if (cs > XRecordAllClients)
+	    pClientspecs[i] = CLIENT_BITS(cs);
+    }
+
+    for (i = 0; i < numClients; i++)
+    {
+	if (pClientspecs[i] == XRecordAllClients ||
+	    pClientspecs[i] == XRecordCurrentClients)
+	{ /* expand All/Current */
+	    int j, nc;
+	    XID *pCanon = (XID *)malloc(sizeof(XID) * (currentMaxClients + 1));
+	    if (!pCanon) return NULL;
+	    for (nc = 0, j = 1; j < currentMaxClients; j++)
+	    {
+		ClientPtr client = clients[j];
+		if (client != NullClient &&
+		    client->clientState == ClientStateRunning &&
+		    client->clientAsMask != excludespec)
+		{
+		    pCanon[nc++] = client->clientAsMask;
+		}
+	    }
+	    if (pClientspecs[i] == XRecordAllClients)
+		pCanon[nc++] = XRecordFutureClients;
+	    *pNumClientspecs = nc;
+	    return pCanon;
+	}
+	else /* not All or Current */
+	{
+	    int j;
+	    for (j = i + 1; j < numClients; )
+	    {
+		if (pClientspecs[i] == pClientspecs[j])
+		{
+		    pClientspecs[j] = pClientspecs[--numClients];
+		}
+		else
+		    j++;
+	    }
+	}
+    } /* end for each clientspec */
+    *pNumClientspecs = numClients;
+    return pClientspecs;
+} /* RecordCanonicalizeClientSpecifiers */
+
+
+/****************************************************************************/
+
+/* stuff for RegisterClients */
+
+/* RecordPadAlign
+ *
+ * Arguments:
+ *	size is the number of bytes taken by an object.
+ *	align is a byte boundary (e.g. 4, 8)
+ *
+ * Returns:
+ *	the number of pad bytes to add at the end of an object of the
+ *	given size so that an object placed immediately behind it will
+ *	begin on an <align>-byte boundary.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordPadAlign(int size, int align)
+{
+    return (align - (size & (align - 1))) & (align - 1);
+} /* RecordPadAlign */
+
+
+/* RecordSanityCheckRegisterClients
+ *
+ * Arguments:
+ *	pContext is the context being registered on.
+ *	client is the client that issued a RecordCreateContext or
+ *	  RecordRegisterClients request.
+ *	stuff is a pointer to the request.
+ *
+ * Returns:
+ *	Any one of several possible error values if any of the request
+ *	arguments are invalid.  Success if everything is OK.
+ *
+ * Side Effects: none.
+ */
+static int
+RecordSanityCheckRegisterClients(RecordContextPtr pContext, ClientPtr client, xRecordRegisterClientsReq *stuff)
+{
+    int err;
+    xRecordRange *pRange;
+    int i;
+    XID recordingClient;
+
+    if (((client->req_len << 2) - SIZEOF(xRecordRegisterClientsReq)) !=
+	4 * stuff->nClients + SIZEOF(xRecordRange) * stuff->nRanges)
+	return BadLength;
+
+    if (stuff->elementHeader &
+     ~(XRecordFromClientSequence|XRecordFromClientTime|XRecordFromServerTime))
+    {
+	client->errorValue = stuff->elementHeader;
+	return BadValue;
+    }
+
+    recordingClient = pContext->pRecordingClient ?
+		      pContext->pRecordingClient->clientAsMask : 0;
+    err = RecordSanityCheckClientSpecifiers(client, (XID *)&stuff[1],
+					    stuff->nClients, recordingClient);
+    if (err != Success) return err;
+
+    pRange = (xRecordRange *)(((XID *)&stuff[1]) + stuff->nClients);
+    for (i = 0; i < stuff->nRanges; i++, pRange++)
+    {
+	if (pRange->coreRequestsFirst > pRange->coreRequestsLast)
+	{
+	    client->errorValue = pRange->coreRequestsFirst;
+	    return BadValue;
+	}
+	if (pRange->coreRepliesFirst > pRange->coreRepliesLast)
+	{
+	    client->errorValue = pRange->coreRepliesFirst;
+	    return BadValue;
+	}
+	if ((pRange->extRequestsMajorFirst || pRange->extRequestsMajorLast) &&
+	    (pRange->extRequestsMajorFirst < 128 ||
+	     pRange->extRequestsMajorLast < 128 ||
+	     pRange->extRequestsMajorFirst > pRange->extRequestsMajorLast))
+	{
+	    client->errorValue = pRange->extRequestsMajorFirst;
+	    return BadValue;
+	}
+	if (pRange->extRequestsMinorFirst > pRange->extRequestsMinorLast)
+	{
+	    client->errorValue = pRange->extRequestsMinorFirst;
+	    return BadValue;
+	}
+	if ((pRange->extRepliesMajorFirst || pRange->extRepliesMajorLast) &&
+	    (pRange->extRepliesMajorFirst < 128 ||
+	     pRange->extRepliesMajorLast < 128 ||
+	     pRange->extRepliesMajorFirst > pRange->extRepliesMajorLast))
+	{
+	    client->errorValue = pRange->extRepliesMajorFirst;
+	    return BadValue;
+	}
+	if (pRange->extRepliesMinorFirst > pRange->extRepliesMinorLast)
+	{
+	    client->errorValue = pRange->extRepliesMinorFirst;
+	    return BadValue;
+	}
+	if ((pRange->deliveredEventsFirst || pRange->deliveredEventsLast) &&
+	    (pRange->deliveredEventsFirst < 2 ||
+	     pRange->deliveredEventsLast < 2 ||
+	     pRange->deliveredEventsFirst > pRange->deliveredEventsLast))
+	{
+	    client->errorValue = pRange->deliveredEventsFirst;
+	    return BadValue;
+	}
+	if ((pRange->deviceEventsFirst || pRange->deviceEventsLast) &&
+	    (pRange->deviceEventsFirst < 2 ||
+	     pRange->deviceEventsLast < 2 ||
+	     pRange->deviceEventsFirst > pRange->deviceEventsLast))
+	{
+	    client->errorValue = pRange->deviceEventsFirst;
+	    return BadValue;
+	}
+	if (pRange->errorsFirst > pRange->errorsLast)
+	{
+	    client->errorValue = pRange->errorsFirst;
+	    return BadValue;
+	}
+	if (pRange->clientStarted != xFalse && pRange->clientStarted != xTrue)
+	{
+	    client->errorValue = pRange->clientStarted;
+	    return BadValue;
+	}
+	if (pRange->clientDied != xFalse && pRange->clientDied != xTrue)
+	{
+	    client->errorValue = pRange->clientDied;
+	    return BadValue;
+	}
+    } /* end for each range */
+    return Success;
+} /* end RecordSanityCheckRegisterClients */
+
+/* This is a tactical structure used to gather information about all the sets
+ * (RecordSetPtr) that need to be created for an RCAP in the process of 
+ * digesting a list of RECORDRANGEs (converting it to the internal
+ * representation).
+ */
+typedef struct
+{
+    int nintervals;	/* number of intervals in following array */
+    RecordSetInterval *intervals;  /* array of intervals for this set */
+    int size;		/* size of intevals array; >= nintervals */
+    int align;		/* alignment restriction for set */
+    int offset;		/* where to store set pointer rel. to start of RCAP */
+    short first, last;	/* if for extension, major opcode interval */
+} SetInfoRec, *SetInfoPtr;
+
+/* These constant are used to index into an array of SetInfoRec. */
+enum {REQ,	/* set info for requests */
+      REP,	/* set info for replies */
+      ERR,	/* set info for errors */
+      DEV,	/* set info for device events */
+      DLEV,	/* set info for delivered events */
+      PREDEFSETS};  /* number of predefined array entries */
+
+
+/* RecordAllocIntervals
+ *
+ * Arguments:
+ *	psi is a pointer to a SetInfoRec whose intervals pointer is NULL.
+ *	nIntervals is the desired size of the intervals array.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ *	If Success is returned, psi->intervals is a pointer to size
+ *	RecordSetIntervals, all zeroed, and psi->size is set to size.
+ */
+static int
+RecordAllocIntervals(SetInfoPtr psi, int nIntervals)
+{
+    assert(!psi->intervals);
+    psi->intervals = (RecordSetInterval *)
+			malloc(nIntervals * sizeof(RecordSetInterval));
+    if (!psi->intervals)
+	return BadAlloc;
+    memset(psi->intervals, 0, nIntervals * sizeof(RecordSetInterval));
+    psi->size = nIntervals;
+    return Success;
+} /* end RecordAllocIntervals */
+
+
+/* RecordConvertRangesToIntervals
+ *
+ * Arguments:
+ *	psi is a pointer to the SetInfoRec we are building.
+ *	pRanges is an array of xRecordRanges.
+ *	nRanges is the number of elements in pRanges.
+ *	byteoffset is the offset from the start of an xRecordRange of the
+ *	  two bytes (1 for first, 1 for last) we are interested in.
+ *	pExtSetInfo, if non-NULL, indicates that the two bytes mentioned
+ *	  above are followed by four bytes (2 for first, 2 for last)
+ *	  representing a minor opcode range, and this information should be
+ *	  stored in one of the SetInfoRecs starting at pExtSetInfo.
+ *	pnExtSetInfo is the number of elements in the pExtSetInfo array.
+ *
+ * Returns:  BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ *	The slice of pRanges indicated by byteoffset is stored in psi.  
+ *	If pExtSetInfo is non-NULL, minor opcode intervals are stored
+ *	in an existing SetInfoRec if the major opcode interval matches, else
+ *	they are stored in a new SetInfoRec, and *pnExtSetInfo is
+ *	increased accordingly.
+ */
+static int
+RecordConvertRangesToIntervals(
+    SetInfoPtr psi,
+    xRecordRange *pRanges,
+    int nRanges,
+    int byteoffset,
+    SetInfoPtr pExtSetInfo,
+    int *pnExtSetInfo
+)
+{
+    int i;
+    CARD8 *pCARD8;
+    int first, last;
+    int err;
+
+    for (i = 0; i < nRanges; i++, pRanges++)
+    {
+	pCARD8 = ((CARD8 *)pRanges) + byteoffset;
+	first = pCARD8[0];
+	last  = pCARD8[1];
+	if (first || last)
+	{
+	    if (!psi->intervals)
+	    {
+		err = RecordAllocIntervals(psi, 2 * (nRanges - i));
+		if (err != Success)
+		    return err;
+	    }
+	    psi->intervals[psi->nintervals].first = first;
+	    psi->intervals[psi->nintervals].last  = last;
+	    psi->nintervals++;
+	    assert(psi->nintervals <= psi->size);
+	    if (pExtSetInfo)
+	    {
+		SetInfoPtr pesi = pExtSetInfo;
+		CARD16 *pCARD16 = (CARD16 *)(pCARD8 + 2);
+		int j;
+
+		for (j = 0; j < *pnExtSetInfo; j++, pesi++)
+		{
+		    if ( (first == pesi->first) && (last == pesi->last) )
+			break;
+		}
+		if (j == *pnExtSetInfo)
+		{
+		    err = RecordAllocIntervals(pesi, 2 * (nRanges - i));
+		    if (err != Success)
+			return err;
+		    pesi->first = first;
+		    pesi->last  = last;
+		    (*pnExtSetInfo)++;
+		}
+		pesi->intervals[pesi->nintervals].first = pCARD16[0];
+		pesi->intervals[pesi->nintervals].last  = pCARD16[1];
+		pesi->nintervals++;
+		assert(pesi->nintervals <= pesi->size);
+	    }
+	}
+    }
+    return Success;
+}  /* end RecordConvertRangesToIntervals */
+
+#define offset_of(_structure, _field) \
+    ((char *)(& (_structure . _field)) - (char *)(&_structure))
+
+/* RecordRegisterClients
+ *
+ * Arguments:
+ *	pContext is the context on which to register the clients.
+ *	client is the client that issued the RecordCreateContext or
+ *	  RecordRegisterClients request.
+ *	stuff is a pointer to the request.
+ *
+ * Returns:
+ *	Any one of several possible error values defined by the protocol.
+ *	Success if everything is OK.
+ *
+ * Side Effects:
+ *	If different element headers are specified, the context is flushed.
+ *	If any of the specified clients are already registered on the
+ *	context, they are first unregistered.  A new RCAP is created to
+ *	hold the specified protocol and clients, and it is linked onto the
+ *	context.  If the context is enabled, appropriate hooks are installed
+ *	to record the new clients and protocol.
+ */
+static int
+RecordRegisterClients(RecordContextPtr pContext, ClientPtr client, xRecordRegisterClientsReq *stuff)
+{
+    int err;
+    int i;
+    SetInfoPtr si;
+    int maxSets;
+    int nExtReqSets = 0;
+    int nExtRepSets = 0;
+    int extReqSetsOffset = 0;
+    int extRepSetsOffset = 0;
+    SetInfoPtr pExtReqSets, pExtRepSets;
+    int clientListOffset;
+    XID *pCanonClients;
+    int clientStarted = 0, clientDied = 0;
+    xRecordRange *pRanges, rr;
+    int nClients;
+    int sizeClients;
+    int totRCAPsize;
+    RecordClientsAndProtocolPtr pRCAP;
+    int pad;
+    XID recordingClient;
+
+    /* do all sanity checking up front */
+
+    err = RecordSanityCheckRegisterClients(pContext, client, stuff);
+    if (err != Success)
+	return err;
+
+    /* if element headers changed, flush buffer */
+	
+    if (pContext->elemHeaders != stuff->elementHeader)
+    {
+	RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+	pContext->elemHeaders = stuff->elementHeader;
+    }
+
+    nClients = stuff->nClients;
+    if (!nClients)
+	/* if empty clients list, we're done. */
+	return Success;
+
+    recordingClient = pContext->pRecordingClient ?
+		      pContext->pRecordingClient->clientAsMask : 0;
+    pCanonClients = RecordCanonicalizeClientSpecifiers((XID *)&stuff[1],
+						 &nClients, recordingClient);
+    if (!pCanonClients)
+	return BadAlloc;
+
+    /* We may have to create as many as one set for each "predefined"
+     * protocol types, plus one per range for extension reuests, plus one per
+     * range for extension replies.
+     */
+    maxSets = PREDEFSETS + 2 * stuff->nRanges;
+    si = (SetInfoPtr)malloc(sizeof(SetInfoRec) * maxSets);
+    if (!si)
+    {
+	err = BadAlloc;
+	goto bailout;
+    }
+    memset(si, 0, sizeof(SetInfoRec) * maxSets);
+
+    /* theoretically you must do this because NULL may not be all-bits-zero */
+    for (i = 0; i < maxSets; i++)
+	si[i].intervals = NULL;
+
+    pExtReqSets = si + PREDEFSETS;
+    pExtRepSets = pExtReqSets + stuff->nRanges;
+
+    pRanges = (xRecordRange *)(((XID *)&stuff[1]) + stuff->nClients);
+
+    err = RecordConvertRangesToIntervals(&si[REQ], pRanges, stuff->nRanges,
+			offset_of(rr, coreRequestsFirst), NULL, NULL);
+    if (err != Success) goto bailout;
+
+    err = RecordConvertRangesToIntervals(&si[REQ], pRanges, stuff->nRanges,
+	   offset_of(rr, extRequestsMajorFirst), pExtReqSets, &nExtReqSets);
+    if (err != Success) goto bailout;
+
+    err = RecordConvertRangesToIntervals(&si[REP], pRanges, stuff->nRanges,
+			offset_of(rr, coreRepliesFirst), NULL, NULL);
+    if (err != Success) goto bailout;
+
+    err = RecordConvertRangesToIntervals(&si[REP], pRanges, stuff->nRanges,
+	   offset_of(rr, extRepliesMajorFirst), pExtRepSets, &nExtRepSets);
+    if (err != Success) goto bailout;
+
+    err = RecordConvertRangesToIntervals(&si[ERR], pRanges, stuff->nRanges,
+			offset_of(rr, errorsFirst), NULL, NULL);
+    if (err != Success) goto bailout;
+
+    err = RecordConvertRangesToIntervals(&si[DLEV], pRanges, stuff->nRanges,
+			offset_of(rr, deliveredEventsFirst), NULL, NULL);
+    if (err != Success) goto bailout;
+
+    err = RecordConvertRangesToIntervals(&si[DEV], pRanges, stuff->nRanges,
+			offset_of(rr, deviceEventsFirst), NULL, NULL);
+    if (err != Success) goto bailout;
+
+    /* collect client-started and client-died */
+
+    for (i = 0; i < stuff->nRanges; i++)
+    {
+	if (pRanges[i].clientStarted) clientStarted = TRUE;
+	if (pRanges[i].clientDied)    clientDied    = TRUE;
+    }
+
+    /*  We now have all the information collected to create all the sets,
+     * and we can compute the total memory required for the RCAP.
+     */
+
+    totRCAPsize = sizeof(RecordClientsAndProtocolRec);
+
+    /* leave a little room to grow before forcing a separate allocation */
+    sizeClients = nClients + CLIENT_ARRAY_GROWTH_INCREMENT;
+    pad = RecordPadAlign(totRCAPsize, sizeof(XID));
+    clientListOffset = totRCAPsize + pad;
+    totRCAPsize += pad + sizeClients * sizeof(XID);
+
+    if (nExtReqSets)
+    {
+	pad = RecordPadAlign(totRCAPsize, sizeof(RecordSetPtr));
+	extReqSetsOffset = totRCAPsize + pad;
+	totRCAPsize += pad + (nExtReqSets + 1) * sizeof(RecordMinorOpRec);
+    }
+    if (nExtRepSets)
+    {
+	pad = RecordPadAlign(totRCAPsize, sizeof(RecordSetPtr));
+	extRepSetsOffset = totRCAPsize + pad;
+	totRCAPsize += pad + (nExtRepSets + 1) * sizeof(RecordMinorOpRec);
+    }
+
+    for (i = 0; i < maxSets; i++)
+    {
+	if (si[i].nintervals)
+	{
+	    si[i].size = RecordSetMemoryRequirements(
+				si[i].intervals, si[i].nintervals, &si[i].align);
+	    pad = RecordPadAlign(totRCAPsize, si[i].align);
+	    si[i].offset = pad + totRCAPsize;
+	    totRCAPsize += pad + si[i].size;
+	}
+    }
+
+    /* allocate memory for the whole RCAP */
+
+    pRCAP = (RecordClientsAndProtocolPtr)malloc(totRCAPsize);
+    if (!pRCAP) 
+    {
+	err = BadAlloc;
+	goto bailout;
+    }
+
+    /* fill in the RCAP */
+
+    pRCAP->pContext = pContext;
+    pRCAP->pClientIDs = (XID *)((char *)pRCAP + clientListOffset);
+    pRCAP->numClients  = nClients;
+    pRCAP->sizeClients = sizeClients;
+    pRCAP->clientIDsSeparatelyAllocated = 0;
+    for (i = 0; i < nClients; i++)
+    {
+	RecordDeleteClientFromContext(pContext, pCanonClients[i]);
+	pRCAP->pClientIDs[i] = pCanonClients[i];
+    }
+
+    /* create all the sets */
+
+    if (si[REQ].intervals)
+    {
+	pRCAP->pRequestMajorOpSet =
+	    RecordCreateSet(si[REQ].intervals, si[REQ].nintervals,
+		(RecordSetPtr)((char *)pRCAP + si[REQ].offset), si[REQ].size);
+    }
+    else pRCAP->pRequestMajorOpSet = NULL;
+
+    if (si[REP].intervals)
+    {
+	pRCAP->pReplyMajorOpSet =
+	    RecordCreateSet(si[REP].intervals, si[REP].nintervals,
+		(RecordSetPtr)((char *)pRCAP + si[REP].offset), si[REP].size);
+    }
+    else pRCAP->pReplyMajorOpSet = NULL;
+
+    if (si[ERR].intervals)
+    {
+	pRCAP->pErrorSet =
+	    RecordCreateSet(si[ERR].intervals, si[ERR].nintervals,
+		(RecordSetPtr)((char *)pRCAP + si[ERR].offset), si[ERR].size);
+    }
+    else pRCAP->pErrorSet = NULL;
+
+    if (si[DEV].intervals)
+    {
+	pRCAP->pDeviceEventSet =
+	    RecordCreateSet(si[DEV].intervals, si[DEV].nintervals,
+		(RecordSetPtr)((char *)pRCAP + si[DEV].offset), si[DEV].size);
+    }
+    else pRCAP->pDeviceEventSet = NULL;
+
+    if (si[DLEV].intervals)
+    {
+	pRCAP->pDeliveredEventSet =
+	    RecordCreateSet(si[DLEV].intervals, si[DLEV].nintervals,
+	      (RecordSetPtr)((char *)pRCAP + si[DLEV].offset), si[DLEV].size);
+    }
+    else pRCAP->pDeliveredEventSet = NULL;
+
+    if (nExtReqSets)
+    {
+	pRCAP->pRequestMinOpInfo = (RecordMinorOpPtr)
+					((char *)pRCAP + extReqSetsOffset);
+	pRCAP->pRequestMinOpInfo[0].count = nExtReqSets;
+	for (i = 0; i < nExtReqSets; i++, pExtReqSets++)
+	{
+	    pRCAP->pRequestMinOpInfo[i+1].major.first = pExtReqSets->first;
+	    pRCAP->pRequestMinOpInfo[i+1].major.last  = pExtReqSets->last;
+	    pRCAP->pRequestMinOpInfo[i+1].major.pMinOpSet =
+		RecordCreateSet(pExtReqSets->intervals,
+				pExtReqSets->nintervals, 
+		  (RecordSetPtr)((char *)pRCAP + pExtReqSets->offset),
+				pExtReqSets->size);
+	}
+    }
+    else pRCAP->pRequestMinOpInfo = NULL;
+
+    if (nExtRepSets)
+    {
+	pRCAP->pReplyMinOpInfo = (RecordMinorOpPtr)
+					((char *)pRCAP + extRepSetsOffset);
+	pRCAP->pReplyMinOpInfo[0].count = nExtRepSets;
+	for (i = 0; i < nExtRepSets; i++, pExtRepSets++)
+	{
+	    pRCAP->pReplyMinOpInfo[i+1].major.first = pExtRepSets->first;
+	    pRCAP->pReplyMinOpInfo[i+1].major.last  = pExtRepSets->last;
+	    pRCAP->pReplyMinOpInfo[i+1].major.pMinOpSet =
+		RecordCreateSet(pExtRepSets->intervals,
+				pExtRepSets->nintervals, 
+		  (RecordSetPtr)((char *)pRCAP + pExtRepSets->offset),
+				pExtRepSets->size);
+	}
+    }
+    else pRCAP->pReplyMinOpInfo = NULL;
+
+    pRCAP->clientStarted = clientStarted;
+    pRCAP->clientDied    = clientDied;
+
+    /* link the RCAP onto the context */
+
+    pRCAP->pNextRCAP = pContext->pListOfRCAP;
+    pContext->pListOfRCAP = pRCAP;
+
+    if (pContext->pRecordingClient) /* context enabled */
+	RecordInstallHooks(pRCAP, 0);
+
+bailout:
+    if (si)
+    {
+	for (i = 0; i < maxSets; i++)
+	    free(si[i].intervals);
+	free(si);
+    }
+    if (pCanonClients && pCanonClients != (XID *)&stuff[1])
+	free(pCanonClients);
+    return err;
+} /* RecordRegisterClients */
+
+
+/* Proc functions all take a client argument, execute the request in
+ * client->requestBuffer, and return a protocol error status.
+ */
+
+static int
+ProcRecordQueryVersion(ClientPtr client)
+{
+    /* REQUEST(xRecordQueryVersionReq); */
+    xRecordQueryVersionReply 	rep;
+    int 		n;
+
+    REQUEST_SIZE_MATCH(xRecordQueryVersionReq);
+    rep.type        	= X_Reply;
+    rep.sequenceNumber 	= client->sequence;
+    rep.length         	= 0;
+    rep.majorVersion  	= SERVER_RECORD_MAJOR_VERSION;
+    rep.minorVersion  	= SERVER_RECORD_MINOR_VERSION;
+    if(client->swapped)
+    {
+    	swaps(&rep.sequenceNumber, n);
+	swaps(&rep.majorVersion, n);
+	swaps(&rep.minorVersion, n);
+    }
+    (void)WriteToClient(client, sizeof(xRecordQueryVersionReply),
+			(char *)&rep);
+    return Success;
+} /* ProcRecordQueryVersion */
+
+
+static int
+ProcRecordCreateContext(ClientPtr client)
+{
+    REQUEST(xRecordCreateContextReq);
+    RecordContextPtr pContext;
+    RecordContextPtr *ppNewAllContexts = NULL;
+    int err = BadAlloc;
+
+    REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq);
+    LEGAL_NEW_RESOURCE(stuff->context, client);
+
+    pContext = (RecordContextPtr)malloc(sizeof(RecordContextRec));
+    if (!pContext)
+	goto bailout;
+
+    /* make sure there is room in ppAllContexts to store the new context */
+
+    ppNewAllContexts = (RecordContextPtr *)
+	realloc(ppAllContexts, sizeof(RecordContextPtr) * (numContexts + 1));
+    if (!ppNewAllContexts)
+	goto bailout;
+    ppAllContexts = ppNewAllContexts;
+
+    pContext->id = stuff->context;
+    pContext->pRecordingClient = NULL;
+    pContext->pListOfRCAP = NULL;
+    pContext->elemHeaders = 0;
+    pContext->bufCategory = 0;
+    pContext->numBufBytes = 0;
+    pContext->pBufClient = NULL;
+    pContext->continuedReply = 0;
+    pContext->inFlush = 0;
+
+    err = RecordRegisterClients(pContext, client,
+				(xRecordRegisterClientsReq *)stuff);
+    if (err != Success)
+	goto bailout;
+
+    if (AddResource(pContext->id, RTContext, pContext))
+    {
+	ppAllContexts[numContexts++] = pContext;
+	return Success;
+    }
+    else
+    {
+	RecordDeleteContext((pointer)pContext, pContext->id);
+	err = BadAlloc;
+    }
+bailout:
+    free(pContext);
+    return err;
+} /* ProcRecordCreateContext */
+
+
+static int
+ProcRecordRegisterClients(ClientPtr client)
+{
+    RecordContextPtr pContext;
+    REQUEST(xRecordRegisterClientsReq);
+
+    REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq);
+    VERIFY_CONTEXT(pContext, stuff->context, client);
+
+    return RecordRegisterClients(pContext, client, stuff);
+} /* ProcRecordRegisterClients */
+
+
+static int
+ProcRecordUnregisterClients(ClientPtr client)
+{
+    RecordContextPtr pContext;
+    int err;
+    REQUEST(xRecordUnregisterClientsReq);
+    XID *pCanonClients;
+    int nClients;
+    int i;
+
+    REQUEST_AT_LEAST_SIZE(xRecordUnregisterClientsReq);
+    if ((client->req_len << 2) - SIZEOF(xRecordUnregisterClientsReq) !=
+	4 * stuff->nClients)
+	return BadLength;
+    VERIFY_CONTEXT(pContext, stuff->context, client);
+    err = RecordSanityCheckClientSpecifiers(client, (XID *)&stuff[1],
+					    stuff->nClients, 0);
+    if (err != Success)
+	return err;
+
+    nClients = stuff->nClients;
+    pCanonClients = RecordCanonicalizeClientSpecifiers((XID *)&stuff[1],
+						 &nClients, 0);
+    if (!pCanonClients)
+	return BadAlloc;
+
+    for (i = 0; i < nClients; i++)
+    {
+	RecordDeleteClientFromContext(pContext, pCanonClients[i]);
+    }
+    if (pCanonClients != (XID *)&stuff[1])
+	free(pCanonClients);
+    return Success;
+} /* ProcRecordUnregisterClients */
+
+
+/****************************************************************************/
+
+/* stuff for GetContext */
+
+/* This is a tactical structure used to hold the xRecordRanges as they are
+ * being reconstituted from the sets in the RCAPs.
+ */
+
+typedef struct {
+    xRecordRange *pRanges;  /* array of xRecordRanges for one RCAP */
+    int size;		/* number of elements in pRanges, >= nRanges */
+    int nRanges;	/* number of occupied element of pRanges */
+} GetContextRangeInfoRec, *GetContextRangeInfoPtr;
+
+
+/* RecordAllocRanges
+ *
+ * Arguments:
+ *	pri is a pointer to a GetContextRangeInfoRec to allocate for.
+ *	nRanges is the number of xRecordRanges desired for pri.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ *	If Success is returned, pri->pRanges points to at least nRanges
+ *	ranges.  pri->nRanges is set to nRanges.  pri->size is the actual
+ *	number of ranges.  Newly allocated ranges are zeroed.
+ */
+static int
+RecordAllocRanges(GetContextRangeInfoPtr pri, int nRanges)
+{
+    int newsize;
+    xRecordRange *pNewRange;
+#define SZINCR 8
+
+    newsize = max(pri->size + SZINCR, nRanges);
+    pNewRange = (xRecordRange *)realloc(pri->pRanges,
+			 newsize * sizeof(xRecordRange));
+    if (!pNewRange)
+	return BadAlloc;
+
+    pri->pRanges = pNewRange;
+    pri->size = newsize;
+    memset(&pri->pRanges[pri->size - SZINCR], 0, SZINCR * sizeof(xRecordRange));
+    if (pri->nRanges < nRanges)
+	pri->nRanges = nRanges;
+    return Success;
+} /* RecordAllocRanges */
+
+
+/* RecordConvertSetToRanges
+ *
+ * Arguments:
+ *	pSet is the set to be converted.
+ *	pri is where the result should be stored.
+ *	byteoffset is the offset from the start of an xRecordRange of the
+ *	  two vales (first, last) we are interested in.
+ *	card8 is TRUE if the vales are one byte each and FALSE if two bytes
+ *	  each.
+ *	imax is the largest set value to store in pri->pRanges.
+ *	pStartIndex, if non-NULL, is the index of the first range in
+ *	  pri->pRanges that should be stored to.  If NULL,
+ *	  start at index 0.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ *	If Success is returned, the slice of pri->pRanges indicated by
+ *	byteoffset and card8 is filled in with the intervals from pSet.
+ *	if pStartIndex was non-NULL, *pStartIndex is filled in with one
+ *	more than the index of the last xRecordRange that was touched.
+ */
+static int
+RecordConvertSetToRanges(
+    RecordSetPtr pSet,
+    GetContextRangeInfoPtr pri,
+    int byteoffset,
+    Bool card8,
+    unsigned int imax,
+    int *pStartIndex
+)
+{
+    int nRanges;
+    RecordSetIteratePtr pIter = NULL;
+    RecordSetInterval interval;
+    CARD8 *pCARD8;
+    CARD16 *pCARD16;
+    int err;
+
+    if (!pSet)
+	return Success;
+
+    nRanges = pStartIndex ? *pStartIndex : 0;
+    while ((pIter = RecordIterateSet(pSet, pIter, &interval)))
+    {
+	if (interval.first > imax) break;
+	if (interval.last  > imax) interval.last = imax;
+	nRanges++;
+	if (nRanges > pri->size)
+	{
+	    err = RecordAllocRanges(pri, nRanges);
+	    if (err != Success)
+		return err;
+	}
+	else
+	    pri->nRanges = max(pri->nRanges, nRanges);
+	if (card8)
+	{
+	    pCARD8 = ((CARD8 *)&pri->pRanges[nRanges-1]) + byteoffset;
+	    *pCARD8++ = interval.first;
+	    *pCARD8   = interval.last;
+	}
+	else
+	{
+	    pCARD16 = (CARD16 *)
+			(((char *)&pri->pRanges[nRanges-1]) + byteoffset);
+	    *pCARD16++ = interval.first;
+	    *pCARD16   = interval.last;
+	}
+    }
+    if (pStartIndex)
+	*pStartIndex = nRanges;
+    return Success;
+} /* RecordConvertSetToRanges */
+
+
+/* RecordConvertMinorOpInfoToRanges
+ *
+ * Arguments:
+ *	pMinOpInfo is the minor opcode info to convert to xRecordRanges.
+ *	pri is where the result should be stored.
+ *	byteoffset is the offset from the start of an xRecordRange of the
+ *	  four vales (CARD8 major_first, CARD8 major_last,
+ *	  CARD16 minor_first, CARD16 minor_last) we are going to store.
+ *
+ * Returns: BadAlloc if a memory allocation error occurred, else Success.
+ *
+ * Side Effects:
+ *	If Success is returned, the slice of pri->pRanges indicated by
+ *	byteoffset is filled in with the information from pMinOpInfo.
+ */
+static int
+RecordConvertMinorOpInfoToRanges(
+    RecordMinorOpPtr pMinOpInfo,
+    GetContextRangeInfoPtr pri,
+    int byteoffset
+)
+{
+    int nsets;
+    int start;
+    int i;
+    int err;
+
+    if (!pMinOpInfo)
+	return Success;
+
+    nsets = pMinOpInfo->count;
+    pMinOpInfo++;
+    start = 0;
+    for (i = 0; i < nsets; i++)
+    {
+	int j, s;
+	s = start;
+	err = RecordConvertSetToRanges(pMinOpInfo[i].major.pMinOpSet, pri,
+				byteoffset + 2, FALSE, 65535, &start);
+	if (err != Success) return err;
+	for (j = s; j < start; j++)
+	{
+	    CARD8 *pCARD8 = ((CARD8 *)&pri->pRanges[j]) + byteoffset;
+	    *pCARD8++ = pMinOpInfo[i].major.first;
+	    *pCARD8   = pMinOpInfo[i].major.last;
+	}
+    }
+    return Success;
+} /* RecordConvertMinorOpInfoToRanges */
+
+
+/* RecordSwapRanges
+ *
+ * Arguments:
+ *	pRanges is an array of xRecordRanges.
+ *	nRanges is the number of elements in pRanges.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	The 16 bit fields of each xRecordRange are byte swapped.
+ */
+static void
+RecordSwapRanges(xRecordRange *pRanges, int nRanges)
+{
+    int i;
+    register char n;
+    for (i = 0; i < nRanges; i++, pRanges++)
+    {
+	swaps(&pRanges->extRequestsMinorFirst, n);
+	swaps(&pRanges->extRequestsMinorLast, n);
+	swaps(&pRanges->extRepliesMinorFirst, n);
+	swaps(&pRanges->extRepliesMinorLast, n);
+    }
+} /* RecordSwapRanges */
+
+
+static int
+ProcRecordGetContext(ClientPtr client)
+{
+    RecordContextPtr pContext;
+    REQUEST(xRecordGetContextReq);
+    xRecordGetContextReply rep;
+    int n;
+    RecordClientsAndProtocolPtr pRCAP;
+    int nRCAPs = 0;
+    GetContextRangeInfoPtr pRangeInfo;
+    GetContextRangeInfoPtr pri;
+    int i;
+    int err;
+
+    REQUEST_SIZE_MATCH(xRecordGetContextReq);
+    VERIFY_CONTEXT(pContext, stuff->context, client);
+
+    /* how many RCAPs are there on this context? */
+
+    for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+	nRCAPs++;
+
+    /* allocate and initialize space for record range info */
+
+    pRangeInfo = (GetContextRangeInfoPtr)malloc(
+				nRCAPs * sizeof(GetContextRangeInfoRec));
+    if (!pRangeInfo && nRCAPs > 0)
+	return BadAlloc;
+    for (i = 0; i < nRCAPs; i++)
+    {
+	pRangeInfo[i].pRanges = NULL;
+	pRangeInfo[i].size = 0;
+	pRangeInfo[i].nRanges = 0;
+    }
+
+    /* convert the RCAP (internal) representation of the recorded protocol
+     * to the wire protocol (external) representation, storing the information
+     * for the ith RCAP in pri[i]
+     */
+
+    for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
+	 pRCAP;
+	 pRCAP = pRCAP->pNextRCAP, pri++)
+    {
+	xRecordRange rr;
+
+	err = RecordConvertSetToRanges(pRCAP->pRequestMajorOpSet, pri,
+			offset_of(rr, coreRequestsFirst), TRUE, 127, NULL);
+	if (err != Success) goto bailout;
+
+	err = RecordConvertSetToRanges(pRCAP->pReplyMajorOpSet, pri,
+			offset_of(rr, coreRepliesFirst), TRUE, 127, NULL);
+	if (err != Success) goto bailout;
+
+	err = RecordConvertSetToRanges(pRCAP->pDeliveredEventSet, pri,
+			offset_of(rr, deliveredEventsFirst), TRUE, 255, NULL);
+	if (err != Success) goto bailout;
+
+	err = RecordConvertSetToRanges(pRCAP->pDeviceEventSet, pri,
+			offset_of(rr, deviceEventsFirst), TRUE, 255, NULL);
+	if (err != Success) goto bailout;
+
+	err = RecordConvertSetToRanges(pRCAP->pErrorSet, pri,
+			      offset_of(rr, errorsFirst), TRUE, 255, NULL);
+	if (err != Success) goto bailout;
+
+	err = RecordConvertMinorOpInfoToRanges(pRCAP->pRequestMinOpInfo,
+				pri, offset_of(rr, extRequestsMajorFirst));
+	if (err != Success) goto bailout;
+
+	err = RecordConvertMinorOpInfoToRanges(pRCAP->pReplyMinOpInfo,
+				pri, offset_of(rr, extRepliesMajorFirst));
+	if (err != Success) goto bailout;
+
+	if (pRCAP->clientStarted || pRCAP->clientDied)
+	{
+	    if (pri->nRanges == 0)
+		RecordAllocRanges(pri, 1);
+	    pri->pRanges[0].clientStarted = pRCAP->clientStarted;
+	    pri->pRanges[0].clientDied    = pRCAP->clientDied;
+	}
+    }
+
+    /* calculate number of clients and reply length */
+
+    rep.nClients = 0;
+    rep.length = 0;
+    for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
+	 pRCAP;
+	 pRCAP = pRCAP->pNextRCAP, pri++)
+    {
+	rep.nClients += pRCAP->numClients;
+	rep.length += pRCAP->numClients *
+		( bytes_to_int32(sizeof(xRecordClientInfo)) +
+		  pri->nRanges * bytes_to_int32(sizeof(xRecordRange)));
+    }
+
+    /* write the reply header */
+
+    rep.type = X_Reply;
+    rep.sequenceNumber 	= client->sequence;
+    rep.enabled = pContext->pRecordingClient != NULL;
+    rep.elementHeader = pContext->elemHeaders;
+    if(client->swapped)
+    {
+    	swaps(&rep.sequenceNumber, n);
+    	swapl(&rep.length, n);
+    	swapl(&rep.nClients, n);
+    }
+    (void)WriteToClient(client, sizeof(xRecordGetContextReply),
+			(char *)&rep);
+
+    /* write all the CLIENT_INFOs */
+
+    for (pRCAP = pContext->pListOfRCAP, pri = pRangeInfo;
+	 pRCAP;
+	 pRCAP = pRCAP->pNextRCAP, pri++)
+    {
+	xRecordClientInfo rci;
+	rci.nRanges = pri->nRanges;
+	if (client->swapped)
+	{
+	    swapl(&rci.nRanges, n);
+	    RecordSwapRanges(pri->pRanges, pri->nRanges);
+	}
+	for (i = 0; i < pRCAP->numClients; i++)
+	{
+	    rci.clientResource = pRCAP->pClientIDs[i];
+	    if (client->swapped) swapl(&rci.clientResource, n);
+	    WriteToClient(client, sizeof(xRecordClientInfo), (char *)&rci);
+	    WriteToClient(client, sizeof(xRecordRange) * pri->nRanges,
+			  (char *)pri->pRanges);
+	}
+    }
+    err = Success;
+
+bailout:
+    for (i = 0; i < nRCAPs; i++)
+    {
+	free(pRangeInfo[i].pRanges);
+    }
+    free(pRangeInfo);
+    return err;
+} /* ProcRecordGetContext */
+
+
+static int
+ProcRecordEnableContext(ClientPtr client)
+{
+    RecordContextPtr pContext;
+    REQUEST(xRecordEnableContextReq);
+    int i;
+    RecordClientsAndProtocolPtr pRCAP;
+
+    REQUEST_SIZE_MATCH(xRecordGetContextReq);
+    VERIFY_CONTEXT(pContext, stuff->context, client);
+    if (pContext->pRecordingClient)
+	return BadMatch; /* already enabled */
+
+    /* install record hooks for each RCAP */
+
+    for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+    {
+	int err = RecordInstallHooks(pRCAP, 0);
+	if (err != Success)
+	{ /* undo the previous installs */
+	    RecordClientsAndProtocolPtr pUninstallRCAP;
+	    for (pUninstallRCAP = pContext->pListOfRCAP;
+		 pUninstallRCAP != pRCAP;
+		 pUninstallRCAP = pUninstallRCAP->pNextRCAP)
+	    {
+		RecordUninstallHooks(pUninstallRCAP, 0);
+	    }
+	    return err;
+	}
+    }
+
+    /* Disallow further request processing on this connection until
+     * the context is disabled.
+     */
+    IgnoreClient(client);
+    pContext->pRecordingClient = client;
+
+    /* Don't allow the data connection to record itself; unregister it. */
+    RecordDeleteClientFromContext(pContext,
+				  pContext->pRecordingClient->clientAsMask);
+
+    /* move the newly enabled context to the front part of ppAllContexts,
+     * where all the enabled contexts are
+     */
+    i = RecordFindContextOnAllContexts(pContext);
+    assert(i >= numEnabledContexts);
+    if (i != numEnabledContexts)
+    {
+	ppAllContexts[i] = ppAllContexts[numEnabledContexts];
+	ppAllContexts[numEnabledContexts] = pContext;
+    }
+
+    ++numEnabledContexts;
+    assert(numEnabledContexts > 0);
+
+    /* send StartOfData */
+    RecordAProtocolElement(pContext, NULL, XRecordStartOfData, NULL, 0, 0);
+    RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+    return Success;
+} /* ProcRecordEnableContext */
+
+
+/* RecordDisableContext
+ *
+ * Arguments:
+ *	pContext is the context to disable.
+ *	nRanges is the number of elements in pRanges.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	If the context was enabled, it is disabled.  An EndOfData
+ *	message is sent to the recording client.  Recording hooks for
+ *	this context are uninstalled.  The context is moved to the
+ *	rear part of the ppAllContexts array.  numEnabledContexts is
+ *	decremented.  Request processing for the formerly recording client
+ *	is resumed.
+ */
+static void
+RecordDisableContext(RecordContextPtr pContext)
+{
+    RecordClientsAndProtocolPtr pRCAP;
+    int i;
+
+    if (!pContext->pRecordingClient) return;
+    if (!pContext->pRecordingClient->clientGone)
+    {
+	RecordAProtocolElement(pContext, NULL, XRecordEndOfData, NULL, 0, 0);
+	RecordFlushReplyBuffer(pContext, NULL, 0, NULL, 0);
+	/* Re-enable request processing on this connection. */
+	AttendClient(pContext->pRecordingClient);
+    }
+
+    for (pRCAP = pContext->pListOfRCAP; pRCAP; pRCAP = pRCAP->pNextRCAP)
+    {
+	RecordUninstallHooks(pRCAP, 0);
+    }
+
+    pContext->pRecordingClient = NULL;
+
+    /* move the newly disabled context to the rear part of ppAllContexts,
+     * where all the disabled contexts are
+     */
+    i = RecordFindContextOnAllContexts(pContext);
+    assert( (i != -1) && (i < numEnabledContexts) );
+    if (i != (numEnabledContexts - 1) )
+    {
+	ppAllContexts[i] = ppAllContexts[numEnabledContexts-1];
+	ppAllContexts[numEnabledContexts-1] = pContext;
+    }
+    --numEnabledContexts;
+    assert(numEnabledContexts >= 0);
+} /* RecordDisableContext */
+
+
+static int
+ProcRecordDisableContext(ClientPtr client)
+{
+    RecordContextPtr pContext;
+    REQUEST(xRecordDisableContextReq);
+
+    REQUEST_SIZE_MATCH(xRecordDisableContextReq);
+    VERIFY_CONTEXT(pContext, stuff->context, client);
+    RecordDisableContext(pContext);
+    return Success;
+} /* ProcRecordDisableContext */
+
+
+/* RecordDeleteContext
+ *
+ * Arguments:
+ *	value is the context to delete.
+ *	id is its resource ID.
+ *
+ * Returns: Success.
+ *
+ * Side Effects:
+ *	Disables the context, frees all associated memory, and removes
+ *	it from the ppAllContexts array.
+ */
+static int
+RecordDeleteContext(pointer value, XID id)
+{
+    int i;
+    RecordContextPtr pContext = (RecordContextPtr)value;
+    RecordClientsAndProtocolPtr pRCAP;
+
+    RecordDisableContext(pContext);
+
+    /*  Remove all the clients from all the RCAPs.
+     *  As a result, the RCAPs will be freed.
+     */
+
+    while ((pRCAP = pContext->pListOfRCAP))
+    {
+	int numClients = pRCAP->numClients;
+	/* when the last client is deleted, the RCAP will go away. */
+	while(numClients--)
+	{
+	    RecordDeleteClientFromRCAP(pRCAP, numClients);
+	}
+    }
+
+    /* remove context from AllContexts list */
+
+    if (-1 != (i = RecordFindContextOnAllContexts(pContext)))
+    {
+	ppAllContexts[i] = ppAllContexts[numContexts - 1];
+	if (--numContexts == 0)
+	{
+	    free(ppAllContexts);
+	    ppAllContexts = NULL;
+	}
+    }
+    free(pContext);
+
+    return Success;
+} /* RecordDeleteContext */
+
+
+static int
+ProcRecordFreeContext(ClientPtr client)
+{
+    RecordContextPtr pContext;
+    REQUEST(xRecordFreeContextReq);
+
+    REQUEST_SIZE_MATCH(xRecordFreeContextReq);
+    VERIFY_CONTEXT(pContext, stuff->context, client);
+    FreeResource(stuff->context, RT_NONE);
+    return Success;
+} /* ProcRecordFreeContext */
+
+
+static int
+ProcRecordDispatch(ClientPtr client)
+{
+    REQUEST(xReq);
+
+    switch (stuff->data)
+    {
+	case X_RecordQueryVersion:
+	    return ProcRecordQueryVersion(client);
+	case X_RecordCreateContext:
+	    return ProcRecordCreateContext(client);
+	case X_RecordRegisterClients:
+	    return ProcRecordRegisterClients(client);
+	case X_RecordUnregisterClients:
+	    return ProcRecordUnregisterClients(client);
+	case X_RecordGetContext:
+	    return ProcRecordGetContext(client);
+	case X_RecordEnableContext:
+	    return ProcRecordEnableContext(client);
+	case X_RecordDisableContext:
+	    return ProcRecordDisableContext(client);
+	case X_RecordFreeContext:
+	    return ProcRecordFreeContext(client);
+       default:
+	    return BadRequest;
+    }
+} /* ProcRecordDispatch */
+
+
+static int
+SProcRecordQueryVersion(ClientPtr client)
+{
+    REQUEST(xRecordQueryVersionReq);
+    register char 	n;
+
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xRecordQueryVersionReq);
+    swaps(&stuff->majorVersion, n);
+    swaps(&stuff->minorVersion,n);
+    return ProcRecordQueryVersion(client);
+} /* SProcRecordQueryVersion */
+
+
+static int
+SwapCreateRegister(xRecordRegisterClientsReq *stuff)
+{
+    register char n;
+    int i;
+    XID *pClientID;
+
+    swapl(&stuff->context, n);
+    swapl(&stuff->nClients, n);
+    swapl(&stuff->nRanges, n);
+    pClientID = (XID *)&stuff[1];
+    if (stuff->nClients > stuff->length - bytes_to_int32(sz_xRecordRegisterClientsReq))
+	return BadLength;
+    for (i = 0; i < stuff->nClients; i++, pClientID++)
+    {
+	swapl(pClientID, n);
+    }
+    if (stuff->nRanges > stuff->length - bytes_to_int32(sz_xRecordRegisterClientsReq)
+	- stuff->nClients)
+	return BadLength;
+    RecordSwapRanges((xRecordRange *)pClientID, stuff->nRanges);
+    return Success;
+} /* SwapCreateRegister */
+
+
+static int
+SProcRecordCreateContext(ClientPtr client)
+{
+    REQUEST(xRecordCreateContextReq);
+    int			status;
+    register char 	n;
+
+    swaps(&stuff->length, n);
+    REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq);
+    if ((status = SwapCreateRegister((pointer)stuff)) != Success)
+	return status;
+    return ProcRecordCreateContext(client);
+} /* SProcRecordCreateContext */
+
+
+static int
+SProcRecordRegisterClients(ClientPtr client)
+{
+    REQUEST(xRecordRegisterClientsReq);
+    int			status;
+    register char 	n;
+
+    swaps(&stuff->length, n);
+    REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq);
+    if ((status = SwapCreateRegister((pointer)stuff)) != Success)
+	return status;
+    return ProcRecordRegisterClients(client);
+} /* SProcRecordRegisterClients */
+
+
+static int
+SProcRecordUnregisterClients(ClientPtr client)
+{
+    REQUEST(xRecordUnregisterClientsReq);
+    register char 	n;
+
+    swaps(&stuff->length, n);
+    REQUEST_AT_LEAST_SIZE(xRecordUnregisterClientsReq);
+    swapl(&stuff->context, n);
+    swapl(&stuff->nClients, n);
+    SwapRestL(stuff);
+    return ProcRecordUnregisterClients(client);
+} /* SProcRecordUnregisterClients */
+
+
+static int
+SProcRecordGetContext(ClientPtr client)
+{
+    REQUEST(xRecordGetContextReq);
+    register char 	n;
+
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xRecordGetContextReq);
+    swapl(&stuff->context, n);
+    return ProcRecordGetContext(client);
+} /* SProcRecordGetContext */
+
+static int
+SProcRecordEnableContext(ClientPtr client)
+{
+    REQUEST(xRecordEnableContextReq);
+    register char 	n;
+
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xRecordEnableContextReq);
+    swapl(&stuff->context, n);
+    return ProcRecordEnableContext(client);
+} /* SProcRecordEnableContext */
+
+
+static int
+SProcRecordDisableContext(ClientPtr client)
+{
+    REQUEST(xRecordDisableContextReq);
+    register char 	n;
+
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xRecordDisableContextReq);
+    swapl(&stuff->context, n);
+    return ProcRecordDisableContext(client);
+} /* SProcRecordDisableContext */
+
+
+static int
+SProcRecordFreeContext(ClientPtr client)
+{
+    REQUEST(xRecordFreeContextReq);
+    register char 	n;
+
+    swaps(&stuff->length, n);
+    REQUEST_SIZE_MATCH(xRecordFreeContextReq);
+    swapl(&stuff->context, n);
+    return ProcRecordFreeContext(client);
+} /* SProcRecordFreeContext */
+
+
+static int
+SProcRecordDispatch(ClientPtr client)
+{
+    REQUEST(xReq);
+
+    switch (stuff->data)
+    {
+	case X_RecordQueryVersion:
+	    return SProcRecordQueryVersion(client);
+	case X_RecordCreateContext:
+	    return SProcRecordCreateContext(client);
+	case X_RecordRegisterClients:
+	    return SProcRecordRegisterClients(client);
+	case X_RecordUnregisterClients:
+	    return SProcRecordUnregisterClients(client);
+	case X_RecordGetContext:
+	    return SProcRecordGetContext(client);
+	case X_RecordEnableContext:
+	    return SProcRecordEnableContext(client);
+	case X_RecordDisableContext:
+	    return SProcRecordDisableContext(client);
+	case X_RecordFreeContext:
+	    return SProcRecordFreeContext(client);
+       default:
+	    return BadRequest;
+    }
+} /* SProcRecordDispatch */
+
+/* RecordConnectionSetupInfo
+ *
+ * Arguments:
+ *	pContext is an enabled context that specifies recording of 
+ *	  connection setup info.
+ *	pci holds the connection setup info.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	The connection setup info is sent to the recording client.
+ */
+static void
+RecordConnectionSetupInfo(RecordContextPtr pContext, NewClientInfoRec *pci)
+{
+    int prefixsize = SIZEOF(xConnSetupPrefix);
+    int restsize = pci->prefix->length * 4;
+
+    if (pci->client->swapped)
+    {
+	char *pConnSetup = (char *)malloc(prefixsize + restsize);
+	if (!pConnSetup)
+	    return;
+	SwapConnSetupPrefix(pci->prefix, (xConnSetupPrefix*)pConnSetup);
+	SwapConnSetupInfo((char*)pci->setup, (char*)(pConnSetup + prefixsize));
+	RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
+			       (pointer)pConnSetup, prefixsize + restsize, 0);
+	free(pConnSetup);
+    }
+    else
+    {
+	/* don't alloc and copy as in the swapped case; just send the
+	 * data in two pieces
+	 */
+	RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
+			(pointer)pci->prefix, prefixsize, restsize);
+	RecordAProtocolElement(pContext, pci->client, XRecordClientStarted,
+			(pointer)pci->setup, restsize, /* continuation */ -1);
+    }
+} /* RecordConnectionSetupInfo */
+
+
+/* RecordDeleteContext
+ *
+ * Arguments:
+ *	pcbl is &ClientStateCallback.
+ *	nullata is NULL.
+ *	calldata is a pointer to a NewClientInfoRec (include/dixstruct.h)
+ *	which contains information about client state changes.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	If a new client has connected and any contexts have specified
+ *	XRecordFutureClients, the new client is registered on those contexts.
+ *	If any of those contexts specify recording of the connection setup
+ *	info, it is recorded.
+ *
+ *	If an existing client has disconnected, it is deleted from any
+ *	contexts that it was registered on.  If any of those contexts
+ *	specified XRecordClientDied, they record a ClientDied protocol element.
+ *	If the disconnectiong client happened to be the data connection of an
+ *	enabled context, the context is disabled.
+ */
+
+static void
+RecordAClientStateChange(CallbackListPtr *pcbl, pointer nulldata, pointer calldata)
+{
+    NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
+    int i;
+    ClientPtr pClient = pci->client;
+    RecordContextPtr *ppAllContextsCopy = NULL;
+    int numContextsCopy = 0;
+
+    switch (pClient->clientState)
+    {
+    case ClientStateRunning: /* new client */
+	for (i = 0; i < numContexts; i++)
+	{
+	    RecordClientsAndProtocolPtr pRCAP;
+	    RecordContextPtr pContext = ppAllContexts[i];
+
+	    if ((pRCAP = RecordFindClientOnContext(pContext,
+					    XRecordFutureClients, NULL)))
+	    {
+		RecordAddClientToRCAP(pRCAP, pClient->clientAsMask);
+		if (pContext->pRecordingClient && pRCAP->clientStarted)
+		    RecordConnectionSetupInfo(pContext, pci);
+	    }
+	}
+    break;
+
+    case ClientStateGone:
+    case ClientStateRetained: /* client disconnected */
+
+        /* RecordDisableContext modifies contents of ppAllContexts. */
+	numContextsCopy = numContexts;
+	ppAllContextsCopy = malloc(numContextsCopy * sizeof(RecordContextPtr));
+	assert(ppAllContextsCopy);
+	memcpy(ppAllContextsCopy, ppAllContexts, numContextsCopy * sizeof(RecordContextPtr));
+
+	for (i = 0; i < numContextsCopy; i++)
+	{
+	    RecordClientsAndProtocolPtr pRCAP;
+	    RecordContextPtr pContext = ppAllContextsCopy[i];
+	    int pos;
+
+	    if (pContext->pRecordingClient == pClient)
+		RecordDisableContext(pContext);
+	    if ((pRCAP = RecordFindClientOnContext(pContext,
+				    pClient->clientAsMask, &pos)))
+	    {
+		if (pContext->pRecordingClient && pRCAP->clientDied)
+		    RecordAProtocolElement(pContext, pClient,
+					   XRecordClientDied, NULL, 0, 0);
+		RecordDeleteClientFromRCAP(pRCAP, pos);
+	    }
+	}
+
+	free(ppAllContextsCopy);
+    break;
+
+    default:
+    break;
+    } /* end switch on client state */
+} /* RecordAClientStateChange */
+
+
+/* RecordCloseDown
+ *
+ * Arguments:
+ *	extEntry is the extension information for RECORD.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	Performs any cleanup needed by RECORD at server shutdown time.
+ *	
+ */
+static void
+RecordCloseDown(ExtensionEntry *extEntry)
+{
+    DeleteCallback(&ClientStateCallback, RecordAClientStateChange, NULL);
+} /* RecordCloseDown */
+
+
+/* RecordExtensionInit
+ *
+ * Arguments: none.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *	Enables the RECORD extension if possible.
+ */
+void 
+RecordExtensionInit(void)
+{
+    ExtensionEntry *extentry;
+
+    RTContext = CreateNewResourceType(RecordDeleteContext, "RecordContext");
+    if (!RTContext)
+	return;
+
+    if (!dixRegisterPrivateKey(RecordClientPrivateKey, PRIVATE_CLIENT, 0))
+        return;
+
+    ppAllContexts = NULL;
+    numContexts = numEnabledContexts = numEnabledRCAPs = 0;
+
+    if (!AddCallback(&ClientStateCallback, RecordAClientStateChange, NULL))
+	return;
+
+    extentry = AddExtension(RECORD_NAME, RecordNumEvents, RecordNumErrors,
+			    ProcRecordDispatch, SProcRecordDispatch,
+			    RecordCloseDown, StandardMinorOpcode);
+    if (!extentry)
+    {
+	DeleteCallback(&ClientStateCallback, RecordAClientStateChange, NULL);
+	return;
+    }
+    SetResourceTypeErrorValue(RTContext, extentry->errorBase + XRecordBadContext);
+
+} /* RecordExtensionInit */
+
diff --git a/xorg-server/render/mipict.c b/xorg-server/render/mipict.c
index 3b7388879..1623b335f 100644
--- a/xorg-server/render/mipict.c
+++ b/xorg-server/render/mipict.c
@@ -1,644 +1,610 @@
-/*
- *
- * Copyright © 1999 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "picturestr.h"
-#include "mipict.h"
-
-#ifndef __GNUC__
-#define __inline
-#endif
-
-int
-miCreatePicture (PicturePtr pPicture)
-{
-    return Success;
-}
-
-void
-miDestroyPicture (PicturePtr pPicture)
-{
-    if (pPicture->freeCompClip)
-	RegionDestroy(pPicture->pCompositeClip);
-}
-
-void
-miDestroyPictureClip (PicturePtr pPicture)
-{
-    switch (pPicture->clientClipType) {
-    case CT_NONE:
-	return;
-    case CT_PIXMAP:
-	(*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip));
-	break;
-    default:
-	/*
-	 * we know we'll never have a list of rectangles, since ChangeClip
-	 * immediately turns them into a region
-	 */
-	RegionDestroy(pPicture->clientClip);
-	break;
-    }
-    pPicture->clientClip = NULL;
-    pPicture->clientClipType = CT_NONE;
-}    
-
-int
-miChangePictureClip (PicturePtr    pPicture,
-		     int	   type,
-		     pointer	   value,
-		     int	   n)
-{
-    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
-    PictureScreenPtr    ps = GetPictureScreen(pScreen);
-    pointer		clientClip;
-    int			clientClipType;
-    
-    switch (type) {
-    case CT_PIXMAP:
-	/* convert the pixmap to a region */
-	clientClip = (pointer) BitmapToRegion(pScreen, (PixmapPtr) value);
-	if (!clientClip)
-	    return BadAlloc;
-	clientClipType = CT_REGION;
-	(*pScreen->DestroyPixmap) ((PixmapPtr) value);
-	break;
-    case CT_REGION:
-	clientClip = value;
-	clientClipType = CT_REGION;
-	break;
-    case CT_NONE:
-	clientClip = 0;
-	clientClipType = CT_NONE;
-	break;
-    default:
-	clientClip = (pointer) RegionFromRects(n,
-					       (xRectangle *) value,
-					       type);
-	if (!clientClip)
-	    return BadAlloc;
-	clientClipType = CT_REGION;
-	free(value);
-	break;
-    }
-    (*ps->DestroyPictureClip) (pPicture);
-    pPicture->clientClip = clientClip;
-    pPicture->clientClipType = clientClipType;
-    pPicture->stateChanges |= CPClipMask;
-    return Success;
-}
-
-void
-miChangePicture (PicturePtr pPicture,
-		 Mask       mask)
-{
-    return;
-}
-
-void
-miValidatePicture (PicturePtr pPicture,
-		   Mask       mask)
-{
-    DrawablePtr	    pDrawable = pPicture->pDrawable;
-
-    if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) ||
-	(pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS)))
-    {
-	if (pDrawable->type == DRAWABLE_WINDOW)
-	{
-	    WindowPtr       pWin = (WindowPtr) pDrawable;
-	    RegionPtr       pregWin;
-	    Bool            freeTmpClip, freeCompClip;
-
-	    if (pPicture->subWindowMode == IncludeInferiors)
-	    {
-		pregWin = NotClippedByChildren(pWin);
-		freeTmpClip = TRUE;
-	    }
-	    else
-	    {
-		pregWin = &pWin->clipList;
-		freeTmpClip = FALSE;
-	    }
-	    freeCompClip = pPicture->freeCompClip;
-
-	    /*
-	     * if there is no client clip, we can get by with just keeping the
-	     * pointer we got, and remembering whether or not should destroy
-	     * (or maybe re-use) it later.  this way, we avoid unnecessary
-	     * copying of regions.  (this wins especially if many clients clip
-	     * by children and have no client clip.)
-	     */
-	    if (pPicture->clientClipType == CT_NONE)
-	    {
-		if (freeCompClip)
-		    RegionDestroy(pPicture->pCompositeClip);
-		pPicture->pCompositeClip = pregWin;
-		pPicture->freeCompClip = freeTmpClip;
-	    }
-	    else
-	    {
-		/*
-		 * we need one 'real' region to put into the composite clip. if
-		 * pregWin the current composite clip are real, we can get rid of
-		 * one. if pregWin is real and the current composite clip isn't,
-		 * use pregWin for the composite clip. if the current composite
-		 * clip is real and pregWin isn't, use the current composite
-		 * clip. if neither is real, create a new region.
-		 */
-
-		RegionTranslate(pPicture->clientClip,
-				 pDrawable->x + pPicture->clipOrigin.x,
-				 pDrawable->y + pPicture->clipOrigin.y);
-
-		if (freeCompClip)
-		{
-		    RegionIntersect(pPicture->pCompositeClip,
-				     pregWin, pPicture->clientClip);
-		    if (freeTmpClip)
-			RegionDestroy(pregWin);
-		}
-		else if (freeTmpClip)
-		{
-		    RegionIntersect(pregWin, pregWin, pPicture->clientClip);
-		    pPicture->pCompositeClip = pregWin;
-		}
-		else
-		{
-		    pPicture->pCompositeClip = RegionCreate(NullBox, 0);
-		    RegionIntersect(pPicture->pCompositeClip,
-				     pregWin, pPicture->clientClip);
-		}
-		pPicture->freeCompClip = TRUE;
-		RegionTranslate(pPicture->clientClip,
-				 -(pDrawable->x + pPicture->clipOrigin.x),
-				 -(pDrawable->y + pPicture->clipOrigin.y));
-	    }
-	}	/* end of composite clip for a window */
-	else
-	{
-	    BoxRec          pixbounds;
-
-	    /* XXX should we translate by drawable.x/y here ? */
-	    /* If you want pixmaps in offscreen memory, yes */
-	    pixbounds.x1 = pDrawable->x;
-	    pixbounds.y1 = pDrawable->y;
-	    pixbounds.x2 = pDrawable->x + pDrawable->width;
-	    pixbounds.y2 = pDrawable->y + pDrawable->height;
-
-	    if (pPicture->freeCompClip)
-	    {
-		RegionReset(pPicture->pCompositeClip, &pixbounds);
-	    }
-	    else
-	    {
-		pPicture->freeCompClip = TRUE;
-		pPicture->pCompositeClip = RegionCreate(&pixbounds, 1);
-	    }
-
-	    if (pPicture->clientClipType == CT_REGION)
-	    {
-		if(pDrawable->x || pDrawable->y) {
-		    RegionTranslate(pPicture->clientClip,
-				     pDrawable->x + pPicture->clipOrigin.x, 
-				     pDrawable->y + pPicture->clipOrigin.y);
-		    RegionIntersect(pPicture->pCompositeClip,
-				     pPicture->pCompositeClip, pPicture->clientClip);
-		    RegionTranslate(pPicture->clientClip,
-				     -(pDrawable->x + pPicture->clipOrigin.x), 
-				     -(pDrawable->y + pPicture->clipOrigin.y));
-		} else {
-		    RegionTranslate(pPicture->pCompositeClip,
-				     -pPicture->clipOrigin.x, -pPicture->clipOrigin.y);
-		    RegionIntersect(pPicture->pCompositeClip,
-				     pPicture->pCompositeClip, pPicture->clientClip);
-		    RegionTranslate(pPicture->pCompositeClip,
-				     pPicture->clipOrigin.x, pPicture->clipOrigin.y);
-		}
-	    }
-	}	/* end of composite clip for pixmap */
-    }
-}
-
-int
-miChangePictureTransform (PicturePtr	pPicture,
-			  PictTransform *transform)
-{
-    return Success;
-}
-
-int
-miChangePictureFilter (PicturePtr pPicture,
-		       int	  filter,
-		       xFixed     *params,
-		       int	  nparams)
-{
-    return Success;
-}
-
-#define BOUND(v)	(INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
-
-static inline pixman_bool_t
-miClipPictureReg (pixman_region16_t *	pRegion,
-		  pixman_region16_t *	pClip,
-		  int		dx,
-		  int		dy)
-{
-    if (pixman_region_n_rects(pRegion) == 1 &&
-	pixman_region_n_rects(pClip) == 1)
-    {
-	pixman_box16_t *  pRbox = pixman_region_rectangles(pRegion, NULL);
-	pixman_box16_t *  pCbox = pixman_region_rectangles(pClip, NULL);
-	int	v;
-	
-	if (pRbox->x1 < (v = pCbox->x1 + dx))
-	    pRbox->x1 = BOUND(v);
-	if (pRbox->x2 > (v = pCbox->x2 + dx))
-	    pRbox->x2 = BOUND(v);
-	if (pRbox->y1 < (v = pCbox->y1 + dy))
-	    pRbox->y1 = BOUND(v);
-	if (pRbox->y2 > (v = pCbox->y2 + dy))
-	    pRbox->y2 = BOUND(v);
-	if (pRbox->x1 >= pRbox->x2 ||
-	    pRbox->y1 >= pRbox->y2)
-	{
-	    pixman_region_init (pRegion);
-	}
-    }
-    else if (!pixman_region_not_empty (pClip))
-	return FALSE;
-    else
-    {
-	if (dx || dy)
-	    pixman_region_translate (pRegion, -dx, -dy);
-	if (!pixman_region_intersect (pRegion, pRegion, pClip))
-	    return FALSE;
-	if (dx || dy)
-	    pixman_region_translate(pRegion, dx, dy);
-    }
-    return pixman_region_not_empty(pRegion);
-}
-
-static __inline Bool
-miClipPictureSrc (RegionPtr	pRegion,
-		  PicturePtr	pPicture,
-		  int		dx,
-		  int		dy)
-{
-    if (pPicture->clientClipType != CT_NONE)
-    {
-	Bool result;
-	
-	pixman_region_translate ( pPicture->clientClip,
-				  pPicture->clipOrigin.x + dx,
-				  pPicture->clipOrigin.y + dy);
-
-	result = RegionIntersect(pRegion, pRegion, pPicture->clientClip);
-	
-	pixman_region_translate ( pPicture->clientClip,
-				  - (pPicture->clipOrigin.x + dx),
-				  - (pPicture->clipOrigin.y + dy));
-
-	if (!result)
-	    return FALSE;
-    }
-    return TRUE;
-}
-
-void
-miCompositeSourceValidate (PicturePtr	pPicture,
-			   INT16	x,
-			   INT16	y,
-			   CARD16	width,
-			   CARD16	height)
-{
-    DrawablePtr	pDrawable = pPicture->pDrawable;
-    ScreenPtr	pScreen;
-
-    if (!pDrawable)
-        return;
-
-    pScreen = pDrawable->pScreen;
-    
-    if (pScreen->SourceValidate)
-    {
-	if (pPicture->transform)
-	{
-	    xPoint	    points[4];
-	    int		    i;
-	    int		    xmin, ymin, xmax, ymax;
-
-#define VectorSet(i,_x,_y) { points[i].x = _x; points[i].y = _y; }
-	    VectorSet (0, x, y);
-	    VectorSet (1, x + width, y);
-	    VectorSet (2, x, y + height);
-	    VectorSet (3, x + width, y + height);
-	    xmin = ymin = 32767;
-	    xmax = ymax = -32737;
-	    for (i = 0; i < 4; i++)
-	    {
-		PictVector  t;
-		t.vector[0] = IntToxFixed (points[i].x);
-		t.vector[1] = IntToxFixed (points[i].y);
-		t.vector[2] = xFixed1;
-		if (pixman_transform_point (pPicture->transform, &t))
-		{
-		    int	tx = xFixedToInt (t.vector[0]);
-		    int ty = xFixedToInt (t.vector[1]);
-		    if (tx < xmin) xmin = tx;
-		    if (tx > xmax) xmax = tx;
-		    if (ty < ymin) ymin = ty;
-		    if (ty > ymax) ymax = ty;
-		}
-	    }
-	    x = xmin;
-	    y = ymin;
-	    width = xmax - xmin;
-	    height = ymax - ymin;
-	}
-        x += pPicture->pDrawable->x;
-        y += pPicture->pDrawable->y;
-	(*pScreen->SourceValidate) (pDrawable, x, y, width, height,
-				    pPicture->subWindowMode);
-    }
-}
-
-/*
- * returns FALSE if the final region is empty.  Indistinguishable from
- * an allocation failure, but rendering ignores those anyways.
- */
-
-Bool
-miComputeCompositeRegion (RegionPtr	pRegion,
-			  PicturePtr	pSrc,
-			  PicturePtr	pMask,
-			  PicturePtr	pDst,
-			  INT16		xSrc,
-			  INT16		ySrc,
-			  INT16		xMask,
-			  INT16		yMask,
-			  INT16		xDst,
-			  INT16		yDst,
-			  CARD16	width,
-			  CARD16	height)
-{
-    
-    int		v;
-
-    pRegion->extents.x1 = xDst;
-    v = xDst + width;
-    pRegion->extents.x2 = BOUND(v);
-    pRegion->extents.y1 = yDst;
-    v = yDst + height;
-    pRegion->extents.y2 = BOUND(v);
-    pRegion->data = 0;
-    /* Check for empty operation */
-    if (pRegion->extents.x1 >= pRegion->extents.x2 ||
-	pRegion->extents.y1 >= pRegion->extents.y2)
-    {
-	pixman_region_init (pRegion);
-	return FALSE;
-    }
-    /* clip against dst */
-    if (!miClipPictureReg (pRegion, pDst->pCompositeClip, 0, 0))
-    {
-	pixman_region_fini (pRegion);
-	return FALSE;
-    }
-    if (pDst->alphaMap)
-    {
-	if (!miClipPictureReg (pRegion, pDst->alphaMap->pCompositeClip,
-			       -pDst->alphaOrigin.x,
-			       -pDst->alphaOrigin.y))
-	{
-	    pixman_region_fini (pRegion);
-	    return FALSE;
-	}
-    }
-    /* clip against src */
-    if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
-    {
-	pixman_region_fini (pRegion);
-	return FALSE;
-    }
-    if (pSrc->alphaMap)
-    {
-	if (!miClipPictureSrc (pRegion, pSrc->alphaMap,
-			       xDst - (xSrc - pSrc->alphaOrigin.x),
-			       yDst - (ySrc - pSrc->alphaOrigin.y)))
-	{
-	    pixman_region_fini (pRegion);
-	    return FALSE;
-	}
-    }
-    /* clip against mask */
-    if (pMask)
-    {
-	if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask))
-	{
-	    pixman_region_fini (pRegion);
-	    return FALSE;
-	}	
-	if (pMask->alphaMap)
-	{
-	    if (!miClipPictureSrc (pRegion, pMask->alphaMap,
-				   xDst - (xMask - pMask->alphaOrigin.x),
-				   yDst - (yMask - pMask->alphaOrigin.y)))
-	    {
-		pixman_region_fini (pRegion);
-		return FALSE;
-	    }
-	}
-    }
-
-    
-    miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height);
-    if (pMask)
-	miCompositeSourceValidate (pMask, xMask, yMask, width, height);
-
-    return TRUE;
-}
-
-void
-miRenderColorToPixel (PictFormatPtr format,
-		      xRenderColor  *color,
-		      CARD32	    *pixel)
-{
-    CARD32	    r, g, b, a;
-    miIndexedPtr    pIndexed;
-
-    switch (format->type) {
-    case PictTypeDirect:
-	r = color->red >> (16 - Ones (format->direct.redMask));
-	g = color->green >> (16 - Ones (format->direct.greenMask));
-	b = color->blue >> (16 - Ones (format->direct.blueMask));
-	a = color->alpha >> (16 - Ones (format->direct.alphaMask));
-	r = r << format->direct.red;
-	g = g << format->direct.green;
-	b = b << format->direct.blue;
-	a = a << format->direct.alpha;
-	*pixel = r|g|b|a;
-	break;
-    case PictTypeIndexed:
-	pIndexed = (miIndexedPtr) (format->index.devPrivate);
-	if (pIndexed->color)
-	{
-	    r = color->red >> 11;
-	    g = color->green >> 11;
-	    b = color->blue >> 11;
-	    *pixel = miIndexToEnt15 (pIndexed, (r << 10) | (g << 5) | b);
-	}
-	else
-	{
-	    r = color->red >> 8;
-	    g = color->green >> 8;
-	    b = color->blue >> 8;
-	    *pixel = miIndexToEntY24 (pIndexed, (r << 16) | (g << 8) | b);
-	}
-	break;
-    }
-}
-
-static CARD16
-miFillColor (CARD32 pixel, int bits)
-{
-    while (bits < 16)
-    {
-	pixel |= pixel << bits;
-	bits <<= 1;
-    }
-    return (CARD16) pixel;
-}
-
-Bool
-miIsSolidAlpha (PicturePtr pSrc)
-{
-    ScreenPtr	pScreen;
-    char	line[1];
-
-    if (!pSrc->pDrawable)
-        return FALSE;
-
-    pScreen = pSrc->pDrawable->pScreen;
-    
-    /* Alpha-only */
-    if (PICT_FORMAT_TYPE (pSrc->format) != PICT_TYPE_A)
-	return FALSE;
-    /* repeat */
-    if (!pSrc->repeat)
-	return FALSE;
-    /* 1x1 */
-    if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1)
-	return FALSE;
-    line[0] = 1;
-    (*pScreen->GetImage) (pSrc->pDrawable, 0, 0, 1, 1, ZPixmap, ~0L, line);
-    switch (pSrc->pDrawable->bitsPerPixel) {
-    case 1:
-	return (CARD8) line[0] == 1 || (CARD8) line[0] == 0x80;
-    case 4:
-	return (CARD8) line[0] == 0xf || (CARD8) line[0] == 0xf0;
-    case 8:
-	return (CARD8) line[0] == 0xff;
-    default:
-	return FALSE;
-    }
-}
-
-void
-miRenderPixelToColor (PictFormatPtr format,
-		      CARD32	    pixel,
-		      xRenderColor  *color)
-{
-    CARD32	    r, g, b, a;
-    miIndexedPtr    pIndexed;
-    
-    switch (format->type) {
-    case PictTypeDirect:
-	r = (pixel >> format->direct.red) & format->direct.redMask;
-	g = (pixel >> format->direct.green) & format->direct.greenMask;
-	b = (pixel >> format->direct.blue) & format->direct.blueMask;
-	a = (pixel >> format->direct.alpha) & format->direct.alphaMask;
-	color->red = miFillColor (r, Ones (format->direct.redMask));
-	color->green = miFillColor (g, Ones (format->direct.greenMask));
-	color->blue = miFillColor (b, Ones (format->direct.blueMask));
-	color->alpha = miFillColor (a, Ones (format->direct.alphaMask));
-	break;
-    case PictTypeIndexed:
-	pIndexed = (miIndexedPtr) (format->index.devPrivate);
-	pixel = pIndexed->rgba[pixel & (MI_MAX_INDEXED-1)];
-	r = (pixel >> 16) & 0xff;
-	g = (pixel >>  8) & 0xff;
-	b = (pixel      ) & 0xff;
-	color->red = miFillColor (r, 8);
-	color->green = miFillColor (g, 8);
-	color->blue = miFillColor (b, 8);
-	color->alpha = 0xffff;
-	break;
-    }
-}
-
-Bool
-miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
-{
-    PictureScreenPtr    ps;
-    
-    if (!PictureInit (pScreen, formats, nformats))
-	return FALSE;
-    ps = GetPictureScreen(pScreen);
-    ps->CreatePicture = miCreatePicture;
-    ps->DestroyPicture = miDestroyPicture;
-    ps->ChangePictureClip = miChangePictureClip;
-    ps->DestroyPictureClip = miDestroyPictureClip;
-    ps->ChangePicture = miChangePicture;
-    ps->ValidatePicture = miValidatePicture;
-    ps->InitIndexed = miInitIndexed;
-    ps->CloseIndexed = miCloseIndexed;
-    ps->UpdateIndexed = miUpdateIndexed;
-    ps->ChangePictureTransform = miChangePictureTransform;
-    ps->ChangePictureFilter = miChangePictureFilter;
-    ps->RealizeGlyph = miRealizeGlyph;
-    ps->UnrealizeGlyph = miUnrealizeGlyph;
-
-    /* MI rendering routines */
-    ps->Composite	= 0;			/* requires DDX support */
-    ps->Glyphs		= miGlyphs;
-    ps->CompositeRects	= miCompositeRects;
-    ps->Trapezoids	= 0;
-    ps->Triangles	= 0;
-    ps->TriStrip	= miTriStrip;
-    ps->TriFan		= miTriFan;
-    
-    ps->RasterizeTrapezoid = 0;			/* requires DDX support */
-    ps->AddTraps	= 0;			/* requires DDX support */
-    ps->AddTriangles	= 0;			/* requires DDX support */
-
-    return TRUE;
-}
+/*
+ *
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+#ifndef __GNUC__
+#define __inline
+#endif
+
+int
+miCreatePicture (PicturePtr pPicture)
+{
+    return Success;
+}
+
+void
+miDestroyPicture (PicturePtr pPicture)
+{
+    if (pPicture->freeCompClip)
+	RegionDestroy(pPicture->pCompositeClip);
+}
+
+void
+miDestroyPictureClip (PicturePtr pPicture)
+{
+    switch (pPicture->clientClipType) {
+    case CT_NONE:
+	return;
+    case CT_PIXMAP:
+	(*pPicture->pDrawable->pScreen->DestroyPixmap) ((PixmapPtr) (pPicture->clientClip));
+	break;
+    default:
+	/*
+	 * we know we'll never have a list of rectangles, since ChangeClip
+	 * immediately turns them into a region
+	 */
+	RegionDestroy(pPicture->clientClip);
+	break;
+    }
+    pPicture->clientClip = NULL;
+    pPicture->clientClipType = CT_NONE;
+}    
+
+int
+miChangePictureClip (PicturePtr    pPicture,
+		     int	   type,
+		     pointer	   value,
+		     int	   n)
+{
+    ScreenPtr		pScreen = pPicture->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    pointer		clientClip;
+    int			clientClipType;
+    
+    switch (type) {
+    case CT_PIXMAP:
+	/* convert the pixmap to a region */
+	clientClip = (pointer) BitmapToRegion(pScreen, (PixmapPtr) value);
+	if (!clientClip)
+	    return BadAlloc;
+	clientClipType = CT_REGION;
+	(*pScreen->DestroyPixmap) ((PixmapPtr) value);
+	break;
+    case CT_REGION:
+	clientClip = value;
+	clientClipType = CT_REGION;
+	break;
+    case CT_NONE:
+	clientClip = 0;
+	clientClipType = CT_NONE;
+	break;
+    default:
+	clientClip = (pointer) RegionFromRects(n,
+					       (xRectangle *) value,
+					       type);
+	if (!clientClip)
+	    return BadAlloc;
+	clientClipType = CT_REGION;
+	free(value);
+	break;
+    }
+    (*ps->DestroyPictureClip) (pPicture);
+    pPicture->clientClip = clientClip;
+    pPicture->clientClipType = clientClipType;
+    pPicture->stateChanges |= CPClipMask;
+    return Success;
+}
+
+void
+miChangePicture (PicturePtr pPicture,
+		 Mask       mask)
+{
+    return;
+}
+
+void
+miValidatePicture (PicturePtr pPicture,
+		   Mask       mask)
+{
+    DrawablePtr	    pDrawable = pPicture->pDrawable;
+
+    if ((mask & (CPClipXOrigin|CPClipYOrigin|CPClipMask|CPSubwindowMode)) ||
+	(pDrawable->serialNumber != (pPicture->serialNumber & DRAWABLE_SERIAL_BITS)))
+    {
+	if (pDrawable->type == DRAWABLE_WINDOW)
+	{
+	    WindowPtr       pWin = (WindowPtr) pDrawable;
+	    RegionPtr       pregWin;
+	    Bool            freeTmpClip, freeCompClip;
+
+	    if (pPicture->subWindowMode == IncludeInferiors)
+	    {
+		pregWin = NotClippedByChildren(pWin);
+		freeTmpClip = TRUE;
+	    }
+	    else
+	    {
+		pregWin = &pWin->clipList;
+		freeTmpClip = FALSE;
+	    }
+	    freeCompClip = pPicture->freeCompClip;
+
+	    /*
+	     * if there is no client clip, we can get by with just keeping the
+	     * pointer we got, and remembering whether or not should destroy
+	     * (or maybe re-use) it later.  this way, we avoid unnecessary
+	     * copying of regions.  (this wins especially if many clients clip
+	     * by children and have no client clip.)
+	     */
+	    if (pPicture->clientClipType == CT_NONE)
+	    {
+		if (freeCompClip)
+		    RegionDestroy(pPicture->pCompositeClip);
+		pPicture->pCompositeClip = pregWin;
+		pPicture->freeCompClip = freeTmpClip;
+	    }
+	    else
+	    {
+		/*
+		 * we need one 'real' region to put into the composite clip. if
+		 * pregWin the current composite clip are real, we can get rid of
+		 * one. if pregWin is real and the current composite clip isn't,
+		 * use pregWin for the composite clip. if the current composite
+		 * clip is real and pregWin isn't, use the current composite
+		 * clip. if neither is real, create a new region.
+		 */
+
+		RegionTranslate(pPicture->clientClip,
+				 pDrawable->x + pPicture->clipOrigin.x,
+				 pDrawable->y + pPicture->clipOrigin.y);
+
+		if (freeCompClip)
+		{
+		    RegionIntersect(pPicture->pCompositeClip,
+				     pregWin, pPicture->clientClip);
+		    if (freeTmpClip)
+			RegionDestroy(pregWin);
+		}
+		else if (freeTmpClip)
+		{
+		    RegionIntersect(pregWin, pregWin, pPicture->clientClip);
+		    pPicture->pCompositeClip = pregWin;
+		}
+		else
+		{
+		    pPicture->pCompositeClip = RegionCreate(NullBox, 0);
+		    RegionIntersect(pPicture->pCompositeClip,
+				     pregWin, pPicture->clientClip);
+		}
+		pPicture->freeCompClip = TRUE;
+		RegionTranslate(pPicture->clientClip,
+				 -(pDrawable->x + pPicture->clipOrigin.x),
+				 -(pDrawable->y + pPicture->clipOrigin.y));
+	    }
+	}	/* end of composite clip for a window */
+	else
+	{
+	    BoxRec          pixbounds;
+
+	    /* XXX should we translate by drawable.x/y here ? */
+	    /* If you want pixmaps in offscreen memory, yes */
+	    pixbounds.x1 = pDrawable->x;
+	    pixbounds.y1 = pDrawable->y;
+	    pixbounds.x2 = pDrawable->x + pDrawable->width;
+	    pixbounds.y2 = pDrawable->y + pDrawable->height;
+
+	    if (pPicture->freeCompClip)
+	    {
+		RegionReset(pPicture->pCompositeClip, &pixbounds);
+	    }
+	    else
+	    {
+		pPicture->freeCompClip = TRUE;
+		pPicture->pCompositeClip = RegionCreate(&pixbounds, 1);
+	    }
+
+	    if (pPicture->clientClipType == CT_REGION)
+	    {
+		if(pDrawable->x || pDrawable->y) {
+		    RegionTranslate(pPicture->clientClip,
+				     pDrawable->x + pPicture->clipOrigin.x, 
+				     pDrawable->y + pPicture->clipOrigin.y);
+		    RegionIntersect(pPicture->pCompositeClip,
+				     pPicture->pCompositeClip, pPicture->clientClip);
+		    RegionTranslate(pPicture->clientClip,
+				     -(pDrawable->x + pPicture->clipOrigin.x), 
+				     -(pDrawable->y + pPicture->clipOrigin.y));
+		} else {
+		    RegionTranslate(pPicture->pCompositeClip,
+				     -pPicture->clipOrigin.x, -pPicture->clipOrigin.y);
+		    RegionIntersect(pPicture->pCompositeClip,
+				     pPicture->pCompositeClip, pPicture->clientClip);
+		    RegionTranslate(pPicture->pCompositeClip,
+				     pPicture->clipOrigin.x, pPicture->clipOrigin.y);
+		}
+	    }
+	}	/* end of composite clip for pixmap */
+    }
+}
+
+int
+miChangePictureTransform (PicturePtr	pPicture,
+			  PictTransform *transform)
+{
+    return Success;
+}
+
+int
+miChangePictureFilter (PicturePtr pPicture,
+		       int	  filter,
+		       xFixed     *params,
+		       int	  nparams)
+{
+    return Success;
+}
+
+#define BOUND(v)	(INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v))
+
+static inline pixman_bool_t
+miClipPictureReg (pixman_region16_t *	pRegion,
+		  pixman_region16_t *	pClip,
+		  int		dx,
+		  int		dy)
+{
+    if (pixman_region_n_rects(pRegion) == 1 &&
+	pixman_region_n_rects(pClip) == 1)
+    {
+	pixman_box16_t *  pRbox = pixman_region_rectangles(pRegion, NULL);
+	pixman_box16_t *  pCbox = pixman_region_rectangles(pClip, NULL);
+	int	v;
+	
+	if (pRbox->x1 < (v = pCbox->x1 + dx))
+	    pRbox->x1 = BOUND(v);
+	if (pRbox->x2 > (v = pCbox->x2 + dx))
+	    pRbox->x2 = BOUND(v);
+	if (pRbox->y1 < (v = pCbox->y1 + dy))
+	    pRbox->y1 = BOUND(v);
+	if (pRbox->y2 > (v = pCbox->y2 + dy))
+	    pRbox->y2 = BOUND(v);
+	if (pRbox->x1 >= pRbox->x2 ||
+	    pRbox->y1 >= pRbox->y2)
+	{
+	    pixman_region_init (pRegion);
+	}
+    }
+    else if (!pixman_region_not_empty (pClip))
+	return FALSE;
+    else
+    {
+	if (dx || dy)
+	    pixman_region_translate (pRegion, -dx, -dy);
+	if (!pixman_region_intersect (pRegion, pRegion, pClip))
+	    return FALSE;
+	if (dx || dy)
+	    pixman_region_translate(pRegion, dx, dy);
+    }
+    return pixman_region_not_empty(pRegion);
+}
+
+static __inline Bool
+miClipPictureSrc (RegionPtr	pRegion,
+		  PicturePtr	pPicture,
+		  int		dx,
+		  int		dy)
+{
+    if (pPicture->clientClipType != CT_NONE)
+    {
+	Bool result;
+	
+	pixman_region_translate ( pPicture->clientClip,
+				  pPicture->clipOrigin.x + dx,
+				  pPicture->clipOrigin.y + dy);
+
+	result = RegionIntersect(pRegion, pRegion, pPicture->clientClip);
+	
+	pixman_region_translate ( pPicture->clientClip,
+				  - (pPicture->clipOrigin.x + dx),
+				  - (pPicture->clipOrigin.y + dy));
+
+	if (!result)
+	    return FALSE;
+    }
+    return TRUE;
+}
+
+static void
+SourceValidateOnePicture (PicturePtr pPicture)
+{
+    DrawablePtr	pDrawable = pPicture->pDrawable;
+    ScreenPtr	pScreen;
+
+    if (!pDrawable)
+        return;
+
+    pScreen = pDrawable->pScreen;
+
+    if (pScreen->SourceValidate)
+    {
+	pScreen->SourceValidate (
+	    pDrawable, 0, 0, pDrawable->width, pDrawable->height, pPicture->subWindowMode);
+    }
+}
+
+void
+miCompositeSourceValidate (PicturePtr pPicture)
+{
+    SourceValidateOnePicture (pPicture);
+    if (pPicture->alphaMap)
+	SourceValidateOnePicture (pPicture->alphaMap);
+}
+
+/*
+ * returns FALSE if the final region is empty.  Indistinguishable from
+ * an allocation failure, but rendering ignores those anyways.
+ */
+
+Bool
+miComputeCompositeRegion (RegionPtr	pRegion,
+			  PicturePtr	pSrc,
+			  PicturePtr	pMask,
+			  PicturePtr	pDst,
+			  INT16		xSrc,
+			  INT16		ySrc,
+			  INT16		xMask,
+			  INT16		yMask,
+			  INT16		xDst,
+			  INT16		yDst,
+			  CARD16	width,
+			  CARD16	height)
+{
+    
+    int		v;
+
+    pRegion->extents.x1 = xDst;
+    v = xDst + width;
+    pRegion->extents.x2 = BOUND(v);
+    pRegion->extents.y1 = yDst;
+    v = yDst + height;
+    pRegion->extents.y2 = BOUND(v);
+    pRegion->data = 0;
+    /* Check for empty operation */
+    if (pRegion->extents.x1 >= pRegion->extents.x2 ||
+	pRegion->extents.y1 >= pRegion->extents.y2)
+    {
+	pixman_region_init (pRegion);
+	return FALSE;
+    }
+    /* clip against dst */
+    if (!miClipPictureReg (pRegion, pDst->pCompositeClip, 0, 0))
+    {
+	pixman_region_fini (pRegion);
+	return FALSE;
+    }
+    if (pDst->alphaMap)
+    {
+	if (!miClipPictureReg (pRegion, pDst->alphaMap->pCompositeClip,
+			       -pDst->alphaOrigin.x,
+			       -pDst->alphaOrigin.y))
+	{
+	    pixman_region_fini (pRegion);
+	    return FALSE;
+	}
+    }
+    /* clip against src */
+    if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
+    {
+	pixman_region_fini (pRegion);
+	return FALSE;
+    }
+    if (pSrc->alphaMap)
+    {
+	if (!miClipPictureSrc (pRegion, pSrc->alphaMap,
+			       xDst - (xSrc - pSrc->alphaOrigin.x),
+			       yDst - (ySrc - pSrc->alphaOrigin.y)))
+	{
+	    pixman_region_fini (pRegion);
+	    return FALSE;
+	}
+    }
+    /* clip against mask */
+    if (pMask)
+    {
+	if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask))
+	{
+	    pixman_region_fini (pRegion);
+	    return FALSE;
+	}	
+	if (pMask->alphaMap)
+	{
+	    if (!miClipPictureSrc (pRegion, pMask->alphaMap,
+				   xDst - (xMask - pMask->alphaOrigin.x),
+				   yDst - (yMask - pMask->alphaOrigin.y)))
+	    {
+		pixman_region_fini (pRegion);
+		return FALSE;
+	    }
+	}
+    }
+
+    
+    miCompositeSourceValidate (pSrc);
+    if (pMask)
+	miCompositeSourceValidate (pMask);
+
+    return TRUE;
+}
+
+void
+miRenderColorToPixel (PictFormatPtr format,
+		      xRenderColor  *color,
+		      CARD32	    *pixel)
+{
+    CARD32	    r, g, b, a;
+    miIndexedPtr    pIndexed;
+
+    switch (format->type) {
+    case PictTypeDirect:
+	r = color->red >> (16 - Ones (format->direct.redMask));
+	g = color->green >> (16 - Ones (format->direct.greenMask));
+	b = color->blue >> (16 - Ones (format->direct.blueMask));
+	a = color->alpha >> (16 - Ones (format->direct.alphaMask));
+	r = r << format->direct.red;
+	g = g << format->direct.green;
+	b = b << format->direct.blue;
+	a = a << format->direct.alpha;
+	*pixel = r|g|b|a;
+	break;
+    case PictTypeIndexed:
+	pIndexed = (miIndexedPtr) (format->index.devPrivate);
+	if (pIndexed->color)
+	{
+	    r = color->red >> 11;
+	    g = color->green >> 11;
+	    b = color->blue >> 11;
+	    *pixel = miIndexToEnt15 (pIndexed, (r << 10) | (g << 5) | b);
+	}
+	else
+	{
+	    r = color->red >> 8;
+	    g = color->green >> 8;
+	    b = color->blue >> 8;
+	    *pixel = miIndexToEntY24 (pIndexed, (r << 16) | (g << 8) | b);
+	}
+	break;
+    }
+}
+
+static CARD16
+miFillColor (CARD32 pixel, int bits)
+{
+    while (bits < 16)
+    {
+	pixel |= pixel << bits;
+	bits <<= 1;
+    }
+    return (CARD16) pixel;
+}
+
+Bool
+miIsSolidAlpha (PicturePtr pSrc)
+{
+    ScreenPtr	pScreen;
+    char	line[1];
+
+    if (!pSrc->pDrawable)
+        return FALSE;
+
+    pScreen = pSrc->pDrawable->pScreen;
+    
+    /* Alpha-only */
+    if (PICT_FORMAT_TYPE (pSrc->format) != PICT_TYPE_A)
+	return FALSE;
+    /* repeat */
+    if (!pSrc->repeat)
+	return FALSE;
+    /* 1x1 */
+    if (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1)
+	return FALSE;
+    line[0] = 1;
+    (*pScreen->GetImage) (pSrc->pDrawable, 0, 0, 1, 1, ZPixmap, ~0L, line);
+    switch (pSrc->pDrawable->bitsPerPixel) {
+    case 1:
+	return (CARD8) line[0] == 1 || (CARD8) line[0] == 0x80;
+    case 4:
+	return (CARD8) line[0] == 0xf || (CARD8) line[0] == 0xf0;
+    case 8:
+	return (CARD8) line[0] == 0xff;
+    default:
+	return FALSE;
+    }
+}
+
+void
+miRenderPixelToColor (PictFormatPtr format,
+		      CARD32	    pixel,
+		      xRenderColor  *color)
+{
+    CARD32	    r, g, b, a;
+    miIndexedPtr    pIndexed;
+    
+    switch (format->type) {
+    case PictTypeDirect:
+	r = (pixel >> format->direct.red) & format->direct.redMask;
+	g = (pixel >> format->direct.green) & format->direct.greenMask;
+	b = (pixel >> format->direct.blue) & format->direct.blueMask;
+	a = (pixel >> format->direct.alpha) & format->direct.alphaMask;
+	color->red = miFillColor (r, Ones (format->direct.redMask));
+	color->green = miFillColor (g, Ones (format->direct.greenMask));
+	color->blue = miFillColor (b, Ones (format->direct.blueMask));
+	color->alpha = miFillColor (a, Ones (format->direct.alphaMask));
+	break;
+    case PictTypeIndexed:
+	pIndexed = (miIndexedPtr) (format->index.devPrivate);
+	pixel = pIndexed->rgba[pixel & (MI_MAX_INDEXED-1)];
+	r = (pixel >> 16) & 0xff;
+	g = (pixel >>  8) & 0xff;
+	b = (pixel      ) & 0xff;
+	color->red = miFillColor (r, 8);
+	color->green = miFillColor (g, 8);
+	color->blue = miFillColor (b, 8);
+	color->alpha = 0xffff;
+	break;
+    }
+}
+
+Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats)
+{
+    PictureScreenPtr    ps;
+    
+    if (!PictureInit (pScreen, formats, nformats))
+	return FALSE;
+    ps = GetPictureScreen(pScreen);
+    ps->CreatePicture = miCreatePicture;
+    ps->DestroyPicture = miDestroyPicture;
+    ps->ChangePictureClip = miChangePictureClip;
+    ps->DestroyPictureClip = miDestroyPictureClip;
+    ps->ChangePicture = miChangePicture;
+    ps->ValidatePicture = miValidatePicture;
+    ps->InitIndexed = miInitIndexed;
+    ps->CloseIndexed = miCloseIndexed;
+    ps->UpdateIndexed = miUpdateIndexed;
+    ps->ChangePictureTransform = miChangePictureTransform;
+    ps->ChangePictureFilter = miChangePictureFilter;
+    ps->RealizeGlyph = miRealizeGlyph;
+    ps->UnrealizeGlyph = miUnrealizeGlyph;
+
+    /* MI rendering routines */
+    ps->Composite	= 0;			/* requires DDX support */
+    ps->Glyphs		= miGlyphs;
+    ps->CompositeRects	= miCompositeRects;
+    ps->Trapezoids	= 0;
+    ps->Triangles	= 0;
+    
+    ps->RasterizeTrapezoid = 0;			/* requires DDX support */
+    ps->AddTraps	= 0;			/* requires DDX support */
+    ps->AddTriangles	= 0;			/* requires DDX support */
+
+    return TRUE;
+}
diff --git a/xorg-server/render/mipict.h b/xorg-server/render/mipict.h
index d1495891e..f2df601e4 100644
--- a/xorg-server/render/mipict.h
+++ b/xorg-server/render/mipict.h
@@ -1,188 +1,165 @@
-/*
- *
- * Copyright © 2000 SuSE, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  SuSE makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
- *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author:  Keith Packard, SuSE, Inc.
- */
-
-#ifndef _MIPICT_H_
-#define _MIPICT_H_
-
-#include "picturestr.h"
-
-#define MI_MAX_INDEXED	256 /* XXX depth must be <= 8 */
-
-#if MI_MAX_INDEXED <= 256
-typedef CARD8 miIndexType;
-#endif
-
-typedef struct _miIndexed {
-    Bool	color;
-    CARD32	rgba[MI_MAX_INDEXED];
-    miIndexType	ent[32768];
-} miIndexedRec, *miIndexedPtr;
-
-#define miCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) | \
-			     (((s) >> 6) & 0x03e0) | \
-			     (((s) >> 9) & 0x7c00))
-#define miIndexToEnt15(mif,rgb15) ((mif)->ent[rgb15])
-#define miIndexToEnt24(mif,rgb24) miIndexToEnt15(mif,miCvtR8G8B8to15(rgb24))
-
-#define miIndexToEntY24(mif,rgb24) ((mif)->ent[CvtR8G8B8toY15(rgb24)])
-
-extern _X_EXPORT int
-miCreatePicture (PicturePtr pPicture);
-
-extern _X_EXPORT void
-miDestroyPicture (PicturePtr pPicture);
-
-extern _X_EXPORT void
-miDestroyPictureClip (PicturePtr pPicture);
-
-extern _X_EXPORT int
-miChangePictureClip (PicturePtr    pPicture,
-		     int	   type,
-		     pointer	   value,
-		     int	   n);
-
-extern _X_EXPORT void
-miChangePicture (PicturePtr pPicture,
-		 Mask       mask);
-
-extern _X_EXPORT void
-miValidatePicture (PicturePtr pPicture,
-		   Mask       mask);
-
-extern _X_EXPORT int
-miChangePictureTransform (PicturePtr	pPicture,
-			  PictTransform *transform);
-
-extern _X_EXPORT int
-miChangePictureFilter (PicturePtr pPicture,
-		       int	  filter,
-		       xFixed     *params,
-		       int	  nparams);
-
-extern _X_EXPORT void
-miCompositeSourceValidate (PicturePtr	pPicture,
-			   INT16	x,
-			   INT16	y,
-			   CARD16	width,
-			   CARD16	height);
-extern _X_EXPORT Bool
-miComputeCompositeRegion (RegionPtr	pRegion,
-			  PicturePtr	pSrc,
-			  PicturePtr	pMask,
-			  PicturePtr	pDst,
-			  INT16		xSrc,
-			  INT16		ySrc,
-			  INT16		xMask,
-			  INT16		yMask,
-			  INT16		xDst,
-			  INT16		yDst,
-			  CARD16	width,
-			  CARD16	height);
-
-extern _X_EXPORT Bool
-miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
-
-extern _X_EXPORT Bool
-miRealizeGlyph (ScreenPtr pScreen,
-		GlyphPtr  glyph);
-
-extern _X_EXPORT void
-miUnrealizeGlyph (ScreenPtr pScreen,
-		  GlyphPtr  glyph);
-
-extern _X_EXPORT void
-miGlyphs (CARD8		op,
-	  PicturePtr	pSrc,
-	  PicturePtr	pDst,
-	  PictFormatPtr	maskFormat,
-	  INT16		xSrc,
-	  INT16		ySrc,
-	  int		nlist,
-	  GlyphListPtr	list,
-	  GlyphPtr	*glyphs);
-
-extern _X_EXPORT void
-miRenderColorToPixel (PictFormatPtr pPict,
-		      xRenderColor  *color,
-		      CARD32	    *pixel);
-
-extern _X_EXPORT void
-miRenderPixelToColor (PictFormatPtr pPict,
-		      CARD32	    pixel,
-		      xRenderColor  *color);
-
-extern _X_EXPORT Bool
-miIsSolidAlpha (PicturePtr pSrc);
-
-extern _X_EXPORT void
-miCompositeRects (CARD8		op,
-		  PicturePtr	pDst,
-		  xRenderColor  *color,
-		  int		nRect,
-		  xRectangle    *rects);
-
-extern _X_EXPORT void
-miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
-
-extern _X_EXPORT void
-miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds);
-    
-extern _X_EXPORT void
-miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds);
-
-extern _X_EXPORT void
-miTriStrip (CARD8	    op,
-	    PicturePtr	    pSrc,
-	    PicturePtr	    pDst,
-	    PictFormatPtr   maskFormat,
-	    INT16	    xSrc,
-	    INT16	    ySrc,
-	    int		    npoint,
-	    xPointFixed	    *points);
-
-extern _X_EXPORT void
-miTriFan (CARD8		op,
-	  PicturePtr	pSrc,
-	  PicturePtr	pDst,
-	  PictFormatPtr maskFormat,
-	  INT16		xSrc,
-	  INT16		ySrc,
-	  int		npoint,
-	  xPointFixed	*points);
-
-extern _X_EXPORT Bool
-miInitIndexed (ScreenPtr	pScreen,
-	       PictFormatPtr	pFormat);
-
-extern _X_EXPORT void
-miCloseIndexed (ScreenPtr	pScreen,
-		PictFormatPtr	pFormat);
-
-extern _X_EXPORT void
-miUpdateIndexed (ScreenPtr	pScreen,
-		 PictFormatPtr	pFormat,
-		 int		ndef,
-		 xColorItem	*pdef);
-
-#endif /* _MIPICT_H_ */
+/*
+ *
+ * Copyright © 2000 SuSE, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author:  Keith Packard, SuSE, Inc.
+ */
+
+#ifndef _MIPICT_H_
+#define _MIPICT_H_
+
+#include "picturestr.h"
+
+#define MI_MAX_INDEXED	256 /* XXX depth must be <= 8 */
+
+#if MI_MAX_INDEXED <= 256
+typedef CARD8 miIndexType;
+#endif
+
+typedef struct _miIndexed {
+    Bool	color;
+    CARD32	rgba[MI_MAX_INDEXED];
+    miIndexType	ent[32768];
+} miIndexedRec, *miIndexedPtr;
+
+#define miCvtR8G8B8to15(s) ((((s) >> 3) & 0x001f) | \
+			     (((s) >> 6) & 0x03e0) | \
+			     (((s) >> 9) & 0x7c00))
+#define miIndexToEnt15(mif,rgb15) ((mif)->ent[rgb15])
+#define miIndexToEnt24(mif,rgb24) miIndexToEnt15(mif,miCvtR8G8B8to15(rgb24))
+
+#define miIndexToEntY24(mif,rgb24) ((mif)->ent[CvtR8G8B8toY15(rgb24)])
+
+extern _X_EXPORT int
+miCreatePicture (PicturePtr pPicture);
+
+extern _X_EXPORT void
+miDestroyPicture (PicturePtr pPicture);
+
+extern _X_EXPORT void
+miDestroyPictureClip (PicturePtr pPicture);
+
+extern _X_EXPORT int
+miChangePictureClip (PicturePtr    pPicture,
+		     int	   type,
+		     pointer	   value,
+		     int	   n);
+
+extern _X_EXPORT void
+miChangePicture (PicturePtr pPicture,
+		 Mask       mask);
+
+extern _X_EXPORT void
+miValidatePicture (PicturePtr pPicture,
+		   Mask       mask);
+
+extern _X_EXPORT int
+miChangePictureTransform (PicturePtr	pPicture,
+			  PictTransform *transform);
+
+extern _X_EXPORT int
+miChangePictureFilter (PicturePtr pPicture,
+		       int	  filter,
+		       xFixed     *params,
+		       int	  nparams);
+
+extern _X_EXPORT void
+miCompositeSourceValidate (PicturePtr pPicture);
+
+extern _X_EXPORT Bool
+miComputeCompositeRegion (RegionPtr	pRegion,
+			  PicturePtr	pSrc,
+			  PicturePtr	pMask,
+			  PicturePtr	pDst,
+			  INT16		xSrc,
+			  INT16		ySrc,
+			  INT16		xMask,
+			  INT16		yMask,
+			  INT16		xDst,
+			  INT16		yDst,
+			  CARD16	width,
+			  CARD16	height);
+
+extern _X_EXPORT Bool
+miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats);
+
+extern _X_EXPORT Bool
+miRealizeGlyph (ScreenPtr pScreen,
+		GlyphPtr  glyph);
+
+extern _X_EXPORT void
+miUnrealizeGlyph (ScreenPtr pScreen,
+		  GlyphPtr  glyph);
+
+extern _X_EXPORT void
+miGlyphs (CARD8		op,
+	  PicturePtr	pSrc,
+	  PicturePtr	pDst,
+	  PictFormatPtr	maskFormat,
+	  INT16		xSrc,
+	  INT16		ySrc,
+	  int		nlist,
+	  GlyphListPtr	list,
+	  GlyphPtr	*glyphs);
+
+extern _X_EXPORT void
+miRenderColorToPixel (PictFormatPtr pPict,
+		      xRenderColor  *color,
+		      CARD32	    *pixel);
+
+extern _X_EXPORT void
+miRenderPixelToColor (PictFormatPtr pPict,
+		      CARD32	    pixel,
+		      xRenderColor  *color);
+
+extern _X_EXPORT Bool
+miIsSolidAlpha (PicturePtr pSrc);
+
+extern _X_EXPORT void
+miCompositeRects (CARD8		op,
+		  PicturePtr	pDst,
+		  xRenderColor  *color,
+		  int		nRect,
+		  xRectangle    *rects);
+
+extern _X_EXPORT void
+miTrapezoidBounds (int ntrap, xTrapezoid *traps, BoxPtr box);
+
+extern _X_EXPORT void
+miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds);
+    
+extern _X_EXPORT void
+miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds);
+
+extern _X_EXPORT Bool
+miInitIndexed (ScreenPtr	pScreen,
+	       PictFormatPtr	pFormat);
+
+extern _X_EXPORT void
+miCloseIndexed (ScreenPtr	pScreen,
+		PictFormatPtr	pFormat);
+
+extern _X_EXPORT void
+miUpdateIndexed (ScreenPtr	pScreen,
+		 PictFormatPtr	pFormat,
+		 int		ndef,
+		 xColorItem	*pdef);
+
+#endif /* _MIPICT_H_ */
diff --git a/xorg-server/render/mitri.c b/xorg-server/render/mitri.c
index b258c2156..8c5298e25 100644
--- a/xorg-server/render/mitri.c
+++ b/xorg-server/render/mitri.c
@@ -1,132 +1,68 @@
-/*
- *
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "picturestr.h"
-#include "mipict.h"
-
-void
-miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds)
-{
-    bounds->x1 = xFixedToInt (points->x);
-    bounds->x2 = xFixedToInt (xFixedCeil (points->x));
-    bounds->y1 = xFixedToInt (points->y);
-    bounds->y2 = xFixedToInt (xFixedCeil (points->y));
-    points++;
-    npoint--;
-    while (npoint-- > 0)
-    {
-	INT16	x1 = xFixedToInt (points->x);
-	INT16	x2 = xFixedToInt (xFixedCeil (points->x));
-	INT16	y1 = xFixedToInt (points->y);
-	INT16	y2 = xFixedToInt (xFixedCeil (points->y));
-
-	if (x1 < bounds->x1)
-	    bounds->x1 = x1;
-	else if (x2 > bounds->x2)
-	    bounds->x2 = x2;
-	if (y1 < bounds->y1)
-	    bounds->y1 = y1;
-	else if (y2 > bounds->y2)
-	    bounds->y2 = y2;
-	points++;
-    }
-}
-
-void
-miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds)
-{
-    miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds);
-}
-
-void
-miTriStrip (CARD8	    op,
-	    PicturePtr	    pSrc,
-	    PicturePtr	    pDst,
-	    PictFormatPtr   maskFormat,
-	    INT16	    xSrc,
-	    INT16	    ySrc,
-	    int		    npoint,
-	    xPointFixed	    *points)
-{
-    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
-    PictureScreenPtr    ps = GetPictureScreen(pScreen);
-    xTriangle		*tris, *tri;
-    int			ntri;
-    
-    if (npoint < 3)
-	return;
-    ntri = npoint - 2;
-    tris = malloc(ntri * sizeof (xTriangle));
-    if (!tris)
-	return;
-    for (tri = tris; npoint >= 3; npoint--, points++, tri++)
-    {
-	tri->p1 = points[0];
-	tri->p2 = points[1];
-	tri->p3 = points[2];
-    }
-    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
-    free(tris);
-}
-
-void
-miTriFan (CARD8		op,
-	  PicturePtr	pSrc,
-	  PicturePtr	pDst,
-	  PictFormatPtr	maskFormat,
-	  INT16		xSrc,
-	  INT16		ySrc,
-	  int		npoint,
-	  xPointFixed	*points)
-{
-    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
-    PictureScreenPtr    ps = GetPictureScreen(pScreen);
-    xTriangle		*tris, *tri;
-    xPointFixed		*first;
-    int			ntri;
-    
-    if (npoint < 3)
-	return;
-    ntri = npoint - 2;
-    tris = malloc(ntri * sizeof (xTriangle));
-    if (!tris)
-	return;
-    first = points++;
-    for (tri = tris; npoint >= 3; npoint--, points++, tri++)
-    {
-	tri->p1 = *first;
-	tri->p2 = points[0];
-	tri->p3 = points[1];
-    }
-    (*ps->Triangles) (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
-    free(tris);
-}
+/*
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "mipict.h"
+
+void
+miPointFixedBounds (int npoint, xPointFixed *points, BoxPtr bounds)
+{
+    bounds->x1 = xFixedToInt (points->x);
+    bounds->x2 = xFixedToInt (xFixedCeil (points->x));
+    bounds->y1 = xFixedToInt (points->y);
+    bounds->y2 = xFixedToInt (xFixedCeil (points->y));
+    points++;
+    npoint--;
+    while (npoint-- > 0)
+    {
+	INT16	x1 = xFixedToInt (points->x);
+	INT16	x2 = xFixedToInt (xFixedCeil (points->x));
+	INT16	y1 = xFixedToInt (points->y);
+	INT16	y2 = xFixedToInt (xFixedCeil (points->y));
+
+	if (x1 < bounds->x1)
+	    bounds->x1 = x1;
+	else if (x2 > bounds->x2)
+	    bounds->x2 = x2;
+	if (y1 < bounds->y1)
+	    bounds->y1 = y1;
+	else if (y2 > bounds->y2)
+	    bounds->y2 = y2;
+	points++;
+    }
+}
+
+void
+miTriangleBounds (int ntri, xTriangle *tris, BoxPtr bounds)
+{
+    miPointFixedBounds (ntri * 3, (xPointFixed *) tris, bounds);
+}
diff --git a/xorg-server/render/picture.c b/xorg-server/render/picture.c
index d31b77466..ed7a1d8f1 100644
--- a/xorg-server/render/picture.c
+++ b/xorg-server/render/picture.c
@@ -1773,11 +1773,25 @@ CompositeTriStrip (CARD8	    op,
 		   int		    npoints,
 		   xPointFixed	    *points)
 {
-    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    ScreenPtr           pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+    xTriangle           *tris, *tri;
+    int                 ntri;
     
-    ValidatePicture (pSrc);
-    ValidatePicture (pDst);
-    (*ps->TriStrip) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+    if (npoints < 3)
+        return;
+    ntri = npoints - 2;
+    tris = malloc(ntri * sizeof (xTriangle));
+    if (!tris)
+        return;
+    for (tri = tris; npoints >= 3; npoints--, points++, tri++)
+    {
+        tri->p1 = points[0];
+        tri->p2 = points[1];
+        tri->p3 = points[2];
+    }
+    CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
+    free(tris);
 }
 
 void
@@ -1790,11 +1804,26 @@ CompositeTriFan (CARD8		op,
 		 int		npoints,
 		 xPointFixed	*points)
 {
-    PictureScreenPtr	ps = GetPictureScreen(pDst->pDrawable->pScreen);
+    ScreenPtr		pScreen = pDst->pDrawable->pScreen;
+    xTriangle		*tris, *tri;
+    xPointFixed		*first;
+    int			ntri;
     
-    ValidatePicture (pSrc);
-    ValidatePicture (pDst);
-    (*ps->TriFan) (op, pSrc, pDst, maskFormat, xSrc, ySrc, npoints, points);
+    if (npoints < 3)
+	return;
+    ntri = npoints - 2;
+    tris = malloc(ntri * sizeof (xTriangle));
+    if (!tris)
+	return;
+    first = points++;
+    for (tri = tris; npoints >= 3; npoints--, points++, tri++)
+    {
+	tri->p1 = *first;
+	tri->p2 = points[0];
+	tri->p3 = points[1];
+    }
+    CompositeTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, tris);
+    free(tris);
 }
 
 void
diff --git a/xorg-server/render/picturestr.h b/xorg-server/render/picturestr.h
index ee62e6a17..f642bf0df 100644
--- a/xorg-server/render/picturestr.h
+++ b/xorg-server/render/picturestr.h
@@ -381,8 +381,6 @@ typedef struct _PictureScreen {
 
     TrapezoidsProcPtr		Trapezoids;
     TrianglesProcPtr		Triangles;
-    TriStripProcPtr		TriStrip;
-    TriFanProcPtr		TriFan;
 
     RasterizeTrapezoidProcPtr	RasterizeTrapezoid;
 
diff --git a/xorg-server/test/Makefile.am b/xorg-server/test/Makefile.am
index 8bb3a0688..d93c7a223 100644
--- a/xorg-server/test/Makefile.am
+++ b/xorg-server/test/Makefile.am
@@ -1,6 +1,6 @@
 if UNITTESTS
 SUBDIRS= . xi2
-check_PROGRAMS = xkb input xtest
+check_PROGRAMS = xkb input xtest list
 check_LTLIBRARIES = libxservertest.la
 
 TESTS=$(check_PROGRAMS)
@@ -16,6 +16,7 @@ endif
 xkb_LDADD=$(TEST_LDADD)
 input_LDADD=$(TEST_LDADD)
 xtest_LDADD=$(TEST_LDADD)
+list_LDADD=$(TEST_LDADD)
 
 libxservertest_la_LIBADD = \
             $(XSERVER_LIBS) \
diff --git a/xorg-server/test/list.c b/xorg-server/test/list.c
new file mode 100644
index 000000000..7e035fe58
--- /dev/null
+++ b/xorg-server/test/list.c
@@ -0,0 +1,176 @@
+/**
+ * Copyright © 2011 Red Hat, Inc.
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),
+ *  to deal in the Software without restriction, including without limitation
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice (including the next
+ *  paragraph) shall be included in all copies or substantial portions of the
+ *  Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/Xlib.h>
+#include <list.h>
+#include <string.h>
+#include <glib.h>
+
+struct parent {
+    int a;
+    struct list children;
+    int b;
+};
+
+struct child {
+    int foo;
+    int bar;
+    struct list node;
+};
+
+static void
+test_list_init(void)
+{
+    struct parent parent, tmp;
+
+    memset(&parent, 0, sizeof(parent));
+    parent.a = 0xa5a5a5;
+    parent.b = ~0xa5a5a5;
+
+    tmp = parent;
+
+    list_init(&parent.children);
+
+    /* test we haven't touched anything else. */
+    g_assert(parent.a == tmp.a);
+    g_assert(parent.b == tmp.b);
+
+    g_assert(list_is_empty(&parent.children));
+}
+
+static void
+test_list_add(void)
+{
+    struct parent parent = {0};
+    struct child child[3];
+    struct child *c;
+
+    list_init(&parent.children);
+
+    list_add(&child[0].node, &parent.children);
+    g_assert(!list_is_empty(&parent.children));
+
+    c = list_first_entry(&parent.children, struct child, node);
+    g_assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
+
+    /* note: list_add prepends */
+    list_add(&child[1].node, &parent.children);
+    c = list_first_entry(&parent.children, struct child, node);
+    g_assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
+
+    list_add(&child[2].node, &parent.children);
+    c = list_first_entry(&parent.children, struct child, node);
+    g_assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
+};
+
+static void
+test_list_del(void)
+{
+    struct parent parent = {0};
+    struct child child[3];
+    struct child *c;
+
+    list_init(&parent.children);
+
+    list_add(&child[0].node, &parent.children);
+    g_assert(!list_is_empty(&parent.children));
+
+    list_del(&parent.children);
+    g_assert(list_is_empty(&parent.children));
+
+    list_add(&child[0].node, &parent.children);
+    list_del(&child[0].node);
+    g_assert(list_is_empty(&parent.children));
+
+    list_add(&child[0].node, &parent.children);
+    list_add(&child[1].node, &parent.children);
+
+    c = list_first_entry(&parent.children, struct child, node);
+    g_assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
+
+    /* delete first node */
+    list_del(&child[1].node);
+    g_assert(!list_is_empty(&parent.children));
+    g_assert(list_is_empty(&child[1].node));
+    c = list_first_entry(&parent.children, struct child, node);
+    g_assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
+
+    /* delete last node */
+    list_add(&child[1].node, &parent.children);
+    list_del(&child[0].node);
+    c = list_first_entry(&parent.children, struct child, node);
+    g_assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
+
+    /* delete list head */
+    list_add(&child[0].node, &parent.children);
+    list_del(&parent.children);
+    g_assert(list_is_empty(&parent.children));
+    g_assert(!list_is_empty(&child[1].node));
+    g_assert(!list_is_empty(&child[2].node));
+}
+
+static void
+test_list_for_each(void)
+{
+    struct parent parent = {0};
+    struct child child[3];
+    struct child *c;
+    int i = 0;
+
+    list_init(&parent.children);
+
+    list_add(&child[2].node, &parent.children);
+    list_add(&child[1].node, &parent.children);
+    list_add(&child[0].node, &parent.children);
+
+    list_for_each_entry(c, &parent.children, node) {
+        g_assert(memcmp(c, &child[i], sizeof(struct child)) == 0);
+        i++;
+    }
+
+    /* foreach on empty list */
+    list_del(&parent.children);
+    g_assert(list_is_empty(&parent.children));
+
+    list_for_each_entry(c, &parent.children, node) {
+        g_assert(0); /* we must not get here */
+    }
+}
+
+
+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("/list/init", test_list_init);
+    g_test_add_func("/list/add", test_list_add);
+    g_test_add_func("/list/del", test_list_del);
+    g_test_add_func("/list/for_each", test_list_for_each);
+
+    return g_test_run();
+}
diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c
index 65c678af8..8cd9b44a1 100644
--- a/xorg-server/xkb/xkbActions.c
+++ b/xorg-server/xkb/xkbActions.c
@@ -1,1441 +1,1434 @@
-/************************************************************
-Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
-
-Permission to use, copy, modify, and distribute this
-software and its documentation for any purpose and without
-fee is hereby granted, provided that the above copyright
-notice appear in all copies and that both that copyright
-notice and this permission notice appear in supporting
-documentation, and that the name of Silicon Graphics not be 
-used in advertising or publicity pertaining to distribution 
-of the software without specific prior written permission.
-Silicon Graphics makes no representation about the suitability 
-of this software for any purpose. It is provided "as is"
-without any express or implied warranty.
-
-SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
-SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
-AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
-GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
-OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
-THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-********************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stdio.h>
-#include <math.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include "misc.h"
-#include "inputstr.h"
-#include "exevents.h"
-#include "eventstr.h"
-#include <xkbsrv.h>
-#include "xkb.h"
-#include <ctype.h>
-#include "mi.h"
-#include "mipointer.h"
-#include "inpututils.h"
-#define EXTENSION_EVENT_BASE 64
-
-DevPrivateKeyRec xkbDevicePrivateKeyRec;
-
-void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
-static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
-
-void
-xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
-                   pointer data)
-{
-    xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
-    ProcessInputProc backupproc;
-    if(xkbPrivPtr->unwrapProc)
-	xkbPrivPtr->unwrapProc = NULL;
-
-    UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc);
-    proc(device,data);
-    COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
-				 backupproc,xkbUnwrapProc);
-}
-
-Bool
-XkbInitPrivates(void)
-{
-    return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE, 0);
-}
-
-void
-XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
-{
-    xkbDeviceInfoPtr xkbPrivPtr;
-
-    xkbPrivPtr = (xkbDeviceInfoPtr) calloc(1, sizeof(xkbDeviceInfoRec));
-    if (!xkbPrivPtr)
-	return;
-    xkbPrivPtr->unwrapProc = NULL;
-
-    dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr);
-    WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
-}
-
-/***====================================================================***/
-
-static XkbAction
-_FixUpAction(XkbDescPtr xkb,XkbAction *act)
-{
-static XkbAction	fake;
-
-    if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
-	fake.type = XkbSA_NoAction;
-	return fake;
-    }
-    if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
-	if (act->any.type==XkbSA_SetMods) {
-	    fake.mods.type = XkbSA_LatchMods;
-	    fake.mods.mask = act->mods.mask;
-	    if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
-		 fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
-	    else fake.mods.flags= XkbSA_ClearLocks;
-	    return fake;
-	}
-	if (act->any.type==XkbSA_SetGroup) {
-	    fake.group.type = XkbSA_LatchGroup;
-	    if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
-		 fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
-	    else fake.group.flags= XkbSA_ClearLocks;
-	    XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
-	    return fake;
-	}
-    }
-    return *act;
-}
-
-static XkbAction
-XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
-{
-int			effectiveGroup;
-int			col;
-XkbDescPtr		xkb;
-XkbKeyTypePtr		type;
-XkbAction *		pActs;
-static XkbAction 	fake;
-
-    xkb= xkbi->desc;
-    if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
-	fake.type = XkbSA_NoAction;
-	return fake;
-    }
-    pActs= XkbKeyActionsPtr(xkb,key);
-    col= 0;
-
-    effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
-    if (effectiveGroup != XkbGroup1Index)
-        col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
-
-    type= XkbKeyKeyType(xkb,key,effectiveGroup);
-    if (type->map!=NULL) {
-	register unsigned		i,mods;
-	register XkbKTMapEntryPtr	entry;
-	mods= xkbState->mods&type->mods.mask;
-	for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
-	    if ((entry->active)&&(entry->mods.mask==mods)) {
-		col+= entry->level;
-		break;
-	    }
-	}
-    }
-    if (pActs[col].any.type==XkbSA_NoAction)
-	return pActs[col];
-    fake= _FixUpAction(xkb,&pActs[col]);
-    return fake;
-}
-
-static XkbAction
-XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
-{
-XkbAction fake;
-   if ((dev->button)&&(dev->button->xkb_acts)) {
-	if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
-	    fake= _FixUpAction(kbd->key->xkbInfo->desc,
-					&dev->button->xkb_acts[button-1]);
-	    return fake;
-	}
-   }
-   fake.any.type= XkbSA_NoAction;
-   return fake;
-}
-
-/***====================================================================***/
-
-#define	SYNTHETIC_KEYCODE	1
-#define	BTN_ACT_FLAG		0x100
-
-static int
-_XkbFilterSetState(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *pAction)
-{
-    if (filter->keycode==0) {		/* initial press */
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
-	filter->priv = 0;
-	filter->filter = _XkbFilterSetState;
-	if (pAction->type==XkbSA_SetMods) {
-	    filter->upAction = *pAction;
-	    xkbi->setMods= pAction->mods.mask;
-	}
-	else {
-	    xkbi->groupChange = XkbSAGroup(&pAction->group);
-	    if (pAction->group.flags&XkbSA_GroupAbsolute)
-		xkbi->groupChange-= xkbi->state.base_group;
-	    filter->upAction= *pAction;
-	    XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
-	}
-    }
-    else if (filter->keycode==keycode) {
-	if (filter->upAction.type==XkbSA_SetMods) {
-	    xkbi->clearMods = filter->upAction.mods.mask;
-	    if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
-		xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
-	    }
-	}
-	else {
-	    if (filter->upAction.group.flags&XkbSA_ClearLocks) {
-		xkbi->state.locked_group = 0;
-	    }
-	    xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
-	}
-	filter->active = 0;
-    }
-    else {
-	filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
-	filter->filterOthers = 0;
-    }
-    return 1;
-}
-
-#define	LATCH_KEY_DOWN	1
-#define	LATCH_PENDING	2
-#define	NO_LATCH	3
-
-static int
-_XkbFilterLatchState(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-
-    if (filter->keycode==0) {			/* initial press */
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 1;
-	filter->priv = LATCH_KEY_DOWN;
-	filter->filter = _XkbFilterLatchState;
-	if (pAction->type==XkbSA_LatchMods) {
-	    filter->upAction = *pAction;
-	    xkbi->setMods = pAction->mods.mask;
-	}
-	else {
-	    xkbi->groupChange = XkbSAGroup(&pAction->group);
-	    if (pAction->group.flags&XkbSA_GroupAbsolute)
-		 xkbi->groupChange-= xkbi->state.base_group;
-	    filter->upAction= *pAction;
-	    XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
-	}
-    }
-    else if ( pAction && (filter->priv==LATCH_PENDING) ) {
-	if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
-	    filter->active = 0;
-	    if (filter->upAction.type==XkbSA_LatchMods)
-		 xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
-	    else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
-	}
-	else if ((pAction->type==filter->upAction.type)&&
-		 (pAction->mods.flags==filter->upAction.mods.flags)&&
-		 (pAction->mods.mask==filter->upAction.mods.mask)) {
-	    if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
-		XkbControlsPtr ctrls= xkbi->desc->ctrls;
-		if (filter->upAction.type==XkbSA_LatchMods)
-		     pAction->mods.type= XkbSA_LockMods;
-		else pAction->group.type= XkbSA_LockGroup;
-		if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
-		    		(ctrls->enabled_ctrls&XkbStickyKeysMask)) {
-		    XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
-						XkbStickyKeysMask);
-		}
-	    }
-	    else {
-		if (filter->upAction.type==XkbSA_LatchMods)
-		     pAction->mods.type= XkbSA_SetMods;
-		else pAction->group.type= XkbSA_SetGroup;
-	    }
-	    if (filter->upAction.type==XkbSA_LatchMods)
-		 xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
-	    else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
-	    filter->active = 0;
-	}
-    }
-    else if (filter->keycode==keycode) {	/* release */
-	XkbControlsPtr	ctrls= xkbi->desc->ctrls;
-	int		needBeep;
-	int		beepType= _BEEP_NONE;
-
-	needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
-			XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
-	if (filter->upAction.type==XkbSA_LatchMods) {
-	    xkbi->clearMods = filter->upAction.mods.mask;
-	    if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
-		 (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
-		xkbi->state.locked_mods&= ~xkbi->clearMods;
-		filter->priv= NO_LATCH;
-		beepType= _BEEP_STICKY_UNLOCK;
-	    }
-	}
-	else {
-	    xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
-	    if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
-						(xkbi->state.locked_group)) {
-		xkbi->state.locked_group = 0;
-		filter->priv = NO_LATCH;
-		beepType= _BEEP_STICKY_UNLOCK;
-	    }
-	}
-	if (filter->priv==NO_LATCH) {
-	    filter->active= 0;
-	}
-	else {
-	    filter->priv= LATCH_PENDING;
-	    if (filter->upAction.type==XkbSA_LatchMods) {
-		xkbi->state.latched_mods |= filter->upAction.mods.mask;
-		needBeep = xkbi->state.latched_mods ? needBeep : 0;
-		xkbi->state.latched_mods |= filter->upAction.mods.mask;
-	    }
-	    else {
-		xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
-	    }
-	    if (needBeep && (beepType==_BEEP_NONE))
-		beepType= _BEEP_STICKY_LATCH;
-	}
-	if (needBeep && (beepType!=_BEEP_NONE))
-	    XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
-    }
-    else if (filter->priv==LATCH_KEY_DOWN) {
-	filter->priv= NO_LATCH;
-	filter->filterOthers = 0;
-    }
-    return 1;
-}
-
-static int
-_XkbFilterLockState(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-    if (pAction&&(pAction->type==XkbSA_LockGroup)) {
-	if (pAction->group.flags&XkbSA_GroupAbsolute)
-	     xkbi->state.locked_group= XkbSAGroup(&pAction->group);
-	else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
-	return 1;
-    }
-    if (filter->keycode==0) {		/* initial press */
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 0;
-	filter->priv = 0;
-	filter->filter = _XkbFilterLockState;
-	filter->upAction = *pAction;
-	xkbi->state.locked_mods^= pAction->mods.mask;
-	xkbi->setMods = pAction->mods.mask;
-    }
-    else if (filter->keycode==keycode) {
-	filter->active = 0;
-	xkbi->clearMods = filter->upAction.mods.mask;
-    }
-    return 1;
-}
-
-#define	ISO_KEY_DOWN		0
-#define	NO_ISO_LOCK		1
-
-static int
-_XkbFilterISOLock(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-
-    if (filter->keycode==0) {		/* initial press */
-	CARD8	flags= pAction->iso.flags;
-
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 1;
-	filter->priv = ISO_KEY_DOWN;
-	filter->upAction = *pAction;
-	filter->filter = _XkbFilterISOLock;
-	if (flags&XkbSA_ISODfltIsGroup) {
-	    xkbi->groupChange = XkbSAGroup(&pAction->iso);
-	    xkbi->setMods = 0;
-	}
-	else {
-	    xkbi->setMods = pAction->iso.mask;
-	    xkbi->groupChange = 0;
-	}
-	if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
-	    filter->priv= NO_ISO_LOCK;
-	    xkbi->state.locked_mods^= xkbi->state.base_mods;
-	}
-	if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
-/* 6/22/93 (ef) -- lock groups if group key is down first */
-	}
-	if (!(flags&XkbSA_ISONoAffectPtr)) {
-/* 6/22/93 (ef) -- lock mouse buttons if they're down */
-	}
-    }
-    else if (filter->keycode==keycode) {
-	CARD8	flags= filter->upAction.iso.flags;
-
-	if (flags&XkbSA_ISODfltIsGroup) {
-	    xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
-	    xkbi->clearMods = 0;
-	    if (filter->priv==ISO_KEY_DOWN)
-		xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
-	}
-	else {
-	    xkbi->clearMods= filter->upAction.iso.mask;
-	    xkbi->groupChange= 0;
-	    if (filter->priv==ISO_KEY_DOWN)
-		xkbi->state.locked_mods^= filter->upAction.iso.mask;
-	}
-	filter->active = 0;
-    }
-    else if (pAction) {
-	CARD8	flags= filter->upAction.iso.flags;
-
-	switch (pAction->type) {
-	    case XkbSA_SetMods: case XkbSA_LatchMods:
-		if (!(flags&XkbSA_ISONoAffectMods)) {
-		    pAction->type= XkbSA_LockMods;
-		    filter->priv= NO_ISO_LOCK;
-		}
-		break;
-	    case XkbSA_SetGroup: case XkbSA_LatchGroup:
-		if (!(flags&XkbSA_ISONoAffectGroup)) {
-		    pAction->type= XkbSA_LockGroup;
-		    filter->priv= NO_ISO_LOCK;
-		}
-		break;
-	    case XkbSA_PtrBtn:
-		if (!(flags&XkbSA_ISONoAffectPtr)) {
-		     pAction->type= XkbSA_LockPtrBtn;
-		     filter->priv= NO_ISO_LOCK;
-		}
-		break;
-	    case XkbSA_SetControls:
-		if (!(flags&XkbSA_ISONoAffectCtrls)) {
-		    pAction->type= XkbSA_LockControls;
-		    filter->priv= NO_ISO_LOCK;
-		}
-		break;
-	}
-    }
-    return 1;
-}
-
-
-static CARD32
-_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
-{
-XkbSrvInfoPtr	xkbi= (XkbSrvInfoPtr)arg;
-XkbControlsPtr	ctrls= xkbi->desc->ctrls;
-int		dx,dy;
-
-    if (xkbi->mouseKey==0)
-	return 0;
-
-    if (xkbi->mouseKeysAccel) {
-	if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
-	    double step;
-	    xkbi->mouseKeysCounter++;
-	    step= xkbi->mouseKeysCurveFactor*
-		 pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
-	    if (xkbi->mouseKeysDX<0)
-		 dx= floor( ((double)xkbi->mouseKeysDX)*step );
-	    else dx=  ceil( ((double)xkbi->mouseKeysDX)*step );
-	    if (xkbi->mouseKeysDY<0)
-		 dy= floor( ((double)xkbi->mouseKeysDY)*step );
-	    else dy=  ceil( ((double)xkbi->mouseKeysDY)*step );
-	}
-	else {
-	    dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
-	    dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
-	}
-	if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
-	    dx= xkbi->mouseKeysDX;
-	if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
-	    dy= xkbi->mouseKeysDY;
-    }
-    else {
-	dx= xkbi->mouseKeysDX;
-	dy= xkbi->mouseKeysDY;
-    }
-    XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
-    return xkbi->desc->ctrls->mk_interval;
-}
-
-static int
-_XkbFilterPointerMove(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-int	x,y;
-Bool	accel;
-
-    if (filter->keycode==0) {		/* initial press */
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 0;
-	filter->priv=0;
-	filter->filter = _XkbFilterPointerMove;
-	filter->upAction= *pAction;
-	xkbi->mouseKeysCounter= 0;
-	xkbi->mouseKey= keycode;
-	accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
-	x= XkbPtrActionX(&pAction->ptr);
-	y= XkbPtrActionY(&pAction->ptr);
-	XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
-	AccessXCancelRepeatKey(xkbi,keycode);
-	xkbi->mouseKeysAccel= accel&&
-		(xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
-	xkbi->mouseKeysFlags= pAction->ptr.flags;
-	xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
-	xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
-	xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
-				xkbi->desc->ctrls->mk_delay,
-				_XkbPtrAccelExpire,(pointer)xkbi);
-    }
-    else if (filter->keycode==keycode) {
-	filter->active = 0;
-	if (xkbi->mouseKey==keycode) {
-	    xkbi->mouseKey= 0;
-	    xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
-							NULL, NULL);
-	}
-    }
-    return 0;
-}
-
-static int
-_XkbFilterPointerBtn(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-    if (filter->keycode==0) {		/* initial press */
-	int	button= pAction->btn.button;
-
-	if (button==XkbSA_UseDfltButton)
-	    button = xkbi->desc->ctrls->mk_dflt_btn;
-
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 0;
-	filter->priv=0;
-	filter->filter = _XkbFilterPointerBtn;
-	filter->upAction= *pAction;
-	filter->upAction.btn.button= button;
-	switch (pAction->type) {
-	    case XkbSA_LockPtrBtn:
-		if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
-			((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
-		    xkbi->lockedPtrButtons|= (1<<button);
-		    AccessXCancelRepeatKey(xkbi,keycode);
-		    XkbFakeDeviceButton(xkbi->device, 1, button);
-		    filter->upAction.type= XkbSA_NoAction;
-		}
-		break;
-	    case XkbSA_PtrBtn:
-		{
-		    register int i,nClicks;
-		    AccessXCancelRepeatKey(xkbi,keycode);
-		    if (pAction->btn.count>0) {
-			nClicks= pAction->btn.count;
-			for (i=0;i<nClicks;i++) {
-			    XkbFakeDeviceButton(xkbi->device, 1, button);
-			    XkbFakeDeviceButton(xkbi->device, 0, button);
-			}
-			filter->upAction.type= XkbSA_NoAction;
-		    }
-		    else XkbFakeDeviceButton(xkbi->device, 1, button);
-		}
-		break;
-	    case XkbSA_SetPtrDflt:
-		{
-		    XkbControlsPtr	ctrls= xkbi->desc->ctrls;
-		    XkbControlsRec	old;
-		    xkbControlsNotify	cn;
-
-		    old= *ctrls;
-		    AccessXCancelRepeatKey(xkbi,keycode);
-		    switch (pAction->dflt.affect) {
-			case XkbSA_AffectDfltBtn:
-			    if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
-				ctrls->mk_dflt_btn= 
-					XkbSAPtrDfltValue(&pAction->dflt);
-			    else {
-				ctrls->mk_dflt_btn+=
-					XkbSAPtrDfltValue(&pAction->dflt);
-				if (ctrls->mk_dflt_btn>5)
-				    ctrls->mk_dflt_btn= 5;
-				else if (ctrls->mk_dflt_btn<1)
-				    ctrls->mk_dflt_btn= 1;
-			    }
-			    break;
-			default:
-			    ErrorF(
-		"Attempt to change unknown pointer default (%d) ignored\n",
-							pAction->dflt.affect);
-			    break;
-		    }
-		    if (XkbComputeControlsNotify(xkbi->device,
-						&old,xkbi->desc->ctrls,
-						&cn,FALSE)) {
-			cn.keycode = keycode;
-                        /* XXX: what about DeviceKeyPress? */
-			cn.eventType = KeyPress;
-			cn.requestMajor = 0;
-			cn.requestMinor = 0;
-			XkbSendControlsNotify(xkbi->device,&cn);
-		    }
-		}
-		break;
-	}
-    }
-    else if (filter->keycode==keycode) {
-	int	button= filter->upAction.btn.button;
-
-	switch (filter->upAction.type) {
-	    case XkbSA_LockPtrBtn:
-		if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
-				((xkbi->lockedPtrButtons&(1<<button))==0)) {
-		    break;
-		}
-		xkbi->lockedPtrButtons&= ~(1<<button);
-
-		if (IsMaster(xkbi->device))
-		{
-		    XkbMergeLockedPtrBtns(xkbi->device);
-                    /* One SD still has lock set, don't post event */
-		    if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
-			break;
-		}
-
-		/* fallthrough */
-	    case XkbSA_PtrBtn:
-		XkbFakeDeviceButton(xkbi->device, 0, button);
-		break;
-	}
-	filter->active = 0;
-    }
-    return 0;
-}
-
-static int
-_XkbFilterControls(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-XkbControlsRec		old;
-XkbControlsPtr		ctrls;
-DeviceIntPtr		kbd;
-unsigned int		change;
-XkbEventCauseRec	cause;
-
-    kbd= xkbi->device;
-    ctrls= xkbi->desc->ctrls;
-    old= *ctrls;
-    if (filter->keycode==0) {		/* initial press */
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 0;
-	change= XkbActionCtrls(&pAction->ctrls);
-	filter->priv = change;
-	filter->filter = _XkbFilterControls;
-	filter->upAction = *pAction;
-
-	if (pAction->type==XkbSA_LockControls) {
-	    filter->priv= (ctrls->enabled_ctrls&change);
-	    change&= ~ctrls->enabled_ctrls;
-	}
-
-	if (change) {
-	    xkbControlsNotify	cn;
-	    XkbSrvLedInfoPtr	sli;
-
-	    ctrls->enabled_ctrls|= change;
-	    if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
-		cn.keycode = keycode;
-                /* XXX: what about DeviceKeyPress? */
-		cn.eventType = KeyPress;
-		cn.requestMajor = 0;
-		cn.requestMinor = 0;
-		XkbSendControlsNotify(kbd,&cn);
-	    }
-
-	    XkbSetCauseKey(&cause,keycode,KeyPress);
-
-	    /* If sticky keys were disabled, clear all locks and latches */
-	    if ((old.enabled_ctrls&XkbStickyKeysMask)&&
-		(!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
-		XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
-    	    }
-	    sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
-	    XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
-	    if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
-		XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
-	}
-    }
-    else if (filter->keycode==keycode) {
-	change= filter->priv;
-	if (change) {
-	    xkbControlsNotify 	cn;
-	    XkbSrvLedInfoPtr	sli;
-
-	    ctrls->enabled_ctrls&= ~change;
-	    if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
-		cn.keycode = keycode;
-		cn.eventType = KeyRelease;
-		cn.requestMajor = 0;
-		cn.requestMinor = 0;
-		XkbSendControlsNotify(kbd,&cn);
-	    }
-
-	    XkbSetCauseKey(&cause,keycode,KeyRelease);
-	    /* If sticky keys were disabled, clear all locks and latches */
-	    if ((old.enabled_ctrls&XkbStickyKeysMask)&&
-		(!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
-		XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
-    	    }
-	    sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
-	    XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
-	    if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
-		XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
-	}
-	filter->keycode= 0;
-	filter->active= 0;
-    }
-    return 1;
-}
-
-static int
-_XkbFilterActionMessage(XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-XkbMessageAction *	pMsg;
-DeviceIntPtr		kbd;
-
-    kbd= xkbi->device;
-    if (filter->keycode==0) {		/* initial press */
-	pMsg= &pAction->msg;
-	if ((pMsg->flags&XkbSA_MessageOnRelease)||
-	    ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
-	    filter->keycode = keycode;
-	    filter->active = 1;
-	    filter->filterOthers = 0;
-	    filter->priv = 0;
-	    filter->filter = _XkbFilterActionMessage;
-	    filter->upAction = *pAction;
-	}
-	if (pMsg->flags&XkbSA_MessageOnPress)  {
-	    xkbActionMessage	msg;
-
-	    msg.keycode= keycode;
-	    msg.press= 1;
-	    msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
-	    memcpy((char *)msg.message,
-				(char *)pMsg->message,XkbActionMessageLength);
-	    XkbSendActionMessage(kbd,&msg);
-	}
-	return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
-    }
-    else if (filter->keycode==keycode) {
-	pMsg= &filter->upAction.msg;
-	if (pMsg->flags&XkbSA_MessageOnRelease) {
-	    xkbActionMessage	msg;
-
-	    msg.keycode= keycode;
-	    msg.press= 0;
-	    msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
-	    memcpy((char *)msg.message,(char *)pMsg->message,
-						XkbActionMessageLength);
-	    XkbSendActionMessage(kbd,&msg);
-	}
-	filter->keycode= 0;
-	filter->active= 0;
-	return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
-    }
-    return 0;
-}
-
-static int
-_XkbFilterRedirectKey(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-DeviceEvent	ev;
-int		x,y;
-XkbStateRec	old;
-unsigned	mods,mask;
-xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
-ProcessInputProc backupproc;
-
-    /* never actually used uninitialised, but gcc isn't smart enough
-     * to work that out. */
-    memset(&old, 0, sizeof(old));
-    memset(&ev, 0, sizeof(ev));
-
-    if ((filter->keycode!=0)&&(filter->keycode!=keycode))
-	return 1;
-
-    GetSpritePosition(xkbi->device, &x,&y);
-    ev.header = ET_Internal;
-    ev.length = sizeof(DeviceEvent);
-    ev.time = GetTimeInMillis();
-    ev.root_x = x;
-    ev.root_y = y;
-
-    if (filter->keycode==0) {		/* initial press */
-	if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
-	    (pAction->redirect.new_key>xkbi->desc->max_key_code)) {
-	    return 1;
-	}
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 0;
-	filter->priv = 0;
-	filter->filter = _XkbFilterRedirectKey;
-	filter->upAction = *pAction;
-
-        ev.type = ET_KeyPress;
-        ev.detail.key = pAction->redirect.new_key;
-
-        mask= XkbSARedirectVModsMask(&pAction->redirect);
-        mods= XkbSARedirectVMods(&pAction->redirect);
-        if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
-        if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
-        mask|= pAction->redirect.mods_mask;
-        mods|= pAction->redirect.mods;
-
-	if ( mask || mods ) {
-	    old= xkbi->state;
-	    xkbi->state.base_mods&= ~mask;
-	    xkbi->state.base_mods|= (mods&mask);
-	    xkbi->state.latched_mods&= ~mask;
-	    xkbi->state.latched_mods|= (mods&mask);
-	    xkbi->state.locked_mods&= ~mask;
-	    xkbi->state.locked_mods|= (mods&mask);
-	    XkbComputeDerivedState(xkbi);
-	}
-
-	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
-	xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
-	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
-				     backupproc,xkbUnwrapProc);
-	
-	if ( mask || mods )
-	    xkbi->state= old;
-    }
-    else if (filter->keycode==keycode) {
-
-        ev.type = ET_KeyRelease;
-        ev.detail.key = filter->upAction.redirect.new_key;
-
-        mask= XkbSARedirectVModsMask(&filter->upAction.redirect);
-        mods= XkbSARedirectVMods(&filter->upAction.redirect);
-        if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
-        if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
-        mask|= filter->upAction.redirect.mods_mask;
-        mods|= filter->upAction.redirect.mods;
-
-	if ( mask || mods ) {
-	    old= xkbi->state;
-	    xkbi->state.base_mods&= ~mask;
-	    xkbi->state.base_mods|= (mods&mask);
-	    xkbi->state.latched_mods&= ~mask;
-	    xkbi->state.latched_mods|= (mods&mask);
-	    xkbi->state.locked_mods&= ~mask;
-	    xkbi->state.locked_mods|= (mods&mask);
-	    XkbComputeDerivedState(xkbi);
-	}
-
-	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
-	xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
-	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
-				     backupproc,xkbUnwrapProc);
-
-	if ( mask || mods )
-	    xkbi->state= old;
-
-	filter->keycode= 0;
-	filter->active= 0;
-    }
-    return 0;
-}
-
-static int
-_XkbFilterSwitchScreen(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-    DeviceIntPtr dev = xkbi->device;
-    if (dev == inputInfo.keyboard)
-        return 0;
-
-    if (filter->keycode==0) {		/* initial press */
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 0;
-	filter->filter = _XkbFilterSwitchScreen;
-	AccessXCancelRepeatKey(xkbi, keycode);
-	XkbDDXSwitchScreen(dev,keycode,pAction);
-        return 0; 
-    }
-    else if (filter->keycode==keycode) {
-	filter->active= 0;
-        return 0; 
-    }
-    return 1;
-}
-
-static int
-_XkbFilterXF86Private(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-    DeviceIntPtr dev = xkbi->device;
-    if (dev == inputInfo.keyboard)
-        return 0;
-
-    if (filter->keycode==0) {		/* initial press */
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 0;
-	filter->filter = _XkbFilterXF86Private;
-	XkbDDXPrivate(dev,keycode,pAction);
-        return 0; 
-    }
-    else if (filter->keycode==keycode) {
-	filter->active= 0;
-        return 0; 
-    }
-    return 1;
-}
-
-
-static int
-_XkbFilterDeviceBtn(	XkbSrvInfoPtr	xkbi,
-			XkbFilterPtr	filter,
-			unsigned	keycode,
-			XkbAction *	pAction)
-{
-DeviceIntPtr	dev;
-int		button;
-
-    if (xkbi->device == inputInfo.keyboard)
-        return 0;
-
-    if (filter->keycode==0) {		/* initial press */
-	_XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
-			       DixUnknownAccess, &button);
-	if (!dev || !dev->public.on)
-	    return 1;
-
-	button= pAction->devbtn.button;
-	if ((button<1)||(button>dev->button->numButtons))
-	    return 1;
-
-	filter->keycode = keycode;
-	filter->active = 1;
-	filter->filterOthers = 0;
-	filter->priv=0;
-	filter->filter = _XkbFilterDeviceBtn;
-	filter->upAction= *pAction;
-	switch (pAction->type) {
-	    case XkbSA_LockDeviceBtn:
-		if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
-		    BitIsOn(dev->button->down, button))
-		    return 0;
-		XkbFakeDeviceButton(dev,TRUE,button);
-		filter->upAction.type= XkbSA_NoAction;
-		break;
-	    case XkbSA_DeviceBtn:
-		if (pAction->devbtn.count>0) {
-		    int nClicks,i;
-		    nClicks= pAction->btn.count;
-		    for (i=0;i<nClicks;i++) {
-			XkbFakeDeviceButton(dev,TRUE,button);
-			XkbFakeDeviceButton(dev,FALSE,button);
-		    }
-		    filter->upAction.type= XkbSA_NoAction;
-		}
-		else XkbFakeDeviceButton(dev,TRUE,button);
-		break;
-	}
-    }
-    else if (filter->keycode==keycode) {
-	int	button;
-
-	filter->active= 0;
-	_XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
-			       serverClient, DixUnknownAccess, &button);
-	if (!dev || !dev->public.on)
-	    return 1;
-
-	button= filter->upAction.btn.button;
-	switch (filter->upAction.type) {
-	    case XkbSA_LockDeviceBtn:
-		if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
-		    !BitIsOn(dev->button->down, button))
-		    return 0;
-		XkbFakeDeviceButton(dev,FALSE,button);
-		break;
-	    case XkbSA_DeviceBtn:
-		XkbFakeDeviceButton(dev,FALSE,button);
-		break;
-	}
-	filter->active = 0;
-    }
-    return 0;
-}
-
-static XkbFilterPtr
-_XkbNextFreeFilter(
-	XkbSrvInfoPtr xkbi
-)
-{
-register int	i;
-
-    if (xkbi->szFilters==0) {
-	xkbi->szFilters = 4;
-	xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
-	/* 6/21/93 (ef) -- XXX! deal with allocation failure */
-    }
-    for (i=0;i<xkbi->szFilters;i++) {
-	if (!xkbi->filters[i].active) {
-	    xkbi->filters[i].keycode = 0;
-	    return &xkbi->filters[i];
-	}
-    }
-    xkbi->szFilters*=2;
-    xkbi->filters= realloc(xkbi->filters,
-                            xkbi->szFilters * sizeof(XkbFilterRec));
-    /* 6/21/93 (ef) -- XXX! deal with allocation failure */
-    memset(&xkbi->filters[xkbi->szFilters/2], 0,
-            (xkbi->szFilters/2)*sizeof(XkbFilterRec));
-    return &xkbi->filters[xkbi->szFilters/2];
-}
-
-static int
-_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
-{
-register int	i,send;
-
-    send= 1;
-    for (i=0;i<xkbi->szFilters;i++) {
-	if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter))
-	    send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction) 
-                    && send);
-    }
-    return send;
-}
-
-void
-XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event)
-{
-int		key,bit,i;
-XkbSrvInfoPtr	xkbi;
-KeyClassPtr	keyc;
-int		changed,sendEvent;
-Bool		genStateNotify;
-XkbAction	act;
-XkbFilterPtr	filter;
-Bool		keyEvent;
-Bool		pressEvent;
-ProcessInputProc backupproc;
-    
-xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
-
-    keyc= kbd->key;
-    xkbi= keyc->xkbInfo;
-    key= event->detail.key;
-    /* The state may change, so if we're not in the middle of sending a state
-     * notify, prepare for it */
-    if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
-	xkbi->prev_state = xkbi->state;
-	xkbi->flags|= _XkbStateNotifyInProgress;
-	genStateNotify= TRUE;
-    }
-    else genStateNotify= FALSE;
-
-    xkbi->clearMods = xkbi->setMods = 0;
-    xkbi->groupChange = 0;
-
-    sendEvent = 1;
-    keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
-    pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress));
-
-    if (pressEvent) {
-	if (keyEvent)	
-	    act = XkbGetKeyAction(xkbi,&xkbi->state,key);
-	else {
-	    act = XkbGetButtonAction(kbd,dev,key);
-	    key|= BTN_ACT_FLAG;
-	}
-	sendEvent = _XkbApplyFilters(xkbi,key,&act);
-	if (sendEvent) {
-	    switch (act.type) {
-		case XkbSA_SetMods:
-		case XkbSA_SetGroup:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_LatchMods:
-		case XkbSA_LatchGroup:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_LockMods:
-		case XkbSA_LockGroup:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_ISOLock:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_MovePtr:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_PtrBtn:
-		case XkbSA_LockPtrBtn:
-		case XkbSA_SetPtrDflt:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_Terminate:
-		    sendEvent= XkbDDXTerminateServer(dev,key,&act);
-		    break;
-		case XkbSA_SwitchScreen:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_SetControls:
-		case XkbSA_LockControls:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_ActionMessage:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_RedirectKey:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_DeviceBtn:
-		case XkbSA_LockDeviceBtn:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
-		    break;
-		case XkbSA_XFree86Private:
-		    filter = _XkbNextFreeFilter(xkbi);
-		    sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
-		    break;
-	    }
-	}
-    }
-    else {
-	if (!keyEvent)
-	    key|= BTN_ACT_FLAG;
-	sendEvent = _XkbApplyFilters(xkbi,key,NULL);
-    }
-
-    if (xkbi->groupChange!=0)
-	xkbi->state.base_group+= xkbi->groupChange;
-    if (xkbi->setMods) {
-	for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
-	    if (xkbi->setMods&bit) {
-		keyc->modifierKeyCount[i]++;
-		xkbi->state.base_mods|= bit;
-		xkbi->setMods&= ~bit;
-	    }
-	}
-    }
-    if (xkbi->clearMods) {
-	for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
-	    if (xkbi->clearMods&bit) {
-		keyc->modifierKeyCount[i]--;
-		if (keyc->modifierKeyCount[i]<=0) {
-		    xkbi->state.base_mods&= ~bit;
-		    keyc->modifierKeyCount[i] = 0;
-		}
-		xkbi->clearMods&= ~bit;
-	    }
-	}
-    }
-
-    if (sendEvent) {
-        DeviceIntPtr tmpdev;
-	if (keyEvent)
-            tmpdev = dev;
-        else
-            tmpdev = GetPairedDevice(dev);
-
-        UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
-        dev->public.processInputProc((InternalEvent*)event, tmpdev);
-        COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
-                                     backupproc,xkbUnwrapProc);
-    }
-    else if (keyEvent) {
-	FixKeyState(event, dev);
-    }
-
-    XkbComputeDerivedState(xkbi);
-    changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state);
-    if (genStateNotify) {
-	if (changed) {
-	    xkbStateNotify	sn;
-	    sn.keycode= key;
-	    sn.eventType= event->type;
-	    sn.requestMajor = sn.requestMinor = 0;
-	    sn.changed= changed;
-	    XkbSendStateNotify(dev,&sn);
-	}
-	xkbi->flags&= ~_XkbStateNotifyInProgress;
-    }
-    changed= XkbIndicatorsToUpdate(dev,changed,FALSE);
-    if (changed) {
-	XkbEventCauseRec	cause;
-	XkbSetCauseKey(&cause, key, event->type);
-	XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause);
-    }
-    return;
-}
-
-int
-XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
-{
-XkbSrvInfoPtr	xkbi;
-XkbFilterPtr	filter;
-XkbAction	act;
-unsigned	clear;
-
-    if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
-	xkbi = pXDev->key->xkbInfo;
-	clear= (mask&(~latches));
-	xkbi->state.latched_mods&= ~clear;
-	/* Clear any pending latch to locks.
-	 */
-	act.type = XkbSA_NoAction;
-	_XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
-	act.type = XkbSA_LatchMods;
-	act.mods.flags = 0;
-	act.mods.mask  = mask&latches;
-	filter = _XkbNextFreeFilter(xkbi);
-	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
-	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
-	return Success;
-    }
-    return BadValue;
-}
-
-int
-XkbLatchGroup(DeviceIntPtr pXDev,int group)
-{
-XkbSrvInfoPtr	xkbi;
-XkbFilterPtr	filter;
-XkbAction	act;
-
-    if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
-	xkbi = pXDev->key->xkbInfo;
-	act.type = XkbSA_LatchGroup;
-	act.group.flags = 0;
-	XkbSASetGroup(&act.group,group);
-	filter = _XkbNextFreeFilter(xkbi);
-	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
-	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
-	return Success;
-    }
-    return BadValue;
-}
-
-/***====================================================================***/
-
-void
-XkbClearAllLatchesAndLocks(	DeviceIntPtr		dev,
-				XkbSrvInfoPtr		xkbi,
-				Bool			genEv,
-				XkbEventCausePtr	cause)
-{
-XkbStateRec	os;
-xkbStateNotify	sn;
-
-    sn.changed= 0;
-    os= xkbi->state;
-    if (os.latched_mods) { /* clear all latches */
-	XkbLatchModifiers(dev,~0,0);
-	sn.changed|= XkbModifierLatchMask;
-    }
-    if (os.latched_group) {
-	XkbLatchGroup(dev,0);
-	sn.changed|= XkbGroupLatchMask;
-    }
-    if (os.locked_mods) {
-	xkbi->state.locked_mods= 0;
-	sn.changed|= XkbModifierLockMask;
-    }
-    if (os.locked_group) {
-	xkbi->state.locked_group= 0;
-	sn.changed|= XkbGroupLockMask;
-    }
-    if ( genEv && sn.changed) {
-	CARD32 	changed;
-
-	XkbComputeDerivedState(xkbi);
-	sn.keycode= 		cause->kc;
-	sn.eventType=		cause->event;
-	sn.requestMajor= 	cause->mjr;
-	sn.requestMinor= 	cause->mnr;
-	sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
-	XkbSendStateNotify(dev,&sn);
-	changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE);
-	if (changed) {
-	    XkbUpdateIndicators(dev,changed,TRUE,NULL,cause);
-	}
-    }
-    return;
-}
-
-/*
- * The event is injected into the event processing, not the EQ. Thus,
- * ensure that we restore the master after the event sequence to the
- * original set of classes. Otherwise, the master remains on the XTEST
- * classes and drops events that don't fit into the XTEST layout (e.g.
- * events with more than 2 valuators).
- *
- * FIXME: EQ injection in the processing stage is not designed for, so this
- * is a rather awkward hack. The event list returned by GetPointerEvents()
- * and friends is always prefixed with a DCE if the last _posted_ device was
- * different. For normal events, this sequence then resets the master during
- * the processing stage. Since we inject the PointerKey events in the
- * processing stage though, we need to manually reset to restore the
- * previous order, because the events already in the EQ must be sent for the
- * right device.
- * So we post-fix the event list we get from GPE with a DCE back to the
- * previous slave device.
- *
- * First one on drinking island wins!
- */
-static void
-InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask)
-{
-    ScreenPtr           pScreen;
-    EventListPtr        events;
-    int                 nevents, i;
-    DeviceIntPtr        ptr, mpointer, lastSlave = NULL;
-    Bool                saveWait;
-
-    if (IsMaster(dev)) {
-        mpointer = GetMaster(dev, MASTER_POINTER);
-        lastSlave = mpointer->lastSlave;
-        ptr = GetXTestDevice(mpointer);
-    } else if (IsFloating(dev))
-        ptr = dev;
-    else
-        return;
-
-
-    events = InitEventList(GetMaximumEventsNum() + 1);
-    OsBlockSignals();
-    pScreen = miPointerGetScreen(ptr);
-    saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
-    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);
-    OsReleaseSignals();
-
-    for (i = 0; i < nevents; i++)
-        mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
-
-    FreeEventList(events, GetMaximumEventsNum());
-
-}
-
-static void
-XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
-{
-    ValuatorMask        mask;
-    int                 gpe_flags = 0;
-
-    /* ignore attached SDs */
-    if (!IsMaster(dev) && !IsFloating(dev))
-        return;
-
-    if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
-        gpe_flags = POINTER_ABSOLUTE;
-    else
-        gpe_flags = POINTER_RELATIVE;
-
-    valuator_mask_set_range(&mask, 0, 2, (int[]){x, y});
-
-    InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
-}
-
-void
-XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
-{
-    DeviceIntPtr        ptr;
-    int                 down;
-
-    /* If dev is a slave device, and the SD is attached, do nothing. If we'd
-     * post through the attached master pointer we'd get duplicate events.
-     *
-     * if dev is a master keyboard, post through the XTEST device
-     *
-     * if dev is a floating slave, post through the device itself.
-     */
-
-    if (IsMaster(dev)) {
-        DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
-        ptr = GetXTestDevice(mpointer);
-    } else if (IsFloating(dev))
-        ptr = dev;
-    else
-        return;
-
-    down = button_is_down(ptr, button, BUTTON_PROCESSED);
-    if (press == down)
-        return;
-
-    InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
-                           button, 0, NULL);
-}
+/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be 
+used in advertising or publicity pertaining to distribution 
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability 
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL 
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "exevents.h"
+#include "eventstr.h"
+#include <xkbsrv.h>
+#include "xkb.h"
+#include <ctype.h>
+#include "mi.h"
+#include "mipointer.h"
+#include "inpututils.h"
+#define EXTENSION_EVENT_BASE 64
+
+DevPrivateKeyRec xkbDevicePrivateKeyRec;
+
+void XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button);
+static void XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y);
+
+void
+xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
+                   pointer data)
+{
+    xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
+    ProcessInputProc backupproc;
+    if(xkbPrivPtr->unwrapProc)
+	xkbPrivPtr->unwrapProc = NULL;
+
+    UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc);
+    proc(device,data);
+    COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
+				 backupproc,xkbUnwrapProc);
+}
+
+Bool
+XkbInitPrivates(void)
+{
+    return dixRegisterPrivateKey(&xkbDevicePrivateKeyRec, PRIVATE_DEVICE, sizeof(xkbDeviceInfoRec));
+}
+
+void
+XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
+{
+    xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
+    WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
+}
+
+/***====================================================================***/
+
+static XkbAction
+_FixUpAction(XkbDescPtr xkb,XkbAction *act)
+{
+static XkbAction	fake;
+
+    if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
+	fake.type = XkbSA_NoAction;
+	return fake;
+    }
+    if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
+	if (act->any.type==XkbSA_SetMods) {
+	    fake.mods.type = XkbSA_LatchMods;
+	    fake.mods.mask = act->mods.mask;
+	    if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+		 fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+	    else fake.mods.flags= XkbSA_ClearLocks;
+	    return fake;
+	}
+	if (act->any.type==XkbSA_SetGroup) {
+	    fake.group.type = XkbSA_LatchGroup;
+	    if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+		 fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+	    else fake.group.flags= XkbSA_ClearLocks;
+	    XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
+	    return fake;
+	}
+    }
+    return *act;
+}
+
+static XkbAction
+XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
+{
+int			effectiveGroup;
+int			col;
+XkbDescPtr		xkb;
+XkbKeyTypePtr		type;
+XkbAction *		pActs;
+static XkbAction 	fake;
+
+    xkb= xkbi->desc;
+    if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
+	fake.type = XkbSA_NoAction;
+	return fake;
+    }
+    pActs= XkbKeyActionsPtr(xkb,key);
+    col= 0;
+
+    effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
+    if (effectiveGroup != XkbGroup1Index)
+        col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
+
+    type= XkbKeyKeyType(xkb,key,effectiveGroup);
+    if (type->map!=NULL) {
+	register unsigned		i,mods;
+	register XkbKTMapEntryPtr	entry;
+	mods= xkbState->mods&type->mods.mask;
+	for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
+	    if ((entry->active)&&(entry->mods.mask==mods)) {
+		col+= entry->level;
+		break;
+	    }
+	}
+    }
+    if (pActs[col].any.type==XkbSA_NoAction)
+	return pActs[col];
+    fake= _FixUpAction(xkb,&pActs[col]);
+    return fake;
+}
+
+static XkbAction
+XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
+{
+XkbAction fake;
+   if ((dev->button)&&(dev->button->xkb_acts)) {
+	if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
+	    fake= _FixUpAction(kbd->key->xkbInfo->desc,
+					&dev->button->xkb_acts[button-1]);
+	    return fake;
+	}
+   }
+   fake.any.type= XkbSA_NoAction;
+   return fake;
+}
+
+/***====================================================================***/
+
+#define	SYNTHETIC_KEYCODE	1
+#define	BTN_ACT_FLAG		0x100
+
+static int
+_XkbFilterSetState(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *pAction)
+{
+    if (filter->keycode==0) {		/* initial press */
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
+	filter->priv = 0;
+	filter->filter = _XkbFilterSetState;
+	if (pAction->type==XkbSA_SetMods) {
+	    filter->upAction = *pAction;
+	    xkbi->setMods= pAction->mods.mask;
+	}
+	else {
+	    xkbi->groupChange = XkbSAGroup(&pAction->group);
+	    if (pAction->group.flags&XkbSA_GroupAbsolute)
+		xkbi->groupChange-= xkbi->state.base_group;
+	    filter->upAction= *pAction;
+	    XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+	}
+    }
+    else if (filter->keycode==keycode) {
+	if (filter->upAction.type==XkbSA_SetMods) {
+	    xkbi->clearMods = filter->upAction.mods.mask;
+	    if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
+		xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
+	    }
+	}
+	else {
+	    if (filter->upAction.group.flags&XkbSA_ClearLocks) {
+		xkbi->state.locked_group = 0;
+	    }
+	    xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+	}
+	filter->active = 0;
+    }
+    else {
+	filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
+	filter->filterOthers = 0;
+    }
+    return 1;
+}
+
+#define	LATCH_KEY_DOWN	1
+#define	LATCH_PENDING	2
+#define	NO_LATCH	3
+
+static int
+_XkbFilterLatchState(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+
+    if (filter->keycode==0) {			/* initial press */
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 1;
+	filter->priv = LATCH_KEY_DOWN;
+	filter->filter = _XkbFilterLatchState;
+	if (pAction->type==XkbSA_LatchMods) {
+	    filter->upAction = *pAction;
+	    xkbi->setMods = pAction->mods.mask;
+	}
+	else {
+	    xkbi->groupChange = XkbSAGroup(&pAction->group);
+	    if (pAction->group.flags&XkbSA_GroupAbsolute)
+		 xkbi->groupChange-= xkbi->state.base_group;
+	    filter->upAction= *pAction;
+	    XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+	}
+    }
+    else if ( pAction && (filter->priv==LATCH_PENDING) ) {
+	if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
+	    filter->active = 0;
+	    if (filter->upAction.type==XkbSA_LatchMods)
+		 xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+	    else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+	}
+	else if ((pAction->type==filter->upAction.type)&&
+		 (pAction->mods.flags==filter->upAction.mods.flags)&&
+		 (pAction->mods.mask==filter->upAction.mods.mask)) {
+	    if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
+		XkbControlsPtr ctrls= xkbi->desc->ctrls;
+		if (filter->upAction.type==XkbSA_LatchMods)
+		     pAction->mods.type= XkbSA_LockMods;
+		else pAction->group.type= XkbSA_LockGroup;
+		if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
+		    		(ctrls->enabled_ctrls&XkbStickyKeysMask)) {
+		    XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
+						XkbStickyKeysMask);
+		}
+	    }
+	    else {
+		if (filter->upAction.type==XkbSA_LatchMods)
+		     pAction->mods.type= XkbSA_SetMods;
+		else pAction->group.type= XkbSA_SetGroup;
+	    }
+	    if (filter->upAction.type==XkbSA_LatchMods)
+		 xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+	    else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+	    filter->active = 0;
+	}
+    }
+    else if (filter->keycode==keycode) {	/* release */
+	XkbControlsPtr	ctrls= xkbi->desc->ctrls;
+	int		needBeep;
+	int		beepType= _BEEP_NONE;
+
+	needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
+			XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
+	if (filter->upAction.type==XkbSA_LatchMods) {
+	    xkbi->clearMods = filter->upAction.mods.mask;
+	    if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
+		 (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
+		xkbi->state.locked_mods&= ~xkbi->clearMods;
+		filter->priv= NO_LATCH;
+		beepType= _BEEP_STICKY_UNLOCK;
+	    }
+	}
+	else {
+	    xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+	    if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
+						(xkbi->state.locked_group)) {
+		xkbi->state.locked_group = 0;
+		filter->priv = NO_LATCH;
+		beepType= _BEEP_STICKY_UNLOCK;
+	    }
+	}
+	if (filter->priv==NO_LATCH) {
+	    filter->active= 0;
+	}
+	else {
+	    filter->priv= LATCH_PENDING;
+	    if (filter->upAction.type==XkbSA_LatchMods) {
+		xkbi->state.latched_mods |= filter->upAction.mods.mask;
+		needBeep = xkbi->state.latched_mods ? needBeep : 0;
+		xkbi->state.latched_mods |= filter->upAction.mods.mask;
+	    }
+	    else {
+		xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
+	    }
+	    if (needBeep && (beepType==_BEEP_NONE))
+		beepType= _BEEP_STICKY_LATCH;
+	}
+	if (needBeep && (beepType!=_BEEP_NONE))
+	    XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
+    }
+    else if (filter->priv==LATCH_KEY_DOWN) {
+	filter->priv= NO_LATCH;
+	filter->filterOthers = 0;
+    }
+    return 1;
+}
+
+static int
+_XkbFilterLockState(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+    if (pAction&&(pAction->type==XkbSA_LockGroup)) {
+	if (pAction->group.flags&XkbSA_GroupAbsolute)
+	     xkbi->state.locked_group= XkbSAGroup(&pAction->group);
+	else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
+	return 1;
+    }
+    if (filter->keycode==0) {		/* initial press */
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 0;
+	filter->priv = 0;
+	filter->filter = _XkbFilterLockState;
+	filter->upAction = *pAction;
+	xkbi->state.locked_mods^= pAction->mods.mask;
+	xkbi->setMods = pAction->mods.mask;
+    }
+    else if (filter->keycode==keycode) {
+	filter->active = 0;
+	xkbi->clearMods = filter->upAction.mods.mask;
+    }
+    return 1;
+}
+
+#define	ISO_KEY_DOWN		0
+#define	NO_ISO_LOCK		1
+
+static int
+_XkbFilterISOLock(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+
+    if (filter->keycode==0) {		/* initial press */
+	CARD8	flags= pAction->iso.flags;
+
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 1;
+	filter->priv = ISO_KEY_DOWN;
+	filter->upAction = *pAction;
+	filter->filter = _XkbFilterISOLock;
+	if (flags&XkbSA_ISODfltIsGroup) {
+	    xkbi->groupChange = XkbSAGroup(&pAction->iso);
+	    xkbi->setMods = 0;
+	}
+	else {
+	    xkbi->setMods = pAction->iso.mask;
+	    xkbi->groupChange = 0;
+	}
+	if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
+	    filter->priv= NO_ISO_LOCK;
+	    xkbi->state.locked_mods^= xkbi->state.base_mods;
+	}
+	if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
+/* 6/22/93 (ef) -- lock groups if group key is down first */
+	}
+	if (!(flags&XkbSA_ISONoAffectPtr)) {
+/* 6/22/93 (ef) -- lock mouse buttons if they're down */
+	}
+    }
+    else if (filter->keycode==keycode) {
+	CARD8	flags= filter->upAction.iso.flags;
+
+	if (flags&XkbSA_ISODfltIsGroup) {
+	    xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
+	    xkbi->clearMods = 0;
+	    if (filter->priv==ISO_KEY_DOWN)
+		xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
+	}
+	else {
+	    xkbi->clearMods= filter->upAction.iso.mask;
+	    xkbi->groupChange= 0;
+	    if (filter->priv==ISO_KEY_DOWN)
+		xkbi->state.locked_mods^= filter->upAction.iso.mask;
+	}
+	filter->active = 0;
+    }
+    else if (pAction) {
+	CARD8	flags= filter->upAction.iso.flags;
+
+	switch (pAction->type) {
+	    case XkbSA_SetMods: case XkbSA_LatchMods:
+		if (!(flags&XkbSA_ISONoAffectMods)) {
+		    pAction->type= XkbSA_LockMods;
+		    filter->priv= NO_ISO_LOCK;
+		}
+		break;
+	    case XkbSA_SetGroup: case XkbSA_LatchGroup:
+		if (!(flags&XkbSA_ISONoAffectGroup)) {
+		    pAction->type= XkbSA_LockGroup;
+		    filter->priv= NO_ISO_LOCK;
+		}
+		break;
+	    case XkbSA_PtrBtn:
+		if (!(flags&XkbSA_ISONoAffectPtr)) {
+		     pAction->type= XkbSA_LockPtrBtn;
+		     filter->priv= NO_ISO_LOCK;
+		}
+		break;
+	    case XkbSA_SetControls:
+		if (!(flags&XkbSA_ISONoAffectCtrls)) {
+		    pAction->type= XkbSA_LockControls;
+		    filter->priv= NO_ISO_LOCK;
+		}
+		break;
+	}
+    }
+    return 1;
+}
+
+
+static CARD32
+_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+{
+XkbSrvInfoPtr	xkbi= (XkbSrvInfoPtr)arg;
+XkbControlsPtr	ctrls= xkbi->desc->ctrls;
+int		dx,dy;
+
+    if (xkbi->mouseKey==0)
+	return 0;
+
+    if (xkbi->mouseKeysAccel) {
+	if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
+	    double step;
+	    xkbi->mouseKeysCounter++;
+	    step= xkbi->mouseKeysCurveFactor*
+		 pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
+	    if (xkbi->mouseKeysDX<0)
+		 dx= floor( ((double)xkbi->mouseKeysDX)*step );
+	    else dx=  ceil( ((double)xkbi->mouseKeysDX)*step );
+	    if (xkbi->mouseKeysDY<0)
+		 dy= floor( ((double)xkbi->mouseKeysDY)*step );
+	    else dy=  ceil( ((double)xkbi->mouseKeysDY)*step );
+	}
+	else {
+	    dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
+	    dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
+	}
+	if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
+	    dx= xkbi->mouseKeysDX;
+	if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
+	    dy= xkbi->mouseKeysDY;
+    }
+    else {
+	dx= xkbi->mouseKeysDX;
+	dy= xkbi->mouseKeysDY;
+    }
+    XkbFakePointerMotion(xkbi->device, xkbi->mouseKeysFlags,dx,dy);
+    return xkbi->desc->ctrls->mk_interval;
+}
+
+static int
+_XkbFilterPointerMove(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+int	x,y;
+Bool	accel;
+
+    if (filter->keycode==0) {		/* initial press */
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 0;
+	filter->priv=0;
+	filter->filter = _XkbFilterPointerMove;
+	filter->upAction= *pAction;
+	xkbi->mouseKeysCounter= 0;
+	xkbi->mouseKey= keycode;
+	accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
+	x= XkbPtrActionX(&pAction->ptr);
+	y= XkbPtrActionY(&pAction->ptr);
+	XkbFakePointerMotion(xkbi->device, pAction->ptr.flags,x,y);
+	AccessXCancelRepeatKey(xkbi,keycode);
+	xkbi->mouseKeysAccel= accel&&
+		(xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
+	xkbi->mouseKeysFlags= pAction->ptr.flags;
+	xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
+	xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
+	xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
+				xkbi->desc->ctrls->mk_delay,
+				_XkbPtrAccelExpire,(pointer)xkbi);
+    }
+    else if (filter->keycode==keycode) {
+	filter->active = 0;
+	if (xkbi->mouseKey==keycode) {
+	    xkbi->mouseKey= 0;
+	    xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
+							NULL, NULL);
+	}
+    }
+    return 0;
+}
+
+static int
+_XkbFilterPointerBtn(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+    if (filter->keycode==0) {		/* initial press */
+	int	button= pAction->btn.button;
+
+	if (button==XkbSA_UseDfltButton)
+	    button = xkbi->desc->ctrls->mk_dflt_btn;
+
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 0;
+	filter->priv=0;
+	filter->filter = _XkbFilterPointerBtn;
+	filter->upAction= *pAction;
+	filter->upAction.btn.button= button;
+	switch (pAction->type) {
+	    case XkbSA_LockPtrBtn:
+		if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
+			((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
+		    xkbi->lockedPtrButtons|= (1<<button);
+		    AccessXCancelRepeatKey(xkbi,keycode);
+		    XkbFakeDeviceButton(xkbi->device, 1, button);
+		    filter->upAction.type= XkbSA_NoAction;
+		}
+		break;
+	    case XkbSA_PtrBtn:
+		{
+		    register int i,nClicks;
+		    AccessXCancelRepeatKey(xkbi,keycode);
+		    if (pAction->btn.count>0) {
+			nClicks= pAction->btn.count;
+			for (i=0;i<nClicks;i++) {
+			    XkbFakeDeviceButton(xkbi->device, 1, button);
+			    XkbFakeDeviceButton(xkbi->device, 0, button);
+			}
+			filter->upAction.type= XkbSA_NoAction;
+		    }
+		    else XkbFakeDeviceButton(xkbi->device, 1, button);
+		}
+		break;
+	    case XkbSA_SetPtrDflt:
+		{
+		    XkbControlsPtr	ctrls= xkbi->desc->ctrls;
+		    XkbControlsRec	old;
+		    xkbControlsNotify	cn;
+
+		    old= *ctrls;
+		    AccessXCancelRepeatKey(xkbi,keycode);
+		    switch (pAction->dflt.affect) {
+			case XkbSA_AffectDfltBtn:
+			    if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
+				ctrls->mk_dflt_btn= 
+					XkbSAPtrDfltValue(&pAction->dflt);
+			    else {
+				ctrls->mk_dflt_btn+=
+					XkbSAPtrDfltValue(&pAction->dflt);
+				if (ctrls->mk_dflt_btn>5)
+				    ctrls->mk_dflt_btn= 5;
+				else if (ctrls->mk_dflt_btn<1)
+				    ctrls->mk_dflt_btn= 1;
+			    }
+			    break;
+			default:
+			    ErrorF(
+		"Attempt to change unknown pointer default (%d) ignored\n",
+							pAction->dflt.affect);
+			    break;
+		    }
+		    if (XkbComputeControlsNotify(xkbi->device,
+						&old,xkbi->desc->ctrls,
+						&cn,FALSE)) {
+			cn.keycode = keycode;
+                        /* XXX: what about DeviceKeyPress? */
+			cn.eventType = KeyPress;
+			cn.requestMajor = 0;
+			cn.requestMinor = 0;
+			XkbSendControlsNotify(xkbi->device,&cn);
+		    }
+		}
+		break;
+	}
+    }
+    else if (filter->keycode==keycode) {
+	int	button= filter->upAction.btn.button;
+
+	switch (filter->upAction.type) {
+	    case XkbSA_LockPtrBtn:
+		if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
+				((xkbi->lockedPtrButtons&(1<<button))==0)) {
+		    break;
+		}
+		xkbi->lockedPtrButtons&= ~(1<<button);
+
+		if (IsMaster(xkbi->device))
+		{
+		    XkbMergeLockedPtrBtns(xkbi->device);
+                    /* One SD still has lock set, don't post event */
+		    if ((xkbi->lockedPtrButtons & (1 << button)) != 0)
+			break;
+		}
+
+		/* fallthrough */
+	    case XkbSA_PtrBtn:
+		XkbFakeDeviceButton(xkbi->device, 0, button);
+		break;
+	}
+	filter->active = 0;
+    }
+    return 0;
+}
+
+static int
+_XkbFilterControls(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+XkbControlsRec		old;
+XkbControlsPtr		ctrls;
+DeviceIntPtr		kbd;
+unsigned int		change;
+XkbEventCauseRec	cause;
+
+    kbd= xkbi->device;
+    ctrls= xkbi->desc->ctrls;
+    old= *ctrls;
+    if (filter->keycode==0) {		/* initial press */
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 0;
+	change= XkbActionCtrls(&pAction->ctrls);
+	filter->priv = change;
+	filter->filter = _XkbFilterControls;
+	filter->upAction = *pAction;
+
+	if (pAction->type==XkbSA_LockControls) {
+	    filter->priv= (ctrls->enabled_ctrls&change);
+	    change&= ~ctrls->enabled_ctrls;
+	}
+
+	if (change) {
+	    xkbControlsNotify	cn;
+	    XkbSrvLedInfoPtr	sli;
+
+	    ctrls->enabled_ctrls|= change;
+	    if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
+		cn.keycode = keycode;
+                /* XXX: what about DeviceKeyPress? */
+		cn.eventType = KeyPress;
+		cn.requestMajor = 0;
+		cn.requestMinor = 0;
+		XkbSendControlsNotify(kbd,&cn);
+	    }
+
+	    XkbSetCauseKey(&cause,keycode,KeyPress);
+
+	    /* If sticky keys were disabled, clear all locks and latches */
+	    if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+		(!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+		XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
+    	    }
+	    sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+	    XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
+	    if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+		XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
+	}
+    }
+    else if (filter->keycode==keycode) {
+	change= filter->priv;
+	if (change) {
+	    xkbControlsNotify 	cn;
+	    XkbSrvLedInfoPtr	sli;
+
+	    ctrls->enabled_ctrls&= ~change;
+	    if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
+		cn.keycode = keycode;
+		cn.eventType = KeyRelease;
+		cn.requestMajor = 0;
+		cn.requestMinor = 0;
+		XkbSendControlsNotify(kbd,&cn);
+	    }
+
+	    XkbSetCauseKey(&cause,keycode,KeyRelease);
+	    /* If sticky keys were disabled, clear all locks and latches */
+	    if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+		(!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+		XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
+    	    }
+	    sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+	    XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
+	    if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+		XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
+	}
+	filter->keycode= 0;
+	filter->active= 0;
+    }
+    return 1;
+}
+
+static int
+_XkbFilterActionMessage(XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+XkbMessageAction *	pMsg;
+DeviceIntPtr		kbd;
+
+    kbd= xkbi->device;
+    if (filter->keycode==0) {		/* initial press */
+	pMsg= &pAction->msg;
+	if ((pMsg->flags&XkbSA_MessageOnRelease)||
+	    ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
+	    filter->keycode = keycode;
+	    filter->active = 1;
+	    filter->filterOthers = 0;
+	    filter->priv = 0;
+	    filter->filter = _XkbFilterActionMessage;
+	    filter->upAction = *pAction;
+	}
+	if (pMsg->flags&XkbSA_MessageOnPress)  {
+	    xkbActionMessage	msg;
+
+	    msg.keycode= keycode;
+	    msg.press= 1;
+	    msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+	    memcpy((char *)msg.message,
+				(char *)pMsg->message,XkbActionMessageLength);
+	    XkbSendActionMessage(kbd,&msg);
+	}
+	return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
+    }
+    else if (filter->keycode==keycode) {
+	pMsg= &filter->upAction.msg;
+	if (pMsg->flags&XkbSA_MessageOnRelease) {
+	    xkbActionMessage	msg;
+
+	    msg.keycode= keycode;
+	    msg.press= 0;
+	    msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+	    memcpy((char *)msg.message,(char *)pMsg->message,
+						XkbActionMessageLength);
+	    XkbSendActionMessage(kbd,&msg);
+	}
+	filter->keycode= 0;
+	filter->active= 0;
+	return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+    }
+    return 0;
+}
+
+static int
+_XkbFilterRedirectKey(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+DeviceEvent	ev;
+int		x,y;
+XkbStateRec	old;
+unsigned	mods,mask;
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
+ProcessInputProc backupproc;
+
+    /* never actually used uninitialised, but gcc isn't smart enough
+     * to work that out. */
+    memset(&old, 0, sizeof(old));
+    memset(&ev, 0, sizeof(ev));
+
+    if ((filter->keycode!=0)&&(filter->keycode!=keycode))
+	return 1;
+
+    GetSpritePosition(xkbi->device, &x,&y);
+    ev.header = ET_Internal;
+    ev.length = sizeof(DeviceEvent);
+    ev.time = GetTimeInMillis();
+    ev.root_x = x;
+    ev.root_y = y;
+
+    if (filter->keycode==0) {		/* initial press */
+	if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
+	    (pAction->redirect.new_key>xkbi->desc->max_key_code)) {
+	    return 1;
+	}
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 0;
+	filter->priv = 0;
+	filter->filter = _XkbFilterRedirectKey;
+	filter->upAction = *pAction;
+
+        ev.type = ET_KeyPress;
+        ev.detail.key = pAction->redirect.new_key;
+
+        mask= XkbSARedirectVModsMask(&pAction->redirect);
+        mods= XkbSARedirectVMods(&pAction->redirect);
+        if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
+        if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
+        mask|= pAction->redirect.mods_mask;
+        mods|= pAction->redirect.mods;
+
+	if ( mask || mods ) {
+	    old= xkbi->state;
+	    xkbi->state.base_mods&= ~mask;
+	    xkbi->state.base_mods|= (mods&mask);
+	    xkbi->state.latched_mods&= ~mask;
+	    xkbi->state.latched_mods|= (mods&mask);
+	    xkbi->state.locked_mods&= ~mask;
+	    xkbi->state.locked_mods|= (mods&mask);
+	    XkbComputeDerivedState(xkbi);
+	}
+
+	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
+	xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
+	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+				     backupproc,xkbUnwrapProc);
+	
+	if ( mask || mods )
+	    xkbi->state= old;
+    }
+    else if (filter->keycode==keycode) {
+
+        ev.type = ET_KeyRelease;
+        ev.detail.key = filter->upAction.redirect.new_key;
+
+        mask= XkbSARedirectVModsMask(&filter->upAction.redirect);
+        mods= XkbSARedirectVMods(&filter->upAction.redirect);
+        if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
+        if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
+        mask|= filter->upAction.redirect.mods_mask;
+        mods|= filter->upAction.redirect.mods;
+
+	if ( mask || mods ) {
+	    old= xkbi->state;
+	    xkbi->state.base_mods&= ~mask;
+	    xkbi->state.base_mods|= (mods&mask);
+	    xkbi->state.latched_mods&= ~mask;
+	    xkbi->state.latched_mods|= (mods&mask);
+	    xkbi->state.locked_mods&= ~mask;
+	    xkbi->state.locked_mods|= (mods&mask);
+	    XkbComputeDerivedState(xkbi);
+	}
+
+	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
+	xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
+	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+				     backupproc,xkbUnwrapProc);
+
+	if ( mask || mods )
+	    xkbi->state= old;
+
+	filter->keycode= 0;
+	filter->active= 0;
+    }
+    return 0;
+}
+
+static int
+_XkbFilterSwitchScreen(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+    DeviceIntPtr dev = xkbi->device;
+    if (dev == inputInfo.keyboard)
+        return 0;
+
+    if (filter->keycode==0) {		/* initial press */
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 0;
+	filter->filter = _XkbFilterSwitchScreen;
+	AccessXCancelRepeatKey(xkbi, keycode);
+	XkbDDXSwitchScreen(dev,keycode,pAction);
+        return 0; 
+    }
+    else if (filter->keycode==keycode) {
+	filter->active= 0;
+        return 0; 
+    }
+    return 1;
+}
+
+static int
+_XkbFilterXF86Private(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+    DeviceIntPtr dev = xkbi->device;
+    if (dev == inputInfo.keyboard)
+        return 0;
+
+    if (filter->keycode==0) {		/* initial press */
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 0;
+	filter->filter = _XkbFilterXF86Private;
+	XkbDDXPrivate(dev,keycode,pAction);
+        return 0; 
+    }
+    else if (filter->keycode==keycode) {
+	filter->active= 0;
+        return 0; 
+    }
+    return 1;
+}
+
+
+static int
+_XkbFilterDeviceBtn(	XkbSrvInfoPtr	xkbi,
+			XkbFilterPtr	filter,
+			unsigned	keycode,
+			XkbAction *	pAction)
+{
+DeviceIntPtr	dev;
+int		button;
+
+    if (xkbi->device == inputInfo.keyboard)
+        return 0;
+
+    if (filter->keycode==0) {		/* initial press */
+	_XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
+			       DixUnknownAccess, &button);
+	if (!dev || !dev->public.on)
+	    return 1;
+
+	button= pAction->devbtn.button;
+	if ((button<1)||(button>dev->button->numButtons))
+	    return 1;
+
+	filter->keycode = keycode;
+	filter->active = 1;
+	filter->filterOthers = 0;
+	filter->priv=0;
+	filter->filter = _XkbFilterDeviceBtn;
+	filter->upAction= *pAction;
+	switch (pAction->type) {
+	    case XkbSA_LockDeviceBtn:
+		if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
+		    BitIsOn(dev->button->down, button))
+		    return 0;
+		XkbFakeDeviceButton(dev,TRUE,button);
+		filter->upAction.type= XkbSA_NoAction;
+		break;
+	    case XkbSA_DeviceBtn:
+		if (pAction->devbtn.count>0) {
+		    int nClicks,i;
+		    nClicks= pAction->btn.count;
+		    for (i=0;i<nClicks;i++) {
+			XkbFakeDeviceButton(dev,TRUE,button);
+			XkbFakeDeviceButton(dev,FALSE,button);
+		    }
+		    filter->upAction.type= XkbSA_NoAction;
+		}
+		else XkbFakeDeviceButton(dev,TRUE,button);
+		break;
+	}
+    }
+    else if (filter->keycode==keycode) {
+	int	button;
+
+	filter->active= 0;
+	_XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
+			       serverClient, DixUnknownAccess, &button);
+	if (!dev || !dev->public.on)
+	    return 1;
+
+	button= filter->upAction.btn.button;
+	switch (filter->upAction.type) {
+	    case XkbSA_LockDeviceBtn:
+		if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
+		    !BitIsOn(dev->button->down, button))
+		    return 0;
+		XkbFakeDeviceButton(dev,FALSE,button);
+		break;
+	    case XkbSA_DeviceBtn:
+		XkbFakeDeviceButton(dev,FALSE,button);
+		break;
+	}
+	filter->active = 0;
+    }
+    return 0;
+}
+
+static XkbFilterPtr
+_XkbNextFreeFilter(
+	XkbSrvInfoPtr xkbi
+)
+{
+register int	i;
+
+    if (xkbi->szFilters==0) {
+	xkbi->szFilters = 4;
+	xkbi->filters = calloc(xkbi->szFilters, sizeof(XkbFilterRec));
+	/* 6/21/93 (ef) -- XXX! deal with allocation failure */
+    }
+    for (i=0;i<xkbi->szFilters;i++) {
+	if (!xkbi->filters[i].active) {
+	    xkbi->filters[i].keycode = 0;
+	    return &xkbi->filters[i];
+	}
+    }
+    xkbi->szFilters*=2;
+    xkbi->filters= realloc(xkbi->filters,
+                            xkbi->szFilters * sizeof(XkbFilterRec));
+    /* 6/21/93 (ef) -- XXX! deal with allocation failure */
+    memset(&xkbi->filters[xkbi->szFilters/2], 0,
+            (xkbi->szFilters/2)*sizeof(XkbFilterRec));
+    return &xkbi->filters[xkbi->szFilters/2];
+}
+
+static int
+_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
+{
+register int	i,send;
+
+    send= 1;
+    for (i=0;i<xkbi->szFilters;i++) {
+	if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter))
+	    send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction) 
+                    && send);
+    }
+    return send;
+}
+
+void
+XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event)
+{
+int		key,bit,i;
+XkbSrvInfoPtr	xkbi;
+KeyClassPtr	keyc;
+int		changed,sendEvent;
+Bool		genStateNotify;
+XkbAction	act;
+XkbFilterPtr	filter;
+Bool		keyEvent;
+Bool		pressEvent;
+ProcessInputProc backupproc;
+    
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
+
+    keyc= kbd->key;
+    xkbi= keyc->xkbInfo;
+    key= event->detail.key;
+    /* The state may change, so if we're not in the middle of sending a state
+     * notify, prepare for it */
+    if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
+	xkbi->prev_state = xkbi->state;
+	xkbi->flags|= _XkbStateNotifyInProgress;
+	genStateNotify= TRUE;
+    }
+    else genStateNotify= FALSE;
+
+    xkbi->clearMods = xkbi->setMods = 0;
+    xkbi->groupChange = 0;
+
+    sendEvent = 1;
+    keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
+    pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress));
+
+    if (pressEvent) {
+	if (keyEvent)	
+	    act = XkbGetKeyAction(xkbi,&xkbi->state,key);
+	else {
+	    act = XkbGetButtonAction(kbd,dev,key);
+	    key|= BTN_ACT_FLAG;
+	}
+	sendEvent = _XkbApplyFilters(xkbi,key,&act);
+	if (sendEvent) {
+	    switch (act.type) {
+		case XkbSA_SetMods:
+		case XkbSA_SetGroup:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_LatchMods:
+		case XkbSA_LatchGroup:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_LockMods:
+		case XkbSA_LockGroup:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_ISOLock:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_MovePtr:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_PtrBtn:
+		case XkbSA_LockPtrBtn:
+		case XkbSA_SetPtrDflt:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_Terminate:
+		    sendEvent= XkbDDXTerminateServer(dev,key,&act);
+		    break;
+		case XkbSA_SwitchScreen:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_SetControls:
+		case XkbSA_LockControls:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_ActionMessage:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_RedirectKey:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_DeviceBtn:
+		case XkbSA_LockDeviceBtn:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
+		    break;
+		case XkbSA_XFree86Private:
+		    filter = _XkbNextFreeFilter(xkbi);
+		    sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
+		    break;
+	    }
+	}
+    }
+    else {
+	if (!keyEvent)
+	    key|= BTN_ACT_FLAG;
+	sendEvent = _XkbApplyFilters(xkbi,key,NULL);
+    }
+
+    if (xkbi->groupChange!=0)
+	xkbi->state.base_group+= xkbi->groupChange;
+    if (xkbi->setMods) {
+	for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
+	    if (xkbi->setMods&bit) {
+		keyc->modifierKeyCount[i]++;
+		xkbi->state.base_mods|= bit;
+		xkbi->setMods&= ~bit;
+	    }
+	}
+    }
+    if (xkbi->clearMods) {
+	for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
+	    if (xkbi->clearMods&bit) {
+		keyc->modifierKeyCount[i]--;
+		if (keyc->modifierKeyCount[i]<=0) {
+		    xkbi->state.base_mods&= ~bit;
+		    keyc->modifierKeyCount[i] = 0;
+		}
+		xkbi->clearMods&= ~bit;
+	    }
+	}
+    }
+
+    if (sendEvent) {
+        DeviceIntPtr tmpdev;
+	if (keyEvent)
+            tmpdev = dev;
+        else
+            tmpdev = GetPairedDevice(dev);
+
+        UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
+        dev->public.processInputProc((InternalEvent*)event, tmpdev);
+        COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
+                                     backupproc,xkbUnwrapProc);
+    }
+    else if (keyEvent) {
+	FixKeyState(event, dev);
+    }
+
+    XkbComputeDerivedState(xkbi);
+    changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state);
+    if (genStateNotify) {
+	if (changed) {
+	    xkbStateNotify	sn;
+	    sn.keycode= key;
+	    sn.eventType= event->type;
+	    sn.requestMajor = sn.requestMinor = 0;
+	    sn.changed= changed;
+	    XkbSendStateNotify(dev,&sn);
+	}
+	xkbi->flags&= ~_XkbStateNotifyInProgress;
+    }
+    changed= XkbIndicatorsToUpdate(dev,changed,FALSE);
+    if (changed) {
+	XkbEventCauseRec	cause;
+	XkbSetCauseKey(&cause, key, event->type);
+	XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause);
+    }
+    return;
+}
+
+int
+XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
+{
+XkbSrvInfoPtr	xkbi;
+XkbFilterPtr	filter;
+XkbAction	act;
+unsigned	clear;
+
+    if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+	xkbi = pXDev->key->xkbInfo;
+	clear= (mask&(~latches));
+	xkbi->state.latched_mods&= ~clear;
+	/* Clear any pending latch to locks.
+	 */
+	act.type = XkbSA_NoAction;
+	_XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
+	act.type = XkbSA_LatchMods;
+	act.mods.flags = 0;
+	act.mods.mask  = mask&latches;
+	filter = _XkbNextFreeFilter(xkbi);
+	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+	return Success;
+    }
+    return BadValue;
+}
+
+int
+XkbLatchGroup(DeviceIntPtr pXDev,int group)
+{
+XkbSrvInfoPtr	xkbi;
+XkbFilterPtr	filter;
+XkbAction	act;
+
+    if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+	xkbi = pXDev->key->xkbInfo;
+	act.type = XkbSA_LatchGroup;
+	act.group.flags = 0;
+	XkbSASetGroup(&act.group,group);
+	filter = _XkbNextFreeFilter(xkbi);
+	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+	_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+	return Success;
+    }
+    return BadValue;
+}
+
+/***====================================================================***/
+
+void
+XkbClearAllLatchesAndLocks(	DeviceIntPtr		dev,
+				XkbSrvInfoPtr		xkbi,
+				Bool			genEv,
+				XkbEventCausePtr	cause)
+{
+XkbStateRec	os;
+xkbStateNotify	sn;
+
+    sn.changed= 0;
+    os= xkbi->state;
+    if (os.latched_mods) { /* clear all latches */
+	XkbLatchModifiers(dev,~0,0);
+	sn.changed|= XkbModifierLatchMask;
+    }
+    if (os.latched_group) {
+	XkbLatchGroup(dev,0);
+	sn.changed|= XkbGroupLatchMask;
+    }
+    if (os.locked_mods) {
+	xkbi->state.locked_mods= 0;
+	sn.changed|= XkbModifierLockMask;
+    }
+    if (os.locked_group) {
+	xkbi->state.locked_group= 0;
+	sn.changed|= XkbGroupLockMask;
+    }
+    if ( genEv && sn.changed) {
+	CARD32 	changed;
+
+	XkbComputeDerivedState(xkbi);
+	sn.keycode= 		cause->kc;
+	sn.eventType=		cause->event;
+	sn.requestMajor= 	cause->mjr;
+	sn.requestMinor= 	cause->mnr;
+	sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
+	XkbSendStateNotify(dev,&sn);
+	changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE);
+	if (changed) {
+	    XkbUpdateIndicators(dev,changed,TRUE,NULL,cause);
+	}
+    }
+    return;
+}
+
+/*
+ * The event is injected into the event processing, not the EQ. Thus,
+ * ensure that we restore the master after the event sequence to the
+ * original set of classes. Otherwise, the master remains on the XTEST
+ * classes and drops events that don't fit into the XTEST layout (e.g.
+ * events with more than 2 valuators).
+ *
+ * FIXME: EQ injection in the processing stage is not designed for, so this
+ * is a rather awkward hack. The event list returned by GetPointerEvents()
+ * and friends is always prefixed with a DCE if the last _posted_ device was
+ * different. For normal events, this sequence then resets the master during
+ * the processing stage. Since we inject the PointerKey events in the
+ * processing stage though, we need to manually reset to restore the
+ * previous order, because the events already in the EQ must be sent for the
+ * right device.
+ * So we post-fix the event list we get from GPE with a DCE back to the
+ * previous slave device.
+ *
+ * First one on drinking island wins!
+ */
+static void
+InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask)
+{
+    ScreenPtr           pScreen;
+    EventListPtr        events;
+    int                 nevents, i;
+    DeviceIntPtr        ptr, mpointer, lastSlave = NULL;
+    Bool                saveWait;
+
+    if (IsMaster(dev)) {
+        mpointer = GetMaster(dev, MASTER_POINTER);
+        lastSlave = mpointer->lastSlave;
+        ptr = GetXTestDevice(mpointer);
+    } else if (IsFloating(dev))
+        ptr = dev;
+    else
+        return;
+
+
+    events = InitEventList(GetMaximumEventsNum() + 1);
+    OsBlockSignals();
+    pScreen = miPointerGetScreen(ptr);
+    saveWait = miPointerSetWaitForUpdate(pScreen, FALSE);
+    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);
+    OsReleaseSignals();
+
+    for (i = 0; i < nevents; i++)
+        mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
+
+    FreeEventList(events, GetMaximumEventsNum());
+
+}
+
+static void
+XkbFakePointerMotion(DeviceIntPtr dev, unsigned flags,int x,int y)
+{
+    ValuatorMask        mask;
+    int                 gpe_flags = 0;
+
+    /* ignore attached SDs */
+    if (!IsMaster(dev) && !IsFloating(dev))
+        return;
+
+    if (flags & XkbSA_MoveAbsoluteX || flags & XkbSA_MoveAbsoluteY)
+        gpe_flags = POINTER_ABSOLUTE;
+    else
+        gpe_flags = POINTER_RELATIVE;
+
+    valuator_mask_set_range(&mask, 0, 2, (int[]){x, y});
+
+    InjectPointerKeyEvents(dev, MotionNotify, 0, gpe_flags, &mask);
+}
+
+void
+XkbFakeDeviceButton(DeviceIntPtr dev,Bool press,int button)
+{
+    DeviceIntPtr        ptr;
+    int                 down;
+
+    /* If dev is a slave device, and the SD is attached, do nothing. If we'd
+     * post through the attached master pointer we'd get duplicate events.
+     *
+     * if dev is a master keyboard, post through the XTEST device
+     *
+     * if dev is a floating slave, post through the device itself.
+     */
+
+    if (IsMaster(dev)) {
+        DeviceIntPtr mpointer = GetMaster(dev, MASTER_POINTER);
+        ptr = GetXTestDevice(mpointer);
+    } else if (IsFloating(dev))
+        ptr = dev;
+    else
+        return;
+
+    down = button_is_down(ptr, button, BUTTON_PROCESSED);
+    if (press == down)
+        return;
+
+    InjectPointerKeyEvents(dev, press ? ButtonPress : ButtonRelease,
+                           button, 0, NULL);
+}
-- 
cgit v1.2.3