1 /*
2  * Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm dot org>
3  *
4  * This file is part of Zrythm
5  *
6  * Zrythm is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Affero General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Zrythm is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Affero General Public License for more details.
15  *
16  * You should have received a copy of the GNU Affero General Public License
17  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 /**
21  * \file
22  *
23  * The main Zrythm struct.
24  */
25 
26 #ifndef __ZRYTHM_H__
27 #define __ZRYTHM_H__
28 
29 #include "zrythm-config.h"
30 
31 #include "zix/sem.h"
32 
33 #include <glib.h>
34 
35 typedef struct Project Project;
36 typedef struct Symap Symap;
37 typedef struct RecordingManager RecordingManager;
38 typedef struct EventManager EventManager;
39 typedef struct ObjectUtils ObjectUtils;
40 typedef struct PluginManager PluginManager;
41 typedef struct FileManager FileManager;
42 typedef struct Settings Settings;
43 typedef struct Log Log;
44 typedef struct CairoCaches CairoCaches;
45 typedef struct PCGRand PCGRand;
46 
47 /**
48  * @addtogroup general
49  *
50  * @{
51  */
52 
53 #define ZRYTHM (zrythm)
54 
55 #define ZRYTHM_PROJECTS_DIR "projects"
56 
57 #define MAX_RECENT_PROJECTS 20
58 #define DEBUGGING \
59   (G_UNLIKELY (ZRYTHM && ZRYTHM->debug))
60 #define ZRYTHM_TESTING \
61   (G_UNLIKELY (ZRYTHM && ZRYTHM->testing))
62 #define ZRYTHM_GENERATING_PROJECT \
63   (ZRYTHM->generating_project)
64 #define ZRYTHM_HAVE_UI (ZRYTHM && ZRYTHM->have_ui)
65 
66 #ifdef HAVE_LSP_DSP
67 #define ZRYTHM_USE_OPTIMIZED_DSP \
68   (G_LIKELY (ZRYTHM->use_optimized_dsp))
69 #else
70 #define ZRYTHM_USE_OPTIMIZED_DSP false
71 #endif
72 
73 /**
74  * Type of Zrythm directory.
75  */
76 typedef enum ZrythmDirType
77 {
78   /*
79    * ----
80    * System directories that ship with Zrythm
81    * and must not be changed.
82    * ----
83    */
84 
85   /**
86    * The prefix, or in the case of windows installer
87    * the root dir (C/program files/zrythm), or in the
88    * case of macos installer the bundle path.
89    *
90    * In all cases, "share" is expected to be found
91    * in this dir.
92    */
93   ZRYTHM_DIR_SYSTEM_PREFIX,
94 
95   /** "bin" under \ref ZRYTHM_DIR_SYSTEM_PREFIX. */
96   ZRYTHM_DIR_SYSTEM_BINDIR,
97 
98   /** "share" under \ref ZRYTHM_DIR_SYSTEM_PREFIX. */
99   ZRYTHM_DIR_SYSTEM_PARENT_DATADIR,
100 
101   /** "lib" under \ref ZRYTHM_DIR_SYSTEM_PREFIX. */
102   ZRYTHM_DIR_SYSTEM_PARENT_LIBDIR,
103 
104   /** lib/zrythm */
105   ZRYTHM_DIR_SYSTEM_ZRYTHM_LIBDIR,
106 
107   /** Localization under "share". */
108   ZRYTHM_DIR_SYSTEM_LOCALEDIR,
109 
110   /**
111    * "gtksourceview-4/language-specs" under
112    * "share".
113    */
114   ZRYTHM_DIR_SYSTEM_SOURCEVIEW_LANGUAGE_SPECS_DIR,
115 
116   /** share/zrythm */
117   ZRYTHM_DIR_SYSTEM_ZRYTHM_DATADIR,
118 
119   /** Samples. */
120   ZRYTHM_DIR_SYSTEM_SAMPLESDIR,
121 
122   /** Scripts. */
123   ZRYTHM_DIR_SYSTEM_SCRIPTSDIR,
124 
125   /** Themes. */
126   ZRYTHM_DIR_SYSTEM_THEMESDIR,
127 
128   /** CSS themes. */
129   ZRYTHM_DIR_SYSTEM_THEMES_CSS_DIR,
130 
131   /** Built-in plugins path. */
132   ZRYTHM_DIR_SYSTEM_LV2_PLUGINS_DIR,
133 
134   /* ************************************ */
135 
136   /*
137    * ----
138    * Zrythm user directories that contain
139    * user-modifiable data.
140    * ----
141    */
142 
143   /** Main zrythm directory from gsettings. */
144   ZRYTHM_DIR_USER_TOP,
145 
146   /** Subdirs of \ref ZRYTHM_DIR_USER_TOP. */
147   ZRYTHM_DIR_USER_PROJECTS,
148   ZRYTHM_DIR_USER_TEMPLATES,
149   ZRYTHM_DIR_USER_THEMES,
150 
151   /** User CSS themes. */
152   ZRYTHM_DIR_USER_THEMES_CSS,
153 
154   /** User scripts. */
155   ZRYTHM_DIR_USER_SCRIPTS,
156 
157   /** Log files. */
158   ZRYTHM_DIR_USER_LOG,
159 
160   /** Profiling files. */
161   ZRYTHM_DIR_USER_PROFILING,
162 
163   /** Gdb backtrace files. */
164   ZRYTHM_DIR_USER_GDB,
165 
166   /** Backtraces. */
167   ZRYTHM_DIR_USER_BACKTRACE,
168 
169 } ZrythmDirType;
170 
171 /**
172  * To be used throughout the program.
173  *
174  * Everything here should be global and function
175  * regardless of the project.
176  */
177 typedef struct Zrythm
178 {
179   /** argv[0]. */
180   const char *        exe_path;
181 
182   /**
183    * Manages plugins (loading, instantiating, etc.)
184    */
185   PluginManager *     plugin_manager;
186 
187   /**
188    * Application settings
189    */
190   Settings *          settings;
191 
192   /**
193    * Project data.
194    *
195    * This is what should be exported/imported when
196    * saving/loading projects.
197    *
198    * The only reason this is a pointer is to easily
199    * deserialize.
200    */
201   Project *           project;
202 
203   /** +1 to ensure last element is NULL in case
204    * full. */
205   char *
206     recent_projects[MAX_RECENT_PROJECTS + 1];
207   int                 num_recent_projects;
208 
209   /** NULL terminated array of project template
210    * absolute paths. */
211   char **             templates;
212 
213   /** Whether the open file is a template to be used
214    * to create a new project from. */
215   bool                opening_template;
216 
217   /** Whether creating a new project, either from
218    * a template or blank. */
219   bool                creating_project;
220 
221   /** Path to create a project in, including its
222    * title. */
223   char *              create_project_path;
224 
225   /**
226    * Filename to open passed through the command
227    * line.
228    *
229    * Used only when a filename is passed.
230    * E.g., zrytm myproject.xml
231    */
232   char *              open_filename;
233 
234   EventManager *      event_manager;
235 
236   /** Recording manager. */
237   RecordingManager *  recording_manager;
238 
239   /** File manager. */
240   FileManager *       file_manager;
241 
242   /**
243    * String interner for internal things.
244    */
245   Symap *             symap;
246 
247   /**
248    * String interner for error domains.
249    */
250   Symap *             error_domain_symap;
251 
252   /** Object utils. */
253   ObjectUtils *       object_utils;
254 
255   /** Random number generator. */
256   PCGRand *           rand;
257 
258   /**
259    * In debug mode or not (determined by GSetting).
260    */
261   bool                debug;
262 
263   /**
264    * Used when running the tests.
265    *
266    * This is set by the TESTING environment variable.
267    */
268   bool                testing;
269 
270   /** Whether this is a dummy instance used when
271    * generating projects. */
272   bool                generating_project;
273 
274   /** Log settings. */
275   //Log *               log;
276 
277   /**
278    * Progress done (0.0 ~ 1.0).
279    *
280    * To be used in things like the splash screen,
281    * loading projects, etc.
282    */
283   double              progress;
284 
285   /** 1 if Zrythm has a UI, 0 if headless (eg, when
286    * unit-testing). */
287   bool                have_ui;
288 
289   /** Whether to use optimized DSP when
290    * available. */
291   bool                use_optimized_dsp;
292 
293   CairoCaches *       cairo_caches;
294 
295   /** Zrythm directory used during unit tests. */
296   char *              testing_dir;
297 
298   /** Undo stack length, used during tests. */
299   int                 undo_stack_len;
300 
301   /** Cached version (without 'v'). */
302   char *              version;
303 } Zrythm;
304 
305 /**
306  * Global variable, should be available to all files.
307  */
308 extern Zrythm * zrythm;
309 
310 void
311 zrythm_add_to_recent_projects (
312   Zrythm * self,
313   const char * filepath);
314 
315 void
316 zrythm_remove_recent_project (
317   char * filepath);
318 
319 /**
320  * Returns the version string.
321  *
322  * Must be g_free()'d.
323  *
324  * @param with_v Include a starting "v".
325  */
326 char *
327 zrythm_get_version (
328   bool with_v);
329 
330 /**
331  * Returns whether the current Zrythm version is a
332  * release version.
333  *
334  * @note This only does regex checking.
335  */
336 bool
337 zrythm_is_release (
338   bool official);
339 
340 /**
341  * Returns the latest release version.
342  */
343 char *
344 zrythm_fetch_latest_release_ver (void);
345 
346 /**
347  * Returns whether this is the latest release.
348  *
349  * @p error will be set if an error occured and the
350  * return value should be ignored.
351  */
352 bool
353 zrythm_is_latest_release (
354   GError ** error);
355 
356 /**
357  * Returns the veresion and the capabilities.
358  */
359 void
360 zrythm_get_version_with_capabilities (
361   char * str);
362 
363 /**
364  * Returns the default user "zrythm" dir.
365  *
366  * This is used when resetting or when the
367  * dir is not selected by the user yet.
368  */
369 char *
370 zrythm_get_default_user_dir (void);
371 
372 /**
373  * Returns a Zrythm directory specified by
374  * \ref type.
375  *
376  * @return A newly allocated string.
377  */
378 char *
379 zrythm_get_dir (
380   ZrythmDirType type);
381 
382 /**
383  * Returns the prefix or in the case of windows
384  * the root dir (C/program files/zrythm) or in the
385  * case of macos the bundle path.
386  *
387  * In all cases, "share" is expected to be found
388  * in this dir.
389  *
390  * @return A newly allocated string.
391  */
392 char *
393 zrythm_get_prefix (void);
394 
395 /**
396  * Gets the zrythm directory, either from the
397  * settings if non-empty, or the default
398  * ($XDG_DATA_DIR/zrythm).
399  *
400  * @param force_default Ignore the settings and get
401  *   the default dir.
402  *
403  * Must be free'd by caler.
404  */
405 char *
406 zrythm_get_user_dir (
407   bool  force_default);
408 
409 /**
410  * Initializes/creates the default dirs/files in
411  * the user directory.
412  */
413 NONNULL
414 void
415 zrythm_init_user_dirs_and_files (
416   Zrythm * self);
417 
418 /**
419  * Initializes the array of project templates.
420  */
421 NONNULL
422 void
423 zrythm_init_templates (
424   Zrythm * self);
425 
426 /**
427  * Creates a new Zrythm instance.
428  *
429  * @param have_ui Whether Zrythm is instantiated
430  *   with a UI (false if headless).
431  * @param testing Whether this is a unit test.
432  */
433 Zrythm *
434 zrythm_new (
435   const char * exe_path,
436   bool         have_ui,
437   bool         testing,
438   bool         optimized_dsp);
439 
440 /**
441  * Frees the instance and any unfreed members.
442  */
443 void
444 zrythm_free (
445   Zrythm * self);
446 
447 /**
448  * @}
449  */
450 
451 #endif /* __ZRYTHM_H__ */
452