Merge from Harmonic Skeleton branch
[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_Merge(d, PyModule_GetDict(mod), 0); /* 0 - dont overwrite existing values */
1075                 
1076                 /* Only keep for backwards compat! - just import all math into root, they are standard */
1077                 PyDict_SetItemString(d, "math", mod);
1078                 PyDict_SetItemString(d, "m", mod);
1079                 Py_DECREF(mod);
1080         } 
1081
1082         mod = PyImport_ImportModule("Blender.Noise");
1083         if (mod) {
1084                 PyDict_SetItemString(d, "noise", mod);
1085                 PyDict_SetItemString(d, "n", mod);
1086                 Py_DECREF(mod);
1087         }
1088
1089         /* If there's a Blender text called pydrivers.py, import it.
1090          * Users can add their own functions to this module. */
1091         mod = importText("pydrivers"); /* can also use PyImport_Import() */
1092         if (mod) {
1093                 PyDict_SetItemString(d, "pydrivers", mod);
1094                 PyDict_SetItemString(d, "p", mod);
1095                 Py_DECREF(mod);
1096         }
1097         else
1098                 PyErr_Clear();
1099
1100         /* short aliases for some Get() functions: */
1101
1102         /* ob(obname) == Blender.Object.Get(obname) */
1103         mod = PyImport_ImportModule("Blender.Object");
1104         if (mod) {
1105                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1106                 Py_DECREF(mod);
1107                 if (fcn) {
1108                         PyDict_SetItemString(d, "ob", fcn);
1109                         Py_DECREF(fcn);
1110                 }
1111         }
1112         
1113         /* TODO - change these */
1114         /* me(meshname) == Blender.Mesh.Get(meshname) */
1115         mod = PyImport_ImportModule("Blender.Mesh");
1116         if (mod) {
1117                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1118                 Py_DECREF(mod);
1119                 if (fcn) {
1120                         PyDict_SetItemString(d, "me", fcn);
1121                         Py_DECREF(fcn);
1122                 }
1123         }
1124
1125         /* ma(matname) == Blender.Material.Get(matname) */
1126         mod = PyImport_ImportModule("Blender.Material");
1127         if (mod) {
1128                 PyObject *fcn = PyObject_GetAttrString(mod, "Get");
1129                 Py_DECREF(mod);
1130                 if (fcn) {
1131                         PyDict_SetItemString(d, "ma", fcn);
1132                         Py_DECREF(fcn);
1133                 }
1134         }
1135
1136         return 0;
1137 }
1138
1139 /* error return function for BPY_eval_pydriver */
1140 static float pydriver_error(IpoDriver *driver) {
1141
1142         if (bpy_pydriver_oblist)
1143                 bpy_pydriver_freeList();
1144
1145         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
1146                 PyDict_Clear(bpy_pydriver_Dict);
1147                 Py_DECREF(bpy_pydriver_Dict);
1148                 bpy_pydriver_Dict = NULL;
1149         }
1150
1151         driver->flag |= IPO_DRIVER_FLAG_INVALID; /* py expression failed */
1152         
1153         if (driver->ob)
1154                 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);
1155         else
1156                 fprintf(stderr, "\nError in Ipo Driver: No Object\nThis is the failed Python expression:\n'%s'\n\n", driver->name);
1157         
1158         PyErr_Print();
1159
1160         return 0.0f;
1161 }
1162
1163
1164 /********PyConstraints*********/
1165
1166 /* This function checks whether a text-buffer is a PyConstraint candidate.
1167  * It uses simple text parsing that could be easily confused!
1168  */
1169 int BPY_is_pyconstraint(Text *text)
1170 {
1171         TextLine *tline = text->lines.first;
1172
1173         if (tline && (tline->len > 10)) {
1174                 char *line = tline->line;
1175                 
1176                 /* Expected format: #BPYCONSTRAINT
1177                  * The actual checks are forgiving, so slight variations also work. */
1178                 if (line && line[0] == '#' && strstr(line, "BPYCONSTRAINT")) return 1;
1179         }
1180         return 0;
1181 }
1182
1183 /* This function is called to update PyConstraint data so that it is compatible with the script. 
1184  * Some of the allocating/freeing of memory for constraint targets occurs here, espcially
1185  * if the number of targets changes.
1186  */
1187 void BPY_pyconstraint_update(Object *owner, bConstraint *con)
1188 {
1189         bPythonConstraint *data= con->data;
1190         
1191         if (data->text) {       
1192                 /* script does exist. it is assumed that this is a valid pyconstraint script */
1193                 PyObject *globals;
1194                 PyObject *retval, *gval;
1195                 int num, i;
1196                 
1197                 /* clear the relevant flags first */
1198                 data->flag = 0;
1199                                 
1200                 /* populate globals dictionary */
1201                 globals = CreateGlobalDictionary();
1202                 retval = RunPython(data->text, globals);
1203                 
1204                 if (retval == NULL) {
1205                         BPY_Err_Handle(data->text->id.name);
1206                         ReleaseGlobalDictionary(globals);
1207                         data->flag |= PYCON_SCRIPTERROR;
1208                         return;
1209                 }
1210                 
1211                 Py_XDECREF(retval);
1212                 retval = NULL;
1213                 
1214                 /* try to find NUM_TARGETS */
1215                 gval = PyDict_GetItemString(globals, "NUM_TARGETS");
1216                 if ( (gval) && (num= PyInt_AsLong(gval)) ) {
1217                         /* NUM_TARGETS is defined... and non-zero */
1218                         bConstraintTarget *ct;
1219                         
1220                         /* check if it is valid (just make sure it is not negative)
1221                          *      TODO: PyInt_AsLong may return -1 as sign of invalid input... 
1222                          */
1223                         num = abs(num);
1224                         data->flag |= PYCON_USETARGETS;
1225                         
1226                         /* check if the number of targets has changed */
1227                         if (num < data->tarnum) {
1228                                 /* free a few targets */
1229                                 num= data->tarnum - num;
1230                                 for (i = 0; i < num; i++, data->tarnum--) {
1231                                         ct= data->targets.last;
1232                                         BLI_freelinkN(&data->targets, ct);
1233                                 }
1234                         }
1235                         else if (num > data->tarnum) {
1236                                 /* add a few targets */
1237                                 num = num - data->tarnum;
1238                                 for (i = 0; i < num; i++, data->tarnum++) {
1239                                         ct= MEM_callocN(sizeof(bConstraintTarget), "PyConTarget");
1240                                         BLI_addtail(&data->targets, ct);
1241                                 }
1242                         }
1243                         
1244                         /* validate targets */
1245                         con->flag &= ~CONSTRAINT_DISABLE;
1246                         for (ct= data->targets.first; ct; ct= ct->next) {
1247                                 if (!exist_object(ct->tar)) {
1248                                         ct->tar = NULL;
1249                                         con->flag |= CONSTRAINT_DISABLE;
1250                                         break;
1251                                 }
1252                                 
1253                                 if ((ct->tar == owner) && (ct->subtarget[0] != 0)) {
1254                                         if (get_named_bone(get_armature(owner), ct->subtarget) == NULL) {
1255                                                 con->flag |= CONSTRAINT_DISABLE;
1256                                                 break;
1257                                         }
1258                                 }
1259                         }
1260                         
1261                         /* clear globals */
1262                         ReleaseGlobalDictionary(globals);
1263                 }
1264                 else {
1265                         /* NUM_TARGETS is not defined or equals 0 */
1266                         ReleaseGlobalDictionary(globals);
1267                         
1268                         /* free all targets */
1269                         BLI_freelistN(&data->targets);
1270                         data->tarnum = 0;
1271                         data->flag &= ~PYCON_USETARGETS;
1272                         
1273                         return;
1274                 }
1275         }
1276         else {
1277                 /* no script, so clear any settings/data now */
1278                 data->tarnum = 0;
1279                 data->flag = 0;
1280                 con->flag &= ~CONSTRAINT_DISABLE;
1281                 
1282                 BLI_freelistN(&data->targets);
1283                 
1284                 /* supposedly this should still leave the base struct... */
1285                 IDP_FreeProperty(data->prop);
1286         }
1287 }
1288
1289 /* PyConstraints Evaluation Function (only called from evaluate_constraint)
1290  * This function is responsible for modifying the ownermat that it is passed. 
1291  */
1292 void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase *targets)
1293 {
1294         PyObject *srcmat, *tarmat, *tarmats, *idprop;
1295         PyObject *globals;
1296         PyObject *gval;
1297         PyObject *pyargs, *retval;
1298         bConstraintTarget *ct;
1299         MatrixObject *retmat;
1300         int row, col, index;
1301         
1302         if (!con->text) return;
1303         if (con->flag & PYCON_SCRIPTERROR) return;
1304         
1305         globals = CreateGlobalDictionary();
1306         
1307         /* wrap blender-data as PyObjects for evaluation 
1308          *      - we expose the owner's matrix as pymatrix
1309          *      - id-properties are wrapped using the id-properties pyapi
1310          *      - targets are presented as a list of matrices
1311          */
1312         srcmat = newMatrixObject((float *)cob->matrix, 4, 4, Py_NEW);
1313         idprop = BPy_Wrap_IDProperty(NULL, con->prop, NULL);
1314         
1315         tarmats= PyList_New(con->tarnum); 
1316         for (ct=targets->first, index=0; ct; ct=ct->next, index++) {
1317                 tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
1318                 PyList_SET_ITEM(tarmats, index, tarmat);
1319         }
1320         
1321         
1322 /*  since I can't remember what the armature weakrefs do, I'll just leave this here
1323     commented out.  This function was based on pydrivers, and it might still be relevent.
1324         if( !setup_armature_weakrefs()){
1325                 fprintf( stderr, "Oops - weakref dict setup\n");
1326                 return result;
1327         }
1328 */
1329         
1330         retval = RunPython(con->text, globals);
1331         
1332         if (retval == NULL) {
1333                 BPY_Err_Handle(con->text->id.name);
1334                 con->flag |= PYCON_SCRIPTERROR;
1335                 
1336                 /* free temp objects */
1337                 Py_XDECREF(idprop);
1338                 Py_XDECREF(srcmat);
1339                 Py_XDECREF(tarmats);
1340                 
1341                 ReleaseGlobalDictionary(globals);
1342                 
1343                 return;
1344         }
1345
1346         if (retval) {Py_XDECREF( retval );}
1347         retval = NULL;
1348         
1349         gval = PyDict_GetItemString(globals, "doConstraint");
1350         if (!gval) {
1351                 printf("ERROR: no doConstraint function in constraint!\n");
1352                 
1353                 /* free temp objects */
1354                 Py_XDECREF(idprop);
1355                 Py_XDECREF(srcmat);
1356                 Py_XDECREF(tarmats);
1357                 
1358                 ReleaseGlobalDictionary(globals);
1359                 
1360                 return;
1361         }
1362         
1363         /* Now for the fun part! Try and find the functions we need. */
1364         if (PyFunction_Check(gval)) {
1365                 pyargs = Py_BuildValue("OOO", srcmat, tarmats, idprop);
1366                 retval = PyObject_CallObject(gval, pyargs);
1367                 Py_XDECREF(pyargs);
1368         } 
1369         else {
1370                 printf("ERROR: doConstraint is supposed to be a function!\n");
1371                 con->flag |= PYCON_SCRIPTERROR;
1372                 
1373                 Py_XDECREF(idprop);
1374                 Py_XDECREF(srcmat);
1375                 Py_XDECREF(tarmats);
1376                 
1377                 ReleaseGlobalDictionary(globals);
1378                 
1379                 return;
1380         }
1381         
1382         if (!retval) {
1383                 BPY_Err_Handle(con->text->id.name);
1384                 con->flag |= PYCON_SCRIPTERROR;
1385                 
1386                 /* free temp objects */
1387                 Py_XDECREF(idprop);
1388                 Py_XDECREF(srcmat);
1389                 Py_XDECREF(tarmats);
1390                 
1391                 ReleaseGlobalDictionary(globals);
1392                 
1393                 return;
1394         }
1395         
1396         
1397         if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1398                 printf("Error in PyConstraint - doConstraint: Function not returning a matrix!\n");
1399                 con->flag |= PYCON_SCRIPTERROR;
1400                 
1401                 Py_XDECREF(idprop);
1402                 Py_XDECREF(srcmat);
1403                 Py_XDECREF(tarmats);
1404                 Py_XDECREF(retval);
1405                 
1406                 ReleaseGlobalDictionary(globals);
1407                 
1408                 return;
1409         }
1410         
1411         retmat = (MatrixObject *)retval;
1412         if (retmat->rowSize != 4 || retmat->colSize != 4) {
1413                 printf("Error in PyConstraint - doConstraint: Matrix returned is the wrong size!\n");
1414                 con->flag |= PYCON_SCRIPTERROR;
1415                 
1416                 Py_XDECREF(idprop);
1417                 Py_XDECREF(srcmat);
1418                 Py_XDECREF(tarmats);
1419                 Py_XDECREF(retval);
1420                 
1421                 ReleaseGlobalDictionary(globals);
1422                 
1423                 return;
1424         }       
1425
1426         /* this is the reverse of code taken from newMatrix() */
1427         for(row = 0; row < 4; row++) {
1428                 for(col = 0; col < 4; col++) {
1429                         cob->matrix[row][col] = retmat->contigPtr[row*4+col];
1430                 }
1431         }
1432         
1433         /* free temp objects */
1434         Py_XDECREF(idprop);
1435         Py_XDECREF(srcmat);
1436         Py_XDECREF(tarmats);
1437         Py_XDECREF(retval);
1438         
1439         /* clear globals */
1440         ReleaseGlobalDictionary(globals);
1441 }
1442
1443 /* This evaluates the target matrix for each target the PyConstraint uses.
1444  * NOTE: it only does one target at a time!
1445  */
1446 void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
1447 {
1448         PyObject *tar, *subtar;
1449         PyObject *tarmat, *idprop;
1450         PyObject *globals;
1451         PyObject *gval;
1452         PyObject *pyargs, *retval;
1453         MatrixObject *retmat;
1454         int row, col;
1455         
1456         if (!con->text) return;
1457         if (con->flag & PYCON_SCRIPTERROR) return;
1458         if (!ct) return;
1459         
1460         globals = CreateGlobalDictionary();
1461         
1462         tar = Object_CreatePyObject(ct->tar);
1463         if ((ct->tar) && (ct->tar->type==OB_ARMATURE)) {
1464                 bPoseChannel *pchan;
1465                 pchan = get_pose_channel(ct->tar->pose, ct->subtarget);
1466                 subtar = PyPoseBone_FromPosechannel(pchan);
1467         }
1468         else
1469                 subtar = PyString_FromString(ct->subtarget);
1470         
1471         tarmat = newMatrixObject((float *)ct->matrix, 4, 4, Py_NEW);
1472         idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1473         
1474 /*  since I can't remember what the armature weakrefs do, I'll just leave this here
1475     commented out.  This function was based on pydrivers, and it might still be relevent.
1476         if( !setup_armature_weakrefs()){
1477                 fprintf( stderr, "Oops - weakref dict setup\n");
1478                 return result;
1479         }
1480 */
1481         retval = RunPython(con->text, globals);
1482
1483         if (retval == NULL) {
1484                 BPY_Err_Handle(con->text->id.name);
1485                 con->flag |= PYCON_SCRIPTERROR;
1486                 
1487                 /* free temp objects */
1488                 Py_XDECREF(tar);
1489                 Py_XDECREF(subtar);
1490                 Py_XDECREF(idprop);
1491                 Py_XDECREF(tarmat);
1492                 
1493                 ReleaseGlobalDictionary(globals);
1494                 
1495                 return;
1496         }
1497
1498         Py_XDECREF(retval);
1499         retval = NULL;
1500         
1501         /* try to find doTarget function to set the target matrix */
1502         gval = PyDict_GetItemString(globals, "doTarget");
1503         if (!gval) {
1504                 /* free temp objects */
1505                 Py_XDECREF(tar);
1506                 Py_XDECREF(subtar);
1507                 Py_XDECREF(idprop);
1508                 Py_XDECREF(tarmat);
1509                 
1510                 ReleaseGlobalDictionary(globals);
1511                 
1512                 return;
1513         }
1514         
1515         /* Now for the fun part! Try and find the functions we need.*/
1516         if (PyFunction_Check(gval)) {
1517                 pyargs = Py_BuildValue("OOOO", tar, subtar, tarmat, idprop);
1518                 retval = PyObject_CallObject(gval, pyargs);
1519                 Py_XDECREF(pyargs);
1520         } 
1521         else {
1522                 printf("ERROR: doTarget is supposed to be a function!\n");
1523                 con->flag |= PYCON_SCRIPTERROR;
1524                 
1525                 Py_XDECREF(tar);
1526                 Py_XDECREF(subtar);
1527                 Py_XDECREF(idprop);
1528                 Py_XDECREF(tarmat);
1529                 
1530                 ReleaseGlobalDictionary(globals);
1531                 return;
1532         }
1533         
1534         if (!retval) {
1535                 BPY_Err_Handle(con->text->id.name);
1536                 con->flag |= PYCON_SCRIPTERROR;
1537                 
1538                 
1539                 /* free temp objects */
1540                 Py_XDECREF(tar);
1541                 Py_XDECREF(subtar);
1542                 Py_XDECREF(idprop);
1543                 Py_XDECREF(tarmat);
1544                 
1545                 ReleaseGlobalDictionary(globals);
1546                 return;
1547         }
1548         
1549         if (!PyObject_TypeCheck(retval, &matrix_Type)) {
1550                 con->flag |= PYCON_SCRIPTERROR;
1551                 
1552                 Py_XDECREF(tar);
1553                 Py_XDECREF(subtar);
1554                 Py_XDECREF(idprop);
1555                 Py_XDECREF(tarmat);
1556                 Py_XDECREF(retval);
1557                 
1558                 ReleaseGlobalDictionary(globals);
1559                 return;
1560         }
1561         
1562         retmat = (MatrixObject *)retval;
1563         if (retmat->rowSize != 4 || retmat->colSize != 4) {
1564                 printf("Error in PyConstraint - doTarget: Matrix returned is the wrong size!\n");
1565                 con->flag |= PYCON_SCRIPTERROR;
1566                 
1567                 Py_XDECREF(tar);
1568                 Py_XDECREF(subtar);
1569                 Py_XDECREF(idprop);
1570                 Py_XDECREF(tarmat);
1571                 Py_XDECREF(retval);
1572                 
1573                 ReleaseGlobalDictionary(globals);
1574                 return;
1575         }       
1576
1577         /* this is the reverse of code taken from newMatrix() */
1578         for(row = 0; row < 4; row++) {
1579                 for(col = 0; col < 4; col++) {
1580                         ct->matrix[row][col] = retmat->contigPtr[row*4+col];
1581                 }
1582         }
1583         
1584         /* free temp objects */
1585         Py_XDECREF(tar);
1586         Py_XDECREF(subtar);
1587         Py_XDECREF(idprop);
1588         Py_XDECREF(tarmat);
1589         Py_XDECREF(retval);
1590         
1591         /* clear globals */
1592         ReleaseGlobalDictionary(globals);
1593 }
1594
1595 /* This draws+handles the user-defined interface for editing pyconstraints idprops */
1596 void BPY_pyconstraint_settings(void *arg1, void *arg2)
1597 {
1598         bPythonConstraint *con= (bPythonConstraint *)arg1;
1599         PyObject *idprop;
1600         PyObject *globals;
1601         PyObject *gval;
1602         PyObject *retval;
1603         
1604         if (!con->text) return;
1605         if (con->flag & PYCON_SCRIPTERROR) return;
1606         
1607         globals = CreateGlobalDictionary();
1608         
1609         idprop = BPy_Wrap_IDProperty( NULL, con->prop, NULL);
1610         
1611         retval = RunPython(con->text, globals);
1612
1613         if (retval == NULL) {
1614                 BPY_Err_Handle(con->text->id.name);
1615                 ReleaseGlobalDictionary(globals);
1616                 con->flag |= PYCON_SCRIPTERROR;
1617         
1618                 /* free temp objects */
1619                 Py_XDECREF(idprop);
1620                 return;
1621         }
1622
1623         if (retval) {Py_XDECREF( retval );}
1624         retval = NULL;
1625         
1626         gval = PyDict_GetItemString(globals, "getSettings");
1627         if (!gval) {
1628                 printf("ERROR: no getSettings function in constraint!\n");
1629                 
1630                 /* free temp objects */
1631                 ReleaseGlobalDictionary( globals );
1632                 Py_XDECREF(idprop);
1633                 return;
1634         }
1635         
1636         /* Now for the fun part! Try and find the functions we need. */
1637         if (PyFunction_Check(gval)) {
1638                 retval = PyObject_CallFunction(gval, "O", idprop);
1639         } 
1640         else {
1641                 printf("ERROR: getSettings is supposed to be a function!\n");
1642                 ReleaseGlobalDictionary( globals );
1643                 
1644                 Py_XDECREF(idprop);
1645                 return;
1646         }
1647         
1648         if (!retval) {
1649                 BPY_Err_Handle(con->text->id.name);
1650                 con->flag |= PYCON_SCRIPTERROR;
1651                 
1652                 /* free temp objects */
1653                 ReleaseGlobalDictionary(globals);
1654                 Py_XDECREF(idprop);
1655                 return;
1656         }
1657         else {
1658                 /* clear globals */
1659                 ReleaseGlobalDictionary(globals);
1660                 
1661                 /* free temp objects */
1662                 Py_XDECREF(idprop);
1663                 Py_DECREF(retval);
1664                 return;
1665         }
1666 }
1667
1668 /* Update function, it gets rid of pydrivers global dictionary, forcing
1669  * BPY_pydriver_eval to recreate it. This function is used to force
1670  * reloading the Blender text module "pydrivers.py", if available, so
1671  * updates in it reach pydriver evaluation. */
1672 void BPY_pydriver_update(void)
1673 {
1674         if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
1675                 PyDict_Clear(bpy_pydriver_Dict);
1676                 Py_DECREF(bpy_pydriver_Dict);
1677                 bpy_pydriver_Dict = NULL;
1678         }
1679
1680         return;
1681 }
1682
1683 /* for depsgraph.c, runs py expr once to collect all refs. made
1684  * to objects (self refs. to the object that owns the py driver
1685  * are not allowed). */
1686 struct Object **BPY_pydriver_get_objects(IpoDriver *driver)
1687 {
1688         /*if (!driver || !driver->ob || driver->name[0] == '\0')
1689                 return NULL;*/
1690
1691         /*PyErr_Clear();*/
1692
1693         /* clear the flag that marks invalid python expressions */
1694         driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
1695
1696         /* tell we're running a pydriver, so Get() functions know they need
1697          * to add the requested obj to our list */
1698         bpy_pydriver_running(1);
1699
1700         /* append driver owner object as the 1st ob in the list;
1701          * we put it there to make sure it is not itself referenced in
1702          * its pydriver expression */
1703         bpy_pydriver_appendToList(driver->ob);
1704
1705         /* this will append any other ob referenced in expr (driver->name)
1706          * or set the driver's error flag if driver's py expression fails */
1707         BPY_pydriver_eval(driver);
1708
1709         bpy_pydriver_running(0); /* ok, we're done */
1710
1711         return bpy_pydriver_obArrayFromList(); /* NULL if eval failed */
1712 }
1713
1714 /* This evals py driver expressions, 'expr' is a Python expression that
1715  * should evaluate to a float number, which is returned. */
1716 float BPY_pydriver_eval(IpoDriver *driver)
1717 {
1718         char *expr = NULL;
1719         PyObject *retval, *bpy_ob = NULL;
1720         float result = 0.0f; /* default return */
1721         int setitem_retval;
1722
1723         if (!driver) return result;
1724
1725         expr = driver->name; /* the py expression to be evaluated */
1726         if (!expr || expr[0]=='\0') return result;
1727
1728         if (!bpy_pydriver_Dict) {
1729                 if (bpy_pydriver_create_dict() != 0) {
1730                         fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
1731                         return result;
1732                 }
1733         }
1734
1735         if (driver->ob)
1736                 bpy_ob = Object_CreatePyObject(driver->ob);
1737
1738         if (!bpy_ob) {
1739                 Py_INCREF(Py_None);
1740                 bpy_ob = Py_None;
1741         }
1742
1743         setitem_retval = EXPP_dict_set_item_str(bpy_pydriver_Dict, "self", bpy_ob);
1744
1745         if( !setup_armature_weakrefs()){
1746                 fprintf( stderr, "Oops - weakref dict setup\n");
1747                 return result;
1748         }
1749
1750         retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict,
1751                 bpy_pydriver_Dict);
1752
1753         if (retval == NULL) {
1754                 return pydriver_error(driver);
1755         }
1756
1757         result = ( float )PyFloat_AsDouble( retval );
1758         
1759         if (result == -1 && PyErr_Occurred()) 
1760                 return pydriver_error(driver);
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                 PyDict_SetItemString(   g_blenderdict, "bylink", Py_True);
1969                 EXPP_dict_set_item_str( g_blenderdict, "link", value );
1970                 EXPP_dict_set_item_str( g_blenderdict, "event",
1971                                       PyString_FromString( event_to_name
1972                                                            ( event ) ) );
1973                 if (event == SCRIPT_POSTRENDER) event = SCRIPT_RENDER;
1974
1975                 for( index = 0; index < scriptlink->totscript; index++ ) {
1976                         if( ( scriptlink->flag[index] == event ) &&
1977                             ( scriptlink->scripts[index] != NULL ) ) {
1978                                 dict = CreateGlobalDictionary(  );
1979                                 ret = RunPython( ( Text * ) scriptlink->
1980                                                  scripts[index], dict );
1981                                 ReleaseGlobalDictionary( dict );
1982
1983                                 if( !ret ) {
1984                                         /* Failed execution of the script */
1985                                         BPY_Err_Handle( scriptlink->
1986                                                         scripts[index]->name +
1987                                                         2 );
1988                                         //BPY_end_python ();
1989                                         //BPY_start_python ();
1990                                 } else {
1991                                         Py_DECREF( ret );
1992                                 }
1993                                 /* If a scriptlink has just loaded a new .blend file, the
1994                                  * scriptlink pointer became invalid (see api2_2x/Blender.c),
1995                                  * so we stop here. */
1996                                 if( during_scriptlink(  ) == -1 ) {
1997                                         during_slink = 1;
1998                                         break;
1999                                 }
2000                         }
2001                 }
2002
2003                 disable_where_scriptlink( (short)(during_slink - 1) );
2004
2005                 /* cleanup bylink flag and clear link so PyObject
2006                  * can be released 
2007                  */
2008                 PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
2009                 PyDict_SetItemString( g_blenderdict, "link", Py_None );
2010                 EXPP_dict_set_item_str( g_blenderdict, "event", PyString_FromString( "" ) );
2011         }
2012 }
2013
2014
2015 /* SPACE HANDLERS */
2016
2017 /* These are special script links that can be assigned to ScrArea's to
2018  * (EVENT type) receive events sent to a given space (and use or ignore them) or
2019  * (DRAW type) be called after the space is drawn, to draw anything on top of
2020  * the space area. */
2021
2022 /* How to add space handlers to other spaces:
2023  * - add the space event defines to DNA_scriptlink_types.h, as done for
2024  *   3d view: SPACEHANDLER_VIEW3D_EVENT, for example;
2025  * - add the new defines to Blender.SpaceHandler dictionary in Blender.c;
2026  * - check space.c for how to call the event handlers;
2027  * - check drawview.c for how to call the draw handlers;
2028  * - check header_view3d.c for how to add the "Space Handler Scripts" menu.
2029  * Note: DRAW handlers should be called with 'event = 0', chech drawview.c */
2030
2031 int BPY_has_spacehandler(Text *text, ScrArea *sa)
2032 {
2033         ScriptLink *slink;
2034         int index;
2035
2036         if (!sa || !text) return 0;
2037
2038         slink = &sa->scriptlink;
2039
2040         for (index = 0; index < slink->totscript; index++) {
2041                 if (slink->scripts[index] && (slink->scripts[index] == (ID *)text))
2042                         return 1;
2043         }
2044
2045         return 0;       
2046 }
2047
2048 int BPY_is_spacehandler(Text *text, char spacetype)
2049 {
2050         TextLine *tline = text->lines.first;
2051         unsigned short type = 0;
2052
2053         if (tline && (tline->len > 10)) {
2054                 char *line = tline->line;
2055
2056                 /* Expected format: # SPACEHANDLER.SPACE.TYPE
2057                  * Ex: # SPACEHANDLER.VIEW3D.DRAW
2058                  * The actual checks are forgiving, so slight variations also work. */
2059                 if (line && line[0] == '#' && strstr(line, "HANDLER")) {
2060                         line++; /* skip '#' */
2061
2062                         /* only done for 3D View right now, trivial to add for others: */
2063                         switch (spacetype) {
2064                                 case SPACE_VIEW3D:
2065                                         if (strstr(line, "3D")) { /* VIEW3D, 3DVIEW */
2066                                                 if (strstr(line, "DRAW")) type = SPACEHANDLER_VIEW3D_DRAW;
2067                                                 else if (strstr(line, "EVENT")) type = SPACEHANDLER_VIEW3D_EVENT;
2068                                         }
2069                                         break;
2070                         }
2071                 }
2072         }
2073         return type; /* 0 if not a space handler */
2074 }
2075
2076 int BPY_del_spacehandler(Text *text, ScrArea *sa)
2077 {
2078         ScriptLink *slink;
2079         int i, j;
2080
2081         if (!sa || !text) return -1;
2082
2083         slink = &sa->scriptlink;
2084         if (slink->totscript < 1) return -1;
2085
2086         for (i = 0; i < slink->totscript; i++) {
2087                 if (text == (Text *)slink->scripts[i]) {
2088
2089                         for (j = i; j < slink->totscript - 1; j++) {
2090                                 slink->flag[j] = slink->flag[j+1];
2091                                 slink->scripts[j] = slink->scripts[j+1];
2092                         }
2093                         slink->totscript--;
2094                         /* like done in buttons_script.c we just free memory
2095                          * if all slinks have been removed -- less fragmentation,
2096                          * these should be quite small arrays */
2097                         if (slink->totscript == 0) {
2098                                 if (slink->scripts) MEM_freeN(slink->scripts);
2099                                 if (slink->flag) MEM_freeN(slink->flag);
2100                                 break;
2101                         }
2102                 }
2103         }
2104         return 0;
2105 }
2106
2107 int BPY_add_spacehandler(Text *text, ScrArea *sa, char spacetype)
2108 {
2109         unsigned short handlertype;
2110
2111         if (!sa || !text) return -1;
2112
2113         handlertype = (unsigned short)BPY_is_spacehandler(text, spacetype);
2114
2115         if (handlertype) {
2116                 ScriptLink *slink = &sa->scriptlink;
2117                 void *stmp, *ftmp;
2118                 unsigned short space_event = SPACEHANDLER_VIEW3D_EVENT;
2119
2120                 /* extend slink */
2121
2122                 stmp= slink->scripts;           
2123                 slink->scripts= MEM_mallocN(sizeof(ID*)*(slink->totscript+1),
2124                         "spacehandlerscripts");
2125         
2126                 ftmp= slink->flag;              
2127                 slink->flag= MEM_mallocN(sizeof(short*)*(slink->totscript+1),
2128                         "spacehandlerflags");
2129         
2130                 if (slink->totscript) {
2131                         memcpy(slink->scripts, stmp, sizeof(ID*)*(slink->totscript));
2132                         MEM_freeN(stmp);
2133
2134                         memcpy(slink->flag, ftmp, sizeof(short)*(slink->totscript));
2135                         MEM_freeN(ftmp);
2136                 }
2137
2138                 switch (spacetype) {
2139                         case SPACE_VIEW3D:
2140                                 if (handlertype == 1) space_event = SPACEHANDLER_VIEW3D_EVENT;
2141                                 else space_event = SPACEHANDLER_VIEW3D_DRAW;
2142                                 break;
2143                         default:
2144                                 break;
2145                 }
2146
2147                 slink->scripts[slink->totscript] = (ID *)text;
2148                 slink->flag[slink->totscript]= space_event;
2149
2150                 slink->totscript++;
2151                 slink->actscript = slink->totscript;
2152
2153         }
2154         return 0;
2155 }
2156
2157 int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
2158         unsigned short space_event )
2159 {
2160         ScriptLink *scriptlink;
2161         int retval = 0;
2162         
2163         if (!sa || !(G.f & G_DOSCRIPTLINKS)) return 0;
2164         
2165         scriptlink = &sa->scriptlink;
2166
2167         if (scriptlink->totscript > 0) {
2168                 PyObject *dict;
2169                 PyObject *ret;
2170                 int index, during_slink = during_scriptlink();
2171
2172                 /* invalid scriptlinks (new .blend was just loaded), return */
2173                 if (during_slink < 0) return 0;
2174
2175                 /* tell we're running a scriptlink.  The sum also tells if this script
2176                  * is running nested inside another.  Blender.Load needs this info to
2177                  * avoid trouble with invalid slink pointers.
2178                  * Update (test): allow EVENT space handlers to call file/image selectors,
2179                  * still disabled for DRAW space handlers: */
2180                 if (event == 0) { /* event = 0: DRAW space handler */
2181                         during_slink++;
2182                         disable_where_scriptlink( (short)during_slink );
2183                 }
2184
2185                 if( !setup_armature_weakrefs()){
2186                         printf("Oops - weakref dict, this is a bug\n");
2187                         return 0;
2188                 }
2189                 
2190                 /* set globals in Blender module to identify space handler scriptlink */
2191                 PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
2192                 /* unlike normal scriptlinks, here Blender.link is int (space event type) */
2193                 EXPP_dict_set_item_str(g_blenderdict, "link", PyInt_FromLong(space_event));
2194                 /* note: DRAW space_events set event to 0 */
2195                 EXPP_dict_set_item_str(g_blenderdict, "event", PyInt_FromLong(event));
2196                 /* now run all assigned space handlers for this space and space_event */
2197                 for( index = 0; index < scriptlink->totscript; index++ ) {
2198
2199                         /* for DRAW handlers: */
2200                         if (event == 0) {
2201                                 glPushAttrib(GL_ALL_ATTRIB_BITS);
2202                                 glMatrixMode(GL_PROJECTION);
2203                                 glPushMatrix();
2204                                 glMatrixMode(GL_MODELVIEW);
2205                                 glPushMatrix();
2206                         }
2207
2208                         if( ( scriptlink->flag[index] == space_event ) &&
2209                             ( scriptlink->scripts[index] != NULL ) ) {
2210                                 dict = CreateGlobalDictionary();
2211                                 ret = RunPython( ( Text * ) scriptlink->scripts[index], dict );
2212                                 ReleaseGlobalDictionary( dict );
2213
2214                                 if (!ret) { /* Failed execution of the script */
2215                                         BPY_Err_Handle( scriptlink->scripts[index]->name+2 );
2216                                 } else {
2217                                         Py_DECREF(ret);
2218
2219                                         /* an EVENT type (event != 0) script can either accept an event or
2220                                          * ignore it:
2221                                          * if the script sets Blender.event to None it accepted it;
2222                                          * otherwise the space's event handling callback that called us
2223                                          * can go on processing the event */
2224                                         if (event && (PyDict_GetItemString(g_blenderdict,"event") == Py_None))
2225                                                 retval = 1; /* event was swallowed */
2226                                 }
2227
2228                                 /* If a scriptlink has just loaded a new .blend file, the
2229                                  * scriptlink pointer became invalid (see api2_2x/Blender.c),
2230                                  * so we stop here. */
2231                                 if( during_scriptlink(  ) == -1 ) {
2232                                         during_slink = 1;
2233                                         if (event == 0) glPopAttrib();
2234                                         break;
2235                                 }
2236                         }
2237
2238                         /* for DRAW handlers: */
2239                         if (event == 0) {
2240                                 glMatrixMode(GL_PROJECTION);
2241                                 glPopMatrix();
2242                                 glMatrixMode(GL_MODELVIEW);
2243                                 glPopMatrix();
2244                                 glPopAttrib();
2245                                 disable_where_scriptlink( (short)(during_slink - 1) );
2246                         }
2247
2248                 }
2249
2250                 PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
2251                 PyDict_SetItemString(g_blenderdict, "link", Py_None );
2252                 EXPP_dict_set_item_str(g_blenderdict, "event", PyString_FromString(""));
2253         }
2254         
2255         /* retval:
2256          * space_event is of type EVENT:
2257          * 0 - event was returned,
2258          * 1 - event was processed;
2259          * space_event is of type DRAW:
2260          * 0 always */
2261
2262         return retval;
2263 }
2264
2265 /*****************************************************************************
2266 * Description:  
2267 * Notes:
2268 *****************************************************************************/
2269 void BPY_free_scriptlink( struct ScriptLink *slink )
2270 {
2271         if( slink->totscript ) {
2272                 if( slink->flag ) {
2273                         MEM_freeN( slink->flag );
2274                         slink->flag= NULL;
2275                 }
2276                 if( slink->scripts ) {
2277                         MEM_freeN( slink->scripts );
2278                         slink->scripts= NULL;
2279                 }
2280         }
2281
2282         return;
2283 }
2284
2285 static int CheckAllSpaceHandlers(Text *text)
2286 {
2287         bScreen *screen;
2288         ScrArea *sa;
2289         ScriptLink *slink;
2290         int fixed = 0;
2291
2292         for (screen = G.main->screen.first; screen; screen = screen->id.next) {
2293                 for (sa = screen->areabase.first; sa; sa = sa->next) {
2294                         slink = &sa->scriptlink;
2295                         if (!slink->totscript) continue;
2296                         if (BPY_del_spacehandler(text, sa) == 0) fixed++;
2297                 }
2298         }
2299         return fixed;
2300 }
2301
2302 static int CheckAllScriptsFromList( ListBase * list, Text * text )
2303 {
2304         ID *id;
2305         ScriptLink *scriptlink;
2306         int index;
2307         int fixed = 0;
2308
2309         id = list->first;
2310
2311         while( id != NULL ) {
2312                 scriptlink = ID_getScriptlink( id );
2313                 if( scriptlink && scriptlink->totscript ) {
2314                         for( index = 0; index < scriptlink->totscript; index++) {
2315                                 if ((Text *)scriptlink->scripts[index] == text) {
2316                                         scriptlink->scripts[index] = NULL;
2317                                         fixed++;
2318                                 }
2319                         }
2320                 }
2321                 id = id->next;
2322         }
2323
2324         return fixed;
2325 }
2326
2327 /* When a Text is deleted, we need to unlink it from eventual scriptlinks */
2328 int BPY_check_all_scriptlinks( Text * text )
2329 {
2330         int fixed = 0;
2331         fixed += CheckAllScriptsFromList( &( G.main->object ), text );
2332         fixed += CheckAllScriptsFromList( &( G.main->lamp ), text );
2333         fixed += CheckAllScriptsFromList( &( G.main->camera ), text );
2334         fixed += CheckAllScriptsFromList( &( G.main->mat ), text );
2335         fixed += CheckAllScriptsFromList( &( G.main->world ), text );
2336         fixed += CheckAllScriptsFromList( &( G.main->scene ), text );
2337         fixed += CheckAllSpaceHandlers(text);
2338
2339         return fixed;
2340 }
2341
2342 /*****************************************************************************
2343 * Description: 
2344 * Notes:
2345 *****************************************************************************/
2346 void BPY_copy_scriptlink( struct ScriptLink *scriptlink )
2347 {
2348         void *tmp;
2349
2350         if( scriptlink->totscript ) {
2351
2352                 tmp = scriptlink->scripts;
2353                 scriptlink->scripts =
2354                         MEM_mallocN( sizeof( ID * ) * scriptlink->totscript,
2355                                      "scriptlistL" );
2356                 memcpy( scriptlink->scripts, tmp,
2357                         sizeof( ID * ) * scriptlink->totscript );
2358
2359                 tmp = scriptlink->flag;
2360                 scriptlink->flag =
2361                         MEM_mallocN( sizeof( short ) * scriptlink->totscript,
2362                                      "scriptlistF" );
2363                 memcpy( scriptlink->flag, tmp,
2364                         sizeof( short ) * scriptlink->totscript );
2365         }
2366
2367         return;
2368 }
2369
2370 /****************************************************************************
2371 * Description:
2372 * Notes:                Not implemented yet
2373 *****************************************************************************/
2374 int BPY_call_importloader( char *name )
2375 {                       /* XXX Should this function go away from Blender? */
2376         printf( "In BPY_call_importloader(name=%s)\n", name );
2377         return ( 0 );
2378 }
2379
2380 /*****************************************************************************
2381 * Private functions
2382 *****************************************************************************/
2383
2384 /*****************************************************************************
2385 * Description: This function executes the python script passed by text. 
2386 *               The Python dictionary containing global variables needs to
2387 *               be passed in globaldict.
2388 *****************************************************************************/
2389 PyObject *RunPython( Text * text, PyObject * globaldict )
2390 {
2391         char *buf = NULL;
2392
2393 /* The script text is compiled to Python bytecode and saved at text->compiled
2394  * to speed-up execution if the user executes the script multiple times */
2395
2396         if( !text->compiled ) { /* if it wasn't already compiled, do it now */
2397                 buf = txt_to_buf( text );
2398
2399                 text->compiled =
2400                         Py_CompileString( buf, GetName( text ),
2401                                           Py_file_input );
2402
2403                 MEM_freeN( buf );
2404
2405                 if( PyErr_Occurred(  ) ) {
2406                         BPY_free_compiled_text( text );
2407                         return NULL;
2408                 }
2409
2410         }
2411
2412         return PyEval_EvalCode( text->compiled, globaldict, globaldict );
2413 }
2414
2415 /*****************************************************************************
2416 * Description: This function returns the value of the name field of the 
2417 *       given Text struct.
2418 *****************************************************************************/
2419 char *GetName( Text * text )
2420 {
2421         return ( text->id.name + 2 );
2422 }
2423
2424 /*****************************************************************************
2425 * Description: This function creates a new Python dictionary object.
2426 *****************************************************************************/
2427 PyObject *CreateGlobalDictionary( void )
2428 {
2429         PyObject *dict = PyDict_New(  );
2430
2431         PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins(  ) );
2432         EXPP_dict_set_item_str( dict, "__name__",
2433                               PyString_FromString( "__main__" ) );
2434
2435         return dict;
2436 }
2437
2438 /*****************************************************************************
2439 * Description: This function deletes a given Python dictionary object.
2440 *****************************************************************************/
2441 void ReleaseGlobalDictionary( PyObject * dict )
2442 {
2443         PyDict_Clear( dict );
2444         Py_DECREF( dict );      /* Release dictionary. */
2445
2446         return;
2447 }
2448
2449 /***************************************************************************
2450 * Description: This function runs all scripts (if any) present in the
2451 *               list argument. The event by which the function has been 
2452 *               called, is passed in the event argument.
2453 *****************************************************************************/
2454 void DoAllScriptsFromList( ListBase * list, short event )
2455 {
2456         ID *id;
2457
2458         id = list->first;
2459
2460         while( id != NULL ) {
2461                 BPY_do_pyscript( id, event );
2462                 id = id->next;
2463         }
2464
2465         return;
2466 }
2467
2468 PyObject *importText( char *name )
2469 {
2470         Text *text;
2471         char *txtname;
2472         char *buf = NULL;
2473         int namelen = strlen( name );
2474
2475         txtname = malloc( namelen + 3 + 1 );
2476         if( !txtname )
2477                 return NULL;
2478
2479         memcpy( txtname, name, namelen );
2480         memcpy( &txtname[namelen], ".py", 4 );
2481
2482         text = ( Text * ) & ( G.main->text.first );
2483
2484         while( text ) {
2485                 if( !strcmp( txtname, GetName( text ) ) )
2486                         break;
2487                 text = text->id.next;
2488         }
2489
2490         if( !text ) {
2491                 free( txtname );
2492                 return NULL;
2493         }
2494
2495         if( !text->compiled ) {
2496                 buf = txt_to_buf( text );
2497                 text->compiled =
2498                         Py_CompileString( buf, GetName( text ),
2499                                           Py_file_input );
2500                 MEM_freeN( buf );
2501
2502                 if( PyErr_Occurred(  ) ) {
2503                         PyErr_Print(  );
2504                         BPY_free_compiled_text( text );
2505                         free( txtname );
2506                         return NULL;
2507                 }
2508         }
2509
2510         free( txtname );
2511         return PyImport_ExecCodeModule( name, text->compiled );
2512 }
2513
2514 static PyMethodDef bimport[] = {
2515         {"blimport", blender_import, METH_VARARGS, "our own import"}
2516 };
2517
2518 PyObject *blender_import( PyObject * self, PyObject * args )
2519 {
2520         PyObject *exception, *err, *tb;
2521         char *name;
2522         PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
2523         PyObject *m;
2524
2525         if( !PyArg_ParseTuple( args, "s|OOO:bimport",
2526                                &name, &globals, &locals, &fromlist ) )
2527                 return NULL;
2528
2529         m = PyImport_ImportModuleEx( name, globals, locals, fromlist );
2530
2531         if( m )
2532                 return m;
2533         else
2534                 PyErr_Fetch( &exception, &err, &tb );   /*restore for probable later use */
2535
2536         m = importText( name );
2537         if( m ) {               /* found module, ignore above exception */
2538                 PyErr_Clear(  );
2539                 Py_XDECREF( exception );
2540                 Py_XDECREF( err );
2541                 Py_XDECREF( tb );
2542                 printf( "imported from text buffer...\n" );
2543         } else {
2544                 PyErr_Restore( exception, err, tb );
2545         }
2546         return m;
2547 }
2548
2549 void init_ourImport( void )
2550 {
2551         PyObject *m, *d;
2552         PyObject *import = PyCFunction_New( bimport, NULL );
2553
2554         m = PyImport_AddModule( "__builtin__" );
2555         d = PyModule_GetDict( m );
2556         
2557         EXPP_dict_set_item_str( d, "__import__", import );
2558 }
2559
2560 /*
2561  * find in-memory module and recompile
2562  */
2563
2564 static PyObject *reimportText( PyObject *module )
2565 {
2566         Text *text;
2567         char *txtname;
2568         char *name;
2569         char *buf = NULL;
2570
2571         /* get name, filename from the module itself */
2572
2573         txtname = PyModule_GetFilename( module );
2574         name = PyModule_GetName( module );
2575         if( !txtname || !name)
2576                 return NULL;
2577
2578         /* look up the text object */
2579         text = ( Text * ) & ( G.main->text.first );
2580         while( text ) {
2581                 if( !strcmp( txtname, GetName( text ) ) )
2582                         break;
2583                 text = text->id.next;
2584         }
2585
2586         /* uh-oh.... didn't find it */
2587         if( !text )
2588                 return NULL;
2589
2590         /* if previously compiled, free the object */
2591         /* (can't see how could be NULL, but check just in case) */ 
2592         if( text->compiled ){
2593                 Py_DECREF( (PyObject *)text->compiled );
2594         }
2595
2596         /* compile the buffer */
2597         buf = txt_to_buf( text );
2598         text->compiled = Py_CompileString( buf, GetName( text ),
2599                         Py_file_input );
2600         MEM_freeN( buf );
2601
2602         /* if compile failed.... return this error */
2603         if( PyErr_Occurred(  ) ) {
2604                 PyErr_Print(  );
2605                 BPY_free_compiled_text( text );
2606                 return NULL;
2607         }
2608
2609         /* make into a module */
2610         return PyImport_ExecCodeModule( name, text->compiled );
2611 }
2612
2613 /*
2614  * our reload() module, to handle reloading in-memory scripts
2615  */
2616
2617 static PyObject *blender_reload( PyObject * self, PyObject * args )
2618 {
2619         PyObject *exception, *err, *tb;
2620         PyObject *module = NULL;
2621         PyObject *newmodule = NULL;
2622
2623         /* check for a module arg */
2624         if( !PyArg_ParseTuple( args, "O:breload", &module ) )
2625                 return NULL;
2626
2627         /* try reimporting from file */
2628         newmodule = PyImport_ReloadModule( module );
2629         if( newmodule )
2630                 return newmodule;
2631
2632         /* no file, try importing from memory */
2633         PyErr_Fetch( &exception, &err, &tb );   /*restore for probable later use */
2634
2635         newmodule = reimportText( module );
2636         if( newmodule ) {               /* found module, ignore above exception */
2637                 PyErr_Clear(  );
2638                 Py_XDECREF( exception );
2639                 Py_XDECREF( err );
2640                 Py_XDECREF( tb );
2641         } else
2642                 PyErr_Restore( exception, err, tb );
2643
2644         return newmodule;
2645 }
2646
2647 static PyMethodDef breload[] = {
2648         {"blreload", blender_reload, METH_VARARGS, "our own reload"}
2649 };
2650
2651 void init_ourReload( void )
2652 {
2653         PyObject *m, *d;
2654         PyObject *reload = PyCFunction_New( breload, NULL );
2655
2656         m = PyImport_AddModule( "__builtin__" );
2657         d = PyModule_GetDict( m );
2658         EXPP_dict_set_item_str( d, "reload", reload );
2659 }