From e7ed326d2e914a57017c9f34459824614075519b Mon Sep 17 00:00:00 2001 From: "osandov@osandov.com" Date: Sat, 18 Mar 2017 11:55:04 +0100 Subject: [PATCH] Support xterm Ms feature to set clipboard This is used by, e.g., tmux. --- st.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ st.info | 1 + win.h | 1 + x.c | 1 - 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/st.c b/st.c index 1e4196e..d7bd32a 100644 --- a/st.c +++ b/st.c @@ -198,6 +198,8 @@ static char utf8encodebyte(Rune, size_t); static char *utf8strchr(char *s, Rune u); static size_t utf8validate(Rune *, size_t); +static char *base64dec(const char *); + static ssize_t xwrite(int, const char *, size_t); static void *xrealloc(void *, size_t); @@ -369,6 +371,48 @@ utf8validate(Rune *u, size_t i) return i; } +static const char base64_digits[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, + 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, -1, 0, 0, 0, 0, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +char * +base64dec(const char *src) +{ + size_t in_len = strlen(src); + char *result, *dst; + + if (in_len % 4) + return NULL; + result = dst = xmalloc(in_len / 4 * 3 + 1); + while (*src) { + int a = base64_digits[(unsigned char) *src++]; + int b = base64_digits[(unsigned char) *src++]; + int c = base64_digits[(unsigned char) *src++]; + int d = base64_digits[(unsigned char) *src++]; + + *dst++ = (a << 2) | ((b & 0x30) >> 4); + if (c == -1) + break; + *dst++ = ((b & 0x0f) << 4) | ((c & 0x3c) >> 2); + if (d == -1) + break; + *dst++ = ((c & 0x03) << 6) | d; + } + *dst = '\0'; + return result; +} + void selinit(void) { @@ -1820,6 +1864,19 @@ strhandle(void) if (narg > 1) xsettitle(strescseq.args[1]); return; + case 52: + if (narg > 2) { + char *dec; + + dec = base64dec(strescseq.args[2]); + if (dec) { + xsetsel(dec, CurrentTime); + clipcopy(NULL); + } else { + fprintf(stderr, "erresc: invalid base64\n"); + } + } + return; case 4: /* color set */ if (narg < 3) break; diff --git a/st.info b/st.info index 13cc8eb..0b928af 100644 --- a/st.info +++ b/st.info @@ -189,6 +189,7 @@ st| simpleterm, Se, Ss, Tc, + Ms=\E]52;%p1%s;%p2%s\007, st-256color| simpleterm with 256 colors, use=st, diff --git a/win.h b/win.h index d684797..428111c 100644 --- a/win.h +++ b/win.h @@ -27,3 +27,4 @@ void xunloadfonts(void); void xresize(int, int); void xselpaste(void); unsigned long xwinid(void); +void xsetsel(char *, Time); diff --git a/x.c b/x.c index 6474a01..743b084 100644 --- a/x.c +++ b/x.c @@ -88,7 +88,6 @@ static void xclear(int, int, int, int); static void xdrawcursor(void); static int xgeommasktogravity(int); static int xloadfont(Font *, FcPattern *); -static void xsetsel(char *, Time); static void xunloadfont(Font *); static void expose(XEvent *);