term: add ICH
[fbpad.git] / term.c
blobf3b4c39be37a64254a2647edded18c03f0ec9566
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 memset(SQRADDR(row, sc), 0, (ec - sc) * sizeof(screen[0]));
174 for (i = sc; i < ec; i++)
175 term_show(row, i, 0);
176 move_cursor(row, col);
179 static void move_chars(int sc, int nc, int n)
181 int i;
182 term_show(row, col, 0);
183 memmove(SQRADDR(row, sc + n), SQRADDR(row, sc),
184 nc * sizeof(screen[0]));
185 if (n > 0)
186 memset(SQRADDR(row, sc), 0, n * sizeof(screen[0]));
187 else
188 memset(SQRADDR(row, pad_rows() + n), 0, -n * sizeof(screen[0]));
189 for (i = MIN(sc, sc + n); i < pad_cols(); i++)
190 term_show(row, i, 0);
191 term_show(row, col, 1);
194 static void delete_chars(int n)
196 move_chars(col + n, pad_cols(), -n);
199 static void insert_chars(int n)
201 int nc = pad_cols() - col - n;
202 move_chars(col, nc, n);
205 void term_blank(void)
207 pad_blank(bg);
208 memset(screen, 0, sizeof(screen));
211 static void ctlseq(void);
212 void term_read(void)
214 ctlseq();
217 void term_exec(char *cmd)
219 if ((pid = forkpty(&fd, NULL, NULL, NULL)) == -1)
220 xerror("failed to create a pty");
221 if (!pid) {
222 setenv("TERM", "linux", 1);
223 execl(cmd, cmd, NULL);
224 exit(1);
226 setsize();
227 setmode(0);
228 term_blank();
231 void term_save(struct term_state *state)
233 state->row = row;
234 state->col = col;
235 state->fd = fd;
236 state->pid = pid;
237 state->fg = fg;
238 state->bg = bg;
239 memcpy(state->screen, screen,
240 pad_rows() * pad_cols() * sizeof(screen[0]));
243 void term_load(struct term_state *state)
245 int i;
246 row = state->row;
247 col = state->col;
248 fd = state->fd;
249 pid = state->pid;
250 fg = state->fg;
251 bg = state->bg;
252 memcpy(screen, state->screen,
253 pad_rows() * pad_cols() * sizeof(screen[0]));
254 for (i = 0; i < pad_rows() * pad_cols(); i++)
255 term_show(i / pad_cols(), i % pad_cols(), 0);
256 term_show(row, col, 1);
259 int term_fd(void)
261 return fd;
264 void term_init(void)
266 pad_init();
267 bot = pad_rows();
268 term_blank();
271 void term_free(void)
273 pad_free();
276 void term_end(void)
278 fd = 0;
279 row = col = 0;
280 fg = 0;
281 bg = 0;
282 term_blank();
285 #include "vt102.c"