diff --git a/kitty/data-types.h b/kitty/data-types.h index 82c9af8e1..63f5680cd 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -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) diff --git a/kitty/parser.c b/kitty/parser.c index 59ee10593..f84beeb4f 100644 --- a/kitty/parser.c +++ b/kitty/parser.c @@ -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 diff --git a/kitty/screen.c b/kitty/screen.c index bdbbdb7e8..88b01a4df 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -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; diff --git a/kitty/screen.h b/kitty/screen.h index a9686e400..7c14e8d60 100644 --- a/kitty/screen.h +++ b/kitty/screen.h @@ -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*/);