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

pull/30/head
Ondřej Hruška 7 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. 68
      user/screen.c
  10. 19
      user/screen.h
  11. 21
      user/user_main.c

1
.gitignore vendored

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

@ -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

@ -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 */

@ -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 */

@ -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;
}
}

@ -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 ; 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) {

@ -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.");

@ -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:

@ -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);

@ -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();

Loading…
Cancel
Save