diff -upr gdm-2.19.3-pre/gui/greeter/greeter.c gdm-2.19.3-post/gui/greeter/greeter.c --- gdm-2.19.3-pre/gui/greeter/greeter.c 2007-06-17 13:07:26.000000000 -0400 +++ gdm-2.19.3-post/gui/greeter/greeter.c 2007-07-31 21:19:51.000000000 -0400 @@ -1239,6 +1239,7 @@ main (int argc, char *argv[]) int r; gint i; gchar *key_string = NULL; + GdkColor black = { 0, 0, 0, 0 }; if (g_getenv ("DOING_GDM_DEVELOPMENT") != NULL) DOING_GDM_DEVELOPMENT = TRUE; @@ -1348,6 +1349,7 @@ main (int argc, char *argv[]) } window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_modify_bg (window, GTK_STATE_NORMAL, &black); if G_UNLIKELY (DOING_GDM_DEVELOPMENT) { g_signal_connect (G_OBJECT (window), "key_press_event", @@ -1364,6 +1366,7 @@ main (int argc, char *argv[]) gtk_window_set_default_size (GTK_WINDOW (window), gdm_wm_screen.width, gdm_wm_screen.height); + gtk_widget_modify_bg (canvas, GTK_STATE_NORMAL, &black); gtk_container_add (GTK_CONTAINER (window), canvas); /* diff -upr gdm-2.19.3-pre/gui/greeter/greeter_canvas_item.c gdm-2.19.3-post/gui/greeter/greeter_canvas_item.c --- gdm-2.19.3-pre/gui/greeter/greeter_canvas_item.c 2007-06-17 13:07:26.000000000 -0400 +++ gdm-2.19.3-post/gui/greeter/greeter_canvas_item.c 2007-07-31 21:18:11.000000000 -0400 @@ -24,6 +24,12 @@ #include #include +#include +#include + +#include +#include + #include "gdm.h" #include "gdmcommon.h" #include "gdmconfig.h" @@ -258,6 +264,127 @@ greeter_item_run_button_action_callback gtk_widget_grab_focus (entry); } +/* 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 gboolean +set_root_pixmap (GdkPixmap *pixmap) +{ + Atom type; + gulong nitems, bytes_after; + gint format; + guchar *data_esetroot; + Pixmap pixmap_id; + Display *display; + GdkScreen *screen; + int screen_num; + + screen = (GdkScreen *) g_object_get_data (G_OBJECT (pixmap), + "gdkscreen"); + + 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); + + return FALSE; +} + void greeter_item_create_canvas_item (GreeterItemInfo *item) { @@ -355,12 +482,53 @@ greeter_item_create_canvas_item (Greeter } if (item->data.pixmap.pixbufs[GREETER_ITEM_STATE_NORMAL] != NULL) + { + static int bg_set = 1; /* disabled */ + item->item = gnome_canvas_item_new (group, GNOME_TYPE_CANVAS_PIXBUF, "x", (gdouble) x1, "y", (gdouble) y1, "pixbuf", item->data.pixmap.pixbufs[GREETER_ITEM_STATE_NORMAL], NULL); + + if (!bg_set) + { + GdkPixmap *pixmap; + GdkPixbuf *pixbuf; + GdkScreen *screen; + GdkGC *gc; + gint width, height; + + screen = gtk_widget_get_screen (GTK_WIDGET (canvas)); + + pixbuf = item->data.pixmap.pixbufs[GREETER_ITEM_STATE_NORMAL]; + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + + pixmap = make_root_pixmap (screen, width, height); + + gc = gdk_gc_new (GDK_DRAWABLE (pixmap)); + + gdk_draw_pixbuf (GDK_DRAWABLE (pixmap), + gc, + pixbuf, + 0, 0, 0, 0, + width, + height, + GDK_RGB_DITHER_NORMAL, + 0, 0); + + g_object_set_data (G_OBJECT (pixmap), "gdkscreen", screen); + + g_timeout_add (1000, set_root_pixmap, pixmap); + + g_object_unref (gc); + + bg_set = 1; + } + } break; case GREETER_ITEM_TYPE_LABEL: text = gdm_common_expand_text (item->data.text.orig_text);