insert mode
This commit is contained in:
@@ -65,10 +65,12 @@ apars_handle_plainchar(char c)
|
||||
}
|
||||
else {
|
||||
if (c == 14) {
|
||||
// ShiftIN
|
||||
screen_set_charset_n(1);
|
||||
return;
|
||||
}
|
||||
if (c == 15) {
|
||||
// ShiftOUT
|
||||
screen_set_charset_n(0);
|
||||
return;
|
||||
}
|
||||
@@ -97,6 +99,7 @@ apars_handle_characterSet(char leadchar, char c)
|
||||
{
|
||||
if (leadchar == '(') screen_set_charset(0, c);
|
||||
else if (leadchar == ')') screen_set_charset(1, c);
|
||||
// other alternatives * + . - / not implemented
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
@@ -119,6 +122,7 @@ apars_handle_CSI(char leadchar, int *params, int count, char keychar)
|
||||
int n2 = params[1];
|
||||
int n3 = params[2];
|
||||
static char buf[20];
|
||||
bool yn = 0; // for ? l h
|
||||
|
||||
// defaults
|
||||
switch (keychar) {
|
||||
@@ -224,7 +228,6 @@ apars_handle_CSI(char leadchar, int *params, int count, char keychar)
|
||||
case 'n': // queries
|
||||
if (n1 == 6) {
|
||||
// Query cursor position
|
||||
char buf[20];
|
||||
int x, y;
|
||||
screen_cursor_get(&y, &x);
|
||||
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
|
||||
|
||||
case 'h': // feature enable
|
||||
if (leadchar == '?') {
|
||||
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;
|
||||
|
||||
yn = 1;
|
||||
case 'l': // feature disable
|
||||
for (int i = 0; i < count; i++) {
|
||||
int n = params[i];
|
||||
if (leadchar == '?') {
|
||||
if (n1 == 25) screen_cursor_enable(0);
|
||||
else if (n1 == 7) screen_wrap_enable(0);
|
||||
else if (n1 == 1) {
|
||||
// TODO see above
|
||||
if (n == 25) {
|
||||
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", n1);
|
||||
ansi_warn("NOIMPL DEC opt %d", n);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (n1 == 4) {
|
||||
// TODO see above
|
||||
if (n == 4) {
|
||||
screen_set_insert_mode(yn);
|
||||
}
|
||||
else {
|
||||
ansi_warn("NOIMPL flag %d", n1);
|
||||
ansi_warn("NOIMPL flag %d", n);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -379,19 +370,14 @@ apars_handle_CSI(char leadchar, int *params, int count, char keychar)
|
||||
ansi_warn("NOIMPL cursor back tab");
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
// TODO setmode (??)
|
||||
ansi_warn("NOIMPL CSI setmode %d", n1);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (leadchar == '!') {
|
||||
info("SOFT RESET!");
|
||||
system_restart();
|
||||
screen_reset(); // TODO do soft reset
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'c': // CSI-c
|
||||
// report capabilities (pretend we're vt4xx)
|
||||
UART_WriteString(UART0, "\033[?64;22;c", UART_TIMEOUT_US);
|
||||
break;
|
||||
@@ -449,17 +435,16 @@ void ICACHE_FLASH_ATTR apars_handle_shortCode(char c)
|
||||
// ansi_warn("NOIMPL set tab");
|
||||
break;
|
||||
|
||||
// TODO those don't seem to do anything
|
||||
case '>':
|
||||
// ansi_warn("NOIMPL NUMKP");
|
||||
screen_set_keypad_application_mode(false);
|
||||
break;
|
||||
|
||||
case '<':
|
||||
// ansi_warn("NOIMPL SETANSI");
|
||||
// "Enter ANSI / VT100 mode" - no-op
|
||||
break;
|
||||
|
||||
case '=':
|
||||
// ansi_warn("NOIMPL ALTKP");
|
||||
screen_set_keypad_application_mode(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+84
-52
@@ -14,44 +14,6 @@ static void utf8_remap(char* out, char g, char table);
|
||||
#define W termconf_scratch.width
|
||||
#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
|
||||
*/
|
||||
@@ -79,6 +41,12 @@ static struct {
|
||||
int x; //!< X coordinate
|
||||
int y; //!< Y coordinate
|
||||
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 inverse;
|
||||
u8 attrs;
|
||||
@@ -121,6 +89,45 @@ static volatile int notifyLock = 0;
|
||||
if (notifyLock == 0) screen_notifyChange(CHANGE_CONTENT); \
|
||||
} 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
|
||||
*/
|
||||
@@ -151,6 +158,8 @@ clear_range(unsigned int from, unsigned int to)
|
||||
static void ICACHE_FLASH_ATTR
|
||||
cursor_reset(void)
|
||||
{
|
||||
// TODO this should probably be public and invoked by "soft reset"
|
||||
|
||||
cursor.x = 0;
|
||||
cursor.y = 0;
|
||||
cursor.fg = termconf_scratch.default_fg;
|
||||
@@ -158,6 +167,10 @@ cursor_reset(void)
|
||||
cursor.visible = 1;
|
||||
cursor.autowrap = 1;
|
||||
cursor.attrs = 0;
|
||||
cursor.insert_mode = 0;
|
||||
|
||||
cursor.kp_alternate = 0;
|
||||
cursor.curs_alternate = 0;
|
||||
|
||||
cursor.charset0 = 'B';
|
||||
cursor.charset1 = '0';
|
||||
@@ -657,13 +670,27 @@ void ICACHE_FLASH_ATTR screen_set_charset(int Gx, char 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.
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
screen_putchar(const char *ch)
|
||||
{
|
||||
char buf[4];
|
||||
NOTIFY_LOCK();
|
||||
|
||||
Cell *c = &screen[cursor.x + cursor.y * W];
|
||||
@@ -681,18 +708,13 @@ screen_putchar(const char *ch)
|
||||
case 8: // BS
|
||||
if (cursor.x > 0) {
|
||||
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;
|
||||
|
||||
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)) {
|
||||
c->c[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) {
|
||||
// we have len=1 and ASCII
|
||||
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];
|
||||
}
|
||||
break;
|
||||
|
||||
case 'A': /* UK, replaces # with GBP */
|
||||
if (g == '#') utf = 0x20a4;
|
||||
break;
|
||||
|
||||
default:
|
||||
// no remap
|
||||
utf = (unsigned char)g;
|
||||
break;
|
||||
}
|
||||
|
||||
// Encode to UTF-8
|
||||
if (utf > 0x7F) {
|
||||
// formulas taken from: https://gist.github.com/yamamushi/5823402
|
||||
if ((utf >= 0x80) && (utf <= 0x07FF)) {
|
||||
// 2-byte unicode
|
||||
out[0] = (char) ((utf >> 0x06) ^ 0xC0);
|
||||
out[1] = (char) (((utf ^ 0xFFC0) | 0x80) & ~0x40);
|
||||
out[2]=0;
|
||||
}
|
||||
else if ((utf >= 0x0800) && (utf <= 0xFFFF)) {
|
||||
else {
|
||||
// 3-byte unicode
|
||||
out[0] = (char) (((utf ^ 0xFC0FFF) >> 0x0C) | 0xE0);
|
||||
out[1] = (char) ((((utf ^ 0xFFF03F) >> 0x06) | 0x80) & ~0x40);
|
||||
out[2] = (char) (((utf ^ 0xFFFC0) | 0x80) & ~0x40);
|
||||
out[3]=0;
|
||||
} else {
|
||||
out[0] = g;
|
||||
out[1] = 0;
|
||||
}
|
||||
} else {
|
||||
out[0] = g;
|
||||
// low ASCII
|
||||
out[0] = (char) utf;
|
||||
out[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-1
@@ -172,10 +172,18 @@ void screen_set_fg(Color color);
|
||||
/** Set cursor background coloor */
|
||||
void screen_set_bg(Color color);
|
||||
|
||||
// enable or disable attrs by bitmask
|
||||
/** enable attrs by bitmask */
|
||||
void screen_attr_enable(u8 attrs);
|
||||
/** disable attrs by bitmask */
|
||||
void screen_attr_disable(u8 attrs);
|
||||
/** Set the inverse cursor attribute */
|
||||
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(int Gx, char charset);
|
||||
|
||||
Reference in New Issue
Block a user