-- Leo's gemini proxy

-- Connecting to git.thebackupbox.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

repo: rxvt-unicode-sixel
action: commit
revision:
path_from:
revision_from: 3d8e6f2f43a3c229c168fed50cba08f2afc9fdac:
path_to:
revision_to:

git.thebackupbox.net

rxvt-unicode-sixel

git://git.thebackupbox.net/rxvt-unicode-sixel

commit 3d8e6f2f43a3c229c168fed50cba08f2afc9fdac
Author: Marc Lehmann <schmorp@schmorp.de>
Date:   Sun Jan 29 20:51:28 2006 +0000

    *** empty log message ***

diff --git a/Changes b/Changes

index f4d0ab6c1a0f53f845d971d143a12e8a30730b90..

index ..a7921a2f6038a91278e7c90abab23553f643cc01 100644

--- a/Changes
+++ b/Changes
@@ -17,6 +17,9 @@ DUMB: support tex fonts
         - changed version number report again, now to emulate xterm closer.
         - added the OSC sequence 702 to detect the urxvt version number.
         - small configure updates.
+        - overhauled color management: smaller codesize, alpha support.
+        - do not include X11/Intrinsic.h anymore, directly use
+          Xlib/Xutil/Xresource directly.

 7.4  Sat Jan 28 15:26:27 CET 2006
 	- screen background wasn't always erased properly when scrolling,
diff --git a/doc/rxvt.1.pod b/doc/rxvt.1.pod

index f6119485ac4c806abd5e9f472e0e5e9487055a23..

index ..5ed8b6508dd767ca78783df3407c09ed630f8d59 100644

--- a/doc/rxvt.1.pod
+++ b/doc/rxvt.1.pod
@@ -1312,7 +1312,7 @@ on some systems or setgid to root or to some other group on others.
 In addition to the default foreground and background colours,
 B<@@RXVT_NAME@@> can display up to 16 colours (8 ANSI colours plus
 high-intensity bold/blink versions of the same). Here is a list of the
-colours with their B<rgb.txt> names.
+colours with their names.

 =begin table

@@ -1342,6 +1342,14 @@ B<background>, B<cursorColor>, B<cursorColor2>, B<colorBD>, B<colorUL> as
 a number 0-15, as a convenient shorthand to reference the colour name of
 color0-color15.

+If Xft support has been compiled in and as long as Xft/Xrender don't get
+their act together, rxvt-unicode will support C<#ARGB>, C<#AARRGGBB>
+and C<#AAAARRRRGGGGBBBB> colour specifications, in addition to the ones
+provided by X, where the additional A component specifies alpha (opacity)
+values (0 is completely transparent and the maximum is opaque). You
+probably need to specify B<"-depth 32">, too, as X is far from just
+supporting ARGB visuals out of the box.
+
 Note that B<-rv> (B<"reverseVideo: True">) simulates reverse video by
 always swapping the foreground/background colours. This is in contrast to
 I<xterm>(1) where the colours are only swapped if they have not otherwise
diff --git a/src/command.C b/src/command.C

index 7161464482eef6d1795ae1b7691467c0527748e1..

index ..f5db1c2112a657970b755d5b0b02521f67655f91 100644

--- a/src/command.C
+++ b/src/command.C
@@ -2533,12 +2533,12 @@ rxvt_term::check_our_parents ()
 #if TINTING
           if (ISSET_PIXCOLOR (Color_tint))
             {
-              unsigned short rm, gm, bm;
+              rxvt_rgba c;
               int shade = rs[Rs_shade] ? atoi (rs[Rs_shade]) : 100;

-              pix_colors_focused[Color_tint].get (this, rm, gm, bm);
+              pix_colors_focused[Color_tint].get (this, c);

-              ShadeXImage (this, image, shade, rm, gm, bm);
+              ShadeXImage (this, image, shade, c.r, c.g, c.b);
             }
 #endif

@@ -3716,9 +3716,15 @@ rxvt_term::process_color_seq (int report, int color, const char *str, char resp)
 {
   if (str[0] == '?' && !str[1])
     {
-      unsigned short r, g, b;
-      pix_colors_focused[color].get (this, r, g, b);
-      tt_printf ("\033]%d;rgb:%04x/%04x/%04x%c", report, r, g, b, resp);
+      rxvt_rgba c;
+      pix_colors_focused[color].get (this, c);
+
+#if XFT
+      if (c.a != rxvt_rgba::MAX_CC)
+        tt_printf ("\033]%d;#%04x%04x%04x%04x%c", report, c.a, c.r, c.g, c.b, resp);
+      else
+#endif
+        tt_printf ("\033]%d;rgb:%04x/%04x/%04x%c", report, c.r, c.g, c.b, resp);
     }
   else
     set_window_color (color, str);
@@ -3803,14 +3809,7 @@ rxvt_term::process_xterm_seq (int op, const char *str, char resp)
             if ((buf = strchr (name, ';')) != NULL)
               *buf++ = '\0';

-            if (name[0] == '?' && !name[1])
-              {
-                unsigned short r, g, b;
-                pix_colors_focused[color].get (this, r, g, b);
-                tt_printf ("\033]%d;%d;rgb:%04x/%04x/%04x%c", op, color, r, g, b, resp);
-              }
-            else
-              set_window_color (color, name);
+            process_color_seq (op, color, name, resp);
           }
         break;
       case XTerm_Color00:
diff --git a/src/init.C b/src/init.C

index 9e80aed96a04370f5923ea207d861d9d56f163d1..

index ..fad6894bf8378dc819850e56084dbe218c144207 100644

--- a/src/init.C
+++ b/src/init.C
@@ -739,20 +739,23 @@ rxvt_term::Get_Colours ()
        * xcol[2] == bot shadow */

       xcol[1] = pix_colors[Color_scroll];
-      xcol[0].set (this, 65535, 65535, 65535);
+      xcol[0].set (this, rxvt_rgba (rxvt_rgba::MAX_CC, rxvt_rgba::MAX_CC, rxvt_rgba::MAX_CC));

-      unsigned short pr1, pg1, pb1, pr0, pg0, pb0;
+      rxvt_rgba c0, c1;

-      xcol[0].get (this, pr0, pg0, pb0);
-      xcol[1].get (this, pr1, pg1, pb1);
+      xcol[0].get (this, c0);
+      xcol[1].get (this, c1);

       pix_colors[Color_bottomShadow] = xcol[1].fade (this, 50);

       /* topShadowColor */
       if (!xcol[1].set (this,
-                        min (pr0, max (pr0 / 5, pr1) * 7 / 5),
-                        min (pg0, max (pg0 / 5, pg1) * 7 / 5),
-                        min (pb0, max (pb0 / 5, pb1) * 7 / 5)))
+                        rxvt_rgba (
+                          min (c0.r, max (c1.r / 5, c1.r) * 7 / 5),
+                          min (c0.g, max (c1.g / 5, c1.g) * 7 / 5),
+                          min (c0.b, max (c1.b / 5, c1.b) * 7 / 5),
+                          c1.a) // pa1 vs. pa0: arbitrary
+                        ));
         xcol[1] = pix_colors[Color_White];

       pix_colors[Color_topShadow] = xcol[1];
@@ -902,7 +905,7 @@ rxvt_term::create_windows (int argc, const char *const *argv)
       if (XInternAtom (xdisp, "_MOTIF_WM_INFO", True) == None)
         {
           /*     print_warning("Window Manager does not support MWM hints.  Bypassing window manager control for borderless window.\n");*/
-          attributes.override_redirect = TRUE;
+          attributes.override_redirect = true;
           mwmhints.flags = 0;
         }
       else
diff --git a/src/rxvtfont.C b/src/rxvtfont.C

index d2565fd5eb2ec25df55b874f03de26f17ce9766a..

index ..7fa925c2f01e3054939fac670b1a5063d2884282 100644

--- a/src/rxvtfont.C
+++ b/src/rxvtfont.C
@@ -247,7 +247,7 @@ rxvt_font::clear_rect (rxvt_drawable &d, int x, int y, int w, int h, int color)
   dTermGC;

   if (color == Color_bg)
-    XClearArea (disp, d, x, y, w, h, FALSE);
+    XClearArea (disp, d, x, y, w, h, false);
   else if (color >= 0)
     {
 #if XFT
diff --git a/src/rxvtlib.h.in b/src/rxvtlib.h.in

index 15cc845516a4fe344ec5d6ddc44af92d23b36daf..

index ..0bd83c28b7624ca40cbf2e6f65dc96c801ad2f86 100644

--- a/src/rxvtlib.h.in
+++ b/src/rxvtlib.h.in
@@ -31,7 +31,9 @@
 #endif

 extern "C" {
-#include <X11/Intrinsic.h>      /* Xlib, Xutil, Xresource, Xfuncproto */
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xresource.h>
 }

 /*
diff --git a/src/rxvtperl.xs b/src/rxvtperl.xs

index d128705363349a6dfe2fc392d70e5f1a0a4c78e6..

index ..f9b1e558624add84d02060cf71481eac34249807 100644

--- a/src/rxvtperl.xs
+++ b/src/rxvtperl.xs
@@ -115,8 +115,8 @@ SvPTR (SV *sv, const char *klass)
   return (long)mg->mg_ptr;
 }

-#define newSVterm(term) SvREFCNT_inc ((SV *)term->perl.self)
-#define SvTERM(sv) (rxvt_term *)SvPTR (sv, "urxvt::term")
+#define newSVterm(term) SvREFCNT_inc ((SV *)(term)->perl.self)
+#define SvTERM(sv) (rxvt_term *)SvPTR ((sv), "urxvt::term")

 /////////////////////////////////////////////////////////////////////////////

@@ -173,8 +173,8 @@ perl_watcher::invoke (const char *type, SV *self, int arg)
     rxvt_warn ("%s callback evaluation error: %s", type, SvPV_nolen (ERRSV));
 }

-#define newSVtimer(timer) new_ref (timer->self, "urxvt::timer")
-#define SvTIMER(sv) (timer *)(perl_watcher *)SvPTR (sv, "urxvt::timer")
+#define newSVtimer(timer) new_ref ((timer)->self, "urxvt::timer")
+#define SvTIMER(sv) (timer *)(perl_watcher *)SvPTR ((sv), "urxvt::timer")

 struct timer : perl_watcher, time_watcher
 {
@@ -194,8 +194,8 @@ struct timer : perl_watcher, time_watcher
   }
 };

-#define newSViow(iow) new_ref (iow->self, "urxvt::iow")
-#define SvIOW(sv) (iow *)(perl_watcher *)SvPTR (sv, "urxvt::iow")
+#define newSViow(iow) new_ref ((iow)->self, "urxvt::iow")
+#define SvIOW(sv) (iow *)(perl_watcher *)SvPTR ((sv), "urxvt::iow")

 struct iow : perl_watcher, io_watcher
 {
@@ -210,8 +210,8 @@ struct iow : perl_watcher, io_watcher
   }
 };

-#define newSViw(iw) new_ref (iw->self, "urxvt::iw")
-#define SvIW(sv) (iw *)(perl_watcher *)SvPTR (sv, "urxvt::iw")
+#define newSViw(iw) new_ref ((iw)->self, "urxvt::iw")
+#define SvIW(sv) (iw *)(perl_watcher *)SvPTR ((sv), "urxvt::iw")

 struct iw : perl_watcher, idle_watcher
 {
@@ -226,8 +226,8 @@ struct iw : perl_watcher, idle_watcher
   }
 };

-#define newSVpw(pw) new_ref (pw->self, "urxvt::pw")
-#define SvPW(sv) (pw *)(perl_watcher *)SvPTR (sv, "urxvt::pw")
+#define newSVpw(pw) new_ref ((pw)->self, "urxvt::pw")
+#define SvPW(sv) (pw *)(perl_watcher *)SvPTR ((sv), "urxvt::pw")

 struct pw : perl_watcher, child_watcher
 {
@@ -496,8 +496,8 @@ ungrab (rxvt_term *THIS)
 {
   if (THIS->perl.grabtime)
     {
-      XUngrabKeyboard (THIS->display->display, THIS->perl.grabtime);
-      XUngrabPointer  (THIS->display->display, THIS->perl.grabtime);
+      XUngrabKeyboard (THIS->xdisp, THIS->perl.grabtime);
+      XUngrabPointer  (THIS->xdisp, THIS->perl.grabtime);
       THIS->perl.grabtime = 0;
     }
 }
@@ -958,24 +958,31 @@ SET_CUSTOM (int rend, int new_value)
 	OUTPUT:
         RETVAL

+void
+termlist ()
+	PPCODE:
+{
+        EXTEND (SP, rxvt_term::termlist.size ());
+
+        for (rxvt_term **t = rxvt_term::termlist.begin (); t < rxvt_term::termlist.end (); t++)
+          if ((*t)->perl.self)
+            PUSHs (sv_2mortal (newSVterm (*t)));
+}
+
 MODULE = urxvt             PACKAGE = urxvt::term

 SV *
-_new (...)
+_new (AV *env, AV *arg)
 	CODE:
 {
-	if (items < 1 || !SvROK (ST (0)) || SvTYPE (SvRV (ST (0))) != SVt_PVAV)
-          croak ("first argument to urxvt::term->_new must be arrayref");
-
         rxvt_term *term = new rxvt_term;

 	stringvec *argv = new stringvec;
 	stringvec *envv = new stringvec;

-        for (int i = 1; i < items; i++)
-          argv->push_back (strdup (SvPVbyte_nolen (ST (i))));
+        for (int i = 0; i <= AvFILL (arg); i++)
+          argv->push_back (strdup (SvPVbyte_nolen (*av_fetch (arg, i, 1))));

-        AV *env = (AV *)SvRV (ST (0));
         for (int i = AvFILL (env) + 1; i--; )
           envv->push_back (strdup (SvPVbyte_nolen (*av_fetch (env, i, 1))));

@@ -1013,12 +1020,31 @@ rxvt_term::set_should_invoke (int htype, int inc)
         THIS->perl.should_invoke [htype] += inc;

 void
-rxvt_term::grab_button (int button, U32 modifiers)
+rxvt_term::grab_button (int button, U32 modifiers, Window window = THIS->vt)
 	CODE:
-	XGrabButton (THIS->display->display, button, modifiers, THIS->vt, 1,
+        XGrabButton (THIS->xdisp, button, modifiers, window, 1,
                      ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
                      GrabModeSync, GrabModeSync, None, GRAB_CURSOR);

+void
+rxvt_term::ungrab_button (int button, U32 modifiers, Window window = THIS->vt)
+	CODE:
+        XUngrabButton (THIS->xdisp, button, modifiers, window);
+
+#if 0
+
+void
+XGrabKey (rxvt_term *THIS, int keycode, U32 modifiers, Window window = THIS->vt)
+	C_ARGS:
+        THIS->xdisp, keycode, modifiers, window, 1,
+        GrabModeSync, GrabModeSync
+
+void
+XUngrabKey (rxvt_term *THIS, int keycode, U32 modifiers, Window window = THIS->vt)
+	C_ARGS: THIS->xdisp, keycode, modifiers, window
+
+#endif
+
 bool
 rxvt_term::grab (Time eventtime, int sync = 0)
 	CODE:
@@ -1027,13 +1053,13 @@ rxvt_term::grab (Time eventtime, int sync = 0)

         THIS->perl.grabtime = 0;

-        if (!XGrabPointer (THIS->display->display, THIS->vt, 0,
+        if (!XGrabPointer (THIS->xdisp, THIS->vt, 0,
                            ButtonPressMask | ButtonReleaseMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
                            mode, mode, None, GRAB_CURSOR, eventtime))
-          if (!XGrabKeyboard (THIS->display->display, THIS->vt, 0, mode, mode, eventtime))
+          if (!XGrabKeyboard (THIS->xdisp, THIS->vt, 0, mode, mode, eventtime))
             THIS->perl.grabtime = eventtime;
           else
-            XUngrabPointer (THIS->display->display, eventtime);
+            XUngrabPointer (THIS->xdisp, eventtime);

         RETVAL = !!THIS->perl.grabtime;
 }
@@ -1043,18 +1069,18 @@ rxvt_term::grab (Time eventtime, int sync = 0)
 void
 rxvt_term::allow_events_async ()
 	CODE:
-        XAllowEvents (THIS->display->display, AsyncBoth,      THIS->perl.grabtime);
+        XAllowEvents (THIS->xdisp, AsyncBoth,      THIS->perl.grabtime);

 void
 rxvt_term::allow_events_sync ()
 	CODE:
-        XAllowEvents (THIS->display->display, SyncBoth,       THIS->perl.grabtime);
+        XAllowEvents (THIS->xdisp, SyncBoth,       THIS->perl.grabtime);

 void
 rxvt_term::allow_events_replay ()
 	CODE:
-        XAllowEvents (THIS->display->display, ReplayPointer,  THIS->perl.grabtime);
-        XAllowEvents (THIS->display->display, ReplayKeyboard, THIS->perl.grabtime);
+        XAllowEvents (THIS->xdisp, ReplayPointer,  THIS->perl.grabtime);
+        XAllowEvents (THIS->xdisp, ReplayKeyboard, THIS->perl.grabtime);

 void
 rxvt_term::ungrab ()
@@ -1713,7 +1739,7 @@ rxvt_term::XListProperties (Window window)
 	PPCODE:
 {
 	int count;
-	Atom *props = XListProperties (THIS->display->display, window, &count);
+	Atom *props = XListProperties (THIS->xdisp, window, &count);

         EXTEND (SP, count);
         while (count--)
@@ -1732,7 +1758,7 @@ rxvt_term::XGetWindowProperty (Window window, Atom property)
         unsigned long bytes_after;
         unsigned char *prop;

-	XGetWindowProperty (THIS->display->display, window, property,
+	XGetWindowProperty (THIS->xdisp, window, property,
                             0, 1<<24, 0, AnyPropertyType,
                             &type, &format, &nitems, &bytes_after, &prop);

@@ -1761,25 +1787,25 @@ rxvt_term::XChangeWindowProperty (Window window, Atom property, Atom type, int f
                      : format == 32 ? sizeof (long)
                      :                1;

-	XChangeProperty (THIS->display->display, window, property,
+	XChangeProperty (THIS->xdisp, window, property,
                          type, format, PropModeReplace,
                          (unsigned char *)data_, len / elemsize);
-        XSync (THIS->display->display, 0);
+        XSync (THIS->xdisp, 0);
 }

 Atom
 XInternAtom (rxvt_term *term, char *atom_name, int only_if_exists = FALSE)
-	C_ARGS: term->display->display, atom_name, only_if_exists
+	C_ARGS: term->xdisp, atom_name, only_if_exists

 char *
 XGetAtomName (rxvt_term *term, Atom atom)
-	C_ARGS: term->display->display, atom
+	C_ARGS: term->xdisp, atom
         CLEANUP:
         XFree (RETVAL);

 void
 XDeleteProperty (rxvt_term *term, Window window, Atom property)
-  	C_ARGS: term->display->display, window, property
+  	C_ARGS: term->xdisp, window, property

 Window
 rxvt_term::DefaultRootWindow ()
@@ -1792,7 +1818,7 @@ rxvt_term::DefaultRootWindow ()

 Window
 XCreateSimpleWindow (rxvt_term *term, Window parent, int x, int y, unsigned int width, unsigned int height)
-	C_ARGS: term->display->display, (Window)parent,
+	C_ARGS: term->xdisp, (Window)parent,
                 x, y, width, height, 0,
                 term->pix_colors_focused[Color_border],
                 term->pix_colors_focused[Color_border]
@@ -1801,27 +1827,27 @@ XCreateSimpleWindow (rxvt_term *term, Window parent, int x, int y, unsigned int

 void
 XReparentWindow (rxvt_term *term, Window window, Window parent, int x = 0, int y = 0)
-	C_ARGS: term->display->display, window, parent, x, y
+	C_ARGS: term->xdisp, window, parent, x, y

 void
 XMapWindow (rxvt_term *term, Window window)
-	C_ARGS: term->display->display, window
+	C_ARGS: term->xdisp, window

 void
 XUnmapWindow (rxvt_term *term, Window window)
-	C_ARGS: term->display->display, window
+	C_ARGS: term->xdisp, window

 void
 XMoveResizeWindow (rxvt_term *term, Window window, int x, int y, unsigned int width, unsigned int height)
-	C_ARGS: term->display->display, window, x, y, width, height
+	C_ARGS: term->xdisp, window, x, y, width, height

 void
 rxvt_term::XChangeInput (Window window, U32 add_events, U32 del_events = 0)
 	CODE:
 {
 	XWindowAttributes attr;
-        XGetWindowAttributes (THIS->display->display, window, &attr);
-        XSelectInput (THIS->display->display, window, attr.your_event_mask | add_events & ~del_events);
+        XGetWindowAttributes (THIS->xdisp, window, &attr);
+        XSelectInput (THIS->xdisp, window, attr.your_event_mask | add_events & ~del_events);
 }

 void
@@ -1831,7 +1857,7 @@ rxvt_term::XTranslateCoordinates (Window src, Window dst, int x, int y)
         int dx, dy;
         Window child;

-        if (XTranslateCoordinates (THIS->display->display, src, dst, x, y, &dx, &dy, &child))
+        if (XTranslateCoordinates (THIS->xdisp, src, dst, x, y, &dx, &dy, &child))
           {
             EXTEND (SP, 3);
             PUSHs (newSViv (dx));
diff --git a/src/rxvttoolkit.C b/src/rxvttoolkit.C

index d59eefd8c6e6fbbe9650e8584dd4b40c4ab02640..

index ..972f6fa871150a214fb380d9ce8e6c8369056829 100644

--- a/src/rxvttoolkit.C
+++ b/src/rxvttoolkit.C
@@ -193,17 +193,17 @@ rxvt_screen::set (rxvt_display *disp)
 }

 void
-rxvt_screen::set (rxvt_display *disp, int depth)
+rxvt_screen::set (rxvt_display *disp, int bitdepth)
 {
   set (disp);

   XVisualInfo vinfo;

-  if (XMatchVisualInfo (xdisp, display->screen, depth, TrueColor, &vinfo))
+  if (XMatchVisualInfo (xdisp, display->screen, bitdepth, TrueColor, &vinfo))
     {
-      this->depth  = depth;
-      this->visual = vinfo.visual;
-      this->cmap   = XCreateColormap (xdisp, disp->root, visual, AllocNone);
+      depth  = bitdepth;
+      visual = vinfo.visual;
+      cmap   = XCreateColormap (xdisp, disp->root, visual, AllocNone);
     }
 }

@@ -535,82 +535,84 @@ refcache<rxvt_display> displays;

 /////////////////////////////////////////////////////////////////////////////

-bool
-rxvt_color::set (rxvt_screen *screen, Pixel p)
-{
-#if XFT
-  XColor xc;
-
-  xc.pixel = p;
-  if (!XQueryColor (screen->xdisp, screen->cmap, &xc))
-    return false;
-
-  XRenderColor d;
-
-  d.red   = xc.red;
-  d.green = xc.green;
-  d.blue  = xc.blue;
-  d.alpha = 0xffff;
-
-  return
-    XftColorAllocValue (screen->xdisp,
-                        screen->visual,
-                        screen->cmap,
-                        &d, &c);
-#else
-  this->p = p;
-#endif
-
-  return true;
-}
-
 bool
 rxvt_color::set (rxvt_screen *screen, const char *name)
 {
 #if XFT
-  return XftColorAllocName (screen->xdisp, screen->visual, screen->cmap, name, &c);
+  int l = strlen (name);
+  rxvt_rgba r;
+  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))
+    mult = 0x1111;
+  else if (l == 1+4*2 && 4 == sscanf (name, "#%2hx%2hx%2hx%2hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
+    mult = 0x0101;
+  else if (l == 1+4*4 && 4 == sscanf (name, "#%4hx%4hx%4hx%4hx%c", &r.a, &r.r, &r.g, &r.b, &eos))
+    mult = 0x0001;
+  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, xc.red, xc.green, xc.blue);
+    return set (screen, rxvt_rgba (xc.red, xc.green, xc.blue));

   return false;
 #endif
 }

 bool
-rxvt_color::set (rxvt_screen *screen, unsigned short cr, unsigned short cg, unsigned short cb)
+rxvt_color::set (rxvt_screen *screen, rxvt_rgba rgba)
 {
+#if XFT
+  XRenderColor d;
+
+  d.red   = rgba.r;
+  d.green = rgba.g;
+  d.blue  = rgba.b;
+  d.alpha = rgba.a;
+
+  return XftColorAllocValue (screen->xdisp, screen->visual, screen->cmap, &d, &c);
+#else
   XColor xc;

-  xc.red   = cr;
-  xc.green = cg;
-  xc.blue  = cb;
+  xc.red   = rgba.r;
+  xc.green = rgba.g;
+  xc.blue  = rgba.b;
   xc.flags = DoRed | DoGreen | DoBlue;

   if (XAllocColor (screen->xdisp, screen->cmap, &xc))
-    return set (screen, xc.pixel);
+    {
+      p = xc.pixel;
+      return true;
+    }

   return false;
+#endif
 }

 void
-rxvt_color::get (rxvt_screen *screen, unsigned short &cr, unsigned short &cg, unsigned short &cb)
+rxvt_color::get (rxvt_screen *screen, rxvt_rgba &rgba)
 {
 #if XFT
-  cr = c.color.red;
-  cg = c.color.green;
-  cb = c.color.blue;
+  rgba.r = c.color.red;
+  rgba.g = c.color.green;
+  rgba.b = c.color.blue;
+  rgba.a = c.color.alpha;
 #else
   XColor c;

   c.pixel = p;
   XQueryColor (screen->xdisp, screen->cmap, &c);

-  cr = c.red;
-  cg = c.green;
-  cb = c.blue;
+  rgba.r = c.red;
+  rgba.g = c.green;
+  rgba.b = c.blue;
+  rgba.a = rxvt_rgba::MAX_CC;
 #endif
 }

@@ -627,42 +629,37 @@ rxvt_color::free (rxvt_screen *screen)
 rxvt_color
 rxvt_color::fade (rxvt_screen *screen, int percent)
 {
-  percent = 100 - percent;
-
-  unsigned short cr, cg, cb;
   rxvt_color faded;

-  get (screen, cr, cg, cb);
+  rxvt_rgba c;
+  get (screen, c);

-  faded.set (
-    screen,
-    cr * percent / 100,
-    cg * percent / 100,
-    cb * percent / 100
-  );
+  c.r = lerp (0, c.r, percent);
+  c.g = lerp (0, c.g, percent);
+  c.b = lerp (0, c.b, percent);
+
+  faded.set (screen, c);

   return faded;
 }

-#define LERP(a,b,p) (a * p + b * (100 - p)) / 100
-
 rxvt_color
 rxvt_color::fade (rxvt_screen *screen, int percent, rxvt_color &fadeto)
 {
-  percent = 100 - percent;
-
-  unsigned short cr, cg, cb;
-  unsigned short fcr, fcg, fcb;
+  rxvt_rgba c, fc;
   rxvt_color faded;

-  get (screen, cr, cg, cb);
-  fadeto.get (screen, fcr, fcg, fcb);
+  get (screen, c);
+  fadeto.get (screen, fc);

   faded.set (
     screen,
-    LERP (cr, fcr, percent),
-    LERP (cg, fcg, percent),
-    LERP (cb, fcb, percent)
+    rxvt_rgba (
+      lerp (fc.r, c.r, percent),
+      lerp (fc.g, c.g, percent),
+      lerp (fc.b, c.b, percent),
+      lerp (fc.a, c.a, percent)
+    )
   );

   return faded;
diff --git a/src/rxvttoolkit.h b/src/rxvttoolkit.h

index a4d2cf52450f595c4e0be3a998555c8484c6052d..

index ..1a78b3adb1cb49dbd15420d9672217579ed97b06 100644

--- a/src/rxvttoolkit.h
+++ b/src/rxvttoolkit.h
@@ -106,7 +106,7 @@ struct rxvt_screen {
   Colormap cmap;

   void set (rxvt_display *disp);
-  void set (rxvt_display *disp, int depth);
+  void set (rxvt_display *disp, int bitdepth);
   void clear ();
 };

@@ -201,6 +201,19 @@ extern refcache<rxvt_display> displays;

 typedef unsigned long Pixel;

+struct rxvt_rgba {
+  unsigned short r, g, b, a;
+
+  enum { MIN_CC = 0x0000, MAX_CC  = 0xffff };
+
+  rxvt_rgba ()
+  { }
+
+  rxvt_rgba (unsigned short r, unsigned short g, unsigned short b, unsigned short a = MAX_CC)
+  : r(r), g(g), b(b), a(a)
+  { }
+};
+
 struct rxvt_color {
 #if XFT
   XftColor c;
@@ -213,11 +226,10 @@ struct rxvt_color {
   bool operator == (const rxvt_color &b) const { return Pixel (*this) == Pixel (b); }
   bool operator != (const rxvt_color &b) const { return Pixel (*this) != Pixel (b); }

-  void get (rxvt_screen *screen, unsigned short &cr, unsigned short &cg, unsigned short &cb);
+  void get (rxvt_screen *screen, rxvt_rgba &rgba);

-  bool set (rxvt_screen *screen, Pixel p);
   bool set (rxvt_screen *screen, const char *name);
-  bool set (rxvt_screen *screen, unsigned short cr, unsigned short cg, unsigned short cb);
+  bool set (rxvt_screen *screen, rxvt_rgba rgba);

   rxvt_color fade (rxvt_screen *screen, int percent); // fades to black
   rxvt_color fade (rxvt_screen *screen, int percent, rxvt_color &fadeto);
diff --git a/src/rxvtutil.h b/src/rxvtutil.h

index 2a3ef5bc37bff53b65f6ad6b616d8fb7acc8d163..

index ..644a2979cc707ad32d5e673b08edd43a16b06913 100644

--- a/src/rxvtutil.h
+++ b/src/rxvtutil.h
@@ -31,6 +31,14 @@ 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; }

+// linear interpolation
+template<typename T, typename U, typename P>
+static inline
+T lerp (T a, U b, P p)
+{
+  return (int(a) * int(p) + int(b) * int(100 - p)) / 100;
+}
+
 // in range including end
 #define IN_RANGE_INC(val,beg,end) \
   ((unsigned int)(val) - (unsigned int)(beg) <= (unsigned int)(end) - (unsigned int)(beg))
diff --git a/src/urxvt.pm b/src/urxvt.pm

index 82bba672941598939d6525b904535c69eb8d593d..

index ..6ef1d5fdb0ddf4846d10c4be70debe4eb7cd68ea 100644

--- a/src/urxvt.pm
+++ b/src/urxvt.pm
@@ -669,6 +669,13 @@ correct place, e.g. on stderr of the connecting urxvtc client.

 Messages have a size limit of 1023 bytes currently.

+=item @terms = urxvt::termlist
+
+Returns all urxvt::term objects that exist in this process, regardless of
+wether they are started, being destroyed etc., so be careful. Only term
+objects that have perl extensions attached will be returned (because there
+is no urxvt::term objet associated with others).
+
 =item $time = urxvt::NOW

 Returns the "current time" (as per the event loop).
@@ -1058,14 +1065,18 @@ hash which defines the environment of the new terminal.
 Croaks (and probably outputs an error message) if the new instance
 couldn't be created.  Returns C<undef> if the new instance didn't
 initialise perl, and the terminal object otherwise. The C<init> and
-C<start> hooks will be called during this call.
+C<start> hooks will be called before this call returns, and are free to
+refer to global data (which is race free).

 =cut

 sub new {
    my ($class, $env, @args) = @_;

-   _new ([ map "$_=$env->{$_}", keys %$env ], @args);
+   $env  or Carp::croak "environment hash missing in call to urxvt::term->new";
+   @args or Carp::croak "name argument missing in call to urxvt::term->new";
+
+   _new ([ map "$_=$env->{$_}", keys %$env ], \@args);
 }

 =item $term->destroy
@@ -1629,9 +1640,12 @@ C<< $term->ROW_t >> for details.
 Converts rxvt-unicodes text reprsentation into a perl string. See
 C<< $term->ROW_t >> for details.

-=item $success = $term->grab_button ($button, $modifiermask)
+=item $success = $term->grab_button ($button, $modifiermask[, $window = $term->vt])
+
+=item $term->ungrab_button ($button, $modifiermask[, $window = $term->vt])

-Registers a synchronous button grab. See the XGrabButton manpage.
+Register/unregister a synchronous button grab. See the XGrabButton
+manpage.

 =item $success = $term->grab ($eventtime[, $sync])

-----END OF PAGE-----

-- Response ended

-- Page fetched on Sun Jun 2 09:35:27 2024