Index: /trunk/include/VBox/VBoxVideoGuest.h
===================================================================
--- /trunk/include/VBox/VBoxVideoGuest.h	(revision 53965)
+++ /trunk/include/VBox/VBoxVideoGuest.h	(revision 53966)
@@ -257,4 +257,6 @@
                                              uint8_t *pPixels,
                                              uint32_t cbLength);
+RTDECL(int)      VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y,
+                                         uint32_t *pxHost, uint32_t *pyHost);
 
 /** @}  */
@@ -329,4 +331,6 @@
                                              uint16_t cBPP,
                                              uint16_t fFlags);
+RTDECL(int)      VBoxHGSMIUpdateInputMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, int32_t  cOriginX, int32_t  cOriginY,
+                                             uint32_t cWidth, uint32_t cHeight);
 RTDECL(int) VBoxHGSMIGetModeHints(PHGSMIGUESTCOMMANDCONTEXT pCtx,
                                   unsigned cScreens, VBVAMODEHINT *paHints);
Index: /trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp	(revision 53965)
+++ /trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp	(revision 53966)
@@ -581,4 +581,51 @@
 
 
+/** 
+ * Report the guest cursor position.  The host may wish to use this information
+ * to re-position its own cursor (though this is currently unlikely).  The
+ * current host cursor position is returned.
+ * @param  pCtx             The context containing the heap used.
+ * @param  fReportPosition  Are we reporting a position?
+ * @param  x                Guest cursor X position.
+ * @param  y                Guest cursor Y position.
+ * @param  pxHost           Host cursor X position is stored here.  Optional.
+ * @param  pyHost           Host cursor Y position is stored here.  Optional.
+ * @returns  iprt status code.
+ * @returns  VERR_NO_MEMORY      HGSMI heap allocation failed.
+ */
+RTDECL(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y,
+                                    uint32_t *pxHost, uint32_t *pyHost)
+{
+    int rc = VINF_SUCCESS;
+    VBVACURSORPOSITION *p;
+    LogRelFlowFunc(("x=%u, y=%u\n", (unsigned)x, (unsigned)y));
+
+    /* Allocate the IO buffer. */
+    p = (VBVACURSORPOSITION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACURSORPOSITION), HGSMI_CH_VBVA, VBVA_CURSOR_POSITION);
+    if (p)
+    {
+        /* Prepare data to be sent to the host. */
+        p->fReportPosition = fReportPosition ? 1 : 0;
+        p->x = x;
+        p->y = y;
+        rc = VBoxHGSMIBufferSubmit(pCtx, p);
+        if (RT_SUCCESS(rc))
+        {
+            if (pxHost)
+                *pxHost = p->x;
+            if (pyHost)
+                *pyHost = p->y;
+            LogRelFlowFunc(("return: x=%u, y=%u\n", (unsigned)x, (unsigned)y));
+        }
+        /* Free the IO buffer. */
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    LogFunc(("rc = %d\n", rc));
+    return rc;
+}
+
+
 /** @todo Mouse pointer position to be read from VMMDev memory, address of the memory region
  * can be queried from VMMDev via an IOCTL. This VMMDev memory region will contain
Index: /trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp	(revision 53965)
+++ /trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp	(revision 53966)
@@ -280,4 +280,47 @@
 }
 
+
+/** Report the rectangle relative to which absolute pointer events should be
+ *  expressed.  This information remains valid until the next VBVA resize event
+ *  for any screen, at which time it is reset to the bounding rectangle of all
+ *  virtual screens. 
+ * @param  pCtx      The context containing the heap to use.
+ * @param  cOriginX  Upper left X co-ordinate relative to the first screen.
+ * @param  cOriginY  Upper left Y co-ordinate relative to the first screen.
+ * @param  cWidth    Rectangle width.
+ * @param  cHeight   Rectangle height.
+ * @returns  iprt status code.
+ * @returns  VERR_NO_MEMORY      HGSMI heap allocation failed.
+ */
+RTDECL(int)      VBoxHGSMIUpdateInputMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, int32_t  cOriginX, int32_t  cOriginY,
+                                             uint32_t cWidth, uint32_t cHeight)
+{
+    int rc = VINF_SUCCESS;
+    VBVAREPORTINPUTMAPPING *p;
+    LogRelFlowFunc(("cOriginX=%u, cOriginY=%u, cWidth=%u, cHeight=%u\n",
+                    (unsigned)cOriginX, (unsigned)cOriginX,
+                    (unsigned)cWidth, (unsigned)cHeight));
+
+    /* Allocate the IO buffer. */
+    p = (VBVAREPORTINPUTMAPPING *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAREPORTINPUTMAPPING), HGSMI_CH_VBVA,
+                                                       VBVA_REPORT_INPUT_MAPPING);
+    if (p)
+    {
+        /* Prepare data to be sent to the host. */
+        p->x  = cOriginX;
+        p->y  = cOriginY;
+        p->cx = cWidth;
+        p->cy = cHeight;
+        rc = VBoxHGSMIBufferSubmit(pCtx, p);
+        /* Free the IO buffer. */
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    LogFunc(("rc = %d\n", rc));
+    return rc;
+}
+
+
 /**
  * Get most recent video mode hints.
Index: /trunk/src/VBox/Additions/x11/VBoxClient/display.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/display.cpp	(revision 53965)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/display.cpp	(revision 53966)
@@ -25,5 +25,4 @@
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
-#include <X11/cursorfont.h>
 
 #include <iprt/assert.h>
@@ -39,7 +38,36 @@
 #include "VBoxClient.h"
 
-/** State information we need for interacting with the X server. */
-struct x11State
-{
+/* TESTING: Dynamic resizing and mouse integration toggling should work
+ * correctly with a range of X servers (pre-1.3, 1.3 and later under Linux, 1.3
+ * and later under Solaris) with Guest Additions installed.  Switching to a
+ * virtual terminal while a user session is in place should disable dynamic
+ * resizing and cursor integration, switching back should re-enable them. */
+
+/** Most recent information received for a particular screen. */
+struct screenInformation
+{
+    unsigned cx;
+    unsigned cy;
+    unsigned cBPP;
+    unsigned x;
+    unsigned y;
+    bool fEnabled;
+    bool fUpdateSize;
+    bool fUpdatePosition;
+};
+
+/** Display magic number, start of a UUID. */
+#define DISPLAYSTATE_MAGIC UINT32_C(0xf0029993)
+
+/** State information needed for the service.  The main VBoxClient code provides
+ *  the daemon logic needed by all services. */
+struct DISPLAYSTATE
+{
+    /** The service interface. */
+    struct VBCLSERVICE *pInterface;
+    /** Magic number for sanity checks. */
+    uint32_t magic;
+    /** Are we initialised yet? */
+    bool mfInit;
     /** The connection to the server. */
     Display *pDisplay;
@@ -50,10 +78,8 @@
      * would it make sense to use absolute paths on all systems? */
     const char *pcszXrandr;
-    /** The size of our array of size hints. */
-    unsigned cSizeHints;
-    /** Array of size hints.  Large enough to hold the highest display
-     * number we have had a hint for so far, reallocated when a higher one
-     * comes.  Zero means no hint for that display. */
-    long *paSizeHints;
+    /** The number of screens we are currently aware of. */
+    unsigned cScreensTracked;
+    /** Array of information about different screens. */
+    struct screenInformation *paScreenInformation;
 };
 
@@ -92,5 +118,5 @@
 }
 
-static int initX11(struct x11State *pState)
+static int initDisplay(struct DISPLAYSTATE *pState)
 {
     char szCommand[256];
@@ -111,99 +137,138 @@
     if (WEXITSTATUS(status) == 0)
         pState->fHaveRandR12 = true;
-    pState->cSizeHints = 0;
-    pState->paSizeHints = NULL;
+    pState->cScreensTracked = 0;
+    pState->paScreenInformation = NULL;
     return VINF_SUCCESS;
 }
 
-static void setModeX11(struct x11State *pState, unsigned cx, unsigned cy,
-                       unsigned cBPP, unsigned iDisplay, unsigned x,
-                       unsigned y, bool fEnabled, bool fChangeOrigin)
+static void updateScreenInformation(struct DISPLAYSTATE *pState, unsigned cx, unsigned cy, unsigned cBPP, unsigned iDisplay,
+                                    unsigned x, unsigned y, bool fEnabled, bool fUpdatePosition)
+{
+    uint32_t i;
+
+    if (iDisplay >= pState->cScreensTracked)
+    {
+        pState->paScreenInformation =
+                (struct screenInformation *)RTMemRealloc(pState->paScreenInformation,
+                                                         (iDisplay + 1) * sizeof(*pState->paScreenInformation));
+        if (!pState->paScreenInformation)
+            VBClFatalError(("Failed to re-allocate screen information.\n"));
+        for (i = pState->cScreensTracked; i < iDisplay + 1; ++i)
+            RT_ZERO(pState->paScreenInformation[i]);
+        pState->cScreensTracked = iDisplay + 1;
+    }
+    pState->paScreenInformation[iDisplay].cx = cx;
+    pState->paScreenInformation[iDisplay].cy = cy;
+    pState->paScreenInformation[iDisplay].cBPP = cBPP;
+    pState->paScreenInformation[iDisplay].x = x;
+    pState->paScreenInformation[iDisplay].y = y;
+    pState->paScreenInformation[iDisplay].fEnabled = fEnabled;
+    pState->paScreenInformation[iDisplay].fUpdateSize = true;
+    pState->paScreenInformation[iDisplay].fUpdatePosition = fUpdatePosition;
+}
+
+static void updateSizeHintsProperty(struct DISPLAYSTATE *pState)
+{
+    int32_t *paSizeHints = (int32_t *)RTMemTmpAllocZ(pState->cScreensTracked * sizeof(int32_t));
+    unsigned i;
+
+    if (paSizeHints == NULL)
+        VBClFatalError(("Failed to allocate size hint property memory.\n"));
+    for (i = 0; i < pState->cScreensTracked; ++i)
+    {
+        if (   pState->paScreenInformation[i].fEnabled
+            && pState->paScreenInformation[i].cx != 0 && pState->paScreenInformation[i].cy != 0)
+            paSizeHints[i] = (pState->paScreenInformation[i].cx & 0x8fff) << 16 | (pState->paScreenInformation[i].cy & 0x8fff);
+        else if (pState->paScreenInformation[i].cx != 0 && pState->paScreenInformation[i].cy != 0)
+            paSizeHints[i] = -1;
+    }
+    XChangeProperty(pState->pDisplay, DefaultRootWindow(pState->pDisplay), XInternAtom(pState->pDisplay, "VBOX_SIZE_HINTS", 0),
+                    XA_INTEGER, 32, PropModeReplace, (unsigned char *)paSizeHints, pState->cScreensTracked);
+    XFlush(pState->pDisplay);
+    RTMemTmpFree(paSizeHints);
+}
+
+static void notifyXServer(struct DISPLAYSTATE *pState)
 {
     char szCommand[256];
-    uint32_t i;
+    unsigned i;
+    bool fUpdateInformation = false;
 
     /** @note The xrandr command can fail if something else accesses RandR at
      *  the same time.  We just ignore failure for now and let the user try
      *  again as we do not know what someone else is doing. */
-    if (iDisplay >= pState->cSizeHints)
+    for (i = 0; i < pState->cScreensTracked; ++i)
+        if (pState->paScreenInformation[i].fUpdateSize)
+            fUpdateInformation = true;
+    if (   !pState->fHaveRandR12 && pState->paScreenInformation[0].fUpdateSize
+        && pState->paScreenInformation[0].cx > 0 && pState->paScreenInformation[0].cy > 0)
     {
-        pState->paSizeHints = (long *)RTMemRealloc(pState->paSizeHints,
-                                                  (iDisplay + 1)
-                                                * sizeof(*pState->paSizeHints));
-        if (!pState->paSizeHints)
-            VBClFatalError(("Failed to re-allocate size hint memory.\n"));
-        for (i = pState->cSizeHints; i < iDisplay + 1; ++i)
-            pState->paSizeHints[i] = 0;
-        pState->cSizeHints = iDisplay + 1;
+        RTStrPrintf(szCommand, sizeof(szCommand), "%s -s %ux%u",
+                    pState->pcszXrandr, pState->paScreenInformation[0].cx, pState->paScreenInformation[0].cy);
+        system(szCommand);
+        pState->paScreenInformation[0].fUpdateSize = false;
     }
-    if (!fEnabled || (cx != 0 && cy != 0))
+    else if (pState->fHaveRandR12 && fUpdateInformation)
+        for (i = 0; i < pState->cScreensTracked; ++i)
+        {
+            if (pState->paScreenInformation[i].fUpdateSize)
+            {
+                RTStrPrintf(szCommand, sizeof(szCommand), "%s --output VGA-%u --preferred", pState->pcszXrandr, i);
+                system(szCommand);
+            }
+            if (pState->paScreenInformation[i].fUpdatePosition)
+            {
+                RTStrPrintf(szCommand, sizeof(szCommand), "%s --output VGA-%u --auto --pos %ux%u",
+                            pState->pcszXrandr, i, pState->paScreenInformation[i].x, pState->paScreenInformation[i].y);
+                system(szCommand);
+            }
+            pState->paScreenInformation[i].fUpdateSize = pState->paScreenInformation[i].fUpdatePosition = false;
+        }
+    else
     {
-        pState->paSizeHints[iDisplay] = (cx & 0x8fff) << 16 | (cy & 0x8fff);
-        XChangeProperty(pState->pDisplay, DefaultRootWindow(pState->pDisplay),
-                        XInternAtom(pState->pDisplay, "VBOX_SIZE_HINTS", 0),
-                        XA_INTEGER, 32, PropModeReplace,
-                        (unsigned char *)pState->paSizeHints,
-                        pState->cSizeHints);
-        XFlush(pState->pDisplay);
-    }
-    if (!pState->fHaveRandR12)
-    {
-        RTStrPrintf(szCommand, sizeof(szCommand),
-                    "%s -s %ux%u", pState->pcszXrandr, cx, cy);
+        RTStrPrintf(szCommand, sizeof(szCommand), "%s", pState->pcszXrandr);
         system(szCommand);
     }
+}
+
+static void updateMouseCapabilities(struct DISPLAYSTATE *pState)
+{
+    uint32_t fFeatures = 0;
+    int rc;
+    unsigned i;
+
+    rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
+    
+    if (rc != VINF_SUCCESS)
+        VBClFatalError(("Failed to get mouse status, rc=%Rrc\n", rc));
+    XChangeProperty(pState->pDisplay, DefaultRootWindow(pState->pDisplay),
+                    XInternAtom(pState->pDisplay, "VBOX_MOUSE_CAPABILITIES", 0), XA_INTEGER, 32, PropModeReplace,
+                    (unsigned char *)&fFeatures, 1);
+    XFlush(pState->pDisplay);
+    if (pState->fHaveRandR12)
+        for (i = 0; i < pState->cScreensTracked; ++i)
+            pState->paScreenInformation[i].fUpdateSize = true;
     else
-    {
-        if (fChangeOrigin && fEnabled)
-        {
-            /* Extended Display support possible . Secondary monitor
-             * position supported */
-            RTStrPrintf(szCommand, sizeof(szCommand),
-                        "%s --output VGA-%u --auto --pos %ux%u",
-                        pState->pcszXrandr, iDisplay, x, y);
-            system(szCommand);
-        }
-        if ((!fChangeOrigin || fEnabled) && cx != 0 && cy != 0)
-        {
-            RTStrPrintf(szCommand, sizeof(szCommand),
-                        "%s --output VGA-%u --preferred",
-                        pState->pcszXrandr, iDisplay);
-            system(szCommand);
-        }
-        if (!fEnabled)
-        {
-            /* disable the virtual monitor */
-            RTStrPrintf(szCommand, sizeof(szCommand),
-                        "%s --output VGA-%u --off",
-                         pState->pcszXrandr, iDisplay);
-            system(szCommand);
-        }
-    }
+        pState->paScreenInformation[0].fUpdateSize = true;
 }
 
 /**
  * Display change request monitor thread function.
- * Before entering the loop, we re-read the last request
- * received, and if the first one received inside the
- * loop is identical we ignore it, because it is probably
- * stale.
  */
-static void runDisplay(struct x11State *pState)
+static void runDisplay(struct DISPLAYSTATE *pState)
 {
     int status, rc;
-    unsigned i, cScreens;
+    unsigned i, cScreensTracked;
     char szCommand[256];
-    Cursor hClockCursor = XCreateFontCursor(pState->pDisplay, XC_watch);
-    Cursor hArrowCursor = XCreateFontCursor(pState->pDisplay, XC_left_ptr);
 
     LogRelFlowFunc(("\n"));
-    rc = VbglR3VideoModeGetHighestSavedScreen(&cScreens);
+    rc = VbglR3VideoModeGetHighestSavedScreen(&cScreensTracked);
     if (rc != VINF_SUCCESS && rc != VERR_NOT_SUPPORTED)
-        VBClFatalError(("Failed to get the number of saved screen modes, rc=%Rrc\n",
-                    rc));
+        VBClFatalError(("Failed to get the number of saved screen modes, rc=%Rrc\n", rc));
+    /* Make sure that we have an entry for screen 1 at least. */
+    updateScreenInformation(pState, 1024, 768, 0, 1, 0, 0, true, false);
     if (rc == VINF_SUCCESS)
-        /* The "8" is to sanity test that VbglR3VideoModeGetHighestSavedScreen()
-         * worked right. */
-        for (i = 0; i < RT_MAX(cScreens + 1, 8); ++i)
+        /* The "8" is for the sanity test below. */
+        for (i = 0; i < RT_MAX(cScreensTracked + 1, 8); ++i)
         {
             unsigned cx = 0, cy = 0, cBPP = 0, x = 0, y = 0;
@@ -212,14 +277,16 @@
             rc = VbglR3RetrieveVideoMode(i, &cx, &cy, &cBPP, &x, &y,
                                          &fEnabled);
-            /* Sanity test. */
-            if (i > cScreens && rc != VERR_NOT_FOUND)
+            /* Sanity test for VbglR3VideoModeGetHighestSavedScreen(). */
+            if (i > cScreensTracked && rc != VERR_NOT_FOUND)
                 VBClFatalError(("Internal error retrieving the number of saved screen modes.\n"));
             if (rc == VINF_SUCCESS)
-                setModeX11(pState, cx, cy, cBPP, i, x, y, fEnabled,
-                           true);
+                updateScreenInformation(pState, cx, cy, cBPP, i, x, y, fEnabled, true);
         }
     while (true)
     {
         uint32_t fEvents;
+        updateMouseCapabilities(pState);
+        updateSizeHintsProperty(pState);
+        notifyXServer(pState);
         do
             rc = VbglR3WaitEvent(  VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST
@@ -229,32 +296,14 @@
         if (RT_FAILURE(rc))  /* VERR_NO_MEMORY? */
             VBClFatalError(("event wait failed, rc=%Rrc\n", rc));
-        if (fEvents & VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED)
-        {
-            /* Jiggle the mouse pointer to trigger a switch to a software
-             * cursor if necessary. */
-            XGrabPointer(pState->pDisplay,
-                         DefaultRootWindow(pState->pDisplay), true, 0,
-                         GrabModeAsync, GrabModeAsync, None, hClockCursor,
-                         CurrentTime);
-            XFlush(pState->pDisplay);
-            XGrabPointer(pState->pDisplay,
-                         DefaultRootWindow(pState->pDisplay), true, 0,
-                         GrabModeAsync, GrabModeAsync, None, hArrowCursor,
-                         CurrentTime);
-            XFlush(pState->pDisplay);
-            XUngrabPointer(pState->pDisplay, CurrentTime);
-            XFlush(pState->pDisplay);
-        }
-        /* And if it is a size hint, set the new size. */
+        /* If it is a size hint, set the new size. */
         if (fEvents & VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST)
         {
             uint32_t cx = 0, cy = 0, cBPP = 0, iDisplay = 0, x = 0, y = 0;
-            bool fEnabled = true, fChangeOrigin = true;
+            bool fEnabled = true, fUpdatePosition = true;
             VMMDevSeamlessMode Mode;
 
             rc = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBPP, &iDisplay,
                                                &x, &y, &fEnabled,
-                                               &fChangeOrigin, true);
-            /* Extended display version not supported on host */
+                                               &fUpdatePosition, true);
             if (rc != VINF_SUCCESS)
                 VBClFatalError(("Failed to get display change request, rc=%Rrc\n",
@@ -262,9 +311,9 @@
             else
                 LogRelFlowFunc(("Got size hint from host cx=%d, cy=%d, bpp=%d, iDisplay=%d, x=%d, y=%d fEnabled=%d\n",
-                                cx, cy, cBPP, iDisplay, x, y,
-                                fEnabled));
+                                cx, cy, cBPP, iDisplay, x, y, fEnabled));
             if (iDisplay > INT32_MAX)
                 VBClFatalError(("Received a size hint for too high display number %u\n",
                             (unsigned) iDisplay));
+            updateScreenInformation(pState, cx, cy, cBPP, i, x, y, fEnabled, fUpdatePosition);
             rc = VbglR3SeamlessGetLastEvent(&Mode);
             if (RT_FAILURE(rc))
@@ -277,28 +326,8 @@
                     VBClFatalError(("Failed to save size hint, rc=%Rrc\n", rc));
             }
-            setModeX11(pState, cx, cy, cBPP, iDisplay, x, y, fEnabled,
-                       fChangeOrigin);
         }
     }
 }
 
-/** Display magic number, start of a UUID. */
-#define DISPLAYSERVICE_MAGIC 0xf0029993
-
-/** VBoxClient service class wrapping the logic for the display service while
- *  the main VBoxClient code provides the daemon logic needed by all services.
- */
-struct DISPLAYSERVICE
-{
-    /** The service interface. */
-    struct VBCLSERVICE *pInterface;
-    /** Magic number for sanity checks. */
-    uint32_t magic;
-    /** State related to the X server. */
-    struct x11State mState;
-    /** Are we initialised yet? */
-    bool mfInit;
-};
-
 static const char *getPidFilePath()
 {
@@ -306,9 +335,8 @@
 }
 
-static struct DISPLAYSERVICE *getClassFromInterface(struct VBCLSERVICE **
-                                                         ppInterface)
-{
-    struct DISPLAYSERVICE *pSelf = (struct DISPLAYSERVICE *)ppInterface;
-    if (pSelf->magic != DISPLAYSERVICE_MAGIC)
+static struct DISPLAYSTATE *getStateFromInterface(struct VBCLSERVICE **ppInterface)
+{
+    struct DISPLAYSTATE *pSelf = (struct DISPLAYSTATE *)ppInterface;
+    if (pSelf->magic != DISPLAYSTATE_MAGIC)
         VBClFatalError(("Bad display service object!\n"));
     return pSelf;
@@ -317,10 +345,10 @@
 static int init(struct VBCLSERVICE **ppInterface)
 {
-    struct DISPLAYSERVICE *pSelf = getClassFromInterface(ppInterface);
+    struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);
     int rc;
 
     if (pSelf->mfInit)
         return VERR_WRONG_ORDER;
-    rc = initX11(&pSelf->mState);
+    rc = initDisplay(pSelf);
     if (RT_FAILURE(rc))
         return rc;
@@ -333,5 +361,5 @@
 static int run(struct VBCLSERVICE **ppInterface, bool fDaemonised)
 {
-    struct DISPLAYSERVICE *pSelf = getClassFromInterface(ppInterface);
+    struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);
     int rc;
 
@@ -341,5 +369,5 @@
     if (RT_FAILURE(rc))
         VBClFatalError(("Failed to start the VT monitor thread: %Rrc\n", rc));
-    runDisplay(&pSelf->mState);
+    runDisplay(pSelf);
     return VERR_INTERNAL_ERROR;  /* "Should never reach here." */
 }
@@ -347,5 +375,5 @@
 static int pause(struct VBCLSERVICE **ppInterface)
 {
-    struct DISPLAYSERVICE *pSelf = getClassFromInterface(ppInterface);
+    struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);
 
     if (!pSelf->mfInit)
@@ -356,5 +384,5 @@
 static int resume(struct VBCLSERVICE **ppInterface)
 {
-    struct DISPLAYSERVICE *pSelf = getClassFromInterface(ppInterface);
+    struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);
 
     if (!pSelf->mfInit)
@@ -381,11 +409,10 @@
 struct VBCLSERVICE **VBClGetDisplayService()
 {
-    struct DISPLAYSERVICE *pService =
-        (struct DISPLAYSERVICE *)RTMemAlloc(sizeof(*pService));
+    struct DISPLAYSTATE *pService = (struct DISPLAYSTATE *)RTMemAlloc(sizeof(*pService));
 
     if (!pService)
         VBClFatalError(("Out of memory\n"));
     pService->pInterface = &vbclDisplayInterface;
-    pService->magic = DISPLAYSERVICE_MAGIC;
+    pService->magic = DISPLAYSTATE_MAGIC;
     pService->mfInit = false;
     return &pService->pInterface;
Index: /trunk/src/VBox/Additions/x11/vboxvideo/getmode.c
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/getmode.c	(revision 53965)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/getmode.c	(revision 53966)
@@ -17,4 +17,5 @@
 
 #include "vboxvideo.h"
+#include <VBox/VMMDev.h>
 
 #define NEED_XF86_TYPES
@@ -249,19 +250,48 @@
 }
 
-# define SIZE_HINTS_PROPERTY "VBOX_SIZE_HINTS"
+static void updateUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities)
+{
+    bool fGuestCanReportAbsolutePosition = false;
+    bool fHostWishesToReportAbsolutePosition = false;
+
+    if (   (fCursorCapabilities & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
+            /* As of this version (server 1.6) all major Linux releases
+             * are known to handle USB tablets correctly. */
+        || (fCursorCapabilities & VMMDEV_MOUSE_HOST_HAS_ABS_DEV)
+#endif
+        )
+        fGuestCanReportAbsolutePosition = true;
+    if (   !(fCursorCapabilities & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER)
+        && (fCursorCapabilities & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
+        fHostWishesToReportAbsolutePosition = true;
+    pVBox->fUseHardwareCursor = fGuestCanReportAbsolutePosition && fHostWishesToReportAbsolutePosition;
+}
+
+# define SIZE_HINTS_PROPERTY         "VBOX_SIZE_HINTS"
+# define MOUSE_CAPABILITIES_PROPERTY "VBOX_MOUSE_CAPABILITIES"
 
 /** Read in information about the most recent size hints requested for the
  * guest screens.  A client application sets the hint information as a root
  * window property. */
+/* TESTING: dynamic resizing and absolute pointer toggling work on old guest X servers and recent ones on Linux at the log-in screen. */
+/** @note we try to maximise code coverage by typically using all code paths (HGSMI and properties) in a single X session. */
 void VBoxUpdateSizeHints(ScrnInfoPtr pScrn)
 {
     VBOXPtr pVBox = VBOXGetRec(pScrn);
-    size_t cModes;
-    int32_t *paModes;
+    size_t cModesFromProperty, cDummy;
+    int32_t *paModeHints, *pfCursorCapabilities;
     unsigned i;
-
+    uint32_t fCursorCapabilities;
+    bool fOldUseHardwareCursor = pVBox->fUseHardwareCursor;
+
+    if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cModesFromProperty, &paModeHints) != VINF_SUCCESS)
+        paModeHints = NULL;
+    if (   vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) != VINF_SUCCESS
+        || cDummy != 1)
+        pfCursorCapabilities = NULL;
 #ifdef VBOXVIDEO_13
-    if (RT_SUCCESS(VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens,
-                                         pVBox->paVBVAModeHints)))
+    if (!pVBox->fHaveReadHGSMIModeHintData && RT_SUCCESS(VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens,
+                                                         pVBox->paVBVAModeHints)))
     {
         for (i = 0; i < pVBox->cScreens; ++i)
@@ -269,27 +299,47 @@
             if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC)
             {
-                pVBox->pScreens[i].aPreferredSize.cx =
-                    pVBox->paVBVAModeHints[i].cx;
-                pVBox->pScreens[i].aPreferredSize.cy =
-                    pVBox->paVBVAModeHints[i].cy;
-                pVBox->pScreens[i].afConnected =
-                    pVBox->paVBVAModeHints[i].fEnabled;
+                pVBox->pScreens[i].aPreferredSize.cx = pVBox->paVBVAModeHints[i].cx;
+                pVBox->pScreens[i].aPreferredSize.cy = pVBox->paVBVAModeHints[i].cy;
+                pVBox->pScreens[i].afConnected = pVBox->paVBVAModeHints[i].fEnabled;
+                /* Do not re-read this if we have data from HGSMI. */
+                if (paModeHints != NULL && i < cModesFromProperty)
+                    pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i];
             }
         }
-        return;
-    }
+    }
+    if (!pVBox->fHaveReadHGSMIModeHintData)
+    {
+        if (RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities)))
+            updateUseHardwareCursor(pVBox, fCursorCapabilities);
+        else
+            pVBox->fUseHardwareCursor = false;
+        /* Do not re-read this if we have data from HGSMI. */
+        if (pfCursorCapabilities != NULL)
+            pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities;
+    }
+    pVBox->fHaveReadHGSMIModeHintData = true;
 #endif
-    if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cModes, &paModes) != VINF_SUCCESS)
-        return;
-    for (i = 0; i < cModes && i < pVBox->cScreens; ++i)
-    {
-        if (paModes[i] != 0)
+    if (paModeHints != NULL)
+        for (i = 0; i < cModesFromProperty && i < pVBox->cScreens; ++i)
         {
-            pVBox->pScreens[i].aPreferredSize.cx =
-                paModes[i] >> 16;
-            pVBox->pScreens[i].aPreferredSize.cy =
-                paModes[i] & 0x8fff;
+            if (paModeHints[i] != 0 && paModeHints[i] != pVBox->pScreens[i].lastModeHintFromProperty)
+            {
+                if (paModeHints[i] == -1)
+                    pVBox->pScreens[i].afConnected = false;
+                else
+                {
+                    pVBox->pScreens[i].aPreferredSize.cx = paModeHints[i] >> 16;
+                    pVBox->pScreens[i].aPreferredSize.cy = paModeHints[i] & 0x8fff;
+                    pVBox->pScreens[i].afConnected = true;
+                }
+                pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i];
+            }
         }
-    }
+    if (pfCursorCapabilities != NULL && *pfCursorCapabilities != pVBox->fLastCursorCapabilitiesFromProperty)
+    {
+        updateUseHardwareCursor(pVBox, (uint32_t)*pfCursorCapabilities);
+        pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities;
+    }
+    pVBox->fForceModeSet = (pVBox->fUseHardwareCursor != fOldUseHardwareCursor);
 }
 
@@ -302,4 +352,5 @@
 static int (*g_pfnVBoxRandRSwappedProc)(ClientPtr) = NULL;
 
+/* TESTING: dynamic resizing and toggling cursor integration work with older guest X servers (1.2 and older). */
 static void vboxRandRDispatchCore(ClientPtr pClient)
 {
@@ -318,10 +369,22 @@
     pScrn = xf86Screens[pWin->drawable.pScreen->myNum];
     pVBox = VBOXGetRec(pScrn);
+    TRACE_LOG("pVBox->fForceModeSet=%u, pVBox->fUseHardwareCursor=%u\n", (unsigned)pVBox->fForceModeSet,
+              pVBox->fUseHardwareCursor);
     VBoxUpdateSizeHints(pScrn);
     pMode = pScrn->modes;
     if (pScrn->currentMode == pMode)
-        pMode = pMode->next;
+    {
+        if (pVBox->fForceModeSet)  /* Swap modes so that the new mode is before the current one. */
+        {
+            pScrn->currentMode = pMode->next;
+            pMode->next->HDisplay = pMode->HDisplay;
+            pMode->next->VDisplay = pMode->VDisplay;
+        }
+        else
+            pMode = pMode->next;
+    }
     pMode->HDisplay = pVBox->pScreens[0].aPreferredSize.cx;
     pMode->VDisplay = pVBox->pScreens[0].aPreferredSize.cy;
+    pVBox->fForceModeSet = false;
 }
 
@@ -413,19 +476,25 @@
 #ifdef VBOXVIDEO_13
 # ifdef RT_OS_LINUX
+/* TESTING: dynamic resizing works on recent Linux guest X servers at the log-in screen. */
+/** @note to maximise code coverage we only read data from HGSMI once, and only when responding to an ACPI event. */
 static void acpiEventHandler(int fd, void *pvData)
 {
+    ScreenPtr pScreen = (ScreenPtr)pvData;
+    VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
     struct input_event event;
     ssize_t rc;
 
-    RRGetInfo((ScreenPtr)pvData
+    pVBox->fHaveReadHGSMIModeHintData = false;
+    RRGetInfo(pScreen
 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
               , TRUE
 # endif
              );
+    VBVXASSERT(pVBox->fHaveReadHGSMIModeHintData == true, ("fHaveReadHGSMIModeHintData not set.\n"));
     do
         rc = read(fd, &event, sizeof(event));
     while (rc > 0 || (rc == -1 && errno == EINTR));
-    if (rc == -1 && errno != EAGAIN)  /* Why not just return 0? */
-        FatalError("Reading ACPI input event failed.\n");
+    /* Why do they return EAGAIN instead of zero bytes read like everyone else does? */
+    VBVXASSERT(rc != -1 || errno == EAGAIN, ("Reading ACPI input event failed.\n"));
 }
 
Index: /trunk/src/VBox/Additions/x11/vboxvideo/pointer.c
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/pointer.c	(revision 53965)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/pointer.c	(revision 53966)
@@ -15,5 +15,4 @@
  */
 
-#include <VBox/VMMDev.h>
 #include <VBox/VBoxGuestLib.h>
 
@@ -112,53 +111,4 @@
 
 /**************************************************************************
-* Helper functions and macros                                             *
-**************************************************************************/
-
-/* This is called by the X server every time it loads a new cursor to see
- * whether our "cursor hardware" can handle the cursor.  This provides us with
- * a mechanism (the only one!) to switch back from a software to a hardware
- * cursor. */
-static Bool
-vbox_host_uses_hwcursor(ScrnInfoPtr pScrn)
-{
-    Bool rc = TRUE;
-    uint32_t fFeatures = 0;
-    VBOXPtr pVBox = pScrn->driverPrivate;
-
-    /* We may want to force the use of a software cursor.  Currently this is
-     * needed if the guest uses a large virtual resolution, as in this case
-     * the host and guest tend to disagree about the pointer location. */
-    if (pVBox->forceSWCursor)
-        rc = FALSE;
-    /* Query information about mouse integration from the host. */
-    if (rc) {
-        int vrc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
-        if (RT_FAILURE(vrc))
-            rc = FALSE;
-    }
-    /* If we got the information from the host then make sure the host wants
-     * to draw the pointer. */
-    if (rc)
-    {
-        if (   (fFeatures & VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE)
-#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
-                /* As of this version (server 1.6) all major Linux releases
-                 * are known to handle USB tablets correctly. */
-            || (fFeatures & VMMDEV_MOUSE_HOST_HAS_ABS_DEV)
-#endif
-            )
-            /* Assume this will never be unloaded as long as the X session is
-             * running. */
-            pVBox->guestCanAbsolute = TRUE;
-        if (   (fFeatures & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER)
-            || !pVBox->guestCanAbsolute
-            || !(fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE)
-           )
-            rc = FALSE;
-    }
-    return rc;
-}
-
-/**************************************************************************
 * Main functions                                                          *
 **************************************************************************/
@@ -174,24 +124,4 @@
 }
 
-Bool
-vbox_init(int scrnIndex, VBOXPtr pVBox)
-{
-    Bool rc = TRUE;
-    int vrc;
-    uint32_t fMouseFeatures = 0;
-
-    TRACE_ENTRY();
-    vrc = VbglR3Init();
-    if (RT_FAILURE(vrc))
-    {
-        xf86DrvMsg(scrnIndex, X_ERROR,
-                   "Failed to initialize the VirtualBox device (rc=%d) - make sure that the VirtualBox guest additions are properly installed.  If you are not sure, try reinstalling them.  The X Window graphics drivers will run in compatibility mode.\n",
-                   vrc);
-        rc = FALSE;
-    }
-    pVBox->useDevice = rc;
-    return rc;
-}
-
 static void
 vbox_vmm_hide_cursor(ScrnInfoPtr pScrn, VBOXPtr pVBox)
@@ -200,12 +130,5 @@
 
     rc = VBoxHGSMIUpdatePointerShape(&pVBox->guestCtx, 0, 0, 0, 0, 0, NULL, 0);
-    if (RT_FAILURE(rc))
-    {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not hide the virtual mouse pointer, VBox error %d.\n", rc);
-        /* Play safe, and disable the hardware cursor until the next mode
-         * switch, since obviously something happened that we didn't
-         * anticipate. */
-        pVBox->forceSWCursor = TRUE;
-    }
+    VBVXASSERT(rc == VINF_SUCCESS, ("Could not hide the virtual mouse pointer, VBox error %d.\n", rc));
 }
 
@@ -215,15 +138,9 @@
     int rc;
 
-    if (!vbox_host_uses_hwcursor(pScrn))
+    if (!pVBox->fUseHardwareCursor)
         return;
     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");
-        /* Play safe, and disable the hardware cursor until the next mode
-         * switch, since obviously something happened that we didn't
-         * anticipate. */
-        pVBox->forceSWCursor = TRUE;
-    }
+    VBVXASSERT(rc == VINF_SUCCESS, ("Could not unhide the virtual mouse pointer.\n"));
 }
 
@@ -243,11 +160,5 @@
              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");
-        /* Play safe, and disable the hardware cursor until the next mode
-         * switch, since obviously something happened that we didn't
-         * anticipate. */
-        pVBox->forceSWCursor = TRUE;
-    }
+    VBVXASSERT(rc == VINF_SUCCESS, ("Unable to set the virtual mouse pointer image.\n"));
 }
 
@@ -265,9 +176,8 @@
 vbox_set_cursor_position(ScrnInfoPtr pScrn, int x, int y)
 {
-    /* Nothing to do here, as we are telling the guest where the mouse is,
-     * not vice versa. */
-    NOREF(pScrn);
-    NOREF(x);
-    NOREF(y);
+    VBOXPtr pVBox = pScrn->driverPrivate;
+
+    /* This currently does nothing. */
+    VBoxHGSMICursorPosition(&pVBox->guestCtx, true, x, y, NULL, NULL);
 }
 
@@ -300,5 +210,6 @@
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    return vbox_host_uses_hwcursor(pScrn);
+    VBOXPtr pVBox = pScrn->driverPrivate;
+    return pVBox->fUseHardwareCursor;
 }
 
@@ -433,16 +344,13 @@
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-    Bool rc = TRUE;
-
-    if (!vbox_host_uses_hwcursor(pScrn))
-        rc = FALSE;
-    if (   rc
-        && (   (pCurs->bits->height > VBOX_MAX_CURSOR_HEIGHT)
-            || (pCurs->bits->width > VBOX_MAX_CURSOR_WIDTH)
-            || (pScrn->bitsPerPixel <= 8)
-           )
-       )
-        rc = FALSE;
-    return rc;
+    VBOXPtr pVBox = pScrn->driverPrivate;
+
+    if (!pVBox->fUseHardwareCursor)
+        return FALSE;
+    if (   (pCurs->bits->height > VBOX_MAX_CURSOR_HEIGHT)
+        || (pCurs->bits->width > VBOX_MAX_CURSOR_WIDTH)
+        || (pScrn->bitsPerPixel <= 8))
+        return FALSE;
+    return TRUE;
 }
 
@@ -565,8 +473,4 @@
 #endif
 
-        /* Hide the host cursor before we initialise if we wish to use a
-         * software cursor. */
-        if (pVBox->forceSWCursor)
-            vbox_vmm_hide_cursor(pScrn, pVBox);
         rc = xf86InitCursor(pScreen, pCurs);
     }
Index: /trunk/src/VBox/Additions/x11/vboxvideo/setmode.c
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/setmode.c	(revision 53965)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/setmode.c	(revision 53966)
@@ -102,4 +102,5 @@
     bool fEnabled;
     uint16_t fFlags;
+    int rc;
 
     TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n",
@@ -132,4 +133,11 @@
                                 offStart, pVBox->cbLine, cwReal, cHeight,
                                 fEnabled ? vboxBPP(pScrn) : 0, fFlags);
+    if (cDisplay == 0)
+    {
+        rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x,
+                                         0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY);
+        if (RT_FAILURE(rc))
+            FatalError("Failed to update the input mapping.\n");
+    }
     return TRUE;
 }
@@ -145,4 +153,5 @@
     uint64_t cbLine = vboxLineLength(pScrn, width);
     int displayWidth = vboxDisplayPitch(pScrn, cbLine);
+    int rc;
 
     TRACE_LOG("width=%d, height=%d\n", width, height);
@@ -177,4 +186,5 @@
 #ifdef VBOXVIDEO_13
     /* Write the new values to the hardware */
+    /** @todo why is this only for VBOXVIDEO_13? */
     {
         unsigned i;
@@ -185,4 +195,9 @@
                             pVBox->pScreens[i].aScreenLocation.y);
     }
+#else
+    rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x,
+                                     0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY);
+    if (RT_FAILURE(rc))
+        FatalError("Failed to update the input mapping.\n");
 #endif
 #ifdef RT_OS_SOLARIS
Index: /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c	(revision 53965)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c	(revision 53966)
@@ -455,11 +455,10 @@
 }
 
-static DisplayModePtr
-vbox_output_add_mode (VBOXPtr pVBox, DisplayModePtr *pModes,
-                      const char *pszName, int x, int y,
-                      Bool isPreferred, Bool isUserDef)
+static DisplayModePtr vbox_output_add_mode(VBOXPtr pVBox, DisplayModePtr *pModes, const char *pszName, int x, int y,
+                                           Bool isPreferred, Bool fDifferentRefresh, Bool isUserDef)
 {
     TRACE_LOG("pszName=%s, x=%d, y=%d\n", pszName ? pszName : "(null)", x, y);
     DisplayModePtr pMode = xnfcalloc(1, sizeof(DisplayModeRec));
+    int cRefresh = fDifferentRefresh ? 70 : 60;
 
     pMode->status        = MODE_OK;
@@ -482,5 +481,5 @@
     pMode->VSyncEnd      = pMode->VDisplay + 4;
     pMode->VTotal        = pMode->VDisplay + 6;
-    pMode->Clock         = pMode->HTotal * pMode->VTotal * 60 / 1000; /* kHz */
+    pMode->Clock         = pMode->HTotal * pMode->VTotal * cRefresh / 1000; /* kHz */
     if (NULL == pszName) {
         xf86SetModeDefaultName(pMode);
@@ -504,8 +503,6 @@
     iScreen = (uintptr_t)output->driver_private;
     VBoxUpdateSizeHints(pScrn);
-    pMode = vbox_output_add_mode(pVBox, &pModes, NULL,
-                                 pVBox->pScreens[iScreen].aPreferredSize.cx,
-                                 pVBox->pScreens[iScreen].aPreferredSize.cy, TRUE,
-                                 FALSE);
+    pMode = vbox_output_add_mode(pVBox, &pModes, NULL, pVBox->pScreens[iScreen].aPreferredSize.cx,
+                                 pVBox->pScreens[iScreen].aPreferredSize.cy, TRUE, pVBox->fUseHardwareCursor, FALSE);
     VBOXEDIDSet(output, pMode);
     /* Add standard modes supported by the host */
@@ -515,5 +512,5 @@
         if (cIndex == 0)
             break;
-        vbox_output_add_mode(pVBox, &pModes, NULL, x, y, FALSE, FALSE);
+        vbox_output_add_mode(pVBox, &pModes, NULL, x, y, FALSE, FALSE, FALSE);
     }
 
@@ -523,6 +520,5 @@
     {
         if (2 == sscanf(pScrn->display->modes[i], "%ux%u", &x, &y))
-            vbox_output_add_mode(pVBox, &pModes, pScrn->display->modes[i], x, y,
-                                 FALSE, TRUE);
+            vbox_output_add_mode(pVBox, &pModes, pScrn->display->modes[i], x, y, FALSE, FALSE, TRUE);
     }
     TRACE_EXIT();
@@ -798,7 +794,4 @@
         return FALSE;
 
-    /* Initialise the guest library */
-    vbox_init(pScrn->scrnIndex, pVBox);
-
     /* Entity information seems to mean bus information. */
     pVBox->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
Index: /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h	(revision 53965)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h	(revision 53966)
@@ -165,4 +165,6 @@
     /** Has this screen been enabled by the host? */
     Bool afConnected;
+    /** The last mode hint data read from the X11 property. */
+    int32_t lastModeHintFromProperty;
 };
 
@@ -194,8 +196,10 @@
     /** @todo we never actually free this */
     xf86CursorInfoPtr pCurs;
-    Bool useDevice;
-    Bool forceSWCursor;
-    /** Do we know that the guest can handle absolute co-ordinates? */
-    Bool guestCanAbsolute;
+    /** Do we currently want to use the host cursor? */
+    Bool fUseHardwareCursor;
+    /** Do we want to force a reset of the current mode because the host cursor support changed?  Only used by old servers. */
+    Bool fForceModeSet;
+    /** The last cursor capabilities data read from the X11 property. */
+    int32_t fLastCursorCapabilitiesFromProperty;
     /** Number of screens attached */
     uint32_t cScreens;
@@ -212,4 +216,6 @@
     /** Input handler handle for ACPI hot-plug listener. */
     void *hACPIEventHandler;
+    /** Have we read all available HGSMI mode hint data? */
+    bool fHaveReadHGSMIModeHintData;
 # endif
 #else
@@ -242,9 +248,7 @@
 
 /* setmode.c */
-extern Bool vbox_init(int scrnIndex, VBOXPtr pVBox);
 extern Bool vbox_cursor_init (ScreenPtr pScreen);
 extern void vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox);
 extern void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBox);
-extern Bool vbox_device_available(VBOXPtr pVBox);
 
 extern Bool vboxEnableVbva(ScrnInfoPtr pScrn);
