VirtualBox

Changeset 72352 in vbox for trunk/src


Ignore:
Timestamp:
May 26, 2018 12:37:50 PM (7 years ago)
Author:
vboxsync
Message:

Main, VMMDev: implemented IDisplay::SetScreenLayout, VMMDev multimonitor resize request and VBoxManage controlvm setscreenlayout. bugref:8393

Location:
trunk/src/VBox
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDisplay.cpp

    r69500 r72352  
    769769}
    770770
     771static void doResize(PVBOXDISPLAYCONTEXT pCtx,
     772                     uint32_t iDisplay,
     773                     uint32_t cx,
     774                     uint32_t cy,
     775                     uint32_t cBits,
     776                     bool     fEnabled,
     777                     uint32_t cxOrigin,
     778                     uint32_t cyOrigin,
     779                     bool     fChangeOrigin)
     780{
     781    for (;;)
     782    {
     783        VBOXDISPLAY_DRIVER_TYPE enmDriverType = getVBoxDisplayDriverType(pCtx);
     784        if (enmDriverType == VBOXDISPLAY_DRIVER_TYPE_UNKNOWN)
     785        {
     786            LogFlowFunc(("vboxDisplayDriver is not active\n"));
     787            break;
     788        }
     789
     790        if (pCtx->pfnChangeDisplaySettingsEx != 0)
     791        {
     792            LogFlowFunc(("Detected W2K or later\n"));
     793            if (!ResizeDisplayDevice(pCtx,
     794                                     iDisplay,
     795                                     cx,
     796                                     cy,
     797                                     cBits,
     798                                     fEnabled,
     799                                     cxOrigin,
     800                                     cyOrigin,
     801                                     fChangeOrigin,
     802                                     true /*fExtDispSup*/ ))
     803            {
     804                LogFlowFunc(("ResizeDipspalyDevice return 0\n"));
     805                break;
     806            }
     807
     808        }
     809        else
     810        {
     811            LogFlowFunc(("Detected NT\n"));
     812            ResizeDisplayDeviceNT4(cx, cy, cBits);
     813            break;
     814        }
     815
     816        /* Retry the change a bit later. */
     817        RTThreadSleep(1000);
     818    }
     819}
     820
    771821/**
    772822 * Thread function to wait for and process display change requests.
     
    821871            {
    822872                LogFlowFunc(("going to get display change information\n"));
     873
     874#if 0
     875                /* Prototype code which processes the multimonitor resize request. */
     876                VMMDevDisplayDef aDisplays[64];
     877                uint32_t cDisplays = VBoxDisplayGetCount();
     878                rc = VbglR3GetDisplayChangeRequestMulti(cDisplays, &cDisplays, &aDisplays[0], true /* fAck */);
     879                if (RT_SUCCESS(rc))
     880                {
     881                    LogRel(("Got multi resize request %d displays\n", cDisplays));
     882
     883                    uint32_t i;
     884                    for (i = 0; i < cDisplays; ++i)
     885                    {
     886                        LogRel(("[%d]: %d 0x%02X %d,%d %dx%d %d\n",
     887                                 i, aDisplays[i].idDisplay,
     888                                 aDisplays[i].fDisplayFlags,
     889                                 aDisplays[i].xOrigin,
     890                                 aDisplays[i].yOrigin,
     891                                 aDisplays[i].cx,
     892                                 aDisplays[i].cy,
     893                                 aDisplays[i].cBitsPerPixel));
     894
     895                        doResize(pCtx,
     896                                 aDisplays[i].idDisplay,
     897                                 (aDisplays[i].fDisplayFlags & VMMDEV_DISPLAY_CX) ? aDisplays[i].cx : 0,
     898                                 (aDisplays[i].fDisplayFlags & VMMDEV_DISPLAY_CY) ? aDisplays[i].cy : 0,
     899                                 (aDisplays[i].fDisplayFlags & VMMDEV_DISPLAY_BPP) ? aDisplays[i].cBitsPerPixel : 0,
     900                                 !RT_BOOL(aDisplays[i].fDisplayFlags & VMMDEV_DISPLAY_DISABLED),
     901                                 aDisplays[i].xOrigin,
     902                                 aDisplays[i].yOrigin,
     903                                 RT_BOOL(aDisplays[i].fDisplayFlags & VMMDEV_DISPLAY_ORIGIN));
     904                    }
     905
     906                    continue; /* Done */
     907                }
     908                /* Fall back to the single monitor resize request. */
     909#endif
    823910
    824911                /*
     
    850937                                 iDisplay, cx, cy, cBits, fEnabled, cxOrigin, cyOrigin, fChangeOrigin));
    851938
    852                     for (;;)
    853                     {
    854                         VBOXDISPLAY_DRIVER_TYPE enmDriverType = getVBoxDisplayDriverType(pCtx);
    855                         if (enmDriverType == VBOXDISPLAY_DRIVER_TYPE_UNKNOWN)
    856                         {
    857                             LogFlowFunc(("vboxDisplayDriver is not active\n"));
    858                             break;
    859                         }
    860 
    861                         if (pCtx->pfnChangeDisplaySettingsEx != 0)
    862                         {
    863                             LogFlowFunc(("Detected W2K or later\n"));
    864                             if (!ResizeDisplayDevice(pCtx,
    865                                                      iDisplay,
    866                                                      cx,
    867                                                      cy,
    868                                                      cBits,
    869                                                      fEnabled,
    870                                                      cxOrigin,
    871                                                      cyOrigin,
    872                                                      fChangeOrigin,
    873                                                      true /*fExtDispSup*/ ))
    874                             {
    875                                 LogFlowFunc(("ResizeDipspalyDevice return 0\n"));
    876                                 break;
    877                             }
    878 
    879                         }
    880                         else
    881                         {
    882                             LogFlowFunc(("Detected NT\n"));
    883                             ResizeDisplayDeviceNT4(cx, cy, cBits);
    884                             break;
    885                         }
    886 
    887                         /* Retry the change a bit later. */
    888                         RTThreadSleep(1000);
    889                     }
     939                    doResize(pCtx,
     940                             iDisplay,
     941                             cx,
     942                             cy,
     943                             cBits,
     944                             fEnabled,
     945                             cxOrigin,
     946                             cyOrigin,
     947                             fChangeOrigin);
    890948                }
    891949            } // if (fDisplayChangeQueried)
  • trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp

    r70873 r72352  
    23812381        case VMMDevReq_VideoSetVisibleRegion:
    23822382        case VMMDevReq_GetDisplayChangeRequestEx:
     2383        case VMMDevReq_GetDisplayChangeRequestMulti:
    23832384        case VMMDevReq_GetSeamlessChangeRequest:
    23842385        case VMMDevReq_GetVRDPChangeRequest:
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibGenericRequest.cpp

    r70873 r72352  
    8282     */
    8383    if (   pReq->requestType == VMMDevReq_ChangeMemBalloon
     84        || pReq->requestType == VMMDevReq_GetDisplayChangeRequestMulti
    8485#ifdef VBOX_WITH_64_BITS_GUESTS
    8586        || pReq->requestType == VMMDevReq_HGCMCall32
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibVideo.cpp

    r70061 r72352  
    273273        return getDisplayChangeRequest2(pcx, pcy, pcBits, piDisplay, fAck);
    274274    }
     275    return rc;
     276}
     277
     278
     279/**
     280 * Query the last display change request sent from the host to the guest.
     281 *
     282 * @returns iprt status value
     283 * @param   cDisplaysIn   How many elements in the paDisplays array.
     284 * @param   pcDisplaysOut How many elements were returned.
     285 * @param   paDisplays    Display information.
     286 * @param   fAck          Whether or not to acknowledge the newest request sent by
     287 *                        the host.  If this is set, the function will return the
     288 *                        most recent host request, otherwise it will return the
     289 *                        last request to be acknowledged.
     290 */
     291VBGLR3DECL(int) VbglR3GetDisplayChangeRequestMulti(uint32_t cDisplaysIn,
     292                                                   uint32_t *pcDisplaysOut,
     293                                                   VMMDevDisplayDef *paDisplays,
     294                                                   bool fAck)
     295{
     296    VMMDevDisplayChangeRequestMulti *pReq;
     297    size_t cbDisplays;
     298    size_t cbAlloc;
     299    int rc = VINF_SUCCESS;
     300
     301    AssertReturn(cDisplaysIn > 0 && cDisplaysIn <= 64 /* VBOX_VIDEO_MAX_SCREENS */, VERR_INVALID_PARAMETER);
     302    AssertPtrReturn(pcDisplaysOut, VERR_INVALID_PARAMETER);
     303    AssertPtrReturn(paDisplays, VERR_INVALID_PARAMETER);
     304
     305    cbDisplays = cDisplaysIn * sizeof(VMMDevDisplayDef);
     306    cbAlloc = RT_UOFFSETOF(VMMDevDisplayChangeRequestMulti, aDisplays) + cbDisplays;
     307    pReq = (VMMDevDisplayChangeRequestMulti *)RTMemAllocZ(cbAlloc);
     308    AssertPtrReturn(pReq, VERR_NO_MEMORY);
     309
     310    rc = vmmdevInitRequest(&pReq->header, VMMDevReq_GetDisplayChangeRequestMulti);
     311    AssertRCReturnStmt(rc, RTMemFree(pReq), rc);
     312
     313    pReq->header.size += (uint32_t)cbDisplays;
     314    pReq->cDisplays = cDisplaysIn;
     315    if (fAck)
     316        pReq->eventAck = VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
     317
     318    rc = vbglR3GRPerform(&pReq->header);
     319    AssertRCReturnStmt(rc, RTMemFree(pReq), rc);
     320
     321    rc = pReq->header.rc;
     322    if (RT_SUCCESS(rc))
     323    {
     324        memcpy(paDisplays, pReq->aDisplays, pReq->cDisplays * sizeof(VMMDevDisplayDef));
     325        *pcDisplaysOut = pReq->cDisplays;
     326    }
     327
     328    RTMemFree(pReq);
    275329    return rc;
    276330}
  • trunk/src/VBox/Devices/VMMDev/VMMDev.cpp

    r71891 r72352  
    8383/* Enable dev_vmm Log3 statements to get IRQ-related logging. */
    8484#define LOG_GROUP LOG_GROUP_DEV_VMM
    85 #include <VBoxVideo.h>  /* For VBVA definitions. */
     85#include <VBox/AssertGuest.h>
    8686#include <VBox/VMMDev.h>
    8787#include <VBox/vmm/mm.h>
     
    13111311    }
    13121312
    1313     if (pThis->displayChangeData.fGuestSentChangeEventAck)
    1314     {
    1315         pReq->xres = pDispRequest->lastReadDisplayChangeRequest.xres;
    1316         pReq->yres = pDispRequest->lastReadDisplayChangeRequest.yres;
    1317         pReq->bpp  = pDispRequest->lastReadDisplayChangeRequest.bpp;
    1318     }
    1319     else
    1320     {
    1321         /* This is not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just
    1322          * read the last valid video mode hint. This happens when the guest X server
    1323          * determines the initial mode. */
    1324         pReq->xres = pDispRequest->displayChangeRequest.xres;
    1325         pReq->yres = pDispRequest->displayChangeRequest.yres;
    1326         pReq->bpp  = pDispRequest->displayChangeRequest.bpp;
    1327     }
     1313    /* If not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just
     1314     * read the last valid video mode hint. This happens when the guest X server
     1315     * determines the initial mode. */
     1316    VMMDevDisplayDef const *pDisplayDef = pThis->displayChangeData.fGuestSentChangeEventAck ?
     1317                                              &pDispRequest->lastReadDisplayChangeRequest :
     1318                                              &pDispRequest->displayChangeRequest;
     1319    pReq->xres = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CX)  ? pDisplayDef->cx : 0;
     1320    pReq->yres = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CY)  ? pDisplayDef->cy : 0;
     1321    pReq->bpp  = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_BPP) ? pDisplayDef->cBitsPerPixel : 0;
     1322
    13281323    Log(("VMMDev: returning display change request xres = %d, yres = %d, bpp = %d\n", pReq->xres, pReq->yres, pReq->bpp));
    13291324
     
    13961391    }
    13971392
    1398     if (pThis->displayChangeData.fGuestSentChangeEventAck)
    1399     {
    1400         pReq->xres    = pDispRequest->lastReadDisplayChangeRequest.xres;
    1401         pReq->yres    = pDispRequest->lastReadDisplayChangeRequest.yres;
    1402         pReq->bpp     = pDispRequest->lastReadDisplayChangeRequest.bpp;
    1403         pReq->display = pDispRequest->lastReadDisplayChangeRequest.display;
    1404     }
    1405     else
    1406     {
    1407         /* This is not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just
    1408          * read the last valid video mode hint. This happens when the guest X server
    1409          * determines the initial video mode. */
    1410         pReq->xres    = pDispRequest->displayChangeRequest.xres;
    1411         pReq->yres    = pDispRequest->displayChangeRequest.yres;
    1412         pReq->bpp     = pDispRequest->displayChangeRequest.bpp;
    1413         pReq->display = pDispRequest->displayChangeRequest.display;
    1414     }
     1393    /* If not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just
     1394     * read the last valid video mode hint. This happens when the guest X server
     1395     * determines the initial mode. */
     1396    VMMDevDisplayDef const *pDisplayDef = pThis->displayChangeData.fGuestSentChangeEventAck ?
     1397                                              &pDispRequest->lastReadDisplayChangeRequest :
     1398                                              &pDispRequest->displayChangeRequest;
     1399    pReq->xres    = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CX)  ? pDisplayDef->cx : 0;
     1400    pReq->yres    = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CY)  ? pDisplayDef->cy : 0;
     1401    pReq->bpp     = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_BPP) ? pDisplayDef->cBitsPerPixel : 0;
     1402    pReq->display = pDisplayDef->idDisplay;
     1403
    14151404    Log(("VMMDev: returning display change request xres = %d, yres = %d, bpp = %d at %d\n",
    14161405         pReq->xres, pReq->yres, pReq->bpp, pReq->display));
     
    14871476    }
    14881477
    1489     if (pThis->displayChangeData.fGuestSentChangeEventAck)
    1490     {
    1491         pReq->xres          = pDispRequest->lastReadDisplayChangeRequest.xres;
    1492         pReq->yres          = pDispRequest->lastReadDisplayChangeRequest.yres;
    1493         pReq->bpp           = pDispRequest->lastReadDisplayChangeRequest.bpp;
    1494         pReq->display       = pDispRequest->lastReadDisplayChangeRequest.display;
    1495         pReq->cxOrigin      = pDispRequest->lastReadDisplayChangeRequest.xOrigin;
    1496         pReq->cyOrigin      = pDispRequest->lastReadDisplayChangeRequest.yOrigin;
    1497         pReq->fEnabled      = pDispRequest->lastReadDisplayChangeRequest.fEnabled;
    1498         pReq->fChangeOrigin = pDispRequest->lastReadDisplayChangeRequest.fChangeOrigin;
    1499     }
    1500     else
    1501     {
    1502         /* This is not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just
    1503          * read the last valid video mode hint. This happens when the guest X server
    1504          * determines the initial video mode. */
    1505         pReq->xres          = pDispRequest->displayChangeRequest.xres;
    1506         pReq->yres          = pDispRequest->displayChangeRequest.yres;
    1507         pReq->bpp           = pDispRequest->displayChangeRequest.bpp;
    1508         pReq->display       = pDispRequest->displayChangeRequest.display;
    1509         pReq->cxOrigin      = pDispRequest->displayChangeRequest.xOrigin;
    1510         pReq->cyOrigin      = pDispRequest->displayChangeRequest.yOrigin;
    1511         pReq->fEnabled      = pDispRequest->displayChangeRequest.fEnabled;
    1512         pReq->fChangeOrigin = pDispRequest->displayChangeRequest.fChangeOrigin;
    1513 
    1514     }
     1478    /* If not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just
     1479     * read the last valid video mode hint. This happens when the guest X server
     1480     * determines the initial mode. */
     1481    VMMDevDisplayDef const *pDisplayDef = pThis->displayChangeData.fGuestSentChangeEventAck ?
     1482                                              &pDispRequest->lastReadDisplayChangeRequest :
     1483                                              &pDispRequest->displayChangeRequest;
     1484    pReq->xres          = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CX)  ? pDisplayDef->cx : 0;
     1485    pReq->yres          = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_CY)  ? pDisplayDef->cy : 0;
     1486    pReq->bpp           = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_BPP) ? pDisplayDef->cBitsPerPixel : 0;
     1487    pReq->display       = pDisplayDef->idDisplay;
     1488    pReq->cxOrigin      = pDisplayDef->xOrigin;
     1489    pReq->cyOrigin      = pDisplayDef->yOrigin;
     1490    pReq->fEnabled      = !RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_DISABLED);
     1491    pReq->fChangeOrigin = RT_BOOL(pDisplayDef->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN);
     1492
    15151493    Log(("VMMDevEx: returning display change request xres = %d, yres = %d, bpp = %d id %d xPos = %d, yPos = %d & Enabled=%d\n",
    15161494         pReq->xres, pReq->yres, pReq->bpp, pReq->display, pReq->cxOrigin, pReq->cyOrigin, pReq->fEnabled));
     1495
     1496    return VINF_SUCCESS;
     1497}
     1498
     1499
     1500/**
     1501 * Handles VMMDevReq_GetDisplayChangeRequestMulti.
     1502 *
     1503 * @returns VBox status code that the guest should see.
     1504 * @param   pThis           The VMMDev instance data.
     1505 * @param   pReqHdr         The header of the request to handle.
     1506 */
     1507static int vmmdevReqHandler_GetDisplayChangeRequestMulti(PVMMDEV pThis, VMMDevRequestHeader *pReqHdr)
     1508{
     1509    VMMDevDisplayChangeRequestMulti *pReq = (VMMDevDisplayChangeRequestMulti *)pReqHdr;
     1510    unsigned i;
     1511
     1512    ASSERT_GUEST_MSG_RETURN(pReq->header.size >= sizeof(*pReq),
     1513                            ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
     1514    RT_UNTRUSTED_VALIDATED_FENCE();
     1515
     1516    uint32_t const cDisplays = pReq->cDisplays;
     1517    ASSERT_GUEST_MSG_RETURN(cDisplays > 0 && cDisplays <= RT_ELEMENTS(pThis->displayChangeData.aRequests),
     1518                            ("cDisplays %u\n", cDisplays), VERR_INVALID_PARAMETER);
     1519    RT_UNTRUSTED_VALIDATED_FENCE();
     1520
     1521    ASSERT_GUEST_MSG_RETURN(pReq->header.size >= sizeof(*pReq) + (cDisplays - 1) * sizeof(VMMDevDisplayDef),
     1522                            ("%u\n", pReq->header.size), VERR_INVALID_PARAMETER);
     1523    RT_UNTRUSTED_VALIDATED_FENCE();
     1524
     1525    if (pReq->eventAck == VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST)
     1526    {
     1527        /* Remember which resolution the client has queried, subsequent reads
     1528         * will return the same values. */
     1529        for (i = 0; i < RT_ELEMENTS(pThis->displayChangeData.aRequests); ++i)
     1530        {
     1531            DISPLAYCHANGEREQUEST *pDCR = &pThis->displayChangeData.aRequests[i];
     1532
     1533            pDCR->lastReadDisplayChangeRequest = pDCR->displayChangeRequest;
     1534            pDCR->fPending = false;
     1535        }
     1536    }
     1537
     1538    /* Fill the guest request with monitor layout data. */
     1539    for (i = 0; i < cDisplays; ++i)
     1540    {
     1541        /* If not a response to a VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, just
     1542         * read the last valid video mode hint. This happens when the guest X server
     1543         * determines the initial mode. */
     1544        DISPLAYCHANGEREQUEST const *pDCR = &pThis->displayChangeData.aRequests[i];
     1545        VMMDevDisplayDef const *pDisplayDef = pThis->displayChangeData.fGuestSentChangeEventAck ?
     1546                                                  &pDCR->lastReadDisplayChangeRequest :
     1547                                                  &pDCR->displayChangeRequest;
     1548        pReq->aDisplays[i] = *pDisplayDef;
     1549    }
     1550
     1551    Log(("VMMDev: returning multimonitor display change request cDisplays %d\n", cDisplays));
    15171552
    15181553    return VINF_SUCCESS;
     
    25702605        case VMMDevReq_GetDisplayChangeRequestEx:
    25712606            pReqHdr->rc = vmmdevReqHandler_GetDisplayChangeRequestEx(pThis, pReqHdr);
     2607            break;
     2608
     2609        case VMMDevReq_GetDisplayChangeRequestMulti:
     2610            pReqHdr->rc = vmmdevReqHandler_GetDisplayChangeRequestMulti(pThis, pReqHdr);
    25722611            break;
    25732612
     
    31823221}
    31833222
     3223static bool vmmdevIsMonitorDefEqual(VMMDevDisplayDef const *pNew, VMMDevDisplayDef const *pOld)
     3224{
     3225    bool     fEqual = pNew->idDisplay == pOld->idDisplay;
     3226
     3227    fEqual = fEqual && (   !RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN)    /* No change. */
     3228                        || (   RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN) /* Old value exists and */
     3229                            && pNew->xOrigin == pOld->xOrigin                       /* the old is equal to the new. */
     3230                            && pNew->yOrigin == pOld->yOrigin));
     3231
     3232    fEqual = fEqual && (   !RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_CX)
     3233                        || (   RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_CX)
     3234                            && pNew->cx == pOld->cx));
     3235
     3236    fEqual = fEqual && (   !RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_CY)
     3237                        || (   RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_CY)
     3238                            && pNew->cy == pOld->cy));
     3239
     3240    fEqual = fEqual && (   !RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_BPP)
     3241                        || (   RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_BPP)
     3242                            && pNew->cBitsPerPixel == pOld->cBitsPerPixel));
     3243
     3244    fEqual = fEqual && (   RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_DISABLED)
     3245                        == RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_DISABLED));
     3246
     3247    fEqual = fEqual && (   RT_BOOL(pNew->fDisplayFlags & VMMDEV_DISPLAY_PRIMARY)
     3248                        == RT_BOOL(pOld->fDisplayFlags & VMMDEV_DISPLAY_PRIMARY));
     3249
     3250    return fEqual;
     3251}
     3252
    31843253/**
    31853254 * @interface_method_impl{PDMIVMMDEVPORT,pfnRequestDisplayChange}
    31863255 */
    31873256static DECLCALLBACK(int)
    3188 vmmdevIPort_RequestDisplayChange(PPDMIVMMDEVPORT pInterface, uint32_t cx, uint32_t cy, uint32_t cBits, uint32_t idxDisplay,
    3189                                  int32_t xOrigin, int32_t yOrigin, bool fEnabled, bool fChangeOrigin)
    3190 {
     3257vmmdevIPort_RequestDisplayChange(PPDMIVMMDEVPORT pInterface, uint32_t cDisplays, VMMDevDisplayDef const *paDisplays, bool fForce)
     3258{
     3259    int rc = VINF_SUCCESS;
     3260
    31913261    PVMMDEV pThis = RT_FROM_MEMBER(pInterface, VMMDEV, IPort);
    3192 
    3193     if (idxDisplay >= RT_ELEMENTS(pThis->displayChangeData.aRequests))
    3194         return VERR_INVALID_PARAMETER;
     3262    bool fNotifyGuest = false;
    31953263
    31963264    PDMCritSectEnter(&pThis->CritSect, VERR_IGNORED);
    31973265
    3198     DISPLAYCHANGEREQUEST *pRequest = &pThis->displayChangeData.aRequests[idxDisplay];
    3199 
    3200     /* Verify that the new resolution is different and that guest does not yet know about it. */
    3201     bool fSameResolution = (!cx    || pRequest->lastReadDisplayChangeRequest.xres == cx)
    3202                         && (!cy    || pRequest->lastReadDisplayChangeRequest.yres == cy)
    3203                         && (!cBits || pRequest->lastReadDisplayChangeRequest.bpp  == cBits)
    3204                         && pRequest->lastReadDisplayChangeRequest.xOrigin  == xOrigin
    3205                         && pRequest->lastReadDisplayChangeRequest.yOrigin  == yOrigin
    3206                         && pRequest->lastReadDisplayChangeRequest.fEnabled == fEnabled
    3207                         && pRequest->lastReadDisplayChangeRequest.display  == idxDisplay;
    3208 
    3209     if (!cx && !cy && !cBits)
    3210     {
    3211         /* Special case of reset video mode. */
    3212         fSameResolution = false;
    3213     }
    3214 
    3215     Log3(("vmmdevIPort_RequestDisplayChange: same=%d. new: cx=%d, cy=%d, cBits=%d, idxDisplay=%d.\
    3216           old: cx=%d, cy=%d, cBits=%d, idxDisplay=%d. \n \
    3217           ,OriginX = %d , OriginY=%d, Enabled=%d, ChangeOrigin=%d\n",
    3218           fSameResolution, cx, cy, cBits, idxDisplay, pRequest->lastReadDisplayChangeRequest.xres,
    3219           pRequest->lastReadDisplayChangeRequest.yres, pRequest->lastReadDisplayChangeRequest.bpp,
    3220           pRequest->lastReadDisplayChangeRequest.display,
    3221           xOrigin, yOrigin, fEnabled, fChangeOrigin));
    3222 
    3223     /* we could validate the information here but hey, the guest can do that as well! */
    3224     pRequest->displayChangeRequest.xres          = cx;
    3225     pRequest->displayChangeRequest.yres          = cy;
    3226     pRequest->displayChangeRequest.bpp           = cBits;
    3227     pRequest->displayChangeRequest.display       = idxDisplay;
    3228     pRequest->displayChangeRequest.xOrigin       = xOrigin;
    3229     pRequest->displayChangeRequest.yOrigin       = yOrigin;
    3230     pRequest->displayChangeRequest.fEnabled      = fEnabled;
    3231     pRequest->displayChangeRequest.fChangeOrigin = fChangeOrigin;
    3232 
    3233     pRequest->fPending = !fSameResolution;
    3234 
    3235     if (!fSameResolution)
    3236     {
    3237         LogRel(("VMMDev: SetVideoModeHint: Got a video mode hint (%dx%dx%d)@(%dx%d),(%d;%d) at %d\n",
    3238                 cx, cy, cBits, xOrigin, yOrigin, fEnabled, fChangeOrigin, idxDisplay));
    3239 
    3240         /* IRQ so the guest knows what's going on */
    3241         VMMDevNotifyGuest(pThis, VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST);
     3266    uint32_t i;
     3267    for (i = 0; i < cDisplays; ++i)
     3268    {
     3269        VMMDevDisplayDef const *p = &paDisplays[i];
     3270
     3271        /* Either one display definition is provided or the display id must be equal to the array index. */
     3272        AssertBreakStmt(cDisplays == 1 || p->idDisplay == i, rc = VERR_INVALID_PARAMETER);
     3273        AssertBreakStmt(p->idDisplay < RT_ELEMENTS(pThis->displayChangeData.aRequests), rc = VERR_INVALID_PARAMETER);
     3274
     3275        DISPLAYCHANGEREQUEST *pRequest = &pThis->displayChangeData.aRequests[p->idDisplay];
     3276
     3277        VMMDevDisplayDef const *pLastRead = &pRequest->lastReadDisplayChangeRequest;
     3278
     3279        /* Verify that the new resolution is different and that guest does not yet know about it. */
     3280        bool const fDifferentResolution = fForce || !vmmdevIsMonitorDefEqual(p, pLastRead);
     3281
     3282        LogFunc(("same=%d. New: %dx%d, cBits=%d, id=%d. Old: %dx%d, cBits=%d, id=%d. @%d,%d, Enabled=%d, ChangeOrigin=%d\n",
     3283                 !fDifferentResolution, p->cx, p->cy, p->cBitsPerPixel, p->idDisplay,
     3284                 pLastRead->cx, pLastRead->cy, pLastRead->cBitsPerPixel, pLastRead->idDisplay,
     3285                 p->xOrigin, p->yOrigin,
     3286                 !RT_BOOL(p->fDisplayFlags & VMMDEV_DISPLAY_DISABLED),
     3287                 RT_BOOL(p->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN)));
     3288
     3289        /* We could validate the information here but hey, the guest can do that as well! */
     3290        pRequest->displayChangeRequest = *p;
     3291        pRequest->fPending = fDifferentResolution;
     3292
     3293        fNotifyGuest = fNotifyGuest || fDifferentResolution;
     3294    }
     3295
     3296    if (RT_SUCCESS(rc))
     3297    {
     3298        if (fNotifyGuest)
     3299        {
     3300            for (i = 0; i < RT_ELEMENTS(pThis->displayChangeData.aRequests); ++i)
     3301            {
     3302                DISPLAYCHANGEREQUEST *pRequest = &pThis->displayChangeData.aRequests[i];
     3303                if (pRequest->fPending)
     3304                {
     3305                    VMMDevDisplayDef const *p = &pRequest->displayChangeRequest;
     3306                    LogRel(("VMMDev: SetVideoModeHint: Got a video mode hint (%dx%dx%d)@(%dx%d),(%d;%d) at %d\n",
     3307                            p->cx, p->cy, p->cBitsPerPixel, p->xOrigin, p->yOrigin,
     3308                            !RT_BOOL(p->fDisplayFlags & VMMDEV_DISPLAY_DISABLED),
     3309                            RT_BOOL(p->fDisplayFlags & VMMDEV_DISPLAY_ORIGIN), i));
     3310                }
     3311            }
     3312
     3313            /* IRQ so the guest knows what's going on */
     3314            VMMDevNotifyGuest(pThis, VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST);
     3315        }
    32423316    }
    32433317
    32443318    PDMCritSectLeave(&pThis->CritSect);
    3245     return VINF_SUCCESS;
     3319    return rc;
    32463320}
    32473321
  • trunk/src/VBox/Devices/VMMDev/VMMDevState.h

    r71891 r72352  
    1919#define ___VMMDev_VMMDevState_h
    2020
     21#include <VBoxVideo.h>  /* For VBVA definitions. */
    2122#include <VBox/VMMDev.h>
    2223#include <VBox/vmm/pdmdev.h>
     
    3132#define VMMDEV_WITH_ALT_TIMESYNC
    3233
    33 typedef struct DISPLAYCHANGEINFO
    34 {
    35     uint32_t xres;
    36     uint32_t yres;
    37     uint32_t bpp;
    38     uint32_t display;
    39     int32_t xOrigin;
    40     int32_t yOrigin;
    41     bool fEnabled;
    42     bool fChangeOrigin;
    43 } DISPLAYCHANGEINFO;
    44 
    4534typedef struct DISPLAYCHANGEREQUEST
    4635{
    4736    bool fPending;
    4837    bool afAlignment[3];
    49     DISPLAYCHANGEINFO displayChangeRequest;
    50     DISPLAYCHANGEINFO lastReadDisplayChangeRequest;
     38    VMMDevDisplayDef displayChangeRequest;
     39    VMMDevDisplayDef lastReadDisplayChangeRequest;
    5140} DISPLAYCHANGEREQUEST;
    5241
     
    6049    bool afAlignment[3];
    6150
    62     DISPLAYCHANGEREQUEST aRequests[64]; /// @todo maxMonitors
     51    DISPLAYCHANGEREQUEST aRequests[VBOX_VIDEO_MAX_SCREENS];
    6352} DISPLAYCHANGEDATA;
    6453
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageControlVM.cpp

    r70766 r72352  
    14411441                                                         uXRes, uYRes, uBpp));
    14421442        }
     1443        else if (!strcmp(a->argv[1], "setscreenlayout"))
     1444        {
     1445            if (a->argc < 4)
     1446            {
     1447                errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     1448                rc = E_FAIL;
     1449                break;
     1450            }
     1451
     1452            ComPtr<IDisplay> pDisplay;
     1453            CHECK_ERROR_BREAK(console, COMGETTER(Display)(pDisplay.asOutParam()));
     1454            if (!pDisplay)
     1455            {
     1456                RTMsgError("Guest not running");
     1457                rc = E_FAIL;
     1458                break;
     1459            }
     1460
     1461            com::SafeIfaceArray<IGuestScreenInfo> aGuestScreenInfos;
     1462
     1463            /* Parse "<display> on|primary <xorigin> <yorigin> <xres> <yres> <bpp> | off" sequences. */
     1464            int argc = a->argc - 2;
     1465            char **argv = &a->argv[2];
     1466            while (argc >= 2)
     1467            {
     1468                ULONG aDisplay = RTStrToUInt32(argv[0]);
     1469                BOOL aPrimary = FALSE;
     1470
     1471                GuestMonitorStatus_T aStatus;
     1472                if (RTStrICmp(argv[1], "primary") == 0)
     1473                {
     1474                    aStatus = GuestMonitorStatus_Enabled;
     1475                    aPrimary = TRUE;
     1476                }
     1477                else if (RTStrICmp(argv[1], "on") == 0)
     1478                    aStatus = GuestMonitorStatus_Enabled;
     1479                else if (RTStrICmp(argv[1], "off") == 0)
     1480                    aStatus = GuestMonitorStatus_Disabled;
     1481                else
     1482                {
     1483                    errorSyntax(USAGE_CONTROLVM, "Display status must be <on> or <off>");
     1484                    rc = E_FAIL;
     1485                    break;
     1486                }
     1487
     1488                BOOL aChangeOrigin = FALSE;
     1489                LONG aOriginX = 0;
     1490                LONG aOriginY = 0;
     1491                ULONG aWidth = 0;
     1492                ULONG aHeight = 0;
     1493                ULONG aBitsPerPixel = 0;
     1494                if (aStatus = GuestMonitorStatus_Enabled)
     1495                {
     1496                    if (argc < 7)
     1497                    {
     1498                        errorSyntax(USAGE_CONTROLVM, "Incorrect number of parameters");
     1499                        rc = E_FAIL;
     1500                        break;
     1501                    }
     1502
     1503                    aChangeOrigin = TRUE;
     1504                    aOriginX      = RTStrToUInt32(argv[2]);
     1505                    aOriginY      = RTStrToUInt32(argv[3]);
     1506                    aWidth        = RTStrToUInt32(argv[4]);
     1507                    aHeight       = RTStrToUInt32(argv[5]);
     1508                    aBitsPerPixel = RTStrToUInt32(argv[6]);
     1509
     1510                    argc -= 7;
     1511                    argv += 7;
     1512                }
     1513                else
     1514                {
     1515                    argc -= 2;
     1516                    argv += 2;
     1517                }
     1518
     1519                ComPtr<IGuestScreenInfo> pInfo;
     1520                CHECK_ERROR_BREAK(pDisplay, CreateGuestScreenInfo(aDisplay, aStatus, aPrimary, aChangeOrigin,
     1521                                                                  aOriginX, aOriginY, aWidth, aHeight, aBitsPerPixel,
     1522                                                                  pInfo.asOutParam()));
     1523                aGuestScreenInfos.push_back(pInfo);
     1524            }
     1525
     1526            if (FAILED(rc))
     1527                break;
     1528
     1529            CHECK_ERROR_BREAK(pDisplay, SetScreenLayout(ScreenLayoutMode_Apply, ComSafeArrayAsInParam(aGuestScreenInfos)));
     1530        }
    14431531        else if (!strcmp(a->argv[1], "setcredentials"))
    14441532        {
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp

    r71868 r72352  
    825825                     "                                            [[<display>] [<enabled:yes|no> |\n"
    826826                     "                                              [<xorigin> <yorigin>]]] |\n"
     827                     "                            setscreenlayout <display> on|primary <xorigin> <yorigin> <xres> <yres> <bpp> | off\n"
    827828                     "                            screenshotpng <file> [display] |\n"
    828829                     "                            videocap on|off |\n"
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r72332 r72352  
    1749517495    wsmap="managed"
    1749617496    wrap-hint-server-addinterfaces="IEventListener"
    17497     reservedMethods="4" reservedAttributes="2"
     17497    reservedMethods="3" reservedAttributes="2"
    1749817498    >
    1749917499    <desc>
     
    1784417844      </desc>
    1784517845      <param name="screenIds" type="long" safearray="yes" dir="in"/>
     17846    </method>
     17847
     17848    <method name="createGuestScreenInfo">
     17849      <desc>
     17850        Make a IGuestScreenInfo object with the provided parameters.
     17851      </desc>
     17852      <param name="display" type="unsigned long" dir="in">
     17853        <desc>
     17854          The number of the guest display.
     17855        </desc>
     17856      </param>
     17857      <param name="status" type="GuestMonitorStatus" dir="in">
     17858        <desc>
     17859          @c True, if this guest screen is enabled,
     17860          @c False otherwise.
     17861        </desc>
     17862      </param>
     17863      <param name="primary" type="boolean" dir="in">
     17864        <desc>
     17865          Whether this guest monitor must be primary.
     17866        </desc>
     17867      </param>
     17868      <param name="changeOrigin" type="boolean" dir="in">
     17869        <desc>
     17870          @c True, if the origin of the guest screen should be changed,
     17871          @c False otherwise.
     17872        </desc>
     17873      </param>
     17874      <param name="originX" type="long" dir="in">
     17875        <desc>
     17876          The X origin of the guest screen.
     17877        </desc>
     17878      </param>
     17879      <param name="originY" type="long" dir="in">
     17880        <desc>
     17881          The Y origin of the guest screen.
     17882        </desc>
     17883      </param>
     17884      <param name="width" type="unsigned long" dir="in">
     17885        <desc>
     17886          The width of the guest screen.
     17887        </desc>
     17888      </param>
     17889      <param name="height" type="unsigned long" dir="in">
     17890        <desc>
     17891          The height of the guest screen.
     17892        </desc>
     17893      </param>
     17894      <param name="bitsPerPixel" type="unsigned long" dir="in">
     17895        <desc>
     17896          The number of bits per pixel of the guest screen.
     17897        </desc>
     17898      </param>
     17899      <param name="guestScreenInfo" type="IGuestScreenInfo" dir="out">
     17900        <desc>
     17901          The created object.
     17902        </desc>
     17903      </param>
    1784617904    </method>
    1784717905
  • trunk/src/VBox/Main/include/DisplayImpl.h

    r72014 r72352  
    3838
    3939#include "DisplaySourceBitmapWrap.h"
     40#include "GuestScreenInfoWrap.h"
    4041
    4142
     
    298299                                    const std::vector<ComPtr<IGuestScreenInfo> > &aGuestScreenInfo);
    299300    virtual HRESULT detachScreens(const std::vector<LONG> &aScreenIds);
     301    virtual HRESULT createGuestScreenInfo(ULONG aDisplay,
     302                                          GuestMonitorStatus_T aStatus,
     303                                          BOOL aPrimary,
     304                                          BOOL aChangeOrigin,
     305                                          LONG aOriginX,
     306                                          LONG aOriginY,
     307                                          ULONG aWidth,
     308                                          ULONG aHeight,
     309                                          ULONG aBitsPerPixel,
     310                                          ComPtr<IGuestScreenInfo> &aGuestScreenInfo);
    300311
    301312    // Wrapped IEventListener properties
     
    596607};
    597608
     609class ATL_NO_VTABLE GuestScreenInfo:
     610    public GuestScreenInfoWrap
     611{
     612public:
     613
     614    DECLARE_EMPTY_CTOR_DTOR(GuestScreenInfo)
     615
     616    HRESULT FinalConstruct();
     617    void FinalRelease();
     618
     619    /* Public initializer/uninitializer for internal purposes only. */
     620    HRESULT init(ULONG aDisplay,
     621                 GuestMonitorStatus_T aGuestMonitorStatus,
     622                 BOOL aPrimary,
     623                 BOOL aChangeOrigin,
     624                 LONG aOriginX,
     625                 LONG aOriginY,
     626                 ULONG aWidth,
     627                 ULONG aHeight,
     628                 ULONG aBitsPerPixel);
     629    void uninit();
     630
     631private:
     632    // wrapped IGuestScreenInfo properties
     633    virtual HRESULT getScreenId(ULONG *aScreenId);
     634    virtual HRESULT getGuestMonitorStatus(GuestMonitorStatus_T *aGuestMonitorStatus);
     635    virtual HRESULT getPrimary(BOOL *aPrimary);
     636    virtual HRESULT getOrigin(BOOL *aOrigin);
     637    virtual HRESULT getOriginX(LONG *aOriginX);
     638    virtual HRESULT getOriginY(LONG *aOriginY);
     639    virtual HRESULT getWidth(ULONG *aWidth);
     640    virtual HRESULT getHeight(ULONG *aHeight);
     641    virtual HRESULT getBitsPerPixel(ULONG *aBitsPerPixel);
     642    virtual HRESULT getExtendedInfo(com::Utf8Str &aExtendedInfo);
     643
     644    ULONG mScreenId;
     645    GuestMonitorStatus_T mGuestMonitorStatus;
     646    BOOL  mPrimary;
     647    BOOL  mOrigin;
     648    LONG  mOriginX;
     649    LONG  mOriginY;
     650    ULONG mWidth;
     651    ULONG mHeight;
     652    ULONG mBitsPerPixel;
     653};
     654
    598655#endif // !____H_DISPLAYIMPL
    599656/* vi: set tabstop=4 shiftwidth=4 expandtab: */
  • trunk/src/VBox/Main/src-client/DisplayImpl.cpp

    r72014 r72352  
    19541954        PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
    19551955        if (pVMMDevPort)
    1956             pVMMDevPort->pfnRequestDisplayChange(pVMMDevPort, aWidth, aHeight, aBitsPerPixel,
    1957                                                  aDisplay, aOriginX, aOriginY,
    1958                                                  RT_BOOL(aEnabled), RT_BOOL(aChangeOrigin));
     1956        {
     1957            VMMDevDisplayDef d;
     1958            d.idDisplay     = aDisplay;
     1959            d.xOrigin       = aOriginX;
     1960            d.yOrigin       = aOriginY;
     1961            d.cx            = aWidth;
     1962            d.cy            = aHeight;
     1963            d.cBitsPerPixel = aBitsPerPixel;
     1964            d.fDisplayFlags = VMMDEV_DISPLAY_CX | VMMDEV_DISPLAY_CY | VMMDEV_DISPLAY_BPP;
     1965            if (!aEnabled)
     1966                d.fDisplayFlags |= VMMDEV_DISPLAY_DISABLED;
     1967            if (aChangeOrigin)
     1968                d.fDisplayFlags |= VMMDEV_DISPLAY_ORIGIN;
     1969            if (aDisplay == 0)
     1970                d.fDisplayFlags |= VMMDEV_DISPLAY_PRIMARY;
     1971
     1972            pVMMDevPort->pfnRequestDisplayChange(pVMMDevPort, 1, &d, false);
     1973        }
    19591974    }
    19601975    return S_OK;
     
    31223137
    31233138HRESULT Display::setScreenLayout(ScreenLayoutMode_T aScreenLayoutMode,
    3124                                     const std::vector<ComPtr<IGuestScreenInfo> > &aGuestScreenInfo)
    3125 {
    3126     NOREF(aScreenLayoutMode);
    3127     NOREF(aGuestScreenInfo);
    3128     return E_NOTIMPL;
     3139                                 const std::vector<ComPtr<IGuestScreenInfo> > &aGuestScreenInfo)
     3140{
     3141    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3142
     3143    if (aGuestScreenInfo.size() != mcMonitors)
     3144        return E_INVALIDARG;
     3145
     3146    CHECK_CONSOLE_DRV(mpDrv);
     3147
     3148    /*
     3149     * It is up to the guest to decide whether the hint is
     3150     * valid. Therefore don't do any VRAM sanity checks here.
     3151     */
     3152
     3153    /* Have to release the lock because the pfnRequestDisplayChange
     3154     * will call EMT.  */
     3155    alock.release();
     3156
     3157    VMMDev *pVMMDev = mParent->i_getVMMDev();
     3158    if (pVMMDev)
     3159    {
     3160        PPDMIVMMDEVPORT pVMMDevPort = pVMMDev->getVMMDevPort();
     3161        if (pVMMDevPort)
     3162        {
     3163            uint32_t const cDisplays = (uint32_t)aGuestScreenInfo.size();
     3164
     3165            size_t const cbAlloc = cDisplays * sizeof(VMMDevDisplayDef);
     3166            VMMDevDisplayDef *paDisplayDefs = (VMMDevDisplayDef *)RTMemAlloc(cbAlloc);
     3167            if (paDisplayDefs)
     3168            {
     3169                for (uint32_t i = 0; i < cDisplays; ++i)
     3170                {
     3171                    VMMDevDisplayDef *p = &paDisplayDefs[i];
     3172                    ComPtr<IGuestScreenInfo> pScreenInfo = aGuestScreenInfo[i];
     3173
     3174                    ULONG screenId     = 0;
     3175                    GuestMonitorStatus_T guestMonitorStatus = GuestMonitorStatus_Enabled;
     3176                    BOOL  origin       = FALSE;
     3177                    BOOL  primary      = FALSE;
     3178                    LONG  originX      = 0;
     3179                    LONG  originY      = 0;
     3180                    ULONG width        = 0;
     3181                    ULONG height       = 0;
     3182                    ULONG bitsPerPixel = 0;
     3183
     3184                    pScreenInfo->COMGETTER(ScreenId)    (&screenId);
     3185                    pScreenInfo->COMGETTER(GuestMonitorStatus)(&guestMonitorStatus);
     3186                    pScreenInfo->COMGETTER(Primary)     (&primary);
     3187                    pScreenInfo->COMGETTER(Origin)      (&origin);
     3188                    pScreenInfo->COMGETTER(OriginX)     (&originX);
     3189                    pScreenInfo->COMGETTER(OriginY)     (&originY);
     3190                    pScreenInfo->COMGETTER(Width)       (&width);
     3191                    pScreenInfo->COMGETTER(Height)      (&height);
     3192                    pScreenInfo->COMGETTER(BitsPerPixel)(&bitsPerPixel);
     3193
     3194                    LogFlowFunc(("%d %d,%d %dx%d\n", screenId, originX, originY, width, height));
     3195
     3196                    p->idDisplay     = screenId;
     3197                    p->xOrigin       = originX;
     3198                    p->yOrigin       = originY;
     3199                    p->cx            = width;
     3200                    p->cy            = height;
     3201                    p->cBitsPerPixel = bitsPerPixel;
     3202                    p->fDisplayFlags = VMMDEV_DISPLAY_CX | VMMDEV_DISPLAY_CY | VMMDEV_DISPLAY_BPP;
     3203                    if (guestMonitorStatus == GuestMonitorStatus_Disabled)
     3204                        p->fDisplayFlags |= VMMDEV_DISPLAY_DISABLED;
     3205                    if (origin)
     3206                        p->fDisplayFlags |= VMMDEV_DISPLAY_ORIGIN;
     3207                    if (primary)
     3208                        p->fDisplayFlags |= VMMDEV_DISPLAY_PRIMARY;
     3209                }
     3210
     3211                bool const fForce =    aScreenLayoutMode == ScreenLayoutMode_Reset
     3212                                    || aScreenLayoutMode == ScreenLayoutMode_Apply;
     3213                pVMMDevPort->pfnRequestDisplayChange(pVMMDevPort, cDisplays, paDisplayDefs, fForce);
     3214
     3215                RTMemFree(paDisplayDefs);
     3216            }
     3217        }
     3218    }
     3219    return S_OK;
    31293220}
    31303221
     
    31333224    NOREF(aScreenIds);
    31343225    return E_NOTIMPL;
     3226}
     3227
     3228HRESULT Display::createGuestScreenInfo(ULONG aDisplay,
     3229                                       GuestMonitorStatus_T aStatus,
     3230                                       BOOL aPrimary,
     3231                                       BOOL aChangeOrigin,
     3232                                       LONG aOriginX,
     3233                                       LONG aOriginY,
     3234                                       ULONG aWidth,
     3235                                       ULONG aHeight,
     3236                                       ULONG aBitsPerPixel,
     3237                                       ComPtr<IGuestScreenInfo> &aGuestScreenInfo)
     3238{
     3239    /* Create a new object. */
     3240    ComObjPtr<GuestScreenInfo> obj;
     3241    HRESULT hr = obj.createObject();
     3242    if (SUCCEEDED(hr))
     3243        hr = obj->init(aDisplay, aStatus, aPrimary, aChangeOrigin, aOriginX, aOriginY,
     3244                       aWidth, aHeight, aBitsPerPixel);
     3245    if (SUCCEEDED(hr))
     3246        obj.queryInterfaceTo(aGuestScreenInfo.asOutParam());
     3247
     3248    return hr;
     3249}
     3250
     3251
     3252/*
     3253 * GuestScreenInfo implementation.
     3254 */
     3255DEFINE_EMPTY_CTOR_DTOR(GuestScreenInfo)
     3256
     3257HRESULT GuestScreenInfo::FinalConstruct()
     3258{
     3259    return BaseFinalConstruct();
     3260}
     3261
     3262void GuestScreenInfo::FinalRelease()
     3263{
     3264    uninit();
     3265
     3266    BaseFinalRelease();
     3267}
     3268
     3269HRESULT GuestScreenInfo::init(ULONG aDisplay,
     3270                              GuestMonitorStatus_T aGuestMonitorStatus,
     3271                              BOOL aPrimary,
     3272                              BOOL aChangeOrigin,
     3273                              LONG aOriginX,
     3274                              LONG aOriginY,
     3275                              ULONG aWidth,
     3276                              ULONG aHeight,
     3277                              ULONG aBitsPerPixel)
     3278{
     3279    LogFlowThisFunc(("[%u]\n", aDisplay));
     3280
     3281    /* Enclose the state transition NotReady->InInit->Ready */
     3282    AutoInitSpan autoInitSpan(this);
     3283    AssertReturn(autoInitSpan.isOk(), E_FAIL);
     3284
     3285    mScreenId = aDisplay;
     3286    mGuestMonitorStatus = aGuestMonitorStatus;
     3287    mPrimary = aPrimary;
     3288    mOrigin = aChangeOrigin;
     3289    mOriginX =  aOriginX;
     3290    mOriginY = aOriginY;
     3291    mWidth = aWidth;
     3292    mHeight = aHeight;
     3293    mBitsPerPixel = aBitsPerPixel;
     3294
     3295    /* Confirm a successful initialization */
     3296    autoInitSpan.setSucceeded();
     3297
     3298    return S_OK;
     3299}
     3300
     3301void GuestScreenInfo::uninit()
     3302{
     3303    /* Enclose the state transition Ready->InUninit->NotReady */
     3304    AutoUninitSpan autoUninitSpan(this);
     3305    if (autoUninitSpan.uninitDone())
     3306        return;
     3307
     3308    LogFlowThisFunc(("[%u]\n", mScreenId));
     3309}
     3310
     3311HRESULT GuestScreenInfo::getScreenId(ULONG *aScreenId)
     3312{
     3313    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3314    *aScreenId = mScreenId;
     3315    return S_OK;
     3316}
     3317
     3318HRESULT GuestScreenInfo::getGuestMonitorStatus(GuestMonitorStatus_T *aGuestMonitorStatus)
     3319{
     3320    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3321    *aGuestMonitorStatus = mGuestMonitorStatus;
     3322    return S_OK;
     3323}
     3324
     3325HRESULT GuestScreenInfo::getPrimary(BOOL *aPrimary)
     3326{
     3327    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3328    *aPrimary = mPrimary;
     3329    return S_OK;
     3330}
     3331
     3332HRESULT GuestScreenInfo::getOrigin(BOOL *aOrigin)
     3333{
     3334    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3335    *aOrigin = mOrigin;
     3336    return S_OK;
     3337}
     3338
     3339HRESULT GuestScreenInfo::getOriginX(LONG *aOriginX)
     3340{
     3341    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3342    *aOriginX = mOriginX;
     3343    return S_OK;
     3344}
     3345
     3346HRESULT GuestScreenInfo::getOriginY(LONG *aOriginY)
     3347{
     3348    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3349    *aOriginY = mOriginY;
     3350    return S_OK;
     3351}
     3352
     3353HRESULT GuestScreenInfo::getWidth(ULONG *aWidth)
     3354{
     3355    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3356    *aWidth = mWidth;
     3357    return S_OK;
     3358}
     3359
     3360HRESULT GuestScreenInfo::getHeight(ULONG *aHeight)
     3361{
     3362    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3363    *aHeight = mHeight;
     3364    return S_OK;
     3365}
     3366
     3367HRESULT GuestScreenInfo::getBitsPerPixel(ULONG *aBitsPerPixel)
     3368{
     3369    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3370    *aBitsPerPixel = mBitsPerPixel;
     3371    return S_OK;
     3372}
     3373
     3374HRESULT GuestScreenInfo::getExtendedInfo(com::Utf8Str &aExtendedInfo)
     3375{
     3376    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     3377    aExtendedInfo = com::Utf8Str();
     3378    return S_OK;
    31353379}
    31363380
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