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