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 <string.h> 00033 #include <stddef.h> 00034 00035 #include "BLO_sys_types.h" 00036 00037 #include "DNA_windowmanager_types.h" 00038 00039 #include "GHOST_C-api.h" 00040 00041 #include "MEM_guardedalloc.h" 00042 00043 #include "BLI_utildefines.h" 00044 #include "BLI_blenlib.h" 00045 #include "BLI_ghash.h" 00046 00047 #include "BKE_blender.h" 00048 #include "BKE_context.h" 00049 #include "BKE_idprop.h" 00050 #include "BKE_library.h" 00051 #include "BKE_main.h" 00052 #include "BKE_screen.h" 00053 #include "BKE_report.h" 00054 #include "BKE_global.h" 00055 00056 #include "WM_api.h" 00057 #include "WM_types.h" 00058 #include "wm_window.h" 00059 #include "wm_event_system.h" 00060 #include "wm_event_types.h" 00061 #include "wm_draw.h" 00062 #include "wm.h" 00063 00064 #include "ED_screen.h" 00065 00066 #ifdef WITH_PYTHON 00067 #include "BPY_extern.h" 00068 #endif 00069 00070 /* ****************************************************** */ 00071 00072 #define MAX_OP_REGISTERED 32 00073 00074 void WM_operator_free(wmOperator *op) 00075 { 00076 00077 #ifdef WITH_PYTHON 00078 if(op->py_instance) { 00079 /* do this first incase there are any __del__ functions or 00080 * similar that use properties */ 00081 BPY_DECREF(op->py_instance); 00082 } 00083 #endif 00084 00085 if(op->ptr) { 00086 op->properties= op->ptr->data; 00087 MEM_freeN(op->ptr); 00088 } 00089 00090 if(op->properties) { 00091 IDP_FreeProperty(op->properties); 00092 MEM_freeN(op->properties); 00093 } 00094 00095 if(op->reports && (op->reports->flag & RPT_FREE)) { 00096 BKE_reports_clear(op->reports); 00097 MEM_freeN(op->reports); 00098 } 00099 00100 if(op->macro.first) { 00101 wmOperator *opm, *opmnext; 00102 for(opm= op->macro.first; opm; opm= opmnext) { 00103 opmnext = opm->next; 00104 WM_operator_free(opm); 00105 } 00106 } 00107 00108 MEM_freeN(op); 00109 } 00110 00111 static void wm_reports_free(wmWindowManager *wm) 00112 { 00113 BKE_reports_clear(&wm->reports); 00114 WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); 00115 } 00116 00117 /* all operations get registered in the windowmanager here */ 00118 /* called on event handling by event_system.c */ 00119 void wm_operator_register(bContext *C, wmOperator *op) 00120 { 00121 wmWindowManager *wm= CTX_wm_manager(C); 00122 int tot; 00123 00124 BLI_addtail(&wm->operators, op); 00125 tot= BLI_countlist(&wm->operators); 00126 00127 while(tot>MAX_OP_REGISTERED) { 00128 wmOperator *opt= wm->operators.first; 00129 BLI_remlink(&wm->operators, opt); 00130 WM_operator_free(opt); 00131 tot--; 00132 } 00133 00134 /* so the console is redrawn */ 00135 WM_event_add_notifier(C, NC_SPACE|ND_SPACE_INFO_REPORT, NULL); 00136 WM_event_add_notifier(C, NC_WM|ND_HISTORY, NULL); 00137 } 00138 00139 00140 void WM_operator_stack_clear(wmWindowManager *wm) 00141 { 00142 wmOperator *op; 00143 00144 while((op= wm->operators.first)) { 00145 BLI_remlink(&wm->operators, op); 00146 WM_operator_free(op); 00147 } 00148 00149 WM_main_add_notifier(NC_WM|ND_HISTORY, NULL); 00150 } 00151 00152 /* ****************************************** */ 00153 00154 static GHash *menutypes_hash= NULL; 00155 00156 MenuType *WM_menutype_find(const char *idname, int quiet) 00157 { 00158 MenuType* mt; 00159 00160 if (idname[0]) { 00161 mt= BLI_ghash_lookup(menutypes_hash, idname); 00162 if(mt) 00163 return mt; 00164 } 00165 00166 if(!quiet) 00167 printf("search for unknown menutype %s\n", idname); 00168 00169 return NULL; 00170 } 00171 00172 int WM_menutype_add(MenuType* mt) 00173 { 00174 BLI_ghash_insert(menutypes_hash, (void *)mt->idname, mt); 00175 return 1; 00176 } 00177 00178 void WM_menutype_freelink(MenuType* mt) 00179 { 00180 BLI_ghash_remove(menutypes_hash, mt->idname, NULL, (GHashValFreeFP)MEM_freeN); 00181 } 00182 00183 /* called on initialize WM_init() */ 00184 void WM_menutype_init(void) 00185 { 00186 menutypes_hash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "menutypes_hash gh"); 00187 } 00188 00189 void WM_menutype_free(void) 00190 { 00191 GHashIterator *iter= BLI_ghashIterator_new(menutypes_hash); 00192 00193 for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) { 00194 MenuType *mt= BLI_ghashIterator_getValue(iter); 00195 if(mt->ext.free) { 00196 mt->ext.free(mt->ext.data); 00197 } 00198 } 00199 BLI_ghashIterator_free(iter); 00200 00201 BLI_ghash_free(menutypes_hash, NULL, (GHashValFreeFP)MEM_freeN); 00202 menutypes_hash= NULL; 00203 } 00204 00205 /* ****************************************** */ 00206 00207 void WM_keymap_init(bContext *C) 00208 { 00209 wmWindowManager *wm= CTX_wm_manager(C); 00210 00211 /* create standard key configs */ 00212 if(!wm->defaultconf) 00213 wm->defaultconf= WM_keyconfig_new(wm, "Blender"); 00214 if(!wm->addonconf) 00215 wm->addonconf= WM_keyconfig_new(wm, "Blender Addon"); 00216 if(!wm->userconf) 00217 wm->userconf= WM_keyconfig_new(wm, "Blender User"); 00218 00219 /* initialize only after python init is done, for keymaps that 00220 use python operators */ 00221 if(CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) { 00222 /* create default key config, only initialize once, 00223 it's persistent across sessions */ 00224 if(!(wm->defaultconf->flag & KEYCONF_INIT_DEFAULT)) { 00225 wm_window_keymap(wm->defaultconf); 00226 ED_spacetypes_keymap(wm->defaultconf); 00227 00228 wm->defaultconf->flag |= KEYCONF_INIT_DEFAULT; 00229 } 00230 00231 WM_keyconfig_update_tag(NULL, NULL); 00232 WM_keyconfig_update(wm); 00233 00234 wm->initialized |= WM_INIT_KEYMAP; 00235 } 00236 } 00237 00238 void WM_check(bContext *C) 00239 { 00240 wmWindowManager *wm= CTX_wm_manager(C); 00241 00242 /* wm context */ 00243 if(wm==NULL) { 00244 wm= CTX_data_main(C)->wm.first; 00245 CTX_wm_manager_set(C, wm); 00246 } 00247 if(wm==NULL) return; 00248 if(wm->windows.first==NULL) return; 00249 00250 if (!G.background) { 00251 /* case: fileread */ 00252 if((wm->initialized & WM_INIT_WINDOW) == 0) { 00253 WM_keymap_init(C); 00254 WM_autosave_init(wm); 00255 } 00256 00257 /* case: no open windows at all, for old file reads */ 00258 wm_window_add_ghostwindows(C, wm); 00259 } 00260 00261 /* case: fileread */ 00262 /* note: this runs in bg mode to set the screen context cb */ 00263 if((wm->initialized & WM_INIT_WINDOW) == 0) { 00264 ED_screens_initialize(wm); 00265 wm->initialized |= WM_INIT_WINDOW; 00266 } 00267 } 00268 00269 void wm_clear_default_size(bContext *C) 00270 { 00271 wmWindowManager *wm= CTX_wm_manager(C); 00272 wmWindow *win; 00273 00274 /* wm context */ 00275 if(wm==NULL) { 00276 wm= CTX_data_main(C)->wm.first; 00277 CTX_wm_manager_set(C, wm); 00278 } 00279 if(wm==NULL) return; 00280 if(wm->windows.first==NULL) return; 00281 00282 for(win= wm->windows.first; win; win= win->next) { 00283 win->sizex = 0; 00284 win->sizey = 0; 00285 win->posx = 0; 00286 win->posy = 0; 00287 } 00288 00289 } 00290 00291 /* on startup, it adds all data, for matching */ 00292 void wm_add_default(bContext *C) 00293 { 00294 wmWindowManager *wm= alloc_libblock(&CTX_data_main(C)->wm, ID_WM, "WinMan"); 00295 wmWindow *win; 00296 bScreen *screen= CTX_wm_screen(C); /* XXX from file read hrmf */ 00297 00298 CTX_wm_manager_set(C, wm); 00299 win= wm_window_new(C); 00300 win->screen= screen; 00301 screen->winid= win->winid; 00302 BLI_strncpy(win->screenname, screen->id.name+2, sizeof(win->screenname)); 00303 00304 wm->winactive= win; 00305 wm->file_saved= 1; 00306 wm_window_make_drawable(C, win); 00307 } 00308 00309 00310 /* context is allowed to be NULL, do not free wm itself (library.c) */ 00311 void wm_close_and_free(bContext *C, wmWindowManager *wm) 00312 { 00313 wmWindow *win; 00314 wmOperator *op; 00315 wmKeyConfig *keyconf; 00316 00317 if(wm->autosavetimer) 00318 wm_autosave_timer_ended(wm); 00319 00320 while((win= wm->windows.first)) { 00321 BLI_remlink(&wm->windows, win); 00322 win->screen= NULL; /* prevent draw clear to use screen */ 00323 wm_draw_window_clear(win); 00324 wm_window_free(C, wm, win); 00325 } 00326 00327 while((op= wm->operators.first)) { 00328 BLI_remlink(&wm->operators, op); 00329 WM_operator_free(op); 00330 } 00331 00332 while((keyconf=wm->keyconfigs.first)) { 00333 BLI_remlink(&wm->keyconfigs, keyconf); 00334 WM_keyconfig_free(keyconf); 00335 } 00336 00337 BLI_freelistN(&wm->queue); 00338 00339 BLI_freelistN(&wm->paintcursors); 00340 BLI_freelistN(&wm->drags); 00341 00342 wm_reports_free(wm); 00343 00344 if(C && CTX_wm_manager(C)==wm) CTX_wm_manager_set(C, NULL); 00345 } 00346 00347 void wm_close_and_free_all(bContext *C, ListBase *wmlist) 00348 { 00349 wmWindowManager *wm; 00350 00351 while((wm=wmlist->first)) { 00352 wm_close_and_free(C, wm); 00353 BLI_remlink(wmlist, wm); 00354 MEM_freeN(wm); 00355 } 00356 } 00357 00358 void WM_main(bContext *C) 00359 { 00360 while(1) { 00361 00362 /* get events from ghost, handle window events, add to window queues */ 00363 wm_window_process_events(C); 00364 00365 /* per window, all events to the window, screen, area and region handlers */ 00366 wm_event_do_handlers(C); 00367 00368 /* events have left notes about changes, we handle and cache it */ 00369 wm_event_do_notifiers(C); 00370 00371 /* execute cached changes draw */ 00372 wm_draw_update(C); 00373 } 00374 } 00375 00376