VirtualBox

Ignore:
Timestamp:
Apr 14, 2015 2:17:18 PM (10 years ago)
Author:
vboxsync
Message:

Additions/x11: temporary check in of local changes to vboxvideo for 5.0beta2.

Location:
trunk/src/VBox/Additions/x11/vboxvideo
Files:
7 edited

Legend:

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

    r55191 r55250  
    77 * Dynamic resizing should work, on CentOS 6 and later Linux guests it should
    88   work without VBoxClient running.
    9  * Disabling and enabling virtual screens (only possible as of 4.4).
     9 * Disabling and enabling virtual screens (VBoxManage in 4.3).
    1010 * Dynamic resizing with one of more virtual screens disabled.
    1111 * Test switching to virtual terminals and back from windowed, full screen and
    12    seamless modes.
     12   seamless modes (seamless currently only works properly with VBoxClient
     13   running).
    1314 * Test switching directly between normal, full-screen, seamless and scaled
    1415   modes.
    15  * Test enabling and disabling guest screens from the host.
    1616 * execute "xprop -root | grep VBOX" after resizing a screen: VBOX_SIZE_HINTS
    1717   should be set, and VBOX_SIZE_HINTS_MISMATCH should equal 0 on CentOS 6 and
    18    later.
     18   later (4.4 and later).
     19 * Test re-ordering the virtual screen using the native guest operating system
     20   tools and make sure that mouse integration still works as expected.
     21 * Test disabling and re-enabling guest screens with the native system tools.
     22 * Try disabling and re-enabling mouse integration and check that capturing
     23   works with multiple guest screens.
    1924 * Shutting down and re-starting a virtual machine should restore the last size
    20    for all monitors (note: currently only after log-in).
     25   for all monitors (note: currently only after log-in).  Full shut-down, not
     26   a reboot.
     27 * Test power management by disabling guest screens ("xrandr --output VGA-n
     28   --off") and re-enabling them ("xrandr --output VGA-n --preferred --pos XxY")
     29   where X and Y are the position of the screen before disabling it.
     30 * Test sending video mode hints with screen position information via
     31   VBoxManage.  The screen position is a hint only.  The approximate position
     32   should be preserved after a shut down and re-start of the guest.
     33 * Test re-starting the X server after resizing all guest windows.  The server
     34   should not crash.
  • trunk/src/VBox/Additions/x11/vboxvideo/getmode.c

    r55225 r55250  
    3838#ifdef VBOXVIDEO_13
    3939# ifdef RT_OS_LINUX
    40 # include "randrstr.h"
    41 # include "xf86_OSproc.h"
    4240#  include <linux/input.h>
    4341#  ifndef EVIOCGRAB
     
    5351# endif /* RT_OS_LINUX */
    5452#endif /* VBOXVIDEO_13 */
     53
    5554/**************************************************************************
    5655* Main functions                                                          *
     
    155154}
    156155
    157 /** Set the initial values for the guest screen size hints by reading saved
    158  * values from files. */
    159 /** @todo Actually read the files instead of setting dummies. */
     156/** Set the initial values for the guest screen size hints to standard values
     157 * in case nothing else is available. */
    160158void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn)
    161159{
     
    173171    pScrn->modes->HDisplay = pVBox->pScreens[0].aPreferredSize.cx;
    174172    pScrn->modes->VDisplay = pVBox->pScreens[0].aPreferredSize.cy;
    175     /* RandR 1.1 quirk: make sure that the initial resolution is always present
    176      * in the mode list as RandR will always advertise a mode of the initial
    177      * virtual resolution via GetScreenInfo. */
    178     pMode = vboxAddEmptyScreenMode(pScrn);
    179     vboxFillDisplayMode(pScrn, pMode, NULL, pVBox->pScreens[0].aPreferredSize.cx,
    180                         pVBox->pScreens[0].aPreferredSize.cy);
    181 }
    182 
    183 static void updateUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities)
    184 {
    185     if (   !(fCursorCapabilities & VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER)
    186         && (fCursorCapabilities & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
    187         pVBox->fUseHardwareCursor = true;
    188     else
    189         pVBox->fUseHardwareCursor = false;
    190 }
    191 
    192 # define SIZE_HINTS_PROPERTY         "VBOX_SIZE_HINTS"
    193 # define MOUSE_CAPABILITIES_PROPERTY "VBOX_MOUSE_CAPABILITIES"
    194 
    195 /** Read in information about the most recent size hints requested for the
    196  * guest screens.  A client application sets the hint information as a root
    197  * window property. */
    198 /* TESTING: dynamic resizing and absolute pointer toggling work on old guest X servers and recent ones on Linux at the log-in screen. */
    199 /** @note we try to maximise code coverage by typically using all code paths (HGSMI and properties) in a single X session. */
    200 void VBoxUpdateSizeHints(ScrnInfoPtr pScrn)
    201 {
    202     VBOXPtr pVBox = VBOXGetRec(pScrn);
    203     size_t cModesFromProperty, cDummy;
    204     int32_t *paModeHints, *pfCursorCapabilities;
    205     unsigned i;
    206     uint32_t fCursorCapabilities;
    207     bool fOldUseHardwareCursor = pVBox->fUseHardwareCursor;
    208 
    209     if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cModesFromProperty, &paModeHints) != VINF_SUCCESS)
    210         paModeHints = NULL;
    211     if (   vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) != VINF_SUCCESS
    212         || cDummy != 1)
    213         pfCursorCapabilities = NULL;
    214 #ifdef VBOXVIDEO_13
    215     if (!pVBox->fHaveReadHGSMIModeHintData && RT_SUCCESS(VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens,
    216                                                          pVBox->paVBVAModeHints)))
    217     {
    218         for (i = 0; i < pVBox->cScreens; ++i)
    219         {
    220             if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC)
    221             {
    222                 pVBox->pScreens[i].aPreferredSize.cx = pVBox->paVBVAModeHints[i].cx;
    223                 pVBox->pScreens[i].aPreferredSize.cy = pVBox->paVBVAModeHints[i].cy;
    224                 pVBox->pScreens[i].afConnected = pVBox->paVBVAModeHints[i].fEnabled;
    225                 /* Do not re-read this if we have data from HGSMI. */
    226                 if (paModeHints != NULL && i < cModesFromProperty)
    227                     pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i];
    228             }
    229         }
    230     }
    231     if (!pVBox->fHaveReadHGSMIModeHintData)
    232     {
    233         if (RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities)))
    234             updateUseHardwareCursor(pVBox, fCursorCapabilities);
    235         else
    236             pVBox->fUseHardwareCursor = false;
    237         /* Do not re-read this if we have data from HGSMI. */
    238         if (pfCursorCapabilities != NULL)
    239             pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities;
    240     }
    241     pVBox->fHaveReadHGSMIModeHintData = true;
    242 #endif
    243     if (paModeHints != NULL)
    244         for (i = 0; i < cModesFromProperty && i < pVBox->cScreens; ++i)
    245         {
    246             if (paModeHints[i] != 0 && paModeHints[i] != pVBox->pScreens[i].lastModeHintFromProperty)
    247             {
    248                 if (paModeHints[i] == -1)
    249                     pVBox->pScreens[i].afConnected = false;
    250                 else
    251                 {
    252                     pVBox->pScreens[i].aPreferredSize.cx = paModeHints[i] >> 16;
    253                     pVBox->pScreens[i].aPreferredSize.cy = paModeHints[i] & 0x8fff;
    254                     pVBox->pScreens[i].afConnected = true;
    255                 }
    256                 pVBox->pScreens[i].lastModeHintFromProperty = paModeHints[i];
    257             }
    258         }
    259     if (pfCursorCapabilities != NULL && *pfCursorCapabilities != pVBox->fLastCursorCapabilitiesFromProperty)
    260     {
    261         updateUseHardwareCursor(pVBox, (uint32_t)*pfCursorCapabilities);
    262         pVBox->fLastCursorCapabilitiesFromProperty = *pfCursorCapabilities;
    263     }
    264     if (pVBox->fUseHardwareCursor != fOldUseHardwareCursor)
    265         vbvxReprobeCursor(pScrn);
    266173}
    267174
     
    397304#undef COMPARE_AND_MAYBE_SET
    398305
    399 #ifndef VBOXVIDEO_13
    400 
    401 /** The RandR "proc" vector, which we wrap with our own in order to notice
    402  * when a client sends a GetScreenInfo request. */
    403 static int (*g_pfnVBoxRandRProc)(ClientPtr) = NULL;
    404 /** The swapped RandR "proc" vector. */
    405 static int (*g_pfnVBoxRandRSwappedProc)(ClientPtr) = NULL;
    406 
    407 /* TESTING: dynamic resizing and toggling cursor integration work with older guest X servers (1.2 and older). */
    408 static void vboxRandRDispatchCore(ClientPtr pClient)
    409 {
    410     xRRGetScreenInfoReq *pReq = (xRRGetScreenInfoReq *)pClient->requestBuffer;
    411     WindowPtr pWin;
    412     ScrnInfoPtr pScrn;
    413     VBOXPtr pVBox;
    414     DisplayModePtr pMode;
    415 
    416     if (pClient->req_len != sizeof(xRRGetScreenInfoReq) >> 2)
    417         return;
    418     pWin = (WindowPtr)SecurityLookupWindow(pReq->window, pClient,
    419                                            SecurityReadAccess);
    420     if (!pWin)
    421         return;
    422     pScrn = xf86Screens[pWin->drawable.pScreen->myNum];
    423     pVBox = VBOXGetRec(pScrn);
    424     TRACE_LOG("pVBox->fUseHardwareCursor=%u\n", pVBox->fUseHardwareCursor);
    425     VBoxUpdateSizeHints(pScrn);
    426     pMode = pScrn->modes;
    427     if (pScrn->currentMode == pMode)
    428         pMode = pMode->next;
    429     pMode->HDisplay = pVBox->pScreens[0].aPreferredSize.cx;
    430     pMode->VDisplay = pVBox->pScreens[0].aPreferredSize.cy;
    431 }
    432 
    433 static int vboxRandRDispatch(ClientPtr pClient)
    434 {
    435     xReq *pReq = (xReq *)pClient->requestBuffer;
    436 
    437     if (pReq->data == X_RRGetScreenInfo)
    438         vboxRandRDispatchCore(pClient);
    439     return g_pfnVBoxRandRProc(pClient);
    440 }
    441 
    442 static int vboxRandRSwappedDispatch(ClientPtr pClient)
    443 {
    444     xReq *pReq = (xReq *)pClient->requestBuffer;
    445 
    446     if (pReq->data == X_RRGetScreenInfo)
    447         vboxRandRDispatchCore(pClient);
    448     return g_pfnVBoxRandRSwappedProc(pClient);
    449 }
    450 
    451 static Bool vboxRandRCreateScreenResources(ScreenPtr pScreen)
    452 {
    453     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    454     VBOXPtr pVBox = VBOXGetRec(pScrn);
    455     ExtensionEntry *pExt;
    456 
    457     pScreen->CreateScreenResources = pVBox->pfnCreateScreenResources;
    458     if (!pScreen->CreateScreenResources(pScreen))
    459         return FALSE;
    460     /* I doubt we can be loaded twice - should I fail here? */
    461     if (g_pfnVBoxRandRProc)
    462         return TRUE;
    463     pExt = CheckExtension(RANDR_NAME);
    464     if (!pExt)
    465     {
    466         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    467                    "RandR extension not found, disabling dynamic resizing.\n");
    468         return TRUE;
    469     }
    470     if (   !ProcVector[pExt->base]
    471 #if    !defined(XF86_VERSION_CURRENT) \
    472     || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0)
    473     /* SwappedProcVector is not exported in XFree86, so we will not support
    474      * swapped byte order clients.  I doubt this is a big issue. */
    475         || !SwappedProcVector[pExt->base]
    476 #endif
    477         )
    478         FatalError("RandR \"proc\" vector not initialised\n");
    479     g_pfnVBoxRandRProc = ProcVector[pExt->base];
    480     ProcVector[pExt->base] = vboxRandRDispatch;
    481 #if    !defined(XF86_VERSION_CURRENT) \
    482     || XF86_VERSION_CURRENT >= XF86_VERSION_NUMERIC(4, 3, 99, 0, 0)
    483     g_pfnVBoxRandRSwappedProc = SwappedProcVector[pExt->base];
    484     SwappedProcVector[pExt->base] = vboxRandRSwappedDispatch;
    485 #endif
    486     return TRUE;
    487 }
    488 
    489 /** Install our private RandR hook procedure, so that we can detect
    490  * GetScreenInfo requests from clients to update our dynamic mode.  This works
    491  * by installing a wrapper around CreateScreenResources(), which will be called
    492  * after RandR is initialised.  The wrapper then in turn wraps the RandR "proc"
    493  * vectors with its own handlers which will get called on any client RandR
    494  * request.  This should not be used in conjunction with RandR 1.2 or later.
    495  * A couple of points of interest in our RandR 1.1 support:
    496  *  * We use the first two screen modes as dynamic modes.  When a new mode hint
    497  *    arrives we update the first of the two which is not the current mode with
    498  *    the new size.
    499  *  * RandR 1.1 always advertises a mode of the size of the initial virtual
    500  *    resolution via GetScreenInfo(), so we make sure that a mode of that size
    501  *    is always present in the list.
    502  *  * RandR adds each new mode it sees to an internal array, but never removes
    503  *    entries.  This array might end up getting rather long given that we can
    504  *    report a lot more modes than physical hardware.
    505  */
    506 void VBoxSetUpRandR11(ScreenPtr pScreen)
    507 {
    508     VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
    509 
    510     if (!pScreen->CreateScreenResources)
    511         FatalError("called to early: CreateScreenResources not yet initialised\n");
    512     pVBox->pfnCreateScreenResources = pScreen->CreateScreenResources;
    513     pScreen->CreateScreenResources = vboxRandRCreateScreenResources;
    514 }
    515 
    516 #endif /* !VBOXVIDEO_13 */
    517 
    518306#ifdef VBOXVIDEO_13
    519307# ifdef RT_OS_LINUX
    520 /* TESTING: dynamic resizing works on recent Linux guest X servers at the log-in screen. */
    521 /** @note to maximise code coverage we only read data from HGSMI once, and only when responding to an ACPI event. */
     308/** We have this for two purposes: one is to ensure that the X server is woken
     309 * up when we get a video ACPI event.  Two is to grab ACPI video events to
     310 * prevent gnome-settings-daemon from seeing them, as older versions ignored
     311 * the time stamp and handled them at the wrong time. */
    522312static void acpiEventHandler(int fd, void *pvData)
    523313{
     
    527317    ssize_t rc;
    528318
    529     pVBox->fHaveReadHGSMIModeHintData = false;
    530     RRGetInfo(pScreen
    531 # if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
    532               , TRUE
    533 # endif
    534              );
    535     VBVXASSERT(pVBox->fHaveReadHGSMIModeHintData == true, ("fHaveReadHGSMIModeHintData not set.\n"));
    536319    do
    537320        rc = read(fd, &event, sizeof(event));
     
    541324}
    542325
    543 void VBoxSetUpLinuxACPI(ScreenPtr pScreen)
     326void vbvxSetUpLinuxACPI(ScreenPtr pScreen)
    544327{
    545328    VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
     
    591374}
    592375
    593 void VBoxCleanUpLinuxACPI(ScreenPtr pScreen)
     376void vbvxCleanUpLinuxACPI(ScreenPtr pScreen)
    594377{
    595378    VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
     
    602385# endif /* RT_OS_LINUX */
    603386#endif /* VBOXVIDEO_13 */
     387
  • trunk/src/VBox/Additions/x11/vboxvideo/helpers.c

    r55225 r55250  
    5555}
    5656
    57 /* TESTING: if this is broken, dynamic resizing will not work on old X servers (1.2 and older). */
    5857int vbvxGetIntegerPropery(ScrnInfoPtr pScrn, char *pszName, size_t *pcData, int32_t **ppaData)
    5958{
  • trunk/src/VBox/Additions/x11/vboxvideo/setmode.c

    r55242 r55250  
    9191}
    9292
    93 /** Clear the virtual framebuffer in VRAM.  Optionally also clear up to the
    94  * size of a new framebuffer.  Framebuffer sizes larger than available VRAM
    95  * be treated as zero and passed over. */
    96 void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY)
    97 {
    98     VBOXPtr pVBox = VBOXGetRec(pScrn);
    99     uint64_t cbOldFB, cbNewFB;
    100 
    101     cbOldFB = pVBox->cbLine * pScrn->virtualX;
    102     cbNewFB = vboxLineLength(pScrn, cNewX) * cNewY;
    103     if (cbOldFB > (uint64_t)pVBox->cbFBMax)
    104         cbOldFB = 0;
    105     if (cbNewFB > (uint64_t)pVBox->cbFBMax)
    106         cbNewFB = 0;
    107     memset(pVBox->base, 0, max(cbOldFB, cbNewFB));
    108 }
    109 
    11093/** Set a graphics mode.  Poke any required values into registers, do an HGSMI
    11194 * mode set and tell the host we support advanced graphics functions.
     
    140123}
    141124
    142 /** Set a graphics mode.  Poke any required values into registers, do an HGSMI
    143  * mode set and tell the host we support advanced graphics functions.  This
    144  * procedure is complicated by the fact that X.Org can implicitly disable a
    145  * screen by resizing the virtual framebuffer so that the screen is no longer
    146  * inside it.  We have to spot and handle this.
    147  */
    148 Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
    149                  unsigned cHeight, int x, int y)
    150 {
    151     VBOXPtr pVBox = VBOXGetRec(pScrn);
    152     uint32_t offStart, cwReal = cWidth;
    153     bool fEnabled;
    154     uint16_t fFlags;
    155     int rc;
    156 
    157     TRACE_LOG("cDisplay=%u, cWidth=%u, cHeight=%u, x=%d, y=%d, displayWidth=%d\n",
    158               cDisplay, cWidth, cHeight, x, y, pScrn->displayWidth);
    159     offStart = y * pVBox->cbLine + x * vboxBPP(pScrn) / 8;
    160     /* Deactivate the screen if the mode - specifically the virtual width - is
    161      * too large for VRAM as we sometimes have to do this - see comments in
    162      * VBOXPreInit. */
    163     if (   offStart + pVBox->cbLine * cHeight > pVBox->cbFBMax
    164         || pVBox->cbLine * pScrn->virtualY > pVBox->cbFBMax)
    165         return FALSE;
    166     /* Deactivate the screen if it is outside of the virtual framebuffer and
    167      * clamp it to lie inside if it is partly outside. */
    168     if (x >= pScrn->displayWidth || x + (int) cWidth <= 0)
    169         return FALSE;
    170     else
    171         cwReal = RT_MIN((int) cWidth, pScrn->displayWidth - x);
    172     TRACE_LOG("pVBox->pScreens[%u].fCrtcEnabled=%d, fOutputEnabled=%d\n",
    173               cDisplay, (int)pVBox->pScreens[cDisplay].fCrtcEnabled,
    174               (int)pVBox->pScreens[cDisplay].fOutputEnabled);
    175     if (cDisplay == 0)
    176         VBoxVideoSetModeRegisters(cwReal, cHeight, pScrn->displayWidth,
    177                                   vboxBPP(pScrn), 0, x, y);
    178     fEnabled =    pVBox->pScreens[cDisplay].fCrtcEnabled
    179                && pVBox->pScreens[cDisplay].fOutputEnabled;
    180     fFlags = VBVA_SCREEN_F_ACTIVE;
    181     fFlags |= (pVBox->pScreens[cDisplay].afConnected ? 0
    182                                                      : VBVA_SCREEN_F_DISABLED);
    183     VBoxHGSMIProcessDisplayInfo(&pVBox->guestCtx, cDisplay, x, y,
    184                                 offStart, pVBox->cbLine, cwReal, cHeight,
    185                                 fEnabled ? vboxBPP(pScrn) : 0, fFlags);
    186     if (cDisplay == 0)
    187     {
    188         rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x,
    189                                          0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY);
    190         if (RT_FAILURE(rc))
    191             FatalError("Failed to update the input mapping.\n");
    192     }
    193     return TRUE;
    194 }
    195 
    196 /** Resize the virtual framebuffer.  After resizing we reset all modes
    197  * (X.Org 1.3+) to adjust them to the new framebuffer.
    198  */
    199 Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
    200 {
    201     ScreenPtr pScreen = pScrn->pScreen;
    202     PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
    203     VBOXPtr pVBox = VBOXGetRec(pScrn);
    204     uint64_t cbLine = vboxLineLength(pScrn, width);
    205     int displayWidth = vboxDisplayPitch(pScrn, cbLine);
    206     int rc;
    207 
    208     TRACE_LOG("width=%d, height=%d\n", width, height);
    209     if (   width == pScrn->virtualX
    210         && height == pScrn->virtualY
    211         && displayWidth == pScrn->displayWidth)
    212         return TRUE;
    213     if (!pPixmap) {
    214         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    215                    "Failed to get the screen pixmap.\n");
    216         return FALSE;
    217     }
    218     if (cbLine > UINT32_MAX || cbLine * height >= pVBox->cbFBMax)
    219     {
    220         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    221                    "Unable to set up a virtual screen size of %dx%d with %lu of %d Kb of video memory available.  Please increase the video memory size.\n",
    222                    width, height, pVBox->cbFBMax / 1024, pScrn->videoRam);
    223         return FALSE;
    224     }
    225     pScreen->ModifyPixmapHeader(pPixmap, width, height,
    226                                 pScrn->depth, vboxBPP(pScrn), cbLine,
    227                                 pVBox->base);
    228     vboxClearVRAM(pScrn, width, height);
    229     pScrn->virtualX = width;
    230     pScrn->virtualY = height;
    231     pScrn->displayWidth = displayWidth;
    232     pVBox->cbLine = cbLine;
    233 #ifdef VBOX_DRI_OLD
    234     if (pVBox->useDRI)
    235         VBOXDRIUpdateStride(pScrn, pVBox);
    236 #endif
    237 #ifdef VBOXVIDEO_13
    238     /* Write the new values to the hardware */
    239     /** @todo why is this only for VBOXVIDEO_13? */
    240     {
    241         unsigned i;
    242         for (i = 0; i < pVBox->cScreens; ++i)
    243             VBOXSetMode(pScrn, i, pVBox->pScreens[i].aScreenLocation.cx,
    244                             pVBox->pScreens[i].aScreenLocation.cy,
    245                             pVBox->pScreens[i].aScreenLocation.x,
    246                             pVBox->pScreens[i].aScreenLocation.y);
    247     }
    248 #else
    249     rc = VBoxHGSMIUpdateInputMapping(&pVBox->guestCtx, 0 - pVBox->pScreens[0].aScreenLocation.x,
    250                                      0 - pVBox->pScreens[0].aScreenLocation.y, pScrn->virtualX, pScrn->virtualY);
    251     if (RT_FAILURE(rc))
    252         FatalError("Failed to update the input mapping.\n");
    253 #endif
    254     vbvxSetSolarisMouseRange(width, height);
    255     return TRUE;
    256 }
    257 
    258125/** Tell the virtual mouse device about the new virtual desktop size. */
    259126void vbvxSetSolarisMouseRange(int width, int height)
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c

    r55236 r55250  
    8080
    8181#include "fb.h"
     82#include "os.h"
    8283
    8384#include "vboxvideo.h"
    8485#include <VBox/VBoxGuest.h>
     86#include <VBox/Hardware/VBoxVideoVBE.h>
    8587#include "version-generated.h"
    8688#include "product-generated.h"
     
    98100/* #define DPMS_SERVER
    99101#include "extensions/dpms.h" */
     102
     103/* ShadowFB support */
     104#include "shadowfb.h"
    100105
    101106/* VGA hardware functions for setting and restoring text mode */
     
    145150static void VBOXSaveMode(ScrnInfoPtr pScrn);
    146151static void VBOXRestoreMode(ScrnInfoPtr pScrn);
     152static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime);
     153
     154#ifndef XF86_SCRN_INTERFACE
     155# define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum]
     156# define xf86ScrnToScreen(pScrn) screenInfo.screens[(pScrn)->scrnIndex]
     157#endif
    147158
    148159static inline void VBOXSetRec(ScrnInfoPtr pScrn)
     
    262273#endif /* !XORG_7X */
    263274
     275/** Resize the virtual framebuffer. */
     276static Bool adjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
     277{
     278    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
     279    VBOXPtr pVBox = VBOXGetRec(pScrn);
     280    int adjustedWidth = pScrn->bitsPerPixel == 16 ? (width + 1) & ~1 : width;
     281    int cbLine = adjustedWidth * pScrn->bitsPerPixel / 8;
     282    PixmapPtr pPixmap;
     283    int rc;
     284
     285    TRACE_LOG("width=%d, height=%d\n", width, height);
     286    VBVXASSERT(width >= 0 && height >= 0, ("Invalid negative width (%d) or height (%d)\n", width, height));
     287    if (pScreen == NULL)  /* Not yet initialised. */
     288        return TRUE;
     289    pPixmap = pScreen->GetScreenPixmap(pScreen);
     290    VBVXASSERT(pPixmap != NULL, ("Failed to get the screen pixmap.\n"));
     291    TRACE_LOG("pPixmap=%p adjustedWidth=%d height=%d pScrn->depth=%d pScrn->bitsPerPixel=%d cbLine=%d pVBox->base=%p pPixmap->drawable.width=%d pPixmap->drawable.height=%d\n",
     292              pPixmap, adjustedWidth, height, pScrn->depth, pScrn->bitsPerPixel, cbLine, pVBox->base, pPixmap->drawable.width,
     293              pPixmap->drawable.height);
     294    if (   adjustedWidth != pPixmap->drawable.width
     295        || height != pPixmap->drawable.height)
     296    {
     297        if (   adjustedWidth > VBOX_VIDEO_MAX_VIRTUAL || height > VBOX_VIDEO_MAX_VIRTUAL
     298            || (unsigned)cbLine * (unsigned)height >= pVBox->cbFBMax)
     299        {
     300            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
     301                       "Virtual framebuffer %dx%d too large.  For information, video memory: %u Kb.\n",
     302                       adjustedWidth, height, (unsigned) pVBox->cbFBMax / 1024);
     303            return FALSE;
     304        }
     305        vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8,
     306                      adjustedWidth * height * pScrn->bitsPerPixel / 8);
     307        pScreen->ModifyPixmapHeader(pPixmap, adjustedWidth, height, pScrn->depth, pScrn->bitsPerPixel, cbLine, pVBox->base);
     308    }
     309    pScrn->displayWidth = pScrn->virtualX = adjustedWidth;
     310    pScrn->virtualY = height;
     311#ifdef VBOX_DRI_OLD
     312    if (pVBox->useDRI)
     313        VBOXDRIUpdateStride(pScrn, pVBox);
     314#endif
     315    return TRUE;
     316}
     317
     318/** Set a video mode to the hardware, RandR 1.1 version.  Since we no longer do
     319 * virtual frame buffers, adjust the screen pixmap dimensions to match. */
     320static void setModeRandR11(ScrnInfoPtr pScrn, DisplayModePtr pMode, bool fLimitedContext)
     321{
     322    VBOXPtr pVBox = VBOXGetRec(pScrn);
     323    struct vbvxFrameBuffer frameBuffer = { 0, 0, pMode->HDisplay, pMode->VDisplay, pScrn->bitsPerPixel};
     324
     325    pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay;
     326    pVBox->pScreens[0].aScreenLocation.cy = pMode->VDisplay;
     327    if (fLimitedContext)
     328    {
     329        pScrn->displayWidth = pScrn->virtualX = pMode->HDisplay;
     330        pScrn->virtualY = pMode->VDisplay;
     331    }
     332    else
     333        adjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay);
     334    if (pMode->HDisplay != 0 && pMode->VDisplay != 0)
     335        vbvxSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay, 0, 0, true, true, &frameBuffer);
     336    pScrn->currentMode = pMode;
     337}
     338
    264339#ifdef VBOXVIDEO_13
    265340/* X.org 1.3+ mode-setting support ******************************************/
     341
     342/** Set a video mode to the hardware, RandR 1.2 version.  If this is the first
     343 * screen, re-set the current mode for all others (the offset for the first
     344 * screen is always treated as zero by the hardware, so all other screens need
     345 * to be changed to compensate for any changes!).  The mode to set is taken
     346 * from the X.Org Crtc structure. */
     347static void setModeRandR12(ScrnInfoPtr pScrn, unsigned cScreen)
     348{
     349    VBOXPtr pVBox = VBOXGetRec(pScrn);
     350    unsigned i;
     351    struct vbvxFrameBuffer frameBuffer = { pVBox->pScreens[0].paCrtcs->x, pVBox->pScreens[0].paCrtcs->y, pScrn->virtualX,
     352                                           pScrn->virtualY, pScrn->bitsPerPixel };
     353    unsigned cFirst = cScreen;
     354    unsigned cLast = cScreen != 0 ? cScreen + 1 : pVBox->cScreens;
     355
     356    for (i = cFirst; i < cLast; ++i)
     357        if (pVBox->pScreens[i].paCrtcs->mode.HDisplay != 0 && pVBox->pScreens[i].paCrtcs->mode.VDisplay != 0)
     358            vbvxSetMode(pScrn, i, pVBox->pScreens[i].paCrtcs->mode.HDisplay, pVBox->pScreens[i].paCrtcs->mode.VDisplay,
     359                        pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y, pVBox->pScreens[i].fPowerOn,
     360                        pVBox->pScreens[i].paOutputs->status == XF86OutputStatusConnected, &frameBuffer);
     361}
     362
     363/** Wrapper around setModeRandR12() to avoid exposing non-obvious semantics.
     364 */
     365static void setAllModesRandR12(ScrnInfoPtr pScrn)
     366{
     367    setModeRandR12(pScrn, 0);
     368}
    266369
    267370/* For descriptions of these functions and structures, see
     
    272375{
    273376    VBOXPtr pVBox = VBOXGetRec(pScrn);
     377    Bool rc;
     378    unsigned i;
     379
    274380    TRACE_LOG("width=%d, height=%d\n", cw, ch);
    275     /* Save the size in case we need to re-set it later. */
    276     pVBox->FBSize.cx = cw;
    277     pVBox->FBSize.cy = ch;
    278381    /* Don't fiddle with the hardware if we are switched
    279382     * to a virtual terminal. */
     
    283386        return TRUE;
    284387    }
    285     return VBOXAdjustScreenPixmap(pScrn, cw, ch);
     388    rc = adjustScreenPixmap(pScrn, cw, ch);
     389    /* Power-on all screens (the server expects this) and set the new pitch to them. */
     390    for (i = 0; i < pVBox->cScreens; ++i)
     391        pVBox->pScreens[i].fPowerOn = true;
     392    setAllModesRandR12(pScrn);
     393    vbvxSetSolarisMouseRange(cw, ch);
     394    return rc;
    286395}
    287396
     
    293402vbox_crtc_dpms(xf86CrtcPtr crtc, int mode)
    294403{
    295     VBOXPtr pVBox = VBOXGetRec(crtc->scrn);
     404    ScrnInfoPtr pScrn = crtc->scrn;
     405    VBOXPtr pVBox = VBOXGetRec(pScrn);
    296406    unsigned cDisplay = (uintptr_t)crtc->driver_private;
    297     bool fEnabled = (mode != DPMSModeOff);
    298 
    299     TRACE_LOG("cDisplay=%u, mode=%i\n", cDisplay, mode);
    300     pVBox->pScreens[cDisplay].fCrtcEnabled = fEnabled;
    301     /* Don't fiddle with the hardware if we are switched
    302      * to a virtual terminal. */
    303     if (!crtc->scrn->vtSema) {
    304         xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
    305                    "We do not own the active VT, exiting.\n");
    306         return;
    307     }
    308     if (   pVBox->pScreens[cDisplay].aScreenLocation.cx
    309         && pVBox->pScreens[cDisplay].aScreenLocation.cy)
    310         VBOXSetMode(crtc->scrn, cDisplay,
    311                     pVBox->pScreens[cDisplay].aScreenLocation.cx,
    312                     pVBox->pScreens[cDisplay].aScreenLocation.cy,
    313                     pVBox->pScreens[cDisplay].aScreenLocation.x,
    314                     pVBox->pScreens[cDisplay].aScreenLocation.y);
     407
     408    TRACE_LOG("mode=%d\n", mode);
     409    pVBox->pScreens[cDisplay].fPowerOn = (mode != DPMSModeOff);
     410    setModeRandR12(pScrn, cDisplay);
    315411}
    316412
     
    345441    TRACE_LOG("name=%s, HDisplay=%d, VDisplay=%d, x=%d, y=%d\n", adjusted_mode->name,
    346442           adjusted_mode->HDisplay, adjusted_mode->VDisplay, x, y);
    347     pVBox->pScreens[cDisplay].fCrtcEnabled = true;
    348     pVBox->pScreens[cDisplay].fOutputEnabled = true;
     443    pVBox->pScreens[cDisplay].fPowerOn = true;
    349444    pVBox->pScreens[cDisplay].aScreenLocation.cx = adjusted_mode->HDisplay;
    350445    pVBox->pScreens[cDisplay].aScreenLocation.cy = adjusted_mode->VDisplay;
     
    359454        return;
    360455    }
    361     VBOXSetMode(crtc->scrn, cDisplay, adjusted_mode->HDisplay,
    362                 adjusted_mode->VDisplay, x, y);
     456    setModeRandR12(crtc->scrn, cDisplay);
    363457}
    364458
     
    402496vbox_output_dpms (xf86OutputPtr output, int mode)
    403497{
    404     VBOXPtr pVBox = VBOXGetRec(output->scrn);
    405     unsigned cDisplay = (uintptr_t)output->driver_private;
    406     bool fEnabled = (mode == DPMSModeOn);
    407 
    408     TRACE_LOG("cDisplay=%u, mode=%i\n", cDisplay, mode);
    409     pVBox->pScreens[cDisplay].fOutputEnabled = fEnabled;
    410     /* Don't fiddle with the hardware if we are switched
    411      * to a virtual terminal. */
    412     if (!output->scrn->vtSema) {
    413         xf86DrvMsg(output->scrn->scrnIndex, X_ERROR,
    414                    "We do not own the active VT, exiting.\n");
    415         return;
    416     }
    417     if (   pVBox->pScreens[cDisplay].aScreenLocation.cx
    418         && pVBox->pScreens[cDisplay].aScreenLocation.cy)
    419         VBOXSetMode(output->scrn, cDisplay,
    420                     pVBox->pScreens[cDisplay].aScreenLocation.cx,
    421                     pVBox->pScreens[cDisplay].aScreenLocation.cy,
    422                     pVBox->pScreens[cDisplay].aScreenLocation.x,
    423                     pVBox->pScreens[cDisplay].aScreenLocation.y);
     498    (void)output; (void)mode;
    424499}
    425500
     
    498573    uint32_t x, y, iScreen;
    499574    iScreen = (uintptr_t)output->driver_private;
    500     VBoxUpdateSizeHints(pScrn);
    501     pMode = vbox_output_add_mode(pVBox, &pModes, NULL, pVBox->pScreens[iScreen].aPreferredSize.cx,
    502                                  pVBox->pScreens[iScreen].aPreferredSize.cy, TRUE, FALSE);
     575    pMode = vbox_output_add_mode(pVBox, &pModes, NULL,
     576                                 RT_CLAMP(pVBox->pScreens[iScreen].aPreferredSize.cx, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL),
     577                                 RT_CLAMP(pVBox->pScreens[iScreen].aPreferredSize.cy, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL),
     578                                 TRUE, FALSE);
     579    // VBOXEDIDSet(output, pMode);
    503580    TRACE_EXIT();
    504581    return pModes;
     
    600677
    601678#ifndef XF86_SCRN_INTERFACE
    602 # define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum]
    603 # define xf86ScrnToScreen(pScrn) screenInfo.screens[(pScrn)->scrnIndex]
    604679# define SCRNINDEXAPI(pfn) pfn ## Index
    605680static Bool VBOXScreenInitIndex(int scrnIndex, ScreenPtr pScreen, int argc,
     
    872947
    873948    /* Set the right virtual resolution. */
    874     pScrn->virtualX = pScrn->currentMode->HDisplay;
     949    pScrn->virtualX = pScrn->bitsPerPixel == 16 ? (pScrn->currentMode->HDisplay + 1) & ~1 : pScrn->currentMode->HDisplay;
    875950    pScrn->virtualY = pScrn->currentMode->VDisplay;
    876951
     
    878953
    879954    /* Needed before we initialise DRI. */
    880     pVBox->cbLine = vboxLineLength(pScrn, pScrn->virtualX);
    881     pScrn->displayWidth = vboxDisplayPitch(pScrn, pVBox->cbLine);
     955    pScrn->displayWidth = pScrn->virtualX;
    882956
    883957    xf86PrintModes(pScrn);
     
    9751049#endif /* SET_HAVE_VT_PROPERTY */
    9761050
     1051#ifdef VBOXVIDEO_13
     1052
     1053static void setVirtualSizeRandR12(ScrnInfoPtr pScrn, bool fLimitedContext)
     1054{
     1055    VBOXPtr pVBox = VBOXGetRec(pScrn);
     1056    unsigned i;
     1057    unsigned cx = 0;
     1058    unsigned cy = 0;
     1059
     1060    for (i = 0; i < pVBox->cScreens; ++i)
     1061    {
     1062        if (   pVBox->fHaveHGSMIModeHints && pVBox->pScreens[i].afHaveLocation)
     1063        {
     1064            pVBox->pScreens[i].paCrtcs->x = pVBox->pScreens[i].aPreferredLocation.x;
     1065            pVBox->pScreens[i].paCrtcs->y = pVBox->pScreens[i].aPreferredLocation.y;
     1066        }
     1067        if (   pVBox->pScreens[i].paOutputs->status == XF86OutputStatusConnected
     1068            && pVBox->pScreens[i].paCrtcs->x + pVBox->pScreens[i].aPreferredSize.cx < VBOX_VIDEO_MAX_VIRTUAL
     1069            && pVBox->pScreens[i].paCrtcs->y + pVBox->pScreens[i].aPreferredSize.cy < VBOX_VIDEO_MAX_VIRTUAL)
     1070        {
     1071            cx = max(cx, pVBox->pScreens[i].paCrtcs->x + pVBox->pScreens[i].aPreferredSize.cx);
     1072            cy = max(cy, pVBox->pScreens[i].paCrtcs->y + pVBox->pScreens[i].aPreferredSize.cy);
     1073        }
     1074    }
     1075    if (cx != 0 && cy != 0)
     1076    {
     1077        if (fLimitedContext)
     1078        {
     1079            pScrn->virtualX = cx;
     1080            pScrn->virtualY = cy;
     1081        }
     1082        else
     1083        {
     1084            TRACE_LOG("cx=%u, cy=%u\n", cx, cy);
     1085            xf86ScrnToScreen(pScrn)->width = cx;
     1086            xf86ScrnToScreen(pScrn)->height = cy;
     1087#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 14
     1088            xf86UpdateDesktopDimensions();
     1089#elif GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 12
     1090            screenInfo.width = cx;
     1091            screenInfo.height = cy;
     1092#endif
     1093            adjustScreenPixmap(pScrn, cx, cy);
     1094        }
     1095    }
     1096}
     1097
     1098static void setScreenSizesRandR12(ScrnInfoPtr pScrn, bool fLimitedContext)
     1099{
     1100    VBOXPtr pVBox = VBOXGetRec(pScrn);
     1101    unsigned i;
     1102
     1103    for (i = 0; i < pVBox->cScreens; ++i)
     1104    {
     1105        if (!pVBox->pScreens[i].afConnected)
     1106            continue;
     1107        /* The Crtc can get "unset" if the screen was disconnected previously.
     1108         * I couldn't find an API to re-set it which did not have side-effects.
     1109         */
     1110        pVBox->pScreens[i].paOutputs->crtc = pVBox->pScreens[i].paCrtcs;
     1111        xf86CrtcSetMode(pVBox->pScreens[i].paCrtcs, pVBox->pScreens[i].paOutputs->probed_modes, RR_Rotate_0,
     1112                        pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y);
     1113        if (!fLimitedContext)
     1114            RRCrtcNotify(pVBox->pScreens[i].paCrtcs->randr_crtc, pVBox->pScreens[i].paOutputs->randr_output->modes[0],
     1115                         pVBox->pScreens[i].paCrtcs->x, pVBox->pScreens[i].paCrtcs->y, RR_Rotate_0,
     1116#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
     1117                         NULL,
     1118#endif
     1119                         1, &pVBox->pScreens[i].paOutputs->randr_output);
     1120    }
     1121}
     1122
     1123static void setSizesRandR12(ScrnInfoPtr pScrn, bool fLimitedContext)
     1124{
     1125    VBOXPtr pVBox = VBOXGetRec(pScrn);
     1126
     1127# if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
     1128    RRGetInfo(xf86ScrnToScreen(pScrn), TRUE);
     1129# else
     1130    RRGetInfo(xf86ScrnToScreen(pScrn));
     1131# endif
     1132    setVirtualSizeRandR12(pScrn, fLimitedContext);
     1133    setScreenSizesRandR12(pScrn, fLimitedContext);
     1134    if (!fLimitedContext)
     1135    {
     1136        RRScreenSizeNotify(xf86ScrnToScreen(pScrn));
     1137        RRTellChanged(xf86ScrnToScreen(pScrn));
     1138    }
     1139}
     1140
     1141#else
     1142
     1143static void setSizesRandR11(ScrnInfoPtr pScrn, bool fLimitedContext)
     1144{
     1145    VBOXPtr pVBox = VBOXGetRec(pScrn);
     1146    DisplayModePtr pNewMode;
     1147
     1148    pNewMode = pScrn->modes != pScrn->currentMode ? pScrn->modes : pScrn->modes->next;
     1149    pNewMode->HDisplay = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cx, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL);
     1150    pNewMode->VDisplay = RT_CLAMP(pVBox->pScreens[0].aPreferredSize.cy, VBOX_VIDEO_MIN_SIZE, VBOX_VIDEO_MAX_VIRTUAL);
     1151    setModeRandR11(pScrn, pNewMode, fLimitedContext);
     1152}
     1153
     1154#endif
     1155
     1156static void setSizesAndCursorIntegration(ScrnInfoPtr pScrn, bool fScreenInitTime)
     1157{
     1158    VBOXPtr pVBox = VBOXGetRec(pScrn);
     1159   
     1160    TRACE_LOG("fScreenInitTime=%d\n", (int)fScreenInitTime);
     1161#ifdef VBOXVIDEO_13
     1162    setSizesRandR12(pScrn, fScreenInitTime);
     1163#else
     1164    setSizesRandR11(pScrn, fScreenInitTime);
     1165#endif
     1166    if (pScrn->vtSema)
     1167        vbvxReprobeCursor(pScrn);
     1168}
     1169
     1170/* We update the size hints from the X11 property set by VBoxClient every time
     1171 * that the X server goes to sleep (to catch the property change request).
     1172 * Although this is far more often than necessary it should not have real-life
     1173 * performance consequences and allows us to simplify the code quite a bit. */
     1174static void updateSizeHintsBlockHandler(pointer pData, OSTimePtr pTimeout, pointer pReadmask)
     1175{
     1176    ScrnInfoPtr pScrn = (ScrnInfoPtr)pData;
     1177    VBOXPtr pVBox = VBOXGetRec(pScrn);
     1178    bool fNeedUpdate = false;
     1179
     1180    (void)pTimeout;
     1181    (void)pReadmask;
     1182    if (!pScrn->vtSema)
     1183        return;
     1184    vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, &fNeedUpdate);
     1185    if (ROOT_WINDOW(pScrn) != NULL)
     1186        vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, &fNeedUpdate);
     1187    if (fNeedUpdate)
     1188        setSizesAndCursorIntegration(pScrn, false);
     1189}
     1190
    9771191/*
    9781192 * QUOTE from the XFree86 DESIGN document:
     
    10481262
    10491263#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
    1050     VBoxSetUpLinuxACPI(pScreen);
    1051 #endif
    1052 
    1053     vbox_open (pScrn, pScreen, pVBox);
     1264    vbvxSetUpLinuxACPI(pScreen);
     1265#endif
     1266
     1267    if (!VBoxHGSMIIsSupported())
     1268    {
     1269        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Graphics device too old to support.\n");
     1270        return FALSE;
     1271    }
     1272    vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024);
     1273    pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
     1274    pVBox->pScreens = xnfcalloc(pVBox->cScreens, sizeof(*pVBox->pScreens));
     1275    pVBox->paVBVAModeHints = xnfcalloc(pVBox->cScreens, sizeof(*pVBox->paVBVAModeHints));
     1276    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n", pVBox->cScreens);
    10541277    vboxEnableVbva(pScrn);
     1278    /* Set up the dirty rectangle handler.  It will be added into a function
     1279     * chain and gets removed when the screen is cleaned up. */
     1280    if (ShadowFBInit2(pScreen, NULL, vbvxHandleDirtyRect) != TRUE)
     1281        return FALSE;
    10551282    VBoxInitialiseSizeHints(pScrn);
     1283    /* Get any screen size hints from HGSMI.  Do not yet try to access X11
     1284     * properties, as they are not yet set up, and nor are the clients that
     1285     * might have set them. */
     1286    vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL);
    10561287
    10571288#ifdef VBOXVIDEO_13
     
    10971328    }
    10981329
    1099     /* Initialise randr 1.2 mode-setting functions and set first mode.
    1100      * Note that the mode won't be usable until the server has resized the
    1101      * framebuffer to something reasonable. */
     1330    /* Initialise randr 1.2 mode-setting functions. */
    11021331    if (!xf86CrtcScreenInit(pScreen)) {
    11031332        return FALSE;
    11041333    }
    11051334
    1106     if (!xf86SetDesiredModes(pScrn)) {
    1107         return FALSE;
    1108     }
    1109 #else /* !VBOXVIDEO_13 */
    1110     VBoxSetUpRandR11(pScreen);
     1335#endif
    11111336    /* set first video mode */
    1112     if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay,
    1113                      pScrn->currentMode->VDisplay, pScrn->frameX0,
    1114                      pScrn->frameY0))
    1115         return FALSE;
    1116     /* Save the size in case we need to re-set it later. */
    1117     pVBox->FBSize.cx = pScrn->currentMode->HDisplay;
    1118     pVBox->FBSize.cy = pScrn->currentMode->VDisplay;
    1119     pVBox->pScreens[0].aScreenLocation.cx = pScrn->currentMode->HDisplay;
    1120     pVBox->pScreens[0].aScreenLocation.cy = pScrn->currentMode->VDisplay;
    1121     pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0;
    1122     pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0;
    1123 #endif /* !VBOXVIDEO_13 */
     1337    setSizesAndCursorIntegration(pScrn, true);
     1338
     1339    /* Register block and wake-up handlers for getting new screen size hints. */
     1340    RegisterBlockAndWakeupHandlers(updateSizeHintsBlockHandler, (WakeupHandlerProcPtr)NoopDDA, (pointer)pScrn);
    11241341
    11251342    /* software cursor */
     
    11821399    }
    11831400#endif
     1401    vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024);
    11841402    vboxEnableVbva(pScrn);
    1185     /* Re-assert this in case we had a change request while switched out. */
    1186     if (pVBox->FBSize.cx && pVBox->FBSize.cy)
    1187         VBOXAdjustScreenPixmap(pScrn, pVBox->FBSize.cx, pVBox->FBSize.cy);
    1188 #ifdef VBOXVIDEO_13
    1189     if (!xf86SetDesiredModes(pScrn))
    1190         return FALSE;
    1191 #else
    1192     if (!VBOXSetMode(pScrn, 0, pScrn->currentMode->HDisplay,
    1193                      pScrn->currentMode->VDisplay, pScrn->frameX0,
    1194                      pScrn->frameY0))
    1195         return FALSE;
    1196 #endif
     1403    /* Re-set video mode */
     1404    vbvxReadSizesAndCursorIntegrationFromHGSMI(pScrn, NULL);
     1405    vbvxReadSizesAndCursorIntegrationFromProperties(pScrn, NULL);
     1406    /* This prevents a crash in CentOS 3.  I was unable to debug it to
     1407     * satisfaction, partly due to the lack of symbols.  My guess is that
     1408     * pScrn->ModifyPixmapHeader() expects certain things to be set up when
     1409     * it sees pScrn->vtSema set to true which are not quite done at this
     1410     * point of the VT switch. */
     1411    pScrn->vtSema = FALSE;
     1412    setSizesAndCursorIntegration(pScrn, false);
     1413    pScrn->vtSema = TRUE;
    11971414#ifdef SET_HAVE_VT_PROPERTY
    11981415    updateHasVTProperty(pScrn, TRUE);
     
    12111428#ifdef VBOXVIDEO_13
    12121429    for (i = 0; i < pVBox->cScreens; ++i)
    1213         vbox_output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff);
     1430        vbox_crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff);
    12141431#endif
    12151432    vboxDisableVbva(pScrn);
    1216     vboxClearVRAM(pScrn, 0, 0);
     1433    vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0);
    12171434#ifdef VBOX_DRI_OLD
    12181435    if (pVBox->useDRI)
     
    12421459
    12431460        for (i = 0; i < pVBox->cScreens; ++i)
    1244             vbox_output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff);
     1461            vbox_crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff);
    12451462#endif
    12461463        vboxDisableVbva(pScrn);
    1247         vboxClearVRAM(pScrn, 0, 0);
     1464        vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0);
    12481465    }
    12491466#ifdef VBOX_DRI
     
    12721489    pScreen->CloseScreen = pVBox->CloseScreen;
    12731490#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
    1274     VBoxCleanUpLinuxACPI(pScreen);
     1491    vbvxCleanUpLinuxACPI(pScreen);
    12751492#endif
    12761493#ifndef XF86_SCRN_INTERFACE
     
    12841501{
    12851502    VBOXPtr pVBox;
    1286     Bool rc;
     1503    Bool rc = TRUE;
    12871504
    12881505    TRACE_LOG("HDisplay=%d, VDisplay=%d\n", pMode->HDisplay, pMode->VDisplay);
    1289 #ifndef VBOXVIDEO_13
    1290     pVBox = VBOXGetRec(pScrn);
    1291     /* Save the size in case we need to re-set it later. */
    1292     pVBox->FBSize.cx = pMode->HDisplay;
    1293     pVBox->FBSize.cy = pMode->VDisplay;
    1294     pVBox->pScreens[0].aScreenLocation.cx = pMode->HDisplay;
    1295     pVBox->pScreens[0].aScreenLocation.cy = pMode->VDisplay;
    1296     pVBox->pScreens[0].aScreenLocation.x = pScrn->frameX0;
    1297     pVBox->pScreens[0].aScreenLocation.y = pScrn->frameY0;
    1298 #endif
    12991506    if (!pScrn->vtSema)
    13001507    {
     
    13061513    rc = xf86SetSingleMode(pScrn, pMode, RR_Rotate_0);
    13071514#else
    1308     VBOXAdjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay);
    1309     rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay,
    1310                      pScrn->frameX0, pScrn->frameY0);
     1515    setModeRandR11(pScrn, pMode, false);
    13111516#endif
    13121517    TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
     
    13151520
    13161521static void VBOXAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
    1317 {
    1318     VBOXPtr pVBox = VBOXGetRec(pScrn);
    1319 
    1320     TRACE_ENTRY();
    1321     pVBox->pScreens[0].aScreenLocation.x = x;
    1322     pVBox->pScreens[0].aScreenLocation.y = y;
    1323     /* Don't fiddle with the hardware if we are switched
    1324      * to a virtual terminal. */
    1325     if (!pScrn->vtSema)
    1326     {
    1327         xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
    1328                    "We do not own the active VT, exiting.\n");
    1329         return;
    1330     }
    1331     VBOXSetMode(pScrn, 0, pVBox->pScreens[0].aScreenLocation.cx,
    1332                 pVBox->pScreens[0].aScreenLocation.cy, x, y);
    1333     TRACE_EXIT();
    1334 }
     1522{ (void)pScrn; (void)x; (void)y; }
    13351523
    13361524static void VBOXFreeScreen(ScrnInfoPtr pScrn)
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h

    r55241 r55250  
    5555#include <VBox/VBoxVideoGuest.h>
    5656#include <VBox/VBoxVideo.h>
     57
     58#ifndef VBVA_SCREEN_F_BLANK
     59# define VBVA_SCREEN_F_BLANK    0x0004
     60#endif
    5761
    5862#ifdef DEBUG
     
    151155    RTRECT2 aScreenLocation;
    152156    /** Is this CRTC enabled or in DPMS off state? */
    153     Bool fCrtcEnabled;
    154     /** Is this output enabled or in DPMS low power state? */
    155     Bool fOutputEnabled;
     157    Bool fPowerOn;
    156158#ifdef VBOXVIDEO_13
    157159    /** The virtual crtcs. */
     
    170172    /** Has this screen been enabled by the host? */
    171173    Bool afConnected;
    172     /** The last mode hint data read from the X11 property. */
    173     int32_t lastModeHintFromProperty;
    174174    /** Does this screen have a preferred location? */
    175175    Bool afHaveLocation;
     
    190190    /** The size of the framebuffer and the VBVA buffers at the end of it. */
    191191    unsigned long cbView;
    192     /** The current line size in bytes */
    193     uint32_t cbLine;
    194192    /** Whether the pre-X-server mode was a VBE mode */
    195193    bool fSavedVBEMode;
     
    205203    /** Do we currently want to use the host cursor? */
    206204    Bool fUseHardwareCursor;
    207     /** The last cursor capabilities data read from the X11 property. */
    208     int32_t fLastCursorCapabilitiesFromProperty;
    209205    /** Number of screens attached */
    210206    uint32_t cScreens;
    211207    /** Information about each virtual screen. */
    212208    struct VBoxScreen *pScreens;
    213     /** The last requested framebuffer size. */
    214     RTRECTSIZE FBSize;
    215209    /** Can we get mode hint and cursor integration information from HGSMI? */
    216210    bool fHaveHGSMIModeHints;
     
    226220    void *hACPIEventHandler;
    227221# endif
    228     /** Have we read all available HGSMI mode hint data? */
    229     bool fHaveReadHGSMIModeHintData;
    230 #else
    231     /** The original CreateScreenResources procedure which we wrap with our own.
    232      */
    233     CreateScreenResourcesProcPtr pfnCreateScreenResources;
    234222#endif
    235223    /** HGSMI guest heap context */
     
    275263};
    276264
     265extern void vbvxClearVRAM(ScrnInfoPtr pScrn, size_t cbOldSize, size_t cbNewSize);
    277266extern void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled,
    278                          bool fConnected, struct vbvxFrameBuffer *pFrameBuffer);
    279 extern void vbvxClearVRAM(ScrnInfoPtr pScrn, size_t cbOldSize, size_t cbNewSize);
     267                        bool fConnected, struct vbvxFrameBuffer *pFrameBuffer);
    280268extern void vbvxSetSolarisMouseRange(int width, int height);
    281269
     270/* pointer.c */
    282271extern Bool vbox_cursor_init (ScreenPtr pScreen);
    283 extern void vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox);
    284272extern void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBox);
    285273
     274/* vbva.c */
     275extern void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects);
     276extern void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM);
    286277extern Bool vboxEnableVbva(ScrnInfoPtr pScrn);
    287278extern void vboxDisableVbva(ScrnInfoPtr pScrn);
     
    290281extern void vboxAddModes(ScrnInfoPtr pScrn);
    291282extern void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn);
    292 extern void VBoxUpdateSizeHints(ScrnInfoPtr pScrn);
    293 #ifndef VBOXVIDEO_13
    294 extern void VBoxSetUpRandR11(ScreenPtr pScreen);
    295 #else
    296 void VBoxSetUpLinuxACPI(ScreenPtr pScreen);
    297 void VBoxCleanUpLinuxACPI(ScreenPtr pScreen);
    298 #endif
     283extern void vbvxReadSizesAndCursorIntegrationFromProperties(ScrnInfoPtr pScrn, bool *pfNeedUpdate);
     284extern void vbvxReadSizesAndCursorIntegrationFromHGSMI(ScrnInfoPtr pScrn, bool *pfNeedUpdate);
     285extern void vbvxSetUpLinuxACPI(ScreenPtr pScreen);
     286extern void vbvxCleanUpLinuxACPI(ScreenPtr pScreen);
    299287
    300288/* DRI stuff */
     
    305293extern void VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox);
    306294
    307 /* Utilities */
    308 
    309 /** Calculate the BPP from the screen depth */
    310 static inline uint16_t vboxBPP(ScrnInfoPtr pScrn)
    311 {
    312     return pScrn->depth == 24 ? 32 : 16;
    313 }
    314 
    315 /** Calculate the scan line length for a display width */
    316 static inline int32_t vboxLineLength(ScrnInfoPtr pScrn, int32_t cDisplayWidth)
    317 {
    318     uint32_t cbLine = (cDisplayWidth * vboxBPP(pScrn) / 8 + 3) & ~3;
    319     return cbLine < INT32_MAX ? cbLine : INT32_MAX;
    320 }
    321 
    322 /** Calculate the display pitch from the scan line length */
    323 static inline int32_t vboxDisplayPitch(ScrnInfoPtr pScrn, int32_t cbLine)
    324 {
    325     return cbLine * 8 / vboxBPP(pScrn);
    326 }
    327 
    328 extern void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY);
    329 extern Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
    330                         unsigned cHeight, int x, int y);
    331 extern Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height);
    332 
    333295#endif /* _VBOXVIDEO_H_ */
    334296
  • trunk/src/VBox/Additions/x11/vboxvideo/vbva.c

    r55191 r55250  
    1818#include <VBox/VBoxGuestLib.h>
    1919
    20 #ifndef PCIACCESS
    21 # include <xf86Pci.h>
    22 # include <Pci.h>
    23 #endif
    24 
    25 #include "xf86.h"
    26 #define NEED_XF86_TYPES
    2720#include <iprt/string.h>
    2821#include "compiler.h"
    29 
    30 /* ShadowFB support */
    31 #include "shadowfb.h"
    3222
    3323#include "vboxvideo.h"
     
    5141 *                rectangles
    5242 */
    53 static void
    54 vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
     43void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
    5544{
    5645    VBVACMDHDR cmdHdr;
     
    7968                || aRects[i].y2 <   pVBox->pScreens[j].aScreenLocation.y)
    8069                continue;
    81             cmdHdr.x = (int16_t)aRects[i].x1;
    82             cmdHdr.y = (int16_t)aRects[i].y1;
     70            cmdHdr.x = (int16_t)aRects[i].x1 - pVBox->pScreens[0].aScreenLocation.x;
     71            cmdHdr.y = (int16_t)aRects[i].y1 - pVBox->pScreens[0].aScreenLocation.y;
    8372            cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
    8473            cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
     
    10089}
    10190
     91static DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb)
     92{
     93    NOREF(pvEnv);
     94    return calloc(1, cb);
     95}
     96
     97static DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv)
     98{
     99    NOREF(pvEnv);
     100    free(pv);
     101}
     102
     103static HGSMIENV g_hgsmiEnv =
     104{
     105    NULL,
     106    hgsmiEnvAlloc,
     107    hgsmiEnvFree
     108};
     109
     110/**
     111 * Calculate the location in video RAM of and initialise the heap for guest to
     112 * host messages.  In the VirtualBox 4.3 and earlier Guest Additions this
     113 * function creates the heap structures directly in guest video RAM, so it
     114 * needs to be called whenever video RAM is (re-)set-up.
     115 */
     116void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM)
     117{
     118    int rc;
     119    uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
     120    void *pvGuestHeapMemory;
     121
     122    VBoxHGSMIGetBaseMappingInfo(cbVRAM, &offVRAMBaseMapping, NULL, &offGuestHeapMemory, &cbGuestHeapMemory, NULL);
     123    pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping + offGuestHeapMemory;
     124    rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory, cbGuestHeapMemory,
     125                                    offVRAMBaseMapping + offGuestHeapMemory, &g_hgsmiEnv);
     126    VBVXASSERT(RT_SUCCESS(rc), ("Failed to set up the guest-to-host message buffer heap, rc=%d\n", rc));
     127    pVBox->cbView = offVRAMBaseMapping;
     128}
     129
    102130/** Callback to fill in the view structures */
    103131static int
     
    121149 * @returns TRUE on success, FALSE on failure
    122150 */
    123 static Bool
    124 vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
    125 {
    126     ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     151static Bool vboxSetupVRAMVbva(VBOXPtr pVBox)
     152{
    127153    int rc = VINF_SUCCESS;
    128 
    129     /* Why is this here?  In case things break before we have found the real
    130      * count? */
    131     pVBox->cScreens = 1;
    132     if (!VBoxHGSMIIsSupported())
    133     {
    134         xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI.  Disableing video acceleration.\n");
    135         return FALSE;
    136     }
    137 
    138     /* Set up the dirty rectangle handler.  It will be added into a function
    139      * chain and gets removed when the screen is cleaned up. */
    140     if (ShadowFBInit2(pScreen, NULL, vboxHandleDirtyRect) != TRUE)
    141     {
    142         xf86DrvMsg(scrnIndex, X_ERROR,
    143                    "Unable to install dirty rectangle handler for VirtualBox graphics acceleration.\n");
    144         return FALSE;
    145     }
    146     return TRUE;
    147 }
    148 
    149 static DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb)
    150 {
    151     NOREF(pvEnv);
    152     return calloc(1, cb);
    153 }
    154 
    155 static DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv)
    156 {
    157     NOREF(pvEnv);
    158     free(pv);
    159 }
    160 
    161 static HGSMIENV g_hgsmiEnv =
    162 {
    163     NULL,
    164     hgsmiEnvAlloc,
    165     hgsmiEnvFree
    166 };
    167 
    168 /**
    169  * Initialise VirtualBox's accelerated video extensions.
    170  *
    171  * @returns TRUE on success, FALSE on failure
    172  */
    173 static Bool
    174 vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)
    175 {
    176     int rc = VINF_SUCCESS;
    177     unsigned i;
    178     uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
    179     void *pvGuestHeapMemory;
    180 
    181     VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,
    182                                 NULL, &offGuestHeapMemory, &cbGuestHeapMemory,
    183                                 NULL);
    184     pvGuestHeapMemory =   ((uint8_t *)pVBox->base) + offVRAMBaseMapping
    185                         + offGuestHeapMemory;
    186     TRACE_LOG("video RAM: %u KB, guest heap offset: 0x%x, cbGuestHeapMemory: %u\n",
    187               pScrn->videoRam, offVRAMBaseMapping + offGuestHeapMemory,
    188               cbGuestHeapMemory);
    189     rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory,
    190                                     cbGuestHeapMemory,
    191                                     offVRAMBaseMapping + offGuestHeapMemory,
    192                                     &g_hgsmiEnv);
    193     if (RT_FAILURE(rc))
    194     {
    195         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc);
    196         return FALSE;
    197     }
    198     pVBox->cbView = pVBox->cbFBMax = offVRAMBaseMapping;
    199     pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
    200     pVBox->pScreens = calloc(pVBox->cScreens, sizeof(*pVBox->pScreens));
    201     if (pVBox->pScreens == NULL)
    202         FatalError("Failed to allocate memory for screens array.\n");
    203 #ifdef VBOXVIDEO_13
    204     pVBox->paVBVAModeHints = calloc(pVBox->cScreens,
    205                                     sizeof(*pVBox->paVBVAModeHints));
    206     if (pVBox->paVBVAModeHints == NULL)
    207         FatalError("Failed to allocate memory for mode hints array.\n");
    208 #endif
    209     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n",
    210                pVBox->cScreens);
     154    unsigned i;
     155
     156    pVBox->cbFBMax = pVBox->cbView;
    211157    for (i = 0; i < pVBox->cScreens; ++i)
    212158    {
     
    224170    rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
    225171                               vboxFillViewInfo, (void *)pVBox);
    226     if (RT_FAILURE(rc))
    227     {
    228         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to send the view information to the host, rc=%d\n", rc);
    229         return FALSE;
    230     }
     172    VBVXASSERT(RT_SUCCESS(rc), ("Failed to send the view information to the host, rc=%d\n", rc));
    231173    return TRUE;
    232174}
    233175
    234 void
    235 vbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
    236 {
    237     TRACE_ENTRY();
    238 
    239     if (!vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox))
    240         FatalError("failed to initialise vboxvideo graphics acceleration.\n");
     176static bool haveHGSMIModeHintAndCursorReportingInterface(VBOXPtr pVBox)
     177{
     178    uint32_t fModeHintReporting, fCursorReporting;
     179
     180    return    RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_MODE_HINT_REPORTING, &fModeHintReporting))
     181           && RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_GUEST_CURSOR_REPORTING, &fCursorReporting))
     182           && fModeHintReporting == VINF_SUCCESS
     183           && fCursorReporting == VINF_SUCCESS;
     184}
     185
     186static bool hostHasScreenBlankingFlag(VBOXPtr pVBox)
     187{
     188    uint32_t fScreenFlags;
     189
     190    return    RT_SUCCESS(VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_SCREEN_FLAGS, &fScreenFlags))
     191           && fScreenFlags & VBVA_SCREEN_F_BLANK;
    241192}
    242193
     
    252203{
    253204    bool rc = TRUE;
    254     int scrnIndex = pScrn->scrnIndex;
    255205    unsigned i;
    256206    VBOXPtr pVBox = pScrn->driverPrivate;
    257207
    258208    TRACE_ENTRY();
    259     if (!vboxSetupVRAMVbva(pScrn, pVBox))
     209    if (!vboxSetupVRAMVbva(pVBox))
    260210        return FALSE;
    261211    for (i = 0; i < pVBox->cScreens; ++i)
     
    269219            rc = FALSE;
    270220    }
    271     if (!rc)
    272     {
    273         /* Request not accepted - disable for old hosts. */
    274         xf86DrvMsg(scrnIndex, X_ERROR,
    275                    "Failed to enable screen update reporting for at least one virtual monitor.\n");
    276          vboxDisableVbva(pScrn);
    277     }
     221    VBVXASSERT(rc, ("Failed to enable screen update reporting for at least one virtual monitor.\n"));
    278222#ifdef VBOXVIDEO_13
    279 # ifdef RT_OS_LINUX
    280     if (rc && pVBox->hACPIEventHandler != NULL)
    281         /* We ignore the return value as the fall-back should be active
    282          * anyway. */
    283         VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION);
    284 # endif
     223    VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION);
     224    pVBox->fHaveHGSMIModeHints = haveHGSMIModeHintAndCursorReportingInterface(pVBox);
     225    pVBox->fHostHasScreenBlankingFlag = hostHasScreenBlankingFlag(pVBox);
    285226#endif
    286227    return rc;
     
    299240{
    300241    int rc;
    301     int scrnIndex = pScrn->scrnIndex;
    302242    unsigned i;
    303243    VBOXPtr pVBox = pScrn->driverPrivate;
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