7ed1c4304315022aa86634b4d190f18035a3ee70
[blender-staging.git] / source / blender / src / usiblender.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33         /* placed up here because of crappy
34          * winsock stuff.
35          */
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39
40 #ifdef WIN32
41 #include <windows.h> /* need to include windows.h so _WIN32_IE is defined  */
42 #ifndef _WIN32_IE
43 #define _WIN32_IE 0x0400 /* minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already */
44 #endif
45 #include <shlobj.h> /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff because 'near' is disabled through BLI_windstuff */
46 #include "BLI_winstuff.h"
47 #include <process.h> /* getpid */
48 #else
49 #include <unistd.h> /* getpid */
50 #endif
51 #include "MEM_guardedalloc.h"
52 #include "MEM_CacheLimiterC-Api.h"
53
54 #include "BMF_Api.h"
55 #include "BIF_language.h"
56 #ifdef INTERNATIONAL
57 #include "FTF_Api.h"
58 #endif
59
60 #include "BLI_blenlib.h"
61 #include "BLI_arithb.h"
62 #include "BLI_linklist.h"
63
64 #include "IMB_imbuf_types.h"
65 #include "IMB_imbuf.h"
66
67 #include "DNA_object_types.h"
68 #include "DNA_space_types.h"
69 #include "DNA_userdef_types.h"
70 #include "DNA_sound_types.h"
71 #include "DNA_scene_types.h"
72 #include "DNA_screen_types.h"
73
74 #include "BKE_blender.h"
75 #include "BKE_curve.h"
76 #include "BKE_displist.h"
77 #include "BKE_DerivedMesh.h"
78 #include "BKE_exotic.h"
79 #include "BKE_font.h"
80 #include "BKE_global.h"
81 #include "BKE_main.h"
82 #include "BKE_mball.h"
83 #include "BKE_node.h"
84 #include "BKE_packedFile.h"
85 #include "BKE_texture.h"
86 #include "BKE_utildefines.h"
87 #include "BKE_pointcache.h"
88
89 #ifdef WITH_VERSE
90 #include "BKE_verse.h"
91 #endif
92
93 #include "BLI_vfontdata.h"
94
95 #include "BIF_fsmenu.h"
96 #include "BIF_gl.h"
97 #include "BIF_interface.h"
98 #include "BIF_usiblender.h"
99 #include "BIF_drawtext.h"
100 #include "BIF_editaction.h"
101 #include "BIF_editarmature.h"
102 #include "BIF_editlattice.h"
103 #include "BIF_editfont.h"
104 #include "BIF_editmesh.h"
105 #include "BIF_editmode_undo.h"
106 #include "BIF_editsound.h"
107 #include "BIF_filelist.h"
108 #include "BIF_poseobject.h"
109 #include "BIF_previewrender.h"
110 #include "BIF_renderwin.h"
111 #include "BIF_resources.h"
112 #include "BIF_screen.h"
113 #include "BIF_space.h"
114 #include "BIF_toolbox.h"
115 #include "BIF_cursors.h"
116
117 #ifdef WITH_VERSE
118 #include "BIF_verse.h"
119 #endif
120
121
122 #include "BSE_drawview.h"
123 #include "BSE_edit.h"
124 #include "BSE_editipo.h"
125 #include "BSE_filesel.h"
126 #include "BSE_headerbuttons.h"
127 #include "BSE_node.h"
128
129 #include "BLO_readfile.h"
130 #include "BLO_writefile.h"
131
132 #include "BDR_drawobject.h"
133 #include "BDR_editobject.h"
134 #include "BDR_editcurve.h"
135 #include "BDR_imagepaint.h"
136 #include "BDR_vpaint.h"
137
138 #include "BPY_extern.h"
139
140 #include "blendef.h"
141
142 #include "RE_pipeline.h"                /* RE_ free stuff */
143
144 #include "radio.h"
145 #include "datatoc.h"
146
147 #include "SYS_System.h"
148
149 #include "PIL_time.h"
150
151 /***/
152
153 /* define for setting colors in theme below */
154 #define SETCOL(col, r, g, b, a)  col[0]=r; col[1]=g; col[2]= b; col[3]= a;
155
156 /* patching UserDef struct, set globals for UI stuff */
157 static void init_userdef_file(void)
158 {
159         
160         BIF_InitTheme();        // sets default again
161         
162         mainwindow_set_filename_to_title("");   // empty string re-initializes title to "Blender"
163         countall();
164         G.save_over = 0;        // start with save preference untitled.blend
165         
166         /*  disable autoplay in .B.blend... */
167         G.fileflags &= ~G_FILE_AUTOPLAY;
168         
169         /* the UserDef struct is not corrected with do_versions() .... ugh! */
170         if(U.wheellinescroll == 0) U.wheellinescroll = 3;
171         if(U.menuthreshold1==0) {
172                 U.menuthreshold1= 5;
173                 U.menuthreshold2= 2;
174         }
175         if(U.tb_leftmouse==0) {
176                 U.tb_leftmouse= 5;
177                 U.tb_rightmouse= 5;
178         }
179         if(U.mixbufsize==0) U.mixbufsize= 2048;
180         if (BLI_streq(U.tempdir, "/")) {
181                 BLI_where_is_temp(U.tempdir, 0);
182         }
183         if (U.savetime <= 0) {
184                 U.savetime = 1;
185                 error(".B.blend is buggy, please consider removing it.\n");
186         }
187         /* transform widget settings */
188         if(U.tw_hotspot==0) {
189                 U.tw_hotspot= 14;
190                 U.tw_size= 20;                  // percentage of window size
191                 U.tw_handlesize= 16;    // percentage of widget radius
192         }
193         if(U.pad_rot_angle==0)
194                 U.pad_rot_angle= 15;
195         
196    if (U.ndof_pan==0) {
197         U.ndof_pan = 100;
198    }
199     if (U.ndof_rotate==0) {
200         U.ndof_rotate = 100;
201    }
202
203         if(U.flag & USER_CUSTOM_RANGE) 
204                 vDM_ColorBand_store(&U.coba_weight); /* signal for derivedmesh to use colorband */
205         
206         /* Auto-keyframing settings */
207         if(U.autokey_mode == 0) {
208                 /* AUTOKEY_MODE_NORMAL - AUTOKEY_ON = x  <==> 3 - 1 = 2 */
209                 U.autokey_mode |= 2;
210                 
211                 if(U.flag & (1<<15)) U.autokey_flag |= AUTOKEY_FLAG_INSERTAVAIL;
212                 if(U.flag & (1<<19)) U.autokey_flag |= AUTOKEY_FLAG_INSERTNEEDED;
213                 if(G.flags & (1<<30)) U.autokey_flag |= AUTOKEY_FLAG_AUTOMATKEY;
214         }
215         
216         if (G.main->versionfile <= 191) {
217                 strcpy(U.plugtexdir, U.textudir);
218                 strcpy(U.sounddir, "/");
219         }
220         
221         /* patch to set Dupli Armature */
222         if (G.main->versionfile < 220) {
223                 U.dupflag |= USER_DUP_ARM;
224         }
225         
226         /* userdef new option */
227         if (G.main->versionfile <= 222) {
228                 U.vrmlflag= USER_VRML_LAYERS;
229         }
230         
231         /* added seam, normal color, undo */
232         if (G.main->versionfile <= 234) {
233                 bTheme *btheme;
234                 
235                 U.uiflag |= USER_GLOBALUNDO;
236                 if (U.undosteps==0) U.undosteps=32;
237                 
238                 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
239                         /* check for alpha==0 is safe, then color was never set */
240                         if(btheme->tv3d.edge_seam[3]==0) {
241                                 SETCOL(btheme->tv3d.edge_seam, 230, 150, 50, 255);
242                         }
243                         if(btheme->tv3d.normal[3]==0) {
244                                 SETCOL(btheme->tv3d.normal, 0x22, 0xDD, 0xDD, 255);
245                         }
246                         if(btheme->tv3d.face_dot[3]==0) {
247                                 SETCOL(btheme->tv3d.face_dot, 255, 138, 48, 255);
248                                 btheme->tv3d.facedot_size= 4;
249                         }
250                 }
251         }
252         if (G.main->versionfile <= 235) {
253                 /* illegal combo... */
254                 if (U.flag & USER_LMOUSESELECT) 
255                         U.flag &= ~USER_TWOBUTTONMOUSE;
256         }
257         if (G.main->versionfile <= 236) {
258                 bTheme *btheme;
259                 /* new space type */
260                 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
261                         /* check for alpha==0 is safe, then color was never set */
262                         if(btheme->ttime.back[3]==0) {
263                                 btheme->ttime = btheme->tsnd;   // copy from sound
264                         }
265                         if(btheme->text.syntaxn[3]==0) {
266                                 SETCOL(btheme->text.syntaxn,    0, 0, 200, 255);        /* Numbers  Blue*/
267                                 SETCOL(btheme->text.syntaxl,    100, 0, 0, 255);        /* Strings  red */
268                                 SETCOL(btheme->text.syntaxc,    0, 100, 50, 255);       /* Comments greenish */
269                                 SETCOL(btheme->text.syntaxv,    95, 95, 0, 255);        /* Special */
270                                 SETCOL(btheme->text.syntaxb,    128, 0, 80, 255);       /* Builtin, red-purple */
271                         }
272                 }
273         }
274         if (G.main->versionfile <= 237) {
275                 bTheme *btheme;
276                 /* bone colors */
277                 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
278                         /* check for alpha==0 is safe, then color was never set */
279                         if(btheme->tv3d.bone_solid[3]==0) {
280                                 SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
281                                 SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80);
282                         }
283                 }
284         }
285         if (G.main->versionfile <= 238) {
286                 bTheme *btheme;
287                 /* bone colors */
288                 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
289                         /* check for alpha==0 is safe, then color was never set */
290                         if(btheme->tnla.strip[3]==0) {
291                                 SETCOL(btheme->tnla.strip_select,       0xff, 0xff, 0xaa, 255);
292                                 SETCOL(btheme->tnla.strip, 0xe4, 0x9c, 0xc6, 255);
293                         }
294                 }
295         }
296         if (G.main->versionfile <= 239) {
297                 bTheme *btheme;
298                 
299                 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
300                         /* Lamp theme, check for alpha==0 is safe, then color was never set */
301                         if(btheme->tv3d.lamp[3]==0) {
302                                 SETCOL(btheme->tv3d.lamp,       0, 0, 0, 40);
303 /* TEMPORAL, remove me! (ton) */                                
304                                 U.uiflag |= USER_PLAINMENUS;
305                         }
306                         
307                         /* check for text field selection highlight, set it to text editor highlight by default */
308                         if(btheme->tui.textfield_hi[3]==0) {
309                                 SETCOL(btheme->tui.textfield_hi,        
310                                         btheme->text.shade2[0], 
311                                         btheme->text.shade2[1], 
312                                         btheme->text.shade2[2],
313                                         255);
314                         }
315                 }
316                 if(U.obcenter_dia==0) U.obcenter_dia= 6;
317         }
318         if (G.main->versionfile <= 241) {
319                 bTheme *btheme;
320                 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
321                         /* Node editor theme, check for alpha==0 is safe, then color was never set */
322                         if(btheme->tnode.syntaxn[3]==0) {
323                                 /* re-uses syntax color storage */
324                                 btheme->tnode= btheme->tv3d;
325                                 SETCOL(btheme->tnode.edge_select, 255, 255, 255, 255);
326                                 SETCOL(btheme->tnode.syntaxl, 150, 150, 150, 255);      /* TH_NODE, backdrop */
327                                 SETCOL(btheme->tnode.syntaxn, 129, 131, 144, 255);      /* in/output */
328                                 SETCOL(btheme->tnode.syntaxb, 127,127,127, 255);        /* operator */
329                                 SETCOL(btheme->tnode.syntaxv, 142, 138, 145, 255);      /* generator */
330                                 SETCOL(btheme->tnode.syntaxc, 120, 145, 120, 255);      /* group */
331                         }
332                         /* Group theme colors */
333                         if(btheme->tv3d.group[3]==0) {
334                                 SETCOL(btheme->tv3d.group, 0x10, 0x40, 0x10, 255);
335                                 SETCOL(btheme->tv3d.group_active, 0x66, 0xFF, 0x66, 255);
336                         }
337                         /* Sequence editor theme*/
338                         if(btheme->tseq.movie[3]==0) {
339                                 SETCOL(btheme->tseq.movie,      81, 105, 135, 255);
340                                 SETCOL(btheme->tseq.image,      109, 88, 129, 255);
341                                 SETCOL(btheme->tseq.scene,      78, 152, 62, 255);
342                                 SETCOL(btheme->tseq.audio,      46, 143, 143, 255);
343                                 SETCOL(btheme->tseq.effect,     169, 84, 124, 255);
344                                 SETCOL(btheme->tseq.plugin,     126, 126, 80, 255);
345                                 SETCOL(btheme->tseq.transition, 162, 95, 111, 255);
346                                 SETCOL(btheme->tseq.meta,       109, 145, 131, 255);
347                         }
348                         if(!(btheme->tui.iconfile)) {
349                                 BLI_strncpy(btheme->tui.iconfile, "", sizeof(btheme->tui.iconfile));
350                         }
351                 }
352                 
353                 /* set defaults for 3D View rotating axis indicator */ 
354                 /* since size can't be set to 0, this indicates it's not saved in .B.blend */
355                 if (U.rvisize == 0) {
356                         U.rvisize = 15;
357                         U.rvibright = 8;
358                         U.uiflag |= USER_SHOW_ROTVIEWICON;
359                 }
360                 
361         }
362         if (G.main->versionfile <= 242) {
363                 bTheme *btheme;
364                 
365                 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
366                         /* long keyframe color */
367                         /* check for alpha==0 is safe, then color was never set */
368                         if(btheme->tact.strip[3]==0) {
369                                 SETCOL(btheme->tv3d.edge_sharp, 255, 32, 32, 255);
370                                 SETCOL(btheme->tact.strip_select,       0xff, 0xff, 0xaa, 204);
371                                 SETCOL(btheme->tact.strip, 0xe4, 0x9c, 0xc6, 204);
372                         }
373                         
374                         /* IPO-Editor - Vertex Size*/
375                         if(btheme->tipo.vertex_size == 0) {
376                                 btheme->tipo.vertex_size= 3;
377                         }
378                 }
379         }
380         if (G.main->versionfile <= 243) {
381                 /* set default number of recently-used files (if not set) */
382                 if (U.recent_files == 0) U.recent_files = 10;
383         }
384         if (G.main->versionfile < 245 || (G.main->versionfile == 245 && G.main->subversionfile < 3)) {
385                 bTheme *btheme;
386                 for(btheme= U.themes.first; btheme; btheme= btheme->next) {
387                         SETCOL(btheme->tv3d.editmesh_active, 255, 255, 255, 128);
388                 }
389                 if(U.coba_weight.tot==0)
390                         init_colorband(&U.coba_weight, 1);
391         }
392         if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 11)) {
393                 bTheme *btheme;
394                 for (btheme= U.themes.first; btheme; btheme= btheme->next) {
395                         /* these should all use the same colour */
396                         SETCOL(btheme->tv3d.cframe, 0x60, 0xc0, 0x40, 255);
397                         SETCOL(btheme->tipo.cframe, 0x60, 0xc0, 0x40, 255);
398                         SETCOL(btheme->tact.cframe, 0x60, 0xc0, 0x40, 255);
399                         SETCOL(btheme->tnla.cframe, 0x60, 0xc0, 0x40, 255);
400                         SETCOL(btheme->tseq.cframe, 0x60, 0xc0, 0x40, 255);
401                         SETCOL(btheme->tsnd.cframe, 0x60, 0xc0, 0x40, 255);
402                         SETCOL(btheme->ttime.cframe, 0x60, 0xc0, 0x40, 255);
403                 }
404         }
405         if ((G.main->versionfile < 245) || (G.main->versionfile == 245 && G.main->subversionfile < 13)) {
406                 bTheme *btheme;
407                 for (btheme= U.themes.first; btheme; btheme= btheme->next) {
408                         /* action channel groups (recolour anyway) */
409                         SETCOL(btheme->tact.group, 0x39, 0x7d, 0x1b, 255);
410                         SETCOL(btheme->tact.group_active, 0x7d, 0xe9, 0x60, 255);
411                         
412                         /* bone custom-color sets */
413                         // FIXME: this check for initialised colors is bad
414                         if (btheme->tarm[0].solid[3] == 0) {
415                                         /* set 1 */
416                                 SETCOL(btheme->tarm[0].solid, 0x9a, 0x00, 0x00, 255);
417                                 SETCOL(btheme->tarm[0].select, 0xbd, 0x11, 0x11, 255);
418                                 SETCOL(btheme->tarm[0].active, 0xf7, 0x0a, 0x0a, 255);
419                                         /* set 2 */
420                                 SETCOL(btheme->tarm[1].solid, 0xf7, 0x40, 0x18, 255);
421                                 SETCOL(btheme->tarm[1].select, 0xf6, 0x69, 0x13, 255);
422                                 SETCOL(btheme->tarm[1].active, 0xfa, 0x99, 0x00, 255);
423                                         /* set 3 */
424                                 SETCOL(btheme->tarm[2].solid, 0x1e, 0x91, 0x09, 255);
425                                 SETCOL(btheme->tarm[2].select, 0x59, 0xb7, 0x0b, 255);
426                                 SETCOL(btheme->tarm[2].active, 0x83, 0xef, 0x1d, 255);
427                                         /* set 4 */
428                                 SETCOL(btheme->tarm[3].solid, 0x0a, 0x36, 0x94, 255);
429                                 SETCOL(btheme->tarm[3].select, 0x36, 0x67, 0xdf, 255);
430                                 SETCOL(btheme->tarm[3].active, 0x5e, 0xc1, 0xef, 255);
431                                         /* set 5 */
432                                 SETCOL(btheme->tarm[4].solid, 0xa9, 0x29, 0x4e, 255);
433                                 SETCOL(btheme->tarm[4].select, 0xc1, 0x41, 0x6a, 255);
434                                 SETCOL(btheme->tarm[4].active, 0xf0, 0x5d, 0x91, 255);
435                                         /* set 6 */
436                                 SETCOL(btheme->tarm[5].solid, 0x43, 0x0c, 0x78, 255);
437                                 SETCOL(btheme->tarm[5].select, 0x54, 0x3a, 0xa3, 255);
438                                 SETCOL(btheme->tarm[5].active, 0x87, 0x64, 0xd5, 255);
439                                         /* set 7 */
440                                 SETCOL(btheme->tarm[6].solid, 0x24, 0x78, 0x5a, 255);
441                                 SETCOL(btheme->tarm[6].select, 0x3c, 0x95, 0x79, 255);
442                                 SETCOL(btheme->tarm[6].active, 0x6f, 0xb6, 0xab, 255);
443                                         /* set 8 */
444                                 SETCOL(btheme->tarm[7].solid, 0x4b, 0x70, 0x7c, 255);
445                                 SETCOL(btheme->tarm[7].select, 0x6a, 0x86, 0x91, 255);
446                                 SETCOL(btheme->tarm[7].active, 0x9b, 0xc2, 0xcd, 255);
447                                         /* set 9 */
448                                 SETCOL(btheme->tarm[8].solid, 0xf4, 0xc9, 0x0c, 255);
449                                 SETCOL(btheme->tarm[8].select, 0xee, 0xc2, 0x36, 255);
450                                 SETCOL(btheme->tarm[8].active, 0xf3, 0xff, 0x00, 255);
451                                         /* set 10 */
452                                 SETCOL(btheme->tarm[9].solid, 0x1e, 0x20, 0x24, 255);
453                                 SETCOL(btheme->tarm[9].select, 0x48, 0x4c, 0x56, 255);
454                                 SETCOL(btheme->tarm[9].active, 0xff, 0xff, 0xff, 255);
455                                         /* set 11 */
456                                 SETCOL(btheme->tarm[10].solid, 0x6f, 0x2f, 0x6a, 255);
457                                 SETCOL(btheme->tarm[10].select, 0x98, 0x45, 0xbe, 255);
458                                 SETCOL(btheme->tarm[10].active, 0xd3, 0x30, 0xd6, 255);
459                                         /* set 12 */
460                                 SETCOL(btheme->tarm[11].solid, 0x6c, 0x8e, 0x22, 255);
461                                 SETCOL(btheme->tarm[11].select, 0x7f, 0xb0, 0x22, 255);
462                                 SETCOL(btheme->tarm[11].active, 0xbb, 0xef, 0x5b, 255);
463                                         /* set 13 */
464                                 SETCOL(btheme->tarm[12].solid, 0x8d, 0x8d, 0x8d, 255);
465                                 SETCOL(btheme->tarm[12].select, 0xb0, 0xb0, 0xb0, 255);
466                                 SETCOL(btheme->tarm[12].active, 0xde, 0xde, 0xde, 255);
467                                         /* set 14 */
468                                 SETCOL(btheme->tarm[13].solid, 0x83, 0x43, 0x26, 255);
469                                 SETCOL(btheme->tarm[13].select, 0x8b, 0x58, 0x11, 255);
470                                 SETCOL(btheme->tarm[13].active, 0xbd, 0x6a, 0x11, 255);
471                                         /* set 15 */
472                                 SETCOL(btheme->tarm[14].solid, 0x08, 0x31, 0x0e, 255);
473                                 SETCOL(btheme->tarm[14].select, 0x1c, 0x43, 0x0b, 255);
474                                 SETCOL(btheme->tarm[14].active, 0x34, 0x62, 0x2b, 255);
475                         }
476                 }
477         }
478         
479         /* GL Texture Garbage Collection (variable abused above!) */
480         if (U.textimeout == 0) {
481                 U.texcollectrate = 60;
482                 U.textimeout = 120;
483         }
484         if (U.memcachelimit <= 0) {
485                 U.memcachelimit = 32;
486         }
487         if (U.frameserverport == 0) {
488                 U.frameserverport = 8080;
489         }
490
491         MEM_CacheLimiter_set_maximum(U.memcachelimit * 1024 * 1024);
492         
493         reset_autosave();
494         
495 #ifdef INTERNATIONAL
496         read_languagefile();
497 #endif
498         
499         refresh_interface_font();
500
501 #ifdef WITH_VERSE
502         if(strlen(U.versemaster)<1) {
503                         strcpy(U.versemaster, "master.uni-verse.org");
504         }
505         if(strlen(U.verseuser)<1) {
506                         char *name = verse_client_name();
507                         strcpy(U.verseuser, name);
508                         MEM_freeN(name);
509         }
510 #endif
511
512 }
513
514 #ifdef WITH_VERSE
515 extern ListBase session_list;
516 #endif
517
518 void BIF_read_file(char *name)
519 {
520         extern short winqueue_break; /* editscreen.c */
521         int retval;
522 #ifdef WITH_VERSE
523         struct VerseSession *session;
524         struct VNode *vnode;
525
526         session = session_list.first;
527         while(session) {
528                 vnode = session->nodes.lb.first;
529                 while(vnode) {
530                         switch(vnode->type) {
531                                 case V_NT_OBJECT:
532                                         unsubscribe_from_obj_node(vnode);
533                                         break;
534                                 case V_NT_GEOMETRY:
535                                         unsubscribe_from_geom_node(vnode);
536                                         break;
537                                 case V_NT_BITMAP:
538                                         unsubscribe_from_bitmap_node(vnode);
539                                         break;
540                         }
541                         vnode = vnode->next;
542                 }
543                 session = session->next;
544         }
545 #endif
546
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);
550         
551         if (retval== 0) {
552                 BIF_clear_tempfiles();
553                 
554                 /* we didn't succeed, now try to read Blender file */
555                 retval= BKE_read_file(name, NULL);
556
557                 mainwindow_set_filename_to_title(G.main->name);
558                 countall();
559                 sound_initialize_sounds();
560
561                 winqueue_break= 1;      /* leave queues everywhere */
562
563                 if(retval==2) init_userdef_file();      // in case a userdef is read from regular .blend
564                 
565                 if (retval!=0) G.relbase_valid = 1;
566
567                 undo_editmode_clear();
568                 BKE_reset_undo();
569                 BKE_write_undo("original");     /* save current state */
570
571                 refresh_interface_font();
572         }
573         else if(retval==1)
574                 BIF_undo_push("Import file");
575 }
576
577 static void outliner_242_patch(void)
578 {
579         ScrArea *sa;
580         
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);
589                                 }
590                         }
591                 }
592         }
593         G.fileflags |= G_FILE_GAME_MAT;
594 }
595
596 /* only here settings for fullscreen */
597 int BIF_read_homefile(int from_memory)
598 {
599         char tstr[FILE_MAXDIR+FILE_MAXFILE], scestr[FILE_MAXDIR];
600         char *home= BLI_gethome();
601         int success;
602         struct TmpFont *tf;
603         
604         BIF_clear_tempfiles();
605         
606         BLI_clean(home);
607
608         tf= G.ttfdata.first;
609         while(tf)
610         {
611                 freePackedFile(tf->pf);
612                 tf->pf = NULL;
613                 tf->vfont = NULL;
614                 tf= tf->next;
615         }
616         BLI_freelistN(&G.ttfdata);
617                 
618         G.relbase_valid = 0;
619         if (!from_memory) BLI_make_file_string(G.sce, tstr, home, ".B.blend");
620         strcpy(scestr, G.sce);  /* temporal store */
621         
622         /* prevent loading no UI */
623         G.fileflags &= ~G_FILE_NO_UI;
624         
625         if (!from_memory && BLI_exists(tstr)) {
626                 success = BKE_read_file(tstr, NULL);
627         } else {
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();
631         }
632
633         BLI_clean(scestr);
634         strcpy(G.sce, scestr);
635
636         space_set_commmandline_options();
637         
638         init_userdef_file();
639
640         undo_editmode_clear();
641         BKE_reset_undo();
642         BKE_write_undo("original");     /* save current state */
643         
644         return success;
645 }
646
647
648 static void get_autosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE])
649 {
650         char pidstr[32];
651 #ifdef WIN32
652         char subdir[9];
653         char savedir[FILE_MAXDIR];
654 #endif
655
656         sprintf(pidstr, "%d.blend", abs(getpid()));
657         
658 #ifdef WIN32
659         if (!BLI_exists(btempdir)) {
660                 BLI_strncpy(subdir, "autosave", sizeof(subdir));
661                 BLI_make_file_string("/", savedir, BLI_gethome(), subdir);
662                 
663                 /* create a new autosave dir
664                  * function already checks for existence or not */
665                 BLI_recurdir_fileops(savedir);
666         
667                 BLI_make_file_string("/", buf, savedir, pidstr);
668                 return;
669         }
670 #endif
671         
672         BLI_make_file_string("/", buf, btempdir, pidstr);
673 }
674
675 void BIF_read_autosavefile(void)
676 {
677         char tstr[FILE_MAX], scestr[FILE_MAX];
678         int save_over;
679
680         BLI_strncpy(scestr, G.sce, FILE_MAX);   /* temporal store */
681         
682         get_autosave_location(tstr);
683
684         save_over = G.save_over;
685         BKE_read_file(tstr, NULL);
686         G.save_over = save_over;
687         BLI_strncpy(G.sce, scestr, FILE_MAX);
688 }
689
690 /* free strings of open recent files */
691 static void free_openrecent(void)
692 {
693         struct RecentFile *recent;
694
695         for(recent = G.recent_files.first; recent; recent=recent->next)
696                 MEM_freeN(recent->filename);
697
698         BLI_freelistN(&(G.recent_files));
699 }
700
701 static void readBlog(void)
702 {
703         char name[FILE_MAX], filename[FILE_MAX];
704         LinkNode *l, *lines;
705         struct RecentFile *recent;
706         char *line;
707         int num;
708
709         BLI_make_file_string("/", name, BLI_gethome(), ".Blog");
710         lines= BLI_read_file_as_lines(name);
711
712         G.recent_files.first = G.recent_files.last = NULL;
713
714         /* read list of recent opend files from .Blog to memory */
715         for (l= lines, num= 0; l && (num<U.recent_files); l= l->next, num++) {
716                 line = l->link;
717                 if (!BLI_streq(line, "")) {
718                         if (num==0) 
719                                 strcpy(G.sce, line);
720                         
721                         recent = (RecentFile*)MEM_mallocN(sizeof(RecentFile),"RecentFile");
722                         BLI_addtail(&(G.recent_files), recent);
723                         recent->filename = (char*)MEM_mallocN(sizeof(char)*(strlen(line)+1), "name of file");
724                         recent->filename[0] = '\0';
725                         
726                         strcpy(recent->filename, line);
727                 }
728         }
729
730         if(G.sce[0] == 0)
731                 BLI_make_file_string("/", G.sce, BLI_gethome(), "untitled.blend");
732         
733         BLI_free_file_lines(lines);
734
735 #ifdef WIN32
736         /* Add the drive names to the listing */
737         {
738                 __int64 tmp;
739                 char folder[MAX_PATH];
740                 char tmps[4];
741                 int i;
742                         
743                 tmp= GetLogicalDrives();
744                 
745                 for (i=2; i < 26; i++) {
746                         if ((tmp>>i) & 1) {
747                                 tmps[0]='a'+i;
748                                 tmps[1]=':';
749                                 tmps[2]='\\';
750                                 tmps[3]=0;
751                                 
752                                 fsmenu_insert_entry(tmps, 0, 0);
753                         }
754                 }
755
756                 /* Adding Desktop and My Documents */
757                 fsmenu_append_separator();
758
759                 SHGetSpecialFolderPath(0, folder, CSIDL_PERSONAL, 0);
760                 fsmenu_insert_entry(folder, 0, 0);
761                 SHGetSpecialFolderPath(0, folder, CSIDL_DESKTOPDIRECTORY, 0);
762                 fsmenu_insert_entry(folder, 0, 0);
763
764                 fsmenu_append_separator();
765         }
766 #else
767         /* add home dir on linux systems */
768         fsmenu_insert_entry(BLI_gethome(), 0, 0);
769 #endif
770
771         BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs");
772         lines= BLI_read_file_as_lines(name);
773
774         for (l= lines; l; l= l->next) {
775                 char *line= l->link;
776                         
777                 if (!BLI_streq(line, "")) {
778                         fsmenu_insert_entry(line, 0, 1);
779                 }
780         }
781
782         fsmenu_append_separator();
783         
784         /* add last saved file */
785         BLI_split_dirfile(G.sce, name, filename); /* G.sce shouldn't be relative */
786         
787         fsmenu_insert_entry(name, 0, 0);
788         
789         BLI_free_file_lines(lines);
790 }
791
792 static void writeBlog(void)
793 {
794         struct RecentFile *recent, *next_recent;
795         char name[FILE_MAXDIR+FILE_MAXFILE];
796         FILE *fp;
797         int i;
798
799         BLI_make_file_string("/", name, BLI_gethome(), ".Blog");
800
801         recent = G.recent_files.first;
802         /* refresh .Blog of recent opened files, when current file was changed */
803         if(!(recent) || (strcmp(recent->filename, G.sce)!=0)) {
804                 fp= fopen(name, "w");
805                 if (fp) {
806                         /* add current file to the beginning of list */
807                         recent = (RecentFile*)MEM_mallocN(sizeof(RecentFile),"RecentFile");
808                         recent->filename = (char*)MEM_mallocN(sizeof(char)*(strlen(G.sce)+1), "name of file");
809                         recent->filename[0] = '\0';
810                         strcpy(recent->filename, G.sce);
811                         BLI_addhead(&(G.recent_files), recent);
812                         /* write current file to .Blog */
813                         fprintf(fp, "%s\n", recent->filename);
814                         recent = recent->next;
815                         i=1;
816                         /* write rest of recent opened files to .Blog */
817                         while((i<U.recent_files) && (recent)){
818                                 /* this prevents to have duplicities in list */
819                                 if (strcmp(recent->filename, G.sce)!=0) {
820                                         fprintf(fp, "%s\n", recent->filename);
821                                         recent = recent->next;
822                                 }
823                                 else {
824                                         next_recent = recent->next;
825                                         MEM_freeN(recent->filename);
826                                         BLI_freelinkN(&(G.recent_files), recent);
827                                         recent = next_recent;
828                                 }
829                                 i++;
830                         }
831                         fclose(fp);
832                 }
833         }
834 }
835
836 static void do_history(char *name)
837 {
838         char tempname1[FILE_MAXDIR+FILE_MAXFILE], tempname2[FILE_MAXDIR+FILE_MAXFILE];
839         int hisnr= U.versions;
840         
841         if(U.versions==0) return;
842         if(strlen(name)<2) return;
843                 
844         while(  hisnr > 1) {
845                 sprintf(tempname1, "%s%d", name, hisnr-1);
846                 sprintf(tempname2, "%s%d", name, hisnr);
847         
848                 if(BLI_rename(tempname1, tempname2))
849                         error("Unable to make version backup");
850                         
851                 hisnr--;
852         }
853                 
854         /* is needed when hisnr==1 */
855         sprintf(tempname1, "%s%d", name, hisnr);
856         
857         if(BLI_rename(name, tempname1))
858                 error("Unable to make version backup");
859 }
860
861 void BIF_write_file(char *target)
862 {
863         Library *li;
864         int writeflags, len;
865         char di[FILE_MAX];
866         char *err;
867         
868         len = strlen(target);
869         
870         if (len == 0) return;
871         if (len >= FILE_MAX) {
872                 error("Path too long, cannot save");
873                 return;
874         }
875  
876         /* send the OnSave event */
877         if (G.f & G_DOSCRIPTLINKS) BPY_do_pyscript(&G.scene->id, SCRIPT_ONSAVE);
878
879         for (li= G.main->library.first; li; li= li->id.next) {
880                 if (BLI_streq(li->name, target)) {
881                         error("Cannot overwrite used library");
882                         return;
883                 }
884         }
885         
886         if (!BLO_has_bfile_extension(target) && (len+6 < FILE_MAX)) {
887                 sprintf(di, "%s.blend", target);
888         } else {
889                 strcpy(di, target);
890         }
891
892         if (BLI_exists(di)) {
893                 if(!saveover(di))
894                         return; 
895         }
896         
897         if(G.obedit) {
898                 exit_editmode(0);       /* 0 = no free data */
899         }
900         if (G.fileflags & G_AUTOPACK) {
901                 packAll();
902         }
903         
904         waitcursor(1);  // exit_editmode sets cursor too
905
906         do_history(di);
907         
908         /* we use the UserDef to define compression flag */
909         writeflags= G.fileflags & ~G_FILE_COMPRESS;
910         if(U.flag & USER_FILECOMPRESS)
911                 writeflags |= G_FILE_COMPRESS;
912         
913         if (BLO_write_file(di, writeflags, &err)) {
914                 strcpy(G.sce, di);
915                 G.relbase_valid = 1;
916                 strcpy(G.main->name, di);       /* is guaranteed current file */
917
918                 mainwindow_set_filename_to_title(G.main->name);
919
920                 G.save_over = 1;
921
922                 writeBlog();
923         } else {
924                 error("%s", err);
925         }
926
927         waitcursor(0);
928 }
929
930 void BIF_write_homefile(void)
931 {
932         char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
933         int write_flags;
934         
935         BLI_make_file_string("/", tstr, BLI_gethome(), ".B.blend");
936                 
937         /*  force save as regular blend file */
938         write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
939         BLO_write_file(tstr, write_flags, &err);
940 }
941
942 void BIF_write_autosave(void)
943 {
944         char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
945         int write_flags;
946         
947         get_autosave_location(tstr);
948
949                 /*  force save as regular blend file */
950         write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
951         BLO_write_file(tstr, write_flags, &err);
952 }
953
954 /* remove temp files assosiated with this blend file when quitting, loading or saving in a new path */
955 void BIF_clear_tempfiles( void )
956 {
957         /* TODO - remove exr files from the temp dir */
958         
959         if (!G.relbase_valid) { /* We could have pointcache saved in tyhe temp dir, if its there */
960                 BKE_ptcache_remove();
961         }
962 }
963
964 /* if global undo; remove tempsave, otherwise rename */
965 static void delete_autosave(void)
966 {
967         char tstr[FILE_MAXDIR+FILE_MAXFILE];
968         
969         get_autosave_location(tstr);
970
971         if (BLI_exists(tstr)) {
972                 char str[FILE_MAXDIR+FILE_MAXFILE];
973                 BLI_make_file_string("/", str, btempdir, "quit.blend");
974
975                 if(U.uiflag & USER_GLOBALUNDO) BLI_delete(tstr, 0, 0);
976                 else BLI_rename(tstr, str);
977         }
978 }
979
980 /***/
981
982 static void initbuttons(void)
983 {
984         uiDefFont(UI_HELVB, 
985                                 BMF_GetFont(BMF_kHelveticaBold14), 
986                                 BMF_GetFont(BMF_kHelveticaBold12), 
987                                 BMF_GetFont(BMF_kHelveticaBold10), 
988                                 BMF_GetFont(BMF_kHelveticaBold8));
989         uiDefFont(UI_HELV, 
990                                 BMF_GetFont(BMF_kHelvetica12), 
991                                 BMF_GetFont(BMF_kHelvetica12), 
992                                 BMF_GetFont(BMF_kHelvetica10), 
993                                 BMF_GetFont(BMF_kHelveticaBold8));
994
995         glClearColor(.7f, .7f, .6f, 0.0);
996         
997         G.font= BMF_GetFont(BMF_kHelvetica12);
998         G.fonts= BMF_GetFont(BMF_kHelvetica10);
999         G.fontss= BMF_GetFont(BMF_kHelveticaBold8);
1000
1001         clear_matcopybuf();
1002         
1003         glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
1004 }
1005
1006
1007 static void sound_init_listener(void)
1008 {
1009         G.listener = MEM_callocN(sizeof(bSoundListener), "soundlistener");
1010         G.listener->gain = 1.0;
1011         G.listener->dopplerfactor = 1.0;
1012         G.listener->dopplervelocity = 340.29f;
1013 }
1014
1015 void BIF_init(void)
1016 {
1017
1018         initscreen();   /* for (visuele) speed, this first, then setscreen */
1019         initbuttons();
1020         InitCursorData();
1021         sound_init_listener();
1022         init_node_butfuncs();
1023         
1024         BIF_preview_init_dbase();
1025         BIF_read_homefile(0);
1026
1027         BIF_resources_init();   /* after homefile, to dynamically load an icon file based on theme settings */
1028         
1029         BIF_filelist_init_icons();
1030
1031         init_gl_stuff();        /* drawview.c, after homefile */
1032         readBlog();
1033         BLI_strncpy(G.lib, G.sce, FILE_MAX);
1034 }
1035
1036 /***/
1037
1038 extern ListBase editNurb;
1039 extern ListBase editelems;
1040
1041 void exit_usiblender(void)
1042 {
1043         struct TmpFont *tf;
1044         
1045         BIF_clear_tempfiles();
1046         
1047         tf= G.ttfdata.first;
1048         while(tf)
1049         {
1050                 freePackedFile(tf->pf);
1051                 tf->pf= NULL;
1052                 tf->vfont= NULL;
1053                 tf= tf->next;
1054         }
1055         BLI_freelistN(&G.ttfdata);
1056 #ifdef WITH_VERSE
1057         end_all_verse_sessions();
1058 #endif
1059         free_openrecent();
1060
1061         freeAllRad();
1062         BKE_freecubetable();
1063
1064         if (G.background == 0)
1065                 sound_end_all_sounds();
1066
1067         if(G.obedit) {
1068                 if(G.obedit->type==OB_FONT) {
1069                         free_editText();
1070                 }
1071                 else if(G.obedit->type==OB_MBALL) BLI_freelistN(&editelems);
1072                 free_editMesh(G.editMesh);
1073         }
1074
1075         free_editLatt();
1076         free_editArmature();
1077         free_posebuf();
1078
1079         /* before free_blender so py's gc happens while library still exists */
1080         /* needed at least for a rare sigsegv that can happen in pydrivers */
1081         BPY_end_python();
1082
1083         fastshade_free_render();        /* shaded view */
1084         free_blender();                         /* blender.c, does entire library */
1085         free_matcopybuf();
1086         free_ipocopybuf();
1087         free_actcopybuf();
1088         free_vertexpaint();
1089         free_imagepaint();
1090         
1091         /* editnurb can remain to exist outside editmode */
1092         freeNurblist(&editNurb);
1093
1094         fsmenu_free();
1095
1096 #ifdef INTERNATIONAL
1097         free_languagemenu();
1098 #endif
1099         
1100         RE_FreeAllRender();
1101         
1102         free_txt_data();
1103
1104         sound_exit_audio();
1105         if(G.listener) MEM_freeN(G.listener);
1106
1107
1108         libtiff_exit();
1109
1110 #ifdef WITH_QUICKTIME
1111         quicktime_exit();
1112 #endif
1113
1114         /* undo free stuff */
1115         undo_editmode_clear();
1116         
1117         BKE_undo_save_quit();   // saves quit.blend if global undo is on
1118         BKE_reset_undo(); 
1119         
1120         if (!G.background) {
1121                 BIF_resources_free();
1122                 
1123                 BIF_filelist_free_icons();
1124
1125                 BIF_free_render_spare();
1126                 BIF_close_render_display();
1127                 mainwindow_close();
1128         }
1129
1130 #ifdef INTERNATIONAL
1131         FTF_End();
1132 #endif
1133
1134         if (copybuf) MEM_freeN(copybuf);
1135         if (copybufinfo) MEM_freeN(copybufinfo);
1136
1137 //      
1138         BLI_freelistN(&U.themes);
1139         BIF_preview_free_dbase();
1140         
1141         if(totblock!=0) {
1142                 printf("Error Totblock: %d\n",totblock);
1143                 MEM_printmemlist();
1144         }
1145         delete_autosave();
1146         
1147         printf("\nBlender quit\n");
1148
1149 #ifdef WIN32   
1150         /* ask user to press enter when in debug mode */
1151         if(G.f & G_DEBUG) {
1152                 printf("press enter key to exit...\n\n");
1153                 getchar();
1154         }
1155 #endif 
1156
1157
1158         SYS_DeleteSystem(SYS_GetSystem());
1159         
1160         exit(G.afbreek==1);
1161 }