tMerge remote-tracking branch 'upstream/master' - st - [fork] customized build … | |
git clone git://src.adamsgaard.dk/st | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 6edf2d3761f7f169b940c5977192277158d9f360 | |
parent d5b8228f1ab248cae2889ed6c083e614e3c5b9d9 | |
Author: Anders Damsgaard <[email protected]> | |
Date: Mon, 3 Jan 2022 10:11:05 +0100 | |
Merge remote-tracking branch 'upstream/master' | |
Diffstat: | |
M FAQ | 4 ++-- | |
M config.def.h | 8 +++++--- | |
M st.c | 143 +++++++++++++++++++++++++----… | |
M st.h | 7 +++++-- | |
M win.h | 1 + | |
M x.c | 47 +++++++++++++++++++++++++----… | |
6 files changed, 170 insertions(+), 40 deletions(-) | |
--- | |
diff --git a/FAQ b/FAQ | |
t@@ -29,8 +29,8 @@ you can manually run `tic -sx st.info`. | |
## 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. | |
+You can add the absolute path 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? | |
diff --git a/config.def.h b/config.def.h | |
t@@ -120,6 +120,8 @@ static const char *colorname[] = { | |
/* more colors can be added after 255 to use with DefaultXX */ | |
"#cccccc", | |
"#555555", | |
+ "gray90", /* default foreground colour */ | |
+ "black", /* default background colour */ | |
}; | |
t@@ -127,9 +129,9 @@ static const char *colorname[] = { | |
* Default colors (colorname index) | |
* foreground, background, cursor, reverse cursor | |
*/ | |
-unsigned int defaultfg = 7; | |
-unsigned int defaultbg = 0; | |
-static unsigned int defaultcs = 256; | |
+unsigned int defaultfg = 258; | |
+unsigned int defaultbg = 259; | |
+unsigned int defaultcs = 256; | |
static unsigned int defaultrcs = 257; | |
/* | |
diff --git a/st.c b/st.c | |
t@@ -186,18 +186,18 @@ static void tputc(Rune); | |
static void treset(void); | |
static void tscrollup(int, int); | |
static void tscrolldown(int, int); | |
-static void tsetattr(int *, int); | |
-static void tsetchar(Rune, Glyph *, int, int); | |
+static void tsetattr(const int *, int); | |
+static void tsetchar(Rune, const Glyph *, int, int); | |
static void tsetdirt(int, int); | |
static void tsetscroll(int, int); | |
static void tswapscreen(void); | |
-static void tsetmode(int, int, int *, int); | |
+static void tsetmode(int, int, const int *, int); | |
static int twrite(const char *, int, int); | |
static void tfulldirt(void); | |
static void tcontrolcode(uchar ); | |
static void tdectest(char ); | |
static void tdefutf8(char); | |
-static int32_t tdefcolor(int *, int *, int); | |
+static int32_t tdefcolor(const int *, int *, int); | |
static void tdeftran(char); | |
static void tstrsequence(uchar); | |
t@@ -226,10 +226,10 @@ static int iofd = 1; | |
static int cmdfd; | |
static pid_t pid; | |
-static uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; | |
-static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; | |
-static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; | |
-static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; | |
+static const uchar utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; | |
+static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; | |
+static const Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x100… | |
+static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FF… | |
ssize_t | |
xwrite(int fd, const char *s, size_t len) | |
t@@ -269,12 +269,14 @@ xrealloc(void *p, size_t len) | |
} | |
char * | |
-xstrdup(char *s) | |
+xstrdup(const char *s) | |
{ | |
- if ((s = strdup(s)) == NULL) | |
+ char *p; | |
+ | |
+ if ((p = strdup(s)) == NULL) | |
die("strdup: %s\n", strerror(errno)); | |
- return s; | |
+ return p; | |
} | |
size_t | |
t@@ -518,7 +520,7 @@ selsnap(int *x, int *y, int direction) | |
{ | |
int newx, newy, xt, yt; | |
int delim, prevdelim; | |
- Glyph *gp, *prevgp; | |
+ const Glyph *gp, *prevgp; | |
switch (sel.snap) { | |
case SNAP_WORD: | |
t@@ -591,7 +593,7 @@ getsel(void) | |
{ | |
char *str, *ptr; | |
int y, bufsize, lastx, linelen; | |
- Glyph *gp, *last; | |
+ const Glyph *gp, *last; | |
if (sel.ob.x == -1) | |
return NULL; | |
t@@ -758,7 +760,7 @@ stty(char **args) | |
} | |
int | |
-ttynew(char *line, char *cmd, char *out, char **args) | |
+ttynew(const char *line, char *cmd, const char *out, char **args) | |
{ | |
int m, s; | |
t@@ -791,14 +793,15 @@ ttynew(char *line, char *cmd, char *out, char **args) | |
break; | |
case 0: | |
close(iofd); | |
+ close(m); | |
setsid(); /* create a new process group */ | |
dup2(s, 0); | |
dup2(s, 1); | |
dup2(s, 2); | |
if (ioctl(s, TIOCSCTTY, NULL) < 0) | |
die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); | |
- close(s); | |
- close(m); | |
+ if (s > 2) | |
+ close(s); | |
#ifdef __OpenBSD__ | |
if (pledge("stdio getpw proc exec", NULL) == -1) | |
die("pledge\n"); | |
t@@ -1186,9 +1189,9 @@ tmoveto(int x, int y) | |
} | |
void | |
-tsetchar(Rune u, Glyph *attr, int x, int y) | |
+tsetchar(Rune u, const Glyph *attr, int x, int y) | |
{ | |
- static char *vt100_0[62] = { /* 0x41 - 0x7e */ | |
+ static const char *vt100_0[62] = { /* 0x41 - 0x7e */ | |
"↑", "↓", "→", "←", "█", "▚", "☃", /* A - G */ | |
0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ | |
0, 0, 0, 0, 0, 0, 0, 0, /* P - W */ | |
t@@ -1300,7 +1303,7 @@ tdeleteline(int n) | |
} | |
int32_t | |
-tdefcolor(int *attr, int *npar, int l) | |
+tdefcolor(const int *attr, int *npar, int l) | |
{ | |
int32_t idx = -1; | |
uint r, g, b; | |
t@@ -1350,7 +1353,7 @@ tdefcolor(int *attr, int *npar, int l) | |
} | |
void | |
-tsetattr(int *attr, int l) | |
+tsetattr(const int *attr, int l) | |
{ | |
int i; | |
int32_t idx; | |
t@@ -1468,9 +1471,9 @@ tsetscroll(int t, int b) | |
} | |
void | |
-tsetmode(int priv, int set, int *args, int narg) | |
+tsetmode(int priv, int set, const int *args, int narg) | |
{ | |
- int alt, *lim; | |
+ int alt; const int *lim; | |
for (lim = args + narg; args < lim; ++args) { | |
if (priv) { | |
t@@ -1840,6 +1843,42 @@ csireset(void) | |
} | |
void | |
+osc4_color_response(int num) | |
+{ | |
+ int n; | |
+ char buf[32]; | |
+ unsigned char r, g, b; | |
+ | |
+ if (xgetcolor(num, &r, &g, &b)) { | |
+ fprintf(stderr, "erresc: failed to fetch osc4 color %d\n", num… | |
+ return; | |
+ } | |
+ | |
+ n = snprintf(buf, sizeof buf, "\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02… | |
+ num, r, r, g, g, b, b); | |
+ | |
+ ttywrite(buf, n, 1); | |
+} | |
+ | |
+void | |
+osc_color_response(int index, int num) | |
+{ | |
+ int n; | |
+ char buf[32]; | |
+ unsigned char r, g, b; | |
+ | |
+ if (xgetcolor(index, &r, &g, &b)) { | |
+ fprintf(stderr, "erresc: failed to fetch osc color %d\n", inde… | |
+ return; | |
+ } | |
+ | |
+ n = snprintf(buf, sizeof buf, "\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\… | |
+ num, r, r, g, g, b, b); | |
+ | |
+ ttywrite(buf, n, 1); | |
+} | |
+ | |
+void | |
strhandle(void) | |
{ | |
char *p = NULL, *dec; | |
t@@ -1853,7 +1892,15 @@ strhandle(void) | |
case ']': /* OSC -- Operating System Command */ | |
switch (par) { | |
case 0: | |
+ if (narg > 1) { | |
+ xsettitle(strescseq.args[1]); | |
+ xseticontitle(strescseq.args[1]); | |
+ } | |
+ return; | |
case 1: | |
+ if (narg > 1) | |
+ xseticontitle(strescseq.args[1]); | |
+ return; | |
case 2: | |
if (narg > 1) | |
xsettitle(strescseq.args[1]); | |
t@@ -1869,14 +1916,56 @@ strhandle(void) | |
} | |
} | |
return; | |
+ case 10: | |
+ if (narg < 2) | |
+ break; | |
+ | |
+ p = strescseq.args[1]; | |
+ | |
+ if (!strcmp(p, "?")) | |
+ osc_color_response(defaultfg, 10); | |
+ else if (xsetcolorname(defaultfg, p)) | |
+ fprintf(stderr, "erresc: invalid foreground co… | |
+ else | |
+ redraw(); | |
+ return; | |
+ case 11: | |
+ if (narg < 2) | |
+ break; | |
+ | |
+ p = strescseq.args[1]; | |
+ | |
+ if (!strcmp(p, "?")) | |
+ osc_color_response(defaultbg, 11); | |
+ else if (xsetcolorname(defaultbg, p)) | |
+ fprintf(stderr, "erresc: invalid background co… | |
+ else | |
+ redraw(); | |
+ return; | |
+ case 12: | |
+ if (narg < 2) | |
+ break; | |
+ | |
+ p = strescseq.args[1]; | |
+ | |
+ if (!strcmp(p, "?")) | |
+ osc_color_response(defaultcs, 12); | |
+ else if (xsetcolorname(defaultcs, p)) | |
+ fprintf(stderr, "erresc: invalid cursor color:… | |
+ else | |
+ redraw(); | |
+ return; | |
case 4: /* color set */ | |
if (narg < 3) | |
break; | |
p = strescseq.args[2]; | |
/* FALLTHROUGH */ | |
- case 104: /* color reset, here p = NULL */ | |
+ case 104: /* color reset */ | |
j = (narg > 1) ? atoi(strescseq.args[1]) : -1; | |
- if (xsetcolorname(j, p)) { | |
+ | |
+ if (p && !strcmp(p, "?")) | |
+ osc4_color_response(j); | |
+ else if (xsetcolorname(j, p)) { | |
if (par == 104 && narg <= 1) | |
return; /* color reset without paramet… | |
fprintf(stderr, "erresc: invalid color j=%d, p… | |
t@@ -2012,7 +2101,7 @@ void | |
tdumpline(int n) | |
{ | |
char buf[UTF_SIZ]; | |
- Glyph *bp, *end; | |
+ const Glyph *bp, *end; | |
bp = &term.line[n][0]; | |
end = &bp[MIN(tlinelen(n), term.col) - 1]; | |
t@@ -2418,6 +2507,10 @@ check_control_code: | |
if (width == 2) { | |
gp->mode |= ATTR_WIDE; | |
if (term.c.x+1 < term.col) { | |
+ if (gp[1].mode == ATTR_WIDE && term.c.x+2 < term.col) { | |
+ gp[2].u = ' '; | |
+ gp[2].mode &= ~ATTR_WDUMMY; | |
+ } | |
gp[1].u = '\0'; | |
gp[1].mode = ATTR_WDUMMY; | |
} | |
diff --git a/st.h b/st.h | |
t@@ -91,7 +91,7 @@ void tnew(int, int); | |
void tresize(int, int); | |
void tsetdirtattr(int); | |
void ttyhangup(void); | |
-int ttynew(char *, char *, char *, char **); | |
+int ttynew(const char *, char *, const char *, char **); | |
size_t ttyread(void); | |
void ttyresize(int, int); | |
void ttywrite(const char *, size_t, int); | |
t@@ -109,7 +109,9 @@ size_t utf8encode(Rune, char *); | |
void *xmalloc(size_t); | |
void *xrealloc(void *, size_t); | |
-char *xstrdup(char *); | |
+char *xstrdup(const char *); | |
+ | |
+int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b); | |
/* config.h globals */ | |
extern char *utmp; | |
t@@ -123,3 +125,4 @@ extern char *termname; | |
extern unsigned int tabspaces; | |
extern unsigned int defaultfg; | |
extern unsigned int defaultbg; | |
+extern unsigned int defaultcs; | |
diff --git a/win.h b/win.h | |
t@@ -30,6 +30,7 @@ void xdrawline(Line, int, int, int); | |
void xfinishdraw(void); | |
void xloadcols(void); | |
int xsetcolorname(int, const char *); | |
+void xseticontitle(char *); | |
void xsettitle(char *); | |
int xsetcursor(int); | |
void xsetmode(int, unsigned int); | |
diff --git a/x.c b/x.c | |
t@@ -48,7 +48,7 @@ typedef struct { | |
/* X modifiers */ | |
#define XK_ANY_MOD UINT_MAX | |
#define XK_NO_MOD 0 | |
-#define XK_SWITCH_MOD (1<<13) | |
+#define XK_SWITCH_MOD (1<<13|1<<14) | |
/* function definitions used in config.h */ | |
static void clipcopy(const Arg *); | |
t@@ -94,7 +94,7 @@ typedef struct { | |
Window win; | |
Drawable buf; | |
GlyphFontSpec *specbuf; /* font spec buffer used for rendering */ | |
- Atom xembed, wmdeletewin, netwmname, netwmpid; | |
+ Atom xembed, wmdeletewin, netwmname, netwmiconname, netwmpid; | |
struct { | |
XIM xim; | |
XIC xic; | |
t@@ -157,7 +157,7 @@ static void xresize(int, int); | |
static void xhints(void); | |
static int xloadcolor(int, const char *, Color *); | |
static int xloadfont(Font *, FcPattern *); | |
-static void xloadfonts(char *, double); | |
+static void xloadfonts(const char *, double); | |
static void xunloadfont(Font *); | |
static void xunloadfonts(void); | |
static void xsetenv(void); | |
t@@ -415,7 +415,9 @@ mousereport(XEvent *e) | |
button = 3; | |
} else { | |
button -= Button1; | |
- if (button >= 3) | |
+ if (button >= 7) | |
+ button += 128 - 7; | |
+ else if (button >= 3) | |
button += 64 - 3; | |
} | |
if (e->xbutton.type == ButtonPress) { | |
t@@ -829,6 +831,19 @@ xloadcols(void) | |
} | |
int | |
+xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b) | |
+{ | |
+ if (!BETWEEN(x, 0, dc.collen)) | |
+ return 1; | |
+ | |
+ *r = dc.col[x].color.red >> 8; | |
+ *g = dc.col[x].color.green >> 8; | |
+ *b = dc.col[x].color.blue >> 8; | |
+ | |
+ return 0; | |
+} | |
+ | |
+int | |
xsetcolorname(int x, const char *name) | |
{ | |
Color ncolor; | |
t@@ -983,7 +998,7 @@ xloadfont(Font *f, FcPattern *pattern) | |
} | |
void | |
-xloadfonts(char *fontstr, double fontsize) | |
+xloadfonts(const char *fontstr, double fontsize) | |
{ | |
FcPattern *pattern; | |
double fontval; | |
t@@ -991,7 +1006,7 @@ xloadfonts(char *fontstr, double fontsize) | |
if (fontstr[0] == '-') | |
pattern = XftXlfdParse(fontstr, False, False); | |
else | |
- pattern = FcNameParse((FcChar8 *)fontstr); | |
+ pattern = FcNameParse((const FcChar8 *)fontstr); | |
if (!pattern) | |
die("can't open font %s\n", fontstr); | |
t@@ -1219,6 +1234,7 @@ xinit(int cols, int rows) | |
xw.xembed = XInternAtom(xw.dpy, "_XEMBED", False); | |
xw.wmdeletewin = XInternAtom(xw.dpy, "WM_DELETE_WINDOW", False); | |
xw.netwmname = XInternAtom(xw.dpy, "_NET_WM_NAME", False); | |
+ xw.netwmiconname = XInternAtom(xw.dpy, "_NET_WM_ICON_NAME", False); | |
XSetWMProtocols(xw.dpy, xw.win, &xw.wmdeletewin, 1); | |
xw.netwmpid = XInternAtom(xw.dpy, "_NET_WM_PID", False); | |
t@@ -1620,13 +1636,28 @@ xsetenv(void) | |
} | |
void | |
+xseticontitle(char *p) | |
+{ | |
+ XTextProperty prop; | |
+ DEFAULT(p, opt_title); | |
+ | |
+ if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, | |
+ &prop) != Success) | |
+ return; | |
+ XSetWMIconName(xw.dpy, xw.win, &prop); | |
+ XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmiconname); | |
+ XFree(prop.value); | |
+} | |
+ | |
+void | |
xsettitle(char *p) | |
{ | |
XTextProperty prop; | |
DEFAULT(p, opt_title); | |
- Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, | |
- &prop); | |
+ if (Xutf8TextListToTextProperty(xw.dpy, &p, 1, XUTF8StringStyle, | |
+ &prop) != Success) | |
+ return; | |
XSetWMName(xw.dpy, xw.win, &prop); | |
XSetTextProperty(xw.dpy, xw.win, &prop, xw.netwmname); | |
XFree(prop.value); |