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.25 by root, Wed Jan 25 02:42:06 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{
177 201
178#endif 202#endif
179 203
180///////////////////////////////////////////////////////////////////////////// 204/////////////////////////////////////////////////////////////////////////////
181 205
206void
207rxvt_screen::set (rxvt_display *disp)
208{
209 display = disp;
210 xdisp = disp->display;
211
212 Screen *screen = ScreenOfDisplay (xdisp, disp->screen);
213
214 depth = DefaultDepthOfScreen (screen);
215 visual = DefaultVisualOfScreen (screen);
216 cmap = DefaultColormapOfScreen (screen);
217}
218
219void
220rxvt_screen::set (rxvt_display *disp, int bitdepth)
221{
222 set (disp);
223
224#if XFT
225 XVisualInfo vinfo;
226
227 if (XMatchVisualInfo (xdisp, display->screen, bitdepth, TrueColor, &vinfo))
228 {
229 depth = bitdepth;
230 visual = vinfo.visual;
231 cmap = XCreateColormap (xdisp, disp->root, visual, AllocNone);
232 }
233#endif
234}
235
236void
237rxvt_screen::clear ()
238{
239 if (cmap != DefaultColormapOfScreen (ScreenOfDisplay (xdisp, display->screen)))
240 XFreeColormap (xdisp, cmap);
241}
242
243/////////////////////////////////////////////////////////////////////////////
244
182rxvt_display::rxvt_display (const char *id) 245rxvt_display::rxvt_display (const char *id)
183: refcounted (id) 246: refcounted (id)
184, x_ev (this, &rxvt_display::x_cb) 247, x_ev (this, &rxvt_display::x_cb)
185, selection_owner (0) 248, selection_owner (0)
186{ 249{
287 if (!display) 350 if (!display)
288 return false; 351 return false;
289 352
290 screen = DefaultScreen (display); 353 screen = DefaultScreen (display);
291 root = DefaultRootWindow (display); 354 root = DefaultRootWindow (display);
292 visual = DefaultVisual (display, screen);
293 cmap = DefaultColormap (display, screen);
294 depth = DefaultDepth (display, screen);
295 355
296 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA); 356 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA);
297 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa); 357 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa);
298 358
299 XrmSetDatabase (display, get_resources ()); 359 XrmSetDatabase (display, get_resources ());
307 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ', 367 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ',
308 &blackcolour, &blackcolour); 368 &blackcolour, &blackcolour);
309 XUnloadFont (display, f); 369 XUnloadFont (display, f);
310#endif 370#endif
311 371
312#ifdef PREFER_24BIT
313 /*
314 * If depth is not 24, look for a 24bit visual.
315 */
316 if (depth != 24)
317 {
318 XVisualInfo vinfo;
319
320 if (XMatchVisualInfo (display, screen, 24, TrueColor, &vinfo))
321 {
322 depth = 24;
323 visual = vinfo.visual;
324 cmap = XCreateColormap (display,
325 RootWindow (display, screen),
326 visual, AllocNone);
327 }
328 }
329#endif
330
331 int fd = XConnectionNumber (display); 372 int fd = XConnectionNumber (display);
332 373
333#ifndef NO_SLOW_LINK_SUPPORT 374#ifndef NO_SLOW_LINK_SUPPORT
334 // try to detect wether we have a local connection. 375 // try to detect wether we have a local connection.
335 // assume unix domains socket == local, everything else not 376 // assume unix domains socket == local, everything else not
517 558
518template class refcache<rxvt_display>; 559template class refcache<rxvt_display>;
519refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
520 561
521///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
522 563
523bool 564bool
524rxvt_color::set (rxvt_display *display, Pixel p) 565rxvt_color::alloc (rxvt_screen *screen, rxvt_rgba rgba)
525{ 566{
526#if XFT 567#if XFT
527 XColor xc; 568 XRenderPictFormat *format;
528 569
529 xc.pixel = p; 570 // FUCKING Xft gets it wrong, of course, so work around it
530 if (!XQueryColor (display->display, display->cmap, &xc)) 571 // transparency users should eat shit and die, and then
531 return false; 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;
532 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 {
533 XRenderColor d; 591 XRenderColor d;
534 592
535 d.red = xc.red; 593 d.red = rgba.r;
536 d.green = xc.green; 594 d.green = rgba.g;
537 d.blue = xc.blue; 595 d.blue = rgba.b;
538 d.alpha = 0xffff; 596 d.alpha = rgba.a;
539 597
540 return 598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
541 XftColorAllocValue (display->display, 599 }
542 display->visual,
543 display->cmap,
544 &d, &c);
545#else 600#else
546 this->p = p; 601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
547#endif 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 );
548 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;
549 return true; 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;
550} 633}
551 634
552bool 635bool
553rxvt_color::set (rxvt_display *display, const char *name) 636rxvt_color::set (rxvt_screen *screen, const char *name)
637{
638 rxvt_rgba c;
639 char eos;
640 int skip;
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
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 }
676 }
677
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)
692 {
693 XColor *colors = new XColor [screen->visual->map_entries];
694
695 for (int i = 0; i < cmap_size; i++)
696 colors [i].pixel = i;
697
698 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
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
728void
729rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba)
554{ 730{
555#if XFT 731#if XFT
556 return XftColorAllocName (display->display, display->visual, display->cmap,
557 name, &c);
558#else
559 XColor xc;
560
561 if (XParseColor (display->display, display->cmap, name, &xc))
562 return set (display, xc.red, xc.green, xc.blue);
563
564 return false;
565#endif
566}
567
568bool
569rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
570{
571 XColor xc;
572
573 xc.red = cr;
574 xc.green = cg;
575 xc.blue = cb;
576 xc.flags = DoRed | DoGreen | DoBlue;
577
578 if (XAllocColor (display->display, display->cmap, &xc))
579 return set (display, xc.pixel);
580
581 return false;
582}
583
584void
585rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
586{
587#if XFT
588 cr = c.color.red; 732 rgba.r = c.color.red;
589 cg = c.color.green; 733 rgba.g = c.color.green;
590 cb = c.color.blue; 734 rgba.b = c.color.blue;
735 rgba.a = c.color.alpha;
591#else 736#else
592 XColor c; 737 XColor c;
593 738
594 c.pixel = p; 739 c.pixel = p;
595 XQueryColor (display->display, display->cmap, &c); 740 XQueryColor (screen->xdisp, screen->cmap, &c);
596 741
597 cr = c.red; 742 rgba.r = c.red;
598 cg = c.green; 743 rgba.g = c.green;
599 cb = c.blue; 744 rgba.b = c.blue;
745 rgba.a = rxvt_rgba::MAX_CC;
600#endif 746#endif
601} 747}
602 748
603void 749void
604rxvt_color::free (rxvt_display *display) 750rxvt_color::free (rxvt_screen *screen)
605{ 751{
606#if XFT 752#if XFT
607 XftColorFree (display->display, display->visual, display->cmap, &c); 753 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
608#else 754#else
609 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes); 755 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
610#endif 756#endif
611} 757}
612 758
613rxvt_color 759rxvt_color
614rxvt_color::fade (rxvt_display *display, int percent) 760rxvt_color::fade (rxvt_screen *screen, int percent)
615{ 761{
616 percent = 100 - percent;
617
618 unsigned short cr, cg, cb;
619 rxvt_color faded; 762 rxvt_color faded;
620 763
621 get (display, cr, cg, cb); 764 rxvt_rgba c;
765 get (screen, c);
622 766
623 faded.set ( 767 c.r = lerp (0, c.r, percent);
624 display, 768 c.g = lerp (0, c.g, percent);
625 cr * percent / 100, 769 c.b = lerp (0, c.b, percent);
626 cg * percent / 100, 770
627 cb * percent / 100 771 faded.set (screen, c);
628 );
629 772
630 return faded; 773 return faded;
631} 774}
632 775
633#define LERP(a,b,p) (a * p + b * (100 - p)) / 100
634
635rxvt_color 776rxvt_color
636rxvt_color::fade (rxvt_display *display, int percent, rxvt_color &fadeto) 777rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
637{ 778{
638 percent = 100 - percent; 779 rxvt_rgba c, fc;
639
640 unsigned short cr, cg, cb;
641 unsigned short fcr, fcg, fcb;
642 rxvt_color faded; 780 rxvt_color faded;
643 781
644 get (display, cr, cg, cb); 782 get (screen, c);
645 fadeto.get(display, fcr, fcg, fcb); 783 fadeto.get (screen, fc);
646 784
647 faded.set ( 785 faded.set (
648 display, 786 screen,
787 rxvt_rgba (
649 LERP (cr, fcr, percent), 788 lerp (fc.r, c.r, percent),
650 LERP (cg, fcg, percent), 789 lerp (fc.g, c.g, percent),
651 LERP (cb, fcb, percent) 790 lerp (fc.b, c.b, percent),
791 lerp (fc.a, c.a, percent)
792 )
652 ); 793 );
653 794
654 return faded; 795 return faded;
655} 796}
656 797

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines