X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=64e2cec468d9f260bc1ff043d54684d69ae0d83e;hb=d032b6159719b2fbbbd550781b378ca79a25d3a2;hp=17e0a65493aeab1b63097b187529a476dc5be13d;hpb=f8c6e7d0419d10c1425cb2c7123c5798ffb3b942;p=st.git diff --git a/st.c b/st.c index 17e0a65..64e2cec 100644 --- a/st.c +++ b/st.c @@ -62,26 +62,28 @@ char *argv0; #define XK_SWITCH_MOD (1<<13) /* macros */ -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define MAX(a, b) ((a) < (b) ? (b) : (a)) -#define LEN(a) (sizeof(a) / sizeof(a)[0]) -#define DEFAULT(a, b) (a) = (a) ? (a) : (b) -#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) -#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') -#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) -#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) -#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL) -#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) -#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || (a).bg != (b).bg) -#define IS_SET(flag) ((term.mode & (flag)) != 0) -#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + (t1.tv_nsec-t2.tv_nsec)/1E6) -#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) - -#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) -#define IS_TRUECOL(x) (1 << 24 & (x)) -#define TRUERED(x) (((x) & 0xff0000) >> 8) -#define TRUEGREEN(x) (((x) & 0xff00)) -#define TRUEBLUE(x) (((x) & 0xff) << 8) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) < (b) ? (b) : (a)) +#define LEN(a) (sizeof(a) / sizeof(a)[0]) +#define DEFAULT(a, b) (a) = (a) ? (a) : (b) +#define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) +#define ISCONTROLC0(c) (BETWEEN(c, 0, 0x1f) || (c) == '\177') +#define ISCONTROLC1(c) (BETWEEN(c, 0x80, 0x9f)) +#define ISCONTROL(c) (ISCONTROLC0(c) || ISCONTROLC1(c)) +#define ISDELIM(u) (utf8strchr(worddelimiters, u) != NULL) +#define LIMIT(x, a, b) (x) = (x) < (a) ? (a) : (x) > (b) ? (b) : (x) +#define ATTRCMP(a, b) ((a).mode != (b).mode || (a).fg != (b).fg || \ + (a).bg != (b).bg) +#define IS_SET(flag) ((term.mode & (flag)) != 0) +#define TIMEDIFF(t1, t2) ((t1.tv_sec-t2.tv_sec)*1000 + \ + (t1.tv_nsec-t2.tv_nsec)/1E6) +#define MODBIT(x, set, bit) ((set) ? ((x) |= (bit)) : ((x) &= ~(bit))) + +#define TRUECOLOR(r,g,b) (1 << 24 | (r) << 16 | (g) << 8 | (b)) +#define IS_TRUECOL(x) (1 << 24 & (x)) +#define TRUERED(x) (((x) & 0xff0000) >> 8) +#define TRUEGREEN(x) (((x) & 0xff00)) +#define TRUEBLUE(x) (((x) & 0xff) << 8) enum glyph_attribute { @@ -558,15 +560,16 @@ static int frclen = 0; ssize_t xwrite(int fd, const char *s, size_t len) { - size_t aux = len; + size_t aux = len, r; while (len > 0) { - ssize_t r = write(fd, s, len); + r = write(fd, s, len); if (r < 0) return r; len -= r; s += r; } + return aux; } @@ -620,6 +623,7 @@ utf8decode(char *c, Rune *u, size_t clen) return 0; *u = udecoded; utf8validate(u, len); + return len; } @@ -629,6 +633,7 @@ utf8decodebyte(char c, size_t *i) for (*i = 0; *i < LEN(utfmask); ++(*i)) if (((uchar)c & utfmask[*i]) == utfbyte[*i]) return (uchar)c & ~utfmask[*i]; + return 0; } @@ -640,11 +645,13 @@ utf8encode(Rune u, char *c) len = utf8validate(&u, 0); if (len > UTF_SIZ) return 0; + for (i = len - 1; i != 0; --i) { c[i] = utf8encodebyte(u, 0); u >>= 6; } c[0] = utf8encodebyte(u, len); + return len; } @@ -667,6 +674,7 @@ utf8strchr(char *s, Rune u) if (r == u) return &(s[i]); } + return NULL; } @@ -677,6 +685,7 @@ utf8validate(Rune *u, size_t i) *u = UTF_INVALID; for (i = 1; *u > utfmax[i]; ++i) ; + return i; } @@ -1044,7 +1053,7 @@ propnotify(XEvent *e) if (xpev->state == PropertyNewValue && (xpev->atom == XA_PRIMARY || xpev->atom == clipboard)) { - slenotify(e); + selnotify(e); } } @@ -1056,6 +1065,8 @@ selnotify(XEvent *e) uchar *data, *last, *repl; Atom type, incratom, property; + incratom = XInternAtom(xw.dpy, "INCR", 0); + ofs = 0; if (e->type == SelectionNotify) { property = e->xselection.property; @@ -1478,8 +1489,57 @@ ttyread(void) void ttywrite(const char *s, size_t n) { - if (xwrite(cmdfd, s, n) == -1) - die("write error on tty: %s\n", strerror(errno)); + fd_set wfd; + struct timespec tv; + ssize_t r; + + /* + * Remember that we are using a pty, which might be a modem line. + * Writing too much will clog the line. That's why we are doing this + * dance. + * FIXME: Migrate the world to Plan 9. + */ + while (n > 0) { + FD_ZERO(&wfd); + FD_SET(cmdfd, &wfd); + tv.tv_sec = 0; + tv.tv_nsec = 0; + + /* Check if we can write. */ + if (pselect(cmdfd+1, NULL, &wfd, NULL, &tv, NULL) < 0) { + if (errno == EINTR) + continue; + die("select failed: %s\n", strerror(errno)); + } + if(!FD_ISSET(cmdfd, &wfd)) { + /* No, then free some buffer space. */ + ttyread(); + } else { + /* + * Only write 256 bytes at maximum. This seems to be a + * reasonable value for a serial line. Bigger values + * might clog the I/O. + */ + r = write(cmdfd, s, (n < 256)? n : 256); + if (r < 0) { + die("write error on tty: %s\n", + strerror(errno)); + } + if (r < n) { + /* + * We weren't able to write out everything. + * This means the buffer is getting full + * again. Empty it. + */ + ttyread(); + n -= r; + s += r; + } else { + /* All bytes have been written. */ + break; + } + } + } } void @@ -3074,6 +3134,7 @@ xloadcolor(int i, const char *name, Color *ncolor) } else name = colorname[i]; } + return XftColorAllocName(xw.dpy, xw.vis, xw.cmap, name, ncolor); } @@ -3113,6 +3174,7 @@ xsetcolorname(int x, const char *name) XftColorFree(xw.dpy, xw.vis, xw.cmap, &dc.col[x]); dc.col[x] = ncolor; + return 0; } @@ -3182,6 +3244,7 @@ xgeommasktogravity(int mask) case YNegative: return SouthWestGravity; } + return SouthEastGravity; } @@ -4097,9 +4160,9 @@ run(void) do { XNextEvent(xw.dpy, &ev); /* - * XFilterEvent is required to be called after you using XOpenIM, - * this is not unnecessary.It does not only filter the key event, - * but some clientmessage for input method as well. + * This XFilterEvent call is required because of XOpenIM. It + * does filter out the key event and some client message for + * the input method too. */ if (XFilterEvent(&ev, None)) continue; @@ -4265,3 +4328,4 @@ run: return 0; } +