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.177 by sf-exg, Wed Dec 14 12:07:12 2011 UTC vs.
Revision 1.198 by sf-exg, Wed Jan 11 13:51:07 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)
107 129
108 return false; 130 return false;
109} 131}
110 132
111# ifdef BG_IMAGE_FROM_FILE 133# ifdef BG_IMAGE_FROM_FILE
112static inline bool
113check_set_scale_value (int geom_flags, int flag, unsigned int &scale, unsigned int new_value)
114{
115 if (geom_flags & flag)
116 {
117 if (new_value > 1000)
118 new_value = 1000;
119 if (new_value != scale)
120 {
121 scale = new_value;
122 return true;
123 }
124 }
125 return false;
126}
127
128static inline bool
129check_set_align_value (int geom_flags, int flag, int &align, int new_value)
130{
131 if (geom_flags & flag)
132 {
133 if (new_value < -100)
134 new_value = -100;
135 else if (new_value > 200)
136 new_value = 200;
137 if (new_value != align)
138 {
139 align = new_value;
140 return true;
141 }
142 }
143 return false;
144}
145
146static inline int 134static inline int
147make_align_position (int align, int window_size, int image_size) 135make_align_position (int align, int window_size, int image_size)
148{ 136{
149 int diff = window_size - image_size; 137 int diff = window_size - image_size;
150 int smaller = min (image_size, window_size); 138 int smaller = min (image_size, window_size);
169 src_pos = -pos; 157 src_pos = -pos;
170 dst_pos = 0; 158 dst_pos = 0;
171 dst_size += pos; 159 dst_size += pos;
172 } 160 }
173 161
174 if (dst_pos + dst_size > target_size)
175 dst_size = target_size - dst_pos; 162 min_it (dst_size, target_size - dst_pos);
176 return src_pos; 163 return src_pos;
177} 164}
178 165
179bool 166bool
180rxvt_term::bg_set_geometry (const char *geom, bool update) 167rxvt_term::bg_set_geometry (const char *geom, bool update)
181{ 168{
182 bool changed = false; 169 bool changed = false;
183 int geom_flags = 0; 170 int geom_flags = 0;
184 int x = 0, y = 0; 171 int x = h_align;
172 int y = v_align;
185 unsigned int w = 0, h = 0; 173 unsigned int w = h_scale;
186 unsigned long new_flags = bg_flags & ~BG_GEOMETRY_FLAGS; 174 unsigned int h = v_scale;
175 unsigned long new_flags = 0;
187 176
188 if (geom == NULL) 177 if (geom == NULL)
189 return false; 178 return false;
190 179
191 if (geom[0]) 180 if (geom[0])
284 } /* done parsing ops */ 273 } /* done parsing ops */
285 274
286 rxvt_free_strsplit (arr); 275 rxvt_free_strsplit (arr);
287 } 276 }
288 277
278 new_flags |= bg_flags & ~BG_GEOMETRY_FLAGS;
279
289 if (!update) 280 if (!update)
290 { 281 {
291 if (!(geom_flags & XValue)) 282 if (!(geom_flags & XValue))
292 x = y = defaultAlign; 283 x = y = defaultAlign;
293 else if (!(geom_flags & YValue)) 284 else if (!(geom_flags & YValue))
297 w = h = defaultScale; 288 w = h = defaultScale;
298 else if (!(geom_flags & HeightValue)) 289 else if (!(geom_flags & HeightValue))
299 h = w; 290 h = w;
300 else if (!(geom_flags & WidthValue)) 291 else if (!(geom_flags & WidthValue))
301 w = h; 292 w = h;
302
303 geom_flags |= WidthValue|HeightValue|XValue|YValue;
304 } 293 }
305 294
306 if (check_set_scale_value (geom_flags, WidthValue, h_scale, w)) changed = true; 295 min_it (w, 1000);
307 if (check_set_scale_value (geom_flags, HeightValue, v_scale, h)) changed = true; 296 min_it (h, 1000);
308 if (check_set_align_value (geom_flags, XValue, h_align, x)) changed = true; 297 clamp_it (x, -100, 200);
309 if (check_set_align_value (geom_flags, YValue, v_align, y)) changed = true; 298 clamp_it (y, -100, 200);
310 299
311 if (new_flags != bg_flags) 300 if (bg_flags != new_flags
301 || h_scale != w
302 || v_scale != h
303 || h_align != x
304 || v_align != y)
312 { 305 {
313 bg_flags = new_flags; 306 bg_flags = new_flags;
307 h_scale = w;
308 v_scale = h;
309 h_align = x;
310 v_align = y;
314 changed = true; 311 changed = true;
315 } 312 }
316 313
317 return changed; 314 return changed;
318} 315}
800 } 797 }
801 798
802#if XRENDER 799#if XRENDER
803 if (tr_flags) 800 if (tr_flags)
804 { 801 {
805 XRenderPictureAttributes pa;
806
807 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, visual); 802 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
803
808 Picture src = XRenderCreatePicture (dpy, root_pmap, src_format, 0, &pa); 804 Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0);
809 805
810 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
811 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, dst_format, 0, &pa); 806 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, format, 0, 0);
812 807
813 pa.repeat = True; 808 Picture mask = create_xrender_mask (dpy, vt, False, False);
814 Pixmap mask_pmap = XCreatePixmap (dpy, vt, 1, 1, 8);
815 XRenderPictFormat *mask_format = XRenderFindStandardFormat (dpy, PictStandardA8);
816 Picture mask = XRenderCreatePicture (dpy, mask_pmap, mask_format, CPRepeat, &pa);
817 XFreePixmap (dpy, mask_pmap);
818 809
819 XRenderColor mask_c; 810 XRenderColor mask_c;
820 811
821 mask_c.alpha = 0x8000; 812 mask_c.alpha = 0x8000;
822 mask_c.red = 0; 813 mask_c.red =
823 mask_c.green = 0; 814 mask_c.green =
824 mask_c.blue = 0; 815 mask_c.blue = 0;
825 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); 816 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
817
826 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, target_width, target_height); 818 XRenderComposite (dpy, PictOpOver, src, mask, dst, 0, 0, 0, 0, 0, 0, target_width, target_height);
827 819
828 XRenderFreePicture (dpy, src); 820 XRenderFreePicture (dpy, src);
829 XRenderFreePicture (dpy, dst); 821 XRenderFreePicture (dpy, dst);
830 XRenderFreePicture (dpy, mask); 822 XRenderFreePicture (dpy, mask);
942 { 934 {
943 changed = true; 935 changed = true;
944 v_blurRadius = vr; 936 v_blurRadius = vr;
945 } 937 }
946 938
947 if (v_blurRadius == 0 && h_blurRadius == 0) 939 if (h_blurRadius == 0 || v_blurRadius == 0)
948 bg_flags &= ~BG_NEEDS_BLUR; 940 bg_flags &= ~BG_NEEDS_BLUR;
949 else 941 else
950 bg_flags |= BG_NEEDS_BLUR; 942 bg_flags |= BG_NEEDS_BLUR;
951 943
952 return changed; 944 return changed;
953} 945}
954 946
955void 947void
956rxvt_term::set_tint_shade_flags () 948rxvt_term::set_tint_shade_flags ()
957{ 949{
958 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 950 rgba c;
959 bool has_shade = shade != 100; 951 bool has_shade = shade != 100;
960 952
961 bg_flags &= ~BG_TINT_FLAGS; 953 bg_flags &= ~BG_TINT_FLAGS;
962 954
963 if (bg_flags & BG_TINT_SET) 955 if (bg_flags & BG_TINT_SET)
989} 981}
990 982
991bool 983bool
992rxvt_term::bg_set_shade (const char *shade_str) 984rxvt_term::bg_set_shade (const char *shade_str)
993{ 985{
994 int new_shade = (shade_str) ? atoi (shade_str) : 100; 986 int new_shade = atoi (shade_str);
995 987
996 clamp_it (new_shade, -100, 200); 988 clamp_it (new_shade, -100, 200);
997 if (new_shade < 0) 989 if (new_shade < 0)
998 new_shade = 200 - (100 + new_shade); 990 new_shade = 200 - (100 + new_shade);
999 991
1029 params[i+2] = XDoubleToFixed (kernel[i] / sum); 1021 params[i+2] = XDoubleToFixed (kernel[i] / sum);
1030} 1022}
1031#endif 1023#endif
1032 1024
1033bool 1025bool
1034rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height) 1026rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height, int depth)
1035{ 1027{
1036 bool ret = false; 1028 bool ret = false;
1037#if XRENDER 1029#if XRENDER
1030 if (!(bg_flags & BG_HAS_RENDER_CONV))
1031 return false;
1032
1038 int size = max (h_blurRadius, v_blurRadius) * 2 + 1; 1033 int size = max (h_blurRadius, v_blurRadius) * 2 + 1;
1039 double *kernel = (double *)malloc (size * sizeof (double)); 1034 double *kernel = (double *)malloc (size * sizeof (double));
1040 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 1035 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
1041 1036
1042 XRenderPictureAttributes pa; 1037 XRenderPictureAttributes pa;
1043 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1038 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1044 1039
1040 pa.repeat = RepeatPad;
1045 Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1041 Picture src = XRenderCreatePicture (dpy, pixmap, format, CPRepeat, &pa);
1042 Pixmap tmp = XCreatePixmap (dpy, pixmap, width, height, depth);
1046 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1043 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa);
1044 XFreePixmap (dpy, tmp);
1047 1045
1048 if (kernel && params) 1046 if (kernel && params)
1049 { 1047 {
1050 if (h_blurRadius)
1051 {
1052 size = h_blurRadius * 2 + 1; 1048 size = h_blurRadius * 2 + 1;
1053 get_gaussian_kernel (h_blurRadius, size, kernel, params); 1049 get_gaussian_kernel (h_blurRadius, size, kernel, params);
1054 1050
1055 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1051 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1056 XRenderComposite (dpy, 1052 XRenderComposite (dpy,
1057 PictOpSrc, 1053 PictOpSrc,
1058 src, 1054 src,
1059 None, 1055 None,
1060 dst, 1056 dst,
1061 0, 0, 1057 0, 0,
1062 0, 0, 1058 0, 0,
1063 0, 0, 1059 0, 0,
1064 width, height); 1060 width, height);
1065 }
1066 1061
1067 if (v_blurRadius) 1062 ::swap (src, dst);
1068 { 1063
1069 size = v_blurRadius * 2 + 1; 1064 size = v_blurRadius * 2 + 1;
1070 get_gaussian_kernel (v_blurRadius, size, kernel, params); 1065 get_gaussian_kernel (v_blurRadius, size, kernel, params);
1071 ::swap (params[0], params[1]); 1066 ::swap (params[0], params[1]);
1072 1067
1073 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1068 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1074 XRenderComposite (dpy, 1069 XRenderComposite (dpy,
1075 PictOpSrc, 1070 PictOpSrc,
1076 src, 1071 src,
1077 None, 1072 None,
1078 dst, 1073 dst,
1079 0, 0, 1074 0, 0,
1080 0, 0, 1075 0, 0,
1081 0, 0, 1076 0, 0,
1082 width, height); 1077 width, height);
1083 }
1084 1078
1085 ret = true; 1079 ret = true;
1086 } 1080 }
1087 1081
1088 free (kernel); 1082 free (kernel);
1115 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height); 1109 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height);
1116 ret = true; 1110 ret = true;
1117 XFreeGC (dpy, gc); 1111 XFreeGC (dpy, gc);
1118 } 1112 }
1119 } 1113 }
1120 else
1121 {
1122# if XRENDER 1114# if XRENDER
1115 else if (bg_flags & BG_HAS_RENDER)
1116 {
1123 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1117 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1124 1118
1125 if (bg_flags & BG_TINT_SET) 1119 if (bg_flags & BG_TINT_SET)
1126 tint.get (c); 1120 tint.get (c);
1127 1121
1136 c.r = c.r * (200 - shade) / 100; 1130 c.r = c.r * (200 - shade) / 100;
1137 c.g = c.g * (200 - shade) / 100; 1131 c.g = c.g * (200 - shade) / 100;
1138 c.b = c.b * (200 - shade) / 100; 1132 c.b = c.b * (200 - shade) / 100;
1139 } 1133 }
1140 1134
1141 XRenderPictFormat *solid_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
1142 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1135 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1143 XRenderPictureAttributes pa;
1144 1136
1145 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1137 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1146 1138
1147 pa.repeat = True; 1139 Picture overlay_pic = create_xrender_mask (dpy, pixmap, True, False);
1148 1140
1149 Pixmap overlay_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32); 1141 Picture mask_pic = create_xrender_mask (dpy, pixmap, True, True);
1150 Picture overlay_pic = XRenderCreatePicture (dpy, overlay_pmap, solid_format, CPRepeat, &pa);
1151 XFreePixmap (dpy, overlay_pmap);
1152
1153 pa.component_alpha = True;
1154 Pixmap mask_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32);
1155 Picture mask_pic = XRenderCreatePicture (dpy, mask_pmap, solid_format, CPRepeat | CPComponentAlpha, &pa);
1156 XFreePixmap (dpy, mask_pmap);
1157 1142
1158 XRenderColor mask_c; 1143 XRenderColor mask_c;
1159 1144
1160 mask_c.alpha = 0xffff; 1145 mask_c.alpha = 0xffff;
1161 mask_c.red = 1146 mask_c.red =
1166 mask_c.alpha = 0; 1151 mask_c.alpha = 0;
1167 mask_c.red = 0xffff - c.r; 1152 mask_c.red = 0xffff - c.r;
1168 mask_c.green = 0xffff - c.g; 1153 mask_c.green = 0xffff - c.g;
1169 mask_c.blue = 0xffff - c.b; 1154 mask_c.blue = 0xffff - c.b;
1170 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); 1155 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1);
1156
1171 XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, width, height); 1157 XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, width, height);
1172 1158
1173 if (shade > 100) 1159 if (shade > 100)
1174 { 1160 {
1175 mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100;
1176 mask_c.alpha = 0; 1161 mask_c.alpha = 0;
1162 mask_c.red =
1163 mask_c.green =
1164 mask_c.blue = 0xffff * (shade - 100) / 100;
1177 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); 1165 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1);
1178 1166
1179 XRenderComposite (dpy, PictOpOver, overlay_pic, None, back_pic, 0, 0, 0, 0, 0, 0, width, height); 1167 XRenderComposite (dpy, PictOpOver, overlay_pic, None, back_pic, 0, 0, 0, 0, 0, 0, width, height);
1180 } 1168 }
1181 1169
1182 ret = true; 1170 ret = true;
1183 1171
1184 XRenderFreePicture (dpy, mask_pic); 1172 XRenderFreePicture (dpy, mask_pic);
1185 XRenderFreePicture (dpy, overlay_pic); 1173 XRenderFreePicture (dpy, overlay_pic);
1186 XRenderFreePicture (dpy, back_pic); 1174 XRenderFreePicture (dpy, back_pic);
1175 }
1187# endif 1176# endif
1188 }
1189 1177
1190 return ret; 1178 return ret;
1191} 1179}
1192 1180
1193/* 1181/*
1244#if XRENDER 1232#if XRENDER
1245 if (bg_flags & BG_HAS_RENDER) 1233 if (bg_flags & BG_HAS_RENDER)
1246 { 1234 {
1247 recoded_root_pmap = XCreatePixmap (dpy, vt, root_pmap_width, root_pmap_height, depth); 1235 recoded_root_pmap = XCreatePixmap (dpy, vt, root_pmap_width, root_pmap_height, depth);
1248 1236
1249 XRenderPictureAttributes pa;
1250
1251 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); 1237 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
1252 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); 1238 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, 0);
1253 1239
1254 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); 1240 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
1255 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); 1241 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, 0);
1256 1242
1257 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height); 1243 XRenderComposite (dpy, PictOpSrc, src, None, dst, 0, 0, 0, 0, 0, 0, root_pmap_width, root_pmap_height);
1258 1244
1259 XRenderFreePicture (dpy, src); 1245 XRenderFreePicture (dpy, src);
1260 XRenderFreePicture (dpy, dst); 1246 XRenderFreePicture (dpy, dst);
1277 bg_pmap_width = window_width; 1263 bg_pmap_width = window_width;
1278 bg_pmap_height = window_height; 1264 bg_pmap_height = window_height;
1279 } 1265 }
1280 1266
1281 /* straightforward pixmap copy */ 1267 /* straightforward pixmap copy */
1282 while (sx < 0) sx += root_width; 1268 while (sx < 0) sx += root_pmap_width;
1283 while (sy < 0) sy += root_height; 1269 while (sy < 0) sy += root_pmap_height;
1284 1270
1285 gcv.tile = recoded_root_pmap; 1271 gcv.tile = recoded_root_pmap;
1286 gcv.fill_style = FillTiled; 1272 gcv.fill_style = FillTiled;
1287 gcv.ts_x_origin = -sx; 1273 gcv.ts_x_origin = -sx;
1288 gcv.ts_y_origin = -sy; 1274 gcv.ts_y_origin = -sy;
1290 1276
1291 if (gc) 1277 if (gc)
1292 { 1278 {
1293 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1279 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1294 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS); 1280 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS);
1295 XFreeGC (dpy, gc);
1296 1281
1297 if (!(bg_flags & BG_CLIENT_RENDER)) 1282 if (!(bg_flags & BG_CLIENT_RENDER))
1298 { 1283 {
1299 if ((bg_flags & BG_NEEDS_BLUR) 1284 if (bg_flags & BG_NEEDS_BLUR)
1300 && (bg_flags & BG_HAS_RENDER_CONV))
1301 { 1285 {
1302 if (blur_pixmap (bg_pixmap, visual, window_width, window_height)) 1286 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth))
1303 result &= ~BG_NEEDS_BLUR; 1287 result &= ~BG_NEEDS_BLUR;
1304 } 1288 }
1305 if ((bg_flags & BG_NEEDS_TINT) 1289 if (bg_flags & BG_NEEDS_TINT)
1306 && (bg_flags & (BG_TINT_BITAND | BG_HAS_RENDER)))
1307 { 1290 {
1308 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1291 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1309 result &= ~BG_NEEDS_TINT; 1292 result &= ~BG_NEEDS_TINT;
1310 } 1293 }
1294# ifndef HAVE_AFTERIMAGE
1295 if (result & BG_NEEDS_TINT)
1296 {
1297 XImage *ximage = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1298 if (ximage)
1299 {
1300 /* our own client-side tinting */
1301 tint_ximage (DefaultVisual (dpy, display->screen), ximage);
1302
1303 XPutImage (dpy, bg_pixmap, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height);
1304 XDestroyImage (ximage);
1305 }
1306 }
1307# endif
1311 } /* server side rendering completed */ 1308 } /* server side rendering completed */
1309
1310 XFreeGC (dpy, gc);
1312 } 1311 }
1313 1312
1314 if (recoded_root_pmap != root_pixmap) 1313 if (recoded_root_pmap != root_pixmap)
1315 XFreePixmap (dpy, recoded_root_pmap); 1314 XFreePixmap (dpy, recoded_root_pmap);
1316 1315
1325 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]); 1324 new_root_pixmap = get_pixmap_property (xa[XA_ESETROOT_PMAP_ID]);
1326 1325
1327 root_pixmap = new_root_pixmap; 1326 root_pixmap = new_root_pixmap;
1328} 1327}
1329# endif /* ENABLE_TRANSPARENCY */ 1328# endif /* ENABLE_TRANSPARENCY */
1330
1331#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1332static void shade_ximage (Visual *visual, XImage *ximage, int shade, const rgba &c);
1333# endif
1334 1329
1335bool 1330bool
1336rxvt_term::bg_render () 1331rxvt_term::bg_render ()
1337{ 1332{
1338 unsigned long tr_flags = 0; 1333 unsigned long tr_flags = 0;
1353 if ((bg_flags & BG_IS_FROM_FILE) 1348 if ((bg_flags & BG_IS_FROM_FILE)
1354 || (tr_flags & BG_EFFECTS_FLAGS)) 1349 || (tr_flags & BG_EFFECTS_FLAGS))
1355 { 1350 {
1356 if (render_image (tr_flags)) 1351 if (render_image (tr_flags))
1357 bg_flags |= BG_IS_VALID; 1352 bg_flags |= BG_IS_VALID;
1358 }
1359# endif
1360
1361# if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1362 XImage *result = NULL;
1363
1364 if (tr_flags & BG_NEEDS_TINT)
1365 {
1366 result = XGetImage (dpy, bg_pixmap, 0, 0, bg_pmap_width, bg_pmap_height, AllPlanes, ZPixmap);
1367 }
1368
1369 if (result)
1370 {
1371 /* our own client-side tinting */
1372 //if (tr_flags & BG_NEEDS_TINT)
1373 if (1)
1374 {
1375 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC);
1376 if (bg_flags & BG_TINT_SET)
1377 tint.get (c);
1378 shade_ximage (DefaultVisual (dpy, display->screen), result, shade, c);
1379 }
1380
1381 GC gc = XCreateGC (dpy, vt, 0UL, NULL);
1382
1383 if (gc)
1384 {
1385 XPutImage (dpy, bg_pixmap, gc, result, 0, 0, 0, 0, result->width, result->height);
1386
1387 XFreeGC (dpy, gc);
1388 }
1389
1390 XDestroyImage (result);
1391 } 1353 }
1392# endif 1354# endif
1393 1355
1394 if (!(bg_flags & BG_IS_VALID)) 1356 if (!(bg_flags & BG_IS_VALID))
1395 { 1357 {
1435#endif /* HAVE_BG_PIXMAP */ 1397#endif /* HAVE_BG_PIXMAP */
1436 1398
1437#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) 1399#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1438/* based on code from aterm-0.4.2 */ 1400/* based on code from aterm-0.4.2 */
1439 1401
1440static void 1402static inline void
1441shade_ximage (Visual *visual, XImage *ximage, int shade, const rgba &c) 1403fill_lut (uint32_t *lookup, uint32_t mask, int sh, unsigned short low, unsigned short high)
1404{
1405 for (int i = 0; i <= mask >> sh; i++)
1406 {
1407 uint32_t tmp;
1408 tmp = i * high;
1409 tmp += (mask >> sh) * low;
1410 lookup[i] = (tmp / 0xffff) << sh;
1411 }
1412}
1413
1414void
1415rxvt_term::tint_ximage (Visual *visual, XImage *ximage)
1442{ 1416{
1443 int sh_r, sh_g, sh_b; 1417 int sh_r, sh_g, sh_b;
1444 uint32_t mask_r, mask_g, mask_b; 1418 uint32_t mask_r, mask_g, mask_b;
1445 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1419 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1446 rgba low; 1420 unsigned short low;
1447 rgba high;
1448 int i;
1449 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1421 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1450 1422
1451 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return; 1423 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return;
1452 1424
1453 /* for convenience */ 1425 /* for convenience */
1512 break; 1484 break;
1513 default: 1485 default:
1514 return; /* we do not support this color depth */ 1486 return; /* we do not support this color depth */
1515 } 1487 }
1516 1488
1489 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1490
1491 if (bg_flags & BG_TINT_SET)
1492 tint.get (c);
1493
1517 /* prepare limits for color transformation (each channel is handled separately) */ 1494 /* prepare limits for color transformation (each channel is handled separately) */
1518 if (shade > 100) 1495 if (shade > 100)
1519 { 1496 {
1520 shade = 200 - shade;
1521
1522 high.r = c.r * shade / 100;
1523 high.g = c.g * shade / 100;
1524 high.b = c.b * shade / 100;
1525
1526 low.r = 65535 * (100 - shade) / 100; 1497 c.r = c.r * (200 - shade) / 100;
1527 low.g = 65535 * (100 - shade) / 100; 1498 c.g = c.g * (200 - shade) / 100;
1528 low.b = 65535 * (100 - shade) / 100; 1499 c.b = c.b * (200 - shade) / 100;
1500
1501 low = 0xffff * (shade - 100) / 100;
1529 } 1502 }
1530 else 1503 else
1531 { 1504 {
1532 high.r = c.r * shade / 100; 1505 c.r = c.r * shade / 100;
1533 high.g = c.g * shade / 100; 1506 c.g = c.g * shade / 100;
1534 high.b = c.b * shade / 100; 1507 c.b = c.b * shade / 100;
1535 1508
1536 low.r = low.g = low.b = 0; 1509 low = 0;
1537 } 1510 }
1538 1511
1539 /* fill our lookup tables */ 1512 /* fill our lookup tables */
1540 for (i = 0; i <= mask_r>>sh_r; i++) 1513 fill_lut (lookup_r, mask_r, sh_r, low, c.r);
1541 { 1514 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1542 uint32_t tmp; 1515 fill_lut (lookup_b, mask_b, sh_b, low, c.b);
1543 tmp = i * high.r;
1544 tmp += (mask_r>>sh_r) * low.r;
1545 lookup_r[i] = (tmp/65535)<<sh_r;
1546 }
1547 for (i = 0; i <= mask_g>>sh_g; i++)
1548 {
1549 uint32_t tmp;
1550 tmp = i * high.g;
1551 tmp += (mask_g>>sh_g) * low.g;
1552 lookup_g[i] = (tmp/65535)<<sh_g;
1553 }
1554 for (i = 0; i <= mask_b>>sh_b; i++)
1555 {
1556 uint32_t tmp;
1557 tmp = i * high.b;
1558 tmp += (mask_b>>sh_b) * low.b;
1559 lookup_b[i] = (tmp/65535)<<sh_b;
1560 }
1561 1516
1562 /* apply table to input image (replacing colors by newly calculated ones) */ 1517 /* apply table to input image (replacing colors by newly calculated ones) */
1563 if (ximage->bits_per_pixel == 32 1518 if (ximage->bits_per_pixel == 32
1564 && (ximage->depth == 24 || ximage->depth == 32) 1519 && (ximage->depth == 24 || ximage->depth == 32)
1565 && ximage->byte_order == host_byte_order) 1520 && ximage->byte_order == host_byte_order)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines