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