*** empty log message ***
authorroot <root>
Mon, 30 Jan 2006 19:46:13 +0000 (19:46 +0000)
committerroot <root>
Mon, 30 Jan 2006 19:46:13 +0000 (19:46 +0000)
Changes
doc/rxvt.7.pod
src/init.C
src/main.C
src/rxvt.h
src/rxvttoolkit.C
src/rxvttoolkit.h
src/rxvtutil.h

diff --git a/Changes b/Changes
index 5812239..b0cc13a 100644 (file)
--- 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.
index 8735081..c7f40f2 100644 (file)
@@ -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
index a46f866..e034d81 100644 (file)
@@ -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:
index 4394189..7ac0e41 100644 (file)
@@ -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;
 }
 
 /* -------------------------------------------------------------------- *
index b127091..42a88c3 100644 (file)
@@ -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
index 19aa2b5..ffd0109 100644 (file)
@@ -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<rxvt_display>;
 refcache<rxvt_display> 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<int> (rgba.r >> 2, colors [i].red   >> 2))
+                + (squared_diff<int> (rgba.g >> 2, colors [i].green >> 2))
+                + (squared_diff<int> (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 
index d3b8b64..da2b9dc 100644 (file)
@@ -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);
 
index 4b978a3..618b863 100644 (file)
@@ -56,6 +56,8 @@ template<typename T, typename U, typename V> static inline void clamp_it (T &v,
 
 template<typename T, typename U> static inline void swap (T& a, U& b) { T t=a; a=(T)b; b=(U)t; }
 
+template<typename T> static inline T squared_diff (T a, T b) { return (a-b)*(a-b); }
+
 // linear interpolation
 template<typename T, typename U, typename P>
 static inline