1 // Copyright (c) 2015 Sergio Gonzalez. All rights reserved.
2 // License: https://github.com/serge-rgb/milton#license
3 
4 
5 #pragma once
6 
7 #include "common.h"
8 #include "memory.h"
9 
10 #include "system_includes.h"
11 #include "utils.h"
12 #include "vector.h"
13 
14 #if defined(__cplusplus)
15 extern "C" {
16 #endif
17 
18 
19 // EasyTab for drawing tablet support
20 
21 #if defined(_MSC_VER)
22 #pragma warning(push)
23 #pragma warning(disable:4668)
24 #endif
25 
26 #include "easytab.h"
27 
28 #if defined(_MSC_VER)
29 #pragma warning(pop)
30 #endif
31 
32 enum LayoutType
33 {
34     LayoutType_QWERTY,
35     LayoutType_AZERTY,
36     LayoutType_QWERTZ,
37     LayoutType_DVORAK,
38     LayoutType_COLEMAK,
39 };
40 
41 struct SDL_Cursor;
42 
43 struct PlatformSpecific;
44 
45 struct PlatformState
46 {
47     i32 width;
48     i32 height;
49 
50     v2i pointer;
51 
52     b32 is_space_down;
53     b32 is_pointer_down;
54     b32 is_middle_button_down;
55 
56     b32 is_panning;
57     b32 was_panning;
58     b32 waiting_for_pan_input; // Start panning from GUI menu.
59 
60     v2l pan_start;
61     v2l pan_point;
62 
63     b32 should_quit;
64     u32 window_id;
65 
66     i32 num_pressure_results;
67     i32 num_point_results;
68     b32 stopped_panning;
69 
70     b32 force_next_frame;  // Used for IMGUI, since some operations take 1+ frames.
71 
72     // SDL Cursors
73     SDL_Cursor* cursor_default;
74     SDL_Cursor* cursor_hand;
75     SDL_Cursor* cursor_crosshair;
76     SDL_Cursor* cursor_sizeall;
77     SDL_Cursor* cursor_brush;  // Custom cursor.
78 
79     // Current keyboard layout.
80     LayoutType keyboard_layout;
81 
82     SDL_Window* window;
83 
84     PlatformSpecific* specific;
85 
86     float ui_scale;
87 };
88 
89 typedef enum HistoryDebug
90 {
91     HistoryDebug_NOTHING,
92 
93     HistoryDebug_RECORD,
94     HistoryDebug_REPLAY,
95 } HistoryDebug;
96 
97 typedef struct MiltonStartupFlags
98 {
99     HistoryDebug history_debug;
100 } MiltonStartupFlags;
101 
102 typedef struct TabletState_s TabletState;
103 
104 int milton_main(bool is_fullscreen, char* file_to_open);
105 
106 void    platform_init(PlatformState* platform, SDL_SysWMinfo* sysinfo);
107 void    platform_deinit(PlatformState* platform);
108 
109 void    platform_setup_cursor(Arena* arena, PlatformState* platform);
110 
111 void    platform_cursor_set_position(PlatformState* platform, v2i pos);
112 // Get cursor position in client-rect space, whether or not it is within the client rect.
113 v2i     platform_cursor_get_position(PlatformState* platform);
114 
115 EasyTabResult platform_handle_sysevent(PlatformState* platform, SDL_SysWMEvent* sysevent);
116 void          platform_event_tick();
117 
118 void*   platform_allocate(size_t size);
119 #define platform_deallocate(pointer) platform_deallocate_internal((void**)&(pointer));
120 void    platform_deallocate_internal(void** ptr);
121 float   platform_ui_scale(PlatformState* p);
122 void    platform_point_to_pixel(PlatformState* ps, v2l* inout);
123 void    platform_point_to_pixel_i(PlatformState* ps, v2i* inout);
124 void    platform_pixel_to_point(PlatformState* ps, v2l* inout);
125 
126 #define milton_log platform_milton_log
127 #define milton_log_args platform_milton_log_args
128 void    milton_fatal(char* message);
129 void    milton_die_gracefully(char* message);
130 
131 int platform_titlebar_height(PlatformState* p);
132 
133 void cursor_show();
134 void cursor_hide();
135 
136 enum FileKind
137 {
138     FileKind_IMAGE,
139     FileKind_MILTON_CANVAS,
140 
141     FileKind_COUNT,
142 };
143 
144 
145 #if !defined(MAX_PATH) && defined(PATH_MAX)
146     #define MAX_PATH PATH_MAX
147 #endif
148 
149 // BACKWARDS-COMPATIBILITY NOTE: Should only grow down.
150 struct PlatformSettings
151 {
152     // Store the window size at the time of quitting.
153     i32 width;
154     i32 height;
155 
156     // Last opened file.
157     PATH_CHAR last_mlt_file[MAX_PATH];
158 
159     // GUI settings.
160     i32 brush_window_left;
161     i32 brush_window_top;
162     i32 brush_window_width;
163     i32 brush_window_height;
164 
165     i32 layer_window_left;
166     i32 layer_window_top;
167     i32 layer_window_width;
168     i32 layer_window_height;
169 };
170 
171 // Defined in platform_windows.cc
172 FILE*   platform_fopen(const PATH_CHAR* fname, const PATH_CHAR* mode);
173 
174 // Returns a 0-terminated string with the full path of the target file.
175 // If the user cancels the operation it returns NULL.
176 PATH_CHAR*   platform_open_dialog(FileKind kind);
177 PATH_CHAR*   platform_save_dialog(FileKind kind);
178 
179 void    platform_dialog(char* info, char* title);
180 b32     platform_dialog_yesno(char* info, char* title);
181 
182 // NOTE: These constants end with an underscore in order to prevent issues on
183 // macOS where the Objective-C headers define macros `YES` and `NO` as part of
184 // the `BOOL` type. Removing the underscores and compiling on macOS causes the
185 // compiler to attempt macro expansion on these names resulting in errors.
186 enum YesNoCancelAnswer
187 {
188     YES_,
189     NO_,
190     CANCEL_,
191 };
192 YesNoCancelAnswer platform_dialog_yesnocancel(char* info, char* title);
193 
194 void*   platform_get_gl_proc(char* name);
195 void    platform_load_gl_func_pointers();
196 
197 void    platform_fname_at_exe(PATH_CHAR* fname, size_t len);
198 b32     platform_move_file(PATH_CHAR* src, PATH_CHAR* dest);
199 
200 void str_to_path_char(char* str, PATH_CHAR* out, size_t out_sz);
201 // void path_char_to_str(char* str, PATH_CHAR* out, size_t out_sz);
202 
203 enum DeleteErrorTolerance
204 {
205     DeleteErrorTolerance_NONE         = 1<<0,
206     DeleteErrorTolerance_OK_NOT_EXIST = 1<<1,
207 };
208 b32     platform_delete_file_at_config(PATH_CHAR* fname, int error_tolerance);
209 void    platform_fname_at_config(PATH_CHAR* fname, size_t len);
210 
211 // Does *not* verify link. Do not expose to user facing inputs.
212 void    platform_open_link(char* link);
213 
214 WallTime platform_get_walltime();
215 
216 u64 difference_in_ms(WallTime start, WallTime end);
217 
218 void    platform_cursor_hide();
219 void    platform_cursor_show();
220 
221 i32 platform_monitor_refresh_hz();
222 
223 // Microsecond (us) resolution timer.
224 u64 perf_counter();
225 float perf_count_to_sec(u64 counter);
226 
227 
228 #if defined(__cplusplus)
229 }
230 #endif
231 
232 #if defined(_WIN32)
233 #include "platform_windows.h"
234 #elif defined(__linux__) || defined(__MACH__) || defined(__FreeBSD__)
235 #include "platform_unix.h"
236 #endif
237