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