--- rxvt-unicode/src/rxvttoolkit.C 2006/01/29 21:54:33 1.30 +++ rxvt-unicode/src/rxvttoolkit.C 2006/01/30 17:49:48 1.37 @@ -34,41 +34,57 @@ # include #endif +#if XFT +# include +#endif + const char *const xa_names[] = - { - "TEXT", - "COMPOUND_TEXT", - "UTF8_STRING", - "MULTIPLE", - "TARGETS", - "TIMESTAMP", - "VT_SELECTION", - "INCR", - "WM_PROTOCOLS", - "WM_DELETE_WINDOW", - "CLIPBOARD", +{ + "TEXT", + "COMPOUND_TEXT", + "UTF8_STRING", + "MULTIPLE", + "TARGETS", + "TIMESTAMP", + "VT_SELECTION", + "INCR", + "WM_PROTOCOLS", + "WM_DELETE_WINDOW", + "CLIPBOARD", + "AVERAGE_WIDTH", + "WEIGHT_NAME", + "SLANT", + "CHARSET_REGISTRY", + "CHARSET_ENCODING", #if ENABLE_FRILLS - "_MOTIF_WM_HINTS", + "_MOTIF_WM_HINTS", #endif #if ENABLE_EWMH - "_NET_WM_PID", - "_NET_WM_NAME", - "_NET_WM_ICON_NAME", - "_NET_WM_PING", + "_NET_WM_PID", + "_NET_WM_NAME", + "_NET_WM_ICON_NAME", + "_NET_WM_PING", #endif #if USE_XIM - "WM_LOCALE_NAME", - "XIM_SERVERS", + "WM_LOCALE_NAME", + "XIM_SERVERS", #endif #ifdef TRANSPARENT - "_XROOTPMAP_ID", - "ESETROOT_PMAP_ID", + "_XROOTPMAP_ID", + "ESETROOT_PMAP_ID", #endif #if ENABLE_XEMBED - "_XEMBED", - "_XEMBED_INFO", + "_XEMBED", + "_XEMBED_INFO", #endif - }; +#if !ENABLE_MINIMAL + "SCREEN_RESOURCES", + "XDCCC_LINEAR_RGB_CORRECTION", + "XDCCC_LINEAR_RGB_MATRICES", + "WM_COLORMAP_WINDOWS", + "WM_STATE", +#endif +}; ///////////////////////////////////////////////////////////////////////////// @@ -197,6 +213,7 @@ { set (disp); +#if XFT XVisualInfo vinfo; if (XMatchVisualInfo (xdisp, display->screen, bitdepth, TrueColor, &vinfo)) @@ -205,6 +222,7 @@ visual = vinfo.visual; cmap = XCreateColormap (xdisp, disp->root, visual, AllocNone); } +#endif } void @@ -544,7 +562,15 @@ char eos; int mult; - if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos)) + // shortcutting this saves countless server RTTs for the built-in colours + if (l == 3+3*3 && 3 == sscanf (name, "rgb:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos)) + { + r.a = rxvt_rgba::MAX_CC; + mult = rxvt_rgba::MAX_CC / 0x00ff; + } + + // parse a number of non-standard ARGB colour specifications + else if ( l == 1+4*1 && 4 == sscanf (name, "#%1hx%1hx%1hx%1hx%c", &r.a, &r.r, &r.g, &r.b, &eos)) mult = rxvt_rgba::MAX_CC / 0x000f; else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos)) mult = rxvt_rgba::MAX_CC / 0x00ff; @@ -552,10 +578,13 @@ mult = rxvt_rgba::MAX_CC / 0xffff; else if (l == 4+5*4 && 4 == sscanf (name, "rgba:%hx/%hx/%hx/%hx%c", &r.r, &r.g, &r.b, &r.a, &eos)) mult = rxvt_rgba::MAX_CC / 0xffff; + + // slow case: server round trip else return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c); r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult; + return set (screen, r); #else XColor xc; @@ -571,41 +600,67 @@ rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba) { #if XFT - XRenderColor d; + XRenderPictFormat *format; - d.red = rgba.r; - d.green = rgba.g; - d.blue = rgba.b; - d.alpha = rgba.a; - - if (XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c)) - { - // FUCKING Xft gets it wrong, of course, fix it for the common case - // transparency users should eat shit and die, and then - // XRenderQueryPictIndexValues themselves plenty. - if (screen->depth == 32 && screen->visual->c_class == TrueColor) - if ((screen->visual->red_mask | screen->visual->green_mask | screen->visual->blue_mask) == 0x00ffffffUL) - c.pixel = c.pixel & 0x00ffffffUL | ((rgba.a >> 8) << 24); - else if ((screen->visual->red_mask | screen->visual->green_mask | screen->visual->blue_mask) == 0xffffff00UL) - c.pixel = c.pixel & 0xffffff00UL | (rgba.a >> 8); + // FUCKING Xft gets it wrong, of course, so work around it + // transparency users should eat shit and die, and then + // XRenderQueryPictIndexValues themselves plenty. + if ((screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor) + && (format = XRenderFindVisualFormat (screen->xdisp, screen->visual))) + { + // the fun lies in doing everything manually... + c.color.red = rgba.r; + c.color.green = rgba.g; + c.color.blue = rgba.b; + c.color.alpha = rgba.a; + + c.pixel = ((rgba.r * format->direct.redMask / rxvt_rgba::MAX_CC) << format->direct.red ) + | ((rgba.g * format->direct.greenMask / rxvt_rgba::MAX_CC) << format->direct.green) + | ((rgba.b * format->direct.blueMask / rxvt_rgba::MAX_CC) << format->direct.blue ) + | ((rgba.a * format->direct.alphaMask / rxvt_rgba::MAX_CC) << format->direct.alpha); return true; } + else + { + XRenderColor d; - return false; -#else - XColor xc; + d.red = rgba.r; + d.green = rgba.g; + d.blue = rgba.b; + d.alpha = rgba.a; - xc.red = rgba.r; - xc.green = rgba.g; - xc.blue = rgba.b; - xc.flags = DoRed | DoGreen | DoBlue; + return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c); + } - if (XAllocColor (screen->xdisp, screen->cmap, &xc)) + return false; +#else + if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor) { - p = xc.pixel; + p = (rgba.r * (screen->visual->red_mask >> ctz (screen->visual->red_mask )) + / rxvt_rgba::MAX_CC) << ctz (screen->visual->red_mask ) + | (rgba.g * (screen->visual->green_mask >> ctz (screen->visual->green_mask)) + / rxvt_rgba::MAX_CC) << ctz (screen->visual->green_mask) + | (rgba.b * (screen->visual->blue_mask >> ctz (screen->visual->blue_mask )) + / rxvt_rgba::MAX_CC) << ctz (screen->visual->blue_mask ); + return true; } + else + { + XColor xc; + + xc.red = rgba.r; + xc.green = rgba.g; + xc.blue = rgba.b; + xc.flags = DoRed | DoGreen | DoBlue; + + if (XAllocColor (screen->xdisp, screen->cmap, &xc)) + { + p = xc.pixel; + return true; + } + } return false; #endif