ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/background.C
(Generate patch)

Comparing rxvt-unicode/src/background.C (file contents):
Revision 1.164 by sf-exg, Sun Aug 14 22:01:25 2011 UTC vs.
Revision 1.193 by sf-exg, Sun Jan 1 14:31:29 2012 UTC

32 32
33#ifndef FilterConvolution 33#ifndef FilterConvolution
34#define FilterConvolution "convolution" 34#define FilterConvolution "convolution"
35#endif 35#endif
36 36
37/*
38 * Pixmap geometry string interpretation :
39 * Each geometry string contains zero or one scale/position
40 * adjustment and may optionally be followed by a colon and one or more
41 * colon-delimited pixmap operations.
42 * The following table shows the valid geometry strings and their
43 * effects on the background image :
44 *
45 * WxH+X+Y Set scaling to W% by H%, and position to X% by Y%.
46 * W and H are percentages of the terminal window size.
47 * X and Y are also percentages; e.g., +50+50 centers
48 * the image in the window.
49 *
50 * Pixmap Operations : (should be prepended by a colon)
51 */
52
53#ifdef HAVE_BG_PIXMAP 37#ifdef HAVE_BG_PIXMAP
38# if XRENDER
39static Picture
40create_xrender_mask (Display *dpy, Drawable drawable, Bool argb, Bool component_alpha)
41{
42 Pixmap pixmap = XCreatePixmap (dpy, drawable, 1, 1, argb ? 32 : 8);
43
44 XRenderPictFormat *format = XRenderFindStandardFormat (dpy, argb ? PictStandardARGB32 : PictStandardA8);
45 XRenderPictureAttributes pa;
46 pa.repeat = True;
47 pa.component_alpha = component_alpha;
48 Picture mask = XRenderCreatePicture (dpy, pixmap, format, CPRepeat | CPComponentAlpha, &pa);
49
50 XFreePixmap (dpy, pixmap);
51
52 return mask;
53}
54# endif
55
54void 56void
55rxvt_term::bg_destroy () 57rxvt_term::bg_destroy ()
56{ 58{
57#ifdef HAVE_AFTERIMAGE 59#ifdef HAVE_AFTERIMAGE
58 if (original_asim) 60 if (original_asim)
166 int smaller = min (image_size, window_size); 168 int smaller = min (image_size, window_size);
167 169
168 if (align >= 0 && align <= 100) 170 if (align >= 0 && align <= 100)
169 return diff * align / 100; 171 return diff * align / 100;
170 else if (align > 100 && align <= 200) 172 else if (align > 100 && align <= 200)
171 return ((align - 100) * smaller / 100) + window_size - smaller; 173 return (align - 100) * smaller / 100 + window_size - smaller;
172 else if (align >= -100 && align < 0) 174 else if (align >= -100 && align < 0)
173 return ((align + 100) * smaller / 100) - image_size; 175 return (align + 100) * smaller / 100 - image_size;
174 return 0; 176 return 0;
175} 177}
176 178
177static inline int 179static inline int
178make_clip_rectangle (int pos, int size, int target_size, int &dst_pos, int &dst_size) 180make_clip_rectangle (int pos, int size, int target_size, int &dst_pos, int &dst_size)
197{ 199{
198 bool changed = false; 200 bool changed = false;
199 int geom_flags = 0; 201 int geom_flags = 0;
200 int x = 0, y = 0; 202 int x = 0, y = 0;
201 unsigned int w = 0, h = 0; 203 unsigned int w = 0, h = 0;
202 unsigned long new_flags = (bg_flags & (~BG_GEOMETRY_FLAGS)); 204 unsigned long new_flags = 0;
203 205
204 if (geom == NULL) 206 if (geom == NULL)
205 return false; 207 return false;
206 208
207 if (geom[0]) 209 if (geom[0])
208 { 210 {
209 char **arr = rxvt_strsplit (':', geom); 211 char **arr = rxvt_strsplit (':', geom);
210 212
211 for (int i = 0; arr[i]; i++) 213 for (int i = 0; arr[i]; i++)
212 { 214 {
213 if (!strcasecmp (arr[i], "style=tiled")) 215 if (!strcasecmp (arr[i], "style=tiled"))
214 { 216 {
215 new_flags = BG_TILE; 217 new_flags = BG_TILE;
216 w = h = noScale; 218 w = h = noScale;
217 x = y = 0; 219 x = y = 0;
218 geom_flags = WidthValue|HeightValue|XValue|YValue; 220 geom_flags = WidthValue|HeightValue|XValue|YValue;
219 } 221 }
220 else if (!strcasecmp (arr[i], "style=aspect-stretched")) 222 else if (!strcasecmp (arr[i], "style=aspect-stretched"))
221 { 223 {
222 new_flags = BG_PROP_SCALE; 224 new_flags = BG_KEEP_ASPECT;
223 w = h = windowScale; 225 w = h = windowScale;
224 x = y = centerAlign; 226 x = y = centerAlign;
225 geom_flags = WidthValue|HeightValue|XValue|YValue; 227 geom_flags = WidthValue|HeightValue|XValue|YValue;
226 } 228 }
227 else if (!strcasecmp (arr[i], "style=stretched")) 229 else if (!strcasecmp (arr[i], "style=stretched"))
243 w = h = noScale; 245 w = h = noScale;
244 geom_flags = WidthValue|HeightValue; 246 geom_flags = WidthValue|HeightValue;
245 } 247 }
246 else if (!strcasecmp (arr[i], "op=tile")) 248 else if (!strcasecmp (arr[i], "op=tile"))
247 new_flags |= BG_TILE; 249 new_flags |= BG_TILE;
248 else if (!strcasecmp (arr[i], "op=pscale")) 250 else if (!strcasecmp (arr[i], "op=keep-aspect"))
249 new_flags |= BG_PROP_SCALE; 251 new_flags |= BG_KEEP_ASPECT;
250 else if (!strcasecmp (arr[i], "op=root")) 252 else if (!strcasecmp (arr[i], "op=root-align"))
251 new_flags |= BG_ROOT_ALIGN; 253 new_flags |= BG_ROOT_ALIGN;
252 254
253 // deprecated 255 // deprecated
254 else if (!strcasecmp (arr[i], "tile")) 256 else if (!strcasecmp (arr[i], "tile"))
255 { 257 {
257 w = h = noScale; 259 w = h = noScale;
258 geom_flags |= WidthValue|HeightValue; 260 geom_flags |= WidthValue|HeightValue;
259 } 261 }
260 else if (!strcasecmp (arr[i], "propscale")) 262 else if (!strcasecmp (arr[i], "propscale"))
261 { 263 {
262 new_flags |= BG_PROP_SCALE; 264 new_flags |= BG_KEEP_ASPECT;
265 w = h = windowScale;
266 geom_flags |= WidthValue|HeightValue;
263 } 267 }
264 else if (!strcasecmp (arr[i], "hscale")) 268 else if (!strcasecmp (arr[i], "hscale"))
265 { 269 {
266 new_flags |= BG_TILE; 270 new_flags |= BG_TILE;
267 w = windowScale; 271 w = windowScale;
297 geom_flags |= XParseGeometry (arr[i], &x, &y, &w, &h); 301 geom_flags |= XParseGeometry (arr[i], &x, &y, &w, &h);
298 } /* done parsing ops */ 302 } /* done parsing ops */
299 303
300 rxvt_free_strsplit (arr); 304 rxvt_free_strsplit (arr);
301 } 305 }
306
307 new_flags |= bg_flags & ~BG_GEOMETRY_FLAGS;
302 308
303 if (!update) 309 if (!update)
304 { 310 {
305 if (!(geom_flags & XValue)) 311 if (!(geom_flags & XValue))
306 x = y = defaultAlign; 312 x = y = defaultAlign;
338 int target_height = szHint.height; 344 int target_height = szHint.height;
339 345
340 w = h_scale * target_width / 100; 346 w = h_scale * target_width / 100;
341 h = v_scale * target_height / 100; 347 h = v_scale * target_height / 100;
342 348
343 if (bg_flags & BG_PROP_SCALE) 349 if (bg_flags & BG_KEEP_ASPECT)
344 { 350 {
345 float scale = (float)w / image_width; 351 float scale = (float)w / image_width;
346 min_it (scale, (float)h / image_height); 352 min_it (scale, (float)h / image_height);
347 w = image_width * scale + 0.5; 353 w = image_width * scale + 0.5;
348 h = image_height * scale + 0.5; 354 h = image_height * scale + 0.5;
386 if (tr_flags & BG_NEEDS_TINT) 392 if (tr_flags & BG_NEEDS_TINT)
387 { 393 {
388 ShadingInfo as_shade; 394 ShadingInfo as_shade;
389 as_shade.shading = shade; 395 as_shade.shading = shade;
390 396
391 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 397 rgba c;
392 if (bg_flags & BG_TINT_SET)
393 tint.get (c); 398 tint.get (c);
394 as_shade.tintColor.red = c.r; 399 as_shade.tintColor.red = c.r;
395 as_shade.tintColor.green = c.g; 400 as_shade.tintColor.green = c.g;
396 as_shade.tintColor.blue = c.b; 401 as_shade.tintColor.blue = c.b;
397 402
398 background_tint = shading2tint32 (&as_shade); 403 background_tint = shading2tint32 (&as_shade);
399 } 404 }
400 405
401 if ((tr_flags & BG_NEEDS_BLUR) && background != NULL) 406 if ((tr_flags & BG_NEEDS_BLUR) && background != NULL)
402 { 407 {
403 ASImage *tmp = blur_asimage_gauss (asv, background, h_blurRadius, v_blurRadius, 0xFFFFFFFF, 408 ASImage *tmp = blur_asimage_gauss (asv, background, h_blurRadius, v_blurRadius, 0xFFFFFFFF,
404 (original_asim == NULL || tint == TINT_LEAVE_SAME) ? ASA_XImage : ASA_ASImage, 409 ASA_XImage,
405 100, ASIMAGE_QUALITY_DEFAULT); 410 100, ASIMAGE_QUALITY_DEFAULT);
406 if (tmp) 411 if (tmp)
407 { 412 {
408 destroy_asimage (&background); 413 destroy_asimage (&background);
409 background = tmp; 414 background = tmp;
428 433
429 if (!original_asim 434 if (!original_asim
430 || (!(bg_flags & BG_ROOT_ALIGN) 435 || (!(bg_flags & BG_ROOT_ALIGN)
431 && (x >= target_width 436 && (x >= target_width
432 || y >= target_height 437 || y >= target_height
433 || (x + w <= 0) 438 || x + w <= 0
434 || (y + h <= 0)))) 439 || y + h <= 0)))
435 { 440 {
436 if (background) 441 if (background)
437 { 442 {
438 new_pmap_width = background->width; 443 new_pmap_width = background->width;
439 new_pmap_height = background->height; 444 new_pmap_height = background->height;
453 } 458 }
454 else 459 else
455 { 460 {
456 result = original_asim; 461 result = original_asim;
457 462
458 if ((w != original_asim->width) 463 if (w != original_asim->width
459 || (h != original_asim->height)) 464 || h != original_asim->height)
460 { 465 {
461 result = scale_asimage (asv, original_asim, 466 result = scale_asimage (asv, original_asim,
462 w, h, 467 w, h,
463 background ? ASA_ASImage : ASA_XImage, 468 ASA_XImage,
464 100, ASIMAGE_QUALITY_DEFAULT); 469 100, ASIMAGE_QUALITY_DEFAULT);
465 } 470 }
466 471
467 if (background == NULL) 472 if (background == NULL)
468 { 473 {
718 get_image_geometry (image_width, image_height, w, h, x, y); 723 get_image_geometry (image_width, image_height, w, h, x, y);
719 724
720 if (!(bg_flags & BG_ROOT_ALIGN) 725 if (!(bg_flags & BG_ROOT_ALIGN)
721 && (x >= target_width 726 && (x >= target_width
722 || y >= target_height 727 || y >= target_height
723 || (x + w <= 0) 728 || x + w <= 0
724 || (y + h <= 0))) 729 || y + h <= 0))
725 return false; 730 return false;
726 731
727 result = pixbuf; 732 result = pixbuf;
728 733
729 if ((w != image_width) 734 if (w != image_width
730 || (h != image_height)) 735 || h != image_height)
731 { 736 {
732 result = gdk_pixbuf_scale_simple (pixbuf, 737 result = gdk_pixbuf_scale_simple (pixbuf,
733 w, h, 738 w, h,
734 GDK_INTERP_BILINEAR); 739 GDK_INTERP_BILINEAR);
735 } 740 }
814 } 819 }
815 820
816#if XRENDER 821#if XRENDER
817 if (tr_flags) 822 if (tr_flags)
818 { 823 {
819 XRenderPictureAttributes pa;
820
821 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, visual); 824 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
825
822 Picture src = XRenderCreatePicture (dpy, root_pmap, src_format, 0, &pa); 826 Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0);
823 827
824 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
825 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, dst_format, 0, &pa); 828 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, format, 0, 0);
826 829
827 pa.repeat = True; 830 Picture mask = create_xrender_mask (dpy, vt, False, False);
828 Pixmap mask_pmap = XCreatePixmap (dpy, vt, 1, 1, 8);
829 XRenderPictFormat *mask_format = XRenderFindStandardFormat (dpy, PictStandardA8);
830 Picture mask = XRenderCreatePicture (dpy, mask_pmap, mask_format, CPRepeat, &pa);
831 XFreePixmap (dpy, mask_pmap);
832 831
833 XRenderColor mask_c; 832 XRenderColor mask_c;
834 833
835 mask_c.alpha = 0x8000; 834 mask_c.alpha = 0x8000;
836 mask_c.red = 0; 835 mask_c.red =
837 mask_c.green = 0; 836 mask_c.green =
838 mask_c.blue = 0; 837 mask_c.blue = 0;
839 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); 838 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
839
840 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, target_width, target_height); 840 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, target_width, target_height);
841 841
842 XRenderFreePicture (dpy, src); 842 XRenderFreePicture (dpy, src);
843 XRenderFreePicture (dpy, dst); 843 XRenderFreePicture (dpy, dst);
844 XRenderFreePicture (dpy, mask); 844 XRenderFreePicture (dpy, mask);
864rxvt_term::bg_set_file (const char *file) 864rxvt_term::bg_set_file (const char *file)
865{ 865{
866 if (!file || !*file) 866 if (!file || !*file)
867 return false; 867 return false;
868 868
869 bool ret = false;
869 if (const char *p = strchr (file, ';')) 870 const char *p = strchr (file, ';');
871
872 if (p)
870 { 873 {
871 size_t len = p - file; 874 size_t len = p - file;
872 char *f = rxvt_temp_buf<char> (len + 1); 875 char *f = rxvt_temp_buf<char> (len + 1);
873 memcpy (f, file, len); 876 memcpy (f, file, len);
874 f[len] = '\0'; 877 f[len] = '\0';
883 { 886 {
884 if (original_asim) 887 if (original_asim)
885 safe_asimage_destroy (original_asim); 888 safe_asimage_destroy (original_asim);
886 original_asim = image; 889 original_asim = image;
887 bg_flags |= BG_IS_FROM_FILE | BG_CLIENT_RENDER; 890 bg_flags |= BG_IS_FROM_FILE | BG_CLIENT_RENDER;
888 return true; 891 ret = true;
889 } 892 }
890# endif 893# endif
891 894
892# ifdef HAVE_PIXBUF 895# ifdef HAVE_PIXBUF
893 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL); 896 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL);
895 { 898 {
896 if (pixbuf) 899 if (pixbuf)
897 g_object_unref (pixbuf); 900 g_object_unref (pixbuf);
898 pixbuf = image; 901 pixbuf = image;
899 bg_flags |= BG_IS_FROM_FILE; 902 bg_flags |= BG_IS_FROM_FILE;
900 return true; 903 ret = true;
901 } 904 }
902# endif 905# endif
903 906
907 if (ret)
908 {
909 if (p)
910 bg_set_geometry (p + 1);
911 else
912 bg_set_default_geometry ();
913 }
914
904 return false; 915 return ret;
905} 916}
906 917
907# endif /* BG_IMAGE_FROM_FILE */ 918# endif /* BG_IMAGE_FROM_FILE */
908 919
909# ifdef ENABLE_TRANSPARENCY 920# ifdef ENABLE_TRANSPARENCY
945 { 956 {
946 changed = true; 957 changed = true;
947 v_blurRadius = vr; 958 v_blurRadius = vr;
948 } 959 }
949 960
950 if (v_blurRadius == 0 && h_blurRadius == 0) 961 if (h_blurRadius == 0 || v_blurRadius == 0)
951 bg_flags &= ~BG_NEEDS_BLUR; 962 bg_flags &= ~BG_NEEDS_BLUR;
952 else 963 else
953 bg_flags |= BG_NEEDS_BLUR; 964 bg_flags |= BG_NEEDS_BLUR;
954 965
955 return changed; 966 return changed;
956} 967}
957 968
958void 969void
959rxvt_term::set_tint_shade_flags () 970rxvt_term::set_tint_shade_flags ()
960{ 971{
961 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 972 rgba c;
962 bool has_shade = shade != 100; 973 bool has_shade = shade != 100;
963 974
964 bg_flags &= ~BG_TINT_FLAGS; 975 bg_flags &= ~BG_TINT_FLAGS;
965 976
966 if (bg_flags & BG_TINT_SET)
967 {
968 tint.get (c); 977 tint.get (c);
978
969 if (!has_shade 979 if (!has_shade
970 && (c.r <= 0x00ff || c.r >= 0xff00) 980 && (c.r <= 0x00ff || c.r >= 0xff00)
971 && (c.g <= 0x00ff || c.g >= 0xff00) 981 && (c.g <= 0x00ff || c.g >= 0xff00)
972 && (c.b <= 0x00ff || c.b >= 0xff00)) 982 && (c.b <= 0x00ff || c.b >= 0xff00))
973 bg_flags |= BG_TINT_BITAND; 983 bg_flags |= BG_TINT_BITAND;
974 }
975 984
976 if (has_shade || (bg_flags & BG_TINT_SET)) 985 if (has_shade
986 || c.r < 0xff00
987 || c.g < 0xff00
988 || c.b < 0xff00)
977 bg_flags |= BG_NEEDS_TINT; 989 bg_flags |= BG_NEEDS_TINT;
978} 990}
979 991
980bool 992bool
981rxvt_term::bg_set_tint (rxvt_color &new_tint) 993rxvt_term::bg_set_tint (rxvt_color &new_tint)
982{ 994{
983 if (!(bg_flags & BG_TINT_SET) || tint != new_tint) 995 if (tint != new_tint)
984 { 996 {
985 tint = new_tint; 997 tint = new_tint;
986 bg_flags |= BG_TINT_SET;
987 set_tint_shade_flags (); 998 set_tint_shade_flags ();
988 return true; 999 return true;
989 } 1000 }
990 1001
991 return false; 1002 return false;
992} 1003}
993 1004
994bool 1005bool
995rxvt_term::bg_set_shade (const char *shade_str) 1006rxvt_term::bg_set_shade (const char *shade_str)
996{ 1007{
997 int new_shade = (shade_str) ? atoi (shade_str) : 100; 1008 int new_shade = atoi (shade_str);
998 1009
999 clamp_it (new_shade, -100, 200); 1010 clamp_it (new_shade, -100, 200);
1000 if (new_shade < 0) 1011 if (new_shade < 0)
1001 new_shade = 200 - (100 + new_shade); 1012 new_shade = 200 - (100 + new_shade);
1002 1013
1036bool 1047bool
1037rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height) 1048rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height)
1038{ 1049{
1039 bool ret = false; 1050 bool ret = false;
1040#if XRENDER 1051#if XRENDER
1052 if (!(bg_flags & BG_HAS_RENDER_CONV))
1053 return false;
1054
1041 int size = max (h_blurRadius, v_blurRadius) * 2 + 1; 1055 int size = max (h_blurRadius, v_blurRadius) * 2 + 1;
1042 double *kernel = (double *)malloc (size * sizeof (double)); 1056 double *kernel = (double *)malloc (size * sizeof (double));
1043 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 1057 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
1044 1058
1045 XRenderPictureAttributes pa;
1046 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1059 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1047 1060
1048 Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1061 Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1049 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1062 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1050 1063
1051 if (kernel && params) 1064 if (kernel && params)
1052 { 1065 {
1053 if (h_blurRadius)
1054 {
1055 size = h_blurRadius * 2 + 1; 1066 size = h_blurRadius * 2 + 1;
1056 get_gaussian_kernel (h_blurRadius, size, kernel, params); 1067 get_gaussian_kernel (h_blurRadius, size, kernel, params);
1057 1068
1058 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1069 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1059 XRenderComposite (dpy, 1070 XRenderComposite (dpy,
1060 PictOpSrc, 1071 PictOpSrc,
1061 src, 1072 src,
1062 None, 1073 None,
1063 dst, 1074 dst,
1064 0, 0, 1075 0, 0,
1065 0, 0, 1076 0, 0,
1066 0, 0, 1077 0, 0,
1067 width, height); 1078 width, height);
1068 }
1069 1079
1070 if (v_blurRadius)
1071 {
1072 size = v_blurRadius * 2 + 1; 1080 size = v_blurRadius * 2 + 1;
1073 get_gaussian_kernel (v_blurRadius, size, kernel, params); 1081 get_gaussian_kernel (v_blurRadius, size, kernel, params);
1074 ::swap (params[0], params[1]); 1082 ::swap (params[0], params[1]);
1075 1083
1076 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1084 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1077 XRenderComposite (dpy, 1085 XRenderComposite (dpy,
1078 PictOpSrc, 1086 PictOpSrc,
1079 src, 1087 src,
1080 None, 1088 None,
1081 dst, 1089 dst,
1082 0, 0, 1090 0, 0,
1083 0, 0, 1091 0, 0,
1084 0, 0, 1092 0, 0,
1085 width, height); 1093 width, height);
1086 }
1087 1094
1088 ret = true; 1095 ret = true;
1089 } 1096 }
1090 1097
1091 free (kernel); 1098 free (kernel);
1118 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height); 1125 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height);
1119 ret = true; 1126 ret = true;
1120 XFreeGC (dpy, gc); 1127 XFreeGC (dpy, gc);
1121 } 1128 }
1122 } 1129 }
1123 else
1124 {
1125# if XRENDER 1130# if XRENDER
1126 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1131 else if (bg_flags & BG_HAS_RENDER)
1132 {
1133 rgba c;
1127 1134
1128 if (bg_flags & BG_TINT_SET)
1129 tint.get (c); 1135 tint.get (c);
1130 1136
1131 if (shade <= 100) 1137 if (shade <= 100)
1132 { 1138 {
1133 c.r = c.r * shade / 100; 1139 c.r = c.r * shade / 100;
1134 c.g = c.g * shade / 100; 1140 c.g = c.g * shade / 100;
1139 c.r = c.r * (200 - shade) / 100; 1145 c.r = c.r * (200 - shade) / 100;
1140 c.g = c.g * (200 - shade) / 100; 1146 c.g = c.g * (200 - shade) / 100;
1141 c.b = c.b * (200 - shade) / 100; 1147 c.b = c.b * (200 - shade) / 100;
1142 } 1148 }
1143 1149
1144 XRenderPictFormat *solid_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
1145 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1150 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1146 XRenderPictureAttributes pa;
1147 1151
1148 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1152 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1149 1153
1150 pa.repeat = True; 1154 Picture overlay_pic = create_xrender_mask (dpy, pixmap, True, False);
1151 1155
1152 Pixmap overlay_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32); 1156 Picture mask_pic = create_xrender_mask (dpy, pixmap, True, True);
1153 Picture overlay_pic = XRenderCreatePicture (dpy, overlay_pmap, solid_format, CPRepeat, &pa);
1154 XFreePixmap (dpy, overlay_pmap);
1155
1156 pa.component_alpha = True;
1157 Pixmap mask_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32);
1158 Picture mask_pic = XRenderCreatePicture (dpy, mask_pmap, solid_format, CPRepeat | CPComponentAlpha, &pa);
1159 XFreePixmap (dpy, mask_pmap);
1160 1157
1161 XRenderColor mask_c; 1158 XRenderColor mask_c;
1162 1159
1163 mask_c.alpha = 0xffff; 1160 mask_c.alpha = 0xffff;
1164 mask_c.red = 1161 mask_c.red =
1169 mask_c.alpha = 0; 1166 mask_c.alpha = 0;
1170 mask_c.red = 0xffff - c.r; 1167 mask_c.red = 0xffff - c.r;
1171 mask_c.green = 0xffff - c.g; 1168 mask_c.green = 0xffff - c.g;
1172 mask_c.blue = 0xffff - c.b; 1169 mask_c.blue = 0xffff - c.b;
1173 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); 1170 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1);
1171
1174 XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, width, height); 1172 XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, width, height);
1175 1173
1176 if (shade > 100) 1174 if (shade > 100)
1177 { 1175 {
1178 mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100;
1179 mask_c.alpha = 0; 1176 mask_c.alpha = 0;
1177 mask_c.red =
1178 mask_c.green =
1179 mask_c.blue = 0xffff * (shade - 100) / 100;
1180 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); 1180 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1);
1181 1181
1182 XRenderComposite (dpy, PictOpOver, overlay_pic, None, back_pic, 0, 0, 0, 0, 0, 0, width, height); 1182 XRenderComposite (dpy, PictOpOver, overlay_pic, None, back_pic, 0, 0, 0, 0, 0, 0, width, height);
1183 } 1183 }
1184 1184
1185 ret = true; 1185 ret = true;
1186 1186
1187 XRenderFreePicture (dpy, mask_pic); 1187 XRenderFreePicture (dpy, mask_pic);
1188 XRenderFreePicture (dpy, overlay_pic); 1188 XRenderFreePicture (dpy, overlay_pic);
1189 XRenderFreePicture (dpy, back_pic); 1189 XRenderFreePicture (dpy, back_pic);
1190 }
1190# endif 1191# endif
1191 }
1192 1192
1193 return ret; 1193 return ret;
1194} 1194}
1195 1195
1196/* 1196/*
1247#if XRENDER 1247#if XRENDER
1248 if (bg_flags & BG_HAS_RENDER) 1248 if (bg_flags & BG_HAS_RENDER)
1249 { 1249 {
1250 recoded_root_pmap = XCreatePixmap (dpy, vt, root_pmap_width, root_pmap_height, depth); 1250 recoded_root_pmap = XCreatePixmap (dpy, vt, root_pmap_width, root_pmap_height, depth);
1251 1251
1252 XRenderPictureAttributes pa;
1253
1254 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); 1252 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
1255 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); 1253 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, 0);
1256 1254
1257 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); 1255 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
1258 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); 1256 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, 0);
1259 1257
1260 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height); 1258 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height);
1261 1259
1262 XRenderFreePicture (dpy, src); 1260 XRenderFreePicture (dpy, src);
1263 XRenderFreePicture (dpy, dst); 1261 XRenderFreePicture (dpy, dst);
1280 bg_pmap_width = window_width; 1278 bg_pmap_width = window_width;
1281 bg_pmap_height = window_height; 1279 bg_pmap_height = window_height;
1282 } 1280 }
1283 1281
1284 /* straightforward pixmap copy */ 1282 /* straightforward pixmap copy */
1285 while (sx < 0) sx += root_width; 1283 while (sx < 0) sx += root_pmap_width;
1286 while (sy < 0) sy += root_height; 1284 while (sy < 0) sy += root_pmap_height;
1287 1285
1288 gcv.tile = recoded_root_pmap; 1286 gcv.tile = recoded_root_pmap;
1289 gcv.fill_style = FillTiled; 1287 gcv.fill_style = FillTiled;
1290 gcv.ts_x_origin = -sx; 1288 gcv.ts_x_origin = -sx;
1291 gcv.ts_y_origin = -sy; 1289 gcv.ts_y_origin = -sy;
1293 1291
1294 if (gc) 1292 if (gc)
1295 { 1293 {
1296 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1294 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1297 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS); 1295 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS);
1298 XFreeGC (dpy, gc);
1299 1296
1300 if (!(bg_flags & BG_CLIENT_RENDER)) 1297 if (!(bg_flags & BG_CLIENT_RENDER))
1301 { 1298 {
1302 if ((bg_flags & BG_NEEDS_BLUR) 1299 if (bg_flags & BG_NEEDS_BLUR)
1303 && (bg_flags & BG_HAS_RENDER_CONV))
1304 { 1300 {
1305 if (blur_pixmap (bg_pixmap, visual, window_width, window_height)) 1301 if (blur_pixmap (bg_pixmap, visual, window_width, window_height))
1306 result &= ~BG_NEEDS_BLUR; 1302 result &= ~BG_NEEDS_BLUR;
1307 } 1303 }
1308 if ((bg_flags & BG_NEEDS_TINT) 1304 if (bg_flags & BG_NEEDS_TINT)
1309 && (bg_flags & (BG_TINT_BITAND | BG_HAS_RENDER)))
1310 { 1305 {
1311 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1306 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1312 result &= ~BG_NEEDS_TINT; 1307 result &= ~BG_NEEDS_TINT;
1313 } 1308 }
1309# ifndef HAVE_AFTERIMAGE
1310 if (result & BG_NEEDS_TINT)
1311 {
1312 XImage *ximage = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1313 if (ximage)
1314 {
1315 /* our own client-side tinting */
1316 tint_ximage (DefaultVisual (dpy, display->screen), ximage);
1317
1318 XPutImage (dpy, bg_pixmap, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height);
1319 XDestroyImage (ximage);
1320 }
1321 }
1322# endif
1314 } /* server side rendering completed */ 1323 } /* server side rendering completed */
1324
1325 XFreeGC (dpy, gc);
1315 } 1326 }
1316 1327
1317 if (recoded_root_pmap != root_pixmap) 1328 if (recoded_root_pmap != root_pixmap)
1318 XFreePixmap (dpy, recoded_root_pmap); 1329 XFreePixmap (dpy, recoded_root_pmap);
1319 1330
1328 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]); 1339 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]);
1329 1340
1330 root_pixmap = new_root_pixmap; 1341 root_pixmap = new_root_pixmap;
1331} 1342}
1332# endif /* ENABLE_TRANSPARENCY */ 1343# endif /* ENABLE_TRANSPARENCY */
1333
1334#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1335static void shade_ximage (Visual *visual, XImage *ximage, int shade, const rgba &c);
1336# endif
1337 1344
1338bool 1345bool
1339rxvt_term::bg_render () 1346rxvt_term::bg_render ()
1340{ 1347{
1341 unsigned long tr_flags = 0; 1348 unsigned long tr_flags = 0;
1346 { 1353 {
1347 /* we need to re-generate transparency pixmap in that case ! */ 1354 /* we need to re-generate transparency pixmap in that case ! */
1348 tr_flags = make_transparency_pixmap (); 1355 tr_flags = make_transparency_pixmap ();
1349 if (tr_flags == 0) 1356 if (tr_flags == 0)
1350 return false; 1357 return false;
1351 else if (!(tr_flags & BG_EFFECTS_FLAGS))
1352 bg_flags |= BG_IS_VALID; 1358 bg_flags |= BG_IS_VALID;
1353 } 1359 }
1354# endif 1360# endif
1355 1361
1356# ifdef BG_IMAGE_FROM_FILE 1362# ifdef BG_IMAGE_FROM_FILE
1357 if ((bg_flags & BG_IS_FROM_FILE) 1363 if ((bg_flags & BG_IS_FROM_FILE)
1360 if (render_image (tr_flags)) 1366 if (render_image (tr_flags))
1361 bg_flags |= BG_IS_VALID; 1367 bg_flags |= BG_IS_VALID;
1362 } 1368 }
1363# endif 1369# endif
1364 1370
1365# if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1366 XImage *result = NULL;
1367
1368 if (tr_flags && !(bg_flags & BG_IS_VALID))
1369 {
1370 result = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1371 }
1372
1373 if (result)
1374 {
1375 /* our own client-side tinting */
1376 if (tr_flags & BG_NEEDS_TINT)
1377 {
1378 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC);
1379 if (bg_flags & BG_TINT_SET)
1380 tint.get (c);
1381 shade_ximage (DefaultVisual (dpy, display->screen), result, shade, c);
1382 }
1383
1384 GC gc = XCreateGC (dpy, vt, 0UL, NULL);
1385
1386 if (gc)
1387 {
1388 XPutImage (dpy, bg_pixmap, gc, result, 0, 0, 0, 0, result->width, result->height);
1389
1390 XFreeGC (dpy, gc);
1391 bg_flags |= BG_IS_VALID;
1392 }
1393
1394 XDestroyImage (result);
1395 }
1396# endif
1397
1398 if (!(bg_flags & BG_IS_VALID)) 1371 if (!(bg_flags & BG_IS_VALID))
1399 { 1372 {
1400 if (bg_pixmap != None) 1373 if (bg_pixmap != None)
1401 { 1374 {
1402 XFreePixmap (dpy, bg_pixmap); 1375 XFreePixmap (dpy, bg_pixmap);
1414 1387
1415void 1388void
1416rxvt_term::bg_init () 1389rxvt_term::bg_init ()
1417{ 1390{
1418#ifdef ENABLE_TRANSPARENCY 1391#ifdef ENABLE_TRANSPARENCY
1392 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1393 tint.set (this, c);
1419 shade = 100; 1394 shade = 100;
1420#endif 1395#endif
1421 1396
1422 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV); 1397 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV);
1423#if XRENDER 1398#if XRENDER
1437} 1412}
1438 1413
1439#endif /* HAVE_BG_PIXMAP */ 1414#endif /* HAVE_BG_PIXMAP */
1440 1415
1441#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) 1416#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1442/* taken from aterm-0.4.2 */ 1417/* based on code from aterm-0.4.2 */
1443 1418
1444static void 1419static inline void
1445shade_ximage (Visual *visual, XImage *ximage, int shade, const rgba &c) 1420fill_lut (uint32_t *lookup, uint32_t mask, int sh, unsigned short low, unsigned short high)
1421{
1422 for (int i = 0; i <= mask >> sh; i++)
1423 {
1424 uint32_t tmp;
1425 tmp = i * high;
1426 tmp += (mask >> sh) * low;
1427 lookup[i] = (tmp / 0xffff) << sh;
1428 }
1429}
1430
1431void
1432rxvt_term::tint_ximage (Visual *visual, XImage *ximage)
1446{ 1433{
1447 int sh_r, sh_g, sh_b; 1434 int sh_r, sh_g, sh_b;
1448 uint32_t mask_r, mask_g, mask_b; 1435 uint32_t mask_r, mask_g, mask_b;
1449 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1436 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1450 rgba low; 1437 unsigned short low;
1451 rgba high;
1452 int i;
1453 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1438 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1454 1439
1455 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return; 1440 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return;
1456 1441
1457 /* for convenience */ 1442 /* for convenience */
1516 break; 1501 break;
1517 default: 1502 default:
1518 return; /* we do not support this color depth */ 1503 return; /* we do not support this color depth */
1519 } 1504 }
1520 1505
1506 rgba c;
1507
1508 tint.get (c);
1509
1521 /* prepare limits for color transformation (each channel is handled separately) */ 1510 /* prepare limits for color transformation (each channel is handled separately) */
1522 if (shade > 100) 1511 if (shade > 100)
1523 { 1512 {
1524 shade = 200 - shade;
1525
1526 high.r = c.r * shade / 100;
1527 high.g = c.g * shade / 100;
1528 high.b = c.b * shade / 100;
1529
1530 low.r = 65535 * (100 - shade) / 100; 1513 c.r = c.r * (200 - shade) / 100;
1531 low.g = 65535 * (100 - shade) / 100; 1514 c.g = c.g * (200 - shade) / 100;
1532 low.b = 65535 * (100 - shade) / 100; 1515 c.b = c.b * (200 - shade) / 100;
1516
1517 low = 0xffff * (shade - 100) / 100;
1533 } 1518 }
1534 else 1519 else
1535 { 1520 {
1536 high.r = c.r * shade / 100; 1521 c.r = c.r * shade / 100;
1537 high.g = c.g * shade / 100; 1522 c.g = c.g * shade / 100;
1538 high.b = c.b * shade / 100; 1523 c.b = c.b * shade / 100;
1539 1524
1540 low.r = low.g = low.b = 0; 1525 low = 0;
1541 } 1526 }
1542 1527
1543 /* fill our lookup tables */ 1528 /* fill our lookup tables */
1544 for (i = 0; i <= mask_r>>sh_r; i++) 1529 fill_lut (lookup_r, mask_r, sh_r, low, c.r);
1545 { 1530 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1546 uint32_t tmp; 1531 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1547 tmp = i * high.r;
1548 tmp += (mask_r>>sh_r) * low.r;
1549 lookup_r[i] = (tmp/65535)<<sh_r;
1550 }
1551 for (i = 0; i <= mask_g>>sh_g; i++)
1552 {
1553 uint32_t tmp;
1554 tmp = i * high.g;
1555 tmp += (mask_g>>sh_g) * low.g;
1556 lookup_g[i] = (tmp/65535)<<sh_g;
1557 }
1558 for (i = 0; i <= mask_b>>sh_b; i++)
1559 {
1560 uint32_t tmp;
1561 tmp = i * high.b;
1562 tmp += (mask_b>>sh_b) * low.b;
1563 lookup_b[i] = (tmp/65535)<<sh_b;
1564 }
1565 1532
1566 /* apply table to input image (replacing colors by newly calculated ones) */ 1533 /* apply table to input image (replacing colors by newly calculated ones) */
1567 if (ximage->bits_per_pixel == 32 1534 if (ximage->bits_per_pixel == 32
1568 && (ximage->depth == 24 || ximage->depth == 32) 1535 && (ximage->depth == 24 || ximage->depth == 32)
1569 && ximage->byte_order == host_byte_order) 1536 && ximage->byte_order == host_byte_order)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines