|
Blender
V2.59
|
00001 /* 00002 * $Id: wm_init_exit.c 39293 2011-08-11 06:06:17Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2007 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Blender Foundation 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <stdlib.h> 00035 #include <stdio.h> 00036 #include <string.h> 00037 00038 #include "MEM_guardedalloc.h" 00039 #include "MEM_CacheLimiterC-Api.h" 00040 00041 #include "IMB_imbuf_types.h" 00042 #include "IMB_imbuf.h" 00043 00044 #include "DNA_object_types.h" 00045 #include "DNA_scene_types.h" 00046 #include "DNA_userdef_types.h" 00047 #include "DNA_windowmanager_types.h" 00048 00049 #include "BKE_blender.h" 00050 #include "BKE_context.h" 00051 #include "BKE_screen.h" 00052 #include "BKE_curve.h" 00053 #include "BKE_displist.h" 00054 #include "BKE_DerivedMesh.h" 00055 #include "BKE_font.h" 00056 #include "BKE_global.h" 00057 #include "BKE_library.h" 00058 #include "BKE_main.h" 00059 #include "BKE_mball.h" 00060 #include "BKE_report.h" 00061 00062 #include "BKE_packedFile.h" 00063 #include "BKE_sequencer.h" /* free seq clipboard */ 00064 #include "BKE_material.h" /* clear_matcopybuf */ 00065 00066 #include "BLI_blenlib.h" 00067 #include "BLI_winstuff.h" 00068 00069 #include "RE_pipeline.h" /* RE_ free stuff */ 00070 00071 #ifdef WITH_PYTHON 00072 #include "BPY_extern.h" 00073 #endif 00074 00075 #ifdef WITH_GAMEENGINE 00076 #include "BL_System.h" 00077 #endif 00078 #include "GHOST_Path-api.h" 00079 #include "GHOST_C-api.h" 00080 00081 #include "RNA_define.h" 00082 00083 #include "WM_api.h" 00084 #include "WM_types.h" 00085 00086 #include "wm_cursors.h" 00087 #include "wm_event_system.h" 00088 #include "wm.h" 00089 #include "wm_files.h" 00090 #include "wm_window.h" 00091 00092 #include "ED_armature.h" 00093 #include "ED_keyframing.h" 00094 #include "ED_node.h" 00095 #include "ED_render.h" 00096 #include "ED_space_api.h" 00097 #include "ED_screen.h" 00098 #include "ED_util.h" 00099 00100 #include "UI_interface.h" 00101 #include "BLF_api.h" 00102 00103 #include "GPU_buffers.h" 00104 #include "GPU_extensions.h" 00105 #include "GPU_draw.h" 00106 00107 #include "BKE_depsgraph.h" 00108 #include "BKE_sound.h" 00109 00110 static void wm_init_reports(bContext *C) 00111 { 00112 BKE_reports_init(CTX_wm_reports(C), RPT_STORE); 00113 } 00114 static void wm_free_reports(bContext *C) 00115 { 00116 BKE_reports_clear(CTX_wm_reports(C)); 00117 } 00118 00119 int wm_start_with_console = 0; 00120 00121 /* only called once, for startup */ 00122 void WM_init(bContext *C, int argc, const char **argv) 00123 { 00124 if (!G.background) { 00125 wm_ghost_init(C); /* note: it assigns C to ghost! */ 00126 wm_init_cursor_data(); 00127 } 00128 GHOST_CreateSystemPaths(); 00129 wm_operatortype_init(); 00130 WM_menutype_init(); 00131 00132 set_free_windowmanager_cb(wm_close_and_free); /* library.c */ 00133 set_blender_test_break_cb(wm_window_testbreak); /* blender.c */ 00134 DAG_editors_update_cb(ED_render_id_flush_update); /* depsgraph.c */ 00135 00136 ED_spacetypes_init(); /* editors/space_api/spacetype.c */ 00137 00138 ED_file_init(); /* for fsmenu */ 00139 ED_init_node_butfuncs(); 00140 00141 BLF_init(11, U.dpi); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */ 00142 BLF_lang_init(); 00143 /* get the default database, plus a wm */ 00144 WM_read_homefile(C, NULL, G.factory_startup); 00145 00146 /* note: there is a bug where python needs initializing before loading the 00147 * startup.blend because it may contain PyDrivers. It also needs to be after 00148 * initializing space types and other internal data. 00149 * 00150 * However cant redo this at the moment. Solution is to load python 00151 * before WM_read_homefile() or make py-drivers check if python is running. 00152 * Will try fix when the crash can be repeated. - campbell. */ 00153 00154 #ifdef WITH_PYTHON 00155 BPY_context_set(C); /* necessary evil */ 00156 BPY_python_start(argc, argv); 00157 00158 BPY_driver_reset(); 00159 BPY_app_handlers_reset(); /* causes addon callbacks to be freed [#28068], 00160 * but this is actually what we want. */ 00161 BPY_modules_load_user(C); 00162 #else 00163 (void)argc; /* unused */ 00164 (void)argv; /* unused */ 00165 #endif 00166 00167 if (!G.background && !wm_start_with_console) 00168 GHOST_toggleConsole(3); 00169 00170 wm_init_reports(C); /* reports cant be initialized before the wm */ 00171 00172 if (!G.background) { 00173 GPU_extensions_init(); 00174 GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP)); 00175 GPU_set_anisotropic(U.anisotropic_filter); 00176 00177 UI_init(); 00178 } 00179 00180 clear_matcopybuf(); 00181 ED_render_clear_mtex_copybuf(); 00182 00183 // glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 00184 00185 ED_preview_init_dbase(); 00186 00187 WM_read_history(); 00188 00189 /* allow a path of "", this is what happens when making a new file */ 00190 /* 00191 if(G.main->name[0] == 0) 00192 BLI_make_file_string("/", G.main->name, BLI_getDefaultDocumentFolder(), "untitled.blend"); 00193 */ 00194 00195 BLI_strncpy(G.lib, G.main->name, FILE_MAX); 00196 } 00197 00198 void WM_init_splash(bContext *C) 00199 { 00200 if((U.uiflag & USER_SPLASH_DISABLE) == 0) { 00201 wmWindowManager *wm= CTX_wm_manager(C); 00202 wmWindow *prevwin= CTX_wm_window(C); 00203 00204 if(wm->windows.first) { 00205 CTX_wm_window_set(C, wm->windows.first); 00206 WM_operator_name_call(C, "WM_OT_splash", WM_OP_INVOKE_DEFAULT, NULL); 00207 CTX_wm_window_set(C, prevwin); 00208 } 00209 } 00210 } 00211 00212 static ScrArea *biggest_view3d(bContext *C) 00213 { 00214 bScreen *sc= CTX_wm_screen(C); 00215 ScrArea *sa, *big= NULL; 00216 int size, maxsize= 0; 00217 00218 for(sa= sc->areabase.first; sa; sa= sa->next) { 00219 if(sa->spacetype==SPACE_VIEW3D) { 00220 size= sa->winx * sa->winy; 00221 if(size > maxsize) { 00222 maxsize= size; 00223 big= sa; 00224 } 00225 } 00226 } 00227 return big; 00228 } 00229 00230 int WM_init_game(bContext *C) 00231 { 00232 wmWindowManager *wm= CTX_wm_manager(C); 00233 wmWindow* win; 00234 00235 ScrArea *sa; 00236 ARegion *ar= NULL; 00237 00238 Scene *scene= CTX_data_scene(C); 00239 00240 if (!scene) { 00241 // XXX, this should not be needed. 00242 Main *bmain = CTX_data_main(C); 00243 scene= bmain->scene.first; 00244 } 00245 00246 win = wm->windows.first; 00247 00248 //first to get a valid window 00249 if(win) 00250 CTX_wm_window_set(C, win); 00251 00252 sa = biggest_view3d(C); 00253 ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); 00254 00255 // if we have a valid 3D view 00256 if (sa && ar) { 00257 ARegion *arhide; 00258 00259 CTX_wm_area_set(C, sa); 00260 CTX_wm_region_set(C, ar); 00261 00262 /* disable quad view */ 00263 if(ar->alignment == RGN_ALIGN_QSPLIT) 00264 WM_operator_name_call(C, "SCREEN_OT_region_quadview", WM_OP_EXEC_DEFAULT, NULL); 00265 00266 /* toolbox, properties panel and header are hidden */ 00267 for(arhide=sa->regionbase.first; arhide; arhide=arhide->next) { 00268 if(arhide->regiontype != RGN_TYPE_WINDOW) { 00269 if(!(arhide->flag & RGN_FLAG_HIDDEN)) { 00270 ED_region_toggle_hidden(C, arhide); 00271 } 00272 } 00273 } 00274 00275 /* full screen the area */ 00276 if(!sa->full) { 00277 ED_screen_full_toggle(C, win, sa); 00278 } 00279 00280 /* Fullscreen */ 00281 if(scene->gm.fullscreen) { 00282 WM_operator_name_call(C, "WM_OT_window_fullscreen_toggle", WM_OP_EXEC_DEFAULT, NULL); 00283 wm_get_screensize(&ar->winrct.xmax, &ar->winrct.ymax); 00284 ar->winx = ar->winrct.xmax + 1; 00285 ar->winy = ar->winrct.ymax + 1; 00286 } 00287 else 00288 { 00289 GHOST_RectangleHandle rect = GHOST_GetClientBounds(win->ghostwin); 00290 ar->winrct.ymax = GHOST_GetHeightRectangle(rect); 00291 ar->winrct.xmax = GHOST_GetWidthRectangle(rect); 00292 ar->winx = ar->winrct.xmax + 1; 00293 ar->winy = ar->winrct.ymax + 1; 00294 GHOST_DisposeRectangle(rect); 00295 } 00296 00297 WM_operator_name_call(C, "VIEW3D_OT_game_start", WM_OP_EXEC_DEFAULT, NULL); 00298 00299 return 1; 00300 } 00301 else 00302 { 00303 ReportTimerInfo *rti; 00304 00305 BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found. Game auto start is not possible."); 00306 00307 /* After adding the report to the global list, reset the report timer. */ 00308 WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); 00309 00310 /* Records time since last report was added */ 00311 wm->reports.reporttimer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER, 0.02); 00312 00313 rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo"); 00314 wm->reports.reporttimer->customdata = rti; 00315 } 00316 return 0; 00317 } 00318 00319 /* free strings of open recent files */ 00320 static void free_openrecent(void) 00321 { 00322 struct RecentFile *recent; 00323 00324 for(recent = G.recent_files.first; recent; recent=recent->next) 00325 MEM_freeN(recent->filepath); 00326 00327 BLI_freelistN(&(G.recent_files)); 00328 } 00329 00330 00331 /* bad stuff*/ 00332 00333 extern wchar_t *copybuf; 00334 extern wchar_t *copybufinfo; 00335 00336 // XXX copy/paste buffer stuff... 00337 extern void free_anim_copybuf(void); 00338 extern void free_anim_drivers_copybuf(void); 00339 extern void free_fmodifiers_copybuf(void); 00340 extern void free_posebuf(void); 00341 00342 /* called in creator.c even... tsk, split this! */ 00343 void WM_exit(bContext *C) 00344 { 00345 wmWindow *win; 00346 00347 sound_exit(); 00348 00349 00350 /* first wrap up running stuff, we assume only the active WM is running */ 00351 /* modal handlers are on window level freed, others too? */ 00352 /* note; same code copied in wm_files.c */ 00353 if(C && CTX_wm_manager(C)) { 00354 00355 WM_jobs_stop_all(CTX_wm_manager(C)); 00356 00357 for(win= CTX_wm_manager(C)->windows.first; win; win= win->next) { 00358 00359 CTX_wm_window_set(C, win); /* needed by operator close callbacks */ 00360 WM_event_remove_handlers(C, &win->handlers); 00361 WM_event_remove_handlers(C, &win->modalhandlers); 00362 ED_screen_exit(C, win, win->screen); 00363 } 00364 } 00365 wm_operatortype_free(); 00366 wm_dropbox_free(); 00367 WM_menutype_free(); 00368 00369 /* all non-screen and non-space stuff editors did, like editmode */ 00370 if(C) 00371 ED_editors_exit(C); 00372 00373 // XXX 00374 // BIF_GlobalReebFree(); 00375 // BIF_freeRetarget(); 00376 BIF_freeTemplates(C); 00377 00378 free_ttfont(); /* bke_font.h */ 00379 00380 free_openrecent(); 00381 00382 BKE_freecubetable(); 00383 00384 ED_preview_free_dbase(); /* frees a Main dbase, before free_blender! */ 00385 00386 if(C && CTX_wm_manager(C)) 00387 wm_free_reports(C); /* before free_blender! - since the ListBases get freed there */ 00388 00389 seq_free_clipboard(); /* sequencer.c */ 00390 00391 free_blender(); /* blender.c, does entire library and spacetypes */ 00392 // free_matcopybuf(); 00393 free_anim_copybuf(); 00394 free_anim_drivers_copybuf(); 00395 free_fmodifiers_copybuf(); 00396 free_posebuf(); 00397 00398 BLF_exit(); 00399 00400 ANIM_keyingset_infos_exit(); 00401 00402 RE_FreeAllRender(); 00403 RE_engines_exit(); 00404 00405 // free_txt_data(); 00406 00407 00408 #ifdef WITH_PYTHON 00409 /* XXX - old note */ 00410 /* before free_blender so py's gc happens while library still exists */ 00411 /* needed at least for a rare sigsegv that can happen in pydrivers */ 00412 00413 /* Update for blender 2.5, move after free_blender because blender now holds references to PyObject's 00414 * so decref'ing them after python ends causes bad problems every time 00415 * the pyDriver bug can be fixed if it happens again we can deal with it then */ 00416 BPY_python_end(); 00417 #endif 00418 00419 GPU_global_buffer_pool_free(); 00420 GPU_free_unused_buffers(); 00421 GPU_extensions_exit(); 00422 00423 // if (copybuf) MEM_freeN(copybuf); 00424 // if (copybufinfo) MEM_freeN(copybufinfo); 00425 if (!G.background) { 00426 BKE_undo_save_quit(); // saves quit.blend if global undo is on 00427 } 00428 BKE_reset_undo(); 00429 00430 ED_file_exit(); /* for fsmenu */ 00431 00432 UI_exit(); 00433 BKE_userdef_free(); 00434 00435 RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */ 00436 00437 wm_ghost_exit(); 00438 00439 CTX_free(C); 00440 #ifdef WITH_GAMEENGINE 00441 SYS_DeleteSystem(SYS_GetSystem()); 00442 #endif 00443 00444 GHOST_DisposeSystemPaths(); 00445 00446 if(MEM_get_memory_blocks_in_use()!=0) { 00447 printf("Error: Not freed memory blocks: %d\n", MEM_get_memory_blocks_in_use()); 00448 MEM_printmemlist(); 00449 } 00450 wm_autosave_delete(); 00451 00452 printf("\nBlender quit\n"); 00453 00454 #ifdef WIN32 00455 /* ask user to press enter when in debug mode */ 00456 if(G.f & G_DEBUG) { 00457 printf("press enter key to exit...\n\n"); 00458 getchar(); 00459 } 00460 #endif 00461 exit(G.afbreek==1); 00462 } 00463