static int set_env(int argc, const char **argv, void *UNUSED(data)) { /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */ char env[64] = "BLENDER"; char *ch_dst = env + 7; /* skip BLENDER */ const char *ch_src = argv[0] + 5; /* skip --env */ if (argc < 2) { printf("%s requires one argument\n", argv[0]); exit(1); } for (; *ch_src; ch_src++, ch_dst++) { *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* toupper() */ } *ch_dst = '\0'; BLI_setenv(env, argv[1]); return 1; }
/* must be called before Py_Initialize, expects output of BLI_get_folder(BLENDER_PYTHON, NULL) */ void PyC_SetHomePath(const char *py_path_bundle) { if(py_path_bundle==NULL) { /* Common enough to have bundled *nix python but complain on OSX/Win */ #if defined(__APPLE__) || defined(_WIN32) fprintf(stderr, "Warning! bundled python not found and is expected on this platform. (if you built with CMake: 'install' target may have not been built)\n"); #endif return; } /* set the environment path */ printf("found bundled python: %s\n", py_path_bundle); #ifdef __APPLE__ /* OSX allow file/directory names to contain : character (represented as / in the Finder) but current Python lib (release 3.1.1) doesn't handle these correctly */ if(strchr(py_path_bundle, ':')) printf("Warning : Blender application is located in a path containing : or / chars\ \nThis may make python import function fail\n"); #endif #ifdef _WIN32 /* cmake/MSVC debug build crashes without this, why only in this case is unknown.. */ { BLI_setenv("PYTHONPATH", py_path_bundle); } #endif { static wchar_t py_path_bundle_wchar[1024]; /* cant use this, on linux gives bug: #23018, TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 22008 */ /* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */ utf8towchar(py_path_bundle_wchar, py_path_bundle); Py_SetPythonHome(py_path_bundle_wchar); // printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar); } }
/* call BPY_context_set first */ void BPY_python_start(int argc, const char **argv) { #ifndef WITH_PYTHON_MODULE PyThreadState *py_tstate = NULL; /* not essential but nice to set our name */ static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */ BLI_strncpy_wchar_from_utf8(program_path_wchar, BLI_program_path(), sizeof(program_path_wchar) / sizeof(wchar_t)); Py_SetProgramName(program_path_wchar); /* must run before python initializes */ PyImport_ExtendInittab(bpy_internal_modules); /* allow to use our own included python */ PyC_SetHomePath(BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL)); /* without this the sys.stdout may be set to 'ascii' * (it is on my system at least), where printing unicode values will raise * an error, this is highly annoying, another stumbling block for devs, * so use a more relaxed error handler and enforce utf-8 since the rest of * blender is utf-8 too - campbell */ BLI_setenv("PYTHONIOENCODING", "utf-8:surrogateescape"); /* Python 3.2 now looks for '2.xx/python/include/python3.2d/pyconfig.h' to * parse from the 'sysconfig' module which is used by 'site', * so for now disable site. alternatively we could copy the file. */ Py_NoSiteFlag = 1; Py_Initialize(); // PySys_SetArgv(argc, argv); // broken in py3, not a huge deal /* sigh, why do python guys not have a (char **) version anymore? */ { int i; PyObject *py_argv = PyList_New(argc); for (i = 0; i < argc; i++) { /* should fix bug #20021 - utf path name problems, by replacing * PyUnicode_FromString, with this one */ PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i])); } PySys_SetObject("argv", py_argv); Py_DECREF(py_argv); } /* Initialize thread support (also acquires lock) */ PyEval_InitThreads(); #else (void)argc; (void)argv; /* must run before python initializes */ PyImport_ExtendInittab(bpy_internal_modules); #endif bpy_intern_string_init(); /* bpy.* and lets us import it */ BPy_init_modules(); bpy_import_init(PyEval_GetBuiltins()); pyrna_alloc_types(); #ifndef WITH_PYTHON_MODULE /* py module runs atexit when bpy is freed */ BPY_atexit_register(); /* this can init any time */ py_tstate = PyGILState_GetThisThreadState(); PyEval_ReleaseThread(py_tstate); #endif }
/** * Only set an env var if already not there. * Like Unix setenv(env, val, 0); */ void BLI_setenv_if_new(const char *env, const char *val) { if (getenv(env) == NULL) BLI_setenv(env, val); }
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) */
/* XXX WARNING!!! IN osx somehow the previous function call jumps in this one??? (ton, ppc) */ void BLF_lang_set(const char *str) { char *locreturn; const char *short_locale; int ok = 1; const char *long_locale = locales[2 * U.language]; if ((U.transopts&USER_DOTRANSLATE) == 0) return; if (str) short_locale = str; else short_locale = locales[ 2 * U.language + 1]; #if defined (_WIN32) && !defined(FREE_WINDOWS) if (short_locale) { char *envStr; if (U.language == 0)/* use system setting */ envStr = BLI_sprintfN( "LANG=%s", getenv("LANG") ); else envStr = BLI_sprintfN( "LANG=%s", short_locale ); gettext_putenv(envStr); MEM_freeN(envStr); } locreturn = setlocale(LC_ALL, long_locale); if (locreturn == NULL) { if (G.debug & G_DEBUG) printf("Could not change locale to %s\n", long_locale); ok = 0; } #else { static char default_lang[64] ="\0"; static char default_language[64] ="\0"; if (default_lang[0] == 0) get_language_variable("LANG", default_lang, sizeof(default_lang)); if (default_language[0] == 0) get_language_variable("LANGUAGE", default_language, sizeof(default_language)); if (short_locale[0]) { if (G.debug & G_DEBUG) printf("Setting LANG= and LANGUAGE to %s\n", short_locale); BLI_setenv("LANG", short_locale); BLI_setenv("LANGUAGE", short_locale); } else { if (G.debug & G_DEBUG) printf("Setting LANG=%s and LANGUAGE=%s\n", default_lang, default_language); BLI_setenv("LANG", default_lang); BLI_setenv("LANGUAGE", default_language); } locreturn = setlocale(LC_ALL, short_locale); if (locreturn == NULL) { char *short_locale_utf8 = NULL; if (short_locale[0]) { short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale); locreturn = setlocale(LC_ALL, short_locale_utf8); } if (locreturn == NULL) { char language[65]; get_language(long_locale, default_lang, language, sizeof(language)); if (G.debug & G_DEBUG) { if (short_locale[0]) printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); else printf("Could not reset locale\n"); printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); } /* fallback to default settings */ BLI_setenv("LANG", default_lang); BLI_setenv("LANGUAGE", language); locreturn = setlocale(LC_ALL, ""); ok = 0; } if (short_locale_utf8) MEM_freeN(short_locale_utf8); } } #endif if (ok) { /*printf("Change locale to %s\n", locreturn ); */ BLI_strncpy(global_language, locreturn, sizeof(global_language)); } setlocale(LC_NUMERIC, "C"); textdomain(TEXT_DOMAIN_NAME); bindtextdomain(TEXT_DOMAIN_NAME, global_messagepath); bind_textdomain_codeset(TEXT_DOMAIN_NAME, global_encoding_name); }
/* XXX WARNING!!! IN osx somehow the previous function call jumps in this one??? (ton, ppc) */ void BLF_lang_set(const char *str) { char *locreturn; const char *short_locale; int ok= 1; #if defined (_WIN32) && !defined(FREE_WINDOWS) const char *long_locale = locales[ 2 * U.language]; #endif if((U.transopts&USER_DOTRANSLATE)==0) return; if(str) short_locale = str; else short_locale = locales[ 2 * U.language + 1]; #if defined (_WIN32) && !defined(FREE_WINDOWS) if(short_locale) { char *envStr; if( U.language==0 )/* use system setting */ envStr = BLI_sprintfN( "LANG=%s", getenv("LANG") ); else envStr = BLI_sprintfN( "LANG=%s", short_locale ); gettext_putenv(envStr); MEM_freeN(envStr); } locreturn= setlocale(LC_ALL, long_locale); if (locreturn == NULL) { printf("Could not change locale to %s\n", long_locale); ok= 0; } #else { const char *locale; static char default_locale[64]="\0"; if(default_locale[0]==0) { char *env_language= getenv("LANGUAGE"); if(env_language) { char *s; /* store defaul locale */ BLI_strncpy(default_locale, env_language, sizeof(default_locale)); /* use first language as default */ s= strchr(default_locale, ':'); if(s) s[0]= 0; } } if(short_locale[0]) locale= short_locale; else locale= default_locale; BLI_setenv("LANG", locale); BLI_setenv("LANGUAGE", locale); locreturn= setlocale(LC_ALL, locale); if (locreturn == NULL) { char *short_locale_utf8= BLI_sprintfN("%s.UTF-8", short_locale); locreturn= setlocale(LC_ALL, short_locale_utf8); if (locreturn == NULL) { printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); ok= 0; } MEM_freeN(short_locale_utf8); } } #endif if(ok) { //printf("Change locale to %s\n", locreturn ); BLI_strncpy(global_language, locreturn, sizeof(global_language)); } setlocale(LC_NUMERIC, "C"); textdomain(DOMAIN_NAME); bindtextdomain(DOMAIN_NAME, global_messagepath); bind_textdomain_codeset(DOMAIN_NAME, global_encoding_name); }