[gtk+/wip/matthiasc/monitor] x11: Convert to new monitor api
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/monitor] x11: Convert to new monitor api
- Date: Sun, 3 Apr 2016 14:52:09 +0000 (UTC)
commit 7a00f361f3791042f7e9e39da49fb692e461abce
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Apr 3 00:12:39 2016 -0400
x11: Convert to new monitor api
gdk/x11/gdkdisplay-x11.c | 27 ++
gdk/x11/gdkscreen-x11.c | 667 ++++++++++++++++++++++------------------------
gdk/x11/gdkscreen-x11.h | 6 +-
gdk/x11/gdkwindow-x11.c | 5 +-
4 files changed, 355 insertions(+), 350 deletions(-)
---
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 6804ed2..235d7e2 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -2903,6 +2903,30 @@ gdk_x11_display_get_default_seat (GdkDisplay *display)
return NULL;
}
+static GdkMonitor **
+gdk_x11_display_get_monitors (GdkDisplay *display,
+ int *n_monitors)
+{
+ GdkX11Screen *screen;
+
+ screen = GDK_X11_SCREEN (GDK_X11_DISPLAY (display)->screen);
+ *n_monitors = screen->monitors->len;
+
+ return (GdkMonitor **)screen->monitors->pdata;
+}
+
+static GdkMonitor *
+gdk_x11_display_get_primary_monitor (GdkDisplay *display)
+{
+ GdkX11Screen *screen;
+
+ screen = GDK_X11_SCREEN (GDK_X11_DISPLAY (display)->screen);
+ if (0 <= screen->primary_monitor && screen->primary_monitor < screen->monitors->len)
+ return screen->monitors->pdata[screen->primary_monitor];
+
+ return NULL;
+}
+
static void
gdk_x11_display_class_init (GdkX11DisplayClass * class)
{
@@ -2959,5 +2983,8 @@ gdk_x11_display_class_init (GdkX11DisplayClass * class)
display_class->get_default_seat = gdk_x11_display_get_default_seat;
+ display_class->get_monitors = gdk_x11_display_get_monitors;
+ display_class->get_primary_monitor = gdk_x11_display_get_primary_monitor;
+
_gdk_x11_windowing_init ();
}
diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c
index 2cb62ff..09b4a7c 100644
--- a/gdk/x11/gdkscreen-x11.c
+++ b/gdk/x11/gdkscreen-x11.c
@@ -25,6 +25,7 @@
#include "gdkdisplay-x11.h"
#include "gdkprivate-x11.h"
#include "xsettings-client.h"
+#include "gdkmonitorprivate.h"
#include <glib.h>
@@ -44,7 +45,6 @@
static void gdk_x11_screen_dispose (GObject *object);
static void gdk_x11_screen_finalize (GObject *object);
static void init_randr_support (GdkScreen *screen);
-static void deinit_multihead (GdkScreen *screen);
enum
{
@@ -66,14 +66,28 @@ struct _NetWmSupportedAtoms
struct _GdkX11Monitor
{
- GdkRectangle geometry;
- XID output;
- int width_mm;
- int height_mm;
- char * output_name;
- char * manufacturer;
+ GdkMonitor parent;
+
+ XID output;
+ guint add : 1;
+ guint remove : 1;
+ guint changed : 1;
};
+typedef struct _GdkX11Monitor GdkX11Monitor;
+typedef GdkMonitorClass GdkX11MonitorClass;
+
+G_DEFINE_TYPE (GdkX11Monitor, gdk_x11_monitor, GDK_TYPE_MONITOR);
+
+static void
+gdk_x11_monitor_init (GdkX11Monitor *monitor)
+{
+}
+
+static void
+gdk_x11_monitor_class_init (GdkX11MonitorClass *class)
+{
+}
static void
gdk_x11_screen_init (GdkX11Screen *screen)
@@ -171,50 +185,11 @@ gdk_x11_screen_finalize (GObject *object)
g_free (x11_screen->window_manager_name);
- deinit_multihead (GDK_SCREEN (object));
+ g_ptr_array_free (x11_screen->monitors, TRUE);
G_OBJECT_CLASS (gdk_x11_screen_parent_class)->finalize (object);
}
-static gint
-gdk_x11_screen_get_n_monitors (GdkScreen *screen)
-{
- return GDK_X11_SCREEN (screen)->n_monitors;
-}
-
-static gint
-gdk_x11_screen_get_primary_monitor (GdkScreen *screen)
-{
- return GDK_X11_SCREEN (screen)->primary_monitor;
-}
-
-static gint
-gdk_x11_screen_get_monitor_width_mm (GdkScreen *screen,
- gint monitor_num)
-{
- GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
-
- return x11_screen->monitors[monitor_num].width_mm;
-}
-
-static gint
-gdk_x11_screen_get_monitor_height_mm (GdkScreen *screen,
- gint monitor_num)
-{
- GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
-
- return x11_screen->monitors[monitor_num].height_mm;
-}
-
-static gchar *
-gdk_x11_screen_get_monitor_plug_name (GdkScreen *screen,
- gint monitor_num)
-{
- GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
-
- return g_strdup (x11_screen->monitors[monitor_num].output_name);
-}
-
/**
* gdk_x11_screen_get_monitor_output:
* @screen: (type GdkX11Screen): a #GdkScreen
@@ -233,29 +208,14 @@ gdk_x11_screen_get_monitor_output (GdkScreen *screen,
gint monitor_num)
{
GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
+ GdkX11Monitor *monitor;
g_return_val_if_fail (GDK_IS_SCREEN (screen), None);
g_return_val_if_fail (monitor_num >= 0, None);
- g_return_val_if_fail (monitor_num < x11_screen->n_monitors, None);
+ g_return_val_if_fail (monitor_num < x11_screen->monitors->len, None);
- return x11_screen->monitors[monitor_num].output;
-}
-
-static void
-gdk_x11_screen_get_monitor_geometry (GdkScreen *screen,
- gint monitor_num,
- GdkRectangle *dest)
-{
- GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
-
- if (dest)
- {
- *dest = x11_screen->monitors[monitor_num].geometry;
- dest->x /= x11_screen->window_scale;
- dest->y /= x11_screen->window_scale;
- dest->width /= x11_screen->window_scale;
- dest->height /= x11_screen->window_scale;
- }
+ monitor = x11_screen->monitors->pdata[monitor_num];
+ return monitor->output;
}
static int
@@ -403,39 +363,6 @@ gdk_x11_screen_monitor_has_fullscreen_window (GdkScreen *screen,
return has_fullscreen;
}
-static void
-gdk_x11_screen_get_monitor_workarea (GdkScreen *screen,
- gint monitor_num,
- GdkRectangle *dest)
-{
- GdkRectangle workarea;
-
- gdk_x11_screen_get_monitor_geometry (screen, monitor_num, dest);
-
- /* The EWMH constrains workarea to be a rectangle, so it
- * can't adequately deal with L-shaped monitor arrangements.
- * As a workaround, we ignore the workarea for anything
- * but the primary monitor. Since that is where the 'desktop
- * chrome' usually lives, this works ok in practice.
- */
- if (monitor_num == GDK_X11_SCREEN (screen)->primary_monitor &&
- !gdk_x11_screen_monitor_has_fullscreen_window (screen, monitor_num))
- {
- get_work_area (screen, &workarea);
- if (gdk_rectangle_intersect (dest, &workarea, &workarea))
- *dest = workarea;
- }
-}
-
-static gint
-gdk_x11_screen_get_monitor_scale_factor (GdkScreen *screen,
- gint monitor_num)
-{
- GdkX11Screen *screen_x11 = GDK_X11_SCREEN (screen);
-
- return screen_x11->window_scale;
-}
-
static GdkVisual *
gdk_x11_screen_get_rgba_visual (GdkScreen *screen)
{
@@ -494,66 +421,37 @@ check_is_composited (GdkDisplay *display,
return xwindow != None;
}
-static void
-init_monitor_geometry (GdkX11Monitor *monitor,
- int x, int y, int width, int height)
-{
- monitor->geometry.x = x;
- monitor->geometry.y = y;
- monitor->geometry.width = width;
- monitor->geometry.height = height;
-
- monitor->output = None;
- monitor->width_mm = -1;
- monitor->height_mm = -1;
- monitor->output_name = NULL;
- monitor->manufacturer = NULL;
-}
-
-static void
-free_monitors (GdkX11Monitor *monitors,
- gint n_monitors)
+static GdkX11Monitor *
+find_monitor_by_output (GdkX11Screen *screen, RROutput output)
{
int i;
- for (i = 0; i < n_monitors; ++i)
+ for (i = 0; i < screen->monitors->len; i++)
{
- g_free (monitors[i].output_name);
- g_free (monitors[i].manufacturer);
+ GdkX11Monitor *monitor = screen->monitors->pdata[i];
+ if (monitor->output == output)
+ return monitor;
}
- g_free (monitors);
+ return NULL;
}
-#ifdef HAVE_RANDR
-static int
-monitor_compare_function (GdkX11Monitor *monitor1,
- GdkX11Monitor *monitor2)
+static GdkSubpixelLayout
+translate_subpixel_order (int subpixel)
{
- /* Sort the leftmost/topmost monitors first.
- * For "cloned" monitors, sort the bigger ones first
- * (giving preference to taller monitors over wider
- * monitors)
- */
-
- if (monitor1->geometry.x != monitor2->geometry.x)
- return monitor1->geometry.x - monitor2->geometry.x;
-
- if (monitor1->geometry.y != monitor2->geometry.y)
- return monitor1->geometry.y - monitor2->geometry.y;
-
- if (monitor1->geometry.height != monitor2->geometry.height)
- return - (monitor1->geometry.height - monitor2->geometry.height);
-
- if (monitor1->geometry.width != monitor2->geometry.width)
- return - (monitor1->geometry.width - monitor2->geometry.width);
-
- return 0;
+ switch (subpixel)
+ {
+ case 1: return GDK_SUBPIXEL_LAYOUT_HORIZONTAL_RGB;
+ case 2: return GDK_SUBPIXEL_LAYOUT_HORIZONTAL_BGR;
+ case 3: return GDK_SUBPIXEL_LAYOUT_VERTICAL_RGB;
+ case 4: return GDK_SUBPIXEL_LAYOUT_VERTICAL_BGR;
+ case 5: return GDK_SUBPIXEL_LAYOUT_NONE;
+ default: return GDK_SUBPIXEL_LAYOUT_UNKNOWN;
+ }
}
-#endif
static gboolean
-init_randr15 (GdkScreen *screen)
+init_randr15 (GdkScreen *screen, gboolean *changed)
{
#ifdef HAVE_RANDR15
GdkDisplay *display = gdk_screen_get_display (screen);
@@ -563,10 +461,10 @@ init_randr15 (GdkScreen *screen)
RROutput primary_output = None;
RROutput first_output = None;
int i;
- GArray *monitors;
gboolean randr12_compat = FALSE;
XRRMonitorInfo *rr_monitors;
int num_rr_monitors;
+ int old_primary;
if (!display_x11->have_randr15)
return FALSE;
@@ -583,13 +481,20 @@ init_randr15 (GdkScreen *screen)
if (!rr_monitors)
return FALSE;
- monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor), num_rr_monitors);
+ for (i = 0; i < x11_screen->monitors->len; i++)
+ {
+ GdkX11Monitor *monitor = x11_screen->monitors->pdata[i];
+ monitor->add = FALSE;
+ monitor->remove = TRUE;
+ }
for (i = 0; i < num_rr_monitors; i++)
{
RROutput output = rr_monitors[i].outputs[0];
XRROutputInfo *output_info;
- GdkX11Monitor monitor;
+ GdkX11Monitor *monitor;
+ GdkRectangle geometry;
+ char *name;
gdk_x11_display_error_trap_push (display);
output_info = XRRGetOutputInfo (x11_screen->xdisplay, resources, output);
@@ -611,21 +516,48 @@ init_randr15 (GdkScreen *screen)
if (first_output == None)
first_output = output;
- init_monitor_geometry (&monitor,
- rr_monitors[i].x,
- rr_monitors[i].y,
- rr_monitors[i].width,
- rr_monitors[i].height);
+ monitor = find_monitor_by_output (x11_screen, 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_screen->monitors, monitor);
+ }
- monitor.width_mm = rr_monitors[i].mwidth;
- monitor.height_mm = rr_monitors[i].mheight;
- monitor.output = output;
- monitor.output_name = g_strndup (output_info->name, output_info->nameLen);
+ gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry);
+ if (rr_monitors[i].x != geometry.x || rr_monitors[i].y != geometry.y ||
+ rr_monitors[i].width != geometry.width || rr_monitors[i].height != geometry.height ||
+ gdk_monitor_get_width_mm (GDK_MONITOR (monitor)) != rr_monitors[i].mwidth ||
+ gdk_monitor_get_height_mm (GDK_MONITOR (monitor)) != rr_monitors[i].mheight)
+ *changed = TRUE;
+
+ gdk_monitor_set_position (GDK_MONITOR (monitor),
+ rr_monitors[i].x,
+ rr_monitors[i].y);
+ gdk_monitor_set_size (GDK_MONITOR (monitor),
+ rr_monitors[i].width,
+ rr_monitors[i].height);
+ gdk_monitor_set_physical_size (GDK_MONITOR (monitor),
+ rr_monitors[i].mwidth,
+ rr_monitors[i].mheight);
+ gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor),
+ translate_subpixel_order (output_info->subpixel_order));
+
+ name = g_strndup (output_info->name, output_info->nameLen);
+ if (g_strcmp0 (name, gdk_monitor_get_model (GDK_MONITOR (monitor))) != 0)
+ *changed = TRUE;
+
+ gdk_monitor_set_model (GDK_MONITOR (monitor), name);
+ g_free (name);
if (rr_monitors[i].primary)
- primary_output = monitor.output;
+ primary_output = monitor->output;
- g_array_append_val (monitors, monitor);
XRRFreeOutputInfo (output_info);
}
@@ -635,22 +567,40 @@ init_randr15 (GdkScreen *screen)
/* 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);
+ for (i = 0; i < x11_screen->monitors->len; i++)
+ {
+ GdkX11Monitor *monitor = x11_screen->monitors->pdata[i];
+ if (monitor->remove)
+ gdk_display_monitor_removed (display, GDK_MONITOR (monitor));
+ }
+ g_ptr_array_remove_range (x11_screen->monitors, 0, x11_screen->monitors->len);
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);
+ for (i = x11_screen->monitors->len - 1; i >= 0; i--)
+ {
+ GdkX11Monitor *monitor = x11_screen->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_screen->monitors, monitor);
+ gdk_display_monitor_removed (display, GDK_MONITOR (monitor));
+ g_object_unref (monitor);
+ *changed = TRUE;
+ }
+ }
+ old_primary = x11_screen->primary_monitor;
x11_screen->primary_monitor = 0;
-
- for (i = 0; i < x11_screen->n_monitors; ++i)
+ for (i = 0; i < x11_screen->monitors->len; ++i)
{
- if (x11_screen->monitors[i].output == primary_output)
+ GdkX11Monitor *monitor = x11_screen->monitors->pdata[i];
+ if (monitor->output == primary_output)
{
x11_screen->primary_monitor = i;
break;
@@ -658,25 +608,28 @@ init_randr15 (GdkScreen *screen)
/* 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)
+ g_ascii_strncasecmp (gdk_monitor_get_model (GDK_MONITOR (monitor)), "LVDS", 4) == 0)
{
x11_screen->primary_monitor = i;
break;
}
/* No primary specified and no LVDS found */
- if (x11_screen->monitors[i].output == first_output)
+ if (monitor->output == first_output)
x11_screen->primary_monitor = i;
}
- return x11_screen->n_monitors > 0;
+ if (x11_screen->primary_monitor != old_primary)
+ *changed = TRUE;
+
+ return x11_screen->monitors->len > 0;
#endif
return FALSE;
}
static gboolean
-init_randr13 (GdkScreen *screen)
+init_randr13 (GdkScreen *screen, gboolean *changed)
{
#ifdef HAVE_RANDR
GdkDisplay *display = gdk_screen_get_display (screen);
@@ -686,8 +639,8 @@ init_randr13 (GdkScreen *screen)
RROutput primary_output = None;
RROutput first_output = None;
int i;
- GArray *monitors;
gboolean randr12_compat = FALSE;
+ int old_primary;
if (!display_x11->have_randr13)
return FALSE;
@@ -697,7 +650,12 @@ init_randr13 (GdkScreen *screen)
if (!resources)
return FALSE;
- monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor), resources->noutput);
+ for (i = 0; i < x11_screen->monitors->len; i++)
+ {
+ GdkX11Monitor *monitor = x11_screen->monitors->pdata[i];
+ monitor->add = FALSE;
+ monitor->remove = TRUE;
+ }
for (i = 0; i < resources->noutput; ++i)
{
@@ -716,16 +674,47 @@ init_randr13 (GdkScreen *screen)
if (output_info->crtc)
{
- GdkX11Monitor monitor;
+ GdkX11Monitor *monitor;
XRRCrtcInfo *crtc = XRRGetCrtcInfo (x11_screen->xdisplay, resources, output_info->crtc);
+ char *name;
+ GdkRectangle geometry;
- 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);
+ monitor = find_monitor_by_output (x11_screen, 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_screen->monitors, monitor);
+ }
- g_array_append_val (monitors, monitor);
+ gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry);
+ if (crtc->x != geometry.x || crtc->y != geometry.y ||
+ crtc->width != geometry.width || crtc->height != geometry.height ||
+ gdk_monitor_get_width_mm (GDK_MONITOR (monitor)) != output_info->mm_width ||
+ gdk_monitor_get_height_mm (GDK_MONITOR (monitor)) != output_info->mm_height)
+ *changed = TRUE;
+
+ gdk_monitor_set_position (GDK_MONITOR (monitor),
+ crtc->x, crtc->y);
+ gdk_monitor_set_size (GDK_MONITOR (monitor),
+ crtc->width, crtc->height);
+ 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));
+
+ name = g_strndup (output_info->name, output_info->nameLen);
+ if (g_strcmp0 (name, gdk_monitor_get_model (GDK_MONITOR (monitor))) != 0)
+ *changed = TRUE;
+
+ gdk_monitor_set_model (GDK_MONITOR (monitor), name);
+ g_free (name);
XRRFreeCrtcInfo (crtc);
}
@@ -738,29 +727,45 @@ init_randr13 (GdkScreen *screen)
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);
-
+ for (i = 0; i < x11_screen->monitors->len; i++)
+ {
+ GdkX11Monitor *monitor = x11_screen->monitors->pdata[i];
+ if (monitor->remove)
+ gdk_display_monitor_removed (display, GDK_MONITOR (monitor));
+ }
+ g_ptr_array_remove_range (x11_screen->monitors, 0, x11_screen->monitors->len);
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);
+ for (i = x11_screen->monitors->len - 1; i >= 0; i--)
+ {
+ GdkX11Monitor *monitor = x11_screen->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_screen->monitors, monitor);
+ gdk_display_monitor_removed (display, GDK_MONITOR (monitor));
+ g_object_unref (monitor);
+ *changed = TRUE;
+ }
+ }
+ old_primary = x11_screen->primary_monitor;
x11_screen->primary_monitor = 0;
-
primary_output = XRRGetOutputPrimary (x11_screen->xdisplay,
x11_screen->xroot_window);
- for (i = 0; i < x11_screen->n_monitors; ++i)
+ for (i = 0; i < x11_screen->monitors->len; ++i)
{
- if (x11_screen->monitors[i].output == primary_output)
+ GdkX11Monitor *monitor = x11_screen->monitors->pdata[i];
+ if (monitor->output == primary_output)
{
x11_screen->primary_monitor = i;
break;
@@ -768,143 +773,102 @@ init_randr13 (GdkScreen *screen)
/* 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)
+ g_ascii_strncasecmp (gdk_monitor_get_model (GDK_MONITOR (monitor)), "LVDS", 4) == 0)
{
x11_screen->primary_monitor = i;
break;
}
/* No primary specified and no LVDS found */
- if (x11_screen->monitors[i].output == first_output)
+ if (monitor->output == first_output)
x11_screen->primary_monitor = i;
}
- return x11_screen->n_monitors > 0;
+ if (x11_screen->primary_monitor != old_primary)
+ *changed = TRUE;
+
+ return x11_screen->monitors->len > 0;
#endif
return FALSE;
}
-void
-_gdk_x11_screen_get_edge_monitors (GdkScreen *screen,
- gint *top,
- gint *bottom,
- gint *left,
- gint *right)
+static void
+init_no_multihead (GdkScreen *screen, gboolean *changed)
{
GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
- gint top_most_pos = x11_screen->height;
- gint left_most_pos = x11_screen->width;
- gint bottom_most_pos = 0;
- gint right_most_pos = 0;
- gint monitor_num;
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ GdkX11Monitor *monitor;
+ GdkRectangle geometry;
+ int i;
- for (monitor_num = 0; monitor_num < x11_screen->n_monitors; monitor_num++)
+ for (i = 0; i < x11_screen->monitors->len; i++)
{
- gint monitor_x = x11_screen->monitors[monitor_num].geometry.x;
- gint monitor_y = x11_screen->monitors[monitor_num].geometry.y;
- gint monitor_max_x = monitor_x + x11_screen->monitors[monitor_num].geometry.width;
- gint monitor_max_y = monitor_y + x11_screen->monitors[monitor_num].geometry.height;
-
- if (left && left_most_pos > monitor_x)
- {
- left_most_pos = monitor_x;
- *left = monitor_num;
- }
- if (right && right_most_pos < monitor_max_x)
- {
- right_most_pos = monitor_max_x;
- *right = monitor_num;
- }
- if (top && top_most_pos > monitor_y)
- {
- top_most_pos = monitor_y;
- *top = monitor_num;
- }
- if (bottom && bottom_most_pos < monitor_max_y)
- {
- bottom_most_pos = monitor_max_y;
- *bottom = monitor_num;
- }
+ GdkX11Monitor *monitor = x11_screen->monitors->pdata[i];
+ monitor->add = FALSE;
+ monitor->remove = TRUE;
}
-}
-
-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 gboolean
-compare_monitor (GdkX11Monitor *m1,
- GdkX11Monitor *m2)
-{
- if (m1->geometry.x != m2->geometry.x ||
- m1->geometry.y != m2->geometry.y ||
- m1->geometry.width != m2->geometry.width ||
- m1->geometry.height != m2->geometry.height)
- return FALSE;
-
- if (m1->width_mm != m2->width_mm ||
- m1->height_mm != m2->height_mm)
- return FALSE;
-
- if (g_strcmp0 (m1->output_name, m2->output_name) != 0)
- return FALSE;
-
- if (g_strcmp0 (m1->manufacturer, m2->manufacturer) != 0)
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-compare_monitors (GdkX11Monitor *monitors1, gint n_monitors1,
- GdkX11Monitor *monitors2, gint n_monitors2)
-{
- gint i;
-
- if (n_monitors1 != n_monitors2)
- return FALSE;
-
- for (i = 0; i < n_monitors1; i++)
+ monitor = find_monitor_by_output (x11_screen, 0);
+ if (monitor)
+ monitor->remove = FALSE;
+ else
{
- if (!compare_monitor (monitors1 + i, monitors2 + i))
- return FALSE;
+ monitor = g_object_new (gdk_x11_monitor_get_type (),
+ "display", display,
+ NULL);
+ monitor->output = 0;
+ monitor->add = TRUE;
+ g_ptr_array_add (x11_screen->monitors, monitor);
}
- return TRUE;
-}
-
-static void
-init_no_multihead (GdkScreen *screen)
-{
- GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
-
- x11_screen->n_monitors = 1;
- x11_screen->monitors = g_new0 (GdkX11Monitor, 1);
+ gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry);
+ if (0 != geometry.x || 0 != geometry.y ||
+ WidthOfScreen (x11_screen->xscreen) != geometry.width || HeightOfScreen (x11_screen->xscreen) !=
geometry.height ||
+ gdk_monitor_get_width_mm (GDK_MONITOR (monitor)) != WidthMMOfScreen (x11_screen->xscreen) ||
+ gdk_monitor_get_height_mm (GDK_MONITOR (monitor)) != HeightMMOfScreen (x11_screen->xscreen))
+ *changed = TRUE;
+ gdk_monitor_set_position (GDK_MONITOR (monitor), 0, 0);
+ gdk_monitor_set_size (GDK_MONITOR (monitor),
+ WidthOfScreen (x11_screen->xscreen),
+ HeightOfScreen (x11_screen->xscreen));
+ gdk_monitor_set_physical_size (GDK_MONITOR (monitor),
+ WidthMMOfScreen (x11_screen->xscreen),
+ HeightMMOfScreen (x11_screen->xscreen));
+
+ if (x11_screen->primary_monitor != 0)
+ *changed = TRUE;
x11_screen->primary_monitor = 0;
- init_monitor_geometry (x11_screen->monitors, 0, 0,
- WidthOfScreen (x11_screen->xscreen),
- HeightOfScreen (x11_screen->xscreen));
+ for (i = x11_screen->monitors->len - 1; i >= 0; i--)
+ {
+ GdkX11Monitor *monitor = x11_screen->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_screen->monitors, monitor);
+ gdk_display_monitor_removed (display, GDK_MONITOR (monitor));
+ g_object_unref (monitor);
+ *changed = TRUE;
+ }
+ }
}
-static void
+static gboolean
init_multihead (GdkScreen *screen)
{
- if (init_randr15 (screen))
- return;
+ gboolean any_changed = FALSE;
- if (init_randr13 (screen))
- return;
+ if (!init_randr15 (screen, &any_changed) &&
+ !init_randr13 (screen, &any_changed))
+ init_no_multihead (screen, &any_changed);
- init_no_multihead (screen);
+ return any_changed;
}
static void
@@ -916,15 +880,16 @@ update_bounding_box (GdkScreen *screen)
x1 = y1 = G_MAXINT;
x2 = y2 = G_MININT;
- for (i = 0; i < x11_screen->n_monitors; i++)
+ for (i = 0; i < x11_screen->monitors->len; i++)
{
- GdkX11Monitor *monitor;
-
- monitor = &x11_screen->monitors[i];
- x1 = MIN (x1, monitor->geometry.x);
- y1 = MIN (y1, monitor->geometry.y);
- x2 = MAX (x2, monitor->geometry.x + monitor->geometry.width);
- y2 = MAX (y2, monitor->geometry.y + monitor->geometry.height);
+ GdkX11Monitor *monitor = x11_screen->monitors->pdata[i];
+ GdkRectangle geometry;
+
+ gdk_monitor_get_geometry (GDK_MONITOR (monitor), &geometry);
+ x1 = MIN (x1, geometry.x);
+ y1 = MIN (y1, geometry.y);
+ x2 = MAX (x2, geometry.x + geometry.width);
+ y2 = MAX (y2, geometry.y + geometry.height);
}
x11_screen->width = x2 - x1;
@@ -963,9 +928,11 @@ _gdk_x11_screen_new (GdkDisplay *display,
else
x11_screen->window_scale = 1;
- init_multihead (screen);
+ x11_screen->monitors = g_ptr_array_new_with_free_func (g_object_unref);
+
init_randr_support (screen);
-
+ init_multihead (screen);
+
_gdk_x11_screen_init_visuals (screen);
_gdk_x11_screen_init_root_window (screen);
update_bounding_box (screen);
@@ -1048,29 +1015,7 @@ init_randr_support (GdkScreen *screen)
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)
+ if (init_multihead (screen))
{
update_bounding_box (screen);
g_signal_emit_by_name (screen, "monitors-changed");
@@ -1117,6 +1062,50 @@ _gdk_x11_screen_size_changed (GdkScreen *screen,
}
void
+_gdk_x11_screen_get_edge_monitors (GdkScreen *screen,
+ gint *top,
+ gint *bottom,
+ gint *left,
+ gint *right)
+{
+ GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
+ gint top_most_pos = x11_screen->height;
+ gint left_most_pos = x11_screen->width;
+ gint bottom_most_pos = 0;
+ gint right_most_pos = 0;
+ gint i;
+
+ for (i = 0; i < x11_screen->monitors->len; i++)
+ {
+ GdkMonitor *monitor = x11_screen->monitors->pdata[i];
+ GdkRectangle geometry;
+
+ gdk_monitor_get_geometry (monitor, &geometry);
+
+ if (left && left_most_pos > geometry.x)
+ {
+ left_most_pos = geometry.x;
+ *left = i;
+ }
+ if (right && right_most_pos < geometry.x + geometry.width)
+ {
+ right_most_pos = geometry.x + geometry.width;
+ *right = i;
+ }
+ if (top && top_most_pos > geometry.y)
+ {
+ top_most_pos = geometry.y;
+ *top = i;
+ }
+ if (bottom && bottom_most_pos < geometry.y + geometry.height)
+ {
+ bottom_most_pos = geometry.y + geometry.height;
+ *bottom = i;
+ }
+ }
+}
+
+void
_gdk_x11_screen_window_manager_changed (GdkScreen *screen)
{
g_signal_emit (screen, signals[WINDOW_MANAGER_CHANGED], 0);
@@ -1567,14 +1556,6 @@ gdk_x11_screen_class_init (GdkX11ScreenClass *klass)
screen_class->get_height_mm = gdk_x11_screen_get_height_mm;
screen_class->get_number = gdk_x11_screen_get_number;
screen_class->get_root_window = gdk_x11_screen_get_root_window;
- screen_class->get_n_monitors = gdk_x11_screen_get_n_monitors;
- screen_class->get_primary_monitor = gdk_x11_screen_get_primary_monitor;
- screen_class->get_monitor_width_mm = gdk_x11_screen_get_monitor_width_mm;
- screen_class->get_monitor_height_mm = gdk_x11_screen_get_monitor_height_mm;
- screen_class->get_monitor_plug_name = gdk_x11_screen_get_monitor_plug_name;
- screen_class->get_monitor_geometry = gdk_x11_screen_get_monitor_geometry;
- screen_class->get_monitor_workarea = gdk_x11_screen_get_monitor_workarea;
- screen_class->get_monitor_scale_factor = gdk_x11_screen_get_monitor_scale_factor;
screen_class->get_system_visual = _gdk_x11_screen_get_system_visual;
screen_class->get_rgba_visual = gdk_x11_screen_get_rgba_visual;
screen_class->is_composited = gdk_x11_screen_is_composited;
diff --git a/gdk/x11/gdkscreen-x11.h b/gdk/x11/gdkscreen-x11.h
index db82735..710ee7f 100644
--- a/gdk/x11/gdkscreen-x11.h
+++ b/gdk/x11/gdkscreen-x11.h
@@ -42,9 +42,7 @@ struct _GdkX11Screen
Window xroot_window;
GdkWindow *root_window;
gint screen_num;
- /* Xinerama/RandR 1.2 */
- gint n_monitors;
- GdkX11Monitor *monitors;
+ GPtrArray *monitors;
gint primary_monitor;
gint width;
@@ -116,8 +114,6 @@ void _gdk_x11_screen_size_changed (GdkScreen *screen,
XEvent *event);
void _gdk_x11_screen_process_owner_change (GdkScreen *screen,
XEvent *event);
-gint _gdk_x11_screen_get_xinerama_index (GdkScreen *screen,
- gint monitor_num);
void _gdk_x11_screen_get_edge_monitors (GdkScreen *screen,
gint *top,
gint *bottom,
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 9ed087a..3aa4038 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -4215,8 +4215,9 @@ gdk_x11_window_apply_fullscreen_mode (GdkWindow *window)
/* Translate all 4 monitors from the GDK set into XINERAMA indices */
for (i = 0; i < 4; ++i)
{
- xclient.data.l[i] = _gdk_x11_screen_get_xinerama_index (GDK_WINDOW_SCREEN (window),
- gdk_monitors[i]);
+ /* FIXME
+ xclient.data.l[i] = _gdk_x11_screen_ge_xinerama_index (GDK_WINDOW_SCREEN (window),
gdk_monitors[i]); */
+ xclient.data.l[i] = 0;
/* Sanity check, if XINERAMA is not available, we could have invalid
* negative values for the XINERAMA indices.
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]