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.34 by root, Mon Jan 30 02:21:20 2006 UTC vs.
Revision 1.39 by root, Tue Jan 31 00:25:16 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
550 558
551template class refcache<rxvt_display>; 559template class refcache<rxvt_display>;
552refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
553 561
554///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
555 563
556bool 564bool
557rxvt_color::set (rxvt_screen *screen, const char *name)
558{
559#if XFT
560 int l = strlen (name);
561 rxvt_rgba r;
562 char eos;
563 int mult;
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
590 XColor xc;
591
592 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
593 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue));
594
595 return false;
596#endif
597}
598
599bool
600rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba) 565rxvt_color::alloc (rxvt_screen *screen, rxvt_rgba rgba)
601{ 566{
602#if XFT 567#if XFT
603 XRenderPictFormat *format; 568 XRenderPictFormat *format;
604 569
605 // FUCKING Xft gets it wrong, of course, so work around it 570 // FUCKING Xft gets it wrong, of course, so work around it
606 // transparency users should eat shit and die, and then 571 // transparency users should eat shit and die, and then
607 // XRenderQueryPictIndexValues themselves plenty. 572 // XRenderQueryPictIndexValues themselves plenty.
608 if (screen->visual->c_class == TrueColor 573 if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
609 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual))) 574 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
610 { 575 {
611 // the fun lies in doing everything manually... 576 // the fun lies in doing everything manually...
612 c.color.red = rgba.r; 577 c.color.red = rgba.r;
613 c.color.green = rgba.g; 578 c.color.green = rgba.g;
630 d.blue = rgba.b; 595 d.blue = rgba.b;
631 d.alpha = rgba.a; 596 d.alpha = rgba.a;
632 597
633 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c); 598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
634 } 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
635 631
636 return false; 632 return false;
637#else 633}
638 XColor xc;
639 634
640 xc.red = rgba.r; 635bool
641 xc.green = rgba.g; 636rxvt_color::set (rxvt_screen *screen, const char *name)
642 xc.blue = rgba.b; 637{
643 xc.flags = DoRed | DoGreen | DoBlue; 638 rxvt_rgba c;
639 char eos;
640 int skip;
644 641
642 if (1 <= sscanf (name, "[%hx]%n", &c.a, &skip))
643 {
644 switch (skip)
645 {
646 case 2 + 1: c.a *= rxvt_rgba::MAX_CC / 0x000f; break;
647 case 2 + 2: c.a *= rxvt_rgba::MAX_CC / 0x00ff; break;
648 case 2 + 3: c.a *= rxvt_rgba::MAX_CC / 0x0fff; break;
649 case 2 + 4: c.a *= rxvt_rgba::MAX_CC / 0xffff; break;
650 }
651
652 name += skip;
653 }
654 else
655 c.a = rxvt_rgba::MAX_CC;
656
657 // parse the non-standard rgba format
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))
659 {
660 XColor xc, xc_exact;
661
645 if (XAllocColor (screen->xdisp, screen->cmap, &xc)) 662 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
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;
673
674 rxvt_warn ("unable to parse color '%s', using pink instead.\n", name);
675 }
646 { 676 }
647 p = xc.pixel; 677
648 return true; 678 return set (screen, c);
679}
680
681bool
682rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
683{
684 bool got = alloc (screen, rgba);
685
686#if !ENABLE_MINIMAL
687 int cmap_size = screen->visual->map_entries;
688
689 if (!got
690 && screen->visual->c_class == PseudoColor
691 && cmap_size < 4096)
649 } 692 {
693 XColor *colors = new XColor [screen->visual->map_entries];
650 694
651 return false; 695 for (int i = 0; i < cmap_size; i++)
652#endif 696 colors [i].pixel = i;
653} 697
698 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
654 699
700 int diff = 0x7fffffffUL;
701 XColor *best = colors;
702
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;
722 }
723#endif
724
725 return got;
726}
727
655void 728void
656rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 729rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba)
657{ 730{
658#if XFT 731#if XFT
659 rgba.r = c.color.red; 732 rgba.r = c.color.red;
660 rgba.g = c.color.green; 733 rgba.g = c.color.green;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines