147 lines
4.8 KiB
Diff
147 lines
4.8 KiB
Diff
2008-01-15 Federico Mena Quintero <federico@novell.com>
|
|
|
|
Start fixing https://bugzilla.novell.com/show_bug.cgi?id=343858 -
|
|
X servers with Intel 915GM graphics report a connected VGA output
|
|
incorrectly, so applications don't use the whole screen.
|
|
|
|
* gdk/x11/gdkscreen-x11.c (check_xfree_xinerama): Sanitize the
|
|
monitors that we get from XineramaQueryScreens().
|
|
(sanitize_monitors): Workaround for an Intel 915GM driver bug,
|
|
where it will return that a VGA output is connected to a laptop,
|
|
even though it isn't. In the case of just two overlapping
|
|
monitors ("laptop plus cloned external display"), simulate that we
|
|
have only *one* monitor.
|
|
|
|
diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c
|
|
index 624870f..7626ca8 100644
|
|
--- a/gdk/x11/gdkscreen-x11.c
|
|
+++ b/gdk/x11/gdkscreen-x11.c
|
|
@@ -596,6 +596,73 @@ check_solaris_xinerama (GdkScreen *screen)
|
|
return FALSE;
|
|
}
|
|
|
|
+static GdkRectangle
|
|
+pick_the_biggest_geometry (GdkRectangle *geometries, int num_geometries)
|
|
+{
|
|
+ long max_pixels;
|
|
+ int largest_index;
|
|
+ int i;
|
|
+
|
|
+ max_pixels = 0;
|
|
+ largest_index = 0;
|
|
+
|
|
+ for (i = 0; i < num_geometries; i++)
|
|
+ {
|
|
+ long pixels;
|
|
+
|
|
+ pixels = (long) geometries[i].width * geometries[i].height;
|
|
+
|
|
+ if (pixels > max_pixels)
|
|
+ {
|
|
+ max_pixels = pixels;
|
|
+ largest_index = i;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return geometries[largest_index];
|
|
+}
|
|
+
|
|
+static void
|
|
+sanitize_monitors (GdkRectangle *monitors, int n_monitors,
|
|
+ GdkRectangle **monitors_ret, int *n_monitors_ret)
|
|
+{
|
|
+ if (n_monitors == 2
|
|
+ && gdk_rectangle_intersect (monitors + 0, monitors + 1, NULL))
|
|
+ {
|
|
+ /* https://bugzilla.novell.com/show_bug.cgi?id=310208
|
|
+ *
|
|
+ * The X driver for Intel 915GM chipsets has/had a bug where it would
|
|
+ * report that laptops started with a VGA output connected, and most
|
|
+ * of the time it defaults to a resolution of 1024x768. This doesn't
|
|
+ * match the resolution of the laptop, which these days is big and fancy.
|
|
+ *
|
|
+ * Both monitors (the VGA output's and the laptop's) *overlap* in the Xinerama
|
|
+ * configuration, since that is how "clone the display" is implemented.
|
|
+ * So, we see if there are only two monitors *and* if they intersect --- in
|
|
+ * that case, we can be reasonably confident that we can just pick the bigger
|
|
+ * monitor, which will be the laptop's display.
|
|
+ *
|
|
+ * This shouldn't break real setups with "make a big screen out of two monitors",
|
|
+ * since those monitors don't overlap in the Xinerama configuration.
|
|
+ *
|
|
+ * To summarize: in the case of just two overlapping monitors ("laptop
|
|
+ * plus cloned external display"), we simulate that we have only *one* monitor.
|
|
+ */
|
|
+
|
|
+ *n_monitors_ret = 1;
|
|
+ *monitors_ret = g_new (GdkRectangle, 1);
|
|
+
|
|
+ **monitors_ret = pick_the_biggest_geometry (monitors, n_monitors);
|
|
+
|
|
+ g_free (monitors);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ *monitors_ret = monitors;
|
|
+ *n_monitors_ret = n_monitors;
|
|
+ }
|
|
+}
|
|
+
|
|
static gboolean
|
|
check_xfree_xinerama (GdkScreen *screen)
|
|
{
|
|
@@ -603,9 +670,10 @@ check_xfree_xinerama (GdkScreen *screen)
|
|
if (XineramaIsActive (GDK_SCREEN_XDISPLAY (screen)))
|
|
{
|
|
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
|
|
+ int num_monitors;
|
|
XineramaScreenInfo *monitors = XineramaQueryScreens (GDK_SCREEN_XDISPLAY (screen),
|
|
- &screen_x11->num_monitors);
|
|
- if (screen_x11->num_monitors <= 0 || monitors == NULL)
|
|
+ &num_monitors);
|
|
+ if (num_monitors <= 0 || monitors == NULL)
|
|
{
|
|
/* If Xinerama doesn't think we have any monitors, try acting as
|
|
* though we had no Xinerama. If the "no monitors" condition
|
|
@@ -614,23 +682,34 @@ check_xfree_xinerama (GdkScreen *screen)
|
|
* and can go back into Xinerama-ish mode at that point. */
|
|
if (monitors)
|
|
XFree (monitors);
|
|
+
|
|
+ screen_x11->num_monitors = 0;
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
+ GdkRectangle *rects;
|
|
int i;
|
|
- screen_x11->monitors = g_new0 (GdkRectangle, screen_x11->num_monitors);
|
|
+ GdkRectangle *sane_rects;
|
|
+ int sane_num_monitors;
|
|
+
|
|
+ rects = g_new0 (GdkRectangle, num_monitors);
|
|
|
|
- for (i = 0; i < screen_x11->num_monitors; i++)
|
|
+ for (i = 0; i < num_monitors; i++)
|
|
{
|
|
- screen_x11->monitors[i].x = monitors[i].x_org;
|
|
- screen_x11->monitors[i].y = monitors[i].y_org;
|
|
- screen_x11->monitors[i].width = monitors[i].width;
|
|
- screen_x11->monitors[i].height = monitors[i].height;
|
|
+ rects[i].x = monitors[i].x_org;
|
|
+ rects[i].y = monitors[i].y_org;
|
|
+ rects[i].width = monitors[i].width;
|
|
+ rects[i].height = monitors[i].height;
|
|
}
|
|
|
|
XFree (monitors);
|
|
|
|
+ sanitize_monitors (rects, num_monitors, &sane_rects, &sane_num_monitors);
|
|
+
|
|
+ screen_x11->num_monitors = sane_num_monitors;
|
|
+ screen_x11->monitors = sane_rects;
|
|
+
|
|
return TRUE;
|
|
}
|
|
}
|