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