vt100.c - libvt100 - A library for heling in console programming.
(HTM) git clone git://r-36.net/libvt100
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
vt100.c (6538B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #include <termios.h>
7 #include <unistd.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <stdarg.h>
11 #include <string.h>
12 #include <strings.h>
13
14 #include "vt100.h"
15
16 termwin_t *
17 termwin_new(term_t *term, int r, int c, int rows, int cols)
18 {
19 termwin_t *win;
20
21 win = malloc(sizeof(termwin_t));
22 if (win == NULL)
23 return NULL;
24 bzero(win, sizeof(win));
25
26 win->r = r;
27 win->c = c;
28 win->rows = rows;
29 win->cols = cols;
30 win->term = term;
31
32 if (term->first == NULL)
33 term->first = win;
34 else {
35 term->last->next = win;
36 win->prev = term->last;
37 term->last = win;
38 }
39
40 return win;
41 }
42
43 void
44 termwin_free(term_t *term, termwin_t *win)
45 {
46 if (term->first == win)
47 term->first = win->next;
48 if (term->last == win)
49 term->last = win->prev;
50 if (win->next != NULL)
51 win->next->prev = win->prev;
52 if (win->prev != NULL)
53 win->prev->next = win->next;
54
55 free(win);
56 }
57
58 term_t *
59 term_new(void)
60 {
61 term_t *term;
62
63 term = malloc(sizeof(term_t));
64 if (term == NULL)
65 return NULL;
66 bzero(term, sizeof(term));
67
68 term_init(term);
69
70 return term;
71 }
72
73 void
74 term_free(term_t *term)
75 {
76 termwin_t *win;
77
78 if (term->first != NULL) {
79 for (win = term->first; win; win = win->next)
80 termwin_free(term, win);
81 }
82
83 free(term);
84 }
85
86 void
87 term_setpos(int row, int col)
88 {
89 printf("\033[%d;%dH", row, col);
90 fflush(stdout);
91 }
92
93 void
94 term_up(int rows)
95 {
96 printf("\033[%dA", rows);
97 fflush(stdout);
98 }
99
100 void
101 term_down(int rows)
102 {
103 printf("\033[%dB", rows);
104 fflush(stdout);
105 }
106
107 void
108 term_forward(int cols)
109 {
110 printf("\033[%dC", cols);
111 fflush(stdout);
112 }
113
114 void
115 term_backward(int cols)
116 {
117 printf("\033[%dD", cols);
118 fflush(stdout);
119 }
120
121 void
122 term_erasepos(int row, int col)
123 {
124 term_setpos(row, col);
125 printf("\033[OK");
126 fflush(stdout);
127 }
128
129 void
130 term_eraserow(int row)
131 {
132 term_setpos(row, 0);
133 printf("\033[K0");
134 fflush(stdout);
135 }
136
137 void
138 term_erasescreen(void)
139 {
140 printf("\033[2J");
141 fflush(stdout);
142 }
143
144 void
145 term_backspace(void)
146 {
147 term_backward(2);
148 }
149
150 void
151 term_setscrolling(int start, int end)
152 {
153 printf("\x033[%d;%dr", start, end);
154 fflush(stdout);
155 }
156
157 void
158 term_scrollup(int times)
159 {
160 int i;
161
162 for (i = 0; i < times; i++) {
163 printf("\x033");
164 printf("D");
165 }
166 fflush(stdout);
167 }
168
169 void
170 term_scrolldown(int times)
171 {
172 int i;
173
174 for (i = 0; i < times; i++)
175 printf("\x033H");
176 fflush(stdout);
177 }
178
179 void
180 term_showcursor(void)
181 {
182 printf("\033[?25h");
183 fflush(stdout);
184 }
185
186 void
187 term_hidecursor(void)
188 {
189 printf("\033[?25l");
190 fflush(stdout);
191 }
192
193 void
194 term_blinkcursor(void)
195 {
196 printf("\033[?12h");
197 fflush(stdout);
198 }
199
200 void
201 term_staticursor(void)
202 {
203 printf("\033[?12l");
204 fflush(stdout);
205 }
206
207 void
208 term_reset(term_t *term)
209 {
210 printf("\033[?47l");
211 printf("\033[%d;1H", term->rows);
212 fflush(stdout);
213 tcsetattr(0, TCSANOW, &term->tioin);
214 tcsetattr(1, TCSANOW, &term->tioout);
215
216 term_showcursor();
217 }
218
219 void
220 term_init(term_t *term)
221 {
222 char buf[65];
223 struct termios tio;
224 int i, ro, co;
225
226 bzero(buf, sizeof(buf));
227
228 tcgetattr(1, &term->tioout);
229 tcgetattr(0, &tio);
230 memmove(&term->tioin, &tio, sizeof(tio));
231 cfmakeraw(&tio);
232 tcsetattr(0, TCSAFLUSH, &tio);
233 tcgetattr(1, &tio);
234 cfmakeraw(&tio);
235 tcsetattr(1, TCSADRAIN, &tio);
236
237 /* disable line wrap. */
238 printf("\033[7l");
239
240 printf("\033[18t");
241 fflush(stdout);
242 for (i = 0; read(0, &buf[i], 1) && i < sizeof(buf)-1; i++) {
243 if (buf[i] == 't') {
244 buf[i] = '\0';
245 break;
246 }
247 }
248 if (i >= sizeof(buf)-1) {
249 term->rows = 24;
250 term->cols = 80;
251 } else {
252 sscanf(&buf[4], "%d;%d", &ro, &co);
253 term->rows = ro;
254 term->cols = co;
255 printf("\033[?37h");
256 fflush(stdout);
257 }
258
259 term_hidecursor();
260 term_erasescreen();
261 }
262
263 void
264 term_error(term_t *term, char *fmt, ...)
265 {
266 va_list fmtargs;
267
268 term_eraserow(term->rows);
269 printf("\033[%d:%dH", term->rows, 1);
270 va_start(fmtargs, fmt);
271 vfprintf(stdout, fmt, fmtargs);
272 va_end(fmtargs);
273 printf("\r");
274 fflush(stdout);
275 }
276
277 void
278 term_printf(int row, int col, char *fmt, ...)
279 {
280 va_list fmtargs;
281
282 term_setpos(row, col);
283 va_start(fmtargs, fmt);
284 vfprintf(stdout, fmt, fmtargs);
285 va_end(fmtargs);
286 printf("\n\r");
287 fflush(stdout);
288 }
289
290 /* Bresenham's line algorithm */
291 void
292 term_drawline(term_t *term, int r0, int c0, int r1, int c1, char line)
293 {
294 int dr, dc, sr, sc, err, err2;
295
296 dr = abs(r1 - r0);
297 dc = abs(c1 - c0);
298 sr = (r0 < r1)? 1 : -1;
299 sc = (c0 < c1)? 1 : -1;
300 err = dr - dc;
301
302 for (;;) {
303 term_printf(r0, c0, "%c", line);
304 if (r0 == r1 && c0 == c1)
305 break;
306 err2 = 2 * err;
307 if (err2 > -dc) {
308 err -= dc;
309 r0 += sr;
310 }
311 if (err2 < dr) {
312 err += dr;
313 c0 += sc;
314 }
315 }
316 fflush(stdout);
317 }
318
319 void
320 term_drawrectangle(term_t *term, int r0, int c0, int r1, int c1,
321 char hline, char vline, char uredge, char uledge,
322 char lredge, char lledge)
323 {
324 term_printf(r0, c0, "%c", uredge);
325 term_drawline(term, r0, c0+1, r0, c1-1, hline);
326 term_printf(r0, c1, "%c", uledge);
327 term_drawline(term, r0+1, c1, r1-1, c1, vline);
328 term_printf(r1, c1, "%c", lledge);
329 term_drawline(term, r1, c0+1, r1, c1-1, hline);
330 term_printf(r1, c0, "%c", lredge);
331 term_drawline(term, r0+1, c0, r1-1, c0, vline);
332 }
333
334 void
335 term_fillrectangle(term_t *term, int r0, int c0, int r1, int c1, char fill)
336 {
337 int br, be;
338
339 br = (r0 < r1)? r0 : r1;
340 be = (r0 < r1)? r1 : r0;
341 for (; br <= be; br++)
342 term_drawline(term, br, c0, br, c1, fill);
343 }
344
345
346 void
347 termwin_setpos(termwin_t *win, int row, int col)
348 {
349 if (row <= win->drows && col <= win->dcols && row > 0 && col > 0) {
350 win->cr = row;
351 win->cc = col;
352 }
353 }
354
355 int
356 termwin_inwindow(termwin_t *win, int row, int col)
357 {
358 return (row >= win->dr && row < win->dr + win->drows
359 && col >= win->dc && col < win->dc + win->dcols);
360 }
361
362 void
363 termwin_up(termwin_t *win, int rows)
364 {
365 win->cr -= rows;
366 if (win->cr < 1)
367 win->cr = 11;
368 }
369
370 void
371 termwin_down(termwin_t *win, int rows)
372 {
373 win->cr += rows;
374 if (win->cr > win->drows)
375 win->cr = win->drows;
376 }
377
378 void
379 termwin_forward(termwin_t *win, int cols)
380 {
381 win->cc += cols;
382 if (win->cc > win->dcols)
383 win->cc = win->dcols;
384 }
385
386 void
387 termwin_backward(termwin_t *win, int cols)
388 {
389 win->cc -= cols;
390 if (win->cc < 1)
391 win->cc = 1;
392 }
393
394 void
395 termwin_erasepos(termwin_t *win, int row, int col)
396 {
397 if (termwin_inwindow(win, row, col))
398 term_printf(win->dr + row, win->dc + col, " ");
399 }
400
401
402 void
403 termwin_eraserow(termwin_t *win, int row)
404 {
405 if (row > 0 && row <= win->drows) {
406 term_drawline(win->term, win->dr + row, win->dc,
407 win->dr + row, win->dc + win->cols, ' ');
408 }
409 }
410
411 void
412 termwin_erasewin(termwin_t *win)
413 {
414 term_fillrectangle(win->term, win->dr, win->dc, win->dr + win->drows,
415 win->dc + win->dcols, ' ');
416 }
417
418 void
419 termwin_backspace(termwin_t *win)
420 {
421 termwin_backward(win, 2);
422 }
423
424