diff options
author | Stefano Karapetsas <[email protected]> | 2012-11-15 08:26:24 -0800 |
---|---|---|
committer | Stefano Karapetsas <[email protected]> | 2012-11-15 08:26:24 -0800 |
commit | 86a51f1ba55208272a50e17ac94f745907131758 (patch) | |
tree | 93d19d85feadd31f2027f09557447998ebd42bda /libmate-desktop | |
parent | 30ec51cebbfaa251bff071e39ab777af012cb015 (diff) | |
parent | 39d84d1c8a3ff07d20126f7220b7a3bfec5e306a (diff) | |
download | mate-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')
-rw-r--r-- | libmate-desktop/Makefile.am | 18 | ||||
-rw-r--r-- | libmate-desktop/libmateui/Makefile.am | 12 | ||||
-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 | 412 | ||||
-rw-r--r-- | libmate-desktop/mate-rr-labeler.c | 151 | ||||
-rw-r--r-- | libmate-desktop/mate-rr.c | 8 |
8 files changed, 548 insertions, 320 deletions
diff --git a/libmate-desktop/Makefile.am b/libmate-desktop/Makefile.am index 322963e..878303d 100644 --- a/libmate-desktop/Makefile.am +++ b/libmate-desktop/Makefile.am @@ -1,14 +1,16 @@ SUBDIRS = libmate libmateui -INCLUDES = \ - -DMATELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale\"" \ - -DPNP_IDS=\""$(PNP_IDS)"\" \ - $(WARN_CFLAGS) \ - $(DISABLE_DEPRECATED) \ +lib_LTLIBRARIES = libmate-desktop-2.la + +AM_CPPFLAGS = \ + $(MATE_DESKTOP_CFLAGS) \ $(XLIB_CFLAGS) \ - $(MATE_DESKTOP_CFLAGS) + -DG_LOG_DOMAIN=\"MateDesktop\" \ + -DMATELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale\"" \ + -DPNP_IDS=\""$(PNP_IDS)"\" \ + $(DISABLE_DEPRECATED_CFLAGS) -lib_LTLIBRARIES = libmate-desktop-2.la +AM_CFLAGS = $(WARN_CFLAGS) noinst_PROGRAMS = test-ditem @@ -47,11 +49,11 @@ test_ditem_LDADD = \ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = mate-desktop-2.0.pc -pnpdata_DATA_dist = pnp.ids if USE_INTERNAL_PNP_IDS pnpdatadir = $(datadir)/libmate-desktop pnpdata_DATA = pnp.ids endif +pnpdata_DATA_dist = pnp.ids check: test -s $(top_srcdir)/libmate-desktop/pnp.ids diff --git a/libmate-desktop/libmateui/Makefile.am b/libmate-desktop/libmateui/Makefile.am index ca42525..413fee0 100644 --- a/libmate-desktop/libmateui/Makefile.am +++ b/libmate-desktop/libmateui/Makefile.am @@ -1,10 +1,10 @@ libmateui_desktopdir = $(includedir)/mate-desktop-2.0/libmateui -libmateui_desktop_HEADERS = \ - mate-bg.h \ - mate-bg-crossfade.h \ - mate-desktop-thumbnail.h \ - mate-rr.h \ - mate-rr-config.h \ +libmateui_desktop_HEADERS = \ + mate-bg.h \ + mate-bg-crossfade.h \ + mate-desktop-thumbnail.h \ + mate-rr.h \ + mate-rr-config.h \ mate-rr-labeler.h -include $(top_srcdir)/git.mk 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..a02eb95 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" @@ -97,9 +102,6 @@ struct _MateBG { GdkColor primary; GdkColor secondary; - gint last_pixmap_width; - gint last_pixmap_height; - GFileMonitor* file_monitor; guint changed_id; @@ -129,11 +131,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 +148,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 +618,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 +662,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 +676,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 +768,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 +810,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 +825,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 +848,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,78 +937,76 @@ 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) { - if (bg->pixbuf_cache) { - g_object_unref (bg->pixbuf_cache); - bg->pixbuf_cache = NULL; - } + if (bg->pixbuf_cache && + gdk_pixbuf_get_width (bg->pixbuf_cache) != width && + gdk_pixbuf_get_height (bg->pixbuf_cache) != height) + { + g_object_unref (bg->pixbuf_cache); + bg->pixbuf_cache = NULL; } - bg->last_pixmap_width = width; - bg->last_pixmap_height = height; /* 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 +1015,7 @@ mate_bg_get_pixmap_size (MateBG *bg, cairo_destroy (cr); - return pixmap; + return surface; } @@ -1092,23 +1065,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 +1108,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 +1230,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 +1257,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 +1271,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 +1282,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_ignored (); +#else source_pixmap = gdk_pixmap_foreign_new (*(Pixmap *) data); gdk_error_trap_pop (); @@ -1320,19 +1309,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 +1354,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; @@ -1389,13 +1402,21 @@ mate_bg_create_thumbnail (MateBG *bg, nitems == 1) { gdk_error_trap_push (); XKillClient (display, *(Pixmap *)data_esetroot); +#if GTK_CHECK_VERSION (3, 0, 0) + gdk_error_trap_pop_ignored (); +#else gdk_flush (); gdk_error_trap_pop (); +#endif } 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 +1429,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 +1464,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 +1479,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 +1519,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); @@ -1722,9 +1758,12 @@ get_as_pixbuf_for_size (MateBG *bg, /* If scalable choose maximum size */ format = gdk_pixbuf_get_file_info (filename, NULL, NULL); - if (format != NULL) - tmp = gdk_pixbuf_format_get_name (format); - if (format != NULL && + if (format != NULL) { + tmp = gdk_pixbuf_format_get_name (format); + } else { + tmp = NULL; + } + if (tmp != NULL && g_strcmp0 (tmp, "svg") == 0 && (best_width > 0 && best_height > 0) && (bg->placement == MATE_BG_PLACEMENT_FILL_SCREEN || @@ -2363,11 +2402,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; diff --git a/libmate-desktop/mate-rr-labeler.c b/libmate-desktop/mate-rr-labeler.c index 577a33a..c649f81 100644 --- a/libmate-desktop/mate-rr-labeler.c +++ b/libmate-desktop/mate-rr-labeler.c @@ -1,4 +1,6 @@ -/* mate-rr-labeler.c - Utility to label monitors to identify them +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * mate-rr-labeler.c - Utility to label monitors to identify them * while they are being configured. * * Copyright 2008, Novell, Inc. @@ -30,6 +32,12 @@ #include "libmateui/mate-rr-labeler.h" #include <gtk/gtk.h> +#include <X11/Xproto.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <gdk/gdkx.h> + struct _MateRRLabeler { GObject parent; @@ -39,6 +47,9 @@ struct _MateRRLabeler { GdkColor *palette; GtkWidget **windows; + + GdkScreen *screen; + Atom workarea_atom; }; struct _MateRRLabelerClass { @@ -48,11 +59,105 @@ struct _MateRRLabelerClass { G_DEFINE_TYPE (MateRRLabeler, mate_rr_labeler, G_TYPE_OBJECT); static void mate_rr_labeler_finalize (GObject *object); +static void create_label_windows (MateRRLabeler *labeler); + +static gboolean +get_work_area (MateRRLabeler *labeler, + GdkRectangle *rect) +{ + Atom workarea; + Atom type; + Window win; + int format; + gulong num; + gulong leftovers; + gulong max_len = 4 * 32; + guchar *ret_workarea; + long *workareas; + int result; + int disp_screen; + Display *display; + + display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (labeler->screen)); + workarea = XInternAtom (display, "_NET_WORKAREA", True); + + disp_screen = GDK_SCREEN_XNUMBER (labeler->screen); + + /* Defaults in case of error */ + rect->x = 0; + rect->y = 0; + rect->width = gdk_screen_get_width (labeler->screen); + rect->height = gdk_screen_get_height (labeler->screen); + + if (workarea == None) + return FALSE; + + win = XRootWindow (display, disp_screen); + result = XGetWindowProperty (display, + win, + workarea, + 0, + max_len, + False, + AnyPropertyType, + &type, + &format, + &num, + &leftovers, + &ret_workarea); + + if (result != Success + || type == None + || format == 0 + || leftovers + || num % 4) { + return FALSE; + } + + workareas = (long *) ret_workarea; + rect->x = workareas[disp_screen * 4]; + rect->y = workareas[disp_screen * 4 + 1]; + rect->width = workareas[disp_screen * 4 + 2]; + rect->height = workareas[disp_screen * 4 + 3]; + + XFree (ret_workarea); + + return TRUE; +} + +static GdkFilterReturn +screen_xevent_filter (GdkXEvent *xevent, + GdkEvent *event, + MateRRLabeler *labeler) +{ + XEvent *xev; + + xev = (XEvent *) xevent; + + if (xev->type == PropertyNotify && + xev->xproperty.atom == labeler->workarea_atom) { + /* update label positions */ + mate_rr_labeler_hide (labeler); + create_label_windows (labeler); + } + + return GDK_FILTER_CONTINUE; +} static void mate_rr_labeler_init (MateRRLabeler *labeler) { - /* nothing */ + GdkWindow *gdkwindow; + + labeler->workarea_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), + "_NET_WORKAREA", + True); + + labeler->screen = gdk_screen_get_default (); + /* code is not really designed to handle multiple screens so *shrug* */ + gdkwindow = gdk_screen_get_root_window (labeler->screen); + gdk_window_add_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler); + gdk_window_set_events (gdkwindow, gdk_window_get_events (gdkwindow) | GDK_PROPERTY_CHANGE_MASK); } static void @@ -69,9 +174,13 @@ static void mate_rr_labeler_finalize (GObject *object) { MateRRLabeler *labeler; + GdkWindow *gdkwindow; labeler = MATE_RR_LABELER (object); + gdkwindow = gdk_screen_get_root_window (labeler->screen); + gdk_window_remove_filter (gdkwindow, (GdkFilterFunc) screen_xevent_filter, labeler); + /* We don't destroy the labeler->config (a MateRRConfig*) here; let our * caller do that instead. */ @@ -141,16 +250,21 @@ make_palette (MateRRLabeler *labeler) #define LABEL_WINDOW_PADDING 12 static gboolean +#if GTK_CHECK_VERSION (3, 0, 0) +label_window_draw_event_cb (GtkWidget *widget, cairo_t *cr, gpointer data) +#else label_window_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data) +#endif { - cairo_t *cr; GdkColor *color; GtkAllocation allocation; color = g_object_get_data (G_OBJECT (widget), "color"); gtk_widget_get_allocation (widget, &allocation); - cr = gdk_cairo_create (gtk_widget_get_window (widget)); +#if !GTK_CHECK_VERSION (3, 0, 0) + cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget)); +#endif /* edge outline */ @@ -173,11 +287,33 @@ label_window_expose_event_cb (GtkWidget *widget, GdkEventExpose *event, gpointer allocation.height - LABEL_WINDOW_EDGE_THICKNESS * 2); cairo_fill (cr); +#if !GTK_CHECK_VERSION (3, 0, 0) cairo_destroy (cr); +#endif return FALSE; } +static void +position_window (MateRRLabeler *labeler, + GtkWidget *window, + int x, + int y) +{ + GdkRectangle workarea; + GdkRectangle monitor; + int monitor_num; + + get_work_area (labeler, &workarea); + monitor_num = gdk_screen_get_monitor_at_point (labeler->screen, x, y); + gdk_screen_get_monitor_geometry (labeler->screen, + monitor_num, + &monitor); + gdk_rectangle_intersect (&monitor, &workarea, &workarea); + + gtk_window_move (GTK_WINDOW (window), workarea.x, workarea.y); +} + static GtkWidget * create_label_window (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *color) { @@ -198,8 +334,13 @@ create_label_window (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *c */ g_object_set_data (G_OBJECT (window), "color", color); +#if GTK_CHECK_VERSION (3, 0, 0) + g_signal_connect (window, "draw", + G_CALLBACK (label_window_draw_event_cb), labeler); +#else g_signal_connect (window, "expose-event", G_CALLBACK (label_window_expose_event_cb), labeler); +#endif if (labeler->config->clone) { /* Keep this string in sync with mate-control-center/capplets/display/xrandr-capplet.c:get_display_name() */ @@ -227,7 +368,7 @@ create_label_window (MateRRLabeler *labeler, MateOutputInfo *output, GdkColor *c gtk_container_add (GTK_CONTAINER (window), widget); /* Should we center this at the top edge of the monitor, instead of using the upper-left corner? */ - gtk_window_move (GTK_WINDOW (window), output->x, output->y); + position_window (labeler, window, output->x, output->y); gtk_widget_show_all (window); diff --git a/libmate-desktop/mate-rr.c b/libmate-desktop/mate-rr.c index 5c73ce9..22852d4 100644 --- a/libmate-desktop/mate-rr.c +++ b/libmate-desktop/mate-rr.c @@ -486,8 +486,12 @@ fill_out_screen_info (Display *xdisplay, if (info->screen->rr_major_version == 1 && info->screen->rr_minor_version >= 3) { gdk_error_trap_push (); info->primary = XRRGetOutputPrimary (xdisplay, xroot); + #if GTK_CHECK_VERSION (3, 0, 0) + gdk_error_trap_pop_ignored (); + #else gdk_flush (); gdk_error_trap_pop (); /* ignore error */ + #endif } #endif @@ -746,8 +750,12 @@ mate_rr_screen_set_size (MateRRScreen *screen, gdk_error_trap_push (); XRRSetScreenSize (screen->xdisplay, screen->xroot, width, height, mm_width, mm_height); + #if GTK_CHECK_VERSION (3, 0, 0) + gdk_error_trap_pop_ignored (); + #else gdk_flush (); gdk_error_trap_pop (); /* ignore error */ + #endif #endif } |