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