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.38 by root, Mon Jan 30 19:46:13 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 int l = strlen (name);
639 rxvt_rgba r;
640 char eos;
641 int mult;
642 XColor xc, xc_exact;
643
644 // parse a number of non-standard ARGB colour specifications
645 if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
646 mult = rxvt_rgba::MAX_CC / 0x0010;
647 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
648 mult = rxvt_rgba::MAX_CC / 0x0100;
649 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
650 mult = rxvt_rgba::MAX_CC / 0x0100;
651 else if (l == 4+5*4 && 4 == sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
652 mult = rxvt_rgba::MAX_CC / 0xffff;
653 else if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
654 {
655 r.r = xc.red;
656 r.g = xc.green;
657 r.b = xc.blue;
658 mult = rxvt_rgba::MAX_CC / 0xffff;
659 }
660 else
661 {
662 rxvt_warn ("failed to allocate color '%s', using pink instead.\n", name);
663 r.r = 255;
664 r.g = 105;
665 r.b = 180;
666 mult = rxvt_rgba::MAX_CC / 0x00ff;
667 }
668
669 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult;
670
671 return set (screen, r);
672}
673
674bool
675rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
676{
677 bool got = alloc (screen, rgba);
678
679#if !ENABLE_MINIMAL
680 int cmap_size = screen->visual->map_entries;
681
682 if (!got
683 && screen->visual->c_class == PseudoColor
684 && cmap_size < 4096)
685 {
686 XColor *colors = new XColor [screen->visual->map_entries];
687
688 for (int i = 0; i < cmap_size; i++)
689 colors [i].pixel = i;
690
691 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
692
693 int diff = 0x7fffffffUL;
694 XColor *best = colors;
695
696 for (int i = 0; i < cmap_size; i++)
697 {
698 int d = (squared_diff<int> (rgba.r >> 2, colors [i].red >> 2))
699 + (squared_diff<int> (rgba.g >> 2, colors [i].green >> 2))
700 + (squared_diff<int> (rgba.b >> 2, colors [i].blue >> 2));
701
702 if (d < diff)
703 {
704 diff = d;
705 best = colors + i;
706 }
707 }
708
709 //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n",
710 // rgba.r, rgba.g, rgba.b, best->red, best->green, best->blue, diff);
711
712 got = alloc (screen, rxvt_rgba (best->red, best->green, best->blue));
713
714 delete colors;
715 }
716#endif
717
718 return got;
719}
720
721void
722rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba)
554{ 723{
555#if XFT 724#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; 725 rgba.r = c.color.red;
589 cg = c.color.green; 726 rgba.g = c.color.green;
590 cb = c.color.blue; 727 rgba.b = c.color.blue;
728 rgba.a = c.color.alpha;
591#else 729#else
592 XColor c; 730 XColor c;
593 731
594 c.pixel = p; 732 c.pixel = p;
595 XQueryColor (display->display, display->cmap, &c); 733 XQueryColor (screen->xdisp, screen->cmap, &c);
596 734
597 cr = c.red; 735 rgba.r = c.red;
598 cg = c.green; 736 rgba.g = c.green;
599 cb = c.blue; 737 rgba.b = c.blue;
738 rgba.a = rxvt_rgba::MAX_CC;
600#endif 739#endif
601} 740}
602 741
603void 742void
604rxvt_color::free (rxvt_display *display) 743rxvt_color::free (rxvt_screen *screen)
605{ 744{
606#if XFT 745#if XFT
607 XftColorFree (display->display, display->visual, display->cmap, &c); 746 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
608#else 747#else
609 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes); 748 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
610#endif 749#endif
611} 750}
612 751
613rxvt_color 752rxvt_color
614rxvt_color::fade (rxvt_display *display, int percent) 753rxvt_color::fade (rxvt_screen *screen, int percent)
615{ 754{
616 percent = 100 - percent;
617
618 unsigned short cr, cg, cb;
619 rxvt_color faded; 755 rxvt_color faded;
620 756
621 get (display, cr, cg, cb); 757 rxvt_rgba c;
758 get (screen, c);
622 759
623 faded.set ( 760 c.r = lerp (0, c.r, percent);
624 display, 761 c.g = lerp (0, c.g, percent);
625 cr * percent / 100, 762 c.b = lerp (0, c.b, percent);
626 cg * percent / 100, 763
627 cb * percent / 100 764 faded.set (screen, c);
628 );
629 765
630 return faded; 766 return faded;
631} 767}
632 768
633#define LERP(a,b,p) (a * p + b * (100 - p)) / 100
634
635rxvt_color 769rxvt_color
636rxvt_color::fade (rxvt_display *display, int percent, rxvt_color &fadeto) 770rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
637{ 771{
638 percent = 100 - percent; 772 rxvt_rgba c, fc;
639
640 unsigned short cr, cg, cb;
641 unsigned short fcr, fcg, fcb;
642 rxvt_color faded; 773 rxvt_color faded;
643 774
644 get (display, cr, cg, cb); 775 get (screen, c);
645 fadeto.get(display, fcr, fcg, fcb); 776 fadeto.get (screen, fc);
646 777
647 faded.set ( 778 faded.set (
648 display, 779 screen,
780 rxvt_rgba (
649 LERP (cr, fcr, percent), 781 lerp (fc.r, c.r, percent),
650 LERP (cg, fcg, percent), 782 lerp (fc.g, c.g, percent),
651 LERP (cb, fcb, percent) 783 lerp (fc.b, c.b, percent),
784 lerp (fc.a, c.a, percent)
785 )
652 ); 786 );
653 787
654 return faded; 788 return faded;
655} 789}
656 790

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines