/* 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; }
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); }
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; }
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; }
display display::from_window(window const* w) { Window root = w? *w : g_root; display result; if (randr.is_available) { XRRScreenResources* sr = XRRGetScreenResources(g_display, root); RROutput primary = XRRGetOutputPrimary(g_display, g_root); result = init(sr, primary); XRRFreeScreenResources(sr); } else { result.scale = 1; result.color_depth = XDefaultDepth(g_display, g_screen); result.color_depth_per_component = result.color_depth >= 24? 8 : 0; result.rect = result.work_rect = rectangle<int>(0, 0, DisplayWidthMM(g_display, g_screen), DisplayHeightMM(g_display, g_screen)); } return result; }
static gboolean fill_out_screen_info (Display *xdisplay, Window xroot, ScreenInfo *info, gboolean needs_reprobe, GError **error) { #ifdef HAVE_RANDR XRRScreenResources *resources; g_assert (xdisplay != NULL); g_assert (info != NULL); /* First update the screen resources */ if (needs_reprobe) resources = XRRGetScreenResources (xdisplay, xroot); else { /* XRRGetScreenResourcesCurrent is less expensive than * XRRGetScreenResources, however it is available only * in RandR 1.3 or higher */ #if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) /* Runtime check for RandR 1.3 or higher */ if (info->screen->rr_major_version == 1 && info->screen->rr_minor_version >= 3) resources = XRRGetScreenResourcesCurrent (xdisplay, xroot); else resources = XRRGetScreenResources (xdisplay, xroot); #else resources = XRRGetScreenResources (xdisplay, xroot); #endif } if (resources) { if (!fill_screen_info_from_resources (info, resources, error)) return FALSE; } else { g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_RANDR_ERROR, /* Translators: a CRTC is a CRT Controller (this is X terminology). */ _("could not get the screen resources (CRTCs, outputs, modes)")); return FALSE; } /* Then update the screen size range. We do this after XRRGetScreenResources() so that * the X server will already have an updated view of the outputs. */ if (needs_reprobe) { gboolean success; gdk_error_trap_push (); success = XRRGetScreenSizeRange (xdisplay, xroot, &(info->min_width), &(info->min_height), &(info->max_width), &(info->max_height)); gdk_flush (); if (gdk_error_trap_pop ()) { g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_UNKNOWN, _("unhandled X error while getting the range of screen sizes")); return FALSE; } if (!success) { g_set_error (error, MATE_RR_ERROR, MATE_RR_ERROR_RANDR_ERROR, _("could not get the range of screen sizes")); return FALSE; } } else { mate_rr_screen_get_ranges (info->screen, &(info->min_width), &(info->max_width), &(info->min_height), &(info->max_height)); } info->primary = None; #if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) /* Runtime check for RandR 1.3 or higher */ if (info->screen->rr_major_version == 1 && info->screen->rr_minor_version >= 3) { gdk_error_trap_push (); info->primary = XRRGetOutputPrimary (xdisplay, xroot); #if GTK_CHECK_VERSION (3, 0, 0) gdk_error_trap_pop_ignored (); #else gdk_flush (); gdk_error_trap_pop (); /* ignore error */ #endif } #endif return TRUE; #else return FALSE; #endif /* HAVE_RANDR */ }
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); }
static gboolean init_randr13 (GdkScreen *screen) { #ifdef HAVE_RANDR GdkDisplay *display = gdk_screen_get_display (screen); GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); Display *dpy = GDK_SCREEN_XDISPLAY (screen); XRRScreenResources *resources; RROutput primary_output; RROutput first_output = None; int i; GArray *monitors; gboolean randr12_compat = FALSE; if (!display_x11->have_randr13) return FALSE; resources = XRRGetScreenResourcesCurrent (x11_screen->xdisplay, x11_screen->xroot_window); if (!resources) return FALSE; monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor), resources->noutput); for (i = 0; i < resources->noutput; ++i) { XRROutputInfo *output = XRRGetOutputInfo (dpy, resources, resources->outputs[i]); /* Non RandR1.2 X driver have output name "default" */ randr12_compat |= !g_strcmp0 (output->name, "default"); if (output->connection == RR_Disconnected) { XRRFreeOutputInfo (output); continue; } if (output->crtc) { GdkX11Monitor monitor; XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, output->crtc); monitor.geometry.x = crtc->x; monitor.geometry.y = crtc->y; monitor.geometry.width = crtc->width; monitor.geometry.height = crtc->height; monitor.output = resources->outputs[i]; monitor.width_mm = output->mm_width; monitor.height_mm = output->mm_height; monitor.output_name = g_strdup (output->name); /* FIXME: need EDID parser */ monitor.manufacturer = NULL; g_array_append_val (monitors, monitor); XRRFreeCrtcInfo (crtc); } XRRFreeOutputInfo (output); } if (resources->noutput > 0) first_output = resources->outputs[0]; XRRFreeScreenResources (resources); /* non RandR 1.2 X driver doesn't return any usable multihead data */ if (randr12_compat) { guint n_monitors = monitors->len; free_monitors ((GdkX11Monitor *)g_array_free (monitors, FALSE), n_monitors); return FALSE; } g_array_sort (monitors, (GCompareFunc) monitor_compare_function); x11_screen->n_monitors = monitors->len; x11_screen->monitors = (GdkX11Monitor *)g_array_free (monitors, FALSE); x11_screen->primary_monitor = 0; primary_output = XRRGetOutputPrimary (x11_screen->xdisplay, x11_screen->xroot_window); for (i = 0; i < x11_screen->n_monitors; ++i) { if (x11_screen->monitors[i].output == primary_output) { x11_screen->primary_monitor = i; break; } /* No RandR1.3+ available or no primary set, fall back to prefer LVDS as primary if present */ if (primary_output == None && g_ascii_strncasecmp (x11_screen->monitors[i].output_name, "LVDS", 4) == 0) { x11_screen->primary_monitor = i; break; } /* No primary specified and no LVDS found */ if (x11_screen->monitors[i].output == first_output) x11_screen->primary_monitor = i; } return x11_screen->n_monitors > 0; #endif return FALSE; }
static gboolean panel_multiscreen_get_randr_monitors_for_screen (GdkScreen *screen, int *monitors_ret, GdkRectangle **geometries_ret) { #ifdef HAVE_RANDR Display *xdisplay; Window xroot; XRRScreenResources *resources; RROutput primary; GArray *geometries; int i; gboolean driver_is_pre_randr_1_2; if (!have_randr) return FALSE; /* GTK+ 2.14.x uses the Xinerama API, instead of RANDR, to get the * monitor geometries. It does this to avoid calling * XRRGetScreenResources(), which is slow as it re-detects all the * monitors --- note that XRRGetScreenResourcesCurrent() had not been * introduced yet. Using Xinerama in GTK+ has the bad side effect that * gdk_screen_get_monitor_plug_name() will return NULL, as Xinerama * does not provide that information, unlike RANDR. * * Here we need to identify the output names, so that we can put the * built-in LCD in a laptop *before* all other outputs. This is so * that mate-panel will normally prefer to appear on the "native" * display rather than on an external monitor. * * To get the output names and geometries, we will not use * gdk_screen_get_n_monitors() and friends, but rather we will call * XRR*() directly. * * See https://bugzilla.novell.com/show_bug.cgi?id=479684 for this * particular bug, and and * http://bugzilla.gnome.org/show_bug.cgi?id=562944 for a more * long-term solution. */ xdisplay = GDK_SCREEN_XDISPLAY (screen); #if GTK_CHECK_VERSION (3, 0, 0) xroot = GDK_WINDOW_XID (gdk_screen_get_root_window (screen)); #else xroot = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen)); #endif #if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) if (have_randr_1_3) { resources = XRRGetScreenResourcesCurrent (xdisplay, xroot); if (resources->noutput == 0) { /* This might happen if nothing tried to get randr * resources from the server before, so we need an * active probe. See comment #27 in * https://bugzilla.gnome.org/show_bug.cgi?id=597101 */ XRRFreeScreenResources (resources); resources = XRRGetScreenResources (xdisplay, xroot); } } else resources = XRRGetScreenResources (xdisplay, xroot); #else resources = XRRGetScreenResources (xdisplay, xroot); #endif if (!resources) return FALSE; primary = None; #if (RANDR_MAJOR > 1 || (RANDR_MAJOR == 1 && RANDR_MINOR >= 3)) if (have_randr_1_3) primary = XRRGetOutputPrimary (xdisplay, xroot); #endif geometries = g_array_sized_new (FALSE, FALSE, sizeof (GdkRectangle), resources->noutput); driver_is_pre_randr_1_2 = FALSE; for (i = 0; i < resources->noutput; i++) { XRROutputInfo *output; output = XRRGetOutputInfo (xdisplay, resources, resources->outputs[i]); /* Drivers before RANDR 1.2 return "default" for the output * name */ if (g_strcmp0 (output->name, "default") == 0) driver_is_pre_randr_1_2 = TRUE; if (output->connection != RR_Disconnected && output->crtc != 0) { XRRCrtcInfo *crtc; GdkRectangle rect; crtc = XRRGetCrtcInfo (xdisplay, resources, output->crtc); rect.x = crtc->x; rect.y = crtc->y; rect.width = crtc->width; rect.height = crtc->height; XRRFreeCrtcInfo (crtc); if (_panel_multiscreen_output_should_be_first (xdisplay, resources->outputs[i], output, primary)) g_array_prepend_vals (geometries, &rect, 1); else g_array_append_vals (geometries, &rect, 1); } XRRFreeOutputInfo (output); } XRRFreeScreenResources (resources); if (driver_is_pre_randr_1_2) { /* Drivers before RANDR 1.2 don't provide useful info about * outputs */ g_array_free (geometries, TRUE); return FALSE; } if (geometries->len == 0) { /* This can happen in at least one case: * https://bugzilla.novell.com/show_bug.cgi?id=543876 where all * monitors appear disconnected (possibly because the screen * is behing a KVM switch) -- see comment #8. * There might be other cases too, so we stay on the safe side. */ g_array_free (geometries, TRUE); return FALSE; } *monitors_ret = geometries->len; *geometries_ret = (GdkRectangle *) g_array_free (geometries, FALSE); return TRUE; #else return FALSE; #endif }
void get_monitors() { if (XineramaIsActive(server.display)) { int num_monitors; XineramaScreenInfo *info = XineramaQueryScreens(server.display, &num_monitors); XRRScreenResources *res = XRRGetScreenResourcesCurrent(server.display, server.root_win); RROutput primary_output = XRRGetOutputPrimary(server.display, server.root_win); if (res && res->ncrtc >= num_monitors) { // use xrandr to identify monitors (does not work with proprietery nvidia drivers) // Workaround for issue https://gitlab.com/o9000/tint2/issues/353 // on some recent configs, XRRGetScreenResourcesCurrent returns a fantom monitor at last position { int i = res->ncrtc - 1; XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(server.display, res, res->crtcs[i]); if (!(crtc_info->x || crtc_info->y || crtc_info->width || crtc_info->height)) { res->ncrtc -= 1; } XRRFreeCrtcInfo(crtc_info); } printf("xRandr: Found crtc's: %d\n", res->ncrtc); server.monitors = calloc(res->ncrtc, sizeof(Monitor)); for (int i = 0; i < res->ncrtc; ++i) { XRRCrtcInfo *crtc_info = XRRGetCrtcInfo(server.display, res, res->crtcs[i]); server.monitors[i].x = crtc_info->x; server.monitors[i].y = crtc_info->y; server.monitors[i].width = crtc_info->width; server.monitors[i].height = crtc_info->height; server.monitors[i].names = calloc((crtc_info->noutput + 1), sizeof(gchar *)); for (int j = 0; j < crtc_info->noutput; ++j) { XRROutputInfo *output_info = XRRGetOutputInfo(server.display, res, crtc_info->outputs[j]); printf("xRandr: Linking output %s with crtc %d\n", output_info->name, i); server.monitors[i].names[j] = g_strdup(output_info->name); XRRFreeOutputInfo(output_info); server.monitors[i].primary = crtc_info->outputs[j] == primary_output; } server.monitors[i].names[crtc_info->noutput] = NULL; XRRFreeCrtcInfo(crtc_info); } num_monitors = res->ncrtc; } else if (info && num_monitors > 0) { server.monitors = calloc(num_monitors, sizeof(Monitor)); for (int i = 0; i < num_monitors; i++) { server.monitors[i].x = info[i].x_org; server.monitors[i].y = info[i].y_org; server.monitors[i].width = info[i].width; server.monitors[i].height = info[i].height; server.monitors[i].names = 0; } } // Sort monitors by inclusion qsort(server.monitors, num_monitors, sizeof(Monitor), monitor_includes_monitor); // Remove monitors included in other ones int i = 0; while (i < num_monitors) { for (int j = 0; j < i; j++) { if (monitor_includes_monitor(&server.monitors[i], &server.monitors[j]) > 0) { goto next; } } i++; } next: for (int j = i; j < num_monitors; ++j) if (server.monitors[j].names) g_strfreev(server.monitors[j].names); server.num_monitors = i; server.monitors = realloc(server.monitors, server.num_monitors * sizeof(Monitor)); qsort(server.monitors, server.num_monitors, sizeof(Monitor), compare_monitor_pos); if (res) XRRFreeScreenResources(res); XFree(info); } if (!server.num_monitors) { server.num_monitors = 1; server.monitors = calloc(1, sizeof(Monitor)); server.monitors[0].x = server.monitors[0].y = 0; server.monitors[0].width = DisplayWidth(server.display, server.screen); server.monitors[0].height = DisplayHeight(server.display, server.screen); server.monitors[0].names = 0; } }
static int _gfx_x11_init_monitors( int major, int minor) { /* Iterate over all screens */ Screen* def = XDefaultScreenOfDisplay(_gfx_x11.display); unsigned int count = XScreenCount(_gfx_x11.display); while(count--) { /* Get screen resources */ Screen* scr = XScreenOfDisplay(_gfx_x11.display, count); Window root = XRootWindowOfScreen(scr); XRRScreenResources* res = XRRGetScreenResources(_gfx_x11.display, root); RROutput prim = res->outputs[0]; /* Get primary if RandR 1.3 is supported */ if(major > 1 || (major == 1 && minor > 2)) prim = XRRGetOutputPrimary(_gfx_x11.display, root); /* Insert the screen's display modes */ size_t first = _gfx_x11_init_modes(scr, res); /* Iterate through outputs */ unsigned int i; for(i = 0; i < res->noutput; ++i) { /* Validate output */ XRROutputInfo* out = XRRGetOutputInfo(_gfx_x11.display, res, res->outputs[i]); if(out->connection != RR_Connected) { XRRFreeOutputInfo(out); continue; } /* Create new monitor */ XRRCrtcInfo* crtc = XRRGetCrtcInfo(_gfx_x11.display, res, out->crtc); int rot = crtc->rotation & (RR_Rotate_90 | RR_Rotate_270); GFX_X11_Monitor mon = { .screen = scr, .crtc = out->crtc, .mode = crtc->mode, .numModes = 0, .modes = malloc(sizeof(size_t) * out->nmode), .x = crtc->x, .y = crtc->y, .width = rot ? crtc->height : crtc->width, .height = rot ? crtc->width : crtc->height }; /* Retrieve output modes */ unsigned int j; if(mon.modes) for(j = 0; j < out->nmode; ++j) { GFX_X11_Mode* mode; for( mode = gfx_vector_at(&_gfx_x11.modes, first); mode != _gfx_x11.modes.end; mode = gfx_vector_next(&_gfx_x11.modes, mode)) { /* Also check if resolution isn't too big */ if( mode->id == out->modes[j] && mode->mode.width <= crtc->width && mode->mode.height <= crtc->height) { mon.modes[mon.numModes++] = gfx_vector_get_index( &_gfx_x11.modes, mode ); break; } } } /* Insert at beginning if primary */ GFXVectorIterator monPos = scr == def && res->outputs[i] == prim ? _gfx_x11.monitors.begin : _gfx_x11.monitors.end; monPos = gfx_vector_insert(&_gfx_x11.monitors, &mon, monPos); if(monPos == _gfx_x11.monitors.end) free(mon.modes); XRRFreeCrtcInfo(crtc); XRRFreeOutputInfo(out); } XRRFreeScreenResources(res); } /* Need at least one monitor */ return _gfx_x11.monitors.begin != _gfx_x11.monitors.end; } /******************************************************/ static GFXKey _gfx_x11_get_key( KeySym symbol) { /* Unicode numbers */ if(symbol >= XK_0 && symbol <= XK_9) return (GFXKey)(symbol - XK_0 + GFX_KEY_0); /* Keypad numbers */ if(symbol >= XK_KP_0 && symbol <= XK_KP_9) return (GFXKey)(symbol - XK_KP_0 + GFX_KEY_KP_0); /* Unicode capitals */ if(symbol >= XK_A && symbol <= XK_Z) return (GFXKey)(symbol - XK_A + GFX_KEY_A); /* Unicode lowercase */ if(symbol >= XK_a && symbol <= XK_z) return (GFXKey)(symbol - XK_a + GFX_KEY_A); /* Function keys */ if(symbol >= XK_F1 && symbol <= XK_F24) return (GFXKey)(symbol - XK_F1 + GFX_KEY_F1); /* Non-unicode */ switch(symbol) { case XK_VoidSymbol : return GFX_KEY_UNKNOWN; case XK_BackSpace : return GFX_KEY_BACKSPACE; case XK_Tab : return GFX_KEY_TAB; case XK_KP_Tab : return GFX_KEY_TAB; case XK_Clear : return GFX_KEY_CLEAR; case XK_Return : return GFX_KEY_RETURN; case XK_Pause : return GFX_KEY_PAUSE; case XK_Scroll_Lock : return GFX_KEY_SCROLL_LOCK; case XK_Escape : return GFX_KEY_ESCAPE; case XK_Delete : return GFX_KEY_DELETE; case XK_KP_Delete : return GFX_KEY_DELETE; case XK_Home : return GFX_KEY_HOME; case XK_KP_Home : return GFX_KEY_HOME; case XK_Left : return GFX_KEY_LEFT; case XK_KP_Left : return GFX_KEY_LEFT; case XK_Up : return GFX_KEY_UP; case XK_KP_Up : return GFX_KEY_UP; case XK_Right : return GFX_KEY_RIGHT; case XK_KP_Right : return GFX_KEY_RIGHT; case XK_Down : return GFX_KEY_DOWN; case XK_KP_Down : return GFX_KEY_DOWN; case XK_Page_Down : return GFX_KEY_PAGE_DOWN; case XK_KP_Page_Down : return GFX_KEY_PAGE_DOWN; case XK_Page_Up : return GFX_KEY_PAGE_UP; case XK_KP_Page_Up : return GFX_KEY_PAGE_UP; case XK_End : return GFX_KEY_END; case XK_KP_End : return GFX_KEY_END; case XK_Select : return GFX_KEY_SELECT; case XK_Print : return GFX_KEY_PRINT; case XK_Execute : return GFX_KEY_EXECUTE; case XK_Insert : return GFX_KEY_INSERT; case XK_KP_Insert : return GFX_KEY_INSERT; case XK_Menu : return GFX_KEY_MENU; case XK_Cancel : return GFX_KEY_CANCEL; case XK_Help : return GFX_KEY_HELP; case XK_Num_Lock : return GFX_KEY_NUM_LOCK; case XK_KP_Space : return GFX_KEY_SPACE; case XK_space : return GFX_KEY_SPACE; case XK_KP_Enter : return GFX_KEY_KP_RETURN; case XK_KP_Multiply : return GFX_KEY_KP_MULTIPLY; case XK_KP_Add : return GFX_KEY_KP_ADD; case XK_KP_Separator : return GFX_KEY_KP_SEPARATOR; case XK_KP_Subtract : return GFX_KEY_KP_SUBTRACT; case XK_KP_Decimal : return GFX_KEY_KP_DECIMAL; case XK_KP_Divide : return GFX_KEY_KP_DIVIDE; case XK_Shift_L : return GFX_KEY_SHIFT_LEFT; case XK_Shift_R : return GFX_KEY_SHIFT_RIGHT; case XK_Control_L : return GFX_KEY_CONTROL_LEFT; case XK_Control_R : return GFX_KEY_CONTROL_RIGHT; case XK_Alt_L : return GFX_KEY_ALT_LEFT; case XK_Alt_R : return GFX_KEY_ALT_RIGHT; case XK_Super_L : return GFX_KEY_SUPER_LEFT; case XK_Super_R : return GFX_KEY_SUPER_RIGHT; } return GFX_KEY_UNKNOWN; } /******************************************************/ static void _gfx_x11_create_key_table(void) { /* Get permitted keycodes and their symbols */ int minKey, maxKey; XDisplayKeycodes(_gfx_x11.display, &minKey, &maxKey); maxKey = maxKey > GFX_X11_MAX_KEYCODE ? GFX_X11_MAX_KEYCODE : maxKey; int numKeys = maxKey - minKey + 1; int symbolsPerKey; KeySym* symbols = XGetKeyboardMapping( _gfx_x11.display, minKey, numKeys, &symbolsPerKey ); /* Use the first symbol of all keycodes */ size_t i; for(i = minKey; i <= maxKey; ++i) _gfx_x11.keys[i] = _gfx_x11_get_key( symbols[(i - minKey) * symbolsPerKey]); XFree(symbols); }
static gboolean init_randr13 (GdkScreen *screen, gboolean *changed) { #ifdef HAVE_RANDR GdkDisplay *display = gdk_screen_get_display (screen); GdkX11Display *x11_display = GDK_X11_DISPLAY (display); GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); XRRScreenResources *resources; RROutput primary_output = None; RROutput first_output = None; int i; gboolean randr12_compat = FALSE; int old_primary; if (!x11_display->have_randr13) return FALSE; resources = XRRGetScreenResourcesCurrent (x11_screen->xdisplay, x11_screen->xroot_window); if (!resources) return FALSE; for (i = 0; i < x11_display->monitors->len; i++) { GdkX11Monitor *monitor = x11_display->monitors->pdata[i]; monitor->add = FALSE; monitor->remove = TRUE; } for (i = 0; i < resources->noutput; ++i) { RROutput output = resources->outputs[i]; XRROutputInfo *output_info = XRRGetOutputInfo (x11_screen->xdisplay, resources, output); /* Non RandR1.2+ X driver have output name "default" */ randr12_compat |= !g_strcmp0 (output_info->name, "default"); if (output_info->connection == RR_Disconnected) { XRRFreeOutputInfo (output_info); continue; } if (output_info->crtc) { GdkX11Monitor *monitor; XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc); char *name; GdkRectangle geometry; GdkRectangle newgeo; int j; int refresh_rate = 0; for (j = 0; j < resources->nmode; j++) { XRRModeInfo *xmode = &resources->modes[j]; if (xmode->id == crtc->mode) { refresh_rate = (1000 * xmode->dotClock) / (xmode->hTotal *xmode->vTotal); break; } } monitor = find_monitor_by_output (x11_display, output); if (monitor) monitor->remove = FALSE; else { monitor = g_object_new (gdk_x11_monitor_get_type (), "display", display, NULL); monitor->output = output; monitor->add = TRUE; g_ptr_array_add (x11_display->monitors, monitor); } gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry); name = g_strndup (output_info->name, output_info->nameLen); newgeo.x = crtc->x / x11_screen->window_scale; newgeo.y = crtc->y / x11_screen->window_scale; newgeo.width = crtc->width / x11_screen->window_scale; newgeo.height = crtc->height / x11_screen->window_scale; if (newgeo.x != geometry.x || newgeo.y != geometry.y || newgeo.width != geometry.width || newgeo.height != geometry.height || output_info->mm_width != gdk_monitor_get_width_mm (GDK_MONITOR (monitor)) || output_info->mm_height != gdk_monitor_get_height_mm (GDK_MONITOR (monitor)) || g_strcmp0 (name, gdk_monitor_get_model (GDK_MONITOR (monitor))) != 0) *changed = TRUE; gdk_monitor_set_position (GDK_MONITOR (monitor), newgeo.x, newgeo.y); gdk_monitor_set_size (GDK_MONITOR (monitor), newgeo.width, newgeo.height); g_object_notify (G_OBJECT (monitor), "workarea"); gdk_monitor_set_physical_size (GDK_MONITOR (monitor), output_info->mm_width, output_info->mm_height); gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor), translate_subpixel_order (output_info->subpixel_order)); gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh_rate); gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), x11_screen->window_scale); gdk_monitor_set_model (GDK_MONITOR (monitor), name); g_free (name); XRRFreeCrtcInfo (crtc); } XRRFreeOutputInfo (output_info); } if (resources->noutput > 0) first_output = resources->outputs[0]; XRRFreeScreenResources (resources); if (randr12_compat) { for (i = 0; i < x11_display->monitors->len; i++) { GdkX11Monitor *monitor = x11_display->monitors->pdata[i]; if (monitor->remove) gdk_display_monitor_removed (display, GDK_MONITOR (monitor)); } g_ptr_array_remove_range (x11_display->monitors, 0, x11_display->monitors->len); return FALSE; } for (i = x11_display->monitors->len - 1; i >= 0; i--) { GdkX11Monitor *monitor = x11_display->monitors->pdata[i]; if (monitor->add) { gdk_display_monitor_added (display, GDK_MONITOR (monitor)); *changed = TRUE; } else if (monitor->remove) { g_object_ref (monitor); g_ptr_array_remove (x11_display->monitors, monitor); gdk_display_monitor_removed (display, GDK_MONITOR (monitor)); g_object_unref (monitor); *changed = TRUE; } } old_primary = x11_display->primary_monitor; x11_display->primary_monitor = 0; primary_output = XRRGetOutputPrimary (x11_screen->xdisplay, x11_screen->xroot_window); for (i = 0; i < x11_display->monitors->len; ++i) { GdkX11Monitor *monitor = x11_display->monitors->pdata[i]; if (monitor->output == primary_output) { x11_display->primary_monitor = i; break; } /* No RandR1.3+ available or no primary set, fall back to prefer LVDS as primary if present */ if (primary_output == None && g_ascii_strncasecmp (gdk_monitor_get_model (GDK_MONITOR (monitor)), "LVDS", 4) == 0) { x11_display->primary_monitor = i; break; } /* No primary specified and no LVDS found */ if (monitor->output == first_output) x11_display->primary_monitor = i; } if (x11_display->primary_monitor != old_primary) *changed = TRUE; return x11_display->monitors->len > 0; #endif return FALSE; }
static void xfce_randr_populate (XfceRandr *randr, Display *xdisplay, GdkWindow *root_window) { GPtrArray *outputs; XRROutputInfo *output_info; XRRCrtcInfo *crtc_info; gint n; guint m, connected; guint *output_ids = NULL; XfconfChannel *display_channel = xfconf_channel_new ("displays"); 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 (); output_ids = g_malloc0 (randr->priv->resources->noutput * sizeof (guint)); /* walk the outputs */ connected = 0; 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; } else { output_ids[connected] = n; connected++; } /* 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->position = g_new0 (XfceOutputPosition, randr->noutput); randr->rotation = g_new0 (Rotation, randr->noutput); randr->rotations = g_new0 (Rotation, randr->noutput); randr->mirrored = g_new0 (gboolean, 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[output_ids[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->position[m].x = crtc_info->x; randr->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, output_ids[m]); /* Update display info, primary display may have changed. */ xfce_randr_save_output (randr, "Default", display_channel, m); /* Replace spaces with underscore in name for xfconf compatibility */ g_strcanon(randr->priv->output_info[m]->name, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_<>", '_'); } /* populate mirrored details */ xfce_randr_guess_relations (randr); g_free (output_ids); }
/* * 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_id) { Display * dpy = (Display *) (intptr_t) display; XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources; RRCrtc crtc = findRRCrtc( resources, (RRCrtc)(intptr_t)crt_id ); if( 0 == crtc ) { // n/a return NULL; } XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo; if( NULL == xrrCrtcInfo ) { // n/a return NULL; } if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) { // disabled return NULL; } Window root = RootWindow(dpy, 0); // FIXME screen_idx); RROutput pxid = XRRGetOutputPrimary (dpy, root); int isPrimary = 0; RROutput output = xrrCrtcInfo->outputs[0]; if ( None != pxid && pxid == output ) { isPrimary = 1; } 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_id; prop[propIndex++] = 0; // isClone, does not work: 0 < xrrOutputInfo->nclone ? 1 : 0; prop[propIndex++] = isPrimary; prop[propIndex++] = xrrOutputInfo->mm_width; prop[propIndex++] = xrrOutputInfo->mm_height; prop[propIndex++] = xrrCrtcInfo->x; // rotated viewport pixel units prop[propIndex++] = xrrCrtcInfo->y; // rotated viewport pixel units prop[propIndex++] = xrrCrtcInfo->width; // rotated viewport pixel units prop[propIndex++] = xrrCrtcInfo->height; // rotated viewport pixel units prop[propIndex++] = xrrCrtcInfo->x; // rotated viewport window units (same) prop[propIndex++] = xrrCrtcInfo->y; // rotated viewport window units (same) prop[propIndex++] = xrrCrtcInfo->width; // rotated viewport window units (same) prop[propIndex++] = xrrCrtcInfo->height; // rotated viewport window units (same) 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; }
bool iRandR::reload( bool _overwriteLatest, bool _overwriteDefaults ) { if ( !vIsRandRSupported_B ) return false; SizeID lTemoID_suI; int lTempSizes_I; Rotation lTempRotate_XRR; // Exists only for XRRConfigCurrentConfiguration(...); to make it happy vConfig_XRR = XRRGetScreenInfo( vDisplay_X11, vRootWindow_X11 ); vResources_XRR = XRRGetScreenResources( vDisplay_X11, vRootWindow_X11 ); lTemoID_suI = XRRConfigCurrentConfiguration( vConfig_XRR, &lTempRotate_XRR ); XRRScreenSize *lTempSizes_XRR = XRRSizes( vDisplay_X11, 0, &lTempSizes_I ); if ( lTemoID_suI < lTempSizes_I ) { vScreenWidth_uI = static_cast<unsigned>( lTempSizes_XRR[lTemoID_suI].width ); vScreenHeight_uI = static_cast<unsigned>( lTempSizes_XRR[lTemoID_suI].height ); } if ( _overwriteLatest ) { vLatestConfig_RandR.primary = XRRGetOutputPrimary( vDisplay_X11, vRootWindow_X11 ); for ( auto &elem : vLatestConfig_RandR.gamma ) XRRFreeGamma( elem ); vLatestConfig_RandR.gamma.clear(); for ( int i = 0; i < vResources_XRR->ncrtc; ++i ) { vLatestConfig_RandR.gamma.push_back( XRRGetCrtcGamma( vDisplay_X11, vResources_XRR->crtcs[i] ) ); } } if ( _overwriteDefaults ) { vDefaultConfig_RandR.primary = XRRGetOutputPrimary( vDisplay_X11, vRootWindow_X11 ); for ( auto &elem : vDefaultConfig_RandR.gamma ) XRRFreeGamma( elem ); vDefaultConfig_RandR.gamma.clear(); for ( int i = 0; i < vResources_XRR->ncrtc; ++i ) { vDefaultConfig_RandR.gamma.push_back( XRRGetCrtcGamma( vDisplay_X11, vResources_XRR->crtcs[i] ) ); } } // Clear old data vCRTC_V_RandR.clear(); vOutput_V_RandR.clear(); vMode_V_RandR.clear(); vLatestConfig_RandR.CRTCInfo.clear(); // CRTC for ( int i = 0; i < vResources_XRR->ncrtc; ++i ) { internal::_crtc lTempCRTC_RandR; XRRCrtcInfo *lTempCRTCInfo_XRR = XRRGetCrtcInfo( vDisplay_X11, vResources_XRR, vResources_XRR->crtcs[i] ); lTempCRTC_RandR.id = vResources_XRR->crtcs[i]; lTempCRTC_RandR.timestamp = lTempCRTCInfo_XRR->timestamp; lTempCRTC_RandR.posX = lTempCRTCInfo_XRR->x; lTempCRTC_RandR.posY = lTempCRTCInfo_XRR->y; lTempCRTC_RandR.width = lTempCRTCInfo_XRR->width; lTempCRTC_RandR.height = lTempCRTCInfo_XRR->height; lTempCRTC_RandR.mode = lTempCRTCInfo_XRR->mode; lTempCRTC_RandR.rotation = lTempCRTCInfo_XRR->rotation; lTempCRTC_RandR.rotations = lTempCRTCInfo_XRR->rotations; for ( int j = 0; j < lTempCRTCInfo_XRR->noutput; ++j ) { lTempCRTC_RandR.outputs.push_back( lTempCRTCInfo_XRR->outputs[j] ); } for ( int j = 0; j < lTempCRTCInfo_XRR->npossible; ++j ) { lTempCRTC_RandR.possibleOutputs.push_back( lTempCRTCInfo_XRR->possible[j] ); } vCRTC_V_RandR.push_back( lTempCRTC_RandR ); XRRFreeCrtcInfo( lTempCRTCInfo_XRR ); } // Output for ( int i = 0; i < vResources_XRR->noutput; ++i ) { internal::_output lTempOutput_RandR; XRROutputInfo *lTempOutputInfo_XRR = XRRGetOutputInfo( vDisplay_X11, vResources_XRR, vResources_XRR->outputs[i] ); lTempOutput_RandR.id = vResources_XRR->outputs[i]; lTempOutput_RandR.timestamp = lTempOutputInfo_XRR->timestamp; lTempOutput_RandR.crtc = lTempOutputInfo_XRR->crtc; lTempOutput_RandR.name = lTempOutputInfo_XRR->name; lTempOutput_RandR.mm_width = lTempOutputInfo_XRR->mm_width; lTempOutput_RandR.mm_height = lTempOutputInfo_XRR->mm_height; lTempOutput_RandR.connection = lTempOutputInfo_XRR->connection; lTempOutput_RandR.subpixel_order = lTempOutputInfo_XRR->subpixel_order; lTempOutput_RandR.npreferred = lTempOutputInfo_XRR->npreferred; for ( int j = 0; j < lTempOutputInfo_XRR->ncrtc; ++j ) { lTempOutput_RandR.crtcs.push_back( lTempOutputInfo_XRR->crtcs[j] ); } for ( int j = 0; j < lTempOutputInfo_XRR->nclone; ++j ) { lTempOutput_RandR.clones.push_back( lTempOutputInfo_XRR->clones[j] ); } for ( int j = 0; j < lTempOutputInfo_XRR->nmode; ++j ) { lTempOutput_RandR.modes.push_back( lTempOutputInfo_XRR->modes[j] ); } vOutput_V_RandR.push_back( lTempOutput_RandR ); XRRFreeOutputInfo( lTempOutputInfo_XRR ); } // Modes for ( int i = 0; i < vResources_XRR->nmode; ++i ) { internal::_mode lTempMode_RandR; XRRModeInfo lTempModeInfo_XRR = vResources_XRR->modes[i]; lTempMode_RandR.id = lTempModeInfo_XRR.id; lTempMode_RandR.width = lTempModeInfo_XRR.width; lTempMode_RandR.height = lTempModeInfo_XRR.height; lTempMode_RandR.dotClock = lTempModeInfo_XRR.dotClock; lTempMode_RandR.hSyncStart = lTempModeInfo_XRR.hSyncStart; lTempMode_RandR.hSyncEnd = lTempModeInfo_XRR.hSyncEnd; lTempMode_RandR.hTotal = lTempModeInfo_XRR.hTotal; lTempMode_RandR.hSkew = lTempModeInfo_XRR.hSkew; lTempMode_RandR.vSyncStart = lTempModeInfo_XRR.vSyncStart; lTempMode_RandR.vSyncEnd = lTempModeInfo_XRR.vSyncEnd; lTempMode_RandR.vTotal = lTempModeInfo_XRR.vTotal; lTempMode_RandR.name = lTempModeInfo_XRR.name; lTempMode_RandR.modeFlags = lTempModeInfo_XRR.modeFlags; /* v refresh frequency in Hz */ unsigned int lVTotalTemp = lTempMode_RandR.vTotal; if ( lTempMode_RandR.modeFlags & RR_DoubleScan ) lVTotalTemp *= 2; if ( lTempMode_RandR.modeFlags & RR_Interlace ) lVTotalTemp /= 2; if ( lTempMode_RandR.hTotal && lVTotalTemp ) lTempMode_RandR.refresh = ( static_cast<double>( lTempMode_RandR.dotClock ) / ( static_cast<double>( lTempMode_RandR.hTotal ) * static_cast<double>( lVTotalTemp ) ) ); else lTempMode_RandR.refresh = 0; /* h sync frequency in Hz */ if ( lTempMode_RandR.hTotal ) lTempMode_RandR.syncFreq = lTempMode_RandR.dotClock / lTempMode_RandR.hTotal; else lTempMode_RandR.syncFreq = 0; vMode_V_RandR.push_back( lTempMode_RandR ); } vLatestConfig_RandR.CRTCInfo = vCRTC_V_RandR; if ( _overwriteLatest ) vDefaultConfig_RandR.CRTCInfo = vCRTC_V_RandR; vMode_V_RandR.sort(); return true; }
JNIEXPORT jlong JNICALL Java_org_lwjgl_system_linux_Xrandr_nXRRGetOutputPrimary(JNIEnv *__env, jclass clazz, jlong displayAddress, jlong w) { Display *display = (Display *)(intptr_t)displayAddress; UNUSED_PARAMS(__env, clazz) return (jlong)XRRGetOutputPrimary(display, (Window)w); }
// Poll for changes in the set of connected monitors // void _glfwPollMonitorsX11(void) { if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken) { int i, j, disconnectedCount, screenCount = 0; _GLFWmonitor** disconnected = NULL; XineramaScreenInfo* screens = NULL; XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root); RROutput primary = XRRGetOutputPrimary(_glfw.x11.display, _glfw.x11.root); if (_glfw.x11.xinerama.available) screens = XineramaQueryScreens(_glfw.x11.display, &screenCount); disconnectedCount = _glfw.monitorCount; if (disconnectedCount) { disconnected = calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*)); memcpy(disconnected, _glfw.monitors, _glfw.monitorCount * sizeof(_GLFWmonitor*)); } for (i = 0; i < sr->noutput; i++) { int type, widthMM, heightMM; XRROutputInfo* oi; XRRCrtcInfo* ci; _GLFWmonitor* monitor; oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]); if (oi->connection != RR_Connected || oi->crtc == None) { XRRFreeOutputInfo(oi); continue; } for (j = 0; j < disconnectedCount; j++) { if (disconnected[j] && disconnected[j]->x11.output == sr->outputs[i]) { disconnected[j] = NULL; break; } } if (j < disconnectedCount) { XRRFreeOutputInfo(oi); continue; } ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc); if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270) { widthMM = oi->mm_height; heightMM = oi->mm_width; } else { widthMM = oi->mm_width; heightMM = oi->mm_height; } monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM); monitor->x11.output = sr->outputs[i]; monitor->x11.crtc = oi->crtc; for (j = 0; j < screenCount; j++) { if (screens[j].x_org == ci->x && screens[j].y_org == ci->y && screens[j].width == ci->width && screens[j].height == ci->height) { monitor->x11.index = j; break; } } if (monitor->x11.output == primary) type = _GLFW_INSERT_FIRST; else type = _GLFW_INSERT_LAST; _glfwInputMonitor(monitor, GLFW_CONNECTED, type); XRRFreeOutputInfo(oi); XRRFreeCrtcInfo(ci); } XRRFreeScreenResources(sr); if (screens) XFree(screens); for (i = 0; i < disconnectedCount; i++) { if (disconnected[i]) _glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0); } free(disconnected); } else { const int widthMM = DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen); const int heightMM = DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen); _glfwInputMonitor(_glfwAllocMonitor("Display", widthMM, heightMM), GLFW_CONNECTED, _GLFW_INSERT_FIRST); } }