… | |
… | |
609 | /* make_transparency_pixmap() |
609 | /* make_transparency_pixmap() |
610 | * Builds a pixmap sized the same as terminal window, with depth same as the root window |
610 | * Builds a pixmap sized the same as terminal window, with depth same as the root window |
611 | * that pixmap contains tiled portion of the root pixmap that is supposed to be covered by |
611 | * that pixmap contains tiled portion of the root pixmap that is supposed to be covered by |
612 | * our window. |
612 | * our window. |
613 | */ |
613 | */ |
614 | #if 0 |
|
|
615 | bool |
614 | bool |
616 | bgPixmap_t::make_transparency_pixmap() |
615 | bgPixmap_t::make_transparency_pixmap() |
617 | { |
616 | { |
618 | if (target == NULL) |
617 | if (target == NULL) |
619 | return false; |
618 | return false; |
620 | |
619 | |
|
|
620 | /* root dimentions may change from call to call - but Display structure should |
|
|
621 | * be always up-to-date, so let's use it : |
|
|
622 | */ |
|
|
623 | Window root = target->display->root; |
|
|
624 | int screen = target->display->screen; |
|
|
625 | Display *dpy = target->dpy; |
|
|
626 | int root_width = DisplayWidth (dpy, screen); |
|
|
627 | int root_height = DisplayHeight (dpy, screen); |
|
|
628 | unsigned int root_pmap_width, root_pmap_height; |
|
|
629 | int window_width = target->szHint.width; |
|
|
630 | int window_height = target->szHint.height; |
621 | int sx, sy; |
631 | int sx, sy; |
622 | Window cr; |
|
|
623 | XTranslateCoordinates (target->dpy, target->parent[0], target->display->root, |
|
|
624 | 0, 0, &sx, &sy, &cr); |
|
|
625 | |
632 | |
|
|
633 | target->get_window_origin (sx, sy); |
|
|
634 | |
626 | /* check if we are outside of the visible part of the virtual screen : */ |
635 | /* check if we are outside of the visible part of the virtual screen : */ |
627 | if( sx + (int)szHint.width <= 0 || sy + (int)szHint.height <= 0 |
636 | if (sx + window_width <= 0 || sy + window_height <= 0 |
628 | || sx >= wrootattr.width || sy >= wrootattr.height ) |
637 | || sx >= root_width || sy >= root_height) |
629 | return false ; |
638 | return false; |
630 | |
|
|
631 | XWindowAttributes wattr, wrootattr; |
|
|
632 | |
639 | |
633 | XGetWindowAttributes (dpy, display->root, &wrootattr); |
640 | if (root_pixmap != None) |
634 | |
641 | {/* we want to validate the pixmap and get it's size at the same time : */ |
635 | /* |
642 | int junk; |
636 | * Make the frame window set by the window manager have |
643 | unsigned int ujunk; |
637 | * the root background. Some window managers put multiple nested frame |
644 | /* root pixmap may be bad - allow a error */ |
638 | * windows for each client, so we have to take care about that. |
645 | target->allowedxerror = -1; |
639 | */ |
646 | if (!XGetGeometry (dpy, root_pixmap, &root, &junk, &junk, &root_pmap_width, &root_pmap_height, &ujunk, &ujunk)) |
640 | i = (xa[XA_XROOTPMAP_ID] |
|
|
641 | && XGetWindowProperty (dpy, display->root, xa[XA_XROOTPMAP_ID], |
|
|
642 | 0L, 1L, False, XA_PIXMAP, &atype, &aformat, |
|
|
643 | &nitems, &bytes_after, &prop) == Success); |
|
|
644 | |
|
|
645 | if (!i || prop == NULL) |
|
|
646 | i = (xa[XA_ESETROOT_PMAP_ID] |
|
|
647 | && XGetWindowProperty (dpy, display->root, xa[XA_ESETROOT_PMAP_ID], |
|
|
648 | 0L, 1L, False, XA_PIXMAP, &atype, &aformat, |
|
|
649 | &nitems, &bytes_after, &prop) == Success); |
|
|
650 | |
|
|
651 | if (!i || prop == NULL) |
|
|
652 | rootpixmap = None; |
647 | root_pixmap = None; |
|
|
648 | target->allowedxerror = 0; |
|
|
649 | } |
653 | |
650 | |
|
|
651 | Pixmap tiled_root_pmap = XCreatePixmap (dpy, root, window_width, window_height, root_depth); |
|
|
652 | GC gc = NULL; |
|
|
653 | |
|
|
654 | if (tiled_root_pmap == None) /* something really bad happened - abort */ |
|
|
655 | return false; |
|
|
656 | |
|
|
657 | if (root_pixmap == None) |
|
|
658 | { /* use tricks to obtain the root background image :*/ |
|
|
659 | /* we want to create Overrideredirect window overlapping out window |
|
|
660 | with background type of Parent Relative and then grab it */ |
|
|
661 | XSetWindowAttributes attr; |
|
|
662 | Window src; |
|
|
663 | bool success = false; |
|
|
664 | |
|
|
665 | attr.background_pixmap = ParentRelative; |
|
|
666 | attr.backing_store = Always; |
|
|
667 | attr.event_mask = ExposureMask; |
|
|
668 | attr.override_redirect = True; |
|
|
669 | src = XCreateWindow (dpy, root, sx, sy, window_width, window_height, 0, |
|
|
670 | CopyFromParent, CopyFromParent, CopyFromParent, |
|
|
671 | CWBackPixmap|CWBackingStore|CWOverrideRedirect|CWEventMask, |
|
|
672 | &attr); |
|
|
673 | |
|
|
674 | if (src != None) |
|
|
675 | { |
|
|
676 | XEvent event; |
|
|
677 | int ev_count = 0; |
|
|
678 | XGrabServer (dpy); |
|
|
679 | XMapRaised (dpy, src); |
|
|
680 | XSync (dpy, False); |
|
|
681 | /* XSync should get window where it's properly exposed, |
|
|
682 | * but to be on the safe side - let's check for the actuall event to arrive : */ |
|
|
683 | while (XCheckWindowEvent (dpy, src, ExposureMask, &event)) |
|
|
684 | ++ev_count; |
|
|
685 | if (ev_count > 0); |
|
|
686 | { /* hooray! - we can grab the image! */ |
|
|
687 | gc = XCreateGC (dpy, root, 0, NULL); |
|
|
688 | XCopyArea (dpy, src, tiled_root_pmap, gc, 0, 0, window_width, window_height, 0, 0); |
|
|
689 | success = true; |
|
|
690 | } |
|
|
691 | XDestroyWindow (dpy, src); |
|
|
692 | XUngrabServer (dpy); |
|
|
693 | //fprintf (stderr, "%s:%d: ev_count = %d\n", __FUNCTION__, __LINE__, ev_count); |
|
|
694 | } |
|
|
695 | if (!success) |
|
|
696 | { |
|
|
697 | XFreePixmap (dpy, tiled_root_pmap); |
|
|
698 | tiled_root_pmap = None; |
|
|
699 | } |
|
|
700 | } |
|
|
701 | else |
|
|
702 | {/* strightforward pixmap copy */ |
|
|
703 | XGCValues gcv; |
|
|
704 | gcv.tile = root_pixmap; |
|
|
705 | gcv.fill_style = FillTiled; |
|
|
706 | while (sx < 0) sx += (int)window_width; |
|
|
707 | while (sy < 0) sy += (int)window_height; |
|
|
708 | gcv.ts_x_origin = -sx; |
|
|
709 | gcv.ts_y_origin = -sy; |
|
|
710 | gc = XCreateGC (dpy, root, GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin, &gcv); |
|
|
711 | XFillRectangle (dpy, tiled_root_pmap, gc, 0, 0, window_width, window_height); |
|
|
712 | } |
|
|
713 | |
|
|
714 | if (gc) |
|
|
715 | XFreeGC (dpy, gc); |
|
|
716 | |
|
|
717 | if (tiled_root_pmap != None) |
|
|
718 | { |
|
|
719 | if (pixmap) |
|
|
720 | XFreePixmap (dpy, pixmap); |
|
|
721 | pixmap = tiled_root_pmap; |
|
|
722 | pmap_width = window_width; |
|
|
723 | pmap_height = window_height; |
|
|
724 | pmap_depth = root_depth; |
|
|
725 | } |
654 | } |
726 | } |
655 | #endif /* 0 */ |
727 | |
656 | # endif /* ENABLE_TRANSPARENCY */ |
728 | # endif /* ENABLE_TRANSPARENCY */ |
|
|
729 | |
|
|
730 | bool |
|
|
731 | bgPixmap_t::set_target (rxvt_term *new_target) |
|
|
732 | { |
|
|
733 | if (new_target) |
|
|
734 | if (target != new_target) |
|
|
735 | { |
|
|
736 | target = new_target; |
|
|
737 | # ifdef ENABLE_TRANSPARENCY |
|
|
738 | root_depth = DefaultDepthOfScreen (ScreenOfDisplay (target->dpy, target->display->screen)); |
|
|
739 | root_pixmap = target->get_pixmap_property (XA_XROOTPMAP_ID); |
|
|
740 | if (root_pixmap == None) |
|
|
741 | root_pixmap = target->get_pixmap_property (XA_ESETROOT_PMAP_ID); |
|
|
742 | # endif |
|
|
743 | return true; |
|
|
744 | } |
|
|
745 | return false; |
|
|
746 | } |
657 | |
747 | |
658 | void |
748 | void |
659 | bgPixmap_t::apply_background() |
749 | bgPixmap_t::apply_background() |
660 | { |
750 | { |
661 | if (target) |
751 | if (target) |
… | |
… | |
691 | XClearArea (target->dpy, target->parent[0], 0, 0, 0, 0, True); |
781 | XClearArea (target->dpy, target->parent[0], 0, 0, 0, 0, True); |
692 | } |
782 | } |
693 | } |
783 | } |
694 | #endif /* HAVE_BG_PIXMAP */ |
784 | #endif /* HAVE_BG_PIXMAP */ |
695 | |
785 | |
|
|
786 | |
|
|
787 | void |
|
|
788 | rxvt_term::get_window_origin (int &x, int &y) |
|
|
789 | { |
|
|
790 | Window cr; |
|
|
791 | XTranslateCoordinates (dpy, parent[0], display->root, 0, 0, &x, &y, &cr); |
|
|
792 | } |
|
|
793 | |
|
|
794 | Pixmap |
|
|
795 | rxvt_term::get_pixmap_property (int prop_id) |
|
|
796 | { |
|
|
797 | if (prop_id > 0 && prop_id < NUM_XA) |
|
|
798 | if (xa[prop_id]) |
|
|
799 | { |
|
|
800 | int aformat, rootdepth; |
|
|
801 | unsigned long nitems, bytes_after; |
|
|
802 | Atom atype; |
|
|
803 | unsigned char *prop = NULL; |
|
|
804 | int result = XGetWindowProperty (dpy, display->root, xa[prop_id], |
|
|
805 | 0L, 1L, False, XA_PIXMAP, &atype, &aformat, |
|
|
806 | &nitems, &bytes_after, &prop); |
|
|
807 | if (result == Success && prop && atype == XA_PIXMAP) |
|
|
808 | { |
|
|
809 | return *(Pixmap *)prop; |
|
|
810 | } |
|
|
811 | } |
|
|
812 | return None; |
|
|
813 | } |
696 | |
814 | |
697 | |
815 | |
698 | #ifdef ENABLE_TRANSPARENCY |
816 | #ifdef ENABLE_TRANSPARENCY |
699 | #ifndef HAVE_AFTERIMAGE |
817 | #ifndef HAVE_AFTERIMAGE |
700 | /* taken from aterm-0.4.2 */ |
818 | /* taken from aterm-0.4.2 */ |
… | |
… | |
954 | Window cr; |
1072 | Window cr; |
955 | unsigned int rootpixmap_w = 0, rootpixmap_h = 0; |
1073 | unsigned int rootpixmap_w = 0, rootpixmap_h = 0; |
956 | |
1074 | |
957 | if (!option (Opt_transparent)) |
1075 | if (!option (Opt_transparent)) |
958 | return; /* Don't try any more */ |
1076 | return; /* Don't try any more */ |
959 | |
|
|
960 | #if 0 |
1077 | #if 0 |
961 | struct timeval stv; |
1078 | struct timeval stv; |
962 | gettimeofday (&stv,NULL); |
1079 | gettimeofday (&stv,NULL); |
963 | #define PRINT_BACKGROUND_OP_TIME do{ struct timeval tv;gettimeofday (&tv,NULL); tv.tv_sec-= stv.tv_sec;\ |
1080 | #define PRINT_BACKGROUND_OP_TIME do{ struct timeval tv;gettimeofday (&tv,NULL); tv.tv_sec-= stv.tv_sec;\ |
964 | fprintf (stderr,"%d: elapsed %ld usec\n",__LINE__,\ |
1081 | fprintf (stderr,"%d: elapsed %ld usec\n",__LINE__,\ |
… | |
… | |
1047 | whole_tint = (IS_COMPONENT_WHOLESOME(c.r) |
1164 | whole_tint = (IS_COMPONENT_WHOLESOME(c.r) |
1048 | && IS_COMPONENT_WHOLESOME(c.g) |
1165 | && IS_COMPONENT_WHOLESOME(c.g) |
1049 | && IS_COMPONENT_WHOLESOME(c.b)); |
1166 | && IS_COMPONENT_WHOLESOME(c.b)); |
1050 | no_tint = (c.r >= 0x00f700 && c.g >= 0x00f700 && c.b >= 0x00f700); |
1167 | no_tint = (c.r >= 0x00f700 && c.g >= 0x00f700 && c.b >= 0x00f700); |
1051 | #undef IS_COMPONENT_WHOLESOME |
1168 | #undef IS_COMPONENT_WHOLESOME |
1052 | /* theer are no performance advantages to reusing same pixmap */ |
|
|
1053 | if (bgPixmap.pixmap != None) |
|
|
1054 | XFreePixmap (dpy, bgPixmap.pixmap); |
|
|
1055 | bgPixmap.pixmap = XCreatePixmap (dpy, vt, szHint.width, szHint.height, rootdepth); |
|
|
1056 | bgPixmap.pmap_width = szHint.width; |
|
|
1057 | bgPixmap.pmap_height = szHint.height; |
|
|
1058 | bgPixmap.pmap_depth = rootdepth; |
|
|
1059 | |
1169 | |
1060 | #if 0 /* TODO : identify cases where this will be detrimental to performance : */ |
1170 | bgPixmap.make_transparency_pixmap(); |
1061 | /* we want to tile root pixmap into our own pixmap in this cases : |
|
|
1062 | * 1) rootpixmap does not cover our window entirely |
|
|
1063 | * 2) whole_tint - we can use server-side tinting or tinting disabled |
|
|
1064 | */ |
|
|
1065 | if ( whole_tint || no_tint || pmap_w < sx + szHint.width || pmap_h < sy + szHint.height) |
|
|
1066 | { |
|
|
1067 | } |
|
|
1068 | #endif |
|
|
1069 | gcvalue.tile = rootpixmap; |
|
|
1070 | gcvalue.fill_style = FillTiled; |
|
|
1071 | gcvalue.ts_x_origin = -sx; |
|
|
1072 | gcvalue.ts_y_origin = -sy; |
|
|
1073 | gc = XCreateGC (dpy, rootpixmap, GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin, &gcvalue); |
|
|
1074 | XFillRectangle (dpy, bgPixmap.pixmap, gc, 0, 0, szHint.width, szHint.height); |
|
|
1075 | |
1171 | |
1076 | if (whole_tint && !no_tint) |
1172 | if (whole_tint && !no_tint) |
1077 | { |
1173 | { |
1078 | /* In this case we can tint image server-side getting significant |
1174 | /* In this case we can tint image server-side getting significant |
1079 | * performance improvements, as we eliminate XImage transfer |
1175 | * performance improvements, as we eliminate XImage transfer |
1080 | */ |
1176 | */ |
1081 | gcvalue.foreground = Pixel (pix_colors_focused [Color_tint]); |
1177 | gcvalue.foreground = Pixel (pix_colors_focused [Color_tint]); |
1082 | gcvalue.function = GXand; |
1178 | gcvalue.function = GXand; |
1083 | gcvalue.fill_style = FillSolid; |
1179 | gcvalue.fill_style = FillSolid; |
|
|
1180 | if (gc) |
1084 | XChangeGC (dpy, gc, GCFillStyle | GCForeground | GCFunction, &gcvalue); |
1181 | XChangeGC (dpy, gc, GCFillStyle | GCForeground | GCFunction, &gcvalue); |
|
|
1182 | else |
|
|
1183 | gc = XCreateGC (dpy, root, GCFillStyle | GCForeground | GCFunction, &gcvalue); |
1085 | XFillRectangle (dpy, bgPixmap.pixmap, gc, 0, 0, szHint.width, szHint.height); |
1184 | XFillRectangle (dpy, bgPixmap.pixmap, gc, 0, 0, szHint.width, szHint.height); |
1086 | } |
1185 | } |
1087 | success = True; |
1186 | success = True; |
1088 | #ifdef HAVE_AFTERIMAGE |
1187 | #ifdef HAVE_AFTERIMAGE |
1089 | if (rs[Rs_blurradius] || bgPixmap.original_asim != NULL || (!whole_tint && (!no_tint || shade !=100))) |
1188 | if (rs[Rs_blurradius] || bgPixmap.original_asim != NULL || (!whole_tint && (!no_tint || shade !=100))) |