static void process_monitors_change (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); gint n_monitors; gint primary_monitor; GdkX11Monitor *monitors; gboolean changed; primary_monitor = x11_screen->primary_monitor; n_monitors = x11_screen->n_monitors; monitors = x11_screen->monitors; x11_screen->n_monitors = 0; x11_screen->monitors = NULL; init_multihead (screen); changed = !compare_monitors (monitors, n_monitors, x11_screen->monitors, x11_screen->n_monitors) || x11_screen->primary_monitor != primary_monitor; free_monitors (monitors, n_monitors); if (changed) g_signal_emit_by_name (screen, "monitors-changed"); }
static void deinit_multihead (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); free_monitors (x11_screen->monitors, x11_screen->n_monitors); x11_screen->n_monitors = 0; x11_screen->monitors = NULL; }
static void deinit_multihead (GdkScreen *screen) { GdkScreenGix *screen_gix = GDK_SCREEN_GIX (screen); free_monitors (screen_gix->monitors, screen_gix->n_monitors); screen_gix->n_monitors = 0; screen_gix->monitors = NULL; }
static void deinit_multihead (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); free_monitors (x11_screen->monitors, x11_screen->n_monitors); g_clear_pointer (&x11_screen->xinerama_matches, g_hash_table_destroy); x11_screen->n_monitors = 0; x11_screen->monitors = NULL; }
/* Synchronize the contents of si->ssi to the current state of the monitors. Doesn't change anything if nothing has changed; otherwise, alters and reuses existing saver_screen_info structs as much as possible. Returns True if anything changed. */ Bool update_screen_layout (saver_info *si) { monitor **monitors = scan_monitors (si); int count = 0; int good_count = 0; int i, j; int seen_screens[100] = { 0, }; if (! layouts_differ_p (monitors, si->monitor_layout)) { free_monitors (monitors); return False; } free_monitors (si->monitor_layout); si->monitor_layout = monitors; check_monitor_sanity (si->monitor_layout); while (monitors[count]) { if (monitors[count]->sanity == S_SANE) good_count++; count++; } if (si->ssi_count == 0) { si->ssi_count = 10; si->screens = (saver_screen_info *) calloc (sizeof(*si->screens), si->ssi_count); } if (si->ssi_count <= good_count) { si->ssi_count = good_count + 10; si->screens = (saver_screen_info *) realloc (si->screens, sizeof(*si->screens) * si->ssi_count); memset (si->screens + si->nscreens, 0, sizeof(*si->screens) * (si->ssi_count - si->nscreens)); } if (! si->screens) abort(); si->nscreens = good_count; /* Regenerate the list of GL visuals as needed. */ if (si->best_gl_visuals) free (si->best_gl_visuals); si->best_gl_visuals = 0; for (i = 0, j = 0; i < count; i++) { monitor *m = monitors[i]; saver_screen_info *ssi = &si->screens[j]; Screen *old_screen = ssi->screen; int sn; if (monitors[i]->sanity != S_SANE) continue; ssi->global = si; ssi->number = j; sn = screen_number (m->screen); ssi->screen = m->screen; ssi->real_screen_number = sn; ssi->real_screen_p = (seen_screens[sn] == 0); seen_screens[sn]++; ssi->default_visual = get_visual_resource (ssi->screen, "visualID", "VisualID", False); ssi->current_visual = ssi->default_visual; ssi->current_depth = visual_depth (ssi->screen, ssi->current_visual); /* If the screen changed (or if this is the first time) we need a new toplevel shell for this screen's depth. */ if (ssi->screen != old_screen) initialize_screen_root_widget (ssi); ssi->poll_mouse_last_root_x = -1; ssi->poll_mouse_last_root_y = -1; ssi->x = m->x; ssi->y = m->y; ssi->width = m->width; ssi->height = m->height; # ifndef DEBUG_MULTISCREEN { saver_preferences *p = &si->prefs; if (p->debug_p # ifdef QUAD_MODE && !p->quad_p # endif ) ssi->width /= 2; } # endif j++; } si->default_screen = &si->screens[0]; return True; }
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; }