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);
 | 
			
		||||
  } 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. */
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
@ -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 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 *
 | 
			
		||||
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_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;
 | 
			
		||||
@ -888,13 +908,33 @@ 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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
@ -912,27 +952,35 @@ output_handle_mode(void *data,
 | 
			
		||||
  monitor->geometry.height = height;
 | 
			
		||||
  monitor->refresh_rate = refresh;
 | 
			
		||||
 | 
			
		||||
  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);
 | 
			
		||||
@ -977,3 +1025,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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user