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.29 by root, Sun Jan 29 21:45:47 2006 UTC vs.
Revision 1.39 by root, Tue Jan 31 00:25:16 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, rxvt_rgba rgba)
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 = rgba.r;
578 c.color.green = rgba.g;
579 c.color.blue = rgba.b;
580 c.color.alpha = rgba.a;
581
582 c.pixel = ((rgba.r * format->direct.redMask / rxvt_rgba::MAX_CC) << format->direct.red )
583 | ((rgba.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green)
584 | ((rgba.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue )
585 | ((rgba.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 = rgba.r;
594 d.green = rgba.g;
595 d.blue = rgba.b;
596 d.alpha = rgba.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 = (rgba.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask ))
604 / rxvt_rgba::MAX_CC) << ctz (screen->visual->red_mask )
605 | (rgba.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask))
606 / rxvt_rgba::MAX_CC) << ctz (screen->visual->green_mask)
607 | (rgba.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 = rgba.r;
617 xc.green = rgba.g;
618 xc.blue = rgba.b;
619
620 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
621 {
622 p = xc.pixel;
623 return true;
624 }
625 else
626 p = (rgba.r + rgba.g + rgba.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{
541#if XFT
542 int l = strlen (name);
543 rxvt_rgba r; 638 rxvt_rgba c;
544 char eos; 639 char eos;
545 int mult; 640 int skip;
546 641
547 if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos)) 642 if (1 <= sscanf (name, "[%hx]%n", &c.a, &skip))
548 mult = rxvt_rgba::MAX_CC / 0x000f; 643 {
549 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos)) 644 switch (skip)
550 mult = rxvt_rgba::MAX_CC / 0x00ff; 645 {
551 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos)) 646 case 2 + 1: c.a *= rxvt_rgba::MAX_CC / 0x000f; break;
552 mult = rxvt_rgba::MAX_CC / 0xffff; 647 case 2 + 2: c.a *= rxvt_rgba::MAX_CC / 0x00ff; break;
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)) 648 case 2 + 3: c.a *= rxvt_rgba::MAX_CC / 0x0fff; break;
554 mult = rxvt_rgba::MAX_CC / 0xffff; 649 case 2 + 4: c.a *= rxvt_rgba::MAX_CC / 0xffff; break;
650 }
651
652 name += skip;
653 }
555 else 654 else
556 return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c); 655 c.a = rxvt_rgba::MAX_CC;
557 656
558 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult; 657 // parse the non-standard rgba format
559 return set (screen, r); 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))
560#else 659 {
561 XColor xc; 660 XColor xc, xc_exact;
562 661
563 if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) 662 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
564 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue)); 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;
565 673
566 return false; 674 rxvt_warn ("unable to parse color '%s', using pink instead.\n", name);
567#endif 675 }
676 }
677
678 return set (screen, c);
568} 679}
569 680
570bool 681bool
571rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba) 682rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
572{ 683{
573#if XFT 684 bool got = alloc (screen, rgba);
574 XRenderColor d;
575 685
576 d.red = rgba.r; 686#if !ENABLE_MINIMAL
577 d.green = rgba.g; 687 int cmap_size = screen->visual->map_entries;
578 d.blue = rgba.b;
579 d.alpha = rgba.a;
580 688
581 if (XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c)) 689 if (!got
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
587 && screen->visual->c_class == TrueColor 690 && screen->visual->c_class == PseudoColor
588 && screen->visual->red_mask == 0x00ff0000 691 && cmap_size < 4096)
589 && screen->visual->green_mask == 0x0000ff00
590 && screen->visual->blue_mask == 0x000000ff)
591 c.pixel = c.pixel & 0x00ffffffUL | ((rgba.a >> 8) << 24);
592
593 return true;
594 } 692 {
693 XColor *colors = new XColor [screen->visual->map_entries];
595 694
596 return false; 695 for (int i = 0; i < cmap_size; i++)
597#else 696 colors [i].pixel = i;
598 XColor xc; 697
698 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
599 699
600 xc.red = rgba.r; 700 int diff = 0x7fffffffUL;
601 xc.green = rgba.g; 701 XColor *best = colors;
602 xc.blue = rgba.b;
603 xc.flags = DoRed | DoGreen | DoBlue;
604 702
605 if (XAllocColor (screen->xdisp, screen->cmap, &xc)) 703 for (int i = 0; i < cmap_size; i++)
704 {
705 int d = (squared_diff<int> (rgba.r >> 2, colors [i].red >> 2))
706 + (squared_diff<int> (rgba.g >> 2, colors [i].green >> 2))
707 + (squared_diff<int> (rgba.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 // rgba.r, rgba.g, rgba.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;
606 { 722 }
607 p = xc.pixel;
608 return true;
609 }
610
611 return false;
612#endif 723#endif
613}
614 724
725 return got;
726}
727
615void 728void
616rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 729rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba)
617{ 730{
618#if XFT 731#if XFT
619 rgba.r = c.color.red; 732 rgba.r = c.color.red;
620 rgba.g = c.color.green; 733 rgba.g = c.color.green;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines