cccd208
diff -up gnome-desktop-2.28.1/libgnome-desktop/gnome-bg.c.per-monitor-background gnome-desktop-2.28.1/libgnome-desktop/gnome-bg.c
cccd208
--- gnome-desktop-2.28.1/libgnome-desktop/gnome-bg.c.per-monitor-background	2009-08-19 11:51:03.000000000 -0400
cccd208
+++ gnome-desktop-2.28.1/libgnome-desktop/gnome-bg.c	2009-11-09 17:05:49.839583495 -0500
cccd208
@@ -168,6 +168,9 @@ static gboolean   get_thumb_annotations 
cccd208
 					 int                   *orig_height);
cccd208
 
cccd208
 /* Cache */
cccd208
+static GdkPixbuf *get_pixbuf_for_size  (GnomeBG               *bg,
cccd208
+					int                    width,
cccd208
+					int                    height);
cccd208
 static GdkPixbuf *get_pixbuf           (GnomeBG               *bg);
cccd208
 static void       clear_cache          (GnomeBG               *bg);
cccd208
 static gboolean   is_different         (GnomeBG               *bg,
cccd208
@@ -685,12 +688,13 @@ get_scaled_pixbuf (GnomeBGPlacement plac
cccd208
 }
cccd208
 
cccd208
 static void
cccd208
-draw_image (GnomeBGPlacement  placement,
cccd208
-	    GdkPixbuf        *pixbuf,
cccd208
-	    GdkPixbuf        *dest)
cccd208
+draw_image_region (GnomeBGPlacement  placement,
cccd208
+		   GdkPixbuf        *pixbuf,
cccd208
+		   GdkPixbuf        *dest,
cccd208
+		   GdkRectangle     *region)
cccd208
 {
cccd208
-	int dest_width = gdk_pixbuf_get_width (dest);
cccd208
-	int dest_height = gdk_pixbuf_get_height (dest);
cccd208
+	int dest_width = region->width;
cccd208
+	int dest_height = region->height;
cccd208
 	int x, y, w, h;
cccd208
 	GdkPixbuf *scaled;
cccd208
 	
cccd208
@@ -708,7 +712,7 @@ draw_image (GnomeBGPlacement  placement,
cccd208
 	case GNOME_BG_PLACEMENT_CENTERED:
cccd208
 	case GNOME_BG_PLACEMENT_FILL_SCREEN:
cccd208
 	case GNOME_BG_PLACEMENT_SCALED:
cccd208
-		pixbuf_blend (scaled, dest, 0, 0, w, h, x, y, 1.0);
cccd208
+		pixbuf_blend (scaled, dest, 0, 0, w, h, x + region->x, y + region->y, 1.0);
cccd208
 		break;
cccd208
 	default:
cccd208
 		g_assert_not_reached ();
cccd208
@@ -718,15 +722,62 @@ draw_image (GnomeBGPlacement  placement,
cccd208
 	g_object_unref (scaled);
cccd208
 }
cccd208
 
cccd208
-void
cccd208
-gnome_bg_draw (GnomeBG *bg, GdkPixbuf *dest)
cccd208
+static void
cccd208
+draw_image (GnomeBGPlacement  placement,
cccd208
+	    GdkPixbuf        *pixbuf,
cccd208
+	    GdkPixbuf        *dest)
cccd208
+{
cccd208
+	GdkRectangle rect;
cccd208
+
cccd208
+	rect.x = 0;
cccd208
+	rect.y = 0;
cccd208
+	rect.width = gdk_pixbuf_get_width (dest);
cccd208
+	rect.height = gdk_pixbuf_get_height (dest);
cccd208
+
cccd208
+	draw_image_region (placement, pixbuf, dest, &rect);
cccd208
+}
cccd208
+
cccd208
+static void
cccd208
+draw_on_monitor (GnomeBG *bg, GdkPixbuf *dest, GdkRectangle *region)
cccd208
+{
cccd208
+	draw_image_region (bg->placement, get_pixbuf_for_size (bg, region->width, region->height), dest, region);
cccd208
+}
cccd208
+
cccd208
+static void
cccd208
+draw_each_monitor (GnomeBG *bg, GdkPixbuf *dest, GdkScreen *screen)
cccd208
+{
cccd208
+	if (bg->placement == GNOME_BG_PLACEMENT_TILED) {
cccd208
+		/* don't worry about aligning on every monitor */
cccd208
+		draw_image (bg->placement, get_pixbuf (bg), dest);
cccd208
+	} else {
cccd208
+		gint num_monitors;
cccd208
+		GdkRectangle rect;
cccd208
+		int monitor;
cccd208
+
cccd208
+		num_monitors = gdk_screen_get_n_monitors (screen);
cccd208
+
cccd208
+		for (monitor = 0; monitor < num_monitors; monitor++) {
cccd208
+			gdk_screen_get_monitor_geometry (screen, monitor, &rect);
cccd208
+			draw_on_monitor (bg, dest, &rect);
cccd208
+		}
cccd208
+	}
cccd208
+}
cccd208
+
cccd208
+static void
cccd208
+draw_on_screen (GnomeBG *bg, GdkPixbuf *dest, GdkScreen *screen)
cccd208
 {
cccd208
 	if (!bg)
cccd208
 		return;
cccd208
 	
cccd208
 	draw_color (bg, dest);
cccd208
 	
cccd208
-	draw_image (bg->placement, get_pixbuf (bg), dest);
cccd208
+	draw_each_monitor (bg, dest, screen);
cccd208
+}
cccd208
+
cccd208
+void
cccd208
+gnome_bg_draw (GnomeBG *bg, GdkPixbuf *dest)
cccd208
+{
cccd208
+	draw_on_screen (bg, dest, gdk_screen_get_default ());
cccd208
 }
cccd208
 
cccd208
 gboolean
cccd208
@@ -883,7 +934,7 @@ gnome_bg_create_pixmap (GnomeBG	    *bg,
cccd208
 		
cccd208
 		pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
cccd208
 					 width, height);
cccd208
-		gnome_bg_draw (bg, pixbuf);
cccd208
+		draw_on_screen (bg, pixbuf, gdk_drawable_get_screen (GDK_DRAWABLE (window)));
cccd208
 		gdk_draw_pixbuf (pixmap, NULL, pixbuf,
cccd208
 				 0, 0,
cccd208
 				 0, 0, width, height,
cccd208
@@ -1880,13 +1931,16 @@ find_best_size (GSList *sizes, gint widt
cccd208
 }
cccd208
 
cccd208
 static GdkPixbuf *
cccd208
-get_pixbuf (GnomeBG *bg)
cccd208
+get_pixbuf_for_size (GnomeBG *bg, gint best_width, gint best_height)
cccd208
 {
cccd208
 	/* FIXME: this ref=TRUE/FALSE stuff is crazy */
cccd208
-	
cccd208
+	gint width, height;
cccd208
 	guint time_until_next_change;
cccd208
 	gboolean ref = FALSE;
cccd208
-	
cccd208
+
cccd208
+	width = (best_width > 0) ? best_width : bg->last_pixmap_width;
cccd208
+	height = (best_height > 0) ? best_height : bg->last_pixmap_height;
cccd208
+
cccd208
 	if (!bg->pixbuf_cache && bg->filename) {
cccd208
 		ref = TRUE;
cccd208
 		bg->file_mtime = get_mtime (bg->filename);
cccd208
@@ -1906,15 +1960,15 @@ get_pixbuf (GnomeBG *bg)
cccd208
 				time_until_next_change = (guint)get_slide_timeout (slide);
cccd208
 				if (slide->fixed) {
cccd208
 					FileSize *size;
cccd208
-					size = find_best_size (slide->file1, bg->last_pixmap_width, bg->last_pixmap_height);
cccd208
+					size = find_best_size (slide->file1, width, height);
cccd208
 					bg->pixbuf_cache = get_as_pixbuf (bg, size->file);
cccd208
 				}
cccd208
 				else {
cccd208
 					FileSize *size;
cccd208
 					GdkPixbuf *p1, *p2;
cccd208
-					size = find_best_size (slide->file1, bg->last_pixmap_width, bg->last_pixmap_height);
cccd208
+					size = find_best_size (slide->file1, width, height);
cccd208
 					p1 = get_as_pixbuf (bg, size->file);
cccd208
-					size = find_best_size (slide->file2, bg->last_pixmap_width, bg->last_pixmap_height);
cccd208
+					size = find_best_size (slide->file2, width, height);
cccd208
 					p2 = get_as_pixbuf (bg, size->file);
cccd208
 
cccd208
 
cccd208
@@ -1943,6 +1997,22 @@ get_pixbuf (GnomeBG *bg)
cccd208
 	return bg->pixbuf_cache;
cccd208
 }
cccd208
 
cccd208
+static GdkPixbuf *
cccd208
+get_pixbuf (GnomeBG *bg)
cccd208
+{
cccd208
+	GdkPixbuf   *pixbuf;
cccd208
+	GdkScreen   *screen;
cccd208
+	GdkRectangle rect;
cccd208
+
cccd208
+	screen = gdk_screen_get_default ();
cccd208
+
cccd208
+	/* default to caching the primary monitor */
cccd208
+	gdk_screen_get_monitor_geometry (screen, 0, &rect);
cccd208
+	pixbuf = get_pixbuf_for_size (bg, rect.width, rect.height);
cccd208
+
cccd208
+	return pixbuf;
cccd208
+}
cccd208
+
cccd208
 static gboolean
cccd208
 is_different (GnomeBG    *bg,
cccd208
 	      const char *filename)