Defining and setting custom resolutions at runtime is not currently possible with dummy, which is unconvenient for remote desktop applications, see: http://lists.x.org/archives/xorg-devel/2014-September/043928.html
This patch adds support XRandR 1.2, which allows custom modes. This is done by using more recent initialization functions such as xf86CrtcConfigInit/xf86OutputCreate/xf86InitialConfiguration. Signed-off-by: Nicolas Boichat <[email protected]> --- I'm not 100% sure that I'm calling the right functions in the right order, or if other parts of Init/PreInit could be removed (e.g. do we still want DGA/cursor support?). Hoping somebody here can verify that. In any case, this works without glitches in my application. Thank you, Best, src/dummy_driver.c | 213 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 144 insertions(+), 69 deletions(-) diff --git a/src/dummy_driver.c b/src/dummy_driver.c index 6062c39..d15f77d 100644 --- a/src/dummy_driver.c +++ b/src/dummy_driver.c @@ -34,6 +34,8 @@ #include <X11/extensions/Xv.h> #endif +#include "xf86Crtc.h" + /* * Driver data structures. */ @@ -178,6 +180,115 @@ dummySetup(pointer module, pointer opts, int *errmaj, int *errmin) #endif /* XFree86LOADER */ static Bool +size_valid(ScrnInfoPtr pScrn, int width, int height) +{ + /* Guard against invalid parameters */ + if (width == 0 || height == 0 || + width > DUMMY_MAX_WIDTH || height > DUMMY_MAX_HEIGHT) + return FALSE; + + /* videoRam is in kb, divide first to avoid 32-bit int overflow */ + if ((width*height+1023)/1024*pScrn->bitsPerPixel/8 > pScrn->videoRam) + return FALSE; + + return TRUE; +} + +static Bool +dummy_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height) +{ + int old_width, old_height; + + old_width = pScrn->virtualX; + old_height = pScrn->virtualY; + + if (size_valid(pScrn, width, height)) { + PixmapPtr rootPixmap; + ScreenPtr pScreen = pScrn->pScreen; + + pScrn->virtualX = width; + pScrn->virtualY = height; + + rootPixmap = pScreen->GetScreenPixmap(pScreen); + if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, + -1, -1, -1, NULL)) { + pScrn->virtualX = old_width; + pScrn->virtualY = old_height; + return FALSE; + } + + pScrn->displayWidth = rootPixmap->devKind / + (rootPixmap->drawable.bitsPerPixel / 8); + + return TRUE; + } else { + return FALSE; + } +} + +static const xf86CrtcConfigFuncsRec dummy_xf86crtc_config_funcs = { + dummy_xf86crtc_resize +}; + +static xf86OutputStatus +dummy_output_detect(xf86OutputPtr output) +{ + return XF86OutputStatusConnected; +} + +static int +dummy_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +{ + if (size_valid(output->scrn, pMode->HDisplay, pMode->VDisplay)) { + return MODE_OK; + } else { + return MODE_MEM; + } +} + +static DisplayModePtr +dummy_output_get_modes(xf86OutputPtr output) +{ + return NULL; +} + +static void +dummy_output_dpms(xf86OutputPtr output, int dpms) +{ + return; +} + +static const xf86OutputFuncsRec dummy_output_funcs = { + .detect = dummy_output_detect, + .mode_valid = dummy_output_mode_valid, + .get_modes = dummy_output_get_modes, + .dpms = dummy_output_dpms, +}; + +static Bool +dummy_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, + Rotation rotation, int x, int y) +{ + crtc->mode = *mode; + crtc->x = x; + crtc->y = y; + crtc->rotation = rotation; + + return TRUE; +} + +static void +dummy_crtc_dpms(xf86CrtcPtr output, int dpms) +{ + return; +} + +static const xf86CrtcFuncsRec dummy_crtc_funcs = { + .set_mode_major = dummy_crtc_set_mode_major, + .dpms = dummy_crtc_dpms, +}; + +static Bool DUMMYGetRec(ScrnInfoPtr pScrn) { /* @@ -283,6 +394,8 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) DUMMYPtr dPtr; int maxClock = 230000; GDevPtr device = xf86GetEntityInfo(pScrn->entityList[0])->device; + xf86OutputPtr output; + xf86CrtcPtr crtc; if (flags & PROBE_DETECT) return TRUE; @@ -346,13 +459,6 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; - if (pScrn->depth > 1) { - Gamma zeros = {0.0, 0.0, 0.0}; - - if (!xf86SetGamma(pScrn, zeros)) - return FALSE; - } - xf86CollectOptions(pScrn, device->options); /* Process the options */ if (!(dPtr->Options = malloc(sizeof(DUMMYOptions)))) @@ -382,64 +488,45 @@ DUMMYPreInit(ScrnInfoPtr pScrn, int flags) maxClock); } - pScrn->progClock = TRUE; - /* - * Setup the ClockRanges, which describe what clock ranges are available, - * and what sort of modes they can be used for. - */ - clockRanges = (ClockRangePtr)xnfcalloc(sizeof(ClockRange), 1); - clockRanges->next = NULL; - clockRanges->ClockMulFactor = 1; - clockRanges->minClock = 11000; /* guessed ยงยงยง */ - clockRanges->maxClock = 300000; - clockRanges->clockIndex = -1; /* programmable */ - clockRanges->interlaceAllowed = TRUE; - clockRanges->doubleScanAllowed = TRUE; - - /* Subtract memory for HW cursor */ - - - { - int apertureSize = (pScrn->videoRam * 1024); - i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, - pScrn->display->modes, clockRanges, - NULL, 256, DUMMY_MAX_WIDTH, - (8 * pScrn->bitsPerPixel), - 128, DUMMY_MAX_HEIGHT, pScrn->display->virtualX, - pScrn->display->virtualY, apertureSize, - LOOKUP_BEST_REFRESH); - - if (i == -1) - RETURN; - } + xf86CrtcConfigInit(pScrn, &dummy_xf86crtc_config_funcs); + + xf86CrtcSetSizeRange(pScrn, 256, 256, DUMMY_MAX_WIDTH, DUMMY_MAX_HEIGHT); + + crtc = xf86CrtcCreate(pScrn, &dummy_crtc_funcs); + + output = xf86OutputCreate(pScrn, &dummy_output_funcs, "default"); + + output->possible_crtcs = 0x7f; - /* Prune the modes marked as invalid */ - xf86PruneDriverModes(pScrn); + xf86InitialConfiguration(pScrn, TRUE); + + if (pScrn->depth > 1) { + Gamma zeros = {0.0, 0.0, 0.0}; + + if (!xf86SetGamma(pScrn, zeros)) + return FALSE; + } - if (i == 0 || pScrn->modes == NULL) { + if (pScrn->modes == NULL) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); RETURN; } - /* - * Set the CRTC parameters for all of the modes based on the type - * of mode, and the chipset's interlace requirements. - * - * Calling this is required if the mode->Crtc* values are used by the - * driver and if the driver doesn't provide code to set them. They - * are not pre-initialised at all. - */ - xf86SetCrtcForModes(pScrn, 0); - /* Set the current mode to the first in the list */ pScrn->currentMode = pScrn->modes; - /* Print the list of modes being used */ - xf86PrintModes(pScrn); + /* Set default mode in CRTC */ + crtc->funcs->set_mode_major(crtc, pScrn->currentMode, RR_Rotate_0, 0, 0); /* If monitor resolution is set on the command line, use it */ xf86SetDpi(pScrn, 0, 0); + /* Set monitor size based on DPI */ + output->mm_width = pScrn->xDpi > 0 ? + (pScrn->virtualX * 254 / (10*pScrn->xDpi)) : 0; + output->mm_height = pScrn->yDpi > 0 ? + (pScrn->virtualY * 254 / (10*pScrn->yDpi)) : 0; + if (xf86LoadSubModule(pScrn, "fb") == NULL) { RETURN; } @@ -559,6 +646,8 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) if (!miSetPixmapDepths ()) return FALSE; + pScrn->displayWidth = pScrn->virtualX; + /* * Call the framebuffer layer's ScreenInit function, and fill in other * pScreen fields. @@ -597,23 +686,6 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) if (dPtr->swCursor) xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using Software Cursor.\n"); - { - - - BoxRec AvailFBArea; - int lines = pScrn->videoRam * 1024 / - (pScrn->displayWidth * (pScrn->bitsPerPixel >> 3)); - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = lines; - xf86InitFBManager(pScreen, &AvailFBArea); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %i scanlines of offscreen memory \n" - , lines - pScrn->virtualY); - } - xf86SetBackingStore(pScreen); xf86SetSilkenMouse(pScreen); @@ -640,6 +712,9 @@ DUMMYScreenInit(SCREEN_INIT_ARGS_DECL) | CMAP_RELOAD_ON_MODE_SWITCH)) return FALSE; + if (!xf86CrtcScreenInit(pScreen)) + return FALSE; + /* DUMMYInitVideo(pScreen); */ pScreen->SaveScreen = DUMMYSaveScreen; -- 2.1.3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
