--- rxvt-unicode/src/rxvttoolkit.C 2011/05/30 18:39:03 1.127 +++ rxvt-unicode/src/rxvttoolkit.C 2014/12/17 13:16:18 1.147 @@ -8,7 +8,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -25,6 +25,8 @@ #include #include +#include + #include #include @@ -68,7 +70,7 @@ "WM_LOCALE_NAME", "XIM_SERVERS", #endif -#ifdef ENABLE_TRANSPARENCY +#if HAVE_IMG || ENABLE_PERL "_XROOTPMAP_ID", "ESETROOT_PMAP_ID", #endif @@ -155,7 +157,7 @@ ///////////////////////////////////////////////////////////////////////////// -#ifdef USE_XIM +#if USE_XIM static void #if XIMCB_PROTO_BROKEN @@ -262,22 +264,42 @@ cmap = DefaultColormapOfScreen (screen); } +#if ENABLE_FRILLS + void -rxvt_screen::select_visual (int bitdepth) +rxvt_screen::select_visual (int id) { -#if XFT XVisualInfo vinfo; + vinfo.visualid = id; + int n; - if (XMatchVisualInfo (dpy, display->screen, bitdepth, TrueColor, &vinfo)) + if (XVisualInfo *vi = XGetVisualInfo (dpy, VisualIDMask, &vinfo, &n)) { - depth = bitdepth; - visual = vinfo.visual; - cmap = XCreateColormap (dpy, display->root, visual, AllocNone); + depth = vi->depth; + visual = vi->visual; + + XFree (vi); + + cmap = XCreateColormap (dpy, display->root, visual, AllocNone); } -#endif + else + rxvt_warn ("no visual found for requested id 0x%02x, using default visual.\n", id); } void +rxvt_screen::select_depth (int bitdepth) +{ + XVisualInfo vinfo; + + if (XMatchVisualInfo (dpy, display->screen, bitdepth, TrueColor, &vinfo)) + select_visual (vinfo.visualid); + else + rxvt_warn ("no visual found for requested depth %d, using default visual.\n", bitdepth); +} + +#endif + +void rxvt_screen::clear () { #if XFT @@ -432,10 +454,11 @@ #ifdef LOCAL_X_IS_UNIX if (id[0] == ':') { - if (!(val = rxvt_temp_buf (5 + strlen (id) + 1))) - return false; + char *val = rxvt_temp_buf (5 + strlen (id) + 1); + strcpy (val, "unix/"); strcat (val, id); + dpy = XOpenDisplay (val); } else @@ -467,6 +490,25 @@ XUnloadFont (dpy, f); #endif + flags = 0; +#if XRENDER + int major, minor; + if (XRenderQueryVersion (dpy, &major, &minor)) + if (major > 0 || (major == 0 && minor >= 11)) + { + flags |= DISPLAY_HAS_RENDER; + + if (XFilters *filters = XRenderQueryFilters (dpy, root)) + { + for (int i = 0; i < filters->nfilter; i++) + if (!strcmp (filters->filter [i], FilterConvolution)) + flags |= DISPLAY_HAS_RENDER_CONV; + + XFree (filters); + } + } +#endif + int fd = XConnectionNumber (dpy); // try to detect whether we have a local connection. @@ -513,14 +555,14 @@ #endif x_ev.stop (); flush_ev.stop (); -#ifdef USE_XIM +#if USE_XIM xims.clear (); #endif XrmDestroyDatabase (XrmGetDatabase (dpy)); XCloseDisplay (dpy); } -#ifdef USE_XIM +#if USE_XIM void rxvt_display::im_change_cb () { for (im_watcher **i = imw.begin (); i != imw.end (); ++i) @@ -566,7 +608,7 @@ XEvent xev; XNextEvent (dpy, &xev); -#ifdef USE_XIM +#if USE_XIM if (!XFilterEvent (&xev, None)) { if (xev.type == PropertyNotify @@ -584,7 +626,7 @@ else if (xw[i]->window == xev.xany.window) xw[i]->call (xev); } -#ifdef USE_XIM +#if USE_XIM } #endif } @@ -625,7 +667,7 @@ cur_owner = owner; } -#ifdef USE_XIM +#if USE_XIM void rxvt_display::reg (im_watcher *w) { @@ -670,6 +712,28 @@ return XInternAtom (dpy, name, False); } +Pixmap +rxvt_display::get_pixmap_property (Atom property) +{ + Pixmap pixmap = None; + + int aformat; + unsigned long nitems, bytes_after; + Atom atype; + unsigned char *prop; + int result = XGetWindowProperty (dpy, root, property, + 0L, 1L, False, XA_PIXMAP, &atype, &aformat, + &nitems, &bytes_after, &prop); + if (result == Success) + { + if (atype == XA_PIXMAP) + pixmap = *(Pixmap *)prop; + XFree (prop); + } + + return pixmap; +} + ///////////////////////////////////////////////////////////////////////////// template class refcache; @@ -688,7 +752,7 @@ rxvt_color::alloc (rxvt_screen *screen, const rgba &color) { //TODO: only supports 24 bit - int alpha = color.a >= 0xff00 ? 0xffff : color.a; + unsigned int alpha = color.a >= 0xff00 ? 0xffff : color.a; #if XFT XRenderPictFormat *format; @@ -727,7 +791,9 @@ d.blue = color.b; d.alpha = alpha; - return XftColorAllocValue (screen->dpy, screen->visual, screen->cmap, &d, &c); + // XftColorAlloc always returns 100% transparent pixels(!) + if (XftColorAllocValue (screen->dpy, screen->visual, screen->cmap, &d, &c)) + return true; } #else c.red = color.r; @@ -744,12 +810,13 @@ } else if (XAllocColor (screen->dpy, screen->cmap, &c)) return true; - else - c.pixel = (color.r + color.g + color.b) > 128*3 - ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->dpy)) - : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->dpy)); #endif + //TODO: set c.color* or c.* + c.pixel = (color.r * 2 + color.g * 3 + color.b) >= 0x8000 * 6 + ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->dpy)) + : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->dpy)); + return false; } @@ -814,26 +881,35 @@ // many extra optimisations. XQueryColors (screen->dpy, screen->cmap, colors, cmap_size); - int diff = 0x7fffffffUL; - XColor *best = colors; - - for (int i = 0; i < cmap_size; i++) + while (cmap_size) { - int d = (squared_diff (color.r >> 2, colors [i].red >> 2)) - + (squared_diff (color.g >> 2, colors [i].green >> 2)) - + (squared_diff (color.b >> 2, colors [i].blue >> 2)); + int diff = 0x7fffffffL; + XColor *best = colors; - if (d < diff) + for (int i = 0; i < cmap_size; i++) { - diff = d; - best = colors + i; + // simple weighted rgb distance sucks, but keeps it simple + int d = abs (color.r - colors [i].red ) * 2 + + abs (color.g - colors [i].green) * 3 + + abs (color.b - colors [i].blue ); + + if (d < diff) + { + diff = d; + best = colors + i; + } } - } - //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n", - // color.r, color.g, color.b, best->red, best->green, best->blue, diff); + //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d,%d)\n", + // color.r, color.g, color.b, best->red, best->green, best->blue, diff, best - colors); - got = alloc (screen, rgba (best->red, best->green, best->blue)); + got = alloc (screen, rgba (best->red, best->green, best->blue)); + + if (got) + break; + + *best = colors [--cmap_size]; + } delete [] colors; } @@ -843,9 +919,10 @@ } void -rxvt_color::get (rgba &color) +rxvt_color::get (rgba &color) const { #if XFT + //TODO premultiplied alpha?? color.r = c.color.red; color.g = c.color.green; color.b = c.color.blue; @@ -859,7 +936,7 @@ } void -rxvt_color::get (XColor &color) +rxvt_color::get (XColor &color) const { rgba c; get (c); @@ -913,6 +990,7 @@ incr_buf_size = incr_buf_fill = 0; selection_wait = Sel_normal; selection_type = selnum; + cb_sv = 0; } void @@ -962,7 +1040,7 @@ void rxvt_selection::finish (char *data, unsigned int len) { - if (term) + if (!cb_sv) { if (data) term->paste (data, len);