[gtk+] wayland: Port to new monitor api



commit 9026289381b5a9a7d80d525109eb0929ddb83217
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Apr 2 10:18:56 2016 -0400

    wayland: Port to new monitor api

 gdk/wayland/Makefile.am          |    3 +
 gdk/wayland/gdkdisplay-wayland.c |   27 ++++
 gdk/wayland/gdkdisplay-wayland.h |    2 +
 gdk/wayland/gdkmonitor-wayland.c |   64 ++++++++
 gdk/wayland/gdkmonitor-wayland.h |   39 +++++
 gdk/wayland/gdkscreen-wayland.c  |  303 +++++++++++++-------------------------
 gdk/wayland/gdkwayland.h         |    1 +
 gdk/wayland/gdkwaylandmonitor.h  |   48 ++++++
 8 files changed, 290 insertions(+), 197 deletions(-)
---
diff --git a/gdk/wayland/Makefile.am b/gdk/wayland/Makefile.am
index da18afd..da62012 100644
--- a/gdk/wayland/Makefile.am
+++ b/gdk/wayland/Makefile.am
@@ -48,6 +48,8 @@ libgdk_wayland_la_SOURCES =                   \
        gdkkeys-wayland.c                       \
        gdkglcontext-wayland.c                  \
        gdkglcontext-wayland.h                  \
+       gdkmonitor-wayland.c                    \
+       gdkmonitor-wayland.h                    \
        gdkscreen-wayland.c                     \
        gdkseat-wayland.h                       \
        gdkselection-wayland.c                  \
@@ -64,6 +66,7 @@ libgdkwaylandinclude_HEADERS =                        \
        gdkwaylanddevice.h                      \
        gdkwaylanddisplay.h                     \
        gdkwaylandglcontext.h                   \
+       gdkwaylandmonitor.h                     \
        gdkwaylandselection.h                   \
        gdkwaylandwindow.h
 
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index 9872d6c..8f6a398 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -598,6 +598,8 @@ gdk_wayland_display_finalize (GObject *object)
 
   g_free (display_wayland->startup_notification_id);
 
+  g_ptr_array_free (display_wayland->monitors, TRUE);
+
   G_OBJECT_CLASS (gdk_wayland_display_parent_class)->finalize (object);
 }
 
@@ -812,6 +814,26 @@ gdk_wayland_display_pop_error_trap (GdkDisplay *display,
   return 0;
 }
 
+static int
+gdk_wayland_display_get_n_monitors (GdkDisplay *display)
+{
+  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
+
+  return display_wayland->monitors->len;
+}
+
+static GdkMonitor *
+gdk_wayland_display_get_monitor (GdkDisplay *display,
+                                 int         monitor_num)
+{
+  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (display);
+
+  if (monitor_num < 0 || monitor_num >= display_wayland->monitors->len)
+    return NULL;
+
+  return (GdkMonitor *)display_wayland->monitors->pdata[monitor_num];
+}
+
 static void
 gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
 {
@@ -863,12 +885,17 @@ gdk_wayland_display_class_init (GdkWaylandDisplayClass *class)
   display_class->utf8_to_string_target = _gdk_wayland_display_utf8_to_string_target;
 
   display_class->make_gl_context_current = gdk_wayland_display_make_gl_context_current;
+
+  display_class->get_n_monitors = gdk_wayland_display_get_n_monitors;
+  display_class->get_monitor = gdk_wayland_display_get_monitor;
 }
 
 static void
 gdk_wayland_display_init (GdkWaylandDisplay *display)
 {
   display->xkb_context = xkb_context_new (0);
+
+  display->monitors = g_ptr_array_new_with_free_func (g_object_unref);
 }
 
 void
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index a6cd14f..f4cf92a 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -103,6 +103,8 @@ struct _GdkWaylandDisplay
 
   GdkWaylandSelection *selection;
 
+  GPtrArray *monitors;
+
   /* egl info */
   EGLDisplay egl_display;
   int egl_major_version;
diff --git a/gdk/wayland/gdkmonitor-wayland.c b/gdk/wayland/gdkmonitor-wayland.c
new file mode 100644
index 0000000..59ab74e
--- /dev/null
+++ b/gdk/wayland/gdkmonitor-wayland.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright © 2016 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#include <gio/gio.h>
+#include "gdkprivate-wayland.h"
+
+#include "gdkmonitor-wayland.h"
+
+G_DEFINE_TYPE (GdkWaylandMonitor, gdk_wayland_monitor, GDK_TYPE_MONITOR)
+
+static void
+gdk_wayland_monitor_init (GdkWaylandMonitor *monitor)
+{
+}
+
+static void
+gdk_wayland_monitor_finalize (GObject *object)
+{
+  GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)object;
+
+  wl_output_destroy (monitor->output);
+
+  G_OBJECT_CLASS (gdk_wayland_monitor_parent_class)->finalize (object);
+}
+
+static void
+gdk_wayland_monitor_class_init (GdkWaylandMonitorClass *class)
+{
+  G_OBJECT_CLASS (class)->finalize = gdk_wayland_monitor_finalize;
+}
+
+/**
+ * gdk_wayland_monitor_get_wl_output:
+ * @monitor: (type GdkWaylandMonitor): a #GdkMonitor
+ *
+ * Returns the Wayland wl_output of a #GdkMonitor.
+ *
+ * Returns: (transfer none): a Wayland wl_output
+ * Since: 3.22
+ */
+struct wl_output *
+gdk_wayland_monitor_get_wl_output (GdkMonitor *monitor)
+{
+  g_return_val_if_fail (GDK_IS_WAYLAND_MONITOR (monitor), NULL);
+
+  return GDK_WAYLAND_MONITOR (monitor)->output;
+}
diff --git a/gdk/wayland/gdkmonitor-wayland.h b/gdk/wayland/gdkmonitor-wayland.h
new file mode 100644
index 0000000..581908c
--- /dev/null
+++ b/gdk/wayland/gdkmonitor-wayland.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright © 2016 Red Hat, Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GDK_WAYLAND_MONITOR_PRIVATE_H__
+#define __GDK_WAYLAND_MONITOR_PRIVATE_H__
+
+#include <glib.h>
+#include "gdkwaylandmonitor.h"
+#include "gdkmonitorprivate.h"
+#include "gdkprivate-wayland.h"
+
+struct _GdkWaylandMonitor {
+  GdkMonitor parent;
+
+  guint32 id;
+  guint32 version;
+  struct wl_output *output;
+  gboolean added;
+};
+
+struct _GdkWaylandMonitorClass {
+  GdkMonitorClass parent_class;
+};
+
+#endif
diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c
index 2643ef9..ff2ab19 100644
--- a/gdk/wayland/gdkscreen-wayland.c
+++ b/gdk/wayland/gdkscreen-wayland.c
@@ -26,6 +26,7 @@
 #include "gdkvisualprivate.h"
 #include "gdkdisplay.h"
 #include "gdkdisplay-wayland.h"
+#include "gdkmonitor-wayland.h"
 #include "gdkwayland.h"
 #include "gdkprivate-wayland.h"
 
@@ -49,7 +50,6 @@ typedef struct {
         const gchar *hintstyle;
 } GsdXftSettings;
 
-typedef struct _GdkWaylandMonitor GdkWaylandMonitor;
 
 struct _GdkWaylandScreen
 {
@@ -64,9 +64,6 @@ struct _GdkWaylandScreen
   /* Visual Part */
   GdkVisual *visual;
 
-  /* Xinerama/RandR 1.2 */
-  GPtrArray *monitors;
-
   GHashTable *settings;
   GsdXftSettings xft_settings;
 
@@ -80,59 +77,12 @@ struct _GdkWaylandScreenClass
 
 #define OUTPUT_VERSION_WITH_DONE 2
 
-struct _GdkWaylandMonitor
-{
-  GdkWaylandScreen *screen;
-  guint32       id;
-  guint32       version;
-  struct wl_output *output;
-  GdkRectangle  geometry;
-  int          width_mm;
-  int          height_mm;
-  char *       output_name;
-  char *       manufacturer;
-  int          refresh_rate;
-  gint          scale;
-};
 
 GType _gdk_wayland_screen_get_type (void);
 
 G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
 
 static void
-free_monitor (gpointer data)
-{
-  GdkWaylandMonitor *monitor = data;
-
-  if (monitor == NULL)
-    return;
-
-  wl_output_destroy (monitor->output);
-  g_free (monitor->output_name);
-  g_free (monitor->manufacturer);
-
-  g_free (monitor);
-}
-
-static void
-deinit_multihead (GdkScreen *screen)
-{
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
-
-  g_ptr_array_free (screen_wayland->monitors, TRUE);
-
-  screen_wayland->monitors = NULL;
-}
-
-static void
-init_multihead (GdkScreen *screen)
-{
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
-
-  screen_wayland->monitors = g_ptr_array_new_with_free_func (free_monitor);
-}
-
-static void
 gdk_wayland_screen_dispose (GObject *object)
 {
   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (object);
@@ -153,8 +103,6 @@ gdk_wayland_screen_finalize (GObject *object)
 
   g_object_unref (screen_wayland->visual);
 
-  deinit_multihead (GDK_SCREEN (object));
-
   g_hash_table_destroy (screen_wayland->settings);
 
   G_OBJECT_CLASS (_gdk_wayland_screen_parent_class)->finalize (object);
@@ -202,80 +150,6 @@ gdk_wayland_screen_get_root_window (GdkScreen *screen)
   return GDK_WAYLAND_SCREEN (screen)->root_window;
 }
 
-static gint
-gdk_wayland_screen_get_n_monitors (GdkScreen *screen)
-{
-  return GDK_WAYLAND_SCREEN (screen)->monitors->len;
-}
-
-static gint
-gdk_wayland_screen_get_primary_monitor (GdkScreen *screen)
-{
-  return 0;
-}
-
-static gint
-gdk_wayland_screen_get_monitor_width_mm        (GdkScreen *screen,
-                                        gint       monitor_num)
-{
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
-  GdkWaylandMonitor *monitor;
-
-  monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
-
-  return monitor->width_mm;
-}
-
-static gint
-gdk_wayland_screen_get_monitor_height_mm (GdkScreen *screen,
-                                         gint       monitor_num)
-{
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
-  GdkWaylandMonitor *monitor;
-
-  monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
-
-  return monitor->height_mm;
-}
-
-static gchar *
-gdk_wayland_screen_get_monitor_plug_name (GdkScreen *screen,
-                                         gint       monitor_num)
-{
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
-  GdkWaylandMonitor *monitor;
-
-  monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
-
-  return g_strdup (monitor->output_name);
-}
-
-static void
-gdk_wayland_screen_get_monitor_geometry (GdkScreen    *screen,
-                                        gint          monitor_num,
-                                        GdkRectangle *dest)
-{
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
-  GdkWaylandMonitor *monitor;
-
-  monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
-
-  if (dest)
-    *dest = monitor->geometry;
-}
-
-static gint
-gdk_wayland_screen_get_monitor_scale_factor (GdkScreen *screen,
-                                            gint       monitor_num)
-{
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
-  GdkWaylandMonitor *monitor;
-
-  monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
-
-  return monitor->scale;
-}
-
 static GdkVisual *
 gdk_wayland_screen_get_system_visual (GdkScreen * screen)
 {
@@ -961,8 +835,6 @@ _gdk_wayland_screen_new (GdkDisplay *display)
 
   screen_wayland->visual = gdk_wayland_visual_new (screen);
 
-  init_multihead (screen);
-
   screen_wayland->root_window =
     _gdk_wayland_screen_create_root_window (screen,
                                             screen_wayland->width,
@@ -989,14 +861,6 @@ _gdk_wayland_screen_class_init (GdkWaylandScreenClass *klass)
   screen_class->get_height_mm = gdk_wayland_screen_get_height_mm;
   screen_class->get_number = gdk_wayland_screen_get_number;
   screen_class->get_root_window = gdk_wayland_screen_get_root_window;
-  screen_class->get_n_monitors = gdk_wayland_screen_get_n_monitors;
-  screen_class->get_primary_monitor = gdk_wayland_screen_get_primary_monitor;
-  screen_class->get_monitor_width_mm = gdk_wayland_screen_get_monitor_width_mm;
-  screen_class->get_monitor_height_mm = gdk_wayland_screen_get_monitor_height_mm;
-  screen_class->get_monitor_plug_name = gdk_wayland_screen_get_monitor_plug_name;
-  screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
-  screen_class->get_monitor_workarea = gdk_wayland_screen_get_monitor_geometry;
-  screen_class->get_monitor_scale_factor = gdk_wayland_screen_get_monitor_scale_factor;
   screen_class->get_system_visual = gdk_wayland_screen_get_system_visual;
   screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
   screen_class->is_composited = gdk_wayland_screen_is_composited;
@@ -1024,16 +888,17 @@ _gdk_wayland_screen_init (GdkWaylandScreen *screen_wayland)
 static void
 update_screen_size (GdkWaylandScreen *screen_wayland)
 {
+  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
   gboolean emit_changed = FALSE;
   gint width, height;
   gint width_mm, height_mm;
-  gint i;
+  int i;
 
   width = height = 0;
   width_mm = height_mm = 0;
-  for (i = 0; i < screen_wayland->monitors->len; i++)
+  for (i = 0; i < display_wayland->monitors->len; i++)
     {
-      GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
+      GdkMonitor *monitor = display_wayland->monitors->pdata[i];
 
       /* XXX: Largely assuming here that monitor areas
        * are contiguous and never overlap.
@@ -1140,19 +1005,18 @@ output_handle_geometry (void             *data,
             g_message ("handle geometry output %d, position %d %d, phys. size %d %d, subpixel layout %s, 
manufacturer %s, model %s, transform %s",
                        monitor->id, x, y, physical_width, physical_height, subpixel_to_string (subpixel), 
make, model, transform_to_string (transform)));
 
-  monitor->geometry.x = x;
-  monitor->geometry.y = y;
-
-  monitor->width_mm = physical_width;
-  monitor->height_mm = physical_height;
+  gdk_monitor_set_position (GDK_MONITOR (monitor), x, y);
+  gdk_monitor_set_physical_size (GDK_MONITOR (monitor), physical_width, physical_height);
+  gdk_monitor_set_subpixel_layout (GDK_MONITOR (monitor), subpixel);
+  gdk_monitor_set_manufacturer (GDK_MONITOR (monitor), make);
+  gdk_monitor_set_model (GDK_MONITOR (monitor), model);
 
-  monitor->manufacturer = g_strdup (make);
-  monitor->output_name = g_strdup (model);
-
-  if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
+  if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
     {
-      g_signal_emit_by_name (monitor->screen, "monitors-changed");
-      update_screen_size (monitor->screen);
+      GdkDisplay *display = GDK_MONITOR (monitor)->display;
+      GdkWaylandScreen *screen = GDK_WAYLAND_SCREEN (gdk_display_get_default_screen (display));
+      g_signal_emit_by_name (screen, "monitors-changed");
+      update_screen_size (screen);
     }
 }
 
@@ -1161,12 +1025,21 @@ output_handle_done (void             *data,
                     struct wl_output *wl_output)
 {
   GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
+  GdkDisplay *display = gdk_monitor_get_display (GDK_MONITOR (monitor));
+  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (gdk_display_get_default_screen (display));
 
   GDK_NOTE (MISC,
             g_message ("handle done output %d", monitor->id));
 
-  g_signal_emit_by_name (monitor->screen, "monitors-changed");
-  update_screen_size (monitor->screen);
+  if (!monitor->added)
+    {
+      monitor->added = TRUE;
+      g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
+      gdk_display_monitor_added (display, GDK_MONITOR (monitor));
+    }
+
+  g_signal_emit_by_name (screen_wayland, "monitors-changed");
+  update_screen_size (screen_wayland);
 }
 
 static void
@@ -1179,10 +1052,13 @@ output_handle_scale (void             *data,
   GDK_NOTE (MISC,
             g_message ("handle scale output %d, scale %d", monitor->id, scale));
 
-  monitor->scale = scale;
+  gdk_monitor_set_scale_factor (GDK_MONITOR (monitor), scale);
 
-  if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
-    g_signal_emit_by_name (monitor->screen, "monitors-changed");
+  if (GDK_MONITOR (monitor)->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
+    {
+      GdkScreen *screen = gdk_display_get_default_screen (GDK_MONITOR (monitor)->display);
+      g_signal_emit_by_name (screen, "monitors-changed");
+    }
 }
 
 static void
@@ -1202,14 +1078,14 @@ output_handle_mode (void             *data,
   if ((flags & WL_OUTPUT_MODE_CURRENT) == 0)
     return;
 
-  monitor->geometry.width = width;
-  monitor->geometry.height = height;
-  monitor->refresh_rate = refresh;
+  gdk_monitor_set_size (GDK_MONITOR (monitor), width, height);
+  gdk_monitor_set_refresh_rate (GDK_MONITOR (monitor), refresh);
 
-  if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
+  if (width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
     {
-      g_signal_emit_by_name (monitor->screen, "monitors-changed");
-      update_screen_size (monitor->screen);
+      GdkScreen *screen = gdk_display_get_default_screen (GDK_MONITOR (monitor)->display);
+      g_signal_emit_by_name (screen, "monitors-changed");
+      update_screen_size (GDK_WAYLAND_SCREEN (screen));
     }
 }
 
@@ -1227,18 +1103,22 @@ _gdk_wayland_screen_add_output (GdkScreen        *screen,
                                 struct wl_output *output,
                                guint32           version)
 {
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
+  GdkDisplay *display = gdk_screen_get_display (screen);
   GdkWaylandMonitor *monitor;
 
-  monitor = g_new0 (GdkWaylandMonitor, 1);
+  monitor = g_object_new (GDK_TYPE_WAYLAND_MONITOR,
+                          "display", display,
+                          NULL);
 
   monitor->id = id;
   monitor->output = output;
   monitor->version = version;
-  monitor->screen = screen_wayland;
-  monitor->scale = 1;
 
-  g_ptr_array_add (screen_wayland->monitors, monitor);
+  if (monitor->version < OUTPUT_VERSION_WITH_DONE)
+    {
+      g_ptr_array_add (GDK_WAYLAND_DISPLAY (display)->monitors, monitor);
+      gdk_display_monitor_added (display, GDK_MONITOR (monitor));
+    }
 
   wl_output_add_listener (output, &output_listener, monitor);
 }
@@ -1247,47 +1127,80 @@ struct wl_output *
 _gdk_wayland_screen_get_wl_output (GdkScreen *screen,
                                    gint monitor_num)
 {
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
-  GdkWaylandMonitor *monitor = g_ptr_array_index (screen_wayland->monitors, monitor_num);
+  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (GDK_WAYLAND_SCREEN (screen)->display);
+  GdkWaylandMonitor *monitor;
+
+  monitor = display_wayland->monitors->pdata[monitor_num];
+
   return monitor->output;
 }
 
-void
-_gdk_wayland_screen_remove_output (GdkScreen *screen,
-                                   guint32    id)
+static GdkWaylandMonitor *
+get_monitor_for_id (GdkWaylandScreen *screen_wayland,
+                    guint32           id)
 {
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
+  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
   int i;
 
-  for (i = 0; i < screen_wayland->monitors->len; i++)
+  for (i = 0; i < display_wayland->monitors->len; i++)
     {
-      GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
+      GdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
 
       if (monitor->id == id)
-        {
-          g_ptr_array_remove (screen_wayland->monitors, monitor);
-
-          g_signal_emit_by_name (screen_wayland, "monitors-changed");
-          update_screen_size (screen_wayland);
-          break;
-        }
+        return monitor;
     }
+
+  return NULL;
 }
 
-int
-_gdk_wayland_screen_get_output_refresh_rate (GdkScreen        *screen,
-                                             struct wl_output *output)
+static GdkWaylandMonitor *
+get_monitor_for_output (GdkWaylandScreen *screen_wayland,
+                        struct wl_output *output)
 {
-  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
+  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
   int i;
 
-  for (i = 0; i < screen_wayland->monitors->len; i++)
+  for (i = 0; i < display_wayland->monitors->len; i++)
     {
-      GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
+      GdkWaylandMonitor *monitor = display_wayland->monitors->pdata[i];
 
       if (monitor->output == output)
-        return monitor->refresh_rate;
+        return monitor;
+    }
+
+  return NULL;
+}
+
+void
+_gdk_wayland_screen_remove_output (GdkScreen *screen,
+                                   guint32    id)
+{
+  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
+  GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (screen_wayland->display);
+  GdkWaylandMonitor *monitor;
+
+  monitor = get_monitor_for_id (screen_wayland, id);
+  if (monitor != NULL)
+    {
+      g_object_ref (monitor);
+      g_ptr_array_remove (display_wayland->monitors, monitor);
+      gdk_display_monitor_removed (GDK_DISPLAY (display_wayland), GDK_MONITOR (monitor));
+      g_object_unref (monitor);
+      g_signal_emit_by_name (screen_wayland, "monitors-changed");
+      update_screen_size (screen_wayland);
     }
+}
+
+int
+_gdk_wayland_screen_get_output_refresh_rate (GdkScreen        *screen,
+                                             struct wl_output *output)
+{
+  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
+  GdkWaylandMonitor *monitor;
+
+  monitor = get_monitor_for_output (screen_wayland, output);
+  if (monitor != NULL)
+    return gdk_monitor_get_refresh_rate (GDK_MONITOR (monitor));
 
   return 0;
 }
@@ -1297,15 +1210,11 @@ _gdk_wayland_screen_get_output_scale (GdkScreen        *screen,
                                      struct wl_output *output)
 {
   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
-  int i;
-
-  for (i = 0; i < screen_wayland->monitors->len; i++)
-    {
-      GdkWaylandMonitor *monitor = screen_wayland->monitors->pdata[i];
+  GdkWaylandMonitor *monitor;
 
-      if (monitor->output == output)
-        return monitor->scale;
-    }
+  monitor = get_monitor_for_output (screen_wayland, output);
+  if (monitor != NULL)
+    return gdk_monitor_get_scale_factor (GDK_MONITOR (monitor));
 
   return 0;
 }
diff --git a/gdk/wayland/gdkwayland.h b/gdk/wayland/gdkwayland.h
index 64f64b6..2b79295 100644
--- a/gdk/wayland/gdkwayland.h
+++ b/gdk/wayland/gdkwayland.h
@@ -31,6 +31,7 @@
 
 #include <gdk/wayland/gdkwaylanddevice.h>
 #include <gdk/wayland/gdkwaylanddisplay.h>
+#include <gdk/wayland/gdkwaylandmonitor.h>
 #include <gdk/wayland/gdkwaylandselection.h>
 #include <gdk/wayland/gdkwaylandwindow.h>
 #include <gdk/wayland/gdkwaylandglcontext.h>
diff --git a/gdk/wayland/gdkwaylandmonitor.h b/gdk/wayland/gdkwaylandmonitor.h
new file mode 100644
index 0000000..966d8c1
--- /dev/null
+++ b/gdk/wayland/gdkwaylandmonitor.h
@@ -0,0 +1,48 @@
+/*
+ * gdkwaylandmonitor.h
+ *
+ * Copyright 2016 Red Hat, Inc.
+ *
+ * Matthias Clasen <mclasen redhat com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GDK_WAYLAND_MONITOR_H__
+#define __GDK_WAYLAND_MONITOR_H__
+
+#if !defined (__GDKWAYLAND_H_INSIDE__) && !defined (GDK_COMPILATION)
+#error "Only <gdk/gdkwayland.h> can be included directly."
+#endif
+
+#include <gdk/gdkmonitor.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_WAYLAND_MONITOR           (gdk_wayland_monitor_get_type ())
+#define GDK_WAYLAND_MONITOR(object)        (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_WAYLAND_MONITOR, 
GdkWaylandMonitor))
+#define GDK_IS_WAYLAND_MONITOR(object)     (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_WAYLAND_MONITOR))
+
+typedef struct _GdkWaylandMonitor      GdkWaylandMonitor;
+typedef struct _GdkWaylandMonitorClass GdkWaylandMonitorClass;
+
+GDK_AVAILABLE_IN_3_22
+GType             gdk_wayland_monitor_get_type            (void) G_GNUC_CONST;
+
+GDK_AVAILABLE_IN_3_22
+struct wl_output *gdk_wayland_monitor_get_wl_output       (GdkMonitor *monitor);
+
+G_END_DECLS
+
+#endif  /* __GDK_WAYLAND_MONITOR_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]