[gnome-flashback] common: avoid gnome_bg_get_surface_from_root



commit ae2fe1c54424121025932405e5c83973034a1bdb
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Mon Nov 25 02:25:33 2019 +0200

    common: avoid gnome_bg_get_surface_from_root
    
    gnome-desktop is removing x11 dependency, get_surface_from_root
    now does nothing and will be removed.
    
    https://gitlab.gnome.org/GNOME/gnome-desktop/commit/b8e99fc3378aca

 gnome-flashback/libcommon/gf-background-utils.c | 112 +++++++++++++++++++++++-
 gnome-flashback/libcommon/gf-background-utils.h |   4 +-
 gnome-flashback/libdesktop/gf-background.c      |   4 +-
 gnome-flashback/libdesktop/gf-desktop-window.c  |   5 +-
 4 files changed, 120 insertions(+), 5 deletions(-)
---
diff --git a/gnome-flashback/libcommon/gf-background-utils.c b/gnome-flashback/libcommon/gf-background-utils.c
index fe5c0b3..21884c4 100644
--- a/gnome-flashback/libcommon/gf-background-utils.c
+++ b/gnome-flashback/libcommon/gf-background-utils.c
@@ -18,6 +18,60 @@
 #include "config.h"
 #include "gf-background-utils.h"
 
+#include <cairo-xlib.h>
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+
+static Pixmap
+get_xrootpmap_id (GdkDisplay *display)
+{
+  Display *xdisplay;
+  Atom xrootpmap_id_atom;
+  int result;
+  Atom actual_type;
+  int actual_format;
+  unsigned long n_items;
+  unsigned long bytes_after;
+  unsigned char *prop;
+  Pixmap pixmap;
+
+  xdisplay = gdk_x11_display_get_xdisplay (display);
+  xrootpmap_id_atom = XInternAtom (xdisplay, "_XROOTPMAP_ID", False);
+
+  gdk_x11_display_error_trap_push (display);
+
+  result = XGetWindowProperty (xdisplay,
+                               XDefaultRootWindow (xdisplay),
+                               xrootpmap_id_atom,
+                               0l,
+                               1l,
+                               False,
+                               XA_PIXMAP,
+                               &actual_type,
+                               &actual_format,
+                               &n_items,
+                               &bytes_after,
+                               &prop);
+
+  gdk_x11_display_error_trap_pop_ignored (display);
+
+  if (result != Success ||
+      actual_type != XA_PIXMAP ||
+      actual_format != 32 ||
+      n_items != 1)
+    {
+      if (prop != NULL)
+        XFree (prop);
+
+      return None;
+    }
+
+  pixmap = *(Pixmap *) prop;
+  XFree (prop);
+
+  return pixmap;
+}
+
 cairo_surface_t *
 gf_background_surface_create (GdkDisplay *display,
                               GnomeBG    *bg,
@@ -29,13 +83,67 @@ gf_background_surface_create (GdkDisplay *display,
 }
 
 cairo_surface_t *
-gf_background_surface_get_from_root (GdkDisplay *display)
+gf_background_surface_get_from_root (GdkDisplay *display,
+                                     int         width,
+                                     int         height)
 {
+  Display *xdisplay;
+  Pixmap root_pixmap;
+  Visual *xvisual;
   GdkScreen *screen;
+  GdkWindow *root;
+  int scale;
+  cairo_surface_t *pixmap_surface;
+  cairo_surface_t *surface;
+
+  xdisplay = gdk_x11_display_get_xdisplay (display);
+
+  root_pixmap = get_xrootpmap_id (display);
+  xvisual = DefaultVisual (xdisplay, DefaultScreen (xdisplay));
 
   screen = gdk_display_get_default_screen (display);
+  root = gdk_screen_get_root_window (screen);
+  scale = gdk_window_get_scale_factor (root);
+
+  pixmap_surface = cairo_xlib_surface_create (xdisplay,
+                                              root_pixmap,
+                                              xvisual,
+                                              width * scale,
+                                              height * scale);
+
+  surface = NULL;
+  if (pixmap_surface != NULL)
+    {
+      cairo_t *cr;
+
+      surface = cairo_surface_create_similar (pixmap_surface,
+                                              CAIRO_CONTENT_COLOR,
+                                              width * scale,
+                                              height * scale);
+
+      cr = cairo_create (surface);
+      cairo_set_source_surface (cr, pixmap_surface, 0, 0);
+      cairo_surface_destroy (pixmap_surface);
+
+      cairo_paint (cr);
+
+      if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
+        g_clear_pointer (&surface, cairo_surface_destroy);
+
+      cairo_destroy (cr);
+    }
+
+  if (surface != NULL)
+    {
+      cairo_surface_set_device_scale (surface, scale, scale);
+
+      return surface;
+    }
 
-  return gnome_bg_get_surface_from_root (screen);
+  return gdk_window_create_similar_surface (root,
+                                            CAIRO_CONTENT_COLOR,
+                                            width,
+                                            height);
 }
 
 void
diff --git a/gnome-flashback/libcommon/gf-background-utils.h b/gnome-flashback/libcommon/gf-background-utils.h
index 95b908c..a2c100e 100644
--- a/gnome-flashback/libcommon/gf-background-utils.h
+++ b/gnome-flashback/libcommon/gf-background-utils.h
@@ -28,7 +28,9 @@ cairo_surface_t *gf_background_surface_create        (GdkDisplay      *display,
                                                       int              width,
                                                       int              height);
 
-cairo_surface_t *gf_background_surface_get_from_root (GdkDisplay      *display);
+cairo_surface_t *gf_background_surface_get_from_root (GdkDisplay      *display,
+                                                      int              width,
+                                                      int              height);
 
 void             gf_background_surface_set_as_root   (GdkDisplay      *display,
                                                       cairo_surface_t *surface);
diff --git a/gnome-flashback/libdesktop/gf-background.c b/gnome-flashback/libdesktop/gf-background.c
index 2d2d69c..869fbd2 100644
--- a/gnome-flashback/libdesktop/gf-background.c
+++ b/gnome-flashback/libdesktop/gf-background.c
@@ -166,7 +166,9 @@ change (GfBackground *self,
       if (self->surface != NULL)
         data->start = cairo_surface_reference (self->surface);
       else
-        data->start = gf_background_surface_get_from_root (display);
+        data->start = gf_background_surface_get_from_root (display,
+                                                           width,
+                                                           height);
 
       data->end = gf_background_surface_create (display,
                                                 self->bg,
diff --git a/gnome-flashback/libdesktop/gf-desktop-window.c b/gnome-flashback/libdesktop/gf-desktop-window.c
index 784bd39..bbb1b22 100644
--- a/gnome-flashback/libdesktop/gf-desktop-window.c
+++ b/gnome-flashback/libdesktop/gf-desktop-window.c
@@ -174,7 +174,10 @@ ensure_surface (GfDesktopWindow *self)
 
   display = gtk_widget_get_display (widget);
 
-  self->surface = gf_background_surface_get_from_root (display);
+  self->surface = gf_background_surface_get_from_root (display,
+                                                       self->width,
+                                                       self->height);
+
   gtk_widget_queue_draw (widget);
   update_css_class (self);
 }


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