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