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.31 by root, Sun Jan 29 22:27:04 2006 UTC vs.
Revision 1.48 by root, Thu Feb 2 12:51:22 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{
375 395
376void 396void
377rxvt_display::ref_next () 397rxvt_display::ref_next ()
378{ 398{
379 // TODO: somehow check wether the database files/resources changed 399 // TODO: somehow check wether the database files/resources changed
380 // before re-loading/parsing 400 // before affording re-loading/parsing
381 XrmDestroyDatabase (XrmGetDatabase (display)); 401 XrmDestroyDatabase (XrmGetDatabase (display));
382 XrmSetDatabase (display, get_resources ()); 402 XrmSetDatabase (display, get_resources ());
383} 403}
384 404
385rxvt_display::~rxvt_display () 405rxvt_display::~rxvt_display ()
488 508
489 selection_owner = owner; 509 selection_owner = owner;
490} 510}
491 511
492#ifdef USE_XIM 512#ifdef USE_XIM
513
493void rxvt_display::reg (im_watcher *w) 514void rxvt_display::reg (im_watcher *w)
494{ 515{
495 imw.push_back (w); 516 imw.push_back (w);
496} 517}
497 518
521 return xim; 542 return xim;
522} 543}
523 544
524void rxvt_display::put_xim (rxvt_xim *xim) 545void rxvt_display::put_xim (rxvt_xim *xim)
525{ 546{
526#if XLIB_IS_RACEFREE 547# if XLIB_IS_RACEFREE
527 xims.put (xim); 548 xims.put (xim);
528#endif 549# endif
529} 550}
551
530#endif 552#endif
531 553
532Atom rxvt_display::atom (const char *name) 554Atom rxvt_display::atom (const char *name)
533{ 555{
534 return XInternAtom (display, name, False); 556 return XInternAtom (display, name, False);
538 560
539template class refcache<rxvt_display>; 561template class refcache<rxvt_display>;
540refcache<rxvt_display> displays; 562refcache<rxvt_display> displays;
541 563
542///////////////////////////////////////////////////////////////////////////// 564/////////////////////////////////////////////////////////////////////////////
543 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
544bool 629bool
545rxvt_color::set (rxvt_screen *screen, const char *name) 630rxvt_color::set (rxvt_screen *screen, const char *name)
546{ 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{
547#if XFT 721#if XFT
548 int l = strlen (name); 722 color.r = c.color.red;
549 rxvt_rgba r; 723 color.g = c.color.green;
550 char eos; 724 color.b = c.color.blue;
551 int mult; 725 color.a = c.color.alpha;
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 726#else
567 XColor xc; 727 color.r = c.red;
568 728 color.g = c.green;
569 if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) 729 color.b = c.blue;
570 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue)); 730 color.a = rgba::MAX_CC;
571
572 return false;
573#endif 731#endif
574} 732}
575 733
576bool
577rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
578{
579#if XFT
580 XRenderPictFormat *format;
581
582 // FUCKING Xft gets it wrong, of course, so work around it
583 // transparency users should eat shit and die, and then
584 // XRenderQueryPictIndexValues themselves plenty.
585 if (screen->visual->c_class == TrueColor
586 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
587 {
588 // the fun lies in doing everything manually...
589 c.color.red = rgba.r;
590 c.color.green = rgba.g;
591 c.color.blue = rgba.b;
592 c.color.alpha = rgba.a;
593
594 c.pixel = (rgba.r >> (16 - popcount (format->direct.redMask )) << format->direct.red)
595 | (rgba.g >> (16 - popcount (format->direct.greenMask)) << format->direct.green)
596 | (rgba.b >> (16 - popcount (format->direct.blueMask )) << format->direct.blue)
597 | (rgba.a >> (16 - popcount (format->direct.alphaMask)) << format->direct.alpha);
598
599 return true;
600 }
601 else
602 {
603 XRenderColor d;
604
605 d.red = rgba.r;
606 d.green = rgba.g;
607 d.blue = rgba.b;
608 d.alpha = rgba.a;
609
610 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
611 }
612
613 return false;
614#else
615 XColor xc;
616
617 xc.red = rgba.r;
618 xc.green = rgba.g;
619 xc.blue = rgba.b;
620 xc.flags = DoRed | DoGreen | DoBlue;
621
622 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
623 {
624 p = xc.pixel;
625 return true;
626 }
627
628 return false;
629#endif
630}
631
632void 734void
633rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 735rxvt_color::get (XColor &color)
634{ 736{
635#if XFT 737 rgba c;
636 rgba.r = c.color.red; 738 get (c);
637 rgba.g = c.color.green;
638 rgba.b = c.color.blue;
639 rgba.a = c.color.alpha;
640#else
641 XColor c;
642 739
643 c.pixel = p; 740 color.red = c.r;
644 XQueryColor (screen->xdisp, screen->cmap, &c); 741 color.green = c.g;
645 742 color.blue = c.b;
646 rgba.r = c.red; 743 color.pixel = (Pixel)*this;
647 rgba.g = c.green;
648 rgba.b = c.blue;
649 rgba.a = rxvt_rgba::MAX_CC;
650#endif
651} 744}
652 745
653void 746void
654rxvt_color::free (rxvt_screen *screen) 747rxvt_color::free (rxvt_screen *screen)
655{ 748{
656#if XFT 749#if XFT
657 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 750 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
658#else 751#else
659 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 752 XFreeColors (screen->xdisp, screen->cmap, &c.pixel, 1, AllPlanes);
660#endif 753#endif
661} 754}
662 755
663rxvt_color 756void
664rxvt_color::fade (rxvt_screen *screen, int percent)
665{
666 rxvt_color faded;
667
668 rxvt_rgba c;
669 get (screen, c);
670
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) 757rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
682{ 758{
683 rxvt_rgba c, fc; 759 rgba c;
684 rxvt_color faded; 760 get (c);
685
686 get (screen, c);
687 fadeto.get (screen, fc);
688 761
689 faded.set ( 762 result.set (
690 screen, 763 screen,
691 rxvt_rgba ( 764 rgba (
692 lerp (fc.r, c.r, percent), 765 lerp (c.r, to.r, percent),
693 lerp (fc.g, c.g, percent), 766 lerp (c.g, to.g, percent),
694 lerp (fc.b, c.b, percent), 767 lerp (c.b, to.b, percent),
695 lerp (fc.a, c.a, percent) 768 lerp (c.a, to.a, percent)
696 ) 769 )
697 ); 770 );
698
699 return faded;
700} 771}
701 772

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines