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