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.191 by sf-exg, Fri Dec 30 11:22:48 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
38# if XRENDER 42# if XRENDER
39static Picture 43static Picture
40create_xrender_mask (Display *dpy, Drawable drawable, Bool argb, Bool component_alpha) 44create_xrender_mask (Display *dpy, Drawable drawable, Bool argb, Bool component_alpha)
41{ 45{
125 129
126 return false; 130 return false;
127} 131}
128 132
129# ifdef BG_IMAGE_FROM_FILE 133# ifdef BG_IMAGE_FROM_FILE
130static inline bool
131check_set_scale_value (int geom_flags, int flag, unsigned int &scale, unsigned int new_value)
132{
133 if (geom_flags & flag)
134 {
135 if (new_value > 1000)
136 new_value = 1000;
137 if (new_value != scale)
138 {
139 scale = new_value;
140 return true;
141 }
142 }
143 return false;
144}
145
146static inline bool
147check_set_align_value (int geom_flags, int flag, int &align, int new_value)
148{
149 if (geom_flags & flag)
150 {
151 if (new_value < -100)
152 new_value = -100;
153 else if (new_value > 200)
154 new_value = 200;
155 if (new_value != align)
156 {
157 align = new_value;
158 return true;
159 }
160 }
161 return false;
162}
163
164static inline int 134static inline int
165make_align_position (int align, int window_size, int image_size) 135make_align_position (int align, int window_size, int image_size)
166{ 136{
167 int diff = window_size - image_size; 137 int diff = window_size - image_size;
168 int smaller = min (image_size, window_size); 138 int smaller = min (image_size, window_size);
187 src_pos = -pos; 157 src_pos = -pos;
188 dst_pos = 0; 158 dst_pos = 0;
189 dst_size += pos; 159 dst_size += pos;
190 } 160 }
191 161
192 if (dst_pos + dst_size > target_size)
193 dst_size = target_size - dst_pos; 162 min_it (dst_size, target_size - dst_pos);
194 return src_pos; 163 return src_pos;
195} 164}
196 165
197bool 166bool
198rxvt_term::bg_set_geometry (const char *geom, bool update) 167rxvt_term::bg_set_geometry (const char *geom, bool update)
199{ 168{
200 bool changed = false; 169 bool changed = false;
201 int geom_flags = 0; 170 int geom_flags = 0;
202 int x = 0, y = 0; 171 int x = h_align;
172 int y = v_align;
203 unsigned int w = 0, h = 0; 173 unsigned int w = h_scale;
174 unsigned int h = v_scale;
204 unsigned long new_flags = 0; 175 unsigned long new_flags = 0;
205 176
206 if (geom == NULL) 177 if (geom == NULL)
207 return false; 178 return false;
208 179
317 w = h = defaultScale; 288 w = h = defaultScale;
318 else if (!(geom_flags & HeightValue)) 289 else if (!(geom_flags & HeightValue))
319 h = w; 290 h = w;
320 else if (!(geom_flags & WidthValue)) 291 else if (!(geom_flags & WidthValue))
321 w = h; 292 w = h;
322
323 geom_flags |= WidthValue|HeightValue|XValue|YValue;
324 } 293 }
325 294
326 if (check_set_scale_value (geom_flags, WidthValue, h_scale, w)) changed = true; 295 min_it (w, 1000);
327 if (check_set_scale_value (geom_flags, HeightValue, v_scale, h)) changed = true; 296 min_it (h, 1000);
328 if (check_set_align_value (geom_flags, XValue, h_align, x)) changed = true; 297 clamp_it (x, -100, 200);
329 if (check_set_align_value (geom_flags, YValue, v_align, y)) changed = true; 298 clamp_it (y, -100, 200);
330 299
331 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)
332 { 305 {
333 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;
334 changed = true; 311 changed = true;
335 } 312 }
336 313
337 return changed; 314 return changed;
338} 315}
392 if (tr_flags & BG_NEEDS_TINT) 369 if (tr_flags & BG_NEEDS_TINT)
393 { 370 {
394 ShadingInfo as_shade; 371 ShadingInfo as_shade;
395 as_shade.shading = shade; 372 as_shade.shading = shade;
396 373
397 rgba c; 374 rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC);
375 if (bg_flags & BG_TINT_SET)
398 tint.get (c); 376 tint.get (c);
399 as_shade.tintColor.red = c.r; 377 as_shade.tintColor.red = c.r;
400 as_shade.tintColor.green = c.g; 378 as_shade.tintColor.green = c.g;
401 as_shade.tintColor.blue = c.b; 379 as_shade.tintColor.blue = c.b;
402 380
403 background_tint = shading2tint32 (&as_shade); 381 background_tint = shading2tint32 (&as_shade);
830 Picture mask = create_xrender_mask (dpy, vt, False, False); 808 Picture mask = create_xrender_mask (dpy, vt, False, False);
831 809
832 XRenderColor mask_c; 810 XRenderColor mask_c;
833 811
834 mask_c.alpha = 0x8000; 812 mask_c.alpha = 0x8000;
835 mask_c.red = 0; 813 mask_c.red =
836 mask_c.green = 0; 814 mask_c.green =
837 mask_c.blue = 0; 815 mask_c.blue = 0;
838 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); 816 XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1);
817
839 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);
840 819
841 XRenderFreePicture (dpy, src); 820 XRenderFreePicture (dpy, src);
842 XRenderFreePicture (dpy, dst); 821 XRenderFreePicture (dpy, dst);
843 XRenderFreePicture (dpy, mask); 822 XRenderFreePicture (dpy, mask);
955 { 934 {
956 changed = true; 935 changed = true;
957 v_blurRadius = vr; 936 v_blurRadius = vr;
958 } 937 }
959 938
960 if (v_blurRadius == 0 && h_blurRadius == 0) 939 if (h_blurRadius == 0 || v_blurRadius == 0)
961 bg_flags &= ~BG_NEEDS_BLUR; 940 bg_flags &= ~BG_NEEDS_BLUR;
962 else 941 else
963 bg_flags |= BG_NEEDS_BLUR; 942 bg_flags |= BG_NEEDS_BLUR;
964 943
965 return changed; 944 return changed;
971 rgba c; 950 rgba c;
972 bool has_shade = shade != 100; 951 bool has_shade = shade != 100;
973 952
974 bg_flags &= ~BG_TINT_FLAGS; 953 bg_flags &= ~BG_TINT_FLAGS;
975 954
955 if (bg_flags & BG_TINT_SET)
956 {
976 tint.get (c); 957 tint.get (c);
977
978 if (!has_shade 958 if (!has_shade
979 && (c.r <= 0x00ff || c.r >= 0xff00) 959 && (c.r <= 0x00ff || c.r >= 0xff00)
980 && (c.g <= 0x00ff || c.g >= 0xff00) 960 && (c.g <= 0x00ff || c.g >= 0xff00)
981 && (c.b <= 0x00ff || c.b >= 0xff00)) 961 && (c.b <= 0x00ff || c.b >= 0xff00))
982 bg_flags |= BG_TINT_BITAND; 962 bg_flags |= BG_TINT_BITAND;
963 }
983 964
984 if (has_shade 965 if (has_shade || (bg_flags & BG_TINT_SET))
985 || c.r < 0xff00
986 || c.g < 0xff00
987 || c.b < 0xff00)
988 bg_flags |= BG_NEEDS_TINT; 966 bg_flags |= BG_NEEDS_TINT;
989} 967}
990 968
991bool 969bool
992rxvt_term::bg_set_tint (rxvt_color &new_tint) 970rxvt_term::bg_set_tint (rxvt_color &new_tint)
993{ 971{
994 if (tint != new_tint) 972 if (!(bg_flags & BG_TINT_SET) || tint != new_tint)
995 { 973 {
996 tint = new_tint; 974 tint = new_tint;
975 bg_flags |= BG_TINT_SET;
997 set_tint_shade_flags (); 976 set_tint_shade_flags ();
998 return true; 977 return true;
999 } 978 }
1000 979
1001 return false; 980 return false;
1042 params[i+2] = XDoubleToFixed (kernel[i] / sum); 1021 params[i+2] = XDoubleToFixed (kernel[i] / sum);
1043} 1022}
1044#endif 1023#endif
1045 1024
1046bool 1025bool
1047rxvt_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)
1048{ 1027{
1049 bool ret = false; 1028 bool ret = false;
1050#if XRENDER 1029#if XRENDER
1051 if (!(bg_flags & BG_HAS_RENDER_CONV)) 1030 if (!(bg_flags & BG_HAS_RENDER_CONV))
1052 return false; 1031 return false;
1053 1032
1054 int size = max (h_blurRadius, v_blurRadius) * 2 + 1; 1033 int size = max (h_blurRadius, v_blurRadius) * 2 + 1;
1055 double *kernel = (double *)malloc (size * sizeof (double)); 1034 double *kernel = (double *)malloc (size * sizeof (double));
1056 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); 1035 XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed));
1057 1036
1037 XRenderPictureAttributes pa;
1058 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); 1038 XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual);
1059 1039
1040 pa.repeat = RepeatPad;
1060 Picture src = XRenderCreatePicture (dpy, pixmap, format, 0, 0); 1041 Picture src = XRenderCreatePicture (dpy, pixmap, format, CPRepeat, &pa);
1042 Pixmap tmp = XCreatePixmap (dpy, pixmap, width, height, depth);
1061 Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, 0); 1043 Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa);
1044 XFreePixmap (dpy, tmp);
1062 1045
1063 if (kernel && params) 1046 if (kernel && params)
1064 { 1047 {
1065 if (h_blurRadius)
1066 {
1067 size = h_blurRadius * 2 + 1; 1048 size = h_blurRadius * 2 + 1;
1068 get_gaussian_kernel (h_blurRadius, size, kernel, params); 1049 get_gaussian_kernel (h_blurRadius, size, kernel, params);
1069 1050
1070 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1051 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1071 XRenderComposite (dpy, 1052 XRenderComposite (dpy,
1072 PictOpSrc, 1053 PictOpSrc,
1073 src, 1054 src,
1074 None, 1055 None,
1075 dst, 1056 dst,
1076 0, 0, 1057 0, 0,
1077 0, 0, 1058 0, 0,
1078 0, 0, 1059 0, 0,
1079 width, height); 1060 width, height);
1080 }
1081 1061
1082 if (v_blurRadius) 1062 ::swap (src, dst);
1083 { 1063
1084 size = v_blurRadius * 2 + 1; 1064 size = v_blurRadius * 2 + 1;
1085 get_gaussian_kernel (v_blurRadius, size, kernel, params); 1065 get_gaussian_kernel (v_blurRadius, size, kernel, params);
1086 ::swap (params[0], params[1]); 1066 ::swap (params[0], params[1]);
1087 1067
1088 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); 1068 XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2);
1089 XRenderComposite (dpy, 1069 XRenderComposite (dpy,
1090 PictOpSrc, 1070 PictOpSrc,
1091 src, 1071 src,
1092 None, 1072 None,
1093 dst, 1073 dst,
1094 0, 0, 1074 0, 0,
1095 0, 0, 1075 0, 0,
1096 0, 0, 1076 0, 0,
1097 width, height); 1077 width, height);
1098 }
1099 1078
1100 ret = true; 1079 ret = true;
1101 } 1080 }
1102 1081
1103 free (kernel); 1082 free (kernel);
1133 } 1112 }
1134 } 1113 }
1135# if XRENDER 1114# if XRENDER
1136 else if (bg_flags & BG_HAS_RENDER) 1115 else if (bg_flags & BG_HAS_RENDER)
1137 { 1116 {
1138 rgba c; 1117 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1139 1118
1119 if (bg_flags & BG_TINT_SET)
1140 tint.get (c); 1120 tint.get (c);
1141 1121
1142 if (shade <= 100) 1122 if (shade <= 100)
1143 { 1123 {
1144 c.r = c.r * shade / 100; 1124 c.r = c.r * shade / 100;
1145 c.g = c.g * shade / 100; 1125 c.g = c.g * shade / 100;
1171 mask_c.alpha = 0; 1151 mask_c.alpha = 0;
1172 mask_c.red = 0xffff - c.r; 1152 mask_c.red = 0xffff - c.r;
1173 mask_c.green = 0xffff - c.g; 1153 mask_c.green = 0xffff - c.g;
1174 mask_c.blue = 0xffff - c.b; 1154 mask_c.blue = 0xffff - c.b;
1175 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); 1155 XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1);
1156
1176 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);
1177 1158
1178 if (shade > 100) 1159 if (shade > 100)
1179 { 1160 {
1180 mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100;
1181 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;
1182 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); 1165 XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1);
1183 1166
1184 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);
1185 } 1168 }
1186 1169
1298 1281
1299 if (!(bg_flags & BG_CLIENT_RENDER)) 1282 if (!(bg_flags & BG_CLIENT_RENDER))
1300 { 1283 {
1301 if (bg_flags & BG_NEEDS_BLUR) 1284 if (bg_flags & BG_NEEDS_BLUR)
1302 { 1285 {
1303 if (blur_pixmap (bg_pixmap, visual, window_width, window_height)) 1286 if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth))
1304 result &= ~BG_NEEDS_BLUR; 1287 result &= ~BG_NEEDS_BLUR;
1305 } 1288 }
1306 if (bg_flags & BG_NEEDS_TINT) 1289 if (bg_flags & BG_NEEDS_TINT)
1307 { 1290 {
1308 if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) 1291 if (tint_pixmap (bg_pixmap, visual, window_width, window_height))
1353# ifdef ENABLE_TRANSPARENCY 1336# ifdef ENABLE_TRANSPARENCY
1354 if (bg_flags & BG_IS_TRANSPARENT) 1337 if (bg_flags & BG_IS_TRANSPARENT)
1355 { 1338 {
1356 /* we need to re-generate transparency pixmap in that case ! */ 1339 /* we need to re-generate transparency pixmap in that case ! */
1357 tr_flags = make_transparency_pixmap (); 1340 tr_flags = make_transparency_pixmap ();
1358 if (tr_flags == 0) 1341 if (tr_flags)
1359 return false;
1360 bg_flags |= BG_IS_VALID; 1342 bg_flags |= BG_IS_VALID;
1361 } 1343 }
1362# endif 1344# endif
1363 1345
1364# ifdef BG_IMAGE_FROM_FILE 1346# ifdef BG_IMAGE_FROM_FILE
1365 if ((bg_flags & BG_IS_FROM_FILE) 1347 if ((bg_flags & BG_IS_FROM_FILE)
1389 1371
1390void 1372void
1391rxvt_term::bg_init () 1373rxvt_term::bg_init ()
1392{ 1374{
1393#ifdef ENABLE_TRANSPARENCY 1375#ifdef ENABLE_TRANSPARENCY
1394 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1395 tint.set (this, c);
1396 shade = 100; 1376 shade = 100;
1397#endif 1377#endif
1398 1378
1399 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV); 1379 bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV);
1400#if XRENDER 1380#if XRENDER
1503 break; 1483 break;
1504 default: 1484 default:
1505 return; /* we do not support this color depth */ 1485 return; /* we do not support this color depth */
1506 } 1486 }
1507 1487
1508 rgba c; 1488 rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC);
1509 1489
1490 if (bg_flags & BG_TINT_SET)
1510 tint.get (c); 1491 tint.get (c);
1511 1492
1512 /* prepare limits for color transformation (each channel is handled separately) */ 1493 /* prepare limits for color transformation (each channel is handled separately) */
1513 if (shade > 100) 1494 if (shade > 100)
1514 { 1495 {
1515 c.r = c.r * (200 - shade) / 100; 1496 c.r = c.r * (200 - shade) / 100;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines