DECLEXPORT(int32_t) crVBoxServerMapScreen(int sIndex, int32_t x, int32_t y, uint32_t w, uint32_t h, uint64_t winID) { crDebug("crVBoxServerMapScreen(%i) [%i,%i:%u,%u %x]", sIndex, x, y, w, h, winID); if (sIndex<0 || sIndex>=cr_server.screenCount) return VERR_INVALID_PARAMETER; if (MAPPED(SCREEN(sIndex)) && SCREEN(sIndex).winID!=winID) { crDebug("Mapped screen[%i] is being remapped.", sIndex); crVBoxServerUnmapScreen(sIndex); } SCREEN(sIndex).winID = winID; SCREEN(sIndex).x = x; SCREEN(sIndex).y = y; SCREEN(sIndex).w = w; SCREEN(sIndex).h = h; renderspuSetWindowId(SCREEN(sIndex).winID); crHashtableWalk(cr_server.muralTable, crVBoxServerReparentMuralCB, &sIndex); renderspuSetWindowId(SCREEN(0).winID); crHashtableWalk(cr_server.muralTable, crVBoxServerCheckMuralCB, NULL); #ifndef WINDOWS /*Restore FB content for clients, which have current window on a screen being remapped*/ { GLint i; for (i = 0; i < cr_server.numClients; i++) { cr_server.curClient = cr_server.clients[i]; if (cr_server.curClient->currentCtx && (cr_server.curClient->currentCtx->buffer.pFrontImg || cr_server.curClient->currentCtx->buffer.pBackImg) && cr_server.curClient->currentMural && cr_server.curClient->currentMural->screenId == sIndex && cr_server.curClient->currentCtx->buffer.storedHeight == h && cr_server.curClient->currentCtx->buffer.storedWidth == w) { int clientWindow = cr_server.curClient->currentWindow; int clientContext = cr_server.curClient->currentContextNumber; if (clientWindow && clientWindow != cr_server.currentWindow) { crServerDispatchMakeCurrent(clientWindow, 0, clientContext); } crStateApplyFBImage(cr_server.curClient->currentCtx); } } cr_server.curClient = NULL; } #endif return VINF_SUCCESS; }
DECLEXPORT(int32_t) crVBoxServerUnmapScreen(int sIndex) { crDebug("crVBoxServerUnmapScreen(%i)", sIndex); if (sIndex<0 || sIndex>=cr_server.screenCount) return VERR_INVALID_PARAMETER; if (MAPPED(SCREEN(sIndex))) { SCREEN(sIndex).winID = 0; renderspuSetWindowId(0); crHashtableWalk(cr_server.muralTable, crVBoxServerReparentMuralCB, &sIndex); } renderspuSetWindowId(SCREEN(0).winID); return VINF_SUCCESS; }
void crServerCheckMuralGeometry(CRMuralInfo *mural) { int tlS, brS, trS, blS; int overlappingScreenCount, primaryS, i; if (!mural->width || !mural->height) return; if (cr_server.screenCount<2 && !cr_server.bForceOffscreenRendering) { CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId]; CRASSERT(cr_server.screenCount>0); mural->hX = mural->gX-cr_server.screen[0].x; mural->hY = mural->gY-cr_server.screen[0].y; cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y); return; } tlS = crServerGetPointScreen(mural->gX, mural->gY); brS = crServerGetPointScreen(mural->gX+mural->width-1, mural->gY+mural->height-1); if (tlS==brS && tlS>=0) { overlappingScreenCount = 1; primaryS = tlS; } else { trS = crServerGetPointScreen(mural->gX+mural->width-1, mural->gY); blS = crServerGetPointScreen(mural->gX, mural->gY+mural->height-1); primaryS = -1; overlappingScreenCount = 0; for (i=0; i<cr_server.screenCount; ++i) { if ((i==tlS) || (i==brS) || (i==trS) || (i==blS) || crServerMuralCoverScreen(mural, i)) { overlappingScreenCount++; primaryS = primaryS<0 ? i:primaryS; } } if (!overlappingScreenCount) { primaryS = 0; } } if (primaryS!=mural->screenId) { mural->screenId = primaryS; renderspuSetWindowId(cr_server.screen[primaryS].winID); renderspuReparentWindow(mural->spuWindow); renderspuSetWindowId(cr_server.screen[0].winID); } mural->hX = mural->gX-cr_server.screen[primaryS].x; mural->hY = mural->gY-cr_server.screen[primaryS].y; if (overlappingScreenCount<2 && !cr_server.bForceOffscreenRendering) { CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId]; if (mural->bUseFBO) { crServerRedirMuralFBO(mural, GL_FALSE); crServerDeleteMuralFBO(mural); } cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y); } else { if (mural->spuWindow) { if (!mural->bUseFBO) { crServerRedirMuralFBO(mural, GL_TRUE); } else { if (mural->width!=mural->fboWidth || mural->height!=mural->height) { crServerRedirMuralFBO(mural, GL_FALSE); crServerDeleteMuralFBO(mural); crServerRedirMuralFBO(mural, GL_TRUE); } } } #ifdef DEBUG_misha else { Assert(!mural->bUseFBO); } #endif if (!mural->bUseFBO) { CRScreenViewportInfo *pVieport = &cr_server.screenVieport[mural->screenId]; cr_server.head_spu->dispatch_table.WindowPosition(mural->spuWindow, mural->hX - pVieport->x, mural->hY - pVieport->y); } } if (mural->pvOutputRedirectInstance) { cr_server.outputRedirect.CRORGeometry(mural->pvOutputRedirectInstance, mural->hX, mural->hY, mural->width, mural->height); } }