Gizmo: match the DOF gizmo size with the non-gizmo indicator
[blender.git] / source / creator / creator.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 creator
22  */
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #ifdef WIN32
28 #  include <windows.h>
29 #  include "utfconv.h"
30 #endif
31
32 #include "MEM_guardedalloc.h"
33
34 #include "CLG_log.h"
35
36 #include "DNA_genfile.h"
37
38 #include "BLI_args.h"
39 #include "BLI_threads.h"
40 #include "BLI_utildefines.h"
41 #include "BLI_callbacks.h"
42 #include "BLI_string.h"
43 #include "BLI_system.h"
44
45 /* mostly init functions */
46 #include "BKE_appdir.h"
47 #include "BKE_blender.h"
48 #include "BKE_brush.h"
49 #include "BKE_cachefile.h"
50 #include "BKE_context.h"
51 #include "BKE_font.h"
52 #include "BKE_global.h"
53 #include "BKE_material.h"
54 #include "BKE_modifier.h"
55 #include "BKE_gpencil_modifier.h"
56 #include "BKE_node.h"
57 #include "BKE_shader_fx.h"
58 #include "BKE_sound.h"
59 #include "BKE_image.h"
60 #include "BKE_particle.h"
61
62 #include "DEG_depsgraph.h"
63
64 #include "IMB_imbuf.h" /* for IMB_init */
65
66 #include "RE_engine.h"
67 #include "RE_render_ext.h"
68
69 #include "ED_datafiles.h"
70
71 #include "WM_api.h"
72 #include "WM_toolsystem.h"
73
74 #include "RNA_define.h"
75
76 #ifdef WITH_FREESTYLE
77 #  include "FRS_freestyle.h"
78 #endif
79
80 #include <signal.h>
81
82 #ifdef __FreeBSD__
83 #  include <floatingpoint.h>
84 #endif
85
86 #ifdef WITH_BINRELOC
87 #  include "binreloc.h"
88 #endif
89
90 #ifdef WITH_LIBMV
91 #  include "libmv-capi.h"
92 #endif
93
94 #ifdef WITH_CYCLES_LOGGING
95 #  include "CCL_api.h"
96 #endif
97
98 #ifdef WITH_SDL_DYNLOAD
99 #  include "sdlew.h"
100 #endif
101
102 #include "creator_intern.h" /* own include */
103
104 /*  Local Function prototypes */
105 #ifdef WITH_PYTHON_MODULE
106 int main_python_enter(int argc, const char **argv);
107 void main_python_exit(void);
108 #endif
109
110 /* written to by 'creator_args.c' */
111 struct ApplicationState app_state = {
112     .signal =
113         {
114             .use_crash_handler = true,
115             .use_abort_handler = true,
116         },
117     .exit_code_on_error =
118         {
119             .python = 0,
120         },
121 };
122
123 /* -------------------------------------------------------------------- */
124 /** \name Application Level Callbacks
125  *
126  * Initialize callbacks for the modules that need them.
127  *
128  * \{ */
129
130 static void callback_mem_error(const char *errorStr)
131 {
132   fputs(errorStr, stderr);
133   fflush(stderr);
134 }
135
136 static void main_callback_setup(void)
137 {
138   /* Error output from the alloc routines: */
139   MEM_set_error_callback(callback_mem_error);
140 }
141
142 /* free data on early exit (if Python calls 'sys.exit()' while parsing args for eg). */
143 struct CreatorAtExitData {
144   bArgs *ba;
145 #ifdef WIN32
146   const char **argv;
147   int argv_num;
148 #endif
149 };
150
151 static void callback_main_atexit(void *user_data)
152 {
153   struct CreatorAtExitData *app_init_data = user_data;
154
155   if (app_init_data->ba) {
156     BLI_argsFree(app_init_data->ba);
157     app_init_data->ba = NULL;
158   }
159
160 #ifdef WIN32
161   if (app_init_data->argv) {
162     while (app_init_data->argv_num) {
163       free((void *)app_init_data->argv[--app_init_data->argv_num]);
164     }
165     free((void *)app_init_data->argv);
166     app_init_data->argv = NULL;
167   }
168 #endif
169 }
170
171 static void callback_clg_fatal(void *fp)
172 {
173   BLI_system_backtrace(fp);
174 }
175
176 /** \} */
177
178 /* -------------------------------------------------------------------- */
179 /** \name Main Function
180  * \{ */
181
182 #ifdef WITH_PYTHON_MODULE
183 /* allow python module to call main */
184 #  define main main_python_enter
185 static void *evil_C = NULL;
186
187 #  ifdef __APPLE__
188 /* environ is not available in mac shared libraries */
189 #    include <crt_externs.h>
190 char **environ = NULL;
191 #  endif
192 #endif
193
194 /**
195  * Blender's main function responsibilities are:
196  * - setup subsystems.
197  * - handle arguments.
198  * - run #WM_main() event loop,
199  *   or exit immediately when running in background mode.
200  */
201 int main(int argc,
202 #ifdef WIN32
203          const char **UNUSED(argv_c)
204 #else
205          const char **argv
206 #endif
207 )
208 {
209   bContext *C;
210
211 #ifndef WITH_PYTHON_MODULE
212   bArgs *ba;
213 #endif
214
215 #ifdef WIN32
216   char **argv;
217   int argv_num;
218 #endif
219
220   /* --- end declarations --- */
221
222   /* ensure we free data on early-exit */
223   struct CreatorAtExitData app_init_data = {NULL};
224   BKE_blender_atexit_register(callback_main_atexit, &app_init_data);
225
226   /* Unbuffered stdout makes stdout and stderr better synchronized, and helps
227    * when stepping through code in a debugger (prints are immediately
228    * visible). */
229   setvbuf(stdout, NULL, _IONBF, 0);
230
231 #ifdef WIN32
232   /* We delay loading of openmp so we can set the policy here. */
233 #  if defined(_MSC_VER)
234   _putenv_s("OMP_WAIT_POLICY", "PASSIVE");
235 #  endif
236
237   /* Win32 Unicode Args */
238   /* NOTE: cannot use guardedalloc malloc here, as it's not yet initialized
239    *       (it depends on the args passed in, which is what we're getting here!)
240    */
241   {
242     wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
243     argv = malloc(argc * sizeof(char *));
244     for (argv_num = 0; argv_num < argc; argv_num++) {
245       argv[argv_num] = alloc_utf_8_from_16(argv_16[argv_num], 0);
246     }
247     LocalFree(argv_16);
248
249     /* free on early-exit */
250     app_init_data.argv = argv;
251     app_init_data.argv_num = argv_num;
252   }
253 #endif /* WIN32 */
254
255   /* NOTE: Special exception for guarded allocator type switch:
256    *       we need to perform switch from lock-free to fully
257    *       guarded allocator before any allocation happened.
258    */
259   {
260     int i;
261     for (i = 0; i < argc; i++) {
262       if (STR_ELEM(argv[i], "-d", "--debug", "--debug-memory", "--debug-all")) {
263         printf("Switching to fully guarded memory allocator.\n");
264         MEM_use_guarded_allocator();
265         break;
266       }
267       else if (STREQ(argv[i], "--")) {
268         break;
269       }
270     }
271   }
272
273 #ifdef BUILD_DATE
274   {
275     time_t temp_time = build_commit_timestamp;
276     struct tm *tm = gmtime(&temp_time);
277     if (LIKELY(tm)) {
278       strftime(build_commit_date, sizeof(build_commit_date), "%Y-%m-%d", tm);
279       strftime(build_commit_time, sizeof(build_commit_time), "%H:%M", tm);
280     }
281     else {
282       const char *unknown = "date-unknown";
283       BLI_strncpy(build_commit_date, unknown, sizeof(build_commit_date));
284       BLI_strncpy(build_commit_time, unknown, sizeof(build_commit_time));
285     }
286   }
287 #endif
288
289 #ifdef WITH_SDL_DYNLOAD
290   sdlewInit();
291 #endif
292
293   /* Initialize logging */
294   CLG_init();
295   CLG_fatal_fn_set(callback_clg_fatal);
296
297   C = CTX_create();
298
299 #ifdef WITH_PYTHON_MODULE
300 #  ifdef __APPLE__
301   environ = *_NSGetEnviron();
302 #  endif
303
304 #  undef main
305   evil_C = C;
306 #endif
307
308 #ifdef WITH_BINRELOC
309   br_init(NULL);
310 #endif
311
312 #ifdef WITH_LIBMV
313   libmv_initLogging(argv[0]);
314 #elif defined(WITH_CYCLES_LOGGING)
315   CCL_init_logging(argv[0]);
316 #endif
317
318   main_callback_setup();
319
320 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
321   /* patch to ignore argument finder gives us (pid?) */
322   if (argc == 2 && STREQLEN(argv[1], "-psn_", 5)) {
323     extern int GHOST_HACK_getFirstFile(char buf[]);
324     static char firstfilebuf[512];
325
326     argc = 1;
327
328     if (GHOST_HACK_getFirstFile(firstfilebuf)) {
329       argc = 2;
330       argv[1] = firstfilebuf;
331     }
332   }
333 #endif
334
335 #ifdef __FreeBSD__
336   fpsetmask(0);
337 #endif
338
339   /* initialize path to executable */
340   BKE_appdir_program_path_init(argv[0]);
341
342   BLI_threadapi_init();
343   BLI_thread_put_process_on_fast_node();
344
345   DNA_sdna_current_init();
346
347   BKE_blender_globals_init(); /* blender.c */
348
349   IMB_init();
350   BKE_cachefiles_init();
351   BKE_images_init();
352   BKE_modifier_init();
353   BKE_gpencil_modifier_init();
354   BKE_shaderfx_init();
355   DEG_register_node_types();
356
357   BKE_brush_system_init();
358   RE_texture_rng_init();
359
360   BLI_callback_global_init();
361
362   /* first test for background */
363 #ifndef WITH_PYTHON_MODULE
364   ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
365
366   /* ensure we free on early exit */
367   app_init_data.ba = ba;
368
369   main_args_setup(C, ba);
370
371   BLI_argsParse(ba, 1, NULL, NULL);
372
373   main_signal_setup();
374
375 #else
376   /* using preferences or user startup makes no sense for py-as-module */
377   G.factory_startup = true;
378 #endif
379
380 #ifdef WITH_FFMPEG
381   IMB_ffmpeg_init();
382 #endif
383
384   /* after level 1 args, this is so playanim skips RNA init */
385   RNA_init();
386
387   RE_engines_init();
388   init_nodesystem();
389   psys_init_rng();
390   /* end second init */
391
392 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
393   G.background = true; /* python module mode ALWAYS runs in background mode (for now) */
394 #else
395   if (G.background) {
396     main_signal_setup_background();
397   }
398 #endif
399
400   /* background render uses this font too */
401   BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);
402
403   /* Initialize ffmpeg if built in, also needed for background-mode if videos are
404    * rendered via ffmpeg. */
405   BKE_sound_init_once();
406
407   init_def_material();
408
409   if (G.background == 0) {
410 #ifndef WITH_PYTHON_MODULE
411     BLI_argsParse(ba, 2, NULL, NULL);
412     BLI_argsParse(ba, 3, NULL, NULL);
413 #endif
414     WM_init(C, argc, (const char **)argv);
415
416     /* this is properly initialized with user defs, but this is default */
417     /* call after loading the startup.blend so we can read U.tempdir */
418     BKE_tempdir_init(U.tempdir);
419   }
420   else {
421 #ifndef WITH_PYTHON_MODULE
422     BLI_argsParse(ba, 3, NULL, NULL);
423 #endif
424
425     WM_init(C, argc, (const char **)argv);
426
427     /* don't use user preferences temp dir */
428     BKE_tempdir_init(NULL);
429   }
430 #ifdef WITH_PYTHON
431   /**
432    * NOTE: the U.pythondir string is NULL until WM_init() is executed,
433    * so we provide the BPY_ function below to append the user defined
434    * python-dir to Python's sys.path at this point.  Simply putting
435    * WM_init() before #BPY_python_start() crashes Blender at startup.
436    */
437
438   /* TODO - U.pythondir */
439 #else
440   printf(
441       "\n* WARNING * - Blender compiled without Python!\n"
442       "this is not intended for typical usage\n\n");
443 #endif
444
445   CTX_py_init_set(C, true);
446   WM_keyconfig_init(C);
447
448 #ifdef WITH_FREESTYLE
449   /* initialize Freestyle */
450   FRS_initialize();
451   FRS_set_context(C);
452 #endif
453
454   /* OK we are ready for it */
455 #ifndef WITH_PYTHON_MODULE
456   main_args_setup_post(C, ba);
457 #endif
458
459   /* Explicitly free data allocated for argument parsing:
460    * - 'ba'
461    * - 'argv' on WIN32.
462    */
463   callback_main_atexit(&app_init_data);
464   BKE_blender_atexit_unregister(callback_main_atexit, &app_init_data);
465
466   /* paranoid, avoid accidental re-use */
467 #ifndef WITH_PYTHON_MODULE
468   ba = NULL;
469   (void)ba;
470 #endif
471
472 #ifdef WIN32
473   argv = NULL;
474   (void)argv;
475 #endif
476
477 #ifdef WITH_PYTHON_MODULE
478   return 0; /* keep blender in background mode running */
479 #endif
480
481   if (G.background) {
482     /* Using window-manager API in background mode is a bit odd, but works fine. */
483     WM_exit(C);
484   }
485   else {
486     if (!G.file_loaded) {
487       WM_init_splash(C);
488     }
489   }
490
491   WM_main(C);
492
493   return 0;
494 } /* end of int main(argc, argv) */
495
496 #ifdef WITH_PYTHON_MODULE
497 void main_python_exit(void)
498 {
499   WM_exit_ex((bContext *)evil_C, true);
500   evil_C = NULL;
501 }
502 #endif
503
504 /** \} */