git.y1.nz

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.