|
|
@ -10,7 +10,7 @@ TerminalConfigBundle * const termconf = &persist.current.termconf; |
|
|
|
TerminalConfigBundle termconf_scratch; |
|
|
|
TerminalConfigBundle termconf_scratch; |
|
|
|
|
|
|
|
|
|
|
|
// forward declare
|
|
|
|
// forward declare
|
|
|
|
static void utf8_remap(char* out, char g, char table); |
|
|
|
static void utf8_remap(char* out, char g, char charset); |
|
|
|
|
|
|
|
|
|
|
|
#define W termconf_scratch.width |
|
|
|
#define W termconf_scratch.width |
|
|
|
#define H termconf_scratch.height |
|
|
|
#define H termconf_scratch.height |
|
|
@ -55,9 +55,6 @@ static struct { |
|
|
|
// Vertical margin bounds (inclusive start/end of scrolling region)
|
|
|
|
// Vertical margin bounds (inclusive start/end of scrolling region)
|
|
|
|
int vm0; |
|
|
|
int vm0; |
|
|
|
int vm1; |
|
|
|
int vm1; |
|
|
|
|
|
|
|
|
|
|
|
char charset0; |
|
|
|
|
|
|
|
char charset1; |
|
|
|
|
|
|
|
} scr; |
|
|
|
} scr; |
|
|
|
|
|
|
|
|
|
|
|
#define R0 scr.vm0 |
|
|
|
#define R0 scr.vm0 |
|
|
@ -77,6 +74,8 @@ typedef struct { |
|
|
|
|
|
|
|
|
|
|
|
// Other attribs
|
|
|
|
// Other attribs
|
|
|
|
int charsetN; |
|
|
|
int charsetN; |
|
|
|
|
|
|
|
char charset0; |
|
|
|
|
|
|
|
char charset1; |
|
|
|
bool wraparound; //!< Wrapping when EOL
|
|
|
|
bool wraparound; //!< Wrapping when EOL
|
|
|
|
bool origin_mode; // DECOM - absolute positioning is relative to vertical margins
|
|
|
|
bool origin_mode; // DECOM - absolute positioning is relative to vertical margins
|
|
|
|
bool selective_erase; // TODO implement
|
|
|
|
bool selective_erase; // TODO implement
|
|
|
@ -95,6 +94,7 @@ static CursorTypeDef cursor; |
|
|
|
* Saved cursor position, used with the SCP RCP commands |
|
|
|
* Saved cursor position, used with the SCP RCP commands |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static CursorTypeDef cursor_sav; |
|
|
|
static CursorTypeDef cursor_sav; |
|
|
|
|
|
|
|
bool cursor_saved = false; |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* This is used to prevent premature change notifications |
|
|
|
* This is used to prevent premature change notifications |
|
|
@ -215,6 +215,8 @@ cursor_reset(void) |
|
|
|
cursor.origin_mode = false; |
|
|
|
cursor.origin_mode = false; |
|
|
|
|
|
|
|
|
|
|
|
cursor.charsetN = 0; |
|
|
|
cursor.charsetN = 0; |
|
|
|
|
|
|
|
cursor.charset0 = CS_USASCII; |
|
|
|
|
|
|
|
cursor.charset1 = CS_DEC_SUPPLEMENTAL; |
|
|
|
cursor.wraparound = true; |
|
|
|
cursor.wraparound = true; |
|
|
|
|
|
|
|
|
|
|
|
screen_reset_sgr(); |
|
|
|
screen_reset_sgr(); |
|
|
@ -247,9 +249,6 @@ screen_reset(void) |
|
|
|
scr.newline_mode = false; |
|
|
|
scr.newline_mode = false; |
|
|
|
scr.reverse = false; |
|
|
|
scr.reverse = false; |
|
|
|
|
|
|
|
|
|
|
|
scr.charset0 = 'B'; |
|
|
|
|
|
|
|
scr.charset1 = '0'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scr.vm0 = 0; |
|
|
|
scr.vm0 = 0; |
|
|
|
scr.vm1 = H-1; |
|
|
|
scr.vm1 = H-1; |
|
|
|
|
|
|
|
|
|
|
@ -834,6 +833,7 @@ screen_cursor_save(bool withAttrs) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// always save with attribs
|
|
|
|
// always save with attribs
|
|
|
|
memcpy(&cursor_sav, &cursor, sizeof(CursorTypeDef)); |
|
|
|
memcpy(&cursor_sav, &cursor, sizeof(CursorTypeDef)); |
|
|
|
|
|
|
|
cursor_saved = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -844,12 +844,18 @@ screen_cursor_restore(bool withAttrs) |
|
|
|
{ |
|
|
|
{ |
|
|
|
NOTIFY_LOCK(); |
|
|
|
NOTIFY_LOCK(); |
|
|
|
|
|
|
|
|
|
|
|
if (withAttrs) { |
|
|
|
if (!cursor_saved) { |
|
|
|
memcpy(&cursor_sav, &cursor, sizeof(CursorTypeDef)); |
|
|
|
cursor_reset(); |
|
|
|
} else { |
|
|
|
} |
|
|
|
cursor.x = cursor_sav.x; |
|
|
|
else { |
|
|
|
cursor.y = cursor_sav.y; |
|
|
|
if (withAttrs) { |
|
|
|
cursor.hanging = cursor_sav.hanging; |
|
|
|
memcpy(&cursor, &cursor_sav, sizeof(CursorTypeDef)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
cursor.x = cursor_sav.x; |
|
|
|
|
|
|
|
cursor.y = cursor_sav.y; |
|
|
|
|
|
|
|
cursor.hanging = cursor_sav.hanging; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
NOTIFY_DONE(); |
|
|
|
NOTIFY_DONE(); |
|
|
@ -938,8 +944,8 @@ screen_set_charset_n(int Gx) |
|
|
|
void ICACHE_FLASH_ATTR |
|
|
|
void ICACHE_FLASH_ATTR |
|
|
|
screen_set_charset(int Gx, char charset) |
|
|
|
screen_set_charset(int Gx, char charset) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (Gx == 0) scr.charset0 = charset; |
|
|
|
if (Gx == 0) cursor.charset0 = charset; |
|
|
|
else if (Gx == 1) scr.charset1 = charset; |
|
|
|
else if (Gx == 1) cursor.charset1 = charset; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void ICACHE_FLASH_ATTR |
|
|
|
void ICACHE_FLASH_ATTR |
|
|
@ -1073,7 +1079,7 @@ screen_putchar(const char *ch) |
|
|
|
|
|
|
|
|
|
|
|
if (ch[1] == 0 && ch[0] <= 0x7f) { |
|
|
|
if (ch[1] == 0 && ch[0] <= 0x7f) { |
|
|
|
// we have len=1 and ASCII
|
|
|
|
// we have len=1 and ASCII
|
|
|
|
utf8_remap(c->c, ch[0], (cursor.charsetN == 0) ? scr.charset0 : scr.charset1); |
|
|
|
utf8_remap(c->c, ch[0], (cursor.charsetN == 0) ? cursor.charset0 : cursor.charset1); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
// copy unicode char
|
|
|
|
// copy unicode char
|
|
|
@ -1241,32 +1247,37 @@ static const u16 codepage_1[] = |
|
|
|
* UTF remap |
|
|
|
* UTF remap |
|
|
|
* @param out - output char[4] |
|
|
|
* @param out - output char[4] |
|
|
|
* @param g - ASCII char |
|
|
|
* @param g - ASCII char |
|
|
|
* @param table - table name (0, A, B) |
|
|
|
* @param charset - table name (0, A, B) |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static void ICACHE_FLASH_ATTR |
|
|
|
static void ICACHE_FLASH_ATTR |
|
|
|
utf8_remap(char *out, char g, char table) |
|
|
|
utf8_remap(char *out, char g, char charset) |
|
|
|
{ |
|
|
|
{ |
|
|
|
u16 n; |
|
|
|
u16 n; |
|
|
|
u16 utf = (unsigned char)g; |
|
|
|
u16 utf = (unsigned char)g; |
|
|
|
|
|
|
|
|
|
|
|
switch (table) { |
|
|
|
switch (charset) { |
|
|
|
case '0': /* DEC Special Character & Line Drawing Set */ |
|
|
|
case CS_DEC_SUPPLEMENTAL: /* DEC Special Character & Line Drawing Set */ |
|
|
|
if ((g >= 96) && (g < 0x7F)) { |
|
|
|
if ((g >= 96) && (g < 0x7F)) { |
|
|
|
n = codepage_0[g - 96]; |
|
|
|
n = codepage_0[g - 96]; |
|
|
|
if (n) utf = n; |
|
|
|
if (n) utf = n; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case '1': /* ESPTerm Character Rom 1 */ |
|
|
|
case CS_DOS_437: /* ESPTerm Character Rom 1 */ |
|
|
|
if ((g >= 33) && (g < 0x7F)) { |
|
|
|
if ((g >= 33) && (g < 0x7F)) { |
|
|
|
n = codepage_1[g - 33]; |
|
|
|
n = codepage_1[g - 33]; |
|
|
|
if (n) utf = n; |
|
|
|
if (n) utf = n; |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case 'A': /* UK, replaces # with GBP */ |
|
|
|
case CS_UKASCII: /* UK, replaces # with GBP */ |
|
|
|
if (g == '#') utf = 0x20a4; |
|
|
|
if (g == '#') utf = 0x20a4; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
case CS_USASCII: |
|
|
|
|
|
|
|
// No change
|
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Encode to UTF-8
|
|
|
|
// Encode to UTF-8
|
|
|
|