From f5dbe36cf314176d2da5828b3cce4b06a6cd8def Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 8 Sep 2017 18:41:04 +0530 Subject: [PATCH] Remove the now useless change tracking code --- kitty/char_grid.py | 2 +- kitty/data-types.c | 1 - kitty/data-types.h | 21 +--- kitty/screen.c | 104 ++++++++---------- kitty/tracker.c | 265 --------------------------------------------- kitty/tracker.h | 55 ---------- 6 files changed, 48 insertions(+), 400 deletions(-) delete mode 100644 kitty/tracker.c delete mode 100644 kitty/tracker.h diff --git a/kitty/char_grid.py b/kitty/char_grid.py index 365273abd..7a6d59774 100644 --- a/kitty/char_grid.py +++ b/kitty/char_grid.py @@ -357,7 +357,7 @@ class CharGrid: def prepare_for_render(self, cell_program): if self.vao_id is None: self.vao_id = cell_program.create_sprite_map() - if self.scroll_changed or self.screen.is_dirty(): + if self.scroll_changed or self.screen.is_dirty: self.update_cell_data(cell_program) self.scroll_changed = False sg = self.render_data diff --git a/kitty/data-types.c b/kitty/data-types.c index 7f934b810..76a09ec32 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -114,7 +114,6 @@ PyInit_fast_data_types(void) { if (!init_Timers(m)) return NULL; if (!init_ChildMonitor(m)) return NULL; if (!init_ColorProfile(m)) return NULL; - if (!init_ChangeTracker(m)) return NULL; if (!init_Screen(m)) return NULL; if (!add_module_gl_constants(m)) return NULL; if (!init_glfw(m)) return NULL; diff --git a/kitty/data-types.h b/kitty/data-types.h index 87a656578..1531a744f 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -195,21 +195,6 @@ typedef struct { } ColorProfile; PyTypeObject ColorProfile_Type; -typedef struct { - PyObject_HEAD - - index_type xnum, ynum; - bool screen_changed; - bool cursor_changed; - bool dirty; - bool *changed_lines; - bool *lines_with_changed_cells; - bool *changed_cells; - unsigned int history_line_added_count; -} ChangeTracker; -PyTypeObject ChangeTracker_Type; - - typedef struct { bool mLNM, mIRM, mDECTCEM, mDECSCNM, mDECOM, mDECAWM, mDECCOLM, mDECARM, mDECCKM, mBRACKETED_PASTE, mFOCUS_TRACKING, mEXTENDED_KEYBOARD; @@ -245,11 +230,11 @@ typedef struct { bool use_latin1; Cursor *cursor; SavepointBuffer main_savepoints, alt_savepoints; - PyObject *callbacks; + PyObject *callbacks, *is_dirty, *cursor_changed; LineBuf *linebuf, *main_linebuf, *alt_linebuf; HistoryBuf *historybuf; + unsigned int history_line_added_count; bool *tabstops, *main_tabstops, *alt_tabstops; - ChangeTracker *change_tracker; ScreenModes modes; ColorProfile *color_profile; @@ -307,7 +292,6 @@ Line* alloc_line(); Cursor* alloc_cursor(); LineBuf* alloc_linebuf(unsigned int, unsigned int); HistoryBuf* alloc_historybuf(unsigned int, unsigned int); -ChangeTracker* alloc_change_tracker(unsigned int, unsigned int); ColorProfile* alloc_color_profile(); int init_LineBuf(PyObject *); int init_HistoryBuf(PyObject *); @@ -316,7 +300,6 @@ int init_Timers(PyObject *); int init_ChildMonitor(PyObject *); int init_Line(PyObject *); int init_ColorProfile(PyObject *); -int init_ChangeTracker(PyObject *); int init_Screen(PyObject *); int init_Face(PyObject *); int init_Window(PyObject *); diff --git a/kitty/screen.c b/kitty/screen.c index ca4b6f3b7..d8b764ed8 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -9,7 +9,6 @@ #include #include #include "unicode-data.h" -#include "tracker.h" #include "modes.h" #include "wcwidth9.h" @@ -59,17 +58,18 @@ new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) { self->columns = columns; self->lines = lines; self->write_buf = NULL; self->modes = empty_modes; + self->cursor_changed = Py_True; self->is_dirty = Py_True; self->margin_top = 0; self->margin_bottom = self->lines - 1; + self->history_line_added_count = 0; RESET_CHARSETS; self->callbacks = callbacks; Py_INCREF(callbacks); self->cursor = alloc_cursor(); self->color_profile = alloc_color_profile(); self->main_linebuf = alloc_linebuf(lines, columns); self->alt_linebuf = alloc_linebuf(lines, columns); self->linebuf = self->main_linebuf; - self->change_tracker = alloc_change_tracker(lines, columns); self->historybuf = alloc_historybuf(MAX(scrollback, lines), columns); self->main_tabstops = PyMem_Calloc(2 * self->columns, sizeof(bool)); - if (self->cursor == NULL || self->main_linebuf == NULL || self->alt_linebuf == NULL || self->change_tracker == NULL || self->main_tabstops == NULL || self->historybuf == NULL || self->color_profile == NULL) { + if (self->cursor == NULL || self->main_linebuf == NULL || self->alt_linebuf == NULL || self->main_tabstops == NULL || self->historybuf == NULL || self->color_profile == NULL) { Py_CLEAR(self); return NULL; } self->alt_tabstops = self->main_tabstops + self->columns * sizeof(bool); @@ -94,12 +94,12 @@ screen_reset(Screen *self) { init_tabstops(self->main_tabstops, self->columns); init_tabstops(self->alt_tabstops, self->columns); cursor_reset(self->cursor); - tracker_cursor_changed(self->change_tracker); + self->cursor_changed = Py_True; + self->is_dirty = Py_True; screen_cursor_position(self, 1, 1); set_dynamic_color(self, 110, NULL); set_dynamic_color(self, 111, NULL); set_color_table_color(self, 104, NULL); - tracker_update_screen(self->change_tracker); } static inline HistoryBuf* @@ -150,7 +150,6 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) { self->linebuf = is_main ? self->main_linebuf : self->alt_linebuf; if (is_x_shrink && cursor_x >= columns) self->cursor->x = columns - 1; - if (!tracker_resize(self->change_tracker, lines, columns)) return false; self->lines = lines; self->columns = columns; self->margin_top = 0; self->margin_bottom = self->lines - 1; @@ -161,8 +160,7 @@ screen_resize(Screen *self, unsigned int lines, unsigned int columns) { self->tabstops = self->main_tabstops; init_tabstops(self->main_tabstops, self->columns); init_tabstops(self->alt_tabstops, self->columns); - tracker_update_screen(self->change_tracker); - tracker_cursor_changed(self->change_tracker); + self->cursor_changed = Py_True; self->is_dirty = Py_True; if (index_after_resize) screen_index(self); return true; @@ -200,7 +198,6 @@ dealloc(Screen* self) { Py_CLEAR(self->cursor); Py_CLEAR(self->main_linebuf); Py_CLEAR(self->alt_linebuf); - Py_CLEAR(self->change_tracker); Py_CLEAR(self->historybuf); Py_CLEAR(self->color_profile); PyMem_Free(self->main_tabstops); @@ -268,7 +265,6 @@ screen_draw(Screen *self, uint32_t och) { } } if (char_width > 0) { - unsigned int cx = self->cursor->x; linebuf_init_line(self->linebuf, self->cursor->y); if (self->modes.mIRM) { line_right_shift(self->linebuf->line, self->cursor->x, char_width); @@ -279,20 +275,19 @@ screen_draw(Screen *self, uint32_t och) { line_set_char(self->linebuf->line, self->cursor->x, 0, 0, self->cursor); self->cursor->x++; } - unsigned int right = self->modes.mIRM ? self->columns - 1 : MIN((MAX(self->cursor->x, 1) - 1), self->columns - 1); - tracker_update_cell_range(self->change_tracker, self->cursor->y, cx, right); + self->is_dirty = Py_True; } else if (is_combining_char(ch)) { if (self->cursor->x > 0) { linebuf_init_line(self->linebuf, self->cursor->y); line_add_combining_char(self->linebuf->line, ch, self->cursor->x - 1); - tracker_update_cell_range(self->change_tracker, self->cursor->y, self->cursor->x - 1, self->cursor->x - 1); + self->is_dirty = Py_True; } else if (self->cursor->y > 0) { linebuf_init_line(self->linebuf, self->cursor->y - 1); line_add_combining_char(self->linebuf->line, ch, self->columns - 1); - tracker_update_cell_range(self->change_tracker, self->cursor->y - 1, self->columns - 1, self->columns - 1); + self->is_dirty = Py_True; } } - if (x != self->cursor->x || y != self->cursor->y) tracker_cursor_changed(self->change_tracker); + if (x != self->cursor->x || y != self->cursor->y) self->cursor_changed = Py_True; } void @@ -414,7 +409,7 @@ screen_toggle_screen_buffer(Screen *self) { screen_restore_cursor(self); } CALLBACK("buf_toggled", "O", self->linebuf == self->main_linebuf ? Py_True : Py_False); - tracker_update_screen(self->change_tracker); + self->is_dirty = Py_True; } void screen_normal_keypad_mode(Screen UNUSED *self) {} // Not implemented as this is handled by the GUI @@ -453,13 +448,13 @@ set_mode_from_const(Screen *self, unsigned int mode, bool val) { break; case DECTCEM: self->modes.mDECTCEM = val; - tracker_cursor_changed(self->change_tracker); + self->cursor_changed = Py_True; break; case DECSCNM: // Render screen in reverse video if (self->modes.mDECSCNM != val) { self->modes.mDECSCNM = val; - tracker_update_screen(self->change_tracker); + self->is_dirty = Py_True; } break; case DECOM: @@ -479,7 +474,7 @@ set_mode_from_const(Screen *self, unsigned int mode, bool val) { break; case CONTROL_CURSOR_BLINK: self->cursor->blink = val; - tracker_cursor_changed(self->change_tracker); + self->cursor_changed = Py_True; break; case ALTERNATE_SCREEN: if (val && self->linebuf == self->main_linebuf) screen_toggle_screen_buffer(self); @@ -521,7 +516,7 @@ screen_tab(Screen *self) { if (!found) found = self->columns - 1; if (found != self->cursor->x) { self->cursor->x = found; - tracker_cursor_changed(self->change_tracker); + self->cursor_changed = Py_True; } } @@ -538,7 +533,7 @@ screen_backtab(Screen *self, unsigned int count) { } if (i <= 0) self->cursor->x = 0; } - if (before != self->cursor->x) tracker_cursor_changed(self->change_tracker); + if (before != self->cursor->x) self->cursor_changed = Py_True; } void @@ -571,7 +566,7 @@ screen_cursor_back(Screen *self, unsigned int count/*=1*/, int move_direction/*= if (move_direction < 0 && count > self->cursor->x) self->cursor->x = 0; else self->cursor->x += move_direction * count; screen_ensure_bounds(self, false); - if (x != self->cursor->x) tracker_cursor_changed(self->change_tracker); + if (x != self->cursor->x) self->cursor_changed = Py_True; } void @@ -587,7 +582,7 @@ screen_cursor_up(Screen *self, unsigned int count/*=1*/, bool do_carriage_return else self->cursor->y += move_direction * count; screen_ensure_bounds(self, true); if (do_carriage_return) self->cursor->x = 0; - if (x != self->cursor->x || y != self->cursor->y) tracker_cursor_changed(self->change_tracker); + if (x != self->cursor->x || y != self->cursor->y) self->cursor_changed = Py_True; } void @@ -611,7 +606,7 @@ screen_cursor_to_column(Screen *self, unsigned int column) { if (x != self->cursor->x) { self->cursor->x = x; screen_ensure_bounds(self, false); - tracker_cursor_changed(self->change_tracker); + self->cursor_changed = Py_True; } } @@ -621,11 +616,10 @@ screen_cursor_to_column(Screen *self, unsigned int column) { /* Only add to history when no page margins have been set */ \ linebuf_init_line(self->linebuf, bottom); \ historybuf_add_line(self->historybuf, self->linebuf->line); \ - tracker_line_added_to_history(self->change_tracker); \ + self->history_line_added_count++; \ } \ linebuf_clear_line(self->linebuf, bottom); \ - if (bottom - top > self->lines - 1) tracker_update_screen(self->change_tracker); \ - else tracker_update_line_range(self->change_tracker, top, bottom); + self->is_dirty = Py_True; void screen_index(Screen *self) { @@ -650,8 +644,7 @@ screen_scroll(Screen *self, unsigned int count) { #define INDEX_DOWN \ linebuf_reverse_index(self->linebuf, top, bottom); \ linebuf_clear_line(self->linebuf, top); \ - if (bottom - top > self->lines - 1) tracker_update_screen(self->change_tracker); \ - else tracker_update_line_range(self->change_tracker, top, bottom); + self->is_dirty = Py_True; void screen_reverse_index(Screen *self) { @@ -678,7 +671,7 @@ void screen_carriage_return(Screen *self) { if (self->cursor->x != 0) { self->cursor->x = 0; - tracker_cursor_changed(self->change_tracker); + self->cursor_changed = Py_True; } } @@ -729,7 +722,7 @@ screen_restore_cursor(Screen *self) { Savepoint *sp = savepoints_pop(pts); if (sp == NULL) { screen_cursor_position(self, 1, 1); - tracker_cursor_changed(self->change_tracker); + self->cursor_changed = Py_True; screen_reset_mode(self, DECOM); RESET_CHARSETS; screen_reset_mode(self, DECSCNM); @@ -766,7 +759,7 @@ screen_cursor_position(Screen *self, unsigned int line, unsigned int column) { unsigned int x = self->cursor->x, y = self->cursor->y; self->cursor->x = column; self->cursor->y = line; screen_ensure_bounds(self, false); - if (x != self->cursor->x || y != self->cursor->y) tracker_cursor_changed(self->change_tracker); + if (x != self->cursor->x || y != self->cursor->y) self->cursor_changed = Py_True; } void @@ -813,7 +806,7 @@ void screen_erase_in_line(Screen *self, unsigned int how, bool private) { } else { line_apply_cursor(self->linebuf->line, self->cursor, s, n, true); } - tracker_update_cell_range(self->change_tracker, self->cursor->y, s, MIN(s+n, self->columns) - 1); + self->is_dirty = Py_True; } } @@ -850,7 +843,7 @@ void screen_erase_in_display(Screen *self, unsigned int how, bool private) { line_apply_cursor(self->linebuf->line, self->cursor, 0, self->columns, true); } } - tracker_update_line_range(self->change_tracker, a, b-1); + self->is_dirty = Py_True; } if (how != 2) { screen_erase_in_line(self, how, private); @@ -862,7 +855,7 @@ void screen_insert_lines(Screen *self, unsigned int count) { if (count == 0) count = 1; if (top <= self->cursor->y && self->cursor->y <= bottom) { linebuf_insert_lines(self->linebuf, count, self->cursor->y, bottom); - tracker_update_line_range(self->change_tracker, self->cursor->y, bottom); + self->is_dirty = Py_True; screen_carriage_return(self); } } @@ -872,7 +865,7 @@ void screen_delete_lines(Screen *self, unsigned int count) { if (count == 0) count = 1; if (top <= self->cursor->y && self->cursor->y <= bottom) { linebuf_delete_lines(self->linebuf, count, self->cursor->y, bottom); - tracker_update_line_range(self->change_tracker, self->cursor->y, bottom); + self->is_dirty = Py_True; screen_carriage_return(self); } } @@ -886,7 +879,7 @@ void screen_insert_characters(Screen *self, unsigned int count) { linebuf_init_line(self->linebuf, self->cursor->y); line_right_shift(self->linebuf->line, x, num); line_apply_cursor(self->linebuf->line, self->cursor, x, num, true); - tracker_update_cell_range(self->change_tracker, self->cursor->y, x, self->columns - 1); + self->is_dirty = Py_True; } } @@ -900,7 +893,7 @@ void screen_delete_characters(Screen *self, unsigned int count) { linebuf_init_line(self->linebuf, self->cursor->y); left_shift_line(self->linebuf->line, x, num); line_apply_cursor(self->linebuf->line, self->cursor, self->columns - num, num, true); - tracker_update_cell_range(self->change_tracker, self->cursor->y, x, self->columns - 1); + self->is_dirty = Py_True; } } @@ -911,7 +904,7 @@ void screen_erase_characters(Screen *self, unsigned int count) { unsigned int num = MIN(self->columns - x, count); linebuf_init_line(self->linebuf, self->cursor->y); line_apply_cursor(self->linebuf->line, self->cursor, x, num, true); - tracker_update_cell_range(self->change_tracker, self->cursor->y, x, MIN(x + num, self->columns) - 1); + self->is_dirty = Py_True; } // }}} @@ -1034,7 +1027,7 @@ screen_set_cursor(Screen *self, unsigned int mode, uint8_t secondary) { } if (shape != self->cursor->shape || blink != self->cursor->blink) { self->cursor->shape = shape; self->cursor->blink = blink; - tracker_cursor_changed(self->change_tracker); + self->cursor_changed = Py_True; } break; } @@ -1124,15 +1117,12 @@ set_mode(Screen *self, PyObject *args) { static PyObject* reset_dirty(Screen *self) { - tracker_reset(self->change_tracker); + self->is_dirty = Py_False; + self->cursor_changed = Py_False; + self->history_line_added_count = 0; Py_RETURN_NONE; } -static PyObject* -consolidate_changes(Screen *self) { - return tracker_consolidate_changes(self->change_tracker); -} - WRAP1E(cursor_back, 1, -1) WRAP1B(erase_in_line, 0) WRAP1B(erase_in_display, 0) @@ -1194,12 +1184,12 @@ screen_update_cell_data(Screen *self, PyObject *args) { unsigned int *data; int force_screen_refresh; unsigned int scrolled_by; - unsigned int history_line_added_count = self->change_tracker->history_line_added_count; + unsigned int history_line_added_count = self->history_line_added_count; if (!PyArg_ParseTuple(args, "O!Ip", &PyLong_Type, &dp, &scrolled_by, &force_screen_refresh)) return NULL; data = PyLong_AsVoidPtr(dp); - PyObject *cursor_changed = self->change_tracker->cursor_changed ? Py_True : Py_False; + PyObject *cursor_changed = self->cursor_changed; if (scrolled_by) scrolled_by = MIN(scrolled_by + history_line_added_count, self->historybuf->count); - tracker_reset(self->change_tracker); + reset_dirty(self); for (index_type y = 0; y < MIN(self->lines, scrolled_by); y++) { historybuf_init_line(self->historybuf, scrolled_by - 1 - y, self->historybuf->line); self->historybuf->line->ynum = y; @@ -1227,14 +1217,9 @@ apply_selection(Screen *self, PyObject *args) { Py_RETURN_NONE; } -static PyObject* is_dirty(Screen *self) { - PyObject *ans = self->change_tracker->dirty ? Py_True : Py_False; - Py_INCREF(ans); - return ans; -} - -static PyObject* mark_as_dirty(Screen *self) { - tracker_update_screen(self->change_tracker); +static +PyObject* mark_as_dirty(Screen *self) { + self->is_dirty = Py_True; Py_RETURN_NONE; } @@ -1286,7 +1271,6 @@ static PyMethodDef methods[] = { MND(reset, METH_NOARGS) MND(reset_dirty, METH_NOARGS) MND(is_main_linebuf, METH_NOARGS) - MND(consolidate_changes, METH_NOARGS) MND(cursor_back, METH_VARARGS) MND(erase_in_line, METH_VARARGS) MND(erase_in_display, METH_VARARGS) @@ -1313,7 +1297,6 @@ static PyMethodDef methods[] = { MND(clear_tab_stop, METH_VARARGS) MND(reverse_index, METH_NOARGS) MND(refresh_sprite_positions, METH_NOARGS) - MND(is_dirty, METH_NOARGS) MND(mark_as_dirty, METH_NOARGS) MND(resize, METH_VARARGS) MND(set_margins, METH_VARARGS) @@ -1346,6 +1329,8 @@ static PyGetSetDef getsetters[] = { static PyMemberDef members[] = { {"callbacks", T_OBJECT_EX, offsetof(Screen, callbacks), 0, "callbacks"}, + {"cursor_changed", T_OBJECT_EX, offsetof(Screen, cursor_changed), 0, "cursor_changed"}, + {"is_dirty", T_OBJECT_EX, offsetof(Screen, is_dirty), 0, "is_dirty"}, {"cursor", T_OBJECT_EX, offsetof(Screen, cursor), READONLY, "cursor"}, {"color_profile", T_OBJECT_EX, offsetof(Screen, color_profile), READONLY, "color_profile"}, {"linebuf", T_OBJECT_EX, offsetof(Screen, linebuf), READONLY, "linebuf"}, @@ -1354,6 +1339,7 @@ static PyMemberDef members[] = { {"columns", T_UINT, offsetof(Screen, columns), READONLY, "columns"}, {"margin_top", T_UINT, offsetof(Screen, margin_top), READONLY, "margin_top"}, {"margin_bottom", T_UINT, offsetof(Screen, margin_bottom), READONLY, "margin_bottom"}, + {"history_line_added_count", T_UINT, offsetof(Screen, history_line_added_count), 0, "history_line_added_count"}, {NULL} }; diff --git a/kitty/tracker.c b/kitty/tracker.c deleted file mode 100644 index b75db9c02..000000000 --- a/kitty/tracker.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * tracker.c - * Copyright (C) 2016 Kovid Goyal - * - * Distributed under terms of the GPL3 license. - */ - -#include "data-types.h" -#include "tracker.h" - - -bool tracker_resize(ChangeTracker *self, unsigned int ynum, unsigned int xnum) { -#define ALLOC_VAR(name, sz) \ - bool *name = PyMem_Calloc(sz, sizeof(bool)); \ - if (name == NULL) { PyErr_NoMemory(); return false; } \ - PyMem_Free(self->name); self->name = name; - - self->ynum = ynum; self->xnum = xnum; - ALLOC_VAR(changed_lines, self->ynum); - ALLOC_VAR(changed_cells, self->xnum * self->ynum); - ALLOC_VAR(lines_with_changed_cells, self->ynum); - RESET_STATE_VARS(self); - return true; -} - -static PyObject* -resize(ChangeTracker *self, PyObject *args) { -#define resize_doc "Resize this change tracker must be called when the screen it is tracking for is resized" - unsigned int ynum=1, xnum=1; - if (!PyArg_ParseTuple(args, "|II", &ynum, &xnum)) return NULL; - if (!tracker_resize(self, ynum, xnum)) return NULL; - Py_RETURN_NONE; -} - -static PyObject* -new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) { - ChangeTracker *self; - self = (ChangeTracker *)type->tp_alloc(type, 0); - if (self != NULL) { - PyObject *ret = resize(self, args); - if (ret == NULL) { Py_CLEAR(self); return NULL; } - Py_CLEAR(ret); - } - return (PyObject*) self; -} - -static void -dealloc(ChangeTracker* self) { - PyMem_Free(self->changed_lines); PyMem_Free(self->changed_cells); PyMem_Free(self->lines_with_changed_cells); - Py_TYPE(self)->tp_free((PyObject*)self); -} - -static PyObject* -reset(ChangeTracker *self) { -#define reset_doc "Reset all changes" - tracker_reset(self); - - Py_RETURN_NONE; -} - -static PyObject* -cursor_changed(ChangeTracker *self) { -#define cursor_changed_doc "" - tracker_cursor_changed(self); - Py_RETURN_NONE; -} - -static PyObject* -line_added_to_history(ChangeTracker *self) { -#define line_added_to_history_doc "" - tracker_line_added_to_history(self); - Py_RETURN_NONE; -} - -static PyObject* -update_screen(ChangeTracker *self) { -#define update_screen_doc "" - tracker_update_screen(self); - Py_RETURN_NONE; -} - -static PyObject* -update_line_range(ChangeTracker *self, PyObject *args) { -#define update_line_range_doc "" - unsigned int f, l; - if (!PyArg_ParseTuple(args, "II", &f, &l)) return NULL; - tracker_update_line_range(self, f, l); - Py_RETURN_NONE; -} - -static PyObject* -update_cell_range(ChangeTracker *self, PyObject *args) { -#define update_cell_range_doc "" - unsigned int line, f, l; - if (!PyArg_ParseTuple(args, "III", &line, &f, &l)) return NULL; - tracker_update_cell_range(self, line, f, l); - Py_RETURN_NONE; -} - -bool tracker_update_cell_data(ScreenModes *modes, ChangeTracker *self, LineBuf *lb, unsigned int *data, bool force_screen_refresh) { - unsigned int y; - Py_ssize_t start; - -#define UPDATE_RANGE(xstart, xmax) \ - linebuf_init_line(lb, y); \ - if (!update_cell_range_data(modes, lb->line, (xstart), (xmax), data)) return false; - - if (self->screen_changed || force_screen_refresh) { - for (y = 0; y < self->ynum; y++) { - UPDATE_RANGE(0, self->xnum - 1); - } - } else { - for (y = 0; y < self->ynum; y++) { - if (self->changed_lines[y]) { - UPDATE_RANGE(0, self->xnum - 1); - } else if (self->lines_with_changed_cells[y]) { - start = -1; - bool *line = self->changed_cells + y * self->xnum; - for (unsigned int i = 0; i < self->xnum; i++) { - if (line[i]) { - if (start == -1) { - start = i; - } - } else { - if (start != -1) { - UPDATE_RANGE(start, i - 1); - start = -1; - } - } - } - if (start != -1) { - UPDATE_RANGE(start, self->xnum - 1); - } - } - } - } - tracker_reset(self); - return true; -} - -static inline PyObject* -get_ranges(bool *line, unsigned int xnum) { - PyObject *ans = PyList_New(0), *t; - Py_ssize_t start = -1; - if (ans == NULL) return PyErr_NoMemory(); - -#define APPEND_RANGE(x) \ - t = Py_BuildValue("nI", start, x); \ - if (t == NULL) { Py_CLEAR(ans); return NULL; } \ - if (PyList_Append(ans, t) != 0) { Py_CLEAR(ans); Py_CLEAR(t); return NULL; } \ - Py_CLEAR(t); - - for (unsigned int i = 0; i < xnum; i++) { - if (line[i]) { - if (start == -1) { - start = i; - } - } else { - if (start != -1) { - APPEND_RANGE(i - 1); - start = -1; - } - } - } - if (start != -1) { - APPEND_RANGE(xnum - 1); - } - - return ans; -} - -PyObject* -tracker_consolidate_changes(ChangeTracker *self) { - PyObject *ans = PyDict_New(); - if (ans == NULL) return PyErr_NoMemory(); - if (PyDict_SetItemString(ans, "screen", self->screen_changed ? Py_True : Py_False) != 0) { Py_CLEAR(ans); return NULL; } - if (PyDict_SetItemString(ans, "cursor", self->cursor_changed ? Py_True : Py_False) != 0) { Py_CLEAR(ans); return NULL; } - PyObject *t = PyLong_FromUnsignedLong((unsigned long)self->history_line_added_count); - if (t == NULL) { Py_CLEAR(ans); return NULL; } - if (PyDict_SetItemString(ans, "history_line_added_count", t) != 0) { Py_CLEAR(t); Py_CLEAR(ans); return NULL; } - Py_CLEAR(t); - - // Changed lines - Py_ssize_t num = 0; - if (!self->screen_changed) { - for (unsigned int i = 0; i < self->ynum; i++) { num += self->changed_lines[i]; } - } - t = PyTuple_New(num); - if (t == NULL) { Py_CLEAR(ans); return NULL; } - if (num > 0) { - for (unsigned int i = 0, j=0; i < self->ynum; i++) { - if (self->changed_lines[i]) { - PyObject *n = PyLong_FromUnsignedLong(i); - if (n == NULL) { Py_CLEAR(t); Py_CLEAR(ans); return NULL; } - PyTuple_SET_ITEM(t, j++, n); - } - } - } - if (PyDict_SetItemString(ans, "lines", t) != 0) { Py_CLEAR(t); Py_CLEAR(ans); return NULL; } - Py_CLEAR(t); - - // Changed cells - t = PyDict_New(); - if (t == NULL) { Py_CLEAR(ans); return PyErr_NoMemory(); } - if (!self->screen_changed) { - for (unsigned int i = 0; i < self->ynum; i++) { - if (self->lines_with_changed_cells[i] && !self->changed_lines[i]) { - PyObject *ranges = get_ranges(self->changed_cells + i * self->xnum, self->xnum); - if (ranges == NULL) { Py_CLEAR(t); Py_CLEAR(ans); return NULL; } - PyObject *key = PyLong_FromUnsignedLong(i); - if (key == NULL) { Py_CLEAR(t); Py_CLEAR(ans); Py_CLEAR(ranges); return NULL; } - if (PyDict_SetItem(t, key, ranges) != 0) { Py_CLEAR(key); Py_CLEAR(t); Py_CLEAR(ans); Py_CLEAR(ranges); return NULL; } - Py_CLEAR(key); Py_CLEAR(ranges); - } - } - } - - if (PyDict_SetItemString(ans, "cells", t) != 0) { Py_CLEAR(t); Py_CLEAR(ans); return NULL; } - Py_CLEAR(t); - - tracker_reset(self); - return ans; -} - -// Boilerplate {{{ - -BOOL_GETSET(ChangeTracker, dirty) -static PyGetSetDef getseters[] = { - GETSET(dirty) - {NULL} /* Sentinel */ -}; - -static PyMethodDef methods[] = { - METHOD(resize, METH_VARARGS) - METHOD(reset, METH_NOARGS) - METHOD(cursor_changed, METH_NOARGS) - {"consolidate_changes", (PyCFunction)tracker_consolidate_changes, METH_NOARGS, ""}, - METHOD(line_added_to_history, METH_NOARGS) - METHOD(update_screen, METH_NOARGS) - METHOD(update_line_range, METH_VARARGS) - METHOD(update_cell_range, METH_VARARGS) - {NULL} /* Sentinel */ -}; - - -PyTypeObject ChangeTracker_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "fast_data_types.ChangeTracker", - .tp_basicsize = sizeof(ChangeTracker), - .tp_dealloc = (destructor)dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_doc = "ChangeTracker", - .tp_methods = methods, - .tp_getset = getseters, - .tp_new = new, -}; - -INIT_TYPE(ChangeTracker) -// }}} - -ChangeTracker* alloc_change_tracker(unsigned int ynum, unsigned int xnum) { - ChangeTracker *self = (ChangeTracker *)(&ChangeTracker_Type)->tp_alloc((&ChangeTracker_Type), 0); - if (!tracker_resize(self, ynum, xnum)) { Py_CLEAR(self); return NULL; } - return self; -} diff --git a/kitty/tracker.h b/kitty/tracker.h deleted file mode 100644 index 7d2780389..000000000 --- a/kitty/tracker.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * tracker.h - * Copyright (C) 2016 Kovid Goyal - * - * Distributed under terms of the GPL3 license. - */ - -#pragma once - -static inline void tracker_cursor_changed(ChangeTracker *self) { - self->cursor_changed = true; - self->dirty = true; -} - -static inline void tracker_line_added_to_history(ChangeTracker *self) { - self->history_line_added_count++; - self->dirty = true; -} - -static inline void tracker_update_screen(ChangeTracker *self) { - self->screen_changed = true; - self->dirty = true; -} - -static inline void tracker_update_line_range(ChangeTracker *self, unsigned int first_line, unsigned int last_line) { - if (!self->screen_changed) { - for (unsigned int i = first_line; i <= MIN(self->ynum - 1, last_line); i++) self->changed_lines[i] = true; - self->dirty = true; - } -} - -static inline void tracker_update_cell_range(ChangeTracker *self, unsigned int line, unsigned int first_cell, unsigned int last_cell) { - if (!self->screen_changed && line < self->ynum && !self->changed_lines[line]) { - self->lines_with_changed_cells[line] = true; - unsigned int base = line * self->xnum; - for (unsigned int i = first_cell; i <= MIN(self->xnum - 1, last_cell); i++) self->changed_cells[base + i] = true; - self->dirty = true; - } -} - -#define RESET_STATE_VARS(self) \ - self->screen_changed = false; self->cursor_changed = false; self->dirty = false; self->history_line_added_count = 0; - -static inline void tracker_reset(ChangeTracker *self) { - self->screen_changed = false; self->cursor_changed = false; self->dirty = false; - self->history_line_added_count = 0; - memset(self->changed_lines, 0, self->ynum * sizeof(bool)); - memset(self->changed_cells, 0, self->ynum * self->xnum * sizeof(bool)); - memset(self->lines_with_changed_cells, 0, self->ynum * sizeof(bool)); - RESET_STATE_VARS(self); -} - -PyObject* tracker_consolidate_changes(ChangeTracker *self); -bool tracker_resize(ChangeTracker *self, unsigned int ynum, unsigned int xnum); -bool tracker_update_cell_data(ScreenModes*, ChangeTracker *, LineBuf *, unsigned int *, bool);