static display init(XRRScreenResources* sr, RROutput output) { display result; XRROutputInfo* oi = XRRGetOutputInfo(g_display, sr, output); if (oi->connection == RR_Connected) { result.scale = 1; result.name = oi->name; result.color_depth = XDefaultDepth(g_display, g_screen); result.color_depth_per_component = result.color_depth >= 24? 8 : 0; result.crtc = oi->crtc; result.output = output; XRRCrtcInfo* ci = XRRGetCrtcInfo(g_display, sr, oi->crtc); result.rect.left = ci->x; result.rect.top = ci->y; result.rect.width = ci->width; result.rect.height = ci->height; if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) { std::swap(result.rect.width, result.rect.height); } XRRFreeCrtcInfo(ci); result.work_rect = result.rect; } XRRFreeOutputInfo(oi); return result; }
static void dumpOutput(const char *prefix, Display *dpy, int screen_idx, XRRScreenResources *resources, int outputIdx, RROutput output) { int i, j, primIdx=0; Window root = RootWindow(dpy, screen_idx); RROutput pxid = XRRGetOutputPrimary (dpy, root); int isPrim =0; if ( None != pxid && pxid == output ) { primIdx = i; isPrim = 1; } XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output); fprintf(stderr, "%s: Output[%d]: id %#lx, crtx 0x%lX, name %s (%d), %lux%lu, ncrtc %d, nclone %d, nmode %d (preferred %d), primary %d\n", prefix, outputIdx, output, xrrOutputInfo->crtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, xrrOutputInfo->ncrtc, xrrOutputInfo->nclone, xrrOutputInfo->nmode, xrrOutputInfo->npreferred, isPrim); for(j=0; j<xrrOutputInfo->ncrtc; j++) { fprintf(stderr, "%s: Output[%d].Crtc[%d].id %#lx\n", prefix, i, j, xrrOutputInfo->crtcs[j]); } for(j=0; j<xrrOutputInfo->nclone; j++) { fprintf(stderr, "%s: Output[%d].Clones[%d].id %#lx\n", prefix, i, j, xrrOutputInfo->clones[j]); } for(j=0; j<xrrOutputInfo->nmode; j++) { fprintf(stderr, "%s: Output[%d].Mode[%d].id %#lx\n", prefix, i, j, xrrOutputInfo->modes[j]); } XRRFreeOutputInfo (xrrOutputInfo); }
std::vector<display::mode> display::modes() const { std::vector<display::mode> result; if (randr.is_available) { XRRScreenResources* sr = XRRGetScreenResources(g_display, g_root); XRRCrtcInfo* ci = XRRGetCrtcInfo(g_display, sr, crtc); XRROutputInfo* oi = XRRGetOutputInfo(g_display, sr, output); for (int i = 0; i < oi->nmode; ++i) { XRRModeInfo const* mi = mode_info(sr, oi->modes[i]); if (mi && !(mi->modeFlags & RR_Interlace)) { result.emplace_back(make_mode(mi, ci)); } } XRRFreeOutputInfo(oi); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); std::sort(result.begin(), result.end()); result.erase(std::unique(result.begin(), result.end()), result.end()); } else { result.emplace_back(current_mode()); } return result; }
/* In the case of multiple outputs of a single crtc (mirroring), we consider one of the * outputs the "main". This is the one we consider "owning" the windows, so if * the mirroring is changed to a dual monitor setup then the windows are moved to the * crtc that now has that main output. If one of the outputs is the primary that is * always the main, otherwise we just use the first. */ static XID find_main_output_for_crtc (XRRScreenResources *resources, XRRCrtcInfo *crtc, Display *xdisplay, XID xroot) { XRROutputInfo *output; RROutput primary_output; int i; XID res; primary_output = XRRGetOutputPrimary (xdisplay, xroot); res = None; for (i = 0; i < crtc->noutput; i++) { output = XRRGetOutputInfo (xdisplay, resources, crtc->outputs[i]); if (output->connection != RR_Disconnected && (res == None || crtc->outputs[i] == primary_output)) { res = crtc->outputs[i]; } XRRFreeOutputInfo (output); } return res; }
int main() { Display *disp; XRRScreenResources *screen; XRROutputInfo *info; XRRCrtcInfo *crtc_info; int iscres; int icrtc; disp = XOpenDisplay(0); screen = XRRGetScreenResources (disp, DefaultRootWindow(disp)); for (iscres = screen->noutput; iscres > 0; ) { --iscres; info = XRRGetOutputInfo (disp, screen, screen->outputs[iscres]); if (info->connection == RR_Connected) { for (icrtc = info->ncrtc; icrtc > 0;) { --icrtc; crtc_info = XRRGetCrtcInfo (disp, screen, screen->crtcs[icrtc]); fprintf(stderr, "==> %dx%d+%dx%d\n", crtc_info->x, crtc_info->y, crtc_info->width, crtc_info->height); XRRFreeCrtcInfo(crtc_info); } } XRRFreeOutputInfo (info); } XRRFreeScreenResources(screen); return 0; }
void XRRConfiguration::AddResolutions(wxArrayString& arrayStringFor_FullscreenResolution) { if (!bValid || !screenResources) return; //Get all full screen resolutions for the config dialog for (int i = 0; i < screenResources->noutput; i++) { XRROutputInfo *output_info = XRRGetOutputInfo(dpy, screenResources, screenResources->outputs[i]); if (output_info && output_info->crtc && output_info->connection == RR_Connected) { std::vector<std::string> resos; for (int j = 0; j < output_info->nmode; j++) for (int k = 0; k < screenResources->nmode; k++) if (output_info->modes[j] == screenResources->modes[k].id) { const std::string strRes = std::string(output_info->name) + ": " + std::string(screenResources->modes[k].name); // Only add unique resolutions if (std::find(resos.begin(), resos.end(), strRes) == resos.end()) { resos.push_back(strRes); arrayStringFor_FullscreenResolution.Add(StrToWxStr(strRes)); } } } if (output_info) XRRFreeOutputInfo(output_info); } }
/* Caller must free return value */ static XRROutputInfo* find_output_xrandr(Display *dpy, const char *output_name) { XRRScreenResources *res; XRROutputInfo *output_info = NULL; int i; int found = 0; res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy)); for (i = 0; i < res->noutput && !found; i++) { output_info = XRRGetOutputInfo(dpy, res, res->outputs[i]); if (output_info->crtc && output_info->connection == RR_Connected && strcmp(output_info->name, output_name) == 0) { found = 1; break; } XRRFreeOutputInfo(output_info); } XRRFreeScreenResources(res); if (!found) output_info = NULL; return output_info; }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) { GLFWvidmode* result; *found = 0; // Build array of available resolutions if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { int i, j; XRRScreenResources* sr; XRROutputInfo* oi; sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); result = calloc(oi->nmode, sizeof(GLFWvidmode)); for (i = 0; i < oi->nmode; i++) { const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); if (!modeIsGood(mi)) continue; const GLFWvidmode mode = vidmodeFromModeInfo(mi); for (j = 0; j < *found; j++) { if (result[j].width == mode.width && result[j].height == mode.height && result[j].refreshRate == mode.refreshRate) { break; } } if (j < *found) { // This is a duplicate, so skip it continue; } result[*found] = mode; (*found)++; } XRRFreeOutputInfo(oi); XRRFreeScreenResources(sr); } else { *found = 1; result = calloc(1, sizeof(GLFWvidmode)); _glfwPlatformGetVideoMode(monitor, result); } return result; }
void RandROutput::queryOutputInfo(void) { XRROutputInfo *info = XRRGetOutputInfo(QX11Info::display(), m_screen->resources(), m_id); Q_ASSERT(info); if (RandR::timestamp != info->timestamp) RandR::timestamp = info->timestamp; // Set up the output's connection status, name, and current // CRT controller. m_connected = (info->connection == RR_Connected); m_name = info->name; kDebug() << "XID" << m_id << "is output" << m_name << (isConnected() ? "(connected)" : "(disconnected)"); setCrtc(m_screen->crtc(info->crtc)); kDebug() << "Possible CRTCs for output" << m_name << ":"; if (!info->ncrtc) { kDebug() << " - none"; } for(int i = 0; i < info->ncrtc; ++i) { kDebug() << " - CRTC" << info->crtcs[i]; m_possibleCrtcs.append(info->crtcs[i]); } //TODO: is it worth notifying changes on mode list changing? m_modes.clear(); for (int i = 0; i < info->nmode; ++i) { if (i < info->npreferred) { m_preferredMode = m_screen->mode(info->modes[i]); } m_modes.append(info->modes[i]); } //get all possible rotations m_rotations = 0; for (int i = 0; i < m_possibleCrtcs.count(); ++i) { RandRCrtc *crtc = m_screen->crtc(m_possibleCrtcs.at(i)); Q_ASSERT(crtc); m_rotations |= crtc->rotations(); } m_originalRotation = m_crtc->rotation(); m_originalRate = m_crtc->refreshRate(); m_originalRect = m_crtc->rect(); if(isConnected()) { kDebug() << "Current configuration for output" << m_name << ":"; kDebug() << " - Refresh rate:" << m_originalRate; kDebug() << " - Rect:" << m_originalRect; kDebug() << " - Rotation:" << m_originalRotation; } XRRFreeOutputInfo(info); }
static void randrd(void) { XRRScreenResources *resources; XRROutputInfo *info; XRROutputChangeNotifyEvent *rrocevt; XRRNotifyEvent *rrevt; char *new_edidhash; Window root; XEvent evt; exec_script(script, "init", "", current_edidhash); XRRSelectInput(dpy, DefaultRootWindow(dpy), RROutputChangeNotifyMask); while (!quit) { root = RootWindow(dpy, DefaultScreen(dpy)); resources = XRRGetScreenResources(dpy, root); while (XPending(dpy)) { XNextEvent(dpy, &evt); if (evt.type != rr_event_base + RRNotify) continue; rrevt = (XRRNotifyEvent *)&evt; if (rrevt->subtype != RRNotify_OutputChange) continue; new_edidhash = getedidhash1(resources); if (new_edidhash == NULL) continue; if (!strcmp(current_edidhash, new_edidhash)) { free(new_edidhash); continue; } free(current_edidhash); current_edidhash = new_edidhash; rrocevt = (XRROutputChangeNotifyEvent *)&evt; info = XRRGetOutputInfo(rrocevt->display, resources, rrocevt->output); syslog(LOG_INFO, "%s %s", info->name, connstates[info->connection]); exec_script(script, connstates[info->connection], info->name, new_edidhash); XRRFreeOutputInfo(info); } XRRFreeScreenResources(resources); sleep(interval); } }
MonitorManager *monitor_mgr_create() { Display *display = XOpenDisplay(NULL); if (!display) { fprintf(stderr, "Cannot open display.\n"); return NULL; } MonitorManager *mgr = malloc(sizeof(MonitorManager*)); mgr->monitor_count = 0; mgr->monitors = NULL; Window root = DefaultRootWindow(display); RROutput primary_output = XRRGetOutputPrimary(display, root); XRRScreenResources *screen = XRRGetScreenResources(display, root); assert(screen); for (int i = 0; i < screen->noutput; i++) { XRROutputInfo *output_info = XRRGetOutputInfo( display, screen, screen->outputs[i]); assert(output_info); if (output_info->connection == RR_Connected) { XRRCrtcInfo *crtc_info = XRRGetCrtcInfo( display, screen, output_info->crtc); assert(crtc_info); int primary = 0; for (int j = 0; j < crtc_info->noutput; j++) if (crtc_info->outputs[j] == primary_output) primary = 1; Monitor *monitor = monitor_create( primary, crtc_info->x, crtc_info->y, crtc_info->width, crtc_info->height); assert(monitor); monitor_mgr_add(mgr, monitor); XRRFreeCrtcInfo(crtc_info); } XRRFreeOutputInfo(output_info); } XRRFreeScreenResources(screen); XCloseDisplay(display); return mgr; }
static void ExtInitRR(int available) { Rotation rot; if (!available) return; /* Listen for RandR events */ XRRSelectInput(disp, WinGetXwin(VROOT), RRScreenChangeNotifyMask); XRRRotations(disp, Dpy.screen, &rot); Mode.screen.rotation = rot; #if 0 /* Debug */ if (EDebug(EDBUG_TYPE_VERBOSE)) { XRRScreenResources *psr; XRRCrtcInfo *pci; XRROutputInfo *poi; int i; psr = XRRGetScreenResources(disp, WinGetXwin(VROOT)); if (!psr) return; Eprintf("CRTC ID X,Y WxH mode rot nout\n"); for (i = 0; i < psr->ncrtc; i++) { pci = XRRGetCrtcInfo(disp, psr, psr->crtcs[i]); if (!pci) break; Eprintf("%3d %#04lx %4d,%4d %4ux%4u %#04lx %4d %5d\n", i, psr->crtcs[i], pci->x, pci->y, pci->width, pci->height, pci->mode, pci->rotation, pci->noutput); XRRFreeCrtcInfo(pci); } Eprintf("OUTP ID Name WxH crtc ncrtc nclon nmode\n"); for (i = 0; i < psr->noutput; i++) { poi = XRRGetOutputInfo(disp, psr, psr->outputs[i]); if (!poi) break; Eprintf("%3d %#04lx %-8s %4lux%4lu %#04lx %4d %5d %5d\n", i, psr->outputs[i], poi->name, poi->mm_width, poi->mm_height, poi->crtc, poi->ncrtc, poi->nclone, poi->nmode); XRRFreeOutputInfo(poi); } XRRFreeScreenResources(psr); } #endif }
// Set the current video mode for the specified monitor // void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired) { if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { XRRScreenResources* sr; XRRCrtcInfo* ci; XRROutputInfo* oi; GLFWvidmode current; const GLFWvidmode* best; RRMode native = None; int i; best = _glfwChooseVideoMode(monitor, desired); _glfwPlatformGetVideoMode(monitor, ¤t); if (_glfwCompareVideoModes(¤t, best) == 0) return; sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); for (i = 0; i < oi->nmode; i++) { const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); if (!modeIsGood(mi)) continue; const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci); if (_glfwCompareVideoModes(best, &mode) == 0) { native = mi->id; break; } } if (native) { if (monitor->x11.oldMode == None) monitor->x11.oldMode = ci->mode; XRRSetCrtcConfig(_glfw.x11.display, sr, monitor->x11.crtc, CurrentTime, ci->x, ci->y, native, ci->rotation, ci->outputs, ci->noutput); } XRRFreeOutputInfo(oi); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); } }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count) { GLFWvidmode* result; *count = 0; if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { int i, j; XRRScreenResources* sr; XRRCrtcInfo* ci; XRROutputInfo* oi; sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); result = calloc(oi->nmode, sizeof(GLFWvidmode)); for (i = 0; i < oi->nmode; i++) { const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); if (!modeIsGood(mi)) continue; const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci); for (j = 0; j < *count; j++) { if (_glfwCompareVideoModes(result + j, &mode) == 0) break; } // Skip duplicate modes if (j < *count) continue; (*count)++; result[*count - 1] = mode; } XRRFreeOutputInfo(oi); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); } else { *count = 1; result = calloc(1, sizeof(GLFWvidmode)); _glfwPlatformGetVideoMode(monitor, result); } return result; }
void RandROutput::loadSettings(bool notify) { int changes = 0; XRROutputInfo *info = XRRGetOutputInfo(QX11Info::display(), m_screen->resources(), m_id); Q_ASSERT(info); if (RandR::timestamp != info->timestamp) RandR::timestamp = info->timestamp; // this information shouldn't change, so m_name = info->name; m_possibleCrtcs.clear(); for (int i = 0; i < info->ncrtc; ++i) m_possibleCrtcs.append(info->crtcs[i]); //check if the crtc changed if (info->crtc != m_currentCrtc) { setCrtc(info->crtc); changes |= RandR::ChangeCrtc; } bool connected = (info->connection == RR_Connected); if (connected != m_connected) { m_connected = connected; changes |= RandR::ChangeConnection; } //CHECK: is it worth notifying changes on mode list changing? //get modes m_modes.clear(); for (int i = 0; i < info->nmode; ++i) m_modes.append(info->modes[i]); //get all possible rotations m_rotations = 0; for (int i = 0; i < m_possibleCrtcs.count(); ++i) { RandRCrtc *crtc = m_screen->crtc(m_possibleCrtcs.at(i)); Q_ASSERT(crtc); m_rotations |= crtc->rotations(); } // free the info XRRFreeOutputInfo(info); if (changes && notify) emit outputChanged(m_id, changes); }
/* * Class: jogamp_newt_driver_x11_RandR13 * Method: getMonitorDevice0 * Signature: (JJJJ)[I */ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDevice0 (JNIEnv *env, jclass clazz, jlong display, jlong screenResources, jlong monitorInfo, jint crt_idx) { Display * dpy = (Display *) (intptr_t) display; XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo; if( NULL == resources || NULL == xrrCrtcInfo || crt_idx >= resources->ncrtc ) { // n/a return NULL; } if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) { // disabled return NULL; } RROutput output = xrrCrtcInfo->outputs[0]; XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output); int numModes = xrrOutputInfo->nmode; jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 + numModes; jint prop[ propCount ]; int propIndex = 0; prop[propIndex++] = propCount; prop[propIndex++] = crt_idx; prop[propIndex++] = xrrOutputInfo->mm_width; prop[propIndex++] = xrrOutputInfo->mm_height; prop[propIndex++] = xrrCrtcInfo->x; prop[propIndex++] = xrrCrtcInfo->y; prop[propIndex++] = xrrCrtcInfo->width; prop[propIndex++] = xrrCrtcInfo->height; prop[propIndex++] = xrrCrtcInfo->mode; // current mode id prop[propIndex++] = NewtScreen_XRotation2Degree(env, xrrCrtcInfo->rotation); int i; for(i=0; i<numModes; i++) { // avail modes .. prop[propIndex++] = xrrOutputInfo->modes[i]; } XRRFreeOutputInfo (xrrOutputInfo); jintArray properties = (*env)->NewIntArray(env, propCount); if (properties == NULL) { NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount); } (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop); return properties; }
static RRCrtc get_crtc_id(Display *display, XRRScreenResources *resources, const char* const x_output_name) { if (!display || !resources || !x_output_name) return (RRCrtc) -1; size_t len = strlen(x_output_name); if (len == 0) return (RRCrtc) -1; // Check if x_output_name is XID bool is_digit = true; for (size_t i = 0; i < len; ++i) { if (!isdigit(x_output_name[i])) { is_digit = false; break; } } XRROutputInfo *output_info = 0; for (int i = 0; i < resources->noutput; ++i) { XRROutputInfo *info = XRRGetOutputInfo(display, resources, resources->outputs[i]); if (is_digit) { RROutput output = strtoul(x_output_name, 0, 0); if (output == resources->outputs[i]) { output_info = info; break; } } else { if (strcmp(x_output_name, info->name) == 0) { output_info = info; break; } } XRRFreeOutputInfo(info); } RRCrtc crtc_id = (RRCrtc) -1; if (output_info) { if (output_info->connection != RR_Connected) printf("Output \"%s\" is not connected to a monitor. Default will be used.\n", output_info->name); else crtc_id = output_info->crtc; XRRFreeOutputInfo(output_info); } else printf("\"%s\" is not valid output. Default will be used.\n", x_output_name); return crtc_id; }
static void dumpOutputs(const char *prefix, Display *dpy, XRRScreenResources *resources, int noutput, RROutput * outputs) { int i, j; fprintf(stderr, "%s %p: Output count %d\n", prefix, resources, noutput); for(i=0; i<noutput; i++) { RROutput output = outputs[i]; XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output); fprintf(stderr, " Output[%d]: id %#lx, crtx 0x%X, name %s (%d), %lux%lu, ncrtc %d, .., nmode %d (preferred %d)\n", i, output, xrrOutputInfo->crtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, xrrOutputInfo->ncrtc, xrrOutputInfo->nmode, xrrOutputInfo->npreferred); for(j=0; j<xrrOutputInfo->nmode; j++) { fprintf(stderr, " Output[%d].Mode[%d].id %#lx\n", i, j, xrrOutputInfo->modes[j]); } XRRFreeOutputInfo (xrrOutputInfo); } }
void get_xrandr_config(Display *dpy, Window root, char *name, int *x, int *y, int *width, int *height) { XRRScreenResources *res; XRROutputInfo *output_info; XRRCrtcInfo *crtc_info; int o, found = 0; res = XRRGetScreenResources(dpy, root); for (o = 0; o < res->noutput; o++) { output_info = XRRGetOutputInfo (dpy, res, res->outputs[o]); if (!output_info) { fprintf(stderr, "could not get output 0x%lx information\n", res->outputs[o]); exit(2); } if (output_info->crtc != 0) { crtc_info = XRRGetCrtcInfo(dpy, res, output_info->crtc); if (!crtc_info) { fprintf(stderr, "%s: could not get crtc 0x%lx " "information\n", __progname, output_info->crtc); exit(2); } printf("%s: %dx%d+%d+%d\n", output_info->name, crtc_info->width, crtc_info->height, crtc_info->x, crtc_info->y); if (!strcmp(output_info->name, name)) { *x = crtc_info->x; *y = crtc_info->y; *width = crtc_info->width; *height = crtc_info->height; found = 1; } } } if (!found) { fprintf(stderr, "%s: output %s not found\n", __progname, name); exit(2); } }
static XRROutputInfo * pick_output (Display *xdpy, XRRScreenResources *screen_res) { XRROutputInfo *laptop_output = NULL; XRROutputInfo *external_output = NULL; int i; for (i = 0; i < screen_res->noutput; i++) { XRROutputInfo *oi; RROutput o = screen_res->outputs[i]; oi = XRRGetOutputInfo (xdpy, screen_res, o); if (oi->connection != RR_Connected) { XRRFreeOutputInfo (oi); continue; } if (output_is_laptop (oi->name)) { if (laptop_output) XRRFreeOutputInfo (laptop_output); laptop_output = oi; } else { if (external_output) XRRFreeOutputInfo (external_output); external_output = oi; } } g_assert (laptop_output || external_output); return external_output ? external_output : laptop_output; }
int init_monitor(){ int outi; char msg[255]; dis = XOpenDisplay(NULL); startLogger(); if (!dis){ logMessage(ERROR, "Cannot connect into XServer using default display...exiting"); return ENOMEM; } screen = DefaultScreen(dis); logMessage(INFO, "Loading root window"); root = RootWindow(dis, screen); /*Select X input to handle the events*/ logMessage(INFO, "Selecting input"); XSelectInput(dis, root, StructureNotifyMask); /*Getting Screen Resources*/ logMessage(INFO, "Getting screen resources"); res = XRRGetScreenResources(dis, root); sprintf(msg, "%d resources found", res->noutput); logMessage(INFO, msg); for (outi = 0; outi < res->noutput; outi++){ output_info = XRRGetOutputInfo(dis, res, res->outputs[outi]); sprintf(msg, "Output name: %s", output_info->name); logMessage(INFO, msg); } return 0; }
int _screen_info(const char *name, int num, Rect *r) { XRRScreenResources *res = XRRGetScreenResources(dpy, root); if (!res) return 0; int i, n = res->noutput; XRROutputInfo *info; XRRCrtcInfo *crtc; r->w = r->h = 0; for (i = 0; i < n; ++i) { /* skip if output lacks info or crtc */ if (!(info=XRRGetOutputInfo(dpy, res, res->outputs[i]))) continue; if (!info->crtc || !(crtc=XRRGetCrtcInfo(dpy,res,info->crtc))) { XRRFreeOutputInfo(info); continue; } /* skip if name is provided and doesn't match */ if (name && strncmp(name, info->name, strlen(name))) { XRRFreeCrtcInfo(crtc); XRRFreeOutputInfo(info); continue; } /* and skip if number is provided and doesn't match */ if (num && num - 1 != i) { XRRFreeCrtcInfo(crtc); XRRFreeOutputInfo(info); continue; } /* match found, return size */ r->x = crtc->x; r->y = crtc->y; r->w = crtc->width; r->h = crtc->height; XRRFreeCrtcInfo(crtc); XRRFreeOutputInfo(info); if (r->w && r->h) break; } XRRFreeScreenResources(res); return n; }
void XRRConfiguration::AddResolutions(std::vector<std::string>& resos) { if (!bValid || !screenResources) return; //Get all full screen resolutions for the config dialog for (int i = 0; i < screenResources->noutput; i++) { XRROutputInfo *output_info = XRRGetOutputInfo(dpy, screenResources, screenResources->outputs[i]); if (output_info && output_info->crtc && output_info->connection == RR_Connected) { for (int j = 0; j < output_info->nmode; j++) { for (int k = 0; k < screenResources->nmode; k++) { if (output_info->modes[j] == screenResources->modes[k].id) { bool interlaced = !!(screenResources->modes[k].modeFlags & RR_Interlace); const std::string strRes = std::string(output_info->name) + ": " + std::string(screenResources->modes[k].name) + (interlaced? "i" : ""); // Only add unique resolutions if (std::find(resos.begin(), resos.end(), strRes) == resos.end()) { resos.push_back(strRes); } } } } } if (output_info) XRRFreeOutputInfo(output_info); } }
JNIEXPORT jlong JNICALL Java_org_lwjgl_system_linux_Xrandr_nXRRGetOutputInfo(JNIEnv *__env, jclass clazz, jlong displayAddress, jlong resourcesAddress, jlong output) { Display *display = (Display *)(intptr_t)displayAddress; XRRScreenResources *resources = (XRRScreenResources *)(intptr_t)resourcesAddress; UNUSED_PARAMS(__env, clazz) return (jlong)(intptr_t)XRRGetOutputInfo(display, resources, (RROutput)output); }
void XRRConfiguration::Update() { if (SConfig::GetInstance().strFullscreenResolution == "Auto") return; if (!bValid) return; if (outputInfo) { XRRFreeOutputInfo(outputInfo); outputInfo = nullptr; } if (crtcInfo) { XRRFreeCrtcInfo(crtcInfo); crtcInfo = nullptr; } fullMode = 0; // Get the resolution setings for fullscreen mode unsigned int fullWidth, fullHeight; char *output_name = nullptr; char auxFlag = '\0'; if (SConfig::GetInstance().strFullscreenResolution.find(':') == std::string::npos) { fullWidth = fb_width; fullHeight = fb_height; } else { sscanf(SConfig::GetInstance().strFullscreenResolution.c_str(), "%m[^:]: %ux%u%c", &output_name, &fullWidth, &fullHeight, &auxFlag); } bool want_interlaced = ('i' == auxFlag); for (int i = 0; i < screenResources->noutput; i++) { XRROutputInfo *output_info = XRRGetOutputInfo(dpy, screenResources, screenResources->outputs[i]); if (output_info && output_info->crtc && output_info->connection == RR_Connected) { XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(dpy, screenResources, output_info->crtc); if (crtc_info) { if (!output_name || !strcmp(output_name, output_info->name)) { // Use the first output for the default setting. if (!output_name) { output_name = strdup(output_info->name); SConfig::GetInstance().strFullscreenResolution = StringFromFormat("%s: %ux%u", output_info->name, fullWidth, fullHeight); } outputInfo = output_info; crtcInfo = crtc_info; for (int j = 0; j < output_info->nmode && fullMode == 0; j++) { for (int k = 0; k < screenResources->nmode && fullMode == 0; k++) { if (output_info->modes[j] == screenResources->modes[k].id) { if (fullWidth == screenResources->modes[k].width && fullHeight == screenResources->modes[k].height && want_interlaced == !!(screenResources->modes[k].modeFlags & RR_Interlace)) { fullMode = screenResources->modes[k].id; if (crtcInfo->x + (int)screenResources->modes[k].width > fs_fb_width) fs_fb_width = crtcInfo->x + screenResources->modes[k].width; if (crtcInfo->y + (int)screenResources->modes[k].height > fs_fb_height) fs_fb_height = crtcInfo->y + screenResources->modes[k].height; } } } } } else { if (crtc_info->x + (int)crtc_info->width > fs_fb_width) fs_fb_width = crtc_info->x + crtc_info->width; if (crtc_info->y + (int)crtc_info->height > fs_fb_height) fs_fb_height = crtc_info->y + crtc_info->height; } } if (crtc_info && crtcInfo != crtc_info) XRRFreeCrtcInfo(crtc_info); } if (output_info && outputInfo != output_info) XRRFreeOutputInfo(output_info); } fs_fb_width_mm = fs_fb_width * DisplayHeightMM(dpy, screen) / DisplayHeight(dpy, screen); fs_fb_height_mm = fs_fb_height * DisplayHeightMM(dpy, screen) / DisplayHeight(dpy, screen); if (output_name) free(output_name); if (outputInfo && crtcInfo && fullMode) { INFO_LOG(VIDEO, "Fullscreen Resolution %dx%d", fullWidth, fullHeight); } else { ERROR_LOG(VIDEO, "Failed to obtain fullscreen size.\n" "Using current desktop resolution for fullscreen."); } }
static gboolean output_initialize (MateRROutput *output, XRRScreenResources *res, GError **error) { XRROutputInfo *info = XRRGetOutputInfo ( DISPLAY (output), res, output->id); GPtrArray *a; int i; #if 0 g_print ("Output %lx Timestamp: %u\n", output->id, (guint32)info->timestamp); #endif if (!info || !output->info) { /* FIXME: see the comment in crtc_initialize() */ /* Translators: here, an "output" is a video output */ g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_RANDR_ERROR, _("could not get information about output %d"), (int) output->id); return FALSE; } output->name = g_strdup (info->name); /* FIXME: what is nameLen used for? */ output->current_crtc = crtc_by_id (output->info, info->crtc); output->width_mm = info->mm_width; output->height_mm = info->mm_height; output->connected = (info->connection == RR_Connected); output->connector_type = get_connector_type_string (output); /* Possible crtcs */ a = g_ptr_array_new (); for (i = 0; i < info->ncrtc; ++i) { MateRRCrtc *crtc = crtc_by_id (output->info, info->crtcs[i]); if (crtc) g_ptr_array_add (a, crtc); } g_ptr_array_add (a, NULL); output->possible_crtcs = (MateRRCrtc **)g_ptr_array_free (a, FALSE); /* Clones */ a = g_ptr_array_new (); for (i = 0; i < info->nclone; ++i) { MateRROutput *mate_rr_output = mate_rr_output_by_id (output->info, info->clones[i]); if (mate_rr_output) g_ptr_array_add (a, mate_rr_output); } g_ptr_array_add (a, NULL); output->clones = (MateRROutput **)g_ptr_array_free (a, FALSE); /* Modes */ a = g_ptr_array_new (); for (i = 0; i < info->nmode; ++i) { MateRRMode *mode = mode_by_id (output->info, info->modes[i]); if (mode) g_ptr_array_add (a, mode); } g_ptr_array_add (a, NULL); output->modes = (MateRRMode **)g_ptr_array_free (a, FALSE); output->n_preferred = info->npreferred; /* Edid data */ output->edid_data = read_edid_data (output); XRRFreeOutputInfo (info); return TRUE; }
static void xfce_randr_populate (XfceRandr *randr, Display *xdisplay, GdkWindow *root_window) { GPtrArray *outputs; XRROutputInfo *output_info; XRRCrtcInfo *crtc_info; gint n; guint m; g_return_if_fail (randr != NULL); g_return_if_fail (randr->priv != NULL); g_return_if_fail (randr->priv->resources != NULL); /* prepare the temporary cache */ outputs = g_ptr_array_new (); /* walk the outputs */ for (n = 0; n < randr->priv->resources->noutput; ++n) { /* get the output info */ output_info = XRRGetOutputInfo (xdisplay, randr->priv->resources, randr->priv->resources->outputs[n]); /* forget about disconnected outputs */ if (output_info->connection != RR_Connected) { XRRFreeOutputInfo (output_info); continue; } /* cache it */ g_ptr_array_add (outputs, output_info); } /* migrate the temporary cache */ randr->noutput = outputs->len; randr->priv->output_info = (XRROutputInfo **) g_ptr_array_free (outputs, FALSE); /* allocate final space for the settings */ randr->mode = g_new0 (RRMode, randr->noutput); randr->priv->modes = g_new0 (XfceRRMode *, randr->noutput); randr->priv->position = g_new0 (XfceOutputPosition, randr->noutput); randr->rotation = g_new0 (Rotation, randr->noutput); randr->rotations = g_new0 (Rotation, randr->noutput); randr->relation = g_new0 (XfceOutputRelation, randr->noutput); randr->related_to = g_new0 (guint, randr->noutput); randr->status = g_new0 (XfceOutputStatus, randr->noutput); randr->friendly_name = g_new0 (gchar *, randr->noutput); /* walk the connected outputs */ for (m = 0; m < randr->noutput; ++m) { /* fill in supported modes */ randr->priv->modes[m] = xfce_randr_list_supported_modes (randr->priv->resources, randr->priv->output_info[m]); #ifdef HAS_RANDR_ONE_POINT_THREE /* find the primary screen if supported */ if (randr->priv->has_1_3 && XRRGetOutputPrimary (xdisplay, GDK_WINDOW_XID (root_window)) == randr->priv->resources->outputs[m]) randr->status[m] = XFCE_OUTPUT_STATUS_PRIMARY; else #endif randr->status[m] = XFCE_OUTPUT_STATUS_SECONDARY; if (randr->priv->output_info[m]->crtc != None) { crtc_info = XRRGetCrtcInfo (xdisplay, randr->priv->resources, randr->priv->output_info[m]->crtc); randr->mode[m] = crtc_info->mode; randr->rotation[m] = crtc_info->rotation; randr->rotations[m] = crtc_info->rotations; randr->priv->position[m].x = crtc_info->x; randr->priv->position[m].y = crtc_info->y; XRRFreeCrtcInfo (crtc_info); } else { /* output disabled */ randr->mode[m] = None; randr->rotation[m] = RR_Rotate_0; randr->rotations[m] = xfce_randr_get_safe_rotations (randr, xdisplay, m); } /* fill in the name used by the UI */ randr->friendly_name[m] = xfce_randr_friendly_name (randr, m); } /* calculate relations from positions */ xfce_randr_guess_relations (randr); }
GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) { GLFWvidmode* result; int depth, r, g, b; depth = DefaultDepth(_glfw.x11.display, _glfw.x11.screen); _glfwSplitBPP(depth, &r, &g, &b); *found = 0; // Build array of available resolutions if (_glfw.x11.randr.available) { int i, j; XRRScreenResources* sr; XRROutputInfo* oi; sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); result = calloc(oi->nmode, sizeof(GLFWvidmode)); for (i = 0; i < oi->nmode; i++) { GLFWvidmode mode; const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]); mode.width = mi->width; mode.height = mi->height; mode.refreshRate = calculateRefreshRate(mi); for (j = 0; j < *found; j++) { if (result[j].width == mode.width && result[j].height == mode.height && result[j].refreshRate == mode.refreshRate) { break; } } if (j < *found) { // This is a duplicate, so skip it continue; } mode.redBits = r; mode.greenBits = g; mode.blueBits = b; result[*found] = mode; (*found)++; } XRRFreeOutputInfo(oi); XRRFreeScreenResources(sr); } else { *found = 1; result = calloc(1, sizeof(GLFWvidmode)); result[0].width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen); result[0].height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen); result[0].redBits = r; result[0].greenBits = g; result[0].blueBits = b; result[0].refreshRate = 0; } return result; }
// Set the current video mode for the specified monitor // void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) { if (_glfw.x11.randr.available) { int i, j; XRRScreenResources* sr; XRRCrtcInfo* ci; XRROutputInfo* oi; RRMode bestMode = 0; unsigned int sizeDiff, leastSizeDiff = UINT_MAX; unsigned int rateDiff, leastRateDiff = UINT_MAX; sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output); for (i = 0; i < sr->nmode; i++) { const XRRModeInfo* mi = sr->modes + i; if (mi->modeFlags & RR_Interlace) continue; for (j = 0; j < oi->nmode; j++) { if (oi->modes[j] == mi->id) break; } if (j == oi->nmode) continue; sizeDiff = (mi->width - desired->width) * (mi->width - desired->width) + (mi->height - desired->height) * (mi->height - desired->height); if (desired->refreshRate) rateDiff = abs(calculateRefreshRate(mi) - desired->refreshRate); else rateDiff = UINT_MAX - calculateRefreshRate(mi); if ((sizeDiff < leastSizeDiff) || (sizeDiff == leastSizeDiff && rateDiff < leastRateDiff)) { bestMode = mi->id; leastSizeDiff = sizeDiff; leastRateDiff = rateDiff; } } if (bestMode == ci->mode) return; if (monitor->x11.oldMode == None) monitor->x11.oldMode = ci->mode; XRRSetCrtcConfig(_glfw.x11.display, sr, monitor->x11.crtc, CurrentTime, ci->x, ci->y, bestMode, ci->rotation, ci->outputs, ci->noutput); XRRFreeOutputInfo(oi); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); } }
void psb_xrandr_refresh(VADriverContextP ctx) { int i; XRROutputInfo *output_info; XRRCrtcInfo *crtc_info; psb_xrandr_crtc_p p_crtc; psb_xrandr_output_p p_output; pthread_mutex_lock(&psb_xrandr_info->psb_extvideo_mutex); //deinit crtc if (psb_xrandr_info->crtc_head) { while (psb_xrandr_info->crtc_head) { psb_xrandr_info->crtc_tail = psb_xrandr_info->crtc_head->next; free(psb_xrandr_info->crtc_head); psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail; } psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail = NULL; } for (i = 0; i < psb_xrandr_info->res->ncrtc; i++) { crtc_info = XRRGetCrtcInfo(psb_xrandr_info->dpy, psb_xrandr_info->res, psb_xrandr_info->res->crtcs[i]); if (crtc_info) { p_crtc = (psb_xrandr_crtc_p)calloc(1, sizeof(psb_xrandr_crtc_s)); if (!p_crtc) { drv_debug_msg(VIDEO_DEBUG_ERROR, "output of memory\n"); return; } if (i == 0) psb_xrandr_info->crtc_head = psb_xrandr_info->crtc_tail = p_crtc; p_crtc->crtc_id = psb_xrandr_info->res->crtcs[i]; p_crtc->x = crtc_info->x; p_crtc->y = crtc_info->y; p_crtc->width = crtc_info->width; p_crtc->height = crtc_info->height; p_crtc->crtc_mode = crtc_info->mode; p_crtc->noutput = crtc_info->noutput; p_crtc->rotation = crtc_info->rotation; psb_xrandr_info->crtc_tail->next = p_crtc; p_crtc->next = NULL; psb_xrandr_info->crtc_tail = p_crtc; } else { drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get crtc_info\n"); pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return; } } //deinit output if (psb_xrandr_info->output_head) { while (psb_xrandr_info->output_head) { psb_xrandr_info->output_tail = psb_xrandr_info->output_head->next; free(psb_xrandr_info->output_head); psb_xrandr_info->output_head = psb_xrandr_info->output_tail; } psb_xrandr_info->output_head = psb_xrandr_info->output_tail = NULL; } #if 0 //destroy the full-screen window //FIXME: commited out for X Error message: BadDrawable, need more investigation if (va_output) { if (va_output->extend_drawable) { XDestroyWindow(ctx->native_dpy, va_output->extend_drawable); va_output->extend_drawable = 0; texture_priv->extend_dri_init_flag = 0; } } #endif for (i = 0; i < psb_xrandr_info->res->noutput; i++) { output_info = XRRGetOutputInfo(psb_xrandr_info->dpy, psb_xrandr_info->res, psb_xrandr_info->res->outputs[i]); if (output_info) { p_output = (psb_xrandr_output_p)calloc(1, sizeof(psb_xrandr_output_s)); if (!p_output) { drv_debug_msg(VIDEO_DEBUG_ERROR, "output of memory\n"); return; } if (i == 0) psb_xrandr_info->output_head = psb_xrandr_info->output_tail = p_output; p_output->output_id = psb_xrandr_info->res->outputs[i]; p_output->connection = output_info->connection; if (p_output->connection == RR_Connected) psb_xrandr_info->nconnected_output++; strcpy(p_output->name, output_info->name); if (output_info->crtc) p_output->crtc = get_crtc_by_id(output_info->crtc); else p_output->crtc = NULL; psb_xrandr_info->output_tail->next = p_output; p_output->next = NULL; psb_xrandr_info->output_tail = p_output; } else { drv_debug_msg(VIDEO_DEBUG_ERROR, "failed to get output_info\n"); pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); return; } } psb_xrandr_coordinate_init(ctx); psb_RecalcAlternativeOutput(ctx); pthread_mutex_unlock(&psb_xrandr_info->psb_extvideo_mutex); }