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.48 by root, Thu Feb 2 12:51:22 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{
369 395
370void 396void
371rxvt_display::ref_next () 397rxvt_display::ref_next ()
372{ 398{
373 // TODO: somehow check wether the database files/resources changed 399 // TODO: somehow check wether the database files/resources changed
374 // before re-loading/parsing 400 // before affording re-loading/parsing
375 XrmDestroyDatabase (XrmGetDatabase (display)); 401 XrmDestroyDatabase (XrmGetDatabase (display));
376 XrmSetDatabase (display, get_resources ()); 402 XrmSetDatabase (display, get_resources ());
377} 403}
378 404
379rxvt_display::~rxvt_display () 405rxvt_display::~rxvt_display ()
482 508
483 selection_owner = owner; 509 selection_owner = owner;
484} 510}
485 511
486#ifdef USE_XIM 512#ifdef USE_XIM
513
487void rxvt_display::reg (im_watcher *w) 514void rxvt_display::reg (im_watcher *w)
488{ 515{
489 imw.push_back (w); 516 imw.push_back (w);
490} 517}
491 518
515 return xim; 542 return xim;
516} 543}
517 544
518void rxvt_display::put_xim (rxvt_xim *xim) 545void rxvt_display::put_xim (rxvt_xim *xim)
519{ 546{
520#if XLIB_IS_RACEFREE 547# if XLIB_IS_RACEFREE
521 xims.put (xim); 548 xims.put (xim);
522#endif 549# endif
523} 550}
551
524#endif 552#endif
525 553
526Atom rxvt_display::atom (const char *name) 554Atom rxvt_display::atom (const char *name)
527{ 555{
528 return XInternAtom (display, name, False); 556 return XInternAtom (display, name, False);
532 560
533template class refcache<rxvt_display>; 561template class refcache<rxvt_display>;
534refcache<rxvt_display> displays; 562refcache<rxvt_display> displays;
535 563
536///////////////////////////////////////////////////////////////////////////// 564/////////////////////////////////////////////////////////////////////////////
537 565
566bool
567rxvt_color::alloc (rxvt_screen *screen, const rgba &color)
568{
569#if XFT
570 XRenderPictFormat *format;
571
572 // FUCKING Xft gets it wrong, of course, so work around it.
573 // Transparency users should eat shit and die, and then
574 // XRenderQueryPictIndexValues themselves plenty.
575 if ((screen->visual->c_class == TrueColor)
576 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
577 {
578 // the fun lies in doing everything manually...
579 c.color.red = color.r;
580 c.color.green = color.g;
581 c.color.blue = color.b;
582 c.color.alpha = color.a;
583
584 c.pixel = ((color.r * format->direct.redMask / rgba::MAX_CC) << format->direct.red )
585 | ((color.g * format->direct.greenMask / rgba::MAX_CC) << format->direct.green)
586 | ((color.b * format->direct.blueMask / rgba::MAX_CC) << format->direct.blue )
587 | ((color.a * format->direct.alphaMask / rgba::MAX_CC) << format->direct.alpha);
588
589 return true;
590 }
591 else
592 {
593 XRenderColor d;
594
595 d.red = color.r;
596 d.green = color.g;
597 d.blue = color.b;
598 d.alpha = color.a;
599
600 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
601 }
602#else
603 c.red = color.r;
604 c.green = color.g;
605 c.blue = color.b;
606
607 if (screen->visual->c_class == TrueColor)
608 {
609 c.pixel = (color.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask ))
610 / rgba::MAX_CC) << ctz (screen->visual->red_mask )
611 | (color.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask))
612 / rgba::MAX_CC) << ctz (screen->visual->green_mask)
613 | (color.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask ))
614 / rgba::MAX_CC) << ctz (screen->visual->blue_mask );
615
616 return true;
617 }
618 else if (XAllocColor (screen->xdisp, screen->cmap, &c))
619 return true;
620 else
621 c.pixel = (color.r + color.g + color.b) > 128*3
622 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->xdisp))
623 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->xdisp));
624#endif
625
626 return false;
627}
628
538bool 629bool
539rxvt_color::set (rxvt_screen *screen, const char *name) 630rxvt_color::set (rxvt_screen *screen, const char *name)
540{ 631{
632 rgba c;
633 char eos;
634 int skip;
635
636 // parse the nonstandard "[alphapercent]" prefix
637 if (1 <= sscanf (name, "[%hd]%n", &c.a, &skip))
638 {
639 c.a = lerp<int, int, int> (0, rgba::MAX_CC, c.a);
640 name += skip;
641 }
642 else
643 c.a = rgba::MAX_CC;
644
645 // parse the non-standard "rgba:rrrr/gggg/bbbb/aaaa" format
646 if (strlen (name) != 4+5*4 || 4 != sscanf (name, "rgba:%4hx/%4hx/%4hx/%4hx%c", &c.r, &c.g, &c.b, &c.a, &eos))
647 {
648 XColor xc, xc_exact;
649
650 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
651 {
652 c.r = xc.red;
653 c.g = xc.green;
654 c.b = xc.blue;
655 }
656 else
657 {
658 c.r = 0xffff;
659 c.g = 0x6969;
660 c.b = 0xb4b4;
661
662 rxvt_warn ("unable to parse color '%s', using pink instead.\n", name);
663 }
664 }
665
666 return set (screen, c);
667}
668
669bool
670rxvt_color::set (rxvt_screen *screen, const rgba &color)
671{
672 bool got = alloc (screen, color);
673
674#if !ENABLE_MINIMAL
675 int cmap_size = screen->visual->map_entries;
676
677 if (!got
678 && screen->visual->c_class == PseudoColor
679 && cmap_size < 4096)
680 {
681 XColor *colors = new XColor [screen->visual->map_entries];
682
683 for (int i = 0; i < cmap_size; i++)
684 colors [i].pixel = i;
685
686 // many kilobytes transfer per colour, but pseudocolor isn't worth
687 // many extra optimisations.
688 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
689
690 int diff = 0x7fffffffUL;
691 XColor *best = colors;
692
693 for (int i = 0; i < cmap_size; i++)
694 {
695 int d = (squared_diff<int> (color.r >> 2, colors [i].red >> 2))
696 + (squared_diff<int> (color.g >> 2, colors [i].green >> 2))
697 + (squared_diff<int> (color.b >> 2, colors [i].blue >> 2));
698
699 if (d < diff)
700 {
701 diff = d;
702 best = colors + i;
703 }
704 }
705
706 //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n",
707 // color.r, color.g, color.b, best->red, best->green, best->blue, diff);
708
709 got = alloc (screen, rgba (best->red, best->green, best->blue));
710
711 delete colors;
712 }
713#endif
714
715 return got;
716}
717
718void
719rxvt_color::get (rgba &color)
720{
541#if XFT 721#if XFT
542 int l = strlen (name); 722 color.r = c.color.red;
543 rxvt_rgba r; 723 color.g = c.color.green;
544 char eos; 724 color.b = c.color.blue;
545 int mult; 725 color.a = c.color.alpha;
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 726#else
561 XColor xc; 727 color.r = c.red;
562 728 color.g = c.green;
563 if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) 729 color.b = c.blue;
564 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue)); 730 color.a = rgba::MAX_CC;
565
566 return false;
567#endif 731#endif
568} 732}
569 733
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 734void
615rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 735rxvt_color::get (XColor &color)
616{ 736{
617#if XFT 737 rgba c;
618 rgba.r = c.color.red; 738 get (c);
619 rgba.g = c.color.green;
620 rgba.b = c.color.blue;
621 rgba.a = c.color.alpha;
622#else
623 XColor c;
624 739
625 c.pixel = p; 740 color.red = c.r;
626 XQueryColor (screen->xdisp, screen->cmap, &c); 741 color.green = c.g;
627 742 color.blue = c.b;
628 rgba.r = c.red; 743 color.pixel = (Pixel)*this;
629 rgba.g = c.green;
630 rgba.b = c.blue;
631 rgba.a = rxvt_rgba::MAX_CC;
632#endif
633} 744}
634 745
635void 746void
636rxvt_color::free (rxvt_screen *screen) 747rxvt_color::free (rxvt_screen *screen)
637{ 748{
638#if XFT 749#if XFT
639 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 750 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
640#else 751#else
641 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 752 XFreeColors (screen->xdisp, screen->cmap, &c.pixel, 1, AllPlanes);
642#endif 753#endif
643} 754}
644 755
645rxvt_color 756void
646rxvt_color::fade (rxvt_screen *screen, int percent)
647{
648 rxvt_color faded;
649
650 rxvt_rgba c;
651 get (screen, c);
652
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) 757rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
664{ 758{
665 rxvt_rgba c, fc; 759 rgba c;
666 rxvt_color faded; 760 get (c);
667
668 get (screen, c);
669 fadeto.get (screen, fc);
670 761
671 faded.set ( 762 result.set (
672 screen, 763 screen,
673 rxvt_rgba ( 764 rgba (
674 lerp (fc.r, c.r, percent), 765 lerp (c.r, to.r, percent),
675 lerp (fc.g, c.g, percent), 766 lerp (c.g, to.g, percent),
676 lerp (fc.b, c.b, percent), 767 lerp (c.b, to.b, percent),
677 lerp (fc.a, c.a, percent) 768 lerp (c.a, to.a, percent)
678 ) 769 )
679 ); 770 );
680
681 return faded;
682} 771}
683 772

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines