Compare commits

...
5 Commits
12 changed files with 124 additions and 54 deletions
+1 -1
View File
@@ -748,7 +748,7 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
.ansiref.w100 { .ansiref.w100 {
width: 100%; } width: 100%; }
.ansiref.w100 td:nth-child(1) { .ansiref.w100 td:nth-child(1) {
width: 7em; } width: 9em; }
.ansiref.w100 td:nth-child(2) { .ansiref.w100 td:nth-child(2) {
width: 8em; } width: 8em; }
+29 -19
View File
@@ -29,7 +29,7 @@
<ul> <ul>
<li>Most ANSI escape sequences are supported.</li> <li>Most ANSI escape sequences are supported.</li>
<li>The max screen size is 2000 characters (eg. <b>25x80</b>), default is <b>10x26</b>. Set using <code>\e]W?;?\a</code> with rows;cols.</li> <li>The max screen size is 2000 characters (eg. <b>25x80</b>), default is <b>10x26</b>. Set using <code>\e]W&lt;rows&gt;;&lt;cols&gt;\a</code>.</li>
<li>The screen will automatically scroll, can be used for log output.</li> <li>The screen will automatically scroll, can be used for log output.</li>
<li>Display update is sent <b>after 20 ms of inactivity</b>.</li> <li>Display update is sent <b>after 20 ms of inactivity</b>.</li>
<li>The browser display needs WebSockets for the real-time updating. It may not work on really old phones / browsers.</li> <li>The browser display needs WebSockets for the real-time updating. It may not work on really old phones / browsers.</li>
@@ -39,7 +39,7 @@
<div class="Box"> <div class="Box">
<h2>Color Reference</h2> <h2>Color Reference</h2>
<p>Color is set using <code>\e[?m</code> or <code>\e[?;?m</code> where "?" are numbers from the following tables:</p> <p>Color is set using <code>\e[&lt;c&gt;m</code> or <code>\e[&lt;c&gt;;&lt;c&gt;m</code> where "&lt;c&gt;" are numbers from the following tables:</p>
<b>Foreground</b> <b>Foreground</b>
@@ -103,8 +103,8 @@
<p>The buttons under the screen send ASCII codes 1, 2, 3, 4, 5.</p> <p>The buttons under the screen send ASCII codes 1, 2, 3, 4, 5.</p>
<p> <p>
<b>Mouse input</b> (click/tap) is sent as <code>\e?;?M</code> with row;column. You can use this for on-screen buttons, menu navigation etc. <b>Mouse input</b> (click/tap) is sent as <code>\e[&lt;y&gt;;&lt;x&gt;M</code>. You can use this for on-screen buttons, menu navigation etc.
<i>Please note this is a custom sequence, not supported by PuTTY or other terminals.</i> <i>Please note this is a custom escape sequence, not supported by PuTTY or other terminals.</i>
</p> </p>
</div> </div>
@@ -167,42 +167,42 @@
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>\e[?A</td> <td>\e[&lt;n&gt;A</td>
<td>[count]</td> <td>[count]</td>
<td>Move cursor up</td> <td>Move cursor up</td>
</tr> </tr>
<tr> <tr>
<td>\e[?B</td> <td>\e[&lt;n&gt;B</td>
<td>[count]</td> <td>[count]</td>
<td>Move cursor down</td> <td>Move cursor down</td>
</tr> </tr>
<tr> <tr>
<td>\e[?C</td> <td>\e[&lt;n&gt;C</td>
<td>[count]</td> <td>[count]</td>
<td>Move cursor forward (right)</td> <td>Move cursor forward (right)</td>
</tr> </tr>
<tr> <tr>
<td>\e[?D</td> <td>\e[&lt;n&gt;D</td>
<td>[count]</td> <td>[count]</td>
<td>Move cursor backward (left)</td> <td>Move cursor backward (left)</td>
</tr> </tr>
<tr> <tr>
<td>\e[?E</td> <td>\e[&lt;n&gt;E</td>
<td>[count]</td> <td>[count]</td>
<td>Go N line down, start of line</td> <td>Go N line down, start of line</td>
</tr> </tr>
<tr> <tr>
<td>\e[?F</td> <td>\e[&lt;n&gt;F</td>
<td>[count]</td> <td>[count]</td>
<td>Go N lines up, start of line</td> <td>Go N lines up, start of line</td>
</tr> </tr>
<tr> <tr>
<td>\e[?G</td> <td>\e[&lt;n&gt;G</td>
<td>column</td> <td>column</td>
<td>Go to column</td> <td>Go to column</td>
</tr> </tr>
<tr> <tr>
<td>\e[?;?G</td> <td>\e[&lt;y&gt;;&lt;x&gt;G</td>
<td>[row=1];[col=1]</td> <td>[row=1];[col=1]</td>
<td>Go to row and column</td> <td>Go to row and column</td>
</tr> </tr>
@@ -234,12 +234,22 @@
<tr> <tr>
<td>\e[?25l</td> <td>\e[?25l</td>
<td>--</td> <td>--</td>
<td>Hide cursor (literal question mark, lowercase L!)</td> <td>Hide cursor</td>
</tr> </tr>
<tr> <tr>
<td>\e[?25h</td> <td>\e[?25h</td>
<td>--</td> <td>--</td>
<td>Show cursor (literal question mark!)</td> <td>Show cursor</td>
</tr>
<tr>
<td>\e[?7l</td>
<td>--</td>
<td>Disable cursor auto-wrap & auto-scroll at end of screen</td>
</tr>
<tr>
<td>\e[?7h</td>
<td>--</td>
<td>Enable cursor auto-wrap & auto-scroll at end of screen</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -256,27 +266,27 @@
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td>\e[?J</td> <td>\e[&lt;m&gt;J</td>
<td>[mode=0]</td> <td>[mode=0]</td>
<td>Clear screen. Mode: 0 - from cursor, 1 - to cursor, 2 - all</td> <td>Clear screen. Mode: 0 - from cursor, 1 - to cursor, 2 - all</td>
</tr> </tr>
<tr> <tr>
<td>\e[?K</td> <td>\e[&lt;m&gt;K</td>
<td>[mode=0]</td> <td>[mode=0]</td>
<td>Erase line. Mode: 0 - from cursor, 1 - to cursor, 2 - all</td> <td>Erase line. Mode: 0 - from cursor, 1 - to cursor, 2 - all</td>
</tr> </tr>
<tr> <tr>
<td>\e[?S</td> <td>\e[&lt;n&gt;S</td>
<td>[lines]</td> <td>[lines]</td>
<td>Scroll screen content up, add empty line at the bottom</td> <td>Scroll screen content up, add empty line at the bottom</td>
</tr> </tr>
<tr> <tr>
<td>\e[?T</td> <td>\e[&lt;n&gt;T</td>
<td>[lines]</td> <td>[lines]</td>
<td>Scroll screen content down, add empty line at the top</td> <td>Scroll screen content down, add empty line at the top</td>
</tr> </tr>
<tr> <tr>
<td>\e]W?;?\a</td> <td>\e]W&lt;r&gt;;&lt;c&gt;\a</td>
<td>rows;cols</td> <td>rows;cols</td>
<td>Set screen size, maximum 25x80 (resp. total 2000 characters). This also clears the screen.</td> <td>Set screen size, maximum 25x80 (resp. total 2000 characters). This also clears the screen.</td>
</tr> </tr>
+11 -9
View File
@@ -896,7 +896,8 @@ $._loader = function(vis) {
var screen = []; var screen = [];
var blinkIval; var blinkIval;
/** Clear screen */ /*
/!** Clear screen *!/
function cls() { function cls() {
screen.forEach(function(cell, i) { screen.forEach(function(cell, i) {
cell.t = ' '; cell.t = ' ';
@@ -905,6 +906,7 @@ $._loader = function(vis) {
blit(cell); blit(cell);
}); });
} }
*/
/** Set text and color at XY */ /** Set text and color at XY */
function cellAt(y, x) { function cellAt(y, x) {
@@ -916,14 +918,15 @@ $._loader = function(vis) {
return cellAt(cursor.y, cursor.x); return cellAt(cursor.y, cursor.x);
} }
/** Enable or disable cursor visibility */ /*
/!** Enable or disable cursor visibility *!/
function cursorEnable(enable) { function cursorEnable(enable) {
cursor.hidden = !enable; cursor.hidden = !enable;
cursor.a &= enable; cursor.a &= enable;
blit(cursorCell(), cursor.a); blit(cursorCell(), cursor.a);
} }
/** Safely move cursor */ /!** Safely move cursor *!/
function cursorSet(y, x) { function cursorSet(y, x) {
// Hide and prevent from showing up during the move // Hide and prevent from showing up during the move
cursor.suppress = true; cursor.suppress = true;
@@ -936,6 +939,7 @@ $._loader = function(vis) {
cursor.suppress = false; cursor.suppress = false;
blit(cursorCell(), cursor.a); blit(cursorCell(), cursor.a);
} }
*/
/** Update cell on display. inv = invert (for cursor) */ /** Update cell on display. inv = invert (for cursor) */
function blit(cell, inv) { function blit(cell, inv) {
@@ -1081,7 +1085,10 @@ $._loader = function(vis) {
} }
function onClose(evt) { function onClose(evt) {
console.error("SOCKET CLOSED"); console.warn("SOCKET CLOSED, code "+evt.code+". Reconnecting...");
setTimeout(function() {
init();
}, 2000);
} }
function onMessage(evt) { function onMessage(evt) {
@@ -1094,10 +1101,6 @@ $._loader = function(vis) {
} }
} }
function onError(evt) {
console.error(evt.data);
}
function doSend(message) { function doSend(message) {
console.log("TX: ", message); console.log("TX: ", message);
if (ws.readyState != 1) { if (ws.readyState != 1) {
@@ -1115,7 +1118,6 @@ $._loader = function(vis) {
ws.onopen = onOpen; ws.onopen = onOpen;
ws.onclose = onClose; ws.onclose = onClose;
ws.onmessage = onMessage; ws.onmessage = onMessage;
ws.onerror = onError;
console.log("Opening socket."); console.log("Opening socket.");
} }
+4 -6
View File
@@ -197,7 +197,10 @@
} }
function onClose(evt) { function onClose(evt) {
console.error("SOCKET CLOSED"); console.warn("SOCKET CLOSED, code "+evt.code+". Reconnecting...");
setTimeout(function() {
init();
}, 1000);
} }
function onMessage(evt) { function onMessage(evt) {
@@ -210,10 +213,6 @@
} }
} }
function onError(evt) {
console.error(evt.data);
}
function doSend(message) { function doSend(message) {
console.log("TX: ", message); console.log("TX: ", message);
if (ws.readyState != 1) { if (ws.readyState != 1) {
@@ -231,7 +230,6 @@
ws.onopen = onOpen; ws.onopen = onOpen;
ws.onclose = onClose; ws.onclose = onClose;
ws.onmessage = onMessage; ws.onmessage = onMessage;
ws.onerror = onError;
console.log("Opening socket."); console.log("Opening socket.");
} }
+2
View File
@@ -1,5 +1,7 @@
#!/bin/bash #!/bin/bash
echo "Packing js..."
cat jssrc/chibi.js \ cat jssrc/chibi.js \
jssrc/utils.js \ jssrc/utils.js \
jssrc/modal.js \ jssrc/modal.js \
+1 -1
View File
@@ -53,7 +53,7 @@
width: 100%; width: 100%;
td:nth-child(1) { td:nth-child(1) {
width: 7em; width: 9em;
} }
td:nth-child(2) { td:nth-child(2) {
+16 -2
View File
@@ -5,6 +5,15 @@
<title>ESP8266 Remote Terminal</title> <title>ESP8266 Remote Terminal</title>
<meta name="viewport" content="width=device-width,shrink-to-fit=no,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"> <meta name="viewport" content="width=device-width,shrink-to-fit=no,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
<script>
// Workaround for badly loaded page
setTimeout(function() {
if (typeof termInit == 'undefined' || typeof $ == 'undefined') {
location.reload(true);
}
}, 2000);
</script>
<link rel="stylesheet" href="/css/app.css"> <link rel="stylesheet" href="/css/app.css">
<script src="/js/app.js"></script> <script src="/js/app.js"></script>
</head> </head>
@@ -31,8 +40,13 @@
</nav> </nav>
<script> <script>
_root = window.location.host; try {
termInit(%screenData%); _root = window.location.host;
termInit(%screenData%);
} catch(e) {
console.error("Fail, reloading...");
location.reload(true);
}
</script> </script>
</body> </body>
+16 -7
View File
@@ -160,16 +160,25 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
} }
break; break;
// DECTCEM cursor show hide // DECTCEM feature enable / disable
case 'l':
if (leadchar == '?' && n1 == 25) { case 'h':
screen_cursor_enable(0); if (leadchar == '?') {
if (n1 == 25) {
screen_cursor_enable(1);
} else if (n1 == 7) {
screen_wrap_enable(1);
}
} }
break; break;
case 'h': case 'l':
if (leadchar == '?' && n1 == 25) { if (leadchar == '?') {
screen_cursor_enable(1); if (n1 == 25) {
screen_cursor_enable(0);
} else if (n1 == 7) {
screen_wrap_enable(0);
}
} }
break; break;
+25 -8
View File
@@ -31,6 +31,7 @@ static struct {
int y; //!< Y coordinate int y; //!< Y coordinate
bool visible; //!< Visible bool visible; //!< Visible
bool inverse; //!< Inverse colors bool inverse; //!< Inverse colors
bool autowrap; //!< Wrapping when EOL
Color fg; //!< Foreground color for writing Color fg; //!< Foreground color for writing
Color bg; //!< Background color for writing Color bg; //!< Background color for writing
} cursor; } cursor;
@@ -102,6 +103,7 @@ cursor_reset(void)
cursor.bg = SCREEN_DEF_BG; cursor.bg = SCREEN_DEF_BG;
cursor.visible = 1; cursor.visible = 1;
cursor.inverse = 0; cursor.inverse = 0;
cursor.autowrap = 1;
} }
//endregion //endregion
@@ -397,6 +399,17 @@ screen_cursor_enable(bool enable)
NOTIFY_DONE(); NOTIFY_DONE();
} }
/**
* Enable autowrap
*/
void ICACHE_FLASH_ATTR
screen_wrap_enable(bool enable)
{
NOTIFY_LOCK();
cursor.autowrap = enable;
NOTIFY_DONE();
}
//endregion //endregion
//region Colors //region Colors
@@ -492,7 +505,7 @@ screen_putchar(char ch)
cursor.x--; cursor.x--;
} else { } else {
// wrap around start of line // wrap around start of line
if (cursor.y>0) { if (cursor.autowrap && cursor.y>0) {
cursor.x=W-1; cursor.x=W-1;
cursor.y--; cursor.y--;
} }
@@ -532,13 +545,17 @@ screen_putchar(char ch)
cursor.x++; cursor.x++;
// X wrap // X wrap
if (cursor.x >= W) { if (cursor.x >= W) {
cursor.x = 0; if (cursor.autowrap) {
cursor.y++; cursor.x = 0;
// Y wrap cursor.y++;
if (cursor.y > H-1) { // Y wrap
// Scroll up, so we have space for writing if (cursor.y > H - 1) {
screen_scroll_up(1); // Scroll up, so we have space for writing
cursor.y = H-1; screen_scroll_up(1);
cursor.y = H - 1;
}
} else {
cursor.x = W - 1;
} }
} }
+3
View File
@@ -109,6 +109,9 @@ void screen_cursor_restore(bool withAttrs);
/** Enable cursor display */ /** Enable cursor display */
void screen_cursor_enable(bool enable); void screen_cursor_enable(bool enable);
/** Enable auto wrap */
void screen_wrap_enable(bool enable);
// --- Colors --- // --- Colors ---
/** Set cursor foreground color */ /** Set cursor foreground color */
+15
View File
@@ -24,6 +24,8 @@
#include "screen.h" #include "screen.h"
#include "routes.h" #include "routes.h"
#include "user_main.h" #include "user_main.h"
#include "uart_driver.h"
#include "ansi_parser_callbacks.h"
#ifdef ESPFS_POS #ifdef ESPFS_POS
CgiUploadFlashDef uploadParams={ CgiUploadFlashDef uploadParams={
@@ -92,6 +94,15 @@ void ICACHE_FLASH_ATTR user_init(void)
ioInit(); ioInit();
// Change AP name if AI-THINKER found (means un-initialized device)
struct softap_config apconf;
wifi_softap_get_config(&apconf);
if (strstarts((char*)apconf.ssid, "AI-THINKER")) {
warn("Un-initialized device, performing factory reset.");
apars_handle_OSC_FactoryReset();
return;
}
// 0x40200000 is the base address for spi flash memory mapping, ESPFS_POS is the position // 0x40200000 is the base address for spi flash memory mapping, ESPFS_POS is the position
// where image is written in flash that is defined in Makefile. // where image is written in flash that is defined in Makefile.
#ifdef ESPFS_POS #ifdef ESPFS_POS
@@ -114,6 +125,10 @@ void ICACHE_FLASH_ATTR user_init(void)
// The terminal screen // The terminal screen
screen_init(); screen_init();
// Print the CANCEL character to indicate the module has restarted
// Critically important for client application if any kind of screen persistence / content re-use is needed
UART_WriteChar(UART0, 24, UART_TIMEOUT_US); // 0x18 - 24 - CAN
info("Listening on UART0, 115200-8-N-1!"); info("Listening on UART0, 115200-8-N-1!");
} }
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef USER_MAIN_H_H #ifndef USER_MAIN_H_H
#define USER_MAIN_H_H #define USER_MAIN_H_H
#define FIRMWARE_VERSION "0.5.1" #define FIRMWARE_VERSION "0.5.4"
#define TERMINAL_GITHUB_REPO "https://github.com/MightyPork/esp-vt100-firmware" #define TERMINAL_GITHUB_REPO "https://github.com/MightyPork/esp-vt100-firmware"
#endif //USER_MAIN_H_H #endif //USER_MAIN_H_H