diff --git a/.gitignore b/.gitignore index 7e32919..0df67ed 100644 --- a/.gitignore +++ b/.gitignore @@ -14,5 +14,6 @@ eagle.app.sym .idea/ CMakeLists.txt cmake-build-debug/ +.sass-cache *.map diff --git a/build_web.sh b/build_web.sh index b86d192..361c5fd 100755 --- a/build_web.sh +++ b/build_web.sh @@ -11,6 +11,8 @@ cat $DD/chibi.js \ $DD/term.js \ $DD/wifi.js > html/js/app.js +sass --sourcemap=none html_orig/sass/app.scss html_orig/css/app.css + # No need to compress CSS and JS now, we run YUI on it later cp html_orig/css/app.css html/css/app.css cp html_orig/term.html html/term.tpl diff --git a/html/css/app.css b/html/css/app.css index 11eba21..cfe6420 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -668,6 +668,10 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele .page-term h1 { font-size: 1.42383em; } } .page-term #screen { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; font-family: monospace; font-size: 16pt; white-space: nowrap; @@ -680,7 +684,7 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele cursor: pointer; } .page-term #screen span:hover { outline: 1px solid rgba(255, 255, 255, 0.4); } - @media screen and (max-width: 1000px) { + @media screen and (max-width: 544px) { .page-term #screen span:hover { outline: 0 none; } } .page-term #buttons { @@ -697,5 +701,3 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele #termwrap { text-align: center; } - -/*# sourceMappingURL=app.css.map */ diff --git a/html_orig/css/app.css b/html_orig/css/app.css index 11eba21..cfe6420 100644 --- a/html_orig/css/app.css +++ b/html_orig/css/app.css @@ -668,6 +668,10 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele .page-term h1 { font-size: 1.42383em; } } .page-term #screen { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; font-family: monospace; font-size: 16pt; white-space: nowrap; @@ -680,7 +684,7 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele cursor: pointer; } .page-term #screen span:hover { outline: 1px solid rgba(255, 255, 255, 0.4); } - @media screen and (max-width: 1000px) { + @media screen and (max-width: 544px) { .page-term #screen span:hover { outline: 0 none; } } .page-term #buttons { @@ -697,5 +701,3 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele #termwrap { text-align: center; } - -/*# sourceMappingURL=app.css.map */ diff --git a/html_orig/sass/pages/_term.scss b/html_orig/sass/pages/_term.scss index aef9183..ef8f3b4 100755 --- a/html_orig/sass/pages/_term.scss +++ b/html_orig/sass/pages/_term.scss @@ -7,6 +7,8 @@ } #screen { + @include noselect(); + font-family: monospace; font-size: 16pt; white-space: nowrap; @@ -21,7 +23,7 @@ cursor: pointer; &:hover { outline: 1px solid rgba(#ffffff,0.4); - @include media($tablet-max) { + @include media($phone) { outline: 0 none; } } diff --git a/libesphttpd b/libesphttpd index 439df03..fba7cec 160000 --- a/libesphttpd +++ b/libesphttpd @@ -1 +1 @@ -Subproject commit 439df03f4b8e4c1ec5d7dc14695c80a4e35eb7ce +Subproject commit fba7cec0b6443c5ee71afde9a45cf832c49562c9 diff --git a/user/ansi_parser_callbacks.c b/user/ansi_parser_callbacks.c index f344bfa..290dc95 100644 --- a/user/ansi_parser_callbacks.c +++ b/user/ansi_parser_callbacks.c @@ -53,7 +53,7 @@ apars_handle_CSI(char leadchar, int *params, char keychar) CSI n T SD – Scroll Down CSI n ; m f HVP – Horizontal and Vertical Position CSI n m SGR – Select Graphic Rendition (Implemented only some) - CSI 6n DSR – Device Status Report NOT IMPL + CSI 6n DSR – Device Status Report CSI s SCP – Save Cursor Position CSI u RCP – Restore Cursor Position CSI ?25l DECTCEM Hides the cursor @@ -92,18 +92,18 @@ apars_handle_CSI(char leadchar, int *params, char keychar) switch (keychar) { // CUU CUD CUF CUB - case 'A': screen_cursor_move(0, -n1); break; - case 'B': screen_cursor_move(0, n1); break; - case 'C': screen_cursor_move(n1, 0); break; - case 'D': screen_cursor_move(-n1, 0); break; + case 'A': screen_cursor_move(-n1, 0); break; + case 'B': screen_cursor_move(n1, 0); break; + case 'C': screen_cursor_move(0, n1); break; + case 'D': screen_cursor_move(0, -n1); break; case 'E': // CNL - screen_cursor_move(0, n1); + screen_cursor_move(n1, 0); screen_cursor_set_x(0); break; case 'F': // CPL - screen_cursor_move(0, -n1); + screen_cursor_move(-n1, 0); screen_cursor_set_x(0); break; @@ -118,7 +118,7 @@ apars_handle_CSI(char leadchar, int *params, char keychar) // CUP,HVP case 'H': case 'f': - screen_cursor_set(n2-1, n1-1); break; // 1-based + screen_cursor_set(n1-1, n2-1); break; // 1-based case 'J': // ED if (n1 == 0) { @@ -146,6 +146,16 @@ apars_handle_CSI(char leadchar, int *params, char keychar) case 's': screen_cursor_save(); break; case 'u': screen_cursor_restore(); break; + case 'n': + if (n1 == 6) { + char buf[20]; + int x, y; + screen_cursor_get(&y, &x); + sprintf(buf, "\033[%d;%dR", y+1, x+1); + UART_WriteString(UART0, buf, UART_TIMEOUT_US); + } + break; + // DECTCEM cursor show hide case 'l': if (leadchar == '?' && n1 == 25) { diff --git a/user/cgi_sockets.c b/user/cgi_sockets.c index e27fb77..32a3ca5 100644 --- a/user/cgi_sockets.c +++ b/user/cgi_sockets.c @@ -32,12 +32,12 @@ void ICACHE_FLASH_ATTR screen_notifyChange() /** Socket received a message */ void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags) { + char buf[20]; // Add terminator if missing (seems to randomly happen) data[len] = 0; dbg("Sock RX str: %s, len %d", data, len); - if (strstarts(data, "STR:")) { // pass string verbatim UART_WriteString(UART0, data+4, UART_TIMEOUT_US); @@ -50,8 +50,37 @@ void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags) } } else if (strstarts(data, "TAP:")) { - // TODO - warn("TODO mouse input handling not implemented!"); + // this comes in as 0-based + + int y=0, x=0; + + char *pc=data+4; + char c; + int phase=0; + + while((c=*pc++) != '\0') { + if (c==','||c==';') { + phase++; + } + else if (c>='0' && c<='9') { + if (phase==0) { + y=y*10+(c-'0'); + } else { + x=x*10+(c-'0'); + } + } + } + + if (!screen_isCoordValid(y, x)) { + warn("Mouse input at invalid coordinates"); + return; + } + + dbg("Screen clicked at row %d, col %d", y+1, x+1); + + // Send as 1-based to user + sprintf(buf, "\033[%d;%dM", y+1, x+1); + UART_WriteString(UART0, buf, UART_TIMEOUT_US); } else { warn("Bad command."); diff --git a/user/screen.c b/user/screen.c index 4f03887..22503a4 100644 --- a/user/screen.c +++ b/user/screen.c @@ -27,8 +27,8 @@ static Cell screen[MAX_SCREEN_SIZE]; * Cursor position and attributes */ static struct { - Coordinate x; //!< X coordinate - Coordinate y; //!< Y coordinate + int x; //!< X coordinate + int y; //!< Y coordinate bool visible; //!< Visible bool inverse; //!< Inverse colors Color fg; //!< Foreground color for writing @@ -39,19 +39,19 @@ static struct { * Saved cursor position, used with the SCP RCP commands */ static struct { - Coordinate x; - Coordinate y; + int x; + int y; } cursor_sav; /** * Active screen width */ -static Coordinate W = SCREEN_DEF_W; +static int W = SCREEN_DEF_W; /** * Active screen height */ -static Coordinate H = SCREEN_DEF_H; +static int H = SCREEN_DEF_H; // XXX volatile is probably not needed static volatile int notifyLock = 0; @@ -193,7 +193,7 @@ screen_clear_line(ClearMode mode) * @param rows - new height */ void ICACHE_FLASH_ATTR -screen_resize(Coordinate rows, Coordinate cols) +screen_resize(int rows, int cols) { NOTIFY_LOCK(); // sanitize @@ -277,7 +277,7 @@ done: * Set cursor position */ void ICACHE_FLASH_ATTR -screen_cursor_set(Coordinate x, Coordinate y) +screen_cursor_set(int y, int x) { NOTIFY_LOCK(); if (x >= W) x = W - 1; @@ -287,11 +287,21 @@ screen_cursor_set(Coordinate x, Coordinate y) NOTIFY_DONE(); } +/** + * Set cursor position + */ +void ICACHE_FLASH_ATTR +screen_cursor_get(int *y, int *x) +{ + *x = cursor.x; + *y = cursor.y; +} + /** * Set cursor X position */ void ICACHE_FLASH_ATTR -screen_cursor_set_x(Coordinate x) +screen_cursor_set_x(int x) { NOTIFY_LOCK(); if (x >= W) x = W - 1; @@ -303,7 +313,7 @@ screen_cursor_set_x(Coordinate x) * Set cursor Y position */ void ICACHE_FLASH_ATTR -screen_cursor_set_y(Coordinate y) +screen_cursor_set_y(int y) { NOTIFY_LOCK(); if (y >= H) y = H - 1; @@ -315,7 +325,7 @@ screen_cursor_set_y(Coordinate y) * Relative cursor move */ void ICACHE_FLASH_ATTR -screen_cursor_move(int dx, int dy) +screen_cursor_move(int dy, int dx) { NOTIFY_LOCK(); int move; @@ -431,6 +441,18 @@ screen_set_bright_fg(void) //endregion +/** + * Check if coords are in range + * + * @param y + * @param x + * @return OK + */ +bool ICACHE_FLASH_ATTR screen_isCoordValid(int y, int x) +{ + return x >= 0 && y >= 0 && x < W && y < H; +} + /** * Set a character in the cursor color, move to right with wrap. */ @@ -448,23 +470,31 @@ screen_putchar(char ch) goto done; case '\n': - screen_cursor_move(0, 1); + screen_cursor_move(1, 0); goto done; case 8: // BS - if (cursor.x > 0) cursor.x--; + if (cursor.x > 0) { + cursor.x--; + } else { + // wrap around start of line + if (cursor.y>0) { + cursor.x=W-1; + cursor.y--; + } + } // erase target cell c = &screen[cursor.x + cursor.y * W]; c->c = ' '; goto done; case 9: // TAB - c->c = ' '; - // nested recurs >:( but it's ok - screen_putchar(' '); - screen_putchar(' '); - screen_putchar(' '); - screen_putchar(' '); + if (cursor.x<((W-1)-(W-1)%4)) { + c->c = ' '; + do { + screen_putchar(' '); + } while(cursor.x%4!=0); + } goto done; default: diff --git a/user/screen.h b/user/screen.h index d8a02ad..785eea0 100644 --- a/user/screen.h +++ b/user/screen.h @@ -24,7 +24,7 @@ * 8 black, 9 red, 10 green, 11 yellow * 12 blue, 13 mag, 14 cyan, 15 white * - * Coordinates are 0-based, left-top is the origin. + * ints are 0-based, left-top is the origin. * X grows to the right, Y to the bottom. * * +----> @@ -53,7 +53,6 @@ typedef enum { } ClearMode; typedef uint8_t Color; -typedef int Coordinate; httpd_cgi_state ICACHE_FLASH_ATTR screenSerializeToBuffer(char *buffer, size_t buf_len, void **data); @@ -62,7 +61,10 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data); void screen_init(void); /** Change the screen size */ -void screen_resize(Coordinate rows, Coordinate cols); +void screen_resize(int rows, int cols); + +/** Check if coord is valid */ +bool screen_isCoordValid(int y, int x); // --- Clearing --- @@ -84,16 +86,19 @@ void screen_scroll_down(unsigned int lines); // --- Cursor control --- /** Set cursor position */ -void screen_cursor_set(Coordinate x, Coordinate y); +void screen_cursor_set(int y, int x); + +/** Read cursor pos to given vars */ +void screen_cursor_get(int *y, int *x); /** Set cursor X position */ -void screen_cursor_set_x(Coordinate x); +void screen_cursor_set_x(int x); /** Set cursor Y position */ -void screen_cursor_set_y(Coordinate y); +void screen_cursor_set_y(int y); /** Relative cursor move */ -void screen_cursor_move(int dx, int dy); +void screen_cursor_move(int dy, int dx); /** Save the cursor pos */ void screen_cursor_save(void); diff --git a/user/user_main.c b/user/user_main.c index 0f33295..1be9dbd 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -23,7 +23,7 @@ #include "screen.h" #include "routes.h" -#define FIRMWARE_VERSION "0.2" +#define FIRMWARE_VERSION "0.3" #ifdef ESPFS_POS CgiUploadFlashDef uploadParams={ @@ -50,20 +50,29 @@ static ETSTimer prHeapTimer; /** Periodically show heap usage */ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) { - static uint32_t last = 0; + static int last = 0; + static int cnt = 0; + + int heap = system_get_free_heap_size(); + int diff = (heap-last); - uint32_t heap = system_get_free_heap_size(); - int32_t diff = (heap-last); const char *cc = "+"; if (diff<0) cc = ""; if (diff == 0) { - dbg("Free heap: %d bytes", heap); + if (cnt == 5) { + // only every 5 secs if no change + dbg("Free heap: %d bytes", heap); + cnt = 0; + } } else { + // report change dbg("Free heap: %d bytes (%s%d)", heap, cc, diff); + cnt = 0; } last = heap; + cnt++; } //Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done. @@ -100,7 +109,7 @@ void ICACHE_FLASH_ATTR user_init(void) // Heap use timer & blink os_timer_disarm(&prHeapTimer); os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL); - os_timer_arm(&prHeapTimer, 5000, 1); + os_timer_arm(&prHeapTimer, 1000, 1); // The terminal screen screen_init();