… | |
… | |
84 | } |
84 | } |
85 | # endif |
85 | # endif |
86 | # ifdef ENABLE_TRANSPARENCY |
86 | # ifdef ENABLE_TRANSPARENCY |
87 | if (flags & isTransparent) |
87 | if (flags & isTransparent) |
88 | return true; |
88 | return true; |
|
|
89 | # endif |
|
|
90 | return false; |
|
|
91 | } |
|
|
92 | |
|
|
93 | bool bgPixmap_t::need_client_side_rendering () |
|
|
94 | { |
|
|
95 | # ifdef HAVE_AFTERIMAGE |
|
|
96 | if (original_asim != NULL) |
|
|
97 | return true; |
|
|
98 | # endif |
|
|
99 | # ifdef ENABLE_TRANSPARENCY |
|
|
100 | if (flags & isTransparent) |
|
|
101 | { |
|
|
102 | if ((flags & blurNeeded) |
|
|
103 | || ((flags & tintNeeded) && !(flags & tintServerSide))) |
|
|
104 | return true; |
|
|
105 | } |
89 | # endif |
106 | # endif |
90 | return false; |
107 | return false; |
91 | } |
108 | } |
92 | |
109 | |
93 | # ifdef XPM_BACKGROUND |
110 | # ifdef XPM_BACKGROUND |
… | |
… | |
597 | if (v_blurRadius != vr) |
614 | if (v_blurRadius != vr) |
598 | { |
615 | { |
599 | ++changed; |
616 | ++changed; |
600 | v_blurRadius = vr; |
617 | v_blurRadius = vr; |
601 | } |
618 | } |
|
|
619 | if (v_blurRadius == 0 && h_blurRadius == 0) |
|
|
620 | flags &= ~blurNeeded; |
|
|
621 | else |
|
|
622 | flags |= blurNeeded; |
602 | return (changed>0); |
623 | return (changed>0); |
603 | } |
624 | } |
604 | |
625 | |
605 | static inline unsigned long |
626 | static inline unsigned long |
606 | compute_tint_shade_flags (rxvt_color *tint, int shade) |
627 | compute_tint_shade_flags (rxvt_color *tint, int shade) |
… | |
… | |
612 | else if (tint) |
633 | else if (tint) |
613 | { |
634 | { |
614 | rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); |
635 | rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); |
615 | tint->get (c); |
636 | tint->get (c); |
616 | |
637 | |
617 | flags |= bgPixmap_t::tintNeeded; |
|
|
618 | if ((c.r > 0x000700 || c.g > 0x000700 || c.b > 0x000700) |
638 | if ((c.r > 0x000700 || c.g > 0x000700 || c.b > 0x000700) |
619 | && (c.r < 0x00f700 || c.g < 0x00f700 || c.b < 0x00f700)) |
639 | && (c.r < 0x00f700 || c.g < 0x00f700 || c.b < 0x00f700)) |
620 | { |
640 | { |
621 | flags |= bgPixmap_t::tintNeeded; |
641 | flags |= bgPixmap_t::tintNeeded; |
622 | #define IS_COMPONENT_WHOLESOME(cmp) ((cmp) <= 0x000700 || (cmp) >= 0x00f700) |
642 | # define IS_COMPONENT_WHOLESOME(cmp) ((cmp) <= 0x000700 || (cmp) >= 0x00f700) |
623 | if (IS_COMPONENT_WHOLESOME (c.r) |
643 | if (IS_COMPONENT_WHOLESOME (c.r) |
624 | && IS_COMPONENT_WHOLESOME (c.g) |
644 | && IS_COMPONENT_WHOLESOME (c.g) |
625 | && IS_COMPONENT_WHOLESOME (c.b)) |
645 | && IS_COMPONENT_WHOLESOME (c.b)) |
626 | flags |= bgPixmap_t::tintServerSide; |
646 | flags |= bgPixmap_t::tintServerSide; |
627 | #undef IS_COMPONENT_WHOLESOME |
647 | # undef IS_COMPONENT_WHOLESOME |
628 | } |
648 | } |
629 | } |
649 | } |
630 | return flags; |
650 | return flags; |
631 | } |
651 | } |
632 | |
652 | |
… | |
… | |
791 | } |
811 | } |
792 | } |
812 | } |
793 | |
813 | |
794 | if (tiled_root_pmap != None) |
814 | if (tiled_root_pmap != None) |
795 | { |
815 | { |
796 | if (flags & tintNeeded) |
816 | if (flags & tintNeeded && !need_client_side_rendering ()) |
797 | { |
817 | { |
798 | if ((flags & tintServerSide) |
|
|
799 | && h_blurRadius <= 1 && v_blurRadius <= 1 |
|
|
800 | # ifdef HAVE_AFTERIMAGE |
|
|
801 | && original_asim == NULL |
|
|
802 | # endif |
|
|
803 | ) |
|
|
804 | { /* In this case we can tint image server-side getting significant |
818 | /* In this case we can tint image server-side getting significant |
805 | * performance improvements, as we eliminate XImage transfer |
819 | * performance improvements, as we eliminate XImage transfer |
806 | */ |
820 | */ |
807 | gcv.foreground = Pixel (tint); |
821 | gcv.foreground = Pixel (tint); |
808 | gcv.function = GXand; |
822 | gcv.function = GXand; |
809 | gcv.fill_style = FillSolid; |
823 | gcv.fill_style = FillSolid; |
810 | if (gc) |
824 | if (gc) |
811 | XChangeGC (dpy, gc, GCFillStyle | GCForeground | GCFunction, &gcv); |
825 | XChangeGC (dpy, gc, GCFillStyle | GCForeground | GCFunction, &gcv); |
812 | else |
826 | else |
813 | gc = XCreateGC (dpy, root, GCFillStyle | GCForeground | GCFunction, &gcv); |
827 | gc = XCreateGC (dpy, root, GCFillStyle | GCForeground | GCFunction, &gcv); |
814 | if (gc) |
828 | if (gc) |
815 | { |
829 | { |
816 | XFillRectangle (dpy, tiled_root_pmap, gc, 0, 0, window_width, window_height); |
830 | XFillRectangle (dpy, tiled_root_pmap, gc, 0, 0, window_width, window_height); |
817 | result |= transpPmapTinted; |
831 | result |= transpPmapTinted; |
818 | } |
|
|
819 | } |
832 | } |
820 | } |
833 | } |
821 | if (pixmap) |
834 | if (pixmap) |
822 | XFreePixmap (dpy, pixmap); |
835 | XFreePixmap (dpy, pixmap); |
823 | pixmap = tiled_root_pmap; |
836 | pixmap = tiled_root_pmap; |
… | |
… | |
850 | } |
863 | } |
851 | # endif /* ENABLE_TRANSPARENCY */ |
864 | # endif /* ENABLE_TRANSPARENCY */ |
852 | |
865 | |
853 | # ifndef HAVE_AFTERIMAGE |
866 | # ifndef HAVE_AFTERIMAGE |
854 | static void ShadeXImage(rxvt_term *term, XImage* srcImage, int shade, int rm, int gm, int bm); |
867 | static void ShadeXImage(rxvt_term *term, XImage* srcImage, int shade, int rm, int gm, int bm); |
855 | #endif |
868 | # endif |
856 | |
869 | |
857 | |
870 | |
858 | bool |
871 | bool |
859 | bgPixmap_t::render () |
872 | bgPixmap_t::render () |
860 | { |
873 | { |
… | |
… | |
885 | ASImage *background = NULL; |
898 | ASImage *background = NULL; |
886 | ARGB32 as_tint = TINT_LEAVE_SAME; |
899 | ARGB32 as_tint = TINT_LEAVE_SAME; |
887 | if (background_flags) |
900 | if (background_flags) |
888 | background = pixmap2ximage (target->asv, pixmap, 0, 0, pmap_width, pmap_height, AllPlanes, 100); |
901 | background = pixmap2ximage (target->asv, pixmap, 0, 0, pmap_width, pmap_height, AllPlanes, 100); |
889 | |
902 | |
|
|
903 | # ifdef ENABLE_TRANSPARENCY |
890 | if (!(background_flags & transpPmapTinted) && (flags & tintNeeded)) |
904 | if (!(background_flags & transpPmapTinted) && (flags & tintNeeded)) |
891 | { |
905 | { |
892 | ShadingInfo as_shade; |
906 | ShadingInfo as_shade; |
893 | as_shade.shading = (shade == 0) ? 100 : shade; |
907 | as_shade.shading = (shade == 0) ? 100 : shade; |
894 | |
908 | |
… | |
… | |
899 | as_shade.tintColor.green = c.g; |
913 | as_shade.tintColor.green = c.g; |
900 | as_shade.tintColor.blue = c.b; |
914 | as_shade.tintColor.blue = c.b; |
901 | |
915 | |
902 | as_tint = shading2tint32 (&as_shade); |
916 | as_tint = shading2tint32 (&as_shade); |
903 | } |
917 | } |
|
|
918 | if (!(background_flags & transpPmapBlured) && (flags & blurNeeded) && background != NULL) |
|
|
919 | { |
|
|
920 | ASImage* tmp = blur_asimage_gauss (target->asv, background, h_blurRadius, v_blurRadius, 0xFFFFFFFF, |
|
|
921 | (original_asim == NULL || tint == TINT_LEAVE_SAME)?ASA_XImage:ASA_ASImage, |
|
|
922 | 100, ASIMAGE_QUALITY_DEFAULT); |
|
|
923 | if (tmp) |
|
|
924 | { |
|
|
925 | destroy_asimage (&background); |
|
|
926 | background = tmp; |
|
|
927 | } |
|
|
928 | } |
|
|
929 | # endif |
|
|
930 | |
904 | if (render_asim (background, as_tint)) |
931 | if (render_asim (background, as_tint)) |
905 | flags = flags & ~isInvalid; |
932 | flags = flags & ~isInvalid; |
906 | if (background) |
933 | if (background) |
907 | destroy_asimage (&background); |
934 | destroy_asimage (&background); |
908 | } |
935 | } |
… | |
… | |
920 | if (flags & tintSet) |
947 | if (flags & tintSet) |
921 | tint.get (c); |
948 | tint.get (c); |
922 | ShadeXImage (target, result, shade, c.r, c.g, c.b); |
949 | ShadeXImage (target, result, shade, c.r, c.g, c.b); |
923 | } |
950 | } |
924 | } |
951 | } |
925 | # endif |
952 | # endif /* HAVE_AFTERIMAGE */ |
926 | if (result != NULL) |
953 | if (result != NULL) |
927 | { |
954 | { |
928 | GC gc = XCreateGC (target->dpy, target->vt, 0UL, NULL); |
955 | GC gc = XCreateGC (target->dpy, target->vt, 0UL, NULL); |
929 | if (gc) |
956 | if (gc) |
930 | { |
957 | { |
931 | if (pmap_depth != target->depth && pixmap != None) |
958 | if (/*pmap_depth != target->depth &&*/ pixmap != None) |
932 | { |
959 | { |
933 | XFreePixmap (target->dpy, pixmap); |
960 | XFreePixmap (target->dpy, pixmap); |
934 | pixmap = None; |
961 | pixmap = None; |
935 | } |
962 | } |
936 | if (pixmap == None) |
963 | if (pixmap == None) |
… | |
… | |
938 | pixmap = XCreatePixmap (target->dpy, target->vt, result->width, result->height, target->depth); |
965 | pixmap = XCreatePixmap (target->dpy, target->vt, result->width, result->height, target->depth); |
939 | pmap_width = result->width; |
966 | pmap_width = result->width; |
940 | pmap_height = result->height; |
967 | pmap_height = result->height; |
941 | pmap_depth = target->depth; |
968 | pmap_depth = target->depth; |
942 | } |
969 | } |
|
|
970 | if (pmap_depth != result->depth) |
|
|
971 | { /* Bad Match error will ensue ! stupid X !!!! */ |
|
|
972 | if( result->depth == 24 && pmap_depth == 32) |
|
|
973 | result->depth = 32; |
|
|
974 | else if( result->depth == 32 && pmap_depth == 24) |
|
|
975 | result->depth = 24; |
|
|
976 | else |
|
|
977 | { |
|
|
978 | /* TODO: implement image recoding */ |
|
|
979 | } |
|
|
980 | } |
|
|
981 | if (pmap_depth == result->depth) |
943 | XPutImage (target->dpy, pixmap, gc, result, 0, 0, 0, 0, result->width, result->height); |
982 | XPutImage (target->dpy, pixmap, gc, result, 0, 0, 0, 0, result->width, result->height); |
944 | XFreeGC (target->dpy, gc); |
983 | XFreeGC (target->dpy, gc); |
945 | flags = flags & ~isInvalid; |
984 | flags = flags & ~isInvalid; |
946 | } |
985 | } |
947 | XDestroyImage (result); |
986 | XDestroyImage (result); |
948 | } |
987 | } |
… | |
… | |
952 | if (pixmap != None) |
991 | if (pixmap != None) |
953 | { |
992 | { |
954 | XFreePixmap (target->dpy, pixmap); |
993 | XFreePixmap (target->dpy, pixmap); |
955 | pixmap = None; |
994 | pixmap = None; |
956 | } |
995 | } |
957 | // TODO : we need to get rid of that garbadge : |
|
|
958 | target->am_transparent = target->am_pixmap_trans = 0; |
|
|
959 | } |
996 | } |
960 | else |
|
|
961 | target->am_transparent = target->am_pixmap_trans = 1; |
|
|
962 | |
997 | |
963 | apply (); |
998 | apply (); |
964 | |
999 | |
965 | return true; |
1000 | return true; |
966 | } |
1001 | } |
… | |
… | |
1022 | } |
1057 | } |
1023 | /* don't want Expose on the parent */ |
1058 | /* don't want Expose on the parent */ |
1024 | XClearArea (target->dpy, target->parent[0], 0, 0, 0, 0, False); |
1059 | XClearArea (target->dpy, target->parent[0], 0, 0, 0, 0, False); |
1025 | /* do want Expose on the vt */ |
1060 | /* do want Expose on the vt */ |
1026 | XClearArea (target->dpy, target->parent[0], 0, 0, 0, 0, True); |
1061 | XClearArea (target->dpy, target->parent[0], 0, 0, 0, 0, True); |
1027 | #if HAVE_SCROLLBARS |
1062 | # if HAVE_SCROLLBARS |
1028 | if (target->scrollBar.win) |
1063 | if (target->scrollBar.win) |
1029 | { |
1064 | { |
1030 | target->scrollBar.setIdle (); |
1065 | target->scrollBar.setIdle (); |
1031 | target->scrollbar_show (0); |
1066 | target->scrollbar_show (0); |
1032 | } |
1067 | } |
1033 | #endif |
1068 | # endif |
|
|
1069 | /* Is that really neccessary? we did a XClearArea to generate Expose events alreday ! */ |
|
|
1070 | target->want_refresh = 1; |
|
|
1071 | # ifdef ENABLE_TRANSPARENCY |
1034 | target->want_refresh = target->want_full_refresh = 1; |
1072 | target->want_full_refresh = 1; |
|
|
1073 | # endif |
|
|
1074 | /* TODO: why do we need a flush here ??? It causes segfault on resize ! */ |
1035 | target->flush (); |
1075 | // target->flush (); |
1036 | } |
1076 | } |
1037 | } |
1077 | } |
1038 | #endif /* HAVE_BG_PIXMAP */ |
|
|
1039 | |
|
|
1040 | |
1078 | |
1041 | void |
1079 | void |
1042 | rxvt_term::get_window_origin (int &x, int &y) |
1080 | rxvt_term::get_window_origin (int &x, int &y) |
1043 | { |
1081 | { |
1044 | Window cr; |
1082 | Window cr; |
1045 | XTranslateCoordinates (dpy, parent[0], display->root, 0, 0, &x, &y, &cr); |
1083 | XTranslateCoordinates (dpy, parent[0], display->root, 0, 0, &x, &y, &cr); |
|
|
1084 | /* fprintf( stderr, "origin is %+d%+d\n", x, y);*/ |
1046 | } |
1085 | } |
1047 | |
1086 | |
1048 | Pixmap |
1087 | Pixmap |
1049 | rxvt_term::get_pixmap_property (int prop_id) |
1088 | rxvt_term::get_pixmap_property (int prop_id) |
1050 | { |
1089 | { |
… | |
… | |
1064 | } |
1103 | } |
1065 | } |
1104 | } |
1066 | return None; |
1105 | return None; |
1067 | } |
1106 | } |
1068 | |
1107 | |
|
|
1108 | /* |
|
|
1109 | * Check our parents are still who we think they are. |
|
|
1110 | * Do transparency updates if required |
|
|
1111 | */ |
|
|
1112 | int |
|
|
1113 | rxvt_term::update_background () |
|
|
1114 | { |
|
|
1115 | bgPixmap.invalidate(); |
|
|
1116 | /* no chance of real time refresh if we are blurring ! */ |
|
|
1117 | if (bgPixmap.invalid_since + 0.5 < NOW && !(bgPixmap.flags & bgPixmap_t::blurNeeded)) |
|
|
1118 | bgPixmap.render(); |
|
|
1119 | else |
|
|
1120 | { |
|
|
1121 | update_background_ev.stop (); |
|
|
1122 | if (!bgPixmap.need_client_side_rendering()) |
|
|
1123 | update_background_ev.start (NOW + .05); |
|
|
1124 | else if (bgPixmap.flags & bgPixmap_t::blurNeeded) |
|
|
1125 | update_background_ev.start (NOW + .2); /* very slow !!! */ |
|
|
1126 | else |
|
|
1127 | update_background_ev.start (NOW + .07); |
|
|
1128 | } |
|
|
1129 | return 0; |
|
|
1130 | } |
1069 | |
1131 | |
1070 | #ifdef ENABLE_TRANSPARENCY |
1132 | void |
1071 | #ifndef HAVE_AFTERIMAGE |
1133 | rxvt_term::update_background_cb (time_watcher &w) |
|
|
1134 | { |
|
|
1135 | bgPixmap.render (); |
|
|
1136 | } |
|
|
1137 | #endif /* HAVE_BG_PIXMAP */ |
|
|
1138 | |
|
|
1139 | #if defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) |
1072 | /* taken from aterm-0.4.2 */ |
1140 | /* taken from aterm-0.4.2 */ |
1073 | |
1141 | |
1074 | typedef uint32_t RUINT32T; |
1142 | typedef uint32_t RUINT32T; |
1075 | |
1143 | |
1076 | static void |
1144 | static void |
… | |
… | |
1299 | } |
1367 | } |
1300 | } |
1368 | } |
1301 | |
1369 | |
1302 | free (lookup); |
1370 | free (lookup); |
1303 | } |
1371 | } |
1304 | #endif |
1372 | #endif /* defined(ENABLE_TRANSPARENCY) && !defined(HAVE_AFTERIMAGE) */ |
1305 | |
1373 | |
1306 | /* |
1374 | #if 0 /* replaced by a bgPixmap_t::render() - leve here temporarily for reference */ |
1307 | * Check our parents are still who we think they are. |
|
|
1308 | * Do transparency updates if required |
|
|
1309 | */ |
|
|
1310 | int |
|
|
1311 | rxvt_term::check_our_parents () |
|
|
1312 | { |
|
|
1313 | check_our_parents_ev.stop (); |
|
|
1314 | check_our_parents_ev.start (NOW + .1); |
|
|
1315 | return 0; |
|
|
1316 | } |
|
|
1317 | |
|
|
1318 | void |
1375 | void |
1319 | rxvt_term::check_our_parents_cb (time_watcher &w) |
1376 | rxvt_term::check_our_parents_cb (time_watcher &w) |
1320 | { |
1377 | { |
1321 | #if 0 /* replaced by a bgPixmap_t::render() - leve here temporarily for reference */ |
|
|
1322 | |
1378 | |
1323 | int i, aformat, rootdepth; |
1379 | int i, aformat, rootdepth; |
1324 | unsigned long nitems, bytes_after; |
1380 | unsigned long nitems, bytes_after; |
1325 | Atom atype; |
1381 | Atom atype; |
1326 | unsigned char *prop = NULL; |
1382 | unsigned char *prop = NULL; |
… | |
… | |
1524 | want_refresh = want_full_refresh = 1; |
1580 | want_refresh = want_full_refresh = 1; |
1525 | if (am_pixmap_trans) |
1581 | if (am_pixmap_trans) |
1526 | flush (); |
1582 | flush (); |
1527 | } |
1583 | } |
1528 | } |
1584 | } |
|
|
1585 | } |
1529 | #endif |
1586 | #endif |
1530 | } |
|
|
1531 | #endif |
|
|