mirror of
https://github.com/tmate-io/tmate.git
synced 2025-08-17 00:51:36 +02:00
New input parser via state machine.
This commit is contained in:
266
screen.c
266
screen.c
@ -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)
|
||||
|
Reference in New Issue
Block a user