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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines