… | |
… | |
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | *---------------------------------------------------------------------*/ |
24 | *---------------------------------------------------------------------*/ |
25 | |
25 | |
26 | #include "../config.h" /* NECESSARY */ |
26 | #include "../config.h" /* NECESSARY */ |
27 | #include "rxvt.h" /* NECESSARY */ |
27 | #include "rxvt.h" /* NECESSARY */ |
|
|
28 | |
|
|
29 | #define DO_TIMING_TEST 0 |
|
|
30 | |
|
|
31 | #if DO_TIMING_TEST |
|
|
32 | #define TIMING_TEST_START(id) \ |
|
|
33 | struct timeval timing_test_##id##_stv;\ |
|
|
34 | gettimeofday (&timing_test_##id##_stv, NULL); |
|
|
35 | |
|
|
36 | #define TIMING_TEST_PRINT_RESULT(id) \ |
|
|
37 | do{ struct timeval tv;gettimeofday (&tv, NULL); tv.tv_sec -= (timing_test_##id##_stv).tv_sec;\ |
|
|
38 | fprintf (stderr, "%s: %s: %d: elapsed %ld usec\n", #id, __FILE__, __LINE__,\ |
|
|
39 | tv.tv_sec * 1000000 + tv.tv_usec - (timing_test_##id##_stv).tv_usec);}while (0) |
|
|
40 | |
|
|
41 | #else |
|
|
42 | #define TIMING_TEST_START(id) do{}while (0) |
|
|
43 | #define TIMING_TEST_PRINT_RESULT(id) do{}while (0) |
|
|
44 | #endif |
28 | |
45 | |
29 | /* |
46 | /* |
30 | * Pixmap geometry string interpretation : |
47 | * Pixmap geometry string interpretation : |
31 | * Each geometry string contains zero or one scale/position |
48 | * Each geometry string contains zero or one scale/position |
32 | * adjustment and may optionally be followed by a colon and one or more |
49 | * adjustment and may optionally be followed by a colon and one or more |
… | |
… | |
376 | int x = 0; |
393 | int x = 0; |
377 | int y = 0; |
394 | int y = 0; |
378 | int w = h_scale * target_width / 100; |
395 | int w = h_scale * target_width / 100; |
379 | int h = v_scale * target_height / 100; |
396 | int h = v_scale * target_height / 100; |
380 | |
397 | |
|
|
398 | TIMING_TEST_START (asim); |
|
|
399 | |
381 | if (original_asim) |
400 | if (original_asim) |
382 | { |
401 | { |
383 | x = make_align_position (h_align, target_width, w > 0 ? w : (int)original_asim->width); |
402 | x = make_align_position (h_align, target_width, w > 0 ? w : (int)original_asim->width); |
384 | y = make_align_position (v_align, target_height, h > 0 ? h : (int)original_asim->height); |
403 | y = make_align_position (v_align, target_height, h > 0 ? h : (int)original_asim->height); |
385 | } |
404 | } |
… | |
… | |
489 | result = tmp; |
508 | result = tmp; |
490 | } |
509 | } |
491 | free (layers); |
510 | free (layers); |
492 | } |
511 | } |
493 | } |
512 | } |
|
|
513 | TIMING_TEST_PRINT_RESULT (asim); |
494 | |
514 | |
495 | if (pixmap) |
515 | if (pixmap) |
496 | { |
516 | { |
497 | if (result == NULL |
517 | if (result == NULL |
498 | || pmap_width != new_pmap_width |
518 | || pmap_width != new_pmap_width |
… | |
… | |
544 | |
564 | |
545 | if (result != background && result != original_asim) |
565 | if (result != background && result != original_asim) |
546 | destroy_asimage (&result); |
566 | destroy_asimage (&result); |
547 | |
567 | |
548 | XFreeGC (target->dpy, gc); |
568 | XFreeGC (target->dpy, gc); |
|
|
569 | TIMING_TEST_PRINT_RESULT (asim); |
549 | } |
570 | } |
550 | |
571 | |
551 | return true; |
572 | return true; |
552 | } |
573 | } |
553 | # endif /* HAVE_AFTERIMAGE */ |
574 | # endif /* HAVE_AFTERIMAGE */ |
… | |
… | |
625 | |
646 | |
626 | static inline unsigned long |
647 | static inline unsigned long |
627 | compute_tint_shade_flags (rxvt_color *tint, int shade) |
648 | compute_tint_shade_flags (rxvt_color *tint, int shade) |
628 | { |
649 | { |
629 | unsigned long flags = 0; |
650 | unsigned long flags = 0; |
|
|
651 | rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); |
630 | |
652 | |
631 | if (shade > 0 && shade <100) |
653 | if (tint) |
|
|
654 | { |
|
|
655 | tint->get (c); |
|
|
656 | # define IS_COMPONENT_WHOLESOME(cmp) ((cmp) <= 0x000700 || (cmp) >= 0x00f700) |
|
|
657 | if (IS_COMPONENT_WHOLESOME (c.r) |
|
|
658 | && IS_COMPONENT_WHOLESOME (c.g) |
|
|
659 | && IS_COMPONENT_WHOLESOME (c.b)) |
|
|
660 | flags |= bgPixmap_t::tintWholesome; |
|
|
661 | # undef IS_COMPONENT_WHOLESOME |
|
|
662 | } |
|
|
663 | |
|
|
664 | if ((shade > 0 && shade < 100) || (shade > 100 && shade < 200)) |
632 | flags |= bgPixmap_t::tintNeeded; |
665 | flags |= bgPixmap_t::tintNeeded; |
633 | else if (tint) |
666 | else if (tint) |
634 | { |
667 | { |
635 | rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); |
|
|
636 | tint->get (c); |
|
|
637 | |
|
|
638 | if ((c.r > 0x000700 || c.g > 0x000700 || c.b > 0x000700) |
668 | if ((c.r > 0x000700 || c.g > 0x000700 || c.b > 0x000700) |
639 | && (c.r < 0x00f700 || c.g < 0x00f700 || c.b < 0x00f700)) |
669 | && (c.r < 0x00f700 || c.g < 0x00f700 || c.b < 0x00f700)) |
640 | { |
670 | { |
641 | flags |= bgPixmap_t::tintNeeded; |
671 | flags |= bgPixmap_t::tintNeeded; |
642 | # define IS_COMPONENT_WHOLESOME(cmp) ((cmp) <= 0x000700 || (cmp) >= 0x00f700) |
|
|
643 | if (IS_COMPONENT_WHOLESOME (c.r) |
|
|
644 | && IS_COMPONENT_WHOLESOME (c.g) |
|
|
645 | && IS_COMPONENT_WHOLESOME (c.b)) |
|
|
646 | flags |= bgPixmap_t::tintServerSide; |
|
|
647 | # undef IS_COMPONENT_WHOLESOME |
|
|
648 | } |
672 | } |
649 | } |
673 | } |
|
|
674 | |
|
|
675 | if (flags & bgPixmap_t::tintNeeded) |
|
|
676 | { |
|
|
677 | if (flags & bgPixmap_t::tintWholesome) |
|
|
678 | flags |= bgPixmap_t::tintServerSide; |
|
|
679 | #if XFT |
|
|
680 | /* TODO: add logic for XRENDER tinting */ |
|
|
681 | flags |= bgPixmap_t::tintServerSide; |
|
|
682 | #endif |
|
|
683 | } |
|
|
684 | |
650 | return flags; |
685 | return flags; |
651 | } |
686 | } |
652 | |
687 | |
653 | bool |
688 | bool |
654 | bgPixmap_t::set_tint (rxvt_color &new_tint) |
689 | bgPixmap_t::set_tint (rxvt_color &new_tint) |
… | |
… | |
684 | if (new_shade == 100) |
719 | if (new_shade == 100) |
685 | new_shade = 0; |
720 | new_shade = 0; |
686 | |
721 | |
687 | if (new_shade != shade) |
722 | if (new_shade != shade) |
688 | { |
723 | { |
689 | unsigned long new_flags = compute_tint_shade_flags (&tint, new_shade); |
724 | unsigned long new_flags = compute_tint_shade_flags ((flags & tintSet) ? &tint : NULL, new_shade); |
690 | shade = new_shade; |
725 | shade = new_shade; |
691 | flags = (flags & ~tintFlags) | new_flags; |
726 | flags = (flags & ~tintFlags) | new_flags; |
692 | return true; |
727 | return true; |
693 | } |
728 | } |
694 | return false; |
729 | return false; |
… | |
… | |
720 | int window_width = target->szHint.width; |
755 | int window_width = target->szHint.width; |
721 | int window_height = target->szHint.height; |
756 | int window_height = target->szHint.height; |
722 | int sx, sy; |
757 | int sx, sy; |
723 | XGCValues gcv; |
758 | XGCValues gcv; |
724 | |
759 | |
|
|
760 | TIMING_TEST_START (tp); |
725 | target->get_window_origin (sx, sy); |
761 | target->get_window_origin (sx, sy); |
726 | |
762 | |
727 | /* check if we are outside of the visible part of the virtual screen : */ |
763 | /* check if we are outside of the visible part of the virtual screen : */ |
728 | if (sx + window_width <= 0 || sy + window_height <= 0 |
764 | if (sx + window_width <= 0 || sy + window_height <= 0 |
729 | || sx >= root_width || sy >= root_height) |
765 | || sx >= root_width || sy >= root_height) |
… | |
… | |
808 | { |
844 | { |
809 | XFillRectangle (dpy, tiled_root_pmap, gc, 0, 0, window_width, window_height); |
845 | XFillRectangle (dpy, tiled_root_pmap, gc, 0, 0, window_width, window_height); |
810 | result |= transpPmapTiled; |
846 | result |= transpPmapTiled; |
811 | } |
847 | } |
812 | } |
848 | } |
|
|
849 | TIMING_TEST_PRINT_RESULT (tp); |
813 | |
850 | |
814 | if (tiled_root_pmap != None) |
851 | if (tiled_root_pmap != None) |
815 | { |
852 | { |
816 | if (flags & tintNeeded && !need_client_side_rendering ()) |
853 | if ((flags & tintNeeded) && !need_client_side_rendering ()) |
|
|
854 | { |
|
|
855 | if (flags & tintWholesome) |
817 | { |
856 | { |
818 | /* In this case we can tint image server-side getting significant |
857 | /* In this case we can tint image server-side getting significant |
819 | * performance improvements, as we eliminate XImage transfer |
858 | * performance improvements, as we eliminate XImage transfer |
820 | */ |
859 | */ |
821 | gcv.foreground = Pixel (tint); |
860 | gcv.foreground = Pixel (tint); |
822 | gcv.function = GXand; |
861 | gcv.function = GXand; |
823 | gcv.fill_style = FillSolid; |
862 | gcv.fill_style = FillSolid; |
824 | if (gc) |
863 | if (gc) |
825 | XChangeGC (dpy, gc, GCFillStyle | GCForeground | GCFunction, &gcv); |
864 | XChangeGC (dpy, gc, GCFillStyle | GCForeground | GCFunction, &gcv); |
826 | else |
865 | else |
827 | gc = XCreateGC (dpy, root, GCFillStyle | GCForeground | GCFunction, &gcv); |
866 | gc = XCreateGC (dpy, root, GCFillStyle | GCForeground | GCFunction, &gcv); |
828 | if (gc) |
867 | if (gc) |
829 | { |
868 | { |
830 | XFillRectangle (dpy, tiled_root_pmap, gc, 0, 0, window_width, window_height); |
869 | XFillRectangle (dpy, tiled_root_pmap, gc, 0, 0, window_width, window_height); |
831 | result |= transpPmapTinted; |
870 | result |= transpPmapTinted; |
832 | } |
871 | } |
833 | } |
872 | } |
|
|
873 | else |
|
|
874 | { |
|
|
875 | #if XFT /* TODO : implement proper detection of XRENDER, as XFT may be present without XRENDER ! */ |
|
|
876 | rgba c (rgba::MAX_CC,rgba::MAX_CC,rgba::MAX_CC); |
|
|
877 | if (flags & tintSet) |
|
|
878 | tint.get (c); |
|
|
879 | if (shade > 0 && shade < 100) |
|
|
880 | { |
|
|
881 | c.r = (c.r * shade) / 100; |
|
|
882 | c.g = (c.g * shade) / 100; |
|
|
883 | c.b = (c.b * shade) / 100; |
|
|
884 | } |
|
|
885 | else if( shade > 100 && shade < 200) |
|
|
886 | { |
|
|
887 | c.r = (c.r * (200 - shade)) / 100; |
|
|
888 | c.g = (c.g * (200 - shade)) / 100; |
|
|
889 | c.b = (c.b * (200 - shade)) / 100; |
|
|
890 | } |
|
|
891 | |
|
|
892 | XRenderPictFormat pf; |
|
|
893 | pf.type = PictTypeDirect; |
|
|
894 | pf.depth = 32; |
|
|
895 | pf.direct.redMask = 0xff; |
|
|
896 | pf.direct.greenMask = 0xff; |
|
|
897 | pf.direct.blueMask = 0xff; |
|
|
898 | pf.direct.alphaMask = 0xff; |
|
|
899 | |
|
|
900 | XRenderPictFormat *solid_format = XRenderFindFormat (dpy, |
|
|
901 | (PictFormatType| |
|
|
902 | PictFormatDepth| |
|
|
903 | PictFormatRedMask| |
|
|
904 | PictFormatGreenMask| |
|
|
905 | PictFormatBlueMask| |
|
|
906 | PictFormatAlphaMask), |
|
|
907 | &pf, |
|
|
908 | 0); |
|
|
909 | XRenderPictFormat *root_format = XRenderFindVisualFormat (dpy, DefaultVisualOfScreen (ScreenOfDisplay (dpy, target->display->screen))); |
|
|
910 | XRenderPictureAttributes pa ; |
|
|
911 | |
|
|
912 | Picture back_pic = XRenderCreatePicture (dpy, tiled_root_pmap, root_format, 0, &pa); |
|
|
913 | |
|
|
914 | pa.repeat = True; |
|
|
915 | |
|
|
916 | Pixmap overlay_pmap = XCreatePixmap (dpy, root, 1, 1, 32); |
|
|
917 | Picture overlay_pic = XRenderCreatePicture (dpy, overlay_pmap, solid_format, CPRepeat, &pa); |
|
|
918 | XFreePixmap (dpy, overlay_pmap); |
|
|
919 | |
|
|
920 | pa.component_alpha = True; |
|
|
921 | Pixmap mask_pmap = XCreatePixmap (dpy, root, 1, 1, 32); |
|
|
922 | Picture mask_pic = XRenderCreatePicture (dpy, mask_pmap, solid_format, CPRepeat|CPComponentAlpha, &pa); |
|
|
923 | XFreePixmap (dpy, mask_pmap); |
|
|
924 | |
|
|
925 | if (mask_pic && overlay_pic && back_pic) |
|
|
926 | { |
|
|
927 | XRenderColor mask_c; |
|
|
928 | |
|
|
929 | memset (&mask_c, (shade > 100) ? 0xFF : 0x0, sizeof(mask_c)); |
|
|
930 | mask_c.alpha = 0xffff; |
|
|
931 | XRenderFillRectangle (dpy, PictOpSrc, overlay_pic, &mask_c, 0, 0, 1, 1); |
|
|
932 | memset (&mask_c, 0x0, sizeof(mask_c)); |
|
|
933 | mask_c.alpha = 0; |
|
|
934 | if (c.r == c.b && c.b == c.g) /* pure shading */ |
|
|
935 | { |
|
|
936 | mask_c.red = mask_c.green = mask_c.blue = 0xffff-c.r; |
|
|
937 | XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); |
|
|
938 | XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, window_width, window_height); |
|
|
939 | } |
|
|
940 | else |
|
|
941 | { |
|
|
942 | mask_c.red = 0xffff-c.r; |
|
|
943 | XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); |
|
|
944 | XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, window_width, window_height); |
|
|
945 | mask_c.red = 0; |
|
|
946 | mask_c.green = 0xffff-c.g; |
|
|
947 | XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); |
|
|
948 | XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, window_width, window_height); |
|
|
949 | mask_c.green = 0; |
|
|
950 | mask_c.blue = 0xffff-c.b; |
|
|
951 | XRenderFillRectangle (dpy, PictOpSrc, mask_pic, &mask_c, 0, 0, 1, 1); |
|
|
952 | XRenderComposite (dpy, PictOpOver, overlay_pic, mask_pic, back_pic, 0, 0, 0, 0, 0, 0, window_width, window_height); |
|
|
953 | } |
|
|
954 | result |= transpPmapTinted; |
|
|
955 | } |
|
|
956 | XRenderFreePicture (dpy, mask_pic); |
|
|
957 | XRenderFreePicture (dpy, overlay_pic); |
|
|
958 | XRenderFreePicture (dpy, back_pic); |
|
|
959 | #endif |
|
|
960 | } |
|
|
961 | } |
834 | if (pixmap) |
962 | if (pixmap) |
835 | XFreePixmap (dpy, pixmap); |
963 | XFreePixmap (dpy, pixmap); |
836 | pixmap = tiled_root_pmap; |
964 | pixmap = tiled_root_pmap; |
837 | pmap_width = window_width; |
965 | pmap_width = window_width; |
838 | pmap_height = window_height; |
966 | pmap_height = window_height; |
839 | pmap_depth = root_depth; |
967 | pmap_depth = root_depth; |
840 | } |
968 | } |
841 | |
969 | |
842 | if (gc) |
970 | if (gc) |
843 | XFreeGC (dpy, gc); |
971 | XFreeGC (dpy, gc); |
|
|
972 | |
|
|
973 | TIMING_TEST_PRINT_RESULT (tp); |
844 | |
974 | |
845 | return result; |
975 | return result; |
846 | } |
976 | } |
847 | |
977 | |
848 | bool |
978 | bool |
849 | bgPixmap_t::set_root_pixmap () |
979 | bgPixmap_t::set_root_pixmap () |
850 | { |
980 | { |
… | |
… | |
1155 | |
1285 | |
1156 | if (visual->c_class != TrueColor || srcImage->format != ZPixmap) return ; |
1286 | if (visual->c_class != TrueColor || srcImage->format != ZPixmap) return ; |
1157 | |
1287 | |
1158 | if (shade == 0) |
1288 | if (shade == 0) |
1159 | shade = 100; |
1289 | shade = 100; |
1160 | |
1290 | |
1161 | /* for convenience */ |
1291 | /* for convenience */ |
1162 | mask_r = visual->red_mask; |
1292 | mask_r = visual->red_mask; |
1163 | mask_g = visual->green_mask; |
1293 | mask_g = visual->green_mask; |
1164 | mask_b = visual->blue_mask; |
1294 | mask_b = visual->blue_mask; |
1165 | |
1295 | |
… | |
… | |
1387 | Window cr; |
1517 | Window cr; |
1388 | unsigned int rootpixmap_w = 0, rootpixmap_h = 0; |
1518 | unsigned int rootpixmap_w = 0, rootpixmap_h = 0; |
1389 | |
1519 | |
1390 | if (!option (Opt_transparent)) |
1520 | if (!option (Opt_transparent)) |
1391 | return; /* Don't try any more */ |
1521 | return; /* Don't try any more */ |
1392 | #if 0 |
|
|
1393 | struct timeval stv; |
|
|
1394 | gettimeofday (&stv,NULL); |
|
|
1395 | #define PRINT_BACKGROUND_OP_TIME do{ struct timeval tv;gettimeofday (&tv,NULL); tv.tv_sec-= stv.tv_sec;\ |
|
|
1396 | fprintf (stderr,"%d: elapsed %ld usec\n",__LINE__,\ |
|
|
1397 | tv.tv_sec*1000000+tv.tv_usec-stv.tv_usec );}while(0) |
|
|
1398 | #else |
|
|
1399 | #define PRINT_BACKGROUND_OP_TIME do{}while(0) |
|
|
1400 | #endif |
|
|
1401 | |
|
|
1402 | |
1522 | |
1403 | XGetWindowAttributes (dpy, display->root, &wrootattr); |
1523 | XGetWindowAttributes (dpy, display->root, &wrootattr); |
1404 | rootdepth = wrootattr.depth; |
1524 | rootdepth = wrootattr.depth; |
1405 | |
1525 | |
1406 | XGetWindowAttributes (dpy, parent[0], &wattr); |
1526 | XGetWindowAttributes (dpy, parent[0], &wattr); |
… | |
… | |
1540 | { |
1660 | { |
1541 | XImage *image = XGetImage (dpy, bgPixmap.pixmap, 0, 0, szHint.width, szHint.height, AllPlanes, ZPixmap); |
1661 | XImage *image = XGetImage (dpy, bgPixmap.pixmap, 0, 0, szHint.width, szHint.height, AllPlanes, ZPixmap); |
1542 | success = False; |
1662 | success = False; |
1543 | if (image != NULL) |
1663 | if (image != NULL) |
1544 | { |
1664 | { |
1545 | PRINT_BACKGROUND_OP_TIME; |
|
|
1546 | if (gc == NULL) |
1665 | if (gc == NULL) |
1547 | gc = XCreateGC (dpy, vt, 0UL, &gcvalue); |
1666 | gc = XCreateGC (dpy, vt, 0UL, &gcvalue); |
1548 | if (ISSET_PIXCOLOR (Color_tint) || shade != 100) |
1667 | if (ISSET_PIXCOLOR (Color_tint) || shade != 100) |
1549 | ShadeXImage (this, image, shade, c.r, c.g, c.b); |
1668 | ShadeXImage (this, image, shade, c.r, c.g, c.b); |
1550 | XPutImage (dpy, bgPixmap.pixmap, gc, image, 0, 0, 0, 0, image->width, image->height); |
1669 | XPutImage (dpy, bgPixmap.pixmap, gc, image, 0, 0, 0, 0, image->width, image->height); |
1551 | XDestroyImage (image); |
1670 | XDestroyImage (image); |
1552 | success = True; |
1671 | success = True; |
1553 | } |
1672 | } |
1554 | } |
1673 | } |
1555 | #endif /* HAVE_AFTERIMAGE */ |
1674 | #endif /* HAVE_AFTERIMAGE */ |
1556 | PRINT_BACKGROUND_OP_TIME; |
|
|
1557 | |
1675 | |
1558 | if (gc != NULL) |
1676 | if (gc != NULL) |
1559 | XFreeGC (dpy, gc); |
1677 | XFreeGC (dpy, gc); |
1560 | |
1678 | |
1561 | bgPixmap.apply(); |
1679 | bgPixmap.apply(); |