diff options
-rw-r--r-- | libmate-desktop/libmateui/mate-bg-crossfade.h | 12 | ||||
-rw-r--r-- | libmate-desktop/libmateui/mate-bg.h | 35 | ||||
-rw-r--r-- | libmate-desktop/mate-bg-crossfade.c | 220 | ||||
-rw-r--r-- | libmate-desktop/mate-bg.c | 385 |
4 files changed, 364 insertions, 288 deletions
diff --git a/libmate-desktop/libmateui/mate-bg-crossfade.h b/libmate-desktop/libmateui/mate-bg-crossfade.h index 268f1c7..28c1e28 100644 --- a/libmate-desktop/libmateui/mate-bg-crossfade.h +++ b/libmate-desktop/libmateui/mate-bg-crossfade.h @@ -66,11 +66,15 @@ MateBGCrossfade *mate_bg_crossfade_new (int width, int height); #if GTK_CHECK_VERSION(3, 0, 0) - gboolean mate_bg_crossfade_set_start_pixmap(MateBGCrossfade* fade, cairo_surface_t* pixmap); - gboolean mate_bg_crossfade_set_end_pixmap(MateBGCrossfade* fade, cairo_surface_t* pixmap); +gboolean mate_bg_crossfade_set_start_surface (MateBGCrossfade *fade, + cairo_surface_t *surface); +gboolean mate_bg_crossfade_set_end_surface (MateBGCrossfade *fade, + cairo_surface_t *surface); #else - gboolean mate_bg_crossfade_set_start_pixmap(MateBGCrossfade* fade, GdkPixmap* pixmap); - gboolean mate_bg_crossfade_set_end_pixmap(MateBGCrossfade* fade, GdkPixmap* pixmap); +gboolean mate_bg_crossfade_set_start_pixmap (MateBGCrossfade *fade, + GdkPixmap *pixmap); +gboolean mate_bg_crossfade_set_end_pixmap (MateBGCrossfade *fade, + GdkPixmap *pixmap); #endif void mate_bg_crossfade_start (MateBGCrossfade *fade, diff --git a/libmate-desktop/libmateui/mate-bg.h b/libmate-desktop/libmateui/mate-bg.h index 45b3615..61e2a01 100644 --- a/libmate-desktop/libmateui/mate-bg.h +++ b/libmate-desktop/libmateui/mate-bg.h @@ -96,10 +96,14 @@ void mate_bg_draw (MateBG *bg, gboolean is_root); #if GTK_CHECK_VERSION(3, 0, 0) - cairo_surface_t* mate_bg_create_pixmap(MateBG* bg, GdkWindow* window, int width, int height, gboolean root); +cairo_surface_t *mate_bg_create_surface (MateBG *bg, #else - GdkPixmap* mate_bg_create_pixmap(MateBG* bg, GdkWindow* window, int width, int height, gboolean root); +GdkPixmap *mate_bg_create_pixmap (MateBG *bg, #endif + GdkWindow *window, + int width, + int height, + gboolean root); gboolean mate_bg_get_image_size (MateBG *bg, MateDesktopThumbnailFactory *factory, @@ -124,20 +128,25 @@ GdkPixbuf * mate_bg_create_frame_thumbnail (MateBG *bg, int dest_height, int frame_num); -/* Set a pixmap as root - not a MateBG method. At some point +/* Set a surface as root - not a MateBG method. At some point * if we decide to stabilize the API then we may want to make - * these object methods, drop mate_bg_create_pixmap, etc. + * these object methods, drop mate_bg_create_surface, etc. */ - #if GTK_CHECK_VERSION(3, 0, 0) - void mate_bg_set_pixmap_as_root(GdkScreen* screen, cairo_surface_t* pixmap); - MateBGCrossfade* mate_bg_set_pixmap_as_root_with_crossfade(GdkScreen* screen, cairo_surface_t* pixmap); - cairo_surface_t* mate_bg_get_pixmap_from_root(GdkScreen* screen); -#else - void mate_bg_set_pixmap_as_root(GdkScreen* screen, GdkPixmap* pixmap); - MateBGCrossfade* mate_bg_set_pixmap_as_root_with_crossfade(GdkScreen* screen, GdkPixmap* pixmap); - GdkPixmap* mate_bg_get_pixmap_from_root(GdkScreen* screen); -#endif +void mate_bg_set_surface_as_root (GdkScreen *screen, + cairo_surface_t *surface); +MateBGCrossfade *mate_bg_set_surface_as_root_with_crossfade (GdkScreen *screen, + cairo_surface_t *surface); +cairo_surface_t *mate_bg_get_surface_from_root (GdkScreen *screen); + +#else /* GTK_CHECK_VERSION(3, 0, 0) */ + +void mate_bg_set_pixmap_as_root (GdkScreen *screen, + GdkPixmap *pixmap); +MateBGCrossfade *mate_bg_set_pixmap_as_root_with_crossfade (GdkScreen *screen, + GdkPixmap *pixmap); +GdkPixmap *mate_bg_get_pixmap_from_root (GdkScreen *screen); +#endif /* GTK_CHECK_VERSION(3, 0, 0) */ #ifdef __cplusplus } diff --git a/libmate-desktop/mate-bg-crossfade.c b/libmate-desktop/mate-bg-crossfade.c index 48afc37..c3667cd 100644 --- a/libmate-desktop/mate-bg-crossfade.c +++ b/libmate-desktop/mate-bg-crossfade.c @@ -1,4 +1,4 @@ -/* mate-bg-crossfade.h - fade window background between two pixmaps +/* mate-bg-crossfade.h - fade window background between two surfaces * * Copyright (C) 2008 Red Hat, Inc. * @@ -38,24 +38,24 @@ #include <libmateui/mate-bg.h> #include "libmateui/mate-bg-crossfade.h" +#if !GTK_CHECK_VERSION(3, 0, 0) +#define cairo_surface_t GdkPixmap +#define cairo_create gdk_cairo_create +#define cairo_set_source_surface gdk_cairo_set_source_pixmap +#define cairo_surface_destroy g_object_unref +#endif + struct _MateBGCrossfadePrivate { - GdkWindow *window; - int width; - int height; - - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_surface_t* fading_pixmap; - cairo_surface_t* end_pixmap; - #else - GdkPixmap* fading_pixmap; - GdkPixmap* end_pixmap; - #endif - - gdouble start_time; - gdouble total_duration; - guint timeout_id; - guint is_first_frame : 1; + GdkWindow *window; + int width; + int height; + cairo_surface_t *fading_surface; + cairo_surface_t *end_surface; + gdouble start_time; + gdouble total_duration; + guint timeout_id; + guint is_first_frame : 1; }; enum { @@ -138,14 +138,14 @@ mate_bg_crossfade_finalize (GObject *object) mate_bg_crossfade_stop (fade); - if (fade->priv->fading_pixmap != NULL) { - g_object_unref (fade->priv->fading_pixmap); - fade->priv->fading_pixmap = NULL; + if (fade->priv->fading_surface != NULL) { + cairo_surface_destroy (fade->priv->fading_surface); + fade->priv->fading_surface = NULL; } - if (fade->priv->end_pixmap != NULL) { - g_object_unref (fade->priv->end_pixmap); - fade->priv->end_pixmap = NULL; + if (fade->priv->end_surface != NULL) { + cairo_surface_destroy (fade->priv->end_surface); + fade->priv->end_surface = NULL; } } @@ -164,7 +164,7 @@ mate_bg_crossfade_class_init (MateBGCrossfadeClass *fade_class) * MateBGCrossfade:width: * * When a crossfade is running, this is width of the fading - * pixmap. + * surface. */ g_object_class_install_property (gobject_class, PROP_WIDTH, @@ -178,7 +178,7 @@ mate_bg_crossfade_class_init (MateBGCrossfadeClass *fade_class) * MateBGCrossfade:height: * * When a crossfade is running, this is height of the fading - * pixmap. + * surface. */ g_object_class_install_property (gobject_class, PROP_HEIGHT, @@ -193,7 +193,7 @@ mate_bg_crossfade_class_init (MateBGCrossfadeClass *fade_class) * @window: the #GdkWindow the crossfade happend on. * * When a crossfade finishes, @window will have a copy - * of the end pixmap as its background, and this signal will + * of the end surface as its background, and this signal will * get emitted. */ signals[FINISHED] = g_signal_new ("finished", @@ -210,8 +210,8 @@ mate_bg_crossfade_init (MateBGCrossfade *fade) { fade->priv = MATE_BG_CROSSFADE_GET_PRIVATE (fade); - fade->priv->fading_pixmap = NULL; - fade->priv->end_pixmap = NULL; + fade->priv->fading_surface = NULL; + fade->priv->end_surface = NULL; fade->priv->timeout_id = 0; } @@ -221,11 +221,11 @@ mate_bg_crossfade_init (MateBGCrossfade *fade) * @height: The height of the crossfading window * * Creates a new object to manage crossfading a - * window background between two #GdkPixmap drawables. + * window background between two #cairo_surface_ts. * * Return value: the new #MateBGCrossfade **/ -MateBGCrossfade* mate_bg_crossfade_new(int width, int height) +MateBGCrossfade* mate_bg_crossfade_new (int width, int height) { GObject* object; @@ -237,28 +237,37 @@ MateBGCrossfade* mate_bg_crossfade_new(int width, int height) return (MateBGCrossfade*) object; } -#if GTK_CHECK_VERSION(3, 0, 0) - static cairo_surface_t* tile_pixmap(cairo_surface_t* pixmap, int width, int height) -#else - static GdkPixmap* tile_pixmap(GdkPixmap* pixmap, int width, int height) -#endif +static cairo_surface_t * +tile_surface (cairo_surface_t *surface, + int width, + int height) { - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_surface_t* copy; - #else - GdkPixmap* copy; - #endif - + cairo_surface_t *copy; cairo_t *cr; - copy = gdk_pixmap_new(pixmap, width, height, pixmap == NULL? 24 : -1); +#if GTK_CHECK_VERSION (3, 0, 0) + if (surface == NULL) + { + copy = gdk_window_create_similar_surface (gdk_get_default_root_window (), + CAIRO_CONTENT_COLOR, + width, height); + } + else + { + copy = cairo_surface_create_similar (surface, + cairo_surface_get_content (surface), + width, height); + } +#else + copy = gdk_pixmap_new(surface, width, height, surface == NULL? 24 : -1); +#endif - cr = gdk_cairo_create(copy); + cr = cairo_create (copy); - if (pixmap != NULL) + if (surface != NULL) { cairo_pattern_t *pattern; - gdk_cairo_set_source_pixmap (cr, pixmap, 0.0, 0.0); + cairo_set_source_surface (cr, surface, 0.0, 0.0); pattern = cairo_get_source (cr); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); } @@ -273,7 +282,7 @@ MateBGCrossfade* mate_bg_crossfade_new(int width, int height) if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { - g_object_unref (copy); + cairo_surface_destroy (copy); copy = NULL; } @@ -283,36 +292,37 @@ MateBGCrossfade* mate_bg_crossfade_new(int width, int height) } /** - * mate_bg_crossfade_set_start_pixmap: + * mate_bg_crossfade_set_start_surface: * @fade: a #MateBGCrossfade - * @pixmap: The #GdkPixmap to fade from + * @surface: The cairo surface to fade from * * Before initiating a crossfade with mate_bg_crossfade_start() - * a start and end pixmap have to be set. This function sets - * the pixmap shown at the beginning of the crossfade effect. + * a start and end surface have to be set. This function sets + * the surface shown at the beginning of the crossfade effect. * - * Return value: %TRUE if successful, or %FALSE if the pixmap + * Return value: %TRUE if successful, or %FALSE if the surface * could not be copied. **/ +gboolean #if GTK_CHECK_VERSION(3, 0, 0) - gboolean mate_bg_crossfade_set_start_pixmap(MateBGCrossfade* fade, cairo_surface_t* pixmap) +mate_bg_crossfade_set_start_surface (MateBGCrossfade* fade, cairo_surface_t *surface) #else - gboolean mate_bg_crossfade_set_start_pixmap(MateBGCrossfade* fade, GdkPixmap* pixmap) +mate_bg_crossfade_set_start_pixmap (MateBGCrossfade* fade, GdkPixmap *surface) #endif { g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE); - if (fade->priv->fading_pixmap != NULL) + if (fade->priv->fading_surface != NULL) { - g_object_unref (fade->priv->fading_pixmap); - fade->priv->fading_pixmap = NULL; + cairo_surface_destroy (fade->priv->fading_surface); + fade->priv->fading_surface = NULL; } - fade->priv->fading_pixmap = tile_pixmap(pixmap, - fade->priv->width, - fade->priv->height); + fade->priv->fading_surface = tile_surface (surface, + fade->priv->width, + fade->priv->height); - return fade->priv->fading_pixmap != NULL; + return fade->priv->fading_surface != NULL; } static gdouble @@ -331,38 +341,39 @@ get_current_time (void) } /** - * mate_bg_crossfade_set_end_pixmap: + * mate_bg_crossfade_set_end_surface: * @fade: a #MateBGCrossfade - * @pixmap: The #GdkPixmap to fade to + * @surface: The cairo surface to fade to * * Before initiating a crossfade with mate_bg_crossfade_start() - * a start and end pixmap have to be set. This function sets - * the pixmap shown at the end of the crossfade effect. + * a start and end surface have to be set. This function sets + * the surface shown at the end of the crossfade effect. * - * Return value: %TRUE if successful, or %FALSE if the pixmap + * Return value: %TRUE if successful, or %FALSE if the surface * could not be copied. **/ +gboolean #if GTK_CHECK_VERSION(3, 0, 0) - gboolean mate_bg_crossfade_set_end_pixmap(MateBGCrossfade* fade, cairo_surface_t* pixmap) +mate_bg_crossfade_set_end_surface (MateBGCrossfade* fade, cairo_surface_t *surface) #else - gboolean mate_bg_crossfade_set_end_pixmap(MateBGCrossfade* fade, GdkPixmap* pixmap) +mate_bg_crossfade_set_end_pixmap (MateBGCrossfade* fade, GdkPixmap *surface) #endif { g_return_val_if_fail (MATE_IS_BG_CROSSFADE (fade), FALSE); - if (fade->priv->end_pixmap != NULL) { - g_object_unref (fade->priv->end_pixmap); - fade->priv->end_pixmap = NULL; + if (fade->priv->end_surface != NULL) { + cairo_surface_destroy (fade->priv->end_surface); + fade->priv->end_surface = NULL; } - fade->priv->end_pixmap = tile_pixmap (pixmap, - fade->priv->width, - fade->priv->height); + fade->priv->end_surface = tile_surface (surface, + fade->priv->width, + fade->priv->height); /* Reset timer in case we're called while animating */ fade->priv->start_time = get_current_time (); - return fade->priv->end_pixmap != NULL; + return fade->priv->end_surface != NULL; } static gboolean @@ -374,11 +385,7 @@ animations_are_disabled (MateBGCrossfade *fade) g_assert (fade->priv->window != NULL); - #if GTK_CHECK_VERSION(2, 24, 0) - screen = gdk_window_get_screen(fade->priv->window); - #else // since 2.2 - screen = gdk_drawable_get_screen(GDK_DRAWABLE(fade->priv->window)); - #endif + screen = gdk_window_get_screen(fade->priv->window); settings = gtk_settings_get_for_screen (screen); @@ -391,9 +398,12 @@ static void draw_background (MateBGCrossfade *fade) { if (GDK_WINDOW_TYPE (fade->priv->window) == GDK_WINDOW_ROOT) { - GdkDisplay *display; - display = gdk_drawable_get_display (fade->priv->window); - gdk_window_clear (fade->priv->window); + XClearArea (GDK_WINDOW_XDISPLAY (fade->priv->window), + GDK_WINDOW_XID (fade->priv->window), + 0, 0, + gdk_window_get_width (fade->priv->window), + gdk_window_get_height (fade->priv->window), + False); gdk_flush (); } else { gdk_window_invalidate_rect (fade->priv->window, NULL, FALSE); @@ -425,7 +435,7 @@ on_tick (MateBGCrossfade *fade) return on_tick (fade); } - if (fade->priv->fading_pixmap == NULL) { + if (fade->priv->fading_surface == NULL) { return FALSE; } @@ -441,10 +451,10 @@ on_tick (MateBGCrossfade *fade) * even the fastest machines will get *some* fade because the framerate * is capped. */ - cr = gdk_cairo_create (fade->priv->fading_pixmap); + cr = cairo_create (fade->priv->fading_surface); - gdk_cairo_set_source_pixmap (cr, fade->priv->end_pixmap, - 0.0, 0.0); + cairo_set_source_surface (cr, fade->priv->end_surface, + 0.0, 0.0); cairo_paint_with_alpha (cr, percent_done); status = cairo_status (cr); @@ -462,20 +472,27 @@ on_finished (MateBGCrossfade *fade) if (fade->priv->timeout_id == 0) return; - g_assert (fade->priv->end_pixmap != NULL); + g_assert (fade->priv->end_surface != NULL); +#if GTK_CHECK_VERSION (3, 0, 0) + cairo_pattern_t *pattern; + pattern = cairo_pattern_create_for_surface (fade->priv->end_surface); + gdk_window_set_background_pattern (fade->priv->window, pattern); + cairo_pattern_destroy (pattern); +#else gdk_window_set_back_pixmap (fade->priv->window, - fade->priv->end_pixmap, + fade->priv->end_surface, FALSE); +#endif draw_background (fade); - g_object_unref (fade->priv->end_pixmap); - fade->priv->end_pixmap = NULL; + cairo_surface_destroy (fade->priv->end_surface); + fade->priv->end_surface = NULL; - g_assert (fade->priv->fading_pixmap != NULL); + g_assert (fade->priv->fading_surface != NULL); - g_object_unref (fade->priv->fading_pixmap); - fade->priv->fading_pixmap = NULL; + cairo_surface_destroy (fade->priv->fading_surface); + fade->priv->fading_surface = NULL; fade->priv->timeout_id = 0; g_signal_emit (fade, signals[FINISHED], 0, fade->priv->window); @@ -486,11 +503,11 @@ on_finished (MateBGCrossfade *fade) * @fade: a #MateBGCrossfade * @window: The #GdkWindow to draw crossfade on * - * This function initiates a quick crossfade between two pixmaps on + * This function initiates a quick crossfade between two surfaces on * the background of @window. Before initiating the crossfade both * mate_bg_crossfade_start() and mate_bg_crossfade_end() need to * be called. If animations are disabled, the crossfade is skipped, - * and the window background is set immediately to the end pixmap. + * and the window background is set immediately to the end surface. **/ void mate_bg_crossfade_start (MateBGCrossfade *fade, @@ -501,8 +518,8 @@ mate_bg_crossfade_start (MateBGCrossfade *fade, g_return_if_fail (MATE_IS_BG_CROSSFADE (fade)); g_return_if_fail (window != NULL); - g_return_if_fail (fade->priv->fading_pixmap != NULL); - g_return_if_fail (fade->priv->end_pixmap != NULL); + g_return_if_fail (fade->priv->fading_surface != NULL); + g_return_if_fail (fade->priv->end_surface != NULL); g_return_if_fail (!mate_bg_crossfade_is_started (fade)); g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN); @@ -516,9 +533,16 @@ mate_bg_crossfade_start (MateBGCrossfade *fade, g_source_unref (source); fade->priv->window = window; +#if GTK_CHECK_VERSION (3, 0, 0) + cairo_pattern_t *pattern; + pattern = cairo_pattern_create_for_surface (fade->priv->fading_surface); + gdk_window_set_background_pattern (fade->priv->window, pattern); + cairo_pattern_destroy (pattern); +#else gdk_window_set_back_pixmap (fade->priv->window, - fade->priv->fading_pixmap, + fade->priv->fading_surface, FALSE); +#endif draw_background (fade); fade->priv->is_first_frame = TRUE; diff --git a/libmate-desktop/mate-bg.c b/libmate-desktop/mate-bg.c index 0e95471..1423415 100644 --- a/libmate-desktop/mate-bg.c +++ b/libmate-desktop/mate-bg.c @@ -34,19 +34,24 @@ Author: Soren Sandmann <[email protected]> #include <gio/gio.h> -#include <gdk/gdk.h> #include <gdk/gdkx.h> #include <X11/Xlib.h> #include <X11/Xatom.h> #include <cairo.h> -#include <gio/gio.h> - #define MATE_DESKTOP_USE_UNSTABLE_API #include <libmateui/mate-bg.h> #include <libmateui/mate-bg-crossfade.h> +#if GTK_CHECK_VERSION (3, 0, 0) +# include <cairo-xlib.h> +#else +#define cairo_surface_t GdkPixmap +#define cairo_create gdk_cairo_create +#define cairo_surface_destroy g_object_unref +#endif + #define BG_KEY_DRAW_BACKGROUND "draw-background" #define BG_KEY_PRIMARY_COLOR "primary-color" #define BG_KEY_SECONDARY_COLOR "secondary-color" @@ -129,11 +134,13 @@ static guint signals[N_SIGNALS] = {0}; G_DEFINE_TYPE(MateBG, mate_bg, G_TYPE_OBJECT) -#if GTK_CHECK_VERSION(3, 0, 0) - static cairo_surface_t* make_root_pixmap(GdkScreen* screen, gint width, gint height); +#if GTK_CHECK_VERSION (3, 0, 0) +static cairo_surface_t *make_root_pixmap (GdkScreen *screen, #else - static GdkPixmap* make_root_pixmap(GdkScreen* screen, gint width, gint height); +static GdkPixmap *make_root_pixmap (GdkScreen *screen, #endif + gint width, + gint height); /* Pixbuf utils */ static guint32 pixbuf_average_value (GdkPixbuf *pixbuf); @@ -144,12 +151,11 @@ static GdkPixbuf *pixbuf_scale_to_min (GdkPixbuf *src, int min_width, int min_height); -#if GTK_CHECK_VERSION(3, 0, 0) - static void pixbuf_draw_gradient(GdkPixbuf* pixbuf, gboolean horizontal, GdkColor* c1, GdkColor* c2, cairo_rectangle_int_t* rect); -#else - static void pixbuf_draw_gradient(GdkPixbuf* pixbuf, gboolean horizontal, GdkColor* c1, GdkColor* c2, GdkRectangle* rect); -#endif - +static void pixbuf_draw_gradient (GdkPixbuf *pixbuf, + gboolean horizontal, + GdkColor *c1, + GdkColor *c2, + GdkRectangle *rect); static void pixbuf_tile (GdkPixbuf *src, GdkPixbuf *dest); @@ -615,27 +621,20 @@ mate_bg_set_filename (MateBG *bg, } } -#if GTK_CHECK_VERSION(3, 0, 0) - static void draw_color_area(MateBG* bg, GdkPixbuf* dest, cairo_rectangle_int_t* rect) -#else - static void draw_color_area(MateBG* bg, GdkPixbuf* dest, GdkRectangle* rect) -#endif +static void +draw_color_area (MateBG *bg, + GdkPixbuf *dest, + GdkRectangle *rect) { guint32 pixel; - - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_rectangle_int_t extent; - #else - GdkRectangle extent; - #endif - + GdkRectangle extent; extent.x = 0; extent.y = 0; extent.width = gdk_pixbuf_get_width (dest); extent.height = gdk_pixbuf_get_height (dest); - gdk_rectangle_intersect(rect, &extent, rect); + gdk_rectangle_intersect (rect, &extent, rect); switch (bg->color_type) { case MATE_BG_COLOR_SOLID: @@ -666,11 +665,7 @@ draw_color (MateBG *bg, GdkPixbuf *dest, GdkScreen *screen) { - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_rectangle_int_t rect; - #else - GdkRectangle rect; - #endif + GdkRectangle rect; rect.x = 0; rect.y = 0; @@ -684,11 +679,7 @@ draw_color_each_monitor (MateBG *bg, GdkPixbuf *dest, GdkScreen *screen) { - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_rectangle_int_t rect; - #else - GdkRectangle rect; - #endif + GdkRectangle rect; gint num_monitors; int monitor; @@ -780,11 +771,11 @@ get_scaled_pixbuf (MateBGPlacement placement, } -#if GTK_CHECK_VERSION(3, 0, 0) - static void draw_image_area(MateBGPlacement placement, GdkPixbuf* pixbuf, GdkPixbuf* dest, cairo_rectangle_int_t* area) -#else - static void draw_image_area(MateBGPlacement placement, GdkPixbuf* pixbuf, GdkPixbuf* dest, GdkRectangle* area) -#endif +static void +draw_image_area (MateBGPlacement placement, + GdkPixbuf *pixbuf, + GdkPixbuf *dest, + GdkRectangle *area) { int dest_width = area->width; int dest_height = area->height; @@ -822,11 +813,7 @@ draw_image (MateBGPlacement placement, GdkPixbuf *pixbuf, GdkPixbuf *dest) { - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_rectangle_int_t rect; - #else - GdkRectangle rect; - #endif + GdkRectangle rect; rect.x = 0; rect.y = 0; @@ -841,12 +828,7 @@ draw_once (MateBG *bg, GdkPixbuf *dest, GdkScreen *screen) { - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_rectangle_int_t rect; - #else - GdkRectangle rect; - #endif - + GdkRectangle rect; GdkPixbuf *pixbuf; rect.x = 0; @@ -869,11 +851,7 @@ draw_each_monitor (MateBG *bg, GdkPixbuf *dest, GdkScreen *screen) { - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_rectangle_int_t rect; - #else - GdkRectangle rect; - #endif + GdkRectangle rect; gint num_monitors; int monitor; @@ -962,39 +940,41 @@ mate_bg_get_pixmap_size (MateBG *bg, } /** - * mate_bg_get_pixmap: + * mate_bg_create_surface: * @bg: MateBG * @window: * @width: * @height: + * @is_root: * - * Create a pixmap that can be set as background for @window. If @root is TRUE, - * the pixmap created will be created by a temporary X server connection so - * that if someone calls XKillClient on it, it won't affect the application who - * created it. - * - * Since: 2.20 + * Create a surface that can be set as background for @window. If @is_root is + * TRUE, the surface created will be created by a temporary X server connection + * so that if someone calls XKillClient on it, it won't affect the application + * who created it. **/ -#if GTK_CHECK_VERSION(3, 0, 0) - cairo_surface_t* mate_bg_create_pixmap(MateBG* bg, GdkWindow* window, int width, int height, gboolean is_root) +#if GTK_CHECK_VERSION (3, 0, 0) +cairo_surface_t * +mate_bg_create_surface (MateBG *bg, #else - GdkPixmap* mate_bg_create_pixmap(MateBG* bg, GdkWindow* window, int width, int height, gboolean is_root) +GdkPixmap * +mate_bg_create_pixmap (MateBG *bg, #endif + GdkWindow *window, + int width, + int height, + gboolean is_root) { int pm_width, pm_height; - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_surface_t* pixmap; - #else - GdkPixmap* pixmap; - #endif + cairo_surface_t *surface; cairo_t *cr; g_return_val_if_fail (bg != NULL, NULL); g_return_val_if_fail (window != NULL, NULL); if (bg->last_pixmap_width != width || - bg->last_pixmap_height != height) { + bg->last_pixmap_height != height) + { if (bg->pixbuf_cache) { g_object_unref (bg->pixbuf_cache); bg->pixbuf_cache = NULL; @@ -1006,34 +986,33 @@ mate_bg_get_pixmap_size (MateBG *bg, /* has the side effect of loading and caching pixbuf only when in tile mode */ mate_bg_get_pixmap_size (bg, width, height, &pm_width, &pm_height); - if (is_root) { - - #if GTK_CHECK_VERSION(2, 24, 0) - pixmap = make_root_pixmap(gdk_window_get_screen(window), pm_width, pm_height); - #else // since 2.2 - pixmap = make_root_pixmap(gdk_drawable_get_screen(GDK_DRAWABLE(window)), pm_width, pm_height); - #endif - + if (is_root) + { + surface = make_root_pixmap (gdk_window_get_screen(window), + pm_width, pm_height); } - else { - pixmap = gdk_pixmap_new (window, pm_width, pm_height, -1); + else + { +#if GTK_CHECK_VERSION (3, 0, 0) + surface = gdk_window_create_similar_surface (window, + CAIRO_CONTENT_COLOR, + pm_width, pm_height); +#else + surface = gdk_pixmap_new (window, pm_width, pm_height, -1); +#endif } - cr = gdk_cairo_create (pixmap); + cr = cairo_create (surface); if (!bg->filename && bg->color_type == MATE_BG_COLOR_SOLID) { gdk_cairo_set_source_color (cr, &(bg->primary)); } - else { + else + { GdkPixbuf *pixbuf; - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); - - #if GTK_CHECK_VERSION(2, 24, 0) - mate_bg_draw(bg, pixbuf, gdk_window_get_screen(window), is_root); - #else // since 2.2 - mate_bg_draw(bg, pixbuf, gdk_drawable_get_screen(GDK_DRAWABLE(window)), is_root); - #endif - + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, + width, height); + mate_bg_draw (bg, pixbuf, gdk_window_get_screen (window), is_root); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); g_object_unref (pixbuf); } @@ -1042,7 +1021,7 @@ mate_bg_get_pixmap_size (MateBG *bg, cairo_destroy (cr); - return pixmap; + return surface; } @@ -1092,23 +1071,17 @@ mate_bg_is_dark (MateBG *bg, * Create a persistent pixmap. We create a separate display * and set the closedown mode on it to RetainPermanent. */ - -#if GTK_CHECK_VERSION(3, 0, 0) - static cairo_surface_t* make_root_pixmap(GdkScreen* screen, gint width, gint height) +#if GTK_CHECK_VERSION (3, 0, 0) +static cairo_surface_t * #else - static GdkPixmap* make_root_pixmap(GdkScreen* screen, gint width, gint height) +static GdkPixmap * #endif +make_root_pixmap (GdkScreen *screen, gint width, gint height) { - Display* display; - const char* display_name; + Display *display; + const char *display_name; Pixmap result; - - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_surface_t* gdk_pixmap; - #else - GdkPixmap* gdk_pixmap; - #endif - + cairo_surface_t *surface; int screen_num; int depth; @@ -1141,14 +1114,21 @@ mate_bg_is_dark (MateBG *bg, XCloseDisplay (display); - gdk_pixmap = gdk_pixmap_foreign_new_for_screen (screen, result, +#if GTK_CHECK_VERSION (3, 0, 0) + surface = cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (screen), + result, + GDK_VISUAL_XVISUAL (gdk_screen_get_system_visual (screen)), + width, height); +#else + surface = gdk_pixmap_foreign_new_for_screen (screen, result, width, height, depth); gdk_drawable_set_colormap ( - GDK_DRAWABLE (gdk_pixmap), + GDK_DRAWABLE (surface), gdk_drawable_get_colormap (gdk_screen_get_root_window (screen))); +#endif - return gdk_pixmap; + return surface; } static gboolean @@ -1256,21 +1236,23 @@ mate_bg_create_thumbnail (MateBG *bg, } /** - * mate_bg_get_pixmap_from_root: + * mate_bg_get_surface_from_root: * @screen: a #GdkScreen * * This function queries the _XROOTPMAP_ID property from * the root window associated with @screen to determine - * the current root window background pixmap and returns + * the current root window background surface and returns * a copy of it. If the _XROOTPMAP_ID is not set, then - * a black pixmap is returned. + * a black surface is returned. * - * Return value: a #GdkPixmap if successful or %NULL + * Return value: a #cairo_surface_t if successful or %NULL **/ -#if GTK_CHECK_VERSION(3, 0, 0) - cairo_surface_t* mate_bg_get_pixmap_from_root(GdkScreen* screen) +#if GTK_CHECK_VERSION (3, 0, 0) +cairo_surface_t * +mate_bg_get_surface_from_root (GdkScreen *screen) #else - GdkPixmap* mate_bg_get_pixmap_from_root(GdkScreen* screen) +GdkPixmap * +mate_bg_get_pixmap_from_root (GdkScreen *screen) #endif { int result; @@ -1281,17 +1263,10 @@ mate_bg_create_thumbnail (MateBG *bg, Atom type; Display *display; int screen_num; - - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_surface_t* pixmap; - cairo_surface_t* source_pixmap; - #else - GdkPixmap* pixmap; - GdkPixmap* source_pixmap; - #endif + cairo_surface_t *surface; + cairo_surface_t *source_pixmap; int width, height; cairo_t *cr; - cairo_pattern_t *pattern; display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen)); screen_num = gdk_screen_get_number (screen); @@ -1302,7 +1277,7 @@ mate_bg_create_thumbnail (MateBG *bg, 0L, 1L, False, XA_PIXMAP, &type, &format, &nitems, &bytes_after, &data); - pixmap = NULL; + surface = NULL; source_pixmap = NULL; if (result != Success || type != XA_PIXMAP || @@ -1313,6 +1288,26 @@ mate_bg_create_thumbnail (MateBG *bg, if (data != NULL) { gdk_error_trap_push (); + +#if GTK_CHECK_VERSION (3, 0, 0) + Pixmap xpixmap = *(Pixmap *) data; + Window root_return; + int x_ret, y_ret; + unsigned int w_ret, h_ret, bw_ret, depth_ret; + + if (XGetGeometry (GDK_SCREEN_XDISPLAY (screen), + xpixmap, + &root_return, + &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret)) + { + source_pixmap = cairo_xlib_surface_create (GDK_SCREEN_XDISPLAY (screen), + xpixmap, + GDK_VISUAL_XVISUAL (gdk_screen_get_system_visual (screen)), + w_ret, h_ret); + } + + gdk_error_trap_pop (); +#else source_pixmap = gdk_pixmap_foreign_new (*(Pixmap *) data); gdk_error_trap_pop (); @@ -1320,19 +1315,44 @@ mate_bg_create_thumbnail (MateBG *bg, gdk_drawable_set_colormap (source_pixmap, gdk_screen_get_default_colormap (screen)); } +#endif } width = gdk_screen_get_width (screen); height = gdk_screen_get_height (screen); - pixmap = gdk_pixmap_new (source_pixmap != NULL? source_pixmap : +#if GTK_CHECK_VERSION (3, 0, 0) + if (source_pixmap) { + surface = cairo_surface_create_similar (source_pixmap, + CAIRO_CONTENT_COLOR, + width, height); + + cr = cairo_create (surface); + cairo_set_source_surface (cr, source_pixmap, 0, 0); + cairo_paint (cr); + + if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { + cairo_surface_destroy (surface); + surface = NULL; + } + + cairo_destroy (cr); + } + + if (surface == NULL) { + surface = gdk_window_create_similar_surface (gdk_screen_get_root_window (screen), + CAIRO_CONTENT_COLOR, + width, height); + } +#else + surface = gdk_pixmap_new (source_pixmap != NULL? source_pixmap : gdk_screen_get_root_window (screen), width, height, -1); - cr = gdk_cairo_create (pixmap); + cr = gdk_cairo_create (surface); if (source_pixmap != NULL) { gdk_cairo_set_source_pixmap (cr, source_pixmap, 0, 0); - pattern = cairo_get_source (cr); + cairo_pattern_t *pattern = cairo_get_source (cr); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); } else { cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); @@ -1340,25 +1360,24 @@ mate_bg_create_thumbnail (MateBG *bg, cairo_paint (cr); if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) { - g_object_unref (pixmap); - pixmap = NULL; + g_object_unref (surface); + surface = NULL; } cairo_destroy (cr); +#endif if (source_pixmap != NULL) - g_object_unref (source_pixmap); + cairo_surface_destroy (source_pixmap); if (data != NULL) XFree (data); - return pixmap; + return surface; } -#if GTK_CHECK_VERSION(3, 0, 0) - static void mate_bg_set_root_pixmap_id(GdkScreen* screen, cairo_surface_t* pixmap) -#else - static void mate_bg_set_root_pixmap_id(GdkScreen* screen, GdkPixmap* pixmap) -#endif +static void +mate_bg_set_root_pixmap_id (GdkScreen *screen, + cairo_surface_t *surface) { int result; gint format; @@ -1395,7 +1414,11 @@ mate_bg_create_thumbnail (MateBG *bg, XFree (data_esetroot); } - pixmap_id = GDK_WINDOW_XWINDOW (pixmap); +#if GTK_CHECK_VERSION (3, 0, 0) + pixmap_id = cairo_xlib_surface_get_drawable (surface); +#else + pixmap_id = GDK_WINDOW_XWINDOW (surface); +#endif XChangeProperty (display, RootWindow (display, screen_num), gdk_x11_get_xatom_by_name ("ESETROOT_PMAP_ID"), @@ -1408,28 +1431,34 @@ mate_bg_create_thumbnail (MateBG *bg, } /** - * mate_bg_set_pixmap_as_root: + * mate_bg_set_surface_as_root: * @screen: the #GdkScreen to change root background on - * @pixmap: the #GdkPixmap to set root background from + * @surface: the #cairo_surface_t to set root background from. + * Must be an xlib surface backing a pixmap. * * Set the root pixmap, and properties pointing to it. We * do this atomically with a server grab to make sure that * we won't leak the pixmap if somebody else it setting * it at the same time. (This assumes that they follow the - * same conventions we do). @pixmap should come from a call - * to mate_bg_create_pixmap(). + * same conventions we do). @surface should come from a call + * to mate_bg_create_surface(). **/ -#if GTK_CHECK_VERSION(3, 0, 0) - void mate_bg_set_pixmap_as_root(GdkScreen* screen, cairo_surface_t* pixmap) +void +#if GTK_CHECK_VERSION (3, 0, 0) +mate_bg_set_surface_as_root (GdkScreen *screen, cairo_surface_t *surface) #else - void mate_bg_set_pixmap_as_root(GdkScreen* screen, GdkPixmap* pixmap) +mate_bg_set_pixmap_as_root (GdkScreen *screen, GdkPixmap *surface) #endif { Display *display; int screen_num; g_return_if_fail (screen != NULL); - g_return_if_fail (pixmap != NULL); +#if GTK_CHECK_VERSION (3, 0, 0) + g_return_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB); +#else + g_return_if_fail (surface != NULL); +#endif screen_num = gdk_screen_get_number (screen); @@ -1437,10 +1466,14 @@ mate_bg_create_thumbnail (MateBG *bg, gdk_x11_display_grab (gdk_screen_get_display (screen)); - mate_bg_set_root_pixmap_id (screen, pixmap); + mate_bg_set_root_pixmap_id (screen, surface); XSetWindowBackgroundPixmap (display, RootWindow (display, screen_num), - GDK_PIXMAP_XID (pixmap)); +#if GTK_CHECK_VERSION (3, 0, 0) + cairo_xlib_surface_get_drawable (surface)); +#else + GDK_PIXMAP_XID (surface)); +#endif XClearWindow (display, RootWindow (display, screen_num)); gdk_display_flush (gdk_screen_get_display (screen)); @@ -1448,39 +1481,36 @@ mate_bg_create_thumbnail (MateBG *bg, } /** - * mate_bg_set_pixmap_as_root_with_crossfade: + * mate_bg_set_surface_as_root_with_crossfade: * @screen: the #GdkScreen to change root background on - * @pixmap: the #GdkPixmap to set root background from + * @surface: the cairo xlib surface to set root background from * @context: a #GMainContext or %NULL * * Set the root pixmap, and properties pointing to it. - * This function differs from mate_bg_set_pixmap_as_root() + * This function differs from mate_bg_set_surface_as_root() * in that it adds a subtle crossfade animation from the * current root pixmap to the new one. - * same conventions we do). * * Return value: a #MateBGCrossfade object **/ -#if GTK_CHECK_VERSION(3, 0, 0) - MateBGCrossfade* mate_bg_set_pixmap_as_root_with_crossfade(GdkScreen* screen, cairo_surface_t* pixmap) +MateBGCrossfade * +#if GTK_CHECK_VERSION (3, 0, 0) +mate_bg_set_surface_as_root_with_crossfade (GdkScreen *screen, + cairo_surface_t *surface) #else - MateBGCrossfade* mate_bg_set_pixmap_as_root_with_crossfade(GdkScreen* screen, GdkPixmap* pixmap) +mate_bg_set_pixmap_as_root_with_crossfade (GdkScreen *screen, + GdkPixmap *surface) #endif { GdkDisplay *display; GdkWindow *root_window; - - #if GTK_CHECK_VERSION(3, 0, 0) - cairo_surface_t* old_pixmap; - #else - GdkPixmap* old_pixmap; - #endif + cairo_surface_t *old_surface; int width, height; MateBGCrossfade *fade; g_return_val_if_fail (screen != NULL, NULL); - g_return_val_if_fail (pixmap != NULL, NULL); + g_return_val_if_fail (surface != NULL, NULL); root_window = gdk_screen_get_root_window (screen); @@ -1491,11 +1521,19 @@ mate_bg_create_thumbnail (MateBG *bg, display = gdk_screen_get_display (screen); gdk_x11_display_grab (display); - old_pixmap = mate_bg_get_pixmap_from_root (screen); - mate_bg_set_root_pixmap_id (screen, pixmap); - mate_bg_crossfade_set_start_pixmap (fade, old_pixmap); - g_object_unref (old_pixmap); - mate_bg_crossfade_set_end_pixmap (fade, pixmap); +#if GTK_CHECK_VERSION (3, 0, 0) + old_surface = mate_bg_get_surface_from_root (screen); + mate_bg_set_root_pixmap_id (screen, surface); + mate_bg_crossfade_set_start_surface (fade, old_surface); + cairo_surface_destroy (old_surface); + mate_bg_crossfade_set_end_surface (fade, surface); +#else + old_surface = mate_bg_get_pixmap_from_root (screen); + mate_bg_set_root_pixmap_id (screen, surface); + mate_bg_crossfade_set_start_pixmap (fade, old_surface); + cairo_surface_destroy (old_surface); + mate_bg_crossfade_set_end_pixmap (fade, surface); +#endif gdk_display_flush (display); gdk_x11_display_ungrab (display); @@ -2363,11 +2401,12 @@ create_gradient (const GdkColor *primary, return result; } -#if GTK_CHECK_VERSION(3, 0, 0) - static void pixbuf_draw_gradient(GdkPixbuf* pixbuf, gboolean horizontal, GdkColor* primary, GdkColor* secondary, cairo_rectangle_int_t* rect) -#else - static void pixbuf_draw_gradient(GdkPixbuf* pixbuf, gboolean horizontal, GdkColor* primary, GdkColor* secondary, GdkRectangle* rect) -#endif +static void +pixbuf_draw_gradient (GdkPixbuf *pixbuf, + gboolean horizontal, + GdkColor *primary, + GdkColor *secondary, + GdkRectangle *rect) { int width; int height; |