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.175 by sf-exg, Mon Dec 5 18:17:17 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#ifndef RepeatPad
38#define RepeatPad True
39#endif
40
37#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
38void 60void
39rxvt_term::bg_destroy () 61rxvt_term::bg_destroy ()
40{ 62{
41#ifdef HAVE_AFTERIMAGE 63#ifdef HAVE_AFTERIMAGE
42 if (original_asim) 64 if (original_asim)
169 src_pos = -pos; 191 src_pos = -pos;
170 dst_pos = 0; 192 dst_pos = 0;
171 dst_size += pos; 193 dst_size += pos;
172 } 194 }
173 195
174 if (dst_pos + dst_size > target_size)
175 dst_size = target_size - dst_pos; 196 min_it (dst_size, target_size - dst_pos);
176 return src_pos; 197 return src_pos;
177} 198}
178 199
179bool 200bool
180rxvt_term::bg_set_geometry (const char *geom, bool update) 201rxvt_term::bg_set_geometry (const char *geom, bool update)
181{ 202{
182 bool changed = false; 203 bool changed = false;
183 int geom_flags = 0; 204 int geom_flags = 0;
184 int x = 0, y = 0; 205 int x = 0, y = 0;
185 unsigned int w = 0, h = 0; 206 unsigned int w = 0, h = 0;
186 unsigned long new_flags = bg_flags & ~BG_GEOMETRY_FLAGS; 207 unsigned long new_flags = 0;
187 208
188 if (geom == NULL) 209 if (geom == NULL)
189 return false; 210 return false;
190 211
191 if (geom[0]) 212 if (geom[0])
201 x = y = 0; 222 x = y = 0;
202 geom_flags = WidthValue|HeightValue|XValue|YValue; 223 geom_flags = WidthValue|HeightValue|XValue|YValue;
203 } 224 }
204 else if (!strcasecmp (arr[i], "style=aspect-stretched")) 225 else if (!strcasecmp (arr[i], "style=aspect-stretched"))
205 { 226 {
206 new_flags = BG_PROP_SCALE; 227 new_flags = BG_KEEP_ASPECT;
207 w = h = windowScale; 228 w = h = windowScale;
208 x = y = centerAlign; 229 x = y = centerAlign;
209 geom_flags = WidthValue|HeightValue|XValue|YValue; 230 geom_flags = WidthValue|HeightValue|XValue|YValue;
210 } 231 }
211 else if (!strcasecmp (arr[i], "style=stretched")) 232 else if (!strcasecmp (arr[i], "style=stretched"))
227 w = h = noScale; 248 w = h = noScale;
228 geom_flags = WidthValue|HeightValue; 249 geom_flags = WidthValue|HeightValue;
229 } 250 }
230 else if (!strcasecmp (arr[i], "op=tile")) 251 else if (!strcasecmp (arr[i], "op=tile"))
231 new_flags |= BG_TILE; 252 new_flags |= BG_TILE;
232 else if (!strcasecmp (arr[i], "op=pscale")) 253 else if (!strcasecmp (arr[i], "op=keep-aspect"))
233 new_flags |= BG_PROP_SCALE; 254 new_flags |= BG_KEEP_ASPECT;
234 else if (!strcasecmp (arr[i], "op=root")) 255 else if (!strcasecmp (arr[i], "op=root-align"))
235 new_flags |= BG_ROOT_ALIGN; 256 new_flags |= BG_ROOT_ALIGN;
236 257
237 // deprecated 258 // deprecated
238 else if (!strcasecmp (arr[i], "tile")) 259 else if (!strcasecmp (arr[i], "tile"))
239 { 260 {
241 w = h = noScale; 262 w = h = noScale;
242 geom_flags |= WidthValue|HeightValue; 263 geom_flags |= WidthValue|HeightValue;
243 } 264 }
244 else if (!strcasecmp (arr[i], "propscale")) 265 else if (!strcasecmp (arr[i], "propscale"))
245 { 266 {
246 new_flags |= BG_PROP_SCALE; 267 new_flags |= BG_KEEP_ASPECT;
268 w = h = windowScale;
269 geom_flags |= WidthValue|HeightValue;
247 } 270 }
248 else if (!strcasecmp (arr[i], "hscale")) 271 else if (!strcasecmp (arr[i], "hscale"))
249 { 272 {
250 new_flags |= BG_TILE; 273 new_flags |= BG_TILE;
251 w = windowScale; 274 w = windowScale;
281 geom_flags |= XParseGeometry (arr[i], &x, &y, &w, &h); 304 geom_flags |= XParseGeometry (arr[i], &x, &y, &w, &h);
282 } /* done parsing ops */ 305 } /* done parsing ops */
283 306
284 rxvt_free_strsplit (arr); 307 rxvt_free_strsplit (arr);
285 } 308 }
309
310 new_flags |= bg_flags & ~BG_GEOMETRY_FLAGS;
286 311
287 if (!update) 312 if (!update)
288 { 313 {
289 if (!(geom_flags & XValue)) 314 if (!(geom_flags & XValue))
290 x = y = defaultAlign; 315 x = y = defaultAlign;
322 int target_height = szHint.height; 347 int target_height = szHint.height;
323 348
324 w = h_scale * target_width / 100; 349 w = h_scale * target_width / 100;
325 h = v_scale * target_height / 100; 350 h = v_scale * target_height / 100;
326 351
327 if (bg_flags & BG_PROP_SCALE) 352 if (bg_flags & BG_KEEP_ASPECT)
328 { 353 {
329 float scale = (float)w / image_width; 354 float scale = (float)w / image_width;
330 min_it (scale, (float)h / image_height); 355 min_it (scale, (float)h / image_height);
331 w = image_width * scale + 0.5; 356 w = image_width * scale + 0.5;
332 h = image_height * scale + 0.5; 357 h = image_height * scale + 0.5;
798 } 823 }
799 824
800#if XRENDER 825#if XRENDER
801 if (tr_flags) 826 if (tr_flags)
802 { 827 {
803 XRenderPictureAttributes pa;
804
805 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, visual); 828 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
829
806 Picture src = XRenderCreatePicture (dpy, root_pmap, src_format, 0, &pa); 830 Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0);
807 831
808 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
809 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, dst_format, 0, &pa); 832 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, format, 0, 0);
810 833
811 pa.repeat = True; 834 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 835
817 XRenderColor mask_c; 836 XRenderColor mask_c;
818 837
819 mask_c.alpha = 0x8000; 838 mask_c.alpha = 0x8000;
820 mask_c.red = 0; 839 mask_c.red =
821 mask_c.green = 0; 840 mask_c.green =
822 mask_c.blue = 0; 841 mask_c.blue = 0;
823 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); 842 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
843
824 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);
825 845
826 XRenderFreePicture (dpy, src); 846 XRenderFreePicture (dpy, src);
827 XRenderFreePicture (dpy, dst); 847 XRenderFreePicture (dpy, dst);
828 XRenderFreePicture (dpy, mask); 848 XRenderFreePicture (dpy, mask);
940 { 960 {
941 changed = true; 961 changed = true;
942 v_blurRadius = vr; 962 v_blurRadius = vr;
943 } 963 }
944 964
945 if (v_blurRadius == 0 && h_blurRadius == 0) 965 if (h_blurRadius == 0 || v_blurRadius == 0)
946 bg_flags &= ~BG_NEEDS_BLUR; 966 bg_flags &= ~BG_NEEDS_BLUR;
947 else 967 else
948 bg_flags |= BG_NEEDS_BLUR; 968 bg_flags |= BG_NEEDS_BLUR;
949 969
950 return changed; 970 return changed;
951} 971}
952 972
953void 973void
954rxvt_term::set_tint_shade_flags () 974rxvt_term::set_tint_shade_flags ()
955{ 975{
956 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 976 rgba c;
957 bool has_shade = shade != 100; 977 bool has_shade = shade != 100;
958 978
959 bg_flags &= ~BG_TINT_FLAGS; 979 bg_flags &= ~BG_TINT_FLAGS;
960 980
961 if (bg_flags & BG_TINT_SET) 981 if (bg_flags & BG_TINT_SET)
987} 1007}
988 1008
989bool 1009bool
990rxvt_term::bg_set_shade (const char *shade_str) 1010rxvt_term::bg_set_shade (const char *shade_str)
991{ 1011{
992 int new_shade = (shade_str) ? atoi (shade_str) : 100; 1012 int new_shade = atoi (shade_str);
993 1013
994 clamp_it (new_shade, -100, 200); 1014 clamp_it (new_shade, -100, 200);
995 if (new_shade < 0) 1015 if (new_shade < 0)
996 new_shade = 200 - (100 + new_shade); 1016 new_shade = 200 - (100 + new_shade);
997 1017
1027 params[i+2] = XDoubleToFixed (kernel[i] / sum); 1047 params[i+2] = XDoubleToFixed (kernel[i] / sum);
1028} 1048}
1029#endif 1049#endif
1030 1050
1031bool 1051bool
1032rxvt_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)
1033{ 1053{
1034 bool ret = false; 1054 bool ret = false;
1035#if XRENDER 1055#if XRENDER
1056 if (!(bg_flags & BG_HAS_RENDER_CONV))
1057 return false;
1058
1036 int size = max (h_blurRadius, v_blurRadius) * 2 + 1; 1059 int size = max (h_blurRadius, v_blurRadius) * 2 + 1;
1037 double *kernel = (double *)malloc (size * sizeof (double)); 1060 double *kernel = (double *)malloc (size * sizeof (double));
1038 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 1061 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
1039 1062
1040 XRenderPictureAttributes pa; 1063 XRenderPictureAttributes pa;
1041 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1064 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1042 1065
1066 pa.repeat = RepeatPad;
1043 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);
1044 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1069 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa);
1070 XFreePixmap (dpy, tmp);
1045 1071
1046 if (kernel && params) 1072 if (kernel && params)
1047 { 1073 {
1048 if (h_blurRadius)
1049 {
1050 size = h_blurRadius * 2 + 1; 1074 size = h_blurRadius * 2 + 1;
1051 get_gaussian_kernel (h_blurRadius, size, kernel, params); 1075 get_gaussian_kernel (h_blurRadius, size, kernel, params);
1052 1076
1053 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1077 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1054 XRenderComposite (dpy, 1078 XRenderComposite (dpy,
1055 PictOpSrc, 1079 PictOpSrc,
1056 src, 1080 src,
1057 None, 1081 None,
1058 dst, 1082 dst,
1059 0, 0, 1083 0, 0,
1060 0, 0, 1084 0, 0,
1061 0, 0, 1085 0, 0,
1062 width, height); 1086 width, height);
1063 }
1064 1087
1065 if (v_blurRadius) 1088 ::swap (src, dst);
1066 { 1089
1067 size = v_blurRadius * 2 + 1; 1090 size = v_blurRadius * 2 + 1;
1068 get_gaussian_kernel (v_blurRadius, size, kernel, params); 1091 get_gaussian_kernel (v_blurRadius, size, kernel, params);
1069 ::swap (params[0], params[1]); 1092 ::swap (params[0], params[1]);
1070 1093
1071 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1094 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1072 XRenderComposite (dpy, 1095 XRenderComposite (dpy,
1073 PictOpSrc, 1096 PictOpSrc,
1074 src, 1097 src,
1075 None, 1098 None,
1076 dst, 1099 dst,
1077 0, 0, 1100 0, 0,
1078 0, 0, 1101 0, 0,
1079 0, 0, 1102 0, 0,
1080 width, height); 1103 width, height);
1081 }
1082 1104
1083 ret = true; 1105 ret = true;
1084 } 1106 }
1085 1107
1086 free (kernel); 1108 free (kernel);
1113 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height); 1135 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height);
1114 ret = true; 1136 ret = true;
1115 XFreeGC (dpy, gc); 1137 XFreeGC (dpy, gc);
1116 } 1138 }
1117 } 1139 }
1118 else
1119 {
1120# if XRENDER 1140# if XRENDER
1141 else if (bg_flags & BG_HAS_RENDER)
1142 {
1121 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1143 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1122 1144
1123 if (bg_flags & BG_TINT_SET) 1145 if (bg_flags & BG_TINT_SET)
1124 tint.get (c); 1146 tint.get (c);
1125 1147
1134 c.r = c.r * (200 - shade) / 100; 1156 c.r = c.r * (200 - shade) / 100;
1135 c.g = c.g * (200 - shade) / 100; 1157 c.g = c.g * (200 - shade) / 100;
1136 c.b = c.b * (200 - shade) / 100; 1158 c.b = c.b * (200 - shade) / 100;
1137 } 1159 }
1138 1160
1139 XRenderPictFormat *solid_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
1140 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1161 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1141 XRenderPictureAttributes pa;
1142 1162
1143 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1163 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1144 1164
1145 pa.repeat = True; 1165 Picture overlay_pic = create_xrender_mask (dpy, pixmap, True, False);
1146 1166
1147 Pixmap overlay_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32); 1167 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 1168
1156 XRenderColor mask_c; 1169 XRenderColor mask_c;
1157 1170
1158 mask_c.alpha = 0xffff; 1171 mask_c.alpha = 0xffff;
1159 mask_c.red = 1172 mask_c.red =
1164 mask_c.alpha = 0; 1177 mask_c.alpha = 0;
1165 mask_c.red = 0xffff - c.r; 1178 mask_c.red = 0xffff - c.r;
1166 mask_c.green = 0xffff - c.g; 1179 mask_c.green = 0xffff - c.g;
1167 mask_c.blue = 0xffff - c.b; 1180 mask_c.blue = 0xffff - c.b;
1168 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); 1181 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1);
1182
1169 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);
1170 1184
1171 if (shade > 100) 1185 if (shade > 100)
1172 { 1186 {
1173 mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100;
1174 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;
1175 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); 1191 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1);
1176 1192
1177 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);
1178 } 1194 }
1179 1195
1180 ret = true; 1196 ret = true;
1181 1197
1182 XRenderFreePicture (dpy, mask_pic); 1198 XRenderFreePicture (dpy, mask_pic);
1183 XRenderFreePicture (dpy, overlay_pic); 1199 XRenderFreePicture (dpy, overlay_pic);
1184 XRenderFreePicture (dpy, back_pic); 1200 XRenderFreePicture (dpy, back_pic);
1201 }
1185# endif 1202# endif
1186 }
1187 1203
1188 return ret; 1204 return ret;
1189} 1205}
1190 1206
1191/* 1207/*
1242#if XRENDER 1258#if XRENDER
1243 if (bg_flags & BG_HAS_RENDER) 1259 if (bg_flags & BG_HAS_RENDER)
1244 { 1260 {
1245 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);
1246 1262
1247 XRenderPictureAttributes pa;
1248
1249 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); 1263 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
1250 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); 1264 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, 0);
1251 1265
1252 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); 1266 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
1253 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); 1267 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, 0);
1254 1268
1255 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);
1256 1270
1257 XRenderFreePicture (dpy, src); 1271 XRenderFreePicture (dpy, src);
1258 XRenderFreePicture (dpy, dst); 1272 XRenderFreePicture (dpy, dst);
1275 bg_pmap_width = window_width; 1289 bg_pmap_width = window_width;
1276 bg_pmap_height = window_height; 1290 bg_pmap_height = window_height;
1277 } 1291 }
1278 1292
1279 /* straightforward pixmap copy */ 1293 /* straightforward pixmap copy */
1280 while (sx < 0) sx += root_width; 1294 while (sx < 0) sx += root_pmap_width;
1281 while (sy < 0) sy += root_height; 1295 while (sy < 0) sy += root_pmap_height;
1282 1296
1283 gcv.tile = recoded_root_pmap; 1297 gcv.tile = recoded_root_pmap;
1284 gcv.fill_style = FillTiled; 1298 gcv.fill_style = FillTiled;
1285 gcv.ts_x_origin = -sx; 1299 gcv.ts_x_origin = -sx;
1286 gcv.ts_y_origin = -sy; 1300 gcv.ts_y_origin = -sy;
1288 1302
1289 if (gc) 1303 if (gc)
1290 { 1304 {
1291 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1305 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1292 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS); 1306 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS);
1293 XFreeGC (dpy, gc);
1294 1307
1295 if (!(bg_flags & BG_CLIENT_RENDER)) 1308 if (!(bg_flags & BG_CLIENT_RENDER))
1296 { 1309 {
1297 if ((bg_flags & BG_NEEDS_BLUR) 1310 if (bg_flags & BG_NEEDS_BLUR)
1298 && (bg_flags & BG_HAS_RENDER_CONV))
1299 { 1311 {
1300 if (blur_pixmap (bg_pixmap, visual, window_width, window_height)) 1312 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth))
1301 result &= ~BG_NEEDS_BLUR; 1313 result &= ~BG_NEEDS_BLUR;
1302 } 1314 }
1303 if ((bg_flags & BG_NEEDS_TINT) 1315 if (bg_flags & BG_NEEDS_TINT)
1304 && (bg_flags & (BG_TINT_BITAND | BG_HAS_RENDER)))
1305 { 1316 {
1306 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1317 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1307 result &= ~BG_NEEDS_TINT; 1318 result &= ~BG_NEEDS_TINT;
1308 } 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
1309 } /* server side rendering completed */ 1334 } /* server side rendering completed */
1335
1336 XFreeGC (dpy, gc);
1310 } 1337 }
1311 1338
1312 if (recoded_root_pmap != root_pixmap) 1339 if (recoded_root_pmap != root_pixmap)
1313 XFreePixmap (dpy, recoded_root_pmap); 1340 XFreePixmap (dpy, recoded_root_pmap);
1314 1341
1323 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]); 1350 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]);
1324 1351
1325 root_pixmap = new_root_pixmap; 1352 root_pixmap = new_root_pixmap;
1326} 1353}
1327# endif /* ENABLE_TRANSPARENCY */ 1354# 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 1355
1333bool 1356bool
1334rxvt_term::bg_render () 1357rxvt_term::bg_render ()
1335{ 1358{
1336 unsigned long tr_flags = 0; 1359 unsigned long tr_flags = 0;
1351 if ((bg_flags & BG_IS_FROM_FILE) 1374 if ((bg_flags & BG_IS_FROM_FILE)
1352 || (tr_flags & BG_EFFECTS_FLAGS)) 1375 || (tr_flags & BG_EFFECTS_FLAGS))
1353 { 1376 {
1354 if (render_image (tr_flags)) 1377 if (render_image (tr_flags))
1355 bg_flags |= BG_IS_VALID; 1378 bg_flags |= BG_IS_VALID;
1356 }
1357# endif
1358
1359# if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1360 XImage *result = NULL;
1361
1362 if (tr_flags & BG_NEEDS_TINT)
1363 {
1364 result = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1365 }
1366
1367 if (result)
1368 {
1369 /* our own client-side tinting */
1370 //if (tr_flags & BG_NEEDS_TINT)
1371 if (1)
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 }
1387
1388 XDestroyImage (result);
1389 } 1379 }
1390# endif 1380# endif
1391 1381
1392 if (!(bg_flags & BG_IS_VALID)) 1382 if (!(bg_flags & BG_IS_VALID))
1393 { 1383 {
1433#endif /* HAVE_BG_PIXMAP */ 1423#endif /* HAVE_BG_PIXMAP */
1434 1424
1435#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) 1425#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1436/* based on code from aterm-0.4.2 */ 1426/* based on code from aterm-0.4.2 */
1437 1427
1438static void 1428static inline void
1439shade_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)
1440{ 1442{
1441 int sh_r, sh_g, sh_b; 1443 int sh_r, sh_g, sh_b;
1442 uint32_t mask_r, mask_g, mask_b; 1444 uint32_t mask_r, mask_g, mask_b;
1443 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1445 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1444 rgba low; 1446 unsigned short low;
1445 rgba high;
1446 int i;
1447 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1447 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1448 1448
1449 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return; 1449 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return;
1450 1450
1451 /* for convenience */ 1451 /* for convenience */
1510 break; 1510 break;
1511 default: 1511 default:
1512 return; /* we do not support this color depth */ 1512 return; /* we do not support this color depth */
1513 } 1513 }
1514 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
1515 /* prepare limits for color transformation (each channel is handled separately) */ 1520 /* prepare limits for color transformation (each channel is handled separately) */
1516 if (shade > 100) 1521 if (shade > 100)
1517 { 1522 {
1518 shade = 200 - shade;
1519
1520 high.r = c.r * shade / 100;
1521 high.g = c.g * shade / 100;
1522 high.b = c.b * shade / 100;
1523
1524 low.r = 65535 * (100 - shade) / 100; 1523 c.r = c.r * (200 - shade) / 100;
1525 low.g = 65535 * (100 - shade) / 100; 1524 c.g = c.g * (200 - shade) / 100;
1526 low.b = 65535 * (100 - shade) / 100; 1525 c.b = c.b * (200 - shade) / 100;
1526
1527 low = 0xffff * (shade - 100) / 100;
1527 } 1528 }
1528 else 1529 else
1529 { 1530 {
1530 high.r = c.r * shade / 100; 1531 c.r = c.r * shade / 100;
1531 high.g = c.g * shade / 100; 1532 c.g = c.g * shade / 100;
1532 high.b = c.b * shade / 100; 1533 c.b = c.b * shade / 100;
1533 1534
1534 low.r = low.g = low.b = 0; 1535 low = 0;
1535 } 1536 }
1536 1537
1537 /* fill our lookup tables */ 1538 /* fill our lookup tables */
1538 for (i = 0; i <= mask_r>>sh_r; i++) 1539 fill_lut (lookup_r, mask_r, sh_r, low, c.r);
1539 { 1540 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1540 uint32_t tmp; 1541 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1541 tmp = i * high.r;
1542 tmp += (mask_r>>sh_r) * low.r;
1543 lookup_r[i] = (tmp/65535)<<sh_r;
1544 }
1545 for (i = 0; i <= mask_g>>sh_g; i++)
1546 {
1547 uint32_t tmp;
1548 tmp = i * high.g;
1549 tmp += (mask_g>>sh_g) * low.g;
1550 lookup_g[i] = (tmp/65535)<<sh_g;
1551 }
1552 for (i = 0; i <= mask_b>>sh_b; i++)
1553 {
1554 uint32_t tmp;
1555 tmp = i * high.b;
1556 tmp += (mask_b>>sh_b) * low.b;
1557 lookup_b[i] = (tmp/65535)<<sh_b;
1558 }
1559 1542
1560 /* apply table to input image (replacing colors by newly calculated ones) */ 1543 /* apply table to input image (replacing colors by newly calculated ones) */
1561 if (ximage->bits_per_pixel == 32 1544 if (ximage->bits_per_pixel == 32
1562 && (ximage->depth == 24 || ximage->depth == 32) 1545 && (ximage->depth == 24 || ximage->depth == 32)
1563 && ximage->byte_order == host_byte_order) 1546 && ximage->byte_order == host_byte_order)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines