Implemented factory reset & split ansi_parser to parser and callbacks
This commit is contained in:
+27
-224
@@ -1,208 +1,11 @@
|
|||||||
|
|
||||||
/* #line 1 "user/ansi_parser.rl" */
|
/* #line 1 "user/ansi_parser.rl" */
|
||||||
#include <esp8266.h>
|
#include <esp8266.h>
|
||||||
#include "screen.h"
|
|
||||||
#include "ansi_parser.h"
|
#include "ansi_parser.h"
|
||||||
|
|
||||||
// Max nr of CSI parameters
|
|
||||||
#define CSI_N_MAX 3
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Handle fully received CSI ANSI sequence
|
|
||||||
* \param leadchar - private range leading character, 0 if none
|
|
||||||
* \param params - array of CSI_N_MAX ints holding the numeric arguments
|
|
||||||
* \param keychar - the char terminating the sequence
|
|
||||||
*/
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_CSI(char leadchar, int *params, char keychar)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Implemented codes (from Wikipedia)
|
|
||||||
|
|
||||||
CSI n A CUU – Cursor Up
|
|
||||||
CSI n B CUD – Cursor Down
|
|
||||||
CSI n C CUF – Cursor Forward
|
|
||||||
CSI n D CUB – Cursor Back
|
|
||||||
CSI n E CNL – Cursor Next Line
|
|
||||||
CSI n F CPL – Cursor Previous Line
|
|
||||||
CSI n G CHA – Cursor Horizontal Absolute
|
|
||||||
CSI n ; m H CUP – Cursor Position
|
|
||||||
CSI n J ED – Erase Display
|
|
||||||
CSI n K EL – Erase in Line
|
|
||||||
CSI n S SU – Scroll Up
|
|
||||||
CSI n T SD – Scroll Down
|
|
||||||
CSI n ; m f HVP – Horizontal and Vertical Position
|
|
||||||
CSI n m SGR – Select Graphic Rendition (Implemented only some)
|
|
||||||
CSI 6n DSR – Device Status Report NOT IMPL
|
|
||||||
CSI s SCP – Save Cursor Position
|
|
||||||
CSI u RCP – Restore Cursor Position
|
|
||||||
CSI ?25l DECTCEM Hides the cursor
|
|
||||||
CSI ?25h DECTCEM Shows the cursor
|
|
||||||
*/
|
|
||||||
|
|
||||||
int n1 = params[0];
|
|
||||||
int n2 = params[1];
|
|
||||||
// int n3 = params[2];
|
|
||||||
|
|
||||||
// defaults
|
|
||||||
switch (keychar) {
|
|
||||||
case 'A':
|
|
||||||
case 'B':
|
|
||||||
case 'C':
|
|
||||||
case 'D':
|
|
||||||
case 'E':
|
|
||||||
case 'F':
|
|
||||||
case 'G':
|
|
||||||
case 'S':
|
|
||||||
case 'T':
|
|
||||||
if (n1 == 0) n1 = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'H':
|
|
||||||
case 'f':
|
|
||||||
if (n1 == 0) n1 = 1;
|
|
||||||
if (n2 == 0) n2 = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'J':
|
|
||||||
case 'K':
|
|
||||||
if (n1 > 2) n1 = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (keychar) {
|
|
||||||
// CUU CUD CUF CUB
|
|
||||||
case 'A': screen_cursor_move(0, -n1); break;
|
|
||||||
case 'B': screen_cursor_move(0, n1); break;
|
|
||||||
case 'C': screen_cursor_move(n1, 0); break;
|
|
||||||
case 'D': screen_cursor_move(-n1, 0); break;
|
|
||||||
|
|
||||||
case 'E': // CNL
|
|
||||||
screen_cursor_move(0, n1);
|
|
||||||
screen_cursor_set_x(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'F': // CPL
|
|
||||||
screen_cursor_move(0, -n1);
|
|
||||||
screen_cursor_set_x(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// CHA
|
|
||||||
case 'G':
|
|
||||||
screen_cursor_set_x(n1 - 1); break; // 1-based
|
|
||||||
|
|
||||||
// SU, SD
|
|
||||||
case 'S': screen_scroll_up(n1); break;
|
|
||||||
case 'T': screen_scroll_down(n1); break;
|
|
||||||
|
|
||||||
// CUP,HVP
|
|
||||||
case 'H':
|
|
||||||
case 'f':
|
|
||||||
screen_cursor_set(n2-1, n1-1); break; // 1-based
|
|
||||||
|
|
||||||
case 'J': // ED
|
|
||||||
if (n1 == 0) {
|
|
||||||
screen_clear(CLEAR_TO_CURSOR);
|
|
||||||
} else if (n1 == 1) {
|
|
||||||
screen_clear(CLEAR_FROM_CURSOR);
|
|
||||||
} else {
|
|
||||||
screen_clear(CLEAR_ALL);
|
|
||||||
screen_cursor_set(0, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'K': // EL
|
|
||||||
if (n1 == 0) {
|
|
||||||
screen_clear_line(CLEAR_TO_CURSOR);
|
|
||||||
} else if (n1 == 1) {
|
|
||||||
screen_clear_line(CLEAR_FROM_CURSOR);
|
|
||||||
} else {
|
|
||||||
screen_clear_line(CLEAR_ALL);
|
|
||||||
screen_cursor_set_x(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// SCP, RCP
|
|
||||||
case 's': screen_cursor_save(); break;
|
|
||||||
case 'u': screen_cursor_restore(); break;
|
|
||||||
|
|
||||||
// DECTCEM cursor show hide
|
|
||||||
case 'l':
|
|
||||||
if (leadchar == '?' && n1 == 25) {
|
|
||||||
screen_cursor_enable(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'h':
|
|
||||||
if (leadchar == '?' && n1 == 25) {
|
|
||||||
screen_cursor_enable(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'm': // SGR
|
|
||||||
// iterate arguments
|
|
||||||
for (int i = 0; i < CSI_N_MAX; i++) {
|
|
||||||
int n = params[i];
|
|
||||||
|
|
||||||
if (i == 0 && n == 0) { // reset SGR
|
|
||||||
screen_set_fg(7);
|
|
||||||
screen_set_bg(0);
|
|
||||||
break; // cannot combine reset with others
|
|
||||||
}
|
|
||||||
else if (n >= 30 && n <= 37) screen_set_fg(n-30); // ANSI normal fg
|
|
||||||
else if (n >= 40 && n <= 47) screen_set_bg(n-40); // ANSI normal bg
|
|
||||||
else if (n == 39) screen_set_fg(7); // default fg
|
|
||||||
else if (n == 49) screen_set_bg(0); // default bg
|
|
||||||
else if (n == 7) screen_inverse(1); // inverse
|
|
||||||
else if (n == 27) screen_inverse(0); // positive
|
|
||||||
else if (n == 1) screen_set_bright_fg(); // ANSI bold = bright fg
|
|
||||||
else if (n >= 90 && n <= 97) screen_set_fg(n-90+8); // AIX bright fg
|
|
||||||
else if (n >= 100 && n <= 107) screen_set_bg(n-100+8); // AIX bright bg
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Handle a request to reset the display device
|
|
||||||
*/
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_RESET_cmd(void)
|
|
||||||
{
|
|
||||||
screen_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Handle a received plain character
|
|
||||||
* \param c - the character
|
|
||||||
*/
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_plainchar(char c)
|
|
||||||
{
|
|
||||||
screen_putchar(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_OSC_FactoryReset(void)
|
|
||||||
{
|
|
||||||
info("OSC: Factory reset");
|
|
||||||
|
|
||||||
warn("NOT IMPLEMENTED");
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_OSC_SetScreenSize(int rows, int cols)
|
|
||||||
{
|
|
||||||
info("OSC: Set screen size to %d x %d", rows, cols);
|
|
||||||
|
|
||||||
screen_resize(rows, cols);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Ragel constants block */
|
/* Ragel constants block */
|
||||||
|
|
||||||
/* #line 206 "user/ansi_parser.c" */
|
/* #line 9 "user/ansi_parser.c" */
|
||||||
static const char _ansi_actions[] = {
|
static const char _ansi_actions[] = {
|
||||||
0, 1, 0, 1, 1, 1, 2, 1,
|
0, 1, 0, 1, 1, 1, 2, 1,
|
||||||
3, 1, 4, 1, 5, 1, 6, 1,
|
3, 1, 4, 1, 5, 1, 6, 1,
|
||||||
@@ -224,7 +27,7 @@ static const int ansi_en_OSC_body = 5;
|
|||||||
static const int ansi_en_main = 1;
|
static const int ansi_en_main = 1;
|
||||||
|
|
||||||
|
|
||||||
/* #line 205 "user/ansi_parser.rl" */
|
/* #line 8 "user/ansi_parser.rl" */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -261,17 +64,17 @@ ansi_parser(const char *newdata, size_t len)
|
|||||||
// Init Ragel on the first run
|
// Init Ragel on the first run
|
||||||
if (cs == -1) {
|
if (cs == -1) {
|
||||||
|
|
||||||
/* #line 265 "user/ansi_parser.c" */
|
/* #line 68 "user/ansi_parser.c" */
|
||||||
{
|
{
|
||||||
cs = ansi_start;
|
cs = ansi_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #line 241 "user/ansi_parser.rl" */
|
/* #line 44 "user/ansi_parser.rl" */
|
||||||
}
|
}
|
||||||
|
|
||||||
// The parser
|
// The parser
|
||||||
|
|
||||||
/* #line 275 "user/ansi_parser.c" */
|
/* #line 78 "user/ansi_parser.c" */
|
||||||
{
|
{
|
||||||
const char *_acts;
|
const char *_acts;
|
||||||
unsigned int _nacts;
|
unsigned int _nacts;
|
||||||
@@ -419,13 +222,13 @@ execFuncs:
|
|||||||
while ( _nacts-- > 0 ) {
|
while ( _nacts-- > 0 ) {
|
||||||
switch ( *_acts++ ) {
|
switch ( *_acts++ ) {
|
||||||
case 0:
|
case 0:
|
||||||
/* #line 251 "user/ansi_parser.rl" */
|
/* #line 54 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
handle_plainchar((*p));
|
apars_handle_plainchar((*p));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
/* #line 258 "user/ansi_parser.rl" */
|
/* #line 61 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
/* Reset the CSI builder */
|
/* Reset the CSI builder */
|
||||||
csi_leading = csi_char = 0;
|
csi_leading = csi_char = 0;
|
||||||
@@ -440,13 +243,13 @@ execFuncs:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
/* #line 271 "user/ansi_parser.rl" */
|
/* #line 74 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
csi_leading = (*p);
|
csi_leading = (*p);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
/* #line 275 "user/ansi_parser.rl" */
|
/* #line 78 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
/* x10 + digit */
|
/* x10 + digit */
|
||||||
if (csi_ni < CSI_N_MAX) {
|
if (csi_ni < CSI_N_MAX) {
|
||||||
@@ -455,30 +258,30 @@ execFuncs:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
/* #line 282 "user/ansi_parser.rl" */
|
/* #line 85 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
csi_ni++;
|
csi_ni++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
/* #line 286 "user/ansi_parser.rl" */
|
/* #line 89 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
csi_char = (*p);
|
csi_char = (*p);
|
||||||
|
|
||||||
handle_CSI(csi_leading, csi_n, csi_char);
|
apars_handle_CSI(csi_leading, csi_n, csi_char);
|
||||||
|
|
||||||
{cs = 1; goto _again;}
|
{cs = 1; goto _again;}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
/* #line 294 "user/ansi_parser.rl" */
|
/* #line 97 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
warn("Invalid escape sequence discarded.");
|
apars_handle_badseq();
|
||||||
{cs = 1; goto _again;}
|
{cs = 1; goto _again;}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
/* #line 311 "user/ansi_parser.rl" */
|
/* #line 114 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
csi_ni = 0;
|
csi_ni = 0;
|
||||||
|
|
||||||
@@ -491,29 +294,29 @@ execFuncs:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
/* #line 322 "user/ansi_parser.rl" */
|
/* #line 125 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
handle_OSC_FactoryReset();
|
apars_handle_OSC_FactoryReset();
|
||||||
{cs = 1; goto _again;}
|
{cs = 1; goto _again;}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
/* #line 327 "user/ansi_parser.rl" */
|
/* #line 130 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
handle_OSC_SetScreenSize(csi_n[0], csi_n[1]);
|
apars_handle_OSC_SetScreenSize(csi_n[0], csi_n[1]);
|
||||||
|
|
||||||
{cs = 1; goto _again;}
|
{cs = 1; goto _again;}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
/* #line 338 "user/ansi_parser.rl" */
|
/* #line 141 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
// Reset screen
|
// Reset screen
|
||||||
handle_RESET_cmd();
|
apars_handle_RESET_cmd();
|
||||||
{cs = 1; goto _again;}
|
{cs = 1; goto _again;}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* #line 517 "user/ansi_parser.c" */
|
/* #line 320 "user/ansi_parser.c" */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto _again;
|
goto _again;
|
||||||
@@ -531,13 +334,13 @@ _again:
|
|||||||
while ( __nacts-- > 0 ) {
|
while ( __nacts-- > 0 ) {
|
||||||
switch ( *__acts++ ) {
|
switch ( *__acts++ ) {
|
||||||
case 6:
|
case 6:
|
||||||
/* #line 294 "user/ansi_parser.rl" */
|
/* #line 97 "user/ansi_parser.rl" */
|
||||||
{
|
{
|
||||||
warn("Invalid escape sequence discarded.");
|
apars_handle_badseq();
|
||||||
{cs = 1; goto _again;}
|
{cs = 1; goto _again;}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* #line 541 "user/ansi_parser.c" */
|
/* #line 344 "user/ansi_parser.c" */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -545,6 +348,6 @@ _again:
|
|||||||
_out: {}
|
_out: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* #line 356 "user/ansi_parser.rl" */
|
/* #line 159 "user/ansi_parser.rl" */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,13 @@
|
|||||||
// Max nr of CSI parameters
|
// Max nr of CSI parameters
|
||||||
#define CSI_N_MAX 3
|
#define CSI_N_MAX 3
|
||||||
|
|
||||||
|
extern void apars_handle_badseq(void);
|
||||||
|
extern void apars_handle_CSI(char leadchar, int *params, char keychar);
|
||||||
|
extern void apars_handle_RESET_cmd(void);
|
||||||
|
extern void apars_handle_plainchar(char c);
|
||||||
|
extern void apars_handle_OSC_FactoryReset(void);
|
||||||
|
extern void apars_handle_OSC_SetScreenSize(int rows, int cols);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Linear ANSI chars stream parser
|
* \brief Linear ANSI chars stream parser
|
||||||
*
|
*
|
||||||
|
|||||||
+6
-203
@@ -1,203 +1,6 @@
|
|||||||
#include <esp8266.h>
|
#include <esp8266.h>
|
||||||
#include "screen.h"
|
|
||||||
#include "ansi_parser.h"
|
#include "ansi_parser.h"
|
||||||
|
|
||||||
// Max nr of CSI parameters
|
|
||||||
#define CSI_N_MAX 3
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Handle fully received CSI ANSI sequence
|
|
||||||
* \param leadchar - private range leading character, 0 if none
|
|
||||||
* \param params - array of CSI_N_MAX ints holding the numeric arguments
|
|
||||||
* \param keychar - the char terminating the sequence
|
|
||||||
*/
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_CSI(char leadchar, int *params, char keychar)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Implemented codes (from Wikipedia)
|
|
||||||
|
|
||||||
CSI n A CUU – Cursor Up
|
|
||||||
CSI n B CUD – Cursor Down
|
|
||||||
CSI n C CUF – Cursor Forward
|
|
||||||
CSI n D CUB – Cursor Back
|
|
||||||
CSI n E CNL – Cursor Next Line
|
|
||||||
CSI n F CPL – Cursor Previous Line
|
|
||||||
CSI n G CHA – Cursor Horizontal Absolute
|
|
||||||
CSI n ; m H CUP – Cursor Position
|
|
||||||
CSI n J ED – Erase Display
|
|
||||||
CSI n K EL – Erase in Line
|
|
||||||
CSI n S SU – Scroll Up
|
|
||||||
CSI n T SD – Scroll Down
|
|
||||||
CSI n ; m f HVP – Horizontal and Vertical Position
|
|
||||||
CSI n m SGR – Select Graphic Rendition (Implemented only some)
|
|
||||||
CSI 6n DSR – Device Status Report NOT IMPL
|
|
||||||
CSI s SCP – Save Cursor Position
|
|
||||||
CSI u RCP – Restore Cursor Position
|
|
||||||
CSI ?25l DECTCEM Hides the cursor
|
|
||||||
CSI ?25h DECTCEM Shows the cursor
|
|
||||||
*/
|
|
||||||
|
|
||||||
int n1 = params[0];
|
|
||||||
int n2 = params[1];
|
|
||||||
// int n3 = params[2];
|
|
||||||
|
|
||||||
// defaults
|
|
||||||
switch (keychar) {
|
|
||||||
case 'A':
|
|
||||||
case 'B':
|
|
||||||
case 'C':
|
|
||||||
case 'D':
|
|
||||||
case 'E':
|
|
||||||
case 'F':
|
|
||||||
case 'G':
|
|
||||||
case 'S':
|
|
||||||
case 'T':
|
|
||||||
if (n1 == 0) n1 = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'H':
|
|
||||||
case 'f':
|
|
||||||
if (n1 == 0) n1 = 1;
|
|
||||||
if (n2 == 0) n2 = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'J':
|
|
||||||
case 'K':
|
|
||||||
if (n1 > 2) n1 = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (keychar) {
|
|
||||||
// CUU CUD CUF CUB
|
|
||||||
case 'A': screen_cursor_move(0, -n1); break;
|
|
||||||
case 'B': screen_cursor_move(0, n1); break;
|
|
||||||
case 'C': screen_cursor_move(n1, 0); break;
|
|
||||||
case 'D': screen_cursor_move(-n1, 0); break;
|
|
||||||
|
|
||||||
case 'E': // CNL
|
|
||||||
screen_cursor_move(0, n1);
|
|
||||||
screen_cursor_set_x(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'F': // CPL
|
|
||||||
screen_cursor_move(0, -n1);
|
|
||||||
screen_cursor_set_x(0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// CHA
|
|
||||||
case 'G':
|
|
||||||
screen_cursor_set_x(n1 - 1); break; // 1-based
|
|
||||||
|
|
||||||
// SU, SD
|
|
||||||
case 'S': screen_scroll_up(n1); break;
|
|
||||||
case 'T': screen_scroll_down(n1); break;
|
|
||||||
|
|
||||||
// CUP,HVP
|
|
||||||
case 'H':
|
|
||||||
case 'f':
|
|
||||||
screen_cursor_set(n2-1, n1-1); break; // 1-based
|
|
||||||
|
|
||||||
case 'J': // ED
|
|
||||||
if (n1 == 0) {
|
|
||||||
screen_clear(CLEAR_TO_CURSOR);
|
|
||||||
} else if (n1 == 1) {
|
|
||||||
screen_clear(CLEAR_FROM_CURSOR);
|
|
||||||
} else {
|
|
||||||
screen_clear(CLEAR_ALL);
|
|
||||||
screen_cursor_set(0, 0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'K': // EL
|
|
||||||
if (n1 == 0) {
|
|
||||||
screen_clear_line(CLEAR_TO_CURSOR);
|
|
||||||
} else if (n1 == 1) {
|
|
||||||
screen_clear_line(CLEAR_FROM_CURSOR);
|
|
||||||
} else {
|
|
||||||
screen_clear_line(CLEAR_ALL);
|
|
||||||
screen_cursor_set_x(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// SCP, RCP
|
|
||||||
case 's': screen_cursor_save(); break;
|
|
||||||
case 'u': screen_cursor_restore(); break;
|
|
||||||
|
|
||||||
// DECTCEM cursor show hide
|
|
||||||
case 'l':
|
|
||||||
if (leadchar == '?' && n1 == 25) {
|
|
||||||
screen_cursor_enable(1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'h':
|
|
||||||
if (leadchar == '?' && n1 == 25) {
|
|
||||||
screen_cursor_enable(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'm': // SGR
|
|
||||||
// iterate arguments
|
|
||||||
for (int i = 0; i < CSI_N_MAX; i++) {
|
|
||||||
int n = params[i];
|
|
||||||
|
|
||||||
if (i == 0 && n == 0) { // reset SGR
|
|
||||||
screen_set_fg(7);
|
|
||||||
screen_set_bg(0);
|
|
||||||
break; // cannot combine reset with others
|
|
||||||
}
|
|
||||||
else if (n >= 30 && n <= 37) screen_set_fg(n-30); // ANSI normal fg
|
|
||||||
else if (n >= 40 && n <= 47) screen_set_bg(n-40); // ANSI normal bg
|
|
||||||
else if (n == 39) screen_set_fg(7); // default fg
|
|
||||||
else if (n == 49) screen_set_bg(0); // default bg
|
|
||||||
else if (n == 7) screen_inverse(1); // inverse
|
|
||||||
else if (n == 27) screen_inverse(0); // positive
|
|
||||||
else if (n == 1) screen_set_bright_fg(); // ANSI bold = bright fg
|
|
||||||
else if (n >= 90 && n <= 97) screen_set_fg(n-90+8); // AIX bright fg
|
|
||||||
else if (n >= 100 && n <= 107) screen_set_bg(n-100+8); // AIX bright bg
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Handle a request to reset the display device
|
|
||||||
*/
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_RESET_cmd(void)
|
|
||||||
{
|
|
||||||
screen_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Handle a received plain character
|
|
||||||
* \param c - the character
|
|
||||||
*/
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_plainchar(char c)
|
|
||||||
{
|
|
||||||
screen_putchar(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_OSC_FactoryReset(void)
|
|
||||||
{
|
|
||||||
info("OSC: Factory reset");
|
|
||||||
|
|
||||||
warn("NOT IMPLEMENTED");
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void ICACHE_FLASH_ATTR
|
|
||||||
handle_OSC_SetScreenSize(int rows, int cols)
|
|
||||||
{
|
|
||||||
info("OSC: Set screen size to %d x %d", rows, cols);
|
|
||||||
|
|
||||||
screen_resize(rows, cols);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Ragel constants block */
|
/* Ragel constants block */
|
||||||
%%{
|
%%{
|
||||||
machine ansi;
|
machine ansi;
|
||||||
@@ -249,7 +52,7 @@ ansi_parser(const char *newdata, size_t len)
|
|||||||
# --- Regular characters to be printed ---
|
# --- Regular characters to be printed ---
|
||||||
|
|
||||||
action plain_char {
|
action plain_char {
|
||||||
handle_plainchar(fc);
|
apars_handle_plainchar(fc);
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- CSI CSI commands (Select Graphic Rendition) ---
|
# --- CSI CSI commands (Select Graphic Rendition) ---
|
||||||
@@ -286,13 +89,13 @@ ansi_parser(const char *newdata, size_t len)
|
|||||||
action CSI_end {
|
action CSI_end {
|
||||||
csi_char = fc;
|
csi_char = fc;
|
||||||
|
|
||||||
handle_CSI(csi_leading, csi_n, csi_char);
|
apars_handle_CSI(csi_leading, csi_n, csi_char);
|
||||||
|
|
||||||
fgoto main;
|
fgoto main;
|
||||||
}
|
}
|
||||||
|
|
||||||
action errBadSeq {
|
action errBadSeq {
|
||||||
warn("Invalid escape sequence discarded.");
|
apars_handle_badseq();
|
||||||
fgoto main;
|
fgoto main;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,12 +123,12 @@ ansi_parser(const char *newdata, size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
action OSC_fr {
|
action OSC_fr {
|
||||||
handle_OSC_FactoryReset();
|
apars_handle_OSC_FactoryReset();
|
||||||
fgoto main;
|
fgoto main;
|
||||||
}
|
}
|
||||||
|
|
||||||
action OSC_resize {
|
action OSC_resize {
|
||||||
handle_OSC_SetScreenSize(csi_n[0], csi_n[1]);
|
apars_handle_OSC_SetScreenSize(csi_n[0], csi_n[1]);
|
||||||
|
|
||||||
fgoto main;
|
fgoto main;
|
||||||
}
|
}
|
||||||
@@ -337,7 +140,7 @@ ansi_parser(const char *newdata, size_t len)
|
|||||||
|
|
||||||
action RESET_cmd {
|
action RESET_cmd {
|
||||||
// Reset screen
|
// Reset screen
|
||||||
handle_RESET_cmd();
|
apars_handle_RESET_cmd();
|
||||||
fgoto main;
|
fgoto main;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,256 @@
|
|||||||
|
/**
|
||||||
|
* ANSI code parser callbacks that do the actual work.
|
||||||
|
* Split from the parser itself for easier editing without
|
||||||
|
* having to deal with Ragel.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <esp8266.h>
|
||||||
|
#include "ansi_parser_callbacks.h"
|
||||||
|
#include "screen.h"
|
||||||
|
#include "ansi_parser.h"
|
||||||
|
#include "uart_driver.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a received plain character
|
||||||
|
*/
|
||||||
|
void ICACHE_FLASH_ATTR
|
||||||
|
apars_handle_plainchar(char c)
|
||||||
|
{
|
||||||
|
screen_putchar(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bad sequence received, show warning
|
||||||
|
*/
|
||||||
|
void apars_handle_badseq(void)
|
||||||
|
{
|
||||||
|
warn("Invalid escape sequence discarded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Handle fully received CSI ANSI sequence
|
||||||
|
* \param leadchar - private range leading character, 0 if none
|
||||||
|
* \param params - array of CSI_N_MAX ints holding the numeric arguments
|
||||||
|
* \param keychar - the char terminating the sequence
|
||||||
|
*/
|
||||||
|
void ICACHE_FLASH_ATTR
|
||||||
|
apars_handle_CSI(char leadchar, int *params, char keychar)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Implemented codes (from Wikipedia)
|
||||||
|
|
||||||
|
CSI n A CUU – Cursor Up
|
||||||
|
CSI n B CUD – Cursor Down
|
||||||
|
CSI n C CUF – Cursor Forward
|
||||||
|
CSI n D CUB – Cursor Back
|
||||||
|
CSI n E CNL – Cursor Next Line
|
||||||
|
CSI n F CPL – Cursor Previous Line
|
||||||
|
CSI n G CHA – Cursor Horizontal Absolute
|
||||||
|
CSI n ; m H CUP – Cursor Position
|
||||||
|
CSI n J ED – Erase Display
|
||||||
|
CSI n K EL – Erase in Line
|
||||||
|
CSI n S SU – Scroll Up
|
||||||
|
CSI n T SD – Scroll Down
|
||||||
|
CSI n ; m f HVP – Horizontal and Vertical Position
|
||||||
|
CSI n m SGR – Select Graphic Rendition (Implemented only some)
|
||||||
|
CSI 6n DSR – Device Status Report NOT IMPL
|
||||||
|
CSI s SCP – Save Cursor Position
|
||||||
|
CSI u RCP – Restore Cursor Position
|
||||||
|
CSI ?25l DECTCEM Hides the cursor
|
||||||
|
CSI ?25h DECTCEM Shows the cursor
|
||||||
|
*/
|
||||||
|
|
||||||
|
int n1 = params[0];
|
||||||
|
int n2 = params[1];
|
||||||
|
// int n3 = params[2];
|
||||||
|
|
||||||
|
// defaults
|
||||||
|
switch (keychar) {
|
||||||
|
case 'A':
|
||||||
|
case 'B':
|
||||||
|
case 'C':
|
||||||
|
case 'D':
|
||||||
|
case 'E':
|
||||||
|
case 'F':
|
||||||
|
case 'G':
|
||||||
|
case 'S':
|
||||||
|
case 'T':
|
||||||
|
if (n1 == 0) n1 = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'H':
|
||||||
|
case 'f':
|
||||||
|
if (n1 == 0) n1 = 1;
|
||||||
|
if (n2 == 0) n2 = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'J':
|
||||||
|
case 'K':
|
||||||
|
if (n1 > 2) n1 = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (keychar) {
|
||||||
|
// CUU CUD CUF CUB
|
||||||
|
case 'A': screen_cursor_move(0, -n1); break;
|
||||||
|
case 'B': screen_cursor_move(0, n1); break;
|
||||||
|
case 'C': screen_cursor_move(n1, 0); break;
|
||||||
|
case 'D': screen_cursor_move(-n1, 0); break;
|
||||||
|
|
||||||
|
case 'E': // CNL
|
||||||
|
screen_cursor_move(0, n1);
|
||||||
|
screen_cursor_set_x(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'F': // CPL
|
||||||
|
screen_cursor_move(0, -n1);
|
||||||
|
screen_cursor_set_x(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// CHA
|
||||||
|
case 'G':
|
||||||
|
screen_cursor_set_x(n1 - 1); break; // 1-based
|
||||||
|
|
||||||
|
// SU, SD
|
||||||
|
case 'S': screen_scroll_up(n1); break;
|
||||||
|
case 'T': screen_scroll_down(n1); break;
|
||||||
|
|
||||||
|
// CUP,HVP
|
||||||
|
case 'H':
|
||||||
|
case 'f':
|
||||||
|
screen_cursor_set(n2-1, n1-1); break; // 1-based
|
||||||
|
|
||||||
|
case 'J': // ED
|
||||||
|
if (n1 == 0) {
|
||||||
|
screen_clear(CLEAR_TO_CURSOR);
|
||||||
|
} else if (n1 == 1) {
|
||||||
|
screen_clear(CLEAR_FROM_CURSOR);
|
||||||
|
} else {
|
||||||
|
screen_clear(CLEAR_ALL);
|
||||||
|
screen_cursor_set(0, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'K': // EL
|
||||||
|
if (n1 == 0) {
|
||||||
|
screen_clear_line(CLEAR_TO_CURSOR);
|
||||||
|
} else if (n1 == 1) {
|
||||||
|
screen_clear_line(CLEAR_FROM_CURSOR);
|
||||||
|
} else {
|
||||||
|
screen_clear_line(CLEAR_ALL);
|
||||||
|
screen_cursor_set_x(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// SCP, RCP
|
||||||
|
case 's': screen_cursor_save(); break;
|
||||||
|
case 'u': screen_cursor_restore(); break;
|
||||||
|
|
||||||
|
// DECTCEM cursor show hide
|
||||||
|
case 'l':
|
||||||
|
if (leadchar == '?' && n1 == 25) {
|
||||||
|
screen_cursor_enable(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
if (leadchar == '?' && n1 == 25) {
|
||||||
|
screen_cursor_enable(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm': // SGR
|
||||||
|
// iterate arguments
|
||||||
|
for (int i = 0; i < CSI_N_MAX; i++) {
|
||||||
|
int n = params[i];
|
||||||
|
|
||||||
|
if (i == 0 && n == 0) { // reset SGR
|
||||||
|
screen_set_fg(7);
|
||||||
|
screen_set_bg(0);
|
||||||
|
break; // cannot combine reset with others
|
||||||
|
}
|
||||||
|
else if (n >= 30 && n <= 37) screen_set_fg(n-30); // ANSI normal fg
|
||||||
|
else if (n >= 40 && n <= 47) screen_set_bg(n-40); // ANSI normal bg
|
||||||
|
else if (n == 39) screen_set_fg(7); // default fg
|
||||||
|
else if (n == 49) screen_set_bg(0); // default bg
|
||||||
|
else if (n == 7) screen_inverse(1); // inverse
|
||||||
|
else if (n == 27) screen_inverse(0); // positive
|
||||||
|
else if (n == 1) screen_set_bright_fg(); // ANSI bold = bright fg
|
||||||
|
else if (n >= 90 && n <= 97) screen_set_fg(n-90+8); // AIX bright fg
|
||||||
|
else if (n >= 100 && n <= 107) screen_set_bg(n-100+8); // AIX bright bg
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Handle a request to reset the display device
|
||||||
|
*/
|
||||||
|
void ICACHE_FLASH_ATTR
|
||||||
|
apars_handle_RESET_cmd(void)
|
||||||
|
{
|
||||||
|
// XXX maybe user wanted to reset the module instead?
|
||||||
|
screen_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a factory reset request
|
||||||
|
*/
|
||||||
|
void ICACHE_FLASH_ATTR
|
||||||
|
apars_handle_OSC_FactoryReset(void)
|
||||||
|
{
|
||||||
|
info("OSC: Factory reset");
|
||||||
|
|
||||||
|
// Send acknowledgement message to UART0
|
||||||
|
// User is performing this manually, so we can just print it as string
|
||||||
|
UART_WriteString(UART0, "\r\nFACTORY RESET\r\n", UART_TIMEOUT_US);
|
||||||
|
|
||||||
|
// Disconnect from AP if connected
|
||||||
|
int opmode = wifi_get_opmode();
|
||||||
|
if (opmode != SOFTAP_MODE) {
|
||||||
|
wifi_station_disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both must be enabled so we can manipulate their settings
|
||||||
|
wifi_set_opmode(STATIONAP_MODE);
|
||||||
|
|
||||||
|
// --- AP config ---
|
||||||
|
struct softap_config apconf;
|
||||||
|
wifi_softap_get_config(&apconf);
|
||||||
|
apconf.authmode=AUTH_OPEN; // Disable access protection
|
||||||
|
apconf.channel=1; // Reset channel; user may have set bad channel in the UI
|
||||||
|
|
||||||
|
// generate unique AP name
|
||||||
|
u8 mac[6];
|
||||||
|
wifi_get_macaddr(SOFTAP_IF, mac);
|
||||||
|
sprintf((char*)apconf.ssid, "TERM-%02X%02X%02X", mac[3], mac[4], mac[5]);
|
||||||
|
apconf.ssid_len = (u8)strlen((char*)apconf.ssid);
|
||||||
|
|
||||||
|
// --- Station ---
|
||||||
|
struct station_config staconf;
|
||||||
|
wifi_station_get_config(&staconf);
|
||||||
|
|
||||||
|
// clear info about SSID
|
||||||
|
staconf.ssid[0]=0;
|
||||||
|
staconf.bssid_set=0;
|
||||||
|
staconf.password[0]=0;
|
||||||
|
|
||||||
|
wifi_softap_set_config(&apconf);
|
||||||
|
wifi_station_set_config(&staconf);
|
||||||
|
|
||||||
|
UART_WriteString(UART0, "Factory Reset complete, device reset.\r\n\r\n", UART_TIMEOUT_US);
|
||||||
|
|
||||||
|
// Reboot to clean STA+AP mode with Channel 1 & reset AP SSID.
|
||||||
|
system_restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a screen resize request
|
||||||
|
*/
|
||||||
|
void ICACHE_FLASH_ATTR
|
||||||
|
apars_handle_OSC_SetScreenSize(int rows, int cols)
|
||||||
|
{
|
||||||
|
info("OSC: Set screen size to %d x %d", rows, cols);
|
||||||
|
|
||||||
|
screen_resize(rows, cols);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef ANSI_PARSER_CALLBACKS_H
|
||||||
|
#define ANSI_PARSER_CALLBACKS_H
|
||||||
|
|
||||||
|
void apars_handle_badseq(void);
|
||||||
|
void apars_handle_CSI(char leadchar, int *params, char keychar);
|
||||||
|
void apars_handle_RESET_cmd(void);
|
||||||
|
void apars_handle_plainchar(char c);
|
||||||
|
void apars_handle_OSC_FactoryReset(void);
|
||||||
|
void apars_handle_OSC_SetScreenSize(int rows, int cols);
|
||||||
|
|
||||||
|
#endif //ESP_VT100_FIRMWARE_ANSI_PARSER_CALLBACKS_H
|
||||||
Reference in New Issue
Block a user