Ejemplo n.º 1
0
/** Set a graphics mode.  Poke any required values into registers, do an HGSMI
 * mode set and tell the host we support advanced graphics functions.
 */
static void vbox_do_modeset(struct drm_crtc *crtc,
                            const struct drm_display_mode *mode)
{
    struct vbox_crtc   *vbox_crtc = to_vbox_crtc(crtc);
    struct vbox_private *vbox;
    int width, height, cBPP, pitch;
    unsigned iCrtc;
    uint16_t fFlags;

    LogFunc(("vboxvideo: %d: vbox_crtc=%p, CRTC_FB(crtc)=%p\n", __LINE__,
             vbox_crtc, CRTC_FB(crtc)));
    vbox = crtc->dev->dev_private;
    width = mode->hdisplay ? mode->hdisplay : 640;
    height = mode->vdisplay ? mode->vdisplay : 480;
    iCrtc = vbox_crtc->crtc_id;
    cBPP = crtc->enabled ? CRTC_FB(crtc)->bits_per_pixel : 32;
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
    pitch = crtc->enabled ? CRTC_FB(crtc)->pitch : width * cBPP / 8;
#else
    pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * cBPP / 8;
#endif
    /* if (vbox_crtc->crtc_id == 0 && crtc->enabled)
        VBoxVideoSetModeRegisters(width, height, pitch * 8 / cBPP,
                                  CRTC_FB(crtc)->bits_per_pixel, 0,
                                  crtc->x, crtc->y); */
    fFlags = VBVA_SCREEN_F_ACTIVE;
    fFlags |= (crtc->enabled ? 0 : VBVA_SCREEN_F_DISABLED);
    VBoxHGSMIProcessDisplayInfo(&vbox->Ctx, vbox_crtc->crtc_id,
                                crtc->x, crtc->y,
                                crtc->x * cBPP / 8 + crtc->y * pitch,
                                pitch, width, height,
                                vbox_crtc->fBlanked ? 0 : cBPP, fFlags);
    LogFunc(("vboxvideo: %d\n", __LINE__));
}
Ejemplo n.º 2
0
/* Called to notify driver about various events */
VOID APIENTRY VBoxDispDrvNotify(SURFOBJ *pso, ULONG iType, PVOID pvData)
{
    PVBOXDISPDEV pDev = (PVBOXDISPDEV)pso->dhpdev;
    LOGF_ENTER();

    switch (iType)
    {
        case DN_DEVICE_ORIGIN:
        {
            /*device origin in dualview*/
            POINTL *pOrg = (POINTL *)pvData;
            if (pOrg)
            {
                LOG(("DN_DEVICE_ORIGIN (pso=%p, pDev[%d]=%p) old=%d,%d new=%d,%d",
                     pso, pDev->iDevice, pDev, pDev->orgDev.x, pDev->orgDev.y, pOrg->x, pOrg->y));
                if (pDev->orgDev.x!=pOrg->x || pDev->orgDev.y!=pOrg->y)
                {
                    pDev->orgDev = *pOrg;

                    /* Inform host about display change */
                    VBoxHGSMIProcessDisplayInfo(&pDev->hgsmi.ctx, pDev->iDevice, pDev->orgDev.x, pDev->orgDev.y,
                                                0, abs(pDev->mode.lScanlineStride),
                                                pDev->mode.ulWidth, pDev->mode.ulHeight,
                                                (uint16_t)pDev->mode.ulBitsPerPel, VBVA_SCREEN_F_ACTIVE);
                }
            }
            else
            {
                WARN(("DN_DEVICE_ORIGIN pvData==NULL"));
            }

            break;
        }
        case DN_DRAWING_BEGIN:
        {
            /*first drawing op is about to happen for this device*/
            LOG(("DN_DRAWING_BEGIN (pso=%p, pDev[%d]=%p)", pso, pDev->iDevice, pDev));
            break;
        }
        default:
        {
            LOG(("unknown iType=%#x", iType));
        }
    }

    LOGF_LEAVE();
    return;
}
Ejemplo n.º 3
0
/** Set a graphics mode.  Poke any required values into registers, do an HGSMI
 * mode set and tell the host we support advanced graphics functions.  This
 * procedure is complicated by the fact that X.Org can implicitly disable a
 * screen by resizing the virtual framebuffer so that the screen is no longer
 * inside it.  We have to spot and handle this.
 */
Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
                 unsigned cHeight, int x, int y)
{
    VBOXPtr pVBox = VBOXGetRec(pScrn);
    uint32_t offStart, cwReal = cWidth;

    TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n",
              cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth);
    offStart = y * pVBox->cbLine + x * vboxBPP(pScrn) / 8;
    /* Deactivate the screen if the mode - specifically the virtual width - is
     * too large for VRAM as we sometimes have to do this - see comments in
     * VBOXPreInit. */
    if (   offStart + pVBox->cbLine * cHeight > pVBox->cbFBMax
        || pVBox->cbLine * pScrn->virtualY > pVBox->cbFBMax)
        return FALSE;
    /* Deactivate the screen if it is outside of the virtual framebuffer and
     * clamp it to lie inside if it is partly outside. */
    if (x >= pScrn->displayWidth || x + (int) cWidth <= 0)
        return FALSE;
    else
        cwReal = RT_MIN((int) cWidth, pScrn->displayWidth - x);
    TRACE_LOG("pVBox->afDisabled[%u]=%d\n",
              cDisplay, (int)pVBox->afDisabled[cDisplay]);
    if (cDisplay == 0)
        VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth,
                                  vboxBPP(pScrn), 0, x, y);
    /* Tell the host we support graphics */
    if (vbox_device_available(pVBox))
        vboxEnableGraphicsCap(pVBox);
    if (pVBox->fHaveHGSMI)
    {
        uint16_t fFlags = VBVA_SCREEN_F_ACTIVE;
        fFlags |= (pVBox->afDisabled[cDisplay] ? VBVA_SCREEN_F_DISABLED : 0);
        VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y,
                                    offStart, pVBox->cbLine, cwReal, cHeight,
                                    vboxBPP(pScrn), fFlags);
    }
    return TRUE;
}
Ejemplo n.º 4
0
/* Called to reset device to default mode or to mode specified with dhpdev */
BOOL APIENTRY VBoxDispDrvAssertMode(DHPDEV dhpdev, BOOL bEnable)
{
    PVBOXDISPDEV pDev = (PVBOXDISPDEV) dhpdev;
    DWORD dwrc;
    int rc;
    LOGF_ENTER();

    if (!bEnable)
    {
        LOGF(("!bEnable"));
#ifdef VBOX_WITH_VIDEOHWACCEL
        /* tells we can not process host commands any more and ensures that
         * we've completed processing of the host VHWA commands
         */
        VBoxDispVHWADisable(pDev);
#endif

        /* disable VBVA */
        if (pDev->hgsmi.bSupported)
        {
            VBoxVBVADisable(&pDev->vbvaCtx, &pDev->hgsmi.ctx, -1);
        }

        /* reset the device to default mode */
        rc = VBoxDispMPResetDevice(pDev->hDriver);
        VBOX_WARNRC_RETV(rc, FALSE);
    }
    else
    {
        LOGF(("bEnable"));

        /* switch device to previous pDev mode */
        rc = VBoxDispMPSetCurrentMode(pDev->hDriver, pDev->mode.ulIndex);
        VBOX_WARNRC_RETV(rc, NULL);

        /* enable VBVA */
        if (pDev->hgsmi.bSupported)
        {
            if (pDev->mode.ulBitsPerPel==16 || pDev->mode.ulBitsPerPel==24 || pDev->mode.ulBitsPerPel==32)
            {
                VBVABUFFER *pVBVA = (VBVABUFFER *)((uint8_t *)pDev->memInfo.VideoRamBase+pDev->layout.offVBVABuffer);
                pDev->hgsmi.bSupported = VBoxVBVAEnable(&pDev->vbvaCtx, &pDev->hgsmi.ctx, pVBVA, -1);
                LogRel(("VBoxDisp[%d]: VBVA %senabled\n", pDev->iDevice, pDev->hgsmi.bSupported? "":"not "));
            }
        }

        /* inform host */
        if (pDev->hgsmi.bSupported)
        {
            VBoxHGSMIProcessDisplayInfo(&pDev->hgsmi.ctx, pDev->iDevice, pDev->orgDev.x, pDev->orgDev.y,
                                        0, abs(pDev->mode.lScanlineStride), pDev->mode.ulWidth, pDev->mode.ulHeight,
                                        (uint16_t)pDev->mode.ulBitsPerPel, VBVA_SCREEN_F_ACTIVE);
        }

#ifdef VBOX_WITH_VIDEOHWACCEL
        /* tells we can process host commands */
       VBoxDispVHWAEnable(pDev);
#endif

        /* Associate back GDI bitmap residing in our framebuffer memory with GDI's handle to our device */
        dwrc = EngAssociateSurface((HSURF)pDev->surface.hBitmap, pDev->hDevGDI, 0);
        if (dwrc != NO_ERROR)
        {
            WARN(("EngAssociateSurface on bitmap failed with %#x", dwrc));
            return FALSE;
        }

        /* Associate device managed surface with GDI's handle to our device */
        dwrc = EngAssociateSurface(pDev->surface.hSurface, pDev->hDevGDI, pDev->flDrawingHooks);
        if (dwrc != NO_ERROR)
        {
            WARN(("EngAssociateSurface on surface failed with %#x", dwrc));
            return FALSE;
        }
    }

    LOGF_LEAVE();
    return TRUE;
}
Ejemplo n.º 5
0
/* Called to create and associate surface with device */
HSURF APIENTRY VBoxDispDrvEnableSurface(DHPDEV dhpdev)
{
    int rc;
    PVBOXDISPDEV pDev = (PVBOXDISPDEV)dhpdev;

    LOGF_ENTER();

    /* Switch device to mode requested in VBoxDispDrvEnablePDEV */
    rc = VBoxDispMPSetCurrentMode(pDev->hDriver, pDev->mode.ulIndex);
    VBOX_WARNRC_RETV(rc, NULL);

    /* Map fb and vram */
    rc = VBoxDispMPMapMemory(pDev, &pDev->memInfo);
    VBOX_WARNRC_RETV(rc, NULL);

    /* Clear mapped memory, to avoid garbage while video mode is switching */
    /* @todo: VIDEO_MODE_NO_ZERO_MEMORY does nothing in miniport's IOCTL_VIDEO_SET_CURRENT_MODE*/
    memset(pDev->memInfo.FrameBufferBase, 0, pDev->mode.ulHeight * abs(pDev->mode.lScanlineStride));

    /* Allocate memory for pointer attrs */
    rc = VBoxDispInitPointerAttrs(pDev);
    VBOX_WARNRC_RETV(rc, NULL);

    /* Init VBVA */
    rc = VBoxDispVBVAInit(pDev);
    VBOX_WARNRC_RETV(rc, NULL);

    /* Enable VBVA */
    if (pDev->hgsmi.bSupported)
    {
        if (pDev->mode.ulBitsPerPel==16 || pDev->mode.ulBitsPerPel==24 || pDev->mode.ulBitsPerPel==32)
        {
            VBVABUFFER *pVBVA = (VBVABUFFER *)((uint8_t *)pDev->memInfo.VideoRamBase+pDev->layout.offVBVABuffer);
            pDev->hgsmi.bSupported = VBoxVBVAEnable(&pDev->vbvaCtx, &pDev->hgsmi.ctx, pVBVA, -1);
            LogRel(("VBoxDisp[%d]: VBVA %senabled\n", pDev->iDevice, pDev->hgsmi.bSupported? "":"not "));
        }
    }

    /* Inform host */
    if (pDev->hgsmi.bSupported)
    {
        VBoxHGSMIProcessDisplayInfo(&pDev->hgsmi.ctx, pDev->iDevice, pDev->orgDev.x, pDev->orgDev.y,
                                    0, abs(pDev->mode.lScanlineStride), pDev->mode.ulWidth, pDev->mode.ulHeight,
                                    (uint16_t)pDev->mode.ulBitsPerPel, VBVA_SCREEN_F_ACTIVE);
    }

#ifdef VBOX_WITH_VIDEOHWACCEL
    VBoxDispVHWAEnable(pDev);
#endif

    /* Set device palette if needed */
    if (pDev->mode.ulBitsPerPel == 8)
    {
        rc = VBoxDispSetPalette8BPP(pDev);
        VBOX_WARNRC_RETV(rc, NULL);
    }

    pDev->orgDisp.x = 0;
    pDev->orgDisp.y = 0;

    /* Create GDI managed bitmap, which resides in our framebuffer memory */
    ULONG iFormat;
    SIZEL size;

    switch (pDev->mode.ulBitsPerPel)
    {
        case 8:
        {
            iFormat = BMF_8BPP;
            break;
        }
        case 16:
        {
            iFormat = BMF_16BPP;
            break;
        }
        case 24:
        {
            iFormat = BMF_24BPP;
            break;
        }
        case 32:
        {
            iFormat = BMF_32BPP;
            break;
        }
    }

    size.cx = pDev->mode.ulWidth;
    size.cy = pDev->mode.ulHeight;

    pDev->surface.hBitmap = EngCreateBitmap(size, pDev->mode.lScanlineStride, iFormat,
                                            pDev->mode.lScanlineStride>0 ? BMF_TOPDOWN:0,
                                            pDev->memInfo.FrameBufferBase);
    if (!pDev->surface.hBitmap)
    {
        WARN(("EngCreateBitmap failed!"));
        return NULL;
    }
    pDev->surface.psoBitmap = EngLockSurface((HSURF)pDev->surface.hBitmap);

    /* Create device-managed surface */
    pDev->surface.hSurface = EngCreateDeviceSurface((DHSURF)pDev, size, iFormat);
    if (!pDev->surface.hSurface)
    {
        WARN(("EngCreateDeviceSurface failed!"));
        VBoxDispDrvDisableSurface(dhpdev);
        return NULL;
    }

    FLONG flHooks = HOOK_BITBLT|HOOK_TEXTOUT|HOOK_FILLPATH|HOOK_COPYBITS|HOOK_STROKEPATH|HOOK_LINETO|
                    HOOK_PAINT|HOOK_STRETCHBLT;

    /* Associate created surface with our device */
    if (!EngAssociateSurface(pDev->surface.hSurface, pDev->hDevGDI, flHooks))
    {
        WARN(("EngAssociateSurface failed!"));
        VBoxDispDrvDisableSurface(dhpdev);
        return NULL;
    }

    pDev->surface.ulFormat = iFormat;
    pDev->flDrawingHooks = flHooks;

    LOG(("Created surface %p for physical device %p", pDev->surface.hSurface, pDev));

    LOGF_LEAVE();
    return pDev->surface.hSurface;
}
/* Process Video Request Packet. */
static BOOLEAN
VBoxDrvStartIO(PVOID HwDeviceExtension, PVIDEO_REQUEST_PACKET RequestPacket)
{
    PVBOXMP_DEVEXT pExt = (PVBOXMP_DEVEXT) HwDeviceExtension;
    PSTATUS_BLOCK  pStatus = RequestPacket->StatusBlock;
    BOOLEAN        bResult = FALSE;

    PAGED_CODE();

    LOGF(("IOCTL %#x, fn(%#x)", RequestPacket->IoControlCode, (RequestPacket->IoControlCode >> 2) & 0xFFF));

    pStatus->Status = NO_ERROR;

    switch (RequestPacket->IoControlCode)
    {
        /* ==================== System VRPs ==================== */

        /*Maps FrameBuffer and video RAM to a caller's virtual adress space.*/
        case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
        {
            STARTIO_IN(VIDEO_MEMORY, pMemory);
            STARTIO_OUT(VIDEO_MEMORY_INFORMATION, pMemInfo);

            bResult = VBoxMPMapVideoMemory(pExt, pMemory, pMemInfo, pStatus);
            break;
        }

        /*Unmaps previously mapped FrameBuffer and video RAM from caller's virtual adress space.*/
        case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
        {
            STARTIO_IN(VIDEO_MEMORY, pMemory);

            bResult = VBoxMPUnmapVideoMemory(pExt, pMemory, pStatus);
            break;
        }

        /*Maps FrameBuffer as a linear frame buffer to a caller's virtual adress space. (obsolete)*/
        case IOCTL_VIDEO_SHARE_VIDEO_MEMORY:
        {
            STARTIO_IN(VIDEO_SHARE_MEMORY, pShareMemory);
            STARTIO_OUT(VIDEO_SHARE_MEMORY_INFORMATION, pShareMemInfo);

            bResult = VBoxMPShareVideoMemory(pExt, pShareMemory, pShareMemInfo, pStatus);
            break;
        }

        /*Unmaps framebuffer previously mapped with IOCTL_VIDEO_SHARE_VIDEO_MEMORY*/
        case IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY:
        {
            STARTIO_IN(VIDEO_SHARE_MEMORY, pShareMemory);

            bResult = VBoxMPUnshareVideoMemory(pExt, pShareMemory, pStatus);
            break;
        }

        /*Reset device to a state it comes at system boot time.*/
        case IOCTL_VIDEO_RESET_DEVICE:
        {
            bResult = VBoxMPResetDevice(pExt, pStatus);
            break;
        }

        /*Set adapter video mode.*/
        case IOCTL_VIDEO_SET_CURRENT_MODE:
        {
            STARTIO_IN(VIDEO_MODE, pMode);

            bResult = VBoxMPSetCurrentMode(pExt, pMode, pStatus);
            break;
        }

        /*Returns information about current video mode.*/
        case IOCTL_VIDEO_QUERY_CURRENT_MODE:
        {
            STARTIO_OUT(VIDEO_MODE_INFORMATION, pModeInfo);

            bResult = VBoxMPQueryCurrentMode(pExt, pModeInfo, pStatus);
            break;
        }

        /* Returns count of supported video modes and structure size in bytes,
         * used to allocate buffer for the following IOCTL_VIDEO_QUERY_AVAIL_MODES call.
         */
        case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
        {
            STARTIO_OUT(VIDEO_NUM_MODES, pNumModes);

            bResult = VBoxMPQueryNumAvailModes(pExt, pNumModes, pStatus);
            break;
        }

        /* Returns information about supported video modes. */
        case IOCTL_VIDEO_QUERY_AVAIL_MODES:
        {
            PVIDEO_MODE_INFORMATION pModes = (PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer;

            if (RequestPacket->OutputBufferLength < VBoxMPXpdmGetVideoModesCount(pExt)*sizeof(VIDEO_MODE_INFORMATION))
            {
                pStatus->Status = ERROR_INSUFFICIENT_BUFFER;
                break;
            }

            bResult = VBoxMPQueryAvailModes(pExt, pModes, pStatus);
            break;
        }

        /* Sets adapter's color registers, have to be implemented if we support palette based modes. */
        case IOCTL_VIDEO_SET_COLOR_REGISTERS:
        {
            STARTIO_IN(VIDEO_CLUT, pClut);

            if (RequestPacket->InputBufferLength < (sizeof(VIDEO_CLUT) + pClut->NumEntries * sizeof(ULONG)))
            {
                pStatus->Status = ERROR_INSUFFICIENT_BUFFER;
                break;
            }

            bResult = VBoxMPSetColorRegisters(pExt, pClut, pStatus);
            break;
        }

        /* Sets pointer attributes. */
        case IOCTL_VIDEO_SET_POINTER_ATTR:
        {
            STARTIO_IN(VIDEO_POINTER_ATTRIBUTES, pPointerAttrs);

            bResult = VBoxMPSetPointerAttr(pExt, pPointerAttrs, RequestPacket->InputBufferLength, pStatus);
            break;
        }

        /* Makes pointer visible. */
        case IOCTL_VIDEO_ENABLE_POINTER:
        {
            bResult = VBoxMPEnablePointer(pExt, TRUE, pStatus);
            break;
        }

        /* Hides pointer. */
        case IOCTL_VIDEO_DISABLE_POINTER:
        {
            bResult = VBoxMPEnablePointer(pExt, FALSE, pStatus);
            break;
        }

        /* Sets pointer position, is called after IOCTL_VIDEO_ENABLE_POINTER. */
        case IOCTL_VIDEO_SET_POINTER_POSITION:
        {
            STARTIO_IN(VIDEO_POINTER_POSITION, pPos);

            NOREF(pPos); /** @todo set pointer position*/
            bResult = VBoxMPEnablePointer(pExt, TRUE, pStatus);
            break;
        }

        /* Query pointer position. */
        case IOCTL_VIDEO_QUERY_POINTER_POSITION:
        {
            STARTIO_OUT(VIDEO_POINTER_POSITION, pPos);

            bResult = VBoxMPQueryPointerPosition(pExt, pPos, pStatus);
            break;
        }

        /* Query supported hardware pointer feaures. */
        case IOCTL_VIDEO_QUERY_POINTER_CAPABILITIES:
        {
            STARTIO_OUT(VIDEO_POINTER_CAPABILITIES, pCaps);

            bResult = VBoxMPQueryPointerCapabilities(pExt, pCaps, pStatus);
            break;
        }

        /* Query pointer attributes. (optional) */
        case IOCTL_VIDEO_QUERY_POINTER_ATTR:
        {
            STARTIO_OUT(VIDEO_POINTER_ATTRIBUTES, pPointerAttrs);

            NOREF(pPointerAttrs); /* Not Implemented */
            pStatus->Status = ERROR_INVALID_FUNCTION;

            bResult = FALSE;
            break;
        }

        /* Called when a secondary adapter is about to be enabled/disabled. */
        case IOCTL_VIDEO_SWITCH_DUALVIEW:
        {
            STARTIO_IN(ULONG, pAttach);

            LOGF(("IOCTL_VIDEO_SWITCH_DUALVIEW: [%d] attach = %d", pExt->iDevice, *pAttach));

            if (pExt->iDevice>0)
            {
                pExt->u.secondary.bEnabled = (BOOLEAN)(*pAttach);

                /* Inform the host.
                 * Currently only about secondary devices, because the driver does not support
                 * disconnecting the primary display (it does not allow to change the primary display).
                 */
                if (!pExt->u.secondary.bEnabled)
                {
                    PVBOXMP_COMMON pCommon = VBoxCommonFromDeviceExt(pExt);
                    if (pCommon->bHGSMI)
                    {
                        VBoxHGSMIProcessDisplayInfo(&pCommon->guestCtx, pExt->iDevice,
                                                    /* cOriginX = */ 0, /* cOriginY = */ 0,
                                                    /* offStart = */ 0, /* cbPitch = */ 0,
                                                    /* cWidth = */ 0, /* cHeight = */ 0, /* cBPP = */ 0,
                                                    VBVA_SCREEN_F_ACTIVE | VBVA_SCREEN_F_DISABLED);
                    }
                }
            }

            bResult = TRUE;
            break;
        }

        /* Called to get child device status */
        case IOCTL_VIDEO_GET_CHILD_STATE:
        {
            STARTIO_IN(ULONG, pChildIndex);
            STARTIO_OUT(ULONG, pChildState);

            LOGF(("IOCTL_VIDEO_GET_CHILD_STATE: [%d] idx = %d", pExt->iDevice, *pChildIndex));

            if (*pChildIndex>0 && *pChildIndex<=(ULONG)VBoxCommonFromDeviceExt(pExt)->cDisplays)
            {
                *pChildState = VIDEO_CHILD_ACTIVE;
                pStatus->Information = sizeof(ULONG);
                bResult = TRUE;
            }
            else
            {
                pStatus->Status = ERROR_INVALID_PARAMETER;
                bResult = FALSE;
            }

            break;
        }

        /* ==================== VirtualBox specific VRPs ==================== */

        /* Called by the display driver when it is ready to switch to VBVA operation mode. */
        case IOCTL_VIDEO_VBVA_ENABLE:
        {
            STARTIO_IN(ULONG, pEnable);
            STARTIO_OUT(VBVAENABLERESULT, pResult);

            bResult = VBoxMPVBVAEnable(pExt, (BOOLEAN)*pEnable, pResult, pStatus);
            break;
        }

        /* Called by the display driver when it recieves visible regions information. */
        case IOCTL_VIDEO_VBOX_SETVISIBLEREGION:
        {
            STARTIO_IN(RTRECT, pRects);

            uint32_t cRects = RequestPacket->InputBufferLength/sizeof(RTRECT);
            /*Sanity check*/
            if (   cRects > _1M
                || RequestPacket->InputBufferLength != cRects * sizeof(RTRECT))
            {
                pStatus->Status = ERROR_INSUFFICIENT_BUFFER;
                break;
            }

            bResult = VBoxMPSetVisibleRegion(cRects, pRects, pStatus);
            break;
        }

        /* Returns video port api function pointers. */
        case IOCTL_VIDEO_HGSMI_QUERY_PORTPROCS:
        {
            STARTIO_OUT(HGSMIQUERYCPORTPROCS, pProcs);

            bResult = VBoxMPHGSMIQueryPortProcs(pExt, pProcs, pStatus);
            break;
        }

        /* Returns HGSMI related callbacks. */
        case IOCTL_VIDEO_HGSMI_QUERY_CALLBACKS:
        {
            STARTIO_OUT(HGSMIQUERYCALLBACKS, pCallbacks);

            bResult = VBoxMPHGSMIQueryCallbacks(pExt, pCallbacks, pStatus);
            break;
        }

        /* Returns hgsmi info for this adapter. */
        case IOCTL_VIDEO_QUERY_HGSMI_INFO:
        {
            STARTIO_OUT(QUERYHGSMIRESULT, pResult);

            bResult = VBoxMPQueryHgsmiInfo(pExt, pResult, pStatus);
            break;
        }

        /* Enables HGSMI miniport channel. */
        case IOCTL_VIDEO_HGSMI_HANDLER_ENABLE:
        {
            STARTIO_IN(HGSMIHANDLERENABLE, pChannel);

            bResult = VBoxMPHgsmiHandlerEnable(pExt, pChannel, pStatus);
            break;
        }

        case IOCTL_VIDEO_HGSMI_HANDLER_DISABLE:
        {
            /** @todo not implemented */
            break;
        }

#ifdef VBOX_WITH_VIDEOHWACCEL
        /* Returns framebuffer offset. */
        case IOCTL_VIDEO_VHWA_QUERY_INFO:
        {
            STARTIO_OUT(VHWAQUERYINFO, pInfo);

            bResult = VBoxMPVhwaQueryInfo(pExt, pInfo, pStatus);
            break;
        }
#endif

        case IOCTL_VIDEO_VBOX_ISANYX:
        {
            STARTIO_OUT(uint32_t, pu32AnyX);
            *pu32AnyX = VBoxCommonFromDeviceExt(pExt)->fAnyX;
            pStatus->Information = sizeof (uint32_t);
            bResult = TRUE;
            break;
        }

        case IOCTL_VIDEO_QUERY_VBOXVIDEO_INFO:
        {
            STARTIO_IN(ULONG, pulInfoLevel);
            if (*pulInfoLevel == VBOXVIDEO_INFO_LEVEL_REGISTRY_FLAGS)
            {
                STARTIO_OUT(ULONG, pulFlags);
                bResult = VBoxMPQueryRegistryFlags(pExt, pulFlags, pStatus);
            }
            else
            {
                pStatus->Status = ERROR_INVALID_PARAMETER;
                bResult = FALSE;
            }

            break;
        }

        default:
        {
            WARN(("unsupported IOCTL %#x, fn(%#x)", RequestPacket->IoControlCode, (RequestPacket->IoControlCode >> 2) & 0xFFF));
            RequestPacket->StatusBlock->Status = ERROR_INVALID_FUNCTION;
        }
    }

    if (!bResult)
    {
        pStatus->Information = NULL;
    }

    VBOXMP_WARN_VPS(pStatus->Status);
    LOGF_LEAVE();
    return TRUE;
}