X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=st.c;h=8f6aa0448bf20d0634ffc6e73590706769c23a1e;hb=eab9aad1dcd87ba1721bc63ef987203b7a643c69;hp=ebe896cd75854f5ec81d0eb5914cb9f153a158df;hpb=fbb66da9a9ef3c12c1e8dee7433d003b85d70e9c;p=st.git diff --git a/st.c b/st.c index ebe896c..8f6aa04 100644 --- a/st.c +++ b/st.c @@ -20,6 +20,14 @@ #include #include +#if defined(LINUX) + #include +#elif defined(OPENBSD) + #include +#elif defined(FREEBSD) + #include +#endif + /* Arbitrary sizes */ #define ESC_TITLE_SIZ 256 #define ESC_BUF_SIZ 256 @@ -34,7 +42,7 @@ #define BETWEEN(x, a, b) ((a) <= (x) && (x) <= (b)) #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) +#define IS_SET(flag) (term.mode & (flag)) /* Attribute, Cursor, Character state, Terminal mode, Screen draw mode */ enum { ATTR_NULL=0 , ATTR_REVERSE=1 , ATTR_UNDERLINE=2, ATTR_BOLD=4, ATTR_GFX=8 }; @@ -59,6 +67,7 @@ typedef struct { Glyph attr; /* current char attributes */ int x; int y; + char hide; } TCursor; /* CSI Escape sequence structs */ @@ -78,7 +87,6 @@ typedef struct { int col; /* nb col */ Line* line; /* screen */ TCursor c; /* cursor */ - char hidec; int top; /* top scroll limit */ int bot; /* bottom scroll limit */ int mode; /* terminal mode flags */ @@ -141,7 +149,6 @@ static void tputc(char); static void tputs(char*, int); static void treset(void); static void tresize(int, int); -static void tscroll(void); static void tscrollup(int); static void tscrolldown(int); static void tsetattr(int*, int); @@ -214,17 +221,17 @@ die(const char *errstr, ...) { void execsh(void) { char *args[3] = {getenv("SHELL"), "-i", NULL}; - DEFAULT(args[0], "/bin/sh"); /* default shell if getenv() failed */ + DEFAULT(args[0], "/bin/sh"); /* if getenv() failed */ putenv("TERM=" TNAME); execvp(args[0], args); } void -xbell(void) { /* visual bell */ - XRectangle r = { BORDER, BORDER, xw.bufw, xw.bufh }; +xbell(void) { XSetForeground(xw.dis, dc.gc, dc.col[BellCol]); - XFillRectangles(xw.dis, xw.win, dc.gc, &r, 1); - /* usleep(30000); */ + XFillRectangle(xw.dis, xw.win, dc.gc, BORDER, BORDER, xw.bufw, xw.bufh); + XFlush(xw.dis); + usleep(BellTime); draw(SCREEN_REDRAW); } @@ -242,19 +249,12 @@ sigchld(int a) { void ttynew(void) { int m, s; - char *pts; - - if((m = posix_openpt(O_RDWR | O_NOCTTY)) < 0) - die("openpt failed: %s\n", SERRNO); - if(grantpt(m) < 0) - die("grantpt failed: %s\n", SERRNO); - if(unlockpt(m) < 0) - die("unlockpt failed: %s\n", SERRNO); - if(!(pts = ptsname(m))) - die("ptsname failed: %s\n", SERRNO); - if((s = open(pts, O_RDWR | O_NOCTTY)) < 0) - die("Couldn't open slave: %s\n", SERRNO); - fcntl(s, F_SETFL, O_NDELAY); + + /* seems to work fine on linux, openbsd and freebsd */ + struct winsize w = {term.row, term.col, 0, 0}; + if(openpty(&m, &s, NULL, NULL, &w) < 0) + die("openpty failed: %s\n", SERRNO); + switch(pid = fork()) { case -1: die("fork failed\n"); @@ -325,11 +325,12 @@ tcursor(int mode) { void treset(void) { - term.c.attr.mode = ATTR_NULL; - term.c.attr.fg = DefaultFG; - term.c.attr.bg = DefaultBG; - term.c.x = term.c.y = 0; - term.hidec = 0; + term.c = (TCursor){{ + .mode = ATTR_NULL, + .fg = DefaultFG, + .bg = DefaultBG + }, .x = 0, .y = 0, .hide = 0}; + term.top = 0, term.bot = term.row - 1; term.mode = MODE_WRAP; tclearregion(0, 0, term.col-1, term.row-1); @@ -337,33 +338,13 @@ treset(void) { void tnew(int col, int row) { - /* screen size */ + /* set screen size */ term.row = row, term.col = col; - term.top = 0, term.bot = term.row - 1; - /* mode */ - term.mode = MODE_WRAP; - /* cursor */ - term.c.attr.mode = ATTR_NULL; - term.c.attr.fg = DefaultFG; - term.c.attr.bg = DefaultBG; - term.c.x = term.c.y = 0; - term.hidec = 0; - /* allocate screen */ - term.line = calloc(term.row, sizeof(Line)); + term.line = malloc(term.row * sizeof(Line)); for(row = 0 ; row < term.row; row++) - term.line[row] = calloc(term.col, sizeof(Glyph)); -} - -/* TODO: Replace with scrollup/scolldown */ -void -tscroll(void) { - Line temp = term.line[term.top]; - int i; - - for(i = term.top; i < term.bot; i++) - term.line[i] = term.line[i+1]; - memset(temp, 0, sizeof(Glyph) * term.col); - term.line[term.bot] = temp; + term.line[row] = malloc(term.col * sizeof(Glyph)); + /* setup screen */ + treset(); } void @@ -403,7 +384,7 @@ void tnewline(void) { int y = term.c.y + 1; if(y > term.bot) - tscroll(), y = term.bot; + tscrollup(1), y = term.bot; tmoveto(0, y); } @@ -730,7 +711,7 @@ csihandle(void) { case 12: /* att610 -- Stop blinking cursor (IGNORED) */ break; case 25: - term.hidec = 1; + term.c.hide = 1; break; case 1048: /* XXX: no alt. screen to erase/save */ case 1049: @@ -779,7 +760,7 @@ csihandle(void) { case 12: /* att610 -- Start blinking cursor (IGNORED) */ break; case 25: - term.hidec = 0; + term.c.hide = 0; break; case 1048: case 1049: /* XXX: no alt. screen to erase/save */ @@ -1078,10 +1059,9 @@ xhints(void) void xinit(void) { - xw.dis = XOpenDisplay(NULL); - xw.scr = XDefaultScreen(xw.dis); - if(!xw.dis) + if(!(xw.dis = XOpenDisplay(NULL))) die("Can't open display\n"); + xw.scr = XDefaultScreen(xw.dis); /* font */ if(!(dc.font = XLoadQueryFont(xw.dis, FONT)) || !(dc.bfont = XLoadQueryFont(xw.dis, BOLDFONT))) @@ -1186,7 +1166,7 @@ draw(int dummy) { if(term.line[y][x].state & GLYPH_SET) xdrawc(x, y, term.line[y][x]); - if(!term.hidec) + if(!term.c.hide) xcursor(CURSOR_DRAW); XCopyArea(xw.dis, xw.buf, xw.win, dc.gc, 0, 0, xw.bufw, xw.bufh, BORDER, BORDER); XFlush(xw.dis); @@ -1219,7 +1199,7 @@ draw(int redraw_all) { } xdraws(buf, base, ox, y, i); } - xcursor(term.hidec ? CURSOR_HIDE : CURSOR_DRAW); + xcursor(term.c.hide ? CURSOR_HIDE : CURSOR_DRAW); XCopyArea(xw.dis, xw.buf, xw.win, dc.gc, 0, 0, xw.bufw, xw.bufh, BORDER, BORDER); XFlush(xw.dis); } @@ -1314,7 +1294,7 @@ run(void) { FD_ZERO(&rfd); FD_SET(cmdfd, &rfd); FD_SET(xfd, &rfd); - if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, NULL) == -1) { + if(select(MAX(xfd, cmdfd)+1, &rfd, NULL, NULL, NULL) < 0) { if(errno == EINTR) continue; die("select failed: %s\n", SERRNO);