VirtualBox

Ignore:
Timestamp:
Dec 15, 2010 4:33:59 PM (14 years ago)
Author:
vboxsync
Message:

Additions/VBoxVideo: support disabling the screen via VBVA_SCREEN_F_DISABLE

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c

    r35048 r35150  
    12811281}
    12821282
    1283 /** Get the index of the screen we will use as the primary one.  This is in
    1284  * fact the first screen located fully inside the virtual desktop, or zero
    1285  * if none are.  Screens which are not fully inside will be set up to be
    1286  * identical to the primary one, so from the host's point of view the first
    1287  * screen can always be treated as the primary. */
    1288 static uint32_t
    1289 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].cx
    1295                <= pScrn->virtualX
    1296             &&    pVBox->aScreenLocation[i].y + pVBox->aScreenLocation[i].cy
    1297                <= 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't
    1304  * let us disable screens.  If a guest screen is not enabled we set it to
    1305  * match the display on the primary screen.
    1306  */
    1307 static uint32_t
    1308 vboxGetRealLocationIndex(ScrnInfoPtr pScrn, unsigned i)
    1309 {
    1310     VBOXPtr pVBox = VBOXGetRec(pScrn);
    1311     if (      pVBox->aScreenLocation[i].x + pVBox->aScreenLocation[i].cx
    1312            <= pScrn->virtualX
    1313         &&    pVBox->aScreenLocation[i].y + pVBox->aScreenLocation[i].cy
    1314            <= pScrn->virtualY)
    1315         return i;
    1316     return vboxGetPrimaryIndex(pScrn);
    1317    
    1318 }
    1319 
    13201283/** Set a graphics mode.  Poke any required values into registers, do an HGSMI
    13211284 * 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.
    13351288 */
    13361289static Bool
     
    13391292{
    13401293    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;
    13471296
    13481297    TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n",
    13491298              cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth);
    1350     cxOld = pVBox->aScreenLocation[cDisplay].cx;
    1351     cyOld = pVBox->aScreenLocation[cDisplay].cy;
    13521299    pVBox->aScreenLocation[cDisplay].cx = cWidth;
    13531300    pVBox->aScreenLocation[cDisplay].cy = cHeight;
    13541301    pVBox->aScreenLocation[cDisplay].x = x;
    13551302    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
    13641306     * 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);
    13671315    /* Don't fiddle with the hardware if we are switched
    13681316     * 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    {
    13751319        if (cDisplay == 0)
    1376             VBoxVideoSetModeRegisters(cwReal, chReal, pScrn->displayWidth,
    1377                                       vboxBPP(pScrn), cxReal, cyReal);
     1320            VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth,
     1321                                      vboxBPP(pScrn), x, y);
    13781322        /* Tell the host we support graphics */
    13791323        if (vbox_device_available(pVBox))
     
    13831327        && (pVBox->fHaveHGSMI)
    13841328        && !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));
    13881334    TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
    13891335    return rc;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette