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.30 by root, Sun Jan 29 21:54:33 2006 UTC vs.
Revision 1.41 by root, Tue Jan 31 16:43:55 2006 UTC

32#ifndef NO_SLOW_LINK_SUPPORT 32#ifndef NO_SLOW_LINK_SUPPORT
33# include <sys/socket.h> 33# include <sys/socket.h>
34# include <sys/un.h> 34# include <sys/un.h>
35#endif 35#endif
36 36
37#if XFT
38# include <X11/extensions/Xrender.h>
39#endif
40
37const char *const xa_names[] = 41const char *const xa_names[] =
38 { 42{
39 "TEXT", 43 "TEXT",
40 "COMPOUND_TEXT", 44 "COMPOUND_TEXT",
41 "UTF8_STRING", 45 "UTF8_STRING",
42 "MULTIPLE", 46 "MULTIPLE",
43 "TARGETS", 47 "TARGETS",
44 "TIMESTAMP", 48 "TIMESTAMP",
45 "VT_SELECTION", 49 "VT_SELECTION",
46 "INCR", 50 "INCR",
47 "WM_PROTOCOLS", 51 "WM_PROTOCOLS",
48 "WM_DELETE_WINDOW", 52 "WM_DELETE_WINDOW",
49 "CLIPBOARD", 53 "CLIPBOARD",
54 "AVERAGE_WIDTH",
55 "WEIGHT_NAME",
56 "SLANT",
57 "CHARSET_REGISTRY",
58 "CHARSET_ENCODING",
50#if ENABLE_FRILLS 59#if ENABLE_FRILLS
51 "_MOTIF_WM_HINTS", 60 "_MOTIF_WM_HINTS",
52#endif 61#endif
53#if ENABLE_EWMH 62#if ENABLE_EWMH
54 "_NET_WM_PID", 63 "_NET_WM_PID",
55 "_NET_WM_NAME", 64 "_NET_WM_NAME",
56 "_NET_WM_ICON_NAME", 65 "_NET_WM_ICON_NAME",
57 "_NET_WM_PING", 66 "_NET_WM_PING",
58#endif 67#endif
59#if USE_XIM 68#if USE_XIM
60 "WM_LOCALE_NAME", 69 "WM_LOCALE_NAME",
61 "XIM_SERVERS", 70 "XIM_SERVERS",
62#endif 71#endif
63#ifdef TRANSPARENT 72#ifdef TRANSPARENT
64 "_XROOTPMAP_ID", 73 "_XROOTPMAP_ID",
65 "ESETROOT_PMAP_ID", 74 "ESETROOT_PMAP_ID",
66#endif 75#endif
67#if ENABLE_XEMBED 76#if ENABLE_XEMBED
68 "_XEMBED", 77 "_XEMBED",
69 "_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",
70#endif 93# endif
71 }; 94#endif
95};
72 96
73///////////////////////////////////////////////////////////////////////////// 97/////////////////////////////////////////////////////////////////////////////
74 98
75refcounted::refcounted (const char *id) 99refcounted::refcounted (const char *id)
76{ 100{
195void 219void
196rxvt_screen::set (rxvt_display *disp, int bitdepth) 220rxvt_screen::set (rxvt_display *disp, int bitdepth)
197{ 221{
198 set (disp); 222 set (disp);
199 223
224#if XFT
200 XVisualInfo vinfo; 225 XVisualInfo vinfo;
201 226
202 if (XMatchVisualInfo (xdisp, display->screen, bitdepth, TrueColor, &vinfo)) 227 if (XMatchVisualInfo (xdisp, display->screen, bitdepth, TrueColor, &vinfo))
203 { 228 {
204 depth = bitdepth; 229 depth = bitdepth;
205 visual = vinfo.visual; 230 visual = vinfo.visual;
206 cmap = XCreateColormap (xdisp, disp->root, visual, AllocNone); 231 cmap = XCreateColormap (xdisp, disp->root, visual, AllocNone);
207 } 232 }
233#endif
208} 234}
209 235
210void 236void
211rxvt_screen::clear () 237rxvt_screen::clear ()
212{ 238{
532 558
533template class refcache<rxvt_display>; 559template class refcache<rxvt_display>;
534refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
535 561
536///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
537 563
564bool
565rxvt_color::alloc (rxvt_screen *screen, const rxvt_rgba &color)
566{
567#if XFT
568 XRenderPictFormat *format;
569
570 // FUCKING Xft gets it wrong, of course, so work around it
571 // transparency users should eat shit and die, and then
572 // XRenderQueryPictIndexValues themselves plenty.
573 if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
574 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
575 {
576 // the fun lies in doing everything manually...
577 c.color.red = color.r;
578 c.color.green = color.g;
579 c.color.blue = color.b;
580 c.color.alpha = color.a;
581
582 c.pixel = ((color.r * format->direct.redMask / rxvt_rgba::MAX_CC) << format->direct.red )
583 | ((color.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green)
584 | ((color.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue )
585 | ((color.a * format->direct.alphaMask / rxvt_rgba::MAX_CC) << format->direct.alpha);
586
587 return true;
588 }
589 else
590 {
591 XRenderColor d;
592
593 d.red = color.r;
594 d.green = color.g;
595 d.blue = color.b;
596 d.alpha = color.a;
597
598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
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
631
632 return false;
633}
634
538bool 635bool
539rxvt_color::set (rxvt_screen *screen, const char *name) 636rxvt_color::set (rxvt_screen *screen, const char *name)
540{ 637{
638 rxvt_rgba c;
639 char eos;
640 int skip;
641
642 if (1 <= sscanf (name, "[%hd]%n", &c.a, &skip))
643 {
644 c.a = lerp<int, int, int> (0, rxvt_rgba::MAX_CC, c.a);
645 name += skip;
646 }
647 else
648 c.a = rxvt_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 rxvt_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 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, rxvt_rgba (best->red, best->green, best->blue));
713
714 delete colors;
715 }
716#endif
717
718 return got;
719}
720
721void
722rxvt_color::get (rxvt_screen *screen, rxvt_rgba &color)
723{
541#if XFT 724#if XFT
542 int l = strlen (name);
543 rxvt_rgba r;
544 char eos;
545 int mult;
546
547 if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
548 mult = rxvt_rgba::MAX_CC / 0x000f;
549 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
550 mult = rxvt_rgba::MAX_CC / 0x00ff;
551 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
552 mult = rxvt_rgba::MAX_CC / 0xffff;
553 else if (l == 4+5*4 && 4 == sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
554 mult = rxvt_rgba::MAX_CC / 0xffff;
555 else
556 return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c);
557
558 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult;
559 return set (screen, r);
560#else
561 XColor xc;
562
563 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
564 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue));
565
566 return false;
567#endif
568}
569
570bool
571rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
572{
573#if XFT
574 XRenderColor d;
575
576 d.red = rgba.r;
577 d.green = rgba.g;
578 d.blue = rgba.b;
579 d.alpha = rgba.a;
580
581 if (XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c))
582 {
583 // FUCKING Xft gets it wrong, of course, fix it for the common case
584 // transparency users should eat shit and die, and then
585 // XRenderQueryPictIndexValues themselves plenty.
586 if (screen->depth == 32 && screen->visual->c_class == TrueColor)
587 if ((screen->visual->red_mask | screen->visual->green_mask | screen->visual->blue_mask) == 0x00ffffffUL)
588 c.pixel = c.pixel & 0x00ffffffUL | ((rgba.a >> 8) << 24);
589 else if ((screen->visual->red_mask | screen->visual->green_mask | screen->visual->blue_mask) == 0xffffff00UL)
590 c.pixel = c.pixel & 0xffffff00UL | (rgba.a >> 8);
591
592 return true;
593 }
594
595 return false;
596#else
597 XColor xc;
598
599 xc.red = rgba.r;
600 xc.green = rgba.g;
601 xc.blue = rgba.b;
602 xc.flags = DoRed | DoGreen | DoBlue;
603
604 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
605 {
606 p = xc.pixel;
607 return true;
608 }
609
610 return false;
611#endif
612}
613
614void
615rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba)
616{
617#if XFT
618 rgba.r = c.color.red; 725 color.r = c.color.red;
619 rgba.g = c.color.green; 726 color.g = c.color.green;
620 rgba.b = c.color.blue; 727 color.b = c.color.blue;
621 rgba.a = c.color.alpha; 728 color.a = c.color.alpha;
622#else 729#else
623 XColor c; 730 XColor c;
624 731
625 c.pixel = p; 732 c.pixel = p;
626 XQueryColor (screen->xdisp, screen->cmap, &c); 733 XQueryColor (screen->xdisp, screen->cmap, &c);
627 734
628 rgba.r = c.red; 735 color.r = c.red;
629 rgba.g = c.green; 736 color.g = c.green;
630 rgba.b = c.blue; 737 color.b = c.blue;
631 rgba.a = rxvt_rgba::MAX_CC; 738 color.a = rxvt_rgba::MAX_CC;
632#endif 739#endif
633} 740}
634 741
635void 742void
636rxvt_color::free (rxvt_screen *screen) 743rxvt_color::free (rxvt_screen *screen)
641 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 748 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
642#endif 749#endif
643} 750}
644 751
645rxvt_color 752rxvt_color
646rxvt_color::fade (rxvt_screen *screen, int percent) 753rxvt_color::fade (rxvt_screen *screen, int percent, const rxvt_rgba &to)
647{ 754{
648 rxvt_color faded;
649
650 rxvt_rgba c; 755 rxvt_rgba c;
651 get (screen, c); 756 get (screen, c);
652 757
653 c.r = lerp (0, c.r, percent);
654 c.g = lerp (0, c.g, percent);
655 c.b = lerp (0, c.b, percent);
656
657 faded.set (screen, c);
658
659 return faded;
660}
661
662rxvt_color
663rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
664{
665 rxvt_rgba c, fc;
666 rxvt_color faded; 758 rxvt_color faded;
667
668 get (screen, c);
669 fadeto.get (screen, fc);
670
671 faded.set ( 759 faded.set (
672 screen, 760 screen,
673 rxvt_rgba ( 761 rxvt_rgba (
674 lerp (fc.r, c.r, percent), 762 lerp (to.r, c.r, percent),
675 lerp (fc.g, c.g, percent), 763 lerp (to.g, c.g, percent),
676 lerp (fc.b, c.b, percent), 764 lerp (to.b, c.b, percent),
677 lerp (fc.a, c.a, percent) 765 lerp (to.a, c.a, percent)
678 ) 766 )
679 ); 767 );
680 768
681 return faded; 769 return faded;
682} 770}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines