[gtk+] Use the surface output event to keep track of the suggested scale value



commit 252ccb846fd94327f75ed25b90d53e427b3b3e50
Author: Andreas Pokorny <andreas pokorny canonical com>
Date:   Tue Jul 19 14:56:34 2016 +0200

    Use the surface output event to keep track of the suggested scale value
    
    The event will be sent when the surface becomes visible on an output. With this change the 
GdkMirWindowImpl keeps track of the scale value and sends a configure event on change.
    
    Signed-off-by: Andreas Pokorny <andreas pokorny canonical com>

 gdk/mir/gdkmir-private.h    |    2 +
 gdk/mir/gdkmireventsource.c |   10 +++++++++
 gdk/mir/gdkmirwindowimpl.c  |   44 +++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 54 insertions(+), 2 deletions(-)
---
diff --git a/gdk/mir/gdkmir-private.h b/gdk/mir/gdkmir-private.h
index 84051a7..53f5a66 100644
--- a/gdk/mir/gdkmir-private.h
+++ b/gdk/mir/gdkmir-private.h
@@ -89,6 +89,8 @@ void _gdk_mir_window_impl_set_surface_state (GdkMirWindowImpl *impl, MirSurfaceS
 
 void _gdk_mir_window_impl_set_surface_type (GdkMirWindowImpl *impl, MirSurfaceType type);
 
+void _gdk_mir_window_set_surface_output (GdkWindow *window, gdouble scale);
+
 void _gdk_mir_window_impl_set_cursor_state (GdkMirWindowImpl *impl, gdouble x, gdouble y, gboolean 
cursor_inside, guint button_state);
 
 void _gdk_mir_window_impl_get_cursor_state (GdkMirWindowImpl *impl, gdouble *x, gdouble *y, gboolean 
*cursor_inside, guint *button_state);
diff --git a/gdk/mir/gdkmireventsource.c b/gdk/mir/gdkmireventsource.c
index 458228a..b829c8f 100644
--- a/gdk/mir/gdkmireventsource.c
+++ b/gdk/mir/gdkmireventsource.c
@@ -544,6 +544,13 @@ handle_close_event (GdkWindow *window)
   gdk_window_destroy_notify (window);
 }
 
+static void
+handle_surface_output_event (GdkWindow                  *window,
+                             const MirSurfaceOutputEvent *event)
+{
+  _gdk_mir_window_set_surface_output (window, mir_surface_output_event_get_scale (event));
+}
+
 typedef struct
 {
   GdkWindow *window;
@@ -598,6 +605,9 @@ gdk_mir_event_source_queue_event (GdkDisplay     *display,
     case mir_event_type_close_surface:
       handle_close_event (window);
       break;
+    case mir_event_type_surface_output:
+      handle_surface_output_event (window, mir_event_get_surface_output_event (event));
+      break;
     default:
       g_warning ("Ignoring unknown Mir event %d", mir_event_get_type (event));
       // FIXME?
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index 1a19ec9..3d234cd 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -16,6 +16,7 @@
  */
 
 #include <inttypes.h>
+#include <math.h>
 
 #include "config.h"
 
@@ -65,6 +66,7 @@ struct _GdkMirWindowImpl
 
   /* Surface being rendered to (only exists when window visible) */
   MirSurface *surface;
+  MirBufferStream *buffer_stream;
 
   /* Cairo context for current frame */
   cairo_surface_t *cairo_surface;
@@ -80,6 +82,8 @@ struct _GdkMirWindowImpl
 
   /* TRUE if cursor is inside this window */
   gboolean cursor_inside;
+
+  gint output_scale;
 };
 
 struct _GdkMirWindowImplClass
@@ -91,6 +95,14 @@ G_DEFINE_TYPE (GdkMirWindowImpl, gdk_mir_window_impl, GDK_TYPE_WINDOW_IMPL)
 
 static cairo_surface_t *gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window);
 
+static void
+drop_cairo_surface (GdkWindow *window)
+{
+  GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+
+  g_clear_pointer (&impl->cairo_surface, cairo_surface_destroy);
+}
+
 GdkWindowImpl *
 _gdk_mir_window_impl_new (void)
 {
@@ -144,6 +156,7 @@ gdk_mir_window_impl_init (GdkMirWindowImpl *impl)
 {
   impl->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
   impl->surface_state = mir_surface_state_unknown;
+  impl->output_scale = 1;
 }
 
 static void
@@ -356,6 +369,7 @@ ensure_surface_full (GdkWindow *window,
                                       impl->has_rect ? &impl->rect : NULL,
                                       impl->has_rect ? impl->edge : mir_edge_attachment_any,
                                       buffer_usage);
+  impl->buffer_stream = mir_surface_get_buffer_stream (impl->surface);
 
   /* FIXME: can't make an initial resize event */
   // MirEvent *resize_event;
@@ -448,6 +462,7 @@ gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window)
   if (window->gl_paint_context)
     {
       cairo_surface = cairo_image_surface_create (pixel_format, window->width, window->height);
+      cairo_surface_set_device_scale (cairo_surface, (double) impl->output_scale, (double) 
impl->output_scale);
     }
   else if (impl->visible)
     {
@@ -496,6 +511,7 @@ gdk_mir_window_impl_ref_cairo_surface (GdkWindow *window)
                                                            region.width,
                                                            region.height,
                                                            region.stride);
+      cairo_surface_set_device_scale (cairo_surface, (double) impl->output_scale, (double) 
impl->output_scale);
     }
   else
     cairo_surface = cairo_image_surface_create (pixel_format, 0, 0);
@@ -1344,8 +1360,8 @@ static gint
 gdk_mir_window_impl_get_scale_factor (GdkWindow *window)
 {
   //g_printerr ("gdk_mir_window_impl_get_scale_factor window=%p\n", window);
-  /* Don't support monitor scaling */
-  return 1;
+  GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+  return impl->output_scale;
 }
 
 static void
@@ -1603,6 +1619,30 @@ gdk_mir_window_get_mir_surface (GdkWindow *window)
   return impl->surface;
 }
 
+void
+_gdk_mir_window_set_surface_output (GdkWindow *window, gdouble scale)
+{
+  // g_printerr ("_gdk_mir_window_impl_set_surface_output impl=%p\n", impl);
+  GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+  GdkRectangle area = {0, 0, window->width, window->height};
+  cairo_region_t *region;
+  gint new_scale = (gint) round (scale);
+
+  if (impl->output_scale != new_scale)
+    {
+      impl->output_scale = new_scale;
+
+      drop_cairo_surface (window);
+
+      if (impl->buffer_stream)
+        mir_buffer_stream_set_scale (impl->buffer_stream, (float) new_scale);
+
+      region = cairo_region_create_rectangle (&area);
+      _gdk_window_invalidate_for_expose (window, region);
+      cairo_region_destroy (region);
+    }
+}
+
 static void
 gdk_mir_window_impl_class_init (GdkMirWindowImplClass *klass)
 {


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