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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines