summaryrefslogtreecommitdiff
path: root/libmate-desktop
diff options
context:
space:
mode:
Diffstat (limited to 'libmate-desktop')
-rw-r--r--libmate-desktop/Makefile.am18
-rw-r--r--libmate-desktop/libmateui/Makefile.am12
-rw-r--r--libmate-desktop/libmateui/mate-bg-crossfade.h12
-rw-r--r--libmate-desktop/libmateui/mate-bg.h35
-rw-r--r--libmate-desktop/mate-bg-crossfade.c220
-rw-r--r--libmate-desktop/mate-bg.c412
-rw-r--r--libmate-desktop/mate-rr-labeler.c151
-rw-r--r--libmate-desktop/mate-rr.c8
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
}