Index: trunk/src/VBox/Additions/x11/vboxvideo/getmode.c
===================================================================
--- trunk/src/VBox/Additions/x11/vboxvideo/getmode.c	(revision 55224)
+++ trunk/src/VBox/Additions/x11/vboxvideo/getmode.c	(revision 55225)
@@ -266,4 +266,135 @@
 }
 
+static bool useHardwareCursor(uint32_t fCursorCapabilities)
+{
+    if (   !(fCursorCapabilities & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER)
+        && (fCursorCapabilities & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
+        return true;
+    return false;
+}
+
+static void compareAndMaybeSetUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities, bool *pfChanged, bool fSet)
+{
+    if (pVBox->fUseHardwareCursor != useHardwareCursor(fCursorCapabilities))
+        *pfChanged = true;
+    if (fSet)
+        pVBox->fUseHardwareCursor = useHardwareCursor(fCursorCapabilities);
+}
+
+#define SIZE_HINTS_PROPERTY          "VBOX_SIZE_HINTS"
+#define SIZE_HINTS_MISMATCH_PROPERTY "VBOX_SIZE_HINTS_MISMATCH"
+#define MOUSE_CAPABILITIES_PROPERTY  "VBOX_MOUSE_CAPABILITIES"
+
+#define COMPARE_AND_MAYBE_SET(pDest, src, pfChanged, fSet) \
+do { \
+    if (*(pDest) != (src)) \
+    { \
+        if (fSet) \
+            *(pDest) = (src); \
+        *(pfChanged) = true; \
+    } \
+} while(0)
+
+/** Read in information about the most recent size hints and cursor
+ * capabilities requested for the guest screens from a root window property set
+ * by an X11 client.  Information obtained via HGSMI takes priority. */
+void vbvxReadSizesAndCursorIntegrationFromProperties(ScrnInfoPtr pScrn, bool *pfNeedUpdate)
+{
+    VBOXPtr pVBox = VBOXGetRec(pScrn);
+    size_t cPropertyElements, cDummy;
+    int32_t *paModeHints,  *pfCursorCapabilities;
+    int rc;
+    unsigned i;
+    bool fChanged;
+    bool fNeedUpdate = false;
+    int32_t fSizeMismatch = false;
+
+    if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cPropertyElements, &paModeHints) != VINF_SUCCESS)
+        paModeHints = NULL;
+    if (paModeHints != NULL)
+        for (i = 0; i < cPropertyElements / 2 && i < pVBox->cScreens; ++i)
+        {
+            VBVAMODEHINT *pVBVAModeHint = &pVBox->paVBVAModeHints[i];
+            int32_t iSizeHint = paModeHints[i * 2];
+            int32_t iLocation = paModeHints[i * 2 + 1];
+            bool fNoHGSMI = !pVBox->fHaveHGSMIModeHints || pVBVAModeHint->magic != VBVAMODEHINT_MAGIC;
+
+            fChanged = false;
+            if (iSizeHint != 0)
+            {
+                if (iSizeHint == -1)
+                    COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, false, &fChanged, fNoHGSMI);
+                else
+                {
+                    COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cx, (iSizeHint >> 16) & 0x8fff, &fChanged, fNoHGSMI);
+                    COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cy, iSizeHint & 0x8fff, &fChanged, fNoHGSMI);
+                    COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, true, &fChanged, fNoHGSMI);
+                }
+                if (iLocation == -1)
+                    COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afHaveLocation, false, &fChanged, fNoHGSMI);
+                else
+                {
+                    COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.x, (iLocation >> 16) & 0x8fff, &fChanged,
+                                          fNoHGSMI);
+                    COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.y, iLocation & 0x8fff, &fChanged, fNoHGSMI);
+                    COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afHaveLocation, true, &fChanged, fNoHGSMI);
+                }
+                if (fChanged && fNoHGSMI)
+                    fNeedUpdate = true;
+                if (fChanged && !fNoHGSMI)
+                    fSizeMismatch = true;
+            }
+        }
+    fChanged = false;
+    if (   vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) == VINF_SUCCESS
+        && cDummy == 1)
+        compareAndMaybeSetUseHardwareCursor(pVBox, *pfCursorCapabilities, &fChanged, !pVBox->fHaveHGSMIModeHints);
+    if (fChanged && !pVBox->fHaveHGSMIModeHints)
+        fNeedUpdate = true;
+    if (fChanged && pVBox->fHaveHGSMIModeHints)
+        fSizeMismatch = true;
+    vbvxSetIntegerPropery(pScrn, SIZE_HINTS_MISMATCH_PROPERTY, 1, &fSizeMismatch, false);
+    if (pfNeedUpdate != NULL && fNeedUpdate)
+        *pfNeedUpdate = true;
+}
+
+/** Read in information about the most recent size hints and cursor
+ * capabilities requested for the guest screens from HGSMI. */
+void vbvxReadSizesAndCursorIntegrationFromHGSMI(ScrnInfoPtr pScrn, bool *pfNeedUpdate)
+{
+    VBOXPtr pVBox = VBOXGetRec(pScrn);
+    int rc;
+    unsigned i;
+    bool fChanged = false;
+    uint32_t fCursorCapabilities;
+
+    if (!pVBox->fHaveHGSMIModeHints)
+        return;
+    rc = VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens, pVBox->paVBVAModeHints);
+    VBVXASSERT(rc == VINF_SUCCESS, ("VBoxHGSMIGetModeHints failed, rc=%d.\n", rc));
+    for (i = 0; i < pVBox->cScreens; ++i)
+        if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC)
+        {
+            COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cx, pVBox->paVBVAModeHints[i].cx & 0x8fff, &fChanged, true);
+            COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cy, pVBox->paVBVAModeHints[i].cy & 0x8fff, &fChanged, true);
+            COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, RT_BOOL(pVBox->paVBVAModeHints[i].fEnabled), &fChanged, true);
+            COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.x, (int32_t)pVBox->paVBVAModeHints[i].dx & 0x8fff, &fChanged,
+                                  true);
+            COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.y, (int32_t)pVBox->paVBVAModeHints[i].dy & 0x8fff, &fChanged,
+                                  true);
+            if (pVBox->paVBVAModeHints[i].dx != ~(uint32_t)0 && pVBox->paVBVAModeHints[i].dy != ~(uint32_t)0)
+                COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afHaveLocation, true, &fChanged, true);
+            else
+                COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afHaveLocation, false, &fChanged, true);
+        }
+    rc = VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities);
+    VBVXASSERT(rc == VINF_SUCCESS, ("Getting VBOX_VBVA_CONF32_CURSOR_CAPABILITIES failed, rc=%d.\n", rc));
+    compareAndMaybeSetUseHardwareCursor(pVBox, fCursorCapabilities, &fChanged, true);
+    if (pfNeedUpdate != NULL && fChanged)
+        *pfNeedUpdate = true;
+}
+
+#undef COMPARE_AND_MAYBE_SET
+
 #ifndef VBOXVIDEO_13
 
Index: trunk/src/VBox/Additions/x11/vboxvideo/helpers.c
===================================================================
--- trunk/src/VBox/Additions/x11/vboxvideo/helpers.c	(revision 55224)
+++ trunk/src/VBox/Additions/x11/vboxvideo/helpers.c	(revision 55225)
@@ -78,4 +78,14 @@
 }
 
+void vbvxSetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t cData, int32_t *paData, Bool fSendEvent)
+{
+    Atom property_name;
+    int i;
+
+    property_name = MakeAtom(pszName, strlen(pszName), TRUE);
+    VBVXASSERT(property_name != BAD_RESOURCE, ("Failed to set atom \"%s\"\n", pszName));
+    ChangeWindowProperty(ROOT_WINDOW(pScrn), property_name, XA_INTEGER, 32, PropModeReplace, cData, paData, fSendEvent);
+}
+
 void vbvxReprobeCursor(ScrnInfoPtr pScrn)
 {
Index: trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h
===================================================================
--- trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h	(revision 55224)
+++ trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h	(revision 55225)
@@ -163,8 +163,12 @@
     /** The current preferred resolution for the screen */
     RTRECTSIZE aPreferredSize;
+    /** The current preferred location for the screen. */
+    RTPOINT aPreferredLocation;
     /** Has this screen been enabled by the host? */
     Bool afConnected;
     /** The last mode hint data read from the X11 property. */
     int32_t lastModeHintFromProperty;
+    /** Does this screen have a preferred location? */
+    Bool afHaveLocation;
 };
 
@@ -206,7 +210,9 @@
     /** The last requested framebuffer size. */
     RTRECTSIZE FBSize;
-#ifdef VBOXVIDEO_13
+    /** Can we get mode hint and cursor integration information from HGSMI? */
+    bool fHaveHGSMIModeHints;
     /** Array of structures for receiving mode hints. */
     VBVAMODEHINT *paVBVAModeHints;
+#ifdef VBOXVIDEO_13
 # ifdef RT_OS_LINUX
     /** Input device file descriptor for getting ACPI hot-plug events. */
@@ -244,4 +250,5 @@
 #define VBOXGetRec vbvxGetRec  /* Temporary */
 extern int vbvxGetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t *pcData, int32_t **ppaData);
+extern void vbvxSetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t cData, int32_t *paData, Bool fSendEvent);
 extern void vbvxReprobeCursor(ScrnInfoPtr pScrn);
 
