vboxutils.c revision 1e6a6fd0da07b825554f344b6534cf5319454eea
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * VirtualBox X11 Additions graphics driver utility functions
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Copyright (C) 2006-2007 Oracle Corporation
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * available from http://www.virtualbox.org. This file is free software;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * General Public License (GPL) as published by the Free Software
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**************************************************************************
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync* Main functions *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync**************************************************************************/
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Callback function called by the X server to tell us about dirty
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * rectangles in the video buffer.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScreen pointer to the information structure for the current
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param iRects Number of dirty rectangles to update
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param aRects Array of structures containing the coordinates of the
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * rectangles
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned j;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (i = 0; i < iRects; ++i)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Just continue quietly if VBVA is not currently active. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Callback to fill in the view structures */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (i = 0; i < cViews; ++i)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Initialise VirtualBox's accelerated video extensions.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE on success, FALSE on failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI. Disableing video acceleration.\n");
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Set up the dirty rectangle handler. It will be added into a function
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * chain and gets removed when the screen is cleaned up. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (ShadowFBInit2(pScreen, NULL, vboxHandleDirtyRect) != TRUE)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync "Unable to install dirty rectangle handler for VirtualBox graphics acceleration.\n");
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Initialise VirtualBox's accelerated video extensions.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE on success, FALSE on failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("video RAM: %u KB, guest heap offset: 0x%x, cbGuestHeapMemory: %u\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pScrn->videoRam, offVRAMBaseMapping + offGuestHeapMemory,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->cbView = pVBox->cbFBMax = offVRAMBaseMapping;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("VBVA buffer offset for screen %u: 0x%lx\n", i,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("Maximum framebuffer size: %lu (0x%lx)\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to send the view information to the host, rc=%d\n", rc);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->fHaveHGSMI = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Inform VBox that we will supply it with dirty rectangle information
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * and install the dirty rectangle handler.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE for success, FALSE for failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScrn Pointer to a structure describing the X screen in use
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBVA = (struct VBVABUFFER *) ( ((uint8_t *)pVBox->base)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!VBoxVBVAEnable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, pVBVA, i))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Request not accepted - disable for old hosts. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync "Failed to enable screen update reporting for at least one virtual monitor.\n");
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Inform VBox that we will stop supplying it with dirty rectangle
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * information. This function is intended to be called when an X
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * virtual terminal is disabled, or the X server is terminated.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE for success, FALSE for failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScrn Pointer to a structure describing the X screen in use
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->fHaveHGSMI) /* Ths function should not have been called */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Inform VBox that we are aware of advanced graphics functions
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * (i.e. dynamic resizing, seamless).
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE for success, FALSE for failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return RT_SUCCESS(VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Inform VBox that we are no longer aware of advanced graphics functions
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * (i.e. dynamic resizing, seamless).
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE for success, FALSE for failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return RT_SUCCESS(VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Query the last display change request.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns boolean success indicator.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScrn Pointer to the X screen info structure.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pcx Where to store the horizontal pixel resolution (0 = do not change).
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pcy Where to store the vertical pixel resolution (0 = do not change).
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pcBits Where to store the bits per pixel (0 = do not change).
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param iDisplay Where to store the display number the request was for - 0 for the
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * primary display, 1 for the first secondary, etc.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxGetDisplayChangeRequest(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int rc = VbglR3GetDisplayChangeRequest(pcx, pcy, pcBits, piDisplay, false);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to obtain the last resolution requested by the guest, rc=%d.\n", rc);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Query the host as to whether it likes a specific video mode.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns the result of the query
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param cx the width of the mode being queried
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param cy the height of the mode being queried
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param cBits the bpp of the mode being queried
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxHostLikesVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return TRUE; /* If we can't ask the host then we like everything. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Check if any seamless mode is enabled.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Seamless is only relevant for the newer Xorg modules.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns the result of the query
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * (true = seamless enabled, false = seamless not enabled)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScrn Screen info pointer.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Save video mode parameters to the registry.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns iprt status value
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pszName the name to save the mode parameters under
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param cx mode width
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param cy mode height
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param cBits bits per pixel for the mode
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxSaveVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return RT_SUCCESS(VbglR3SaveVideoMode("SavedMode", cx, cy, cBits));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Retrieve video mode parameters from the registry.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns iprt status value
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pszName the name under which the mode parameters are saved
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pcx where to store the mode width
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pcy where to store the mode height
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pcBits where to store the bits per pixel for the mode
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxRetrieveVideoMode(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int rc = VbglR3RetrieveVideoMode("SavedMode", pcx, pcy, pcBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("Retrieved a video mode of %dx%dx%d\n", *pcx, *pcy, *pcBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("Failed to retrieve video mode, error %d\n", rc);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Fills a display mode M with a built-in mode of name pszName and dimensions
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * cx and cy.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic void vboxFillDisplayMode(ScrnInfoPtr pScrn, DisplayModePtr m,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("pszName=%s, cx=%u, cy=%u\n", pszName, cx, cy);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Older versions of VBox only support screen widths which are a multiple
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->Clock = m->HTotal * m->VTotal * 60 / 1000; /* kHz */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** vboxvideo's list of standard video modes */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** mode width */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** mode height */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0])
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Returns a standard mode which the host likes. Can be called multiple
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * times with the index returned by the previous call to get a list of modes.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns the index of the mode in the list, or 0 if no more modes are
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * available
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScrn the screen information structure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScrn->bitsPerPixel
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * if this is non-null, only modes with this BPP will be
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param cIndex the index of the last mode queried, or 0 to query the
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * first mode available. Note: the first index is 1
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pcx where to store the mode's width
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pcy where to store the mode's height
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pcBits where to store the mode's BPP
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncunsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (unsigned i = cIndex; i < vboxNumStdModes - 1; ++i)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (cBits != 0 && !vboxHostLikesVideoMode(pScrn, cx, cy, cBits))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync else if (vboxHostLikesVideoMode(pScrn, cx, cy, 16))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return i + 1;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Returns the preferred video mode. The current order of preference is
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * (from highest to least preferred):
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * - The mode corresponding to the last size hint from the host
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * - The video mode saved from the last session
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * - The largest standard mode which the host likes, falling back to
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * 640x480x32 as a worst case
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * - If the host can't be contacted at all, we return 1024x768x32
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * The return type is void as we guarantee we will return some mode.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvoid vboxGetPreferredMode(ScrnInfoPtr pScrn, uint32_t iScreen, uint32_t *pcx,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Query the host for the preferred resolution and colour depth */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t cx = 0, cy = 0, iScreenIn = iScreen, cBits = 32;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync bool found = false;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if ((cx == 0) || (cy == 0) || iScreenIn != iScreen)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = vboxRetrieveVideoMode(pScrn, &cx, &cy, &cBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = (vboxNextStandardMode(pScrn, 0, &cx, &cy, &cBits) != 0);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Last resort */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("cx=%u, cy=%u, cBits=%u\n", cx, cy, cBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/* Move a screen mode found to the end of the list, so that RandR will give
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * it the highest priority when a mode switch is requested. Returns the mode
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * that was previously before the mode in the list in order to allow the
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * caller to continue walking the list. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic DisplayModePtr vboxMoveModeToFront(ScrnInfoPtr pScrn,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Rewrites the first dynamic mode found which is not the current screen mode
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * to contain the host's currently preferred screen size, then moves that
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * mode to the front of the screen information structure's mode list.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Additionally, if the current mode is not dynamic, the second dynamic mode
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * will be set to match the current mode and also added to the front. This
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * ensures that the user can always reset the current size to kick the driver
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * to update its mode list.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvoid vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync bool found = false;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Count the number of modes for sanity */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (pCount = pScrn->modes; ; pCount = pCount->next, ++cModes)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxFillDisplayMode(pScrn, pMode, NULL, pCurrent->HDisplay,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ("vboxvideo: no free dynamic mode found. Exiting.\n"));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync || ( (pScrn->modes->HDisplay == pCurrent->HDisplay)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ("pScrn->modes->HDisplay=%u, pScrn->modes->next->HDisplay=%u\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pScrn->modes->HDisplay, pScrn->modes->next->HDisplay));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync || ( (pScrn->modes->VDisplay == pCurrent->VDisplay)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ("pScrn->modes->VDisplay=%u, pScrn->modes->next->VDisplay=%u\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pScrn->modes->VDisplay, pScrn->modes->next->VDisplay));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Allocates an empty display mode and links it into the doubly linked list of
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * modes pointed to by pScrn->modes. Returns a pointer to the newly allocated
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic DisplayModePtr vboxAddEmptyScreenMode(ScrnInfoPtr pScrn)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync DisplayModePtr pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Create display mode entries in the screen information structure for each
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * of the initial graphics modes that we wish to support. This includes:
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * - An initial mode, of the size requested by the caller
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * - Two dynamic modes, one of which will be updated to match the last size
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * hint from the host on each mode switch, but initially also of the
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * requested size
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * - Several standard modes, if possible ones that the host likes
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * - Any modes that the user requested in xorg.conf/XFree86Config
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvoid vboxAddModes(ScrnInfoPtr pScrn, uint32_t cxInit, uint32_t cyInit)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* For reasons related to the way RandR 1.1 is implemented, we need to
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * make sure that the initial mode (more precisely, a mode equal to the
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * initial virtual resolution) is always present in the mode list. RandR
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * has the assumption build in that there will either be a mode of that
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * size present at all times, or that the first mode in the list will
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * always be smaller than the initial virtual resolution. Since our
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * approach to dynamic resizing isn't quite the way RandR was intended to
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * be, and breaks the second assumption, we guarantee the first. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync DisplayModePtr pMode = vboxAddEmptyScreenMode(pScrn);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxFillDisplayMode(pScrn, pMode, "VBoxInitialMode", cxInit, cyInit);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Create our two dynamic modes. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Add standard modes supported by the host */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for ( ; ; )
if (cIndex == 0)