Backend changes for offscale default fg and bg + future-proofing

- 16-bit attribs
- added attribs FG and BG, if not set, default colors
- added attrib INVERT, removed server-side color flipping
- added screen attrib REVERSE_VIDEO (can't be done server-side if we want it to work with off-scale colors)
- changed Attribs encoding to 3B
- removed old migrations, made useless by the flash wipe caused by adding Admin PW section
- some cleaning in CSI parser
- removed function to set SGR inverse separately (now use normal SGR setter)
- added functions to set fg and bg to defaults
http-comm
Ondřej Hruška 7 years ago
parent 7607b639b0
commit 948bcb62ff
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 38
      user/apars_csi.c
  2. 8
      user/cgi_main.c
  3. 4
      user/cgi_term_cfg.c
  4. 2
      user/persist.h
  5. 147
      user/screen.c
  6. 39
      user/screen.h
  7. 19
      user/syscfg.c
  8. 2
      user/syscfg.h

@ -551,31 +551,27 @@ do_csi_sgr(CSI_Data *opts)
else if (n >= SGR_FG_BRT_START && n <= SGR_FG_BRT_END) screen_set_fg((Color) ((n - SGR_FG_BRT_START) + 8)); // AIX bright fg
else if (n >= SGR_BG_BRT_START && n <= SGR_BG_BRT_END) screen_set_bg((Color) ((n - SGR_BG_BRT_START) + 8)); // AIX bright bg
// reset color
else if (n == SGR_FG_DEFAULT) screen_set_fg(termconf_live.default_fg); // default fg
else if (n == SGR_BG_DEFAULT) screen_set_bg(termconf_live.default_bg); // default bg
else if (n == SGR_FG_DEFAULT) screen_set_default_fg();
else if (n == SGR_BG_DEFAULT) screen_set_default_bg();
// 256 colors
else if (n == SGR_FG_256 || n == SGR_BG_256) {
if (i < count-2) {
if (opts->n[i + 1] == 5) {
u8 color = (u8) opts->n[i + 2];
bool fg = n == SGR_FG_256;
if (fg) {
screen_set_fg(color);
} else {
screen_set_bg(color);
}
}
else {
ansi_warn("SGR syntax err");
apars_show_context();
break; // abandon further
}
i += 2;
} else {
if (i >= count-2) {
ansi_warn("SGR syntax err");
apars_show_context();
break; // abandon further
}
if (opts->n[i + 1] != 5) {
ansi_warn("SGR syntax err");
apars_show_context();
break; // abandon further
}
u8 color = (u8) opts->n[i + 2];
bool fg = n == SGR_FG_256;
if (fg) screen_set_fg(color);
else screen_set_bg(color);
i += 2;
}
// -- set attr --
else if (n == SGR_BOLD) screen_set_sgr(ATTR_BOLD, 1);
@ -585,7 +581,7 @@ do_csi_sgr(CSI_Data *opts)
else if (n == SGR_BLINK || n == SGR_BLINK_FAST) screen_set_sgr(ATTR_BLINK, 1); // 6 - rapid blink, not supported
else if (n == SGR_STRIKE) screen_set_sgr(ATTR_STRIKE, 1);
else if (n == SGR_FRAKTUR) screen_set_sgr(ATTR_FRAKTUR, 1);
else if (n == SGR_INVERSE) screen_set_sgr_inverse(1);
else if (n == SGR_INVERSE) screen_set_sgr(ATTR_INVERSE, 1);
else if (n == SGR_CONCEAL) screen_set_sgr_conceal(1);
else if (n == SGR_OVERLINE) screen_set_sgr(ATTR_OVERLINE, 1);
// -- clear attr --
@ -595,7 +591,7 @@ do_csi_sgr(CSI_Data *opts)
else if (n == SGR_NO_UNDERLINE) screen_set_sgr(ATTR_UNDERLINE, 0);
else if (n == SGR_NO_BLINK) screen_set_sgr(ATTR_BLINK, 0);
else if (n == SGR_NO_STRIKE) screen_set_sgr(ATTR_STRIKE, 0);
else if (n == SGR_NO_INVERSE) screen_set_sgr_inverse(0);
else if (n == SGR_NO_INVERSE) screen_set_sgr(ATTR_INVERSE, 0);
else if (n == SGR_NO_CONCEAL) screen_set_sgr_conceal(0);
else if (n == SGR_NO_OVERLINE) screen_set_sgr(ATTR_OVERLINE, 0);
else {

@ -37,6 +37,14 @@ httpd_cgi_state ICACHE_FLASH_ATTR tplScreen(HttpdConnData *connData, char *token
sprintf(buff, "%d", termconf->want_all_fn);
tplSend(connData, buff, -1);
}
else if (streq(token, "default_fg")) {
sprintf(buff, "0x%08X", termconf->default_fg);
tplSend(connData, buff, -1);
}
else if (streq(token, "default_bg")) {
sprintf(buff, "0x%08X", termconf->default_bg);
tplSend(connData, buff, -1);
}
return HTTPD_CGI_DONE;
}

@ -86,7 +86,7 @@ cgiTermCfgSetParams(HttpdConnData *connData)
n = atoi(buff);
if (n >= 0 && n < 16) {
if (termconf->default_bg != n) {
termconf->default_bg = (u8) n;
termconf->default_bg = n;
shall_clear_screen = true;
}
} else {
@ -100,7 +100,7 @@ cgiTermCfgSetParams(HttpdConnData *connData)
n = atoi(buff);
if (n >= 0 && n < 16) {
if (termconf->default_fg != n) {
termconf->default_fg = (u8) n;
termconf->default_fg = n;
shall_clear_screen = true;
}
} else {

@ -52,7 +52,7 @@ typedef struct { // the entire block should be 1024 bytes long (for compatibilit
uint32_t checksum; // computed before write and tested on load. If it doesn't match, values are reset to hard defaults.
} AppConfigBundle;
#define ADMINCONF_VERSION 1
#define ADMINCONF_VERSION 0
#define ADMINCONF_SIZE 256
typedef struct {

@ -20,11 +20,6 @@ static void utf8_remap(char* out, char g, char charset);
#define W termconf_live.width
#define H termconf_live.height
/**
* Highest permissible value of the color attribute
*/
#define COLOR_MAX 15
/**
* Screen cell data type (16 bits)
*/
@ -32,7 +27,7 @@ typedef struct __attribute__((packed)) {
UnicodeCacheRef symbol : 8;
Color fg;
Color bg;
u8 attrs;
CellAttrs attrs;
} Cell;
/**
@ -78,9 +73,9 @@ typedef struct {
bool hanging; //!< xenl state - cursor half-wrapped
/* SGR */
bool inverse; //!< not in attrs bc it's applied server-side (not sent to browser)
bool conceal; //!< similar to inverse, causes all to be replaced by SP
u8 attrs;
bool inverse; //!< not in attrs bc it's applied immediately when writing the cell
bool conceal; //!< similar to inverse, causes all to be replaced by SP
u16 attrs;
Color fg; //!< Foreground color for writing
Color bg; //!< Background color for writing
@ -207,45 +202,12 @@ terminal_apply_settings_noclear(void)
{
bool changed = false;
// Migrate to v1
if (termconf->config_version < 1) {
persist_dbg("termconf: Updating to version 1");
termconf->display_cooldown_ms = SCR_DEF_DISPLAY_COOLDOWN_MS;
changed = 1;
}
// Migrate to v2
if (termconf->config_version < 2) {
persist_dbg("termconf: Updating to version 2");
termconf->loopback = 0;
termconf->show_config_links = 1;
termconf->show_buttons = 1;
changed = 1;
}
// Migrate to v3
if (termconf->config_version < 3) {
persist_dbg("termconf: Updating to version 3");
for(int i=1; i <= TERM_BTN_COUNT; i++) {
sprintf(termconf->btn_msg[i-1], "%c", i);
}
changed = 1;
}
// Migrate to v4
if (termconf->config_version < 4) {
persist_dbg("termconf: Updating to version 4");
termconf->cursor_shape = CURSOR_BLOCK_BL;
termconf->crlf_mode = false;
changed = 1;
}
// Migrate to v5
if (termconf->config_version < 4) {
persist_dbg("termconf: Updating to version 5");
termconf->want_all_fn = 0;
changed = 1;
}
// // Migrate to v1
// if (termconf->config_version < 1) {
// persist_dbg("termconf: Updating to version %d", 1);
// termconf->display_cooldown_ms = SCR_DEF_DISPLAY_COOLDOWN_MS;
// changed = 1;
// }
termconf->config_version = TERMCONF_VERSION;
@ -288,9 +250,9 @@ screen_init(void)
NOTIFY_LOCK();
Cell sample;
sample.symbol = ' ';
sample.fg = termconf->default_fg;
sample.bg = termconf->default_bg;
sample.attrs = 0;
sample.fg = 0;
sample.bg = 0;
sample.attrs = 0; // use default colors
for (unsigned int i = 0; i < MAX_SCREEN_SIZE; i++) {
memcpy(&screen[i], &sample, sizeof(Cell));
}
@ -345,10 +307,9 @@ screen_reset_on_resize(void)
void ICACHE_FLASH_ATTR
screen_reset_sgr(void)
{
cursor.fg = termconf->default_fg;
cursor.bg = termconf->default_bg;
cursor.fg = 0;
cursor.bg = 0;
cursor.attrs = 0;
cursor.inverse = false;
cursor.conceal = false;
}
@ -588,14 +549,13 @@ static void ICACHE_FLASH_ATTR
clear_range(unsigned int from, unsigned int to)
{
if (to >= W*H) to = W*H-1;
Color fg = (cursor.inverse) ? cursor.bg : cursor.fg;
Color bg = (cursor.inverse) ? cursor.fg : cursor.bg;
Cell sample;
sample.symbol = ' ';
sample.fg = fg;
sample.bg = bg;
sample.attrs = 0;
sample.fg = cursor.fg;
sample.bg = cursor.bg;
// we discard all attributes except color-set flags
sample.attrs = (CellAttrs) (cursor.attrs & (ATTR_FG | ATTR_BG));
for (unsigned int i = from; i <= to; i++) {
UnicodeCacheRef symbol = screen[i].symbol;
@ -771,8 +731,8 @@ screen_fill_with_E(void)
Cell sample;
sample.symbol = 'E';
sample.fg = termconf->default_fg;
sample.bg = termconf->default_bg;
sample.fg = 0;
sample.bg = 0;
sample.attrs = 0;
for (unsigned int i = 0; i <= W*H-1; i++) {
@ -1174,6 +1134,7 @@ void ICACHE_FLASH_ATTR
screen_set_fg(Color color)
{
cursor.fg = color;
cursor.attrs |= ATTR_FG;
}
/**
@ -1183,10 +1144,31 @@ void ICACHE_FLASH_ATTR
screen_set_bg(Color color)
{
cursor.bg = color;
cursor.attrs |= ATTR_BG;
}
/**
* Set cursor foreground color to default
*/
void ICACHE_FLASH_ATTR
screen_set_sgr(u8 attrs, bool ena)
screen_set_default_fg(void)
{
cursor.fg = 0;
cursor.attrs &= ~ATTR_FG;
}
/**
* Set cursor background color to default
*/
void ICACHE_FLASH_ATTR
screen_set_default_bg(void)
{
cursor.bg = 0;
cursor.attrs &= ~ATTR_BG;
}
void ICACHE_FLASH_ATTR
screen_set_sgr(CellAttrs attrs, bool ena)
{
if (ena) {
cursor.attrs |= attrs;
@ -1196,12 +1178,6 @@ screen_set_sgr(u8 attrs, bool ena)
}
}
void ICACHE_FLASH_ATTR
screen_set_sgr_inverse(bool ena)
{
cursor.inverse = ena;
}
void ICACHE_FLASH_ATTR
screen_set_sgr_conceal(bool ena)
{
@ -1359,9 +1335,11 @@ screen_report_sgr(char *buffer)
if (cursor.attrs & ATTR_BLINK) buffer += sprintf(buffer, ";%d", SGR_BLINK);
if (cursor.attrs & ATTR_FRAKTUR) buffer += sprintf(buffer, ";%d", SGR_FRAKTUR);
if (cursor.attrs & ATTR_STRIKE) buffer += sprintf(buffer, ";%d", SGR_STRIKE);
if (cursor.inverse) buffer += sprintf(buffer, ";%d", SGR_INVERSE);
if (cursor.fg != termconf->default_fg) buffer += sprintf(buffer, ";%d", ((cursor.fg > 7) ? SGR_FG_BRT_START : SGR_FG_START) + (cursor.fg&7));
if (cursor.bg != termconf->default_bg) buffer += sprintf(buffer, ";%d", ((cursor.bg > 7) ? SGR_BG_BRT_START : SGR_BG_START) + (cursor.bg&7));
if (cursor.attrs & ATTR_INVERSE) buffer += sprintf(buffer, ";%d", SGR_INVERSE);
if (cursor.attrs & ATTR_FG)
buffer += sprintf(buffer, ";%d", ((cursor.fg > 7) ? SGR_FG_BRT_START : SGR_FG_START) + (cursor.fg&7));
if (cursor.attrs & ATTR_BG)
buffer += sprintf(buffer, ";%d", ((cursor.bg > 7) ? SGR_BG_BRT_START : SGR_BG_START) + (cursor.bg&7));
(void)buffer;
}
@ -1403,14 +1381,8 @@ putchar_graphic(const char *ch)
}
unicode_cache_remove(c->symbol);
c->symbol = unicode_cache_add((const u8 *)ch);
if (cursor.inverse) {
c->fg = cursor.bg;
c->bg = cursor.fg;
} else {
c->fg = cursor.fg;
c->bg = cursor.bg;
}
c->fg = cursor.fg;
c->bg = cursor.bg;
c->attrs = cursor.attrs;
cursor.x++;
@ -1543,7 +1515,7 @@ utf8_remap(char *out, char g, char charset)
struct ScreenSerializeState {
Color lastFg;
Color lastBg;
bool lastAttrs;
CellAttrs lastAttrs;
UnicodeCacheRef lastSymbol;
char lastChar[4];
u8 lastCharLen;
@ -1656,7 +1628,8 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data)
(termconf_live.show_config_links << 8) |
((termconf_live.cursor_shape&0x07) << 9) | // 9,10,11 - cursor shape based on DECSCUSR
(termconf_live.crlf_mode << 12) |
(scr.bracketed_paste << 13)
(scr.bracketed_paste << 13) |
(scr.reverse_video << 14)
);
}
@ -1691,14 +1664,8 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data)
Color fg, bg;
// Reverse fg and bg if we're in global reverse mode
if (! scr.reverse_video) {
fg = cell0->fg;
bg = cell0->bg;
}
else {
fg = cell0->bg;
bg = cell0->fg;
}
fg = cell0->fg;
bg = cell0->bg;
if (changeColors) {
bufput_t3B(SEQ_TAG_COLORS, bg<<8 | fg);
@ -1711,7 +1678,7 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data)
}
if (changeAttrs) {
bufput_t2B(SEQ_TAG_ATTRS, cell0->attrs);
bufput_t3B(SEQ_TAG_ATTRS, cell0->attrs);
}
// copy the symbol, until first 0 or reached 4 bytes

@ -37,7 +37,7 @@
// Size designed for the terminal config structure
// Must be constant to avoid corrupting user config after upgrade
#define TERMCONF_SIZE 300
#define TERMCONF_VERSION 5
#define TERMCONF_VERSION 0
#define TERM_BTN_LEN 10
#define TERM_BTN_MSG_LEN 10
@ -77,8 +77,8 @@ enum CursorShape {
typedef struct {
u32 width;
u32 height;
u8 default_bg; // should be the Color typedef, but this way the size is more explicit
u8 default_fg;
u32 default_bg; // 00-FFh - ANSI colors, (00:00:00-FF:FF:FF)+256 - True Color, 1<<24 + 256 - default from theme
u32 default_fg;
char title[TERM_TITLE_LEN];
char btn[TERM_BTN_COUNT][TERM_BTN_LEN];
u8 theme;
@ -228,25 +228,32 @@ void screen_set_origin_mode(bool region_origin);
// --- Graphic rendition setting ---
typedef uint8_t Color; // 0-16
#define ATTR_BOLD (1<<0)
#define ATTR_FAINT (1<<1)
#define ATTR_ITALIC (1<<2)
#define ATTR_UNDERLINE (1<<3)
#define ATTR_BLINK (1<<4)
#define ATTR_FRAKTUR (1<<5)
#define ATTR_STRIKE (1<<6)
#define ATTR_OVERLINE (1<<7)
typedef uint8_t Color;
typedef uint16_t CellAttrs;
// TODO sort by the expected frequency of being set - so when we switch to utf-8 encoding for data fields, it uses fewer bytes
#define ATTR_BOLD (1<<0) //!< Bold font
#define ATTR_FAINT (1<<1) //!< Faint foreground color (reduced alpha)
#define ATTR_ITALIC (1<<2) //!< Italic font
#define ATTR_UNDERLINE (1<<3) //!< Underline decoration
#define ATTR_BLINK (1<<4) //!< Blinking
#define ATTR_FRAKTUR (1<<5) //!< Fraktur font (unicode substitution)
#define ATTR_STRIKE (1<<6) //!< Strike-through decoration
#define ATTR_OVERLINE (1<<7) //!< Over-line decoration
#define ATTR_FG (1<<8) //!< 1 if not using default background color (ignore cell bg) - color extension bit
#define ATTR_BG (1<<9) //!< 1 if not using default foreground color (ignore cell fg) - color extension bit
#define ATTR_INVERSE (1<<10) //!< Invert colors - this is useful so we can clear then with SGR manipulation commands
/** Set cursor foreground color */
void screen_set_fg(Color color);
/** Set cursor background coloor */
void screen_set_bg(Color color);
/** Set cursor foreground color to default */
void screen_set_default_fg(void);
/** Set cursor background color to default */
void screen_set_default_bg(void);
/** Enable/disable attrs by bitmask */
void screen_set_sgr(u8 attrs, bool ena);
/** Set the inverse attribute */
void screen_set_sgr_inverse(bool ena);
void screen_set_sgr(CellAttrs attrs, bool ena);
/** Conceal style */
void screen_set_sgr_conceal(bool ena);
/** Reset cursor attribs */

@ -13,19 +13,10 @@ void ICACHE_FLASH_ATTR
sysconf_apply_settings(void)
{
bool changed = false;
if (sysconf->config_version < 1) {
dbg("Upgrading syscfg to v 1");
sysconf->access_pw[0] = 0;
sysconf->pwlock = PWLOCK_NONE;
changed = true;
}
if (sysconf->config_version < 2) {
dbg("Upgrading syscfg to v 2");
strcpy(sysconf->access_pw, DEF_ACCESS_PW);
strcpy(sysconf->access_name, DEF_ACCESS_NAME);
changed = true;
}
// if (sysconf->config_version < 1) {
// dbg("Upgrading syscfg to v 1");
// changed = true;
// }
sysconf->config_version = SYSCONF_VERSION;
@ -45,4 +36,6 @@ sysconf_restore_defaults(void)
sysconf->config_version = SYSCONF_VERSION;
sysconf->access_pw[0] = 0;
sysconf->pwlock = PWLOCK_NONE;
strcpy(sysconf->access_pw, DEF_ACCESS_PW);
strcpy(sysconf->access_name, DEF_ACCESS_NAME);
}

@ -10,7 +10,7 @@
// Size designed for the wifi config structure
// Must be constant to avoid corrupting user config after upgrade
#define SYSCONF_SIZE 300
#define SYSCONF_VERSION 2
#define SYSCONF_VERSION 0
#define DEF_ACCESS_PW "1234"
#define DEF_ACCESS_NAME "espterm"

Loading…
Cancel
Save