summaryrefslogtreecommitdiff
path: root/libmate-desktop/mate-bg-crossfade.c
diff options
context:
space:
mode:
authorStefano Karapetsas <[email protected]>2012-11-15 08:26:24 -0800
committerStefano Karapetsas <[email protected]>2012-11-15 08:26:24 -0800
commit86a51f1ba55208272a50e17ac94f745907131758 (patch)
tree93d19d85feadd31f2027f09557447998ebd42bda /libmate-desktop/mate-bg-crossfade.c
parent30ec51cebbfaa251bff071e39ab777af012cb015 (diff)
parent39d84d1c8a3ff07d20126f7220b7a3bfec5e306a (diff)
downloadmate-desktop-86a51f1ba55208272a50e17ac94f745907131758.tar.bz2
mate-desktop-86a51f1ba55208272a50e17ac94f745907131758.tar.xz
Merge pull request #36 from jasmineaura/develop
Properly support GTK3, simplify GTK2 compat, and some fixes
Diffstat (limited to 'libmate-desktop/mate-bg-crossfade.c')
-rw-r--r--libmate-desktop/mate-bg-crossfade.c220
1 files changed, 122 insertions, 98 deletions
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;