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.23 by root, Wed Jan 11 00:59:58 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
41const char *const xa_names[] =
42{
43 "TEXT",
44 "COMPOUND_TEXT",
45 "UTF8_STRING",
46 "MULTIPLE",
47 "TARGETS",
48 "TIMESTAMP",
49 "VT_SELECTION",
50 "INCR",
51 "WM_PROTOCOLS",
52 "WM_DELETE_WINDOW",
53 "CLIPBOARD",
54 "AVERAGE_WIDTH",
55 "WEIGHT_NAME",
56 "SLANT",
57 "CHARSET_REGISTRY",
58 "CHARSET_ENCODING",
59#if ENABLE_FRILLS
60 "_MOTIF_WM_HINTS",
61#endif
62#if ENABLE_EWMH
63 "_NET_WM_PID",
64 "_NET_WM_NAME",
65 "_NET_WM_ICON_NAME",
66 "_NET_WM_PING",
67#endif
68#if USE_XIM
69 "WM_LOCALE_NAME",
70 "XIM_SERVERS",
71#endif
72#ifdef TRANSPARENT
73 "_XROOTPMAP_ID",
74 "ESETROOT_PMAP_ID",
75#endif
76#if ENABLE_XEMBED
77 "_XEMBED",
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",
93# endif
94#endif
95};
96
97/////////////////////////////////////////////////////////////////////////////
98
37refcounted::refcounted (const char *id) 99refcounted::refcounted (const char *id)
38{ 100{
39 this->id = strdup (id); 101 this->id = strdup (id);
40} 102}
41 103
93} 155}
94 156
95///////////////////////////////////////////////////////////////////////////// 157/////////////////////////////////////////////////////////////////////////////
96 158
97#ifdef USE_XIM 159#ifdef USE_XIM
160
98static void 161static void
99#if XIMCB_PROTO_BROKEN 162#if XIMCB_PROTO_BROKEN
100im_destroy_cb (XIC unused1, XPointer client_data, XPointer unused3) 163im_destroy_cb (XIC unused1, XPointer client_data, XPointer unused3)
101#else 164#else
102im_destroy_cb (XIM unused1, XPointer client_data, XPointer unused3) 165im_destroy_cb (XIM unused1, XPointer client_data, XPointer unused3)
133rxvt_xim::~rxvt_xim () 196rxvt_xim::~rxvt_xim ()
134{ 197{
135 if (xim) 198 if (xim)
136 XCloseIM (xim); 199 XCloseIM (xim);
137} 200}
201
138#endif 202#endif
203
204/////////////////////////////////////////////////////////////////////////////
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}
139 242
140///////////////////////////////////////////////////////////////////////////// 243/////////////////////////////////////////////////////////////////////////////
141 244
142rxvt_display::rxvt_display (const char *id) 245rxvt_display::rxvt_display (const char *id)
143: refcounted (id) 246: refcounted (id)
247 if (!display) 350 if (!display)
248 return false; 351 return false;
249 352
250 screen = DefaultScreen (display); 353 screen = DefaultScreen (display);
251 root = DefaultRootWindow (display); 354 root = DefaultRootWindow (display);
252 visual = DefaultVisual (display, screen); 355
253 cmap = DefaultColormap (display, screen); 356 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA);
254 depth = DefaultDepth (display, screen); 357 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa);
255 358
256 XrmSetDatabase (display, get_resources ()); 359 XrmSetDatabase (display, get_resources ());
257 360
258#ifdef POINTER_BLANK 361#ifdef POINTER_BLANK
259 XColor blackcolour; 362 XColor blackcolour;
264 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ', 367 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ',
265 &blackcolour, &blackcolour); 368 &blackcolour, &blackcolour);
266 XUnloadFont (display, f); 369 XUnloadFont (display, f);
267#endif 370#endif
268 371
269#ifdef PREFER_24BIT
270 /*
271 * If depth is not 24, look for a 24bit visual.
272 */
273 if (depth != 24)
274 {
275 XVisualInfo vinfo;
276
277 if (XMatchVisualInfo (display, screen, 24, TrueColor, &vinfo))
278 {
279 depth = 24;
280 visual = vinfo.visual;
281 cmap = XCreateColormap (display,
282 RootWindow (display, screen),
283 visual, AllocNone);
284 }
285 }
286#endif
287
288 int fd = XConnectionNumber (display); 372 int fd = XConnectionNumber (display);
289 373
290#ifndef NO_SLOW_LINK_SUPPORT 374#ifndef NO_SLOW_LINK_SUPPORT
291 // try to detect wether we have a local connection. 375 // try to detect wether we have a local connection.
292 // assume unix domains socket == local, everything else not 376 // assume unix domains socket == local, everything else not
301 385
302 x_ev.start (fd, EVENT_READ); 386 x_ev.start (fd, EVENT_READ);
303 fcntl (fd, F_SETFD, FD_CLOEXEC); 387 fcntl (fd, F_SETFD, FD_CLOEXEC);
304 388
305 XSelectInput (display, root, PropertyChangeMask); 389 XSelectInput (display, root, PropertyChangeMask);
306#ifdef USE_XIM
307 xa_xim_servers = XInternAtom (display, "XIM_SERVERS", 0);
308#endif
309 390
310 flush (); 391 flush ();
311 392
312 return true; 393 return true;
313} 394}
349 // registers, as xlib crashes due to a race otherwise. 430 // registers, as xlib crashes due to a race otherwise.
350 Atom actual_type, *atoms; 431 Atom actual_type, *atoms;
351 int actual_format; 432 int actual_format;
352 unsigned long nitems, bytes_after; 433 unsigned long nitems, bytes_after;
353 434
354 if (XGetWindowProperty (display, root, xa_xim_servers, 0L, 1000000L, 435 if (XGetWindowProperty (display, root, xa[XA_XIM_SERVERS], 0L, 1000000L,
355 False, XA_ATOM, &actual_type, &actual_format, 436 False, XA_ATOM, &actual_type, &actual_format,
356 &nitems, &bytes_after, (unsigned char **)&atoms) 437 &nitems, &bytes_after, (unsigned char **)&atoms)
357 != Success ) 438 != Success )
358 return; 439 return;
359 440
379#ifdef USE_XIM 460#ifdef USE_XIM
380 if (!XFilterEvent (&xev, None)) 461 if (!XFilterEvent (&xev, None))
381 { 462 {
382 if (xev.type == PropertyNotify 463 if (xev.type == PropertyNotify
383 && xev.xany.window == root 464 && xev.xany.window == root
384 && xev.xproperty.atom == xa_xim_servers) 465 && xev.xproperty.atom == xa[XA_XIM_SERVERS])
385 im_change_check (); 466 im_change_check ();
386#endif 467#endif
387 for (int i = xw.size (); i--; ) 468 for (int i = xw.size (); i--; )
388 { 469 {
389 if (!xw[i]) 470 if (!xw[i])
477 558
478template class refcache<rxvt_display>; 559template class refcache<rxvt_display>;
479refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
480 561
481///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
482 563
483bool 564bool
484rxvt_color::set (rxvt_display *display, Pixel p) 565rxvt_color::alloc (rxvt_screen *screen, rxvt_rgba rgba)
485{ 566{
486#if XFT 567#if XFT
487 XColor xc; 568 XRenderPictFormat *format;
488 569
489 xc.pixel = p; 570 // FUCKING Xft gets it wrong, of course, so work around it
490 if (!XQueryColor (display->display, display->cmap, &xc)) 571 // transparency users should eat shit and die, and then
491 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;
492 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 {
493 XRenderColor d; 591 XRenderColor d;
494 592
495 d.red = xc.red; 593 d.red = rgba.r;
496 d.green = xc.green; 594 d.green = rgba.g;
497 d.blue = xc.blue; 595 d.blue = rgba.b;
498 d.alpha = 0xffff; 596 d.alpha = rgba.a;
499 597
500 return 598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
501 XftColorAllocValue (display->display, 599 }
502 display->visual,
503 display->cmap,
504 &d, &c);
505#else 600#else
506 this->p = p; 601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
507#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 );
508 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;
509 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;
510} 633}
511 634
512bool 635bool
513rxvt_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)
514{ 723{
515#if XFT 724#if XFT
516 return XftColorAllocName (display->display, display->visual, display->cmap,
517 name, &c);
518#else
519 XColor xc;
520
521 if (XParseColor (display->display, display->cmap, name, &xc))
522 return set (display, xc.red, xc.green, xc.blue);
523
524 return false;
525#endif
526}
527
528bool
529rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
530{
531 XColor xc;
532
533 xc.red = cr;
534 xc.green = cg;
535 xc.blue = cb;
536 xc.flags = DoRed | DoGreen | DoBlue;
537
538 if (XAllocColor (display->display, display->cmap, &xc))
539 return set (display, xc.pixel);
540
541 return false;
542}
543
544void
545rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
546{
547#if XFT
548 cr = c.color.red; 725 rgba.r = c.color.red;
549 cg = c.color.green; 726 rgba.g = c.color.green;
550 cb = c.color.blue; 727 rgba.b = c.color.blue;
728 rgba.a = c.color.alpha;
551#else 729#else
552 XColor c; 730 XColor c;
553 731
554 c.pixel = p; 732 c.pixel = p;
555 XQueryColor (display->display, display->cmap, &c); 733 XQueryColor (screen->xdisp, screen->cmap, &c);
556 734
557 cr = c.red; 735 rgba.r = c.red;
558 cg = c.green; 736 rgba.g = c.green;
559 cb = c.blue; 737 rgba.b = c.blue;
738 rgba.a = rxvt_rgba::MAX_CC;
560#endif 739#endif
561} 740}
562 741
563void 742void
564rxvt_color::free (rxvt_display *display) 743rxvt_color::free (rxvt_screen *screen)
565{ 744{
566#if XFT 745#if XFT
567 XftColorFree (display->display, display->visual, display->cmap, &c); 746 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
568#else 747#else
569 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes); 748 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
570#endif 749#endif
571} 750}
572 751
573rxvt_color 752rxvt_color
574rxvt_color::fade (rxvt_display *display, int percent) 753rxvt_color::fade (rxvt_screen *screen, int percent)
575{ 754{
576 percent = 100 - percent;
577
578 unsigned short cr, cg, cb;
579 rxvt_color faded; 755 rxvt_color faded;
580 756
581 get (display, cr, cg, cb); 757 rxvt_rgba c;
758 get (screen, c);
582 759
583 faded.set ( 760 c.r = lerp (0, c.r, percent);
584 display, 761 c.g = lerp (0, c.g, percent);
585 cr * percent / 100, 762 c.b = lerp (0, c.b, percent);
586 cg * percent / 100, 763
587 cb * percent / 100 764 faded.set (screen, c);
588 );
589 765
590 return faded; 766 return faded;
591} 767}
592 768
593#define LERP(a,b,p) (a * p + b * (100 - p)) / 100
594
595rxvt_color 769rxvt_color
596rxvt_color::fade (rxvt_display *display, int percent, rxvt_color &fadeto) 770rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
597{ 771{
598 percent = 100 - percent; 772 rxvt_rgba c, fc;
599
600 unsigned short cr, cg, cb;
601 unsigned short fcr, fcg, fcb;
602 rxvt_color faded; 773 rxvt_color faded;
603 774
604 get (display, cr, cg, cb); 775 get (screen, c);
605 fadeto.get(display, fcr, fcg, fcb); 776 fadeto.get (screen, fc);
606 777
607 faded.set ( 778 faded.set (
608 display, 779 screen,
780 rxvt_rgba (
609 LERP (cr, fcr, percent), 781 lerp (fc.r, c.r, percent),
610 LERP (cg, fcg, percent), 782 lerp (fc.g, c.g, percent),
611 LERP (cb, fcb, percent) 783 lerp (fc.b, c.b, percent),
784 lerp (fc.a, c.a, percent)
785 )
612 ); 786 );
613 787
614 return faded; 788 return faded;
615} 789}
616 790

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines