Index: /trunk/src/VBox/Additions/WINNT/Graphics/Display/vhwa.c
===================================================================
--- /trunk/src/VBox/Additions/WINNT/Graphics/Display/vhwa.c	(revision 22644)
+++ /trunk/src/VBox/Additions/WINNT/Graphics/Display/vhwa.c	(revision 22644)
@@ -0,0 +1,666 @@
+/* $Id$ */
+/** @file
+ * VBoxGuest -- VirtualBox Win 2000/XP guest display driver
+ *
+ * Video HW Acceleration support functions.
+ */
+
+/*
+ * Copyright (C) 2009 Sun Microsystems, Inc.
+ *
+ * Sun Microsystems, Inc. confidential
+ * All rights reserved
+ */
+#include "driver.h"
+#include "dd.h"
+#undef CO_E_NOTINITIALIZED
+#include <winerror.h>
+#include <iprt/asm.h>
+
+#define MEMTAG 'AWHV'
+PVBOXVHWASURFDESC vboxVHWASurfDescAlloc()
+{
+    return EngAllocMem(FL_NONPAGED_MEMORY | FL_ZERO_MEMORY, sizeof(VBOXVHWASURFDESC), MEMTAG);
+}
+
+void vboxVHWASurfDescFree(PVBOXVHWASURFDESC pDesc)
+{
+    EngFreeMem(pDesc);
+}
+
+#define VBOX_DD(_f) DD##_f
+#define VBOX_VHWA(_f) VBOXVHWA_##_f
+#define VBOX_DD2VHWA(_out, _in, _f) do {if((_in) & VBOX_DD(_f)) _out |= VBOX_VHWA(_f); }while(0)
+#define VBOX_DD_VHWA_PAIR(_v) {VBOX_DD(_v), VBOX_VHWA(_v)}
+#define VBOX_DD_DUMMY_PAIR(_v) {VBOX_DD(_v), 0}
+
+
+static const uint32_t g_SupportedCapList[][2] = {
+        VBOX_DD_VHWA_PAIR(CAPS_BLT),
+        VBOX_DD_VHWA_PAIR(CAPS_BLTQUEUE),
+        VBOX_DD_VHWA_PAIR(CAPS_BLTCOLORFILL),
+        VBOX_DD_VHWA_PAIR(CAPS_BLTFOURCC),
+        VBOX_DD_VHWA_PAIR(CAPS_BLTSTRETCH),
+        VBOX_DD_VHWA_PAIR(CAPS_OVERLAY),
+        VBOX_DD_VHWA_PAIR(CAPS_OVERLAYCANTCLIP),
+        VBOX_DD_VHWA_PAIR(CAPS_OVERLAYFOURCC),
+        VBOX_DD_VHWA_PAIR(CAPS_OVERLAYSTRETCH),
+        VBOX_DD_VHWA_PAIR(CAPS_COLORKEY),
+        VBOX_DD_VHWA_PAIR(CAPS_COLORKEYHWASSIST)
+};
+
+static const uint32_t g_SupportedCap2List[][2] = {
+        VBOX_DD_VHWA_PAIR(CAPS2_COPYFOURCC),
+};
+
+
+static const uint32_t g_SupportedSCapList[][2] = {
+        VBOX_DD_VHWA_PAIR(SCAPS_FLIP),
+        VBOX_DD_VHWA_PAIR(SCAPS_PRIMARYSURFACE),
+        VBOX_DD_VHWA_PAIR(SCAPS_OVERLAY),
+        VBOX_DD_VHWA_PAIR(SCAPS_VISIBLE),
+        VBOX_DD_VHWA_PAIR(SCAPS_VIDEOMEMORY),
+        VBOX_DD_VHWA_PAIR(SCAPS_OFFSCREENPLAIN),
+        VBOX_DD_VHWA_PAIR(SCAPS_LOCALVIDMEM),
+        VBOX_DD_VHWA_PAIR(SCAPS_COMPLEX)
+};
+
+static const uint32_t gSupportedSDList[][2] = {
+        VBOX_DD_VHWA_PAIR(SD_BACKBUFFERCOUNT),
+        VBOX_DD_VHWA_PAIR(SD_CAPS),
+        VBOX_DD_VHWA_PAIR(SD_CKDESTBLT),
+        VBOX_DD_VHWA_PAIR(SD_CKDESTOVERLAY),
+        VBOX_DD_VHWA_PAIR(SD_CKSRCBLT),
+        VBOX_DD_VHWA_PAIR(SD_CKSRCOVERLAY),
+        VBOX_DD_VHWA_PAIR(SD_HEIGHT),
+        VBOX_DD_VHWA_PAIR(SD_PITCH),
+        VBOX_DD_VHWA_PAIR(SD_PIXELFORMAT),
+        VBOX_DD_VHWA_PAIR(SD_WIDTH),
+};
+
+static const uint32_t g_SupportedPFList[][2] = {
+        VBOX_DD_VHWA_PAIR(PF_RGB),
+        VBOX_DD_VHWA_PAIR(PF_RGBTOYUV),
+        VBOX_DD_VHWA_PAIR(PF_YUV),
+        VBOX_DD_VHWA_PAIR(PF_FOURCC)
+};
+
+static const uint32_t g_SupportedCKeyCapList[][2] = {
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_DESTBLT),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_DESTBLTCLRSPACE),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_DESTBLTCLRSPACEYUV),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_DESTBLTYUV),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_DESTOVERLAY),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_DESTOVERLAYCLRSPACE),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_DESTOVERLAYCLRSPACEYUV),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_DESTOVERLAYONEACTIVE),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_DESTOVERLAYYUV),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_NOCOSTOVERLAY),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_SRCBLT),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_SRCBLTCLRSPACE),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_SRCBLTCLRSPACEYUV),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_SRCBLTYUV),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_SRCOVERLAY),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_SRCOVERLAYCLRSPACE),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_SRCOVERLAYCLRSPACEYUV),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_SRCOVERLAYONEACTIVE),
+        VBOX_DD_VHWA_PAIR(CKEYCAPS_SRCOVERLAYYUV)
+};
+
+//static const uint32_t g_SupportedOverList[][2] = {
+//        VBOX_DD_VHWA_PAIR(OVER_DDFX),
+//        VBOX_DD_VHWA_PAIR(OVER_HIDE),
+//        VBOX_DD_VHWA_PAIR(OVER_KEYDEST),
+//        VBOX_DD_VHWA_PAIR(OVER_KEYDESTOVERRIDE),
+//        VBOX_DD_VHWA_PAIR(OVER_KEYSRC),
+//        VBOX_DD_VHWA_PAIR(OVER_KEYSRCOVERRIDE),
+//        VBOX_DD_VHWA_PAIR(OVER_SHOW)
+//};
+//
+//static const uint32_t g_SupportedCKeyList[][2] = {
+//        VBOX_DD_VHWA_PAIR(CKEY_COLORSPACE),
+//        VBOX_DD_VHWA_PAIR(CKEY_DESTBLT),
+//        VBOX_DD_VHWA_PAIR(CKEY_DESTOVERLAY),
+//        VBOX_DD_VHWA_PAIR(CKEY_SRCBLTE),
+//        VBOX_DD_VHWA_PAIR(CKEY_SRCOVERLAY)
+//};
+
+static uint32_t g_SupportedVHWACaps;
+static uint32_t g_SupportedVHWASCaps;
+static uint32_t g_SupportedVHWAPFs;
+static uint32_t g_SupportedVHWASDs;
+static uint32_t g_SupportedDDCaps;
+static uint32_t g_SupportedDDSCaps;
+static uint32_t g_SupportedDDPFs;
+static uint32_t g_SupportedDDSDs;
+
+static uint32_t g_SupportedVHWACKeyCaps;
+static uint32_t g_SupportedDDCKeyCaps;
+
+static uint32_t g_SupportedOVERs;
+static uint32_t g_SupportedCKEYs;
+
+
+void vboxVHWAInit()
+{
+    int i;
+    g_SupportedVHWACaps = 0;
+    g_SupportedVHWASCaps = 0;
+    g_SupportedVHWAPFs = 0;
+    g_SupportedVHWASDs = 0;
+    g_SupportedDDCaps = 0;
+    g_SupportedDDSCaps = 0;
+    g_SupportedDDPFs = 0;
+    g_SupportedDDSDs = 0;
+
+    g_SupportedVHWACKeyCaps = 0;
+    g_SupportedDDCKeyCaps = 0;
+
+    for(i = 0; i < sizeof(g_SupportedCapList)/sizeof(g_SupportedCapList[0]); i++)
+    {
+        g_SupportedDDCaps |= g_SupportedCapList[i][0];
+        g_SupportedVHWACaps |= g_SupportedCapList[i][1];
+    }
+
+    for(i = 0; i < sizeof(g_SupportedSCapList)/sizeof(g_SupportedSCapList[0]); i++)
+    {
+        g_SupportedDDSCaps |= g_SupportedSCapList[i][0];
+        g_SupportedVHWASCaps |= g_SupportedSCapList[i][1];
+    }
+
+    for(i = 0; i < sizeof(g_SupportedPFList)/sizeof(g_SupportedPFList[0]); i++)
+    {
+        g_SupportedDDPFs |= g_SupportedPFList[i][0];
+        g_SupportedVHWAPFs |= g_SupportedPFList[i][1];
+    }
+
+    for(i = 0; i < sizeof(gSupportedSDList)/sizeof(gSupportedSDList[0]); i++)
+    {
+        g_SupportedDDSDs |= gSupportedSDList[i][0];
+        g_SupportedVHWASDs |= gSupportedSDList[i][1];
+    }
+
+    for(i = 0; i < sizeof(g_SupportedCKeyCapList)/sizeof(g_SupportedCKeyCapList[0]); i++)
+    {
+        g_SupportedDDCKeyCaps |= g_SupportedCKeyCapList[i][0];
+        g_SupportedVHWACKeyCaps |= g_SupportedCKeyCapList[i][1];
+    }
+
+    g_SupportedOVERs = VBOXVHWA_OVER_DDFX
+                       | VBOXVHWA_OVER_HIDE
+                       | VBOXVHWA_OVER_KEYDEST
+                       | VBOXVHWA_OVER_KEYDESTOVERRIDE
+                       | VBOXVHWA_OVER_KEYSRC
+                       | VBOXVHWA_OVER_KEYSRCOVERRIDE
+                       | VBOXVHWA_OVER_SHOW;
+
+    g_SupportedCKEYs = VBOXVHWA_CKEY_COLORSPACE
+                       | VBOXVHWA_CKEY_DESTBLT
+                       | VBOXVHWA_CKEY_DESTOVERLAY
+                       | VBOXVHWA_CKEY_SRCBLT
+                       | VBOXVHWA_CKEY_SRCOVERLAY;
+}
+
+void vboxVHWATerm()
+{
+
+}
+
+uint32_t vboxVHWAUnsupportedDDCAPS(uint32_t caps)
+{
+    return caps & (~g_SupportedDDCaps);
+}
+
+uint32_t vboxVHWAUnsupportedDDSCAPS(uint32_t caps)
+{
+    return caps & (~g_SupportedDDSCaps);
+}
+
+uint32_t vboxVHWAUnsupportedDDPFS(uint32_t caps)
+{
+    return caps & (~g_SupportedDDPFs);
+}
+
+uint32_t vboxVHWAUnsupportedDSS(uint32_t caps)
+{
+    return caps & (~g_SupportedDDSDs);
+}
+
+uint32_t vboxVHWAUnsupportedDDCEYCAPS(uint32_t caps)
+{
+    return caps & (~g_SupportedDDCKeyCaps);
+}
+
+uint32_t vboxVHWASupportedDDCEYCAPS(uint32_t caps)
+{
+    return caps & (g_SupportedDDCKeyCaps);
+}
+
+
+uint32_t vboxVHWASupportedDDCAPS(uint32_t caps)
+{
+    return caps & (g_SupportedDDCaps);
+}
+
+uint32_t vboxVHWASupportedDDSCAPS(uint32_t caps)
+{
+    return caps & (g_SupportedDDSCaps);
+}
+
+uint32_t vboxVHWASupportedDDPFS(uint32_t caps)
+{
+    return caps & (g_SupportedDDPFs);
+}
+
+uint32_t vboxVHWASupportedDSS(uint32_t caps)
+{
+    return caps & (g_SupportedDDSDs);
+}
+
+uint32_t vboxVHWASupportedOVERs(uint32_t caps)
+{
+    return caps & (g_SupportedOVERs);
+}
+
+uint32_t vboxVHWAUnsupportedOVERs(uint32_t caps)
+{
+    return caps & (~g_SupportedOVERs);
+}
+
+uint32_t vboxVHWASupportedCKEYs(uint32_t caps)
+{
+    return caps & (g_SupportedCKEYs);
+}
+
+uint32_t vboxVHWAUnsupportedCKEYs(uint32_t caps)
+{
+    return caps & (~g_SupportedCKEYs);
+}
+
+uint32_t vboxVHWAFromDDOVERs(uint32_t caps) { return caps; }
+uint32_t vboxVHWAToDDOVERs(uint32_t caps)   { return caps; }
+uint32_t vboxVHWAFromDDCKEYs(uint32_t caps) { return caps; }
+uint32_t vboxVHWAToDDCKEYs(uint32_t caps)   { return caps; }
+
+void vboxVHWAFromDDOVERLAYFX(VBOXVHWA_OVERLAYFX *pVHWAOverlay, DDOVERLAYFX *pDdOverlay)
+{
+    //TODO: fxFlags
+    vboxVHWAFromDDCOLORKEY(&pVHWAOverlay->DstCK, &pDdOverlay->dckDestColorkey);
+    vboxVHWAFromDDCOLORKEY(&pVHWAOverlay->SrcCK, &pDdOverlay->dckSrcColorkey);
+}
+
+uint32_t vboxVHWAFromDDCAPS(uint32_t caps)
+{
+    uint32_t vhwaCaps = 0;
+    int i;
+    for(i = 0; i < sizeof(g_SupportedCapList)/sizeof(g_SupportedCapList[0]); i++)
+    {
+        if(caps & g_SupportedCapList[i][0])
+        {
+            vhwaCaps |= g_SupportedCapList[i][1];
+        }
+    }
+    return vhwaCaps;
+}
+
+uint32_t vboxVHWAToDDCAPS(uint32_t caps)
+{
+    uint32_t vhwaCaps = 0;
+    int i;
+    for(i = 0; i < sizeof(g_SupportedCapList)/sizeof(g_SupportedCapList[0]); i++)
+    {
+        if(caps & g_SupportedCapList[i][1])
+        {
+            vhwaCaps |= g_SupportedCapList[i][0];
+        }
+    }
+    return vhwaCaps;
+}
+
+uint32_t vboxVHWAFromDDCAPS2(uint32_t caps)
+{
+    return caps;
+}
+
+uint32_t vboxVHWAToDDCAPS2(uint32_t caps)
+{
+    return caps;
+}
+
+uint32_t vboxVHWAFromDDSCAPS(uint32_t caps)
+{
+    uint32_t vhwaCaps = 0;
+    int i;
+    for(i = 0; i < sizeof(g_SupportedSCapList)/sizeof(g_SupportedSCapList[0]); i++)
+    {
+        if(caps & g_SupportedSCapList[i][0])
+        {
+            vhwaCaps |= g_SupportedSCapList[i][1];
+        }
+    }
+    return vhwaCaps;
+}
+
+uint32_t vboxVHWAToDDSCAPS(uint32_t caps)
+{
+    uint32_t vhwaCaps = 0;
+    int i;
+    for(i = 0; i < sizeof(g_SupportedSCapList)/sizeof(g_SupportedSCapList[0]); i++)
+    {
+        if(caps & g_SupportedSCapList[i][1])
+        {
+            vhwaCaps |= g_SupportedSCapList[i][0];
+        }
+    }
+    return vhwaCaps;
+}
+
+uint32_t vboxVHWAFromDDPFS(uint32_t caps)
+{
+    uint32_t vhwaCaps = 0;
+    int i;
+    for(i = 0; i < sizeof(g_SupportedPFList)/sizeof(g_SupportedPFList[0]); i++)
+    {
+        if(caps & g_SupportedPFList[i][0])
+        {
+            vhwaCaps |= g_SupportedPFList[i][1];
+        }
+    }
+    return vhwaCaps;
+}
+
+uint32_t vboxVHWAToDDPFS(uint32_t caps)
+{
+    uint32_t vhwaCaps = 0;
+    int i;
+    for(i = 0; i < sizeof(g_SupportedPFList)/sizeof(g_SupportedPFList[0]); i++)
+    {
+        if(caps & g_SupportedPFList[i][1])
+        {
+            vhwaCaps |= g_SupportedPFList[i][0];
+        }
+    }
+    return vhwaCaps;
+}
+
+uint32_t vboxVHWAFromDDCKEYCAPS(uint32_t caps)
+{
+    uint32_t vhwaCaps = 0;
+    int i;
+    for(i = 0; i < sizeof(g_SupportedCKeyCapList)/sizeof(g_SupportedCKeyCapList[0]); i++)
+    {
+        if(caps & g_SupportedCKeyCapList[i][0])
+        {
+            vhwaCaps |= g_SupportedCKeyCapList[i][1];
+        }
+    }
+    return vhwaCaps;
+}
+
+uint32_t vboxVHWAToDDCKEYCAPS(uint32_t caps)
+{
+    uint32_t vhwaCaps = 0;
+    int i;
+    for(i = 0; i < sizeof(g_SupportedCKeyCapList)/sizeof(g_SupportedCKeyCapList[0]); i++)
+    {
+        if(caps & g_SupportedCKeyCapList[i][1])
+        {
+            vhwaCaps |= g_SupportedCKeyCapList[i][0];
+        }
+    }
+    return vhwaCaps;
+}
+
+uint32_t vboxVHWAToDDBLTs(uint32_t caps)
+{
+    return caps;
+}
+
+uint32_t vboxVHWAFromDDBLTs(uint32_t caps)
+{
+    return caps;
+}
+
+void vboxVHWAFromDDBLTFX(VBOXVHWA_BLTFX *pVHWABlt, DDBLTFX *pDdBlt)
+{
+//    pVHWABlt->flags;
+//    uint32_t rop;
+//    uint32_t rotationOp;
+//    uint32_t rotation;
+
+    pVHWABlt->fillColor = pDdBlt->dwFillColor;
+
+    vboxVHWAFromDDCOLORKEY(&pVHWABlt->DstCK, &pDdBlt->ddckDestColorkey);
+    vboxVHWAFromDDCOLORKEY(&pVHWABlt->SrcCK, &pDdBlt->ddckSrcColorkey);
+}
+
+int vboxVHWAFromDDPIXELFORMAT(VBOXVHWA_PIXELFORMAT *pVHWAFormat, DDPIXELFORMAT *pDdFormat)
+{
+    uint32_t unsup = vboxVHWAUnsupportedDDPFS(pDdFormat->dwFlags);
+    Assert(!unsup);
+    if(unsup)
+        return VERR_GENERAL_FAILURE;
+
+    pVHWAFormat->flags = vboxVHWAFromDDPFS(pDdFormat->dwFlags);
+    pVHWAFormat->fourCC = pDdFormat->dwFourCC;
+    pVHWAFormat->c.rgbBitCount = pDdFormat->dwRGBBitCount;
+    pVHWAFormat->m1.rgbRBitMask = pDdFormat->dwRBitMask;
+    pVHWAFormat->m2.rgbGBitMask = pDdFormat->dwGBitMask;
+    pVHWAFormat->m3.rgbBBitMask = pDdFormat->dwBBitMask;
+    return VINF_SUCCESS;
+}
+
+void vboxVHWAFromDDCOLORKEY(VBOXVHWA_COLORKEY *pVHWACKey, DDCOLORKEY  *pDdCKey)
+{
+    pVHWACKey->low = pDdCKey->dwColorSpaceLowValue;
+    pVHWACKey->high = pDdCKey->dwColorSpaceHighValue;
+}
+
+int vboxVHWAFromDDSURFACEDESC(VBOXVHWA_SURFACEDESC *pVHWADesc, DDSURFACEDESC *pDdDesc)
+{
+    uint32_t unsupds = vboxVHWAUnsupportedDSS(pDdDesc->dwFlags);
+    Assert(!unsupds);
+    if(unsupds)
+        return VERR_GENERAL_FAILURE;
+
+    pVHWADesc->flags = 0;
+
+    if(pDdDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
+    {
+        pVHWADesc->flags |= VBOXVHWA_SD_BACKBUFFERCOUNT;
+        pVHWADesc->cBackBuffers = pDdDesc->dwBackBufferCount;
+    }
+    if(pDdDesc->dwFlags & DDSD_CAPS)
+    {
+        uint32_t unsup = vboxVHWAUnsupportedDDSCAPS(pDdDesc->ddsCaps.dwCaps);
+        Assert(!unsup);
+        if(unsup)
+            return VERR_GENERAL_FAILURE;
+        pVHWADesc->flags |= VBOXVHWA_SD_CAPS;
+        pVHWADesc->surfCaps = vboxVHWAFromDDSCAPS(pDdDesc->ddsCaps.dwCaps);
+    }
+    if(pDdDesc->dwFlags & DDSD_CKDESTBLT)
+    {
+        pVHWADesc->flags |= VBOXVHWA_SD_CKDESTBLT;
+        vboxVHWAFromDDCOLORKEY(&pVHWADesc->DstBltCK, &pDdDesc->ddckCKDestBlt);
+    }
+    if(pDdDesc->dwFlags & DDSD_CKDESTOVERLAY)
+    {
+        pVHWADesc->flags |= VBOXVHWA_SD_CKDESTOVERLAY;
+        vboxVHWAFromDDCOLORKEY(&pVHWADesc->DstOverlayCK, &pDdDesc->ddckCKDestOverlay);
+    }
+    if(pDdDesc->dwFlags & DDSD_CKSRCBLT)
+    {
+        pVHWADesc->flags |= VBOXVHWA_SD_CKSRCBLT;
+        vboxVHWAFromDDCOLORKEY(&pVHWADesc->SrcBltCK, &pDdDesc->ddckCKSrcBlt);
+    }
+    if(pDdDesc->dwFlags & DDSD_CKSRCOVERLAY)
+    {
+        pVHWADesc->flags |= VBOXVHWA_SD_CKSRCOVERLAY;
+        vboxVHWAFromDDCOLORKEY(&pVHWADesc->SrcOverlayCK, &pDdDesc->ddckCKSrcOverlay);
+    }
+    if(pDdDesc->dwFlags & DDSD_HEIGHT)
+    {
+        pVHWADesc->flags |= VBOXVHWA_SD_HEIGHT;
+        pVHWADesc->height = pDdDesc->dwHeight;
+    }
+    if(pDdDesc->dwFlags & DDSD_WIDTH)
+    {
+        pVHWADesc->flags |= VBOXVHWA_SD_WIDTH;
+        pVHWADesc->width = pDdDesc->dwWidth;
+    }
+    if(pDdDesc->dwFlags & DDSD_PITCH)
+    {
+        pVHWADesc->flags |= VBOXVHWA_SD_PITCH;
+        pVHWADesc->pitch = pDdDesc->lPitch;
+    }
+    if(pDdDesc->dwFlags & DDSD_PIXELFORMAT)
+    {
+        int rc = vboxVHWAFromDDPIXELFORMAT(&pVHWADesc->PixelFormat, &pDdDesc->ddpfPixelFormat);
+        if(RT_FAILURE(rc))
+            return rc;
+        pVHWADesc->flags |= VBOXVHWA_SD_PIXELFORMAT;
+    }
+    return VINF_SUCCESS;
+}
+
+void vboxVHWAFromRECTL(VBOXVHWA_RECTL *pDst, RECTL *pSrc)
+{
+//    Assert(pSrc->left <= pSrc->right);
+//    Assert(pSrc->top <= pSrc->bottom);
+    pDst->left = pSrc->left;
+    pDst->top = pSrc->top;
+    pDst->right = pSrc->right;
+    pDst->bottom = pSrc->bottom;
+}
+
+#define MIN(_a, _b) (_a) < (_b) ? (_a) : (_b)
+#define MAX(_a, _b) (_a) > (_b) ? (_a) : (_b)
+
+void vboxVHWARectUnited(RECTL * pDst, RECTL * pRect1, RECTL * pRect2)
+{
+    pDst->left = MIN(pRect1->left, pRect2->left);
+    pDst->top = MIN(pRect1->top, pRect2->top);
+    pDst->right = MAX(pRect1->right, pRect2->right);
+    pDst->bottom = MAX(pRect1->bottom, pRect2->bottom);
+}
+
+bool vboxVHWARectIsEmpty(RECTL * pRect)
+{
+    return pRect->left == pRect->right-1 && pRect->top == pRect->bottom-1;
+}
+
+bool vboxVHWARectIntersect(RECTL * pRect1, RECTL * pRect2)
+{
+    return !((pRect1->left < pRect2->left && pRect1->right < pRect2->left)
+            || (pRect2->left < pRect1->left && pRect2->right < pRect1->left)
+            || (pRect1->top < pRect2->top && pRect1->bottom < pRect2->top)
+            || (pRect2->top < pRect1->top && pRect2->bottom < pRect1->top));
+}
+
+bool vboxVHWARectInclude(RECTL * pRect1, RECTL * pRect2)
+{
+    return ((pRect1->left <= pRect2->left && pRect1->right >= pRect2->right)
+            && (pRect1->top <= pRect2->top && pRect1->bottom >= pRect2->bottom));
+}
+
+
+bool vboxVHWARegionIntersects(PVBOXVHWAREGION pReg, RECTL * pRect)
+{
+    if(!pReg->bValid)
+        return false;
+    return vboxVHWARectIntersect(&pReg->Rect, pRect);
+}
+
+bool vboxVHWARegionIncludes(PVBOXVHWAREGION pReg, RECTL * pRect)
+{
+    if(!pReg->bValid)
+        return false;
+    return vboxVHWARectInclude(&pReg->Rect, pRect);
+}
+
+bool vboxVHWARegionIncluded(PVBOXVHWAREGION pReg, RECTL * pRect)
+{
+    if(!pReg->bValid)
+        return true;
+    return vboxVHWARectInclude(pRect, &pReg->Rect);
+}
+
+void vboxVHWARegionSet(PVBOXVHWAREGION pReg, RECTL * pRect)
+{
+    if(vboxVHWARectIsEmpty(pRect))
+    {
+        pReg->bValid = false;
+    }
+    else
+    {
+        pReg->Rect = *pRect;
+        pReg->bValid = true;
+    }
+}
+
+void vboxVHWARegionAdd(PVBOXVHWAREGION pReg, RECTL * pRect)
+{
+    if(vboxVHWARectIsEmpty(pRect))
+    {
+        return;
+    }
+    else if(!pReg->bValid)
+    {
+        vboxVHWARegionSet(pReg, pRect);
+    }
+    else
+    {
+        vboxVHWARectUnited(&pReg->Rect, &pReg->Rect, pRect);
+    }
+}
+
+void vboxVHWARegionInit(PVBOXVHWAREGION pReg)
+{
+    pReg->bValid = false;
+}
+
+void vboxVHWARegionClear(PVBOXVHWAREGION pReg)
+{
+    pReg->bValid = false;
+}
+
+bool vboxVHWARegionValid(PVBOXVHWAREGION pReg)
+{
+    return pReg->bValid;
+}
+
+void vboxVHWARegionTrySubstitute(PVBOXVHWAREGION pReg, const RECTL *pRect)
+{
+    if(!pReg->bValid)
+        return;
+
+    if(pReg->Rect.left >= pRect->left && pReg->Rect.right <= pRect->right)
+    {
+        LONG t = MAX(pReg->Rect.top, pRect->top);
+        LONG b = MIN(pReg->Rect.bottom, pRect->bottom);
+        if(t < b)
+        {
+            pReg->Rect.top = t;
+            pReg->Rect.bottom = b;
+        }
+        else
+        {
+            pReg->bValid = false;
+        }
+    }
+    else if(pReg->Rect.top >= pRect->top && pReg->Rect.bottom <= pRect->bottom)
+    {
+        LONG l = MAX(pReg->Rect.left, pRect->left);
+        LONG r = MIN(pReg->Rect.right, pRect->right);
+        if(l < r)
+        {
+            pReg->Rect.left = l;
+            pReg->Rect.right = r;
+        }
+        else
+        {
+            pReg->bValid = false;
+        }
+    }
+}
