[gtk+/wip/window-scales: 9/11] wayland: Implement gdk_screen_get_monitor_scale()



commit 63ffd4425e695cf6980c31103cc6f8783a3b4df6
Author: Alexander Larsson <alexl redhat com>
Date:   Tue Jun 4 11:18:49 2013 +0200

    wayland: Implement gdk_screen_get_monitor_scale()
    
    We bind to the newer version of the wl_output which supports
    the new done and scale events, and if we use this to get the
    scale for each monitor (defaulting to 1 if not supported).

 gdk/wayland/gdkdisplay-wayland.c |    4 +-
 gdk/wayland/gdkprivate-wayland.h |    5 ++-
 gdk/wayland/gdkscreen-wayland.c  |   76 +++++++++++++++++++++++++++++++++++--
 3 files changed, 77 insertions(+), 8 deletions(-)
---
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index ee51ab5..dec350a 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -168,8 +168,8 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id
        wl_registry_bind(display_wayland->wl_registry, id, &wl_shell_interface, 1);
   } else if (strcmp(interface, "wl_output") == 0) {
     output =
-      wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 1);
-    _gdk_wayland_screen_add_output(display_wayland->screen, id, output);
+      wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 2);
+    _gdk_wayland_screen_add_output(display_wayland->screen, id, output, version);
     /* We need another roundtrip to receive the modes and geometry
      * events for the output, which gives us the physical properties
      * and available modes on the output. */
diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h
index 43d1c3d..ebe4f43 100644
--- a/gdk/wayland/gdkprivate-wayland.h
+++ b/gdk/wayland/gdkprivate-wayland.h
@@ -161,11 +161,14 @@ GdkWindow *_gdk_wayland_screen_create_root_window (GdkScreen *screen,
 GdkScreen *_gdk_wayland_screen_new (GdkDisplay *display);
 void _gdk_wayland_screen_add_output (GdkScreen        *screen,
                                      guint32           id,
-                                     struct wl_output *output);
+                                     struct wl_output *output,
+                                    guint32           version);
 void _gdk_wayland_screen_remove_output (GdkScreen *screen,
                                         guint32 id);
 int _gdk_wayland_screen_get_output_refresh_rate (GdkScreen        *screen,
                                                  struct wl_output *output);
+guint32 _gdk_wayland_screen_get_output_scale (GdkScreen        *screen,
+                                             struct wl_output *output);
 
 void _gdk_wayland_window_set_device_grabbed (GdkWindow      *window,
                                              GdkDevice      *device,
diff --git a/gdk/wayland/gdkscreen-wayland.c b/gdk/wayland/gdkscreen-wayland.c
index c7a0fe3..1e3a9e7 100644
--- a/gdk/wayland/gdkscreen-wayland.c
+++ b/gdk/wayland/gdkscreen-wayland.c
@@ -77,10 +77,13 @@ struct _GdkWaylandScreenClass
   void (* window_manager_changed) (GdkWaylandScreen *screen_wayland);
 };
 
+#define OUTPUT_VERSION_WITH_DONE 2
+
 struct _GdkWaylandMonitor
 {
   GdkWaylandScreen *screen;
   guint32       id;
+  guint32       version;
   struct wl_output *output;
   GdkRectangle  geometry;
   int          width_mm;
@@ -88,6 +91,7 @@ struct _GdkWaylandMonitor
   char *       output_name;
   char *       manufacturer;
   int          refresh_rate;
+  gint          scale;
 };
 
 G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
@@ -249,6 +253,21 @@ gdk_wayland_screen_get_monitor_geometry (GdkScreen    *screen,
     *dest = monitor->geometry;
 }
 
+static gdouble
+gdk_wayland_screen_get_monitor_scale_factor (GdkScreen *screen,
+                                            gint       monitor_num)
+{
+  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
+  GdkWaylandMonitor *monitor;
+
+  if (monitor_num >= screen_wayland->monitors->len)
+    return 1.0;
+
+  monitor = g_ptr_array_index(screen_wayland->monitors, monitor_num);
+
+  return monitor->scale;
+}
+
 static GdkVisual *
 gdk_wayland_screen_get_system_visual (GdkScreen * screen)
 {
@@ -830,6 +849,7 @@ _gdk_wayland_screen_class_init (GdkWaylandScreenClass *klass)
   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;
@@ -896,7 +916,7 @@ output_handle_geometry(void *data,
   monitor->manufacturer = g_strdup (make);
   monitor->output_name = g_strdup (model);
 
-  if (monitor->geometry.width != 0)
+  if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
     {
       g_signal_emit_by_name (monitor->screen, "monitors-changed");
       update_screen_size (monitor->screen);
@@ -904,6 +924,26 @@ output_handle_geometry(void *data,
 }
 
 static void
+output_handle_done(void *data,
+                  struct wl_output *wl_output)
+{
+  GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
+
+  g_signal_emit_by_name (monitor->screen, "monitors-changed");
+  update_screen_size (monitor->screen);
+}
+
+static void
+output_handle_scale(void *data,
+                   struct wl_output *wl_output,
+                   uint32_t factor)
+{
+  GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
+
+  monitor->scale = factor;
+}
+
+static void
 output_handle_mode(void *data,
                    struct wl_output *wl_output,
                    uint32_t flags,
@@ -920,27 +960,35 @@ output_handle_mode(void *data,
   monitor->geometry.height = height;
   monitor->refresh_rate = refresh;
 
-  g_signal_emit_by_name (monitor->screen, "monitors-changed");
-  update_screen_size (monitor->screen);
+  if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
+    {
+      g_signal_emit_by_name (monitor->screen, "monitors-changed");
+      update_screen_size (monitor->screen);
+    }
 }
 
 static const struct wl_output_listener output_listener =
 {
   output_handle_geometry,
-  output_handle_mode
+  output_handle_mode,
+  output_handle_done,
+  output_handle_scale,
 };
 
 void
 _gdk_wayland_screen_add_output (GdkScreen        *screen,
                                 guint32           id,
-                                struct wl_output *output)
+                                struct wl_output *output,
+                               guint32           version)
 {
   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
   GdkWaylandMonitor *monitor = g_new0(GdkWaylandMonitor, 1);
 
   monitor->id = id;
   monitor->output = output;
+  monitor->version = version;
   monitor->screen = screen_wayland;
+  monitor->scale = 1;
   g_ptr_array_add(screen_wayland->monitors, monitor);
 
   wl_output_add_listener(output, &output_listener, monitor);
@@ -985,3 +1033,21 @@ _gdk_wayland_screen_get_output_refresh_rate (GdkScreen        *screen,
 
   return 0;
 }
+
+guint32
+_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];
+
+      if (monitor->output == output)
+        return monitor->scale;
+    }
+
+  return 0;
+}


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