diff --git a/kitty/boss.py b/kitty/boss.py index 5cfb3ee5d..c2cb81526 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -15,12 +15,12 @@ from queue import Queue, Empty import glfw from pyte.streams import Stream, DebugStream -from pyte import modes as mo from .char_grid import CharGrid from .keys import interpret_text_event, interpret_key_event from .screen import Screen from .utils import resize_pty, create_pty +from .fast_data_types import BRACKETED_PASTE_START, BRACKETED_PASTE_END def handle_unix_signals(): @@ -52,7 +52,7 @@ class Boss(Thread): self.queue_action(self.initialize) self.profile = args.profile self.window, self.opts = window, opts - self.screen = Screen(self.opts, self) + self.screen = Screen(self.opts.scrollback_lines, self) self.char_grid = CharGrid(self.screen, opts, window_width, window_height) sclass = DebugStream if args.dump_commands else Stream self.stream = sclass(self.screen) @@ -111,7 +111,7 @@ class Boss(Thread): text = subprocess.check_output(['xsel']) if text: if self.screen.in_bracketed_paste_mode: - text = mo.BRACKETED_PASTE_START + text + mo.BRACKETED_PASTE_END + text = BRACKETED_PASTE_START.encode('ascii') + text + BRACKETED_PASTE_END.encode('ascii') self.write_to_child(text) def on_key(self, window, key, scancode, action, mods): @@ -139,7 +139,6 @@ class Boss(Thread): self.queue_action(self.apply_opts_to_screen) def apply_opts_to_screen(self): - self.screen.apply_opts(self.opts) self.char_grid.apply_opts(self.opts) self.char_grid.dirty_everything() diff --git a/kitty/char_grid.py b/kitty/char_grid.py index 671d16340..56a511b91 100644 --- a/kitty/char_grid.py +++ b/kitty/char_grid.py @@ -181,6 +181,7 @@ class CharGrid: def apply_opts(self, opts): self.dpix, self.dpiy = get_logical_dpi() self.opts = opts + self.screen.change_scrollback_size(opts.scrollback_lines) self.color_profile.update_ansi_color_table(build_ansi_color_table(opts)) self.default_cursor = Cursor(0, 0, False, opts.cursor_shape, opts.cursor, opts.cursor_blink) self.opts = opts diff --git a/kitty/charsets.c b/kitty/charsets.c new file mode 100644 index 000000000..e7846513e --- /dev/null +++ b/kitty/charsets.c @@ -0,0 +1,168 @@ +/* + * consolemap.c + * Copyright (C) 2016 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ + +#include "data-types.h" + +// Taken from consolemap.c in the linux vt driver sourcecode + +static uint16_t charset_translations[4][256] = { + /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */ + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff + }, + /* VT100 graphics mapped to Unicode */ + { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f, + 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0, + 0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1, + 0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba, + 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c, + 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff + }, + /* IBM Codepage 437 mapped to Unicode */ + { + 0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, + 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c, + 0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8, + 0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 + }, + // VAX 42 map + { + 0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, + 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c, + 0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8, + 0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc, + 0x0020, 0x043b, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x0435, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0441, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0435, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x043a, + 0x0070, 0x0071, 0x0442, 0x0073, 0x043b, 0x0435, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 + } + +}; + +uint16_t* translation_table(char which) { + switch(which){ + case 'B': + return charset_translations[0]; + case '0': + return charset_translations[1]; + case 'U': + return charset_translations[2]; + case 'V': + return charset_translations[3]; + } + return charset_translations[0]; +} diff --git a/kitty/data-types.c b/kitty/data-types.c index 6f8dac951..b7d1ad06c 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -12,10 +12,12 @@ extern int init_Line(PyObject *); extern int init_ColorProfile(PyObject *); extern int init_SpriteMap(PyObject *); extern int init_ChangeTracker(PyObject *); +extern int init_Screen(PyObject *); extern PyObject* create_256_color_table(); extern PyObject* parse_bytes_dump(PyObject UNUSED *self, PyObject *val); extern PyObject* parse_bytes(PyObject UNUSED *self, PyObject *val); #include "gl.h" +#include "modes.h" static PyMethodDef module_methods[] = { GL_METHODS @@ -47,12 +49,15 @@ PyInit_fast_data_types(void) { if (!init_ColorProfile(m)) return NULL; if (!init_SpriteMap(m)) return NULL; if (!init_ChangeTracker(m)) return NULL; + if (!init_Screen(m)) return NULL; if (!add_module_gl_constants(m)) return NULL; PyModule_AddIntConstant(m, "BOLD", BOLD_SHIFT); PyModule_AddIntConstant(m, "ITALIC", ITALIC_SHIFT); PyModule_AddIntConstant(m, "REVERSE", REVERSE_SHIFT); PyModule_AddIntConstant(m, "STRIKETHROUGH", STRIKE_SHIFT); PyModule_AddIntConstant(m, "DECORATION", DECORATION_SHIFT); + PyModule_AddStringMacro(m, BRACKETED_PASTE_START); + PyModule_AddStringMacro(m, BRACKETED_PASTE_END); } return m; diff --git a/kitty/data-types.h b/kitty/data-types.h index cf90672c1..ecf7786cc 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -191,8 +191,30 @@ typedef struct { unsigned int history_line_added_count; } ChangeTracker; + +typedef struct { + bool LNM, IRM, DECTEM, DECSCNM, DECOM, DECAWM, DECCOLM; +} ScreenModes; + + +typedef struct { + PyObject_HEAD + + unsigned int columns, lines, margin_top, margin_bottom; + unsigned int current_charset; + uint32_t utf8_state; + uint16_t *g0_charset, *g1_charset; + Cursor *cursor; + PyObject *savepoints, *main_savepoints, *alt_savepoints, *callbacks; + LineBuf *linebuf, *main_linebuf, *alt_linebuf; + ChangeTracker *change_tracker; + ScreenModes modes; +} Screen; + Line* alloc_line(); Cursor* alloc_cursor(); +LineBuf* alloc_linebuf(); +ChangeTracker* alloc_change_tracker(); #define left_shift_line(line, at, num) \ for(index_type __i__ = (at); __i__ < (line)->xnum - (num); __i__++) { \ diff --git a/kitty/line-buf.c b/kitty/line-buf.c index 48b049bcb..b351c2185 100644 --- a/kitty/line-buf.c +++ b/kitty/line-buf.c @@ -480,3 +480,7 @@ rewrap(LineBuf *self, PyObject *val) { end: return Py_BuildValue("Ni", ret, cursor_y); } + +LineBuf *alloc_linebuf() { + return (LineBuf*)new(&LineBuf_Type, NULL, NULL); +} diff --git a/kitty/modes.h b/kitty/modes.h new file mode 100644 index 000000000..4b2b04530 --- /dev/null +++ b/kitty/modes.h @@ -0,0 +1,62 @@ +/* + * modes.h + * Copyright (C) 2016 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ + +#pragma once + +/* *Line Feed/New Line Mode*: When enabled, causes a received + LF, FF, or VT to move the cursor to the first column of + the next line. +*/ +#define LNM 20 + +/* *Insert/Replace Mode*: When enabled, new display characters move + old display characters to the right. Characters moved past the + right margin are lost. Otherwise, new display characters replace + old display characters at the cursor position. +*/ +#define IRM + + +// Private modes. + +// *Text Cursor Enable Mode*: determines if the text cursor is visible. +#define DECTCEM (25 << 5) + +// *Screen Mode*: toggles screen-wide reverse-video mode. +#define DECSCNM (5 << 5) + +/* *Origin Mode*: allows cursor addressing relative to a user-defined + origin. This mode resets when the terminal is powered up or reset. + It does not affect the erase in display (ED) function. +*/ +#define DECOM (6 << 5) + +// *Auto Wrap Mode*: selects where received graphic characters appear +// when the cursor is at the right margin. +#define DECAWM (7 << 5) + +// *Column Mode*: selects the number of columns per line (80 or 132) +// on the screen. +#define DECCOLM (3 << 5) + +// Bracketed paste mode +// http://cirw.in/blog/bracketed-paste +#define BRACKETED_PASTE (2004 << 5) +#define BRACKETED_PASTE_START "\033[200~" +#define BRACKETED_PASTE_END "\033[201~" + +// Alternate screen buffer +#define ALTERNATE_SCREEN (1049 << 5) + +// Xterm mouse protocol +#define SEND_MOUSE_ON_PRESS_AND_RELEASE (1000 << 5) +#define HILITE_MOUSE_TRACKING (1001 << 5) +#define CELL_MOTION_MOUSE_TRACKING (1002 << 5) +#define FOCUS_TRACKING (1004 << 5) +#define UTF8_MOUSE_MODE (1005 << 5) +#define SGR_MOUSE_MODE (1006 << 6) + diff --git a/kitty/parser.c b/kitty/parser.c index bd3021f05..9f3f72d79 100644 --- a/kitty/parser.c +++ b/kitty/parser.c @@ -6,15 +6,21 @@ */ #include "data-types.h" - +extern PyTypeObject Screen_Type; PyObject* #ifdef DUMP_COMMANDS parse_bytes_dump(PyObject UNUSED *self, PyObject *args) { + PyObject *dump_callback = NULL; #else parse_bytes(PyObject UNUSED *self, PyObject *args) { #endif Py_buffer pybuf; - if (!PyArg_ParseTuple(args, "y*", &pybuf)) return NULL; + Screen *screen; +#ifdef DUMP_COMMANDS + if (!PyArg_ParseTuple(args, "OO!y*", &dump_callback, &Screen_Type, &screen, &pybuf)) return NULL; +#else + if (!PyArg_ParseTuple(args, "O!y*", &Screen_Type, &screen, &pybuf)) return NULL; +#endif Py_RETURN_NONE; } diff --git a/kitty/screen.c b/kitty/screen.c new file mode 100644 index 000000000..746a7834a --- /dev/null +++ b/kitty/screen.c @@ -0,0 +1,69 @@ +/* + * screen.c + * Copyright (C) 2016 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ + +#include "data-types.h" + +static const ScreenModes empty_modes = {0}; + +static PyObject* +new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) { + Screen *self; + PyObject *callbacks = Py_None; + if (!PyArg_ParseTuple(args, "|O", &callbacks)) return NULL; + + self = (Screen *)type->tp_alloc(type, 0); + if (self != NULL) { + self->current_charset = 2; + self->columns = 80; self->lines=24; + self->modes = empty_modes; + self->utf8_state = 0; + self->margin_top = 0; self->margin_bottom = self->lines - 1; + self->callbacks = callbacks; Py_INCREF(callbacks); + self->cursor = alloc_cursor(); + self->main_linebuf = alloc_linebuf(); self->alt_linebuf = alloc_linebuf(); + self->linebuf = self->main_linebuf; + self->main_savepoints = PyList_New(0); self->alt_savepoints = PyList_New(0); + self->savepoints = self->main_savepoints; + self->change_tracker = alloc_change_tracker(); + if (self->cursor == NULL || self->main_linebuf == NULL || self->alt_linebuf == NULL || self->main_savepoints == NULL || self->alt_savepoints == NULL || self->change_tracker == NULL) { + Py_CLEAR(self); return NULL; + } + } + return (PyObject*) self; +} + +static void +dealloc(Screen* self) { + Py_CLEAR(self->callbacks); + Py_CLEAR(self->cursor); Py_CLEAR(self->main_linebuf); Py_CLEAR(self->alt_linebuf); + Py_CLEAR(self->main_savepoints); Py_CLEAR(self->alt_savepoints); Py_CLEAR(self->change_tracker); + Py_TYPE(self)->tp_free((PyObject*)self); +} + + +// Boilerplate {{{ + +static PyMethodDef methods[] = { + {NULL} /* Sentinel */ +}; + + +PyTypeObject Screen_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "fast_data_types.Screen", + .tp_basicsize = sizeof(Screen), + .tp_dealloc = (destructor)dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_doc = "Screen", + .tp_methods = methods, + .tp_new = new, +}; + +INIT_TYPE(Screen) +// }}} + + diff --git a/kitty/screen.py b/kitty/screen.py index 4147026f9..c4615195e 100644 --- a/kitty/screen.py +++ b/kitty/screen.py @@ -55,7 +55,7 @@ class Screen: tracker_callbacks = 'cursor_changed update_screen update_line_range update_cell_range line_added_to_history'.split() _notify_cursor_position = True - def __init__(self, opts, callbacks=None, columns: int=80, lines: int=24): + def __init__(self, scrollback_sz, callbacks=None, columns: int=80, lines: int=24): for attr in default_callbacks: setattr(self, attr, getattr(callbacks, attr, default_callbacks[attr])) self.main_savepoints, self.alt_savepoints = deque(), deque() @@ -67,7 +67,7 @@ class Screen: setattr(self, attr, getattr(self.tracker, attr)) self.consolidate_changes = self.tracker.consolidate_changes self.reset_dirty = self.tracker.reset - sz = max(1000, opts.scrollback_lines) + sz = max(1000, scrollback_sz) self.tophistorybuf = deque(maxlen=sz) self.main_linebuf, self.alt_linebuf = LineBuf(self.lines, self.columns), LineBuf(self.lines, self.columns) self.linebuf = self.main_linebuf @@ -77,8 +77,8 @@ class Screen: def is_dirty(self): return self.tracker.dirty - def apply_opts(self, opts): - sz = max(1000, opts.scrollback_lines) + def change_scrollback_size(self, sz): + sz = max(1000, sz) if sz != self.tophistorybuf.maxlen: previous = self.tophistorybuf self.tophistorybuf = deque(maxlen=sz) diff --git a/kitty/tracker.c b/kitty/tracker.c index b553f4f6f..0986e00d0 100644 --- a/kitty/tracker.c +++ b/kitty/tracker.c @@ -19,8 +19,10 @@ extern void linebuf_init_line(LineBuf *, index_type); static PyObject* resize(ChangeTracker *self, PyObject *args) { #define resize_doc "Resize theis change tracker must be called when the screen it is tracking for is resized" - unsigned long ynum, xnum; - if (!PyArg_ParseTuple(args, "kk", &ynum, &xnum)) return NULL; + unsigned long ynum=1, xnum=1; + if (args) { + if (!PyArg_ParseTuple(args, "kk", &ynum, &xnum)) return NULL; + } self->ynum = ynum; self->xnum = xnum; #define ALLOC_VAR(name, sz) \ bool *name = PyMem_Calloc(sz, sizeof(bool)); \ @@ -285,3 +287,7 @@ static PyTypeObject ChangeTracker_Type = { INIT_TYPE(ChangeTracker) // }}} + +ChangeTracker* alloc_change_tracker() { + return (ChangeTracker*)new(&ChangeTracker_Type, NULL, NULL); +} diff --git a/kitty_tests/__init__.py b/kitty_tests/__init__.py index e1c135150..e1949d568 100644 --- a/kitty_tests/__init__.py +++ b/kitty_tests/__init__.py @@ -5,7 +5,6 @@ from unittest import TestCase from kitty.screen import Screen -from kitty.config import defaults from kitty.fast_data_types import LineBuf, Cursor @@ -32,8 +31,7 @@ class BaseTest(TestCase): ae = TestCase.assertEqual def create_screen(self, cols=5, lines=5, history_size=5): - opts = defaults._replace(scrollback_lines=history_size) - s = Screen(opts, columns=cols, lines=lines) + s = Screen(history_size, columns=cols, lines=lines) return s def assertEqualAttributes(self, c1, c2):