diff --git a/Makefile b/Makefile index 51f3721..029bef0 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,6 @@ define maplookup $(patsubst $(strip $(1)):%,%,$(filter $(strip $(1)):%,$(2))) endef - #Include options and target specific to the OUTPUT_TYPE include Makefile.$(OUTPUT_TYPE) @@ -203,13 +202,16 @@ espsize: espmac: $(Q) esptool --port /dev/ttyUSB0 read_mac -all: checkdirs parser $(TARGET_OUT) $(FW_BASE) +all: checkdirs + $(Q) make actual_all -j4 -B + +actual_all: parser $(TARGET_OUT) $(FW_BASE) libesphttpd/Makefile: $(Q) [[ -e "libesphttpd/Makefile" ]] || echo -e "\e[31mlibesphttpd submodule missing.\nIf build fails, run \"git submodule init\" and \"git submodule update\".\e[0m" libesphttpd: libesphttpd/Makefile - $(Q) make -C libesphttpd USE_OPENSDK=$(USE_OPENSDK) SERVERNAME_PREFIX="ESPTerm " + $(Q) make -C libesphttpd USE_OPENSDK=$(USE_OPENSDK) SERVERNAME_PREFIX="ESPTerm " -j4 $(APP_AR): libesphttpd $(OBJ) $(vecho) "AR $@" @@ -217,6 +219,9 @@ $(APP_AR): libesphttpd $(OBJ) checkdirs: $(BUILD_DIR) html/favicon.ico +html/favicon.ico: + $(Q) [[ -e "html/favicon.ico" ]] || ./build_web.sh + $(BUILD_DIR): $(Q) mkdir -p $@ diff --git a/front-end b/front-end index 79664f5..0a975e8 160000 --- a/front-end +++ b/front-end @@ -1 +1 @@ -Subproject commit 79664f56a63122da87ad91eaebcdf85083b7f0a5 +Subproject commit 0a975e88016f953d5ca4d99d53c6dce7d164c119 diff --git a/user/apars_csi.c b/user/apars_csi.c index fc12b02..4ed852d 100644 --- a/user/apars_csi.c +++ b/user/apars_csi.c @@ -244,8 +244,7 @@ switch_csi_Plain(CSI_Data *opts) break; case 'b': - // TODO repeat preceding graphic character n1 times - ansi_noimpl("Repeat char"); + screen_repeat_last_character(n1); return; // Set X diff --git a/user/screen.c b/user/screen.c index 53bc27e..2a86075 100644 --- a/user/screen.c +++ b/user/screen.c @@ -61,6 +61,7 @@ static struct { int vm1; u32 tab_stops[TABSTOP_WORDS]; // tab stops bitmap + char last_char[4]; } scr; #define R0 scr.vm0 @@ -995,7 +996,7 @@ screen_cursor_move(int dy, int dx, bool scroll) if (cursor.auto_wrap && cursor.reverse_wrap) { // this is mimicking a behavior from xterm that allows any number of steps backwards with reverse wraparound enabled int steps = -cursor.x; - if(steps > 1000) steps = 1; // avoid something stupid causing infinite loop here + if(steps > W*H) steps = W*H; // avoid something stupid causing infinite loop here for(;steps>0;steps--) { if (cursor.x > 0) { // backspace should go to col 79 if "hanging" after 80 (as if it never actually left the 80th col) @@ -1349,44 +1350,8 @@ screen_report_sgr(char *buffer) //region --- Printing --- -/** - * Set a character in the cursor color, move to right with wrap. - */ -void ICACHE_FLASH_ATTR -screen_putchar(const char *ch) +static const char *putchar_graphic(const char *ch) { - NOTIFY_LOCK(); - - // clear "hanging" flag if not possible - clear_invalid_hanging(); - - if (cursor.conceal) { - ch = " "; - } - - // Special treatment for CRLF - switch (ch[0]) { - case CR: - screen_cursor_set_x(0); - goto done; - - case LF: - screen_cursor_move(1, 0, true); // can scroll - goto done; - - case BS: - screen_cursor_move(0, -1, false); - // we should not wrap around, and backspace should not even clear the cell (verified in xterm) - goto done; - - default: - if (ch[0] < SP) { - // Discard - warn("Ignoring control char %d", (int)ch[0]); - goto done; - } - } - if (cursor.hanging) { // perform the scheduled wrap if hanging // if auto-wrap = off, it overwrites the last char @@ -1410,7 +1375,7 @@ screen_putchar(const char *ch) if (cursor.x < W-1 && scr.insert_mode) screen_insert_characters(1); if (ch[1] == 0 && ch[0] <= 0x7f) { - // we have len=1 and ASCII + // we have len=1 and ASCII, can be re-mapped using a table utf8_remap(c->c, ch[0], (cursor.charsetN == 0) ? cursor.charset0 : cursor.charset1); } else { @@ -1434,10 +1399,80 @@ screen_putchar(const char *ch) cursor.x = W - 1; } + return c->c; +} + +/** + * Set a character in the cursor color, move to right with wrap. + */ +void ICACHE_FLASH_ATTR +screen_putchar(const char *ch) +{ + NOTIFY_LOCK(); + + // clear "hanging" flag if not possible + clear_invalid_hanging(); + + if (cursor.conceal) { + ch = " "; + } + + // Special treatment for CRLF + switch (ch[0]) { + case CR: + screen_cursor_set_x(0); + goto done; + + case LF: + screen_cursor_move(1, 0, true); // can scroll + goto done; + + case BS: + screen_cursor_move(0, -1, false); + // we should not wrap around, and backspace should not even clear the cell (verified in xterm) + goto done; + + default: + if (ch[0] < SP) { + // Discard + warn("Ignoring control char %d", (int)ch[0]); + goto done; + } + } + + const char *result = putchar_graphic(ch); + + // Remember the resulting character + // If we re-mapped ASCII to high UTF, the following Repeat command will + // not have to call the remap function repeatedly. + strncpy(scr.last_char, result, 4); + done: NOTIFY_DONE(); } +/** + * Repeat last graphic character + * @param count + */ +void ICACHE_FLASH_ATTR +screen_repeat_last_character(int count) +{ + NOTIFY_LOCK(); + if (scr.last_char[0]==0) { + scr.last_char[0] = ' '; + scr.last_char[1] = 0; + } + + if (count > W*H) count = W*H; + + while (count > 0) { + putchar_graphic(scr.last_char); + count--; + } + NOTIFY_DONE(); +} + /** * UTF remap * @param out - output char[4] diff --git a/user/screen.h b/user/screen.h index 68c64ba..e5918ea 100644 --- a/user/screen.h +++ b/user/screen.h @@ -302,6 +302,12 @@ void screen_putchar(const char *ch); */ void screen_fill_with_E(void); +/** + * Repeat last graphic character + * @param count + */ +void screen_repeat_last_character(int count); + // --- Queries --- /** Report current SGR as num;num;... for DAC query */