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