getmode.c revision 4dfffd317fbef2019753944090bbbab9e53878fd
/* $Id$ */
/** @file
* VirtualBox X11 Additions graphics driver dynamic video mode functions.
*/
/*
* Copyright (C) 2006-2014 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#include "vboxvideo.h"
#define NEED_XF86_TYPES
#include "xf86.h"
#include "dixstruct.h"
#ifdef VBOX_GUESTR3XF86MOD
#endif
#include "extnsionst.h"
#include "windowstr.h"
#ifdef XORG_7X
# include <stdio.h>
# include <stdlib.h>
#endif
#ifdef VBOXVIDEO_13
# ifdef RT_OS_LINUX
# ifndef EVIOCGRAB
# endif
# ifndef KEY_SWITCHVIDEOMODE
# define KEY_SWITCHVIDEOMODE 227
# endif
# include <dirent.h>
# include <errno.h>
# include <fcntl.h>
# include <unistd.h>
# endif /* RT_OS_LINUX */
#endif /* VBOXVIDEO_13 */
/**************************************************************************
* Main functions *
**************************************************************************/
/**
* Fills a display mode M with a built-in mode of name pszName and dimensions
* cx and cy.
*/
{
char szName[256];
if (!pszName)
{
}
if (m->name)
memset(m, '\0', sizeof(*m));
m->type = M_T_BUILTIN;
/* Older versions of VBox only support screen widths which are a multiple
* of 8 */
else
}
/**
* Allocates an empty display mode and links it into the doubly linked list of
* modes pointed to by pScrn->modes. Returns a pointer to the newly allocated
* memory.
*/
{
TRACE_ENTRY();
{
}
else
{
}
return pMode;
}
/**
* Create display mode entries in the screen information structure for each
* of the graphics modes that we wish to support, that is:
* - A dynamic mode in first place which will be updated by the RandR code.
* - Any modes that the user requested in xorg.conf/XFree86Config.
*/
{
unsigned i;
/* Add two dynamic mode entries. When we receive a new size hint we will
* update whichever of these is not current. */
/* Add any modes specified by the user. We assume here that the mode names
* reflect the mode sizes. */
{
{
}
}
}
/** Set the initial values for the guest screen size hints to standard values
* in case nothing else is available. */
{
unsigned i;
{
}
/* Set up the first mode correctly to match the requested initial mode. */
}
{
return true;
return false;
}
static void compareAndMaybeSetUseHardwareCursor(VBOXPtr pVBox, uint32_t fCursorCapabilities, bool *pfChanged, bool fSet)
{
*pfChanged = true;
if (fSet)
}
#define SIZE_HINTS_PROPERTY "VBOX_SIZE_HINTS"
#define SIZE_HINTS_MISMATCH_PROPERTY "VBOX_SIZE_HINTS_MISMATCH"
#define MOUSE_CAPABILITIES_PROPERTY "VBOX_MOUSE_CAPABILITIES"
do { \
{ \
if (fSet) \
*(pfChanged) = true; \
} \
} while(0)
/** Read in information about the most recent size hints and cursor
* capabilities requested for the guest screens from a root window property set
* by an X11 client. Information obtained via HGSMI takes priority. */
{
int rc;
unsigned i;
bool fChanged;
bool fNeedUpdate = false;
int32_t fSizeMismatch = false;
if (vbvxGetIntegerPropery(pScrn, SIZE_HINTS_PROPERTY, &cPropertyElements, &paModeHints) != VINF_SUCCESS)
paModeHints = NULL;
if (paModeHints != NULL)
{
fChanged = false;
if (iSizeHint != 0)
{
if (iSizeHint == -1)
else
{
COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cx, (iSizeHint >> 16) & 0x8fff, &fChanged, fNoHGSMI);
COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cy, iSizeHint & 0x8fff, &fChanged, fNoHGSMI);
}
if (iLocation == -1)
else
{
COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.x, (iLocation >> 16) & 0x8fff, &fChanged,
fNoHGSMI);
COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.y, iLocation & 0x8fff, &fChanged, fNoHGSMI);
}
fNeedUpdate = true;
fSizeMismatch = true;
}
}
fChanged = false;
if ( vbvxGetIntegerPropery(pScrn, MOUSE_CAPABILITIES_PROPERTY, &cDummy, &pfCursorCapabilities) == VINF_SUCCESS
&& cDummy == 1)
compareAndMaybeSetUseHardwareCursor(pVBox, *pfCursorCapabilities, &fChanged, !pVBox->fHaveHGSMIModeHints);
fNeedUpdate = true;
fSizeMismatch = true;
*pfNeedUpdate = true;
}
/** Read in information about the most recent size hints and cursor
* capabilities requested for the guest screens from HGSMI. */
{
int rc;
unsigned i;
bool fChanged = false;
if (!pVBox->fHaveHGSMIModeHints)
return;
{
COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cx, pVBox->paVBVAModeHints[i].cx & 0x8fff, &fChanged, true);
COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredSize.cy, pVBox->paVBVAModeHints[i].cy & 0x8fff, &fChanged, true);
COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].afConnected, RT_BOOL(pVBox->paVBVAModeHints[i].fEnabled), &fChanged, true);
COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.x, (int32_t)pVBox->paVBVAModeHints[i].dx & 0x8fff, &fChanged,
true);
COMPARE_AND_MAYBE_SET(&pVBox->pScreens[i].aPreferredLocation.y, (int32_t)pVBox->paVBVAModeHints[i].dy & 0x8fff, &fChanged,
true);
else
}
rc = VBoxQueryConfHGSMI(&pVBox->guestCtx, VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &fCursorCapabilities);
VBVXASSERT(rc == VINF_SUCCESS, ("Getting VBOX_VBVA_CONF32_CURSOR_CAPABILITIES failed, rc=%d.\n", rc));
*pfNeedUpdate = true;
}
#ifdef VBOXVIDEO_13
# ifdef RT_OS_LINUX
/** We have this for two purposes: one is to ensure that the X server is woken
* up when we get a video ACPI event. Two is to grab ACPI video events to
* prevent gnome-settings-daemon from seeing them, as older versions ignored
* the time stamp and handled them at the wrong time. */
{
struct input_event event;
do
/* Why do they return EAGAIN instead of zero bytes read like everyone else does? */
}
{
int fd = -1;
FatalError("ACPI input file descriptor not initialised correctly.\n");
return;
{
{
#define BITS_PER_BLOCK (sizeof(unsigned long) * 8)
if (fd != -1)
if ( fd == -1
continue;
break;
break;
break;
fd = -1;
break;
}
}
if (fd != -1)
}
{
}
# endif /* RT_OS_LINUX */
#endif /* VBOXVIDEO_13 */