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.31 by root, Sun Jan 29 22:27:04 2006 UTC vs.
Revision 1.49 by root, Thu Feb 2 14:41:00 2006 UTC

37#if XFT 37#if XFT
38# include <X11/extensions/Xrender.h> 38# include <X11/extensions/Xrender.h>
39#endif 39#endif
40 40
41const char *const xa_names[] = 41const char *const xa_names[] =
42 { 42{
43 "TEXT", 43 "TEXT",
44 "COMPOUND_TEXT", 44 "COMPOUND_TEXT",
45 "UTF8_STRING", 45 "UTF8_STRING",
46 "MULTIPLE", 46 "MULTIPLE",
47 "TARGETS", 47 "TARGETS",
48 "TIMESTAMP", 48 "TIMESTAMP",
49 "VT_SELECTION", 49 "VT_SELECTION",
50 "INCR", 50 "INCR",
51 "WM_PROTOCOLS", 51 "WM_PROTOCOLS",
52 "WM_DELETE_WINDOW", 52 "WM_DELETE_WINDOW",
53 "CLIPBOARD", 53 "CLIPBOARD",
54 "AVERAGE_WIDTH",
55 "WEIGHT_NAME",
56 "SLANT",
57 "CHARSET_REGISTRY",
58 "CHARSET_ENCODING",
54#if ENABLE_FRILLS 59#if ENABLE_FRILLS
55 "_MOTIF_WM_HINTS", 60 "_MOTIF_WM_HINTS",
56#endif 61#endif
57#if ENABLE_EWMH 62#if ENABLE_EWMH
58 "_NET_WM_PID", 63 "_NET_WM_PID",
59 "_NET_WM_NAME", 64 "_NET_WM_NAME",
60 "_NET_WM_ICON_NAME", 65 "_NET_WM_ICON_NAME",
61 "_NET_WM_PING", 66 "_NET_WM_PING",
62#endif 67#endif
63#if USE_XIM 68#if USE_XIM
64 "WM_LOCALE_NAME", 69 "WM_LOCALE_NAME",
65 "XIM_SERVERS", 70 "XIM_SERVERS",
66#endif 71#endif
67#ifdef TRANSPARENT 72#ifdef TRANSPARENT
68 "_XROOTPMAP_ID", 73 "_XROOTPMAP_ID",
69 "ESETROOT_PMAP_ID", 74 "ESETROOT_PMAP_ID",
70#endif 75#endif
71#if ENABLE_XEMBED 76#if ENABLE_XEMBED
72 "_XEMBED", 77 "_XEMBED",
73 "_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",
74#endif 93# endif
75 }; 94#endif
95};
76 96
77///////////////////////////////////////////////////////////////////////////// 97/////////////////////////////////////////////////////////////////////////////
78 98
79refcounted::refcounted (const char *id) 99refcounted::refcounted (const char *id)
80{ 100{
157bool 177bool
158rxvt_xim::ref_init () 178rxvt_xim::ref_init ()
159{ 179{
160 display = GET_R->display; //HACK: TODO 180 display = GET_R->display; //HACK: TODO
161 181
162 xim = XOpenIM (display->display, NULL, NULL, NULL); 182 xim = XOpenIM (display->display, 0, 0, 0);
163 183
164 if (!xim) 184 if (!xim)
165 return false; 185 return false;
166 186
167 XIMCallback ximcallback; 187 XIMCallback ximcallback;
168 ximcallback.client_data = (XPointer)this; 188 ximcallback.client_data = (XPointer)this;
169 ximcallback.callback = im_destroy_cb; 189 ximcallback.callback = im_destroy_cb;
170 190
171 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL); 191 XSetIMValues (xim, XNDestroyCallback, &ximcallback, 0);
172 192
173 return true; 193 return true;
174} 194}
175 195
176rxvt_xim::~rxvt_xim () 196rxvt_xim::~rxvt_xim ()
228, selection_owner (0) 248, selection_owner (0)
229{ 249{
230} 250}
231 251
232XrmDatabase 252XrmDatabase
233rxvt_display::get_resources () 253rxvt_display::get_resources (bool refresh)
234{ 254{
235 char *homedir = (char *)getenv ("HOME"); 255 char *homedir = (char *)getenv ("HOME");
236 char fname[1024]; 256 char fname[1024];
237 257
238 /* 258 /*
239 * get resources using the X library function 259 * get resources using the X library function
240 */ 260 */
241 char *displayResource, *xe; 261 char *displayResource, *xe;
242 XrmDatabase database, rdb1; 262 XrmDatabase rdb1, database = 0;
243
244 database = NULL;
245 263
246 // for ordering, see for example http://www.faqs.org/faqs/Xt-FAQ/ Subject: 20 264 // for ordering, see for example http://www.faqs.org/faqs/Xt-FAQ/ Subject: 20
247 265
248 // 6. System wide per application default file. 266 // 6. System wide per application default file.
249 267
259 // 5. User's per application default file. 277 // 5. User's per application default file.
260 // none 278 // none
261 279
262 // 4. User's defaults file. 280 // 4. User's defaults file.
263 /* Get any Xserver defaults */ 281 /* Get any Xserver defaults */
282 if (refresh)
283 {
284 // fucking xlib keeps a copy of the rm string
285 Atom actual_type;
286 int actual_format;
287 unsigned long nitems, nremaining;
288 char *val = 0;
289
290#if XLIB_ILLEGAL_ACCESS
291 if (display->xdefaults)
292 XFree (display->xdefaults);
293#endif
294
295 if (XGetWindowProperty (display, root, XA_RESOURCE_MANAGER,
296 0L, 100000000L, False,
297 XA_STRING, &actual_type, &actual_format,
298 &nitems, &nremaining,
299 (unsigned char **)&val) == Success
300 && actual_type == XA_STRING
301 && actual_format == 8)
302 displayResource = val;
303 else
304 {
305 displayResource = 0;
306 if (val)
307 XFree(val);
308 }
309
310#if XLIB_ILLEGAL_ACCESS
311 display->xdefaults = displayResource;
312#endif
313 }
314 else
264 displayResource = XResourceManagerString (display); 315 displayResource = XResourceManagerString (display);
265 316
266 if (displayResource != NULL) 317 if (displayResource)
267 { 318 {
268 if ((rdb1 = XrmGetStringDatabase (displayResource))) 319 if ((rdb1 = XrmGetStringDatabase (displayResource)))
269 XrmMergeDatabases (rdb1, &database); 320 XrmMergeDatabases (rdb1, &database);
270 } 321 }
271 else if (homedir) 322 else if (homedir)
274 325
275 if ((rdb1 = XrmGetFileDatabase (fname))) 326 if ((rdb1 = XrmGetFileDatabase (fname)))
276 XrmMergeDatabases (rdb1, &database); 327 XrmMergeDatabases (rdb1, &database);
277 } 328 }
278 329
330#if !XLIB_ILLEGAL_ACCESS
331 if (refresh && displayResource)
332 XFree (displayResource);
333#endif
334
279 /* Get screen specific resources */ 335 /* Get screen specific resources */
280 displayResource = XScreenResourceString (ScreenOfDisplay (display, screen)); 336 displayResource = XScreenResourceString (ScreenOfDisplay (display, screen));
281 337
282 if (displayResource != NULL) 338 if (displayResource)
283 { 339 {
284 if ((rdb1 = XrmGetStringDatabase (displayResource))) 340 if ((rdb1 = XrmGetStringDatabase (displayResource)))
285 /* Merge with screen-independent resources */ 341 /* Merge with screen-independent resources */
286 XrmMergeDatabases (rdb1, &database); 342 XrmMergeDatabases (rdb1, &database);
287 343
328 display = XOpenDisplay (id); 384 display = XOpenDisplay (id);
329 385
330 if (!display) 386 if (!display)
331 return false; 387 return false;
332 388
333 screen = DefaultScreen (display); 389 screen = DefaultScreen (display);
334 root = DefaultRootWindow (display); 390 root = DefaultRootWindow (display);
335 391
336 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA); 392 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA);
337 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa); 393 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa);
338 394
339 XrmSetDatabase (display, get_resources ()); 395 XrmSetDatabase (display, get_resources (false));
340 396
341#ifdef POINTER_BLANK 397#ifdef POINTER_BLANK
342 XColor blackcolour; 398 XColor blackcolour;
343 blackcolour.red = 0; 399 blackcolour.red = 0;
344 blackcolour.green = 0; 400 blackcolour.green = 0;
375 431
376void 432void
377rxvt_display::ref_next () 433rxvt_display::ref_next ()
378{ 434{
379 // TODO: somehow check wether the database files/resources changed 435 // TODO: somehow check wether the database files/resources changed
380 // before re-loading/parsing 436 // before affording re-loading/parsing
381 XrmDestroyDatabase (XrmGetDatabase (display)); 437 XrmDestroyDatabase (XrmGetDatabase (display));
382 XrmSetDatabase (display, get_resources ()); 438 XrmSetDatabase (display, get_resources (true));
383} 439}
384 440
385rxvt_display::~rxvt_display () 441rxvt_display::~rxvt_display ()
386{ 442{
387 if (!display) 443 if (!display)
488 544
489 selection_owner = owner; 545 selection_owner = owner;
490} 546}
491 547
492#ifdef USE_XIM 548#ifdef USE_XIM
549
493void rxvt_display::reg (im_watcher *w) 550void rxvt_display::reg (im_watcher *w)
494{ 551{
495 imw.push_back (w); 552 imw.push_back (w);
496} 553}
497 554
521 return xim; 578 return xim;
522} 579}
523 580
524void rxvt_display::put_xim (rxvt_xim *xim) 581void rxvt_display::put_xim (rxvt_xim *xim)
525{ 582{
526#if XLIB_IS_RACEFREE 583# if XLIB_IS_RACEFREE
527 xims.put (xim); 584 xims.put (xim);
528#endif 585# endif
529} 586}
587
530#endif 588#endif
531 589
532Atom rxvt_display::atom (const char *name) 590Atom rxvt_display::atom (const char *name)
533{ 591{
534 return XInternAtom (display, name, False); 592 return XInternAtom (display, name, False);
538 596
539template class refcache<rxvt_display>; 597template class refcache<rxvt_display>;
540refcache<rxvt_display> displays; 598refcache<rxvt_display> displays;
541 599
542///////////////////////////////////////////////////////////////////////////// 600/////////////////////////////////////////////////////////////////////////////
543 601
602bool
603rxvt_color::alloc (rxvt_screen *screen, const rgba &color)
604{
605#if XFT
606 XRenderPictFormat *format;
607
608 // FUCKING Xft gets it wrong, of course, so work around it.
609 // Transparency users should eat shit and die, and then
610 // XRenderQueryPictIndexValues themselves plenty.
611 if ((screen->visual->c_class == TrueColor)
612 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
613 {
614 // the fun lies in doing everything manually...
615 c.color.red = color.r;
616 c.color.green = color.g;
617 c.color.blue = color.b;
618 c.color.alpha = color.a;
619
620 c.pixel = ((color.r * format->direct.redMask / rgba::MAX_CC) << format->direct.red )
621 | ((color.g * format->direct.greenMask / rgba::MAX_CC) << format->direct.green)
622 | ((color.b * format->direct.blueMask / rgba::MAX_CC) << format->direct.blue )
623 | ((color.a * format->direct.alphaMask / rgba::MAX_CC) << format->direct.alpha);
624
625 return true;
626 }
627 else
628 {
629 XRenderColor d;
630
631 d.red = color.r;
632 d.green = color.g;
633 d.blue = color.b;
634 d.alpha = color.a;
635
636 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
637 }
638#else
639 c.red = color.r;
640 c.green = color.g;
641 c.blue = color.b;
642
643 if (screen->visual->c_class == TrueColor)
644 {
645 c.pixel = (color.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask ))
646 / rgba::MAX_CC) << ctz (screen->visual->red_mask )
647 | (color.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask))
648 / rgba::MAX_CC) << ctz (screen->visual->green_mask)
649 | (color.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask ))
650 / rgba::MAX_CC) << ctz (screen->visual->blue_mask );
651
652 return true;
653 }
654 else if (XAllocColor (screen->xdisp, screen->cmap, &c))
655 return true;
656 else
657 c.pixel = (color.r + color.g + color.b) > 128*3
658 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->xdisp))
659 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->xdisp));
660#endif
661
662 return false;
663}
664
544bool 665bool
545rxvt_color::set (rxvt_screen *screen, const char *name) 666rxvt_color::set (rxvt_screen *screen, const char *name)
546{ 667{
668 rgba c;
669 char eos;
670 int skip;
671
672 // parse the nonstandard "[alphapercent]" prefix
673 if (1 <= sscanf (name, "[%hd]%n", &c.a, &skip))
674 {
675 c.a = lerp<int, int, int> (0, rgba::MAX_CC, c.a);
676 name += skip;
677 }
678 else
679 c.a = rgba::MAX_CC;
680
681 // parse the non-standard "rgba:rrrr/gggg/bbbb/aaaa" format
682 if (strlen (name) != 4+5*4 || 4 != sscanf (name, "rgba:%4hx/%4hx/%4hx/%4hx%c", &c.r, &c.g, &c.b, &c.a, &eos))
683 {
684 XColor xc, xc_exact;
685
686 if (XParseColor (screen->xdisp, screen->cmap, name, &xc))
687 {
688 c.r = xc.red;
689 c.g = xc.green;
690 c.b = xc.blue;
691 }
692 else
693 {
694 c.r = 0xffff;
695 c.g = 0x6969;
696 c.b = 0xb4b4;
697
698 rxvt_warn ("unable to parse color '%s', using pink instead.\n", name);
699 }
700 }
701
702 return set (screen, c);
703}
704
705bool
706rxvt_color::set (rxvt_screen *screen, const rgba &color)
707{
708 bool got = alloc (screen, color);
709
710#if !ENABLE_MINIMAL
711 int cmap_size = screen->visual->map_entries;
712
713 if (!got
714 && screen->visual->c_class == PseudoColor
715 && cmap_size < 4096)
716 {
717 XColor *colors = new XColor [screen->visual->map_entries];
718
719 for (int i = 0; i < cmap_size; i++)
720 colors [i].pixel = i;
721
722 // many kilobytes transfer per colour, but pseudocolor isn't worth
723 // many extra optimisations.
724 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size);
725
726 int diff = 0x7fffffffUL;
727 XColor *best = colors;
728
729 for (int i = 0; i < cmap_size; i++)
730 {
731 int d = (squared_diff<int> (color.r >> 2, colors [i].red >> 2))
732 + (squared_diff<int> (color.g >> 2, colors [i].green >> 2))
733 + (squared_diff<int> (color.b >> 2, colors [i].blue >> 2));
734
735 if (d < diff)
736 {
737 diff = d;
738 best = colors + i;
739 }
740 }
741
742 //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n",
743 // color.r, color.g, color.b, best->red, best->green, best->blue, diff);
744
745 got = alloc (screen, rgba (best->red, best->green, best->blue));
746
747 delete colors;
748 }
749#endif
750
751 return got;
752}
753
754void
755rxvt_color::get (rgba &color)
756{
547#if XFT 757#if XFT
548 int l = strlen (name); 758 color.r = c.color.red;
549 rxvt_rgba r; 759 color.g = c.color.green;
550 char eos; 760 color.b = c.color.blue;
551 int mult; 761 color.a = c.color.alpha;
552
553 if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
554 mult = rxvt_rgba::MAX_CC / 0x000f;
555 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
556 mult = rxvt_rgba::MAX_CC / 0x00ff;
557 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
558 mult = rxvt_rgba::MAX_CC / 0xffff;
559 else if (l == 4+5*4 && 4 == sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
560 mult = rxvt_rgba::MAX_CC / 0xffff;
561 else
562 return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c);
563
564 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult;
565 return set (screen, r);
566#else 762#else
567 XColor xc; 763 color.r = c.red;
568 764 color.g = c.green;
569 if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) 765 color.b = c.blue;
570 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue)); 766 color.a = rgba::MAX_CC;
571
572 return false;
573#endif 767#endif
574} 768}
575 769
576bool
577rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
578{
579#if XFT
580 XRenderPictFormat *format;
581
582 // FUCKING Xft gets it wrong, of course, so work around it
583 // transparency users should eat shit and die, and then
584 // XRenderQueryPictIndexValues themselves plenty.
585 if (screen->visual->c_class == TrueColor
586 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
587 {
588 // the fun lies in doing everything manually...
589 c.color.red = rgba.r;
590 c.color.green = rgba.g;
591 c.color.blue = rgba.b;
592 c.color.alpha = rgba.a;
593
594 c.pixel = (rgba.r >> (16 - popcount (format->direct.redMask )) << format->direct.red)
595 | (rgba.g >> (16 - popcount (format->direct.greenMask)) << format->direct.green)
596 | (rgba.b >> (16 - popcount (format->direct.blueMask )) << format->direct.blue)
597 | (rgba.a >> (16 - popcount (format->direct.alphaMask)) << format->direct.alpha);
598
599 return true;
600 }
601 else
602 {
603 XRenderColor d;
604
605 d.red = rgba.r;
606 d.green = rgba.g;
607 d.blue = rgba.b;
608 d.alpha = rgba.a;
609
610 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
611 }
612
613 return false;
614#else
615 XColor xc;
616
617 xc.red = rgba.r;
618 xc.green = rgba.g;
619 xc.blue = rgba.b;
620 xc.flags = DoRed | DoGreen | DoBlue;
621
622 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
623 {
624 p = xc.pixel;
625 return true;
626 }
627
628 return false;
629#endif
630}
631
632void 770void
633rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 771rxvt_color::get (XColor &color)
634{ 772{
635#if XFT 773 rgba c;
636 rgba.r = c.color.red; 774 get (c);
637 rgba.g = c.color.green;
638 rgba.b = c.color.blue;
639 rgba.a = c.color.alpha;
640#else
641 XColor c;
642 775
643 c.pixel = p; 776 color.red = c.r;
644 XQueryColor (screen->xdisp, screen->cmap, &c); 777 color.green = c.g;
645 778 color.blue = c.b;
646 rgba.r = c.red; 779 color.pixel = (Pixel)*this;
647 rgba.g = c.green;
648 rgba.b = c.blue;
649 rgba.a = rxvt_rgba::MAX_CC;
650#endif
651} 780}
652 781
653void 782void
654rxvt_color::free (rxvt_screen *screen) 783rxvt_color::free (rxvt_screen *screen)
655{ 784{
656#if XFT 785#if XFT
657 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 786 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
658#else 787#else
659 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 788 XFreeColors (screen->xdisp, screen->cmap, &c.pixel, 1, AllPlanes);
660#endif 789#endif
661} 790}
662 791
663rxvt_color 792void
664rxvt_color::fade (rxvt_screen *screen, int percent)
665{
666 rxvt_color faded;
667
668 rxvt_rgba c;
669 get (screen, c);
670
671 c.r = lerp (0, c.r, percent);
672 c.g = lerp (0, c.g, percent);
673 c.b = lerp (0, c.b, percent);
674
675 faded.set (screen, c);
676
677 return faded;
678}
679
680rxvt_color
681rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto) 793rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
682{ 794{
683 rxvt_rgba c, fc; 795 rgba c;
684 rxvt_color faded; 796 get (c);
685
686 get (screen, c);
687 fadeto.get (screen, fc);
688 797
689 faded.set ( 798 result.set (
690 screen, 799 screen,
691 rxvt_rgba ( 800 rgba (
692 lerp (fc.r, c.r, percent), 801 lerp (c.r, to.r, percent),
693 lerp (fc.g, c.g, percent), 802 lerp (c.g, to.g, percent),
694 lerp (fc.b, c.b, percent), 803 lerp (c.b, to.b, percent),
695 lerp (fc.a, c.a, percent) 804 lerp (c.a, to.a, percent)
696 ) 805 )
697 ); 806 );
698
699 return faded;
700} 807}
701 808

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines