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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines