/* in case UserDef was read, we re-initialize all, and do versioning */ static void wm_init_userdef(bContext *C, const bool from_memory) { /* versioning is here */ UI_init_userdef(); MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024); sound_init(CTX_data_main(C)); /* needed so loading a file from the command line respects user-pref [#26156] */ if (U.flag & USER_FILENOUI) G.fileflags |= G_FILE_NO_UI; else G.fileflags &= ~G_FILE_NO_UI; /* set the python auto-execute setting from user prefs */ /* enabled by default, unless explicitly enabled in the command line which overrides */ if ((G.f & G_SCRIPT_OVERRIDE_PREF) == 0) { if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) G.f |= G_SCRIPT_AUTOEXEC; else G.f &= ~G_SCRIPT_AUTOEXEC; } /* avoid re-saving for every small change to our prefs, allow overrides */ if (from_memory) { UI_init_userdef_factory(); } /* update tempdir from user preferences */ BLI_init_temporary_dir(U.tempdir); BKE_userdef_state(); }
int main(int argc, const char **argv) #endif { bContext *C = CTX_create(); SYS_SystemHandle syshandle; #ifndef WITH_PYTHON_MODULE bArgs *ba; #endif #ifdef WIN32 wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc); int argci = 0; char **argv = MEM_mallocN(argc * sizeof(char *), "argv array"); for (argci = 0; argci < argc; argci++) { argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0); } LocalFree(argv_16); #endif #ifdef WITH_PYTHON_MODULE #ifdef __APPLE__ environ = *_NSGetEnviron(); #endif #undef main evil_C = C; #endif #ifdef WITH_BINRELOC br_init(NULL); #endif #ifdef WITH_LIBMV libmv_initLogging(argv[0]); #endif setCallbacks(); #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE) /* patch to ignore argument finder gives us (pid?) */ if (argc == 2 && strncmp(argv[1], "-psn_", 5) == 0) { extern int GHOST_HACK_getFirstFile(char buf[]); static char firstfilebuf[512]; argc = 1; if (GHOST_HACK_getFirstFile(firstfilebuf)) { argc = 2; argv[1] = firstfilebuf; } } #endif #ifdef __FreeBSD__ fpsetmask(0); #endif /* initialize path to executable */ BLI_init_program_path(argv[0]); BLI_threadapi_init(); initglobals(); /* blender.c */ IMB_init(); BKE_images_init(); BKE_brush_system_init(); BLI_callback_global_init(); #ifdef WITH_GAMEENGINE syshandle = SYS_GetSystem(); #else syshandle = 0; #endif /* first test for background */ #ifndef WITH_PYTHON_MODULE ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */ setupArguments(C, ba, &syshandle); BLI_argsParse(ba, 1, NULL, NULL); if (use_crash_handler) { /* after parsing args */ signal(SIGSEGV, blender_crash_handler); } #else G.factory_startup = true; /* using preferences or user startup makes no sense for py-as-module */ (void)syshandle; #endif #ifdef WITH_FFMPEG IMB_ffmpeg_init(); #endif /* after level 1 args, this is so playanim skips RNA init */ RNA_init(); RE_engines_init(); init_nodesystem(); /* end second init */ #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS) G.background = true; /* python module mode ALWAYS runs in background mode (for now) */ #else /* for all platforms, even windos has it! */ if (G.background) { signal(SIGINT, blender_esc); /* ctrl c out bg render */ } #endif /* background render uses this font too */ BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size); /* Initialize ffmpeg if built in, also needed for bg mode if videos are * rendered via ffmpeg */ sound_init_once(); init_def_material(); if (G.background == 0) { #ifndef WITH_PYTHON_MODULE BLI_argsParse(ba, 2, NULL, NULL); BLI_argsParse(ba, 3, NULL, NULL); #endif WM_init(C, argc, (const char **)argv); /* this is properly initialized with user defs, but this is default */ /* call after loading the startup.blend so we can read U.tempdir */ BLI_init_temporary_dir(U.tempdir); #ifdef WITH_SDL BLI_setenv("SDL_VIDEODRIVER", "dummy"); #endif } else { #ifndef WITH_PYTHON_MODULE BLI_argsParse(ba, 3, NULL, NULL); #endif WM_init(C, argc, (const char **)argv); /* don't use user preferences temp dir */ BLI_init_temporary_dir(NULL); } #ifdef WITH_PYTHON /** * NOTE: the U.pythondir string is NULL until WM_init() is executed, * so we provide the BPY_ function below to append the user defined * python-dir to Python's sys.path at this point. Simply putting * WM_init() before #BPY_python_start() crashes Blender at startup. */ /* TODO - U.pythondir */ #else printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n"); #endif CTX_py_init_set(C, 1); WM_keymap_init(C); #ifdef WITH_FREESTYLE /* initialize Freestyle */ FRS_initialize(); FRS_set_context(C); #endif /* OK we are ready for it */ #ifndef WITH_PYTHON_MODULE BLI_argsParse(ba, 4, load_file, C); if (G.background == 0) { if (!G.file_loaded) if (U.uiflag2 & USER_KEEP_SESSION) WM_recover_last_session(C, NULL); } #endif #ifndef WITH_PYTHON_MODULE BLI_argsFree(ba); #endif #ifdef WIN32 while (argci) { free(argv[--argci]); } MEM_freeN(argv); argv = NULL; #endif #ifdef WITH_PYTHON_MODULE return 0; /* keep blender in background mode running */ #endif if (G.background) { /* actually incorrect, but works for now (ton) */ WM_exit(C); } else { if (G.fileflags & G_FILE_AUTOPLAY) { if (G.f & G_SCRIPT_AUTOEXEC) { if (WM_init_game(C)) { return 0; } } else { if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) { G.f |= G_SCRIPT_AUTOEXEC_FAIL; BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Game AutoStart"); } } } if (!G.file_loaded) { WM_init_splash(C); } } WM_main(C); return 0; } /* end of int main(argc, argv) */
/* custom_file can be NULL */ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const char *custom_file) { ListBase wmbase; char startstr[FILE_MAX]; char prefstr[FILE_MAX]; int success = 0; /* Indicates whether user prefereneces were really load from memory. * * This is used for versioning code, and for this we can not rely on from_memory * passed via argument. This is because there might be configuration folder * exists but it might not have userpref.blend and in this case we fallback to * reading home file from memory. * * And in this case versioning code is to be run. */ bool read_userdef_from_memory = true; /* options exclude eachother */ BLI_assert((from_memory && custom_file) == 0); BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); G.relbase_valid = 0; if (!from_memory) { const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); if (custom_file) { BLI_strncpy(startstr, custom_file, FILE_MAX); if (cfgdir) { BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { prefstr[0] = '\0'; } } else if (cfgdir) { BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE); BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { startstr[0] = '\0'; prefstr[0] = '\0'; from_memory = 1; } } /* prevent loading no UI */ G.fileflags &= ~G_FILE_NO_UI; /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); if (!from_memory) { if (BLI_access(startstr, R_OK) == 0) { success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL); } if (U.themes.first == NULL) { if (G.debug & G_DEBUG) printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr); success = 0; } } if (success == 0 && custom_file && reports) { BKE_reportf(reports, RPT_ERROR, "Could not read '%s'", custom_file); /*We can not return from here because wm is already reset*/ } if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL, true); if (wmbase.first == NULL) wm_clear_default_size(C); BLI_init_temporary_dir(U.tempdir); #ifdef WITH_PYTHON_SECURITY /* use alternative setting for security nuts * otherwise we'd need to patch the binary blob - startup.blend.c */ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; #endif } /* check new prefs only after startup.blend was finished */ if (!from_memory && BLI_exists(prefstr)) { int done = BKE_read_file_userdef(prefstr, NULL); if (done) { read_userdef_from_memory = false; printf("Read new prefs: %s\n", prefstr); } } /* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; /* check userdef before open window, keymaps etc */ wm_init_userdef(C, read_userdef_from_memory); /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ G.main->name[0] = '\0'; /* When loading factory settings, the reset solid OpenGL lights need to be applied. */ if (!G.background) GPU_default_lights(); /* XXX */ G.save_over = 0; // start with save preference untitled.blend G.fileflags &= ~G_FILE_AUTOPLAY; /* disable autoplay in startup.blend... */ // refresh_interface_font(); // undo_editmode_clear(); BKE_reset_undo(); BKE_write_undo(C, "original"); /* save current state */ ED_editors_init(C); DAG_on_visible_update(CTX_data_main(C), TRUE); #ifdef WITH_PYTHON if (CTX_py_init_get(C)) { /* sync addons, these may have changed from the defaults */ BPY_string_exec(C, "__import__('addon_utils').reset_all()"); BPY_python_reset(C); } #endif /* important to do before NULL'ing the context */ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL); /* in background mode the scene will stay NULL */ if (!G.background) { CTX_wm_window_set(C, NULL); /* exits queues */ } return TRUE; }