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