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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines