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; }
/* * 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; }