summaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorMarcelo Lira <setanta@gmail.com>2025-03-02 03:00:07 -0300
committerMarcelo Lira <setanta@gmail.com>2025-03-03 16:12:29 -0300
commit050e0bef8e571a571684a12c4c86364c637c12d7 (patch)
treec785a796495798fdd062e662e45e139ff6253b24 /st.c
parent01d5521913a1ff71cbc4f1534d8eb26c9e2f2978 (diff)
Undercurl patch
https://st.suckless.org/patches/undercurl/
Diffstat (limited to 'st.c')
-rw-r--r--st.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/st.c b/st.c
index ef8a793..6351657 100644
--- a/st.c
+++ b/st.c
@@ -33,6 +33,7 @@
#define UTF_SIZ 4
#define ESC_BUF_SIZ (128*UTF_SIZ)
#define ESC_ARG_SIZ 16
+#define CAR_PER_ARG 4
#define STR_BUF_SIZ ESC_BUF_SIZ
#define STR_ARG_SIZ ESC_ARG_SIZ
@@ -139,6 +140,7 @@ typedef struct {
int arg[ESC_ARG_SIZ];
int narg; /* nb of args */
char mode[2];
+ int carg[ESC_ARG_SIZ][CAR_PER_ARG]; /* colon args */
} CSIEscape;
/* STR Escape sequence structs */
@@ -159,6 +161,7 @@ static void ttywriteraw(const char *, size_t);
static void csidump(void);
static void csihandle(void);
+static void readcolonargs(char **, int, int[][CAR_PER_ARG]);
static void csiparse(void);
static void csireset(void);
static void osc_color_response(int, int, int);
@@ -1128,6 +1131,28 @@ tnewline(int first_col)
}
void
+readcolonargs(char **p, int cursor, int params[][CAR_PER_ARG])
+{
+ int i = 0;
+ for (; i < CAR_PER_ARG; i++)
+ params[cursor][i] = -1;
+
+ if (**p != ':')
+ return;
+
+ char *np = NULL;
+ i = 0;
+
+ while (**p == ':' && i < CAR_PER_ARG) {
+ while (**p == ':')
+ (*p)++;
+ params[cursor][i] = strtol(*p, &np, 10);
+ *p = np;
+ i++;
+ }
+}
+
+void
csiparse(void)
{
char *p = csiescseq.buf, *np;
@@ -1150,6 +1175,7 @@ csiparse(void)
v = -1;
csiescseq.arg[csiescseq.narg++] = v;
p = np;
+ readcolonargs(&p, csiescseq.narg-1, csiescseq.carg);
if (sep == ';' && *p == ':')
sep = ':'; /* allow override to colon once */
if (*p != sep || csiescseq.narg == ESC_ARG_SIZ)
@@ -1368,6 +1394,10 @@ tsetattr(const int *attr, int l)
ATTR_STRUCK );
term.c.attr.fg = defaultfg;
term.c.attr.bg = defaultbg;
+ term.c.attr.ustyle = -1;
+ term.c.attr.ucolor[0] = -1;
+ term.c.attr.ucolor[1] = -1;
+ term.c.attr.ucolor[2] = -1;
break;
case 1:
term.c.attr.mode |= ATTR_BOLD;
@@ -1379,7 +1409,14 @@ tsetattr(const int *attr, int l)
term.c.attr.mode |= ATTR_ITALIC;
break;
case 4:
- term.c.attr.mode |= ATTR_UNDERLINE;
+ term.c.attr.ustyle = csiescseq.carg[i][0];
+
+ if (term.c.attr.ustyle != 0)
+ term.c.attr.mode |= ATTR_UNDERLINE;
+ else
+ term.c.attr.mode &= ~ATTR_UNDERLINE;
+
+ term.c.attr.mode ^= ATTR_DIRTYUNDERLINE;
break;
case 5: /* slow blink */
/* FALLTHROUGH */
@@ -1430,6 +1467,18 @@ tsetattr(const int *attr, int l)
case 49:
term.c.attr.bg = defaultbg;
break;
+ case 58:
+ term.c.attr.ucolor[0] = csiescseq.carg[i][1];
+ term.c.attr.ucolor[1] = csiescseq.carg[i][2];
+ term.c.attr.ucolor[2] = csiescseq.carg[i][3];
+ term.c.attr.mode ^= ATTR_DIRTYUNDERLINE;
+ break;
+ case 59:
+ term.c.attr.ucolor[0] = -1;
+ term.c.attr.ucolor[1] = -1;
+ term.c.attr.ucolor[2] = -1;
+ term.c.attr.mode ^= ATTR_DIRTYUNDERLINE;
+ break;
default:
if (BETWEEN(attr[i], 30, 37)) {
term.c.attr.fg = attr[i] - 30;