implemented mouse input, CSI6n cmd, added sass cmd to build_web.sh

pull/30/head
Ondřej Hruška 8 years ago
parent def04042a7
commit 1d52cd551a
  1. 1
      .gitignore
  2. 2
      build_web.sh
  3. 8
      html/css/app.css
  4. 8
      html_orig/css/app.css
  5. 4
      html_orig/sass/pages/_term.scss
  6. 2
      libesphttpd
  7. 26
      user/ansi_parser_callbacks.c
  8. 35
      user/cgi_sockets.c
  9. 64
      user/screen.c
  10. 19
      user/screen.h
  11. 19
      user/user_main.c

1
.gitignore vendored

@ -14,5 +14,6 @@ eagle.app.sym
.idea/ .idea/
CMakeLists.txt CMakeLists.txt
cmake-build-debug/ cmake-build-debug/
.sass-cache
*.map *.map

@ -11,6 +11,8 @@ cat $DD/chibi.js \
$DD/term.js \ $DD/term.js \
$DD/wifi.js > html/js/app.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 # 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/css/app.css html/css/app.css
cp html_orig/term.html html/term.tpl cp html_orig/term.html html/term.tpl

@ -668,6 +668,10 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
.page-term h1 { .page-term h1 {
font-size: 1.42383em; } } font-size: 1.42383em; } }
.page-term #screen { .page-term #screen {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
font-family: monospace; font-family: monospace;
font-size: 16pt; font-size: 16pt;
white-space: nowrap; white-space: nowrap;
@ -680,7 +684,7 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
cursor: pointer; } cursor: pointer; }
.page-term #screen span:hover { .page-term #screen span:hover {
outline: 1px solid rgba(255, 255, 255, 0.4); } 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 { .page-term #screen span:hover {
outline: 0 none; } } outline: 0 none; } }
.page-term #buttons { .page-term #buttons {
@ -697,5 +701,3 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
#termwrap { #termwrap {
text-align: center; } text-align: center; }
/*# sourceMappingURL=app.css.map */

@ -668,6 +668,10 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
.page-term h1 { .page-term h1 {
font-size: 1.42383em; } } font-size: 1.42383em; } }
.page-term #screen { .page-term #screen {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
font-family: monospace; font-family: monospace;
font-size: 16pt; font-size: 16pt;
white-space: nowrap; white-space: nowrap;
@ -680,7 +684,7 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
cursor: pointer; } cursor: pointer; }
.page-term #screen span:hover { .page-term #screen span:hover {
outline: 1px solid rgba(255, 255, 255, 0.4); } 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 { .page-term #screen span:hover {
outline: 0 none; } } outline: 0 none; } }
.page-term #buttons { .page-term #buttons {
@ -697,5 +701,3 @@ input[type="number"], input[type="password"], input[type="text"], textarea, sele
#termwrap { #termwrap {
text-align: center; } text-align: center; }
/*# sourceMappingURL=app.css.map */

@ -7,6 +7,8 @@
} }
#screen { #screen {
@include noselect();
font-family: monospace; font-family: monospace;
font-size: 16pt; font-size: 16pt;
white-space: nowrap; white-space: nowrap;
@ -21,7 +23,7 @@
cursor: pointer; cursor: pointer;
&:hover { &:hover {
outline: 1px solid rgba(#ffffff,0.4); outline: 1px solid rgba(#ffffff,0.4);
@include media($tablet-max) { @include media($phone) {
outline: 0 none; outline: 0 none;
} }
} }

@ -1 +1 @@
Subproject commit 439df03f4b8e4c1ec5d7dc14695c80a4e35eb7ce Subproject commit fba7cec0b6443c5ee71afde9a45cf832c49562c9

@ -53,7 +53,7 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
CSI n T SD Scroll Down CSI n T SD Scroll Down
CSI n ; m f HVP Horizontal and Vertical Position CSI n ; m f HVP Horizontal and Vertical Position
CSI n m SGR Select Graphic Rendition (Implemented only some) 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 s SCP Save Cursor Position
CSI u RCP Restore Cursor Position CSI u RCP Restore Cursor Position
CSI ?25l DECTCEM Hides the cursor CSI ?25l DECTCEM Hides the cursor
@ -92,18 +92,18 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
switch (keychar) { switch (keychar) {
// CUU CUD CUF CUB // CUU CUD CUF CUB
case 'A': screen_cursor_move(0, -n1); break; case 'A': screen_cursor_move(-n1, 0); break;
case 'B': screen_cursor_move(0, n1); break; case 'B': screen_cursor_move(n1, 0); break;
case 'C': screen_cursor_move(n1, 0); break; case 'C': screen_cursor_move(0, n1); break;
case 'D': screen_cursor_move(-n1, 0); break; case 'D': screen_cursor_move(0, -n1); break;
case 'E': // CNL case 'E': // CNL
screen_cursor_move(0, n1); screen_cursor_move(n1, 0);
screen_cursor_set_x(0); screen_cursor_set_x(0);
break; break;
case 'F': // CPL case 'F': // CPL
screen_cursor_move(0, -n1); screen_cursor_move(-n1, 0);
screen_cursor_set_x(0); screen_cursor_set_x(0);
break; break;
@ -118,7 +118,7 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
// CUP,HVP // CUP,HVP
case 'H': case 'H':
case 'f': 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 case 'J': // ED
if (n1 == 0) { if (n1 == 0) {
@ -146,6 +146,16 @@ apars_handle_CSI(char leadchar, int *params, char keychar)
case 's': screen_cursor_save(); break; case 's': screen_cursor_save(); break;
case 'u': screen_cursor_restore(); 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 // DECTCEM cursor show hide
case 'l': case 'l':
if (leadchar == '?' && n1 == 25) { if (leadchar == '?' && n1 == 25) {

@ -32,12 +32,12 @@ void ICACHE_FLASH_ATTR screen_notifyChange()
/** Socket received a message */ /** Socket received a message */
void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags) void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
{ {
char buf[20];
// Add terminator if missing (seems to randomly happen) // Add terminator if missing (seems to randomly happen)
data[len] = 0; data[len] = 0;
dbg("Sock RX str: %s, len %d", data, len); dbg("Sock RX str: %s, len %d", data, len);
if (strstarts(data, "STR:")) { if (strstarts(data, "STR:")) {
// pass string verbatim // pass string verbatim
UART_WriteString(UART0, data+4, UART_TIMEOUT_US); 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:")) { else if (strstarts(data, "TAP:")) {
// TODO // this comes in as 0-based
warn("TODO mouse input handling not implemented!");
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 { else {
warn("Bad command."); warn("Bad command.");

@ -27,8 +27,8 @@ static Cell screen[MAX_SCREEN_SIZE];
* Cursor position and attributes * Cursor position and attributes
*/ */
static struct { static struct {
Coordinate x; //!< X coordinate int x; //!< X coordinate
Coordinate y; //!< Y coordinate int y; //!< Y coordinate
bool visible; //!< Visible bool visible; //!< Visible
bool inverse; //!< Inverse colors bool inverse; //!< Inverse colors
Color fg; //!< Foreground color for writing Color fg; //!< Foreground color for writing
@ -39,19 +39,19 @@ static struct {
* Saved cursor position, used with the SCP RCP commands * Saved cursor position, used with the SCP RCP commands
*/ */
static struct { static struct {
Coordinate x; int x;
Coordinate y; int y;
} cursor_sav; } cursor_sav;
/** /**
* Active screen width * Active screen width
*/ */
static Coordinate W = SCREEN_DEF_W; static int W = SCREEN_DEF_W;
/** /**
* Active screen height * Active screen height
*/ */
static Coordinate H = SCREEN_DEF_H; static int H = SCREEN_DEF_H;
// XXX volatile is probably not needed // XXX volatile is probably not needed
static volatile int notifyLock = 0; static volatile int notifyLock = 0;
@ -193,7 +193,7 @@ screen_clear_line(ClearMode mode)
* @param rows - new height * @param rows - new height
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_resize(Coordinate rows, Coordinate cols) screen_resize(int rows, int cols)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
// sanitize // sanitize
@ -277,7 +277,7 @@ done:
* Set cursor position * Set cursor position
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_cursor_set(Coordinate x, Coordinate y) screen_cursor_set(int y, int x)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
if (x >= W) x = W - 1; if (x >= W) x = W - 1;
@ -287,11 +287,21 @@ screen_cursor_set(Coordinate x, Coordinate y)
NOTIFY_DONE(); 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 * Set cursor X position
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_cursor_set_x(Coordinate x) screen_cursor_set_x(int x)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
if (x >= W) x = W - 1; if (x >= W) x = W - 1;
@ -303,7 +313,7 @@ screen_cursor_set_x(Coordinate x)
* Set cursor Y position * Set cursor Y position
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_cursor_set_y(Coordinate y) screen_cursor_set_y(int y)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
if (y >= H) y = H - 1; if (y >= H) y = H - 1;
@ -315,7 +325,7 @@ screen_cursor_set_y(Coordinate y)
* Relative cursor move * Relative cursor move
*/ */
void ICACHE_FLASH_ATTR void ICACHE_FLASH_ATTR
screen_cursor_move(int dx, int dy) screen_cursor_move(int dy, int dx)
{ {
NOTIFY_LOCK(); NOTIFY_LOCK();
int move; int move;
@ -431,6 +441,18 @@ screen_set_bright_fg(void)
//endregion //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. * Set a character in the cursor color, move to right with wrap.
*/ */
@ -448,23 +470,31 @@ screen_putchar(char ch)
goto done; goto done;
case '\n': case '\n':
screen_cursor_move(0, 1); screen_cursor_move(1, 0);
goto done; goto done;
case 8: // BS 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 // erase target cell
c = &screen[cursor.x + cursor.y * W]; c = &screen[cursor.x + cursor.y * W];
c->c = ' '; c->c = ' ';
goto done; goto done;
case 9: // TAB case 9: // TAB
if (cursor.x<((W-1)-(W-1)%4)) {
c->c = ' '; c->c = ' ';
// nested recurs >:( but it's ok do {
screen_putchar(' ');
screen_putchar(' ');
screen_putchar(' ');
screen_putchar(' '); screen_putchar(' ');
} while(cursor.x%4!=0);
}
goto done; goto done;
default: default:

@ -24,7 +24,7 @@
* 8 black, 9 red, 10 green, 11 yellow * 8 black, 9 red, 10 green, 11 yellow
* 12 blue, 13 mag, 14 cyan, 15 white * 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. * X grows to the right, Y to the bottom.
* *
* +----> * +---->
@ -53,7 +53,6 @@ typedef enum {
} ClearMode; } ClearMode;
typedef uint8_t Color; typedef uint8_t Color;
typedef int Coordinate;
httpd_cgi_state ICACHE_FLASH_ATTR httpd_cgi_state ICACHE_FLASH_ATTR
screenSerializeToBuffer(char *buffer, size_t buf_len, void **data); 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); void screen_init(void);
/** Change the screen size */ /** 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 --- // --- Clearing ---
@ -84,16 +86,19 @@ void screen_scroll_down(unsigned int lines);
// --- Cursor control --- // --- Cursor control ---
/** Set cursor position */ /** 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 */ /** Set cursor X position */
void screen_cursor_set_x(Coordinate x); void screen_cursor_set_x(int x);
/** Set cursor Y position */ /** Set cursor Y position */
void screen_cursor_set_y(Coordinate y); void screen_cursor_set_y(int y);
/** Relative cursor move */ /** Relative cursor move */
void screen_cursor_move(int dx, int dy); void screen_cursor_move(int dy, int dx);
/** Save the cursor pos */ /** Save the cursor pos */
void screen_cursor_save(void); void screen_cursor_save(void);

@ -23,7 +23,7 @@
#include "screen.h" #include "screen.h"
#include "routes.h" #include "routes.h"
#define FIRMWARE_VERSION "0.2" #define FIRMWARE_VERSION "0.3"
#ifdef ESPFS_POS #ifdef ESPFS_POS
CgiUploadFlashDef uploadParams={ CgiUploadFlashDef uploadParams={
@ -50,20 +50,29 @@ static ETSTimer prHeapTimer;
/** Periodically show heap usage */ /** Periodically show heap usage */
static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) 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 = "+"; const char *cc = "+";
if (diff<0) cc = ""; if (diff<0) cc = "";
if (diff == 0) { if (diff == 0) {
if (cnt == 5) {
// only every 5 secs if no change
dbg("Free heap: %d bytes", heap); dbg("Free heap: %d bytes", heap);
cnt = 0;
}
} else { } else {
// report change
dbg("Free heap: %d bytes (%s%d)", heap, cc, diff); dbg("Free heap: %d bytes (%s%d)", heap, cc, diff);
cnt = 0;
} }
last = heap; last = heap;
cnt++;
} }
//Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done. //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 // Heap use timer & blink
os_timer_disarm(&prHeapTimer); os_timer_disarm(&prHeapTimer);
os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL); os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL);
os_timer_arm(&prHeapTimer, 5000, 1); os_timer_arm(&prHeapTimer, 1000, 1);
// The terminal screen // The terminal screen
screen_init(); screen_init();

Loading…
Cancel
Save