File gdm-2.8.0.7-bg-4.patch of Package gdm

--- gdm-2.16.1/gui/greeter/greeter.c
+++ gdm-2.16.1/gui/greeter/greeter.c
@@ -1025,6 +1025,7 @@
   const char *gdm_gtk_theme;
   guint sid;
   int r;
+  GdkColor black = { 0, 0, 0, 0 };
 
   if (g_getenv ("DOING_GDM_DEVELOPMENT") != NULL)
     DOING_GDM_DEVELOPMENT = TRUE;
@@ -1123,6 +1124,7 @@
   }
   
   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",
@@ -1139,6 +1141,7 @@
   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);
 
  /*
--- gdm-2.16.1/gui/greeter/greeter_canvas_item.c
+++ gdm-2.16.1/gui/greeter/greeter_canvas_item.c
@@ -24,6 +24,12 @@
 #include <glib/gi18n.h>
 #include <librsvg/rsvg.h>
 
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
 #include "gdm.h"
 #include "gdmcommon.h"
 #include "gdmconfig.h"
@@ -249,6 +255,127 @@
 	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)
 {
@@ -346,12 +473,53 @@
       }
     
     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);
openSUSE Build Service is sponsored by