summaryrefslogtreecommitdiff
path: root/eel/eel-background.c
diff options
context:
space:
mode:
authorJasmine Hassan <[email protected]>2012-11-26 19:16:22 +0200
committerJasmine Hassan <[email protected]>2012-12-03 21:15:16 +0200
commit4ca41b3e2371f706dd129bd8938a55cf2e421ad8 (patch)
tree9a39e87a9792c473e5e7fdd78b8a4bcda4d526bd /eel/eel-background.c
parent83a8343b64850c98e5e650ee464e12d71fb595b8 (diff)
downloadcaja-4ca41b3e2371f706dd129bd8938a55cf2e421ad8.tar.bz2
caja-4ca41b3e2371f706dd129bd8938a55cf2e421ad8.tar.xz
[eel-background] refactor to untangle directory & desktop bg-setting code
Diffstat (limited to 'eel/eel-background.c')
-rw-r--r--eel/eel-background.c1422
1 files changed, 668 insertions, 754 deletions
diff --git a/eel/eel-background.c b/eel/eel-background.c
index fefc55cc..2706e713 100644
--- a/eel/eel-background.c
+++ b/eel/eel-background.c
@@ -3,6 +3,7 @@
eel-background.c: Object for the background of a widget.
Copyright (C) 2000 Eazel, Inc.
+ Copyright (C) 2012 Jasmine Hassan <[email protected]>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -19,7 +20,8 @@
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301, USA.
- Author: Darin Adler <[email protected]>
+ Authors: Darin Adler <[email protected]>
+ Jasmine Hassan <[email protected]>
*/
#include <config.h>
@@ -42,7 +44,6 @@
#if !GTK_CHECK_VERSION(3, 0, 0)
#define cairo_surface_t GdkPixmap
-#define cairo_surface_reference g_object_ref
#define cairo_surface_destroy g_object_unref
#define cairo_xlib_surface_get_display GDK_PIXMAP_XDISPLAY
#define cairo_xlib_surface_get_drawable GDK_PIXMAP_XID
@@ -54,11 +55,6 @@
#define mate_bg_crossfade_set_end_surface mate_bg_crossfade_set_end_pixmap
#endif
-static void set_image_properties (EelBackground *background);
-
-static void init_fade (EelBackground *background, GtkWidget *widget);
-static void free_fade (EelBackground *background);
-
G_DEFINE_TYPE (EelBackground, eel_background, G_TYPE_OBJECT);
enum
@@ -73,17 +69,16 @@ static guint signals[LAST_SIGNAL];
struct EelBackgroundDetails
{
- char *color;
-
- MateBG *bg;
GtkWidget *widget;
+ MateBG *bg;
+ char *color;
/* Realized data: */
- cairo_surface_t *background_surface;
- gboolean background_surface_is_unset_root_surface;
+ cairo_surface_t *bg_surface;
+ gboolean unset_root_surface;
MateBGCrossfade *fade;
- int background_entire_width;
- int background_entire_height;
+ int bg_entire_width;
+ int bg_entire_height;
GdkColor default_color;
gboolean use_base;
@@ -103,804 +98,550 @@ struct EelBackgroundDetails
};
static void
-on_bg_changed (MateBG *bg, EelBackground *background)
-{
- init_fade (background, background->details->widget);
- g_signal_emit (G_OBJECT (background),
- signals[APPEARANCE_CHANGED], 0);
-}
-
-static void
-on_bg_transitioned (MateBG *bg, EelBackground *background)
-{
- free_fade (background);
- g_signal_emit (G_OBJECT (background),
- signals[APPEARANCE_CHANGED], 0);
-}
-
-static void
-eel_background_init (EelBackground *background)
-{
- background->details =
- G_TYPE_INSTANCE_GET_PRIVATE (background,
- EEL_TYPE_BACKGROUND,
- EelBackgroundDetails);
-
- background->details->default_color.red = 0xffff;
- background->details->default_color.green = 0xffff;
- background->details->default_color.blue = 0xffff;
- background->details->bg = mate_bg_new ();
- background->details->is_active = TRUE;
-
- g_signal_connect (background->details->bg, "changed",
- G_CALLBACK (on_bg_changed), background);
- g_signal_connect (background->details->bg, "transitioned",
- G_CALLBACK (on_bg_transitioned), background);
-
-}
-
-/* The safe way to clear an image from a background is:
- * eel_background_set_image_uri (NULL);
- * This fn is a private utility - it does NOT clear
- * the details->bg_uri setting.
- */
-static void
-eel_background_remove_current_image (EelBackground *background)
-{
- if (background->details->bg != NULL)
- {
- g_object_unref (G_OBJECT (background->details->bg));
- background->details->bg = NULL;
- }
-}
-
-static void
-free_fade (EelBackground *background)
+free_fade (EelBackground *self)
{
- if (background->details->fade != NULL)
+ if (self->details->fade != NULL)
{
- g_object_unref (background->details->fade);
- background->details->fade = NULL;
+ g_object_unref (self->details->fade);
+ self->details->fade = NULL;
}
}
static void
-free_background_surface (EelBackground *background)
+free_background_surface (EelBackground *self)
{
cairo_surface_t *surface;
- surface = background->details->background_surface;
+ surface = self->details->bg_surface;
if (surface != NULL)
{
/* If we created a root surface and didn't set it as background
it will live forever, so we need to kill it manually.
If set as root background it will be killed next time the
background is changed. */
- if (background->details->background_surface_is_unset_root_surface)
+ if (self->details->unset_root_surface)
{
XKillClient (cairo_xlib_surface_get_display (surface),
cairo_xlib_surface_get_drawable (surface));
}
cairo_surface_destroy (surface);
- background->details->background_surface = NULL;
- }
-}
-
-
-static EelBackgroundImagePlacement
-placement_mate_to_eel (MateBGPlacement p)
-{
- switch (p)
- {
- case MATE_BG_PLACEMENT_CENTERED:
- return EEL_BACKGROUND_CENTERED;
- case MATE_BG_PLACEMENT_FILL_SCREEN:
- return EEL_BACKGROUND_SCALED;
- case MATE_BG_PLACEMENT_SCALED:
- return EEL_BACKGROUND_SCALED_ASPECT;
- case MATE_BG_PLACEMENT_ZOOMED:
- return EEL_BACKGROUND_ZOOM;
- case MATE_BG_PLACEMENT_TILED:
- return EEL_BACKGROUND_TILED;
- case MATE_BG_PLACEMENT_SPANNED:
- return EEL_BACKGROUND_SPANNED;
- }
-
- return EEL_BACKGROUND_TILED;
-}
-
-static MateBGPlacement
-placement_eel_to_mate (EelBackgroundImagePlacement p)
-{
- switch (p)
- {
- case EEL_BACKGROUND_CENTERED:
- return MATE_BG_PLACEMENT_CENTERED;
- case EEL_BACKGROUND_SCALED:
- return MATE_BG_PLACEMENT_FILL_SCREEN;
- case EEL_BACKGROUND_SCALED_ASPECT:
- return MATE_BG_PLACEMENT_SCALED;
- case EEL_BACKGROUND_ZOOM:
- return MATE_BG_PLACEMENT_ZOOMED;
- case EEL_BACKGROUND_TILED:
- return MATE_BG_PLACEMENT_TILED;
- case EEL_BACKGROUND_SPANNED:
- return MATE_BG_PLACEMENT_SPANNED;
+ self->details->bg_surface = NULL;
}
-
- return MATE_BG_PLACEMENT_TILED;
-}
-
-EelBackgroundImagePlacement
-eel_background_get_image_placement (EelBackground *background)
-{
- g_return_val_if_fail (EEL_IS_BACKGROUND (background), EEL_BACKGROUND_TILED);
-
- return placement_mate_to_eel (mate_bg_get_placement (background->details->bg));
-}
-
-void
-eel_background_set_image_placement (EelBackground *background,
- EelBackgroundImagePlacement new_placement)
-{
- g_return_if_fail (EEL_IS_BACKGROUND (background));
-
- mate_bg_set_placement (background->details->bg,
- placement_eel_to_mate (new_placement));
}
-
static void
eel_background_finalize (GObject *object)
{
- EelBackground *background;
+ EelBackground *self = EEL_BACKGROUND (object);
- background = EEL_BACKGROUND (object);
+ g_free (self->details->color);
- g_free (background->details->color);
- eel_background_remove_current_image (background);
+ if (self->details->bg != NULL) {
+ g_object_unref (G_OBJECT (self->details->bg));
+ self->details->bg = NULL;
+ }
- free_background_surface (background);
+ free_background_surface (self);
- free_fade (background);
+ free_fade (self);
G_OBJECT_CLASS (eel_background_parent_class)->finalize (object);
}
static void
-eel_background_class_init (EelBackgroundClass *klass)
+eel_background_unrealize (EelBackground *self)
{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
-
- signals[APPEARANCE_CHANGED] =
- g_signal_new ("appearance_changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
- G_STRUCT_OFFSET (EelBackgroundClass,
- appearance_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
- signals[SETTINGS_CHANGED] =
- g_signal_new ("settings_changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
- G_STRUCT_OFFSET (EelBackgroundClass,
- settings_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE,
- 1, G_TYPE_INT);
- signals[RESET] =
- g_signal_new ("reset",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
- G_STRUCT_OFFSET (EelBackgroundClass,
- reset),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+ free_background_surface (self);
- object_class->finalize = eel_background_finalize;
-
- g_type_class_add_private (klass, sizeof (EelBackgroundDetails));
+ self->details->bg_entire_width = 0;
+ self->details->bg_entire_height = 0;
+ self->details->default_color.red = 0xffff;
+ self->details->default_color.green = 0xffff;
+ self->details->default_color.blue = 0xffff;
}
-EelBackground *
-eel_background_new (void)
-{
- return EEL_BACKGROUND (g_object_new (EEL_TYPE_BACKGROUND, NULL));
-}
+#define CLAMP_COLOR(v) (t = (v), CLAMP (t, 0, G_MAXUSHORT))
+#define SATURATE(v) ((1.0 - saturation) * intensity + saturation * (v))
static void
-eel_background_unrealize (EelBackground *background)
+make_color_inactive (EelBackground *self,
+ GdkColor *color)
{
- free_background_surface (background);
+ double intensity, saturation;
+ gushort t;
- background->details->background_entire_width = 0;
- background->details->background_entire_height = 0;
- background->details->default_color.red = 0xffff;
- background->details->default_color.green = 0xffff;
- background->details->default_color.blue = 0xffff;
-}
+ if (self->details->is_active) {
+ return;
+ }
-static void
-drawable_get_adjusted_size (EelBackground *background,
- GdkWindow *window,
- int *width,
- int *height)
-{
- *width = gdk_window_get_width(GDK_WINDOW(window));
- *height = gdk_window_get_height(GDK_WINDOW(window));
+ saturation = 0.7;
+ intensity = color->red * 0.30 + color->green * 0.59 + color->blue * 0.11;
+ color->red = SATURATE (color->red);
+ color->green = SATURATE (color->green);
+ color->blue = SATURATE (color->blue);
- if (background->details->is_desktop)
+ if (intensity > G_MAXUSHORT / 2)
{
- GdkScreen *screen;
- screen = gdk_window_get_screen (window);
- *width = gdk_screen_get_width (screen);
- *height = gdk_screen_get_height (screen);
+ color->red *= 0.9;
+ color->green *= 0.9;
+ color->blue *= 0.9;
+ }
+ else
+ {
+ color->red *= 1.25;
+ color->green *= 1.25;
+ color->blue *= 1.25;
}
+
+ color->red = CLAMP_COLOR (color->red);
+ color->green = CLAMP_COLOR (color->green);
+ color->blue = CLAMP_COLOR (color->blue);
}
-static gboolean
-eel_background_ensure_realized (EelBackground *background, GdkWindow *window)
+gchar *
+eel_bg_get_desktop_color (EelBackground *self)
{
- gpointer data;
- GtkWidget *widget;
- GtkStyle *style;
- gboolean changed;
- int entire_width;
- int entire_height;
+ MateBGColorType type;
+ GdkColor primary, secondary;
+ char *start_color, *end_color, *color_spec;
+ gboolean use_gradient = TRUE;
+ gboolean is_horizontal = FALSE;
- drawable_get_adjusted_size (background, window, &entire_width, &entire_height);
+ mate_bg_get_color (self->details->bg, &type, &primary, &secondary);
- /* Set the default color */
-
- /* Get the widget to which the window belongs and its style as well */
- gdk_window_get_user_data (window, &data);
- widget = GTK_WIDGET (data);
- if (widget != NULL)
+ if (type == MATE_BG_COLOR_V_GRADIENT)
{
- style = gtk_widget_get_style (widget);
- if (background->details->use_base)
- {
- background->details->default_color = style->base[GTK_STATE_NORMAL];
- }
- else
- {
- background->details->default_color = style->bg[GTK_STATE_NORMAL];
- }
-
+ is_horizontal = FALSE;
}
-
- /* If the window size is the same as last time, don't update */
- if (entire_width == background->details->background_entire_width &&
- entire_height == background->details->background_entire_height)
+ else if (type == MATE_BG_COLOR_H_GRADIENT)
{
- return FALSE;
+ is_horizontal = TRUE;
}
-
- free_background_surface (background);
-
- changed = FALSE;
-
- set_image_properties (background);
-
- background->details->background_surface = mate_bg_create_surface (background->details->bg,
- window,
- entire_width, entire_height,
- background->details->is_desktop);
- background->details->background_surface_is_unset_root_surface = background->details->is_desktop;
-
- /* We got the surface and everything, so we don't care about a change
- that is pending (unless things actually change after this time) */
- g_object_set_data (G_OBJECT (background->details->bg),
- "ignore-pending-change", GINT_TO_POINTER (TRUE));
- changed = TRUE;
-
-
- background->details->background_entire_width = entire_width;
- background->details->background_entire_height = entire_height;
-
- return changed;
-}
-
-#define CLAMP_COLOR(v) (t = (v), CLAMP (t, 0, G_MAXUSHORT))
-#define SATURATE(v) ((1.0 - saturation) * intensity + saturation * (v))
-
-static void
-make_color_inactive (EelBackground *background, GdkColor *color)
-{
- double intensity, saturation;
- gushort t;
-
- if (!background->details->is_active)
+ else /* implicit (type == MATE_BG_COLOR_SOLID) */
{
- saturation = 0.7;
- intensity = color->red * 0.30 + color->green * 0.59 + color->blue * 0.11;
- color->red = SATURATE (color->red);
- color->green = SATURATE (color->green);
- color->blue = SATURATE (color->blue);
-
- if (intensity > G_MAXUSHORT / 2)
- {
- color->red *= 0.9;
- color->green *= 0.9;
- color->blue *= 0.9;
- }
- else
- {
- color->red *= 1.25;
- color->green *= 1.25;
- color->blue *= 1.25;
- }
-
- color->red = CLAMP_COLOR (color->red);
- color->green = CLAMP_COLOR (color->green);
- color->blue = CLAMP_COLOR (color->blue);
+ use_gradient = FALSE;
}
-}
-
-void
-#if GTK_CHECK_VERSION (3, 0, 0)
-eel_background_draw (GtkWidget *widget,
- cairo_t *cr)
-#else
-eel_background_expose (GtkWidget *widget,
- GdkEventExpose *event)
-#endif
-{
- int window_width;
- int window_height;
- GdkWindow *widget_window;
-
- widget_window = gtk_widget_get_window (widget);
-
-#if !GTK_CHECK_VERSION (3, 0, 0)
- g_return_if_fail (event->window == widget_window);
-#endif
-
- EelBackground *background = eel_get_widget_background (widget);
-
- drawable_get_adjusted_size (background, widget_window, &window_width, &window_height);
-
- eel_background_ensure_realized (background, widget_window);
- make_color_inactive (background, &background->details->default_color);
-#if GTK_CHECK_VERSION(3,0,0)
- cairo_save (cr);
-#else
- cairo_t *cr = gdk_cairo_create (widget_window);
-#endif
+ start_color = eel_gdk_rgb_to_color_spec (eel_gdk_color_to_rgb (&primary));
- if (background->details->background_surface != NULL) {
- cairo_set_source_surface (cr, background->details->background_surface, 0, 0);
- cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
- } else {
- gdk_cairo_set_source_color (cr, &background->details->default_color);
+ if (use_gradient)
+ {
+ end_color = eel_gdk_rgb_to_color_spec (eel_gdk_color_to_rgb (&secondary));
+ color_spec = eel_gradient_new (start_color, end_color, is_horizontal);
+ g_free (end_color);
}
+ else
+ {
+ color_spec = g_strdup (start_color);
+ }
+ g_free (start_color);
-#if !GTK_CHECK_VERSION (3, 0, 0)
- gdk_cairo_rectangle (cr, &event->area);
- cairo_clip (cr);
-#endif
-
- cairo_rectangle (cr, 0, 0, window_width, window_height);
- cairo_fill (cr);
-
-#if GTK_CHECK_VERSION(3,0,0)
- cairo_restore (cr);
-#else
- cairo_destroy (cr);
-#endif
+ return color_spec;
}
static void
-set_image_properties (EelBackground *background)
+set_image_properties (EelBackground *self)
{
GdkColor c;
- if (!background->details->color)
+
+ if (self->details->is_desktop && !self->details->color)
+ self->details->color = eel_bg_get_desktop_color (self);
+
+ if (!self->details->color)
{
- c = background->details->default_color;
- make_color_inactive (background, &c);
- mate_bg_set_color (background->details->bg, MATE_BG_COLOR_SOLID,
- &c, NULL);
+ c = self->details->default_color;
+ make_color_inactive (self, &c);
+ mate_bg_set_color (self->details->bg, MATE_BG_COLOR_SOLID, &c, NULL);
}
- else if (!eel_gradient_is_gradient (background->details->color))
+ else if (!eel_gradient_is_gradient (self->details->color))
{
- eel_gdk_color_parse_with_white_default (background->details->color, &c);
- make_color_inactive (background, &c);
- mate_bg_set_color (background->details->bg, MATE_BG_COLOR_SOLID, &c, NULL);
+ eel_gdk_color_parse_with_white_default (self->details->color, &c);
+ make_color_inactive (self, &c);
+ mate_bg_set_color (self->details->bg, MATE_BG_COLOR_SOLID, &c, NULL);
}
else
{
- GdkColor c1;
- GdkColor c2;
+ GdkColor c1, c2;
char *spec;
- spec = eel_gradient_get_start_color_spec (background->details->color);
+ spec = eel_gradient_get_start_color_spec (self->details->color);
eel_gdk_color_parse_with_white_default (spec, &c1);
- make_color_inactive (background, &c1);
+ make_color_inactive (self, &c1);
g_free (spec);
- spec = eel_gradient_get_end_color_spec (background->details->color);
+ spec = eel_gradient_get_end_color_spec (self->details->color);
eel_gdk_color_parse_with_white_default (spec, &c2);
- make_color_inactive (background, &c2);
+ make_color_inactive (self, &c2);
g_free (spec);
- if (eel_gradient_is_horizontal (background->details->color))
- mate_bg_set_color (background->details->bg, MATE_BG_COLOR_H_GRADIENT, &c1, &c2);
- else
- mate_bg_set_color (background->details->bg, MATE_BG_COLOR_V_GRADIENT, &c1, &c2);
-
+ if (eel_gradient_is_horizontal (self->details->color)) {
+ mate_bg_set_color (self->details->bg, MATE_BG_COLOR_H_GRADIENT, &c1, &c2);
+ } else {
+ mate_bg_set_color (self->details->bg, MATE_BG_COLOR_V_GRADIENT, &c1, &c2);
+ }
}
}
-char *
-eel_background_get_color (EelBackground *background)
+gchar *
+eel_background_get_color (EelBackground *self)
{
- g_return_val_if_fail (EEL_IS_BACKGROUND (background), NULL);
+ g_return_val_if_fail (EEL_IS_BACKGROUND (self), NULL);
- return g_strdup (background->details->color);
+ return g_strdup (self->details->color);
}
-char *
-eel_background_get_image_uri (EelBackground *background)
+/* @color: color or gradient to set */
+void
+eel_background_set_color (EelBackground *self,
+ const gchar *color)
{
- const char *filename;
-
- g_return_val_if_fail (EEL_IS_BACKGROUND (background), NULL);
-
- filename = mate_bg_get_filename (background->details->bg);
- if (filename)
+ if (g_strcmp0 (self->details->color, color) != 0)
{
- return g_filename_to_uri (filename, NULL, NULL);
+ g_free (self->details->color);
+ self->details->color = g_strdup (color);
+
+ set_image_properties (self);
}
- return NULL;
}
/* Use style->base as the default color instead of bg */
void
-eel_background_set_use_base (EelBackground *background,
- gboolean use_base)
+eel_background_set_use_base (EelBackground *self,
+ gboolean use_base)
{
- background->details->use_base = use_base;
+ self->details->use_base = use_base;
}
-void
-eel_background_set_color (EelBackground *background,
- const char *color)
+static void
+drawable_get_adjusted_size (EelBackground *self,
+ int *width,
+ int *height)
{
- if (g_strcmp0 (background->details->color, color) != 0)
+ if (self->details->is_desktop)
{
- g_free (background->details->color);
- background->details->color = g_strdup (color);
-
- set_image_properties (background);
+ GdkScreen *screen = gtk_widget_get_screen (self->details->widget);
+ *width = gdk_screen_get_width (screen);
+ *height = gdk_screen_get_height (screen);
+ }
+ else
+ {
+ GdkWindow *window = gtk_widget_get_window (self->details->widget);
+ *width = gdk_window_get_width (window);
+ *height = gdk_window_get_height (window);
}
}
static gboolean
-eel_background_set_image_uri_helper (EelBackground *background,
- const char *image_uri,
- gboolean emit_signal)
+eel_background_ensure_realized (EelBackground *self)
{
- char *filename;
+ GtkStyle *style;
+ int width, height;
+ GdkWindow *window;
- if (image_uri != NULL)
- {
- filename = g_filename_from_uri (image_uri, NULL, NULL);
+ /* Set the default color */
+ style = gtk_widget_get_style (self->details->widget);
+ if (self->details->use_base) {
+ self->details->default_color = style->base[GTK_STATE_NORMAL];
+ } else {
+ self->details->default_color = style->bg[GTK_STATE_NORMAL];
}
- else
+
+ /* If the window size is the same as last time, don't update */
+ drawable_get_adjusted_size (self, &width, &height);
+ if (width == self->details->bg_entire_width &&
+ height == self->details->bg_entire_height)
{
- filename = NULL;
+ return FALSE;
}
- mate_bg_set_filename (background->details->bg, filename);
+ free_background_surface (self);
- if (emit_signal)
- {
- g_signal_emit (background, signals[SETTINGS_CHANGED], 0, GDK_ACTION_COPY);
- }
+ /* Calls mate_bg_set_color, which sets "ignore-pending-change" to false,
+ and queues emission of changed signal if it's still false */
+ set_image_properties (self);
- set_image_properties (background);
+ window = gtk_widget_get_window (self->details->widget);
+ self->details->bg_surface = mate_bg_create_surface (self->details->bg,
+ window, width, height,
+ self->details->is_desktop);
+ self->details->unset_root_surface = self->details->is_desktop;
- g_free (filename);
+ /* We got the surface and everything, so we don't care about a change
+ that is pending (unless things actually change after this time) */
+ g_object_set_data (G_OBJECT (self->details->bg),
+ "ignore-pending-change",
+ GINT_TO_POINTER (TRUE));
+
+ self->details->bg_entire_width = width;
+ self->details->bg_entire_height = height;
return TRUE;
}
void
-eel_background_set_image_uri (EelBackground *background, const char *image_uri)
+eel_background_draw (GtkWidget *widget,
+# if GTK_CHECK_VERSION (3, 0, 0)
+ cairo_t *cr)
{
+# else
+ GdkEventExpose *event)
+{
+# endif
+ int width, height;
+ GdkWindow *window = gtk_widget_get_window (widget);
+# if !GTK_CHECK_VERSION (3, 0, 0)
+ if (event->window != window)
+ return;
+# endif
- eel_background_set_image_uri_helper (background, image_uri, TRUE);
-}
+ EelBackground *self = eel_get_widget_background (widget);
-/* Use this fn to set both the image and color and avoid flash. The color isn't
- * changed till after the image is done loading, that way if an update occurs
- * before then, it will use the old color and image.
- */
-static void
-eel_background_set_image_uri_and_color (EelBackground *background, GdkDragAction action,
- const char *image_uri, const char *color)
-{
- eel_background_set_image_uri_helper (background, image_uri, FALSE);
- eel_background_set_color (background, color);
+ drawable_get_adjusted_size (self, &width, &height);
- /* We always emit, even if the color didn't change, because the image change
- * relies on us doing it here.
- */
+ eel_background_ensure_realized (self);
+ make_color_inactive (self, &self->details->default_color);
- g_signal_emit (background, signals[SETTINGS_CHANGED], 0, action);
-}
+# if GTK_CHECK_VERSION(3,0,0)
+ cairo_save (cr);
+# else
+ cairo_t *cr = gdk_cairo_create (window);
+# endif
-void
-eel_background_receive_dropped_background_image (EelBackground *background,
- GdkDragAction action,
- const char *image_uri)
-{
- /* Currently, we only support tiled images. So we set the placement.
- * We rely on eel_background_set_image_uri_and_color to emit
- * the SETTINGS_CHANGED & APPEARANCE_CHANGE signals.
- */
- eel_background_set_image_placement (background, EEL_BACKGROUND_TILED);
+ if (self->details->bg_surface != NULL) {
+ cairo_set_source_surface (cr, self->details->bg_surface, 0, 0);
+ cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
+ } else {
+ gdk_cairo_set_source_color (cr, &self->details->default_color);
+ }
- eel_background_set_image_uri_and_color (background, action, image_uri, NULL);
-}
+# if !GTK_CHECK_VERSION (3, 0, 0)
+ gdk_cairo_rectangle (cr, &event->area);
+ cairo_clip (cr);
+# endif
-/**
- * eel_background_is_set:
- *
- * Check whether the background's color or image has been set.
- */
-gboolean
-eel_background_is_set (EelBackground *background)
-{
- g_assert (EEL_IS_BACKGROUND (background));
+ cairo_rectangle (cr, 0, 0, width, height);
+ cairo_fill (cr);
- return background->details->color != NULL
- || mate_bg_get_filename (background->details->bg) != NULL;
+# if GTK_CHECK_VERSION(3,0,0)
+ cairo_restore (cr);
+# else
+ cairo_destroy (cr);
+# endif
}
-/**
- * eel_background_reset:
- *
- * Emit the reset signal to forget any color or image that has been
- * set previously.
- */
-void
-eel_background_reset (EelBackground *background)
+static void
+set_root_surface (EelBackground *self,
+ GdkWindow *window,
+ GdkScreen *screen)
{
- g_return_if_fail (EEL_IS_BACKGROUND (background));
+ eel_background_ensure_realized (self);
- g_signal_emit (background, signals[RESET], 0);
+ if (self->details->use_common_surface) {
+ self->details->unset_root_surface = FALSE;
+ } else {
+ int width, height;
+ drawable_get_adjusted_size (self, &width, &height);
+ self->details->bg_surface = mate_bg_create_surface (self->details->bg, window,
+ width, height, TRUE);
+ }
+
+ if (self->details->bg_surface != NULL)
+ mate_bg_set_surface_as_root (screen, self->details->bg_surface);
}
static void
-set_root_surface (EelBackground *background,
- GdkWindow *window)
+init_fade (EelBackground *self)
{
- GdkScreen *screen;
+ GtkWidget *widget = self->details->widget;
- eel_background_ensure_realized (background, window);
- screen = gdk_window_get_screen (window);
+ if (!self->details->is_desktop || widget == NULL || !gtk_widget_get_realized (widget)) {
+ return;
+ }
- if (background->details->use_common_surface)
+ if (self->details->fade == NULL)
{
- background->details->background_surface_is_unset_root_surface = FALSE;
+ int width, height;
+
+ /* If this was the result of a screen size change,
+ * we don't want to crossfade
+ */
+ drawable_get_adjusted_size (self, &width, &height);
+ if (width == self->details->bg_entire_width &&
+ height == self->details->bg_entire_height)
+ {
+ self->details->fade = mate_bg_crossfade_new (width, height);
+ g_signal_connect_swapped (self->details->fade,
+ "finished",
+ G_CALLBACK (free_fade),
+ self);
+ }
}
- else
+
+ if (self->details->fade != NULL && !mate_bg_crossfade_is_started (self->details->fade))
{
- background->details->background_surface =
- mate_bg_create_surface (background->details->bg, window,
- gdk_screen_get_width (screen), gdk_screen_get_height (screen), TRUE);
+ if (self->details->bg_surface == NULL)
+ {
+ cairo_surface_t *start_surface;
+ start_surface = mate_bg_get_surface_from_root (gtk_widget_get_screen (widget));
+ mate_bg_crossfade_set_start_surface (self->details->fade, start_surface);
+ cairo_surface_destroy (start_surface);
+ }
+ else
+ {
+ mate_bg_crossfade_set_start_surface (self->details->fade, self->details->bg_surface);
+ }
}
-
- mate_bg_set_surface_as_root (screen, background->details->background_surface);
}
static void
on_fade_finished (MateBGCrossfade *fade,
- GdkWindow *window,
- EelBackground *background)
+ GdkWindow *window,
+ gpointer user_data)
{
- set_root_surface (background, window);
+ EelBackground *self = EEL_BACKGROUND (user_data);
+
+ set_root_surface (self, window, gdk_window_get_screen (window));
}
static gboolean
-fade_to_surface (EelBackground *background,
+fade_to_surface (EelBackground *self,
GdkWindow *window,
cairo_surface_t *surface)
{
- if (background->details->fade == NULL)
- {
- return FALSE;
- }
-
- if (!mate_bg_crossfade_set_end_surface (background->details->fade,
- surface))
+ if (self->details->fade == NULL ||
+ !mate_bg_crossfade_set_end_surface (self->details->fade, surface))
{
return FALSE;
}
- if (!mate_bg_crossfade_is_started (background->details->fade))
+ if (!mate_bg_crossfade_is_started (self->details->fade))
{
- mate_bg_crossfade_start (background->details->fade, window);
- if (background->details->is_desktop)
+ mate_bg_crossfade_start (self->details->fade, window);
+ if (self->details->is_desktop)
{
- g_signal_connect (background->details->fade,
+ g_signal_connect (self->details->fade,
"finished",
- G_CALLBACK (on_fade_finished), background);
+ G_CALLBACK (on_fade_finished), self);
}
}
- return mate_bg_crossfade_is_started (background->details->fade);
+ return mate_bg_crossfade_is_started (self->details->fade);
}
-
static void
-eel_background_set_up_widget (EelBackground *background, GtkWidget *widget)
+eel_background_set_up_widget (EelBackground *self)
{
GdkWindow *window;
- GdkWindow *widget_window;
- gboolean in_fade;
+ GtkWidget *widget = self->details->widget;
+ gboolean in_fade = FALSE;
if (!gtk_widget_get_realized (widget))
- {
return;
- }
- widget_window = gtk_widget_get_window (widget);
+ eel_background_ensure_realized (self);
+ make_color_inactive (self, &self->details->default_color);
- eel_background_ensure_realized (background, widget_window);
- make_color_inactive (background, &background->details->default_color);
+ if (self->details->bg_surface == NULL)
+ return;
- if (EEL_IS_CANVAS (widget))
- {
+ if (EEL_IS_CANVAS (widget)) {
window = gtk_layout_get_bin_window (GTK_LAYOUT (widget));
- }
- else
- {
- window = widget_window;
+ } else {
+ window = gtk_widget_get_window (widget);
}
- if (background->details->fade != NULL)
- {
- in_fade = fade_to_surface (background, window,
- background->details->background_surface);
- }
- else
- {
- in_fade = FALSE;
- }
+ if (self->details->fade != NULL)
+ in_fade = fade_to_surface (self, window, self->details->bg_surface);
if (!in_fade)
{
-#if GTK_CHECK_VERSION (3, 0, 0)
+# if GTK_CHECK_VERSION (3, 0, 0)
cairo_pattern_t *pattern;
- pattern = cairo_pattern_create_for_surface (background->details->background_surface);
+ pattern = cairo_pattern_create_for_surface (self->details->bg_surface);
gdk_window_set_background_pattern (window, pattern);
cairo_pattern_destroy (pattern);
-#endif
- if (!background->details->is_desktop) {
- gdk_window_set_background (window, &background->details->default_color);
+# endif
+
+ if (self->details->is_desktop)
+ {
+# if !GTK_CHECK_VERSION (3, 0, 0)
+ gdk_window_set_back_pixmap (window, self->details->bg_surface, FALSE);
+# endif
+ set_root_surface (self, window, gtk_widget_get_screen (widget));
+ }
+ else
+ {
+ gdk_window_set_background (window, &self->details->default_color);
+# if !GTK_CHECK_VERSION (3, 0, 0)
+ gdk_window_set_back_pixmap (window, self->details->bg_surface, FALSE);
+# endif
}
-#if !GTK_CHECK_VERSION (3, 0, 0)
- gdk_window_set_back_pixmap (window, background->details->background_surface, FALSE);
-#endif
- }
- if (background->details->is_desktop && !in_fade)
- {
- set_root_surface (background, window);
+ gdk_window_invalidate_rect (window, NULL, TRUE);
}
}
static gboolean
-on_background_changed (EelBackground *background)
+background_changed_cb (EelBackground *self)
{
- if (background->details->change_idle_id == 0)
- {
+ if (self->details->change_idle_id == 0) {
return FALSE;
}
+ self->details->change_idle_id = 0;
- background->details->change_idle_id = 0;
-
- eel_background_unrealize (background);
- eel_background_set_up_widget (background, background->details->widget);
+ eel_background_unrealize (self);
+ eel_background_set_up_widget (self);
- gtk_widget_queue_draw (background->details->widget);
+ gtk_widget_queue_draw (self->details->widget);
return FALSE;
}
static void
-init_fade (EelBackground *background, GtkWidget *widget)
+widget_queue_background_change (GtkWidget *widget,
+ gpointer user_data)
{
- if (widget == NULL || !gtk_widget_get_realized (widget))
- return;
-
- if (!background->details->is_desktop)
- {
- return;
- }
+ EelBackground *self = EEL_BACKGROUND (user_data);
- if (background->details->fade == NULL)
+ if (self->details->change_idle_id != 0)
{
- GdkWindow *window;
- int old_width, old_height, width, height;
-
- /* If this was the result of a screen size change,
- * we don't want to crossfade
- */
- window = gtk_widget_get_window (widget);
- old_width = gdk_window_get_width(GDK_WINDOW(window));
- old_height = gdk_window_get_height(GDK_WINDOW(window));
- drawable_get_adjusted_size (background, window,
- &width, &height);
- if (old_width == width && old_height == height)
- {
- background->details->fade = mate_bg_crossfade_new (width, height);
- g_signal_connect_swapped (background->details->fade,
- "finished",
- G_CALLBACK (free_fade),
- background);
- }
+ g_source_remove (self->details->change_idle_id);
}
- if (background->details->fade != NULL && !mate_bg_crossfade_is_started (background->details->fade))
- {
- cairo_surface_t *start_surface;
-
- if (background->details->background_surface == NULL)
- {
- start_surface = mate_bg_get_surface_from_root (gtk_widget_get_screen (widget));
- }
- else
- {
- start_surface = cairo_surface_reference (background->details->background_surface);
- }
- mate_bg_crossfade_set_start_surface (background->details->fade,
- start_surface);
- cairo_surface_destroy (start_surface);
- }
+ self->details->change_idle_id =
+ g_idle_add ((GSourceFunc) background_changed_cb, self);
}
+/* Callback used when the style of a widget changes. We have to regenerate its
+ * EelBackgroundStyle so that it will match the chosen GTK+ theme.
+ */
static void
-eel_widget_queue_background_change (GtkWidget *widget)
+widget_style_set_cb (GtkWidget *widget,
+ GtkStyle *previous_style,
+ gpointer user_data)
{
- EelBackground *background;
-
- background = eel_get_widget_background (widget);
+ if (previous_style != NULL)
+ widget_queue_background_change (widget, user_data);
+}
- if (background->details->change_idle_id > 0)
- {
- return;
- }
+static void
+eel_background_changed (MateBG *bg,
+ gpointer user_data)
+{
+ EelBackground *self = EEL_BACKGROUND (user_data);
- background->details->change_idle_id = g_idle_add ((GSourceFunc) on_background_changed, background);
+ init_fade (self);
+ g_signal_emit (G_OBJECT (self), signals[APPEARANCE_CHANGED], 0);
}
-/* Callback used when the style of a widget changes. We have to regenerate its
- * EelBackgroundStyle so that it will match the chosen GTK+ theme.
- */
static void
-widget_style_set_cb (GtkWidget *widget, GtkStyle *previous_style, gpointer data)
+eel_background_transitioned (MateBG *bg, gpointer user_data)
{
- EelBackground *background;
-
- background = EEL_BACKGROUND (data);
+ EelBackground *self = EEL_BACKGROUND (user_data);
- if (previous_style != NULL)
- {
- eel_widget_queue_background_change (widget);
- }
+ free_fade (self);
+ g_signal_emit (G_OBJECT (self), signals[APPEARANCE_CHANGED], 0);
}
#define VERBOSE
@@ -908,26 +649,25 @@ widget_style_set_cb (GtkWidget *widget, GtkStyle *previous_style, gpointer data)
static void
screen_size_changed (GdkScreen *screen, EelBackground *background)
{
- GdkWindow *window;
int w, h;
- window = gdk_screen_get_root_window(screen);
-
/* Find the monitor where our desktop window is, then get its geometry */
-// GdkRectangle rect;
-// gint monitor;
-// monitor = gdk_screen_get_monitor_at_window (screen, window);
-// gdk_screen_get_monitor_geometry (screen, monitor, &rect);
-// g_message ("Resized GdkWindow = %dx%d\n", rect.width, rect.height);
-
- drawable_get_adjusted_size (background, window, &w, &h);
- if (w != background->details->background_entire_width ||
- h != background->details->background_entire_height)
+/*
+ GdkRectangle rect;
+ gint monitor;
+ GdkWindow *window = gdk_screen_get_root_window(screen);
+ monitor = gdk_screen_get_monitor_at_window (screen, window);
+ gdk_screen_get_monitor_geometry (screen, monitor, &rect);
+ g_message ("Resized GdkWindow = %dx%d\n", rect.width, rect.height);
+*/
+ drawable_get_adjusted_size (background, &w, &h);
+ if (w != background->details->bg_entire_width ||
+ h != background->details->bg_entire_height)
{
#ifdef VERBOSE
g_message ("size changed: %dx%d -> %dx%d. Emitting changed signal.\n",
- background->details->background_entire_width,
- background->details->background_entire_height,
+ background->details->bg_entire_width,
+ background->details->bg_entire_height,
w, h);
#endif
g_signal_emit (background, signals[APPEARANCE_CHANGED], 0);
@@ -935,114 +675,81 @@ screen_size_changed (GdkScreen *screen, EelBackground *background)
}
static void
-widget_realized_setup (GtkWidget *widget, gpointer data)
+widget_realized_setup (GtkWidget *widget,
+ EelBackground *self)
{
- EelBackground *background;
+ if (!self->details->is_desktop) {
+ return;
+ }
- background = EEL_BACKGROUND (data);
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+ GdkWindow *window = gdk_screen_get_root_window (screen);
- if (background->details->is_desktop)
+ if (self->details->screen_size_handler > 0)
{
- GdkWindow *root_window;
- GdkScreen *screen;
-
- screen = gtk_widget_get_screen (widget);
-
- if (background->details->screen_size_handler > 0)
- {
- g_signal_handler_disconnect (screen,
- background->details->screen_size_handler);
- }
-
- background->details->screen_size_handler =
- g_signal_connect (screen, "size_changed",
- G_CALLBACK (screen_size_changed), background);
- if (background->details->screen_monitors_handler > 0)
- {
- g_signal_handler_disconnect (screen,
- background->details->screen_monitors_handler);
- }
- background->details->screen_monitors_handler =
- g_signal_connect (screen, "monitors-changed",
- G_CALLBACK (screen_size_changed), background);
+ g_signal_handler_disconnect (screen, self->details->screen_size_handler);
+ }
+ self->details->screen_size_handler =
+ g_signal_connect (screen, "size_changed", G_CALLBACK (screen_size_changed), self);
- root_window = gdk_screen_get_root_window(screen);
+ if (self->details->screen_monitors_handler > 0)
+ {
+ g_signal_handler_disconnect (screen, self->details->screen_monitors_handler);
+ }
+ self->details->screen_monitors_handler =
+ g_signal_connect (screen, "monitors-changed", G_CALLBACK (screen_size_changed), self);
- if (gdk_window_get_visual(root_window) == gtk_widget_get_visual(widget))
- {
- background->details->use_common_surface = TRUE;
- }
- else
- {
- background->details->use_common_surface = FALSE;
- }
+ self->details->use_common_surface =
+ (gdk_window_get_visual (window) == gtk_widget_get_visual (widget)) ? TRUE : FALSE;
- init_fade (background, widget);
- }
+ init_fade (self);
}
static void
-widget_realize_cb (GtkWidget *widget, gpointer data)
+widget_realize_cb (GtkWidget *widget,
+ gpointer user_data)
{
- EelBackground *background;
+ EelBackground *self = EEL_BACKGROUND (user_data);
- background = EEL_BACKGROUND (data);
+ widget_realized_setup (widget, self);
- widget_realized_setup (widget, data);
-
- eel_background_set_up_widget (background, widget);
+ eel_background_set_up_widget (self);
}
static void
-widget_unrealize_cb (GtkWidget *widget, gpointer data)
+widget_unrealize_cb (GtkWidget *widget,
+ gpointer user_data)
{
- EelBackground *background;
-
- background = EEL_BACKGROUND (data);
+ EelBackground *self = EEL_BACKGROUND (user_data);
- if (background->details->screen_size_handler > 0)
- {
- g_signal_handler_disconnect (gtk_widget_get_screen (GTK_WIDGET (widget)),
- background->details->screen_size_handler);
- background->details->screen_size_handler = 0;
- }
- if (background->details->screen_monitors_handler > 0)
- {
+ if (self->details->screen_size_handler > 0) {
g_signal_handler_disconnect (gtk_widget_get_screen (GTK_WIDGET (widget)),
- background->details->screen_monitors_handler);
- background->details->screen_monitors_handler = 0;
+ self->details->screen_size_handler);
+ self->details->screen_size_handler = 0;
}
- background->details->use_common_surface = FALSE;
-}
-
-void
-eel_background_set_desktop (EelBackground *background, GtkWidget *widget, gboolean is_desktop)
-{
- background->details->is_desktop = is_desktop;
- if (gtk_widget_get_realized (widget) && background->details->is_desktop)
- {
- widget_realized_setup (widget, background);
+ if (self->details->screen_monitors_handler > 0) {
+ g_signal_handler_disconnect (gtk_widget_get_screen (GTK_WIDGET (widget)),
+ self->details->screen_monitors_handler);
+ self->details->screen_monitors_handler = 0;
}
-}
-
-gboolean
-eel_background_is_desktop (EelBackground *background)
-{
- return background->details->is_desktop;
+ self->details->use_common_surface = FALSE;
}
static void
-on_widget_destroyed (GtkWidget *widget, EelBackground *background)
+on_widget_destroyed (GtkWidget *widget,
+ gpointer user_data)
{
- if (background->details->change_idle_id != 0)
- {
- g_source_remove (background->details->change_idle_id);
- background->details->change_idle_id = 0;
+ EelBackground *self = EEL_BACKGROUND (user_data);
+
+ if (self->details->change_idle_id != 0) {
+ g_source_remove (self->details->change_idle_id);
+ self->details->change_idle_id = 0;
}
- background->details->widget = NULL;
+ free_fade (self);
+ self->details->widget = NULL;
}
/* Gets the background attached to a widget.
@@ -1052,8 +759,8 @@ on_widget_destroyed (GtkWidget *widget, EelBackground *background)
just call eel_background methods on the widget.
If the widget is a canvas, nothing more needs to be done. For
- normal widgets, you need to call eel_background_expose() from your
- expose handler to draw the background.
+ normal widgets, you need to call eel_background_draw() from your
+ draw/expose handler to draw the background.
Later, we might want a call to find out if we already have a background,
or a way to share the same background among multiple widgets; both would
@@ -1062,13 +769,11 @@ on_widget_destroyed (GtkWidget *widget, EelBackground *background)
EelBackground *
eel_get_widget_background (GtkWidget *widget)
{
- gpointer data;
- EelBackground *background;
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
/* Check for an existing background. */
- data = g_object_get_data (G_OBJECT (widget), "eel_background");
+ gpointer data = g_object_get_data (G_OBJECT (widget), "eel_background");
if (data != NULL)
{
g_assert (EEL_IS_BACKGROUND (data));
@@ -1076,56 +781,276 @@ eel_get_widget_background (GtkWidget *widget)
}
/* Store the background in the widget's data. */
- background = eel_background_new ();
+ EelBackground *self = eel_background_new ();
g_object_set_data_full (G_OBJECT (widget), "eel_background",
- background, g_object_unref);
- background->details->widget = widget;
- g_signal_connect_object (widget, "destroy", G_CALLBACK (on_widget_destroyed), background, 0);
-
- /* Arrange to get the signal whenever the background changes. */
- g_signal_connect_object (background, "appearance_changed",
- G_CALLBACK (eel_widget_queue_background_change), widget, G_CONNECT_SWAPPED);
- eel_widget_queue_background_change (widget);
+ self, g_object_unref);
+ self->details->widget = widget;
- g_signal_connect_object (widget, "style_set",
- G_CALLBACK (widget_style_set_cb),
- background,
- 0);
+ g_signal_connect_object (widget, "destroy",
+ G_CALLBACK (on_widget_destroyed), self, 0);
g_signal_connect_object (widget, "realize",
- G_CALLBACK (widget_realize_cb),
- background,
- 0);
+ G_CALLBACK (widget_realize_cb), self, 0);
g_signal_connect_object (widget, "unrealize",
- G_CALLBACK (widget_unrealize_cb),
- background,
- 0);
+ G_CALLBACK (widget_unrealize_cb), self, 0);
+
+ g_signal_connect_object (widget, "style_set",
+ G_CALLBACK (widget_style_set_cb), self, 0);
+
+ /* Arrange to get the signal whenever the background changes. */
+ g_signal_connect_object (self, "appearance_changed",
+ G_CALLBACK (widget_queue_background_change),
+ widget, G_CONNECT_SWAPPED);
+ widget_queue_background_change (widget, self);
- return background;
+ return self;
+}
+
+static void
+eel_background_class_init (EelBackgroundClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ signals[APPEARANCE_CHANGED] =
+ g_signal_new ("appearance_changed", G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (EelBackgroundClass, appearance_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ signals[SETTINGS_CHANGED] =
+ g_signal_new ("settings_changed", G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (EelBackgroundClass, settings_changed),
+ NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+ signals[RESET] =
+ g_signal_new ("reset", G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (EelBackgroundClass, reset),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ object_class->finalize = eel_background_finalize;
+
+ g_type_class_add_private (klass, sizeof (EelBackgroundDetails));
+}
+
+static void
+eel_background_init (EelBackground *self)
+{
+ self->details =
+ G_TYPE_INSTANCE_GET_PRIVATE (self,
+ EEL_TYPE_BACKGROUND,
+ EelBackgroundDetails);
+
+ self->details->bg = mate_bg_new ();
+ self->details->default_color.red = 0xffff;
+ self->details->default_color.green = 0xffff;
+ self->details->default_color.blue = 0xffff;
+ self->details->is_active = TRUE;
+
+ g_signal_connect (self->details->bg, "changed",
+ G_CALLBACK (eel_background_changed), self);
+ g_signal_connect (self->details->bg, "transitioned",
+ G_CALLBACK (eel_background_transitioned), self);
+
+}
+
+/**
+ * eel_background_is_set:
+ *
+ * Check whether the background's color or image has been set.
+ */
+gboolean
+eel_background_is_set (EelBackground *self)
+{
+ g_assert (EEL_IS_BACKGROUND (self));
+
+ return self->details->color != NULL ||
+ mate_bg_get_filename (self->details->bg) != NULL;
+}
+
+/**
+ * eel_background_reset:
+ *
+ * Emit the reset signal to forget any color or image that has been
+ * set previously.
+ */
+void
+eel_background_reset (EelBackground *self)
+{
+ g_return_if_fail (EEL_IS_BACKGROUND (self));
+
+ g_signal_emit (self, signals[RESET], 0);
+}
+
+void
+eel_background_set_desktop (EelBackground *self,
+ GtkWidget *widget,
+ gboolean is_desktop)
+{
+ self->details->is_desktop = is_desktop;
+
+ if (gtk_widget_get_realized (widget) && is_desktop)
+ {
+ widget_realized_setup (widget, self);
+ }
+}
+
+gboolean
+eel_background_is_desktop (EelBackground *self)
+{
+ return self->details->is_desktop;
+}
+
+void
+eel_background_set_active (EelBackground *self,
+ gboolean is_active)
+{
+ if (self->details->is_active != is_active)
+ {
+ self->details->is_active = is_active;
+ set_image_properties (self);
+ }
}
/* determine if a background is darker or lighter than average, to help clients know what
colors to draw on top with */
gboolean
-eel_background_is_dark (EelBackground *background)
+eel_background_is_dark (EelBackground *self)
{
- GdkScreen *screen;
GdkRectangle rect;
/* only check for the background on the 0th monitor */
- screen = gdk_screen_get_default ();
+ GdkScreen *screen = gdk_screen_get_default ();
gdk_screen_get_monitor_geometry (screen, 0, &rect);
- return mate_bg_is_dark (background->details->bg, rect.width, rect.height);
+ return mate_bg_is_dark (self->details->bg, rect.width, rect.height);
+}
+
+gchar *
+eel_background_get_image_uri (EelBackground *self)
+{
+ g_return_val_if_fail (EEL_IS_BACKGROUND (self), NULL);
+
+ const gchar *filename = mate_bg_get_filename (self->details->bg);
+
+ if (filename) {
+ return g_filename_to_uri (filename, NULL, NULL);
+ }
+ return NULL;
+}
+
+static void
+eel_bg_set_image_uri_helper (EelBackground *self,
+ const gchar *image_uri,
+ gboolean emit_signal)
+{
+ gchar *filename = g_strdup (""); /* GSettings expects a string, not NULL */
+
+ if (image_uri != NULL)
+ filename = g_filename_from_uri (image_uri, NULL, NULL);
+
+ mate_bg_set_filename (self->details->bg, filename);
+
+ if (emit_signal)
+ g_signal_emit (self, signals[SETTINGS_CHANGED], 0, GDK_ACTION_COPY);
+
+ set_image_properties (self);
+
+ g_free (filename);
+}
+
+/* Use this function to set an image only (no color).
+ * Also, to unset an image, use: eel_bg_set_image_uri (background, NULL)
+ */
+void
+eel_background_set_image_uri (EelBackground *self,
+ const gchar *image_uri)
+{
+ eel_bg_set_image_uri_helper (self, image_uri, TRUE);
+}
+
+/* Use this fn to set both the image and color and avoid flash. The color isn't
+ * changed till after the image is done loading, that way if an update occurs
+ * before then, it will use the old color and image.
+ */
+static void
+eel_bg_set_image_uri_and_color (EelBackground *self,
+ GdkDragAction action,
+ const gchar *image_uri,
+ const gchar *color)
+{
+ if (self->details->is_desktop &&
+ !mate_bg_get_draw_background (self->details->bg))
+ {
+ mate_bg_set_draw_background (self->details->bg, TRUE);
+ }
+
+ eel_bg_set_image_uri_helper (self, image_uri, FALSE);
+ eel_background_set_color (self, color);
+
+ /* We always emit, even if the color didn't change, because the image change
+ relies on us doing it here. */
+ g_signal_emit (self, signals[SETTINGS_CHANGED], 0, action);
+}
+
+void
+eel_bg_set_placement (EelBackground *self,
+ MateBGPlacement placement)
+{
+ if (self->details->bg)
+ mate_bg_set_placement (self->details->bg,
+ placement);
+}
+
+void
+eel_bg_save_to_gsettings (EelBackground *self,
+ GSettings *settings)
+{
+ if (self->details->bg)
+ mate_bg_save_to_gsettings (self->details->bg,
+ settings);
+}
+
+void
+eel_bg_load_from_gsettings (EelBackground *self,
+ GSettings *settings)
+{
+ if (self->details->bg)
+ mate_bg_load_from_gsettings (self->details->bg,
+ settings);
+}
+
+void
+eel_bg_load_from_system_gsettings (EelBackground *self,
+ GSettings *settings,
+ gboolean apply)
+{
+ if (self->details->bg)
+ mate_bg_load_from_system_gsettings (self->details->bg,
+ settings,
+ apply);
+}
+
+/* handle dropped images */
+void
+eel_background_set_dropped_image (EelBackground *self,
+ GdkDragAction action,
+ const gchar *image_uri)
+{
+ /* Currently, we only support tiled images. So we set the placement. */
+ mate_bg_set_placement (self->details->bg, MATE_BG_PLACEMENT_TILED);
+
+ eel_bg_set_image_uri_and_color (self, action, image_uri, NULL);
}
/* handle dropped colors */
void
-eel_background_receive_dropped_color (EelBackground *background,
- GtkWidget *widget,
- GdkDragAction action,
- int drop_location_x,
- int drop_location_y,
- const GtkSelectionData *selection_data)
+eel_background_set_dropped_color (EelBackground *self,
+ GtkWidget *widget,
+ GdkDragAction action,
+ int drop_location_x,
+ int drop_location_y,
+ const GtkSelectionData *selection_data)
{
guint16 *channels;
char *color_spec, *gradient_spec;
@@ -1133,7 +1058,7 @@ eel_background_receive_dropped_color (EelBackground *background,
int left_border, right_border, top_border, bottom_border;
GtkAllocation allocation;
- g_return_if_fail (EEL_IS_BACKGROUND (background));
+ g_return_if_fail (EEL_IS_BACKGROUND (self));
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_if_fail (selection_data != NULL);
@@ -1161,13 +1086,13 @@ eel_background_receive_dropped_color (EelBackground *background,
bottom_border = allocation.height - 32;
/* If a custom background color isn't set, get the GtkStyle's bg color. */
- if (!background->details->color)
+ if (!self->details->color)
{
gradient_spec = gdk_color_to_string (&gtk_widget_get_style (widget)->bg[GTK_STATE_NORMAL]);
}
else
{
- gradient_spec = g_strdup (background->details->color);
+ gradient_spec = g_strdup (self->details->color);
}
if (drop_location_x < left_border && drop_location_x <= right_border)
@@ -1194,48 +1119,37 @@ eel_background_receive_dropped_color (EelBackground *background,
g_free (color_spec);
g_free (gradient_spec);
- eel_background_set_image_uri_and_color (background, action, NULL, new_gradient_spec);
+ eel_bg_set_image_uri_and_color (self, action, NULL, new_gradient_spec);
g_free (new_gradient_spec);
}
-void
-eel_background_save_to_settings (EelBackground *background)
+EelBackground *
+eel_background_new (void)
{
- if (background->details->bg)
- mate_bg_save_to_preferences (background->details->bg);
+ return EEL_BACKGROUND (g_object_new (EEL_TYPE_BACKGROUND, NULL));
}
-void
-eel_background_set_active (EelBackground *background,
- gboolean is_active)
-{
- if (background->details->is_active != is_active)
- {
- background->details->is_active = is_active;
- set_image_properties (background);
- }
-}
-/* self check code */
+/*
+ * self check code
+ */
#if !defined (EEL_OMIT_SELF_CHECK)
void
eel_self_check_background (void)
{
- EelBackground *background;
-
- background = eel_background_new ();
+ EelBackground *self = eel_background_new ();
- eel_background_set_color (background, NULL);
- eel_background_set_color (background, "");
- eel_background_set_color (background, "red");
- eel_background_set_color (background, "red-blue");
- eel_background_set_color (background, "red-blue:h");
+ eel_background_set_color (self, NULL);
+ eel_background_set_color (self, "");
+ eel_background_set_color (self, "red");
+ eel_background_set_color (self, "red-blue");
+ eel_background_set_color (self, "red-blue:h");
- g_object_ref_sink (background);
- g_object_unref (background);
+ g_object_ref_sink (self);
+ g_object_unref (self);
}
#endif