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.20 by root, Fri Jan 6 02:11:15 2006 UTC vs.
Revision 1.38 by root, Mon Jan 30 19:46:13 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;
228} 394}
229 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 ());
403}
404
230rxvt_display::~rxvt_display () 405rxvt_display::~rxvt_display ()
231{ 406{
407 if (!display)
408 return;
409
410#ifdef POINTER_BLANK
411 XFreeCursor (display, blank_cursor);
412#endif
232 x_ev.stop (); 413 x_ev.stop ();
233#ifdef USE_XIM 414#ifdef USE_XIM
234 xims.clear (); 415 xims.clear ();
235#endif 416#endif
236
237 if (display)
238 XCloseDisplay (display); 417 XCloseDisplay (display);
239} 418}
240 419
241#ifdef USE_XIM 420#ifdef USE_XIM
242void rxvt_display::im_change_cb () 421void rxvt_display::im_change_cb ()
243{ 422{
251 // registers, as xlib crashes due to a race otherwise. 430 // registers, as xlib crashes due to a race otherwise.
252 Atom actual_type, *atoms; 431 Atom actual_type, *atoms;
253 int actual_format; 432 int actual_format;
254 unsigned long nitems, bytes_after; 433 unsigned long nitems, bytes_after;
255 434
256 if (XGetWindowProperty (display, root, xa_xim_servers, 0L, 1000000L, 435 if (XGetWindowProperty (display, root, xa[XA_XIM_SERVERS], 0L, 1000000L,
257 False, XA_ATOM, &actual_type, &actual_format, 436 False, XA_ATOM, &actual_type, &actual_format,
258 &nitems, &bytes_after, (unsigned char **)&atoms) 437 &nitems, &bytes_after, (unsigned char **)&atoms)
259 != Success ) 438 != Success )
260 return; 439 return;
261 440
281#ifdef USE_XIM 460#ifdef USE_XIM
282 if (!XFilterEvent (&xev, None)) 461 if (!XFilterEvent (&xev, None))
283 { 462 {
284 if (xev.type == PropertyNotify 463 if (xev.type == PropertyNotify
285 && xev.xany.window == root 464 && xev.xany.window == root
286 && xev.xproperty.atom == xa_xim_servers) 465 && xev.xproperty.atom == xa[XA_XIM_SERVERS])
287 im_change_check (); 466 im_change_check ();
288#endif 467#endif
289 for (int i = xw.size (); i--; ) 468 for (int i = xw.size (); i--; )
290 { 469 {
291 if (!xw[i]) 470 if (!xw[i])
379 558
380template class refcache<rxvt_display>; 559template class refcache<rxvt_display>;
381refcache<rxvt_display> displays; 560refcache<rxvt_display> displays;
382 561
383///////////////////////////////////////////////////////////////////////////// 562/////////////////////////////////////////////////////////////////////////////
384 563
385bool 564bool
386rxvt_color::set (rxvt_display *display, Pixel p) 565rxvt_color::alloc (rxvt_screen *screen, rxvt_rgba rgba)
387{ 566{
388#if XFT 567#if XFT
389 XColor xc; 568 XRenderPictFormat *format;
390 569
391 xc.pixel = p; 570 // FUCKING Xft gets it wrong, of course, so work around it
392 if (!XQueryColor (display->display, display->cmap, &xc)) 571 // transparency users should eat shit and die, and then
393 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;
394 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 {
395 XRenderColor d; 591 XRenderColor d;
396 592
397 d.red = xc.red; 593 d.red = rgba.r;
398 d.green = xc.green; 594 d.green = rgba.g;
399 d.blue = xc.blue; 595 d.blue = rgba.b;
400 d.alpha = 0xffff; 596 d.alpha = rgba.a;
401 597
402 return 598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
403 XftColorAllocValue (display->display, 599 }
404 display->visual,
405 display->cmap,
406 &d, &c);
407#else 600#else
408 this->p = p; 601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor)
409#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 );
410 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;
411 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;
412} 633}
413 634
414bool 635bool
415rxvt_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)
416{ 723{
417#if XFT 724#if XFT
418 return XftColorAllocName (display->display, display->visual, display->cmap,
419 name, &c);
420#else
421 XColor xc;
422
423 if (XParseColor (display->display, display->cmap, name, &xc))
424 return set (display, xc.red, xc.green, xc.blue);
425
426 return false;
427#endif
428}
429
430bool
431rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
432{
433 XColor xc;
434
435 xc.red = cr;
436 xc.green = cg;
437 xc.blue = cb;
438 xc.flags = DoRed | DoGreen | DoBlue;
439
440 if (XAllocColor (display->display, display->cmap, &xc))
441 return set (display, xc.pixel);
442
443 return false;
444}
445
446void
447rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
448{
449#if XFT
450 cr = c.color.red; 725 rgba.r = c.color.red;
451 cg = c.color.green; 726 rgba.g = c.color.green;
452 cb = c.color.blue; 727 rgba.b = c.color.blue;
728 rgba.a = c.color.alpha;
453#else 729#else
454 XColor c; 730 XColor c;
455 731
456 c.pixel = p; 732 c.pixel = p;
457 XQueryColor (display->display, display->cmap, &c); 733 XQueryColor (screen->xdisp, screen->cmap, &c);
458 734
459 cr = c.red; 735 rgba.r = c.red;
460 cg = c.green; 736 rgba.g = c.green;
461 cb = c.blue; 737 rgba.b = c.blue;
738 rgba.a = rxvt_rgba::MAX_CC;
462#endif 739#endif
463} 740}
464 741
465void 742void
466rxvt_color::free (rxvt_display *display) 743rxvt_color::free (rxvt_screen *screen)
467{ 744{
468#if XFT 745#if XFT
469 XftColorFree (display->display, display->visual, display->cmap, &c); 746 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c);
470#else 747#else
471 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes); 748 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes);
472#endif 749#endif
473} 750}
474 751
475rxvt_color 752rxvt_color
476rxvt_color::fade (rxvt_display *display, int percent) 753rxvt_color::fade (rxvt_screen *screen, int percent)
477{ 754{
478 percent = 100 - percent;
479
480 unsigned short cr, cg, cb;
481 rxvt_color faded; 755 rxvt_color faded;
482 756
483 get (display, cr, cg, cb); 757 rxvt_rgba c;
758 get (screen, c);
484 759
485 faded.set ( 760 c.r = lerp (0, c.r, percent);
486 display, 761 c.g = lerp (0, c.g, percent);
487 cr * percent / 100, 762 c.b = lerp (0, c.b, percent);
488 cg * percent / 100, 763
489 cb * percent / 100 764 faded.set (screen, c);
490 );
491 765
492 return faded; 766 return faded;
493} 767}
494 768
495#define LERP(a,b,p) (a * p + b * (100 - p)) / 100
496
497rxvt_color 769rxvt_color
498rxvt_color::fade (rxvt_display *display, int percent, rxvt_color &fadeto) 770rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
499{ 771{
500 percent = 100 - percent; 772 rxvt_rgba c, fc;
501
502 unsigned short cr, cg, cb;
503 unsigned short fcr, fcg, fcb;
504 rxvt_color faded; 773 rxvt_color faded;
505 774
506 get (display, cr, cg, cb); 775 get (screen, c);
507 fadeto.get(display, fcr, fcg, fcb); 776 fadeto.get (screen, fc);
508 777
509 faded.set ( 778 faded.set (
510 display, 779 screen,
780 rxvt_rgba (
511 LERP (cr, fcr, percent), 781 lerp (fc.r, c.r, percent),
512 LERP (cg, fcg, percent), 782 lerp (fc.g, c.g, percent),
513 LERP (cb, fcb, percent) 783 lerp (fc.b, c.b, percent),
784 lerp (fc.a, c.a, percent)
785 )
514 ); 786 );
515 787
516 return faded; 788 return faded;
517} 789}
518 790

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines