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.36 by root, Mon Jan 30 17:43:20 2006 UTC vs.
Revision 1.49 by root, Thu Feb 2 14:41:00 2006 UTC

81 "SCREEN_RESOURCES", 81 "SCREEN_RESOURCES",
82 "XDCCC_LINEAR_RGB_CORRECTION", 82 "XDCCC_LINEAR_RGB_CORRECTION",
83 "XDCCC_LINEAR_RGB_MATRICES", 83 "XDCCC_LINEAR_RGB_MATRICES",
84 "WM_COLORMAP_WINDOWS", 84 "WM_COLORMAP_WINDOWS",
85 "WM_STATE", 85 "WM_STATE",
86 "cursor",
87# if USE_XIM
88 "TRANSPORT",
89 "LOCALES",
90 "_XIM_PROTOCOL",
91 "_XIM_XCONNECT",
92 "_XIM_MOREDATA",
93# endif
86#endif 94#endif
87}; 95};
88 96
89///////////////////////////////////////////////////////////////////////////// 97/////////////////////////////////////////////////////////////////////////////
90 98
169bool 177bool
170rxvt_xim::ref_init () 178rxvt_xim::ref_init ()
171{ 179{
172 display = GET_R->display; //HACK: TODO 180 display = GET_R->display; //HACK: TODO
173 181
174 xim = XOpenIM (display->display, NULL, NULL, NULL); 182 xim = XOpenIM (display->display, 0, 0, 0);
175 183
176 if (!xim) 184 if (!xim)
177 return false; 185 return false;
178 186
179 XIMCallback ximcallback; 187 XIMCallback ximcallback;
180 ximcallback.client_data = (XPointer)this; 188 ximcallback.client_data = (XPointer)this;
181 ximcallback.callback = im_destroy_cb; 189 ximcallback.callback = im_destroy_cb;
182 190
183 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL); 191 XSetIMValues (xim, XNDestroyCallback, &ximcallback, 0);
184 192
185 return true; 193 return true;
186} 194}
187 195
188rxvt_xim::~rxvt_xim () 196rxvt_xim::~rxvt_xim ()
240, selection_owner (0) 248, selection_owner (0)
241{ 249{
242} 250}
243 251
244XrmDatabase 252XrmDatabase
245rxvt_display::get_resources () 253rxvt_display::get_resources (bool refresh)
246{ 254{
247 char *homedir = (char *)getenv ("HOME"); 255 char *homedir = (char *)getenv ("HOME");
248 char fname[1024]; 256 char fname[1024];
249 257
250 /* 258 /*
251 * get resources using the X library function 259 * get resources using the X library function
252 */ 260 */
253 char *displayResource, *xe; 261 char *displayResource, *xe;
254 XrmDatabase database, rdb1; 262 XrmDatabase rdb1, database = 0;
255
256 database = NULL;
257 263
258 // 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
259 265
260 // 6. System wide per application default file. 266 // 6. System wide per application default file.
261 267
271 // 5. User's per application default file. 277 // 5. User's per application default file.
272 // none 278 // none
273 279
274 // 4. User's defaults file. 280 // 4. User's defaults file.
275 /* 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
276 displayResource = XResourceManagerString (display); 315 displayResource = XResourceManagerString (display);
277 316
278 if (displayResource != NULL) 317 if (displayResource)
279 { 318 {
280 if ((rdb1 = XrmGetStringDatabase (displayResource))) 319 if ((rdb1 = XrmGetStringDatabase (displayResource)))
281 XrmMergeDatabases (rdb1, &database); 320 XrmMergeDatabases (rdb1, &database);
282 } 321 }
283 else if (homedir) 322 else if (homedir)
286 325
287 if ((rdb1 = XrmGetFileDatabase (fname))) 326 if ((rdb1 = XrmGetFileDatabase (fname)))
288 XrmMergeDatabases (rdb1, &database); 327 XrmMergeDatabases (rdb1, &database);
289 } 328 }
290 329
330#if !XLIB_ILLEGAL_ACCESS
331 if (refresh && displayResource)
332 XFree (displayResource);
333#endif
334
291 /* Get screen specific resources */ 335 /* Get screen specific resources */
292 displayResource = XScreenResourceString (ScreenOfDisplay (display, screen)); 336 displayResource = XScreenResourceString (ScreenOfDisplay (display, screen));
293 337
294 if (displayResource != NULL) 338 if (displayResource)
295 { 339 {
296 if ((rdb1 = XrmGetStringDatabase (displayResource))) 340 if ((rdb1 = XrmGetStringDatabase (displayResource)))
297 /* Merge with screen-independent resources */ 341 /* Merge with screen-independent resources */
298 XrmMergeDatabases (rdb1, &database); 342 XrmMergeDatabases (rdb1, &database);
299 343
340 display = XOpenDisplay (id); 384 display = XOpenDisplay (id);
341 385
342 if (!display) 386 if (!display)
343 return false; 387 return false;
344 388
345 screen = DefaultScreen (display); 389 screen = DefaultScreen (display);
346 root = DefaultRootWindow (display); 390 root = DefaultRootWindow (display);
347 391
348 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA); 392 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA);
349 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa); 393 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa);
350 394
351 XrmSetDatabase (display, get_resources ()); 395 XrmSetDatabase (display, get_resources (false));
352 396
353#ifdef POINTER_BLANK 397#ifdef POINTER_BLANK
354 XColor blackcolour; 398 XColor blackcolour;
355 blackcolour.red = 0; 399 blackcolour.red = 0;
356 blackcolour.green = 0; 400 blackcolour.green = 0;
387 431
388void 432void
389rxvt_display::ref_next () 433rxvt_display::ref_next ()
390{ 434{
391 // TODO: somehow check wether the database files/resources changed 435 // TODO: somehow check wether the database files/resources changed
392 // before re-loading/parsing 436 // before affording re-loading/parsing
393 XrmDestroyDatabase (XrmGetDatabase (display)); 437 XrmDestroyDatabase (XrmGetDatabase (display));
394 XrmSetDatabase (display, get_resources ()); 438 XrmSetDatabase (display, get_resources (true));
395} 439}
396 440
397rxvt_display::~rxvt_display () 441rxvt_display::~rxvt_display ()
398{ 442{
399 if (!display) 443 if (!display)
500 544
501 selection_owner = owner; 545 selection_owner = owner;
502} 546}
503 547
504#ifdef USE_XIM 548#ifdef USE_XIM
549
505void rxvt_display::reg (im_watcher *w) 550void rxvt_display::reg (im_watcher *w)
506{ 551{
507 imw.push_back (w); 552 imw.push_back (w);
508} 553}
509 554
533 return xim; 578 return xim;
534} 579}
535 580
536void rxvt_display::put_xim (rxvt_xim *xim) 581void rxvt_display::put_xim (rxvt_xim *xim)
537{ 582{
538#if XLIB_IS_RACEFREE 583# if XLIB_IS_RACEFREE
539 xims.put (xim); 584 xims.put (xim);
540#endif 585# endif
541} 586}
587
542#endif 588#endif
543 589
544Atom rxvt_display::atom (const char *name) 590Atom rxvt_display::atom (const char *name)
545{ 591{
546 return XInternAtom (display, name, False); 592 return XInternAtom (display, name, False);
550 596
551template class refcache<rxvt_display>; 597template class refcache<rxvt_display>;
552refcache<rxvt_display> displays; 598refcache<rxvt_display> displays;
553 599
554///////////////////////////////////////////////////////////////////////////// 600/////////////////////////////////////////////////////////////////////////////
555 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
556bool 665bool
557rxvt_color::set (rxvt_screen *screen, const char *name) 666rxvt_color::set (rxvt_screen *screen, const char *name)
558{ 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{
559#if XFT 757#if XFT
560 int l = strlen (name); 758 color.r = c.color.red;
561 rxvt_rgba r; 759 color.g = c.color.green;
562 char eos; 760 color.b = c.color.blue;
563 int mult; 761 color.a = c.color.alpha;
564
565 // shortcutting this saves countless server RTTs for the built-in colours
566 if (l == 3+3*3 && 3 == sscanf (name, "rgb:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
567 {
568 r.a = rxvt_rgba::MAX_CC;
569 mult = rxvt_rgba::MAX_CC / 0x00ff;
570 }
571
572 // parse a number of non-standard ARGB colour specifications
573 else if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
574 mult = rxvt_rgba::MAX_CC / 0x000f;
575 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
576 mult = rxvt_rgba::MAX_CC / 0x00ff;
577 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
578 mult = rxvt_rgba::MAX_CC / 0xffff;
579 else if (l == 4+5*4 && 4 == sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos))
580 mult = rxvt_rgba::MAX_CC / 0xffff;
581
582 // slow case: server round trip
583 else
584 return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c);
585
586 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult;
587
588 return set (screen, r);
589#else 762#else
590 XColor xc; 763 color.r = c.red;
591 764 color.g = c.green;
592 if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) 765 color.b = c.blue;
593 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue)); 766 color.a = rgba::MAX_CC;
594
595 return false;
596#endif 767#endif
597} 768}
598 769
599bool
600rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
601{
602#if XFT
603 XRenderPictFormat *format;
604
605 // FUCKING Xft gets it wrong, of course, so work around it
606 // transparency users should eat shit and die, and then
607 // XRenderQueryPictIndexValues themselves plenty.
608 if (screen->visual->c_class == TrueColor
609 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual)))
610 {
611 // the fun lies in doing everything manually...
612 c.color.red = rgba.r;
613 c.color.green = rgba.g;
614 c.color.blue = rgba.b;
615 c.color.alpha = rgba.a;
616
617 c.pixel = ((rgba.r * format->direct.redMask / rxvt_rgba::MAX_CC) << format->direct.red )
618 | ((rgba.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green)
619 | ((rgba.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue )
620 | ((rgba.a * format->direct.alphaMask / rxvt_rgba::MAX_CC) << format->direct.alpha);
621
622 return true;
623 }
624 else
625 {
626 XRenderColor d;
627
628 d.red = rgba.r;
629 d.green = rgba.g;
630 d.blue = rgba.b;
631 d.alpha = rgba.a;
632
633 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
634 }
635
636 return false;
637#else
638 if (screen->visual->c_class == TrueColor)
639 {
640 p = ((rgba.r * ((1 << screen->visual->bits_per_rgb) - 1)
641 / rxvt_rgba::MAX_CC) << ctz (screen->visual->red_mask ))
642 | ((rgba.g * ((1 << screen->visual->bits_per_rgb) - 1)
643 / rxvt_rgba::MAX_CC) << ctz (screen->visual->green_mask))
644 | ((rgba.b * ((1 << screen->visual->bits_per_rgb) - 1)
645 / rxvt_rgba::MAX_CC) << ctz (screen->visual->blue_mask ));
646
647 return true;
648 }
649 else
650 {
651 XColor xc;
652
653 xc.red = rgba.r;
654 xc.green = rgba.g;
655 xc.blue = rgba.b;
656 xc.flags = DoRed | DoGreen | DoBlue;
657
658 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
659 {
660 p = xc.pixel;
661 return true;
662 }
663 }
664
665 return false;
666#endif
667}
668
669void 770void
670rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 771rxvt_color::get (XColor &color)
671{ 772{
672#if XFT 773 rgba c;
673 rgba.r = c.color.red; 774 get (c);
674 rgba.g = c.color.green;
675 rgba.b = c.color.blue;
676 rgba.a = c.color.alpha;
677#else
678 XColor c;
679 775
680 c.pixel = p; 776 color.red = c.r;
681 XQueryColor (screen->xdisp, screen->cmap, &c); 777 color.green = c.g;
682 778 color.blue = c.b;
683 rgba.r = c.red; 779 color.pixel = (Pixel)*this;
684 rgba.g = c.green;
685 rgba.b = c.blue;
686 rgba.a = rxvt_rgba::MAX_CC;
687#endif
688} 780}
689 781
690void 782void
691rxvt_color::free (rxvt_screen *screen) 783rxvt_color::free (rxvt_screen *screen)
692{ 784{
693#if XFT 785#if XFT
694 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 786 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
695#else 787#else
696 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 788 XFreeColors (screen->xdisp, screen->cmap, &c.pixel, 1, AllPlanes);
697#endif 789#endif
698} 790}
699 791
700rxvt_color 792void
701rxvt_color::fade (rxvt_screen *screen, int percent)
702{
703 rxvt_color faded;
704
705 rxvt_rgba c;
706 get (screen, c);
707
708 c.r = lerp (0, c.r, percent);
709 c.g = lerp (0, c.g, percent);
710 c.b = lerp (0, c.b, percent);
711
712 faded.set (screen, c);
713
714 return faded;
715}
716
717rxvt_color
718rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto) 793rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
719{ 794{
720 rxvt_rgba c, fc; 795 rgba c;
721 rxvt_color faded; 796 get (c);
722
723 get (screen, c);
724 fadeto.get (screen, fc);
725 797
726 faded.set ( 798 result.set (
727 screen, 799 screen,
728 rxvt_rgba ( 800 rgba (
729 lerp (fc.r, c.r, percent), 801 lerp (c.r, to.r, percent),
730 lerp (fc.g, c.g, percent), 802 lerp (c.g, to.g, percent),
731 lerp (fc.b, c.b, percent), 803 lerp (c.b, to.b, percent),
732 lerp (fc.a, c.a, percent) 804 lerp (c.a, to.a, percent)
733 ) 805 )
734 ); 806 );
735
736 return faded;
737} 807}
738 808

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines