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:
Alexander Larsson 2013-06-04 11:18:49 +02:00
parent 8524e0c150
commit ce68a2f870
3 changed files with 77 additions and 8 deletions

View File

@ -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. */

View File

@ -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,

View File

@ -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;
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);
@ -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;
}