8411ee00cb955678258232dcb483d493fb9c4750
[blender.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  * Chris Keith
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 */
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
35
36 #include <Python.h>
37 #include "compile.h" /* for the PyCodeObject */
38 #include "eval.h" /* for PyEval_EvalCode */
39
40 #include <stdio.h>
41
42 #include <MEM_guardedalloc.h>
43 #include <BLI_blenlib.h> /* for BLI_last_slash() */
44
45 #include <BIF_interface.h> /* for pupmenu() */
46 #include <BIF_space.h>
47 #include <BIF_screen.h>
48 #include <BIF_toolbox.h>
49 #include <BKE_global.h>
50 #include <BKE_library.h>
51 #include <BKE_main.h>
52 #include <BKE_object.h> /* during_scriptlink() */
53 #include <BKE_text.h>
54 #include <BKE_utildefines.h>
55 #include <BPI_script.h>
56
57 #include <DNA_camera_types.h>
58 #include <DNA_ID.h>
59 #include <DNA_lamp_types.h>
60 #include <DNA_material_types.h>
61 #include <DNA_object_types.h>
62 #include <DNA_scene_types.h>
63 #include <DNA_screen_types.h>
64 #include <DNA_scriptlink_types.h>
65 #include <DNA_space_types.h>
66 #include <DNA_text_types.h>
67 #include <DNA_world_types.h>
68 #include <DNA_userdef_types.h> /* for U.pythondir */
69
70 #include "BPY_extern.h"
71 #include "BPY_menus.h"
72 #include "api2_2x/EXPP_interface.h"
73 #include "api2_2x/constant.h"
74 #include "api2_2x/modules.h"
75
76 /* bpy_registryDict is declared in api2_2x/Registry.h and defined
77  * here.        This Python dictionary will be used to store data that scripts
78  * choose to preserve after they are executed, so user changes can be
79  * restored next time the script is used.  Check the Blender.Registry module. */
80 extern PyObject *bpy_registryDict;
81
82 /*****************************************************************************/
83 /* Structure definitions                                                                                                                                                                                                                 */
84 /*****************************************************************************/
85 #define FILENAME_LENGTH 24
86 typedef struct _ScriptError {
87         char filename[FILENAME_LENGTH];
88         int lineno;
89 } ScriptError;
90
91 /*****************************************************************************/
92 /* Global variables                                                                                                                                                                                                                                      */
93 /*****************************************************************************/
94 ScriptError g_script_error;
95
96 /*****************************************************************************/
97 /* Function prototypes                                                                                                                                                                                                                   */
98 /*****************************************************************************/
99 PyObject *RunPython(Text *text, PyObject *globaldict);
100 char             *GetName(Text *text);
101 PyObject *CreateGlobalDictionary (void);
102 void                    ReleaseGlobalDictionary (PyObject * dict);
103 void                    DoAllScriptsFromList (ListBase * list, short event);
104 PyObject *importText(char *name);
105 void init_ourImport(void);
106 PyObject *blender_import(PyObject *self, PyObject *args);
107
108 /*****************************************************************************/
109 /* Description: This function will initialise Python and all the implemented */
110 /*                                                      api variations.                                                                                                                                                                                  */
111 /* Notes:                               Currently only the api for 2.2x will be initialised.                             */
112 /*****************************************************************************/
113 void BPY_start_python(void)
114 {
115         bpy_registryDict = PyDict_New(); /* check comment at start of this file */
116
117         if (!bpy_registryDict)
118                 printf("Error: Couldn't create the Registry Python Dictionary!");
119
120 /* TODO: Shouldn't "blender" be replaced by PACKAGE ?? (config.h) */
121         Py_SetProgramName("blender");
122
123         Py_Initialize ();
124
125         init_ourImport ();
126
127         initBlenderApi2_2x ();
128
129         init_syspath();
130
131         return;
132 }
133
134 /*****************************************************************************/
135 /* Description: This function will terminate the Python interpreter                                      */
136 /*****************************************************************************/
137 void BPY_end_python(void)
138 {
139         if (bpy_registryDict) {
140                 Py_DECREF (bpy_registryDict);
141                 bpy_registryDict = NULL;
142         }
143
144         Py_Finalize();
145
146         BPyMenu_RemoveAllEntries(); /* freeing bpymenu mem */
147
148         /* a script might've opened a .blend file but didn't close it, so: */
149         EXPP_Library_Close();
150
151         return;
152 }
153
154 void syspath_append(char *dirname)
155 {
156         PyObject *mod_sys, *dict, *path, *dir;
157
158         PyErr_Clear();
159
160         dir = Py_BuildValue("s", dirname);
161
162         mod_sys = PyImport_ImportModule("sys"); /* new ref */
163         dict = PyModule_GetDict(mod_sys);                               /* borrowed ref */
164         path = PyDict_GetItemString(dict, "path"); /* borrowed ref */
165
166         if (!PyList_Check(path)) return;
167
168         PyList_Append(path, dir);
169
170         if (PyErr_Occurred()) Py_FatalError("could not build sys.path");
171
172         Py_DECREF(mod_sys);
173 }
174
175 void init_syspath(void)
176 {
177         PyObject *path;
178         PyObject *mod, *d;
179         PyObject *p;
180         char *c, *progname;
181         char execdir[FILE_MAXDIR + FILE_MAXFILE];/*defines from DNA_space_types.h*/
182
183         int n;
184
185         path = Py_BuildValue("s", bprogname);
186
187         mod = PyImport_ImportModule("Blender.sys");
188
189         if (mod) {
190                 d = PyModule_GetDict(mod);
191                 PyDict_SetItemString(d, "progname", path);
192                 Py_DECREF(mod);
193         }
194         else
195                 printf("Warning: could not set Blender.sys.progname\n");
196
197         progname = BLI_last_slash(bprogname); /* looks for the last dir separator */
198
199         c = Py_GetPath(); /* get python system path */
200         PySys_SetPath(c); /* initialize */
201
202         n = progname - bprogname;
203         if (n > 0) {
204                 strncpy(execdir, bprogname, n);
205                 if (execdir[n-1] == '.') n--; /*fix for when run as ./blender */
206                 execdir[n] = '\0';
207
208                 syspath_append(execdir);        /* append to module search path */
209
210                 /* set Blender.sys.progname */
211         }
212         else
213                 printf ("Warning: could not determine argv[0] path\n");
214
215         /* 
216          * bring in the site module so we can add 
217          * site-package dirs to sys.path 
218          */
219
220         mod = PyImport_ImportModule("site"); /* new ref */
221
222         if (mod) {
223                 PyObject* item;
224                 int size = 0;
225                 int index;
226
227                 /* get the value of 'sitedirs' from the module */
228
229                 /* the ref man says GetDict() never fails!!! */
230                 d = PyModule_GetDict (mod); /* borrowed ref */
231                 p = PyDict_GetItemString (d, "sitedirs");  /* borrowed ref */
232
233                 if( p ) {  /* we got our string */
234                         /* append each item in sitedirs list to path */
235                         size = PyList_Size (p);
236
237                         for (index = 0; index < size; index++) {
238         item    = PySequence_GetItem (p, index);        /* new ref */
239         if( item )
240                 syspath_append (PyString_AsString(item));
241                         }
242                 }
243                 Py_DECREF(mod);
244         }
245         else {  /* import 'site' failed */
246                 PyErr_Clear();
247                 printf("sys_init:warning - no sitedirs added from site module.\n");
248         }
249
250         /* 
251          * initialize the sys module
252          * set sys.executable to the Blender exe 
253          * set argv[0] to the Blender exe
254          */
255
256         mod = PyImport_ImportModule("sys"); /* new ref */
257
258         if (mod) {
259                 d = PyModule_GetDict(mod); /* borrowed ref */
260                 PyDict_SetItemString(d, "executable", Py_BuildValue("s", bprogname));
261                 /* in the future this can be extended to have more argv's if needed: */
262                 PyDict_SetItemString(d, "argv", Py_BuildValue("[s]", bprogname));
263                 Py_DECREF(mod);
264         }
265 }
266
267 /*****************************************************************************/
268 /* Description: This function finishes Python initialization in Blender.                 */
269 /*                                                      Because U.pythondir (user defined dir for scripts) isn't                 */
270 /*                                                      initialized when BPY_start_Python needs to be executed, we       */
271 /*                                                      postpone adding U.pythondir to sys.path and also BPyMenus                */
272 /*                                                      (mechanism to register scripts in Blender menus) for when                */
273 /*                                                      that dir info is available.                                                                                                                                      */
274 /*****************************************************************************/
275 void BPY_post_start_python(void)
276 {
277         PyObject *result, *dict;
278
279         if (U.pythondir && U.pythondir[0] != '\0')
280                 syspath_append(U.pythondir);    /* append to module search path */
281
282         BPyMenu_Init(0); /* get dynamic menus (registered scripts) data */
283
284         dict = PyDict_New();
285
286         /* here we check if the user has (some of) the expected modules */
287         if (dict) {
288                 char *s = "import chunk, gzip, math, os, struct, string";
289                 result = PyRun_String(s, Py_eval_input, dict, dict);
290                 if (!result) {
291                         PyErr_Clear();
292                         /*XXX print msg about this, point to readme.html */
293                 }
294                 else Py_DECREF(result);
295                 Py_DECREF(dict);
296         }
297 }
298
299 /*****************************************************************************/
300 /* Description: This function will return the linenumber on which an error       */
301 /*                                                      has occurred in the Python script.                                                                                                       */
302 /*****************************************************************************/
303 int BPY_Err_getLinenumber(void)
304 {
305         return g_script_error.lineno;
306 }
307
308 /*****************************************************************************/
309 /* Description: This function will return the filename of the python script. */
310 /*****************************************************************************/
311 const char *BPY_Err_getFilename(void)
312 {
313         return g_script_error.filename;
314 }
315
316 /*****************************************************************************/
317 /* Description: Return PyString filename from a traceback object                                                 */
318 /*****************************************************************************/
319 PyObject *traceback_getFilename(PyObject *tb)
320 {
321         PyObject *v;
322
323 /* co_filename is in f_code, which is in tb_frame, which is in tb */
324
325         v = PyObject_GetAttrString(tb, "tb_frame"); Py_XDECREF(v);
326         v = PyObject_GetAttrString(v, "f_code"); Py_XDECREF(v);
327         v = PyObject_GetAttrString(v, "co_filename");
328
329         return v;
330 }
331
332 /*****************************************************************************/
333 /* Description: Blender Python error handler. This catches the error and                 */
334 /* stores filename and line number in a global                                                                                                                   */
335 /*****************************************************************************/
336 void BPY_Err_Handle(char *script_name)
337 {
338         PyObject *exception, *err, *tb, *v;
339
340         if (!script_name) {
341                 printf("Error: script has NULL name\n");
342                 return;
343         }
344
345         PyErr_Fetch(&exception, &err, &tb);
346
347         if (!exception && !tb) {
348                 printf("FATAL: spurious exception\n");
349                 return;
350         }
351
352         strcpy(g_script_error.filename, script_name);
353
354         if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
355                 /* no traceback available when SyntaxError */
356                 PyErr_Restore(exception, err, tb); /* takes away reference! */
357                 PyErr_Print();
358                 v = PyObject_GetAttrString(err, "lineno");
359                 if (v) {
360                         g_script_error.lineno = PyInt_AsLong(v);
361                         Py_DECREF(v);
362                 } else {
363                         g_script_error.lineno = -1;
364                 }
365                 /* this avoids an abort in Python 2.3's garbage collecting: */
366                 PyErr_Clear(); 
367                 return;
368         } else {
369                 PyErr_NormalizeException(&exception, &err, &tb);
370                 PyErr_Restore(exception, err, tb); // takes away reference!
371                 PyErr_Print();
372                 tb = PySys_GetObject("last_traceback");
373
374                 if (!tb) {
375                         printf("\nCan't get traceback\n");
376                         return;
377                 }
378
379                 Py_INCREF(tb);
380
381 /* From old bpython BPY_main.c:
382  * 'check traceback objects and look for last traceback in the
383  *      same text file. This is used to jump to the line of where the
384  *      error occured. "If the error occured in another text file or module,
385  *      the last frame in the current file is adressed."' */
386
387                 while (1) { 
388                         v = PyObject_GetAttrString(tb, "tb_next");
389
390                         if (v == Py_None || strcmp(PyString_AsString(traceback_getFilename(v)),
391                                                                                                                         script_name)) {
392                                 break;
393                         }
394
395                         Py_DECREF(tb);
396                         tb = v;
397                 }
398
399                 v = PyObject_GetAttrString(tb, "tb_lineno");
400                 g_script_error.lineno = PyInt_AsLong(v);
401                 Py_XDECREF(v);
402                 v = traceback_getFilename(tb);
403                 strncpy(g_script_error.filename, PyString_AsString(v), FILENAME_LENGTH);
404                 Py_XDECREF(v);
405                 Py_DECREF(tb);
406         }
407
408         return;
409 }
410
411 /*****************************************************************************/
412 /* Description: This function executes the script passed by st.                                                  */
413 /* Notes:                               It is called by blender/src/drawtext.c when a Blender user       */
414 /*                                                      presses ALT+PKEY in the script's text window.                                                            */
415 /*****************************************************************************/
416 int BPY_txt_do_python_Text(struct Text* text)
417 {
418         PyObject *py_dict, *py_result;
419         BPy_constant *info;
420         char textname[24];
421         Script *script = G.main->script.first;
422
423         if (!text) return 0;
424
425         /* check if this text is already running */
426         while (script) {
427                 if (!strcmp(script->id.name+2, text->id.name+2)) {
428                         /* if this text is already a running script, just move to it: */        
429                         SpaceScript *sc;
430                         newspace(curarea, SPACE_SCRIPT);
431                         sc = curarea->spacedata.first;
432                         sc->script = script;
433                         return 1;
434                 }
435                 script = script->id.next;
436         }
437
438         /* Create a new script structure and initialize it: */
439         script = alloc_libblock(&G.main->script, ID_SCRIPT, GetName(text));
440
441         if (!script) {
442                 printf("couldn't allocate memory for Script struct!");
443                 return 0;
444         }
445
446         /* if in the script Blender.Load(blendfile) is not the last command,
447          * an error after it will call BPY_Err_Handle below, but the text struct
448          * will have been deallocated already, so we need to copy its name here. */
449         BLI_strncpy(textname, GetName(text), strlen(GetName(text))+1);
450
451         script->id.us = 1;
452         script->flags = SCRIPT_RUNNING;
453         script->py_draw = NULL;
454         script->py_event = NULL;
455         script->py_button = NULL;
456
457         py_dict = CreateGlobalDictionary();
458
459         script->py_globaldict = py_dict;
460
461         info = (BPy_constant *)M_constant_New();
462         if (info) {
463                 constant_insert(info, "name", PyString_FromString(script->id.name+2));
464                 Py_INCREF (Py_None);
465                 constant_insert(info, "arg", Py_None);
466                 PyDict_SetItemString(py_dict, "__script__", (PyObject *)info);
467         }
468
469         py_result = RunPython (text, py_dict); /* Run the script */
470
471         if (!py_result) { /* Failed execution of the script */
472
473                 BPY_Err_Handle(textname);
474                 ReleaseGlobalDictionary(py_dict);
475                 script->py_globaldict = NULL;
476                 if (G.main->script.first) free_libblock(&G.main->script, script);
477
478                 return 0;
479         }
480         else {
481                 Py_DECREF (py_result);
482                 script->flags &=~SCRIPT_RUNNING;
483                 if (!script->flags) {
484                         ReleaseGlobalDictionary(py_dict);
485                         script->py_globaldict = NULL;
486                         free_libblock(&G.main->script, script);
487                 }
488         }
489
490         return 1; /* normal return */
491 }
492
493 /*****************************************************************************/
494 /* Description: The original function of this name has been refactored                   */
495 /* into BPY_txt_do_python_Text.  That version is needed for the command                  */
496 /* line support for Python.  This is here to keep the interface the                                      */
497 /* same and reduce code changes elsewhere.                                                                                                                                       */
498 /*****************************************************************************/
499 int BPY_txt_do_python(struct SpaceText* st)
500 {
501         return BPY_txt_do_python_Text(st->text);
502 }
503
504 /*****************************************************************************/
505 /* Description: Called from command line to run a Python script
506 * automatically. */
507 /*****************************************************************************/
508 void BPY_run_python_script(char *fn)
509 {
510         Text    *text = NULL;
511         int is_blenText = 0;
512
513         if ( !BLI_exists(fn) ) { /* if there's no such filename ...*/
514                 text = G.main->text.first; /* try an already existing Blender Text */
515                 while (text) {
516                         if (!strcmp(fn, text->id.name+2)) break;
517                         text = text->id.next;
518                 }
519
520                 if (!text) {
521                         printf("\nError: no such file or Blender text -- %s.\n", fn);
522                         return;
523                 }
524                 else is_blenText = 1; /* fn is already a Blender Text */
525         }
526
527         if (!is_blenText) text = add_text(fn);
528         if (text == NULL) {
529                 printf("Error in BPY_run_python_script: couldn't create Blender text "
530                         "from %s\n", fn);
531                 // Chris: On Windows if I continue I just get a segmentation
532                 // violation.  To get a baseline file I exit here.
533                 exit(2);
534         }
535
536         if (BPY_txt_do_python_Text(text) != 1) {
537                 printf( "\nError executing Python script from command-line:\n"
538                         "%s (at line %d).\n", fn, BPY_Err_getLinenumber());
539         }
540
541         if (!is_blenText) free_libblock(&G.main->text, text);
542 }
543
544 /*****************************************************************************/
545 /* Description: This function executes the script chosen from a menu.                            */
546 /* Notes:                               It is called by the ui code in src/header_???.c when a user  */
547 /*                                                      clicks on a menu entry that refers to a script.                                                  */
548 /*                                                      Scripts are searched in the BPyMenuTable, using the given                */
549 /*                                                      menutype and event values to know which one was chosen.                  */
550 /*****************************************************************************/
551 int BPY_menu_do_python(short menutype, int event)
552 {
553         PyObject *py_dict, *py_res, *pyarg = NULL;
554         BPy_constant *info;
555         BPyMenu *pym;
556         BPySubMenu *pysm;
557         FILE *fp = NULL;
558         char *buffer, *s;
559         char filestr[FILE_MAXDIR+FILE_MAXFILE];
560         char dirname[FILE_MAXDIR];
561         Script *script = G.main->script.first;
562         int len;
563
564         pym = BPyMenu_GetEntry(menutype, (short)event);
565
566         if (!pym) return 0;
567
568         if (pym->version > G.version)
569                 notice ("Version mismatch: script was written for Blender %d. "
570                                                 "It may fail with yours: %d.", pym->version, G.version);
571
572 /* if there are submenus, let the user choose one from a pupmenu that we
573  * create here.*/
574         pysm = pym->submenus;
575         if (pysm) {
576                 char *pupstr; 
577                 int arg;
578
579                 pupstr = BPyMenu_CreatePupmenuStr(pym, menutype);
580
581                 if (pupstr) {
582                         arg = pupmenu(pupstr);
583                         MEM_freeN(pupstr);
584
585                         if (arg >= 0) {
586                                 while (arg--) pysm = pysm->next;
587                                 pyarg = PyString_FromString(pysm->arg);
588                         }
589                         else return 0;
590                 }
591         }
592
593         if (!pyarg) {/* no submenus */
594                 Py_INCREF (Py_None);
595                 pyarg = Py_None;
596         }
597
598         if (pym->dir) /* script is in U.pythondir */
599                 BLI_make_file_string("/", filestr, U.pythondir, pym->filename);
600         else { /* script is in ~/.blender/scripts/ */
601                 BLI_make_file_string("/", dirname, bpy_gethome(), "scripts");
602                 BLI_make_file_string("/", filestr, dirname,     pym->filename);
603         }
604
605         fp = fopen(filestr, "rb");
606         if (!fp) {
607                 printf("Error loading script: couldn't open file %s\n", filestr);
608                 return 0;
609         }
610
611         /* Create a new script structure and initialize it: */
612         script = alloc_libblock(&G.main->script, ID_SCRIPT, pym->name);
613
614         if (!script) {
615                 printf("couldn't allocate memory for Script struct!");
616                 fclose(fp);
617                 return 0;
618         }
619
620         /* let's find a proper area for an eventual script gui:
621          * (still experimenting here, need definition on which win
622          * each group will be put to code this properly) */
623         switch (menutype) {
624
625                 case PYMENU_IMPORT: /* first 3 were handled in header_info.c */
626                 case PYMENU_EXPORT:
627                 case PYMENU_HELP: 
628                 case PYMENU_WIZARDS:
629                         break;
630
631                 default:
632                         if (curarea->spacetype != SPACE_SCRIPT) {
633                                 ScrArea *sa = NULL;
634
635                                 sa = find_biggest_area_of_type(SPACE_BUTS);
636                                 if (sa) {
637                                         if ((1.5 * sa->winx) < sa->winy) sa = NULL; /* too narrow? */
638                                 }
639
640                                 if (!sa) sa = find_biggest_area_of_type(SPACE_SCRIPT);
641                                 if (!sa) sa = find_biggest_area_of_type(SPACE_TEXT);
642                                 if (!sa) sa = find_biggest_area_of_type(SPACE_IMAGE); /* group UV */
643                                 if (!sa) sa = find_biggest_area_of_type(SPACE_VIEW3D);
644
645                                 if (!sa) sa = find_biggest_area();
646
647                                 areawinset(sa->win);
648                         }
649                         break;
650         }
651
652         script->id.us = 1;
653         script->flags = SCRIPT_RUNNING;
654         script->py_draw = NULL;
655         script->py_event = NULL;
656         script->py_button = NULL;
657
658         py_dict = CreateGlobalDictionary();
659
660         script->py_globaldict = py_dict;
661
662         info = (BPy_constant *)M_constant_New();
663         if (info) {
664                 constant_insert(info, "name", PyString_FromString(script->id.name+2));
665                 constant_insert(info, "arg", pyarg);
666                 PyDict_SetItemString(py_dict, "__script__", (PyObject *)info);
667         }
668
669         /* Previously we used PyRun_File to run directly the code on a FILE object,
670          * but as written in the Python/C API Ref Manual, chapter 2,
671          * 'FILE structs for different C libraries can be different and incompatible'
672          * 
673          * So now we load the script file data to a buffer */
674
675         fseek(fp, 0L, SEEK_END);
676         len = ftell(fp);
677         fseek(fp, 0L, SEEK_SET);
678
679         buffer = MEM_mallocN(len+2, "pyfilebuf"); /* len+2 to add '\n\0' */
680         len = fread(buffer, 1, len, fp);
681
682         buffer[len] = '\n'; /* fix syntax error in files w/o eol*/
683         buffer[len+1] = '\0';
684
685         /* fast clean-up of dos cr/lf line endings: change '\r' to space */
686
687         /* we also have to check for line splitters: '\\' */
688         /* to avoid possible syntax errors on dos files on win */
689         /**/
690         /* but first make sure we won't disturb memory below &buffer[0]: */
691         if (*buffer == '\r') *buffer = ' ';
692
693         /* now handle the whole buffer */
694         for (s = buffer + 1; *s != '\0'; s++)   {
695                 if (*s == '\r') {
696                         if (*(s-1) == '\\') { /* special case: long lines split with '\': */
697                                 *(s-1) = ' '; /* we write ' \', because '\ ' is a syntax error */
698                                 *s = '\\';
699                         }
700                         else *s = ' '; /* not a split line, just replace '\r' with ' ' */
701                 }
702         }
703
704         fclose(fp);
705
706         /* run the string buffer */
707
708         py_res = PyRun_String(buffer, Py_file_input, py_dict, py_dict);
709
710         MEM_freeN(buffer);
711
712         if (!py_res) { /* Failed execution of the script */
713
714                 BPY_Err_Handle(script->id.name+2);
715                 PyErr_Print();
716                 ReleaseGlobalDictionary(py_dict);
717                 if (G.main->script.first) free_libblock(&G.main->script, script);
718                 error ("Python script error: check console");
719
720                 return 0;
721         }
722         else {
723                 Py_DECREF (py_res);
724                 script->flags &=~SCRIPT_RUNNING;
725
726                 if (!script->flags) {
727                         ReleaseGlobalDictionary(py_dict);
728                         script->py_globaldict = NULL;
729                         free_libblock(&G.main->script, script);
730
731                         /* special case: called from the menu in the Scripts window
732                          * we have to change sc->script pointer, since it'll be freed here.*/
733                         if (curarea->spacetype == SPACE_SCRIPT) {
734                                 SpaceScript *sc = curarea->spacedata.first;
735                                 sc->script = G.main->script.first; /* can be null, which is ok ... */
736                                 /* ... meaning no other script is running right now. */
737                         }
738         
739                 }
740         }
741
742         return 1; /* normal return */
743 }
744
745 /*****************************************************************************/
746 /* Description:                                                                                                                                                                                                                                                  */
747 /* Notes:                                                                                                                                                                                                                                                                                */
748 /*****************************************************************************/
749 void BPY_free_compiled_text(struct Text* text)
750 {
751         if (!text->compiled) return;
752         Py_DECREF((PyObject*) text->compiled);
753         text->compiled = NULL;
754
755         return;
756 }
757
758 /*****************************************************************************/
759 /* Description: This function frees a finished (flags == 0) script.                                      */
760 /*****************************************************************************/
761 void BPY_free_finished_script(Script *script)
762 {
763         if (!script) return;
764
765         if (PyErr_Occurred()) { /* if script ended after filesel */
766                 PyErr_Print(); /* eventual errors are handled now */
767                 error ("Python script error: check console");
768         }
769
770         free_libblock(&G.main->script, script);
771         return;
772 }
773
774 void unlink_script(Script *script)
775 { /* copied from unlink_text in drawtext.c */
776         bScreen *scr;
777         ScrArea *area;
778         SpaceLink *sl;
779
780         for (scr= G.main->screen.first; scr; scr= scr->id.next) {
781                 for (area= scr->areabase.first; area; area= area->next) {
782                         for (sl= area->spacedata.first; sl; sl= sl->next) {
783                                 if (sl->spacetype==SPACE_SCRIPT) {
784                                         SpaceScript *sc= (SpaceScript*) sl;
785
786                                         if (sc->script==script) {
787                                                 sc->script= NULL;
788
789                                                 if (sc==area->spacedata.first) {
790                                                         scrarea_queue_redraw(area);
791                                                 }
792                                         }
793                                 }
794                         }
795                 }
796         }
797 }
798
799 void BPY_clear_script (Script *script)
800 {
801         PyObject *dict;
802
803         if (!script) return;
804
805         Py_XDECREF((PyObject *)script->py_draw);
806         Py_XDECREF((PyObject *)script->py_event);
807         Py_XDECREF((PyObject *)script->py_button);
808
809         dict = script->py_globaldict;
810
811         if (dict) {
812                 PyDict_Clear (dict);
813                 Py_DECREF (dict);               /* Release dictionary. */
814                 script->py_globaldict = NULL;
815         }
816
817         unlink_script (script);
818 }
819
820 /*****************************************************************************/
821 /* ScriptLinks                                                                                                                                                                                                                                                   */
822 /*****************************************************************************/
823
824 /*****************************************************************************/
825 /* Description:                                                                                                                                                                                                                                                  */
826 /* Notes:                               Not implemented yet                                                                                                                                                                      */
827 /*****************************************************************************/
828 void BPY_clear_bad_scriptlinks(struct Text *byebye)
829 {
830 /*
831         BPY_clear_bad_scriptlist(getObjectList(), byebye);
832         BPY_clear_bad_scriptlist(getLampList(), byebye);
833         BPY_clear_bad_scriptlist(getCameraList(), byebye);
834         BPY_clear_bad_scriptlist(getMaterialList(), byebye);
835         BPY_clear_bad_scriptlist(getWorldList(),        byebye);
836         BPY_clear_bad_scriptlink(&scene_getCurrent()->id, byebye);
837
838         allqueue(REDRAWBUTSSCRIPT, 0);
839 */
840         return;
841 }
842
843 /*****************************************************************************/
844 /* Description: Loop through all scripts of a list of object types, and                  */
845 /*                                                      execute these scripts.                                                                                                                                                   */
846 /*                                                      For the scene, only the current active scene the scripts are */
847 /*                                                      executed (if any).                                                                                                                                                                       */
848 /*****************************************************************************/
849 void BPY_do_all_scripts(short event)
850 {
851         DoAllScriptsFromList (&(G.main->object), event);
852         DoAllScriptsFromList (&(G.main->lamp), event);
853         DoAllScriptsFromList (&(G.main->camera), event);
854         DoAllScriptsFromList (&(G.main->mat), event);
855         DoAllScriptsFromList (&(G.main->world), event);
856
857         BPY_do_pyscript (&(G.scene->id), event);
858
859         return;
860 }
861
862 /*****************************************************************************/
863 /* Description: Execute a Python script when an event occurs. The following  */
864 /*                                                      events are possible: frame changed, load script and redraw.  */
865 /*                                                      Only events happening to one of the following object types       */
866 /*                                                      are handled: Object, Lamp, Camera, Material, World and                   */
867 /*                                                      Scene.                                                                                                                                                                                                                   */
868 /*****************************************************************************/
869
870 static ScriptLink *ID_getScriptlink(ID *id)
871 {
872         switch (MAKE_ID2 (id->name[0], id->name[1])) {
873         case ID_OB:
874                 return &((Object*)id)->scriptlink;
875         case ID_LA:
876                 return &((Lamp*)id)->scriptlink;
877         case ID_CA:
878                 return &((Camera*)id)->scriptlink;
879         case ID_MA:
880                 return &((Material*)id)->scriptlink;
881         case ID_WO:
882                 return &((World*)id)->scriptlink;
883         case ID_SCE:
884                 return &((Scene*)id)->scriptlink;
885         default:
886                 return NULL;
887         }
888 }
889
890 static PyObject *ID_asPyObject(ID *id)
891 {
892         switch (MAKE_ID2 (id->name[0], id->name[1])) {
893         case ID_OB:
894                 return Object_CreatePyObject((Object*) id);
895         case ID_LA:
896                 return Lamp_CreatePyObject((Lamp*) id);
897         case ID_CA:
898                 return Camera_CreatePyObject((Camera*) id);
899         case ID_MA:
900                 return Material_CreatePyObject((Material*) id);
901         case ID_WO:
902                 return World_CreatePyObject((World*) id);
903         case ID_SCE:
904                 return Scene_CreatePyObject((Scene*) id);
905         default:
906                 Py_INCREF (Py_None);
907                 return Py_None;
908         }
909 }
910
911 int BPY_has_onload_script(void)
912 {
913         ScriptLink *slink = &G.scene->scriptlink;
914         int i;
915
916         if (!slink || !slink->totscript) return 0;
917
918         for (i = 0; i < slink->totscript; i++) {
919                         if ((slink->flag[i] == SCRIPT_ONLOAD) && (slink->scripts[i] != NULL))
920                                 return 1;
921         }
922
923         return 0;
924 }
925
926 void BPY_do_pyscript(ID *id, short event)
927 {
928         ScriptLink *scriptlink = ID_getScriptlink(id);
929
930         if (scriptlink && scriptlink->totscript) {
931                 PyObject *dict;
932                 PyObject *ret;
933                 int index, during_slink = during_scriptlink();
934
935                 /* invalid scriptlinks (new .blend was just loaded), return */
936                 if (during_slink < 0) return;
937
938                 /* tell we're running a scriptlink.  The sum also tells if this script
939                  * is running nested inside another.  Blender.Load needs this info to
940                  * avoid trouble with invalid slink pointers. */
941                 during_slink++;
942                 disable_where_scriptlink(during_slink);
943
944                 /* set globals in Blender module to identify scriptlink */
945                 Py_INCREF(Py_True);
946                 PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
947                 PyDict_SetItemString(g_blenderdict, "link", ID_asPyObject(id));
948                 PyDict_SetItemString(g_blenderdict, "event", 
949                         PyString_FromString(event_to_name(event)));
950
951                 for (index = 0; index < scriptlink->totscript; index++) {
952                         if ((scriptlink->flag[index] == event) &&
953                                         (scriptlink->scripts[index] != NULL)) {
954                                 dict = CreateGlobalDictionary();
955                                 ret = RunPython ((Text*) scriptlink->scripts[index], dict);
956                                 ReleaseGlobalDictionary (dict);
957
958                                 if (!ret) {
959                                         /* Failed execution of the script */
960                                         BPY_Err_Handle (scriptlink->scripts[index]->name+2);
961                                         //BPY_end_python ();
962                                         //BPY_start_python ();
963                                 } else {
964                                         Py_DECREF (ret);
965                                 }
966                                 /* If a scriptlink has just loaded a new .blend file, the
967                                  * scriptlink pointer became invalid (see api2_2x/Blender.c),
968                                  * so we stop here. */
969                                 if (during_scriptlink() == -1) {
970                                         during_slink = 1;
971                                         break;
972                                 }
973                         }
974                 }
975
976                 disable_where_scriptlink(during_slink - 1);
977
978                 /* cleanup bylink flag and clear link so PyObject can be released */
979                 Py_INCREF(Py_False);
980                 PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
981                 Py_INCREF(Py_None);
982                 PyDict_SetItemString(g_blenderdict, "link", Py_None);
983                 PyDict_SetItemString(g_blenderdict, "event", PyString_FromString(""));
984         }
985 }
986
987 /*****************************************************************************/
988 /* Description:                                                                                                                                                                                                                                                  */
989 /* Notes:                                                                                                                                                                                                                                                                                */
990 /*****************************************************************************/
991 void BPY_free_scriptlink(struct ScriptLink *slink)
992 {
993         if (slink->totscript) {
994                 if(slink->flag) MEM_freeN(slink->flag);
995                 if(slink->scripts) MEM_freeN(slink->scripts); 
996         }
997
998         return;
999 }
1000
1001 /*****************************************************************************/
1002 /* Description:                                                                                                                                                                                                                                                  */
1003 /* Notes:                                                                                                                                                                                                                                                                                */
1004 /*****************************************************************************/
1005 void BPY_copy_scriptlink(struct ScriptLink *scriptlink)
1006 {
1007         void *tmp;
1008
1009         if (scriptlink->totscript) {
1010
1011                 tmp = scriptlink->scripts;
1012                 scriptlink->scripts =
1013                         MEM_mallocN(sizeof(ID*)*scriptlink->totscript, "scriptlistL");
1014                 memcpy(scriptlink->scripts, tmp, sizeof(ID*)*scriptlink->totscript);
1015
1016                 tmp = scriptlink->flag;
1017                 scriptlink->flag =
1018                         MEM_mallocN(sizeof(short)*scriptlink->totscript, "scriptlistF");
1019                 memcpy(scriptlink->flag, tmp, sizeof(short)*scriptlink->totscript);
1020         }
1021
1022         return;
1023 }
1024
1025 /*****************************************************************************/
1026 /* Description:                                                                                                                                                                                                                                                  */
1027 /* Notes:                               Not implemented yet                                                                                                                                                                      */
1028 /*****************************************************************************/
1029 int BPY_call_importloader(char *name)
1030 { /* XXX Should this function go away from Blender? */
1031         printf ("In BPY_call_importloader(name=%s)\n",name);
1032         return (0);
1033 }
1034
1035 /*****************************************************************************/
1036 /* Private functions                                                                                                                                                                                                                             */
1037 /*****************************************************************************/
1038
1039 /*****************************************************************************/
1040 /* Description: This function executes the python script passed by text.                 */
1041 /*                                                      The Python dictionary containing global variables needs to       */
1042 /*                                                      be passed in globaldict.                                                                                                                                                 */
1043 /*****************************************************************************/
1044 PyObject * RunPython(Text *text, PyObject *globaldict)
1045 {
1046         char *buf = NULL;
1047
1048 /* The script text is compiled to Python bytecode and saved at text->compiled
1049  * to speed-up execution if the user executes the script multiple times */
1050
1051         if (!text->compiled) { /* if it wasn't already compiled, do it now */
1052                 buf = txt_to_buf(text);
1053
1054                 text->compiled = Py_CompileString(buf, GetName(text), Py_file_input);
1055
1056                 MEM_freeN(buf);
1057
1058                 if (PyErr_Occurred()) {
1059                         BPY_free_compiled_text(text);
1060                         return NULL;
1061                 }
1062
1063         }
1064
1065         return PyEval_EvalCode(text->compiled, globaldict, globaldict);
1066 }
1067
1068 /*****************************************************************************/
1069 /* Description: This function returns the value of the name field of the                 */
1070 /*                                                      given Text struct.                                                                                                                                                                       */
1071 /*****************************************************************************/
1072 char * GetName(Text *text)
1073 {
1074         return (text->id.name+2);
1075 }
1076
1077 /*****************************************************************************/
1078 /* Description: This function creates a new Python dictionary object.                            */
1079 /*****************************************************************************/
1080 PyObject * CreateGlobalDictionary (void)
1081 {
1082         PyObject *dict = PyDict_New();
1083
1084         PyDict_SetItemString (dict, "__builtins__", PyEval_GetBuiltins());
1085         PyDict_SetItemString (dict, "__name__", PyString_FromString("__main__"));
1086
1087         return dict;
1088 }
1089
1090 /*****************************************************************************/
1091 /* Description: This function deletes a given Python dictionary object.                  */
1092 /*****************************************************************************/
1093 void ReleaseGlobalDictionary (PyObject * dict)
1094 {
1095         PyDict_Clear (dict);
1096         Py_DECREF (dict);               /* Release dictionary. */
1097
1098         return;
1099 }
1100
1101 /*****************************************************************************/
1102 /* Description: This function runs all scripts (if any) present in the                   */
1103 /*                                                      list argument. The event by which the function has been                  */
1104 /*                                                      called, is passed in the event argument.                                                                                 */
1105 /*****************************************************************************/
1106 void DoAllScriptsFromList (ListBase *list, short event)
1107 {
1108         ID *id;
1109
1110         id = list->first;
1111
1112         while (id != NULL) {
1113                 BPY_do_pyscript (id, event);
1114                 id = id->next;
1115         }
1116
1117         return;
1118 }
1119
1120 PyObject *importText(char *name)
1121 {
1122         Text *text;
1123         char *txtname;
1124         char *buf = NULL;
1125         int namelen = strlen(name);
1126
1127         txtname = malloc(namelen+3+1);
1128         if (!txtname) return NULL;
1129
1130         memcpy(txtname, name, namelen);
1131         memcpy(&txtname[namelen], ".py", 4);
1132
1133         text = (Text*) &(G.main->text.first);
1134
1135         while(text) {
1136                 if (!strcmp (txtname, GetName(text)))
1137                         break;
1138                 text = text->id.next;
1139         }
1140
1141         if (!text) {
1142                 free(txtname);
1143                 return NULL;
1144         }
1145
1146         if (!text->compiled) {
1147                 buf = txt_to_buf(text);
1148                 text->compiled = Py_CompileString(buf, GetName(text), Py_file_input);
1149                 MEM_freeN(buf);
1150
1151                 if (PyErr_Occurred()) {
1152                         PyErr_Print();
1153                         BPY_free_compiled_text(text);
1154                         free(txtname);
1155                         return NULL;
1156                 }
1157         }
1158
1159         free(txtname);
1160         return PyImport_ExecCodeModule(name, text->compiled);
1161 }
1162
1163 static PyMethodDef bimport[] = {
1164         { "blimport", blender_import, METH_VARARGS, "our own import"}
1165 };
1166
1167 PyObject *blender_import(PyObject *self, PyObject *args)
1168 {
1169         PyObject *exception, *err, *tb;
1170         char *name;
1171         PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
1172         PyObject *m;
1173
1174         if (!PyArg_ParseTuple(args, "s|OOO:bimport",
1175                                         &name, &globals, &locals, &fromlist))
1176                         return NULL;
1177
1178         m = PyImport_ImportModuleEx(name, globals, locals, fromlist);
1179
1180         if (m) 
1181                 return m;
1182         else
1183                 PyErr_Fetch(&exception, &err, &tb); /*restore for probable later use*/
1184         
1185         m = importText(name);
1186         if (m) { /* found module, ignore above exception*/
1187                 PyErr_Clear();
1188                 Py_XDECREF(exception); Py_XDECREF(err); Py_XDECREF(tb);
1189                 printf("imported from text buffer...\n");
1190         } else {
1191                 PyErr_Restore(exception, err, tb);
1192         }
1193         return m;
1194 }
1195
1196 void init_ourImport(void)
1197 {
1198         PyObject *m, *d;
1199         PyObject *import = PyCFunction_New(bimport, NULL);
1200
1201         m = PyImport_AddModule("__builtin__");
1202         d = PyModule_GetDict(m);
1203         PyDict_SetItemString(d, "__import__", import);
1204 }
1205
1206 /* this makes sure BLI_gethome() returns a path with '.blender' appended
1207  * Besides, this function now either returns userhome/.blender (if it exists)
1208  * or blenderInstallDir/.blender/ otherwise */
1209 char *bpy_gethome()
1210 {
1211         static char homedir[FILE_MAXDIR];
1212         char bprogdir[FILE_MAXDIR];
1213         char *s;
1214         int i;
1215
1216         if (homedir[0] != '\0') return homedir; /* no need to search twice */
1217
1218         s = BLI_gethome();
1219
1220         if (strstr(s, ".blender")) PyOS_snprintf(homedir, FILE_MAXDIR, s);
1221         else BLI_make_file_string ("/", homedir, s, ".blender/");
1222
1223         /* if userhome/.blender/ exists, return it */
1224         if (BLI_exists(homedir)) return homedir;
1225
1226         /* otherwise, use argv[0] (bprogname) to get .blender/ in
1227          * Blender's installation dir */
1228         s = BLI_last_slash(bprogname);
1229
1230         i = s - bprogname + 1;
1231
1232         PyOS_snprintf(bprogdir, i, bprogname);
1233         BLI_make_file_string ("/", homedir, bprogdir, ".blender/");
1234
1235         return homedir;
1236 }