[gtk+/wip/window-scales2: 15/40] wayland: Support gdk_window_get_scale
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/window-scales2: 15/40] wayland: Support gdk_window_get_scale
- Date: Wed, 3 Jul 2013 12:43:13 +0000 (UTC)
commit ed4fcee4c62a50c1b4fa612f4ba0fc96031cb9af
Author: Alexander Larsson <alexl redhat com>
Date: Tue Jun 4 11:39:36 2013 +0200
wayland: Support gdk_window_get_scale
We track the list of outputs each window is on, and set the
scale to the largest scale value of the outputs. Any time the scale
changes we also emit a configure event.
gdk/wayland/gdkwindow-wayland.c | 96 +++++++++++++++++++++++++++++++++++----
1 files changed, 86 insertions(+), 10 deletions(-)
---
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index 1e7eba1..f872049 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -145,6 +145,7 @@ struct _GdkWindowImplWayland
gboolean use_custom_surface;
+ guint32 scale;
gboolean pending_commit;
gint64 pending_frame_counter;
};
@@ -154,11 +155,15 @@ struct _GdkWindowImplWaylandClass
GdkWindowImplClass parent_class;
};
+static void gdk_wayland_window_configure (GdkWindow *window,
+ int width, int height, int edges);
+
G_DEFINE_TYPE (GdkWindowImplWayland, _gdk_window_impl_wayland, GDK_TYPE_WINDOW_IMPL)
static void
_gdk_window_impl_wayland_init (GdkWindowImplWayland *impl)
{
+ impl->scale = 1;
}
void
@@ -391,6 +396,7 @@ typedef struct _GdkWaylandCairoSurfaceData {
struct wl_buffer *buffer;
GdkWaylandDisplay *display;
int32_t width, height;
+ uint32_t scale;
gboolean busy;
} GdkWaylandCairoSurfaceData;
@@ -419,6 +425,44 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
data->busy = TRUE;
}
+static void
+window_update_scale (GdkWindow *window)
+{
+ GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+ GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
+ guint32 scale;
+ GSList *l;
+
+ scale = 1;
+ for (l = impl->outputs; l != NULL; l = l->next)
+ {
+ guint32 output_scale =
+ _gdk_wayland_screen_get_output_scale (wayland_display->screen,
+ l->data);
+ scale = MAX (scale, output_scale);
+ }
+
+#ifndef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
+ /* Don't announce a scale if we can't support it */
+ scale = 1;
+#endif
+
+ if (scale != impl->scale)
+ {
+ impl->scale = scale;
+
+ /* Notify app that scale changed */
+ gdk_wayland_window_configure (window, window->width, window->height, impl->resize_edges);
+ }
+}
+
+static void
+on_monitors_changed (GdkScreen *screen,
+ GdkWindow *window)
+{
+ window_update_scale (window);
+}
+
void
_gdk_wayland_display_create_window_impl (GdkDisplay *display,
GdkWindow *window,
@@ -449,6 +493,9 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
g_object_ref (window);
+ /* More likely to be right than just assuming 1 */
+ impl->scale = gdk_screen_get_monitor_scale_factor (screen, 0);
+
impl->title = NULL;
switch (GDK_WINDOW_TYPE (window))
@@ -477,6 +524,9 @@ _gdk_wayland_display_create_window_impl (GdkDisplay *display,
G_CALLBACK (on_frame_clock_before_paint), window);
g_signal_connect (frame_clock, "after-paint",
G_CALLBACK (on_frame_clock_after_paint), window);
+
+ g_signal_connect (screen, "monitors-changed",
+ G_CALLBACK (on_monitors_changed), window);
}
static void
@@ -528,6 +578,8 @@ gdk_wayland_window_attach_image (GdkWindow *window)
/* Attach this new buffer to the surface */
wl_surface_attach (impl->surface, data->buffer, dx, dy);
+ wl_surface_set_buffer_scale (impl->surface, data->scale);
+
impl->pending_commit = TRUE;
}
@@ -609,7 +661,7 @@ static const struct wl_buffer_listener buffer_listener = {
static cairo_surface_t *
gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
- int width, int height)
+ int width, int height, guint scale)
{
GdkWaylandCairoSurfaceData *data;
cairo_surface_t *surface = NULL;
@@ -621,29 +673,34 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
data->buffer = NULL;
data->width = width;
data->height = height;
+ data->scale = scale;
data->busy = FALSE;
stride = width * 4;
data->pool = _create_shm_pool (display->shm,
- width, height,
+ width*scale, height*scale,
&data->buf_length,
&data->buf);
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
- width, height,
- stride, WL_SHM_FORMAT_ARGB8888);
+ width*scale, height*scale,
+ stride*scale, WL_SHM_FORMAT_ARGB8888);
wl_buffer_add_listener (data->buffer, &buffer_listener, data);
surface = cairo_image_surface_create_for_data (data->buf,
CAIRO_FORMAT_ARGB32,
- width,
- height,
- stride);
+ width*scale,
+ height*scale,
+ stride*scale);
cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key,
data, gdk_wayland_cairo_surface_destroy);
+#ifdef HAVE_CAIRO_SURFACE_SET_DEVICE_SCALE
+ cairo_surface_set_device_scale (surface, scale, scale);
+#endif
+
status = cairo_surface_status (surface);
if (status != CAIRO_STATUS_SUCCESS)
{
@@ -665,8 +722,9 @@ gdk_wayland_window_ensure_cairo_surface (GdkWindow *window)
impl->cairo_surface =
gdk_wayland_create_cairo_surface (display_wayland,
- impl->wrapper->width,
- impl->wrapper->height);
+ impl->wrapper->width,
+ impl->wrapper->height,
+ impl->scale);
}
}
@@ -727,7 +785,7 @@ gdk_wayland_window_configure (GdkWindow *window,
display = gdk_window_get_display (window);
- /* TODO: Only generate a configure event if width or height have actually
+ /* TODO: Only generate a configure event if width/height/scale have actually
* changed?
*/
event = gdk_event_new (GDK_CONFIGURE);
@@ -841,6 +899,8 @@ surface_enter (void *data,
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
impl->outputs = g_slist_prepend (impl->outputs, output);
+
+ window_update_scale (window);
}
static void
@@ -852,8 +912,11 @@ surface_leave (void *data,
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
impl->outputs = g_slist_remove (impl->outputs, output);
+
+ window_update_scale (window);
}
+
static void
shell_surface_handle_configure(void *data,
struct wl_shell_surface *shell_surface,
@@ -1905,6 +1968,18 @@ gdk_wayland_window_delete_property (GdkWindow *window,
{
}
+static gint
+gdk_wayland_window_get_scale_factor (GdkWindow *window)
+{
+ GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
+
+ if (GDK_WINDOW_DESTROYED (window))
+ return 1;
+
+ return impl->scale;
+}
+
+
static void
_gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
{
@@ -1991,6 +2066,7 @@ _gdk_window_impl_wayland_class_init (GdkWindowImplWaylandClass *klass)
impl_class->get_property = gdk_wayland_window_get_property;
impl_class->change_property = gdk_wayland_window_change_property;
impl_class->delete_property = gdk_wayland_window_delete_property;
+ impl_class->get_scale_factor = gdk_wayland_window_get_scale_factor;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]