Index: trunk/src/VBox/Additions/x11/xgraphics/vboxutils.c
===================================================================
--- trunk/src/VBox/Additions/x11/xgraphics/vboxutils.c	(revision 7118)
+++ trunk/src/VBox/Additions/x11/xgraphics/vboxutils.c	(revision 7168)
@@ -119,6 +119,4 @@
     xfree (pVBox->reqp);
     pVBox->reqp = NULL;
-
-    VbglR3Term();
 }
 
@@ -308,4 +306,17 @@
 
 Bool
+vbox_init(int scrnIndex)
+{
+    Bool rc = TRUE;
+    int vrc = VbglR3Init();
+    if (RT_FAILURE(vrc))
+    {
+        xf86DrvMsg(scrnIndex, X_ERROR, "VbglR3Init failed rc=%d.\n", rc);
+        rc = FALSE;
+    }
+    return rc;
+}
+
+Bool
 vbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
 {
@@ -324,11 +335,4 @@
         pVBox->useVbva = vboxInitVbva(scrnIndex, pScreen, pVBox);
         return TRUE;
-    }
-
-    rc = VbglR3Init();
-    if (RT_FAILURE(rc))
-    {
-        xf86DrvMsg(scrnIndex, X_ERROR, "VbglR3Init failed rc=%d.\n", rc);
-        return FALSE;
     }
 
@@ -352,5 +356,4 @@
     }
     xf86DrvMsg(scrnIndex, X_ERROR, "Could not allocate %lu bytes for VMM request\n", (unsigned long)size);
-    VbglR3Term();
     return FALSE;
 }
Index: trunk/src/VBox/Additions/x11/xgraphics/vboxvideo.h
===================================================================
--- trunk/src/VBox/Additions/x11/xgraphics/vboxvideo.h	(revision 7118)
+++ trunk/src/VBox/Additions/x11/xgraphics/vboxvideo.h	(revision 7168)
@@ -183,7 +183,8 @@
 #endif
 
-Bool vbox_cursor_init (ScreenPtr pScreen);
-Bool vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBOX);
-void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBOX);
+extern Bool vbox_init(int scrnIndex);
+extern Bool vbox_cursor_init (ScreenPtr pScreen);
+extern Bool vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBOX);
+extern void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBOX);
 
 extern Bool vboxEnableVbva(ScrnInfoPtr pScrn);
Index: trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_13.c
===================================================================
--- trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_13.c	(revision 7118)
+++ trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_13.c	(revision 7168)
@@ -409,7 +409,7 @@
         vbox_output_add_mode(&pModes, NULL, x, y, TRUE);
     }
-    vbox_output_add_mode(&pModes, "1024x768", 1024, 768, FALSE);
-    vbox_output_add_mode(&pModes, "800x600", 800, 600, FALSE);
-    vbox_output_add_mode(&pModes, "640x480", 640, 480, FALSE);
+    vbox_output_add_mode(&pModes, NULL, 1024, 768, FALSE);
+    vbox_output_add_mode(&pModes, NULL, 800, 600, FALSE);
+    vbox_output_add_mode(&pModes, NULL, 640, 480, FALSE);
     TRACE2;
     return pModes;
@@ -648,7 +648,11 @@
         return (FALSE);
 
-    xf86Msg(X_INFO,
-            "VirtualBox guest additions video driver version "
-            VBOX_VERSION_STRING "\n");
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+               "VirtualBox guest additions video driver version "
+               VBOX_VERSION_STRING "\n");
+
+    /* Initialise the guest library */
+    if (!vbox_init(pScrn->scrnIndex))
+        return FALSE;
 
     /* Get our private data from the ScrnInfoRec structure. */
@@ -700,15 +704,16 @@
     pScrn->videoRam = inl(VBE_DISPI_IOPORT_DATA) / 1024;
 
-    /* This function asks X to choose a depth and bpp based on the
-       config file and the command line, and gives a default in
-       case none is specified.  Note that we only support 32bpp, not
-       24bpp.  After spending ages looking through the XFree86 4.2
-       source code however, I realised that it automatically uses
-       32bpp for depth 24 unless you explicitly add a "24 24"
-       format to its internal list. */
-    if (!xf86SetDepthBpp(pScrn, pScrn->videoRam >= 2048 ? 24 : 16, 0, 0,
-                         Support32bppFb))
-        return FALSE;
-    if (pScrn->depth != 24 && pScrn->depth != 16)
+    /* Query the host for the preferred colour depth */
+    {
+        uint32_t cx, cy, iDisplay, cBits = 24;
+
+        /* 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,
@@ -734,13 +739,25 @@
     output = xf86OutputCreate(pScrn, &VBOXOutputFuncs, "Virtual Output");
 
-    /* Set a sane minimum and maximum mode size */
-    xf86CrtcSetSizeRange(pScrn, 64, 64, 64000, 64000);
-
-    /* I don't know exactly what these are for (and they are only used in a couple
-       of places in the X server code), but due to a bug in RandR 1.2 they place
-       an upper limit on possible resolutions.  To add to the fun, they get set
-       automatically if we don't do it ourselves. */
-    pScrn->display->virtualX = 64000;
-    pScrn->display->virtualY = 64000;
+    /* Set a sane minimum mode size and the maximum allowed by the available VRAM */
+    /** @todo Make sure that the host resolution is supported if it fits into VRAM. */
+    {
+        unsigned maxSize, trySize = 512;
+
+        do {
+            maxSize = trySize;
+            trySize += 128;
+        } while (trySize * trySize * pScrn->bitsPerPixel / 8 < pScrn->videoRam * 1024);
+
+        xf86CrtcSetSizeRange(pScrn, 64, 64, maxSize, maxSize);
+
+        /* I don't know exactly what these are for (and they are only used in a couple
+           of places in the X server code), but due to a bug in RandR 1.2 they place
+           an upper limit on possible resolutions.  To add to the fun, they get set
+           automatically if we don't do it ourselves. */
+        pScrn->display->virtualX = maxSize;
+        pScrn->display->virtualY = maxSize;
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                   "The maximum supported resolution is currently %dx%d\n", maxSize, maxSize);
+    }
 
     /* We are not interested in the monitor section in the configuration file. */
@@ -1047,12 +1064,12 @@
     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);
-    /* 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);
     if (pVBox->useVbva == TRUE)
         if (vboxEnableVbva(pScrn) != TRUE)  /* Bad but not fatal */
Index: trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_68.c
===================================================================
--- trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_68.c	(revision 7118)
+++ trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_68.c	(revision 7168)
@@ -371,7 +371,7 @@
         return (FALSE);
 
-    xf86Msg(X_INFO,
-            "VirtualBox guest additions video driver version "
-            VBOX_VERSION_STRING "\n");
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+               "VirtualBox guest additions video driver version "
+               VBOX_VERSION_STRING "\n");
 
     /* Get our private data from the ScrnInfoRec structure. */
@@ -453,5 +453,5 @@
                          Support32bppFb))
         return FALSE;
-    if (pScrn->depth != 24 && pScrn->depth != 16)
+    if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16)
     {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -497,9 +497,4 @@
     }
 
-    /* Determine the virtual screen resolution from the first mode (which will be selected) */
-    sscanf(pScrn->display->modes[0], "%dx%d",
-           &pScrn->display->virtualX, &pScrn->display->virtualY);
-    pScrn->display->virtualX = (pScrn->display->virtualX + 7) & ~7;
-
     /* Create a builtin mode for every specified mode. This allows to specify arbitrary
      * screen resolutions */
@@ -511,11 +506,4 @@
 
         sscanf(pScrn->display->modes[i], "%dx%d", &x, &y);
-        /* sanity check, smaller resolutions does not make sense */
-        if (x < 64 || y < 64)
-        {
-            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring mode \"%s\"\n",
-                       pScrn->display->modes[i]);
-            continue;
-        }
         m                = xnfcalloc(sizeof(DisplayModeRec), 1);
         m->status        = MODE_OK;
@@ -533,13 +521,28 @@
     }
 
+    /* Set a sane minimum mode size and the maximum allowed by the available VRAM */
+    {
+        unsigned maxSize, trySize = 512;
+
+        do {
+            maxSize = trySize;
+            trySize += 128;
+        } while (trySize * trySize * pScrn->bitsPerPixel / 8 < pScrn->videoRam * 1024);
+
+        /* I don't know exactly what these are for (and they are only used in a couple
+           of places in the X server code). */
+        pScrn->display->virtualX = maxSize;
+        pScrn->display->virtualY = maxSize;
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                   "The maximum supported resolution is currently %dx%d\n", maxSize, maxSize);
+    }
+
     /* Filter out video modes not supported by the virtual hardware
-       we described.  All modes used by the Windows additions should
-       work fine. */
+       we described. */
     i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
                           pScrn->display->modes,
-                          clockRanges, NULL, 0, 6400, 1, 0, 1440,
-                          pScrn->display->virtualX,
-                          pScrn->display->virtualY,
-                          pScrn->videoRam, LOOKUP_BEST_REFRESH);
+                          clockRanges, NULL, 64, pScrn->display->virtualX, 1,
+                          64, pScrn->display->virtualY, 0, 0,
+                          pScrn->videoRam * 1024, LOOKUP_BEST_REFRESH);
 
     if (i <= 0) {
@@ -554,6 +557,6 @@
     xf86PrintModes(pScrn);
 
-    /* Set display resolution.  This was arbitrarily chosen to be about the same as my monitor. */
-    xf86SetDpi(pScrn, 100, 100);
+    /* Set display resolution.  Perhaps we should read this from the host. */
+    xf86SetDpi(pScrn, 96, 96);
 
     if (pScrn->modes == NULL) {
Index: trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_70.c
===================================================================
--- trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_70.c	(revision 7118)
+++ trunk/src/VBox/Additions/x11/xgraphics/vboxvideo_70.c	(revision 7168)
@@ -381,4 +381,5 @@
     int i;
     DisplayModePtr m_prev;
+    char *pcHostModeName = NULL;
 
     /* Are we really starting the server, or is this just a dummy run? */
@@ -386,9 +387,13 @@
         return (FALSE);
 
-    xf86Msg(X_INFO,
-            "VirtualBox guest additions video driver version "
-            VBOX_VERSION_STRING "\n");
-
-    /* Get our private data from the ScrnInfoRec structure. */
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+               "VirtualBox guest additions video driver version "
+               VBOX_VERSION_STRING "\n");
+
+    /* Initialise the guest library */
+    if (!vbox_init(pScrn->scrnIndex))
+        return FALSE;
+
+     /* Get our private data from the ScrnInfoRec structure. */
     pVBox = VBOXGetRec(pScrn);
 
@@ -458,15 +463,19 @@
     clockRanges->ClockDivFactor = 1;
 
-    /* This function asks X to choose a depth and bpp based on the
-       config file and the command line, and gives a default in
-       case none is specified.  Note that we only support 32bpp, not
-       24bpp.  After spending ages looking through the XFree86 4.2
-       source code however, I realised that it automatically uses
-       32bpp for depth 24 unless you explicitly add a "24 24"
-       format to its internal list. */
-    if (!xf86SetDepthBpp(pScrn, pScrn->videoRam >= 2048 ? 24 : 16, 0, 0,
-                         Support32bppFb))
-        return FALSE;
-    if (pScrn->depth != 24 && pScrn->depth != 16)
+    /* Query the host for the preferred resolution and colour depth */
+    {
+        uint32_t cx, cy, iDisplay, cBits = 24;
+
+        if (vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits, &iDisplay))
+        {
+            /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
+            if (cBits != 16)
+                cBits = 24;
+            pcHostModeName = XNFprintf("%dx%d", cx, cy);
+        }
+        if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb))
+            return FALSE;
+    }
+    if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16)
     {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -476,44 +485,30 @@
     xf86PrintDepthBpp(pScrn);
 
-    /* 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);
-
     /* To get around the problem of SUSE specifying a single, invalid mode in their
-     * Xorg.conf by default, we add an additional mode to the end of the user specified
+     * Xorg.conf by default, we add additional modes to the end of the user specified
      * list. This means that if all user modes are invalid, X will try our mode before
      * falling back to its standard mode list. */
     if (pScrn->display->modes == NULL)
     {
-        /* The user specified no modes at all - specify 1024x768 as a default. */
-        pScrn->display->modes    = xnfalloc(4 * sizeof(char*));
-        pScrn->display->modes[0] = "1024x768";
-        pScrn->display->modes[1] = "800x600";
-        pScrn->display->modes[2] = "640x480";
-        pScrn->display->modes[3] = NULL;
+        i = 0;
+        /* The user specified no modes at all. */
+        pScrn->display->modes = xnfalloc(5 * sizeof(char*));
     }
     else
     {
-        /* Add 1024x768 to the end of the mode list in case the others are all invalid. */
         for (i = 0; pScrn->display->modes[i] != NULL; i++);
-        pScrn->display->modes      = xnfrealloc(pScrn->display->modes, (i + 4)
-                                   * sizeof(char *));
-        pScrn->display->modes[i  ] = "1024x768";
-        pScrn->display->modes[i+1] = "800x600";
-        pScrn->display->modes[i+2] = "640x480";
-        pScrn->display->modes[i+3] = NULL;
-    }
-
-    /* Determine the virtual screen resolution from the first mode (which will be selected) */
-    sscanf(pScrn->display->modes[0], "%dx%d",
-           &pScrn->display->virtualX, &pScrn->display->virtualY);
-    pScrn->display->virtualX = (pScrn->display->virtualX + 7) & ~7;
+        pScrn->display->modes =   xnfrealloc(pScrn->display->modes, (i + 5)
+                                * sizeof(char *));
+    }
+    /* Add additional modes to the end of the mode list in case the others are
+       all invalid. */
+    if (pcHostModeName != NULL)
+        pScrn->display->modes[i] = pcHostModeName;
+    else
+        --i;
+    pScrn->display->modes[i+1] = "1024x768";
+    pScrn->display->modes[i+2] = "800x600";
+    pScrn->display->modes[i+3] = "640x480";
+    pScrn->display->modes[i+4] = NULL;
 
     /* Create a builtin mode for every specified mode. This allows to specify arbitrary
@@ -526,11 +521,4 @@
 
         sscanf(pScrn->display->modes[i], "%dx%d", &x, &y);
-        /* sanity check, smaller resolutions does not make sense */
-        if (x < 64 || y < 64)
-        {
-            xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Ignoring mode \"%s\"\n",
-                       pScrn->display->modes[i]);
-            continue;
-        }
         m                = xnfcalloc(sizeof(DisplayModeRec), 1);
         m->status        = MODE_OK;
@@ -555,13 +543,39 @@
     }
 
+    /* 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 sane minimum mode size and the maximum allowed by the available VRAM */
+    {
+        unsigned maxSize, trySize = 512;
+
+        do {
+            maxSize = trySize;
+            trySize += 128;
+        } while (trySize * trySize * pScrn->bitsPerPixel / 8 < pScrn->videoRam * 1024);
+
+        /* I don't know exactly what these are for (and they are only used in a couple
+           of places in the X server code). */
+        pScrn->display->virtualX = maxSize;
+        pScrn->display->virtualY = maxSize;
+        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+                   "The maximum supported resolution is currently %dx%d\n", maxSize, maxSize);
+    }
+
     /* Filter out video modes not supported by the virtual hardware
-       we described.  All modes used by the Windows additions should
-       work fine. */
+       we described. */
     i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
                           pScrn->display->modes,
-                          clockRanges, NULL, 0, 6400, 1, 0, 1440,
-                          pScrn->display->virtualX,
-                          pScrn->display->virtualY,
-                          pScrn->videoRam, LOOKUP_BEST_REFRESH);
+                          clockRanges, NULL, 64, pScrn->display->virtualX, 1,
+                          64, pScrn->display->virtualY, 0, 0,
+                          pScrn->videoRam * 1024, LOOKUP_BEST_REFRESH);
 
     if (i <= 0) {
@@ -576,6 +590,6 @@
     xf86PrintModes(pScrn);
 
-    /* Set display resolution.  This was arbitrarily chosen to be about the same as my monitor. */
-    xf86SetDpi(pScrn, 100, 100);
+    /* Set display resolution.  Perhaps we should read this from the host. */
+    xf86SetDpi(pScrn, 96, 96);
 
     if (pScrn->modes == NULL) {
