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

Comparing rxvt-unicode/src/rxvttoolkit.C (file contents):
Revision 1.32 by root, Sun Jan 29 22:30:21 2006 UTC vs.
Revision 1.45 by root, Wed Feb 1 01:58:47 2006 UTC

37#if XFT 37#if XFT
38# include <X11/extensions/Xrender.h> 38# include <X11/extensions/Xrender.h>
39#endif 39#endif
40 40
41const char *const xa_names[] = 41const char *const xa_names[] =
42 { 42{
43 "TEXT", 43 "TEXT",
44 "COMPOUND_TEXT", 44 "COMPOUND_TEXT",
45 "UTF8_STRING", 45 "UTF8_STRING",
46 "MULTIPLE", 46 "MULTIPLE",
47 "TARGETS", 47 "TARGETS",
48 "TIMESTAMP", 48 "TIMESTAMP",
49 "VT_SELECTION", 49 "VT_SELECTION",
50 "INCR", 50 "INCR",
51 "WM_PROTOCOLS", 51 "WM_PROTOCOLS",
52 "WM_DELETE_WINDOW", 52 "WM_DELETE_WINDOW",
53 "CLIPBOARD", 53 "CLIPBOARD",
54 "AVERAGE_WIDTH",
55 "WEIGHT_NAME",
56 "SLANT",
57 "CHARSET_REGISTRY",
58 "CHARSET_ENCODING",
54#if ENABLE_FRILLS 59#if ENABLE_FRILLS
55 "_MOTIF_WM_HINTS", 60 "_MOTIF_WM_HINTS",
56#endif 61#endif
57#if ENABLE_EWMH 62#if ENABLE_EWMH
58 "_NET_WM_PID", 63 "_NET_WM_PID",
59 "_NET_WM_NAME", 64 "_NET_WM_NAME",
60 "_NET_WM_ICON_NAME", 65 "_NET_WM_ICON_NAME",
61 "_NET_WM_PING", 66 "_NET_WM_PING",
62#endif 67#endif
63#if USE_XIM 68#if USE_XIM
64 "WM_LOCALE_NAME", 69 "WM_LOCALE_NAME",
65 "XIM_SERVERS", 70 "XIM_SERVERS",
66#endif 71#endif
67#ifdef TRANSPARENT 72#ifdef TRANSPARENT
68 "_XROOTPMAP_ID", 73 "_XROOTPMAP_ID",
69 "ESETROOT_PMAP_ID", 74 "ESETROOT_PMAP_ID",
70#endif 75#endif
71#if ENABLE_XEMBED 76#if ENABLE_XEMBED
72 "_XEMBED", 77 "_XEMBED",
73 "_XEMBED_INFO", 78 "_XEMBED_INFO",
79#endif
80#if !ENABLE_MINIMAL
81 "SCREEN_RESOURCES",
82 "XDCCC_LINEAR_RGB_CORRECTION",
83 "XDCCC_LINEAR_RGB_MATRICES",
84 "WM_COLORMAP_WINDOWS",
85 "WM_STATE",
86 "cursor",
87# if USE_XIM
88 "TRANSPORT",
89 "LOCALES",
90 "_XIM_PROTOCOL",
91 "_XIM_XCONNECT",
92 "_XIM_MOREDATA",
74#endif 93# endif
75 }; 94#endif
95};
76 96
77///////////////////////////////////////////////////////////////////////////// 97/////////////////////////////////////////////////////////////////////////////
78 98
79refcounted::refcounted (const char *id) 99refcounted::refcounted (const char *id)
80{ 100{
538 558
539template class refcache<rxvt_display>; 559template class refcache<rxvt_display>;
540refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
541 561
542///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
543 563
544bool 564bool
545rxvt_color::set (rxvt_screen *screen, const char *name) 565rxvt_color::alloc (rxvt_screen *screen, const rgba &color)
546{
547#if XFT
548 int l = strlen (name);
549 rxvt_rgba r;
550 char eos;
551 int mult;
552
553 if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
554 mult = rxvt_rgba::MAX_CC / 0x000f;
555 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
556 mult = rxvt_rgba::MAX_CC / 0x00ff;
557 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
558 mult = rxvt_rgba::MAX_CC / 0xffff;
559 else if (l == 4+5*4 && 4 == sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
560 mult = rxvt_rgba::MAX_CC / 0xffff;
561 else
562 return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c);
563
564 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult;
565 return set (screen, r);
566#else
567 XColor xc;
568
569 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
570 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue));
571
572 return false;
573#endif
574}
575
576bool
577rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
578{ 566{
579#if XFT 567#if XFT
580 XRenderPictFormat *format; 568 XRenderPictFormat *format;
581 569
582 // FUCKING Xft gets it wrong, of course, so work around it 570 // FUCKING Xft gets it wrong, of course, so work around it
583 // transparency users should eat shit and die, and then 571 // transparency users should eat shit and die, and then
584 // XRenderQueryPictIndexValues themselves plenty. 572 // XRenderQueryPictIndexValues themselves plenty.
585 if (screen->visual->c_class == TrueColor 573 if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
586 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual))) 574 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
587 { 575 {
588 // the fun lies in doing everything manually... 576 // the fun lies in doing everything manually...
589 c.color.red = rgba.r; 577 c.color.red = color.r;
590 c.color.green = rgba.g; 578 c.color.green = color.g;
591 c.color.blue = rgba.b; 579 c.color.blue = color.b;
592 c.color.alpha = rgba.a; 580 c.color.alpha = color.a;
593 581
594 c.pixel = ((rgba.r * format->direct.redMask / rxvt_rgba::MAX_CC) << format->direct.red) 582 c.pixel = ((color.r * format->direct.redMask / rgba::MAX_CC) << format->direct.red )
595 | ((rgba.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green) 583 | ((color.g * format->direct.greenMask / rgba::MAX_CC) << format->direct.green)
596 | ((rgba.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue) 584 | ((color.b * format->direct.blueMask / rgba::MAX_CC) << format->direct.blue )
597 | ((rgba.a * format->direct.alphaMask / rxvt_rgba::MAX_CC) << format->direct.alpha); 585 | ((color.a * format->direct.alphaMask / rgba::MAX_CC) << format->direct.alpha);
598 586
599 return true; 587 return true;
600 } 588 }
601 else 589 else
602 { 590 {
603 XRenderColor d; 591 XRenderColor d;
604 592
605 d.red = rgba.r; 593 d.red = color.r;
606 d.green = rgba.g; 594 d.green = color.g;
607 d.blue = rgba.b; 595 d.blue = color.b;
608 d.alpha = rgba.a; 596 d.alpha = color.a;
609 597
610 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c); 598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
611 } 599 }
600#else
601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
602 {
603 c.red = color.g;
604 c.green = color.g;
605 c.blue = color.g;
606 c.pixel = (color.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask ))
607 / rgba::MAX_CC) << ctz (screen->visual->red_mask )
608 | (color.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask))
609 / rgba::MAX_CC) << ctz (screen->visual->green_mask)
610 | (color.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask ))
611 / rgba::MAX_CC) << ctz (screen->visual->blue_mask );
612
613 return true;
614 }
615 else
616 {
617 c.red = color.r;
618 c.green = color.g;
619 c.blue = color.b;
620
621 if (XAllocColor (screen->xdisp, screen->cmap, &c))
622 return true;
623 else
624 c.pixel = (color.r + color.g + color.b) > 128*3
625 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->xdisp))
626 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->xdisp));
627 }
628#endif
612 629
613 return false; 630 return false;
631}
632
633bool
634rxvt_color::set (rxvt_screen *screen, const char *name)
635{
636 rgba c;
637 char eos;
638 int skip;
639
640 if (1 <= sscanf (name, "[%hd]%n", &c.a, &skip))
641 {
642 c.a = lerp<int, int, int> (0, rgba::MAX_CC, c.a);
643 name += skip;
644 }
645 else
646 c.a = rgba::MAX_CC;
647
648 // parse the non-standard rgba format
649 if (strlen (name) != 4+5*4 || 4 != sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &c.r, &c.g, &c.b, &c.a, &eos))
650 {
651 XColor xc, xc_exact;
652
653 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
654 {
655 c.r = xc.red;
656 c.g = xc.green;
657 c.b = xc.blue;
658 }
659 else
660 {
661 c.r = 0xffff;
662 c.g = 0x6969;
663 c.b = 0xb4b4;
664
665 rxvt_warn ("unable to parse color '%s', using pink instead.\n", name);
666 }
667 }
668
669 return set (screen, c);
670}
671
672bool
673rxvt_color::set (rxvt_screen *screen, const rgba &color)
674{
675 bool got = alloc (screen, color);
676
677#if !ENABLE_MINIMAL
678 int cmap_size = screen->visual->map_entries;
679
680 if (!got
681 && screen->visual->c_class == PseudoColor
682 && cmap_size < 4096)
683 {
684 XColor *colors = new XColor [screen->visual->map_entries];
685
686 for (int i = 0; i < cmap_size; i++)
687 colors [i].pixel = i;
688
689 // many kilobytes transfer per colour, but pseudocolor isn't worth
690 // many extra optimisations.
691 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
692
693 int diff = 0x7fffffffUL;
694 XColor *best = colors;
695
696 for (int i = 0; i < cmap_size; i++)
697 {
698 int d = (squared_diff<int> (color.r >> 2, colors [i].red >> 2))
699 + (squared_diff<int> (color.g >> 2, colors [i].green >> 2))
700 + (squared_diff<int> (color.b >> 2, colors [i].blue >> 2));
701
702 if (d < diff)
703 {
704 diff = d;
705 best = colors + i;
706 }
707 }
708
709 //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n",
710 // color.r, color.g, color.b, best->red, best->green, best->blue, diff);
711
712 got = alloc (screen, rgba (best->red, best->green, best->blue));
713
714 delete colors;
715 }
716#endif
717
718 return got;
719}
720
721void
722rxvt_color::get (rgba &color)
723{
724#if XFT
725 color.r = c.color.red;
726 color.g = c.color.green;
727 color.b = c.color.blue;
728 color.a = c.color.alpha;
614#else 729#else
615 XColor xc;
616
617 xc.red = rgba.r;
618 xc.green = rgba.g;
619 xc.blue = rgba.b;
620 xc.flags = DoRed | DoGreen | DoBlue;
621
622 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
623 {
624 p = xc.pixel;
625 return true;
626 }
627
628 return false;
629#endif
630}
631
632void
633rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba)
634{
635#if XFT
636 rgba.r = c.color.red;
637 rgba.g = c.color.green;
638 rgba.b = c.color.blue;
639 rgba.a = c.color.alpha;
640#else
641 XColor c;
642
643 c.pixel = p;
644 XQueryColor (screen->xdisp, screen->cmap, &c);
645
646 rgba.r = c.red; 730 color.r = c.red;
647 rgba.g = c.green; 731 color.g = c.green;
648 rgba.b = c.blue; 732 color.b = c.blue;
649 rgba.a = rxvt_rgba::MAX_CC; 733 color.a = rgba::MAX_CC;
650#endif 734#endif
651} 735}
652 736
653void 737void
654rxvt_color::free (rxvt_screen *screen) 738rxvt_color::free (rxvt_screen *screen)
655{ 739{
656#if XFT 740#if XFT
657 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 741 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
658#else 742#else
659 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 743 XFreeColors (screen->xdisp, screen->cmap, &c.pixel, 1, AllPlanes);
660#endif 744#endif
661} 745}
662 746
663rxvt_color 747void
664rxvt_color::fade (rxvt_screen *screen, int percent)
665{
666 rxvt_color faded;
667
668 rxvt_rgba c;
669 get (screen, c);
670
671 c.r = lerp (0, c.r, percent);
672 c.g = lerp (0, c.g, percent);
673 c.b = lerp (0, c.b, percent);
674
675 faded.set (screen, c);
676
677 return faded;
678}
679
680rxvt_color
681rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto) 748rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
682{ 749{
683 rxvt_rgba c, fc; 750 rgba c;
684 rxvt_color faded; 751 get (c);
685
686 get (screen, c);
687 fadeto.get (screen, fc);
688 752
689 faded.set ( 753 result.set (
690 screen, 754 screen,
691 rxvt_rgba ( 755 rgba (
692 lerp (fc.r, c.r, percent), 756 lerp (c.r, to.r, percent),
693 lerp (fc.g, c.g, percent), 757 lerp (c.g, to.g, percent),
694 lerp (fc.b, c.b, percent), 758 lerp (c.b, to.b, percent),
695 lerp (fc.a, c.a, percent) 759 lerp (c.a, to.a, percent)
696 ) 760 )
697 ); 761 );
698
699 return faded;
700} 762}
701 763

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines