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/windowmanager/intern/wm_files.c')
-rw-r--r--source/blender/windowmanager/intern/wm_files.c929
1 files changed, 929 insertions, 0 deletions
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
new file mode 100644
index 00000000000..20539e15bc0
--- /dev/null
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -0,0 +1,929 @@
+/**
+ * $Id: wm_files.c
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation 2007
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+ /* placed up here because of crappy
+ * winsock stuff.
+ */
+#include <stdio.h>
+#include <string.h>
+
+#ifdef WIN32
+#include <windows.h> /* need to include windows.h so _WIN32_IE is defined */
+#ifndef _WIN32_IE
+#define _WIN32_IE 0x0400 /* minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already */
+#endif
+#include <shlobj.h> /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff because 'near' is disabled through BLI_windstuff */
+#include "BLI_winstuff.h"
+#include <process.h> /* getpid */
+#else
+#include <unistd.h> /* getpid */
+#endif
+
+#include "MEM_guardedalloc.h"
+#include "MEM_CacheLimiterC-Api.h"
+
+#include "BIF_language.h"
+#ifdef INTERNATIONAL
+#include "FTF_Api.h"
+#endif
+
+#include "BLI_blenlib.h"
+#include "BLI_linklist.h"
+
+#include "DNA_object_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BKE_blender.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_exotic.h"
+#include "BKE_font.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_packedFile.h"
+#include "BKE_texture.h"
+#include "BKE_utildefines.h"
+
+#ifdef WITH_VERSE
+#include "BKE_verse.h"
+#endif
+
+#include "BIF_fsmenu.h"
+#include "BIF_interface.h"
+#include "BIF_usiblender.h" /* XXX */
+
+#include "BIF_editsound.h"
+#include "BIF_editmode_undo.h"
+#include "BIF_filelist.h"
+#include "BIF_resources.h"
+#include "BIF_screen.h"
+#include "BIF_space.h"
+#include "BIF_toolbox.h"
+
+#ifdef WITH_VERSE
+#include "BIF_verse.h"
+#endif
+
+#include "BDR_editobject.h"
+
+#include "BLO_readfile.h"
+#include "BLO_writefile.h"
+
+// XXX #include "BPY_extern.h"
+
+#include "datatoc.h"
+
+#include "WM_api.h"
+#include "wm.h"
+
+/***/
+
+/* define for setting colors in theme below */
+#define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
+
+/* patching UserDef struct and Themes */
+static void init_userdef_themes(void)
+{
+
+// XXX BIF_InitTheme(); // sets default again
+
+// countall();
+
+ /* the UserDef struct is not corrected with do_versions() .... ugh! */
+ if(U.wheellinescroll == 0) U.wheellinescroll = 3;
+ if(U.menuthreshold1==0) {
+ U.menuthreshold1= 5;
+ U.menuthreshold2= 2;
+ }
+ if(U.tb_leftmouse==0) {
+ U.tb_leftmouse= 5;
+ U.tb_rightmouse= 5;
+ }
+ if(U.mixbufsize==0) U.mixbufsize= 2048;
+ if (BLI_streq(U.tempdir, "/")) {
+ char *tmp= getenv("TEMP");
+
+ strcpy(U.tempdir, tmp?tmp:"/tmp/");
+ }
+ if (U.savetime <= 0) {
+ U.savetime = 1;
+// XXX error(".B.blend is buggy, please consider removing it.\n");
+ }
+ /* transform widget settings */
+ if(U.tw_hotspot==0) {
+ U.tw_hotspot= 14;
+ U.tw_size= 20; // percentage of window size
+ U.tw_handlesize= 16; // percentage of widget radius
+ }
+ if(U.pad_rot_angle==0)
+ U.pad_rot_angle= 15;
+
+ if(U.flag & USER_CUSTOM_RANGE)
+ vDM_ColorBand_store(&U.coba_weight); /* signal for derivedmesh to use colorband */
+
+ if (G.main->versionfile <= 191) {
+ strcpy(U.plugtexdir, U.textudir);
+ strcpy(U.sounddir, "/");
+ }
+
+ /* patch to set Dupli Armature */
+ if (G.main->versionfile < 220) {
+ U.dupflag |= USER_DUP_ARM;
+ }
+
+ /* userdef new option */
+ if (G.main->versionfile <= 222) {
+ U.vrmlflag= USER_VRML_LAYERS;
+ }
+
+ /* added seam, normal color, undo */
+ if (G.main->versionfile <= 234) {
+ bTheme *btheme;
+
+ U.uiflag |= USER_GLOBALUNDO;
+ if (U.undosteps==0) U.undosteps=32;
+
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* check for alpha==0 is safe, then color was never set */
+ if(btheme->tv3d.edge_seam[3]==0) {
+ SETCOL(btheme->tv3d.edge_seam, 230, 150, 50, 255);
+ }
+ if(btheme->tv3d.normal[3]==0) {
+ SETCOL(btheme->tv3d.normal, 0x22, 0xDD, 0xDD, 255);
+ }
+ if(btheme->tv3d.face_dot[3]==0) {
+ SETCOL(btheme->tv3d.face_dot, 255, 138, 48, 255);
+ btheme->tv3d.facedot_size= 4;
+ }
+ }
+ }
+ if (G.main->versionfile <= 235) {
+ /* illegal combo... */
+ if (U.flag & USER_LMOUSESELECT)
+ U.flag &= ~USER_TWOBUTTONMOUSE;
+ }
+ if (G.main->versionfile <= 236) {
+ bTheme *btheme;
+ /* new space type */
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* check for alpha==0 is safe, then color was never set */
+ if(btheme->ttime.back[3]==0) {
+ btheme->ttime = btheme->tsnd; // copy from sound
+ }
+ if(btheme->text.syntaxn[3]==0) {
+ SETCOL(btheme->text.syntaxn, 0, 0, 200, 255); /* Numbers Blue*/
+ SETCOL(btheme->text.syntaxl, 100, 0, 0, 255); /* Strings red */
+ SETCOL(btheme->text.syntaxc, 0, 100, 50, 255); /* Comments greenish */
+ SETCOL(btheme->text.syntaxv, 95, 95, 0, 255); /* Special */
+ SETCOL(btheme->text.syntaxb, 128, 0, 80, 255); /* Builtin, red-purple */
+ }
+ }
+ }
+ if (G.main->versionfile <= 237) {
+ bTheme *btheme;
+ /* bone colors */
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* check for alpha==0 is safe, then color was never set */
+ if(btheme->tv3d.bone_solid[3]==0) {
+ SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
+ SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80);
+ }
+ }
+ }
+ if (G.main->versionfile <= 238) {
+ bTheme *btheme;
+ /* bone colors */
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* check for alpha==0 is safe, then color was never set */
+ if(btheme->tnla.strip[3]==0) {
+ SETCOL(btheme->tnla.strip_select, 0xff, 0xff, 0xaa, 255);
+ SETCOL(btheme->tnla.strip, 0xe4, 0x9c, 0xc6, 255);
+ }
+ }
+ }
+ if (G.main->versionfile <= 239) {
+ bTheme *btheme;
+
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* Lamp theme, check for alpha==0 is safe, then color was never set */
+ if(btheme->tv3d.lamp[3]==0) {
+ SETCOL(btheme->tv3d.lamp, 0, 0, 0, 40);
+/* TEMPORAL, remove me! (ton) */
+ U.uiflag |= USER_PLAINMENUS;
+ }
+
+ /* check for text field selection highlight, set it to text editor highlight by default */
+ if(btheme->tui.textfield_hi[3]==0) {
+ SETCOL(btheme->tui.textfield_hi,
+ btheme->text.shade2[0],
+ btheme->text.shade2[1],
+ btheme->text.shade2[2],
+ 255);
+ }
+ }
+ if(U.obcenter_dia==0) U.obcenter_dia= 6;
+ }
+ if (G.main->versionfile <= 241) {
+ bTheme *btheme;
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* Node editor theme, check for alpha==0 is safe, then color was never set */
+ if(btheme->tnode.syntaxn[3]==0) {
+ /* re-uses syntax color storage */
+ btheme->tnode= btheme->tv3d;
+ SETCOL(btheme->tnode.edge_select, 255, 255, 255, 255);
+ SETCOL(btheme->tnode.syntaxl, 150, 150, 150, 255); /* TH_NODE, backdrop */
+ SETCOL(btheme->tnode.syntaxn, 129, 131, 144, 255); /* in/output */
+ SETCOL(btheme->tnode.syntaxb, 127,127,127, 255); /* operator */
+ SETCOL(btheme->tnode.syntaxv, 142, 138, 145, 255); /* generator */
+ SETCOL(btheme->tnode.syntaxc, 120, 145, 120, 255); /* group */
+ }
+ /* Group theme colors */
+ if(btheme->tv3d.group[3]==0) {
+ SETCOL(btheme->tv3d.group, 0x10, 0x40, 0x10, 255);
+ SETCOL(btheme->tv3d.group_active, 0x66, 0xFF, 0x66, 255);
+ }
+ /* Sequence editor theme*/
+ if(btheme->tseq.movie[3]==0) {
+ SETCOL(btheme->tseq.movie, 81, 105, 135, 255);
+ SETCOL(btheme->tseq.image, 109, 88, 129, 255);
+ SETCOL(btheme->tseq.scene, 78, 152, 62, 255);
+ SETCOL(btheme->tseq.audio, 46, 143, 143, 255);
+ SETCOL(btheme->tseq.effect, 169, 84, 124, 255);
+ SETCOL(btheme->tseq.plugin, 126, 126, 80, 255);
+ SETCOL(btheme->tseq.transition, 162, 95, 111, 255);
+ SETCOL(btheme->tseq.meta, 109, 145, 131, 255);
+ }
+ if(!(btheme->tui.iconfile)) {
+ BLI_strncpy(btheme->tui.iconfile, "", sizeof(btheme->tui.iconfile));
+ }
+ }
+
+ /* set defaults for 3D View rotating axis indicator */
+ /* since size can't be set to 0, this indicates it's not saved in .B.blend */
+ if (U.rvisize == 0) {
+ U.rvisize = 15;
+ U.rvibright = 8;
+ U.uiflag |= USER_SHOW_ROTVIEWICON;
+ }
+
+ }
+ if (G.main->versionfile <= 242) {
+ bTheme *btheme;
+
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* long keyframe color */
+ /* check for alpha==0 is safe, then color was never set */
+ if(btheme->tact.strip[3]==0) {
+ SETCOL(btheme->tv3d.edge_sharp, 255, 32, 32, 255);
+ SETCOL(btheme->tact.strip_select, 0xff, 0xff, 0xaa, 204);
+ SETCOL(btheme->tact.strip, 0xe4, 0x9c, 0xc6, 204);
+ }
+
+ /* IPO-Editor - Vertex Size*/
+ if(btheme->tipo.vertex_size == 0) {
+ btheme->tipo.vertex_size= 3;
+ }
+ }
+ }
+ if (G.main->versionfile <= 243) {
+ /* set default number of recently-used files (if not set) */
+ if (U.recent_files == 0) U.recent_files = 10;
+ }
+ if (G.main->versionfile < 245 || (G.main->versionfile == 245 && G.main->subversionfile < 3)) {
+ bTheme *btheme;
+ for(btheme= U.themes.first; btheme; btheme= btheme->next) {
+ SETCOL(btheme->tv3d.editmesh_active, 255, 255, 255, 128);
+ }
+ if(U.coba_weight.tot==0)
+ init_colorband(&U.coba_weight, 1);
+ }
+ if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 11)) {
+ bTheme *btheme;
+ for (btheme= U.themes.first; btheme; btheme= btheme->next) {
+ /* these should all use the same colour */
+ SETCOL(btheme->tv3d.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tipo.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tact.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tnla.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tseq.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->tsnd.cframe, 0x60, 0xc0, 0x40, 255);
+ SETCOL(btheme->ttime.cframe, 0x60, 0xc0, 0x40, 255);
+ }
+ }
+
+ /* GL Texture Garbage Collection (variable abused above!) */
+ if (U.textimeout == 0) {
+ U.texcollectrate = 60;
+ U.textimeout = 120;
+ }
+ if (U.memcachelimit <= 0) {
+ U.memcachelimit = 32;
+ }
+ if (U.frameserverport == 0) {
+ U.frameserverport = 8080;
+ }
+
+ MEM_CacheLimiter_set_maximum(U.memcachelimit * 1024 * 1024);
+
+ /* funny name, but it is GE stuff, moves userdef stuff to engine */
+// XXX space_set_commmandline_options();
+ /* this timer uses U */
+// XXX reset_autosave();
+
+#ifdef WITH_VERSE
+ if(strlen(U.versemaster)<1) {
+ strcpy(U.versemaster, "master.uni-verse.org");
+ }
+ if(strlen(U.verseuser)<1) {
+ char *name = verse_client_name();
+ strcpy(U.verseuser, name);
+ MEM_freeN(name);
+ }
+#endif
+
+}
+
+/* To be able to read files without windows closing, opening, moving
+ we try to prepare for worst case:
+ - active window gets active screen from file
+ - restoring the screens from non-active windows
+ Best case is all screens match, in that case they get assigned to proper window
+*/
+static void wm_window_match_init(bContext *C, ListBase *wmlist)
+{
+ wmWindowManager *wm= G.main->wm.first;
+ wmWindow *win;
+
+ *wmlist= G.main->wm;
+ G.main->wm.first= G.main->wm.last= NULL;
+
+return;
+ if(wm==NULL) return;
+ if(G.fileflags & G_FILE_NO_UI) return;
+
+ /* we take apart the used screens from non-active window */
+ for(win= wm->windows.first; win; win= win->next) {
+ BLI_strncpy(win->screenname, win->screen->id.name, MAX_ID_NAME);
+ if(win!=C->window) {
+ BLI_remlink(&G.main->screen, win->screen);
+ //BLI_addtail(screenbase, win->screen);
+ }
+ }
+}
+
+/* match old WM with new, 4 cases:
+ 1- no current wm, no read wm: make new default
+ 2- no current wm, but read wm: that's OK, do nothing
+ 3- current wm, but not in file: try match screen names
+ 4- current wm, and wm in file: try match ghostwin
+
+*/
+static void wm_window_match_do(bContext *C, ListBase *wmlist)
+{
+ wmWindowManager *oldwm, *wm;
+ wmWindow *oldwin, *win;
+
+ /* cases 1 and 2 */
+ if(wmlist->first==NULL) {
+ if(G.main->wm.first); /* nothing todo */
+ else
+ wm_add_default(C);
+ }
+ else {
+ /* cases 3 and 4 */
+
+ /* we've read file without wm... */
+ if(G.main->wm.first==NULL) {
+ /* match oldwm to new dbase, only old files */
+
+ for(wm= wmlist->first; wm; wm= wm->id.next) {
+ for(win= wm->windows.first; win; win= win->next) {
+ win->screen= (bScreen *)find_id("SR", win->screenname);
+ if(win->screen->winid==0) {
+ if(win->screen==NULL)
+ win->screen= C->screen; /* active screen */
+
+ win->screen->winid= win->winid;
+ }
+ }
+ }
+ /* XXX still solve, case where multiple windows open */
+
+ G.main->wm= *wmlist;
+ }
+ else {
+ /* what if old was 3, and loaded 1? */
+ /* this code could move to setup_appdata */
+ oldwm= wmlist->first;
+ wm= G.main->wm.first;
+ /* only first wm in list has ghostwins */
+ for(win= wm->windows.first; win; win= win->next) {
+ for(oldwin= oldwm->windows.first; oldwin; oldwin= oldwin->next) {
+
+ if(oldwin->winid == win->winid ) {
+ win->ghostwin= oldwin->ghostwin;
+ oldwin->ghostwin= NULL;
+ }
+ }
+ }
+ wm_close_and_free_all(C, wmlist);
+ }
+ }
+}
+
+#ifdef WITH_VERSE
+static void verse_unsub(void)
+{
+ extern ListBase session_list;
+ struct VerseSession *session;
+ struct VNode *vnode;
+
+ session = session_list.first;
+ while(session) {
+ vnode = session->nodes.lb.first;
+ while(vnode) {
+ switch(vnode->type) {
+ case V_NT_OBJECT:
+ unsubscribe_from_obj_node(vnode);
+ break;
+ case V_NT_GEOMETRY:
+ unsubscribe_from_geom_node(vnode);
+ break;
+ case V_NT_BITMAP:
+ unsubscribe_from_bitmap_node(vnode);
+ break;
+ }
+ vnode = vnode->next;
+ }
+ session = session->next;
+ }
+}
+#endif
+
+void WM_read_file(bContext *C, char *name)
+{
+ int retval;
+
+#ifdef WITH_VERSE
+ verse_unsub(); /* bad call here (ton) */
+#endif
+
+ /* first try to append data from exotic file formats... */
+ /* it throws error box when file doesnt exist and returns -1 */
+ retval= BKE_read_exotic(name);
+
+ /* we didn't succeed, now try to read Blender file */
+ if (retval== 0) {
+ ListBase wmbase;
+
+ /* put aside screens to match with persistant windows later */
+ wm_window_match_init(C, &wmbase);
+
+ retval= BKE_read_file(C, name, NULL);
+
+ /* match the read WM with current WM */
+ wm_window_match_do(C, &wmbase);
+
+// XXX mainwindow_set_filename_to_title(G.main->name);
+// countall(); <-- will be listener
+// XXX sound_initialize_sounds();
+
+// winqueue_break= 1; /* leave queues everywhere */
+
+ if(retval==2) init_userdef_themes(); // in case a userdef is read from regular .blend
+
+ if (retval!=0) G.relbase_valid = 1;
+
+// XXX undo_editmode_clear();
+ BKE_reset_undo();
+ BKE_write_undo(C, "original"); /* save current state */
+
+// refresh_interface_font();
+ }
+// else if(retval==1)
+// XXX BIF_undo_push("Import file");
+}
+
+static void outliner_242_patch(void)
+{
+ ScrArea *sa;
+
+ for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
+ SpaceLink *sl= sa->spacedata.first;
+ for(; sl; sl= sl->next) {
+ if(sl->spacetype==SPACE_OOPS) {
+ SpaceOops *soops= (SpaceOops *)sl;
+ if(soops->type!=SO_OUTLINER) {
+ soops->type= SO_OUTLINER;
+// XXX init_v2d_oops(sa, soops);
+ }
+ }
+ }
+ }
+ G.fileflags |= G_FILE_GAME_MAT;
+}
+
+/* called on startup, (context entirely filled with NULLs) */
+/* or called for 'Erase All' */
+int WM_read_homefile(bContext *C, int from_memory)
+{
+ ListBase wmbase;
+ char tstr[FILE_MAXDIR+FILE_MAXFILE], scestr[FILE_MAXDIR];
+ char *home= BLI_gethome();
+ int success;
+
+ BLI_clean(home);
+
+ free_ttfont(); /* still weird... what does it here? */
+
+ G.relbase_valid = 0;
+ if (!from_memory) BLI_make_file_string(G.sce, tstr, home, ".B.blend");
+ strcpy(scestr, G.sce); /* temporary store */
+
+ /* prevent loading no UI */
+ G.fileflags &= ~G_FILE_NO_UI;
+
+ /* put aside screens to match with persistant windows later */
+ wm_window_match_init(C, &wmbase);
+
+ if (!from_memory && BLI_exists(tstr)) {
+ success = BKE_read_file(C, tstr, NULL);
+ } else {
+ success = BKE_read_file_from_memory(C, datatoc_B_blend, datatoc_B_blend_size, NULL);
+ /* outliner patch for 2.42 .b.blend */
+ outliner_242_patch();
+ }
+
+ /* match the read WM with current WM */
+ wm_window_match_do(C, &wmbase);
+
+ strcpy(G.sce, scestr); /* restore */
+
+ init_userdef_themes();
+
+ /* XXX */
+ G.save_over = 0; // start with save preference untitled.blend
+ G.fileflags &= ~G_FILE_AUTOPLAY; /* disable autoplay in .B.blend... */
+// mainwindow_set_filename_to_title(""); // empty string re-initializes title to "Blender"
+
+#ifdef INTERNATIONAL
+// XXX read_languagefile();
+#endif
+
+// refresh_interface_font();
+
+// undo_editmode_clear();
+ BKE_reset_undo();
+ BKE_write_undo(C, "original"); /* save current state */
+
+ return success;
+}
+
+
+static void get_autosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE])
+{
+ char pidstr[32];
+#ifdef WIN32
+ char subdir[9];
+ char savedir[FILE_MAXDIR];
+#endif
+
+ sprintf(pidstr, "%d.blend", abs(getpid()));
+
+#ifdef WIN32
+ if (!BLI_exists(U.tempdir)) {
+ BLI_strncpy(subdir, "autosave", sizeof(subdir));
+ BLI_make_file_string("/", savedir, BLI_gethome(), subdir);
+
+ /* create a new autosave dir
+ * function already checks for existence or not */
+ BLI_recurdir_fileops(savedir);
+
+ BLI_make_file_string("/", buf, savedir, pidstr);
+ return;
+ }
+#endif
+
+ BLI_make_file_string("/", buf, U.tempdir, pidstr);
+}
+
+void WM_read_autosavefile(bContext *C)
+{
+ char tstr[FILE_MAX], scestr[FILE_MAX];
+ int save_over;
+
+ BLI_strncpy(scestr, G.sce, FILE_MAX); /* temporal store */
+
+ get_autosave_location(tstr);
+
+ save_over = G.save_over;
+ BKE_read_file(C, tstr, NULL);
+ G.save_over = save_over;
+ BLI_strncpy(G.sce, scestr, FILE_MAX);
+}
+
+
+void read_Blog(void)
+{
+ char name[FILE_MAX], filename[FILE_MAX];
+ LinkNode *l, *lines;
+ struct RecentFile *recent;
+ char *line;
+ int num;
+
+ BLI_make_file_string("/", name, BLI_gethome(), ".Blog");
+ lines= BLI_read_file_as_lines(name);
+
+ G.recent_files.first = G.recent_files.last = NULL;
+
+ /* read list of recent opend files from .Blog to memory */
+ for (l= lines, num= 0; l && (num<U.recent_files); l= l->next, num++) {
+ line = l->link;
+ if (!BLI_streq(line, "")) {
+ if (num==0)
+ strcpy(G.sce, line);
+
+ recent = (RecentFile*)MEM_mallocN(sizeof(RecentFile),"RecentFile");
+ BLI_addtail(&(G.recent_files), recent);
+ recent->filename = (char*)MEM_mallocN(sizeof(char)*(strlen(line)+1), "name of file");
+ recent->filename[0] = '\0';
+
+ strcpy(recent->filename, line);
+ }
+ }
+
+ if(G.sce[0] == 0)
+ BLI_make_file_string("/", G.sce, BLI_gethome(), "untitled.blend");
+
+ BLI_free_file_lines(lines);
+
+#ifdef WIN32
+ /* Add the drive names to the listing */
+ {
+ __int64 tmp;
+ char folder[MAX_PATH];
+ char tmps[4];
+ int i;
+
+ tmp= GetLogicalDrives();
+
+ for (i=2; i < 26; i++) {
+ if ((tmp>>i) & 1) {
+ tmps[0]='a'+i;
+ tmps[1]=':';
+ tmps[2]='\\';
+ tmps[3]=0;
+
+// XX fsmenu_insert_entry(tmps, 0, 0);
+ }
+ }
+
+ /* Adding Desktop and My Documents */
+// XXX fsmenu_append_separator();
+
+ SHGetSpecialFolderPath(0, folder, CSIDL_PERSONAL, 0);
+// XXX fsmenu_insert_entry(folder, 0, 0);
+ SHGetSpecialFolderPath(0, folder, CSIDL_DESKTOPDIRECTORY, 0);
+// XXX fsmenu_insert_entry(folder, 0, 0);
+
+// XXX fsmenu_append_separator();
+ }
+#endif
+
+ BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs");
+ lines= BLI_read_file_as_lines(name);
+
+ for (l= lines; l; l= l->next) {
+ char *line= l->link;
+
+ if (!BLI_streq(line, "")) {
+// XXX fsmenu_insert_entry(line, 0, 1);
+ }
+ }
+
+// XXX fsmenu_append_separator();
+
+ /* add last saved file */
+ BLI_split_dirfile(G.sce, name, filename); /* G.sce shouldn't be relative */
+
+// XXX fsmenu_insert_entry(name, 0, 0);
+
+ BLI_free_file_lines(lines);
+}
+
+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 void do_history(char *name)
+{
+ char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE];
+ int hisnr= U.versions;
+
+ if(U.versions==0) return;
+ if(strlen(name)<2) return;
+
+ while( hisnr > 1) {
+ sprintf(tempname1, "%s%d", name, hisnr-1);
+ sprintf(tempname2, "%s%d", name, hisnr);
+
+// if(BLI_rename(tempname1, tempname2))
+// XXX error("Unable to make version backup");
+
+ hisnr--;
+ }
+
+ /* is needed when hisnr==1 */
+ sprintf(tempname1, "%s%d", name, hisnr);
+
+// if(BLI_rename(name, tempname1))
+// XXX error("Unable to make version backup");
+}
+
+void WM_write_file(bContext *C, char *target)
+{
+ Library *li;
+ int writeflags, len;
+ char di[FILE_MAX];
+ char *err;
+
+ len = strlen(target);
+
+ if (len == 0) return;
+ if (len >= FILE_MAX) {
+// XXX error("Path too long, cannot save");
+ return;
+ }
+
+ /* send the OnSave event */
+// XXX if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript(&C->scene->id, SCRIPT_ONSAVE);
+
+ for (li= G.main->library.first; li; li= li->id.next) {
+ if (BLI_streq(li->name, target)) {
+// XXX error("Cannot overwrite used library");
+ return;
+ }
+ }
+
+ if (!BLO_has_bfile_extension(target) && (len+6 < FILE_MAX)) {
+ sprintf(di, "%s.blend", target);
+ } else {
+ strcpy(di, target);
+ }
+
+ if (BLI_exists(di)) {
+// XXX if(!saveover(di))
+// XXX return;
+ }
+
+ if(G.obedit) {
+// XXX exit_editmode(0); /* 0 = no free data */
+ }
+ if (G.fileflags & G_AUTOPACK) {
+ packAll();
+ }
+
+// XXX waitcursor(1); // exit_editmode sets cursor too
+
+ do_history(di);
+
+ /* we use the UserDef to define compression flag */
+ writeflags= G.fileflags & ~G_FILE_COMPRESS;
+ if(U.flag & USER_FILECOMPRESS)
+ writeflags |= G_FILE_COMPRESS;
+
+ if (BLO_write_file(C, di, writeflags, &err)) {
+ strcpy(G.sce, di);
+ G.relbase_valid = 1;
+ strcpy(G.main->name, di); /* is guaranteed current file */
+
+// XXX mainwindow_set_filename_to_title(G.main->name);
+
+ G.save_over = 1;
+
+ writeBlog();
+ } else {
+// XXX error("%s", err);
+ }
+
+// XXX waitcursor(0);
+}
+
+/* operator entry */
+int WM_write_homefile(bContext *C, wmOperator *op)
+{
+ char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
+ int write_flags;
+
+ BLI_make_file_string("/", tstr, BLI_gethome(), ".B.blend");
+
+ /* force save as regular blend file */
+ write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
+ BLO_write_file(C, tstr, write_flags, &err);
+
+ return 1;
+}
+
+void WM_write_autosave(bContext *C)
+{
+ char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
+ int write_flags;
+
+ get_autosave_location(tstr);
+
+ /* force save as regular blend file */
+ write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
+ BLO_write_file(C, tstr, write_flags, &err);
+}
+
+/* if global undo; remove tempsave, otherwise rename */
+void delete_autosave(void)
+{
+ char tstr[FILE_MAXDIR+FILE_MAXFILE];
+
+ get_autosave_location(tstr);
+
+ if (BLI_exists(tstr)) {
+ char str[FILE_MAXDIR+FILE_MAXFILE];
+ BLI_make_file_string("/", str, U.tempdir, "quit.blend");
+
+ if(U.uiflag & USER_GLOBALUNDO) BLI_delete(tstr, 0, 0);
+ else BLI_rename(tstr, str);
+ }
+}
+
+/***/
+
+
+
+
+