Index: trunk/src/VBox/Additions/WINNT/Graphics/Display/Makefile.kmk
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Display/Makefile.kmk	(revision 34677)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Display/Makefile.kmk	(revision 34686)
@@ -49,4 +49,5 @@
 	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
 	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp \
 	VBoxDisp.def \
 	VBoxDisp.rc
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/Makefile.kmk
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/Makefile.kmk	(revision 34677)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/Makefile.kmk	(revision 34686)
@@ -46,5 +46,6 @@
 	VBoxVideo.rc \
 	VBoxVideoHGSMI.cpp \
-	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
 VBoxVideo_LIBS.x86    = \
 	$(PATH_SDK_W2K3DDK_LIB)/exsup.lib
@@ -101,4 +102,5 @@
  	VBoxVideoHGSMI.cpp \
 	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp \
  	VBoxVideo.cpp \
     Helper.cpp \
Index: trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp
===================================================================
--- trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 34677)
+++ trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 34686)
@@ -4159,14 +4159,4 @@
         )
 {
-    /* set the mode characteristics */
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, width);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, height);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, bpp);
-    /* enable the mode */
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
 #ifdef VBOX_WITH_WDDM
     /* encode linear offDisplay to xOffset & yOffset to ensure offset fits USHORT */
@@ -4185,17 +4175,10 @@
     Assert(xOffset <= 0xffff);
     Assert(yOffset <= 0xffff);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_X_OFFSET);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, (USHORT)xOffset);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_Y_OFFSET);
-    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, (USHORT)yOffset);
-#endif
+#else
+    ULONG xOffset = 0, yOffset = 0;
+#endif
+    VBoxVideoSetModeRegisters(width, height, width, bpp, (uint16_t)xOffset,
+                              (uint16_t)yOffset);
     /** @todo read from the port to see if the mode switch was successful */
-
-    /* Tell the host that we now support graphics in the additions.
-     * @todo: Keep old behaviour, because VBoxVideoResetDevice is called on every graphics
-     *        mode switch and causes an OFF/ON sequence which is not handled by frontends
-     *        (for example Qt GUI debug build asserts when seamless is being enabled).
-     */
-    // VBoxVideoSetGraphicsCap(TRUE);
 
     return TRUE;
Index: trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp	(revision 34677)
+++ trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp	(revision 34686)
@@ -173,38 +173,4 @@
 
     return VERR_INVALID_PARAMETER;
-}
-
-
-/** Query the host for an HGSMI configuration parameter via an HGSMI command.
- */
-static int vboxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t u32Index,
-                              uint32_t *pulValue)
-{
-    int rc = VINF_SUCCESS;
-    VBVACONF32 *p;
-    LogFunc(("u32Index = %d\n", u32Index));
-
-    /* Allocate the IO buffer. */
-    p = (VBVACONF32 *)HGSMIHeapAlloc(&pCtx->heapCtx,
-                                     sizeof(VBVACONF32), HGSMI_CH_VBVA,
-                                     VBVA_QUERY_CONF32);
-    if (p)
-    {
-        /* Prepare data to be sent to the host. */
-        p->u32Index = u32Index;
-        p->u32Value = 0;
-        rc = VBoxHGSMIBufferSubmit(pCtx, p);
-        if (RT_SUCCESS(rc))
-        {
-            *pulValue = p->u32Value;
-            LogFunc(("u32Value = %d\n", p->u32Value));
-        }
-        /* Free the IO buffer. */
-        HGSMIHeapFree(&pCtx->heapCtx, p);
-    }
-    else
-        rc = VERR_NO_MEMORY;
-    LogFunc(("rc = %d\n", rc));
-    return rc;
 }
 
@@ -291,41 +257,4 @@
         /* Free the IO buffer. */
         HGSMIHeapFree(&pCtx->heapCtx, p);
-    }
-    else
-        rc = VERR_NO_MEMORY;
-    return rc;
-}
-
-
-/**
- * Tell the host about how VRAM is divided up between each screen via an HGSMI
- * command.  It is acceptable to specifiy identical data for each screen if
- * they share a single framebuffer.
- * @todo confirm that that really is acceptable
- *
- * @returns iprt status code, either VERR_NO_MEMORY or the status returned by
- *          @a pfnFill
- * @param  pCtx      the context containing the heap to use
- * @param  u32Count  the number of screens we are activating
- * @param  pfnFill   a callback which initialises the VBVAINFOVIEW structures
- *                   for all screens
- * @param  pvData    context data for @a pfnFill
- */
-RTDECL(int) VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
-                                  uint32_t u32Count,
-                                  PFNHGSMIFILLVIEWINFO pfnFill,
-                                  void *pvData)
-{
-    int rc;
-    /* Issue the screen info command. */
-    void *p = VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAINFOVIEW) * u32Count,
-                                   HGSMI_CH_VBVA, VBVA_INFO_VIEW);
-    if (p)
-    {
-        VBVAINFOVIEW *pInfo = (VBVAINFOVIEW *)p;
-        rc = pfnFill(pvData, pInfo, u32Count);
-        if (RT_SUCCESS(rc))
-            VBoxHGSMIBufferSubmit (pCtx, p);
-        VBoxHGSMIBufferFree(pCtx, p);
     }
     else
@@ -422,5 +351,5 @@
     AssertPtrReturnVoid(poffVRAMHostArea);
     AssertPtrReturnVoid(pcbHostArea);
-    vboxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea);
+    VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea);
     if (cbHostArea != 0)
     {
@@ -517,20 +446,40 @@
 
 /**
- * Gets the count of virtual monitors attached to the guest via an HGSMI
- * command
- *
- * @returns the right count on success or 1 on failure.
- * @param  pCtx  the context containing the heap to use
- */
-RTDECL(uint32_t) VBoxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx)
-{
-    /* Query the configured number of displays. */
-    uint32_t cDisplays = 0;
-    vboxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_MONITOR_COUNT, &cDisplays);
-    LogFunc(("cDisplays = %d\n", cDisplays));
-    if (cDisplays == 0 || cDisplays > VBOX_VIDEO_MAX_SCREENS)
-        /* Host reported some bad value. Continue in the 1 screen mode. */
-        cDisplays = 1;
-    return cDisplays;
+ * Query the host for an HGSMI configuration parameter via an HGSMI command.
+ * @returns iprt status value
+ * @param  pCtx      the context containing the heap used
+ * @param  u32Index  the index of the parameter to query,
+ *                   @see VBVACONF32::u32Index
+ * @param  pulValue  where to store the value of the parameter on success
+ */
+RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                               uint32_t u32Index, uint32_t *pulValue)
+{
+    int rc = VINF_SUCCESS;
+    VBVACONF32 *p;
+    LogFunc(("u32Index = %d\n", u32Index));
+
+    /* Allocate the IO buffer. */
+    p = (VBVACONF32 *)HGSMIHeapAlloc(&pCtx->heapCtx,
+                                     sizeof(VBVACONF32), HGSMI_CH_VBVA,
+                                     VBVA_QUERY_CONF32);
+    if (p)
+    {
+        /* Prepare data to be sent to the host. */
+        p->u32Index = u32Index;
+        p->u32Value = 0;
+        rc = VBoxHGSMIBufferSubmit(pCtx, p);
+        if (RT_SUCCESS(rc))
+        {
+            *pulValue = p->u32Value;
+            LogFunc(("u32Value = %d\n", p->u32Value));
+        }
+        /* Free the IO buffer. */
+        HGSMIHeapFree(&pCtx->heapCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    LogFunc(("rc = %d\n", rc));
+    return rc;
 }
 
Index: trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp	(revision 34686)
+++ trunk/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp	(revision 34686)
@@ -0,0 +1,170 @@
+/* $Id$ */
+/** @file
+ * VirtualBox Video driver, common code - HGSMI initialisation and helper
+ * functions.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <VBox/VBoxVideoGuest.h>
+#include <VBox/VBoxVideo.h>
+#include <VBox/VBoxGuest.h>
+#include <VBox/Hardware/VBoxVideoVBE.h>
+#include <VBox/VMMDev.h>
+
+#include <iprt/asm.h>
+#include <iprt/log.h>
+
+/**
+ * Gets the count of virtual monitors attached to the guest via an HGSMI
+ * command
+ *
+ * @returns the right count on success or 1 on failure.
+ * @param  pCtx  the context containing the heap to use
+ */
+RTDECL(uint32_t) VBoxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx)
+{
+    /* Query the configured number of displays. */
+    uint32_t cDisplays = 0;
+    VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_MONITOR_COUNT, &cDisplays);
+    LogFunc(("cDisplays = %d\n", cDisplays));
+    if (cDisplays == 0 || cDisplays > VBOX_VIDEO_MAX_SCREENS)
+        /* Host reported some bad value. Continue in the 1 screen mode. */
+        cDisplays = 1;
+    return cDisplays;
+}
+
+
+/**
+ * Tell the host about how VRAM is divided up between each screen via an HGSMI
+ * command.  It is acceptable to specifiy identical data for each screen if
+ * they share a single framebuffer.
+ *
+ * @returns iprt status code, either VERR_NO_MEMORY or the status returned by
+ *          @a pfnFill
+ * @param  pCtx      the context containing the heap to use
+ * @param  u32Count  the number of screens we are activating
+ * @param  pfnFill   a callback which initialises the VBVAINFOVIEW structures
+ *                   for all screens
+ * @param  pvData    context data for @a pfnFill
+ */
+RTDECL(int) VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                  uint32_t u32Count,
+                                  PFNHGSMIFILLVIEWINFO pfnFill,
+                                  void *pvData)
+{
+    int rc;
+    /* Issue the screen info command. */
+    void *p = VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAINFOVIEW) * u32Count,
+                                   HGSMI_CH_VBVA, VBVA_INFO_VIEW);
+    if (p)
+    {
+        VBVAINFOVIEW *pInfo = (VBVAINFOVIEW *)p;
+        rc = pfnFill(pvData, pInfo, u32Count);
+        if (RT_SUCCESS(rc))
+            VBoxHGSMIBufferSubmit (pCtx, p);
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+    return rc;
+}
+
+
+/**
+ * Set a video mode using port registers.  This must be done for the first
+ * screen before every HGSMI modeset and also works when HGSM is not enabled.
+ * @param  cWidth    the mode width
+ * @param  cHeight   the mode height
+ * @param  cBPP      the colour depth of the mode
+ * @param  cx        the horizontal panning offset
+ * @param  cy        the vertical panning offset
+ */
+RTDECL(void) VBoxVideoSetModeRegisters(uint16_t cWidth, uint16_t cHeight,
+                                       uint16_t cVirtWidth, uint16_t cBPP,
+                                       uint16_t cx, uint16_t cy)
+{
+    /* set the mode characteristics */
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cWidth);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cHeight);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIRT_WIDTH);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cVirtWidth);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cBPP);
+    /* enable the mode */
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ENABLE);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);
+    /* Panning registers */
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_X_OFFSET);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cx);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_Y_OFFSET);
+    VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, cy);
+    /** @todo read from the port to see if the mode switch was successful */
+}
+
+
+/**
+ * Set a video mode via an HGSMI request.  The views must have been
+ * initialised first using @a VBoxHGSMISendViewInfo and if the mode is being
+ * set on the first display then it must be set first using registers.
+ * @param  cDisplay  the screen number
+ * @param  cOriginX  the horizontal displacement relative to the first screen
+ * @param  cOriginY  the vertical displacement relative to the first screen
+ * @param  offStart  the offset of the visible area of the framebuffer
+ *                   relative to the framebuffer start
+ * @param  cbPitch   the offset in bytes between the starts of two adjecent
+ *                   scan lines in video RAM
+ * @param  cWidth    the mode width
+ * @param  cHeight   the mode height
+ * @param  cBPP      the colour depth of the mode
+ */
+RTDECL(void) VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+                                         uint32_t cDisplay,
+                                         int32_t  cOriginX,
+                                         int32_t  cOriginY,
+                                         uint32_t offStart,
+                                         uint32_t cbPitch,
+                                         uint32_t cWidth,
+                                         uint32_t cHeight,
+                                         uint16_t cBPP)
+{
+    /* Issue the screen info command. */
+    void *p = VBoxHGSMIBufferAlloc(pCtx,
+                                   sizeof (VBVAINFOSCREEN),
+                                   HGSMI_CH_VBVA,
+                                   VBVA_INFO_SCREEN);
+    if (!p)
+    {
+        LogFunc(("HGSMIHeapAlloc failed\n"));
+    }
+    else
+    {
+        VBVAINFOSCREEN *pScreen = (VBVAINFOSCREEN *)p;
+
+        pScreen->u32ViewIndex    = cDisplay;
+        pScreen->i32OriginX      = cOriginX;
+        pScreen->i32OriginY      = cOriginY;
+        pScreen->u32StartOffset  = offStart;
+        pScreen->u32LineSize     = cbPitch;
+        pScreen->u32Width        = cWidth;
+        pScreen->u32Height       = cHeight;
+        pScreen->u16BitsPerPixel = cBPP;
+        pScreen->u16Flags        = VBVA_SCREEN_F_ACTIVE;
+
+        VBoxHGSMIBufferSubmit(pCtx, p);
+
+        VBoxHGSMIBufferFree(pCtx, p);
+    }
+}
Index: trunk/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp	(revision 34677)
+++ trunk/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp	(revision 34686)
@@ -389,41 +389,2 @@
     pCtx->cbBuffer      = cbBuffer;
 }
-
-RTDECL(void) VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
-                                         uint32_t cDisplay,
-                                         int32_t  cOriginX,
-                                         int32_t  cOriginY,
-                                         uint32_t offStart,
-                                         uint32_t cbPitch,
-                                         uint32_t cWidth,
-                                         uint32_t cHeight,
-                                         uint16_t cBPP)
-{
-    /* Issue the screen info command. */
-    void *p = VBoxHGSMIBufferAlloc(pCtx,
-                                   sizeof (VBVAINFOSCREEN),
-                                   HGSMI_CH_VBVA,
-                                   VBVA_INFO_SCREEN);
-    if (!p)
-    {
-        LogFunc(("HGSMIHeapAlloc failed\n"));
-    }
-    else
-    {
-        VBVAINFOSCREEN *pScreen = (VBVAINFOSCREEN *)p;
-
-        pScreen->u32ViewIndex    = cDisplay;
-        pScreen->i32OriginX      = cOriginX;
-        pScreen->i32OriginY      = cOriginY;
-        pScreen->u32StartOffset  = offStart;
-        pScreen->u32LineSize     = cbPitch;
-        pScreen->u32Width        = cWidth;
-        pScreen->u32Height       = cHeight;
-        pScreen->u16BitsPerPixel = cBPP;
-        pScreen->u16Flags        = VBVA_SCREEN_F_ACTIVE;
-
-        VBoxHGSMIBufferSubmit(pCtx, p);
-
-        VBoxHGSMIBufferFree(pCtx, p);
-    }
-}
