Index: /trunk/src/VBox/Additions/x11/vboxvideo/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/Makefile.kmk	(revision 34714)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/Makefile.kmk	(revision 34715)
@@ -38,4 +38,5 @@
  	BUILDDEBUG X_BYTE_ORDER=X_LITTLE_ENDIAN DNDEBUG FUNCPROTO=15 NARROWPROTO \
  	IN_MODULE XFree86Module
+ vboxvideo_drv_DEFS += memset=xf86memset memcpy=xf86memcpy
  vboxvideo_drv_INCS = \
 	$(VBOX_PATH_X11_XFREE_4_3)/include \
@@ -68,7 +69,14 @@
 	$(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/randr \
 	$(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/Xext
+ vboxvideo_drv_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
  vboxvideo_drv_SOURCES = \
-	vboxvideo_70.c \
-	vboxutils.c
+	vboxvideo_13.c \
+	vboxutils.c \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
+	$(PATH_ROOT)/src/VBox/GuestHost/HGSMI/HGSMICommon.cpp \
+	$(PATH_ROOT)/src/VBox/Runtime/common/alloc/heapsimple.cpp \
+	$(PATH_ROOT)/src/VBox/Runtime/common/alloc/heapoffset.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
 endif   # target linux
 
@@ -97,4 +105,5 @@
 	$(VBOX_PATH_X11_XORG_7_0)/X11 \
 	$(VBOX_PATH_X11_XORG_7_0)/xorg
+vboxvideo_drv_70_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
 vboxvideo_drv_70_SOURCES  = $(vboxvideo_drv_SOURCES)
 
@@ -111,4 +120,5 @@
 	$(VBOX_PATH_X11_XORG_7_1)/X11 \
 	$(VBOX_PATH_X11_XORG_7_1)/xorg
+vboxvideo_drv_71_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
 vboxvideo_drv_71_SOURCES  = $(vboxvideo_drv_SOURCES)
 
@@ -129,7 +139,14 @@
 	$(VBOX_PATH_X11_ROOT)/libdrm-2.4.13 \
 	$(VBOX_PATH_X11_ROOT)/xf86driproto-2.1.0
+vboxvideo_drv_13_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
 vboxvideo_drv_13_SOURCES = \
 	vboxvideo_13.c \
-	vboxutils.c
+	vboxutils.c \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
+	$(PATH_ROOT)/src/VBox/GuestHost/HGSMI/HGSMICommon.cpp \
+	$(PATH_ROOT)/src/VBox/Runtime/common/alloc/heapsimple.cpp \
+	$(PATH_ROOT)/src/VBox/Runtime/common/alloc/heapoffset.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
 
 
@@ -152,4 +169,5 @@
 	$(VBOX_PATH_X11_ROOT)/libdrm-2.4.13 \
 	$(VBOX_PATH_X11_ROOT)/xf86driproto-2.1.0
+vboxvideo_drv_14_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
 vboxvideo_drv_14_SOURCES  = $(vboxvideo_drv_13_SOURCES)
 
@@ -174,4 +192,5 @@
 	$(VBOX_PATH_X11_ROOT)/xf86driproto-2.1.0 \
 	$(VBOX_PATH_X11_ROOT)/xorg-server-1.5.3
+vboxvideo_drv_15_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
 vboxvideo_drv_15_SOURCES  = $(vboxvideo_drv_13_SOURCES)
 if1of ($(KBUILD_TARGET), linux solaris)
@@ -197,4 +216,5 @@
 	$(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0 \
 	$(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local
+vboxvideo_drv_16_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
 vboxvideo_drv_16_SOURCES := $(vboxvideo_drv_15_SOURCES)
 
@@ -223,4 +243,5 @@
 	$(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local \
 	$(VBOX_PATH_X11_ROOT)/xproto-7.0.18
+vboxvideo_drv_17_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
 vboxvideo_drv_17_SOURCES := $(vboxvideo_drv_15_SOURCES)
 
@@ -249,4 +270,5 @@
 	$(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local \
 	$(VBOX_PATH_X11_ROOT)/xproto-7.0.18
+vboxvideo_drv_18_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
 vboxvideo_drv_18_SOURCES := $(vboxvideo_drv_15_SOURCES)
 
@@ -275,4 +297,5 @@
 	$(VBOX_PATH_X11_ROOT)/xorg-server-1.6.0-local \
 	$(VBOX_PATH_X11_ROOT)/xproto-7.0.18
+vboxvideo_drv_19_INCS += $(PATH_ROOT)/src/VBox/Runtime/include
 vboxvideo_drv_19_SOURCES := $(vboxvideo_drv_15_SOURCES)
 
Index: /trunk/src/VBox/Additions/x11/vboxvideo/vboxutils.c
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/vboxutils.c	(revision 34714)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/vboxutils.c	(revision 34715)
@@ -59,4 +59,18 @@
     while (0)
 
+/** Structure to pass cursor image data between realise_cursor() and
+ * load_cursor_image().  The members match the parameters to
+ * @a VBoxHGSMIUpdatePointerShape(). */
+struct vboxCursorImage
+{
+    uint32_t fFlags;
+    uint32_t cHotX;
+    uint32_t cHotY;
+    uint32_t cWidth;
+    uint32_t cHeight;
+    uint8_t *pPixels;
+    uint32_t cbLength;
+};
+
 #ifdef DEBUG_POINTER
 static void
@@ -69,5 +83,5 @@
     size_t sizeMask;
 
-    image    += offsetof(VMMDevReqMousePointer, pointerData);
+    image    += sizeof(struct vboxCursorImage);
     mask      = image;
     pitch     = (w + 7) / 8;
@@ -150,18 +164,4 @@
 }
 
-/**
- * Macro to disable VBVA extensions and return, for use when an
- * unexplained error occurs.
- */
-#define DISABLE_VBVA_AND_RETURN(pScrn, ...) \
-    do \
-    { \
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, __VA_ARGS__); \
-        vboxDisableVbva(pScrn); \
-        pVBox->useVbva = FALSE; \
-        return; \
-    } \
-    while (0)
-
 /**************************************************************************
 * Main functions                                                          *
@@ -193,109 +193,56 @@
     VBVACMDHDR cmdHdr;
     VBOXPtr pVBox;
-    VBVARECORD *pRecord;
-    VBVAMEMORY *pMem;
-    CARD32 indexRecordNext;
-    CARD32 off32Data;
-    CARD32 off32Free;
-    INT32 i32Diff;
-    CARD32 cbHwBufferAvail;
-    int scrnIndex;
     int i;
+    unsigned j;
 
     pVBox = pScrn->driverPrivate;
-    if (pVBox->useVbva == FALSE)
+    if (pVBox->fHaveHGSMI == FALSE)
         return;
-    pMem = pVBox->pVbvaMemory;
-    /* Just return quietly if VBVA is not currently active. */
-    if ((pMem->fu32ModeFlags & VBVA_F_MODE_ENABLED) == 0)
-        return;
-    scrnIndex = pScrn->scrnIndex;
-
-    for (i = 0; i < iRects; i++)
-    {
-        cmdHdr.x = (int16_t)aRects[i].x1 - pVBox->viewportX;
-        cmdHdr.y = (int16_t)aRects[i].y1 - pVBox->viewportY;
-        cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
-        cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
-
-        /* Get the active record and move the pointer along */
-        indexRecordNext = (pMem->indexRecordFree + 1) % VBVA_MAX_RECORDS;
-        if (indexRecordNext == pMem->indexRecordFirst)
+
+    for (i = 0; i < iRects; ++i)
+        for (j = 0; j < pVBox->cScreens; ++j)
         {
-            /* All slots in the records queue are used. */
-            if (VbglR3VideoAccelFlush() < 0)
-                DISABLE_VBVA_AND_RETURN(pScrn,
-                    "Unable to clear the VirtualBox graphics acceleration queue "
-                    "- the request to the virtual machine failed.  Switching to "
-                    "unaccelerated mode.\n");
+            /* Just continue quietly if VBVA is not currently active. */
+            struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA;
+            if (   !pVBVA
+                || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
+                continue;
+            if (   aRects[i].x1 >   pVBox->aScreenLocation[j].x
+                                  + pVBox->aScreenLocation[j].cx
+                || aRects[i].y1 >   pVBox->aScreenLocation[j].y
+                                  + pVBox->aScreenLocation[j].cy
+                || aRects[i].x2 <   pVBox->aScreenLocation[j].x
+                || aRects[i].y2 <   pVBox->aScreenLocation[j].y)
+                continue;
+            cmdHdr.x = (int16_t)aRects[i].x1 - pVBox->aScreenLocation[j].x;
+            cmdHdr.y = (int16_t)aRects[i].y1 - pVBox->aScreenLocation[j].y;
+            cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
+            cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
+
+            TRACE_LOG("x=%d, y=%d, w=%d, z=%d\n", cmdHdr.x, cmdHdr.y,
+                      cmdHdr.w, cmdHdr.h);
+            
+            VBoxVBVABufferBeginUpdate(&pVBox->aVbvaCtx[j], &pVBox->guestCtx);
+            VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr,
+                          sizeof(cmdHdr));
+            VBoxVBVABufferEndUpdate(&pVBox->aVbvaCtx[j]);
         }
-        if (indexRecordNext == pMem->indexRecordFirst)
-            DISABLE_VBVA_AND_RETURN(pScrn,
-                "Failed to clear the VirtualBox graphics acceleration queue.  "
-                "Switching to unaccelerated mode.\n");
-        pRecord = &pMem->aRecords[pMem->indexRecordFree];
-        /* Mark the record as being updated. */
-        pRecord->cbRecord = VBVA_F_RECORD_PARTIAL;
-        pMem->indexRecordFree = indexRecordNext;
-        /* Compute how many bytes we have in the ring buffer. */
-        off32Free = pMem->off32Free;
-        off32Data = pMem->off32Data;
-        /* Free is writing position. Data is reading position.
-         * Data == Free means buffer is free.
-         * There must be always gap between free and data when data
-         * are in the buffer.
-         * Guest only changes free, host only changes data.
-         */
-        i32Diff = off32Data - off32Free;
-        cbHwBufferAvail = i32Diff > 0 ? i32Diff : VBVA_RING_BUFFER_SIZE + i32Diff;
-        if (cbHwBufferAvail <= VBVA_RING_BUFFER_THRESHOLD)
-        {
-            if (VbglR3VideoAccelFlush() < 0)
-                DISABLE_VBVA_AND_RETURN(pScrn,
-                    "Unable to clear the VirtualBox graphics acceleration queue "
-                    "- the request to the virtual machine failed.  Switching to "
-                    "unaccelerated mode.\n");
-            /* Calculate the free space again. */
-            off32Free = pMem->off32Free;
-            off32Data = pMem->off32Data;
-            i32Diff = off32Data - off32Free;
-            cbHwBufferAvail = i32Diff > 0? i32Diff:
-                                  VBVA_RING_BUFFER_SIZE + i32Diff;
-            if (cbHwBufferAvail <= VBVA_RING_BUFFER_THRESHOLD)
-                DISABLE_VBVA_AND_RETURN(pScrn,
-                    "No space left in the VirtualBox graphics acceleration command buffer, "
-                    "despite clearing the queue.  Switching to unaccelerated mode.\n");
-        }
-        /* Now copy the data into the buffer */
-        if (off32Free + sizeof(cmdHdr) < VBVA_RING_BUFFER_SIZE)
-        {
-            memcpy(&pMem->au8RingBuffer[off32Free], &cmdHdr, sizeof(cmdHdr));
-            pMem->off32Free = pMem->off32Free + sizeof(cmdHdr);
-        }
-        else
-        {
-            CARD32 u32First = VBVA_RING_BUFFER_SIZE - off32Free;
-            /* The following is impressively ugly! */
-            CARD8 *pu8Second = (CARD8 *)&cmdHdr + u32First;
-            CARD32 u32Second = sizeof(cmdHdr) - u32First;
-            memcpy(&pMem->au8RingBuffer[off32Free], &cmdHdr, u32First);
-            if (u32Second)
-                memcpy(&pMem->au8RingBuffer[0], pu8Second, u32Second);
-            pMem->off32Free = u32Second;
-        }
-        pRecord->cbRecord += sizeof(cmdHdr);
-        /* Mark the record completed. */
-        pRecord->cbRecord &= ~VBVA_F_RECORD_PARTIAL;
-    }
-}
-
-#ifdef PCIACCESS
-/* As of X.org server 1.5, we are using the pciaccess library functions to
- * access PCI.  This structure describes our VMM device. */
-/** Structure describing the VMM device */
-static const struct pci_id_match vboxVMMDevID =
-{ VMMDEV_VENDORID, VMMDEV_DEVICEID, PCI_MATCH_ANY, PCI_MATCH_ANY,
-  0, 0, 0 };
-#endif
+}
+
+/** Callback to fill in the view structures */
+static int
+vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
+{
+    VBOXPtr pVBox = (VBOXPtr)pvVBox;
+    unsigned i;
+    for (i = 0; i < cViews; ++i)
+    {
+        pViews[i].u32ViewIndex = i;
+        pViews[i].u32ViewOffset = 0;
+        pViews[i].u32ViewSize = pVBox->cbFramebuffer;
+        pViews[i].u32MaxScreenSize = pVBox->cbFramebuffer;
+    }
+    return VINF_SUCCESS;
+}
 
 /**
@@ -307,71 +254,45 @@
 vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
 {
-#ifdef PCIACCESS
-    struct pci_device_iterator *devIter = NULL;
-
-    TRACE_ENTRY();
-    pVBox->vmmDevInfo = NULL;
-    devIter = pci_id_match_iterator_create(&vboxVMMDevID);
-    if (devIter)
-    {
-        pVBox->vmmDevInfo = pci_device_next(devIter);
-        pci_iterator_destroy(devIter);
-    }
-    if (pVBox->vmmDevInfo)
-    {
-        if (pci_device_probe(pVBox->vmmDevInfo) != 0)
-        {
-            xf86DrvMsg (scrnIndex, X_ERROR,
-                        "Failed to probe VMM device (vendor=%04x, devid=%04x)\n",
-                        pVBox->vmmDevInfo->vendor_id,
-                        pVBox->vmmDevInfo->device_id);
-        }
-        else
-        {
-            if (pci_device_map_range(pVBox->vmmDevInfo,
-                                     pVBox->vmmDevInfo->regions[1].base_addr,
-                                     pVBox->vmmDevInfo->regions[1].size,
-                                     PCI_DEV_MAP_FLAG_WRITABLE,
-                                     (void **)&pVBox->pVMMDevMemory) != 0)
-                xf86DrvMsg (scrnIndex, X_ERROR,
-                            "Failed to map VMM device range\n");
-        }
-    }
-#else
-    PCITAG pciTagDev;
-    ADDRESS pciAddrDev;
-
-    TRACE_ENTRY();
-    /* Locate the device.  It should already have been enabled by
-       the kernel driver. */
-    pciTagDev = pciFindFirst((unsigned) VMMDEV_DEVICEID << 16 | VMMDEV_VENDORID,
-                             (CARD32) ~0);
-    if (pciTagDev == PCI_NOT_FOUND)
-    {
-        xf86DrvMsg(scrnIndex, X_ERROR,
-                   "Could not find the VirtualBox base device on the PCI bus.\n");
+    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+    int rc = VINF_SUCCESS;
+    unsigned i;
+    uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory,
+             cScreens;
+    void *pvGuestHeapMemory;
+
+    pVBox->cScreens = 1;
+    if (!VBoxHGSMIIsSupported())
+    {
+        xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI.  Disableing video acceleration.\n");
         return FALSE;
     }
-    /* Read the address and size of the second I/O region. */
-    pciAddrDev = pciReadLong(pciTagDev, PCI_MAP_REG_START + 4);
-    if (pciAddrDev == 0 || pciAddrDev == (CARD32) ~0)
-        RETERROR(scrnIndex, FALSE,
-                 "The VirtualBox base device contains an invalid memory address.\n");
-    if (PCI_MAP_IS64BITMEM(pciAddrDev))
-        RETERROR(scrnIndex, FALSE,
-                 "The VirtualBox base device has a 64bit mapping address.  "
-                 "This is currently not supported.\n");
-    /* Map it.  We hardcode the size as X does not export the
-       function needed to determine it. */
-    pVBox->pVMMDevMemory = xf86MapPciMem(scrnIndex, 0, pciTagDev, pciAddrDev,
-                                         sizeof(VMMDevMemory));
-#endif
-    if (pVBox->pVMMDevMemory == NULL)
-    {
-        xf86DrvMsg(scrnIndex, X_ERROR,
-                   "Failed to map VirtualBox video extension memory.\n");
+    VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,
+                                NULL, &offGuestHeapMemory, &cbGuestHeapMemory,
+                                NULL);
+    pvGuestHeapMemory =   ((uint8_t *)pVBox->base) + offVRAMBaseMapping
+                        + offGuestHeapMemory;
+    rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory,
+                                    cbGuestHeapMemory,
+                                    offVRAMBaseMapping + offGuestHeapMemory);
+    if (RT_FAILURE(rc))
+    {
+        xf86DrvMsg(scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc);
         return FALSE;
     }
-    pVBox->pVbvaMemory = &pVBox->pVMMDevMemory->vbvaMemory;
+    pVBox->cbFramebuffer = offVRAMBaseMapping;
+    pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
+    xf86DrvMsg(scrnIndex, X_INFO, "Requested monitor count: %u\n",
+               pVBox->cScreens);
+    rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
+                               vboxFillViewInfo, (void *)pVBox);
+    for (i = 0; i < pVBox->cScreens; ++i)
+    {
+        pVBox->cbFramebuffer -= VBVA_MIN_BUFFER_SIZE;
+        pVBox->aoffVBVABuffer[i] = pVBox->cbFramebuffer;
+        VBoxVBVASetupBufferContext(&pVBox->aVbvaCtx[i],
+                                   pVBox->aoffVBVABuffer[i], 
+                                   VBVA_MIN_BUFFER_SIZE);
+    }
+
     /* Set up the dirty rectangle handler.  Since this seems to be a
        delicate operation, and removing it doubly so, this will
@@ -396,5 +317,4 @@
 
     TRACE_ENTRY();
-    pVBox->useVbva = FALSE;
     vrc = VbglR3Init();
     if (RT_FAILURE(vrc))
@@ -423,5 +343,5 @@
     if (!pVBox->useDevice)
         return FALSE;
-    pVBox->useVbva = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
+    pVBox->fHaveHGSMI = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
     return TRUE;
 }
@@ -438,5 +358,5 @@
     int rc;
 
-    rc = VbglR3SetPointerShape(0, 0, 0, 0, 0, NULL, 0);
+    rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, 0, 0, 0, 0, 0, NULL, 0);
     if (RT_FAILURE(rc))
     {
@@ -456,5 +376,6 @@
     if (!vbox_host_uses_hwcursor(pScrn))
         return;
-    rc = VbglR3SetPointerShape(VBOX_MOUSE_POINTER_VISIBLE, 0, 0, 0, 0, NULL, 0);
+    rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, VBOX_MOUSE_POINTER_VISIBLE,
+                                     0, 0, 0, 0, NULL, 0);
     if (RT_FAILURE(rc)) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not unhide the virtual mouse pointer.\n");
@@ -468,15 +389,17 @@
 static void
 vbox_vmm_load_cursor_image(ScrnInfoPtr pScrn, VBOXPtr pVBox,
-                           unsigned char *image)
+                           unsigned char *pvImage)
 {
     int rc;
-    VMMDevReqMousePointer *reqp;
-    reqp = (VMMDevReqMousePointer *)image;
+    struct vboxCursorImage *pImage;
+    pImage = (struct vboxCursorImage *)pvImage;
 
 #ifdef DEBUG_POINTER
-    vbox_show_shape(reqp->width, reqp->height, 0, image);
+    vbox_show_shape(pImage->cWidth, pImage->cHeight, 0, pvImage);
 #endif
 
-    rc = VbglR3SetPointerShapeReq(reqp);
+    rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, pImage->fFlags,
+             pImage->cHotX, pImage->cHotY, pImage->cWidth, pImage->cHeight,
+             pImage->pPixels, pImage->cbLength);
     if (RT_FAILURE(rc)) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,  "Unable to set the virtual mouse pointer image.\n");
@@ -555,5 +478,5 @@
     CARD32 fc, bc, *cp;
     int rc, scrnIndex = infoPtr->pScrn->scrnIndex;
-    VMMDevReqMousePointer *reqp;
+    struct vboxCursorImage *pImage;
 
     pVBox = infoPtr->pScrn->driverPrivate;
@@ -575,5 +498,5 @@
     sizeMask = ((dstPitch * h) + 3) & (size_t) ~3;
     sizeRgba = w * h * 4;
-    sizeRequest = sizeMask + sizeRgba + sizeof(VMMDevReqMousePointer);
+    sizeRequest = sizeMask + sizeRgba + sizeof(*pImage);
 
     p = c = calloc (1, sizeRequest);
@@ -583,13 +506,6 @@
                  (unsigned long) sizeRequest);
 
-    rc = vmmdevInitRequest((VMMDevRequestHeader *)p, VMMDevReq_SetPointerShape);
-    if (RT_FAILURE(rc))
-    {
-        xf86DrvMsg(scrnIndex, X_ERROR, "Could not init VMM request: rc = %d\n", rc);
-        free(p);
-        return NULL;
-    }
-
-    m = p + offsetof(VMMDevReqMousePointer, pointerData);
+    pImage = (struct vboxCursorImage *)p;
+    pImage->pPixels = m = p + sizeof(*pImage);
     cp = (CARD32 *)(m + sizeMask);
 
@@ -656,11 +572,10 @@
     }
 
-    reqp = (VMMDevReqMousePointer *)p;
-    reqp->width  = w;
-    reqp->height = h;
-    reqp->xHot   = bitsp->xhot;
-    reqp->yHot   = bitsp->yhot;
-    reqp->fFlags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE;
-    reqp->header.size = sizeRequest;
+    pImage->cWidth   = w;
+    pImage->cHeight  = h;
+    pImage->cHotX    = bitsp->xhot;
+    pImage->cHotY    = bitsp->yhot;
+    pImage->fFlags   = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE;
+    pImage->cbLength = sizeRequest - sizeof(*pImage);
 
 #ifdef DEBUG_POINTER
@@ -775,5 +690,6 @@
     }
 
-    rc = VbglR3SetPointerShape(fFlags, bitsp->xhot, bitsp->yhot, w, h, p, sizeData);
+    rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, fFlags, bitsp->xhot,
+                                     bitsp->yhot, w, h, p, sizeData);
     TRACE_LOG(": leaving, returning %d\n", rc);
     free(p);
@@ -790,5 +706,5 @@
 
     TRACE_ENTRY();
-    if (!pVBox->useDevice)
+    if (!pVBox->fHaveHGSMI)
         return FALSE;
     pVBox->pCurs = pCurs = xf86CreateCursorInfoRec();
@@ -844,18 +760,26 @@
     bool rc = TRUE;
     int scrnIndex = pScrn->scrnIndex;
-    VBOXPtr pVBox = pScrn->driverPrivate;
-
-    TRACE_ENTRY();
-    if (pVBox->useVbva != TRUE)
-        rc = FALSE;
-    if (rc && RT_FAILURE(VbglR3VideoAccelEnable(true)))
+    unsigned i;
+    VBOXPtr pVBox = pScrn->driverPrivate;
+
+    TRACE_ENTRY();
+    if (!pVBox->fHaveHGSMI)
+        return FALSE;
+    for (i = 0; i < pVBox->cScreens; ++i)
+    {
+        struct VBVABUFFER *pVBVA;
+
+        pVBVA = (struct VBVABUFFER *) (  ((uint8_t *)pVBox->base)
+                                       + pVBox->aoffVBVABuffer[i]);
+        if (!VBoxVBVAEnable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, pVBVA, i))
+            rc = FALSE;
+    }
+    if (!rc)
+    {
         /* Request not accepted - disable for old hosts. */
         xf86DrvMsg(scrnIndex, X_ERROR,
-                   "Unable to activate VirtualBox graphics acceleration "
-                   "- the request to the virtual machine failed.  "
-                   "You may be running an old version of VirtualBox.\n");
-    pVBox->useVbva = rc;
-    if (!rc)
-        VbglR3VideoAccelEnable(false);
+                   "Failed to enable screen update reporting for at least one virtual monitor.\n");
+         vboxDisableVbva(pScrn);
+    }
     return rc;
 }
@@ -869,24 +793,17 @@
  * @param   pScrn   Pointer to a structure describing the X screen in use
  */
-Bool
+void
 vboxDisableVbva(ScrnInfoPtr pScrn)
 {
     int rc;
     int scrnIndex = pScrn->scrnIndex;
-    VBOXPtr pVBox = pScrn->driverPrivate;
-
-    TRACE_ENTRY();
-    if (pVBox->useVbva != TRUE)  /* Ths function should not have been called */
-        return FALSE;
-    rc = VbglR3VideoAccelEnable(false);
-    if (RT_FAILURE(rc))
-    {
-        xf86DrvMsg(scrnIndex, X_ERROR,
-                   "Unable to disable VirtualBox graphics acceleration "
-                   "- the request to the virtual machine failed.\n");
-    }
-    else
-        memset(pVBox->pVbvaMemory, 0, sizeof(VBVAMEMORY));
-    return TRUE;
+    unsigned i;
+    VBOXPtr pVBox = pScrn->driverPrivate;
+
+    TRACE_ENTRY();
+    if (!pVBox->fHaveHGSMI)  /* Ths function should not have been called */
+        return;
+    for (i = 0; i < pVBox->cScreens; ++i)
+        VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i);
 }
 
Index: /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h	(revision 34714)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h	(revision 34715)
@@ -52,4 +52,7 @@
 #ifndef _VBOXVIDEO_H_
 #define _VBOXVIDEO_H_
+
+#include <VBox/VBoxVideoGuest.h>
+#include <VBox/VBoxVideo.h>
 
 #ifdef DEBUG
@@ -168,5 +171,5 @@
 /*XXX*/
 
-typedef struct _VBOXRec
+typedef struct VBOXRec
 {
     vbeInfoPtr pVbe;  /** @todo do the VBE bits ourselves? */
@@ -179,6 +182,7 @@
     PCITAG pciTag;
 #endif
-    unsigned long mapSize;	/* video memory */
     void *base;
+    /** The amount of VRAM available for use as a framebuffer */
+    unsigned long cbFramebuffer;
     CARD8 *state, *pstate;	/* SVGA state */
     int statePage, stateSize, stateMode;
@@ -201,8 +205,17 @@
      * safe to touch the hardware. */
     Bool vtSwitch;
-    Bool useVbva;
-    int viewportX, viewportY;
-    VMMDevMemory *pVMMDevMemory;
-    VBVAMEMORY *pVbvaMemory;
+    /** Does this host support sending graphics commands using HGSMI? */
+    Bool fHaveHGSMI;
+    /** Number of screens attached */
+    uint32_t cScreens;
+    /** Position information for each virtual screen for the purposes of
+     * sending dirty rectangle information to the right one. */
+    RTRECT2 aScreenLocation[VBOX_VIDEO_MAX_SCREENS];
+    /** Offsets of VBVA buffers in video RAM */
+    uint32_t aoffVBVABuffer[VBOX_VIDEO_MAX_SCREENS];
+    /** Context information about the VBVA buffers for each screen */
+    struct VBVABUFFERCONTEXT aVbvaCtx[VBOX_VIDEO_MAX_SCREENS];
+    /** HGSMI guest heap context */
+    HGSMIGUESTCOMMANDCONTEXT guestCtx;
     Bool fAnyX;   /* Unrestricted horizontal resolution flag. */
 #ifdef VBOX_DRI
@@ -222,5 +235,5 @@
 
 extern Bool vboxEnableVbva(ScrnInfoPtr pScrn);
-extern Bool vboxDisableVbva(ScrnInfoPtr pScrn);
+extern void vboxDisableVbva(ScrnInfoPtr pScrn);
 
 extern Bool vboxEnableGraphicsCap(VBOXPtr pVBox);
@@ -246,4 +259,8 @@
 extern void VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox);
 
+/* Xinerama stuff */
+#define VBOXRAMA_MAJOR_VERSION 1
+#define VBOXRAMA_MINOR_VERSION 0
+
 #endif /* _VBOXVIDEO_H_ */
 
Index: /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_13.c
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_13.c	(revision 34714)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_13.c	(revision 34715)
@@ -1,4 +1,5 @@
 /* $Id$ */
 /** @file
+ *
  * Linux Additions X11 graphics driver
  */
@@ -48,5 +49,8 @@
  */
 
-#include "xorg-server.h"
+#ifdef XORG_7X
+# include "xorg-server.h"
+# include <string.h>
+#endif
 #include "vboxvideo.h"
 #include "version-generated.h"
@@ -71,8 +75,10 @@
 #include "vgaHW.h"
 
+#ifdef VBOXVIDEO_13
 /* X.org 1.3+ mode setting */
-#define _HAVE_STRING_ARCH_strsep /* bits/string2.h, __strsep_1c. */
-#include "xf86Crtc.h"
-#include "xf86Modes.h"
+# define _HAVE_STRING_ARCH_strsep /* bits/string2.h, __strsep_1c. */
+# include "xf86Crtc.h"
+# include "xf86Modes.h"
+#endif
 
 /* Mandatory functions */
@@ -92,10 +98,13 @@
 static void VBOXLeaveVT(int scrnIndex, int flags);
 static Bool VBOXCloseScreen(int scrnIndex, ScreenPtr pScreen);
+static Bool VBOXSaveScreen(ScreenPtr pScreen, int mode);
 static Bool VBOXSwitchMode(int scrnIndex, DisplayModePtr pMode, int flags);
-static ModeStatus VBOXValidMode(int scrn, DisplayModePtr p, Bool flag, int pass);
-static Bool VBOXSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
+static Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
+                        unsigned cHeight, int x, int y);
 static void VBOXAdjustFrame(int scrnIndex, int x, int y, int flags);
 static void VBOXFreeScreen(int scrnIndex, int flags);
 static void VBOXFreeRec(ScrnInfoPtr pScrn);
+static void VBOXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode,
+                                          int flags);
 
 /* locally used functions */
@@ -104,4 +113,5 @@
 static Bool VBOXSaveRestore(ScrnInfoPtr pScrn,
                             vbeSaveRestoreFunction function);
+static Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height);
 
 enum GenericTypes
@@ -141,5 +151,8 @@
  */
 
-_X_EXPORT DriverRec VBOXVIDEO = {
+#ifdef XORG_7X
+_X_EXPORT
+#endif
+DriverRec VBOXVIDEO = {
     VBOX_VERSION,
     VBOX_DRIVER_NAME,
@@ -153,6 +166,7 @@
     NULL,
     0,
+#ifdef XORG_7X
     NULL,
-
+#endif
 #ifdef PCIACCESS
     vbox_device_match,
@@ -166,8 +180,71 @@
 };
 
+#ifndef XORG_7X
+/*
+ * List of symbols from other modules that this module references.  This
+ * list is used to tell the loader that it is OK for symbols here to be
+ * unresolved providing that it hasn't been told that they haven't been
+ * told that they are essential via a call to xf86LoaderReqSymbols() or
+ * xf86LoaderReqSymLists().  The purpose is this is to avoid warnings about
+ * unresolved symbols that are not required.
+ */
+static const char *fbSymbols[] = {
+    "fbPictureInit",
+    "fbScreenInit",
+    NULL
+};
+
+static const char *shadowfbSymbols[] = {
+  "ShadowFBInit2",
+  NULL
+};
+
+static const char *vbeSymbols[] = {
+    "VBEExtendedInit",
+    "VBEFindSupportedDepths",
+    "VBEGetModeInfo",
+    "VBEGetVBEInfo",
+    "VBEGetVBEMode",
+    "VBEPrintModes",
+    "VBESaveRestore",
+    "VBESetDisplayStart",
+    "VBESetGetDACPaletteFormat",
+    "VBESetGetLogicalScanlineLength",
+    "VBESetGetPaletteData",
+    "VBESetModeNames",
+    "VBESetModeParameters",
+    "VBESetVBEMode",
+    "VBEValidateModes",
+    "vbeDoEDID",
+    "vbeFree",
+    NULL
+};
+
+static const char *ramdacSymbols[] = {
+    "xf86InitCursor",
+    "xf86CreateCursorInfoRec",
+    NULL
+};
+
+static const char *vgahwSymbols[] = {
+    "vgaHWGetHWRec",
+    "vgaHWHandleColormaps",
+    "vgaHWFreeHWRec",
+    "vgaHWMapMem",
+    "vgaHWUnmapMem",
+    "vgaHWSaveFonts",
+    "vgaHWRestoreFonts",
+    "vgaHWGetIndex",
+    "vgaHWSaveScreen",
+    "vgaHWDPMSSet",
+    NULL
+};
+#endif /* !XORG_7X */
+
 static VBOXPtr
 VBOXGetRec(ScrnInfoPtr pScrn)
 {
-    if (!pScrn->driverPrivate) {
+    if (!pScrn->driverPrivate)
+    {
         pScrn->driverPrivate = calloc(sizeof(VBOXRec), 1);
     }
@@ -186,4 +263,5 @@
 }
 
+#ifdef VBOXVIDEO_13
 /* X.org 1.3+ mode-setting support ******************************************/
 
@@ -192,57 +270,6 @@
    X.Org source tree. */
 
-static Bool
-VBOXCrtcResize(ScrnInfoPtr scrn, int width, int height)
-{
-    int bpp = scrn->bitsPerPixel;
-    ScreenPtr pScreen = scrn->pScreen;
-    PixmapPtr pPixmap = NULL;
-    VBOXPtr pVBox = VBOXGetRec(scrn);
-    Bool rc = TRUE;
-
-    TRACE_LOG("width=%d, height=%d\n", width, height);
-    if (width * height * bpp / 8 >= scrn->videoRam * 1024)
-    {
-        xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-                   "Unable to set up a virtual screen size of %dx%d with %d Kb of video memory.  Please increase the video memory size.\n",
-                   width, height, scrn->videoRam);
-        rc = FALSE;
-    }
-    if (rc) {
-        pPixmap = pScreen->GetScreenPixmap(pScreen);
-        if (NULL == pPixmap) {
-            xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-                       "Failed to get the screen pixmap.\n");
-            rc = FALSE;
-        }
-    }
-    if (rc) {
-        if (
-            !pScreen->ModifyPixmapHeader(pPixmap, width, height,
-                                         scrn->depth, bpp, width * bpp / 8,
-                                         pVBox->base)
-           ) {
-            xf86DrvMsg(scrn->scrnIndex, X_ERROR,
-                       "Failed to set up the screen pixmap.\n");
-            rc = FALSE;
-        }
-    }
-    if (rc) {
-        scrn->virtualX = width;
-        scrn->virtualY = height;
-        scrn->displayWidth = width;
-#ifdef VBOX_DRI
-        if (pVBox->useDRI)
-            VBOXDRIUpdateStride(scrn, pVBox);
-#endif
-        /* Write the new values to the hardware */
-        rc = xf86SetDesiredModes(scrn);
-    }
-    TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
-    return rc;
-}
-
 static const xf86CrtcConfigFuncsRec VBOXCrtcConfigFuncs = {
-    VBOXCrtcResize
+    VBOXAdjustScreenPixmap
 };
 
@@ -269,8 +296,11 @@
 {
     (void) mode;
+    VBOXPtr pVBox = VBOXGetRec(crtc->scrn);
+    int bpp = crtc->scrn->depth == 24 ? 32 : 16;
+
     TRACE_LOG("name=%s, HDisplay=%d, VDisplay=%d, x=%d, y=%d\n", adjusted_mode->name,
            adjusted_mode->HDisplay, adjusted_mode->VDisplay, x, y);
-    VBOXSetMode(crtc->scrn, adjusted_mode);
-    VBOXAdjustFrame(crtc->scrn->scrnIndex, x, y, 0);
+    VBOXSetMode(crtc->scrn, 0, adjusted_mode->HDisplay, adjusted_mode->VDisplay,
+                x, y);
     /* Don't remember any modes set while we are seamless, as they are
      * just temporary. */
@@ -454,4 +484,5 @@
     .destroy = vbox_output_stub
 };
+#endif /* VBOXVIDEO_13 */
 
 #ifdef XFree86LOADER
@@ -465,5 +496,9 @@
     MODINFOSTRING1,
     MODINFOSTRING2,
+#ifdef XORG_7X
     XORG_VERSION_CURRENT,
+#else
+    XF86_VERSION_CURRENT,
+#endif
     1,                          /* Module major version. Xorg-specific */
     0,                          /* Module minor version. Xorg-specific */
@@ -479,5 +514,8 @@
  * followed by "ModuleData".
  */
-_X_EXPORT XF86ModuleData vboxvideoModuleData = { &vboxVersionRec, vboxSetup, NULL };
+#ifdef XORG_7X
+_X_EXPORT
+#endif
+XF86ModuleData vboxvideoModuleData = { &vboxVersionRec, vboxSetup, NULL };
 
 static pointer
@@ -494,4 +532,12 @@
         xf86AddDriver(&VBOXVIDEO, Module, 0);
 #endif
+#ifndef XORG_7X
+        LoaderRefSymLists(fbSymbols,
+                          shadowfbSymbols,
+                          vbeSymbols,
+                          ramdacSymbols,
+                          vgahwSymbols,
+                          NULL);
+#endif
         xf86Msg(X_CONFIG, "Load address of symbol \"VBOXVIDEO\" is %p\n",
                 (void *)&VBOXVIDEO);
@@ -543,5 +589,4 @@
         pScrn->ScreenInit    = VBOXScreenInit;
         pScrn->SwitchMode    = VBOXSwitchMode;
-        pScrn->ValidMode     = VBOXValidMode;
         pScrn->AdjustFrame   = VBOXAdjustFrame;
         pScrn->EnterVT       = VBOXEnterVT;
@@ -599,5 +644,4 @@
 			pScrn->ScreenInit    = VBOXScreenInit;
 			pScrn->SwitchMode    = VBOXSwitchMode;
-			pScrn->ValidMode     = VBOXValidMode;
 			pScrn->AdjustFrame   = VBOXAdjustFrame;
 			pScrn->EnterVT       = VBOXEnterVT;
@@ -618,201 +662,4 @@
 #endif
 
-/*
- * QUOTE from the XFree86 DESIGN document:
- *
- * The purpose of this function is to find out all the information
- * required to determine if the configuration is usable, and to initialise
- * those parts of the ScrnInfoRec that can be set once at the beginning of
- * the first server generation.
- *
- * (...)
- *
- * This includes probing for video memory, clocks, ramdac, and all other
- * HW info that is needed. It includes determining the depth/bpp/visual
- * and related info. It includes validating and determining the set of
- * video modes that will be used (and anything that is required to
- * determine that).
- *
- * This information should be determined in the least intrusive way
- * possible. The state of the HW must remain unchanged by this function.
- * Although video memory (including MMIO) may be mapped within this
- * function, it must be unmapped before returning.
- *
- * END QUOTE
- */
-
-static Bool
-VBOXPreInit(ScrnInfoPtr pScrn, int flags)
-{
-    VBOXPtr pVBox;
-    Gamma gzeros = {0.0, 0.0, 0.0};
-    rgb rzeros = {0, 0, 0};
-    xf86OutputPtr output;
-    unsigned DispiId;
-
-    /* Are we really starting the server, or is this just a dummy run? */
-    if (flags & PROBE_DETECT)
-        return (FALSE);
-
-    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-               "VirtualBox guest additions video driver version "
-               VBOX_VERSION_STRING "\n");
-
-    /* Get our private data from the ScrnInfoRec structure. */
-    pVBox = VBOXGetRec(pScrn);
-
-    /* Initialise the guest library */
-    vbox_init(pScrn->scrnIndex, pVBox);
-
-    /* Entity information seems to mean bus information. */
-    pVBox->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
-
-    /* We need the vbe module because we use VBE code to save and restore
-       text mode, in order to keep our code simple. */
-    if (!xf86LoadSubModule(pScrn, "vbe"))
-        return (FALSE);
-
-    if ((pVBox->pVbe = VBEExtendedInit(NULL, pVBox->pEnt->index,
-                                       SET_BIOS_SCRATCH
-                                       | RESTORE_BIOS_SCRATCH)) == NULL)
-        return (FALSE);
-
-#ifndef PCIACCESS
-    if (pVBox->pEnt->location.type != BUS_PCI)
-        return FALSE;
-
-    pVBox->pciInfo = xf86GetPciInfoForEntity(pVBox->pEnt->index);
-    pVBox->pciTag = pciTag(pVBox->pciInfo->bus,
-                           pVBox->pciInfo->device,
-                           pVBox->pciInfo->func);
-#endif
-
-    /* The ramdac module is needed for the hardware cursor. */
-    if (!xf86LoadSubModule(pScrn, "ramdac"))
-        return FALSE;
-
-    /* The framebuffer module. */
-    if (xf86LoadSubModule(pScrn, "fb") == NULL)
-        return (FALSE);
-
-    if (!xf86LoadSubModule(pScrn, "shadowfb"))
-        return FALSE;
-
-    if (!xf86LoadSubModule(pScrn, "vgahw"))
-        return FALSE;
-
-    /* Set up our ScrnInfoRec structure to describe our virtual
-       capabilities to X. */
-
-    pScrn->chipset = "vbox";
-
-    /* This *is* still needed, at least for server version 1.3 */
-    pScrn->monitor = pScrn->confScreen->monitor;
-
-    pScrn->progClock = TRUE;
-    pScrn->rgbBits = 8;
-
-    /* Using the PCI information caused problems with non-powers-of-two
-       sized video RAM configurations */
-    pScrn->videoRam = inl(VBE_DISPI_IOPORT_DATA) / 1024;
-
-    /* Check if the chip restricts horizontal resolution or not. */
-    outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
-    outw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
-    DispiId = inw(VBE_DISPI_IOPORT_DATA);
-    if (DispiId == VBE_DISPI_ID_ANYX)
-        pVBox->fAnyX = TRUE;
-    else
-        pVBox->fAnyX = FALSE;
-
-    /* Query the host for the preferred colour depth */
-    {
-        uint32_t cx, cy, iDisplay, cBits = 24;
-
-        if (vbox_device_available(pVBox))
-        {
-            /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
-            if (   vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits,
-                                               &iDisplay)
-                && (cBits != 16)
-               )
-                cBits = 24;
-        }
-        if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb))
-            return FALSE;
-    }
-    if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16)
-    {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "The VBox additions only support 16 and 32bpp graphics modes\n");
-        return FALSE;
-    }
-    xf86PrintDepthBpp(pScrn);
-
-    /* options */
-    xf86CollectOptions(pScrn, NULL);
-    if (!(pVBox->Options = malloc(sizeof(VBOXOptions))))
-        return FALSE;
-    memcpy(pVBox->Options, VBOXOptions, sizeof(VBOXOptions));
-    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pVBox->Options);
-
-    /* Work around a bug in the original X server modesetting code, which
-     * took the first valid values set to these two as maxima over the
-     * server lifetime. */
-    pScrn->virtualX = 32000;
-    pScrn->virtualY = 32000;
-
-    /* Initialise CRTC and output configuration for use with randr1.2. */
-    xf86CrtcConfigInit(pScrn, &VBOXCrtcConfigFuncs);
-
-    /* Setup our single virtual CRTC. */
-    xf86CrtcCreate(pScrn, &VBOXCrtcFuncs);
-
-    /* Set up our single virtual output. */
-    output = xf86OutputCreate(pScrn, &VBOXOutputFuncs, "VBOX1");
-
-    /* Set a sane minimum and maximum mode size */
-    xf86CrtcSetSizeRange(pScrn, 64, 64, 32000, 32000);
-
-    /* We are not interested in the monitor section in the configuration file. */
-    xf86OutputUseScreenMonitor(output, FALSE);
-    output->possible_crtcs = 1;
-    output->possible_clones = 0;
-
-    /* Now create our initial CRTC/output configuration. */
-    if (!xf86InitialConfiguration(pScrn, TRUE)) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Initial CRTC configuration failed!\n");
-        return (FALSE);
-    }
-
-    /* Colour weight - we always call this, since we are always in
-       truecolour. */
-    if (!xf86SetWeight(pScrn, rzeros, rzeros))
-        return (FALSE);
-
-    /* visual init */
-    if (!xf86SetDefaultVisual(pScrn, -1))
-        return (FALSE);
-
-    xf86SetGamma(pScrn, gzeros);
-
-    /* Set a default display resolution. */
-    xf86SetDpi(pScrn, 96, 96);
-
-    /* Framebuffer-related setup */
-    pScrn->bitmapBitOrder = BITMAP_BIT_ORDER;
-
-    /* VGA hardware initialisation */
-    if (!vgaHWGetHWRec(pScrn))
-        return FALSE;
-
-#ifdef VBOX_DRI
-    /* Load the dri module. */
-    if (!xf86LoadSubModule(pScrn, "dri"))
-        return FALSE;
-#endif
-    return (TRUE);
-}
-
 /**
  * This function hooks into the chain that is called when framebuffer access
@@ -839,4 +686,237 @@
  * QUOTE from the XFree86 DESIGN document:
  *
+ * The purpose of this function is to find out all the information
+ * required to determine if the configuration is usable, and to initialise
+ * those parts of the ScrnInfoRec that can be set once at the beginning of
+ * the first server generation.
+ *
+ * (...)
+ *
+ * This includes probing for video memory, clocks, ramdac, and all other
+ * HW info that is needed. It includes determining the depth/bpp/visual
+ * and related info. It includes validating and determining the set of
+ * video modes that will be used (and anything that is required to
+ * determine that).
+ *
+ * This information should be determined in the least intrusive way
+ * possible. The state of the HW must remain unchanged by this function.
+ * Although video memory (including MMIO) may be mapped within this
+ * function, it must be unmapped before returning.
+ *
+ * END QUOTE
+ */
+
+static Bool
+VBOXPreInit(ScrnInfoPtr pScrn, int flags)
+{
+    VBOXPtr pVBox;
+    Gamma gzeros = {0.0, 0.0, 0.0};
+    rgb rzeros = {0, 0, 0};
+#ifdef VBOXVIDEO_13
+    xf86OutputPtr output;
+#endif
+    unsigned DispiId;
+
+    TRACE_ENTRY();
+    /* Are we really starting the server, or is this just a dummy run? */
+    if (flags & PROBE_DETECT)
+        return (FALSE);
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+               "VirtualBox guest additions video driver version "
+               VBOX_VERSION_STRING "\n");
+
+    /* Get our private data from the ScrnInfoRec structure. */
+    pVBox = VBOXGetRec(pScrn);
+
+    /* Initialise the guest library */
+    vbox_init(pScrn->scrnIndex, pVBox);
+
+    /* Entity information seems to mean bus information. */
+    pVBox->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
+
+    /* The ramdac module is needed for the hardware cursor. */
+    if (!xf86LoadSubModule(pScrn, "ramdac"))
+        return FALSE;
+
+    /* We need the vbe module because we use VBE code to save and restore
+       text mode, in order to keep our code simple. */
+    if (!xf86LoadSubModule(pScrn, "vbe"))
+        return (FALSE);
+
+    /* The framebuffer module. */
+    if (xf86LoadSubModule(pScrn, "fb") == NULL)
+        return (FALSE);
+
+    if (!xf86LoadSubModule(pScrn, "shadowfb"))
+        return FALSE;
+
+    if (!xf86LoadSubModule(pScrn, "vgahw"))
+        return FALSE;
+
+#ifdef VBOX_DRI
+    /* Load the dri module. */
+    if (!xf86LoadSubModule(pScrn, "dri"))
+        return FALSE;
+#endif
+
+#ifndef PCIACCESS
+    if (pVBox->pEnt->location.type != BUS_PCI)
+        return FALSE;
+
+    pVBox->pciInfo = xf86GetPciInfoForEntity(pVBox->pEnt->index);
+    pVBox->pciTag = pciTag(pVBox->pciInfo->bus,
+                           pVBox->pciInfo->device,
+                           pVBox->pciInfo->func);
+#endif
+
+    /* Set up our ScrnInfoRec structure to describe our virtual
+       capabilities to X. */
+
+    pScrn->chipset = "vbox";
+    pScrn->rgbBits = 8;
+
+    /* Let's create a nice, capable virtual monitor.
+     * This *is* still needed, at least for server version 1.3 */
+    pScrn->monitor = pScrn->confScreen->monitor;
+    pScrn->monitor->DDC = NULL;
+    pScrn->monitor->nHsync = 1;
+    pScrn->monitor->hsync[0].lo = 1;
+    pScrn->monitor->hsync[0].hi = 10000;
+    pScrn->monitor->nVrefresh = 1;
+    pScrn->monitor->vrefresh[0].lo = 1;
+    pScrn->monitor->vrefresh[0].hi = 100;
+
+    pScrn->progClock = TRUE;
+
+    /* Using the PCI information caused problems with non-powers-of-two
+       sized video RAM configurations */
+    pVBox->cbFramebuffer = inl(VBE_DISPI_IOPORT_DATA);
+    pScrn->videoRam = pVBox->cbFramebuffer / 1024;
+
+    /* Check if the chip restricts horizontal resolution or not. */
+    outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
+    outw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_ANYX);
+    DispiId = inw(VBE_DISPI_IOPORT_DATA);
+    if (DispiId == VBE_DISPI_ID_ANYX)
+        pVBox->fAnyX = TRUE;
+    else
+        pVBox->fAnyX = FALSE;
+
+    /* Set up clock information that will support all modes we need. */
+    pScrn->clockRanges = xnfcalloc(sizeof(ClockRange), 1);
+    pScrn->clockRanges->minClock = 1000;
+    pScrn->clockRanges->maxClock = 1000000000;
+    pScrn->clockRanges->clockIndex = -1;
+    pScrn->clockRanges->ClockMulFactor = 1;
+    pScrn->clockRanges->ClockDivFactor = 1;
+
+    /* Query the host for the preferred colour depth */
+    {
+        uint32_t cx = 0, cy = 0, cBits = 0;
+
+        vboxGetPreferredMode(pScrn, &cx, &cy, &cBits);
+        /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
+        if (cBits != 16)
+            cBits = 24;
+        if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb))
+            return FALSE;
+#ifndef VBOXVIDEO_13
+        vboxAddModes(pScrn, cx, cy);
+#endif
+    }
+    if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16)
+    {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "The VBox additions only support 16 and 32bpp graphics modes\n");
+        return FALSE;
+    }
+    xf86PrintDepthBpp(pScrn);
+
+#ifdef VBOXVIDEO_13
+    /* Work around a bug in the original X server modesetting code, which
+     * took the first valid values set to these two as maxima over the
+     * server lifetime. */
+    pScrn->virtualX = 32000;
+    pScrn->virtualY = 32000;
+
+    /* Initialise CRTC and output configuration for use with randr1.2. */
+    xf86CrtcConfigInit(pScrn, &VBOXCrtcConfigFuncs);
+
+    /* Setup our single virtual CRTC. */
+    xf86CrtcCreate(pScrn, &VBOXCrtcFuncs);
+
+    /* Set up our single virtual output. */
+    output = xf86OutputCreate(pScrn, &VBOXOutputFuncs, "VBOX1");
+
+    /* Set a sane minimum and maximum mode size */
+    xf86CrtcSetSizeRange(pScrn, 64, 64, 32000, 32000);
+
+    /* We are not interested in the monitor section in the configuration file. */
+    xf86OutputUseScreenMonitor(output, FALSE);
+    output->possible_crtcs = 1;
+    output->possible_clones = 0;
+
+    /* Now create our initial CRTC/output configuration. */
+    if (!xf86InitialConfiguration(pScrn, TRUE)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Initial CRTC configuration failed!\n");
+        return (FALSE);
+    }
+#else /* !VBOXVIDEO_13 */
+    /* We don't validate with xf86ValidateModes and xf86PruneModes as we
+     * already know what we like and what we don't. */
+
+    pScrn->currentMode = pScrn->modes;
+
+    /* Set the right virtual resolution. */
+    pScrn->virtualX = pScrn->currentMode->HDisplay;
+    pScrn->virtualY = pScrn->currentMode->VDisplay;
+
+    pScrn->displayWidth = pScrn->virtualX;
+
+    xf86PrintModes(pScrn);
+
+#endif /* !VBOXVIDEO_13 */
+
+    /* Colour weight - we always call this, since we are always in
+       truecolour. */
+    if (!xf86SetWeight(pScrn, rzeros, rzeros))
+        return (FALSE);
+
+    /* visual init */
+    if (!xf86SetDefaultVisual(pScrn, -1))
+        return (FALSE);
+
+    xf86SetGamma(pScrn, gzeros);
+
+    /* Set the DPI.  Perhaps we should read this from the host? */
+    xf86SetDpi(pScrn, 96, 96);
+
+    /* Framebuffer-related setup */
+    pScrn->bitmapBitOrder = BITMAP_BIT_ORDER;
+
+    /* VGA hardware initialisation */
+    if (!vgaHWGetHWRec(pScrn))
+        return FALSE;
+
+    TRACE_EXIT();
+    return (TRUE);
+}
+
+/**
+ * Dummy function for setting the colour palette, which we actually never
+ * touch.  However, the server still requires us to provide this.
+ */
+static void
+vboxLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+          LOCO *colors, VisualPtr pVisual)
+{
+    (void)pScrn; (void) numColors; (void) indices; (void) colors;
+    (void)pVisual;
+}
+
+/*
+ * QUOTE from the XFree86 DESIGN document:
+ *
  * This is called at the start of each server generation.
  *
@@ -848,5 +928,5 @@
  * mode.
  *
- * End QUOTE.Initialise the initial video mode.
+ * End QUOTE.
  */
 static Bool
@@ -857,4 +937,12 @@
     VisualPtr visual;
     unsigned flags;
+
+    TRACE_ENTRY();
+    /* We make use of the X11 VBE code to save and restore text mode, in
+       order to keep our code simple. */
+    if ((pVBox->pVbe = VBEExtendedInit(NULL, pVBox->pEnt->index,
+                                       SET_BIOS_SCRATCH
+                                       | RESTORE_BIOS_SCRATCH)) == NULL)
+        return (FALSE);
 
     if (pScrn->memPhysBase == 0) {
@@ -864,8 +952,4 @@
         pScrn->memPhysBase = pVBox->pciInfo->memBase[0];
 #endif
-/*        pVBox->mapSize = 1 << pVBox->pciInfo->size[0]; */
-        /* Using the PCI information caused problems with
-           non-powers-of-two sized video RAM configurations */
-        pVBox->mapSize = inl(VBE_DISPI_IOPORT_DATA);
         pScrn->fbOffset = 0;
     }
@@ -876,6 +960,4 @@
     /* save current video state */
     VBOXSaveRestore(pScrn, MODE_SAVE);
-    pVBox->savedPal = VBESetGetPaletteData(pVBox->pVbe, FALSE, 0, 256,
-                                           NULL, FALSE, FALSE);
 
     /* mi layer - reset the visual list (?)*/
@@ -928,9 +1010,14 @@
      */
     pVBox->vtSwitch = FALSE;
-    /* Initialise DGA.  The cast is unfortunately correct - it gets cast back
-       to (unsigned char *) later. */
-    xf86DiDGAInit(pScreen, (unsigned long) pVBox->base);
-
-    /* Initialise randr 1.2 mode-setting functions and set first mode. */
+
+    if (vbox_device_available(pVBox) && vbox_open (pScrn, pScreen, pVBox)) {
+        vboxEnableVbva(pScrn);
+        vboxEnableGraphicsCap(pVBox);
+    }
+
+#ifdef VBOXVIDEO_13
+    /* Initialise randr 1.2 mode-setting functions and set first mode.
+     * Note that the mode won't be usable until the server has resized the
+     * framebuffer to something reasonable. */
     if (!xf86CrtcScreenInit(pScreen)) {
         return FALSE;
@@ -940,4 +1027,14 @@
         return FALSE;
     }
+#else /* !VBOXVIDEO_13 */
+    /* set first video mode */
+    if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay,
+                     pScrn->currentMode->VDisplay, pScrn->frameX0,
+                     pScrn->frameY0))
+        return FALSE;
+    /* And make sure that a non-current dynamic mode is at the front of the
+     * list */
+    vboxWriteHostModes(pScrn, pScrn->currentMode);
+#endif /* !VBOXVIDEO_13 */
 
     /* software cursor */
@@ -948,7 +1045,5 @@
 	return (FALSE);
 
-    flags = CMAP_RELOAD_ON_MODE_SWITCH;
-
-    if(!vgaHWHandleColormaps(pScreen))
+    if(!xf86HandleColormaps(pScreen, 256, 8, vboxLoadPalette, NULL, 0))
         return (FALSE);
 
@@ -962,9 +1057,9 @@
     pVBox->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = VBOXCloseScreen;
-    pScreen->SaveScreen = xf86SaveScreen;
+    pScreen->SaveScreen = VBOXSaveScreen;
 
     /* We probably do want to support power management - even if we just use
        a dummy function. */
-    xf86DPMSInit(pScreen, xf86DPMSSet, 0);
+    xf86DPMSInit(pScreen, VBOXDisplayPowerManagementSet, 0);
 
     /* Report any unused options (only for the first generation) */
@@ -972,13 +1067,7 @@
         xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
 
-    if (vbox_device_available(pVBox) && vbox_open (pScrn, pScreen, pVBox)) {
-        if (vbox_cursor_init(pScreen) != TRUE)
-            xf86DrvMsg(scrnIndex, X_ERROR,
-                       "Unable to start the VirtualBox mouse pointer integration with the host system.\n");
-        if (vboxEnableVbva(pScrn) == TRUE)
-            xf86DrvMsg(scrnIndex, X_INFO,
-                      "The VBox video extensions are now enabled.\n");
-        vboxEnableGraphicsCap(pVBox);
-    }
+    if (vbox_cursor_init(pScreen) != TRUE)
+        xf86DrvMsg(scrnIndex, X_ERROR,
+                   "Unable to start the VirtualBox mouse pointer integration with the host system.\n");
 
 #ifdef VBOX_DRI
@@ -994,5 +1083,4 @@
     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     VBOXPtr pVBox = VBOXGetRec(pScrn);
-    bool rc;
 
     TRACE_ENTRY();
@@ -1002,7 +1090,16 @@
         DRIUnlock(screenInfo.screens[scrnIndex]);
 #endif
-    rc = xf86SetDesiredModes(pScrn);
-    TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
-    return rc;
+#ifdef VBOXVIDEO_13
+    if (!xf86SetDesiredModes(pScrn))
+        return FALSE;
+#else
+    if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay,
+                     pScrn->currentMode->VDisplay, pScrn->frameX0,
+                     pScrn->frameY0))
+        return FALSE;
+#endif
+    if (pVBox->fHaveHGSMI)
+        vboxEnableVbva(pScrn);
+    return TRUE;
 }
 
@@ -1016,10 +1113,7 @@
     pVBox->vtSwitch = TRUE;
     VBOXSaveRestore(pScrn, MODE_RESTORE);
-    if (vbox_device_available(pVBox))
-    {
-        if (pVBox->useVbva == TRUE)
-            vboxDisableVbva(pScrn);
-        vboxDisableGraphicsCap(pVBox);
-    }
+    if (pVBox->fHaveHGSMI)
+        vboxDisableVbva(pScrn);
+    vboxDisableGraphicsCap(pVBox);
 #ifdef VBOX_DRI
     if (pVBox->useDRI)
@@ -1041,16 +1135,10 @@
 #endif
 
-    if (vbox_device_available(pVBox))
-    {
-        if (TRUE == pVBox->useVbva)
-            vboxDisableVbva(pScrn);
-        vboxDisableGraphicsCap(pVBox);
-    }
+    if (pVBox->fHaveHGSMI)
+        vboxDisableVbva(pScrn);
+    vboxDisableGraphicsCap(pVBox);
     if (pScrn->vtSema) {
-	VBOXSaveRestore(xf86Screens[scrnIndex], MODE_RESTORE);
-	if (pVBox->savedPal)
-	    VBESetGetPaletteData(pVBox->pVbe, TRUE, 0, 256,
-				 pVBox->savedPal, FALSE, TRUE);
-	VBOXUnmapVidMem(pScrn);
+        VBOXSaveRestore(xf86Screens[scrnIndex], MODE_RESTORE);
+        VBOXUnmapVidMem(pScrn);
     }
     pScrn->vtSema = FALSE;
@@ -1066,66 +1154,4 @@
     pScreen->CloseScreen = pVBox->CloseScreen;
     return pScreen->CloseScreen(scrnIndex, pScreen);
-}
-
-/**
- * Quoted from "How to add an (S)VGA driver to XFree86"
- * (http://www.xfree86.org/3.3.6/VGADriver.html):
- *
- * The ValidMode() function is required. It is used to check for any
- * chipset-dependent reasons why a graphics mode might not be valid. It gets
- * called by higher levels of the code after the Probe() stage. In many cases
- * no special checking will be required and this function will simply return
- * TRUE always.
- *
- * Note: we check here that our generated video modes fulfil the X server's
- * criteria for the monitor, since this can otherwise cause problems in
- * randr 1.2.
- */
-static ModeStatus
-VBOXValidMode(int scrn, DisplayModePtr p, Bool flag, int pass)
-{
-    static int warned = 0;
-    ScrnInfoPtr pScrn = xf86Screens[scrn];
-    MonPtr mon = pScrn->monitor;
-    ModeStatus ret = MODE_BAD;
-    DisplayModePtr mode;
-    float v;
-
-    TRACE_LOG("HDisplay=%d, VDisplay=%d, flag=%s, pass=%d\n",
-           p->HDisplay, p->VDisplay, flag ? "TRUE" : "FALSE", pass);
-    if (pass != MODECHECK_FINAL) {
-        if (!warned) {
-            xf86DrvMsg(scrn, X_WARNING, "VBOXValidMode called unexpectedly\n");
-            warned = 1;
-        }
-    }
-#if 0
-    /*
-     * First off, if this isn't a mode we handed to the server (ie,
-     * M_T_BUILTIN), then we reject it out of hand.
-     */
-    if (!(p->type & M_T_BUILTIN))
-        return MODE_NOMODE;
-#endif
-    /*
-     * Finally, walk through the vsync rates 1Hz at a time looking for a mode
-     * that will fit.  This is assuredly a terrible way to do this, but
-     * there's no obvious method for computing a mode of a given size that
-     * will pass xf86CheckModeForMonitor.
-     */
-    for (v = mon->vrefresh[0].lo; v <= mon->vrefresh[0].hi; v++) {
-        mode = xf86CVTMode(p->HDisplay, p->VDisplay, v, 0, 0);
-        ret = xf86CheckModeForMonitor(mode, mon);
-        free(mode);
-        if (ret == MODE_OK)
-            break;
-    }
-
-    if (ret != MODE_OK)
-    {
-        xf86DrvMsg(scrn, X_WARNING, "Graphics mode %s rejected by the X server\n", p->name);
-    }
-    TRACE_LOG("returning %d\n", ret);
-    return ret;
 }
 
@@ -1144,5 +1170,18 @@
     if (pVBox->accessEnabled)
         pVBox->EnableDisableFBAccess(scrnIndex, FALSE);
+#ifdef VBOXVIDEO_13
     rc = xf86SetSingleMode(pScrn, pMode, 0);
+#else
+    rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay,
+                     pScrn->frameX0, pScrn->frameY0);
+    if (rc)
+    {
+        vboxWriteHostModes(pScrn, pMode);
+        xf86PrintModes(pScrn);
+    }
+#endif
+    if (rc && !vboxGuestIsSeamless(pScrn))
+        vboxSaveVideoMode(pScrn, pMode->HDisplay, pMode->VDisplay,
+                          pScrn->bitsPerPixel);
     if (pVBox->accessEnabled)
         pVBox->EnableDisableFBAccess(scrnIndex, TRUE);
@@ -1155,5 +1194,6 @@
    graphics functions. */
 static Bool
-VBOXSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
+VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
+            unsigned cHeight, int x, int y)
 {
     VBOXPtr pVBox;
@@ -1161,6 +1201,6 @@
 
     int bpp = pScrn->depth == 24 ? 32 : 16;
-    TRACE_LOG("HDisplay=%d, VDisplay=%d, displayWidth=%d\n",
-              pMode->HDisplay, pMode->VDisplay, pScrn->displayWidth);
+    TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n",
+              cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth);
     pVBox = VBOXGetRec(pScrn);
     /* Don't fiddle with the hardware if we are switched
@@ -1168,44 +1208,64 @@
     if (!pVBox->vtSwitch)
     {
-        if (    vbox_device_available(pVBox)
-            && (TRUE == pVBox->useVbva)
-            && (vboxDisableVbva(pScrn) != TRUE)
-           )  /* This would be bad. */
-            rc = FALSE;
-        if (rc)
-        {
-            /* Disable linear framebuffer mode before making changes to the resolution. */
-            outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
-            outw(VBE_DISPI_IOPORT_DATA, VBE_DISPI_DISABLED);
-            /* Unlike the resolution, the depth is fixed for a given screen
-               for the lifetime of the X session. */
-            outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
-            outw(VBE_DISPI_IOPORT_DATA, bpp);
-            /* HDisplay and VDisplay are actually monitor information about
-               the display part of the scanlines. */
-            outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
-            outw(VBE_DISPI_IOPORT_DATA, pMode->HDisplay);
-            outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
-            outw(VBE_DISPI_IOPORT_DATA, pMode->VDisplay);
-            /* Set the virtual resolution.  We are still using VESA to control
-               the virtual offset. */
-            outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIRT_WIDTH);
-            outw(VBE_DISPI_IOPORT_DATA, pScrn->displayWidth);
-            /* Enable linear framebuffer mode. */
-            outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
-            outw(VBE_DISPI_IOPORT_DATA,
-                 VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
-            /* Enable acceleration and tell the host we support graphics */
-            if (vbox_device_available(pVBox))
-            {
-                if ((TRUE == pVBox->useVbva) && (vboxEnableVbva(pScrn) != TRUE))
-                /* Bad but not fatal */
-                    pVBox->useVbva = FALSE;
-                vboxEnableGraphicsCap(pVBox);
-            }
-        }
-    }
+        if (cDisplay == 0)
+            VBoxVideoSetModeRegisters(cWidth, cHeight, pScrn->displayWidth,
+                                      bpp, x, y);
+        /* Tell the host we support graphics */
+        if (vbox_device_available(pVBox))
+            vboxEnableGraphicsCap(pVBox);
+    }
+    if (    vbox_device_available(pVBox)
+        && (pVBox->fHaveHGSMI)
+        && !pVBox->vtSwitch)
+        VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y,
+                                    (y * pScrn->displayWidth + x) * bpp / 8,
+                                    pScrn->displayWidth * bpp / 8,
+                                    cWidth, cHeight, bpp);
+    pVBox->aScreenLocation[0].cx = cWidth;
+    pVBox->aScreenLocation[0].cy = cHeight;
+    pVBox->aScreenLocation[0].x = x;
+    pVBox->aScreenLocation[0].y = y;
     TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
     return rc;
+}
+
+static Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
+{
+    ScreenPtr pScreen = pScrn->pScreen;
+    PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
+    VBOXPtr pVBox = VBOXGetRec(pScrn);
+    int bpp = pScrn->depth == 24 ? 32 : 16;
+
+    TRACE_LOG("width=%d, height=%d\n", width, height);
+    if ((uint64_t)width * height * bpp / 8 >= pVBox->cbFramebuffer)
+    {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "Unable to set up a virtual screen size of %dx%d with %lu of %d Kb of video memory available.  Please increase the video memory size.\n",
+                   width, height, pVBox->cbFramebuffer / 1024, pScrn->videoRam);
+        return FALSE;
+    }
+    if (!pPixmap) {
+        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                   "Failed to get the screen pixmap.\n");
+        return FALSE;
+    }
+    pScreen->ModifyPixmapHeader(pPixmap, width, height,
+                                pScrn->depth, bpp, width * bpp / 8,
+                                pVBox->base);
+    pScrn->virtualX = width;
+    pScrn->virtualY = height;
+    pScrn->displayWidth = width;
+#ifdef VBOX_DRI
+    if (pVBox->useDRI)
+        VBOXDRIUpdateStride(pScrn, pVBox);
+#endif
+#ifdef VBOXVIDEO_13
+    /* Write the new values to the hardware */
+    xf86SetDesiredModes(pScrn);
+#else
+    pScrn->EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
+    pScrn->EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
+#endif
+    return TRUE;
 }
 
@@ -1219,14 +1279,6 @@
     /* Don't fiddle with the hardware if we are switched
      * to a virtual terminal. */
-    if (!pVBox->vtSwitch) {
-        pVBox->viewportX = x;
-        pVBox->viewportY = y;
-        /* If VBVA is enabled the graphics card will not notice the change. */
-        if (pVBox->useVbva == TRUE)
-            vboxDisableVbva(pScrn);
-        VBESetDisplayStart(pVBox->pVbe, x, y, TRUE);
-        if (pVBox->useVbva == TRUE)
-            vboxEnableVbva(pScrn);
-    }
+    VBOXSetMode(pScrn, 0, pVBox->aScreenLocation[0].cx,
+                pVBox->aScreenLocation[0].cy, x, y);
     TRACE_EXIT();
 }
@@ -1250,5 +1302,5 @@
         (void) pci_device_map_range(pVBox->pciInfo,
                                     pScrn->memPhysBase,
-                                    pVBox->mapSize,
+                                    pScrn->videoRam * 1024,
                                     PCI_DEV_MAP_FLAG_WRITABLE,
                                     & pVBox->base);
@@ -1257,5 +1309,5 @@
                                     VIDMEM_FRAMEBUFFER,
                                     pVBox->pciTag, pScrn->memPhysBase,
-                                    (unsigned) pVBox->mapSize);
+                                    (unsigned) pScrn->videoRam * 1024);
 #endif
         if (pVBox->base)
@@ -1284,8 +1336,8 @@
     (void) pci_device_unmap_range(pVBox->pciInfo,
                                   pVBox->base,
-                                  pVBox->mapSize);
+                                  pScrn->videoRam * 1024);
 #else
     xf86UnMapVidMem(pScrn->scrnIndex, pVBox->base,
-                    (unsigned) pVBox->mapSize);
+                    (unsigned) pScrn->videoRam * 1024);
 #endif
     vgaHWUnmapMem(pScrn);
@@ -1294,4 +1346,10 @@
 }
 
+static Bool
+VBOXSaveScreen(ScreenPtr pScreen, int mode)
+{
+    (void)pScreen; (void)mode;
+    return TRUE;
+}
 
 Bool
@@ -1357,2 +1415,9 @@
     return rc;
 }
+
+static void
+VBOXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int mode,
+                int flags)
+{
+    (void)pScrn; (void)mode; (void) flags;
+}
Index: /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c	(revision 34714)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c	(revision 34715)
@@ -175,5 +175,5 @@
         || (pVBox->pciInfo == NULL)
         || (pVBox->base == NULL)
-        || (pVBox->mapSize == 0))
+        || (pVBox->cbFramebuffer == 0))
     {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: preconditions failed\n",
@@ -256,5 +256,5 @@
         pDRIInfo->maxDrawableTableEntry = VBOX_MAX_DRAWABLES;
         pDRIInfo->frameBufferPhysicalAddress = (pointer)pScrn->memPhysBase;
-        pDRIInfo->frameBufferSize = pVBox->mapSize;
+        pDRIInfo->frameBufferSize = pVBox->cbFramebuffer;
         pDRIInfo->frameBufferStride =   pScrn->displayWidth
                                       * pScrn->bitsPerPixel / 8;
