insert mode
This commit is contained in:
@@ -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
|
||||||
if (leadchar == '?') {
|
yn = 1;
|
||||||
if (n1 == 25) screen_cursor_enable(1);
|
|
||||||
else if (n1 == 7) screen_wrap_enable(1);
|
|
||||||
else if (n1 == 1) {
|
|
||||||
// TODO something with arrow keys??
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ansi_warn("NOIMPL DEC opt %d", n1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (n1 == 4) {
|
|
||||||
// TODO insert mode, i think this is to suppress user input
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ansi_warn("NOIMPL flag %d", n1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'l': // feature disable
|
case 'l': // feature disable
|
||||||
if (leadchar == '?') {
|
for (int i = 0; i < count; i++) {
|
||||||
if (n1 == 25) screen_cursor_enable(0);
|
int n = params[i];
|
||||||
else if (n1 == 7) screen_wrap_enable(0);
|
if (leadchar == '?') {
|
||||||
else if (n1 == 1) {
|
if (n == 25) {
|
||||||
// TODO see above
|
screen_cursor_enable(yn);
|
||||||
|
}
|
||||||
|
else if (n == 7) {
|
||||||
|
screen_wrap_enable(yn);
|
||||||
|
}
|
||||||
|
else if (n == 1) {
|
||||||
|
screen_set_cursor_application_mode(yn);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ansi_warn("NOIMPL DEC opt %d", n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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;
|
||||||
@@ -320,7 +311,7 @@ apars_handle_CSI(char leadchar, int *params, int count, char keychar)
|
|||||||
else if (n >= 90 && n <= 97) screen_set_fg((Color) (n - 90 + 8)); // AIX bright fg
|
else if (n >= 90 && n <= 97) screen_set_fg((Color) (n - 90 + 8)); // AIX bright fg
|
||||||
else if (n >= 100 && n <= 107) screen_set_bg((Color) (n - 100 + 8)); // AIX bright bg
|
else if (n >= 100 && n <= 107) screen_set_bg((Color) (n - 100 + 8)); // AIX bright bg
|
||||||
else {
|
else {
|
||||||
ansi_warn("NOIMPL SGR attr %d", n);
|
ansi_warn("NOIMPL SGR attr %d", n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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:
|
||||||
|
|||||||
+84
-52
@@ -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--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// apparently backspace should not clear the cell
|
// we should not wrap around
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user