diff options
Diffstat (limited to 'st.c')
-rw-r--r-- | st.c | 168 |
1 files changed, 130 insertions, 38 deletions
@@ -195,18 +195,18 @@ static void tputc(Rune); static void treset(void); static void tscrollup(int, int, int); static void tscrolldown(int, 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); @@ -235,10 +235,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, 0x10000}; +static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; ssize_t xwrite(int fd, const char *s, size_t len) @@ -278,12 +278,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 @@ -527,7 +529,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: @@ -600,7 +602,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; @@ -773,7 +775,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; @@ -806,14 +808,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"); @@ -1107,16 +1110,11 @@ kscrollup(const Arg* a) if (n < 0) n = term.row + n; - if (term.scr <= term.histi-n) { + if (term.scr <= HISTSIZE-n) { term.scr += n; selscroll(0, n); tfulldirt(); - } else { - n = term.histi - term.scr; - term.scr = term.histi; - selscroll(0, n); - tfulldirt(); - } + } } void @@ -1266,9 +1264,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 */ @@ -1380,7 +1378,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; @@ -1430,7 +1428,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; @@ -1548,9 +1546,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) { @@ -1789,11 +1787,9 @@ csihandle(void) if (term.c.y > 1) tclearregion(0, 0, term.col-1, term.c.y-1); tclearregion(0, term.c.y, term.c.x, term.c.y); - term.histi=0; break; case 2: /* all */ tclearregion(0, 0, term.col-1, term.row-1); - term.histi=0; break; default: goto unknown; @@ -1949,6 +1945,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%02x\007", + 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", index); + return; + } + + n = snprintf(buf, sizeof buf, "\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", + num, r, r, g, g, b, b); + + ttywrite(buf, n, 1); +} + +void strhandle(void) { char *p = NULL, *dec; @@ -1959,11 +1991,19 @@ strhandle(void) switch (strescseq.type) { case ']': /* OSC -- Operating System Command */ - strparse(); - par = (narg = strescseq.narg) ? atoi(STRESCARGJUST(0)) : 0; + strparse(); + par = (narg = strescseq.narg) ? atoi(STRESCARGJUST(0)) : 0; switch (par) { case 0: + if (narg > 1) { + xsettitle(STRESCARGREST(1), 0); + xseticontitle(STRESCARGREST(1)); + } + return; case 1: + if (narg > 1) + xsettitle(STRESCARGREST(1), 0); + return; case 2: if (narg > 1) xsettitle(STRESCARGREST(1), 0); @@ -1979,6 +2019,47 @@ strhandle(void) } } return; + /* + case 10: + if (narg < 2) + break; + + p = STRESCARGREST(1); + + if (!strcmp(p, "?")) + osc_color_response(defaultfg, 10); + else if (xsetcolorname(defaultfg, p)) + fprintf(stderr, "erresc: invalid foreground color: %s\n", p); + else + redraw(); + return; + case 11: + if (narg < 2) + break; + + p = STRESCARGREST(1); + + if (!strcmp(p, "?")) + osc_color_response(defaultbg, 11); + else if (xsetcolorname(defaultbg, p)) + fprintf(stderr, "erresc: invalid background color: %s\n", p); + else + redraw(); + return; + case 12: + if (narg < 2) + break; + + p = STRESCARGREST(1); + + if (!strcmp(p, "?")) + osc_color_response(defaultcs, 12); + else if (xsetcolorname(defaultcs, p)) + fprintf(stderr, "erresc: invalid cursor color: %s\n", p); + else + redraw(); + return; + */ case 10: /* set foreground color */ if (narg < 2) break; @@ -2014,16 +2095,23 @@ strhandle(void) break; p = STRESCARGJUST(2); /* FALLTHROUGH */ - case 104: /* color reset, here p = NULL */ + case 104: /* color reset */ j = (narg > 1) ? atoi(STRESCARGJUST(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 parameter */ fprintf(stderr, "erresc: invalid color j=%d, p=%s\n", j, p ? p : "(null)"); } else { - if (j == defaultbg) - xclearwin(); + /* + * TODO if defaultbg color is changed, borders + * are dirty + */ + if (j == defaultbg) + xclearwin(); redraw(); } return; @@ -2224,7 +2312,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]; @@ -2631,6 +2719,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; } |