fbui | Framebuffer-based graphical environment |
| download: https://git.y1.nz/archives/fbui.tar.gz | |
| README | Files | Log | Refs |
libfbui/Term/ansi.c
1
2 #include <linux/fb.h>
3
4 #include "fbterm.h"
5
6
7 void fbtermEraseLine ();
8 void fbtermEraseToEOL ();
9 void fbtermEraseFromBOL ();
10 void fbtermEraseDisplay ();
11 void fbtermEraseToEOD ();
12 void fbtermEraseFromBOD ();
13 void fbtermInsertChars (unsigned int);
14 void fbtermEraseNChars (unsigned int);
15 void fbtermDeleteChars (unsigned int);
16 void fbtermScrollUp (unsigned int);
17 void fbtermScrollDown (unsigned int);
18 void fbtermNextPos ();
19
20 int savedcursor_x, savedcursor_y;
21 int saved_blink, saved_bold, saved_invisible, saved_reverse, saved_underline, saved_altcharset;
22 int linewrap_pending;
23
24 extern wchar_t last_char;
25 extern int cursor_x, cursor_y, cursor_x0, cursor_y0, cell_w, cell_h;
26 extern int terminal_width, terminal_height;
27 extern int blink_mode, bold_mode, invisible_mode, reverse_mode, underline_mode, altcharset_mode;
28 extern int autowrap;
29 extern int force_cursor_mode;
30 extern int region_top, region_bottom;
31 extern int (*fbtermWriteChar) (wchar_t);
32
33
34 extern char* tabstops;
35
36 extern unsigned long color[];
37 extern int default_bgcolor, default_fgcolor, fgcolor, bgcolor;
38 extern ggi_visual_t vis;
39
40 int min (int a, int b)
41 {
42 return (b<a?b:a);
43 }
44
45
46 void MoveCursor (int x, int y)
47 {
48 debug (DEBUG_DETAIL, "Entering with cursor position (%d,%d)", cursor_x/cell_w+1, cursor_y/cell_h+1);
49
50 cursor_x = x;
51 cursor_y = y;
52 while (cursor_y >= region_bottom * cell_h)
53 {
54 fbtermScrollUp (1);
55 cursor_y -= cell_h;
56 }
57 if (autowrap && cursor_x > (terminal_width-1) * cell_w)
58 {
59 cursor_x = cursor_x0 + (terminal_width-1) * cell_w;
60 linewrap_pending = 1;
61 }
62 else
63 {
64 linewrap_pending = 0;
65 }
66 debug (DEBUG_DETAIL, "Leaving with cursor position (%d,%d)", cursor_x/cell_w+1, cursor_y/cell_h+1);
67 if (linewrap_pending) debug (DEBUG_DETAIL, "Line wrap pending");
68 }
69
70
71 /*------------------------------------------------------------------------------
72 | Cursor motion |
73 ------------------------------------------------------------------------------*/
74
75 void do_CR ()
76 {
77 debug (DEBUG_DETAIL, "Special character code [CR] detected");
78 MoveCursor (cursor_x0, cursor_y);
79 }
80
81 void do_LF ()
82 {
83 debug (DEBUG_DETAIL, "Special character code [LF] detected");
84 MoveCursor (cursor_x, cursor_y + cell_h);
85 }
86
87 void do_cub (unsigned int p1)
88 {
89 debug (DEBUG_DETAIL, "Escape Sequence 'cub %d' detected", p1);
90 /* Move cursor p1 characters to the left */
91 MoveCursor (cursor_x - (cell_w * p1), cursor_y);
92 }
93
94 void do_cud (unsigned int p1)
95 {
96 debug (DEBUG_DETAIL, "Escape Sequence 'cud %d' detected", p1);
97 /* Move cursor down p1 lines */
98 MoveCursor (cursor_x, cursor_y + (cell_h * p1));
99 }
100
101 void do_cuf (unsigned int p1)
102 {
103 debug (DEBUG_DETAIL, "Escape Sequence 'cuf %d' detected", p1);
104 /* Move cursor p1 characters to the right */
105 MoveCursor (cursor_x + (cell_w * p1), cursor_y);
106 }
107
108 void do_cup (unsigned int row, unsigned int column)
109 {
110 debug (DEBUG_DETAIL, "Escape Sequence 'cup %d %d' detected", row, column);
111 MoveCursor (cursor_x0 + (column - 1) * cell_w, cursor_y0 + (row - 1) * cell_h);
112 }
113
114 void do_cuu (unsigned int p1)
115 {
116 debug (DEBUG_DETAIL, "Escape Sequence 'cuu %d' detected", p1);
117 /* Move cursor up p1 lines */
118 MoveCursor (cursor_x, cursor_y - (cell_h * p1));
119 }
120
121 void do_home ()
122 {
123 debug (DEBUG_DETAIL, "Escape Sequence 'home' detected");
124 MoveCursor (cursor_x0, cursor_y0);
125 }
126
127
128 /*------------------------------------------------------------------------------
129 | Mode handling |
130 ------------------------------------------------------------------------------*/
131
132 void do_blink ()
133 {
134 debug (DEBUG_DETAIL, "Escape Sequence 'blink' or part of 'sgr' detected");
135 debug (DEBUG_DETAIL, "Entering blink mode");
136 blink_mode = 1;
137 }
138
139 void do_bold ()
140 {
141 debug (DEBUG_DETAIL, "Escape Sequence 'bold' or part of 'sgr' detected");
142 debug (DEBUG_DETAIL, "Entering bold mode");
143 bold_mode = 1;
144 }
145
146 void do_invis ()
147 {
148 debug (DEBUG_DETAIL, "Escape Sequence 'invis' or part of 'sgr' detected");
149 debug (DEBUG_DETAIL, "Entering invisible mode");
150 invisible_mode = 1;
151 }
152
153 void do_rev ()
154 {
155 debug (DEBUG_DETAIL, "Escape Sequence 'rev|smso' or part of 'sgr' detected");
156 debug (DEBUG_DETAIL, "Entering reverse video mode");
157 reverse_mode = 1;
158 }
159
160 void do_rmacs ()
161 {
162 debug (DEBUG_DETAIL, "Escape Sequence 'rmacs' or part of 'sgr|sgr0' detected");
163 debug (DEBUG_DETAIL, "Leaving altcharset mode");
164 altcharset_mode = 0;
165 }
166
167 void do_smacs ()
168 {
169 debug (DEBUG_DETAIL, "Escape Sequence 'smacs' or part of 'sgr' detected");
170 debug (DEBUG_DETAIL, "Entering altcharset mode");
171 altcharset_mode = 1;
172 }
173
174 void do_smul ()
175 {
176 debug (DEBUG_DETAIL, "Escape Sequence 'smul' or part of 'sgr' detected");
177 debug (DEBUG_DETAIL, "Entering underline mode");
178 underline_mode = 1;
179 }
180
181 void do_leave_all_modes ()
182 {
183 debug (DEBUG_DETAIL, "Leaving all modes except altcharset");
184 bold_mode = 0;
185 blink_mode = 0;
186 underline_mode = 0;
187 reverse_mode = 0;
188 invisible_mode = 0;
189 altcharset_mode = 0;
190 fgcolor = default_fgcolor;
191 bgcolor = default_bgcolor;
192 }
193
194 /*------------------------------------------------------------------------------
195 | Area clear |
196 ------------------------------------------------------------------------------*/
197
198 void do_ed ()
199 {
200 debug (DEBUG_DETAIL, "Escape Sequence 'ed' detected");
201 fbtermEraseToEOD ();
202 }
203
204 void do_el ()
205 {
206 debug (DEBUG_DETAIL, "Escape Sequence 'el' detected");
207 fbtermEraseToEOL ();
208 }
209
210 void do_el1 ()
211 {
212 debug (DEBUG_DETAIL, "Escape Sequence 'el1' detected");
213 fbtermEraseFromBOL ();
214 }
215
216 /*------------------------------------------------------------------------------
217 | Insert/Delete characters |
218 ------------------------------------------------------------------------------*/
219
220 void do_ich (unsigned int p1)
221 {
222 debug (DEBUG_DETAIL, "Escape Sequence 'ich %d' detected", p1);
223 /* Insert p1 characters at current position */
224 fbtermInsertChars (p1);
225 }
226
227 void do_dch (unsigned int p1)
228 {
229 debug (DEBUG_DETAIL, "Escape Sequence 'dch %d' detected", p1);
230 /* Delete p1 characters */
231 fbtermDeleteChars (p1);
232 }
233
234 void do_ech (unsigned int p1)
235 {
236 debug (DEBUG_DETAIL, "Escape Sequence 'ech %d' detected", p1);
237 /* Erase p1 characters, starting at current position */
238 fbtermEraseNChars (p1);
239 }
240
241
242 /*------------------------------------------------------------------------------
243 | Scrolling |
244 ------------------------------------------------------------------------------*/
245
246 void do_indn (unsigned int p1)
247 {
248 debug (DEBUG_DETAIL, "Escape Sequence 'indn %d' detected", p1);
249 /* Scroll forward p1 lines */
250 fbtermScrollUp (p1);
251 }
252
253 void do_rin (unsigned int p1)
254 {
255 debug (DEBUG_DETAIL, "Escape Sequence 'rin %d' detected", p1);
256 /* Scroll back p1 lines */
257 fbtermScrollDown (p1);
258 }
259
260 void do_change_region (unsigned int p1, unsigned int p2)
261 {
262 debug (DEBUG_DETAIL, "Escape Sequence 'csr %d %d' detected", p1, p2);
263 /* Set scrolling region to lines p1->p2 */
264 region_top = p1-1;
265 region_bottom = p2;
266 }
267
268 /*------------------------------------------------------------------------------
269 | Tabs |
270 ------------------------------------------------------------------------------*/
271
272 void do_cbt ()
273 {
274 debug (DEBUG_DETAIL, "Escape Sequence 'cbt' detected");
275 /* Back to preceding tap stop */
276 do
277 {
278 MoveCursor (cursor_x - cell_w, cursor_y);
279 }
280 while (cursor_x/cell_w && !tabstops[cursor_x/cell_w]);
281 }
282
283 void do_ht ()
284 {
285 debug (DEBUG_DETAIL, "Escape Sequence 'ht' detected");
286 /* Go to the next tab stop */
287 do
288 {
289 MoveCursor (cursor_x + cell_w, cursor_y);
290 }
291 while (cursor_x/cell_w < terminal_width-1 && !tabstops[cursor_x/cell_w]);
292 }
293
294 void do_hts ()
295 {
296 debug (DEBUG_DETAIL, "Escape Sequence 'hts' detected");
297 /* Set a tab stop in current column */
298 tabstops[cursor_x/cell_w] = 1;
299 }
300
301 void do_tbc ()
302 {
303 debug (DEBUG_DETAIL, "Escape Sequence 'tbc' detected");
304 /* Clear all tab stops */
305 memset (tabstops, 0, terminal_width);
306 /*tabstops[0] = 1;
307 tabstops[terminal_width] = 1;*/
308 }
309
310 void do_clear_current_tab ()
311 {
312 /* vt100 but not in terminfo */
313 tabstops[cursor_x/cell_w] = 0;
314 }
315
316 /*------------------------------------------------------------------------------
317 | Colors |
318 ------------------------------------------------------------------------------*/
319
320 void do_op ()
321 {
322 debug (DEBUG_DETAIL, "Escape Sequence 'op' detected");
323 /* Reset fg and bg colors to their default values */
324 fgcolor = default_fgcolor;
325 bgcolor = default_bgcolor;
326 }
327
328 void do_setab (unsigned int p1)
329 {
330 debug (DEBUG_DETAIL, "Escape Sequence 'setab %d' detected", p1);
331 /* Set bg color to color #p1 */
332 if (p1 == 9) bgcolor = default_bgcolor;
333 else bgcolor = p1;
334 }
335
336 void do_setaf (unsigned int p1)
337 {
338 debug (DEBUG_DETAIL, "Escape Sequence 'setaf %d' detected", p1);
339 /* Set fg color to color #p1 */
340 if (p1 == 9) fgcolor = default_fgcolor;
341 else fgcolor = p1;
342 }
343
344 /*------------------------------------------------------------------------------
345 | User strings |
346 ------------------------------------------------------------------------------*/
347
348 void do_identify (unsigned char *shellinput, size_t *shellinput_size)
349 {
350 debug (DEBUG_DETAIL, "User string 'u9' or Enquiry detected");
351 /* Enquire sequence sent to identify the terminal type
352 Should answer by sending the u8 user string */
353 memcpy (shellinput + *shellinput_size, "\033[?1;0c", 7);
354 *shellinput_size += 7;
355 }
356
357 void do_send_cursor_position (unsigned char *shellinput, size_t *shellinput_size)
358 {
359 debug (DEBUG_DETAIL, "Query cursor position detected");
360 /* Cursor position request */
361 *shellinput_size += sprintf ((char*)shellinput, "\033[%d;%dR", cursor_y / cell_h + 1, cursor_x / cell_w + 1);
362 }
363
364 void do_send_status (unsigned char *shellinput, size_t *shellinput_size)
365 {
366 debug (DEBUG_DETAIL, "Terminal status report requested");
367 /* Request terminal status
368 \E[0n if OK, \E[3n if NOK (but we're always OK, aren't we?) */
369 memcpy (shellinput + *shellinput_size, "\033[0n", 4);
370 *shellinput_size += 4;
371 }
372
373
374 /*------------------------------------------------------------------------------
375 | Others |
376 ------------------------------------------------------------------------------*/
377
378 void do_BELL ()
379 {
380 debug (DEBUG_DETAIL, "Special character code [BELL] detected");
381 /* This should be a visual bell! */
382 }
383
384 void do_rep (unsigned int count)
385 {
386 debug (DEBUG_DETAIL, "Escape Sequence 'rep %d' detected", count);
387 /* Repeat last character count times */
388 while (count)
389 {
390 fbtermWriteChar (last_char);
391 fbtermNextPos ();
392 count--;
393 }
394 }
395
396
397 int
398 HandleEscapeSequences (unsigned char **buf, size_t *bufsize, unsigned char *shellinput, size_t *shellinput_size)
399 {
400 size_t index;
401 unsigned char *escape;
402 unsigned int param[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
403 int in_ansi=0, in_escape=0, num_param=1, finished=0, i, ansi_question_mark=0;
404
405 escape = *buf;
406 index = 0;
407
408 do
409 {
410 if (!in_escape && !in_ansi)
411 {
412 finished = 1;
413 switch (escape[index])
414 {
415 case 000: /* ignored */
416 break;
417 case 005:
418 if (SHELLINPUT_SIZE - *shellinput_size >= 5) do_identify (shellinput, shellinput_size);
419 else return 2;
420 break;
421 case 007: /* Bell (7) */
422 do_BELL ();
423 break;
424 case 010: /* Backspace */
425 do_cub (1);
426 break;
427 case 011: /* Tab expansion */
428 do_ht ();
429 break;
430 case 012: /* Line feed (10) */
431 case 013:
432 case 014:
433 do_LF ();
434 break;
435 case 015: /* Carriage return (13) */
436 do_CR ();
437 break;
438 case 016:
439 do_smacs ();
440 break;
441 case 017:
442 do_rmacs ();
443 break;
444 case 033: /* Escape character */
445 in_escape = 1;
446 finished = 0;
447 break;
448 case 0177: /* for FreeBSD */
449 do_cub (1);
450 break;
451 default:
452 return 1;
453 }
454 index++;
455 continue;
456 }
457 if (in_escape && !in_ansi)
458 {
459 finished = 1;
460 switch (escape[index])
461 {
462 case '[':
463 in_ansi = 1;
464 finished = 0;
465 break;
466 /* Character set designator (we don't care) */
467 case '(': /* G0 */
468 case ')': /* G1 */
469 if (index != 1) return 1;
470 finished = 0;
471 break;
472 /* Character set */
473 case '0': /* line drawing set */
474 if (index != 2) return 1;
475 switch (escape[1])
476 {
477 case '(':
478 altcharset_mode = 1;
479 break;
480 case ')': break;
481 }
482 finished = 1;
483 case '1': /* alternate character ROM */
484 case '2': /* alternate character ROM (graphics) */
485 case 'A': /* United Kingdom */
486 case 'B': /* US ASCII */
487 if (index != 2) return 1;
488 switch (escape[1])
489 {
490 case '(':
491 altcharset_mode = 0;
492 break;
493 case ')': break;
494 }
495 finished = 1;
496 break;
497 case 'D':
498 do_indn (1);
499 break;
500 case 'E':
501 do_CR ();
502 do_LF ();
503 break;
504 case 'H':
505 do_hts ();
506 break;
507 case 'M':
508 do_rin (1);
509 break;
510 case 'Z': /* identify, same as \E[c */
511 if (SHELLINPUT_SIZE - *shellinput_size >= 7) do_identify (shellinput, shellinput_size);
512 else return 2;
513 break;
514 case '>':
515 /*force_cursor_mode = 1;*/
516 break;
517 case '=':
518 /*force_cursor_mode = 0;*/
519 break;
520 case '7':
521 /* Should we save current colors too? */
522 saved_blink = blink_mode;
523 saved_bold = bold_mode;
524 saved_invisible = invisible_mode;
525 saved_reverse = reverse_mode;
526 saved_underline = underline_mode;
527 saved_altcharset = altcharset_mode;
528 savedcursor_x = cursor_x;
529 savedcursor_y = cursor_y;
530 break;
531 case '8':
532 blink_mode = saved_blink;
533 bold_mode = saved_bold;
534 invisible_mode = saved_invisible;
535 reverse_mode = saved_reverse;
536 underline_mode = saved_underline;
537 altcharset_mode = saved_altcharset;
538 cursor_x = savedcursor_x;
539 cursor_y = savedcursor_y;
540 break;
541 default:
542 return 1;
543 }
544 index++;
545 continue;
546 }
547 if (in_ansi)
548 {
549 finished = 1;
550 switch (escape[index])
551 {
552 case '0':
553 case '1':
554 case '2':
555 case '3':
556 case '4':
557 case '5':
558 case '6':
559 case '7':
560 case '8':
561 case '9':
562 param[num_param-1] = param[num_param-1]*10+escape[index]-48;
563 finished = 0;
564 break;
565 case ';':
566 num_param++;
567 finished = 0;
568 break;
569 case '?':
570 if (escape[index-1] != '[')
571 {
572 return 1;
573 }
574 ansi_question_mark = 1;
575 finished = 0;
576 break;
577 case '@':
578 if (!param[0]) param[0] = 1;
579 do_ich (param[0]);
580 break;
581 case 'A':
582 if (!param[0]) param[0] = 1;
583 do_cuu (param[0]);
584 break;
585 case 'B':
586 if (!param[0]) param[0] = 1;
587 do_cud (param[0]);
588 break;
589 case 'C':
590 if (!param[0]) param[0] = 1;
591 do_cuf (param[0]);
592 break;
593 case 'D':
594 if (!param[0]) param[0] = 1;
595 do_cub (param[0]);
596 break;
597 case 'F':
598 if (!param[0]) param[0] = 1;
599 do_rep (param[0]);
600 break;
601 case 'H':
602 case 'f':
603 if (!param[0]) param[0] = 1;
604 if (!param[1]) param[1] = 1;
605 do_cup (param[0], param[1]);
606 break;
607 case 'J':
608 switch (param[0])
609 {
610 case 0:
611 /* Erase from cursor to end of screen */
612 do_ed ();
613 break;
614 case 1:
615 /* Erase from beginning of screen to cursor */
616 /* vt100 but no associated capability */
617 fbtermEraseFromBOD ();
618 break;
619 case 2:
620 /* Erase entire screen */
621 /* vt100 but no associated capability */
622 fbtermEraseDisplay ();
623 break;
624 default:
625 return 1;
626 }
627 break;
628 case 'K':
629 switch (param[0])
630 {
631 case 0:
632 /* Erase from cursor to end of line */
633 do_el ();
634 break;
635 case 1:
636 /* Erase from beginning of line to cursor */
637 do_el1 ();
638 break;
639 case 2:
640 /* Erase entire line containing cursor */
641 /* vt100 but no associated capability */
642 fbtermEraseLine ();
643 break;
644 default:
645 return 1;
646 }
647 break;
648 case 'P':
649 if (!param[0]) param[0] = 1;
650 do_dch (param[0]);
651 break;
652 case 'S':
653 if (!param[0]) param[0] = 1;
654 do_indn (param[0]);
655 break;
656 case 'T':
657 if (!param[0]) param[0] = 1;
658 do_rin (param[0]);
659 break;
660 case 'X':
661 if (!param[0]) param[0] = 1;
662 do_ech (param[0]);
663 break;
664 case 'Z':
665 do_cbt ();
666 break;
667 case 'c':
668 if (param[0]) return 1;
669 if (SHELLINPUT_SIZE - *shellinput_size >= 7) do_identify (shellinput, shellinput_size);
670 else return 2;
671 break;
672 case 'g':
673 switch (param[0])
674 {
675 case 3:
676 do_tbc ();
677 break;
678 case 0:
679 do_clear_current_tab ();
680 break;
681 default:
682 return 1;
683 }
684 break;
685 case 'h':
686 if (ansi_question_mark)
687 {
688 for (i = 0; i < num_param; i++)
689 {
690 switch (param[i])
691 {
692 case 1:
693 force_cursor_mode = 1;
694 break;
695 case 7:
696 autowrap = 1;
697 break;
698 /* the other modes are not implemented */
699 case 3:
700 case 4:
701 case 5:
702 case 6:
703 case 8:
704 case 9:
705 break;
706 default:
707 return 1;
708 }
709 }
710 }
711 else
712 {
713 if (param[0] != 20) return 1;
714 }
715 break;
716 case 'l':
717 if (ansi_question_mark)
718 {
719 for (i = 0; i < num_param; i++)
720 {
721 switch (param[i])
722 {
723 case 1:
724 force_cursor_mode = 0;
725 break;
726 case 7:
727 autowrap = 0;
728 break;
729 /* the other modes are not implemented */
730 case 2:
731 case 3:
732 case 4:
733 case 5:
734 case 6:
735 case 8:
736 case 9:
737 break;
738 default:
739 return 1;
740 }
741 }
742 }
743 else
744 {
745 if (param[0] != 20) return 1;
746 }
747 break;
748 case 'm':
749 for (i = 0; i < num_param; i++)
750 {
751 switch (param[i])
752 {
753 case 0:
754 do_leave_all_modes ();
755 break;
756 case 1:
757 do_bold ();
758 break;
759 case 4:
760 do_smul ();
761 break;
762 case 5:
763 do_blink ();
764 break;
765 case 7:
766 do_rev ();
767 break;
768 case 8:
769 do_invis ();
770 break;
771 default:
772 if (param[i]/10 == 3)
773 {
774 do_setaf (param[i] - 30);
775 break;
776 }
777 if (param[i]/10 == 4)
778 {
779 do_setab (param[i] - 40);
780 break;
781 }
782 return 1;
783 }
784 }
785 break;
786 case 'n':
787 switch (param[0])
788 {
789 case 5: /* status report */
790 if (SHELLINPUT_SIZE - *shellinput_size >= 4)
791 do_send_status (shellinput, shellinput_size);
792 else return 2;
793 break;
794 case 6: /* curosr position */
795 if (SHELLINPUT_SIZE - *shellinput_size >= MAX_PARAM_SIZE*2+5)
796 do_send_cursor_position (shellinput, shellinput_size);
797 else return 2;
798 break;
799 default:
800 return 1;
801 }
802 break;
803 case 'r':
804 if (!param[0]) param[0] = 1;
805 if (!param[1]) param[0] = terminal_height;
806 do_change_region (param[0], param[1]);
807 break;
808 default:
809 return 1;
810 }
811 }
812 index++;
813 }
814 while (index<(*bufsize) && !finished && num_param<=MAX_PARAM_NUM && param[num_param]<=MAX_PARAM_VALUE);
815
816 if (finished)
817 {
818 (*buf) += index;
819 (*bufsize) -= index;
820 return 0;
821 }
822 if (index>=(*bufsize)) return 2;
823 return 1;
824 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.