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.24 by root, Wed Jan 25 00:42:21 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
139 201
140#endif 202#endif
141 203
142///////////////////////////////////////////////////////////////////////////// 204/////////////////////////////////////////////////////////////////////////////
143 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
144rxvt_display::rxvt_display (const char *id) 245rxvt_display::rxvt_display (const char *id)
145: refcounted (id) 246: refcounted (id)
146, x_ev (this, &rxvt_display::x_cb) 247, x_ev (this, &rxvt_display::x_cb)
147, selection_owner (0) 248, selection_owner (0)
148{ 249{
249 if (!display) 350 if (!display)
250 return false; 351 return false;
251 352
252 screen = DefaultScreen (display); 353 screen = DefaultScreen (display);
253 root = DefaultRootWindow (display); 354 root = DefaultRootWindow (display);
254 visual = DefaultVisual (display, screen); 355
255 cmap = DefaultColormap (display, screen); 356 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA);
256 depth = DefaultDepth (display, screen); 357 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa);
257 358
258 XrmSetDatabase (display, get_resources ()); 359 XrmSetDatabase (display, get_resources ());
259 360
260#ifdef POINTER_BLANK 361#ifdef POINTER_BLANK
261 XColor blackcolour; 362 XColor blackcolour;
266 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ', 367 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ',
267 &blackcolour, &blackcolour); 368 &blackcolour, &blackcolour);
268 XUnloadFont (display, f); 369 XUnloadFont (display, f);
269#endif 370#endif
270 371
271#ifdef PREFER_24BIT
272 /*
273 * If depth is not 24, look for a 24bit visual.
274 */
275 if (depth != 24)
276 {
277 XVisualInfo vinfo;
278
279 if (XMatchVisualInfo (display, screen, 24, TrueColor, &vinfo))
280 {
281 depth = 24;
282 visual = vinfo.visual;
283 cmap = XCreateColormap (display,
284 RootWindow (display, screen),
285 visual, AllocNone);
286 }
287 }
288#endif
289
290 int fd = XConnectionNumber (display); 372 int fd = XConnectionNumber (display);
291 373
292#ifndef NO_SLOW_LINK_SUPPORT 374#ifndef NO_SLOW_LINK_SUPPORT
293 // try to detect wether we have a local connection. 375 // try to detect wether we have a local connection.
294 // assume unix domains socket == local, everything else not 376 // assume unix domains socket == local, everything else not
303 385
304 x_ev.start (fd, EVENT_READ); 386 x_ev.start (fd, EVENT_READ);
305 fcntl (fd, F_SETFD, FD_CLOEXEC); 387 fcntl (fd, F_SETFD, FD_CLOEXEC);
306 388
307 XSelectInput (display, root, PropertyChangeMask); 389 XSelectInput (display, root, PropertyChangeMask);
308#ifdef USE_XIM
309 xa_xim_servers = XInternAtom (display, "XIM_SERVERS", 0);
310#endif
311 390
312 flush (); 391 flush ();
313 392
314 return true; 393 return true;
315} 394}
351 // registers, as xlib crashes due to a race otherwise. 430 // registers, as xlib crashes due to a race otherwise.
352 Atom actual_type, *atoms; 431 Atom actual_type, *atoms;
353 int actual_format; 432 int actual_format;
354 unsigned long nitems, bytes_after; 433 unsigned long nitems, bytes_after;
355 434
356 if (XGetWindowProperty (display, root, xa_xim_servers, 0L, 1000000L, 435 if (XGetWindowProperty (display, root, xa[XA_XIM_SERVERS], 0L, 1000000L,
357 False, XA_ATOM, &actual_type, &actual_format, 436 False, XA_ATOM, &actual_type, &actual_format,
358 &nitems, &bytes_after, (unsigned char **)&atoms) 437 &nitems, &bytes_after, (unsigned char **)&atoms)
359 != Success ) 438 != Success )
360 return; 439 return;
361 440
381#ifdef USE_XIM 460#ifdef USE_XIM
382 if (!XFilterEvent (&xev, None)) 461 if (!XFilterEvent (&xev, None))
383 { 462 {
384 if (xev.type == PropertyNotify 463 if (xev.type == PropertyNotify
385 && xev.xany.window == root 464 && xev.xany.window == root
386 && xev.xproperty.atom == xa_xim_servers) 465 && xev.xproperty.atom == xa[XA_XIM_SERVERS])
387 im_change_check (); 466 im_change_check ();
388#endif 467#endif
389 for (int i = xw.size (); i--; ) 468 for (int i = xw.size (); i--; )
390 { 469 {
391 if (!xw[i]) 470 if (!xw[i])
479 558
480template class refcache<rxvt_display>; 559template class refcache<rxvt_display>;
481refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
482 561
483///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
484 563
485bool 564bool
486rxvt_color::set (rxvt_display *display, Pixel p) 565rxvt_color::alloc (rxvt_screen *screen, rxvt_rgba rgba)
487{ 566{
488#if XFT 567#if XFT
489 XColor xc; 568 XRenderPictFormat *format;
490 569
491 xc.pixel = p; 570 // FUCKING Xft gets it wrong, of course, so work around it
492 if (!XQueryColor (display->display, display->cmap, &xc)) 571 // transparency users should eat shit and die, and then
493 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;
494 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 {
495 XRenderColor d; 591 XRenderColor d;
496 592
497 d.red = xc.red; 593 d.red = rgba.r;
498 d.green = xc.green; 594 d.green = rgba.g;
499 d.blue = xc.blue; 595 d.blue = rgba.b;
500 d.alpha = 0xffff; 596 d.alpha = rgba.a;
501 597
502 return 598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
503 XftColorAllocValue (display->display, 599 }
504 display->visual,
505 display->cmap,
506 &d, &c);
507#else 600#else
508 this->p = p; 601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
509#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 );
510 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;
511 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;
512} 633}
513 634
514bool 635bool
515rxvt_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)
516{ 730{
517#if XFT 731#if XFT
518 return XftColorAllocName (display->display, display->visual, display->cmap,
519 name, &c);
520#else
521 XColor xc;
522
523 if (XParseColor (display->display, display->cmap, name, &xc))
524 return set (display, xc.red, xc.green, xc.blue);
525
526 return false;
527#endif
528}
529
530bool
531rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
532{
533 XColor xc;
534
535 xc.red = cr;
536 xc.green = cg;
537 xc.blue = cb;
538 xc.flags = DoRed | DoGreen | DoBlue;
539
540 if (XAllocColor (display->display, display->cmap, &xc))
541 return set (display, xc.pixel);
542
543 return false;
544}
545
546void
547rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
548{
549#if XFT
550 cr = c.color.red; 732 rgba.r = c.color.red;
551 cg = c.color.green; 733 rgba.g = c.color.green;
552 cb = c.color.blue; 734 rgba.b = c.color.blue;
735 rgba.a = c.color.alpha;
553#else 736#else
554 XColor c; 737 XColor c;
555 738
556 c.pixel = p; 739 c.pixel = p;
557 XQueryColor (display->display, display->cmap, &c); 740 XQueryColor (screen->xdisp, screen->cmap, &c);
558 741
559 cr = c.red; 742 rgba.r = c.red;
560 cg = c.green; 743 rgba.g = c.green;
561 cb = c.blue; 744 rgba.b = c.blue;
745 rgba.a = rxvt_rgba::MAX_CC;
562#endif 746#endif
563} 747}
564 748
565void 749void
566rxvt_color::free (rxvt_display *display) 750rxvt_color::free (rxvt_screen *screen)
567{ 751{
568#if XFT 752#if XFT
569 XftColorFree (display->display, display->visual, display->cmap, &c); 753 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
570#else 754#else
571 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes); 755 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
572#endif 756#endif
573} 757}
574 758
575rxvt_color 759rxvt_color
576rxvt_color::fade (rxvt_display *display, int percent) 760rxvt_color::fade (rxvt_screen *screen, int percent)
577{ 761{
578 percent = 100 - percent;
579
580 unsigned short cr, cg, cb;
581 rxvt_color faded; 762 rxvt_color faded;
582 763
583 get (display, cr, cg, cb); 764 rxvt_rgba c;
765 get (screen, c);
584 766
585 faded.set ( 767 c.r = lerp (0, c.r, percent);
586 display, 768 c.g = lerp (0, c.g, percent);
587 cr * percent / 100, 769 c.b = lerp (0, c.b, percent);
588 cg * percent / 100, 770
589 cb * percent / 100 771 faded.set (screen, c);
590 );
591 772
592 return faded; 773 return faded;
593} 774}
594 775
595#define LERP(a,b,p) (a * p + b * (100 - p)) / 100
596
597rxvt_color 776rxvt_color
598rxvt_color::fade (rxvt_display *display, int percent, rxvt_color &fadeto) 777rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
599{ 778{
600 percent = 100 - percent; 779 rxvt_rgba c, fc;
601
602 unsigned short cr, cg, cb;
603 unsigned short fcr, fcg, fcb;
604 rxvt_color faded; 780 rxvt_color faded;
605 781
606 get (display, cr, cg, cb); 782 get (screen, c);
607 fadeto.get(display, fcr, fcg, fcb); 783 fadeto.get (screen, fc);
608 784
609 faded.set ( 785 faded.set (
610 display, 786 screen,
787 rxvt_rgba (
611 LERP (cr, fcr, percent), 788 lerp (fc.r, c.r, percent),
612 LERP (cg, fcg, percent), 789 lerp (fc.g, c.g, percent),
613 LERP (cb, fcb, percent) 790 lerp (fc.b, c.b, percent),
791 lerp (fc.a, c.a, percent)
792 )
614 ); 793 );
615 794
616 return faded; 795 return faded;
617} 796}
618 797

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines