summaryrefslogtreecommitdiff
path: root/gdk/x11
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2016-02-20 10:19:13 -0500
committerMatthias Clasen <mclasen@redhat.com>2016-02-20 10:54:48 -0500
commite837aa69b686b3f32f9511e30f4e0b7acc0e1ffb (patch)
treef7b77329d6961d960e8cb60c6fb7171ae8df31c3 /gdk/x11
parent1dda932109f10d7582a8da9fd22626da835e9124 (diff)
downloadgtk+-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.c165
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