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.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
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 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)
514{ 730{
515#if XFT 731#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; 732 rgba.r = c.color.red;
549 cg = c.color.green; 733 rgba.g = c.color.green;
550 cb = c.color.blue; 734 rgba.b = c.color.blue;
735 rgba.a = c.color.alpha;
551#else 736#else
552 XColor c; 737 XColor c;
553 738
554 c.pixel = p; 739 c.pixel = p;
555 XQueryColor (display->display, display->cmap, &c); 740 XQueryColor (screen->xdisp, screen->cmap, &c);
556 741
557 cr = c.red; 742 rgba.r = c.red;
558 cg = c.green; 743 rgba.g = c.green;
559 cb = c.blue; 744 rgba.b = c.blue;
745 rgba.a = rxvt_rgba::MAX_CC;
560#endif 746#endif
561} 747}
562 748
563void 749void
564rxvt_color::free (rxvt_display *display) 750rxvt_color::free (rxvt_screen *screen)
565{ 751{
566#if XFT 752#if XFT
567 XftColorFree (display->display, display->visual, display->cmap, &c); 753 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
568#else 754#else
569 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes); 755 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
570#endif 756#endif
571} 757}
572 758
573rxvt_color 759rxvt_color
574rxvt_color::fade (rxvt_display *display, int percent) 760rxvt_color::fade (rxvt_screen *screen, int percent)
575{ 761{
576 percent = 100 - percent;
577
578 unsigned short cr, cg, cb;
579 rxvt_color faded; 762 rxvt_color faded;
580 763
581 get (display, cr, cg, cb); 764 rxvt_rgba c;
765 get (screen, c);
582 766
583 faded.set ( 767 c.r = lerp (0, c.r, percent);
584 display, 768 c.g = lerp (0, c.g, percent);
585 cr * percent / 100, 769 c.b = lerp (0, c.b, percent);
586 cg * percent / 100, 770
587 cb * percent / 100 771 faded.set (screen, c);
588 );
589 772
590 return faded; 773 return faded;
591} 774}
592 775
593#define LERP(a,b,p) (a * p + b * (100 - p)) / 100
594
595rxvt_color 776rxvt_color
596rxvt_color::fade (rxvt_display *display, int percent, rxvt_color &fadeto) 777rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
597{ 778{
598 percent = 100 - percent; 779 rxvt_rgba c, fc;
599
600 unsigned short cr, cg, cb;
601 unsigned short fcr, fcg, fcb;
602 rxvt_color faded; 780 rxvt_color faded;
603 781
604 get (display, cr, cg, cb); 782 get (screen, c);
605 fadeto.get(display, fcr, fcg, fcb); 783 fadeto.get (screen, fc);
606 784
607 faded.set ( 785 faded.set (
608 display, 786 screen,
787 rxvt_rgba (
609 LERP (cr, fcr, percent), 788 lerp (fc.r, c.r, percent),
610 LERP (cg, fcg, percent), 789 lerp (fc.g, c.g, percent),
611 LERP (cb, fcb, percent) 790 lerp (fc.b, c.b, percent),
791 lerp (fc.a, c.a, percent)
792 )
612 ); 793 );
613 794
614 return faded; 795 return faded;
615} 796}
616 797

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines