static RROutputPtr rdpRRAddOutput(rdpPtr dev, const char *aname, int x, int y, int width, int height) { RRModePtr mode; RRCrtcPtr crtc; RROutputPtr output; xRRModeInfo modeInfo; char name[64]; sprintf (name, "%dx%d", width, height); memset (&modeInfo, 0, sizeof(modeInfo)); modeInfo.width = width; modeInfo.height = height; modeInfo.nameLength = strlen(name); mode = RRModeGet(&modeInfo, name); if (mode == 0) { LLOGLN(0, ("rdpRRAddOutput: RRModeGet failed")); return 0; } crtc = RRCrtcCreate(dev->pScreen, NULL); if (crtc == 0) { LLOGLN(0, ("rdpRRAddOutput: RRCrtcCreate failed")); RRModeDestroy(mode); return 0; } output = RROutputCreate(dev->pScreen, aname, strlen(aname), NULL); if (output == 0) { LLOGLN(0, ("rdpRRAddOutput: RROutputCreate failed")); RRCrtcDestroy(crtc); RRModeDestroy(mode); return 0; } if (!RROutputSetClones(output, NULL, 0)) { LLOGLN(0, ("rdpRRAddOutput: RROutputSetClones failed")); } if (!RROutputSetModes(output, &mode, 1, 0)) { LLOGLN(0, ("rdpRRAddOutput: RROutputSetModes failed")); } if (!RROutputSetCrtcs(output, &crtc, 1)) { LLOGLN(0, ("rdpRRAddOutput: RROutputSetCrtcs failed")); } if (!RROutputSetConnection(output, RR_Connected)) { LLOGLN(0, ("rdpRRAddOutput: RROutputSetConnection failed")); } RRCrtcNotify(crtc, mode, x, y, RR_Rotate_0, NULL, 1, &output); dev->output[dev->extra_outputs] = output; dev->crtc[dev->extra_outputs] = crtc; dev->extra_outputs++; return output; }
static Bool vncRandRCrtcSet(ScreenPtr pScreen, RRCrtcPtr crtc, RRModePtr mode, int x, int y, Rotation rotation, int num_outputs, RROutputPtr *outputs) { Bool ret; int i; /* * Some applications get confused by a connected output without a * mode or CRTC, so we need to fiddle with the connection state as well. */ for (i = 0;i < crtc->numOutputs;i++) RROutputSetConnection(crtc->outputs[i], RR_Disconnected); for (i = 0;i < num_outputs;i++) { if (mode != NULL) RROutputSetConnection(outputs[i], RR_Connected); else RROutputSetConnection(outputs[i], RR_Disconnected); } /* Let RandR know we approve, and let it update its internal state */ ret = RRCrtcNotify(crtc, mode, x, y, rotation, NULL, num_outputs, outputs); if (!ret) return FALSE; return TRUE; }
static Bool xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc) { ScreenPtr pScreen = randr_crtc->pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); RRModePtr randr_mode = NULL; int x; int y; Rotation rotation; int numOutputs; RROutputPtr *randr_outputs; RROutputPtr randr_output; xf86CrtcPtr crtc = randr_crtc->devPrivate; xf86OutputPtr output; int i, j; DisplayModePtr mode = &crtc->mode; Bool ret; randr_outputs = xalloc(config->num_output * sizeof (RROutputPtr)); if (!randr_outputs) return FALSE; x = crtc->x; y = crtc->y; rotation = crtc->rotation; numOutputs = 0; randr_mode = NULL; for (i = 0; i < config->num_output; i++) { output = config->output[i]; if (output->crtc == crtc) { randr_output = output->randr_output; randr_outputs[numOutputs++] = randr_output; /* * We make copies of modes, so pointer equality * isn't sufficient */ for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++) { RRModePtr m = (j < randr_output->numModes ? randr_output->modes[j] : randr_output->userModes[j-randr_output->numModes]); if (xf86RandRModeMatches (m, mode)) { randr_mode = m; break; } } } } ret = RRCrtcNotify (randr_crtc, randr_mode, x, y, rotation, crtc->transformPresent ? &crtc->transform : NULL, numOutputs, randr_outputs); xfree(randr_outputs); return ret; }
/* * Request that the Crtc be reconfigured */ Bool RRCrtcSet (RRCrtcPtr crtc, RRModePtr mode, int x, int y, Rotation rotation, int numOutputs, RROutputPtr *outputs) { ScreenPtr pScreen = crtc->pScreen; Bool ret = FALSE; rrScrPriv(pScreen); /* See if nothing changed */ if (crtc->mode == mode && crtc->x == x && crtc->y == y && crtc->rotation == rotation && crtc->numOutputs == numOutputs && !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) && !RRCrtcPendingProperties (crtc) && !RRCrtcPendingTransform (crtc)) { ret = TRUE; } else { #if RANDR_12_INTERFACE if (pScrPriv->rrCrtcSet) { ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y, rotation, numOutputs, outputs); } else #endif { #if RANDR_10_INTERFACE if (pScrPriv->rrSetConfig) { RRScreenSize size; RRScreenRate rate; if (!mode) { RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL); ret = TRUE; } else { size.width = mode->mode.width; size.height = mode->mode.height; if (outputs[0]->mmWidth && outputs[0]->mmHeight) { size.mmWidth = outputs[0]->mmWidth; size.mmHeight = outputs[0]->mmHeight; } else { size.mmWidth = pScreen->mmWidth; size.mmHeight = pScreen->mmHeight; } size.nRates = 1; rate.rate = RRVerticalRefresh (&mode->mode); size.pRates = &rate; ret = (*pScrPriv->rrSetConfig) (pScreen, rotation, rate.rate, &size); /* * Old 1.0 interface tied screen size to mode size */ if (ret) { RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs); RRScreenSizeNotify (pScreen); } } } #endif } if (ret) { int o; RRTellChanged (pScreen); for (o = 0; o < numOutputs; o++) RRPostPendingProperties (outputs[o]); } } return ret; }
static void RRScanOldConfig (ScreenPtr pScreen, Rotation rotations) { rrScrPriv(pScreen); RROutputPtr output; RRCrtcPtr crtc; RRModePtr mode, newMode = NULL; int i; CARD16 minWidth = MAXSHORT, minHeight = MAXSHORT; CARD16 maxWidth = 0, maxHeight = 0; CARD16 width, height; /* * First time through, create a crtc and output and hook * them together */ if (pScrPriv->numOutputs == 0 && pScrPriv->numCrtcs == 0) { crtc = RRCrtcCreate (pScreen, NULL); if (!crtc) return; output = RROutputCreate (pScreen, "default", 7, NULL); if (!output) return; RROutputSetCrtcs (output, &crtc, 1); RROutputSetConnection (output, RR_Connected); #ifdef RENDER RROutputSetSubpixelOrder (output, PictureGetSubpixelOrder (pScreen)); #endif } output = pScrPriv->outputs[0]; if (!output) return; crtc = pScrPriv->crtcs[0]; if (!crtc) return; /* check rotations */ if (rotations != crtc->rotations) { crtc->rotations = rotations; crtc->changed = TRUE; pScrPriv->changed = TRUE; } /* regenerate mode list */ for (i = 0; i < pScrPriv->nSizes; i++) { RRScreenSizePtr size = &pScrPriv->pSizes[i]; int r; if (size->nRates) { for (r = 0; r < size->nRates; r++) { mode = RROldModeAdd (output, size, size->pRates[r].rate); if (i == pScrPriv->size && size->pRates[r].rate == pScrPriv->rate) { newMode = mode; } } xfree (size->pRates); } else { mode = RROldModeAdd (output, size, 0); if (i == pScrPriv->size) newMode = mode; } } if (pScrPriv->nSizes) xfree (pScrPriv->pSizes); pScrPriv->pSizes = NULL; pScrPriv->nSizes = 0; /* find size bounds */ for (i = 0; i < output->numModes + output->numUserModes; i++) { mode = (i < output->numModes ? output->modes[i] : output->userModes[i-output->numModes]); width = mode->mode.width; height = mode->mode.height; if (width < minWidth) minWidth = width; if (width > maxWidth) maxWidth = width; if (height < minHeight) minHeight = height; if (height > maxHeight) maxHeight = height; } RRScreenSetSizeRange (pScreen, minWidth, minHeight, maxWidth, maxHeight); /* notice current mode */ if (newMode) RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation, 1, &output); }