term: handle DA command
[fbpad.git] / term.c
bloba3130b6fb12b419a12c0a327c4e639b64698d540
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, nowrap;
23 static int saved_row, saved_col, saved_fg, saved_bg;
25 static void setsize(void)
27 struct winsize size;
28 size.ws_col = pad_cols();
29 size.ws_row = pad_rows();
30 size.ws_xpixel = 0;
31 size.ws_ypixel = 0;
32 ioctl(fd, TIOCSWINSZ, &size);
35 static int readpty(void)
37 char b;
38 if (read(fd, &b, 1) > 0)
39 return (int) b;
40 return -1;
43 static void term_show(int r, int c, int cursor)
45 struct square *sqr = SQRADDR(r, c);
46 int fgcolor = sqr->c ? sqr->fg : fg;
47 int bgcolor = sqr->c ? sqr->bg : bg;
48 if (cursor && !nocursor) {
49 int t = fgcolor;
50 fgcolor = bgcolor;
51 bgcolor = t;
53 pad_put(sqr->c, r, c, fgcolor, bgcolor);
56 void term_put(int ch, int r, int c)
58 struct square *sqr = SQRADDR(r, c);
59 sqr->c = ch;
60 sqr->fg = fg;
61 sqr->bg = bg;
62 term_show(r, c, 0);
65 static void empty_rows(int sr, int er)
67 memset(SQRADDR(sr, 0), 0, (er - sr) * sizeof(screen[0]) * pad_cols());
70 static void blank_rows(int sr, int er)
72 int i;
73 empty_rows(sr, er);
74 for (i = sr * pad_cols(); i < er * pad_cols(); i++)
75 term_show(i / pad_cols(), i % pad_cols(), 0);
76 term_show(row, col, 1);
79 static void scroll_screen(int sr, int nr, int n)
81 term_show(row, col, 0);
82 memmove(SQRADDR(sr + n, 0), SQRADDR(sr, 0),
83 nr * pad_cols() * sizeof(screen[0]));
84 if (n > 0)
85 empty_rows(sr, sr + n);
86 else
87 empty_rows(sr + nr + n, sr + nr);
88 pad_scroll(sr, nr, n, bg);
89 term_show(row, col, 1);
92 static void insert_lines(int n)
94 int sr = MAX(top, row);
95 int nr = bot - row - n;
96 if (nr > 0)
97 scroll_screen(sr, nr, n);
100 static void delete_lines(int n)
102 int r = MAX(top, row);
103 int sr = r + n;
104 int nr = bot - r - n;
105 if (nr > 0)
106 scroll_screen(sr, nr, -n);
109 static void move_cursor(int r, int c)
111 term_show(row, col, 0);
112 if (c >= pad_cols()) {
113 if (nowrap) {
114 c = pad_cols() - 1;
115 } else {
116 r++;
117 c = 0;
120 if (r >= bot) {
121 int n = bot - r - 1;
122 int nr = (bot - top) + n;
123 scroll_screen(-n, nr, n);
124 r = bot - 1;
126 row = MAX(0, MIN(r, pad_rows() - 1));
127 col = MAX(0, MIN(c, pad_cols() - 1));
128 term_show(row, col, 1);
131 static void advance(int dr, int dc)
133 int r = row + dr;
134 int c = col + dc;
135 move_cursor(MAX(0, r), MAX(0, c));
138 void term_send(int c)
140 unsigned char b = (unsigned char) c;
141 if (fd)
142 write(fd, &b, 1);
145 void term_sendstr(char *s)
147 if (fd)
148 write(fd, s, strlen(s));
151 static void setmode(int m)
153 if (m == 0) {
154 fg = FGCOLOR;
155 bg = BGCOLOR;
157 if (m == 1)
158 fg = fg | 0x08;
159 if (m == 7) {
160 int t = fg;
161 fg = bg;
162 bg = t;
164 if (m >= 30 && m <= 37)
165 fg = m - 30;
166 if (m >= 40 && m <= 47)
167 bg = m - 40;
170 static void kill_chars(int sc, int ec)
172 int i;
173 memmove(SQRADDR(row, sc), SQRADDR(row, ec),
174 (pad_cols() - ec) * sizeof(screen[0]));
175 memset(SQRADDR(row, sc + pad_cols() - ec), 0,
176 (ec - sc) * sizeof(screen[0]));
177 for (i = col; i < pad_cols(); i++)
178 term_show(row, i, 0);
179 move_cursor(row, col);
182 void term_blank(void)
184 pad_blank(bg);
185 memset(screen, 0, sizeof(screen));
188 static void ctlseq(void);
189 void term_read(void)
191 ctlseq();
194 void term_exec(char *cmd)
196 if ((pid = forkpty(&fd, NULL, NULL, NULL)) == -1)
197 xerror("failed to create a pty");
198 if (!pid) {
199 setenv("TERM", "linux", 1);
200 execl(cmd, cmd, NULL);
201 exit(1);
203 setsize();
204 setmode(0);
205 term_blank();
208 void term_save(struct term_state *state)
210 state->row = row;
211 state->col = col;
212 state->fd = fd;
213 state->pid = pid;
214 state->fg = fg;
215 state->bg = bg;
216 memcpy(state->screen, screen,
217 pad_rows() * pad_cols() * sizeof(screen[0]));
220 void term_load(struct term_state *state)
222 int i;
223 row = state->row;
224 col = state->col;
225 fd = state->fd;
226 pid = state->pid;
227 fg = state->fg;
228 bg = state->bg;
229 memcpy(screen, state->screen,
230 pad_rows() * pad_cols() * sizeof(screen[0]));
231 for (i = 0; i < pad_rows() * pad_cols(); i++)
232 term_show(i / pad_cols(), i % pad_cols(), 0);
233 term_show(row, col, 1);
236 int term_fd(void)
238 return fd;
241 void term_init(void)
243 pad_init();
244 bot = pad_rows();
245 term_blank();
248 void term_free(void)
250 pad_free();
253 void term_end(void)
255 fd = 0;
256 row = col = 0;
257 fg = 0;
258 bg = 0;
259 term_blank();
262 #include "vt102.c"