Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/blender.c')
-rw-r--r--source/blender/blenkernel/intern/blender.c133
1 files changed, 97 insertions, 36 deletions
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index fff8265a158..9aad3cf564b 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -61,6 +61,7 @@
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
+#include "BKE_appdir.h"
#include "BKE_blender.h"
#include "BKE_bpath.h"
#include "BKE_brush.h"
@@ -80,6 +81,7 @@
#include "BKE_sound.h"
#include "RE_pipeline.h"
+#include "RE_render_ext.h"
#include "BLF_api.h"
@@ -119,6 +121,7 @@ void free_blender(void)
DAG_exit();
BKE_brush_system_exit();
+ RE_exit_texture_rng();
BLI_callback_global_finalize();
@@ -143,10 +146,6 @@ void initglobals(void)
else
BLI_snprintf(versionstr, sizeof(versionstr), "v%d.%02d", BLENDER_VERSION / 100, BLENDER_VERSION % 100);
-#ifdef _WIN32
- G.windowstate = 0;
-#endif
-
#ifndef WITH_PYTHON_SECURITY /* default */
G.f |= G_SCRIPT_AUTOEXEC;
#else
@@ -186,6 +185,17 @@ static void clean_paths(Main *main)
}
}
+static bool wm_scene_is_visible(wmWindowManager *wm, Scene *scene)
+{
+ wmWindow *win;
+ for (win = wm->windows.first; win; win = win->next) {
+ if (win->screen->scene == scene) {
+ return true;
+ }
+ }
+ return false;
+}
+
/* context matching */
/* handle no-ui case */
@@ -229,6 +239,20 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
/* no load screens? */
if (mode != LOAD_UI) {
+ /* Logic for 'track_undo_scene' is to keep using the scene which the active screen has,
+ * as long as the scene associated with the undo operation is visible in one of the open windows.
+ *
+ * - 'curscreen->scene' - scene the user is currently looking at.
+ * - 'bfd->curscene' - scene undo-step was created in.
+ *
+ * This means users can have 2+ windows open and undo in both without screens switching.
+ * But if they close one of the screens,
+ * undo will ensure that the scene being operated on will be activated
+ * (otherwise we'd be undoing on an off-screen scene which isn't acceptable).
+ * see: T43424
+ */
+ bool track_undo_scene;
+
/* comes from readfile.c */
SWAP(ListBase, G.main->wm, bfd->main->wm);
SWAP(ListBase, G.main->screen, bfd->main->screen);
@@ -238,15 +262,40 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
curscreen = CTX_wm_screen(C);
/* but use new Scene pointer */
curscene = bfd->curscene;
+
+ track_undo_scene = (mode == LOAD_UNDO && curscreen && curscene && bfd->main->wm.first);
+
if (curscene == NULL) curscene = bfd->main->scene.first;
/* empty file, we add a scene to make Blender work */
if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty");
-
- /* and we enforce curscene to be in current screen */
- if (curscreen) curscreen->scene = curscene; /* can run in bgmode */
+
+ if (track_undo_scene) {
+ /* keep the old (free'd) scene, let 'blo_lib_link_screen_restore'
+ * replace it with 'curscene' if its needed */
+ }
+ else {
+ /* and we enforce curscene to be in current screen */
+ if (curscreen) {
+ /* can run in bgmode */
+ curscreen->scene = curscene;
+ }
+ }
/* clear_global will free G.main, here we can still restore pointers */
blo_lib_link_screen_restore(bfd->main, curscreen, curscene);
+ /* curscreen might not be set when loading without ui (see T44217) so only re-assign if available */
+ if (curscreen) {
+ curscene = curscreen->scene;
+ }
+
+ if (track_undo_scene) {
+ wmWindowManager *wm = bfd->main->wm.first;
+ if (wm_scene_is_visible(wm, bfd->curscene) == false) {
+ curscene = bfd->curscene;
+ curscreen->scene = curscene;
+ BKE_screen_view3d_scene_sync(curscreen);
+ }
+ }
}
/* free G.main Main database */
@@ -260,14 +309,23 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
CTX_data_main_set(C, G.main);
- sound_init_main(G.main);
-
if (bfd->user) {
/* only here free userdef themes... */
BKE_userdef_free();
U = *bfd->user;
+
+ /* Security issue: any blend file could include a USER block.
+ *
+ * Currently we load prefs from BLENDER_STARTUP_FILE and later on load BLENDER_USERPREF_FILE,
+ * to load the preferences defined in the users home dir.
+ *
+ * This means we will never accidentally (or maliciously)
+ * enable scripts auto-execution by loading a '.blend' file.
+ */
+ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE;
+
MEM_freeN(bfd->user);
}
@@ -277,8 +335,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
CTX_data_scene_set(C, curscene);
}
else {
- G.winpos = bfd->winpos;
- G.displaymode = bfd->displaymode;
G.fileflags = bfd->fileflags;
CTX_wm_manager_set(C, G.main->wm.first);
CTX_wm_screen_set(C, bfd->curscreen);
@@ -361,6 +417,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
BKE_scene_set_background(G.main, curscene);
if (mode != LOAD_UNDO) {
+ RE_FreeAllPersistentData();
IMB_colormanagement_check_file_config(G.main);
}
@@ -491,10 +548,11 @@ bool BKE_read_file_from_memory(
BLO_update_defaults_startup_blend(bfd->main);
setup_app_data(C, bfd, "<memory2>");
}
- else
+ else {
BKE_reports_prepend(reports, "Loading failed: ");
+ }
- return (bfd ? 1 : 0);
+ return (bfd != NULL);
}
/* memfile is the undo buffer */
@@ -514,10 +572,11 @@ bool BKE_read_file_from_memfile(
setup_app_data(C, bfd, "<memory1>");
}
- else
+ else {
BKE_reports_prepend(reports, "Loading failed: ");
+ }
- return (bfd ? 1 : 0);
+ return (bfd != NULL);
}
/* only read the userdef from a .blend */
@@ -563,7 +622,7 @@ int BKE_write_file_userdef(const char *filepath, ReportList *reports)
static void (*blender_test_break_cb)(void) = NULL;
-void set_blender_test_break_cb(void (*func)(void) )
+void BKE_blender_callback_test_break_set(void (*func)(void))
{
blender_test_break_cb = func;
}
@@ -627,7 +686,7 @@ static int read_undosave(bContext *C, UndoElem *uel)
}
/* name can be a dynamic string */
-void BKE_write_undo(bContext *C, const char *name)
+void BKE_undo_write(bContext *C, const char *name)
{
uintptr_t maxmem, totmem, memused;
int nr /*, success */ /* UNUSED */;
@@ -645,7 +704,7 @@ void BKE_write_undo(bContext *C, const char *name)
while (undobase.last != curundo) {
uel = undobase.last;
BLI_remlink(&undobase, uel);
- BLO_free_memfile(&uel->memfile);
+ BLO_memfile_free(&uel->memfile);
MEM_freeN(uel);
}
@@ -667,7 +726,7 @@ void BKE_write_undo(bContext *C, const char *name)
UndoElem *first = undobase.first;
BLI_remlink(&undobase, first);
/* the merge is because of compression */
- BLO_merge_memfile(&first->memfile, &first->next->memfile);
+ BLO_memfile_merge(&first->memfile, &first->next->memfile);
MEM_freeN(first);
}
}
@@ -685,7 +744,7 @@ void BKE_write_undo(bContext *C, const char *name)
counter = counter % U.undosteps;
BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter);
- BLI_make_file_string("/", filepath, BLI_temp_dir_session(), numstr);
+ BLI_make_file_string("/", filepath, BKE_tempdir_session(), numstr);
/* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL);
@@ -722,7 +781,7 @@ void BKE_write_undo(bContext *C, const char *name)
UndoElem *first = undobase.first;
BLI_remlink(&undobase, first);
/* the merge is because of compression */
- BLO_merge_memfile(&first->memfile, &first->next->memfile);
+ BLO_memfile_merge(&first->memfile, &first->next->memfile);
MEM_freeN(first);
}
}
@@ -761,13 +820,13 @@ void BKE_undo_step(bContext *C, int step)
}
}
-void BKE_reset_undo(void)
+void BKE_undo_reset(void)
{
UndoElem *uel;
uel = undobase.first;
while (uel) {
- BLO_free_memfile(&uel->memfile);
+ BLO_memfile_free(&uel->memfile);
uel = uel->next;
}
@@ -794,7 +853,7 @@ void BKE_undo_name(bContext *C, const char *name)
}
/* name optional */
-int BKE_undo_valid(const char *name)
+bool BKE_undo_is_valid(const char *name)
{
if (name) {
UndoElem *uel = BLI_rfindstring(&undobase, name, offsetof(UndoElem, name));
@@ -806,15 +865,16 @@ int BKE_undo_valid(const char *name)
/* get name of undo item, return null if no item with this index */
/* if active pointer, set it to 1 if true */
-const char *BKE_undo_get_name(int nr, int *active)
+const char *BKE_undo_get_name(int nr, bool *r_active)
{
UndoElem *uel = BLI_findlink(&undobase, nr);
- if (active) *active = 0;
+ if (r_active) *r_active = false;
if (uel) {
- if (active && uel == curundo)
- *active = 1;
+ if (r_active && (uel == curundo)) {
+ *r_active = true;
+ }
return uel->name;
}
return NULL;
@@ -832,13 +892,13 @@ bool BKE_undo_save_file(const char *filename)
int file, oflags;
if ((U.uiflag & USER_GLOBALUNDO) == 0) {
- return 0;
+ return false;
}
uel = curundo;
if (uel == NULL) {
fprintf(stderr, "No undo buffer to save recovery file\n");
- return 0;
+ return false;
}
/* note: This is currently used for autosave and 'quit.blend', where _not_ following symlinks is OK,
@@ -860,7 +920,7 @@ bool BKE_undo_save_file(const char *filename)
if (file == -1) {
fprintf(stderr, "Unable to save '%s': %s\n",
filename, errno ? strerror(errno) : "Unknown error opening file");
- return 0;
+ return false;
}
for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) {
@@ -874,21 +934,22 @@ bool BKE_undo_save_file(const char *filename)
if (chunk) {
fprintf(stderr, "Unable to save '%s': %s\n",
filename, errno ? strerror(errno) : "Unknown error writing file");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/* sets curscene */
-Main *BKE_undo_get_main(Scene **scene)
+Main *BKE_undo_get_main(Scene **r_scene)
{
Main *mainp = NULL;
BlendFileData *bfd = BLO_read_from_memfile(G.main, G.main->name, &curundo->memfile, NULL);
if (bfd) {
mainp = bfd->main;
- if (scene)
- *scene = bfd->curscene;
+ if (r_scene) {
+ *r_scene = bfd->curscene;
+ }
MEM_freeN(bfd);
}