This change add support for resetting the terminal bg/fg/cursor
colors via OSC 110/111/112. These OSC command are widely used
among other terminals and are part of the XTerm control
sequences. Some terminals that implement this include but
not limited to: xterm, vte, konsole, foot, ghostty, alacritty,
iterm2, apple terminal, st, and many other.

Signed-off-by: Ayman Bagabas <[email protected]>
---
 src/command.C | 36 ++++++++++++++---------
 src/init.C    |  5 +++-
 src/main.C    | 23 +++++++++++++++
 src/rxvt.h    | 79 ++++++++++++++++++++++++++++-----------------------
 4 files changed, 93 insertions(+), 50 deletions(-)

diff --git a/src/command.C b/src/command.C
index 891ffab4ad0a..42cf7cbcd02d 100644
--- a/src/command.C
+++ b/src/command.C
@@ -3315,22 +3315,22 @@ void
 rxvt_term::process_osc_seq ()
 {
   int arg;
+  string_term st;
+  char *s;
 
-  unicode_t ch = cmd_getc ();
-  for (arg = 0; isdigit (ch); ch = cmd_getc ())
-    arg = arg * 10 + (ch - '0');
+  s = get_to_st (st);
+  if (!s)
+    return;
 
-  if (ch == ';')
-    {
-      string_term st;
-      char *s = get_to_st (st);
+  char *ch = s;
+  for (arg = 0; isdigit (ch[0]); ch++)
+    arg = arg * 10 + (*ch - '0');
 
-      if (s)
-        {
-          process_xterm_seq (arg, s, st);
-          free (s);
-        }
-    }
+  if (*ch == ';')
+    ch++;
+
+  process_xterm_seq (arg, ch, st);
+  free (s);
 }
 
 static unsigned int
@@ -3479,6 +3479,13 @@ rxvt_term::process_xterm_seq (int op, char *str, 
string_term &st)
   if (HOOK_INVOKE ((this, HOOK_OSC_SEQ, DT_INT, op, DT_STR, str, DT_END)))
     return;
 
+  // These operations take no parameters and expect empty string.
+  if (strlen (str) == 0 &&
+      op != XTerm_RestoreColor00 &&
+      op != XTerm_RestoreColor01 &&
+      op != XTerm_RestoreColor_cursor)
+    return;
+
   switch (op)
     {
       case XTerm_name:
@@ -3549,14 +3556,17 @@ rxvt_term::process_xterm_seq (int op, char *str, 
string_term &st)
         break;
       case Rxvt_restoreFG:
       case XTerm_Color00:
+      case XTerm_RestoreColor00:
         process_color_seq (op, Color_fg, str, st);
         break;
       case Rxvt_restoreBG:
       case XTerm_Color01:
+      case XTerm_RestoreColor01:
         process_color_seq (op, Color_bg, str, st);
         break;
 #ifndef NO_CURSORCOLOR
       case XTerm_Color_cursor:
+      case XTerm_RestoreColor_cursor:
         process_color_seq (op, Color_cursor, str, st);
         break;
 #endif
diff --git a/src/init.C b/src/init.C
index 907cdabe87c4..80d5e5065202 100644
--- a/src/init.C
+++ b/src/init.C
@@ -765,10 +765,13 @@ rxvt_term::init_resources (int argc, const char *const 
*argv)
     }
 #endif
 
-  for (i = 0; i < NRS_COLORS; i++)
+  for (i = 0; i < NRS_COLORS; i++) {
     if (!rs[Rs_color + i])
       rs[Rs_color + i] = def_colorName[i];
 
+    def_colors[i] = rs[Rs_color + i];
+  }
+
 #ifndef XTERM_REVERSE_VIDEO
   /* this is how we implement reverseVideo */
   if (option (Opt_reverseVideo))
diff --git a/src/main.C b/src/main.C
index 10e5065bbd22..6921378451ea 100644
--- a/src/main.C
+++ b/src/main.C
@@ -944,6 +944,8 @@ rxvt_term::set_window_color (int idx, const char *color)
 {
 #ifdef XTERM_COLOR_CHANGE
   if (color == NULL || *color == '\0')
+    color = get_def_color (idx);
+  if (!color)
     return;
 
   color = strdup (color);
@@ -1045,6 +1047,27 @@ rxvt_term::set_color (rxvt_color &color, const char 
*name)
   return false;
 }
 
+const char *
+rxvt_term::get_def_color(int idx)
+{
+  const char *color;
+
+  color = def_colors[idx];
+  if (!color) {
+    // If cursor colors are not defined, use fg/bg respectively.
+    switch (idx) {
+    case Color_cursor:
+      color = def_colors[Color_fg];
+      break;
+    case Color_cursor2:
+      color = def_colors[Color_bg];
+      break;
+    }
+  }
+
+  return color;
+}
+
 void
 rxvt_term::alias_color (int dst, int src)
 {
diff --git a/src/rxvt.h b/src/rxvt.h
index 37aba23ace80..8cda9a46cef5 100644
--- a/src/rxvt.h
+++ b/src/rxvt.h
@@ -412,54 +412,58 @@ struct string_term
  * colour extensions by Christian W. Zuckschwerdt <[email protected]>
  */
 enum {
-  XTerm_name             =  0,
-  XTerm_iconName         =  1,
-  XTerm_title            =  2,
-  XTerm_property         =  3,      // change X property
-  XTerm_Color            =  4,      // change colors
-  XTerm_Color00          = 10,      // change fg color
-  XTerm_Color01          = 11,      // change bg color
-  XTerm_Color_cursor     = 12,      // change actual 'Cursor' color
-  XTerm_Color_pointer_fg = 13,      // change actual 'Pointer' fg color
-  XTerm_Color_pointer_bg = 14,      // change actual 'Pointer' bg color
-  XTerm_Color05          = 15,      // not implemented (tektronix fg)
-  XTerm_Color06          = 16,      // not implemented (tektronix bg)
-  XTerm_Color_HC         = 17,      // change actual 'Highlight' bg color
-  XTerm_Color_HTC        = 19,      // change actual 'Highlight' fg color
-  XTerm_logfile          = 46,      // not implemented
-  XTerm_font             = 50,
+  XTerm_name                =  0,
+  XTerm_iconName            =  1,
+  XTerm_title               =  2,
+  XTerm_property            =  3,      // change X property
+  XTerm_Color               =  4,      // change colors
+  XTerm_Color00             = 10,      // change fg color
+  XTerm_Color01             = 11,      // change bg color
+  XTerm_Color_cursor        = 12,      // change actual 'Cursor' color
+  XTerm_Color_pointer_fg    = 13,      // change actual 'Pointer' fg color
+  XTerm_Color_pointer_bg    = 14,      // change actual 'Pointer' bg color
+  XTerm_Color05             = 15,      // not implemented (tektronix fg)
+  XTerm_Color06             = 16,      // not implemented (tektronix bg)
+  XTerm_Color_HC            = 17,      // change actual 'Highlight' bg color
+  XTerm_Color_HTC           = 19,      // change actual 'Highlight' fg color
+  XTerm_logfile             = 46,      // not implemented
+  XTerm_font                = 50,
 
-  XTerm_konsole30        = 30,      // reserved for konsole
-  XTerm_konsole31        = 31,      // reserved for konsole
-  XTerm_emacs51          = 51,      // reserved for emacs shell
+  XTerm_konsole30           = 30,      // reserved for konsole
+  XTerm_konsole31           = 31,      // reserved for konsole
+  XTerm_emacs51             = 51,      // reserved for emacs shell
   /*
    * rxvt extensions of XTerm OSCs: ESC ] Ps;Pt (ST|BEL)
    */
 
   // deprecated
-  Rxvt_restoreFG         = 39,
-  Rxvt_restoreBG         = 49,
+  Rxvt_restoreFG            = 39,
+  Rxvt_restoreBG            = 49,
 
-  Rxvt_dumpscreen        = 55,      // dump scrollback and all of screen
+  Rxvt_dumpscreen           = 55,      // dump scrollback and all of screen
+                                       //
+  XTerm_RestoreColor00      = 110,     // restore fg color
+  XTerm_RestoreColor01      = 111,     // restore bg color
+  XTerm_RestoreColor_cursor = 112,     // restore cursor color
 
-  URxvt_locale           = 701,     // change locale
-  URxvt_version          = 702,     // request version
+  URxvt_locale              = 701,     // change locale
+  URxvt_version             = 702,     // request version
 
-  URxvt_Color_IT         = 704,     // change actual 'Italic' colour
-  URxvt_Color_BD         = 706,     // change actual 'Bold' color
-  URxvt_Color_UL         = 707,     // change actual 'Underline' color
-  URxvt_Color_border     = 708,
+  URxvt_Color_IT            = 704,     // change actual 'Italic' colour
+  URxvt_Color_BD            = 706,     // change actual 'Bold' color
+  URxvt_Color_UL            = 707,     // change actual 'Underline' color
+  URxvt_Color_border        = 708,
 
-  URxvt_font             = 710,
-  URxvt_boldFont         = 711,
-  URxvt_italicFont       = 712,
-  URxvt_boldItalicFont   = 713,
+  URxvt_font                = 710,
+  URxvt_boldFont            = 711,
+  URxvt_italicFont          = 712,
+  URxvt_boldItalicFont      = 713,
 
-  URxvt_view_up          = 720,
-  URxvt_view_down        = 721,
+  URxvt_view_up             = 720,
+  URxvt_view_down           = 721,
 
-  URxvt_cellinfo         = 776,     // returns font cell width, height etc.
-  URxvt_perl             = 777,     // for use by perl extensions, starts with 
"extension-name;"
+  URxvt_cellinfo            = 776,     // returns font cell width, height etc.
+  URxvt_perl                = 777,     // for use by perl extensions, starts 
with "extension-name;"
 };
 
 /* Words starting with `Color_' are colours.  Others are counts */
@@ -1228,6 +1232,8 @@ struct rxvt_term : zero_initialized, rxvt_vars, 
rxvt_screen
 #endif
 
   const char     *rs[NUM_RESOURCES];
+  const char     *def_colors[NRS_COLORS];
+
   /* command input buffering */
   char           *cmdbuf_ptr, *cmdbuf_endp;
   char            cmdbuf_base[CBUFSIZ];
@@ -1417,6 +1423,7 @@ struct rxvt_term : zero_initialized, rxvt_vars, 
rxvt_screen
   void set_window_color (int idx, const char *color);
   char *get_colorfgbg ();
   bool set_color (rxvt_color &color, const char *name);
+  const char *get_def_color(int idx);
   void alias_color (int dst, int src);
   void set_widthheight (unsigned int newwidth, unsigned int newheight);
   void get_window_origin (int &x, int &y);
-- 
2.51.0


_______________________________________________
rxvt-unicode mailing list
[email protected]
http://lists.schmorp.de/mailman/listinfo/rxvt-unicode

Reply via email to