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 <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "MEM_guardedalloc.h"
31 
32 #include "BLI_listbase.h"
33 #include "BLI_string.h"
34 #include "BLI_utildefines.h"
35 
36 #include "IMB_imbuf.h"
37 #include "IMB_moviecache.h"
38 
39 #include "BKE_addon.h"
40 #include "BKE_blender.h" /* own include */
41 #include "BKE_blender_user_menu.h"
42 #include "BKE_blender_version.h" /* own include */
43 #include "BKE_blendfile.h"
44 #include "BKE_brush.h"
45 #include "BKE_cachefile.h"
46 #include "BKE_callbacks.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 /* -------------------------------------------------------------------- */
70 /** \name Blender Free on Exit
71  * \{ */
72 
73 /* only to be called on exit blender */
BKE_blender_free(void)74 void BKE_blender_free(void)
75 {
76   /* samples are in a global list..., also sets G_MAIN->sound->sample NULL */
77 
78   /* Needs to run before main free as wm is still referenced for icons preview jobs. */
79   BKE_studiolight_free();
80 
81   BKE_main_free(G_MAIN);
82   G_MAIN = NULL;
83 
84   if (G.log.file != NULL) {
85     fclose(G.log.file);
86   }
87 
88   BKE_spacetypes_free(); /* after free main, it uses space callbacks */
89 
90   IMB_exit();
91   BKE_cachefiles_exit();
92   BKE_images_exit();
93   DEG_free_node_types();
94 
95   BKE_brush_system_exit();
96   RE_texture_rng_exit();
97 
98   BKE_callback_global_finalize();
99 
100   IMB_moviecache_destruct();
101 
102   free_nodesystem();
103 }
104 
105 /** \} */
106 
107 /* -------------------------------------------------------------------- */
108 /** \name Blender Version Access
109  * \{ */
110 
111 static char blender_version_string[48] = "";
112 
blender_version_init(void)113 static void blender_version_init(void)
114 {
115   const char *version_cycle = "";
116   if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha")) {
117     version_cycle = " Alpha";
118   }
119   else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "beta")) {
120     version_cycle = " Beta";
121   }
122   else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "rc")) {
123     version_cycle = " Release Candidate";
124   }
125   else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
126     version_cycle = "";
127   }
128   else {
129     BLI_assert(!"Invalid Blender version cycle");
130   }
131 
132   BLI_snprintf(blender_version_string,
133                ARRAY_SIZE(blender_version_string),
134                "%d.%02d.%d%s",
135                BLENDER_VERSION / 100,
136                BLENDER_VERSION % 100,
137                BLENDER_VERSION_PATCH,
138                version_cycle);
139 }
140 
BKE_blender_version_string(void)141 const char *BKE_blender_version_string(void)
142 {
143   return blender_version_string;
144 }
145 
BKE_blender_version_is_alpha(void)146 bool BKE_blender_version_is_alpha(void)
147 {
148   bool is_alpha = STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha");
149   return is_alpha;
150 }
151 
152 /** \} */
153 
154 /* -------------------------------------------------------------------- */
155 /** \name Blender #Global Initialize/Clear
156  * \{ */
157 
BKE_blender_globals_init(void)158 void BKE_blender_globals_init(void)
159 {
160   blender_version_init();
161 
162   memset(&G, 0, sizeof(Global));
163 
164   U.savetime = 1;
165 
166   G_MAIN = BKE_main_new();
167 
168   strcpy(G.ima, "//");
169 
170 #ifndef WITH_PYTHON_SECURITY /* default */
171   G.f |= G_FLAG_SCRIPT_AUTOEXEC;
172 #else
173   G.f &= ~G_FLAG_SCRIPT_AUTOEXEC;
174 #endif
175 
176   G.log.level = 1;
177 }
178 
BKE_blender_globals_clear(void)179 void BKE_blender_globals_clear(void)
180 {
181   BKE_main_free(G_MAIN); /* free all lib data */
182 
183   G_MAIN = NULL;
184 }
185 
186 /** \} */
187 
188 /* -------------------------------------------------------------------- */
189 /** \name Blender Preferences
190  * \{ */
191 
keymap_item_free(wmKeyMapItem * kmi)192 static void keymap_item_free(wmKeyMapItem *kmi)
193 {
194   if (kmi->properties) {
195     IDP_FreeProperty(kmi->properties);
196   }
197   if (kmi->ptr) {
198     MEM_freeN(kmi->ptr);
199   }
200 }
201 
BKE_blender_userdef_data_swap(UserDef * userdef_a,UserDef * userdef_b)202 void BKE_blender_userdef_data_swap(UserDef *userdef_a, UserDef *userdef_b)
203 {
204   SWAP(UserDef, *userdef_a, *userdef_b);
205 }
206 
BKE_blender_userdef_data_set(UserDef * userdef)207 void BKE_blender_userdef_data_set(UserDef *userdef)
208 {
209   BKE_blender_userdef_data_swap(&U, userdef);
210   BKE_blender_userdef_data_free(userdef, true);
211 }
212 
BKE_blender_userdef_data_set_and_free(UserDef * userdef)213 void BKE_blender_userdef_data_set_and_free(UserDef *userdef)
214 {
215   BKE_blender_userdef_data_set(userdef);
216   MEM_freeN(userdef);
217 }
218 
userdef_free_keymaps(UserDef * userdef)219 static void userdef_free_keymaps(UserDef *userdef)
220 {
221   for (wmKeyMap *km = userdef->user_keymaps.first, *km_next; km; km = km_next) {
222     km_next = km->next;
223     LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &km->diff_items) {
224       if (kmdi->add_item) {
225         keymap_item_free(kmdi->add_item);
226         MEM_freeN(kmdi->add_item);
227       }
228       if (kmdi->remove_item) {
229         keymap_item_free(kmdi->remove_item);
230         MEM_freeN(kmdi->remove_item);
231       }
232     }
233 
234     LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
235       keymap_item_free(kmi);
236     }
237 
238     BLI_freelistN(&km->diff_items);
239     BLI_freelistN(&km->items);
240 
241     MEM_freeN(km);
242   }
243   BLI_listbase_clear(&userdef->user_keymaps);
244 }
245 
userdef_free_keyconfig_prefs(UserDef * userdef)246 static void userdef_free_keyconfig_prefs(UserDef *userdef)
247 {
248   for (wmKeyConfigPref *kpt = userdef->user_keyconfig_prefs.first, *kpt_next; kpt;
249        kpt = kpt_next) {
250     kpt_next = kpt->next;
251     IDP_FreeProperty(kpt->prop);
252     MEM_freeN(kpt);
253   }
254   BLI_listbase_clear(&userdef->user_keyconfig_prefs);
255 }
256 
userdef_free_user_menus(UserDef * userdef)257 static void userdef_free_user_menus(UserDef *userdef)
258 {
259   for (bUserMenu *um = userdef->user_menus.first, *um_next; um; um = um_next) {
260     um_next = um->next;
261     BKE_blender_user_menu_item_free_list(&um->items);
262     MEM_freeN(um);
263   }
264 }
265 
userdef_free_addons(UserDef * userdef)266 static void userdef_free_addons(UserDef *userdef)
267 {
268   for (bAddon *addon = userdef->addons.first, *addon_next; addon; addon = addon_next) {
269     addon_next = addon->next;
270     BKE_addon_free(addon);
271   }
272   BLI_listbase_clear(&userdef->addons);
273 }
274 
275 /**
276  * When loading a new userdef from file,
277  * or when exiting Blender.
278  */
BKE_blender_userdef_data_free(UserDef * userdef,bool clear_fonts)279 void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
280 {
281 #define U BLI_STATIC_ASSERT(false, "Global 'U' not allowed, only use arguments passed in!")
282 #ifdef U /* quiet warning */
283 #endif
284 
285   userdef_free_keymaps(userdef);
286   userdef_free_keyconfig_prefs(userdef);
287   userdef_free_user_menus(userdef);
288   userdef_free_addons(userdef);
289 
290   if (clear_fonts) {
291     LISTBASE_FOREACH (uiFont *, font, &userdef->uifonts) {
292       BLF_unload_id(font->blf_id);
293     }
294     BLF_default_set(-1);
295   }
296 
297   BLI_freelistN(&userdef->autoexec_paths);
298 
299   BLI_freelistN(&userdef->uistyles);
300   BLI_freelistN(&userdef->uifonts);
301   BLI_freelistN(&userdef->themes);
302 
303 #undef U
304 }
305 
306 /** \} */
307 
308 /* -------------------------------------------------------------------- */
309 /** \name Blender Preferences (Application Templates)
310  * \{ */
311 
312 /**
313  * Write U from userdef.
314  * This function defines which settings a template will override for the user preferences.
315  */
BKE_blender_userdef_app_template_data_swap(UserDef * userdef_a,UserDef * userdef_b)316 void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *userdef_b)
317 {
318   /* TODO:
319    * - various minor settings (add as needed).
320    */
321 
322 #define DATA_SWAP(id) \
323   { \
324     UserDef userdef_tmp; \
325     memcpy(&(userdef_tmp.id), &(userdef_a->id), sizeof(userdef_tmp.id)); \
326     memcpy(&(userdef_a->id), &(userdef_b->id), sizeof(userdef_tmp.id)); \
327     memcpy(&(userdef_b->id), &(userdef_tmp.id), sizeof(userdef_tmp.id)); \
328   } \
329   ((void)0)
330 
331 #define LIST_SWAP(id) \
332   { \
333     SWAP(ListBase, userdef_a->id, userdef_b->id); \
334   } \
335   ((void)0)
336 
337 #define FLAG_SWAP(id, ty, flags) \
338   { \
339     CHECK_TYPE(&(userdef_a->id), ty *); \
340     const ty f = flags; \
341     const ty a = userdef_a->id; \
342     const ty b = userdef_b->id; \
343     userdef_a->id = (userdef_a->id & ~f) | (b & f); \
344     userdef_b->id = (userdef_b->id & ~f) | (a & f); \
345   } \
346   ((void)0)
347 
348   LIST_SWAP(uistyles);
349   LIST_SWAP(uifonts);
350   LIST_SWAP(themes);
351   LIST_SWAP(addons);
352   LIST_SWAP(user_keymaps);
353   LIST_SWAP(user_keyconfig_prefs);
354 
355   DATA_SWAP(font_path_ui);
356   DATA_SWAP(font_path_ui_mono);
357   DATA_SWAP(keyconfigstr);
358 
359   DATA_SWAP(gizmo_flag);
360   DATA_SWAP(app_flag);
361 
362   /* We could add others. */
363   FLAG_SWAP(uiflag, int, USER_SAVE_PROMPT);
364 
365 #undef SWAP_TYPELESS
366 #undef DATA_SWAP
367 #undef LIST_SWAP
368 #undef FLAG_SWAP
369 }
370 
BKE_blender_userdef_app_template_data_set(UserDef * userdef)371 void BKE_blender_userdef_app_template_data_set(UserDef *userdef)
372 {
373   BKE_blender_userdef_app_template_data_swap(&U, userdef);
374   BKE_blender_userdef_data_free(userdef, true);
375 }
376 
BKE_blender_userdef_app_template_data_set_and_free(UserDef * userdef)377 void BKE_blender_userdef_app_template_data_set_and_free(UserDef *userdef)
378 {
379   BKE_blender_userdef_app_template_data_set(userdef);
380   MEM_freeN(userdef);
381 }
382 
383 /** \} */
384 
385 /* -------------------------------------------------------------------- */
386 /** \name Blender's AtExit
387  *
388  * \note Don't use MEM_mallocN so functions can be registered at any time.
389  * \{ */
390 
391 static struct AtExitData {
392   struct AtExitData *next;
393 
394   void (*func)(void *user_data);
395   void *user_data;
396 } *g_atexit = NULL;
397 
BKE_blender_atexit_register(void (* func)(void * user_data),void * user_data)398 void BKE_blender_atexit_register(void (*func)(void *user_data), void *user_data)
399 {
400   struct AtExitData *ae = malloc(sizeof(*ae));
401   ae->next = g_atexit;
402   ae->func = func;
403   ae->user_data = user_data;
404   g_atexit = ae;
405 }
406 
BKE_blender_atexit_unregister(void (* func)(void * user_data),const void * user_data)407 void BKE_blender_atexit_unregister(void (*func)(void *user_data), const void *user_data)
408 {
409   struct AtExitData *ae = g_atexit;
410   struct AtExitData **ae_p = &g_atexit;
411 
412   while (ae) {
413     if ((ae->func == func) && (ae->user_data == user_data)) {
414       *ae_p = ae->next;
415       free(ae);
416       return;
417     }
418     ae_p = &ae;
419     ae = ae->next;
420   }
421 }
422 
BKE_blender_atexit(void)423 void BKE_blender_atexit(void)
424 {
425   struct AtExitData *ae = g_atexit, *ae_next;
426   while (ae) {
427     ae_next = ae->next;
428 
429     ae->func(ae->user_data);
430 
431     free(ae);
432     ae = ae_next;
433   }
434   g_atexit = NULL;
435 }
436 
437 /** \} */
438