X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=13104267ee790c252195172b02385cb42df6c189;hb=1ab42fd49e68a11bfbbe5990ebdab2d3ca502178;hp=8e3d72ff7228687a6555d2ec8ce46b7dfb53ede0;hpb=00ba6969f863c75536910a0138b5161bbd0638c9;p=st.git diff --git a/st.c b/st.c index 8e3d72f..1310426 100644 --- a/st.c +++ b/st.c @@ -16,14 +16,15 @@ #include #include #include -#include #include -#include +#include #include +#include +#include #if defined(__linux) #include -#elif defined(__OpenBSD__) || defined(__NetBSD__) +#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) #include #elif defined(__FreeBSD__) || defined(__DragonFly__) #include @@ -247,7 +248,7 @@ static CSIEscape escseq; static int cmdfd; static pid_t pid; static Selection sel; -static char *opt_cmd = NULL; +static char **opt_cmd = NULL; static char *opt_title = NULL; static char *opt_class = NULL; @@ -405,7 +406,7 @@ bpress(XEvent *e) { void selcopy(void) { char *str, *ptr; - int ls, x, y, sz, sl; + int x, y, sz, sl, ls = 0; if(sel.bx == -1) str = NULL; @@ -545,13 +546,14 @@ die(const char *errstr, ...) { void execsh(void) { - char *args[] = {getenv("SHELL"), "-i", NULL}; - if(opt_cmd) - args[0] = opt_cmd, args[1] = NULL; - else - DEFAULT(args[0], SHELL); + char **args; + char *envshell = getenv("SHELL"); + + DEFAULT(envshell, "sh"); putenv("TERM="TNAME); + args = opt_cmd ? opt_cmd : (char*[]){envshell, "-i", NULL}; execvp(args[0], args); + exit(EXIT_FAILURE); } void @@ -606,24 +608,31 @@ dump(char c) { void ttyread(void) { - char buf[BUFSIZ], *ptr; + static char buf[BUFSIZ]; + static int buflen = 0; + char *ptr; char s[UTF_SIZ]; - int ret, br; - static int buflen = 0; - long u; + int charsize; /* size of utf8 char in bytes */ + long utf8c; + int ret; + /* append read bytes to unprocessed bytes */ if((ret = read(cmdfd, buf+buflen, LEN(buf)-buflen)) < 0) die("Couldn't read from shell: %s\n", SERRNO); - else { - buflen += ret; - for(ptr=buf; buflen>=UTF_SIZ||isfullutf8(ptr,buflen); buflen-=br) { - br = utf8decode(ptr, &u); - utf8encode(&u, s); - tputc(s); - ptr += br; - } - memcpy(buf, ptr, buflen); + + /* process every complete utf8 char */ + buflen += ret; + ptr = buf; + while(buflen >= UTF_SIZ || isfullutf8(ptr,buflen)) { + charsize = utf8decode(ptr, &utf8c); + utf8encode(&utf8c, s); + tputc(s); + ptr += charsize; + buflen -= charsize; } + + /* keep any uncomplete utf8 char for the next call */ + memmove(buf, ptr, buflen); } void @@ -926,7 +935,7 @@ csihandle(void) { switch(escseq.mode) { default: unknown: - printf("erresc: unknown csi "); + fprintf(stderr, "erresc: unknown csi "); csidump(); /* die(""); */ break; @@ -1198,7 +1207,7 @@ tputc(char *c) { term.c.attr.mode &= ~ATTR_GFX; break; default: - printf("esc unhandled charset: ESC ( %c\n", ascii); + fprintf(stderr, "esc unhandled charset: ESC ( %c\n", ascii); } term.esc = 0; } else { @@ -1495,6 +1504,7 @@ initfonts(char *fontstr, char *bfontstr) void xinit(void) { XSetWindowAttributes attrs; + Cursor cursor; if(!(xw.dpy = XOpenDisplay(NULL))) die("Can't open display\n"); @@ -1542,6 +1552,13 @@ xinit(void) { /* gc */ dc.gc = XCreateGC(xw.dpy, xw.win, 0, NULL); + /* white cursor, black outline */ + cursor = XCreateFontCursor(xw.dpy, XC_xterm); + XDefineCursor(xw.dpy, xw.win, cursor); + XRecolorCursor(xw.dpy, cursor, + &(XColor){.red = 0xffff, .green = 0xffff, .blue = 0xffff}, + &(XColor){.red = 0x0000, .green = 0x0000, .blue = 0x0000}); + XMapWindow(xw.dpy, xw.win); xhints(); XStoreName(xw.dpy, xw.win, opt_title ? opt_title : "st"); @@ -1774,7 +1791,6 @@ kpress(XEvent *ev) { /* 3. X lookup */ default: if(len > 0) { - buf[sizeof(buf)-1] = '\0'; if(meta && len == 1) ttywrite("\033", 1); ttywrite(buf, len); @@ -1845,12 +1861,15 @@ main(int argc, char *argv[]) { if(++i < argc) opt_class = argv[i]; break; case 'e': - if(++i < argc) opt_cmd = argv[i]; + if(++i < argc) opt_cmd = &argv[i]; break; case 'v': default: die(USAGE); } + /* -e eats every remaining arguments */ + if(opt_cmd) + break; } setlocale(LC_CTYPE, ""); tnew(80, 24);