From 8a191c08ddda2e66fa26f148d6c21959bb08f923 Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Sun, 20 Feb 2011 12:29:25 +0000
Subject: xserver xkeyboard-config libX11 pixman mesa git update 2011

---
 xorg-server/hw/xfree86/common/xf86Init.c    | 2994 ++++++------
 xorg-server/hw/xfree86/common/xf86VidMode.c |    2 +-
 xorg-server/hw/xfree86/common/xf86xv.c      |  210 +-
 xorg-server/hw/xfree86/common/xf86xv.h      |    3 +
 xorg-server/hw/xfree86/common/xf86xvpriv.h  |    6 +-
 xorg-server/hw/xfree86/dri2/dri2.c          |    2 +-
 xorg-server/hw/xfree86/fbdevhw/fbdevhw.c    |   56 +-
 xorg-server/hw/xfree86/int10/helper_exec.c  | 1466 +++---
 xorg-server/hw/xfree86/modes/xf86Crtc.c     | 6563 +++++++++++++--------------
 xorg-server/hw/xwin/winclipboardxevents.c   |    3 +
 xorg-server/hw/xwin/winconfig.c             |   77 +-
 xorg-server/hw/xwin/winkeybd.c              |    8 +-
 xorg-server/hw/xwin/winkeybd.h              |   16 +-
 xorg-server/hw/xwin/winkeyhook.c            |    4 +-
 xorg-server/hw/xwin/winkeynames.h           |   13 +-
 xorg-server/hw/xwin/winlayouts.h            |    8 +-
 16 files changed, 5720 insertions(+), 5711 deletions(-)

(limited to 'xorg-server/hw')

diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index a1fda54cd..e017d9dce 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -1,1497 +1,1497 @@
-/*
- * Loosely based on code bearing the following copyright:
- *
- *   Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- */
-/*
- * Copyright (c) 1992-2003 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,
- * 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 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 <stdlib.h>
-#include <errno.h>
-
-#undef HAS_UTSNAME
-#if !defined(WIN32)
-#define HAS_UTSNAME 1
-#include <sys/utsname.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include <X11/Xproto.h>
-#include <X11/Xatom.h>
-#include "input.h"
-#include "servermd.h"
-#include "windowstr.h"
-#include "scrnintstr.h"
-#include "site.h"
-#include "mi.h"
-
-#include "compiler.h"
-
-#include "loaderProcs.h"
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-#define XF86_OS_PRIVS
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xf86cmap.h"
-#include "xorgVersion.h"
-#include "xf86Build.h"
-#include "mipointer.h"
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "xf86DDC.h"
-#include "xf86Xinput.h"
-#include "xf86InPriv.h"
-#include "picturestr.h"
-
-#include "xf86Bus.h"
-#include "xf86VGAarbiter.h"
-#include "globals.h"
-
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-#include <hotplug.h>
-
-
-#ifdef XF86PM
-void (*xf86OSPMClose)(void) = NULL;
-#endif
-static Bool xorgHWOpenConsole = FALSE;
-
-/* Common pixmap formats */
-
-static PixmapFormatRec formats[MAXFORMATS] = {
-	{ 1,	1,	BITMAP_SCANLINE_PAD },
-	{ 4,	8,	BITMAP_SCANLINE_PAD },
-	{ 8,	8,	BITMAP_SCANLINE_PAD },
-	{ 15,	16,	BITMAP_SCANLINE_PAD },
-	{ 16,	16,	BITMAP_SCANLINE_PAD },
-	{ 24,	32,	BITMAP_SCANLINE_PAD },
-	{ 32,	32,	BITMAP_SCANLINE_PAD },
-};
-static int numFormats = 7;
-static Bool formatsDone = FALSE;
-
-#ifndef OSNAME
-#define OSNAME " unknown"
-#endif
-#ifndef OSVENDOR
-#define OSVENDOR ""
-#endif
-#ifndef PRE_RELEASE
-#define PRE_RELEASE XORG_VERSION_SNAP
-#endif
-
-static void
-xf86PrintBanner(void)
-{
-#if PRE_RELEASE
-  xf86ErrorFVerb(0, "\n"
-    "This is a pre-release version of the X server from " XVENDORNAME ".\n"
-    "It is not supported in any way.\n"
-    "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
-    "Select the \"xorg\" product for bugs you find in this release.\n"
-    "Before reporting bugs in pre-release versions please check the\n"
-    "latest version in the X.Org Foundation git repository.\n"
-    "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
-#endif
-  xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
-	 XORG_VERSION_MAJOR,
-	 XORG_VERSION_MINOR,
-	 XORG_VERSION_PATCH);
-#if XORG_VERSION_SNAP > 0
-  xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
-#endif
-
-#if XORG_VERSION_SNAP >= 900
-  /* When the minor number is 99, that signifies that the we are making
-   * a release candidate for a major version.  (X.0.0)
-   * When the patch number is 99, that signifies that the we are making
-   * a release candidate for a minor version.  (X.Y.0)
-   * When the patch number is < 99, then we are making a release
-   * candidate for the next point release.  (X.Y.Z)
-   */
-#if XORG_VERSION_MINOR >= 99
-  xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1,
-                 XORG_VERSION_SNAP - 900);
-#elif XORG_VERSION_PATCH == 99
-  xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
-                 XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
-#else
-  xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
-                 XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
-                 XORG_VERSION_SNAP - 900);
-#endif
-#endif
-
-#ifdef XORG_CUSTOM_VERSION
-  xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
-#endif
-#ifndef XORG_DATE
-# define XORG_DATE "Unknown"
-#endif
-  xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
-  xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
-         X_PROTOCOL, X_PROTOCOL_REVISION);
-  xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
-#ifdef HAS_UTSNAME
-  {
-    struct utsname name;
-
-    /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
-       and Irix) and Single Unix Spec 3 just say that non-negative is success.
-       All agree that failure is represented by a negative number.
-     */
-    if (uname(&name) >= 0) {
-      xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
-	name.sysname, name.nodename, name.release, name.version, name.machine);
-#ifdef linux
-      do {
-	  char buf[80];
-	  int fd = open("/proc/cmdline", O_RDONLY);
-	  if (fd != -1) {
-	    xf86ErrorFVerb(0, "Kernel command line: ");
-	    memset(buf, 0, 80);
-	    while (read(fd, buf, 80) > 0) {
-		xf86ErrorFVerb(0, "%.80s", buf);
-		memset(buf, 0, 80);
-	    }
-	    close(fd);
-	  } 
-      } while (0);
-#endif
-    }
-  }
-#endif
-#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
-  {
-    struct tm t;
-    char buf[100];
-
-    memset(&t, 0, sizeof(t));
-    memset(buf, 0, sizeof(buf));
-    t.tm_mday = BUILD_DATE % 100;
-    t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
-    t.tm_year = BUILD_DATE / 10000 - 1900;
-#if defined(BUILD_TIME)
-    t.tm_sec = BUILD_TIME % 100;
-    t.tm_min = (BUILD_TIME / 100) % 100;
-    t.tm_hour = (BUILD_TIME / 10000) % 100;
-    if (strftime(buf, sizeof(buf), "%d %B %Y  %I:%M:%S%p", &t))
-       xf86ErrorFVerb(0, "Build Date: %s\n", buf);
-#else
-    if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
-       xf86ErrorFVerb(0, "Build Date: %s\n", buf);
-#endif
-  }
-#endif
-#if defined(BUILDERSTRING)
-  xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
-#endif
-  xf86ErrorFVerb(0, "Current version of pixman: %s\n",
-                 pixman_version_string());
-  xf86ErrorFVerb(0, "\tBefore reporting problems, check "
-                 ""__VENDORDWEBSUPPORT__"\n"
-                 "\tto make sure that you have the latest version.\n");
-}
-
-static void
-xf86PrintMarkers(void)
-{
-  LogPrintMarkers();
-}
-
-static Bool
-xf86CreateRootWindow(WindowPtr pWin)
-{
-  int ret = TRUE;
-  int err = Success;
-  ScreenPtr pScreen = pWin->drawable.pScreen;
-  RootWinPropPtr pProp;
-  CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
-      dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
-
-  DebugF("xf86CreateRootWindow(%p)\n", pWin);
-
-  if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
-    /* Can't find hook we are hung on */
-	xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
-		  "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
-		   (void *)xf86CreateRootWindow,
-		   (void *)pScreen->CreateWindow );
-  }
-
-  /* Unhook this function ... */
-  pScreen->CreateWindow = CreateWindow;
-  dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
-
-  /* ... and call the previous CreateWindow fuction, if any */
-  if (NULL!=pScreen->CreateWindow) {
-    ret = (*pScreen->CreateWindow)(pWin);
-  }
-
-  /* Now do our stuff */
-  if (xf86RegisteredPropertiesTable != NULL) {
-    if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
-      for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
-	   pProp != NULL && err==Success;
-	   pProp = pProp->next )
-	{
-	  Atom prop;
-
-	  prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
-	  err = dixChangeWindowProperty(serverClient, pWin,
-					prop, pProp->type,
-					pProp->format, PropModeReplace,
-					pProp->size, pProp->data,
-					FALSE);
-	}
-
-      /* Look at err */
-      ret &= (err==Success);
-
-    } else {
-      xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
-	      "non-root window %p (parent %p)\n",
-	      (void *)pWin, (void *)pWin->parent);
-      ret = FALSE;
-    }
-  }
-
-  DebugF("xf86CreateRootWindow() returns %d\n", ret);
-  return ret;
-}
-
-
-static void
-InstallSignalHandlers(void)
-{
-    /*
-     * Install signal handler for unexpected signals
-     */
-    xf86Info.caughtSignal=FALSE;
-    if (!xf86Info.notrapSignals) {
-	OsRegisterSigWrapper(xf86SigWrapper);
-    } else {
-	signal(SIGSEGV, SIG_DFL);
-	signal(SIGILL, SIG_DFL);
-#ifdef SIGEMT
-	signal(SIGEMT, SIG_DFL);
-#endif
-	signal(SIGFPE, SIG_DFL);
-	signal(SIGBUS, SIG_DFL);
-	signal(SIGSYS, SIG_DFL);
-	signal(SIGXCPU, SIG_DFL);
-	signal(SIGXFSZ, SIG_DFL);
-    }
-}
-
-/*
- * InitOutput --
- *	Initialize screenInfo for all actually accessible framebuffers.
- *      That includes vt-manager setup, querying all possible devices and
- *      collecting the pixmap formats.
- */
-void
-InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
-{
-  int                    i, j, k, scr_index, was_blocked = 0;
-  char                   **modulelist;
-  pointer                *optionlist;
-  Pix24Flags		 screenpix24, pix24;
-  MessageType		 pix24From = X_DEFAULT;
-  Bool			 pix24Fail = FALSE;
-  Bool			 autoconfig = FALSE;
-  GDevPtr		 configured_device;
-
-  xf86Initialising = TRUE;
-
-  if (serverGeneration == 1) {
-    if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
-      xf86ServerName++;
-    else
-      xf86ServerName = argv[0];
-
-	xf86PrintBanner();
-	xf86PrintMarkers();
-	if (xf86LogFile)  {
-	    time_t t;
-	    const char *ct;
-	    t = time(NULL);
-	    ct = ctime(&t);
-	    xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
-			xf86LogFile, ct);
-	}
-
-    /* Read and parse the config file */
-    if (!xf86DoConfigure && !xf86DoShowOptions) {
-      switch (xf86HandleConfigFile(FALSE)) {
-      case CONFIG_OK:
-	break;
-      case CONFIG_PARSE_ERROR:
-	xf86Msg(X_ERROR, "Error parsing the config file\n");
-	return;
-      case CONFIG_NOFILE:
-	autoconfig = TRUE;
-	break;
-      }
-    }
-
-    InstallSignalHandlers();
-
-    /* Initialise the loader */
-    LoaderInit();
-
-    /* Tell the loader the default module search path */
-    LoaderSetPath(xf86ModulePath);
-
-    if (xf86Info.ignoreABI) {
-        LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
-    }
-
-    if (xf86DoShowOptions)
-        DoShowOptions();
-
-    /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
-    xf86BusProbe();
-
-    if (xf86DoConfigure)
-	DoConfigure();
-
-    if (autoconfig) {
-	if (!xf86AutoConfig()) {
-	    xf86Msg(X_ERROR, "Auto configuration failed\n");
-	    return;
-	}
-    }
-
-#ifdef XF86PM
-    xf86OSPMClose = xf86OSPMOpen();
-#endif
-
-    /* Load all modules specified explicitly in the config file */
-    if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
-      xf86LoadModules(modulelist, optionlist);
-      free(modulelist);
-      free(optionlist);
-    }
-
-    /* Load all driver modules specified in the config file */
-    /* If there aren't any specified in the config file, autoconfig them */
-    /* FIXME: Does not handle multiple active screen sections, but I'm not
-     * sure if we really want to handle that case*/
-    configured_device = xf86ConfigLayout.screens->screen->device;
-    if ((!configured_device) || (!configured_device->driver)) {
-        if (!autoConfigDevice(configured_device)) {
-            xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
-            return ;
-        }
-    }
-    if ((modulelist = xf86DriverlistFromConfig())) {
-      xf86LoadModules(modulelist, NULL);
-      free(modulelist);
-    }
-
-    /* Load all input driver modules specified in the config file. */
-    if ((modulelist = xf86InputDriverlistFromConfig())) {
-      xf86LoadModules(modulelist, NULL);
-      free(modulelist);
-    }
-
-    /*
-     * It is expected that xf86AddDriver()/xf86AddInputDriver will be
-     * called for each driver as it is loaded.  Those functions save the
-     * module pointers for drivers.
-     * XXX Nothing keeps track of them for other modules.
-     */
-    /* XXX What do we do if not all of these could be loaded? */
-
-    /*
-     * At this point, xf86DriverList[] is all filled in with entries for
-     * each of the drivers to try and xf86NumDrivers has the number of
-     * drivers.  If there are none, return now.
-     */
-
-    if (xf86NumDrivers == 0) {
-      xf86Msg(X_ERROR, "No drivers available.\n");
-      return;
-    }
-
-    /*
-     * Call each of the Identify functions and call the driverFunc to check
-     * if HW access is required.  The Identify functions print out some
-     * identifying information, and anything else that might be
-     * needed at this early stage.
-     */
-
-    for (i = 0; i < xf86NumDrivers; i++) {
-	if (xf86DriverList[i]->Identify != NULL)
-	    xf86DriverList[i]->Identify(0);
-
-	if (!xorgHWAccess || !xorgHWOpenConsole) {
-	    xorgHWFlags flags;
-	    if(!xf86DriverList[i]->driverFunc
-		|| !xf86DriverList[i]->driverFunc(NULL,
-						  GET_REQUIRED_HW_INTERFACES,
-						  &flags))
-		flags = HW_IO;
-
-	    if(NEED_IO_ENABLED(flags))
-		xorgHWAccess = TRUE;
-	    if(!(flags & HW_SKIP_CONSOLE))
-		xorgHWOpenConsole = TRUE;
-	}
-    }
-
-    if (xorgHWOpenConsole)
-	xf86OpenConsole();
-    else
-	xf86Info.dontVTSwitch = TRUE;
-
-    if (xf86BusConfig() == FALSE)
-        return;
-
-    xf86PostProbe();
-
-    /*
-     * Sort the drivers to match the requested ording.  Using a slow
-     * bubble sort.
-     */
-    for (j = 0; j < xf86NumScreens - 1; j++) {
-	for (i = 0; i < xf86NumScreens - j - 1; i++) {
-	    if (xf86Screens[i + 1]->confScreen->screennum <
-		xf86Screens[i]->confScreen->screennum) {
-		ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
-		xf86Screens[i + 1] = xf86Screens[i];
-		xf86Screens[i] = tmpScrn;
-	    }
-	}
-    }
-    /* Fix up the indexes */
-    for (i = 0; i < xf86NumScreens; i++) {
-	xf86Screens[i]->scrnIndex = i;
-    }
-
-    /*
-     * Call the driver's PreInit()'s to complete initialisation for the first
-     * generation.
-     */
-
-    for (i = 0; i < xf86NumScreens; i++) {
-	xf86VGAarbiterScrnInit(xf86Screens[i]);
-	xf86VGAarbiterLock(xf86Screens[i]);
-	if (xf86Screens[i]->PreInit &&
-	    xf86Screens[i]->PreInit(xf86Screens[i], 0))
-	    xf86Screens[i]->configured = TRUE;
-	xf86VGAarbiterUnlock(xf86Screens[i]);
-    }
-    for (i = 0; i < xf86NumScreens; i++)
-	if (!xf86Screens[i]->configured)
-	    xf86DeleteScreen(i--, 0);
-
-    /*
-     * If no screens left, return now.
-     */
-
-    if (xf86NumScreens == 0) {
-      xf86Msg(X_ERROR,
-	      "Screen(s) found, but none have a usable configuration.\n");
-      return;
-    }
-
-    for (i = 0; i < xf86NumScreens; i++) {
-      if (xf86Screens[i]->name == NULL) {
-	XNFasprintf(&xf86Screens[i]->name, "screen%d", i);
-	xf86MsgVerb(X_WARNING, 0,
-		    "Screen driver %d has no name set, using `%s'.\n",
-		    i, xf86Screens[i]->name);
-      }
-    }
-
-    /* Remove (unload) drivers that are not required */
-    for (i = 0; i < xf86NumDrivers; i++)
-	if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
-	    xf86DeleteDriver(i);
-
-    /*
-     * At this stage we know how many screens there are.
-     */
-
-    for (i = 0; i < xf86NumScreens; i++)
-      xf86InitViewport(xf86Screens[i]);
-
-    /*
-     * Collect all pixmap formats and check for conflicts at the display
-     * level.  Should we die here?  Or just delete the offending screens?
-     */
-    screenpix24 = Pix24DontCare;
-    for (i = 0; i < xf86NumScreens; i++) {
-	if (xf86Screens[i]->imageByteOrder !=
-	    xf86Screens[0]->imageByteOrder)
-	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
-	if (xf86Screens[i]->bitmapScanlinePad !=
-	    xf86Screens[0]->bitmapScanlinePad)
-	    FatalError("Inconsistent display bitmapScanlinePad.  Exiting\n");
-	if (xf86Screens[i]->bitmapScanlineUnit !=
-	    xf86Screens[0]->bitmapScanlineUnit)
-	    FatalError("Inconsistent display bitmapScanlineUnit.  Exiting\n");
-	if (xf86Screens[i]->bitmapBitOrder !=
-	    xf86Screens[0]->bitmapBitOrder)
-	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
-
-	/* Determine the depth 24 pixmap format the screens would like */
-	if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
-	    if (screenpix24 == Pix24DontCare)
-		screenpix24 = xf86Screens[i]->pixmap24;
-	    else if (screenpix24 != xf86Screens[i]->pixmap24)
-		FatalError("Inconsistent depth 24 pixmap format.  Exiting\n");
-	}
-    }
-    /* check if screenpix24 is consistent with the config/cmdline */
-    if (xf86Info.pixmap24 != Pix24DontCare) {
-	pix24 = xf86Info.pixmap24;
-	pix24From = xf86Info.pix24From;
-	if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
-	    pix24Fail = TRUE;
-    } else if (screenpix24 != Pix24DontCare) {
-	pix24 = screenpix24;
-	pix24From = X_PROBED;
-    } else
-	pix24 = Pix24Use32;
-
-    if (pix24Fail)
-	FatalError("Screen(s) can't use the required depth 24 pixmap format"
-		   " (%d).  Exiting\n", PIX24TOBPP(pix24));
-
-    /* Initialise the depth 24 format */
-    for (j = 0; j < numFormats && formats[j].depth != 24; j++)
-	;
-    formats[j].bitsPerPixel = PIX24TOBPP(pix24);
-
-    /* Collect additional formats */
-    for (i = 0; i < xf86NumScreens; i++) {
-	for (j = 0; j < xf86Screens[i]->numFormats; j++) {
-	    for (k = 0; ; k++) {
-		if (k >= numFormats) {
-		    if (k >= MAXFORMATS)
-			FatalError("Too many pixmap formats!  Exiting\n");
-		    formats[k] = xf86Screens[i]->formats[j];
-		    numFormats++;
-		    break;
-		}
-		if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
-		    if ((formats[k].bitsPerPixel ==
-			 xf86Screens[i]->formats[j].bitsPerPixel) &&
-		        (formats[k].scanlinePad ==
-			 xf86Screens[i]->formats[j].scanlinePad))
-			break;
-		    FatalError("Inconsistent pixmap format for depth %d."
-			       "  Exiting\n", formats[k].depth);
-		}
-	    }
-	}
-    }
-    formatsDone = TRUE;
-
-    if (xf86Info.vtno >= 0 ) {
-#define VT_ATOM_NAME         "XFree86_VT"
-      Atom VTAtom=-1;
-      CARD32  *VT = NULL;
-      int  ret;
-
-      /* This memory needs to stay available until the screen has been
-	 initialized, and we can create the property for real.
-      */
-      if ( (VT = malloc(sizeof(CARD32)))==NULL ) {
-	FatalError("Unable to make VT property - out of memory. Exiting...\n");
-      }
-      *VT = xf86Info.vtno;
-
-      VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
-
-      for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
-	ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
-					     VTAtom, XA_INTEGER, 32,
-					     1, VT );
-	if (ret != Success)
-	  xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
-		     "Failed to register VT property\n");
-      }
-    }
-
-    /* If a screen uses depth 24, show what the pixmap format is */
-    for (i = 0; i < xf86NumScreens; i++) {
-	if (xf86Screens[i]->depth == 24) {
-	    xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
-		    PIX24TOBPP(pix24));
-	    break;
-	}
-    }
-  } else {
-    /*
-     * serverGeneration != 1; some OSs have to do things here, too.
-     */
-    if (xorgHWOpenConsole)
-	xf86OpenConsole();
-
-#ifdef XF86PM
-    /*
-      should we reopen it here? We need to deal with an already opened
-      device. We could leave this to the OS layer. For now we simply
-      close it here
-    */
-    if (xf86OSPMClose)
-        xf86OSPMClose();
-    if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
-	xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
-#endif
-
-    /* Make sure full I/O access is enabled */
-    if (xorgHWAccess)
-	xf86EnableIO();
-  }
-
-  /*
-   * Use the previously collected parts to setup pScreenInfo
-   */
-
-  pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
-  pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
-  pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
-  pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
-  pScreenInfo->numPixmapFormats = numFormats;
-  for (i = 0; i < numFormats; i++)
-    pScreenInfo->formats[i] = formats[i];
-
-  /* Make sure the server's VT is active */
-
-  if (serverGeneration != 1) {
-    xf86Resetting = TRUE;
-    /* All screens are in the same state, so just check the first */
-    if (!xf86Screens[0]->vtSema) {
-#ifdef HAS_USL_VTS
-      ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
-#endif
-      xf86AccessEnter();
-      was_blocked = xf86BlockSIGIO();
-    }
-  }
-
-  for (i = 0; i < xf86NumScreens; i++)
-      if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
-	  FatalError("Cannot register DDX private keys");
-
-  if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) ||
-      !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
-      FatalError("Cannot register DDX private keys");
-
-  for (i = 0; i < xf86NumScreens; i++) {
-	xf86VGAarbiterLock(xf86Screens[i]);
-	/*
-	 * Almost everything uses these defaults, and many of those that
-	 * don't, will wrap them.
-	 */
-	xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
-#ifdef XFreeXDGA
-	xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
-#endif
-	xf86Screens[i]->DPMSSet = NULL;
-	xf86Screens[i]->LoadPalette = NULL;
-	xf86Screens[i]->SetOverscan = NULL;
-	xf86Screens[i]->DriverFunc = NULL;
-	xf86Screens[i]->pScreen = NULL;
-	scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
-	xf86VGAarbiterUnlock(xf86Screens[i]);
-      if (scr_index == i) {
-	/*
-	 * Hook in our ScrnInfoRec, and initialise some other pScreen
-	 * fields.
-	 */
-	dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
-		      xf86ScreenKey, xf86Screens[i]);
-	xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
-	/* The driver should set this, but make sure it is set anyway */
-	xf86Screens[i]->vtSema = TRUE;
-      } else {
-	/* This shouldn't normally happen */
-	FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
-      }
-
-      DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
-	     i, xf86Screens[i]->pScreen );
-      DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
-	     i, xf86Screens[i]->pScreen->CreateWindow );
-
-      dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
-		    xf86CreateRootWindowKey,
-		    xf86Screens[i]->pScreen->CreateWindow);
-      xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
-
-    if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
-    {
-	xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
-	PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
-				 DDC ?
-				 (DDC->features.input_type ?
-				  SubPixelHorizontalRGB : SubPixelNone) :
-				 SubPixelUnknown);
-    }
-#ifdef RANDR
-    if (!xf86Info.disableRandR)
-	xf86RandRInit (screenInfo.screens[scr_index]);
-    xf86Msg(xf86Info.randRFrom, "RandR %s\n",
-	    xf86Info.disableRandR ? "disabled" : "enabled");
-#endif
-  }
-
-  xf86VGAarbiterWrapFunctions();
-  xf86UnblockSIGIO(was_blocked);
-
-  xf86InitOrigins();
-
-  xf86Resetting = FALSE;
-  xf86Initialising = FALSE;
-
-  RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
-				 NULL);
-}
-
-/*
- * InitInput --
- *      Initialize all supported input devices.
- */
-
-void
-InitInput(int argc, char **argv)
-{
-    InputInfoPtr* pDev;
-    DeviceIntPtr dev;
-
-    xf86Info.vtRequestsPending = FALSE;
-
-    mieqInit();
-
-    GetEventList(&xf86Events);
-
-    /* Call the PreInit function for each input device instance. */
-    for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
-        /* Replace obsolete keyboard driver with kbd */
-        if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
-            strcpy((*pDev)->driver, "kbd");
-        }
-
-        /* If one fails, the others will too */
-        if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc)
-            break;
-    }
-
-    config_init();
-}
-
-void
-CloseInput (void)
-{
-    config_fini();
-}
-
-/*
- * OsVendorInit --
- *      OS/Vendor-specific initialisations.  Called from OsInit(), which
- *      is called by dix before establishing the well known sockets.
- */
-
-void
-OsVendorInit(void)
-{
-  static Bool beenHere = FALSE;
-
-  signal(SIGCHLD, SIG_DFL);	/* Need to wait for child processes */
-
-  if (!beenHere) {
-    umask(022);
-    xf86LogInit();
-  }
-
-        /* Set stderr to non-blocking. */
-#ifndef O_NONBLOCK
-#if defined(FNDELAY)
-#define O_NONBLOCK FNDELAY
-#elif defined(O_NDELAY)
-#define O_NONBLOCK O_NDELAY
-#endif
-
-#ifdef O_NONBLOCK
-  if (!beenHere) {
-    if (geteuid() == 0 && getuid() != geteuid())
-    {
-      int status;
-
-      status = fcntl(fileno(stderr), F_GETFL, 0);
-      if (status != -1) {
-	fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
-      }
-    }
-  }
-#endif
-#endif
-
-  beenHere = TRUE;
-}
-
-/*
- * ddxGiveUp --
- *      Device dependent cleanup. Called by by dix before normal server death.
- *      For SYSV386 we must switch the terminal back to normal mode. No error-
- *      checking here, since there should be restored as much as possible.
- */
-
-void
-ddxGiveUp(void)
-{
-    int i;
-
-    xf86VGAarbiterFini();
-
-#ifdef XF86PM
-    if (xf86OSPMClose)
-	xf86OSPMClose();
-    xf86OSPMClose = NULL;
-#endif
-
-    for (i = 0; i < xf86NumScreens; i++) {
-	/*
-	 * zero all access functions to
-	 * trap calls when switched away.
-	 */
-	xf86Screens[i]->vtSema = FALSE;
-    }
-
-#ifdef XFreeXDGA
-    DGAShutdown();
-#endif
-
-    if (xorgHWOpenConsole)
-	xf86CloseConsole();
-
-    xf86CloseLog();
-
-    /* If an unexpected signal was caught, dump a core for debugging */
-    if (xf86Info.caughtSignal)
-	OsAbort();
-}
-
-
-
-/*
- * AbortDDX --
- *      DDX - specific abort routine.  Called by AbortServer(). The attempt is
- *      made to restore all original setting of the displays. Also all devices
- *      are closed.
- */
-
-void
-AbortDDX(void)
-{
-  int i;
-
-  xf86BlockSIGIO();
-
-  /*
-   * try to restore the original video state
-   */
-#ifdef DPMSExtension /* Turn screens back on */
-  if (DPMSPowerLevel != DPMSModeOn)
-      DPMSSet(serverClient, DPMSModeOn);
-#endif
-  if (xf86Screens) {
-      for (i = 0; i < xf86NumScreens; i++)
-	  if (xf86Screens[i]->vtSema) {
-	      /*
-	       * if we are aborting before ScreenInit() has finished
-	       * we might not have been wrapped yet. Therefore enable
-	       * screen explicitely.
-	       */
-	      xf86VGAarbiterLock(xf86Screens[i]);
-	      (xf86Screens[i]->LeaveVT)(i, 0);
-	      xf86VGAarbiterUnlock(xf86Screens[i]);
-	  }
-  }
-
-  xf86AccessLeave();
-
-  /*
-   * This is needed for an abnormal server exit, since the normal exit stuff
-   * MUST also be performed (i.e. the vt must be left in a defined state)
-   */
-  ddxGiveUp();
-}
-
-void
-OsVendorFatalError(void)
-{
-#ifdef VENDORSUPPORT
-    ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
-	   "at %s for support on this crash.\n",VENDORSUPPORT);
-#else
-    ErrorF("\nPlease consult the "XVENDORNAME" support \n"
-	   "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
-#endif
-    if (xf86LogFile && xf86LogFileWasOpened)
-	ErrorF("Please also check the log file at \"%s\" for additional "
-              "information.\n", xf86LogFile);
-    ErrorF("\n");
-}
-
-int
-xf86SetVerbosity(int verb)
-{
-    int save = xf86Verbose;
-
-    xf86Verbose = verb;
-    LogSetParameter(XLOG_VERBOSITY, verb);
-    return save;
-}
-
-int
-xf86SetLogVerbosity(int verb)
-{
-    int save = xf86LogVerbose;
-
-    xf86LogVerbose = verb;
-    LogSetParameter(XLOG_FILE_VERBOSITY, verb);
-    return save;
-}
-
-static void
-xf86PrintDefaultModulePath(void)
-{
-  ErrorF("%s\n", DEFAULT_MODULE_PATH);
-}
-
-static void
-xf86PrintDefaultLibraryPath(void)
-{
-  ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
-}
-
-/*
- * ddxProcessArgument --
- *	Process device-dependent command line args. Returns 0 if argument is
- *      not device dependent, otherwise Count of number of elements of argv
- *      that are part of a device dependent commandline option.
- *
- */
-
-/* ARGSUSED */
-int
-ddxProcessArgument(int argc, char **argv, int i)
-{
-#define CHECK_FOR_REQUIRED_ARGUMENT() \
-    if (((i + 1) >= argc) || (!argv[i + 1])) { 				\
-      ErrorF("Required argument to %s not specified\n", argv[i]); 	\
-      UseMsg(); 							\
-      FatalError("Required argument to %s not specified\n", argv[i]);	\
-    }
-
-  /* First the options that are only allowed for root */
-  if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
-    if ( (geteuid() == 0) && (getuid() != 0) ) {
-      FatalError("The '%s' option can only be used by root.\n", argv[i]);
-    }
-    else if (!strcmp(argv[i], "-modulepath"))
-    {
-      char *mp;
-      CHECK_FOR_REQUIRED_ARGUMENT();
-      mp = strdup(argv[i + 1]);
-      if (!mp)
-	FatalError("Can't allocate memory for ModulePath\n");
-      xf86ModulePath = mp;
-      xf86ModPathFrom = X_CMDLINE;
-      return 2;
-    }
-    else if (!strcmp(argv[i], "-logfile"))
-    {
-      char *lf;
-      CHECK_FOR_REQUIRED_ARGUMENT();
-      lf = strdup(argv[i + 1]);
-      if (!lf)
-	FatalError("Can't allocate memory for LogFile\n");
-      xf86LogFile = lf;
-      xf86LogFileFrom = X_CMDLINE;
-      return 2;
-    }
-  }
-  if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
-  {
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
-      FatalError("\nInvalid argument for %s\n"
-	  "\tFor non-root users, the file specified with %s must be\n"
-	  "\ta relative path and must not contain any \"..\" elements.\n"
-	  "\tUsing default "__XCONFIGFILE__" search path.\n\n",
-	  argv[i], argv[i]);
-    }
-    xf86ConfigFile = argv[i + 1];
-    return 2;
-  }
-  if (!strcmp(argv[i], "-configdir"))
-  {
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
-      FatalError("\nInvalid argument for %s\n"
-	  "\tFor non-root users, the file specified with %s must be\n"
-	  "\ta relative path and must not contain any \"..\" elements.\n"
-	  "\tUsing default "__XCONFIGDIR__" search path.\n\n",
-	  argv[i], argv[i]);
-    }
-    xf86ConfigDir = argv[i + 1];
-    return 2;
-  }
-  if (!strcmp(argv[i],"-flipPixels"))
-  {
-    xf86FlipPixels = TRUE;
-    return 1;
-  }
-#ifdef XF86VIDMODE
-  if (!strcmp(argv[i],"-disableVidMode"))
-  {
-    xf86VidModeDisabled = TRUE;
-    return 1;
-  }
-  if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
-  {
-    xf86VidModeAllowNonLocal = TRUE;
-    return 1;
-  }
-#endif
-  if (!strcmp(argv[i],"-allowMouseOpenFail"))
-  {
-    xf86AllowMouseOpenFail = TRUE;
-    return 1;
-  }
-  if (!strcmp(argv[i],"-ignoreABI"))
-  {
-    LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
-    return 1;
-  }
-  if (!strcmp(argv[i],"-verbose"))
-  {
-    if (++i < argc && argv[i])
-    {
-      char *end;
-      long val;
-      val = strtol(argv[i], &end, 0);
-      if (*end == '\0')
-      {
-	xf86SetVerbosity(val);
-	return 2;
-      }
-    }
-    xf86SetVerbosity(++xf86Verbose);
-    return 1;
-  }
-  if (!strcmp(argv[i],"-logverbose"))
-  {
-    if (++i < argc && argv[i])
-    {
-      char *end;
-      long val;
-      val = strtol(argv[i], &end, 0);
-      if (*end == '\0')
-      {
-	xf86SetLogVerbosity(val);
-	return 2;
-      }
-    }
-    xf86SetLogVerbosity(++xf86LogVerbose);
-    return 1;
-  }
-  if (!strcmp(argv[i],"-quiet"))
-  {
-    xf86SetVerbosity(-1);
-    return 1;
-  }
-  if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
-  {
-    xf86PrintBanner();
-    exit(0);
-  }
-  if (!strcmp(argv[i],"-showDefaultModulePath"))
-  {
-    xf86PrintDefaultModulePath();
-    exit(0);
-  }
-  if (!strcmp(argv[i],"-showDefaultLibPath"))
-  {
-    xf86PrintDefaultLibraryPath();
-    exit(0);
-  }
-  /* Notice the -fp flag, but allow it to pass to the dix layer */
-  if (!strcmp(argv[i], "-fp"))
-  {
-    xf86fpFlag = TRUE;
-    return 0;
-  }
-  /* Notice the -bs flag, but allow it to pass to the dix layer */
-  if (!strcmp(argv[i], "-bs"))
-  {
-    xf86bsDisableFlag = TRUE;
-    return 0;
-  }
-  /* Notice the +bs flag, but allow it to pass to the dix layer */
-  if (!strcmp(argv[i], "+bs"))
-  {
-    xf86bsEnableFlag = TRUE;
-    return 0;
-  }
-  /* Notice the -s flag, but allow it to pass to the dix layer */
-  if (!strcmp(argv[i], "-s"))
-  {
-    xf86sFlag = TRUE;
-    return 0;
-  }
-  if (!strcmp(argv[i], "-pixmap24"))
-  {
-    xf86Pix24 = Pix24Use24;
-    return 1;
-  }
-  if (!strcmp(argv[i], "-pixmap32"))
-  {
-    xf86Pix24 = Pix24Use32;
-    return 1;
-  }
-  if (!strcmp(argv[i], "-fbbpp"))
-  {
-    int bpp;
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    if (sscanf(argv[++i], "%d", &bpp) == 1)
-    {
-      xf86FbBpp = bpp;
-      return 2;
-    }
-    else
-    {
-      ErrorF("Invalid fbbpp\n");
-      return 0;
-    }
-  }
-  if (!strcmp(argv[i], "-depth"))
-  {
-    int depth;
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    if (sscanf(argv[++i], "%d", &depth) == 1)
-    {
-      xf86Depth = depth;
-      return 2;
-    }
-    else
-    {
-      ErrorF("Invalid depth\n");
-      return 0;
-    }
-  }
-  if (!strcmp(argv[i], "-weight"))
-  {
-    int red, green, blue;
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
-    {
-      xf86Weight.red = red;
-      xf86Weight.green = green;
-      xf86Weight.blue = blue;
-      return 2;
-    }
-    else
-    {
-      ErrorF("Invalid weighting\n");
-      return 0;
-    }
-  }
-  if (!strcmp(argv[i], "-gamma")  || !strcmp(argv[i], "-rgamma") ||
-      !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
-  {
-    double gamma;
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    if (sscanf(argv[++i], "%lf", &gamma) == 1) {
-       if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
-	  ErrorF("gamma out of range, only  %.2f <= gamma_value <= %.1f"
-		 " is valid\n", GAMMA_MIN, GAMMA_MAX);
-	  return 0;
-       }
-       if (!strcmp(argv[i-1], "-gamma"))
-	  xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
-       else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
-       else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
-       else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
-       return 2;
-    }
-  }
-  if (!strcmp(argv[i], "-layout"))
-  {
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    xf86LayoutName = argv[++i];
-    return 2;
-  }
-  if (!strcmp(argv[i], "-screen"))
-  {
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    xf86ScreenName = argv[++i];
-    return 2;
-  }
-  if (!strcmp(argv[i], "-pointer"))
-  {
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    xf86PointerName = argv[++i];
-    return 2;
-  }
-  if (!strcmp(argv[i], "-keyboard"))
-  {
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    xf86KeyboardName = argv[++i];
-    return 2;
-  }
-  if (!strcmp(argv[i], "-nosilk"))
-  {
-    xf86silkenMouseDisableFlag = TRUE;
-    return 1;
-  }
-#ifdef HAVE_ACPI
-  if (!strcmp(argv[i], "-noacpi"))
-  {
-    xf86acpiDisableFlag = TRUE;
-    return 1;
-  }
-#endif
-  if (!strcmp(argv[i], "-configure"))
-  {
-    if (getuid() != 0 && geteuid() == 0) {
-	ErrorF("The '-configure' option can only be used by root.\n");
-	exit(1);
-    }
-    xf86DoConfigure = TRUE;
-    xf86AllowMouseOpenFail = TRUE;
-    return 1;
-  }
-  if (!strcmp(argv[i], "-showopts"))
-  {
-    if (getuid() != 0 && geteuid() == 0) {
-    ErrorF("The '-showopts' option can only be used by root.\n");
-    exit(1);
-    }
-    xf86DoShowOptions = TRUE;
-    return 1;
-  }
-  if (!strcmp(argv[i], "-isolateDevice"))
-  {
-    CHECK_FOR_REQUIRED_ARGUMENT();
-    if (strncmp(argv[++i], "PCI:", 4)) {
-       FatalError("Bus types other than PCI not yet isolable\n");
-    }
-    xf86PciIsolateDevice(argv[i]);
-    return 2;
-  }
-  /* Notice cmdline xkbdir, but pass to dix as well */
-  if (!strcmp(argv[i], "-xkbdir"))
-  {
-    xf86xkbdirFlag = TRUE;
-    return 0;
-  }
-
-  /* OS-specific processing */
-  return xf86ProcessArgument(argc, argv, i);
-}
-
-/*
- * ddxUseMsg --
- *	Print out correct use of device dependent commandline options.
- *      Maybe the user now knows what really to do ...
- */
-
-void
-ddxUseMsg(void)
-{
-  ErrorF("\n");
-  ErrorF("\n");
-  ErrorF("Device Dependent Usage\n");
-  if (getuid() == 0 || geteuid() != 0)
-  {
-    ErrorF("-modulepath paths      specify the module search path\n");
-    ErrorF("-logfile file          specify a log file name\n");
-    ErrorF("-configure             probe for devices and write an "__XCONFIGFILE__"\n");
-    ErrorF("-showopts              print available options for all installed drivers\n");
-  }
-  ErrorF("-config file           specify a configuration file, relative to the\n");
-  ErrorF("                       "__XCONFIGFILE__" search path, only root can use absolute\n");
-  ErrorF("-configdir dir         specify a configuration directory, relative to the\n");
-  ErrorF("                       "__XCONFIGDIR__" search path, only root can use absolute\n");
-  ErrorF("-verbose [n]           verbose startup messages\n");
-  ErrorF("-logverbose [n]        verbose log messages\n");
-  ErrorF("-quiet                 minimal startup messages\n");
-  ErrorF("-pixmap24              use 24bpp pixmaps for depth 24\n");
-  ErrorF("-pixmap32              use 32bpp pixmaps for depth 24\n");
-  ErrorF("-fbbpp n               set bpp for the framebuffer. Default: 8\n");
-  ErrorF("-depth n               set colour depth. Default: 8\n");
-  ErrorF("-gamma f               set gamma value (0.1 < f < 10.0) Default: 1.0\n");
-  ErrorF("-rgamma f              set gamma value for red phase\n");
-  ErrorF("-ggamma f              set gamma value for green phase\n");
-  ErrorF("-bgamma f              set gamma value for blue phase\n");
-  ErrorF("-weight nnn            set RGB weighting at 16 bpp.  Default: 565\n");
-  ErrorF("-layout name           specify the ServerLayout section name\n");
-  ErrorF("-screen name           specify the Screen section name\n");
-  ErrorF("-keyboard name         specify the core keyboard InputDevice name\n");
-  ErrorF("-pointer name          specify the core pointer InputDevice name\n");
-  ErrorF("-nosilk                disable Silken Mouse\n");
-  ErrorF("-flipPixels            swap default black/white Pixel values\n");
-#ifdef XF86VIDMODE
-  ErrorF("-disableVidMode        disable mode adjustments with xvidtune\n");
-  ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
-#endif
-  ErrorF("-allowMouseOpenFail    start server even if the mouse can't be initialized\n");
-  ErrorF("-ignoreABI             make module ABI mismatches non-fatal\n");
-  ErrorF("-isolateDevice bus_id  restrict device resets to bus_id (PCI only)\n");
-  ErrorF("-version               show the server version\n");
-  ErrorF("-showDefaultModulePath show the server default module path\n");
-  ErrorF("-showDefaultLibPath    show the server default library path\n");
-  /* OS-specific usage */
-  xf86UseMsg();
-  ErrorF("\n");
-}
-
-
-/*
- * xf86LoadModules iterates over a list that is being passed in.
- */
-Bool
-xf86LoadModules(char **list, pointer *optlist)
-{
-    int errmaj, errmin;
-    pointer opt;
-    int i;
-    char *name;
-    Bool failed = FALSE;
-
-    if (!list)
-	return TRUE;
-
-    for (i = 0; list[i] != NULL; i++) {
-
-	/* Normalise the module name */
-	name = xf86NormalizeName(list[i]);
-
-	/* Skip empty names */
-	if (name == NULL || *name == '\0')
-	    continue;
-
-	/* Replace obsolete keyboard driver with kbd */
-	if (!xf86NameCmp(name, "keyboard")) {
-	    strcpy(name, "kbd");
-	}
-
-	if (optlist)
-	    opt = optlist[i];
-	else
-	    opt = NULL;
-
-        if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
-	    LoaderErrorMsg(NULL, name, errmaj, errmin);
-	    failed = TRUE;
-	}
-	free(name);
-    }
-    return !failed;
-}
-
-/* Pixmap format stuff */
-
-PixmapFormatPtr
-xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
-{
-    int i;
-    static PixmapFormatRec format;	/* XXX not reentrant */
-
-    /*
-     * When the formats[] list initialisation isn't complete, check the
-     * depth 24 pixmap config/cmdline options and screen-specified formats.
-     */
-
-    if (!formatsDone) {
-	if (depth == 24) {
-	    Pix24Flags pix24 = Pix24DontCare;
-
-	    format.depth = 24;
-	    format.scanlinePad = BITMAP_SCANLINE_PAD;
-	    if (xf86Info.pixmap24 != Pix24DontCare)
-		pix24 = xf86Info.pixmap24;
-	    else if (pScrn->pixmap24 != Pix24DontCare)
-		pix24 = pScrn->pixmap24;
-	    if (pix24 == Pix24Use24)
-		format.bitsPerPixel = 24;
-	    else
-		format.bitsPerPixel = 32;
-	    return &format;
-	}
-    }
-
-    for (i = 0; i < numFormats; i++)
-	if (formats[i].depth == depth)
-	   break;
-    if (i != numFormats)
-	return &formats[i];
-    else if (!formatsDone) {
-	/* Check for screen-specified formats */
-	for (i = 0; i < pScrn->numFormats; i++)
-	    if (pScrn->formats[i].depth == depth)
-		break;
-	if (i != pScrn->numFormats)
-	    return &pScrn->formats[i];
-    }
-    return NULL;
-}
-
-int
-xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
-{
-    PixmapFormatPtr format;
-
-
-    format = xf86GetPixFormat(pScrn, depth);
-    if (format)
-	return format->bitsPerPixel;
-    else
-	return 0;
-}
+/*
+ * Loosely based on code bearing the following copyright:
+ *
+ *   Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ */
+/*
+ * Copyright (c) 1992-2003 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,
+ * 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 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 <stdlib.h>
+#include <errno.h>
+
+#undef HAS_UTSNAME
+#if !defined(WIN32)
+#define HAS_UTSNAME 1
+#include <sys/utsname.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include "input.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "site.h"
+#include "mi.h"
+
+#include "compiler.h"
+
+#include "loaderProcs.h"
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#define XF86_OS_PRIVS
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xf86cmap.h"
+#include "xorgVersion.h"
+#include "xf86Build.h"
+#include "mipointer.h"
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "xf86DDC.h"
+#include "xf86Xinput.h"
+#include "xf86InPriv.h"
+#include "picturestr.h"
+
+#include "xf86Bus.h"
+#include "xf86VGAarbiter.h"
+#include "globals.h"
+
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+#include <hotplug.h>
+
+
+#ifdef XF86PM
+void (*xf86OSPMClose)(void) = NULL;
+#endif
+static Bool xorgHWOpenConsole = FALSE;
+
+/* Common pixmap formats */
+
+static PixmapFormatRec formats[MAXFORMATS] = {
+	{ 1,	1,	BITMAP_SCANLINE_PAD },
+	{ 4,	8,	BITMAP_SCANLINE_PAD },
+	{ 8,	8,	BITMAP_SCANLINE_PAD },
+	{ 15,	16,	BITMAP_SCANLINE_PAD },
+	{ 16,	16,	BITMAP_SCANLINE_PAD },
+	{ 24,	32,	BITMAP_SCANLINE_PAD },
+	{ 32,	32,	BITMAP_SCANLINE_PAD },
+};
+static int numFormats = 7;
+static Bool formatsDone = FALSE;
+
+#ifndef OSNAME
+#define OSNAME " unknown"
+#endif
+#ifndef OSVENDOR
+#define OSVENDOR ""
+#endif
+#ifndef PRE_RELEASE
+#define PRE_RELEASE XORG_VERSION_SNAP
+#endif
+
+static void
+xf86PrintBanner(void)
+{
+#if PRE_RELEASE
+  xf86ErrorFVerb(0, "\n"
+    "This is a pre-release version of the X server from " XVENDORNAME ".\n"
+    "It is not supported in any way.\n"
+    "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
+    "Select the \"xorg\" product for bugs you find in this release.\n"
+    "Before reporting bugs in pre-release versions please check the\n"
+    "latest version in the X.Org Foundation git repository.\n"
+    "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
+#endif
+  xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
+	 XORG_VERSION_MAJOR,
+	 XORG_VERSION_MINOR,
+	 XORG_VERSION_PATCH);
+#if XORG_VERSION_SNAP > 0
+  xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
+#endif
+
+#if XORG_VERSION_SNAP >= 900
+  /* When the minor number is 99, that signifies that the we are making
+   * a release candidate for a major version.  (X.0.0)
+   * When the patch number is 99, that signifies that the we are making
+   * a release candidate for a minor version.  (X.Y.0)
+   * When the patch number is < 99, then we are making a release
+   * candidate for the next point release.  (X.Y.Z)
+   */
+#if XORG_VERSION_MINOR >= 99
+  xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1,
+                 XORG_VERSION_SNAP - 900);
+#elif XORG_VERSION_PATCH == 99
+  xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
+                 XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
+#else
+  xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
+                 XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
+                 XORG_VERSION_SNAP - 900);
+#endif
+#endif
+
+#ifdef XORG_CUSTOM_VERSION
+  xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
+#endif
+#ifndef XORG_DATE
+# define XORG_DATE "Unknown"
+#endif
+  xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
+  xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
+         X_PROTOCOL, X_PROTOCOL_REVISION);
+  xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
+#ifdef HAS_UTSNAME
+  {
+    struct utsname name;
+
+    /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
+       and Irix) and Single Unix Spec 3 just say that non-negative is success.
+       All agree that failure is represented by a negative number.
+     */
+    if (uname(&name) >= 0) {
+      xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
+	name.sysname, name.nodename, name.release, name.version, name.machine);
+#ifdef linux
+      do {
+	  char buf[80];
+	  int fd = open("/proc/cmdline", O_RDONLY);
+	  if (fd != -1) {
+	    xf86ErrorFVerb(0, "Kernel command line: ");
+	    memset(buf, 0, 80);
+	    while (read(fd, buf, 80) > 0) {
+		xf86ErrorFVerb(0, "%.80s", buf);
+		memset(buf, 0, 80);
+	    }
+	    close(fd);
+	  } 
+      } while (0);
+#endif
+    }
+  }
+#endif
+#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
+  {
+    struct tm t;
+    char buf[100];
+
+    memset(&t, 0, sizeof(t));
+    memset(buf, 0, sizeof(buf));
+    t.tm_mday = BUILD_DATE % 100;
+    t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
+    t.tm_year = BUILD_DATE / 10000 - 1900;
+#if defined(BUILD_TIME)
+    t.tm_sec = BUILD_TIME % 100;
+    t.tm_min = (BUILD_TIME / 100) % 100;
+    t.tm_hour = (BUILD_TIME / 10000) % 100;
+    if (strftime(buf, sizeof(buf), "%d %B %Y  %I:%M:%S%p", &t))
+       xf86ErrorFVerb(0, "Build Date: %s\n", buf);
+#else
+    if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
+       xf86ErrorFVerb(0, "Build Date: %s\n", buf);
+#endif
+  }
+#endif
+#if defined(BUILDERSTRING)
+  xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
+#endif
+  xf86ErrorFVerb(0, "Current version of pixman: %s\n",
+                 pixman_version_string());
+  xf86ErrorFVerb(0, "\tBefore reporting problems, check "
+                 ""__VENDORDWEBSUPPORT__"\n"
+                 "\tto make sure that you have the latest version.\n");
+}
+
+static void
+xf86PrintMarkers(void)
+{
+  LogPrintMarkers();
+}
+
+static Bool
+xf86CreateRootWindow(WindowPtr pWin)
+{
+  int ret = TRUE;
+  int err = Success;
+  ScreenPtr pScreen = pWin->drawable.pScreen;
+  RootWinPropPtr pProp;
+  CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
+      dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
+
+  DebugF("xf86CreateRootWindow(%p)\n", pWin);
+
+  if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
+    /* Can't find hook we are hung on */
+	xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
+		  "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
+		   (void *)xf86CreateRootWindow,
+		   (void *)pScreen->CreateWindow );
+  }
+
+  /* Unhook this function ... */
+  pScreen->CreateWindow = CreateWindow;
+  dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
+
+  /* ... and call the previous CreateWindow fuction, if any */
+  if (NULL!=pScreen->CreateWindow) {
+    ret = (*pScreen->CreateWindow)(pWin);
+  }
+
+  /* Now do our stuff */
+  if (xf86RegisteredPropertiesTable != NULL) {
+    if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
+      for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
+	   pProp != NULL && err==Success;
+	   pProp = pProp->next )
+	{
+	  Atom prop;
+
+	  prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
+	  err = dixChangeWindowProperty(serverClient, pWin,
+					prop, pProp->type,
+					pProp->format, PropModeReplace,
+					pProp->size, pProp->data,
+					FALSE);
+	}
+
+      /* Look at err */
+      ret &= (err==Success);
+
+    } else {
+      xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
+	      "non-root window %p (parent %p)\n",
+	      (void *)pWin, (void *)pWin->parent);
+      ret = FALSE;
+    }
+  }
+
+  DebugF("xf86CreateRootWindow() returns %d\n", ret);
+  return ret;
+}
+
+
+static void
+InstallSignalHandlers(void)
+{
+    /*
+     * Install signal handler for unexpected signals
+     */
+    xf86Info.caughtSignal=FALSE;
+    if (!xf86Info.notrapSignals) {
+	OsRegisterSigWrapper(xf86SigWrapper);
+    } else {
+	signal(SIGSEGV, SIG_DFL);
+	signal(SIGILL, SIG_DFL);
+#ifdef SIGEMT
+	signal(SIGEMT, SIG_DFL);
+#endif
+	signal(SIGFPE, SIG_DFL);
+	signal(SIGBUS, SIG_DFL);
+	signal(SIGSYS, SIG_DFL);
+	signal(SIGXCPU, SIG_DFL);
+	signal(SIGXFSZ, SIG_DFL);
+    }
+}
+
+/*
+ * InitOutput --
+ *	Initialize screenInfo for all actually accessible framebuffers.
+ *      That includes vt-manager setup, querying all possible devices and
+ *      collecting the pixmap formats.
+ */
+void
+InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+  int                    i, j, k, scr_index, was_blocked = 0;
+  char                   **modulelist;
+  pointer                *optionlist;
+  Pix24Flags		 screenpix24, pix24;
+  MessageType		 pix24From = X_DEFAULT;
+  Bool			 pix24Fail = FALSE;
+  Bool			 autoconfig = FALSE;
+  GDevPtr		 configured_device;
+
+  xf86Initialising = TRUE;
+
+  if (serverGeneration == 1) {
+    if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
+      xf86ServerName++;
+    else
+      xf86ServerName = argv[0];
+
+	xf86PrintBanner();
+	xf86PrintMarkers();
+	if (xf86LogFile)  {
+	    time_t t;
+	    const char *ct;
+	    t = time(NULL);
+	    ct = ctime(&t);
+	    xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
+			xf86LogFile, ct);
+	}
+
+    /* Read and parse the config file */
+    if (!xf86DoConfigure && !xf86DoShowOptions) {
+      switch (xf86HandleConfigFile(FALSE)) {
+      case CONFIG_OK:
+	break;
+      case CONFIG_PARSE_ERROR:
+	xf86Msg(X_ERROR, "Error parsing the config file\n");
+	return;
+      case CONFIG_NOFILE:
+	autoconfig = TRUE;
+	break;
+      }
+    }
+
+    InstallSignalHandlers();
+
+    /* Initialise the loader */
+    LoaderInit();
+
+    /* Tell the loader the default module search path */
+    LoaderSetPath(xf86ModulePath);
+
+    if (xf86Info.ignoreABI) {
+        LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
+    }
+
+    if (xf86DoShowOptions)
+        DoShowOptions();
+
+    /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
+    xf86BusProbe();
+
+    if (xf86DoConfigure)
+	DoConfigure();
+
+    if (autoconfig) {
+	if (!xf86AutoConfig()) {
+	    xf86Msg(X_ERROR, "Auto configuration failed\n");
+	    return;
+	}
+    }
+
+#ifdef XF86PM
+    xf86OSPMClose = xf86OSPMOpen();
+#endif
+
+    /* Load all modules specified explicitly in the config file */
+    if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
+      xf86LoadModules(modulelist, optionlist);
+      free(modulelist);
+      free(optionlist);
+    }
+
+    /* Load all driver modules specified in the config file */
+    /* If there aren't any specified in the config file, autoconfig them */
+    /* FIXME: Does not handle multiple active screen sections, but I'm not
+     * sure if we really want to handle that case*/
+    configured_device = xf86ConfigLayout.screens->screen->device;
+    if ((!configured_device) || (!configured_device->driver)) {
+        if (!autoConfigDevice(configured_device)) {
+            xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
+            return ;
+        }
+    }
+    if ((modulelist = xf86DriverlistFromConfig())) {
+      xf86LoadModules(modulelist, NULL);
+      free(modulelist);
+    }
+
+    /* Load all input driver modules specified in the config file. */
+    if ((modulelist = xf86InputDriverlistFromConfig())) {
+      xf86LoadModules(modulelist, NULL);
+      free(modulelist);
+    }
+
+    /*
+     * It is expected that xf86AddDriver()/xf86AddInputDriver will be
+     * called for each driver as it is loaded.  Those functions save the
+     * module pointers for drivers.
+     * XXX Nothing keeps track of them for other modules.
+     */
+    /* XXX What do we do if not all of these could be loaded? */
+
+    /*
+     * At this point, xf86DriverList[] is all filled in with entries for
+     * each of the drivers to try and xf86NumDrivers has the number of
+     * drivers.  If there are none, return now.
+     */
+
+    if (xf86NumDrivers == 0) {
+      xf86Msg(X_ERROR, "No drivers available.\n");
+      return;
+    }
+
+    /*
+     * Call each of the Identify functions and call the driverFunc to check
+     * if HW access is required.  The Identify functions print out some
+     * identifying information, and anything else that might be
+     * needed at this early stage.
+     */
+
+    for (i = 0; i < xf86NumDrivers; i++) {
+	if (xf86DriverList[i]->Identify != NULL)
+	    xf86DriverList[i]->Identify(0);
+
+	if (!xorgHWAccess || !xorgHWOpenConsole) {
+	    xorgHWFlags flags;
+	    if(!xf86DriverList[i]->driverFunc
+		|| !xf86DriverList[i]->driverFunc(NULL,
+						  GET_REQUIRED_HW_INTERFACES,
+						  &flags))
+		flags = HW_IO;
+
+	    if(NEED_IO_ENABLED(flags))
+		xorgHWAccess = TRUE;
+	    if(!(flags & HW_SKIP_CONSOLE))
+		xorgHWOpenConsole = TRUE;
+	}
+    }
+
+    if (xorgHWOpenConsole)
+	xf86OpenConsole();
+    else
+	xf86Info.dontVTSwitch = TRUE;
+
+    if (xf86BusConfig() == FALSE)
+        return;
+
+    xf86PostProbe();
+
+    /*
+     * Sort the drivers to match the requested ording.  Using a slow
+     * bubble sort.
+     */
+    for (j = 0; j < xf86NumScreens - 1; j++) {
+	for (i = 0; i < xf86NumScreens - j - 1; i++) {
+	    if (xf86Screens[i + 1]->confScreen->screennum <
+		xf86Screens[i]->confScreen->screennum) {
+		ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
+		xf86Screens[i + 1] = xf86Screens[i];
+		xf86Screens[i] = tmpScrn;
+	    }
+	}
+    }
+    /* Fix up the indexes */
+    for (i = 0; i < xf86NumScreens; i++) {
+	xf86Screens[i]->scrnIndex = i;
+    }
+
+    /*
+     * Call the driver's PreInit()'s to complete initialisation for the first
+     * generation.
+     */
+
+    for (i = 0; i < xf86NumScreens; i++) {
+	xf86VGAarbiterScrnInit(xf86Screens[i]);
+	xf86VGAarbiterLock(xf86Screens[i]);
+	if (xf86Screens[i]->PreInit &&
+	    xf86Screens[i]->PreInit(xf86Screens[i], 0))
+	    xf86Screens[i]->configured = TRUE;
+	xf86VGAarbiterUnlock(xf86Screens[i]);
+    }
+    for (i = 0; i < xf86NumScreens; i++)
+	if (!xf86Screens[i]->configured)
+	    xf86DeleteScreen(i--, 0);
+
+    /*
+     * If no screens left, return now.
+     */
+
+    if (xf86NumScreens == 0) {
+      xf86Msg(X_ERROR,
+	      "Screen(s) found, but none have a usable configuration.\n");
+      return;
+    }
+
+    for (i = 0; i < xf86NumScreens; i++) {
+      if (xf86Screens[i]->name == NULL) {
+	XNFasprintf(&xf86Screens[i]->name, "screen%d", i);
+	xf86MsgVerb(X_WARNING, 0,
+		    "Screen driver %d has no name set, using `%s'.\n",
+		    i, xf86Screens[i]->name);
+      }
+    }
+
+    /* Remove (unload) drivers that are not required */
+    for (i = 0; i < xf86NumDrivers; i++)
+	if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
+	    xf86DeleteDriver(i);
+
+    /*
+     * At this stage we know how many screens there are.
+     */
+
+    for (i = 0; i < xf86NumScreens; i++)
+      xf86InitViewport(xf86Screens[i]);
+
+    /*
+     * Collect all pixmap formats and check for conflicts at the display
+     * level.  Should we die here?  Or just delete the offending screens?
+     */
+    screenpix24 = Pix24DontCare;
+    for (i = 0; i < xf86NumScreens; i++) {
+	if (xf86Screens[i]->imageByteOrder !=
+	    xf86Screens[0]->imageByteOrder)
+	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
+	if (xf86Screens[i]->bitmapScanlinePad !=
+	    xf86Screens[0]->bitmapScanlinePad)
+	    FatalError("Inconsistent display bitmapScanlinePad.  Exiting\n");
+	if (xf86Screens[i]->bitmapScanlineUnit !=
+	    xf86Screens[0]->bitmapScanlineUnit)
+	    FatalError("Inconsistent display bitmapScanlineUnit.  Exiting\n");
+	if (xf86Screens[i]->bitmapBitOrder !=
+	    xf86Screens[0]->bitmapBitOrder)
+	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
+
+	/* Determine the depth 24 pixmap format the screens would like */
+	if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
+	    if (screenpix24 == Pix24DontCare)
+		screenpix24 = xf86Screens[i]->pixmap24;
+	    else if (screenpix24 != xf86Screens[i]->pixmap24)
+		FatalError("Inconsistent depth 24 pixmap format.  Exiting\n");
+	}
+    }
+    /* check if screenpix24 is consistent with the config/cmdline */
+    if (xf86Info.pixmap24 != Pix24DontCare) {
+	pix24 = xf86Info.pixmap24;
+	pix24From = xf86Info.pix24From;
+	if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
+	    pix24Fail = TRUE;
+    } else if (screenpix24 != Pix24DontCare) {
+	pix24 = screenpix24;
+	pix24From = X_PROBED;
+    } else
+	pix24 = Pix24Use32;
+
+    if (pix24Fail)
+	FatalError("Screen(s) can't use the required depth 24 pixmap format"
+		   " (%d).  Exiting\n", PIX24TOBPP(pix24));
+
+    /* Initialise the depth 24 format */
+    for (j = 0; j < numFormats && formats[j].depth != 24; j++)
+	;
+    formats[j].bitsPerPixel = PIX24TOBPP(pix24);
+
+    /* Collect additional formats */
+    for (i = 0; i < xf86NumScreens; i++) {
+	for (j = 0; j < xf86Screens[i]->numFormats; j++) {
+	    for (k = 0; ; k++) {
+		if (k >= numFormats) {
+		    if (k >= MAXFORMATS)
+			FatalError("Too many pixmap formats!  Exiting\n");
+		    formats[k] = xf86Screens[i]->formats[j];
+		    numFormats++;
+		    break;
+		}
+		if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
+		    if ((formats[k].bitsPerPixel ==
+			 xf86Screens[i]->formats[j].bitsPerPixel) &&
+		        (formats[k].scanlinePad ==
+			 xf86Screens[i]->formats[j].scanlinePad))
+			break;
+		    FatalError("Inconsistent pixmap format for depth %d."
+			       "  Exiting\n", formats[k].depth);
+		}
+	    }
+	}
+    }
+    formatsDone = TRUE;
+
+    if (xf86Info.vtno >= 0 ) {
+#define VT_ATOM_NAME         "XFree86_VT"
+      Atom VTAtom=-1;
+      CARD32  *VT = NULL;
+      int  ret;
+
+      /* This memory needs to stay available until the screen has been
+	 initialized, and we can create the property for real.
+      */
+      if ( (VT = malloc(sizeof(CARD32)))==NULL ) {
+	FatalError("Unable to make VT property - out of memory. Exiting...\n");
+      }
+      *VT = xf86Info.vtno;
+
+      VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
+
+      for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
+	ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
+					     VTAtom, XA_INTEGER, 32,
+					     1, VT );
+	if (ret != Success)
+	  xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
+		     "Failed to register VT property\n");
+      }
+    }
+
+    /* If a screen uses depth 24, show what the pixmap format is */
+    for (i = 0; i < xf86NumScreens; i++) {
+	if (xf86Screens[i]->depth == 24) {
+	    xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
+		    PIX24TOBPP(pix24));
+	    break;
+	}
+    }
+  } else {
+    /*
+     * serverGeneration != 1; some OSs have to do things here, too.
+     */
+    if (xorgHWOpenConsole)
+	xf86OpenConsole();
+
+#ifdef XF86PM
+    /*
+      should we reopen it here? We need to deal with an already opened
+      device. We could leave this to the OS layer. For now we simply
+      close it here
+    */
+    if (xf86OSPMClose)
+        xf86OSPMClose();
+    if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
+	xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
+#endif
+
+    /* Make sure full I/O access is enabled */
+    if (xorgHWAccess)
+	xf86EnableIO();
+  }
+
+  /*
+   * Use the previously collected parts to setup pScreenInfo
+   */
+
+  pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
+  pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
+  pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
+  pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
+  pScreenInfo->numPixmapFormats = numFormats;
+  for (i = 0; i < numFormats; i++)
+    pScreenInfo->formats[i] = formats[i];
+
+  /* Make sure the server's VT is active */
+
+  if (serverGeneration != 1) {
+    xf86Resetting = TRUE;
+    /* All screens are in the same state, so just check the first */
+    if (!xf86Screens[0]->vtSema) {
+#ifdef HAS_USL_VTS
+      ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
+#endif
+      xf86AccessEnter();
+      was_blocked = xf86BlockSIGIO();
+    }
+  }
+
+  for (i = 0; i < xf86NumScreens; i++)
+      if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
+	  FatalError("Cannot register DDX private keys");
+
+  if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) ||
+      !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0))
+      FatalError("Cannot register DDX private keys");
+
+  for (i = 0; i < xf86NumScreens; i++) {
+	xf86VGAarbiterLock(xf86Screens[i]);
+	/*
+	 * Almost everything uses these defaults, and many of those that
+	 * don't, will wrap them.
+	 */
+	xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+#ifdef XFreeXDGA
+	xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
+#endif
+	xf86Screens[i]->DPMSSet = NULL;
+	xf86Screens[i]->LoadPalette = NULL;
+	xf86Screens[i]->SetOverscan = NULL;
+	xf86Screens[i]->DriverFunc = NULL;
+	xf86Screens[i]->pScreen = NULL;
+	scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
+	xf86VGAarbiterUnlock(xf86Screens[i]);
+      if (scr_index == i) {
+	/*
+	 * Hook in our ScrnInfoRec, and initialise some other pScreen
+	 * fields.
+	 */
+	dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
+		      xf86ScreenKey, xf86Screens[i]);
+	xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
+	/* The driver should set this, but make sure it is set anyway */
+	xf86Screens[i]->vtSema = TRUE;
+      } else {
+	/* This shouldn't normally happen */
+	FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
+      }
+
+      DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
+	     i, xf86Screens[i]->pScreen );
+      DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
+	     i, xf86Screens[i]->pScreen->CreateWindow );
+
+      dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
+		    xf86CreateRootWindowKey,
+		    xf86Screens[i]->pScreen->CreateWindow);
+      xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
+
+    if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
+    {
+	xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
+	PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
+				 DDC ?
+				 (DDC->features.input_type ?
+				  SubPixelHorizontalRGB : SubPixelNone) :
+				 SubPixelUnknown);
+    }
+#ifdef RANDR
+    if (!xf86Info.disableRandR)
+	xf86RandRInit (screenInfo.screens[scr_index]);
+    xf86Msg(xf86Info.randRFrom, "RandR %s\n",
+	    xf86Info.disableRandR ? "disabled" : "enabled");
+#endif
+  }
+
+  xf86VGAarbiterWrapFunctions();
+  xf86UnblockSIGIO(was_blocked);
+
+  xf86InitOrigins();
+
+  xf86Resetting = FALSE;
+  xf86Initialising = FALSE;
+
+  RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
+				 NULL);
+}
+
+/*
+ * InitInput --
+ *      Initialize all supported input devices.
+ */
+
+void
+InitInput(int argc, char **argv)
+{
+    InputInfoPtr* pDev;
+    DeviceIntPtr dev;
+
+    xf86Info.vtRequestsPending = FALSE;
+
+    mieqInit();
+
+    GetEventList(&xf86Events);
+
+    /* Initialize all configured input devices */
+    for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
+        /* Replace obsolete keyboard driver with kbd */
+        if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
+            strcpy((*pDev)->driver, "kbd");
+        }
+
+        /* If one fails, the others will too */
+        if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc)
+            break;
+    }
+
+    config_init();
+}
+
+void
+CloseInput (void)
+{
+    config_fini();
+}
+
+/*
+ * OsVendorInit --
+ *      OS/Vendor-specific initialisations.  Called from OsInit(), which
+ *      is called by dix before establishing the well known sockets.
+ */
+
+void
+OsVendorInit(void)
+{
+  static Bool beenHere = FALSE;
+
+  signal(SIGCHLD, SIG_DFL);	/* Need to wait for child processes */
+
+  if (!beenHere) {
+    umask(022);
+    xf86LogInit();
+  }
+
+        /* Set stderr to non-blocking. */
+#ifndef O_NONBLOCK
+#if defined(FNDELAY)
+#define O_NONBLOCK FNDELAY
+#elif defined(O_NDELAY)
+#define O_NONBLOCK O_NDELAY
+#endif
+
+#ifdef O_NONBLOCK
+  if (!beenHere) {
+    if (geteuid() == 0 && getuid() != geteuid())
+    {
+      int status;
+
+      status = fcntl(fileno(stderr), F_GETFL, 0);
+      if (status != -1) {
+	fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
+      }
+    }
+  }
+#endif
+#endif
+
+  beenHere = TRUE;
+}
+
+/*
+ * ddxGiveUp --
+ *      Device dependent cleanup. Called by by dix before normal server death.
+ *      For SYSV386 we must switch the terminal back to normal mode. No error-
+ *      checking here, since there should be restored as much as possible.
+ */
+
+void
+ddxGiveUp(void)
+{
+    int i;
+
+    xf86VGAarbiterFini();
+
+#ifdef XF86PM
+    if (xf86OSPMClose)
+	xf86OSPMClose();
+    xf86OSPMClose = NULL;
+#endif
+
+    for (i = 0; i < xf86NumScreens; i++) {
+	/*
+	 * zero all access functions to
+	 * trap calls when switched away.
+	 */
+	xf86Screens[i]->vtSema = FALSE;
+    }
+
+#ifdef XFreeXDGA
+    DGAShutdown();
+#endif
+
+    if (xorgHWOpenConsole)
+	xf86CloseConsole();
+
+    xf86CloseLog();
+
+    /* If an unexpected signal was caught, dump a core for debugging */
+    if (xf86Info.caughtSignal)
+	OsAbort();
+}
+
+
+
+/*
+ * AbortDDX --
+ *      DDX - specific abort routine.  Called by AbortServer(). The attempt is
+ *      made to restore all original setting of the displays. Also all devices
+ *      are closed.
+ */
+
+void
+AbortDDX(void)
+{
+  int i;
+
+  xf86BlockSIGIO();
+
+  /*
+   * try to restore the original video state
+   */
+#ifdef DPMSExtension /* Turn screens back on */
+  if (DPMSPowerLevel != DPMSModeOn)
+      DPMSSet(serverClient, DPMSModeOn);
+#endif
+  if (xf86Screens) {
+      for (i = 0; i < xf86NumScreens; i++)
+	  if (xf86Screens[i]->vtSema) {
+	      /*
+	       * if we are aborting before ScreenInit() has finished
+	       * we might not have been wrapped yet. Therefore enable
+	       * screen explicitely.
+	       */
+	      xf86VGAarbiterLock(xf86Screens[i]);
+	      (xf86Screens[i]->LeaveVT)(i, 0);
+	      xf86VGAarbiterUnlock(xf86Screens[i]);
+	  }
+  }
+
+  xf86AccessLeave();
+
+  /*
+   * This is needed for an abnormal server exit, since the normal exit stuff
+   * MUST also be performed (i.e. the vt must be left in a defined state)
+   */
+  ddxGiveUp();
+}
+
+void
+OsVendorFatalError(void)
+{
+#ifdef VENDORSUPPORT
+    ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
+	   "at %s for support on this crash.\n",VENDORSUPPORT);
+#else
+    ErrorF("\nPlease consult the "XVENDORNAME" support \n"
+	   "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
+#endif
+    if (xf86LogFile && xf86LogFileWasOpened)
+	ErrorF("Please also check the log file at \"%s\" for additional "
+              "information.\n", xf86LogFile);
+    ErrorF("\n");
+}
+
+int
+xf86SetVerbosity(int verb)
+{
+    int save = xf86Verbose;
+
+    xf86Verbose = verb;
+    LogSetParameter(XLOG_VERBOSITY, verb);
+    return save;
+}
+
+int
+xf86SetLogVerbosity(int verb)
+{
+    int save = xf86LogVerbose;
+
+    xf86LogVerbose = verb;
+    LogSetParameter(XLOG_FILE_VERBOSITY, verb);
+    return save;
+}
+
+static void
+xf86PrintDefaultModulePath(void)
+{
+  ErrorF("%s\n", DEFAULT_MODULE_PATH);
+}
+
+static void
+xf86PrintDefaultLibraryPath(void)
+{
+  ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
+}
+
+/*
+ * ddxProcessArgument --
+ *	Process device-dependent command line args. Returns 0 if argument is
+ *      not device dependent, otherwise Count of number of elements of argv
+ *      that are part of a device dependent commandline option.
+ *
+ */
+
+/* ARGSUSED */
+int
+ddxProcessArgument(int argc, char **argv, int i)
+{
+#define CHECK_FOR_REQUIRED_ARGUMENT() \
+    if (((i + 1) >= argc) || (!argv[i + 1])) { 				\
+      ErrorF("Required argument to %s not specified\n", argv[i]); 	\
+      UseMsg(); 							\
+      FatalError("Required argument to %s not specified\n", argv[i]);	\
+    }
+
+  /* First the options that are only allowed for root */
+  if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
+    if ( (geteuid() == 0) && (getuid() != 0) ) {
+      FatalError("The '%s' option can only be used by root.\n", argv[i]);
+    }
+    else if (!strcmp(argv[i], "-modulepath"))
+    {
+      char *mp;
+      CHECK_FOR_REQUIRED_ARGUMENT();
+      mp = strdup(argv[i + 1]);
+      if (!mp)
+	FatalError("Can't allocate memory for ModulePath\n");
+      xf86ModulePath = mp;
+      xf86ModPathFrom = X_CMDLINE;
+      return 2;
+    }
+    else if (!strcmp(argv[i], "-logfile"))
+    {
+      char *lf;
+      CHECK_FOR_REQUIRED_ARGUMENT();
+      lf = strdup(argv[i + 1]);
+      if (!lf)
+	FatalError("Can't allocate memory for LogFile\n");
+      xf86LogFile = lf;
+      xf86LogFileFrom = X_CMDLINE;
+      return 2;
+    }
+  }
+  if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
+  {
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+      FatalError("\nInvalid argument for %s\n"
+	  "\tFor non-root users, the file specified with %s must be\n"
+	  "\ta relative path and must not contain any \"..\" elements.\n"
+	  "\tUsing default "__XCONFIGFILE__" search path.\n\n",
+	  argv[i], argv[i]);
+    }
+    xf86ConfigFile = argv[i + 1];
+    return 2;
+  }
+  if (!strcmp(argv[i], "-configdir"))
+  {
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+      FatalError("\nInvalid argument for %s\n"
+	  "\tFor non-root users, the file specified with %s must be\n"
+	  "\ta relative path and must not contain any \"..\" elements.\n"
+	  "\tUsing default "__XCONFIGDIR__" search path.\n\n",
+	  argv[i], argv[i]);
+    }
+    xf86ConfigDir = argv[i + 1];
+    return 2;
+  }
+  if (!strcmp(argv[i],"-flipPixels"))
+  {
+    xf86FlipPixels = TRUE;
+    return 1;
+  }
+#ifdef XF86VIDMODE
+  if (!strcmp(argv[i],"-disableVidMode"))
+  {
+    xf86VidModeDisabled = TRUE;
+    return 1;
+  }
+  if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
+  {
+    xf86VidModeAllowNonLocal = TRUE;
+    return 1;
+  }
+#endif
+  if (!strcmp(argv[i],"-allowMouseOpenFail"))
+  {
+    xf86AllowMouseOpenFail = TRUE;
+    return 1;
+  }
+  if (!strcmp(argv[i],"-ignoreABI"))
+  {
+    LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
+    return 1;
+  }
+  if (!strcmp(argv[i],"-verbose"))
+  {
+    if (++i < argc && argv[i])
+    {
+      char *end;
+      long val;
+      val = strtol(argv[i], &end, 0);
+      if (*end == '\0')
+      {
+	xf86SetVerbosity(val);
+	return 2;
+      }
+    }
+    xf86SetVerbosity(++xf86Verbose);
+    return 1;
+  }
+  if (!strcmp(argv[i],"-logverbose"))
+  {
+    if (++i < argc && argv[i])
+    {
+      char *end;
+      long val;
+      val = strtol(argv[i], &end, 0);
+      if (*end == '\0')
+      {
+	xf86SetLogVerbosity(val);
+	return 2;
+      }
+    }
+    xf86SetLogVerbosity(++xf86LogVerbose);
+    return 1;
+  }
+  if (!strcmp(argv[i],"-quiet"))
+  {
+    xf86SetVerbosity(-1);
+    return 1;
+  }
+  if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
+  {
+    xf86PrintBanner();
+    exit(0);
+  }
+  if (!strcmp(argv[i],"-showDefaultModulePath"))
+  {
+    xf86PrintDefaultModulePath();
+    exit(0);
+  }
+  if (!strcmp(argv[i],"-showDefaultLibPath"))
+  {
+    xf86PrintDefaultLibraryPath();
+    exit(0);
+  }
+  /* Notice the -fp flag, but allow it to pass to the dix layer */
+  if (!strcmp(argv[i], "-fp"))
+  {
+    xf86fpFlag = TRUE;
+    return 0;
+  }
+  /* Notice the -bs flag, but allow it to pass to the dix layer */
+  if (!strcmp(argv[i], "-bs"))
+  {
+    xf86bsDisableFlag = TRUE;
+    return 0;
+  }
+  /* Notice the +bs flag, but allow it to pass to the dix layer */
+  if (!strcmp(argv[i], "+bs"))
+  {
+    xf86bsEnableFlag = TRUE;
+    return 0;
+  }
+  /* Notice the -s flag, but allow it to pass to the dix layer */
+  if (!strcmp(argv[i], "-s"))
+  {
+    xf86sFlag = TRUE;
+    return 0;
+  }
+  if (!strcmp(argv[i], "-pixmap24"))
+  {
+    xf86Pix24 = Pix24Use24;
+    return 1;
+  }
+  if (!strcmp(argv[i], "-pixmap32"))
+  {
+    xf86Pix24 = Pix24Use32;
+    return 1;
+  }
+  if (!strcmp(argv[i], "-fbbpp"))
+  {
+    int bpp;
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    if (sscanf(argv[++i], "%d", &bpp) == 1)
+    {
+      xf86FbBpp = bpp;
+      return 2;
+    }
+    else
+    {
+      ErrorF("Invalid fbbpp\n");
+      return 0;
+    }
+  }
+  if (!strcmp(argv[i], "-depth"))
+  {
+    int depth;
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    if (sscanf(argv[++i], "%d", &depth) == 1)
+    {
+      xf86Depth = depth;
+      return 2;
+    }
+    else
+    {
+      ErrorF("Invalid depth\n");
+      return 0;
+    }
+  }
+  if (!strcmp(argv[i], "-weight"))
+  {
+    int red, green, blue;
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
+    {
+      xf86Weight.red = red;
+      xf86Weight.green = green;
+      xf86Weight.blue = blue;
+      return 2;
+    }
+    else
+    {
+      ErrorF("Invalid weighting\n");
+      return 0;
+    }
+  }
+  if (!strcmp(argv[i], "-gamma")  || !strcmp(argv[i], "-rgamma") ||
+      !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
+  {
+    double gamma;
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    if (sscanf(argv[++i], "%lf", &gamma) == 1) {
+       if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
+	  ErrorF("gamma out of range, only  %.2f <= gamma_value <= %.1f"
+		 " is valid\n", GAMMA_MIN, GAMMA_MAX);
+	  return 0;
+       }
+       if (!strcmp(argv[i-1], "-gamma"))
+	  xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
+       else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
+       else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
+       else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
+       return 2;
+    }
+  }
+  if (!strcmp(argv[i], "-layout"))
+  {
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    xf86LayoutName = argv[++i];
+    return 2;
+  }
+  if (!strcmp(argv[i], "-screen"))
+  {
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    xf86ScreenName = argv[++i];
+    return 2;
+  }
+  if (!strcmp(argv[i], "-pointer"))
+  {
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    xf86PointerName = argv[++i];
+    return 2;
+  }
+  if (!strcmp(argv[i], "-keyboard"))
+  {
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    xf86KeyboardName = argv[++i];
+    return 2;
+  }
+  if (!strcmp(argv[i], "-nosilk"))
+  {
+    xf86silkenMouseDisableFlag = TRUE;
+    return 1;
+  }
+#ifdef HAVE_ACPI
+  if (!strcmp(argv[i], "-noacpi"))
+  {
+    xf86acpiDisableFlag = TRUE;
+    return 1;
+  }
+#endif
+  if (!strcmp(argv[i], "-configure"))
+  {
+    if (getuid() != 0 && geteuid() == 0) {
+	ErrorF("The '-configure' option can only be used by root.\n");
+	exit(1);
+    }
+    xf86DoConfigure = TRUE;
+    xf86AllowMouseOpenFail = TRUE;
+    return 1;
+  }
+  if (!strcmp(argv[i], "-showopts"))
+  {
+    if (getuid() != 0 && geteuid() == 0) {
+    ErrorF("The '-showopts' option can only be used by root.\n");
+    exit(1);
+    }
+    xf86DoShowOptions = TRUE;
+    return 1;
+  }
+  if (!strcmp(argv[i], "-isolateDevice"))
+  {
+    CHECK_FOR_REQUIRED_ARGUMENT();
+    if (strncmp(argv[++i], "PCI:", 4)) {
+       FatalError("Bus types other than PCI not yet isolable\n");
+    }
+    xf86PciIsolateDevice(argv[i]);
+    return 2;
+  }
+  /* Notice cmdline xkbdir, but pass to dix as well */
+  if (!strcmp(argv[i], "-xkbdir"))
+  {
+    xf86xkbdirFlag = TRUE;
+    return 0;
+  }
+
+  /* OS-specific processing */
+  return xf86ProcessArgument(argc, argv, i);
+}
+
+/*
+ * ddxUseMsg --
+ *	Print out correct use of device dependent commandline options.
+ *      Maybe the user now knows what really to do ...
+ */
+
+void
+ddxUseMsg(void)
+{
+  ErrorF("\n");
+  ErrorF("\n");
+  ErrorF("Device Dependent Usage\n");
+  if (getuid() == 0 || geteuid() != 0)
+  {
+    ErrorF("-modulepath paths      specify the module search path\n");
+    ErrorF("-logfile file          specify a log file name\n");
+    ErrorF("-configure             probe for devices and write an "__XCONFIGFILE__"\n");
+    ErrorF("-showopts              print available options for all installed drivers\n");
+  }
+  ErrorF("-config file           specify a configuration file, relative to the\n");
+  ErrorF("                       "__XCONFIGFILE__" search path, only root can use absolute\n");
+  ErrorF("-configdir dir         specify a configuration directory, relative to the\n");
+  ErrorF("                       "__XCONFIGDIR__" search path, only root can use absolute\n");
+  ErrorF("-verbose [n]           verbose startup messages\n");
+  ErrorF("-logverbose [n]        verbose log messages\n");
+  ErrorF("-quiet                 minimal startup messages\n");
+  ErrorF("-pixmap24              use 24bpp pixmaps for depth 24\n");
+  ErrorF("-pixmap32              use 32bpp pixmaps for depth 24\n");
+  ErrorF("-fbbpp n               set bpp for the framebuffer. Default: 8\n");
+  ErrorF("-depth n               set colour depth. Default: 8\n");
+  ErrorF("-gamma f               set gamma value (0.1 < f < 10.0) Default: 1.0\n");
+  ErrorF("-rgamma f              set gamma value for red phase\n");
+  ErrorF("-ggamma f              set gamma value for green phase\n");
+  ErrorF("-bgamma f              set gamma value for blue phase\n");
+  ErrorF("-weight nnn            set RGB weighting at 16 bpp.  Default: 565\n");
+  ErrorF("-layout name           specify the ServerLayout section name\n");
+  ErrorF("-screen name           specify the Screen section name\n");
+  ErrorF("-keyboard name         specify the core keyboard InputDevice name\n");
+  ErrorF("-pointer name          specify the core pointer InputDevice name\n");
+  ErrorF("-nosilk                disable Silken Mouse\n");
+  ErrorF("-flipPixels            swap default black/white Pixel values\n");
+#ifdef XF86VIDMODE
+  ErrorF("-disableVidMode        disable mode adjustments with xvidtune\n");
+  ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
+#endif
+  ErrorF("-allowMouseOpenFail    start server even if the mouse can't be initialized\n");
+  ErrorF("-ignoreABI             make module ABI mismatches non-fatal\n");
+  ErrorF("-isolateDevice bus_id  restrict device resets to bus_id (PCI only)\n");
+  ErrorF("-version               show the server version\n");
+  ErrorF("-showDefaultModulePath show the server default module path\n");
+  ErrorF("-showDefaultLibPath    show the server default library path\n");
+  /* OS-specific usage */
+  xf86UseMsg();
+  ErrorF("\n");
+}
+
+
+/*
+ * xf86LoadModules iterates over a list that is being passed in.
+ */
+Bool
+xf86LoadModules(char **list, pointer *optlist)
+{
+    int errmaj, errmin;
+    pointer opt;
+    int i;
+    char *name;
+    Bool failed = FALSE;
+
+    if (!list)
+	return TRUE;
+
+    for (i = 0; list[i] != NULL; i++) {
+
+	/* Normalise the module name */
+	name = xf86NormalizeName(list[i]);
+
+	/* Skip empty names */
+	if (name == NULL || *name == '\0')
+	    continue;
+
+	/* Replace obsolete keyboard driver with kbd */
+	if (!xf86NameCmp(name, "keyboard")) {
+	    strcpy(name, "kbd");
+	}
+
+	if (optlist)
+	    opt = optlist[i];
+	else
+	    opt = NULL;
+
+        if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
+	    LoaderErrorMsg(NULL, name, errmaj, errmin);
+	    failed = TRUE;
+	}
+	free(name);
+    }
+    return !failed;
+}
+
+/* Pixmap format stuff */
+
+PixmapFormatPtr
+xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
+{
+    int i;
+    static PixmapFormatRec format;	/* XXX not reentrant */
+
+    /*
+     * When the formats[] list initialisation isn't complete, check the
+     * depth 24 pixmap config/cmdline options and screen-specified formats.
+     */
+
+    if (!formatsDone) {
+	if (depth == 24) {
+	    Pix24Flags pix24 = Pix24DontCare;
+
+	    format.depth = 24;
+	    format.scanlinePad = BITMAP_SCANLINE_PAD;
+	    if (xf86Info.pixmap24 != Pix24DontCare)
+		pix24 = xf86Info.pixmap24;
+	    else if (pScrn->pixmap24 != Pix24DontCare)
+		pix24 = pScrn->pixmap24;
+	    if (pix24 == Pix24Use24)
+		format.bitsPerPixel = 24;
+	    else
+		format.bitsPerPixel = 32;
+	    return &format;
+	}
+    }
+
+    for (i = 0; i < numFormats; i++)
+	if (formats[i].depth == depth)
+	   break;
+    if (i != numFormats)
+	return &formats[i];
+    else if (!formatsDone) {
+	/* Check for screen-specified formats */
+	for (i = 0; i < pScrn->numFormats; i++)
+	    if (pScrn->formats[i].depth == depth)
+		break;
+	if (i != pScrn->numFormats)
+	    return &pScrn->formats[i];
+    }
+    return NULL;
+}
+
+int
+xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
+{
+    PixmapFormatPtr format;
+
+
+    format = xf86GetPixFormat(pScrn, depth);
+    if (format)
+	return format->bitsPerPixel;
+    else
+	return 0;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86VidMode.c b/xorg-server/hw/xfree86/common/xf86VidMode.c
index 591c338b1..eb29fd09e 100644
--- a/xorg-server/hw/xfree86/common/xf86VidMode.c
+++ b/xorg-server/hw/xfree86/common/xf86VidMode.c
@@ -634,7 +634,7 @@ VidModeSetModeValue(pointer mode, int valtyp, int val)
 vidMonitorValue
 VidModeGetMonitorValue(pointer monitor, int valtyp, int indx)
 {
-  vidMonitorValue ret;
+  vidMonitorValue ret = { NULL, };
   
   switch (valtyp) {
     case VIDMODE_MON_VENDOR:
diff --git a/xorg-server/hw/xfree86/common/xf86xv.c b/xorg-server/hw/xfree86/common/xf86xv.c
index 9f62a8397..8115075b3 100644
--- a/xorg-server/hw/xfree86/common/xf86xv.c
+++ b/xorg-server/hw/xfree86/common/xf86xv.c
@@ -97,8 +97,11 @@ static int xf86XVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
 
 static Bool xf86XVDestroyWindow(WindowPtr pWin);
 static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
+static void xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind);
 static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
 
+#define PostValidateTreeUndefined ((PostValidateTreeProcPtr)-1)
+
 /* ScrnInfoRec functions */
 
 static Bool xf86XVEnterVT(int, int);
@@ -280,10 +283,9 @@ xf86XVScreenInit(
 
   pScrn = xf86Screens[pScreen->myNum];
 
-  ScreenPriv->videoGC = NULL;  /* for the helper */
-
   ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
   ScreenPriv->WindowExposures = pScreen->WindowExposures;
+  ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
   ScreenPriv->ClipNotify = pScreen->ClipNotify;
   ScreenPriv->EnterVT = pScrn->EnterVT;
   ScreenPriv->LeaveVT = pScrn->LeaveVT;
@@ -333,6 +335,8 @@ xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
 		RegionDestroy(pPriv->clientClip);
 	     if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
 		RegionDestroy(pPriv->pCompositeClip);
+	     if (pPriv->ckeyFilled)
+		RegionDestroy(pPriv->ckeyFilled);
 	     free(pPriv);
 	  }
       }
@@ -1018,7 +1022,6 @@ static void
 xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
 {
      XF86XVWindowPtr winPriv, prevPriv = NULL;
-
      winPriv = GET_XF86XV_WINDOW(pWin);
 
      while(winPriv) {
@@ -1035,6 +1038,11 @@ xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
 	winPriv = winPriv->next;
      }
      portPriv->pDraw = NULL;
+     if (portPriv->ckeyFilled) {
+	RegionDestroy(portPriv->ckeyFilled);
+	portPriv->ckeyFilled = NULL;
+     }
+     portPriv->clipChanged = FALSE;
 }
 
 static void
@@ -1069,7 +1077,7 @@ xf86XVReputOrStopPort(XvPortRecPrivatePtr pPriv,
 }
 
 static void
-xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn)
+xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn, Bool onlyChanged)
 {
     ScreenPtr pScreen = pScrn->pScreen;
     XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
@@ -1087,6 +1095,9 @@ xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn)
 	    if (pPriv->isOn == XV_OFF || !pWin)
 		continue;
 
+	    if (onlyChanged && !pPriv->clipChanged)
+		continue;
+
 	    visible = pWin->visibility == VisibilityUnobscured ||
 		      pWin->visibility == VisibilityPartiallyObscured;
 
@@ -1098,6 +1109,8 @@ xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn)
 		visible = FALSE;
 
 	    xf86XVReputOrStopPort(pPriv, pWin, visible);
+
+	    pPriv->clipChanged = FALSE;
 	}
     }
 }
@@ -1123,9 +1136,6 @@ xf86XVDestroyWindow(WindowPtr pWin)
 
      pPriv->pDraw = NULL;
      tmp = WinPriv;
-     if(WinPriv->pGC) {
-       FreeGC(WinPriv->pGC, 0);
-     }
      WinPriv = WinPriv->next;
      free(tmp);
   }
@@ -1139,6 +1149,29 @@ xf86XVDestroyWindow(WindowPtr pWin)
   return ret;
 }
 
+static void
+xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind)
+{
+    ScreenPtr pScreen;
+    XF86XVScreenPtr ScreenPriv;
+    ScrnInfoPtr pScrn;
+
+    if (pWin)
+	pScreen = pWin->drawable.pScreen;
+    else
+	pScreen = pLayerWin->drawable.pScreen;
+
+    ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+    pScrn = xf86Screens[pScreen->myNum];
+
+    xf86XVReputOrStopAllPorts(pScrn, TRUE);
+
+    pScreen->PostValidateTree = ScreenPriv->PostValidateTree;
+    if (pScreen->PostValidateTree) {
+	(*pScreen->PostValidateTree)(pWin, pLayerWin, kind);
+    }
+    ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
+}
 
 static void
 xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
@@ -1170,12 +1203,28 @@ xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
      if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
 	visible = !AreasExposed;
 
+     /*
+      * Subtract exposed areas from overlaid image to match textured video
+      * behavior.
+      */
+     if (!pPriv->type && pPriv->clientClip)
+	    RegionSubtract(pPriv->clientClip, pPriv->clientClip, reg1);
+
+     if (visible && pPriv->ckeyFilled) {
+        RegionRec tmp;
+        RegionNull(&tmp);
+        RegionCopy(&tmp, reg1);
+        RegionTranslate(&tmp, pWin->drawable.x, pWin->drawable.y);
+        RegionSubtract(pPriv->ckeyFilled, pPriv->ckeyFilled, &tmp);
+     }
+
      WinPriv = WinPriv->next;
      xf86XVReputOrStopPort(pPriv, pWin, visible);
+
+     pPriv->clipChanged = FALSE;
   }
 }
 
-
 static void
 xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
 {
@@ -1185,9 +1234,6 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
   XvPortRecPrivatePtr pPriv;
 
   while(WinPriv) {
-     Bool visible = pWin->visibility == VisibilityUnobscured ||
-		    pWin->visibility == VisibilityPartiallyObscured;
-
      pPriv = WinPriv->PortRec;
 
      if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
@@ -1199,15 +1245,14 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
         (*pPriv->AdaptorRec->ClipNotify)(pPriv->pScrn, pPriv->DevPriv.ptr,
                                          pWin, dx, dy);
 
-     /*
-      * Stop and remove still/images if
-      * ReputImage isn't supported.
-      */
-     if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
-	visible = FALSE;
+     pPriv->clipChanged = TRUE;
+
+     if (ScreenPriv->PostValidateTree == PostValidateTreeUndefined) {
+        ScreenPriv->PostValidateTree = pScreen->PostValidateTree;
+        pScreen->PostValidateTree = xf86XVPostValidateTree;
+     }
 
      WinPriv = WinPriv->next;
-     xf86XVReputOrStopPort(pPriv, pWin, visible);
   }
 
   if(ScreenPriv->ClipNotify) {
@@ -1232,11 +1277,6 @@ xf86XVCloseScreen(int i, ScreenPtr pScreen)
 
   if(!ScreenPriv) return TRUE;
 
-  if(ScreenPriv->videoGC) {
-     FreeGC(ScreenPriv->videoGC, 0);
-     ScreenPriv->videoGC = NULL;
-  }
-
   pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
   pScreen->WindowExposures = ScreenPriv->WindowExposures;
   pScreen->ClipNotify = ScreenPriv->ClipNotify;
@@ -1345,7 +1385,7 @@ xf86XVAdjustFrame(int index, int x, int y, int flags)
 	pScrn->AdjustFrame = xf86XVAdjustFrame;
   }
 
-  xf86XVReputOrStopAllPorts(pScrn);
+  xf86XVReputOrStopAllPorts(pScrn, FALSE);
 }
 
 static void
@@ -1366,7 +1406,7 @@ xf86XVModeSet(ScrnInfoPtr pScrn)
 	pScrn->ModeSet = xf86XVModeSet;
     }
 
-    xf86XVReputOrStopAllPorts(pScrn);
+    xf86XVReputOrStopAllPorts(pScrn, FALSE);
 }
 
 /**** XvAdaptorRec fields ****/
@@ -1869,92 +1909,92 @@ xf86XVQueryImageAttributes(
 			format->id, width, height, pitches, offsets);
 }
 
-
 void
-xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes)
+xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr fillboxes)
 {
    ScreenPtr pScreen = pDraw->pScreen;
-   WindowPtr pWin = (WindowPtr)pDraw;
-   XF86XVWindowPtr pPriv = GET_XF86XV_WINDOW(pWin);
-   GCPtr pGC = NULL;
-   BoxPtr pbox = RegionRects(clipboxes);
-   int i, nbox = RegionNumRects(clipboxes);
-   xRectangle *rects;
-
-   if(!xf86Screens[pScreen->myNum]->vtSema) return;
-
-   if(pPriv)
-      pGC = pPriv->pGC;
-
-   if(!pGC) {
-       int status;
-       XID pval[2];
-       pval[0] = key;
-       pval[1] = IncludeInferiors;
-       pGC = CreateGC(pDraw, GCForeground | GCSubwindowMode, pval, &status,
-		      (XID)0, serverClient);
-       if(!pGC) return;
-       ValidateGC(pDraw, pGC);
-       if (pPriv) pPriv->pGC = pGC;
-   } else if (key != pGC->fgPixel){
-       ChangeGCVal val;
-       val.val = key;
-       ChangeGC(NullClient, pGC, GCForeground, &val);
-       ValidateGC(pDraw, pGC);
-   }
-
-   RegionTranslate(clipboxes, -pDraw->x, -pDraw->y);
-
-   rects = malloc(nbox * sizeof(xRectangle));
-
-   for(i = 0; i < nbox; i++, pbox++) {
-      rects[i].x = pbox->x1;
-      rects[i].y = pbox->y1;
-      rects[i].width = pbox->x2 - pbox->x1;
-      rects[i].height = pbox->y2 - pbox->y1;
-   }
-
-   (*pGC->ops->PolyFillRect)(pDraw, pGC, nbox, rects);
-
-   if (!pPriv) FreeGC(pGC, 0);
-
-   free(rects);
-}
-
-void
-xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
-{
-   DrawablePtr root = &pScreen->root->drawable;
    ChangeGCVal pval[2];
-   BoxPtr pbox = RegionRects(clipboxes);
-   int i, nbox = RegionNumRects(clipboxes);
+   BoxPtr pbox = RegionRects(fillboxes);
+   int i, nbox = RegionNumRects(fillboxes);
    xRectangle *rects;
    GCPtr gc;
 
    if(!xf86Screens[pScreen->myNum]->vtSema) return;
 
-   gc = GetScratchGC(root->depth, pScreen);
+   gc = GetScratchGC(pDraw->depth, pScreen);
    pval[0].val = key;
    pval[1].val = IncludeInferiors;
    (void) ChangeGC(NullClient, gc, GCForeground|GCSubwindowMode, pval);
-   ValidateGC(root, gc);
+   ValidateGC(pDraw, gc);
 
    rects = malloc(nbox * sizeof(xRectangle));
 
    for(i = 0; i < nbox; i++, pbox++) 
    {
-      rects[i].x = pbox->x1;
-      rects[i].y = pbox->y1;
+      rects[i].x = pbox->x1 - pDraw->x;
+      rects[i].y = pbox->y1 - pDraw->y;
       rects[i].width = pbox->x2 - pbox->x1;
       rects[i].height = pbox->y2 - pbox->y1;
    }
    
-   (*gc->ops->PolyFillRect)(root, gc, nbox, rects);
+   (*gc->ops->PolyFillRect)(pDraw, gc, nbox, rects);
    
    free(rects);
    FreeScratchGC (gc);
 }
 
+void
+xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr fillboxes)
+{
+    xf86XVFillKeyHelperDrawable (&pScreen->root->drawable, key, fillboxes);
+}
+
+void
+xf86XVFillKeyHelperPort (DrawablePtr pDraw, pointer data, CARD32 key, RegionPtr clipboxes, Bool fillEverything)
+{
+    WindowPtr pWin = (WindowPtr)pDraw;
+    XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+    XvPortRecPrivatePtr portPriv = NULL;
+    RegionRec reg;
+    RegionPtr fillboxes;
+
+    while (WinPriv) {
+	XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
+
+	if (data == pPriv->DevPriv.ptr) {
+	    portPriv = pPriv;
+	    break;
+	}
+
+	WinPriv = WinPriv->next;
+    }
+
+    if (!portPriv)
+	return;
+
+    if (!portPriv->ckeyFilled)
+	portPriv->ckeyFilled = RegionCreate(NULL, 0);
+
+    if (!fillEverything) {
+	RegionNull(&reg);
+	fillboxes = &reg;
+	RegionSubtract(fillboxes, clipboxes, portPriv->ckeyFilled);
+
+	if (!RegionNotEmpty(fillboxes))
+	    goto out;
+    } else
+	fillboxes = clipboxes;
+
+
+    RegionCopy(portPriv->ckeyFilled, clipboxes);
+
+    xf86XVFillKeyHelperDrawable(pDraw, key, fillboxes);
+out:
+    if (!fillEverything)
+        RegionUninit(&reg);
+}
+
+
 /* xf86XVClipVideoHelper -
 
    Takes the dst box in standard X BoxRec form (top and left
diff --git a/xorg-server/hw/xfree86/common/xf86xv.h b/xorg-server/hw/xfree86/common/xf86xv.h
index 25f3e4ad3..08e5c790d 100644
--- a/xorg-server/hw/xfree86/common/xf86xv.h
+++ b/xorg-server/hw/xfree86/common/xf86xv.h
@@ -244,6 +244,9 @@ xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes);
 extern _X_EXPORT void
 xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes);
 
+extern _X_EXPORT void
+xf86XVFillKeyHelperPort (DrawablePtr pDraw, pointer data, CARD32 key, RegionPtr clipboxes, Bool fillEverything);
+
 extern _X_EXPORT Bool
 xf86XVClipVideoHelper(
     BoxPtr dst,
diff --git a/xorg-server/hw/xfree86/common/xf86xvpriv.h b/xorg-server/hw/xfree86/common/xf86xvpriv.h
index 35d72ca9c..7eb46e51f 100644
--- a/xorg-server/hw/xfree86/common/xf86xvpriv.h
+++ b/xorg-server/hw/xfree86/common/xf86xvpriv.h
@@ -40,10 +40,10 @@ typedef struct {
    DestroyWindowProcPtr		DestroyWindow;
    ClipNotifyProcPtr		ClipNotify;
    WindowExposuresProcPtr	WindowExposures;
+   PostValidateTreeProcPtr	PostValidateTree;
    void                         (*AdjustFrame)(int, int, int, int);
    Bool                         (*EnterVT)(int, int);
    void                         (*LeaveVT)(int, int);
-   GCPtr			videoGC;
    xf86ModeSetProc		*ModeSet;
 } XF86XVScreenRec, *XF86XVScreenPtr;
 
@@ -69,11 +69,12 @@ typedef struct {
    unsigned char type;
    unsigned int subWindowMode;
    RegionPtr clientClip;
+   RegionPtr ckeyFilled;
    RegionPtr pCompositeClip;
    Bool FreeCompositeClip;
    XvAdaptorRecPrivatePtr AdaptorRec;
    XvStatus isOn;
-   Bool moved;
+   Bool clipChanged;
    int vid_x, vid_y, vid_w, vid_h;
    int drw_x, drw_y, drw_w, drw_h;
    DevUnion DevPriv;
@@ -82,7 +83,6 @@ typedef struct {
 typedef struct _XF86XVWindowRec{
    XvPortRecPrivatePtr PortRec;
    struct _XF86XVWindowRec *next;
-   GCPtr pGC;
 } XF86XVWindowRec, *XF86XVWindowPtr;
 
 #endif  /* _XF86XVPRIV_H_ */
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index aba2202d6..7d6f772d7 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -403,7 +403,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
 	&& (pDraw->height == pPriv->height)
 	&& (pPriv->serialNumber == DRI2DrawableSerial(pDraw));
 
-    buffers = malloc((count + 1) * sizeof(buffers[0]));
+    buffers = calloc((count + 1), sizeof(buffers[0]));
 
     for (i = 0; i < count; i++) {
 	const unsigned attachment = *(attachments++);
diff --git a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c
index 49d0bd044..ef69d58bc 100644
--- a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c
@@ -264,14 +264,7 @@ fbdev_open_pci(struct pci_device * pPci, char **namep)
 {
     struct	fb_fix_screeninfo fix;
     char	filename[256];
-    int	fd,i,j;
-
-
-    /* There are two ways to that we can determine which fb device is
-     * associated with this PCI device.  The more modern way is to look in
-     * the sysfs directory for the PCI device for a file named
-     * "graphics/fb*"
-     */
+    int	fd, i;
 
     for (i = 0; i < 8; i++) {
 	sprintf(filename, 
@@ -304,55 +297,10 @@ fbdev_open_pci(struct pci_device * pPci, char **namep)
 	}
     }
 
-
-    /* The other way is to examine the resources associated with each fb
-     * device and see if there is a match with the PCI device.  This technique
-     * has some problems on certain mixed 64-bit / 32-bit architectures.
-     * There is a flaw in the fb_fix_screeninfo structure in that it only
-     * returns the low 32-bits of the address of the resources associated with
-     * a device.  However, on a mixed architecture the base addresses of PCI
-     * devices, even for 32-bit applications, may be higher than 0x0f0000000.
-     */
-
-    for (i = 0; i < 8; i++) {
-	sprintf(filename,"/dev/fb%d",i);
-	if (-1 == (fd = open(filename,O_RDWR,0))) {
-	    xf86DrvMsg(-1, X_WARNING,
-		       "open %s: %s\n", filename, strerror(errno));
-	    continue;
-	}
-	if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)&fix)) {
-	    close(fd);
-	    continue;
-	}
-	for (j = 0; j < 6; j++) {
-	    const pciaddr_t res_start = pPci->regions[j].base_addr;
-	    const pciaddr_t res_end = res_start + pPci->regions[j].size;
-
-	    if ((0 != fix.smem_len &&
-		 (pciaddr_t) fix.smem_start >= res_start &&
-		 (pciaddr_t) fix.smem_start < res_end) ||
-		(0 != fix.mmio_len &&
-		 (pciaddr_t) fix.mmio_start >= res_start &&
-		 (pciaddr_t) fix.mmio_start < res_end))
-	      break;
-	}
-	if (j == 6) {
-	    close(fd);
-	    continue;
-	}
-	if (namep) {
-	    *namep = xnfalloc(16);
-	    strncpy(*namep,fix.id,16);
-	}
-	return fd;
-    }
-
     if (namep)
       *namep = NULL;
 
-    xf86DrvMsg(-1, X_ERROR,
-	       "Unable to find a valid framebuffer device\n");
+    xf86DrvMsg(-1, X_ERROR, "Unable to find a valid framebuffer device\n");
     return -1;
 }
 
diff --git a/xorg-server/hw/xfree86/int10/helper_exec.c b/xorg-server/hw/xfree86/int10/helper_exec.c
index b9af473b1..1043fcde7 100644
--- a/xorg-server/hw/xfree86/int10/helper_exec.c
+++ b/xorg-server/hw/xfree86/int10/helper_exec.c
@@ -1,733 +1,733 @@
-/*
- *                   XFree86 int10 module
- *   execute BIOS int 10h calls in x86 real mode environment
- *                 Copyright 1999 Egbert Eich
- *
- *   Part of this code was inspired  by the VBIOS POSTing code in DOSEMU
- *   developed by the "DOSEMU-Development-Team"
- */
-
-/*
- * To debug port accesses define PRINT_PORT to 1.
- * Note! You also have to comment out ioperm()
- * in xf86EnableIO(). Otherwise we won't trap
- * on PIO.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#define PRINT_PORT 0
-
-#include <unistd.h>
-
-#include <X11/Xos.h>
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "compiler.h"
-#define _INT10_PRIVATE
-#include "int10Defines.h"
-#include "xf86int10.h"
-#include "Pci.h"
-#ifdef _X86EMU
-#include "x86emu/x86emui.h"
-#else
-#define DEBUG_IO_TRACE() 0
-#endif
-#include <pciaccess.h>
-
-static int pciCfg1in(CARD16 addr, CARD32 *val);
-static int pciCfg1out(CARD16 addr, CARD32 val);
-static int pciCfg1inw(CARD16 addr, CARD16 *val);
-static int pciCfg1outw(CARD16 addr, CARD16 val);
-static int pciCfg1inb(CARD16 addr, CARD8 *val);
-static int pciCfg1outb(CARD16 addr, CARD8 val);
-#if defined (_PC)
-static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set);
-#endif
-
-#define REG pInt
-
-int
-setup_int(xf86Int10InfoPtr pInt)
-{
-    if (pInt != Int10Current) {
-	if (!MapCurrentInt10(pInt))
-	    return -1;
-	Int10Current = pInt;
-    }
-    X86_EAX = (CARD32) pInt->ax;
-    X86_EBX = (CARD32) pInt->bx;
-    X86_ECX = (CARD32) pInt->cx;
-    X86_EDX = (CARD32) pInt->dx;
-    X86_ESI = (CARD32) pInt->si;
-    X86_EDI = (CARD32) pInt->di;
-    X86_EBP = (CARD32) pInt->bp;
-    X86_ESP = 0x1000; X86_SS = pInt->stackseg >> 4;
-    X86_EIP = 0x0600; X86_CS = 0x0;	/* address of 'hlt' */
-    X86_DS = 0x40;			/* standard pc ds */
-    X86_ES = pInt->es;
-    X86_FS = 0;
-    X86_GS = 0;
-    X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
-#if defined (_PC)
-    if (pInt->Flags & SET_BIOS_SCRATCH)
-	SetResetBIOSVars(pInt, TRUE);
-#endif
-    OsBlockSignals();
-    return 0;
-}
-
-void
-finish_int(xf86Int10InfoPtr pInt, int sig)
-{
-    OsReleaseSignals();
-    pInt->ax = (CARD32) X86_EAX;
-    pInt->bx = (CARD32) X86_EBX;
-    pInt->cx = (CARD32) X86_ECX;
-    pInt->dx = (CARD32) X86_EDX;
-    pInt->si = (CARD32) X86_ESI;
-    pInt->di = (CARD32) X86_EDI;
-    pInt->es = (CARD16) X86_ES;
-    pInt->bp = (CARD32) X86_EBP;
-    pInt->flags = (CARD32) X86_FLAGS;
-#if defined (_PC)
-    if (pInt->Flags & RESTORE_BIOS_SCRATCH)
-	SetResetBIOSVars(pInt, FALSE);
-#endif
-}
-
-/* general software interrupt handler */
-CARD32
-getIntVect(xf86Int10InfoPtr pInt,int num)
-{
-    return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4);
-}
-
-void
-pushw(xf86Int10InfoPtr pInt, CARD16 val)
-{
-    X86_ESP -= 2;
-    MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val);
-}
-
-int
-run_bios_int(int num, xf86Int10InfoPtr pInt)
-{
-    CARD32 eflags;
-#ifndef _PC
-    /* check if bios vector is initialized */
-    if (MEM_RW(pInt, (num << 2) + 2) == (SYS_BIOS >> 4)) { /* SYS_BIOS_SEG ?*/
-
-	if (num == 21 && X86_AH == 0x4e) {
- 	    xf86DrvMsg(pInt->scrnIndex, X_NOTICE,
-		       "Failing Find-Matching-File on non-PC"
-			" (int 21, func 4e)\n");
- 	    X86_AX = 2;
- 	    SET_FLAG(F_CF);
- 	    return 1;
- 	} else {
-	    xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
-			   "Ignoring int 0x%02x call\n", num);
-	    if (xf86GetVerbosity() > 3) {
-		dump_registers(pInt);
-		stack_trace(pInt);
-	    }
-	    return 1;
-	}
-    }
-#endif
-#ifdef PRINT_INT
-    ErrorF("calling card BIOS at: ");
-#endif
-    eflags = X86_EFLAGS;
-#if 0
-    eflags = eflags | IF_MASK;
-    X86_EFLAGS = X86_EFLAGS  & ~(VIF_MASK | TF_MASK | IF_MASK | NT_MASK);
-#endif
-    pushw(pInt, eflags);
-    pushw(pInt, X86_CS);
-    pushw(pInt, X86_IP);
-    X86_CS = MEM_RW(pInt, (num << 2) + 2);
-    X86_IP = MEM_RW(pInt,  num << 2);
-#ifdef PRINT_INT
-    ErrorF("0x%x:%lx\n", X86_CS, X86_EIP);
-#endif
-    return 1;
-}
-
-/* Debugging stuff */
-void
-dump_code(xf86Int10InfoPtr pInt)
-{
-    int i;
-    unsigned long lina = SEG_ADR((CARD32), X86_CS, IP);
-
-    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, "code at 0x%8.8lx:\n", lina);
-    for (i=0; i<0x10; i++)
-	xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
-    xf86ErrorFVerb(3, "\n");
-    for (; i<0x20; i++)
-	xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
-    xf86ErrorFVerb(3, "\n");
-}
-
-void
-dump_registers(xf86Int10InfoPtr pInt)
-{
-    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
-	"EAX=0x%8.8lx, EBX=0x%8.8lx, ECX=0x%8.8lx, EDX=0x%8.8lx\n",
-	(unsigned long)X86_EAX, (unsigned long)X86_EBX,
-	(unsigned long)X86_ECX, (unsigned long)X86_EDX);
-    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
-	"ESP=0x%8.8lx, EBP=0x%8.8lx, ESI=0x%8.8lx, EDI=0x%8.8lx\n",
-	(unsigned long)X86_ESP, (unsigned long)X86_EBP,
-	(unsigned long)X86_ESI, (unsigned long)X86_EDI);
-    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
-	"CS=0x%4.4x, SS=0x%4.4x,"
-	" DS=0x%4.4x, ES=0x%4.4x, FS=0x%4.4x, GS=0x%4.4x\n",
-	X86_CS, X86_SS, X86_DS, X86_ES, X86_FS, X86_GS);
-    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
-	"EIP=0x%8.8lx, EFLAGS=0x%8.8lx\n",
-	(unsigned long)X86_EIP, (unsigned long)X86_EFLAGS);
-}
-
-void
-stack_trace(xf86Int10InfoPtr pInt)
-{
-    int i = 0;
-    unsigned long stack = SEG_ADR((CARD32), X86_SS, SP);
-    unsigned long tail  = (CARD32)((X86_SS << 4) + 0x1000);
-
-    if (stack >= tail) return;
-
-    xf86MsgVerb(X_INFO, 3, "stack at 0x%8.8lx:\n", stack);
-    for (; stack < tail; stack++) {
-	xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, stack));
-	i = (i + 1) % 0x10;
-	if (!i)
-	    xf86ErrorFVerb(3, "\n");
-    }
-    if (i)
-	xf86ErrorFVerb(3, "\n");
-}
-
-int
-port_rep_inb(xf86Int10InfoPtr pInt,
-	     CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
-    register int inc = d_f ? -1 : 1;
-    CARD32 dst = base;
-    if (PRINT_PORT && DEBUG_IO_TRACE())
-	ErrorF(" rep_insb(%#x) %ld bytes at %8.8lx %s\n",
-		port, count, base, d_f ? "up" : "down");
-    while (count--) {
-	MEM_WB(pInt, dst, x_inb(port));
-	dst += inc;
-    }
-    return dst - base;
-}
-
-int
-port_rep_inw(xf86Int10InfoPtr pInt,
-	     CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
-    register int inc = d_f ? -2 : 2;
-    CARD32 dst = base;
-    if (PRINT_PORT && DEBUG_IO_TRACE())
-	ErrorF(" rep_insw(%#x) %ld bytes at %8.8lx %s\n",
-	     port, count, base, d_f ? "up" : "down");
-    while (count--) {
-	MEM_WW(pInt, dst, x_inw(port));
-	dst += inc;
-    }
-    return dst - base;
-}
-
-int
-port_rep_inl(xf86Int10InfoPtr pInt,
-	     CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
-    register int inc = d_f ? -4 : 4;
-    CARD32 dst = base;
-    if (PRINT_PORT && DEBUG_IO_TRACE())
-	ErrorF(" rep_insl(%#x) %ld bytes at %8.8lx %s\n",
-	     port, count, base, d_f ? "up" : "down");
-    while (count--) {
-	MEM_WL(pInt, dst, x_inl(port));
-	dst += inc;
-    }
-    return dst - base;
-}
-
-int
-port_rep_outb(xf86Int10InfoPtr pInt,
-	      CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
-    register int inc = d_f ? -1 : 1;
-    CARD32 dst = base;
-    if (PRINT_PORT && DEBUG_IO_TRACE())
-	ErrorF(" rep_outb(%#x) %ld bytes at %8.8lx %s\n",
-	     port, count, base, d_f ? "up" : "down");
-    while (count--) {
-	x_outb(port, MEM_RB(pInt, dst));
-	dst += inc;
-    }
-    return dst - base;
-}
-
-int
-port_rep_outw(xf86Int10InfoPtr pInt,
-	      CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
-    register int inc = d_f ? -2 : 2;
-    CARD32 dst = base;
-    if (PRINT_PORT && DEBUG_IO_TRACE())
-	ErrorF(" rep_outw(%#x) %ld bytes at %8.8lx %s\n",
-	     port, count, base, d_f ? "up" : "down");
-    while (count--) {
-	x_outw(port, MEM_RW(pInt, dst));
-	dst += inc;
-    }
-    return dst - base;
-}
-
-int
-port_rep_outl(xf86Int10InfoPtr pInt,
-	      CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
-    register int inc = d_f ? -4 : 4;
-    CARD32 dst = base;
-    if (PRINT_PORT && DEBUG_IO_TRACE())
-	ErrorF(" rep_outl(%#x) %ld bytes at %8.8lx %s\n",
-	     port, count, base, d_f ? "up" : "down");
-    while (count--) {
-	x_outl(port, MEM_RL(pInt, dst));
-	dst += inc;
-    }
-    return dst - base;
-}
-
-CARD8
-x_inb(CARD16 port)
-{
-    CARD8 val;
-
-    if (port == 0x40) {
-	Int10Current->inb40time++;
-	val = (CARD8)(Int10Current->inb40time >>
-		      ((Int10Current->inb40time & 1) << 3));
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" inb(%#x) = %2.2x\n", port, val);
-#ifdef __NOT_YET__
-    } else if (port < 0x0100) {		/* Don't interfere with mainboard */
-	val = 0;
-	xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
-	    "inb 0x%4.4x\n", port);
-	if (xf86GetVerbosity() > 3) {
-	    dump_registers(Int10Current);
-	    stack_trace(Int10Current);
-	}
-#endif /* __NOT_YET__ */
-    } else if (!pciCfg1inb(port, &val)) {
-	val = inb(Int10Current->ioBase + port);
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" inb(%#x) = %2.2x\n", port, val);
-    }
-    return val;
-}
-
-CARD16
-x_inw(CARD16 port)
-{
-    CARD16 val;
-
-    if (port == 0x5c) {
-	struct timeval tv;
-
-	/*
-	 * Emulate a PC98's timer.  Typical resolution is 3.26 usec.
-	 * Approximate this by dividing by 3.
-	 */
-	X_GETTIMEOFDAY(&tv);
-	val = (CARD16)(tv.tv_usec / 3);
-    } else if (!pciCfg1inw(port, &val)) {
-	val = inw(Int10Current->ioBase + port);
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" inw(%#x) = %4.4x\n", port, val);
-    }
-    return val;
-}
-
-void
-x_outb(CARD16 port, CARD8 val)
-{
-    if ((port == 0x43) && (val == 0)) {
-	struct timeval tv;
-	/*
-	 * Emulate a PC's timer 0.  Such timers typically have a resolution of
-	 * some .838 usec per tick, but this can only provide 1 usec per tick.
-	 * (Not that this matters much, given inherent emulation delays.)  Use
-	 * the bottom bit as a byte select.  See inb(0x40) above.
-	 */
-	X_GETTIMEOFDAY(&tv);
-	Int10Current->inb40time = (CARD16)(tv.tv_usec | 1);
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" outb(%#x, %2.2x)\n", port, val);
-#ifdef __NOT_YET__
-    } else if (port < 0x0100) {		/* Don't interfere with mainboard */
-	xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
-	    "outb 0x%4.4x,0x%2.2x\n", port, val);
-	if (xf86GetVerbosity() > 3) {
-	    dump_registers(Int10Current);
-	    stack_trace(Int10Current);
-	}
-#endif /* __NOT_YET__ */
-    } else if (!pciCfg1outb(port, val)) {
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" outb(%#x, %2.2x)\n", port, val);
-	outb(Int10Current->ioBase + port, val);
-    }
-}
-
-void
-x_outw(CARD16 port, CARD16 val)
-{
-
-    if (!pciCfg1outw(port, val)) {
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" outw(%#x, %4.4x)\n", port, val);
-	outw(Int10Current->ioBase + port, val);
-    }
-}
-
-CARD32
-x_inl(CARD16 port)
-{
-    CARD32 val;
-
-    if (!pciCfg1in(port, &val)) {
-	val = inl(Int10Current->ioBase + port);
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" inl(%#x) = %8.8lx\n", port, val);
-    }
-    return val;
-}
-
-void
-x_outl(CARD16 port, CARD32 val)
-{
-    if (!pciCfg1out(port, val)) {
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" outl(%#x, %8.8lx)\n", port, val);
-	outl(Int10Current->ioBase + port, val);
-    }
-}
-
-CARD8
-Mem_rb(CARD32 addr)
-{
-    return (*Int10Current->mem->rb)(Int10Current, addr);
-}
-
-CARD16
-Mem_rw(CARD32 addr)
-{
-    return (*Int10Current->mem->rw)(Int10Current, addr);
-}
-
-CARD32
-Mem_rl(CARD32 addr)
-{
-    return (*Int10Current->mem->rl)(Int10Current, addr);
-}
-
-void
-Mem_wb(CARD32 addr, CARD8 val)
-{
-    (*Int10Current->mem->wb)(Int10Current, addr, val);
-}
-
-void
-Mem_ww(CARD32 addr, CARD16 val)
-{
-    (*Int10Current->mem->ww)(Int10Current, addr, val);
-}
-
-void
-Mem_wl(CARD32 addr, CARD32 val)
-{
-    (*Int10Current->mem->wl)(Int10Current, addr, val);
-}
-
-static CARD32 PciCfg1Addr = 0;
-
-#define PCI_DOM_FROM_TAG(tag)  (((tag) >> 24) & (PCI_DOM_MASK))
-#define PCI_BUS_FROM_TAG(tag)  (((tag) >> 16) & (PCI_DOMBUS_MASK))
-#define PCI_DEV_FROM_TAG(tag)  (((tag) & 0x0000f800u) >> 11)
-#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8)
-
-#define PCI_OFFSET(x) ((x) & 0x000000ff)
-#define PCI_TAG(x)    ((x) & 0x7fffff00)
-
-static struct pci_device*
-pci_device_for_cfg_address (CARD32 addr)
-{
-	struct pci_device *dev = NULL;
-	PCITAG tag = PCI_TAG(addr);
-	struct pci_slot_match slot_match = {
-		.domain = PCI_DOM_FROM_TAG(tag),
-		.bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)),
-		.dev = PCI_DEV_FROM_TAG(tag),
-		.func = PCI_FUNC_FROM_TAG(tag),
-		.match_data = 0
-	};
-
-	struct pci_device_iterator *iter =
-	    pci_slot_match_iterator_create (&slot_match);
-
-	if (iter)
-		dev = pci_device_next(iter);
-
-	pci_iterator_destroy(iter);
-
-	return dev;
-}
-
-static int
-pciCfg1in(CARD16 addr, CARD32 *val)
-{
-    if (addr == 0xCF8) {
-	*val = PciCfg1Addr;
-	return 1;
-    }
-    if (addr == 0xCFC) {
-	pci_device_cfg_read_u32(pci_device_for_cfg_address(PciCfg1Addr),
-			val, PCI_OFFSET(PciCfg1Addr));
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" cfg_inl(%#lx) = %8.8lx\n", PciCfg1Addr, *val);
-	return 1;
-    }
-    return 0;
-}
-
-static int
-pciCfg1out(CARD16 addr, CARD32 val)
-{
-    if (addr == 0xCF8) {
-	PciCfg1Addr = val;
-	return 1;
-    }
-    if (addr == 0xCFC) {
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" cfg_outl(%#lx, %8.8lx)\n", PciCfg1Addr, val);
-	pci_device_cfg_write_u32(pci_device_for_cfg_address(PciCfg1Addr),
-			val, PCI_OFFSET(PciCfg1Addr));
-	return 1;
-    }
-    return 0;
-}
-
-static int
-pciCfg1inw(CARD16 addr, CARD16 *val)
-{
-    int shift;
-
-    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
-	shift = (addr - 0xCF8) * 8;
-	*val = (PciCfg1Addr >> shift) & 0xffff;
-	return 1;
-    }
-    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
-	const unsigned offset = addr - 0xCFC;
-
-	pci_device_cfg_read_u16(pci_device_for_cfg_address(PciCfg1Addr),
-			val, PCI_OFFSET(PciCfg1Addr) + offset);
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" cfg_inw(%#lx) = %4.4x\n", PciCfg1Addr + offset, *val);
-	return 1;
-    }
-    return 0;
-}
-
-static int
-pciCfg1outw(CARD16 addr, CARD16 val)
-{
-    int shift;
-
-    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
-	shift = (addr - 0xCF8) * 8;
-	PciCfg1Addr &= ~(0xffff << shift);
-	PciCfg1Addr |= ((CARD32) val) << shift;
-	return 1;
-    }
-    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
-	const unsigned offset = addr - 0xCFC;
-
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" cfg_outw(%#lx, %4.4x)\n", PciCfg1Addr + offset, val);
-	pci_device_cfg_write_u16(pci_device_for_cfg_address(PciCfg1Addr),
-			val, PCI_OFFSET(PciCfg1Addr) + offset);
-	return 1;
-    }
-    return 0;
-}
-
-static int
-pciCfg1inb(CARD16 addr, CARD8 *val)
-{
-    int shift;
-
-    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
-	shift = (addr - 0xCF8) * 8;
-	*val = (PciCfg1Addr >> shift) & 0xff;
-	return 1;
-    }
-    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
-	const unsigned offset = addr - 0xCFC;
-
-	pci_device_cfg_read_u8(pci_device_for_cfg_address(PciCfg1Addr),
-			val, PCI_OFFSET(PciCfg1Addr) + offset);
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" cfg_inb(%#lx) = %2.2x\n", PciCfg1Addr + offset, *val);
-	return 1;
-    }
-    return 0;
-}
-
-static int
-pciCfg1outb(CARD16 addr, CARD8 val)
-{
-    int shift;
-
-    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
-	shift = (addr - 0xCF8) * 8;
-	PciCfg1Addr &= ~(0xff << shift);
-	PciCfg1Addr |= ((CARD32) val) << shift;
-	return 1;
-    }
-    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
-	const unsigned offset = addr - 0xCFC;
-
-	if (PRINT_PORT && DEBUG_IO_TRACE())
-	    ErrorF(" cfg_outb(%#lx, %2.2x)\n", PciCfg1Addr + offset, val);
-	pci_device_cfg_write_u8(pci_device_for_cfg_address(PciCfg1Addr),
-			val, PCI_OFFSET(PciCfg1Addr) + offset);
-	return 1;
-    }
-    return 0;
-}
-
-CARD8
-bios_checksum(const CARD8 *start, int size)
-{
-    CARD8 sum = 0;
-
-    while (size-- > 0)
-	sum += *start++;
-    return sum;
-}
-
-/*
- * Lock/Unlock legacy VGA. Some Bioses try to be very clever and make
- * an attempt to detect a legacy ISA card. If they find one they might
- * act very strange: for example they might configure the card as a
- * monochrome card. This might cause some drivers to choke.
- * To avoid this we attempt legacy VGA by writing to all know VGA
- * disable registers before we call the BIOS initialization and
- * restore the original values afterwards. In beween we hold our
- * breath. To get to a (possibly exising) ISA card need to disable
- * our current PCI card.
- */
-/*
- * This is just for booting: we just want to catch pure
- * legacy vga therefore we don't worry about mmio etc.
- * This stuff should really go into vgaHW.c. However then
- * the driver would have to load the vga-module prior to
- * doing int10.
- */
-void
-LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
-{
-    vga->save_msr    = inb(pInt->ioBase + 0x03CC);
-    vga->save_vse    = inb(pInt->ioBase + 0x03C3);
-#ifndef __ia64__
-    vga->save_46e8   = inb(pInt->ioBase + 0x46E8);
-#endif
-    vga->save_pos102 = inb(pInt->ioBase + 0x0102);
-    outb(pInt->ioBase + 0x03C2, ~(CARD8)0x03 & vga->save_msr);
-    outb(pInt->ioBase + 0x03C3, ~(CARD8)0x01 & vga->save_vse);
-#ifndef __ia64__
-    outb(pInt->ioBase + 0x46E8, ~(CARD8)0x08 & vga->save_46e8);
-#endif
-    outb(pInt->ioBase + 0x0102, ~(CARD8)0x01 & vga->save_pos102);
-}
-
-void
-UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
-{
-    outb(pInt->ioBase + 0x0102, vga->save_pos102);
-#ifndef __ia64__
-    outb(pInt->ioBase + 0x46E8, vga->save_46e8);
-#endif
-    outb(pInt->ioBase + 0x03C3, vga->save_vse);
-    outb(pInt->ioBase + 0x03C2, vga->save_msr);
-}
-
-#if defined (_PC)
-static void
-SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set)
-{
-    int pagesize = getpagesize();
-    unsigned char* base = xf86MapVidMem(pInt->scrnIndex,
-					VIDMEM_MMIO, 0, pagesize);
-    int i;
-
-    if (set) {
-	for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
-	    MEM_WW(pInt, i, *(base + i));
-    } else {
-	for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
-	    *(base + i) = MEM_RW(pInt, i);
-    }
-    
-    xf86UnMapVidMem(pInt->scrnIndex,base,pagesize);
-}
-
-void
-xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt, Bool save)
-{
-    int pagesize = getpagesize();
-    unsigned char* base;
-    int i;
-
-    if (!xf86IsEntityPrimary(pInt->entityIndex)
-	|| (!save && !pInt->BIOSScratch))
-	return;
-    
-    base = xf86MapVidMem(pInt->scrnIndex, VIDMEM_MMIO, 0, pagesize);
-    base += BIOS_SCRATCH_OFF;
-    if (save) {
-	if ((pInt->BIOSScratch
-	     = xnfalloc(BIOS_SCRATCH_LEN)))
-	    for (i = 0; i < BIOS_SCRATCH_LEN; i++)
-		*(((char*)pInt->BIOSScratch + i)) = *(base + i);	
-    } else {
-	if (pInt->BIOSScratch) {
-	    for (i = 0; i < BIOS_SCRATCH_LEN; i++)
-		*(base + i) = *(pInt->BIOSScratch + i); 
-	    free(pInt->BIOSScratch);
-	    pInt->BIOSScratch = NULL;
-	}
-    }
-    
-    xf86UnMapVidMem(pInt->scrnIndex,base - BIOS_SCRATCH_OFF ,pagesize);
-}
-#endif
-
-xf86Int10InfoPtr
-xf86InitInt10(int entityIndex)
-{
-    return xf86ExtendedInitInt10(entityIndex, 0);
-}
+/*
+ *                   XFree86 int10 module
+ *   execute BIOS int 10h calls in x86 real mode environment
+ *                 Copyright 1999 Egbert Eich
+ *
+ *   Part of this code was inspired  by the VBIOS POSTing code in DOSEMU
+ *   developed by the "DOSEMU-Development-Team"
+ */
+
+/*
+ * To debug port accesses define PRINT_PORT to 1.
+ * Note! You also have to comment out ioperm()
+ * in xf86EnableIO(). Otherwise we won't trap
+ * on PIO.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#define PRINT_PORT 0
+
+#include <unistd.h>
+
+#include <X11/Xos.h>
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "compiler.h"
+#define _INT10_PRIVATE
+#include "int10Defines.h"
+#include "xf86int10.h"
+#include "Pci.h"
+#ifdef _X86EMU
+#include "x86emu/x86emui.h"
+#else
+#define DEBUG_IO_TRACE() 0
+#endif
+#include <pciaccess.h>
+
+static int pciCfg1in(CARD16 addr, CARD32 *val);
+static int pciCfg1out(CARD16 addr, CARD32 val);
+static int pciCfg1inw(CARD16 addr, CARD16 *val);
+static int pciCfg1outw(CARD16 addr, CARD16 val);
+static int pciCfg1inb(CARD16 addr, CARD8 *val);
+static int pciCfg1outb(CARD16 addr, CARD8 val);
+#if defined (_PC)
+static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set);
+#endif
+
+#define REG pInt
+
+int
+setup_int(xf86Int10InfoPtr pInt)
+{
+    if (pInt != Int10Current) {
+	if (!MapCurrentInt10(pInt))
+	    return -1;
+	Int10Current = pInt;
+    }
+    X86_EAX = (CARD32) pInt->ax;
+    X86_EBX = (CARD32) pInt->bx;
+    X86_ECX = (CARD32) pInt->cx;
+    X86_EDX = (CARD32) pInt->dx;
+    X86_ESI = (CARD32) pInt->si;
+    X86_EDI = (CARD32) pInt->di;
+    X86_EBP = (CARD32) pInt->bp;
+    X86_ESP = 0x1000; X86_SS = pInt->stackseg >> 4;
+    X86_EIP = 0x0600; X86_CS = 0x0;	/* address of 'hlt' */
+    X86_DS = 0x40;			/* standard pc ds */
+    X86_ES = pInt->es;
+    X86_FS = 0;
+    X86_GS = 0;
+    X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
+#if defined (_PC)
+    if (pInt->Flags & SET_BIOS_SCRATCH)
+	SetResetBIOSVars(pInt, TRUE);
+#endif
+    OsBlockSignals();
+    return 0;
+}
+
+void
+finish_int(xf86Int10InfoPtr pInt, int sig)
+{
+    OsReleaseSignals();
+    pInt->ax = (CARD32) X86_EAX;
+    pInt->bx = (CARD32) X86_EBX;
+    pInt->cx = (CARD32) X86_ECX;
+    pInt->dx = (CARD32) X86_EDX;
+    pInt->si = (CARD32) X86_ESI;
+    pInt->di = (CARD32) X86_EDI;
+    pInt->es = (CARD16) X86_ES;
+    pInt->bp = (CARD32) X86_EBP;
+    pInt->flags = (CARD32) X86_FLAGS;
+#if defined (_PC)
+    if (pInt->Flags & RESTORE_BIOS_SCRATCH)
+	SetResetBIOSVars(pInt, FALSE);
+#endif
+}
+
+/* general software interrupt handler */
+CARD32
+getIntVect(xf86Int10InfoPtr pInt,int num)
+{
+    return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4);
+}
+
+void
+pushw(xf86Int10InfoPtr pInt, CARD16 val)
+{
+    X86_ESP -= 2;
+    MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val);
+}
+
+int
+run_bios_int(int num, xf86Int10InfoPtr pInt)
+{
+    CARD32 eflags;
+#ifndef _PC
+    /* check if bios vector is initialized */
+    if (MEM_RW(pInt, (num << 2) + 2) == (SYS_BIOS >> 4)) { /* SYS_BIOS_SEG ?*/
+
+	if (num == 21 && X86_AH == 0x4e) {
+ 	    xf86DrvMsg(pInt->scrnIndex, X_NOTICE,
+		       "Failing Find-Matching-File on non-PC"
+			" (int 21, func 4e)\n");
+ 	    X86_AX = 2;
+ 	    SET_FLAG(F_CF);
+ 	    return 1;
+ 	} else {
+	    xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
+			   "Ignoring int 0x%02x call\n", num);
+	    if (xf86GetVerbosity() > 3) {
+		dump_registers(pInt);
+		stack_trace(pInt);
+	    }
+	    return 1;
+	}
+    }
+#endif
+#ifdef PRINT_INT
+    ErrorF("calling card BIOS at: ");
+#endif
+    eflags = X86_EFLAGS;
+#if 0
+    eflags = eflags | IF_MASK;
+    X86_EFLAGS = X86_EFLAGS  & ~(VIF_MASK | TF_MASK | IF_MASK | NT_MASK);
+#endif
+    pushw(pInt, eflags);
+    pushw(pInt, X86_CS);
+    pushw(pInt, X86_IP);
+    X86_CS = MEM_RW(pInt, (num << 2) + 2);
+    X86_IP = MEM_RW(pInt,  num << 2);
+#ifdef PRINT_INT
+    ErrorF("0x%x:%lx\n", X86_CS, X86_EIP);
+#endif
+    return 1;
+}
+
+/* Debugging stuff */
+void
+dump_code(xf86Int10InfoPtr pInt)
+{
+    int i;
+    unsigned long lina = SEG_ADR((CARD32), X86_CS, IP);
+
+    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, "code at 0x%8.8lx:\n", lina);
+    for (i=0; i<0x10; i++)
+	xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
+    xf86ErrorFVerb(3, "\n");
+    for (; i<0x20; i++)
+	xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
+    xf86ErrorFVerb(3, "\n");
+}
+
+void
+dump_registers(xf86Int10InfoPtr pInt)
+{
+    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
+	"EAX=0x%8.8lx, EBX=0x%8.8lx, ECX=0x%8.8lx, EDX=0x%8.8lx\n",
+	(unsigned long)X86_EAX, (unsigned long)X86_EBX,
+	(unsigned long)X86_ECX, (unsigned long)X86_EDX);
+    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
+	"ESP=0x%8.8lx, EBP=0x%8.8lx, ESI=0x%8.8lx, EDI=0x%8.8lx\n",
+	(unsigned long)X86_ESP, (unsigned long)X86_EBP,
+	(unsigned long)X86_ESI, (unsigned long)X86_EDI);
+    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
+	"CS=0x%4.4x, SS=0x%4.4x,"
+	" DS=0x%4.4x, ES=0x%4.4x, FS=0x%4.4x, GS=0x%4.4x\n",
+	X86_CS, X86_SS, X86_DS, X86_ES, X86_FS, X86_GS);
+    xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
+	"EIP=0x%8.8lx, EFLAGS=0x%8.8lx\n",
+	(unsigned long)X86_EIP, (unsigned long)X86_EFLAGS);
+}
+
+void
+stack_trace(xf86Int10InfoPtr pInt)
+{
+    int i = 0;
+    unsigned long stack = SEG_ADR((CARD32), X86_SS, SP);
+    unsigned long tail  = (CARD32)((X86_SS << 4) + 0x1000);
+
+    if (stack >= tail) return;
+
+    xf86MsgVerb(X_INFO, 3, "stack at 0x%8.8lx:\n", stack);
+    for (; stack < tail; stack++) {
+	xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, stack));
+	i = (i + 1) % 0x10;
+	if (!i)
+	    xf86ErrorFVerb(3, "\n");
+    }
+    if (i)
+	xf86ErrorFVerb(3, "\n");
+}
+
+int
+port_rep_inb(xf86Int10InfoPtr pInt,
+	     CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+    register int inc = d_f ? -1 : 1;
+    CARD32 dst = base;
+    if (PRINT_PORT && DEBUG_IO_TRACE())
+	ErrorF(" rep_insb(%#x) %ld bytes at %8.8lx %s\n",
+		port, count, base, d_f ? "up" : "down");
+    while (count--) {
+	MEM_WB(pInt, dst, x_inb(port));
+	dst += inc;
+    }
+    return dst - base;
+}
+
+int
+port_rep_inw(xf86Int10InfoPtr pInt,
+	     CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+    register int inc = d_f ? -2 : 2;
+    CARD32 dst = base;
+    if (PRINT_PORT && DEBUG_IO_TRACE())
+	ErrorF(" rep_insw(%#x) %ld bytes at %8.8lx %s\n",
+	     port, count, base, d_f ? "up" : "down");
+    while (count--) {
+	MEM_WW(pInt, dst, x_inw(port));
+	dst += inc;
+    }
+    return dst - base;
+}
+
+int
+port_rep_inl(xf86Int10InfoPtr pInt,
+	     CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+    register int inc = d_f ? -4 : 4;
+    CARD32 dst = base;
+    if (PRINT_PORT && DEBUG_IO_TRACE())
+	ErrorF(" rep_insl(%#x) %ld bytes at %8.8lx %s\n",
+	     port, count, base, d_f ? "up" : "down");
+    while (count--) {
+	MEM_WL(pInt, dst, x_inl(port));
+	dst += inc;
+    }
+    return dst - base;
+}
+
+int
+port_rep_outb(xf86Int10InfoPtr pInt,
+	      CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+    register int inc = d_f ? -1 : 1;
+    CARD32 dst = base;
+    if (PRINT_PORT && DEBUG_IO_TRACE())
+	ErrorF(" rep_outb(%#x) %ld bytes at %8.8lx %s\n",
+	     port, count, base, d_f ? "up" : "down");
+    while (count--) {
+	x_outb(port, MEM_RB(pInt, dst));
+	dst += inc;
+    }
+    return dst - base;
+}
+
+int
+port_rep_outw(xf86Int10InfoPtr pInt,
+	      CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+    register int inc = d_f ? -2 : 2;
+    CARD32 dst = base;
+    if (PRINT_PORT && DEBUG_IO_TRACE())
+	ErrorF(" rep_outw(%#x) %ld bytes at %8.8lx %s\n",
+	     port, count, base, d_f ? "up" : "down");
+    while (count--) {
+	x_outw(port, MEM_RW(pInt, dst));
+	dst += inc;
+    }
+    return dst - base;
+}
+
+int
+port_rep_outl(xf86Int10InfoPtr pInt,
+	      CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+    register int inc = d_f ? -4 : 4;
+    CARD32 dst = base;
+    if (PRINT_PORT && DEBUG_IO_TRACE())
+	ErrorF(" rep_outl(%#x) %ld bytes at %8.8lx %s\n",
+	     port, count, base, d_f ? "up" : "down");
+    while (count--) {
+	x_outl(port, MEM_RL(pInt, dst));
+	dst += inc;
+    }
+    return dst - base;
+}
+
+CARD8
+x_inb(CARD16 port)
+{
+    CARD8 val;
+
+    if (port == 0x40) {
+	Int10Current->inb40time++;
+	val = (CARD8)(Int10Current->inb40time >>
+		      ((Int10Current->inb40time & 1) << 3));
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" inb(%#x) = %2.2x\n", port, val);
+#ifdef __NOT_YET__
+    } else if (port < 0x0100) {		/* Don't interfere with mainboard */
+	val = 0;
+	xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
+	    "inb 0x%4.4x\n", port);
+	if (xf86GetVerbosity() > 3) {
+	    dump_registers(Int10Current);
+	    stack_trace(Int10Current);
+	}
+#endif /* __NOT_YET__ */
+    } else if (!pciCfg1inb(port, &val)) {
+	val = inb(Int10Current->ioBase + port);
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" inb(%#x) = %2.2x\n", port, val);
+    }
+    return val;
+}
+
+CARD16
+x_inw(CARD16 port)
+{
+    CARD16 val;
+
+    if (port == 0x5c) {
+	struct timeval tv;
+
+	/*
+	 * Emulate a PC98's timer.  Typical resolution is 3.26 usec.
+	 * Approximate this by dividing by 3.
+	 */
+	X_GETTIMEOFDAY(&tv);
+	val = (CARD16)(tv.tv_usec / 3);
+    } else if (!pciCfg1inw(port, &val)) {
+	val = inw(Int10Current->ioBase + port);
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" inw(%#x) = %4.4x\n", port, val);
+    }
+    return val;
+}
+
+void
+x_outb(CARD16 port, CARD8 val)
+{
+    if ((port == 0x43) && (val == 0)) {
+	struct timeval tv;
+	/*
+	 * Emulate a PC's timer 0.  Such timers typically have a resolution of
+	 * some .838 usec per tick, but this can only provide 1 usec per tick.
+	 * (Not that this matters much, given inherent emulation delays.)  Use
+	 * the bottom bit as a byte select.  See inb(0x40) above.
+	 */
+	X_GETTIMEOFDAY(&tv);
+	Int10Current->inb40time = (CARD16)(tv.tv_usec | 1);
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" outb(%#x, %2.2x)\n", port, val);
+#ifdef __NOT_YET__
+    } else if (port < 0x0100) {		/* Don't interfere with mainboard */
+	xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
+	    "outb 0x%4.4x,0x%2.2x\n", port, val);
+	if (xf86GetVerbosity() > 3) {
+	    dump_registers(Int10Current);
+	    stack_trace(Int10Current);
+	}
+#endif /* __NOT_YET__ */
+    } else if (!pciCfg1outb(port, val)) {
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" outb(%#x, %2.2x)\n", port, val);
+	outb(Int10Current->ioBase + port, val);
+    }
+}
+
+void
+x_outw(CARD16 port, CARD16 val)
+{
+
+    if (!pciCfg1outw(port, val)) {
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" outw(%#x, %4.4x)\n", port, val);
+	outw(Int10Current->ioBase + port, val);
+    }
+}
+
+CARD32
+x_inl(CARD16 port)
+{
+    CARD32 val;
+
+    if (!pciCfg1in(port, &val)) {
+	val = inl(Int10Current->ioBase + port);
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" inl(%#x) = %8.8lx\n", port, val);
+    }
+    return val;
+}
+
+void
+x_outl(CARD16 port, CARD32 val)
+{
+    if (!pciCfg1out(port, val)) {
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" outl(%#x, %8.8lx)\n", port, val);
+	outl(Int10Current->ioBase + port, val);
+    }
+}
+
+CARD8
+Mem_rb(CARD32 addr)
+{
+    return (*Int10Current->mem->rb)(Int10Current, addr);
+}
+
+CARD16
+Mem_rw(CARD32 addr)
+{
+    return (*Int10Current->mem->rw)(Int10Current, addr);
+}
+
+CARD32
+Mem_rl(CARD32 addr)
+{
+    return (*Int10Current->mem->rl)(Int10Current, addr);
+}
+
+void
+Mem_wb(CARD32 addr, CARD8 val)
+{
+    (*Int10Current->mem->wb)(Int10Current, addr, val);
+}
+
+void
+Mem_ww(CARD32 addr, CARD16 val)
+{
+    (*Int10Current->mem->ww)(Int10Current, addr, val);
+}
+
+void
+Mem_wl(CARD32 addr, CARD32 val)
+{
+    (*Int10Current->mem->wl)(Int10Current, addr, val);
+}
+
+static CARD32 PciCfg1Addr = 0;
+
+#define PCI_DOM_FROM_TAG(tag)  (((tag) >> 24) & (PCI_DOM_MASK))
+#define PCI_BUS_FROM_TAG(tag)  (((tag) >> 16) & (PCI_DOMBUS_MASK))
+#define PCI_DEV_FROM_TAG(tag)  (((tag) & 0x0000f800u) >> 11)
+#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8)
+
+#define PCI_OFFSET(x) ((x) & 0x000000ff)
+#define PCI_TAG(x)    ((x) & 0x7fffff00)
+
+static struct pci_device*
+pci_device_for_cfg_address (CARD32 addr)
+{
+	struct pci_device *dev = NULL;
+	PCITAG tag = PCI_TAG(addr);
+	struct pci_slot_match slot_match = {
+		.domain = PCI_DOM_FROM_TAG(tag),
+		.bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)),
+		.dev = PCI_DEV_FROM_TAG(tag),
+		.func = PCI_FUNC_FROM_TAG(tag),
+		.match_data = 0
+	};
+
+	struct pci_device_iterator *iter =
+	    pci_slot_match_iterator_create (&slot_match);
+
+	if (iter)
+		dev = pci_device_next(iter);
+
+	pci_iterator_destroy(iter);
+
+	return dev;
+}
+
+static int
+pciCfg1in(CARD16 addr, CARD32 *val)
+{
+    if (addr == 0xCF8) {
+	*val = PciCfg1Addr;
+	return 1;
+    }
+    if (addr == 0xCFC) {
+	pci_device_cfg_read_u32(pci_device_for_cfg_address(PciCfg1Addr),
+			(uint32_t *)val, PCI_OFFSET(PciCfg1Addr));
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" cfg_inl(%#lx) = %8.8lx\n", PciCfg1Addr, *val);
+	return 1;
+    }
+    return 0;
+}
+
+static int
+pciCfg1out(CARD16 addr, CARD32 val)
+{
+    if (addr == 0xCF8) {
+	PciCfg1Addr = val;
+	return 1;
+    }
+    if (addr == 0xCFC) {
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" cfg_outl(%#lx, %8.8lx)\n", PciCfg1Addr, val);
+	pci_device_cfg_write_u32(pci_device_for_cfg_address(PciCfg1Addr),
+			val, PCI_OFFSET(PciCfg1Addr));
+	return 1;
+    }
+    return 0;
+}
+
+static int
+pciCfg1inw(CARD16 addr, CARD16 *val)
+{
+    int shift;
+
+    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
+	shift = (addr - 0xCF8) * 8;
+	*val = (PciCfg1Addr >> shift) & 0xffff;
+	return 1;
+    }
+    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
+	const unsigned offset = addr - 0xCFC;
+
+	pci_device_cfg_read_u16(pci_device_for_cfg_address(PciCfg1Addr),
+			val, PCI_OFFSET(PciCfg1Addr) + offset);
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" cfg_inw(%#lx) = %4.4x\n", PciCfg1Addr + offset, *val);
+	return 1;
+    }
+    return 0;
+}
+
+static int
+pciCfg1outw(CARD16 addr, CARD16 val)
+{
+    int shift;
+
+    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
+	shift = (addr - 0xCF8) * 8;
+	PciCfg1Addr &= ~(0xffff << shift);
+	PciCfg1Addr |= ((CARD32) val) << shift;
+	return 1;
+    }
+    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
+	const unsigned offset = addr - 0xCFC;
+
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" cfg_outw(%#lx, %4.4x)\n", PciCfg1Addr + offset, val);
+	pci_device_cfg_write_u16(pci_device_for_cfg_address(PciCfg1Addr),
+			val, PCI_OFFSET(PciCfg1Addr) + offset);
+	return 1;
+    }
+    return 0;
+}
+
+static int
+pciCfg1inb(CARD16 addr, CARD8 *val)
+{
+    int shift;
+
+    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
+	shift = (addr - 0xCF8) * 8;
+	*val = (PciCfg1Addr >> shift) & 0xff;
+	return 1;
+    }
+    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
+	const unsigned offset = addr - 0xCFC;
+
+	pci_device_cfg_read_u8(pci_device_for_cfg_address(PciCfg1Addr),
+			val, PCI_OFFSET(PciCfg1Addr) + offset);
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" cfg_inb(%#lx) = %2.2x\n", PciCfg1Addr + offset, *val);
+	return 1;
+    }
+    return 0;
+}
+
+static int
+pciCfg1outb(CARD16 addr, CARD8 val)
+{
+    int shift;
+
+    if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
+	shift = (addr - 0xCF8) * 8;
+	PciCfg1Addr &= ~(0xff << shift);
+	PciCfg1Addr |= ((CARD32) val) << shift;
+	return 1;
+    }
+    if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
+	const unsigned offset = addr - 0xCFC;
+
+	if (PRINT_PORT && DEBUG_IO_TRACE())
+	    ErrorF(" cfg_outb(%#lx, %2.2x)\n", PciCfg1Addr + offset, val);
+	pci_device_cfg_write_u8(pci_device_for_cfg_address(PciCfg1Addr),
+			val, PCI_OFFSET(PciCfg1Addr) + offset);
+	return 1;
+    }
+    return 0;
+}
+
+CARD8
+bios_checksum(const CARD8 *start, int size)
+{
+    CARD8 sum = 0;
+
+    while (size-- > 0)
+	sum += *start++;
+    return sum;
+}
+
+/*
+ * Lock/Unlock legacy VGA. Some Bioses try to be very clever and make
+ * an attempt to detect a legacy ISA card. If they find one they might
+ * act very strange: for example they might configure the card as a
+ * monochrome card. This might cause some drivers to choke.
+ * To avoid this we attempt legacy VGA by writing to all know VGA
+ * disable registers before we call the BIOS initialization and
+ * restore the original values afterwards. In beween we hold our
+ * breath. To get to a (possibly exising) ISA card need to disable
+ * our current PCI card.
+ */
+/*
+ * This is just for booting: we just want to catch pure
+ * legacy vga therefore we don't worry about mmio etc.
+ * This stuff should really go into vgaHW.c. However then
+ * the driver would have to load the vga-module prior to
+ * doing int10.
+ */
+void
+LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
+{
+    vga->save_msr    = inb(pInt->ioBase + 0x03CC);
+    vga->save_vse    = inb(pInt->ioBase + 0x03C3);
+#ifndef __ia64__
+    vga->save_46e8   = inb(pInt->ioBase + 0x46E8);
+#endif
+    vga->save_pos102 = inb(pInt->ioBase + 0x0102);
+    outb(pInt->ioBase + 0x03C2, ~(CARD8)0x03 & vga->save_msr);
+    outb(pInt->ioBase + 0x03C3, ~(CARD8)0x01 & vga->save_vse);
+#ifndef __ia64__
+    outb(pInt->ioBase + 0x46E8, ~(CARD8)0x08 & vga->save_46e8);
+#endif
+    outb(pInt->ioBase + 0x0102, ~(CARD8)0x01 & vga->save_pos102);
+}
+
+void
+UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
+{
+    outb(pInt->ioBase + 0x0102, vga->save_pos102);
+#ifndef __ia64__
+    outb(pInt->ioBase + 0x46E8, vga->save_46e8);
+#endif
+    outb(pInt->ioBase + 0x03C3, vga->save_vse);
+    outb(pInt->ioBase + 0x03C2, vga->save_msr);
+}
+
+#if defined (_PC)
+static void
+SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set)
+{
+    int pagesize = getpagesize();
+    unsigned char* base = xf86MapVidMem(pInt->scrnIndex,
+					VIDMEM_MMIO, 0, pagesize);
+    int i;
+
+    if (set) {
+	for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
+	    MEM_WW(pInt, i, *(base + i));
+    } else {
+	for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
+	    *(base + i) = MEM_RW(pInt, i);
+    }
+    
+    xf86UnMapVidMem(pInt->scrnIndex,base,pagesize);
+}
+
+void
+xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt, Bool save)
+{
+    int pagesize = getpagesize();
+    unsigned char* base;
+    int i;
+
+    if (!xf86IsEntityPrimary(pInt->entityIndex)
+	|| (!save && !pInt->BIOSScratch))
+	return;
+    
+    base = xf86MapVidMem(pInt->scrnIndex, VIDMEM_MMIO, 0, pagesize);
+    base += BIOS_SCRATCH_OFF;
+    if (save) {
+	if ((pInt->BIOSScratch
+	     = xnfalloc(BIOS_SCRATCH_LEN)))
+	    for (i = 0; i < BIOS_SCRATCH_LEN; i++)
+		*(((char*)pInt->BIOSScratch + i)) = *(base + i);	
+    } else {
+	if (pInt->BIOSScratch) {
+	    for (i = 0; i < BIOS_SCRATCH_LEN; i++)
+		*(base + i) = *(pInt->BIOSScratch + i); 
+	    free(pInt->BIOSScratch);
+	    pInt->BIOSScratch = NULL;
+	}
+    }
+    
+    xf86UnMapVidMem(pInt->scrnIndex,base - BIOS_SCRATCH_OFF ,pagesize);
+}
+#endif
+
+xf86Int10InfoPtr
+xf86InitInt10(int entityIndex)
+{
+    return xf86ExtendedInitInt10(entityIndex, 0);
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c
index 47d3ad14c..d721b131f 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.c
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c
@@ -1,3282 +1,3281 @@
-/*
- * 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;
-}
-
-void
-xf86CrtcSetScanoutFormats(ScrnInfoPtr		scrn,
-			  int			num_formats,
-			  xf86CrtcScanoutFormat	*formats)
-{
-    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
-
-    config->num_scanout_formats = num_formats;
-    config->scanout_formats = formats;
-}
-
-/*
- * 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);
-    pixman_f_transform_init_identity (&crtc->f_screen_to_crtc);
-    pixman_f_transform_init_identity (&crtc->user_sprite_position_transform);
-    pixman_f_transform_init_identity (&crtc->f_crtc_to_cursor);
-    pixman_f_transform_init_identity (&crtc->user_sprite_image_transform);
-    crtc->filter = NULL;
-    crtc->params = NULL;
-    crtc->nparams = 0;
-    crtc->filter_width = 0;
-    crtc->filter_height = 0;
-    crtc->transform_in_use = FALSE;
-    crtc->sprite_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
-xf86CrtcSet(xf86CrtcPtr crtc, xf86CrtcSetRec *set)
-{
-    ScrnInfoPtr		scrn = crtc->scrn;
-    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-    int			i;
-    Bool		ret = FALSE;
-    Bool		didLock = FALSE;
-    DisplayModePtr	adjusted_mode = NULL;
-    DisplayModeRec	saved_mode;
-    int			saved_x, saved_y;
-    Rotation		saved_rotation;
-    RRTransformRec	saved_transform;
-    Bool		saved_transform_present;
-    PixmapPtr		saved_scanout_pixmap;
-
-    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;
-    }
-
-    /* See if nothing has changed */
-    if (!set->flags)
-	return TRUE;
-
-    saved_mode = crtc->mode;
-    saved_x = crtc->x;
-    saved_y = crtc->y;
-    saved_rotation = crtc->rotation;
-    saved_scanout_pixmap = crtc->scanoutPixmap;
-    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.
-     */
-    if (set->flags & XF86CrtcSetMode)
-	crtc->mode = *set->mode;
-    if (set->flags & XF86CrtcSetOrigin) {
-	crtc->x = set->x;
-	crtc->y = set->y;
-    }
-    if (set->flags & XF86CrtcSetRotation)
-	crtc->rotation = set->rotation;
-    if (set->flags & XF86CrtcSetScanoutPixmap)
-	crtc->scanoutPixmap = set->scanout_pixmap;
-
-    if (set->flags & XF86CrtcSetTransform) {
-	if (set->transform) {
-	    RRTransformCopy (&crtc->transform, set->transform);
-	    crtc->transformPresent = TRUE;
-	} else
-	    crtc->transformPresent = FALSE;
-    }
-
-    if (crtc->funcs->set) {
-	ret = crtc->funcs->set(crtc, set->flags);
-	goto done;
-    }
-
-    if (set->flags == XF86CrtcSetOrigin && crtc->funcs->set_origin) {
-	ret = xf86CrtcRotate(crtc);
-	if (ret)
-	    crtc->funcs->set_origin(crtc, crtc->x, crtc->y);
-	goto done;
-    }
-
-    if (crtc->funcs->set_mode_major) {
-	ret = crtc->funcs->set_mode_major(crtc, &crtc->mode,
-					  crtc->rotation,
-					  crtc->x, crtc->y);
-	goto done;
-    }
-
-    adjusted_mode = xf86DuplicateMode(&crtc->mode);
-
-    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, &crtc->mode, adjusted_mode)) {
-	    goto done;
-	}
-    }
-
-    if (!crtc->funcs->mode_fixup(crtc, &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, &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, &crtc->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;
-	crtc->scanoutPixmap = saved_scanout_pixmap;
-    }
-
-    if (adjusted_mode) {
-	free(adjusted_mode->name);
-	free(adjusted_mode);
-    }
-
-    if (didLock)
-	crtc->funcs->unlock (crtc);
-
-    return ret;
-}
-
-/**
- * Pans the screen, does not change the mode
- */
-void
-xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
-{
-    xf86CrtcSetRec	set;
-
-    if (x != crtc->x || y != crtc->y) {
-	set.x = x;
-	set.y = y;
-	set.flags = XF86CrtcSetOrigin;
-	(void) xf86CrtcSet(crtc, &set);
-    }
-}
-
-/*
- * 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)
-{
-    enum { sync_config, sync_edid, sync_default };
-    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 = xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE);
-	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);
-	
-	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;
-	xf86CrtcSetRec	set;
-	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;
-	set.mode = &crtc->desiredMode;
-	set.rotation = crtc->desiredRotation;
-	set.transform = transform;
-	set.x = crtc->desiredX;
-	set.y = crtc->desiredY;
-	set.flags = (XF86CrtcSetMode | XF86CrtcSetOutput |
-		     XF86CrtcSetOrigin | XF86CrtcSetTransform |
-		     XF86CrtcSetRotation);
-	if (!xf86CrtcSet(crtc, &set))
-	    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;
-	xf86CrtcSetRec	set;
-
-	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;
-	}
-	set.mode = crtc_mode;
-	set.rotation = rotation;
-	set.transform = NULL;
-	set.x = 0;
-	set.y = 0;
-	set.flags = (XF86CrtcSetMode | XF86CrtcSetOutput |
-		     XF86CrtcSetOrigin | XF86CrtcSetTransform |
-		     XF86CrtcSetRotation);
-	if (!xf86CrtcSet (crtc, &set))
-	    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;
+}
+
+void
+xf86CrtcSetScanoutFormats(ScrnInfoPtr		scrn,
+			  int			num_formats,
+			  xf86CrtcScanoutFormat	*formats)
+{
+    xf86CrtcConfigPtr	config = XF86_CRTC_CONFIG_PTR(scrn);
+
+    config->num_scanout_formats = num_formats;
+    config->scanout_formats = formats;
+}
+
+/*
+ * 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);
+    pixman_f_transform_init_identity (&crtc->f_screen_to_crtc);
+    pixman_f_transform_init_identity (&crtc->user_sprite_position_transform);
+    pixman_f_transform_init_identity (&crtc->f_crtc_to_cursor);
+    pixman_f_transform_init_identity (&crtc->user_sprite_image_transform);
+    crtc->filter = NULL;
+    crtc->params = NULL;
+    crtc->nparams = 0;
+    crtc->filter_width = 0;
+    crtc->filter_height = 0;
+    crtc->transform_in_use = FALSE;
+    crtc->sprite_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
+xf86CrtcSet(xf86CrtcPtr crtc, xf86CrtcSetRec *set)
+{
+    ScrnInfoPtr		scrn = crtc->scrn;
+    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+    int			i;
+    Bool		ret = FALSE;
+    Bool		didLock = FALSE;
+    DisplayModePtr	adjusted_mode = NULL;
+    DisplayModeRec	saved_mode;
+    int			saved_x, saved_y;
+    Rotation		saved_rotation;
+    RRTransformRec	saved_transform;
+    Bool		saved_transform_present;
+    PixmapPtr		saved_scanout_pixmap;
+
+    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;
+    }
+
+    /* See if nothing has changed */
+    if (!set->flags)
+	return TRUE;
+
+    saved_mode = crtc->mode;
+    saved_x = crtc->x;
+    saved_y = crtc->y;
+    saved_rotation = crtc->rotation;
+    saved_scanout_pixmap = crtc->scanoutPixmap;
+    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.
+     */
+    if (set->flags & XF86CrtcSetMode)
+	crtc->mode = *set->mode;
+    if (set->flags & XF86CrtcSetOrigin) {
+	crtc->x = set->x;
+	crtc->y = set->y;
+    }
+    if (set->flags & XF86CrtcSetRotation)
+	crtc->rotation = set->rotation;
+    if (set->flags & XF86CrtcSetScanoutPixmap)
+	crtc->scanoutPixmap = set->scanout_pixmap;
+
+    if (set->flags & XF86CrtcSetTransform) {
+	if (set->transform) {
+	    RRTransformCopy (&crtc->transform, set->transform);
+	    crtc->transformPresent = TRUE;
+	} else
+	    crtc->transformPresent = FALSE;
+    }
+
+    if (crtc->funcs->set) {
+	ret = crtc->funcs->set(crtc, set->flags);
+	goto done;
+    }
+
+    if (set->flags == XF86CrtcSetOrigin && crtc->funcs->set_origin) {
+	ret = xf86CrtcRotate(crtc);
+	if (ret)
+	    crtc->funcs->set_origin(crtc, crtc->x, crtc->y);
+	goto done;
+    }
+
+    if (crtc->funcs->set_mode_major) {
+	ret = crtc->funcs->set_mode_major(crtc, &crtc->mode,
+					  crtc->rotation,
+					  crtc->x, crtc->y);
+	goto done;
+    }
+
+    adjusted_mode = xf86DuplicateMode(&crtc->mode);
+
+    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, &crtc->mode, adjusted_mode)) {
+	    goto done;
+	}
+    }
+
+    if (!crtc->funcs->mode_fixup(crtc, &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, &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, &crtc->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;
+	crtc->scanoutPixmap = saved_scanout_pixmap;
+    }
+
+    if (adjusted_mode) {
+	free(adjusted_mode->name);
+	free(adjusted_mode);
+    }
+
+    if (didLock)
+	crtc->funcs->unlock (crtc);
+
+    return ret;
+}
+
+/**
+ * Pans the screen, does not change the mode
+ */
+void
+xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
+{
+    xf86CrtcSetRec	set;
+
+    if (x != crtc->x || y != crtc->y) {
+	set.x = x;
+	set.y = y;
+	set.flags = XF86CrtcSetOrigin;
+	(void) xf86CrtcSet(crtc, &set);
+    }
+}
+
+/*
+ * 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 = xf86ReturnOptValBool(output->options, OPTION_DEFAULT_MODES, TRUE);
+	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);
+	
+	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;
+	xf86CrtcSetRec	set;
+	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;
+	set.mode = &crtc->desiredMode;
+	set.rotation = crtc->desiredRotation;
+	set.transform = transform;
+	set.x = crtc->desiredX;
+	set.y = crtc->desiredY;
+	set.flags = (XF86CrtcSetMode | XF86CrtcSetOutput |
+		     XF86CrtcSetOrigin | XF86CrtcSetTransform |
+		     XF86CrtcSetRotation);
+	if (!xf86CrtcSet(crtc, &set))
+	    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;
+	xf86CrtcSetRec	set;
+
+	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;
+	}
+	set.mode = crtc_mode;
+	set.rotation = rotation;
+	set.transform = NULL;
+	set.x = 0;
+	set.y = 0;
+	set.flags = (XF86CrtcSetMode | XF86CrtcSetOutput |
+		     XF86CrtcSetOrigin | XF86CrtcSetTransform |
+		     XF86CrtcSetRotation);
+	if (!xf86CrtcSet (crtc, &set))
+	    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/xwin/winclipboardxevents.c b/xorg-server/hw/xwin/winclipboardxevents.c
index c331f402e..e65717008 100644
--- a/xorg-server/hw/xwin/winclipboardxevents.c
+++ b/xorg-server/hw/xwin/winclipboardxevents.c
@@ -789,6 +789,9 @@ winClipboardFlushXEvents (HWND hwnd,
 	case PropertyNotify:
 	  break;
 
+	case MappingNotify:
+	  break;
+
 	default:
           ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type);
 	  break;
diff --git a/xorg-server/hw/xwin/winconfig.c b/xorg-server/hw/xwin/winconfig.c
index 2503bcb1a..7b26432f2 100644
--- a/xorg-server/hw/xwin/winconfig.c
+++ b/xorg-server/hw/xwin/winconfig.c
@@ -240,6 +240,7 @@ Bool
 winConfigKeyboard (DeviceIntPtr pDevice)
 {
   char                          layoutName[KL_NAMELENGTH];
+  unsigned char                 layoutFriendlyName[256];
   static unsigned int           layoutNum = 0;
   int                           keyboardType;
 #ifdef XWIN_XF86CONFIG
@@ -299,11 +300,32 @@ winConfigKeyboard (DeviceIntPtr pDevice)
 	    if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL)
 	      winMsg (X_INFO, "Loading US keyboard layout.\n");
 	    else
-	      winMsg (X_ERROR, "LoadKeyboardLaout failed.\n");
+	      winMsg (X_ERROR, "LoadKeyboardLayout failed.\n");
 	  }
     }
-    winMsg (X_PROBED, "winConfigKeyboard - Layout: \"%s\" (%08x) \n", 
-            layoutName, layoutNum);
+
+    /* Discover the friendly name of the current layout */
+    {
+      HKEY                regkey = NULL;
+      const char          regtempl[] = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
+      char                *regpath;
+      DWORD               namesize = sizeof(layoutFriendlyName);
+
+      regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
+      strcpy(regpath, regtempl);
+      strcat(regpath, layoutName);
+
+      if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, &regkey))
+          RegQueryValueEx(regkey, "Layout Text", 0, NULL, layoutFriendlyName, &namesize);
+
+      /* Close registry key */
+      if (regkey)
+        RegCloseKey (regkey);
+      free(regpath);
+    }
+
+    winMsg (X_PROBED, "Windows keyboard layout: \"%s\" (%08x) \"%s\", type %d\n",
+            layoutName, layoutNum, layoutFriendlyName, keyboardType);
 
     for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++)
       {
@@ -311,46 +333,35 @@ winConfigKeyboard (DeviceIntPtr pDevice)
 	  continue;
 	if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
 	  continue;
-	
+
         bfound = TRUE;
 	winMsg (X_PROBED,
-		"Using preset keyboard for \"%s\" (%x), type \"%d\"\n",
-		pLayout->layoutname, pLayout->winlayout, keyboardType);
-	
+		"Found matching XKB configuration \"%s\"\n",
+		pLayout->layoutname);
+
+        winMsg(X_PROBED,
+               "Model = \"%s\" Layout = \"%s\""
+               " Variant = \"%s\" Options = \"%s\"\n",
+               pLayout->xkbmodel ? pLayout->xkbmodel : "none",
+               pLayout->xkblayout ? pLayout->xkblayout : "none",
+               pLayout->xkbvariant ? pLayout->xkbvariant : "none",
+               pLayout->xkboptions ? pLayout->xkboptions : "none");
+
 	g_winInfo.xkb.model = pLayout->xkbmodel;
 	g_winInfo.xkb.layout = pLayout->xkblayout;
 	g_winInfo.xkb.variant = pLayout->xkbvariant;
-	g_winInfo.xkb.options = pLayout->xkboptions; 
+	g_winInfo.xkb.options = pLayout->xkboptions;
+
+
 	break;
       }
-    
+
     if (!bfound)
       {
-        HKEY                regkey = NULL;
-        const char          regtempl[] = 
-          "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
-        char                *regpath;
-        unsigned char       lname[256];
-        DWORD               namesize = sizeof(lname);
-
-        regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
-        strcpy(regpath, regtempl);
-        strcat(regpath, layoutName);
-
-        if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, &regkey) &&
-          !RegQueryValueEx(regkey, "Layout Text", 0, NULL, lname, &namesize))
-          {
-	    winMsg (X_ERROR,
-		"Keyboardlayout \"%s\" (%s) is unknown\n", lname, layoutName);
-          }
-
-	/* Close registry key */
-	if (regkey)
-	  RegCloseKey (regkey);
-        free(regpath);
+        winMsg (X_ERROR, "Keyboardlayout \"%s\" (%s) is unknown, using X server default layout\n", layoutFriendlyName, layoutName);
       }
-  }  
-  
+  }
+
   /* parse the configuration */
 #ifdef XWIN_XF86CONFIG
   if (g_cmdline.keyboard)
diff --git a/xorg-server/hw/xwin/winkeybd.c b/xorg-server/hw/xwin/winkeybd.c
index 1a44695c6..94318969f 100644
--- a/xorg-server/hw/xwin/winkeybd.c
+++ b/xorg-server/hw/xwin/winkeybd.c
@@ -73,6 +73,8 @@ winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode)
   int		iParam = HIWORD (lParam);
   int		iParamScanCode = LOBYTE (iParam);
 
+  winDebug("winTranslateKey: wParam %08x lParam %08x\n", wParam, lParam);
+
 /* WM_ key messages faked by Vista speech recognition (WSR) don't have a
  * scan code.
  *
@@ -488,10 +490,8 @@ winSendKeyEvent (DWORD dwKey, Bool fDown)
   for (i = 0; i < nevents; i++)
     mieqEnqueue(g_pwinKeyboard, (InternalEvent*)events[i].event);
 
-#if CYGDEBUG
-  ErrorF("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n",
-          dwKey, fDown, nevents);
-#endif
+  winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n",
+           dwKey, fDown, nevents);
 }
 
 BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam)
diff --git a/xorg-server/hw/xwin/winkeybd.h b/xorg-server/hw/xwin/winkeybd.h
index fc5e6b53a..40fbc179f 100644
--- a/xorg-server/hw/xwin/winkeybd.h
+++ b/xorg-server/hw/xwin/winkeybd.h
@@ -216,13 +216,13 @@ g_iKeyMap [] = {
   /* 170 */	0,		0,		0,
   /* 171 */	0,		0,		0,
   /* 172 */	0,		0,		0,
-  /* 173 */	0,		0,		0,
-  /* 174 */	0,		0,		0,
-  /* 175 */	0,		0,		0,
-  /* 176 */	0,		0,		0,
-  /* 177 */	0,		0,		0,
-  /* 178 */	0,		0,		0,
-  /* 179 */	0,		0,		0,
+  /* 173 */	VK_VOLUME_MUTE,	0,		KEY_Mute,
+  /* 174 */	VK_VOLUME_DOWN,	0,		KEY_AudioLower,
+  /* 175 */	VK_VOLUME_UP,	0,		KEY_AudioRaise,
+  /* 176 */	VK_MEDIA_NEXT_TRACK,	0,	KEY_NEXTSONG,
+  /* 177 */	VK_MEDIA_PREV_TRACK,	0,	KEY_PREVIOUSSONG,
+  /* 178 */	VK_MEDIA_STOP,	0,		KEY_STOPCD,
+  /* 179 */	VK_MEDIA_PLAY_PAUSE,	0,	KEY_PLAYPAUSE,
   /* 180 */	0,		0,		0,
   /* 181 */	0,		0,		0,
   /* 182 */	0,		0,		0,
@@ -266,7 +266,7 @@ g_iKeyMap [] = {
   /* 220 */	0,		0,		0,
   /* 221 */	0,		0,		0,
   /* 222 */	0,		0,		0,
-  /* 223 */	0,		0,		0,
+  /* 223 */	VK_OEM_8,	0,		KEY_RCtrl,  /* at least on Candian Multilingual Standard layout */
   /* 224 */	0,		0,		0,
   /* 225 */	0,		0,		0,
   /* 226 */	0,		0,		0,
diff --git a/xorg-server/hw/xwin/winkeyhook.c b/xorg-server/hw/xwin/winkeyhook.c
index fcf222fd4..e452fa5f7 100644
--- a/xorg-server/hw/xwin/winkeyhook.c
+++ b/xorg-server/hw/xwin/winkeyhook.c
@@ -88,9 +88,7 @@ winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam)
   /* Pass keystrokes on to our main message loop */
   if (iCode == HC_ACTION)
     {
-#if 0
-      ErrorF ("vkCode: %08x\tscanCode: %08x\n", p->vkCode, p->scanCode);
-#endif
+      winDebug("winKeyboardMessageHook: vkCode: %08x scanCode: %08x\n", p->vkCode, p->scanCode);
 
       switch (wParam)
 	{
diff --git a/xorg-server/hw/xwin/winkeynames.h b/xorg-server/hw/xwin/winkeynames.h
index 5649e2f66..a6738330e 100644
--- a/xorg-server/hw/xwin/winkeynames.h
+++ b/xorg-server/hw/xwin/winkeynames.h
@@ -23,10 +23,6 @@
  *
  */
 
-#define XK_TECHNICAL
-#define	XK_KATAKANA
-#include <X11/keysym.h>
-
 #define GLYPHS_PER_KEY	4
 #define NUM_KEYCODES	248
 #define MIN_KEYCODE     8
@@ -194,6 +190,15 @@
 #define KEY_HKTG         /* Hirugana/Katakana tog 0xc8  */  200
 #define KEY_BSlash2      /* \           _         0xcb  */  203
 
+#define KEY_Mute         /* Audio Mute                  */  152
+#define KEY_AudioLower   /* Audio Lower                 */  168
+#define KEY_AudioRaise   /* Audio Raise                 */  166
+
+#define KEY_NEXTSONG     /* Media next                  */  145
+#define KEY_PLAYPAUSE    /* Media play/pause toggle     */  154
+#define KEY_PREVIOUSSONG /* Media previous              */  136
+#define KEY_STOPCD       /* Media stop                  */  156
+
 /* These are for "notused" and "unknown" entries in translation maps. */
 #define KEY_NOTUSED	  0
 #define KEY_UNKNOWN	255
diff --git a/xorg-server/hw/xwin/winlayouts.h b/xorg-server/hw/xwin/winlayouts.h
index 3cbc91244..743f03c39 100644
--- a/xorg-server/hw/xwin/winlayouts.h
+++ b/xorg-server/hw/xwin/winlayouts.h
@@ -55,13 +55,15 @@ WinKBLayoutRec winKBLayouts[] =
     {  0x00010409, -1, "pc105",     "dvorak",    NULL,        NULL, "English (USA,Dvorak)"},
     {  0x00020409, -1, "pc105",     "us_intl",   NULL,        NULL, "English (USA,International)"},
     {  0x00000809, -1, "pc105",     "gb",        NULL,        NULL, "English (United Kingdom)"},
+    {  0x00001009, -1, "pc105",     "ca",        "fr",        NULL, "French (Canada)"},
+    {  0x00011009, -1, "pc105",     "ca",        "multix",    NULL, "Canadian Multilingual Standard"},
     {  0x00001809, -1, "pc105",     "ie",        NULL,        NULL, "Irish"},
     {  0x0000040a, -1, "pc105",     "es",        NULL,        NULL, "Spanish (Spain,Traditional Sort)"},
     {  0x0000080a, -1, "pc105",     "latam",     NULL,        NULL, "Latin American"},
     {  0x0000040b, -1, "pc105",     "fi",        NULL,        NULL, "Finnish"},
     {  0x0000040c, -1, "pc105",     "fr",        NULL,        NULL, "French (Standard)"},
     {  0x0000080c, -1, "pc105",     "be",        NULL,        NULL, "French (Belgian)"},
-    {  0x00000c0c, -1, "pc105",     "ca",        "fr",        NULL, "French (Canada)"},
+    {  0x00000c0c, -1, "pc105",     "ca",        "fr-legacy", NULL, "French (Canada, Legacy)"},
     {  0x0000100c, -1, "pc105",     "ch",        "fr",        NULL, "French (Switzerland)"},
     {  0x0000040d, -1, "pc105",     "il",        NULL,        NULL, "Hebrew"},
     {  0x0000040e, -1, "pc105",     "hu",        NULL,        NULL, "Hungarian"},
@@ -79,6 +81,8 @@ WinKBLayoutRec winKBLayouts[] =
     {  0x00000816, -1, "pc105",     "pt",        NULL,        NULL, "Portuguese (Portugal)"},
     {  0x0000041a, -1, "pc105",     "hr",        NULL,        NULL, "Croatian"},
     {  0x0000041d, -1, "pc105",     "se",        NULL,        NULL, "Swedish (Sweden)"},
+    {  0x0000041f, -1, "pc105",     "tr",        NULL,        NULL, "Turkish (Q)"},
+    {  0x0001041f, -1, "pc105",     "tr",        "f",         NULL, "Turkish (F)"},
     {  0x00000424, -1, "pc105",     "si",        NULL,        NULL, "Slovenian"},
     {  0x00000425, -1, "pc105",     "ee",        NULL,        NULL, "Estonian"},
     {  0x00000452, -1, "pc105",     "gb",        "intl",      NULL, "United Kingdom (Extended)"},
@@ -89,5 +93,3 @@ WinKBLayoutRec winKBLayouts[] =
   See http://technet.microsoft.com/en-us/library/cc766503%28WS.10%29.aspx
   for a listing of input locale (keyboard layout) codes
 */
-
-
-- 
cgit v1.2.3