summaryrefslogtreecommitdiff
path: root/libnautilus-private/nautilus-directory-background.c
diff options
context:
space:
mode:
authorMike Engber <engber@src.gnome.org>2000-08-15 23:46:29 +0000
committerMike Engber <engber@src.gnome.org>2000-08-15 23:46:29 +0000
commit9057707471267a49aae183a6d6d64e771b692c7a (patch)
treee78dfe8bea96e15066aa6c9ce71cad8e8a9bb00a /libnautilus-private/nautilus-directory-background.c
parent732df6128747db7d26909f8f4cd296a442a3da17 (diff)
downloadnautilus-9057707471267a49aae183a6d6d64e771b692c7a.tar.gz
Third cut at syncing our desktop background with GNOME's (bug 1047) Now we
Third cut at syncing our desktop background with GNOME's (bug 1047) Now we update the GNOME desktop (root window) when we make changes. Still need to handle nautilus getting notified when the capplet makes changes. * libnautilus-extensions/nautilus-background.c: (nautilus_background_initialize_class), (nautilus_background_set_color_no_signal), (nautilus_background_set_color), (load_image_callback), (nautilus_background_set_image_uri_no_signal), (nautilus_background_set_image_uri), (nautilus_background_is_loaded), (nautilus_background_real_reset), (nautilus_background_receive_dropped_color): * libnautilus-extensions/nautilus-background.h: * libnautilus-extensions/nautilus-directory-background.c: (nautilus_directory_background_write_desktop_settings), (nautilus_directory_background_write_desktop_default_settings), (make_root_pixmap), (dispose_root_pixmap), (set_root_pixmap), (image_loaded_callback), (nautilus_directory_update_root_window), (background_changed_callback), (background_reset_callback):
Diffstat (limited to 'libnautilus-private/nautilus-directory-background.c')
-rw-r--r--libnautilus-private/nautilus-directory-background.c150
1 files changed, 144 insertions, 6 deletions
diff --git a/libnautilus-private/nautilus-directory-background.c b/libnautilus-private/nautilus-directory-background.c
index d5812cfbc..9f08dbbf7 100644
--- a/libnautilus-private/nautilus-directory-background.c
+++ b/libnautilus-private/nautilus-directory-background.c
@@ -36,13 +36,16 @@
#include "nautilus-theme.h"
#include "libnautilus-extensions/nautilus-gdk-extensions.h"
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+
static void background_changed_callback (NautilusBackground *background,
NautilusDirectory *directory);
static void directory_changed_callback (NautilusDirectory *directory,
NautilusBackground *background);
static void background_reset_callback (NautilusBackground *background,
NautilusDirectory *directory);
-
+
void
static nautilus_directory_background_set_desktop (NautilusBackground *background)
{
@@ -257,10 +260,6 @@ nautilus_directory_background_write_desktop_settings (char *color, char *image,
}
gnome_config_sync ();
-
- /* FIXME
- * Try to trick GNOME into re-reading the settings.
- */
}
static void
@@ -272,7 +271,138 @@ nautilus_directory_background_write_desktop_default_settings ()
nautilus_background_image_placement placement;
nautilus_directory_background_get_default_settings (TRUE, &color, &image, &placement, &combine);
nautilus_directory_background_write_desktop_settings (color, image, placement, combine);
-}
+}
+
+/* Create a persistant pixmap. We create a separate display
+ * and set the closedown mode on it to RetainPermanent
+ * (copied from gnome-source/control-panels/capplets/background-properties/render-background.c)
+ */
+static GdkPixmap *
+make_root_pixmap (gint width, gint height)
+{
+ Pixmap result;
+
+ gdk_flush ();
+
+ XSetCloseDownMode (gdk_display, RetainPermanent);
+
+ result = XCreatePixmap (gdk_display,
+ DefaultRootWindow (gdk_display),
+ width, height,
+ DefaultDepthOfScreen (DefaultScreenOfDisplay (GDK_DISPLAY())));
+
+ return gdk_pixmap_foreign_new (result);
+}
+
+/* (copied from gnome-source/control-panels/capplets/background-properties/render-background.c)
+ */
+static void
+dispose_root_pixmap (GdkPixmap *pixmap)
+{
+ /* Unrefing a foreign pixmap causes it to be destroyed - so we include
+ * this bad hack, that will work for GTK+-1.2 until the problem
+ * is fixed in the next release
+ */
+
+ GdkWindowPrivate *private = (GdkWindowPrivate *)pixmap;
+
+ gdk_xid_table_remove (private->xwindow);
+ g_dataset_destroy (private);
+ g_free (private);
+
+}
+
+/* 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
+ * (copied from gnome-source/control-panels/capplets/background-properties/render-background.c)
+ */
+static void
+set_root_pixmap (GdkPixmap *pixmap)
+{
+ GdkAtom type;
+ gulong nitems, bytes_after;
+ gint format;
+ guchar *data_esetroot;
+ Pixmap pixmap_id = GDK_WINDOW_XWINDOW (pixmap);
+
+ XGrabServer (GDK_DISPLAY());
+
+ XGetWindowProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+ gdk_atom_intern("ESETROOT_PMAP_ID", FALSE),
+ 0L, 1L, False, XA_PIXMAP,
+ &type, &format, &nitems, &bytes_after,
+ &data_esetroot);
+
+ if (type == XA_PIXMAP) {
+ if (format == 32 && nitems == 4)
+ XKillClient(GDK_DISPLAY(), *((Pixmap*)data_esetroot));
+
+ XFree (data_esetroot);
+ }
+
+ XChangeProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+ gdk_atom_intern("ESETROOT_PMAP_ID", FALSE), XA_PIXMAP,
+ 32, PropModeReplace,
+ (guchar *) &pixmap_id, 1);
+ XChangeProperty (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
+ gdk_atom_intern("_XROOTPMAP_ID", FALSE), XA_PIXMAP,
+ 32, PropModeReplace,
+ (guchar *) &pixmap_id, 1);
+
+ XSetWindowBackgroundPixmap (GDK_DISPLAY(), GDK_ROOT_WINDOW(), pixmap_id);
+ XClearWindow (GDK_DISPLAY (), GDK_ROOT_WINDOW ());
+
+ XUngrabServer (GDK_DISPLAY());
+
+ XFlush(GDK_DISPLAY());
+}
+
+static void
+image_loaded_callback (NautilusBackground *background, void *calledDirectly)
+{
+ GdkGC *gc;
+ GdkPixmap *bg_pixmap;
+ GdkRectangle screen_rectangle;
+
+ g_assert (NAUTILUS_IS_BACKGROUND (background));
+
+ if (!(gboolean) calledDirectly) {
+ gtk_signal_disconnect_by_func (GTK_OBJECT (background),
+ GTK_SIGNAL_FUNC (image_loaded_callback),
+ calledDirectly);
+ }
+
+ screen_rectangle.x = 0;
+ screen_rectangle.y = 0;
+ screen_rectangle.width = gdk_screen_width ();
+ screen_rectangle.height = gdk_screen_height ();
+
+ bg_pixmap = make_root_pixmap (screen_rectangle.width, screen_rectangle.height);
+ gc = gdk_gc_new (bg_pixmap);
+
+ nautilus_background_draw (background, bg_pixmap, gc, &screen_rectangle, 0, 0);
+
+ set_root_pixmap (bg_pixmap);
+
+ dispose_root_pixmap (bg_pixmap);
+ gdk_gc_unref (gc);
+}
+
+static void
+nautilus_directory_update_root_window (NautilusBackground *background)
+{
+ if (nautilus_background_is_loaded (background)) {
+ image_loaded_callback (background, (void *) TRUE);
+ } else {
+ gtk_signal_connect (GTK_OBJECT (background),
+ "image_loaded",
+ GTK_SIGNAL_FUNC (image_loaded_callback),
+ (void *) FALSE);
+ }
+}
/* return true if the background is not in the default state */
gboolean
@@ -353,6 +483,10 @@ background_changed_callback (NautilusBackground *background,
g_free (color);
g_free (image);
+
+ if (nautilus_directory_background_is_desktop (background)) {
+ nautilus_directory_update_root_window (background);
+ }
}
/* handle the directory changed signal */
@@ -461,6 +595,10 @@ background_reset_callback (NautilusBackground *background,
* It will set color and image_uri to NULL.
*/
gtk_signal_emit_stop_by_name (GTK_OBJECT (background), "reset");
+
+ if (nautilus_directory_background_is_desktop (background)) {
+ nautilus_directory_update_root_window (background);
+ }
}
/* handle the background destroyed signal */