2 * fbpad - A small linux framebuffer virtual terminal
4 * Copyright (C) 2009 Ali Gholami Rudi
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License, as published by the
8 * Free Software Foundation.
26 #define CTRLKEY(x) ((x) - 96)
27 #define BADPOLLFLAGS (POLLHUP | POLLERR | POLLNVAL)
28 #define NTAGS sizeof(tags)
30 static char tags
[] = TAGS
;
31 static struct term terms
[NTAGS
* 2];
32 static int cterm
; /* current tag */
33 static int lterm
; /* last tag */
37 static int readchar(void)
40 if (read(STDIN_FILENO
, &b
, 1) > 0)
45 static void showterm(int n
)
47 if (cterm
% NTAGS
!= n
% NTAGS
)
49 term_save(&terms
[cterm
]);
51 term_load(&terms
[cterm
], hidden
? TERM_HIDDEN
: TERM_REDRAW
);
54 static struct term
*mainterm(void)
61 static void exec_cmd(char *file
)
67 static int altterm(int n
)
69 return n
< NTAGS
? n
+ NTAGS
: n
- NTAGS
;
72 static void nextterm(void)
74 int n
= (cterm
+ 1) % ARRAY_SIZE(terms
);
80 n
= (n
+ 1) % ARRAY_SIZE(terms
);
84 static void showterms(void)
86 int colors
[] = {FGCOLOR
, 4, 2, 5};
88 int r
= pad_rows() - 1;
90 pad_put('T', r
, c
++, FGCOLOR
, BGCOLOR
);
91 pad_put('A', r
, c
++, FGCOLOR
, BGCOLOR
);
92 pad_put('G', r
, c
++, FGCOLOR
, BGCOLOR
);
93 pad_put('S', r
, c
++, FGCOLOR
, BGCOLOR
);
94 pad_put(':', r
, c
++, FGCOLOR
, BGCOLOR
);
95 pad_put(' ', r
, c
++, FGCOLOR
, BGCOLOR
);
96 for (i
= 0; i
< NTAGS
; i
++) {
98 int shown
= i
== cterm
|| altterm(i
) == cterm
;
101 if (terms
[altterm(i
)].fd
)
103 pad_put(shown
? '(' : ' ', r
, c
++, FGCOLOR
, BGCOLOR
);
104 pad_put(tags
[i
], r
, c
++, colors
[nt
], 7);
105 pad_put(shown
? ')' : ' ', r
, c
++, FGCOLOR
, BGCOLOR
);
109 static void directkey(void)
113 switch ((c
= readchar())) {
125 showterm(altterm(cterm
));
143 if (strchr(tags
, c
)) {
144 showterm(strchr(tags
, c
) - tags
);
151 if (c
!= -1 && mainterm())
155 static int find_by_fd(int fd
)
158 for (i
= 0; i
< ARRAY_SIZE(terms
); i
++)
159 if (terms
[i
].fd
== fd
)
164 static int fill_ufds(struct pollfd
*ufds
)
168 ufds
[0].fd
= STDIN_FILENO
;
169 ufds
[0].events
= POLLIN
;
170 for (i
= 0; i
< ARRAY_SIZE(terms
); i
++) {
172 ufds
[n
].fd
= terms
[i
].fd
;
173 ufds
[n
].events
= POLLIN
;
180 static void temp_switch(int termid
)
182 if (termid
!= cterm
) {
183 term_save(&terms
[cterm
]);
184 term_load(&terms
[termid
], TERM_HIDDEN
);
188 static void switch_back(int termid
)
190 if (termid
!= cterm
) {
191 term_save(&terms
[termid
]);
192 term_load(&terms
[cterm
], hidden
? TERM_HIDDEN
: TERM_VISIBLE
);
196 static void check_ufds(struct pollfd
*ufds
, int n
)
199 for (i
= 1; i
< n
; i
++) {
200 int idx
= find_by_fd(ufds
[i
].fd
);
201 if (ufds
[i
].revents
& BADPOLLFLAGS
) {
205 } else if (ufds
[i
].revents
& POLLIN
) {
213 static void mainloop(void)
215 struct pollfd ufds
[ARRAY_SIZE(terms
) + 1];
216 struct termios oldtermios
, termios
;
219 tcgetattr(STDIN_FILENO
, &termios
);
220 oldtermios
= termios
;
222 tcsetattr(STDIN_FILENO
, TCSAFLUSH
, &termios
);
223 memset(ufds
, 0, sizeof(ufds
));
224 term_load(&terms
[cterm
], TERM_REDRAW
);
227 rv
= poll(ufds
, n
, 1000);
228 if (rv
== -1 && errno
!= EINTR
)
230 if (ufds
[0].revents
& BADPOLLFLAGS
)
232 if (ufds
[0].revents
& POLLIN
)
237 tcsetattr(STDIN_FILENO
, 0, &oldtermios
);
240 static void signalreceived(int n
)
247 term_save(&terms
[cterm
]);
248 term_load(&terms
[cterm
], TERM_HIDDEN
);
249 ioctl(STDIN_FILENO
, VT_RELDISP
, 1);
254 term_save(&terms
[cterm
]);
255 term_load(&terms
[cterm
], TERM_REDRAW
);
258 while (waitpid(-1, 0, WNOHANG
) > 0)
264 static void setupsignals(void)
267 vtm
.mode
= VT_PROCESS
;
269 vtm
.relsig
= SIGUSR1
;
270 vtm
.acqsig
= SIGUSR2
;
272 ioctl(STDIN_FILENO
, VT_SETMODE
, &vtm
);
274 signal(SIGUSR1
, signalreceived
);
275 signal(SIGUSR2
, signalreceived
);
276 signal(SIGCHLD
, signalreceived
);
281 char *hide
= "\x1b[?25l";
282 char *clear
= "\x1b[2J\x1b[H";
283 char *show
= "\x1b[?25h";
284 setlocale(LC_ALL
, "");
285 write(STDIN_FILENO
, clear
, strlen(clear
));
286 write(STDIN_FILENO
, hide
, strlen(hide
));
289 fcntl(STDIN_FILENO
, F_SETFL
,
290 fcntl(STDIN_FILENO
, F_GETFL
) | O_NONBLOCK
);
293 write(STDIN_FILENO
, show
, strlen(show
));