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