term: enable hiding the cursor
[fbpad.git] / term.c
blob60ac0b1055a644751afabc09d36cba515cf0ecb4
1 #include <ctype.h>
2 #include <pty.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8 #include "pad.h"
9 #include "util.h"
10 #include "term.h"
12 #define FGCOLOR 0
13 #define BGCOLOR 7
14 #define SQRADDR(r, c) (&screen[(r) * pad_cols() + (c)])
16 static pid_t pid;
17 static int fd;
18 static int row, col;
19 static int fg, bg;
20 static struct square screen[MAXCHARS];
21 static int top, bot;
22 static int nocursor;
24 static void setsize(void)
26 struct winsize size;
27 size.ws_col = pad_cols();
28 size.ws_row = pad_rows();
29 size.ws_xpixel = 0;
30 size.ws_ypixel = 0;
31 ioctl(fd, TIOCSWINSZ, &size);
34 static int readpty(void)
36 char b;
37 if (read(fd, &b, 1) > 0)
38 return (int) b;
39 return -1;
42 static void term_show(int r, int c, int cursor)
44 struct square *sqr = SQRADDR(r, c);
45 int fgcolor = sqr->c ? sqr->fg : fg;
46 int bgcolor = sqr->c ? sqr->bg : bg;
47 if (cursor && !nocursor) {
48 int t = fgcolor;
49 fgcolor = bgcolor;
50 bgcolor = t;
52 pad_put(sqr->c, r, c, fgcolor, bgcolor);
55 void term_put(int ch, int r, int c)
57 struct square *sqr = SQRADDR(r, c);
58 sqr->c = ch;
59 sqr->fg = fg;
60 sqr->bg = bg;
61 term_show(r, c, 0);
64 static void empty_rows(int sr, int er)
66 memset(SQRADDR(sr, 0), 0, (er - sr) * sizeof(screen[0]) * pad_cols());
69 static void blank_rows(int sr, int er)
71 int i;
72 empty_rows(sr, er);
73 for (i = sr * pad_cols(); i < er * pad_cols(); i++)
74 term_show(i / pad_cols(), i % pad_cols(), 0);
75 term_show(row, col, 1);
78 static void scroll_screen(int sr, int nr, int n)
80 term_show(row, col, 0);
81 memmove(SQRADDR(sr + n, 0), SQRADDR(sr, 0),
82 nr * pad_cols() * sizeof(screen[0]));
83 if (n > 0)
84 empty_rows(sr, sr + n);
85 else
86 empty_rows(sr + nr + n, sr + nr);
87 pad_scroll(sr, nr, n, bg);
88 term_show(row, col, 1);
91 static void insert_lines(int n)
93 int sr = MAX(top, row);
94 int nr = bot - row - n;
95 if (nr > 0)
96 scroll_screen(sr, nr, n);
99 static void delete_lines(int n)
101 int r = MAX(top, row);
102 int sr = r + n;
103 int nr = bot - r - n;
104 if (nr > 0)
105 scroll_screen(sr, nr, -n);
108 static void move_cursor(int r, int c)
110 term_show(row, col, 0);
111 if (c >= pad_cols()) {
112 r++;
113 c = 0;
115 if (r >= bot) {
116 int n = bot - r - 1;
117 int nr = (bot - top) + n;
118 scroll_screen(-n, nr, n);
119 r = bot - 1;
121 row = MAX(0, MIN(r, pad_rows() - 1));
122 col = MAX(0, MIN(c, pad_cols() - 1));
123 term_show(row, col, 1);
126 static void advance(int dr, int dc)
128 int r = row + dr;
129 int c = col + dc;
130 move_cursor(MAX(0, r), MAX(0, c));
133 void term_send(int c)
135 unsigned char b = (unsigned char) c;
136 if (fd)
137 write(fd, &b, 1);
140 static void setmode(int m)
142 if (m == 0) {
143 fg = FGCOLOR;
144 bg = BGCOLOR;
146 if (m == 1)
147 fg = fg | 0x08;
148 if (m == 7) {
149 int t = fg;
150 fg = bg;
151 bg = t;
153 if (m >= 30 && m <= 37)
154 fg = m - 30;
155 if (m >= 40 && m <= 47)
156 bg = m - 40;
159 static void kill_chars(int sc, int ec)
161 int i;
162 memmove(SQRADDR(row, sc), SQRADDR(row, ec),
163 (pad_cols() - ec) * sizeof(screen[0]));
164 memset(SQRADDR(row, sc + pad_cols() - ec), 0,
165 (ec - sc) * sizeof(screen[0]));
166 for (i = col; i < pad_cols(); i++)
167 term_show(row, i, 0);
168 move_cursor(row, col);
171 void term_blank(void)
173 pad_blank(bg);
174 memset(screen, 0, sizeof(screen));
177 static void ctlseq(void);
178 void term_read(void)
180 ctlseq();
183 void term_exec(char *cmd)
185 if ((pid = forkpty(&fd, NULL, NULL, NULL)) == -1)
186 xerror("failed to create a pty");
187 if (!pid) {
188 setenv("TERM", "linux", 1);
189 execl(cmd, cmd, NULL);
190 exit(1);
192 setsize();
193 setmode(0);
194 term_blank();
197 void term_save(struct term_state *state)
199 state->row = row;
200 state->col = col;
201 state->fd = fd;
202 state->pid = pid;
203 state->fg = fg;
204 state->bg = bg;
205 memcpy(state->screen, screen,
206 pad_rows() * pad_cols() * sizeof(screen[0]));
209 void term_load(struct term_state *state)
211 int i;
212 row = state->row;
213 col = state->col;
214 fd = state->fd;
215 pid = state->pid;
216 fg = state->fg;
217 bg = state->bg;
218 memcpy(screen, state->screen,
219 pad_rows() * pad_cols() * sizeof(screen[0]));
220 for (i = 0; i < pad_rows() * pad_cols(); i++)
221 term_show(i / pad_cols(), i % pad_cols(), 0);
222 term_show(row, col, 1);
225 int term_fd(void)
227 return fd;
230 void term_init(void)
232 pad_init();
233 bot = pad_rows();
234 term_blank();
237 void term_free(void)
239 pad_free();
242 void term_end(void)
244 fd = 0;
245 row = col = 0;
246 fg = 0;
247 bg = 0;
248 term_blank();
251 #include "vt102.c"