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.42 by root, Tue Jan 31 16:57:35 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)
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) 565rxvt_color::alloc (rxvt_screen *screen, const rxvt_rgba &color)
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 / rxvt_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 / rxvt_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 / rxvt_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 / rxvt_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 p = (color.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask ))
604 / rxvt_rgba::MAX_CC) << ctz (screen->visual->red_mask )
605 | (color.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask))
606 / rxvt_rgba::MAX_CC) << ctz (screen->visual->green_mask)
607 | (color.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask ))
608 / rxvt_rgba::MAX_CC) << ctz (screen->visual->blue_mask );
609
610 return true;
611 }
612 else
613 {
614 XColor xc;
615
616 xc.red = color.r;
617 xc.green = color.g;
618 xc.blue = color.b;
619
620 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
621 {
622 p = xc.pixel;
623 return true;
624 }
625 else
626 p = (color.r + color.g + color.b) > 128*3
627 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->xdisp))
628 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->xdisp));
629 }
630#endif
635 631
636 return false; 632 return false;
637#else 633}
638 XColor xc;
639 634
640 xc.red = rgba.r; 635bool
641 xc.green = rgba.g; 636rxvt_color::set (rxvt_screen *screen, const char *name)
642 xc.blue = rgba.b; 637{
643 xc.flags = DoRed | DoGreen | DoBlue; 638 rxvt_rgba c;
639 char eos;
640 int skip;
644 641
642 if (1 <= sscanf (name, "[%hd]%n", &c.a, &skip))
643 {
644 printf ("X %d\n", c.a);
645 c.a = lerp<int, int, int> (0, rxvt_rgba::MAX_CC, c.a);
646 name += skip;
647 printf ("y %04x\n", c.a);
648 }
649 else
650 c.a = rxvt_rgba::MAX_CC;
651
652 // parse the non-standard rgba format
653 if (strlen (name) != 4+5*4 || 4 != sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &c.r, &c.g, &c.b, &c.a, &eos))
654 {
655 XColor xc, xc_exact;
656
645 if (XAllocColor (screen->xdisp, screen->cmap, &xc)) 657 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
658 {
659 c.r = xc.red;
660 c.g = xc.green;
661 c.b = xc.blue;
662 }
663 else
664 {
665 c.r = 0xffff;
666 c.g = 0x6969;
667 c.b = 0xb4b4;
668
669 rxvt_warn ("unable to parse color '%s', using pink instead.\n", name);
670 }
646 { 671 }
647 p = xc.pixel; 672
648 return true; 673 return set (screen, c);
674}
675
676bool
677rxvt_color::set (rxvt_screen *screen, const rxvt_rgba &color)
678{
679 bool got = alloc (screen, color);
680
681#if !ENABLE_MINIMAL
682 int cmap_size = screen->visual->map_entries;
683
684 if (!got
685 && screen->visual->c_class == PseudoColor
686 && cmap_size < 4096)
649 } 687 {
688 XColor *colors = new XColor [screen->visual->map_entries];
650 689
651 return false; 690 for (int i = 0; i < cmap_size; i++)
652#endif 691 colors [i].pixel = i;
653} 692
693 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
654 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, rxvt_rgba (best->red, best->green, best->blue));
715
716 delete colors;
717 }
718#endif
719
720 return got;
721}
722
655void 723void
656rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 724rxvt_color::get (rxvt_screen *screen, rxvt_rgba &color)
657{ 725{
658#if XFT 726#if XFT
659 rgba.r = c.color.red; 727 color.r = c.color.red;
660 rgba.g = c.color.green; 728 color.g = c.color.green;
661 rgba.b = c.color.blue; 729 color.b = c.color.blue;
662 rgba.a = c.color.alpha; 730 color.a = c.color.alpha;
663#else 731#else
664 XColor c; 732 XColor c;
665 733
666 c.pixel = p; 734 c.pixel = p;
667 XQueryColor (screen->xdisp, screen->cmap, &c); 735 XQueryColor (screen->xdisp, screen->cmap, &c);
668 736
669 rgba.r = c.red; 737 color.r = c.red;
670 rgba.g = c.green; 738 color.g = c.green;
671 rgba.b = c.blue; 739 color.b = c.blue;
672 rgba.a = rxvt_rgba::MAX_CC; 740 color.a = rxvt_rgba::MAX_CC;
673#endif 741#endif
674} 742}
675 743
676void 744void
677rxvt_color::free (rxvt_screen *screen) 745rxvt_color::free (rxvt_screen *screen)
681#else 749#else
682 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 750 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
683#endif 751#endif
684} 752}
685 753
686rxvt_color 754void
687rxvt_color::fade (rxvt_screen *screen, int percent) 755rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rxvt_rgba &to)
688{ 756{
689 rxvt_color faded;
690
691 rxvt_rgba c; 757 rxvt_rgba c;
692 get (screen, c); 758 get (screen, c);
693 759
694 c.r = lerp (0, c.r, percent); 760 result.set (
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)
705{
706 rxvt_rgba c, fc;
707 rxvt_color faded;
708
709 get (screen, c);
710 fadeto.get (screen, fc);
711
712 faded.set (
713 screen, 761 screen,
714 rxvt_rgba ( 762 rxvt_rgba (
715 lerp (fc.r, c.r, percent), 763 lerp (c.r, to.r, percent),
716 lerp (fc.g, c.g, percent), 764 lerp (c.g, to.g, percent),
717 lerp (fc.b, c.b, percent), 765 lerp (c.b, to.b, percent),
718 lerp (fc.a, c.a, percent) 766 lerp (c.a, to.a, percent)
719 ) 767 )
720 ); 768 );
721
722 return faded;
723} 769}
724 770

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines