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.34 by root, Mon Jan 30 02:21:20 2006 UTC vs.
Revision 1.44 by root, Tue Jan 31 19:53:31 2006 UTC

81 "SCREEN_RESOURCES", 81 "SCREEN_RESOURCES",
82 "XDCCC_LINEAR_RGB_CORRECTION", 82 "XDCCC_LINEAR_RGB_CORRECTION",
83 "XDCCC_LINEAR_RGB_MATRICES", 83 "XDCCC_LINEAR_RGB_MATRICES",
84 "WM_COLORMAP_WINDOWS", 84 "WM_COLORMAP_WINDOWS",
85 "WM_STATE", 85 "WM_STATE",
86 "cursor",
87# if USE_XIM
88 "TRANSPORT",
89 "LOCALES",
90 "_XIM_PROTOCOL",
91 "_XIM_XCONNECT",
92 "_XIM_MOREDATA",
93# endif
86#endif 94#endif
87}; 95};
88 96
89///////////////////////////////////////////////////////////////////////////// 97/////////////////////////////////////////////////////////////////////////////
90 98
550 558
551template class refcache<rxvt_display>; 559template class refcache<rxvt_display>;
552refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
553 561
554///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
555 563
556bool 564bool
557rxvt_color::set (rxvt_screen *screen, const char *name) 565rxvt_color::alloc (rxvt_screen *screen, const rgba &color)
558{
559#if XFT
560 int l = strlen (name);
561 rxvt_rgba r;
562 char eos;
563 int mult;
564
565 // shortcutting this saves countless server RTTs for the built-in colours
566 if (l == 3+3*3 && 3 == sscanf (name, "rgb:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
567 {
568 r.a = rxvt_rgba::MAX_CC;
569 mult = rxvt_rgba::MAX_CC / 0x00ff;
570 }
571
572 // parse a number of non-standard ARGB colour specifications
573 else if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
574 mult = rxvt_rgba::MAX_CC / 0x000f;
575 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
576 mult = rxvt_rgba::MAX_CC / 0x00ff;
577 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
578 mult = rxvt_rgba::MAX_CC / 0xffff;
579 else if (l == 4+5*4 && 4 == sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
580 mult = rxvt_rgba::MAX_CC / 0xffff;
581
582 // slow case: server round trip
583 else
584 return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c);
585
586 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult;
587
588 return set (screen, r);
589#else
590 XColor xc;
591
592 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
593 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue));
594
595 return false;
596#endif
597}
598
599bool
600rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
601{ 566{
602#if XFT 567#if XFT
603 XRenderPictFormat *format; 568 XRenderPictFormat *format;
604 569
605 // FUCKING Xft gets it wrong, of course, so work around it 570 // FUCKING Xft gets it wrong, of course, so work around it
606 // transparency users should eat shit and die, and then 571 // transparency users should eat shit and die, and then
607 // XRenderQueryPictIndexValues themselves plenty. 572 // XRenderQueryPictIndexValues themselves plenty.
608 if (screen->visual->c_class == TrueColor 573 if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
609 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual))) 574 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
610 { 575 {
611 // the fun lies in doing everything manually... 576 // the fun lies in doing everything manually...
612 c.color.red = rgba.r; 577 c.color.red = color.r;
613 c.color.green = rgba.g; 578 c.color.green = color.g;
614 c.color.blue = rgba.b; 579 c.color.blue = color.b;
615 c.color.alpha = rgba.a; 580 c.color.alpha = color.a;
616 581
617 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 )
618 | ((rgba.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green) 583 | ((color.g * format->direct.greenMask / rgba::MAX_CC) << format->direct.green)
619 | ((rgba.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue ) 584 | ((color.b * format->direct.blueMask / rgba::MAX_CC) << format->direct.blue )
620 | ((rgba.a * format->direct.alphaMask / rxvt_rgba::MAX_CC) << format->direct.alpha); 585 | ((color.a * format->direct.alphaMask / rgba::MAX_CC) << format->direct.alpha);
621 586
622 return true; 587 return true;
623 } 588 }
624 else 589 else
625 { 590 {
626 XRenderColor d; 591 XRenderColor d;
627 592
628 d.red = rgba.r; 593 d.red = color.r;
629 d.green = rgba.g; 594 d.green = color.g;
630 d.blue = rgba.b; 595 d.blue = color.b;
631 d.alpha = rgba.a; 596 d.alpha = color.a;
632 597
633 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c); 598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
634 } 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
635 629
636 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 printf ("X %d\n", c.a);
643 c.a = lerp<int, int, int> (0, rgba::MAX_CC, c.a);
644 name += skip;
645 printf ("y %04x\n", c.a);
646 }
647 else
648 c.a = rgba::MAX_CC;
649
650 // parse the non-standard rgba format
651 if (strlen (name) != 4+5*4 || 4 != sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &c.r, &c.g, &c.b, &c.a, &eos))
652 {
653 XColor xc, xc_exact;
654
655 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
656 {
657 c.r = xc.red;
658 c.g = xc.green;
659 c.b = xc.blue;
660 }
661 else
662 {
663 c.r = 0xffff;
664 c.g = 0x6969;
665 c.b = 0xb4b4;
666
667 rxvt_warn ("unable to parse color '%s', using pink instead.\n", name);
668 }
669 }
670
671 return set (screen, c);
672}
673
674bool
675rxvt_color::set (rxvt_screen *screen, const rgba &color)
676{
677 bool got = alloc (screen, color);
678
679#if !ENABLE_MINIMAL
680 int cmap_size = screen->visual->map_entries;
681
682 if (!got
683 && screen->visual->c_class == PseudoColor
684 && cmap_size < 4096)
685 {
686 XColor *colors = new XColor [screen->visual->map_entries];
687
688 for (int i = 0; i < cmap_size; i++)
689 colors [i].pixel = i;
690
691 // many kilobytes transfer per colour, but pseudocolor isn't worth
692 // many extra optimisations.
693 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
694
695 int diff = 0x7fffffffUL;
696 XColor *best = colors;
697
698 for (int i = 0; i < cmap_size; i++)
699 {
700 int d = (squared_diff<int> (color.r >> 2, colors [i].red >> 2))
701 + (squared_diff<int> (color.g >> 2, colors [i].green >> 2))
702 + (squared_diff<int> (color.b >> 2, colors [i].blue >> 2));
703
704 if (d < diff)
705 {
706 diff = d;
707 best = colors + i;
708 }
709 }
710
711 //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n",
712 // color.r, color.g, color.b, best->red, best->green, best->blue, diff);
713
714 got = alloc (screen, rgba (best->red, best->green, best->blue));
715
716 delete colors;
717 }
718#endif
719
720 return got;
721}
722
723void
724rxvt_color::get (rgba &color)
725{
726#if XFT
727 color.r = c.color.red;
728 color.g = c.color.green;
729 color.b = c.color.blue;
730 color.a = c.color.alpha;
637#else 731#else
638 XColor xc;
639
640 xc.red = rgba.r;
641 xc.green = rgba.g;
642 xc.blue = rgba.b;
643 xc.flags = DoRed | DoGreen | DoBlue;
644
645 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
646 {
647 p = xc.pixel;
648 return true;
649 }
650
651 return false;
652#endif
653}
654
655void
656rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba)
657{
658#if XFT
659 rgba.r = c.color.red;
660 rgba.g = c.color.green;
661 rgba.b = c.color.blue;
662 rgba.a = c.color.alpha;
663#else
664 XColor c;
665
666 c.pixel = p;
667 XQueryColor (screen->xdisp, screen->cmap, &c);
668
669 rgba.r = c.red; 732 color.r = c.red;
670 rgba.g = c.green; 733 color.g = c.green;
671 rgba.b = c.blue; 734 color.b = c.blue;
672 rgba.a = rxvt_rgba::MAX_CC; 735 color.a = rgba::MAX_CC;
673#endif 736#endif
674} 737}
675 738
676void 739void
677rxvt_color::free (rxvt_screen *screen) 740rxvt_color::free (rxvt_screen *screen)
678{ 741{
679#if XFT 742#if XFT
680 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 743 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
681#else 744#else
682 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 745 XFreeColors (screen->xdisp, screen->cmap, &c.pixel, 1, AllPlanes);
683#endif 746#endif
684} 747}
685 748
686rxvt_color 749void
687rxvt_color::fade (rxvt_screen *screen, int percent)
688{
689 rxvt_color faded;
690
691 rxvt_rgba c;
692 get (screen, c);
693
694 c.r = lerp (0, c.r, percent);
695 c.g = lerp (0, c.g, percent);
696 c.b = lerp (0, c.b, percent);
697
698 faded.set (screen, c);
699
700 return faded;
701}
702
703rxvt_color
704rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto) 750rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
705{ 751{
706 rxvt_rgba c, fc; 752 rgba c;
707 rxvt_color faded; 753 get (c);
708
709 get (screen, c);
710 fadeto.get (screen, fc);
711 754
712 faded.set ( 755 result.set (
713 screen, 756 screen,
714 rxvt_rgba ( 757 rgba (
715 lerp (fc.r, c.r, percent), 758 lerp (c.r, to.r, percent),
716 lerp (fc.g, c.g, percent), 759 lerp (c.g, to.g, percent),
717 lerp (fc.b, c.b, percent), 760 lerp (c.b, to.b, percent),
718 lerp (fc.a, c.a, percent) 761 lerp (c.a, to.a, percent)
719 ) 762 )
720 ); 763 );
721
722 return faded;
723} 764}
724 765

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines