implemented saving to alternate buffer (except screen content)

http-comm
Ondřej Hruška 7 years ago
parent a12dcfc86f
commit ea97752867
  1. 7
      user/apars_csi.c
  2. 117
      user/screen.c
  3. 2
      user/wifimgr.c

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

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

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

Loading…
Cancel
Save