static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); char name[FILE_MAX]; struct FSMenu *fsmenu = fsmenu_get(); while (fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) { fsmenu_remove_entry(fsmenu, FS_CATEGORY_RECENT, 0); } BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu, name); ED_area_tag_redraw(sa); return OPERATOR_FINISHED; }
void wm_autosave_delete(void) { char filename[FILE_MAX]; wm_autosave_location(filename); if (BLI_exists(filename)) { char str[FILE_MAX]; BLI_make_file_string("/", str, BKE_tempdir_base(), BLENDER_QUIT_FILE); /* if global undo; remove tempsave, otherwise rename */ if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, false, false); else BLI_rename(filename, str); } }
static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) { char newname[FILE_MAX + 12]; char orgname[FILE_MAX + 12]; char filename[FILE_MAX + 12]; wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C); ARegion *ar = CTX_wm_region(C); BLI_make_file_string(G.main->name, orgname, sfile->params->dir, oldname); BLI_strncpy(filename, sfile->params->renameedit, sizeof(filename)); BLI_filename_make_safe(filename); BLI_make_file_string(G.main->name, newname, sfile->params->dir, filename); if (!STREQ(orgname, newname)) { if (!BLI_exists(newname)) { BLI_rename(orgname, newname); /* to make sure we show what is on disk */ ED_fileselect_clear(wm, sfile); } ED_region_tag_redraw(ar); } }
void wm_autosave_delete(void) { char filename[FILE_MAX]; wm_autosave_location(filename); if (BLI_exists(filename)) { char str[FILE_MAX]; BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend"); /* if global undo; remove tempsave, otherwise rename */ if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0); else BLI_rename(filename, str); } }
int file_delete_exec(bContext *C, wmOperator *UNUSED(op)) { char str[FILE_MAX]; SpaceFile *sfile= CTX_wm_space_file(C); struct direntry* file; file = filelist_file(sfile->files, sfile->params->active_file); BLI_make_file_string(G.main->name, str, sfile->params->dir, file->relname); BLI_delete(str, 0, 0); ED_fileselect_clear(C, sfile); WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; }
/* path to temporary exr file */ void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath) { char name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100]; const char *fi = BLI_path_basename(G.main->name); if (sample == 0) { BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname); } else { BLI_snprintf(name, sizeof(name), "%s_%s_%s%d.exr", fi, scene->id.name + 2, layname, sample); } /* Make name safe for paths, see T43275. */ BLI_filename_make_safe(name); BLI_make_file_string("/", filepath, BKE_tempdir_session(), name); }
ImBuf *get_brush_icon(Brush *brush) { static const int flags = IB_rect | IB_multilayer | IB_metadata; char path[FILE_MAX]; const char *folder; if (!(brush->icon_imbuf)) { if (brush->flag & BRUSH_CUSTOM_ICON) { if (brush->icon_filepath[0]) { // first use the path directly to try and load the file BLI_strncpy(path, brush->icon_filepath, sizeof(brush->icon_filepath)); BLI_path_abs(path, BKE_main_blendfile_path_from_global()); /* use default colorspaces for brushes */ brush->icon_imbuf = IMB_loadiffname(path, flags, NULL); // otherwise lets try to find it in other directories if (!(brush->icon_imbuf)) { folder = BKE_appdir_folder_id(BLENDER_DATAFILES, "brushicons"); BLI_make_file_string( BKE_main_blendfile_path_from_global(), path, folder, brush->icon_filepath); if (path[0]) { /* use fefault color spaces */ brush->icon_imbuf = IMB_loadiffname(path, flags, NULL); } } if (brush->icon_imbuf) { BKE_icon_changed(BKE_icon_id_ensure(&brush->id)); } } } } if (!(brush->icon_imbuf)) { brush->id.icon_id = 0; } return brush->icon_imbuf; }
static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); struct FSMenu *fsmenu = fsmenu_get(); struct FileSelectParams *params = ED_fileselect_get_params(sfile); if (params->dir[0] != '\0') { char name[FILE_MAX]; fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, FS_INSERT_SAVE); BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu, name); } ED_area_tag_redraw(sa); return OPERATOR_FINISHED; }
static void writeBlog(void) { struct RecentFile *recent, *next_recent; char name[FILE_MAXDIR+FILE_MAXFILE]; FILE *fp; int i; BLI_make_file_string("/", name, BLI_gethome(), ".Blog"); recent = G.recent_files.first; /* refresh .Blog of recent opened files, when current file was changed */ if(!(recent) || (strcmp(recent->filename, G.sce)!=0)) { fp= fopen(name, "w"); if (fp) { /* add current file to the beginning of list */ recent = (RecentFile*)MEM_mallocN(sizeof(RecentFile),"RecentFile"); recent->filename = (char*)MEM_mallocN(sizeof(char)*(strlen(G.sce)+1), "name of file"); recent->filename[0] = '\0'; strcpy(recent->filename, G.sce); BLI_addhead(&(G.recent_files), recent); /* write current file to .Blog */ fprintf(fp, "%s\n", recent->filename); recent = recent->next; i=1; /* write rest of recent opened files to .Blog */ while((i<U.recent_files) && (recent)){ /* this prevents to have duplicities in list */ if (strcmp(recent->filename, G.sce)!=0) { fprintf(fp, "%s\n", recent->filename); recent = recent->next; } else { next_recent = recent->next; MEM_freeN(recent->filename); BLI_freelinkN(&(G.recent_files), recent); recent = next_recent; } i++; } fclose(fp); } } }
static int bookmark_delete_exec(bContext *C, wmOperator *op) { ScrArea *sa = CTX_wm_area(C); struct FSMenu *fsmenu = fsmenu_get(); int nentries = fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS); if (RNA_struct_find_property(op->ptr, "index")) { int index = RNA_int_get(op->ptr, "index"); if ((index > -1) && (index < nentries)) { char name[FILE_MAX]; fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index); BLI_make_file_string("/", name, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu, name); ED_area_tag_redraw(sa); } } return OPERATOR_FINISHED; }
/* Only save the prefs block. operator entry */ int wm_userpref_write_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); char filepath[FILE_MAX]; /* update keymaps in user preferences */ WM_keyconfig_update(wm); BLI_make_file_string("/", filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_USERPREF_FILE); printf("trying to save userpref at %s ", filepath); if (BKE_write_file_userdef(filepath, op->reports) == 0) { printf("fail\n"); return OPERATOR_CANCELLED; } printf("ok\n"); return OPERATOR_FINISHED; }
ImBuf* get_brush_icon(Brush *brush) { static const int flags = IB_rect|IB_multilayer|IB_metadata; char path[240]; char *folder; if (!(brush->icon_imbuf)) { if (brush->flag & BRUSH_CUSTOM_ICON) { if (brush->icon_filepath[0]) { // first use the path directly to try and load the file BLI_strncpy(path, brush->icon_filepath, sizeof(brush->icon_filepath)); BLI_path_abs(path, G.main->name); brush->icon_imbuf= IMB_loadiffname(path, flags); // otherwise lets try to find it in other directories if (!(brush->icon_imbuf)) { folder= BLI_get_folder(BLENDER_DATAFILES, "brushicons"); path[0]= 0; BLI_make_file_string(G.main->name, path, folder, brush->icon_filepath); if (path[0]) brush->icon_imbuf= IMB_loadiffname(path, flags); } if (brush->icon_imbuf) BKE_icon_changed(BKE_icon_getid(&brush->id)); } } } if (!(brush->icon_imbuf)) brush->id.icon_id = 0; return brush->icon_imbuf; }
/* sends events now, so things get handled on windowqueue level */ int file_exec(bContext *C, wmOperator *exec_op) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); char filepath[FILE_MAX]; if (sfile->op) { wmOperator *op = sfile->op; /* when used as a macro, for doubleclick, * to prevent closing when doubleclicking on .. item */ if (RNA_boolean_get(exec_op->ptr, "need_active")) { int i, active = 0; for (i = 0; i < filelist_numfiles(sfile->files); i++) { if (filelist_is_selected(sfile->files, i, CHECK_ALL)) { active = 1; break; } } if (active == 0) return OPERATOR_CANCELLED; } sfile->op = NULL; file_sfile_to_operator(op, sfile, filepath); if (BLI_exists(sfile->params->dir)) { fsmenu_insert_entry(fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, FS_INSERT_SAVE | FS_INSERT_FIRST); } BLI_make_file_string(G.main->name, filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu_get(), filepath); WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC); } return OPERATOR_FINISHED; }
/** * Write #BLENDER_HISTORY_FILE as-is, without checking the environment * (thats handled by #wm_history_file_update). */ static void wm_history_file_write(void) { const char *user_config_dir; char name[FILE_MAX]; FILE *fp; /* will be NULL in background mode */ user_config_dir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL); if (!user_config_dir) return; BLI_make_file_string("/", name, user_config_dir, BLENDER_HISTORY_FILE); fp = BLI_fopen(name, "w"); if (fp) { struct RecentFile *recent; for (recent = G.recent_files.first; recent; recent = recent->next) { fprintf(fp, "%s\n", recent->filepath); } fclose(fp); } }
/* operator entry */ int WM_write_homefile(bContext *C, wmOperator *op) { wmWindowManager *wm= CTX_wm_manager(C); wmWindow *win= CTX_wm_window(C); char tstr[FILE_MAXDIR+FILE_MAXFILE]; int fileflags; /* check current window and close it if temp */ if(win->screen->full == SCREENTEMP) wm_window_close(C, wm, win); BLI_make_file_string("/", tstr, BLI_gethome(), ".B25.blend"); /* force save as regular blend file */ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN); BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports); G.save_over= 0; return OPERATOR_FINISHED; }
/* saves quit.blend */ void BKE_undo_save_quit(void) { UndoElem *uel; MemFileChunk *chunk; int file; char str[FILE_MAXDIR+FILE_MAXFILE]; if( (U.uiflag & USER_GLOBALUNDO)==0) return; uel= curundo; if(uel==NULL) { printf("No undo buffer to save recovery file\n"); return; } /* no undo state to save */ if(undobase.first==undobase.last) return; BLI_make_file_string("/", str, btempdir, "quit.blend"); file = open(str,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); if(file == -1) { //XXX error("Unable to save %s, check you have permissions", str); return; } chunk= uel->memfile.chunks.first; while(chunk) { if( write(file, chunk->buf, chunk->size) != chunk->size) break; chunk= chunk->next; } close(file); if(chunk) ; //XXX error("Unable to save %s, internal error", str); else printf("Saved session recovery to %s\n", str); }
/** * \see #wm_file_write wraps #BLO_write_file in a similar way. */ int wm_homefile_write_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); char filepath[FILE_MAX]; int fileflags; BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); /* check current window and close it if temp */ if (win && win->screen->temp) wm_window_close(C, wm, win); /* update keymaps in user preferences */ WM_keyconfig_update(wm); BLI_make_file_string("/", filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); printf("trying to save homefile at %s ", filepath); ED_editors_flush_edits(C, false); /* force save as regular blend file */ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_HISTORY); if (BLO_write_file(CTX_data_main(C), filepath, fileflags | G_FILE_USERPREFS, op->reports, NULL) == 0) { printf("fail\n"); return OPERATOR_CANCELLED; } printf("ok\n"); G.save_over = 0; BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_POST); return OPERATOR_FINISHED; }
/* * Should only be done with command line paths. * this is NOT something blenders internal paths support like the // prefix */ int BLI_path_cwd(char *path) { int wasrelative = 1; int filelen = strlen(path); #ifdef WIN32 if (filelen >= 3 && path[1] == ':' && (path[2] == '\\' || path[2] == '/')) wasrelative = 0; #else if (filelen >= 2 && path[0] == '/') wasrelative = 0; #endif if (wasrelative == 1) { char cwd[FILE_MAX] = ""; BLI_current_working_dir(cwd, sizeof(cwd)); /* in case the full path to the blend isn't used */ if (cwd[0] == '\0') { printf("Could not get the current working directory - $PWD for an unknown reason.\n"); } else { /* uses the blend path relative to cwd important for loading relative linked files. * * cwd should contain c:\ etc on win32 so the relbase can be NULL * relbase being NULL also prevents // being misunderstood as relative to the current * blend file which isn't a feature we want to use in this case since were dealing * with a path from the command line, rather than from inside Blender */ char origpath[FILE_MAX]; BLI_strncpy(origpath, path, FILE_MAX); BLI_make_file_string(NULL, path, cwd, origpath); } } return wasrelative; }
/** * called on startup, (context entirely filled with NULLs) * or called for 'New File' * both startup.blend and userpref.blend are checked * the optional parameter custom_file points to an alternative startup page * 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 preferences 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); if ((G.f & G_SCRIPT_OVERRIDE_PREF) == 0) { BKE_BIT_TEST_SET(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_SCRIPT_AUTOEXEC); } BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); UI_view2d_zoom_cache_reset(); G.relbase_valid = 0; if (!from_memory) { const char * const cfgdir = BKE_appdir_folder_id(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; } } /* 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 (BLI_listbase_is_empty(&U.themes)) { 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 (BLI_listbase_is_empty(&wmbase)) { wm_clear_default_size(C); } BKE_tempdir_init(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 != BKE_READ_FILE_FAIL) { 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... */ wm_file_read_post(C, true); return true; }
static void blender_crash_handler(int signum) { #if 0 { char fname[FILE_MAX]; if (!G.main->name[0]) { BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend"); } else { BLI_strncpy(fname, G.main->name, sizeof(fname)); BLI_replace_extension(fname, sizeof(fname), ".crash.blend"); } printf("Writing: %s\n", fname); fflush(stdout); BKE_undo_save_file(fname); } #endif FILE *fp; char header[512]; wmWindowManager *wm = G.main->wm.first; char fname[FILE_MAX]; if (!G.main->name[0]) { BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), "blender.crash.txt"); } else { BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), BLI_path_basename(G.main->name)); BLI_replace_extension(fname, sizeof(fname), ".crash.txt"); } printf("Writing: %s\n", fname); fflush(stdout); BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Revision: %s\n", BLEND_VERSION_ARG, #ifdef BUILD_DATE build_rev #else "Unknown" #endif ); /* open the crash log */ errno = 0; fp = BLI_fopen(fname, "wb"); if (fp == NULL) { fprintf(stderr, "Unable to save '%s': %s\n", fname, errno ? strerror(errno) : "Unknown error opening file"); } else { if (wm) { BKE_report_write_file_fp(fp, &wm->reports, header); } blender_crash_handler_backtrace(fp); fclose(fp); } /* really crash */ signal(signum, SIG_DFL); #ifndef WIN32 kill(getpid(), signum); #else TerminateProcess(GetCurrentProcess(), signum); #endif }
/* op can be NULL */ int WM_read_homefile(bContext *C, ReportList *UNUSED(reports), short from_memory) { ListBase wmbase; char tstr[FILE_MAX]; int success = 0; free_ttfont(); /* still weird... what does it here? */ G.relbase_valid = 0; if (!from_memory) { char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); if (cfgdir) { BLI_make_file_string(G.main->name, tstr, cfgdir, BLENDER_STARTUP_FILE); } else { tstr[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 && BLI_exists(tstr)) { success = (BKE_read_file(C, tstr, NULL) != BKE_READ_FILE_FAIL); if (U.themes.first == NULL) { printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); success = 0; } } if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL); if (wmbase.first == NULL) wm_clear_default_size(C); #ifdef WITH_PYTHON_SECURITY /* not default */ /* 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 } /* 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); /* 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... */ // mainwindow_set_filename_to_title(""); // empty string re-initializes title to "Blender" // 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_driver_reset(); BPY_app_handlers_reset(FALSE); BPY_modules_load_user(C); } #endif 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; }
/** * \note doesn't run exit() call #WM_exit() for that. */ void WM_exit_ext(bContext *C, const bool do_python) { wmWindowManager *wm = C ? CTX_wm_manager(C) : NULL; /* first wrap up running stuff, we assume only the active WM is running */ /* modal handlers are on window level freed, others too? */ /* note; same code copied in wm_files.c */ if (C && wm) { wmWindow *win; if (!G.background) { struct MemFile *undo_memfile = wm->undo_stack ? ED_undosys_stack_memfile_get_active(wm->undo_stack) : NULL; if ((U.uiflag2 & USER_KEEP_SESSION) || (undo_memfile != NULL)) { /* save the undo state as quit.blend */ char filename[FILE_MAX]; bool has_edited; int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_HISTORY); BLI_make_file_string("/", filename, BKE_tempdir_base(), BLENDER_QUIT_FILE); has_edited = ED_editors_flush_edits(C, false); if ((has_edited && BLO_write_file(CTX_data_main(C), filename, fileflags, NULL, NULL)) || (undo_memfile && BLO_memfile_write_file(undo_memfile, filename))) { printf("Saved session recovery to '%s'\n", filename); } } } WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { CTX_wm_window_set(C, win); /* needed by operator close callbacks */ WM_event_remove_handlers(C, &win->handlers); WM_event_remove_handlers(C, &win->modalhandlers); ED_screen_exit(C, win, win->screen); } } BKE_addon_pref_type_free(); wm_operatortype_free(); wm_dropbox_free(); WM_menutype_free(); WM_uilisttype_free(); /* all non-screen and non-space stuff editors did, like editmode */ if (C) ED_editors_exit(C); ED_undosys_type_free(); // XXX // BIF_GlobalReebFree(); // BIF_freeRetarget(); BIF_freeTemplates(C); free_openrecent(); BKE_mball_cubeTable_free(); /* render code might still access databases */ RE_FreeAllRender(); RE_engines_exit(); ED_preview_free_dbase(); /* frees a Main dbase, before BKE_blender_free! */ if (C && wm) wm_free_reports(C); /* before BKE_blender_free! - since the ListBases get freed there */ BKE_sequencer_free_clipboard(); /* sequencer.c */ BKE_tracking_clipboard_free(); BKE_mask_clipboard_free(); BKE_vfont_clipboard_free(); #ifdef WITH_COMPOSITOR COM_deinitialize(); #endif BKE_blender_free(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); ANIM_fcurves_copybuf_free(); ANIM_drivers_copybuf_free(); ANIM_driver_vars_copybuf_free(); ANIM_fmodifiers_copybuf_free(); ED_gpencil_anim_copybuf_free(); ED_gpencil_strokes_copybuf_free(); BKE_node_clipboard_clear(); BLF_exit(); #ifdef WITH_INTERNATIONAL BLF_free_unifont(); BLF_free_unifont_mono(); BLT_lang_free(); #endif ANIM_keyingset_infos_exit(); // free_txt_data(); #ifdef WITH_PYTHON /* option not to close python so we can use 'atexit' */ if (do_python && ((C == NULL) || CTX_py_init_get(C))) { /* XXX - old note */ /* before BKE_blender_free so py's gc happens while library still exists */ /* needed at least for a rare sigsegv that can happen in pydrivers */ /* Update for blender 2.5, move after BKE_blender_free because blender now holds references to PyObject's * so decref'ing them after python ends causes bad problems every time * the pyDriver bug can be fixed if it happens again we can deal with it then */ BPY_python_end(); } #else (void)do_python; #endif if (!G.background) { #ifdef WITH_OPENSUBDIV BKE_subsurf_osd_cleanup(); #endif GPU_global_buffer_pool_free(); GPU_free_unused_buffers(G_MAIN); GPU_exit(); } ED_file_exit(); /* for fsmenu */ UI_exit(); BKE_blender_userdef_data_free(&U, false); RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */ wm_ghost_exit(); CTX_free(C); #ifdef WITH_GAMEENGINE SYS_DeleteSystem(SYS_GetSystem()); #endif GHOST_DisposeSystemPaths(); DNA_sdna_current_free(); BLI_threadapi_exit(); /* No need to call this early, rather do it late so that other pieces of Blender using sound may exit cleanly, * see also T50676. */ BKE_sound_exit(); CLG_exit(); BKE_blender_atexit(); if (MEM_get_memory_blocks_in_use() != 0) { size_t mem_in_use = MEM_get_memory_in_use() + MEM_get_memory_in_use(); printf("Error: Not freed memory blocks: %u, total unfreed memory %f MB\n", MEM_get_memory_blocks_in_use(), (double)mem_in_use / 1024 / 1024); MEM_printmemlist(); } wm_autosave_delete(); BKE_tempdir_session_purge(); }
/* only called once, for startup */ void WM_init(bContext *C, int argc, const char **argv) { if (!G.background) { wm_ghost_init(C); /* note: it assigns C to ghost! */ wm_init_cursor_data(); } GHOST_CreateSystemPaths(); BKE_addon_pref_type_init(); wm_operatortype_init(); wm_operatortypes_register(); WM_menutype_init(); WM_uilisttype_init(); ED_undosys_type_init(); BKE_library_callback_free_window_manager_set(wm_close_and_free); /* library.c */ BKE_library_callback_free_notifier_reference_set(WM_main_remove_notifier_reference); /* library.c */ BKE_library_callback_remap_editor_id_reference_set(WM_main_remap_editor_id_reference); /* library.c */ BKE_blender_callback_test_break_set(wm_window_testbreak); /* blender.c */ BKE_spacedata_callback_id_remap_set(ED_spacedata_id_remap); /* screen.c */ DAG_editors_update_cb(ED_render_id_flush_update, ED_render_scene_update, ED_render_scene_update_pre); /* depsgraph.c */ ED_spacetypes_init(); /* editors/space_api/spacetype.c */ ED_file_init(); /* for fsmenu */ ED_node_init_butfuncs(); BLF_init(); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */ BLT_lang_init(); /* Must call first before doing any .blend file reading, since versionning code may create new IDs... See T57066. */ BLT_lang_set(NULL); /* reports cant be initialized before the wm, * but keep before file reading, since that may report errors */ wm_init_reports(C); /* get the default database, plus a wm */ wm_homefile_read(C, NULL, G.factory_startup, false, true, NULL, WM_init_state_app_template_get()); /* Call again to set from userpreferences... */ BLT_lang_set(NULL); if (!G.background) { #ifdef WITH_INPUT_NDOF /* sets 3D mouse deadzone */ WM_ndof_deadzone_set(U.ndof_deadzone); #endif GPU_init(); GPU_set_mipmap(G_MAIN, !(U.gameflags & USER_DISABLE_MIPMAP)); GPU_set_linear_mipmap(true); GPU_set_anisotropic(G_MAIN, U.anisotropic_filter); GPU_set_gpu_mipmapping(G_MAIN, U.use_gpu_mipmap); #ifdef WITH_OPENSUBDIV BKE_subsurf_osd_init(); #endif UI_init(); } else { /* Note: Currently only inits icons, which we now want in background mode too * (scripts could use those in background processing...). * In case we do more later, we may need to pass a 'background' flag. * Called from 'UI_init' above */ BKE_icons_init(1); } ED_spacemacros_init(); /* note: there is a bug where python needs initializing before loading the * startup.blend because it may contain PyDrivers. It also needs to be after * initializing space types and other internal data. * * However cant redo this at the moment. Solution is to load python * before wm_homefile_read() or make py-drivers check if python is running. * Will try fix when the crash can be repeated. - campbell. */ #ifdef WITH_PYTHON BPY_context_set(C); /* necessary evil */ BPY_python_start(argc, argv); BPY_python_reset(C); #else (void)argc; /* unused */ (void)argv; /* unused */ #endif if (!G.background && !wm_start_with_console) GHOST_toggleConsole(3); clear_matcopybuf(); ED_render_clear_mtex_copybuf(); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); wm_history_file_read(); /* allow a path of "", this is what happens when making a new file */ #if 0 if (BKE_main_blendfile_path_from_global()[0] == '\0') BLI_make_file_string("/", G_MAIN->name, BKE_appdir_folder_default(), "untitled.blend"); #endif BLI_strncpy(G.lib, BKE_main_blendfile_path_from_global(), sizeof(G.lib)); #ifdef WITH_COMPOSITOR if (1) { extern void *COM_linker_hack; COM_linker_hack = COM_execute; } #endif /* load last session, uses regular file reading so it has to be in end (after init py etc) */ if (U.uiflag2 & USER_KEEP_SESSION) { /* calling WM_recover_last_session(C, NULL) has been moved to creator.c */ /* that prevents loading both the kept session, and the file on the command line */ } else { Main *bmain = CTX_data_main(C); /* note, logic here is from wm_file_read_post, * call functions that depend on Python being initialized. */ /* normally 'wm_homefile_read' will do this, * however python is not initialized when called from this function. * * unlikely any handlers are set but its possible, * note that recovering the last session does its own callbacks. */ CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); BLI_callback_exec(bmain, NULL, BLI_CB_EVT_VERSION_UPDATE); BLI_callback_exec(bmain, NULL, BLI_CB_EVT_LOAD_POST); wm_file_read_report(C, bmain); if (!G.background) { CTX_wm_window_set(C, NULL); } } }
/* only called once, for startup */ void WM_init(bContext *C, int argc, const char **argv) { if (!G.background) { wm_ghost_init(C); /* note: it assigns C to ghost! */ wm_init_cursor_data(); } GHOST_CreateSystemPaths(); BKE_addon_pref_type_init(); wm_operatortype_init(); WM_menutype_init(); WM_uilisttype_init(); set_free_windowmanager_cb(wm_close_and_free); /* library.c */ set_free_notifier_reference_cb(WM_main_remove_notifier_reference); /* library.c */ set_blender_test_break_cb(wm_window_testbreak); /* blender.c */ DAG_editors_update_cb(ED_render_id_flush_update, ED_render_scene_update); /* depsgraph.c */ ED_spacetypes_init(); /* editors/space_api/spacetype.c */ ED_file_init(); /* for fsmenu */ ED_node_init_butfuncs(); BLF_init(11, U.dpi); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */ BLF_lang_init(); /* get the default database, plus a wm */ wm_homefile_read(C, NULL, G.factory_startup); BLF_lang_set(NULL); /* note: there is a bug where python needs initializing before loading the * startup.blend because it may contain PyDrivers. It also needs to be after * initializing space types and other internal data. * * However cant redo this at the moment. Solution is to load python * before wm_homefile_read() or make py-drivers check if python is running. * Will try fix when the crash can be repeated. - campbell. */ #ifdef WITH_PYTHON BPY_context_set(C); /* necessary evil */ BPY_python_start(argc, argv); BPY_python_reset(C); #else (void)argc; /* unused */ (void)argv; /* unused */ #endif if (!G.background && !wm_start_with_console) GHOST_toggleConsole(3); wm_init_reports(C); /* reports cant be initialized before the wm */ if (!G.background) { GPU_extensions_init(); GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP)); GPU_set_anisotropic(U.anisotropic_filter); GPU_set_gpu_mipmapping(U.use_gpu_mipmap); UI_init(); } clear_matcopybuf(); ED_render_clear_mtex_copybuf(); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); ED_preview_init_dbase(); wm_read_history(); /* allow a path of "", this is what happens when making a new file */ #if 0 if (G.main->name[0] == 0) BLI_make_file_string("/", G.main->name, BLI_getDefaultDocumentFolder(), "untitled.blend"); #endif BLI_strncpy(G.lib, G.main->name, FILE_MAX); #ifdef WITH_COMPOSITOR if (1) { extern void *COM_linker_hack; COM_linker_hack = COM_execute; } #endif /* load last session, uses regular file reading so it has to be in end (after init py etc) */ if (U.uiflag2 & USER_KEEP_SESSION) { /* calling WM_recover_last_session(C, NULL) has been moved to creator.c */ /* that prevents loading both the kept session, and the file on the command line */ } else { /* normally 'wm_homefile_read' will do this, * however python is not initialized when called from this function. * * unlikely any handlers are set but its possible, * note that recovering the last session does its own callbacks. */ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); } }
/* name can be a dynamic string */ void BKE_write_undo(bContext *C, const char *name) { uintptr_t maxmem, totmem, memused; int nr /*, success */ /* UNUSED */; UndoElem *uel; if ((U.uiflag & USER_GLOBALUNDO) == 0) { return; } if (U.undosteps == 0) { return; } /* remove all undos after (also when curundo == NULL) */ while (undobase.last != curundo) { uel = undobase.last; BLI_remlink(&undobase, uel); BLO_free_memfile(&uel->memfile); MEM_freeN(uel); } /* make new */ curundo = uel = MEM_callocN(sizeof(UndoElem), "undo file"); BLI_strncpy(uel->name, name, sizeof(uel->name)); BLI_addtail(&undobase, uel); /* and limit amount to the maximum */ nr = 0; uel = undobase.last; while (uel) { nr++; if (nr == U.undosteps) break; uel = uel->prev; } if (uel) { while (undobase.first != uel) { UndoElem *first = undobase.first; BLI_remlink(&undobase, first); /* the merge is because of compression */ BLO_merge_memfile(&first->memfile, &first->next->memfile); MEM_freeN(first); } } /* disk save version */ if (UNDO_DISK) { static int counter = 0; char filepath[FILE_MAX]; char numstr[32]; int fileflags = G.fileflags & ~(G_FILE_HISTORY); /* don't do file history on undo */ /* calculate current filepath */ counter++; counter = counter % U.undosteps; BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter); BLI_make_file_string("/", filepath, BKE_tempdir_session(), numstr); /* success = */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); BLI_strncpy(curundo->str, filepath, sizeof(curundo->str)); } else { MemFile *prevfile = NULL; if (curundo->prev) prevfile = &(curundo->prev->memfile); memused = MEM_get_memory_in_use(); /* success = */ /* UNUSED */ BLO_write_file_mem(CTX_data_main(C), prevfile, &curundo->memfile, G.fileflags); curundo->undosize = MEM_get_memory_in_use() - memused; } if (U.undomemory != 0) { /* limit to maximum memory (afterwards, we can't know in advance) */ totmem = 0; maxmem = ((uintptr_t)U.undomemory) * 1024 * 1024; /* keep at least two (original + other) */ uel = undobase.last; while (uel && uel->prev) { totmem += uel->undosize; if (totmem > maxmem) break; uel = uel->prev; } if (uel) { if (uel->prev && uel->prev->prev) uel = uel->prev; while (undobase.first != uel) { UndoElem *first = undobase.first; BLI_remlink(&undobase, first); /* the merge is because of compression */ BLO_merge_memfile(&first->memfile, &first->next->memfile); MEM_freeN(first); } } } }
short ED_fileselect_set_params(SpaceFile *sfile) { char name[FILE_MAX], dir[FILE_MAX], file[FILE_MAX]; FileSelectParams *params; wmOperator *op = sfile->op; /* create new parameters if necessary */ if (!sfile->params) { sfile->params= MEM_callocN(sizeof(FileSelectParams), "fileselparams"); /* set path to most recently opened .blend */ BLI_strncpy(sfile->params->dir, G.sce, sizeof(sfile->params->dir)); BLI_split_dirfile(G.sce, dir, file); BLI_strncpy(sfile->params->file, file, sizeof(sfile->params->file)); BLI_make_file_string(G.sce, sfile->params->dir, dir, ""); /* XXX needed ? - also solve G.sce */ } params = sfile->params; /* set the parameters from the operator, if it exists */ if (op) { BLI_strncpy(params->title, op->type->name, sizeof(params->title)); if(RNA_struct_find_property(op->ptr, "filename")) params->type = RNA_int_get(op->ptr, "filemode"); else params->type = FILE_SPECIAL; if (RNA_property_is_set(op->ptr, "path")) { RNA_string_get(op->ptr, "path", name); if (params->type == FILE_LOADLIB) { BLI_strncpy(params->dir, name, sizeof(params->dir)); BLI_cleanup_dir(G.sce, params->dir); } else { /* if operator has path set, use it, otherwise keep the last */ BLI_convertstringcode(name, G.sce); BLI_split_dirfile(name, dir, file); BLI_strncpy(params->file, file, sizeof(params->file)); BLI_make_file_string(G.sce, params->dir, dir, ""); /* XXX needed ? - also solve G.sce */ } } params->filter = 0; if(RNA_struct_find_property(op->ptr, "filter_blender")) params->filter |= RNA_boolean_get(op->ptr, "filter_blender") ? BLENDERFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_image")) params->filter |= RNA_boolean_get(op->ptr, "filter_image") ? IMAGEFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_movie")) params->filter |= RNA_boolean_get(op->ptr, "filter_movie") ? MOVIEFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_text")) params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_python")) params->filter |= RNA_boolean_get(op->ptr, "filter_python") ? PYSCRIPTFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_font")) params->filter |= RNA_boolean_get(op->ptr, "filter_font") ? FTFONTFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_sound")) params->filter |= RNA_boolean_get(op->ptr, "filter_sound") ? SOUNDFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_text")) params->filter |= RNA_boolean_get(op->ptr, "filter_text") ? TEXTFILE : 0; if(RNA_struct_find_property(op->ptr, "filter_folder")) params->filter |= RNA_boolean_get(op->ptr, "filter_folder") ? FOLDERFILE : 0; if (params->filter != 0) params->flag |= FILE_FILTER; params->flag |= FILE_HIDE_DOT; if (params->type == FILE_LOADLIB) { params->flag |= RNA_boolean_get(op->ptr, "link") ? FILE_LINK : 0; params->flag |= RNA_boolean_get(op->ptr, "autoselect") ? FILE_AUTOSELECT : 0; params->flag |= RNA_boolean_get(op->ptr, "active_layer") ? FILE_ACTIVELAY : 0; } if(params->filter & (IMAGEFILE|MOVIEFILE)) params->display= FILE_IMGDISPLAY; else params->display= FILE_SHORTDISPLAY; } else { /* default values, if no operator */ params->type = FILE_UNIX; params->flag |= FILE_HIDE_DOT; params->display = FILE_SHORTDISPLAY; params->filter = 0; params->sort = FILE_SORT_ALPHA; } return 1; }
/* note, doesnt run exit() call WM_exit() for that */ void WM_exit_ext(bContext *C, const short do_python) { wmWindowManager *wm = C ? CTX_wm_manager(C) : NULL; sound_exit(); /* first wrap up running stuff, we assume only the active WM is running */ /* modal handlers are on window level freed, others too? */ /* note; same code copied in wm_files.c */ if (C && wm) { wmWindow *win; if (!G.background) { if ((U.uiflag2 & USER_KEEP_SESSION) || BKE_undo_valid(NULL)) { /* save the undo state as quit.blend */ char filename[FILE_MAX]; BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE); if (BKE_undo_save_file(filename)) printf("Saved session recovery to '%s'\n", filename); } } WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { CTX_wm_window_set(C, win); /* needed by operator close callbacks */ WM_event_remove_handlers(C, &win->handlers); WM_event_remove_handlers(C, &win->modalhandlers); ED_screen_exit(C, win, win->screen); } } BKE_addon_pref_type_free(); wm_operatortype_free(); wm_dropbox_free(); WM_menutype_free(); WM_uilisttype_free(); /* all non-screen and non-space stuff editors did, like editmode */ if (C) ED_editors_exit(C); // XXX // BIF_GlobalReebFree(); // BIF_freeRetarget(); BIF_freeTemplates(C); free_openrecent(); BKE_mball_cubeTable_free(); /* render code might still access databases */ RE_FreeAllRender(); RE_engines_exit(); ED_preview_free_dbase(); /* frees a Main dbase, before free_blender! */ if (C && wm) wm_free_reports(C); /* before free_blender! - since the ListBases get freed there */ BKE_sequencer_free_clipboard(); /* sequencer.c */ BKE_tracking_clipboard_free(); #ifdef WITH_COMPOSITOR COM_deinitialize(); #endif free_blender(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); free_anim_copybuf(); free_anim_drivers_copybuf(); free_fmodifiers_copybuf(); ED_clipboard_posebuf_free(); BKE_node_clipboard_clear(); BLF_exit(); #ifdef WITH_INTERNATIONAL BLF_free_unifont(); BLF_free_unifont_mono(); BLF_lang_free(); #endif ANIM_keyingset_infos_exit(); // free_txt_data(); #ifdef WITH_PYTHON /* option not to close python so we can use 'atexit' */ if (do_python) { /* XXX - old note */ /* before free_blender so py's gc happens while library still exists */ /* needed at least for a rare sigsegv that can happen in pydrivers */ /* Update for blender 2.5, move after free_blender because blender now holds references to PyObject's * so decref'ing them after python ends causes bad problems every time * the pyDriver bug can be fixed if it happens again we can deal with it then */ BPY_python_end(); } #else (void)do_python; #endif GPU_global_buffer_pool_free(); GPU_free_unused_buffers(); GPU_extensions_exit(); BKE_reset_undo(); ED_file_exit(); /* for fsmenu */ UI_exit(); BKE_userdef_free(); RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */ wm_ghost_exit(); CTX_free(C); #ifdef WITH_GAMEENGINE SYS_DeleteSystem(SYS_GetSystem()); #endif GHOST_DisposeSystemPaths(); if (MEM_get_memory_blocks_in_use() != 0) { printf("Error: Not freed memory blocks: %d\n", MEM_get_memory_blocks_in_use()); MEM_printmemlist(); } wm_autosave_delete(); printf("\nBlender quit\n"); #ifdef WIN32 /* ask user to press a key when in debug mode */ if (G.debug & G_DEBUG) { printf("Press any key to exit . . .\n\n"); wait_for_console_key(); } #endif }
/* only called once, for startup */ void WM_init(bContext *C, int argc, const char **argv) { if (!G.background) { wm_ghost_init(C); /* note: it assigns C to ghost! */ wm_init_cursor_data(); } GHOST_CreateSystemPaths(); wm_operatortype_init(); WM_menutype_init(); set_free_windowmanager_cb(wm_close_and_free); /* library.c */ set_blender_test_break_cb(wm_window_testbreak); /* blender.c */ DAG_editors_update_cb(ED_render_id_flush_update, ED_render_scene_update); /* depsgraph.c */ ED_spacetypes_init(); /* editors/space_api/spacetype.c */ ED_file_init(); /* for fsmenu */ ED_init_node_butfuncs(); BLF_init(11, U.dpi); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */ BLF_lang_init(); /* get the default database, plus a wm */ WM_read_homefile(C, NULL, G.factory_startup); BLF_lang_set(NULL); /* note: there is a bug where python needs initializing before loading the * startup.blend because it may contain PyDrivers. It also needs to be after * initializing space types and other internal data. * * However cant redo this at the moment. Solution is to load python * before WM_read_homefile() or make py-drivers check if python is running. * Will try fix when the crash can be repeated. - campbell. */ #ifdef WITH_PYTHON BPY_context_set(C); /* necessary evil */ BPY_python_start(argc, argv); BPY_driver_reset(); BPY_app_handlers_reset(FALSE); /* causes addon callbacks to be freed [#28068], * but this is actually what we want. */ BPY_modules_load_user(C); #else (void)argc; /* unused */ (void)argv; /* unused */ #endif if (!G.background && !wm_start_with_console) GHOST_toggleConsole(3); wm_init_reports(C); /* reports cant be initialized before the wm */ if (!G.background) { GPU_extensions_init(); GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP)); GPU_set_anisotropic(U.anisotropic_filter); GPU_set_gpu_mipmapping(U.use_gpu_mipmap); UI_init(); } clear_matcopybuf(); ED_render_clear_mtex_copybuf(); // glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); ED_preview_init_dbase(); WM_read_history(); /* allow a path of "", this is what happens when making a new file */ #if 0 if (G.main->name[0] == 0) BLI_make_file_string("/", G.main->name, BLI_getDefaultDocumentFolder(), "untitled.blend"); #endif BLI_strncpy(G.lib, G.main->name, FILE_MAX); #ifdef WITH_COMPOSITOR if (1) { extern void *COM_linker_hack; extern void *COM_execute; COM_linker_hack = COM_execute; } #endif }
/* 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; }