Purge temporary files on abort
[blender-staging.git] / source / creator / creator.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file creator/creator.c
29  *  \ingroup creator
30  */
31
32
33 #if defined(__linux__) && defined(__GNUC__)
34 #  define _GNU_SOURCE
35 #  include <fenv.h>
36 #endif
37
38 #if (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
39 #  define OSX_SSE_FPE
40 #  include <xmmintrin.h>
41 #endif
42
43 #ifdef WIN32
44 #  if defined(_MSC_VER) && _MSC_VER >= 1800 && defined(_M_X64)
45 #    include <math.h> /* needed for _set_FMA3_enable */
46 #  endif
47 #  include <windows.h>
48 #  include "utfconv.h"
49 #endif
50
51 #include <stdlib.h>
52 #include <stddef.h>
53 #include <string.h>
54 #include <errno.h>
55 #include <time.h>
56
57 /* This little block needed for linking to Blender... */
58
59 #include "MEM_guardedalloc.h"
60
61 #ifdef WIN32
62 #  include "BLI_winstuff.h"
63 #endif
64
65 #include "BLI_args.h"
66 #include "BLI_threads.h"
67 #include "BLI_utildefines.h"
68 #include "BLI_callbacks.h"
69 #include "BLI_blenlib.h"
70 #include "BLI_mempool.h"
71 #include "BLI_system.h"
72 #include BLI_SYSTEM_PID_H
73
74 #include "DNA_ID.h"
75 #include "DNA_scene_types.h"
76 #include "DNA_userdef_types.h"
77
78 #include "BKE_appdir.h"
79 #include "BKE_blender.h"
80 #include "BKE_brush.h"
81 #include "BKE_context.h"
82 #include "BKE_depsgraph.h" /* for DAG_on_visible_update */
83 #include "BKE_font.h"
84 #include "BKE_global.h"
85 #include "BKE_library.h"
86 #include "BKE_main.h"
87 #include "BKE_material.h"
88 #include "BKE_modifier.h"
89 #include "BKE_scene.h"
90 #include "BKE_node.h"
91 #include "BKE_report.h"
92 #include "BKE_sound.h"
93 #include "BKE_image.h"
94 #include "BKE_particle.h"
95
96 #include "IMB_imbuf.h"  /* for IMB_init */
97
98 #ifdef WITH_PYTHON
99 #include "BPY_extern.h"
100 #endif
101
102 #include "RE_engine.h"
103 #include "RE_pipeline.h"
104 #include "RE_render_ext.h"
105
106 #include "ED_datafiles.h"
107 #include "ED_util.h"
108
109 #include "WM_api.h"
110
111 #include "RNA_define.h"
112
113 #include "GPU_draw.h"
114 #include "GPU_extensions.h"
115
116 #ifdef WITH_FREESTYLE
117 #  include "FRS_freestyle.h"
118 #endif
119
120 #ifdef WITH_BUILDINFO_HEADER
121 #  define BUILD_DATE
122 #endif
123
124 /* for passing information between creator and gameengine */
125 #ifdef WITH_GAMEENGINE
126 #  include "BL_System.h"
127 #else /* dummy */
128 #  define SYS_SystemHandle int
129 #endif
130
131 #include <signal.h>
132
133 #ifdef __FreeBSD__
134 #  include <sys/types.h>
135 #  include <floatingpoint.h>
136 #  include <sys/rtprio.h>
137 #endif
138
139 #ifdef WITH_BINRELOC
140 #  include "binreloc.h"
141 #endif
142
143 #ifdef WITH_LIBMV
144 #  include "libmv-capi.h"
145 #endif
146
147 #ifdef WITH_CYCLES_LOGGING
148 #  include "CCL_api.h"
149 #endif
150
151 #ifdef WITH_SDL_DYNLOAD
152 #  include "sdlew.h"
153 #endif
154
155 /* from buildinfo.c */
156 #ifdef BUILD_DATE
157 extern char build_date[];
158 extern char build_time[];
159 extern char build_hash[];
160 extern unsigned long build_commit_timestamp;
161
162 /* TODO(sergey): ideally size need to be in sync with buildinfo.c */
163 extern char build_commit_date[16];
164 extern char build_commit_time[16];
165
166 extern char build_branch[];
167 extern char build_platform[];
168 extern char build_type[];
169 extern char build_cflags[];
170 extern char build_cxxflags[];
171 extern char build_linkflags[];
172 extern char build_system[];
173 #endif
174
175 /*      Local Function prototypes */
176 #ifdef WITH_PYTHON_MODULE
177 int  main_python_enter(int argc, const char **argv);
178 void main_python_exit(void);
179 #else
180 static int print_help(int argc, const char **argv, void *data);
181 static int print_version(int argc, const char **argv, void *data);
182 #endif
183
184 /* for the callbacks: */
185 #ifndef WITH_PYTHON_MODULE
186 #define BLEND_VERSION_FMT         "Blender %d.%02d (sub %d)"
187 #define BLEND_VERSION_ARG         BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION
188 /* pass directly to printf */
189 #define BLEND_VERSION_STRING_FMT  BLEND_VERSION_FMT "\n", BLEND_VERSION_ARG
190 #endif
191
192 /* Initialize callbacks for the modules that need them */
193 static void setCallbacks(void); 
194
195 #ifndef WITH_PYTHON_MODULE
196
197 static bool use_crash_handler = true;
198 static bool use_abort_handler = true;
199
200 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
201 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
202 static void fpe_handler(int UNUSED(sig))
203 {
204         fprintf(stderr, "debug: SIGFPE trapped\n");
205 }
206 #endif
207
208 /* handling ctrl-c event in console */
209 #if !(defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS))
210 static void blender_esc(int sig)
211 {
212         static int count = 0;
213         
214         G.is_break = true;  /* forces render loop to read queue, not sure if its needed */
215         
216         if (sig == 2) {
217                 if (count) {
218                         printf("\nBlender killed\n");
219                         exit(2);
220                 }
221                 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
222                 count++;
223         }
224 }
225 #endif
226
227 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
228 {
229         printf(BLEND_VERSION_STRING_FMT);
230 #ifdef BUILD_DATE
231         printf("\tbuild date: %s\n", build_date);
232         printf("\tbuild time: %s\n", build_time);
233         printf("\tbuild commit date: %s\n", build_commit_date);
234         printf("\tbuild commit time: %s\n", build_commit_time);
235         printf("\tbuild hash: %s\n", build_hash);
236         printf("\tbuild platform: %s\n", build_platform);
237         printf("\tbuild type: %s\n", build_type);
238         printf("\tbuild c flags: %s\n", build_cflags);
239         printf("\tbuild c++ flags: %s\n", build_cxxflags);
240         printf("\tbuild link flags: %s\n", build_linkflags);
241         printf("\tbuild system: %s\n", build_system);
242 #endif
243         exit(0);
244
245         return 0;
246 }
247
248 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
249 {
250         bArgs *ba = (bArgs *)data;
251
252         printf(BLEND_VERSION_STRING_FMT);
253         printf("Usage: blender [args ...] [file] [args ...]\n\n");
254
255         printf("Render Options:\n");
256         BLI_argsPrintArgDoc(ba, "--background");
257         BLI_argsPrintArgDoc(ba, "--render-anim");
258         BLI_argsPrintArgDoc(ba, "--scene");
259         BLI_argsPrintArgDoc(ba, "--render-frame");
260         BLI_argsPrintArgDoc(ba, "--frame-start");
261         BLI_argsPrintArgDoc(ba, "--frame-end");
262         BLI_argsPrintArgDoc(ba, "--frame-jump");
263         BLI_argsPrintArgDoc(ba, "--render-output");
264         BLI_argsPrintArgDoc(ba, "--engine");
265         BLI_argsPrintArgDoc(ba, "--threads");
266         
267         printf("\n");
268         printf("Format Options:\n");
269         BLI_argsPrintArgDoc(ba, "--render-format");
270         BLI_argsPrintArgDoc(ba, "--use-extension");
271
272         printf("\n");
273         printf("Animation Playback Options:\n");
274         BLI_argsPrintArgDoc(ba, "-a");
275                                 
276         printf("\n");
277         printf("Window Options:\n");
278         BLI_argsPrintArgDoc(ba, "--window-border");
279         BLI_argsPrintArgDoc(ba, "--window-borderless");
280         BLI_argsPrintArgDoc(ba, "--window-geometry");
281         BLI_argsPrintArgDoc(ba, "--start-console");
282         BLI_argsPrintArgDoc(ba, "--no-native-pixels");
283
284
285         printf("\n");
286         printf("Game Engine Specific Options:\n");
287         BLI_argsPrintArgDoc(ba, "-g");
288
289         printf("\n");
290         printf("Python Options:\n");
291         BLI_argsPrintArgDoc(ba, "--enable-autoexec");
292         BLI_argsPrintArgDoc(ba, "--disable-autoexec");
293
294         printf("\n");
295
296         BLI_argsPrintArgDoc(ba, "--python");
297         BLI_argsPrintArgDoc(ba, "--python-text");
298         BLI_argsPrintArgDoc(ba, "--python-console");
299         BLI_argsPrintArgDoc(ba, "--addons");
300
301
302         printf("\n");
303         printf("Debug Options:\n");
304         BLI_argsPrintArgDoc(ba, "--debug");
305         BLI_argsPrintArgDoc(ba, "--debug-value");
306
307         printf("\n");
308         BLI_argsPrintArgDoc(ba, "--debug-events");
309 #ifdef WITH_FFMPEG
310         BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
311 #endif
312         BLI_argsPrintArgDoc(ba, "--debug-handlers");
313 #ifdef WITH_LIBMV
314         BLI_argsPrintArgDoc(ba, "--debug-libmv");
315 #endif
316 #ifdef WITH_CYCLES_LOGGING
317         BLI_argsPrintArgDoc(ba, "--debug-cycles");
318 #endif
319         BLI_argsPrintArgDoc(ba, "--debug-memory");
320         BLI_argsPrintArgDoc(ba, "--debug-jobs");
321         BLI_argsPrintArgDoc(ba, "--debug-python");
322         BLI_argsPrintArgDoc(ba, "--debug-depsgraph");
323
324         BLI_argsPrintArgDoc(ba, "--debug-wm");
325         BLI_argsPrintArgDoc(ba, "--debug-all");
326
327         printf("\n");
328         BLI_argsPrintArgDoc(ba, "--debug-fpe");
329         BLI_argsPrintArgDoc(ba, "--disable-crash-handler");
330
331         printf("\n");
332         printf("Misc Options:\n");
333         BLI_argsPrintArgDoc(ba, "--factory-startup");
334         printf("\n");
335         BLI_argsPrintArgDoc(ba, "--env-system-config");
336         BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
337         BLI_argsPrintArgDoc(ba, "--env-system-scripts");
338         BLI_argsPrintArgDoc(ba, "--env-system-python");
339         printf("\n");
340         BLI_argsPrintArgDoc(ba, "-nojoystick");
341         BLI_argsPrintArgDoc(ba, "-noglsl");
342         BLI_argsPrintArgDoc(ba, "-noaudio");
343         BLI_argsPrintArgDoc(ba, "-setaudio");
344
345         printf("\n");
346
347         BLI_argsPrintArgDoc(ba, "--help");
348
349 #ifdef WIN32
350         BLI_argsPrintArgDoc(ba, "-R");
351         BLI_argsPrintArgDoc(ba, "-r");
352 #endif
353         BLI_argsPrintArgDoc(ba, "--version");
354
355         BLI_argsPrintArgDoc(ba, "--");
356
357         printf("Other Options:\n");
358         BLI_argsPrintOtherDoc(ba);
359
360         printf("Argument Parsing:\n");
361         printf("\targuments must be separated by white space. eg\n");
362         printf("\t\t\"blender -ba test.blend\"\n");
363         printf("\t...will ignore the 'a'\n");
364         printf("\t\t\"blender -b test.blend -f8\"\n");
365         printf("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
366
367         printf("Argument Order:\n");
368         printf("\targuments are executed in the order they are given. eg\n");
369         printf("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
370         printf("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
371         printf("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
372         printf("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
373         printf("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
374
375         printf("\nEnvironment Variables:\n");
376         printf("  $BLENDER_USER_CONFIG      Directory for user configuration files.\n");
377         printf("  $BLENDER_USER_SCRIPTS     Directory for user scripts.\n");
378         printf("  $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.\n");
379         printf("  $BLENDER_USER_DATAFILES   Directory for user data files (icons, translations, ..).\n");
380         printf("  $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
381         printf("  $BLENDER_SYSTEM_PYTHON    Directory for system python libraries.\n");
382 #ifdef WIN32
383         printf("  $TEMP                     Store temporary files here.\n");
384 #else
385         printf("  $TMP or $TMPDIR           Store temporary files here.\n");
386 #endif
387 #ifdef WITH_SDL
388         printf("  $SDL_AUDIODRIVER          LibSDL audio driver - alsa, esd, dma.\n");
389 #endif
390         printf("  $PYTHONHOME               Path to the python directory, eg. /usr/lib/python.\n\n");
391
392         exit(0);
393
394         return 0;
395 }
396
397 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
398 {
399         return -1;
400 }
401
402 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
403 {
404         G.f |= G_SCRIPT_AUTOEXEC;
405         G.f |= G_SCRIPT_OVERRIDE_PREF;
406         return 0;
407 }
408
409 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
410 {
411         G.f &= ~G_SCRIPT_AUTOEXEC;
412         G.f |= G_SCRIPT_OVERRIDE_PREF;
413         return 0;
414 }
415
416 static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
417 {
418         use_crash_handler = false;
419         return 0;
420 }
421
422 static int disable_abort_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
423 {
424         use_abort_handler = false;
425         return 0;
426 }
427
428 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
429 {
430         G.background = 1;
431         return 0;
432 }
433
434 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
435 {
436         G.debug |= G_DEBUG;  /* std output printf's */
437         printf(BLEND_VERSION_STRING_FMT);
438         MEM_set_memory_debug();
439 #ifdef DEBUG
440         BLI_mempool_set_memory_debug();
441 #endif
442
443 #ifdef WITH_BUILDINFO
444         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
445 #endif
446
447         BLI_argsPrint(data);
448         return 0;
449 }
450
451 static int debug_mode_generic(int UNUSED(argc), const char **UNUSED(argv), void *data)
452 {
453         G.debug |= GET_INT_FROM_POINTER(data);
454         return 0;
455 }
456
457 #ifdef WITH_LIBMV
458 static int debug_mode_libmv(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
459 {
460         libmv_startDebugLogging();
461
462         return 0;
463 }
464 #endif
465
466 #ifdef WITH_CYCLES_LOGGING
467 static int debug_mode_cycles(int UNUSED(argc), const char **UNUSED(argv),
468                              void *UNUSED(data))
469 {
470         CCL_start_debug_logging();
471         return 0;
472 }
473 #endif
474
475 static int debug_mode_memory(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
476 {
477         MEM_set_memory_debug();
478         return 0;
479 }
480
481 static int set_debug_value(int argc, const char **argv, void *UNUSED(data))
482 {
483         if (argc > 1) {
484                 G.debug_value = atoi(argv[1]);
485
486                 return 1;
487         }
488         else {
489                 printf("\nError: you must specify debug value to set.\n");
490                 return 0;
491         }
492 }
493
494 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
495 {
496 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
497         /* zealous but makes float issues a heck of a lot easier to find!
498          * set breakpoints on fpe_handler */
499         signal(SIGFPE, fpe_handler);
500
501 # if defined(__linux__) && defined(__GNUC__)
502         feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
503 # endif /* defined(__linux__) && defined(__GNUC__) */
504 # if defined(OSX_SSE_FPE)
505         /* OSX uses SSE for floating point by default, so here 
506          * use SSE instructions to throw floating point exceptions */
507         _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK & ~
508                                (_MM_MASK_OVERFLOW | _MM_MASK_INVALID | _MM_MASK_DIV_ZERO));
509 # endif /* OSX_SSE_FPE */
510 # if defined(_WIN32) && defined(_MSC_VER)
511         _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
512         _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
513 # endif /* _WIN32 && _MSC_VER */
514 #endif
515
516         return 0;
517 }
518
519 static void blender_crash_handler_backtrace(FILE *fp)
520 {
521         fputs("\n# backtrace\n", fp);
522         BLI_system_backtrace(fp);
523 }
524
525 static void blender_crash_handler(int signum)
526 {
527
528 #if 0
529         {
530                 char fname[FILE_MAX];
531
532                 if (!G.main->name[0]) {
533                         BLI_make_file_string("/", fname, BKE_tempdir_base(), "crash.blend");
534                 }
535                 else {
536                         BLI_strncpy(fname, G.main->name, sizeof(fname));
537                         BLI_replace_extension(fname, sizeof(fname), ".crash.blend");
538                 }
539
540                 printf("Writing: %s\n", fname);
541                 fflush(stdout);
542
543                 BKE_undo_save_file(fname);
544         }
545 #endif
546
547         FILE *fp;
548         char header[512];
549         wmWindowManager *wm = G.main->wm.first;
550
551         char fname[FILE_MAX];
552
553         if (!G.main->name[0]) {
554                 BLI_join_dirfile(fname, sizeof(fname), BKE_tempdir_base(), "blender.crash.txt");
555         }
556         else {
557                 BLI_join_dirfile(fname, sizeof(fname), BKE_tempdir_base(), BLI_path_basename(G.main->name));
558                 BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
559         }
560
561         printf("Writing: %s\n", fname);
562         fflush(stdout);
563
564 #ifndef BUILD_DATE
565         BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Unknown revision\n", BLEND_VERSION_ARG);
566 #else
567         BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Commit date: %s %s, Hash %s\n",
568                      BLEND_VERSION_ARG, build_commit_date, build_commit_time, build_hash);
569 #endif
570
571         /* open the crash log */
572         errno = 0;
573         fp = BLI_fopen(fname, "wb");
574         if (fp == NULL) {
575                 fprintf(stderr, "Unable to save '%s': %s\n",
576                         fname, errno ? strerror(errno) : "Unknown error opening file");
577         }
578         else {
579                 if (wm) {
580                         BKE_report_write_file_fp(fp, &wm->reports, header);
581                 }
582
583                 blender_crash_handler_backtrace(fp);
584
585                 fclose(fp);
586         }
587
588         /* Delete content of temp dir! */
589         BKE_tempdir_session_purge();
590
591         /* really crash */
592         signal(signum, SIG_DFL);
593 #ifndef WIN32
594         kill(getpid(), signum);
595 #else
596         TerminateProcess(GetCurrentProcess(), signum);
597 #endif
598 }
599
600 static void blender_abort_handler(int UNUSED(signum))
601 {
602         /* Delete content of temp dir! */
603         BKE_tempdir_session_purge();
604 }
605
606 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
607 {
608         G.factory_startup = 1;
609         return 0;
610 }
611
612 static int set_env(int argc, const char **argv, void *UNUSED(data))
613 {
614         /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
615
616         char env[64] = "BLENDER";
617         char *ch_dst = env + 7; /* skip BLENDER */
618         const char *ch_src = argv[0] + 5; /* skip --env */
619
620         if (argc < 2) {
621                 printf("%s requires one argument\n", argv[0]);
622                 exit(1);
623         }
624
625         for (; *ch_src; ch_src++, ch_dst++) {
626                 *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* toupper() */
627         }
628
629         *ch_dst = '\0';
630         BLI_setenv(env, argv[1]);
631         return 1;
632 }
633
634 static int playback_mode(int argc, const char **argv, void *UNUSED(data))
635 {
636         /* not if -b was given first */
637         if (G.background == 0) {
638 #ifdef WITH_FFMPEG
639                 /* Setup FFmpeg with current debug flags. */
640                 IMB_ffmpeg_init();
641 #endif
642
643                 WM_main_playanim(argc, argv); /* not the same argc and argv as before */
644                 exit(0); /* 2.4x didn't do this */
645         }
646
647         return -2;
648 }
649
650 static int prefsize(int argc, const char **argv, void *UNUSED(data))
651 {
652         int stax, stay, sizx, sizy;
653
654         if (argc < 5) {
655                 fprintf(stderr, "-p requires four arguments\n");
656                 exit(1);
657         }
658
659         stax = atoi(argv[1]);
660         stay = atoi(argv[2]);
661         sizx = atoi(argv[3]);
662         sizy = atoi(argv[4]);
663
664         WM_init_state_size_set(stax, stay, sizx, sizy);
665
666         return 4;
667 }
668
669 static int native_pixels(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
670 {
671         WM_init_native_pixels(false);
672         return 0;
673 }
674
675 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
676 {
677         WM_init_state_normal_set();
678         return 0;
679 }
680
681 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
682 {
683         WM_init_state_fullscreen_set();
684         return 0;
685 }
686
687 extern bool wm_start_with_console; /* wm_init_exit.c */
688 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
689 {
690         wm_start_with_console = true;
691         return 0;
692 }
693
694 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
695 {
696 #ifdef WIN32
697         if (data)
698                 G.background = 1;
699         RegisterBlendExtension();
700 #else
701         (void)data; /* unused */
702 #endif
703         return 0;
704 }
705
706 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
707 {
708 #ifndef WITH_GAMEENGINE
709         (void)data;
710 #else
711         SYS_SystemHandle *syshandle = data;
712
713         /**
714          * don't initialize joysticks if user doesn't want to use joysticks
715          * failed joystick initialization delays over 5 seconds, before game engine start
716          */
717         SYS_WriteCommandLineInt(*syshandle, "nojoystick", 1);
718         if (G.debug & G_DEBUG) printf("disabling nojoystick\n");
719 #endif
720
721         return 0;
722 }
723
724 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
725 {
726         GPU_extensions_disable();
727         return 0;
728 }
729
730 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
731 {
732         sound_force_device(0);
733         return 0;
734 }
735
736 static int set_audio(int argc, const char **argv, void *UNUSED(data))
737 {
738         if (argc < 1) {
739                 fprintf(stderr, "-setaudio require one argument\n");
740                 exit(1);
741         }
742
743         sound_force_device(sound_define_from_str(argv[1]));
744         return 1;
745 }
746
747 static int set_output(int argc, const char **argv, void *data)
748 {
749         bContext *C = data;
750         if (argc > 1) {
751                 Scene *scene = CTX_data_scene(C);
752                 if (scene) {
753                         BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
754                 }
755                 else {
756                         printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
757                 }
758                 return 1;
759         }
760         else {
761                 printf("\nError: you must specify a path after '-o  / --render-output'.\n");
762                 return 0;
763         }
764 }
765
766 static int set_engine(int argc, const char **argv, void *data)
767 {
768         bContext *C = data;
769         if (argc >= 2) {
770                 if (STREQ(argv[1], "help")) {
771                         RenderEngineType *type = NULL;
772                         printf("Blender Engine Listing:\n");
773                         for (type = R_engines.first; type; type = type->next) {
774                                 printf("\t%s\n", type->idname);
775                         }
776                         exit(0);
777                 }
778                 else {
779                         Scene *scene = CTX_data_scene(C);
780                         if (scene) {
781                                 RenderData *rd = &scene->r;
782
783                                 if (BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
784                                         BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
785                                 }
786                                 else {
787                                         printf("\nError: engine not found '%s'\n", argv[1]);
788                                         exit(1);
789                                 }
790                         }
791                         else {
792                                 printf("\nError: no blend loaded. order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
793                         }
794                 }
795
796                 return 1;
797         }
798         else {
799                 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
800                 return 0;
801         }
802 }
803
804 static int set_image_type(int argc, const char **argv, void *data)
805 {
806         bContext *C = data;
807         if (argc > 1) {
808                 const char *imtype = argv[1];
809                 Scene *scene = CTX_data_scene(C);
810                 if (scene) {
811                         const char imtype_new = BKE_imtype_from_arg(imtype);
812
813                         if (imtype_new == R_IMF_IMTYPE_INVALID) {
814                                 printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
815                         }
816                         else {
817                                 scene->r.im_format.imtype = imtype_new;
818                         }
819                 }
820                 else {
821                         printf("\nError: no blend loaded. order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
822                 }
823                 return 1;
824         }
825         else {
826                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
827                 return 0;
828         }
829 }
830
831 static int set_threads(int argc, const char **argv, void *UNUSED(data))
832 {
833         if (argc > 1) {
834                 int threads = atoi(argv[1]);
835
836                 if (threads >= 0 && threads <= BLENDER_MAX_THREADS) {
837                         BLI_system_num_threads_override_set(threads);
838                 }
839                 else {
840                         printf("Error, threads has to be in range 0-%d\n", BLENDER_MAX_THREADS);
841                 }
842                 return 1;
843         }
844         else {
845                 printf("\nError: you must specify a number of threads between 0 and %d '-t / --threads'.\n", BLENDER_MAX_THREADS);
846                 return 0;
847         }
848 }
849
850 static int set_verbosity(int argc, const char **argv, void *UNUSED(data))
851 {
852         if (argc > 1) {
853                 int level = atoi(argv[1]);
854
855 #ifdef WITH_LIBMV
856                 libmv_setLoggingVerbosity(level);
857 #elif defined(WITH_CYCLES_LOGGING)
858                 CCL_logging_verbosity_set(level);
859 #else
860                 (void)level;
861 #endif
862
863                 return 1;
864         }
865         else {
866                 printf("\nError: you must specify a verbosity level.\n");
867                 return 0;
868         }
869 }
870
871 static int set_extension(int argc, const char **argv, void *data)
872 {
873         bContext *C = data;
874         if (argc > 1) {
875                 Scene *scene = CTX_data_scene(C);
876                 if (scene) {
877                         if (argv[1][0] == '0') {
878                                 scene->r.scemode &= ~R_EXTENSION;
879                         }
880                         else if (argv[1][0] == '1') {
881                                 scene->r.scemode |= R_EXTENSION;
882                         }
883                         else {
884                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
885                         }
886                 }
887                 else {
888                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
889                 }
890                 return 1;
891         }
892         else {
893                 printf("\nError: you must specify a path after '- '.\n");
894                 return 0;
895         }
896 }
897
898 static int set_ge_parameters(int argc, const char **argv, void *data)
899 {
900         int a = 0;
901 #ifdef WITH_GAMEENGINE
902         SYS_SystemHandle syshandle = *(SYS_SystemHandle *)data;
903 #else
904         (void)data;
905 #endif
906
907         /**
908          * gameengine parameters are automatically put into system
909          * -g [paramname = value]
910          * -g [boolparamname]
911          * example:
912          * -g novertexarrays
913          * -g maxvertexarraysize = 512
914          */
915
916         if (argc >= 1) {
917                 const char *paramname = argv[a];
918                 /* check for single value versus assignment */
919                 if (a + 1 < argc && (*(argv[a + 1]) == '=')) {
920                         a++;
921                         if (a + 1 < argc) {
922                                 a++;
923                                 /* assignment */
924 #ifdef WITH_GAMEENGINE
925                                 SYS_WriteCommandLineString(syshandle, paramname, argv[a]);
926 #endif
927                         }
928                         else {
929                                 printf("error: argument assignment (%s) without value.\n", paramname);
930                                 return 0;
931                         }
932                         /* name arg eaten */
933
934                 }
935                 else {
936 #ifdef WITH_GAMEENGINE
937                         SYS_WriteCommandLineInt(syshandle, argv[a], 1);
938 #endif
939                         /* doMipMap */
940                         if (STREQ(argv[a], "nomipmap")) {
941                                 GPU_set_mipmap(0); //doMipMap = 0;
942                         }
943                         /* linearMipMap */
944                         if (STREQ(argv[a], "linearmipmap")) {
945                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
946                         }
947
948
949                 } /* if (*(argv[a + 1]) == '=') */
950         }
951
952         return a;
953 }
954
955 static int render_frame(int argc, const char **argv, void *data)
956 {
957         bContext *C = data;
958         Scene *scene = CTX_data_scene(C);
959         if (scene) {
960                 Main *bmain = CTX_data_main(C);
961
962                 if (argc > 1) {
963                         Render *re = RE_NewRender(scene->id.name);
964                         int frame;
965                         ReportList reports;
966
967                         switch (*argv[1]) {
968                                 case '+':
969                                         frame = scene->r.sfra + atoi(argv[1] + 1);
970                                         break;
971                                 case '-':
972                                         frame = (scene->r.efra - atoi(argv[1] + 1)) + 1;
973                                         break;
974                                 default:
975                                         frame = atoi(argv[1]);
976                                         break;
977                         }
978
979                         BLI_begin_threaded_malloc();
980                         BKE_reports_init(&reports, RPT_PRINT);
981
982                         frame = CLAMPIS(frame, MINAFRAME, MAXFRAME);
983
984                         RE_SetReports(re, &reports);
985                         RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
986                         RE_SetReports(re, NULL);
987                         BLI_end_threaded_malloc();
988                         return 1;
989                 }
990                 else {
991                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
992                         return 0;
993                 }
994         }
995         else {
996                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
997                 return 0;
998         }
999 }
1000
1001 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
1002 {
1003         bContext *C = data;
1004         Scene *scene = CTX_data_scene(C);
1005         if (scene) {
1006                 Main *bmain = CTX_data_main(C);
1007                 Render *re = RE_NewRender(scene->id.name);
1008                 ReportList reports;
1009                 BLI_begin_threaded_malloc();
1010                 BKE_reports_init(&reports, RPT_PRINT);
1011                 RE_SetReports(re, &reports);
1012                 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
1013                 RE_SetReports(re, NULL);
1014                 BLI_end_threaded_malloc();
1015         }
1016         else {
1017                 printf("\nError: no blend loaded. cannot use '-a'.\n");
1018         }
1019         return 0;
1020 }
1021
1022 static int set_scene(int argc, const char **argv, void *data)
1023 {
1024         if (argc > 1) {
1025                 bContext *C = data;
1026                 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
1027                 if (scene) {
1028                         CTX_data_scene_set(C, scene);
1029                 }
1030                 return 1;
1031         }
1032         else {
1033                 printf("\nError: Scene name must follow '-S / --scene'.\n");
1034                 return 0;
1035         }
1036 }
1037
1038 static int set_start_frame(int argc, const char **argv, void *data)
1039 {
1040         bContext *C = data;
1041         Scene *scene = CTX_data_scene(C);
1042         if (scene) {
1043                 if (argc > 1) {
1044                         int frame = atoi(argv[1]);
1045                         (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
1046                         return 1;
1047                 }
1048                 else {
1049                         printf("\nError: frame number must follow '-s / --frame-start'.\n");
1050                         return 0;
1051                 }
1052         }
1053         else {
1054                 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
1055                 return 0;
1056         }
1057 }
1058
1059 static int set_end_frame(int argc, const char **argv, void *data)
1060 {
1061         bContext *C = data;
1062         Scene *scene = CTX_data_scene(C);
1063         if (scene) {
1064                 if (argc > 1) {
1065                         int frame = atoi(argv[1]);
1066                         (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
1067                         return 1;
1068                 }
1069                 else {
1070                         printf("\nError: frame number must follow '-e / --frame-end'.\n");
1071                         return 0;
1072                 }
1073         }
1074         else {
1075                 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
1076                 return 0;
1077         }
1078 }
1079
1080 static int set_skip_frame(int argc, const char **argv, void *data)
1081 {
1082         bContext *C = data;
1083         Scene *scene = CTX_data_scene(C);
1084         if (scene) {
1085                 if (argc > 1) {
1086                         int frame = atoi(argv[1]);
1087                         (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
1088                         return 1;
1089                 }
1090                 else {
1091                         printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
1092                         return 0;
1093                 }
1094         }
1095         else {
1096                 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
1097                 return 0;
1098         }
1099 }
1100
1101 /* macro for ugly context setup/reset */
1102 #ifdef WITH_PYTHON
1103 #define BPY_CTX_SETUP(_cmd)                                                   \
1104         {                                                                         \
1105                 wmWindowManager *wm = CTX_wm_manager(C);                              \
1106                 wmWindow *prevwin = CTX_wm_window(C);                                 \
1107                 Scene *prevscene = CTX_data_scene(C);                                 \
1108                 if (wm->windows.first) {                                              \
1109                         CTX_wm_window_set(C, wm->windows.first);                          \
1110                         _cmd;                                                             \
1111                         CTX_wm_window_set(C, prevwin);                                    \
1112                 }                                                                     \
1113                 else {                                                                \
1114                         fprintf(stderr, "Python script \"%s\" "                           \
1115                                 "running with missing context data.\n", argv[1]);         \
1116                         _cmd;                                                             \
1117                 }                                                                     \
1118                 CTX_data_scene_set(C, prevscene);                                     \
1119         } (void)0                                                                 \
1120
1121 #endif /* WITH_PYTHON */
1122
1123 static int run_python_file(int argc, const char **argv, void *data)
1124 {
1125 #ifdef WITH_PYTHON
1126         bContext *C = data;
1127
1128         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1129         if (argc > 1) {
1130                 /* Make the path absolute because its needed for relative linked blends to be found */
1131                 char filename[FILE_MAX];
1132                 BLI_strncpy(filename, argv[1], sizeof(filename));
1133                 BLI_path_cwd(filename);
1134
1135                 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL));
1136
1137                 return 1;
1138         }
1139         else {
1140                 printf("\nError: you must specify a filepath after '%s'.\n", argv[0]);
1141                 return 0;
1142         }
1143 #else
1144         UNUSED_VARS(argc, argv, data);
1145         printf("This blender was built without python support\n");
1146         return 0;
1147 #endif /* WITH_PYTHON */
1148 }
1149
1150 static int run_python_text(int argc, const char **argv, void *data)
1151 {
1152 #ifdef WITH_PYTHON
1153         bContext *C = data;
1154
1155         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1156         if (argc > 1) {
1157                 /* Make the path absolute because its needed for relative linked blends to be found */
1158                 struct Text *text = (struct Text *)BKE_libblock_find_name(ID_TXT, argv[1]);
1159
1160                 if (text) {
1161                         BPY_CTX_SETUP(BPY_text_exec(C, text, NULL, false));
1162                         return 1;
1163                 }
1164                 else {
1165                         printf("\nError: text block not found %s.\n", argv[1]);
1166                         return 1;
1167                 }
1168         }
1169         else {
1170                 printf("\nError: you must specify a text block after '%s'.\n", argv[0]);
1171                 return 0;
1172         }
1173 #else
1174         UNUSED_VARS(argc, argv, data);
1175         printf("This blender was built without python support\n");
1176         return 0;
1177 #endif /* WITH_PYTHON */
1178 }
1179
1180 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
1181 {
1182 #ifdef WITH_PYTHON
1183         bContext *C = data;
1184
1185         BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"));
1186
1187         return 0;
1188 #else
1189         UNUSED_VARS(argv, data);
1190         printf("This blender was built without python support\n");
1191         return 0;
1192 #endif /* WITH_PYTHON */
1193 }
1194
1195 static int set_addons(int argc, const char **argv, void *data)
1196 {
1197         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1198         if (argc > 1) {
1199 #ifdef WITH_PYTHON
1200                 const int slen = strlen(argv[1]) + 128;
1201                 char *str = malloc(slen);
1202                 bContext *C = data;
1203                 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
1204                 BPY_CTX_SETUP(BPY_string_exec(C, str));
1205                 free(str);
1206 #else
1207                 UNUSED_VARS(argv, data);
1208 #endif /* WITH_PYTHON */
1209                 return 1;
1210         }
1211         else {
1212                 printf("\nError: you must specify a comma separated list after '--addons'.\n");
1213                 return 0;
1214         }
1215 }
1216
1217 static int load_file(int UNUSED(argc), const char **argv, void *data)
1218 {
1219         bContext *C = data;
1220
1221         /* Make the path absolute because its needed for relative linked blends to be found */
1222         char filename[FILE_MAX];
1223
1224         /* note, we could skip these, but so far we always tried to load these files */
1225         if (argv[0][0] == '-') {
1226                 fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
1227         }
1228
1229         BLI_strncpy(filename, argv[0], sizeof(filename));
1230         BLI_path_cwd(filename);
1231
1232         if (G.background) {
1233                 int retval;
1234
1235                 BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE);
1236
1237                 retval = BKE_read_file(C, filename, NULL);
1238
1239                 /* we successfully loaded a blend file, get sure that
1240                  * pointcache works */
1241                 if (retval != BKE_READ_FILE_FAIL) {
1242                         wmWindowManager *wm = CTX_wm_manager(C);
1243                         Main *bmain = CTX_data_main(C);
1244
1245                         /* special case, 2.4x files */
1246                         if (wm == NULL && BLI_listbase_is_empty(&bmain->wm)) {
1247                                 extern void wm_add_default(bContext *C);
1248
1249                                 /* wm_add_default() needs the screen to be set. */
1250                                 CTX_wm_screen_set(C, bmain->screen.first);
1251                                 wm_add_default(C);
1252                         }
1253
1254                         CTX_wm_manager_set(C, NULL); /* remove wm to force check */
1255                         WM_check(C);
1256                         if (bmain->name[0]) {
1257                                 G.save_over = 1;
1258                                 G.relbase_valid = 1;
1259                         }
1260                         else {
1261                                 G.save_over = 0;
1262                                 G.relbase_valid = 0;
1263                         }
1264                         if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm);  /* reset wm */
1265
1266                         /* WM_file_read would call normally */
1267                         ED_editors_init(C);
1268                         DAG_on_visible_update(bmain, true);
1269                         BKE_scene_update_tagged(bmain->eval_ctx, bmain, CTX_data_scene(C));
1270                 }
1271                 else {
1272                         /* failed to load file, stop processing arguments */
1273                         return -1;
1274                 }
1275
1276                 /* WM_file_read() runs normally but since we're in background mode do here */
1277 #ifdef WITH_PYTHON
1278                 /* run any texts that were loaded in and flagged as modules */
1279                 BPY_python_reset(C);
1280 #endif
1281
1282                 BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST);
1283
1284                 /* happens for the UI on file reading too (huh? (ton))*/
1285                 // XXX          BKE_reset_undo();
1286                 //                      BKE_write_undo("original");     /* save current state */
1287         }
1288         else {
1289                 /* we are not running in background mode here, but start blender in UI mode with
1290                  * a file - this should do everything a 'load file' does */
1291                 ReportList reports;
1292                 BKE_reports_init(&reports, RPT_PRINT);
1293                 WM_file_autoexec_init(filename);
1294                 WM_file_read(C, filename, &reports);
1295                 BKE_reports_clear(&reports);
1296         }
1297
1298         G.file_loaded = 1;
1299
1300         return 0;
1301 }
1302
1303 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1304 {
1305         static char output_doc[] = "<path>"
1306                 "\n\tSet the render path and file name."
1307                 "\n\tUse // at the start of the path to"
1308                 "\n\t\trender relative to the blend file."
1309                 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1310                 "\n\t\tani_##_test.png becomes ani_01_test.png"
1311                 "\n\t\ttest-######.png becomes test-000001.png"
1312                 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1313                 "\n\tThe frame number will be added at the end of the filename."
1314                 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1315                 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1316
1317         static char format_doc[] = "<format>"
1318                 "\n\tSet the render format, Valid options are..."
1319                 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1320                 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1321                 "\n\t(formats that can be compiled into blender, not available on all systems)"
1322                 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1323
1324         static char playback_doc[] = "<options> <file(s)>"
1325                 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1326                 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1327                 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1328                 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1329                 "\n\t\t-j <frame>\tSet frame step to <frame>"
1330                 "\n\t\t-s <frame>\tPlay from <frame>"
1331                 "\n\t\t-e <frame>\tPlay until <frame>";
1332
1333         static char game_doc[] = "Game Engine specific options"
1334                 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1335                 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1336                 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1337                 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1338
1339         static char debug_doc[] = "\n\tTurn debugging on\n"
1340                 "\n\t* Prints every operator call and their arguments"
1341                 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1342                 "\n\t* Keeps python sys.stdin rather than setting it to None";
1343
1344         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1345
1346         /* end argument processing after -- */
1347         BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1348
1349         /* first pass: background mode, disable python and commands that exit after usage */
1350         BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1351         /* Windows only */
1352         BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1353
1354         BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1355         
1356         /* only to give help message */
1357 #ifndef WITH_PYTHON_SECURITY /* default */
1358 #  define   PY_ENABLE_AUTO ", (default)"
1359 #  define   PY_DISABLE_AUTO ""
1360 #else
1361 #  define   PY_ENABLE_AUTO ""
1362 #  define   PY_DISABLE_AUTO ", (compiled as non-standard default)"
1363 #endif
1364
1365         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1366         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
1367
1368         BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL);
1369         BLI_argsAdd(ba, 1, NULL, "--disable-abort-handler", "\n\tDisable the abort handler", disable_abort_handler, NULL);
1370
1371 #undef PY_ENABLE_AUTO
1372 #undef PY_DISABLE_AUTO
1373         
1374         BLI_argsAdd(ba, 1, "-b", "--background", "\n\tRun in background (often used for UI-less rendering)", background_mode, NULL);
1375
1376         BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1377
1378         BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1379
1380 #ifdef WITH_FFMPEG
1381         BLI_argsAdd(ba, 1, NULL, "--debug-ffmpeg", "\n\tEnable debug messages from FFmpeg library", debug_mode_generic, (void *)G_DEBUG_FFMPEG);
1382 #endif
1383
1384 #ifdef WITH_FREESTYLE
1385         BLI_argsAdd(ba, 1, NULL, "--debug-freestyle", "\n\tEnable debug/profiling messages from Freestyle rendering", debug_mode_generic, (void *)G_DEBUG_FREESTYLE);
1386 #endif
1387
1388         BLI_argsAdd(ba, 1, NULL, "--debug-python", "\n\tEnable debug messages for python", debug_mode_generic, (void *)G_DEBUG_PYTHON);
1389         BLI_argsAdd(ba, 1, NULL, "--debug-events", "\n\tEnable debug messages for the event system", debug_mode_generic, (void *)G_DEBUG_EVENTS);
1390         BLI_argsAdd(ba, 1, NULL, "--debug-handlers", "\n\tEnable debug messages for event handling", debug_mode_generic, (void *)G_DEBUG_HANDLERS);
1391         BLI_argsAdd(ba, 1, NULL, "--debug-wm",     "\n\tEnable debug messages for the window manager", debug_mode_generic, (void *)G_DEBUG_WM);
1392         BLI_argsAdd(ba, 1, NULL, "--debug-all",    "\n\tEnable all debug messages (excludes libmv)", debug_mode_generic, (void *)G_DEBUG_ALL);
1393
1394         BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1395
1396 #ifdef WITH_LIBMV
1397         BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
1398 #endif
1399 #ifdef WITH_CYCLES_LOGGING
1400         BLI_argsAdd(ba, 1, NULL, "--debug-cycles", "\n\tEnable debug messages from Cycles", debug_mode_cycles, NULL);
1401 #endif
1402         BLI_argsAdd(ba, 1, NULL, "--debug-memory", "\n\tEnable fully guarded memory allocation and debugging", debug_mode_memory, NULL);
1403
1404         BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
1405         BLI_argsAdd(ba, 1, NULL, "--debug-jobs",  "\n\tEnable time profiling for background jobs.", debug_mode_generic, (void *)G_DEBUG_JOBS);
1406         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph", "\n\tEnable debug messages from dependency graph", debug_mode_generic, (void *)G_DEBUG_DEPSGRAPH);
1407
1408         BLI_argsAdd(ba, 1, NULL, "--verbose", "<verbose>\n\tSet logging verbosity level.", set_verbosity, NULL);
1409
1410         BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY (BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1411
1412         /* TODO, add user env vars? */
1413         BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles",  "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1414         BLI_argsAdd(ba, 1, NULL, "--env-system-scripts",    "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1415         BLI_argsAdd(ba, 1, NULL, "--env-system-python",     "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1416
1417         /* second pass: custom window stuff */
1418         BLI_argsAdd(ba, 2, "-p", "--window-geometry", "<sx> <sy> <w> <h>\n\tOpen with lower left corner at <sx>, <sy> and width and height as <w>, <h>", prefsize, NULL);
1419         BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1420         BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1421         BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set), (Windows only)", start_with_console, NULL);
1422         BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1423         BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1424         BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", "\n\tDo not use native pixel size, for high resolution displays (MacBook 'Retina')", native_pixels, ba);
1425
1426         /* third pass: disabling things and forcing settings */
1427         BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1428         BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1429         BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1430         BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1431
1432         /* fourth pass: processing arguments */
1433         BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1434         BLI_argsAdd(ba, 4, "-f", "--render-frame", "<frame>\n\tRender frame <frame> and save it.\n\t+<frame> start frame relative, -<frame> end frame relative.", render_frame, C);
1435         BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1436         BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1437         BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1438         BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1439         BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1440         BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script file", run_python_file, C);
1441         BLI_argsAdd(ba, 4, NULL, "--python-text", "<name>\n\tRun the given Python script text block", run_python_text, C);
1442         BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1443         BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1444
1445         BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1446         BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1447
1448         BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1449         BLI_argsAdd(ba, 4, "-t", "--threads", "<threads>\n\tUse amount of <threads> for rendering and other operations\n\t[1-" STRINGIFY(BLENDER_MAX_THREADS) "], 0 for systems processor count.", set_threads, NULL);
1450         BLI_argsAdd(ba, 4, "-x", "--use-extension", "<bool>\n\tSet option to add the file extension to the end of the file", set_extension, C);
1451
1452 }
1453 #endif /* WITH_PYTHON_MODULE */
1454
1455 #ifdef WITH_PYTHON_MODULE
1456 /* allow python module to call main */
1457 #  define main main_python_enter
1458 static void *evil_C = NULL;
1459
1460 #  ifdef __APPLE__
1461      /* environ is not available in mac shared libraries */
1462 #    include <crt_externs.h>
1463 char **environ = NULL;
1464 #  endif
1465 #endif
1466
1467 /**
1468  * Blender's main function responsabilities are:
1469  * - setup subsystems.
1470  * - handle arguments.
1471  * - run WM_main() event loop,
1472  *   or exit when running in background mode.
1473  */
1474 int main(
1475        int argc,
1476 #ifdef WIN32
1477         const char **UNUSED(argv_c)
1478 #else
1479         const char **argv
1480 #endif
1481          )
1482 {
1483         bContext *C;
1484         SYS_SystemHandle syshandle;
1485
1486 #ifndef WITH_PYTHON_MODULE
1487         bArgs *ba;
1488 #endif
1489
1490 #ifdef WIN32
1491         /* FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it. */
1492 #  if defined(_MSC_VER) && _MSC_VER >= 1800 && defined(_M_X64)
1493         _set_FMA3_enable(0);
1494 #  endif
1495
1496         /* Win32 Unicode Args */
1497         /* NOTE: cannot use guardedalloc malloc here, as it's not yet initialized
1498          *       (it depends on the args passed in, which is what we're getting here!)
1499          */
1500         wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
1501         char **argv = malloc(argc * sizeof(char *));
1502         int argci = 0;
1503         
1504         for (argci = 0; argci < argc; argci++) {
1505                 argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0);
1506         }
1507         
1508         LocalFree(argv_16);
1509 #endif
1510
1511         /* NOTE: Special exception for guarded allocator type switch:
1512          *       we need to perform switch from lock-free to fully
1513          *       guarded allocator before any allocation happened.
1514          */
1515         {
1516                 int i;
1517                 for (i = 0; i < argc; i++) {
1518                         if (STREQ(argv[i], "--debug") || STREQ(argv[i], "-d") ||
1519                             STREQ(argv[i], "--debug-memory"))
1520                         {
1521                                 printf("Switching to fully guarded memory allocator.\n");
1522                                 MEM_use_guarded_allocator();
1523                                 break;
1524                         }
1525                         else if (STREQ(argv[i], "--")) {
1526                                 break;
1527                         }
1528                 }
1529         }
1530
1531 #ifdef BUILD_DATE
1532         {
1533                 time_t temp_time = build_commit_timestamp;
1534                 struct tm *tm = gmtime(&temp_time);
1535                 if (LIKELY(tm)) {
1536                         strftime(build_commit_date, sizeof(build_commit_date), "%Y-%m-%d", tm);
1537                         strftime(build_commit_time, sizeof(build_commit_time), "%H:%M", tm);
1538                 }
1539                 else {
1540                         const char *unknown = "date-unknown";
1541                         BLI_strncpy(build_commit_date, unknown, sizeof(build_commit_date));
1542                         BLI_strncpy(build_commit_time, unknown, sizeof(build_commit_time));
1543                 }
1544         }
1545 #endif
1546
1547 #ifdef WITH_SDL_DYNLOAD
1548         sdlewInit();
1549 #endif
1550
1551         C = CTX_create();
1552
1553 #ifdef WITH_PYTHON_MODULE
1554 #ifdef __APPLE__
1555         environ = *_NSGetEnviron();
1556 #endif
1557
1558 #undef main
1559         evil_C = C;
1560 #endif
1561
1562
1563
1564 #ifdef WITH_BINRELOC
1565         br_init(NULL);
1566 #endif
1567
1568 #ifdef WITH_LIBMV
1569         libmv_initLogging(argv[0]);
1570 #elif defined(WITH_CYCLES_LOGGING)
1571         CCL_init_logging(argv[0]);
1572 #endif
1573
1574         setCallbacks();
1575         
1576 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
1577 /* patch to ignore argument finder gives us (pid?) */
1578         if (argc == 2 && STREQLEN(argv[1], "-psn_", 5)) {
1579                 extern int GHOST_HACK_getFirstFile(char buf[]);
1580                 static char firstfilebuf[512];
1581
1582                 argc = 1;
1583
1584                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1585                         argc = 2;
1586                         argv[1] = firstfilebuf;
1587                 }
1588         }
1589 #endif
1590         
1591 #ifdef __FreeBSD__
1592         fpsetmask(0);
1593 #endif
1594
1595         /* initialize path to executable */
1596         BKE_appdir_program_path_init(argv[0]);
1597
1598         BLI_threadapi_init();
1599
1600         initglobals();  /* blender.c */
1601
1602         IMB_init();
1603         BKE_images_init();
1604         BKE_modifier_init();
1605         DAG_init();
1606
1607         BKE_brush_system_init();
1608         RE_init_texture_rng();
1609         
1610
1611         BLI_callback_global_init();
1612
1613 #ifdef WITH_GAMEENGINE
1614         syshandle = SYS_GetSystem();
1615 #else
1616         syshandle = 0;
1617 #endif
1618
1619         /* first test for background */
1620 #ifndef WITH_PYTHON_MODULE
1621         ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
1622         setupArguments(C, ba, &syshandle);
1623
1624         BLI_argsParse(ba, 1, NULL, NULL);
1625
1626         if (use_crash_handler) {
1627                 /* after parsing args */
1628                 signal(SIGSEGV, blender_crash_handler);
1629         }
1630
1631         if (use_abort_handler) {
1632                 signal(SIGABRT, blender_abort_handler);
1633         }
1634 #else
1635         G.factory_startup = true;  /* using preferences or user startup makes no sense for py-as-module */
1636         (void)syshandle;
1637 #endif
1638
1639 #ifdef WITH_FFMPEG
1640         IMB_ffmpeg_init();
1641 #endif
1642
1643         /* after level 1 args, this is so playanim skips RNA init */
1644         RNA_init();
1645
1646         RE_engines_init();
1647         init_nodesystem();
1648         psys_init_rng();
1649         /* end second init */
1650
1651
1652 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1653         G.background = true; /* python module mode ALWAYS runs in background mode (for now) */
1654 #else
1655         /* for all platforms, even windos has it! */
1656         if (G.background) {
1657                 signal(SIGINT, blender_esc);  /* ctrl c out bg render */
1658         }
1659 #endif
1660
1661         /* background render uses this font too */
1662         BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);
1663
1664         /* Initialize ffmpeg if built in, also needed for bg mode if videos are
1665          * rendered via ffmpeg */
1666         sound_init_once();
1667         
1668         init_def_material();
1669
1670         if (G.background == 0) {
1671 #ifndef WITH_PYTHON_MODULE
1672                 BLI_argsParse(ba, 2, NULL, NULL);
1673                 BLI_argsParse(ba, 3, NULL, NULL);
1674 #endif
1675                 WM_init(C, argc, (const char **)argv);
1676
1677                 /* this is properly initialized with user defs, but this is default */
1678                 /* call after loading the startup.blend so we can read U.tempdir */
1679                 BKE_tempdir_init(U.tempdir);
1680         }
1681         else {
1682 #ifndef WITH_PYTHON_MODULE
1683                 BLI_argsParse(ba, 3, NULL, NULL);
1684 #endif
1685
1686                 WM_init(C, argc, (const char **)argv);
1687
1688                 /* don't use user preferences temp dir */
1689                 BKE_tempdir_init(NULL);
1690         }
1691 #ifdef WITH_PYTHON
1692         /**
1693          * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1694          * so we provide the BPY_ function below to append the user defined
1695          * python-dir to Python's sys.path at this point.  Simply putting
1696          * WM_init() before #BPY_python_start() crashes Blender at startup.
1697          */
1698
1699         /* TODO - U.pythondir */
1700 #else
1701         printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1702 #endif
1703         
1704         CTX_py_init_set(C, 1);
1705         WM_keymap_init(C);
1706
1707 #ifdef WITH_FREESTYLE
1708         /* initialize Freestyle */
1709         FRS_initialize();
1710         FRS_set_context(C);
1711 #endif
1712
1713         /* OK we are ready for it */
1714 #ifndef WITH_PYTHON_MODULE
1715         BLI_argsParse(ba, 4, load_file, C);
1716         
1717         if (G.background == 0) {
1718                 if (!G.file_loaded)
1719                         if (U.uiflag2 & USER_KEEP_SESSION)
1720                                 WM_recover_last_session(C, NULL);
1721         }
1722
1723 #endif
1724
1725 #ifndef WITH_PYTHON_MODULE
1726         BLI_argsFree(ba);
1727 #endif
1728
1729 #ifdef WIN32
1730         while (argci) {
1731                 free(argv[--argci]);
1732         }
1733         free(argv);
1734         argv = NULL;
1735 #endif
1736
1737 #ifdef WITH_PYTHON_MODULE
1738         return 0; /* keep blender in background mode running */
1739 #endif
1740
1741         if (G.background) {
1742                 /* actually incorrect, but works for now (ton) */
1743                 WM_exit(C);
1744         }
1745         else {
1746                 if (G.fileflags & G_FILE_AUTOPLAY) {
1747                         if (G.f & G_SCRIPT_AUTOEXEC) {
1748                                 if (WM_init_game(C)) {
1749                                         return 0;
1750                                 }
1751                         }
1752                         else {
1753                                 if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
1754                                         G.f |= G_SCRIPT_AUTOEXEC_FAIL;
1755                                         BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Game AutoStart");
1756                                 }
1757                         }
1758                 }
1759
1760                 if (!G.file_loaded) {
1761                         WM_init_splash(C);
1762                 }
1763         }
1764
1765         WM_main(C);
1766
1767         return 0;
1768 } /* end of int main(argc, argv)        */
1769
1770 #ifdef WITH_PYTHON_MODULE
1771 void main_python_exit(void)
1772 {
1773         WM_exit_ext((bContext *)evil_C, true);
1774         evil_C = NULL;
1775 }
1776 #endif
1777
1778 static void mem_error_cb(const char *errorStr)
1779 {
1780         fputs(errorStr, stderr);
1781         fflush(stderr);
1782 }
1783
1784 static void setCallbacks(void)
1785 {
1786         /* Error output from the alloc routines: */
1787         MEM_set_error_callback(mem_error_cb);
1788 }