Implement support for save/restore of DEC private modes (CSI ? s/r)
This commit is contained in:
parent
a9be05c885
commit
855b3de473
@ -201,22 +201,6 @@ typedef struct {
|
||||
DynamicColor configured, overridden;
|
||||
} ColorProfile;
|
||||
|
||||
#define SAVEPOINTS_SZ 256
|
||||
|
||||
typedef struct {
|
||||
uint32_t utf8_state, utf8_codepoint, *g0_charset, *g1_charset, *g_charset;
|
||||
bool use_latin1;
|
||||
Cursor cursor;
|
||||
bool mDECOM, mDECAWM, mDECSCNM;
|
||||
|
||||
} Savepoint;
|
||||
|
||||
|
||||
typedef struct {
|
||||
Savepoint buf[SAVEPOINTS_SZ];
|
||||
index_type start_of_data, count;
|
||||
} SavepointBuffer;
|
||||
|
||||
|
||||
#define PARSER_BUF_SZ (8 * 1024)
|
||||
#define READ_BUF_SZ (1024*1024)
|
||||
|
||||
@ -370,13 +370,13 @@ screen_cursor_back1(Screen *s, unsigned int count) { screen_cursor_back(s, count
|
||||
static inline void
|
||||
screen_tabn(Screen *s, unsigned int count) { for (index_type i=0; i < MAX(1, count); i++) screen_tab(s); }
|
||||
static inline void
|
||||
save_cursor(Screen *s, unsigned int UNUSED param, bool private) {
|
||||
if (private) fprintf(stderr, "%s %s", ERROR_PREFIX, "CSI s in private mode not supported");
|
||||
save_cursor_or_modes(Screen *s, unsigned int UNUSED param, bool private) {
|
||||
if (private) screen_save_modes(s);
|
||||
else screen_save_cursor(s);
|
||||
}
|
||||
static inline void
|
||||
restore_cursor(Screen *s, unsigned int UNUSED param, bool private) {
|
||||
if (private) fprintf(stderr, "%s %s", ERROR_PREFIX, "CSI u in private mode not supported");
|
||||
restore_cursor_or_modes(Screen *s, unsigned int UNUSED param, bool private) {
|
||||
if (private) screen_restore_modes(s);
|
||||
else screen_restore_cursor(s);
|
||||
}
|
||||
|
||||
@ -690,9 +690,9 @@ dispatch_csi(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
|
||||
case DSR:
|
||||
CALL_CSI_HANDLER1P(report_device_status, 0, '?');
|
||||
case SC:
|
||||
CALL_CSI_HANDLER1P(save_cursor, 0, '?');
|
||||
CALL_CSI_HANDLER1P(save_cursor_or_modes, 0, '?');
|
||||
case RC:
|
||||
CALL_CSI_HANDLER1P(restore_cursor, 0, '?');
|
||||
CALL_CSI_HANDLER1P(restore_cursor_or_modes, 0, '?');
|
||||
case 'r':
|
||||
if (!start_modifier && !end_modifier) {
|
||||
// DECSTBM
|
||||
|
||||
@ -748,19 +748,18 @@ screen_linefeed(Screen *self) {
|
||||
screen_ensure_bounds(self, false);
|
||||
}
|
||||
|
||||
static inline Savepoint*
|
||||
savepoints_push(SavepointBuffer *self) {
|
||||
Savepoint *ans = self->buf + ((self->start_of_data + self->count) % SAVEPOINTS_SZ);
|
||||
if (self->count == SAVEPOINTS_SZ) self->start_of_data = (self->start_of_data + 1) % SAVEPOINTS_SZ;
|
||||
else self->count++;
|
||||
return ans;
|
||||
#define buffer_push(self, ans) { \
|
||||
ans = (self)->buf + (((self)->start_of_data + (self)->count) % SAVEPOINTS_SZ); \
|
||||
if ((self)->count == SAVEPOINTS_SZ) (self)->start_of_data = ((self)->start_of_data + 1) % SAVEPOINTS_SZ; \
|
||||
else (self)->count++; \
|
||||
}
|
||||
|
||||
static inline Savepoint*
|
||||
savepoints_pop(SavepointBuffer *self) {
|
||||
if (self->count == 0) return NULL;
|
||||
self->count--;
|
||||
return self->buf + ((self->start_of_data + self->count) % SAVEPOINTS_SZ);
|
||||
#define buffer_pop(self, ans) { \
|
||||
if ((self)->count == 0) ans = NULL; \
|
||||
else { \
|
||||
(self)->count--; \
|
||||
ans = (self)->buf + (((self)->start_of_data + (self)->count) % SAVEPOINTS_SZ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define COPY_CHARSETS(self, sp) \
|
||||
@ -774,7 +773,8 @@ savepoints_pop(SavepointBuffer *self) {
|
||||
void
|
||||
screen_save_cursor(Screen *self) {
|
||||
SavepointBuffer *pts = self->linebuf == self->main_linebuf ? &self->main_savepoints : &self->alt_savepoints;
|
||||
Savepoint *sp = savepoints_push(pts);
|
||||
Savepoint *sp;
|
||||
buffer_push(pts, sp);
|
||||
cursor_copy_to(self->cursor, &(sp->cursor));
|
||||
sp->mDECOM = self->modes.mDECOM;
|
||||
sp->mDECAWM = self->modes.mDECAWM;
|
||||
@ -782,10 +782,18 @@ screen_save_cursor(Screen *self) {
|
||||
COPY_CHARSETS(self, sp);
|
||||
}
|
||||
|
||||
void
|
||||
screen_save_modes(Screen *self) {
|
||||
ScreenModes *m;
|
||||
buffer_push(&self->modes_savepoints, m);
|
||||
*m = self->modes;
|
||||
}
|
||||
|
||||
void
|
||||
screen_restore_cursor(Screen *self) {
|
||||
SavepointBuffer *pts = self->linebuf == self->main_linebuf ? &self->main_savepoints : &self->alt_savepoints;
|
||||
Savepoint *sp = savepoints_pop(pts);
|
||||
Savepoint *sp;
|
||||
buffer_pop(pts, sp);
|
||||
if (sp == NULL) {
|
||||
screen_cursor_position(self, 1, 1);
|
||||
screen_reset_mode(self, DECOM);
|
||||
@ -801,6 +809,15 @@ screen_restore_cursor(Screen *self) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
screen_restore_modes(Screen *self) {
|
||||
ScreenModes *m;
|
||||
buffer_pop(&self->modes_savepoints, m);
|
||||
bool lnm = self->modes.mLNM, irm = self->modes.mIRM, sc81t = self->modes.eight_bit_controls;
|
||||
self->modes = *m;
|
||||
self->modes.mLNM = lnm; self->modes.mIRM = irm; self->modes.eight_bit_controls = sc81t;
|
||||
}
|
||||
|
||||
void
|
||||
screen_ensure_bounds(Screen *self, bool force_use_margins/*=false*/) {
|
||||
unsigned int top, bottom;
|
||||
|
||||
@ -27,6 +27,29 @@ typedef struct {
|
||||
bool in_progress;
|
||||
} Selection;
|
||||
|
||||
#define SAVEPOINTS_SZ 256
|
||||
|
||||
typedef struct {
|
||||
uint32_t utf8_state, utf8_codepoint, *g0_charset, *g1_charset, *g_charset;
|
||||
bool use_latin1;
|
||||
Cursor cursor;
|
||||
bool mDECOM, mDECAWM, mDECSCNM;
|
||||
|
||||
} Savepoint;
|
||||
|
||||
|
||||
typedef struct {
|
||||
Savepoint buf[SAVEPOINTS_SZ];
|
||||
index_type start_of_data, count;
|
||||
} SavepointBuffer;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ScreenModes buf[SAVEPOINTS_SZ];
|
||||
index_type start_of_data, count;
|
||||
} SavemodesBuffer;
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
@ -39,6 +62,7 @@ typedef struct {
|
||||
bool use_latin1, selection_updated_once, is_dirty, scroll_changed, rectangle_select;
|
||||
Cursor *cursor;
|
||||
SavepointBuffer main_savepoints, alt_savepoints;
|
||||
SavemodesBuffer modes_savepoints;
|
||||
PyObject *callbacks, *test_child;
|
||||
LineBuf *linebuf, *main_linebuf, *alt_linebuf;
|
||||
GraphicsManager *grman, *main_grman, *alt_grman;
|
||||
@ -67,6 +91,8 @@ void parse_worker_dump(Screen *screen, PyObject *dump_callback);
|
||||
void screen_align(Screen*);
|
||||
void screen_restore_cursor(Screen *);
|
||||
void screen_save_cursor(Screen *);
|
||||
void screen_restore_modes(Screen *);
|
||||
void screen_save_modes(Screen *);
|
||||
void write_escape_code_to_child(Screen *self, unsigned char which, const char *data);
|
||||
void screen_cursor_position(Screen*, unsigned int, unsigned int);
|
||||
void screen_cursor_back(Screen *self, unsigned int count/*=1*/, int move_direction/*=-1*/);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user