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