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.170 by sf-exg, Sun Aug 21 11:00:02 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);
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 ASA_XImage, 468 ASA_XImage,
448 100, ASIMAGE_QUALITY_DEFAULT); 469 100, ASIMAGE_QUALITY_DEFAULT);
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);
940 { 956 {
941 changed = true; 957 changed = true;
942 v_blurRadius = vr; 958 v_blurRadius = vr;
943 } 959 }
944 960
945 if (v_blurRadius == 0 && h_blurRadius == 0) 961 if (h_blurRadius == 0 || v_blurRadius == 0)
946 bg_flags &= ~BG_NEEDS_BLUR; 962 bg_flags &= ~BG_NEEDS_BLUR;
947 else 963 else
948 bg_flags |= BG_NEEDS_BLUR; 964 bg_flags |= BG_NEEDS_BLUR;
949 965
950 return changed; 966 return changed;
951} 967}
952 968
953void 969void
954rxvt_term::set_tint_shade_flags () 970rxvt_term::set_tint_shade_flags ()
955{ 971{
956 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 972 rgba c;
957 bool has_shade = shade != 100; 973 bool has_shade = shade != 100;
958 974
959 bg_flags &= ~BG_TINT_FLAGS; 975 bg_flags &= ~BG_TINT_FLAGS;
960 976
961 if (bg_flags & BG_TINT_SET)
962 {
963 tint.get (c); 977 tint.get (c);
978
964 if (!has_shade 979 if (!has_shade
965 && (c.r <= 0x00ff || c.r >= 0xff00) 980 && (c.r <= 0x00ff || c.r >= 0xff00)
966 && (c.g <= 0x00ff || c.g >= 0xff00) 981 && (c.g <= 0x00ff || c.g >= 0xff00)
967 && (c.b <= 0x00ff || c.b >= 0xff00)) 982 && (c.b <= 0x00ff || c.b >= 0xff00))
968 bg_flags |= BG_TINT_BITAND; 983 bg_flags |= BG_TINT_BITAND;
969 }
970 984
971 if (has_shade || (bg_flags & BG_TINT_SET)) 985 if (has_shade
986 || c.r < 0xff00
987 || c.g < 0xff00
988 || c.b < 0xff00)
972 bg_flags |= BG_NEEDS_TINT; 989 bg_flags |= BG_NEEDS_TINT;
973} 990}
974 991
975bool 992bool
976rxvt_term::bg_set_tint (rxvt_color &new_tint) 993rxvt_term::bg_set_tint (rxvt_color &new_tint)
977{ 994{
978 if (!(bg_flags & BG_TINT_SET) || tint != new_tint) 995 if (tint != new_tint)
979 { 996 {
980 tint = new_tint; 997 tint = new_tint;
981 bg_flags |= BG_TINT_SET;
982 set_tint_shade_flags (); 998 set_tint_shade_flags ();
983 return true; 999 return true;
984 } 1000 }
985 1001
986 return false; 1002 return false;
987} 1003}
988 1004
989bool 1005bool
990rxvt_term::bg_set_shade (const char *shade_str) 1006rxvt_term::bg_set_shade (const char *shade_str)
991{ 1007{
992 int new_shade = (shade_str) ? atoi (shade_str) : 100; 1008 int new_shade = atoi (shade_str);
993 1009
994 clamp_it (new_shade, -100, 200); 1010 clamp_it (new_shade, -100, 200);
995 if (new_shade < 0) 1011 if (new_shade < 0)
996 new_shade = 200 - (100 + new_shade); 1012 new_shade = 200 - (100 + new_shade);
997 1013
1031bool 1047bool
1032rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height) 1048rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height)
1033{ 1049{
1034 bool ret = false; 1050 bool ret = false;
1035#if XRENDER 1051#if XRENDER
1052 if (!(bg_flags & BG_HAS_RENDER_CONV))
1053 return false;
1054
1036 int size = max (h_blurRadius, v_blurRadius) * 2 + 1; 1055 int size = max (h_blurRadius, v_blurRadius) * 2 + 1;
1037 double *kernel = (double *)malloc (size * sizeof (double)); 1056 double *kernel = (double *)malloc (size * sizeof (double));
1038 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 1057 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
1039 1058
1040 XRenderPictureAttributes pa;
1041 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1059 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1042 1060
1043 Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1061 Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1044 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1062 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1045 1063
1046 if (kernel && params) 1064 if (kernel && params)
1047 { 1065 {
1048 if (h_blurRadius)
1049 {
1050 size = h_blurRadius * 2 + 1; 1066 size = h_blurRadius * 2 + 1;
1051 get_gaussian_kernel (h_blurRadius, size, kernel, params); 1067 get_gaussian_kernel (h_blurRadius, size, kernel, params);
1052 1068
1053 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1069 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1054 XRenderComposite (dpy, 1070 XRenderComposite (dpy,
1055 PictOpSrc, 1071 PictOpSrc,
1056 src, 1072 src,
1057 None, 1073 None,
1058 dst, 1074 dst,
1059 0, 0, 1075 0, 0,
1060 0, 0, 1076 0, 0,
1061 0, 0, 1077 0, 0,
1062 width, height); 1078 width, height);
1063 }
1064 1079
1065 if (v_blurRadius)
1066 {
1067 size = v_blurRadius * 2 + 1; 1080 size = v_blurRadius * 2 + 1;
1068 get_gaussian_kernel (v_blurRadius, size, kernel, params); 1081 get_gaussian_kernel (v_blurRadius, size, kernel, params);
1069 ::swap (params[0], params[1]); 1082 ::swap (params[0], params[1]);
1070 1083
1071 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1084 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1072 XRenderComposite (dpy, 1085 XRenderComposite (dpy,
1073 PictOpSrc, 1086 PictOpSrc,
1074 src, 1087 src,
1075 None, 1088 None,
1076 dst, 1089 dst,
1077 0, 0, 1090 0, 0,
1078 0, 0, 1091 0, 0,
1079 0, 0, 1092 0, 0,
1080 width, height); 1093 width, height);
1081 }
1082 1094
1083 ret = true; 1095 ret = true;
1084 } 1096 }
1085 1097
1086 free (kernel); 1098 free (kernel);
1113 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height); 1125 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height);
1114 ret = true; 1126 ret = true;
1115 XFreeGC (dpy, gc); 1127 XFreeGC (dpy, gc);
1116 } 1128 }
1117 } 1129 }
1118 else
1119 {
1120# if XRENDER 1130# if XRENDER
1121 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1131 else if (bg_flags & BG_HAS_RENDER)
1132 {
1133 rgba c;
1122 1134
1123 if (bg_flags & BG_TINT_SET)
1124 tint.get (c); 1135 tint.get (c);
1125 1136
1126 if (shade <= 100) 1137 if (shade <= 100)
1127 { 1138 {
1128 c.r = c.r * shade / 100; 1139 c.r = c.r * shade / 100;
1129 c.g = c.g * shade / 100; 1140 c.g = c.g * shade / 100;
1134 c.r = c.r * (200 - shade) / 100; 1145 c.r = c.r * (200 - shade) / 100;
1135 c.g = c.g * (200 - shade) / 100; 1146 c.g = c.g * (200 - shade) / 100;
1136 c.b = c.b * (200 - shade) / 100; 1147 c.b = c.b * (200 - shade) / 100;
1137 } 1148 }
1138 1149
1139 XRenderPictFormat *solid_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
1140 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1150 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1141 XRenderPictureAttributes pa;
1142 1151
1143 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1152 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1144 1153
1145 pa.repeat = True; 1154 Picture overlay_pic = create_xrender_mask (dpy, pixmap, True, False);
1146 1155
1147 Pixmap overlay_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32); 1156 Picture mask_pic = create_xrender_mask (dpy, pixmap, True, True);
1148 Picture overlay_pic = XRenderCreatePicture (dpy, overlay_pmap, solid_format, CPRepeat, &pa);
1149 XFreePixmap (dpy, overlay_pmap);
1150
1151 pa.component_alpha = True;
1152 Pixmap mask_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32);
1153 Picture mask_pic = XRenderCreatePicture (dpy, mask_pmap, solid_format, CPRepeat | CPComponentAlpha, &pa);
1154 XFreePixmap (dpy, mask_pmap);
1155 1157
1156 XRenderColor mask_c; 1158 XRenderColor mask_c;
1157 1159
1158 mask_c.alpha = 0xffff; 1160 mask_c.alpha = 0xffff;
1159 mask_c.red = 1161 mask_c.red =
1164 mask_c.alpha = 0; 1166 mask_c.alpha = 0;
1165 mask_c.red = 0xffff - c.r; 1167 mask_c.red = 0xffff - c.r;
1166 mask_c.green = 0xffff - c.g; 1168 mask_c.green = 0xffff - c.g;
1167 mask_c.blue = 0xffff - c.b; 1169 mask_c.blue = 0xffff - c.b;
1168 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); 1170 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1);
1171
1169 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);
1170 1173
1171 if (shade > 100) 1174 if (shade > 100)
1172 { 1175 {
1173 mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100;
1174 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;
1175 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); 1180 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1);
1176 1181
1177 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);
1178 } 1183 }
1179 1184
1180 ret = true; 1185 ret = true;
1181 1186
1182 XRenderFreePicture (dpy, mask_pic); 1187 XRenderFreePicture (dpy, mask_pic);
1183 XRenderFreePicture (dpy, overlay_pic); 1188 XRenderFreePicture (dpy, overlay_pic);
1184 XRenderFreePicture (dpy, back_pic); 1189 XRenderFreePicture (dpy, back_pic);
1190 }
1185# endif 1191# endif
1186 }
1187 1192
1188 return ret; 1193 return ret;
1189} 1194}
1190 1195
1191/* 1196/*
1242#if XRENDER 1247#if XRENDER
1243 if (bg_flags & BG_HAS_RENDER) 1248 if (bg_flags & BG_HAS_RENDER)
1244 { 1249 {
1245 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);
1246 1251
1247 XRenderPictureAttributes pa;
1248
1249 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); 1252 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
1250 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); 1253 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, 0);
1251 1254
1252 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); 1255 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
1253 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); 1256 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, 0);
1254 1257
1255 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);
1256 1259
1257 XRenderFreePicture (dpy, src); 1260 XRenderFreePicture (dpy, src);
1258 XRenderFreePicture (dpy, dst); 1261 XRenderFreePicture (dpy, dst);
1275 bg_pmap_width = window_width; 1278 bg_pmap_width = window_width;
1276 bg_pmap_height = window_height; 1279 bg_pmap_height = window_height;
1277 } 1280 }
1278 1281
1279 /* straightforward pixmap copy */ 1282 /* straightforward pixmap copy */
1280 while (sx < 0) sx += root_width; 1283 while (sx < 0) sx += root_pmap_width;
1281 while (sy < 0) sy += root_height; 1284 while (sy < 0) sy += root_pmap_height;
1282 1285
1283 gcv.tile = recoded_root_pmap; 1286 gcv.tile = recoded_root_pmap;
1284 gcv.fill_style = FillTiled; 1287 gcv.fill_style = FillTiled;
1285 gcv.ts_x_origin = -sx; 1288 gcv.ts_x_origin = -sx;
1286 gcv.ts_y_origin = -sy; 1289 gcv.ts_y_origin = -sy;
1288 1291
1289 if (gc) 1292 if (gc)
1290 { 1293 {
1291 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1294 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1292 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS); 1295 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS);
1293 XFreeGC (dpy, gc);
1294 1296
1295 if (!(bg_flags & BG_CLIENT_RENDER)) 1297 if (!(bg_flags & BG_CLIENT_RENDER))
1296 { 1298 {
1297 if ((bg_flags & BG_NEEDS_BLUR) 1299 if (bg_flags & BG_NEEDS_BLUR)
1298 && (bg_flags & BG_HAS_RENDER_CONV))
1299 { 1300 {
1300 if (blur_pixmap (bg_pixmap, visual, window_width, window_height)) 1301 if (blur_pixmap (bg_pixmap, visual, window_width, window_height))
1301 result &= ~BG_NEEDS_BLUR; 1302 result &= ~BG_NEEDS_BLUR;
1302 } 1303 }
1303 if ((bg_flags & BG_NEEDS_TINT) 1304 if (bg_flags & BG_NEEDS_TINT)
1304 && (bg_flags & (BG_TINT_BITAND | BG_HAS_RENDER)))
1305 { 1305 {
1306 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1306 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1307 result &= ~BG_NEEDS_TINT; 1307 result &= ~BG_NEEDS_TINT;
1308 } 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
1309 } /* server side rendering completed */ 1323 } /* server side rendering completed */
1324
1325 XFreeGC (dpy, gc);
1310 } 1326 }
1311 1327
1312 if (recoded_root_pmap != root_pixmap) 1328 if (recoded_root_pmap != root_pixmap)
1313 XFreePixmap (dpy, recoded_root_pmap); 1329 XFreePixmap (dpy, recoded_root_pmap);
1314 1330
1323 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]); 1339 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]);
1324 1340
1325 root_pixmap = new_root_pixmap; 1341 root_pixmap = new_root_pixmap;
1326} 1342}
1327# endif /* ENABLE_TRANSPARENCY */ 1343# endif /* ENABLE_TRANSPARENCY */
1328
1329#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1330static void shade_ximage (Visual *visual, XImage *ximage, int shade, const rgba &c);
1331# endif
1332 1344
1333bool 1345bool
1334rxvt_term::bg_render () 1346rxvt_term::bg_render ()
1335{ 1347{
1336 unsigned long tr_flags = 0; 1348 unsigned long tr_flags = 0;
1341 { 1353 {
1342 /* we need to re-generate transparency pixmap in that case ! */ 1354 /* we need to re-generate transparency pixmap in that case ! */
1343 tr_flags = make_transparency_pixmap (); 1355 tr_flags = make_transparency_pixmap ();
1344 if (tr_flags == 0) 1356 if (tr_flags == 0)
1345 return false; 1357 return false;
1346 else if (!(tr_flags & BG_EFFECTS_FLAGS))
1347 bg_flags |= BG_IS_VALID; 1358 bg_flags |= BG_IS_VALID;
1348 } 1359 }
1349# endif 1360# endif
1350 1361
1351# ifdef BG_IMAGE_FROM_FILE 1362# ifdef BG_IMAGE_FROM_FILE
1352 if ((bg_flags & BG_IS_FROM_FILE) 1363 if ((bg_flags & BG_IS_FROM_FILE)
1355 if (render_image (tr_flags)) 1366 if (render_image (tr_flags))
1356 bg_flags |= BG_IS_VALID; 1367 bg_flags |= BG_IS_VALID;
1357 } 1368 }
1358# endif 1369# endif
1359 1370
1360# if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1361 XImage *result = NULL;
1362
1363 if (tr_flags && !(bg_flags & BG_IS_VALID))
1364 {
1365 result = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1366 }
1367
1368 if (result)
1369 {
1370 /* our own client-side tinting */
1371 if (tr_flags & BG_NEEDS_TINT)
1372 {
1373 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC);
1374 if (bg_flags & BG_TINT_SET)
1375 tint.get (c);
1376 shade_ximage (DefaultVisual (dpy, display->screen), result, shade, c);
1377 }
1378
1379 GC gc = XCreateGC (dpy, vt, 0UL, NULL);
1380
1381 if (gc)
1382 {
1383 XPutImage (dpy, bg_pixmap, gc, result, 0, 0, 0, 0, result->width, result->height);
1384
1385 XFreeGC (dpy, gc);
1386 bg_flags |= BG_IS_VALID;
1387 }
1388
1389 XDestroyImage (result);
1390 }
1391# endif
1392
1393 if (!(bg_flags & BG_IS_VALID)) 1371 if (!(bg_flags & BG_IS_VALID))
1394 { 1372 {
1395 if (bg_pixmap != None) 1373 if (bg_pixmap != None)
1396 { 1374 {
1397 XFreePixmap (dpy, bg_pixmap); 1375 XFreePixmap (dpy, bg_pixmap);
1409 1387
1410void 1388void
1411rxvt_term::bg_init () 1389rxvt_term::bg_init ()
1412{ 1390{
1413#ifdef ENABLE_TRANSPARENCY 1391#ifdef ENABLE_TRANSPARENCY
1392 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1393 tint.set (this, c);
1414 shade = 100; 1394 shade = 100;
1415#endif 1395#endif
1416 1396
1417 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV); 1397 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV);
1418#if XRENDER 1398#if XRENDER
1434#endif /* HAVE_BG_PIXMAP */ 1414#endif /* HAVE_BG_PIXMAP */
1435 1415
1436#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) 1416#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1437/* based on code from aterm-0.4.2 */ 1417/* based on code from aterm-0.4.2 */
1438 1418
1439static void 1419static inline void
1440shade_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)
1441{ 1433{
1442 int sh_r, sh_g, sh_b; 1434 int sh_r, sh_g, sh_b;
1443 uint32_t mask_r, mask_g, mask_b; 1435 uint32_t mask_r, mask_g, mask_b;
1444 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1436 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1445 rgba low; 1437 unsigned short low;
1446 rgba high;
1447 int i;
1448 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1438 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1449 1439
1450 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return; 1440 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return;
1451 1441
1452 /* for convenience */ 1442 /* for convenience */
1511 break; 1501 break;
1512 default: 1502 default:
1513 return; /* we do not support this color depth */ 1503 return; /* we do not support this color depth */
1514 } 1504 }
1515 1505
1506 rgba c;
1507
1508 tint.get (c);
1509
1516 /* prepare limits for color transformation (each channel is handled separately) */ 1510 /* prepare limits for color transformation (each channel is handled separately) */
1517 if (shade > 100) 1511 if (shade > 100)
1518 { 1512 {
1519 shade = 200 - shade;
1520
1521 high.r = c.r * shade / 100;
1522 high.g = c.g * shade / 100;
1523 high.b = c.b * shade / 100;
1524
1525 low.r = 65535 * (100 - shade) / 100; 1513 c.r = c.r * (200 - shade) / 100;
1526 low.g = 65535 * (100 - shade) / 100; 1514 c.g = c.g * (200 - shade) / 100;
1527 low.b = 65535 * (100 - shade) / 100; 1515 c.b = c.b * (200 - shade) / 100;
1516
1517 low = 0xffff * (shade - 100) / 100;
1528 } 1518 }
1529 else 1519 else
1530 { 1520 {
1531 high.r = c.r * shade / 100; 1521 c.r = c.r * shade / 100;
1532 high.g = c.g * shade / 100; 1522 c.g = c.g * shade / 100;
1533 high.b = c.b * shade / 100; 1523 c.b = c.b * shade / 100;
1534 1524
1535 low.r = low.g = low.b = 0; 1525 low = 0;
1536 } 1526 }
1537 1527
1538 /* fill our lookup tables */ 1528 /* fill our lookup tables */
1539 for (i = 0; i <= mask_r>>sh_r; i++) 1529 fill_lut (lookup_r, mask_r, sh_r, low, c.r);
1540 { 1530 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1541 uint32_t tmp; 1531 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1542 tmp = i * high.r;
1543 tmp += (mask_r>>sh_r) * low.r;
1544 lookup_r[i] = (tmp/65535)<<sh_r;
1545 }
1546 for (i = 0; i <= mask_g>>sh_g; i++)
1547 {
1548 uint32_t tmp;
1549 tmp = i * high.g;
1550 tmp += (mask_g>>sh_g) * low.g;
1551 lookup_g[i] = (tmp/65535)<<sh_g;
1552 }
1553 for (i = 0; i <= mask_b>>sh_b; i++)
1554 {
1555 uint32_t tmp;
1556 tmp = i * high.b;
1557 tmp += (mask_b>>sh_b) * low.b;
1558 lookup_b[i] = (tmp/65535)<<sh_b;
1559 }
1560 1532
1561 /* apply table to input image (replacing colors by newly calculated ones) */ 1533 /* apply table to input image (replacing colors by newly calculated ones) */
1562 if (ximage->bits_per_pixel == 32 1534 if (ximage->bits_per_pixel == 32
1563 && (ximage->depth == 24 || ximage->depth == 32) 1535 && (ximage->depth == 24 || ximage->depth == 32)
1564 && ximage->byte_order == host_byte_order) 1536 && ximage->byte_order == host_byte_order)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines