4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
30 /* placed up here because of crappy
38 #include <windows.h> /* need to include windows.h so _WIN32_IE is defined */
40 #define _WIN32_IE 0x0400 /* minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already */
42 #include <shlobj.h> /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff because 'near' is disabled through BLI_windstuff */
43 #include "BLI_winstuff.h"
44 #include <process.h> /* getpid */
46 #include <unistd.h> /* getpid */
48 #include "MEM_guardedalloc.h"
49 #include "MEM_CacheLimiterC-Api.h"
52 #include "BIF_language.h"
57 #include "BLI_blenlib.h"
58 #include "BLI_arithb.h"
59 #include "BLI_linklist.h"
61 #include "IMB_imbuf_types.h"
62 #include "IMB_imbuf.h"
64 #include "DNA_object_types.h"
65 #include "DNA_space_types.h"
66 #include "DNA_userdef_types.h"
67 #include "DNA_sound_types.h"
68 #include "DNA_scene_types.h"
69 #include "DNA_screen_types.h"
71 #include "BKE_blender.h"
72 #include "BKE_curve.h"
73 #include "BKE_displist.h"
74 #include "BKE_DerivedMesh.h"
75 #include "BKE_exotic.h"
77 #include "BKE_global.h"
79 #include "BKE_mball.h"
81 #include "BKE_packedFile.h"
82 #include "BKE_texture.h"
83 #include "BKE_utildefines.h"
84 #include "BKE_pointcache.h"
87 #include "BKE_verse.h"
90 #include "BLI_vfontdata.h"
92 #include "BIF_fsmenu.h"
94 #include "BIF_interface.h"
95 #include "BIF_usiblender.h"
96 #include "BIF_drawtext.h"
97 #include "BIF_editaction.h"
98 #include "BIF_editarmature.h"
99 #include "BIF_editlattice.h"
100 #include "BIF_editfont.h"
101 #include "BIF_editmesh.h"
102 #include "BIF_editmode_undo.h"
103 #include "BIF_editsound.h"
104 #include "BIF_filelist.h"
105 #include "BIF_poseobject.h"
106 #include "BIF_previewrender.h"
107 #include "BIF_renderwin.h"
108 #include "BIF_resources.h"
109 #include "BIF_screen.h"
110 #include "BIF_space.h"
111 #include "BIF_toolbox.h"
112 #include "BIF_cursors.h"
115 #include "BIF_verse.h"
119 #include "BSE_drawview.h"
120 #include "BSE_edit.h"
121 #include "BSE_editipo.h"
122 #include "BSE_filesel.h"
123 #include "BSE_headerbuttons.h"
124 #include "BSE_node.h"
126 #include "BLO_readfile.h"
127 #include "BLO_writefile.h"
129 #include "BDR_drawobject.h"
130 #include "BDR_editobject.h"
131 #include "BDR_editcurve.h"
132 #include "BDR_imagepaint.h"
133 #include "BDR_vpaint.h"
135 #include "BPY_extern.h"
139 #include "RE_pipeline.h" /* RE_ free stuff */
144 #include "SYS_System.h"
146 #include "PIL_time.h"
150 /* define for setting colors in theme below */
151 #define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
153 /* patching UserDef struct, set globals for UI stuff */
154 static void init_userdef_file(void)
157 BIF_InitTheme(); // sets default again
159 mainwindow_set_filename_to_title(""); // empty string re-initializes title to "Blender"
161 G.save_over = 0; // start with save preference untitled.blend
163 /* disable autoplay in .B.blend... */
164 G.fileflags &= ~G_FILE_AUTOPLAY;
166 /* the UserDef struct is not corrected with do_versions() .... ugh! */
167 if(U.wheellinescroll == 0) U.wheellinescroll = 3;
168 if(U.menuthreshold1==0) {
172 if(U.tb_leftmouse==0) {
176 if(U.mixbufsize==0) U.mixbufsize= 2048;
177 if (BLI_streq(U.tempdir, "/")) {
178 BLI_where_is_temp(U.tempdir, 0);
180 if (U.savetime <= 0) {
182 error(".B.blend is buggy, please consider removing it.\n");
184 /* transform widget settings */
185 if(U.tw_hotspot==0) {
187 U.tw_size= 20; // percentage of window size
188 U.tw_handlesize= 16; // percentage of widget radius
190 if(U.pad_rot_angle==0)
196 if (U.ndof_rotate==0) {
200 if(U.flag & USER_CUSTOM_RANGE)
201 vDM_ColorBand_store(&U.coba_weight); /* signal for derivedmesh to use colorband */
203 /* Auto-keyframing settings */
204 if(U.autokey_mode == 0) {
205 /* AUTOKEY_MODE_NORMAL - AUTOKEY_ON = x <==> 3 - 1 = 2 */
208 if(U.flag & (1<<15)) U.autokey_flag |= AUTOKEY_FLAG_INSERTAVAIL;
209 if(U.flag & (1<<19)) U.autokey_flag |= AUTOKEY_FLAG_INSERTNEEDED;
210 if(G.flags & (1<<30)) U.autokey_flag |= AUTOKEY_FLAG_AUTOMATKEY;
213 if (G.main->versionfile <= 191) {
214 strcpy(U.plugtexdir, U.textudir);
215 strcpy(U.sounddir, "/");
218 /* patch to set Dupli Armature */
219 if (G.main->versionfile < 220) {
220 U.dupflag |= USER_DUP_ARM;
223 /* userdef new option */
224 if (G.main->versionfile <= 222) {
225 U.vrmlflag= USER_VRML_LAYERS;
228 /* added seam, normal color, undo */
229 if (G.main->versionfile <= 234) {
232 U.uiflag |= USER_GLOBALUNDO;
233 if (U.undosteps==0) U.undosteps=32;
235 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
236 /* check for alpha==0 is safe, then color was never set */
237 if(btheme->tv3d.edge_seam[3]==0) {
238 SETCOL(btheme->tv3d.edge_seam, 230, 150, 50, 255);
240 if(btheme->tv3d.normal[3]==0) {
241 SETCOL(btheme->tv3d.normal, 0x22, 0xDD, 0xDD, 255);
243 if(btheme->tv3d.face_dot[3]==0) {
244 SETCOL(btheme->tv3d.face_dot, 255, 138, 48, 255);
245 btheme->tv3d.facedot_size= 4;
249 if (G.main->versionfile <= 235) {
250 /* illegal combo... */
251 if (U.flag & USER_LMOUSESELECT)
252 U.flag &= ~USER_TWOBUTTONMOUSE;
254 if (G.main->versionfile <= 236) {
257 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
258 /* check for alpha==0 is safe, then color was never set */
259 if(btheme->ttime.back[3]==0) {
260 btheme->ttime = btheme->tsnd; // copy from sound
262 if(btheme->text.syntaxn[3]==0) {
263 SETCOL(btheme->text.syntaxn, 0, 0, 200, 255); /* Numbers Blue*/
264 SETCOL(btheme->text.syntaxl, 100, 0, 0, 255); /* Strings red */
265 SETCOL(btheme->text.syntaxc, 0, 100, 50, 255); /* Comments greenish */
266 SETCOL(btheme->text.syntaxv, 95, 95, 0, 255); /* Special */
267 SETCOL(btheme->text.syntaxb, 128, 0, 80, 255); /* Builtin, red-purple */
271 if (G.main->versionfile <= 237) {
274 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
275 /* check for alpha==0 is safe, then color was never set */
276 if(btheme->tv3d.bone_solid[3]==0) {
277 SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
278 SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80);
282 if (G.main->versionfile <= 238) {
285 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
286 /* check for alpha==0 is safe, then color was never set */
287 if(btheme->tnla.strip[3]==0) {
288 SETCOL(btheme->tnla.strip_select, 0xff, 0xff, 0xaa, 255);
289 SETCOL(btheme->tnla.strip, 0xe4, 0x9c, 0xc6, 255);
293 if (G.main->versionfile <= 239) {
296 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
297 /* Lamp theme, check for alpha==0 is safe, then color was never set */
298 if(btheme->tv3d.lamp[3]==0) {
299 SETCOL(btheme->tv3d.lamp, 0, 0, 0, 40);
300 /* TEMPORAL, remove me! (ton) */
301 U.uiflag |= USER_PLAINMENUS;
304 /* check for text field selection highlight, set it to text editor highlight by default */
305 if(btheme->tui.textfield_hi[3]==0) {
306 SETCOL(btheme->tui.textfield_hi,
307 btheme->text.shade2[0],
308 btheme->text.shade2[1],
309 btheme->text.shade2[2],
313 if(U.obcenter_dia==0) U.obcenter_dia= 6;
315 if (G.main->versionfile <= 241) {
317 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
318 /* Node editor theme, check for alpha==0 is safe, then color was never set */
319 if(btheme->tnode.syntaxn[3]==0) {
320 /* re-uses syntax color storage */
321 btheme->tnode= btheme->tv3d;
322 SETCOL(btheme->tnode.edge_select, 255, 255, 255, 255);
323 SETCOL(btheme->tnode.syntaxl, 150, 150, 150, 255); /* TH_NODE, backdrop */
324 SETCOL(btheme->tnode.syntaxn, 129, 131, 144, 255); /* in/output */
325 SETCOL(btheme->tnode.syntaxb, 127,127,127, 255); /* operator */
326 SETCOL(btheme->tnode.syntaxv, 142, 138, 145, 255); /* generator */
327 SETCOL(btheme->tnode.syntaxc, 120, 145, 120, 255); /* group */
329 /* Group theme colors */
330 if(btheme->tv3d.group[3]==0) {
331 SETCOL(btheme->tv3d.group, 0x10, 0x40, 0x10, 255);
332 SETCOL(btheme->tv3d.group_active, 0x66, 0xFF, 0x66, 255);
334 /* Sequence editor theme*/
335 if(btheme->tseq.movie[3]==0) {
336 SETCOL(btheme->tseq.movie, 81, 105, 135, 255);
337 SETCOL(btheme->tseq.image, 109, 88, 129, 255);
338 SETCOL(btheme->tseq.scene, 78, 152, 62, 255);
339 SETCOL(btheme->tseq.audio, 46, 143, 143, 255);
340 SETCOL(btheme->tseq.effect, 169, 84, 124, 255);
341 SETCOL(btheme->tseq.plugin, 126, 126, 80, 255);
342 SETCOL(btheme->tseq.transition, 162, 95, 111, 255);
343 SETCOL(btheme->tseq.meta, 109, 145, 131, 255);
345 if(!(btheme->tui.iconfile)) {
346 BLI_strncpy(btheme->tui.iconfile, "", sizeof(btheme->tui.iconfile));
350 /* set defaults for 3D View rotating axis indicator */
351 /* since size can't be set to 0, this indicates it's not saved in .B.blend */
352 if (U.rvisize == 0) {
355 U.uiflag |= USER_SHOW_ROTVIEWICON;
359 if (G.main->versionfile <= 242) {
362 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
363 /* long keyframe color */
364 /* check for alpha==0 is safe, then color was never set */
365 if(btheme->tact.strip[3]==0) {
366 SETCOL(btheme->tv3d.edge_sharp, 255, 32, 32, 255);
367 SETCOL(btheme->tact.strip_select, 0xff, 0xff, 0xaa, 204);
368 SETCOL(btheme->tact.strip, 0xe4, 0x9c, 0xc6, 204);
371 /* IPO-Editor - Vertex Size*/
372 if(btheme->tipo.vertex_size == 0) {
373 btheme->tipo.vertex_size= 3;
377 if (G.main->versionfile <= 243) {
378 /* set default number of recently-used files (if not set) */
379 if (U.recent_files == 0) U.recent_files = 10;
381 if (G.main->versionfile < 245 || (G.main->versionfile == 245 && G.main->subversionfile < 3)) {
383 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
384 SETCOL(btheme->tv3d.editmesh_active, 255, 255, 255, 128);
386 if(U.coba_weight.tot==0)
387 init_colorband(&U.coba_weight, 1);
389 if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 11)) {
391 for (btheme= U.themes.first; btheme; btheme= btheme->next) {
392 /* these should all use the same colour */
393 SETCOL(btheme->tv3d.cframe, 0x60, 0xc0, 0x40, 255);
394 SETCOL(btheme->tipo.cframe, 0x60, 0xc0, 0x40, 255);
395 SETCOL(btheme->tact.cframe, 0x60, 0xc0, 0x40, 255);
396 SETCOL(btheme->tnla.cframe, 0x60, 0xc0, 0x40, 255);
397 SETCOL(btheme->tseq.cframe, 0x60, 0xc0, 0x40, 255);
398 SETCOL(btheme->tsnd.cframe, 0x60, 0xc0, 0x40, 255);
399 SETCOL(btheme->ttime.cframe, 0x60, 0xc0, 0x40, 255);
402 if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 13)) {
404 for (btheme= U.themes.first; btheme; btheme= btheme->next) {
405 /* action channel groups (recolour anyway) */
406 SETCOL(btheme->tact.group, 0x39, 0x7d, 0x1b, 255);
407 SETCOL(btheme->tact.group_active, 0x7d, 0xe9, 0x60, 255);
409 /* bone custom-color sets */
410 // FIXME: this check for initialised colors is bad
411 if (btheme->tarm[0].solid[3] == 0) {
413 SETCOL(btheme->tarm[0].solid, 0x9a, 0x00, 0x00, 255);
414 SETCOL(btheme->tarm[0].select, 0xbd, 0x11, 0x11, 255);
415 SETCOL(btheme->tarm[0].active, 0xf7, 0x0a, 0x0a, 255);
417 SETCOL(btheme->tarm[1].solid, 0xf7, 0x40, 0x18, 255);
418 SETCOL(btheme->tarm[1].select, 0xf6, 0x69, 0x13, 255);
419 SETCOL(btheme->tarm[1].active, 0xfa, 0x99, 0x00, 255);
421 SETCOL(btheme->tarm[2].solid, 0x1e, 0x91, 0x09, 255);
422 SETCOL(btheme->tarm[2].select, 0x59, 0xb7, 0x0b, 255);
423 SETCOL(btheme->tarm[2].active, 0x83, 0xef, 0x1d, 255);
425 SETCOL(btheme->tarm[3].solid, 0x0a, 0x36, 0x94, 255);
426 SETCOL(btheme->tarm[3].select, 0x36, 0x67, 0xdf, 255);
427 SETCOL(btheme->tarm[3].active, 0x5e, 0xc1, 0xef, 255);
429 SETCOL(btheme->tarm[4].solid, 0xa9, 0x29, 0x4e, 255);
430 SETCOL(btheme->tarm[4].select, 0xc1, 0x41, 0x6a, 255);
431 SETCOL(btheme->tarm[4].active, 0xf0, 0x5d, 0x91, 255);
433 SETCOL(btheme->tarm[5].solid, 0x43, 0x0c, 0x78, 255);
434 SETCOL(btheme->tarm[5].select, 0x54, 0x3a, 0xa3, 255);
435 SETCOL(btheme->tarm[5].active, 0x87, 0x64, 0xd5, 255);
437 SETCOL(btheme->tarm[6].solid, 0x24, 0x78, 0x5a, 255);
438 SETCOL(btheme->tarm[6].select, 0x3c, 0x95, 0x79, 255);
439 SETCOL(btheme->tarm[6].active, 0x6f, 0xb6, 0xab, 255);
441 SETCOL(btheme->tarm[7].solid, 0x4b, 0x70, 0x7c, 255);
442 SETCOL(btheme->tarm[7].select, 0x6a, 0x86, 0x91, 255);
443 SETCOL(btheme->tarm[7].active, 0x9b, 0xc2, 0xcd, 255);
445 SETCOL(btheme->tarm[8].solid, 0xf4, 0xc9, 0x0c, 255);
446 SETCOL(btheme->tarm[8].select, 0xee, 0xc2, 0x36, 255);
447 SETCOL(btheme->tarm[8].active, 0xf3, 0xff, 0x00, 255);
449 SETCOL(btheme->tarm[9].solid, 0x1e, 0x20, 0x24, 255);
450 SETCOL(btheme->tarm[9].select, 0x48, 0x4c, 0x56, 255);
451 SETCOL(btheme->tarm[9].active, 0xff, 0xff, 0xff, 255);
453 SETCOL(btheme->tarm[10].solid, 0x6f, 0x2f, 0x6a, 255);
454 SETCOL(btheme->tarm[10].select, 0x98, 0x45, 0xbe, 255);
455 SETCOL(btheme->tarm[10].active, 0xd3, 0x30, 0xd6, 255);
457 SETCOL(btheme->tarm[11].solid, 0x6c, 0x8e, 0x22, 255);
458 SETCOL(btheme->tarm[11].select, 0x7f, 0xb0, 0x22, 255);
459 SETCOL(btheme->tarm[11].active, 0xbb, 0xef, 0x5b, 255);
461 SETCOL(btheme->tarm[12].solid, 0x8d, 0x8d, 0x8d, 255);
462 SETCOL(btheme->tarm[12].select, 0xb0, 0xb0, 0xb0, 255);
463 SETCOL(btheme->tarm[12].active, 0xde, 0xde, 0xde, 255);
465 SETCOL(btheme->tarm[13].solid, 0x83, 0x43, 0x26, 255);
466 SETCOL(btheme->tarm[13].select, 0x8b, 0x58, 0x11, 255);
467 SETCOL(btheme->tarm[13].active, 0xbd, 0x6a, 0x11, 255);
469 SETCOL(btheme->tarm[14].solid, 0x08, 0x31, 0x0e, 255);
470 SETCOL(btheme->tarm[14].select, 0x1c, 0x43, 0x0b, 255);
471 SETCOL(btheme->tarm[14].active, 0x34, 0x62, 0x2b, 255);
475 if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 16)) {
476 U.flag |= USER_ADD_VIEWALIGNED|USER_ADD_EDITMODE;
479 /* GL Texture Garbage Collection (variable abused above!) */
480 if (U.textimeout == 0) {
481 U.texcollectrate = 60;
484 if (U.memcachelimit <= 0) {
485 U.memcachelimit = 32;
487 if (U.frameserverport == 0) {
488 U.frameserverport = 8080;
491 MEM_CacheLimiter_set_maximum(U.memcachelimit * 1024 * 1024);
499 refresh_interface_font();
502 if(strlen(U.versemaster)<1) {
503 strcpy(U.versemaster, "master.uni-verse.org");
505 if(strlen(U.verseuser)<1) {
506 char *name = verse_client_name();
507 strcpy(U.verseuser, name);
515 extern ListBase session_list;
518 void BIF_read_file(char *name)
520 extern short winqueue_break; /* editscreen.c */
523 struct VerseSession *session;
526 session = session_list.first;
528 vnode = session->nodes.lb.first;
530 switch(vnode->type) {
532 unsubscribe_from_obj_node(vnode);
535 unsubscribe_from_geom_node(vnode);
538 unsubscribe_from_bitmap_node(vnode);
543 session = session->next;
547 /* first try to read exotic file formats... */
548 /* it throws error box when file doesnt exist and returns -1 */
549 retval= BKE_read_exotic(name);
552 BIF_clear_tempfiles();
554 /* we didn't succeed, now try to read Blender file */
555 retval= BKE_read_file(name, NULL);
557 mainwindow_set_filename_to_title(G.main->name);
559 sound_initialize_sounds();
561 winqueue_break= 1; /* leave queues everywhere */
563 if(retval==2) init_userdef_file(); // in case a userdef is read from regular .blend
565 if (retval!=0) G.relbase_valid = 1;
567 undo_editmode_clear();
569 BKE_write_undo("original"); /* save current state */
571 refresh_interface_font();
574 BIF_undo_push("Import file");
577 static void outliner_242_patch(void)
581 for(sa= G.curscreen->areabase.first; sa; sa= sa->next) {
582 SpaceLink *sl= sa->spacedata.first;
583 for(; sl; sl= sl->next) {
584 if(sl->spacetype==SPACE_OOPS) {
585 SpaceOops *soops= (SpaceOops *)sl;
586 if(soops->type!=SO_OUTLINER) {
587 soops->type= SO_OUTLINER;
588 init_v2d_oops(sa, soops);
593 G.fileflags |= G_FILE_GAME_MAT;
596 /* only here settings for fullscreen */
597 int BIF_read_homefile(int from_memory)
599 char tstr[FILE_MAXDIR+FILE_MAXFILE], scestr[FILE_MAX];
600 char *home= BLI_gethome();
604 BIF_clear_tempfiles();
611 freePackedFile(tf->pf);
616 BLI_freelistN(&G.ttfdata);
619 if (!from_memory) BLI_make_file_string(G.sce, tstr, home, ".B.blend");
620 BLI_strncpy(scestr, G.sce, FILE_MAX); /* temporal store */
622 /* prevent loading no UI */
623 G.fileflags &= ~G_FILE_NO_UI;
625 if (!from_memory && BLI_exists(tstr)) {
626 success = BKE_read_file(tstr, NULL);
628 success = BKE_read_file_from_memory(datatoc_B_blend, datatoc_B_blend_size, NULL);
629 /* outliner patch for 2.42 .b.blend */
630 outliner_242_patch();
634 strcpy(G.sce, scestr);
636 space_set_commmandline_options();
640 undo_editmode_clear();
642 BKE_write_undo("original"); /* save current state */
644 /* if from memory, need to refresh python scripts */
652 static void get_autosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE])
657 char savedir[FILE_MAXDIR];
660 sprintf(pidstr, "%d.blend", abs(getpid()));
663 if (!BLI_exists(btempdir)) {
664 BLI_strncpy(subdir, "autosave", sizeof(subdir));
665 BLI_make_file_string("/", savedir, BLI_gethome(), subdir);
667 /* create a new autosave dir
668 * function already checks for existence or not */
669 BLI_recurdir_fileops(savedir);
671 BLI_make_file_string("/", buf, savedir, pidstr);
676 BLI_make_file_string("/", buf, btempdir, pidstr);
679 void BIF_read_autosavefile(void)
681 char tstr[FILE_MAX], scestr[FILE_MAX];
684 BLI_strncpy(scestr, G.sce, FILE_MAX); /* temporal store */
686 get_autosave_location(tstr);
688 save_over = G.save_over;
689 BKE_read_file(tstr, NULL);
690 G.save_over = save_over;
691 BLI_strncpy(G.sce, scestr, FILE_MAX);
694 /* free strings of open recent files */
695 static void free_openrecent(void)
697 struct RecentFile *recent;
699 for(recent = G.recent_files.first; recent; recent=recent->next)
700 MEM_freeN(recent->filename);
702 BLI_freelistN(&(G.recent_files));
705 static void readBlog(void)
707 char name[FILE_MAX], filename[FILE_MAX];
709 struct RecentFile *recent;
713 BLI_make_file_string("/", name, BLI_gethome(), ".Blog");
714 lines= BLI_read_file_as_lines(name);
716 G.recent_files.first = G.recent_files.last = NULL;
718 /* read list of recent opend files from .Blog to memory */
719 for (l= lines, num= 0; l && (num<U.recent_files); l= l->next, num++) {
721 if (!BLI_streq(line, "")) {
725 recent = (RecentFile*)MEM_mallocN(sizeof(RecentFile),"RecentFile");
726 BLI_addtail(&(G.recent_files), recent);
727 recent->filename = (char*)MEM_mallocN(sizeof(char)*(strlen(line)+1), "name of file");
728 recent->filename[0] = '\0';
730 strcpy(recent->filename, line);
735 BLI_make_file_string("/", G.sce, BLI_gethome(), "untitled.blend");
737 BLI_free_file_lines(lines);
740 /* Add the drive names to the listing */
743 char folder[MAX_PATH];
747 tmp= GetLogicalDrives();
749 for (i=2; i < 26; i++) {
756 fsmenu_insert_entry(tmps, 0, 0);
760 /* Adding Desktop and My Documents */
761 fsmenu_append_separator();
763 SHGetSpecialFolderPath(0, folder, CSIDL_PERSONAL, 0);
764 fsmenu_insert_entry(folder, 0, 0);
765 SHGetSpecialFolderPath(0, folder, CSIDL_DESKTOPDIRECTORY, 0);
766 fsmenu_insert_entry(folder, 0, 0);
768 fsmenu_append_separator();
771 /* add home dir on linux systems */
772 fsmenu_insert_entry(BLI_gethome(), 0, 0);
775 BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs");
776 lines= BLI_read_file_as_lines(name);
778 for (l= lines; l; l= l->next) {
781 if (!BLI_streq(line, "")) {
782 fsmenu_insert_entry(line, 0, 1);
786 fsmenu_append_separator();
788 /* add last saved file */
789 BLI_split_dirfile_basic(G.sce, name, filename); /* G.sce shouldn't be relative */
791 fsmenu_insert_entry(name, 0, 0);
793 BLI_free_file_lines(lines);
796 static void writeBlog(void)
798 struct RecentFile *recent, *next_recent;
799 char name[FILE_MAXDIR+FILE_MAXFILE];
803 BLI_make_file_string("/", name, BLI_gethome(), ".Blog");
805 recent = G.recent_files.first;
806 /* refresh .Blog of recent opened files, when current file was changed */
807 if(!(recent) || (strcmp(recent->filename, G.sce)!=0)) {
808 fp= fopen(name, "w");
810 /* add current file to the beginning of list */
811 recent = (RecentFile*)MEM_mallocN(sizeof(RecentFile),"RecentFile");
812 recent->filename = (char*)MEM_mallocN(sizeof(char)*(strlen(G.sce)+1), "name of file");
813 recent->filename[0] = '\0';
814 strcpy(recent->filename, G.sce);
815 BLI_addhead(&(G.recent_files), recent);
816 /* write current file to .Blog */
817 fprintf(fp, "%s\n", recent->filename);
818 recent = recent->next;
820 /* write rest of recent opened files to .Blog */
821 while((i<U.recent_files) && (recent)){
822 /* this prevents to have duplicities in list */
823 if (strcmp(recent->filename, G.sce)!=0) {
824 fprintf(fp, "%s\n", recent->filename);
825 recent = recent->next;
828 next_recent = recent->next;
829 MEM_freeN(recent->filename);
830 BLI_freelinkN(&(G.recent_files), recent);
831 recent = next_recent;
840 static void do_history(char *name)
842 char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE];
843 int hisnr= U.versions;
845 if(U.versions==0) return;
846 if(strlen(name)<2) return;
849 sprintf(tempname1, "%s%d", name, hisnr-1);
850 sprintf(tempname2, "%s%d", name, hisnr);
852 if(BLI_rename(tempname1, tempname2))
853 error("Unable to make version backup");
858 /* is needed when hisnr==1 */
859 sprintf(tempname1, "%s%d", name, hisnr);
861 if(BLI_rename(name, tempname1))
862 error("Unable to make version backup");
865 void BIF_write_file(char *target)
872 len = strlen(target);
874 if (len == 0) return;
875 if (len >= FILE_MAX) {
876 error("Path too long, cannot save");
880 /* send the OnSave event */
881 if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript(&G.scene->id, SCRIPT_ONSAVE);
883 for (li= G.main->library.first; li; li= li->id.next) {
884 if (BLI_streq(li->name, target)) {
885 error("Cannot overwrite used library");
890 if (!BLO_has_bfile_extension(target) && (len+6 < FILE_MAX)) {
891 sprintf(di, "%s.blend", target);
896 if (BLI_exists(di)) {
902 exit_editmode(0); /* 0 = no free data */
904 if (G.fileflags & G_AUTOPACK) {
908 waitcursor(1); // exit_editmode sets cursor too
912 /* we use the UserDef to define compression flag */
913 writeflags= G.fileflags & ~G_FILE_COMPRESS;
914 if(U.flag & USER_FILECOMPRESS)
915 writeflags |= G_FILE_COMPRESS;
917 if (BLO_write_file(di, writeflags, &err)) {
920 BLI_strncpy(G.main->name, di, FILE_MAX); /* is guaranteed current file */
922 mainwindow_set_filename_to_title(G.main->name);
934 void BIF_write_homefile(void)
936 char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
939 BLI_make_file_string("/", tstr, BLI_gethome(), ".B.blend");
941 /* force save as regular blend file */
942 write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
943 BLO_write_file(tstr, write_flags, &err);
946 void BIF_write_autosave(void)
948 char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
951 get_autosave_location(tstr);
953 /* force save as regular blend file */
954 write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
955 BLO_write_file(tstr, write_flags, &err);
958 /* remove temp files assosiated with this blend file when quitting, loading or saving in a new path */
959 void BIF_clear_tempfiles( void )
961 /* TODO - remove exr files from the temp dir */
963 if (!G.relbase_valid) { /* We could have pointcache saved in tyhe temp dir, if its there */
964 BKE_ptcache_remove();
968 /* if global undo; remove tempsave, otherwise rename */
969 static void delete_autosave(void)
971 char tstr[FILE_MAXDIR+FILE_MAXFILE];
973 get_autosave_location(tstr);
975 if (BLI_exists(tstr)) {
976 char str[FILE_MAXDIR+FILE_MAXFILE];
977 BLI_make_file_string("/", str, btempdir, "quit.blend");
979 if(U.uiflag & USER_GLOBALUNDO) BLI_delete(tstr, 0, 0);
980 else BLI_rename(tstr, str);
986 static void initbuttons(void)
989 BMF_GetFont(BMF_kHelveticaBold14),
990 BMF_GetFont(BMF_kHelveticaBold12),
991 BMF_GetFont(BMF_kHelveticaBold10),
992 BMF_GetFont(BMF_kHelveticaBold8));
994 BMF_GetFont(BMF_kHelvetica12),
995 BMF_GetFont(BMF_kHelvetica12),
996 BMF_GetFont(BMF_kHelvetica10),
997 BMF_GetFont(BMF_kHelveticaBold8));
999 glClearColor(.7f, .7f, .6f, 0.0);
1001 G.font= BMF_GetFont(BMF_kHelvetica12);
1002 G.fonts= BMF_GetFont(BMF_kHelvetica10);
1003 G.fontss= BMF_GetFont(BMF_kHelveticaBold8);
1007 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1011 static void sound_init_listener(void)
1013 G.listener = MEM_callocN(sizeof(bSoundListener), "soundlistener");
1014 G.listener->gain = 1.0;
1015 G.listener->dopplerfactor = 1.0;
1016 G.listener->dopplervelocity = 340.29f;
1022 initscreen(); /* for (visuele) speed, this first, then setscreen */
1025 sound_init_listener();
1026 init_node_butfuncs();
1028 BIF_preview_init_dbase();
1029 BIF_read_homefile(0);
1031 BIF_resources_init(); /* after homefile, to dynamically load an icon file based on theme settings */
1033 BIF_filelist_init_icons();
1035 init_gl_stuff(); /* drawview.c, after homefile */
1037 BLI_strncpy(G.lib, G.sce, FILE_MAX);
1042 extern ListBase editNurb;
1043 extern ListBase editelems;
1045 void exit_usiblender(void)
1049 BIF_clear_tempfiles();
1051 tf= G.ttfdata.first;
1054 freePackedFile(tf->pf);
1059 BLI_freelistN(&G.ttfdata);
1061 end_all_verse_sessions();
1066 BKE_freecubetable();
1068 if (G.background == 0)
1069 sound_end_all_sounds();
1072 if(G.obedit->type==OB_FONT) {
1075 else if(G.obedit->type==OB_MBALL) BLI_freelistN(&editelems);
1076 free_editMesh(G.editMesh);
1080 free_editArmature();
1083 /* before free_blender so py's gc happens while library still exists */
1084 /* needed at least for a rare sigsegv that can happen in pydrivers */
1087 fastshade_free_render(); /* shaded view */
1088 free_blender(); /* blender.c, does entire library */
1095 /* editnurb can remain to exist outside editmode */
1096 freeNurblist(&editNurb);
1100 #ifdef INTERNATIONAL
1101 free_languagemenu();
1109 if(G.listener) MEM_freeN(G.listener);
1114 #ifdef WITH_QUICKTIME
1118 /* undo free stuff */
1119 undo_editmode_clear();
1121 BKE_undo_save_quit(); // saves quit.blend if global undo is on
1124 if (!G.background) {
1125 BIF_resources_free();
1127 BIF_filelist_free_icons();
1129 BIF_free_render_spare();
1130 BIF_close_render_display();
1134 #ifdef INTERNATIONAL
1138 if (copybuf) MEM_freeN(copybuf);
1139 if (copybufinfo) MEM_freeN(copybufinfo);
1142 BLI_freelistN(&U.themes);
1143 BIF_preview_free_dbase();
1146 printf("Error Totblock: %d\n",totblock);
1151 printf("\nBlender quit\n");
1154 /* ask user to press enter when in debug mode */
1156 printf("press enter key to exit...\n\n");
1162 SYS_DeleteSystem(SYS_GetSystem());