summaryrefslogtreecommitdiff
path: root/ui.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui.c')
-rw-r--r--ui.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/ui.c b/ui.c
new file mode 100644
index 0000000..4578240
--- /dev/null
+++ b/ui.c
@@ -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));
+}