tMerge remote-tracking branch 'upstream/master' - st - [fork] customized build … | |
git clone git://src.adamsgaard.dk/st | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 8d971068c60f64dee3e8751b54548d86f6fecd6f | |
parent 643585f3d771e48023ce469a5cd4e1a848c84e18 | |
Author: Anders Damsgaard <[email protected]> | |
Date: Fri, 19 Jun 2020 13:47:33 +0200 | |
Merge remote-tracking branch 'upstream/master' | |
Diffstat: | |
M FAQ | 59 ++++++++++++++++++++++++++++-… | |
M LICENSE | 2 +- | |
M config.def.h | 4 ++++ | |
M config.mk | 6 +++--- | |
M st.c | 42 +++++++++++++----------------… | |
M st.h | 1 + | |
M st.info | 2 ++ | |
M x.c | 9 ++++----- | |
8 files changed, 86 insertions(+), 39 deletions(-) | |
--- | |
diff --git a/FAQ b/FAQ | |
t@@ -2,12 +2,14 @@ | |
Use the excellent tool of [utmp](https://git.suckless.org/utmp/) for this task. | |
+ | |
## Some _random program_ complains that st is unknown/not recognised/unsupport… | |
It means that st doesn’t have any terminfo entry on your system. Chances are | |
you did not `make install`. If you just want to test it without installing it, | |
you can manually run `tic -sx st.info`. | |
+ | |
## Nothing works, and nothing is said about an unknown terminal! | |
* Some programs just assume they’re running in xterm i.e. they don’t rely … | |
t@@ -15,6 +17,7 @@ you can manually run `tic -sx st.info`. | |
* Some programs don’t complain about the lacking st description and default … | |
another terminal. In that case see the question about terminfo. | |
+ | |
## How do I scroll back up? | |
* Using a terminal multiplexer. | |
t@@ -23,11 +26,13 @@ you can manually run `tic -sx st.info`. | |
* Using the excellent tool of [scroll](https://git.suckless.org/scroll/). | |
* Using the scrollback [patch](https://st.suckless.org/patches/scrollback/). | |
+ | |
## I would like to have utmp and/or scroll functionality by default | |
You can add the absolute patch of both programs in your config.h | |
file. You only have to modify the value of utmp and scroll variables. | |
+ | |
## Why doesn't the Del key work in some programs? | |
Taken from the terminfo manpage: | |
t@@ -83,12 +88,14 @@ If you are using zsh, then read the zsh FAQ | |
Putting these lines into your .zshrc will fix the problems. | |
+ | |
## How can I use meta in 8bit mode? | |
St supports meta in 8bit mode, but the default terminfo entry doesn't | |
use this capability. If you want it, you have to use the 'st-meta' value | |
in TERM. | |
+ | |
## I cannot compile st in OpenBSD | |
OpenBSD lacks librt, despite it being mandatory in POSIX | |
t@@ -97,6 +104,7 @@ If you want to compile st for OpenBSD you have to remove -l… | |
st will compile without any loss of functionality, because all the functions a… | |
included in libc on this platform. | |
+ | |
## The Backspace Case | |
St is emulating the Linux way of handling backspace being delete and delete be… | |
t@@ -158,19 +166,60 @@ terminal users wants its backspace to be how he feels it: | |
[1] http://www.ibb.net/~anne/keyboard.html | |
[2] http://www.tldp.org/HOWTO/Keyboard-and-Console-HOWTO-5.html | |
+ | |
## But I really want the old grumpy behaviour of my terminal | |
Apply [1]. | |
[1] https://st.suckless.org/patches/delkey | |
-## Why do images not work in st (in programs such as w3m)? | |
-This is a terrible hack that overdraws an image on top of the terminal emulator | |
-window. It also relies on a very specific way the terminal draws it's contents. | |
+## Why do images not work in st using the w3m image hack? | |
+ | |
+w3mimg uses a hack that draws an image on top of the terminal emulator Drawable | |
+window. The hack relies on the terminal to use a single buffer to draw its | |
+contents directly. | |
+ | |
+st uses double-buffered drawing so the image is quickly replaced and may show a | |
+short flicker effect. | |
+ | |
+Below is a patch example to change st double-buffering to a single Drawable | |
+buffer. | |
+ | |
+diff --git a/x.c b/x.c | |
+--- a/x.c | |
++++ b/x.c | |
+@@ -732,10 +732,6 @@ xresize(int col, int row) | |
+ win.tw = col * win.cw; | |
+ win.th = row * win.ch; | |
+ | |
+- XFreePixmap(xw.dpy, xw.buf); | |
+- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, | |
+- DefaultDepth(xw.dpy, xw.scr)); | |
+- XftDrawChange(xw.draw, xw.buf); | |
+ xclear(0, 0, win.w, win.h); | |
+ | |
+ /* resize to new width */ | |
+@@ -1148,8 +1144,7 @@ xinit(int cols, int rows) | |
+ gcvalues.graphics_exposures = False; | |
+ dc.gc = XCreateGC(xw.dpy, parent, GCGraphicsExposures, | |
+ &gcvalues); | |
+- xw.buf = XCreatePixmap(xw.dpy, xw.win, win.w, win.h, | |
+- DefaultDepth(xw.dpy, xw.scr)); | |
++ xw.buf = xw.win; | |
+ XSetForeground(xw.dpy, dc.gc, dc.col[defaultbg].pixel); | |
+ XFillRectangle(xw.dpy, xw.buf, dc.gc, 0, 0, win.w, win.h); | |
+ | |
+@@ -1632,8 +1627,6 @@ xdrawline(Line line, int x1, int y1, int x2) | |
+ void | |
+ xfinishdraw(void) | |
+ { | |
+- XCopyArea(xw.dpy, xw.buf, xw.win, dc.gc, 0, 0, win.w, | |
+- win.h, 0, 0); | |
+ XSetForeground(xw.dpy, dc.gc, | |
+ dc.col[IS_SET(MODE_REVERSE)? | |
+ defaultfg : defaultbg].pixel); | |
-A more proper (but limited way) would be using sixels. Which st doesn't | |
-support. | |
## BadLength X error in Xft when trying to render emoji | |
diff --git a/LICENSE b/LICENSE | |
t@@ -1,7 +1,7 @@ | |
MIT/X Consortium License | |
© 2019-2020 Anders Damsgaard <anders at adamsgaard dot dk> | |
-© 2014-2018 Hiltjo Posthuma <hiltjo at codemadness dot org> | |
+© 2014-2020 Hiltjo Posthuma <hiltjo at codemadness dot org> | |
© 2018 Devin J. Pohly <djpohly at gmail dot com> | |
© 2014-2017 Quentin Rameau <quinq at fifth dot space> | |
© 2009-2012 Aurélien APTEL <aurelien dot aptel at gmail dot com> | |
diff --git a/config.def.h b/config.def.h | |
t@@ -43,6 +43,10 @@ static unsigned int tripleclicktimeout = 600; | |
/* alt screens */ | |
int allowaltscreen = 1; | |
+/* allow certain non-interactive (insecure) window operations such as: | |
+ setting the clipboard text */ | |
+int allowwindowops = 0; | |
+ | |
/* | |
* draw latency range in ms - from new content/keypress/etc until drawing. | |
* within this range, st draws when content stops arriving (idle). mostly it's | |
diff --git a/config.mk b/config.mk | |
t@@ -1,5 +1,5 @@ | |
# st version | |
-VERSION = 0.8.3 | |
+VERSION = 0.8.4 | |
# Customize below to fit your system | |
t@@ -28,8 +28,8 @@ 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 fontconfig` \ | |
+ `$(PKG_CONFIG) --libs freetype2` | |
# compiler and linker | |
# CC = c99 | |
diff --git a/st.c b/st.c | |
t@@ -51,7 +51,6 @@ enum term_mode { | |
MODE_ECHO = 1 << 4, | |
MODE_PRINT = 1 << 5, | |
MODE_UTF8 = 1 << 6, | |
- MODE_SIXEL = 1 << 7, | |
}; | |
enum cursor_movement { | |
t@@ -78,12 +77,11 @@ enum charset { | |
enum escape_state { | |
ESC_START = 1, | |
ESC_CSI = 2, | |
- ESC_STR = 4, /* OSC, PM, APC */ | |
+ ESC_STR = 4, /* DCS, OSC, PM, APC */ | |
ESC_ALTCHARSET = 8, | |
ESC_STR_END = 16, /* a final string was encountered */ | |
ESC_TEST = 32, /* Enter in test mode */ | |
ESC_UTF8 = 64, | |
- ESC_DCS =128, | |
}; | |
typedef struct { | |
t@@ -129,6 +127,7 @@ typedef struct { | |
int charset; /* current charset */ | |
int icharset; /* selected charset for sequence */ | |
int *tabs; | |
+ Rune lastc; /* last printed char outside of sequence, 0 if control */ | |
} Term; | |
/* CSI Escape sequence structs */ | |
t@@ -842,7 +841,6 @@ ttyread(void) | |
if (buflen > 0) | |
memmove(buf, buf + written, buflen); | |
return ret; | |
- | |
} | |
} | |
t@@ -1648,6 +1646,12 @@ csihandle(void) | |
if (csiescseq.arg[0] == 0) | |
ttywrite(vtiden, strlen(vtiden), 0); | |
break; | |
+ case 'b': /* REP -- if last char is printable print it <n> more times … | |
+ DEFAULT(csiescseq.arg[0], 1); | |
+ if (term.lastc) | |
+ while (csiescseq.arg[0]-- > 0) | |
+ tputc(term.lastc); | |
+ break; | |
case 'C': /* CUF -- Cursor <n> Forward */ | |
case 'a': /* HPR -- Cursor <n> Forward */ | |
DEFAULT(csiescseq.arg[0], 1); | |
t@@ -1771,7 +1775,7 @@ csihandle(void) | |
break; | |
case 'n': /* DSR – Device Status Report (cursor position) */ | |
if (csiescseq.arg[0] == 6) { | |
- len = snprintf(buf, sizeof(buf),"\033[%i;%iR", | |
+ len = snprintf(buf, sizeof(buf), "\033[%i;%iR", | |
term.c.y+1, term.c.x+1); | |
ttywrite(buf, len, 0); | |
} | |
t@@ -1855,7 +1859,7 @@ strhandle(void) | |
xsettitle(strescseq.args[1]); | |
return; | |
case 52: | |
- if (narg > 2) { | |
+ if (narg > 2 && allowwindowops) { | |
dec = base64dec(strescseq.args[2]); | |
if (dec) { | |
xsetsel(dec); | |
t@@ -1891,7 +1895,6 @@ strhandle(void) | |
xsettitle(strescseq.args[0]); | |
return; | |
case 'P': /* DCS -- Device Control String */ | |
- term.mode |= ESC_DCS; | |
case '_': /* APC -- Application Program Command */ | |
case '^': /* PM -- Privacy Message */ | |
return; | |
t@@ -2085,12 +2088,9 @@ tdectest(char c) | |
void | |
tstrsequence(uchar c) | |
{ | |
- strreset(); | |
- | |
switch (c) { | |
case 0x90: /* DCS -- Device Control String */ | |
c = 'P'; | |
- term.esc |= ESC_DCS; | |
break; | |
case 0x9f: /* APC -- Application Program Command */ | |
c = '_'; | |
t@@ -2102,6 +2102,7 @@ tstrsequence(uchar c) | |
c = ']'; | |
break; | |
} | |
+ strreset(); | |
strescseq.type = c; | |
term.esc |= ESC_STR; | |
} | |
t@@ -2299,7 +2300,7 @@ tputc(Rune u) | |
Glyph *gp; | |
control = ISCONTROL(u); | |
- if (u < 127 || !IS_SET(MODE_UTF8 | MODE_SIXEL)) { | |
+ if (u < 127 || !IS_SET(MODE_UTF8)) { | |
c[0] = u; | |
width = len = 1; | |
} else { | |
t@@ -2320,23 +2321,11 @@ tputc(Rune u) | |
if (term.esc & ESC_STR) { | |
if (u == '\a' || u == 030 || u == 032 || u == 033 || | |
ISCONTROLC1(u)) { | |
- term.esc &= ~(ESC_START|ESC_STR|ESC_DCS); | |
- if (IS_SET(MODE_SIXEL)) { | |
- /* TODO: render sixel */; | |
- term.mode &= ~MODE_SIXEL; | |
- return; | |
- } | |
+ term.esc &= ~(ESC_START|ESC_STR); | |
term.esc |= ESC_STR_END; | |
goto check_control_code; | |
} | |
- if (IS_SET(MODE_SIXEL)) { | |
- /* TODO: implement sixel mode */ | |
- return; | |
- } | |
- if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q') | |
- term.mode |= MODE_SIXEL; | |
- | |
if (strescseq.len+len >= strescseq.siz) { | |
/* | |
* Here is a bug in terminals. If the user never sends | |
t@@ -2373,6 +2362,8 @@ check_control_code: | |
/* | |
* control codes are not shown ever | |
*/ | |
+ if (!term.esc) | |
+ term.lastc = 0; | |
return; | |
} else if (term.esc & ESC_START) { | |
if (term.esc & ESC_CSI) { | |
t@@ -2422,6 +2413,7 @@ check_control_code: | |
} | |
tsetchar(u, &term.c.attr, term.c.x, term.c.y); | |
+ term.lastc = u; | |
if (width == 2) { | |
gp->mode |= ATTR_WIDE; | |
t@@ -2445,7 +2437,7 @@ twrite(const char *buf, int buflen, int show_ctrl) | |
int n; | |
for (n = 0; n < buflen; n += charsize) { | |
- if (IS_SET(MODE_UTF8) && !IS_SET(MODE_SIXEL)) { | |
+ if (IS_SET(MODE_UTF8)) { | |
/* process a complete utf8 char */ | |
charsize = utf8decode(buf + n, &u, buflen - n); | |
if (charsize == 0) | |
diff --git a/st.h b/st.h | |
t@@ -118,6 +118,7 @@ extern char *stty_args; | |
extern char *vtiden; | |
extern wchar_t *worddelimiters; | |
extern int allowaltscreen; | |
+extern int allowwindowops; | |
extern char *termname; | |
extern unsigned int tabspaces; | |
extern unsigned int defaultfg; | |
diff --git a/st.info b/st.info | |
t@@ -184,6 +184,8 @@ st-mono| simpleterm monocolor, | |
# XTerm extensions | |
rmxx=\E[29m, | |
smxx=\E[9m, | |
+# disabled rep for now: causes some issues with older ncurses versions. | |
+# rep=%p1%c\E[%p2%{1}%-%db, | |
# tmux extensions, see TERMINFO EXTENSIONS in tmux(1) | |
Tc, | |
Ms=\E]52;%p1%s;%p2%s\007, | |
diff --git a/x.c b/x.c | |
t@@ -1566,8 +1566,8 @@ xdrawcursor(int cx, int cy, Glyph g, int ox, int oy, Gly… | |
/* draw the new one */ | |
if (IS_SET(MODE_FOCUSED)) { | |
switch (win.cursor) { | |
- case 7: /* st extension: snowman (U+2603) */ | |
- g.u = 0x2603; | |
+ case 7: /* st extension */ | |
+ g.u = 0x2603; /* snowman (U+2603) */ | |
/* FALLTHROUGH */ | |
case 0: /* Blinking Block */ | |
case 1: /* Blinking Block (Default) */ | |
t@@ -1730,8 +1730,7 @@ xsetmode(int set, unsigned int flags) | |
int | |
xsetcursor(int cursor) | |
{ | |
- DEFAULT(cursor, 1); | |
- if (!BETWEEN(cursor, 0, 6)) | |
+ if (!BETWEEN(cursor, 0, 7)) /* 7: st extension */ | |
return 1; | |
win.cursor = cursor; | |
return 0; | |
t@@ -2023,7 +2022,7 @@ main(int argc, char *argv[]) | |
{ | |
xw.l = xw.t = 0; | |
xw.isfixed = False; | |
- win.cursor = cursorshape; | |
+ xsetcursor(cursorshape); | |
ARGBEGIN { | |
case 'a': |