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.41 by root, Tue Jan 31 16:43:55 2006 UTC vs.
Revision 1.59 by root, Wed Jul 5 20:31:48 2006 UTC

1/*--------------------------------*-C-*---------------------------------* 1/*----------------------------------------------------------------------*
2 * File: rxvttoolkit.C 2 * File: rxvttoolkit.C
3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * 4 *
5 * All portions of code are copyright by their respective author/s. 5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 2003-2004 Marc Lehmann <pcg@goof.com> 6 * Copyright (c) 2003-2006 Marc Lehmann <pcg@goof.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
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> 30#include <sys/utsname.h>
31
32#ifndef NO_SLOW_LINK_SUPPORT
33# include <sys/socket.h> 31#include <sys/socket.h>
34# include <sys/un.h> 32#include <sys/un.h>
35#endif
36 33
37#if XFT 34#if XFT
38# include <X11/extensions/Xrender.h> 35# include <X11/extensions/Xrender.h>
39#endif 36#endif
40 37
177bool 174bool
178rxvt_xim::ref_init () 175rxvt_xim::ref_init ()
179{ 176{
180 display = GET_R->display; //HACK: TODO 177 display = GET_R->display; //HACK: TODO
181 178
182 xim = XOpenIM (display->display, NULL, NULL, NULL); 179 xim = XOpenIM (display->dpy, 0, 0, 0);
183 180
184 if (!xim) 181 if (!xim)
185 return false; 182 return false;
186 183
187 XIMCallback ximcallback; 184 XIMCallback ximcallback;
188 ximcallback.client_data = (XPointer)this; 185 ximcallback.client_data = (XPointer)this;
189 ximcallback.callback = im_destroy_cb; 186 ximcallback.callback = im_destroy_cb;
190 187
191 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL); 188 XSetIMValues (xim, XNDestroyCallback, &ximcallback, 0);
192 189
193 return true; 190 return true;
194} 191}
195 192
196rxvt_xim::~rxvt_xim () 193rxvt_xim::~rxvt_xim ()
201 198
202#endif 199#endif
203 200
204///////////////////////////////////////////////////////////////////////////// 201/////////////////////////////////////////////////////////////////////////////
205 202
203#if XFT
204rxvt_drawable::~rxvt_drawable ()
205{
206 if (xftdrawable)
207 XftDrawDestroy (xftdrawable);
208}
209
210rxvt_drawable::operator XftDraw *()
211{
212 if (!xftdrawable)
213 xftdrawable = XftDrawCreate (screen->dpy, drawable, screen->visual, screen->cmap);
214
215 return xftdrawable;
216}
217#endif
218
219/////////////////////////////////////////////////////////////////////////////
220
221#if XFT
222
223// not strictly necessary as it is only used with superclass of zero_initialised
224rxvt_screen::rxvt_screen ()
225: scratch_area (0)
226{
227}
228
229rxvt_drawable &rxvt_screen::scratch_drawable (int w, int h)
230{
231 // it's actually faster to re-allocate every time. don't ask me
232 // why, but its likely no big deal there are no roundtrips
233 // (I think/hope).
234 if (!scratch_area || w > scratch_w || h > scratch_h || 1/*D*/)
235 {
236 if (scratch_area)
237 {
238 XFreePixmap (dpy, scratch_area->drawable);
239 delete scratch_area;
240 }
241
242 Pixmap pm = XCreatePixmap (dpy, RootWindowOfScreen (ScreenOfDisplay (dpy, display->screen)),
243 scratch_w = w, scratch_h = h, depth);
244
245 scratch_area = new rxvt_drawable (this, pm);
246 }
247
248 return *scratch_area;
249}
250
251#endif
252
206void 253void
207rxvt_screen::set (rxvt_display *disp) 254rxvt_screen::set (rxvt_display *disp)
208{ 255{
209 display = disp; 256 display = disp;
210 xdisp = disp->display; 257 dpy = disp->dpy;
211 258
212 Screen *screen = ScreenOfDisplay (xdisp, disp->screen); 259 Screen *screen = ScreenOfDisplay (dpy, disp->screen);
213 260
214 depth = DefaultDepthOfScreen (screen); 261 depth = DefaultDepthOfScreen (screen);
215 visual = DefaultVisualOfScreen (screen); 262 visual = DefaultVisualOfScreen (screen);
216 cmap = DefaultColormapOfScreen (screen); 263 cmap = DefaultColormapOfScreen (screen);
217} 264}
218 265
219void 266void
220rxvt_screen::set (rxvt_display *disp, int bitdepth) 267rxvt_screen::select_visual (int bitdepth)
221{ 268{
222 set (disp);
223
224#if XFT 269#if XFT
225 XVisualInfo vinfo; 270 XVisualInfo vinfo;
226 271
227 if (XMatchVisualInfo (xdisp, display->screen, bitdepth, TrueColor, &vinfo)) 272 if (XMatchVisualInfo (dpy, display->screen, bitdepth, TrueColor, &vinfo))
228 { 273 {
229 depth = bitdepth; 274 depth = bitdepth;
230 visual = vinfo.visual; 275 visual = vinfo.visual;
231 cmap = XCreateColormap (xdisp, disp->root, visual, AllocNone); 276 cmap = XCreateColormap (dpy, display->root, visual, AllocNone);
232 } 277 }
233#endif 278#endif
234} 279}
235 280
236void 281void
237rxvt_screen::clear () 282rxvt_screen::clear ()
238{ 283{
284#if XFT
285 if (scratch_area)
286 {
287 XFreePixmap (dpy, scratch_area->drawable);
288 delete scratch_area;
289 }
290#endif
291
239 if (cmap != DefaultColormapOfScreen (ScreenOfDisplay (xdisp, display->screen))) 292 if (cmap != DefaultColormapOfScreen (ScreenOfDisplay (dpy, display->screen)))
240 XFreeColormap (xdisp, cmap); 293 XFreeColormap (dpy, cmap);
241} 294}
242 295
243///////////////////////////////////////////////////////////////////////////// 296/////////////////////////////////////////////////////////////////////////////
244 297
245rxvt_display::rxvt_display (const char *id) 298rxvt_display::rxvt_display (const char *id)
248, selection_owner (0) 301, selection_owner (0)
249{ 302{
250} 303}
251 304
252XrmDatabase 305XrmDatabase
253rxvt_display::get_resources () 306rxvt_display::get_resources (bool refresh)
254{ 307{
255 char *homedir = (char *)getenv ("HOME"); 308 char *homedir = (char *)getenv ("HOME");
256 char fname[1024]; 309 char fname[1024];
257 310
258 /* 311 /*
259 * get resources using the X library function 312 * get resources using the X library function
260 */ 313 */
261 char *displayResource, *xe; 314 char *displayResource, *xe;
262 XrmDatabase database, rdb1; 315 XrmDatabase rdb1, database = 0;
263
264 database = NULL;
265 316
266 // for ordering, see for example http://www.faqs.org/faqs/Xt-FAQ/ Subject: 20 317 // for ordering, see for example http://www.faqs.org/faqs/Xt-FAQ/ Subject: 20
267 318
268 // 6. System wide per application default file. 319 // 6. System wide per application default file.
269 320
279 // 5. User's per application default file. 330 // 5. User's per application default file.
280 // none 331 // none
281 332
282 // 4. User's defaults file. 333 // 4. User's defaults file.
283 /* Get any Xserver defaults */ 334 /* Get any Xserver defaults */
335 if (refresh)
336 {
337 // fucking xlib keeps a copy of the rm string
338 Atom actual_type;
339 int actual_format;
340 unsigned long nitems, nremaining;
341 char *val = 0;
342
343#if XLIB_ILLEGAL_ACCESS
344 if (dpy->xdefaults)
345 XFree (dpy->xdefaults);
346#endif
347
348 if (XGetWindowProperty (dpy, RootWindow (dpy, 0), XA_RESOURCE_MANAGER,
349 0L, 100000000L, False,
350 XA_STRING, &actual_type, &actual_format,
351 &nitems, &nremaining,
352 (unsigned char **)&val) == Success
353 && actual_type == XA_STRING
354 && actual_format == 8)
355 displayResource = val;
356 else
357 {
358 displayResource = 0;
359 if (val)
360 XFree(val);
361 }
362
363#if XLIB_ILLEGAL_ACCESS
364 dpy->xdefaults = displayResource;
365#endif
366 }
367 else
284 displayResource = XResourceManagerString (display); 368 displayResource = XResourceManagerString (dpy);
285 369
286 if (displayResource != NULL) 370 if (displayResource)
287 { 371 {
288 if ((rdb1 = XrmGetStringDatabase (displayResource))) 372 if ((rdb1 = XrmGetStringDatabase (displayResource)))
289 XrmMergeDatabases (rdb1, &database); 373 XrmMergeDatabases (rdb1, &database);
290 } 374 }
291 else if (homedir) 375 else if (homedir)
294 378
295 if ((rdb1 = XrmGetFileDatabase (fname))) 379 if ((rdb1 = XrmGetFileDatabase (fname)))
296 XrmMergeDatabases (rdb1, &database); 380 XrmMergeDatabases (rdb1, &database);
297 } 381 }
298 382
383#if !XLIB_ILLEGAL_ACCESS
384 if (refresh && displayResource)
385 XFree (displayResource);
386#endif
387
299 /* Get screen specific resources */ 388 /* Get screen specific resources */
300 displayResource = XScreenResourceString (ScreenOfDisplay (display, screen)); 389 displayResource = XScreenResourceString (ScreenOfDisplay (dpy, screen));
301 390
302 if (displayResource != NULL) 391 if (displayResource)
303 { 392 {
304 if ((rdb1 = XrmGetStringDatabase (displayResource))) 393 if ((rdb1 = XrmGetStringDatabase (displayResource)))
305 /* Merge with screen-independent resources */ 394 /* Merge with screen-independent resources */
306 XrmMergeDatabases (rdb1, &database); 395 XrmMergeDatabases (rdb1, &database);
307 396
335 if (id[0] == ':') 424 if (id[0] == ':')
336 { 425 {
337 val = rxvt_malloc (5 + strlen (id) + 1); 426 val = rxvt_malloc (5 + strlen (id) + 1);
338 strcpy (val, "unix/"); 427 strcpy (val, "unix/");
339 strcat (val, id); 428 strcat (val, id);
340 display = XOpenDisplay (val); 429 dpy = XOpenDisplay (val);
341 free (val); 430 free (val);
342 } 431 }
343 else 432 else
344#endif 433#endif
345 display = 0; 434 dpy = 0;
346 435
347 if (!display) 436 if (!dpy)
348 display = XOpenDisplay (id); 437 dpy = XOpenDisplay (id);
349 438
350 if (!display) 439 if (!dpy)
351 return false; 440 return false;
352 441
353 screen = DefaultScreen (display); 442 screen = DefaultScreen (dpy);
354 root = DefaultRootWindow (display); 443 root = DefaultRootWindow (dpy);
355 444
356 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA); 445 assert (sizeof (xa_names) / sizeof (char *) == NUM_XA);
357 XInternAtoms (display, (char **)xa_names, NUM_XA, False, xa); 446 XInternAtoms (dpy, (char **)xa_names, NUM_XA, False, xa);
358 447
359 XrmSetDatabase (display, get_resources ()); 448 XrmSetDatabase (dpy, get_resources (false));
360 449
361#ifdef POINTER_BLANK 450#ifdef POINTER_BLANK
362 XColor blackcolour; 451 XColor blackcolour;
363 blackcolour.red = 0; 452 blackcolour.red = 0;
364 blackcolour.green = 0; 453 blackcolour.green = 0;
365 blackcolour.blue = 0; 454 blackcolour.blue = 0;
366 Font f = XLoadFont (display, "fixed"); 455 Font f = XLoadFont (dpy, "fixed");
367 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ', 456 blank_cursor = XCreateGlyphCursor (dpy, f, f, ' ', ' ',
368 &blackcolour, &blackcolour); 457 &blackcolour, &blackcolour);
369 XUnloadFont (display, f); 458 XUnloadFont (dpy, f);
370#endif 459#endif
371 460
372 int fd = XConnectionNumber (display); 461 int fd = XConnectionNumber (dpy);
373 462
374#ifndef NO_SLOW_LINK_SUPPORT
375 // try to detect wether we have a local connection. 463 // try to detect wether we have a local connection.
376 // assume unix domains socket == local, everything else not 464 // assume unix domains socket == local, everything else not
377 // TODO: might want to check for inet/127.0.0.1 465 // TODO: might want to check for inet/127.0.0.1
378 is_local = 0; 466 is_local = 0;
379 sockaddr_un sa; 467 sockaddr_un sa;
380 socklen_t sl = sizeof (sa); 468 socklen_t sl = sizeof (sa);
381 469
382 if (!getsockname (fd, (sockaddr *)&sa, &sl)) 470 if (!getsockname (fd, (sockaddr *)&sa, &sl))
383 is_local = sa.sun_family == AF_LOCAL; 471 is_local = sa.sun_family == AF_LOCAL;
384#endif
385 472
386 x_ev.start (fd, EVENT_READ); 473 x_ev.start (fd, EVENT_READ);
387 fcntl (fd, F_SETFD, FD_CLOEXEC); 474 fcntl (fd, F_SETFD, FD_CLOEXEC);
388 475
389 XSelectInput (display, root, PropertyChangeMask); 476 XSelectInput (dpy, root, PropertyChangeMask);
390 477
391 flush (); 478 flush ();
392 479
393 return true; 480 return true;
394} 481}
395 482
396void 483void
397rxvt_display::ref_next () 484rxvt_display::ref_next ()
398{ 485{
399 // TODO: somehow check wether the database files/resources changed 486 // TODO: somehow check wether the database files/resources changed
400 // before re-loading/parsing 487 // before affording re-loading/parsing
401 XrmDestroyDatabase (XrmGetDatabase (display)); 488 XrmDestroyDatabase (XrmGetDatabase (dpy));
402 XrmSetDatabase (display, get_resources ()); 489 XrmSetDatabase (dpy, get_resources (true));
403} 490}
404 491
405rxvt_display::~rxvt_display () 492rxvt_display::~rxvt_display ()
406{ 493{
407 if (!display) 494 if (!dpy)
408 return; 495 return;
409 496
410#ifdef POINTER_BLANK 497#ifdef POINTER_BLANK
411 XFreeCursor (display, blank_cursor); 498 XFreeCursor (dpy, blank_cursor);
412#endif 499#endif
413 x_ev.stop (); 500 x_ev.stop ();
414#ifdef USE_XIM 501#ifdef USE_XIM
415 xims.clear (); 502 xims.clear ();
416#endif 503#endif
417 XCloseDisplay (display); 504 XCloseDisplay (dpy);
418} 505}
419 506
420#ifdef USE_XIM 507#ifdef USE_XIM
421void rxvt_display::im_change_cb () 508void rxvt_display::im_change_cb ()
422{ 509{
430 // registers, as xlib crashes due to a race otherwise. 517 // registers, as xlib crashes due to a race otherwise.
431 Atom actual_type, *atoms; 518 Atom actual_type, *atoms;
432 int actual_format; 519 int actual_format;
433 unsigned long nitems, bytes_after; 520 unsigned long nitems, bytes_after;
434 521
435 if (XGetWindowProperty (display, root, xa[XA_XIM_SERVERS], 0L, 1000000L, 522 if (XGetWindowProperty (dpy, root, xa[XA_XIM_SERVERS], 0L, 1000000L,
436 False, XA_ATOM, &actual_type, &actual_format, 523 False, XA_ATOM, &actual_type, &actual_format,
437 &nitems, &bytes_after, (unsigned char **)&atoms) 524 &nitems, &bytes_after, (unsigned char **)&atoms)
438 != Success ) 525 != Success )
439 return; 526 return;
440 527
441 if (actual_type == XA_ATOM && actual_format == 32) 528 if (actual_type == XA_ATOM && actual_format == 32)
442 for (int i = 0; i < nitems; i++) 529 for (int i = 0; i < nitems; i++)
443 if (XGetSelectionOwner (display, atoms[i])) 530 if (XGetSelectionOwner (dpy, atoms[i]))
444 { 531 {
445 im_change_cb (); 532 im_change_cb ();
446 break; 533 break;
447 } 534 }
448 535
453void rxvt_display::x_cb (io_watcher &w, short revents) 540void rxvt_display::x_cb (io_watcher &w, short revents)
454{ 541{
455 do 542 do
456 { 543 {
457 XEvent xev; 544 XEvent xev;
458 XNextEvent (display, &xev); 545 XNextEvent (dpy, &xev);
459 546
460#ifdef USE_XIM 547#ifdef USE_XIM
461 if (!XFilterEvent (&xev, None)) 548 if (!XFilterEvent (&xev, None))
462 { 549 {
463 if (xev.type == PropertyNotify 550 if (xev.type == PropertyNotify
474 } 561 }
475#ifdef USE_XIM 562#ifdef USE_XIM
476 } 563 }
477#endif 564#endif
478 } 565 }
479 while (XEventsQueued (display, QueuedAlready)); 566 while (XEventsQueued (dpy, QueuedAlready));
480 567
481 XFlush (display); 568 XFlush (dpy);
482} 569}
483 570
484void rxvt_display::flush () 571void rxvt_display::flush ()
485{ 572{
486 if (XEventsQueued (display, QueuedAlready)) 573 if (XEventsQueued (dpy, QueuedAlready))
487 x_cb (x_ev, EVENT_READ); 574 x_cb (x_ev, EVENT_READ);
488 575
489 XFlush (display); 576 XFlush (dpy);
490} 577}
491 578
492void rxvt_display::reg (xevent_watcher *w) 579void rxvt_display::reg (xevent_watcher *w)
493{ 580{
494 xw.push_back (w); 581 xw.push_back (w);
508 595
509 selection_owner = owner; 596 selection_owner = owner;
510} 597}
511 598
512#ifdef USE_XIM 599#ifdef USE_XIM
600
513void rxvt_display::reg (im_watcher *w) 601void rxvt_display::reg (im_watcher *w)
514{ 602{
515 imw.push_back (w); 603 imw.push_back (w);
516} 604}
517 605
541 return xim; 629 return xim;
542} 630}
543 631
544void rxvt_display::put_xim (rxvt_xim *xim) 632void rxvt_display::put_xim (rxvt_xim *xim)
545{ 633{
546#if XLIB_IS_RACEFREE 634# if XLIB_IS_RACEFREE
547 xims.put (xim); 635 xims.put (xim);
548#endif 636# endif
549} 637}
638
550#endif 639#endif
551 640
552Atom rxvt_display::atom (const char *name) 641Atom rxvt_display::atom (const char *name)
553{ 642{
554 return XInternAtom (display, name, False); 643 return XInternAtom (dpy, name, False);
555} 644}
556 645
557///////////////////////////////////////////////////////////////////////////// 646/////////////////////////////////////////////////////////////////////////////
558 647
559template class refcache<rxvt_display>; 648template class refcache<rxvt_display>;
560refcache<rxvt_display> displays; 649refcache<rxvt_display> displays;
561 650
562///////////////////////////////////////////////////////////////////////////// 651/////////////////////////////////////////////////////////////////////////////
652//
653
654static unsigned int
655insert_component (unsigned int value, unsigned int mask, unsigned int shift)
656{
657 return (value * (mask + 1) >> 16) << shift;
658}
563 659
564bool 660bool
565rxvt_color::alloc (rxvt_screen *screen, const rxvt_rgba &color) 661rxvt_color::alloc (rxvt_screen *screen, const rgba &color)
566{ 662{
567#if XFT 663#if XFT
568 XRenderPictFormat *format; 664 XRenderPictFormat *format;
569 665
570 // FUCKING Xft gets it wrong, of course, so work around it 666 // FUCKING Xft gets it wrong, of course, so work around it.
571 // transparency users should eat shit and die, and then 667 // Transparency users should eat shit and die, and then
572 // XRenderQueryPictIndexValues themselves plenty. 668 // XRenderQueryPictIndexValues themselves plenty.
573 if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor) 669 if ((screen->visual->c_class == TrueColor)
574 && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual))) 670 && (format = XRenderFindVisualFormat (screen->dpy, screen->visual)))
575 { 671 {
576 // the fun lies in doing everything manually... 672 // the fun lies in doing everything manually...
577 c.color.red = color.r; 673 c.color.red = color.r;
578 c.color.green = color.g; 674 c.color.green = color.g;
579 c.color.blue = color.b; 675 c.color.blue = color.b;
580 c.color.alpha = color.a; 676 c.color.alpha = color.a;
581 677
582 c.pixel = ((color.r * format->direct.redMask / rxvt_rgba::MAX_CC) << format->direct.red ) 678 c.pixel = insert_component (color.r, format->direct.redMask , format->direct.red )
583 | ((color.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green) 679 | insert_component (color.g, format->direct.greenMask, format->direct.green)
584 | ((color.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue ) 680 | insert_component (color.b, format->direct.blueMask , format->direct.blue )
585 | ((color.a * format->direct.alphaMask / rxvt_rgba::MAX_CC) << format->direct.alpha); 681 | insert_component (color.a, format->direct.alphaMask, format->direct.alpha);
586 682
587 return true; 683 return true;
588 } 684 }
589 else 685 else
590 { 686 {
593 d.red = color.r; 689 d.red = color.r;
594 d.green = color.g; 690 d.green = color.g;
595 d.blue = color.b; 691 d.blue = color.b;
596 d.alpha = color.a; 692 d.alpha = color.a;
597 693
598 return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c); 694 return XftColorAllocValue (screen->dpy, screen->visual, screen->cmap, &d, &c);
599 } 695 }
600#else 696#else
601 if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor) 697 c.red = color.r;
698 c.green = color.g;
699 c.blue = color.b;
700
701 if (screen->visual->c_class == TrueColor)
602 { 702 {
603 p = (color.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask )) 703 c.pixel = (color.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask ))
604 / rxvt_rgba::MAX_CC) << ctz (screen->visual->red_mask ) 704 / rgba::MAX_CC) << ctz (screen->visual->red_mask )
605 | (color.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask)) 705 | (color.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask))
606 / rxvt_rgba::MAX_CC) << ctz (screen->visual->green_mask) 706 / rgba::MAX_CC) << ctz (screen->visual->green_mask)
607 | (color.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask )) 707 | (color.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask ))
608 / rxvt_rgba::MAX_CC) << ctz (screen->visual->blue_mask ); 708 / rgba::MAX_CC) << ctz (screen->visual->blue_mask );
609 709
610 return true; 710 return true;
611 } 711 }
712 else if (XAllocColor (screen->dpy, screen->cmap, &c))
713 return true;
612 else 714 else
613 {
614 XColor xc;
615
616 xc.red = color.r;
617 xc.green = color.g;
618 xc.blue = color.b;
619
620 if (XAllocColor (screen->xdisp, screen->cmap, &xc))
621 {
622 p = xc.pixel;
623 return true;
624 }
625 else
626 p = (color.r + color.g + color.b) > 128*3 715 c.pixel = (color.r + color.g + color.b) > 128*3
627 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->xdisp)) 716 ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->dpy))
628 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->xdisp)); 717 : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->dpy));
629 }
630#endif 718#endif
631 719
632 return false; 720 return false;
633} 721}
634 722
635bool 723bool
636rxvt_color::set (rxvt_screen *screen, const char *name) 724rxvt_color::set (rxvt_screen *screen, const char *name)
637{ 725{
638 rxvt_rgba c; 726 rgba c;
639 char eos; 727 char eos;
640 int skip; 728 int skip;
641 729
730 // parse the nonstandard "[alphapercent]" prefix
642 if (1 <= sscanf (name, "[%hd]%n", &c.a, &skip)) 731 if (1 <= sscanf (name, "[%hd]%n", &c.a, &skip))
643 { 732 {
644 c.a = lerp<int, int, int> (0, rxvt_rgba::MAX_CC, c.a); 733 c.a = lerp<int, int, int> (0, rgba::MAX_CC, c.a);
645 name += skip; 734 name += skip;
646 } 735 }
647 else 736 else
648 c.a = rxvt_rgba::MAX_CC; 737 c.a = rgba::MAX_CC;
649 738
650 // parse the non-standard rgba format 739 // parse the non-standard "rgba:rrrr/gggg/bbbb/aaaa" format
651 if (strlen (name) != 4+5*4 || 4 != sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &c.r, &c.g, &c.b, &c.a, &eos)) 740 if (strlen (name) != 4+5*4 || 4 != sscanf (name, "rgba:%4hx/%4hx/%4hx/%4hx%c", &c.r, &c.g, &c.b, &c.a, &eos))
652 { 741 {
653 XColor xc, xc_exact; 742 XColor xc, xc_exact;
654 743
655 if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) 744 if (XParseColor (screen->dpy, screen->cmap, name, &xc))
656 { 745 {
657 c.r = xc.red; 746 c.r = xc.red;
658 c.g = xc.green; 747 c.g = xc.green;
659 c.b = xc.blue; 748 c.b = xc.blue;
660 } 749 }
670 759
671 return set (screen, c); 760 return set (screen, c);
672} 761}
673 762
674bool 763bool
675rxvt_color::set (rxvt_screen *screen, const rxvt_rgba &color) 764rxvt_color::set (rxvt_screen *screen, const rgba &color)
676{ 765{
677 bool got = alloc (screen, color); 766 bool got = alloc (screen, color);
678 767
679#if !ENABLE_MINIMAL 768#if !ENABLE_MINIMAL
680 int cmap_size = screen->visual->map_entries; 769 int cmap_size = screen->visual->map_entries;
686 XColor *colors = new XColor [screen->visual->map_entries]; 775 XColor *colors = new XColor [screen->visual->map_entries];
687 776
688 for (int i = 0; i < cmap_size; i++) 777 for (int i = 0; i < cmap_size; i++)
689 colors [i].pixel = i; 778 colors [i].pixel = i;
690 779
780 // many kilobytes transfer per colour, but pseudocolor isn't worth
781 // many extra optimisations.
691 XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size); 782 XQueryColors (screen->dpy, screen->cmap, colors, cmap_size);
692 783
693 int diff = 0x7fffffffUL; 784 int diff = 0x7fffffffUL;
694 XColor *best = colors; 785 XColor *best = colors;
695 786
696 for (int i = 0; i < cmap_size; i++) 787 for (int i = 0; i < cmap_size; i++)
707 } 798 }
708 799
709 //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n", 800 //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n",
710 // color.r, color.g, color.b, best->red, best->green, best->blue, diff); 801 // color.r, color.g, color.b, best->red, best->green, best->blue, diff);
711 802
712 got = alloc (screen, rxvt_rgba (best->red, best->green, best->blue)); 803 got = alloc (screen, rgba (best->red, best->green, best->blue));
713 804
714 delete colors; 805 delete colors;
715 } 806 }
716#endif 807#endif
717 808
718 return got; 809 return got;
719} 810}
720 811
721void 812void
722rxvt_color::get (rxvt_screen *screen, rxvt_rgba &color) 813rxvt_color::get (rgba &color)
723{ 814{
724#if XFT 815#if XFT
725 color.r = c.color.red; 816 color.r = c.color.red;
726 color.g = c.color.green; 817 color.g = c.color.green;
727 color.b = c.color.blue; 818 color.b = c.color.blue;
728 color.a = c.color.alpha; 819 color.a = c.color.alpha;
729#else 820#else
730 XColor c;
731
732 c.pixel = p;
733 XQueryColor (screen->xdisp, screen->cmap, &c);
734
735 color.r = c.red; 821 color.r = c.red;
736 color.g = c.green; 822 color.g = c.green;
737 color.b = c.blue; 823 color.b = c.blue;
738 color.a = rxvt_rgba::MAX_CC; 824 color.a = rgba::MAX_CC;
739#endif 825#endif
826}
827
828void
829rxvt_color::get (XColor &color)
830{
831 rgba c;
832 get (c);
833
834 color.red = c.r;
835 color.green = c.g;
836 color.blue = c.b;
837 color.pixel = (Pixel)*this;
740} 838}
741 839
742void 840void
743rxvt_color::free (rxvt_screen *screen) 841rxvt_color::free (rxvt_screen *screen)
744{ 842{
843 if (screen->visual->c_class == TrueColor)
844 return; // nothing to do
845
745#if XFT 846#if XFT
746 XftColorFree (screen->xdisp, screen->visual, screen->cmap, &c); 847 XftColorFree (screen->dpy, screen->visual, screen->cmap, &c);
747#else 848#else
748 XFreeColors (screen->xdisp, screen->cmap, &p, 1, AllPlanes); 849 XFreeColors (screen->dpy, screen->cmap, &c.pixel, 1, AllPlanes);
749#endif 850#endif
750} 851}
751 852
752rxvt_color 853void
753rxvt_color::fade (rxvt_screen *screen, int percent, const rxvt_rgba &to) 854rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &result, const rgba &to)
754{ 855{
755 rxvt_rgba c; 856 rgba c;
756 get (screen, c); 857 get (c);
757 858
758 rxvt_color faded; 859 result.set (
759 faded.set (
760 screen, 860 screen,
761 rxvt_rgba ( 861 rgba (
762 lerp (to.r, c.r, percent), 862 lerp (c.r, to.r, percent),
763 lerp (to.g, c.g, percent), 863 lerp (c.g, to.g, percent),
764 lerp (to.b, c.b, percent), 864 lerp (c.b, to.b, percent),
765 lerp (to.a, c.a, percent) 865 lerp (c.a, to.a, percent)
766 ) 866 )
767 ); 867 );
768
769 return faded;
770} 868}
771 869

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines