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).
This commit is contained in:
		@ -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);
 | 
						wl_registry_bind(display_wayland->wl_registry, id, &wl_shell_interface, 1);
 | 
				
			||||||
  } else if (strcmp(interface, "wl_output") == 0) {
 | 
					  } else if (strcmp(interface, "wl_output") == 0) {
 | 
				
			||||||
    output =
 | 
					    output =
 | 
				
			||||||
      wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 1);
 | 
					      wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 2);
 | 
				
			||||||
    _gdk_wayland_screen_add_output(display_wayland->screen, id, output);
 | 
					    _gdk_wayland_screen_add_output(display_wayland->screen, id, output, version);
 | 
				
			||||||
    /* We need another roundtrip to receive the modes and geometry
 | 
					    /* We need another roundtrip to receive the modes and geometry
 | 
				
			||||||
     * events for the output, which gives us the physical properties
 | 
					     * events for the output, which gives us the physical properties
 | 
				
			||||||
     * and available modes on the output. */
 | 
					     * and available modes on the output. */
 | 
				
			||||||
 | 
				
			|||||||
@ -161,11 +161,14 @@ GdkWindow *_gdk_wayland_screen_create_root_window (GdkScreen *screen,
 | 
				
			|||||||
GdkScreen *_gdk_wayland_screen_new (GdkDisplay *display);
 | 
					GdkScreen *_gdk_wayland_screen_new (GdkDisplay *display);
 | 
				
			||||||
void _gdk_wayland_screen_add_output (GdkScreen        *screen,
 | 
					void _gdk_wayland_screen_add_output (GdkScreen        *screen,
 | 
				
			||||||
                                     guint32           id,
 | 
					                                     guint32           id,
 | 
				
			||||||
                                     struct wl_output *output);
 | 
					                                     struct wl_output *output,
 | 
				
			||||||
 | 
									     guint32           version);
 | 
				
			||||||
void _gdk_wayland_screen_remove_output (GdkScreen *screen,
 | 
					void _gdk_wayland_screen_remove_output (GdkScreen *screen,
 | 
				
			||||||
                                        guint32 id);
 | 
					                                        guint32 id);
 | 
				
			||||||
int _gdk_wayland_screen_get_output_refresh_rate (GdkScreen        *screen,
 | 
					int _gdk_wayland_screen_get_output_refresh_rate (GdkScreen        *screen,
 | 
				
			||||||
                                                 struct wl_output *output);
 | 
					                                                 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,
 | 
					void _gdk_wayland_window_set_device_grabbed (GdkWindow      *window,
 | 
				
			||||||
                                             GdkDevice      *device,
 | 
					                                             GdkDevice      *device,
 | 
				
			||||||
 | 
				
			|||||||
@ -77,10 +77,13 @@ struct _GdkWaylandScreenClass
 | 
				
			|||||||
  void (* window_manager_changed) (GdkWaylandScreen *screen_wayland);
 | 
					  void (* window_manager_changed) (GdkWaylandScreen *screen_wayland);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define OUTPUT_VERSION_WITH_DONE 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct _GdkWaylandMonitor
 | 
					struct _GdkWaylandMonitor
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GdkWaylandScreen *screen;
 | 
					  GdkWaylandScreen *screen;
 | 
				
			||||||
  guint32       id;
 | 
					  guint32       id;
 | 
				
			||||||
 | 
					  guint32       version;
 | 
				
			||||||
  struct wl_output *output;
 | 
					  struct wl_output *output;
 | 
				
			||||||
  GdkRectangle  geometry;
 | 
					  GdkRectangle  geometry;
 | 
				
			||||||
  int		width_mm;
 | 
					  int		width_mm;
 | 
				
			||||||
@ -88,6 +91,7 @@ struct _GdkWaylandMonitor
 | 
				
			|||||||
  char *	output_name;
 | 
					  char *	output_name;
 | 
				
			||||||
  char *	manufacturer;
 | 
					  char *	manufacturer;
 | 
				
			||||||
  int		refresh_rate;
 | 
					  int		refresh_rate;
 | 
				
			||||||
 | 
					  gint          scale;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
G_DEFINE_TYPE (GdkWaylandScreen, _gdk_wayland_screen, GDK_TYPE_SCREEN)
 | 
					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;
 | 
					    *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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (monitor_num >= screen_wayland->monitors->len)
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  monitor = g_ptr_array_index(screen_wayland->monitors, monitor_num);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return monitor->scale;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static GdkVisual *
 | 
					static GdkVisual *
 | 
				
			||||||
gdk_wayland_screen_get_system_visual (GdkScreen * screen)
 | 
					gdk_wayland_screen_get_system_visual (GdkScreen * screen)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -822,6 +841,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_plug_name = gdk_wayland_screen_get_monitor_plug_name;
 | 
				
			||||||
  screen_class->get_monitor_geometry = gdk_wayland_screen_get_monitor_geometry;
 | 
					  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_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_system_visual = gdk_wayland_screen_get_system_visual;
 | 
				
			||||||
  screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
 | 
					  screen_class->get_rgba_visual = gdk_wayland_screen_get_rgba_visual;
 | 
				
			||||||
  screen_class->is_composited = gdk_wayland_screen_is_composited;
 | 
					  screen_class->is_composited = gdk_wayland_screen_is_composited;
 | 
				
			||||||
@ -888,13 +908,33 @@ output_handle_geometry(void *data,
 | 
				
			|||||||
  monitor->manufacturer = g_strdup (make);
 | 
					  monitor->manufacturer = g_strdup (make);
 | 
				
			||||||
  monitor->output_name = g_strdup (model);
 | 
					  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");
 | 
					      g_signal_emit_by_name (monitor->screen, "monitors-changed");
 | 
				
			||||||
      update_screen_size (monitor->screen);
 | 
					      update_screen_size (monitor->screen);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
					static void
 | 
				
			||||||
output_handle_mode(void *data,
 | 
					output_handle_mode(void *data,
 | 
				
			||||||
                   struct wl_output *wl_output,
 | 
					                   struct wl_output *wl_output,
 | 
				
			||||||
@ -912,27 +952,35 @@ output_handle_mode(void *data,
 | 
				
			|||||||
  monitor->geometry.height = height;
 | 
					  monitor->geometry.height = height;
 | 
				
			||||||
  monitor->refresh_rate = refresh;
 | 
					  monitor->refresh_rate = refresh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  g_signal_emit_by_name (monitor->screen, "monitors-changed");
 | 
					  if (monitor->geometry.width != 0 && monitor->version < OUTPUT_VERSION_WITH_DONE)
 | 
				
			||||||
  update_screen_size (monitor->screen);
 | 
					    {
 | 
				
			||||||
 | 
					      g_signal_emit_by_name (monitor->screen, "monitors-changed");
 | 
				
			||||||
 | 
					      update_screen_size (monitor->screen);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct wl_output_listener output_listener =
 | 
					static const struct wl_output_listener output_listener =
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  output_handle_geometry,
 | 
					  output_handle_geometry,
 | 
				
			||||||
  output_handle_mode
 | 
					  output_handle_mode,
 | 
				
			||||||
 | 
					  output_handle_done,
 | 
				
			||||||
 | 
					  output_handle_scale,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
_gdk_wayland_screen_add_output (GdkScreen        *screen,
 | 
					_gdk_wayland_screen_add_output (GdkScreen        *screen,
 | 
				
			||||||
                                guint32           id,
 | 
					                                guint32           id,
 | 
				
			||||||
                                struct wl_output *output)
 | 
					                                struct wl_output *output,
 | 
				
			||||||
 | 
									guint32           version)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
 | 
					  GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen);
 | 
				
			||||||
  GdkWaylandMonitor *monitor = g_new0(GdkWaylandMonitor, 1);
 | 
					  GdkWaylandMonitor *monitor = g_new0(GdkWaylandMonitor, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  monitor->id = id;
 | 
					  monitor->id = id;
 | 
				
			||||||
  monitor->output = output;
 | 
					  monitor->output = output;
 | 
				
			||||||
 | 
					  monitor->version = version;
 | 
				
			||||||
  monitor->screen = screen_wayland;
 | 
					  monitor->screen = screen_wayland;
 | 
				
			||||||
 | 
					  monitor->scale = 1;
 | 
				
			||||||
  g_ptr_array_add(screen_wayland->monitors, monitor);
 | 
					  g_ptr_array_add(screen_wayland->monitors, monitor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  wl_output_add_listener(output, &output_listener, monitor);
 | 
					  wl_output_add_listener(output, &output_listener, monitor);
 | 
				
			||||||
@ -977,3 +1025,21 @@ _gdk_wayland_screen_get_output_refresh_rate (GdkScreen        *screen,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return 0;
 | 
					  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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user