Index: /trunk/include/VBox/VBoxVideo.h
===================================================================
--- /trunk/include/VBox/VBoxVideo.h	(revision 19843)
+++ /trunk/include/VBox/VBoxVideo.h	(revision 19844)
@@ -252,4 +252,74 @@
 #pragma pack()
 
+# ifdef VBOX_WITH_VIDEOHWACCEL
+#pragma pack(1)
+
+typedef enum
+{
+    VBOXVHWACMD_TYPE_SURF_CREATE = 1,
+    VBOXVHWACMD_TYPE_SURF_DESTROY
+} VBOXVHWACMD_TYPE;
+
+typedef struct _VBOXVHWACMD
+{
+    VBOXVHWACMD_TYPE enmCmd; /* command type */
+    int32_t rc; /* command result */
+    int32_t iDisplay; /* display index */
+    int32_t Reserved; /* reserved, must be null*/
+    char body[1];
+} VBOXVHWACMD;
+
+#define VBOXVHWACMD_SIZE(_tCmd) (RT_OFFSETOF(VBOXVHWACMD_HDR, body) + sizeof(_tCmd))
+typedef unsigned int VBOXVHWACMD_LENGTH;
+typedef uint64_t VBOXVHWA_SURFHANDLE;
+#define VBOXVHWACMD_SURFHANDLE_INVALID 0
+#define VBOXVHWACMD_BODY(_p, _t) ((_t*)(_p)->body)
+
+typedef struct _VBOXVHWA_RECTL
+{
+    int16_t x;
+    int16_t y;
+    uint16_t w;
+    uint16_t h;
+} VBOXVHWA_RECTL;
+
+#define VBOXVHWASURF_PRIMARY      0x00000001
+#define VBOXVHWASURF_OVERLAY      0x00000002
+
+typedef struct _VBOXVHWA_SURFINFO
+{
+    uint32_t surfChars;
+    VBOXVHWA_RECTL rectl;
+} VBOXVHWA_SURFINFO;
+
+typedef struct _VBOXVHWACMD_SURF_CREATE
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFINFO SurfInfo;
+        } in;
+
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hSurf;
+        } out;
+    } u;
+} VBOXVHWACMD_SURF_CREATE;
+
+typedef struct _VBOXVHWACMD_SURF_DESTROY
+{
+    union
+    {
+        struct
+        {
+            VBOXVHWA_SURFHANDLE hSurf;
+        } in;
+    } u;
+} VBOXVHWACMD_SURF_DESTROY;
+#pragma pack()
+# endif /* #ifdef VBOX_WITH_VIDEOHWACCEL */
+
 #ifdef VBOX_WITH_HGSMI
 
@@ -279,5 +349,5 @@
 } VBVABUFFER;
 
-
+/* guest->host commands */
 #define VBVA_QUERY_CONF32 1
 #define VBVA_SET_CONF32   2
@@ -288,78 +358,34 @@
 #define VBVA_ENABLE       7
 #define VBVA_MOUSE_POINTER_SHAPE 8
-#ifdef VBOX_WITH_VIDEOHWACCEL
+# ifdef VBOX_WITH_VIDEOHWACCEL
 # define VBVA_INFO_VHWA   9
 # define VBVA_VHWA_CMD    10
-
-typedef enum
-{
-    VBVAVHWACMD_TYPE_SURF_CREATE = 1,
-    VBVAVHWACMD_TYPE_SURF_DESTROY
-} VBVAVHWACMD_TYPE;
-
-typedef struct _VBVAVHWACMD_HDR
-{
-    VBVAVHWACMD_TYPE enmCmd;
+# endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */
+
+/* host->guest commands */
+# ifdef VBOX_WITH_VIDEOHWACCEL
+# define VBVAHG_VHWA_CMDCOMPLETE 1
+
+typedef struct _VBVAHOSTCMDVHWACMDCOMPLETE
+{
+    uint32_t offCmd;
+}VBVAHOSTCMDVHWACMDCOMPLETE;
+# endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */
+
+#pragma pack(1)
+typedef struct _VBVAHOSTCMD
+{
+    /* destination ID if >=0 specifies display index, otherwize the command is directed to the miniport */
+    int32_t iDstID;
+    uint32_t Reserved;
     char body[1];
-} VBVAVHWACMD_HDR;
-
-#define VBVAVHWACMD_SIZE(_tCmd) (RT_OFFSETOF(VBVAVHWACMD_HDR, body) + sizeof(_tCmd))
-typedef unsigned int VBVAVHWACMD_LENGTH;
-typedef uint64_t VBVAVHWA_SURFHANDLE;
-#define VBVAVHWA_SURFHANDLE_INVALID 0
-#define VBVAVHWACMD_BODY(_p, _t) ((_t*)(_p)->body)
-
-typedef struct _VBVAVHWA_RECTL
-{
-    int16_t x;
-    int16_t y;
-    uint16_t w;
-    uint16_t h;
-} VBVAVHWA_RECTL;
-
-#define VBVAVHWASURF_PRIMARY      0x00000001
-#define VBVAVHWASURF_OVERLAY      0x00000002
-
-typedef struct _VBVAVHWA_SURFINFO
-{
-    uint32_t surfChars;
-    VBVAVHWA_RECTL rectl;
-} VBVAVHWA_SURFINFO;
-
-typedef struct _VBVAVHWACMD_SURF_CREATE
-{
-    union
-    {
-        struct
-        {
-            VBVAVHWA_SURFINFO SurfInfo;
-        } in;
-
-        struct
-        {
-            int rc;
-            VBVAVHWA_SURFHANDLE hSurf;
-        } out;
-    } u;
-} VBVAVHWACMD_SURF_CREATE;
-
-typedef struct _VBVAVHWACMD_SURF_DESTROY
-{
-    union
-    {
-        struct
-        {
-            VBVAVHWA_SURFHANDLE hSurf;
-        } in;
-
-        struct
-        {
-            int rc;
-        } out;
-    } u;
-} VBVAVHWACMD_SURF_DESTROY;
-
-#endif
-
+}VBVAHOSTCMD;
+
+#define VBVAHOSTCMD_SIZE(_size) (sizeof(VBVAHOSTCMD) + (_size))
+#define VBVAHOSTCMD_BODY(_pCmd, _tBody) ((_tBody*)(_pCmd)->body)
+#define VBVAHOSTCMD_HDR(_pBody) ((VBVAHOSTCMD*)(((uint8_t*)_pBody) - RT_OFFSETOF(VBVAHOSTCMD, body)))
+#define VBVAHOSTCMD_HDRSIZE (RT_OFFSETOF(VBVAHOSTCMD, body))
+
+#pragma pack()
 
 /* VBVACONF32::u32Index */
Index: /trunk/include/VBox/err.h
===================================================================
--- /trunk/include/VBox/err.h	(revision 19843)
+++ /trunk/include/VBox/err.h	(revision 19844)
@@ -1372,4 +1372,12 @@
 /** @} */
 
+/** @name VBox Video HW Acceleration command status
+ * @{
+ */
+/** command processing is pending, a completion handler will be called */
+#define VINF_VHWA_CMD_PENDING                        4500
+
+/** @} */
+
 /* SED-END */
 
Index: /trunk/include/VBox/pdmifs.h
===================================================================
--- /trunk/include/VBox/pdmifs.h	(revision 19843)
+++ /trunk/include/VBox/pdmifs.h	(revision 19844)
@@ -167,4 +167,6 @@
     /** PDMISCSICONNECTOR       - The SCSI command execution connector interface (Up) Coupled with PDMINTERFACE_SCSI_PORT. */
     PDMINTERFACE_SCSI_CONNECTOR,
+    /** PDMDDISPLAYVBVACALLBACKS       - The Display VBVA call-backs */
+    PDMINTERFACE_DISPLAY_VBVA_CALLBACKS,
 
     /** Maximum interface number. */
@@ -425,4 +427,5 @@
 } PDMIDISPLAYPORT;
 
+typedef struct _VBOXVHWACMD *PVBOXVHWACMD;
 
 /** Pointer to a display connector interface. */
@@ -526,4 +529,12 @@
     DECLR3CALLBACKMEMBER(void, pfnProcessDisplayData, (PPDMIDISPLAYCONNECTOR pInterface, void *pvVRAM, unsigned uScreenId));
 
+    /**
+     * Process the guest Video HW Acceleration command.
+     *
+     * @param   pInterface          Pointer to this interface.
+     * @param   pCmd                Video HW Acceleration Command to be processed.
+     * @thread  The emulation thread.
+     */
+    DECLR3CALLBACKMEMBER(void, pfnVHWACommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCmd));
 
     /** Read-only attributes.
@@ -2587,4 +2598,18 @@
 
 } PDMISCSICONNECTOR;
+
+typedef struct PDMDDISPLAYVBVACALLBACKS *PPDMDDISPLAYVBVACALLBACKS;
+/**
+ * Display VBVA callbacks
+ */
+typedef struct PDMDDISPLAYVBVACALLBACKS
+{
+    /**
+     * Informs guest about completion of processing the given Video HW Acceleration command,
+     * does not wait for the guest to process the command
+     */
+    DECLR3CALLBACKMEMBER(int, pfnVHWACommandCompleteAsynch, (PPDMDDISPLAYVBVACALLBACKS pInterface, PVBOXVHWACMD pCmd));
+}PDMDDISPLAYVBVACALLBACKS;
+
 /** @} */
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h	(revision 19843)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/driver.h	(revision 19844)
@@ -164,4 +164,7 @@
     HGSMIHEAP hgsmiDisplayHeap;
     VBVABUFFER *pVBVA; /* Pointer to the pjScreen + layout->offVBVABuffer. NULL if VBVA is not enabled. */
+
+    HVBOXVIDEOHGSMI hMpHGSMI; /* context handler passed to miniport HGSMI callbacks */
+    PFNVBOXVIDEOHGSMICOMPLETION pfnHGSMICommandComplete; /* called to complete the command we receive from the miniport */
 #endif /* VBOX_WITH_HGSMI */
 
@@ -249,8 +252,12 @@
 void drvLoadEng (void);
 
-#ifdef VBOX_WITH_VIDEOHWACCEL
-VBVAVHWACMD_HDR* vboxVHWACreateCommand (PPDEV ppdev, VBVAVHWACMD_LENGTH cbCmd);
-void vboxVHWAFreeCommand (PPDEV ppdev, VBVAVHWACMD_HDR* pCmd);
-void vboxVHWASubmitCommand (PPDEV ppdev, VBVAVHWACMD_HDR* pCmd);
+#ifdef VBOX_WITH_HGSMI
+DECLCALLBACK(int) vboxVHWACommandHanlder(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer);
+
+ #ifdef VBOX_WITH_VIDEOHWACCEL
+VBOXVHWACMD* vboxVHWACreateCommand (PPDEV ppdev, VBOXVHWACMD_LENGTH cbCmd);
+void vboxVHWAFreeCommand (PPDEV ppdev, VBOXVHWACMD* pCmd);
+void vboxVHWASubmitCommand (PPDEV ppdev, VBOXVHWACMD* pCmd);
+ #endif
 #endif
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c	(revision 19843)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/screen.c	(revision 19844)
@@ -101,7 +101,45 @@
     if (ppdev->bHGSMISupported)
     {
+        HGSMIQUERYCALLBACKS Callbacks;
+        DWORD err;
+        RtlZeroMemory(&Callbacks, sizeof(Callbacks));
+
         iDevice = info.iDevice;
         u32DisplayInfoSize = info.u32DisplayInfoSize;
         u32MinVBVABufferSize = info.u32MinVBVABufferSize;
+
+        err = EngDeviceIoControl(ppdev->hDriver,
+                IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS,
+                NULL,
+                0,
+                &Callbacks,
+                sizeof(Callbacks),
+                &returnedDataLength);
+        Assert(!err);
+        if(!err)
+        {
+            HGSMIHANDLERREGISTER HandlerReg;
+            RtlZeroMemory(&HandlerReg, sizeof(HandlerReg));
+
+            ppdev->hMpHGSMI = Callbacks.hContext;
+            ppdev->pfnHGSMICommandComplete = Callbacks.pfnCompletionHandler;
+            HandlerReg.pfnHandler = vboxVHWACommandHanlder;
+            HandlerReg.pvHandler = ppdev;
+            HandlerReg.u8Channel = HGSMI_CH_VBVA;
+            err = EngDeviceIoControl(ppdev->hDriver,
+                    IOCTL_VIDEO_HGSMI_HANDLER_REGISTER,
+                    &HandlerReg,
+                    sizeof(HandlerReg),
+                    NULL,
+                    0,
+                    &returnedDataLength);
+            Assert(!err);
+        }
+
+        if(err)
+        {
+            ppdev->bHGSMISupported = FALSE;
+        }
+
     }
 #endif /* VBOX_WITH_HGSMI */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c	(revision 19843)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/vbox.c	(revision 19844)
@@ -692,7 +692,7 @@
 # ifdef VBOX_WITH_VIDEOHWACCEL
 
-VBVAVHWACMD_HDR* vboxVHWACreateCommand (PPDEV ppdev, VBVAVHWACMD_LENGTH cbCmd)
-{
-    VBVAVHWACMD_HDR* pHdr = (VBVAVHWACMD_HDR*)HGSMIHeapAlloc (&ppdev->hgsmiDisplayHeap,
+VBOXVHWACMD* vboxVHWACreateCommand (PPDEV ppdev, VBOXVHWACMD_LENGTH cbCmd)
+{
+    VBOXVHWACMD* pHdr = (VBOXVHWACMD*)HGSMIHeapAlloc (&ppdev->hgsmiDisplayHeap,
                               cbCmd,
                               HGSMI_CH_VBVA,
@@ -706,15 +706,56 @@
 }
 
-void vboxVHWAFreeCommand (PPDEV ppdev, VBVAVHWACMD_HDR* pCmd)
+void vboxVHWAFreeCommand (PPDEV ppdev, VBOXVHWACMD* pCmd)
 {
     HGSMIHeapFree (&ppdev->hgsmiDisplayHeap, pCmd);
 }
 
-void vboxVHWASubmitCommand (PPDEV ppdev, VBVAVHWACMD_HDR* pCmd)
+void vboxVHWASubmitCommand (PPDEV ppdev, VBOXVHWACMD* pCmd)
 {
     vboxHGSMIBufferSubmit (ppdev, pCmd);
+    if(pCmd->rc == VINF_VHWA_CMD_PENDING)
+    {
+
+    }
+}
+
+/* do not wait for completion */
+void vboxVHWASubmitCommandAssynch (PPDEV ppdev, VBOXVHWACMD* pCmd)
+{
+    vboxHGSMIBufferSubmit (ppdev, pCmd);
+}
+
+static int vboxVHWAHanldeVHWACmdCompletion(PPDEV ppdev, void *pvBuffer, HGSMISIZE cbBuffer)
+{
+    Assert(0);
+
+    ppdev->pfnHGSMICommandComplete(ppdev->hMpHGSMI, pvBuffer);
+    return 0;
 }
 
 # endif
 
+DECLCALLBACK(int) vboxVHWACommandHanlder(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer)
+{
+    int rc = VINF_SUCCESS;
+    PPDEV ppdev = (PPDEV)pvHandler;
+
+    switch(u16ChannelInfo)
+    {
+# ifdef VBOX_WITH_VIDEOHWACCEL
+        case VBVAHG_VHWA_CMDCOMPLETE:
+        {
+            vboxVHWAHanldeVHWACmdCompletion(ppdev, pvBuffer, cbBuffer);
+            break;
+        }
+# endif
+        default:
+        {
+            ppdev->pfnHGSMICommandComplete(ppdev->hMpHGSMI, pvBuffer);
+        }
+
+    }
+    return rc;
+}
+
 #endif /* VBOX_WITH_HGSMI */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 19843)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.cpp	(revision 19844)
@@ -1875,4 +1875,73 @@
             break;
         }
+        case IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS:
+        {
+            dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS\n"));
+
+            if (RequestPacket->OutputBufferLength < sizeof(HGSMIQUERYCALLBACKS))
+            {
+                dprintf(("VBoxVideo::VBoxVideoStartIO: Output buffer too small: %d needed: %d!!!\n",
+                         RequestPacket->OutputBufferLength, sizeof(HGSMIQUERYCALLBACKS)));
+                RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+                return FALSE;
+            }
+
+            if (!pDevExt->pPrimary->u.primary.bHGSMI)
+            {
+                RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
+                return FALSE;
+            }
+
+            HGSMIQUERYCALLBACKS *pInfo = (HGSMIQUERYCALLBACKS *)RequestPacket->OutputBuffer;
+
+            pInfo->hContext = pDevExt->pPrimary;
+            pInfo->pfnCompletionHandler = hgsmiHostCmdHandlerComplete;
+
+            RequestPacket->StatusBlock->Information = sizeof(HGSMIQUERYCALLBACKS);
+            Result = TRUE;
+            break;
+        }
+        case IOCTL_VIDEO_HGSMI_HANDLER_REGISTER:
+        {
+            dprintf(("VBoxVideo::VBoxVideoStartIO: IOCTL_VIDEO_HGSMI_HANDLER_REGISTER\n"));
+
+            if (RequestPacket->InputBufferLength< sizeof(HGSMIHANDLERREGISTER))
+            {
+                dprintf(("VBoxVideo::VBoxVideoStartIO: Output buffer too small: %d needed: %d!!!\n",
+                         RequestPacket->InputBufferLength, sizeof(HGSMIHANDLERREGISTER)));
+                RequestPacket->StatusBlock->Status = ERROR_INSUFFICIENT_BUFFER;
+                return FALSE;
+            }
+
+            if (!pDevExt->pPrimary->u.primary.bHGSMI)
+            {
+                RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
+                return FALSE;
+            }
+
+            HGSMIHANDLERREGISTER *pInfo = (HGSMIHANDLERREGISTER *)RequestPacket->InputBuffer;
+
+            int rc = vboxHGSMIChannelDisplayRegister (pDevExt->pPrimary,
+                    pDevExt->iDevice, /* negative would mean this is a miniport handler */
+                    pInfo->u8Channel,
+                    pInfo->pfnHandler,
+                    pInfo->pvHandler);
+            if(RT_FAILURE(rc))
+            {
+                RequestPacket->StatusBlock->Status = ERROR_INVALID_NAME;
+            }
+            Result = TRUE;
+            break;
+        }
+        case IOCTL_VIDEO_HGSMI_HANDLER_DEREGISTER:
+        {
+            /* TODO: implement */
+            if (!pDevExt->pPrimary->u.primary.bHGSMI)
+            {
+                RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
+                return FALSE;
+            }
+            break;
+        }
 #endif /* VBOX_WITH_HGSMI */
 
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 19843)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideo.h	(revision 19844)
@@ -29,4 +29,5 @@
 #include <VBox/HGSMI/HGSMI.h>
 #include <VBox/HGSMI/HGSMIChSetup.h>
+#include "VBoxHGSMI.h"
 #endif /* VBOX_WITH_HGSMI */
 
@@ -256,4 +257,12 @@
                                 PVIDEO_POINTER_ATTRIBUTES pointerAttr,
                                 uint32_t cbLength);
+
+DECLCALLBACK(void) hgsmiHostCmdHandlerComplete (HVBOXVIDEOHGSMI hHGSMI, void * pvMem);
+
+int vboxHGSMIChannelDisplayRegister (PDEVICE_EXTENSION PrimaryExtension,
+        int iDisplay, /* negative would mean this is a miniport handler */
+        uint8_t u8Channel,
+        PFNHGSMICHANNELHANDLER pfnChannelHandler,
+        void *pvChannelHandler);
 #endif /* VBOX_WITH_HGSMI */
 } /* extern "C" */
Index: /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/vboxioctl.h
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/vboxioctl.h	(revision 19843)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Miniport/vboxioctl.h	(revision 19844)
@@ -27,4 +27,5 @@
 #ifdef VBOX_WITH_HGSMI
 #include <VBox/HGSMI/HGSMI.h>
+#include "VBoxHGSMI.h"
 #endif /* VBOX_WITH_HGSMI */
 
@@ -48,4 +49,14 @@
 #define IOCTL_VIDEO_QUERY_HGSMI_INFO \
     CTL_CODE(FILE_DEVICE_VIDEO, 0x430, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS \
+    CTL_CODE(FILE_DEVICE_VIDEO, 0x431, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_VIDEO_HGSMI_HANDLER_REGISTER \
+    CTL_CODE(FILE_DEVICE_VIDEO, 0x432, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_VIDEO_HGSMI_HANDLER_DEREGISTER \
+    CTL_CODE(FILE_DEVICE_VIDEO, 0x433, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
 #endif /* VBOX_WITH_HGSMI */
 
@@ -109,4 +120,36 @@
     uint32_t u32MinVBVABufferSize;
 } QUERYHGSMIRESULT;
+
+/**
+ * Data returned by IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS.
+ *
+ */
+typedef struct _HGSMIQUERYCALLBACKS
+{
+    HVBOXVIDEOHGSMI hContext;
+    PFNVBOXVIDEOHGSMICOMPLETION pfnCompletionHandler;
+} HGSMIQUERYCALLBACKS;
+
+/**
+ * Data returned by IOCTL_VIDEO_HGSMI_HANDLER_REGISTER.
+ *
+ */
+typedef struct _HGSMIHANDLERREGISTER
+{
+    PFNHGSMICHANNELHANDLER pfnHandler;
+    void * pvHandler;
+    uint8_t u8Channel;
+} HGSMIHANDLERREGISTER;
+
+/**
+ * Data passed by IOCTL_VIDEO_HGSMI_HANDLER_DEREGISTER.
+ *
+ */
+typedef struct _HGSMIHANDLERDEREGISTER
+{
+    PFNHGSMICHANNELHANDLER pfnHandler;
+    uint8_t u8Channel;
+} HGSMIHANDLERDEREGISTER;
+
 #endif /* VBOX_WITH_HGSMI */
 #pragma pack()
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 19843)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.cpp	(revision 19844)
@@ -4554,4 +4554,8 @@
         case PDMINTERFACE_DISPLAY_PORT:
             return &pThis->Port;
+#if defined(VBOX_WITH_HGSMI) && defined(VBOX_WITH_VIDEOHWACCEL)
+        case PDMINTERFACE_DISPLAY_VBVA_CALLBACKS:
+            return &pThis->VBVACallbacks;
+#endif
         default:
             return NULL;
@@ -5573,4 +5577,7 @@
     pThis->Port.pfnSetRenderVRAM        = vgaPortSetRenderVRAM;
 
+#if defined(VBOX_WITH_HGSMI) && defined(VBOX_WITH_VIDEOHWACCEL)
+    pThis->VBVACallbacks.pfnVHWACommandCompleteAsynch = vbvaVHWACommandCompleteAsynch;
+#endif
 
     /*
Index: /trunk/src/VBox/Devices/Graphics/DevVGA.h
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 19843)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA.h	(revision 19844)
@@ -309,4 +309,8 @@
     /** The display port interface. */
     PDMIDISPLAYPORT             Port;
+#if defined(VBOX_WITH_HGSMI) && defined(VBOX_WITH_VIDEOHWACCEL)
+    /** VBVA callbacks interface */
+    PDMDDISPLAYVBVACALLBACKS    VBVACallbacks;
+#endif
     /** Pointer to base interface of the driver. */
     R3PTRTYPE(PPDMIBASE)        pDrvBase;
@@ -443,4 +447,8 @@
 void     VBVADestroy    (PVGASTATE pVGAState);
 int      VBVAUpdateDisplay (PVGASTATE pVGAState);
+
+# ifdef VBOX_WITH_VIDEOHWACCEL
+int vbvaVHWACommandCompleteAsynch(PPDMDDISPLAYVBVACALLBACKS pInterface, PVBOXVHWACMD pCmd);
+# endif
 #endif /* VBOX_WITH_HGSMI */
 
Index: /trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Devices/Makefile.kmk	(revision 19843)
+++ /trunk/src/VBox/Devices/Makefile.kmk	(revision 19844)
@@ -574,5 +574,5 @@
 endif
 ifdef VBOX_WITH_VIDEOHWACCEL
- VBoxDDGC_DEFS         += VBOX_WITH_VIDEOHWACCEL
+ VBoxDDR0_DEFS         += VBOX_WITH_VIDEOHWACCEL
 endif
 
Index: /trunk/src/VBox/Frontends/VBoxBFE/Framebuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxBFE/Framebuffer.h	(revision 19843)
+++ /trunk/src/VBox/Frontends/VBoxBFE/Framebuffer.h	(revision 19844)
@@ -50,4 +50,6 @@
     virtual HRESULT SetVisibleRegion(BYTE *aRectangles, ULONG aCount) = 0;
 
+    virtual HRESULT ProcessVHWACommand(BYTE *pCommand) = 0;
+
     virtual void    repaint() = 0;
     virtual void    resize() = 0;
Index: /trunk/src/VBox/Frontends/VBoxBFE/SDLFramebuffer.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxBFE/SDLFramebuffer.cpp	(revision 19843)
+++ /trunk/src/VBox/Frontends/VBoxBFE/SDLFramebuffer.cpp	(revision 19844)
@@ -336,4 +336,9 @@
 }
 
+HRESULT SDLFramebuffer::ProcessVHWACommand(BYTE *pCommand)
+{
+    return E_NOTIMPL;
+}
+
 //
 // Internal public methods
Index: /trunk/src/VBox/Frontends/VBoxBFE/SDLFramebuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxBFE/SDLFramebuffer.h	(revision 19843)
+++ /trunk/src/VBox/Frontends/VBoxBFE/SDLFramebuffer.h	(revision 19844)
@@ -55,4 +55,6 @@
     virtual HRESULT SetVisibleRegion(BYTE *aRectangles, ULONG aCount);
 
+    virtual HRESULT ProcessVHWACommand(BYTE *pCommand);
+
     virtual void    repaint();
     virtual void    resize();
Index: /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.cpp	(revision 19843)
+++ /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.cpp	(revision 19844)
@@ -634,5 +634,8 @@
 }
 
-
+STDMETHODIMP FFmpegFB::ProcessVHWACommand(BYTE *pCommand)
+{
+    return E_NOTIMPL;
+}
 // Private Methods
 //////////////////////////////////////////////////////////////////////////
Index: /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.h	(revision 19843)
+++ /trunk/src/VBox/Frontends/VBoxHeadless/VideoCapture/FFmpegFB.h	(revision 19844)
@@ -107,4 +107,6 @@
     STDMETHOD(GetVisibleRegion)(BYTE *rectangles, ULONG count, ULONG *countCopied);
     STDMETHOD(SetVisibleRegion)(BYTE *rectangles, ULONG count);
+
+    STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
 
 private:
Index: /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	(revision 19843)
+++ /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.cpp	(revision 19844)
@@ -578,4 +578,8 @@
 }
 
+STDMETHODIMP VBoxSDLFB::ProcessVHWACommand(BYTE *pCommand)
+{
+    return E_NOTIMPL;
+}
 //
 // Internal public methods
Index: /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h	(revision 19843)
+++ /trunk/src/VBox/Frontends/VBoxSDL/Framebuffer.h	(revision 19844)
@@ -109,4 +109,6 @@
     STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
     STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
+
+    STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
 
     // internal public methods
Index: /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 19843)
+++ /trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 19844)
@@ -434,4 +434,8 @@
 endif
 
+ifdef VBOX_WITH_VIDEOHWACCEL
+ VirtualBox_DEFS += VBOX_WITH_VIDEOHWACCEL
+endif
+
 # The Qt modules we're using.
 # (The include directory and lib/framework for each module will be added by the Qt4 unit.)
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h	(revision 19843)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h	(revision 19844)
@@ -218,4 +218,8 @@
     bool isRunning() { return mLastState == KMachineState_Running; }
 
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    void handleVHWACommand(struct _VBOXVHWACMD *pCommand);
+#endif
+
     static void dimImage (QImage &img);
 
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 19843)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 19844)
@@ -126,4 +126,8 @@
         AddVDMUrlsEventType,
         ChangeDockIconUpdateEventType
+#ifdef VBOX_WITH_VIDEOHWACCEL
+        ,
+        VHWACommandProcessType
+#endif
     };
 
Index: /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 19843)
+++ /trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 19844)
@@ -114,4 +114,18 @@
 };
 
+#ifdef VBOX_WITH_VIDEOHWACCEL
+class VBoxVHWACommandProcessEvent : public QEvent
+{
+public:
+    VBoxVHWACommandProcessEvent (struct _VBOXVHWACMD * pCmd)
+        : QEvent ((QEvent::Type) VBoxDefs::VHWACommandProcessType)
+        , mpCmd (pCmd) {}
+    struct _VBOXVHWACMD * command() { return mpCmd; }
+private:
+    struct _VBOXVHWACMD * mpCmd;
+};
+
+#endif
+
 /////////////////////////////////////////////////////////////////////////////
 
@@ -205,4 +219,6 @@
     STDMETHOD(GetVisibleRegion)(BYTE *aRectangles, ULONG aCount, ULONG *aCountCopied);
     STDMETHOD(SetVisibleRegion)(BYTE *aRectangles, ULONG aCount);
+
+    STDMETHOD(ProcessVHWACommand)(BYTE *pCommand);
 
     ulong width() { return mWdt; }
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 19843)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 19844)
@@ -92,4 +92,8 @@
 # include <VBox/err.h>
 #endif /* defined (Q_WS_MAC) */
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+#include <VBox/VBoxVideo.h>
+#endif
 
 #if defined (Q_WS_WIN32)
@@ -1689,4 +1693,12 @@
             }
 #endif
+#ifdef VBOX_WITH_VIDEOHWACCEL
+            case VBoxDefs::VHWACommandProcessType:
+            {
+                VBoxVHWACommandProcessEvent *cmde = (VBoxVHWACommandProcessEvent *)e;
+                handleVHWACommand(cmde->command());
+                return true;
+            }
+#endif
             default:
                 break;
@@ -1696,4 +1708,30 @@
     return QAbstractScrollArea::event (e);
 }
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+void VBoxConsoleView::handleVHWACommand(struct _VBOXVHWACMD *pCmd)
+{
+    switch(pCmd->enmCmd)
+    {
+        case VBOXVHWACMD_TYPE_SURF_CREATE:
+        {
+            VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
+            pCmd->rc = VERR_NOT_IMPLEMENTED;
+            break;
+        } break;
+        case VBOXVHWACMD_TYPE_SURF_DESTROY:
+        {
+            VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
+            pCmd->rc = VERR_NOT_IMPLEMENTED;
+            break;
+        } break;
+    }
+
+    CDisplay display = mConsole.GetDisplay();
+    Assert (!display.isNull());
+
+    display.CompleteVHWACommand((BYTE*)pCmd);
+}
+#endif
 
 bool VBoxConsoleView::eventFilter (QObject *watched, QEvent *e)
Index: /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp	(revision 19843)
+++ /trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp	(revision 19844)
@@ -260,4 +260,15 @@
 }
 
+STDMETHODIMP VBoxFrameBuffer::ProcessVHWACommand(BYTE *pCommand)
+{
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    QApplication::postEvent (mView,
+                             new VBoxVHWACommandProcessEvent ((struct _VBOXVHWACMD*)pCommand));
+    return S_OK;
+#else
+    return E_NOTIMPL;
+#endif
+}
+
 //
 // VBoxQImageFrameBuffer class
Index: /trunk/src/VBox/Main/DisplayImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/DisplayImpl.cpp	(revision 19843)
+++ /trunk/src/VBox/Main/DisplayImpl.cpp	(revision 19844)
@@ -38,4 +38,7 @@
 #endif
 
+#ifdef VBOX_WITH_VIDEOHWACCEL
+# include <VBox/VBoxVideo.h>
+#endif
 /**
  * Display driver instance data.
@@ -51,4 +54,8 @@
     /** Our display connector interface. */
     PDMIDISPLAYCONNECTOR        Connector;
+#if defined(VBOX_WITH_VIDEOHWACCEL)
+    /** VBVA callbacks */
+    PPDMDDISPLAYVBVACALLBACKS   pVBVACallbacks;
+#endif
 } DRVMAINDISPLAY, *PDRVMAINDISPLAY;
 
@@ -1683,4 +1690,14 @@
 
     return S_OK;
+}
+
+STDMETHODIMP Display::CompleteVHWACommand(BYTE *pCommand)
+{
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    mpDrv->pVBVACallbacks->pfnVHWACommandCompleteAsynch(mpDrv->pVBVACallbacks, (PVBOXVHWACMD)pCommand);
+    return S_OK;
+#else
+    return E_NOTIMPL;
+#endif
 }
 
@@ -2225,4 +2242,49 @@
 }
 
+#ifdef VBOX_WITH_VIDEOHWACCEL
+
+void Display::handleVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand)
+{
+    unsigned id = (unsigned)pCommand->iDisplay;
+    int rc = VINF_SUCCESS;
+    if(id < mcMonitors)
+    {
+        IFramebuffer *pFramebuffer = maFramebuffers[id].pFramebuffer;
+
+        // if there is no framebuffer, this call is not interesting
+        if (pFramebuffer == NULL)
+            return;
+
+        pFramebuffer->Lock();
+
+        HRESULT hr = pFramebuffer->ProcessVHWACommand((BYTE*)pCommand);
+        if(FAILED(hr))
+        {
+            rc = VERR_GENERAL_FAILURE;
+        }
+
+        pFramebuffer->Unlock();
+
+    }
+    else
+    {
+        rc = VERR_INVALID_PARAMETER;
+    }
+
+    if(RT_FAILURE(rc))
+    {
+        /* tell the guest the command is complete */
+        pCommand->rc = rc;
+    }
+}
+
+DECLCALLBACK(void) Display::displayVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand)
+{
+    PDRVMAINDISPLAY pDrv = PDMIDISPLAYCONNECTOR_2_MAINDISPLAY(pInterface);
+
+    pDrv->pDisplay->handleVHWACommandProcess(pInterface, pCommand);
+}
+#endif
+
 /**
  * Queries an interface to the driver.
@@ -2313,4 +2375,7 @@
     pData->Connector.pfnProcessAdapterData = Display::displayProcessAdapterDataCallback;
     pData->Connector.pfnProcessDisplayData = Display::displayProcessDisplayDataCallback;
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    pData->Connector.pfnVHWACommandProcess = Display::displayVHWACommandProcess;
+#endif
 
     /*
@@ -2323,5 +2388,12 @@
         return VERR_PDM_MISSING_INTERFACE_ABOVE;
     }
-
+#if defined(VBOX_WITH_VIDEOHWACCEL)
+    pData->pVBVACallbacks = (PPDMDDISPLAYVBVACALLBACKS)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_DISPLAY_VBVA_CALLBACKS);
+    if (!pData->pVBVACallbacks)
+    {
+        AssertMsgFailed(("Configuration error: No VBVA callback interface above!\n"));
+        return VERR_PDM_MISSING_INTERFACE_ABOVE;
+    }
+#endif
     /*
      * Get the Display object pointer and update the mpDrv member.
Index: /trunk/src/VBox/Main/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Main/Makefile.kmk	(revision 19843)
+++ /trunk/src/VBox/Main/Makefile.kmk	(revision 19844)
@@ -592,4 +592,8 @@
 endif
 
+ifdef VBOX_WITH_VIDEOHWACCEL
+VBoxC_DEFS += VBOX_WITH_VIDEOHWACCEL
+endif
+
 ifdef VBOX_WITH_USB
 VBoxC_SOURCES += \
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 19843)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 19844)
@@ -10276,5 +10276,5 @@
   <interface
      name="IFramebuffer" extends="$unknown"
-     uuid="faaf4c24-d534-4171-8781-c15d2b9fe8c3"
+     uuid="b7ed347a-5765-40a0-ae1c-f543eb4ddeaf"
      wsmap="suppress"
      >
@@ -10581,4 +10581,21 @@
       <param name="count" type="unsigned long" dir="in">
         <desc>Number of <tt>RTRECT</tt> elements in the @a rectangles array.</desc>
+      </param>
+    </method>
+    
+    <method name="processVHWACommand">
+      <desc>
+        Posts a Video HW Acceleration Command to the frame buffer for processing.
+        The commands used for 2D video acceleration (DDraw surface creation/destroying, blitting, scaling, color covnersion, overlaying, etc.)
+        are posted from quest to the host to be processed by the host hardware.
+        
+        <note>
+          The address of the provided command must be in the process space of
+          this IFramebuffer object.
+        </note>
+      </desc>
+    
+      <param name="command" type="octet" mod="ptr" dir="in">
+        <desc>Pointer to VBOXVHWACMD containing the command to execute.</desc>
       </param>
     </method>
@@ -10634,5 +10651,5 @@
   <interface
      name="IDisplay" extends="$unknown"
-     uuid="f1efd4d1-45d4-4f21-a074-29c5a98de8e7"
+     uuid="26881797-bc98-444d-ac69-820633b93ec7"
      wsmap="suppress"
      >
@@ -10794,4 +10811,14 @@
 
       </desc>
+    </method>
+
+    <method name="completeVHWACommand">
+      <desc>
+        Signals that the Video HW Acceleration command has completed.
+      </desc>
+ 
+      <param name="command" type="octet" mod="ptr" dir="in">
+        <desc>Pointer to VBOXVHWACMD containing the completed command.</desc>
+      </param>
     </method>
 
Index: /trunk/src/VBox/Main/include/DisplayImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/DisplayImpl.h	(revision 19843)
+++ /trunk/src/VBox/Main/include/DisplayImpl.h	(revision 19844)
@@ -118,4 +118,7 @@
     int handleDisplayResize (unsigned uScreenId, uint32_t bpp, void *pvVRAM, uint32_t cbLine, int w, int h);
     void handleDisplayUpdate (int x, int y, int cx, int cy);
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    void handleVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand);
+#endif
     IFramebuffer *getFramebuffer()
     {
@@ -241,4 +244,6 @@
     STDMETHOD(UpdateCompleted)();
     STDMETHOD(SetSeamlessMode)(BOOL enabled);
+
+    STDMETHOD(CompleteVHWACommand)(BYTE *pCommand);
 
     // for VirtualBoxSupportErrorInfoImpl
@@ -266,4 +271,8 @@
     static DECLCALLBACK(void)  displayProcessDisplayDataCallback(PPDMIDISPLAYCONNECTOR pInterface, void *pvVRAM, unsigned uScreenId);
 
+#ifdef VBOX_WITH_VIDEOHWACCEL
+    static DECLCALLBACK(void) displayVHWACommandProcess(PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCommand);
+#endif
+
     const ComObjPtr <Console, ComWeakRef> mParent;
     /** Pointer to the associated display driver. */
