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 RRCrtcPtr vncRandRCrtcCreate(ScreenPtr pScreen) { RRCrtcPtr crtc; RROutputPtr output; char name[100]; /* First we create the CRTC... */ crtc = RRCrtcCreate(pScreen, NULL); /* We don't actually support gamma, but xrandr complains when it is missing */ RRCrtcGammaSetSize (crtc, 256); /* Then we create a dummy output for it... */ sprintf(name, "VNC-%d", vncRandRIndex); vncRandRIndex++; output = RROutputCreate(pScreen, name, strlen(name), NULL); RROutputSetCrtcs(output, &crtc, 1); RROutputSetConnection(output, RR_Disconnected); /* Make sure the CRTC has this output set */ vncRandRCrtcSet(pScreen, crtc, NULL, 0, 0, RR_Rotate_0, 1, &output); /* Populate a list of default modes */ vncRandRSetModes(output, -1, -1); return crtc; }
int rdpRRSetRdpOutputs(rdpPtr dev) { rrScrPrivPtr pRRScrPriv; int index; int width; int height; char text[256]; RROutputPtr output; pRRScrPriv = rrGetScrPriv(dev->pScreen); LLOGLN(0, ("rdpRRSetRdpOutputs: numCrtcs %d", pRRScrPriv->numCrtcs)); while (pRRScrPriv->numCrtcs > 0) { RRCrtcDestroy(pRRScrPriv->crtcs[0]); } LLOGLN(0, ("rdpRRSetRdpOutputs: numOutputs %d", pRRScrPriv->numOutputs)); while (pRRScrPriv->numOutputs > 0) { RROutputDestroy(pRRScrPriv->outputs[0]); } if (dev->monitorCount == 0) { rdpRRAddOutput(dev, "rdp0", 0, 0, dev->width, dev->height); } else { for (index = 0; index < dev->monitorCount; index++) { snprintf(text, 255, "rdp%d", index); width = dev->minfo[index].right - dev->minfo[index].left + 1; height = dev->minfo[index].bottom - dev->minfo[index].top + 1; output = rdpRRAddOutput(dev, text, dev->minfo[index].left, dev->minfo[index].top, width, height); if ((output != 0) && (dev->minfo[index].is_primary)) { RRSetPrimaryOutput(pRRScrPriv, output); } } } for (index = 0; index < pRRScrPriv->numOutputs; index++) { RROutputSetCrtcs(pRRScrPriv->outputs[index], pRRScrPriv->crtcs, pRRScrPriv->numCrtcs); } return 0; }
/* * Mirror the current mode configuration to RandR */ static Bool xf86RandR12SetInfo12 (ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); RROutputPtr *clones; RRCrtcPtr *crtcs; int ncrtc; int o, c, l; RRCrtcPtr randr_crtc; int nclone; clones = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr)); crtcs = ALLOCATE_LOCAL (config->num_crtc * sizeof (RRCrtcPtr)); for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; ncrtc = 0; for (c = 0; c < config->num_crtc; c++) if (output->possible_crtcs & (1 << c)) crtcs[ncrtc++] = config->crtc[c]->randr_crtc; if (output->crtc) randr_crtc = output->crtc->randr_crtc; else randr_crtc = NULL; if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc)) { DEALLOCATE_LOCAL (crtcs); DEALLOCATE_LOCAL (clones); return FALSE; } RROutputSetPhysicalSize(output->randr_output, output->mm_width, output->mm_height); xf86RROutputSetModes (output->randr_output, output->probed_modes); switch (output->status) { case XF86OutputStatusConnected: RROutputSetConnection (output->randr_output, RR_Connected); break; case XF86OutputStatusDisconnected: RROutputSetConnection (output->randr_output, RR_Disconnected); break; case XF86OutputStatusUnknown: RROutputSetConnection (output->randr_output, RR_UnknownConnection); break; } RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order); /* * Valid clones */ nclone = 0; for (l = 0; l < config->num_output; l++) { xf86OutputPtr clone = config->output[l]; if (l != o && (output->possible_clones & (1 << l))) clones[nclone++] = clone->randr_output; } if (!RROutputSetClones (output->randr_output, clones, nclone)) { DEALLOCATE_LOCAL (crtcs); DEALLOCATE_LOCAL (clones); return FALSE; } } DEALLOCATE_LOCAL (crtcs); DEALLOCATE_LOCAL (clones); return TRUE; }
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); }