VirtualBox

Changeset 79028 in vbox


Ignore:
Timestamp:
Jun 6, 2019 3:05:36 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
131180
Message:

Additions/VBoxClient/VMSVGA: use VbglR3GetDisplayChangeRequestMulti.
Change log: Additions/linux: do not forget the last size hint on guest reboot.
For VBoxClient with guests using VMSVGA, switch to using
VbglR3GetDisplayChangeRequestMulti to retrieve guest hints and query hints
before waiting for change notifications. This makes sure that hints send
before a guest reboot will keep their effect over the reboot.

Location:
trunk/src/VBox/Additions/x11/VBoxClient
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/display-svga-x11.cpp

    r77938 r79028  
    237237    unsigned i;
    238238    int rc;
    239     uint32_t acx[VMW_MAX_HEADS] = { 0 };
    240     uint32_t acy[VMW_MAX_HEADS] = { 0 };
    241     uint32_t adx[VMW_MAX_HEADS] = { 0 };
    242     uint32_t ady[VMW_MAX_HEADS] = { 0 };
    243     uint32_t afEnabled[VMW_MAX_HEADS] = { false };
    244239    struct X11VMWRECT aRects[VMW_MAX_HEADS];
    245240    unsigned cHeads;
     
    265260    {
    266261        uint32_t events;
    267 
    268         rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, RT_INDEFINITE_WAIT, &events);
     262        struct VMMDevDisplayDef aDisplays[VMW_MAX_HEADS];
     263        uint32_t cDisplaysOut;
     264
     265        /* Query the first size without waiting.  This lets us e.g. pick up
     266         * the last event before a guest reboot when we start again after. */
     267        rc = VbglR3GetDisplayChangeRequestMulti(VMW_MAX_HEADS, &cDisplaysOut, aDisplays, true);
    269268        if (RT_FAILURE(rc))
    270             VBClFatalError(("Failure waiting for event, rc=%Rrc\n", rc));
    271         while (rc != VERR_TIMEOUT)
     269            VBClFatalError(("Failed to get display change request, rc=%Rrc\n", rc));
     270        if (cDisplaysOut > VMW_MAX_HEADS)
     271            VBClFatalError(("Display change request contained, rc=%Rrc\n", rc));
     272        for (i = 0, cHeads = 0; i < cDisplaysOut && i < VMW_MAX_HEADS; ++i)
    272273        {
    273             uint32_t cx, cy, cBits, dx, dy, idx;
    274             bool fEnabled, fChangeOrigin;
    275 
    276             rc = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBits, &idx, &dx, &dy, &fEnabled, &fChangeOrigin, true);
    277             if (RT_FAILURE(rc))
    278                 VBClFatalError(("Failed to get display change request, rc=%Rrc\n", rc));
    279             if (idx < VMW_MAX_HEADS)
     274            if (!(aDisplays[i].fDisplayFlags & VMMDEV_DISPLAY_DISABLED))
    280275            {
    281                 acx[idx] = cx;
    282                 acy[idx] = cy;
    283                 if (fChangeOrigin)
    284                     adx[idx] = dx < INT32_MAX ? dx : 0;
    285                 if (fChangeOrigin)
    286                     ady[idx] = dy < INT32_MAX ? dy : 0;
    287                 afEnabled[idx] = fEnabled;
    288             }
    289             rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0, &events);
    290             if (RT_FAILURE(rc) && rc != VERR_TIMEOUT && rc != VERR_INTERRUPTED)
    291                 VBClFatalError(("Failure waiting for event, rc=%Rrc\n", rc));
    292         }
    293         for (i = 0, cHeads = 0; i < VMW_MAX_HEADS; ++i)
    294         {
    295             if (afEnabled[i])
    296             {
    297                 aRects[cHeads].x = (int16_t)adx[i];
    298                 aRects[cHeads].y = (int16_t)ady[i];
    299                 aRects[cHeads].w = (uint16_t)acx[i];
    300                 aRects[cHeads].h = (uint16_t)acy[i];
     276                if ((i == 0) || (aDisplays[i].fDisplayFlags & VMMDEV_DISPLAY_ORIGIN))
     277                {
     278                    aRects[cHeads].x =   aDisplays[i].xOrigin < INT16_MAX
     279                                       ? (int16_t)aDisplays[i].xOrigin : 0;
     280                    aRects[cHeads].y =   aDisplays[i].yOrigin < INT16_MAX
     281                                       ? (int16_t)aDisplays[i].yOrigin : 0;
     282                } else {
     283                    aRects[cHeads].x = aRects[cHeads - 1].x + aRects[cHeads - 1].w;
     284                    aRects[cHeads].y = aRects[cHeads - 1].y;
     285                }
     286                aRects[cHeads].w = (int16_t)RT_MIN(aDisplays[i].cx, INT16_MAX);
     287                aRects[cHeads].h = (int16_t)RT_MIN(aDisplays[i].cy, INT16_MAX);
    301288                ++cHeads;
    302289            }
     
    304291        x11SendHints(&x11Context, aRects, cHeads);
    305292        x11GetScreenInfo(&x11Context);
     293        rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, RT_INDEFINITE_WAIT, &events);
     294        if (RT_FAILURE(rc))
     295            VBClFatalError(("Failure waiting for event, rc=%Rrc\n", rc));
    306296    }
    307297}
  • trunk/src/VBox/Additions/x11/VBoxClient/display-svga.cpp

    r76553 r79028  
    4747#include <iprt/string.h>
    4848
     49#include <stdio.h>
     50
    4951/** Maximum number of supported screens.  DRM and X11 both limit this to 32. */
    5052/** @todo if this ever changes, dynamically allocate resizeable arrays in the
     
    177179    unsigned i;
    178180    int rc;
    179     uint32_t acx[VMW_MAX_HEADS] = { 0 };
    180     uint32_t acy[VMW_MAX_HEADS] = { 0 };
    181     uint32_t adx[VMW_MAX_HEADS] = { 0 };
    182     uint32_t ady[VMW_MAX_HEADS] = { 0 };
    183     uint32_t afEnabled[VMW_MAX_HEADS] = { false };
    184181    struct DRMVMWRECT aRects[VMW_MAX_HEADS];
    185182    unsigned cHeads;
     183    /* Do not acknowledge the first event we query for to pick up old events,
     184     * e.g. from before a guest reboot. */
     185    bool fAck = false;
    186186
    187187    drmConnect(&drmContext);
     
    203203    {
    204204        uint32_t events;
    205 
    206         rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, RT_INDEFINITE_WAIT, &events);
    207         if (RT_FAILURE(rc))
    208             VBClFatalError(("Failure waiting for event, rc=%Rrc\n", rc));
    209         while (rc != VERR_TIMEOUT)
     205        struct VMMDevDisplayDef aDisplays[VMW_MAX_HEADS];
     206        uint32_t cDisplaysOut;
     207
     208        /* Query the first size without waiting.  This lets us e.g. pick up
     209         * the last event before a guest reboot when we start again after. */
     210        rc = VbglR3GetDisplayChangeRequestMulti(VMW_MAX_HEADS, &cDisplaysOut, aDisplays, fAck);
     211        fAck = true;
     212        if (RT_FAILURE(rc))
     213            VBClFatalError(("Failed to get display change request, rc=%Rrc\n", rc));
     214        if (cDisplaysOut > VMW_MAX_HEADS)
     215            VBClFatalError(("Display change request contained, rc=%Rrc\n", rc));
     216        for (i = 0, cHeads = 0; i < cDisplaysOut && i < VMW_MAX_HEADS; ++i)
    210217        {
    211             uint32_t cx, cy, cBits, dx, dy, idx;
    212             bool fEnabled, fChangeOrigin;
    213 
    214             rc = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBits, &idx, &dx, &dy, &fEnabled, &fChangeOrigin, true);
    215             if (RT_FAILURE(rc))
    216                 VBClFatalError(("Failed to get display change request, rc=%Rrc\n", rc));
    217             if (idx < VMW_MAX_HEADS)
     218            if (!(aDisplays[i].fDisplayFlags & VMMDEV_DISPLAY_DISABLED))
    218219            {
    219                 acx[idx] = cx;
    220                 acy[idx] = cy;
    221                 if (fChangeOrigin)
    222                     adx[idx] = dx < INT32_MAX ? dx : 0;
    223                 if (fChangeOrigin)
    224                     ady[idx] = dy < INT32_MAX ? dy : 0;
    225                 afEnabled[idx] = fEnabled;
    226             }
    227             rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0, &events);
    228             if (RT_FAILURE(rc) && rc != VERR_TIMEOUT && rc != VERR_INTERRUPTED)
    229                 VBClFatalError(("Failure waiting for event, rc=%Rrc\n", rc));
    230         }
    231         for (i = 0, cHeads = 0; i < VMW_MAX_HEADS; ++i)
    232         {
    233             if (afEnabled[i])
    234             {
    235                 if ((i == 0) || (adx[i] || ady[i]))
     220                if ((i == 0) || (aDisplays[i].fDisplayFlags & VMMDEV_DISPLAY_ORIGIN))
    236221                {
    237                     aRects[cHeads].x = (int32_t)adx[i];
    238                     aRects[cHeads].y = (int32_t)ady[i];
     222                    aRects[cHeads].x = aDisplays[i].xOrigin;
     223                    aRects[cHeads].y = aDisplays[i].yOrigin;
    239224                } else {
    240                     aRects[cHeads].x = (int32_t)(adx[i - 1] + acx[i - 1]);
    241                     aRects[cHeads].y = (int32_t)ady[i - 1];
     225                    aRects[cHeads].x = aRects[cHeads - 1].x + aRects[cHeads - 1].w;
     226                    aRects[cHeads].y = aRects[cHeads - 1].y;
    242227                }
    243                 aRects[cHeads].w = acx[i];
    244                 aRects[cHeads].h = acy[i];
     228                aRects[cHeads].w = aDisplays[i].cx;
     229                aRects[cHeads].h = aDisplays[i].cy;
    245230                ++cHeads;
    246231            }
    247232        }
     233        for (i = 0; i < cHeads; ++i)
     234            printf("Head %u: %dx%d, (%d, %d)\n", i, (int)aRects[i].w, (int)aRects[i].h,
     235                   (int)aRects[i].x, (int)aRects[i].y);
    248236        drmSendHints(&drmContext, aRects, cHeads);
     237        rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, RT_INDEFINITE_WAIT, &events);
     238        if (RT_FAILURE(rc))
     239            VBClFatalError(("Failure waiting for event, rc=%Rrc\n", rc));
    249240    }
    250241}
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