Submitted By:            Bruce Dubbs <bdubbs at linuxfromscratch dot org>
Date:                    2018-05-12
Initial Package Version: 13.2.1
Upstream Status:         Unknown
Origin:                  Arch Linux
Description:             Fixes for gcc8 and xorg-server-1.20

diff -Naur xf86-video-vmware-13.2.1.orig/saa/saa.c xf86-video-vmware-13.2.1/saa/saa.c
--- xf86-video-vmware-13.2.1.orig/saa/saa.c	2015-12-03 07:55:45.000000000 -0600
+++ xf86-video-vmware-13.2.1/saa/saa.c	2018-05-12 13:30:01.397137316 -0500
@@ -370,6 +370,11 @@
     }
 }
 
+/* compatibility with xserver >= 1.20 */
+#ifndef fbGetRotatedPixmap
+#define fbGetRotatedPixmap(pGC) NULL
+#endif
+
 static void
 saa_validate_gc(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
 {
diff -Naur xf86-video-vmware-13.2.1.orig/src/vmware_bootstrap.c xf86-video-vmware-13.2.1/src/vmware_bootstrap.c
--- xf86-video-vmware-13.2.1.orig/src/vmware_bootstrap.c	2015-12-03 07:55:45.000000000 -0600
+++ xf86-video-vmware-13.2.1/src/vmware_bootstrap.c	2018-05-12 13:30:35.144466742 -0500
@@ -120,7 +120,7 @@
 #define vmwareLegacyRes NULL
 #endif
 
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
 #define VENDOR_ID(p)      (p)->vendor_id
 #define DEVICE_ID(p)      (p)->device_id
 #define SUBVENDOR_ID(p)   (p)->subvendor_id
@@ -134,7 +134,7 @@
 #define CHIP_REVISION(p)  (p)->chipRev
 #endif
 
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
 
 #define VMWARE_DEVICE_MATCH(d, i) \
     {PCI_VENDOR_ID_VMWARE, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
@@ -213,7 +213,7 @@
 static Bool
 VMwarePreinitStub(ScrnInfoPtr pScrn, int flags)
 {
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
     struct pci_device *pciInfo;
 #else
     pciVideoPtr pciInfo;
@@ -261,7 +261,7 @@
     return (*pScrn->PreInit)(pScrn, flags);
 };
 
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
 static Bool
 VMwarePciProbe (DriverPtr           drv,
                 int                 entity_num,
@@ -511,7 +511,7 @@
     VMWARE_DRIVER_VERSION,
     VMWARE_DRIVER_NAME,
     VMWAREIdentify,
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
     NULL,
 #else
     VMWAREProbe,
@@ -523,7 +523,7 @@
     VMWareDriverFunc,
 #endif
 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 4
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
     VMwareDeviceMatch,
     VMwarePciProbe,
 #else
diff -Naur xf86-video-vmware-13.2.1.orig/src/vmware_bootstrap.c.orig xf86-video-vmware-13.2.1/src/vmware_bootstrap.c.orig
--- xf86-video-vmware-13.2.1.orig/src/vmware_bootstrap.c.orig	1969-12-31 18:00:00.000000000 -0600
+++ xf86-video-vmware-13.2.1/src/vmware_bootstrap.c.orig	2015-12-03 07:55:45.000000000 -0600
@@ -0,0 +1,572 @@
+/*
+ * Copyright 2011 VMWare, Inc.
+ * All Rights Reserved.
+ *
+ * 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, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Unknown at vmware
+ * Author: Thomas Hellstrom <thellstrom@vmware.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xf86.h"
+#include "compiler.h"
+#include "xf86Pci.h"		/* pci */
+#include "vm_device_version.h"
+#include "vmware_bootstrap.h"
+#include <stdint.h>
+
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
+#include "xf86Resources.h"
+#endif
+
+#ifndef XSERVER_LIBPCIACCESS
+#include "vm_basic_types.h"
+#include "svga_reg.h"
+#endif
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+#ifdef XSERVER_PLATFORM_BUS
+#include "xf86platformBus.h"
+#endif
+
+#ifdef HaveDriverFuncs
+#define VMWARE_DRIVER_FUNC HaveDriverFuncs
+#else
+#define VMWARE_DRIVER_FUNC 0
+#endif
+
+/*
+ * So that the file compiles unmodified when dropped in to a < 6.9 source tree.
+ */
+#ifndef _X_EXPORT
+#define _X_EXPORT
+#endif
+/*
+ * So that the file compiles unmodified when dropped into an xfree source tree.
+ */
+#ifndef XORG_VERSION_CURRENT
+#define XORG_VERSION_CURRENT XF86_VERSION_CURRENT
+#endif
+
+/*
+ * This is the only way I know to turn a #define of an integer constant into
+ * a constant string.
+ */
+#define VMW_INNERSTRINGIFY(s) #s
+#define VMW_STRING(str) VMW_INNERSTRINGIFY(str)
+
+#define VMWARE_NAME "vmware"
+#define VMWARE_DRIVER_NAME "vmware"
+#define VMWARE_DRIVER_VERSION \
+   (PACKAGE_VERSION_MAJOR * 65536 + PACKAGE_VERSION_MINOR * 256 + PACKAGE_VERSION_PATCHLEVEL)
+#define VMWARE_DRIVER_VERSION_STRING \
+    VMW_STRING(PACKAGE_VERSION_MAJOR) "." VMW_STRING(PACKAGE_VERSION_MINOR) \
+    "." VMW_STRING(PACKAGE_VERSION_PATCHLEVEL)
+
+static const char VMWAREBuildStr[] = "VMware Guest X Server "
+    VMWARE_DRIVER_VERSION_STRING " - build=$Name$\n";
+
+/*
+ * Standard four digit version string expected by VMware Tools installer.
+ * As the driver's version is only  {major, minor, patchlevel},
+ * The fourth digit may describe the commit number relative to the
+ * last version tag as output from `git describe`
+ */
+
+#ifdef __GNUC__
+#ifdef VMW_SUBPATCH
+const char vmware_drv_modinfo[]
+__attribute__((section(".modinfo"),unused)) =
+  "version=" VMWARE_DRIVER_VERSION_STRING "." VMW_STRING(VMW_SUBPATCH);
+#else
+const char vmware_drv_modinfo[]
+__attribute__((section(".modinfo"),unused)) =
+  "version=" VMWARE_DRIVER_VERSION_STRING ".0";
+#endif /*VMW_SUBPATCH*/
+#endif
+
+#ifndef XSERVER_LIBPCIACCESS
+static resRange vmwareLegacyRes[] = {
+    { ResExcIoBlock, SVGA_LEGACY_BASE_PORT,
+      SVGA_LEGACY_BASE_PORT + SVGA_NUM_PORTS*sizeof(uint32)},
+    _VGA_EXCLUSIVE, _END
+};
+#else
+#define vmwareLegacyRes NULL
+#endif
+
+#if XSERVER_LIBPCIACCESS
+#define VENDOR_ID(p)      (p)->vendor_id
+#define DEVICE_ID(p)      (p)->device_id
+#define SUBVENDOR_ID(p)   (p)->subvendor_id
+#define SUBSYS_ID(p)      (p)->subdevice_id
+#define CHIP_REVISION(p)  (p)->revision
+#else
+#define VENDOR_ID(p)      (p)->vendor
+#define DEVICE_ID(p)      (p)->chipType
+#define SUBVENDOR_ID(p)   (p)->subsysVendor
+#define SUBSYS_ID(p)      (p)->subsysCard
+#define CHIP_REVISION(p)  (p)->chipRev
+#endif
+
+#if XSERVER_LIBPCIACCESS
+
+#define VMWARE_DEVICE_MATCH(d, i) \
+    {PCI_VENDOR_ID_VMWARE, (d), PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, (i) }
+
+static const struct pci_id_match VMwareDeviceMatch[] = {
+    VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA2, 0 ),
+    VMWARE_DEVICE_MATCH (PCI_DEVICE_ID_VMWARE_SVGA, 0 ),
+    { 0, 0, 0 },
+};
+#endif
+
+/*
+ * Currently, even the PCI obedient 0405 chip still only obeys IOSE and
+ * MEMSE for the SVGA resources.  Thus, RES_EXCLUSIVE_VGA is required.
+ *
+ * The 0710 chip also uses hardcoded IO ports that aren't disablable.
+ */
+
+static PciChipsets VMWAREPciChipsets[] = {
+    { PCI_DEVICE_ID_VMWARE_SVGA2, PCI_DEVICE_ID_VMWARE_SVGA2, RES_EXCLUSIVE_VGA },
+    { PCI_DEVICE_ID_VMWARE_SVGA, PCI_DEVICE_ID_VMWARE_SVGA, vmwareLegacyRes },
+    { -1,		       -1,		    RES_UNDEFINED }
+};
+
+static SymTabRec VMWAREChipsets[] = {
+    { PCI_DEVICE_ID_VMWARE_SVGA2, "vmware0405" },
+    { PCI_DEVICE_ID_VMWARE_SVGA, "vmware0710" },
+    { -1,                  NULL }
+};
+
+#ifdef XFree86LOADER
+static XF86ModuleVersionInfo vmwareVersRec = {
+    VMWARE_DRIVER_NAME,
+    MODULEVENDORSTRING,
+    MODINFOSTRING1,
+    MODINFOSTRING2,
+    XORG_VERSION_CURRENT,
+    PACKAGE_VERSION_MAJOR, PACKAGE_VERSION_MINOR, PACKAGE_VERSION_PATCHLEVEL,
+    ABI_CLASS_VIDEODRV,
+    ABI_VIDEODRV_VERSION,
+    MOD_CLASS_VIDEODRV,
+    { 0, 0, 0, 0}
+};
+#endif	/* XFree86LOADER */
+
+static const OptionInfoRec VMWAREOptions[] = {
+    { OPTION_HW_CURSOR, "HWcursor",     OPTV_BOOLEAN,   {0},    FALSE },
+    { OPTION_XINERAMA,  "Xinerama",     OPTV_BOOLEAN,   {0},    FALSE },
+    { OPTION_STATIC_XINERAMA, "StaticXinerama", OPTV_STRING, {0}, FALSE },
+    { OPTION_GUI_LAYOUT, "GuiLayout", OPTV_STRING, {0}, FALSE },
+    { OPTION_DEFAULT_MODE, "AddDefaultMode", OPTV_BOOLEAN,   {0},    FALSE },
+    { OPTION_RENDER_ACCEL, "RenderAccel", OPTV_BOOLEAN, {0}, FALSE},
+    { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE},
+    { OPTION_DIRECT_PRESENTS, "DirectPresents", OPTV_BOOLEAN, {0}, FALSE},
+    { OPTION_HW_PRESENTS, "HWPresents", OPTV_BOOLEAN, {0}, FALSE},
+    { OPTION_RENDERCHECK, "RenderCheck", OPTV_BOOLEAN, {0}, FALSE},
+    { -1,               NULL,           OPTV_NONE,      {0},    FALSE }
+};
+
+OptionInfoPtr VMWARECopyOptions(void)
+{
+    OptionInfoPtr options;
+    if (!(options = malloc(sizeof(VMWAREOptions))))
+        return NULL;
+
+    memcpy(options, VMWAREOptions, sizeof(VMWAREOptions));
+    return options;
+}
+
+/*
+ * Also in vmwgfx_hosted.h, which we don't include.
+ */
+void *
+vmwgfx_hosted_detect(void);
+
+static Bool
+VMwarePreinitStub(ScrnInfoPtr pScrn, int flags)
+{
+#if XSERVER_LIBPCIACCESS
+    struct pci_device *pciInfo;
+#else
+    pciVideoPtr pciInfo;
+#endif /* XSERVER_LIBPCIACCESS */
+    EntityInfoPtr pEnt;
+
+    pScrn->PreInit = pScrn->driverPrivate;
+
+#ifdef BUILD_VMWGFX
+    pScrn->driverPrivate = NULL;
+
+    /*
+     * Try vmwgfx path.
+     */
+    if ((*pScrn->PreInit)(pScrn, flags))
+	return TRUE;
+
+    /*
+     * Can't run legacy hosted
+     */
+    if (vmwgfx_hosted_detect())
+	return FALSE;
+#else
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Driver was compiled without KMS- and 3D support.\n");
+#endif /* defined(BUILD_VMWGFX) */
+    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	       "Disabling 3D support.\n");
+    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	       "Disabling Render Acceleration.\n");
+    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+	       "Disabling RandR12+ support.\n");
+
+    pScrn->driverPrivate = NULL;
+    vmwlegacy_hookup(pScrn);
+
+    pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+    pciInfo = xf86GetPciInfoForEntity(pEnt->index);
+    if (pciInfo == NULL)
+        return FALSE;
+
+    pScrn->chipset = (char*)xf86TokenToString(VMWAREChipsets,
+					      DEVICE_ID(pciInfo));
+
+    return (*pScrn->PreInit)(pScrn, flags);
+};
+
+#if XSERVER_LIBPCIACCESS
+static Bool
+VMwarePciProbe (DriverPtr           drv,
+                int                 entity_num,
+                struct pci_device   *device,
+                intptr_t            match_data)
+{
+    ScrnInfoPtr     scrn = NULL;
+
+    scrn = xf86ConfigPciEntity(scrn, 0, entity_num, VMWAREPciChipsets,
+                               NULL, NULL, NULL, NULL, NULL);
+    if (scrn != NULL) {
+        scrn->driverVersion = VMWARE_DRIVER_VERSION;
+        scrn->driverName = VMWARE_DRIVER_NAME;
+        scrn->name = VMWARE_NAME;
+        scrn->Probe = NULL;
+    }
+
+    switch (DEVICE_ID(device)) {
+    case PCI_DEVICE_ID_VMWARE_SVGA2:
+    case PCI_DEVICE_ID_VMWARE_SVGA:
+        xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Valid device\n");
+
+#ifdef BUILD_VMWGFX
+	vmwgfx_hookup(scrn);
+#else
+	vmwlegacy_hookup(scrn);
+#endif /* defined(BUILD_VMWGFX) */
+
+	scrn->driverPrivate = scrn->PreInit;
+	scrn->PreInit = VMwarePreinitStub;
+        break;
+    default:
+        xf86MsgVerb(X_INFO, 4, "VMwarePciProbe: Unknown device\n");
+    }
+    return scrn != NULL;
+}
+#else
+
+/*
+ *----------------------------------------------------------------------
+ *
+ *  RewriteTagString --
+ *
+ *      Rewrites the given string, removing the $Name$, and
+ *      replacing it with the contents.  The output string must
+ *      have enough room, or else.
+ *
+ * Results:
+ *
+ *      Output string updated.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RewriteTagString(const char *istr, char *ostr, int osize)
+{
+    int chr;
+    Bool inTag = FALSE;
+    char *op = ostr;
+
+    do {
+	chr = *istr++;
+	if (chr == '$') {
+	    if (inTag) {
+		inTag = FALSE;
+		for (; op > ostr && op[-1] == ' '; op--) {
+		}
+		continue;
+	    }
+	    if (strncmp(istr, "Name:", 5) == 0) {
+		istr += 5;
+		istr += strspn(istr, " ");
+		inTag = TRUE;
+		continue;
+	    }
+	}
+	*op++ = chr;
+    } while (chr);
+}
+
+static Bool
+VMWAREProbe(DriverPtr drv, int flags)
+{
+    int numDevSections, numUsed;
+    GDevPtr *devSections;
+    int *usedChips;
+    int i;
+    Bool foundScreen = FALSE;
+    char buildString[sizeof(VMWAREBuildStr)];
+
+    RewriteTagString(VMWAREBuildStr, buildString, sizeof(VMWAREBuildStr));
+    xf86MsgVerb(X_PROBED, 4, "%s", buildString);
+
+    numDevSections = xf86MatchDevice(VMWARE_DRIVER_NAME, &devSections);
+    if (numDevSections <= 0) {
+#ifdef DEBUG
+        xf86MsgVerb(X_ERROR, 0, "No vmware driver section\n");
+#endif
+        return FALSE;
+    }
+    if (xf86GetPciVideoInfo()) {
+        VmwareLog(("Some PCI Video Info Exists\n"));
+        numUsed = xf86MatchPciInstances(VMWARE_NAME, PCI_VENDOR_ID_VMWARE,
+                                        VMWAREChipsets, VMWAREPciChipsets, devSections,
+                                        numDevSections, drv, &usedChips);
+        free(devSections);
+        if (numUsed <= 0)
+            return FALSE;
+        if (flags & PROBE_DETECT)
+            foundScreen = TRUE;
+        else
+            for (i = 0; i < numUsed; i++) {
+                ScrnInfoPtr pScrn = NULL;
+
+                VmwareLog(("Even some VMware SVGA PCI instances exists\n"));
+                pScrn = xf86ConfigPciEntity(pScrn, flags, usedChips[i],
+                                            VMWAREPciChipsets, NULL, NULL, NULL,
+                                            NULL, NULL);
+                if (pScrn) {
+                    VmwareLog(("And even configuration suceeded\n"));
+                    pScrn->driverVersion = VMWARE_DRIVER_VERSION;
+                    pScrn->driverName = VMWARE_DRIVER_NAME;
+                    pScrn->name = VMWARE_NAME;
+                    pScrn->Probe = VMWAREProbe;
+
+#ifdef BUILD_VMWGFX
+		    vmwgfx_hookup(pScrn);
+#else
+		    vmwlegacy_hookup(pScrn);
+#endif /* defined(BUILD_VMWGFX) */
+
+		    pScrn->driverPrivate = pScrn->PreInit;
+		    pScrn->PreInit = VMwarePreinitStub;
+                    foundScreen = TRUE;
+                }
+            }
+        free(usedChips);
+    }
+    return foundScreen;
+}
+#endif
+
+#ifdef XSERVER_PLATFORM_BUS
+static Bool
+VMwarePlatformProbe(DriverPtr drv, int entity, int flags,
+                    struct xf86_platform_device *dev, intptr_t match_data)
+{
+    ScrnInfoPtr pScrn;
+    int scrnFlag = 0;
+
+    if (!dev->pdev)
+        return FALSE;
+
+    if (flags & PLATFORM_PROBE_GPU_SCREEN)
+        scrnFlag = XF86_ALLOCATE_GPU_SCREEN;
+
+    pScrn = xf86AllocateScreen(drv, scrnFlag);
+    if (!pScrn)
+        return FALSE;
+
+    if (xf86IsEntitySharable(entity))
+        xf86SetEntityShared(entity);
+
+    xf86AddEntityToScreen(pScrn, entity);
+
+    pScrn->driverVersion = VMWARE_DRIVER_VERSION;
+    pScrn->driverName = VMWARE_DRIVER_NAME;
+    pScrn->name = VMWARE_NAME;
+    pScrn->Probe = NULL;
+#ifdef BUILD_VMWGFX
+    vmwgfx_hookup(pScrn);
+#else
+    vmwlegacy_hookup(pScrn);
+#endif
+    pScrn->driverPrivate = pScrn->PreInit;
+    pScrn->PreInit = VMwarePreinitStub;
+
+    return TRUE;
+}
+#endif
+
+static void
+VMWAREIdentify(int flags)
+{
+    xf86PrintChipsets(VMWARE_NAME, "driver for VMware SVGA", VMWAREChipsets);
+}
+
+static const OptionInfoRec *
+VMWAREAvailableOptions(int chipid, int busid)
+{
+    return VMWAREOptions;
+}
+
+#if VMWARE_DRIVER_FUNC
+static Bool
+VMWareDriverFunc(ScrnInfoPtr pScrn,
+                 xorgDriverFuncOp op,
+                 pointer data)
+{
+   uint32_t *flag;
+   xorgRRModeMM *modemm;
+
+   switch (op) {
+   case GET_REQUIRED_HW_INTERFACES:
+      flag = (uint32_t *)data;
+
+      if (flag) {
+#ifdef BUILD_VMWGFX
+	  vmwgfx_modify_flags(flag);
+#else
+         *flag = HW_IO | HW_MMIO;
+#endif
+      }
+      return TRUE;
+   case RR_GET_MODE_MM:
+      modemm = (xorgRRModeMM *)data;
+
+      /*
+       * Because changing the resolution of the guest is usually changing the size
+       * of a window on the host desktop, the real physical DPI will not change. To
+       * keep the guest in sync, we scale the 'physical' screen dimensions to
+       * keep the DPI constant.
+       */
+      if (modemm && modemm->mode) {
+	  modemm->mmWidth = (modemm->mode->HDisplay * VMWARE_INCHTOMM +
+			     pScrn->xDpi / 2)  / pScrn->xDpi;
+	  modemm->mmHeight = (modemm->mode->VDisplay * VMWARE_INCHTOMM +
+			      pScrn->yDpi / 2) / pScrn->yDpi;
+      }
+      return TRUE;
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 18
+   case SUPPORTS_SERVER_FDS:
+      return TRUE;
+#endif
+   default:
+      return FALSE;
+   }
+}
+#endif
+
+
+_X_EXPORT DriverRec vmware = {
+    VMWARE_DRIVER_VERSION,
+    VMWARE_DRIVER_NAME,
+    VMWAREIdentify,
+#if XSERVER_LIBPCIACCESS
+    NULL,
+#else
+    VMWAREProbe,
+#endif
+    VMWAREAvailableOptions,
+    NULL,
+    0,
+#if VMWARE_DRIVER_FUNC
+    VMWareDriverFunc,
+#endif
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 4
+#if XSERVER_LIBPCIACCESS
+    VMwareDeviceMatch,
+    VMwarePciProbe,
+#else
+    NULL,
+    NULL,
+#endif
+#endif
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 13
+#ifdef XSERVER_PLATFORM_BUS
+    VMwarePlatformProbe,
+#else
+    NULL,
+#endif
+#endif
+};
+
+
+#ifdef XFree86LOADER
+static MODULESETUPPROTO(vmwareSetup);
+
+_X_EXPORT XF86ModuleData vmwareModuleData = {
+    &vmwareVersRec,
+    vmwareSetup,
+    NULL
+};
+
+static pointer
+vmwareSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+    static Bool setupDone = FALSE;
+
+    if (!setupDone) {
+        setupDone = TRUE;
+
+        xf86AddDriver(&vmware, module, VMWARE_DRIVER_FUNC);
+
+        VMWARERefSymLists();
+
+        return (pointer)1;
+    }
+    if (errmaj) {
+        *errmaj = LDR_ONCEONLY;
+    }
+    return NULL;
+}
+#endif	/* XFree86LOADER */
diff -Naur xf86-video-vmware-13.2.1.orig/src/vmware.c xf86-video-vmware-13.2.1/src/vmware.c
--- xf86-video-vmware-13.2.1.orig/src/vmware.c	2015-12-03 07:55:45.000000000 -0600
+++ xf86-video-vmware-13.2.1/src/vmware.c	2018-05-12 13:30:35.143466732 -0500
@@ -322,7 +322,7 @@
            SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT*sizeof(uint32);
     } else {
         /* Note:  This setting of valueReg causes unaligned I/O */
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
         pVMWARE->portIOBase = pVMWARE->PciInfo->regions[0].base_addr;
 #else
         pVMWARE->portIOBase = pVMWARE->PciInfo->ioBase[0];
@@ -364,7 +364,7 @@
     }
     pVMWARE->suspensionSavedRegId = id;
 
-#if !XSERVER_LIBPCIACCESS
+#ifndef XSERVER_LIBPCIACCESS
     pVMWARE->PciTag = pciTag(pVMWARE->PciInfo->bus, pVMWARE->PciInfo->device,
                              pVMWARE->PciInfo->func);
 #endif
@@ -708,13 +708,13 @@
 VMWAREMapMem(ScrnInfoPtr pScrn)
 {
     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
     int err;
     struct pci_device *const device = pVMWARE->PciInfo;
     void *fbBase;
 #endif
 
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
    err = pci_device_map_range(device,
                               pVMWARE->memPhysBase,
                               pVMWARE->videoRam,
@@ -751,7 +751,7 @@
 
     VmwareLog(("Unmapped: %p/%u\n", pVMWARE->FbBase, pVMWARE->videoRam));
 
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
     pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->FbBase, pVMWARE->videoRam);
 #else
     xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->FbBase, pVMWARE->videoRam);
@@ -1026,7 +1026,7 @@
 VMWAREInitFIFO(ScrnInfoPtr pScrn)
 {
     VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
     struct pci_device *const device = pVMWARE->PciInfo;
     int err;
     void *mmioVirtBase;
@@ -1039,7 +1039,7 @@
 
     pVMWARE->mmioPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_MEM_START);
     pVMWARE->mmioSize = vmwareReadReg(pVMWARE, SVGA_REG_MEM_SIZE) & ~3;
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
     err = pci_device_map_range(device, pVMWARE->mmioPhysBase,
                                pVMWARE->mmioSize,
                                PCI_DEV_MAP_FLAG_WRITABLE,
@@ -1080,7 +1080,7 @@
     TRACEPOINT
 
     vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 0);
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
     pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->mmioVirtBase, pVMWARE->mmioSize);
 #else
     xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->mmioVirtBase, pVMWARE->mmioSize);
diff -Naur xf86-video-vmware-13.2.1.orig/src/vmware.c.orig xf86-video-vmware-13.2.1/src/vmware.c.orig
--- xf86-video-vmware-13.2.1.orig/src/vmware.c.orig	1969-12-31 18:00:00.000000000 -0600
+++ xf86-video-vmware-13.2.1/src/vmware.c.orig	2015-12-03 07:55:45.000000000 -0600
@@ -0,0 +1,1664 @@
+/* **********************************************************
+ * Copyright (C) 1998-2001 VMware, Inc.
+ * All Rights Reserved
+ * **********************************************************/
+#ifdef VMX86_DEVEL
+char rcsId_vmware[] =
+    "Id: vmware.c,v 1.11 2001/02/23 02:10:39 yoel Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * TODO: support the vmware linux kernel fb driver (Option "UseFBDev").
+ */
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "compiler.h"	/* inb/outb */
+
+#include "xf86Pci.h"		/* pci */
+
+#include "mipointer.h"		/* sw cursor */
+#include "micmap.h"		/* mi color map */
+#include "vgaHW.h"		/* VGA hardware */
+#include "fb.h"
+#include "shadowfb.h"           /* ShadowFB wrappers */
+
+#include "xf86cmap.h"		/* xf86HandleColormaps */
+
+#include "vmware.h"
+#include "guest_os.h"
+#include "vm_device_version.h"
+#include "svga_modes.h"
+#include "vmware_bootstrap.h"
+#include "vmware_common.h"
+
+#ifndef HAVE_XORG_SERVER_1_5_0
+#include <xf86_ansic.h>
+#include <xf86_libc.h>
+#endif
+
+#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5)
+
+#define xf86LoaderReqSymLists(...) do {} while (0)
+#define LoaderRefSymLists(...) do {} while (0)
+
+#else
+
+const char *vgahwSymbols[] = {
+    "vgaHWGetHWRec",
+    "vgaHWGetIOBase",
+    "vgaHWGetIndex",
+    "vgaHWInit",
+    "vgaHWProtect",
+    "vgaHWRestore",
+    "vgaHWSave",
+    "vgaHWSaveScreen",
+    "vgaHWUnlock",
+    NULL
+};
+
+static const char *fbSymbols[] = {
+    "fbCreateDefColormap",
+    "fbPictureInit",
+    "fbScreenInit",
+    NULL
+};
+
+static const char *ramdacSymbols[] = {
+    "xf86CreateCursorInfoRec",
+    "xf86DestroyCursorInfoRec",
+    "xf86InitCursor",
+    NULL
+};
+
+static const char *shadowfbSymbols[] = {
+    "ShadowFBInit2",
+    NULL
+};
+#endif
+
+/* Table of default modes to always add to the mode list. */
+
+typedef struct {
+   int width;
+   int height;
+} VMWAREDefaultMode;
+
+#define VMW_MIN_INITIAL_WIDTH 800
+#define VMW_MIN_INITIAL_HEIGHT 600
+
+#define SVGA_DEFAULT_MODE(width, height) { width, height, },
+
+static const VMWAREDefaultMode VMWAREDefaultModes[] = {
+   SVGA_DEFAULT_MODES
+};
+
+#undef SVGA_DEFAULT_MODE
+
+static void VMWAREStopFIFO(ScrnInfoPtr pScrn);
+static void VMWARESave(ScrnInfoPtr pScrn);
+
+static Bool
+VMWAREGetRec(ScrnInfoPtr pScrn)
+{
+    if (pScrn->driverPrivate != NULL) {
+        return TRUE;
+    }
+    pScrn->driverPrivate = xnfcalloc(sizeof(VMWARERec), 1);
+    /* FIXME: Initialize driverPrivate... */
+    return TRUE;
+}
+
+static void
+VMWAREFreeRec(ScrnInfoPtr pScrn)
+{
+    if (pScrn->driverPrivate) {
+        free(pScrn->driverPrivate);
+        pScrn->driverPrivate = NULL;
+    }
+}
+
+CARD32
+vmwareReadReg(VMWAREPtr pVMWARE, int index)
+{
+    /*
+     * Block SIGIO for the duration, so we don't get interrupted after the
+     * outl but before the inl by a mouse move (which write to our registers).
+     */
+    int oldsigio, ret;
+    oldsigio = xf86BlockSIGIO();
+    outl(pVMWARE->indexReg, index);
+    ret = inl(pVMWARE->valueReg);
+    xf86UnblockSIGIO(oldsigio);
+    return ret;
+}
+
+void
+vmwareWriteReg(VMWAREPtr pVMWARE, int index, CARD32 value)
+{
+    /*
+     * Block SIGIO for the duration, so we don't get interrupted in between
+     * the outls by a mouse move (which write to our registers).
+     */
+    int oldsigio;
+    oldsigio = xf86BlockSIGIO();
+    outl(pVMWARE->indexReg, index);
+    outl(pVMWARE->valueReg, value);
+    xf86UnblockSIGIO(oldsigio);
+}
+
+void
+vmwareWriteWordToFIFO(VMWAREPtr pVMWARE, CARD32 value)
+{
+    volatile CARD32* vmwareFIFO = pVMWARE->vmwareFIFO;
+
+    /* Need to sync? */
+    if ((vmwareFIFO[SVGA_FIFO_NEXT_CMD] + sizeof(CARD32) == vmwareFIFO[SVGA_FIFO_STOP])
+     || (vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] - sizeof(CARD32) &&
+	 vmwareFIFO[SVGA_FIFO_STOP] == vmwareFIFO[SVGA_FIFO_MIN])) {
+        VmwareLog(("Syncing because of full fifo\n"));
+        vmwareWaitForFB(pVMWARE);
+    }
+
+    vmwareFIFO[vmwareFIFO[SVGA_FIFO_NEXT_CMD] / sizeof(CARD32)] = value;
+
+    write_mem_barrier();
+
+    if(vmwareFIFO[SVGA_FIFO_NEXT_CMD] == vmwareFIFO[SVGA_FIFO_MAX] -
+       sizeof(CARD32)) {
+        vmwareFIFO[SVGA_FIFO_NEXT_CMD] = vmwareFIFO[SVGA_FIFO_MIN];
+    } else {
+        vmwareFIFO[SVGA_FIFO_NEXT_CMD] += sizeof(CARD32);
+    }
+}
+
+void
+vmwareWaitForFB(VMWAREPtr pVMWARE)
+{
+    vmwareWriteReg(pVMWARE, SVGA_REG_SYNC, 1);
+    while (vmwareReadReg(pVMWARE, SVGA_REG_BUSY));
+}
+
+void
+vmwareSendSVGACmdUpdate(VMWAREPtr pVMWARE, BoxPtr pBB)
+{
+    vmwareWriteWordToFIFO(pVMWARE, SVGA_CMD_UPDATE);
+    vmwareWriteWordToFIFO(pVMWARE, pBB->x1);
+    vmwareWriteWordToFIFO(pVMWARE, pBB->y1);
+    vmwareWriteWordToFIFO(pVMWARE, pBB->x2 - pBB->x1);
+    vmwareWriteWordToFIFO(pVMWARE, pBB->y2 - pBB->y1);
+}
+
+void
+vmwareSendSVGACmdUpdateFullScreen(VMWAREPtr pVMWARE)
+{
+    BoxRec BB;
+
+    BB.x1 = 0;
+    BB.y1 = 0;
+    BB.x2 = pVMWARE->ModeReg.svga_reg_width;
+    BB.y2 = pVMWARE->ModeReg.svga_reg_height;
+    vmwareSendSVGACmdUpdate(pVMWARE, &BB);
+}
+
+static CARD32
+vmwareCalculateWeight(CARD32 mask)
+{
+    CARD32 weight;
+
+    for (weight = 0; mask; mask >>= 1) {
+        if (mask & 1) {
+            weight++;
+        }
+    }
+    return weight;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * VMXGetVMwareSvgaId --
+ *
+ *    Retrieve the SVGA_ID of the VMware SVGA adapter.
+ *    This function should hide any backward compatibility mess.
+ *
+ * Results:
+ *    The SVGA_ID_* of the present VMware adapter.
+ *
+ * Side effects:
+ *    ins/outs
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static uint32
+VMXGetVMwareSvgaId(VMWAREPtr pVMWARE)
+{
+    uint32 vmware_svga_id;
+
+    /* Any version with any SVGA_ID_* support will initialize SVGA_REG_ID
+     * to SVGA_ID_0 to support versions of this driver with SVGA_ID_0.
+     *
+     * Versions of SVGA_ID_0 ignore writes to the SVGA_REG_ID register.
+     *
+     * Versions of SVGA_ID_1 will allow us to overwrite the content
+     * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1.
+     *
+     * Versions of SVGA_ID_2 will allow us to overwrite the content
+     * of the SVGA_REG_ID register only with the values SVGA_ID_0 or SVGA_ID_1
+     * or SVGA_ID_2.
+     */
+
+    vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_2);
+    vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+    if (vmware_svga_id == SVGA_ID_2) {
+        return SVGA_ID_2;
+    }
+
+    vmwareWriteReg(pVMWARE, SVGA_REG_ID, SVGA_ID_1);
+    vmware_svga_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+    if (vmware_svga_id == SVGA_ID_1) {
+        return SVGA_ID_1;
+    }
+
+    if (vmware_svga_id == SVGA_ID_0) {
+        return SVGA_ID_0;
+    }
+
+    /* No supported VMware SVGA devices found */
+    return SVGA_ID_INVALID;
+}
+
+static Bool
+VMWAREPreInit(ScrnInfoPtr pScrn, int flags)
+{
+    MessageType from;
+    VMWAREPtr pVMWARE;
+    OptionInfoPtr options;
+    int bpp24flags;
+    uint32 id;
+    int i;
+    ClockRange* clockRanges;
+    unsigned long domainIOBase = 0;
+    uint32 width = 0, height = 0;
+    Bool defaultMode;
+
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12
+#ifndef BUILD_FOR_420
+    domainIOBase = pScrn->domainIOBase;
+#endif
+#endif
+
+    if (flags & PROBE_DETECT) {
+        return FALSE;
+    }
+
+    if (pScrn->numEntities != 1) {
+        return FALSE;
+    }
+
+    if (!VMWAREGetRec(pScrn)) {
+        return FALSE;
+    }
+    pVMWARE = VMWAREPTR(pScrn);
+
+    pVMWARE->pvtSema = &pScrn->vtSema;
+
+    pVMWARE->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+    pVMWARE->PciInfo = xf86GetPciInfoForEntity(pVMWARE->pEnt->index);
+    if (pVMWARE->PciInfo == NULL) {
+        return FALSE;
+    }
+
+    if (DEVICE_ID(pVMWARE->PciInfo) == PCI_DEVICE_ID_VMWARE_SVGA) {
+        pVMWARE->indexReg = domainIOBase +
+           SVGA_LEGACY_BASE_PORT + SVGA_INDEX_PORT*sizeof(uint32);
+        pVMWARE->valueReg = domainIOBase +
+           SVGA_LEGACY_BASE_PORT + SVGA_VALUE_PORT*sizeof(uint32);
+    } else {
+        /* Note:  This setting of valueReg causes unaligned I/O */
+#if XSERVER_LIBPCIACCESS
+        pVMWARE->portIOBase = pVMWARE->PciInfo->regions[0].base_addr;
+#else
+        pVMWARE->portIOBase = pVMWARE->PciInfo->ioBase[0];
+#endif
+        pVMWARE->indexReg = domainIOBase +
+           pVMWARE->portIOBase + SVGA_INDEX_PORT;
+        pVMWARE->valueReg = domainIOBase +
+           pVMWARE->portIOBase + SVGA_VALUE_PORT;
+    }
+    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+               "VMware SVGA regs at (0x%04lx, 0x%04lx)\n",
+               pVMWARE->indexReg, pVMWARE->valueReg);
+
+    if (!xf86LoadSubModule(pScrn, "vgahw")) {
+        return FALSE;
+    }
+
+    xf86LoaderReqSymLists(vgahwSymbols, NULL);
+
+    if (!vgaHWGetHWRec(pScrn)) {
+        return FALSE;
+    }
+
+#ifdef HAVE_XORG_SERVER_1_12_0
+    vgaHWSetStdFuncs(VGAHWPTR(pScrn));
+#endif
+
+    /*
+     * Save the current video state.  Do it here before VMXGetVMwareSvgaId
+     * writes to any registers.
+     */
+    VMWARESave(pScrn);
+
+    id = VMXGetVMwareSvgaId(pVMWARE);
+    if (id == SVGA_ID_0 || id == SVGA_ID_INVALID) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "No supported VMware SVGA found (read ID 0x%08x).\n", id);
+        return FALSE;
+    }
+    pVMWARE->suspensionSavedRegId = id;
+
+#if !XSERVER_LIBPCIACCESS
+    pVMWARE->PciTag = pciTag(pVMWARE->PciInfo->bus, pVMWARE->PciInfo->device,
+                             pVMWARE->PciInfo->func);
+#endif
+    pVMWARE->Primary = xf86IsPrimaryPci(pVMWARE->PciInfo);
+
+    pScrn->monitor = pScrn->confScreen->monitor;
+
+#ifdef ACCELERATE_OPS
+    pVMWARE->vmwareCapability = vmwareReadReg(pVMWARE, SVGA_REG_CAPABILITIES);
+#else
+    pVMWARE->vmwareCapability = vmwareReadReg(pVMWARE, SVGA_REG_CAPABILITIES) &
+	SVGA_CAP_PITCHLOCK;
+#endif
+
+    pVMWARE->bitsPerPixel = vmwareReadReg(pVMWARE,
+                                          SVGA_REG_HOST_BITS_PER_PIXEL);
+    if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+       vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL, pVMWARE->bitsPerPixel);
+    }
+
+    pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH);
+    pVMWARE->videoRam = vmwareReadReg(pVMWARE, SVGA_REG_VRAM_SIZE);
+    pVMWARE->memPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_FB_START);
+    pVMWARE->maxWidth = vmwareReadReg(pVMWARE, SVGA_REG_MAX_WIDTH);
+    pVMWARE->maxHeight = vmwareReadReg(pVMWARE, SVGA_REG_MAX_HEIGHT);
+    pVMWARE->cursorDefined = FALSE;
+    pVMWARE->cursorShouldBeHidden = FALSE;
+
+    if (pVMWARE->vmwareCapability & SVGA_CAP_CURSOR_BYPASS_2) {
+        pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_REMOVE_FROM_FB;
+        pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_RESTORE_TO_FB;
+    } else {
+        pVMWARE->cursorRemoveFromFB = SVGA_CURSOR_ON_HIDE;
+        pVMWARE->cursorRestoreToFB = SVGA_CURSOR_ON_SHOW;
+    }
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "caps:  0x%08X\n", pVMWARE->vmwareCapability);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "depth: %d\n", pVMWARE->depth);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "bpp:   %d\n", pVMWARE->bitsPerPixel);
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "vram:  %d\n", pVMWARE->videoRam);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "pbase: 0x%08lx\n", pVMWARE->memPhysBase);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mwidt: %d\n", pVMWARE->maxWidth);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED, 2, "mheig: %d\n", pVMWARE->maxHeight);
+
+    if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+        bpp24flags = Support24bppFb | Support32bppFb;
+    } else {
+        switch (pVMWARE->depth) {
+        case 16:
+            /*
+             * In certain cases, the Windows host appears to
+             * report 16 bpp and 16 depth but 555 weight.  Just
+             * silently convert it to depth of 15.
+             */
+            if (pVMWARE->bitsPerPixel == 16 &&
+                pVMWARE->weight.green == 5)
+                pVMWARE->depth = 15;
+        case 8:
+        case 15:
+            bpp24flags = NoDepth24Support;
+         break;
+        case 32:
+            /*
+             * There is no 32 bit depth, apparently it can get
+             * reported this way sometimes on the Windows host.
+             */
+            if (pVMWARE->bitsPerPixel == 32)
+                pVMWARE->depth = 24;
+        case 24:
+            if (pVMWARE->bitsPerPixel == 24)
+                bpp24flags = Support24bppFb;
+            else
+                bpp24flags = Support32bppFb;
+            break;
+       default:
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Adapter is using an unsupported depth (%d).\n",
+                       pVMWARE->depth);
+            return FALSE;
+       }
+    }
+
+    if (!xf86SetDepthBpp(pScrn, pVMWARE->depth, pVMWARE->bitsPerPixel,
+                         pVMWARE->bitsPerPixel, bpp24flags)) {
+        return FALSE;
+    }
+
+    /* Check that the returned depth is one we support */
+    switch (pScrn->depth) {
+    case 8:
+    case 15:
+    case 16:
+    case 24:
+        /* OK */
+        break;
+    default:
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "Given depth (%d) is not supported by this driver\n",
+                   pScrn->depth);
+        return FALSE;
+    }
+
+    if (pScrn->bitsPerPixel != pVMWARE->bitsPerPixel) {
+        if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+            vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
+                           pScrn->bitsPerPixel);
+            pVMWARE->bitsPerPixel =
+               vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL);
+            pVMWARE->depth = vmwareReadReg(pVMWARE, SVGA_REG_DEPTH);
+        } else {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Currently unavailable depth/bpp of %d/%d requested.\n"
+                       "\tThe guest X server must run at the same depth and bpp as the host\n"
+                       "\t(which are currently %d/%d).  This is automatically detected.  Please\n"
+                       "\tdo not specify a depth on the command line or via the config file.\n",
+                       pScrn->depth, pScrn->bitsPerPixel,
+                       pVMWARE->depth, pVMWARE->bitsPerPixel);
+            return FALSE;
+        }
+    }
+
+    /*
+     * Defer reading the colour registers until here in case we changed
+     * bpp above.
+     */
+
+    pVMWARE->weight.red =
+       vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_RED_MASK));
+    pVMWARE->weight.green =
+       vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_GREEN_MASK));
+    pVMWARE->weight.blue =
+       vmwareCalculateWeight(vmwareReadReg(pVMWARE, SVGA_REG_BLUE_MASK));
+    pVMWARE->offset.blue = 0;
+    pVMWARE->offset.green = pVMWARE->weight.blue;
+    pVMWARE->offset.red = pVMWARE->weight.green + pVMWARE->offset.green;
+    pVMWARE->defaultVisual = vmwareReadReg(pVMWARE, SVGA_REG_PSEUDOCOLOR) ?
+       PseudoColor : TrueColor;
+
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+                   2, "depth: %d\n", pVMWARE->depth);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+                   2, "bpp:   %d\n", pVMWARE->bitsPerPixel);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+                   2, "w.red: %d\n", (int)pVMWARE->weight.red);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+                   2, "w.grn: %d\n", (int)pVMWARE->weight.green);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+                   2, "w.blu: %d\n", (int)pVMWARE->weight.blue);
+    xf86DrvMsgVerb(pScrn->scrnIndex, X_PROBED,
+                   2, "vis:   %d\n", pVMWARE->defaultVisual);
+
+    if (pScrn->depth != pVMWARE->depth) {
+        if (pVMWARE->vmwareCapability & SVGA_CAP_8BIT_EMULATION) {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Currently unavailable depth of %d requested.\n"
+                       "\tIf the guest X server's BPP matches the host's "
+                       "BPP, then\n\tthe guest X server's depth must also "
+                       "match the\n\thost's depth (currently %d).\n",
+                       pScrn->depth, pVMWARE->depth);
+        } else {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Currently unavailable depth of %d requested.\n"
+                       "\tThe guest X server must run at the same depth as "
+                       "the host (which\n\tis currently %d).  This is "
+                       "automatically detected.  Please do not\n\tspecify "
+                       "a depth on the command line or via the config file.\n",
+                       pScrn->depth, pVMWARE->depth);
+        }
+           return FALSE;
+    }
+    xf86PrintDepthBpp(pScrn);
+
+#if 0
+    if (pScrn->depth == 24 && pix24bpp == 0) {
+        pix24bpp = xf86GetBppFromDepth(pScrn, 24);
+    }
+#endif
+
+    if (pScrn->depth > 8) {
+        rgb zeros = { 0, 0, 0 };
+
+        if (!xf86SetWeight(pScrn, pVMWARE->weight, zeros)) {
+            return FALSE;
+        }
+        /* FIXME check returned weight */
+    }
+    if (!xf86SetDefaultVisual(pScrn, pVMWARE->defaultVisual)) {
+        return FALSE;
+    }
+    if (pScrn->defaultVisual != pVMWARE->defaultVisual) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "Given visual (%d) is not supported by this driver (%d is required)\n",
+                   pScrn->defaultVisual, pVMWARE->defaultVisual);
+        return FALSE;
+    }
+#if 0
+    bytesPerPixel = pScrn->bitsPerPixel / 8;
+#endif
+    pScrn->progClock = TRUE;
+
+#if 0 /* MGA does not do this */
+    if (pScrn->visual != 0) {	/* FIXME */
+        /* print error message */
+        return FALSE;
+    }
+#endif
+
+    xf86CollectOptions(pScrn, NULL);
+    if (!(options = VMWARECopyOptions()))
+        return FALSE;
+    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+    if (pScrn->depth <= 8) {
+        pScrn->rgbBits = 8;
+    }
+
+    if (!pScrn->chipset) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "ChipID 0x%04x is not recognised\n", DEVICE_ID(pVMWARE->PciInfo));
+        return FALSE;
+    }
+
+    from = X_DEFAULT;
+    pVMWARE->hwCursor = TRUE;
+    if (xf86GetOptValBool(options, OPTION_HW_CURSOR, &pVMWARE->hwCursor)) {
+        from = X_CONFIG;
+    }
+    if (pVMWARE->hwCursor && !(pVMWARE->vmwareCapability & SVGA_CAP_CURSOR)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "HW cursor is not supported in this configuration\n");
+        from = X_PROBED;
+        pVMWARE->hwCursor = FALSE;
+    }
+    xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n",
+               pVMWARE->hwCursor ? "HW" : "SW");
+    pScrn->videoRam = pVMWARE->videoRam / 1024;
+    pScrn->memPhysBase = pVMWARE->memPhysBase;
+
+    from = X_DEFAULT;
+    defaultMode = TRUE;
+    if (xf86GetOptValBool(options, OPTION_DEFAULT_MODE, &defaultMode)) {
+        from = X_CONFIG;
+    }
+
+    width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
+    height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
+    width = MAX(width, VMW_MIN_INITIAL_WIDTH);
+    height = MAX(height, VMW_MIN_INITIAL_HEIGHT);
+
+    if (width > pVMWARE->maxWidth || height > pVMWARE->maxHeight) {
+	/*
+	 * This is an error condition and shouldn't happen.
+	 * revert to MIN_INITIAL_ values
+	 */
+	width = VMW_MIN_INITIAL_WIDTH;
+	height = VMW_MIN_INITIAL_HEIGHT;
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, from,
+	       "Will %sset up a driver mode with dimensions %dx%d.\n",
+	       defaultMode ? "" : "not ", width, height);
+
+    free(options);
+
+    {
+        Gamma zeros = { 0.0, 0.0, 0.0 };
+        if (!xf86SetGamma(pScrn, zeros)) {
+            return FALSE;
+        }
+    }
+#if 0
+    if ((i = xf86GetPciInfoForScreen(pScrn->scrnIndex, &pciList, NULL)) != 1) {
+        /* print error message */
+        VMWAREFreeRec(pScrn);
+        if (i > 0) {
+            free(pciList);
+        }
+        return FALSE;
+    }
+#endif
+    clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+    clockRanges->next = NULL;
+    clockRanges->minClock = 1;
+    clockRanges->maxClock = 400000000;
+    clockRanges->clockIndex = -1;
+    clockRanges->interlaceAllowed = FALSE;
+    clockRanges->doubleScanAllowed = FALSE;
+    clockRanges->ClockMulFactor = 1;
+    clockRanges->ClockDivFactor = 1;
+
+    if (defaultMode) {
+	vmwareAddDefaultMode(pScrn, width, height);
+    }
+
+    i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, pScrn->display->modes,
+                          clockRanges, NULL, 256, pVMWARE->maxWidth,
+                          pVMWARE->bitsPerPixel * 1,
+                          128, pVMWARE->maxHeight,
+                          pScrn->display->virtualX, pScrn->display->virtualY,
+                          pVMWARE->videoRam,
+                          LOOKUP_BEST_REFRESH | LOOKUP_OPTIONAL_TOLERANCES);
+
+    if (i == -1) {
+        VMWAREFreeRec(pScrn);
+        return FALSE;
+    }
+    xf86PruneDriverModes(pScrn);
+    if (i == 0 || pScrn->modes == NULL) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n");
+        VMWAREFreeRec(pScrn);
+        return FALSE;
+    }
+
+    pScrn->currentMode = pScrn->modes;
+    pScrn->virtualX = pScrn->modes->HDisplay;
+    pScrn->virtualY = pScrn->modes->VDisplay;
+
+    xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V);
+
+    xf86PrintModes(pScrn);
+    xf86SetDpi(pScrn, 0, 0);
+    if (!xf86LoadSubModule(pScrn, "fb") ||
+        !xf86LoadSubModule(pScrn, "shadowfb")) {
+        VMWAREFreeRec(pScrn);
+        return FALSE;
+    }
+    xf86LoaderReqSymLists(fbSymbols, shadowfbSymbols, NULL);
+
+    /* Need ramdac for hwcursor */
+    if (pVMWARE->hwCursor) {
+        if (!xf86LoadSubModule(pScrn, "ramdac")) {
+            VMWAREFreeRec(pScrn);
+            return FALSE;
+        }
+        xf86LoaderReqSymLists(ramdacSymbols, NULL);
+    }
+
+    return TRUE;
+}
+
+static Bool
+VMWAREMapMem(ScrnInfoPtr pScrn)
+{
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#if XSERVER_LIBPCIACCESS
+    int err;
+    struct pci_device *const device = pVMWARE->PciInfo;
+    void *fbBase;
+#endif
+
+#if XSERVER_LIBPCIACCESS
+   err = pci_device_map_range(device,
+                              pVMWARE->memPhysBase,
+                              pVMWARE->videoRam,
+                              PCI_DEV_MAP_FLAG_WRITABLE,
+			      &fbBase);
+   if (err) {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                  "Unable to map frame buffer BAR. %s (%d)\n",
+                  strerror (err), err);
+       return FALSE;
+   }
+   pVMWARE->FbBase = fbBase;
+#else
+    pVMWARE->FbBase = xf86MapPciMem(pScrn->scrnIndex, 0,
+                                    pVMWARE->PciTag,
+                                    pVMWARE->memPhysBase,
+                                    pVMWARE->videoRam);
+#endif
+    if (!pVMWARE->FbBase)
+        return FALSE;
+
+    VmwareLog(("FB Mapped: %p/%u -> %p/%u\n",
+               pVMWARE->memPhysBase, pVMWARE->videoRam,
+               pVMWARE->FbBase, pVMWARE->videoRam));
+    return TRUE;
+}
+
+static Bool
+VMWAREUnmapMem(ScrnInfoPtr pScrn)
+{
+    VMWAREPtr pVMWARE;
+
+    pVMWARE = VMWAREPTR(pScrn);
+
+    VmwareLog(("Unmapped: %p/%u\n", pVMWARE->FbBase, pVMWARE->videoRam));
+
+#if XSERVER_LIBPCIACCESS
+    pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->FbBase, pVMWARE->videoRam);
+#else
+    xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->FbBase, pVMWARE->videoRam);
+#endif
+    pVMWARE->FbBase = NULL;
+    return TRUE;
+}
+
+static void
+VMWARESave(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    vgaRegPtr vgaReg = &hwp->SavedReg;
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+    VMWARERegPtr vmwareReg = &pVMWARE->SavedReg;
+
+    vgaHWSave(pScrn, vgaReg, VGA_SR_ALL);
+
+    vmwareReg->svga_reg_enable = vmwareReadReg(pVMWARE, SVGA_REG_ENABLE);
+    vmwareReg->svga_reg_width = vmwareReadReg(pVMWARE, SVGA_REG_WIDTH);
+    vmwareReg->svga_reg_height = vmwareReadReg(pVMWARE, SVGA_REG_HEIGHT);
+    vmwareReg->svga_reg_bits_per_pixel =
+       vmwareReadReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL);
+    vmwareReg->svga_reg_id = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+
+    /* XXX this should be based on the cap bit, not hwCursor... */
+    if (pVMWARE->hwCursor) {
+       vmwareReg->svga_reg_cursor_on =
+          vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ON);
+       vmwareReg->svga_reg_cursor_x =
+          vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_X);
+       vmwareReg->svga_reg_cursor_y =
+          vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_Y);
+       vmwareReg->svga_reg_cursor_id =
+          vmwareReadReg(pVMWARE, SVGA_REG_CURSOR_ID);
+    }
+
+    vmwareReg->svga_fifo_enabled = vmwareReadReg(pVMWARE, SVGA_REG_CONFIG_DONE);
+}
+
+static void
+VMWARERestoreRegs(ScrnInfoPtr pScrn, VMWARERegPtr vmwareReg)
+{
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+    VmwareLog(("VMWARERestoreRegs: W: %d, H: %d, BPP: %d, Enable: %d\n",
+	       vmwareReg->svga_reg_width, vmwareReg->svga_reg_height,
+	       vmwareReg->svga_reg_bits_per_pixel, vmwareReg->svga_reg_enable));
+    if (vmwareReg->svga_reg_enable) {
+        vmwareWriteReg(pVMWARE, SVGA_REG_ID, vmwareReg->svga_reg_id);
+        vmwareWriteReg(pVMWARE, SVGA_REG_WIDTH, vmwareReg->svga_reg_width);
+        vmwareWriteReg(pVMWARE, SVGA_REG_HEIGHT, vmwareReg->svga_reg_height);
+        vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
+                       vmwareReg->svga_reg_bits_per_pixel);
+        vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
+        vmwareWriteReg(pVMWARE, SVGA_REG_GUEST_ID, GUEST_OS_LINUX);
+        if (pVMWARE->hwCursor) {
+            vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ID,
+                           vmwareReg->svga_reg_cursor_id);
+            vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_X,
+                           vmwareReg->svga_reg_cursor_x);
+            vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_Y,
+                           vmwareReg->svga_reg_cursor_y);
+            vmwareWriteReg(pVMWARE, SVGA_REG_CURSOR_ON,
+                           vmwareReg->svga_reg_cursor_on);
+        }
+    } else {
+        vmwareWriteReg(pVMWARE, SVGA_REG_ID, vmwareReg->svga_reg_id);
+        vmwareWriteReg(pVMWARE, SVGA_REG_WIDTH, vmwareReg->svga_reg_width);
+        vmwareWriteReg(pVMWARE, SVGA_REG_HEIGHT, vmwareReg->svga_reg_height);
+        vmwareWriteReg(pVMWARE, SVGA_REG_BITS_PER_PIXEL,
+                       vmwareReg->svga_reg_bits_per_pixel);
+	vmwareWriteReg(pVMWARE, SVGA_REG_ENABLE, vmwareReg->svga_reg_enable);
+    }
+}
+
+static void
+VMWARERestore(ScrnInfoPtr pScrn)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    vgaRegPtr vgaReg = &hwp->SavedReg;
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+    VMWARERegPtr vmwareReg = &pVMWARE->SavedReg;
+
+    vmwareWaitForFB(pVMWARE);
+    if (!vmwareReg->svga_fifo_enabled) {
+        VMWAREStopFIFO(pScrn);
+    }
+
+    vgaHWProtect(pScrn, TRUE);
+    VMWARERestoreRegs(pScrn, vmwareReg);
+    vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+    vgaHWProtect(pScrn, FALSE);
+}
+
+static Bool
+VMWAREModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool rebuildPixmap)
+{
+    vgaHWPtr hwp = VGAHWPTR(pScrn);
+    vgaRegPtr vgaReg = &hwp->ModeReg;
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+    VMWARERegPtr vmwareReg = &pVMWARE->ModeReg;
+
+    vgaHWUnlock(hwp);
+    if (!vgaHWInit(pScrn, mode))
+        return FALSE;
+    pScrn->vtSema = TRUE;
+
+    if (pVMWARE->vmwareCapability & SVGA_CAP_PITCHLOCK)
+	vmwareWriteReg(pVMWARE, SVGA_REG_PITCHLOCK, 0);
+    vmwareReg->svga_reg_enable = 1;
+    vmwareReg->svga_reg_width = max(mode->HDisplay, pScrn->virtualX);
+    vmwareReg->svga_reg_height = max(mode->VDisplay, pScrn->virtualY);
+    vmwareReg->svga_reg_bits_per_pixel = pVMWARE->bitsPerPixel;
+
+    vgaHWProtect(pScrn, TRUE);
+
+    vgaHWRestore(pScrn, vgaReg, VGA_SR_ALL);
+    VMWARERestoreRegs(pScrn, vmwareReg);
+
+    if (pVMWARE->hwCursor) {
+        vmwareCursorModeInit(pScrn, mode);
+    }
+
+    VmwareLog(("Required mode: %ux%u\n", mode->HDisplay, mode->VDisplay));
+    VmwareLog(("Virtual:       %ux%u\n", pScrn->virtualX, pScrn->virtualY));
+    VmwareLog(("dispWidth:     %u\n", pScrn->displayWidth));
+    pVMWARE->fbOffset = vmwareReadReg(pVMWARE, SVGA_REG_FB_OFFSET);
+    pVMWARE->fbPitch = vmwareReadReg(pVMWARE, SVGA_REG_BYTES_PER_LINE);
+    pVMWARE->FbSize = vmwareReadReg(pVMWARE, SVGA_REG_FB_SIZE);
+
+    pScrn->displayWidth = (pVMWARE->fbPitch * 8) / ((pScrn->bitsPerPixel + 7) & ~7);
+    VmwareLog(("fbOffset:      %u\n", pVMWARE->fbOffset));
+    VmwareLog(("fbPitch:       %u\n", pVMWARE->fbPitch));
+    VmwareLog(("fbSize:        %u\n", pVMWARE->FbSize));
+    VmwareLog(("New dispWidth: %u\n", pScrn->displayWidth));
+
+    vmwareCheckVideoSanity(pScrn);
+
+    if (rebuildPixmap) {
+        pScrn->pScreen->ModifyPixmapHeader((*pScrn->pScreen->GetScreenPixmap)(pScrn->pScreen),
+                                           pScrn->pScreen->width,
+                                           pScrn->pScreen->height,
+                                           pScrn->pScreen->rootDepth,
+                                           pScrn->bitsPerPixel,
+                                           PixmapBytePad(pScrn->displayWidth,
+                                                         pScrn->pScreen->rootDepth),
+                                           (pointer)(pVMWARE->FbBase + pScrn->fbOffset));
+
+        (*pScrn->EnableDisableFBAccess)(XF86_SCRN_ARG(pScrn), FALSE);
+        (*pScrn->EnableDisableFBAccess)(XF86_SCRN_ARG(pScrn), TRUE);
+    }
+
+    vgaHWProtect(pScrn, FALSE);
+
+    /*
+     * Push the new Xinerama state to X clients and the hardware,
+     * synchronously with the mode change. Note that this must happen
+     * AFTER we write the new width and height to the hardware
+     * registers, since updating the WIDTH and HEIGHT registers will
+     * reset the device's multimon topology.
+     */
+    vmwareNextXineramaState(pVMWARE);
+
+    return TRUE;
+}
+
+void
+vmwareNextXineramaState(VMWAREPtr pVMWARE)
+{
+    VMWARERegPtr vmwareReg = &pVMWARE->ModeReg;
+
+    /*
+     * Switch to the next Xinerama state (from pVMWARE->xineramaNextState).
+     *
+     * This new state will be available to X clients via the Xinerama
+     * extension, and we push the new state to the virtual hardware,
+     * in order to configure a number of virtual monitors within the
+     * device's framebuffer.
+     *
+     * This function can be called at any time, but it should usually be
+     * called just after a mode switch. This is for two reasons:
+     *
+     *   1) We don't want X clients to see a Xinerama topology and a video
+     *      mode that are inconsistent with each other, so we'd like to switch
+     *      both at the same time.
+     *
+     *   2) We must set the host's display topology registers after setting
+     *      the new video mode, since writes to WIDTH/HEIGHT will reset the
+     *      hardware display topology.
+     */
+
+    /*
+     * Update Xinerama info appropriately.
+     */
+    if (pVMWARE->xinerama && !pVMWARE->xineramaStatic) {
+       if (pVMWARE->xineramaNextState) {
+          free(pVMWARE->xineramaState);
+          pVMWARE->xineramaState = pVMWARE->xineramaNextState;
+          pVMWARE->xineramaNumOutputs = pVMWARE->xineramaNextNumOutputs;
+
+          pVMWARE->xineramaNextState = NULL;
+          pVMWARE->xineramaNextNumOutputs = 0;
+
+       } else {
+          /*
+           * There is no next state pending. Switch back to
+           * single-monitor mode. This is necessary for resetting the
+           * Xinerama state if we get a mode change which doesn't
+           * follow a VMwareCtrlDoSetTopology call.
+           */
+          VMWAREXineramaPtr basicState =
+             (VMWAREXineramaPtr)calloc(1, sizeof (VMWAREXineramaRec));
+          if (basicState) {
+             basicState->x_org = 0;
+             basicState->y_org = 0;
+             basicState->width = vmwareReg->svga_reg_width;
+             basicState->height = vmwareReg->svga_reg_height;
+
+             free(pVMWARE->xineramaState);
+             pVMWARE->xineramaState = basicState;
+             pVMWARE->xineramaNumOutputs = 1;
+          }
+       }
+    }
+
+    /*
+     * Update host's view of guest topology. This tells the device
+     * how we're carving up its framebuffer into virtual screens.
+     */
+    if (pVMWARE->vmwareCapability & SVGA_CAP_DISPLAY_TOPOLOGY) {
+        if (pVMWARE->xinerama) {
+            int i = 0;
+            VMWAREXineramaPtr xineramaState = pVMWARE->xineramaState;
+            vmwareWriteReg(pVMWARE, SVGA_REG_NUM_GUEST_DISPLAYS,
+                           pVMWARE->xineramaNumOutputs);
+
+            for (i = 0; i < pVMWARE->xineramaNumOutputs; i++) {
+                vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, i);
+                vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_IS_PRIMARY, i == 0);
+                vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_X,
+                               xineramaState[i].x_org);
+                vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_Y,
+                               xineramaState[i].y_org);
+                vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH,
+                               xineramaState[i].width);
+                vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT,
+                               xineramaState[i].height);
+            }
+        } else {
+            vmwareWriteReg(pVMWARE, SVGA_REG_NUM_GUEST_DISPLAYS, 1);
+
+            vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, 0);
+            vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_IS_PRIMARY, TRUE);
+            vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_X, 0);
+            vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_POSITION_Y, 0);
+            vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_WIDTH, vmwareReg->svga_reg_width);
+            vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_HEIGHT, vmwareReg->svga_reg_height);
+        }
+
+        /* Done. */
+        vmwareWriteReg(pVMWARE, SVGA_REG_DISPLAY_ID, SVGA_INVALID_DISPLAY_ID);
+    }
+}
+
+static void
+VMWAREAdjustFrame(ADJUST_FRAME_ARGS_DECL)
+{
+    /* FIXME */
+}
+
+static void
+VMWAREInitFIFO(ScrnInfoPtr pScrn)
+{
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+#if XSERVER_LIBPCIACCESS
+    struct pci_device *const device = pVMWARE->PciInfo;
+    int err;
+    void *mmioVirtBase;
+#endif
+    volatile CARD32* vmwareFIFO;
+    Bool extendedFifo;
+    int min;
+
+    TRACEPOINT
+
+    pVMWARE->mmioPhysBase = vmwareReadReg(pVMWARE, SVGA_REG_MEM_START);
+    pVMWARE->mmioSize = vmwareReadReg(pVMWARE, SVGA_REG_MEM_SIZE) & ~3;
+#if XSERVER_LIBPCIACCESS
+    err = pci_device_map_range(device, pVMWARE->mmioPhysBase,
+                               pVMWARE->mmioSize,
+                               PCI_DEV_MAP_FLAG_WRITABLE,
+                               &mmioVirtBase);
+    if (err) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "Unable to map mmio BAR. %s (%d)\n",
+                   strerror (err), err);
+        return;
+    }
+    pVMWARE->mmioVirtBase = mmioVirtBase;
+#else
+    pVMWARE->mmioVirtBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
+                                          pVMWARE->PciTag,
+                                          pVMWARE->mmioPhysBase,
+                                          pVMWARE->mmioSize);
+#endif
+    vmwareFIFO = pVMWARE->vmwareFIFO = (CARD32*)pVMWARE->mmioVirtBase;
+
+    extendedFifo = pVMWARE->vmwareCapability & SVGA_CAP_EXTENDED_FIFO;
+    min = extendedFifo ? vmwareReadReg(pVMWARE, SVGA_REG_MEM_REGS) : 4;
+
+    vmwareWaitForFB(pVMWARE);
+    vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 0);
+
+    vmwareFIFO[SVGA_FIFO_MIN] = min * sizeof(CARD32);
+    vmwareFIFO[SVGA_FIFO_MAX] = pVMWARE->mmioSize;
+    vmwareFIFO[SVGA_FIFO_NEXT_CMD] = min * sizeof(CARD32);
+    vmwareFIFO[SVGA_FIFO_STOP] = min * sizeof(CARD32);
+    vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 1);
+}
+
+static void
+VMWAREStopFIFO(ScrnInfoPtr pScrn)
+{
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+    TRACEPOINT
+
+    vmwareWriteReg(pVMWARE, SVGA_REG_CONFIG_DONE, 0);
+#if XSERVER_LIBPCIACCESS
+    pci_device_unmap_range(pVMWARE->PciInfo, pVMWARE->mmioVirtBase, pVMWARE->mmioSize);
+#else
+    xf86UnMapVidMem(pScrn->scrnIndex, pVMWARE->mmioVirtBase, pVMWARE->mmioSize);
+#endif
+}
+
+static Bool
+VMWARECloseScreen(CLOSE_SCREEN_ARGS_DECL)
+{
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+    ScreenPtr save = &pVMWARE->ScrnFuncs;
+
+    VmwareLog(("cursorSema: %d\n", pVMWARE->cursorSema));
+
+    if (*pVMWARE->pvtSema) {
+        if (pVMWARE->videoStreams) {
+            vmwareVideoEnd(pScreen);
+        }
+
+        if (pVMWARE->CursorInfoRec) {
+            vmwareCursorCloseScreen(pScreen);
+        }
+
+        VMWARERestore(pScrn);
+        VMWAREUnmapMem(pScrn);
+
+        pScrn->vtSema = FALSE;
+    }
+
+    pScreen->CloseScreen = save->CloseScreen;
+    pScreen->SaveScreen = save->SaveScreen;
+
+#if VMWARE_DRIVER_FUNC
+    pScrn->DriverFunc = NULL;
+#endif
+
+    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
+}
+
+static Bool
+VMWARESaveScreen(ScreenPtr pScreen, int mode)
+{
+    VmwareLog(("VMWareSaveScreen() mode = %d\n", mode));
+
+    /*
+     * This thoroughly fails to do anything useful to svga mode.  I doubt
+     * we care; who wants to idle-blank their VM's screen anyway?
+     */
+    return vgaHWSaveScreen(pScreen, mode);
+}
+
+/* disabled by default to reduce spew in DEBUG_LOGGING mode. */
+/*#define DEBUG_LOG_UPDATES*/
+
+static void
+VMWAREPreDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr)
+{
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+#ifdef DEBUG_LOG_UPDATES
+    {
+        int i;
+        for (i = 0; i < nboxes; i++) {
+            VmwareLog(("PreUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes - i,
+                       boxPtr[i].x1, boxPtr[i].y1,
+                       boxPtr[i].x2 - boxPtr[i].x1,
+                       boxPtr[i].y2 - boxPtr[i].y1));
+        }
+    }
+#endif
+
+    /*
+     * We only register this callback if we have a HW cursor.
+     */
+    while (nboxes--) {
+        if (BOX_INTERSECT(*boxPtr, pVMWARE->hwcur.box)) {
+            if (!pVMWARE->cursorExcludedForUpdate) {
+                PRE_OP_HIDE_CURSOR();
+                pVMWARE->cursorExcludedForUpdate = TRUE;
+            }
+	    break;
+        }
+        boxPtr++;
+    }
+}
+
+static void
+VMWAREPostDirtyBBUpdate(ScrnInfoPtr pScrn, int nboxes, BoxPtr boxPtr)
+{
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+    while (nboxes--) {
+#ifdef DEBUG_LOG_UPDATES
+        VmwareLog(("PostUpdate #%d (%d, %d, w = %d, h = %d)\n", nboxes,
+                   boxPtr->x1, boxPtr->y1,
+                   boxPtr->x2 - boxPtr->x1, boxPtr->y2 - boxPtr->y1));
+#endif
+
+        /* Clip off (y only) for offscreen memory */
+        if (boxPtr->y2 >= pVMWARE->ModeReg.svga_reg_height)
+            boxPtr->y2 = pVMWARE->ModeReg.svga_reg_height;
+        if (boxPtr->y1 >= pVMWARE->ModeReg.svga_reg_height)
+            boxPtr->y1 = pVMWARE->ModeReg.svga_reg_height;
+        if (boxPtr->y1 == boxPtr->y2) {
+            boxPtr++;
+            continue;
+        }
+
+        vmwareSendSVGACmdUpdate(pVMWARE, boxPtr++);
+    }
+
+    if (pVMWARE->hwCursor && pVMWARE->cursorExcludedForUpdate) {
+        POST_OP_SHOW_CURSOR();
+        pVMWARE->cursorExcludedForUpdate = FALSE;
+    }
+}
+
+static void
+VMWARELoadPalette(ScrnInfoPtr pScrn, int numColors, int* indices,
+                  LOCO* colors, VisualPtr pVisual)
+{
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+    int i;
+
+    for (i = 0; i < numColors; i++) {
+        vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 0, colors[*indices].red);
+        vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 1, colors[*indices].green);
+        vmwareWriteReg(pVMWARE, SVGA_PALETTE_BASE + *indices * 3 + 2, colors[*indices].blue);
+        indices++;
+    }
+    VmwareLog(("Palette loading done\n"));
+}
+
+
+DisplayModeRec *
+VMWAREAddDisplayMode(ScrnInfoPtr pScrn,
+                     const char *name,
+                     int width,
+                     int height)
+{
+   DisplayModeRec *mode;
+
+   mode = malloc(sizeof(DisplayModeRec));
+   memset(mode, 0, sizeof *mode);
+
+   mode->name = malloc(strlen(name) + 1);
+   strcpy(mode->name, name);
+   mode->status = MODE_OK;
+   mode->type = M_T_DEFAULT;
+   mode->HDisplay = width;
+   mode->VDisplay = height;
+
+   mode->next = pScrn->modes;
+   mode->prev = pScrn->modes->prev;
+   pScrn->modes->prev->next = mode;
+   pScrn->modes->prev = mode;
+
+   return mode;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * vmwareIsRegionEqual --
+ *
+ *    This function implements REGION_EQUAL because older versions of
+ *    regionstr.h don't define it.
+ *    It is a slightly modified version of miRegionEqual from $Xorg: miregion.c
+ *
+ * Results:
+ *    TRUE if regions are equal; FALSE otherwise
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+Bool
+vmwareIsRegionEqual(const RegionPtr reg1,
+                    const RegionPtr reg2)
+{
+    int i, num;
+    BoxPtr rects1, rects2;
+
+    if ((reg1->extents.x1 != reg2->extents.x1) ||
+        (reg1->extents.x2 != reg2->extents.x2) ||
+        (reg1->extents.y1 != reg2->extents.y1) ||
+        (reg1->extents.y2 != reg2->extents.y2)) {
+        return FALSE;
+    }
+
+    num = REGION_NUM_RECTS(reg1);
+    if (num != REGION_NUM_RECTS(reg2)) {
+        return FALSE;
+    }
+
+    rects1 = REGION_RECTS(reg1);
+    rects2 = REGION_RECTS(reg2);
+
+    for (i = 0; i < num; i++) {
+        if ((rects1[i].x1 != rects2[i].x1) ||
+            (rects1[i].x2 != rects2[i].x2) ||
+            (rects1[i].y1 != rects2[i].y1) ||
+            (rects1[i].y2 != rects2[i].y2)) {
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+static Bool
+VMWAREScreenInit(SCREEN_INIT_ARGS_DECL)
+{
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    vgaHWPtr hwp;
+    VMWAREPtr pVMWARE;
+    OptionInfoPtr options;
+    Bool useXinerama = TRUE;
+
+    pVMWARE = VMWAREPTR(pScrn);
+
+
+    xf86CollectOptions(pScrn, NULL);
+    if (!(options = VMWARECopyOptions()))
+        return FALSE;
+    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+    /*
+     * Init xinerama preferences.
+     */
+    useXinerama = xf86ReturnOptValBool(options, OPTION_XINERAMA,
+                                       pVMWARE->vmwareCapability & SVGA_CAP_MULTIMON);
+    if (useXinerama && !(pVMWARE->vmwareCapability & SVGA_CAP_MULTIMON)) {
+       xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                  "Xinerama is not safely supported by the current virtual hardware. "
+                  "Do not request resolutions that require > 16MB of framebuffer.\n");
+    }
+
+
+    if (useXinerama && xf86IsOptionSet(options, OPTION_GUI_LAYOUT)) {
+       char *topology = xf86GetOptValString(options, OPTION_GUI_LAYOUT);
+       if (topology) {
+          pVMWARE->xineramaState =
+             VMWAREParseTopologyString(pScrn, topology,
+				       &pVMWARE->xineramaNumOutputs, "gui");
+
+         pVMWARE->xineramaStatic = pVMWARE->xineramaState != NULL;
+
+         free(topology);
+       }
+    } else if (useXinerama &&
+	       xf86IsOptionSet(options, OPTION_STATIC_XINERAMA)) {
+       char *topology = xf86GetOptValString(options, OPTION_STATIC_XINERAMA);
+       if (topology) {
+          pVMWARE->xineramaState =
+             VMWAREParseTopologyString(pScrn, topology,
+				       &pVMWARE->xineramaNumOutputs,
+				       "static Xinerama");
+
+         pVMWARE->xineramaStatic = pVMWARE->xineramaState != NULL;
+
+         free(topology);
+       }
+    }
+
+    free(options);
+
+    /* Initialise VMWARE_CTRL extension. */
+    VMwareCtrl_ExtInit(pScrn);
+
+    /* Initialise Xinerama extension. */
+    if (useXinerama) {
+       VMwareXinerama_ExtInit(pScrn);
+    }
+
+    if (pVMWARE->xinerama && pVMWARE->xineramaStatic) {
+       xf86DrvMsg(pScrn->scrnIndex, X_INFO, pVMWARE->xineramaState ?
+                                            "Using static Xinerama.\n" :
+                                            "Failed to configure static Xinerama.\n");
+    }
+
+    /*
+     * If using the vgahw module, its data structures and related
+     * things are typically initialised/mapped here.
+     */
+    hwp = VGAHWPTR(pScrn);
+    vgaHWGetIOBase(hwp);
+
+    VMWAREInitFIFO(pScrn);
+
+    /* Initialise the first mode */
+    VMWAREModeInit(pScrn, pScrn->currentMode, FALSE);
+
+    /* Set the viewport if supported */
+    VMWAREAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0));
+
+    /*
+     * Setup the screen's visuals, and initialise the framebuffer
+     * code.
+     */
+    VMWAREMapMem(pScrn);
+
+    /*
+     * Clear the framebuffer (and any black-border mode areas).
+     */
+    memset(pVMWARE->FbBase, 0, pVMWARE->FbSize);
+    vmwareSendSVGACmdUpdateFullScreen(pVMWARE);
+
+    /* Reset the visual list */
+    miClearVisualTypes();
+
+    /*
+     * Setup the visuals supported.  This driver only supports
+     * TrueColor for bpp > 8, so the default set of visuals isn't
+     * acceptable.  To deal with this, call miSetVisualTypes with
+     * the appropriate visual mask.
+     */
+    if (pScrn->bitsPerPixel > 8) {
+        if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
+                              pScrn->rgbBits, pScrn->defaultVisual)) {
+            return FALSE;
+        }
+    } else {
+        if (!miSetVisualTypes(pScrn->depth,
+                              miGetDefaultVisualMask(pScrn->depth),
+                              pScrn->rgbBits, pScrn->defaultVisual)) {
+            return FALSE;
+        }
+    }
+
+    miSetPixmapDepths();
+
+    /*
+     * Initialise the framebuffer.
+     */
+    if (!fbScreenInit(pScreen, pVMWARE->FbBase + pVMWARE->fbOffset,
+                      pScrn->virtualX, pScrn->virtualY,
+                      pScrn->xDpi, pScrn->yDpi,
+                      pScrn->displayWidth,
+                      pScrn->bitsPerPixel)) {
+        return FALSE;
+    }
+
+    /* Override the default mask/offset settings */
+    if (pScrn->bitsPerPixel > 8) {
+        int i;
+        VisualPtr visual;
+
+        for (i = 0, visual = pScreen->visuals;
+             i < pScreen->numVisuals; i++, visual++) {
+            if ((visual->class | DynamicClass) == DirectColor) {
+                visual->offsetRed = pScrn->offset.red;
+                visual->offsetGreen = pScrn->offset.green;
+                visual->offsetBlue = pScrn->offset.blue;
+                visual->redMask = pScrn->mask.red;
+                visual->greenMask = pScrn->mask.green;
+                visual->blueMask = pScrn->mask.blue;
+            }
+        }
+    }
+
+    /* must be after RGB ordering fixed */
+    fbPictureInit (pScreen, 0, 0);
+
+    /*
+     * Save the old screen vector.
+     */
+    pVMWARE->ScrnFuncs = *pScreen;
+
+    /*
+     * Set initial black & white colourmap indices.
+     */
+    xf86SetBlackWhitePixels(pScreen);
+
+    /*
+     * Initialize shadowfb to notify us of dirty rectangles.  We only
+     * need preFB access callbacks if we're using the hw cursor.
+     */
+    if (!ShadowFBInit2(pScreen, 
+                       pVMWARE->hwCursor ? VMWAREPreDirtyBBUpdate : NULL,
+                       VMWAREPostDirtyBBUpdate)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "ShadowFB initialization failed\n");
+        return FALSE;
+    }
+
+    /*
+     * If we have a hw cursor, we need to hook functions that might
+     * read from the framebuffer.
+     */
+    if (pVMWARE->hwCursor) {
+        vmwareCursorHookWrappers(pScreen);
+    }
+
+    /*
+     * If backing store is to be supported (as is usually the case),
+     * initialise it.
+     */
+    xf86SetBackingStore(pScreen);
+    xf86SetSilkenMouse(pScreen);
+
+    /*
+     * Initialize software cursor.
+     */
+    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+    /*
+     * Initialize hardware cursor.
+     */
+    if (pVMWARE->hwCursor) {
+        if (!vmwareCursorInit(pScreen)) {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                       "Hardware cursor initialization failed\n");
+            pVMWARE->hwCursor = FALSE;
+        }
+    }
+
+    /*
+     * Install colourmap functions.  If using the vgahw module,
+     * vgaHandleColormaps would usually be called here.
+     */
+    if (!fbCreateDefColormap(pScreen))
+        return FALSE;
+
+    if (!xf86HandleColormaps(pScreen, 256, 8,
+                             VMWARELoadPalette, NULL,
+                             CMAP_PALETTED_TRUECOLOR |
+                             CMAP_RELOAD_ON_MODE_SWITCH)) {
+        return FALSE;
+    }
+
+    /*
+     * We explictly add a set of default modes because the X server will
+     * not include modes larger than the initial one.
+     */
+   {
+      unsigned int i;
+      unsigned int numModes = sizeof (VMWAREDefaultModes) / sizeof *(VMWAREDefaultModes);
+      char name[10];
+      for (i = 0; i < numModes; i++) {
+         const VMWAREDefaultMode *mode = &VMWAREDefaultModes[i];
+
+         /* Only modes that fit the hardware maximums should be added. */
+         if (mode->width <= pVMWARE->maxWidth && mode->height <= pVMWARE->maxHeight) {
+            snprintf(name, 10, "%dx%d", mode->width, mode->height);
+            VMWAREAddDisplayMode(pScrn, name, mode->width, mode->height);
+         }
+      }
+
+      /* Add the hardware maximums as a mode. */
+      snprintf(name, 10, "%dx%d", pVMWARE->maxWidth, pVMWARE->maxHeight);
+      VMWAREAddDisplayMode(pScrn, name, pVMWARE->maxWidth, pVMWARE->maxHeight);
+   }
+
+    /*
+     * We will lazily add the dynamic modes as the are needed when new
+     * modes are requested through the control extension.
+     */
+    memset(&pVMWARE->dynModes, 0, sizeof pVMWARE->dynModes);
+
+#if VMWARE_DRIVER_FUNC
+    pScrn->DriverFunc = VMWareDriverFunc;
+#endif
+
+    /* Report any unused options (only for the first generation) */
+    if (serverGeneration == 1) {
+        xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
+    }
+
+    /* Initialize Xv extension */
+    pVMWARE->videoStreams = NULL;
+    if (vmwareVideoEnabled(pVMWARE)) {
+        if (!vmwareVideoInit(pScreen)) {
+            xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Xv initialization failed\n");
+        }
+    }
+
+    /**
+     * Wrap CloseScreen and SaveScreen. Do this late since we
+     * want to be first in the callchain, to avoid using resources
+     * already taken down in CloseScreen.
+     */
+
+    pVMWARE->ScrnFuncs.CloseScreen = pScreen->CloseScreen;
+    pVMWARE->ScrnFuncs.SaveScreen = pScreen->SaveScreen;
+
+    pScreen->CloseScreen = VMWARECloseScreen;
+    pScreen->SaveScreen = VMWARESaveScreen;
+
+    /* Done */
+    return TRUE;
+}
+
+static Bool
+VMWARESwitchMode(SWITCH_MODE_ARGS_DECL)
+{
+    SCRN_INFO_PTR(arg);
+    ScreenPtr pScreen = pScrn->pScreen;
+
+    pScreen->mmWidth = (pScreen->width * VMWARE_INCHTOMM +
+			pScrn->xDpi / 2) / pScrn->xDpi;
+    pScreen->mmHeight = (pScreen->height * VMWARE_INCHTOMM +
+			 pScrn->yDpi / 2) / pScrn->yDpi;
+
+    return VMWAREModeInit(pScrn, mode, TRUE);
+}
+
+static Bool
+VMWAREEnterVT(VT_FUNC_ARGS_DECL)
+{
+    SCRN_INFO_PTR(arg);
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+    /*
+     * After system resumes from hiberation, EnterVT will be called and this
+     * is a good place to restore the SVGA ID register.
+     */
+    vmwareWriteReg(pVMWARE, SVGA_REG_ID, pVMWARE->suspensionSavedRegId);
+
+    if (!pVMWARE->SavedReg.svga_fifo_enabled) {       
+        VMWAREInitFIFO(pScrn);
+    }
+
+    return VMWAREModeInit(pScrn, pScrn->currentMode, TRUE);
+}
+
+static void
+VMWARELeaveVT(VT_FUNC_ARGS_DECL)
+{
+    SCRN_INFO_PTR(arg);
+    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
+
+    /*
+     * Before shutting down system for hibneration, LeaveVT will be called,
+     * we save the ID register value here and later restore it in EnterVT.
+     */
+    pVMWARE->suspensionSavedRegId = vmwareReadReg(pVMWARE, SVGA_REG_ID);
+
+    VMWARERestore(pScrn);
+}
+
+static void
+VMWAREFreeScreen(FREE_SCREEN_ARGS_DECL)
+{
+    SCRN_INFO_PTR(arg);
+    /*
+     * If the vgahw module is used vgaHWFreeHWRec() would be called
+     * here.
+     */
+   VMWAREFreeRec(pScrn);
+}
+
+static ModeStatus
+VMWAREValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
+{
+    return MODE_OK;
+}
+
+void
+vmwlegacy_hookup(ScrnInfoPtr pScrn)
+{
+    pScrn->PreInit = VMWAREPreInit;
+    pScrn->ScreenInit = VMWAREScreenInit;
+    pScrn->SwitchMode = VMWARESwitchMode;
+    pScrn->EnterVT = VMWAREEnterVT;
+    pScrn->LeaveVT = VMWARELeaveVT;
+    pScrn->FreeScreen = VMWAREFreeScreen;
+    pScrn->ValidMode = VMWAREValidMode;
+}
+
+#ifdef XFree86LOADER
+void
+VMWARERefSymLists(void)
+{
+    LoaderRefSymLists(vgahwSymbols, fbSymbols, ramdacSymbols,
+		      shadowfbSymbols, NULL);
+}
+#endif	/* XFree86LOADER */
diff -Naur xf86-video-vmware-13.2.1.orig/src/vmware.h xf86-video-vmware-13.2.1/src/vmware.h
--- xf86-video-vmware-13.2.1.orig/src/vmware.h	2015-12-03 07:55:45.000000000 -0600
+++ xf86-video-vmware-13.2.1/src/vmware.h	2018-05-12 13:30:35.142466722 -0500
@@ -83,7 +83,7 @@
 
 typedef struct {
     EntityInfoPtr pEnt;
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
     struct pci_device *PciInfo;
 #else
     pciVideoPtr PciInfo;
@@ -207,7 +207,7 @@
 /* Undefine this to kill all acceleration */
 #define ACCELERATE_OPS
 
-#if XSERVER_LIBPCIACCESS
+#ifdef XSERVER_LIBPCIACCESS
 #define VENDOR_ID(p)      (p)->vendor_id
 #define DEVICE_ID(p)      (p)->device_id
 #define SUBVENDOR_ID(p)   (p)->subvendor_id
