Index: /trunk/src/VBox/Additions/x11/VBoxClient/display.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/display.cpp	(revision 55967)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/display.cpp	(revision 55968)
@@ -271,9 +271,9 @@
         if (!pState->fHaveRandR12)
             notifyXServerRandR11(pState);
-        do
-            rc = VbglR3WaitEvent(  VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST
-                                 | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED,
-                                 RT_INDEFINITE_WAIT, &fEvents);
-        while(rc == VERR_INTERRUPTED);
+        rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST | VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED, RT_INDEFINITE_WAIT,
+                             &fEvents);
+        /* Interrupted is used to re-set the mode without changing it. */
+        if (rc == VERR_INTERRUPTED)
+            rc = VINF_SUCCESS;
         if (RT_FAILURE(rc))  /* VERR_NO_MEMORY? */
             VBClFatalError(("event wait failed, rc=%Rrc\n", rc));
@@ -367,8 +367,13 @@
 {
     struct DISPLAYSTATE *pSelf = getStateFromInterface(ppInterface);
+    int rc;
 
     if (!pSelf->mfInit)
         return VERR_WRONG_ORDER;
-    return enableEventsAndCaps();
+    rc = enableEventsAndCaps();
+    /* RandR 1.1-based drivers only let us change mode when we are not switched
+     * out, so interrupt the wait when we switch in and re-set it. */
+    VbglR3InterruptEventWaits();
+    return rc;
 }
 
Index: /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
===================================================================
--- /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c	(revision 55967)
+++ /trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c	(revision 55968)
@@ -301,5 +301,5 @@
 /** Set a video mode to the hardware, RandR 1.1 version.  Since we no longer do
  * virtual frame buffers, adjust the screen pixmap dimensions to match. */
-static void setModeRandR11(ScrnInfoPtr pScrn, DisplayModePtr pMode, bool fLimitedContext)
+static void setModeRandR11(ScrnInfoPtr pScrn, DisplayModePtr pMode, bool fScreenInitTime)
 {
     VBOXPtr pVBox = VBOXGetRec(pScrn);
@@ -308,6 +308,7 @@
     pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay;
     pVBox->pScreens[0].aScreenLocation.cy = pMode->VDisplay;
-    if (fLimitedContext)
-    {
+    if (fScreenInitTime)
+    {
+        /* The screen structure is not fully set up yet, so do not touch it. */
         pScrn->displayWidth = pScrn->virtualX = pMode->HDisplay;
         pScrn->virtualY = pMode->VDisplay;
@@ -1043,5 +1044,5 @@
 #ifdef VBOXVIDEO_13
 
-static void setVirtualSizeRandR12(ScrnInfoPtr pScrn, bool fLimitedContext)
+static void setVirtualSizeRandR12(ScrnInfoPtr pScrn, bool fScreenInitTime)
 {
     VBOXPtr pVBox = VBOXGetRec(pScrn);
@@ -1070,5 +1071,5 @@
          * cause problems setting up RandR 1.2 which needs it set to the
          * maximum size at this point. */
-        if (!fLimitedContext)
+        if (!fScreenInitTime)
         {
             TRACE_LOG("cx=%u, cy=%u\n", cx, cy);
@@ -1081,5 +1082,5 @@
 }
 
-static void setScreenSizesRandR12(ScrnInfoPtr pScrn, bool fLimitedContext)
+static void setScreenSizesRandR12(ScrnInfoPtr pScrn, bool fScreenInitTime)
 {
     VBOXPtr pVBox = VBOXGetRec(pScrn);
@@ -1096,5 +1097,5 @@
         xf86CrtcSetMode(pVBox->pScreens[i].paCrtcs, pVBox->pScreens[i].paOutputs->probed_modes, RR_Rotate_0,
                         pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y);
-        if (!fLimitedContext)
+        if (!fScreenInitTime)
             RRCrtcNotify(pVBox->pScreens[i].paCrtcs->randr_crtc, pVBox->pScreens[i].paOutputs->randr_output->modes[0],
                          pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y, RR_Rotate_0,
@@ -1106,9 +1107,9 @@
 }
 
-static void setSizesRandR12(ScrnInfoPtr pScrn, bool fLimitedContext)
-{
-    VBOXPtr pVBox = VBOXGetRec(pScrn);
-
-    if (!fLimitedContext)
+static void setSizesRandR12(ScrnInfoPtr pScrn, bool fScreenInitTime)
+{
+    VBOXPtr pVBox = VBOXGetRec(pScrn);
+
+    if (!fScreenInitTime)
     {
 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
@@ -1118,7 +1119,7 @@
 # endif
     }
-    setVirtualSizeRandR12(pScrn, fLimitedContext);
-    setScreenSizesRandR12(pScrn, fLimitedContext);
-    if (!fLimitedContext)
+    setVirtualSizeRandR12(pScrn, fScreenInitTime);
+    setScreenSizesRandR12(pScrn, fScreenInitTime);
+    if (!fScreenInitTime)
     {
         /* We use RRScreenSizeSet() here and not RRScreenSizeNotify() because
@@ -1135,5 +1136,5 @@
 #else
 
-static void setSizesRandR11(ScrnInfoPtr pScrn, bool fLimitedContext)
+static void setSizesRandR11(ScrnInfoPtr pScrn)
 {
     VBOXPtr pVBox = VBOXGetRec(pScrn);
@@ -1143,5 +1144,4 @@
     pNewMode->HDisplay = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cx, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL);
     pNewMode->VDisplay = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cy, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL);
-    setModeRandR11(pScrn, pNewMode, fLimitedContext);
 }
 
@@ -1156,5 +1156,5 @@
     setSizesRandR12(pScrn, fScreenInitTime);
 #else
-    setSizesRandR11(pScrn, fScreenInitTime);
+    setSizesRandR11(pScrn);
 #endif
     if (pScrn->vtSema)
@@ -1327,7 +1327,10 @@
     }
 
-#endif
     /* set first video mode */
     setSizesAndCursorIntegration(pScrn, true);
+#else
+    /* set first video mode */
+    setModeRandR11(pScrn, pScrn->currentMode, true);
+#endif
 
     /* Register block and wake-up handlers for getting new screen size hints. */
@@ -1396,6 +1399,9 @@
     vboxEnableVbva(pScrn);
     /* Re-set video mode */
+#ifdef VBOXVIDEO_13
     vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL);
     vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, NULL);
+    setSizesAndCursorIntegration(pScrn, false);
+#else
     /* This prevents a crash in CentOS 3.  I was unable to debug it to
      * satisfaction, partly due to the lack of symbols.  My guess is that
@@ -1404,6 +1410,7 @@
      * point of the VT switch. */
     pScrn->vtSema = FALSE;
-    setSizesAndCursorIntegration(pScrn, false);
+    setModeRandR11(pScrn, pScrn->currentMode, false);
     pScrn->vtSema = TRUE;
+#endif
 #ifdef SET_HAVE_VT_PROPERTY
     updateHasVTProperty(pScrn, TRUE);
