vboxutils.c revision 1e6a6fd0da07b825554f344b6534cf5319454eea
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** @file
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * VirtualBox X11 Additions graphics driver utility functions
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/*
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Copyright (C) 2006-2007 Oracle Corporation
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
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
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#include <VBox/VMMDev.h>
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#include <VBox/VBoxGuestLib.h>
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#ifndef PCIACCESS
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync# include <xf86Pci.h>
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync# include <Pci.h>
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#endif
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#include "xf86.h"
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#define NEED_XF86_TYPES
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#include <iprt/string.h>
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#include "compiler.h"
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#include "vboxvideo.h"
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**************************************************************************
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync* Main functions *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync**************************************************************************/
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Callback function called by the X server to tell us about dirty
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * rectangles in the video buffer.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScreen pointer to the information structure for the current
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * screen
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param iRects Number of dirty rectangles to update
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param aRects Array of structures containing the coordinates of the
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * rectangles
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic void
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxHandleDirtyRect(ScrnInfoPtr pScrn, int iRects, BoxPtr aRects)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBVACMDHDR cmdHdr;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned j;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pVBox->fHaveHGSMI == FALSE || pVBox->vtSwitch)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (i = 0; i < iRects; ++i)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (j = 0; j < pVBox->cScreens; ++j)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Just continue quietly if VBVA is not currently active. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync struct VBVABUFFER *pVBVA = pVBox->aVbvaCtx[j].pVBVA;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if ( !pVBVA
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync || !(pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_ENABLED))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync continue;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if ( aRects[i].x1 > pVBox->aScreenLocation[j].x
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync + pVBox->aScreenLocation[j].cx
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync || aRects[i].y1 > pVBox->aScreenLocation[j].y
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync + pVBox->aScreenLocation[j].cy
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync || aRects[i].x2 < pVBox->aScreenLocation[j].x
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync || aRects[i].y2 < pVBox->aScreenLocation[j].y)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync continue;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cmdHdr.x = (int16_t)aRects[i].x1;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cmdHdr.y = (int16_t)aRects[i].y1;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cmdHdr.w = (uint16_t)(aRects[i].x2 - aRects[i].x1);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cmdHdr.h = (uint16_t)(aRects[i].y2 - aRects[i].y1);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#if 0
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("display=%u, x=%d, y=%d, w=%d, h=%d\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync j, cmdHdr.x, cmdHdr.y, cmdHdr.w, cmdHdr.h);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#endif
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (VBoxVBVABufferBeginUpdate(&pVBox->aVbvaCtx[j],
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync &pVBox->guestCtx))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBoxVBVAWrite(&pVBox->aVbvaCtx[j], &pVBox->guestCtx, &cmdHdr,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync sizeof(cmdHdr));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBoxVBVABufferEndUpdate(&pVBox->aVbvaCtx[j]);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** Callback to fill in the view structures */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic int
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxFillViewInfo(void *pvVBox, struct VBVAINFOVIEW *pViews, uint32_t cViews)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = (VBOXPtr)pvVBox;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (i = 0; i < cViews; ++i)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pViews[i].u32ViewIndex = i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pViews[i].u32ViewOffset = 0;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pViews[i].u32ViewSize = pVBox->cbView;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pViews[i].u32MaxScreenSize = pVBox->cbFBMax;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return VINF_SUCCESS;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Initialise VirtualBox's accelerated video extensions.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE on success, FALSE on failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic Bool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxInitVbva(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int rc = VINF_SUCCESS;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->cScreens = 1;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!VBoxHGSMIIsSupported())
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(scrnIndex, X_ERROR, "The graphics device does not seem to support HGSMI. Disableing video acceleration.\n");
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
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 {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(scrnIndex, X_ERROR,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync "Unable to install dirty rectangle handler for VirtualBox graphics acceleration.\n");
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return TRUE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Initialise VirtualBox's accelerated video extensions.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE on success, FALSE on failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic Bool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxSetupVRAMVbva(ScrnInfoPtr pScrn, VBOXPtr pVBox)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int rc = VINF_SUCCESS;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t offVRAMBaseMapping, offGuestHeapMemory, cbGuestHeapMemory;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync void *pvGuestHeapMemory;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->fHaveHGSMI)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBoxHGSMIGetBaseMappingInfo(pScrn->videoRam * 1024, &offVRAMBaseMapping,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync NULL, &offGuestHeapMemory, &cbGuestHeapMemory,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync NULL);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pvGuestHeapMemory = ((uint8_t *)pVBox->base) + offVRAMBaseMapping
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync + offGuestHeapMemory;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("video RAM: %u KB, guest heap offset: 0x%x, cbGuestHeapMemory: %u\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pScrn->videoRam, offVRAMBaseMapping + offGuestHeapMemory,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cbGuestHeapMemory);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = VBoxHGSMISetupGuestContext(&pVBox->guestCtx, pvGuestHeapMemory,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cbGuestHeapMemory,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync offVRAMBaseMapping + offGuestHeapMemory);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (RT_FAILURE(rc))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to set up the guest-to-host communication context, rc=%d\n", rc);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->cbView = pVBox->cbFBMax = offVRAMBaseMapping;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->cScreens = VBoxHGSMIGetMonitorCount(&pVBox->guestCtx);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->cScreens);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (i = 0; i < pVBox->cScreens; ++i)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->cbFBMax -= VBVA_MIN_BUFFER_SIZE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->aoffVBVABuffer[i] = pVBox->cbFBMax;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("VBVA buffer offset for screen %u: 0x%lx\n", i,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync (unsigned long) pVBox->cbFBMax);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBoxVBVASetupBufferContext(&pVBox->aVbvaCtx[i],
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->aoffVBVABuffer[i],
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBVA_MIN_BUFFER_SIZE);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("Maximum framebuffer size: %lu (0x%lx)\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync (unsigned long) pVBox->cbFBMax,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync (unsigned long) pVBox->cbFBMax);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = VBoxHGSMISendViewInfo(&pVBox->guestCtx, pVBox->cScreens,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxFillViewInfo, (void *)pVBox);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (RT_FAILURE(rc))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to send the view information to the host, rc=%d\n", rc);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return TRUE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvbox_open(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBox->fHaveHGSMI = vboxInitVbva(pScrn->scrnIndex, pScreen, pVBox);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return pVBox->fHaveHGSMI;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvbox_device_available(VBOXPtr pVBox)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return pVBox->useDevice;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Inform VBox that we will supply it with dirty rectangle information
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * and install the dirty rectangle handler.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE for success, FALSE for failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScrn Pointer to a structure describing the X screen in use
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxEnableVbva(ScrnInfoPtr pScrn)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync bool rc = TRUE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int scrnIndex = pScrn->scrnIndex;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!vboxSetupVRAMVbva(pScrn, pVBox))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (i = 0; i < pVBox->cScreens; ++i)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync struct VBVABUFFER *pVBVA;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pVBVA = (struct VBVABUFFER *) ( ((uint8_t *)pVBox->base)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync + pVBox->aoffVBVABuffer[i]);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!VBoxVBVAEnable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, pVBVA, i))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync rc = FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!rc)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Request not accepted - disable for old hosts. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(scrnIndex, X_ERROR,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync "Failed to enable screen update reporting for at least one virtual monitor.\n");
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxDisableVbva(pScrn);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return rc;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
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 *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE for success, FALSE for failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScrn Pointer to a structure describing the X screen in use
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvoid
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxDisableVbva(ScrnInfoPtr pScrn)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int rc;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int scrnIndex = pScrn->scrnIndex;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned i;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->fHaveHGSMI) /* Ths function should not have been called */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (i = 0; i < pVBox->cScreens; ++i)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBoxVBVADisable(&pVBox->aVbvaCtx[i], &pVBox->guestCtx, i);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Inform VBox that we are aware of advanced graphics functions
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * (i.e. dynamic resizing, seamless).
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE for success, FALSE for failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxEnableGraphicsCap(VBOXPtr pVBox)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->useDevice)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return RT_SUCCESS(VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Inform VBox that we are no longer aware of advanced graphics functions
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * (i.e. dynamic resizing, seamless).
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns TRUE for success, FALSE for failure
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxDisableGraphicsCap(VBOXPtr pVBox)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->useDevice)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return RT_SUCCESS(VbglR3SetGuestCaps(0, VMMDEV_GUEST_SUPPORTS_GRAPHICS));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Query the last display change request.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
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.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxGetDisplayChangeRequest(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t *pcBits, uint32_t *piDisplay)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->useDevice)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int rc = VbglR3GetDisplayChangeRequest(pcx, pcy, pcBits, piDisplay, false);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (RT_SUCCESS(rc))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return TRUE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to obtain the last resolution requested by the guest, rc=%d.\n", rc);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Query the host as to whether it likes a specific video mode.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
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
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxHostLikesVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->useDevice)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return TRUE; /* If we can't ask the host then we like everything. */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return VbglR3HostLikesVideoMode(cx, cy, cBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Check if any seamless mode is enabled.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Seamless is only relevant for the newer Xorg modules.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @returns the result of the query
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * (true = seamless enabled, false = seamless not enabled)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * @param pScrn Screen info pointer.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxGuestIsSeamless(ScrnInfoPtr pScrn)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VMMDevSeamlessMode mode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->useDevice)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (RT_FAILURE(VbglR3SeamlessGetLastEvent(&mode)))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return (mode != VMMDev_Seamless_Disabled);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Save video mode parameters to the registry.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
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
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxSaveVideoMode(ScrnInfoPtr pScrn, uint32_t cx, uint32_t cy, uint32_t cBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->useDevice)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return RT_SUCCESS(VbglR3SaveVideoMode("SavedMode", cx, cy, cBits));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Retrieve video mode parameters from the registry.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *
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
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncBool
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvboxRetrieveVideoMode(ScrnInfoPtr pScrn, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pVBox->useDevice)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return FALSE;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync int rc = VbglR3RetrieveVideoMode("SavedMode", pcx, pcy, pcBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (RT_SUCCESS(rc))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("Retrieved a video mode of %dx%dx%d\n", *pcx, *pcy, *pcBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync else
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("Failed to retrieve video mode, error %d\n", rc);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return (RT_SUCCESS(rc));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * Fills a display mode M with a built-in mode of name pszName and dimensions
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * cx and cy.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic void vboxFillDisplayMode(ScrnInfoPtr pScrn, DisplayModePtr m,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync const char *pszName, unsigned cx, unsigned cy)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("pszName=%s, cx=%u, cy=%u\n", pszName, cx, cy);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->status = MODE_OK;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->type = M_T_BUILTIN;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Older versions of VBox only support screen widths which are a multiple
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * of 8 */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pVBox->fAnyX)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->HDisplay = cx;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync else
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->HDisplay = cx & ~7;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->HSyncStart = m->HDisplay + 2;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->HSyncEnd = m->HDisplay + 4;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->HTotal = m->HDisplay + 6;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->VDisplay = cy;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->VSyncStart = m->VDisplay + 2;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->VSyncEnd = m->VDisplay + 4;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->VTotal = m->VDisplay + 6;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->Clock = m->HTotal * m->VTotal * 60 / 1000; /* kHz */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pszName)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (m->name)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync free(m->name);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync m->name = xnfstrdup(pszName);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/** vboxvideo's list of standard video modes */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstruct
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** mode width */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t cx;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /** mode height */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t cy;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync} vboxStandardModes[] =
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync { 1600, 1200 },
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync { 1440, 1050 },
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync { 1280, 960 },
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync { 1024, 768 },
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync { 800, 600 },
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync { 640, 480 },
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync { 0, 0 }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync};
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncenum
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0])
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync};
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
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 * returned
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
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncunsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t *pcx, uint32_t *pcy,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t *pcBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync XF86ASSERT(cIndex < vboxNumStdModes,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ("cIndex = %d, vboxNumStdModes = %d\n", cIndex,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxNumStdModes));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (unsigned i = cIndex; i < vboxNumStdModes - 1; ++i)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t cBits = pScrn->bitsPerPixel;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t cx = vboxStandardModes[i].cx;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t cy = vboxStandardModes[i].cy;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (cBits != 0 && !vboxHostLikesVideoMode(pScrn, cx, cy, cBits))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync continue;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (vboxHostLikesVideoMode(pScrn, cx, cy, 32))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cBits = 32;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync else if (vboxHostLikesVideoMode(pScrn, cx, cy, 16))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cBits = 16;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync else
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync continue;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pcx)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *pcx = cx;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pcy)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *pcy = cy;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pcBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *pcBits = cBits;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return i + 1;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return 0;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
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 *
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * The return type is void as we guarantee we will return some mode.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvoid vboxGetPreferredMode(ScrnInfoPtr pScrn, uint32_t iScreen, uint32_t *pcx,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t *pcy, uint32_t *pcBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Query the host for the preferred resolution and colour depth */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t cx = 0, cy = 0, iScreenIn = iScreen, cBits = 32;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync VBOXPtr pVBox = pScrn->driverPrivate;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("iScreen=%u\n", iScreen);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync bool found = false;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if ( pVBox->aPreferredSize[iScreen].cx
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync && pVBox->aPreferredSize[iScreen].cy)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cx = pVBox->aPreferredSize[iScreen].cx;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cy = pVBox->aPreferredSize[iScreen].cy;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = true;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pVBox->useDevice)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!found)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync &iScreenIn);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if ((cx == 0) || (cy == 0) || iScreenIn != iScreen)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = false;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!found)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = vboxRetrieveVideoMode(pScrn, &cx, &cy, &cBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if ((cx == 0) || (cy == 0))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = false;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!found)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = (vboxNextStandardMode(pScrn, 0, &cx, &cy, &cBits) != 0);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!found)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Last resort */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cx = 640;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cy = 480;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cBits = 32;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync else
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cx = 1024;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync cy = 768;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pcx)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *pcx = cx;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pcy)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *pcy = cy;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pcBits)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync *pcBits = cBits;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_LOG("cx=%u, cy=%u, cBits=%u\n", cx, cy, cBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
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 DisplayModePtr pMode)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync DisplayModePtr pPrev = pMode->prev;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pMode != pScrn->modes)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->prev->next = pMode->next;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->next->prev = pMode->prev;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->next = pScrn->modes;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->prev = pScrn->modes->prev;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->next->prev = pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->prev->next = pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pScrn->modes = pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return pPrev;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
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.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvoid vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 0;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync DisplayModePtr pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync bool found = false;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxGetPreferredMode(pScrn, 0, &cx, &cy, &cBits);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#ifdef DEBUG
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Count the number of modes for sanity */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned cModes = 1, cMode = 0;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync DisplayModePtr pCount;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (pCount = pScrn->modes; ; pCount = pCount->next, ++cModes)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pCount->next == pScrn->modes)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync break;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#endif
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for (pMode = pScrn->modes; ; pMode = pMode->next)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#ifdef DEBUG
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync XF86ASSERT (cMode++ < cModes, (NULL));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync#endif
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if ( pMode != pCurrent
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync && !strcmp(pMode->name, "VBoxDynamicMode"))
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!found)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxFillDisplayMode(pScrn, pMode, NULL, cx, cy);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync else if (pCurrent)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxFillDisplayMode(pScrn, pMode, NULL, pCurrent->HDisplay,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pCurrent->VDisplay);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync found = true;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode = vboxMoveModeToFront(pScrn, pMode);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (pMode->next == pScrn->modes)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync break;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync XF86ASSERT (found,
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ("vboxvideo: no free dynamic mode found. Exiting.\n"));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync XF86ASSERT ( (pScrn->modes->HDisplay == (long) cx)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync || ( (pScrn->modes->HDisplay == pCurrent->HDisplay)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync && (pScrn->modes->next->HDisplay == (long) cx)),
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ("pScrn->modes->HDisplay=%u, pScrn->modes->next->HDisplay=%u\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pScrn->modes->HDisplay, pScrn->modes->next->HDisplay));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync XF86ASSERT ( (pScrn->modes->VDisplay == (long) cy)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync || ( (pScrn->modes->VDisplay == pCurrent->VDisplay)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync && (pScrn->modes->next->VDisplay == (long) cy)),
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync ("pScrn->modes->VDisplay=%u, pScrn->modes->next->VDisplay=%u\n",
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pScrn->modes->VDisplay, pScrn->modes->next->VDisplay));
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
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
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync * memory.
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncstatic DisplayModePtr vboxAddEmptyScreenMode(ScrnInfoPtr pScrn)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync DisplayModePtr pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync TRACE_ENTRY();
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync if (!pScrn->modes)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pScrn->modes = pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->next = pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->prev = pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync else
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->next = pScrn->modes;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->prev = pScrn->modes->prev;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->next->prev = pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode->prev->next = pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync }
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync return pMode;
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync}
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync/**
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
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsyncvoid vboxAddModes(ScrnInfoPtr pScrn, uint32_t cxInit, uint32_t cyInit)
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync{
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync unsigned cx = 0, cy = 0, cIndex = 0;
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 pMode = vboxAddEmptyScreenMode(pScrn);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync pMode = vboxAddEmptyScreenMode(pScrn);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync vboxFillDisplayMode(pScrn, pMode, "VBoxDynamicMode", cxInit, cyInit);
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync /* Add standard modes supported by the host */
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync for ( ; ; )
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync {
dee9e52b1688c0617890cbbd8a8488f9f315d1b7vboxsync char szName[256];
cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy, NULL);
if (cIndex == 0)
break;
sprintf(szName, "VBox-%ux%u", cx, cy);
pMode = vboxAddEmptyScreenMode(pScrn);
vboxFillDisplayMode(pScrn, pMode, szName, cx, cy);
}
/* And finally any modes specified by the user. We assume here that
* the mode names reflect the mode sizes. */
for (unsigned i = 0; pScrn->display->modes != NULL
&& pScrn->display->modes[i] != NULL; i++)
{
if (sscanf(pScrn->display->modes[i], "%ux%u", &cx, &cy) == 2)
{
pMode = vboxAddEmptyScreenMode(pScrn);
vboxFillDisplayMode(pScrn, pMode, pScrn->display->modes[i], cx, cy);
}
}
}