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.37 by root, Mon Jan 30 17:49:48 2006 UTC vs.
Revision 1.48 by root, Thu Feb 2 12:51:22 2006 UTC

81 "SCREEN_RESOURCES", 81 "SCREEN_RESOURCES",
82 "XDCCC_LINEAR_RGB_CORRECTION", 82 "XDCCC_LINEAR_RGB_CORRECTION",
83 "XDCCC_LINEAR_RGB_MATRICES", 83 "XDCCC_LINEAR_RGB_MATRICES",
84 "WM_COLORMAP_WINDOWS", 84 "WM_COLORMAP_WINDOWS",
85 "WM_STATE", 85 "WM_STATE",
86 "cursor",
87# if USE_XIM
88 "TRANSPORT",
89 "LOCALES",
90 "_XIM_PROTOCOL",
91 "_XIM_XCONNECT",
92 "_XIM_MOREDATA",
93# endif
86#endif 94#endif
87}; 95};
88 96
89///////////////////////////////////////////////////////////////////////////// 97/////////////////////////////////////////////////////////////////////////////
90 98
387 395
388void 396void
389rxvt_display::ref_next () 397rxvt_display::ref_next ()
390{ 398{
391 // TODO: somehow check wether the database files/resources changed 399 // TODO: somehow check wether the database files/resources changed
392 // before re-loading/parsing 400 // before affording re-loading/parsing
393 XrmDestroyDatabase (XrmGetDatabase (display)); 401 XrmDestroyDatabase (XrmGetDatabase (display));
394 XrmSetDatabase (display, get_resources ()); 402 XrmSetDatabase (display, get_resources ());
395} 403}
396 404
397rxvt_display::~rxvt_display () 405rxvt_display::~rxvt_display ()
500 508
501 selection_owner = owner; 509 selection_owner = owner;
502} 510}
503 511
504#ifdef USE_XIM 512#ifdef USE_XIM
513
505void rxvt_display::reg (im_watcher *w) 514void rxvt_display::reg (im_watcher *w)
506{ 515{
507 imw.push_back (w); 516 imw.push_back (w);
508} 517}
509 518
533 return xim; 542 return xim;
534} 543}
535 544
536void rxvt_display::put_xim (rxvt_xim *xim) 545void rxvt_display::put_xim (rxvt_xim *xim)
537{ 546{
538#if XLIB_IS_RACEFREE 547# if XLIB_IS_RACEFREE
539 xims.put (xim); 548 xims.put (xim);
540#endif 549# endif
541} 550}
551
542#endif 552#endif
543 553
544Atom rxvt_display::atom (const char *name) 554Atom rxvt_display::atom (const char *name)
545{ 555{
546 return XInternAtom (display, name, False); 556 return XInternAtom (display, name, False);
550 560
551template class refcache<rxvt_display>; 561template class refcache<rxvt_display>;
552refcache<rxvt_display> displays; 562refcache<rxvt_display> displays;
553 563
554///////////////////////////////////////////////////////////////////////////// 564/////////////////////////////////////////////////////////////////////////////
555 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
556bool 629bool
557rxvt_color::set (rxvt_screen *screen, const char *name) 630rxvt_color::set (rxvt_screen *screen, const char *name)
558{ 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{
559#if XFT 721#if XFT
560 int l = strlen (name); 722 color.r = c.color.red;
561 rxvt_rgba r; 723 color.g = c.color.green;
562 char eos; 724 color.b = c.color.blue;
563 int mult; 725 color.a = c.color.alpha;
564
565 // shortcutting this saves countless server RTTs for the built-in colours
566 if (l == 3+3*3 && 3 == sscanf (name, "rgb:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
567 {
568 r.a = rxvt_rgba::MAX_CC;
569 mult = rxvt_rgba::MAX_CC / 0x00ff;
570 }
571
572 // parse a number of non-standard ARGB colour specifications
573 else if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
574 mult = rxvt_rgba::MAX_CC / 0x000f;
575 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
576 mult = rxvt_rgba::MAX_CC / 0x00ff;
577 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
578 mult = rxvt_rgba::MAX_CC / 0xffff;
579 else if (l == 4+5*4 && 4 == sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
580 mult = rxvt_rgba::MAX_CC / 0xffff;
581
582 // slow case: server round trip
583 else
584 return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c);
585
586 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult;
587
588 return set (screen, r);
589#else 726#else
590 XColor xc; 727 color.r = c.red;
591 728 color.g = c.green;
592 if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) 729 color.b = c.blue;
593 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue)); 730 color.a = rgba::MAX_CC;
594
595 return false;
596#endif 731#endif
597} 732}
598 733
599bool
600rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
601{
602#if XFT
603 XRenderPictFormat *format;
604
605 // FUCKING Xft gets it wrong, of course, so work around it
606 // transparency users should eat shit and die, and then
607 // XRenderQueryPictIndexValues themselves plenty.
608 if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
609 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
610 {
611 // the fun lies in doing everything manually...
612 c.color.red = rgba.r;
613 c.color.green = rgba.g;
614 c.color.blue = rgba.b;
615 c.color.alpha = rgba.a;
616
617 c.pixel = ((rgba.r * format->direct.redMask / rxvt_rgba::MAX_CC) << format->direct.red )
618 | ((rgba.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green)
619 | ((rgba.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue )
620 | ((rgba.a * format->direct.alphaMask / rxvt_rgba::MAX_CC) << format->direct.alpha);
621
622 return true;
623 }
624 else
625 {
626 XRenderColor d;
627
628 d.red = rgba.r;
629 d.green = rgba.g;
630 d.blue = rgba.b;
631 d.alpha = rgba.a;
632
633 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
634 }
635
636 return false;
637#else
638 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
639 {
640 p = (rgba.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask ))
641 / rxvt_rgba::MAX_CC) << ctz (screen->visual->red_mask )
642 | (rgba.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask))
643 / rxvt_rgba::MAX_CC) << ctz (screen->visual->green_mask)
644 | (rgba.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask ))
645 / rxvt_rgba::MAX_CC) << ctz (screen->visual->blue_mask );
646
647 return true;
648 }
649 else
650 {
651 XColor xc;
652
653 xc.red = rgba.r;
654 xc.green = rgba.g;
655 xc.blue = rgba.b;
656 xc.flags = DoRed | DoGreen | DoBlue;
657
658 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
659 {
660 p = xc.pixel;
661 return true;
662 }
663 }
664
665 return false;
666#endif
667}
668
669void 734void
670rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 735rxvt_color::get (XColor &color)
671{ 736{
672#if XFT 737 rgba c;
673 rgba.r = c.color.red; 738 get (c);
674 rgba.g = c.color.green;
675 rgba.b = c.color.blue;
676 rgba.a = c.color.alpha;
677#else
678 XColor c;
679 739
680 c.pixel = p; 740 color.red = c.r;
681 XQueryColor (screen->xdisp, screen->cmap, &c); 741 color.green = c.g;
682 742 color.blue = c.b;
683 rgba.r = c.red; 743 color.pixel = (Pixel)*this;
684 rgba.g = c.green;
685 rgba.b = c.blue;
686 rgba.a = rxvt_rgba::MAX_CC;
687#endif
688} 744}
689 745
690void 746void
691rxvt_color::free (rxvt_screen *screen) 747rxvt_color::free (rxvt_screen *screen)
692{ 748{
693#if XFT 749#if XFT
694 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 750 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
695#else 751#else
696 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 752 XFreeColors (screen->xdisp, screen->cmap, &c.pixel, 1, AllPlanes);
697#endif 753#endif
698} 754}
699 755
700rxvt_color 756void
701rxvt_color::fade (rxvt_screen *screen, int percent)
702{
703 rxvt_color faded;
704
705 rxvt_rgba c;
706 get (screen, c);
707
708 c.r = lerp (0, c.r, percent);
709 c.g = lerp (0, c.g, percent);
710 c.b = lerp (0, c.b, percent);
711
712 faded.set (screen, c);
713
714 return faded;
715}
716
717rxvt_color
718rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto) 757rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
719{ 758{
720 rxvt_rgba c, fc; 759 rgba c;
721 rxvt_color faded; 760 get (c);
722
723 get (screen, c);
724 fadeto.get (screen, fc);
725 761
726 faded.set ( 762 result.set (
727 screen, 763 screen,
728 rxvt_rgba ( 764 rgba (
729 lerp (fc.r, c.r, percent), 765 lerp (c.r, to.r, percent),
730 lerp (fc.g, c.g, percent), 766 lerp (c.g, to.g, percent),
731 lerp (fc.b, c.b, percent), 767 lerp (c.b, to.b, percent),
732 lerp (fc.a, c.a, percent) 768 lerp (c.a, to.a, percent)
733 ) 769 )
734 ); 770 );
735
736 return faded;
737} 771}
738 772

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines