working terminal

This commit is contained in:
2017-01-23 18:27:51 +01:00
parent e3eddca176
commit afa34a43de
12 changed files with 196 additions and 69 deletions
+41 -28
View File
@@ -188,11 +188,11 @@ handle_plainchar(char c)
static const char _ansi_actions[] = {
0, 1, 0, 1, 1, 1, 2, 1,
3, 1, 4, 1, 5, 1, 6, 1,
7, 1, 8
7, 1, 8, 1, 9
};
static const char _ansi_eof_actions[] = {
0, 0, 0, 13, 13, 0, 0
0, 15, 15, 13, 13, 0, 0
};
static const int ansi_start = 1;
@@ -267,11 +267,11 @@ case 1:
goto tr0;
case 2:
switch( (*p) ) {
case 91: goto tr2;
case 91: goto tr3;
case 93: goto tr4;
case 99: goto tr5;
}
goto tr3;
goto tr2;
case 0:
goto _out;
case 5:
@@ -312,27 +312,28 @@ case 6:
goto tr6;
}
tr3: cs = 0; goto _again;
tr6: cs = 0; goto f4;
tr0: cs = 1; goto f0;
tr2: cs = 0; goto f0;
tr6: cs = 0; goto f5;
tr0: cs = 1; goto f1;
tr1: cs = 2; goto _again;
tr7: cs = 4; goto f5;
tr8: cs = 4; goto f6;
tr9: cs = 4; goto f7;
tr2: cs = 5; goto f1;
tr4: cs = 5; goto f2;
tr5: cs = 5; goto f3;
tr10: cs = 6; goto f8;
tr7: cs = 4; goto f6;
tr8: cs = 4; goto f7;
tr9: cs = 4; goto f8;
tr3: cs = 5; goto f2;
tr4: cs = 5; goto f3;
tr5: cs = 5; goto f4;
tr10: cs = 6; goto f9;
f0: _acts = _ansi_actions + 1; goto execFuncs;
f1: _acts = _ansi_actions + 3; goto execFuncs;
f5: _acts = _ansi_actions + 5; goto execFuncs;
f6: _acts = _ansi_actions + 7; goto execFuncs;
f7: _acts = _ansi_actions + 9; goto execFuncs;
f8: _acts = _ansi_actions + 11; goto execFuncs;
f4: _acts = _ansi_actions + 13; goto execFuncs;
f2: _acts = _ansi_actions + 15; goto execFuncs;
f1: _acts = _ansi_actions + 1; goto execFuncs;
f2: _acts = _ansi_actions + 3; goto execFuncs;
f6: _acts = _ansi_actions + 5; goto execFuncs;
f7: _acts = _ansi_actions + 7; goto execFuncs;
f8: _acts = _ansi_actions + 9; goto execFuncs;
f9: _acts = _ansi_actions + 11; goto execFuncs;
f5: _acts = _ansi_actions + 13; goto execFuncs;
f0: _acts = _ansi_actions + 15; goto execFuncs;
f3: _acts = _ansi_actions + 17; goto execFuncs;
f4: _acts = _ansi_actions + 19; goto execFuncs;
execFuncs:
_nacts = *_acts++;
@@ -397,21 +398,27 @@ execFuncs:
}
break;
case 7:
/* #line 288 "user/ansi_parser.rl" */
/* #line 280 "user/ansi_parser.rl" */
{
{cs = 1; goto _again;}
}
break;
case 8:
/* #line 292 "user/ansi_parser.rl" */
{
// TODO implement OS control code parsing
{cs = 1; goto _again;}
}
break;
case 8:
/* #line 293 "user/ansi_parser.rl" */
case 9:
/* #line 297 "user/ansi_parser.rl" */
{
// Reset screen
handle_RESET_cmd();
{cs = 1; goto _again;}
}
break;
/* #line 415 "user/ansi_parser.c" */
/* #line 422 "user/ansi_parser.c" */
}
}
goto _again;
@@ -434,7 +441,13 @@ _again:
{cs = 1; goto _again;}
}
break;
/* #line 438 "user/ansi_parser.c" */
case 7:
/* #line 280 "user/ansi_parser.rl" */
{
{cs = 1; goto _again;}
}
break;
/* #line 451 "user/ansi_parser.c" */
}
}
}
@@ -442,6 +455,6 @@ _again:
_out: {}
}
/* #line 311 "user/ansi_parser.rl" */
/* #line 315 "user/ansi_parser.rl" */
}
+5 -1
View File
@@ -277,6 +277,10 @@ ansi_parser(const char *newdata, size_t len)
fgoto main;
}
action main_fail {
fgoto main;
}
CSI_body := ((32..47|60..64) @CSI_leading)?
((digit @CSI_digit)* ';' @CSI_semi)*
(digit @CSI_digit)* alpha @CSI_end $!CSI_fail;
@@ -305,7 +309,7 @@ ansi_parser(const char *newdata, size_t len)
']' @OSC_start |
'c' @RESET_cmd
)
)+;
)+ $!main_fail;
write exec;
}%%
+106 -22
View File
@@ -53,10 +53,22 @@ static Coordinate W = SCREEN_DEF_W;
*/
static Coordinate H = SCREEN_DEF_H;
// XXX volatile is probably not needed
static volatile int notifyLock = 0;
//endregion
//region Helpers
#define NOTIFY_LOCK() do { \
notifyLock++; \
} while(0)
#define NOTIFY_DONE() do { \
if (notifyLock > 0) notifyLock--; \
if (notifyLock == 0) screen_notifyChange(); \
} while(0)
/**
* Reset a cell
*/
@@ -103,12 +115,13 @@ cursor_reset(void)
void ICACHE_FLASH_ATTR
screen_init(void)
{
NOTIFY_LOCK();
for (unsigned int i = 0; i < MAX_SCREEN_SIZE; i++) {
cell_init(&screen[i]);
}
cursor_reset();
screen_notifyChange();
NOTIFY_DONE();
}
/**
@@ -117,9 +130,10 @@ screen_init(void)
void ICACHE_FLASH_ATTR
screen_reset(void)
{
NOTIFY_LOCK();
screen_clear(CLEAR_ALL);
cursor_reset();
screen_notifyChange();
NOTIFY_DONE();
}
/**
@@ -128,6 +142,7 @@ screen_reset(void)
void ICACHE_FLASH_ATTR
screen_clear(ClearMode mode)
{
NOTIFY_LOCK();
switch (mode) {
case CLEAR_ALL:
clear_range(0, W * H - 1);
@@ -141,7 +156,7 @@ screen_clear(ClearMode mode)
clear_range(0, (cursor.y * W) + cursor.x);
break;
}
screen_notifyChange();
NOTIFY_DONE();
}
/**
@@ -150,6 +165,7 @@ screen_clear(ClearMode mode)
void ICACHE_FLASH_ATTR
screen_clear_line(ClearMode mode)
{
NOTIFY_LOCK();
switch (mode) {
case CLEAR_ALL:
clear_range(cursor.y * W, (cursor.y + 1) * W - 1);
@@ -163,7 +179,7 @@ screen_clear_line(ClearMode mode)
clear_range(cursor.y * W, cursor.y * W + cursor.x);
break;
}
screen_notifyChange();
NOTIFY_DONE();
}
//endregion
@@ -179,6 +195,7 @@ screen_clear_line(ClearMode mode)
void ICACHE_FLASH_ATTR
screen_resize(Coordinate w, Coordinate h)
{
NOTIFY_LOCK();
// sanitize
if (w < 1) w = 1;
if (h < 1) h = 1;
@@ -186,7 +203,7 @@ screen_resize(Coordinate w, Coordinate h)
W = w;
H = h;
screen_reset();
screen_notifyChange();
NOTIFY_DONE();
}
/**
@@ -195,13 +212,15 @@ screen_resize(Coordinate w, Coordinate h)
void ICACHE_FLASH_ATTR
screen_scroll_up(unsigned int lines)
{
NOTIFY_LOCK();
if (lines >= H - 1) {
screen_clear(CLEAR_ALL);
return;
goto done;
}
// bad cmd
if (lines == 0) {
return;
goto done;
}
int y;
@@ -210,7 +229,9 @@ screen_scroll_up(unsigned int lines)
}
clear_range(y * W, W * H - 1);
screen_notifyChange();
done:
NOTIFY_DONE();
}
/**
@@ -219,13 +240,15 @@ screen_scroll_up(unsigned int lines)
void ICACHE_FLASH_ATTR
screen_scroll_down(unsigned int lines)
{
NOTIFY_LOCK();
if (lines >= H - 1) {
screen_clear(CLEAR_ALL);
return;
goto done;
}
// bad cmd
if (lines == 0) {
return;
goto done;
}
int y;
@@ -234,7 +257,8 @@ screen_scroll_down(unsigned int lines)
}
clear_range(0, lines * W-1);
screen_notifyChange();
done:
NOTIFY_DONE();
}
//endregion
@@ -247,11 +271,12 @@ screen_scroll_down(unsigned int lines)
void ICACHE_FLASH_ATTR
screen_cursor_set(Coordinate x, Coordinate y)
{
NOTIFY_LOCK();
if (x >= W) x = W - 1;
if (y >= H) y = H - 1;
cursor.x = x;
cursor.y = y;
screen_notifyChange();
NOTIFY_DONE();
}
/**
@@ -260,9 +285,10 @@ screen_cursor_set(Coordinate x, Coordinate y)
void ICACHE_FLASH_ATTR
screen_cursor_set_x(Coordinate x)
{
NOTIFY_LOCK();
if (x >= W) x = W - 1;
cursor.x = x;
screen_notifyChange();
NOTIFY_DONE();
}
/**
@@ -271,9 +297,10 @@ screen_cursor_set_x(Coordinate x)
void ICACHE_FLASH_ATTR
screen_cursor_set_y(Coordinate y)
{
NOTIFY_LOCK();
if (y >= H) y = H - 1;
cursor.y = y;
screen_notifyChange();
NOTIFY_DONE();
}
/**
@@ -282,10 +309,27 @@ screen_cursor_set_y(Coordinate y)
void ICACHE_FLASH_ATTR
screen_cursor_move(int dx, int dy)
{
if (dx < 0 && -dx > cursor.x) dx = -cursor.x;
if (dy < 0 && -dy > cursor.y) dy = -cursor.y;
screen_cursor_set(cursor.x + dx, cursor.y + dy);
screen_notifyChange();
NOTIFY_LOCK();
int move;
cursor.x += dx;
cursor.y += dy;
if (cursor.x >= W) cursor.x = W - 1;
if (cursor.x < 0) cursor.x = 0;
if (cursor.y < 0) {
move = -cursor.y;
cursor.y = 0;
screen_scroll_down((unsigned int)move);
}
if (cursor.y >= H) {
move = cursor.y - (H - 1);
cursor.y = H - 1;
screen_scroll_up((unsigned int)move);
}
NOTIFY_DONE();
}
/**
@@ -304,9 +348,10 @@ screen_cursor_save(void)
void ICACHE_FLASH_ATTR
screen_cursor_restore(void)
{
NOTIFY_LOCK();
cursor.x = cursor_sav.x;
cursor.y = cursor_sav.y;
screen_notifyChange();
NOTIFY_DONE();
}
/**
@@ -315,8 +360,9 @@ screen_cursor_restore(void)
void ICACHE_FLASH_ATTR
screen_cursor_enable(bool enable)
{
NOTIFY_LOCK();
cursor.visible = enable;
screen_notifyChange();
NOTIFY_DONE();
}
//endregion
@@ -383,7 +429,44 @@ screen_set_bright_fg(void)
void ICACHE_FLASH_ATTR
screen_putchar(char ch)
{
NOTIFY_LOCK();
Cell *c = &screen[cursor.x + cursor.y * W];
// Special treatment for CRLF
switch (ch) {
case '\r':
screen_cursor_set_x(0);
goto done;
case '\n':
screen_cursor_move(0, 1);
goto done;
case 8: // BS
if (cursor.x > 0) cursor.x--;
// erase target cell
c = &screen[cursor.x + cursor.y * W];
c->c = ' ';
goto done;
case 9: // TAB
c->c = ' ';
// nested recurs >:( but it's ok
screen_putchar(' ');
screen_putchar(' ');
screen_putchar(' ');
screen_putchar(' ');
goto done;
default:
if (ch < ' ') {
// Discard
warn("Ignoring control char %d", (int)c);
goto done;
}
}
c->c = ch;
if (cursor.inverse) {
@@ -407,7 +490,8 @@ screen_putchar(char ch)
}
}
screen_notifyChange();
done:
NOTIFY_DONE();
}
@@ -495,7 +579,7 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data)
ss->lastFg = 0;
ss->lastChar = '\0';
bufprint("{x:%d,y:%d,screen:\"", cursor.x, cursor.y);
bufprint("{\"x\":%d,\"y\":%d,\"screen\":\"", cursor.x, cursor.y);
}
int i = ss->index;
+1 -1
View File
@@ -53,7 +53,7 @@ typedef enum {
} ClearMode;
typedef uint8_t Color;
typedef unsigned int Coordinate;
typedef int Coordinate;
httpd_cgi_state ICACHE_FLASH_ATTR
screenSerializeToBuffer(char *buffer, size_t buf_len, void **data);
+6 -3
View File
@@ -25,7 +25,10 @@ void ICACHE_FLASH_ATTR serialInit(void)
*/
void ICACHE_FLASH_ATTR UART_HandleRxByte(char c)
{
// TODO buffering, do not run parser after just 1 char
printf("(%c)", c);
ansi_parser(&c, 1);
if (c > 0 && c < 127) {
// TODO buffering, do not run parser after just 1 char
ansi_parser(&c, 1);
} else {
warn("Bad char %d ('%c')", (unsigned char)c, c);
}
}
+5 -4
View File
@@ -55,8 +55,7 @@ void ICACHE_FLASH_ATTR myWebsocketConnect(Websock *ws) {
* @return
*/
httpd_cgi_state ICACHE_FLASH_ATTR tplScreen(HttpdConnData *connData, char *token, void **arg) {
// cleanup
if (!connData) {
if (token==NULL) {
// Release data object
screenSerializeToBuffer(NULL, 0, arg);
return HTTPD_CGI_DONE;
@@ -67,6 +66,9 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplScreen(HttpdConnData *connData, char *token
if (streq(token, "screenData")) {
httpd_cgi_state cont = screenSerializeToBuffer(buff, bufsiz, arg);
dbg("Sending buf: %s", buff);
httpdSend(connData, buff, -1);
return cont;
}
@@ -104,8 +106,7 @@ HttpdBuiltInUrl builtInUrls[]={ //ICACHE_RODATA_ATTR
// TODO add funcs for WiFi management (when web UI is added)
// ROUTE_TPL_FILE("/", tplScreen, "term.tpl"),
ROUTE_TPL("/term.tpl", tplScreen),
ROUTE_TPL_FILE("/", tplScreen, "term.tpl"),
ROUTE_FILESYSTEM(),
ROUTE_END(),
};