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