Cleanup: style, use braces for blenkernel
[blender.git] / source / blender / blenkernel / intern / blender.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bke
22  *
23  * Application level startup/shutdown functionality.
24  */
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include "MEM_guardedalloc.h"
31
32 #include "BLI_string.h"
33 #include "BLI_listbase.h"
34 #include "BLI_utildefines.h"
35 #include "BLI_callbacks.h"
36
37 #include "IMB_imbuf.h"
38 #include "IMB_moviecache.h"
39
40 #include "BKE_addon.h"
41 #include "BKE_blender.h"         /* own include */
42 #include "BKE_blender_version.h" /* own include */
43 #include "BKE_blender_user_menu.h"
44 #include "BKE_blendfile.h"
45 #include "BKE_brush.h"
46 #include "BKE_cachefile.h"
47 #include "BKE_global.h"
48 #include "BKE_idprop.h"
49 #include "BKE_image.h"
50 #include "BKE_layer.h"
51 #include "BKE_main.h"
52 #include "BKE_node.h"
53 #include "BKE_report.h"
54 #include "BKE_scene.h"
55 #include "BKE_screen.h"
56 #include "BKE_sequencer.h"
57 #include "BKE_studiolight.h"
58
59 #include "DEG_depsgraph.h"
60
61 #include "RE_pipeline.h"
62 #include "RE_render_ext.h"
63
64 #include "BLF_api.h"
65
66 Global G;
67 UserDef U;
68
69 char versionstr[48] = "";
70
71 /* ********** free ********** */
72
73 /* only to be called on exit blender */
74 void BKE_blender_free(void)
75 {
76   /* samples are in a global list..., also sets G_MAIN->sound->sample NULL */
77
78   BKE_studiolight_free(); /* needs to run before main free as wm is still referenced for icons preview jobs */
79   BKE_main_free(G_MAIN);
80   G_MAIN = NULL;
81
82   if (G.log.file != NULL) {
83     fclose(G.log.file);
84   }
85
86   BKE_spacetypes_free(); /* after free main, it uses space callbacks */
87
88   IMB_exit();
89   BKE_cachefiles_exit();
90   BKE_images_exit();
91   DEG_free_node_types();
92
93   BKE_brush_system_exit();
94   RE_texture_rng_exit();
95
96   BLI_callback_global_finalize();
97
98   BKE_sequencer_cache_destruct();
99   IMB_moviecache_destruct();
100
101   free_nodesystem();
102 }
103
104 void BKE_blender_version_string(char *version_str,
105                                 size_t maxncpy,
106                                 short version,
107                                 short subversion,
108                                 bool v_prefix,
109                                 bool include_subversion)
110 {
111   const char *prefix = v_prefix ? "v" : "";
112
113   if (include_subversion && subversion > 0) {
114     BLI_snprintf(
115         version_str, maxncpy, "%s%d.%02d.%d", prefix, version / 100, version % 100, subversion);
116   }
117   else {
118     BLI_snprintf(version_str, maxncpy, "%s%d.%02d", prefix, version / 100, version % 100);
119   }
120 }
121
122 void BKE_blender_globals_init(void)
123 {
124   memset(&G, 0, sizeof(Global));
125
126   U.savetime = 1;
127
128   G_MAIN = BKE_main_new();
129
130   strcpy(G.ima, "//");
131
132   BKE_blender_version_string(
133       versionstr, sizeof(versionstr), BLENDER_VERSION, BLENDER_SUBVERSION, true, true);
134
135 #ifndef WITH_PYTHON_SECURITY /* default */
136   G.f |= G_FLAG_SCRIPT_AUTOEXEC;
137 #else
138   G.f &= ~G_FLAG_SCRIPT_AUTOEXEC;
139 #endif
140
141   G.log.level = 1;
142 }
143
144 void BKE_blender_globals_clear(void)
145 {
146   BKE_main_free(G_MAIN); /* free all lib data */
147
148   G_MAIN = NULL;
149 }
150
151 /***/
152
153 static void keymap_item_free(wmKeyMapItem *kmi)
154 {
155   if (kmi->properties) {
156     IDP_FreeProperty(kmi->properties);
157     MEM_freeN(kmi->properties);
158   }
159   if (kmi->ptr) {
160     MEM_freeN(kmi->ptr);
161   }
162 }
163
164 void BKE_blender_userdef_data_swap(UserDef *userdef_a, UserDef *userdef_b)
165 {
166   SWAP(UserDef, *userdef_a, *userdef_b);
167 }
168
169 void BKE_blender_userdef_data_set(UserDef *userdef)
170 {
171   BKE_blender_userdef_data_swap(&U, userdef);
172   BKE_blender_userdef_data_free(userdef, true);
173 }
174
175 void BKE_blender_userdef_data_set_and_free(UserDef *userdef)
176 {
177   BKE_blender_userdef_data_set(userdef);
178   MEM_freeN(userdef);
179 }
180
181 static void userdef_free_keymaps(UserDef *userdef)
182 {
183   for (wmKeyMap *km = userdef->user_keymaps.first, *km_next; km; km = km_next) {
184     km_next = km->next;
185     for (wmKeyMapDiffItem *kmdi = km->diff_items.first; kmdi; kmdi = kmdi->next) {
186       if (kmdi->add_item) {
187         keymap_item_free(kmdi->add_item);
188         MEM_freeN(kmdi->add_item);
189       }
190       if (kmdi->remove_item) {
191         keymap_item_free(kmdi->remove_item);
192         MEM_freeN(kmdi->remove_item);
193       }
194     }
195
196     for (wmKeyMapItem *kmi = km->items.first; kmi; kmi = kmi->next) {
197       keymap_item_free(kmi);
198     }
199
200     BLI_freelistN(&km->diff_items);
201     BLI_freelistN(&km->items);
202
203     MEM_freeN(km);
204   }
205   BLI_listbase_clear(&userdef->user_keymaps);
206 }
207
208 static void userdef_free_keyconfig_prefs(UserDef *userdef)
209 {
210   for (wmKeyConfigPref *kpt = userdef->user_keyconfig_prefs.first, *kpt_next; kpt;
211        kpt = kpt_next) {
212     kpt_next = kpt->next;
213     IDP_FreeProperty(kpt->prop);
214     MEM_freeN(kpt->prop);
215     MEM_freeN(kpt);
216   }
217   BLI_listbase_clear(&userdef->user_keyconfig_prefs);
218 }
219
220 static void userdef_free_user_menus(UserDef *userdef)
221 {
222   for (bUserMenu *um = userdef->user_menus.first, *um_next; um; um = um_next) {
223     um_next = um->next;
224     BKE_blender_user_menu_item_free_list(&um->items);
225     MEM_freeN(um);
226   }
227 }
228
229 static void userdef_free_addons(UserDef *userdef)
230 {
231   for (bAddon *addon = userdef->addons.first, *addon_next; addon; addon = addon_next) {
232     addon_next = addon->next;
233     BKE_addon_free(addon);
234   }
235   BLI_listbase_clear(&userdef->addons);
236 }
237
238 /**
239  * When loading a new userdef from file,
240  * or when exiting Blender.
241  */
242 void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
243 {
244 #define U _invalid_access_ /* ensure no accidental global access */
245 #ifdef U                   /* quiet warning */
246 #endif
247
248   userdef_free_keymaps(userdef);
249   userdef_free_keyconfig_prefs(userdef);
250   userdef_free_user_menus(userdef);
251   userdef_free_addons(userdef);
252
253   if (clear_fonts) {
254     for (uiFont *font = userdef->uifonts.first; font; font = font->next) {
255       BLF_unload_id(font->blf_id);
256     }
257     BLF_default_set(-1);
258   }
259
260   BLI_freelistN(&userdef->autoexec_paths);
261
262   BLI_freelistN(&userdef->uistyles);
263   BLI_freelistN(&userdef->uifonts);
264   BLI_freelistN(&userdef->themes);
265
266 #undef U
267 }
268
269 /**
270  * Write U from userdef.
271  * This function defines which settings a template will override for the user preferences.
272  */
273 void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *userdef_b)
274 {
275   /* TODO:
276    * - various minor settings (add as needed).
277    */
278
279 #define DATA_SWAP(id) \
280   { \
281     UserDef userdef_tmp; \
282     memcpy(&(userdef_tmp.id), &(userdef_a->id), sizeof(userdef_tmp.id)); \
283     memcpy(&(userdef_a->id), &(userdef_b->id), sizeof(userdef_tmp.id)); \
284     memcpy(&(userdef_b->id), &(userdef_tmp.id), sizeof(userdef_tmp.id)); \
285   } \
286   ((void)0)
287
288 #define LIST_SWAP(id) \
289   { \
290     SWAP(ListBase, userdef_a->id, userdef_b->id); \
291   } \
292   ((void)0)
293
294 #define FLAG_SWAP(id, ty, flags) \
295   { \
296     CHECK_TYPE(&(userdef_a->id), ty *); \
297     const ty f = flags; \
298     const ty a = userdef_a->id; \
299     const ty b = userdef_b->id; \
300     userdef_a->id = (userdef_a->id & ~f) | (b & f); \
301     userdef_b->id = (userdef_b->id & ~f) | (a & f); \
302   } \
303   ((void)0)
304
305   LIST_SWAP(uistyles);
306   LIST_SWAP(uifonts);
307   LIST_SWAP(themes);
308   LIST_SWAP(addons);
309   LIST_SWAP(user_keymaps);
310
311   DATA_SWAP(font_path_ui);
312   DATA_SWAP(font_path_ui_mono);
313   DATA_SWAP(keyconfigstr);
314
315   DATA_SWAP(gizmo_flag);
316   DATA_SWAP(app_flag);
317
318   /* We could add others. */
319   FLAG_SWAP(uiflag, int, USER_SAVE_PROMPT);
320
321 #undef SWAP_TYPELESS
322 #undef DATA_SWAP
323 #undef LIST_SWAP
324 #undef FLAG_SWAP
325 }
326
327 void BKE_blender_userdef_app_template_data_set(UserDef *userdef)
328 {
329   BKE_blender_userdef_app_template_data_swap(&U, userdef);
330   BKE_blender_userdef_data_free(userdef, true);
331 }
332
333 void BKE_blender_userdef_app_template_data_set_and_free(UserDef *userdef)
334 {
335   BKE_blender_userdef_app_template_data_set(userdef);
336   MEM_freeN(userdef);
337 }
338
339 /** \name Blender's AtExit
340  *
341  * \note Don't use MEM_mallocN so functions can be registered at any time.
342  * \{ */
343
344 static struct AtExitData {
345   struct AtExitData *next;
346
347   void (*func)(void *user_data);
348   void *user_data;
349 } *g_atexit = NULL;
350
351 void BKE_blender_atexit_register(void (*func)(void *user_data), void *user_data)
352 {
353   struct AtExitData *ae = malloc(sizeof(*ae));
354   ae->next = g_atexit;
355   ae->func = func;
356   ae->user_data = user_data;
357   g_atexit = ae;
358 }
359
360 void BKE_blender_atexit_unregister(void (*func)(void *user_data), const void *user_data)
361 {
362   struct AtExitData *ae = g_atexit;
363   struct AtExitData **ae_p = &g_atexit;
364
365   while (ae) {
366     if ((ae->func == func) && (ae->user_data == user_data)) {
367       *ae_p = ae->next;
368       free(ae);
369       return;
370     }
371     ae_p = &ae;
372     ae = ae->next;
373   }
374 }
375
376 void BKE_blender_atexit(void)
377 {
378   struct AtExitData *ae = g_atexit, *ae_next;
379   while (ae) {
380     ae_next = ae->next;
381
382     ae->func(ae->user_data);
383
384     free(ae);
385     ae = ae_next;
386   }
387   g_atexit = NULL;
388 }
389
390 /** \} */