diff options
author | Matthias Clasen <mclasen@redhat.com> | 2016-02-20 10:19:13 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2016-02-20 10:54:48 -0500 |
commit | e837aa69b686b3f32f9511e30f4e0b7acc0e1ffb (patch) | |
tree | f7b77329d6961d960e8cb60c6fb7171ae8df31c3 /gdk/x11 | |
parent | 1dda932109f10d7582a8da9fd22626da835e9124 (diff) | |
download | gtk+-e837aa69b686b3f32f9511e30f4e0b7acc0e1ffb.tar.gz |
x11: Some cleanups to the multihead initialization
The significant change here is a memory leak fix in init_xrandr15.
The rest of the changes makes init_xrandr13 and init_xrandr15 more
parallel, and simplifies init_multihead.
Diffstat (limited to 'gdk/x11')
-rw-r--r-- | gdk/x11/gdkscreen-x11.c | 165 |
1 files changed, 79 insertions, 86 deletions
diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c index 2bbac70b04..b0c3cd6db4 100644 --- a/gdk/x11/gdkscreen-x11.c +++ b/gdk/x11/gdkscreen-x11.c @@ -503,7 +503,7 @@ check_is_composited (GdkDisplay *display, static void init_monitor_geometry (GdkX11Monitor *monitor, - int x, int y, int width, int height) + int x, int y, int width, int height) { monitor->geometry.x = x; monitor->geometry.y = y; @@ -613,22 +613,21 @@ monitor_compare_function (GdkX11Monitor *monitor1, } #endif -#ifdef HAVE_RANDR15 static gboolean init_randr15 (GdkScreen *screen) { +#ifdef HAVE_RANDR15 GdkDisplay *display = gdk_screen_get_display (screen); GdkX11Display *display_x11 = GDK_X11_DISPLAY (display); GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); - XRRMonitorInfo *rr_monitors; XRRScreenResources *resources; - RROutput output; + RROutput primary_output = None; RROutput first_output = None; - gboolean randr12_compat = FALSE; - int num_rr_monitors; int i; GArray *monitors; - XID primary_output = None; + gboolean randr12_compat = FALSE; + XRRMonitorInfo *rr_monitors; + int num_rr_monitors; if (!display_x11->have_randr15) return FALSE; @@ -645,14 +644,14 @@ init_randr15 (GdkScreen *screen) if (!rr_monitors) return FALSE; - monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor), - num_rr_monitors); + monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor), num_rr_monitors); for (i = 0; i < num_rr_monitors; i++) { - output = rr_monitors[i].outputs[0]; + RROutput output = rr_monitors[i].outputs[0]; XRROutputInfo *output_info = XRRGetOutputInfo (x11_screen->xdisplay, resources, output); + GdkX11Monitor monitor; /* Non RandR1.2+ X driver have output name "default" */ randr12_compat |= !g_strcmp0 (output_info->name, "default"); @@ -666,7 +665,6 @@ init_randr15 (GdkScreen *screen) if (first_output == None) first_output = output; - GdkX11Monitor monitor; init_monitor_geometry (&monitor, rr_monitors[i].x, rr_monitors[i].y, @@ -684,22 +682,24 @@ init_randr15 (GdkScreen *screen) g_array_append_val (monitors, monitor); XRRFreeOutputInfo (output_info); } + XRRFreeMonitors (rr_monitors); + 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); + free_monitors ((GdkX11Monitor *)g_array_free (monitors, FALSE), n_monitors); return FALSE; } - g_array_sort (monitors, - (GCompareFunc) monitor_compare_function); + 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; for (i = 0; i < x11_screen->n_monitors; ++i) @@ -724,9 +724,11 @@ init_randr15 (GdkScreen *screen) } return x11_screen->n_monitors > 0; -} #endif + return FALSE; +} + static gboolean init_randr13 (GdkScreen *screen) { @@ -734,9 +736,8 @@ init_randr13 (GdkScreen *screen) 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 primary_output = None; RROutput first_output = None; int i; GArray *monitors; @@ -746,50 +747,44 @@ init_randr13 (GdkScreen *screen) return FALSE; resources = XRRGetScreenResourcesCurrent (x11_screen->xdisplay, - x11_screen->xroot_window); + x11_screen->xroot_window); if (!resources) return FALSE; - monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor), - resources->noutput); + 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]); + 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->name, "default"); + /* Non RandR1.2+ X driver have output name "default" */ + randr12_compat |= !g_strcmp0 (output_info->name, "default"); - if (output->connection == RR_Disconnected) + if (output_info->connection == RR_Disconnected) { - XRRFreeOutputInfo (output); + XRRFreeOutputInfo (output_info); continue; } - if (output->crtc) + if (output_info->crtc) { GdkX11Monitor monitor; - XRRCrtcInfo *crtc = XRRGetCrtcInfo (dpy, resources, output->crtc); + XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->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; + init_monitor_geometry (&monitor, crtc->x, crtc->y, crtc->width, crtc->height); + monitor.output = output; + monitor.width_mm = output_info->mm_width; + monitor.height_mm = output_info->mm_height; + monitor.output_name = g_strndup (output_info->name, output_info->nameLen); g_array_append_val (monitors, monitor); XRRFreeCrtcInfo (crtc); } - XRRFreeOutputInfo (output); + XRRFreeOutputInfo (output_info); } if (resources->noutput > 0) @@ -797,19 +792,18 @@ init_randr13 (GdkScreen *screen) XRRFreeScreenResources (resources); - /* non RandR 1.2 X driver doesn't return any usable multihead data */ + /* 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); + free_monitors ((GdkX11Monitor *)g_array_free (monitors, FALSE), n_monitors); return FALSE; } - g_array_sort (monitors, - (GCompareFunc) monitor_compare_function); + g_array_sort (monitors, (GCompareFunc) monitor_compare_function); + x11_screen->n_monitors = monitors->len; x11_screen->monitors = (GdkX11Monitor *)g_array_free (monitors, FALSE); @@ -821,22 +815,22 @@ init_randr13 (GdkScreen *screen) for (i = 0; i < x11_screen->n_monitors; ++i) { if (x11_screen->monitors[i].output == primary_output) - { - x11_screen->primary_monitor = i; - break; - } + { + 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; - } + { + 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; + x11_screen->primary_monitor = i; } return x11_screen->n_monitors > 0; @@ -857,7 +851,12 @@ init_solaris_xinerama (GdkScreen *screen) gint result; int n_monitors; int i; - + int opcode, firstevent, firsterror; + + if (!XQueryExtension (GDK_SCREEN_XDISPLAY (screen), "XINERAMA", + &opcode, &firstevent, &firsterror)) + return FALSE; + if (!XineramaGetState (dpy, screen_no)) return FALSE; @@ -897,7 +896,12 @@ init_xfree_xinerama (GdkScreen *screen) GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); XineramaScreenInfo *monitors; int i, n_monitors; - + int opcode, firstevent, firsterror; + + if (!XQueryExtension (GDK_SCREEN_XDISPLAY (screen), "XINERAMA", + &opcode, &firstevent, &firsterror)) + return FALSE; + if (!XineramaIsActive (dpy)) return FALSE; @@ -1157,49 +1161,38 @@ compare_monitors (GdkX11Monitor *monitors1, gint n_monitors1, } static void -init_multihead (GdkScreen *screen) +init_no_multihead (GdkScreen *screen) { GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen); - int opcode, firstevent, firsterror; - /* There are four different implementations of multihead support: - * - * 1. Fake Xinerama for debugging purposes - * 2. RandR 1.2 - * 3. Solaris Xinerama - * 4. XFree86/Xorg Xinerama - * - * We use them in that order. - */ + x11_screen->n_monitors = 1; + x11_screen->monitors = g_new0 (GdkX11Monitor, 1); + x11_screen->primary_monitor = 0; + + init_monitor_geometry (x11_screen->monitors, 0, 0, + WidthOfScreen (x11_screen->xscreen), + HeightOfScreen (x11_screen->xscreen)); +} + +static void +init_multihead (GdkScreen *screen) +{ if (init_fake_xinerama (screen)) return; -#ifdef HAVE_RANDR15 if (init_randr15 (screen)) return; -#endif if (init_randr13 (screen)) return; - if (XQueryExtension (GDK_SCREEN_XDISPLAY (screen), "XINERAMA", - &opcode, &firstevent, &firsterror)) - { - if (init_solaris_xinerama (screen)) - return; - - if (init_xfree_xinerama (screen)) - return; - } + if (init_solaris_xinerama (screen)) + return; - /* No multihead support of any kind for this screen */ - x11_screen->n_monitors = 1; - x11_screen->monitors = g_new0 (GdkX11Monitor, 1); - x11_screen->primary_monitor = 0; + if (init_xfree_xinerama (screen)) + return; - init_monitor_geometry (x11_screen->monitors, 0, 0, - WidthOfScreen (x11_screen->xscreen), - HeightOfScreen (x11_screen->xscreen)); + init_no_multihead (screen); } static void |