summaryrefslogtreecommitdiff
path: root/st/unpatched
diff options
context:
space:
mode:
authorTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2025-03-08 15:21:28 +0900
committerTheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com>2025-03-08 15:21:28 +0900
commit4437d5b3c3eea76f6e2b0fd4a2ba21c02a098aeb (patch)
treee8dcb20bf144aacf88f93b012dccacdeb08015cd /st/unpatched
parentc2b06f0d5795a789f4ddab459179ff89aedfee98 (diff)
updates
Diffstat (limited to 'st/unpatched')
-rw-r--r--st/unpatched/st-color_schemes-20220615-baa9357.diff169
-rw-r--r--st/unpatched/st-delkey-20201112-4ef0cbd.diff20
-rw-r--r--st/unpatched/st-relativeborder-0.8.3.diff39
-rw-r--r--st/unpatched/st-undercurl-0.9-20240103.diff606
-rw-r--r--st/unpatched/st-universcroll-0.8.4.diff90
-rw-r--r--st/unpatched/st-universcroll-example-0.8.4.diff47
6 files changed, 971 insertions, 0 deletions
diff --git a/st/unpatched/st-color_schemes-20220615-baa9357.diff b/st/unpatched/st-color_schemes-20220615-baa9357.diff
new file mode 100644
index 0000000..188fece
--- /dev/null
+++ b/st/unpatched/st-color_schemes-20220615-baa9357.diff
@@ -0,0 +1,169 @@
+From 285c1c63f22bc00771428088c1938b8a0161bd7b Mon Sep 17 00:00:00 2001
+From: Max Schillinger <maxschillinger@web.de>
+Date: Wed, 15 Jun 2022 21:06:42 +0200
+Subject: [PATCH] color_schemes patch for st commit baa9357
+
+---
+ config.def.h | 57 ++++++++++++++++++++++------------------------------
+ x.c | 35 +++++++++++++++-----------------
+ 2 files changed, 40 insertions(+), 52 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 91ab8ca..22bdb3c 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -93,46 +93,28 @@ char *termname = "st-256color";
+ */
+ unsigned int tabspaces = 8;
+
+-/* Terminal colors (16 first used in escape sequence) */
+-static const char *colorname[] = {
+- /* 8 normal colors */
+- "black",
+- "red3",
+- "green3",
+- "yellow3",
+- "blue2",
+- "magenta3",
+- "cyan3",
+- "gray90",
+-
+- /* 8 bright colors */
+- "gray50",
+- "red",
+- "green",
+- "yellow",
+- "#5c5cff",
+- "magenta",
+- "cyan",
+- "white",
+-
+- [255] = 0,
+-
+- /* more colors can be added after 255 to use with DefaultXX */
+- "#cccccc",
+- "#555555",
+- "gray90", /* default foreground colour */
+- "black", /* default background colour */
++/* Terminal colors (16 used in escape sequence) */
++static const char *palettes[][16] = {
++ {"black", "red3", "green3", "yellow3", "blue2", "magenta3", "cyan3", "gray90",
++ "gray50", "red", "green", "yellow", "#5c5cff", "magenta", "cyan", "white"},
++ {"#223", "#900", "#080", "#fe7", "#35e", "#fc5", "#18e", "#aaa",
++ "#666", "#f25", "#0b0", "#ff6", "#46f", "#d6a", "#6bf", "#ddd"},
++ {"#eaeaea", "#b7141f", "#457b24", "#fc7b08", "#134eb2", "#560088", "#0e717c", "#777777",
++ "#424242", "#e83b3f", "#7aba3a", "#fd8e09", "#54a4f3", "#aa4dbc", "#26bbd1", "#aaaaaa"},
++ {"#20242d", "#b04b57", "#87b379", "#e5c179", "#7d8fa4", "#a47996", "#85a7a5", "#b3b8c3",
++ "#000000", "#b04b57", "#87b379", "#e5c179", "#7d8fa4", "#a47996", "#85a7a5", "#ffffff"},
+ };
+
++static const char **colorname;
+
+ /*
+ * Default colors (colorname index)
+ * foreground, background, cursor, reverse cursor
+ */
+-unsigned int defaultfg = 258;
+-unsigned int defaultbg = 259;
+-unsigned int defaultcs = 256;
+-static unsigned int defaultrcs = 257;
++unsigned int defaultfg = 5;
++unsigned int defaultbg = 0;
++unsigned int defaultcs = 5;
++static unsigned int defaultrcs = 5;
+
+ /*
+ * Default shape of cursor
+@@ -201,6 +183,15 @@ static Shortcut shortcuts[] = {
+ { TERMMOD, XK_Y, selpaste, {.i = 0} },
+ { ShiftMask, XK_Insert, selpaste, {.i = 0} },
+ { TERMMOD, XK_Num_Lock, numlock, {.i = 0} },
++ { MODKEY|ShiftMask, XK_F1, setpalette, {.i = 0} },
++ { MODKEY|ShiftMask, XK_F2, setpalette, {.i = 1} },
++ { MODKEY|ShiftMask, XK_F3, setpalette, {.i = 2} },
++ { MODKEY|ShiftMask, XK_F4, setpalette, {.i = 3} },
++ { MODKEY|ShiftMask, XK_F5, setpalette, {.i = 4} },
++ { MODKEY|ShiftMask, XK_F6, setpalette, {.i = 5} },
++ { MODKEY|ShiftMask, XK_F7, setpalette, {.i = 6} },
++ { MODKEY|ShiftMask, XK_F8, setpalette, {.i = 7} },
++ { MODKEY|ShiftMask, XK_F9, setpalette, {.i = 8} },
+ };
+
+ /*
+diff --git a/x.c b/x.c
+index 2a3bd38..0d77d2a 100644
+--- a/x.c
++++ b/x.c
+@@ -59,6 +59,7 @@ static void zoom(const Arg *);
+ static void zoomabs(const Arg *);
+ static void zoomreset(const Arg *);
+ static void ttysend(const Arg *);
++static void setpalette(const Arg *);
+
+ /* config.h for applying patches and the configuration. */
+ #include "config.h"
+@@ -769,24 +770,8 @@ sixd_to_16bit(int x)
+ int
+ xloadcolor(int i, const char *name, Color *ncolor)
+ {
+- XRenderColor color = { .alpha = 0xffff };
+-
+- if (!name) {
+- if (BETWEEN(i, 16, 255)) { /* 256 color */
+- if (i < 6*6*6+16) { /* same colors as xterm */
+- color.red = sixd_to_16bit( ((i-16)/36)%6 );
+- color.green = sixd_to_16bit( ((i-16)/6) %6 );
+- color.blue = sixd_to_16bit( ((i-16)/1) %6 );
+- } else { /* greyscale */
+- color.red = 0x0808 + 0x0a0a * (i - (6*6*6+16));
+- color.green = color.blue = color.red;
+- }
+- return XftColorAllocValue(xw.dpy, xw.vis,
+- xw.cmap, &color, ncolor);
+- } else
+- name = colorname[i];
+- }
+-
++ if (!name)
++ name = colorname[i];
+ return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor);
+ }
+
+@@ -801,7 +786,7 @@ xloadcols(void)
+ for (cp = dc.col; cp < &dc.col[dc.collen]; ++cp)
+ XftColorFree(xw.dpy, xw.vis, xw.cmap, cp);
+ } else {
+- dc.collen = MAX(LEN(colorname), 256);
++ dc.collen = 16;
+ dc.col = xmalloc(dc.collen * sizeof(Color));
+ }
+
+@@ -2024,6 +2009,16 @@ usage(void)
+ " [stty_args ...]\n", argv0, argv0);
+ }
+
++void
++setpalette(const Arg *arg)
++{
++ if (arg->i < LEN(palettes)) {
++ colorname = palettes[arg->i];
++ xloadcols();
++ cresize(win.w, win.h);
++ }
++}
++
+ int
+ main(int argc, char *argv[])
+ {
+@@ -2076,6 +2071,8 @@ main(int argc, char *argv[])
+ } ARGEND;
+
+ run:
++ colorname = palettes[0];
++
+ if (argc > 0) /* eat all remaining arguments */
+ opt_cmd = argv;
+
+--
+2.36.1
+
diff --git a/st/unpatched/st-delkey-20201112-4ef0cbd.diff b/st/unpatched/st-delkey-20201112-4ef0cbd.diff
new file mode 100644
index 0000000..c334b0d
--- /dev/null
+++ b/st/unpatched/st-delkey-20201112-4ef0cbd.diff
@@ -0,0 +1,20 @@
+--- config.def.h.orig 2020-11-12 20:23:48.867954750 +0100
++++ config.def.h 2020-11-12 20:21:15.055922720 +0100
+@@ -276,7 +276,7 @@
+ { XK_KP_Delete, ControlMask, "\033[3;5~", +1, 0},
+ { XK_KP_Delete, ShiftMask, "\033[2K", -1, 0},
+ { XK_KP_Delete, ShiftMask, "\033[3;2~", +1, 0},
+- { XK_KP_Delete, XK_ANY_MOD, "\033[P", -1, 0},
++ { XK_KP_Delete, XK_ANY_MOD, "\033[3~", -1, 0},
+ { XK_KP_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
+ { XK_KP_Multiply, XK_ANY_MOD, "\033Oj", +2, 0},
+ { XK_KP_Add, XK_ANY_MOD, "\033Ok", +2, 0},
+@@ -344,7 +344,7 @@
+ { XK_Delete, ControlMask, "\033[3;5~", +1, 0},
+ { XK_Delete, ShiftMask, "\033[2K", -1, 0},
+ { XK_Delete, ShiftMask, "\033[3;2~", +1, 0},
+- { XK_Delete, XK_ANY_MOD, "\033[P", -1, 0},
++ { XK_Delete, XK_ANY_MOD, "\033[3~", -1, 0},
+ { XK_Delete, XK_ANY_MOD, "\033[3~", +1, 0},
+ { XK_BackSpace, XK_NO_MOD, "\177", 0, 0},
+ { XK_BackSpace, Mod1Mask, "\033\177", 0, 0},
diff --git a/st/unpatched/st-relativeborder-0.8.3.diff b/st/unpatched/st-relativeborder-0.8.3.diff
new file mode 100644
index 0000000..55839d2
--- /dev/null
+++ b/st/unpatched/st-relativeborder-0.8.3.diff
@@ -0,0 +1,39 @@
+diff -up ../st-0.8.3/config.def.h ./config.def.h
+--- ../st-0.8.3/config.def.h 2020-04-27 13:58:27.000000000 +0200
++++ ./config.def.h 2020-05-24 18:27:19.179361165 +0200
+@@ -4,9 +4,11 @@
+ * appearance
+ *
+ * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html
++ * borderperc: percentage of cell width to use as a border
++ * 0 = no border, 100 = border width is same as cell width
+ */
+ static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true";
+-static int borderpx = 2;
++static int borderperc = 20;
+
+ /*
+ * What program is execed by st depends of these precedence rules:
+diff -up ../st-0.8.3/st.h ./st.h
+--- ../st-0.8.3/st.h 2020-04-27 13:58:27.000000000 +0200
++++ ./st.h 2020-05-24 18:27:20.255369735 +0200
+@@ -52,6 +52,7 @@ enum selection_snap {
+ SNAP_LINE = 2
+ };
+
++int borderpx;
+ typedef unsigned char uchar;
+ typedef unsigned int uint;
+ typedef unsigned long ulong;
+diff -up ../st-0.8.3/x.c ./x.c
+--- ../st-0.8.3/x.c 2020-04-27 13:58:27.000000000 +0200
++++ ./x.c 2020-05-24 18:27:17.551348200 +0200
+@@ -1001,6 +1001,8 @@ xloadfonts(char *fontstr, double fontsiz
+ win.cw = ceilf(dc.font.width * cwscale);
+ win.ch = ceilf(dc.font.height * chscale);
+
++ borderpx = ceilf(((float)borderperc / 100) * win.cw);
++
+ FcPatternDel(pattern, FC_SLANT);
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+ if (xloadfont(&dc.ifont, pattern))
diff --git a/st/unpatched/st-undercurl-0.9-20240103.diff b/st/unpatched/st-undercurl-0.9-20240103.diff
new file mode 100644
index 0000000..b099933
--- /dev/null
+++ b/st/unpatched/st-undercurl-0.9-20240103.diff
@@ -0,0 +1,606 @@
+diff --git a/config.def.h b/config.def.h
+index 6f05dce..7ae1b92 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -470,3 +470,27 @@ static char ascii_printable[] =
+ " !\"#$%&'()*+,-./0123456789:;<=>?"
+ "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
+ "`abcdefghijklmnopqrstuvwxyz{|}~";
++
++/**
++ * Undercurl style. Set UNDERCURL_STYLE to one of the available styles.
++ *
++ * Curly: Dunno how to draw it *shrug*
++ * _ _ _ _
++ * ( ) ( ) ( ) ( )
++ * (_) (_) (_) (_)
++ *
++ * Spiky:
++ * /\ /\ /\ /\
++ * \/ \/ \/
++ *
++ * Capped:
++ * _ _ _
++ * / \ / \ / \
++ * \_/ \_/
++ */
++// Available styles
++#define UNDERCURL_CURLY 0
++#define UNDERCURL_SPIKY 1
++#define UNDERCURL_CAPPED 2
++// Active style
++#define UNDERCURL_STYLE UNDERCURL_SPIKY
+diff --git a/st.c b/st.c
+index 76b7e0d..542ab3a 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,7 +161,8 @@ 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);
+ static int eschandle(uchar);
+@@ -1131,6 +1134,28 @@ tnewline(int first_col)
+ tmoveto(first_col ? 0 : term.c.x, y);
+ }
+
++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)
+ {
+@@ -1153,6 +1178,7 @@ csiparse(void)
+ v = -1;
+ csiescseq.arg[csiescseq.narg++] = v;
+ p = np;
++ readcolonargs(&p, csiescseq.narg-1, csiescseq.carg);
+ if (*p != ';' || csiescseq.narg == ESC_ARG_SIZ)
+ break;
+ p++;
+@@ -1369,6 +1395,10 @@ tsetattr(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;
+@@ -1380,7 +1410,14 @@ tsetattr(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 */
+@@ -1431,6 +1468,18 @@ tsetattr(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;
+diff --git a/st.h b/st.h
+index 3d351b6..95bdcbd 100644
+--- a/st.h
++++ b/st.h
+@@ -34,6 +34,7 @@ enum glyph_attribute {
+ ATTR_WIDE = 1 << 9,
+ ATTR_WDUMMY = 1 << 10,
+ ATTR_BOLD_FAINT = ATTR_BOLD | ATTR_FAINT,
++ ATTR_DIRTYUNDERLINE = 1 << 15,
+ };
+
+ enum selection_mode {
+@@ -65,6 +66,8 @@ typedef struct {
+ ushort mode; /* attribute flags */
+ uint32_t fg; /* foreground */
+ uint32_t bg; /* background */
++ int ustyle; /* underline style */
++ int ucolor[3]; /* underline color */
+ } Glyph;
+
+ typedef Glyph *Line;
+diff --git a/st.info b/st.info
+index 8201ad6..659878c 100644
+--- a/st.info
++++ b/st.info
+@@ -1,4 +1,5 @@
+ st-mono| simpleterm monocolor,
++ Su,
+ acsc=+C\,D-A.B0E``aaffgghFiGjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
+ am,
+ bce,
+diff --git a/x.c b/x.c
+index 210f184..3a0e79e 100644
+--- a/x.c
++++ b/x.c
+@@ -45,6 +45,14 @@ typedef struct {
+ signed char appcursor; /* application cursor */
+ } Key;
+
++/* Undercurl slope types */
++enum undercurl_slope_type {
++ UNDERCURL_SLOPE_ASCENDING = 0,
++ UNDERCURL_SLOPE_TOP_CAP = 1,
++ UNDERCURL_SLOPE_DESCENDING = 2,
++ UNDERCURL_SLOPE_BOTTOM_CAP = 3
++};
++
+ /* X modifiers */
+ #define XK_ANY_MOD UINT_MAX
+ #define XK_NO_MOD 0
+@@ -1339,6 +1347,51 @@ xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x
+ return numspecs;
+ }
+
++static int isSlopeRising (int x, int iPoint, int waveWidth)
++{
++ // . . . .
++ // / \ / \ / \ / \
++ // / \ / \ / \ / \
++ // . . . . .
++
++ // Find absolute `x` of point
++ x += iPoint * (waveWidth/2);
++
++ // Find index of absolute wave
++ int absSlope = x / ((float)waveWidth/2);
++
++ return (absSlope % 2);
++}
++
++static int getSlope (int x, int iPoint, int waveWidth)
++{
++ // Sizes: Caps are half width of slopes
++ // 1_2 1_2 1_2 1_2
++ // / \ / \ / \ / \
++ // / \ / \ / \ / \
++ // 0 3_0 3_0 3_0 3_
++ // <2-> <1> <---6---->
++
++ // Find type of first point
++ int firstType;
++ x -= (x / waveWidth) * waveWidth;
++ if (x < (waveWidth * (2.f/6.f)))
++ firstType = UNDERCURL_SLOPE_ASCENDING;
++ else if (x < (waveWidth * (3.f/6.f)))
++ firstType = UNDERCURL_SLOPE_TOP_CAP;
++ else if (x < (waveWidth * (5.f/6.f)))
++ firstType = UNDERCURL_SLOPE_DESCENDING;
++ else
++ firstType = UNDERCURL_SLOPE_BOTTOM_CAP;
++
++ // Find type of given point
++ int pointType = (iPoint % 4);
++ pointType += firstType;
++ pointType %= 4;
++
++ return pointType;
++}
++
+ void
+ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y)
+ {
+@@ -1461,8 +1514,357 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i
+
+ /* Render underline and strikethrough. */
+ if (base.mode & ATTR_UNDERLINE) {
+- XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent * chscale + 1,
+- width, 1);
++ // Underline Color
++ const int widthThreshold = 28; // +1 width every widthThreshold px of font
++ int wlw = (win.ch / widthThreshold) + 1; // Wave Line Width
++ int linecolor;
++ if ((base.ucolor[0] >= 0) &&
++ !(base.mode & ATTR_BLINK && win.mode & MODE_BLINK) &&
++ !(base.mode & ATTR_INVISIBLE)
++ ) {
++ // Special color for underline
++ // Index
++ if (base.ucolor[1] < 0) {
++ linecolor = dc.col[base.ucolor[0]].pixel;
++ }
++ // RGB
++ else {
++ XColor lcolor;
++ lcolor.red = base.ucolor[0] * 257;
++ lcolor.green = base.ucolor[1] * 257;
++ lcolor.blue = base.ucolor[2] * 257;
++ lcolor.flags = DoRed | DoGreen | DoBlue;
++ XAllocColor(xw.dpy, xw.cmap, &lcolor);
++ linecolor = lcolor.pixel;
++ }
++ } else {
++ // Foreground color for underline
++ linecolor = fg->pixel;
++ }
++
++ XGCValues ugcv = {
++ .foreground = linecolor,
++ .line_width = wlw,
++ .line_style = LineSolid,
++ .cap_style = CapNotLast
++ };
++
++ GC ugc = XCreateGC(xw.dpy, XftDrawDrawable(xw.draw),
++ GCForeground | GCLineWidth | GCLineStyle | GCCapStyle,
++ &ugcv);
++
++ // Underline Style
++ if (base.ustyle != 3) {
++ //XftDrawRect(xw.draw, fg, winx, winy + dc.font.ascent + 1, width, 1);
++ XFillRectangle(xw.dpy, XftDrawDrawable(xw.draw), ugc, winx,
++ winy + dc.font.ascent + 1, width, wlw);
++ } else if (base.ustyle == 3) {
++ int ww = win.cw;//width;
++ int wh = dc.font.descent - wlw/2 - 1;//r.height/7;
++ int wx = winx;
++ int wy = winy + win.ch - dc.font.descent;
++
++#if UNDERCURL_STYLE == UNDERCURL_CURLY
++ // Draw waves
++ int narcs = charlen * 2 + 1;
++ XArc *arcs = xmalloc(sizeof(XArc) * narcs);
++
++ int i = 0;
++ for (i = 0; i < charlen-1; i++) {
++ arcs[i*2] = (XArc) {
++ .x = wx + win.cw * i + ww / 4,
++ .y = wy,
++ .width = win.cw / 2,
++ .height = wh,
++ .angle1 = 0,
++ .angle2 = 180 * 64
++ };
++ arcs[i*2+1] = (XArc) {
++ .x = wx + win.cw * i + ww * 0.75,
++ .y = wy,
++ .width = win.cw/2,
++ .height = wh,
++ .angle1 = 180 * 64,
++ .angle2 = 180 * 64
++ };
++ }
++ // Last wave
++ arcs[i*2] = (XArc) {wx + ww * i + ww / 4, wy, ww / 2, wh,
++ 0, 180 * 64 };
++ // Last wave tail
++ arcs[i*2+1] = (XArc) {wx + ww * i + ww * 0.75, wy, ceil(ww / 2.),
++ wh, 180 * 64, 90 * 64};
++ // First wave tail
++ i++;
++ arcs[i*2] = (XArc) {wx - ww/4 - 1, wy, ceil(ww / 2.), wh, 270 * 64,
++ 90 * 64 };
++
++ XDrawArcs(xw.dpy, XftDrawDrawable(xw.draw), ugc, arcs, narcs);
++
++ free(arcs);
++#elif UNDERCURL_STYLE == UNDERCURL_SPIKY
++ // Make the underline corridor larger
++ /*
++ wy -= wh;
++ */
++ wh *= 2;
++
++ // Set the angle of the slope to 45°
++ ww = wh;
++
++ // Position of wave is independent of word, it's absolute
++ wx = (wx / (ww/2)) * (ww/2);
++
++ int marginStart = winx - wx;
++
++ // Calculate number of points with floating precision
++ float n = width; // Width of word in pixels
++ n = (n / ww) * 2; // Number of slopes (/ or \)
++ n += 2; // Add two last points
++ int npoints = n; // Convert to int
++
++ // Total length of underline
++ float waveLength = 0;
++
++ if (npoints >= 3) {
++ // We add an aditional slot in case we use a bonus point
++ XPoint *points = xmalloc(sizeof(XPoint) * (npoints + 1));
++
++ // First point (Starts with the word bounds)
++ points[0] = (XPoint) {
++ .x = wx + marginStart,
++ .y = (isSlopeRising(wx, 0, ww))
++ ? (wy - marginStart + ww/2.f)
++ : (wy + marginStart)
++ };
++
++ // Second point (Goes back to the absolute point coordinates)
++ points[1] = (XPoint) {
++ .x = (ww/2.f) - marginStart,
++ .y = (isSlopeRising(wx, 1, ww))
++ ? (ww/2.f - marginStart)
++ : (-ww/2.f + marginStart)
++ };
++ waveLength += (ww/2.f) - marginStart;
++
++ // The rest of the points
++ for (int i = 2; i < npoints-1; i++) {
++ points[i] = (XPoint) {
++ .x = ww/2,
++ .y = (isSlopeRising(wx, i, ww))
++ ? wh/2
++ : -wh/2
++ };
++ waveLength += ww/2;
++ }
++
++ // Last point
++ points[npoints-1] = (XPoint) {
++ .x = ww/2,
++ .y = (isSlopeRising(wx, npoints-1, ww))
++ ? wh/2
++ : -wh/2
++ };
++ waveLength += ww/2;
++
++ // End
++ if (waveLength < width) { // Add a bonus point?
++ int marginEnd = width - waveLength;
++ points[npoints] = (XPoint) {
++ .x = marginEnd,
++ .y = (isSlopeRising(wx, npoints, ww))
++ ? (marginEnd)
++ : (-marginEnd)
++ };
++
++ npoints++;
++ } else if (waveLength > width) { // Is last point too far?
++ int marginEnd = waveLength - width;
++ points[npoints-1].x -= marginEnd;
++ if (isSlopeRising(wx, npoints-1, ww))
++ points[npoints-1].y -= (marginEnd);
++ else
++ points[npoints-1].y += (marginEnd);
++ }
++
++ // Draw the lines
++ XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, npoints,
++ CoordModePrevious);
++
++ // Draw a second underline with an offset of 1 pixel
++ if ( ((win.ch / (widthThreshold/2)) % 2)) {
++ points[0].x++;
++
++ XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points,
++ npoints, CoordModePrevious);
++ }
++
++ // Free resources
++ free(points);
++ }
++#else // UNDERCURL_CAPPED
++ // Cap is half of wave width
++ float capRatio = 0.5f;
++
++ // Make the underline corridor larger
++ wh *= 2;
++
++ // Set the angle of the slope to 45°
++ ww = wh;
++ ww *= 1 + capRatio; // Add a bit of width for the cap
++
++ // Position of wave is independent of word, it's absolute
++ wx = (wx / ww) * ww;
++
++ float marginStart;
++ switch(getSlope(winx, 0, ww)) {
++ case UNDERCURL_SLOPE_ASCENDING:
++ marginStart = winx - wx;
++ break;
++ case UNDERCURL_SLOPE_TOP_CAP:
++ marginStart = winx - (wx + (ww * (2.f/6.f)));
++ break;
++ case UNDERCURL_SLOPE_DESCENDING:
++ marginStart = winx - (wx + (ww * (3.f/6.f)));
++ break;
++ case UNDERCURL_SLOPE_BOTTOM_CAP:
++ marginStart = winx - (wx + (ww * (5.f/6.f)));
++ break;
++ }
++
++ // Calculate number of points with floating precision
++ float n = width; // Width of word in pixels
++ // ._.
++ n = (n / ww) * 4; // Number of points (./ \.)
++ n += 2; // Add two last points
++ int npoints = n; // Convert to int
++
++ // Position of the pen to draw the lines
++ float penX = 0;
++ float penY = 0;
++
++ if (npoints >= 3) {
++ XPoint *points = xmalloc(sizeof(XPoint) * (npoints + 1));
++
++ // First point (Starts with the word bounds)
++ penX = winx;
++ switch (getSlope(winx, 0, ww)) {
++ case UNDERCURL_SLOPE_ASCENDING:
++ penY = wy + wh/2.f - marginStart;
++ break;
++ case UNDERCURL_SLOPE_TOP_CAP:
++ penY = wy;
++ break;
++ case UNDERCURL_SLOPE_DESCENDING:
++ penY = wy + marginStart;
++ break;
++ case UNDERCURL_SLOPE_BOTTOM_CAP:
++ penY = wy + wh/2.f;
++ break;
++ }
++ points[0].x = penX;
++ points[0].y = penY;
++
++ // Second point (Goes back to the absolute point coordinates)
++ switch (getSlope(winx, 1, ww)) {
++ case UNDERCURL_SLOPE_ASCENDING:
++ penX += ww * (1.f/6.f) - marginStart;
++ penY += 0;
++ break;
++ case UNDERCURL_SLOPE_TOP_CAP:
++ penX += ww * (2.f/6.f) - marginStart;
++ penY += -wh/2.f + marginStart;
++ break;
++ case UNDERCURL_SLOPE_DESCENDING:
++ penX += ww * (1.f/6.f) - marginStart;
++ penY += 0;
++ break;
++ case UNDERCURL_SLOPE_BOTTOM_CAP:
++ penX += ww * (2.f/6.f) - marginStart;
++ penY += -marginStart + wh/2.f;
++ break;
++ }
++ points[1].x = penX;
++ points[1].y = penY;
++
++ // The rest of the points
++ for (int i = 2; i < npoints; i++) {
++ switch (getSlope(winx, i, ww)) {
++ case UNDERCURL_SLOPE_ASCENDING:
++ case UNDERCURL_SLOPE_DESCENDING:
++ penX += ww * (1.f/6.f);
++ penY += 0;
++ break;
++ case UNDERCURL_SLOPE_TOP_CAP:
++ penX += ww * (2.f/6.f);
++ penY += -wh / 2.f;
++ break;
++ case UNDERCURL_SLOPE_BOTTOM_CAP:
++ penX += ww * (2.f/6.f);
++ penY += wh / 2.f;
++ break;
++ }
++ points[i].x = penX;
++ points[i].y = penY;
++ }
++
++ // End
++ float waveLength = penX - winx;
++ if (waveLength < width) { // Add a bonus point?
++ int marginEnd = width - waveLength;
++ penX += marginEnd;
++ switch(getSlope(winx, npoints, ww)) {
++ case UNDERCURL_SLOPE_ASCENDING:
++ case UNDERCURL_SLOPE_DESCENDING:
++ //penY += 0;
++ break;
++ case UNDERCURL_SLOPE_TOP_CAP:
++ penY += -marginEnd;
++ break;
++ case UNDERCURL_SLOPE_BOTTOM_CAP:
++ penY += marginEnd;
++ break;
++ }
++
++ points[npoints].x = penX;
++ points[npoints].y = penY;
++
++ npoints++;
++ } else if (waveLength > width) { // Is last point too far?
++ int marginEnd = waveLength - width;
++ points[npoints-1].x -= marginEnd;
++ switch(getSlope(winx, npoints-1, ww)) {
++ case UNDERCURL_SLOPE_TOP_CAP:
++ points[npoints-1].y += marginEnd;
++ break;
++ case UNDERCURL_SLOPE_BOTTOM_CAP:
++ points[npoints-1].y -= marginEnd;
++ break;
++ default:
++ break;
++ }
++ }
++
++ // Draw the lines
++ XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points, npoints,
++ CoordModeOrigin);
++
++ // Draw a second underline with an offset of 1 pixel
++ if ( ((win.ch / (widthThreshold/2)) % 2)) {
++ for (int i = 0; i < npoints; i++)
++ points[i].x++;
++
++ XDrawLines(xw.dpy, XftDrawDrawable(xw.draw), ugc, points,
++ npoints, CoordModeOrigin);
++ }
++
++ // Free resources
++ free(points);
++ }
++#endif
++ }
++
++ XFreeGC(xw.dpy, ugc);
+ }
+
+ if (base.mode & ATTR_STRUCK) {
diff --git a/st/unpatched/st-universcroll-0.8.4.diff b/st/unpatched/st-universcroll-0.8.4.diff
new file mode 100644
index 0000000..6a33813
--- /dev/null
+++ b/st/unpatched/st-universcroll-0.8.4.diff
@@ -0,0 +1,90 @@
+From 9726b1e58352126252412e101432e64d46fc51ca Mon Sep 17 00:00:00 2001
+From: Dennis Lee <dennis@dennislee.xyz>
+Date: Sun, 28 Jun 2020 23:01:03 -0700
+Subject: [PATCH] universcroll: mouse wheel only scroll in all modes
+
+Scroll normally via scroll(1), without Shift, when outside of
+`MODE_ALTSCREEN`. Inside an alt screen, continue to scroll normally
+without Shift; in this mode, your scrolling is automatically translated
+into ^Y and ^E. It just werks!
+
+Based on the existing mouse-altscreen patch
+https://st.suckless.org/patches/scrollback/
+adapted for st(1) 0.8.4 and scroll(1).
+---
+ config.def.h | 10 +++++-----
+ st.c | 5 +++++
+ st.h | 1 +
+ x.c | 2 ++
+ 4 files changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index 6f05dce..62e87da 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -173,11 +173,11 @@ static uint forcemousemod = ShiftMask;
+ * Beware that overloading Button1 will disable the selection.
+ */
+ static MouseShortcut mshortcuts[] = {
+- /* mask button function argument release */
+- { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
+- { ShiftMask, Button4, ttysend, {.s = "\033[5;2~"} },
++ /* mask button function argument release alt */
++ { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
++ { XK_ANY_MOD, Button4, ttysend, {.s = "\033[5;2~"}, 0, -1 },
+ { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
+- { ShiftMask, Button5, ttysend, {.s = "\033[6;2~"} },
++ { XK_ANY_MOD, Button5, ttysend, {.s = "\033[6;2~"}, 0, -1 },
+ { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
+ };
+
+diff --git a/st.c b/st.c
+index 76b7e0d..1f65453 100644
+--- a/st.c
++++ b/st.c
+@@ -1047,6 +1047,11 @@ tnew(int col, int row)
+ treset();
+ }
+
++int tisaltscr(void)
++{
++ return IS_SET(MODE_ALTSCREEN);
++}
++
+ void
+ tswapscreen(void)
+ {
+diff --git a/st.h b/st.h
+index 3d351b6..39cc054 100644
+--- a/st.h
++++ b/st.h
+@@ -87,6 +87,7 @@ void sendbreak(const Arg *);
+ void toggleprinter(const Arg *);
+
+ int tattrset(int);
++int tisaltscr(void);
+ void tnew(int, int);
+ void tresize(int, int);
+ void tsetdirtattr(int);
+diff --git a/x.c b/x.c
+index 210f184..210dde9 100644
+--- a/x.c
++++ b/x.c
+@@ -34,6 +34,7 @@ typedef struct {
+ void (*func)(const Arg *);
+ const Arg arg;
+ uint release;
++ int altscrn; /* 0: don't care, -1: not alt screen, 1: alt screen */
+ } MouseShortcut;
+
+ typedef struct {
+@@ -446,6 +447,7 @@ mouseaction(XEvent *e, uint release)
+ for (ms = mshortcuts; ms < mshortcuts + LEN(mshortcuts); ms++) {
+ if (ms->release == release &&
+ ms->button == e->xbutton.button &&
++ (!ms->altscrn || (ms->altscrn == (tisaltscr() ? 1 : -1))) &&
+ (match(ms->mod, state) || /* exact or forced */
+ match(ms->mod, state & ~forcemousemod))) {
+ ms->func(&(ms->arg));
+--
+2.27.0
diff --git a/st/unpatched/st-universcroll-example-0.8.4.diff b/st/unpatched/st-universcroll-example-0.8.4.diff
new file mode 100644
index 0000000..76ff70d
--- /dev/null
+++ b/st/unpatched/st-universcroll-example-0.8.4.diff
@@ -0,0 +1,47 @@
+From 59d2c9b65f90f78507b88d773323aab31194b7b4 Mon Sep 17 00:00:00 2001
+From: Dennis Lee <dennis@dennislee.xyz>
+Date: Mon, 29 Jun 2020 21:33:08 -0700
+Subject: [PATCH] universcroll: sane default configuration
+
+- Set scroll program = "scroll"
+- Mouse wheel scroll only with NO_MOD.
+- Mouse wheel zoom with ShiftMask/ANY_MOD.
+---
+ config.def.h | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/config.def.h b/config.def.h
+index a52c0a2..74fd64c 100644
+--- a/config.def.h
++++ b/config.def.h
+@@ -19,7 +19,7 @@ static int borderpx = 2;
+ static char *shell = "/bin/sh";
+ char *utmp = NULL;
+ /* scroll program: to enable use a string like "scroll" */
+-char *scroll = NULL;
++char *scroll = "scroll";
+ char *stty_args = "stty raw pass8 nl -echo -iexten -cstopb 38400";
+
+ /* identification sequence returned in DA and DECID */
+@@ -175,10 +175,14 @@ static uint forcemousemod = ShiftMask;
+ static MouseShortcut mshortcuts[] = {
+ /* mask button function argument release alt */
+ { XK_ANY_MOD, Button2, selpaste, {.i = 0}, 1 },
+- { XK_ANY_MOD, Button4, ttysend, {.s = "\033[5;2~"}, 0, -1 },
+- { XK_ANY_MOD, Button4, ttysend, {.s = "\031"} },
+- { XK_ANY_MOD, Button5, ttysend, {.s = "\033[6;2~"}, 0, -1 },
+- { XK_ANY_MOD, Button5, ttysend, {.s = "\005"} },
++ { ShiftMask, Button4, zoom, {.f = +1} },
++ { ShiftMask, Button5, zoom, {.f = -1} },
++ { XK_NO_MOD, Button4, ttysend, {.s = "\033[5;2~"}, 0, -1 },
++ { XK_NO_MOD, Button4, ttysend, {.s = "\031"} },
++ { XK_NO_MOD, Button5, ttysend, {.s = "\033[6;2~"}, 0, -1 },
++ { XK_NO_MOD, Button5, ttysend, {.s = "\005"} },
++ { XK_ANY_MOD, Button4, zoom, {.f = +1} },
++ { XK_ANY_MOD, Button5, zoom, {.f = -1} },
+ };
+
+ /* Internal keyboard shortcuts. */
+--
+2.27.0
+