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