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) {
|
||||
// same as DECSC - save/restore cursor with attributes
|
||||
if (yn) {
|
||||
screen_cursor_save(true);
|
||||
}
|
||||
else {
|
||||
screen_cursor_restore(true);
|
||||
}
|
||||
screen_cursor_save(yn);
|
||||
}
|
||||
else if (n == 1049) {
|
||||
// save/restore cursor and screen and clear it
|
||||
|
||||
+91
-26
@@ -7,7 +7,6 @@
|
||||
#include "apars_logging.h"
|
||||
#include "jstring.h"
|
||||
#include "character_sets.h"
|
||||
#include "uart_driver.h"
|
||||
|
||||
TerminalConfigBundle * const termconf = &persist.current.termconf;
|
||||
TerminalConfigBundle termconf_scratch;
|
||||
@@ -41,12 +40,8 @@ typedef struct __attribute__((packed)){
|
||||
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
|
||||
*/
|
||||
@@ -63,6 +58,8 @@ static struct {
|
||||
// Vertical margin bounds (inclusive start/end of scrolling region)
|
||||
int vm0;
|
||||
int vm1;
|
||||
|
||||
u32 tab_stops[TABSTOP_WORDS]; // tab stops bitmap
|
||||
} scr;
|
||||
|
||||
#define R0 scr.vm0
|
||||
@@ -107,6 +104,19 @@ static CursorTypeDef cursor;
|
||||
static CursorTypeDef cursor_sav;
|
||||
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
|
||||
* (from nested calls)
|
||||
@@ -282,12 +292,35 @@ screen_reset_sgr(void)
|
||||
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
|
||||
*/
|
||||
void ICACHE_FLASH_ATTR
|
||||
screen_reset(void)
|
||||
{
|
||||
dbg("Screen reset.");
|
||||
NOTIFY_LOCK();
|
||||
|
||||
cursor_reset();
|
||||
@@ -301,6 +334,8 @@ screen_reset(void)
|
||||
scr.vm0 = 0;
|
||||
scr.vm1 = H-1;
|
||||
|
||||
state_backup.alternate_active = false;
|
||||
|
||||
mouse_tracking.encoding = MTE_SIMPLE;
|
||||
mouse_tracking.focus_tracking = false;
|
||||
mouse_tracking.mode = MTM_NONE;
|
||||
@@ -312,7 +347,7 @@ screen_reset(void)
|
||||
|
||||
// Set initial tabstops
|
||||
for (int i = 0; i < TABSTOP_WORDS; i++) {
|
||||
tab_stops[i] = 0x80808080;
|
||||
scr.tab_stops[i] = 0x80808080;
|
||||
}
|
||||
|
||||
NOTIFY_DONE();
|
||||
@@ -326,7 +361,42 @@ screen_reset(void)
|
||||
void ICACHE_FLASH_ATTR
|
||||
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
|
||||
@@ -336,19 +406,19 @@ screen_swap_state(bool alternate)
|
||||
void ICACHE_FLASH_ATTR
|
||||
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
|
||||
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
|
||||
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 cp = cursor.x;
|
||||
while (idx < TABSTOP_WORDS) {
|
||||
u32 w = tab_stops[idx];
|
||||
u32 w = scr.tab_stops[idx];
|
||||
w >>= offs;
|
||||
for(;offs<32;offs++) {
|
||||
cp++;
|
||||
@@ -396,7 +466,7 @@ prev_tab_stop(void)
|
||||
int offs = (cursor.x-1)%32;
|
||||
int cp = cursor.x;
|
||||
while (idx >= 0) {
|
||||
u32 w = tab_stops[idx];
|
||||
u32 w = scr.tab_stops[idx];
|
||||
w <<= 31-offs;
|
||||
if (w == 0) {
|
||||
cp -= cp%32;
|
||||
@@ -651,22 +721,23 @@ screen_fill_with_E(void)
|
||||
void ICACHE_FLASH_ATTR
|
||||
screen_resize(int rows, int cols)
|
||||
{
|
||||
NOTIFY_LOCK();
|
||||
// sanitize
|
||||
if (cols < 1 || rows < 1) {
|
||||
error("Screen size must be positive");
|
||||
goto done;
|
||||
error("Screen size must be positive, ignoring command: %d x %d", cols, rows);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cols * rows > MAX_SCREEN_SIZE) {
|
||||
error("Max screen size exceeded");
|
||||
goto done;
|
||||
error("Max screen size exceeded, ignoring command: %d x %d", cols, rows);
|
||||
return;
|
||||
}
|
||||
|
||||
if (W == cols && H == rows) return; // Do nothing
|
||||
|
||||
NOTIFY_LOCK();
|
||||
W = cols;
|
||||
H = rows;
|
||||
screen_reset();
|
||||
done:
|
||||
screen_reset_on_resize();
|
||||
NOTIFY_DONE();
|
||||
}
|
||||
|
||||
@@ -1289,12 +1360,6 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data)
|
||||
size_t remain = buf_len;
|
||||
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 { \
|
||||
*bb = (char)c; bb++; \
|
||||
remain--; \
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ configure_station(void)
|
||||
struct station_config conf;
|
||||
strcpy((char *) conf.ssid, (char *) wificonf->sta_ssid);
|
||||
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[0] = 0;
|
||||
wifi_station_disconnect();
|
||||
|
||||
Reference in New Issue
Block a user