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