RandR support in dummy video driver

Properly initialize RandR extension, mostly with stubs. It creates four
virtual outputs (lets hope that nobody will need more at once...). By
default only the first one is in "connected" state, with preferred mode
from xorg.conf. Other outputs get "connected" at first mode set (and
left connected forever - you can always not use it).
So without any xrandr calls it should work as before.

Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
This commit is contained in:
Marek Marczykowski-Górecki
2018-10-16 16:48:47 +02:00
committed by Adam Jackson
parent 850c05161d
commit 327a25c4c3
2 changed files with 273 additions and 0 deletions

View File

@@ -13,6 +13,8 @@
#include "compat-api.h"
#define DUMMY_MAX_SCREENS 4
/* Supported chipsets */
typedef enum {
DUMMY_CHIP
@@ -52,6 +54,12 @@ typedef struct dummyRec
dummy_colors colors[1024];
Bool (*CreateWindow)() ; /* wrapped CreateWindow */
Bool prop;
/* XRANDR support begin */
int num_screens;
struct _xf86Crtc *paCrtcs[DUMMY_MAX_SCREENS];
struct _xf86Output *paOutputs[DUMMY_MAX_SCREENS];
int connected_outputs;
/* XRANDR support end */
} DUMMYRec, *DUMMYPtr;
/* The privates of the DUMMY driver */

View File

@@ -29,6 +29,8 @@
#include "picturestr.h"
#include "xf86Crtc.h"
/*
* Driver data structures.
*/
@@ -132,6 +134,219 @@ static XF86ModuleVersionInfo dummyVersRec =
{0,0,0,0}
};
/************************
* XRANDR support begin *
************************/
static Bool dummy_config_resize(ScrnInfoPtr pScrn, int cw, int ch);
static Bool DUMMYAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height);
static const xf86CrtcConfigFuncsRec DUMMYCrtcConfigFuncs = {
.resize = dummy_config_resize
};
static void
dummy_crtc_dpms(xf86CrtcPtr crtc, int mode)
{
}
static Bool
dummy_crtc_lock (xf86CrtcPtr crtc)
{
return FALSE;
}
static Bool
dummy_crtc_mode_fixup (xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
return TRUE;
}
static void
dummy_crtc_stub (xf86CrtcPtr crtc)
{
}
static void
dummy_crtc_gamma_set (xf86CrtcPtr crtc, CARD16 *red,
CARD16 *green, CARD16 *blue, int size)
{
}
static void *
dummy_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
{
return NULL;
}
static void
dummy_crtc_mode_set (xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode, int x, int y)
{
}
static const xf86CrtcFuncsRec DUMMYCrtcFuncs = {
.dpms = dummy_crtc_dpms,
.save = NULL, /* These two are never called by the server. */
.restore = NULL,
.lock = dummy_crtc_lock,
.unlock = NULL, /* This will not be invoked if lock returns FALSE. */
.mode_fixup = dummy_crtc_mode_fixup,
.prepare = dummy_crtc_stub,
.mode_set = dummy_crtc_mode_set,
.commit = dummy_crtc_stub,
.gamma_set = dummy_crtc_gamma_set,
.shadow_allocate = dummy_crtc_shadow_allocate,
.shadow_create = NULL, /* These two should not be invoked if allocate
returns NULL. */
.shadow_destroy = NULL,
.set_cursor_colors = NULL,
.set_cursor_position = NULL,
.show_cursor = NULL,
.hide_cursor = NULL,
.load_cursor_argb = NULL,
.destroy = dummy_crtc_stub
};
static void
dummy_output_stub (xf86OutputPtr output)
{
}
static void
dummy_output_dpms (xf86OutputPtr output, int mode)
{
}
static int
dummy_output_mode_valid (xf86OutputPtr output, DisplayModePtr mode)
{
return MODE_OK;
}
static Bool
dummy_output_mode_fixup (xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
return TRUE;
}
static void
dummy_output_mode_set (xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
DUMMYPtr dPtr = DUMMYPTR(output->scrn);
int index = (int64_t)output->driver_private;
/* set to connected at first mode set */
dPtr->connected_outputs |= 1 << index;
}
/* The first virtual monitor is always connected. Others only after setting its
* mode */
static xf86OutputStatus
dummy_output_detect (xf86OutputPtr output)
{
DUMMYPtr dPtr = DUMMYPTR(output->scrn);
int index = (int64_t)output->driver_private;
if (dPtr->connected_outputs & (1 << index))
return XF86OutputStatusConnected;
else
return XF86OutputStatusDisconnected;
}
static DisplayModePtr
dummy_output_get_modes (xf86OutputPtr output)
{
DisplayModePtr pModes = NULL, pMode, pModeSrc;
/* copy modes from config */
for (pModeSrc = output->scrn->modes; pModeSrc; pModeSrc = pModeSrc->next)
{
pMode = xnfcalloc(1, sizeof(DisplayModeRec));
memcpy(pMode, pModeSrc, sizeof(DisplayModeRec));
pMode->next = NULL;
pMode->prev = NULL;
pMode->name = strdup(pModeSrc->name);
pModes = xf86ModesAdd(pModes, pMode);
if (pModeSrc->next == output->scrn->modes)
break;
}
return pModes;
}
static const xf86OutputFuncsRec DUMMYOutputFuncs = {
.create_resources = dummy_output_stub,
.dpms = dummy_output_dpms,
.save = NULL, /* These two are never called by the server. */
.restore = NULL,
.mode_valid = dummy_output_mode_valid,
.mode_fixup = dummy_output_mode_fixup,
.prepare = dummy_output_stub,
.commit = dummy_output_stub,
.mode_set = dummy_output_mode_set,
.detect = dummy_output_detect,
.get_modes = dummy_output_get_modes,
#ifdef RANDR_12_INTERFACE
.set_property = NULL,
#endif
.destroy = dummy_output_stub
};
static Bool
dummy_config_resize(ScrnInfoPtr pScrn, int cw, int ch)
{
if (!pScrn->vtSema) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"We do not own the active VT, exiting.\n");
return TRUE;
}
return DUMMYAdjustScreenPixmap(pScrn, cw, ch);
}
Bool DUMMYAdjustScreenPixmap(ScrnInfoPtr pScrn, int width, int height)
{
ScreenPtr pScreen = pScrn->pScreen;
PixmapPtr pPixmap = pScreen->GetScreenPixmap(pScreen);
DUMMYPtr dPtr = DUMMYPTR(pScrn);
uint64_t cbLine = (width * xf86GetBppFromDepth(pScrn, pScrn->depth) / 8 + 3) & ~3;
int displayWidth = cbLine * 8 / xf86GetBppFromDepth(pScrn, pScrn->depth);
if ( width == pScrn->virtualX
&& height == pScrn->virtualY
&& displayWidth == pScrn->displayWidth)
return TRUE;
if (!pPixmap) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to get the screen pixmap.\n");
return FALSE;
}
if (cbLine > UINT32_MAX || cbLine * height >= pScrn->videoRam * 1024)
{
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Unable to set up a virtual screen size of %dx%d with %d Kb of video memory available. Please increase the video memory size.\n",
width, height, pScrn->videoRam);
return FALSE;
}
pScreen->ModifyPixmapHeader(pPixmap, width, height,
pScrn->depth, xf86GetBppFromDepth(pScrn, pScrn->depth), cbLine,
pPixmap->devPrivate.ptr);
pScrn->virtualX = width;
pScrn->virtualY = height;
pScrn->displayWidth = displayWidth;
return TRUE;
}
/**********************
* XRANDR support end *
**********************/
/*
* This is the module init data.
* Its name has to be the driver name followed by ModuleData
@@ -564,6 +779,56 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL)
xf86SetBlackWhitePixels(pScreen);
/* initialize XRANDR */
xf86CrtcConfigInit(pScrn, &DUMMYCrtcConfigFuncs);
/* FIXME */
dPtr->num_screens = DUMMY_MAX_SCREENS;
for (int i=0; i < dPtr->num_screens; i++) {
char szOutput[256];
dPtr->paCrtcs[i] = xf86CrtcCreate(pScrn, &DUMMYCrtcFuncs);
dPtr->paCrtcs[i]->driver_private = (void *)(uintptr_t)i;
/* Set up our virtual outputs. */
snprintf(szOutput, sizeof(szOutput), "DUMMY%u", i);
dPtr->paOutputs[i] = xf86OutputCreate(pScrn, &DUMMYOutputFuncs,
szOutput);
xf86OutputUseScreenMonitor(dPtr->paOutputs[i], FALSE);
dPtr->paOutputs[i]->possible_crtcs = 1 << i;
dPtr->paOutputs[i]->possible_clones = 0;
dPtr->paOutputs[i]->driver_private = (void *)(uintptr_t)i;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Created crtc (%p) and output %s (%p)\n",
(void *)dPtr->paCrtcs[i], szOutput,
(void *)dPtr->paOutputs[i]);
}
/* bitmask */
dPtr->connected_outputs = 1;
xf86CrtcSetSizeRange(pScrn, 64, 64, DUMMY_MAX_WIDTH, DUMMY_MAX_HEIGHT);
/* Now create our initial CRTC/output configuration. */
if (!xf86InitialConfiguration(pScrn, TRUE)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Initial CRTC configuration failed!\n");
return (FALSE);
}
/* Initialise randr 1.2 mode-setting functions and set first mode.
* Note that the mode won't be usable until the server has resized the
* framebuffer to something reasonable. */
if (!xf86CrtcScreenInit(pScreen)) {
return FALSE;
}
if (!xf86SetDesiredModes(pScrn)) {
return FALSE;
}
/* XRANDR initialization end */
if (dPtr->swCursor)
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Software Cursor.\n");