diff options
Diffstat (limited to 'ui.c')
-rw-r--r-- | ui.c | 129 |
1 files changed, 129 insertions, 0 deletions
@@ -0,0 +1,129 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/ioctl.h> +#include <termios.h> +#include <fcntl.h> + +#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)); +} |