fbpad: write to stdin to hide the cursor
[fbpad.git] / fbpad.c
blob8cdc285a88ceb4a668ca281f917c50fd49d144ef
1 #include <errno.h>
2 #include <poll.h>
3 #include <pty.h>
4 #include <signal.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <linux/vt.h>
8 #include <fcntl.h>
9 #include "pad.h"
10 #include "term.h"
11 #include "util.h"
13 #define SHELL "/bin/bash"
14 #define TAGS 8
15 #define CTRLKEY(x) ((x) - 96)
17 static struct term_state terms[TAGS * 2];
18 static int cterm; /* current tag */
19 static int lterm; /* last tag */
20 static int exitit;
22 static int readchar(void)
24 char b;
25 if (read(STDIN_FILENO, &b, 1) > 0)
26 return (int) b;
27 return -1;
30 static void showterm(int n)
32 if (lterm % TAGS != cterm % TAGS)
33 lterm = cterm;
34 term_save(&terms[cterm]);
35 cterm = n;
36 term_load(&terms[cterm]);
39 static void directkey(void)
41 int c = readchar();
42 if (c == ESC) {
43 switch ((c = readchar())) {
44 case 'c':
45 if (!term_fd())
46 term_exec(SHELL);
47 return;
48 case 'j':
49 case 'k':
50 showterm((cterm + TAGS) % ARRAY_SIZE(terms));
51 return;
52 case 'o':
53 showterm(lterm);
54 return;
55 case CTRLKEY('q'):
56 exitit = 1;
57 return;
58 default:
59 term_send(ESC);
62 if (c != -1)
63 term_send(c);
66 static void mainloop(void)
68 struct pollfd ufds[2];
69 int rv;
70 struct termios oldtermios, termios;
71 tcgetattr(STDIN_FILENO, &termios);
72 oldtermios = termios;
73 cfmakeraw(&termios);
74 tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios);
75 memset(ufds, 0, sizeof(ufds));
76 ufds[0].fd = STDIN_FILENO;
77 ufds[0].events = POLLIN;
78 ufds[1].fd = term_fd();
79 ufds[1].events = POLLIN;
80 while (!exitit) {
81 rv = poll(ufds, term_fd() ? 2 : 1, 1000);
82 if (rv == -1 && errno != EINTR)
83 break;
84 if (ufds[0].revents & (POLLHUP | POLLERR | POLLNVAL))
85 break;
86 if (term_fd() && ufds[1].revents & (POLLHUP | POLLERR | POLLNVAL))
87 term_end();
88 if (term_fd() && ufds[1].revents & POLLIN)
89 term_read();
90 if (ufds[0].revents & POLLIN)
91 directkey();
92 ufds[1].fd = term_fd();
94 tcsetattr(STDIN_FILENO, 0, &oldtermios);
97 static void signalreceived(int n)
99 if (exitit)
100 return;
101 switch (n) {
102 case SIGUSR1:
103 term_save(&terms[cterm]);
104 ioctl(STDIN_FILENO, VT_RELDISP, 1);
105 break;
106 case SIGUSR2:
107 pad_shown();
108 term_load(&terms[cterm]);
109 break;
113 static void setupsignals(void)
115 struct vt_mode vtm;
116 vtm.mode = VT_PROCESS;
117 vtm.waitv = 0;
118 vtm.relsig = SIGUSR1;
119 vtm.acqsig = SIGUSR2;
120 vtm.frsig = 0;
121 ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
123 signal(SIGUSR1, signalreceived);
124 signal(SIGUSR2, signalreceived);
127 int main(void)
129 char *hide = "\x1b[?25l";
130 char *clear = "\x1b[2J\x1b[H";
131 char *show = "\x1b[?25h";
132 write(STDIN_FILENO, clear, strlen(clear));
133 write(STDIN_FILENO, hide, strlen(hide));
134 term_init();
135 term_blank();
136 setupsignals();
137 fcntl(STDIN_FILENO, F_SETFL,
138 fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
139 mainloop();
140 term_free();
141 write(STDIN_FILENO, show, strlen(show));
142 return 0;