ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/xpm.C
(Generate patch)

Comparing rxvt-unicode/src/xpm.C (file contents):
Revision 1.63 by sasha, Wed Aug 8 22:39:49 2007 UTC vs.
Revision 1.64 by sasha, Thu Aug 9 22:08:21 2007 UTC

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
615bool 614bool
616bgPixmap_t::make_transparency_pixmap() 615bgPixmap_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
730bool
731bgPixmap_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
658void 748void
659bgPixmap_t::apply_background() 749bgPixmap_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
787void
788rxvt_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
794Pixmap
795rxvt_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)))

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines