insert mode

pull/111/merge
Ondřej Hruška 7 years ago
parent ca410736f7
commit 89fca5c40a
  1. 61
      user/ansi_parser_callbacks.c
  2. 136
      user/screen.c
  3. 10
      user/screen.h

@ -65,10 +65,12 @@ apars_handle_plainchar(char c)
} }
else { else {
if (c == 14) { if (c == 14) {
// ShiftIN
screen_set_charset_n(1); screen_set_charset_n(1);
return; return;
} }
if (c == 15) { if (c == 15) {
// ShiftOUT
screen_set_charset_n(0); screen_set_charset_n(0);
return; return;
} }
@ -97,6 +99,7 @@ apars_handle_characterSet(char leadchar, char c)
{ {
if (leadchar == '(') screen_set_charset(0, c); if (leadchar == '(') screen_set_charset(0, c);
else if (leadchar == ')') screen_set_charset(1, c); else if (leadchar == ')') screen_set_charset(1, c);
// other alternatives * + . - / not implemented
} }
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
@ -119,6 +122,7 @@ apars_handle_CSI(char leadchar, int *params, int count, char keychar)
int n2 = params[1]; int n2 = params[1];
int n3 = params[2]; int n3 = params[2];
static char buf[20]; static char buf[20];
bool yn = 0; // for ? l h
// defaults // defaults
switch (keychar) { switch (keychar) {
@ -224,7 +228,6 @@ apars_handle_CSI(char leadchar, int *params, int count, char keychar)
case 'n': // queries case 'n': // queries
if (n1 == 6) { if (n1 == 6) {
// Query cursor position // Query cursor position
char buf[20];
int x, y; int x, y;
screen_cursor_get(&y, &x); screen_cursor_get(&y, &x);
sprintf(buf, "\033[%d;%dR", y+1, x+1); sprintf(buf, "\033[%d;%dR", y+1, x+1);
@ -242,43 +245,31 @@ apars_handle_CSI(char leadchar, int *params, int count, char keychar)
// DECTCEM feature enable / disable // DECTCEM feature enable / disable
case 'h': // feature enable case 'h': // feature enable
yn = 1;
case 'l': // feature disable
for (int i = 0; i < count; i++) {
int n = params[i];
if (leadchar == '?') { if (leadchar == '?') {
if (n1 == 25) screen_cursor_enable(1); if (n == 25) {
else if (n1 == 7) screen_wrap_enable(1); screen_cursor_enable(yn);
else if (n1 == 1) {
// TODO something with arrow keys??
}
else {
ansi_warn("NOIMPL DEC opt %d", n1);
} }
else if (n == 7) {
screen_wrap_enable(yn);
} }
else { else if (n == 1) {
if (n1 == 4) { screen_set_cursor_application_mode(yn);
// TODO insert mode, i think this is to suppress user input
} }
else { else {
ansi_warn("NOIMPL flag %d", n1); ansi_warn("NOIMPL DEC opt %d", n);
} }
} }
break;
case 'l': // feature disable
if (leadchar == '?') {
if (n1 == 25) screen_cursor_enable(0);
else if (n1 == 7) screen_wrap_enable(0);
else if (n1 == 1) {
// TODO see above
}
else { else {
ansi_warn("NOIMPL DEC opt %d", n1); if (n == 4) {
} screen_set_insert_mode(yn);
} }
else { else {
if (n1 == 4) { ansi_warn("NOIMPL flag %d", n);
// TODO see above
} }
else {
ansi_warn("NOIMPL flag %d", n1);
} }
} }
break; break;
@ -379,19 +370,14 @@ apars_handle_CSI(char leadchar, int *params, int count, char keychar)
ansi_warn("NOIMPL cursor back tab"); ansi_warn("NOIMPL cursor back tab");
break; break;
case 'q':
// TODO setmode (??)
ansi_warn("NOIMPL CSI setmode %d", n1);
break;
case 'p': case 'p':
if (leadchar == '!') { if (leadchar == '!') {
info("SOFT RESET!"); info("SOFT RESET!");
system_restart(); screen_reset(); // TODO do soft reset
} }
break; break;
case 'c': case 'c': // CSI-c
// report capabilities (pretend we're vt4xx) // report capabilities (pretend we're vt4xx)
UART_WriteString(UART0, "\033[?64;22;c", UART_TIMEOUT_US); UART_WriteString(UART0, "\033[?64;22;c", UART_TIMEOUT_US);
break; break;
@ -449,17 +435,16 @@ void ICACHE_FLASH_ATTR apars_handle_shortCode(char c)
// ansi_warn("NOIMPL set tab"); // ansi_warn("NOIMPL set tab");
break; break;
// TODO those don't seem to do anything
case '>': case '>':
// ansi_warn("NOIMPL NUMKP"); screen_set_keypad_application_mode(false);
break; break;
case '<': case '<':
// ansi_warn("NOIMPL SETANSI"); // "Enter ANSI / VT100 mode" - no-op
break; break;
case '=': case '=':
// ansi_warn("NOIMPL ALTKP"); screen_set_keypad_application_mode(true);
break; break;
default: default:

@ -14,44 +14,6 @@ static void utf8_remap(char* out, char g, char table);
#define W termconf_scratch.width #define W termconf_scratch.width
#define H termconf_scratch.height #define H termconf_scratch.height
/**
* Restore hard defaults
*/
void terminal_restore_defaults(void)
{
termconf->default_bg = 0;
termconf->default_fg = 7;
termconf->width = 26;
termconf->height = 10;
termconf->parser_tout_ms = 10;
sprintf(termconf->title, "ESPTerm");
for(int i=1; i <= 5; i++) {
sprintf(termconf->btn[i-1], "%d", i);
}
}
/**
* Apply settings after eg. restore from defaults
*/
void terminal_apply_settings(void)
{
terminal_apply_settings_noclear();
screen_init();
}
void terminal_apply_settings_noclear(void)
{
memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle));
if (W*H >= MAX_SCREEN_SIZE) {
error("BAD SCREEN SIZE: %d rows x %d cols", H, W);
error("reverting terminal settings to default");
terminal_restore_defaults();
persist_store();
memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle));
screen_init();
}
}
/** /**
* Highest permissible value of the color attribute * Highest permissible value of the color attribute
*/ */
@ -79,6 +41,12 @@ static struct {
int x; //!< X coordinate int x; //!< X coordinate
int y; //!< Y coordinate int y; //!< Y coordinate
bool autowrap; //!< Wrapping when EOL bool autowrap; //!< Wrapping when EOL
bool insert_mode; //!< Insert mode (move rest of the line to the right)
// TODO use those for input processing
bool kp_alternate; //!< Application Mode - affects how user input of control keys is sent
bool curs_alternate; //!< Application mode for cursor keys
bool visible; //!< Visible (not attribute, DEC special) bool visible; //!< Visible (not attribute, DEC special)
bool inverse; bool inverse;
u8 attrs; u8 attrs;
@ -121,6 +89,45 @@ static volatile int notifyLock = 0;
if (notifyLock == 0) screen_notifyChange(CHANGE_CONTENT); \ if (notifyLock == 0) screen_notifyChange(CHANGE_CONTENT); \
} while(0) } while(0)
/**
* Restore hard defaults
*/
void terminal_restore_defaults(void)
{
termconf->default_bg = 0;
termconf->default_fg = 7;
termconf->width = 26;
termconf->height = 10;
termconf->parser_tout_ms = 10;
sprintf(termconf->title, "ESPTerm");
for(int i=1; i <= 5; i++) {
sprintf(termconf->btn[i-1], "%d", i);
}
}
/**
* Apply settings after eg. restore from defaults
*/
void terminal_apply_settings(void)
{
terminal_apply_settings_noclear();
screen_init();
}
/** this is used when changing terminal settings that do not affect the screen size */
void terminal_apply_settings_noclear(void)
{
memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle));
if (W*H >= MAX_SCREEN_SIZE) {
error("BAD SCREEN SIZE: %d rows x %d cols", H, W);
error("reverting terminal settings to default");
terminal_restore_defaults();
persist_store();
memcpy(&termconf_scratch, termconf, sizeof(TerminalConfigBundle));
screen_init();
}
}
/** /**
* Clear range, inclusive * Clear range, inclusive
*/ */
@ -151,6 +158,8 @@ clear_range(unsigned int from, unsigned int to)
static void ICACHE_FLASH_ATTR static void ICACHE_FLASH_ATTR
cursor_reset(void) cursor_reset(void)
{ {
// TODO this should probably be public and invoked by "soft reset"
cursor.x = 0; cursor.x = 0;
cursor.y = 0; cursor.y = 0;
cursor.fg = termconf_scratch.default_fg; cursor.fg = termconf_scratch.default_fg;
@ -158,6 +167,10 @@ cursor_reset(void)
cursor.visible = 1; cursor.visible = 1;
cursor.autowrap = 1; cursor.autowrap = 1;
cursor.attrs = 0; cursor.attrs = 0;
cursor.insert_mode = 0;
cursor.kp_alternate = 0;
cursor.curs_alternate = 0;
cursor.charset0 = 'B'; cursor.charset0 = 'B';
cursor.charset1 = '0'; cursor.charset1 = '0';
@ -657,13 +670,27 @@ void ICACHE_FLASH_ATTR screen_set_charset(int Gx, char charset)
if (Gx == 1) cursor.charset1 = charset; if (Gx == 1) cursor.charset1 = charset;
} }
void ICACHE_FLASH_ATTR screen_set_insert_mode(bool insert)
{
cursor.insert_mode = insert;
}
void ICACHE_FLASH_ATTR screen_set_keypad_application_mode(bool app_mode)
{
cursor.kp_alternate = app_mode;
}
void ICACHE_FLASH_ATTR screen_set_cursor_application_mode(bool app_mode)
{
cursor.curs_alternate = app_mode;
}
/** /**
* Set a character in the cursor color, move to right with wrap. * Set a character in the cursor color, move to right with wrap.
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_putchar(const char *ch) screen_putchar(const char *ch)
{ {
char buf[4];
NOTIFY_LOCK(); NOTIFY_LOCK();
Cell *c = &screen[cursor.x + cursor.y * W]; Cell *c = &screen[cursor.x + cursor.y * W];
@ -681,18 +708,13 @@ screen_putchar(const char *ch)
case 8: // BS case 8: // BS
if (cursor.x > 0) { if (cursor.x > 0) {
cursor.x--; cursor.x--;
} else {
// wrap around start of line
if (cursor.autowrap && cursor.y>0) {
cursor.x=W-1;
cursor.y--;
} }
} // we should not wrap around
// apparently backspace should not clear the cell // and apparently backspace should not even clear the cell
goto done; goto done;
case 9: // TAB case 9: // TAB
// TODO change if tab setting is ever implemented // TODO change to "go to next tab stop"
if (cursor.x<((W-1)-(W-1)%4)) { if (cursor.x<((W-1)-(W-1)%4)) {
c->c[0] = ' '; c->c[0] = ' ';
c->c[1] = 0; c->c[1] = 0;
@ -712,6 +734,9 @@ screen_putchar(const char *ch)
} }
} }
// move the rest of the line if we're in Insert Mode
if (cursor.x < W-1 && cursor.insert_mode) screen_insert_characters(1);
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) ? cursor.charset0 : cursor.charset1); utf8_remap(c->c, ch[0], (cursor.charsetN == 0) ? cursor.charset0 : cursor.charset1);
@ -801,29 +826,36 @@ utf8_remap(char *out, char g, char table)
utf = vt100_to_unicode[g - 0x41]; utf = vt100_to_unicode[g - 0x41];
} }
break; break;
case 'A': /* UK, replaces # with GBP */ case 'A': /* UK, replaces # with GBP */
if (g == '#') utf = 0x20a4; if (g == '#') utf = 0x20a4;
break; break;
default:
// no remap
utf = (unsigned char)g;
break;
} }
// Encode to UTF-8
if (utf > 0x7F) { if (utf > 0x7F) {
// formulas taken from: https://gist.github.com/yamamushi/5823402 // formulas taken from: https://gist.github.com/yamamushi/5823402
if ((utf >= 0x80) && (utf <= 0x07FF)) { if ((utf >= 0x80) && (utf <= 0x07FF)) {
// 2-byte unicode
out[0] = (char) ((utf >> 0x06) ^ 0xC0); out[0] = (char) ((utf >> 0x06) ^ 0xC0);
out[1] = (char) (((utf ^ 0xFFC0) | 0x80) & ~0x40); out[1] = (char) (((utf ^ 0xFFC0) | 0x80) & ~0x40);
out[2]=0; out[2]=0;
} }
else if ((utf >= 0x0800) && (utf <= 0xFFFF)) { else {
// 3-byte unicode
out[0] = (char) (((utf ^ 0xFC0FFF) >> 0x0C) | 0xE0); out[0] = (char) (((utf ^ 0xFC0FFF) >> 0x0C) | 0xE0);
out[1] = (char) ((((utf ^ 0xFFF03F) >> 0x06) | 0x80) & ~0x40); out[1] = (char) ((((utf ^ 0xFFF03F) >> 0x06) | 0x80) & ~0x40);
out[2] = (char) (((utf ^ 0xFFFC0) | 0x80) & ~0x40); out[2] = (char) (((utf ^ 0xFFFC0) | 0x80) & ~0x40);
out[3]=0; out[3]=0;
} else {
out[0] = g;
out[1] = 0;
} }
} else { } else {
out[0] = g; // low ASCII
out[0] = (char) utf;
out[1] = 0; out[1] = 0;
} }
} }

@ -172,10 +172,18 @@ void screen_set_fg(Color color);
/** Set cursor background coloor */ /** Set cursor background coloor */
void screen_set_bg(Color color); void screen_set_bg(Color color);
// enable or disable attrs by bitmask /** enable attrs by bitmask */
void screen_attr_enable(u8 attrs); void screen_attr_enable(u8 attrs);
/** disable attrs by bitmask */
void screen_attr_disable(u8 attrs); void screen_attr_disable(u8 attrs);
/** Set the inverse cursor attribute */
void screen_inverse_enable(bool ena); void screen_inverse_enable(bool ena);
/** Toggle INSERT / REPLACE */
void screen_set_insert_mode(bool insert);
/** Toggle application keypad mode */
void screen_set_keypad_application_mode(bool app_mode);
/** Toggle application cursor mode */
void screen_set_cursor_application_mode(bool app_mode);
void screen_set_charset_n(int Gx); void screen_set_charset_n(int Gx);
void screen_set_charset(int Gx, char charset); void screen_set_charset(int Gx, char charset);

Loading…
Cancel
Save