Remove the now useless change tracking code
This commit is contained in:
parent
906937149e
commit
f5dbe36cf3
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 *);
|
||||
|
||||
104
kitty/screen.c
104
kitty/screen.c
@ -9,7 +9,6 @@
|
||||
#include <structmember.h>
|
||||
#include <limits.h>
|
||||
#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}
|
||||
};
|
||||
|
||||
|
||||
265
kitty/tracker.c
265
kitty/tracker.c
@ -1,265 +0,0 @@
|
||||
/*
|
||||
* tracker.c
|
||||
* Copyright (C) 2016 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* tracker.h
|
||||
* Copyright (C) 2016 Kovid Goyal <kovid at kovidgoyal.net>
|
||||
*
|
||||
* 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);
|
||||
Loading…
x
Reference in New Issue
Block a user