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 #include "data-types.h"
9 #include "screen.h"
10 #include "monotonic.h"
11 
12 #define OPT(name) global_state.opts.name
13 
14 typedef enum { LEFT_EDGE, TOP_EDGE, RIGHT_EDGE, BOTTOM_EDGE } Edge;
15 typedef enum { RESIZE_DRAW_STATIC, RESIZE_DRAW_SCALED, RESIZE_DRAW_BLANK, RESIZE_DRAW_SIZE } ResizeDrawStrategy;
16 typedef enum { REPEAT_MIRROR, REPEAT_CLAMP, REPEAT_DEFAULT } RepeatStrategy;
17 
18 typedef struct {
19     char_type string[16];
20     size_t len;
21 } UrlPrefix;
22 
23 typedef struct {
24     monotonic_t visual_bell_duration, cursor_blink_interval, cursor_stop_blinking_after, mouse_hide_wait, click_interval;
25     double wheel_scroll_multiplier, touch_scroll_multiplier;
26     bool enable_audio_bell;
27     CursorShape cursor_shape;
28     float cursor_beam_thickness;
29     float cursor_underline_thickness;
30     unsigned int url_style;
31     unsigned int scrollback_pager_history_size;
32     bool scrollback_fill_enlarged_window;
33     char_type *select_by_word_characters;
34     color_type url_color, background, foreground, active_border_color, inactive_border_color, bell_border_color;
35     color_type mark1_foreground, mark1_background, mark2_foreground, mark2_background, mark3_foreground, mark3_background;
36     monotonic_t repaint_delay, input_delay;
37     bool focus_follows_mouse;
38     unsigned int hide_window_decorations;
39     bool macos_hide_from_tasks, macos_quit_when_last_window_closed, macos_window_resizable, macos_traditional_fullscreen;
40     unsigned int macos_option_as_alt;
41     float macos_thicken_font;
42     WindowTitleIn macos_show_window_title_in;
43     int adjust_line_height_px, adjust_column_width_px, adjust_baseline_px;
44     float adjust_line_height_frac, adjust_column_width_frac, adjust_baseline_frac;
45     float background_opacity, dim_opacity;
46 
47     char* background_image;
48     BackgroundImageLayout background_image_layout;
49     bool background_image_linear;
50     float background_tint;
51 
52     bool dynamic_background_opacity;
53     float inactive_text_alpha;
54     Edge tab_bar_edge;
55     unsigned long tab_bar_min_tabs;
56     DisableLigature disable_ligatures;
57     bool force_ltr;
58     ResizeDrawStrategy resize_draw_strategy;
59     bool resize_in_steps;
60     bool sync_to_monitor;
61     bool close_on_child_death;
62     bool window_alert_on_bell;
63     bool debug_keyboard;
64     bool allow_hyperlinks;
65     monotonic_t resize_debounce_time;
66     MouseShape pointer_shape_when_grabbed;
67     MouseShape default_pointer_shape;
68     MouseShape pointer_shape_when_dragging;
69     struct {
70         UrlPrefix *values;
71         size_t num, max_prefix_len;
72     } url_prefixes;
73     char_type *url_excluded_characters;
74     bool detect_urls;
75     bool tab_bar_hidden;
76     double font_size;
77     struct {
78         double outer, inner;
79     } tab_bar_margin_height;
80 } Options;
81 
82 typedef struct {
83     ssize_t vao_idx, gvao_idx;
84     float xstart, ystart, dx, dy;
85     Screen *screen;
86 } ScreenRenderData;
87 
88 typedef struct {
89     unsigned int left, top, right, bottom;
90 } WindowGeometry;
91 
92 typedef struct {
93     monotonic_t at;
94     int button, modifiers;
95     double x, y;
96 } Click;
97 
98 #define CLICK_QUEUE_SZ 3
99 typedef struct {
100     Click clicks[CLICK_QUEUE_SZ];
101     unsigned int length;
102 } ClickQueue;
103 
104 typedef struct {
105     id_type id;
106     bool visible, cursor_visible_at_last_render;
107     unsigned int last_cursor_x, last_cursor_y;
108     CursorShape last_cursor_shape;
109     PyObject *title;
110     ScreenRenderData render_data;
111     struct {
112         unsigned int cell_x, cell_y;
113         double x, y;
114         bool in_left_half_of_cell;
115     } mouse_pos;
116     struct {
117         unsigned int left, top, right, bottom;
118     } padding;
119     WindowGeometry geometry;
120     ClickQueue click_queues[8];
121     monotonic_t last_drag_scroll_at;
122     uint32_t last_special_key_pressed;
123 } Window;
124 
125 typedef struct {
126     uint32_t left, top, right, bottom, color;
127 } BorderRect;
128 
129 typedef struct {
130     BorderRect *rect_buf;
131     unsigned int num_border_rects, capacity;
132     bool is_dirty;
133     ssize_t vao_idx;
134 } BorderRects;
135 
136 typedef struct {
137     id_type id;
138     unsigned int active_window, num_windows, capacity;
139     Window *windows;
140     BorderRects border_rects;
141 } Tab;
142 
143 typedef struct {
144     int x, y, w, h;
145     bool is_set;
146 } OSWindowGeometry;
147 
148 enum RENDER_STATE { RENDER_FRAME_NOT_REQUESTED, RENDER_FRAME_REQUESTED, RENDER_FRAME_READY };
149 typedef enum { NO_CLOSE_REQUESTED, CONFIRMABLE_CLOSE_REQUESTED, CLOSE_BEING_CONFIRMED, IMPERATIVE_CLOSE_REQUESTED } CloseRequest;
150 
151 typedef struct {
152     monotonic_t last_resize_event_at;
153     bool in_progress;
154     bool from_os_notification;
155     bool os_says_resize_complete;
156     unsigned int width, height, num_of_resize_events;
157 } LiveResizeInfo;
158 
159 
160 typedef struct {
161     void *handle;
162     id_type id;
163     uint32_t offscreen_framebuffer;
164     OSWindowGeometry before_fullscreen;
165     int viewport_width, viewport_height, window_width, window_height;
166     double viewport_x_ratio, viewport_y_ratio;
167     Tab *tabs;
168     BackgroundImage *bgimage;
169     unsigned int active_tab, num_tabs, capacity, last_active_tab, last_num_tabs, last_active_window_id;
170     bool focused_at_last_render, needs_render;
171     ScreenRenderData tab_bar_render_data;
172     bool tab_bar_data_updated;
173     bool is_focused;
174     monotonic_t cursor_blink_zero_time, last_mouse_activity_at;
175     double mouse_x, mouse_y;
176     double logical_dpi_x, logical_dpi_y, font_sz_in_pts;
177     bool mouse_button_pressed[32];
178     PyObject *window_title;
179     bool disallow_title_changes;
180     bool viewport_size_dirty, viewport_updated_at_least_once;
181     LiveResizeInfo live_resize;
182     bool has_pending_resizes, is_semi_transparent, shown_once, is_damaged;
183     uint32_t offscreen_texture_id;
184     unsigned int clear_count;
185     color_type last_titlebar_color;
186     float background_opacity;
187     FONTS_DATA_HANDLE fonts_data;
188     id_type temp_font_group_id;
189     enum RENDER_STATE render_state;
190     monotonic_t last_render_frame_received_at;
191     uint64_t render_calls;
192     id_type last_focused_counter;
193     ssize_t gvao_idx;
194     CloseRequest close_request;
195 } OSWindow;
196 
197 
198 typedef struct {
199     Options opts;
200 
201     id_type os_window_id_counter, tab_id_counter, window_id_counter;
202     PyObject *boss;
203     BackgroundImage *bgimage;
204     OSWindow *os_windows;
205     size_t num_os_windows, capacity;
206     OSWindow *callback_os_window;
207     bool is_wayland;
208     bool has_render_frames;
209     bool debug_rendering, debug_font_fallback;
210     bool has_pending_resizes, has_pending_closes;
211     bool in_sequence_mode;
212     bool check_for_active_animated_images;
213     struct { double x, y; } default_dpi;
214     id_type active_drag_in_window;
215     int active_drag_button;
216     CloseRequest quit_request;
217 } GlobalState;
218 
219 extern GlobalState global_state;
220 
221 #define call_boss(name, ...) if (global_state.boss) { \
222     PyObject *cret_ = PyObject_CallMethod(global_state.boss, #name, __VA_ARGS__); \
223     if (cret_ == NULL) { PyErr_Print(); } \
224     else Py_DECREF(cret_); \
225 }
226 
227 void gl_init(void);
228 void remove_vao(ssize_t vao_idx);
229 bool remove_os_window(id_type os_window_id);
230 void make_os_window_context_current(OSWindow *w);
231 void set_os_window_size(OSWindow *os_window, int x, int y);
232 void get_os_window_size(OSWindow *os_window, int *w, int *h, int *fw, int *fh);
233 void get_os_window_content_scale(OSWindow *os_window, double *xdpi, double *ydpi, float *xscale, float *yscale);
234 void update_os_window_references(void);
235 void mark_os_window_for_close(OSWindow* w, CloseRequest cr);
236 void update_os_window_viewport(OSWindow *window, bool);
237 bool should_os_window_be_rendered(OSWindow* w);
238 void wakeup_main_loop(void);
239 void swap_window_buffers(OSWindow *w);
240 bool make_window_context_current(id_type);
241 void hide_mouse(OSWindow *w);
242 bool is_mouse_hidden(OSWindow *w);
243 void destroy_os_window(OSWindow *w);
244 void focus_os_window(OSWindow *w, bool also_raise);
245 void set_os_window_title(OSWindow *w, const char *title);
246 OSWindow* os_window_for_kitty_window(id_type);
247 OSWindow* add_os_window(void);
248 OSWindow* current_os_window(void);
249 void os_window_regions(OSWindow*, Region *main, Region *tab_bar);
250 bool drag_scroll(Window *, OSWindow*);
251 void draw_borders(ssize_t vao_idx, unsigned int num_border_rects, BorderRect *rect_buf, bool rect_data_is_dirty, uint32_t viewport_width, uint32_t viewport_height, color_type, unsigned int, bool, OSWindow *w);
252 ssize_t create_cell_vao(void);
253 ssize_t create_graphics_vao(void);
254 ssize_t create_border_vao(void);
255 bool send_cell_data_to_gpu(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow *);
256 void draw_cells(ssize_t, ssize_t, float, float, float, float, Screen *, OSWindow *, bool, bool);
257 void draw_centered_alpha_mask(OSWindow *w, size_t screen_width, size_t screen_height, size_t width, size_t height, uint8_t *canvas);
258 void update_surface_size(int, int, uint32_t);
259 void free_texture(uint32_t*);
260 void free_framebuffer(uint32_t*);
261 void send_image_to_gpu(uint32_t*, const void*, int32_t, int32_t, bool, bool, bool, RepeatStrategy);
262 void send_sprite_to_gpu(FONTS_DATA_HANDLE fg, unsigned int, unsigned int, unsigned int, pixel*);
263 void blank_canvas(float, color_type);
264 void blank_os_window(OSWindow *);
265 void set_titlebar_color(OSWindow *w, color_type color, bool use_system_color);
266 FONTS_DATA_HANDLE load_fonts_data(double, double, double);
267 void send_prerendered_sprites_for_window(OSWindow *w);
268 #ifdef __APPLE__
269 void get_cocoa_key_equivalent(uint32_t, int, char *key, size_t key_sz, int*);
270 typedef enum {
271     PREFERENCES_WINDOW,
272     NEW_OS_WINDOW,
273     NEW_OS_WINDOW_WITH_WD,
274     NEW_TAB_WITH_WD,
275     CLOSE_OS_WINDOW,
276     CLOSE_TAB,
277     NEW_TAB,
278     NEXT_TAB,
279     PREVIOUS_TAB,
280     DETACH_TAB,
281     OPEN_FILE,
282     NEW_WINDOW,
283     CLOSE_WINDOW,
284     RESET_TERMINAL,
285     RELOAD_CONFIG,
286 
287     NUM_COCOA_PENDING_ACTIONS
288 } CocoaPendingAction;
289 void set_cocoa_pending_action(CocoaPendingAction action, const char*);
290 #endif
291 void request_frame_render(OSWindow *w);
292 void request_tick_callback(void);
293 typedef void (* timer_callback_fun)(id_type, void*);
294 typedef void (* tick_callback_fun)(void*);
295 id_type add_main_loop_timer(monotonic_t interval, bool repeats, timer_callback_fun callback, void *callback_data, timer_callback_fun free_callback);
296 void remove_main_loop_timer(id_type timer_id);
297 void update_main_loop_timer(id_type timer_id, monotonic_t interval, bool enabled);
298 void run_main_loop(tick_callback_fun, void*);
299 void stop_main_loop(void);
300 void os_window_update_size_increments(OSWindow *window);
301 void set_os_window_title_from_window(Window *w, OSWindow *os_window);
302 void update_os_window_title(OSWindow *os_window);
303 void fake_scroll(Window *w, int amount, bool upwards);
304 Window* window_for_window_id(id_type kitty_window_id);
305 void mouse_open_url(Window *w);
306 void mouse_selection(Window *w, int code, int button);
307 const char* format_mods(unsigned mods);
308 void send_pending_click_to_window_id(id_type, void*);
309 void send_pending_click_to_window(Window*, void*);
310 void get_platform_dependent_config_values(void *glfw_window);
311