Core: Environment variables for deployment

* BLENDER_SYSTEM_SCRIPTS support for multiple script paths, separated by
  ; on Windows and : on other platforms.
* New BLENDER_CUSTOM_SPLASH to replace the splash screen image.
* New BLENDER_CUSTOM_SPLASH_BANNER to overlay an image on the splash.

Contributed by Sony Interactive Entertainment: https://github.com/PlayStation-OpenSource
This commit is contained in:
jlalleve 2025-01-14 20:54:22 +01:00 committed by Brecht Van Lommel
parent 6922418a95
commit 2feadc623b
4 changed files with 126 additions and 10 deletions

View file

@ -418,8 +418,8 @@ def script_paths_pref():
def script_paths_system_environment():
"""Returns a list of system script directories from environment variables."""
if env_system_path := _os.environ.get("BLENDER_SYSTEM_SCRIPTS"):
return [_os.path.normpath(env_system_path)]
if env_system_paths := _os.environ.get("BLENDER_SYSTEM_SCRIPTS"):
return [_os.path.normpath(p) for p in env_system_paths.split(_os.pathsep) if p]
return []

View file

@ -436,6 +436,47 @@ static bool get_path_environment(char *targetpath,
targetpath, targetpath_maxncpy, subfolder_name, envvar, check_is_dir);
}
static blender::Vector<std::string> get_path_environment_multiple(const char *subfolder_name,
const char *envvar,
const bool check_is_dir)
{
blender::Vector<std::string> paths;
const char *env_path = envvar ? BLI_getenv(envvar) : nullptr;
if (!env_path) {
return paths;
}
std::string env_path_str = env_path;
#ifdef _WIN32
const char separator = ';';
#else
const char separator = ':';
#endif
char path[PATH_MAX] = "\0";
size_t last = 0;
size_t next = 0;
for (; (next = env_path_str.find(separator, last)) != std::string::npos; last = next + 1) {
BLI_path_join(
path, sizeof(path), env_path_str.substr(last, next - last).c_str(), subfolder_name);
if (!check_is_dir || BLI_is_dir(path)) {
paths.append(path);
}
}
if (last < env_path_str.size()) {
BLI_path_join(path,
sizeof(path),
env_path_str.substr(last, env_path_str.size() - last).c_str(),
subfolder_name);
if (!check_is_dir || BLI_is_dir(path)) {
paths.append(path);
}
}
return paths;
}
/**
* Returns the path of a folder within the user-files area.
*
@ -1016,13 +1057,8 @@ static blender::Vector<std::string> appdir_app_template_directories()
}
/* Environment variable. */
if (get_path_environment(temp_dir,
sizeof(temp_dir),
"startup" SEP_STR "bl_app_templates_system",
"BLENDER_SYSTEM_SCRIPTS"))
{
directories.append(temp_dir);
}
directories.extend(get_path_environment_multiple(
"startup" SEP_STR "bl_app_templates_system", "BLENDER_SYSTEM_SCRIPTS", true));
/* Local or system directory. */
if (BKE_appdir_folder_id_ex(BLENDER_SYSTEM_SCRIPTS,

View file

@ -147,6 +147,13 @@ static ImBuf *wm_block_splash_image(int width, int *r_height)
}
}
if (ibuf == nullptr) {
const char *custom_splash_path = BLI_getenv("BLENDER_CUSTOM_SPLASH");
if (custom_splash_path) {
ibuf = IMB_loadiffname(custom_splash_path, IB_rect, NULL);
}
}
if (ibuf == nullptr) {
const uchar *splash_data = (const uchar *)datatoc_splash_png;
size_t splash_data_size = datatoc_splash_png_size;
@ -172,6 +179,62 @@ static ImBuf *wm_block_splash_image(int width, int *r_height)
return ibuf;
}
static ImBuf *wm_block_splash_banner_image(int *r_width,
int *r_height,
int max_width,
int max_height)
{
ImBuf *ibuf = nullptr;
int height = 0;
int width = max_width;
#ifndef WITH_HEADLESS
const char *custom_splash_path = BLI_getenv("BLENDER_CUSTOM_SPLASH_BANNER");
if (custom_splash_path) {
ibuf = IMB_loadiffname(custom_splash_path, IB_rect, NULL);
}
if (!ibuf) {
return nullptr;
}
ibuf->planes = 32; /* The image might not have an alpha channel. */
width = ibuf->x;
height = ibuf->y;
if (width > 0 && height > 0 && (width > max_width || height > max_height)) {
float splash_ratio = max_width / (float)max_height;
float banner_ratio = ibuf->x / (float)ibuf->y;
if (banner_ratio > splash_ratio) {
/* The banner is wider than the splash image. */
width = max_width;
height = max_width / banner_ratio;
}
else if (banner_ratio < splash_ratio) {
/* The banner is taller than the splash image. */
height = max_height;
width = max_height * banner_ratio;
}
else {
width = max_width;
height = max_height;
}
if (width != ibuf->x || height != ibuf->y) {
IMB_scale(ibuf, width, height, IMBScaleFilter::Box, false);
}
}
IMB_premultiply_alpha(ibuf);
#else
UNUSED_VARS(width);
#endif
*r_height = height;
*r_width = width;
return ibuf;
}
/**
* Close the splash when opening a file-selector.
*/
@ -251,6 +314,20 @@ static uiBlock *wm_block_splash_create(bContext *C, ARegion *region, void * /*ar
splash_height - 13.0 * UI_SCALE_FAC);
}
/* Banner image passed through the environment, to overlay on the splash and
* indicate a custom Blender version. Transparency can be used. To replace the
* full splash screen, see BLENDER_CUSTOM_SPLASH. */
int banner_width = 0;
int banner_height = 0;
ImBuf *bannerbuf = wm_block_splash_banner_image(
&banner_width, &banner_height, splash_width, splash_height);
if (bannerbuf) {
uiBut *banner_but = uiDefButImage(
block, bannerbuf, 0, 0.5f * U.widget_unit, banner_width, banner_height, nullptr);
UI_but_func_set(banner_but, wm_block_splash_close, block, nullptr);
}
const int layout_margin_x = UI_SCALE_FAC * 26;
uiLayout *layout = UI_block_layout(block,
UI_LAYOUT_VERTICAL,

View file

@ -859,10 +859,13 @@ static void print_help(bArgs *ba, bool all)
PRINT(" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
PRINT("\n");
PRINT(" $BLENDER_SYSTEM_RESOURCES Replace default directory of all bundled resource files.\n");
PRINT(" $BLENDER_SYSTEM_SCRIPTS Directory to add more bundled scripts.\n");
PRINT(" $BLENDER_SYSTEM_SCRIPTS Directories to add extra scripts.\n");
PRINT(" $BLENDER_SYSTEM_EXTENSIONS Directory for system extensions repository.\n");
PRINT(" $BLENDER_SYSTEM_DATAFILES Directory to replace bundled datafiles.\n");
PRINT(" $BLENDER_SYSTEM_PYTHON Directory to replace bundled Python libraries.\n");
PRINT(" $BLENDER_CUSTOM_SPLASH Full path to an image that replaces the splash screen.\n");
PRINT(
" $BLENDER_CUSTOM_SPLASH_BANNER Full path to an image to overlay on the splash screen.\n");
if (defs.with_ocio) {
PRINT(" $OCIO Path to override the OpenColorIO configuration file.\n");