From d0baa7766955c873b21b7aec39c7c5f89aba72fb Mon Sep 17 00:00:00 2001 From: William Jon McCann Date: Dec 15 2009 14:55:48 +0000 Subject: - Better per-monitor backgrounds patch (gnome #147808) --- diff --git a/gnome-desktop.spec b/gnome-desktop.spec index 1a0d8bb..1ba30c5 100644 --- a/gnome-desktop.spec +++ b/gnome-desktop.spec @@ -12,7 +12,7 @@ Summary: Shared code among gnome-panel, gnome-session, nautilus, etc Name: gnome-desktop Version: 2.28.1 -Release: 6%{?dist} +Release: 7%{?dist} URL: http://www.gnome.org Source0: http://download.gnome.org/sources/gnome-desktop/2.28/%{name}-%{version}.tar.bz2 Patch1: concatenate-edid-descriptors.patch @@ -134,6 +134,9 @@ rm -rf $RPM_BUILD_ROOT %doc %{_datadir}/gtk-doc/html/gnome-desktop/ %changelog +* Sun Dec 13 2009 Jon McCann - 2.28.1-7 +- Better per-monitor backgrounds patch (gnome #147808) + * Thu Dec 10 2009 Jon McCann - 2.28.1-6 - Update per-monitor backgrounds patch (gnome #147808) diff --git a/per-monitor-background.patch b/per-monitor-background.patch index b0c026b..8e5d38b 100644 --- a/per-monitor-background.patch +++ b/per-monitor-background.patch @@ -1,19 +1,24 @@ -From 84657b9565dc5a70d709d2746def73efa0c7cf13 Mon Sep 17 00:00:00 2001 -From: William Jon McCann -Date: Sun, 8 Nov 2009 15:56:23 -0500 -Subject: [PATCH] Per monitors backgrounds support - -https://bugzilla.gnome.org/show_bug.cgi?id=147808 ---- - libgnome-desktop/gnome-bg.c | 251 ++++++++++++++++++++------------ - libgnome-desktop/libgnomeui/gnome-bg.h | 11 +- - 2 files changed, 164 insertions(+), 98 deletions(-) - diff --git a/libgnome-desktop/gnome-bg.c b/libgnome-desktop/gnome-bg.c -index a882551..c584147 100644 +index a882551..a539e06 100644 --- a/libgnome-desktop/gnome-bg.c +++ b/libgnome-desktop/gnome-bg.c -@@ -168,7 +168,9 @@ static gboolean get_thumb_annotations (GdkPixbuf *thumb, +@@ -144,10 +144,11 @@ static GdkPixbuf *pixbuf_scale_to_fit (GdkPixbuf *src, + static GdkPixbuf *pixbuf_scale_to_min (GdkPixbuf *src, + int min_width, + int min_height); +-static void pixbuf_draw_gradient (GdkPixbuf *pixbuf, +- gboolean horizontal, +- GdkColor *c1, +- GdkColor *c2); ++static void pixbuf_draw_gradient (GdkPixbuf *pixbuf, ++ gboolean horizontal, ++ GdkColor *c1, ++ GdkColor *c2, ++ GdkRectangle *rect); + static void pixbuf_tile (GdkPixbuf *src, + GdkPixbuf *dest); + static void pixbuf_blend (GdkPixbuf *src, +@@ -168,7 +169,9 @@ static gboolean get_thumb_annotations (GdkPixbuf *thumb, int *orig_height); /* Cache */ @@ -24,7 +29,7 @@ index a882551..c584147 100644 static void clear_cache (GnomeBG *bg); static gboolean is_different (GnomeBG *bg, const char *filename); -@@ -183,7 +185,11 @@ static SlideShow * get_as_slideshow (GnomeBG *bg, +@@ -183,7 +186,11 @@ static SlideShow * get_as_slideshow (GnomeBG *bg, const char *filename); static Slide * get_current_slide (SlideShow *show, double *alpha); @@ -37,7 +42,129 @@ index a882551..c584147 100644 static void color_from_string (const char *string, -@@ -685,12 +691,13 @@ get_scaled_pixbuf (GnomeBGPlacement placement, +@@ -613,13 +620,15 @@ gnome_bg_set_filename (GnomeBG *bg, + } + + static void +-draw_color (GnomeBG *bg, GdkPixbuf *dest) ++draw_color_area (GnomeBG *bg, ++ GdkPixbuf *dest, ++ GdkRectangle *rect) + { + guint32 pixel; + +- switch (bg->color_type) +- { ++ switch (bg->color_type) { + case GNOME_BG_COLOR_SOLID: ++ /* not really a big deal to ignore the area of interest */ + pixel = ((bg->primary.red >> 8) << 24) | + ((bg->primary.green >> 8) << 16) | + ((bg->primary.blue >> 8) << 8) | +@@ -629,11 +638,11 @@ draw_color (GnomeBG *bg, GdkPixbuf *dest) + break; + + case GNOME_BG_COLOR_H_GRADIENT: +- pixbuf_draw_gradient (dest, TRUE, &(bg->primary), &(bg->secondary)); ++ pixbuf_draw_gradient (dest, TRUE, &(bg->primary), &(bg->secondary), rect); + break; + + case GNOME_BG_COLOR_V_GRADIENT: +- pixbuf_draw_gradient (dest, FALSE, &(bg->primary), &(bg->secondary)); ++ pixbuf_draw_gradient (dest, FALSE, &(bg->primary), &(bg->secondary), rect); + break; + + default: +@@ -641,14 +650,77 @@ draw_color (GnomeBG *bg, GdkPixbuf *dest) + } + } + ++static void ++draw_color (GnomeBG *bg, ++ GdkPixbuf *dest, ++ GdkScreen *screen) ++{ ++ GdkRectangle rect; ++ rect.x = 0; ++ rect.y = 0; ++ rect.width = gdk_pixbuf_get_width (dest); ++ rect.height = gdk_pixbuf_get_height (dest); ++ draw_color_area (bg, dest, &rect); ++} ++ ++static void ++draw_color_each_monitor (GnomeBG *bg, ++ GdkPixbuf *dest, ++ GdkScreen *screen) ++{ ++ GdkRectangle rect; ++ gint num_monitors; ++ int monitor; ++ ++ num_monitors = gdk_screen_get_n_monitors (screen); ++ for (monitor = 0; monitor < num_monitors; monitor++) { ++ gdk_screen_get_monitor_geometry (screen, monitor, &rect); ++ draw_color_area (bg, dest, &rect); ++ } ++} ++ ++static GdkPixbuf * ++pixbuf_clip_to_fit (GdkPixbuf *src, ++ int max_width, ++ int max_height) ++{ ++ int src_width, src_height; ++ int w, h; ++ int src_x, src_y; ++ GdkPixbuf *pixbuf; ++ ++ src_width = gdk_pixbuf_get_width (src); ++ src_height = gdk_pixbuf_get_height (src); ++ ++ if (src_width < max_width && src_height < max_height) ++ return g_object_ref (src); ++ ++ w = MIN(src_width, max_width); ++ h = MIN(src_height, max_height); ++ ++ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, ++ gdk_pixbuf_get_has_alpha (src), ++ 8, w, h); ++ ++ src_x = (src_width - w) / 2; ++ src_y = (src_height - h) / 2; ++ gdk_pixbuf_copy_area (src, ++ src_x, src_y, ++ w, h, ++ pixbuf, ++ 0, 0); ++ return pixbuf; ++} ++ + static GdkPixbuf * + get_scaled_pixbuf (GnomeBGPlacement placement, + GdkPixbuf *pixbuf, + int width, int height, +- int *x, int *y, int *w, int *h) ++ int *x, int *y, ++ int *w, int *h) + { + GdkPixbuf *new; +- ++ + #if 0 + g_print ("original_width: %d %d\n", + gdk_pixbuf_get_width (pixbuf), +@@ -672,7 +744,7 @@ get_scaled_pixbuf (GnomeBGPlacement placement, + case GNOME_BG_PLACEMENT_CENTERED: + case GNOME_BG_PLACEMENT_TILED: + default: +- new = g_object_ref (pixbuf); ++ new = pixbuf_clip_to_fit (pixbuf, width, height); + break; + } + +@@ -685,20 +757,20 @@ get_scaled_pixbuf (GnomeBGPlacement placement, } static void @@ -56,7 +183,17 @@ index a882551..c584147 100644 int x, y, w, h; GdkPixbuf *scaled; -@@ -708,7 +715,7 @@ draw_image (GnomeBGPlacement placement, + if (!pixbuf) + return; +- +- scaled = get_scaled_pixbuf ( +- placement, pixbuf, dest_width, dest_height, &x, &y, &w, &h); ++ ++ scaled = get_scaled_pixbuf (placement, pixbuf, dest_width, dest_height, &x, &y, &w, &h); + + switch (placement) { + case GNOME_BG_PLACEMENT_TILED: +@@ -708,7 +780,7 @@ draw_image (GnomeBGPlacement placement, case GNOME_BG_PLACEMENT_CENTERED: case GNOME_BG_PLACEMENT_FILL_SCREEN: case GNOME_BG_PLACEMENT_SCALED: @@ -65,7 +202,7 @@ index a882551..c584147 100644 break; default: g_assert_not_reached (); -@@ -718,51 +725,82 @@ draw_image (GnomeBGPlacement placement, +@@ -718,54 +790,97 @@ draw_image (GnomeBGPlacement placement, g_object_unref (scaled); } @@ -85,46 +222,62 @@ index a882551..c584147 100644 +} + +static void ++draw_once (GnomeBG *bg, ++ GdkPixbuf *dest, ++ GdkScreen *screen) ++{ ++ GdkRectangle rect; ++ ++ rect.x = 0; ++ rect.y = 0; ++ rect.width = gdk_pixbuf_get_width (dest); ++ rect.height = gdk_pixbuf_get_height (dest); ++ ++ draw_image_area (bg->placement, ++ get_pixbuf_for_size (bg, gdk_pixbuf_get_width (dest), gdk_pixbuf_get_height (dest)), ++ dest, ++ &rect); ++} ++ ++static void +draw_each_monitor (GnomeBG *bg, + GdkPixbuf *dest, + GdkScreen *screen) +{ + GdkRectangle rect; ++ gint num_monitors; ++ int monitor; + -+ if (bg->placement == GNOME_BG_PLACEMENT_TILED) { -+ GdkScreen *screen; -+ -+ /* don't worry about aligning on every monitor */ -+ screen = gdk_screen_get_default (); -+ gdk_screen_get_monitor_geometry (screen, 0, &rect); -+ draw_image (bg->placement, -+ get_pixbuf_for_size (bg, rect.width, rect.height), -+ dest); -+ } else { -+ gint num_monitors; -+ int monitor; -+ -+ num_monitors = gdk_screen_get_n_monitors (screen); -+ for (monitor = 0; monitor < num_monitors; monitor++) { -+ gdk_screen_get_monitor_geometry (screen, monitor, &rect); -+ draw_image_area (bg->placement, -+ get_pixbuf_for_size (bg, rect.width, rect.height), -+ dest, &rect); -+ } ++ num_monitors = gdk_screen_get_n_monitors (screen); ++ for (monitor = 0; monitor < num_monitors; monitor++) { ++ gdk_screen_get_monitor_geometry (screen, monitor, &rect); ++ draw_image_area (bg->placement, ++ get_pixbuf_for_size (bg, rect.width, rect.height), ++ dest, &rect); + } +} + void -gnome_bg_draw (GnomeBG *bg, GdkPixbuf *dest) -+gnome_bg_draw (GnomeBG *bg, GdkPixbuf *dest, GdkScreen *screen) ++gnome_bg_draw (GnomeBG *bg, ++ GdkPixbuf *dest, ++ GdkScreen *screen, ++ gboolean is_root) { if (!bg) return; - - draw_color (bg, dest); - +- +- draw_color (bg, dest); +- - draw_image (bg->placement, get_pixbuf (bg), dest); -+ draw_each_monitor (bg, dest, screen); ++ ++ if (is_root) { ++ draw_color_each_monitor (bg, dest, screen); ++ draw_each_monitor (bg, dest, screen); ++ } else { ++ draw_color (bg, dest, screen); ++ draw_once (bg, dest, screen); ++ } } gboolean @@ -173,8 +326,11 @@ index a882551..c584147 100644 + int *pixmap_height) { int dummy; - int pb_width, pb_height; -@@ -774,8 +812,8 @@ gnome_bg_get_pixmap_size (GnomeBG *bg, +- int pb_width, pb_height; + + if (!pixmap_width) + pixmap_width = &dummy; +@@ -774,8 +889,8 @@ gnome_bg_get_pixmap_size (GnomeBG *bg, *pixmap_width = width; *pixmap_height = height; @@ -185,33 +341,73 @@ index a882551..c584147 100644 switch (bg->color_type) { case GNOME_BG_COLOR_SOLID: *pixmap_width = 1; -@@ -796,11 +834,13 @@ gnome_bg_get_pixmap_size (GnomeBG *bg, +@@ -783,44 +898,12 @@ gnome_bg_get_pixmap_size (GnomeBG *bg, + break; + + case GNOME_BG_COLOR_H_GRADIENT: +- *pixmap_width = width; +- *pixmap_height = GRADIENT_PIXMAP_TILE_SIZE; +- break; +- + case GNOME_BG_COLOR_V_GRADIENT: +- *pixmap_width = GRADIENT_PIXMAP_TILE_SIZE; +- *pixmap_height = height; + break; + } + return; } - +- - pb_width = gdk_pixbuf_get_width (get_pixbuf (bg)); - pb_height = gdk_pixbuf_get_height (get_pixbuf (bg)); - - if (bg->placement == GNOME_BG_PLACEMENT_TILED) { +- if (bg->placement == GNOME_BG_PLACEMENT_TILED) { - if (gdk_pixbuf_get_has_alpha (get_pixbuf (bg)) && -+ GdkPixbuf *pixbuf; -+ pixbuf = get_pixbuf_for_size (bg, width, height); -+ pb_width = gdk_pixbuf_get_width (pixbuf); -+ pb_height = gdk_pixbuf_get_height (pixbuf); -+ -+ if (gdk_pixbuf_get_has_alpha (pixbuf) && - bg->color_type != GNOME_BG_COLOR_SOLID) { - if (bg->color_type == GNOME_BG_COLOR_H_GRADIENT) { - /* FIXME: Should this be -@@ -860,6 +900,7 @@ gnome_bg_create_pixmap (GnomeBG *bg, +- bg->color_type != GNOME_BG_COLOR_SOLID) { +- if (bg->color_type == GNOME_BG_COLOR_H_GRADIENT) { +- /* FIXME: Should this be +- * MAX (GRADIENT_TILE_SIZE, pb_height)? +- */ +- *pixmap_height = pb_height; +- *pixmap_width = width; +- } +- else { +- /* FIXME: Should this be +- * MAX (GRAIDENT_TILE_SIZE, pb_width? */ +- *pixmap_width = pb_width; +- *pixmap_height = height; +- } +- } +- else { +- *pixmap_width = pb_width; +- *pixmap_height = pb_height; +- } +- } + } + + /** +@@ -842,7 +925,7 @@ gnome_bg_create_pixmap (GnomeBG *bg, + GdkWindow *window, + int width, + int height, +- gboolean root) ++ gboolean is_root) + { + int pm_width, pm_height; + GdkPixmap *pixmap; +@@ -860,9 +943,10 @@ gnome_bg_create_pixmap (GnomeBG *bg, bg->last_pixmap_width = width; bg->last_pixmap_height = height; + /* has the side effect of loading and caching pixbuf only when in tile mode */ gnome_bg_get_pixmap_size (bg, width, height, &pm_width, &pm_height); - if (root) { -@@ -870,7 +911,7 @@ gnome_bg_create_pixmap (GnomeBG *bg, +- if (root) { ++ if (is_root) { + pixmap = make_root_pixmap (gdk_drawable_get_screen (window), + pm_width, pm_height); + } +@@ -870,7 +954,7 @@ gnome_bg_create_pixmap (GnomeBG *bg, pixmap = gdk_pixmap_new (window, pm_width, pm_height, -1); } @@ -220,16 +416,16 @@ index a882551..c584147 100644 GdkGC *gc = gdk_gc_new (pixmap); gdk_gc_set_rgb_fg_color (gc, &(bg->primary)); -@@ -883,7 +924,7 @@ gnome_bg_create_pixmap (GnomeBG *bg, +@@ -883,7 +967,7 @@ gnome_bg_create_pixmap (GnomeBG *bg, pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); - gnome_bg_draw (bg, pixbuf); -+ gnome_bg_draw (bg, pixbuf, gdk_drawable_get_screen (GDK_DRAWABLE (window))); ++ gnome_bg_draw (bg, pixbuf, gdk_drawable_get_screen (GDK_DRAWABLE (window)), is_root); gdk_draw_pixbuf (pixmap, NULL, pixbuf, 0, 0, 0, 0, width, height, -@@ -899,10 +940,13 @@ gnome_bg_create_pixmap (GnomeBG *bg, +@@ -899,10 +983,13 @@ gnome_bg_create_pixmap (GnomeBG *bg, * clients know what colors to draw on top with */ gboolean @@ -244,7 +440,7 @@ index a882551..c584147 100644 g_return_val_if_fail (bg != NULL, FALSE); -@@ -913,9 +957,9 @@ gnome_bg_is_dark (GnomeBG *bg) +@@ -913,9 +1000,9 @@ gnome_bg_is_dark (GnomeBG *bg) color.green = (bg->primary.green + bg->secondary.green) / 2; color.blue = (bg->primary.blue + bg->secondary.blue) / 2; } @@ -257,7 +453,7 @@ index a882551..c584147 100644 guchar a = (argb >> 24) & 0xff; guchar r = (argb >> 16) & 0xff; guchar g = (argb >> 8) & 0xff; -@@ -1001,9 +1045,31 @@ get_original_size (const char *filename, +@@ -1001,9 +1088,31 @@ get_original_size (const char *filename, return result; } @@ -289,7 +485,7 @@ index a882551..c584147 100644 int *width, int *height) { -@@ -1017,21 +1083,8 @@ gnome_bg_get_image_size (GnomeBG *bg, +@@ -1017,21 +1126,8 @@ gnome_bg_get_image_size (GnomeBG *bg, if (!bg->filename) return FALSE; @@ -312,7 +508,16 @@ index a882551..c584147 100644 if (thumb) { if (get_thumb_annotations (thumb, width, height)) result = TRUE; -@@ -1316,7 +1369,7 @@ struct _SlideShow +@@ -1068,7 +1164,7 @@ gnome_bg_create_thumbnail (GnomeBG *bg, + + result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, dest_width, dest_height); + +- draw_color (bg, result); ++ draw_color (bg, result, screen); + + thumb = create_img_thumbnail (bg, factory, screen, dest_width, dest_height, -1); + +@@ -1316,7 +1412,7 @@ struct _SlideShow GQueue *slides; @@ -321,7 +526,7 @@ index a882551..c584147 100644 /* used during parsing */ struct tm start_tm; -@@ -1356,7 +1409,8 @@ get_current_slide (SlideShow *show, +@@ -1356,7 +1452,8 @@ get_current_slide (SlideShow *show, Slide *slide = list->data; if (elapsed + slide->duration > delta) { @@ -331,7 +536,7 @@ index a882551..c584147 100644 return slide; } -@@ -1512,7 +1566,10 @@ file_cache_add_slide_show (GnomeBG *bg, +@@ -1512,7 +1609,10 @@ file_cache_add_slide_show (GnomeBG *bg, } static GdkPixbuf * @@ -343,7 +548,7 @@ index a882551..c584147 100644 { const FileCacheEntry *ent; if ((ent = file_cache_lookup (bg, PIXBUF, filename))) { -@@ -1523,14 +1580,14 @@ get_as_pixbuf (GnomeBG *bg, const char *filename) +@@ -1523,14 +1623,14 @@ get_as_pixbuf (GnomeBG *bg, const char *filename) GdkPixbuf *pixbuf; /* If scalable choose maximum size */ @@ -361,7 +566,19 @@ index a882551..c584147 100644 else pixbuf = gdk_pixbuf_new_from_file (filename, NULL); -@@ -1784,8 +1841,7 @@ create_img_thumbnail (GnomeBG *bg, +@@ -1763,9 +1863,8 @@ create_img_thumbnail (GnomeBG *bg, + GdkPixbuf *thumb = get_as_thumbnail (bg, factory, bg->filename); + + if (thumb) { +- return scale_thumbnail ( +- bg->placement, bg->filename, +- thumb, screen, dest_width, dest_height); ++ return scale_thumbnail (bg->placement, bg->filename, ++ thumb, screen, dest_width, dest_height); + } + else { + SlideShow *show = get_as_slideshow (bg, bg->filename); +@@ -1784,36 +1883,29 @@ create_img_thumbnail (GnomeBG *bg, if (slide->fixed) { GdkPixbuf *tmp; FileSize *fs; @@ -369,10 +586,13 @@ index a882551..c584147 100644 - fs = slide->file1->data; + fs = find_best_size (slide->file1, dest_width, dest_height); tmp = get_as_thumbnail (bg, factory, fs->file); - - thumb = scale_thumbnail ( -@@ -1793,26 +1849,23 @@ create_img_thumbnail (GnomeBG *bg, - tmp, screen, dest_width, dest_height); +- +- thumb = scale_thumbnail ( +- bg->placement, fs->file, +- tmp, screen, dest_width, dest_height); ++ if (tmp) ++ thumb = scale_thumbnail (bg->placement, fs->file, ++ tmp, screen, dest_width, dest_height); } else { - FileSize *fs; @@ -393,19 +613,22 @@ index a882551..c584147 100644 GdkPixbuf *thumb1, *thumb2; - fs = slide->file1->data; - thumb1 = scale_thumbnail ( +- thumb1 = scale_thumbnail ( - bg->placement, fs->file, -+ bg->placement, fs1->file, - p1, screen, dest_width, dest_height); +- p1, screen, dest_width, dest_height); ++ thumb1 = scale_thumbnail (bg->placement, fs1->file, ++ p1, screen, dest_width, dest_height); - fs = slide->file2->data; - thumb2 = scale_thumbnail ( +- thumb2 = scale_thumbnail ( - bg->placement, fs->file, -+ bg->placement, fs2->file, - p2, screen, dest_width, dest_height); +- p2, screen, dest_width, dest_height); ++ thumb2 = scale_thumbnail (bg->placement, fs2->file, ++ p2, screen, dest_width, dest_height); thumb = blend (thumb1, thumb2, alpha); -@@ -1880,18 +1933,26 @@ find_best_size (GSList *sizes, gint width, gint height) + +@@ -1880,18 +1972,26 @@ find_best_size (GSList *sizes, gint width, gint height) } static GdkPixbuf * @@ -437,7 +660,7 @@ index a882551..c584147 100644 time_until_next_change = G_MAXUINT; if (!bg->pixbuf_cache) { SlideShow *show = get_as_slideshow (bg, bg->filename); -@@ -1906,16 +1967,16 @@ get_pixbuf (GnomeBG *bg) +@@ -1906,16 +2006,16 @@ get_pixbuf (GnomeBG *bg) time_until_next_change = (guint)get_slide_timeout (slide); if (slide->fixed) { FileSize *size; @@ -460,7 +683,188 @@ index a882551..c584147 100644 if (p1 && p2) { -@@ -2368,14 +2429,14 @@ handle_text (GMarkupParseContext *context, +@@ -2084,22 +2184,38 @@ pixbuf_scale_to_min (GdkPixbuf *src, int min_width, int min_height) + double factor; + int src_width, src_height; + int new_width, new_height; +- ++ GdkPixbuf *dest; ++ + src_width = gdk_pixbuf_get_width (src); + src_height = gdk_pixbuf_get_height (src); +- ++ + factor = MAX (min_width / (double) src_width, min_height / (double) src_height); +- ++ + new_width = floor (src_width * factor + 0.5); + new_height = floor (src_height * factor + 0.5); +- +- return gdk_pixbuf_scale_simple (src, new_width, new_height, GDK_INTERP_BILINEAR); ++ ++ dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, ++ gdk_pixbuf_get_has_alpha (src), ++ 8, min_width, min_height); ++ if (!dest) ++ return NULL; ++ ++ /* crop the result */ ++ gdk_pixbuf_scale (src, dest, ++ 0, 0, ++ min_width, min_height, ++ (new_width - min_width) / -2, ++ (new_height - min_height) / -2, ++ factor, ++ factor, ++ GDK_INTERP_BILINEAR); ++ return dest; + } + + static guchar * + create_gradient (const GdkColor *primary, + const GdkColor *secondary, +- int n_pixels) ++ int n_pixels) + { + guchar *result = g_malloc (n_pixels * 3); + int i; +@@ -2116,43 +2232,56 @@ create_gradient (const GdkColor *primary, + } + + static void +-pixbuf_draw_gradient (GdkPixbuf *pixbuf, +- gboolean horizontal, +- GdkColor *primary, +- GdkColor *secondary) +-{ +- int width = gdk_pixbuf_get_width (pixbuf); +- int height = gdk_pixbuf_get_height (pixbuf); +- int rowstride = gdk_pixbuf_get_rowstride (pixbuf); +- guchar *dst = gdk_pixbuf_get_pixels (pixbuf); +- guchar *dst_limit = dst + height * rowstride; +- ++pixbuf_draw_gradient (GdkPixbuf *pixbuf, ++ gboolean horizontal, ++ GdkColor *primary, ++ GdkColor *secondary, ++ GdkRectangle *rect) ++{ ++ int width; ++ int height; ++ int rowstride; ++ guchar *dst; ++ guchar *dst_limit; ++ int n_channels = 3; ++ ++ rowstride = gdk_pixbuf_get_rowstride (pixbuf); ++ width = rect->width; ++ height = rect->height; ++ dst = gdk_pixbuf_get_pixels (pixbuf) + rect->x * n_channels + rowstride * rect->y; ++ dst_limit = dst + height * rowstride; ++ + if (horizontal) { + guchar *gradient = create_gradient (primary, secondary, width); +- int copy_bytes_per_row = width * 3; +- +- while (dst < dst_limit) { +- memcpy (dst, gradient, copy_bytes_per_row); +- dst += rowstride; ++ int copy_bytes_per_row = width * n_channels; ++ int i; ++ ++ for (i = 0; i < height; i++) { ++ guchar *d; ++ d = dst + rowstride * i; ++ memcpy (d, gradient, copy_bytes_per_row); + } + g_free (gradient); + } else { + guchar *gb, *gradient; +- +- gb = gradient = create_gradient (primary, secondary, height); +- while (dst < dst_limit) { +- int i; +- guchar *d = dst; +- guchar r = *gb++; +- guchar g = *gb++; +- guchar b = *gb++; +- for (i = 0; i < width; i++) { +- *d++ = r; +- *d++ = g; +- *d++ = b; ++ int i; ++ ++ gradient = create_gradient (primary, secondary, height); ++ for (i = 0; i < height; i++) { ++ int j; ++ guchar *d; ++ ++ d = dst + rowstride * i; ++ gb = gradient + n_channels * i; ++ for (j = width; j > 0; j--) { ++ int k; ++ ++ for (k = 0; k < n_channels; k++) { ++ *(d++) = gb[k]; ++ } + } +- dst += rowstride; + } ++ + g_free (gradient); + } + } +@@ -2162,8 +2291,8 @@ pixbuf_blend (GdkPixbuf *src, + GdkPixbuf *dest, + int src_x, + int src_y, +- int width, +- int height, ++ int src_width, ++ int src_height, + int dest_x, + int dest_y, + double alpha) +@@ -2173,11 +2302,11 @@ pixbuf_blend (GdkPixbuf *src, + int offset_x = dest_x - src_x; + int offset_y = dest_y - src_y; + +- if (width < 0) +- width = gdk_pixbuf_get_width (src); ++ if (src_width < 0) ++ src_width = gdk_pixbuf_get_width (src); + +- if (height < 0) +- height = gdk_pixbuf_get_height (src); ++ if (src_height < 0) ++ src_height = gdk_pixbuf_get_height (src); + + if (dest_x < 0) + dest_x = 0; +@@ -2185,17 +2314,17 @@ pixbuf_blend (GdkPixbuf *src, + if (dest_y < 0) + dest_y = 0; + +- if (dest_x + width > dest_width) { +- width = dest_width - dest_x; ++ if (dest_x + src_width > dest_width) { ++ src_width = dest_width - dest_x; + } + +- if (dest_y + height > dest_height) { +- height = dest_height - dest_y; ++ if (dest_y + src_height > dest_height) { ++ src_height = dest_height - dest_y; + } + + gdk_pixbuf_composite (src, dest, + dest_x, dest_y, +- width, height, ++ src_width, src_height, + offset_x, offset_y, + 1, 1, GDK_INTERP_NEAREST, + alpha * 0xFF + 0.5); +@@ -2368,14 +2497,14 @@ handle_text (GMarkupParseContext *context, fs->file = g_strdup (text); slide->file1 = g_slist_prepend (slide->file1, fs); if (slide->file1->next != NULL) @@ -477,7 +881,7 @@ index a882551..c584147 100644 } else if (stack_is (parser, "to", "transition", "background", NULL)) { for (i = 0; text[i]; i++) { -@@ -2390,13 +2451,13 @@ handle_text (GMarkupParseContext *context, +@@ -2390,13 +2519,13 @@ handle_text (GMarkupParseContext *context, fs->file = g_strdup (text); slide->file2 = g_slist_prepend (slide->file2, fs); if (slide->file2->next != NULL) @@ -493,7 +897,7 @@ index a882551..c584147 100644 } } -@@ -2639,9 +2700,9 @@ get_thumb_annotations (GdkPixbuf *thumb, +@@ -2639,9 +2768,9 @@ get_thumb_annotations (GdkPixbuf *thumb, } static gboolean @@ -505,21 +909,31 @@ index a882551..c584147 100644 } /* +@@ -2712,7 +2841,7 @@ gnome_bg_create_frame_thumbnail (GnomeBG *bg, + + result = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, dest_width, dest_height); + +- draw_color (bg, result); ++ draw_color (bg, result, screen); + + thumb = create_img_thumbnail (bg, factory, screen, dest_width, dest_height, frame_num + skipped); + diff --git a/libgnome-desktop/libgnomeui/gnome-bg.h b/libgnome-desktop/libgnomeui/gnome-bg.h -index 993173a..ddf9e5c 100644 +index 993173a..6ab2cb0 100644 --- a/libgnome-desktop/libgnomeui/gnome-bg.h +++ b/libgnome-desktop/libgnomeui/gnome-bg.h -@@ -87,7 +87,8 @@ const gchar * gnome_bg_get_filename (GnomeBG *bg); +@@ -87,7 +87,9 @@ const gchar * gnome_bg_get_filename (GnomeBG *bg); /* Drawing and thumbnailing */ void gnome_bg_draw (GnomeBG *bg, - GdkPixbuf *dest); + GdkPixbuf *dest, -+ GdkScreen *screen); ++ GdkScreen *screen, ++ gboolean is_root); GdkPixmap * gnome_bg_create_pixmap (GnomeBG *bg, GdkWindow *window, int width, -@@ -95,6 +96,8 @@ GdkPixmap * gnome_bg_create_pixmap (GnomeBG *bg, +@@ -95,6 +97,8 @@ GdkPixmap * gnome_bg_create_pixmap (GnomeBG *bg, gboolean root); gboolean gnome_bg_get_image_size (GnomeBG *bg, GnomeDesktopThumbnailFactory *factory, @@ -528,7 +942,7 @@ index 993173a..ddf9e5c 100644 int *width, int *height); GdkPixbuf * gnome_bg_create_thumbnail (GnomeBG *bg, -@@ -102,8 +105,10 @@ GdkPixbuf * gnome_bg_create_thumbnail (GnomeBG *bg, +@@ -102,8 +106,10 @@ GdkPixbuf * gnome_bg_create_thumbnail (GnomeBG *bg, GdkScreen *screen, int dest_width, int dest_height); @@ -541,25 +955,3 @@ index 993173a..ddf9e5c 100644 gboolean gnome_bg_changes_with_time (GnomeBG *bg); GdkPixbuf * gnome_bg_create_frame_thumbnail (GnomeBG *bg, GnomeDesktopThumbnailFactory *factory, --- -1.6.5.2 - -diff --git a/libgnome-desktop/gnome-bg.c b/libgnome-desktop/gnome-bg.c -index c584147..f050e70 100644 ---- a/libgnome-desktop/gnome-bg.c -+++ b/libgnome-desktop/gnome-bg.c -@@ -1843,10 +1843,10 @@ create_img_thumbnail (GnomeBG *bg, - FileSize *fs; - fs = find_best_size (slide->file1, dest_width, dest_height); - tmp = get_as_thumbnail (bg, factory, fs->file); -- -- thumb = scale_thumbnail ( -- bg->placement, fs->file, -- tmp, screen, dest_width, dest_height); -+ if (tmp) -+ thumb = scale_thumbnail ( -+ bg->placement, fs->file, -+ tmp, screen, dest_width, dest_height); - } - else { - FileSize *fs1, *fs2;