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.37 by root, Mon Jan 30 17:49:48 2006 UTC vs.
Revision 1.45 by root, Wed Feb 1 01:58:47 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
607 // XRenderQueryPictIndexValues themselves plenty. 572 // XRenderQueryPictIndexValues themselves plenty.
608 if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor) 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 }
635
636 return false;
637#else 600#else
638 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor) 601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
639 { 602 {
603 c.red = color.g;
604 c.green = color.g;
605 c.blue = color.g;
640 p = (rgba.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask )) 606 c.pixel = (color.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask ))
641 / rxvt_rgba::MAX_CC) << ctz (screen->visual->red_mask ) 607 / rgba::MAX_CC) << ctz (screen->visual->red_mask )
642 | (rgba.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask)) 608 | (color.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask))
643 / rxvt_rgba::MAX_CC) << ctz (screen->visual->green_mask) 609 / rgba::MAX_CC) << ctz (screen->visual->green_mask)
644 | (rgba.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask )) 610 | (color.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask ))
645 / rxvt_rgba::MAX_CC) << ctz (screen->visual->blue_mask ); 611 / rgba::MAX_CC) << ctz (screen->visual->blue_mask );
646 612
647 return true; 613 return true;
648 } 614 }
649 else 615 else
650 { 616 {
651 XColor xc;
652
653 xc.red = rgba.r; 617 c.red = color.r;
654 xc.green = rgba.g; 618 c.green = color.g;
655 xc.blue = rgba.b; 619 c.blue = color.b;
656 xc.flags = DoRed | DoGreen | DoBlue;
657 620
658 if (XAllocColor (screen->xdisp, screen->cmap, &xc)) 621 if (XAllocColor (screen->xdisp, screen->cmap, &c))
659 {
660 p = xc.pixel;
661 return true; 622 return true;
662 } 623 else
624 c.pixel = (color.r + color.g + color.b) > 128*3
625 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->xdisp))
626 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->xdisp));
663 } 627 }
628#endif
664 629
665 return false; 630 return false;
666#endif
667} 631}
668 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
669void 721void
670rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 722rxvt_color::get (rgba &color)
671{ 723{
672#if XFT 724#if XFT
673 rgba.r = c.color.red; 725 color.r = c.color.red;
674 rgba.g = c.color.green; 726 color.g = c.color.green;
675 rgba.b = c.color.blue; 727 color.b = c.color.blue;
676 rgba.a = c.color.alpha; 728 color.a = c.color.alpha;
677#else 729#else
678 XColor c;
679
680 c.pixel = p;
681 XQueryColor (screen->xdisp, screen->cmap, &c);
682
683 rgba.r = c.red; 730 color.r = c.red;
684 rgba.g = c.green; 731 color.g = c.green;
685 rgba.b = c.blue; 732 color.b = c.blue;
686 rgba.a = rxvt_rgba::MAX_CC; 733 color.a = rgba::MAX_CC;
687#endif 734#endif
688} 735}
689 736
690void 737void
691rxvt_color::free (rxvt_screen *screen) 738rxvt_color::free (rxvt_screen *screen)
692{ 739{
693#if XFT 740#if XFT
694 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 741 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
695#else 742#else
696 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 743 XFreeColors (screen->xdisp, screen->cmap, &c.pixel, 1, AllPlanes);
697#endif 744#endif
698} 745}
699 746
700rxvt_color 747void
701rxvt_color::fade (rxvt_screen *screen, int percent)
702{
703 rxvt_color faded;
704
705 rxvt_rgba c;
706 get (screen, c);
707
708 c.r = lerp (0, c.r, percent);
709 c.g = lerp (0, c.g, percent);
710 c.b = lerp (0, c.b, percent);
711
712 faded.set (screen, c);
713
714 return faded;
715}
716
717rxvt_color
718rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto) 748rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
719{ 749{
720 rxvt_rgba c, fc; 750 rgba c;
721 rxvt_color faded; 751 get (c);
722
723 get (screen, c);
724 fadeto.get (screen, fc);
725 752
726 faded.set ( 753 result.set (
727 screen, 754 screen,
728 rxvt_rgba ( 755 rgba (
729 lerp (fc.r, c.r, percent), 756 lerp (c.r, to.r, percent),
730 lerp (fc.g, c.g, percent), 757 lerp (c.g, to.g, percent),
731 lerp (fc.b, c.b, percent), 758 lerp (c.b, to.b, percent),
732 lerp (fc.a, c.a, percent) 759 lerp (c.a, to.a, percent)
733 ) 760 )
734 ); 761 );
735
736 return faded;
737} 762}
738 763

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines