X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=demo%2Fboxshell.c;h=76af9146ec6359744a719c820eea09f7e17f0f1a;hb=2ce3ba8535147bd21ce80c140afb13083dd5d289;hp=b3c8f2d9d033c20c1357f901962c1492e55ef7c3;hpb=058608e1586891e4e40beb8785a3317957658365;p=apps%2Fmadtty.git diff --git a/demo/boxshell.c b/demo/boxshell.c index b3c8f2d..76af914 100644 --- a/demo/boxshell.c +++ b/demo/boxshell.c @@ -6,36 +6,68 @@ */ #include -#include + +#include #include +#include #include +#include #include +#include #include #include -static unsigned char getout = 0; +static int getout = 0, sigwinch = 0; static int screen_w, screen_h; static WINDOW *term_win; +static struct timeval const slice = { 0, 1000 * 1000 / 100 }; + +void handler(int signo) +{ + switch (signo) { + case SIGCHLD: + getout = 1; + break; + case SIGWINCH: + sigwinch = 1; + break; + } +} + +static struct timeval timeval_add(struct timeval a, struct timeval b) +{ + int usec = a.tv_usec + b.tv_usec; + a.tv_sec += b.tv_sec; + while (usec > 1000 * 1000) { + a.tv_sec += 1; + usec -= 1000 * 1000; + } + a.tv_usec = usec; + return a; +} -void sigchld(int signo __attribute__((unused))) +static int is_expired(struct timeval now, struct timeval expiry) { - getout = 1; + return now.tv_sec > expiry.tv_sec + || (now.tv_sec == expiry.tv_sec && now.tv_usec > expiry.tv_usec); } int main(void) { - struct timeval next = { 0, 0 }; madtty_t *rt; + int dirty = 0; + struct timeval next; - signal(SIGCHLD, sigchld); + signal(SIGCHLD, handler); + signal(SIGWINCH, handler); madtty_initialize(); getmaxyx(stdscr, screen_h, screen_w); /* create a window with a frame */ term_win = newwin(screen_h - 2, screen_w - 2, 1, 1); - rt = madtty_create(screen_h - 2, screen_w - 2); + rt = madtty_create(screen_h - 2, screen_w -2); { const char *path = getenv("SHELL") ?: "/bin/sh"; const char *args[] = { path, "--login", NULL}; @@ -45,33 +77,59 @@ int main(void) /* keep reading keypresses from the user and passing them to the terminal; * also, redraw the terminal to the window at each iteration */ + gettimeofday(&next, NULL); while (!getout) { + struct timeval tv = { 0, 1000 * 1000 / 100 }; fd_set rfds; - struct timeval tv = { 0 , 1000 }, t; int ch; FD_ZERO(&rfds); + FD_SET(0, &rfds); FD_SET(rt->pty, &rfds); if (select(rt->pty + 1, &rfds, NULL, NULL, &tv) > 0) { - if (madtty_process(rt)) - break; + if (FD_ISSET(rt->pty, &rfds)) { + madtty_process(rt); + dirty = 1; + } + } + + if (sigwinch) { + int fd, cols = -1, rows = -1; + struct winsize w; + + if ((fd = open("/dev/tty", O_RDONLY)) != -1) { + if (ioctl(fd, TIOCGWINSZ, &w) != -1) { + rows = w.ws_row; + cols = w.ws_col; + } + close(fd); + } + if (rows <= 0) { + rows = atoi(getenv("LINES") ?: "24"); + } + if (cols <= 0) { + cols = atoi(getenv("COLUMNS") ?: "80"); + } + + resizeterm(rows, cols); + madtty_resize(rt, rows - 2, cols - 2); + wresize(term_win, rows - 2, cols - 2); + sigwinch = 0; + erase(); } while ((ch = getch()) != ERR) { madtty_keypress(rt, ch); /* pass the keypress for handling */ + dirty = 1; } - gettimeofday(&t, NULL); - if (timercmp(&t, &next, >=)) { + gettimeofday(&tv, NULL); + if (dirty && is_expired(tv, next)) { madtty_draw(rt, term_win, 0, 0); wrefresh(term_win); - gettimeofday(&next, NULL); - next.tv_usec += 1000 * 1000 / 50; - if (next.tv_usec > 1000 * 1000) { - next.tv_usec -= 1000 * 1000; - next.tv_sec++; - } + dirty = 0; + next = timeval_add(tv, slice); } }