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.22 by root, Mon Jan 9 05:08:02 2006 UTC vs.
Revision 1.39 by root, Tue Jan 31 00:25:16 2006 UTC

25#include <rxvttoolkit.h> 25#include <rxvttoolkit.h>
26 26
27#include <unistd.h> 27#include <unistd.h>
28#include <fcntl.h> 28#include <fcntl.h>
29 29
30#include <sys/utsname.h>
31
30#ifndef NO_SLOW_LINK_SUPPORT 32#ifndef NO_SLOW_LINK_SUPPORT
31# include <sys/socket.h> 33# include <sys/socket.h>
32# include <sys/un.h> 34# include <sys/un.h>
33#endif 35#endif
34 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
35refcounted::refcounted (const char *id) 99refcounted::refcounted (const char *id)
36{ 100{
37 this->id = strdup (id); 101 this->id = strdup (id);
38} 102}
39 103
47{ 111{
48 for (T **i = this->begin (); i < this->end (); ++i) 112 for (T **i = this->begin (); i < this->end (); ++i)
49 { 113 {
50 if (!strcmp (id, (*i)->id)) 114 if (!strcmp (id, (*i)->id))
51 { 115 {
52 (*i)->referenced++; 116 ++(*i)->referenced;
117 (*i)->ref_next ();
53 return *i; 118 return *i;
54 } 119 }
55 } 120 }
56 121
57 T *obj = new T (id); 122 T *obj = new T (id);
58 123
59 obj->referenced = 1;
60
61 if (obj && obj->init ()) 124 if (obj && obj->ref_init ())
62 { 125 {
126 obj->referenced = 1;
63 this->push_back (obj); 127 this->push_back (obj);
64 return obj; 128 return obj;
65 } 129 }
66 else 130 else
67 { 131 {
91} 155}
92 156
93///////////////////////////////////////////////////////////////////////////// 157/////////////////////////////////////////////////////////////////////////////
94 158
95#ifdef USE_XIM 159#ifdef USE_XIM
160
96static void 161static void
97#if XIMCB_PROTO_BROKEN 162#if XIMCB_PROTO_BROKEN
98im_destroy_cb (XIC unused1, XPointer client_data, XPointer unused3) 163im_destroy_cb (XIC unused1, XPointer client_data, XPointer unused3)
99#else 164#else
100im_destroy_cb (XIM unused1, XPointer client_data, XPointer unused3) 165im_destroy_cb (XIM unused1, XPointer client_data, XPointer unused3)
107 172
108 display->xims.erase (find (display->xims.begin (), display->xims.end (), xim)); 173 display->xims.erase (find (display->xims.begin (), display->xims.end (), xim));
109 display->im_change_cb (); 174 display->im_change_cb ();
110} 175}
111 176
177bool
112bool rxvt_xim::init () 178rxvt_xim::ref_init ()
113{ 179{
114 display = GET_R->display; //HACK: TODO 180 display = GET_R->display; //HACK: TODO
115 181
116 xim = XOpenIM (display->display, NULL, NULL, NULL); 182 xim = XOpenIM (display->display, NULL, NULL, NULL);
117 183
130rxvt_xim::~rxvt_xim () 196rxvt_xim::~rxvt_xim ()
131{ 197{
132 if (xim) 198 if (xim)
133 XCloseIM (xim); 199 XCloseIM (xim);
134} 200}
201
135#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}
136 242
137///////////////////////////////////////////////////////////////////////////// 243/////////////////////////////////////////////////////////////////////////////
138 244
139rxvt_display::rxvt_display (const char *id) 245rxvt_display::rxvt_display (const char *id)
140: refcounted (id) 246: refcounted (id)
141, x_ev (this, &rxvt_display::x_cb) 247, x_ev (this, &rxvt_display::x_cb)
142, selection_owner (0) 248, selection_owner (0)
143{ 249{
144} 250}
145 251
252XrmDatabase
253rxvt_display::get_resources ()
254{
255 char *homedir = (char *)getenv ("HOME");
256 char fname[1024];
257
258 /*
259 * get resources using the X library function
260 */
261 char *displayResource, *xe;
262 XrmDatabase database, rdb1;
263
264 database = NULL;
265
266 // for ordering, see for example http://www.faqs.org/faqs/Xt-FAQ/ Subject: 20
267
268 // 6. System wide per application default file.
269
270 /* Add in $XAPPLRESDIR/Rxvt only; not bothering with XUSERFILESEARCHPATH */
271 if ((xe = (char *)getenv ("XAPPLRESDIR")))
272 {
273 snprintf (fname, sizeof (fname), "%s/%s", xe, RESCLASS);
274
275 if ((rdb1 = XrmGetFileDatabase (fname)))
276 XrmMergeDatabases (rdb1, &database);
277 }
278
279 // 5. User's per application default file.
280 // none
281
282 // 4. User's defaults file.
283 /* Get any Xserver defaults */
284 displayResource = XResourceManagerString (display);
285
286 if (displayResource != NULL)
287 {
288 if ((rdb1 = XrmGetStringDatabase (displayResource)))
289 XrmMergeDatabases (rdb1, &database);
290 }
291 else if (homedir)
292 {
293 snprintf (fname, sizeof (fname), "%s/.Xdefaults", homedir);
294
295 if ((rdb1 = XrmGetFileDatabase (fname)))
296 XrmMergeDatabases (rdb1, &database);
297 }
298
299 /* Get screen specific resources */
300 displayResource = XScreenResourceString (ScreenOfDisplay (display, screen));
301
302 if (displayResource != NULL)
303 {
304 if ((rdb1 = XrmGetStringDatabase (displayResource)))
305 /* Merge with screen-independent resources */
306 XrmMergeDatabases (rdb1, &database);
307
308 XFree (displayResource);
309 }
310
311 // 3. User's per host defaults file
312 /* Add in XENVIRONMENT file */
313 if ((xe = (char *)getenv ("XENVIRONMENT"))
314 && (rdb1 = XrmGetFileDatabase (xe)))
315 XrmMergeDatabases (rdb1, &database);
316 else if (homedir)
317 {
318 struct utsname un;
319
320 if (!uname (&un))
321 {
322 snprintf (fname, sizeof (fname), "%s/.Xdefaults-%s", homedir, un.nodename);
323
324 if ((rdb1 = XrmGetFileDatabase (fname)))
325 XrmMergeDatabases (rdb1, &database);
326 }
327 }
328
329 return database;
330}
331
146bool rxvt_display::init () 332bool rxvt_display::ref_init ()
147{ 333{
148#ifdef LOCAL_X_IS_UNIX 334#ifdef LOCAL_X_IS_UNIX
149 if (id[0] == ':') 335 if (id[0] == ':')
150 { 336 {
151 val = rxvt_malloc (5 + strlen (id) + 1); 337 val = rxvt_malloc (5 + strlen (id) + 1);
164 if (!display) 350 if (!display)
165 return false; 351 return false;
166 352
167 screen = DefaultScreen (display); 353 screen = DefaultScreen (display);
168 root = DefaultRootWindow (display); 354 root = DefaultRootWindow (display);
169 visual = DefaultVisual (display, screen);
170 cmap = DefaultColormap (display, screen);
171 depth = DefaultDepth (display, screen);
172 355
173 int fd = XConnectionNumber (display); 356 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA);
357 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa);
174 358
175#ifndef NO_SLOW_LINK_SUPPORT 359 XrmSetDatabase (display, get_resources ());
176 // try to detect wether we have a local connection.
177 // assume unix domains socket == local, everything else not
178 // TODO: might want to check for inet/127.0.0.1
179 is_local = 0;
180 sockaddr_un sa;
181 socklen_t sl = sizeof (sa);
182
183 if (!getsockname (fd, (sockaddr *)&sa, &sl))
184 is_local = sa.sun_family == AF_LOCAL;
185#endif
186 360
187#ifdef POINTER_BLANK 361#ifdef POINTER_BLANK
188 XColor blackcolour; 362 XColor blackcolour;
189 blackcolour.red = 0; 363 blackcolour.red = 0;
190 blackcolour.green = 0; 364 blackcolour.green = 0;
193 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ', 367 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ',
194 &blackcolour, &blackcolour); 368 &blackcolour, &blackcolour);
195 XUnloadFont (display, f); 369 XUnloadFont (display, f);
196#endif 370#endif
197 371
198#ifdef PREFER_24BIT 372 int fd = XConnectionNumber (display);
199 /*
200 * If depth is not 24, look for a 24bit visual.
201 */
202 if (depth != 24)
203 {
204 XVisualInfo vinfo;
205 373
206 if (XMatchVisualInfo (display, screen, 24, TrueColor, &vinfo)) 374#ifndef NO_SLOW_LINK_SUPPORT
207 { 375 // try to detect wether we have a local connection.
208 depth = 24; 376 // assume unix domains socket == local, everything else not
209 visual = vinfo.visual; 377 // TODO: might want to check for inet/127.0.0.1
210 cmap = XCreateColormap (display, 378 is_local = 0;
211 RootWindow (display, screen), 379 sockaddr_un sa;
212 visual, AllocNone); 380 socklen_t sl = sizeof (sa);
213 } 381
214 } 382 if (!getsockname (fd, (sockaddr *)&sa, &sl))
383 is_local = sa.sun_family == AF_LOCAL;
215#endif 384#endif
216 385
217 x_ev.start (fd, EVENT_READ); 386 x_ev.start (fd, EVENT_READ);
218 fcntl (fd, F_SETFD, FD_CLOEXEC); 387 fcntl (fd, F_SETFD, FD_CLOEXEC);
219 388
220 XSelectInput (display, root, PropertyChangeMask); 389 XSelectInput (display, root, PropertyChangeMask);
221#ifdef USE_XIM
222 xa_xim_servers = XInternAtom (display, "XIM_SERVERS", 0);
223#endif
224 390
225 flush (); 391 flush ();
226 392
227 return true; 393 return true;
394}
395
396void
397rxvt_display::ref_next ()
398{
399 // TODO: somehow check wether the database files/resources changed
400 // before re-loading/parsing
401 XrmDestroyDatabase (XrmGetDatabase (display));
402 XrmSetDatabase (display, get_resources ());
228} 403}
229 404
230rxvt_display::~rxvt_display () 405rxvt_display::~rxvt_display ()
231{ 406{
232 if (!display) 407 if (!display)
255 // registers, as xlib crashes due to a race otherwise. 430 // registers, as xlib crashes due to a race otherwise.
256 Atom actual_type, *atoms; 431 Atom actual_type, *atoms;
257 int actual_format; 432 int actual_format;
258 unsigned long nitems, bytes_after; 433 unsigned long nitems, bytes_after;
259 434
260 if (XGetWindowProperty (display, root, xa_xim_servers, 0L, 1000000L, 435 if (XGetWindowProperty (display, root, xa[XA_XIM_SERVERS], 0L, 1000000L,
261 False, XA_ATOM, &actual_type, &actual_format, 436 False, XA_ATOM, &actual_type, &actual_format,
262 &nitems, &bytes_after, (unsigned char **)&atoms) 437 &nitems, &bytes_after, (unsigned char **)&atoms)
263 != Success ) 438 != Success )
264 return; 439 return;
265 440
285#ifdef USE_XIM 460#ifdef USE_XIM
286 if (!XFilterEvent (&xev, None)) 461 if (!XFilterEvent (&xev, None))
287 { 462 {
288 if (xev.type == PropertyNotify 463 if (xev.type == PropertyNotify
289 && xev.xany.window == root 464 && xev.xany.window == root
290 && xev.xproperty.atom == xa_xim_servers) 465 && xev.xproperty.atom == xa[XA_XIM_SERVERS])
291 im_change_check (); 466 im_change_check ();
292#endif 467#endif
293 for (int i = xw.size (); i--; ) 468 for (int i = xw.size (); i--; )
294 { 469 {
295 if (!xw[i]) 470 if (!xw[i])
383 558
384template class refcache<rxvt_display>; 559template class refcache<rxvt_display>;
385refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
386 561
387///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
388 563
389bool 564bool
390rxvt_color::set (rxvt_display *display, Pixel p) 565rxvt_color::alloc (rxvt_screen *screen, rxvt_rgba rgba)
391{ 566{
392#if XFT 567#if XFT
393 XColor xc; 568 XRenderPictFormat *format;
394 569
395 xc.pixel = p; 570 // FUCKING Xft gets it wrong, of course, so work around it
396 if (!XQueryColor (display->display, display->cmap, &xc)) 571 // transparency users should eat shit and die, and then
397 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;
398 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 {
399 XRenderColor d; 591 XRenderColor d;
400 592
401 d.red = xc.red; 593 d.red = rgba.r;
402 d.green = xc.green; 594 d.green = rgba.g;
403 d.blue = xc.blue; 595 d.blue = rgba.b;
404 d.alpha = 0xffff; 596 d.alpha = rgba.a;
405 597
406 return 598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
407 XftColorAllocValue (display->display, 599 }
408 display->visual,
409 display->cmap,
410 &d, &c);
411#else 600#else
412 this->p = p; 601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
413#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 );
414 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;
415 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;
416} 633}
417 634
418bool 635bool
419rxvt_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)
420{ 730{
421#if XFT 731#if XFT
422 return XftColorAllocName (display->display, display->visual, display->cmap,
423 name, &c);
424#else
425 XColor xc;
426
427 if (XParseColor (display->display, display->cmap, name, &xc))
428 return set (display, xc.red, xc.green, xc.blue);
429
430 return false;
431#endif
432}
433
434bool
435rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
436{
437 XColor xc;
438
439 xc.red = cr;
440 xc.green = cg;
441 xc.blue = cb;
442 xc.flags = DoRed | DoGreen | DoBlue;
443
444 if (XAllocColor (display->display, display->cmap, &xc))
445 return set (display, xc.pixel);
446
447 return false;
448}
449
450void
451rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
452{
453#if XFT
454 cr = c.color.red; 732 rgba.r = c.color.red;
455 cg = c.color.green; 733 rgba.g = c.color.green;
456 cb = c.color.blue; 734 rgba.b = c.color.blue;
735 rgba.a = c.color.alpha;
457#else 736#else
458 XColor c; 737 XColor c;
459 738
460 c.pixel = p; 739 c.pixel = p;
461 XQueryColor (display->display, display->cmap, &c); 740 XQueryColor (screen->xdisp, screen->cmap, &c);
462 741
463 cr = c.red; 742 rgba.r = c.red;
464 cg = c.green; 743 rgba.g = c.green;
465 cb = c.blue; 744 rgba.b = c.blue;
745 rgba.a = rxvt_rgba::MAX_CC;
466#endif 746#endif
467} 747}
468 748
469void 749void
470rxvt_color::free (rxvt_display *display) 750rxvt_color::free (rxvt_screen *screen)
471{ 751{
472#if XFT 752#if XFT
473 XftColorFree (display->display, display->visual, display->cmap, &c); 753 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
474#else 754#else
475 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes); 755 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
476#endif 756#endif
477} 757}
478 758
479rxvt_color 759rxvt_color
480rxvt_color::fade (rxvt_display *display, int percent) 760rxvt_color::fade (rxvt_screen *screen, int percent)
481{ 761{
482 percent = 100 - percent;
483
484 unsigned short cr, cg, cb;
485 rxvt_color faded; 762 rxvt_color faded;
486 763
487 get (display, cr, cg, cb); 764 rxvt_rgba c;
765 get (screen, c);
488 766
489 faded.set ( 767 c.r = lerp (0, c.r, percent);
490 display, 768 c.g = lerp (0, c.g, percent);
491 cr * percent / 100, 769 c.b = lerp (0, c.b, percent);
492 cg * percent / 100, 770
493 cb * percent / 100 771 faded.set (screen, c);
494 );
495 772
496 return faded; 773 return faded;
497} 774}
498 775
499#define LERP(a,b,p) (a * p + b * (100 - p)) / 100
500
501rxvt_color 776rxvt_color
502rxvt_color::fade (rxvt_display *display, int percent, rxvt_color &fadeto) 777rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
503{ 778{
504 percent = 100 - percent; 779 rxvt_rgba c, fc;
505
506 unsigned short cr, cg, cb;
507 unsigned short fcr, fcg, fcb;
508 rxvt_color faded; 780 rxvt_color faded;
509 781
510 get (display, cr, cg, cb); 782 get (screen, c);
511 fadeto.get(display, fcr, fcg, fcb); 783 fadeto.get (screen, fc);
512 784
513 faded.set ( 785 faded.set (
514 display, 786 screen,
787 rxvt_rgba (
515 LERP (cr, fcr, percent), 788 lerp (fc.r, c.r, percent),
516 LERP (cg, fcg, percent), 789 lerp (fc.g, c.g, percent),
517 LERP (cb, fcb, percent) 790 lerp (fc.b, c.b, percent),
791 lerp (fc.a, c.a, percent)
792 )
518 ); 793 );
519 794
520 return faded; 795 return faded;
521} 796}
522 797

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines