void ui_get_screen_res(int *x0, int *y0, int *width, int *height, int monitor) { int i, n, x, y, di; unsigned int du; Window dw; XRRScreenResources *sr; XRRCrtcInfo *ci = NULL; if (getenv("JGMENU_SCREEN_INFO")) print_screen_info(); sr = XRRGetScreenResources(ui->dpy, DefaultRootWindow(ui->dpy)); BUG_ON(!sr); n = sr->ncrtc; /* * Global variable config.monitor let's the user specify a monitor. * If not set, we use the current pointer position */ if (monitor) { if (monitor > n) die("cannot connect to monitor '%d'", monitor); ci = XRRGetCrtcInfo(ui->dpy, sr, sr->crtcs[monitor - 1]); if (!ci->noutput) die("cannot connect to monitor '%d'", monitor); info("using user specified monitor '%d'", monitor); goto monitor_selected; } XQueryPointer(ui->dpy, ui->root, &dw, &dw, &x, &y, &di, &di, &du); for (i = 0; i < n; i++) { if (ci) XRRFreeCrtcInfo(ci); ci = XRRGetCrtcInfo(ui->dpy, sr, sr->crtcs[i]); BUG_ON(!ci); if (!ci->noutput) continue; if (intersect(x, y, 1, 1, ci)) { info("using monitor '%d'", i + 1); break; } } monitor_selected: if (!ci) die("connection could be established to monitor"); *x0 = ci->x; *y0 = ci->y; *width = ci->width; *height = ci->height; XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); }
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 _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) { if (_glfw.x11.randr.available) { XRRScreenResources* sr; XRRCrtcInfo* ci; sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); mode->width = ci->width; mode->height = ci->height; mode->refreshRate = calculateRefreshRate(getModeInfo(sr, ci->mode)); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); } else { mode->width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen); mode->height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen); mode->refreshRate = 0; } _glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen), &mode->redBits, &mode->greenBits, &mode->blueBits); }
static int map_output_xrandr(Display *dpy, int deviceid, const char *output_name) { int rc = EXIT_FAILURE; XRRScreenResources *res; XRROutputInfo *output_info; res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy)); output_info = find_output_xrandr(dpy, output_name); /* crtc holds our screen info, need to compare to actual screen size */ if (output_info) { XRRCrtcInfo *crtc_info; Matrix m; matrix_set_unity(&m); crtc_info = XRRGetCrtcInfo (dpy, res, output_info->crtc); set_transformation_matrix(dpy, &m, crtc_info->x, crtc_info->y, crtc_info->width, crtc_info->height); rc = apply_matrix(dpy, deviceid, &m); XRRFreeCrtcInfo(crtc_info); XRRFreeOutputInfo(output_info); } else printf("Unable to find output '%s'. " "Output may not be connected.\n", output_name); XRRFreeScreenResources(res); return rc; }
int get_screen_geom(Window last_focused, int *x, int *y, int *w, int *h) { int i; XWindowAttributes wa; XRRScreenResources *resources; XRRCrtcInfo *monitor_info; XGetWindowAttributes(dpy, last_focused, &wa); /* TODO externalize resources */ resources = XRRGetScreenResourcesCurrent(dpy, last_focused); for (i = 0; i < resources->ncrtc; i++) { monitor_info = XRRGetCrtcInfo(dpy, resources, resources->crtcs[i]); if (wa.x >= monitor_info->x && wa.x <= monitor_info->x + monitor_info->width - 1 && wa.y >= monitor_info->y && wa.y <= monitor_info->y + monitor_info->height - 1) { *x = monitor_info->x; *y = monitor_info->y; *w = monitor_info->width; *h = monitor_info->height; return 1; } } return 0; }
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; }
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; }
// Restore the saved (original) video mode for the specified monitor // void _glfwRestoreVideoMode(_GLFWmonitor* monitor) { if (_glfw.x11.randr.available) { XRRScreenResources* sr; XRRCrtcInfo* ci; if (monitor->x11.oldMode == None) return; sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); XRRSetCrtcConfig(_glfw.x11.display, sr, monitor->x11.crtc, CurrentTime, ci->x, ci->y, monitor->x11.oldMode, ci->rotation, ci->outputs, ci->noutput); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); monitor->x11.oldMode = None; } }
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) { if (_glfw.x11.randr.available) { XRRScreenResources* sr; XRRCrtcInfo* ci; sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); if (xpos) *xpos = ci->x; if (ypos) *ypos = ci->y; XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); } else { if (xpos) *xpos = 0; if (ypos) *ypos = 0; } }
int get_monitor_dims(int *ret_left_x, int *ret_right_x, int *ret_top_y, int *ret_bottom_y, int i) { Display *display; if (!(display = XOpenDisplay(0))) { return ERR_COULDNT_OPEN_X_DISPLAY; } XRRScreenResources *screen_res = XRRGetScreenResources(display, DefaultRootWindow(display)); *ret_left_x = INT_MAX; *ret_right_x = INT_MIN; *ret_top_y = INT_MAX; *ret_bottom_y = INT_MIN; int nmonitors = 0; XRRGetMonitors(display, DefaultRootWindow(display), 1, &nmonitors); /* If the user requests a screen outside of the number of monitors, exit */ if (i >= nmonitors) { return ERR_MONITOR_DNE; } XRRCrtcInfo *screen_info = XRRGetCrtcInfo(display, screen_res, screen_res->crtcs[i]); *ret_left_x = screen_info->x; *ret_right_x = screen_info->x + screen_info->width; *ret_top_y = screen_info->y; *ret_bottom_y = screen_info->y + screen_info->height; return 0; }
static inline void _gfx_x11_leave_fullscreen( GFX_X11_Monitor* monitor) { Window root = XRootWindowOfScreen(monitor->screen); XRRScreenResources* res = XRRGetScreenResources(_gfx_x11.display, root); XRRCrtcInfo* crtc = XRRGetCrtcInfo(_gfx_x11.display, res, monitor->crtc); /* Set mode */ XRRSetCrtcConfig( _gfx_x11.display, res, monitor->crtc, crtc->timestamp, crtc->x, crtc->y, monitor->mode, crtc->rotation, crtc->outputs, crtc->noutput ); XRRFreeCrtcInfo(crtc); XRRFreeScreenResources(res); }
static XRRCrtcInfo* getXRRCrtcInfo(Display *dpy, XRRScreenResources *resources, RRCrtc _crtc) { RRCrtc crtc = findRRCrtc( resources, _crtc ); if( 0 == crtc ) { return NULL; } else { return XRRGetCrtcInfo (dpy, resources, crtc); } }
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; 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 < *found; j++) { if (_glfwCompareVideoModes(result + j, &mode) == 0) break; } if (j < *found) { // This is a duplicate, so skip it continue; } result[*found] = mode; (*found)++; } XRRFreeOutputInfo(oi); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); } else { *found = 1; result = calloc(1, sizeof(GLFWvidmode)); _glfwPlatformGetVideoMode(monitor, result); } return result; }
int get_monitor_dims_of_focused_screen(int use_anchors, int *ret_left_x, int *ret_right_x, int *ret_top_y, int *ret_bottom_y) { Display *dpy; if (!(dpy = XOpenDisplay(0))) { return ERR_COULDNT_OPEN_X_DISPLAY; } /* Get currently focused window */ Window win = -1; int focus_status; XGetInputFocus(dpy, &win, &focus_status); if (win == PointerRoot || win == None) { return ERR_WIN_NOT_FOUND; } XRRScreenResources *screen_res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy)); XWindowAttributes win_attr; XGetWindowAttributes(dpy, win, &win_attr); int det_x = 0; int det_y = 0; int nmonitors = 0; XRRGetMonitors(dpy, win, 1, &nmonitors); for (int i = 0; i < nmonitors; i++) { XRRCrtcInfo *screen_info = XRRGetCrtcInfo(dpy, screen_res, screen_res->crtcs[i]); /* option flag for using the "anchor" (top left corner) of a window * to determine what screen it belongs to */ if (use_anchors == 1) { det_x = win_attr.x; det_y = win_attr.y; /* Use the center of the window to determine what screen it's on */ } else { det_x = win_attr.x + ((win_attr.width)/2); det_y = win_attr.y + ((win_attr.height)/2); } /* If the window is on the ith screen in the x */ if (det_x >= screen_info->x && det_x < (screen_info->x + screen_info->width)) { /* If the window is on the ith screen in the y */ if (det_y >= screen_info->y && det_y < (screen_info->y + screen_info->height)) { *ret_left_x = screen_info->x; *ret_right_x = screen_info->x + screen_info->width; *ret_top_y = screen_info->y; *ret_bottom_y = screen_info->y + screen_info->height; return 0; } } } /* If the function has not returned yet, then it could not find a screen * on which 'win' resides. */ return ERR_SCREEN_OF_WIN_NOT_FOUND; }
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; }
// 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); } }
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 }
static void _gfx_x11_enter_fullscreen( GFX_X11_Monitor* monitor, Window handle, RRMode mode) { Window root = XRootWindowOfScreen(monitor->screen); XRRScreenResources* res = XRRGetScreenResources(_gfx_x11.display, root); XRRCrtcInfo* crtc = XRRGetCrtcInfo(_gfx_x11.display, res, monitor->crtc); /* Above state */ XEvent event; memset(&event, 0, sizeof(XEvent)); event.type = ClientMessage; event.xclient.window = handle; event.xclient.message_type = _gfx_x11.NET_WM_STATE; event.xclient.format = 32; event.xclient.data.l[0] = 1; event.xclient.data.l[1] = _gfx_x11.NET_WM_STATE_ABOVE; /* Send event, set mode and move window */ XSendEvent( _gfx_x11.display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &event); XRRSetCrtcConfig( _gfx_x11.display, res, monitor->crtc, crtc->timestamp, crtc->x, crtc->y, mode, crtc->rotation, crtc->outputs, crtc->noutput); XMoveWindow( _gfx_x11.display, handle, crtc->x, crtc->y); XRRFreeCrtcInfo(crtc); XRRFreeScreenResources(res); }
// Set the current video mode for the specified monitor // void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired) { if (_glfw.x11.randr.available) { int i; XRRScreenResources* sr; XRRCrtcInfo* ci; RRMode bestMode = 0; unsigned int leastSizeDiff = UINT_MAX, leastRateDiff = UINT_MAX; sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc); for (i = 0; i < sr->nmode; i++) { XRRModeInfo* mi = sr->modes + i; if (mi->modeFlags & RR_Interlace) continue; const unsigned int sizeDiff = (mi->width - desired->width) * (mi->width - desired->width) + (mi->height - desired->height) * (mi->height - desired->height); const unsigned int rateDiff = abs(calculateRefreshRate(mi) - desired->refreshRate); if ((sizeDiff < leastSizeDiff) || (sizeDiff == leastSizeDiff && rateDiff < leastRateDiff)) { bestMode = mi->id; leastSizeDiff = sizeDiff; leastRateDiff = rateDiff; } } 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); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); } }
static int SwitchRes(char inout, int x __UNUSED__, int y __UNUSED__, int w, int h, int *dw, int *dh) { XRRScreenResources *xsr; XRRCrtcInfo *xci; RRCrtc crtc; RRMode ss_mode_new; int ok = 0; Dprintf("%s: inout=%d\n", __func__, inout); xsr = XRRGetScreenResourcesCurrent(disp, WinGetXwin(VROOT)); if (!xsr) goto done; crtc = xsr->crtcs[0]; /* FIXME - Which crtc? */ if (inout) { /* Save current setup */ xci = XRRGetCrtcInfo(disp, xsr, crtc); if (!xci) goto done; ss_mode = xci->mode; ss_rot = xci->rotation; XRRFreeCrtcInfo(xci); /* Select zoomed setup */ ss_mode_new = FindMode(xsr, w, h, dw, dh); /* Set zoomed setup */ SetPanning(xsr, crtc, 1); ok = SetMode(xsr, crtc, ss_mode_new, ss_rot); } else { /* Revert to original setup */ ok = SetMode(xsr, crtc, ss_mode, ss_rot); SetPanning(xsr, crtc, 0); } done: if (xsr) XRRFreeScreenResources(xsr); Dprintf("%s: ok=%d\n", __func__, ok); return ok; }
/* * Class: jogamp_newt_driver_x11_RandR13 * Method: getMonitorInfoHandle0 * Signature: (JIJI)J */ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorInfoHandle0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenResources, jint crt_idx) { Display *dpy = (Display *) (intptr_t) display; Window root = RootWindow(dpy, (int)screen_idx); XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; if( NULL == resources || crt_idx >= resources->ncrtc ) { return 0; } RRCrtc crtc = resources->crtcs[crt_idx]; XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, resources, crtc); return (jlong) (intptr_t) xrrCrtcInfo; }
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); } }
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_dumpInfo0 (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenResources) { Display * dpy = (Display *) (intptr_t) display; Window root = RootWindow(dpy, (int)screen_idx); XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; int pos[] = { 0, 0 } ; int i, j, minWidth, minHeight, maxWidth, maxHeight; int vs_width = DisplayWidth(dpy, screen_idx); int vs_height = DisplayHeight(dpy, screen_idx); int vs_width_mm = DisplayWidthMM(dpy, screen_idx); int vs_height_mm = DisplayHeightMM(dpy, screen_idx); fprintf(stderr, "ScreenVirtualSize: %dx%d %dx%d mm\n", vs_width, vs_height, vs_width_mm, vs_height_mm); XRRGetScreenSizeRange (dpy, root, &minWidth, &minHeight, &maxWidth, &maxHeight); fprintf(stderr, "XRRGetScreenSizeRange: %dx%d .. %dx%d\n", minWidth, minHeight, maxWidth, maxHeight); if( NULL == resources ) { fprintf(stderr, "XRRScreenResources NULL\n"); return; } fprintf(stderr, "XRRScreenResources %p: Crtc count %d\n", resources, resources->ncrtc); for(i=0; i<resources->ncrtc; i++) { RRCrtc crtc = resources->crtcs[i]; XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, resources, crtc); fprintf(stderr, "Crtc[%d] %#lx: %d/%d %dx%d, rot 0x%X, mode.id %#lx\n", i, crtc, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height, xrrCrtcInfo->rotations, xrrCrtcInfo->mode); for(j=0; j<xrrCrtcInfo->noutput; j++) { fprintf(stderr, " Crtc[%d].Output[%d].id %#lx\n", i, j, xrrCrtcInfo->outputs[j]); dumpOutput(" ", dpy, screen_idx, resources, j, xrrCrtcInfo->outputs[j]); } XRRFreeCrtcInfo(xrrCrtcInfo); } dumpOutputs("XRRScreenResources.outputs", dpy, (int)screen_idx, resources, resources->noutput, resources->outputs); fprintf(stderr, "XRRScreenResources %p: Mode count %d\n", resources, resources->nmode); for(i=0; i<resources->nmode; i++) { XRRModeInfo *mode = &resources->modes[i]; unsigned int dots = mode->hTotal * mode->vTotal; float refresh = getVRefresh(mode); fprintf(stderr, "Mode[%d, id %#lx]: %ux%u@%f, name %s\n", i, mode->id, mode->width, mode->height, refresh, SAFE_STRING(mode->name)); } }
std::vector<display> display::enumerate() { std::vector<display> result; if (randr.is_available) { RROutput const primary = XRRGetOutputPrimary(g_display, g_root); XRRScreenResources* sr = XRRGetScreenResources(g_display, g_root); for (int i = 0; i < sr->ncrtc; ++i) { XRRCrtcInfo* info = XRRGetCrtcInfo(g_display, sr, sr->crtcs[i]); if (info->noutput) { RROutput* output = std::find_if(info->outputs, info->outputs + info->noutput, [primary](RROutput output) { return output == primary; }); if (output == info->outputs + info->noutput) { output = info->outputs; } display disp = init(sr, *output); if (!disp.name.empty()) { result.emplace_back(disp); } } XRRFreeCrtcInfo(info); } XRRFreeScreenResources(sr); std::vector<display>::iterator it = std::find_if(result.begin(), result.end(), [primary](display const& disp) { return disp.output == primary; }); if (it != result.begin() && it != result.end()) { std::iter_swap(it, result.begin()); } } else { result.push_back(primary()); } return result; }
/** Returns an int of 0 if it succeeds in finding the screen number of a * given Window or an int representing the error it ran into. * win the Window we are trying to find the screen of. * *dpy pointer to the Display we will be searching on. * *return_screen_num pointer to an int where the function will fill in the * screen number that 'win' belongs to, if it can be found. * This function will return 0 if it was able to find the screen 'win' belongs * to. If it cannot, then it will return the correct * error code for window-not-found. */ int get_screen_number_of_win(Window win, Display *dpy, int use_anchors, \ int *return_screen_num) { XRRScreenResources *screen_res = XRRGetScreenResources(dpy, DefaultRootWindow(dpy)); XWindowAttributes win_attr; XGetWindowAttributes(dpy, win, &win_attr); int det_x = 0; int det_y = 0; int nmonitors = 0; XRRGetMonitors(dpy, win, 1, &nmonitors); for (int i = 0; i < nmonitors; i++) { XRRCrtcInfo *screen_info = XRRGetCrtcInfo(dpy, screen_res, screen_res->crtcs[i]); /* option flag for using the "anchor" (top left corner) of a window * to determine what screen it belongs to */ if (use_anchors == 1) { det_x = win_attr.x; det_y = win_attr.y; /* Use the center of the window to determine what screen it's on */ } else { det_x = win_attr.x + ((win_attr.width)/2); det_y = win_attr.y + ((win_attr.height)/2); } /* If the window is on the ith screen in the x */ if (det_x >= screen_info->x && det_x < (screen_info->x + screen_info->width)) { /* If the window is on the ith screen in the y */ if (det_y >= screen_info->y && det_y < (screen_info->y + screen_info->height)) { *return_screen_num = i; return 0; } } } /* If the function has not returned yet, then it could not find a screen * on which 'win' resides. */ return ERR_SCREEN_OF_WIN_NOT_FOUND; }
static gboolean force_timestamp_update (MateRRScreen *screen) { MateRRCrtc *crtc; XRRCrtcInfo *current_info; Status status; gboolean timestamp_updated; timestamp_updated = FALSE; crtc = screen->info->crtcs[0]; if (crtc == NULL) goto out; current_info = XRRGetCrtcInfo (screen->xdisplay, screen->info->resources, crtc->id); if (current_info == NULL) goto out; gdk_error_trap_push (); status = XRRSetCrtcConfig (screen->xdisplay, screen->info->resources, crtc->id, current_info->timestamp, current_info->x, current_info->y, current_info->mode, current_info->rotation, current_info->outputs, current_info->noutput); XRRFreeCrtcInfo (current_info); gdk_flush (); if (gdk_error_trap_pop ()) goto out; if (status == RRSetConfigSuccess) timestamp_updated = TRUE; out: return timestamp_updated; }
int main(int argc, char **argv) { Display *dpy = XOpenDisplay(NULL); int screen = DefaultScreen(dpy); Window root = RootWindow(dpy, screen); XRRScreenResources *res = XRRGetScreenResourcesCurrent(dpy, root); int temp = 6500; if (argc > 1) temp = atoi(argv[1]); if (temp < 1000 || temp > 10000) temp = 6500; temp -= 1000; double ratio = temp % 500 / 500.0; #define AVG(c) whitepoints[temp / 500].c * (1 - ratio) + whitepoints[temp / 500 + 1].c * ratio double gammar = AVG(r); double gammag = AVG(g); double gammab = AVG(b); int num_crtcs = res->ncrtc; for (int c = 0; c < res->ncrtc; c++) { int crtcxid = res->crtcs[c]; XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(dpy, res, crtcxid); int size = XRRGetCrtcGammaSize(dpy, crtcxid); XRRCrtcGamma *crtc_gamma = XRRAllocGamma(size); for (int i = 0; i < size; i++) { double g = 65535.0 * i / size; crtc_gamma->red[i] = g * gammar; crtc_gamma->green[i] = g * gammag; crtc_gamma->blue[i] = g * gammab; } XRRSetCrtcGamma(dpy, crtcxid, crtc_gamma); XFree(crtc_gamma); } }
display::mode display::current_mode() const { if (randr.is_available) { XRRScreenResources* sr = XRRGetScreenResources(g_display, g_root); XRRCrtcInfo* ci = XRRGetCrtcInfo(g_display, sr, crtc); XRRModeInfo const* mi = mode_info(sr, ci->mode); display::mode const result = make_mode(mi, ci); XRRFreeCrtcInfo(ci); XRRFreeScreenResources(sr); return result; } else { return display::mode(DisplayWidth(g_display, g_screen), DisplayHeight(g_display, g_screen), DefaultDepth(g_display, g_screen), 0); } }
static crtc_t* createCrtcChain(Display *dpy, XRRScreenResources *resources, RRCrtc customCrtc, XRRCrtcInfo *customCrtcInfo, Rotation customRotation, int customX, int customY, XRRModeInfo *customModeInfo) { crtc_t *root_crtc = NULL; crtc_t *iter_crtc = NULL; int i; for(i=0; i<resources->ncrtc; i++) { crtc_t *next_crtc = calloc(1, sizeof(crtc_t)); if( NULL == iter_crtc ) { root_crtc = next_crtc; } else { iter_crtc->next = next_crtc; } iter_crtc = next_crtc; RRCrtc crtcId = resources->crtcs[i]; iter_crtc->crtc_id = crtcId; if( crtcId == customCrtc && 0 != customCrtc ) { iter_crtc->rotation = customRotation; iter_crtc->x = customX; iter_crtc->y = customY; iter_crtc->mode_info = customModeInfo; iter_crtc->mode_id = customModeInfo->id; iter_crtc->crtc_info = customCrtcInfo; } else { XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, resources, crtcId); iter_crtc->rotation = xrrCrtcInfo->rotation; iter_crtc->x = xrrCrtcInfo->x; iter_crtc->y = xrrCrtcInfo->y; iter_crtc->mode_id = xrrCrtcInfo->mode; iter_crtc->mode_info = findMode(resources, iter_crtc->mode_id); iter_crtc->crtc_info = xrrCrtcInfo; } iter_crtc->panning_info = XRRGetPanning(dpy, resources, crtcId); } return root_crtc; }
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; }