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