From df9d7cfa0d8f8adcd73dfa895e657a5bf9f0f8bc Mon Sep 17 00:00:00 2001 From: root Date: Mon, 30 Jan 2006 19:46:13 +0000 Subject: [PATCH] *** empty log message *** --- Changes | 2 + doc/rxvt.7.pod | 5 ++ src/init.C | 7 +-- src/main.C | 16 +++-- src/rxvt.h | 2 +- src/rxvttoolkit.C | 148 +++++++++++++++++++++++++++++++--------------- src/rxvttoolkit.h | 11 ++++ src/rxvtutil.h | 2 + 8 files changed, 131 insertions(+), 62 deletions(-) diff --git a/Changes b/Changes index 58122399..b0cc13ab 100644 --- a/Changes +++ b/Changes @@ -39,6 +39,8 @@ DUMB: support tex fonts transparent. Long Live Xft! - do not include X11/Intrinsic.h anymore, directly use Xlib/Xutil/Xresource directly. + - try to find a nearest matching color when color allocation fails + on a pseudocolor screen. - SYNCCVS: compared to rxvt-cvs 2006-01-28, no relevant changes. - fix version report (DA) (which was unfortunately broken). - changed version number report again, now to emulate xterm closer. diff --git a/doc/rxvt.7.pod b/doc/rxvt.7.pod index 87350814..c7f40f2b 100644 --- a/doc/rxvt.7.pod +++ b/doc/rxvt.7.pod @@ -2107,6 +2107,11 @@ in combination with other switches) is: skip builtin block graphics (-sbg) sgr modes 90..97 and 100..107 +It also enabled some non-essential features otherwise disabled, such as: + + some round-trip time optimisations + nearest color allocation on pseudocolor screens + =item --enable-iso14755 (default: on) Enable extended ISO 14755 support (see @@RXVT_NAME@@(1), or diff --git a/src/init.C b/src/init.C index a46f8662..e034d812 100644 --- a/src/init.C +++ b/src/init.C @@ -662,7 +662,7 @@ rxvt_term::Get_Colours () if (!rs[Rs_color + i]) continue; - if (!rXParseAllocColor (&xcol, rs[Rs_color + i])) + if (!set_color (xcol, rs[Rs_color + i])) { #ifndef XTERM_REVERSE_VIDEO if (i < 2 && OPTION (Opt_reverseVideo)) @@ -674,15 +674,14 @@ rxvt_term::Get_Colours () if (!rs[Rs_color + i]) continue; - if (!rXParseAllocColor (&xcol, rs[Rs_color + i])) + if (!set_color (xcol, rs[Rs_color + i])) { switch (i) { case Color_fg: case Color_bg: /* fatal: need bg/fg color */ - rxvt_fatal ("unable to get foreground/background colour, aborting.\n"); - /* NOTREACHED */ + rxvt_warn ("unable to get foreground/background colour, continuing.\n"); break; #ifndef NO_CURSORCOLOR case Color_cursor2: diff --git a/src/main.C b/src/main.C index 4394189f..7ac0e415 100644 --- a/src/main.C +++ b/src/main.C @@ -914,7 +914,7 @@ rxvt_term::set_window_color (int idx, const char *color) } } - if (!rXParseAllocColor (&xcol, color)) + if (!set_color (xcol, color)) return; /* XStoreColor (xdisp, display->cmap, XColor*); */ @@ -1008,16 +1008,14 @@ rxvt_term::set_colorfgbg () /*----------------------------------------------------------------------*/ -int -rxvt_term::rXParseAllocColor (rxvt_color *screen_in_out, const char *colour) +bool +rxvt_term::set_color (rxvt_color &color, const char *name) { - if (!screen_in_out->set (this, colour)) - { - rxvt_warn ("can't get colour '%s', continuing without.\n", colour); - return false; - } + if (color.set (this, name)) + return true; - return true; + rxvt_warn ("can't get colour '%s', continuing without.\n", name); + return false; } /* -------------------------------------------------------------------- * diff --git a/src/rxvt.h b/src/rxvt.h index b1270912..42a88c38 100644 --- a/src/rxvt.h +++ b/src/rxvt.h @@ -1258,7 +1258,7 @@ struct rxvt_term : zero_initialized, rxvt_vars, rxvt_screen { void set_icon_name (const char *str); void set_window_color (int idx, const char *color); void set_colorfgbg (); - int rXParseAllocColor (rxvt_color * screen_in_out, const char *colour); + bool set_color (rxvt_color &color, const char *name); void set_widthheight (unsigned int newwidth, unsigned int newheight); // screen.C diff --git a/src/rxvttoolkit.C b/src/rxvttoolkit.C index 19aa2b5a..ffd0109c 100644 --- a/src/rxvttoolkit.C +++ b/src/rxvttoolkit.C @@ -83,6 +83,14 @@ const char *const xa_names[] = "XDCCC_LINEAR_RGB_MATRICES", "WM_COLORMAP_WINDOWS", "WM_STATE", + "cursor", +# if USE_XIM + "TRANSPORT", + "LOCALES", + "_XIM_PROTOCOL", + "_XIM_XCONNECT", + "_XIM_MOREDATA", +# endif #endif }; @@ -552,52 +560,9 @@ template class refcache; refcache displays; ///////////////////////////////////////////////////////////////////////////// - -bool -rxvt_color::set (rxvt_screen *screen, const char *name) -{ -#if XFT - int l = strlen (name); - rxvt_rgba r; - char eos; - int mult; - - // 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; - else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos)) - 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; - - if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) - return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue)); - - return false; -#endif -} - + bool -rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba) +rxvt_color::alloc (rxvt_screen *screen, rxvt_rgba rgba) { #if XFT XRenderPictFormat *format; @@ -632,8 +597,6 @@ rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba) return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c); } - - return false; #else if (screen->visual->c_class == TrueColor || screen->visual->c_class == DirectColor) { @@ -653,17 +616,106 @@ rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba) 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; } + else + p = (rgba.r + rgba.g + rgba.b) > 128*3 + ? WhitePixelOfScreen (DefaultScreenOfDisplay (screen->xdisp)) + : BlackPixelOfScreen (DefaultScreenOfDisplay (screen->xdisp)); } +#endif return false; +} + +bool +rxvt_color::set (rxvt_screen *screen, const char *name) +{ + int l = strlen (name); + rxvt_rgba r; + char eos; + int mult; + XColor xc, xc_exact; + + // parse a number of non-standard ARGB colour specifications + 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 / 0x0010; + 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 / 0x0100; + else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos)) + mult = rxvt_rgba::MAX_CC / 0x0100; + 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; + else if (XParseColor (screen->xdisp, screen->cmap, name, &xc)) + { + r.r = xc.red; + r.g = xc.green; + r.b = xc.blue; + mult = rxvt_rgba::MAX_CC / 0xffff; + } + else + { + rxvt_warn ("failed to allocate color '%s', using pink instead.\n", name); + r.r = 255; + r.g = 105; + r.b = 180; + mult = rxvt_rgba::MAX_CC / 0x00ff; + } + + r.r *= mult; r.g *= mult; r.b *= mult; r.a *= mult; + + return set (screen, r); +} + +bool +rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba) +{ + bool got = alloc (screen, rgba); + +#if !ENABLE_MINIMAL + int cmap_size = screen->visual->map_entries; + + if (!got + && screen->visual->c_class == PseudoColor + && cmap_size < 4096) + { + XColor *colors = new XColor [screen->visual->map_entries]; + + for (int i = 0; i < cmap_size; i++) + colors [i].pixel = i; + + XQueryColors (screen->xdisp, screen->cmap, colors, cmap_size); + + int diff = 0x7fffffffUL; + XColor *best = colors; + + for (int i = 0; i < cmap_size; i++) + { + int d = (squared_diff (rgba.r >> 2, colors [i].red >> 2)) + + (squared_diff (rgba.g >> 2, colors [i].green >> 2)) + + (squared_diff (rgba.b >> 2, colors [i].blue >> 2)); + + if (d < diff) + { + diff = d; + best = colors + i; + } + } + + //rxvt_warn ("could not allocate %04x %04x %04x, getting %04x %04x %04x instead (%d)\n", + // rgba.r, rgba.g, rgba.b, best->red, best->green, best->blue, diff); + + got = alloc (screen, rxvt_rgba (best->red, best->green, best->blue)); + + delete colors; + } #endif + + return got; } void diff --git a/src/rxvttoolkit.h b/src/rxvttoolkit.h index d3b8b641..da2b9dca 100644 --- a/src/rxvttoolkit.h +++ b/src/rxvttoolkit.h @@ -64,6 +64,15 @@ enum { XA_XDCCC_LINEAR_RGB_MATRICES, XA_WM_COLORMAP_WINDOWS, XA_WM_STATE, + XA_cursor, +# if USE_XIM + // various selection targets used by XIM + XA_TRANSPORT, + XA_LOCALES, + XA__XIM_PROTOCOL, + XA__XIM_XCONNECT, + XA__XIM_MOREDATA, +# endif #endif NUM_XA }; @@ -242,6 +251,8 @@ struct rxvt_color { void get (rxvt_screen *screen, rxvt_rgba &rgba); + bool alloc (rxvt_screen *screen, rxvt_rgba rgba); + bool set (rxvt_screen *screen, const char *name); bool set (rxvt_screen *screen, rxvt_rgba rgba); diff --git a/src/rxvtutil.h b/src/rxvtutil.h index 4b978a3a..618b8636 100644 --- a/src/rxvtutil.h +++ b/src/rxvtutil.h @@ -56,6 +56,8 @@ template static inline void clamp_it (T &v, template static inline void swap (T& a, U& b) { T t=a; a=(T)b; b=(U)t; } +template static inline T squared_diff (T a, T b) { return (a-b)*(a-b); } + // linear interpolation template static inline -- 2.34.1