--- rxvt-unicode/src/background.C 2012/05/13 21:12:01 1.213 +++ rxvt-unicode/src/background.C 2012/05/20 16:34:42 1.217 @@ -60,11 +60,6 @@ void rxvt_term::bg_destroy () { -#ifdef HAVE_PIXBUF - if (pixbuf) - g_object_unref (pixbuf); -#endif - if (bg_pixmap) XFreePixmap (dpy, bg_pixmap); } @@ -92,9 +87,11 @@ # endif # ifdef BG_IMAGE_FROM_FILE - if (bg_flags & BG_IS_FROM_FILE) + if (bg_image.flags & IM_IS_SET) { - if (bg_flags & BG_IS_SIZE_SENSITIVE) + if ((bg_image.flags & IM_IS_SIZE_SENSITIVE) + || bg_image.width () > szHint.width + || bg_image.height () > szHint.height) return true; } # endif @@ -111,9 +108,9 @@ # endif # ifdef BG_IMAGE_FROM_FILE - if (bg_flags & BG_IS_FROM_FILE) + if (bg_image.flags & IM_IS_SET) { - if (bg_flags & BG_ROOT_ALIGN) + if (bg_image.flags & IM_ROOT_ALIGN) return true; } # endif @@ -151,7 +148,7 @@ } bool -rxvt_term::bg_set_geometry (const char *geom, bool update) +rxvt_image::set_geometry (const char *geom, bool update) { bool changed = false; int geom_flags = 0; @@ -172,14 +169,14 @@ { if (!strcasecmp (arr[i], "style=tiled")) { - new_flags = BG_TILE; + new_flags = IM_TILE; w = h = noScale; x = y = 0; geom_flags = WidthValue|HeightValue|XValue|YValue; } else if (!strcasecmp (arr[i], "style=aspect-stretched")) { - new_flags = BG_KEEP_ASPECT; + new_flags = IM_KEEP_ASPECT; w = h = windowScale; x = y = centerAlign; geom_flags = WidthValue|HeightValue|XValue|YValue; @@ -199,40 +196,40 @@ } else if (!strcasecmp (arr[i], "style=root-tiled")) { - new_flags = BG_TILE|BG_ROOT_ALIGN; + new_flags = IM_TILE|IM_ROOT_ALIGN; w = h = noScale; geom_flags = WidthValue|HeightValue; } else if (!strcasecmp (arr[i], "op=tile")) - new_flags |= BG_TILE; + new_flags |= IM_TILE; else if (!strcasecmp (arr[i], "op=keep-aspect")) - new_flags |= BG_KEEP_ASPECT; + new_flags |= IM_KEEP_ASPECT; else if (!strcasecmp (arr[i], "op=root-align")) - new_flags |= BG_ROOT_ALIGN; + new_flags |= IM_ROOT_ALIGN; // deprecated else if (!strcasecmp (arr[i], "tile")) { - new_flags |= BG_TILE; + new_flags |= IM_TILE; w = h = noScale; geom_flags |= WidthValue|HeightValue; } else if (!strcasecmp (arr[i], "propscale")) { - new_flags |= BG_KEEP_ASPECT; + new_flags |= IM_KEEP_ASPECT; w = h = windowScale; geom_flags |= WidthValue|HeightValue; } else if (!strcasecmp (arr[i], "hscale")) { - new_flags |= BG_TILE; + new_flags |= IM_TILE; w = windowScale; h = noScale; geom_flags |= WidthValue|HeightValue; } else if (!strcasecmp (arr[i], "vscale")) { - new_flags |= BG_TILE; + new_flags |= IM_TILE; h = windowScale; w = noScale; geom_flags |= WidthValue|HeightValue; @@ -250,7 +247,7 @@ } else if (!strcasecmp (arr[i], "root")) { - new_flags |= BG_TILE|BG_ROOT_ALIGN; + new_flags |= IM_TILE|IM_ROOT_ALIGN; w = h = noScale; geom_flags |= WidthValue|HeightValue; } @@ -262,7 +259,7 @@ rxvt_free_strsplit (arr); } - new_flags |= bg_flags & ~BG_GEOMETRY_FLAGS; + new_flags |= flags & ~IM_GEOMETRY_FLAGS; if (!update) { @@ -279,18 +276,16 @@ w = h; } - min_it (w, 1000); - min_it (h, 1000); clamp_it (x, -100, 200); clamp_it (y, -100, 200); - if (bg_flags != new_flags + if (flags != new_flags || h_scale != w || v_scale != h || h_align != x || v_align != y) { - bg_flags = new_flags; + flags = new_flags; h_scale = w; v_scale = h; h_align = x; @@ -298,19 +293,30 @@ changed = true; } + if (!(flags & IM_TILE) + || h_scale || v_scale + || (!(flags & IM_ROOT_ALIGN) && (h_align || v_align))) + flags |= IM_IS_SIZE_SENSITIVE; + else + flags &= ~IM_IS_SIZE_SENSITIVE; + return changed; } void -rxvt_term::get_image_geometry (int image_width, int image_height, int &w, int &h, int &x, int &y) +rxvt_term::get_image_geometry (rxvt_image &image, int &w, int &h, int &x, int &y) { + int image_width = image.width (); + int image_height = image.height (); int target_width = szHint.width; int target_height = szHint.height; + int h_scale = min (image.h_scale, 32767 * 100 / target_width); + int v_scale = min (image.v_scale, 32767 * 100 / target_height); w = h_scale * target_width / 100; h = v_scale * target_height / 100; - if (bg_flags & BG_KEEP_ASPECT) + if (image.flags & IM_KEEP_ASPECT) { float scale = (float)w / image_width; min_it (scale, (float)h / image_height); @@ -321,24 +327,16 @@ if (!w) w = image_width; if (!h) h = image_height; - if (bg_flags & BG_ROOT_ALIGN) + if (image.flags & IM_ROOT_ALIGN) { x = -target_x; y = -target_y; } else { - x = make_align_position (h_align, target_width, w); - y = make_align_position (v_align, target_height, h); + x = make_align_position (image.h_align, target_width, w); + y = make_align_position (image.v_align, target_height, h); } - - if (!(bg_flags & BG_TILE) - || h_scale || v_scale - || (!(bg_flags & BG_ROOT_ALIGN) && (h_align || v_align)) - || image_width > target_width || image_height > target_height) - bg_flags |= BG_IS_SIZE_SENSITIVE; - else - bg_flags &= ~BG_IS_SIZE_SENSITIVE; } # ifdef HAVE_PIXBUF @@ -456,12 +454,15 @@ } bool -rxvt_term::render_image (bool transparent) +rxvt_term::render_image (rxvt_image &image) { + GdkPixbuf *pixbuf = image.pixbuf; if (!pixbuf) return false; - if (transparent + bool need_blend = bg_flags & BG_IS_VALID; + + if (need_blend && !(bg_flags & BG_HAS_RENDER)) return false; @@ -480,9 +481,9 @@ int w = 0; int h = 0; - get_image_geometry (image_width, image_height, w, h, x, y); + get_image_geometry (image, w, h, x, y); - if (!(bg_flags & BG_ROOT_ALIGN) + if (!(image.flags & IM_ROOT_ALIGN) && (x >= target_width || y >= target_height || x + w <= 0 @@ -506,19 +507,19 @@ XGCValues gcv; GC gc; - Pixmap root_pmap; + Pixmap tmp_pixmap; image_width = gdk_pixbuf_get_width (result); image_height = gdk_pixbuf_get_height (result); - if (transparent) + if (need_blend) { - root_pmap = bg_pixmap; + tmp_pixmap = bg_pixmap; bg_pixmap = None; } else { - if (bg_flags & BG_TILE) + if (image.flags & IM_TILE) { new_pmap_width = min (image_width, target_width); new_pmap_height = min (image_height, target_height); @@ -541,7 +542,7 @@ if (gc) { - if (bg_flags & BG_TILE) + if (image.flags & IM_TILE) { Pixmap tile = XCreatePixmap (dpy, vt, image_width, image_height, depth); pixbuf_to_pixmap (result, tile, gc, @@ -579,11 +580,11 @@ } #if XRENDER - if (transparent) + if (need_blend) { XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); - Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0); + Picture src = XRenderCreatePicture (dpy, tmp_pixmap, format, 0, 0); Picture dst = XRenderCreatePicture (dpy, bg_pixmap, format, 0, 0); @@ -613,15 +614,15 @@ if (result != pixbuf) g_object_unref (result); - if (transparent) - XFreePixmap (dpy, root_pmap); + if (need_blend) + XFreePixmap (dpy, tmp_pixmap); return ret; } # endif /* HAVE_PIXBUF */ bool -rxvt_term::bg_set_file (const char *file) +rxvt_image::set_file (const char *file) { if (!file || !*file) return false; @@ -645,17 +646,18 @@ if (pixbuf) g_object_unref (pixbuf); pixbuf = image; - bg_flags |= BG_IS_FROM_FILE; ret = true; } # endif if (ret) { + flags = IM_IS_SET | IM_IS_SIZE_SENSITIVE; + h_scale = v_scale = defaultScale; + h_align = v_align = defaultAlign; + if (p) - bg_set_geometry (p + 1); - else - bg_set_default_geometry (); + set_geometry (p + 1); } return ret; @@ -1067,23 +1069,20 @@ bool rxvt_term::bg_render () { - bool transparent = false; - bg_invalidate (); # ifdef ENABLE_TRANSPARENCY if (bg_flags & BG_IS_TRANSPARENT) { /* we need to re-generate transparency pixmap in that case ! */ - transparent = make_transparency_pixmap (); - if (transparent) + if (make_transparency_pixmap ()) bg_flags |= BG_IS_VALID; } # endif # ifdef BG_IMAGE_FROM_FILE - if (bg_flags & BG_IS_FROM_FILE) + if (bg_image.flags & IM_IS_SET) { - if (render_image (transparent)) + if (render_image (bg_image)) bg_flags |= BG_IS_VALID; } # endif