font: check sr and sc when copying bitmap
[fbpad.git] / fbpad.c
blob53285e3cb871e77a5d0989c5b6b5a45530646da2
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 MAIL "mutt"
15 #define EDITOR "vim"
16 #define TAGS 8
17 #define CTRLKEY(x) ((x) - 96)
18 #define BADPOLLFLAGS (POLLHUP | POLLERR | POLLNVAL)
21 static struct term terms[TAGS * 2];
22 static int cterm; /* current tag */
23 static int lterm; /* last tag */
24 static int exitit;
26 static int readchar(void)
28 char b;
29 if (read(STDIN_FILENO, &b, 1) > 0)
30 return (int) b;
31 return -1;
34 static void showterm(int n)
36 if (cterm % TAGS != n % TAGS)
37 lterm = cterm;
38 term_save(&terms[cterm]);
39 cterm = n;
40 term_load(&terms[cterm], TERM_REDRAW);
43 static struct term *mainterm(void)
45 if (terms[cterm].fd)
46 return &terms[cterm];
47 return NULL;
50 static void exec_cmd(char *file)
52 if (!mainterm())
53 term_exec(file);
56 static void directkey(void)
58 int c = readchar();
59 char *tags = "xnlhtrv-";
60 if (c == ESC) {
61 switch ((c = readchar())) {
62 case 'c':
63 exec_cmd(SHELL);
64 return;
65 case 'm':
66 exec_cmd(MAIL);
67 return;
68 case 'e':
69 exec_cmd(EDITOR);
70 return;
71 case 'j':
72 case 'k':
73 showterm(cterm < TAGS ? cterm + TAGS : cterm - TAGS);
74 return;
75 case 'o':
76 showterm(lterm);
77 return;
78 case CTRLKEY('q'):
79 exitit = 1;
80 return;
81 default:
82 if (strchr(tags, c)) {
83 showterm(strchr(tags, c) - tags);
84 return;
86 if (mainterm())
87 term_send(ESC);
90 if (c != -1 && mainterm())
91 term_send(c);
94 static int find_by_fd(int fd)
96 int i;
97 for (i = 0; i < ARRAY_SIZE(terms); i++)
98 if (terms[i].fd == fd)
99 return i;
100 return -1;
103 static int fill_ufds(struct pollfd *ufds)
105 int n = 1;
106 int i;
107 ufds[0].fd = STDIN_FILENO;
108 ufds[0].events = POLLIN;
109 for (i = 0; i < ARRAY_SIZE(terms); i++) {
110 if (terms[i].fd) {
111 ufds[n].fd = terms[i].fd;
112 ufds[n].events = POLLIN;
113 n++;
116 return n;
119 static void temp_switch(int termid)
121 if (termid != cterm) {
122 term_save(&terms[cterm]);
123 term_load(&terms[termid], TERM_HIDDEN);
127 static void switch_back(int termid)
129 if (termid != cterm) {
130 term_save(&terms[termid]);
131 term_load(&terms[cterm], TERM_VISIBLE);
135 static void check_ufds(struct pollfd *ufds, int n)
137 int i;
138 for (i = 1; i < n; i++) {
139 int idx = find_by_fd(ufds[i].fd);
140 if (ufds[i].revents & BADPOLLFLAGS) {
141 temp_switch(idx);
142 term_end();
143 switch_back(idx);
145 if (ufds[i].revents & POLLIN) {
146 temp_switch(idx);
147 term_read();
148 switch_back(idx);
153 static void mainloop(void)
155 struct pollfd ufds[ARRAY_SIZE(terms) + 1];
156 struct termios oldtermios, termios;
157 int rv;
158 int n;
159 tcgetattr(STDIN_FILENO, &termios);
160 oldtermios = termios;
161 cfmakeraw(&termios);
162 tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios);
163 memset(ufds, 0, sizeof(ufds));
164 term_load(&terms[cterm], TERM_REDRAW);
165 n = fill_ufds(ufds);
166 while (!exitit) {
167 rv = poll(ufds, n, 1000);
168 if (rv == -1 && errno != EINTR)
169 break;
170 if (ufds[0].revents & BADPOLLFLAGS)
171 break;
172 if (ufds[0].revents & POLLIN)
173 directkey();
174 check_ufds(ufds, n);
175 n = fill_ufds(ufds);
177 tcsetattr(STDIN_FILENO, 0, &oldtermios);
180 static void signalreceived(int n)
182 if (exitit)
183 return;
184 switch (n) {
185 case SIGUSR1:
186 term_save(&terms[cterm]);
187 ioctl(STDIN_FILENO, VT_RELDISP, 1);
188 break;
189 case SIGUSR2:
190 pad_shown();
191 term_load(&terms[cterm], TERM_REDRAW);
192 break;
196 static void setupsignals(void)
198 struct vt_mode vtm;
199 vtm.mode = VT_PROCESS;
200 vtm.waitv = 0;
201 vtm.relsig = SIGUSR1;
202 vtm.acqsig = SIGUSR2;
203 vtm.frsig = 0;
204 ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
206 signal(SIGUSR1, signalreceived);
207 signal(SIGUSR2, signalreceived);
210 int main(void)
212 char *hide = "\x1b[?25l";
213 char *clear = "\x1b[2J\x1b[H";
214 char *show = "\x1b[?25h";
215 write(STDIN_FILENO, clear, strlen(clear));
216 write(STDIN_FILENO, hide, strlen(hide));
217 pad_init();
218 setupsignals();
219 fcntl(STDIN_FILENO, F_SETFL,
220 fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK);
221 mainloop();
222 pad_free();
223 write(STDIN_FILENO, show, strlen(show));
224 return 0;