[metacity] surface: add meta_surface_get_image



commit 4a80ec0127e2770941d5abac8c8972cf8e058cea
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Sat Oct 12 00:13:15 2019 +0300

    surface: add meta_surface_get_image

 src/compositor/meta-compositor-xrender.c |  98 +---------------------------
 src/compositor/meta-surface-private.h    |  12 ++--
 src/compositor/meta-surface-vulkan.c     |   7 ++
 src/compositor/meta-surface-xrender.c    | 106 +++++++++++++++++++++++++++++++
 src/compositor/meta-surface.c            |   6 ++
 src/compositor/meta-surface.h            |  26 ++++----
 6 files changed, 142 insertions(+), 113 deletions(-)
---
diff --git a/src/compositor/meta-compositor-xrender.c b/src/compositor/meta-compositor-xrender.c
index 586f7c3c..43ad3c5e 100644
--- a/src/compositor/meta-compositor-xrender.c
+++ b/src/compositor/meta-compositor-xrender.c
@@ -31,8 +31,6 @@
 
 #include <gdk/gdk.h>
 #include <libmetacity/meta-frame-borders.h>
-#include <cairo/cairo-xlib.h>
-#include <cairo/cairo-xlib-xrender.h>
 
 #include "display-private.h"
 #include "screen.h"
@@ -1686,98 +1684,6 @@ notify_decorated_cb (MetaWindow            *window,
   add_repair (xrender);
 }
 
-static cairo_surface_t *
-get_window_surface (MetaSurface *surface)
-{
-  MetaCompWindow *cw;
-  MetaFrame *frame;
-  MetaDisplay *display;
-  Display *xdisplay;
-  Pixmap back_pixmap;
-  Pixmap mask_pixmap;
-  gboolean free_pixmap;
-  cairo_surface_t *back_surface;
-  cairo_surface_t *window_surface;
-  cairo_t *cr;
-
-  cw = g_object_get_data (G_OBJECT (surface), "cw");
-
-  frame = meta_window_get_frame (cw->window);
-  display = meta_window_get_display (cw->window);
-  xdisplay = meta_display_get_xdisplay (display);
-
-  back_pixmap = meta_surface_get_pixmap (surface);
-  if (back_pixmap == None)
-    return NULL;
-
-  mask_pixmap = meta_surface_xrender_get_mask_pixmap (META_SURFACE_XRENDER (surface));
-  free_pixmap = FALSE;
-
-  if (cw->window->opacity != (guint) OPAQUE)
-    {
-      mask_pixmap = meta_surface_xrender_create_mask_pixmap (META_SURFACE_XRENDER (surface), FALSE);
-      free_pixmap = TRUE;
-    }
-
-  back_surface = cairo_xlib_surface_create (xdisplay, back_pixmap,
-                                            get_toplevel_xvisual (cw->window),
-                                            cw->rect.width, cw->rect.height);
-
-  window_surface = cairo_surface_create_similar (back_surface,
-                                                 CAIRO_CONTENT_COLOR_ALPHA,
-                                                 cw->rect.width,
-                                                 cw->rect.height);
-
-  cr = cairo_create (window_surface);
-  cairo_set_source_surface (cr, back_surface, 0, 0);
-  cairo_surface_destroy (back_surface);
-
-  if (mask_pixmap != None)
-    {
-      Screen *xscreen;
-      XRenderPictFormat *format;
-      int width;
-      int height;
-      cairo_surface_t *mask;
-      cairo_pattern_t *pattern;
-
-      xscreen = DefaultScreenOfDisplay (xdisplay);
-      format = XRenderFindStandardFormat (xdisplay, PictStandardA8);
-
-      width = frame != NULL ? cw->rect.width : 1;
-      height = frame != NULL ? cw->rect.height : 1;
-
-      mask = cairo_xlib_surface_create_with_xrender_format (xdisplay,
-                                                            mask_pixmap,
-                                                            xscreen,
-                                                            format,
-                                                            width,
-                                                            height);
-
-      pattern = cairo_pattern_create_for_surface (mask);
-      cairo_surface_destroy (mask);
-
-      if (frame == NULL)
-        cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
-
-      cairo_mask (cr, pattern);
-      cairo_fill (cr);
-
-      cairo_pattern_destroy (pattern);
-    }
-  else
-    {
-      cairo_paint (cr);
-    }
-
-  cairo_destroy (cr);
-
-  if (free_pixmap && mask_pixmap != None)
-    XFreePixmap (xdisplay, mask_pixmap);
-
-  return window_surface;
-}
-
 static void
 notify_shaded_cb (MetaWindow  *window,
                   GParamSpec  *pspec,
@@ -1794,7 +1700,7 @@ notify_shaded_cb (MetaWindow  *window,
     }
 
   if (meta_window_is_shaded (cw->window))
-    cw->shaded_surface = get_window_surface (surface);
+    cw->shaded_surface = meta_surface_get_image (surface);
 }
 
 /* event processors must all be called with an error trap in place */
@@ -2371,7 +2277,7 @@ meta_compositor_xrender_get_window_surface (MetaCompositor *compositor,
         return NULL;
     }
 
-  return get_window_surface (surface);
+  return meta_surface_get_image (surface);
 }
 
 static void
diff --git a/src/compositor/meta-surface-private.h b/src/compositor/meta-surface-private.h
index 799066c2..a92a69c9 100644
--- a/src/compositor/meta-surface-private.h
+++ b/src/compositor/meta-surface-private.h
@@ -26,15 +26,17 @@ struct _MetaSurfaceClass
 {
   GObjectClass parent_class;
 
-  void (* show)            (MetaSurface *self);
+  cairo_surface_t * (* get_image)       (MetaSurface *self);
 
-  void (* hide)            (MetaSurface *self);
+  void              (* show)            (MetaSurface *self);
 
-  void (* opacity_changed) (MetaSurface *self);
+  void              (* hide)            (MetaSurface *self);
 
-  void (* free_pixmap)     (MetaSurface *self);
+  void              (* opacity_changed) (MetaSurface *self);
 
-  void (* pre_paint)       (MetaSurface *self);
+  void              (* free_pixmap)     (MetaSurface *self);
+
+  void              (* pre_paint)       (MetaSurface *self);
 };
 
 G_END_DECLS
diff --git a/src/compositor/meta-surface-vulkan.c b/src/compositor/meta-surface-vulkan.c
index f106c004..bb02e2d9 100644
--- a/src/compositor/meta-surface-vulkan.c
+++ b/src/compositor/meta-surface-vulkan.c
@@ -25,6 +25,12 @@ struct _MetaSurfaceVulkan
 
 G_DEFINE_TYPE (MetaSurfaceVulkan, meta_surface_vulkan, META_TYPE_SURFACE)
 
+static cairo_surface_t *
+meta_surface_vulkan_get_image (MetaSurface *surface)
+{
+  return NULL;
+}
+
 static void
 meta_surface_vulkan_show (MetaSurface *surface)
 {
@@ -57,6 +63,7 @@ meta_surface_vulkan_class_init (MetaSurfaceVulkanClass *self_class)
 
   surface_class = META_SURFACE_CLASS (self_class);
 
+  surface_class->get_image = meta_surface_vulkan_get_image;
   surface_class->show = meta_surface_vulkan_show;
   surface_class->hide = meta_surface_vulkan_hide;
   surface_class->opacity_changed = meta_surface_vulkan_opacity_changed;
diff --git a/src/compositor/meta-surface-xrender.c b/src/compositor/meta-surface-xrender.c
index 254fea67..edbd6218 100644
--- a/src/compositor/meta-surface-xrender.c
+++ b/src/compositor/meta-surface-xrender.c
@@ -18,6 +18,7 @@
 #include "config.h"
 #include "meta-surface-xrender.h"
 
+#include <cairo/cairo-xlib.h>
 #include <cairo/cairo-xlib-xrender.h>
 #include <libmetacity/meta-frame-borders.h>
 
@@ -185,6 +186,110 @@ meta_surface_xrender_finalize (GObject *object)
   G_OBJECT_CLASS (meta_surface_xrender_parent_class)->finalize (object);
 }
 
+static cairo_surface_t *
+meta_surface_xrender_get_image (MetaSurface *surface)
+{
+  MetaSurfaceXRender *self;
+  Pixmap back_pixmap;
+  MetaWindow *window;
+  Pixmap mask_pixmap;
+  gboolean free_pixmap;
+  MetaDisplay *display;
+  Display *xdisplay;
+  Visual *visual;
+  int width;
+  int height;
+  cairo_surface_t *back_surface;
+  cairo_surface_t *image;
+  cairo_t *cr;
+
+  self = META_SURFACE_XRENDER (surface);
+
+  back_pixmap = meta_surface_get_pixmap (surface);
+  if (back_pixmap == None)
+    return NULL;
+
+  window = meta_surface_get_window (surface);
+
+  mask_pixmap = self->mask_pixmap;
+  free_pixmap = FALSE;
+
+  if (window->opacity != OPAQUE)
+    {
+      mask_pixmap = meta_surface_xrender_create_mask_pixmap (self, FALSE);
+      free_pixmap = TRUE;
+    }
+
+  display = meta_window_get_display (window);
+  xdisplay = meta_display_get_xdisplay (display);
+
+  visual = meta_window_get_toplevel_xvisual (window);
+  width = meta_surface_get_width (surface);
+  height = meta_surface_get_height (surface);
+
+  back_surface = cairo_xlib_surface_create (xdisplay,
+                                            back_pixmap,
+                                            visual,
+                                            width,
+                                            height);
+
+  image = cairo_surface_create_similar (back_surface,
+                                        CAIRO_CONTENT_COLOR_ALPHA,
+                                        width,
+                                        height);
+
+  cr = cairo_create (image);
+  cairo_set_source_surface (cr, back_surface, 0, 0);
+  cairo_surface_destroy (back_surface);
+
+  if (mask_pixmap != None)
+    {
+      Screen *xscreen;
+      XRenderPictFormat *format;
+      MetaFrame *frame;
+      int mask_width;
+      int mask_height;
+      cairo_surface_t *mask;
+      cairo_pattern_t *pattern;
+
+      xscreen = DefaultScreenOfDisplay (xdisplay);
+      format = XRenderFindStandardFormat (xdisplay, PictStandardA8);
+
+      frame = meta_window_get_frame (window);
+      mask_width = frame != NULL ? width : 1;
+      mask_height = frame != NULL ? height : 1;
+
+      mask = cairo_xlib_surface_create_with_xrender_format (xdisplay,
+                                                            mask_pixmap,
+                                                            xscreen,
+                                                            format,
+                                                            mask_width,
+                                                            mask_height);
+
+      pattern = cairo_pattern_create_for_surface (mask);
+      cairo_surface_destroy (mask);
+
+      if (frame == NULL)
+        cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
+
+      cairo_mask (cr, pattern);
+      cairo_pattern_destroy (pattern);
+
+      cairo_fill (cr);
+    }
+  else
+    {
+      cairo_paint (cr);
+    }
+
+  cairo_destroy (cr);
+
+  if (free_pixmap && mask_pixmap != None)
+    XFreePixmap (xdisplay, mask_pixmap);
+
+  return image;
+}
+
 static void
 meta_surface_xrender_show (MetaSurface *surface)
 {
@@ -267,6 +372,7 @@ meta_surface_xrender_class_init (MetaSurfaceXRenderClass *self_class)
 
   object_class->finalize = meta_surface_xrender_finalize;
 
+  surface_class->get_image = meta_surface_xrender_get_image;
   surface_class->show = meta_surface_xrender_show;
   surface_class->hide = meta_surface_xrender_hide;
   surface_class->opacity_changed = meta_surface_xrender_opacity_changed;
diff --git a/src/compositor/meta-surface.c b/src/compositor/meta-surface.c
index 04bb5350..6542df7d 100644
--- a/src/compositor/meta-surface.c
+++ b/src/compositor/meta-surface.c
@@ -334,6 +334,12 @@ meta_surface_get_height (MetaSurface *self)
   return priv->height;
 }
 
+cairo_surface_t *
+meta_surface_get_image (MetaSurface *self)
+{
+  return META_SURFACE_GET_CLASS (self)->get_image (self);
+}
+
 void
 meta_surface_show (MetaSurface *self)
 {
diff --git a/src/compositor/meta-surface.h b/src/compositor/meta-surface.h
index f05404af..7f374d53 100644
--- a/src/compositor/meta-surface.h
+++ b/src/compositor/meta-surface.h
@@ -27,28 +27,30 @@ G_BEGIN_DECLS
 #define META_TYPE_SURFACE (meta_surface_get_type ())
 G_DECLARE_DERIVABLE_TYPE (MetaSurface, meta_surface, META, SURFACE, GObject)
 
-MetaCompositor *meta_surface_get_compositor  (MetaSurface        *self);
+MetaCompositor  *meta_surface_get_compositor  (MetaSurface        *self);
 
-MetaWindow     *meta_surface_get_window      (MetaSurface        *self);
+MetaWindow      *meta_surface_get_window      (MetaSurface        *self);
 
-Pixmap          meta_surface_get_pixmap      (MetaSurface        *self);
+Pixmap           meta_surface_get_pixmap      (MetaSurface        *self);
 
-int             meta_surface_get_width       (MetaSurface        *self);
+int              meta_surface_get_width       (MetaSurface        *self);
 
-int             meta_surface_get_height      (MetaSurface        *self);
+int              meta_surface_get_height      (MetaSurface        *self);
 
-void            meta_surface_show            (MetaSurface        *self);
+cairo_surface_t *meta_surface_get_image       (MetaSurface        *self);
 
-void            meta_surface_hide            (MetaSurface        *self);
+void             meta_surface_show            (MetaSurface        *self);
 
-void            meta_surface_process_damage  (MetaSurface        *self,
-                                              XDamageNotifyEvent *event);
+void             meta_surface_hide            (MetaSurface        *self);
 
-void            meta_surface_opacity_changed (MetaSurface        *self);
+void             meta_surface_process_damage  (MetaSurface        *self,
+                                               XDamageNotifyEvent *event);
 
-void            meta_surface_sync_geometry   (MetaSurface        *self);
+void             meta_surface_opacity_changed (MetaSurface        *self);
 
-void            meta_surface_pre_paint       (MetaSurface        *self);
+void             meta_surface_sync_geometry   (MetaSurface        *self);
+
+void             meta_surface_pre_paint       (MetaSurface        *self);
 
 G_END_DECLS
 


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