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.174 by sf-exg, Wed Nov 23 16:53:53 2011 UTC vs.
Revision 1.199 by sf-exg, Tue Jan 17 19:51:30 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])
201 x = y = 0; 190 x = y = 0;
202 geom_flags = WidthValue|HeightValue|XValue|YValue; 191 geom_flags = WidthValue|HeightValue|XValue|YValue;
203 } 192 }
204 else if (!strcasecmp (arr[i], "style=aspect-stretched")) 193 else if (!strcasecmp (arr[i], "style=aspect-stretched"))
205 { 194 {
206 new_flags = BG_PROP_SCALE; 195 new_flags = BG_KEEP_ASPECT;
207 w = h = windowScale; 196 w = h = windowScale;
208 x = y = centerAlign; 197 x = y = centerAlign;
209 geom_flags = WidthValue|HeightValue|XValue|YValue; 198 geom_flags = WidthValue|HeightValue|XValue|YValue;
210 } 199 }
211 else if (!strcasecmp (arr[i], "style=stretched")) 200 else if (!strcasecmp (arr[i], "style=stretched"))
227 w = h = noScale; 216 w = h = noScale;
228 geom_flags = WidthValue|HeightValue; 217 geom_flags = WidthValue|HeightValue;
229 } 218 }
230 else if (!strcasecmp (arr[i], "op=tile")) 219 else if (!strcasecmp (arr[i], "op=tile"))
231 new_flags |= BG_TILE; 220 new_flags |= BG_TILE;
232 else if (!strcasecmp (arr[i], "op=pscale")) 221 else if (!strcasecmp (arr[i], "op=keep-aspect"))
233 new_flags |= BG_PROP_SCALE; 222 new_flags |= BG_KEEP_ASPECT;
234 else if (!strcasecmp (arr[i], "op=root")) 223 else if (!strcasecmp (arr[i], "op=root-align"))
235 new_flags |= BG_ROOT_ALIGN; 224 new_flags |= BG_ROOT_ALIGN;
236 225
237 // deprecated 226 // deprecated
238 else if (!strcasecmp (arr[i], "tile")) 227 else if (!strcasecmp (arr[i], "tile"))
239 { 228 {
241 w = h = noScale; 230 w = h = noScale;
242 geom_flags |= WidthValue|HeightValue; 231 geom_flags |= WidthValue|HeightValue;
243 } 232 }
244 else if (!strcasecmp (arr[i], "propscale")) 233 else if (!strcasecmp (arr[i], "propscale"))
245 { 234 {
246 new_flags |= BG_PROP_SCALE; 235 new_flags |= BG_KEEP_ASPECT;
236 w = h = windowScale;
237 geom_flags |= WidthValue|HeightValue;
247 } 238 }
248 else if (!strcasecmp (arr[i], "hscale")) 239 else if (!strcasecmp (arr[i], "hscale"))
249 { 240 {
250 new_flags |= BG_TILE; 241 new_flags |= BG_TILE;
251 w = windowScale; 242 w = windowScale;
281 geom_flags |= XParseGeometry (arr[i], &x, &y, &w, &h); 272 geom_flags |= XParseGeometry (arr[i], &x, &y, &w, &h);
282 } /* done parsing ops */ 273 } /* done parsing ops */
283 274
284 rxvt_free_strsplit (arr); 275 rxvt_free_strsplit (arr);
285 } 276 }
277
278 new_flags |= bg_flags & ~BG_GEOMETRY_FLAGS;
286 279
287 if (!update) 280 if (!update)
288 { 281 {
289 if (!(geom_flags & XValue)) 282 if (!(geom_flags & XValue))
290 x = y = defaultAlign; 283 x = y = defaultAlign;
295 w = h = defaultScale; 288 w = h = defaultScale;
296 else if (!(geom_flags & HeightValue)) 289 else if (!(geom_flags & HeightValue))
297 h = w; 290 h = w;
298 else if (!(geom_flags & WidthValue)) 291 else if (!(geom_flags & WidthValue))
299 w = h; 292 w = h;
300
301 geom_flags |= WidthValue|HeightValue|XValue|YValue;
302 } 293 }
303 294
304 if (check_set_scale_value (geom_flags, WidthValue, h_scale, w) 295 min_it (w, 1000);
305 || check_set_scale_value (geom_flags, HeightValue, v_scale, h) 296 min_it (h, 1000);
306 || check_set_align_value (geom_flags, XValue, h_align, x) 297 clamp_it (x, -100, 200);
307 || check_set_align_value (geom_flags, YValue, v_align, y)) 298 clamp_it (y, -100, 200);
308 changed = true;
309 299
310 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)
311 { 305 {
312 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;
313 changed = true; 311 changed = true;
314 } 312 }
315 313
316 return changed; 314 return changed;
317} 315}
323 int target_height = szHint.height; 321 int target_height = szHint.height;
324 322
325 w = h_scale * target_width / 100; 323 w = h_scale * target_width / 100;
326 h = v_scale * target_height / 100; 324 h = v_scale * target_height / 100;
327 325
328 if (bg_flags & BG_PROP_SCALE) 326 if (bg_flags & BG_KEEP_ASPECT)
329 { 327 {
330 float scale = (float)w / image_width; 328 float scale = (float)w / image_width;
331 min_it (scale, (float)h / image_height); 329 min_it (scale, (float)h / image_height);
332 w = image_width * scale + 0.5; 330 w = image_width * scale + 0.5;
333 h = image_height * scale + 0.5; 331 h = image_height * scale + 0.5;
799 } 797 }
800 798
801#if XRENDER 799#if XRENDER
802 if (tr_flags) 800 if (tr_flags)
803 { 801 {
804 XRenderPictureAttributes pa;
805
806 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, visual); 802 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
803
807 Picture src = XRenderCreatePicture (dpy, root_pmap, src_format, 0, &pa); 804 Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0);
808 805
809 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
810 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, dst_format, 0, &pa); 806 Picture dst = XRenderCreatePicture (dpy, bg_pixmap, format, 0, 0);
811 807
812 pa.repeat = True; 808 Picture mask = create_xrender_mask (dpy, vt, False, False);
813 Pixmap mask_pmap = XCreatePixmap (dpy, vt, 1, 1, 8);
814 XRenderPictFormat *mask_format = XRenderFindStandardFormat (dpy, PictStandardA8);
815 Picture mask = XRenderCreatePicture (dpy, mask_pmap, mask_format, CPRepeat, &pa);
816 XFreePixmap (dpy, mask_pmap);
817 809
818 XRenderColor mask_c; 810 XRenderColor mask_c;
819 811
820 mask_c.alpha = 0x8000; 812 mask_c.alpha = 0x8000;
821 mask_c.red = 0; 813 mask_c.red =
822 mask_c.green = 0; 814 mask_c.green =
823 mask_c.blue = 0; 815 mask_c.blue = 0;
824 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); 816 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
817
825 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);
826 819
827 XRenderFreePicture (dpy, src); 820 XRenderFreePicture (dpy, src);
828 XRenderFreePicture (dpy, dst); 821 XRenderFreePicture (dpy, dst);
829 XRenderFreePicture (dpy, mask); 822 XRenderFreePicture (dpy, mask);
941 { 934 {
942 changed = true; 935 changed = true;
943 v_blurRadius = vr; 936 v_blurRadius = vr;
944 } 937 }
945 938
946 if (v_blurRadius == 0 && h_blurRadius == 0) 939 if (h_blurRadius == 0 || v_blurRadius == 0)
947 bg_flags &= ~BG_NEEDS_BLUR; 940 bg_flags &= ~BG_NEEDS_BLUR;
948 else 941 else
949 bg_flags |= BG_NEEDS_BLUR; 942 bg_flags |= BG_NEEDS_BLUR;
950 943
951 return changed; 944 return changed;
952} 945}
953 946
954void 947void
955rxvt_term::set_tint_shade_flags () 948rxvt_term::set_tint_shade_flags ()
956{ 949{
957 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); 950 rgba c;
958 bool has_shade = shade != 100; 951 bool has_shade = shade != 100;
959 952
960 bg_flags &= ~BG_TINT_FLAGS; 953 bg_flags &= ~BG_TINT_FLAGS;
961 954
962 if (bg_flags & BG_TINT_SET) 955 if (bg_flags & BG_TINT_SET)
988} 981}
989 982
990bool 983bool
991rxvt_term::bg_set_shade (const char *shade_str) 984rxvt_term::bg_set_shade (const char *shade_str)
992{ 985{
993 int new_shade = (shade_str) ? atoi (shade_str) : 100; 986 int new_shade = atoi (shade_str);
994 987
995 clamp_it (new_shade, -100, 200); 988 clamp_it (new_shade, -100, 200);
996 if (new_shade < 0) 989 if (new_shade < 0)
997 new_shade = 200 - (100 + new_shade); 990 new_shade = 200 - (100 + new_shade);
998 991
1028 params[i+2] = XDoubleToFixed (kernel[i] / sum); 1021 params[i+2] = XDoubleToFixed (kernel[i] / sum);
1029} 1022}
1030#endif 1023#endif
1031 1024
1032bool 1025bool
1033rxvt_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)
1034{ 1027{
1035 bool ret = false; 1028 bool ret = false;
1036#if XRENDER 1029#if XRENDER
1030 if (!(bg_flags & BG_HAS_RENDER_CONV))
1031 return false;
1032
1037 int size = max (h_blurRadius, v_blurRadius) * 2 + 1; 1033 int size = max (h_blurRadius, v_blurRadius) * 2 + 1;
1038 double *kernel = (double *)malloc (size * sizeof (double)); 1034 double *kernel = (double *)malloc (size * sizeof (double));
1039 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 1035 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
1040 1036
1041 XRenderPictureAttributes pa; 1037 XRenderPictureAttributes pa;
1042 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1038 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1043 1039
1040 pa.repeat = RepeatPad;
1044 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);
1045 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1043 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa);
1044 XFreePixmap (dpy, tmp);
1046 1045
1047 if (kernel && params) 1046 if (kernel && params)
1048 { 1047 {
1049 if (h_blurRadius)
1050 {
1051 size = h_blurRadius * 2 + 1; 1048 size = h_blurRadius * 2 + 1;
1052 get_gaussian_kernel (h_blurRadius, size, kernel, params); 1049 get_gaussian_kernel (h_blurRadius, size, kernel, params);
1053 1050
1054 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1051 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1055 XRenderComposite (dpy, 1052 XRenderComposite (dpy,
1056 PictOpSrc, 1053 PictOpSrc,
1057 src, 1054 src,
1058 None, 1055 None,
1059 dst, 1056 dst,
1060 0, 0, 1057 0, 0,
1061 0, 0, 1058 0, 0,
1062 0, 0, 1059 0, 0,
1063 width, height); 1060 width, height);
1064 }
1065 1061
1066 if (v_blurRadius) 1062 ::swap (src, dst);
1067 { 1063
1068 size = v_blurRadius * 2 + 1; 1064 size = v_blurRadius * 2 + 1;
1069 get_gaussian_kernel (v_blurRadius, size, kernel, params); 1065 get_gaussian_kernel (v_blurRadius, size, kernel, params);
1070 ::swap (params[0], params[1]); 1066 ::swap (params[0], params[1]);
1071 1067
1072 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1068 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1073 XRenderComposite (dpy, 1069 XRenderComposite (dpy,
1074 PictOpSrc, 1070 PictOpSrc,
1075 src, 1071 src,
1076 None, 1072 None,
1077 dst, 1073 dst,
1078 0, 0, 1074 0, 0,
1079 0, 0, 1075 0, 0,
1080 0, 0, 1076 0, 0,
1081 width, height); 1077 width, height);
1082 }
1083 1078
1084 ret = true; 1079 ret = true;
1085 } 1080 }
1086 1081
1087 free (kernel); 1082 free (kernel);
1114 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height); 1109 XFillRectangle (dpy, pixmap, gc, 0, 0, width, height);
1115 ret = true; 1110 ret = true;
1116 XFreeGC (dpy, gc); 1111 XFreeGC (dpy, gc);
1117 } 1112 }
1118 } 1113 }
1119 else
1120 {
1121# if XRENDER 1114# if XRENDER
1115 else if (bg_flags & BG_HAS_RENDER)
1116 {
1122 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); 1117 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1123 1118
1124 if (bg_flags & BG_TINT_SET) 1119 if (bg_flags & BG_TINT_SET)
1125 tint.get (c); 1120 tint.get (c);
1126 1121
1135 c.r = c.r * (200 - shade) / 100; 1130 c.r = c.r * (200 - shade) / 100;
1136 c.g = c.g * (200 - shade) / 100; 1131 c.g = c.g * (200 - shade) / 100;
1137 c.b = c.b * (200 - shade) / 100; 1132 c.b = c.b * (200 - shade) / 100;
1138 } 1133 }
1139 1134
1140 XRenderPictFormat *solid_format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
1141 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1135 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1142 XRenderPictureAttributes pa;
1143 1136
1144 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); 1137 Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, 0);
1145 1138
1146 pa.repeat = True; 1139 Picture overlay_pic = create_xrender_mask (dpy, pixmap, True, False);
1147 1140
1148 Pixmap overlay_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32); 1141 Picture mask_pic = create_xrender_mask (dpy, pixmap, True, True);
1149 Picture overlay_pic = XRenderCreatePicture (dpy, overlay_pmap, solid_format, CPRepeat, &pa);
1150 XFreePixmap (dpy, overlay_pmap);
1151
1152 pa.component_alpha = True;
1153 Pixmap mask_pmap = XCreatePixmap (dpy, pixmap, 1, 1, 32);
1154 Picture mask_pic = XRenderCreatePicture (dpy, mask_pmap, solid_format, CPRepeat | CPComponentAlpha, &pa);
1155 XFreePixmap (dpy, mask_pmap);
1156 1142
1157 XRenderColor mask_c; 1143 XRenderColor mask_c;
1158 1144
1159 mask_c.alpha = 0xffff; 1145 mask_c.alpha = 0xffff;
1160 mask_c.red = 1146 mask_c.red =
1165 mask_c.alpha = 0; 1151 mask_c.alpha = 0;
1166 mask_c.red = 0xffff - c.r; 1152 mask_c.red = 0xffff - c.r;
1167 mask_c.green = 0xffff - c.g; 1153 mask_c.green = 0xffff - c.g;
1168 mask_c.blue = 0xffff - c.b; 1154 mask_c.blue = 0xffff - c.b;
1169 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); 1155 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1);
1156
1170 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);
1171 1158
1172 if (shade > 100) 1159 if (shade > 100)
1173 { 1160 {
1174 mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100;
1175 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;
1176 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); 1165 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1);
1177 1166
1178 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);
1179 } 1168 }
1180 1169
1181 ret = true; 1170 ret = true;
1182 1171
1183 XRenderFreePicture (dpy, mask_pic); 1172 XRenderFreePicture (dpy, mask_pic);
1184 XRenderFreePicture (dpy, overlay_pic); 1173 XRenderFreePicture (dpy, overlay_pic);
1185 XRenderFreePicture (dpy, back_pic); 1174 XRenderFreePicture (dpy, back_pic);
1175 }
1186# endif 1176# endif
1187 }
1188 1177
1189 return ret; 1178 return ret;
1190} 1179}
1191 1180
1192/* 1181/*
1243#if XRENDER 1232#if XRENDER
1244 if (bg_flags & BG_HAS_RENDER) 1233 if (bg_flags & BG_HAS_RENDER)
1245 { 1234 {
1246 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);
1247 1236
1248 XRenderPictureAttributes pa;
1249
1250 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); 1237 XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen));
1251 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); 1238 Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, 0);
1252 1239
1253 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); 1240 XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual);
1254 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); 1241 Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, 0);
1255 1242
1256 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);
1257 1244
1258 XRenderFreePicture (dpy, src); 1245 XRenderFreePicture (dpy, src);
1259 XRenderFreePicture (dpy, dst); 1246 XRenderFreePicture (dpy, dst);
1276 bg_pmap_width = window_width; 1263 bg_pmap_width = window_width;
1277 bg_pmap_height = window_height; 1264 bg_pmap_height = window_height;
1278 } 1265 }
1279 1266
1280 /* straightforward pixmap copy */ 1267 /* straightforward pixmap copy */
1281 while (sx < 0) sx += root_width; 1268 while (sx < 0) sx += root_pmap_width;
1282 while (sy < 0) sy += root_height; 1269 while (sy < 0) sy += root_pmap_height;
1283 1270
1284 gcv.tile = recoded_root_pmap; 1271 gcv.tile = recoded_root_pmap;
1285 gcv.fill_style = FillTiled; 1272 gcv.fill_style = FillTiled;
1286 gcv.ts_x_origin = -sx; 1273 gcv.ts_x_origin = -sx;
1287 gcv.ts_y_origin = -sy; 1274 gcv.ts_y_origin = -sy;
1289 1276
1290 if (gc) 1277 if (gc)
1291 { 1278 {
1292 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height); 1279 XFillRectangle (dpy, bg_pixmap, gc, 0, 0, window_width, window_height);
1293 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS); 1280 result |= BG_IS_VALID | (bg_flags & BG_EFFECTS_FLAGS);
1294 XFreeGC (dpy, gc);
1295 1281
1296 if (!(bg_flags & BG_CLIENT_RENDER)) 1282 if (!(bg_flags & BG_CLIENT_RENDER))
1297 { 1283 {
1298 if ((bg_flags & BG_NEEDS_BLUR) 1284 if (bg_flags & BG_NEEDS_BLUR)
1299 && (bg_flags & BG_HAS_RENDER_CONV))
1300 { 1285 {
1301 if (blur_pixmap (bg_pixmap, visual, window_width, window_height)) 1286 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth))
1302 result &= ~BG_NEEDS_BLUR; 1287 result &= ~BG_NEEDS_BLUR;
1303 } 1288 }
1304 if ((bg_flags & BG_NEEDS_TINT) 1289 if (bg_flags & BG_NEEDS_TINT)
1305 && (bg_flags & (BG_TINT_BITAND | BG_HAS_RENDER)))
1306 { 1290 {
1307 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1291 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1308 result &= ~BG_NEEDS_TINT; 1292 result &= ~BG_NEEDS_TINT;
1309 } 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
1310 } /* server side rendering completed */ 1308 } /* server side rendering completed */
1309
1310 XFreeGC (dpy, gc);
1311 } 1311 }
1312 1312
1313 if (recoded_root_pmap != root_pixmap) 1313 if (recoded_root_pmap != root_pixmap)
1314 XFreePixmap (dpy, recoded_root_pmap); 1314 XFreePixmap (dpy, recoded_root_pmap);
1315 1315
1325 1325
1326 root_pixmap = new_root_pixmap; 1326 root_pixmap = new_root_pixmap;
1327} 1327}
1328# endif /* ENABLE_TRANSPARENCY */ 1328# endif /* ENABLE_TRANSPARENCY */
1329 1329
1330#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1331static void shade_ximage (Visual *visual, XImage *ximage, int shade, const rgba &c);
1332# endif
1333
1334bool 1330bool
1335rxvt_term::bg_render () 1331rxvt_term::bg_render ()
1336{ 1332{
1337 unsigned long tr_flags = 0; 1333 unsigned long tr_flags = 0;
1338 1334
1340# ifdef ENABLE_TRANSPARENCY 1336# ifdef ENABLE_TRANSPARENCY
1341 if (bg_flags & BG_IS_TRANSPARENT) 1337 if (bg_flags & BG_IS_TRANSPARENT)
1342 { 1338 {
1343 /* we need to re-generate transparency pixmap in that case ! */ 1339 /* we need to re-generate transparency pixmap in that case ! */
1344 tr_flags = make_transparency_pixmap (); 1340 tr_flags = make_transparency_pixmap ();
1345 if (tr_flags == 0) 1341 if (tr_flags)
1346 return false;
1347 bg_flags |= BG_IS_VALID; 1342 bg_flags |= BG_IS_VALID;
1348 } 1343 }
1349# endif 1344# endif
1350 1345
1351# ifdef BG_IMAGE_FROM_FILE 1346# ifdef BG_IMAGE_FROM_FILE
1352 if ((bg_flags & BG_IS_FROM_FILE) 1347 if ((bg_flags & BG_IS_FROM_FILE)
1353 || (tr_flags & BG_EFFECTS_FLAGS)) 1348 || (tr_flags & BG_EFFECTS_FLAGS))
1354 { 1349 {
1355 if (render_image (tr_flags)) 1350 if (render_image (tr_flags))
1356 bg_flags |= BG_IS_VALID; 1351 bg_flags |= BG_IS_VALID;
1357 }
1358# endif
1359
1360# if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1361 XImage *result = NULL;
1362
1363 if (tr_flags & BG_NEEDS_TINT)
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 if (1)
1373 {
1374 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC);
1375 if (bg_flags & BG_TINT_SET)
1376 tint.get (c);
1377 shade_ximage (DefaultVisual (dpy, display->screen), result, shade, c);
1378 }
1379
1380 GC gc = XCreateGC (dpy, vt, 0UL, NULL);
1381
1382 if (gc)
1383 {
1384 XPutImage (dpy, bg_pixmap, gc, result, 0, 0, 0, 0, result->width, result->height);
1385
1386 XFreeGC (dpy, gc);
1387 }
1388
1389 XDestroyImage (result);
1390 } 1352 }
1391# endif 1353# endif
1392 1354
1393 if (!(bg_flags & BG_IS_VALID)) 1355 if (!(bg_flags & BG_IS_VALID))
1394 { 1356 {
1434#endif /* HAVE_BG_PIXMAP */ 1396#endif /* HAVE_BG_PIXMAP */
1435 1397
1436#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) 1398#if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE)
1437/* based on code from aterm-0.4.2 */ 1399/* based on code from aterm-0.4.2 */
1438 1400
1439static void 1401static inline void
1440shade_ximage (Visual *visual, XImage *ximage, int shade, const rgba &c) 1402fill_lut (uint32_t *lookup, uint32_t mask, int sh, unsigned short low, unsigned short high)
1403{
1404 for (int i = 0; i <= mask >> sh; i++)
1405 {
1406 uint32_t tmp;
1407 tmp = i * high;
1408 tmp += (mask >> sh) * low;
1409 lookup[i] = (tmp / 0xffff) << sh;
1410 }
1411}
1412
1413void
1414rxvt_term::tint_ximage (Visual *visual, XImage *ximage)
1441{ 1415{
1442 int sh_r, sh_g, sh_b; 1416 int sh_r, sh_g, sh_b;
1443 uint32_t mask_r, mask_g, mask_b; 1417 uint32_t mask_r, mask_g, mask_b;
1444 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b; 1418 uint32_t *lookup, *lookup_r, *lookup_g, *lookup_b;
1445 rgba low; 1419 unsigned short low;
1446 rgba high;
1447 int i;
1448 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst; 1420 int host_byte_order = ecb_big_endian () ? MSBFirst : LSBFirst;
1449 1421
1450 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return; 1422 if (visual->c_class != TrueColor || ximage->format != ZPixmap) return;
1451 1423
1452 /* for convenience */ 1424 /* for convenience */
1511 break; 1483 break;
1512 default: 1484 default:
1513 return; /* we do not support this color depth */ 1485 return; /* we do not support this color depth */
1514 } 1486 }
1515 1487
1488 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1489
1490 if (bg_flags & BG_TINT_SET)
1491 tint.get (c);
1492
1516 /* prepare limits for color transformation (each channel is handled separately) */ 1493 /* prepare limits for color transformation (each channel is handled separately) */
1517 if (shade > 100) 1494 if (shade > 100)
1518 { 1495 {
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; 1496 c.r = c.r * (200 - shade) / 100;
1526 low.g = 65535 * (100 - shade) / 100; 1497 c.g = c.g * (200 - shade) / 100;
1527 low.b = 65535 * (100 - shade) / 100; 1498 c.b = c.b * (200 - shade) / 100;
1499
1500 low = 0xffff * (shade - 100) / 100;
1528 } 1501 }
1529 else 1502 else
1530 { 1503 {
1531 high.r = c.r * shade / 100; 1504 c.r = c.r * shade / 100;
1532 high.g = c.g * shade / 100; 1505 c.g = c.g * shade / 100;
1533 high.b = c.b * shade / 100; 1506 c.b = c.b * shade / 100;
1534 1507
1535 low.r = low.g = low.b = 0; 1508 low = 0;
1536 } 1509 }
1537 1510
1538 /* fill our lookup tables */ 1511 /* fill our lookup tables */
1539 for (i = 0; i <= mask_r>>sh_r; i++) 1512 fill_lut (lookup_r, mask_r, sh_r, low, c.r);
1540 { 1513 fill_lut (lookup_g, mask_g, sh_g, low, c.g);
1541 uint32_t tmp; 1514 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 1515
1561 /* apply table to input image (replacing colors by newly calculated ones) */ 1516 /* apply table to input image (replacing colors by newly calculated ones) */
1562 if (ximage->bits_per_pixel == 32 1517 if (ximage->bits_per_pixel == 32
1563 && (ximage->depth == 24 || ximage->depth == 32) 1518 && (ximage->depth == 24 || ximage->depth == 32)
1564 && ximage->byte_order == host_byte_order) 1519 && ximage->byte_order == host_byte_order)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines