implemented saving to alternate buffer (except screen content)
This commit is contained in:
+1
-6
@@ -672,12 +672,7 @@ do_csi_set_private_option(CSI_Data *opts)
|
|||||||
}
|
}
|
||||||
else if (n == 1048) {
|
else if (n == 1048) {
|
||||||
// same as DECSC - save/restore cursor with attributes
|
// same as DECSC - save/restore cursor with attributes
|
||||||
if (yn) {
|
screen_cursor_save(yn);
|
||||||
screen_cursor_save(true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
screen_cursor_restore(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (n == 1049) {
|
else if (n == 1049) {
|
||||||
// save/restore cursor and screen and clear it
|
// save/restore cursor and screen and clear it
|
||||||
|
|||||||
+91
-26
@@ -7,7 +7,6 @@
|
|||||||
#include "apars_logging.h"
|
#include "apars_logging.h"
|
||||||
#include "jstring.h"
|
#include "jstring.h"
|
||||||
#include "character_sets.h"
|
#include "character_sets.h"
|
||||||
#include "uart_driver.h"
|
|
||||||
|
|
||||||
TerminalConfigBundle * const termconf = &persist.current.termconf;
|
TerminalConfigBundle * const termconf = &persist.current.termconf;
|
||||||
TerminalConfigBundle termconf_scratch;
|
TerminalConfigBundle termconf_scratch;
|
||||||
@@ -41,12 +40,8 @@ typedef struct __attribute__((packed)){
|
|||||||
static Cell screen[MAX_SCREEN_SIZE];
|
static Cell screen[MAX_SCREEN_SIZE];
|
||||||
|
|
||||||
|
|
||||||
#define TABSTOP_WORDS 5
|
|
||||||
/**
|
|
||||||
* Tab stops bitmap
|
|
||||||
*/
|
|
||||||
static u32 tab_stops[TABSTOP_WORDS];
|
|
||||||
|
|
||||||
|
#define TABSTOP_WORDS 5
|
||||||
/**
|
/**
|
||||||
* Screen state structure
|
* Screen state structure
|
||||||
*/
|
*/
|
||||||
@@ -63,6 +58,8 @@ static struct {
|
|||||||
// Vertical margin bounds (inclusive start/end of scrolling region)
|
// Vertical margin bounds (inclusive start/end of scrolling region)
|
||||||
int vm0;
|
int vm0;
|
||||||
int vm1;
|
int vm1;
|
||||||
|
|
||||||
|
u32 tab_stops[TABSTOP_WORDS]; // tab stops bitmap
|
||||||
} scr;
|
} scr;
|
||||||
|
|
||||||
#define R0 scr.vm0
|
#define R0 scr.vm0
|
||||||
@@ -107,6 +104,19 @@ static CursorTypeDef cursor;
|
|||||||
static CursorTypeDef cursor_sav;
|
static CursorTypeDef cursor_sav;
|
||||||
bool cursor_saved = false;
|
bool cursor_saved = false;
|
||||||
|
|
||||||
|
/** This structure holds old state when switching to an alternate buffer */
|
||||||
|
static struct {
|
||||||
|
bool alternate_active;
|
||||||
|
char title[TERM_TITLE_LEN];
|
||||||
|
char btn[TERM_BTN_COUNT][TERM_BTN_LEN];
|
||||||
|
char btn_msg[TERM_BTN_COUNT][TERM_BTN_MSG_LEN];
|
||||||
|
u32 width;
|
||||||
|
u32 height;
|
||||||
|
int vm0;
|
||||||
|
int vm1;
|
||||||
|
u32 tab_stops[TABSTOP_WORDS];
|
||||||
|
} state_backup;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is used to prevent premature change notifications
|
* This is used to prevent premature change notifications
|
||||||
* (from nested calls)
|
* (from nested calls)
|
||||||
@@ -282,12 +292,35 @@ screen_reset_sgr(void)
|
|||||||
cursor.inverse = false;
|
cursor.inverse = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the screen - called by ESC c
|
||||||
|
*/
|
||||||
|
static void ICACHE_FLASH_ATTR
|
||||||
|
screen_reset_on_resize(void)
|
||||||
|
{
|
||||||
|
dbg("Screen partial reset due to resize");
|
||||||
|
NOTIFY_LOCK();
|
||||||
|
|
||||||
|
cursor.x = 0;
|
||||||
|
cursor.y = 0;
|
||||||
|
cursor.hanging = false;
|
||||||
|
|
||||||
|
scr.vm0 = 0;
|
||||||
|
scr.vm1 = H-1;
|
||||||
|
|
||||||
|
// size is left unchanged
|
||||||
|
screen_clear(CLEAR_ALL);
|
||||||
|
|
||||||
|
NOTIFY_DONE();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the screen - called by ESC c
|
* Reset the screen - called by ESC c
|
||||||
*/
|
*/
|
||||||
void ICACHE_FLASH_ATTR
|
void ICACHE_FLASH_ATTR
|
||||||
screen_reset(void)
|
screen_reset(void)
|
||||||
{
|
{
|
||||||
|
dbg("Screen reset.");
|
||||||
NOTIFY_LOCK();
|
NOTIFY_LOCK();
|
||||||
|
|
||||||
cursor_reset();
|
cursor_reset();
|
||||||
@@ -301,6 +334,8 @@ screen_reset(void)
|
|||||||
scr.vm0 = 0;
|
scr.vm0 = 0;
|
||||||
scr.vm1 = H-1;
|
scr.vm1 = H-1;
|
||||||
|
|
||||||
|
state_backup.alternate_active = false;
|
||||||
|
|
||||||
mouse_tracking.encoding = MTE_SIMPLE;
|
mouse_tracking.encoding = MTE_SIMPLE;
|
||||||
mouse_tracking.focus_tracking = false;
|
mouse_tracking.focus_tracking = false;
|
||||||
mouse_tracking.mode = MTM_NONE;
|
mouse_tracking.mode = MTM_NONE;
|
||||||
@@ -312,7 +347,7 @@ screen_reset(void)
|
|||||||
|
|
||||||
// Set initial tabstops
|
// Set initial tabstops
|
||||||
for (int i = 0; i < TABSTOP_WORDS; i++) {
|
for (int i = 0; i < TABSTOP_WORDS; i++) {
|
||||||
tab_stops[i] = 0x80808080;
|
scr.tab_stops[i] = 0x80808080;
|
||||||
}
|
}
|
||||||
|
|
||||||
NOTIFY_DONE();
|
NOTIFY_DONE();
|
||||||
@@ -326,7 +361,42 @@ screen_reset(void)
|
|||||||
void ICACHE_FLASH_ATTR
|
void ICACHE_FLASH_ATTR
|
||||||
screen_swap_state(bool alternate)
|
screen_swap_state(bool alternate)
|
||||||
{
|
{
|
||||||
// TODO impl - backup/restore title, size, global attributes (not SGR)
|
if (alternate == state_backup.alternate_active) {
|
||||||
|
warn("No swap, already alternate = %d", alternate);
|
||||||
|
return; // nothing to do
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alternate) {
|
||||||
|
dbg("Swap to alternate");
|
||||||
|
// store old state
|
||||||
|
memcpy(state_backup.title, termconf_scratch.title, TERM_TITLE_LEN);
|
||||||
|
memcpy(state_backup.btn, termconf_scratch.btn, sizeof(termconf_scratch.btn));
|
||||||
|
memcpy(state_backup.btn_msg, termconf_scratch.btn_msg, sizeof(termconf_scratch.btn_msg));
|
||||||
|
memcpy(state_backup.tab_stops, scr.tab_stops, sizeof(scr.tab_stops));
|
||||||
|
state_backup.vm0 = scr.vm0;
|
||||||
|
state_backup.vm1 = scr.vm1;
|
||||||
|
// remember old size. may have to resize when returning
|
||||||
|
state_backup.width = W;
|
||||||
|
state_backup.height = H;
|
||||||
|
// TODO backup screen content (if this is ever possible)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dbg("Unswap from alternate");
|
||||||
|
NOTIFY_LOCK();
|
||||||
|
memcpy(termconf_scratch.title, state_backup.title, TERM_TITLE_LEN);
|
||||||
|
memcpy(termconf_scratch.btn, state_backup.btn, sizeof(termconf_scratch.btn));
|
||||||
|
memcpy(termconf_scratch.btn_msg, state_backup.btn_msg, sizeof(termconf_scratch.btn_msg));
|
||||||
|
memcpy(scr.tab_stops, state_backup.tab_stops, sizeof(scr.tab_stops));
|
||||||
|
scr.vm0 = state_backup.vm0;
|
||||||
|
scr.vm1 = state_backup.vm1;
|
||||||
|
// this may clear the screen as a side effect if size changed
|
||||||
|
screen_resize(state_backup.height, state_backup.width);
|
||||||
|
// TODO restore screen content (if this is ever possible)
|
||||||
|
NOTIFY_DONE();
|
||||||
|
screen_notifyChange(CHANGE_LABELS);
|
||||||
|
}
|
||||||
|
|
||||||
|
state_backup.alternate_active = alternate;
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
@@ -336,19 +406,19 @@ screen_swap_state(bool alternate)
|
|||||||
void ICACHE_FLASH_ATTR
|
void ICACHE_FLASH_ATTR
|
||||||
screen_clear_all_tabs(void)
|
screen_clear_all_tabs(void)
|
||||||
{
|
{
|
||||||
memset(tab_stops, 0, sizeof(tab_stops));
|
memset(scr.tab_stops, 0, sizeof(scr.tab_stops));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICACHE_FLASH_ATTR
|
void ICACHE_FLASH_ATTR
|
||||||
screen_set_tab(void)
|
screen_set_tab(void)
|
||||||
{
|
{
|
||||||
tab_stops[cursor.x/32] |= (1<<(cursor.x%32));
|
scr.tab_stops[cursor.x/32] |= (1<<(cursor.x%32));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICACHE_FLASH_ATTR
|
void ICACHE_FLASH_ATTR
|
||||||
screen_clear_tab(void)
|
screen_clear_tab(void)
|
||||||
{
|
{
|
||||||
tab_stops[cursor.x/32] &= ~(1<<(cursor.x%32));
|
scr.tab_stops[cursor.x/32] &= ~(1<<(cursor.x%32));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -366,7 +436,7 @@ next_tab_stop(void)
|
|||||||
int offs = (cursor.x+1)%32;
|
int offs = (cursor.x+1)%32;
|
||||||
int cp = cursor.x;
|
int cp = cursor.x;
|
||||||
while (idx < TABSTOP_WORDS) {
|
while (idx < TABSTOP_WORDS) {
|
||||||
u32 w = tab_stops[idx];
|
u32 w = scr.tab_stops[idx];
|
||||||
w >>= offs;
|
w >>= offs;
|
||||||
for(;offs<32;offs++) {
|
for(;offs<32;offs++) {
|
||||||
cp++;
|
cp++;
|
||||||
@@ -396,7 +466,7 @@ prev_tab_stop(void)
|
|||||||
int offs = (cursor.x-1)%32;
|
int offs = (cursor.x-1)%32;
|
||||||
int cp = cursor.x;
|
int cp = cursor.x;
|
||||||
while (idx >= 0) {
|
while (idx >= 0) {
|
||||||
u32 w = tab_stops[idx];
|
u32 w = scr.tab_stops[idx];
|
||||||
w <<= 31-offs;
|
w <<= 31-offs;
|
||||||
if (w == 0) {
|
if (w == 0) {
|
||||||
cp -= cp%32;
|
cp -= cp%32;
|
||||||
@@ -651,22 +721,23 @@ screen_fill_with_E(void)
|
|||||||
void ICACHE_FLASH_ATTR
|
void ICACHE_FLASH_ATTR
|
||||||
screen_resize(int rows, int cols)
|
screen_resize(int rows, int cols)
|
||||||
{
|
{
|
||||||
NOTIFY_LOCK();
|
|
||||||
// sanitize
|
// sanitize
|
||||||
if (cols < 1 || rows < 1) {
|
if (cols < 1 || rows < 1) {
|
||||||
error("Screen size must be positive");
|
error("Screen size must be positive, ignoring command: %d x %d", cols, rows);
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cols * rows > MAX_SCREEN_SIZE) {
|
if (cols * rows > MAX_SCREEN_SIZE) {
|
||||||
error("Max screen size exceeded");
|
error("Max screen size exceeded, ignoring command: %d x %d", cols, rows);
|
||||||
goto done;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (W == cols && H == rows) return; // Do nothing
|
||||||
|
|
||||||
|
NOTIFY_LOCK();
|
||||||
W = cols;
|
W = cols;
|
||||||
H = rows;
|
H = rows;
|
||||||
screen_reset();
|
screen_reset_on_resize();
|
||||||
done:
|
|
||||||
NOTIFY_DONE();
|
NOTIFY_DONE();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1289,12 +1360,6 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data)
|
|||||||
size_t remain = buf_len;
|
size_t remain = buf_len;
|
||||||
char *bb = buffer;
|
char *bb = buffer;
|
||||||
|
|
||||||
// Ideally we'd use snprintf here!
|
|
||||||
#define bufprint(fmt, ...) do { \
|
|
||||||
used = sprintf(bb, fmt, ##__VA_ARGS__); \
|
|
||||||
if(used>0) { bb += used; remain -= used; } \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define bufput_c(c) do { \
|
#define bufput_c(c) do { \
|
||||||
*bb = (char)c; bb++; \
|
*bb = (char)c; bb++; \
|
||||||
remain--; \
|
remain--; \
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ configure_station(void)
|
|||||||
struct station_config conf;
|
struct station_config conf;
|
||||||
strcpy((char *) conf.ssid, (char *) wificonf->sta_ssid);
|
strcpy((char *) conf.ssid, (char *) wificonf->sta_ssid);
|
||||||
strcpy((char *) conf.password, (char *) wificonf->sta_password);
|
strcpy((char *) conf.password, (char *) wificonf->sta_password);
|
||||||
dbg("[WiFi] Connecting to \"%s\", password \"%s\"", conf.ssid, conf.password);
|
dbg("[WiFi] Connecting to \"%s\"%s password", conf.ssid, conf.password[0]!=0?" using saved":", no");
|
||||||
conf.bssid_set = 0;
|
conf.bssid_set = 0;
|
||||||
conf.bssid[0] = 0;
|
conf.bssid[0] = 0;
|
||||||
wifi_station_disconnect();
|
wifi_station_disconnect();
|
||||||
|
|||||||
Reference in New Issue
Block a user