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.33 by root, Sun Jan 29 22:39:26 2006 UTC vs.
Revision 1.40 by root, Tue Jan 31 16:19:16 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)
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) 565rxvt_color::alloc (rxvt_screen *screen, const rxvt_rgba &color)
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 / rxvt_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 / rxvt_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 / rxvt_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 / rxvt_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 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
612 631
613 return false; 632 return false;
614#else 633}
615 XColor xc;
616 634
617 xc.red = rgba.r; 635bool
618 xc.green = rgba.g; 636rxvt_color::set (rxvt_screen *screen, const char *name)
619 xc.blue = rgba.b; 637{
620 xc.flags = DoRed | DoGreen | DoBlue; 638 rxvt_rgba c;
639 char eos;
640 int skip;
621 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
622 if (XAllocColor (screen->xdisp, screen->cmap, &xc)) 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 }
623 { 676 }
624 p = xc.pixel; 677
625 return true; 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)
626 } 692 {
693 XColor *colors = new XColor [screen->visual->map_entries];
627 694
628 return false; 695 for (int i = 0; i < cmap_size; i++)
629#endif 696 colors [i].pixel = i;
630} 697
698 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
631 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
632void 728void
633rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 729rxvt_color::get (rxvt_screen *screen, rxvt_rgba &color)
634{ 730{
635#if XFT 731#if XFT
636 rgba.r = c.color.red; 732 color.r = c.color.red;
637 rgba.g = c.color.green; 733 color.g = c.color.green;
638 rgba.b = c.color.blue; 734 color.b = c.color.blue;
639 rgba.a = c.color.alpha; 735 color.a = c.color.alpha;
640#else 736#else
641 XColor c; 737 XColor c;
642 738
643 c.pixel = p; 739 c.pixel = p;
644 XQueryColor (screen->xdisp, screen->cmap, &c); 740 XQueryColor (screen->xdisp, screen->cmap, &c);
645 741
646 rgba.r = c.red; 742 color.r = c.red;
647 rgba.g = c.green; 743 color.g = c.green;
648 rgba.b = c.blue; 744 color.b = c.blue;
649 rgba.a = rxvt_rgba::MAX_CC; 745 color.a = rxvt_rgba::MAX_CC;
650#endif 746#endif
651} 747}
652 748
653void 749void
654rxvt_color::free (rxvt_screen *screen) 750rxvt_color::free (rxvt_screen *screen)
659 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 755 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
660#endif 756#endif
661} 757}
662 758
663rxvt_color 759rxvt_color
664rxvt_color::fade (rxvt_screen *screen, int percent) 760rxvt_color::fade (rxvt_screen *screen, int percent, const rxvt_rgba &to)
665{ 761{
666 rxvt_color faded;
667
668 rxvt_rgba c; 762 rxvt_rgba c;
669 get (screen, c); 763 get (screen, c);
670 764
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)
682{
683 rxvt_rgba c, fc;
684 rxvt_color faded; 765 rxvt_color faded;
685
686 get (screen, c);
687 fadeto.get (screen, fc);
688
689 faded.set ( 766 faded.set (
690 screen, 767 screen,
691 rxvt_rgba ( 768 rxvt_rgba (
692 lerp (fc.r, c.r, percent), 769 lerp (to.r, c.r, percent),
693 lerp (fc.g, c.g, percent), 770 lerp (to.g, c.g, percent),
694 lerp (fc.b, c.b, percent), 771 lerp (to.b, c.b, percent),
695 lerp (fc.a, c.a, percent) 772 lerp (to.a, c.a, percent)
696 ) 773 )
697 ); 774 );
698 775
699 return faded; 776 return faded;
700} 777}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines