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