# A patch taken from boards.4channel.org/g/thread/87102876 # adds graphics to st diff --git a/st.c b/st.c index 6ba467d..efad5ec 100644 --- a/st.c +++ b/st.c @@ -752,10 +752,11 @@ stty(char **args) perror("Couldn't call stty"); } -int +TTYConn ttynew(const char *line, char *cmd, const char *out, char **args) { int m, s; + int mypipe[2]; if (out) { term.mode |= MODE_PRINT; @@ -766,6 +767,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args) out, strerror(errno)); } } + pipe(mypipe); if (line) { if ((cmdfd = open(line, O_RDWR)) < 0) @@ -773,7 +775,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args) line, strerror(errno)); dup2(cmdfd, 0); stty(args); - return cmdfd; + return (TTYConn){ cmdfd, cmdfd }; } /* seems to work fine on linux, openbsd and freebsd */ @@ -791,6 +793,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args) dup2(s, 0); dup2(s, 1); dup2(s, 2); + dup2(mypipe[1], 3); if (ioctl(s, TIOCSCTTY, NULL) < 0) die("ioctl TIOCSCTTY failed: %s\n", strerror(errno)); if (s > 2) @@ -807,11 +810,12 @@ ttynew(const char *line, char *cmd, const char *out, char **args) die("pledge\n"); #endif close(s); + close(mypipe[1]); cmdfd = m; signal(SIGCHLD, sigchld); break; } - return cmdfd; + return (TTYConn){ .cmdfd = cmdfd, .pipefd = mypipe[0] }; } size_t diff --git a/st.h b/st.h index fd3b0d8..e5613ba 100644 --- a/st.h +++ b/st.h @@ -59,6 +59,10 @@ typedef unsigned short ushort; typedef uint_least32_t Rune; +typedef struct TTYConn { + int cmdfd, pipefd; +} TTYConn; + #define Glyph Glyph_ typedef struct { Rune u; /* character code */ @@ -91,7 +95,7 @@ void tnew(int, int); void tresize(int, int); void tsetdirtattr(int); void ttyhangup(void); -int ttynew(const char *, char *, const char *, char **); +TTYConn ttynew(const char *, char *, const char *, char **); size_t ttyread(void); void ttyresize(int, int); void ttywrite(const char *, size_t, int); diff --git a/x.c b/x.c index 2a3bd38..16caf2b 100644 --- a/x.c +++ b/x.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -1914,9 +1915,11 @@ run(void) XEvent ev; int w = win.w, h = win.h; fd_set rfd; - int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing; + int xfd = XConnectionNumber(xw.dpy), ttyfd, pipefd, xev, drawing; struct timespec seltv, *tv, now, lastblink, trigger; double timeout; + TTYConn conn; + unsigned long color; /* Waiting for window mapping */ do { @@ -1934,12 +1937,17 @@ run(void) } } while (ev.type != MapNotify); - ttyfd = ttynew(opt_line, shell, opt_io, opt_cmd); + conn = ttynew(opt_line, shell, opt_io, opt_cmd); + ttyfd = conn.cmdfd; + pipefd = conn.pipefd; cresize(w, h); + fcntl(pipefd, F_SETFL, O_NONBLOCK); + FILE *command = fdopen(pipefd, "r"); for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) { FD_ZERO(&rfd); FD_SET(ttyfd, &rfd); + FD_SET(pipefd, &rfd); FD_SET(xfd, &rfd); if (XPending(xw.dpy)) @@ -1949,7 +1957,7 @@ run(void) seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec); tv = timeout >= 0 ? &seltv : NULL; - if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { + if (pselect(MAX(MAX(xfd, ttyfd), pipefd)+1, &rfd, NULL, NULL, tv, NULL) < 0) { if (errno == EINTR) continue; die("select failed: %s\n", strerror(errno)); @@ -2006,6 +2014,30 @@ run(void) } draw(); + if(FD_ISSET(pipefd, &rfd)) { + char header[128]; + int x, y; + int w, h; + int r, g, b; + + xstartdraw(); + while(fscanf(command, "%s", header) != EOF) { + printf("Command: %s\n", header); + if(strcmp(header, "set-color") == 0) { + fscanf(command, "%d %d %d", &r, &g, &b); + + color = b + (g << 8) + (r << 16); + } + + if(strcmp(header, "fill-rectangle") == 0) { + fscanf(command, "%d %d %d %d", &x, &y, &w, &h); + XSetForeground(xw.dpy, dc.gc, color); + XFillRectangle(xw.dpy, xw.buf, dc.gc, x, y, w, h); + } + } + xfinishdraw(); + } + XFlush(xw.dpy); drawing = 0; }