VBoxDispD3DIf.cpp revision e0e6ca112bdf0d25db2d07365a502ecda5b391d3
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive/** @file
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive *
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive * VBoxVideo Display D3D User mode dll
5f5d1b4cc970b7f06ff8ef6526128e9a27303d88nd *
acc36ab93565d2880447d535da6ca6e5feac7a70nd * Copyright (C) 2010 Oracle Corporation
acc36ab93565d2880447d535da6ca6e5feac7a70nd *
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * This file is part of VirtualBox Open Source Edition (OSE), as
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * available from http://www.virtualbox.org. This file is free software;
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * you can redistribute it and/or modify it under the terms of the GNU
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * General Public License (GPL) as published by the Free Software
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * Foundation, in version 2 as it comes in the "COPYING" file of the
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
acc36ab93565d2880447d535da6ca6e5feac7a70nd * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
acc36ab93565d2880447d535da6ca6e5feac7a70nd */
acc36ab93565d2880447d535da6ca6e5feac7a70nd#include "VBoxDispD3DIf.h"
acc36ab93565d2880447d535da6ca6e5feac7a70nd#include "VBoxDispD3DCmn.h"
acc36ab93565d2880447d535da6ca6e5feac7a70nd
acc36ab93565d2880447d535da6ca6e5feac7a70nd#include <iprt/assert.h>
acc36ab93565d2880447d535da6ca6e5feac7a70nd
acc36ab93565d2880447d535da6ca6e5feac7a70ndvoid VBoxDispD3DClose(VBOXDISPD3D *pD3D)
acc36ab93565d2880447d535da6ca6e5feac7a70nd{
acc36ab93565d2880447d535da6ca6e5feac7a70nd FreeLibrary(pD3D->hD3DLib);
7db9f691a00ead175b03335457ca296a33ddf31bnd pD3D->hD3DLib = NULL;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive}
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08sliveHRESULT VBoxDispD3DOpen(VBOXDISPD3D *pD3D)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive{
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen pD3D->hD3DLib = LoadLibraryW(L"VBoxD3D9wddm.dll");
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive Assert(pD3D->hD3DLib);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive if (pD3D->hD3DLib)
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar pD3D->pfnDirect3DCreate9Ex = (PFNVBOXDISPD3DCREATE9EX)GetProcAddress(pD3D->hD3DLib, "Direct3DCreate9Ex");
eb0e379101aca2125fcc0bd316078492d39840bdcovener Assert(pD3D->pfnDirect3DCreate9Ex);
eb0e379101aca2125fcc0bd316078492d39840bdcovener if (pD3D->pfnDirect3DCreate9Ex)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive pD3D->pfnVBoxWineExD3DDev9CreateTexture = (PFNVBOXWINEEXD3DDEV9_CREATETEXTURE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9CreateTexture");
d207757a321497bd47d391c95e7dd2144addbb1dslive Assert(pD3D->pfnVBoxWineExD3DDev9CreateTexture);
d207757a321497bd47d391c95e7dd2144addbb1dslive if (pD3D->pfnVBoxWineExD3DDev9CreateTexture)
36a1dcd0eb7ff5a01f23c95d58bf863da1c7045bkess {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive pD3D->pfnVBoxWineExD3DDev9CreateCubeTexture = (PFNVBOXWINEEXD3DDEV9_CREATECUBETEXTURE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9CreateCubeTexture");
51db0c8d97d68b94230ba4972c7a62b55314acd3slive Assert(pD3D->pfnVBoxWineExD3DDev9CreateCubeTexture);
21d8860f1cac3103fabffb8f718769126f118c52rbowen if (pD3D->pfnVBoxWineExD3DDev9CreateCubeTexture)
51db0c8d97d68b94230ba4972c7a62b55314acd3slive {
51db0c8d97d68b94230ba4972c7a62b55314acd3slive pD3D->pfnVBoxWineExD3DDev9Flush = (PFNVBOXWINEEXD3DDEV9_FLUSH)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Flush");
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive Assert(pD3D->pfnVBoxWineExD3DDev9Flush);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive if (pD3D->pfnVBoxWineExD3DDev9Flush)
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive {
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen pD3D->pfnVBoxWineExD3DDev9Update = (PFNVBOXWINEEXD3DDEV9_UPDATE)GetProcAddress(pD3D->hD3DLib, "VBoxWineExD3DDev9Update");
b45563a529f9dba59dfac82ff5a53f1d63ed5ea5kess Assert(pD3D->pfnVBoxWineExD3DDev9Update);
738504ae90e2233e22f4fd0da1d8ccf0b96e579end if (pD3D->pfnVBoxWineExD3DDev9Update)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive return S_OK;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
18831446030f4eda7e0563c92a896ccfdb6eb1d7slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive else
7310251f839057f76c21e4b794b74af31fe3a3daslive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive DWORD winErr = GetLastError();
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive vboxVDbgPrintR((__FUNCTION__": GetProcAddressW (for Direct3DCreate9Ex) failed, winErr = (%d)", winErr));
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive VBoxDispD3DClose(pD3D);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
d207757a321497bd47d391c95e7dd2144addbb1dslive else
e28ae657050a7447c5644eb5ae1e975f2a3cc4b8slive {
e28ae657050a7447c5644eb5ae1e975f2a3cc4b8slive DWORD winErr = GetLastError();
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive vboxVDbgPrintR((__FUNCTION__": LoadLibraryW failed, winErr = (%d)", winErr));
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive return E_FAIL;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive}
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive#define WM_VBOXDISP_CALLPROC (WM_APP+1)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slivetypedef struct VBOXDISP_CALLPROC
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive{
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive PFNVBOXDISPWORKERCB pfnCb;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive void *pvCb;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive} VBOXDISP_CALLPROC;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slivestatic DWORD WINAPI vboxDispWorkerThread(void *pvUser)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive{
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive VBOXDISPWORKER *pWorker = (VBOXDISPWORKER*)pvUser;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive MSG Msg;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive PeekMessage(&Msg,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive NULL /* HWND hWnd */,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive WM_USER /* UINT wMsgFilterMin */,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive WM_USER /* UINT wMsgFilterMax */,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive PM_NOREMOVE);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive RTSemEventSignal(pWorker->hEvent);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive do
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive BOOL bResult = GetMessage(&Msg,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive 0 /*HWND hWnd*/,
d207757a321497bd47d391c95e7dd2144addbb1dslive 0 /*UINT wMsgFilterMin*/,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive 0 /*UINT wMsgFilterMax*/
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive );
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive if(!bResult) /* WM_QUIT was posted */
d207757a321497bd47d391c95e7dd2144addbb1dslive break;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive Assert(bResult != -1);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive if(bResult == -1) /* error occurred */
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive break;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive switch (Msg.message)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
d207757a321497bd47d391c95e7dd2144addbb1dslive case WM_VBOXDISP_CALLPROC:
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive VBOXDISP_CALLPROC* pData = (VBOXDISP_CALLPROC*)Msg.lParam;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive pData->pfnCb(pData->pvCb);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive RTSemEventSignal(pWorker->hEvent);
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen break;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
f915b3725d6bce16d5fa02403601fb9e6872cf49kess default:
157feddbcf673772f0cea97decb59583a0dfdfeesctemme TranslateMessage(&Msg);
157feddbcf673772f0cea97decb59583a0dfdfeesctemme DispatchMessage(&Msg);
157feddbcf673772f0cea97decb59583a0dfdfeesctemme }
157feddbcf673772f0cea97decb59583a0dfdfeesctemme } while (1);
157feddbcf673772f0cea97decb59583a0dfdfeesctemme return 0;
157feddbcf673772f0cea97decb59583a0dfdfeesctemme}
d05d55af575a1453a843186bc7b5fb81026fdefbcovener
157feddbcf673772f0cea97decb59583a0dfdfeesctemmestatic int vboxDispWorkerSubmit(VBOXDISPWORKER *pWorker, UINT Msg, LPARAM lParam)
157feddbcf673772f0cea97decb59583a0dfdfeesctemme{
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar /* need to serialize since vboxDispWorkerThread is using one pWorker->hEvent
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * to signal job completion */
157feddbcf673772f0cea97decb59583a0dfdfeesctemme int rc = RTCritSectEnter(&pWorker->CritSect);
157feddbcf673772f0cea97decb59583a0dfdfeesctemme AssertRC(rc);
157feddbcf673772f0cea97decb59583a0dfdfeesctemme if (RT_SUCCESS(rc))
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar BOOL bResult = PostThreadMessage(pWorker->idThread, Msg, 0, lParam);
157feddbcf673772f0cea97decb59583a0dfdfeesctemme Assert(bResult);
157feddbcf673772f0cea97decb59583a0dfdfeesctemme if (bResult)
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar {
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar rc = RTSemEventWait(pWorker->hEvent, RT_INDEFINITE_WAIT);
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar AssertRC(rc);
157feddbcf673772f0cea97decb59583a0dfdfeesctemme }
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar else
f915b3725d6bce16d5fa02403601fb9e6872cf49kess rc = VERR_GENERAL_FAILURE;
f915b3725d6bce16d5fa02403601fb9e6872cf49kess
193ba167383a0599478b84ea51ac9ddec2bc0328rbowen int tmpRc = RTCritSectLeave(&pWorker->CritSect);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive AssertRC(tmpRc);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
36461702119f178a2a47ca2fe3766a417e282402rbowen return rc;
36461702119f178a2a47ca2fe3766a417e282402rbowen}
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
f915b3725d6bce16d5fa02403601fb9e6872cf49kessHRESULT VBoxDispWorkerSubmitProc(VBOXDISPWORKER *pWorker, PFNVBOXDISPWORKERCB pfnCb, void *pvCb)
f915b3725d6bce16d5fa02403601fb9e6872cf49kess{
2f83bdeb8f4a4f370e26edf99666e7965c58de22poirier VBOXDISP_CALLPROC Ctx;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive Ctx.pfnCb = pfnCb;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive Ctx.pvCb = pvCb;
925a83633d01d5db2fd3554020c7a47770b3550epquerna int rc = vboxDispWorkerSubmit(pWorker, WM_VBOXDISP_CALLPROC, (LPARAM)&Ctx);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive AssertRC(rc);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive return RT_SUCCESS(rc) ? S_OK : E_FAIL;
f915b3725d6bce16d5fa02403601fb9e6872cf49kess}
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
f915b3725d6bce16d5fa02403601fb9e6872cf49kessHRESULT VBoxDispWorkerCreate(VBOXDISPWORKER *pWorker)
f915b3725d6bce16d5fa02403601fb9e6872cf49kess{
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive int rc = RTCritSectInit(&pWorker->CritSect);
36a1dcd0eb7ff5a01f23c95d58bf863da1c7045bkess AssertRC(rc);
f915b3725d6bce16d5fa02403601fb9e6872cf49kess if (RT_SUCCESS(rc))
f915b3725d6bce16d5fa02403601fb9e6872cf49kess {
d207757a321497bd47d391c95e7dd2144addbb1dslive rc = RTSemEventCreate(&pWorker->hEvent);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive AssertRC(rc);
f915b3725d6bce16d5fa02403601fb9e6872cf49kess if (RT_SUCCESS(rc))
f915b3725d6bce16d5fa02403601fb9e6872cf49kess {
f915b3725d6bce16d5fa02403601fb9e6872cf49kess pWorker->hThread = CreateThread(
f915b3725d6bce16d5fa02403601fb9e6872cf49kess NULL /* LPSECURITY_ATTRIBUTES lpThreadAttributes */,
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd 0 /* SIZE_T dwStackSize */,
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd vboxDispWorkerThread,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive pWorker,
860b4efe27e7c1c9a2bf5c872b29c90f76849b51jim 0 /* DWORD dwCreationFlags */,
860b4efe27e7c1c9a2bf5c872b29c90f76849b51jim &pWorker->idThread);
860b4efe27e7c1c9a2bf5c872b29c90f76849b51jim Assert(pWorker->hThread);
860b4efe27e7c1c9a2bf5c872b29c90f76849b51jim if (pWorker->hThread)
fbac1b9bcbd0303aadc34d2bbd843a632f32ac34kess {
860b4efe27e7c1c9a2bf5c872b29c90f76849b51jim rc = RTSemEventWait(pWorker->hEvent, RT_INDEFINITE_WAIT);
860b4efe27e7c1c9a2bf5c872b29c90f76849b51jim AssertRC(rc);
860b4efe27e7c1c9a2bf5c872b29c90f76849b51jim if (RT_SUCCESS(rc))
d207757a321497bd47d391c95e7dd2144addbb1dslive return S_OK;
f915b3725d6bce16d5fa02403601fb9e6872cf49kess /* destroy thread ? */
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive else
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive DWORD winErr = GetLastError();
d207757a321497bd47d391c95e7dd2144addbb1dslive vboxVDbgPrintR((__FUNCTION__": CreateThread failed, winErr = (%d)", winErr));
b45563a529f9dba59dfac82ff5a53f1d63ed5ea5kess rc = VERR_GENERAL_FAILURE;
d207757a321497bd47d391c95e7dd2144addbb1dslive }
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive int tmpRc = RTSemEventDestroy(pWorker->hEvent);
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive AssertRC(tmpRc);
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive }
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive int tmpRc = RTCritSectDelete(&pWorker->CritSect);
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive AssertRC(tmpRc);
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive }
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive return E_FAIL;
645a5920d9fdd53a7f75a6a16e87ff27781b0133slive}
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive
9ed703ab1543b3300f4b60c0405fc1a212b601c8sliveHRESULT VBoxDispWorkerDestroy(VBOXDISPWORKER *pWorker)
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive{
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive int rc = VINF_SUCCESS;
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive BOOL bResult = PostThreadMessage(pWorker->idThread, WM_QUIT, 0, 0);
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive Assert(bResult);
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive if (bResult)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive DWORD dwErr = WaitForSingleObject(pWorker->hThread, INFINITE);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive Assert(dwErr == WAIT_OBJECT_0);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive if (dwErr == WAIT_OBJECT_0)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
654d8eb036bedc99e90e11910ee02d3421417697rbowen rc = RTSemEventDestroy(pWorker->hEvent);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive AssertRC(rc);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive if (RT_SUCCESS(rc))
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
d207757a321497bd47d391c95e7dd2144addbb1dslive rc = RTCritSectDelete(&pWorker->CritSect);
d207757a321497bd47d391c95e7dd2144addbb1dslive AssertRC(rc);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive else
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive rc = VERR_GENERAL_FAILURE;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive else
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive rc = VERR_GENERAL_FAILURE;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive return RT_SUCCESS(rc) ? S_OK : E_FAIL;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive}
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive
9ed703ab1543b3300f4b60c0405fc1a212b601c8slivestatic LRESULT CALLBACK WindowProc(HWND hwnd,
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd UINT uMsg,
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive WPARAM wParam,
d207757a321497bd47d391c95e7dd2144addbb1dslive LPARAM lParam
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive)
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive{
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive switch(uMsg)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive case WM_CLOSE:
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive vboxVDbgPrint((__FUNCTION__": got WM_CLOSE for hwnd(0x%x)", hwnd));
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd return 0;
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive case WM_DESTROY:
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive vboxVDbgPrint((__FUNCTION__": got WM_DESTROY for hwnd(0x%x)", hwnd));
645a5920d9fdd53a7f75a6a16e87ff27781b0133slive return 0;
645a5920d9fdd53a7f75a6a16e87ff27781b0133slive case WM_NCHITTEST:
645a5920d9fdd53a7f75a6a16e87ff27781b0133slive vboxVDbgPrint((__FUNCTION__": got WM_NCHITTEST for hwnd(0x%x)\n", hwnd));
645a5920d9fdd53a7f75a6a16e87ff27781b0133slive return HTNOWHERE;
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive }
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive return DefWindowProc(hwnd, uMsg, wParam, lParam);
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive}
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive#define VBOXDISPWND_NAME L"VboxDispD3DWindow"
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung
4a591802e98a2b28a0b742e0fb636f5baaa0845drjungHRESULT vboxDispWndDoCreate(DWORD w, DWORD h, HWND *phWnd)
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung{
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung HRESULT hr = S_OK;
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung /* Register the Window Class. */
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung WNDCLASS wc;
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung if (!GetClassInfo(hInstance, VBOXDISPWND_NAME, &wc))
475381aeef8ae4f7986e7b02a8d480777d5a14b7nd {
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive wc.style = CS_OWNDC;
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive wc.lpfnWndProc = WindowProc;
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung wc.cbClsExtra = 0;
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive wc.cbWndExtra = 0;
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd wc.hInstance = hInstance;
f87c874dc2012c5e410ea0d25ffda6a61c6c2917slive wc.hIcon = NULL;
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive wc.hCursor = NULL;
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive wc.hbrBackground = NULL;
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive wc.lpszMenuName = NULL;
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd wc.lpszClassName = VBOXDISPWND_NAME;
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive if (!RegisterClass(&wc))
9ed703ab1543b3300f4b60c0405fc1a212b601c8slive {
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd DWORD winErr = GetLastError();
41180d477c0228e5c09e2ad1393054b602295eecrbowen vboxVDbgPrint((__FUNCTION__": RegisterClass failed, winErr(%d)\n", winErr));
41180d477c0228e5c09e2ad1393054b602295eecrbowen hr = E_FAIL;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
36a1dcd0eb7ff5a01f23c95d58bf863da1c7045bkess if (hr == S_OK)
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung {
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung HWND hWnd = CreateWindowEx (WS_EX_TOOLWINDOW,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive VBOXDISPWND_NAME, VBOXDISPWND_NAME,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DISABLED,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive 0, 0,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive w, h,
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung NULL, //GetDesktopWindow() /* hWndParent */,
4a591802e98a2b28a0b742e0fb636f5baaa0845drjung NULL /* hMenu */,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive hInstance,
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive NULL /* lpParam */);
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd Assert(hWnd);
36a1dcd0eb7ff5a01f23c95d58bf863da1c7045bkess if (hWnd)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive *phWnd = hWnd;
7852e17fb37b2a02ccdcab107f2c7f5fd41fd201nd }
7852e17fb37b2a02ccdcab107f2c7f5fd41fd201nd else
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive DWORD winErr = GetLastError();
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive vboxVDbgPrint((__FUNCTION__": CreateWindowEx failed, winErr(%d)\n", winErr));
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive hr = E_FAIL;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive }
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive return hr;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive}
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
d259179bd6f04c8c85976bb3d37c42f736c0039eslivestatic HRESULT vboxDispWndDoDestroy(HWND hWnd)
d207757a321497bd47d391c95e7dd2144addbb1dslive{
860b4efe27e7c1c9a2bf5c872b29c90f76849b51jim BOOL bResult = DestroyWindow(hWnd);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive Assert(bResult);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive if (bResult)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive return S_OK;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
51db0c8d97d68b94230ba4972c7a62b55314acd3slive DWORD winErr = GetLastError();
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive vboxVDbgPrint((__FUNCTION__": DestroyWindow failed, winErr(%d) for hWnd(0x%x)\n", winErr, hWnd));
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive return E_FAIL;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive}
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
847155534c9678f68502de3809d8d6d2623ac32erbowentypedef struct VBOXDISPWND_CREATE_INFO
5e7452e356ccbbc11d7a19368f40ae54a1d6c3d3rbowen{
5e7452e356ccbbc11d7a19368f40ae54a1d6c3d3rbowen int hr;
5e7452e356ccbbc11d7a19368f40ae54a1d6c3d3rbowen HWND hWnd;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive DWORD width;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive DWORD height;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive} VBOXDISPWND_CREATE_INFO;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slivetypedef struct VBOXDISPWND_DESTROY_INFO
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive{
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive int hr;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive HWND hWnd;
738504ae90e2233e22f4fd0da1d8ccf0b96e579end} VBOXDISPWND_DESTROY_INFO;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08sliveDECLCALLBACK(void) vboxDispWndDestroyWorker(void *pvUser)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive{
860b4efe27e7c1c9a2bf5c872b29c90f76849b51jim VBOXDISPWND_DESTROY_INFO *pInfo = (VBOXDISPWND_DESTROY_INFO*)pvUser;
5e7452e356ccbbc11d7a19368f40ae54a1d6c3d3rbowen pInfo->hr = vboxDispWndDoDestroy(pInfo->hWnd);
b51bf223f42d43ca6b1b33c95124edcfa5a871a4nd Assert(pInfo->hr == S_OK);
b51bf223f42d43ca6b1b33c95124edcfa5a871a4nd}
b51bf223f42d43ca6b1b33c95124edcfa5a871a4nd
738504ae90e2233e22f4fd0da1d8ccf0b96e579endDECLCALLBACK(void) vboxDispWndCreateWorker(void *pvUser)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive{
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive VBOXDISPWND_CREATE_INFO *pInfo = (VBOXDISPWND_CREATE_INFO*)pvUser;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive pInfo->hr = vboxDispWndDoCreate(pInfo->width, pInfo->height, &pInfo->hWnd);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive Assert(pInfo->hr == S_OK);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive}
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive
d207757a321497bd47d391c95e7dd2144addbb1dsliveHRESULT VBoxDispWndDestroy(PVBOXWDDMDISP_ADAPTER pAdapter, HWND hWnd)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive{
5e7452e356ccbbc11d7a19368f40ae54a1d6c3d3rbowen VBOXDISPWND_DESTROY_INFO Info;
5e7452e356ccbbc11d7a19368f40ae54a1d6c3d3rbowen Info.hr = E_FAIL;
d207757a321497bd47d391c95e7dd2144addbb1dslive Info.hWnd = hWnd;
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive HRESULT hr = VBoxDispWorkerSubmitProc(&pAdapter->WndWorker, vboxDispWndDestroyWorker, &Info);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive Assert(hr == S_OK);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive if (hr == S_OK)
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive {
d207757a321497bd47d391c95e7dd2144addbb1dslive Assert(Info.hr == S_OK);
e4e4d8f25022f178ceb567b9f2b37be34b729f08slive return Info.hr;
51db0c8d97d68b94230ba4972c7a62b55314acd3slive }
51db0c8d97d68b94230ba4972c7a62b55314acd3slive return hr;
51db0c8d97d68b94230ba4972c7a62b55314acd3slive}
51db0c8d97d68b94230ba4972c7a62b55314acd3slive
51db0c8d97d68b94230ba4972c7a62b55314acd3sliveHRESULT VBoxDispWndCreate(PVBOXWDDMDISP_ADAPTER pAdapter, DWORD width, DWORD height, HWND *phWnd)
654bf71bc72931d6e803910a31d32ca1d7db4a0bhumbedooh{
51db0c8d97d68b94230ba4972c7a62b55314acd3slive VBOXDISPWND_CREATE_INFO Info;
51db0c8d97d68b94230ba4972c7a62b55314acd3slive Info.hr = E_FAIL;
0e07836b674ca484eb457056c4a4ec5edc226139humbedooh Info.width = width;
51db0c8d97d68b94230ba4972c7a62b55314acd3slive Info.height = height;
51db0c8d97d68b94230ba4972c7a62b55314acd3slive HRESULT hr = VBoxDispWorkerSubmitProc(&pAdapter->WndWorker, vboxDispWndCreateWorker, &Info);
51db0c8d97d68b94230ba4972c7a62b55314acd3slive Assert(hr == S_OK);
d207757a321497bd47d391c95e7dd2144addbb1dslive if (hr == S_OK)
51db0c8d97d68b94230ba4972c7a62b55314acd3slive {
51db0c8d97d68b94230ba4972c7a62b55314acd3slive Assert(Info.hr == S_OK);
51db0c8d97d68b94230ba4972c7a62b55314acd3slive if (Info.hr == S_OK)
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd *phWnd = Info.hWnd;
51db0c8d97d68b94230ba4972c7a62b55314acd3slive return Info.hr;
a1ef40892ffa2b44fc249423c5b6c42a74a84c68nd }
51db0c8d97d68b94230ba4972c7a62b55314acd3slive return hr;
d207757a321497bd47d391c95e7dd2144addbb1dslive}
51db0c8d97d68b94230ba4972c7a62b55314acd3slive