summaryrefslogtreecommitdiff
path: root/src/VBox/HostServices
diff options
context:
space:
mode:
authorFelix Geyer <fgeyer@debian.org>2014-04-05 22:17:15 +0200
committerFelix Geyer <fgeyer@debian.org>2014-04-05 22:17:15 +0200
commit1700c7d32f7d9d101cbba9f1fcb8bb57ed16a727 (patch)
tree727251ad65172262944f82bb0f28601c3fb6f6b3 /src/VBox/HostServices
parent1e85aed889b772c2f2daa7a6d9e8bd967aa213d8 (diff)
downloadvirtualbox-upstream.tar.gz
Imported Upstream version 4.3.10-dfsgupstream/4.3.10-dfsgupstream
Diffstat (limited to 'src/VBox/HostServices')
-rw-r--r--src/VBox/HostServices/SharedOpenGL/Makefile.kmk6
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp73
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server.h6
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c290
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp18
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp397
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c22
-rw-r--r--src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c44
-rw-r--r--src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c41
9 files changed, 735 insertions, 162 deletions
diff --git a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
index baf6c702e..971c1c9ae 100644
--- a/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
+++ b/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
@@ -264,6 +264,12 @@ VBoxOGLrenderspu_OBJCFLAGS.darwin = -Wno-shadow
VBoxOGLrenderspu_SOURCES.darwin = \
render/renderspu_cocoa.c \
render/renderspu_cocoa_helper.m
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLrenderspu_DEFS += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_VDMA
+VBoxOGLrenderspu_DEFS += VBOX_WITH_VDMA
+endif
VBoxOGLrenderspu_LDFLAGS.darwin += -install_name $(VBOX_DYLD_EXECUTABLE_PATH)/VBoxOGLrenderspu.dylib
VBoxOGLrenderspu_LIBS = \
$(PATH_STAGE_LIB)/VBoxOGLhostspuload$(VBOX_SUFF_LIB) \
diff --git a/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp b/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
index 4388fde94..77ddf197f 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
+++ b/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp
@@ -961,7 +961,7 @@ static void crScreenshotHandle(CRVBOXHGCMTAKESCREENSHOT *pScreenshot, uint32_t i
/*
* We differentiate between a function handler for the guest and one for the host.
*/
-static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
+static int svcHostCallPerform(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
{
int rc = VINF_SUCCESS;
@@ -979,10 +979,6 @@ static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cPa
switch (u32Function)
{
- case SHCRGL_HOST_FN_CRCMD_NOTIFY_CMDS:
- {
- rc = crVBoxServerCrCmdNotifyCmds();
- } break;
#ifdef VBOX_WITH_CRHGSMI
case SHCRGL_HOST_FN_CRHGSMI_CMD:
{
@@ -1476,6 +1472,73 @@ static DECLCALLBACK(int) svcHostCall (void *, uint32_t u32Function, uint32_t cPa
return rc;
}
+int crVBoxServerHostCtl(VBOXCRCMDCTL *pCtl, uint32_t cbCtl)
+{
+ if ((cbCtl - sizeof (VBOXCRCMDCTL)) % sizeof(VBOXHGCMSVCPARM))
+ {
+ WARN(("invalid param size"));
+ return VERR_INVALID_PARAMETER;
+ }
+ uint32_t cParams = (cbCtl - sizeof (VBOXCRCMDCTL)) / sizeof (VBOXHGCMSVCPARM);
+ return svcHostCallPerform(pCtl->u32Function, cParams, (VBOXHGCMSVCPARM*)(pCtl + 1));
+}
+
+static DECLCALLBACK(int) svcHostCall(void *, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
+{
+ switch (u32Function)
+ {
+ case SHCRGL_HOST_FN_CTL:
+ {
+ if (cParms != 1)
+ {
+ WARN(("cParams != 1"));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if (paParms->type != VBOX_HGCM_SVC_PARM_PTR)
+ {
+ WARN(("invalid param type"));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if (paParms->u.pointer.size < sizeof (VBOXCRCMDCTL))
+ {
+ WARN(("invalid param size"));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ VBOXCRCMDCTL *pCtl = (VBOXCRCMDCTL*)paParms->u.pointer.addr;
+ switch (pCtl->enmType)
+ {
+ case VBOXCRCMDCTL_TYPE_HGCM:
+ {
+ return crVBoxServerHostCtl(pCtl, paParms->u.pointer.size);
+ }
+ case VBOXCRCMDCTL_TYPE_DISABLE:
+ {
+ if (paParms->u.pointer.size != sizeof (VBOXCRCMDCTL))
+ WARN(("invalid param size"));
+ return crVBoxServerHgcmDisable();
+ }
+ case VBOXCRCMDCTL_TYPE_ENABLE:
+ {
+ if (paParms->u.pointer.size != sizeof (VBOXCRCMDCTL_ENABLE))
+ WARN(("invalid param size"));
+ VBOXCRCMDCTL_ENABLE *pEnable = (VBOXCRCMDCTL_ENABLE*)pCtl;
+ return crVBoxServerHgcmEnable(pEnable->hRHCmd, pEnable->pfnRHCmd);
+ }
+ default:
+ WARN(("invalid function"));
+ return VERR_INVALID_PARAMETER;
+ }
+ WARN(("should not be here!"));
+ return VERR_INTERNAL_ERROR;
+ }
+ default:
+ return svcHostCallPerform(u32Function, cParms, paParms);
+ }
+}
+
extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
{
int rc = VINF_SUCCESS;
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h b/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
index 0b8b46432..677bcf0ee 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
@@ -115,7 +115,7 @@ GLboolean crServerClientInBeginEnd(const CRClient *client);
GLint crServerDispatchCreateContextEx(const char *dpyName, GLint visualBits, GLint shareCtx, GLint preloadCtxID, int32_t internalID);
GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint preloadWinID);
-GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID);
+GLint crServerMuralInit(CRMuralInfo *mural, GLboolean fGuestWindow, GLint visBits, GLint preloadWinID);
void crServerMuralTerm(CRMuralInfo *mural);
GLboolean crServerMuralSize(CRMuralInfo *mural, GLint width, GLint height);
void crServerMuralPosition(CRMuralInfo *mural, GLint x, GLint y);
@@ -155,6 +155,8 @@ HCR_FRAMEBUFFER CrPMgrFbGetNextEnabled(HCR_FRAMEBUFFER hFb);
HCR_FRAMEBUFFER CrPMgrFbGetFirstInitialized();
HCR_FRAMEBUFFER CrPMgrFbGetNextInitialized(HCR_FRAMEBUFFER hFb);
+int CrFbRegionsClear(HCR_FRAMEBUFFER hFb);
+
#define CR_SERVER_FBO_BB_IDX(_mural) ((_mural)->iBbBuffer)
#define CR_SERVER_FBO_FB_IDX(_mural) (((_mural)->iBbBuffer + 1) % ((_mural)->cBuffers))
@@ -425,7 +427,7 @@ typedef DECLCALLBACKPTR(bool, PFNCR_FRAMEBUFFER_ENTRIES_VISITOR_CB)(HCR_FRAMEBUF
bool CrFbHas3DData(HCR_FRAMEBUFFER hFb);
void CrFbVisitCreatedEntries(HCR_FRAMEBUFFER hFb, PFNCR_FRAMEBUFFER_ENTRIES_VISITOR_CB pfnVisitorCb, void *pvContext);
int CrFbResize(HCR_FRAMEBUFFER hFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM);
-int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pPrects, CR_BLITTER_IMG *pImg);
+int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pPrects, CR_BLITTER_IMG *pImg);
bool CrFbIsEnabled(HCR_FRAMEBUFFER hFb);
int CrFbEntryCreateForTexId(HCR_FRAMEBUFFER hFb, GLuint idTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry);
int CrFbEntryCreateForTexData(HCR_FRAMEBUFFER hFb, struct CR_TEXDATA *pTex, uint32_t fFlags, HCR_FRAMEBUFFER_ENTRY *phEntry);
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
index 89b9c615b..1a7e360c6 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
@@ -59,6 +59,8 @@ CRServer cr_server;
int tearingdown = 0; /* can't be static */
+static DECLCALLBACK(int) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd);
+
DECLINLINE(int32_t) crVBoxServerClientGet(uint32_t u32ClientID, CRClient **ppClient)
{
CRClient *pClient = NULL;
@@ -161,7 +163,7 @@ static void crServerTearDown( void )
/* sync our state with renderspu,
* do it before mural & context deletion to avoid deleting currently set murals/contexts*/
- cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0);
+ cr_server.head_spu->dispatch_table.MakeCurrent(CR_RENDER_DEFAULT_WINDOW_ID, 0, CR_RENDER_DEFAULT_CONTEXT_ID);
/* Deallocate all semaphores */
crFreeHashtable(cr_server.semaphores, crFree);
@@ -529,6 +531,38 @@ GLboolean crVBoxServerInit(void)
return GL_TRUE;
}
+static int32_t crVBoxServerAddClientObj(uint32_t u32ClientID, CRClient **ppNewClient)
+{
+ CRClient *newClient;
+
+ if (cr_server.numClients>=CR_MAX_CLIENTS)
+ {
+ if (ppNewClient)
+ *ppNewClient = NULL;
+ return VERR_MAX_THRDS_REACHED;
+ }
+
+ newClient = (CRClient *) crCalloc(sizeof(CRClient));
+ crDebug("crServer: AddClient u32ClientID=%d", u32ClientID);
+
+ newClient->spu_id = 0;
+ newClient->currentCtxInfo = &cr_server.MainContextInfo;
+ newClient->currentContextNumber = -1;
+ newClient->conn = crNetAcceptClient(cr_server.protocol, NULL,
+ cr_server.tcpip_port,
+ cr_server.mtu, 0);
+ newClient->conn->u32ClientID = u32ClientID;
+
+ cr_server.clients[cr_server.numClients++] = newClient;
+
+ crServerAddToRunQueue(newClient);
+
+ if (ppNewClient)
+ *ppNewClient = newClient;
+
+ return VINF_SUCCESS;
+}
+
int32_t crVBoxServerAddClient(uint32_t u32ClientID)
{
CRClient *newClient;
@@ -744,6 +778,17 @@ extern DECLEXPORT(int32_t) crVBoxServerClientGetCaps(uint32_t u32ClientID, uint3
return VINF_SUCCESS;
}
+static int32_t crVBoxServerClientObjSetVersion(CRClient *pClient, uint32_t vMajor, uint32_t vMinor)
+{
+ pClient->conn->vMajor = vMajor;
+ pClient->conn->vMinor = vMinor;
+
+ if (vMajor != CR_PROTOCOL_VERSION_MAJOR
+ || vMinor != CR_PROTOCOL_VERSION_MINOR)
+ return VERR_NOT_SUPPORTED;
+ return VINF_SUCCESS;
+}
+
int32_t crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint32_t vMinor)
{
CRClient *pClient=NULL;
@@ -760,15 +805,14 @@ int32_t crVBoxServerClientSetVersion(uint32_t u32ClientID, uint32_t vMajor, uint
}
if (!pClient) return VERR_INVALID_PARAMETER;
- pClient->conn->vMajor = vMajor;
- pClient->conn->vMinor = vMinor;
+ return crVBoxServerClientObjSetVersion(pClient, vMajor, vMinor);
+}
- if (vMajor != CR_PROTOCOL_VERSION_MAJOR
- || vMinor != CR_PROTOCOL_VERSION_MINOR)
- {
- return VERR_NOT_SUPPORTED;
- }
- else return VINF_SUCCESS;
+static int32_t crVBoxServerClientObjSetPID(CRClient *pClient, uint64_t pid)
+{
+ pClient->pid = pid;
+
+ return VINF_SUCCESS;
}
int32_t crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid)
@@ -787,9 +831,7 @@ int32_t crVBoxServerClientSetPID(uint32_t u32ClientID, uint64_t pid)
}
if (!pClient) return VERR_INVALID_PARAMETER;
- pClient->pid = pid;
-
- return VINF_SUCCESS;
+ return crVBoxServerClientObjSetPID(pClient, pid);
}
int
@@ -1004,7 +1046,7 @@ CRMuralInfo * crServerGetDummyMural(GLint visualBits)
crWarning("crCalloc failed!");
return NULL;
}
- id = crServerMuralInit(pMural, "", visualBits, 0);
+ id = crServerMuralInit(pMural, GL_FALSE, visualBits, 0);
if (id < 0)
{
crWarning("crServerMuralInit failed!");
@@ -2599,8 +2641,6 @@ DECLEXPORT(int32_t) crVBoxServerLoadState(PSSMHANDLE pSSM, uint32_t version)
if (version >= SHCROGL_SSM_VERSION_WITH_SCREEN_INFO)
{
- HCR_FRAMEBUFFER hFb;
-
rc = CrPMgrLoadState(pSSM, version);
AssertRCReturn(rc, rc);
}
@@ -2885,10 +2925,37 @@ DECLEXPORT(int32_t) crVBoxServerSetScreenViewport(int sIndex, int32_t x, int32_t
return VINF_SUCCESS;
}
+static void crVBoxServerDefaultContextSet()
+{
+ GLint spuWindow, spuCtx;
+
+ if (cr_server.MainContextInfo.SpuContext)
+ {
+ CRMuralInfo *pMural = crServerGetDummyMural(cr_server.MainContextInfo.CreateInfo.realVisualBits);
+ if (!pMural)
+ {
+ WARN(("dummy mural is NULL"));
+ spuCtx = CR_RENDER_DEFAULT_CONTEXT_ID;
+ spuWindow = CR_RENDER_DEFAULT_WINDOW_ID;
+ }
+ else
+ {
+ spuCtx = cr_server.MainContextInfo.SpuContext;
+ spuWindow = pMural->CreateInfo.realVisualBits;
+ }
+ }
+ else
+ {
+ spuCtx = CR_RENDER_DEFAULT_CONTEXT_ID;
+ spuWindow = CR_RENDER_DEFAULT_WINDOW_ID;
+ }
+
+ cr_server.head_spu->dispatch_table.MakeCurrent(spuWindow, 0, spuCtx);
+}
#ifdef VBOX_WITH_CRHGSMI
-static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCmd)
+static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCmd, uint32_t cbCmd)
{
int32_t rc;
uint32_t cBuffers = pCmd->cBuffers;
@@ -2901,29 +2968,35 @@ static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCm
if (!g_pvVRamBase)
{
- crWarning("g_pvVRamBase is not initialized");
+ WARN(("g_pvVRamBase is not initialized"));
return VERR_INVALID_STATE;
}
if (!cBuffers)
{
- crWarning("zero buffers passed in!");
+ WARN(("zero buffers passed in!"));
return VERR_INVALID_PARAMETER;
}
cParams = cBuffers-1;
+ if (cbCmd != RT_OFFSETOF(VBOXCMDVBVA_CRCMD_CMD, aBuffers[cBuffers]))
+ {
+ WARN(("invalid buffer size"));
+ return VERR_INVALID_PARAMETER;
+ }
+
cbHdr = pCmd->aBuffers[0].cbBuffer;
pHdr = VBOXCRHGSMI_PTR_SAFE(pCmd->aBuffers[0].offBuffer, cbHdr, CRVBOXHGSMIHDR);
if (!pHdr)
{
- crWarning("invalid header buffer!");
+ WARN(("invalid header buffer!"));
return VERR_INVALID_PARAMETER;
}
if (cbHdr < sizeof (*pHdr))
{
- crWarning("invalid header buffer size!");
+ WARN(("invalid header buffer size!"));
return VERR_INVALID_PARAMETER;
}
@@ -3187,24 +3260,110 @@ static int32_t crVBoxServerCmdVbvaCrCmdProcess(struct VBOXCMDVBVA_CRCMD_CMD *pCm
return rc;
}
-static int32_t crVBoxServerCrCmdProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
+static DECLCALLBACK(int) crVBoxCrCmdEnable(HVBOXCRCMDSVR hSvr, VBOXCRCMD_SVRENABLE_INFO *pInfo)
+{
+ cr_server.CrCmdClientInfo = *pInfo;
+
+ crVBoxServerDefaultContextSet();
+
+ return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdDisable(HVBOXCRCMDSVR hSvr)
+{
+ cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0);
+
+ memset(&cr_server.CrCmdClientInfo, 0, sizeof (cr_server.CrCmdClientInfo));
+
+ return VINF_SUCCESS;
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdHostCtl(HVBOXCRCMDSVR hSvr, uint8_t* pCmd, uint32_t cbCmd)
{
+ return crVBoxServerHostCtl((VBOXCRCMDCTL*)pCmd, cbCmd);
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdGuestCtl(HVBOXCRCMDSVR hSvr, uint8_t* pCmd, uint32_t cbCmd)
+{
+ VBOXCMDVBVA_3DCTL *pCtl = (VBOXCMDVBVA_3DCTL*)pCmd;
+ if (cbCmd < sizeof (VBOXCMDVBVA_3DCTL))
+ {
+ WARN(("invalid buffer size"));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ switch (pCtl->u32Type)
+ {
+ case VBOXCMDVBVA3DCTL_TYPE_CONNECT:
+ {
+ VBOXCMDVBVA_3DCTL_CONNECT *pConnect = (VBOXCMDVBVA_3DCTL_CONNECT*)pCtl;
+
+ return VERR_NOT_SUPPORTED;
+ }
+ case VBOXCMDVBVA3DCTL_TYPE_DISCONNECT:
+ {
+ return VERR_NOT_SUPPORTED;
+ }
+ case VBOXCMDVBVA3DCTL_TYPE_CMD:
+ {
+ VBOXCMDVBVA_3DCTL_CMD *p3DCmd;
+ if (cbCmd < sizeof (VBOXCMDVBVA_3DCTL_CMD))
+ {
+ WARN(("invalid size"));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ p3DCmd = (VBOXCMDVBVA_3DCTL_CMD*)pCmd;
+
+ return crVBoxCrCmdCmd(NULL, &p3DCmd->Cmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_3DCTL_CMD, Cmd));
+ }
+ default:
+ WARN(("invalid function"));
+ return VERR_INVALID_PARAMETER;
+ }
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdSaveState(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM)
+{
+ AssertFailed();
+ return VERR_NOT_IMPLEMENTED;
+}
+
+static DECLCALLBACK(int) crVBoxCrCmdLoadState(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM, uint32_t u32Version)
+{
+ AssertFailed();
+ return VERR_NOT_IMPLEMENTED;
+}
+
+
+static DECLCALLBACK(int) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr, PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
+{
+ AssertFailed();
switch (pCmd->u8OpCode)
{
case VBOXCMDVBVA_OPTYPE_CRCMD:
{
- VBOXCMDVBVA_CRCMD *pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd;
- VBOXCMDVBVA_CRCMD_CMD *pCrCmd = &pCrCmdDr->Cmd;
- int rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd);
+ VBOXCMDVBVA_CRCMD *pCrCmdDr;
+ VBOXCMDVBVA_CRCMD_CMD *pCrCmd;
+ int rc;
+ pCrCmdDr = (VBOXCMDVBVA_CRCMD*)pCmd;
+ pCrCmd = &pCrCmdDr->Cmd;
+ if (cbCmd < sizeof (VBOXCMDVBVA_CRCMD))
+ {
+ WARN(("invalid buffer size"));
+ pCmd->u.i8Result = -1;
+ break;
+ }
+ rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd));
if (RT_SUCCESS(rc))
{
/* success */
- pCmd->i8Result = 0;
+ pCmd->u.i8Result = 0;
}
else
{
- crWarning("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc);
- pCmd->i8Result = -1;
+ WARN(("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc));
+ pCmd->u.i8Result = -1;
}
break;
}
@@ -3215,34 +3374,11 @@ static int32_t crVBoxServerCrCmdProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
}
default:
WARN(("unsupported command"));
- pCmd->i8Result = -1;
+ pCmd->u.i8Result = -1;
}
return VINF_SUCCESS;
}
-int32_t crVBoxServerCrCmdNotifyCmds()
-{
- PVBOXCMDVBVA_HDR pCmd = NULL;
- uint32_t cbCmd;
-
- for (;;)
- {
- int rc = cr_server.CltInfo.pfnCmdGet(cr_server.CltInfo.hClient, &pCmd, &cbCmd);
- if (rc == VINF_EOF)
- return VINF_SUCCESS;
- if (!RT_SUCCESS(rc))
- return rc;
-
- rc = crVBoxServerCrCmdProcess(pCmd, cbCmd);
- if (!RT_SUCCESS(rc))
- return rc;
- }
-
- /* should not be here! */
- AssertFailed();
- return VERR_INTERNAL_ERROR;
-}
-
/* We moved all CrHgsmi command processing to crserverlib to keep the logic of dealing with CrHgsmi commands in one place.
*
* For now we need the notion of CrHgdmi commands in the crserver_lib to be able to complete it asynchronously once it is really processed.
@@ -3272,7 +3408,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c
if (!g_pvVRamBase)
{
- crWarning("g_pvVRamBase is not initialized");
+ WARN(("g_pvVRamBase is not initialized"));
crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_STATE);
return VINF_SUCCESS;
@@ -3280,7 +3416,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c
if (!cBuffers)
{
- crWarning("zero buffers passed in!");
+ WARN(("zero buffers passed in!"));
crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
@@ -3292,7 +3428,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c
pHdr = VBOXCRHGSMI_PTR_SAFE(pCmd->aBuffers[0].offBuffer, cbHdr, CRVBOXHGSMIHDR);
if (!pHdr)
{
- crWarning("invalid header buffer!");
+ WARN(("invalid header buffer!"));
crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
@@ -3300,7 +3436,7 @@ int32_t crVBoxServerCrHgsmiCmd(struct VBOXVDMACMD_CHROMIUM_CMD *pCmd, uint32_t c
if (cbHdr < sizeof (*pHdr))
{
- crWarning("invalid header buffer size!");
+ WARN(("invalid header buffer size!"));
crServerCrHgsmiCmdComplete(pCmd, VERR_INVALID_PARAMETER);
return VINF_SUCCESS;
@@ -3595,7 +3731,14 @@ int32_t crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t c
PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP pSetup = (PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP)pCtl;
g_pvVRamBase = (uint8_t*)pSetup->pvVRamBase;
g_cbVRam = pSetup->cbVRam;
- cr_server.CltInfo = *pSetup->pCrCmdClientInfo;
+ pSetup->CrCmdServerInfo.hSvr = NULL;
+ pSetup->CrCmdServerInfo.pfnEnable = crVBoxCrCmdEnable;
+ pSetup->CrCmdServerInfo.pfnDisable = crVBoxCrCmdDisable;
+ pSetup->CrCmdServerInfo.pfnCmd = crVBoxCrCmdCmd;
+ pSetup->CrCmdServerInfo.pfnHostCtl = crVBoxCrCmdHostCtl;
+ pSetup->CrCmdServerInfo.pfnGuestCtl = crVBoxCrCmdGuestCtl;
+ pSetup->CrCmdServerInfo.pfnSaveState = crVBoxCrCmdSaveState;
+ pSetup->CrCmdServerInfo.pfnLoadState = crVBoxCrCmdLoadState;
rc = VINF_SUCCESS;
break;
}
@@ -3628,4 +3771,39 @@ int32_t crVBoxServerCrHgsmiCtl(struct VBOXVDMACMD_CHROMIUM_CTL *pCtl, uint32_t c
return rc;
}
+int32_t crVBoxServerHgcmEnable(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hRHCmd, PFNVBOXCRCMDCTL_REMAINING_HOST_COMMAND pfnRHCmd)
+{
+ int rc = VINF_SUCCESS;
+ uint8_t* pCtl;
+ uint32_t cbCtl;
+
+ if (cr_server.numClients)
+ {
+ WARN(("cr_server.numClients(%d) is not NULL", cr_server.numClients));
+ return VERR_INVALID_STATE;
+ }
+
+ for (pCtl = pfnRHCmd(hRHCmd, &cbCtl, rc); pCtl; pCtl = pfnRHCmd(hRHCmd, &cbCtl, rc))
+ {
+ rc = crVBoxCrCmdHostCtl(NULL, pCtl, cbCtl);
+ }
+
+ crVBoxServerDefaultContextSet();
+
+ return VINF_SUCCESS;
+}
+
+int32_t crVBoxServerHgcmDisable()
+{
+ if (cr_server.numClients)
+ {
+ WARN(("cr_server.numClients(%d) is not NULL", cr_server.numClients));
+ return VERR_INVALID_STATE;
+ }
+
+ cr_server.head_spu->dispatch_table.MakeCurrent(0, 0, 0);
+
+ return VINF_SUCCESS;
+}
+
#endif
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp
index e9ae9e78c..10cdf5cfb 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_muralfbo.cpp
@@ -194,7 +194,6 @@ static int crServerRedirMuralDbSyncFb(CRMuralInfo *mural, HCR_FRAMEBUFFER hFb, C
for (uint32_t i = 0; i < mural->cBuffers; ++i)
{
VBOXVR_TEXTURE Tex;
- int rc;
Tex.width = mural->width;
Tex.height = mural->height;
Tex.hwid = mural->aidColorTexs[i];
@@ -687,7 +686,8 @@ DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, ui
|| pScreen->u32LineSize != pitch
|| pScreen->u16BitsPerPixel != 32)
{
- RTRECT Rect;
+ RTRECT SrcRect;
+ RTRECT DstRect;
pScreenshot->Img.cbData = pScreen->u32LineSize * pScreen->u32Height;
if (!pvBuffer)
@@ -711,11 +711,15 @@ DECLEXPORT(int) crServerVBoxScreenshotGet(uint32_t u32Screen, uint32_t width, ui
pScreenshot->Img.height = height;
pScreenshot->Img.bpp = 32;
pScreenshot->Img.pitch = pitch;
- Rect.xLeft = 0;
- Rect.yTop = 0;
- Rect.xRight = pScreen->u32Width;
- Rect.yBottom = pScreen->u32Height;
- int rc = CrFbBltGetContents(hFb, &Rect, 1, &Rect, &pScreenshot->Img);
+ SrcRect.xLeft = 0;
+ SrcRect.yTop = 0;
+ SrcRect.xRight = pScreen->u32Width;
+ SrcRect.yBottom = pScreen->u32Height;
+ DstRect.xLeft = 0;
+ DstRect.yTop = 0;
+ DstRect.xRight = width;
+ DstRect.yBottom = height;
+ int rc = CrFbBltGetContents(hFb, &SrcRect, &DstRect, 1, &DstRect, &pScreenshot->Img);
if (!RT_SUCCESS(rc))
{
WARN(("CrFbBltGetContents failed %d", rc));
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
index 49fa537cd..e1dca8288 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_presenter.cpp
@@ -247,8 +247,8 @@ static void crFbBltImg(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint,
int32_t srcY = pCopyRect->yTop - pSrcDataPoint->y;
Assert(srcX >= 0);
Assert(srcY >= 0);
- Assert(srcX < pSrc->width);
- Assert(srcY < pSrc->height);
+ Assert(srcX < (int32_t)pSrc->width);
+ Assert(srcY < (int32_t)pSrc->height);
int32_t dstX = pCopyRect->xLeft - pDstDataPoint->x;
int32_t dstY = pCopyRect->yTop - pDstDataPoint->y;
@@ -258,7 +258,7 @@ static void crFbBltImg(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint,
uint8_t *pu8Src = ((uint8_t*)pSrc->pvData) + pSrc->pitch * (!fSrcInvert ? srcY : pSrc->height - srcY - 1) + srcX * 4;
uint8_t *pu8Dst = ((uint8_t*)pDst->pvData) + pDst->pitch * dstY + dstX * 4;
- crFbBltMem(pu8Src, fSrcInvert ? -pSrc->pitch : pSrc->pitch, pu8Dst, pDst->pitch, pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop);
+ crFbBltMem(pu8Src, fSrcInvert ? -((int32_t)pSrc->pitch) : (int32_t)pSrc->pitch, pu8Dst, pDst->pitch, pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop);
}
static void crFbBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, bool fSrcInvert, const RTRECT *pCopyRect, const RTPOINT *pDstDataPoint, float strX, float strY, CR_BLITTER_IMG *pDst)
@@ -267,8 +267,8 @@ static void crFbBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcData
int32_t srcY = pCopyRect->yTop - pSrcDataPoint->y;
Assert(srcX >= 0);
Assert(srcY >= 0);
- Assert(srcX < pSrc->width);
- Assert(srcY < pSrc->height);
+ Assert(srcX < (int32_t)pSrc->width);
+ Assert(srcY < (int32_t)pSrc->height);
RTPOINT ScaledDtsDataPoint;
RTRECT ScaledCopyRect;
@@ -315,10 +315,68 @@ static void crFbBltImgScaled(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcData
ScaledDstWidth,
ScaledDstHeight,
pu8Src,
- fSrcInvert ? -pSrc->pitch : pSrc->pitch,
+ fSrcInvert ? -((int32_t)pSrc->pitch) : (int32_t)pSrc->pitch,
pCopyRect->xRight - pCopyRect->xLeft, pCopyRect->yBottom - pCopyRect->yTop);
}
+static void crFbBltImgScaledRects(const CR_BLITTER_IMG *pSrc, const RTPOINT *pSrcDataPoint, bool fSrcInvert, const RTRECT *pCopyRect, const RTPOINT *pDstDataPoint, float strX, float strY, CR_BLITTER_IMG *pDst)
+{
+ int32_t srcX = pCopyRect->xLeft - pSrcDataPoint->x;
+ int32_t srcY = pCopyRect->yTop - pSrcDataPoint->y;
+ Assert(srcX >= 0);
+ Assert(srcY >= 0);
+
+ RTRECT UnscaledCopyRect;
+ VBoxRectUnscaled(pCopyRect, strX, strY, &UnscaledCopyRect);
+
+ srcX = CR_FLOAT_RCAST(int32_t, srcX / strX);
+ srcY = CR_FLOAT_RCAST(int32_t, srcY / strY);
+
+ int32_t UnscaledSrcWidth = UnscaledCopyRect.xRight - UnscaledCopyRect.xLeft;
+ int32_t delta = (int32_t)pSrc->width - srcX - UnscaledSrcWidth;
+ if (delta < 0)
+ UnscaledSrcWidth += delta;
+
+ if (UnscaledSrcWidth <= 0)
+ {
+ LOG(("UnscaledSrcWidth <= 0"));
+ if (UnscaledSrcWidth < 0)
+ WARN(("src width (%d) < 0", UnscaledSrcWidth));
+ return;
+ }
+
+ int32_t UnscaledSrcHeight = UnscaledCopyRect.yBottom - UnscaledCopyRect.yTop;
+ delta = (int32_t)pSrc->height - srcY - UnscaledSrcHeight;
+ if (delta < 0)
+ UnscaledSrcHeight += delta;
+
+ if (UnscaledSrcHeight <= 0)
+ {
+ LOG(("UnscaledSrcHeight <= 0"));
+ if (UnscaledSrcHeight < 0)
+ WARN(("src height (%d) < 0", UnscaledSrcHeight));
+ return;
+ }
+
+ int32_t dstX = pCopyRect->xLeft - pDstDataPoint->x;
+ int32_t dstY = pCopyRect->yTop - pDstDataPoint->y;
+ Assert(dstX >= 0);
+ Assert(dstY >= 0);
+
+
+ uint8_t *pu8Src = ((uint8_t*)pSrc->pvData) + pSrc->pitch * (!fSrcInvert ? srcY : pSrc->height - srcY - 1) + srcX * 4;
+ uint8_t *pu8Dst = ((uint8_t*)pDst->pvData) + pDst->pitch * dstY + dstX * 4;
+
+ CrBmpScale32(pu8Dst, pDst->pitch,
+ pCopyRect->xRight - pCopyRect->xLeft,
+ pCopyRect->yBottom - pCopyRect->yTop,
+ pu8Src,
+ fSrcInvert ? -pSrc->pitch : pSrc->pitch,
+ UnscaledSrcWidth,
+ UnscaledSrcHeight
+ );
+}
+
static void crFbImgFromScreenVram(const VBVAINFOSCREEN *pScreen, void *pvVram, CR_BLITTER_IMG *pImg)
{
pImg->pvData = pvVram;
@@ -337,7 +395,7 @@ static void crFbImgFromFb(HCR_FRAMEBUFFER hFb, CR_BLITTER_IMG *pImg)
crFbImgFromScreenVram(pScreen, pvVram, pImg);
}
-static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
{
VBOXVR_LIST List;
uint32_t c2DRects = 0;
@@ -347,15 +405,17 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
RTPOINT ScaledEntryPoint = {0};
VBOXVR_SCR_COMPOSITOR_CONST_ITERATOR Iter;
- RTPOINT SrcPoint = {pSrcRect->xLeft, pSrcRect->yTop};
- float strX = ((float)pImg->width) / (pSrcRect->xRight - pSrcRect->xLeft);
- float strY = ((float)pImg->height) / (pSrcRect->yBottom - pSrcRect->yTop);
+ int32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
+ int32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
+ int32_t dstWidth = pDstRect->xRight - pDstRect->xLeft;
+ int32_t dstHeight = pDstRect->yBottom - pDstRect->yTop;
- RTPOINT ScaledSrcPoint;
- ScaledSrcPoint.x = CR_FLOAT_RCAST(int32_t, strX * SrcPoint.x);
- ScaledSrcPoint.y = CR_FLOAT_RCAST(int32_t, strY * SrcPoint.y);
+ RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop};
+ float strX = ((float)dstWidth) / srcWidth;
+ float strY = ((float)dstHeight) / srcHeight;
+ bool fScale = (dstWidth != srcWidth || dstHeight != srcHeight);
- RTPOINT ZeroPoint = {0, 0};
+ const RTPOINT ZeroPoint = {0, 0};
VBoxVrListInit(&List);
int rc = VBoxVrListRectsAdd(&List, 1, CrVrScrCompositorRectGet(&hFb->Compositor), NULL);
@@ -387,18 +447,24 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
goto end;
}
- for (uint32_t i = 0; i < cRects; ++i)
+ for (uint32_t j = 0; j < cRegions; ++j)
{
- const RTRECT * pRect = &pRects[i];
- for (uint32_t j = 0; j < cRegions; ++j)
+ /* rects are in dst coordinates,
+ * while the pReg is in source coords
+ * convert */
+ const RTRECT * pReg = &pRegions[j];
+ RTRECT ScaledReg;
+ /* scale */
+ VBoxRectScaled(pReg, strX, strY, &ScaledReg);
+ /* translate */
+ VBoxRectTranslate(&ScaledReg, pDstRect->xLeft, pDstRect->yTop);
+
+ for (uint32_t i = 0; i < cRects; ++i)
{
- const RTRECT * pReg = &pRegions[j];
- RTRECT Intersection;
- VBoxRectIntersected(pRect, pReg, &Intersection);
- if (VBoxRectIsZero(&Intersection))
- continue;
+ const RTRECT * pRect = &pRects[i];
- VBoxRectScale(&Intersection, strX, strY);
+ RTRECT Intersection;
+ VBoxRectIntersected(pRect, &ScaledReg, &Intersection);
if (VBoxRectIsZero(&Intersection))
continue;
@@ -454,8 +520,8 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
width = CR_FLOAT_RCAST(uint32_t, strX * pVrTex->width);
height = CR_FLOAT_RCAST(uint32_t, strY * pVrTex->height);
- ScaledEntryPoint.x = CR_FLOAT_RCAST(int32_t, strX * CrVrScrCompositorEntryRectGet(pEntry)->xLeft);
- ScaledEntryPoint.y = CR_FLOAT_RCAST(int32_t, strY * CrVrScrCompositorEntryRectGet(pEntry)->yTop);
+ ScaledEntryPoint.x = CR_FLOAT_RCAST(int32_t, strX * CrVrScrCompositorEntryRectGet(pEntry)->xLeft) + pDstRect->xLeft;
+ ScaledEntryPoint.y = CR_FLOAT_RCAST(int32_t, strY * CrVrScrCompositorEntryRectGet(pEntry)->yTop) + pDstRect->yTop;
}
rc = CrTdBltDataAcquireScaled(pTex, GL_BGRA, false, width, height, &pSrcImg);
@@ -467,7 +533,7 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
bool fInvert = !(CrVrScrCompositorEntryFlagsGet(pEntry) & CRBLT_F_INVERT_SRC_YCOORDS);
- crFbBltImg(pSrcImg, &ScaledEntryPoint, fInvert, &Intersection, &ScaledSrcPoint, pImg);
+ crFbBltImg(pSrcImg, &ScaledEntryPoint, fInvert, &Intersection, &ZeroPoint, pImg);
CrTdBltDataReleaseScaled(pTex, pSrcImg);
}
@@ -502,36 +568,34 @@ static int crFbBltGetContentsDirect(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect,
goto end;
}
- RTPOINT Pos = {0};
const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor);
- uint32_t fbWidth = (pCompRect->xRight - pCompRect->xLeft);
- uint32_t fbHeight = pCompRect->yBottom - pCompRect->yTop;
-
- uint32_t stretchedWidth = CR_FLOAT_RCAST(uint32_t, strX * fbWidth);
- uint32_t stretchedHeight = CR_FLOAT_RCAST(uint32_t, strY * fbHeight);
-
CR_BLITTER_IMG FbImg;
- bool fScale = fbWidth != stretchedWidth || fbHeight != stretchedHeight;
-
crFbImgFromFb(hFb, &FbImg);
- for (uint32_t i = 0; i < cRects; ++i)
+ for (uint32_t j = 0; j < c2DRects; ++j)
{
- const RTRECT * pRect = &pRects[i];
- for (uint32_t j = 0; j < c2DRects; ++j)
+ const RTRECT * p2DRect = &p2DRects[j];
+ RTRECT ScaledReg;
+ /* scale */
+ VBoxRectScaled(p2DRect, strX, strY, &ScaledReg);
+ /* translate */
+ VBoxRectTranslate(&ScaledReg, pDstRect->xLeft, pDstRect->yTop);
+
+ for (uint32_t i = 0; i < cRects; ++i)
{
- const RTRECT * p2DRect = &p2DRects[j];
+ const RTRECT * pRect = &pRects[i];
RTRECT Intersection;
- VBoxRectIntersected(pRect, p2DRect, &Intersection);
+
+ VBoxRectIntersected(pRect, &ScaledReg, &Intersection);
if (VBoxRectIsZero(&Intersection))
continue;
if (!fScale)
- crFbBltImg(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, pImg);
+ crFbBltImg(&FbImg, &DstPoint, false, &Intersection, &ZeroPoint, pImg);
else
- crFbBltImgScaled(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, strX, strY, pImg);
+ crFbBltImgScaledRects(&FbImg, &DstPoint, false, &Intersection, &ZeroPoint, strX, strY, pImg);
}
}
}
@@ -549,10 +613,21 @@ end:
return rc;
}
-static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
{
- uint32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
- uint32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
+ int32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
+ int32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
+ int32_t dstWidth = pDstRect->xRight - pDstRect->xLeft;
+ int32_t dstHeight = pDstRect->yBottom - pDstRect->yTop;
+
+ RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop};
+ float strX = ((float)dstWidth) / srcWidth;
+ float strY = ((float)dstHeight) / srcHeight;
+
+ RTRECT DstRect;
+ VBoxRectUnscaled(pDstRect, strX, strY, &DstRect);
+ DstRect.xRight = DstRect.xLeft + srcWidth;
+ DstRect.yBottom = DstRect.yTop + srcHeight;
/* destination is bigger than the source, do 3D data stretching with CPU */
CR_BLITTER_IMG Img;
@@ -569,7 +644,7 @@ static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRec
Img.bpp = pImg->bpp;
Img.pitch = Img.width * 4;
- int rc = CrFbBltGetContents(hFb, pSrcRect, cRects, pRects, &Img);
+ int rc = CrFbBltGetContents(hFb, pSrcRect, &DstRect, cRects, pRects, &Img);
if (RT_SUCCESS(rc))
{
CrBmpScale32((uint8_t *)pImg->pvData,
@@ -588,21 +663,187 @@ static int crFbBltGetContentsScaleCPU(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRec
}
-int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+int CrFbBltGetContents(HCR_FRAMEBUFFER hFb, const RTRECT *pSrcRect, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
{
uint32_t srcWidth = pSrcRect->xRight - pSrcRect->xLeft;
uint32_t srcHeight = pSrcRect->yBottom - pSrcRect->yTop;
- if ((srcWidth == pImg->width
- && srcHeight == pImg->height)
+ uint32_t dstWidth = pDstRect->xRight - pDstRect->xLeft;
+ uint32_t dstHeight = pDstRect->yBottom - pDstRect->yTop;
+ if ((srcWidth == dstWidth
+ && srcHeight == dstHeight)
|| !CrFbHas3DData(hFb)
- || (srcWidth * srcHeight > pImg->width * pImg->height))
+ || (srcWidth * srcHeight > dstWidth * dstHeight))
{
- return crFbBltGetContentsDirect(hFb, pSrcRect, cRects, pRects, pImg);
+ return crFbBltGetContentsDirect(hFb, pSrcRect, pDstRect, cRects, pRects, pImg);
}
- return crFbBltGetContentsScaleCPU(hFb, pSrcRect, cRects, pRects, pImg);
+ return crFbBltGetContentsScaleCPU(hFb, pSrcRect, pDstRect, cRects, pRects, pImg);
}
+#if 0
+static int crFbBltPutContentsVram(HCR_FRAMEBUFFER hFb, const RTPOINT *pDstPoint, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg, float strX, float strY)
+{
+ const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor);
+ const RTPOINT ZeroPoint = {0};
+
+ uint32_t fbWidth = (pCompRect->xRight - pCompRect->xLeft);
+ uint32_t fbHeight = pCompRect->yBottom - pCompRect->yTop;
+
+ uint32_t stretchedWidth = CR_FLOAT_RCAST(uint32_t, strX * fbWidth);
+ uint32_t stretchedHeight = CR_FLOAT_RCAST(uint32_t, strY * fbHeight);
+
+ CR_BLITTER_IMG FbImg;
+
+ bool fScale = fbWidth != stretchedWidth || fbHeight != stretchedHeight;
+
+ crFbImgFromFb(hFb, &FbImg);
+
+ RTRECT Intersection;
+
+ for (uint32_t i = 0; i < cRects; ++i)
+ {
+ const RTRECT * pRect = &pRects[i];
+ VBoxRectIntersected(pRect, pCompRect, &Intersection);
+
+ if (VBoxRectIsZero(&Intersection))
+ continue;
+
+ if (!fScale)
+ crFbBltImg(pImg, pDstPoint, false, &Intersection, &ZeroPoint, &FbImg);
+ else
+ crFbBltImgScaled(pImg, pDstPoint, false, &Intersection, &ZeroPoint, strX, strY, &FbImg);
+ }
+
+ return VINF_SUCCESS;
+}
+
+int CrFbBltPutContents(HCR_FRAMEBUFFER hFb, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+{
+ RTPOINT DstPoint = {pDstRect->xLeft, pDstRect->yTop};
+ float strX = ((float)pImg->width) / (pDstRect->xRight - pDstRect->xLeft);
+ float strY = ((float)pImg->height) / (pDstRect->yBottom - pDstRect->yTop);
+
+ int rc = CrFbEntryRegionsAdd(hFb, NULL, const RTPOINT *pPos, cRects, pRects, true)
+ if (!hFb->cUpdating)
+ {
+ WARN(("not updating\n"));
+ return VERR_INVALID_STATE;
+ }
+}
+
+int CrFbBltPutContentsNe(HCR_FRAMEBUFFER hFb, const RTRECT *pDstRect, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg)
+{
+ uint32_t cCompRects;
+ const RTRECT *pCompRects;
+ int rc = CrVrScrCompositorRegionsGet(&hFb->Compositor, &cCompRects, NULL, NULL, &pCompRects);
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("CrVrScrCompositorRegionsGet failed rc %d", rc));
+ return rc;
+ }
+
+ bool fRegChanged = false;
+ for (uint32_t i = 0; i < cCompRects; ++i)
+ {
+ const RTRECT *pCompRect = pCompRects[i];
+ for (uint32_t j = 0; j < cRects; ++j)
+ {
+ const RTRECT *pRect = pRects[j];
+ if (VBoxRectIsIntersect(pCompRect, pRect))
+ {
+ fRegChanged = true;
+ break;
+ }
+ }
+ }
+
+ if (fRegChanged)
+ {
+ rc = CrFbUpdateBegin(hFb);
+ if (RT_SUCCESS(rc))
+ {
+ rc = CrFbBltPutContents(hFb, pDstRect, cRects, pRects, pImg);
+ if (!RT_SUCCESS(rc))
+ WARN(("CrFbBltPutContents failed rc %d", rc));
+ CrFbUpdateEnd(hFb);
+ }
+ else
+ WARN(("CrFbUpdateBegin failed rc %d", rc));
+
+ return rc;
+ }
+
+ return crFbBltPutContentsVram(HCR_FRAMEBUFFER hFb, const RTPOINT *pDstPoint, uint32_t cRects, const RTRECT *pRects, CR_BLITTER_IMG *pImg, float strX, float strY);
+
+ const RTPOINT ZeroPoint = {0, 0};
+
+ c2DRects = VBoxVrListRectsCount(&List);
+ if (c2DRects)
+ {
+ if (g_CrPresenter.cbTmpBuf2 < c2DRects * sizeof (RTRECT))
+ {
+ if (g_CrPresenter.pvTmpBuf2)
+ RTMemFree(g_CrPresenter.pvTmpBuf2);
+
+ g_CrPresenter.cbTmpBuf2 = (c2DRects + 10) * sizeof (RTRECT);
+ g_CrPresenter.pvTmpBuf2 = RTMemAlloc(g_CrPresenter.cbTmpBuf2);
+ if (!g_CrPresenter.pvTmpBuf2)
+ {
+ WARN(("RTMemAlloc failed!"));
+ g_CrPresenter.cbTmpBuf2 = 0;
+ rc = VERR_NO_MEMORY;
+ goto end;
+ }
+ }
+
+ RTRECT *p2DRects = (RTRECT *)g_CrPresenter.pvTmpBuf2;
+
+ rc = VBoxVrListRectsGet(&List, c2DRects, p2DRects);
+ if (!RT_SUCCESS(rc))
+ {
+ WARN(("VBoxVrListRectsGet failed, rc %d", rc));
+ goto end;
+ }
+
+ RTPOINT Pos = {0};
+ const RTRECT *pCompRect = CrVrScrCompositorRectGet(&hFb->Compositor);
+
+ CR_BLITTER_IMG FbImg;
+
+ crFbImgFromFb(hFb, &FbImg);
+
+ for (uint32_t i = 0; i < cRects; ++i)
+ {
+ const RTRECT * pRect = &pRects[i];
+ for (uint32_t j = 0; j < c2DRects; ++j)
+ {
+ const RTRECT * p2DRect = &p2DRects[j];
+ RTRECT Intersection;
+ VBoxRectIntersected(pRect, p2DRect, &Intersection);
+ if (VBoxRectIsZero(&Intersection))
+ continue;
+
+ if (!fScale)
+ crFbBltImg(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, pImg);
+ else
+ crFbBltImgScaled(&FbImg, &ZeroPoint, false, &Intersection, &SrcPoint, strX, strY, pImg);
+ }
+ }
+ }
+
+end:
+
+ if (pEnteredTex)
+ CrTdBltLeave(pEnteredTex);
+
+ if (pEnteredBlitter)
+ CrBltLeave(pEnteredBlitter);
+
+ VBoxVrListClear(&List);
+
+ return rc;
+}
+#endif
int CrFbResize(CR_FRAMEBUFFER *pFb, const struct VBVAINFOSCREEN * pScreen, void *pvVRAM)
{
@@ -3583,7 +3824,7 @@ HCR_FRAMEBUFFER CrPMgrFbGetEnabled(uint32_t idScreen)
static HCR_FRAMEBUFFER crPMgrFbGetNextEnabled(uint32_t i)
{
- for (;i < cr_server.screenCount; ++i)
+ for (;i < (uint32_t)cr_server.screenCount; ++i)
{
HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(i);
if (hFb)
@@ -3595,7 +3836,7 @@ static HCR_FRAMEBUFFER crPMgrFbGetNextEnabled(uint32_t i)
static HCR_FRAMEBUFFER crPMgrFbGetNextInitialized(uint32_t i)
{
- for (;i < cr_server.screenCount; ++i)
+ for (;i < (uint32_t)cr_server.screenCount; ++i)
{
HCR_FRAMEBUFFER hFb = CrPMgrFbGetInitialized(i);
if (hFb)
@@ -3943,7 +4184,7 @@ int CrPMgrHlpGlblUpdateBegin(CR_FBMAP *pMap)
/*helper function that calls CrFbUpdateEnd for all framebuffers being updated */
void CrPMgrHlpGlblUpdateEnd(CR_FBMAP *pMap)
{
- for (uint32_t i = 0; i < cr_server.screenCount; ++i)
+ for (uint32_t i = 0; i < (uint32_t)cr_server.screenCount; ++i)
{
if (!CrFBmIsSet(pMap, i))
continue;
@@ -4412,12 +4653,12 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
if (u8Flags & (VBOXCMDVBVA_OPF_ALLOC_DSTPRIMARY | VBOXCMDVBVA_OPF_ALLOC_SRCPRIMARY))
{
VBOXCMDVBVA_BLT_PRIMARY *pBlt = (VBOXCMDVBVA_BLT_PRIMARY*)pCmd;
- uint8_t u8PrimaryID = pBlt->Hdr.u8PrimaryID;
+ uint8_t u8PrimaryID = pBlt->Hdr.u.u8PrimaryID;
HCR_FRAMEBUFFER hFb = CrPMgrFbGetEnabled(u8PrimaryID);
if (!hFb)
{
WARN(("request to present on disabled framebuffer, ignore"));
- pCmd->i8Result = -1;
+ pCmd->u.i8Result = -1;
return VINF_SUCCESS;
}
@@ -4435,7 +4676,7 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
{
WARN(("RTMemAlloc failed!"));
g_CrPresenter.cbTmpBuf = 0;
- pCmd->i8Result = -1;
+ pCmd->u.i8Result = -1;
return VINF_SUCCESS;
}
}
@@ -4455,23 +4696,24 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTID)
{
/* TexPresent */
- texId = pBlt->alloc.id;
+ texId = pBlt->alloc.u.id;
}
else
{
- VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.offVRAM;
+ VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.u.offVRAM;
const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height;
if (offVRAM >= g_cbVRam
|| offVRAM + cbScreen >= g_cbVRam)
{
WARN(("invalid param"));
- pCmd->i8Result = -1;
+ pCmd->u.i8Result = -1;
return VINF_SUCCESS;
}
uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
texId = 0;
+// cr_server.CrCmdClientInfo.pfnCltScrUpdateBegin(cr_server.CrCmdClientInfo.hCltScr);
/*todo: notify VGA device to perform updates */
}
@@ -4481,7 +4723,7 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
{
/* blit from one primary to another primary, wow */
WARN(("not implemented"));
- pCmd->i8Result = -1;
+ pCmd->u.i8Result = -1;
return VINF_SUCCESS;
}
}
@@ -4491,38 +4733,43 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
/* blit from primary to non-primary */
if (u8Flags & VBOXCMDVBVA_OPF_ALLOC_DSTID)
{
- uint32_t texId = pBlt->alloc.id;
+ uint32_t texId = pBlt->alloc.u.id;
WARN(("not implemented"));
- pCmd->i8Result = -1;
+ pCmd->u.i8Result = -1;
return VINF_SUCCESS;
}
else
{
- VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.offVRAM;
+ VBOXCMDVBVAOFFSET offVRAM = pBlt->alloc.u.offVRAM;
const VBVAINFOSCREEN *pScreen = CrFbGetScreenInfo(hFb);
uint32_t cbScreen = pScreen->u32LineSize * pScreen->u32Height;
if (offVRAM >= g_cbVRam
|| offVRAM + cbScreen >= g_cbVRam)
{
WARN(("invalid param"));
- pCmd->i8Result = -1;
+ pCmd->u.i8Result = -1;
return VINF_SUCCESS;
}
uint8_t *pu8Buf = g_pvVRamBase + offVRAM;
- RTRECT Rect;
- Rect.xLeft = pBlt->Pos.x;
- Rect.yTop = pBlt->Pos.y;
- Rect.xRight = Rect.xLeft + pScreen->u32Width;
- Rect.yBottom = Rect.yTop + pScreen->u32Height;
+ RTRECT SrcRect;
+ SrcRect.xLeft = 0;
+ SrcRect.yTop = 0;
+ SrcRect.xRight = pScreen->u32Width;
+ SrcRect.yBottom = pScreen->u32Height;
+ RTRECT DstRect;
+ DstRect.xLeft = pBlt->Pos.x;
+ DstRect.yTop = pBlt->Pos.y;
+ DstRect.xRight = DstRect.xLeft + pScreen->u32Width;
+ DstRect.yBottom = DstRect.yTop + pScreen->u32Height;
CR_BLITTER_IMG Img;
crFbImgFromScreenVram(pScreen, pu8Buf, &Img);
- int rc = CrFbBltGetContents(hFb, &Rect, cRects, pRects, &Img);
+ int rc = CrFbBltGetContents(hFb, &SrcRect, &DstRect, cRects, pRects, &Img);
if (!RT_SUCCESS(rc))
{
WARN(("CrFbBltGetContents failed %d", rc));
- pCmd->i8Result = -1;
+ pCmd->u.i8Result = -1;
return VINF_SUCCESS;
}
}
@@ -4531,10 +4778,10 @@ int32_t crVBoxServerCrCmdBltProcess(PVBOXCMDVBVA_HDR pCmd, uint32_t cbCmd)
else
{
WARN(("not implemented"));
- pCmd->i8Result = -1;
+ pCmd->u.i8Result = -1;
return VINF_SUCCESS;
}
- pCmd->i8Result = 0;
+ pCmd->u.i8Result = 0;
return VINF_SUCCESS;
}
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c
index bfadeda92..29670790a 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_stream.c
@@ -281,6 +281,28 @@ crServerDeleteClient( CRClient *client )
pNode->next = cr_server.pCleanupClient;
cr_server.pCleanupClient = pNode;
}
+
+ if (!cr_server.numClients)
+ {
+ /* if no clients, the guest driver may be unloaded,
+ * and thus the visible regions situation might not be under control anymore,
+ * so cleanup the 3D framebuffer data here
+ * @todo: what really should happen is that guest driver on unload
+ * posts some request to host that would copy the current framebuffer 3D data to the 2D buffer
+ * (i.e. to the memory used by the standard IFramebuffer API) */
+ HCR_FRAMEBUFFER hFb;
+ for (hFb = CrPMgrFbGetFirstEnabled(); hFb; hFb = CrPMgrFbGetNextEnabled(hFb))
+ {
+ int rc = CrFbUpdateBegin(hFb);
+ if (RT_SUCCESS(rc))
+ {
+ CrFbRegionsClear(hFb);
+ CrFbUpdateEnd(hFb);
+ }
+ else
+ WARN(("CrFbUpdateBegin failed %d", rc));
+ }
+ }
}
/**
diff --git a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
index b74c6224f..693512557 100644
--- a/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
+++ b/src/VBox/HostServices/SharedOpenGL/crserverlib/server_window.c
@@ -18,26 +18,43 @@ crServerDispatchWindowCreate(const char *dpyName, GLint visBits)
return crServerDispatchWindowCreateEx(dpyName, visBits, -1);
}
-GLint crServerMuralInit(CRMuralInfo *mural, const char *dpyName, GLint visBits, GLint preloadWinID)
+GLint crServerMuralInit(CRMuralInfo *mural, GLboolean fGuestWindow, GLint visBits, GLint preloadWinID)
{
CRMuralInfo *defaultMural;
GLint dims[2];
GLint windowID = -1;
- GLint spuWindow;
- int rc;
+ GLint spuWindow = 0;
GLint realVisBits = visBits;
+ const char *dpyName = "";
crMemset(mural, 0, sizeof (*mural));
if (cr_server.fVisualBitsDefault)
realVisBits = cr_server.fVisualBitsDefault;
- /*
- * Have first SPU make a new window.
- */
- spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, realVisBits );
- if (spuWindow < 0) {
- return spuWindow;
+#ifdef RT_OS_DARWIN
+ if (fGuestWindow)
+ {
+ CRMuralInfo *dummy = crServerGetDummyMural(visBits);
+ if (!dummy)
+ {
+ WARN(("crServerGetDummyMural failed"));
+ return -1;
+ }
+ spuWindow = dummy->spuWindow;
+ mural->fIsDummyRefference = GL_TRUE;
+ }
+ else
+#endif
+ {
+ /*
+ * Have first SPU make a new window.
+ */
+ spuWindow = cr_server.head_spu->dispatch_table.WindowCreate( dpyName, realVisBits );
+ if (spuWindow < 0) {
+ return spuWindow;
+ }
+ mural->fIsDummyRefference = GL_FALSE;
}
/* get initial window size */
@@ -121,7 +138,7 @@ GLint crServerDispatchWindowCreateEx(const char *dpyName, GLint visBits, GLint p
return -1;
}
- windowID = crServerMuralInit(mural, dpyName, visBits, preloadWinID);
+ windowID = crServerMuralInit(mural, GL_TRUE, visBits, preloadWinID);
if (windowID < 0)
{
crWarning("crServerMuralInit failed!");
@@ -181,7 +198,7 @@ void crServerMuralTerm(CRMuralInfo *mural)
* which might lead to muralFBO (offscreen rendering) gl entities being created in a scope of that context */
cr_server.head_spu->dispatch_table.MakeCurrent(dummyMural->spuWindow, 0, cr_server.MainContextInfo.SpuContext);
cr_server.currentWindow = -1;
- cr_server.currentMural = NULL;
+ cr_server.currentMural = dummyMural;
}
else
{
@@ -202,7 +219,10 @@ void crServerMuralTerm(CRMuralInfo *mural)
}
}
- cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
+ if (!mural->fIsDummyRefference)
+ cr_server.head_spu->dispatch_table.WindowDestroy( mural->spuWindow );
+
+ mural->spuWindow = 0;
if (mural->pVisibleRects)
{
diff --git a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
index 1175b29f6..1bd745a80 100644
--- a/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
+++ b/src/VBox/HostServices/SharedOpenGL/render/renderspu_wgl.c
@@ -1232,13 +1232,42 @@ GLboolean renderspu_SystemVBoxCreateWindow( VisualInfo *visual, GLboolean showIt
return GL_TRUE;
}
+static void renderspuWindowRgnApply(WindowInfo *window)
+{
+ HRGN hRgn = window->hRgn;
+ if (hRgn)
+ {
+ /* note: according to the docs, SetWindowRgn owns the regions after it is called,
+ * and the regions will be freed automatically when needed,
+ * i.e. the caller should not do that.
+ * this is why we need to make a copy of the regions to be passed in */
+
+ int result;
+ hRgn = CreateRectRgn(0, 0, 0, 0);
+ if (!hRgn)
+ {
+ WARN(("CreateRectRgn failed"));
+ return;
+ }
+
+ result = CombineRgn(hRgn, window->hRgn, NULL, RGN_COPY);
+ if (result == ERROR)
+ {
+ WARN(("CombineRgn failed"));
+ return;
+ }
+ }
+
+ SetWindowRgn(window->hWnd, hRgn, true);
+}
+
/* Either show or hide the render SPU's window. */
void renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt )
{
if (showIt)
{
crDebug("SHOW renderspu_SystemShowWindow: %x", window->hWnd);
- SetWindowRgn(window->hWnd, window->hRgn, true);
+ renderspuWindowRgnApply(window);
}
else
{
@@ -1246,7 +1275,9 @@ void renderspu_SystemShowWindow( WindowInfo *window, GLboolean showIt )
crDebug("HIDE renderspu_SystemShowWindow: %x", window->hWnd);
hRgn = CreateRectRgn(0, 0, 0, 0);
SetWindowRgn(window->hWnd, hRgn, true);
- DeleteObject(hRgn);
+ /* note: according to the docs, SetWindowRgn owns the regions after it is called,
+ * and the regions will be freed automatically when needed,
+ * i.e. the caller should not do that */
}
window->visible = showIt;
}
@@ -1571,12 +1602,12 @@ void renderspu_SystemWindowVisibleRegion(WindowInfo *window, GLint cRects, const
DeleteObject(hTmpRgn);
}
+ window->hRgn = hRgn;
+
if (window->visible)
- SetWindowRgn(window->hWnd, hRgn, true);
+ renderspuWindowRgnApply(window);
crDebug("Render SPU: SetWindowRgn (%x, cRects=%i)", window->hWnd, cRects);
-
- window->hRgn = hRgn;
}
static void renderspuHandleWindowMessages( HWND hWnd )