diff options
Diffstat (limited to 'source/blender/blenkernel/intern/blender.c')
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 133 |
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); } |