summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Jon McCann <mccann@jhu.edu>2007-09-12 20:48:19 +0000
committerWilliam Jon McCann <mccann@src.gnome.org>2007-09-12 20:48:19 +0000
commit128530db21a5c08c9afa2a285bf2ad114e623214 (patch)
treebd9df950186e9d009dd2cbdd11b71251b22c3f25
parent4e7b2b84f492f576c3944f35d3d1dff835b09bb1 (diff)
downloadgdm-128530db21a5c08c9afa2a285bf2ad114e623214.tar.gz
Added cut-n-paste lib.
2007-09-12 William Jon McCann <mccann@jhu.edu> * gui/simple-greeter/Makefile.am: * gui/simple-greeter/libbackground: Added cut-n-paste lib. svn path=/branches/mccann-gobject/; revision=5251
-rw-r--r--ChangeLog6
-rw-r--r--gui/simple-greeter/Makefile.am3
-rw-r--r--gui/simple-greeter/libbackground/ChangeLog517
-rw-r--r--gui/simple-greeter/libbackground/Makefile.am13
-rw-r--r--gui/simple-greeter/libbackground/applier.c1699
-rw-r--r--gui/simple-greeter/libbackground/applier.h76
-rw-r--r--gui/simple-greeter/libbackground/preferences.c510
-rw-r--r--gui/simple-greeter/libbackground/preferences.h108
-rw-r--r--gui/simple-greeter/libnotificationarea/na-marshal.c165
-rw-r--r--gui/simple-greeter/libnotificationarea/na-marshal.h36
10 files changed, 2932 insertions, 201 deletions
diff --git a/ChangeLog b/ChangeLog
index bf5774bf..323a1728 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,12 @@
2007-09-12 William Jon McCann <mccann@jhu.edu>
* gui/simple-greeter/Makefile.am:
+ * gui/simple-greeter/libbackground:
+ Added cut-n-paste lib.
+
+2007-09-12 William Jon McCann <mccann@jhu.edu>
+
+ * gui/simple-greeter/Makefile.am:
* gui/simple-greeter/cutnpaste/*:
Rename directory.
* gui/simple-greeter/gdm-greeter-background.c:
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
index 0881d963..045e76f1 100644
--- a/gui/simple-greeter/Makefile.am
+++ b/gui/simple-greeter/Makefile.am
@@ -2,12 +2,14 @@ NULL =
SUBDIRS = \
libnotificationarea \
+ libbackground \
$(NULL)
INCLUDES = \
-I$(top_srcdir)/common \
-I$(top_srcdir)/libgreeter \
-I$(top_srcdir)/gui/simple-greeter/libnotificationarea \
+ -I$(top_srcdir)/gui/simple-greeter/libbackground \
-DAUTHDIR=\""$(authdir)"\" \
-DDATADIR=\""$(datadir)"\" \
-DGDMCONFDIR=\"$(gdmconfdir)\" \
@@ -57,6 +59,7 @@ gdm_simple_greeter_LDADD = \
-L$(top_builddir)/libgreeter \
-lgreeter \
$(top_builddir)/gui/simple-greeter/libnotificationarea/libnotificationarea.la \
+ $(top_builddir)/gui/simple-greeter/libbackground/libbackground.la \
$(GLIB_LIBS) \
$(DBUS_LIBS) \
$(GOBJECT_LIBS) \
diff --git a/gui/simple-greeter/libbackground/ChangeLog b/gui/simple-greeter/libbackground/ChangeLog
new file mode 100644
index 00000000..c958a042
--- /dev/null
+++ b/gui/simple-greeter/libbackground/ChangeLog
@@ -0,0 +1,517 @@
+2007-04-16 Jens Granseuer <jensgr@gmx.net>
+
+ Patch by: Erich Schubert <erich@debian.org>
+
+ * applier.c: (get_geometry): fix scaling for WPTYPE_ZOOM. Fixes
+ bug #342356.
+
+2007-01-08 Rodney Dawes <dobey@novell.com>
+
+ * preferences.c (bg_preferences_merge_entry):
+ Set prefs->enabled not prefs->wallpaper_enabled
+ Patch from Jean-Christophe Jaskula
+
+ Fixes #339404
+
+2006-08-23 Kjartan Maraas <kmaraas@gnome.org>
+
+ * preferences.c: (bg_preferences_load),
+ (bg_preferences_merge_entry), (read_wptype_from_string),
+ (read_orientation_from_string): Make read_orientation_from_string()
+ and read_wptype_from_string() behave like read_color_from_string()
+ and adjust all callers. Avoids some excess strduping too I guess.
+ Closes bug #352252.
+
+2006-08-21 Rodney Dawes <dobey@novell.com>
+
+ * preferences.c (bg_preferences_load): Revert previous leak fix from
+ Kjartan Maraas as it seems to cause crashes in nautilus
+
+ see bug #352279
+
+2006-08-21 Kjartan Maraas <kmaraas@gnome.org>
+
+ * preferences.c: (bg_preferences_load): Don't leak gconf strings.
+
+2006-06-27 Sergey Udaltsov <svu@gnome.org>
+
+ * Makefile.am: redundant GNOMELOCALEDIR removed. Patch from #345178
+ applied.
+
+2006-01-14 Alan Swanson <swanson@ukfsn.org>
+
+ * applier.c (get_geometry): Handle the new WPTYPE_ZOOM setting and
+ return proper geometry for it
+
+ * preferences.c (_bg_wptype_values[]): Add the alias for the zoom type
+ (read_wptype_from_string): Handle setting the type for zoom
+ (bg_preferences_get_wptype_as_string): Return the string for the new
+ zoom setting type
+
+ * preferences.h (_wallpaper_type_t): Add the new zoom type
+
+ Partial code for #105231
+
+2005-11-07 Alexis Robert <alexis@linuxcode.eu.org>
+
+ Fixes #320647
+
+ * libbackground/preferences.c (bg_preferences_load): only use strings
+ returned from GConf when not NULL.
+
+2005-10-01 Rodney Dawes <dobey@novell.com>
+
+ * preferences.c (bg_preferences_load, bg_preferences_merge_entry):
+ Make sure that the UTF8 filename is valid and exists before trying
+ to use it, otherwise fall back to using the filename encoding specified
+ by the user with the environment variables used by glib to determine
+ the locale encoding of filenames
+
+ Fixes #168604
+
+2005-06-10 Kjartan Maraas <kmaraas@gnome.org>
+
+ * applier.c: (render_wallpaper), (is_nautilus_running): GCC4
+ build issues.
+
+2005-05-08 Richard Hoelscher <rah@rahga.com>
+
+ * applier.c (refresh_render): Remove egg_pixbuf_new_from_file_at_size,
+ using the gtk+-2.6 function for this instead.
+
+ Fixes #169757
+
+2005-02-10 Rodney Dawes <dobey@novell.com>
+
+ * Makefile.am: Don't define GNOME_ICONDIR as libbackground does not
+ use it in any of the code
+
+2004-10-14 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.8.1
+
+2004-06-27 Rodney Dawes <dobey@novell.com>
+
+ * applier.c: Remove all references to #ifdef HAVE_GTK_MULTIHEAD
+ Patch from Kjartan Maraas <kmaraas@gnome.org>
+
+ Fixes #142749
+
+2004-04-15 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.6.1
+
+2004-03-12 Chris Lahey <clahey@rigger.boston.ximian.com>
+
+ * applier.c (refresh_render): Move the image reload into a separate function.
+ (size_changed_cb): Handle screen resolution changes.
+
+2004-03-11 Chris Lahey <clahey@rigger.boston.ximian.com>
+
+ * applier.c (bg_applier_apply_prefs): If the image is going to be
+ scaled or stretched, load it at the size it's going to be
+ displayed.
+ (need_wallpaper_load_p): If the wallpaper type changed, unless it
+ changed between TILED and CENTERED, we need to reload the image.
+
+2004-04-01 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.6.0.3
+
+2004-03-30 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.6.0.1
+
+2004-03-23 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.6.0
+
+2004-03-11 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.5.4
+
+2003-12-07 Jan Arne Petersen <jpetersen@uni-bonn.de>
+
+ * Makefile.am: remove ununsed preview-file-selection.[ch] from
+ build.
+
+2004-02-13 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.5.3
+
+2004-01-14 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.5.2
+
+2003-12-30 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.5.1.1
+
+2003-12-30 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.5.1
+
+2003-10-28 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.5.0
+
+2003-07-07 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.3.4
+
+2003-06-24 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.3.3
+
+Mon Jun 2 13:35:49 2003 Jonathan Blandford <jrb@redhat.com>
+
+ * preview-file-selection.c
+ (preview_file_selection_intelligent_scale): scaling fix. Patch
+ from Marcus Matèrn <marcus.matern@safecareab.com>, #113816
+
+2003-05-07 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.3.1
+
+2003-04-07 Pasupathi Duraisamy <pasupathi.duraisamy@wipro.com>
+
+ * applier.c (set_root_pixmap): Fixes bogus GC creation.
+ patch from Anders Carlsson <andersca@gnu.org>
+
+2003-02-16 Kjartan Maraas <kmaraas@gnome.org>
+
+ * applier.c: Fix a typo in a comment.
+
+Tue Feb 4 17:09:18 2003 Jonathan Blandford <jrb@redhat.com>
+
+ * Release 2.2.0.1
+
+Tue Jan 21 01:15:14 2003 Jonathan Blandford <jrb@gnome.org>
+
+ * Release 2.2.0
+
+Thu Jan 16 02:41:09 2003 Jonathan Blandford <jrb@gnome.org>
+
+ * Release 2.1.7
+
+2003-01-10 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.1.6
+
+2002-12-18 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.1.5
+
+2002-11-23 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.1.3
+
+2002-11-02 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.1.2
+
+2002-10-21 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.1.1
+
+2002-09-13 Iain <iain@prettypeople.org>
+
+ * preview-file-selection.c (preview_file_selection_update): Update the
+ label with the size of the image.
+ (preview_file_selection_add_preview): Add a label below the preview.
+
+2002-10-01 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.1.0.1
+
+2002-08-21 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.1.0
+
+2002-07-29 jacob berkman <jacob@ximian.com>
+
+ * applier.c (set_root_pixmap):
+ (make_root_pixmap): fixes for building with gdk 2.0
+
+2002-07-27 Mark McLoughlin <mark@skynet.ie>
+
+ Add support for rendering the wallpaper on
+ a particular physical screen.
+
+ * applier.[ch]:
+ (bg_applier_init): init screen and root_window.
+ (bg_applier_class_init), (bg_applier_set_prop),
+ (bg_applier_get_prop): add "screen" property.
+ (bg_applier_new_for_screen): implement.
+ (render_wallpaper), (render_to_screen),
+ (create_pixmap), (wallpaper_full_cover_p): use the
+ screen and root window information.
+ (make_root_pixmap): add a GdkScreen arg, actually
+ use the display we opened, use the correct root
+ window and not the default one
+ (set_root_pixmap): add a GdkScreen arg, use the
+ default display, use the correct root window.
+
+2002-06-18 Jody Goldberg <jody@gnome.org>
+
+ http://bugzilla.gnome.org/show_bug.cgi?id=85224
+ * applier.c (render_wallpaper) : clamp to avoid underflow
+
+2002-06-17 Jody Goldberg <jody@gnome.org>
+
+ * Release 2.0.0
+
+2002-05-31 Damon Chaplin <damon@ximian.com>
+
+ * applier.c (bg_applier_apply_prefs): don't call set_root_pixmap() at
+ all if nautilus is running. It didn't do anything in this case anyway.
+ Removed the nice(20). A library function shouldn't do this. If
+ gnome-settings-daemon wants to be niced then it should do it in main()
+ or something like that.
+ (set_root_pixmap): do a final check to see if nautilus is running
+ before setting the pixmap.
+
+ Fixes part of #74311.
+
+2002-05-21 jacob berkman <jacob@ximian.com>
+
+ * applier.c (render_to_screen): use a gc for the pixmap not the
+ root window
+ (bg_applier_get_preview_widget): don't create the pixmap until we
+ are realized
+ (make_root_pixmap): use gdk_get_display(), not getenv ("DISPLAY"),
+ and set the colormap for our GdkPixmap so we can draw on it
+ (preview_realized_cb): create the pixmap here, and set it on our
+ GtkImage
+
+ fixes #73496
+
+2002-05-16 jacob berkman <jacob@ximian.com>
+
+ * applier.c (bg_applier_apply_prefs): don't spew a warning when
+ files can't be loaded (helps fix #76993)
+
+2002-04-19 Jody Goldberg <jody@gnome.org>
+
+ http://bugzilla.gnome.org/show_bug.cgi?id=79149
+ * preferences.c (bg_preferences_clone) : fix leaks and use
+ gdk_color_free because some wiseguy thought GdkColours should use
+ memchunks.
+ (bg_preferences_load) : ditto.
+ (bg_preferences_merge_entry) : ditto.
+ (read_color_from_string) : ditto.
+ (bg_preferences_finalize) : ditto. clean out pointers to protect
+ against multiple calls.
+
+2002-04-17 Rachel Hestilow <hestilow@ximian.com>
+
+ * applier.c (need_root_pixmap_p): Return TRUE if pixmap is NULL.
+ (create_pixmap): Only set pixmap if not already set.
+
+2002-04-17 Anders Carlsson <andersca@gnu.org>
+
+ * preferences.c: (bg_preferences_finalize), (bg_preferences_load):
+ Plug leaks. Sigh.
+
+2002-04-07 Rachel Hestilow <hestilow@ximian.com>
+
+ * applier.c (bg_applier_get_preview_widget): Connect to "realize"
+ on preview.
+ (preview_realized_cb): Added function to initialize preview pixmap.
+
+2002-03-28 Richard Hestilow <hestilow@ximian.com>
+
+ * applier.c (bg_applier_set_prop): Only set size for preview modes.
+
+2002-03-28 Richard Hestilow <hestilow@ximian.com>
+
+ * applier.c (MONITOR_CONTENTS_WIDTH, MONITOR_CONTENTS_HEIGHT):
+ Rename to _DEFAULT_WIDTH, _DEFAULT_HEIGHT.
+ (draw_disabled_message): Accept width and height as variables.
+ (bg_applier_class_init): Install props preview_width, preview_height.
+ (bg_applier_set_prop): Accept new size properties, only set to
+ default width/height on mode PREVIEW if uninitialized.
+ (bg_applier_new_at_size): Added.
+ (bg_applier_apply_prefs): Call draw_disabled_message with actual
+ width/height.
+ (bg_applier_get_preview_width): Create pixmap based on set size.
+
+2002-03-26 Dave Camp <dave@ximian.com>
+
+ * applier.c: (bg_applier_init): Don't initialize
+ is_nautilus_running here (check it each time in appy_prefs).
+ (bg_applier_apply_prefs): Don't try to apply the background if
+ nautilus is running.
+
+2002-03-19 Richard Hestilow <hestilow@ximian.com>
+
+ * preferences.h (wallpaper_type_t): Remove EMBOSSED since we
+ don't support it.
+
+ * preferences.c:
+ (_bg_wptype_values, _bg_orientation_values): Move name values
+ to nick, change name to "correct" form.
+ (read_wptype_from_string, bg_preferences_get_wptype_as_string):
+ Remove EMBOSSSED option.
+
+ * preview-file-selection.[ch]: Add function
+ preview_file_selection_intelligent_scale.
+
+ * applier.c: Change MONITOR_CONTENTS_WIDTH/HEIGHT to 64/48
+ (correct monitor ratio).
+ (bg_applier_apply_prefs): Disable wallpaper if WPTYPE_NONE.
+ (bg_applier_get_preview_widget): Create to WIDTH/HEIGHT.
+ (get_geometry): Remove reference to EMBOSSED.
+
+2002-03-17 Darin Adler <darin@bentspoon.com>
+
+ * preferences.c: (bg_preferences_merge_entry):
+ Use G_GNUC_FUNCTION so we're not gcc-specific.
+
+2002-03-15 Seth Nickell <snickell@stanford.edu>
+
+ * preferences.c: (bg_preferences_load),
+ (bg_preferences_merge_entry), (read_wptype_from_string),
+ (read_color_from_string), (bg_preferences_get_wptype_as_string):
+ * preferences.h:
+
+ Add an enum type for specifying that we don't know the type (i.e. the
+ key was not available, or set to something invalid). Currently it
+ was using -1, which barfs with some compilers that set enums
+ to be uint.
+
+2002-03-09 Richard Hestilow <hestilow@ximian.com>
+
+ * preview-file-selection.[ch]: Added.
+
+ * Makefile.am: Compile preview-file-selection.c.
+
+ * preferences.c (bg_preferences_init): Initialize adjust_opacity
+ to FALSE.
+
+2002-03-03 Alexander Larsson <alla@lysator.liu.se>
+
+ * preferences.c (bg_preferences_save):
+ Save wallpaper-enabled too.
+
+2002-02-22 Richard Hestilow <hestilow@ximian.com>
+
+ * preferences.[ch]: Add function bg_preferences_save.
+
+2002-02-17 Bradford Hovinen <hovinen@ximian.com>
+
+ * applier.c (need_root_pixmap_p): We don't need a root pixmap if
+ neither a wallpaper nor a gradient is enabled
+ (render_to_screen): Use set_back_pixmap/set_background when just
+ setting a color with a root applier
+ (need_root_pixmap_p): If the last preferences structure had
+ neither gradient nor wallpaper enabled, we need a new root pixmap
+ (need_wallpaper_load_p): We need to reload the wallpaper pixbuf if
+ it is enabled and not loaded
+ (cleanup_cb): Free bg_applier->p->pixbuf too
+ (bg_applier_apply_prefs): Only add the timeout for cleanup if we
+ are in a root renderer; we don't need it for preview
+
+2002-02-12 Lauris Kaplinski <lauris@ximian.com>
+
+ * applier.c (draw_disabled_message): Use g_object_unref for GdkGC
+ (render_wallpaper): Use gdk_drawable_get_size
+ (render_to_screen): Use gdk_get_default_root_window
+ (wallpaper_full_cover_p): Ditto
+
+ * preferences.c (read_color_from_string): Use gdk_rgb_find_color
+
+ * applier.c (bg_applier_get_preview_widget): Use gnome_program_locate_file,
+ replace GDK_ROOT_PARENT with gdk_get_default_root_window, deprecated
+ gdk_window_* methods with gdk_drawable_* ones
+ (bg_applier_get_preview_widget): Removed gtk_widget_push_visual,
+ gtk_widget_pop_visual, use gtk_image instead of gtk_pixmap
+
+2002-02-07 Richard Hestilow <hestilow@ximian.com>
+
+ * applier.c (BGApplierPrivate): Add "timeout" field.
+ (bg_apply_cleanup_cb): Added.
+ (bg_applier_apply_prefs): Add/reset timeout for cleanup function
+ if we load a pixbuf.
+
+2002-02-04 Lauris Kaplinski <lauris@ximian.com>
+
+ * preferences.c (read_wptype_from_string): Do not crash on NULL
+ (read_orientation_from_string): Ditto
+
+ * applier.c (bg_applier_dispose): Replace deprecated methods
+ (draw_disabled_message): Use gtk_image instead of gtk_pixmap,
+ replace deprecated methods
+ (render_wallpaper): Replace deprecated methods
+
+2002-01-13 Seth Nickell <snickell@stanford.edu>
+
+ reviewed by: <delete if not using a buddy>
+
+ * Makefile.am:
+ * applier.c: (bg_applier_apply_prefs),
+ (bg_applier_get_preview_widget), (draw_disabled_message),
+ (create_pixmap), (get_geometry):
+ * preferences.c: (bg_preferences_load),
+ (bg_preferences_merge_entry), (read_wptype_from_string),
+ (read_orientation_from_string):
+ * preferences.h:
+
+2002-01-28 Richard Hestilow <hestilow@ximian.com>
+
+ * Makefile.am: Use libtool to create the static library, thus
+ allowing shlibs to link to libbackground (needed for metatheme).
+
+2002-01-10 Bradford Hovinen <hovinen@ximian.com>
+
+ Courtesy of Jean Schurger <jschurger@schurger.org>:
+ * preferences.c (bg_preferences_merge_entry): Make sure the
+ wallpaper filename is non-NULL before doing anything with it
+
+2001-12-20 Bradford Hovinen <hovinen@ximian.com>
+
+ * applier.c (bg_applier_apply_prefs): Disable the wallpaper if we
+ couldn't load it
+ (bg_applier_apply_prefs): Create a clone of the preferences
+ structure first and work off of that
+ (wallpaper_full_cover_p): Return FALSE if the wallpaper pixbuf is NULL
+
+ * preferences.c (bg_preferences_merge_entry): Don't actually set
+ the wallpaper to "enabled" unless we can load the thing
+
+ * applier.c: Eliminate compiler warnings
+
+ * applier.[ch]: Rename applier to bg_applier to avoid possible
+ namespace collision
+
+ * preferences.[ch]: Rename preferences to bg_preferences to avoid
+ possible namespace collision
+
+2001-12-18 Bradford Hovinen <hovinen@ximian.com>
+
+ * preferences.c: Update GConf keys to use /desktop/gnome/background
+ (preferences_load): Use gconf_client rather than gconf_engine
+
+2001-12-17 Bradford Hovinen <hovinen@ximian.com>
+
+ * applier.c (set_root_pixmap): Set the pixmap_id correctly if
+ pixmap is NULL or -1.
+
+ * preferences.c (preferences_merge_entry): Eliminate name; use
+ entry->key on the warning
+ (preferences_merge_entry): Use correct keys
+
+ * applier.c (applier_get_preview_widget): Make sure the pixmap is
+ masked correctly
+ (applier_apply_prefs): s/gtk_object_destroy/g_object_unref/
+
+2001-12-07 Bradford Hovinen <hovinen@ximian.com>
+
+ * preferences.c (read_color_from_string): Check if string is
+ non-NULL
+ (preferences_load): Initialize the error structure
+
+ * applier.c (applier_class_init): Initialize object_class properly
+ before using it; install property after {get|set}_property are set
+ (applier_get_preview_widget): Construct the GC before using it
+
diff --git a/gui/simple-greeter/libbackground/Makefile.am b/gui/simple-greeter/libbackground/Makefile.am
new file mode 100644
index 00000000..0486b2be
--- /dev/null
+++ b/gui/simple-greeter/libbackground/Makefile.am
@@ -0,0 +1,13 @@
+EXTRA_DIST = ChangeLog
+
+INCLUDES = \
+ -DG_LOG_DOMAIN=\"capplet-common\" \
+ -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
+ -I$(top_srcdir)/ \
+ @CAPPLET_CFLAGS@
+
+noinst_LTLIBRARIES = libbackground.la
+
+libbackground_la_SOURCES = \
+ applier.c applier.h \
+ preferences.c preferences.h
diff --git a/gui/simple-greeter/libbackground/applier.c b/gui/simple-greeter/libbackground/applier.c
new file mode 100644
index 00000000..dcac027c
--- /dev/null
+++ b/gui/simple-greeter/libbackground/applier.c
@@ -0,0 +1,1699 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* -*- mode: c; style: linux -*- */
+
+/* applier.c
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Written by Bradford Hovinen <hovinen@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <string.h>
+#include <gnome.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdkprivate.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+#include <unistd.h>
+
+#include "applier.h"
+
+#define MONITOR_CONTENTS_X 0
+#define MONITOR_CONTENTS_Y 0
+#define MONITOR_CONTENTS_DEFAULT_WIDTH 64
+#define MONITOR_CONTENTS_DEFAULT_HEIGHT 48
+
+enum {
+ PROP_0,
+ PROP_TYPE,
+ PROP_PREVIEW_WIDTH,
+ PROP_PREVIEW_HEIGHT,
+ PROP_SCREEN
+};
+
+struct _BGApplierPrivate
+{
+ GtkWidget *preview_widget; /* The widget for previewing
+ * -- this is not used for
+ * actual rendering; it is
+ * returned if requested */
+ BGPreferences *last_prefs; /* A cache of the last
+ * bg_preferences structure to
+ * be applied */
+
+ GdkPixbuf *wallpaper_pixbuf; /* The "raw" wallpaper pixbuf */
+
+ BGApplierType type; /* Whether we render to the
+ * root or the preview */
+
+ /* Where on the pixmap we should render the background image. Should
+ * have origin 0,0 and width and height equal to the desktop size if we
+ * are rendering to the desktop. The area to which we render the pixbuf
+ * will be smaller if we are rendering a centered image smaller than the
+ * screen or scaling and keeping aspect ratio and the background color
+ * is solid. */
+ GdkRectangle render_geom;
+
+ /* Where to render the pixbuf, relative to the pixmap. This will be the
+ * same as render_geom above if we have no solid color area to worry
+ * about. By convention, a negative value means that the pixbuf is
+ * larger than the pixmap, so the region should be fetched from a subset
+ * of the pixbuf. */
+ GdkRectangle pixbuf_render_geom;
+
+ /* Where to fetch the data from the pixbuf. We use this in case we are
+ * rendering a centered image that is larger than the size of the
+ * desktop. Otherwise it is (0,0) */
+ GdkPoint pixbuf_xlate;
+
+ /* Geometry of the pixbuf used to render the gradient. If the wallpaper
+ * is not enabled, we use the following optimization: On one dimension,
+ * this should be equal to the dimension of render_geom, while on the
+ * other dimension it should be the constant 32. This avoids wasting
+ * memory with rendundant data. */
+ GdkPoint grad_geom;
+
+ GdkPixbuf *pixbuf; /* "working" pixbuf - All data
+ * are rendered onto this for
+ * display */
+ GdkPixmap *pixmap; /* Pixmap onto which we dump the
+ * pixbuf above when we are ready
+ * to render to the screen */
+ gboolean pixmap_is_set; /* TRUE iff the pixmap above
+ * has been set as the root
+ * pixmap */
+ guint timeout; /* "Cleanup" timeout handler;
+ * reset to 30 seconds every
+ * time apply is called. */
+ GdkWindow *root_window; /* Root window on which to
+ * render the background */
+ GdkScreen *screen; /* Screen on which to render
+ * the background */
+ guint size_changed_cb_id; /* Signal connection id. */
+};
+
+static GObjectClass *parent_class;
+
+static void bg_applier_init (BGApplier *prefs,
+ BGApplierClass *class);
+static void bg_applier_class_init (BGApplierClass *class);
+static void bg_applier_base_init (BGApplierClass *class);
+
+static void bg_applier_set_prop (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void bg_applier_get_prop (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void bg_applier_dispose (GObject *object);
+static void bg_applier_finalize (GObject *object);
+
+static void run_render_pipeline (BGApplier *bg_applier,
+ const BGPreferences *prefs);
+static void draw_disabled_message (GtkWidget *widget,
+ const guint width,
+ const guint height);
+
+static void size_changed_cb (GdkScreen *screen,
+ BGApplier *bg_applier);
+static void render_background (BGApplier *bg_applier,
+ const BGPreferences *prefs);
+static void render_wallpaper (BGApplier *bg_applier,
+ const BGPreferences *prefs);
+static void render_to_screen (BGApplier *bg_applier,
+ const BGPreferences *prefs);
+static void create_pixmap (BGApplier *bg_applier,
+ const BGPreferences *prefs);
+static void get_geometry (wallpaper_type_t wallpaper_type,
+ GdkPixbuf *pixbuf,
+ GdkRectangle *field_geom,
+ GdkRectangle *virtual_geom,
+ GdkRectangle *dest_geom,
+ GdkRectangle *src_geom);
+
+static GdkPixbuf *place_pixbuf (GdkPixbuf *dest_pixbuf,
+ GdkPixbuf *src_pixbuf,
+ GdkRectangle *dest_geom,
+ GdkRectangle *src_geom,
+ guint alpha,
+ GdkColor *bg_color);
+static GdkPixbuf *tile_pixbuf (GdkPixbuf *dest_pixbuf,
+ GdkPixbuf *src_pixbuf,
+ GdkRectangle *field_geom,
+ guint alpha,
+ GdkColor *bg_color);
+static void fill_gradient (GdkPixbuf *pixbuf,
+ GdkColor *c1,
+ GdkColor *c2,
+ orientation_t orientation);
+
+static gboolean need_wallpaper_load_p (const BGApplier *bg_applier,
+ const BGPreferences *prefs);
+static gboolean need_root_pixmap_p (const BGApplier *bg_applier,
+ const BGPreferences *prefs);
+static gboolean wallpaper_full_cover_p (const BGApplier *bg_applier,
+ const BGPreferences *prefs);
+static gboolean render_small_pixmap_p (const BGPreferences *prefs);
+
+static GdkPixmap *make_root_pixmap (GdkScreen *screen,
+ gint width,
+ gint height);
+static void set_root_pixmap (GdkPixmap *pixmap,
+ GdkScreen *screen);
+
+static gboolean is_nautilus_running (void);
+
+static gboolean cleanup_cb (BGApplier *bg_applier);
+
+static void preview_realized_cb (GtkWidget *preview,
+ BGApplier *bg_applier);
+
+GType
+bg_applier_get_type (void)
+{
+ static GType bg_applier_type = 0;
+
+ if (!bg_applier_type) {
+ static GTypeInfo bg_applier_info = {
+ sizeof (BGApplierClass),
+ (GBaseInitFunc) bg_applier_base_init,
+ NULL, /* GBaseFinalizeFunc */
+ (GClassInitFunc) bg_applier_class_init,
+ NULL, /* GClassFinalizeFunc */
+ NULL, /* user-supplied data */
+ sizeof (BGApplier),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) bg_applier_init,
+ NULL
+ };
+
+ bg_applier_type =
+ g_type_register_static (G_TYPE_OBJECT,
+ "BGApplier",
+ &bg_applier_info, 0);
+ }
+
+ return bg_applier_type;
+}
+
+static void
+bg_applier_init (BGApplier *bg_applier, BGApplierClass *class)
+{
+ bg_applier->p = g_new0 (BGApplierPrivate, 1);
+ bg_applier->p->last_prefs = NULL;
+ bg_applier->p->pixbuf = NULL;
+ bg_applier->p->wallpaper_pixbuf = NULL;
+ bg_applier->p->timeout = 0;
+ bg_applier->p->render_geom.width = -1;
+ bg_applier->p->render_geom.height = -1;
+ bg_applier->p->type = BG_APPLIER_PREVIEW;
+
+ bg_applier->p->screen = gdk_screen_get_default ();
+ bg_applier->p->root_window = gdk_screen_get_root_window (bg_applier->p->screen);
+
+ bg_applier->p->size_changed_cb_id = 0;
+}
+
+static void
+bg_applier_class_init (BGApplierClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (class);
+
+ object_class->dispose = bg_applier_dispose;
+ object_class->finalize = bg_applier_finalize;
+ object_class->set_property = bg_applier_set_prop;
+ object_class->get_property = bg_applier_get_prop;
+
+ g_object_class_install_property
+ (object_class, PROP_TYPE,
+ g_param_spec_int ("type",
+ _("Type"),
+ _("Type of bg_applier: BG_APPLIER_ROOT for root window or BG_APPLIER_PREVIEW for preview"),
+ 0, 1, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
+ (object_class, PROP_PREVIEW_WIDTH,
+ g_param_spec_uint ("preview_width",
+ _("Preview Width"),
+ _("Width if applier is a preview: Defaults to 64."),
+ 1, 65535, MONITOR_CONTENTS_DEFAULT_WIDTH,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
+ (object_class, PROP_PREVIEW_HEIGHT,
+ g_param_spec_uint ("preview_height",
+ _("Preview Height"),
+ _("Height if applier is a preview: Defaults to 48."),
+ 1, 65535, MONITOR_CONTENTS_DEFAULT_HEIGHT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
+ (object_class, PROP_SCREEN,
+ g_param_spec_object ("screen",
+ _("Screen"),
+ _("Screen on which BGApplier is to draw"),
+ GDK_TYPE_SCREEN,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ parent_class =
+ G_OBJECT_CLASS (g_type_class_ref (G_TYPE_OBJECT));
+}
+
+static void
+bg_applier_base_init (BGApplierClass *class)
+{
+}
+
+static void
+bg_applier_set_prop (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+ BGApplier *bg_applier;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_BG_APPLIER (object));
+
+ bg_applier = BG_APPLIER (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ bg_applier->p->type = g_value_get_int (value);
+
+ switch (bg_applier->p->type) {
+ case BG_APPLIER_ROOT:
+ bg_applier->p->render_geom.x = 0;
+ bg_applier->p->render_geom.y = 0;
+ bg_applier->p->render_geom.width = gdk_screen_get_width (bg_applier->p->screen);
+ bg_applier->p->render_geom.height = gdk_screen_get_height (bg_applier->p->screen);
+ bg_applier->p->pixmap = NULL;
+ bg_applier->p->pixmap_is_set = FALSE;
+
+ if (bg_applier->p->size_changed_cb_id == 0)
+ bg_applier->p->size_changed_cb_id = g_signal_connect (bg_applier->p->screen, "size_changed",
+ G_CALLBACK (size_changed_cb), bg_applier);
+ break;
+
+ case BG_APPLIER_PREVIEW:
+ if (bg_applier->p->size_changed_cb_id)
+ g_signal_handler_disconnect (bg_applier->p->screen,
+ bg_applier->p->size_changed_cb_id);
+ bg_applier->p->size_changed_cb_id = 0;
+ bg_applier->p->render_geom.x = MONITOR_CONTENTS_X;
+ bg_applier->p->render_geom.y = MONITOR_CONTENTS_Y;
+
+ if (bg_applier->p->render_geom.width == -1)
+ {
+ bg_applier->p->render_geom.width = MONITOR_CONTENTS_DEFAULT_WIDTH;
+ bg_applier->p->render_geom.height = MONITOR_CONTENTS_DEFAULT_HEIGHT;
+ }
+
+ break;
+
+ default:
+ g_critical ("Bad bg_applier type: %d", bg_applier->p->type);
+ break;
+ }
+
+ break;
+
+ case PROP_PREVIEW_WIDTH:
+ if (bg_applier->p->type == BG_APPLIER_PREVIEW)
+ bg_applier->p->render_geom.width = g_value_get_uint (value);
+ break;
+
+ case PROP_PREVIEW_HEIGHT:
+ if (bg_applier->p->type == BG_APPLIER_PREVIEW)
+ bg_applier->p->render_geom.height = g_value_get_uint (value);
+ break;
+
+ case PROP_SCREEN:
+ if (bg_applier->p->type == BG_APPLIER_ROOT) {
+ if (bg_applier->p->size_changed_cb_id)
+ g_signal_handler_disconnect (bg_applier->p->screen,
+ bg_applier->p->size_changed_cb_id);
+ bg_applier->p->screen = g_value_get_object (value);
+ bg_applier->p->root_window = gdk_screen_get_root_window (bg_applier->p->screen);
+ bg_applier->p->render_geom.width = gdk_screen_get_width (bg_applier->p->screen);
+ bg_applier->p->render_geom.height = gdk_screen_get_height (bg_applier->p->screen);
+ bg_applier->p->size_changed_cb_id = g_signal_connect (bg_applier->p->screen, "size_changed",
+ G_CALLBACK (size_changed_cb), bg_applier);
+ }
+ break;
+
+ default:
+ g_warning ("Bad property set");
+ break;
+ }
+}
+
+static void
+bg_applier_get_prop (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+ BGApplier *bg_applier;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_BG_APPLIER (object));
+
+ bg_applier = BG_APPLIER (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ g_value_set_int (value, bg_applier->p->type);
+ break;
+
+ case PROP_SCREEN:
+ g_value_set_object (value, bg_applier->p->screen);
+ break;
+
+ default:
+ g_warning ("Bad property get");
+ break;
+ }
+}
+
+static void
+bg_applier_dispose (GObject *object)
+{
+ BGApplier *bg_applier;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_BG_APPLIER (object));
+
+ bg_applier = BG_APPLIER (object);
+
+ g_assert (bg_applier->p->pixbuf == NULL);
+
+ if (bg_applier->p->last_prefs != NULL)
+ g_object_unref (G_OBJECT (bg_applier->p->last_prefs));
+ bg_applier->p->last_prefs = NULL;
+
+ if (bg_applier->p->wallpaper_pixbuf != NULL)
+ g_object_unref (G_OBJECT (bg_applier->p->wallpaper_pixbuf));
+ bg_applier->p->wallpaper_pixbuf = NULL;
+
+ if (bg_applier->p->size_changed_cb_id)
+ g_signal_handler_disconnect (bg_applier->p->screen,
+ bg_applier->p->size_changed_cb_id);
+ bg_applier->p->size_changed_cb_id = 0;
+
+ parent_class->dispose (object);
+}
+
+static void
+bg_applier_finalize (GObject *object)
+{
+ BGApplier *bg_applier;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_BG_APPLIER (object));
+
+ bg_applier = BG_APPLIER (object);
+
+ g_free (bg_applier->p);
+
+ parent_class->finalize (object);
+}
+
+GObject *
+bg_applier_new (BGApplierType type)
+{
+ GObject *object;
+
+ object = g_object_new (bg_applier_get_type (),
+ "type", type,
+ NULL);
+
+ return object;
+}
+
+GObject *
+bg_applier_new_at_size (BGApplierType type,
+ const guint width,
+ const guint height)
+{
+ GObject *object;
+
+ object = g_object_new (bg_applier_get_type (),
+ "type", type,
+ "preview_width", width,
+ "preview_height", height,
+ NULL);
+
+ return object;
+}
+
+GObject *
+bg_applier_new_for_screen (BGApplierType type,
+ GdkScreen *screen)
+{
+ GObject *object;
+
+ g_return_val_if_fail (type == BG_APPLIER_ROOT, NULL);
+
+ object = g_object_new (bg_applier_get_type (),
+ "type", type,
+ "screen", screen,
+ NULL);
+ return object;
+}
+
+static void
+refresh_render (BGApplier *bg_applier,
+ BGPreferences *prefs,
+ gboolean need_wallpaper_load)
+{
+ if (bg_applier->p->type == BG_APPLIER_ROOT && is_nautilus_running ()) {
+ return;
+ }
+
+ if (!prefs->enabled) {
+ if (bg_applier->p->type == BG_APPLIER_PREVIEW)
+ draw_disabled_message (bg_applier_get_preview_widget (bg_applier), bg_applier->p->render_geom.width, bg_applier->p->render_geom.height);
+ return;
+ }
+
+ if (need_wallpaper_load) {
+ if (bg_applier->p->wallpaper_pixbuf != NULL)
+ g_object_unref (G_OBJECT (bg_applier->p->wallpaper_pixbuf));
+
+ bg_applier->p->wallpaper_pixbuf = NULL;
+
+ if (prefs->wallpaper_enabled) {
+ g_return_if_fail (prefs->wallpaper_filename != NULL);
+
+ if (prefs->wallpaper_type == WPTYPE_STRETCHED ||
+ prefs->wallpaper_type == WPTYPE_SCALED) {
+ bg_applier->p->wallpaper_pixbuf =
+ gdk_pixbuf_new_from_file_at_scale (prefs->wallpaper_filename,
+ bg_applier->p->render_geom.width,
+ bg_applier->p->render_geom.height,
+ prefs->wallpaper_type == WPTYPE_SCALED,
+ NULL);
+ } else {
+ bg_applier->p->wallpaper_pixbuf =
+ gdk_pixbuf_new_from_file (prefs->wallpaper_filename, NULL);
+ }
+
+ if (bg_applier->p->wallpaper_pixbuf == NULL) {
+ prefs->wallpaper_enabled = FALSE;
+ }
+ else if (bg_applier->p->type == BG_APPLIER_ROOT) {
+ if (bg_applier->p->timeout)
+ g_source_remove (bg_applier->p->timeout);
+ bg_applier->p->timeout = g_timeout_add (30000, (GSourceFunc) cleanup_cb, bg_applier);
+ }
+ }
+ }
+
+ run_render_pipeline (bg_applier, prefs);
+
+ if (bg_applier->p->type == BG_APPLIER_PREVIEW && bg_applier->p->preview_widget != NULL)
+ gtk_widget_queue_draw (bg_applier->p->preview_widget);
+}
+
+static void
+size_changed_cb (GdkScreen *screen,
+ BGApplier *bg_applier)
+{
+ bg_applier->p->render_geom.width = gdk_screen_get_width (bg_applier->p->screen);
+ bg_applier->p->render_geom.height = gdk_screen_get_height (bg_applier->p->screen);
+ if (bg_applier->p->last_prefs) {
+ refresh_render (bg_applier,
+ bg_applier->p->last_prefs,
+ TRUE);
+ }
+}
+
+void
+bg_applier_apply_prefs (BGApplier *bg_applier,
+ const BGPreferences *prefs)
+{
+ BGPreferences *new_prefs;
+
+ g_return_if_fail (bg_applier != NULL);
+ g_return_if_fail (IS_BG_APPLIER (bg_applier));
+
+ new_prefs = BG_PREFERENCES (bg_preferences_clone (prefs));
+
+ if (new_prefs->wallpaper_type == WPTYPE_NONE)
+ {
+ new_prefs->wallpaper_enabled = FALSE;
+ new_prefs->wallpaper_type = WPTYPE_CENTERED;
+ }
+
+ refresh_render (bg_applier, new_prefs, need_wallpaper_load_p (bg_applier, new_prefs));
+
+ if (bg_applier->p->last_prefs != NULL)
+ g_object_unref (G_OBJECT (bg_applier->p->last_prefs));
+
+ bg_applier->p->last_prefs = new_prefs;
+}
+
+gboolean
+bg_applier_render_color_p (const BGApplier *bg_applier, const BGPreferences *prefs)
+{
+ g_return_val_if_fail (bg_applier != NULL, FALSE);
+ g_return_val_if_fail (IS_BG_APPLIER (bg_applier), FALSE);
+ g_return_val_if_fail (prefs != NULL, FALSE);
+ g_return_val_if_fail (IS_BG_PREFERENCES (prefs), FALSE);
+
+ return prefs->enabled && !wallpaper_full_cover_p (bg_applier, prefs);
+}
+
+GtkWidget *
+bg_applier_get_preview_widget (BGApplier *bg_applier)
+{
+ if (bg_applier->p->preview_widget == NULL)
+ {
+ bg_applier->p->preview_widget = gtk_image_new ();
+
+ /* We need to initialize the pixmap, but this
+ * needs GCs, so we have to wait until realize. */
+ g_signal_connect (G_OBJECT (bg_applier->p->preview_widget),
+ "realize",
+ (GCallback) preview_realized_cb,
+ bg_applier);
+ }
+
+ return bg_applier->p->preview_widget;
+}
+
+GdkPixbuf *
+bg_applier_get_wallpaper_pixbuf (BGApplier *bg_applier)
+{
+ g_return_val_if_fail (bg_applier != NULL, NULL);
+ g_return_val_if_fail (IS_BG_APPLIER (bg_applier), NULL);
+
+ return bg_applier->p->wallpaper_pixbuf;
+}
+
+static void
+draw_disabled_message (GtkWidget *widget, const guint w, const guint h)
+{
+ GdkPixmap *pixmap;
+ GdkColor color;
+ PangoLayout *layout;
+ PangoRectangle extents;
+ GdkGC *gc;
+ gint x, y;
+ const char *disabled_string = _("Disabled");
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_IMAGE (widget));
+
+ x = MONITOR_CONTENTS_X;
+ y = MONITOR_CONTENTS_Y;
+
+ if (!GTK_WIDGET_REALIZED (widget)) {
+ gtk_widget_realize (widget);
+ }
+
+ gtk_image_get_pixmap (GTK_IMAGE (widget), &pixmap, NULL);
+ gc = gdk_gc_new (widget->window);
+
+ color.red = 0x0;
+ color.green = 0x0;
+ color.blue = 0x0;
+ gdk_gc_set_rgb_fg_color (gc, &color);
+ gdk_draw_rectangle (pixmap, gc, TRUE, x, y, w, h);
+
+ layout = gtk_widget_create_pango_layout (widget, disabled_string);
+ pango_layout_get_pixel_extents (layout, &extents, NULL);
+
+ color.red = 0xffff;
+ color.green = 0xffff;
+ color.blue = 0xffff;
+ gdk_gc_set_rgb_fg_color (gc, &color);
+
+ /* fixme: I do not understand the logic (Lauris) */
+
+ gdk_draw_layout (widget->window,
+ gc,
+ x + (w - extents.width) / 2,
+ y + (h - extents.height) / 2 + extents.height / 2,
+ layout);
+
+ g_object_unref (G_OBJECT (gc));
+ g_object_unref (G_OBJECT (layout));
+}
+
+static void
+run_render_pipeline (BGApplier *bg_applier, const BGPreferences *prefs)
+{
+ g_return_if_fail (bg_applier != NULL);
+ g_return_if_fail (IS_BG_APPLIER (bg_applier));
+ g_return_if_fail (prefs != NULL);
+ g_return_if_fail (IS_BG_PREFERENCES (prefs));
+
+ g_assert (bg_applier->p->pixbuf == NULL);
+
+ /* Initialize bg_applier->p->render_geom */
+ bg_applier->p->pixbuf_render_geom.x = bg_applier->p->render_geom.x;
+ bg_applier->p->pixbuf_render_geom.y = bg_applier->p->render_geom.y;
+ bg_applier->p->pixbuf_render_geom.width = bg_applier->p->render_geom.width;
+ bg_applier->p->pixbuf_render_geom.height = bg_applier->p->render_geom.height;
+ bg_applier->p->pixbuf_xlate.x = 0;
+ bg_applier->p->pixbuf_xlate.y = 0;
+
+ render_background (bg_applier, prefs);
+
+ if (need_root_pixmap_p (bg_applier, prefs))
+ create_pixmap (bg_applier, prefs);
+
+ render_wallpaper (bg_applier, prefs);
+ render_to_screen (bg_applier, prefs);
+
+ if (bg_applier->p->pixbuf != NULL) {
+ g_object_unref (G_OBJECT (bg_applier->p->pixbuf));
+ bg_applier->p->pixbuf = NULL;
+ }
+}
+
+/* Create the gradient image if necessary and put it into a fresh pixbuf
+ *
+ * Preconditions:
+ * 1. prefs is valid
+ * 2. The old bg_applier->p->pixbuf, if it existed, has been destroyed
+ *
+ * Postconditions (assuming gradient is enabled):
+ * 1. bg_applier->p->pixbuf contains a newly rendered gradient
+ */
+
+static void
+render_background (BGApplier *bg_applier, const BGPreferences *prefs)
+{
+ g_return_if_fail (bg_applier != NULL);
+ g_return_if_fail (IS_BG_APPLIER (bg_applier));
+ g_return_if_fail (prefs != NULL);
+ g_return_if_fail (IS_BG_PREFERENCES (prefs));
+
+ if (prefs->gradient_enabled && !wallpaper_full_cover_p (bg_applier, prefs)) {
+ bg_applier->p->grad_geom.x = bg_applier->p->render_geom.width;
+ bg_applier->p->grad_geom.y = bg_applier->p->render_geom.height;
+
+ if (bg_applier->p->type == BG_APPLIER_ROOT && !prefs->wallpaper_enabled) {
+ if (prefs->orientation == ORIENTATION_HORIZ)
+ bg_applier->p->grad_geom.y = 32;
+ else
+ bg_applier->p->grad_geom.x = 32;
+ }
+
+ bg_applier->p->pixbuf =
+ gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ FALSE, 8,
+ bg_applier->p->grad_geom.x,
+ bg_applier->p->grad_geom.y);
+
+ fill_gradient (bg_applier->p->pixbuf,
+ prefs->color1, prefs->color2,
+ prefs->orientation);
+
+ bg_applier->p->pixbuf_render_geom.width = bg_applier->p->grad_geom.x;
+ bg_applier->p->pixbuf_render_geom.height = bg_applier->p->grad_geom.y;
+ }
+}
+
+/* Render the wallpaper onto the pixbuf-in-progress.
+ *
+ * Preconditions:
+ * 1. The wallpaper pixbuf has been loaded and is in
+ * bg_applier->p->wallpaper_pixbuf.
+ * 2. The structure bg_applier->p->render_geom is filled out properly as
+ * described in the documentation above (this should be invariant).
+ * 3. The various fields in prefs are valid
+ *
+ * Postconditions (assuming wallpaper is enabled):
+ * 1. bg_applier->p->pixbuf contains the pixbuf-in-progress with the wallpaper
+ * correctly rendered.
+ * 2. bg_applier->p->pixbuf_render_geom has been modified, if necessary,
+ * according to the requirements of the wallpaper; it should be set by
+ * default to be the same as bg_applier->p->render_geom.
+ */
+
+static void
+render_wallpaper (BGApplier *bg_applier, const BGPreferences *prefs)
+{
+ GdkRectangle src_geom = { 0, };
+ GdkRectangle dest_geom = { 0, };
+ GdkRectangle virtual_geom;
+ GdkPixbuf *prescaled_pixbuf = NULL;
+ guint alpha;
+ gint tmp1, tmp2;
+ gint pwidth, pheight;
+
+ g_return_if_fail (bg_applier != NULL);
+ g_return_if_fail (IS_BG_APPLIER (bg_applier));
+ g_return_if_fail (prefs != NULL);
+ g_return_if_fail (IS_BG_PREFERENCES (prefs));
+
+ if (prefs->wallpaper_enabled) {
+ if (bg_applier->p->wallpaper_pixbuf == NULL)
+ return;
+
+ gdk_drawable_get_size (bg_applier->p->root_window, &tmp1, &tmp2);
+ virtual_geom.x = virtual_geom.y = 0;
+ virtual_geom.width = tmp1;
+ virtual_geom.height = tmp2;
+
+ pwidth = gdk_pixbuf_get_width (bg_applier->p->wallpaper_pixbuf);
+ pheight = gdk_pixbuf_get_height (bg_applier->p->wallpaper_pixbuf);
+
+ get_geometry (prefs->wallpaper_type,
+ bg_applier->p->wallpaper_pixbuf,
+ &(bg_applier->p->render_geom),
+ &virtual_geom, &dest_geom, &src_geom);
+
+ /* Modify bg_applier->p->pixbuf_render_geom if necessary */
+ if (bg_applier->p->pixbuf == NULL) { /* This means we didn't render a gradient */
+ bg_applier->p->pixbuf_render_geom.x = dest_geom.x + bg_applier->p->render_geom.x;
+ bg_applier->p->pixbuf_render_geom.y = dest_geom.y + bg_applier->p->render_geom.y;
+ bg_applier->p->pixbuf_render_geom.width = dest_geom.width;
+ bg_applier->p->pixbuf_render_geom.height = dest_geom.height;
+ }
+
+ if (prefs->wallpaper_type == WPTYPE_TILED) {
+ if (dest_geom.width != pwidth || dest_geom.height != pheight) {
+ int hscale = pwidth * bg_applier->p->render_geom.width / virtual_geom.width;
+ int vscale = pheight * bg_applier->p->render_geom.height / virtual_geom.height;
+
+ if (hscale < 1) hscale = 1;
+ if (vscale < 1) vscale = 1;
+
+ prescaled_pixbuf = gdk_pixbuf_scale_simple
+ (bg_applier->p->wallpaper_pixbuf, hscale, vscale,
+ GDK_INTERP_BILINEAR);
+ } else {
+ prescaled_pixbuf = bg_applier->p->wallpaper_pixbuf;
+ g_object_ref (G_OBJECT (prescaled_pixbuf));
+ }
+ }
+
+ if (prefs->adjust_opacity) {
+ alpha = 2.56 * prefs->opacity;
+ alpha = alpha * alpha / 256;
+ alpha = CLAMP (alpha, 0, 255);
+ } else {
+ alpha = 255;
+ }
+
+ if (prefs->wallpaper_type == WPTYPE_TILED)
+ bg_applier->p->pixbuf = tile_pixbuf (bg_applier->p->pixbuf,
+ prescaled_pixbuf,
+ &(bg_applier->p->render_geom),
+ alpha, prefs->color1);
+ else
+ bg_applier->p->pixbuf = place_pixbuf (bg_applier->p->pixbuf,
+ bg_applier->p->wallpaper_pixbuf,
+ &dest_geom, &src_geom,
+ alpha, prefs->color1);
+
+ if (bg_applier->p->pixbuf == bg_applier->p->wallpaper_pixbuf) {
+ bg_applier->p->pixbuf_xlate.x = src_geom.x;
+ bg_applier->p->pixbuf_xlate.y = src_geom.y;
+ }
+
+ if (prescaled_pixbuf != NULL)
+ g_object_unref (G_OBJECT (prescaled_pixbuf));
+ }
+}
+
+/* Take whatever we have rendered and transfer it to the display.
+ *
+ * Preconditions:
+ * 1. We have already rendered the gradient and wallpaper, and
+ * bg_applier->p->pixbuf is a valid GdkPixbuf containing that rendered data.
+ * 2. The structure bg_applier->p->pixbuf_render_geom contains the coordonites on
+ * the destination visual to which we should render the contents of
+ * bg_applier->p->pixbuf
+ * 3. The structure bg_applier->p->render_geom contains the total area that the
+ * background should cover (i.e. the whole desktop if we are rendering to
+ * the root window, or the region inside the monitor if we are rendering to
+ * the preview).
+ * 4. The strucutre prefs->color1 contains the background color to be used on
+ * areas not covered by the above pixbuf.
+ */
+
+static void
+render_to_screen (BGApplier *bg_applier, const BGPreferences *prefs)
+{
+ GdkGC *gc;
+
+ g_return_if_fail (bg_applier != NULL);
+ g_return_if_fail (IS_BG_APPLIER (bg_applier));
+ g_return_if_fail (prefs != NULL);
+ g_return_if_fail (IS_BG_PREFERENCES (prefs));
+
+ gc = gdk_gc_new (bg_applier->p->pixmap);
+
+ if (bg_applier->p->pixbuf != NULL) {
+ if (bg_applier->p->pixbuf_render_geom.x != 0 ||
+ bg_applier->p->pixbuf_render_geom.y != 0 ||
+ bg_applier->p->pixbuf_render_geom.width != bg_applier->p->render_geom.width ||
+ bg_applier->p->pixbuf_render_geom.height != bg_applier->p->render_geom.height)
+ {
+ gboolean success;
+
+#if 0
+ gdk_color_alloc (gdk_window_get_colormap (bg_applier->p->root_window), prefs->color1);
+#else
+ gdk_colormap_alloc_colors (gdk_drawable_get_colormap (bg_applier->p->root_window),
+ prefs->color1, 1, FALSE, TRUE, &success);
+#endif
+
+ gdk_gc_set_foreground (gc, prefs->color1);
+ gdk_draw_rectangle (bg_applier->p->pixmap, gc, TRUE,
+ bg_applier->p->render_geom.x,
+ bg_applier->p->render_geom.y,
+ bg_applier->p->render_geom.width,
+ bg_applier->p->render_geom.height);
+ }
+
+ gdk_pixbuf_render_to_drawable
+ (bg_applier->p->pixbuf,
+ bg_applier->p->pixmap, gc,
+ bg_applier->p->pixbuf_xlate.x,
+ bg_applier->p->pixbuf_xlate.y,
+ bg_applier->p->pixbuf_render_geom.x,
+ bg_applier->p->pixbuf_render_geom.y,
+ bg_applier->p->pixbuf_render_geom.width,
+ bg_applier->p->pixbuf_render_geom.height,
+ GDK_RGB_DITHER_MAX, 0, 0);
+ } else {
+ if (bg_applier->p->type == BG_APPLIER_ROOT) {
+ gboolean success;
+
+#if 0
+ gdk_color_alloc (gdk_window_get_colormap (bg_applier->p->root_window), prefs->color1);
+#else
+ gdk_colormap_alloc_colors (gdk_drawable_get_colormap (bg_applier->p->root_window),
+ prefs->color1, 1, FALSE, TRUE, &success);
+#endif
+ gdk_window_set_background (bg_applier->p->root_window, prefs->color1);
+ gdk_window_clear (bg_applier->p->root_window);
+ }
+ else if (bg_applier->p->type == BG_APPLIER_PREVIEW) {
+ gboolean success;
+
+#if 0
+ gdk_color_alloc (gdk_window_get_colormap (bg_applier->p->preview_widget->window), prefs->color1);
+#else
+ gdk_colormap_alloc_colors (gdk_drawable_get_colormap (bg_applier->p->root_window),
+ prefs->color1, 1, FALSE, TRUE, &success);
+#endif
+
+ if (bg_applier->p->type == BG_APPLIER_PREVIEW) {
+ gdk_gc_set_foreground (gc, prefs->color1);
+ gdk_draw_rectangle (bg_applier->p->pixmap, gc, TRUE,
+ bg_applier->p->render_geom.x,
+ bg_applier->p->render_geom.y,
+ bg_applier->p->render_geom.width,
+ bg_applier->p->render_geom.height);
+ }
+ else if (bg_applier->p->type == BG_APPLIER_ROOT) {
+ gdk_window_set_back_pixmap (bg_applier->p->root_window, NULL, FALSE);
+ gdk_window_set_background (bg_applier->p->root_window, prefs->color1);
+ }
+ }
+ }
+
+ if (bg_applier->p->type == BG_APPLIER_ROOT && !bg_applier->p->pixmap_is_set &&
+ (prefs->wallpaper_enabled || prefs->gradient_enabled))
+ set_root_pixmap (bg_applier->p->pixmap, bg_applier->p->screen);
+ else if (bg_applier->p->type == BG_APPLIER_ROOT && !bg_applier->p->pixmap_is_set)
+ set_root_pixmap (NULL, bg_applier->p->screen);
+
+ g_object_unref (G_OBJECT (gc));
+}
+
+/* Create a pixmap that will replace the current root pixmap. This function has
+ * no effect if the bg_applier is for the preview window
+ */
+
+static void
+create_pixmap (BGApplier *bg_applier, const BGPreferences *prefs)
+{
+ gint width, height;
+
+ g_return_if_fail (bg_applier != NULL);
+ g_return_if_fail (IS_BG_APPLIER (bg_applier));
+ g_return_if_fail (prefs != NULL);
+ g_return_if_fail (IS_BG_PREFERENCES (prefs));
+
+ switch (bg_applier->p->type) {
+ case BG_APPLIER_ROOT:
+ if (prefs->gradient_enabled && !prefs->wallpaper_enabled) {
+ width = bg_applier->p->grad_geom.x;
+ height = bg_applier->p->grad_geom.y;
+ } else {
+ width = bg_applier->p->render_geom.width;
+ height = bg_applier->p->render_geom.height;
+ }
+
+ bg_applier->p->pixmap = make_root_pixmap (bg_applier->p->screen, width, height);
+ bg_applier->p->pixmap_is_set = FALSE;
+ break;
+
+ case BG_APPLIER_PREVIEW:
+ bg_applier_get_preview_widget (bg_applier);
+
+ if (!GTK_WIDGET_REALIZED (bg_applier->p->preview_widget))
+ gtk_widget_realize (bg_applier->p->preview_widget);
+
+#if 0
+ bg_applier->p->pixmap = GTK_PIXMAP (bg_applier->p->preview_widget)->pixmap;
+#else
+ if (!bg_applier->p->pixmap)
+ gtk_image_get_pixmap (GTK_IMAGE (bg_applier->p->preview_widget), &bg_applier->p->pixmap, NULL);
+#endif
+ bg_applier->p->pixmap_is_set = TRUE;
+ break;
+ }
+}
+
+/* Compute geometry information based on the wallpaper type. In particular,
+ * determine where on the destination visual the wallpaper should be rendered
+ * and where the data from the source pixbuf the image should be fetched.
+ */
+
+static void
+get_geometry (wallpaper_type_t wallpaper_type,
+ GdkPixbuf *pixbuf,
+ GdkRectangle *field_geom,
+ GdkRectangle *virtual_geom,
+ GdkRectangle *dest_geom,
+ GdkRectangle *src_geom)
+{
+ gdouble asp, xfactor, yfactor;
+ gint pwidth, pheight;
+ gint st = 0;
+
+ xfactor = (gdouble) field_geom->width / (gdouble) virtual_geom->width;
+ yfactor = (gdouble) field_geom->height / (gdouble) virtual_geom->height;
+
+ pwidth = gdk_pixbuf_get_width (pixbuf);
+ pheight = gdk_pixbuf_get_height (pixbuf);
+
+ switch (wallpaper_type) {
+ case WPTYPE_TILED:
+ src_geom->x = src_geom->y = 0;
+ dest_geom->x = dest_geom->y = 0;
+
+ src_geom->width = pwidth;
+ src_geom->height = pheight;
+
+ dest_geom->width = field_geom->width;
+ dest_geom->height = field_geom->height;
+
+ break;
+
+ case WPTYPE_CENTERED:
+ if (virtual_geom->width < pwidth) {
+ src_geom->width = virtual_geom->width;
+ src_geom->x = (pwidth - virtual_geom->width) / 2;
+ dest_geom->width = field_geom->width;
+ dest_geom->x = 0;
+ } else {
+ src_geom->width = pwidth;
+ src_geom->x = 0;
+ dest_geom->width = MIN ((gdouble) src_geom->width * xfactor, field_geom->width);
+ dest_geom->x = (field_geom->width - dest_geom->width) / 2;
+ }
+
+ if (virtual_geom->height < pheight) {
+ src_geom->height = virtual_geom->height;
+ src_geom->y = (pheight - virtual_geom->height) / 2;
+ dest_geom->height = field_geom->height;
+ dest_geom->y = 0;
+ } else {
+ src_geom->height = pheight;
+ src_geom->y = 0;
+ dest_geom->height = MIN ((gdouble) src_geom->height * yfactor, field_geom->height);
+ dest_geom->y = (field_geom->height - dest_geom->height) / 2;
+ }
+
+ break;
+
+ case WPTYPE_SCALED:
+ asp = (gdouble) pwidth / (gdouble) virtual_geom->width;
+
+ if (asp < (gdouble) pheight / virtual_geom->height) {
+ asp = (gdouble) pheight / (gdouble) virtual_geom->height;
+ st = 1;
+ }
+
+ if (st) {
+ dest_geom->width = pwidth / asp * xfactor;
+ dest_geom->height = field_geom->height;
+ dest_geom->x = (field_geom->width - dest_geom->width) / 2;
+ dest_geom->y = 0;
+ } else {
+ dest_geom->height = pheight / asp * yfactor;
+ dest_geom->width = field_geom->width;
+ dest_geom->x = 0;
+ dest_geom->y = (field_geom->height - dest_geom->height) / 2;
+ }
+
+ src_geom->x = src_geom->y = 0;
+ src_geom->width = pwidth;
+ src_geom->height = pheight;
+
+ break;
+
+ case WPTYPE_ZOOM:
+ asp = (gdouble) pwidth / (gdouble) virtual_geom->width;
+
+ if (asp > (gdouble) pheight / virtual_geom->height) {
+ src_geom->width = pheight * virtual_geom->width / virtual_geom->height;
+ src_geom->height = pheight;
+ src_geom->x = (pwidth - src_geom->width) / 2;
+ src_geom->y = 0;
+ } else {
+ src_geom->width = pwidth;
+ src_geom->height = pwidth * virtual_geom->height / virtual_geom->width;
+ src_geom->x = 0;
+ src_geom->y = (pheight - src_geom->height) / 2;
+ }
+
+ dest_geom->x = dest_geom->y = 0;
+ dest_geom->width = field_geom->width;
+ dest_geom->height = field_geom->height;
+
+ break;
+
+ case WPTYPE_STRETCHED:
+ dest_geom->width = field_geom->width;
+ dest_geom->height = field_geom->height;
+ dest_geom->x = 0;
+ dest_geom->y = 0;
+ src_geom->x = src_geom->y = 0;
+ src_geom->width = pwidth;
+ src_geom->height = pheight;
+ break;
+ default:
+ g_error ("Bad wallpaper type");
+ break;
+ }
+}
+
+/* Place one pixbuf onto another, compositing and scaling as necessary */
+
+static GdkPixbuf *
+place_pixbuf (GdkPixbuf *dest_pixbuf,
+ GdkPixbuf *src_pixbuf,
+ GdkRectangle *dest_geom,
+ GdkRectangle *src_geom,
+ guint alpha,
+ GdkColor *bg_color)
+{
+ gboolean need_composite;
+ gboolean need_scaling;
+ gdouble scale_x, scale_y;
+ gint real_dest_x, real_dest_y;
+ guint colorv;
+
+ need_composite = (alpha < 255 || gdk_pixbuf_get_has_alpha (src_pixbuf));
+ need_scaling = ((dest_geom->width != src_geom->width) || (dest_geom->height != src_geom->height));
+
+ if (need_scaling) {
+ scale_x = (gdouble) dest_geom->width / (gdouble) src_geom->width;
+ scale_y = (gdouble) dest_geom->height / (gdouble) src_geom->height;
+ } else {
+ scale_x = scale_y = 1.0;
+ }
+
+ if (need_composite && dest_pixbuf != NULL) {
+ gdk_pixbuf_composite
+ (src_pixbuf, dest_pixbuf,
+ dest_geom->x, dest_geom->y,
+ dest_geom->width,
+ dest_geom->height,
+ dest_geom->x - src_geom->x * scale_x,
+ dest_geom->y - src_geom->y * scale_y,
+ scale_x, scale_y,
+ GDK_INTERP_BILINEAR,
+ alpha);
+ }
+ else if (need_composite) {
+ dest_pixbuf = gdk_pixbuf_new
+ (GDK_COLORSPACE_RGB, FALSE, 8,
+ dest_geom->width, dest_geom->height);
+
+ colorv = ((bg_color->red & 0xff00) << 8) |
+ (bg_color->green & 0xff00) |
+ ((bg_color->blue & 0xff00) >> 8);
+
+ gdk_pixbuf_composite_color
+ (src_pixbuf, dest_pixbuf,
+ 0, 0,
+ dest_geom->width,
+ dest_geom->height,
+ -src_geom->x * scale_x,
+ -src_geom->y * scale_y,
+ scale_x, scale_y,
+ GDK_INTERP_BILINEAR,
+ alpha, 0, 0, 65536,
+ colorv, colorv);
+ }
+ else if (need_scaling) {
+ if (dest_pixbuf == NULL) {
+ dest_pixbuf = gdk_pixbuf_new
+ (GDK_COLORSPACE_RGB, FALSE, 8,
+ dest_geom->width, dest_geom->height);
+ real_dest_x = real_dest_y = 0;
+ } else {
+ real_dest_x = dest_geom->x;
+ real_dest_y = dest_geom->y;
+ }
+
+ gdk_pixbuf_scale
+ (src_pixbuf, dest_pixbuf,
+ real_dest_x, real_dest_y,
+ dest_geom->width,
+ dest_geom->height,
+ real_dest_x - src_geom->x * scale_x,
+ real_dest_y - src_geom->y * scale_y,
+ scale_x, scale_y,
+ GDK_INTERP_BILINEAR);
+ }
+ else if (dest_pixbuf != NULL) {
+ gdk_pixbuf_copy_area
+ (src_pixbuf,
+ src_geom->x, src_geom->y,
+ src_geom->width,
+ src_geom->height,
+ dest_pixbuf,
+ dest_geom->x, dest_geom->y);
+ } else {
+ dest_pixbuf = src_pixbuf;
+ g_object_ref (G_OBJECT (dest_pixbuf));
+ }
+
+ return dest_pixbuf;
+}
+
+/* Tile one pixbuf repeatedly onto another, compositing as necessary. Assumes
+ * that the source pixbuf has already been scaled properly
+ */
+
+static GdkPixbuf *
+tile_pixbuf (GdkPixbuf *dest_pixbuf,
+ GdkPixbuf *src_pixbuf,
+ GdkRectangle *field_geom,
+ guint alpha,
+ GdkColor *bg_color)
+{
+ gboolean need_composite;
+ gboolean use_simple;
+ gdouble cx, cy;
+ gdouble colorv;
+ gint pwidth, pheight;
+
+ need_composite = (alpha < 255 || gdk_pixbuf_get_has_alpha (src_pixbuf));
+ use_simple = (dest_pixbuf == NULL);
+
+ if (dest_pixbuf == NULL)
+ dest_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, field_geom->width, field_geom->height);
+
+ if (need_composite && use_simple)
+ colorv = ((bg_color->red & 0xff00) << 8) |
+ (bg_color->green & 0xff00) |
+ ((bg_color->blue & 0xff00) >> 8);
+ else
+ colorv = 0;
+
+ pwidth = gdk_pixbuf_get_width (src_pixbuf);
+ pheight = gdk_pixbuf_get_height (src_pixbuf);
+
+ for (cy = 0; cy < field_geom->height; cy += pheight) {
+ for (cx = 0; cx < field_geom->width; cx += pwidth) {
+ if (need_composite && !use_simple)
+ gdk_pixbuf_composite
+ (src_pixbuf, dest_pixbuf,
+ cx, cy,
+ MIN (pwidth, field_geom->width - cx),
+ MIN (pheight, field_geom->height - cy),
+ cx, cy,
+ 1.0, 1.0,
+ GDK_INTERP_BILINEAR,
+ alpha);
+ else if (need_composite && use_simple)
+ gdk_pixbuf_composite_color
+ (src_pixbuf, dest_pixbuf,
+ cx, cy,
+ MIN (pwidth, field_geom->width - cx),
+ MIN (pheight, field_geom->height - cy),
+ cx, cy,
+ 1.0, 1.0,
+ GDK_INTERP_BILINEAR,
+ alpha,
+ 65536, 65536, 65536,
+ colorv, colorv);
+ else
+ gdk_pixbuf_copy_area
+ (src_pixbuf,
+ 0, 0,
+ MIN (pwidth, field_geom->width - cx),
+ MIN (pheight, field_geom->height - cy),
+ dest_pixbuf,
+ cx, cy);
+ }
+ }
+
+ return dest_pixbuf;
+}
+
+/* Fill a raw character array with gradient data; the data may then be imported
+ * into a GdkPixbuf
+ */
+
+static void
+fill_gradient (GdkPixbuf *pixbuf,
+ GdkColor *c1,
+ GdkColor *c2,
+ orientation_t orientation)
+{
+ int i, j;
+ int dr, dg, db;
+ int gs1;
+ int vc = ((orientation == ORIENTATION_HORIZ) || (c1 == c2));
+ int w = gdk_pixbuf_get_width (pixbuf);
+ int h = gdk_pixbuf_get_height (pixbuf);
+ guchar *b, *row;
+ guchar *d = gdk_pixbuf_get_pixels (pixbuf);
+ int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+#define R1 c1->red
+#define G1 c1->green
+#define B1 c1->blue
+#define R2 c2->red
+#define G2 c2->green
+#define B2 c2->blue
+
+ dr = R2 - R1;
+ dg = G2 - G1;
+ db = B2 - B1;
+
+ gs1 = (orientation == ORIENTATION_VERT) ? h-1 : w-1;
+
+ row = g_new (unsigned char, rowstride);
+
+ if (vc) {
+ b = row;
+ for (j = 0; j < w; j++) {
+ *b++ = (R1 + (j * dr) / gs1) >> 8;
+ *b++ = (G1 + (j * dg) / gs1) >> 8;
+ *b++ = (B1 + (j * db) / gs1) >> 8;
+ }
+ }
+
+ for (i = 0; i < h; i++) {
+ if (!vc) {
+ unsigned char cr, cg, cb;
+ cr = (R1 + (i * dr) / gs1) >> 8;
+ cg = (G1 + (i * dg) / gs1) >> 8;
+ cb = (B1 + (i * db) / gs1) >> 8;
+ b = row;
+ for (j = 0; j < w; j++) {
+ *b++ = cr;
+ *b++ = cg;
+ *b++ = cb;
+ }
+ }
+ memcpy (d, row, w * 3);
+ d += rowstride;
+ }
+
+#undef R1
+#undef G1
+#undef B1
+#undef R2
+#undef G2
+#undef B2
+
+ g_free (row);
+}
+
+/* Boolean predicates to assist optimization and rendering */
+
+/* Return TRUE iff the wallpaper filename or enabled settings have changed
+ * between old_prefs and new_prefs
+ */
+
+static gboolean
+need_wallpaper_load_p (const BGApplier *bg_applier, const BGPreferences *prefs)
+{
+ if (bg_applier->p->last_prefs == NULL)
+ return TRUE;
+ else if (prefs->wallpaper_enabled && bg_applier->p->wallpaper_pixbuf == NULL)
+ return TRUE;
+ else if (bg_applier->p->last_prefs->wallpaper_enabled != prefs->wallpaper_enabled)
+ return TRUE;
+ else if (!bg_applier->p->last_prefs->wallpaper_enabled && !prefs->wallpaper_enabled)
+ return FALSE;
+ else if (strcmp (bg_applier->p->last_prefs->wallpaper_filename, prefs->wallpaper_filename))
+ return TRUE;
+ else if (bg_applier->p->last_prefs->wallpaper_type == prefs->wallpaper_type)
+ return FALSE;
+ else if (bg_applier->p->last_prefs->wallpaper_type != WPTYPE_TILED &&
+ bg_applier->p->last_prefs->wallpaper_type != WPTYPE_CENTERED)
+ return TRUE;
+ else if (prefs->wallpaper_type != WPTYPE_TILED &&
+ prefs->wallpaper_type != WPTYPE_CENTERED)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* Return TRUE iff we need to create a new root pixmap */
+
+static gboolean
+need_root_pixmap_p (const BGApplier *bg_applier, const BGPreferences *prefs)
+{
+ if (bg_applier->p->pixmap == NULL)
+ return TRUE;
+ else if (prefs->wallpaper_enabled == FALSE && prefs->gradient_enabled == FALSE)
+ return FALSE;
+ else if (bg_applier->p->last_prefs == NULL)
+ return TRUE;
+ else if (bg_applier->p->last_prefs->wallpaper_enabled == FALSE && bg_applier->p->last_prefs->gradient_enabled == FALSE)
+ return TRUE;
+ else if (render_small_pixmap_p (bg_applier->p->last_prefs) != render_small_pixmap_p (prefs))
+ return TRUE;
+ else if (!render_small_pixmap_p (bg_applier->p->last_prefs) &&
+ !render_small_pixmap_p (prefs))
+ return FALSE;
+ else if (bg_applier->p->last_prefs->orientation != prefs->orientation)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* Return TRUE iff the colors are equal */
+
+/* Return TRUE iff the wallpaper completely covers the colors in the given
+ * bg_preferences structure, assuming we have already loaded the wallpaper pixbuf */
+
+static gboolean
+wallpaper_full_cover_p (const BGApplier *bg_applier, const BGPreferences *prefs)
+{
+ gint swidth, sheight;
+ gint pwidth, pheight;
+ gdouble asp1, asp2;
+
+ if (bg_applier->p->wallpaper_pixbuf == NULL)
+ return FALSE;
+ else if (gdk_pixbuf_get_has_alpha (bg_applier->p->wallpaper_pixbuf))
+ return FALSE;
+ else if (prefs->wallpaper_type == WPTYPE_TILED)
+ return TRUE;
+ else if (prefs->wallpaper_type == WPTYPE_STRETCHED)
+ return TRUE;
+
+ gdk_drawable_get_size (bg_applier->p->root_window, &swidth, &sheight);
+ pwidth = gdk_pixbuf_get_width (bg_applier->p->wallpaper_pixbuf);
+ pheight = gdk_pixbuf_get_height (bg_applier->p->wallpaper_pixbuf);
+
+ if (prefs->wallpaper_type == WPTYPE_CENTERED) {
+ if (pwidth >= swidth && pheight >= sheight)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ else if (prefs->wallpaper_type == WPTYPE_SCALED) {
+ asp1 = (gdouble) swidth / (gdouble) sheight;
+ asp2 = (gdouble) pwidth / (gdouble) pheight;
+
+ if (swidth * (asp1 - asp2) < 1 && swidth * (asp2 - asp1) < 1)
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+/* Return TRUE if we can optimize the rendering by using a small thin pixmap */
+
+static gboolean
+render_small_pixmap_p (const BGPreferences *prefs)
+{
+ return prefs->gradient_enabled && !prefs->wallpaper_enabled;
+}
+
+/* Create a persistent pixmap. We create a separate display
+ * and set the closedown mode on it to RetainPermanent
+ */
+static GdkPixmap *
+make_root_pixmap (GdkScreen *screen, gint width, gint height)
+{
+ Display *display;
+ char *display_name;
+ Pixmap result;
+ GdkPixmap *gdk_pixmap;
+ int screen_num;
+
+ screen_num = gdk_screen_get_number (screen);
+
+ gdk_flush ();
+
+ display_name = DisplayString (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()));
+
+ display = XOpenDisplay (display_name);
+
+ if (display == NULL) {
+ g_warning ("Unable to open display '%s' when setting background pixmap\n",
+ (display_name) ? display_name : "NULL");
+ return NULL;
+ }
+
+ XSetCloseDownMode (display, RetainPermanent);
+
+ result = XCreatePixmap (display,
+ RootWindow (display, screen_num),
+ width, height,
+ DefaultDepth (display, screen_num));
+
+ XCloseDisplay (display);
+
+ gdk_pixmap = gdk_pixmap_foreign_new (result);
+ gdk_drawable_set_colormap (GDK_DRAWABLE (gdk_pixmap),
+ gdk_drawable_get_colormap (gdk_screen_get_root_window (screen)));
+
+ return gdk_pixmap;
+}
+
+/* Set the root pixmap, and properties pointing to it. We
+ * do this atomically with XGrabServer to make sure that
+ * we won't leak the pixmap if somebody else it setting
+ * it at the same time. (This assumes that they follow the
+ * same conventions we do)
+ */
+
+static void
+set_root_pixmap (GdkPixmap *pixmap, GdkScreen *screen)
+{
+ Atom type;
+ gulong nitems, bytes_after;
+ gint format;
+ guchar *data_esetroot;
+ Pixmap pixmap_id;
+ Display *display;
+ int screen_num;
+
+ /* Final check to see if nautilus is running. If it is, we don't
+ touch the root pixmap at all. */
+ if (is_nautilus_running ())
+ return;
+
+ screen_num = gdk_screen_get_number (screen);
+
+ if (pixmap != NULL)
+ pixmap_id = GDK_WINDOW_XWINDOW (pixmap);
+ else
+ pixmap_id = 0;
+
+ display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+ XGrabServer (display);
+
+ XGetWindowProperty (display, RootWindow (display, screen_num),
+ XInternAtom (display, "ESETROOT_PMAP_ID", False),
+ 0L, 1L, False, XA_PIXMAP,
+ &type, &format, &nitems, &bytes_after,
+ &data_esetroot);
+
+ if (type == XA_PIXMAP) {
+ if (format == 32 && nitems == 1) {
+ Pixmap old_pixmap;
+
+ old_pixmap = *((Pixmap *) data_esetroot);
+
+ if (pixmap != NULL && old_pixmap != pixmap_id)
+ XKillClient (display, old_pixmap);
+ else if (pixmap == NULL)
+ pixmap_id = old_pixmap;
+ }
+
+ XFree (data_esetroot);
+ }
+
+ if (pixmap != NULL) {
+ XChangeProperty (display, RootWindow (display, screen_num),
+ XInternAtom (display, "ESETROOT_PMAP_ID", FALSE),
+ XA_PIXMAP, 32, PropModeReplace,
+ (guchar *) &pixmap_id, 1);
+ XChangeProperty (display, RootWindow (display, screen_num),
+ XInternAtom (display, "_XROOTPMAP_ID", FALSE),
+ XA_PIXMAP, 32, PropModeReplace,
+ (guchar *) &pixmap_id, 1);
+
+ XSetWindowBackgroundPixmap (display, RootWindow (display, screen_num),
+ pixmap_id);
+ } else if (pixmap == NULL) {
+ XDeleteProperty (display, RootWindow (display, screen_num),
+ XInternAtom (display, "ESETROOT_PMAP_ID", FALSE));
+ XDeleteProperty (display, RootWindow (display, screen_num),
+ XInternAtom (display, "_XROOTPMAP_ID", FALSE));
+ }
+
+ XClearWindow (display, RootWindow (display, screen_num));
+ XUngrabServer (display);
+ XFlush (display);
+}
+
+static gboolean
+is_nautilus_running (void)
+{
+ Atom window_id_atom;
+ Window nautilus_xid;
+ Atom actual_type;
+ int actual_format;
+ unsigned long nitems, bytes_after;
+ unsigned char *data;
+ int retval;
+ Atom wmclass_atom;
+ gboolean running;
+ gint error;
+
+ window_id_atom = XInternAtom (GDK_DISPLAY (),
+ "NAUTILUS_DESKTOP_WINDOW_ID", True);
+
+ if (window_id_atom == None) return FALSE;
+
+ retval = XGetWindowProperty (GDK_DISPLAY (), GDK_ROOT_WINDOW (),
+ window_id_atom, 0, 1, False, XA_WINDOW,
+ &actual_type, &actual_format, &nitems,
+ &bytes_after, &data);
+
+ if (data != NULL) {
+ nautilus_xid = *(Window *) data;
+ XFree (data);
+ } else {
+ return FALSE;
+ }
+
+ if (actual_type != XA_WINDOW) return FALSE;
+ if (actual_format != 32) return FALSE;
+
+ wmclass_atom = XInternAtom (GDK_DISPLAY (), "WM_CLASS", False);
+
+ gdk_error_trap_push ();
+
+ retval = XGetWindowProperty (GDK_DISPLAY (), nautilus_xid,
+ wmclass_atom, 0, 24, False, XA_STRING,
+ &actual_type, &actual_format, &nitems,
+ &bytes_after, &data);
+
+ error = gdk_error_trap_pop ();
+
+ if (error == BadWindow) return FALSE;
+
+ if (actual_type == XA_STRING &&
+ nitems == 24 &&
+ bytes_after == 0 &&
+ actual_format == 8 &&
+ data != NULL &&
+ !strcmp ((char *)data, "desktop_window") &&
+ !strcmp ((char *)data + strlen ((char *)data) + 1, "Nautilus"))
+ running = TRUE;
+ else
+ running = FALSE;
+
+ if (data != NULL)
+ XFree (data);
+
+ return running;
+}
+
+static gboolean
+cleanup_cb (BGApplier *bg_applier)
+{
+ g_message ("cleanup_cb: Enter");
+
+ if (bg_applier->p->wallpaper_pixbuf != NULL) {
+ g_object_unref (G_OBJECT (bg_applier->p->wallpaper_pixbuf));
+ bg_applier->p->wallpaper_pixbuf = NULL;
+ }
+
+ if (bg_applier->p->pixbuf != NULL) {
+ g_object_unref (G_OBJECT (bg_applier->p->pixbuf));
+ bg_applier->p->pixbuf = NULL;
+ }
+
+ bg_applier->p->timeout = 0;
+
+ return FALSE;
+}
+
+static void
+preview_realized_cb (GtkWidget *preview, BGApplier *bg_applier)
+{
+ GdkPixmap *pixmap;
+
+ /* Only draw clean image if no pref set yet */
+ if (bg_applier->p->last_prefs)
+ return;
+
+ gtk_image_get_pixmap (GTK_IMAGE (preview), &pixmap, NULL);
+ if (!pixmap) {
+ pixmap = gdk_pixmap_new (preview->window,
+ bg_applier->p->render_geom.width,
+ bg_applier->p->render_geom.height,
+ -1);
+ gtk_image_set_from_pixmap (GTK_IMAGE (preview), pixmap, NULL);
+ }
+
+ gdk_draw_rectangle (pixmap,
+ preview->style->bg_gc[preview->state],
+ TRUE,
+ bg_applier->p->render_geom.x,
+ bg_applier->p->render_geom.y,
+ bg_applier->p->render_geom.width,
+ bg_applier->p->render_geom.height);
+}
+
diff --git a/gui/simple-greeter/libbackground/applier.h b/gui/simple-greeter/libbackground/applier.h
new file mode 100644
index 00000000..e058123f
--- /dev/null
+++ b/gui/simple-greeter/libbackground/applier.h
@@ -0,0 +1,76 @@
+/* -*- mode: c; style: linux -*- */
+
+/* applier.h
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Written by Bradford Hovinen <hovinen@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __APPLIER_H
+#define __APPLIER_H
+
+#include <gtk/gtk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include <X11/Xlib.h>
+
+#include "preferences.h"
+
+#define BG_APPLIER(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, bg_applier_get_type (), BGApplier)
+#define BG_APPLIER_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, bg_applier_get_type (), BGApplierClass)
+#define IS_BG_APPLIER(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, bg_applier_get_type ())
+
+typedef struct _BGApplier BGApplier;
+typedef struct _BGApplierClass BGApplierClass;
+
+typedef struct _BGApplierPrivate BGApplierPrivate;
+
+typedef enum _BGApplierType {
+ BG_APPLIER_ROOT, BG_APPLIER_PREVIEW
+} BGApplierType;
+
+struct _BGApplier
+{
+ GObject object;
+ BGApplierPrivate *p;
+};
+
+struct _BGApplierClass
+{
+ GObjectClass klass;
+};
+
+GType bg_applier_get_type (void);
+
+GObject *bg_applier_new (BGApplierType type);
+GObject *bg_applier_new_at_size (BGApplierType type,
+ const guint width,
+ const guint height);
+GObject *bg_applier_new_for_screen (BGApplierType type,
+ GdkScreen *screen);
+
+void bg_applier_apply_prefs (BGApplier *bg_applier,
+ const BGPreferences *prefs);
+
+gboolean bg_applier_render_color_p (const BGApplier *bg_applier,
+ const BGPreferences *prefs);
+
+GtkWidget *bg_applier_get_preview_widget (BGApplier *bg_applier);
+GdkPixbuf *bg_applier_get_wallpaper_pixbuf (BGApplier *bg_applier);
+
+#endif /* __APPLIER_H */
diff --git a/gui/simple-greeter/libbackground/preferences.c b/gui/simple-greeter/libbackground/preferences.c
new file mode 100644
index 00000000..9090657f
--- /dev/null
+++ b/gui/simple-greeter/libbackground/preferences.c
@@ -0,0 +1,510 @@
+/* -*- mode: c; style: linux -*- */
+
+/* preferences.c
+ * Copyright (C) 2001 Ximian, Inc.
+ *
+ * Written by Bradford Hovinen <hovinen@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+#include <gdk/gdk.h>
+
+#include "preferences.h"
+
+static GObjectClass *parent_class;
+
+static void bg_preferences_init (BGPreferences *prefs,
+ BGPreferencesClass *class);
+static void bg_preferences_class_init (BGPreferencesClass *class);
+
+static void bg_preferences_finalize (GObject *object);
+
+static GdkColor *read_color_from_string (const gchar *string);
+static orientation_t read_orientation_from_string (const gchar *string);
+static wallpaper_type_t read_wptype_from_string (const gchar *string);
+
+static GEnumValue _bg_wptype_values[] = {
+ { WPTYPE_TILED, "WPTYPE_TILED", "wallpaper"},
+ { WPTYPE_CENTERED, "WPTYPE_CENTERED", "centered"},
+ { WPTYPE_SCALED, "WPTYPE_SCALED", "scaled"},
+ { WPTYPE_STRETCHED, "WPTYPE_STRETCHED", "stretched"},
+ { WPTYPE_ZOOM, "WPTYPE_ZOOM", "zoom"},
+ { WPTYPE_NONE, "WPTYPE_NONE", "none"},
+ { 0, NULL, NULL }
+};
+
+static GEnumValue _bg_orientation_values[] = {
+ { ORIENTATION_SOLID, "ORIENTATION_SOLID", "solid"},
+ { ORIENTATION_HORIZ, "ORIENTATION_HORIZ", "horizontal-gradient"},
+ { ORIENTATION_VERT, "ORIENTATION_VERT", "vertical-gradient"},
+ { 0, NULL, NULL }
+};
+
+GType
+bg_preferences_wptype_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ type = g_enum_register_static ("BgPreferencesWptype",
+ _bg_wptype_values);
+ }
+
+ return type;
+}
+
+GType
+bg_preferences_orientation_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ type = g_enum_register_static ("BgPreferencesOrientation",
+ _bg_orientation_values);
+ }
+
+ return type;
+}
+
+GType
+bg_preferences_get_type (void)
+{
+ static GType bg_preferences_type = 0;
+
+ if (!bg_preferences_type) {
+ GTypeInfo bg_preferences_info = {
+ sizeof (BGPreferencesClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) bg_preferences_class_init,
+ NULL,
+ NULL,
+ sizeof (BGPreferences),
+ 0,
+ (GInstanceInitFunc) bg_preferences_init,
+ };
+
+ bg_preferences_type =
+ g_type_register_static (G_TYPE_OBJECT, "BGPreferences", &bg_preferences_info, 0);
+ }
+
+ return bg_preferences_type;
+}
+
+static void
+bg_preferences_init (BGPreferences *prefs,
+ BGPreferencesClass *class)
+{
+ prefs->frozen = FALSE;
+
+ /* Load default values */
+ prefs->color1 = read_color_from_string ("#39374b");
+ prefs->color2 = read_color_from_string ("#42528f");
+ prefs->enabled = TRUE;
+ prefs->wallpaper_enabled = FALSE;
+ prefs->gradient_enabled = TRUE;
+ prefs->orientation = ORIENTATION_VERT;
+ prefs->wallpaper_type = WPTYPE_TILED;
+ prefs->wallpaper_filename = NULL;
+ prefs->wallpaper_sel_path = g_strdup (g_get_home_dir ());
+ prefs->auto_apply = TRUE;
+ prefs->wallpapers = NULL;
+ prefs->adjust_opacity = TRUE;
+ prefs->opacity = 255;
+}
+
+static void
+bg_preferences_class_init (BGPreferencesClass *class)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) class;
+ object_class->finalize = bg_preferences_finalize;
+
+ parent_class =
+ G_OBJECT_CLASS (g_type_class_ref (G_TYPE_OBJECT));
+}
+
+GObject *
+bg_preferences_new (void)
+{
+ GObject *object;
+
+ object = g_object_new (bg_preferences_get_type (), NULL);
+ BG_PREFERENCES (object)->enabled = TRUE;
+
+ return object;
+}
+
+GObject *
+bg_preferences_clone (const BGPreferences *prefs)
+{
+ GObject *object;
+ BGPreferences *new_prefs;
+
+ g_return_val_if_fail (prefs != NULL, NULL);
+ g_return_val_if_fail (IS_BG_PREFERENCES (prefs), NULL);
+
+ object = bg_preferences_new ();
+
+ new_prefs = BG_PREFERENCES (object);
+
+ new_prefs->enabled = prefs->enabled;
+ new_prefs->gradient_enabled = prefs->gradient_enabled;
+ new_prefs->wallpaper_enabled = prefs->wallpaper_enabled;
+ new_prefs->orientation = prefs->orientation;
+ new_prefs->wallpaper_type = prefs->wallpaper_type;
+
+ if (new_prefs->color1 != NULL)
+ gdk_color_free (new_prefs->color1);
+ new_prefs->color1 = (prefs->color1 != NULL)
+ ? gdk_color_copy (prefs->color1) : NULL;
+
+ if (new_prefs->color2 != NULL)
+ gdk_color_free (new_prefs->color2);
+ new_prefs->color2 = (prefs->color2 != NULL)
+ ? gdk_color_copy (prefs->color2) : NULL;
+
+ if (new_prefs->wallpaper_filename != NULL)
+ g_free (new_prefs->wallpaper_filename);
+ new_prefs->wallpaper_filename = g_strdup (prefs->wallpaper_filename);
+
+ if (new_prefs->wallpaper_sel_path != NULL)
+ g_free (new_prefs->wallpaper_sel_path);
+ new_prefs->wallpaper_sel_path = g_strdup (prefs->wallpaper_sel_path);;
+
+ new_prefs->auto_apply = prefs->auto_apply;
+ new_prefs->adjust_opacity = prefs->adjust_opacity;
+ new_prefs->opacity = prefs->opacity;
+
+ return object;
+}
+
+static void
+bg_preferences_finalize (GObject *object)
+{
+ BGPreferences *prefs;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_BG_PREFERENCES (object));
+
+ prefs = BG_PREFERENCES (object);
+
+ g_free (prefs->wallpaper_filename);
+ prefs->wallpaper_filename = NULL;
+
+ g_free (prefs->wallpaper_sel_path);
+ prefs->wallpaper_sel_path = NULL;
+
+ if (prefs->color1 != NULL) {
+ gdk_color_free (prefs->color1);
+ prefs->color1 = NULL;
+ }
+ if (prefs->color2 != NULL) {
+ gdk_color_free (prefs->color2);
+ prefs->color2 = NULL;
+ }
+
+ parent_class->finalize (object);
+}
+
+void
+bg_preferences_load (BGPreferences *prefs)
+{
+ GConfClient *client;
+ GError *error = NULL;
+ char *tmp;
+
+ g_return_if_fail (prefs != NULL);
+ g_return_if_fail (IS_BG_PREFERENCES (prefs));
+
+ client = gconf_client_get_default ();
+
+ prefs->enabled = gconf_client_get_bool (client, BG_PREFERENCES_DRAW_BACKGROUND, &error);
+ tmp = gconf_client_get_string (client, BG_PREFERENCES_PICTURE_FILENAME, &error);
+ if (tmp) {
+ if (g_utf8_validate (tmp, -1, NULL) &&
+ g_file_test (tmp, G_FILE_TEST_EXISTS))
+ prefs->wallpaper_filename = g_strdup (tmp);
+ else
+ prefs->wallpaper_filename = g_filename_from_utf8 (tmp, -1, NULL,
+ NULL, NULL);
+ }
+ g_free (tmp);
+
+ if (prefs->color1 != NULL)
+ gdk_color_free (prefs->color1);
+ tmp = gconf_client_get_string (client, BG_PREFERENCES_PRIMARY_COLOR, &error);
+ prefs->color1 = read_color_from_string (tmp);
+ g_free (tmp);
+
+ if (prefs->color2 != NULL)
+ gdk_color_free (prefs->color2);
+ tmp = gconf_client_get_string (client, BG_PREFERENCES_SECONDARY_COLOR, &error);
+ prefs->color2 = read_color_from_string (tmp);
+ g_free (tmp);
+
+ prefs->opacity = gconf_client_get_int (client, BG_PREFERENCES_PICTURE_OPACITY, &error);
+ if (prefs->opacity >= 100 || prefs->opacity < 0)
+ prefs->adjust_opacity = FALSE;
+
+ tmp = gconf_client_get_string (client, BG_PREFERENCES_COLOR_SHADING_TYPE, &error);
+ prefs->orientation = read_orientation_from_string (tmp);
+ g_free (tmp);
+
+ if (prefs->orientation == ORIENTATION_SOLID)
+ prefs->gradient_enabled = FALSE;
+ else
+ prefs->gradient_enabled = TRUE;
+
+ tmp = gconf_client_get_string (client, BG_PREFERENCES_PICTURE_OPTIONS, &error);
+ prefs->wallpaper_type = read_wptype_from_string (tmp);
+ g_free (tmp);
+
+ if (prefs->wallpaper_type == WPTYPE_UNSET) {
+ prefs->wallpaper_enabled = FALSE;
+ prefs->wallpaper_type = WPTYPE_CENTERED;
+ } else {
+ prefs->wallpaper_enabled = TRUE;
+ }
+
+ g_object_unref (client);
+}
+
+/* Parse the event name given (the event being notification of a property having
+ * changed and apply that change to the bg_preferences structure. Eliminates the
+ * need to reload the structure entirely on every event notification
+ */
+
+void
+bg_preferences_merge_entry (BGPreferences *prefs,
+ const GConfEntry *entry)
+{
+ const GConfValue *value = gconf_entry_get_value (entry);
+
+ g_return_if_fail (prefs != NULL);
+ g_return_if_fail (IS_BG_PREFERENCES (prefs));
+
+ if (!strcmp (entry->key, BG_PREFERENCES_PICTURE_OPTIONS)) {
+ wallpaper_type_t wallpaper_type = read_wptype_from_string (gconf_value_get_string (value));
+ if (wallpaper_type == WPTYPE_UNSET) {
+ prefs->wallpaper_enabled = FALSE;
+ } else {
+ prefs->wallpaper_type = wallpaper_type;
+ prefs->wallpaper_enabled = TRUE;
+ }
+ }
+ else if (!strcmp (entry->key, BG_PREFERENCES_PICTURE_FILENAME)) {
+ const char *tmp;
+
+ tmp = gconf_value_get_string (value);
+ if (g_utf8_validate (tmp, -1, NULL) &&
+ g_file_test (tmp, G_FILE_TEST_EXISTS))
+ prefs->wallpaper_filename = g_strdup (tmp);
+ else
+ prefs->wallpaper_filename = g_filename_from_utf8 (tmp, -1,
+ NULL,
+ NULL,
+ NULL);
+
+ if (prefs->wallpaper_filename != NULL &&
+ strcmp (prefs->wallpaper_filename, "") != 0 &&
+ strcmp (prefs->wallpaper_filename, "(none)") != 0)
+ prefs->wallpaper_enabled = TRUE;
+ else
+ prefs->wallpaper_enabled = FALSE;
+ }
+ else if (!strcmp (entry->key, BG_PREFERENCES_PRIMARY_COLOR)) {
+ if (prefs->color1 != NULL)
+ gdk_color_free (prefs->color1);
+ prefs->color1 = read_color_from_string (gconf_value_get_string (value));
+ }
+ else if (!strcmp (entry->key, BG_PREFERENCES_SECONDARY_COLOR)) {
+ if (prefs->color2 != NULL)
+ gdk_color_free (prefs->color2);
+ prefs->color2 = read_color_from_string (gconf_value_get_string (value));
+ }
+ else if (!strcmp (entry->key, BG_PREFERENCES_PICTURE_OPACITY)) {
+ prefs->opacity = gconf_value_get_int (value);
+
+ if (prefs->opacity >= 100)
+ prefs->adjust_opacity = FALSE;
+ }
+ else if (!strcmp (entry->key, BG_PREFERENCES_COLOR_SHADING_TYPE)) {
+ prefs->orientation = read_orientation_from_string (gconf_value_get_string (value));
+
+ if (prefs->orientation == ORIENTATION_SOLID)
+ prefs->gradient_enabled = FALSE;
+ else
+ prefs->gradient_enabled = TRUE;
+ }
+ else if (!strcmp (entry->key, BG_PREFERENCES_DRAW_BACKGROUND)) {
+ if (gconf_value_get_bool (value) &&
+ (prefs->wallpaper_filename != NULL) &&
+ strcmp (prefs->wallpaper_filename, "") != 0 &&
+ strcmp (prefs->wallpaper_filename, "(none)") != 0)
+ prefs->enabled = TRUE;
+ else
+ prefs->enabled = FALSE;
+ } else {
+ g_warning ("%s: Unknown property: %s", G_GNUC_FUNCTION, entry->key);
+ }
+}
+
+static wallpaper_type_t
+read_wptype_from_string (const gchar *string)
+{
+ wallpaper_type_t type = WPTYPE_UNSET;
+
+ if (string) {
+ if (!strncmp (string, "wallpaper", sizeof ("wallpaper"))) {
+ type = WPTYPE_TILED;
+ } else if (!strncmp (string, "centered", sizeof ("centered"))) {
+ type = WPTYPE_CENTERED;
+ } else if (!strncmp (string, "scaled", sizeof ("scaled"))) {
+ type = WPTYPE_SCALED;
+ } else if (!strncmp (string, "stretched", sizeof ("stretched"))) {
+ type = WPTYPE_STRETCHED;
+ } else if (!strncmp (string, "zoom", sizeof ("zoom"))) {
+ type = WPTYPE_ZOOM;
+ }
+ }
+
+ return type;
+}
+
+static orientation_t
+read_orientation_from_string (const gchar *string)
+{
+ orientation_t type = ORIENTATION_SOLID;
+
+ if (string) {
+ if (!strncmp (string, "vertical-gradient", sizeof ("vertical-gradient"))) {
+ type = ORIENTATION_VERT;
+ } else if (!strncmp (string, "horizontal-gradient", sizeof ("horizontal-gradient"))) {
+ type = ORIENTATION_HORIZ;
+ }
+ }
+
+ return type;
+}
+
+static GdkColor *
+read_color_from_string (const gchar *string)
+{
+ GdkColor color;
+
+ /* If all else fails use black */
+ if (string == NULL || !gdk_color_parse (string, &color))
+ gdk_color_parse ("black", &color);
+ gdk_rgb_find_color (gdk_rgb_get_colormap (), &color);
+ return gdk_color_copy (&color);
+}
+
+const gchar*
+bg_preferences_get_wptype_as_string (wallpaper_type_t wp)
+{
+ switch (wp)
+ {
+ case WPTYPE_TILED:
+ return "wallpaper";
+ case WPTYPE_CENTERED:
+ return "centered";
+ case WPTYPE_SCALED:
+ return "scaled";
+ case WPTYPE_STRETCHED:
+ return "stretched";
+ case WPTYPE_ZOOM:
+ return "zoom";
+ case WPTYPE_NONE:
+ return "none";
+ case WPTYPE_UNSET:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+const gchar*
+bg_preferences_get_orientation_as_string (orientation_t o)
+{
+ switch (o)
+ {
+ case ORIENTATION_SOLID:
+ return "solid";
+ case ORIENTATION_HORIZ:
+ return "horizontal-gradient";
+ case ORIENTATION_VERT:
+ return "vertical-gradient";
+ }
+
+ return NULL;
+}
+
+void
+bg_preferences_save (BGPreferences *prefs)
+{
+ GConfChangeSet *cs;
+ gchar *tmp;
+ GConfClient *client;
+
+ g_return_if_fail (prefs != NULL);
+ g_return_if_fail (IS_BG_PREFERENCES (prefs));
+
+ client = gconf_client_get_default();
+
+ cs = gconf_change_set_new ();
+ gconf_change_set_set_bool (cs, BG_PREFERENCES_DRAW_BACKGROUND, prefs->enabled);
+ if (prefs->wallpaper_enabled)
+ gconf_change_set_set_string (cs, BG_PREFERENCES_PICTURE_OPTIONS, bg_preferences_get_wptype_as_string (prefs->wallpaper_type));
+ else
+ gconf_change_set_set_string (cs, BG_PREFERENCES_PICTURE_OPTIONS, "none");
+
+ gconf_change_set_set_string (cs, BG_PREFERENCES_PICTURE_FILENAME, prefs->wallpaper_filename);
+
+ tmp = g_strdup_printf ("#%02x%02x%02x",
+ prefs->color1->red >> 8,
+ prefs->color1->green >> 8,
+ prefs->color1->blue >> 8);
+ gconf_change_set_set_string (cs, BG_PREFERENCES_PRIMARY_COLOR, tmp);
+ g_free (tmp);
+
+ tmp = g_strdup_printf ("#%02x%02x%02x",
+ prefs->color2->red >> 8,
+ prefs->color2->green >> 8,
+ prefs->color2->blue >> 8);
+ gconf_change_set_set_string (cs, BG_PREFERENCES_SECONDARY_COLOR, tmp);
+ g_free (tmp);
+
+ gconf_change_set_set_string (cs, BG_PREFERENCES_COLOR_SHADING_TYPE, bg_preferences_get_orientation_as_string (prefs->orientation));
+
+ gconf_client_commit_change_set (client, cs, TRUE, NULL);
+ gconf_change_set_unref (cs);
+ g_object_unref (client);
+}
+
+
diff --git a/gui/simple-greeter/libbackground/preferences.h b/gui/simple-greeter/libbackground/preferences.h
new file mode 100644
index 00000000..30fb7df1
--- /dev/null
+++ b/gui/simple-greeter/libbackground/preferences.h
@@ -0,0 +1,108 @@
+/* -*- mode: c; style: linux -*- */
+
+/* preferences.h
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Written by Bradford Hovinen <hovinen@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __BGPREFERENCES_H
+#define __BGPREFERENCES_H
+
+#include <glib-object.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gconf/gconf-client.h>
+
+#define BG_PREFERENCES(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, bg_preferences_get_type (), BGPreferences)
+#define BG_PREFERENCES_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, bg_preferences_get_type (), BGPreferencesClass)
+#define IS_BG_PREFERENCES(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, bg_preferences_get_type ())
+
+#define BG_PREFERENCES_DRAW_BACKGROUND "/desktop/gnome/background/draw_background"
+#define BG_PREFERENCES_PRIMARY_COLOR "/desktop/gnome/background/primary_color"
+#define BG_PREFERENCES_SECONDARY_COLOR "/desktop/gnome/background/secondary_color"
+#define BG_PREFERENCES_COLOR_SHADING_TYPE "/desktop/gnome/background/color_shading_type"
+#define BG_PREFERENCES_PICTURE_OPTIONS "/desktop/gnome/background/picture_options"
+#define BG_PREFERENCES_PICTURE_OPACITY "/desktop/gnome/background/picture_opacity"
+#define BG_PREFERENCES_PICTURE_FILENAME "/desktop/gnome/background/picture_filename"
+
+
+typedef struct _BGPreferences BGPreferences;
+typedef struct _BGPreferencesClass BGPreferencesClass;
+
+typedef enum _orientation_t {
+ ORIENTATION_SOLID = 0,
+ ORIENTATION_HORIZ,
+ ORIENTATION_VERT
+} orientation_t;
+
+typedef enum _wallpaper_type_t {
+ WPTYPE_TILED = 0, WPTYPE_CENTERED, WPTYPE_SCALED,
+ WPTYPE_STRETCHED, WPTYPE_ZOOM, WPTYPE_NONE,
+ WPTYPE_UNSET
+} wallpaper_type_t;
+
+struct _BGPreferences
+{
+ GObject object;
+
+ gint frozen;
+ gboolean auto_apply;
+ guint timeout_id;
+
+ gboolean enabled;
+ gboolean gradient_enabled;
+ gboolean wallpaper_enabled;
+ orientation_t orientation;
+ wallpaper_type_t wallpaper_type;
+
+ GdkColor *color1;
+ GdkColor *color2;
+
+ gchar *wallpaper_filename;
+ gchar *wallpaper_sel_path;
+
+ GSList *wallpapers;
+
+ gboolean adjust_opacity;
+ gint opacity;
+};
+
+struct _BGPreferencesClass
+{
+ GObjectClass klass;
+};
+
+GType bg_preferences_get_type (void);
+
+GObject *bg_preferences_new (void);
+GObject *bg_preferences_clone (const BGPreferences *prefs);
+
+void bg_preferences_load (BGPreferences *prefs);
+
+void bg_preferences_merge_entry (BGPreferences *prefs,
+ const GConfEntry *entry);
+
+void bg_preferences_save (BGPreferences *prefs);
+
+const gchar *bg_preferences_get_wptype_as_string (wallpaper_type_t wp);
+const gchar *bg_preferences_get_orientation_as_string (orientation_t o);
+GType bg_preferences_wptype_get_type (void);
+GType bg_preferences_orientation_get_type (void);
+
+
+#endif /* __PREFERENCES_H */
diff --git a/gui/simple-greeter/libnotificationarea/na-marshal.c b/gui/simple-greeter/libnotificationarea/na-marshal.c
deleted file mode 100644
index 7cbaf722..00000000
--- a/gui/simple-greeter/libnotificationarea/na-marshal.c
+++ /dev/null
@@ -1,165 +0,0 @@
-#include "na-marshal.h"
-
-#include <glib-object.h>
-
-
-#ifdef G_ENABLE_DEBUG
-#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v)
-#define g_marshal_value_peek_char(v) g_value_get_char (v)
-#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v)
-#define g_marshal_value_peek_int(v) g_value_get_int (v)
-#define g_marshal_value_peek_uint(v) g_value_get_uint (v)
-#define g_marshal_value_peek_long(v) g_value_get_long (v)
-#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v)
-#define g_marshal_value_peek_int64(v) g_value_get_int64 (v)
-#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v)
-#define g_marshal_value_peek_enum(v) g_value_get_enum (v)
-#define g_marshal_value_peek_flags(v) g_value_get_flags (v)
-#define g_marshal_value_peek_float(v) g_value_get_float (v)
-#define g_marshal_value_peek_double(v) g_value_get_double (v)
-#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v)
-#define g_marshal_value_peek_param(v) g_value_get_param (v)
-#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v)
-#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v)
-#define g_marshal_value_peek_object(v) g_value_get_object (v)
-#else /* !G_ENABLE_DEBUG */
-/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API.
- * Do not access GValues directly in your code. Instead, use the
- * g_value_get_*() functions
- */
-#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
-#define g_marshal_value_peek_char(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_int(v) (v)->data[0].v_int
-#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint
-#define g_marshal_value_peek_long(v) (v)->data[0].v_long
-#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong
-#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64
-#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64
-#define g_marshal_value_peek_enum(v) (v)->data[0].v_long
-#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong
-#define g_marshal_value_peek_float(v) (v)->data[0].v_float
-#define g_marshal_value_peek_double(v) (v)->data[0].v_double
-#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer
-#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer
-#endif /* !G_ENABLE_DEBUG */
-
-
-/* VOID:OBJECT,OBJECT (na-marshal.list:1) */
-void
-_na_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__OBJECT_OBJECT) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__OBJECT_OBJECT callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__OBJECT_OBJECT) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_object (param_values + 1),
- g_marshal_value_peek_object (param_values + 2),
- data2);
-}
-
-/* VOID:OBJECT,STRING,LONG,LONG (na-marshal.list:2) */
-void
-_na_marshal_VOID__OBJECT_STRING_LONG_LONG (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__OBJECT_STRING_LONG_LONG) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- glong arg_3,
- glong arg_4,
- gpointer data2);
- register GMarshalFunc_VOID__OBJECT_STRING_LONG_LONG callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 5);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__OBJECT_STRING_LONG_LONG) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_object (param_values + 1),
- g_marshal_value_peek_string (param_values + 2),
- g_marshal_value_peek_long (param_values + 3),
- g_marshal_value_peek_long (param_values + 4),
- data2);
-}
-
-/* VOID:OBJECT,LONG (na-marshal.list:3) */
-void
-_na_marshal_VOID__OBJECT_LONG (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void (*GMarshalFunc_VOID__OBJECT_LONG) (gpointer data1,
- gpointer arg_1,
- glong arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__OBJECT_LONG callback;
- register GCClosure *cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__OBJECT_LONG) (marshal_data ? marshal_data : cc->callback);
-
- callback (data1,
- g_marshal_value_peek_object (param_values + 1),
- g_marshal_value_peek_long (param_values + 2),
- data2);
-}
-
diff --git a/gui/simple-greeter/libnotificationarea/na-marshal.h b/gui/simple-greeter/libnotificationarea/na-marshal.h
deleted file mode 100644
index 07918a11..00000000
--- a/gui/simple-greeter/libnotificationarea/na-marshal.h
+++ /dev/null
@@ -1,36 +0,0 @@
-
-#ifndef ___na_marshal_MARSHAL_H__
-#define ___na_marshal_MARSHAL_H__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-/* VOID:OBJECT,OBJECT (na-marshal.list:1) */
-extern void _na_marshal_VOID__OBJECT_OBJECT (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:OBJECT,STRING,LONG,LONG (na-marshal.list:2) */
-extern void _na_marshal_VOID__OBJECT_STRING_LONG_LONG (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-/* VOID:OBJECT,LONG (na-marshal.list:3) */
-extern void _na_marshal_VOID__OBJECT_LONG (GClosure *closure,
- GValue *return_value,
- guint n_param_values,
- const GValue *param_values,
- gpointer invocation_hint,
- gpointer marshal_data);
-
-G_END_DECLS
-
-#endif /* ___na_marshal_MARSHAL_H__ */
-