unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#62994: Support styled underlines on TTY frames
@ 2023-04-21 14:29 Mohsin Kaleem
  2024-02-11 17:15 ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames mohkale
  0 siblings, 1 reply; 7+ messages in thread
From: Mohsin Kaleem @ 2023-04-21 14:29 UTC (permalink / raw)
  To: 62994


Hi,

Support for styled underlines double, wave, dotted and dashed is a
relatively recent inclusion for newer terminal emulators. It's exposed
through either the Smulx or Su termcap (the former being an escape
sequence and the latter just a flag). Furthermore. despite not having a
dedicated termcap, these extensions also support colored underlines
through a separate escape sequence; making it possible to have an
underline with a different color to the foreground.

I'd like to add support for these to Emacs. Looking on the mailing list
it seems there's some prior efforts for this but none seem to have had
any traction. I've been working on a patch for these and will submit it
in reply to this message chain.

For testing I've been using kitty. If building with this patch series
you can view the underlines in the scratch buffer like so:

  ./src/emacs -nw -q --eval '(set-face-attribute (quote font-lock-comment-delimiter-face) nil :underline (list :style (quote wave) :color "blue"))'

-- 
Mohsin Kaleem





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames
  2023-04-21 14:29 bug#62994: Support styled underlines on TTY frames Mohsin Kaleem
@ 2024-02-11 17:15 ` mohkale
  2024-02-11 17:15   ` bug#62994: [PATCH v4 1/3] Add face definitions for more underline styles mohkale
                     ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: mohkale @ 2024-02-11 17:15 UTC (permalink / raw)
  To: 62994, Eli Zaretskii; +Cc: Mohsin Kaleem

From: Mohsin Kaleem <mohkale@kisara.moe>

Modern terminals (such as kitty) support setting the style of an
underline with the escape sequence exposed in the Smulx termcap.
This allows for (among others) wavy underlines on terminals.
These terminals also support setting the color of these underlines
using a separate escape sequence that to the best of my knowledge
is not exposed as a termcap but has been adopted by other terminal
supporting editors like neovim.

Mohsin Kaleem (3):
  Add face definitions for more underline styles
  Add support for styled underlines on tty frames
  Add support for colored underlines on tty frames

 etc/NEWS         | 19 ++++++++++
 lisp/cus-face.el |  5 ++-
 src/dispextern.h | 11 ++++--
 src/term.c       | 46 +++++++++++++++++++++---
 src/termchar.h   |  7 ++++
 src/xfaces.c     | 93 ++++++++++++++++++++++++++++++++++++++++++++----
 6 files changed, 167 insertions(+), 14 deletions(-)

-- 
2.43.0






^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#62994: [PATCH v4 1/3] Add face definitions for more underline styles
  2024-02-11 17:15 ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames mohkale
@ 2024-02-11 17:15   ` mohkale
  2024-02-11 17:15   ` bug#62994: [PATCH v4 2/3] Add support for styled underlines on tty frames mohkale
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: mohkale @ 2024-02-11 17:15 UTC (permalink / raw)
  To: 62994, Eli Zaretskii; +Cc: Mohsin Kaleem

From: Mohsin Kaleem <mohkale@kisara.moe>

* src/dispextern.h (face_underline_type, syms_of_xfacse,
internal-set-lisp-face-attribute, gui_supports_face_attributes_p):
Add definitions for new underline styles of Double, Dotted and Dashed.
* lisp/cus-face.el (custom-face-attributes): Add entries for Double,
Dotted and Dashed so they can be set through `customize'.
---
 lisp/cus-face.el |  5 ++++-
 src/dispextern.h |  8 ++++++--
 src/xfaces.c     | 21 ++++++++++++++++++++-
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/lisp/cus-face.el b/lisp/cus-face.el
index 47afa841f5e..12551e37785 100644
--- a/lisp/cus-face.el
+++ b/lisp/cus-face.el
@@ -141,7 +141,10 @@ custom-face-attributes
 		   (const :format "" :value :style)
 		   (choice :tag "Style"
 			   (const :tag "Line" line)
-			   (const :tag "Wave" wave))
+			   (const :tag "Double" double)
+			   (const :tag "Wave" wave)
+			   (const :tag "Dotted" dotted)
+			   (const :tag "Dashed" dashed))
                    (const :format "" :value :position)
                    (choice :tag "Position"
                            (const :tag "At Default Position" nil)
diff --git a/src/dispextern.h b/src/dispextern.h
index 5387cb45603..470d2eea3ae 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1690,9 +1690,13 @@ #define FONT_TOO_HIGH(ft)						\
 
 enum face_underline_type
 {
+  // Note: Order matches the order of the Smulx terminfo extension.
   FACE_NO_UNDERLINE = 0,
   FACE_UNDER_LINE,
-  FACE_UNDER_WAVE
+  FACE_DOUBLE_UNDER_LINE,
+  FACE_UNDER_WAVE,
+  FACE_DOTTED_UNDER_LINE,
+  FACE_DASHED_UNDER_LINE,
 };
 
 /* Structure describing a realized face.
@@ -1776,7 +1780,7 @@ #define FONT_TOO_HIGH(ft)						\
   ENUM_BF (face_box_type) box : 2;
 
   /* Style of underlining. */
-  ENUM_BF (face_underline_type) underline : 2;
+  ENUM_BF (face_underline_type) underline : 3;
 
   /* If `box' above specifies a 3D type, true means use box_color for
      drawing shadows.  */
diff --git a/src/xfaces.c b/src/xfaces.c
index a558e7328c0..a76a9365b8a 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -3311,7 +3311,11 @@ DEFUN ("internal-set-lisp-face-attribute", Finternal_set_lisp_face_attribute,
                 }
 
               else if (EQ (key, QCstyle)
-                       && !(EQ (val, Qline) || EQ (val, Qwave)))
+                       && !(EQ (val, Qline) ||
+                            EQ (val, Qdouble) ||
+                            EQ (val, Qwave) ||
+                            EQ (val, Qdotted) ||
+                            EQ (val, Qdashed)))
                 {
                   valid_p = false;
                   break;
@@ -5266,6 +5270,7 @@ gui_supports_face_attributes_p (struct frame *f,
                                 Lisp_Object attrs[LFACE_VECTOR_SIZE],
                                 struct face *def_face)
 {
+  Lisp_Object val;
   Lisp_Object *def_attrs = def_face->lface;
   Lisp_Object lattrs[LFACE_VECTOR_SIZE];
 
@@ -5360,6 +5365,17 @@ gui_supports_face_attributes_p (struct frame *f,
       return false;
     }
 
+  /* Check supported underline styles. */
+  val = attrs[LFACE_UNDERLINE_INDEX];
+  if (!UNSPECIFIEDP (val)) {
+    if (EQ (CAR_SAFE (val), QCstyle)) {
+      if (!(EQ (CAR_SAFE (CDR_SAFE (val)), Qline) ||
+            EQ (CAR_SAFE (CDR_SAFE (val)), Qwave))) {
+        return false; /* Unsupported underline style */
+      }
+    }
+  }
+
   /* Everything checks out, this face is supported.  */
   return true;
 }
@@ -7229,6 +7245,9 @@ syms_of_xfaces (void)
   DEFSYM (QCposition, ":position");
   DEFSYM (Qline, "line");
   DEFSYM (Qwave, "wave");
+  DEFSYM (Qdouble, "double");
+  DEFSYM (Qdotted, "dotted");
+  DEFSYM (Qdashed, "dashed");
   DEFSYM (Qreleased_button, "released-button");
   DEFSYM (Qpressed_button, "pressed-button");
   DEFSYM (Qflat_button, "flat-button");
-- 
2.43.0






^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#62994: [PATCH v4 2/3] Add support for styled underlines on tty frames
  2024-02-11 17:15 ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames mohkale
  2024-02-11 17:15   ` bug#62994: [PATCH v4 1/3] Add face definitions for more underline styles mohkale
@ 2024-02-11 17:15   ` mohkale
  2024-02-11 17:15   ` bug#62994: [PATCH v4 3/3] Add support for colored " mohkale
  2024-02-11 17:23   ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames Mohsin Kaleem
  3 siblings, 0 replies; 7+ messages in thread
From: mohkale @ 2024-02-11 17:15 UTC (permalink / raw)
  To: 62994, Eli Zaretskii; +Cc: Mohsin Kaleem

From: Mohsin Kaleem <mohkale@kisara.moe>

* src/dispextern.h (face): Convert tty_underline_p from bool to a
face_underline_type enumeration. Add a flag to check whether styled
underlines are available.
* src/termchar.c (tty_display_info): Add an entry for the escape
sequence to set the underline style on terminal frames.
* src/term.c (init_tty, tty_capable_p, turn_on_face): Read and save the
underline style escape sequence from the Smulx termcap (alternatively if
the Su flag is set use a default sequence). Allow checking for support
of styled underlines in the current terminal frame. Output the necessary
escape sequences to activate a styled underline on turn_on_face; this is
currently only used for the new special underline styles, a default
straight underline will still use the "us" termcap.
* src/xfaces.c (tty_supports_face_attributes_p, realize_tty_face):
Assert whether styled underlines are supported by the current terminal
on display-supports-face-attributes-p checks. Populate the correct
underline style in the face spec when realizing a face.
---
 etc/NEWS         | 16 +++++++++++++
 src/dispextern.h |  3 ++-
 src/term.c       | 35 ++++++++++++++++++++++++----
 src/termchar.h   |  4 ++++
 src/xfaces.c     | 60 ++++++++++++++++++++++++++++++++++++++++++++----
 5 files changed, 109 insertions(+), 9 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 5ee1509859b..d868ee773fd 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -420,6 +420,22 @@ These characters can now be input with 'C-x 8 a e' and 'C-x 8 A E',
 respectively, in addition to the existing translations 'C-x 8 / e' and
 'C-x 8 / E'.
 
+---
+** Support for 'styled-underline' face attributes on TTY frames
+If your terminals termcap or terminfo database entry has the 'Su' or
+'Smulx' capability defined, Emacs will now emit the prescribed escape
+sequence necessary to render faces with styled underlines on TTY
+frames.
+
+Styled underlines are any underlines containing a non-default
+underline style.  The available underline styles for TTY frames are
+'double', 'wave', 'dotted', and 'dashed'.
+
+The 'Smulx' capability should define the actual sequence needed to
+render styled underlines. If ommitted, but the 'Su' flag is defined,
+then a default sequence will be used. It's recommended to use 'Smulx'
+instead of 'Su', with priority being given to 'Smulx'.
+
 \f
 * Changes in Specialized Modes and Packages in Emacs 30.1
 
diff --git a/src/dispextern.h b/src/dispextern.h
index 470d2eea3ae..31e946c387a 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1812,7 +1812,7 @@ #define FONT_TOO_HIGH(ft)						\
      string meaning the default color of the TTY.  */
   bool_bf tty_bold_p : 1;
   bool_bf tty_italic_p : 1;
-  bool_bf tty_underline_p : 1;
+  ENUM_BF (face_underline_type) tty_underline : 3;
   bool_bf tty_reverse_p : 1;
   bool_bf tty_strike_through_p : 1;
 
@@ -3425,6 +3425,7 @@ #define TTY_CAP_BOLD		0x04
 #define TTY_CAP_DIM		0x08
 #define TTY_CAP_ITALIC  	0x10
 #define TTY_CAP_STRIKE_THROUGH	0x20
+#define TTY_CAP_UNDERLINE_STYLED	0x32 & TTY_CAP_UNDERLINE
 
 \f
 /***********************************************************************
diff --git a/src/term.c b/src/term.c
index 3fa244be824..06dbb95171e 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2014,8 +2014,17 @@ turn_on_face (struct frame *f, int face_id)
 	OUTPUT1 (tty, tty->TS_enter_dim_mode);
     }
 
-  if (face->tty_underline_p && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE))
-    OUTPUT1_IF (tty, tty->TS_enter_underline_mode);
+  if (face->tty_underline && MAY_USE_WITH_COLORS_P (tty, NC_UNDERLINE)) {
+    if (face->tty_underline == FACE_UNDER_LINE ||
+        !tty->TF_set_underline_style) {
+      OUTPUT1_IF (tty, tty->TS_enter_underline_mode);
+    } else if (tty->TF_set_underline_style) {
+      char *p;
+      p = tparam(tty->TF_set_underline_style, NULL, 0, face->tty_underline, 0, 0, 0);
+      OUTPUT (tty, p);
+      xfree (p);
+    }
+  }
 
   if (face->tty_strike_through_p
       && MAY_USE_WITH_COLORS_P (tty, NC_STRIKE_THROUGH))
@@ -2061,7 +2070,7 @@ turn_off_face (struct frame *f, int face_id)
       if (face->tty_bold_p
 	  || face->tty_italic_p
 	  || face->tty_reverse_p
-	  || face->tty_underline_p
+	  || face->tty_underline
 	  || face->tty_strike_through_p)
 	{
 	  OUTPUT1_IF (tty, tty->TS_exit_attribute_mode);
@@ -2073,7 +2082,7 @@ turn_off_face (struct frame *f, int face_id)
     {
       /* If we don't have "me" we can only have those appearances
 	 that have exit sequences defined.  */
-      if (face->tty_underline_p)
+      if (face->tty_underline)
 	OUTPUT_IF (tty, tty->TS_exit_underline_mode);
     }
 
@@ -2104,6 +2113,9 @@ #define TTY_CAPABLE_P_TRY(tty, cap, TS, NC_bit)				\
   TTY_CAPABLE_P_TRY (tty,
 		     TTY_CAP_UNDERLINE,	  tty->TS_enter_underline_mode,
 		     NC_UNDERLINE);
+  TTY_CAPABLE_P_TRY (tty,
+		     TTY_CAP_UNDERLINE_STYLED,	  tty->TF_set_underline_style,
+             NC_UNDERLINE);
   TTY_CAPABLE_P_TRY (tty,
 		     TTY_CAP_BOLD,	  tty->TS_enter_bold_mode, NC_BOLD);
   TTY_CAPABLE_P_TRY (tty,
@@ -4360,6 +4372,21 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
   tty->TF_underscore = tgetflag ("ul");
   tty->TF_teleray = tgetflag ("xt");
 
+  // Styled underlines.
+  //
+  // Support for this is provided either by the escape sequence in
+  // Smulx or the Su flag. The latter results in a common default
+  // escape sequence and is not recommended.
+#ifdef TERMINFO
+  tty->TF_set_underline_style = tigetstr("Smulx");
+  if (tty->TF_set_underline_style == (char *) (intptr_t) -1)
+    tty->TF_set_underline_style = NULL;
+#else
+  tty->TF_set_underline_style = tgetstr("Smulx", address);
+#endif
+  if (!tty->TF_set_underline_style && tgetflag("Su"))
+    tty->TF_set_underline_style = "\x1b[4:%p1%dm";
+
 #else /* DOS_NT */
 #ifdef WINDOWSNT
   {
diff --git a/src/termchar.h b/src/termchar.h
index 2d845107e11..7fc1f347230 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -171,6 +171,10 @@ #define EMACS_TERMCHAR_H
                                    non-blank position.  Must clear before writing _.  */
   int TF_teleray;               /* termcap xt flag: many weird consequences.
                                    For t1061. */
+  const char *TF_set_underline_style;   /* termcap Smulx entry: Switches the underline
+                                           style based on the parameter. Param should
+                                           be one of: 0 (none), 1 (straight), 2 (double),
+                                           3 (wave), 4 (dotted), or 5 (dashed). */
 
   int RPov;                     /* # chars to start a TS_repeat */
 
diff --git a/src/xfaces.c b/src/xfaces.c
index a76a9365b8a..684e72bd897 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -5470,8 +5470,18 @@ tty_supports_face_attributes_p (struct frame *f,
     {
       if (STRINGP (val))
 	return false;		/* ttys can't use colored underlines */
-      else if (EQ (CAR_SAFE (val), QCstyle) && EQ (CAR_SAFE (CDR_SAFE (val)), Qwave))
-	return false;		/* ttys can't use wave underlines */
+      else if (EQ (CAR_SAFE (val), QCstyle))
+    {
+        if (!(EQ (CAR_SAFE (CDR_SAFE (val)), Qline) ||
+              EQ (CAR_SAFE (CDR_SAFE (val)), Qdouble) ||
+              EQ (CAR_SAFE (CDR_SAFE (val)), Qwave) ||
+              EQ (CAR_SAFE (CDR_SAFE (val)), Qdotted) ||
+              EQ (CAR_SAFE (CDR_SAFE (val)), Qdashed))) {
+            return false; /* Unsupported underline style */
+        }
+
+	    test_caps |= TTY_CAP_UNDERLINE_STYLED;
+    }
       else if (face_attr_equal_p (val, def_attrs[LFACE_UNDERLINE_INDEX]))
 	return false;		/* same as default */
       else
@@ -6397,6 +6407,8 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
                 face->underline = FACE_UNDER_LINE;
               else if (EQ (value, Qwave))
                 face->underline = FACE_UNDER_WAVE;
+              else
+                face->underline = FACE_UNDER_LINE;
             }
 	  else if (EQ (keyword, QCposition))
 	    {
@@ -6531,6 +6543,7 @@ realize_tty_face (struct face_cache *cache,
 {
   struct face *face;
   int weight, slant;
+  Lisp_Object underline;
   bool face_colors_defaulted = false;
   struct frame *f = cache->f;
 
@@ -6550,13 +6563,52 @@ realize_tty_face (struct face_cache *cache,
     face->tty_bold_p = true;
   if (slant != 100)
     face->tty_italic_p = true;
-  if (!NILP (attrs[LFACE_UNDERLINE_INDEX]))
-    face->tty_underline_p = true;
   if (!NILP (attrs[LFACE_INVERSE_INDEX]))
     face->tty_reverse_p = true;
   if (!NILP (attrs[LFACE_STRIKE_THROUGH_INDEX]))
     face->tty_strike_through_p = true;
 
+  /* Text underline.  */
+  underline = attrs[LFACE_UNDERLINE_INDEX];
+  if (NILP (underline)) {
+    face->tty_underline = FACE_NO_UNDERLINE;
+  } else if (EQ (underline, Qt)) {
+    face->tty_underline = FACE_UNDER_LINE;
+  } else if (STRINGP (underline)) {
+    face->tty_underline = FACE_UNDER_LINE;
+  } else if (CONSP (underline)) {
+    /* `(:style STYLE)'.
+       STYLE being one of `line', `double', `wave', `dotted' or `dashed'. */
+    face->tty_underline = FACE_UNDER_LINE;
+
+    while (CONSP (underline)) {
+      Lisp_Object keyword, value;
+
+      keyword = XCAR (underline);
+      underline = XCDR (underline);
+
+      if (!CONSP (underline))
+        break;
+      value = XCAR (underline);
+      underline = XCDR (underline);
+
+      if (EQ (keyword, QCstyle)) {
+        if (EQ (value, Qline))
+          face->tty_underline = FACE_UNDER_LINE;
+        else if (EQ (value, Qdouble))
+          face->tty_underline = FACE_DOUBLE_UNDER_LINE;
+        else if (EQ (value, Qwave))
+          face->tty_underline = FACE_UNDER_WAVE;
+        else if (EQ (value, Qdotted))
+          face->tty_underline = FACE_DOTTED_UNDER_LINE;
+        else if (EQ (value, Qdashed))
+          face->tty_underline = FACE_DASHED_UNDER_LINE;
+        else
+          face->tty_underline = FACE_UNDER_LINE;
+      }
+    }
+  }
+
   /* Map color names to color indices.  */
   map_tty_color (f, face, LFACE_FOREGROUND_INDEX, &face_colors_defaulted);
   map_tty_color (f, face, LFACE_BACKGROUND_INDEX, &face_colors_defaulted);
-- 
2.43.0






^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#62994: [PATCH v4 3/3] Add support for colored underlines on tty frames
  2024-02-11 17:15 ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames mohkale
  2024-02-11 17:15   ` bug#62994: [PATCH v4 1/3] Add face definitions for more underline styles mohkale
  2024-02-11 17:15   ` bug#62994: [PATCH v4 2/3] Add support for styled underlines on tty frames mohkale
@ 2024-02-11 17:15   ` mohkale
  2024-02-11 17:23   ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames Mohsin Kaleem
  3 siblings, 0 replies; 7+ messages in thread
From: mohkale @ 2024-02-11 17:15 UTC (permalink / raw)
  To: 62994, Eli Zaretskii; +Cc: Mohsin Kaleem

From: Mohsin Kaleem <mohkale@kisara.moe>

* src/term.c (turn_on_face, init_tty): Output escape sequence to set
underline color when set in the face and supported by the tty. Save
a default value for this sequence on init_tty when styled underlines
are supported.
* src/termchar.c (tty_display_info): Add an entry for the escape
sequence to set the underline color on terminal frames.
* src/xfaces.c (tty_supports_face_attributes_p, realize_tty_face):
Assert whether colored underlines are supported by the current terminal
on display-supports-face-attributes-p checks. Load and save the color
of the underline from the face spec when realizing a face.
---
 etc/NEWS       | 11 +++++++----
 src/term.c     | 11 +++++++++++
 src/termchar.h |  3 +++
 src/xfaces.c   | 16 +++++++++++++---
 4 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index d868ee773fd..73a15eb44a4 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -421,20 +421,23 @@ respectively, in addition to the existing translations 'C-x 8 / e' and
 'C-x 8 / E'.
 
 ---
-** Support for 'styled-underline' face attributes on TTY frames
+** Support for 'styled' and 'colored' underline face attributes on TTY frames
 If your terminals termcap or terminfo database entry has the 'Su' or
 'Smulx' capability defined, Emacs will now emit the prescribed escape
 sequence necessary to render faces with styled underlines on TTY
 frames.
 
 Styled underlines are any underlines containing a non-default
-underline style.  The available underline styles for TTY frames are
-'double', 'wave', 'dotted', and 'dashed'.
+underline style or a color other than the foreground-color.
+The available underline styles for TTY frames are 'double', 'wave',
+'dotted', and 'dashed'.
 
 The 'Smulx' capability should define the actual sequence needed to
 render styled underlines. If ommitted, but the 'Su' flag is defined,
 then a default sequence will be used. It's recommended to use 'Smulx'
-instead of 'Su', with priority being given to 'Smulx'.
+instead of 'Su', with priority being given to 'Smulx'.  Support for
+colored underlines is automatically enabled with a default escape
+sequence when styled underline are supported.
 
 \f
 * Changes in Specialized Modes and Packages in Emacs 30.1
diff --git a/src/term.c b/src/term.c
index 06dbb95171e..1ab6936db76 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2050,6 +2050,14 @@ turn_on_face (struct frame *f, int face_id)
 	  OUTPUT (tty, p);
 	  xfree (p);
 	}
+
+      ts = tty->TF_set_underline_color;
+      if (ts && face->underline_color)
+	{
+          p = tparam (ts, NULL, 0, face->underline_color, 0, 0, 0);
+	  OUTPUT (tty, p);
+	  xfree (p);
+	}
     }
 }
 
@@ -4387,6 +4395,9 @@ init_tty (const char *name, const char *terminal_type, bool must_succeed)
   if (!tty->TF_set_underline_style && tgetflag("Su"))
     tty->TF_set_underline_style = "\x1b[4:%p1%dm";
 
+  if (tty->TF_set_underline_style)
+    tty->TF_set_underline_color = "\x1b[58:2::%p1%{65536}%/%d:%p1%{256}%/%{255}%&%d:%p1%{255}%&%dm";
+
 #else /* DOS_NT */
 #ifdef WINDOWSNT
   {
diff --git a/src/termchar.h b/src/termchar.h
index 7fc1f347230..846cd3001cc 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -175,6 +175,9 @@ #define EMACS_TERMCHAR_H
                                            style based on the parameter. Param should
                                            be one of: 0 (none), 1 (straight), 2 (double),
                                            3 (wave), 4 (dotted), or 5 (dashed). */
+  const char *TF_set_underline_color;   /* Enabled when TF_set_underline_style is set:
+                                           Sets the color of the underline. Accepts a
+                                           single parameter, the color index. */
 
   int RPov;                     /* # chars to start a TS_repeat */
 
diff --git a/src/xfaces.c b/src/xfaces.c
index 684e72bd897..4d860540cb9 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -5469,7 +5469,7 @@ tty_supports_face_attributes_p (struct frame *f,
   if (!UNSPECIFIEDP (val))
     {
       if (STRINGP (val))
-	return false;		/* ttys can't use colored underlines */
+	test_caps |= TTY_CAP_UNDERLINE_STYLED;
       else if (EQ (CAR_SAFE (val), QCstyle))
     {
         if (!(EQ (CAR_SAFE (CDR_SAFE (val)), Qline) ||
@@ -6572,14 +6572,18 @@ realize_tty_face (struct face_cache *cache,
   underline = attrs[LFACE_UNDERLINE_INDEX];
   if (NILP (underline)) {
     face->tty_underline = FACE_NO_UNDERLINE;
+    face->underline_color = 0;
   } else if (EQ (underline, Qt)) {
     face->tty_underline = FACE_UNDER_LINE;
+    face->underline_color = 0;
   } else if (STRINGP (underline)) {
     face->tty_underline = FACE_UNDER_LINE;
+	face->underline_color = load_color (f, face, underline, LFACE_UNDERLINE_INDEX);
   } else if (CONSP (underline)) {
-    /* `(:style STYLE)'.
+    /* `(:color COLOR :style STYLE)'.
        STYLE being one of `line', `double', `wave', `dotted' or `dashed'. */
     face->tty_underline = FACE_UNDER_LINE;
+    face->underline_color = 0;
 
     while (CONSP (underline)) {
       Lisp_Object keyword, value;
@@ -6592,7 +6596,13 @@ realize_tty_face (struct face_cache *cache,
       value = XCAR (underline);
       underline = XCDR (underline);
 
-      if (EQ (keyword, QCstyle)) {
+      if (EQ (keyword, QCcolor)) {
+        if (EQ (value, Qforeground_color))
+          face->underline_color = 0;
+        else if (STRINGP (value))
+          face->underline_color = load_color (f, face, value, LFACE_UNDERLINE_INDEX);
+      }
+      else if (EQ (keyword, QCstyle)) {
         if (EQ (value, Qline))
           face->tty_underline = FACE_UNDER_LINE;
         else if (EQ (value, Qdouble))
-- 
2.43.0






^ permalink raw reply related	[flat|nested] 7+ messages in thread

* bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames
  2024-02-11 17:15 ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames mohkale
                     ` (2 preceding siblings ...)
  2024-02-11 17:15   ` bug#62994: [PATCH v4 3/3] Add support for colored " mohkale
@ 2024-02-11 17:23   ` Mohsin Kaleem
  2024-02-11 17:46     ` Eli Zaretskii
  3 siblings, 1 reply; 7+ messages in thread
From: Mohsin Kaleem @ 2024-02-11 17:23 UTC (permalink / raw)
  To: 62994, Eli Zaretskii

mohkale@kisara.moe writes:

Hi, sorry, please disregard this email. I seem to have messed up and
published the wrong patchset and also to the wrong email chain.


-- 
Mohsin Kaleem





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames
  2024-02-11 17:23   ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames Mohsin Kaleem
@ 2024-02-11 17:46     ` Eli Zaretskii
  0 siblings, 0 replies; 7+ messages in thread
From: Eli Zaretskii @ 2024-02-11 17:46 UTC (permalink / raw)
  To: Mohsin Kaleem; +Cc: 62994

> From: Mohsin Kaleem <mohkale@kisara.moe>
> Date: Sun, 11 Feb 2024 17:23:58 +0000
> 
> mohkale@kisara.moe writes:
> 
> Hi, sorry, please disregard this email. I seem to have messed up and
> published the wrong patchset and also to the wrong email chain.

If you are going to post this patch again, please note that I prefer
to see a single large patch instead of a series of smaller ones,
especially if some files are touched by more than one patch in the
series.  Having a single patch makes reviewing the changeset easier.

TIA





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-02-11 17:46 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-21 14:29 bug#62994: Support styled underlines on TTY frames Mohsin Kaleem
2024-02-11 17:15 ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames mohkale
2024-02-11 17:15   ` bug#62994: [PATCH v4 1/3] Add face definitions for more underline styles mohkale
2024-02-11 17:15   ` bug#62994: [PATCH v4 2/3] Add support for styled underlines on tty frames mohkale
2024-02-11 17:15   ` bug#62994: [PATCH v4 3/3] Add support for colored " mohkale
2024-02-11 17:23   ` bug#62994: [PATCH v4 0/3] Support styled underlines on tty Emacs frames Mohsin Kaleem
2024-02-11 17:46     ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).