=== PyNodes ===
[blender-staging.git] / source / blender / python / BPY_interface.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney,
29  * Chris Keith, Chris Want, Ken Hughes
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32 */
33
34 #include <Python.h>
35
36 #include "compile.h"            /* for the PyCodeObject */
37 #include "eval.h"               /* for PyEval_EvalCode */
38 #include "BLI_blenlib.h"        /* for BLI_last_slash() */
39 #include "BIF_interface.h"      /* for pupmenu() */
40 #include "BIF_space.h"
41 #include "BIF_screen.h"
42 #include "BIF_toolbox.h"
43 #include "BKE_action.h"         /* for get_pose_channel() */
44 #include "BKE_library.h"
45 #include "BKE_object.h"         /* during_scriptlink() */
46 #include "BKE_text.h"
47 #include "BKE_constraint.h" /* for bConstraintOb */
48 #include "BKE_idprop.h"
49
50 #include "DNA_curve_types.h" /* for struct IpoDriver */
51 #include "DNA_ID.h" /* ipo driver */
52 #include "DNA_object_types.h" /* ipo driver */
53 #include "DNA_constraint_types.h" /* for pyconstraint */
54
55 #include "DNA_screen_types.h"
56 #include "DNA_userdef_types.h"  /* for U.pythondir */
57 #include "MEM_guardedalloc.h"
58 #include "BPY_extern.h"
59 #include "BPY_menus.h"
60 #include "BPI_script.h"
61 #include "BKE_global.h"
62 #include "BKE_main.h"
63 #include "BKE_armature.h"
64 #include "api2_2x/EXPP_interface.h"
65 #include "api2_2x/constant.h"
66 #include "api2_2x/gen_utils.h"
67 #include "api2_2x/gen_library.h" /* GetPyObjectFromID */
68 #include "api2_2x/BGL.h" 
69 #include "api2_2x/Blender.h"
70 #include "api2_2x/Camera.h"
71 #include "api2_2x/Draw.h"
72 #include "api2_2x/Object.h"
73 #include "api2_2x/Registry.h"
74 #include "api2_2x/Pose.h"
75 #include "api2_2x/bpy.h" /* for the new "bpy" module */
76
77 /*these next two are for pyconstraints*/
78 #include "api2_2x/IDProp.h"
79 #include "api2_2x/matrix.h"
80
81 /* for scriptlinks */
82 #include "DNA_lamp_types.h"
83 #include "DNA_camera_types.h"
84 #include "DNA_world_types.h"
85 #include "DNA_scene_types.h"
86 #include "DNA_material_types.h"
87
88 /* bpy_registryDict is declared in api2_2x/Registry.h and defined
89  * in api2_2x/Registry.c
90  * This Python dictionary will be used to store data that scripts
91  * choose to preserve after they are executed, so user changes can be
92  * restored next time the script is used.  Check the Blender.Registry module. 
93  */
94 /*#include "api2_2x/Registry.h" */
95
96 /* for pydrivers (ipo drivers defined by one-line Python expressions) */
97 PyObject *bpy_pydriver_Dict = NULL;
98 PyObject *bpy_orig_syspath_List = NULL;
99
100 /*
101  * set up a weakref list for Armatures
102  *    creates list in __main__ module dict 
103  */
104   
105 int setup_armature_weakrefs()
106 {
107         PyObject *maindict;
108         PyObject *main_module;
109         char *list_name = ARM_WEAKREF_LIST_NAME;
110
111         main_module = PyImport_AddModule( "__main__");
112         if(main_module){
113                 PyObject *weakreflink;
114                 maindict= PyModule_GetDict(main_module);
115
116                 /* check if there is already a dict entry for the armature weakrefs,
117                  * and delete if so before making another one */
118
119                 weakreflink= PyDict_GetItemString(maindict,list_name);
120                 if( weakreflink != NULL ) {
121                         PyDict_DelItemString(maindict,list_name);
122                         Py_XDECREF( weakreflink );
123                 }
124
125                 if (PyDict_SetItemString(maindict, 
126                                                                  list_name, 
127                                                                  PyList_New(0)) == -1){
128                         printf("Oops - setup_armature_weakrefs()\n");
129                         
130                         return 0;
131                 }
132         }
133         return 1;
134 }
135
136 /* Declares the modules and their initialization functions
137  * These are TOP-LEVEL modules e.g. import `module` - there is no
138  * support for packages here e.g. import `package.module` */
139
140 static struct _inittab BPy_Inittab_Modules[] = {
141         {"Blender", M_Blender_Init},
142         {"bpy", m_bpy_init},
143         {NULL, NULL}
144 };
145
146 /*************************************************************************
147 * Structure definitions 
148 **************************************************************************/
149 #define FILENAME_LENGTH 24
150
151 typedef struct _ScriptError {
152         char filename[FILENAME_LENGTH];
153         int lineno;
154 } ScriptError;
155
156 /****************************************************************************
157 * Global variables 
158 ****************************************************************************/
159 ScriptError g_script_error;
160
161 /***************************************************************************
162 * Function prototypes 
163 ***************************************************************************/
164 PyObject *RunPython( Text * text, PyObject * globaldict );
165 char *GetName( Text * text );
166 PyObject *CreateGlobalDictionary( void );
167 void ReleaseGlobalDictionary( PyObject * dict );
168 void DoAllScriptsFromList( ListBase * list, short event );
169 PyObject *importText( char *name );
170 void init_ourImport( void );
171 void init_ourReload( void );
172 PyObject *blender_import( PyObject * self, PyObject * args );
173 PyObject *RunPython2( Text * text, PyObject * globaldict, PyObject *localdict );
174
175
176 void BPY_Err_Handle( char *script_name );
177 PyObject *traceback_getFilename( PyObject * tb );
178
179 /****************************************************************************
180 * Description: This function will start the interpreter and load all modules
181 * as well as search for a python installation.
182 ****************************************************************************/
183 void BPY_start_python( int argc, char **argv )
184 {
185         PyThreadState *py_tstate = NULL;
186         static int argc_copy = 0;
187         static char **argv_copy = NULL;
188         int first_time = argc;
189
190         /* we keep a copy of the values of argc and argv so that the game engine
191          * can call BPY_start_python(0, NULL) whenever a game ends, without having
192          * to know argc and argv there (in source/blender/src/space.c) */
193         if( first_time ) {
194                 argc_copy = argc;
195                 argv_copy = argv;
196         }
197
198         //stuff for Registry module
199         bpy_registryDict = PyDict_New(  );/* check comment at start of this file */
200         if( !bpy_registryDict )
201                 printf( "Error: Couldn't create the Registry Python Dictionary!" );
202         Py_SetProgramName( "blender" );
203
204         /* Py_Initialize() will attempt to import the site module and
205          * print an error if not found.  See init_syspath() for the
206          * rest of our init msgs.
207          */
208
209         /* print Python version
210          * Py_GetVersion() returns a ptr to a static string "9.9.9 (aaaa..." 
211          */
212         {
213                 int count = 3;  /* a nice default for major.minor.  example 2.5 */
214                 const char *version = Py_GetVersion();
215                 /* we know a blank is there somewhere! */
216                 char *blank_ptr = strchr( version, ' '); 
217                 if(blank_ptr)
218                         count = blank_ptr - version;
219                 
220                 printf( "Compiled with Python version %.*s.\n", count, version );
221         }
222
223
224         //Initialize the TOP-LEVEL modules
225         PyImport_ExtendInittab(BPy_Inittab_Modules);
226         
227         //Start the interpreter
228         Py_Initialize(  );
229         PySys_SetArgv( argc_copy, argv_copy );
230
231         /* Initialize thread support (also acquires lock) */
232         PyEval_InitThreads();
233
234         //Overrides __import__
235         init_ourImport(  );
236         init_ourReload(  );
237
238         //init a global dictionary
239         g_blenderdict = NULL;
240
241         //Look for a python installation
242         init_syspath( first_time ); /* not first_time: some msgs are suppressed */
243
244         //PyEval_ReleaseLock();
245         py_tstate = PyGILState_GetThisThreadState();
246         PyEval_ReleaseThread(py_tstate);
247
248         return;
249 }
250
251 /*****************************************************************************/
252 /* Description: This function will terminate the Python interpreter          */
253 /*****************************************************************************/
254 void BPY_end_python( void )
255 {
256         Script *script = NULL;
257
258         PyGILState_Ensure(); /* finalizing, no need to grab the state */
259
260         if( bpy_registryDict ) {
261                 Py_DECREF( bpy_registryDict );
262                 bpy_registryDict = NULL;
263         }
264
265         if( bpy_pydriver_Dict ) {
266                 Py_DECREF( bpy_pydriver_Dict );
267                 bpy_pydriver_Dict = NULL;
268         }
269         
270         if( bpy_orig_syspath_List ) {
271                 Py_DECREF( bpy_orig_syspath_List );
272                 bpy_orig_syspath_List = NULL;
273         }
274
275         /* Freeing all scripts here prevents problems with the order in which
276          * Python is finalized and G.main is freed in exit_usiblender() */
277         for (script = G.main->script.first; script; script = script->id.next) {
278                 BPY_clear_script(script);
279                 free_libblock( &G.main->script, script );
280         }
281
282         Py_Finalize(  );
283
284         BPyMenu_RemoveAllEntries(  );   /* freeing bpymenu mem */
285
286         /* a script might've opened a .blend file but didn't close it, so: */
287         EXPP_Library_Close(  );
288
289         return;
290 }
291
292 void syspath_append( char *dirname )
293 {
294         PyObject *mod_sys= NULL, *dict= NULL, *path= NULL, *dir= NULL;
295         short ok=1;
296         PyErr_Clear(  );
297
298         dir = Py_BuildValue( "s", dirname );
299
300         mod_sys = PyImport_ImportModule( "sys" );       /* new ref */
301         
302         if (mod_sys) {
303                 dict = PyModule_GetDict( mod_sys );     /* borrowed ref */
304                 path = PyDict_GetItemString( dict, "path" );    /* borrowed ref */
305                 if ( !PyList_Check( path ) ) {
306                         ok = 0;
307                 }
308         } else {
309                 /* cant get the sys module */
310                 ok = 0;
311         }
312         
313         if (PySequence_Contains(path, dir)==0) { /* Only add if we need to */
314                 if (ok && PyList_Append( path, dir ) != 0)
315                         ok = 0; /* append failed */
316         
317                 if( (ok==0) || PyErr_Occurred(  ) )
318                         Py_FatalError( "could import or build sys.path, can't continue" );
319         }
320         Py_XDECREF( mod_sys );
321 }
322
323 void init_syspath( int first_time )
324 {
325         PyObject *path;
326         PyObject *mod, *d;
327         char *progname;
328         char execdir[FILE_MAXDIR];      /*defines from DNA_space_types.h */
329
330         int n;
331         
332         
333         path = Py_BuildValue( "s", bprogname );
334
335         mod = PyImport_ImportModule( "Blender.sys" );
336
337         if( mod ) {
338                 d = PyModule_GetDict( mod );
339                 EXPP_dict_set_item_str( d, "progname", path );
340                 Py_DECREF( mod );
341         } else
342                 printf( "Warning: could not set Blender.sys.progname\n" );
343
344         progname = BLI_last_slash( bprogname ); /* looks for the last dir separator */
345
346         n = progname - bprogname;
347         if( n > 0 ) {
348                 strncpy( execdir, bprogname, n );
349                 if( execdir[n - 1] == '.' )
350                         n--;    /*fix for when run as ./blender */
351                 execdir[n] = '\0';
352
353                 syspath_append( execdir );      /* append to module search path */
354         } else {
355                 printf( "Warning: could not determine argv[0] path\n" );
356         }
357         
358         /* 
359            attempt to import 'site' module as a check for valid
360            python install found.
361         */
362
363         printf("Checking for installed Python... "); /* appears after msg "Compiled with Python 2.x"  */
364         mod = PyImport_ImportModule( "site" );  /* new ref */
365
366         if( mod ) {
367                 printf("got it!\n");  
368                 Py_DECREF( mod );
369         } else {                /* import 'site' failed */
370                 PyErr_Clear(  );
371                 if( first_time ) {
372                         printf( "No installed Python found.\n" );
373                         printf( "Only built-in modules are available.  Some scripts may not run.\n" );
374                         printf( "Continuing happily.\n" );
375                 }
376         }
377
378
379         /* 
380          * initialize the sys module
381          * set sys.executable to the Blender exe 
382          */
383
384         mod = PyImport_ImportModule( "sys" );   /* new ref */
385
386         if( mod ) {
387                 d = PyModule_GetDict( mod );    /* borrowed ref */
388                 EXPP_dict_set_item_str( d, "executable", Py_BuildValue( "s", bprogname ) );
389                 
390                 if (bpy_orig_syspath_List == NULL) {
391                         /* backup the original sys.path to rebuild later */     
392                         PyObject *syspath = PyDict_GetItemString( d, "path" );  /* borrowed ref */
393                         if (bpy_orig_syspath_List) { /* This should never happen but just incase, be nice */
394                                 Py_DECREF(bpy_orig_syspath_List);
395                         }
396                         bpy_orig_syspath_List = PyList_GetSlice(syspath, 0, PyList_Size(syspath));
397                 }
398                 
399                 Py_DECREF( mod );
400         } else{
401                 printf("import of sys module failed\n");
402         }
403 }
404
405 void BPY_rebuild_syspath( void )
406 {
407         PyObject *mod, *dict, *syspath;
408         char dirpath[FILE_MAX];
409         char *sdir = NULL;
410         
411         mod = PyImport_ImportModule( "sys" );   
412         if (!mod) {
413                 printf("error: could not import python sys module. some modules may not import.\n");
414                 return;
415         }
416         
417         if (!bpy_orig_syspath_List) { /* should never happen */
418                 printf("error refershing python path\n");
419                 Py_DECREF(mod);
420                 return;
421         }
422         
423         dict = PyModule_GetDict( mod ); /* borrowed ref */
424         
425         /* Reset sys.path */    
426         syspath = PyDict_GetItemString( dict, "path" ); /* borrowed ref */
427         PyList_SetSlice(syspath, 0, PyList_Size(syspath), bpy_orig_syspath_List);
428         
429         if(U.pythondir[0] != '\0' ) {
430                 char modpath[FILE_MAX];
431                 int upyslen = strlen(U.pythondir);
432
433                 /* check if user pydir ends with a slash and, if so, remove the slash
434                  * (for eventual implementations of c library's stat function that might
435                  * not like it) */
436                 if (upyslen > 2) { /* avoids doing anything if dir == '//' */
437                         BLI_add_slash(U.pythondir);
438                 }
439
440                 BLI_strncpy(dirpath, U.pythondir, FILE_MAX);
441                 BLI_convertstringcode(dirpath, G.sce, 0);
442                 syspath_append(dirpath);        /* append to module search path */
443
444                 BLI_make_file_string("/", modpath, dirpath, "bpymodules");
445                 if (BLI_exists(modpath)) syspath_append(modpath);
446         }
447         
448         sdir = bpy_gethome(1);
449         if (sdir) {
450                 syspath_append(sdir);
451                 BLI_make_file_string("/", dirpath, sdir, "bpymodules");
452                 if (BLI_exists(dirpath)) syspath_append(dirpath);
453         }
454         
455         Py_DECREF(mod);
456
457 }
458
459 /****************************************************************************
460 * Description: This function finishes Python initialization in Blender.  
461
462 Because U.pythondir (user defined dir for scripts) isn't         
463 initialized when BPY_start_Python needs to be executed, we       
464 postpone adding U.pythondir to sys.path and also BPyMenus         
465 (mechanism to register scripts in Blender menus) for when  
466 that dir info is available.   
467 ****************************************************************************/
468 void BPY_post_start_python( void )
469 {
470         PyGILState_STATE gilstate = PyGILState_Ensure();
471
472         BPY_rebuild_syspath();
473         BPyMenu_Init( 0 );      /* get dynamic menus (registered scripts) data */
474
475         PyGILState_Release(gilstate);
476 }
477
478 /****************************************************************************
479 * Description: This function will return the linenumber on which an error  
480 *               has occurred in the Python script.                      
481 ****************************************************************************/
482 int BPY_Err_getLinenumber( void )
483 {
484         return g_script_error.lineno;
485 }
486
487 /*****************************************************************************/
488 /* Description: This function will return the filename of the python script. */
489 /*****************************************************************************/
490 const char *BPY_Err_getFilename( void )
491 {
492         return g_script_error.filename;
493 }
494
495 /*****************************************************************************/
496 /* Description: Return PyString filename from a traceback object            */
497 /*****************************************************************************/
498 PyObject *traceback_getFilename( PyObject * tb )
499 {
500         PyObject *v = NULL;
501
502 /* co_filename is in f_code, which is in tb_frame, which is in tb */
503
504         v = PyObject_GetAttrString( tb, "tb_frame" );
505         if (v) {
506                 Py_DECREF( v );
507                 v = PyObject_GetAttrString( v, "f_code" );
508                 if (v) {
509                         Py_DECREF( v );
510                         v = PyObject_GetAttrString( v, "co_filename" );
511                 }
512         }
513
514         if (v) return v;
515         else return PyString_FromString("unknown");
516 }
517
518 /****************************************************************************
519 * Description: Blender Python error handler. This catches the error and 
520 * stores filename and line number in a global  
521 *****************************************************************************/
522 void BPY_Err_Handle( char *script_name )
523 {
524         PyObject *exception, *err, *tb, *v;
525
526         if( !script_name ) {
527                 printf( "Error: script has NULL name\n" );
528                 return;
529         }
530
531         PyErr_Fetch( &exception, &err, &tb );
532
533         if (!script_name) script_name = "untitled";
534         //if( !exception && !tb ) {
535         //      printf( "FATAL: spurious exception\n" );
536         //      return;
537         //}
538
539         strcpy( g_script_error.filename, script_name );
540
541         if( exception
542             && PyErr_GivenExceptionMatches( exception, PyExc_SyntaxError ) ) {
543                 /* no traceback available when SyntaxError */
544                 PyErr_Restore( exception, err, tb );    /* takes away reference! */
545                 PyErr_Print(  );
546                 v = PyObject_GetAttrString( err, "lineno" );
547                 if( v ) {
548                         g_script_error.lineno = PyInt_AsLong( v );
549                         Py_DECREF( v );
550                 } else {
551                         g_script_error.lineno = -1;
552                 }
553                 /* this avoids an abort in Python 2.3's garbage collecting: */
554                 PyErr_Clear(  );
555                 return;
556         } else {
557                 PyErr_NormalizeException( &exception, &err, &tb );
558                 PyErr_Restore( exception, err, tb );    /* takes away reference! */
559                 PyErr_Print(  );
560                 tb = PySys_GetObject( "last_traceback" );
561
562                 if( !tb ) {
563                         printf( "\nCan't get traceback\n" );
564                         return;
565                 }
566
567                 Py_INCREF( tb );
568
569 /* From old bpython BPY_main.c:
570  * 'check traceback objects and look for last traceback in the
571  *      same text file. This is used to jump to the line of where the
572  *      error occured. "If the error occured in another text file or module,
573  *      the last frame in the current file is adressed."' 
574  */
575
576                 for(;;) {
577                         v = PyObject_GetAttrString( tb, "tb_next" );
578
579                         if( !v || v == Py_None ||
580                                 strcmp(PyString_AsString(traceback_getFilename(v)), script_name)) {
581                                 break;
582                         }
583
584                         Py_DECREF( tb );
585                         tb = v;
586                 }
587
588                 v = PyObject_GetAttrString( tb, "tb_lineno" );
589                 if (v) {
590                         g_script_error.lineno = PyInt_AsLong(v);
591                         Py_DECREF(v);
592                 }
593                 v = traceback_getFilename( tb );
594                 if (v) {
595                         strncpy( g_script_error.filename, PyString_AsString( v ),
596                                 FILENAME_LENGTH );
597                         Py_DECREF(v);
598                 }
599                 Py_DECREF( tb );
600         }
601
602         return;
603 }
604
605 /****************************************************************************
606 * Description: This function executes the script passed by st.          
607 * Notes:        It is called by blender/src/drawtext.c when a Blender user  
608 *               presses ALT+PKEY in the script's text window. 
609 *****************************************************************************/
610 int BPY_txt_do_python_Text( struct Text *text )
611 {
612         PyObject *py_dict, *py_result;
613         BPy_constant *info;
614         char textname[24];
615         Script *script = G.main->script.first;
616         PyGILState_STATE gilstate;
617
618         if( !text )
619                 return 0;
620
621         /* check if this text is already running */
622         while( script ) {
623                 if( !strcmp( script->id.name + 2, text->id.name + 2 ) ) {
624                         /* if this text is already a running script, 
625                          * just move to it: */
626                         SpaceScript *sc;
627                         newspace( curarea, SPACE_SCRIPT );
628                         sc = curarea->spacedata.first;
629                         sc->script = script;
630                         return 1;
631                 }
632                 script = script->id.next;
633         }
634
635         /* Create a new script structure and initialize it: */
636         script = alloc_libblock( &G.main->script, ID_SCRIPT, GetName( text ) );
637
638         if( !script ) {
639                 printf( "couldn't allocate memory for Script struct!" );
640                 return 0;
641         }
642
643         /* if in the script Blender.Load(blendfile) is not the last command,
644          * an error after it will call BPY_Err_Handle below, but the text struct
645          * will have been deallocated already, so we need to copy its name here.
646          */
647         BLI_strncpy( textname, GetName( text ),
648                      strlen( GetName( text ) ) + 1 );
649
650         script->id.us = 1;
651         script->flags = SCRIPT_RUNNING;
652         script->py_draw = NULL;
653         script->py_event = NULL;
654         script->py_button = NULL;
655         script->py_browsercallback = NULL;
656
657         gilstate = PyGILState_Ensure();
658
659         py_dict = CreateGlobalDictionary(  );
660
661         if( !setup_armature_weakrefs()){
662                 printf("Oops - weakref dict\n");
663                 PyGILState_Release(gilstate);
664                 return 0;
665         }
666
667         script->py_globaldict = py_dict;
668
669         info = ( BPy_constant * ) PyConstant_New(  );
670         if( info ) {
671                 PyConstant_Insert( info, "name",
672                                  PyString_FromString( script->id.name + 2 ) );
673                 Py_INCREF( Py_None );
674                 PyConstant_Insert( info, "arg", Py_None );
675                 EXPP_dict_set_item_str( py_dict, "__script__",
676                                       ( PyObject * ) info );
677         }
678
679         py_result = RunPython( text, py_dict ); /* Run the script */
680
681         if( !py_result ) {      /* Failed execution of the script */
682
683                 BPY_Err_Handle( textname );
684                 ReleaseGlobalDictionary( py_dict );
685                 script->py_globaldict = NULL;
686                 if( G.main->script.first )
687                         free_libblock( &G.main->script, script );
688                 PyGILState_Release(gilstate);
689                 return 0;
690         } else {
691                 Py_DECREF( py_result );
692                 script->flags &= ~SCRIPT_RUNNING;
693                 if( !script->flags ) {
694                         ReleaseGlobalDictionary( py_dict );
695                         script->py_globaldict = NULL;
696                         free_libblock( &G.main->script, script );
697                 }
698         }
699
700         PyGILState_Release(gilstate);
701
702         return 1;               /* normal return */
703 }
704
705 /****************************************************************************
706 * Description: Called from command line to run a Python script
707 * automatically. The script can be a file or a Blender Text in the current 
708 * .blend.
709 ****************************************************************************/
710 void BPY_run_python_script( char *fn )
711 {
712         Text *text = NULL;
713         int is_blender_text = 0;
714
715         if (!BLI_exists(fn)) {  /* if there's no such filename ... */
716                 text = G.main->text.first;      /* try an already existing Blender Text */
717
718                 while (text) {
719                         if (!strcmp(fn, text->id.name + 2)) break;
720                         text = text->id.next;
721                 }
722
723                 if (text == NULL) {
724                         printf("\nError: no such file or Blender text -- %s.\n", fn);
725                         return;
726                 }
727                 else is_blender_text = 1;       /* fn is already a Blender Text */
728         }
729
730         else {
731                 text = add_text(fn);
732
733                 if (text == NULL) {
734                         printf("\nError in BPY_run_python_script:\n"
735                                 "couldn't create Blender text from %s\n", fn);
736                 /* Chris: On Windows if I continue I just get a segmentation
737                  * violation.  To get a baseline file I exit here. */
738                 exit(2);
739                 /* return; */
740                 }
741         }
742
743         if (BPY_txt_do_python_Text(text) != 1) {
744                 printf("\nError executing Python script from command-line:\n"
745                         "%s (at line %d).\n", fn, BPY_Err_getLinenumber());
746         }
747
748         if (!is_blender_text) {
749                 /* We can't simply free the text, since the script might have called
750                  * Blender.Load() to load a new .blend, freeing previous data.
751                  * So we check if the pointer is still valid. */
752                 Text *txtptr = G.main->text.first;
753                 while (txtptr) {
754                         if (txtptr == text) {
755                                 free_libblock(&G.main->text, text);
756                                 break;
757                         }
758                         txtptr = txtptr->id.next;
759                 }
760         }
761 }
762
763 /****************************************************************************
764 * Description: This function executes the script chosen from a menu.
765 * Notes:        It is called by the ui code in src/header_???.c when a user  
766 *               clicks on a menu entry that refers to a script.
767 *               Scripts are searched in the BPyMenuTable, using the given
768 *               menutype and event values to know which one was chosen. 
769 *****************************************************************************/
770 int BPY_menu_do_python( short menutype, int event )
771 {
772         PyObject *py_dict, *py_res, *pyarg = NULL;
773         BPy_constant *info;
774         BPyMenu *pym;
775         BPySubMenu *pysm;
776         FILE *fp = NULL;
777         char *buffer, *s;
778         char filestr[FILE_MAXDIR + FILE_MAXFILE];
779         char scriptname[21];
780         Script *script = NULL;
781         int len;
782         PyGILState_STATE gilstate;
783
784         pym = BPyMenu_GetEntry( menutype, ( short ) event );
785
786         if( !pym )
787                 return 0;
788
789         gilstate = PyGILState_Ensure();
790
791         if( pym->version > G.version )
792                 notice( "Version mismatch: script was written for Blender %d. "
793                         "It may fail with yours: %d.", pym->version,
794                         G.version );
795
796 /* if there are submenus, let the user choose one from a pupmenu that we
797  * create here.*/
798         pysm = pym->submenus;
799         if( pysm ) {
800                 char *pupstr;
801                 int arg;
802
803                 pupstr = BPyMenu_CreatePupmenuStr( pym, menutype );
804
805                 if( pupstr ) {
806                         arg = pupmenu( pupstr );
807                         MEM_freeN( pupstr );
808
809                         if( arg >= 0 ) {
810                                 while( arg-- )
811                                         pysm = pysm->next;
812                                 pyarg = PyString_FromString( pysm->arg );
813                         } else {
814                                 PyGILState_Release(gilstate);
815                                 return 0;
816                         }
817                 }
818         }
819
820         if( !pyarg ) { /* no submenus */
821                 Py_INCREF( Py_None );
822                 pyarg = Py_None;
823         }
824
825         if( pym->dir ) { /* script is in U.pythondir */
826                 char upythondir[FILE_MAXDIR];
827
828                 /* dirs in Blender can be "//", which has a special meaning */
829                 BLI_strncpy(upythondir, U.pythondir, FILE_MAXDIR);
830                 BLI_convertstringcode(upythondir, G.sce, 0); /* if so, this expands it */
831                 BLI_make_file_string( "/", filestr, upythondir, pym->filename );
832         }
833         else { /* script is in default scripts dir */
834                 char *scriptsdir = bpy_gethome(1);
835
836                 if (!scriptsdir) {
837                         printf("Error loading script: can't find default scripts dir!");
838                         PyGILState_Release(gilstate);
839                         return 0;
840                 }
841
842                 BLI_make_file_string( "/", filestr, scriptsdir, pym->filename );
843         }
844
845         fp = fopen( filestr, "rb" );
846         if( !fp ) {
847                 printf( "Error loading script: couldn't open file %s\n",
848                         filestr );
849                 PyGILState_Release(gilstate);
850                 return 0;
851         }
852
853         BLI_strncpy(scriptname, pym->name, 21);
854         len = strlen(scriptname) - 1;
855         /* by convention, scripts that open the file browser or have submenus
856          * display '...'.  Here we remove them from the datablock name */
857         while ((len > 0) && scriptname[len] == '.') {
858                 scriptname[len] = '\0';
859                 len--;
860         }
861         
862         /* Create a new script structure and initialize it: */
863         script = alloc_libblock( &G.main->script, ID_SCRIPT, scriptname );
864
865         if( !script ) {
866                 printf( "couldn't allocate memory for Script struct!" );
867                 fclose( fp );
868                 PyGILState_Release(gilstate);
869                 return 0;
870         }
871
872         /* let's find a proper area for an eventual script gui:
873          * (still experimenting here, need definition on which win
874          * each group will be put to code this properly) */
875         switch ( menutype ) {
876
877         case PYMENU_IMPORT:     /* first 4 were handled in header_info.c */
878         case PYMENU_EXPORT:
879         case PYMENU_HELP:
880         case PYMENU_RENDER:
881         case PYMENU_WIZARDS:
882         case PYMENU_SCRIPTTEMPLATE:
883         case PYMENU_MESHFACEKEY:
884                 break;
885
886         default:
887                 if( curarea->spacetype != SPACE_SCRIPT ) {
888                         ScrArea *sa = NULL;
889
890                         sa = find_biggest_area_of_type( SPACE_BUTS );
891                         if( sa ) {
892                                 if( ( 1.5 * sa->winx ) < sa->winy )
893                                         sa = NULL;      /* too narrow? */
894                         }
895
896                         if( !sa )
897                                 sa = find_biggest_area_of_type( SPACE_SCRIPT );
898                         if( !sa )
899                                 sa = find_biggest_area_of_type( SPACE_TEXT );
900                         if( !sa )
901                                 sa = find_biggest_area_of_type( SPACE_IMAGE );  /* group UV */
902                         if( !sa )
903                                 sa = find_biggest_area_of_type( SPACE_VIEW3D );
904
905                         if( !sa )
906                                 sa = find_biggest_area(  );
907
908                         areawinset( sa->win );
909                 }
910                 break;
911         }
912
913         script->id.us = 1;
914         script->flags = SCRIPT_RUNNING;
915         script->py_draw = NULL;
916         script->py_event = NULL;
917         script->py_button = NULL;
918         script->py_browsercallback = NULL;
919
920         py_dict = CreateGlobalDictionary(  );
921
922         script->py_globaldict = py_dict;
923
924         info = ( BPy_constant * ) PyConstant_New(  );
925         if( info ) {
926                 PyConstant_Insert( info, "name",
927                                  PyString_FromString( script->id.name + 2 ) );
928                 PyConstant_Insert( info, "arg", pyarg );
929                 EXPP_dict_set_item_str( py_dict, "__script__",
930                                       ( PyObject * ) info );
931         }
932
933         /* Previously we used PyRun_File to run directly the code on a FILE 
934          * object, but as written in the Python/C API Ref Manual, chapter 2,
935          * 'FILE structs for different C libraries can be different and 
936          * incompatible'.
937          * So now we load the script file data to a buffer */
938
939         fseek( fp, 0L, SEEK_END );
940         len = ftell( fp );
941         fseek( fp, 0L, SEEK_SET );
942
943         buffer = MEM_mallocN( len + 2, "pyfilebuf" );   /* len+2 to add '\n\0' */
944         len = fread( buffer, 1, len, fp );
945
946         buffer[len] = '\n';     /* fix syntax error in files w/o eol */
947         buffer[len + 1] = '\0';
948
949         /* fast clean-up of dos cr/lf line endings: change '\r' to space */
950
951         /* we also have to check for line splitters: '\\' */
952         /* to avoid possible syntax errors on dos files on win */
953          /**/
954                 /* but first make sure we won't disturb memory below &buffer[0]: */
955                 if( *buffer == '\r' )
956                 *buffer = ' ';
957
958         /* now handle the whole buffer */
959         for( s = buffer + 1; *s != '\0'; s++ ) {
960                 if( *s == '\r' ) {
961                         if( *( s - 1 ) == '\\' ) {      /* special case: long lines split with '\': */
962                                 *( s - 1 ) = ' ';       /* we write ' \', because '\ ' is a syntax error */
963                                 *s = '\\';
964                         } else
965                                 *s = ' ';       /* not a split line, just replace '\r' with ' ' */
966                 }
967         }
968
969         fclose( fp );
970
971
972         if( !setup_armature_weakrefs()){
973                 printf("Oops - weakref dict\n");
974                 MEM_freeN( buffer );
975                 PyGILState_Release(gilstate);
976                 return 0;
977         }
978
979         /* run the string buffer */
980
981         py_res = PyRun_String( buffer, Py_file_input, py_dict, py_dict );
982
983         MEM_freeN( buffer );
984
985         if( !py_res ) {         /* Failed execution of the script */
986
987                 BPY_Err_Handle( script->id.name + 2 );
988                 ReleaseGlobalDictionary( py_dict );
989                 script->py_globaldict = NULL;
990                 if( G.main->script.first )
991                         free_libblock( &G.main->script, script );
992                 error( "Python script error: check console" );
993
994                 PyGILState_Release(gilstate);
995                 return 0;
996         } else {
997                 Py_DECREF( py_res );
998                 script->flags &= ~SCRIPT_RUNNING;
999
1000                 if( !script->flags ) {
1001                         ReleaseGlobalDictionary( py_dict );
1002                         script->py_globaldict = NULL;
1003                         free_libblock( &G.main->script, script );
1004
1005                         /* special case: called from the menu in the Scripts window
1006                          * we have to change sc->script pointer, since it'll be freed here.*/
1007                         if( curarea->spacetype == SPACE_SCRIPT ) {
1008                                 SpaceScript *sc = curarea->spacedata.first;
1009                                 sc->script = G.main->script.first;      /* can be null, which is ok ... */
1010                                 /* ... meaning no other script is running right now. */
1011                         }
1012
1013                 }
1014         }
1015
1016         PyGILState_Release(gilstate);
1017
1018         return 1;               /* normal return */
1019 }
1020
1021 /*****************************************************************************
1022 * Description:  
1023 * Notes:
1024 *****************************************************************************/
1025 void BPY_free_compiled_text( struct Text *text )
1026 {
1027         if( !text->compiled )
1028                 return;
1029         Py_DECREF( ( PyObject * ) text->compiled );
1030         text->compiled = NULL;
1031
1032         return;
1033 }
1034
1035 /*****************************************************************************
1036 * Description: This function frees a finished (flags == 0) script.
1037 *****************************************************************************/
1038 void BPY_free_finished_script( Script * script )
1039 {
1040         PyGILState_STATE gilstate;
1041
1042         if( !script )
1043                 return;
1044
1045         gilstate = PyGILState_Ensure();
1046
1047         if( PyErr_Occurred(  ) ) {      /* if script ended after filesel */
1048                 PyErr_Print(  );        /* eventual errors are handled now */
1049                 error( "Python script error: check console" );
1050         }
1051
1052         PyGILState_Release(gilstate);
1053
1054         free_libblock( &G.main->script, script );
1055         return;
1056 }
1057
1058 static void unlink_script( Script * script )
1059 {       /* copied from unlink_text in drawtext.c */
1060         bScreen *scr;
1061         ScrArea *area;
1062         SpaceLink *sl;
1063
1064         for( scr = G.main->screen.first; scr; scr = scr->id.next ) {
1065                 for( area = scr->areabase.first; area; area = area->next ) {
1066                         for( sl = area->spacedata.first; sl; sl = sl->next ) {
1067                                 if( sl->spacetype == SPACE_SCRIPT ) {
1068                                         SpaceScript *sc = ( SpaceScript * ) sl;
1069
1070                                         if( sc->script == script ) {
1071                                                 sc->script = NULL;
1072
1073                                                 if( sc ==
1074                                                     area->spacedata.first ) {
1075                                                         scrarea_queue_redraw
1076                                                                 ( area );
1077                                                 }
1078                                         }
1079                                 }
1080                         }
1081                 }
1082         }
1083 }
1084
1085 void BPY_clear_script( Script * script )
1086 {
1087         PyObject *dict;
1088         PyGILState_STATE gilstate;
1089
1090         if( !script )
1091                 return;
1092
1093         gilstate = PyGILState_Ensure();
1094
1095         if (!Py_IsInitialized()) {
1096                 printf("\nError: trying to free script data after finalizing Python!");
1097                 printf("\nScript name: %s\n", script->id.name+2);
1098                 PyGILState_Release(gilstate);
1099                 return;
1100         }
1101
1102         Py_XDECREF( ( PyObject * ) script->py_draw );
1103         Py_XDECREF( ( PyObject * ) script->py_event );
1104         Py_XDECREF( ( PyObject * ) script->py_button );
1105         Py_XDECREF( ( PyObject * ) script->py_browsercallback );
1106         script->py_draw = NULL;
1107         script->py_event = NULL;
1108         script->py_button = NULL;
1109         script->py_browsercallback = NULL;
1110
1111         dict = script->py_globaldict;
1112
1113         if( dict ) {
1114                 PyDict_Clear( dict );
1115                 Py_DECREF( dict );      /* Release dictionary. */
1116                 script->py_globaldict = NULL;
1117         }
1118
1119         PyGILState_Release(gilstate);
1120
1121         unlink_script( script );
1122 }
1123
1124 /* PyDrivers */
1125
1126 /* PyDrivers are Ipo Drivers governed by expressions written in Python.
1127  * Expressions here are one-liners that evaluate to a float value. */
1128
1129 /* For faster execution we keep a special dictionary for pydrivers, with
1130  * the needed modules and aliases. */
1131 static int bpy_pydriver_create_dict(void)
1132 {
1133         PyObject *d, *mod;
1134
1135         if (bpy_pydriver_Dict) return -1;
1136
1137         d = PyDict_New();
1138         if (!d) return -1;
1139
1140         bpy_pydriver_Dict = d;
1141
1142         /* import some modules: builtins, Blender, math, Blender.noise */
1143
1144         PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
1145
1146         mod = PyImport_ImportModule("Blender");
1147         if (mod) {
1148                 PyDict_SetItemString(d, "Blender", mod);
1149                 PyDict_SetItemString(d, "b", mod);
1150                 Py_DECREF(mod);
1151         }
1152
1153         mod = PyImport_ImportModule("math");
1154         if (mod) {
1155                 PyDict_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
1156                 
1157                 /* Only keep for backwards compat! - just import all math into root, they are standard */
1158                 PyDict_SetItemString(d, "math", mod);
1159                 PyDict_SetItemString(d, "m", mod);
1160                 Py_DECREF(mod);
1161         } 
1162
1163         mod = PyImport_ImportModule("Blender.Noise");
1164         if (mod) {
1165                 PyDict_SetItemString(d, "noise", mod);
1166                 PyDict_SetItemString(d, "n", mod);
1167                 Py_DECREF(mod);
1168         }
1169
1170         /* If there's a Blender text called pydrivers.py, import it.
1171          * Users can add their own functions to this module. */
1172         mod = importText("pydrivers"); /* can also use PyImport_Import() */
1173         if (mod) {
1174                 PyDict_SetItemString(d, "pydrivers", mod);
1175                 PyDict_SetItemString(d, "p", mod);
1176                 Py_DECREF(mod);
1177         }
1178         else
1179                 PyErr_Clear();
1180
1181         /* short aliases for some Get() functions: */
1182
1183         /* ob(obname) == Blender.Object.Get(obname) */
1184         mod = PyImport_ImportModule("Blender.Object");
1185         if (mod) {
1186                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1187                 Py_DECREF(mod);
1188                 if (fcn) {
1189                         PyDict_SetItemString(d, "ob", fcn);
1190                         Py_DECREF(fcn);
1191                 }
1192         }
1193         
1194         /* TODO - change these */
1195         /* me(meshname) == Blender.Mesh.Get(meshname) */
1196         mod = PyImport_ImportModule("Blender.Mesh");
1197         if (mod) {
1198                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1199                 Py_DECREF(mod);
1200                 if (fcn) {
1201                         PyDict_SetItemString(d, "me", fcn);
1202                         Py_DECREF(fcn);
1203                 }
1204         }
1205
1206         /* ma(matname) == Blender.Material.Get(matname) */
1207         mod = PyImport_ImportModule("Blender.Material");
1208         if (mod) {
1209                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1210                 Py_DECREF(mod);
1211                 if (fcn) {
1212                         PyDict_SetItemString(d, "ma", fcn);
1213                         Py_DECREF(fcn);
1214                 }
1215         }
1216
1217         return 0;
1218 }
1219
1220 /* error return function for BPY_eval_pydriver */
1221 static float pydriver_error(IpoDriver *driver) {
1222
1223         if (bpy_pydriver_oblist)
1224                 bpy_pydriver_freeList();
1225
1226         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
1227                 PyDict_Clear(bpy_pydriver_Dict);
1228                 Py_DECREF(bpy_pydriver_Dict);
1229                 bpy_pydriver_Dict = NULL;
1230         }
1231
1232         driver->flag |= IPO_DRIVER_FLAG_INVALID; /* py expression failed */
1233         
1234         if (driver->ob)
1235                 fprintf(stderr, "\nError in Ipo Driver: Object %s\nThis is the failed Python expression:\n'%s'\n\n", driver->ob->id.name+2, driver->name);
1236         else
1237                 fprintf(stderr, "\nError in Ipo Driver: No Object\nThis is the failed Python expression:\n'%s'\n\n", driver->name);
1238         
1239         PyErr_Print();
1240
1241         return 0.0f;
1242 }
1243
1244
1245 /********PyConstraints*********/
1246
1247 /* This function checks whether a text-buffer is a PyConstraint candidate.
1248  * It uses simple text parsing that could be easily confused!
1249  */
1250 int BPY_is_pyconstraint(Text *text)
1251 {
1252         TextLine *tline = text->lines.first;
1253
1254         if (tline && (tline->len > 10)) {
1255                 char *line = tline->line;
1256                 
1257                 /* Expected format: #BPYCONSTRAINT
1258                  * The actual checks are forgiving, so slight variations also work. */
1259                 if (line && line[0] == '#' && strstr(line, "BPYCONSTRAINT")) return 1;
1260         }
1261         return 0;
1262 }
1263
1264 /* This function is called to update PyConstraint data so that it is compatible with the script. 
1265  * Some of the allocating/freeing of memory for constraint targets occurs here, espcially
1266  * if the number of targets changes.
1267  */
1268 void BPY_pyconstraint_update(Object *owner, bConstraint *con)
1269 {
1270         bPythonConstraint *data= con->data;
1271         
1272         if (data->text) {       
1273                 /* script does exist. it is assumed that this is a valid pyconstraint script */
1274                 PyObject *globals;
1275                 PyObject *retval, *gval;
1276                 PyGILState_STATE gilstate;
1277                 int num, i;
1278                 
1279                 /* clear the relevant flags first */
1280                 data->flag = 0;
1281
1282                 gilstate = PyGILState_Ensure();
1283
1284                 /* populate globals dictionary */
1285                 globals = CreateGlobalDictionary();
1286                 retval = RunPython(data->text, globals);
1287                 
1288                 if (retval == NULL) {
1289                         BPY_Err_Handle(data->text->id.name);
1290                         ReleaseGlobalDictionary(globals);
1291                         data->flag |= PYCON_SCRIPTERROR;
1292                         PyGILState_Release(gilstate);
1293                         return;
1294                 }
1295                 
1296                 Py_XDECREF(retval);
1297                 retval = NULL;
1298                 
1299                 /* try to find NUM_TARGETS */
1300                 gval = PyDict_GetItemString(globals, "NUM_TARGETS");
1301                 if ( (gval) && (num= PyInt_AsLong(gval)) ) {
1302                         /* NUM_TARGETS is defined... and non-zero */
1303                         bConstraintTarget *ct;
1304                         
1305                         /* check if it is valid (just make sure it is not negative)
1306                          *      TODO: PyInt_AsLong may return -1 as sign of invalid input... 
1307                          */
1308                         num = abs(num);
1309                         data->flag |= PYCON_USETARGETS;
1310                         
1311                         /* check if the number of targets has changed */
1312                         if (num < data->tarnum) {
1313                                 /* free a few targets */
1314                                 num= data->tarnum - num;
1315                                 for (i = 0; i < num; i++, data->tarnum--) {
1316                                         ct= data->targets.last;
1317                                         BLI_freelinkN(&data->targets, ct);
1318                                 }
1319                         }
1320                         else if (num > data->tarnum) {
1321                                 /* add a few targets */
1322                                 num = num - data->tarnum;
1323                                 for (i = 0; i < num; i++, data->tarnum++) {
1324                                         ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
1325                                         BLI_addtail(&data->targets, ct);
1326                                 }
1327                         }
1328                         
1329                         /* validate targets */
1330                         con->flag &= ~CONSTRAINT_DISABLE;
1331                         for (ct= data->targets.first; ct; ct= ct->next) {
1332                                 if (!exist_object(ct->tar)) {
1333                                         ct->tar = NULL;
1334                                         con->flag |= CONSTRAINT_DISABLE;
1335                                         break;
1336                                 }
1337                                 
1338                                 if ((ct->tar == owner) && (ct->subtarget[0] != 0)) {
1339                                         if (get_named_bone(get_armature(owner), ct->subtarget) == NULL) {
1340                                                 con->flag |= CONSTRAINT_DISABLE;
1341                                                 break;
1342                                         }
1343                                 }
1344                         }
1345                         
1346                         /* clear globals */
1347                         ReleaseGlobalDictionary(globals);
1348
1349                         PyGILState_Release(gilstate);
1350
1351                         return;
1352                 }
1353                 else {
1354                         /* NUM_TARGETS is not defined or equals 0 */
1355                         ReleaseGlobalDictionary(globals);
1356                         
1357                         /* free all targets */
1358                         BLI_freelistN(&data->targets);
1359                         data->tarnum = 0;
1360                         data->flag &= ~PYCON_USETARGETS;
1361                         
1362                         PyGILState_Release(gilstate);
1363
1364                         return;
1365                 }
1366         }
1367         else {
1368                 /* no script, so clear any settings/data now */
1369                 data->tarnum = 0;
1370                 data->flag = 0;
1371                 con->flag &= ~CONSTRAINT_DISABLE;
1372                 
1373                 BLI_freelistN(&data->targets);
1374                 
1375                 /* supposedly this should still leave the base struct... */
1376                 IDP_FreeProperty(data->prop);
1377         }
1378 }
1379
1380 /* PyConstraints Evaluation Function (only called from evaluate_constraint)
1381  * This function is responsible for modifying the ownermat that it is passed. 
1382  */
1383 void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase *targets)
1384 {
1385         PyObject *srcmat, *tarmat, *tarmats, *idprop;
1386         PyObject *globals;
1387         PyObject *gval;
1388         PyObject *pyargs, *retval;
1389         bConstraintTarget *ct;
1390         MatrixObject *retmat;
1391         int row, col, index;
1392         PyGILState_STATE gilstate;
1393
1394         if (!con->text) return;
1395         if (con->flag & PYCON_SCRIPTERROR) return;
1396
1397         gilstate = PyGILState_Ensure();
1398
1399         globals = CreateGlobalDictionary();
1400         
1401         /* wrap blender-data as PyObjects for evaluation 
1402          *      - we expose the owner's matrix as pymatrix
1403          *      - id-properties are wrapped using the id-properties pyapi
1404          *      - targets are presented as a list of matrices
1405          */
1406         srcmat = newMatrixObject((float *)cob->matrix, 4, 4, Py_NEW);
1407         idprop = BPy_Wrap_IDProperty(NULL, con->prop, NULL);
1408         
1409         tarmats= PyList_New(con->tarnum); 
1410         for (ct=targets->first, index=0; ct; ct=ct->next, index++) {
1411                 tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
1412                 PyList_SET_ITEM(tarmats, index, tarmat);
1413         }
1414         
1415         if (!setup_armature_weakrefs()) {
1416                 fprintf(stderr, "Oops - weakref dict setup\n");
1417                 PyGILState_Release(gilstate);
1418
1419                 return;
1420         }
1421         
1422         retval = RunPython(con->text, globals);
1423         
1424         if (retval == NULL) {
1425                 BPY_Err_Handle(con->text->id.name);
1426                 con->flag |= PYCON_SCRIPTERROR;
1427                 
1428                 /* free temp objects */
1429                 Py_XDECREF(idprop);
1430                 Py_XDECREF(srcmat);
1431                 Py_XDECREF(tarmats);
1432                 
1433                 ReleaseGlobalDictionary(globals);
1434
1435                 PyGILState_Release(gilstate);
1436
1437                 return;
1438         }
1439
1440         if (retval) {Py_XDECREF( retval );}
1441         retval = NULL;
1442         
1443         gval = PyDict_GetItemString(globals, "doConstraint");
1444         if (!gval) {
1445                 printf("ERROR: no doConstraint function in constraint!\n");
1446                 
1447                 /* free temp objects */
1448                 Py_XDECREF(idprop);
1449                 Py_XDECREF(srcmat);
1450                 Py_XDECREF(tarmats);
1451                 
1452                 ReleaseGlobalDictionary(globals);
1453
1454                 PyGILState_Release(gilstate);
1455
1456                 return;
1457         }
1458         
1459         /* Now for the fun part! Try and find the functions we need. */
1460         if (PyFunction_Check(gval)) {
1461                 pyargs = Py_BuildValue("OOO", srcmat, tarmats, idprop);
1462                 retval = PyObject_CallObject(gval, pyargs);
1463                 Py_XDECREF(pyargs);
1464         } 
1465         else {
1466                 printf("ERROR: doConstraint is supposed to be a function!\n");
1467                 con->flag |= PYCON_SCRIPTERROR;
1468                 
1469                 Py_XDECREF(idprop);
1470                 Py_XDECREF(srcmat);
1471                 Py_XDECREF(tarmats);
1472                 
1473                 ReleaseGlobalDictionary(globals);
1474
1475                 PyGILState_Release(gilstate);
1476
1477                 return;
1478         }
1479         
1480         if (!retval) {
1481                 BPY_Err_Handle(con->text->id.name);
1482                 con->flag |= PYCON_SCRIPTERROR;
1483                 
1484                 /* free temp objects */
1485                 Py_XDECREF(idprop);
1486                 Py_XDECREF(srcmat);
1487                 Py_XDECREF(tarmats);
1488                 
1489                 ReleaseGlobalDictionary(globals);
1490
1491                 PyGILState_Release(gilstate);
1492
1493                 return;
1494         }
1495         
1496         
1497         if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1498                 printf("Error in PyConstraint - doConstraint: Function not returning a matrix!\n");
1499                 con->flag |= PYCON_SCRIPTERROR;
1500                 
1501                 Py_XDECREF(idprop);
1502                 Py_XDECREF(srcmat);
1503                 Py_XDECREF(tarmats);
1504                 Py_XDECREF(retval);
1505                 
1506                 ReleaseGlobalDictionary(globals);
1507
1508                 PyGILState_Release(gilstate);
1509
1510                 return;
1511         }
1512         
1513         retmat = (MatrixObject *)retval;
1514         if (retmat->rowSize != 4 || retmat->colSize != 4) {
1515                 printf("Error in PyConstraint - doConstraint: Matrix returned is the wrong size!\n");
1516                 con->flag |= PYCON_SCRIPTERROR;
1517                 
1518                 Py_XDECREF(idprop);
1519                 Py_XDECREF(srcmat);
1520                 Py_XDECREF(tarmats);
1521                 Py_XDECREF(retval);
1522                 
1523                 ReleaseGlobalDictionary(globals);
1524
1525                 PyGILState_Release(gilstate);
1526
1527                 return;
1528         }       
1529
1530         /* this is the reverse of code taken from newMatrix() */
1531         for(row = 0; row < 4; row++) {
1532                 for(col = 0; col < 4; col++) {
1533                         cob->matrix[row][col] = retmat->contigPtr[row*4+col];
1534                 }
1535         }
1536         
1537         /* free temp objects */
1538         Py_XDECREF(idprop);
1539         Py_XDECREF(srcmat);
1540         Py_XDECREF(tarmats);
1541         Py_XDECREF(retval);
1542         
1543         /* clear globals */
1544         ReleaseGlobalDictionary(globals);
1545
1546         PyGILState_Release(gilstate);
1547 }
1548
1549 /* This evaluates the target matrix for each target the PyConstraint uses.
1550  * NOTE: it only does one target at a time!
1551  */
1552 void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
1553 {
1554         PyObject *tar, *subtar;
1555         PyObject *tarmat, *idprop;
1556         PyObject *globals;
1557         PyObject *gval;
1558         PyObject *pyargs, *retval;
1559         MatrixObject *retmat;
1560         int row, col;
1561         PyGILState_STATE gilstate;
1562
1563         if (!con->text) return;
1564         if (con->flag & PYCON_SCRIPTERROR) return;
1565         if (!ct) return;
1566         
1567         gilstate = PyGILState_Ensure();
1568
1569         globals = CreateGlobalDictionary();
1570         
1571         tar = Object_CreatePyObject(ct->tar);
1572         if ((ct->tar) && (ct->tar->type==OB_ARMATURE)) {
1573                 bPoseChannel *pchan;
1574                 pchan = get_pose_channel(ct->tar->pose, ct->subtarget);
1575                 subtar = PyPoseBone_FromPosechannel(pchan);
1576         }
1577         else
1578                 subtar = PyString_FromString(ct->subtarget);
1579         
1580         tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
1581         idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1582         
1583         if (!setup_armature_weakrefs()) {
1584                 fprintf(stderr, "Oops - weakref dict setup\n");
1585                 PyGILState_Release(gilstate);
1586                 return;
1587         }
1588         
1589         retval = RunPython(con->text, globals);
1590
1591         if (retval == NULL) {
1592                 BPY_Err_Handle(con->text->id.name);
1593                 con->flag |= PYCON_SCRIPTERROR;
1594                 
1595                 /* free temp objects */
1596                 Py_XDECREF(tar);
1597                 Py_XDECREF(subtar);
1598                 Py_XDECREF(idprop);
1599                 Py_XDECREF(tarmat);
1600                 
1601                 ReleaseGlobalDictionary(globals);
1602
1603                 PyGILState_Release(gilstate);
1604
1605                 return;
1606         }
1607
1608         Py_XDECREF(retval);
1609         retval = NULL;
1610         
1611         /* try to find doTarget function to set the target matrix */
1612         gval = PyDict_GetItemString(globals, "doTarget");
1613         if (!gval) {
1614                 /* free temp objects */
1615                 Py_XDECREF(tar);
1616                 Py_XDECREF(subtar);
1617                 Py_XDECREF(idprop);
1618                 Py_XDECREF(tarmat);
1619                 
1620                 ReleaseGlobalDictionary(globals);
1621
1622                 PyGILState_Release(gilstate);
1623
1624                 return;
1625         }
1626         
1627         /* Now for the fun part! Try and find the functions we need.*/
1628         if (PyFunction_Check(gval)) {
1629                 pyargs = Py_BuildValue("OOOO", tar, subtar, tarmat, idprop);
1630                 retval = PyObject_CallObject(gval, pyargs);
1631                 Py_XDECREF(pyargs);
1632         } 
1633         else {
1634                 printf("ERROR: doTarget is supposed to be a function!\n");
1635                 con->flag |= PYCON_SCRIPTERROR;
1636                 
1637                 Py_XDECREF(tar);
1638                 Py_XDECREF(subtar);
1639                 Py_XDECREF(idprop);
1640                 Py_XDECREF(tarmat);
1641                 
1642                 ReleaseGlobalDictionary(globals);
1643
1644                 PyGILState_Release(gilstate);
1645
1646                 return;
1647         }
1648         
1649         if (!retval) {
1650                 BPY_Err_Handle(con->text->id.name);
1651                 con->flag |= PYCON_SCRIPTERROR;
1652                 
1653                 
1654                 /* free temp objects */
1655                 Py_XDECREF(tar);
1656                 Py_XDECREF(subtar);
1657                 Py_XDECREF(idprop);
1658                 Py_XDECREF(tarmat);
1659                 
1660                 ReleaseGlobalDictionary(globals);
1661
1662                 PyGILState_Release(gilstate);
1663
1664                 return;
1665         }
1666         
1667         if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1668                 con->flag |= PYCON_SCRIPTERROR;
1669                 
1670                 Py_XDECREF(tar);
1671                 Py_XDECREF(subtar);
1672                 Py_XDECREF(idprop);
1673                 Py_XDECREF(tarmat);
1674                 Py_XDECREF(retval);
1675                 
1676                 ReleaseGlobalDictionary(globals);
1677
1678                 PyGILState_Release(gilstate);
1679
1680                 return;
1681         }
1682         
1683         retmat = (MatrixObject *)retval;
1684         if (retmat->rowSize != 4 || retmat->colSize != 4) {
1685                 printf("Error in PyConstraint - doTarget: Matrix returned is the wrong size!\n");
1686                 con->flag |= PYCON_SCRIPTERROR;
1687                 
1688                 Py_XDECREF(tar);
1689                 Py_XDECREF(subtar);
1690                 Py_XDECREF(idprop);
1691                 Py_XDECREF(tarmat);
1692                 Py_XDECREF(retval);
1693                 
1694                 ReleaseGlobalDictionary(globals);
1695
1696                 PyGILState_Release(gilstate);
1697
1698                 return;
1699         }       
1700
1701         /* this is the reverse of code taken from newMatrix() */
1702         for(row = 0; row < 4; row++) {
1703                 for(col = 0; col < 4; col++) {
1704                         ct->matrix[row][col] = retmat->contigPtr[row*4+col];
1705                 }
1706         }
1707         
1708         /* free temp objects */
1709         Py_XDECREF(tar);
1710         Py_XDECREF(subtar);
1711         Py_XDECREF(idprop);
1712         Py_XDECREF(tarmat);
1713         Py_XDECREF(retval);
1714         
1715         /* clear globals */
1716         ReleaseGlobalDictionary(globals);
1717
1718         PyGILState_Release(gilstate);
1719 }
1720
1721 /* This draws+handles the user-defined interface for editing pyconstraints idprops */
1722 void BPY_pyconstraint_settings(void *arg1, void *arg2)
1723 {
1724         bPythonConstraint *con= (bPythonConstraint *)arg1;
1725         PyObject *idprop;
1726         PyObject *globals;
1727         PyObject *gval;
1728         PyObject *retval;
1729         PyGILState_STATE gilstate;
1730         
1731         if (!con->text) return;
1732         if (con->flag & PYCON_SCRIPTERROR) return;
1733         
1734         globals = CreateGlobalDictionary();
1735         
1736         idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1737         
1738         retval = RunPython(con->text, globals);
1739
1740         if (retval == NULL) {
1741                 BPY_Err_Handle(con->text->id.name);
1742                 ReleaseGlobalDictionary(globals);
1743                 con->flag |= PYCON_SCRIPTERROR;
1744         
1745                 /* free temp objects */
1746                 Py_XDECREF(idprop);
1747
1748                 PyGILState_Release(gilstate);
1749
1750                 return;
1751         }
1752
1753         if (retval) {Py_XDECREF( retval );}
1754         retval = NULL;
1755         
1756         gval = PyDict_GetItemString(globals, "getSettings");
1757         if (!gval) {
1758                 printf("ERROR: no getSettings function in constraint!\n");
1759                 
1760                 /* free temp objects */
1761                 ReleaseGlobalDictionary( globals );
1762                 Py_XDECREF(idprop);
1763
1764                 PyGILState_Release(gilstate);
1765
1766                 return;
1767         }
1768         
1769         /* Now for the fun part! Try and find the functions we need. */
1770         if (PyFunction_Check(gval)) {
1771                 retval = PyObject_CallFunction(gval, "O", idprop);
1772         } 
1773         else {
1774                 printf("ERROR: getSettings is supposed to be a function!\n");
1775                 ReleaseGlobalDictionary( globals );
1776                 
1777                 Py_XDECREF(idprop);
1778
1779                 PyGILState_Release(gilstate);
1780
1781                 return;
1782         }
1783         
1784         if (!retval) {
1785                 BPY_Err_Handle(con->text->id.name);
1786                 con->flag |= PYCON_SCRIPTERROR;
1787                 
1788                 /* free temp objects */
1789                 ReleaseGlobalDictionary(globals);
1790                 Py_XDECREF(idprop);
1791
1792                 PyGILState_Release(gilstate);
1793
1794                 return;
1795         }
1796         else {
1797                 /* clear globals */
1798                 ReleaseGlobalDictionary(globals);
1799                 
1800                 /* free temp objects */
1801                 Py_XDECREF(idprop);
1802                 Py_DECREF(retval);
1803
1804                 PyGILState_Release(gilstate);
1805
1806                 return;
1807         }
1808 }
1809
1810 /* Update function, it gets rid of pydrivers global dictionary, forcing
1811  * BPY_pydriver_eval to recreate it. This function is used to force
1812  * reloading the Blender text module "pydrivers.py", if available, so
1813  * updates in it reach pydriver evaluation. */
1814 void BPY_pydriver_update(void)
1815 {
1816         PyGILState_STATE gilstate = PyGILState_Ensure();
1817
1818         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
1819                 PyDict_Clear(bpy_pydriver_Dict);
1820                 Py_DECREF(bpy_pydriver_Dict);
1821                 bpy_pydriver_Dict = NULL;
1822         }
1823
1824         PyGILState_Release(gilstate);
1825
1826         return;
1827 }
1828
1829 /* for depsgraph.c, runs py expr once to collect all refs. made
1830  * to objects (self refs. to the object that owns the py driver
1831  * are not allowed). */
1832 struct Object **BPY_pydriver_get_objects(IpoDriver *driver)
1833 {
1834         /*if (!driver || !driver->ob || driver->name[0] == '\0')
1835                 return NULL;*/
1836
1837         /*PyErr_Clear();*/
1838
1839         /* clear the flag that marks invalid python expressions */
1840         driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
1841
1842         /* tell we're running a pydriver, so Get() functions know they need
1843          * to add the requested obj to our list */
1844         bpy_pydriver_running(1);
1845
1846         /* append driver owner object as the 1st ob in the list;
1847          * we put it there to make sure it is not itself referenced in
1848          * its pydriver expression */
1849         bpy_pydriver_appendToList(driver->ob);
1850
1851         /* this will append any other ob referenced in expr (driver->name)
1852          * or set the driver's error flag if driver's py expression fails */
1853         BPY_pydriver_eval(driver);
1854
1855         bpy_pydriver_running(0); /* ok, we're done */
1856
1857         return bpy_pydriver_obArrayFromList(); /* NULL if eval failed */
1858 }
1859
1860 /* This evals py driver expressions, 'expr' is a Python expression that
1861  * should evaluate to a float number, which is returned. */
1862 float BPY_pydriver_eval(IpoDriver *driver)
1863 {
1864         char *expr = NULL;
1865         PyObject *retval, *bpy_ob = NULL;
1866         float result = 0.0f; /* default return */
1867         int setitem_retval;
1868         PyGILState_STATE gilstate;
1869
1870         if (!driver) return result;
1871
1872         expr = driver->name; /* the py expression to be evaluated */
1873         if (!expr || expr[0]=='\0') return result;
1874
1875         gilstate = PyGILState_Ensure();
1876
1877         if (!bpy_pydriver_Dict) {
1878                 if (bpy_pydriver_create_dict() != 0) {
1879                         fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
1880                         PyGILState_Release(gilstate);
1881                         return result;
1882                 }
1883         }
1884
1885         if (driver->ob)
1886                 bpy_ob = Object_CreatePyObject(driver->ob);
1887
1888         if (!bpy_ob) {
1889                 Py_INCREF(Py_None);
1890                 bpy_ob = Py_None;
1891         }
1892
1893         setitem_retval = EXPP_dict_set_item_str(bpy_pydriver_Dict, "self", bpy_ob);
1894
1895         if( !setup_armature_weakrefs()){
1896                 fprintf( stderr, "Oops - weakref dict setup\n");
1897                 PyGILState_Release(gilstate);
1898                 return result;
1899         }
1900
1901         retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
1902                 bpy_pydriver_Dict);
1903
1904         if (retval == NULL) {
1905                 result = pydriver_error(driver);
1906                 PyGILState_Release(gilstate);
1907                 return result;
1908         }
1909
1910         result = ( float )PyFloat_AsDouble( retval );
1911         
1912         if (result == -1 && PyErr_Occurred()) {
1913                 result = pydriver_error(driver);
1914                 PyGILState_Release(gilstate);
1915                 return result;
1916         }
1917
1918         /* remove 'self', since this dict is also used by py buttons */
1919         if (setitem_retval == 0) PyDict_DelItemString(bpy_pydriver_Dict, "self");
1920
1921         /* all fine, make sure the "invalid expression" flag is cleared */
1922         driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
1923
1924         PyGILState_Release(gilstate);
1925
1926         return result;
1927 }
1928
1929 /* Button Python Evaluation */
1930
1931 /* Python evaluation for gui buttons:
1932  *      users can write any valid Python expression (that evals to an int or float)
1933  *      inside Blender's gui number buttons and have them evaluated to their
1934  *      actual int or float value.
1935  *
1936  *      The global dict used for pydrivers is also used here, so all imported
1937  *      modules for pydrivers (including the pydrivers.py Blender text) are
1938  *      available for button py eval, too. */
1939
1940 static int bpy_button_eval_error(char *expr) {
1941
1942         if (bpy_pydriver_oblist)
1943                 bpy_pydriver_freeList();
1944
1945         if (bpy_pydriver_Dict) { /* free the persistent global dict */
1946                 /* it's the same dict used by pydrivers */
1947                 PyDict_Clear(bpy_pydriver_Dict);
1948                 Py_DECREF(bpy_pydriver_Dict);
1949                 bpy_pydriver_Dict = NULL;
1950         }
1951
1952         fprintf(stderr, "\nError in button evaluation:\nThis is the failed Python expression:\n'%s'\n\n", expr);
1953
1954         PyErr_Print();
1955
1956         return -1;
1957 }
1958
1959 int BPY_button_eval(char *expr, double *value)
1960 {
1961         PyObject *retval, *floatval;
1962         PyGILState_STATE gilstate;
1963         int ret;
1964
1965         if (!value || !expr || expr[0]=='\0') return -1;
1966
1967         *value = 0.0; /* default value */
1968
1969         gilstate = PyGILState_Ensure();
1970
1971         if (!bpy_pydriver_Dict) {
1972                 if (bpy_pydriver_create_dict() != 0) {
1973                         fprintf(stderr,
1974                                 "Button Python Eval error: couldn't create Python dictionary");
1975                         PyGILState_Release(gilstate);
1976                         return -1;
1977                 }
1978         }
1979
1980
1981         if( !setup_armature_weakrefs()){
1982                 fprintf(stderr, "Oops - weakref dict\n");
1983                 PyGILState_Release(gilstate);
1984                 return -1;
1985         }
1986
1987         retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
1988                 bpy_pydriver_Dict);
1989
1990         if (retval == NULL) {
1991                 ret = bpy_button_eval_error(expr);
1992                 PyGILState_Release(gilstate);
1993                 return ret;
1994         }
1995         else {
1996                 floatval = PyNumber_Float(retval);
1997                 Py_DECREF(retval);
1998         }
1999
2000         if (floatval == NULL) {
2001                 ret = bpy_button_eval_error(expr);
2002                 PyGILState_Release(gilstate);
2003                 return ret;
2004         } else {
2005                 *value = (float)PyFloat_AsDouble(floatval);
2006                 Py_DECREF(floatval);
2007         }
2008
2009         PyGILState_Release(gilstate);
2010
2011         return 0; /* successful exit */
2012 }
2013
2014
2015 /*****************************************************************************/
2016 /* ScriptLinks                                                        */
2017 /*****************************************************************************/
2018
2019 /*****************************************************************************/
2020 /* Description:                                                          */
2021 /* Notes:                               Not implemented yet      */
2022 /*****************************************************************************/
2023 void BPY_clear_bad_scriptlinks( struct Text *byebye )
2024 {
2025 /*
2026         BPY_clear_bad_scriptlist(getObjectList(), byebye);
2027         BPY_clear_bad_scriptlist(getLampList(), byebye);
2028         BPY_clear_bad_scriptlist(getCameraList(), byebye);
2029         BPY_clear_bad_scriptlist(getMaterialList(), byebye);
2030         BPY_clear_bad_scriptlist(getWorldList(),        byebye);
2031         BPY_clear_bad_scriptlink(&scene_getCurrent()->id, byebye);
2032
2033         allqueue(REDRAWBUTSSCRIPT, 0);
2034 */
2035         return;
2036 }
2037
2038 /*****************************************************************************
2039 * Description: Loop through all scripts of a list of object types, and 
2040 *       execute these scripts.  
2041 *       For the scene, only the current active scene the scripts are 
2042 *       executed (if any).
2043 *****************************************************************************/
2044 void BPY_do_all_scripts( short event )
2045 {
2046         DoAllScriptsFromList( &( G.main->object ), event );
2047         DoAllScriptsFromList( &( G.main->lamp ), event );
2048         DoAllScriptsFromList( &( G.main->camera ), event );
2049         DoAllScriptsFromList( &( G.main->mat ), event );
2050         DoAllScriptsFromList( &( G.main->world ), event );
2051
2052         BPY_do_pyscript( &( G.scene->id ), event );
2053
2054         return;
2055 }
2056
2057 /*****************************************************************************
2058 * Description: Execute a Python script when an event occurs. The following  
2059 *               events are possible: frame changed, load script and redraw.  
2060 *               Only events happening to one of the following object types   
2061 *               are handled: Object, Lamp, Camera, Material, World and      
2062 *               Scene.                  
2063 *****************************************************************************/
2064
2065 static ScriptLink *ID_getScriptlink( ID * id )
2066 {
2067         switch ( MAKE_ID2( id->name[0], id->name[1] ) ) {
2068         case ID_OB:
2069                 return &( ( Object * ) id )->scriptlink;
2070         case ID_LA:
2071                 return &( ( Lamp * ) id )->scriptlink;
2072         case ID_CA:
2073                 return &( ( Camera * ) id )->scriptlink;
2074         case ID_MA:
2075                 return &( ( Material * ) id )->scriptlink;
2076         case ID_WO:
2077                 return &( ( World * ) id )->scriptlink;
2078         case ID_SCE:
2079                 return &( ( Scene * ) id )->scriptlink;
2080         default:
2081                 return NULL;
2082         }
2083 }
2084
2085 int BPY_has_onload_script( void )
2086 {
2087         ScriptLink *slink = &G.scene->scriptlink;
2088         int i;
2089
2090         if( !slink || !slink->totscript )
2091                 return 0;
2092
2093         for( i = 0; i < slink->totscript; i++ ) {
2094                 if( ( slink->flag[i] == SCRIPT_ONLOAD )
2095                     && ( slink->scripts[i] != NULL ) )
2096                         return 1;
2097         }
2098
2099         return 0;
2100 }
2101
2102 void BPY_do_pyscript( ID * id, short event )
2103 {
2104         ScriptLink *scriptlink;
2105
2106         if( !id ) return;
2107
2108         scriptlink = ID_getScriptlink( id );
2109
2110         if( scriptlink && scriptlink->totscript ) {
2111                 PyObject *value;
2112                 PyObject *dict;
2113                 PyObject *ret;
2114                 int index, during_slink = during_scriptlink(  );
2115                 PyGILState_STATE gilstate;
2116
2117                 /* invalid scriptlinks (new .blend was just loaded), return */
2118                 if( during_slink < 0 )
2119                         return;
2120
2121                 gilstate = PyGILState_Ensure();
2122
2123                 if( !setup_armature_weakrefs()){
2124                         printf("Oops - weakref dict, this is a bug\n");
2125                         PyGILState_Release(gilstate);
2126                         return;
2127                 }
2128                 
2129                 value = GetPyObjectFromID( id );
2130                 if( !value){
2131                         printf("Oops - could not get a valid python object for Blender.link, this is a bug\n");
2132                         PyGILState_Release(gilstate);
2133                         return;
2134                 }
2135                 
2136                 /* tell we're running a scriptlink.  The sum also tells if this script
2137                  * is running nested inside another.  Blender.Load needs this info to
2138                  * avoid trouble with invalid slink pointers. */
2139                 during_slink++;
2140                 disable_where_scriptlink( (short)during_slink );
2141
2142                 /* set globals in Blender module to identify scriptlink */
2143                 PyDict_SetItemString(   g_blenderdict, "bylink", Py_True);
2144                 EXPP_dict_set_item_str( g_blenderdict, "link", value );
2145                 EXPP_dict_set_item_str( g_blenderdict, "event",
2146                                       PyString_FromString( event_to_name
2147                                                            ( event ) ) );
2148                 if (event == SCRIPT_POSTRENDER) event = SCRIPT_RENDER;
2149
2150                 for( index = 0; index < scriptlink->totscript; index++ ) {
2151                         if( ( scriptlink->flag[index] == event ) &&
2152                             ( scriptlink->scripts[index] != NULL ) ) {
2153                                 dict = CreateGlobalDictionary(  );
2154                                 ret = RunPython( ( Text * ) scriptlink->
2155                                                  scripts[index], dict );
2156                                 ReleaseGlobalDictionary( dict );
2157
2158                                 if( !ret ) {
2159                                         /* Failed execution of the script */
2160                                         BPY_Err_Handle( scriptlink->
2161                                                         scripts[index]->name +
2162                                                         2 );
2163                                         //BPY_end_python ();
2164                                         //BPY_start_python ();
2165                                 } else {
2166                                         Py_DECREF( ret );
2167                                 }
2168                                 /* If a scriptlink has just loaded a new .blend file, the
2169                                  * scriptlink pointer became invalid (see api2_2x/Blender.c),
2170                                  * so we stop here. */
2171                                 if( during_scriptlink(  ) == -1 ) {
2172                                         during_slink = 1;
2173                                         break;
2174                                 }
2175                         }
2176                 }
2177
2178                 disable_where_scriptlink( (short)(during_slink - 1) );
2179
2180                 /* cleanup bylink flag and clear link so PyObject
2181                  * can be released 
2182                  */
2183                 PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
2184                 PyDict_SetItemString( g_blenderdict, "link", Py_None );
2185                 EXPP_dict_set_item_str( g_blenderdict, "event", PyString_FromString( "" ) );
2186
2187                 PyGILState_Release(gilstate);
2188         }
2189 }
2190
2191
2192 /* SPACE HANDLERS */
2193
2194 /* These are special script links that can be assigned to ScrArea's to
2195  * (EVENT type) receive events sent to a given space (and use or ignore them) or
2196  * (DRAW type) be called after the space is drawn, to draw anything on top of
2197  * the space area. */
2198
2199 /* How to add space handlers to other spaces:
2200  * - add the space event defines to DNA_scriptlink_types.h, as done for
2201  *   3d view: SPACEHANDLER_VIEW3D_EVENT, for example;
2202  * - add the new defines to Blender.SpaceHandler dictionary in Blender.c;
2203  * - check space.c for how to call the event handlers;
2204  * - check drawview.c for how to call the draw handlers;
2205  * - check header_view3d.c for how to add the "Space Handler Scripts" menu.
2206  * Note: DRAW handlers should be called with 'event = 0', chech drawview.c */
2207
2208 int BPY_has_spacehandler(Text *text, ScrArea *sa)
2209 {
2210         ScriptLink *slink;
2211         int index;
2212
2213         if (!sa || !text) return 0;
2214
2215         slink = &sa->scriptlink;
2216
2217         for (index = 0; index < slink->totscript; index++) {
2218                 if (slink->scripts[index] && (slink->scripts[index] == (ID *)text))
2219                         return 1;
2220         }
2221
2222         return 0;       
2223 }
2224
2225 int BPY_is_spacehandler(Text *text, char spacetype)
2226 {
2227         TextLine *tline = text->lines.first;
2228         unsigned short type = 0;
2229
2230         if (tline && (tline->len > 10)) {
2231                 char *line = tline->line;
2232
2233                 /* Expected format: # SPACEHANDLER.SPACE.TYPE
2234                  * Ex: # SPACEHANDLER.VIEW3D.DRAW
2235                  * The actual checks are forgiving, so slight variations also work. */
2236                 if (line && line[0] == '#' && strstr(line, "HANDLER")) {
2237                         line++; /* skip '#' */
2238
2239                         /* only done for 3D View right now, trivial to add for others: */
2240                         switch (spacetype) {
2241                                 case SPACE_VIEW3D:
2242                                         if (strstr(line, "3D")) { /* VIEW3D, 3DVIEW */
2243                                                 if (strstr(line, "DRAW")) type = SPACEHANDLER_VIEW3D_DRAW;
2244                                                 else if (strstr(line, "EVENT")) type = SPACEHANDLER_VIEW3D_EVENT;
2245                                         }
2246                                         break;
2247                         }
2248                 }
2249         }
2250         return type; /* 0 if not a space handler */
2251 }
2252
2253 int BPY_del_spacehandler(Text *text, ScrArea *sa)
2254 {
2255         ScriptLink *slink;
2256         int i, j;
2257
2258         if (!sa || !text) return -1;
2259
2260         slink = &sa->scriptlink;
2261         if (slink->totscript < 1) return -1;
2262
2263         for (i = 0; i < slink->totscript; i++) {
2264                 if (text == (Text *)slink->scripts[i]) {
2265
2266                         for (j = i; j < slink->totscript - 1; j++) {
2267                                 slink->flag[j] = slink->flag[j+1];
2268                                 slink->scripts[j] = slink->scripts[j+1];
2269                         }
2270                         slink->totscript--;
2271                         /* like done in buttons_script.c we just free memory
2272                          * if all slinks have been removed -- less fragmentation,
2273                          * these should be quite small arrays */
2274                         if (slink->totscript == 0) {
2275                                 if (slink->scripts) MEM_freeN(slink->scripts);
2276                                 if (slink->flag) MEM_freeN(slink->flag);
2277                                 break;
2278                         }
2279                 }
2280         }
2281         return 0;
2282 }
2283
2284 int BPY_add_spacehandler(Text *text, ScrArea *sa, char spacetype)
2285 {
2286         unsigned short handlertype;
2287
2288         if (!sa || !text) return -1;
2289
2290         handlertype = (unsigned short)BPY_is_spacehandler(text, spacetype);
2291
2292         if (handlertype) {
2293                 ScriptLink *slink = &sa->scriptlink;
2294                 void *stmp, *ftmp;
2295                 unsigned short space_event = SPACEHANDLER_VIEW3D_EVENT;
2296
2297                 /* extend slink */
2298
2299                 stmp= slink->scripts;           
2300                 slink->scripts= MEM_mallocN(sizeof(ID*)*(slink->totscript+1),
2301                         "spacehandlerscripts");
2302         
2303                 ftmp= slink->flag;              
2304                 slink->flag= MEM_mallocN(sizeof(short*)*(slink->totscript+1),
2305                         "spacehandlerflags");
2306         
2307                 if (slink->totscript) {
2308                         memcpy(slink->scripts, stmp, sizeof(ID*)*(slink->totscript));
2309                         MEM_freeN(stmp);
2310
2311                         memcpy(slink->flag, ftmp, sizeof(short)*(slink->totscript));
2312                         MEM_freeN(ftmp);
2313                 }
2314
2315                 switch (spacetype) {
2316                         case SPACE_VIEW3D:
2317                                 if (handlertype == 1) space_event = SPACEHANDLER_VIEW3D_EVENT;
2318                                 else space_event = SPACEHANDLER_VIEW3D_DRAW;
2319                                 break;
2320                         default:
2321                                 break;
2322                 }
2323
2324                 slink->scripts[slink->totscript] = (ID *)text;
2325                 slink->flag[slink->totscript]= space_event;
2326
2327                 slink->totscript++;
2328                 slink->actscript = slink->totscript;
2329
2330         }
2331         return 0;
2332 }
2333
2334 int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
2335         unsigned short space_event )
2336 {
2337         ScriptLink *scriptlink;
2338         int retval = 0;
2339         PyGILState_STATE gilstate;
2340         
2341         if (!sa || !(G.f & G_DOSCRIPTLINKS)) return 0;
2342         
2343         scriptlink = &sa->scriptlink;
2344
2345         if (scriptlink->totscript > 0) {
2346                 PyObject *dict;
2347                 PyObject *ret;
2348                 int index, during_slink = during_scriptlink();
2349
2350                 /* invalid scriptlinks (new .blend was just loaded), return */
2351                 if (during_slink < 0) return 0;
2352
2353                 /* tell we're running a scriptlink.  The sum also tells if this script
2354                  * is running nested inside another.  Blender.Load needs this info to
2355                  * avoid trouble with invalid slink pointers.
2356                  * Update (test): allow EVENT space handlers to call file/image selectors,
2357                  * still disabled for DRAW space handlers: */
2358                 if (event == 0) { /* event = 0: DRAW space handler */
2359                         during_slink++;
2360                         disable_where_scriptlink( (short)during_slink );
2361                 }
2362
2363                 gilstate = PyGILState_Ensure();
2364
2365                 if( !setup_armature_weakrefs()){
2366                         printf("Oops - weakref dict, this is a bug\n");
2367                         PyGILState_Release(gilstate);
2368                         return 0;
2369                 }
2370                 
2371                 /* set globals in Blender module to identify space handler scriptlink */
2372                 PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
2373                 /* unlike normal scriptlinks, here Blender.link is int (space event type) */
2374                 EXPP_dict_set_item_str(g_blenderdict, "link", PyInt_FromLong(space_event));
2375                 /* note: DRAW space_events set event to 0 */
2376                 EXPP_dict_set_item_str(g_blenderdict, "event", PyInt_FromLong(event));
2377                 /* now run all assigned space handlers for this space and space_event */
2378                 for( index = 0; index < scriptlink->totscript; index++ ) {
2379
2380                         /* for DRAW handlers: */
2381                         if (event == 0) {
2382                                 glPushAttrib(GL_ALL_ATTRIB_BITS);
2383                                 glMatrixMode(GL_PROJECTION);
2384                                 glPushMatrix();
2385                                 glMatrixMode(GL_MODELVIEW);
2386                                 glPushMatrix();
2387                         }
2388
2389                         if( ( scriptlink->flag[index] == space_event ) &&
2390                             ( scriptlink->scripts[index] != NULL ) ) {
2391                                 dict = CreateGlobalDictionary();
2392                                 ret = RunPython( ( Text * ) scriptlink->scripts[index], dict );
2393                                 ReleaseGlobalDictionary( dict );
2394
2395                                 if (!ret) { /* Failed execution of the script */
2396                                         BPY_Err_Handle( scriptlink->scripts[index]->name+2 );
2397                                 } else {
2398                                         Py_DECREF(ret);
2399
2400                                         /* an EVENT type (event != 0) script can either accept an event or
2401                                          * ignore it:
2402                                          * if the script sets Blender.event to None it accepted it;
2403                                          * otherwise the space's event handling callback that called us
2404                                          * can go on processing the event */
2405                                         if (event && (PyDict_GetItemString(g_blenderdict,"event") == Py_None))
2406                                                 retval = 1; /* event was swallowed */
2407                                 }
2408
2409                                 /* If a scriptlink has just loaded a new .blend file, the
2410                                  * scriptlink pointer became invalid (see api2_2x/Blender.c),
2411                                  * so we stop here. */
2412                                 if( during_scriptlink(  ) == -1 ) {
2413                                         during_slink = 1;
2414                                         if (event == 0) glPopAttrib();
2415                                         break;
2416                                 }
2417                         }
2418
2419                         /* for DRAW handlers: */
2420                         if (event == 0) {
2421                                 glMatrixMode(GL_PROJECTION);
2422                                 glPopMatrix();
2423                                 glMatrixMode(GL_MODELVIEW);
2424                                 glPopMatrix();
2425                                 glPopAttrib();
2426                                 disable_where_scriptlink( (short)(during_slink - 1) );
2427                         }
2428
2429                 }
2430
2431                 PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
2432                 PyDict_SetItemString(g_blenderdict, "link", Py_None );
2433                 EXPP_dict_set_item_str(g_blenderdict, "event", PyString_FromString(""));
2434         }
2435         
2436         /* retval:
2437          * space_event is of type EVENT:
2438          * 0 - event was returned,
2439          * 1 - event was processed;
2440          * space_event is of type DRAW:
2441          * 0 always */
2442
2443         PyGILState_Release(gilstate);
2444
2445         return retval;
2446 }
2447
2448 /*****************************************************************************
2449 * Description:  
2450 * Notes:
2451 *****************************************************************************/
2452 void BPY_free_scriptlink( struct ScriptLink *slink )
2453 {
2454         if( slink->totscript ) {
2455                 if( slink->flag ) {
2456                         MEM_freeN( slink->flag );
2457                         slink->flag= NULL;
2458                 }
2459                 if( slink->scripts ) {
2460                         MEM_freeN( slink->scripts );
2461                         slink->scripts= NULL;
2462                 }
2463         }
2464
2465         return;
2466 }
2467
2468 static int CheckAllSpaceHandlers(Text *text)
2469 {
2470         bScreen *screen;
2471         ScrArea *sa;
2472         ScriptLink *slink;
2473         int fixed = 0;
2474
2475         for (screen = G.main->screen.first; screen; screen = screen->id.next) {
2476                 for (sa = screen->areabase.first; sa; sa = sa->next) {
2477                         slink = &sa->scriptlink;
2478                         if (!slink->totscript) continue;
2479                         if (BPY_del_spacehandler(text, sa) == 0) fixed++;
2480                 }
2481         }
2482         return fixed;
2483 }
2484
2485 static int CheckAllScriptsFromList( ListBase * list, Text * text )
2486 {
2487         ID *id;
2488         ScriptLink *scriptlink;
2489         int index;
2490         int fixed = 0;
2491
2492         id = list->first;
2493
2494         while( id != NULL ) {
2495                 scriptlink = ID_getScriptlink( id );
2496                 if( scriptlink && scriptlink->totscript ) {
2497                         for( index = 0; index < scriptlink->totscript; index++) {
2498                                 if ((Text *)scriptlink->scripts[index] == text) {
2499                                         scriptlink->scripts[index] = NULL;
2500                                         fixed++;
2501                                 }
2502                         }
2503                 }
2504                 id = id->next;
2505         }
2506
2507         return fixed;
2508 }
2509
2510 /* When a Text is deleted, we need to unlink it from eventual scriptlinks */
2511 int BPY_check_all_scriptlinks( Text * text )
2512 {
2513         int fixed = 0;
2514         fixed += CheckAllScriptsFromList( &( G.main->object ), text );
2515         fixed += CheckAllScriptsFromList( &( G.main->lamp ), text );
2516         fixed += CheckAllScriptsFromList( &( G.main->camera ), text );
2517         fixed += CheckAllScriptsFromList( &( G.main->mat ), text );
2518         fixed += CheckAllScriptsFromList( &( G.main->world ), text );
2519         fixed += CheckAllScriptsFromList( &( G.main->scene ), text );
2520         fixed += CheckAllSpaceHandlers(text);
2521
2522         return fixed;
2523 }
2524
2525 /*****************************************************************************
2526 * Description: 
2527 * Notes:
2528 *****************************************************************************/
2529 void BPY_copy_scriptlink( struct ScriptLink *scriptlink )
2530 {
2531         void *tmp;
2532
2533         if( scriptlink->totscript ) {
2534
2535                 tmp = scriptlink->scripts;
2536                 scriptlink->scripts =
2537                         MEM_mallocN( sizeof( ID * ) * scriptlink->totscript,
2538                                      "scriptlistL" );
2539                 memcpy( scriptlink->scripts, tmp,
2540                         sizeof( ID * ) * scriptlink->totscript );
2541
2542                 tmp = scriptlink->flag;
2543                 scriptlink->flag =
2544                         MEM_mallocN( sizeof( short ) * scriptlink->totscript,
2545                                      "scriptlistF" );
2546                 memcpy( scriptlink->flag, tmp,
2547                         sizeof( short ) * scriptlink->totscript );
2548         }
2549
2550         return;
2551 }
2552
2553 /****************************************************************************
2554 * Description:
2555 * Notes:                Not implemented yet
2556 *****************************************************************************/
2557 int BPY_call_importloader( char *name )
2558 {                       /* XXX Should this function go away from Blender? */
2559         printf( "In BPY_call_importloader(name=%s)\n", name );
2560         return ( 0 );
2561 }
2562
2563 /*****************************************************************************
2564 * Private functions
2565 *****************************************************************************/
2566
2567 /*****************************************************************************
2568 * Description: This function executes the python script passed by text. 
2569 *               The Python dictionary containing global variables needs to
2570 *               be passed in globaldict.
2571 *****************************************************************************/
2572 PyObject *RunPython( Text * text, PyObject * globaldict )
2573 {
2574         char *buf = NULL;
2575
2576 /* The script text is compiled to Python bytecode and saved at text->compiled
2577  * to speed-up execution if the user executes the script multiple times */
2578
2579         if( !text->compiled ) { /* if it wasn't already compiled, do it now */
2580                 buf = txt_to_buf( text );
2581
2582                 text->compiled =
2583                         Py_CompileString( buf, GetName( text ),
2584                                           Py_file_input );
2585
2586                 MEM_freeN( buf );
2587
2588                 if( PyErr_Occurred(  ) ) {
2589                         BPY_free_compiled_text( text );
2590                         return NULL;
2591                 }
2592
2593         }
2594
2595         return PyEval_EvalCode( text->compiled, globaldict, globaldict );
2596 }
2597
2598 /*****************************************************************************
2599 * Description: This function returns the value of the name field of the 
2600 *       given Text struct.
2601 *****************************************************************************/
2602 char *GetName( Text * text )
2603 {
2604         return ( text->id.name + 2 );
2605 }
2606
2607 /*****************************************************************************
2608 * Description: This function creates a new Python dictionary object.
2609 *****************************************************************************/
2610 PyObject *CreateGlobalDictionary( void )
2611 {
2612         PyObject *dict = PyDict_New(  );
2613
2614         PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) );
2615         EXPP_dict_set_item_str( dict, "__name__",
2616                               PyString_FromString( "__main__" ) );
2617
2618         return dict;
2619 }
2620
2621 /*****************************************************************************
2622 * Description: This function deletes a given Python dictionary object.
2623 *****************************************************************************/
2624 void ReleaseGlobalDictionary( PyObject * dict )
2625 {
2626         PyDict_Clear( dict );
2627         Py_DECREF( dict );      /* Release dictionary. */
2628
2629         return;
2630 }
2631
2632 /***************************************************************************
2633 * Description: This function runs all scripts (if any) present in the
2634 *               list argument. The event by which the function has been 
2635 *               called, is passed in the event argument.
2636 *****************************************************************************/
2637 void DoAllScriptsFromList( ListBase * list, short event )
2638 {
2639         ID *id;
2640
2641         id = list->first;
2642
2643         while( id != NULL ) {
2644                 BPY_do_pyscript( id, event );
2645                 id = id->next;
2646         }
2647
2648         return;
2649 }
2650
2651 PyObject *importText( char *name )
2652 {
2653         Text *text;
2654         char *txtname;
2655         char *buf = NULL;
2656         int namelen = strlen( name );
2657
2658         txtname = malloc( namelen + 3 + 1 );
2659         if( !txtname )
2660                 return NULL;
2661
2662         memcpy( txtname, name, namelen );
2663         memcpy( &txtname[namelen], ".py", 4 );
2664
2665         text = ( Text * ) & ( G.main->text.first );
2666
2667         while( text ) {
2668                 if( !strcmp( txtname, GetName( text ) ) )
2669                         break;
2670                 text = text->id.next;
2671         }
2672
2673         if( !text ) {
2674                 free( txtname );
2675                 return NULL;
2676         }
2677
2678         if( !text->compiled ) {
2679                 buf = txt_to_buf( text );
2680                 text->compiled =
2681                         Py_CompileString( buf, GetName( text ),
2682                                           Py_file_input );
2683                 MEM_freeN( buf );
2684
2685                 if( PyErr_Occurred(  ) ) {
2686                         PyErr_Print(  );
2687                         BPY_free_compiled_text( text );
2688                         free( txtname );
2689                         return NULL;
2690                 }
2691         }
2692
2693         free( txtname );
2694         return PyImport_ExecCodeModule( name, text->compiled );
2695 }
2696
2697 static PyMethodDef bimport[] = {
2698         {"blimport", blender_import, METH_VARARGS, "our own import"}
2699 };
2700
2701 PyObject *blender_import( PyObject * self, PyObject * args )
2702 {
2703         PyObject *exception, *err, *tb;
2704         char *name;
2705         PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
2706         PyObject *m;
2707
2708         if( !PyArg_ParseTuple( args, "s|OOO:bimport",
2709                                &name, &globals, &locals, &fromlist ) )
2710                 return NULL;
2711
2712         m = PyImport_ImportModuleEx( name, globals, locals, fromlist );
2713
2714         if( m )
2715                 return m;
2716         else
2717                 PyErr_Fetch( &exception, &err, &tb );   /*restore for probable later use */
2718
2719         m = importText( name );
2720         if( m ) {               /* found module, ignore above exception */
2721                 PyErr_Clear(  );
2722                 Py_XDECREF( exception );
2723                 Py_XDECREF( err );
2724                 Py_XDECREF( tb );
2725                 printf( "imported from text buffer...\n" );
2726         } else {
2727                 PyErr_Restore( exception, err, tb );
2728         }
2729         return m;
2730 }
2731
2732 void init_ourImport( void )
2733 {
2734         PyObject *m, *d;
2735         PyObject *import = PyCFunction_New( bimport, NULL );
2736
2737         m = PyImport_AddModule( "__builtin__" );
2738         d = PyModule_GetDict( m );
2739         
2740         EXPP_dict_set_item_str( d, "__import__", import );
2741 }
2742
2743 /*
2744  * find in-memory module and recompile
2745  */
2746
2747 static PyObject *reimportText( PyObject *module )
2748 {
2749         Text *text;
2750         char *txtname;
2751         char *name;
2752         char *buf = NULL;
2753
2754         /* get name, filename from the module itself */
2755
2756         txtname = PyModule_GetFilename( module );
2757         name = PyModule_GetName( module );
2758         if( !txtname || !name)
2759                 return NULL;
2760
2761         /* look up the text object */
2762         text = ( Text * ) & ( G.main->text.first );
2763         while( text ) {
2764                 if( !strcmp( txtname, GetName( text ) ) )
2765                         break;
2766                 text = text->id.next;
2767         }
2768
2769         /* uh-oh.... didn't find it */
2770         if( !text )
2771                 return NULL;
2772
2773         /* if previously compiled, free the object */
2774         /* (can't see how could be NULL, but check just in case) */ 
2775         if( text->compiled ){
2776                 Py_DECREF( (PyObject *)text->compiled );
2777         }
2778
2779         /* compile the buffer */
2780         buf = txt_to_buf( text );
2781         text->compiled = Py_CompileString( buf, GetName( text ),
2782                         Py_file_input );
2783         MEM_freeN( buf );
2784
2785         /* if compile failed.... return this error */
2786         if( PyErr_Occurred(  ) ) {
2787                 PyErr_Print(  );
2788                 BPY_free_compiled_text( text );
2789                 return NULL;
2790         }
2791
2792         /* make into a module */
2793         return PyImport_ExecCodeModule( name, text->compiled );
2794 }
2795
2796 /*
2797  * our reload() module, to handle reloading in-memory scripts
2798  */
2799
2800 static PyObject *blender_reload( PyObject * self, PyObject * args )
2801 {
2802         PyObject *exception, *err, *tb;
2803         PyObject *module = NULL;
2804         PyObject *newmodule = NULL;
2805
2806         /* check for a module arg */
2807         if( !PyArg_ParseTuple( args, "O:breload", &module ) )
2808                 return NULL;
2809
2810         /* try reimporting from file */
2811         newmodule = PyImport_ReloadModule( module );
2812         if( newmodule )
2813                 return newmodule;
2814
2815         /* no file, try importing from memory */
2816         PyErr_Fetch( &exception, &err, &tb );   /*restore for probable later use */
2817
2818         newmodule = reimportText( module );
2819         if( newmodule ) {               /* found module, ignore above exception */
2820                 PyErr_Clear(  );
2821                 Py_XDECREF( exception );
2822                 Py_XDECREF( err );
2823                 Py_XDECREF( tb );
2824         } else
2825                 PyErr_Restore( exception, err, tb );
2826
2827         return newmodule;
2828 }
2829
2830 static PyMethodDef breload[] = {
2831         {"blreload", blender_reload, METH_VARARGS, "our own reload"}
2832 };
2833
2834 void init_ourReload( void )
2835 {
2836         PyObject *m, *d;
2837         PyObject *reload = PyCFunction_New( breload, NULL );
2838
2839         m = PyImport_AddModule( "__builtin__" );
2840         d = PyModule_GetDict( m );
2841         EXPP_dict_set_item_str( d, "reload", reload );
2842 }