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.28 by root, Sun Jan 29 20:51:28 2006 UTC vs.
Revision 1.50 by root, Thu Feb 2 18:04:46 2006 UTC

32#ifndef NO_SLOW_LINK_SUPPORT 32#ifndef NO_SLOW_LINK_SUPPORT
33# include <sys/socket.h> 33# include <sys/socket.h>
34# include <sys/un.h> 34# include <sys/un.h>
35#endif 35#endif
36 36
37#if XFT
38# include <X11/extensions/Xrender.h>
39#endif
40
37const char *const xa_names[] = 41const char *const xa_names[] =
38 { 42{
39 "TEXT", 43 "TEXT",
40 "COMPOUND_TEXT", 44 "COMPOUND_TEXT",
41 "UTF8_STRING", 45 "UTF8_STRING",
42 "MULTIPLE", 46 "MULTIPLE",
43 "TARGETS", 47 "TARGETS",
44 "TIMESTAMP", 48 "TIMESTAMP",
45 "VT_SELECTION", 49 "VT_SELECTION",
46 "INCR", 50 "INCR",
47 "WM_PROTOCOLS", 51 "WM_PROTOCOLS",
48 "WM_DELETE_WINDOW", 52 "WM_DELETE_WINDOW",
49 "CLIPBOARD", 53 "CLIPBOARD",
54 "AVERAGE_WIDTH",
55 "WEIGHT_NAME",
56 "SLANT",
57 "CHARSET_REGISTRY",
58 "CHARSET_ENCODING",
50#if ENABLE_FRILLS 59#if ENABLE_FRILLS
51 "_MOTIF_WM_HINTS", 60 "_MOTIF_WM_HINTS",
52#endif 61#endif
53#if ENABLE_EWMH 62#if ENABLE_EWMH
54 "_NET_WM_PID", 63 "_NET_WM_PID",
55 "_NET_WM_NAME", 64 "_NET_WM_NAME",
56 "_NET_WM_ICON_NAME", 65 "_NET_WM_ICON_NAME",
57 "_NET_WM_PING", 66 "_NET_WM_PING",
58#endif 67#endif
59#if USE_XIM 68#if USE_XIM
60 "WM_LOCALE_NAME", 69 "WM_LOCALE_NAME",
61 "XIM_SERVERS", 70 "XIM_SERVERS",
62#endif 71#endif
63#ifdef TRANSPARENT 72#ifdef TRANSPARENT
64 "_XROOTPMAP_ID", 73 "_XROOTPMAP_ID",
65 "ESETROOT_PMAP_ID", 74 "ESETROOT_PMAP_ID",
66#endif 75#endif
67#if ENABLE_XEMBED 76#if ENABLE_XEMBED
68 "_XEMBED", 77 "_XEMBED",
69 "_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",
70#endif 93# endif
71 }; 94#endif
95};
72 96
73///////////////////////////////////////////////////////////////////////////// 97/////////////////////////////////////////////////////////////////////////////
74 98
75refcounted::refcounted (const char *id) 99refcounted::refcounted (const char *id)
76{ 100{
153bool 177bool
154rxvt_xim::ref_init () 178rxvt_xim::ref_init ()
155{ 179{
156 display = GET_R->display; //HACK: TODO 180 display = GET_R->display; //HACK: TODO
157 181
158 xim = XOpenIM (display->display, NULL, NULL, NULL); 182 xim = XOpenIM (display->dpy, 0, 0, 0);
159 183
160 if (!xim) 184 if (!xim)
161 return false; 185 return false;
162 186
163 XIMCallback ximcallback; 187 XIMCallback ximcallback;
164 ximcallback.client_data = (XPointer)this; 188 ximcallback.client_data = (XPointer)this;
165 ximcallback.callback = im_destroy_cb; 189 ximcallback.callback = im_destroy_cb;
166 190
167 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL); 191 XSetIMValues (xim, XNDestroyCallback, &ximcallback, 0);
168 192
169 return true; 193 return true;
170} 194}
171 195
172rxvt_xim::~rxvt_xim () 196rxvt_xim::~rxvt_xim ()
181 205
182void 206void
183rxvt_screen::set (rxvt_display *disp) 207rxvt_screen::set (rxvt_display *disp)
184{ 208{
185 display = disp; 209 display = disp;
186 xdisp = disp->display; 210 dpy = disp->dpy;
187 211
188 Screen *screen = ScreenOfDisplay (xdisp, disp->screen); 212 Screen *screen = ScreenOfDisplay (dpy, disp->screen);
189 213
190 depth = DefaultDepthOfScreen (screen); 214 depth = DefaultDepthOfScreen (screen);
191 visual = DefaultVisualOfScreen (screen); 215 visual = DefaultVisualOfScreen (screen);
192 cmap = DefaultColormapOfScreen (screen); 216 cmap = DefaultColormapOfScreen (screen);
193} 217}
195void 219void
196rxvt_screen::set (rxvt_display *disp, int bitdepth) 220rxvt_screen::set (rxvt_display *disp, int bitdepth)
197{ 221{
198 set (disp); 222 set (disp);
199 223
224#if XFT
200 XVisualInfo vinfo; 225 XVisualInfo vinfo;
201 226
202 if (XMatchVisualInfo (xdisp, display->screen, bitdepth, TrueColor, &vinfo)) 227 if (XMatchVisualInfo (dpy, display->screen, bitdepth, TrueColor, &vinfo))
203 { 228 {
204 depth = bitdepth; 229 depth = bitdepth;
205 visual = vinfo.visual; 230 visual = vinfo.visual;
206 cmap = XCreateColormap (xdisp, disp->root, visual, AllocNone); 231 cmap = XCreateColormap (dpy, disp->root, visual, AllocNone);
207 } 232 }
233#endif
208} 234}
209 235
210void 236void
211rxvt_screen::clear () 237rxvt_screen::clear ()
212{ 238{
213 if (cmap != DefaultColormapOfScreen (ScreenOfDisplay (xdisp, display->screen))) 239 if (cmap != DefaultColormapOfScreen (ScreenOfDisplay (dpy, display->screen)))
214 XFreeColormap (xdisp, cmap); 240 XFreeColormap (dpy, cmap);
215} 241}
216 242
217///////////////////////////////////////////////////////////////////////////// 243/////////////////////////////////////////////////////////////////////////////
218 244
219rxvt_display::rxvt_display (const char *id) 245rxvt_display::rxvt_display (const char *id)
222, selection_owner (0) 248, selection_owner (0)
223{ 249{
224} 250}
225 251
226XrmDatabase 252XrmDatabase
227rxvt_display::get_resources () 253rxvt_display::get_resources (bool refresh)
228{ 254{
229 char *homedir = (char *)getenv ("HOME"); 255 char *homedir = (char *)getenv ("HOME");
230 char fname[1024]; 256 char fname[1024];
231 257
232 /* 258 /*
233 * get resources using the X library function 259 * get resources using the X library function
234 */ 260 */
235 char *displayResource, *xe; 261 char *displayResource, *xe;
236 XrmDatabase database, rdb1; 262 XrmDatabase rdb1, database = 0;
237
238 database = NULL;
239 263
240 // 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
241 265
242 // 6. System wide per application default file. 266 // 6. System wide per application default file.
243 267
253 // 5. User's per application default file. 277 // 5. User's per application default file.
254 // none 278 // none
255 279
256 // 4. User's defaults file. 280 // 4. User's defaults file.
257 /* 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 (dpy->xdefaults)
292 XFree (dpy->xdefaults);
293#endif
294
295 if (XGetWindowProperty (dpy, 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 dpy->xdefaults = displayResource;
312#endif
313 }
314 else
258 displayResource = XResourceManagerString (display); 315 displayResource = XResourceManagerString (dpy);
259 316
260 if (displayResource != NULL) 317 if (displayResource)
261 { 318 {
262 if ((rdb1 = XrmGetStringDatabase (displayResource))) 319 if ((rdb1 = XrmGetStringDatabase (displayResource)))
263 XrmMergeDatabases (rdb1, &database); 320 XrmMergeDatabases (rdb1, &database);
264 } 321 }
265 else if (homedir) 322 else if (homedir)
268 325
269 if ((rdb1 = XrmGetFileDatabase (fname))) 326 if ((rdb1 = XrmGetFileDatabase (fname)))
270 XrmMergeDatabases (rdb1, &database); 327 XrmMergeDatabases (rdb1, &database);
271 } 328 }
272 329
330#if !XLIB_ILLEGAL_ACCESS
331 if (refresh && displayResource)
332 XFree (displayResource);
333#endif
334
273 /* Get screen specific resources */ 335 /* Get screen specific resources */
274 displayResource = XScreenResourceString (ScreenOfDisplay (display, screen)); 336 displayResource = XScreenResourceString (ScreenOfDisplay (dpy, screen));
275 337
276 if (displayResource != NULL) 338 if (displayResource)
277 { 339 {
278 if ((rdb1 = XrmGetStringDatabase (displayResource))) 340 if ((rdb1 = XrmGetStringDatabase (displayResource)))
279 /* Merge with screen-independent resources */ 341 /* Merge with screen-independent resources */
280 XrmMergeDatabases (rdb1, &database); 342 XrmMergeDatabases (rdb1, &database);
281 343
309 if (id[0] == ':') 371 if (id[0] == ':')
310 { 372 {
311 val = rxvt_malloc (5 + strlen (id) + 1); 373 val = rxvt_malloc (5 + strlen (id) + 1);
312 strcpy (val, "unix/"); 374 strcpy (val, "unix/");
313 strcat (val, id); 375 strcat (val, id);
314 display = XOpenDisplay (val); 376 dpy = XOpenDisplay (val);
315 free (val); 377 free (val);
316 } 378 }
317 else 379 else
318#endif 380#endif
319 display = 0; 381 dpy = 0;
320 382
321 if (!display) 383 if (!dpy)
322 display = XOpenDisplay (id); 384 dpy = XOpenDisplay (id);
323 385
324 if (!display) 386 if (!dpy)
325 return false; 387 return false;
326 388
327 screen = DefaultScreen (display); 389 screen = DefaultScreen (dpy);
328 root = DefaultRootWindow (display); 390 root = DefaultRootWindow (dpy);
329 391
330 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA); 392 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA);
331 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa); 393 XInternAtoms (dpy, (char **)xa_names, NUM_XA, False, xa);
332 394
333 XrmSetDatabase (display, get_resources ()); 395 XrmSetDatabase (dpy, get_resources (false));
334 396
335#ifdef POINTER_BLANK 397#ifdef POINTER_BLANK
336 XColor blackcolour; 398 XColor blackcolour;
337 blackcolour.red = 0; 399 blackcolour.red = 0;
338 blackcolour.green = 0; 400 blackcolour.green = 0;
339 blackcolour.blue = 0; 401 blackcolour.blue = 0;
340 Font f = XLoadFont (display, "fixed"); 402 Font f = XLoadFont (dpy, "fixed");
341 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ', 403 blank_cursor = XCreateGlyphCursor (dpy, f, f, ' ', ' ',
342 &blackcolour, &blackcolour); 404 &blackcolour, &blackcolour);
343 XUnloadFont (display, f); 405 XUnloadFont (dpy, f);
344#endif 406#endif
345 407
346 int fd = XConnectionNumber (display); 408 int fd = XConnectionNumber (dpy);
347 409
348#ifndef NO_SLOW_LINK_SUPPORT 410#ifndef NO_SLOW_LINK_SUPPORT
349 // try to detect wether we have a local connection. 411 // try to detect wether we have a local connection.
350 // assume unix domains socket == local, everything else not 412 // assume unix domains socket == local, everything else not
351 // TODO: might want to check for inet/127.0.0.1 413 // TODO: might want to check for inet/127.0.0.1
358#endif 420#endif
359 421
360 x_ev.start (fd, EVENT_READ); 422 x_ev.start (fd, EVENT_READ);
361 fcntl (fd, F_SETFD, FD_CLOEXEC); 423 fcntl (fd, F_SETFD, FD_CLOEXEC);
362 424
363 XSelectInput (display, root, PropertyChangeMask); 425 XSelectInput (dpy, root, PropertyChangeMask);
364 426
365 flush (); 427 flush ();
366 428
367 return true; 429 return true;
368} 430}
369 431
370void 432void
371rxvt_display::ref_next () 433rxvt_display::ref_next ()
372{ 434{
373 // TODO: somehow check wether the database files/resources changed 435 // TODO: somehow check wether the database files/resources changed
374 // before re-loading/parsing 436 // before affording re-loading/parsing
375 XrmDestroyDatabase (XrmGetDatabase (display)); 437 XrmDestroyDatabase (XrmGetDatabase (dpy));
376 XrmSetDatabase (display, get_resources ()); 438 XrmSetDatabase (dpy, get_resources (true));
377} 439}
378 440
379rxvt_display::~rxvt_display () 441rxvt_display::~rxvt_display ()
380{ 442{
381 if (!display) 443 if (!dpy)
382 return; 444 return;
383 445
384#ifdef POINTER_BLANK 446#ifdef POINTER_BLANK
385 XFreeCursor (display, blank_cursor); 447 XFreeCursor (dpy, blank_cursor);
386#endif 448#endif
387 x_ev.stop (); 449 x_ev.stop ();
388#ifdef USE_XIM 450#ifdef USE_XIM
389 xims.clear (); 451 xims.clear ();
390#endif 452#endif
391 XCloseDisplay (display); 453 XCloseDisplay (dpy);
392} 454}
393 455
394#ifdef USE_XIM 456#ifdef USE_XIM
395void rxvt_display::im_change_cb () 457void rxvt_display::im_change_cb ()
396{ 458{
404 // registers, as xlib crashes due to a race otherwise. 466 // registers, as xlib crashes due to a race otherwise.
405 Atom actual_type, *atoms; 467 Atom actual_type, *atoms;
406 int actual_format; 468 int actual_format;
407 unsigned long nitems, bytes_after; 469 unsigned long nitems, bytes_after;
408 470
409 if (XGetWindowProperty (display, root, xa[XA_XIM_SERVERS], 0L, 1000000L, 471 if (XGetWindowProperty (dpy, root, xa[XA_XIM_SERVERS], 0L, 1000000L,
410 False, XA_ATOM, &actual_type, &actual_format, 472 False, XA_ATOM, &actual_type, &actual_format,
411 &nitems, &bytes_after, (unsigned char **)&atoms) 473 &nitems, &bytes_after, (unsigned char **)&atoms)
412 != Success ) 474 != Success )
413 return; 475 return;
414 476
415 if (actual_type == XA_ATOM && actual_format == 32) 477 if (actual_type == XA_ATOM && actual_format == 32)
416 for (int i = 0; i < nitems; i++) 478 for (int i = 0; i < nitems; i++)
417 if (XGetSelectionOwner (display, atoms[i])) 479 if (XGetSelectionOwner (dpy, atoms[i]))
418 { 480 {
419 im_change_cb (); 481 im_change_cb ();
420 break; 482 break;
421 } 483 }
422 484
427void rxvt_display::x_cb (io_watcher &w, short revents) 489void rxvt_display::x_cb (io_watcher &w, short revents)
428{ 490{
429 do 491 do
430 { 492 {
431 XEvent xev; 493 XEvent xev;
432 XNextEvent (display, &xev); 494 XNextEvent (dpy, &xev);
433 495
434#ifdef USE_XIM 496#ifdef USE_XIM
435 if (!XFilterEvent (&xev, None)) 497 if (!XFilterEvent (&xev, None))
436 { 498 {
437 if (xev.type == PropertyNotify 499 if (xev.type == PropertyNotify
448 } 510 }
449#ifdef USE_XIM 511#ifdef USE_XIM
450 } 512 }
451#endif 513#endif
452 } 514 }
453 while (XEventsQueued (display, QueuedAlready)); 515 while (XEventsQueued (dpy, QueuedAlready));
454 516
455 XFlush (display); 517 XFlush (dpy);
456} 518}
457 519
458void rxvt_display::flush () 520void rxvt_display::flush ()
459{ 521{
460 if (XEventsQueued (display, QueuedAlready)) 522 if (XEventsQueued (dpy, QueuedAlready))
461 x_cb (x_ev, EVENT_READ); 523 x_cb (x_ev, EVENT_READ);
462 524
463 XFlush (display); 525 XFlush (dpy);
464} 526}
465 527
466void rxvt_display::reg (xevent_watcher *w) 528void rxvt_display::reg (xevent_watcher *w)
467{ 529{
468 xw.push_back (w); 530 xw.push_back (w);
482 544
483 selection_owner = owner; 545 selection_owner = owner;
484} 546}
485 547
486#ifdef USE_XIM 548#ifdef USE_XIM
549
487void rxvt_display::reg (im_watcher *w) 550void rxvt_display::reg (im_watcher *w)
488{ 551{
489 imw.push_back (w); 552 imw.push_back (w);
490} 553}
491 554
515 return xim; 578 return xim;
516} 579}
517 580
518void rxvt_display::put_xim (rxvt_xim *xim) 581void rxvt_display::put_xim (rxvt_xim *xim)
519{ 582{
520#if XLIB_IS_RACEFREE 583# if XLIB_IS_RACEFREE
521 xims.put (xim); 584 xims.put (xim);
522#endif 585# endif
523} 586}
587
524#endif 588#endif
525 589
526Atom rxvt_display::atom (const char *name) 590Atom rxvt_display::atom (const char *name)
527{ 591{
528 return XInternAtom (display, name, False); 592 return XInternAtom (dpy, name, False);
529} 593}
530 594
531///////////////////////////////////////////////////////////////////////////// 595/////////////////////////////////////////////////////////////////////////////
532 596
533template class refcache<rxvt_display>; 597template class refcache<rxvt_display>;
534refcache<rxvt_display> displays; 598refcache<rxvt_display> displays;
535 599
536///////////////////////////////////////////////////////////////////////////// 600/////////////////////////////////////////////////////////////////////////////
537 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->dpy, 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->dpy, 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->dpy, screen->cmap, &c))
655 return true;
656 else
657 c.pixel = (color.r + color.g + color.b) > 128*3
658 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->dpy))
659 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->dpy));
660#endif
661
662 return false;
663}
664
538bool 665bool
539rxvt_color::set (rxvt_screen *screen, const char *name) 666rxvt_color::set (rxvt_screen *screen, const char *name)
540{ 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->dpy, 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->dpy, 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{
541#if XFT 757#if XFT
542 int l = strlen (name); 758 color.r = c.color.red;
543 rxvt_rgba r; 759 color.g = c.color.green;
544 char eos; 760 color.b = c.color.blue;
545 int mult; 761 color.a = c.color.alpha;
546
547 if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
548 mult = 0x1111;
549 else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
550 mult = 0x0101;
551 else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
552 mult = 0x0001;
553 else
554 return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c);
555
556 r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult;
557 return set (screen, r);
558#else 762#else
559 XColor xc; 763 color.r = c.red;
560 764 color.g = c.green;
561 if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) 765 color.b = c.blue;
562 return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue)); 766 color.a = rgba::MAX_CC;
563
564 return false;
565#endif 767#endif
566} 768}
567 769
568bool
569rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
570{
571#if XFT
572 XRenderColor d;
573
574 d.red = rgba.r;
575 d.green = rgba.g;
576 d.blue = rgba.b;
577 d.alpha = rgba.a;
578
579 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
580#else
581 XColor xc;
582
583 xc.red = rgba.r;
584 xc.green = rgba.g;
585 xc.blue = rgba.b;
586 xc.flags = DoRed | DoGreen | DoBlue;
587
588 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
589 {
590 p = xc.pixel;
591 return true;
592 }
593
594 return false;
595#endif
596}
597
598void 770void
599rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba) 771rxvt_color::get (XColor &color)
600{ 772{
601#if XFT 773 rgba c;
602 rgba.r = c.color.red; 774 get (c);
603 rgba.g = c.color.green;
604 rgba.b = c.color.blue;
605 rgba.a = c.color.alpha;
606#else
607 XColor c;
608 775
609 c.pixel = p; 776 color.red = c.r;
610 XQueryColor (screen->xdisp, screen->cmap, &c); 777 color.green = c.g;
611 778 color.blue = c.b;
612 rgba.r = c.red; 779 color.pixel = (Pixel)*this;
613 rgba.g = c.green;
614 rgba.b = c.blue;
615 rgba.a = rxvt_rgba::MAX_CC;
616#endif
617} 780}
618 781
619void 782void
620rxvt_color::free (rxvt_screen *screen) 783rxvt_color::free (rxvt_screen *screen)
621{ 784{
622#if XFT 785#if XFT
623 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 786 XftColorFree (screen->dpy, screen->visual, screen->cmap, &c);
624#else 787#else
625 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 788 XFreeColors (screen->dpy, screen->cmap, &c.pixel, 1, AllPlanes);
626#endif 789#endif
627} 790}
628 791
629rxvt_color 792void
630rxvt_color::fade (rxvt_screen *screen, int percent)
631{
632 rxvt_color faded;
633
634 rxvt_rgba c;
635 get (screen, c);
636
637 c.r = lerp (0, c.r, percent);
638 c.g = lerp (0, c.g, percent);
639 c.b = lerp (0, c.b, percent);
640
641 faded.set (screen, c);
642
643 return faded;
644}
645
646rxvt_color
647rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto) 793rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
648{ 794{
649 rxvt_rgba c, fc; 795 rgba c;
650 rxvt_color faded; 796 get (c);
651
652 get (screen, c);
653 fadeto.get (screen, fc);
654 797
655 faded.set ( 798 result.set (
656 screen, 799 screen,
657 rxvt_rgba ( 800 rgba (
658 lerp (fc.r, c.r, percent), 801 lerp (c.r, to.r, percent),
659 lerp (fc.g, c.g, percent), 802 lerp (c.g, to.g, percent),
660 lerp (fc.b, c.b, percent), 803 lerp (c.b, to.b, percent),
661 lerp (fc.a, c.a, percent) 804 lerp (c.a, to.a, percent)
662 ) 805 )
663 ); 806 );
664
665 return faded;
666} 807}
667 808

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines