New input parser via state machine.

This commit is contained in:
Nicholas Marriott
2007-09-28 22:47:22 +00:00
parent d2e035f892
commit aafee17de6
9 changed files with 1088 additions and 956 deletions

266
screen.c
View File

@ -1,4 +1,4 @@
/* $Id: screen.c,v 1.11 2007-09-21 19:24:37 nicm Exp $ */
/* $Id: screen.c,v 1.12 2007-09-28 22:47:21 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -35,30 +35,6 @@ void screen_make_lines(struct screen *, u_int, u_int);
void screen_move_lines(struct screen *, u_int, u_int, u_int);
void screen_fill_lines(
struct screen *, u_int, u_int, u_char, u_char, u_char);
uint16_t screen_extract(u_char *);
void screen_write_character(struct screen *, u_char);
void screen_cursor_up_scroll(struct screen *);
void screen_cursor_down_scroll(struct screen *);
void screen_scroll_region_up(struct screen *);
void screen_scroll_region_down(struct screen *);
void screen_scroll_up(struct screen *, u_int);
void screen_scroll_down(struct screen *, u_int);
void screen_fill_screen(struct screen *, u_char, u_char, u_char);
void screen_fill_line(struct screen *, u_int, u_char, u_char, u_char);
void screen_fill_end_of_screen(
struct screen *, u_int, u_int, u_char, u_char, u_char);
void screen_fill_end_of_line(
struct screen *, u_int, u_int, u_char, u_char, u_char);
void screen_fill_start_of_line(
struct screen *, u_int, u_int, u_char, u_char, u_char);
void screen_insert_lines(struct screen *, u_int, u_int);
void screen_delete_lines(struct screen *, u_int, u_int);
void screen_insert_characters(struct screen *, u_int, u_int, u_int);
void screen_delete_characters(struct screen *, u_int, u_int, u_int);
#define SCREEN_DEFDATA ' '
#define SCREEN_DEFATTR 0
#define SCREEN_DEFCOLR 0x88
#define screen_last_y(s) ((s)->sy - 1)
#define screen_last_x(s) ((s)->sx - 1)
@ -380,246 +356,6 @@ screen_fill_lines(
screen_fill_line(s, i, data, attr, colr);
}
/* Update screen with character. */
void
screen_character(struct screen *s, u_char ch)
{
switch (ch) {
case '\n': /* LF */
screen_cursor_down_scroll(s);
break;
case '\r': /* CR */
s->cx = 0;
break;
case '\010': /* BS */
if (s->cx > 0)
s->cx--;
break;
case '\177': /* DC */
/* XXX */
break;
default:
if (ch < ' ')
fatalx("bad control");
screen_write_character(s, ch);
break;
}
}
/* Extract 16-bit value from pointer. */
uint16_t
screen_extract(u_char *ptr)
{
uint16_t n;
memcpy(&n, ptr, sizeof n);
return (n);
}
/* Update screen with escape sequence. */
void
screen_sequence(struct screen *s, u_char *ptr)
{
uint16_t ua, ub;
ptr++;
log_debug("processing code %hhu", *ptr);
switch (*ptr++) {
case CODE_CURSORUP:
ua = screen_extract(ptr);
if (ua > s->cy)
ua = s->cy;
s->cy -= ua;
break;
case CODE_CURSORDOWN:
ua = screen_extract(ptr);
if (s->cy + ua > screen_last_y(s))
ua = screen_last_y(s) - s->cy;
s->cy += ua;
break;
case CODE_CURSORLEFT:
ua = screen_extract(ptr);
if (ua > s->cx)
ua = s->cx;
s->cx -= ua;
break;
case CODE_CURSORRIGHT:
ua = screen_extract(ptr);
if (s->cx + ua > screen_last_x(s))
ua = screen_last_x(s) - s->cx;
s->cx += ua;
break;
case CODE_CURSORMOVE:
ua = screen_extract(ptr);
ptr += 2;
ub = screen_extract(ptr);
if (ub > s->sx)
ub = s->sx;
s->cx = ub - 1;
if (ua > s->sy)
ua = s->sy;
s->cy = ua - 1;
break;
case CODE_CLEARENDOFSCREEN:
screen_fill_end_of_screen(
s, s->cx, s->cy, SCREEN_DEFDATA, s->attr, s->colr);
break;
case CODE_CLEARSCREEN:
screen_fill_screen(s, SCREEN_DEFDATA, s->attr, s->colr);
break;
case CODE_CLEARENDOFLINE:
screen_fill_end_of_line(
s, s->cx, s->cy, SCREEN_DEFDATA, s->attr, s->colr);
break;
case CODE_CLEARSTARTOFLINE:
screen_fill_start_of_line(
s, s->cx, s->cy, SCREEN_DEFDATA, s->attr, s->colr);
break;
case CODE_CLEARLINE:
screen_fill_line(s, s->cy, SCREEN_DEFDATA, s->attr, s->colr);
break;
case CODE_INSERTLINE:
ua = screen_extract(ptr);
screen_insert_lines(s, s->cy, ua);
break;
case CODE_DELETELINE:
ua = screen_extract(ptr);
screen_delete_lines(s, s->cy, ua);
break;
case CODE_INSERTCHARACTER:
ua = screen_extract(ptr);
screen_insert_characters(s, s->cx, s->cy, ua);
break;
case CODE_DELETECHARACTER:
ua = screen_extract(ptr);
screen_delete_characters(s, s->cx, s->cy, ua);
break;
case CODE_CURSORON:
s->mode |= MODE_CURSOR;
break;
case CODE_CURSOROFF:
s->mode &= ~MODE_CURSOR;
break;
case CODE_REVERSEINDEX:
screen_cursor_up_scroll(s);
break;
case CODE_SCROLLREGION:
ua = screen_extract(ptr);
ptr += 2;
ub = screen_extract(ptr);
if (ua > s->sy)
ua = s->sy;
s->ry_upper = ua - 1;
if (ub > s->sy)
ub = s->sy;
s->ry_lower = ub - 1;
break;
case CODE_INSERTOFF:
s->mode &= ~MODE_INSERT;
break;
case CODE_INSERTON:
s->mode |= MODE_INSERT;
break;
case CODE_KCURSOROFF:
s->mode &= ~MODE_KCURSOR;
break;
case CODE_KCURSORON:
s->mode |= MODE_KCURSOR;
break;
case CODE_KKEYPADOFF:
s->mode &= ~MODE_KKEYPAD;
break;
case CODE_KKEYPADON:
s->mode |= MODE_KKEYPAD;
break;
case CODE_TITLE:
ua = screen_extract(ptr);
ptr += 2;
log_debug("new title: %u:%.*s", ua, (int) ua, ptr);
if (ua > (sizeof s->title) - 1)
ua = (sizeof s->title) - 1;
memcpy(s->title, ptr, ua);
s->title[ua] = '\0';
break;
case CODE_ATTRIBUTES:
ua = screen_extract(ptr);
if (ua == 0) {
s->attr = 0;
s->colr = SCREEN_DEFCOLR;
break;
}
while (ua-- > 0) {
ptr += 2;
ub = screen_extract(ptr);
switch (ub) {
case 0:
case 10:
s->attr = 0;
s->colr = SCREEN_DEFCOLR;
break;
case 1:
s->attr |= ATTR_BRIGHT;
break;
case 2:
s->attr |= ATTR_DIM;
break;
case 3:
s->attr |= ATTR_ITALICS;
break;
case 4:
s->attr |= ATTR_UNDERSCORE;
break;
case 5:
s->attr |= ATTR_BLINK;
break;
case 7:
s->attr |= ATTR_REVERSE;
break;
case 8:
s->attr |= ATTR_HIDDEN;
break;
case 23:
s->attr &= ~ATTR_ITALICS;
break;
case 24:
s->attr &= ~ATTR_UNDERSCORE;
break;
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
s->colr &= 0x0f;
s->colr |= (ub - 30) << 4;
break;
case 39:
s->colr &= 0x0f;
s->colr |= 0x80;
break;
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
s->colr &= 0xf0;
s->colr |= ub - 40;
break;
case 49:
s->colr &= 0xf0;
s->colr |= 0x08;
break;
}
}
}
}
/* Write a single character to the screen at the cursor and move forward. */
void
screen_write_character(struct screen *s, u_char ch)