diff options
Diffstat (limited to 'patches')
| -rwxr-xr-x | patches/st-alpha-20240814-a0274bc.diff | 129 | ||||
| -rwxr-xr-x | patches/st-anysize-20220718-baa9357.diff | 164 | ||||
| -rw-r--r-- | patches/st-csi_22_23-0.8.5.diff | 208 | ||||
| -rw-r--r-- | patches/st-desktopentry-0.8.5.diff | 68 | ||||
| -rw-r--r-- | patches/st-dynamic-cursor-color-0.9.diff | 50 | ||||
| -rw-r--r-- | patches/st-font2-0.8.5.diff | 163 | ||||
| -rwxr-xr-x | patches/st-ligatures-20241226-0.9.2.diff | 650 | ||||
| -rwxr-xr-x | patches/st-scrollback-0.9.2.diff | 351 |
8 files changed, 1783 insertions, 0 deletions
diff --git a/patches/st-alpha-20240814-a0274bc.diff b/patches/st-alpha-20240814-a0274bc.diff new file mode 100755 index 0000000..6913d19 --- /dev/null +++ b/patches/st-alpha-20240814-a0274bc.diff @@ -0,0 +1,129 @@ +diff --git a/config.def.h b/config.def.h +index 2cd740a..019a4e1 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -93,6 +93,9 @@ char *termname = "st-256color"; + */ + unsigned int tabspaces = 8; + ++/* bg opacity */ ++float alpha = 0.8; ++ + /* Terminal colors (16 first used in escape sequence) */ + static const char *colorname[] = { + /* 8 normal colors */ +diff --git a/x.c b/x.c +index d73152b..f32fd6c 100644 +--- a/x.c ++++ b/x.c +@@ -105,6 +105,7 @@ typedef struct { + XSetWindowAttributes attrs; + int scr; + int isfixed; /* is fixed geometry? */ ++ int depth; /* bit depth */ + int l, t; /* left and top offset */ + int gm; /* geometry mask */ + } XWindow; +@@ -752,7 +753,7 @@ xresize(int col, int row) + + XFreePixmap(xw.dpy, xw.buf); + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.depth); + XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, win.w, win.h); + +@@ -812,6 +813,10 @@ xloadcols(void) + else + die("could not allocate color %d\n", i); + } ++ ++ dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); ++ dc.col[defaultbg].pixel &= 0x00FFFFFF; ++ dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; + loaded = 1; + } + +@@ -842,6 +847,12 @@ xsetcolorname(int x, const char *name) + XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); + dc.col[x] = ncolor; + ++ if (x == defaultbg) { ++ dc.col[defaultbg].color.alpha = (unsigned short)(0xffff * alpha); ++ dc.col[defaultbg].pixel &= 0x00FFFFFF; ++ dc.col[defaultbg].pixel |= (unsigned char)(0xff * alpha) << 24; ++ } ++ + return 0; + } + +@@ -1134,11 +1145,25 @@ xinit(int cols, int rows) + Window parent, root; + pid_t thispid = getpid(); + XColor xmousefg, xmousebg; ++ XWindowAttributes attr; ++ XVisualInfo vis; + + if (!(xw.dpy = XOpenDisplay(NULL))) + die("can't open display\n"); + xw.scr = XDefaultScreen(xw.dpy); +- xw.vis = XDefaultVisual(xw.dpy, xw.scr); ++ ++ root = XRootWindow(xw.dpy, xw.scr); ++ if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) ++ parent = root; ++ ++ if (XMatchVisualInfo(xw.dpy, xw.scr, 32, TrueColor, &vis) != 0) { ++ xw.vis = vis.visual; ++ xw.depth = vis.depth; ++ } else { ++ XGetWindowAttributes(xw.dpy, parent, &attr); ++ xw.vis = attr.visual; ++ xw.depth = attr.depth; ++ } + + /* font */ + if (!FcInit()) +@@ -1148,7 +1173,7 @@ xinit(int cols, int rows) + xloadfonts(usedfont, 0); + + /* colors */ +- xw.cmap = XDefaultColormap(xw.dpy, xw.scr); ++ xw.cmap = XCreateColormap(xw.dpy, parent, xw.vis, None); + xloadcols(); + + /* adjust fixed window geometry */ +@@ -1168,11 +1193,8 @@ xinit(int cols, int rows) + | ButtonMotionMask | ButtonPressMask | ButtonReleaseMask; + xw.attrs.colormap = xw.cmap; + +- root = XRootWindow(xw.dpy, xw.scr); +- if (!(opt_embed && (parent = strtol(opt_embed, NULL, 0)))) +- parent = root; +- xw.win = XCreateWindow(xw.dpy, root, xw.l, xw.t, +- win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput, ++ xw.win = XCreateWindow(xw.dpy, parent, xw.l, xw.t, ++ win.w, win.h, 0, xw.depth, InputOutput, + xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity + | CWEventMask | CWColormap, &xw.attrs); + if (parent != root) +@@ -1183,7 +1205,7 @@ xinit(int cols, int rows) + dc.gc = XCreateGC(xw.dpy, xw.win, GCGraphicsExposures, + &gcvalues); + xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, +- DefaultDepth(xw.dpy, xw.scr)); ++ xw.depth); + XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); + XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); + +@@ -2047,6 +2069,10 @@ main(int argc, char *argv[]) + case 'a': + allowaltscreen = 0; + break; ++ case 'A': ++ alpha = strtof(EARGF(usage()), NULL); ++ LIMIT(alpha, 0.0, 1.0); ++ break; + case 'c': + opt_class = EARGF(usage()); + break; diff --git a/patches/st-anysize-20220718-baa9357.diff b/patches/st-anysize-20220718-baa9357.diff new file mode 100755 index 0000000..675ffdf --- /dev/null +++ b/patches/st-anysize-20220718-baa9357.diff @@ -0,0 +1,164 @@ +From 8dcdc4b21a73268e167d98aa30f24315c7f3b7ff Mon Sep 17 00:00:00 2001 +From: Bakkeby <bakkeby@gmail.com> +Date: Mon, 18 Jul 2022 16:52:03 +0200 +Subject: [PATCH] Adding anysize patch + +--- + x.c | 56 ++++++++++++++++++++++++++++++-------------------------- + 1 file changed, 30 insertions(+), 26 deletions(-) + +diff --git a/x.c b/x.c +index 2a3bd38..f534347 100644 +--- a/x.c ++++ b/x.c +@@ -81,6 +81,7 @@ typedef XftGlyphFontSpec GlyphFontSpec; + typedef struct { + int tw, th; /* tty width and height */ + int w, h; /* window width and height */ ++ int hborderpx, vborderpx; + int ch; /* char height */ + int cw; /* char width */ + int mode; /* window state/mode flags */ +@@ -331,7 +332,7 @@ ttysend(const Arg *arg) + int + evcol(XEvent *e) + { +- int x = e->xbutton.x - borderpx; ++ int x = e->xbutton.x - win.hborderpx; + LIMIT(x, 0, win.tw - 1); + return x / win.cw; + } +@@ -339,7 +340,7 @@ evcol(XEvent *e) + int + evrow(XEvent *e) + { +- int y = e->xbutton.y - borderpx; ++ int y = e->xbutton.y - win.vborderpx; + LIMIT(y, 0, win.th - 1); + return y / win.ch; + } +@@ -739,6 +740,9 @@ cresize(int width, int height) + col = MAX(1, col); + row = MAX(1, row); + ++ win.hborderpx = (win.w - col * win.cw) / 2; ++ win.vborderpx = (win.h - row * win.ch) / 2; ++ + tresize(col, row); + xresize(col, row); + ttyresize(win.tw, win.th); +@@ -869,8 +873,8 @@ xhints(void) + sizeh->flags = PSize | PResizeInc | PBaseSize | PMinSize; + sizeh->height = win.h; + sizeh->width = win.w; +- sizeh->height_inc = win.ch; +- sizeh->width_inc = win.cw; ++ sizeh->height_inc = 1; ++ sizeh->width_inc = 1; + sizeh->base_height = 2 * borderpx; + sizeh->base_width = 2 * borderpx; + sizeh->min_height = win.ch + 2 * borderpx; +@@ -1152,8 +1156,8 @@ xinit(int cols, int rows) + xloadcols(); + + /* adjust fixed window geometry */ +- win.w = 2 * borderpx + cols * win.cw; +- win.h = 2 * borderpx + rows * win.ch; ++ win.w = 2 * win.hborderpx + 2 * borderpx + cols * win.cw; ++ win.h = 2 * win.vborderpx + 2 * borderpx + rows * win.ch; + if (xw.gm & XNegative) + xw.l += DisplayWidth(xw.dpy, xw.scr) - win.w - 2; + if (xw.gm & YNegative) +@@ -1242,7 +1246,7 @@ xinit(int cols, int rows) + int + xmakeglyphfontspecs(XftGlyphFontSpec *specs, const Glyph *glyphs, int len, int x, int y) + { +- float winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, xp, yp; ++ float winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, xp, yp; + ushort mode, prevmode = USHRT_MAX; + Font *font = &dc.font; + int frcflags = FRC_NORMAL; +@@ -1375,7 +1379,7 @@ void + xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, int y) + { + int charlen = len * ((base.mode & ATTR_WIDE) ? 2 : 1); +- int winx = borderpx + x * win.cw, winy = borderpx + y * win.ch, ++ int winx = win.hborderpx + x * win.cw, winy = win.vborderpx + y * win.ch, + width = charlen * win.cw; + Color *fg, *bg, *temp, revfg, revbg, truefg, truebg; + XRenderColor colfg, colbg; +@@ -1465,17 +1469,17 @@ xdrawglyphfontspecs(const XftGlyphFontSpec *specs, Glyph base, int len, int x, i + + /* Intelligent cleaning up of the borders. */ + if (x == 0) { +- xclear(0, (y == 0)? 0 : winy, borderpx, ++ xclear(0, (y == 0)? 0 : winy, win.hborderpx, + winy + win.ch + +- ((winy + win.ch >= borderpx + win.th)? win.h : 0)); ++ ((winy + win.ch >= win.vborderpx + win.th)? win.h : 0)); + } +- if (winx + width >= borderpx + win.tw) { ++ if (winx + width >= win.hborderpx + win.tw) { + xclear(winx + width, (y == 0)? 0 : winy, win.w, +- ((winy + win.ch >= borderpx + win.th)? win.h : (winy + win.ch))); ++ ((winy + win.ch >= win.vborderpx + win.th)? win.h : (winy + win.ch))); + } + if (y == 0) +- xclear(winx, 0, winx + width, borderpx); +- if (winy + win.ch >= borderpx + win.th) ++ xclear(winx, 0, winx + width, win.vborderpx); ++ if (winy + win.ch >= win.vborderpx + win.th) + xclear(winx, winy + win.ch, winx + width, win.h); + + /* Clean up the region we want to draw to. */ +@@ -1569,35 +1573,35 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) + case 3: /* Blinking Underline */ + case 4: /* Steady Underline */ + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + (cy + 1) * win.ch - \ ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + (cy + 1) * win.ch - \ + cursorthickness, + win.cw, cursorthickness); + break; + case 5: /* Blinking bar */ + case 6: /* Steady bar */ + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + cy * win.ch, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + cy * win.ch, + cursorthickness, win.ch); + break; + } + } else { + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + cy * win.ch, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + cy * win.ch, + win.cw - 1, 1); + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + cy * win.ch, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, +- borderpx + (cx + 1) * win.cw - 1, +- borderpx + cy * win.ch, ++ win.hborderpx + (cx + 1) * win.cw - 1, ++ win.vborderpx + cy * win.ch, + 1, win.ch - 1); + XftDrawRect(xw.draw, &drawcol, +- borderpx + cx * win.cw, +- borderpx + (cy + 1) * win.ch - 1, ++ win.hborderpx + cx * win.cw, ++ win.vborderpx + (cy + 1) * win.ch - 1, + win.cw, 1); + } + } +-- +2.37.1 + diff --git a/patches/st-csi_22_23-0.8.5.diff b/patches/st-csi_22_23-0.8.5.diff new file mode 100644 index 0000000..c49aa30 --- /dev/null +++ b/patches/st-csi_22_23-0.8.5.diff @@ -0,0 +1,208 @@ +From c90af45228c1100377d64ad021fa3f0cff9a1df4 Mon Sep 17 00:00:00 2001 +From: wael <40663@protonmail.com> +Date: Mon, 11 Apr 2022 21:28:43 +0300 +Subject: [PATCH] [st][patch][csi 22 23] update to 0.8.5 + +--- + st.c | 36 ++++++++++++++++++++++++++++++++---- + st.info | 4 ++-- + win.h | 4 +++- + x.c | 41 ++++++++++++++++++++++++++++++++++++++--- + 4 files changed, 75 insertions(+), 10 deletions(-) + +diff --git a/st.c b/st.c +index f43cfd3..2802381 100644 +--- a/st.c ++++ b/st.c +@@ -1801,6 +1801,33 @@ csihandle(void) + goto unknown; + } + break; ++ case 't': /* title stack operations */ ++ switch (csiescseq.arg[0]) { ++ case 22: /* pust current title on stack */ ++ switch (csiescseq.arg[1]) { ++ case 0: ++ case 1: ++ case 2: ++ xpushtitle(); ++ break; ++ default: ++ goto unknown; ++ } ++ break; ++ case 23: /* pop last title from stack */ ++ switch (csiescseq.arg[1]) { ++ case 0: ++ case 1: ++ case 2: ++ xsettitle(NULL, 1); ++ break; ++ default: ++ goto unknown; ++ } ++ break; ++ default: ++ goto unknown; ++ } + } + } + +@@ -1885,7 +1912,7 @@ strhandle(void) + switch (par) { + case 0: + if (narg > 1) { +- xsettitle(strescseq.args[1]); ++ xsettitle(strescseq.args[1], 0); + xseticontitle(strescseq.args[1]); + } + return; +@@ -1895,7 +1922,7 @@ strhandle(void) + return; + case 2: + if (narg > 1) +- xsettitle(strescseq.args[1]); ++ xsettitle(strescseq.args[1], 0); + return; + case 52: + if (narg > 2 && allowwindowops) { +@@ -1973,7 +2000,7 @@ strhandle(void) + } + break; + case 'k': /* old title set compatibility */ +- xsettitle(strescseq.args[0]); ++ xsettitle(strescseq.args[0], 0); + return; + case 'P': /* DCS -- Device Control String */ + case '_': /* APC -- Application Program Command */ +@@ -2345,6 +2372,7 @@ eschandle(uchar ascii) + break; + case 'c': /* RIS -- Reset to initial state */ + treset(); ++ xfreetitlestack(); + resettitle(); + xloadcols(); + break; +@@ -2631,7 +2659,7 @@ tresize(int col, int row) + void + resettitle(void) + { +- xsettitle(NULL); ++ xsettitle(NULL, 0); + } + + void +diff --git a/st.info b/st.info +index 8201ad6..aeef606 100644 +--- a/st.info ++++ b/st.info +@@ -161,7 +161,7 @@ st-mono| simpleterm monocolor, + rin=\E[%p1%dT, + ritm=\E[23m, + rmacs=\E(B, +- rmcup=\E[?1049l, ++ rmcup=\E[?1049l\E[23;0;0t, + rmir=\E[4l, + rmkx=\E[?1l\E>, + rmso=\E[27m, +@@ -172,7 +172,7 @@ st-mono| simpleterm monocolor, + sitm=\E[3m, + sgr0=\E[0m, + smacs=\E(0, +- smcup=\E[?1049h, ++ smcup=\E[?1049h\E[22;0;0t, + smir=\E[4h, + smkx=\E[?1h\E=, + smso=\E[7m, +diff --git a/win.h b/win.h +index e6e4369..ef67fd6 100644 +--- a/win.h ++++ b/win.h +@@ -31,7 +31,9 @@ void xfinishdraw(void); + void xloadcols(void); + int xsetcolorname(int, const char *); + void xseticontitle(char *); +-void xsettitle(char *); ++void xfreetitlestack(void); ++void xsettitle(char *, int); ++void xpushtitle(void); + int xsetcursor(int); + void xsetmode(int, unsigned int); + void xsetpointermotion(int); +diff --git a/x.c b/x.c +index 2a3bd38..babb04c 100644 +--- a/x.c ++++ b/x.c +@@ -63,6 +63,9 @@ static void ttysend(const Arg *); + /* config.h for applying patches and the configuration. */ + #include "config.h" + ++/* size of title stack */ ++#define TITLESTACKSIZE 8 ++ + /* XEMBED messages */ + #define XEMBED_FOCUS_IN 4 + #define XEMBED_FOCUS_OUT 5 +@@ -220,6 +223,8 @@ static DC dc; + static XWindow xw; + static XSelection xsel; + static TermWindow win; ++static int tstki; /* title stack index */ ++static char *titlestack[TITLESTACKSIZE]; /* title stack */ + + /* Font Ring Cache */ + enum { +@@ -1626,10 +1631,30 @@ xseticontitle(char *p) + } + + void +-xsettitle(char *p) ++xfreetitlestack(void) + { +- XTextProperty prop; +- DEFAULT(p, opt_title); ++ for (int i = 0; i < LEN(titlestack); i++) { ++ free(titlestack[i]); ++ titlestack[i] = NULL; ++ } ++} ++ ++void ++xsettitle(char *p, int pop) ++{ ++ XTextProperty prop; ++ ++ free(titlestack[tstki]); ++ if (pop) { ++ titlestack[tstki] = NULL; ++ tstki = (tstki - 1 + TITLESTACKSIZE) % TITLESTACKSIZE; ++ p = titlestack[tstki] ? titlestack[tstki] : opt_title; ++ } else if (p) { ++ titlestack[tstki] = xstrdup(p); ++ } else { ++ titlestack[tstki] = NULL; ++ p = opt_title; ++ } + + if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, + &prop) != Success) +@@ -1639,6 +1664,16 @@ xsettitle(char *p) + XFree(prop.value); + } + ++void ++xpushtitle(void) ++{ ++ int tstkin = (tstki + 1) % TITLESTACKSIZE; ++ ++ free(titlestack[tstkin]); ++ titlestack[tstkin] = titlestack[tstki] ? xstrdup(titlestack[tstki]) : NULL; ++ tstki = tstkin; ++} ++ + int + xstartdraw(void) + { +-- +2.35.1 + diff --git a/patches/st-desktopentry-0.8.5.diff b/patches/st-desktopentry-0.8.5.diff new file mode 100644 index 0000000..1ed7426 --- /dev/null +++ b/patches/st-desktopentry-0.8.5.diff @@ -0,0 +1,68 @@ +From af28f9df9b0194311c25d60a22d1ecd98bfad2e7 Mon Sep 17 00:00:00 2001 +From: aleks <aleks.stier@icloud.com> +Date: Tue, 31 May 2022 00:33:38 +0200 +Subject: [PATCH] Create a desktop-entry for st + +Enables to find st in a graphical menu and to display it with a nice +icon. + +If some applications still are not displaying an icon for st try the patch +[netwmicon](../netwmicon/). Programs like tint2 and alttab rely on a hardcoded +icon which has to be stored by st in the \_NET\_WM\_ICON window-property. +--- + Makefile | 3 +++ + config.mk | 1 + + st.desktop | 12 ++++++++++++ + 3 files changed, 16 insertions(+) + create mode 100644 st.desktop + +diff --git a/Makefile b/Makefile +index 470ac86..2121877 100644 +--- a/Makefile ++++ b/Makefile +@@ -49,9 +49,12 @@ install: st + chmod 644 $(DESTDIR)$(MANPREFIX)/man1/st.1 + tic -sx st.info + @echo Please see the README file regarding the terminfo entry of st. ++ mkdir -p $(DESTDIR)$(APPPREFIX) ++ cp -f st.desktop $(DESTDIR)$(APPPREFIX) + + uninstall: + rm -f $(DESTDIR)$(PREFIX)/bin/st ++ rm -f $(DESTDIR)$(APPPREFIX)/st.desktop + rm -f $(DESTDIR)$(MANPREFIX)/man1/st.1 + + .PHONY: all options clean dist install uninstall +diff --git a/config.mk b/config.mk +index 4c4c5d5..b79c517 100644 +--- a/config.mk ++++ b/config.mk +@@ -5,6 +5,7 @@ VERSION = 0.8.5 + + # paths + PREFIX = /usr/local ++APPPREFIX = $(PREFIX)/share/applications + MANPREFIX = $(PREFIX)/share/man + + X11INC = /usr/X11R6/include +diff --git a/st.desktop b/st.desktop +new file mode 100644 +index 0000000..2d2b76f +--- /dev/null ++++ b/st.desktop +@@ -0,0 +1,12 @@ ++[Desktop Entry] ++Type=Application ++Exec=st ++TryExec=st ++Icon=utilities-terminal ++Terminal=false ++Categories=System;TerminalEmulator; ++ ++Name=st ++GenericName=Terminal ++Comment=st is a simple terminal implementation for X ++StartupWMClass=st-256color +-- +2.36.1 + diff --git a/patches/st-dynamic-cursor-color-0.9.diff b/patches/st-dynamic-cursor-color-0.9.diff new file mode 100644 index 0000000..1034595 --- /dev/null +++ b/patches/st-dynamic-cursor-color-0.9.diff @@ -0,0 +1,50 @@ +From 215ec30d6b5fe3319f88f1c9d16a37b6e14e5a53 Mon Sep 17 00:00:00 2001 +From: Bakkeby <bakkeby@gmail.com> +Date: Mon, 19 Dec 2022 10:20:47 +0100 +Subject: [PATCH] dynamic cursor color: cursor color taken from current + character + +--- + x.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/x.c b/x.c +index 2a3bd38..21aadce 100644 +--- a/x.c ++++ b/x.c +@@ -1520,6 +1520,7 @@ void + xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) + { + Color drawcol; ++ XRenderColor colbg; + + /* remove the old cursor */ + if (selected(ox, oy)) +@@ -1548,11 +1549,21 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Glyph og) + if (selected(cx, cy)) { + g.fg = defaultfg; + g.bg = defaultrcs; ++ } else if (!(og.mode & ATTR_REVERSE)) { ++ unsigned long col = g.bg; ++ g.bg = g.fg; ++ g.fg = col; ++ } ++ ++ if (IS_TRUECOL(g.bg)) { ++ colbg.alpha = 0xffff; ++ colbg.red = TRUERED(g.bg); ++ colbg.green = TRUEGREEN(g.bg); ++ colbg.blue = TRUEBLUE(g.bg); ++ XftColorAllocValue(xw.dpy, xw.vis, xw.cmap, &colbg, &drawcol); + } else { +- g.fg = defaultbg; +- g.bg = defaultcs; ++ drawcol = dc.col[g.bg]; + } +- drawcol = dc.col[g.bg]; + } + + /* draw the new one */ +-- +2.38.1 + diff --git a/patches/st-font2-0.8.5.diff b/patches/st-font2-0.8.5.diff new file mode 100644 index 0000000..9b22b8a --- /dev/null +++ b/patches/st-font2-0.8.5.diff @@ -0,0 +1,163 @@ +From 1635e04d3643dd4caa0c7c2043b585c6d7e4705f Mon Sep 17 00:00:00 2001 +From: Rizqi Nur Assyaufi <bandithijo@gmail.com> +Date: Mon, 18 Jul 2022 01:15:45 +0800 +Subject: [PATCH] [st][patch][font2] Add patch for st-0.8.5 + +--- + config.def.h | 6 +++ + x.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 107 insertions(+) + +diff --git a/config.def.h b/config.def.h +index 91ab8ca..717b2f0 100644 +--- a/config.def.h ++++ b/config.def.h +@@ -6,6 +6,12 @@ + * font: see http://freedesktop.org/software/fontconfig/fontconfig-user.html + */ + static char *font = "Liberation Mono:pixelsize=12:antialias=true:autohint=true"; ++/* Spare fonts */ ++static char *font2[] = { ++/* "Inconsolata for Powerline:pixelsize=12:antialias=true:autohint=true", */ ++/* "Hack Nerd Font Mono:pixelsize=11:antialias=true:autohint=true", */ ++}; ++ + static int borderpx = 2; + + /* +diff --git a/x.c b/x.c +index 8a16faa..220fc4f 100644 +--- a/x.c ++++ b/x.c +@@ -157,6 +157,8 @@ static void xhints(void); + static int xloadcolor(int, const char *, Color *); + static int xloadfont(Font *, FcPattern *); + static void xloadfonts(const char *, double); ++static int xloadsparefont(FcPattern *, int); ++static void xloadsparefonts(void); + static void xunloadfont(Font *); + static void xunloadfonts(void); + static void xsetenv(void); +@@ -306,6 +308,7 @@ zoomabs(const Arg *arg) + { + xunloadfonts(); + xloadfonts(usedfont, arg->f); ++ xloadsparefonts(); + cresize(0, 0); + redraw(); + xhints(); +@@ -1034,6 +1037,101 @@ xloadfonts(const char *fontstr, double fontsize) + FcPatternDestroy(pattern); + } + ++int ++xloadsparefont(FcPattern *pattern, int flags) ++{ ++ FcPattern *match; ++ FcResult result; ++ ++ match = FcFontMatch(NULL, pattern, &result); ++ if (!match) { ++ return 1; ++ } ++ ++ if (!(frc[frclen].font = XftFontOpenPattern(xw.dpy, match))) { ++ FcPatternDestroy(match); ++ return 1; ++ } ++ ++ frc[frclen].flags = flags; ++ /* Believe U+0000 glyph will present in each default font */ ++ frc[frclen].unicodep = 0; ++ frclen++; ++ ++ return 0; ++} ++ ++void ++xloadsparefonts(void) ++{ ++ FcPattern *pattern; ++ double sizeshift, fontval; ++ int fc; ++ char **fp; ++ ++ if (frclen != 0) ++ die("can't embed spare fonts. cache isn't empty"); ++ ++ /* Calculate count of spare fonts */ ++ fc = sizeof(font2) / sizeof(*font2); ++ if (fc == 0) ++ return; ++ ++ /* Allocate memory for cache entries. */ ++ if (frccap < 4 * fc) { ++ frccap += 4 * fc - frccap; ++ frc = xrealloc(frc, frccap * sizeof(Fontcache)); ++ } ++ ++ for (fp = font2; fp - font2 < fc; ++fp) { ++ ++ if (**fp == '-') ++ pattern = XftXlfdParse(*fp, False, False); ++ else ++ pattern = FcNameParse((FcChar8 *)*fp); ++ ++ if (!pattern) ++ die("can't open spare font %s\n", *fp); ++ ++ if (defaultfontsize > 0) { ++ sizeshift = usedfontsize - defaultfontsize; ++ if (sizeshift != 0 && ++ FcPatternGetDouble(pattern, FC_PIXEL_SIZE, 0, &fontval) == ++ FcResultMatch) { ++ fontval += sizeshift; ++ FcPatternDel(pattern, FC_PIXEL_SIZE); ++ FcPatternDel(pattern, FC_SIZE); ++ FcPatternAddDouble(pattern, FC_PIXEL_SIZE, fontval); ++ } ++ } ++ ++ FcPatternAddBool(pattern, FC_SCALABLE, 1); ++ ++ FcConfigSubstitute(NULL, pattern, FcMatchPattern); ++ XftDefaultSubstitute(xw.dpy, xw.scr, pattern); ++ ++ if (xloadsparefont(pattern, FRC_NORMAL)) ++ die("can't open spare font %s\n", *fp); ++ ++ FcPatternDel(pattern, FC_SLANT); ++ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC); ++ if (xloadsparefont(pattern, FRC_ITALIC)) ++ die("can't open spare font %s\n", *fp); ++ ++ FcPatternDel(pattern, FC_WEIGHT); ++ FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD); ++ if (xloadsparefont(pattern, FRC_ITALICBOLD)) ++ die("can't open spare font %s\n", *fp); ++ ++ FcPatternDel(pattern, FC_SLANT); ++ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN); ++ if (xloadsparefont(pattern, FRC_BOLD)) ++ die("can't open spare font %s\n", *fp); ++ ++ FcPatternDestroy(pattern); ++ } ++} ++ + void + xunloadfont(Font *f) + { +@@ -1131,6 +1229,9 @@ xinit(int cols, int rows) + usedfont = (opt_font == NULL)? font : opt_font; + xloadfonts(usedfont, 0); + ++ /* spare fonts */ ++ xloadsparefonts(); ++ + /* colors */ + xw.cmap = XDefaultColormap(xw.dpy, xw.scr); + xloadcols(); +-- +2.37.1 + diff --git a/patches/st-ligatures-20241226-0.9.2.diff b/patches/st-ligatures-20241226-0.9.2.diff new file mode 100755 index 0000000..698516f --- /dev/null +++ b/patches/st-ligatures-20241226-0.9.2.diff @@ -0,0 +1,650 @@ +diff --git a/Makefile b/Makefile +index 15db421..dfcea0f 100644 +--- a/Makefile ++++ b/Makefile +@@ -3,9 +3,9 @@ + .POSIX: + + include config.mk + +-SRC = st.c x.c ++SRC = st.c x.c hb.c + OBJ = $(SRC:.c=.o) + + all: st + +@@ -15,9 +15,10 @@ config.h: + .c.o: + $(CC) $(STCFLAGS) -c $< + + st.o: config.h st.h win.h +-x.o: arg.h config.h st.h win.h ++x.o: arg.h config.h st.h win.h hb.h ++hb.o: st.h + + $(OBJ): config.h config.mk + + st: $(OBJ) +diff --git a/config.mk b/config.mk +index fdc29a7..6833b3b 100644 +--- a/config.mk ++++ b/config.mk +@@ -14,12 +14,14 @@ PKG_CONFIG = pkg-config + + # includes and libs + INCS = -I$(X11INC) \ + `$(PKG_CONFIG) --cflags fontconfig` \ +- `$(PKG_CONFIG) --cflags freetype2` ++ `$(PKG_CONFIG) --cflags freetype2` \ ++ `$(PKG_CONFIG) --cflags harfbuzz` + LIBS = -L$(X11LIB) -lm -lrt -lX11 -lutil -lXft \ + `$(PKG_CONFIG) --libs fontconfig` \ +- `$(PKG_CONFIG) --libs freetype2` ++ `$(PKG_CONFIG) --libs freetype2` \ ++ `$(PKG_CONFIG) --libs harfbuzz` + + # flags + STCPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 + STCFLAGS = $(INCS) $(STCPPFLAGS) $(CPPFLAGS) $(CFLAGS) +@@ -28,9 +30,10 @@ STLDFLAGS = $(LIBS) $(LDFLAGS) + # OpenBSD: + #CPPFLAGS = -DVERSION=\"$(VERSION)\" -D_XOPEN_SOURCE=600 -D_BSD_SOURCE + #LIBS = -L$(X11LIB) -lm -lX11 -lutil -lXft \ + # `$(PKG_CONFIG) --libs fontconfig` \ +-# `$(PKG_CONFIG) --libs freetype2` ++# `$(PKG_CONFIG) --libs freetype2` \ ++# `$(PKG_CONFIG) --libs harfbuzz` + #MANPREFIX = ${PREFIX}/man + + # compiler and linker + # CC = c99 +diff --git a/hb.c b/hb.c +new file mode 100644 +index 0000000..99412c8 +--- /dev/null ++++ b/hb.c +@@ -0,0 +1,125 @@ ++#include <stdlib.h> ++#include <stdio.h> ++#include <math.h> ++#include <X11/Xft/Xft.h> ++#include <X11/cursorfont.h> ++#include <hb.h> ++#include <hb-ft.h> ++ ++#include "st.h" ++#include "hb.h" ++ ++#define FEATURE(c1,c2,c3,c4) { .tag = HB_TAG(c1,c2,c3,c4), .value = 1, .start = HB_FEATURE_GLOBAL_START, .end = HB_FEATURE_GLOBAL_END } ++#define BUFFER_STEP 256 ++ ++hb_font_t *hbfindfont(XftFont *match); ++ ++typedef struct { ++ XftFont *match; ++ hb_font_t *font; ++} HbFontMatch; ++ ++typedef struct { ++ size_t capacity; ++ HbFontMatch *fonts; ++} HbFontCache; ++ ++static HbFontCache hbfontcache = { 0, NULL }; ++ ++typedef struct { ++ size_t capacity; ++ Rune *runes; ++} RuneBuffer; ++ ++static RuneBuffer hbrunebuffer = { 0, NULL }; ++ ++/* ++ * Poplulate the array with a list of font features, wrapped in FEATURE macro, ++ * e. g. ++ * FEATURE('c', 'a', 'l', 't'), FEATURE('d', 'l', 'i', 'g') ++ */ ++hb_feature_t features[] = { }; ++ ++void ++hbunloadfonts() ++{ ++ for (int i = 0; i < hbfontcache.capacity; i++) { ++ hb_font_destroy(hbfontcache.fonts[i].font); ++ XftUnlockFace(hbfontcache.fonts[i].match); ++ } ++ ++ if (hbfontcache.fonts != NULL) { ++ free(hbfontcache.fonts); ++ hbfontcache.fonts = NULL; ++ } ++ hbfontcache.capacity = 0; ++} ++ ++hb_font_t * ++hbfindfont(XftFont *match) ++{ ++ for (int i = 0; i < hbfontcache.capacity; i++) { ++ if (hbfontcache.fonts[i].match == match) ++ return hbfontcache.fonts[i].font; ++ } ++ ++ /* Font not found in cache, caching it now. */ ++ hbfontcache.fonts = realloc(hbfontcache.fonts, sizeof(HbFontMatch) * (hbfontcache.capacity + 1)); ++ FT_Face face = XftLockFace(match); ++ hb_font_t *font = hb_ft_font_create(face, NULL); ++ if (font == NULL) ++ die("Failed to load Harfbuzz font."); ++ ++ hbfontcache.fonts[hbfontcache.capacity].match = match; ++ hbfontcache.fonts[hbfontcache.capacity].font = font; ++ hbfontcache.capacity += 1; ++ ++ return font; ++} ++ ++void hbtransform(HbTransformData *data, XftFont *xfont, const Glyph *glyphs, int start, int length) { ++ ushort mode = USHRT_MAX; ++ unsigned int glyph_count; ++ int rune_idx, glyph_idx, end = start + length; ++ ++ hb_font_t *font = hbfindfont(xfont); ++ if (font == NULL) ++ return; ++ ++ hb_buffer_t *buffer = hb_buffer_create(); ++ hb_buffer_set_direction(buffer, HB_DIRECTION_LTR); ++ hb_buffer_set_cluster_level(buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); ++ ++ /* Resize the buffer if required length is larger. */ ++ if (hbrunebuffer.capacity < length) { ++ hbrunebuffer.capacity = (length / BUFFER_STEP + 1) * BUFFER_STEP; ++ hbrunebuffer.runes = realloc(hbrunebuffer.runes, hbrunebuffer.capacity * sizeof(Rune)); ++ } ++ ++ /* Fill buffer with codepoints. */ ++ for (rune_idx = 0, glyph_idx = start; glyph_idx < end; glyph_idx++, rune_idx++) { ++ hbrunebuffer.runes[rune_idx] = glyphs[glyph_idx].u; ++ mode = glyphs[glyph_idx].mode; ++ if (mode & ATTR_WDUMMY) ++ hbrunebuffer.runes[rune_idx] = 0x0020; ++ } ++ hb_buffer_add_codepoints(buffer, hbrunebuffer.runes, length, 0, length); ++ ++ /* Shape the segment. */ ++ hb_shape(font, buffer, features, sizeof(features)/sizeof(hb_feature_t)); ++ ++ /* Get new glyph info. */ ++ hb_glyph_info_t *info = hb_buffer_get_glyph_infos(buffer, &glyph_count); ++ hb_glyph_position_t *pos = hb_buffer_get_glyph_positions(buffer, &glyph_count); ++ ++ /* Fill the output. */ ++ data->buffer = buffer; ++ data->glyphs = info; ++ data->positions = pos; ++ data->count = glyph_count; ++} ++ ++void hbcleanup(HbTransformData *data) { ++ hb_buffer_destroy(data->buffer); ++ memset(data, 0, sizeof(HbTransformData)); ++} +diff --git a/hb.h b/hb.h +new file mode 100644 +index 0000000..3b0ef44 +--- /dev/null ++++ b/hb.h +@@ -0,0 +1,14 @@ ++#include <X11/Xft/Xft.h> ++#include <hb.h> ++#include <hb-ft.h> ++ ++typedef struct { ++ hb_buffer_t *buffer; ++ hb_glyph_info_t *glyphs; ++ hb_glyph_position_t *positions; ++ unsigned int count; ++} HbTransformData; ++ ++void hbunloadfonts(); ++void hbtransform(HbTransformData *, XftFont *, const Glyph *, int, int); ++void hbcleanup(HbTransformData *); +diff --git a/st.c b/st.c +index b9f66e7..da33a85 100644 +--- a/st.c ++++ b/st.c +@@ -2658,9 +2658,10 @@ draw(void) + cx--; + + drawregion(0, 0, term.col, term.row); + xdrawcursor(cx, term.c.y, term.line[term.c.y][cx], +- term.ocx, term.ocy, term.line[term.ocy][term.ocx]); ++ term.ocx, term.ocy, term.line[term.ocy][term.ocx], ++ term.line[term.ocy], term.col); + term.ocx = cx; + term.ocy = term.c.y; + xfinishdraw(); + if (ocx != term.ocx || ocy != term.ocy) +diff --git a/st.h b/st.h +index fd3b0d8..142fdfe 100644 +--- a/st.h ++++ b/st.h +@@ -10,9 +10,10 @@ + #define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) + #define DIVCEIL(n, d) (((n) + ((d) - 1)) / (d)) + #define DEFAULT(a, b) (a) = (a) ? (a) : (b) + #define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) +-#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \ ++#define ATTRCMP(a, b) (((a).mode & (~ATTR_WRAP)) != ((b).mode & (~ATTR_WRAP)) || \ ++ (a).fg != (b).fg || \ + (a).bg != (b).bg) + #define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ + (t1.tv_nsec-t2.tv_nsec)/1E6) + #define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) +diff --git a/win.h b/win.h +index 6de960d..94679e4 100644 +--- a/win.h ++++ b/win.h +@@ -24,9 +24,9 @@ enum win_mode { + }; + + void xbell(void); + void xclipcopy(void); +-void xdrawcursor(int, int, Glyph, int, int, Glyph); ++void xdrawcursor(int, int, Glyph, int, int, Glyph, Line, int); + void xdrawline(Line, int, int, int); + void xfinishdraw(void); + void xloadcols(void); + int xsetcolorname(int, const char *); +diff --git a/x.c b/x.c +index bd23686..2bf3b72 100644 +--- a/x.c ++++ b/x.c +@@ -18,8 +18,9 @@ + char *argv0; + #include "arg.h" + #include "st.h" + #include "win.h" ++#include "hb.h" + + /* types used in config.h */ + typedef struct { + uint mod; +@@ -140,10 +141,11 @@ typedef struct { + GC gc; + } DC; + + static inline ushort sixd_to_16bit(int); ++static void xresetfontsettings(ushort mode, Font **font, int *frcflags); + static int xmakeglyphfontspecs(XftGlyphFontSpec *, const Glyph *, int, int, int); +-static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int); ++static void xdrawglyphfontspecs(const XftGlyphFontSpec *, Glyph, int, int, int, int); + static void xdrawglyph(Glyph, int, int); + static void xclear(int, int, int, int); + static int xgeommasktogravity(int); + static int ximopen(Display *); +@@ -756,9 +758,9 @@ xresize(int col, int row) + XftDrawChange(xw.draw, xw.buf); + xclear(0, 0, win.w, win.h); + + /* resize to new width */ +- xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec)); ++ xw.specbuf = xrealloc(xw.specbuf, col * sizeof(GlyphFontSpec) * 4); + } + + ushort + sixd_to_16bit(int x) +@@ -1061,8 +1063,11 @@ xunloadfont(Font *f) + + void + xunloadfonts(void) + { ++ /* Clear Harfbuzz font cache. */ ++ hbunloadfonts(); ++ + /* Free the loaded fonts in the font cache. */ + while (frclen > 0) + XftFontClose(xw.dpy, frc[--frclen].font); + +@@ -1184,9 +1189,9 @@ xinit(int cols, int rows) + XSetForeground(xw |
