Merging r42533 through r42601 from trunk into soc-2011-tomato
[blender.git] / source / blender / windowmanager / intern / wm.c
index 651394d51af6cf21146bb4f18966a267a095fb82..c6c67e22bfd9d1b9b00a0a9ba42ca6f39c8dc43e 100644 (file)
@@ -1,6 +1,4 @@
-/**
- * $Id:
- *
+/*
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -15,7 +13,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 *****
  */
 
-#include "DNA_windowmanager_types.h"
+/** \file blender/windowmanager/intern/wm.c
+ *  \ingroup wm
+ */
 
-#include "MEM_guardedalloc.h"
+
+#include <string.h>
+#include <stddef.h>
+
+#include "BLO_sys_types.h"
+
+#include "DNA_windowmanager_types.h"
 
 #include "GHOST_C-api.h"
 
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
 #include "BLI_blenlib.h"
+#include "BLI_ghash.h"
 
 #include "BKE_blender.h"
 #include "BKE_context.h"
 #include "BKE_idprop.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
+#include "BKE_screen.h"
 #include "BKE_report.h"
+#include "BKE_global.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -51,7 +63,9 @@
 
 #include "ED_screen.h"
 
-#include "RNA_types.h"
+#ifdef WITH_PYTHON
+#include "BPY_extern.h"
+#endif
 
 /* ****************************************************** */
 
 
 void WM_operator_free(wmOperator *op)
 {
+
+#ifdef WITH_PYTHON
+       if(op->py_instance) {
+               /* do this first incase there are any __del__ functions or
+                * similar that use properties */
+               BPY_DECREF(op->py_instance);
+       }
+#endif
+
        if(op->ptr) {
                op->properties= op->ptr->data;
                MEM_freeN(op->ptr);
@@ -69,7 +92,7 @@ void WM_operator_free(wmOperator *op)
                MEM_freeN(op->properties);
        }
 
-       if(op->reports && (op->flag & OPERATOR_REPORT_FREE)) {
+       if(op->reports && (op->reports->flag & RPT_FREE)) {
                BKE_reports_clear(op->reports);
                MEM_freeN(op->reports);
        }
@@ -85,13 +108,18 @@ void WM_operator_free(wmOperator *op)
        MEM_freeN(op);
 }
 
+static void wm_reports_free(wmWindowManager *wm)
+{
+       BKE_reports_clear(&wm->reports);
+       WM_event_remove_timer(wm, NULL, wm->reports.reporttimer);
+}
+
 /* all operations get registered in the windowmanager here */
 /* called on event handling by event_system.c */
 void wm_operator_register(bContext *C, wmOperator *op)
 {
        wmWindowManager *wm= CTX_wm_manager(C);
        int tot;
-       char *buf;
 
        BLI_addtail(&wm->operators, op);
        tot= BLI_countlist(&wm->operators);
@@ -103,20 +131,14 @@ void wm_operator_register(bContext *C, wmOperator *op)
                tot--;
        }
        
-       
-       /* Report the string representation of the operator */
-       buf = WM_operator_pystring(C, op->type, op->ptr, 1);
-       BKE_report(CTX_wm_reports(C), RPT_OPERATOR, buf);
-       MEM_freeN(buf);
-       
        /* so the console is redrawn */
-       WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CONSOLE_REPORT, NULL);
+       WM_event_add_notifier(C, NC_SPACE|ND_SPACE_INFO_REPORT, NULL);
+       WM_event_add_notifier(C, NC_WM|ND_HISTORY, NULL);
 }
 
 
-void WM_operator_stack_clear(bContext *C)
+void WM_operator_stack_clear(wmWindowManager *wm)
 {
-       wmWindowManager *wm= CTX_wm_manager(C);
        wmOperator *op;
        
        while((op= wm->operators.first)) {
@@ -124,6 +146,60 @@ void WM_operator_stack_clear(bContext *C)
                WM_operator_free(op);
        }
        
+       WM_main_add_notifier(NC_WM|ND_HISTORY, NULL);
+}
+
+/* ****************************************** */
+
+static GHash *menutypes_hash= NULL;
+
+MenuType *WM_menutype_find(const char *idname, int quiet)
+{
+       MenuType* mt;
+
+       if (idname[0]) {
+               mt= BLI_ghash_lookup(menutypes_hash, idname);
+               if(mt)
+                       return mt;
+       }
+
+       if(!quiet)
+               printf("search for unknown menutype %s\n", idname);
+
+       return NULL;
+}
+
+int WM_menutype_add(MenuType* mt)
+{
+       BLI_ghash_insert(menutypes_hash, (void *)mt->idname, mt);
+       return 1;
+}
+
+void WM_menutype_freelink(MenuType* mt)
+{
+       BLI_ghash_remove(menutypes_hash, mt->idname, NULL, (GHashValFreeFP)MEM_freeN);
+}
+
+/* called on initialize WM_init() */
+void WM_menutype_init(void)
+{
+       menutypes_hash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "menutypes_hash gh");
+}
+
+void WM_menutype_free(void)
+{
+       GHashIterator *iter= BLI_ghashIterator_new(menutypes_hash);
+
+       for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+               MenuType *mt= BLI_ghashIterator_getValue(iter);
+               if(mt->ext.free) {
+                       mt->ext.free(mt->ext.data);
+               }
+       }
+       BLI_ghashIterator_free(iter);
+
+       BLI_ghash_free(menutypes_hash, NULL, (GHashValFreeFP)MEM_freeN);
+       menutypes_hash= NULL;
 }
 
 /* ****************************************** */
@@ -132,15 +208,34 @@ void WM_keymap_init(bContext *C)
 {
        wmWindowManager *wm= CTX_wm_manager(C);
 
-       if(wm && CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) {
-               wm_window_keymap(wm);
-               ED_spacetypes_keymap(wm);
+       /* create standard key configs */
+       if(!wm->defaultconf)
+               wm->defaultconf= WM_keyconfig_new(wm, "Blender");
+       if(!wm->addonconf)
+               wm->addonconf= WM_keyconfig_new(wm, "Blender Addon");
+       if(!wm->userconf)
+               wm->userconf= WM_keyconfig_new(wm, "Blender User");
+       
+       /* initialize only after python init is done, for keymaps that
+          use python operators */
+       if(CTX_py_init_get(C) && (wm->initialized & WM_INIT_KEYMAP) == 0) {
+               /* create default key config, only initialize once,
+                  it's persistent across sessions */
+               if(!(wm->defaultconf->flag & KEYCONF_INIT_DEFAULT)) {
+                       wm_window_keymap(wm->defaultconf);
+                       ED_spacetypes_keymap(wm->defaultconf);
+
+                       wm->defaultconf->flag |= KEYCONF_INIT_DEFAULT;
+               }
+
+               WM_keyconfig_update_tag(NULL, NULL);
+               WM_keyconfig_update(wm);
 
                wm->initialized |= WM_INIT_KEYMAP;
        }
 }
 
-void wm_check(bContext *C)
+void WM_check(bContext *C)
 {
        wmWindowManager *wm= CTX_wm_manager(C);
        
@@ -151,15 +246,21 @@ void wm_check(bContext *C)
        }
        if(wm==NULL) return;
        if(wm->windows.first==NULL) return;
-       
-       /* case: no open windows at all, for old file reads */
-       wm_window_add_ghostwindows(wm);
-       
+
+       if (!G.background) {
+               /* case: fileread */
+               if((wm->initialized & WM_INIT_WINDOW) == 0) {
+                       WM_keymap_init(C);
+                       WM_autosave_init(wm);
+               }
+
+               /* case: no open windows at all, for old file reads */
+               wm_window_add_ghostwindows(C, wm);
+       }
+
        /* case: fileread */
+       /* note: this runs in bg mode to set the screen context cb */
        if((wm->initialized & WM_INIT_WINDOW) == 0) {
-               
-               WM_keymap_init(C);
-               
                ED_screens_initialize(wm);
                wm->initialized |= WM_INIT_WINDOW;
        }
@@ -198,7 +299,7 @@ void wm_add_default(bContext *C)
        win= wm_window_new(C);
        win->screen= screen;
        screen->winid= win->winid;
-       BLI_strncpy(win->screenname, screen->id.name+2, 21);
+       BLI_strncpy(win->screenname, screen->id.name+2, sizeof(win->screenname));
        
        wm->winactive= win;
        wm->file_saved= 1;
@@ -211,14 +312,16 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
 {
        wmWindow *win;
        wmOperator *op;
-       wmKeyMap *km;
-       wmKeymapItem *kmi;
-       
+       wmKeyConfig *keyconf;
+
+       if(wm->autosavetimer)
+               wm_autosave_timer_ended(wm);
+
        while((win= wm->windows.first)) {
                BLI_remlink(&wm->windows, win);
                win->screen= NULL; /* prevent draw clear to use screen */
                wm_draw_window_clear(win);
-               wm_window_free(C, win);
+               wm_window_free(C, wm, win);
        }
        
        while((op= wm->operators.first)) {
@@ -226,22 +329,17 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
                WM_operator_free(op);
        }
 
-       while((km= wm->keymaps.first)) {
-               for(kmi=km->keymap.first; kmi; kmi=kmi->next) {
-                       if(kmi->ptr) {
-                               WM_operator_properties_free(kmi->ptr);
-                               MEM_freeN(kmi->ptr);
-                       }
-               }
-
-               BLI_freelistN(&km->keymap);
-               BLI_remlink(&wm->keymaps, km);
-               MEM_freeN(km);
+       while((keyconf=wm->keyconfigs.first)) {
+               BLI_remlink(&wm->keyconfigs, keyconf);
+               WM_keyconfig_free(keyconf);
        }
-       
+
        BLI_freelistN(&wm->queue);
        
        BLI_freelistN(&wm->paintcursors);
+       BLI_freelistN(&wm->drags);
+       
+       wm_reports_free(wm);
        
        if(C && CTX_wm_manager(C)==wm) CTX_wm_manager_set(C, NULL);
 }