--- rxvt-unicode/src/background.C 2011/01/28 00:20:47 1.144 +++ rxvt-unicode/src/background.C 2011/08/11 12:27:26 1.162 @@ -3,7 +3,7 @@ *----------------------------------------------------------------------* * * All portions of code are copyright by their respective author/s. - * Copyright (c) 2005-2008 Marc Lehmann + * Copyright (c) 2005-2008 Marc Lehmann * Copyright (c) 2007 Sasha Vasko * Copyright (c) 2010 Emanuele Giaquinta * @@ -48,16 +48,6 @@ * the image in the window. * * Pixmap Operations : (should be prepended by a colon) - * tile Tile image. Scaling/position modifiers above will affect - * the tile size and origin. - * propscale When scaling, scale proportionally. That is, maintain the - * proper aspect ratio for the image. Any portion of the - * background not covered by the image is filled with the - * current background color. - * hscale Scale horizontally, tile vertically ? - * vscale Tile horizontally, scale vertically ? - * scale Scale both up and down - * auto Same as 100x100+50+50 */ #ifdef HAVE_BG_PIXMAP @@ -67,6 +57,10 @@ #ifdef HAVE_AFTERIMAGE if (original_asim) safe_asimage_destroy (original_asim); + if (asv) + destroy_asvisual (asv, 0); + if (asimman) + destroy_image_manager (asimman, 0); #endif #ifdef HAVE_PIXBUF @@ -256,8 +250,49 @@ for (int i = 0; arr[i]; i++) { - if (!strcasecmp (arr[i], "tile")) + if (!strcasecmp (arr[i], "style=tiled")) { + new_flags = BG_TILE; + w = h = noScale; + x = y = 0; + geom_flags = WidthValue|HeightValue|XValue|YValue; + } + else if (!strcasecmp (arr[i], "style=aspect-stretched")) + { + new_flags = BG_PROP_SCALE; + x = y = centerAlign; + geom_flags = XValue|YValue; + } + else if (!strcasecmp (arr[i], "style=stretched")) + { + new_flags = 0; + w = h = windowScale; + geom_flags = WidthValue|HeightValue; + } + else if (!strcasecmp (arr[i], "style=centered")) + { + new_flags = 0; + w = h = noScale; + x = y = centerAlign; + geom_flags = WidthValue|HeightValue|XValue|YValue; + } + else if (!strcasecmp (arr[i], "style=root-tiled")) + { + new_flags = BG_TILE|BG_ROOT_ALIGN; + w = h = noScale; + geom_flags = WidthValue|HeightValue; + } + else if (!strcasecmp (arr[i], "op=tile")) + new_flags |= BG_TILE; + else if (!strcasecmp (arr[i], "op=pscale")) + new_flags |= BG_PROP_SCALE; + else if (!strcasecmp (arr[i], "op=root")) + new_flags |= BG_ROOT_ALIGN; + + // deprecated + else if (!strcasecmp (arr[i], "tile")) + { + new_flags |= BG_TILE; w = h = noScale; geom_flags |= WidthValue|HeightValue; } @@ -267,23 +302,21 @@ } else if (!strcasecmp (arr[i], "hscale")) { - if (w == 0) w = windowScale; - + new_flags |= BG_TILE; + w = windowScale; h = noScale; geom_flags |= WidthValue|HeightValue; } else if (!strcasecmp (arr[i], "vscale")) { - if (h == 0) h = windowScale; - + new_flags |= BG_TILE; + h = windowScale; w = noScale; geom_flags |= WidthValue|HeightValue; } else if (!strcasecmp (arr[i], "scale")) { - if (h == 0) h = windowScale; - if (w == 0) w = windowScale; - + w = h = windowScale; geom_flags |= WidthValue|HeightValue; } else if (!strcasecmp (arr[i], "auto")) @@ -294,7 +327,7 @@ } else if (!strcasecmp (arr[i], "root")) { - new_flags |= BG_ROOT_ALIGN; + new_flags |= BG_TILE|BG_ROOT_ALIGN; w = h = noScale; geom_flags |= WidthValue|HeightValue; } @@ -351,7 +384,8 @@ } bg_flags &= ~BG_IS_SIZE_SENSITIVE; - if ((bg_flags & BG_PROP_SCALE) || h_scale || v_scale + if (!(bg_flags & BG_TILE) + || (bg_flags & BG_PROP_SCALE) || h_scale || v_scale || (!(bg_flags & BG_ROOT_ALIGN) && (h_align || v_align)) || w > target_width || h > target_height) bg_flags |= BG_IS_SIZE_SENSITIVE; @@ -453,7 +487,7 @@ if (background == NULL) { - if (h_scale == 0 || v_scale == 0) + if (bg_flags & BG_TILE) { /* if tiling - pixmap has to be sized exactly as the image, but there is no need to make it bigger than the window! */ @@ -488,7 +522,7 @@ layers[0].tint = background_tint; layers[1].im = result; - if (h_scale == 0 || v_scale == 0) + if (bg_flags & BG_TILE) { /* tile horizontally */ while (x > 0) x -= (int)result->width; @@ -502,7 +536,7 @@ layers[1].clip_width = result->width; } - if (h_scale == 0 || v_scale == 0) + if (bg_flags & BG_TILE) { while (y > 0) y -= (int)result->height; layers[1].dst_y = y; @@ -562,7 +596,7 @@ int dst_width = result->width, dst_height = result->height; if (background == NULL) { - if (!(h_scale == 0 || v_scale == 0)) + if (!(bg_flags & BG_TILE)) { src_x = make_clip_rectangle (x, result->width , new_pmap_width , dst_x, dst_width ); src_y = make_clip_rectangle (y, result->height, new_pmap_height, dst_y, dst_height); @@ -618,16 +652,16 @@ else return false; - width_r = rxvt_popcount (visual->red_mask); - width_g = rxvt_popcount (visual->green_mask); - width_b = rxvt_popcount (visual->blue_mask); + width_r = ecb_popcount32 (visual->red_mask); + width_g = ecb_popcount32 (visual->green_mask); + width_b = ecb_popcount32 (visual->blue_mask); if (width_r > 8 || width_g > 8 || width_b > 8) return false; - sh_r = rxvt_ctz (visual->red_mask); - sh_g = rxvt_ctz (visual->green_mask); - sh_b = rxvt_ctz (visual->blue_mask); + sh_r = ecb_ctz32 (visual->red_mask); + sh_g = ecb_ctz32 (visual->green_mask); + sh_b = ecb_ctz32 (visual->blue_mask); if (width > INT_MAX / height / bytes_per_pixel) return false; @@ -644,7 +678,7 @@ return false; } - ximage->byte_order = byteorder::big_endian () ? MSBFirst : LSBFirst; + ximage->byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; rowstride = gdk_pixbuf_get_rowstride (pixbuf); channels = gdk_pixbuf_get_n_channels (pixbuf); @@ -721,46 +755,49 @@ GDK_INTERP_BILINEAR); } + if (!result) + return false; + bool ret = false; - if (result) - { - XGCValues gcv; - GC gc; - Pixmap root_pmap; + XGCValues gcv; + GC gc; + Pixmap root_pmap; - image_width = gdk_pixbuf_get_width (result); - image_height = gdk_pixbuf_get_height (result); + image_width = gdk_pixbuf_get_width (result); + image_height = gdk_pixbuf_get_height (result); - if (tr_flags) - { - root_pmap = bg_pixmap; - bg_pixmap = None; - } - else + if (tr_flags) + { + root_pmap = bg_pixmap; + bg_pixmap = None; + } + else + { + if (bg_flags & BG_TILE) { - if (h_scale == 0 || v_scale == 0) - { - new_pmap_width = min (image_width, target_width); - new_pmap_height = min (image_height, target_height); - } + new_pmap_width = min (image_width, target_width); + new_pmap_height = min (image_height, target_height); } + } - if (bg_pixmap == None - || bg_pmap_width != new_pmap_width - || bg_pmap_height != new_pmap_height) - { - if (bg_pixmap) - XFreePixmap (dpy, bg_pixmap); - bg_pixmap = XCreatePixmap (dpy, vt, new_pmap_width, new_pmap_height, depth); - bg_pmap_width = new_pmap_width; - bg_pmap_height = new_pmap_height; - } + if (bg_pixmap == None + || bg_pmap_width != new_pmap_width + || bg_pmap_height != new_pmap_height) + { + if (bg_pixmap) + XFreePixmap (dpy, bg_pixmap); + bg_pixmap = XCreatePixmap (dpy, vt, new_pmap_width, new_pmap_height, depth); + bg_pmap_width = new_pmap_width; + bg_pmap_height = new_pmap_height; + } - gcv.foreground = pix_colors[Color_bg]; - gc = XCreateGC (dpy, vt, GCForeground, &gcv); + gcv.foreground = pix_colors[Color_bg]; + gc = XCreateGC (dpy, vt, GCForeground, &gcv); - if (h_scale == 0 || v_scale == 0) + if (gc) + { + if (bg_flags & BG_TILE) { Pixmap tile = XCreatePixmap (dpy, vt, image_width, image_height, depth); pixbuf_to_pixmap (result, tile, gc, @@ -814,34 +851,32 @@ Picture mask = XRenderCreatePicture (dpy, mask_pmap, mask_format, CPRepeat, &pa); XFreePixmap (dpy, mask_pmap); - if (src && dst && mask) - { - XRenderColor mask_c; + XRenderColor mask_c; - mask_c.alpha = 0x8000; - mask_c.red = 0; - mask_c.green = 0; - mask_c.blue = 0; - XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); - XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, target_width, target_height); - } + mask_c.alpha = 0x8000; + mask_c.red = 0; + mask_c.green = 0; + mask_c.blue = 0; + XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); + XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, target_width, target_height); XRenderFreePicture (dpy, src); XRenderFreePicture (dpy, dst); XRenderFreePicture (dpy, mask); - - XFreePixmap (dpy, root_pmap); } #endif - if (result != pixbuf) - g_object_unref (result); - XFreeGC (dpy, gc); ret = true; } + if (result != pixbuf) + g_object_unref (result); + + if (tr_flags) + XFreePixmap (dpy, root_pmap); + return ret; } # endif /* HAVE_PIXBUF */ @@ -941,27 +976,26 @@ return changed; } -static inline unsigned long -compute_tint_shade_flags (rxvt_color *tint, int shade) +void +rxvt_term::set_tint_shade_flags () { - unsigned long flags = 0; rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); bool has_shade = shade != 100; - if (tint) + bg_flags &= ~BG_TINT_FLAGS; + + if (bg_flags & BG_TINT_SET) { - tint->get (c); + tint.get (c); if (!has_shade && (c.r <= 0x00ff || c.r >= 0xff00) && (c.g <= 0x00ff || c.g >= 0xff00) && (c.b <= 0x00ff || c.b >= 0xff00)) - flags |= rxvt_term::BG_TINT_BITAND; + bg_flags |= BG_TINT_BITAND; } - if (has_shade || tint) - flags |= rxvt_term::BG_NEEDS_TINT; - - return flags; + if (has_shade || (bg_flags & BG_TINT_SET)) + bg_flags |= BG_NEEDS_TINT; } bool @@ -969,9 +1003,9 @@ { if (!(bg_flags & BG_TINT_SET) || tint != new_tint) { - unsigned long new_flags = compute_tint_shade_flags (&new_tint, shade); tint = new_tint; - bg_flags = (bg_flags & ~BG_TINT_FLAGS) | new_flags | BG_TINT_SET; + bg_flags |= BG_TINT_SET; + set_tint_shade_flags (); return true; } @@ -989,9 +1023,8 @@ if (new_shade != shade) { - unsigned long new_flags = compute_tint_shade_flags ((bg_flags & BG_TINT_SET) ? &tint : NULL, new_shade); shade = new_shade; - bg_flags = (bg_flags & ~BG_TINT_FLAGS) | new_flags; + set_tint_shade_flags (); return true; } @@ -1036,7 +1069,7 @@ Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); - if (kernel && params && src && dst) + if (kernel && params) { if (h_blurRadius) { @@ -1111,22 +1144,22 @@ else { # if XRENDER - rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); + rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); if (bg_flags & BG_TINT_SET) tint.get (c); if (shade <= 100) { - c.r = (c.r * shade) / 100; - c.g = (c.g * shade) / 100; - c.b = (c.b * shade) / 100; + c.r = c.r * shade / 100; + c.g = c.g * shade / 100; + c.b = c.b * shade / 100; } else { - c.r = (c.r * (200 - shade)) / 100; - c.g = (c.g * (200 - shade)) / 100; - c.b = (c.b * (200 - shade)) / 100; + c.r = c.r * (200 - shade) / 100; + c.g = c.g * (200 - shade) / 100; + c.b = c.b * (200 - shade) / 100; } XRenderPictFormat *solid_format = XRenderFindStandardFormat (dpy, PictStandardARGB32); @@ -1143,36 +1176,35 @@ pa.component_alpha = True; Pixmap mask_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32); - Picture mask_pic = XRenderCreatePicture (dpy, mask_pmap, solid_format, CPRepeat|CPComponentAlpha, &pa); + Picture mask_pic = XRenderCreatePicture (dpy, mask_pmap, solid_format, CPRepeat | CPComponentAlpha, &pa); XFreePixmap (dpy, mask_pmap); - if (mask_pic && overlay_pic && back_pic) - { - XRenderColor mask_c; + XRenderColor mask_c; - mask_c.red = mask_c.green = mask_c.blue = 0; - mask_c.alpha = 0xffff; - XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); + mask_c.alpha = 0xffff; + mask_c.red = + mask_c.green = + mask_c.blue = 0; + XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); + + mask_c.alpha = 0; + mask_c.red = 0xffff - c.r; + mask_c.green = 0xffff - c.g; + mask_c.blue = 0xffff - c.b; + XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); + XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, width, height); + if (shade > 100) + { + mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100; mask_c.alpha = 0; - mask_c.red = 0xffff - c.r; - mask_c.green = 0xffff - c.g; - mask_c.blue = 0xffff - c.b; - XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); - XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, width, height); - - if (shade > 100) - { - mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100; - mask_c.alpha = 0; - XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); - - XRenderComposite (dpy, PictOpOver, overlay_pic, None, back_pic, 0, 0, 0, 0, 0, 0, width, height); - } + XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); - ret = true; + XRenderComposite (dpy, PictOpOver, overlay_pic, None, back_pic, 0, 0, 0, 0, 0, 0, width, height); } + ret = true; + XRenderFreePicture (dpy, mask_pic); XRenderFreePicture (dpy, overlay_pic); XRenderFreePicture (dpy, back_pic); @@ -1182,7 +1214,7 @@ return ret; } -/* make_transparency_pixmap() +/* * Builds a pixmap of the same size as the terminal window that contains * the tiled portion of the root pixmap that is supposed to be covered by * our window. @@ -1236,32 +1268,27 @@ #if XRENDER if (bg_flags & BG_HAS_RENDER) { + recoded_root_pmap = XCreatePixmap (dpy, vt, root_pmap_width, root_pmap_height, depth); + XRenderPictureAttributes pa; XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); - recoded_root_pmap = XCreatePixmap (dpy, vt, root_pmap_width, root_pmap_height, depth); XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); - if (src && dst) - XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height); - else - { - XFreePixmap (dpy, recoded_root_pmap); - root_pixmap = None; - } + XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height); XRenderFreePicture (dpy, src); XRenderFreePicture (dpy, dst); } else #endif - root_pixmap = None; + recoded_root_pmap = None; } - if (root_pixmap == None) + if (recoded_root_pmap == None) return 0; if (bg_pixmap == None @@ -1275,12 +1302,9 @@ bg_pmap_height = window_height; } - if (bg_pixmap == None) - return 0; - /* straightforward pixmap copy */ - while (sx < 0) sx += (int)root_width; - while (sy < 0) sy += (int)root_height; + while (sx < 0) sx += root_width; + while (sy < 0) sy += root_height; gcv.tile = recoded_root_pmap; gcv.fill_style = FillTiled; @@ -1447,7 +1471,7 @@ rgba low; rgba high; int i; - int host_byte_order = byteorder::big_endian () ? MSBFirst : LSBFirst; + int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; if (visual->c_class != TrueColor || ximage->format != ZPixmap) return;