|
|
ae4b759 |
--- gnome-desktop-2.19.90/configure.in.gnome-bg 2007-08-13 20:04:02.000000000 -0400
|
|
|
a599c27 |
+++ gnome-desktop-2.19.90/configure.in 2007-08-28 14:01:15.000000000 -0400
|
|
|
0c4bf27 |
@@ -51,10 +51,10 @@
|
|
|
ae4b759 |
AC_SUBST(GNOME_DISTRIBUTOR)
|
|
|
ae4b759 |
AC_SUBST(GNOME_DATE)
|
|
|
ae4b759 |
|
|
|
ae4b759 |
-GNOME_COMMON_INIT
|
|
|
ae4b759 |
-GNOME_DEBUG_CHECK
|
|
|
ae4b759 |
-GNOME_COMPILE_WARNINGS([maximum])
|
|
|
ae4b759 |
-GNOME_MAINTAINER_MODE_DEFINES
|
|
|
ae4b759 |
+#GNOME_COMMON_INIT
|
|
|
ae4b759 |
+#GNOME_DEBUG_CHECK
|
|
|
ae4b759 |
+#GNOME_COMPILE_WARNINGS([maximum])
|
|
|
ae4b759 |
+#GNOME_MAINTAINER_MODE_DEFINES
|
|
|
ae4b759 |
|
|
|
ae4b759 |
# As a special favour for vuntz, support --disable-deprecations
|
|
|
ae4b759 |
|
|
|
0c4bf27 |
--- /dev/null 2007-08-15 18:04:26.337218222 -0400
|
|
|
a599c27 |
+++ gnome-desktop-2.19.90/libgnome-desktop/gnome-bg.c 2007-08-29 16:17:12.000000000 -0400
|
|
|
a599c27 |
@@ -0,0 +1,1824 @@
|
|
|
ae4b759 |
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+gnomebg.c: Object for the desktop background.
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+Copyright (C) 2000 Eazel, Inc.
|
|
|
ae4b759 |
+Copyright (C) 2007 Red Hat, Inc.
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+This program is free software; you can redistribute it and/or
|
|
|
ae4b759 |
+modify it under the terms of the GNU Library General Public License as
|
|
|
ae4b759 |
+published by the Free Software Foundation; either version 2 of the
|
|
|
ae4b759 |
+License, or (at your option) any later version.
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+This program is distributed in the hope that it will be useful,
|
|
|
ae4b759 |
+but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ae4b759 |
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
ae4b759 |
+Library General Public License for more details.
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+You should have received a copy of the GNU Library General Public
|
|
|
ae4b759 |
+License along with this program; if not, write to the
|
|
|
ae4b759 |
+Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
ae4b759 |
+Boston, MA 02111-1307, USA.
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+Derived from eel-background.c and eel-gdk-pixbuf-extensions.c by
|
|
|
ae4b759 |
+Darin Adler <darin@eazel.com> and Ramiro Estrugo <ramiro@eazel.com>
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+Author: Soren Sandmann <sandmann@redhat.com>
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+*/
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+#include <string.h>
|
|
|
ae4b759 |
+#include <libgnomeui/gnome-bg.h>
|
|
|
ae4b759 |
+#include <gdk/gdkx.h>
|
|
|
ae4b759 |
+#include <libgnomevfs/gnome-vfs-ops.h>
|
|
|
ae4b759 |
+#include <libgnomeui/libgnomeui.h>
|
|
|
ae4b759 |
+#include <math.h>
|
|
|
ae4b759 |
+#include <X11/Xlib.h>
|
|
|
ae4b759 |
+#include <X11/Xatom.h>
|
|
|
ae4b759 |
+#include <gdk/gdkx.h>
|
|
|
ae4b759 |
+#include <libgnomevfs/gnome-vfs-utils.h>
|
|
|
ae4b759 |
+#include <stdarg.h>
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+typedef struct _SlideShow SlideShow;
|
|
|
ae4b759 |
+typedef struct _Slide Slide;
|
|
|
ae4b759 |
+
|
|
|
b979214 |
+struct _Slide
|
|
|
b979214 |
+{
|
|
|
b979214 |
+ double duration; /* in seconds */
|
|
|
b979214 |
+ gboolean fixed;
|
|
|
b979214 |
+
|
|
|
b979214 |
+ char *file1;
|
|
|
b979214 |
+ char *file2; /* NULL if fixed is TRUE */
|
|
|
b979214 |
+};
|
|
|
b979214 |
+
|
|
|
ae4b759 |
+/* This is the size of the GdkRGB dither matrix, in order to avoid
|
|
|
ae4b759 |
+ * bad dithering when tiling the gradient
|
|
|
ae4b759 |
+ */
|
|
|
ae4b759 |
+#define GRADIENT_PIXMAP_TILE_SIZE 128
|
|
|
ae4b759 |
+
|
|
|
a599c27 |
+typedef struct FileCacheEntry FileCacheEntry;
|
|
|
a599c27 |
+#define CACHE_SIZE 4
|
|
|
a599c27 |
+
|
|
|
ae4b759 |
+/*
|
|
|
ae4b759 |
+ * Implementation of the GnomeBG class
|
|
|
ae4b759 |
+ */
|
|
|
ae4b759 |
+struct _GnomeBG
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GObject parent_instance;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ char * uri;
|
|
|
ae4b759 |
+ GnomeBGPlacement placement;
|
|
|
ae4b759 |
+ GnomeBGColorType color_type;
|
|
|
ae4b759 |
+ GdkColor c1;
|
|
|
ae4b759 |
+ GdkColor c2;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ /* Cached information, only access through cache accessor functions */
|
|
|
ae4b759 |
+ SlideShow * slideshow;
|
|
|
ae4b759 |
+ time_t uri_mtime;
|
|
|
ae4b759 |
+ GdkPixbuf * pixbuf_cache;
|
|
|
ae4b759 |
+ int timeout_id;
|
|
|
a599c27 |
+
|
|
|
a599c27 |
+ GList * file_cache;
|
|
|
ae4b759 |
+};
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+struct _GnomeBGClass
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GObjectClass parent_class;
|
|
|
ae4b759 |
+};
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+enum {
|
|
|
ae4b759 |
+ CHANGED,
|
|
|
ae4b759 |
+ N_SIGNALS
|
|
|
ae4b759 |
+};
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static guint signals[N_SIGNALS] = { 0 };
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+G_DEFINE_TYPE (GnomeBG, gnome_bg, G_TYPE_OBJECT);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixmap *make_root_pixmap (GdkScreen *screen,
|
|
|
ae4b759 |
+ gint width,
|
|
|
ae4b759 |
+ gint height);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/* Pixbuf utils */
|
|
|
ae4b759 |
+static guint32 pixbuf_average_value (GdkPixbuf *pixbuf);
|
|
|
ae4b759 |
+static GdkPixbuf *pixbuf_scale_to_fit (GdkPixbuf *src,
|
|
|
ae4b759 |
+ int max_width,
|
|
|
ae4b759 |
+ int max_height);
|
|
|
ae4b759 |
+static GdkPixbuf *pixbuf_scale_to_min (GdkPixbuf *src,
|
|
|
ae4b759 |
+ int min_width,
|
|
|
ae4b759 |
+ int min_height);
|
|
|
ae4b759 |
+static void pixbuf_draw_gradient (GdkPixbuf *pixbuf,
|
|
|
ae4b759 |
+ gboolean horizontal,
|
|
|
ae4b759 |
+ GdkColor *c1,
|
|
|
ae4b759 |
+ GdkColor *c2);
|
|
|
ae4b759 |
+static void pixbuf_tile (GdkPixbuf *src,
|
|
|
ae4b759 |
+ GdkPixbuf *dest);
|
|
|
ae4b759 |
+static void pixbuf_blend (GdkPixbuf *src,
|
|
|
ae4b759 |
+ GdkPixbuf *dest,
|
|
|
ae4b759 |
+ int src_x,
|
|
|
ae4b759 |
+ int src_y,
|
|
|
ae4b759 |
+ int width,
|
|
|
ae4b759 |
+ int height,
|
|
|
ae4b759 |
+ int dest_x,
|
|
|
ae4b759 |
+ int dest_y,
|
|
|
ae4b759 |
+ double alpha);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/* Thumbnail utilities */
|
|
|
a599c27 |
+static GdkPixbuf *create_thumbnail_for_uri (GnomeThumbnailFactory *factory,
|
|
|
a599c27 |
+ const char *uri);
|
|
|
ae4b759 |
+static gboolean get_thumb_annotations (GdkPixbuf *thumb,
|
|
|
ae4b759 |
+ int *orig_width,
|
|
|
ae4b759 |
+ int *orig_height);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/* Cache */
|
|
|
ae4b759 |
+static GdkPixbuf *get_pixbuf (GnomeBG *bg);
|
|
|
ae4b759 |
+static void clear_cache (GnomeBG *bg);
|
|
|
ae4b759 |
+static gboolean is_different (GnomeBG *bg,
|
|
|
ae4b759 |
+ const char *uri);
|
|
|
ae4b759 |
+static time_t get_mtime (const char *uri);
|
|
|
ae4b759 |
+static GdkPixbuf *create_img_thumbnail (GnomeBG *bg,
|
|
|
ae4b759 |
+ GnomeThumbnailFactory *factory,
|
|
|
ae4b759 |
+ GdkScreen *screen,
|
|
|
ae4b759 |
+ int dest_width,
|
|
|
ae4b759 |
+ int dest_height);
|
|
|
b979214 |
+static SlideShow * get_as_slideshow (GnomeBG *bg,
|
|
|
b979214 |
+ const char *uri);
|
|
|
b979214 |
+static Slide * get_current_slide (SlideShow *show,
|
|
|
b979214 |
+ double *alpha);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+gnome_bg_init (GnomeBG *bg)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+gnome_bg_finalize (GObject *object)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GnomeBG *bg = GNOME_BG (object);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ clear_cache (bg);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ G_OBJECT_CLASS (gnome_bg_parent_class)->finalize (object);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+gnome_bg_class_init (GnomeBGClass *class)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ object_class->finalize = gnome_bg_finalize;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ signals[CHANGED] = g_signal_new ("changed",
|
|
|
ae4b759 |
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
|
ae4b759 |
+ G_SIGNAL_RUN_LAST,
|
|
|
ae4b759 |
+ 0,
|
|
|
ae4b759 |
+ NULL, NULL,
|
|
|
ae4b759 |
+ g_cclosure_marshal_VOID__VOID,
|
|
|
ae4b759 |
+ G_TYPE_NONE, 0);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+emit_changed (GnomeBG *bg)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ g_signal_emit (G_OBJECT (bg), signals[CHANGED], 0);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+GnomeBG *
|
|
|
ae4b759 |
+gnome_bg_new (void)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ return g_object_new (GNOME_TYPE_BG, NULL);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static gboolean
|
|
|
ae4b759 |
+colors_equal (const GdkColor *c1, const GdkColor *c2)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ return c1->red == c2->red &&
|
|
|
ae4b759 |
+ c1->green == c2->green &&
|
|
|
ae4b759 |
+ c1->blue == c2->blue;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+void
|
|
|
ae4b759 |
+gnome_bg_set_color (GnomeBG *bg,
|
|
|
ae4b759 |
+ GnomeBGColorType type,
|
|
|
ae4b759 |
+ GdkColor *c1,
|
|
|
ae4b759 |
+ GdkColor *c2)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ g_return_if_fail (bg != NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (bg->color_type != type ||
|
|
|
ae4b759 |
+ !colors_equal (&bg->c1, c1) ||
|
|
|
ae4b759 |
+ (c2 && !colors_equal (&bg->c2, c2))) {
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->color_type = type;
|
|
|
ae4b759 |
+ bg->c1 = *c1;
|
|
|
ae4b759 |
+ if (c2) {
|
|
|
ae4b759 |
+ bg->c2 = *c2;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ emit_changed (bg);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+void
|
|
|
ae4b759 |
+gnome_bg_set_placement (GnomeBG *bg,
|
|
|
ae4b759 |
+ GnomeBGPlacement placement)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ g_return_if_fail (bg != NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (bg->placement != placement) {
|
|
|
ae4b759 |
+ bg->placement = placement;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ emit_changed (bg);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+void
|
|
|
ae4b759 |
+gnome_bg_set_uri (GnomeBG *bg,
|
|
|
ae4b759 |
+ const char *uri)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ g_return_if_fail (bg != NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (is_different (bg, uri)) {
|
|
|
ae4b759 |
+ char *tmp = g_strdup (uri);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ /* FIXME: maybe check that it is local */
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_free (bg->uri);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->uri = tmp;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ clear_cache (bg);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ emit_changed (bg);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+draw_color (GnomeBG *bg, GdkPixbuf *dest)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ guint32 pixel;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ switch (bg->color_type)
|
|
|
ae4b759 |
+ {
|
|
|
ae4b759 |
+ case GNOME_BG_COLOR_SOLID:
|
|
|
ae4b759 |
+ pixel = ((bg->c1.red >> 8) << 24) |
|
|
|
ae4b759 |
+ ((bg->c1.green >> 8) << 16) |
|
|
|
ae4b759 |
+ ((bg->c1.blue >> 8) << 8) |
|
|
|
ae4b759 |
+ (0xff);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gdk_pixbuf_fill (dest, pixel);
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ case GNOME_BG_COLOR_H_GRADIENT:
|
|
|
ae4b759 |
+ pixbuf_draw_gradient (dest, TRUE, &(bg->c1), &(bg->c2));
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ case GNOME_BG_COLOR_V_GRADIENT:
|
|
|
ae4b759 |
+ pixbuf_draw_gradient (dest, FALSE, &(bg->c1), &(bg->c2));
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ default:
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
ae4b759 |
+get_scaled_pixbuf (GnomeBGPlacement placement,
|
|
|
ae4b759 |
+ GdkPixbuf *pixbuf,
|
|
|
ae4b759 |
+ int width, int height,
|
|
|
ae4b759 |
+ int *x, int *y, int *w, int *h)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GdkPixbuf *new;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+#if 0
|
|
|
ae4b759 |
+ g_print ("original_width: %d %d\n",
|
|
|
ae4b759 |
+ gdk_pixbuf_get_width (pixbuf),
|
|
|
ae4b759 |
+ gdk_pixbuf_get_height (pixbuf));
|
|
|
ae4b759 |
+#endif
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ switch (placement) {
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_ZOOMED:
|
|
|
ae4b759 |
+ new = pixbuf_scale_to_min (pixbuf, width, height);
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_CENTERED:
|
|
|
ae4b759 |
+ new = g_object_ref (pixbuf);
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_FILL_SCREEN:
|
|
|
ae4b759 |
+ new = gdk_pixbuf_scale_simple (pixbuf, width, height,
|
|
|
ae4b759 |
+ GDK_INTERP_BILINEAR);
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_SCALED:
|
|
|
ae4b759 |
+ new = pixbuf_scale_to_fit (pixbuf, width, height);
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_TILED:
|
|
|
ae4b759 |
+ default:
|
|
|
ae4b759 |
+ new = g_object_ref (pixbuf);
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ *w = gdk_pixbuf_get_width (new);
|
|
|
ae4b759 |
+ *h = gdk_pixbuf_get_height (new);
|
|
|
ae4b759 |
+ *x = (width - *w) / 2;
|
|
|
ae4b759 |
+ *y = (height - *h) / 2;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return new;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+draw_image (GnomeBGPlacement placement,
|
|
|
ae4b759 |
+ GdkPixbuf *pixbuf,
|
|
|
ae4b759 |
+ GdkPixbuf *dest)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ int dest_width = gdk_pixbuf_get_width (dest);
|
|
|
ae4b759 |
+ int dest_height = gdk_pixbuf_get_height (dest);
|
|
|
ae4b759 |
+ int x, y, w, h;
|
|
|
ae4b759 |
+ GdkPixbuf *scaled;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (!pixbuf)
|
|
|
ae4b759 |
+ return;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ scaled = get_scaled_pixbuf (
|
|
|
ae4b759 |
+ placement, pixbuf, dest_width, dest_height, &x, &y, &w, &h);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ switch (placement) {
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_TILED:
|
|
|
ae4b759 |
+ pixbuf_tile (scaled, dest);
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_ZOOMED:
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_CENTERED:
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_FILL_SCREEN:
|
|
|
ae4b759 |
+ case GNOME_BG_PLACEMENT_SCALED:
|
|
|
ae4b759 |
+ pixbuf_blend (scaled, dest, 0, 0, w, h, x, y, 1.0);
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+ default:
|
|
|
ae4b759 |
+ g_assert_not_reached ();
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_object_unref (scaled);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+void
|
|
|
ae4b759 |
+gnome_bg_draw (GnomeBG *bg, GdkPixbuf *dest)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ if (!bg)
|
|
|
ae4b759 |
+ return;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ draw_color (bg, dest);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ draw_image (bg->placement, get_pixbuf (bg), dest);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+gboolean
|
|
|
ae4b759 |
+gnome_bg_changes_with_size (GnomeBG *bg)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ g_return_val_if_fail (bg != NULL, FALSE);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (bg->color_type != GNOME_BG_COLOR_SOLID) {
|
|
|
ae4b759 |
+ if (!get_pixbuf (bg))
|
|
|
ae4b759 |
+ return TRUE;
|
|
|
ae4b759 |
+ if (gdk_pixbuf_get_has_alpha (get_pixbuf (bg)))
|
|
|
ae4b759 |
+ return TRUE;
|
|
|
ae4b759 |
+ if (bg->placement == GNOME_BG_PLACEMENT_CENTERED)
|
|
|
ae4b759 |
+ return TRUE;
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else if (bg->placement == GNOME_BG_PLACEMENT_TILED) {
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ return TRUE;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+gnome_bg_get_pixmap_size (GnomeBG *bg,
|
|
|
ae4b759 |
+ int width,
|
|
|
ae4b759 |
+ int height,
|
|
|
ae4b759 |
+ int *pixmap_width,
|
|
|
ae4b759 |
+ int *pixmap_height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ int dummy;
|
|
|
ae4b759 |
+ int pb_width, pb_height;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (!pixmap_width)
|
|
|
ae4b759 |
+ pixmap_width = &dummy;
|
|
|
ae4b759 |
+ if (!pixmap_height)
|
|
|
ae4b759 |
+ pixmap_height = &dummy;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ *pixmap_width = width;
|
|
|
ae4b759 |
+ *pixmap_height = height;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (!get_pixbuf (bg)) {
|
|
|
ae4b759 |
+ switch (bg->color_type) {
|
|
|
ae4b759 |
+ case GNOME_BG_COLOR_SOLID:
|
|
|
ae4b759 |
+ *pixmap_width = 1;
|
|
|
ae4b759 |
+ *pixmap_height = 1;
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ case GNOME_BG_COLOR_H_GRADIENT:
|
|
|
ae4b759 |
+ *pixmap_width = width;
|
|
|
ae4b759 |
+ *pixmap_height = GRADIENT_PIXMAP_TILE_SIZE;
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ case GNOME_BG_COLOR_V_GRADIENT:
|
|
|
ae4b759 |
+ *pixmap_width = GRADIENT_PIXMAP_TILE_SIZE;
|
|
|
ae4b759 |
+ *pixmap_height = height;
|
|
|
ae4b759 |
+ break;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ pb_width = gdk_pixbuf_get_width (get_pixbuf (bg));
|
|
|
ae4b759 |
+ pb_height = gdk_pixbuf_get_height (get_pixbuf (bg));
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (bg->placement == GNOME_BG_PLACEMENT_TILED) {
|
|
|
ae4b759 |
+ if (gdk_pixbuf_get_has_alpha (get_pixbuf (bg)) &&
|
|
|
ae4b759 |
+ bg->color_type != GNOME_BG_COLOR_SOLID) {
|
|
|
ae4b759 |
+ if (bg->color_type == GNOME_BG_COLOR_H_GRADIENT) {
|
|
|
ae4b759 |
+ /* FIXME: Should this be
|
|
|
ae4b759 |
+ * MAX (GRADIENT_TILE_SIZE, pb_height)?
|
|
|
ae4b759 |
+ */
|
|
|
ae4b759 |
+ *pixmap_height = pb_height;
|
|
|
ae4b759 |
+ *pixmap_width = width;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ /* FIXME: Should this be
|
|
|
ae4b759 |
+ * MAX (GRAIDENT_TILE_SIZE, pb_width? */
|
|
|
ae4b759 |
+ *pixmap_width = pb_width;
|
|
|
ae4b759 |
+ *pixmap_height = height;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ *pixmap_width = pb_width;
|
|
|
ae4b759 |
+ *pixmap_height = pb_height;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/**
|
|
|
ae4b759 |
+ * gnome_bg_get_pixmap:
|
|
|
ae4b759 |
+ * @bg: GnomeBG
|
|
|
ae4b759 |
+ * @window:
|
|
|
ae4b759 |
+ * @width:
|
|
|
ae4b759 |
+ * @height:
|
|
|
ae4b759 |
+ *
|
|
|
ae4b759 |
+ * Create a pixmap that can be set as background for @window. If @root is TRUE,
|
|
|
ae4b759 |
+ * the pixmap created will be created by a temporary X server connection so
|
|
|
ae4b759 |
+ * that if someone calls XKillClient on it, it won't affect the application who
|
|
|
ae4b759 |
+ * created it.
|
|
|
ae4b759 |
+ *
|
|
|
ae4b759 |
+ * Since: 2.20
|
|
|
ae4b759 |
+ **/
|
|
|
ae4b759 |
+GdkPixmap *
|
|
|
ae4b759 |
+gnome_bg_create_pixmap (GnomeBG *bg,
|
|
|
ae4b759 |
+ GdkWindow *window,
|
|
|
ae4b759 |
+ int width,
|
|
|
ae4b759 |
+ int height,
|
|
|
ae4b759 |
+ gboolean root)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ int pm_width, pm_height;
|
|
|
ae4b759 |
+ GdkPixmap *pixmap;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_return_val_if_fail (bg != NULL, NULL);
|
|
|
ae4b759 |
+ g_return_val_if_fail (window != NULL, NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gnome_bg_get_pixmap_size (bg, width, height, &pm_width, &pm_height);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (root) {
|
|
|
ae4b759 |
+ pixmap = make_root_pixmap (gdk_drawable_get_screen (window),
|
|
|
ae4b759 |
+ pm_width, pm_height);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ pixmap = gdk_pixmap_new (window, pm_width, pm_height, -1);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (!get_pixbuf (bg) && bg->color_type == GNOME_BG_COLOR_SOLID) {
|
|
|
ae4b759 |
+ GdkGC *gc = gdk_gc_new (pixmap);
|
|
|
ae4b759 |
+ gdk_gc_set_rgb_fg_color (gc, &(bg->c1));
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gdk_draw_point (pixmap, gc, 0, 0);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_object_unref (gc);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ GdkPixbuf *pixbuf;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
|
|
|
ae4b759 |
+ width, height);
|
|
|
ae4b759 |
+ gnome_bg_draw (bg, pixbuf);
|
|
|
ae4b759 |
+ gdk_draw_pixbuf (pixmap, NULL, pixbuf,
|
|
|
ae4b759 |
+ 0, 0,
|
|
|
ae4b759 |
+ 0, 0, width, height,
|
|
|
ae4b759 |
+ GDK_RGB_DITHER_MAX, 0, 0);
|
|
|
ae4b759 |
+ g_object_unref (pixbuf);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return pixmap;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/* determine if a background is darker or lighter than average, to help
|
|
|
ae4b759 |
+ * clients know what colors to draw on top with
|
|
|
ae4b759 |
+ */
|
|
|
ae4b759 |
+gboolean
|
|
|
ae4b759 |
+gnome_bg_is_dark (GnomeBG *bg)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GdkColor color;
|
|
|
ae4b759 |
+ int intensity;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_return_val_if_fail (bg != NULL, FALSE);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (bg->color_type == GNOME_BG_COLOR_SOLID) {
|
|
|
ae4b759 |
+ color = bg->c1;
|
|
|
ae4b759 |
+ } else {
|
|
|
ae4b759 |
+ color.red = (bg->c1.red + bg->c2.red) / 2;
|
|
|
ae4b759 |
+ color.green = (bg->c1.green + bg->c2.green) / 2;
|
|
|
ae4b759 |
+ color.blue = (bg->c1.blue + bg->c2.blue) / 2;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (get_pixbuf (bg)) {
|
|
|
ae4b759 |
+ guint32 argb = pixbuf_average_value (get_pixbuf (bg));
|
|
|
ae4b759 |
+ guchar a = (argb >> 24) & 0xff;
|
|
|
ae4b759 |
+ guchar r = (argb >> 16) & 0xff;
|
|
|
ae4b759 |
+ guchar g = (argb >> 8) & 0xff;
|
|
|
ae4b759 |
+ guchar b = (argb >> 0) & 0xff;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ color.red = (color.red * (0xFF - a) + r * 0x101 * a) / 0xFF;
|
|
|
ae4b759 |
+ color.green = (color.green * (0xFF - a) + g * 0x101 * a) / 0xFF;
|
|
|
ae4b759 |
+ color.blue = (color.blue * (0xFF - a) + b * 0x101 * a) / 0xFF;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ intensity = (color.red * 77 +
|
|
|
ae4b759 |
+ color.green * 150 +
|
|
|
ae4b759 |
+ color.blue * 28) >> 16;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return intensity < 160; /* biased slightly to be dark */
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+void
|
|
|
ae4b759 |
+gnome_bg_free (GnomeBG *bg)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ g_return_if_fail (bg != NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_object_unref (G_OBJECT (bg));
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/*
|
|
|
ae4b759 |
+ * Create a persistent pixmap. We create a separate display
|
|
|
ae4b759 |
+ * and set the closedown mode on it to RetainPermanent.
|
|
|
ae4b759 |
+ */
|
|
|
ae4b759 |
+static GdkPixmap *
|
|
|
ae4b759 |
+make_root_pixmap (GdkScreen *screen, gint width, gint height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ Display *display;
|
|
|
ae4b759 |
+ const char *display_name;
|
|
|
ae4b759 |
+ Pixmap result;
|
|
|
ae4b759 |
+ GdkPixmap *gdk_pixmap;
|
|
|
ae4b759 |
+ int screen_num;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ screen_num = gdk_screen_get_number (screen);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gdk_flush ();
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ display_name = gdk_display_get_name (gdk_screen_get_display (screen));
|
|
|
ae4b759 |
+ display = XOpenDisplay (display_name);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (display == NULL) {
|
|
|
ae4b759 |
+ g_warning ("Unable to open display '%s' when setting "
|
|
|
ae4b759 |
+ "background pixmap\n",
|
|
|
ae4b759 |
+ (display_name) ? display_name : "NULL");
|
|
|
ae4b759 |
+ return NULL;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ /* Desktop background pixmap should be created from
|
|
|
ae4b759 |
+ * dummy X client since most applications will try to
|
|
|
ae4b759 |
+ * kill it with XKillClient later when changing pixmap
|
|
|
ae4b759 |
+ */
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ XSetCloseDownMode (display, RetainPermanent);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ result = XCreatePixmap (display,
|
|
|
ae4b759 |
+ RootWindow (display, screen_num),
|
|
|
ae4b759 |
+ width, height,
|
|
|
ae4b759 |
+ DefaultDepth (display, screen_num));
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ XCloseDisplay (display);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gdk_pixmap = gdk_pixmap_foreign_new (result);
|
|
|
ae4b759 |
+ gdk_drawable_set_colormap (
|
|
|
ae4b759 |
+ GDK_DRAWABLE (gdk_pixmap),
|
|
|
ae4b759 |
+ gdk_drawable_get_colormap (gdk_screen_get_root_window (screen)));
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return gdk_pixmap;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static gboolean
|
|
|
ae4b759 |
+get_original_size (const char *uri,
|
|
|
ae4b759 |
+ int *orig_width,
|
|
|
ae4b759 |
+ int *orig_height)
|
|
|
ae4b759 |
+{
|
|
|
b979214 |
+ char *filename;
|
|
|
b979214 |
+ gboolean result;
|
|
|
b979214 |
+
|
|
|
b979214 |
+ if (g_str_has_prefix (uri, "file:"))
|
|
|
b979214 |
+ filename = gnome_vfs_get_local_path_from_uri (uri);
|
|
|
b979214 |
+ else
|
|
|
0c4bf27 |
+ filename = g_strdup (uri);
|
|
|
ae4b759 |
+
|
|
|
0c4bf27 |
+ if (gdk_pixbuf_get_file_info (filename, orig_width, orig_height))
|
|
|
0c4bf27 |
+ result = TRUE;
|
|
|
0c4bf27 |
+ else
|
|
|
0c4bf27 |
+ result = FALSE;
|
|
|
ae4b759 |
+
|
|
|
0c4bf27 |
+ g_free (filename);
|
|
|
b979214 |
+
|
|
|
b979214 |
+ return result;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+gboolean
|
|
|
ae4b759 |
+gnome_bg_get_image_size (GnomeBG *bg,
|
|
|
ae4b759 |
+ GnomeThumbnailFactory *factory,
|
|
|
ae4b759 |
+ int *width,
|
|
|
ae4b759 |
+ int *height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GdkPixbuf *thumb;
|
|
|
ae4b759 |
+ gboolean result = FALSE;
|
|
|
b979214 |
+ const gchar *uri;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_return_val_if_fail (bg != NULL, FALSE);
|
|
|
ae4b759 |
+ g_return_val_if_fail (factory != NULL, FALSE);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (!bg->uri)
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+
|
|
|
b979214 |
+ uri = bg->uri;
|
|
|
a599c27 |
+ thumb = create_thumbnail_for_uri (factory, uri);
|
|
|
ae4b759 |
+
|
|
|
b979214 |
+ if (!thumb) {
|
|
|
b979214 |
+ SlideShow *show = get_as_slideshow (bg, bg->uri);
|
|
|
b979214 |
+ if (show) {
|
|
|
b979214 |
+ double alpha;
|
|
|
b979214 |
+ Slide *slide = get_current_slide (show, &alpha);
|
|
|
b979214 |
+ uri = slide->file1;
|
|
|
a599c27 |
+ thumb = create_thumbnail_for_uri (factory, uri);
|
|
|
b979214 |
+ }
|
|
|
b979214 |
+ }
|
|
|
b979214 |
+
|
|
|
ae4b759 |
+ if (thumb) {
|
|
|
ae4b759 |
+ if (get_thumb_annotations (thumb, width, height))
|
|
|
ae4b759 |
+ result = TRUE;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_object_unref (thumb);
|
|
|
ae4b759 |
+ }
|
|
|
b979214 |
+
|
|
|
b979214 |
+ if (!result) {
|
|
|
b979214 |
+ if (get_original_size (uri, width, height))
|
|
|
b979214 |
+ result = TRUE;
|
|
|
b979214 |
+ }
|
|
|
b979214 |
+
|
|
|
ae4b759 |
+ return result;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static double
|
|
|
ae4b759 |
+fit_factor (int from_width, int from_height,
|
|
|
ae4b759 |
+ int to_width, int to_height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ return MIN (to_width / (double) from_width, to_height / (double) from_height);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+GdkPixbuf *
|
|
|
ae4b759 |
+gnome_bg_create_thumbnail (GnomeBG *bg,
|
|
|
ae4b759 |
+ GnomeThumbnailFactory *factory,
|
|
|
ae4b759 |
+ GdkScreen *screen,
|
|
|
ae4b759 |
+ int dest_width,
|
|
|
ae4b759 |
+ int dest_height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GdkPixbuf *result;
|
|
|
ae4b759 |
+ GdkPixbuf *thumb;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_return_val_if_fail (bg != NULL, NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, dest_width, dest_height);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ draw_color (bg, result);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ thumb = create_img_thumbnail (bg, factory, screen, dest_width, dest_height);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (thumb) {
|
|
|
ae4b759 |
+ draw_image (bg->placement, thumb, result);
|
|
|
ae4b759 |
+ g_object_unref (thumb);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return result;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/* Set the root pixmap, and properties pointing to it. We
|
|
|
ae4b759 |
+ * do this atomically with XGrabServer to make sure that
|
|
|
ae4b759 |
+ * we won't leak the pixmap if somebody else it setting
|
|
|
ae4b759 |
+ * it at the same time. (This assumes that they follow the
|
|
|
ae4b759 |
+ * same conventions we do)
|
|
|
ae4b759 |
+ */
|
|
|
ae4b759 |
+void
|
|
|
ae4b759 |
+gnome_bg_set_pixmap_as_root (GdkScreen *screen, GdkPixmap *pixmap)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ int result;
|
|
|
ae4b759 |
+ gint format;
|
|
|
ae4b759 |
+ gulong nitems;
|
|
|
ae4b759 |
+ gulong bytes_after;
|
|
|
ae4b759 |
+ guchar *data_esetroot;
|
|
|
ae4b759 |
+ Pixmap pixmap_id;
|
|
|
ae4b759 |
+ Atom type;
|
|
|
ae4b759 |
+ Display *display;
|
|
|
ae4b759 |
+ int screen_num;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_return_if_fail (screen != NULL);
|
|
|
ae4b759 |
+ g_return_if_fail (pixmap != NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ screen_num = gdk_screen_get_number (screen);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ data_esetroot = NULL;
|
|
|
ae4b759 |
+ display = GDK_DISPLAY_XDISPLAY (gdk_screen_get_display (screen));
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ XGrabServer (display);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ result = XGetWindowProperty (
|
|
|
ae4b759 |
+ display, RootWindow (display, screen_num),
|
|
|
ae4b759 |
+ gdk_x11_get_xatom_by_name ("ESETROOT_PMAP_ID"),
|
|
|
ae4b759 |
+ 0L, 1L, False, XA_PIXMAP,
|
|
|
ae4b759 |
+ &type, &format, &nitems, &bytes_after,
|
|
|
ae4b759 |
+ &data_esetroot);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (data_esetroot != NULL) {
|
|
|
ae4b759 |
+ if (result == Success && type == XA_PIXMAP &&
|
|
|
ae4b759 |
+ format == 32 &&
|
|
|
ae4b759 |
+ nitems == 1) {
|
|
|
ae4b759 |
+ gdk_error_trap_push ();
|
|
|
ae4b759 |
+ XKillClient (display, *(Pixmap *)data_esetroot);
|
|
|
ae4b759 |
+ gdk_flush ();
|
|
|
ae4b759 |
+ gdk_error_trap_pop ();
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ XFree (data_esetroot);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ pixmap_id = GDK_WINDOW_XWINDOW (pixmap);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ XChangeProperty (display, RootWindow (display, screen_num),
|
|
|
ae4b759 |
+ gdk_x11_get_xatom_by_name ("ESETROOT_PMAP_ID"),
|
|
|
ae4b759 |
+ XA_PIXMAP, 32, PropModeReplace,
|
|
|
ae4b759 |
+ (guchar *) &pixmap_id, 1);
|
|
|
ae4b759 |
+ XChangeProperty (display, RootWindow (display, screen_num),
|
|
|
ae4b759 |
+ gdk_x11_get_xatom_by_name ("_XROOTPMAP_ID"), XA_PIXMAP,
|
|
|
ae4b759 |
+ 32, PropModeReplace,
|
|
|
ae4b759 |
+ (guchar *) &pixmap_id, 1);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ XSetWindowBackgroundPixmap (display, RootWindow (display, screen_num),
|
|
|
ae4b759 |
+ pixmap_id);
|
|
|
ae4b759 |
+ XClearWindow (display, RootWindow (display, screen_num));
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ XUngrabServer (display);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ XFlush (display);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/* Implementation of the pixbuf cache */
|
|
|
ae4b759 |
+struct _SlideShow
|
|
|
ae4b759 |
+{
|
|
|
0c4bf27 |
+ double start_time;
|
|
|
ae4b759 |
+ double total_duration;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ GQueue *slides;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ /* used during parsing */
|
|
|
0c4bf27 |
+ struct tm start_tm;
|
|
|
ae4b759 |
+ GQueue *stack;
|
|
|
ae4b759 |
+};
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static SlideShow *read_slideshow_file (const char *filename,
|
|
|
ae4b759 |
+ GError **err);
|
|
|
ae4b759 |
+static void slideshow_free (SlideShow *show);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static double
|
|
|
ae4b759 |
+now (void)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GTimeVal tv;
|
|
|
ae4b759 |
+ time_t t;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_get_current_time (&tv;;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ time (&t);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return (double)tv.tv_sec + (tv.tv_usec / 1000000.0);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static Slide *
|
|
|
ae4b759 |
+get_current_slide (SlideShow *show,
|
|
|
ae4b759 |
+ double *alpha)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ double delta = fmod (now() - show->start_time, show->total_duration);
|
|
|
ae4b759 |
+ GList *list;
|
|
|
ae4b759 |
+ double elapsed;
|
|
|
ae4b759 |
+ int i;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ elapsed = 0;
|
|
|
ae4b759 |
+ i = 0;
|
|
|
ae4b759 |
+ for (list = show->slides->head; list != NULL; list = list->next) {
|
|
|
ae4b759 |
+ Slide *slide = list->data;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (elapsed + slide->duration > delta) {
|
|
|
ae4b759 |
+ *alpha = (delta - elapsed) / (double)slide->duration;
|
|
|
ae4b759 |
+ return slide;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ i++;
|
|
|
ae4b759 |
+ elapsed += slide->duration;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return NULL;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
ae4b759 |
+blend (GdkPixbuf *p1,
|
|
|
ae4b759 |
+ GdkPixbuf *p2,
|
|
|
ae4b759 |
+ double alpha)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GdkPixbuf *result = gdk_pixbuf_copy (p1);
|
|
|
b979214 |
+ GdkPixbuf *tmp;
|
|
|
b979214 |
+
|
|
|
b979214 |
+ if (gdk_pixbuf_get_width (p2) != gdk_pixbuf_get_width (p1) ||
|
|
|
b979214 |
+ gdk_pixbuf_get_height (p2) != gdk_pixbuf_get_height (p1))
|
|
|
b979214 |
+ tmp = gdk_pixbuf_scale_simple (p2,
|
|
|
b979214 |
+ gdk_pixbuf_get_width (p1),
|
|
|
b979214 |
+ gdk_pixbuf_get_height (p1),
|
|
|
b979214 |
+ GDK_INTERP_BILINEAR);
|
|
|
b979214 |
+ else
|
|
|
b979214 |
+ tmp = g_object_ref (p2);
|
|
|
b979214 |
+
|
|
|
b979214 |
+ pixbuf_blend (tmp, result, 0, 0, -1, -1, 0, 0, alpha);
|
|
|
b979214 |
+
|
|
|
b979214 |
+ g_object_unref (tmp);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return result;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+typedef enum {
|
|
|
ae4b759 |
+ PIXBUF,
|
|
|
ae4b759 |
+ SLIDESHOW,
|
|
|
ae4b759 |
+ THUMBNAIL
|
|
|
ae4b759 |
+} FileType;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+struct FileCacheEntry
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ FileType type;
|
|
|
ae4b759 |
+ char *uri;
|
|
|
ae4b759 |
+ union {
|
|
|
ae4b759 |
+ GdkPixbuf *pixbuf;
|
|
|
ae4b759 |
+ SlideShow *slideshow;
|
|
|
ae4b759 |
+ GdkPixbuf *thumbnail;
|
|
|
ae4b759 |
+ } u;
|
|
|
ae4b759 |
+};
|
|
|
ae4b759 |
+
|
|
|
a599c27 |
+static void
|
|
|
a599c27 |
+file_cache_entry_delete (FileCacheEntry *ent)
|
|
|
a599c27 |
+{
|
|
|
a599c27 |
+ g_free (ent->uri);
|
|
|
a599c27 |
+
|
|
|
a599c27 |
+ switch (ent->type) {
|
|
|
a599c27 |
+ case PIXBUF:
|
|
|
a599c27 |
+ g_object_unref (ent->u.pixbuf);
|
|
|
a599c27 |
+ break;
|
|
|
a599c27 |
+ case SLIDESHOW:
|
|
|
a599c27 |
+ slideshow_free (ent->u.slideshow);
|
|
|
a599c27 |
+ break;
|
|
|
a599c27 |
+ case THUMBNAIL:
|
|
|
a599c27 |
+ g_object_unref (ent->u.thumbnail);
|
|
|
a599c27 |
+ break;
|
|
|
a599c27 |
+ }
|
|
|
a599c27 |
+
|
|
|
a599c27 |
+ g_free (ent);
|
|
|
a599c27 |
+}
|
|
|
a599c27 |
+
|
|
|
ae4b759 |
+static const FileCacheEntry *
|
|
|
ae4b759 |
+file_cache_lookup (GnomeBG *bg, FileType type, const char *uri)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GList *list;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ for (list = bg->file_cache; list != NULL; list = list->next) {
|
|
|
ae4b759 |
+ FileCacheEntry *ent = list->data;
|
|
|
ae4b759 |
+
|
|
|
a599c27 |
+ if (ent && ent->type == type && strcmp (ent->uri, uri) == 0)
|
|
|
ae4b759 |
+ return ent;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return NULL;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+file_cache_add_pixbuf (GnomeBG *bg,
|
|
|
ae4b759 |
+ const char *uri,
|
|
|
ae4b759 |
+ GdkPixbuf *pixbuf)
|
|
|
ae4b759 |
+{
|
|
|
a599c27 |
+ FileCacheEntry *ent;
|
|
|
a599c27 |
+
|
|
|
ae4b759 |
+ g_assert (!file_cache_lookup (bg, PIXBUF, uri));
|
|
|
a599c27 |
+
|
|
|
a599c27 |
+ while (g_list_length (bg->file_cache) > CACHE_SIZE) {
|
|
|
a599c27 |
+ GList *last_link = g_list_last (bg->file_cache);
|
|
|
a599c27 |
+ FileCacheEntry *ent = last_link->data;
|
|
|
ae4b759 |
+
|
|
|
a599c27 |
+ file_cache_entry_delete (ent);
|
|
|
a599c27 |
+
|
|
|
a599c27 |
+ bg->file_cache = g_list_delete_link (bg->file_cache, last_link);
|
|
|
a599c27 |
+ }
|
|
|
a599c27 |
+
|
|
|
a599c27 |
+ ent = g_new0 (FileCacheEntry, 1);
|
|
|
a599c27 |
+
|
|
|
ae4b759 |
+ ent->type = PIXBUF;
|
|
|
ae4b759 |
+ ent->uri = g_strdup (uri);
|
|
|
ae4b759 |
+ ent->u.pixbuf = pixbuf;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->file_cache = g_list_prepend (bg->file_cache, ent);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+file_cache_add_thumbnail (GnomeBG *bg,
|
|
|
ae4b759 |
+ const char *uri,
|
|
|
ae4b759 |
+ GdkPixbuf *pixbuf)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ FileCacheEntry *ent = g_new0 (FileCacheEntry, 1);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_assert (!file_cache_lookup (bg, THUMBNAIL, uri));
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ ent->type = THUMBNAIL;
|
|
|
ae4b759 |
+ ent->uri = g_strdup (uri);
|
|
|
ae4b759 |
+ ent->u.thumbnail = pixbuf;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->file_cache = g_list_prepend (bg->file_cache, ent);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+file_cache_add_slide_show (GnomeBG *bg,
|
|
|
ae4b759 |
+ const char *uri,
|
|
|
ae4b759 |
+ SlideShow *show)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ FileCacheEntry *ent = g_new0 (FileCacheEntry, 1);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_assert (!file_cache_lookup (bg, SLIDESHOW, uri));
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ ent->type = SLIDESHOW;
|
|
|
ae4b759 |
+ ent->uri = g_strdup (uri);
|
|
|
ae4b759 |
+ ent->u.slideshow = show;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->file_cache = g_list_prepend (bg->file_cache, ent);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
ae4b759 |
+get_as_pixbuf (GnomeBG *bg, const char *uri)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ const FileCacheEntry *ent;
|
|
|
ae4b759 |
+ if ((ent = file_cache_lookup (bg, PIXBUF, uri))) {
|
|
|
ae4b759 |
+ return ent->u.pixbuf;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ GdkPixbuf *pixbuf = gnome_gdk_pixbuf_new_from_uri (uri);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (pixbuf)
|
|
|
ae4b759 |
+ file_cache_add_pixbuf (bg, uri, pixbuf);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return pixbuf;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static SlideShow *
|
|
|
ae4b759 |
+get_as_slideshow (GnomeBG *bg, const char *uri)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ const FileCacheEntry *ent;
|
|
|
ae4b759 |
+ if ((ent = file_cache_lookup (bg, SLIDESHOW, uri))) {
|
|
|
ae4b759 |
+ return ent->u.slideshow;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ SlideShow *show = read_slideshow_file (uri, NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (show)
|
|
|
ae4b759 |
+ file_cache_add_slide_show (bg, uri, show);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return show;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
ae4b759 |
+get_as_thumbnail (GnomeBG *bg, GnomeThumbnailFactory *factory, const char *uri)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ const FileCacheEntry *ent;
|
|
|
ae4b759 |
+ if ((ent = file_cache_lookup (bg, THUMBNAIL, uri))) {
|
|
|
ae4b759 |
+ return ent->u.thumbnail;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
a599c27 |
+ GdkPixbuf *thumb = create_thumbnail_for_uri (factory, uri);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (thumb)
|
|
|
ae4b759 |
+ file_cache_add_thumbnail (bg, uri, thumb);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return thumb;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static gboolean
|
|
|
ae4b759 |
+on_timeout (gpointer data)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GnomeBG *bg = data;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (bg->pixbuf_cache) {
|
|
|
ae4b759 |
+ g_object_unref (bg->pixbuf_cache);
|
|
|
ae4b759 |
+ bg->pixbuf_cache = NULL;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->timeout_id = 0;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ emit_changed (bg);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+ensure_timeout (GnomeBG *bg,
|
|
|
ae4b759 |
+ Slide *slide)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ if (!bg->timeout_id) {
|
|
|
ae4b759 |
+ double timeout;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (slide->fixed) {
|
|
|
ae4b759 |
+ timeout = slide->duration;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ /* Maybe the number of steps should be configurable? */
|
|
|
ae4b759 |
+ timeout = slide->duration / 255.0;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->timeout_id = g_timeout_add_full (
|
|
|
ae4b759 |
+ G_PRIORITY_LOW,
|
|
|
ae4b759 |
+ timeout * 1000, on_timeout, bg, NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static time_t
|
|
|
ae4b759 |
+get_mtime (const char *uri)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ time_t mtime;
|
|
|
ae4b759 |
+ GnomeVFSFileInfo *info;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ mtime = (time_t)-1;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (uri) {
|
|
|
ae4b759 |
+ GnomeVFSResult vfs_res;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ info = gnome_vfs_file_info_new ();
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ vfs_res = gnome_vfs_get_file_info (
|
|
|
ae4b759 |
+ uri, info, GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (vfs_res == GNOME_VFS_OK)
|
|
|
ae4b759 |
+ mtime = info->mtime;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gnome_vfs_file_info_unref (info);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return mtime;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
ae4b759 |
+scale_thumbnail (GnomeBGPlacement placement,
|
|
|
ae4b759 |
+ const char *uri,
|
|
|
ae4b759 |
+ GdkPixbuf *thumb,
|
|
|
ae4b759 |
+ GdkScreen *screen,
|
|
|
ae4b759 |
+ int dest_width,
|
|
|
ae4b759 |
+ int dest_height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ int o_width;
|
|
|
ae4b759 |
+ int o_height;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (placement != GNOME_BG_PLACEMENT_TILED &&
|
|
|
ae4b759 |
+ placement != GNOME_BG_PLACEMENT_CENTERED) {
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ /* In this case, the pixbuf will be scaled to fit the screen anyway,
|
|
|
ae4b759 |
+ * so just return the pixbuf here
|
|
|
ae4b759 |
+ */
|
|
|
ae4b759 |
+ return g_object_ref (thumb);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ /* FIXME: in case of tiled, we should probably scale the pixbuf to
|
|
|
ae4b759 |
+ * be maybe dest_width/4 pixels tall. While strictly speaking incorrect,
|
|
|
ae4b759 |
+ * it might give a better idea of what the background would actually look
|
|
|
ae4b759 |
+ * like.
|
|
|
ae4b759 |
+ */
|
|
|
ae4b759 |
+ if (get_thumb_annotations (thumb, &o_width, &o_height) ||
|
|
|
ae4b759 |
+ (uri && get_original_size (uri, &o_width, &o_height))) {
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ int scr_height = gdk_screen_get_height (screen);
|
|
|
ae4b759 |
+ int scr_width = gdk_screen_get_width (screen);
|
|
|
ae4b759 |
+ int thumb_width = gdk_pixbuf_get_width (thumb);
|
|
|
ae4b759 |
+ int thumb_height = gdk_pixbuf_get_height (thumb);
|
|
|
ae4b759 |
+ double screen_to_dest = fit_factor (scr_width, scr_height,
|
|
|
ae4b759 |
+ dest_width, dest_height);
|
|
|
ae4b759 |
+ double thumb_to_orig = fit_factor (thumb_width, thumb_height,
|
|
|
ae4b759 |
+ o_width, o_height);
|
|
|
ae4b759 |
+ double f = thumb_to_orig * screen_to_dest;
|
|
|
ae4b759 |
+ int new_width, new_height;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ new_width = floor (thumb_width * f + 0.5);
|
|
|
ae4b759 |
+ new_height = floor (thumb_height * f + 0.5);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ thumb = gdk_pixbuf_scale_simple (thumb, new_width, new_height,
|
|
|
ae4b759 |
+ GDK_INTERP_BILINEAR);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else
|
|
|
ae4b759 |
+ g_object_ref (thumb);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return thumb;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
ae4b759 |
+create_img_thumbnail (GnomeBG *bg,
|
|
|
ae4b759 |
+ GnomeThumbnailFactory *factory,
|
|
|
ae4b759 |
+ GdkScreen *screen,
|
|
|
ae4b759 |
+ int dest_width,
|
|
|
ae4b759 |
+ int dest_height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ if (bg->uri) {
|
|
|
ae4b759 |
+ GdkPixbuf *thumb = get_as_thumbnail (bg, factory, bg->uri);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (thumb) {
|
|
|
ae4b759 |
+ return scale_thumbnail (
|
|
|
ae4b759 |
+ bg->placement, bg->uri,
|
|
|
ae4b759 |
+ thumb, screen, dest_width, dest_height);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ SlideShow *show = get_as_slideshow (bg, bg->uri);
|
|
|
a599c27 |
+
|
|
|
ae4b759 |
+ if (show) {
|
|
|
ae4b759 |
+ double alpha;
|
|
|
ae4b759 |
+ Slide *slide = get_current_slide (show, &alpha);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (slide->fixed) {
|
|
|
ae4b759 |
+ GdkPixbuf *tmp;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ tmp = get_as_thumbnail (bg, factory, slide->file1);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ thumb = scale_thumbnail (
|
|
|
ae4b759 |
+ bg->placement, bg->uri,
|
|
|
ae4b759 |
+ tmp, screen, dest_width, dest_height);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ GdkPixbuf *p1 = get_as_thumbnail (bg, factory, slide->file1);
|
|
|
ae4b759 |
+ GdkPixbuf *p2 = get_as_thumbnail (bg, factory, slide->file2);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (p1 && p2) {
|
|
|
ae4b759 |
+ GdkPixbuf *thumb1, *thumb2;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ thumb1 = scale_thumbnail (
|
|
|
ae4b759 |
+ bg->placement, bg->uri,
|
|
|
ae4b759 |
+ p1, screen, dest_width, dest_height);
|
|
|
ae4b759 |
+ thumb2 = scale_thumbnail (
|
|
|
ae4b759 |
+ bg->placement, bg->uri,
|
|
|
ae4b759 |
+ p2, screen, dest_width, dest_height);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ thumb = blend (thumb1, thumb2, alpha);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_object_unref (thumb1);
|
|
|
ae4b759 |
+ g_object_unref (thumb2);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ ensure_timeout (bg, slide);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return thumb;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return NULL;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
ae4b759 |
+get_pixbuf (GnomeBG *bg)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ /* FIXME: this ref=TRUE/FALSE stuff is crazy */
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gboolean ref = FALSE;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (!bg->pixbuf_cache && bg->uri) {
|
|
|
ae4b759 |
+ ref = TRUE;
|
|
|
ae4b759 |
+ bg->uri_mtime = get_mtime (bg->uri);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->pixbuf_cache = get_as_pixbuf (bg, bg->uri);
|
|
|
ae4b759 |
+ if (!bg->pixbuf_cache) {
|
|
|
ae4b759 |
+ SlideShow *show = get_as_slideshow (bg, bg->uri);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (show) {
|
|
|
ae4b759 |
+ double alpha;
|
|
|
ae4b759 |
+ Slide *slide = get_current_slide (show, &alpha);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (slide->fixed) {
|
|
|
ae4b759 |
+ bg->pixbuf_cache = get_as_pixbuf (bg, slide->file1);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ GdkPixbuf *p1 = get_as_pixbuf (bg, slide->file1);
|
|
|
ae4b759 |
+ GdkPixbuf *p2 = get_as_pixbuf (bg, slide->file2);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (p1 && p2) {
|
|
|
ae4b759 |
+ bg->pixbuf_cache = blend (p1, p2, alpha);
|
|
|
ae4b759 |
+ ref = FALSE;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ ensure_timeout (bg, slide);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (bg->pixbuf_cache && ref)
|
|
|
ae4b759 |
+ g_object_ref (bg->pixbuf_cache);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return bg->pixbuf_cache;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static gboolean
|
|
|
ae4b759 |
+is_different (GnomeBG *bg,
|
|
|
ae4b759 |
+ const char *uri)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ if (!uri && bg->uri) {
|
|
|
ae4b759 |
+ return TRUE;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else if (uri && !bg->uri) {
|
|
|
ae4b759 |
+ return TRUE;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else if (!uri && !bg->uri) {
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else {
|
|
|
ae4b759 |
+ time_t mtime = get_mtime (uri);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (mtime != bg->uri_mtime)
|
|
|
ae4b759 |
+ return TRUE;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (strcmp (uri, bg->uri) != 0)
|
|
|
ae4b759 |
+ return TRUE;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+clear_cache (GnomeBG *bg)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ if (bg->pixbuf_cache) {
|
|
|
ae4b759 |
+ g_object_unref (bg->pixbuf_cache);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->pixbuf_cache = NULL;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (bg->timeout_id) {
|
|
|
ae4b759 |
+ g_source_remove (bg->timeout_id);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ bg->timeout_id = 0;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/* Pixbuf utilities */
|
|
|
ae4b759 |
+static guint32
|
|
|
ae4b759 |
+pixbuf_average_value (GdkPixbuf *pixbuf)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ guint64 a_total, r_total, g_total, b_total;
|
|
|
ae4b759 |
+ guint row, column;
|
|
|
ae4b759 |
+ int row_stride;
|
|
|
ae4b759 |
+ const guchar *pixels, *p;
|
|
|
ae4b759 |
+ int r, g, b, a;
|
|
|
ae4b759 |
+ guint64 dividend;
|
|
|
ae4b759 |
+ guint width, height;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ width = gdk_pixbuf_get_width (pixbuf);
|
|
|
ae4b759 |
+ height = gdk_pixbuf_get_height (pixbuf);
|
|
|
ae4b759 |
+ row_stride = gdk_pixbuf_get_rowstride (pixbuf);
|
|
|
ae4b759 |
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ /* iterate through the pixbuf, counting up each component */
|
|
|
ae4b759 |
+ a_total = 0;
|
|
|
ae4b759 |
+ r_total = 0;
|
|
|
ae4b759 |
+ g_total = 0;
|
|
|
ae4b759 |
+ b_total = 0;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (gdk_pixbuf_get_has_alpha (pixbuf)) {
|
|
|
ae4b759 |
+ for (row = 0; row < height; row++) {
|
|
|
ae4b759 |
+ p = pixels + (row * row_stride);
|
|
|
ae4b759 |
+ for (column = 0; column < width; column++) {
|
|
|
ae4b759 |
+ r = *p++;
|
|
|
ae4b759 |
+ g = *p++;
|
|
|
ae4b759 |
+ b = *p++;
|
|
|
ae4b759 |
+ a = *p++;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ a_total += a;
|
|
|
ae4b759 |
+ r_total += r * a;
|
|
|
ae4b759 |
+ g_total += g * a;
|
|
|
ae4b759 |
+ b_total += b * a;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ dividend = height * width * 0xFF;
|
|
|
ae4b759 |
+ a_total *= 0xFF;
|
|
|
ae4b759 |
+ } else {
|
|
|
ae4b759 |
+ for (row = 0; row < height; row++) {
|
|
|
ae4b759 |
+ p = pixels + (row * row_stride);
|
|
|
ae4b759 |
+ for (column = 0; column < width; column++) {
|
|
|
ae4b759 |
+ r = *p++;
|
|
|
ae4b759 |
+ g = *p++;
|
|
|
ae4b759 |
+ b = *p++;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ r_total += r;
|
|
|
ae4b759 |
+ g_total += g;
|
|
|
ae4b759 |
+ b_total += b;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ dividend = height * width;
|
|
|
ae4b759 |
+ a_total = dividend * 0xFF;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return ((a_total + dividend / 2) / dividend) << 24
|
|
|
ae4b759 |
+ | ((r_total + dividend / 2) / dividend) << 16
|
|
|
ae4b759 |
+ | ((g_total + dividend / 2) / dividend) << 8
|
|
|
ae4b759 |
+ | ((b_total + dividend / 2) / dividend);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
ae4b759 |
+pixbuf_scale_to_fit (GdkPixbuf *src, int max_width, int max_height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ double factor;
|
|
|
ae4b759 |
+ int src_width, src_height;
|
|
|
ae4b759 |
+ int new_width, new_height;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ src_width = gdk_pixbuf_get_width (src);
|
|
|
ae4b759 |
+ src_height = gdk_pixbuf_get_height (src);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ factor = MIN (max_width / (double) src_width, max_height / (double) src_height);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ new_width = floor (src_width * factor + 0.5);
|
|
|
ae4b759 |
+ new_height = floor (src_height * factor + 0.5);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return gdk_pixbuf_scale_simple (src, new_width, new_height, GDK_INTERP_BILINEAR);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
ae4b759 |
+pixbuf_scale_to_min (GdkPixbuf *src, int min_width, int min_height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ double factor;
|
|
|
ae4b759 |
+ int src_width, src_height;
|
|
|
ae4b759 |
+ int new_width, new_height;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ src_width = gdk_pixbuf_get_width (src);
|
|
|
ae4b759 |
+ src_height = gdk_pixbuf_get_height (src);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ factor = MAX (min_width / (double) src_width, min_height / (double) src_height);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ new_width = floor (src_width * factor + 0.5);
|
|
|
ae4b759 |
+ new_height = floor (src_height * factor + 0.5);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return gdk_pixbuf_scale_simple (src, new_width, new_height, GDK_INTERP_BILINEAR);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static guchar *
|
|
|
ae4b759 |
+create_gradient (const GdkColor *c1,
|
|
|
ae4b759 |
+ const GdkColor *c2,
|
|
|
ae4b759 |
+ int n_pixels)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ guchar *result = g_malloc (n_pixels * 3);
|
|
|
ae4b759 |
+ int i;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ for (i = 0; i < n_pixels; ++i) {
|
|
|
ae4b759 |
+ double ratio = (i + 0.5) / n_pixels;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ result[3 * i + 0] = ((guint16) (c1->red * (1 - ratio) + c2->red * ratio)) >> 8;
|
|
|
ae4b759 |
+ result[3 * i + 1] = ((guint16) (c1->green * (1 - ratio) + c2->green * ratio)) >> 8;
|
|
|
ae4b759 |
+ result[3 * i + 2] = ((guint16) (c1->blue * (1 - ratio) + c2->blue * ratio)) >> 8;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return result;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+pixbuf_draw_gradient (GdkPixbuf *pixbuf,
|
|
|
ae4b759 |
+ gboolean horizontal,
|
|
|
ae4b759 |
+ GdkColor *c1,
|
|
|
ae4b759 |
+ GdkColor *c2)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ int width = gdk_pixbuf_get_width (pixbuf);
|
|
|
ae4b759 |
+ int height = gdk_pixbuf_get_height (pixbuf);
|
|
|
ae4b759 |
+ int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
|
|
ae4b759 |
+ guchar *dst = gdk_pixbuf_get_pixels (pixbuf);
|
|
|
ae4b759 |
+ guchar *dst_limit = dst + height * rowstride;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (horizontal) {
|
|
|
ae4b759 |
+ guchar *gradient = create_gradient (c1, c2, width);
|
|
|
ae4b759 |
+ int copy_bytes_per_row = width * 3;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ while (dst < dst_limit) {
|
|
|
ae4b759 |
+ memcpy (dst, gradient, copy_bytes_per_row);
|
|
|
ae4b759 |
+ dst += rowstride;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ g_free (gradient);
|
|
|
ae4b759 |
+ } else {
|
|
|
ae4b759 |
+ guchar *gb, *gradient;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gb = gradient = create_gradient (c1, c2, height);
|
|
|
ae4b759 |
+ while (dst < dst_limit) {
|
|
|
ae4b759 |
+ int i;
|
|
|
ae4b759 |
+ guchar *d = dst;
|
|
|
ae4b759 |
+ guchar r = *gb++;
|
|
|
ae4b759 |
+ guchar g = *gb++;
|
|
|
ae4b759 |
+ guchar b = *gb++;
|
|
|
ae4b759 |
+ for (i = 0; i < width; i++) {
|
|
|
ae4b759 |
+ *d++ = r;
|
|
|
ae4b759 |
+ *d++ = g;
|
|
|
ae4b759 |
+ *d++ = b;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ dst += rowstride;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ g_free (gradient);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+pixbuf_blend (GdkPixbuf *src,
|
|
|
ae4b759 |
+ GdkPixbuf *dest,
|
|
|
ae4b759 |
+ int src_x,
|
|
|
ae4b759 |
+ int src_y,
|
|
|
ae4b759 |
+ int width,
|
|
|
ae4b759 |
+ int height,
|
|
|
ae4b759 |
+ int dest_x,
|
|
|
ae4b759 |
+ int dest_y,
|
|
|
ae4b759 |
+ double alpha)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ int dest_width = gdk_pixbuf_get_width (dest);
|
|
|
ae4b759 |
+ int dest_height = gdk_pixbuf_get_height (dest);
|
|
|
ae4b759 |
+ int offset_x = dest_x - src_x;
|
|
|
ae4b759 |
+ int offset_y = dest_y - src_y;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (width < 0)
|
|
|
ae4b759 |
+ width = gdk_pixbuf_get_width (src);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (height < 0)
|
|
|
ae4b759 |
+ height = gdk_pixbuf_get_height (src);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (dest_x < 0) {
|
|
|
ae4b759 |
+ offset_x -= dest_x;
|
|
|
ae4b759 |
+ dest_x = 0;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (dest_y < 0) {
|
|
|
ae4b759 |
+ offset_y -= dest_y;
|
|
|
ae4b759 |
+ dest_y = 0;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (dest_x + width > dest_width) {
|
|
|
ae4b759 |
+ width = dest_width - dest_x;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (dest_y + height > dest_height) {
|
|
|
ae4b759 |
+ height = dest_height - dest_y;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gdk_pixbuf_composite (src, dest,
|
|
|
ae4b759 |
+ dest_x, dest_y,
|
|
|
ae4b759 |
+ width, height,
|
|
|
ae4b759 |
+ offset_x, offset_y,
|
|
|
ae4b759 |
+ 1, 1, GDK_INTERP_NEAREST,
|
|
|
ae4b759 |
+ alpha * 0xFF + 0.5);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+pixbuf_tile (GdkPixbuf *src, GdkPixbuf *dest)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ int x, y;
|
|
|
ae4b759 |
+ int tile_width, tile_height;
|
|
|
ae4b759 |
+ int dest_width = gdk_pixbuf_get_width (dest);
|
|
|
ae4b759 |
+ int dest_height = gdk_pixbuf_get_height (dest);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ tile_width = gdk_pixbuf_get_width (src);
|
|
|
ae4b759 |
+ tile_height = gdk_pixbuf_get_height (src);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ for (y = 0; y < dest_height; y += tile_height) {
|
|
|
ae4b759 |
+ for (x = 0; x < dest_width; x += tile_width) {
|
|
|
ae4b759 |
+ pixbuf_blend (src, dest, 0, 0,
|
|
|
ae4b759 |
+ tile_width, tile_height, x, y, 1.0);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/* Parser for fading background */
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+handle_start_element (GMarkupParseContext *context,
|
|
|
ae4b759 |
+ const gchar *name,
|
|
|
ae4b759 |
+ const gchar **attr_names,
|
|
|
ae4b759 |
+ const gchar **attr_values,
|
|
|
ae4b759 |
+ gpointer user_data,
|
|
|
ae4b759 |
+ GError **err)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ SlideShow *parser = user_data;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (strcmp (name, "static") == 0 || strcmp (name, "transition") == 0) {
|
|
|
ae4b759 |
+ Slide *slide = g_new0 (Slide, 1);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (strcmp (name, "static") == 0)
|
|
|
ae4b759 |
+ slide->fixed = TRUE;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_queue_push_tail (parser->slides, slide);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_queue_push_tail (parser->stack, g_strdup (name));
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+handle_end_element (GMarkupParseContext *context,
|
|
|
ae4b759 |
+ const gchar *name,
|
|
|
ae4b759 |
+ gpointer user_data,
|
|
|
ae4b759 |
+ GError **err)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ SlideShow *parser = user_data;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_free (g_queue_pop_tail (parser->stack));
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static gboolean
|
|
|
ae4b759 |
+stack_is (SlideShow *parser,
|
|
|
ae4b759 |
+ const char *s1,
|
|
|
ae4b759 |
+ ...)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GList *stack = NULL;
|
|
|
ae4b759 |
+ const char *s;
|
|
|
ae4b759 |
+ GList *l1, *l2;
|
|
|
ae4b759 |
+ va_list args;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ stack = g_list_prepend (stack, (gpointer)s1);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ va_start (args, s1);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ s = va_arg (args, const char *);
|
|
|
ae4b759 |
+ while (s) {
|
|
|
ae4b759 |
+ stack = g_list_prepend (stack, (gpointer)s);
|
|
|
ae4b759 |
+ s = va_arg (args, const char *);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ l1 = stack;
|
|
|
ae4b759 |
+ l2 = parser->stack->head;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ while (l1 && l2) {
|
|
|
ae4b759 |
+ if (strcmp (l1->data, l2->data) != 0)
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ l1 = l1->next;
|
|
|
ae4b759 |
+ l2 = l2->next;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_list_free (stack);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return (!l1 && !l2);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
0c4bf27 |
+static int
|
|
|
0c4bf27 |
+parse_int (const char *text)
|
|
|
0c4bf27 |
+{
|
|
|
0c4bf27 |
+ return strtol (text, NULL, 0);
|
|
|
0c4bf27 |
+}
|
|
|
0c4bf27 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+handle_text (GMarkupParseContext *context,
|
|
|
ae4b759 |
+ const gchar *text,
|
|
|
ae4b759 |
+ gsize text_len,
|
|
|
ae4b759 |
+ gpointer user_data,
|
|
|
ae4b759 |
+ GError **err)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ SlideShow *parser = user_data;
|
|
|
ae4b759 |
+ Slide *slide = parser->slides->tail? parser->slides->tail->data : NULL;
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ if (stack_is (parser, "year", "starttime", "background", NULL)) {
|
|
|
0c4bf27 |
+ parser->start_tm.tm_year = parse_int (text) - 1900;
|
|
|
0c4bf27 |
+ }
|
|
|
0c4bf27 |
+ else if (stack_is (parser, "month", "starttime", "background", NULL)) {
|
|
|
0c4bf27 |
+ parser->start_tm.tm_mon = parse_int (text) - 1;
|
|
|
0c4bf27 |
+ }
|
|
|
0c4bf27 |
+ else if (stack_is (parser, "day", "starttime", "background", NULL)) {
|
|
|
0c4bf27 |
+ parser->start_tm.tm_mday = parse_int (text);
|
|
|
0c4bf27 |
+ }
|
|
|
0c4bf27 |
+ else if (stack_is (parser, "hour", "starttime", "background", NULL)) {
|
|
|
0c4bf27 |
+ parser->start_tm.tm_hour = parse_int (text) - 1;
|
|
|
0c4bf27 |
+ }
|
|
|
0c4bf27 |
+ else if (stack_is (parser, "minute", "starttime", "background", NULL)) {
|
|
|
0c4bf27 |
+ parser->start_tm.tm_min = parse_int (text);
|
|
|
0c4bf27 |
+ }
|
|
|
0c4bf27 |
+ else if (stack_is (parser, "second", "starttime", "background", NULL)) {
|
|
|
0c4bf27 |
+ parser->start_tm.tm_sec = parse_int (text);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else if (stack_is (parser, "duration", "static", "background", NULL) ||
|
|
|
ae4b759 |
+ stack_is (parser, "duration", "transition", "background", NULL)) {
|
|
|
ae4b759 |
+ slide->duration = g_strtod (text, NULL);
|
|
|
ae4b759 |
+ parser->total_duration += slide->duration;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else if (stack_is (parser, "file", "static", "background", NULL) ||
|
|
|
ae4b759 |
+ stack_is (parser, "from", "transition", "background", NULL)) {
|
|
|
ae4b759 |
+ slide->file1 = g_strdup (text);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+ else if (stack_is (parser, "to", "transition", "background", NULL)) {
|
|
|
ae4b759 |
+ slide->file2 = g_strdup (text);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+slideshow_free (SlideShow *show)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GList *list;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ for (list = show->slides->head; list != NULL; list = list->next) {
|
|
|
ae4b759 |
+ Slide *slide = list->data;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_free (slide->file1);
|
|
|
ae4b759 |
+ g_free (slide->file2);
|
|
|
ae4b759 |
+ g_free (slide);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_queue_free (show->slides);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ for (list = show->stack->head; list != NULL; list = list->next) {
|
|
|
ae4b759 |
+ gchar *str = list->data;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_free (str);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_queue_free (show->stack);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_free (show);
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static void
|
|
|
ae4b759 |
+dump_bg (SlideShow *show)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+#if 0
|
|
|
ae4b759 |
+ GList *list;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ for (list = show->slides->head; list != NULL; list = list->next)
|
|
|
ae4b759 |
+ {
|
|
|
ae4b759 |
+ Slide *slide = list->data;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_print ("\nSlide: %s\n", slide->fixed? "fixed" : "transition");
|
|
|
ae4b759 |
+ g_print ("duration: %d\n", slide->duration);
|
|
|
ae4b759 |
+ g_print ("file1: %p %s\n", slide, slide->file1);
|
|
|
ae4b759 |
+ g_print ("file2: %s\n", slide->file2);
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+#endif
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
0c4bf27 |
+static void
|
|
|
0c4bf27 |
+threadsafe_localtime (time_t time, struct tm *tm)
|
|
|
0c4bf27 |
+{
|
|
|
0c4bf27 |
+ struct tm *res;
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ G_LOCK_DEFINE_STATIC (localtime_mutex);
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ G_LOCK (localtime_mutex);
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ res = localtime (&time);
|
|
|
0c4bf27 |
+ if (tm) {
|
|
|
0c4bf27 |
+ *tm = *res;
|
|
|
0c4bf27 |
+ }
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ G_UNLOCK (localtime_mutex);
|
|
|
0c4bf27 |
+}
|
|
|
0c4bf27 |
+
|
|
|
ae4b759 |
+static SlideShow *
|
|
|
ae4b759 |
+read_slideshow_file (const char *uri,
|
|
|
ae4b759 |
+ GError **err)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ GMarkupParser parser = {
|
|
|
ae4b759 |
+ handle_start_element,
|
|
|
ae4b759 |
+ handle_end_element,
|
|
|
ae4b759 |
+ handle_text,
|
|
|
ae4b759 |
+ NULL, /* passthrough */
|
|
|
ae4b759 |
+ NULL, /* error */
|
|
|
ae4b759 |
+ };
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ char *contents = NULL;
|
|
|
ae4b759 |
+ gssize len;
|
|
|
ae4b759 |
+ SlideShow *show = NULL;
|
|
|
ae4b759 |
+ GMarkupParseContext *context = NULL;
|
|
|
0c4bf27 |
+ time_t t;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (!uri || (gnome_vfs_read_entire_file (uri, &len, &contents) != GNOME_VFS_OK))
|
|
|
ae4b759 |
+ return NULL;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ show = g_new0 (SlideShow, 1);
|
|
|
0c4bf27 |
+ threadsafe_localtime ((time_t)0, &show->start_tm);
|
|
|
ae4b759 |
+ show->stack = g_queue_new ();
|
|
|
ae4b759 |
+ show->slides = g_queue_new ();
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ context = g_markup_parse_context_new (&parser, 0, show, NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (!g_markup_parse_context_parse (context, contents, len, err)) {
|
|
|
ae4b759 |
+ slideshow_free (show);
|
|
|
ae4b759 |
+ show = NULL;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (!g_markup_parse_context_end_parse (context, err)) {
|
|
|
ae4b759 |
+ slideshow_free (show);
|
|
|
ae4b759 |
+ show = NULL;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_markup_parse_context_free (context);
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ t = mktime (&show->start_tm);
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ g_print ("start time: %s\n", asctime (&show->start_tm));
|
|
|
ae4b759 |
+
|
|
|
0c4bf27 |
+ show->start_time = (double)t;
|
|
|
0c4bf27 |
+
|
|
|
ae4b759 |
+ dump_bg (show);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_free (contents);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return show;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+/* Thumbnail utilities */
|
|
|
ae4b759 |
+static GdkPixbuf *
|
|
|
a599c27 |
+create_thumbnail_for_uri (GnomeThumbnailFactory *factory,
|
|
|
a599c27 |
+ const char *uri)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ char *filename;
|
|
|
ae4b759 |
+ time_t mtime;
|
|
|
ae4b759 |
+ GdkPixbuf *pixbuf, *orig;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ mtime = get_mtime (uri);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (mtime == (time_t)-1)
|
|
|
ae4b759 |
+ return NULL;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ filename = gnome_thumbnail_factory_lookup (factory, uri, mtime);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (filename) {
|
|
|
ae4b759 |
+ pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return pixbuf;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ orig = gnome_gdk_pixbuf_new_from_uri (uri);
|
|
|
ae4b759 |
+ if (orig) {
|
|
|
ae4b759 |
+ int orig_width = gdk_pixbuf_get_width (orig);
|
|
|
ae4b759 |
+ int orig_height = gdk_pixbuf_get_height (orig);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ pixbuf = pixbuf_scale_to_fit (orig, 128, 128);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_object_set_data_full (G_OBJECT (pixbuf), "gnome-thumbnail-height",
|
|
|
ae4b759 |
+ g_strdup_printf ("%d", orig_height), g_free);
|
|
|
ae4b759 |
+ g_object_set_data_full (G_OBJECT (pixbuf), "gnome-thumbnail-width",
|
|
|
ae4b759 |
+ g_strdup_printf ("%d", orig_width), g_free);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ g_object_unref (orig);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gnome_thumbnail_factory_save_thumbnail (factory, pixbuf, uri, mtime);
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return pixbuf;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ gnome_thumbnail_factory_create_failed_thumbnail (factory, uri, mtime);
|
|
|
ae4b759 |
+ return NULL;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+static gboolean
|
|
|
ae4b759 |
+get_thumb_annotations (GdkPixbuf *thumb,
|
|
|
ae4b759 |
+ int *orig_width,
|
|
|
ae4b759 |
+ int *orig_height)
|
|
|
ae4b759 |
+{
|
|
|
ae4b759 |
+ char *end;
|
|
|
ae4b759 |
+ const char *wstr, *hstr;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ wstr = gdk_pixbuf_get_option (thumb, "tEXt::Thumb::Image::Width");
|
|
|
ae4b759 |
+ hstr = gdk_pixbuf_get_option (thumb, "tEXt::Thumb::Image::Height");
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ if (hstr && wstr) {
|
|
|
ae4b759 |
+ *orig_width = strtol (wstr, &end, 10);
|
|
|
ae4b759 |
+ if (*end != 0)
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ *orig_height = strtol (hstr, &end, 10);
|
|
|
ae4b759 |
+ if (*end != 0)
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return TRUE;
|
|
|
ae4b759 |
+ }
|
|
|
ae4b759 |
+
|
|
|
ae4b759 |
+ return FALSE;
|
|
|
ae4b759 |
+}
|
|
|
ae4b759 |
--- gnome-desktop-2.19.90/libgnome-desktop/Makefile.am.gnome-bg 2007-08-13 20:04:00.000000000 -0400
|
|
|
a599c27 |
+++ gnome-desktop-2.19.90/libgnome-desktop/Makefile.am 2007-08-28 14:01:15.000000000 -0400
|
|
|
0c4bf27 |
@@ -18,7 +18,8 @@
|
|
|
ae4b759 |
libgnome_desktop_2_la_SOURCES = \
|
|
|
ae4b759 |
gnome-desktop-item.c \
|
|
|
ae4b759 |
gnome-ditem-edit.c \
|
|
|
ae4b759 |
- gnome-hint.c
|
|
|
ae4b759 |
+ gnome-hint.c \
|
|
|
ae4b759 |
+ gnome-bg.c
|
|
|
ae4b759 |
|
|
|
ae4b759 |
libgnome_desktop_2_la_LIBADD = \
|
|
|
ae4b759 |
$(GNOME_DESKTOP_LIBS)
|
|
|
0c4bf27 |
--- gnome-desktop-2.19.90/libgnome-desktop/libgnomeui/Makefile.am.gnome-bg 2007-08-13 20:04:00.000000000 -0400
|
|
|
a599c27 |
+++ gnome-desktop-2.19.90/libgnome-desktop/libgnomeui/Makefile.am 2007-08-28 14:01:15.000000000 -0400
|
|
|
0c4bf27 |
@@ -1,4 +1,5 @@
|
|
|
0c4bf27 |
libgnomeui_desktopdir = $(includedir)/gnome-desktop-2.0/libgnomeui
|
|
|
0c4bf27 |
libgnomeui_desktop_HEADERS = \
|
|
|
0c4bf27 |
gnome-ditem-edit.h \
|
|
|
0c4bf27 |
- gnome-hint.h
|
|
|
0c4bf27 |
+ gnome-hint.h \
|
|
|
0c4bf27 |
+ gnome-bg.h
|
|
|
0c4bf27 |
--- /dev/null 2007-08-15 18:04:26.337218222 -0400
|
|
|
a599c27 |
+++ gnome-desktop-2.19.90/libgnome-desktop/libgnomeui/gnome-bg.h 2007-08-28 14:01:15.000000000 -0400
|
|
|
0c4bf27 |
@@ -0,0 +1,99 @@
|
|
|
0c4bf27 |
+/* gnome-bg.h -
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ Copyright 2007, Red Hat, Inc.
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ This file is part of the Gnome Library.
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ The Gnome Library is free software; you can redistribute it and/or
|
|
|
0c4bf27 |
+ modify it under the terms of the GNU Library General Public License as
|
|
|
0c4bf27 |
+ published by the Free Software Foundation; either version 2 of the
|
|
|
0c4bf27 |
+ License, or (at your option) any later version.
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ The Gnome Library is distributed in the hope that it will be useful,
|
|
|
0c4bf27 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
0c4bf27 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
0c4bf27 |
+ Library General Public License for more details.
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ You should have received a copy of the GNU Library General Public
|
|
|
0c4bf27 |
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
|
|
|
0c4bf27 |
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
0c4bf27 |
+ Boston, MA 02111-1307, USA.
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+ Author: Soren Sandmann <sandmann@redhat.com>
|
|
|
0c4bf27 |
+*/
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+#ifndef __GNOME_BG_H__
|
|
|
0c4bf27 |
+#define __GNOME_BG_H__
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+#ifdef __cplusplus
|
|
|
0c4bf27 |
+extern "C" {
|
|
|
0c4bf27 |
+#endif
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+#include <libgnomeui/libgnomeui.h>
|
|
|
0c4bf27 |
+#include <gdk/gdk.h>
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+#define GNOME_TYPE_BG (gnome_bg_get_type ())
|
|
|
0c4bf27 |
+#define GNOME_BG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_BG, GnomeBG))
|
|
|
0c4bf27 |
+#define GNOME_BG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_BG, GnomeBGClass))
|
|
|
0c4bf27 |
+#define GNOME_IS_BG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_TYPE_BG))
|
|
|
0c4bf27 |
+#define GNOME_IS_BG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_BG))
|
|
|
0c4bf27 |
+#define GNOME_BG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_TYPE_BG, GnomeBGClass))
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+typedef struct _GnomeBG GnomeBG;
|
|
|
0c4bf27 |
+typedef struct _GnomeBGClass GnomeBGClass;
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+typedef enum {
|
|
|
0c4bf27 |
+ GNOME_BG_COLOR_SOLID,
|
|
|
0c4bf27 |
+ GNOME_BG_COLOR_H_GRADIENT,
|
|
|
0c4bf27 |
+ GNOME_BG_COLOR_V_GRADIENT
|
|
|
0c4bf27 |
+} GnomeBGColorType;
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+typedef enum {
|
|
|
0c4bf27 |
+ GNOME_BG_PLACEMENT_TILED,
|
|
|
0c4bf27 |
+ GNOME_BG_PLACEMENT_ZOOMED,
|
|
|
0c4bf27 |
+ GNOME_BG_PLACEMENT_CENTERED,
|
|
|
0c4bf27 |
+ GNOME_BG_PLACEMENT_SCALED,
|
|
|
0c4bf27 |
+ GNOME_BG_PLACEMENT_FILL_SCREEN
|
|
|
0c4bf27 |
+} GnomeBGPlacement;
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+GType gnome_bg_get_type (void);
|
|
|
0c4bf27 |
+GnomeBG * gnome_bg_new (void);
|
|
|
0c4bf27 |
+void gnome_bg_free (GnomeBG *img);
|
|
|
0c4bf27 |
+void gnome_bg_set_placement (GnomeBG *img,
|
|
|
0c4bf27 |
+ GnomeBGPlacement placement);
|
|
|
0c4bf27 |
+void gnome_bg_set_color (GnomeBG *img,
|
|
|
0c4bf27 |
+ GnomeBGColorType type,
|
|
|
0c4bf27 |
+ GdkColor *c1,
|
|
|
0c4bf27 |
+ GdkColor *c2);
|
|
|
0c4bf27 |
+void gnome_bg_set_uri (GnomeBG *img,
|
|
|
0c4bf27 |
+ const char *uri);
|
|
|
0c4bf27 |
+void gnome_bg_draw (GnomeBG *img,
|
|
|
0c4bf27 |
+ GdkPixbuf *dest);
|
|
|
0c4bf27 |
+GdkPixmap *gnome_bg_create_pixmap (GnomeBG *img,
|
|
|
0c4bf27 |
+ GdkWindow *window,
|
|
|
0c4bf27 |
+ int width,
|
|
|
0c4bf27 |
+ int height,
|
|
|
0c4bf27 |
+ gboolean root);
|
|
|
0c4bf27 |
+gboolean gnome_bg_get_image_size (GnomeBG *bg,
|
|
|
0c4bf27 |
+ GnomeThumbnailFactory *factory,
|
|
|
0c4bf27 |
+ int *width,
|
|
|
0c4bf27 |
+ int *height);
|
|
|
0c4bf27 |
+GdkPixbuf *gnome_bg_create_thumbnail (GnomeBG *bg,
|
|
|
0c4bf27 |
+ GnomeThumbnailFactory *factory,
|
|
|
0c4bf27 |
+ GdkScreen *screen,
|
|
|
0c4bf27 |
+ int dest_width,
|
|
|
0c4bf27 |
+ int dest_height);
|
|
|
0c4bf27 |
+gboolean gnome_bg_is_dark (GnomeBG *img);
|
|
|
0c4bf27 |
+gboolean gnome_bg_changes_with_size (GnomeBG *img);
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+/* Set a pixmap as root - not a GnomeBG method */
|
|
|
0c4bf27 |
+void gnome_bg_set_pixmap_as_root (GdkScreen *screen,
|
|
|
0c4bf27 |
+ GdkPixmap *pixmap);
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+#ifdef __cplusplus
|
|
|
0c4bf27 |
+}
|
|
|
0c4bf27 |
+#endif
|
|
|
0c4bf27 |
+
|
|
|
0c4bf27 |
+#endif
|