Implement support for save/restore of DEC private modes (CSI ? s/r)

This commit is contained in:
Kovid Goyal 2018-02-01 09:19:43 +05:30
parent a9be05c885
commit 855b3de473
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 62 additions and 35 deletions

View File

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

View File

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

View File

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

View File

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