BPython:
[blender-staging.git] / source / blender / python / BPY_interface.c
1 /* 
2  *
3  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version. The Blender
9  * Foundation also sells licenses for use in proprietary software under
10  * the Blender License.  See http://www.blender.org/BL/ for information
11  * about this.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * This is a new part of Blender.
26  *
27  * Contributor(s): Michel Selten, Willian P. Germano, Stephen Swaney
28  *
29  * ***** END GPL/BL DUAL LICENSE BLOCK *****
30 */
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #include <Python.h>
36 #include "compile.h" /* for the PyCodeObject */
37 #include "eval.h" /* for PyEval_EvalCode */
38
39 #include <stdio.h>
40
41 #include <MEM_guardedalloc.h>
42 #include <BLI_blenlib.h> /* for BLI_last_slash() */
43
44 #include <BIF_interface.h> /* for pupmenu */
45 #include <BIF_space.h>
46 #include <BIF_screen.h>
47 #include <BIF_toolbox.h>
48 #include <BKE_global.h>
49 #include <BKE_library.h>
50 #include <BKE_main.h>
51 #include <BKE_text.h>
52 #include <BKE_utildefines.h>
53 #include <BPI_script.h>
54
55 #include <DNA_camera_types.h>
56 #include <DNA_ID.h>
57 #include <DNA_lamp_types.h>
58 #include <DNA_material_types.h>
59 #include <DNA_object_types.h>
60 #include <DNA_scene_types.h>
61 #include <DNA_screen_types.h>
62 #include <DNA_scriptlink_types.h>
63 #include <DNA_space_types.h>
64 #include <DNA_text_types.h>
65 #include <DNA_world_types.h>
66 #include <DNA_userdef_types.h> /* for U.pythondir */
67
68 #include "BPY_extern.h"
69 #include "BPY_menus.h"
70 #include "api2_2x/EXPP_interface.h"
71 #include "api2_2x/constant.h"
72
73 /* bpy_registryDict is declared in api2_2x/Registry.h and defined
74  * here.  This Python dictionary will be used to store data that scripts
75  * choose to preserve after they are executed, so user changes can be
76  * restored next time the script is used.  Check the Blender.Registry module. */
77 extern PyObject *bpy_registryDict;
78
79 /*****************************************************************************/
80 /* Structure definitions                                                     */
81 /*****************************************************************************/
82 #define FILENAME_LENGTH 24
83 typedef struct _ScriptError {
84   char filename[FILENAME_LENGTH];
85   int lineno;
86 } ScriptError;
87
88 /*****************************************************************************/
89 /* Global variables                                                          */
90 /*****************************************************************************/
91 ScriptError g_script_error;
92 short EXPP_releaseGlobalDict = 1;
93
94 /*****************************************************************************/
95 /* Function prototypes                                                       */
96 /*****************************************************************************/
97 PyObject *RunPython(Text *text, PyObject *globaldict);
98 char     *GetName(Text *text);
99 PyObject *CreateGlobalDictionary (void);
100 void      ReleaseGlobalDictionary (PyObject * dict);
101 void      DoAllScriptsFromList (ListBase * list, short event);
102 PyObject *importText(char *name);
103 void init_ourImport(void);
104 PyObject *blender_import(PyObject *self, PyObject *args);
105
106 /*****************************************************************************/
107 /* Description: This function will initialise Python and all the implemented */
108 /*              api variations.                                              */
109 /* Notes:       Currently only the api for 2.2x will be initialised.         */
110 /*****************************************************************************/
111 void BPY_start_python(void)
112 {
113   bpy_registryDict = PyDict_New(); /* check comment at start of this file */
114
115   if (!bpy_registryDict)
116     printf("Error: Couldn't create the Registry Python Dictionary!");
117
118 /* TODO: Shouldn't "blender" be replaced by PACKAGE ?? (config.h) */
119   Py_SetProgramName("blender");
120
121   Py_Initialize ();
122
123   init_ourImport ();
124
125   initBlenderApi2_2x ();
126
127   init_syspath();
128
129   return;
130 }
131
132 /*****************************************************************************/
133 /* Description: This function will terminate the Python interpreter          */
134 /*****************************************************************************/
135 void BPY_end_python(void)
136 {
137   if (bpy_registryDict) {
138     Py_DECREF (bpy_registryDict);
139     bpy_registryDict = NULL;
140   }
141
142   Py_Finalize();
143
144         BPyMenu_RemoveAllEntries(); /* freeing bpymenu mem */
145
146   return;
147 }
148
149 void syspath_append(char *dirname)
150 {
151   PyObject *mod_sys, *dict, *path, *dir;
152
153   PyErr_Clear();
154
155         dir = Py_BuildValue("s", dirname);
156
157   mod_sys = PyImport_ImportModule("sys"); /* new ref */
158   dict = PyModule_GetDict(mod_sys);       /* borrowed ref */
159   path = PyDict_GetItemString(dict, "path"); /* borrowed ref */
160
161   if (!PyList_Check(path)) return;
162
163   PyList_Append(path, dir);
164
165   if (PyErr_Occurred()) Py_FatalError("could not build sys.path");
166
167   Py_DECREF(mod_sys);
168 }
169
170 void init_syspath(void)
171 {
172   PyObject *path;
173   PyObject *mod, *d;
174   PyObject *p;
175   char *c, *progname;
176   char execdir[FILE_MAXDIR + FILE_MAXFILE];/*defines from DNA_space_types.h*/
177
178   int n;
179
180   path = Py_BuildValue("s", bprogname);
181
182   mod = PyImport_ImportModule("Blender.sys");
183
184   if (mod) {
185     d = PyModule_GetDict(mod);
186     PyDict_SetItemString(d, "progname", path);
187     Py_DECREF(mod);
188   }
189   else
190     printf("Warning: could not set Blender.sys.progname\n");
191
192   progname = BLI_last_slash(bprogname); /* looks for the last dir separator */
193
194   c = Py_GetPath(); /* get python system path */
195   PySys_SetPath(c); /* initialize */
196
197   n = progname - bprogname;
198   if (n > 0) {
199     strncpy(execdir, bprogname, n);
200     if (execdir[n-1] == '.') n--; /*fix for when run as ./blender */
201     execdir[n] = '\0';
202
203     syspath_append(execdir);  /* append to module search path */
204
205     /* set Blender.sys.progname */
206   }
207   else
208     printf ("Warning: could not determine argv[0] path\n");
209
210   /* 
211    * bring in the site module so we can add 
212    * site-package dirs to sys.path 
213    */
214
215   mod = PyImport_ImportModule("site"); /* new ref */
216
217   if (mod) {
218     PyObject* item;
219     int size = 0;
220     int index;
221
222     /* get the value of 'sitedirs' from the module */
223
224     /* the ref man says GetDict() never fails!!! */
225     d = PyModule_GetDict (mod); /* borrowed ref */
226     p = PyDict_GetItemString (d, "sitedirs");  /* borrowed ref */
227
228     if( p ) {  /* we got our string */
229       /* append each item in sitedirs list to path */
230       size = PyList_Size (p);
231
232       for (index = 0; index < size; index++) {
233         item  = PySequence_GetItem (p, index);  /* new ref */
234         if( item )
235           syspath_append (PyString_AsString(item));
236       }
237     }
238     Py_DECREF(mod);
239   }
240   else {  /* import 'site' failed */
241     PyErr_Clear();
242     printf("sys_init:warning - no sitedirs added from site module.\n");
243   }
244
245   /* 
246    * initialize the sys module
247    * set sys.executable to the Blender exe 
248    * set argv[0] to the Blender exe
249    */
250
251   mod = PyImport_ImportModule("sys"); /* new ref */
252
253   if (mod) {
254     d = PyModule_GetDict(mod); /* borrowed ref */
255     PyDict_SetItemString(d, "executable", Py_BuildValue("s", bprogname));
256     /* in the future this can be extended to have more argv's if needed: */
257     PyDict_SetItemString(d, "argv", Py_BuildValue("[s]", bprogname));
258     Py_DECREF(mod);
259   }
260 }
261
262 /*****************************************************************************/
263 /* Description: This function finishes Python initialization in Blender.     */
264 /*              Because U.pythondir (user defined dir for scripts) isn't     */
265 /*              initialized when BPY_start_Python needs to be executed, we   */
266 /*              postpone adding U.pythondir to sys.path and also BPyMenus    */
267 /*              (mechanism to register scripts in Blender menus) for when    */
268 /*              that dir info is available.                                  */
269 /*****************************************************************************/
270 void BPY_post_start_python(void)
271 {
272   if (U.pythondir && U.pythondir[0] != '\0')
273     syspath_append(U.pythondir);  /* append to module search path */
274
275         BPyMenu_Init(0); /* get dynamic menus (registered scripts) data */
276 }
277
278 /*****************************************************************************/
279 /* Description: This function will return the linenumber on which an error   */
280 /*              has occurred in the Python script.                           */
281 /*****************************************************************************/
282 int BPY_Err_getLinenumber(void)
283 {
284   return g_script_error.lineno;
285 }
286
287 /*****************************************************************************/
288 /* Description: This function will return the filename of the python script. */
289 /*****************************************************************************/
290 const char *BPY_Err_getFilename(void)
291 {
292   return g_script_error.filename;
293 }
294
295 /*****************************************************************************/
296 /* Description: Return PyString filename from a traceback object             */
297 /*****************************************************************************/
298 PyObject *traceback_getFilename(PyObject *tb)
299 {
300   PyObject *v;
301
302 /* co_filename is in f_code, which is in tb_frame, which is in tb */
303
304   v = PyObject_GetAttrString(tb, "tb_frame"); Py_XDECREF(v);
305   v = PyObject_GetAttrString(v, "f_code"); Py_XDECREF(v);
306   v = PyObject_GetAttrString(v, "co_filename");
307
308   return v;
309 }
310
311 /*****************************************************************************/
312 /* Description: Blender Python error handler. This catches the error and     */
313 /* stores filename and line number in a global                               */
314 /*****************************************************************************/
315 void BPY_Err_Handle(char *script_name)
316 {
317   PyObject *exception, *err, *tb, *v;
318
319         if (!script_name) {
320                 printf("Error: script has NULL name\n");
321                 return;
322         }
323
324   PyErr_Fetch(&exception, &err, &tb);
325
326   if (!exception && !tb) {
327     printf("FATAL: spurious exception\n");
328     return;
329   }
330
331   strcpy(g_script_error.filename, script_name);
332
333   if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
334     /* no traceback available when SyntaxError */
335     PyErr_Restore(exception, err, tb); /* takes away reference! */
336     PyErr_Print();
337     v = PyObject_GetAttrString(err, "lineno");
338     g_script_error.lineno = PyInt_AsLong(v);
339     Py_XDECREF(v);
340     /* this avoids an abort in Python 2.3's garbage collecting: */
341     PyErr_Clear(); 
342     return;
343   } else {
344     PyErr_NormalizeException(&exception, &err, &tb);
345     PyErr_Restore(exception, err, tb); // takes away reference!
346     PyErr_Print();
347     tb = PySys_GetObject("last_traceback");
348
349     if (!tb) {
350       printf("\nCan't get traceback\n");
351       return;
352     }
353
354     Py_INCREF(tb);
355
356 /* From old bpython BPY_main.c:
357  * 'check traceback objects and look for last traceback in the
358  *  same text file. This is used to jump to the line of where the
359  *  error occured. "If the error occured in another text file or module,
360  *  the last frame in the current file is adressed."' */
361
362     while (1) { 
363       v = PyObject_GetAttrString(tb, "tb_next");
364
365       if (v == Py_None || strcmp(PyString_AsString(traceback_getFilename(v)),
366                               script_name)) {
367         break;
368       }
369
370       Py_DECREF(tb);
371       tb = v;
372     }
373
374     v = PyObject_GetAttrString(tb, "tb_lineno");
375     g_script_error.lineno = PyInt_AsLong(v);
376     Py_XDECREF(v);
377     v = traceback_getFilename(tb);
378     strncpy(g_script_error.filename, PyString_AsString(v), FILENAME_LENGTH);
379     Py_XDECREF(v);
380     Py_DECREF(tb);
381   }
382
383   return;
384 }
385
386 /*****************************************************************************/
387 /* Description: This function executes the script passed by st.              */
388 /* Notes:       It is called by blender/src/drawtext.c when a Blender user   */
389 /*              presses ALT+PKEY in the script's text window.                */
390 /*****************************************************************************/
391 int BPY_txt_do_python(struct SpaceText* st)
392 {
393   PyObject *py_dict, *py_result;
394         BPy_constant *info;
395         Script *script = G.main->script.first;
396
397   if (!st->text) return 0;
398
399         /* check if this text is already running */
400         while (script) {
401                 if (!strcmp(script->id.name+2, st->text->id.name+2)) {
402                         /* if this text is already a running script, just move to it: */        
403                         SpaceScript *sc;
404                         newspace(curarea, SPACE_SCRIPT);
405                         sc = curarea->spacedata.first;
406                         sc->script = script;
407                         return 1;
408                 }
409                 script = script->id.next;
410         }
411
412         /* Create a new script structure and initialize it: */
413         script = alloc_libblock(&G.main->script, ID_SCRIPT, GetName(st->text));
414
415         if (!script) {
416                 printf("couldn't allocate memory for Script struct!");
417                 return 0;
418         }
419
420         script->id.us = 1;
421         script->flags = SCRIPT_RUNNING;
422         script->py_draw = NULL;
423         script->py_event = NULL;
424         script->py_button = NULL;
425
426         py_dict = CreateGlobalDictionary();
427
428         script->py_globaldict = py_dict;
429
430         info = (BPy_constant *)M_constant_New();
431         if (info) {
432                 constant_insert(info, "name", PyString_FromString(script->id.name+2));
433                 Py_INCREF (Py_None);
434                 constant_insert(info, "arg", Py_None);
435                 PyDict_SetItemString(py_dict, "__script__", (PyObject *)info);
436         }
437
438   clearScriptLinks ();
439
440   py_result = RunPython (st->text, py_dict); /* Run the script */
441
442         if (!py_result) { /* Failed execution of the script */
443
444     BPY_Err_Handle(GetName(st->text));
445                 ReleaseGlobalDictionary(py_dict);
446                 free_libblock(&G.main->script, script);
447     //BPY_end_python();
448     //BPY_start_python();
449
450     return 0;
451         }
452         else {
453                 Py_DECREF (py_result);
454                 script->flags &=~SCRIPT_RUNNING;
455                 if (!script->flags) {
456                         ReleaseGlobalDictionary(py_dict);
457                         script->py_globaldict = NULL;
458                         free_libblock(&G.main->script, script);
459                 }
460         }
461
462   return 1; /* normal return */
463 }
464
465 /*****************************************************************************/
466 /* Description: This function executes the script chosen from a menu.        */
467 /* Notes:       It is called by the ui code in src/header_???.c when a user  */
468 /*              clicks on a menu entry that refers to a script.              */
469 /*              Scripts are searched in the BPyMenuTable, using the given    */
470 /*              menutype and event values to know which one was chosen.      */
471 /*****************************************************************************/
472 int BPY_menu_do_python(short menutype, int event)
473 {
474   PyObject *py_dict, *py_res, *pyarg = NULL;
475         BPy_constant *info;
476         BPyMenu *pym;
477         BPySubMenu *pysm;
478         FILE *fp = NULL;
479         char *buffer;
480         char filestr[FILE_MAXDIR+FILE_MAXFILE];
481         char dirname[FILE_MAXDIR];
482         Script *script = G.main->script.first;
483         int len;
484
485         pym = BPyMenu_GetEntry(menutype, (short)event);
486
487         if (!pym) return 0;
488
489         if (pym->version > G.version)
490                 notice ("Version mismatch: script was written for Blender %d. "
491                                                 "It may fail with yours: %d.", pym->version, G.version);
492
493 /* if there are submenus, let the user choose one from a pupmenu that we
494  * create here.*/
495         pysm = pym->submenus;
496         if (pysm) {
497                 char *pupstr; 
498                 int arg;
499
500                 pupstr = BPyMenu_CreatePupmenuStr(pym, menutype);
501
502                 if (pupstr) {
503                         arg = pupmenu(pupstr);
504                         MEM_freeN(pupstr);
505
506                         if (arg >= 0) {
507                                 while (arg--) pysm = pysm->next;
508                                 pyarg = PyString_FromString(pysm->arg);
509                         }
510                         else return 0;
511                 }
512         }
513
514         if (!pyarg) {/* no submenus */
515                 Py_INCREF (Py_None);
516                 pyarg = Py_None;
517         }
518
519         if (pym->dir) /* script is in U.pythondir */
520                 BLI_make_file_string("/", filestr, U.pythondir, pym->filename);
521         else { /* script is in ~/.blender/scripts/ */
522                 BLI_make_file_string("/", dirname, bpymenu_gethome(), "scripts");
523                 BLI_make_file_string("/", filestr, dirname,     pym->filename);
524         }
525
526         fp = fopen(filestr, "r");
527         if (!fp) { /* later also support userhome/.blender/scripts/ or whatever */
528                 printf("Error loading script: couldn't open file %s\n", filestr);
529                 return 0;
530         }
531
532         /* Create a new script structure and initialize it: */
533         script = alloc_libblock(&G.main->script, ID_SCRIPT, pym->name);
534
535         if (!script) {
536                 printf("couldn't allocate memory for Script struct!");
537                 fclose(fp);
538                 return 0;
539         }
540
541         script->id.us = 1;
542         script->flags = SCRIPT_RUNNING;
543         script->py_draw = NULL;
544         script->py_event = NULL;
545         script->py_button = NULL;
546
547         py_dict = CreateGlobalDictionary();
548
549         script->py_globaldict = py_dict;
550
551         info = (BPy_constant *)M_constant_New();
552         if (info) {
553                 constant_insert(info, "name", PyString_FromString(script->id.name+2));
554                 constant_insert(info, "arg", pyarg);
555                 PyDict_SetItemString(py_dict, "__script__", (PyObject *)info);
556         }
557
558   clearScriptLinks ();
559
560         /* Previously we used PyRun_File to run directly the code on a FILE object,
561          * but as written in the Python/C API Ref Manual, chapter 2,
562          * 'FILE structs for different C libraries can be different and incompatible'
563          * 
564          * So now we load the script file data to a buffer */
565
566         fseek(fp, 0L, SEEK_END);
567         len = ftell(fp);
568         fseek(fp, 0L, SEEK_SET);
569
570         buffer = MEM_mallocN(len+1, "pyfilebuf"); /* len+1 to add '\0' */
571         len = fread(buffer, 1, len, fp);
572
573         buffer[len] = '\0';
574
575         fclose(fp);
576
577         /* run the string buffer */
578
579         py_res = PyRun_String(buffer, Py_file_input, py_dict, py_dict);
580
581         MEM_freeN(buffer);
582
583         if (!py_res) { /* Failed execution of the script */
584
585     BPY_Err_Handle(script->id.name+2);
586                 PyErr_Print();
587                 ReleaseGlobalDictionary(py_dict);
588                 free_libblock(&G.main->script, script);
589   //  BPY_end_python();
590   //  BPY_start_python();
591                 error ("Python script error: check console");
592
593     return 0;
594         }
595         else {
596                 Py_DECREF (py_res);
597                 script->flags &=~SCRIPT_RUNNING;
598                 if (!script->flags) {
599                         ReleaseGlobalDictionary(py_dict);
600                         script->py_globaldict = NULL;
601                         free_libblock(&G.main->script, script);
602                 }
603         }
604
605   return 1; /* normal return */
606 }
607
608 /*****************************************************************************/
609 /* Description:                                                              */
610 /* Notes:                                                                    */
611 /*****************************************************************************/
612 void BPY_free_compiled_text(struct Text* text)
613 {
614   if (!text->compiled) return;
615   Py_DECREF((PyObject*) text->compiled);
616   text->compiled = NULL;
617
618   return;
619 }
620
621 /*****************************************************************************/
622 /* Description: This function frees a finished (flags == 0) script.          */
623 /*****************************************************************************/
624 void BPY_free_finished_script(Script *script)
625 {
626         if (!script) return;
627
628         free_libblock(&G.main->script, script);
629         return;
630 }
631
632 void unlink_script(Script *script)
633 { /* copied from unlink_text in drawtext.c */
634         bScreen *scr;
635         ScrArea *area;
636         SpaceLink *sl;
637
638         for (scr= G.main->screen.first; scr; scr= scr->id.next) {
639                 for (area= scr->areabase.first; area; area= area->next) {
640                         for (sl= area->spacedata.first; sl; sl= sl->next) {
641                                 if (sl->spacetype==SPACE_SCRIPT) {
642                                         SpaceScript *sc= (SpaceScript*) sl;
643
644                                         if (sc->script==script) {
645                                                 sc->script= NULL;
646
647                                                 if (sc==area->spacedata.first) {
648                                                         scrarea_queue_redraw(area);
649                                                 }
650                                         }
651                                 }
652                         }
653                 }
654         }
655 }
656
657 void BPY_clear_script (Script *script)
658 {
659         PyObject *dict;
660
661         if (!script) return;
662
663         Py_XDECREF((PyObject *)script->py_draw);
664         Py_XDECREF((PyObject *)script->py_event);
665         Py_XDECREF((PyObject *)script->py_button);
666
667         dict = script->py_globaldict;
668
669         if (dict) {
670         PyDict_Clear (dict);
671         Py_DECREF (dict);   /* Release dictionary. */
672                 script->py_globaldict = NULL;
673         }
674
675         unlink_script (script);
676 }
677
678 /*****************************************************************************/
679 /* ScriptLinks                                                               */
680 /*****************************************************************************/
681
682 /*****************************************************************************/
683 /* Description:                                                              */
684 /* Notes:       Not implemented yet                                          */
685 /*****************************************************************************/
686 void BPY_clear_bad_scriptlinks(struct Text *byebye)
687 {
688 /*
689   BPY_clear_bad_scriptlist(getObjectList(), byebye);
690   BPY_clear_bad_scriptlist(getLampList(), byebye);
691   BPY_clear_bad_scriptlist(getCameraList(), byebye);
692   BPY_clear_bad_scriptlist(getMaterialList(), byebye);
693   BPY_clear_bad_scriptlist(getWorldList(),  byebye);
694   BPY_clear_bad_scriptlink(&scene_getCurrent()->id, byebye);
695
696   allqueue(REDRAWBUTSSCRIPT, 0);
697 */
698   return;
699 }
700
701 /*****************************************************************************/
702 /* Description: Loop through all scripts of a list of object types, and      */
703 /*              execute these scripts.                                       */
704 /*              For the scene, only the current active scene the scripts are */
705 /*              executed (if any).                                           */
706 /*****************************************************************************/
707 void BPY_do_all_scripts(short event)
708 {
709   DoAllScriptsFromList (&(G.main->object), event);
710   DoAllScriptsFromList (&(G.main->lamp), event);
711   DoAllScriptsFromList (&(G.main->camera), event);
712   DoAllScriptsFromList (&(G.main->mat), event);
713   DoAllScriptsFromList (&(G.main->world), event);
714
715   BPY_do_pyscript (&(G.scene->id), event);
716
717   return;
718 }
719
720 /*****************************************************************************/
721 /* Description: Execute a Python script when an event occurs. The following  */
722 /*              events are possible: frame changed, load script and redraw.  */
723 /*              Only events happening to one of the following object types   */
724 /*              are handled: Object, Lamp, Camera, Material, World and       */
725 /*              Scene.                                                       */
726 /*****************************************************************************/
727 void BPY_do_pyscript(struct ID *id, short event)
728 {
729   ScriptLink  * scriptlink;
730   int           index;
731   PyObject    * dict;
732   PyObject    * ret;
733
734   scriptlink = setScriptLinks (id, event);
735
736   if (scriptlink == NULL) return;
737
738   for (index = 0; index < scriptlink->totscript; index++)
739   {
740     if ((scriptlink->flag[index] == event) &&
741         (scriptlink->scripts[index] != NULL))
742     {
743       dict = CreateGlobalDictionary();
744       ret = RunPython ((Text*) scriptlink->scripts[index], dict);
745       ReleaseGlobalDictionary (dict);
746       if (!ret)
747       {
748           /* Failed execution of the script */
749           BPY_Err_Handle (scriptlink->scripts[index]->name+2);
750           BPY_end_python ();
751           BPY_start_python ();
752       }
753       else
754       {
755           Py_DECREF (ret);
756       }
757     }
758   }
759
760   return;
761 }
762
763 /*****************************************************************************/
764 /* Description:                                                              */
765 /* Notes:                                                                    */
766 /*****************************************************************************/
767 void BPY_free_scriptlink(struct ScriptLink *slink)
768 {
769   if (slink->totscript) {
770     if(slink->flag) MEM_freeN(slink->flag);
771     if(slink->scripts) MEM_freeN(slink->scripts); 
772   }
773
774   return;
775 }
776
777 /*****************************************************************************/
778 /* Description:                                                              */
779 /* Notes:                                                                    */
780 /*****************************************************************************/
781 void BPY_copy_scriptlink(struct ScriptLink *scriptlink)
782 {
783   void *tmp;
784
785   if (scriptlink->totscript) {
786
787     tmp = scriptlink->scripts;
788     scriptlink->scripts =
789       MEM_mallocN(sizeof(ID*)*scriptlink->totscript, "scriptlistL");
790     memcpy(scriptlink->scripts, tmp, sizeof(ID*)*scriptlink->totscript);
791
792     tmp = scriptlink->flag;
793     scriptlink->flag =
794       MEM_mallocN(sizeof(short)*scriptlink->totscript, "scriptlistF");
795     memcpy(scriptlink->flag, tmp, sizeof(short)*scriptlink->totscript);
796   }
797
798   return;
799 }
800
801 /*****************************************************************************/
802 /* Description:                                                              */
803 /* Notes:       Not implemented yet                                          */
804 /*****************************************************************************/
805 int BPY_call_importloader(char *name)
806 { /* XXX Should this function go away from Blender? */
807   printf ("In BPY_call_importloader(name=%s)\n",name);
808   return (0);
809 }
810
811 /*****************************************************************************/
812 /* Private functions                                                         */
813 /*****************************************************************************/
814
815 /*****************************************************************************/
816 /* Description: This function executes the python script passed by text.     */
817 /*              The Python dictionary containing global variables needs to   */
818 /*              be passed in globaldict.                                     */
819 /*****************************************************************************/
820 PyObject * RunPython(Text *text, PyObject *globaldict)
821 {
822   char *buf = NULL;
823
824 /* The script text is compiled to Python bytecode and saved at text->compiled
825  * to speed-up execution if the user executes the script multiple times */
826
827   if (!text->compiled) { /* if it wasn't already compiled, do it now */
828     buf = txt_to_buf(text);
829
830     text->compiled = Py_CompileString(buf, GetName(text), Py_file_input);
831
832     MEM_freeN(buf);
833
834     if (PyErr_Occurred()) {
835       BPY_free_compiled_text(text);
836       return NULL;
837     }
838
839   }
840
841   return PyEval_EvalCode(text->compiled, globaldict, globaldict);
842 }
843
844 /*****************************************************************************/
845 /* Description: This function returns the value of the name field of the     */
846 /*              given Text struct.                                           */
847 /*****************************************************************************/
848 char * GetName(Text *text)
849 {
850   return (text->id.name+2);
851 }
852
853 /*****************************************************************************/
854 /* Description: This function creates a new Python dictionary object.        */
855 /*****************************************************************************/
856 PyObject * CreateGlobalDictionary (void)
857 {
858   PyObject *dict = PyDict_New();
859
860   PyDict_SetItemString (dict, "__builtins__", PyEval_GetBuiltins());
861   PyDict_SetItemString (dict, "__name__", PyString_FromString("__main__"));
862
863   return dict;
864 }
865
866 /*****************************************************************************/
867 /* Description: This function deletes a given Python dictionary object.      */
868 /*****************************************************************************/
869 void ReleaseGlobalDictionary (PyObject * dict)
870 {
871   PyDict_Clear (dict);
872   Py_DECREF (dict);   /* Release dictionary. */
873
874   return;
875 }
876
877 /*****************************************************************************/
878 /* Description: This function runs all scripts (if any) present in the       */
879 /*              list argument. The event by which the function has been      */
880 /*              called, is passed in the event argument.                     */
881 /*****************************************************************************/
882 void DoAllScriptsFromList (ListBase *list, short event)
883 {
884   ID *id;
885
886   id = list->first;
887
888   while (id != NULL) {
889     BPY_do_pyscript (id, event);
890     id = id->next;
891   }
892
893   return;
894 }
895
896 PyObject *importText(char *name)
897 {
898   Text *text;
899   char *txtname;
900   char *buf = NULL;
901   int namelen = strlen(name);
902
903   txtname = malloc(namelen+3+1);
904   if (!txtname) return NULL;
905
906   memcpy(txtname, name, namelen);
907   memcpy(&txtname[namelen], ".py", 4);
908
909   text = (Text*) &(G.main->text.first);
910
911   while(text) {
912     if (!strcmp (txtname, GetName(text)))
913       break;
914     text = text->id.next;
915   }
916
917   if (!text) {
918     free(txtname);
919     return NULL;
920   }
921
922   if (!text->compiled) {
923     buf = txt_to_buf(text);
924     text->compiled = Py_CompileString(buf, GetName(text), Py_file_input);
925     MEM_freeN(buf);
926
927     if (PyErr_Occurred()) {
928       PyErr_Print();
929       BPY_free_compiled_text(text);
930       free(txtname);
931       return NULL;
932     }
933   }
934
935   free(txtname);
936   return PyImport_ExecCodeModule(name, text->compiled);
937 }
938
939 static PyMethodDef bimport[] = {
940   { "blimport", blender_import, METH_VARARGS, "our own import"}
941 };
942
943 PyObject *blender_import(PyObject *self, PyObject *args)
944 {
945   PyObject *exception, *err, *tb;
946   char *name;
947   PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
948   PyObject *m;
949
950   if (!PyArg_ParseTuple(args, "s|OOO:bimport",
951           &name, &globals, &locals, &fromlist))
952       return NULL;
953
954   m = PyImport_ImportModuleEx(name, globals, locals, fromlist);
955
956   if (m) 
957     return m;
958   else
959     PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use*/
960   
961   m = importText(name);
962   if (m) { /* found module, ignore above exception*/
963     PyErr_Clear();
964     Py_XDECREF(exception); Py_XDECREF(err); Py_XDECREF(tb);
965     printf("imported from text buffer...\n");
966   } else {
967     PyErr_Restore(exception, err, tb);
968   }
969   return m;
970 }
971
972 void init_ourImport(void)
973 {
974   PyObject *m, *d;
975   PyObject *import = PyCFunction_New(bimport, NULL);
976
977   m = PyImport_AddModule("__builtin__");
978   d = PyModule_GetDict(m);
979   PyDict_SetItemString(d, "__import__", import);
980 }