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