1 /*
2  * Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
3  *
4  * Distributed under terms of the GPL3 license.
5  */
6 
7 #pragma once
8 
9 #include "graphics.h"
10 #include "monotonic.h"
11 #define MAX_PARAMS 256
12 
13 typedef enum ScrollTypes { SCROLL_LINE = -999999, SCROLL_PAGE, SCROLL_FULL } ScrollType;
14 
15 typedef struct {
16     bool mLNM, mIRM, mDECTCEM, mDECSCNM, mDECOM, mDECAWM, mDECCOLM, mDECARM, mDECCKM,
17          mBRACKETED_PASTE, mFOCUS_TRACKING, mDECSACE;
18     MouseTrackingMode mouse_tracking_mode;
19     MouseTrackingProtocol mouse_tracking_protocol;
20     bool eight_bit_controls;  // S8C1T
21 } ScreenModes;
22 
23 typedef struct {
24     unsigned int x, y;
25     bool in_left_half_of_cell;
26 } SelectionBoundary;
27 
28 typedef enum SelectionExtendModes { EXTEND_CELL, EXTEND_WORD, EXTEND_LINE, EXTEND_LINE_FROM_POINT } SelectionExtendMode;
29 
30 typedef struct {
31     index_type x, x_limit;
32 } XRange;
33 
34 typedef struct {
35     int y, y_limit;
36     XRange first, body, last;
37 } IterationData;
38 
39 typedef struct {
40     SelectionBoundary start, end, input_start, input_current;
41     unsigned int start_scrolled_by, end_scrolled_by;
42     bool rectangle_select, adjusting_start;
43     IterationData last_rendered;
44     int sort_y, sort_x;
45     struct {
46         SelectionBoundary start, end;
47         unsigned int scrolled_by;
48     } initial_extent;
49 } Selection;
50 
51 typedef struct {
52     Selection *items;
53     size_t count, capacity, last_rendered_count;
54     bool in_progress, extension_in_progress;
55     SelectionExtendMode extend_mode;
56 } Selections;
57 
58 #define SAVEPOINTS_SZ 256
59 
60 typedef struct {
61     uint32_t utf8_state, utf8_codepoint, *g0_charset, *g1_charset;
62     unsigned int current_charset;
63     bool use_latin1;
64     Cursor cursor;
65     bool mDECOM, mDECAWM, mDECSCNM;
66     bool is_valid;
67 } Savepoint;
68 
69 
70 typedef struct {
71     ScreenModes buf[SAVEPOINTS_SZ];
72     index_type start_of_data, count;
73 } SavemodesBuffer;
74 
75 typedef struct {
76     CPUCell *cpu_cells;
77     GPUCell *gpu_cells;
78     bool is_active;
79     index_type xstart, ynum, xnum;
80 } OverlayLine;
81 
82 typedef struct {
83     PyObject_HEAD
84 
85     unsigned int columns, lines, margin_top, margin_bottom, charset, scrolled_by;
86     double pending_scroll_pixels;
87     CellPixelSize cell_size;
88     OverlayLine overlay_line;
89     id_type window_id;
90     uint32_t utf8_codepoint, *g0_charset, *g1_charset, *g_charset;
91     UTF8State utf8_state;
92     unsigned int current_charset;
93     Selections selections, url_ranges;
94     struct {
95         unsigned int cursor_x, cursor_y, scrolled_by;
96         index_type lines, columns;
97     } last_rendered;
98     bool use_latin1, is_dirty, scroll_changed, reload_all_gpu_data;
99     Cursor *cursor;
100     Savepoint main_savepoint, alt_savepoint;
101     SavemodesBuffer modes_savepoints;
102     PyObject *callbacks, *test_child;
103     LineBuf *linebuf, *main_linebuf, *alt_linebuf;
104     GraphicsManager *grman, *main_grman, *alt_grman;
105     HistoryBuf *historybuf;
106     unsigned int history_line_added_count;
107     bool *tabstops, *main_tabstops, *alt_tabstops;
108     ScreenModes modes;
109     ColorProfile *color_profile;
110     monotonic_t start_visual_bell_at;
111 
112     uint32_t parser_buf[PARSER_BUF_SZ];
113     unsigned int parser_state, parser_text_start, parser_buf_pos;
114     bool parser_has_pending_text;
115     uint8_t read_buf[READ_BUF_SZ], *write_buf;
116     monotonic_t new_input_at;
117     size_t read_buf_sz, write_buf_sz, write_buf_used;
118     pthread_mutex_t read_buf_lock, write_buf_lock;
119 
120     CursorRenderInfo cursor_render_info;
121 
122     struct {
123         size_t capacity, used;
124         uint8_t *buf;
125         monotonic_t activated_at, wait_time;
126         unsigned stop_escape_code_type;
127     } pending_mode;
128     DisableLigature disable_ligatures;
129     PyObject *marker;
130     bool has_focus;
131     bool has_activity_since_last_focus;
132     hyperlink_id_type active_hyperlink_id;
133     HYPERLINK_POOL_HANDLE hyperlink_pool;
134     ANSIBuf as_ansi_buf;
135     char_type last_graphic_char;
136     uint8_t main_key_encoding_flags[8], alt_key_encoding_flags[8], *key_encoding_flags;
137 } Screen;
138 
139 
140 void parse_worker(Screen *screen, PyObject *dump_callback, monotonic_t now);
141 void parse_worker_dump(Screen *screen, PyObject *dump_callback, monotonic_t now);
142 void screen_align(Screen*);
143 void screen_restore_cursor(Screen *);
144 void screen_save_cursor(Screen *);
145 void screen_restore_modes(Screen *);
146 void screen_save_modes(Screen *);
147 void write_escape_code_to_child(Screen *self, unsigned char which, const char *data);
148 void screen_cursor_position(Screen*, unsigned int, unsigned int);
149 void screen_cursor_back(Screen *self, unsigned int count/*=1*/, int move_direction/*=-1*/);
150 void screen_erase_in_line(Screen *, unsigned int, bool);
151 void screen_erase_in_display(Screen *, unsigned int, bool);
152 void screen_draw(Screen *screen, uint32_t codepoint, bool);
153 void screen_ensure_bounds(Screen *self, bool use_margins, bool cursor_was_within_margins);
154 void screen_toggle_screen_buffer(Screen *self, bool, bool);
155 void screen_normal_keypad_mode(Screen *self);
156 void screen_alternate_keypad_mode(Screen *self);
157 void screen_change_default_color(Screen *self, unsigned int which, uint32_t col);
158 void screen_alignment_display(Screen *self);
159 void screen_reverse_index(Screen *self);
160 void screen_index(Screen *self);
161 void screen_scroll(Screen *self, unsigned int count);
162 void screen_reverse_scroll(Screen *self, unsigned int count);
163 void screen_reverse_scroll_and_fill_from_scrollback(Screen *self, unsigned int count);
164 void screen_reset(Screen *self);
165 void screen_set_tab_stop(Screen *self);
166 void screen_tab(Screen *self);
167 void screen_backtab(Screen *self, unsigned int);
168 void screen_clear_tab_stop(Screen *self, unsigned int how);
169 void screen_set_mode(Screen *self, unsigned int mode);
170 void screen_reset_mode(Screen *self, unsigned int mode);
171 void screen_decsace(Screen *self, unsigned int);
172 void screen_xtversion(Screen *self, unsigned int);
173 void screen_insert_characters(Screen *self, unsigned int count);
174 void screen_cursor_up(Screen *self, unsigned int count/*=1*/, bool do_carriage_return/*=false*/, int move_direction/*=-1*/);
175 void screen_set_cursor(Screen *self, unsigned int mode, uint8_t secondary);
176 void screen_cursor_to_column(Screen *self, unsigned int column);
177 void screen_cursor_down(Screen *self, unsigned int count/*=1*/);
178 void screen_cursor_forward(Screen *self, unsigned int count/*=1*/);
179 void screen_cursor_down1(Screen *self, unsigned int count/*=1*/);
180 void screen_cursor_up1(Screen *self, unsigned int count/*=1*/);
181 void screen_cursor_to_line(Screen *screen, unsigned int line);
182 void screen_insert_lines(Screen *self, unsigned int count/*=1*/);
183 void screen_delete_lines(Screen *self, unsigned int count/*=1*/);
184 void screen_repeat_character(Screen *self, unsigned int count);
185 void screen_delete_characters(Screen *self, unsigned int count);
186 void screen_erase_characters(Screen *self, unsigned int count);
187 void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom);
188 void screen_change_charset(Screen *, uint32_t to);
189 void screen_handle_cmd(Screen *, PyObject *cmd);
190 void screen_push_colors(Screen *, unsigned int);
191 void screen_pop_colors(Screen *, unsigned int);
192 void screen_report_color_stack(Screen *);
193 void screen_handle_print(Screen *, PyObject *cmd);
194 void screen_designate_charset(Screen *, uint32_t which, uint32_t as);
195 void screen_use_latin1(Screen *, bool);
196 void set_title(Screen *self, PyObject*);
197 void desktop_notify(Screen *self, unsigned int, PyObject*);
198 void set_icon(Screen *self, PyObject*);
199 void set_dynamic_color(Screen *self, unsigned int code, PyObject*);
200 void clipboard_control(Screen *self, int code, PyObject*);
201 void set_color_table_color(Screen *self, unsigned int code, PyObject*);
202 void process_cwd_notification(Screen *self, unsigned int code, PyObject*);
203 uint32_t* translation_table(uint32_t which);
204 void screen_request_capabilities(Screen *, char, PyObject *);
205 void screen_set_8bit_controls(Screen *, bool);
206 void report_device_attributes(Screen *self, unsigned int UNUSED mode, char start_modifier);
207 void select_graphic_rendition(Screen *self, int *params, unsigned int count, Region*);
208 void report_device_status(Screen *self, unsigned int which, bool UNUSED);
209 void report_mode_status(Screen *self, unsigned int which, bool);
210 void screen_apply_selection(Screen *self, void *address, size_t size);
211 bool screen_is_selection_dirty(Screen *self);
212 bool screen_has_selection(Screen*);
213 bool screen_invert_colors(Screen *self);
214 void screen_update_cell_data(Screen *self, void *address, FONTS_DATA_HANDLE, bool cursor_has_moved);
215 bool screen_is_cursor_visible(Screen *self);
216 bool screen_selection_range_for_line(Screen *self, index_type y, index_type *start, index_type *end);
217 bool screen_selection_range_for_word(Screen *self, const index_type x, const index_type y, index_type *, index_type *, index_type *start, index_type *end, bool);
218 void screen_start_selection(Screen *self, index_type x, index_type y, bool, bool, SelectionExtendMode);
219 typedef struct SelectionUpdate {
220     bool ended, start_extended_selection, set_as_nearest_extend;
221 } SelectionUpdate;
222 void screen_update_selection(Screen *self, index_type x, index_type y, bool in_left_half, SelectionUpdate upd);
223 bool screen_history_scroll(Screen *self, int amt, bool upwards);
224 Line* screen_visual_line(Screen *self, index_type y);
225 unsigned long screen_current_char_width(Screen *self);
226 void screen_mark_url(Screen *self, index_type start_x, index_type start_y, index_type end_x, index_type end_y);
227 void set_active_hyperlink(Screen*, char*, char*);
228 hyperlink_id_type screen_mark_hyperlink(Screen*, index_type, index_type);
229 void screen_handle_graphics_command(Screen *self, const GraphicsCommand *cmd, const uint8_t *payload);
230 bool screen_open_url(Screen*);
231 void screen_dirty_sprite_positions(Screen *self);
232 void screen_rescale_images(Screen *self);
233 void screen_report_size(Screen *, unsigned int which);
234 void screen_manipulate_title_stack(Screen *, unsigned int op, unsigned int which);
235 void screen_draw_overlay_text(Screen *self, const char *utf8_text);
236 void screen_set_key_encoding_flags(Screen *self, uint32_t val, uint32_t how);
237 void screen_push_key_encoding_flags(Screen *self, uint32_t val);
238 void screen_pop_key_encoding_flags(Screen *self, uint32_t num);
239 uint8_t screen_current_key_encoding_flags(Screen *self);
240 void screen_report_key_encoding_flags(Screen *self);
241 void screen_xtmodkeys(Screen *self, uint32_t p1, uint32_t p2);
242 bool screen_detect_url(Screen *screen, unsigned int x, unsigned int y);
243 #define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen);
244 DECLARE_CH_SCREEN_HANDLER(bell)
245 DECLARE_CH_SCREEN_HANDLER(backspace)
246 DECLARE_CH_SCREEN_HANDLER(tab)
247 DECLARE_CH_SCREEN_HANDLER(linefeed)
248 DECLARE_CH_SCREEN_HANDLER(carriage_return)
249 #undef DECLARE_CH_SCREEN_HANDLER
250