VirtualBox

Changeset 27529 in vbox for trunk/src/VBox/Additions/x11


Ignore:
Timestamp:
Mar 19, 2010 12:38:52 PM (15 years ago)
Author:
vboxsync
Message:

Additions/x11/vboxvideo: vboxvideo part of dynamic resizing for older X.Org Additions

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/vboxvideo/Makefile.kmk

    r26054 r27529  
    5050        $(VBOX_PATH_X11_XFREE_4_3)/include/X11 \
    5151        $(VBOX_PATH_X11_XFREE_4_3)/include/X11/extensions \
     52        $(VBOX_PATH_X11_XFREE_4_3)/include/extensions \
    5253        $(VBOX_PATH_X11_XFREE_4_3)/include/fonts \
    5354        $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/afb \
     
    7374        $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/miext/shadow \
    7475        $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/render \
     76        $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/randr \
    7577        $(VBOX_PATH_X11_XFREE_4_3)/programs/Xserver/Xext
    7678 else
  • trunk/src/VBox/Additions/x11/vboxvideo/undefined_70

    r26054 r27529  
    144144xf86sprintf
    145145_GLOBAL_OFFSET_TABLE_
     146XNFstrdup
     147FatalError
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxutils.c

    r27314 r27529  
    4848/* #define DEBUG_POINTER */
    4949
    50 #define BOOL_STR(a) ((a) ? "TRUE" : "FALSE")
    51 
    52 #ifdef DEBUG_VIDEO
    53 # define TRACE_LINE() do \
    54     { \
    55         ErrorF ("%s: line %d\n", __FUNCTION__, __LINE__); \
    56     } while(0)
     50#ifdef DEBUG
    5751# define PUT_PIXEL(c) ErrorF ("%c", c)
    5852#else /* DEBUG_VIDEO not defined */
    5953# define PUT_PIXEL(c) do { } while(0)
    60 # define TRACE_LINE() do { } while(0)
    6154#endif /* DEBUG_VIDEO not defined */
    6255
     
    472465    int rc;
    473466
    474     TRACE_ENTRY();
    475467    pVBox->reqp->fFlags = 0;
    476468    rc = VbglR3SetPointerShapeReq(pVBox->reqp);
     
    490482    int rc;
    491483
    492     TRACE_ENTRY();
    493484    if (vbox_host_uses_hwcursor(pScrn)) {
    494485        pVBox->reqp->fFlags = VBOX_MOUSE_POINTER_VISIBLE;
     
    512503    reqp = (VMMDevReqMousePointer *)image;
    513504
    514     TRACE_LOG("w=%d h=%d size=%d\n", reqp->width, reqp->height, reqp->header.size);
    515505#ifdef DEBUG_POINTER
    516506    vbox_show_shape(reqp->width, reqp->height, 0, image);
     
    530520vbox_set_cursor_colors(ScrnInfoPtr pScrn, int bg, int fg)
    531521{
    532     TRACE_ENTRY();
    533 
    534522    NOREF(pScrn);
    535523    NOREF(bg);
     
    554542    VBOXPtr pVBox = pScrn->driverPrivate;
    555543
    556     TRACE_ENTRY();
    557 
    558544    vbox_vmm_hide_cursor(pScrn, pVBox);
    559545}
     
    564550    VBOXPtr pVBox = pScrn->driverPrivate;
    565551
    566     TRACE_ENTRY();
    567 
    568552    vbox_vmm_show_cursor(pScrn, pVBox);
    569553}
     
    573557{
    574558    VBOXPtr pVBox = pScrn->driverPrivate;
    575 
    576     TRACE_ENTRY();
    577559
    578560    vbox_vmm_load_cursor_image(pScrn, pVBox, image);
     
    604586    VMMDevReqMousePointer *reqp;
    605587
    606     TRACE_ENTRY();
    607588    pVBox = infoPtr->pScrn->driverPrivate;
    608589    bitsp = pCurs->bits;
     
    728709    Bool rc = TRUE;
    729710
    730     TRACE_ENTRY();
    731711    if (!vbox_host_uses_hwcursor(pScrn))
    732712        rc = FALSE;
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h

    r27309 r27529  
    5757#define _VBOXVIDEO_H_
    5858
    59 #ifdef DEBUG_michael
    60 # define DEBUG_VIDEO 1
    61 #endif
    62 
    63 #ifdef DEBUG_VIDEO
     59#ifdef DEBUG
    6460
    6561#define TRACE_ENTRY() \
     
    8278    ErrorF ("%s: line %d\n", __FUNCTION__, __LINE__); \
    8379    } while(0)
    84 
    85 #else  /* DEBUG_VIDEO not defined */
     80# define XF86ASSERT(expr, out) \
     81if (!(expr)) \
     82{ \
     83    ErrorF ("\nAssertion failed!\n\n"); \
     84    ErrorF ("%s\n", #expr); \
     85    ErrorF ("at %s (%s:%d)\n", __PRETTY_FUNCTION__, __FILE__, __LINE__); \
     86    ErrorF out; \
     87    FatalError("Aborting"); \
     88}
     89#else  /* !DEBUG */
    8690
    8791#define TRACE_ENTRY()  do { } while(0)
     
    8993#define TRACE_LOG(...) do { } while(0)
    9094
    91 #endif  /* DEBUG_VIDEO not defined */
     95#endif  /* !DEBUG */
    9296
    9397#define BOOL_STR(a) ((a) ? "TRUE" : "FALSE")
     
    202206    CARD8 *fonts;
    203207    vgaRegRec vgaRegs;  /* Space for saving VGA information */
    204     /* DGA info */
    205     DGAModePtr pDGAMode;
    206     int nDGAMode;
    207208    CloseScreenProcPtr CloseScreen;
    208209    /** Default X server procedure for enabling and disabling framebuffer access */
     
    212213    OptionInfoPtr Options;
    213214    IOADDRESS ioBase;
     215    /** The width of the last resolution set, used to avoid resetting modes */
     216    int cLastWidth;
     217    /** The height of the last resolution set */
     218    int cLastHeight;
    214219    VMMDevReqMousePointer *reqp;
    215220    xf86CursorInfoPtr pCurs;
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_70.c

    r26493 r27529  
    5151 * Authors: Paulo César Pereira de Andrade <[email protected]>
    5252 */
    53 
    54 #ifdef DEBUG_michael
    55 # define DEBUG_VIDEO 1
    56 #endif
    57 #ifdef DEBUG_VIDEO
    58 
    59 #define TRACE \
    60 do { \
    61     xf86Msg(X_INFO, __PRETTY_FUNCTION__); \
    62     xf86Msg(X_INFO, ": entering\n"); \
    63 } while(0)
    64 #define TRACE2 \
    65 do { \
    66     xf86Msg(X_INFO, __PRETTY_FUNCTION__); \
    67     xf86Msg(X_INFO, ": leaving\n"); \
    68 } while(0)
    69 #define TRACE3(...) \
    70 do { \
    71     xf86Msg(X_INFO, __PRETTY_FUNCTION__); \
    72     xf86Msg(X_INFO, __VA_ARGS__); \
    73 } while(0)
    74 
    75 #else  /* DEBUG_VIDEO not defined */
    76 
    77 #define TRACE       do { } while(0)
    78 #define TRACE2      do { } while(0)
    79 #define TRACE3(...) do { } while(0)
    80 
    81 #endif  /* DEBUG_VIDEO not defined */
    8253
    8354#ifdef XORG_7X
     
    132103static Bool VBOXSaveRestore(ScrnInfoPtr pScrn,
    133104                            vbeSaveRestoreFunction function);
    134 
    135 /* Initialise DGA */
    136 
    137 static Bool VBOXDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen);
     105static void vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent);
     106static bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, DisplayModePtr pMode);
    138107
    139108/*
     
    387356}
    388357
     358/**
     359 * Fills a display mode M with a built-in mode of name pszName and dimensions
     360 * cx and cy.
     361 */
     362static void vboxFillDisplayMode(DisplayModePtr m, const char *pszName,
     363                                unsigned cx, unsigned cy)
     364{
     365    TRACE_LOG("pszName=%s, cx=%u, cy=%u\n", pszName, cx, cy);
     366    m->status        = MODE_OK;
     367    m->type          = M_T_BUILTIN;
     368    /* VBox only supports screen widths which are a multiple of 8 */
     369    m->HDisplay      = cx & ~7;
     370    m->HSyncStart    = m->HDisplay + 2;
     371    m->HSyncEnd      = m->HDisplay + 4;
     372    m->HTotal        = m->HDisplay + 6;
     373    m->VDisplay      = cy;
     374    m->VSyncStart    = m->VDisplay + 2;
     375    m->VSyncEnd      = m->VDisplay + 4;
     376    m->VTotal        = m->VDisplay + 6;
     377    m->Clock         = m->HTotal * m->VTotal * 60 / 1000; /* kHz */
     378    if (pszName)
     379    {
     380        if (m->name)
     381            xfree(m->name);
     382        m->name      = xnfstrdup(pszName);
     383    }
     384}
     385
     386/** vboxvideo's list of standard video modes */
     387struct
     388{
     389    /** mode width */
     390    uint32_t cx;
     391    /** mode height */
     392    uint32_t cy;   
     393} vboxStandardModes[] =
     394{
     395    { 1600, 1200 },
     396    { 1440, 1050 },
     397    { 1280, 960 },
     398    { 1024, 768 },
     399    { 800, 600 },
     400    { 640, 480 },
     401    { 0, 0 }
     402};
     403enum
     404{
     405    vboxNumStdModes = sizeof(vboxStandardModes) / sizeof(vboxStandardModes[0])
     406};
     407
     408/**
     409 * Returns a standard mode which the host likes.  Can be called multiple
     410 * times with the index returned by the previous call to get a list of modes.
     411 * @returns  the index of the mode in the list, or 0 if no more modes are
     412 *           available
     413 * @param    pScrn   the screen information structure
     414 * @param    pScrn->bitsPerPixel
     415 *                   if this is non-null, only modes with this BPP will be
     416 *                   returned
     417 * @param    cIndex  the index of the last mode queried, or 0 to query the
     418 *                   first mode available.  Note: the first index is 1
     419 * @param    pcx     where to store the mode's width
     420 * @param    pcy     where to store the mode's height
     421 * @param    pcBits  where to store the mode's BPP
     422 */
     423static unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,
     424                                     uint32_t *pcx, uint32_t *pcy,
     425                                     uint32_t *pcBits)
     426{
     427    XF86ASSERT(cIndex < vboxNumStdModes,
     428               ("cIndex = %d, vboxNumStdModes = %d\n", cIndex,
     429                vboxNumStdModes));
     430    for (unsigned i = cIndex; i < vboxNumStdModes - 1; ++i)
     431    {
     432        uint32_t cBits = pScrn->bitsPerPixel;
     433        uint32_t cx = vboxStandardModes[i].cx;
     434        uint32_t cy = vboxStandardModes[i].cy;
     435
     436        if (cBits != 0 && !vboxHostLikesVideoMode(pScrn, cx, cy, cBits))
     437            continue;
     438        if (vboxHostLikesVideoMode(pScrn, cx, cy, 32))
     439            cBits = 32;
     440        else if (vboxHostLikesVideoMode(pScrn, cx, cy, 16))
     441            cBits = 16;
     442        else
     443            continue;
     444        if (pcx)
     445            *pcx = cx;
     446        if (pcy)
     447            *pcy = cy;
     448        if (pcBits)
     449            *pcBits = cBits;
     450        return i + 1;
     451    }
     452    return 0;
     453}
     454
     455/**
     456 * Returns the preferred video mode.  The current order of preference is
     457 * (from highest to least preferred):
     458 *  - The mode corresponding to the last size hint from the host
     459 *  - The video mode saved from the last session
     460 *  - The largest standard mode which the host likes, falling back to
     461 *    640x480x32 as a worst case
     462 *  - If the host can't be contacted at all, we return 1024x768x32
     463 *
     464 * The return type is void as we guarantee we will return some mode.
     465 */
     466static void vboxGetPreferredMode(ScrnInfoPtr pScrn, uint32_t *pcx,
     467                                 uint32_t *pcy, uint32_t *pcBits)
     468{
     469    /* Query the host for the preferred resolution and colour depth */
     470    uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 32;
     471    VBOXPtr pVBox = pScrn->driverPrivate;
     472
     473    TRACE_ENTRY();
     474    if (pVBox->useDevice)
     475    {
     476        bool found = vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits, &iDisplay);
     477        if ((cx == 0) || (cy == 0))
     478            found = false;
     479        if (!found)
     480            found = vboxRetrieveVideoMode(pScrn, &cx, &cy, &cBits);
     481        if ((cx == 0) || (cy == 0))
     482            found = false;
     483        if (found)
     484            /* Adjust to a multiple of eight */
     485            cx -= cx % 8;
     486        if (!found)
     487            found = (vboxNextStandardMode(pScrn, 0, &cx, &cy, &cBits) != 0);
     488        if (!found)
     489        {
     490            /* Last resort */
     491            cx = 640;
     492            cy = 480;
     493            cBits = 32;
     494        }
     495    }
     496    else
     497    {
     498        cx = 1024;
     499        cy = 768;
     500    }
     501    if (pcx)
     502        *pcx = cx;
     503    if (pcy)
     504        *pcy = cy;
     505    if (pcx)
     506        *pcBits = cBits;
     507}
     508
     509/* Move a screen mode found to the end of the list, so that RandR will give
     510 * it the highest priority when a mode switch is requested.  Returns the mode
     511 * that was previously before the mode in the list in order to allow the
     512 * caller to continue walking the list. */
     513static DisplayModePtr vboxMoveModeToFront(ScrnInfoPtr pScrn,
     514                                          DisplayModePtr pMode)
     515{
     516    DisplayModePtr pPrev = pMode->prev;
     517    if (pMode != pScrn->modes)
     518    {
     519        pMode->prev->next = pMode->next;
     520        pMode->next->prev = pMode->prev;
     521        pMode->next = pScrn->modes;
     522        pMode->prev = pScrn->modes->prev;
     523        pMode->next->prev = pMode;
     524        pMode->prev->next = pMode;
     525        pScrn->modes = pMode;
     526    }
     527    return pPrev;
     528}
     529
     530/**
     531 * Rewrites the first dynamic mode found which is not the current screen mode
     532 * to contain the host's currently preferred screen size, then moves that
     533 * mode to the front of the screen information structure's mode list.
     534 * Additionally, if the current mode is not dynamic, the second dynamic mode
     535 * will be set to match the current mode and also added to the front.  This
     536 * ensures that the user can always reset the current size to kick the driver
     537 * to update its mode list.
     538 */
     539static void vboxWriteHostModes(ScrnInfoPtr pScrn, DisplayModePtr pCurrent)
     540{
     541    uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 0;
     542    DisplayModePtr pMode;
     543    bool found = false;
     544
     545    TRACE_ENTRY();
     546    vboxGetPreferredMode(pScrn, &cx, &cy, &cBits);
     547#ifdef DEBUG
     548    /* Count the number of modes for sanity */
     549    unsigned cModes = 1, cMode = 0;
     550    DisplayModePtr pCount;
     551    for (pCount = pScrn->modes; ; pCount = pCount->next, ++cModes)
     552        if (pCount->next == pScrn->modes)
     553            break;
     554#endif
     555    for (pMode = pScrn->modes; ; pMode = pMode->next)
     556    {
     557#ifdef DEBUG
     558        XF86ASSERT (cMode++ < cModes, (NULL));
     559#endif
     560        if (   pMode != pCurrent
     561            && !strcmp(pMode->name, "VBoxDynamicMode"))
     562        {
     563            if (!found)
     564                vboxFillDisplayMode(pMode, NULL, cx, cy);
     565            else if (pCurrent)
     566                vboxFillDisplayMode(pMode, NULL, pCurrent->HDisplay,
     567                                    pCurrent->VDisplay);
     568            found = true;
     569            pMode = vboxMoveModeToFront(pScrn, pMode);
     570        }
     571        if (pMode->next == pScrn->modes)
     572            break;
     573    }
     574    XF86ASSERT (found,
     575                ("vboxvideo: no free dynamic mode found.  Exiting.\n"));
     576    XF86ASSERT (   (pScrn->modes->HDisplay == (long) cx)
     577                || (   (pScrn->modes->HDisplay == pCurrent->HDisplay)
     578                    && (pScrn->modes->next->HDisplay == (long) cx)),
     579                ("pScrn->modes->HDisplay=%u, pScrn->modes->next->HDisplay=%u\n",
     580                 pScrn->modes->HDisplay, pScrn->modes->next->HDisplay));
     581    XF86ASSERT (   (pScrn->modes->VDisplay == (long) cy)
     582                || (   (pScrn->modes->VDisplay == pCurrent->VDisplay)
     583                    && (pScrn->modes->next->VDisplay == (long) cy)),
     584                ("pScrn->modes->VDisplay=%u, pScrn->modes->next->VDisplay=%u\n",
     585                 pScrn->modes->VDisplay, pScrn->modes->next->VDisplay));
     586}
     587
     588/**
     589 * Allocates an empty display mode and links it into the doubly linked list of
     590 * modes pointed to by pScrn->modes.  Returns a pointer to the newly allocated
     591 * memory.
     592 */
     593static DisplayModePtr vboxAddEmptyScreenMode(ScrnInfoPtr pScrn)
     594{
     595    DisplayModePtr pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
     596
     597    TRACE_ENTRY();
     598    if (!pScrn->modes)
     599    {
     600        pScrn->modes = pMode;
     601        pMode->next = pMode;
     602        pMode->prev = pMode;
     603    }
     604    else
     605    {
     606        pMode->next = pScrn->modes;
     607        pMode->prev = pScrn->modes->prev;
     608        pMode->next->prev = pMode;
     609        pMode->prev->next = pMode;
     610    }
     611    return pMode;
     612}
     613
     614/**
     615 * Create display mode entries in the screen information structure for each
     616 * of the initial graphics modes that we wish to support.  This includes:
     617 *  - An initial mode, of the size requested by the caller
     618 *  - Two dynamic modes, one of which will be updated to match the last size
     619 *    hint from the host on each mode switch, but initially also of the
     620 *    requested size
     621 *  - Several standard modes, if possible ones that the host likes
     622 *  - Any modes that the user requested in xorg.conf/XFree86Config
     623 */
     624static void
     625vboxAddModes(ScrnInfoPtr pScrn, uint32_t cxInit, uint32_t cyInit)
     626{
     627    unsigned cx = 0, cy = 0, cIndex = 0;
     628    /* For reasons related to the way RandR 1.1 is implemented, we need to
     629     * make sure that the initial mode (more precisely, a mode equal to the
     630     * initial virtual resolution) is always present in the mode list.  RandR
     631     * has the assumption build in that there will either be a mode of that
     632     * size present at all times, or that the first mode in the list will
     633     * always be smaller than the initial virtual resolution.  Since our
     634     * approach to dynamic resizing isn't quite the way RandR was intended to
     635     * be, and breaks the second assumption, we guarantee the first. */
     636    DisplayModePtr pMode = vboxAddEmptyScreenMode(pScrn);
     637    vboxFillDisplayMode(pMode, "VBoxInitialMode", cxInit, cyInit);
     638    /* Create our two dynamic modes. */
     639    pMode = vboxAddEmptyScreenMode(pScrn);
     640    vboxFillDisplayMode(pMode, "VBoxDynamicMode", cxInit, cyInit);
     641    pMode = vboxAddEmptyScreenMode(pScrn);
     642    vboxFillDisplayMode(pMode, "VBoxDynamicMode", cxInit, cyInit);
     643    /* Add standard modes supported by the host */
     644    for ( ; ; )
     645    {
     646        char szName[256];
     647        cIndex = vboxNextStandardMode(pScrn, cIndex, &cx, &cy, NULL);
     648        if (cIndex == 0)
     649            break;
     650        sprintf(szName, "VBox-%ux%u", cx, cy);
     651        pMode = vboxAddEmptyScreenMode(pScrn);
     652        vboxFillDisplayMode(pMode, szName, cx, cy);
     653    }
     654    /* And finally any modes specified by the user.  We assume here that
     655     * the mode names reflect the mode sizes. */
     656    for (unsigned i = 0;    pScrn->display->modes != NULL
     657                         && pScrn->display->modes[i] != NULL; i++)
     658    {
     659        if (sscanf(pScrn->display->modes[i], "%ux%u", &cx, &cy) == 2)
     660        {
     661            pMode = vboxAddEmptyScreenMode(pScrn);
     662            vboxFillDisplayMode(pMode, pScrn->display->modes[i], cx, cy);
     663        }
     664    }
     665}
     666
    389667/*
    390668 * QUOTE from the XFree86 DESIGN document:
     
    417695    Gamma gzeros = {0.0, 0.0, 0.0};
    418696    rgb rzeros = {0, 0, 0};
    419     ClockRange *clockRanges;
    420697    int i;
    421     DisplayModePtr m_prev;
    422     char szHostModeName[256] = "";
    423 
     698    DisplayModePtr pMode;
     699    enum { MODE_MIN_SIZE = 64 };
     700
     701    TRACE_ENTRY();
    424702    /* Are we really starting the server, or is this just a dummy run? */
    425703    if (flags & PROBE_DETECT)
     
    493771
    494772    /* Set up clock information that will support all modes we need. */
    495     clockRanges = xnfcalloc(sizeof(ClockRange), 1);
    496     clockRanges->next = NULL;
    497     clockRanges->minClock = 1000;
    498     clockRanges->maxClock = 1000000000;
    499     clockRanges->clockIndex = -1;
    500     clockRanges->ClockMulFactor = 1;
    501     clockRanges->ClockDivFactor = 1;
    502 
    503     /* Query the host for the preferred resolution and colour depth */
    504     {
    505         uint32_t cx = 0, cy = 0, iDisplay = 0, cBits = 24;
    506 
    507         if (vboxGetDisplayChangeRequest(pScrn, &cx, &cy, &cBits, &iDisplay))
    508         {
    509             /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
    510             if (cBits != 16)
    511                 cBits = 24;
    512             if ((0 != cx) && (0 != cy)) {
    513                 cx -= cx % 8;
    514                 xf86sprintf(szHostModeName, "%dx%d", cx, cy);
    515             }
    516         }
     773    pScrn->clockRanges = xnfcalloc(sizeof(ClockRange), 1);
     774    pScrn->clockRanges->minClock = 1000;
     775    pScrn->clockRanges->maxClock = 1000000000;
     776    pScrn->clockRanges->clockIndex = -1;
     777    pScrn->clockRanges->ClockMulFactor = 1;
     778    pScrn->clockRanges->ClockDivFactor = 1;
     779
     780    /* Determine the preferred size and colour depth and setup video modes */
     781    {
     782        uint32_t cx = 0, cy = 0, cBits = 0;
     783
     784        vboxGetPreferredMode(pScrn, &cx, &cy, &cBits);
     785        /* We only support 16 and 24 bits depth (i.e. 16 and 32bpp) */
     786        if (cBits != 16)
     787            cBits = 24;
    517788        if (!xf86SetDepthBpp(pScrn, cBits, 0, 0, Support32bppFb))
    518789            return FALSE;
     790        vboxAddModes(pScrn, cx, cy);
    519791    }
    520792    if (pScrn->bitsPerPixel != 32 && pScrn->bitsPerPixel != 16)
     
    525797    }
    526798    xf86PrintDepthBpp(pScrn);
    527 
    528     /* To get around the problem of SUSE specifying a single, invalid mode in their
    529      * Xorg.conf by default, we add additional modes to the end of the user specified
    530      * list. This means that if all user modes are invalid, X will try our mode before
    531      * falling back to its standard mode list. */
    532     if (pScrn->display->modes == NULL)
    533     {
    534         i = 0;
    535         /* The user specified no modes at all. */
    536         pScrn->display->modes = xnfalloc(5 * sizeof(char*));
    537     }
    538     else
    539     {
    540         for (i = 0; pScrn->display->modes[i] != NULL; i++);
    541         pScrn->display->modes =   xnfrealloc(pScrn->display->modes, (i + 5)
    542                                 * sizeof(char *));
    543     }
    544     /* Add additional modes to the end of the mode list in case the others are
    545        all invalid. */
    546     if (szHostModeName[0])
    547     {
    548         pScrn->display->modes[i] = szHostModeName;
    549         ++i;
    550     }
    551     if (vboxHostLikesVideoMode(pScrn, 1600, 1200, pScrn->bitsPerPixel))
    552     {
    553         pScrn->display->modes[i] = "1600x1200";
    554         ++i;
    555     }
    556     if (vboxHostLikesVideoMode(pScrn, 1440, 1050, pScrn->bitsPerPixel))
    557     {
    558         pScrn->display->modes[i] = "1440x1050";
    559         ++i;
    560     }
    561     if (vboxHostLikesVideoMode(pScrn, 1280, 960, pScrn->bitsPerPixel))
    562     {
    563         pScrn->display->modes[i] = "1280x960";
    564         ++i;
    565     }
    566     if (vboxHostLikesVideoMode(pScrn, 1024, 768, pScrn->bitsPerPixel))
    567     {
    568         pScrn->display->modes[i] = "1024x768";
    569         ++i;
    570     }
    571     if (vboxHostLikesVideoMode(pScrn, 800, 600, pScrn->bitsPerPixel))
    572     {
    573         pScrn->display->modes[i] = "800x600";
    574         ++i;
    575     }
    576     /* A mode of last resort */
    577     pScrn->display->modes[i] = "640x480";
    578     ++i;
    579     pScrn->display->modes[i] = NULL;
    580 
    581     /* Create a builtin mode for every specified mode. This allows to specify arbitrary
    582      * screen resolutions */
    583     m_prev = NULL;
    584     for (i = 0; pScrn->display->modes[i] != NULL; i++)
    585     {
    586         DisplayModePtr m;
    587         int x = 0, y = 0;
    588 
    589         if (sscanf(pScrn->display->modes[i], "%dx%d", &x, &y) == 2)
    590         {
    591             m                = xnfcalloc(sizeof(DisplayModeRec), 1);
    592             m->status        = MODE_OK;
    593             m->type          = M_T_BUILTIN;
    594             /* VBox only supports screen widths which are a multiple of 8 */
    595             m->HDisplay      = (x + 7) & ~7;
    596             m->HSyncStart    = m->HDisplay + 2;
    597             m->HSyncEnd      = m->HDisplay + 4;
    598             m->HTotal        = m->HDisplay + 6;
    599             m->VDisplay      = y;
    600             m->VSyncStart    = m->VDisplay + 2;
    601             m->VSyncEnd      = m->VDisplay + 4;
    602             m->VTotal        = m->VDisplay + 6;
    603             m->Clock         = m->HTotal * m->VTotal * 60 / 1000; /* kHz */
    604             m->name          = strdup(pScrn->display->modes[i]);
    605             if (!m_prev)
    606                 pScrn->modePool = m;
    607             else
    608                 m_prev->next = m;
    609             m->prev = m_prev;
    610             m_prev  = m;
    611         }
    612     }
    613799
    614800    /* Colour weight - we always call this, since we are always in
     
    623809    xf86SetGamma(pScrn, gzeros);
    624810
    625     /* Set a sane minimum mode size and the maximum allowed by the available VRAM */
    626     {
    627         unsigned maxSize, trySize = 512;
    628 
    629         do {
    630             maxSize = trySize;
    631             trySize += 128;
    632         } while (trySize * trySize * pScrn->bitsPerPixel / 8 < (unsigned)pScrn->videoRam * 1024);
    633 
    634         /* I don't know exactly what these are for (and they are only used in a couple
    635            of places in the X server code). */
    636         pScrn->display->virtualX = maxSize;
    637         pScrn->display->virtualY = maxSize;
    638         xf86DrvMsg(pScrn->scrnIndex, X_INFO,
    639                    "The maximum supported resolution is currently %dx%d\n", maxSize, maxSize);
    640     }
    641 
    642     /* Filter out video modes not supported by the virtual hardware
    643        we described. */
    644     i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
    645                           pScrn->display->modes,
    646                           clockRanges, NULL, 64, pScrn->display->virtualX, 1,
    647                           64, pScrn->display->virtualY, 0, 0,
    648                           pScrn->videoRam * 1024, LOOKUP_BEST_REFRESH);
    649 
    650     if (i <= 0) {
    651         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No usable graphics modes found.\n");
    652         return (FALSE);
    653     }
    654     xf86PruneDriverModes(pScrn);
     811    /* We don't validate with xf86ValidateModes and xf86PruneModes as we
     812     * already know what we like and what we don't. */
    655813
    656814    pScrn->currentMode = pScrn->modes;
     815
     816    /* Set the right virtual resolution. */
     817    pScrn->virtualX = pScrn->currentMode->HDisplay;
     818    pScrn->virtualY = pScrn->currentMode->VDisplay;
     819
    657820    pScrn->displayWidth = pScrn->virtualX;
    658821
    659822    xf86PrintModes(pScrn);
    660823
    661     /* Set display resolution.  Perhaps we should read this from the host. */
     824    /* Set the DPI.  Perhaps we should read this from the host? */
    662825    xf86SetDpi(pScrn, 96, 96);
    663 
    664     if (pScrn->modes == NULL) {
    665         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No graphics modes available\n");
    666         return (FALSE);
    667     }
    668826
    669827    /* options */
     
    676834    /* Framebuffer-related setup */
    677835    pScrn->bitmapBitOrder = BITMAP_BIT_ORDER;
     836    TRACE_EXIT();
    678837    return (TRUE);
    679838}
     
    691850 * mode.
    692851 *
    693  * End QUOTE.Initialise the initial video mode.
     852 * End QUOTE.
    694853 */
    695854static Bool
     
    701860    unsigned flags;
    702861
     862    TRACE_ENTRY();
    703863    /* We make use of the X11 VBE code to save and restore text mode, in
    704864       order to keep our code simple. */
     
    724884    pVBox->savedPal = VBESetGetPaletteData(pVBox->pVbe, FALSE, 0, 256,
    725885                                           NULL, FALSE, FALSE);
    726 
    727     /* set first video mode */
    728     if (!VBOXSetMode(pScrn, pScrn->currentMode))
    729         return FALSE;
    730886
    731887    /* set the viewport */
     
    769925    fbPictureInit(pScreen, 0, 0);
    770926
    771     VBOXDGAInit(pScrn, pScreen);
    772 
    773927    xf86SetBlackWhitePixels(pScreen);
    774928    miInitializeBackingStore(pScreen);
     
    800954    if (serverGeneration == 1)
    801955        xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
     956
     957    /* set first video mode */
     958    if (!VBOXSetMode(pScrn, pScrn->currentMode))
     959        return FALSE;
     960    /* And make sure that a non-current dynamic mode is at the front of the
     961     * list */
     962    vboxWriteHostModes(pScrn, pScrn->currentMode);
    802963
    803964    if (vbox_open (pScrn, pScreen, pVBox)) {
     
    809970                      "The VBox video extensions are now enabled.\n");
    810971    }
     972    TRACE_EXIT();
    811973    return (TRUE);
    812974}
     
    8521014        VBOXUnmapVidMem(pScrn);
    8531015    }
    854     if (pVBox->pDGAMode) {
    855         xfree(pVBox->pDGAMode);
    856         pVBox->pDGAMode = NULL;
    857         pVBox->nDGAMode = 0;
    858     }
    8591016    pScrn->vtSema = FALSE;
    8601017
     
    8761033    if (VBOXSetMode(pScrn, pMode) != TRUE)
    8771034        return FALSE;
     1035    if (VBOXAdjustScreenPixmap(pScrn, pMode) != TRUE)
     1036        return FALSE;
     1037    vboxSaveVideoMode(pScrn, pMode->HDisplay, pMode->VDisplay,
     1038                      pScrn->bitsPerPixel);
     1039    vboxWriteHostModes(pScrn, pMode);
     1040    xf86PrintModes(pScrn);
    8781041    if (pVBox->useVbva == TRUE)
    8791042        if (vboxEnableVbva(pScrn) != TRUE)  /* Bad but not fatal */
     
    8861049VBOXSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
    8871050{
     1051    TRACE_ENTRY();
    8881052    int bpp = pScrn->depth == 24 ? 32 : 16;
    889     int xRes = pMode->HDisplay;
    8901053    VBOXPtr pVBox = VBOXGetRec(pScrn);
    8911054
     
    8981061        return FALSE;
    8991062    }
    900     /* We only support horizontal resolutions which are a multiple of 8.  Round down if
    901        necessary. */
    902     if (xRes % 8 != 0)
    903     {
    904         xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
    905                    "VirtualBox only supports screen widths which are a multiple of 8.  Rounding down from %d to %d\n",
    906                    xRes, xRes - (xRes % 8));
    907         xRes = xRes - (xRes % 8);
    908     }
    909 
    910     /* We force a software cursor if the guests virtual resolution is different
    911      * to it's actual resolution, as in this case host and guest will disagree
    912      * about the pointer position. */
    913     if (   (pScrn->virtualX - xRes >= 8)
    914         || (pScrn->virtualY - pMode->VDisplay >= 8))
    915         pVBox->forceSWCursor = TRUE;
    916     else
    917         pVBox->forceSWCursor = FALSE;
     1063    /* Do not reset the current mode - we use this as a way of kicking
     1064     * the driver */
     1065    if (   (pMode->HDisplay == pVBox->cLastWidth)
     1066        && (pMode->VDisplay == pVBox->cLastHeight))
     1067        return TRUE;
    9181068
    9191069    pScrn->vtSema = TRUE;
     
    9291079       the display part of the scanlines. */
    9301080    outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES);
    931     outw(VBE_DISPI_IOPORT_DATA, xRes);
     1081    outw(VBE_DISPI_IOPORT_DATA, pMode->HDisplay);
    9321082    outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES);
    9331083    outw(VBE_DISPI_IOPORT_DATA, pMode->VDisplay);
     
    9391089       the virtual offset. */
    9401090    outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_VIRT_WIDTH);
    941     outw(VBE_DISPI_IOPORT_DATA, pScrn->displayWidth);
     1091    outw(VBE_DISPI_IOPORT_DATA, pMode->HDisplay);
     1092    pVBox->cLastWidth = pMode->HDisplay;
     1093    pVBox->cLastHeight = pMode->VDisplay;
     1094    TRACE_EXIT();
    9421095    return (TRUE);
     1096}
     1097
     1098static bool VBOXAdjustScreenPixmap(ScrnInfoPtr pScrn, DisplayModePtr pMode)
     1099{
     1100    ScreenPtr pScreen = pScrn->pScreen;
     1101    PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
     1102    VBOXPtr pVBox = VBOXGetRec(pScrn);
     1103    int bpp = pScrn->depth == 24 ? 32 : 16;
     1104    if (!pPixmap) {
     1105        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
     1106                   "Failed to get the screen pixmap.\n");
     1107        return FALSE;
     1108    }
     1109    pScreen->ModifyPixmapHeader(pPixmap, pMode->HDisplay, pMode->VDisplay,
     1110                                pScrn->depth, bpp, pMode->HDisplay * bpp / 8,
     1111                                pVBox->base);
     1112    pScrn->EnableDisableFBAccess(pScrn->scrnIndex, FALSE);
     1113    pScrn->EnableDisableFBAccess(pScrn->scrnIndex, TRUE);
     1114    return TRUE;
    9431115}
    9441116
     
    13211493}
    13221494
    1323 
    1324 
    1325 
    1326 /***********************************************************************
    1327  * DGA stuff
    1328  ***********************************************************************/
    1329 static Bool VBOXDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName,
    1330                                    unsigned char **ApertureBase,
    1331                                    int *ApertureSize, int *ApertureOffset,
    1332                                    int *flags);
    1333 static Bool VBOXDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode);
    1334 static void VBOXDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags);
    1335 
    1336 static Bool
    1337 VBOXDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName,
    1338                        unsigned char **ApertureBase, int *ApertureSize,
    1339                        int *ApertureOffset, int *flags)
    1340 {
    1341     VBOXPtr pVBox = VBOXGetRec(pScrn);
    1342 
    1343     *DeviceName = NULL;         /* No special device */
    1344     *ApertureBase = (unsigned char *)(long)(pVBox->mapPhys);
    1345     *ApertureSize = pVBox->mapSize;
    1346     *ApertureOffset = pVBox->mapOff;
    1347     *flags = DGA_NEED_ROOT;
    1348 
    1349     return (TRUE);
    1350 }
    1351 
    1352 static Bool
    1353 VBOXDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode)
    1354 {
    1355     DisplayModePtr pMode;
    1356     int scrnIdx = pScrn->pScreen->myNum;
    1357     int frameX0, frameY0;
    1358 
    1359     if (pDGAMode) {
    1360         pMode = pDGAMode->mode;
    1361         frameX0 = frameY0 = 0;
    1362     }
    1363     else {
    1364         if (!(pMode = pScrn->currentMode))
    1365             return (TRUE);
    1366 
    1367         frameX0 = pScrn->frameX0;
    1368         frameY0 = pScrn->frameY0;
    1369     }
    1370 
    1371     if (!(*pScrn->SwitchMode)(scrnIdx, pMode, 0))
    1372         return (FALSE);
    1373     (*pScrn->AdjustFrame)(scrnIdx, frameX0, frameY0, 0);
    1374 
    1375     return (TRUE);
    1376 }
    1377 
    1378 static void
    1379 VBOXDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
    1380 {
    1381     (*pScrn->AdjustFrame)(pScrn->pScreen->myNum, x, y, flags);
    1382 }
    1383 
    1384 static int
    1385 VBOXDGAGetViewport(ScrnInfoPtr pScrn)
    1386 {
    1387     return (0);
    1388 }
    1389 
    1390 static DGAFunctionRec VBOXDGAFunctions =
    1391 {
    1392     VBOXDGAOpenFramebuffer,
    1393     NULL,       /* CloseFramebuffer */
    1394     VBOXDGASetMode,
    1395     VBOXDGASetViewport,
    1396     VBOXDGAGetViewport,
    1397     NULL,       /* Sync */
    1398     NULL,       /* FillRect */
    1399     NULL,       /* BlitRect */
    1400     NULL,       /* BlitTransRect */
    1401 };
    1402 
    1403 static void
    1404 VBOXDGAAddModes(ScrnInfoPtr pScrn)
    1405 {
    1406     VBOXPtr pVBox = VBOXGetRec(pScrn);
    1407     DisplayModePtr pMode = pScrn->modes;
    1408     DGAModePtr pDGAMode;
    1409 
    1410     do {
    1411         pDGAMode = xrealloc(pVBox->pDGAMode,
    1412                             (pVBox->nDGAMode + 1) * sizeof(DGAModeRec));
    1413         if (!pDGAMode)
    1414             break;
    1415 
    1416         pVBox->pDGAMode = pDGAMode;
    1417         pDGAMode += pVBox->nDGAMode;
    1418         (void)memset(pDGAMode, 0, sizeof(DGAModeRec));
    1419 
    1420         ++pVBox->nDGAMode;
    1421         pDGAMode->mode = pMode;
    1422         pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
    1423         pDGAMode->byteOrder = pScrn->imageByteOrder;
    1424         pDGAMode->depth = pScrn->depth;
    1425         pDGAMode->bitsPerPixel = pScrn->bitsPerPixel;
    1426         pDGAMode->red_mask = pScrn->mask.red;
    1427         pDGAMode->green_mask = pScrn->mask.green;
    1428         pDGAMode->blue_mask = pScrn->mask.blue;
    1429         pDGAMode->visualClass = TrueColor;
    1430         pDGAMode->xViewportStep = 1;
    1431         pDGAMode->yViewportStep = 1;
    1432         pDGAMode->viewportWidth = pMode->HDisplay;
    1433         pDGAMode->viewportHeight = pMode->VDisplay;
    1434 
    1435         pDGAMode->bytesPerScanline = pVBox->maxBytesPerScanline;
    1436         pDGAMode->imageWidth = pMode->HDisplay;
    1437         pDGAMode->imageHeight =  pMode->VDisplay;
    1438         pDGAMode->pixmapWidth = pDGAMode->imageWidth;
    1439         pDGAMode->pixmapHeight = pDGAMode->imageHeight;
    1440         pDGAMode->maxViewportX = pScrn->virtualX -
    1441                                     pDGAMode->viewportWidth;
    1442         pDGAMode->maxViewportY = pScrn->virtualY -
    1443                                     pDGAMode->viewportHeight;
    1444 
    1445         pDGAMode->address = pVBox->base;
    1446 
    1447         pMode = pMode->next;
    1448     } while (pMode != pScrn->modes);
    1449 }
    1450 
    1451 static Bool
    1452 VBOXDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen)
    1453 {
    1454     VBOXPtr pVBox = VBOXGetRec(pScrn);
    1455 
    1456     if (!pVBox->nDGAMode)
    1457         VBOXDGAAddModes(pScrn);
    1458 
    1459     return (DGAInit(pScreen, &VBOXDGAFunctions,
    1460             pVBox->pDGAMode, pVBox->nDGAMode));
    1461 }
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