working terminal
This commit is contained in:
+41
-28
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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(),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user