#include #include #include #include #include #include #include #include "util.h" #include "ui.h" #define MAX_STATUS 128 static char stbuf[MAX_STATUS]; static unsigned short rows; static unsigned short cols; static struct termios prevstate; static int tty_fd; int uiinit(const State *state) { struct winsize w; struct termios t; if ((tty_fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) die("getpass: can't open /dev/tty for input"); tcgetattr(tty_fd, &t); prevstate = t; if (state->flag & IGNORE_ISIG) t.c_lflag &= ~(ISIG); t.c_lflag &= ~(ECHO|INLCR|IGNCR|ICANON); t.c_iflag |= ICRNL; tcsetattr(tty_fd, TCSAFLUSH, &t); tcdrain(tty_fd); if (ioctl(STDIN_FILENO, TIOCGWINSZ, &w) == -1) die("ioctl() failed"); rows = w.ws_row; cols = w.ws_col; printf("%c7", ESC); /* save cursor */ printf("%c[?47h", ESC); /* use alt buffer */ printf("%c[?25l", ESC); /* hide cursor */ printf("%c[2J", ESC); /* clear vt */ return tty_fd; } void pheader(const char *s) { unsigned short col, row; row = rows / 2; col = (cols - strlen(s)) / 2; printf("%c[%d;%dH", ESC, row, col); /* pos curosr */ printf("%c[2K", ESC); /* clear line */ puts(s); } void pstatus(const char *s) { unsigned short col, row; row = rows / 2 + 1; col = (cols - strlen(s)) / 2; printf("%c[%d;%dH", ESC, row, col); /* pos cursor */ printf("%c[2K", ESC); /* clear line */ puts(s); } void pstaticstat(const char *head, const char c) { size_t stlen; if ((stlen = strlen(head)) > MAX_STATUS - 1) stlen = MAX_STATUS - 1; stbuf[stlen] = '\0'; memset(stbuf, c, stlen); pstatus(stbuf); } void genrandstat(const char *head, const char *statstr) { int entropy; size_t srlen, stlen, i; if ((stlen = strlen(head)) > MAX_STATUS - 1) stlen = MAX_STATUS - 1; srlen = strlen(statstr); for (entropy = i = 0; i < stlen; ++i, entropy /= srlen) { if (!entropy) entropy = rand(); stbuf[i] = statstr[entropy % srlen]; } stbuf[stlen] = '\0'; pstatus(stbuf); } void uicleanup(void) { printf("%c[2J", ESC); /* clear vt */ printf("%c[?25h", ESC); /* show cursor */ printf("%c[?47l", ESC); /* use normal buffer */ printf("%c8", ESC); /* restore cursor */ tcsetattr(tty_fd, TCSAFLUSH, &prevstate); close(tty_fd); } void pui(const char *head, const char stat) { size_t stlen; if ((stlen = strlen(head)) > MAX_STATUS - 1) stlen = MAX_STATUS - 1; stbuf[stlen] = '\0'; pheader(head); pstatus(memset(stbuf, stat, stlen)); }