VBoxDispD3DIf.cpp revision 9055f61bb57d2a625c6434d55beac7565c3b3c0d
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* $Id$ */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/** @file
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VBoxVideo Display D3D User mode dll
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/*
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Copyright (C) 2011 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * available from http://www.virtualbox.org. This file is free software;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * General Public License (GPL) as published by the Free Software
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include "VBoxDispD3DIf.h"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include "VBoxDispD3DCmn.h"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#include <iprt/assert.h>
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncvoid VBoxDispD3DClose(VBOXDISPD3D *pD3D)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync FreeLibrary(pD3D->hD3DLib);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pD3D->hD3DLib = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncHRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#ifdef VBOX_WDDM_WOW64
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pD3D->hD3DLib = LoadLibraryW(L"VBoxD3D9wddm-x86.dll");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pD3D->hD3DLib = LoadLibraryW(L"VBoxD3D9wddm.dll");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#endif
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pD3D->hD3DLib);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pD3D->hD3DLib)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pD3D->pfnDirect3DCreate9Ex = (PFNVBOXDISPD3DCREATE9EX)GetProcAddress(pD3D->hD3DLib, "Direct3DCreate9Ex");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pD3D->pfnDirect3DCreate9Ex);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pD3D->pfnDirect3DCreate9Ex)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pD3D->pfnVBoxWineExD3DDev9CreateTexture = (PFNVBOXWINEEXD3DDEV9_CREATETEXTURE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9CreateTexture");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pD3D->pfnVBoxWineExD3DDev9CreateTexture);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pD3D->pfnVBoxWineExD3DDev9CreateTexture)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pD3D->pfnVBoxWineExD3DDev9CreateCubeTexture = (PFNVBOXWINEEXD3DDEV9_CREATECUBETEXTURE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9CreateCubeTexture");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pD3D->pfnVBoxWineExD3DDev9CreateCubeTexture);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pD3D->pfnVBoxWineExD3DDev9CreateCubeTexture)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pD3D->pfnVBoxWineExD3DDev9Flush = (PFNVBOXWINEEXD3DDEV9_FLUSH)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Flush");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pD3D->pfnVBoxWineExD3DDev9Flush);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pD3D->pfnVBoxWineExD3DDev9Flush)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pD3D->pfnVBoxWineExD3DDev9Update = (PFNVBOXWINEEXD3DDEV9_UPDATE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Update");
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pD3D->pfnVBoxWineExD3DDev9Update);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pD3D->pfnVBoxWineExD3DDev9Update)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return S_OK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD winErr = GetLastError();
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVDbgPrintR((__FUNCTION__": GetProcAddressW (for Direct3DCreate9Ex) failed, winErr = (%d)", winErr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBoxDispD3DClose(pD3D);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD winErr = GetLastError();
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVDbgPrintR((__FUNCTION__": LoadLibraryW failed, winErr = (%d)", winErr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return E_FAIL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define WM_VBOXDISP_CALLPROC (WM_APP+1)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef struct VBOXDISP_CALLPROC
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXDISPWORKERCB pfnCb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync void *pvCb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync} VBOXDISP_CALLPROC;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic DWORD WINAPI vboxDispWorkerThread(void *pvUser)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXDISPWORKER *pWorker = (VBOXDISPWORKER*)pvUser;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync MSG Msg;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PeekMessage(&Msg,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NULL /* HWND hWnd */,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WM_USER /* UINT wMsgFilterMin */,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WM_USER /* UINT wMsgFilterMax */,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PM_NOREMOVE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSemEventSignal(pWorker->hEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync do
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync BOOL bResult = GetMessage(&Msg,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 0 /*HWND hWnd*/,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 0 /*UINT wMsgFilterMin*/,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 0 /*UINT wMsgFilterMax*/
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync );
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if(!bResult) /* WM_QUIT was posted */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(bResult != -1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if(bResult == -1) /* error occurred */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch (Msg.message)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case WM_VBOXDISP_CALLPROC:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXDISP_CALLPROC* pData = (VBOXDISP_CALLPROC*)Msg.lParam;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pData->pfnCb(pData->pvCb);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSemEventSignal(pWorker->hEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync break;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync default:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync TranslateMessage(&Msg);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DispatchMessage(&Msg);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (1);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic int vboxDispWorkerSubmit(VBOXDISPWORKER *pWorker, UINT Msg, LPARAM lParam)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* need to serialize since vboxDispWorkerThread is using one pWorker->hEvent
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * to signal job completion */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTCritSectEnter(&pWorker->CritSect);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_SUCCESS(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync BOOL bResult = PostThreadMessage(pWorker->idThread, Msg, 0, lParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(bResult);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = RTSemEventWait(pWorker->hEvent, RT_INDEFINITE_WAIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = VERR_GENERAL_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int tmpRc = RTCritSectLeave(&pWorker->CritSect);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(tmpRc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return rc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncHRESULT VBoxDispWorkerSubmitProc(VBOXDISPWORKER *pWorker, PFNVBOXDISPWORKERCB pfnCb, void *pvCb)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXDISP_CALLPROC Ctx;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Ctx.pfnCb = pfnCb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Ctx.pvCb = pvCb;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = vboxDispWorkerSubmit(pWorker, WM_VBOXDISP_CALLPROC, (LPARAM)&Ctx);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RT_SUCCESS(rc) ? S_OK : E_FAIL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncHRESULT VBoxDispWorkerCreate(VBOXDISPWORKER *pWorker)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTCritSectInit(&pWorker->CritSect);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_SUCCESS(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = RTSemEventCreate(&pWorker->hEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_SUCCESS(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pWorker->hThread = CreateThread(
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NULL /* LPSECURITY_ATTRIBUTES lpThreadAttributes */,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 0 /* SIZE_T dwStackSize */,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxDispWorkerThread,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pWorker,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 0 /* DWORD dwCreationFlags */,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync &pWorker->idThread);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pWorker->hThread);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pWorker->hThread)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = RTSemEventWait(pWorker->hEvent, RT_INDEFINITE_WAIT);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_SUCCESS(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return S_OK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* destroy thread ? */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD winErr = GetLastError();
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVDbgPrintR((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = VERR_GENERAL_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int tmpRc = RTSemEventDestroy(pWorker->hEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(tmpRc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int tmpRc = RTCritSectDelete(&pWorker->CritSect);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(tmpRc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return E_FAIL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncHRESULT VBoxDispWorkerDestroy(VBOXDISPWORKER *pWorker)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = VINF_SUCCESS;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync BOOL bResult = PostThreadMessage(pWorker->idThread, WM_QUIT, 0, 0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(bResult);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD dwErr = WaitForSingleObject(pWorker->hThread, INFINITE);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(dwErr == WAIT_OBJECT_0);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (dwErr == WAIT_OBJECT_0)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = RTSemEventDestroy(pWorker->hEvent);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (RT_SUCCESS(rc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = RTCritSectDelete(&pWorker->CritSect);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync AssertRC(rc);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = VERR_GENERAL_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync rc = VERR_GENERAL_FAILURE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return RT_SUCCESS(rc) ? S_OK : E_FAIL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic LRESULT CALLBACK WindowProc(HWND hwnd,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync UINT uMsg,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WPARAM wParam,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync LPARAM lParam
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync switch(uMsg)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case WM_CLOSE:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVDbgPrint((__FUNCTION__": got WM_CLOSE for hwnd(0x%x)", hwnd));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case WM_DESTROY:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVDbgPrint((__FUNCTION__": got WM_DESTROY for hwnd(0x%x)", hwnd));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync case WM_NCHITTEST:
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVDbgPrint((__FUNCTION__": got WM_NCHITTEST for hwnd(0x%x)\n", hwnd));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return HTNOWHERE;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return DefWindowProc(hwnd, uMsg, wParam, lParam);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXDISPWND_NAME L"VboxDispD3DWindow"
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncHRESULT vboxDispWndDoCreate(DWORD w, DWORD h, HWND *phWnd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HRESULT hr = S_OK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Register the Window Class. */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WNDCLASS wc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!GetClassInfo(hInstance, VBOXDISPWND_NAME, &wc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.style = CS_OWNDC;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.lpfnWndProc = WindowProc;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.cbClsExtra = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.cbWndExtra = 0;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.hInstance = hInstance;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.hIcon = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.hCursor = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.hbrBackground = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.lpszMenuName = NULL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync wc.lpszClassName = VBOXDISPWND_NAME;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (!RegisterClass(&wc))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD winErr = GetLastError();
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVDbgPrint((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync hr = E_FAIL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (hr == S_OK)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HWND hWnd = CreateWindowEx (WS_EX_TOOLWINDOW,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXDISPWND_NAME, VBOXDISPWND_NAME,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync 0, 0,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync w, h,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NULL, //GetDesktopWindow() /* hWndParent */,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NULL /* hMenu */,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync hInstance,
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync NULL /* lpParam */);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(hWnd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (hWnd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *phWnd = hWnd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync else
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD winErr = GetLastError();
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVDbgPrint((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync hr = E_FAIL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return hr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncstatic HRESULT vboxDispWndDoDestroy(HWND hWnd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync BOOL bResult = DestroyWindow(hWnd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(bResult);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (bResult)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return S_OK;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD winErr = GetLastError();
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxVDbgPrint((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return E_FAIL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef struct VBOXDISPWND_CREATE_INFO
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int hr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HWND hWnd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD width;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync DWORD height;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync} VBOXDISPWND_CREATE_INFO;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsynctypedef struct VBOXDISPWND_DESTROY_INFO
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int hr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HWND hWnd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync} VBOXDISPWND_DESTROY_INFO;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLCALLBACK(void) vboxDispWndDestroyWorker(void *pvUser)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXDISPWND_DESTROY_INFO *pInfo = (VBOXDISPWND_DESTROY_INFO*)pvUser;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pInfo->hr = vboxDispWndDoDestroy(pInfo->hWnd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pInfo->hr == S_OK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLCALLBACK(void) vboxDispWndCreateWorker(void *pvUser)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXDISPWND_CREATE_INFO *pInfo = (VBOXDISPWND_CREATE_INFO*)pvUser;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pInfo->hr = vboxDispWndDoCreate(pInfo->width, pInfo->height, &pInfo->hWnd);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(pInfo->hr == S_OK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncHRESULT VBoxDispWndDestroy(PVBOXWDDMDISP_ADAPTER pAdapter, HWND hWnd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXDISPWND_DESTROY_INFO Info;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Info.hr = E_FAIL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Info.hWnd = hWnd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HRESULT hr = VBoxDispWorkerSubmitProc(&pAdapter->WndWorker, vboxDispWndDestroyWorker, &Info);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(hr == S_OK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (hr == S_OK)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Info.hr == S_OK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Info.hr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return hr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncHRESULT VBoxDispWndCreate(PVBOXWDDMDISP_ADAPTER pAdapter, DWORD width, DWORD height, HWND *phWnd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync{
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync VBOXDISPWND_CREATE_INFO Info;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Info.hr = E_FAIL;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Info.width = width;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Info.height = height;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync HRESULT hr = VBoxDispWorkerSubmitProc(&pAdapter->WndWorker, vboxDispWndCreateWorker, &Info);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(hr == S_OK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (hr == S_OK)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync {
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync Assert(Info.hr == S_OK);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (Info.hr == S_OK)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync *phWnd = Info.hWnd;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return Info.hr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync }
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return hr;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync}