VirtualBox

Ignore:
Timestamp:
Dec 12, 2014 8:44:49 PM (10 years ago)
Author:
vboxsync
Message:

Additions/common and Additions/x11: add support for getting video mode hints through the VGA device.

Location:
trunk/src/VBox/Additions/x11/vboxvideo
Files:
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/vboxvideo/getmode.c

    r53513 r53530  
    11/* $Id$ */
    22/** @file
    3  * VirtualBox X11 Additions graphics driver utility functions
     3 * VirtualBox X11 Additions graphics driver dynamic video mode functions.
    44 */
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2014 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    2323#include "xf86.h"
    2424#include "dixstruct.h"
     25#ifdef VBOX_GUESTR3XF86MOD
     26# define EXTENSION_PROC_ARGS char *name, GCPtr pGC
     27#endif
    2528#include "extnsionst.h"
    2629#include "windowstr.h"
     
    3336#endif
    3437
     38#ifdef VBOXVIDEO_13
     39# ifdef RT_OS_LINUX
     40# include "randrstr.h"
     41# include "xf86_OSproc.h"
     42#  include <linux/input.h>
     43#  include <dirent.h>
     44#  include <errno.h>
     45#  include <fcntl.h>
     46#  include <unistd.h>
     47# endif /* RT_OS_LINUX */
     48#endif /* VBOXVIDEO_13 */
    3549/**************************************************************************
    3650* Main functions                                                          *
     
    217231        pVBox->pScreens[i].aPreferredSize.cx = 1024;
    218232        pVBox->pScreens[i].aPreferredSize.cy = 768;
     233        pVBox->pScreens[i].afConnected       = true;
    219234    }
    220235    /* Set up the first mode correctly to match the requested initial mode. */
     
    242257    unsigned i;
    243258
     259#ifdef VBOXVIDEO_13
     260    if (RT_SUCCESS(VBoxHGSMIGetModeHints(&pVBox->guestCtx, pVBox->cScreens,
     261                                         pVBox->paVBVAModeHints)))
     262    {
     263        for (i = 0; i < pVBox->cScreens; ++i)
     264        {
     265            if (pVBox->paVBVAModeHints[i].magic == VBVAMODEHINT_MAGIC)
     266            {
     267                pVBox->pScreens[i].aPreferredSize.cx =
     268                    pVBox->paVBVAModeHints[i].cx;
     269                pVBox->pScreens[i].aPreferredSize.cy =
     270                    pVBox->paVBVAModeHints[i].cy;
     271                pVBox->pScreens[i].afConnected =
     272                    pVBox->paVBVAModeHints[i].fEnabled;
     273            }
     274        }
     275        return;
     276    }
     277#endif   
    244278    /* We can get called early, before the root window is created. */
    245279    if (!ROOT_WINDOW(pScrn))
     
    253287        for (i = 0; i < prop->size && i < pVBox->cScreens; ++i)
    254288        {
    255             if (((int32_t *)prop->data)[i] == 0)
    256             {
    257                 pVBox->pScreens[i].aPreferredSize.cx = 1024;
    258                 pVBox->pScreens[i].aPreferredSize.cy = 768;
    259             }
    260             else
     289            if (((int32_t *)prop->data)[i] != 0)
    261290            {
    262291                pVBox->pScreens[i].aPreferredSize.cx =
     
    384413
    385414#endif /* !VBOXVIDEO_13 */
     415
     416#ifdef VBOXVIDEO_13
     417# ifdef RT_OS_LINUX
     418static void acpiEventHandler(int fd, void *pvData)
     419{
     420    struct input_event event;
     421    ssize_t rc;
     422
     423    RRGetInfo((ScreenPtr)pvData
     424# if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 5
     425              , TRUE
     426# endif
     427             );
     428    do
     429        rc = read(fd, &event, sizeof(event));
     430    while (rc > 0 || (rc == -1 && errno == EINTR));
     431    if (rc == -1 && errno != EAGAIN)  /* Why not just return 0? */
     432        FatalError("Reading ACPI input event failed.\n");
     433}
     434
     435void VBoxSetUpLinuxACPI(ScreenPtr pScreen)
     436{
     437    VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
     438    struct dirent *pDirent;
     439    DIR *pDir;
     440    int fd = -1;
     441
     442    if (pVBox->fdACPIDevices != -1 || pVBox->hACPIEventHandler != NULL)
     443        FatalError("ACPI input file descriptor not initialised correctly.\n");
     444    pDir = opendir("/dev/input");
     445    if (pDir == NULL)
     446        return;
     447    for (pDirent = readdir(pDir); pDirent != NULL; pDirent = readdir(pDir))
     448    {
     449        if (strncmp(pDirent->d_name, "event", sizeof("event") - 1) == 0)
     450        {
     451#define BITS_PER_BLOCK (sizeof(unsigned long) * 8)
     452            char pszFile[64] = "/dev/input/";
     453            char pszDevice[64] = "";
     454            unsigned long afKeys[KEY_MAX / BITS_PER_BLOCK];
     455
     456            strncat(pszFile, pDirent->d_name, sizeof(pszFile));
     457            if (fd != -1)
     458                close(fd);
     459            fd = open(pszFile, O_RDONLY | O_NONBLOCK);
     460            if (   fd == -1
     461                || ioctl(fd, EVIOCGNAME(sizeof(pszDevice)), pszDevice) == -1
     462                || strcmp(pszDevice, "Video Bus") != 0)
     463                continue;
     464            if (   ioctl(fd, EVIOCGBIT(EV_KEY, KEY_MAX), afKeys) == -1
     465                || ((   afKeys[KEY_SWITCHVIDEOMODE / BITS_PER_BLOCK]
     466                     >> KEY_SWITCHVIDEOMODE % BITS_PER_BLOCK) & 1) == 0)
     467                break;
     468            if (ioctl(fd, EVIOCGRAB, (void *)1) != 0)
     469                break;
     470            pVBox->hACPIEventHandler
     471                = xf86AddGeneralHandler(fd, acpiEventHandler, pScreen);
     472            if (pVBox->hACPIEventHandler == NULL)
     473                break;
     474            /* We ignore the return value as the fall-back should be active
     475             * anyway. */
     476            VBoxHGSMISendCapsInfo(&pVBox->guestCtx, VBVACAPS_VIDEO_MODE_HINTS);
     477            pVBox->fdACPIDevices = fd;
     478            fd = -1;
     479            break;
     480#undef BITS_PER_BLOCK
     481        }
     482    }
     483    if (fd != -1)
     484        close(fd);
     485    closedir(pDir);
     486}
     487
     488void VBoxCleanUpLinuxACPI(ScreenPtr pScreen)
     489{
     490    VBOXPtr pVBox = VBOXGetRec(xf86Screens[pScreen->myNum]);
     491    if (pVBox->fdACPIDevices != -1)
     492        close(pVBox->fdACPIDevices);
     493    pVBox->fdACPIDevices = -1;
     494    xf86RemoveGeneralHandler(pVBox->hACPIEventHandler);
     495    pVBox->hACPIEventHandler = NULL;
     496}
     497# endif /* RT_OS_LINUX */
     498#endif /* VBOXVIDEO_13 */
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.c

    r53527 r53530  
    149149{
    150150    if (!pScrn->driverPrivate)
    151         pScrn->driverPrivate = calloc(sizeof(VBOXRec), 1);
     151    {
     152        VBOXPtr pVBox = (VBOXPtr)xnfcalloc(sizeof(VBOXRec), 1);
     153        pScrn->driverPrivate = pVBox;
     154#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
     155        pVBox->fdACPIDevices = -1;
     156#endif
     157    }
    152158}
    153159
     
    11411147#endif
    11421148
     1149#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
     1150    VBoxSetUpLinuxACPI(pScreen);
     1151#endif
     1152
    11431153    /* Report any unused options (only for the first generation) */
    11441154    if (serverGeneration == 1)
     
    12511261
    12521262    pScreen->CloseScreen = pVBox->CloseScreen;
     1263#if defined(VBOXVIDEO_13) && defined(RT_OS_LINUX)
     1264    VBoxCleanUpLinuxACPI(pScreen);
     1265#endif
    12531266#ifndef XF86_SCRN_INTERFACE
    12541267    return pScreen->CloseScreen(pScreen->myNum, pScreen);
  • trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo.h

    r53527 r53530  
    203203    /** The last requested framebuffer size. */
    204204    RTRECTSIZE FBSize;
    205 #ifndef VBOXVIDEO_13
     205#ifdef VBOXVIDEO_13
     206    /** Array of structures for receiving mode hints. */
     207    VBVAMODEHINT *paVBVAModeHints;
     208# ifdef RT_OS_LINUX
     209    /** Input device file descriptor for getting ACPI hot-plug events. */
     210    int fdACPIDevices;
     211    /** Input handler handle for ACPI hot-plug listener. */
     212    void *hACPIEventHandler;
     213# endif
     214#else
    206215    /** The original CreateScreenResources procedure which we wrap with our own.
    207216     */
     
    232241extern void vboxDisableVbva(ScrnInfoPtr pScrn);
    233242
     243/* getmode.c */
    234244extern unsigned vboxNextStandardMode(ScrnInfoPtr pScrn, unsigned cIndex,
    235245                                     uint32_t *pcx, uint32_t *pcy);
     
    239249#ifndef VBOXVIDEO_13
    240250extern void VBoxSetUpRandR11(ScreenPtr pScreen);
     251#else
     252void VBoxSetUpLinuxACPI(ScreenPtr pScreen);
     253void VBoxCleanUpLinuxACPI(ScreenPtr pScreen);
    241254#endif
    242255
  • trunk/src/VBox/Additions/x11/vboxvideo/vbva.c

    r52199 r53530  
    201201    if (pVBox->pScreens == NULL)
    202202        FatalError("Failed to allocate memory for screens array.\n");
     203#ifdef VBOXVIDEO_13
     204    pVBox->paVBVAModeHints = calloc(pVBox->cScreens,
     205                                    sizeof(*pVBox->paVBVAModeHints));
     206    if (pVBox->paVBVAModeHints == NULL)
     207        FatalError("Failed to allocate memory for mode hints array.\n");
     208#endif
    203209    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested monitor count: %u\n",
    204210               pVBox->cScreens);
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