Changeset 35150 in vbox for trunk/src/VBox/Additions/x11/vboxvideo
- Timestamp:
- Dec 15, 2010 4:33:59 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c
r35048 r35150 1281 1281 } 1282 1282 1283 /** Get the index of the screen we will use as the primary one. This is in1284 * fact the first screen located fully inside the virtual desktop, or zero1285 * if none are. Screens which are not fully inside will be set up to be1286 * identical to the primary one, so from the host's point of view the first1287 * screen can always be treated as the primary. */1288 static uint32_t1289 vboxGetPrimaryIndex(ScrnInfoPtr pScrn)1290 {1291 VBOXPtr pVBox = VBOXGetRec(pScrn);1292 unsigned i;1293 for (i = 0; i < pVBox->cScreens; ++i)1294 if ( pVBox->aScreenLocation[i].x + pVBox->aScreenLocation[i].cx1295 <= pScrn->virtualX1296 && pVBox->aScreenLocation[i].y + pVBox->aScreenLocation[i].cy1297 <= pScrn->virtualY)1298 return i;1299 return 0; /* This will probably look bad if it can happen. */1300 }1301 1302 /**1303 * This is a rather un-transparent workaround for the fact that HGSMI doesn't1304 * let us disable screens. If a guest screen is not enabled we set it to1305 * match the display on the primary screen.1306 */1307 static uint32_t1308 vboxGetRealLocationIndex(ScrnInfoPtr pScrn, unsigned i)1309 {1310 VBOXPtr pVBox = VBOXGetRec(pScrn);1311 if ( pVBox->aScreenLocation[i].x + pVBox->aScreenLocation[i].cx1312 <= pScrn->virtualX1313 && pVBox->aScreenLocation[i].y + pVBox->aScreenLocation[i].cy1314 <= pScrn->virtualY)1315 return i;1316 return vboxGetPrimaryIndex(pScrn);1317 1318 }1319 1320 1283 /** Set a graphics mode. Poke any required values into registers, do an HGSMI 1321 1284 * mode set and tell the host we support advanced graphics functions. This 1322 * procedure is complicated by three things. 1323 * - The first is that X.Org can implicitly disable a screen by resizing the 1324 * virtual framebuffer so that the screen is no longer inside it. We have 1325 * to spot and handle this. 1326 * - The second is that HGSMI doesn't actually let us disable a monitor. We 1327 * should add this at some point, but for now I want to implement the 1328 * protocol and not extend it, so I "disable" monitors by setting them to 1329 * show the same thing as the first enabled monitor (see @a 1330 * vboxGetPrimaryIndex). 1331 * - The third is that the code has to work around HGSMI's special handling of 1332 * the primary screen. X.Org doesn't have the same concept, and can move 1333 * the primary about the virtual desktop (not such an issue) and can also 1334 * disable the first screen. 1285 * procedure is complicated by the fact that X.Org can implicitly disable a 1286 * screen by resizing the virtual framebuffer so that the screen is no longer 1287 * inside it. We have to spot and handle this. 1335 1288 */ 1336 1289 static Bool … … 1339 1292 { 1340 1293 VBOXPtr pVBox = VBOXGetRec(pScrn); 1341 Bool rc = TRUE; 1342 Bool fPrimaryMoved = FALSE; 1343 uint32_t cIndex; 1344 uint32_t cwReal, chReal; 1345 uint32_t offStart, offStartReal; 1346 int32_t cxReal, cyReal, cxOld, cyOld; 1294 Bool rc = TRUE, fActive = TRUE; 1295 uint32_t offStart, cwReal; 1347 1296 1348 1297 TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n", 1349 1298 cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth); 1350 cxOld = pVBox->aScreenLocation[cDisplay].cx;1351 cyOld = pVBox->aScreenLocation[cDisplay].cy;1352 1299 pVBox->aScreenLocation[cDisplay].cx = cWidth; 1353 1300 pVBox->aScreenLocation[cDisplay].cy = cHeight; 1354 1301 pVBox->aScreenLocation[cDisplay].x = x; 1355 1302 pVBox->aScreenLocation[cDisplay].y = y; 1356 cIndex = vboxGetRealLocationIndex(pScrn, cDisplay); 1357 cwReal = pVBox->aScreenLocation[cIndex].cx; 1358 chReal = pVBox->aScreenLocation[cIndex].cy; 1359 cxReal = pVBox->aScreenLocation[cIndex].x; 1360 cyReal = pVBox->aScreenLocation[cIndex].y; 1361 offStart = cyReal * pVBox->cbLine + cxReal * vboxBPP(pScrn) / 8; 1362 /* Silently fail if the mode - specifically the virtual width - is too 1363 * large for VRAM as we sometimes have to do this - see comments in 1303 offStart = y * pVBox->cbLine + x * vboxBPP(pScrn) / 8; 1304 /* Deactivate the screen if the mode - specifically the virtual width - is 1305 * too large for VRAM as we sometimes have to do this - see comments in 1364 1306 * VBOXPreInit. */ 1365 if (offStart + pVBox->cbLine * chReal > pVBox->cbFramebuffer) 1366 return TRUE; 1307 if (offStart + pVBox->cbLine * cHeight > pVBox->cbFramebuffer) 1308 fActive = FALSE; 1309 /* Deactivate the screen if it is outside of the virtual framebuffer and 1310 * clamp it to lie inside if it is partly outside. */ 1311 if (x >= pScrn->displayWidth || x + (int) cWidth <= 0) 1312 fActive = FALSE; 1313 else 1314 cwReal = RT_MIN((int) cWidth, pScrn->displayWidth - x); 1367 1315 /* Don't fiddle with the hardware if we are switched 1368 1316 * to a virtual terminal. */ 1369 if (!pVBox->vtSwitch) 1370 { 1371 TRACE_LOG("setting mode. cWidth=%u, cHeight=%u, cwReal=%u, chReal=%u, pScrn->virtualX=%d, pScrn->virtualY=%d, vboxBPP(pScrn)=%d, x=%d, y=%d, cDisplay=%u, cIndex=%u, cxReal=%d, cyReal=%d, pVBox->cbLine=%d\n", 1372 cWidth, cHeight, cwReal, chReal, pScrn->virtualX, 1373 pScrn->virtualY, vboxBPP(pScrn), x, y, cDisplay, 1374 cIndex, cxReal, cyReal, pVBox->cbLine); 1317 if (!pVBox->vtSwitch && fActive) 1318 { 1375 1319 if (cDisplay == 0) 1376 VBoxVideoSetModeRegisters(cwReal, c hReal, pScrn->displayWidth,1377 vboxBPP(pScrn), cxReal, cyReal);1320 VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth, 1321 vboxBPP(pScrn), x, y); 1378 1322 /* Tell the host we support graphics */ 1379 1323 if (vbox_device_available(pVBox)) … … 1383 1327 && (pVBox->fHaveHGSMI) 1384 1328 && !pVBox->vtSwitch) 1385 VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, cxReal, cyReal, 1386 offStart, pVBox->cbLine, cwReal, chReal, 1387 vboxBPP(pScrn)); 1329 VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y, 1330 offStart, pVBox->cbLine, cwReal, cHeight, 1331 vboxBPP(pScrn), 1332 VBVA_SCREEN_F_ACTIVE 1333 | (fActive ? 0: VBVA_SCREEN_F_DISABLED)); 1388 1334 TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE"); 1389 1335 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.