… | |
… | |
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 |
39 | static Picture |
43 | static Picture |
40 | create_xrender_mask (Display *dpy, Drawable drawable, Bool argb, Bool component_alpha) |
44 | create_xrender_mask (Display *dpy, Drawable drawable, Bool argb, Bool component_alpha) |
41 | { |
45 | { |
… | |
… | |
187 | src_pos = -pos; |
191 | src_pos = -pos; |
188 | dst_pos = 0; |
192 | dst_pos = 0; |
189 | dst_size += pos; |
193 | dst_size += pos; |
190 | } |
194 | } |
191 | |
195 | |
192 | if (dst_pos + dst_size > target_size) |
|
|
193 | dst_size = target_size - dst_pos; |
196 | min_it (dst_size, target_size - dst_pos); |
194 | return src_pos; |
197 | return src_pos; |
195 | } |
198 | } |
196 | |
199 | |
197 | bool |
200 | bool |
198 | rxvt_term::bg_set_geometry (const char *geom, bool update) |
201 | rxvt_term::bg_set_geometry (const char *geom, bool update) |
… | |
… | |
392 | if (tr_flags & BG_NEEDS_TINT) |
395 | if (tr_flags & BG_NEEDS_TINT) |
393 | { |
396 | { |
394 | ShadingInfo as_shade; |
397 | ShadingInfo as_shade; |
395 | as_shade.shading = shade; |
398 | as_shade.shading = shade; |
396 | |
399 | |
397 | rgba c; |
400 | rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); |
|
|
401 | if (bg_flags & BG_TINT_SET) |
398 | tint.get (c); |
402 | tint.get (c); |
399 | as_shade.tintColor.red = c.r; |
403 | as_shade.tintColor.red = c.r; |
400 | as_shade.tintColor.green = c.g; |
404 | as_shade.tintColor.green = c.g; |
401 | as_shade.tintColor.blue = c.b; |
405 | as_shade.tintColor.blue = c.b; |
402 | |
406 | |
403 | background_tint = shading2tint32 (&as_shade); |
407 | background_tint = shading2tint32 (&as_shade); |
… | |
… | |
819 | } |
823 | } |
820 | |
824 | |
821 | #if XRENDER |
825 | #if XRENDER |
822 | if (tr_flags) |
826 | if (tr_flags) |
823 | { |
827 | { |
824 | XRenderPictureAttributes pa; |
|
|
825 | |
|
|
826 | XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, visual); |
828 | XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); |
|
|
829 | |
827 | Picture src = XRenderCreatePicture (dpy, root_pmap, src_format, 0, &pa); |
830 | Picture src = XRenderCreatePicture (dpy, root_pmap, format, 0, 0); |
828 | |
831 | |
829 | XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); |
|
|
830 | Picture dst = XRenderCreatePicture (dpy, bg_pixmap, dst_format, 0, &pa); |
832 | Picture dst = XRenderCreatePicture (dpy, bg_pixmap, format, 0, 0); |
831 | |
833 | |
832 | Picture mask = create_xrender_mask (dpy, vt, False, False); |
834 | Picture mask = create_xrender_mask (dpy, vt, False, False); |
833 | |
835 | |
834 | XRenderColor mask_c; |
836 | XRenderColor mask_c; |
835 | |
837 | |
836 | mask_c.alpha = 0x8000; |
838 | mask_c.alpha = 0x8000; |
837 | mask_c.red = 0; |
839 | mask_c.red = |
838 | mask_c.green = 0; |
840 | mask_c.green = |
839 | mask_c.blue = 0; |
841 | mask_c.blue = 0; |
840 | XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); |
842 | XRenderFillRectangle (dpy, PictOpSrc, mask, &mask_c, 0, 0, 1, 1); |
|
|
843 | |
841 | 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); |
842 | |
845 | |
843 | XRenderFreePicture (dpy, src); |
846 | XRenderFreePicture (dpy, src); |
844 | XRenderFreePicture (dpy, dst); |
847 | XRenderFreePicture (dpy, dst); |
845 | XRenderFreePicture (dpy, mask); |
848 | XRenderFreePicture (dpy, mask); |
… | |
… | |
957 | { |
960 | { |
958 | changed = true; |
961 | changed = true; |
959 | v_blurRadius = vr; |
962 | v_blurRadius = vr; |
960 | } |
963 | } |
961 | |
964 | |
962 | if (v_blurRadius == 0 && h_blurRadius == 0) |
965 | if (h_blurRadius == 0 || v_blurRadius == 0) |
963 | bg_flags &= ~BG_NEEDS_BLUR; |
966 | bg_flags &= ~BG_NEEDS_BLUR; |
964 | else |
967 | else |
965 | bg_flags |= BG_NEEDS_BLUR; |
968 | bg_flags |= BG_NEEDS_BLUR; |
966 | |
969 | |
967 | return changed; |
970 | return changed; |
… | |
… | |
973 | rgba c; |
976 | rgba c; |
974 | bool has_shade = shade != 100; |
977 | bool has_shade = shade != 100; |
975 | |
978 | |
976 | bg_flags &= ~BG_TINT_FLAGS; |
979 | bg_flags &= ~BG_TINT_FLAGS; |
977 | |
980 | |
|
|
981 | if (bg_flags & BG_TINT_SET) |
|
|
982 | { |
978 | tint.get (c); |
983 | tint.get (c); |
979 | |
|
|
980 | if (!has_shade |
984 | if (!has_shade |
981 | && (c.r <= 0x00ff || c.r >= 0xff00) |
985 | && (c.r <= 0x00ff || c.r >= 0xff00) |
982 | && (c.g <= 0x00ff || c.g >= 0xff00) |
986 | && (c.g <= 0x00ff || c.g >= 0xff00) |
983 | && (c.b <= 0x00ff || c.b >= 0xff00)) |
987 | && (c.b <= 0x00ff || c.b >= 0xff00)) |
984 | bg_flags |= BG_TINT_BITAND; |
988 | bg_flags |= BG_TINT_BITAND; |
|
|
989 | } |
985 | |
990 | |
986 | if (has_shade |
991 | if (has_shade || (bg_flags & BG_TINT_SET)) |
987 | || c.r < 0xff00 |
|
|
988 | || c.g < 0xff00 |
|
|
989 | || c.b < 0xff00) |
|
|
990 | bg_flags |= BG_NEEDS_TINT; |
992 | bg_flags |= BG_NEEDS_TINT; |
991 | } |
993 | } |
992 | |
994 | |
993 | bool |
995 | bool |
994 | rxvt_term::bg_set_tint (rxvt_color &new_tint) |
996 | rxvt_term::bg_set_tint (rxvt_color &new_tint) |
995 | { |
997 | { |
996 | if (tint != new_tint) |
998 | if (!(bg_flags & BG_TINT_SET) || tint != new_tint) |
997 | { |
999 | { |
998 | tint = new_tint; |
1000 | tint = new_tint; |
|
|
1001 | bg_flags |= BG_TINT_SET; |
999 | set_tint_shade_flags (); |
1002 | set_tint_shade_flags (); |
1000 | return true; |
1003 | return true; |
1001 | } |
1004 | } |
1002 | |
1005 | |
1003 | return false; |
1006 | return false; |
… | |
… | |
1044 | params[i+2] = XDoubleToFixed (kernel[i] / sum); |
1047 | params[i+2] = XDoubleToFixed (kernel[i] / sum); |
1045 | } |
1048 | } |
1046 | #endif |
1049 | #endif |
1047 | |
1050 | |
1048 | bool |
1051 | bool |
1049 | rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height) |
1052 | rxvt_term::blur_pixmap (Pixmap pixmap, Visual *visual, int width, int height, int depth) |
1050 | { |
1053 | { |
1051 | bool ret = false; |
1054 | bool ret = false; |
1052 | #if XRENDER |
1055 | #if XRENDER |
1053 | if (!(bg_flags & BG_HAS_RENDER_CONV)) |
1056 | if (!(bg_flags & BG_HAS_RENDER_CONV)) |
1054 | return false; |
1057 | return false; |
… | |
… | |
1058 | XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); |
1061 | XFixed *params = (XFixed *)malloc ((size + 2) * sizeof (XFixed)); |
1059 | |
1062 | |
1060 | XRenderPictureAttributes pa; |
1063 | XRenderPictureAttributes pa; |
1061 | XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); |
1064 | XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); |
1062 | |
1065 | |
|
|
1066 | pa.repeat = RepeatPad; |
1063 | 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); |
1064 | Picture dst = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); |
1069 | Picture dst = XRenderCreatePicture (dpy, tmp, format, CPRepeat, &pa); |
|
|
1070 | XFreePixmap (dpy, tmp); |
1065 | |
1071 | |
1066 | if (kernel && params) |
1072 | if (kernel && params) |
1067 | { |
1073 | { |
1068 | if (h_blurRadius) |
|
|
1069 | { |
|
|
1070 | size = h_blurRadius * 2 + 1; |
1074 | size = h_blurRadius * 2 + 1; |
1071 | get_gaussian_kernel (h_blurRadius, size, kernel, params); |
1075 | get_gaussian_kernel (h_blurRadius, size, kernel, params); |
1072 | |
1076 | |
1073 | XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); |
1077 | XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); |
1074 | XRenderComposite (dpy, |
1078 | XRenderComposite (dpy, |
1075 | PictOpSrc, |
1079 | PictOpSrc, |
1076 | src, |
1080 | src, |
1077 | None, |
1081 | None, |
1078 | dst, |
1082 | dst, |
1079 | 0, 0, |
1083 | 0, 0, |
1080 | 0, 0, |
1084 | 0, 0, |
1081 | 0, 0, |
1085 | 0, 0, |
1082 | width, height); |
1086 | width, height); |
1083 | } |
|
|
1084 | |
1087 | |
1085 | if (v_blurRadius) |
1088 | ::swap (src, dst); |
1086 | { |
1089 | |
1087 | size = v_blurRadius * 2 + 1; |
1090 | size = v_blurRadius * 2 + 1; |
1088 | get_gaussian_kernel (v_blurRadius, size, kernel, params); |
1091 | get_gaussian_kernel (v_blurRadius, size, kernel, params); |
1089 | ::swap (params[0], params[1]); |
1092 | ::swap (params[0], params[1]); |
1090 | |
1093 | |
1091 | XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); |
1094 | XRenderSetPictureFilter (dpy, src, FilterConvolution, params, size+2); |
1092 | XRenderComposite (dpy, |
1095 | XRenderComposite (dpy, |
1093 | PictOpSrc, |
1096 | PictOpSrc, |
1094 | src, |
1097 | src, |
1095 | None, |
1098 | None, |
1096 | dst, |
1099 | dst, |
1097 | 0, 0, |
1100 | 0, 0, |
1098 | 0, 0, |
1101 | 0, 0, |
1099 | 0, 0, |
1102 | 0, 0, |
1100 | width, height); |
1103 | width, height); |
1101 | } |
|
|
1102 | |
1104 | |
1103 | ret = true; |
1105 | ret = true; |
1104 | } |
1106 | } |
1105 | |
1107 | |
1106 | free (kernel); |
1108 | free (kernel); |
… | |
… | |
1136 | } |
1138 | } |
1137 | } |
1139 | } |
1138 | # if XRENDER |
1140 | # if XRENDER |
1139 | else if (bg_flags & BG_HAS_RENDER) |
1141 | else if (bg_flags & BG_HAS_RENDER) |
1140 | { |
1142 | { |
1141 | rgba c; |
1143 | rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); |
1142 | |
1144 | |
|
|
1145 | if (bg_flags & BG_TINT_SET) |
1143 | tint.get (c); |
1146 | tint.get (c); |
1144 | |
1147 | |
1145 | if (shade <= 100) |
1148 | if (shade <= 100) |
1146 | { |
1149 | { |
1147 | c.r = c.r * shade / 100; |
1150 | c.r = c.r * shade / 100; |
1148 | c.g = c.g * shade / 100; |
1151 | c.g = c.g * shade / 100; |
… | |
… | |
1154 | c.g = c.g * (200 - shade) / 100; |
1157 | c.g = c.g * (200 - shade) / 100; |
1155 | c.b = c.b * (200 - shade) / 100; |
1158 | c.b = c.b * (200 - shade) / 100; |
1156 | } |
1159 | } |
1157 | |
1160 | |
1158 | XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); |
1161 | XRenderPictFormat *format = XRenderFindVisualFormat (dpy, visual); |
1159 | XRenderPictureAttributes pa; |
|
|
1160 | |
1162 | |
1161 | Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, &pa); |
1163 | Picture back_pic = XRenderCreatePicture (dpy, pixmap, format, 0, 0); |
1162 | |
1164 | |
1163 | Picture overlay_pic = create_xrender_mask (dpy, pixmap, True, False); |
1165 | Picture overlay_pic = create_xrender_mask (dpy, pixmap, True, False); |
1164 | |
1166 | |
1165 | Picture mask_pic = create_xrender_mask (dpy, pixmap, True, True); |
1167 | Picture mask_pic = create_xrender_mask (dpy, pixmap, True, True); |
1166 | |
1168 | |
… | |
… | |
1175 | mask_c.alpha = 0; |
1177 | mask_c.alpha = 0; |
1176 | mask_c.red = 0xffff - c.r; |
1178 | mask_c.red = 0xffff - c.r; |
1177 | mask_c.green = 0xffff - c.g; |
1179 | mask_c.green = 0xffff - c.g; |
1178 | mask_c.blue = 0xffff - c.b; |
1180 | mask_c.blue = 0xffff - c.b; |
1179 | XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); |
1181 | XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); |
|
|
1182 | |
1180 | 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); |
1181 | |
1184 | |
1182 | if (shade > 100) |
1185 | if (shade > 100) |
1183 | { |
1186 | { |
1184 | mask_c.red = mask_c.green = mask_c.blue = 0xffff * (shade - 100) / 100; |
|
|
1185 | 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; |
1186 | XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); |
1191 | XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); |
1187 | |
1192 | |
1188 | 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); |
1189 | } |
1194 | } |
1190 | |
1195 | |
… | |
… | |
1253 | #if XRENDER |
1258 | #if XRENDER |
1254 | if (bg_flags & BG_HAS_RENDER) |
1259 | if (bg_flags & BG_HAS_RENDER) |
1255 | { |
1260 | { |
1256 | 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); |
1257 | |
1262 | |
1258 | XRenderPictureAttributes pa; |
|
|
1259 | |
|
|
1260 | XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); |
1263 | XRenderPictFormat *src_format = XRenderFindVisualFormat (dpy, DefaultVisual (dpy, screen)); |
1261 | Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, &pa); |
1264 | Picture src = XRenderCreatePicture (dpy, root_pixmap, src_format, 0, 0); |
1262 | |
1265 | |
1263 | XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); |
1266 | XRenderPictFormat *dst_format = XRenderFindVisualFormat (dpy, visual); |
1264 | Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, &pa); |
1267 | Picture dst = XRenderCreatePicture (dpy, recoded_root_pmap, dst_format, 0, 0); |
1265 | |
1268 | |
1266 | 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); |
1267 | |
1270 | |
1268 | XRenderFreePicture (dpy, src); |
1271 | XRenderFreePicture (dpy, src); |
1269 | XRenderFreePicture (dpy, dst); |
1272 | XRenderFreePicture (dpy, dst); |
… | |
… | |
1304 | |
1307 | |
1305 | if (!(bg_flags & BG_CLIENT_RENDER)) |
1308 | if (!(bg_flags & BG_CLIENT_RENDER)) |
1306 | { |
1309 | { |
1307 | if (bg_flags & BG_NEEDS_BLUR) |
1310 | if (bg_flags & BG_NEEDS_BLUR) |
1308 | { |
1311 | { |
1309 | if (blur_pixmap (bg_pixmap, visual, window_width, window_height)) |
1312 | if (blur_pixmap (bg_pixmap, visual, window_width, window_height, depth)) |
1310 | result &= ~BG_NEEDS_BLUR; |
1313 | result &= ~BG_NEEDS_BLUR; |
1311 | } |
1314 | } |
1312 | if (bg_flags & BG_NEEDS_TINT) |
1315 | if (bg_flags & BG_NEEDS_TINT) |
1313 | { |
1316 | { |
1314 | if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) |
1317 | if (tint_pixmap (bg_pixmap, visual, window_width, window_height)) |
… | |
… | |
1395 | |
1398 | |
1396 | void |
1399 | void |
1397 | rxvt_term::bg_init () |
1400 | rxvt_term::bg_init () |
1398 | { |
1401 | { |
1399 | #ifdef ENABLE_TRANSPARENCY |
1402 | #ifdef ENABLE_TRANSPARENCY |
1400 | rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); |
|
|
1401 | tint.set (this, c); |
|
|
1402 | shade = 100; |
1403 | shade = 100; |
1403 | #endif |
1404 | #endif |
1404 | |
1405 | |
1405 | bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV); |
1406 | bg_flags &= ~(BG_HAS_RENDER | BG_HAS_RENDER_CONV); |
1406 | #if XRENDER |
1407 | #if XRENDER |
… | |
… | |
1509 | break; |
1510 | break; |
1510 | default: |
1511 | default: |
1511 | return; /* we do not support this color depth */ |
1512 | return; /* we do not support this color depth */ |
1512 | } |
1513 | } |
1513 | |
1514 | |
1514 | rgba c; |
1515 | rgba c (rgba::MAX_CC, rgba::MAX_CC, rgba::MAX_CC); |
1515 | |
1516 | |
|
|
1517 | if (bg_flags & BG_TINT_SET) |
1516 | tint.get (c); |
1518 | tint.get (c); |
1517 | |
1519 | |
1518 | /* prepare limits for color transformation (each channel is handled separately) */ |
1520 | /* prepare limits for color transformation (each channel is handled separately) */ |
1519 | if (shade > 100) |
1521 | if (shade > 100) |
1520 | { |
1522 | { |
1521 | c.r = c.r * (200 - shade) / 100; |
1523 | c.r = c.r * (200 - shade) / 100; |