VirtualBox

Ignore:
Timestamp:
Apr 15, 2015 5:34:05 AM (10 years ago)
Author:
vboxsync
Message:

Additions/x11/vboxvideo: reverted temporary commit r99563.

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

Legend:

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

    r55250 r55262  
    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 (VBoxManage in 4.3).
     9 * Disabling and enabling virtual screens (only possible as of 4.4).
    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 (seamless currently only works properly with VBoxClient
    13    running).
     12   seamless modes.
    1413 * Test switching directly between normal, full-screen, seamless and scaled
    1514   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 (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.
     18   later.
    2419 * Shutting down and re-starting a virtual machine should restore the last size
    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.
     20   for all monitors (note: currently only after log-in).
  • trunk/src/VBox/Additions/x11/vboxvideo/getmode.c

    r55250 r55262  
    3838#ifdef VBOXVIDEO_13
    3939# ifdef RT_OS_LINUX
     40# include "randrstr.h"
     41# include "xf86_OSproc.h"
    4042#  include <linux/input.h>
    4143#  ifndef EVIOCGRAB
     
    5153# endif /* RT_OS_LINUX */
    5254#endif /* VBOXVIDEO_13 */
    53 
    5455/**************************************************************************
    5556* Main functions                                                          *
     
    154155}
    155156
    156 /** Set the initial values for the guest screen size hints to standard values
    157  * in case nothing else is available. */
     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. */
    158160void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn)
    159161{
     
    171173    pScrn->modes->HDisplay = pVBox->pScreens[0].aPreferredSize.cx;
    172174    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
     183static 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. */
     200void 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);
    173266}
    174267
     
    304397#undef COMPARE_AND_MAYBE_SET
    305398
     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. */
     403static int (*g_pfnVBoxRandRProc)(ClientPtr) = NULL;
     404/** The swapped RandR "proc" vector. */
     405static int (*g_pfnVBoxRandRSwappedProc)(ClientPtr) = NULL;
     406
     407/* TESTING: dynamic resizing and toggling cursor integration work with older guest X servers (1.2 and older). */
     408static 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
     433static 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
     442static 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
     451static 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 */
     506void 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
    306518#ifdef VBOXVIDEO_13
    307519# ifdef RT_OS_LINUX
    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. */
     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. */
    312522static void acpiEventHandler(int fd, void *pvData)
    313523{
     
    317527    ssize_t rc;
    318528
     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"));
    319536    do
    320537        rc = read(fd, &event, sizeof(event));
     
    324541}
    325542
    326 void vbvxSetUpLinuxACPI(ScreenPtr pScreen)
     543void VBoxSetUpLinuxACPI(ScreenPtr pScreen)
    327544{
    328545    VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
     
    374591}
    375592
    376 void vbvxCleanUpLinuxACPI(ScreenPtr pScreen)
     593void VBoxCleanUpLinuxACPI(ScreenPtr pScreen)
    377594{
    378595    VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
     
    385602# endif /* RT_OS_LINUX */
    386603#endif /* VBOXVIDEO_13 */
    387 
  • trunk/src/VBox/Additions/x11/vboxvideo/helpers.c

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

    r55250 r55262  
    8989        cbNewSize = pVBox->cbFBMax;
    9090    memset(pVBox->base, 0, max(cbOldSize, cbNewSize));
     91}
     92
     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. */
     96void 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));
    91108}
    92109
     
    123140}
    124141
     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 */
     148Bool 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 */
     199Bool 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
    125258/** Tell the virtual mouse device about the new virtual desktop size. */
    126259void vbvxSetSolarisMouseRange(int width, int height)
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c

    r55250 r55262  
    8080
    8181#include "fb.h"
    82 #include "os.h"
    8382
    8483#include "vboxvideo.h"
    8584#include <VBox/VBoxGuest.h>
    86 #include <VBox/Hardware/VBoxVideoVBE.h>
    8785#include "version-generated.h"
    8886#include "product-generated.h"
     
    10098/* #define DPMS_SERVER
    10199#include "extensions/dpms.h" */
    102 
    103 /* ShadowFB support */
    104 #include "shadowfb.h"
    105100
    106101/* VGA hardware functions for setting and restoring text mode */
     
    150145static void VBOXSaveMode(ScrnInfoPtr pScrn);
    151146static void VBOXRestoreMode(ScrnInfoPtr pScrn);
    152 static 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
    158147
    159148static inline void VBOXSetRec(ScrnInfoPtr pScrn)
     
    273262#endif /* !XORG_7X */
    274263
    275 /** Resize the virtual framebuffer. */
    276 static 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. */
    320 static 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 
    339264#ifdef VBOXVIDEO_13
    340265/* 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. */
    347 static 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  */
    365 static void setAllModesRandR12(ScrnInfoPtr pScrn)
    366 {
    367     setModeRandR12(pScrn, 0);
    368 }
    369266
    370267/* For descriptions of these functions and structures, see
     
    375272{
    376273    VBOXPtr pVBox = VBOXGetRec(pScrn);
    377     Bool rc;
    378     unsigned i;
    379 
    380274    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;
    381278    /* Don't fiddle with the hardware if we are switched
    382279     * to a virtual terminal. */
     
    386283        return TRUE;
    387284    }
    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;
     285    return VBOXAdjustScreenPixmap(pScrn, cw, ch);
    395286}
    396287
     
    402293vbox_crtc_dpms(xf86CrtcPtr crtc, int mode)
    403294{
    404     ScrnInfoPtr pScrn = crtc->scrn;
    405     VBOXPtr pVBox = VBOXGetRec(pScrn);
     295    VBOXPtr pVBox = VBOXGetRec(crtc->scrn);
    406296    unsigned cDisplay = (uintptr_t)crtc->driver_private;
    407 
    408     TRACE_LOG("mode=%d\n", mode);
    409     pVBox->pScreens[cDisplay].fPowerOn = (mode != DPMSModeOff);
    410     setModeRandR12(pScrn, cDisplay);
     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);
    411315}
    412316
     
    441345    TRACE_LOG("name=%s, HDisplay=%d, VDisplay=%d, x=%d, y=%d\n", adjusted_mode->name,
    442346           adjusted_mode->HDisplay, adjusted_mode->VDisplay, x, y);
    443     pVBox->pScreens[cDisplay].fPowerOn = true;
     347    pVBox->pScreens[cDisplay].fCrtcEnabled = true;
     348    pVBox->pScreens[cDisplay].fOutputEnabled = true;
    444349    pVBox->pScreens[cDisplay].aScreenLocation.cx = adjusted_mode->HDisplay;
    445350    pVBox->pScreens[cDisplay].aScreenLocation.cy = adjusted_mode->VDisplay;
     
    454359        return;
    455360    }
    456     setModeRandR12(crtc->scrn, cDisplay);
     361    VBOXSetMode(crtc->scrn, cDisplay, adjusted_mode->HDisplay,
     362                adjusted_mode->VDisplay, x, y);
    457363}
    458364
     
    496402vbox_output_dpms (xf86OutputPtr output, int mode)
    497403{
    498     (void)output; (void)mode;
     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);
    499424}
    500425
     
    573498    uint32_t x, y, iScreen;
    574499    iScreen = (uintptr_t)output->driver_private;
    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);
     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);
    580503    TRACE_EXIT();
    581504    return pModes;
     
    677600
    678601#ifndef XF86_SCRN_INTERFACE
     602# define xf86ScreenToScrn(pScreen) xf86Screens[(pScreen)->myNum]
     603# define xf86ScrnToScreen(pScrn) screenInfo.screens[(pScrn)->scrnIndex]
    679604# define SCRNINDEXAPI(pfn) pfn ## Index
    680605static Bool VBOXScreenInitIndex(int scrnIndex, ScreenPtr pScreen, int argc,
     
    947872
    948873    /* Set the right virtual resolution. */
    949     pScrn->virtualX = pScrn->bitsPerPixel == 16 ? (pScrn->currentMode->HDisplay + 1) & ~1 : pScrn->currentMode->HDisplay;
     874    pScrn->virtualX = pScrn->currentMode->HDisplay;
    950875    pScrn->virtualY = pScrn->currentMode->VDisplay;
    951876
     
    953878
    954879    /* Needed before we initialise DRI. */
    955     pScrn->displayWidth = pScrn->virtualX;
     880    pVBox->cbLine = vboxLineLength(pScrn, pScrn->virtualX);
     881    pScrn->displayWidth = vboxDisplayPitch(pScrn, pVBox->cbLine);
    956882
    957883    xf86PrintModes(pScrn);
     
    1049975#endif /* SET_HAVE_VT_PROPERTY */
    1050976
    1051 #ifdef VBOXVIDEO_13
    1052 
    1053 static 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 
    1098 static 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 
    1123 static 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 
    1143 static 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 
    1156 static 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. */
    1174 static 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 
    1191977/*
    1192978 * QUOTE from the XFree86 DESIGN document:
     
    12621048
    12631049#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
    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);
     1050    VBoxSetUpLinuxACPI(pScreen);
     1051#endif
     1052
     1053    vbox_open (pScrn, pScreen, pVBox);
    12771054    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;
    12821055    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);
    12871056
    12881057#ifdef VBOXVIDEO_13
     
    13281097    }
    13291098
    1330     /* Initialise randr 1.2 mode-setting functions. */
     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. */
    13311102    if (!xf86CrtcScreenInit(pScreen)) {
    13321103        return FALSE;
    13331104    }
    13341105
    1335 #endif
     1106    if (!xf86SetDesiredModes(pScrn)) {
     1107        return FALSE;
     1108    }
     1109#else /* !VBOXVIDEO_13 */
     1110    VBoxSetUpRandR11(pScreen);
    13361111    /* set first video mode */
    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);
     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 */
    13411124
    13421125    /* software cursor */
     
    13991182    }
    14001183#endif
    1401     vbvxSetUpHGSMIHeapInGuest(pVBox, pScrn->videoRam * 1024);
    14021184    vboxEnableVbva(pScrn);
    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;
     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
    14141197#ifdef SET_HAVE_VT_PROPERTY
    14151198    updateHasVTProperty(pScrn, TRUE);
     
    14281211#ifdef VBOXVIDEO_13
    14291212    for (i = 0; i < pVBox->cScreens; ++i)
    1430         vbox_crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff);
     1213        vbox_output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff);
    14311214#endif
    14321215    vboxDisableVbva(pScrn);
    1433     vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0);
     1216    vboxClearVRAM(pScrn, 0, 0);
    14341217#ifdef VBOX_DRI_OLD
    14351218    if (pVBox->useDRI)
     
    14591242
    14601243        for (i = 0; i < pVBox->cScreens; ++i)
    1461             vbox_crtc_dpms(pVBox->pScreens[i].paCrtcs, DPMSModeOff);
     1244            vbox_output_dpms(pVBox->pScreens[i].paOutputs, DPMSModeOff);
    14621245#endif
    14631246        vboxDisableVbva(pScrn);
    1464         vbvxClearVRAM(pScrn, pScrn->virtualX * pScrn->virtualY * pScrn->bitsPerPixel / 8, 0);
     1247        vboxClearVRAM(pScrn, 0, 0);
    14651248    }
    14661249#ifdef VBOX_DRI
     
    14891272    pScreen->CloseScreen = pVBox->CloseScreen;
    14901273#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
    1491     vbvxCleanUpLinuxACPI(pScreen);
     1274    VBoxCleanUpLinuxACPI(pScreen);
    14921275#endif
    14931276#ifndef XF86_SCRN_INTERFACE
     
    15011284{
    15021285    VBOXPtr pVBox;
    1503     Bool rc = TRUE;
     1286    Bool rc;
    15041287
    15051288    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
    15061299    if (!pScrn->vtSema)
    15071300    {
     
    15131306    rc = xf86SetSingleMode(pScrn, pMode, RR_Rotate_0);
    15141307#else
    1515     setModeRandR11(pScrn, pMode, false);
     1308    VBOXAdjustScreenPixmap(pScrn, pMode->HDisplay, pMode->VDisplay);
     1309    rc = VBOXSetMode(pScrn, 0, pMode->HDisplay, pMode->VDisplay,
     1310                     pScrn->frameX0, pScrn->frameY0);
    15161311#endif
    15171312    TRACE_LOG("returning %s\n", rc ? "TRUE" : "FALSE");
     
    15201315
    15211316static void VBOXAdjustFrame(ScrnInfoPtr pScrn, int x, int y)
    1522 { (void)pScrn; (void)x; (void)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}
    15231335
    15241336static void VBOXFreeScreen(ScrnInfoPtr pScrn)
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h

    r55250 r55262  
    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
    6157
    6258#ifdef DEBUG
     
    155151    RTRECT2 aScreenLocation;
    156152    /** Is this CRTC enabled or in DPMS off state? */
    157     Bool fPowerOn;
     153    Bool fCrtcEnabled;
     154    /** Is this output enabled or in DPMS low power state? */
     155    Bool fOutputEnabled;
    158156#ifdef VBOXVIDEO_13
    159157    /** The virtual crtcs. */
     
    172170    /** Has this screen been enabled by the host? */
    173171    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;
    192194    /** Whether the pre-X-server mode was a VBE mode */
    193195    bool fSavedVBEMode;
     
    203205    /** Do we currently want to use the host cursor? */
    204206    Bool fUseHardwareCursor;
     207    /** The last cursor capabilities data read from the X11 property. */
     208    int32_t fLastCursorCapabilitiesFromProperty;
    205209    /** Number of screens attached */
    206210    uint32_t cScreens;
    207211    /** Information about each virtual screen. */
    208212    struct VBoxScreen *pScreens;
     213    /** The last requested framebuffer size. */
     214    RTRECTSIZE FBSize;
    209215    /** Can we get mode hint and cursor integration information from HGSMI? */
    210216    bool fHaveHGSMIModeHints;
     
    220226    void *hACPIEventHandler;
    221227# 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;
    222234#endif
    223235    /** HGSMI guest heap context */
     
    263275};
    264276
     277extern void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled,
     278                         bool fConnected, struct vbvxFrameBuffer *pFrameBuffer);
    265279extern void vbvxClearVRAM(ScrnInfoPtr pScrn, size_t cbOldSize, size_t cbNewSize);
    266 extern void vbvxSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth, unsigned cHeight, int x, int y, bool fEnabled,
    267                         bool fConnected, struct vbvxFrameBuffer *pFrameBuffer);
    268280extern void vbvxSetSolarisMouseRange(int width, int height);
    269281
    270 /* pointer.c */
    271282extern Bool vbox_cursor_init (ScreenPtr pScreen);
     283extern void vbox_open (ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox);
    272284extern void vbox_close (ScrnInfoPtr pScrn, VBOXPtr pVBox);
    273285
    274 /* vbva.c */
    275 extern void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects);
    276 extern void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM);
    277286extern Bool vboxEnableVbva(ScrnInfoPtr pScrn);
    278287extern void vboxDisableVbva(ScrnInfoPtr pScrn);
     
    281290extern void vboxAddModes(ScrnInfoPtr pScrn);
    282291extern void VBoxInitialiseSizeHints(ScrnInfoPtr pScrn);
    283 extern void vbvxReadSizesAndCursorIntegrationFromProperties(ScrnInfoPtr pScrn, bool *pfNeedUpdate);
    284 extern void vbvxReadSizesAndCursorIntegrationFromHGSMI(ScrnInfoPtr pScrn, bool *pfNeedUpdate);
    285 extern void vbvxSetUpLinuxACPI(ScreenPtr pScreen);
    286 extern void vbvxCleanUpLinuxACPI(ScreenPtr pScreen);
     292extern void VBoxUpdateSizeHints(ScrnInfoPtr pScrn);
     293#ifndef VBOXVIDEO_13
     294extern void VBoxSetUpRandR11(ScreenPtr pScreen);
     295#else
     296void VBoxSetUpLinuxACPI(ScreenPtr pScreen);
     297void VBoxCleanUpLinuxACPI(ScreenPtr pScreen);
     298#endif
    287299
    288300/* DRI stuff */
     
    293305extern void VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox);
    294306
     307/* Utilities */
     308
     309/** Calculate the BPP from the screen depth */
     310static 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 */
     316static 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 */
     323static inline int32_t vboxDisplayPitch(ScrnInfoPtr pScrn, int32_t cbLine)
     324{
     325    return cbLine * 8 / vboxBPP(pScrn);
     326}
     327
     328extern void vboxClearVRAM(ScrnInfoPtr pScrn, int32_t cNewX, int32_t cNewY);
     329extern Bool VBOXSetMode(ScrnInfoPtr pScrn, unsigned cDisplay, unsigned cWidth,
     330                        unsigned cHeight, int x, int y);
     331extern Bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height);
     332
    295333#endif /* _VBOXVIDEO_H_ */
    296334
  • trunk/src/VBox/Additions/x11/vboxvideo/vbva.c

    r55250 r55262  
    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
    2027#include <iprt/string.h>
    2128#include "compiler.h"
     29
     30/* ShadowFB support */
     31#include "shadowfb.h"
    2232
    2333#include "vboxvideo.h"
     
    4151 *                rectangles
    4252 */
    43 void vbvxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
     53static void
     54vboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
    4455{
    4556    VBVACMDHDR cmdHdr;
     
    6879                || aRects[i].y2 <   pVBox->pScreens[j].aScreenLocation.y)
    6980                continue;
    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;
     81            cmdHdr.x = (int16_t)aRects[i].x1;
     82            cmdHdr.y = (int16_t)aRects[i].y1;
    7283            cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
    7384            cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
     
    89100}
    90101
     102/** Callback to fill in the view structures */
     103static int
     104vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
     105{
     106    VBOXPtr pVBox = (VBOXPtr)pvVBox;
     107    unsigned i;
     108    for (i = 0; i < cViews; ++i)
     109    {
     110        pViews[i].u32ViewIndex = i;
     111        pViews[i].u32ViewOffset = 0;
     112        pViews[i].u32ViewSize = pVBox->cbView;
     113        pViews[i].u32MaxScreenSize = pVBox->cbFBMax;
     114    }
     115    return VINF_SUCCESS;
     116}
     117
     118/**
     119 * Initialise VirtualBox's accelerated video extensions.
     120 *
     121 * @returns TRUE on success, FALSE on failure
     122 */
     123static Bool
     124vboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
     125{
     126    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
     127    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
    91149static DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb)
    92150{
     
    109167
    110168/**
    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  */
    116 void vbvxSetUpHGSMIHeapInGuest(VBOXPtr pVBox, uint32_t cbVRAM)
    117 {
    118     int rc;
     169 * Initialise VirtualBox's accelerated video extensions.
     170 *
     171 * @returns TRUE on success, FALSE on failure
     172 */
     173static Bool
     174vboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)
     175{
     176    int rc = VINF_SUCCESS;
     177    unsigned i;
    119178    uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
    120179    void *pvGuestHeapMemory;
    121180
    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 
    130 /** Callback to fill in the view structures */
    131 static int
    132 vboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
    133 {
    134     VBOXPtr pVBox = (VBOXPtr)pvVBox;
    135     unsigned i;
    136     for (i = 0; i < cViews; ++i)
    137     {
    138         pViews[i].u32ViewIndex = i;
    139         pViews[i].u32ViewOffset = 0;
    140         pViews[i].u32ViewSize = pVBox->cbView;
    141         pViews[i].u32MaxScreenSize = pVBox->cbFBMax;
    142     }
    143     return VINF_SUCCESS;
    144 }
    145 
    146 /**
    147  * Initialise VirtualBox's accelerated video extensions.
    148  *
    149  * @returns TRUE on success, FALSE on failure
    150  */
    151 static Bool vboxSetupVRAMVbva(VBOXPtr pVBox)
    152 {
    153     int rc = VINF_SUCCESS;
    154     unsigned i;
    155 
    156     pVBox->cbFBMax = pVBox->cbView;
     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);
    157211    for (i = 0; i < pVBox->cScreens; ++i)
    158212    {
     
    170224    rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
    171225                               vboxFillViewInfo, (void *)pVBox);
    172     VBVXASSERT(RT_SUCCESS(rc), ("Failed to send the view information to the host, rc=%d\n", rc));
     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    }
    173231    return TRUE;
    174232}
    175233
    176 static 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 
    186 static 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;
     234void
     235vbox_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");
    192241}
    193242
     
    203252{
    204253    bool rc = TRUE;
     254    int scrnIndex = pScrn->scrnIndex;
    205255    unsigned i;
    206256    VBOXPtr pVBox = pScrn->driverPrivate;
    207257
    208258    TRACE_ENTRY();
    209     if (!vboxSetupVRAMVbva(pVBox))
     259    if (!vboxSetupVRAMVbva(pScrn, pVBox))
    210260        return FALSE;
    211261    for (i = 0; i < pVBox->cScreens; ++i)
     
    219269            rc = FALSE;
    220270    }
    221     VBVXASSERT(rc, ("Failed to enable screen update reporting for at least one virtual monitor.\n"));
     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    }
    222278#ifdef VBOXVIDEO_13
    223     VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS | VBVACAPS_DISABLE_CURSOR_INTEGRATION);
    224     pVBox->fHaveHGSMIModeHints = haveHGSMIModeHintAndCursorReportingInterface(pVBox);
    225     pVBox->fHostHasScreenBlankingFlag = hostHasScreenBlankingFlag(pVBox);
     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
    226285#endif
    227286    return rc;
     
    240299{
    241300    int rc;
     301    int scrnIndex = pScrn->scrnIndex;
    242302    unsigned i;
    243303    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