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.166 by sf-exg, Mon Aug 15 11:01:54 2011 UTC vs.
Revision 1.193 by sf-exg, Sun Jan 1 14:31:29 2012 UTC

33#ifndef FilterConvolution 33#ifndef FilterConvolution
34#define FilterConvolution "convolution" 34#define FilterConvolution "convolution"
35#endif 35#endif
36 36
37#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
38void 56void
39rxvt_term::bg_destroy () 57rxvt_term::bg_destroy ()
40{ 58{
41#ifdef HAVE_AFTERIMAGE 59#ifdef HAVE_AFTERIMAGE
42 if (original_asim) 60 if (original_asim)
150 int smaller = min (image_size, window_size); 168 int smaller = min (image_size, window_size);
151 169
152 if (align >= 0 && align <= 100) 170 if (align >= 0 && align <= 100)
153 return diff * align / 100; 171 return diff * align / 100;
154 else if (align > 100 && align <= 200) 172 else if (align > 100 && align <= 200)
155 return ((align - 100) * smaller / 100) + window_size - smaller; 173 return (align - 100) * smaller / 100 + window_size - smaller;
156 else if (align >= -100 && align < 0) 174 else if (align >= -100 && align < 0)
157 return ((align + 100) * smaller / 100) - image_size; 175 return (align + 100) * smaller / 100 - image_size;
158 return 0; 176 return 0;
159} 177}
160 178
161static inline int 179static inline int
162make_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)
181{ 199{
182 bool changed = false; 200 bool changed = false;
183 int geom_flags = 0; 201 int geom_flags = 0;
184 int x = 0, y = 0; 202 int x = 0, y = 0;
185 unsigned int w = 0, h = 0; 203 unsigned int w = 0, h = 0;
186 unsigned long new_flags = (bg_flags & (~BG_GEOMETRY_FLAGS)); 204 unsigned long new_flags = 0;
187 205
188 if (geom == NULL) 206 if (geom == NULL)
189 return false; 207 return false;
190 208
191 if (geom[0]) 209 if (geom[0])
192 { 210 {
193 char **arr = rxvt_strsplit (':', geom); 211 char **arr = rxvt_strsplit (':', geom);
194 212
195 for (int i = 0; arr[i]; i++) 213 for (int i = 0; arr[i]; i++)
196 { 214 {
197 if (!strcasecmp (arr[i], "style=tiled")) 215 if (!strcasecmp (arr[i], "style=tiled"))
198 { 216 {
199 new_flags = BG_TILE; 217 new_flags = BG_TILE;
200 w = h = noScale; 218 w = h = noScale;
201 x = y = 0; 219 x = y = 0;
202 geom_flags = WidthValue|HeightValue|XValue|YValue; 220 geom_flags = WidthValue|HeightValue|XValue|YValue;
203 } 221 }
204 else if (!strcasecmp (arr[i], "style=aspect-stretched")) 222 else if (!strcasecmp (arr[i], "style=aspect-stretched"))
205 { 223 {
206 new_flags = BG_PROP_SCALE; 224 new_flags = BG_KEEP_ASPECT;
207 w = h = windowScale; 225 w = h = windowScale;
208 x = y = centerAlign; 226 x = y = centerAlign;
209 geom_flags = WidthValue|HeightValue|XValue|YValue; 227 geom_flags = WidthValue|HeightValue|XValue|YValue;
210 } 228 }
211 else if (!strcasecmp (arr[i], "style=stretched")) 229 else if (!strcasecmp (arr[i], "style=stretched"))
227 w = h = noScale; 245 w = h = noScale;
228 geom_flags = WidthValue|HeightValue; 246 geom_flags = WidthValue|HeightValue;
229 } 247 }
230 else if (!strcasecmp (arr[i], "op=tile")) 248 else if (!strcasecmp (arr[i], "op=tile"))
231 new_flags |= BG_TILE; 249 new_flags |= BG_TILE;
232 else if (!strcasecmp (arr[i], "op=pscale")) 250 else if (!strcasecmp (arr[i], "op=keep-aspect"))
233 new_flags |= BG_PROP_SCALE; 251 new_flags |= BG_KEEP_ASPECT;
234 else if (!strcasecmp (arr[i], "op=root")) 252 else if (!strcasecmp (arr[i], "op=root-align"))
235 new_flags |= BG_ROOT_ALIGN; 253 new_flags |= BG_ROOT_ALIGN;
236 254
237 // deprecated 255 // deprecated
238 else if (!strcasecmp (arr[i], "tile")) 256 else if (!strcasecmp (arr[i], "tile"))
239 { 257 {
241 w = h = noScale; 259 w = h = noScale;
242 geom_flags |= WidthValue|HeightValue; 260 geom_flags |= WidthValue|HeightValue;
243 } 261 }
244 else if (!strcasecmp (arr[i], "propscale")) 262 else if (!strcasecmp (arr[i], "propscale"))
245 { 263 {
246 new_flags |= BG_PROP_SCALE; 264 new_flags |= BG_KEEP_ASPECT;
265 w = h = windowScale;
266 geom_flags |= WidthValue|HeightValue;
247 } 267 }
248 else if (!strcasecmp (arr[i], "hscale")) 268 else if (!strcasecmp (arr[i], "hscale"))
249 { 269 {
250 new_flags |= BG_TILE; 270 new_flags |= BG_TILE;
251 w = windowScale; 271 w = windowScale;
281 geom_flags |= XParseGeometry (arr[i], &x, &y, &w, &h); 301 geom_flags |= XParseGeometry (arr[i], &x, &y, &w, &h);
282 } /* done parsing ops */ 302 } /* done parsing ops */
283 303
284 rxvt_free_strsplit (arr); 304 rxvt_free_strsplit (arr);
285 } 305 }
306
307 new_flags |= bg_flags & ~BG_GEOMETRY_FLAGS;
286 308
287 if (!update) 309 if (!update)
288 { 310 {
289 if (!(geom_flags & XValue)) 311 if (!(geom_flags & XValue))
290 x = y = defaultAlign; 312 x = y = defaultAlign;
322 int target_height = szHint.height; 344 int target_height = szHint.height;
323 345
324 w = h_scale * target_width / 100; 346 w = h_scale * target_width / 100;
325 h = v_scale * target_height / 100; 347 h = v_scale * target_height / 100;
326 348
327 if (bg_flags & BG_PROP_SCALE) 349 if (bg_flags & BG_KEEP_ASPECT)
328 { 350 {
329 float scale = (float)w / image_width; 351 float scale = (float)w / image_width;
330 min_it (scale, (float)h / image_height); 352 min_it (scale, (float)h / image_height);
331 w = image_width * scale + 0.5; 353 w = image_width * scale + 0.5;
332 h = image_height * scale + 0.5; 354 h = image_height * scale + 0.5;
370 if (tr_flags & BG_NEEDS_TINT) 392 if (tr_flags & BG_NEEDS_TINT)
371 { 393 {
372 ShadingInfo as_shade; 394 ShadingInfo as_shade;
373 as_shade.shading = shade; 395 as_shade.shading = shade;
374 396
375 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 397 rgba c;
376 if (bg_flags & BG_TINT_SET)
377 tint.get (c); 398 tint.get (c);
378 as_shade.tintColor.red = c.r; 399 as_shade.tintColor.red = c.r;
379 as_shade.tintColor.green = c.g; 400 as_shade.tintColor.green = c.g;
380 as_shade.tintColor.blue = c.b; 401 as_shade.tintColor.blue = c.b;
381 402
382 background_tint = shading2tint32 (&as_shade); 403 background_tint = shading2tint32 (&as_shade);
383 } 404 }
384 405
385 if ((tr_flags & BG_NEEDS_BLUR) && background != NULL) 406 if ((tr_flags & BG_NEEDS_BLUR) && background != NULL)
386 { 407 {
387 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,
388 (original_asim == NULL || tint == TINT_LEAVE_SAME) ? ASA_XImage : ASA_ASImage, 409 ASA_XImage,
389 100, ASIMAGE_QUALITY_DEFAULT); 410 100, ASIMAGE_QUALITY_DEFAULT);
390 if (tmp) 411 if (tmp)
391 { 412 {
392 destroy_asimage (&background); 413 destroy_asimage (&background);
393 background = tmp; 414 background = tmp;
412 433
413 if (!original_asim 434 if (!original_asim
414 || (!(bg_flags & BG_ROOT_ALIGN) 435 || (!(bg_flags & BG_ROOT_ALIGN)
415 && (x >= target_width 436 && (x >= target_width
416 || y >= target_height 437 || y >= target_height
417 || (x + w <= 0) 438 || x + w <= 0
418 || (y + h <= 0)))) 439 || y + h <= 0)))
419 { 440 {
420 if (background) 441 if (background)
421 { 442 {
422 new_pmap_width = background->width; 443 new_pmap_width = background->width;
423 new_pmap_height = background->height; 444 new_pmap_height = background->height;
437 } 458 }
438 else 459 else
439 { 460 {
440 result = original_asim; 461 result = original_asim;
441 462
442 if ((w != original_asim->width) 463 if (w != original_asim->width
443 || (h != original_asim->height)) 464 || h != original_asim->height)
444 { 465 {
445 result = scale_asimage (asv, original_asim, 466 result = scale_asimage (asv, original_asim,
446 w, h, 467 w, h,
447 background ? ASA_ASImage : ASA_XImage, 468 ASA_XImage,
448 100, ASIMAGE_QUALITY_DEFAULT); 469 100, ASIMAGE_QUALITY_DEFAULT);
449 } 470 }
450 471
451 if (background == NULL) 472 if (background == NULL)
452 { 473 {
702 get_image_geometry (image_width, image_height, w, h, x, y); 723 get_image_geometry (image_width, image_height, w, h, x, y);
703 724
704 if (!(bg_flags & BG_ROOT_ALIGN) 725 if (!(bg_flags & BG_ROOT_ALIGN)
705 && (x >= target_width 726 && (x >= target_width
706 || y >= target_height 727 || y >= target_height
707 || (x + w <= 0) 728 || x + w <= 0
708 || (y + h <= 0))) 729 || y + h <= 0))
709 return false; 730 return false;
710 731
711 result = pixbuf; 732 result = pixbuf;
712 733
713 if ((w != image_width) 734 if (w != image_width
714 || (h != image_height)) 735 || h != image_height)
715 { 736 {
716 result = gdk_pixbuf_scale_simple (pixbuf, 737 result = gdk_pixbuf_scale_simple (pixbuf,
717 w, h, 738 w, h,
718 GDK_INTERP_BILINEAR); 739 GDK_INTERP_BILINEAR);
719 } 740 }
798 } 819 }
799 820
800#if XRENDER 821#if XRENDER
801 if (tr_flags) 822 if (tr_flags)
802 { 823 {
803 XRenderPictureAttributes pa;
804
805 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, visual); 824 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
825
806 Picture src = XRenderCreatePicture (dpy, root_pmap, src_format, 0, &pa); 826 Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0);
807 827
808 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
809 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, dst_format, 0, &pa); 828 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, format, 0, 0);
810 829
811 pa.repeat = True; 830 Picture mask = create_xrender_mask (dpy, vt, False, False);
812 Pixmap mask_pmap = XCreatePixmap (dpy, vt, 1, 1, 8);
813 XRenderPictFormat *mask_format = XRenderFindStandardFormat (dpy, PictStandardA8);
814 Picture mask = XRenderCreatePicture (dpy, mask_pmap, mask_format, CPRepeat, &pa);
815 XFreePixmap (dpy, mask_pmap);
816 831
817 XRenderColor mask_c; 832 XRenderColor mask_c;
818 833
819 mask_c.alpha = 0x8000; 834 mask_c.alpha = 0x8000;
820 mask_c.red = 0; 835 mask_c.red =
821 mask_c.green = 0; 836 mask_c.green =
822 mask_c.blue = 0; 837 mask_c.blue = 0;
823 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); 838 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
839
824 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);
825 841
826 XRenderFreePicture (dpy, src); 842 XRenderFreePicture (dpy, src);
827 XRenderFreePicture (dpy, dst); 843 XRenderFreePicture (dpy, dst);
828 XRenderFreePicture (dpy, mask); 844 XRenderFreePicture (dpy, mask);
848rxvt_term::bg_set_file (const char *file) 864rxvt_term::bg_set_file (const char *file)
849{ 865{
850 if (!file || !*file) 866 if (!file || !*file)
851 return false; 867 return false;
852 868
869 bool ret = false;
853 if (const char *p = strchr (file, ';')) 870 const char *p = strchr (file, ';');
871
872 if (p)
854 { 873 {
855 size_t len = p - file; 874 size_t len = p - file;
856 char *f = rxvt_temp_buf<char> (len + 1); 875 char *f = rxvt_temp_buf<char> (len + 1);
857 memcpy (f, file, len); 876 memcpy (f, file, len);
858 f[len] = '\0'; 877 f[len] = '\0';
867 { 886 {
868 if (original_asim) 887 if (original_asim)
869 safe_asimage_destroy (original_asim); 888 safe_asimage_destroy (original_asim);
870 original_asim = image; 889 original_asim = image;
871 bg_flags |= BG_IS_FROM_FILE | BG_CLIENT_RENDER; 890 bg_flags |= BG_IS_FROM_FILE | BG_CLIENT_RENDER;
872 return true; 891 ret = true;
873 } 892 }
874# endif 893# endif
875 894
876# ifdef HAVE_PIXBUF 895# ifdef HAVE_PIXBUF
877 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL); 896 GdkPixbuf *image = gdk_pixbuf_new_from_file (file, NULL);
879 { 898 {
880 if (pixbuf) 899 if (pixbuf)
881 g_object_unref (pixbuf); 900 g_object_unref (pixbuf);
882 pixbuf = image; 901 pixbuf = image;
883 bg_flags |= BG_IS_FROM_FILE; 902 bg_flags |= BG_IS_FROM_FILE;
884 return true; 903 ret = true;
885 } 904 }
886# endif 905# endif
887 906
907 if (ret)
908 {
909 if (p)
910 bg_set_geometry (p + 1);
911 else
912 bg_set_default_geometry ();
913 }
914
888 return false; 915 return ret;
889} 916}
890 917
891# endif /* BG_IMAGE_FROM_FILE */ 918# endif /* BG_IMAGE_FROM_FILE */
892 919
893# ifdef ENABLE_TRANSPARENCY 920# ifdef ENABLE_TRANSPARENCY
929 { 956 {
930 changed = true; 957 changed = true;
931 v_blurRadius = vr; 958 v_blurRadius = vr;
932 } 959 }
933 960
934 if (v_blurRadius == 0 && h_blurRadius == 0) 961 if (h_blurRadius == 0 || v_blurRadius == 0)
935 bg_flags &= ~BG_NEEDS_BLUR; 962 bg_flags &= ~BG_NEEDS_BLUR;
936 else 963 else
937 bg_flags |= BG_NEEDS_BLUR; 964 bg_flags |= BG_NEEDS_BLUR;
938 965
939 return changed; 966 return changed;
940} 967}
941 968
942void 969void
943rxvt_term::set_tint_shade_flags () 970rxvt_term::set_tint_shade_flags ()
944{ 971{
945 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 972 rgba c;
946 bool has_shade = shade != 100; 973 bool has_shade = shade != 100;
947 974
948 bg_flags &= ~BG_TINT_FLAGS; 975 bg_flags &= ~BG_TINT_FLAGS;
949 976
950 if (bg_flags & BG_TINT_SET)
951 {
952 tint.get (c); 977 tint.get (c);
978
953 if (!has_shade 979 if (!has_shade
954 && (c.r <= 0x00ff || c.r >= 0xff00) 980 && (c.r <= 0x00ff || c.r >= 0xff00)
955 && (c.g <= 0x00ff || c.g >= 0xff00) 981 && (c.g <= 0x00ff || c.g >= 0xff00)
956 && (c.b <= 0x00ff || c.b >= 0xff00)) 982 && (c.b <= 0x00ff || c.b >= 0xff00))
957 bg_flags |= BG_TINT_BITAND; 983 bg_flags |= BG_TINT_BITAND;
958 }
959 984
960 if (has_shade || (bg_flags & BG_TINT_SET)) 985 if (has_shade
986 || c.r < 0xff00
987 || c.g < 0xff00
988 || c.b < 0xff00)
961 bg_flags |= BG_NEEDS_TINT; 989 bg_flags |= BG_NEEDS_TINT;
962} 990}
963 991
964bool 992bool
965rxvt_term::bg_set_tint (rxvt_color &new_tint) 993rxvt_term::bg_set_tint (rxvt_color &new_tint)
966{ 994{
967 if (!(bg_flags & BG_TINT_SET) || tint != new_tint) 995 if (tint != new_tint)
968 { 996 {
969 tint = new_tint; 997 tint = new_tint;
970 bg_flags |= BG_TINT_SET;
971 set_tint_shade_flags (); 998 set_tint_shade_flags ();
972 return true; 999 return true;
973 } 1000 }
974 1001
975 return false; 1002 return false;
976} 1003}
977 1004
978bool 1005bool
979rxvt_term::bg_set_shade (const char *shade_str) 1006rxvt_term::bg_set_shade (const char *shade_str)
980{ 1007{
981 int new_shade = (shade_str) ? atoi (shade_str) : 100; 1008 int new_shade = atoi (shade_str);
982 1009
983 clamp_it (new_shade, -100, 200); 1010 clamp_it (new_shade, -100, 200);
984 if (new_shade < 0) 1011 if (new_shade < 0)
985 new_shade = 200 - (100 + new_shade); 1012 new_shade = 200 - (100 + new_shade);
986 1013
1020bool 1047bool
1021rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height) 1048rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height)
1022{ 1049{
1023 bool ret = false; 1050 bool ret = false;
1024#if XRENDER 1051#if XRENDER
1052 if (!(bg_flags & BG_HAS_RENDER_CONV))
1053 return false;
1054
1025 int size = max (h_blurRadius, v_blurRadius) * 2 + 1; 1055 int size = max (h_blurRadius, v_blurRadius) * 2 + 1;
1026 double *kernel = (double *)malloc (size * sizeof (double)); 1056 double *kernel = (double *)malloc (size * sizeof (double));
1027 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 1057 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
1028 1058
1029 XRenderPictureAttributes pa;
1030 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1059 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1031 1060
1032 Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1061 Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1033 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1062 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1034 1063
1035 if (kernel && params) 1064 if (kernel && params)
1036 { 1065 {
1037 if (h_blurRadius)
1038 {
1039 size = h_blurRadius * 2 + 1; 1066 size = h_blurRadius * 2 + 1;
1040 get_gaussian_kernel (h_blurRadius, size, kernel, params); 1067 get_gaussian_kernel (h_blurRadius, size, kernel, params);
1041 1068
1042 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1069 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1043 XRenderComposite (dpy, 1070 XRenderComposite (dpy,
1044 PictOpSrc, 1071 PictOpSrc,
1045 src, 1072 src,
1046 None, 1073 None,
1047 dst, 1074 dst,
1048 0, 0, 1075 0, 0,
1049 0, 0, 1076 0, 0,
1050 0, 0, 1077 0, 0,
1051 width, height); 1078 width, height);
1052 }
1053 1079
1054 if (v_blurRadius)
1055 {
1056 size = v_blurRadius * 2 + 1; 1080 size = v_blurRadius * 2 + 1;
1057 get_gaussian_kernel (v_blurRadius, size, kernel, params); 1081 get_gaussian_kernel (v_blurRadius, size, kernel, params);
1058 ::swap (params[0], params[1]); 1082 ::swap (params[0], params[1]);
1059 1083
1060 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1084 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1061 XRenderComposite (dpy, 1085 XRenderComposite (dpy,
1062 PictOpSrc, 1086 PictOpSrc,
1063 src, 1087 src,
1064 None, 1088 None,
1065 dst, 1089 dst,
1066 0, 0, 1090 0, 0,
1067 0, 0, 1091 0, 0,
1068 0, 0, 1092 0, 0,
1069 width, height); 1093 width, height);
1070 }
1071 1094
1072 ret = true; 1095 ret = true;
1073 } 1096 }
1074 1097
1075 free (kernel); 1098 free (kernel);
1102 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height); 1125 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height);
1103 ret = true; 1126 ret = true;
1104 XFreeGC (dpy, gc); 1127 XFreeGC (dpy, gc);
1105 } 1128 }
1106 } 1129 }
1107 else
1108 {
1109# if XRENDER 1130# if XRENDER
1110 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1131 else if (bg_flags & BG_HAS_RENDER)
1132 {
1133 rgba c;
1111 1134
1112 if (bg_flags & BG_TINT_SET)
1113 tint.get (c); 1135 tint.get (c);
1114 1136
1115 if (shade <= 100) 1137 if (shade <= 100)
1116 { 1138 {
1117 c.r = c.r * shade / 100; 1139 c.r = c.r * shade / 100;
1118 c.g = c.g * shade / 100; 1140 c.g = c.g * shade / 100;
1123 c.r = c.r * (200 - shade) / 100; 1145 c.r = c.r * (200 - shade) / 100;
1124 c.g = c.g * (200 - shade) / 100; 1146 c.g = c.g * (200 - shade) / 100;
1125 c.b = c.b * (200 - shade) / 100; 1147 c.b = c.b * (200 - shade) / 100;
1126 } 1148 }
1127 1149
1128 XRenderPictFormat *solid_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
1129 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1150 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1130 XRenderPictureAttributes pa;
1131 1151
1132 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1152 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1133 1153
1134 pa.repeat = True; 1154 Picture overlay_pic = create_xrender_mask (dpy, pixmap, True, False);
1135 1155
1136 Pixmap overlay_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32); 1156 Picture mask_pic = create_xrender_mask (dpy, pixmap, True, True);
1137 Picture overlay_pic = XRenderCreatePicture (dpy, overlay_pmap, solid_format, CPRepeat, &pa);
1138 XFreePixmap (dpy, overlay_pmap);
1139
1140 pa.component_alpha = True;
1141 Pixmap mask_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32);
1142 Picture mask_pic = XRenderCreatePicture (dpy, mask_pmap, solid_format, CPRepeat | CPComponentAlpha, &pa);
1143 XFreePixmap (dpy, mask_pmap);
1144 1157
1145 XRenderColor mask_c; 1158 XRenderColor mask_c;
1146 1159
1147 mask_c.alpha = 0xffff; 1160 mask_c.alpha = 0xffff;
1148 mask_c.red = 1161 mask_c.red =
1153 mask_c.alpha = 0; 1166 mask_c.alpha = 0;
1154 mask_c.red = 0xffff - c.r; 1167 mask_c.red = 0xffff - c.r;
1155 mask_c.green = 0xffff - c.g; 1168 mask_c.green = 0xffff - c.g;
1156 mask_c.blue = 0xffff - c.b; 1169 mask_c.blue = 0xffff - c.b;
1157 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); 1170 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1);
1171
1158 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);
1159 1173
1160 if (shade > 100) 1174 if (shade > 100)
1161 { 1175 {
1162 mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100;
1163 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;
1164 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); 1180 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1);
1165 1181
1166 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);
1167 } 1183 }
1168 1184
1169 ret = true; 1185 ret = true;
1170 1186
1171 XRenderFreePicture (dpy, mask_pic); 1187 XRenderFreePicture (dpy, mask_pic);
1172 XRenderFreePicture (dpy, overlay_pic); 1188 XRenderFreePicture (dpy, overlay_pic);
1173 XRenderFreePicture (dpy, back_pic); 1189 XRenderFreePicture (dpy, back_pic);
1190 }
1174# endif 1191# endif
1175 }
1176 1192
1177 return ret; 1193 return ret;
1178} 1194}
1179 1195
1180/* 1196/*
1231#if XRENDER 1247#if XRENDER
1232 if (bg_flags & BG_HAS_RENDER) 1248 if (bg_flags & BG_HAS_RENDER)
1233 { 1249 {
1234 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);
1235 1251
1236 XRenderPictureAttributes pa;
1237
1238 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); 1252 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
1239 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); 1253 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, 0);
1240 1254
1241 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); 1255 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
1242 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); 1256 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, 0);
1243 1257
1244 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);
1245 1259
1246 XRenderFreePicture (dpy, src); 1260 XRenderFreePicture (dpy, src);
1247 XRenderFreePicture (dpy, dst); 1261 XRenderFreePicture (dpy, dst);
1264 bg_pmap_width = window_width; 1278 bg_pmap_width = window_width;
1265 bg_pmap_height = window_height; 1279 bg_pmap_height = window_height;
1266 } 1280 }
1267 1281
1268 /* straightforward pixmap copy */ 1282 /* straightforward pixmap copy */
1269 while (sx < 0) sx += root_width; 1283 while (sx < 0) sx += root_pmap_width;
1270 while (sy < 0) sy += root_height; 1284 while (sy < 0) sy += root_pmap_height;
1271 1285
1272 gcv.tile = recoded_root_pmap; 1286 gcv.tile = recoded_root_pmap;
1273 gcv.fill_style = FillTiled; 1287 gcv.fill_style = FillTiled;
1274 gcv.ts_x_origin = -sx; 1288 gcv.ts_x_origin = -sx;
1275 gcv.ts_y_origin = -sy; 1289 gcv.ts_y_origin = -sy;
1277 1291
1278 if (gc) 1292 if (gc)
1279 { 1293 {
1280 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1294 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1281 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS); 1295 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS);
1282 XFreeGC (dpy, gc);
1283 1296
1284 if (!(bg_flags & BG_CLIENT_RENDER)) 1297 if (!(bg_flags & BG_CLIENT_RENDER))
1285 { 1298 {
1286 if ((bg_flags & BG_NEEDS_BLUR) 1299 if (bg_flags & BG_NEEDS_BLUR)
1287 && (bg_flags & BG_HAS_RENDER_CONV))
1288 { 1300 {
1289 if (blur_pixmap (bg_pixmap, visual, window_width, window_height)) 1301 if (blur_pixmap (bg_pixmap, visual, window_width, window_height))
1290 result &= ~BG_NEEDS_BLUR; 1302 result &= ~BG_NEEDS_BLUR;
1291 } 1303 }
1292 if ((bg_flags & BG_NEEDS_TINT) 1304 if (bg_flags & BG_NEEDS_TINT)
1293 && (bg_flags & (BG_TINT_BITAND | BG_HAS_RENDER)))
1294 { 1305 {
1295 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1306 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1296 result &= ~BG_NEEDS_TINT; 1307 result &= ~BG_NEEDS_TINT;
1297 } 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
1298 } /* server side rendering completed */ 1323 } /* server side rendering completed */
1324
1325 XFreeGC (dpy, gc);
1299 } 1326 }
1300 1327
1301 if (recoded_root_pmap != root_pixmap) 1328 if (recoded_root_pmap != root_pixmap)
1302 XFreePixmap (dpy, recoded_root_pmap); 1329 XFreePixmap (dpy, recoded_root_pmap);
1303 1330
1312 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]); 1339 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]);
1313 1340
1314 root_pixmap = new_root_pixmap; 1341 root_pixmap = new_root_pixmap;
1315} 1342}
1316# endif /* ENABLE_TRANSPARENCY */ 1343# endif /* ENABLE_TRANSPARENCY */
1317
1318#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1319static void shade_ximage (Visual *visual, XImage *ximage, int shade, const rgba &c);
1320# endif
1321 1344
1322bool 1345bool
1323rxvt_term::bg_render () 1346rxvt_term::bg_render ()
1324{ 1347{
1325 unsigned long tr_flags = 0; 1348 unsigned long tr_flags = 0;
1330 { 1353 {
1331 /* we need to re-generate transparency pixmap in that case ! */ 1354 /* we need to re-generate transparency pixmap in that case ! */
1332 tr_flags = make_transparency_pixmap (); 1355 tr_flags = make_transparency_pixmap ();
1333 if (tr_flags == 0) 1356 if (tr_flags == 0)
1334 return false; 1357 return false;
1335 else if (!(tr_flags & BG_EFFECTS_FLAGS))
1336 bg_flags |= BG_IS_VALID; 1358 bg_flags |= BG_IS_VALID;
1337 } 1359 }
1338# endif 1360# endif
1339 1361
1340# ifdef BG_IMAGE_FROM_FILE 1362# ifdef BG_IMAGE_FROM_FILE
1341 if ((bg_flags & BG_IS_FROM_FILE) 1363 if ((bg_flags & BG_IS_FROM_FILE)
1344 if (render_image (tr_flags)) 1366 if (render_image (tr_flags))
1345 bg_flags |= BG_IS_VALID; 1367 bg_flags |= BG_IS_VALID;
1346 } 1368 }
1347# endif 1369# endif
1348 1370
1349# if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1350 XImage *result = NULL;
1351
1352 if (tr_flags && !(bg_flags & BG_IS_VALID))
1353 {
1354 result = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1355 }
1356
1357 if (result)
1358 {
1359 /* our own client-side tinting */
1360 if (tr_flags & BG_NEEDS_TINT)
1361 {
1362 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC);
1363 if (bg_flags & BG_TINT_SET)
1364 tint.get (c);
1365 shade_ximage (DefaultVisual (dpy, display->screen), result, shade, c);
1366 }
1367
1368 GC gc = XCreateGC (dpy, vt, 0UL, NULL);
1369
1370 if (gc)
1371 {
1372 XPutImage (dpy, bg_pixmap, gc, result, 0, 0, 0, 0, result->width, result->height);
1373
1374 XFreeGC (dpy, gc);
1375 bg_flags |= BG_IS_VALID;
1376 }
1377
1378 XDestroyImage (result);
1379 }
1380# endif
1381
1382 if (!(bg_flags & BG_IS_VALID)) 1371 if (!(bg_flags & BG_IS_VALID))
1383 { 1372 {
1384 if (bg_pixmap != None) 1373 if (bg_pixmap != None)
1385 { 1374 {
1386 XFreePixmap (dpy, bg_pixmap); 1375 XFreePixmap (dpy, bg_pixmap);
1398 1387
1399void 1388void
1400rxvt_term::bg_init () 1389rxvt_term::bg_init ()
1401{ 1390{
1402#ifdef ENABLE_TRANSPARENCY 1391#ifdef ENABLE_TRANSPARENCY
1392 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1393 tint.set (this, c);
1403 shade = 100; 1394 shade = 100;
1404#endif 1395#endif
1405 1396
1406 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV); 1397 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV);
1407#if XRENDER 1398#if XRENDER
1416 bg_flags |= BG_HAS_RENDER_CONV; 1407 bg_flags |= BG_HAS_RENDER_CONV;
1417 1408
1418 XFree (filters); 1409 XFree (filters);
1419 } 1410 }
1420#endif 1411#endif
1421
1422#ifdef HAVE_AFTERIMAGE
1423 set_application_name ((char *)rs[Rs_name]);
1424 set_output_threshold (OUTPUT_LEVEL_WARNING);
1425#endif
1426
1427#ifdef HAVE_PIXBUF
1428 g_type_init ();
1429#endif
1430} 1412}
1431 1413
1432#endif /* HAVE_BG_PIXMAP */ 1414#endif /* HAVE_BG_PIXMAP */
1433 1415
1434#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) 1416#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1435/* taken from aterm-0.4.2 */ 1417/* based on code from aterm-0.4.2 */
1436 1418
1437static void 1419static inline void
1438shade_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)
1439{ 1433{
1440 int sh_r, sh_g, sh_b; 1434 int sh_r, sh_g, sh_b;
1441 uint32_t mask_r, mask_g, mask_b; 1435 uint32_t mask_r, mask_g, mask_b;
1442 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1436 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1443 rgba low; 1437 unsigned short low;
1444 rgba high;
1445 int i;
1446 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1438 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1447 1439
1448 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return; 1440 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return;
1449 1441
1450 /* for convenience */ 1442 /* for convenience */
1509 break; 1501 break;
1510 default: 1502 default:
1511 return; /* we do not support this color depth */ 1503 return; /* we do not support this color depth */
1512 } 1504 }
1513 1505
1506 rgba c;
1507
1508 tint.get (c);
1509
1514 /* prepare limits for color transformation (each channel is handled separately) */ 1510 /* prepare limits for color transformation (each channel is handled separately) */
1515 if (shade > 100) 1511 if (shade > 100)
1516 { 1512 {
1517 shade = 200 - shade;
1518
1519 high.r = c.r * shade / 100;
1520 high.g = c.g * shade / 100;
1521 high.b = c.b * shade / 100;
1522
1523 low.r = 65535 * (100 - shade) / 100; 1513 c.r = c.r * (200 - shade) / 100;
1524 low.g = 65535 * (100 - shade) / 100; 1514 c.g = c.g * (200 - shade) / 100;
1525 low.b = 65535 * (100 - shade) / 100; 1515 c.b = c.b * (200 - shade) / 100;
1516
1517 low = 0xffff * (shade - 100) / 100;
1526 } 1518 }
1527 else 1519 else
1528 { 1520 {
1529 high.r = c.r * shade / 100; 1521 c.r = c.r * shade / 100;
1530 high.g = c.g * shade / 100; 1522 c.g = c.g * shade / 100;
1531 high.b = c.b * shade / 100; 1523 c.b = c.b * shade / 100;
1532 1524
1533 low.r = low.g = low.b = 0; 1525 low = 0;
1534 } 1526 }
1535 1527
1536 /* fill our lookup tables */ 1528 /* fill our lookup tables */
1537 for (i = 0; i <= mask_r>>sh_r; i++) 1529 fill_lut (lookup_r, mask_r, sh_r, low, c.r);
1538 { 1530 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1539 uint32_t tmp; 1531 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1540 tmp = i * high.r;
1541 tmp += (mask_r>>sh_r) * low.r;
1542 lookup_r[i] = (tmp/65535)<<sh_r;
1543 }
1544 for (i = 0; i <= mask_g>>sh_g; i++)
1545 {
1546 uint32_t tmp;
1547 tmp = i * high.g;
1548 tmp += (mask_g>>sh_g) * low.g;
1549 lookup_g[i] = (tmp/65535)<<sh_g;
1550 }
1551 for (i = 0; i <= mask_b>>sh_b; i++)
1552 {
1553 uint32_t tmp;
1554 tmp = i * high.b;
1555 tmp += (mask_b>>sh_b) * low.b;
1556 lookup_b[i] = (tmp/65535)<<sh_b;
1557 }
1558 1532
1559 /* apply table to input image (replacing colors by newly calculated ones) */ 1533 /* apply table to input image (replacing colors by newly calculated ones) */
1560 if (ximage->bits_per_pixel == 32 1534 if (ximage->bits_per_pixel == 32
1561 && (ximage->depth == 24 || ximage->depth == 32) 1535 && (ximage->depth == 24 || ximage->depth == 32)
1562 && ximage->byte_order == host_byte_order) 1536 && ximage->byte_order == host_byte_order)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines