svn merge -r36564:36583 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / blender / windowmanager / intern / wm_init_exit.c
index 09eecf2f4255fdd4c42a594dda058aae9bbf8717..2a37654a23bc0a21d0491bdd9c7d692daa445f19 100644 (file)
@@ -1,5 +1,5 @@
-/**
- * $Id:
+/*
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
@@ -15,7 +15,7 @@
  *
  * 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.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2007 Blender Foundation.
  * All rights reserved.
  * ***** END GPL LICENSE BLOCK *****
  */
 
+/** \file blender/windowmanager/intern/wm_init_exit.c
+ *  \ingroup wm
+ */
+
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include "BKE_font.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
+#include "BKE_main.h"
 #include "BKE_mball.h"
 #include "BKE_report.h"
-#include "BKE_utildefines.h"
+
 #include "BKE_packedFile.h"
+#include "BKE_sequencer.h" /* free seq clipboard */
+#include "BKE_material.h" /* clear_matcopybuf */
 
 #include "BLI_blenlib.h"
+#include "BLI_cellalloc.h"
+#include "BLI_winstuff.h"
 
 #include "RE_pipeline.h"               /* RE_ free stuff */
 
-#ifndef DISABLE_PYTHON
+#ifdef WITH_PYTHON
 #include "BPY_extern.h"
 #endif
 
-#include "SYS_System.h"
+#ifdef WITH_GAMEENGINE
+#include "BL_System.h"
+#endif
+#include "GHOST_Path-api.h"
+#include "GHOST_C-api.h"
 
 #include "RNA_define.h"
 
 #include "UI_interface.h"
 #include "BLF_api.h"
 
-#include "gpu_buffers.h"
+#include "GPU_buffers.h"
 #include "GPU_extensions.h"
 #include "GPU_draw.h"
 
@@ -102,16 +116,16 @@ static void wm_free_reports(bContext *C)
        BKE_reports_clear(CTX_wm_reports(C));
 }
 
-
+int wm_start_with_console = 0;
 
 /* only called once, for startup */
-void WM_init(bContext *C)
+void WM_init(bContext *C, int argc, const char **argv)
 {
-       
        if (!G.background) {
                wm_ghost_init(C);       /* note: it assigns C to ghost! */
                wm_init_cursor_data();
        }
+       GHOST_CreateSystemPaths();
        wm_operatortype_init();
        
        set_free_windowmanager_cb(wm_close_and_free);   /* library.c */
@@ -123,47 +137,189 @@ void WM_init(bContext *C)
        ED_file_init();                 /* for fsmenu */
        ED_init_node_butfuncs();        
        
-       BLF_init(11, U.dpi);
+       BLF_init(11, U.dpi); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */
        BLF_lang_init();
-       
-       init_builtin_keyingsets(); /* editors/animation/keyframing.c */
-       
        /* get the default database, plus a wm */
-       WM_read_homefile(C, NULL);
-       
+       WM_read_homefile(C, NULL, G.factory_startup);
+
+       /* note: there is a bug where python needs initializing before loading the
+        * startup.blend because it may contain PyDrivers. It also needs to be after
+        * initializing space types and other internal data.
+        *
+        * However cant redo this at the moment. Solution is to load python
+        * before WM_read_homefile() or make py-drivers check if python is running.
+        * Will try fix when the crash can be repeated. - campbell. */
+
+#ifdef WITH_PYTHON
+       BPY_context_set(C); /* necessary evil */
+       BPY_python_start(argc, argv);
+
+       BPY_driver_reset();
+       BPY_modules_load_user(C);
+#else
+       (void)argc; /* unused */
+       (void)argv; /* unused */
+#endif
+
+       if (!G.background && !wm_start_with_console)
+               GHOST_toggleConsole(3);
+
        wm_init_reports(C); /* reports cant be initialized before the wm */
 
        if (!G.background) {
                GPU_extensions_init();
+               GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP));
        
                UI_init();
        }
        
-       //      clear_matcopybuf(); /* XXX */
-       
+       clear_matcopybuf();
+       ED_render_clear_mtex_copybuf();
+
        //      glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
-       
-//     init_node_butfuncs();
-       
+               
        ED_preview_init_dbase();
        
        G.ndofdevice = -1;      /* XXX bad initializer, needs set otherwise buttons show! */
        
-       read_Blog();
-       BLI_strncpy(G.lib, G.sce, FILE_MAX);
+       WM_read_history();
 
+       /* allow a path of "", this is what happens when making a new file */
+       /*
+       if(G.main->name[0] == 0)
+               BLI_make_file_string("/", G.main->name, BLI_getDefaultDocumentFolder(), "untitled.blend");
+       */
+
+       BLI_strncpy(G.lib, G.main->name, FILE_MAX);
 }
 
 void WM_init_splash(bContext *C)
+{
+       if((U.uiflag & USER_SPLASH_DISABLE) == 0) {
+               wmWindowManager *wm= CTX_wm_manager(C);
+               wmWindow *prevwin= CTX_wm_window(C);
+       
+               if(wm->windows.first) {
+                       CTX_wm_window_set(C, wm->windows.first);
+                       WM_operator_name_call(C, "WM_OT_splash", WM_OP_INVOKE_DEFAULT, NULL);
+                       CTX_wm_window_set(C, prevwin);
+               }
+       }
+}
+
+static ScrArea *biggest_view3d(bContext *C)
+{
+       bScreen *sc= CTX_wm_screen(C);
+       ScrArea *sa, *big= NULL;
+       int size, maxsize= 0;
+
+       for(sa= sc->areabase.first; sa; sa= sa->next) {
+               if(sa->spacetype==SPACE_VIEW3D) {
+                       size= sa->winx * sa->winy;
+                       if(size > maxsize) {
+                               maxsize= size;
+                               big= sa;
+                       }
+               }
+       }
+       return big;
+}
+
+int WM_init_game(bContext *C)
 {
        wmWindowManager *wm= CTX_wm_manager(C);
-       wmWindow *prevwin= CTX_wm_window(C);
-       
-       if(wm->windows.first) {
-               CTX_wm_window_set(C, wm->windows.first);
-               WM_operator_name_call(C, "WM_OT_splash", WM_OP_INVOKE_DEFAULT, NULL);
-               CTX_wm_window_set(C, prevwin);
+       wmWindow* win;
+
+       ScrArea *sa;
+       ARegion *ar= NULL;
+
+       Scene *scene= CTX_data_scene(C);
+
+       if (!scene) {
+               // XXX, this should not be needed.
+               Main *bmain = CTX_data_main(C);
+               scene= bmain->scene.first;
+       }
+
+       win = wm->windows.first;
+
+       //first to get a valid window
+       if(win)
+               CTX_wm_window_set(C, win);
+
+       sa = biggest_view3d(C);
+
+       if(sa)
+       {
+               for(ar=sa->regionbase.first; ar; ar=ar->next) {
+                       if(ar->regiontype == RGN_TYPE_WINDOW) {
+                               break;
+                       }
+               }
+       }
+
+       // if we have a valid 3D view
+       if (sa && ar) {
+               ARegion *arhide;
+
+               CTX_wm_area_set(C, sa);
+               CTX_wm_region_set(C, ar);
+
+               /* disable quad view */
+               if(ar->alignment == RGN_ALIGN_QSPLIT)
+                       WM_operator_name_call(C, "SCREEN_OT_region_quadview", WM_OP_EXEC_DEFAULT, NULL);
+
+               /* toolbox, properties panel and header are hidden */
+               for(arhide=sa->regionbase.first; arhide; arhide=arhide->next) {
+                       if(arhide->regiontype != RGN_TYPE_WINDOW) {
+                               if(!(arhide->flag & RGN_FLAG_HIDDEN)) {
+                                       ED_region_toggle_hidden(C, arhide);
+                               }
+                       }
+               }
+
+               /* full screen the area */
+               if(!sa->full) {
+                       ED_screen_full_toggle(C, win, sa);
+               }
+
+               /* Fullscreen */
+               if(scene->gm.fullscreen) {
+                       WM_operator_name_call(C, "WM_OT_window_fullscreen_toggle", WM_OP_EXEC_DEFAULT, NULL);
+                       wm_get_screensize(&ar->winrct.xmax, &ar->winrct.ymax);
+                       ar->winx = ar->winrct.xmax + 1;
+                       ar->winy = ar->winrct.ymax + 1;
+               }
+               else
+               {
+                       GHOST_RectangleHandle rect = GHOST_GetClientBounds(win->ghostwin);
+                       ar->winrct.ymax = GHOST_GetHeightRectangle(rect);
+                       ar->winrct.xmax = GHOST_GetWidthRectangle(rect);
+                       ar->winx = ar->winrct.xmax + 1;
+                       ar->winy = ar->winrct.ymax + 1;
+                       GHOST_DisposeRectangle(rect);
+               }
+
+               WM_operator_name_call(C, "VIEW3D_OT_game_start", WM_OP_EXEC_DEFAULT, NULL);
+
+               return 1;
+       }
+       else
+       {
+               ReportTimerInfo *rti;
+
+               BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found. Game auto start is not possible.");
+
+               /* After adding the report to the global list, reset the report timer. */
+               WM_event_remove_timer(wm, NULL, wm->reports.reporttimer);
+
+               /* Records time since last report was added */
+               wm->reports.reporttimer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER, 0.02);
+
+               rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo");
+               wm->reports.reporttimer->customdata = rti;
        }
+       return 0;
 }
 
 /* free strings of open recent files */
@@ -172,7 +328,7 @@ static void free_openrecent(void)
        struct RecentFile *recent;
        
        for(recent = G.recent_files.first; recent; recent=recent->next)
-               MEM_freeN(recent->filename);
+               MEM_freeN(recent->filepath);
        
        BLI_freelistN(&(G.recent_files));
 }
@@ -185,9 +341,10 @@ extern wchar_t *copybuf;
 extern wchar_t *copybufinfo;
 
        // XXX copy/paste buffer stuff...
-extern void free_anim_copybuf(); 
-extern void free_anim_drivers_copybuf(); 
-extern void free_posebuf(); 
+extern void free_anim_copybuf(void); 
+extern void free_anim_drivers_copybuf(void); 
+extern void free_fmodifiers_copybuf(void); 
+extern void free_posebuf(void); 
 
 /* called in creator.c even... tsk, split this! */
 void WM_exit(bContext *C)
@@ -196,6 +353,7 @@ void WM_exit(bContext *C)
 
        sound_exit();
 
+
        /* first wrap up running stuff, we assume only the active WM is running */
        /* modal handlers are on window level freed, others too? */
        /* note; same code copied in wm_files.c */
@@ -212,6 +370,7 @@ void WM_exit(bContext *C)
                }
        }
        wm_operatortype_free();
+       wm_dropbox_free();
        WM_menutype_free();
        
        /* all non-screen and non-space stuff editors did, like editmode */
@@ -234,11 +393,14 @@ void WM_exit(bContext *C)
 
        if(C && CTX_wm_manager(C))
                wm_free_reports(C);                     /* before free_blender! - since the ListBases get freed there */
+
+       seq_free_clipboard(); /* sequencer.c */
                
        free_blender();                         /* blender.c, does entire library and spacetypes */
 //     free_matcopybuf();
        free_anim_copybuf();
        free_anim_drivers_copybuf();
+       free_fmodifiers_copybuf();
        free_posebuf();
 //     free_vertexpaint();
 //     free_imagepaint();
@@ -246,14 +408,16 @@ void WM_exit(bContext *C)
 //     fsmenu_free();
 
        BLF_exit();
-
+       
+       ANIM_keyingset_infos_exit();
+       
        RE_FreeAllRender();
        RE_engines_exit();
        
 //     free_txt_data();
        
 
-#ifndef DISABLE_PYTHON
+#ifdef WITH_PYTHON
        /* XXX - old note */
        /* before free_blender so py's gc happens while library still exists */
        /* needed at least for a rare sigsegv that can happen in pydrivers */
@@ -261,26 +425,22 @@ void WM_exit(bContext *C)
        /* Update for blender 2.5, move after free_blender because blender now holds references to PyObject's
         * so decref'ing them after python ends causes bad problems every time
         * the pyDriver bug can be fixed if it happens again we can deal with it then */
-       BPY_end_python();
+       BPY_python_end();
 #endif
 
-       libtiff_exit();
-       
-#ifdef WITH_QUICKTIME
-       quicktime_exit();
-#endif
-       
        if (!G.background) {
 // XXX         UI_filelist_free_icons();
        }
        
-       GPU_buffer_pool_free(0);
+       GPU_buffer_pool_free(NULL);
+       GPU_free_unused_buffers();
        GPU_extensions_exit();
        
 //     if (copybuf) MEM_freeN(copybuf);
 //     if (copybufinfo) MEM_freeN(copybufinfo);
-       
-       BKE_undo_save_quit();   // saves quit.blend if global undo is on
+       if (!G.background) {
+               BKE_undo_save_quit();   // saves quit.blend if global undo is on
+       }
        BKE_reset_undo(); 
        
        ED_file_exit(); /* for fsmenu */
@@ -288,17 +448,22 @@ void WM_exit(bContext *C)
        UI_exit();
        BKE_userdef_free();
 
-       RNA_exit(); /* should be after BPY_end_python so struct python slots are cleared */
+       RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */
        
        wm_ghost_exit();
 
        CTX_free(C);
-       
+#ifdef WITH_GAMEENGINE
        SYS_DeleteSystem(SYS_GetSystem());
+#endif
+       
+       GHOST_DisposeSystemPaths();
 
        if(MEM_get_memory_blocks_in_use()!=0) {
-               printf("Error Totblock: %d\n", MEM_get_memory_blocks_in_use());
+               printf("Error: Not freed memory blocks: %d\n", MEM_get_memory_blocks_in_use()+BLI_cellalloc_get_totblock());
                MEM_printmemlist();
+               BLI_cellalloc_printleaks();
+               BLI_cellalloc_destroy();
        }
        wm_autosave_delete();
        
@@ -311,7 +476,6 @@ void WM_exit(bContext *C)
                getchar();
        }
 #endif 
-       
        exit(G.afbreek==1);
 }