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;
|
DynamicColor configured, overridden;
|
||||||
} ColorProfile;
|
} 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 PARSER_BUF_SZ (8 * 1024)
|
||||||
#define READ_BUF_SZ (1024*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
|
static inline void
|
||||||
screen_tabn(Screen *s, unsigned int count) { for (index_type i=0; i < MAX(1, count); i++) screen_tab(s); }
|
screen_tabn(Screen *s, unsigned int count) { for (index_type i=0; i < MAX(1, count); i++) screen_tab(s); }
|
||||||
static inline void
|
static inline void
|
||||||
save_cursor(Screen *s, unsigned int UNUSED param, bool private) {
|
save_cursor_or_modes(Screen *s, unsigned int UNUSED param, bool private) {
|
||||||
if (private) fprintf(stderr, "%s %s", ERROR_PREFIX, "CSI s in private mode not supported");
|
if (private) screen_save_modes(s);
|
||||||
else screen_save_cursor(s);
|
else screen_save_cursor(s);
|
||||||
}
|
}
|
||||||
static inline void
|
static inline void
|
||||||
restore_cursor(Screen *s, unsigned int UNUSED param, bool private) {
|
restore_cursor_or_modes(Screen *s, unsigned int UNUSED param, bool private) {
|
||||||
if (private) fprintf(stderr, "%s %s", ERROR_PREFIX, "CSI u in private mode not supported");
|
if (private) screen_restore_modes(s);
|
||||||
else screen_restore_cursor(s);
|
else screen_restore_cursor(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,9 +690,9 @@ dispatch_csi(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
|
|||||||
case DSR:
|
case DSR:
|
||||||
CALL_CSI_HANDLER1P(report_device_status, 0, '?');
|
CALL_CSI_HANDLER1P(report_device_status, 0, '?');
|
||||||
case SC:
|
case SC:
|
||||||
CALL_CSI_HANDLER1P(save_cursor, 0, '?');
|
CALL_CSI_HANDLER1P(save_cursor_or_modes, 0, '?');
|
||||||
case RC:
|
case RC:
|
||||||
CALL_CSI_HANDLER1P(restore_cursor, 0, '?');
|
CALL_CSI_HANDLER1P(restore_cursor_or_modes, 0, '?');
|
||||||
case 'r':
|
case 'r':
|
||||||
if (!start_modifier && !end_modifier) {
|
if (!start_modifier && !end_modifier) {
|
||||||
// DECSTBM
|
// DECSTBM
|
||||||
|
|||||||
@ -748,19 +748,18 @@ screen_linefeed(Screen *self) {
|
|||||||
screen_ensure_bounds(self, false);
|
screen_ensure_bounds(self, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Savepoint*
|
#define buffer_push(self, ans) { \
|
||||||
savepoints_push(SavepointBuffer *self) {
|
ans = (self)->buf + (((self)->start_of_data + (self)->count) % SAVEPOINTS_SZ); \
|
||||||
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; \
|
||||||
if (self->count == SAVEPOINTS_SZ) self->start_of_data = (self->start_of_data + 1) % SAVEPOINTS_SZ;
|
else (self)->count++; \
|
||||||
else self->count++;
|
|
||||||
return ans;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Savepoint*
|
#define buffer_pop(self, ans) { \
|
||||||
savepoints_pop(SavepointBuffer *self) {
|
if ((self)->count == 0) ans = NULL; \
|
||||||
if (self->count == 0) return NULL;
|
else { \
|
||||||
self->count--;
|
(self)->count--; \
|
||||||
return self->buf + ((self->start_of_data + self->count) % SAVEPOINTS_SZ);
|
ans = (self)->buf + (((self)->start_of_data + (self)->count) % SAVEPOINTS_SZ); \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define COPY_CHARSETS(self, sp) \
|
#define COPY_CHARSETS(self, sp) \
|
||||||
@ -774,7 +773,8 @@ savepoints_pop(SavepointBuffer *self) {
|
|||||||
void
|
void
|
||||||
screen_save_cursor(Screen *self) {
|
screen_save_cursor(Screen *self) {
|
||||||
SavepointBuffer *pts = self->linebuf == self->main_linebuf ? &self->main_savepoints : &self->alt_savepoints;
|
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));
|
cursor_copy_to(self->cursor, &(sp->cursor));
|
||||||
sp->mDECOM = self->modes.mDECOM;
|
sp->mDECOM = self->modes.mDECOM;
|
||||||
sp->mDECAWM = self->modes.mDECAWM;
|
sp->mDECAWM = self->modes.mDECAWM;
|
||||||
@ -782,10 +782,18 @@ screen_save_cursor(Screen *self) {
|
|||||||
COPY_CHARSETS(self, sp);
|
COPY_CHARSETS(self, sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
screen_save_modes(Screen *self) {
|
||||||
|
ScreenModes *m;
|
||||||
|
buffer_push(&self->modes_savepoints, m);
|
||||||
|
*m = self->modes;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_restore_cursor(Screen *self) {
|
screen_restore_cursor(Screen *self) {
|
||||||
SavepointBuffer *pts = self->linebuf == self->main_linebuf ? &self->main_savepoints : &self->alt_savepoints;
|
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) {
|
if (sp == NULL) {
|
||||||
screen_cursor_position(self, 1, 1);
|
screen_cursor_position(self, 1, 1);
|
||||||
screen_reset_mode(self, DECOM);
|
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
|
void
|
||||||
screen_ensure_bounds(Screen *self, bool force_use_margins/*=false*/) {
|
screen_ensure_bounds(Screen *self, bool force_use_margins/*=false*/) {
|
||||||
unsigned int top, bottom;
|
unsigned int top, bottom;
|
||||||
|
|||||||
@ -27,6 +27,29 @@ typedef struct {
|
|||||||
bool in_progress;
|
bool in_progress;
|
||||||
} Selection;
|
} 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 {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
@ -39,6 +62,7 @@ typedef struct {
|
|||||||
bool use_latin1, selection_updated_once, is_dirty, scroll_changed, rectangle_select;
|
bool use_latin1, selection_updated_once, is_dirty, scroll_changed, rectangle_select;
|
||||||
Cursor *cursor;
|
Cursor *cursor;
|
||||||
SavepointBuffer main_savepoints, alt_savepoints;
|
SavepointBuffer main_savepoints, alt_savepoints;
|
||||||
|
SavemodesBuffer modes_savepoints;
|
||||||
PyObject *callbacks, *test_child;
|
PyObject *callbacks, *test_child;
|
||||||
LineBuf *linebuf, *main_linebuf, *alt_linebuf;
|
LineBuf *linebuf, *main_linebuf, *alt_linebuf;
|
||||||
GraphicsManager *grman, *main_grman, *alt_grman;
|
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_align(Screen*);
|
||||||
void screen_restore_cursor(Screen *);
|
void screen_restore_cursor(Screen *);
|
||||||
void screen_save_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 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_position(Screen*, unsigned int, unsigned int);
|
||||||
void screen_cursor_back(Screen *self, unsigned int count/*=1*/, int move_direction/*=-1*/);
|
void screen_cursor_back(Screen *self, unsigned int count/*=1*/, int move_direction/*=-1*/);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user