==Python API==
[blender.git] / source / blender / python / api2_2x / Window.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Willian P. Germano, Tom Musgrove, Michael Reimpell,
29  * Yann Vernier, Ken Hughes
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32 */
33
34 #include <Python.h>
35
36 #include "BDR_editobject.h"     /* enter / leave editmode */
37 #include "BKE_global.h"
38 #include "BKE_main.h"
39 #include "BKE_object.h"         /* for during_script() and during_scriptlink() */
40 #include "BKE_scene.h"          /* scene_find_camera() */
41 #include "BPI_script.h"
42 #include "BIF_mywindow.h"
43 #include "BIF_imasel.h"
44 #include "BSE_headerbuttons.h"
45 #include "BSE_filesel.h"
46 #include "BIF_editmesh.h"       /* for undo_push_mesh() */
47 #include "BIF_screen.h"
48 #include "BIF_space.h"
49 #include "BIF_drawtext.h"
50 #include "BIF_poseobject.h"
51 #include "DNA_view3d_types.h"
52 #include "DNA_space_types.h"
53 #include "DNA_scene_types.h"
54 #include "DNA_text_types.h"
55 #include "DNA_object_types.h"
56 #include "mydevice.h"
57 #include "blendef.h"            /* OBACT */
58 #include "windowTheme.h"
59 #include "Mathutils.h"
60 #include "constant.h"
61 #include "gen_utils.h"
62 #include "Armature.h"
63
64 /* See Draw.c */
65 extern int EXPP_disable_force_draw;
66 extern void setcameratoview3d(void);
67
68 /*****************************************************************************/
69 /* Python API function prototypes for the Window module.                */
70 /*****************************************************************************/
71 PyObject *M_Window_Redraw( PyObject * self, PyObject * args );
72 static PyObject *M_Window_RedrawAll( PyObject * self, PyObject * args );
73 static PyObject *M_Window_QRedrawAll( PyObject * self, PyObject * args );
74 static PyObject *M_Window_DrawProgressBar( PyObject * self, PyObject * args );
75 static PyObject *M_Window_GetCursorPos( PyObject * self );
76 static PyObject *M_Window_SetCursorPos( PyObject * self, PyObject * args );
77 static PyObject *M_Window_WaitCursor( PyObject * self, PyObject * args );
78 static PyObject *M_Window_GetViewVector( PyObject * self );
79 static PyObject *M_Window_GetActiveLayer( PyObject * self );
80 static PyObject *M_Window_SetActiveLayer( PyObject * self, PyObject * args );
81 static PyObject *M_Window_GetViewQuat( PyObject * self );
82 static PyObject *M_Window_SetViewQuat( PyObject * self, PyObject * args );
83 static PyObject *M_Window_GetViewOffset( PyObject * self );
84 static PyObject *M_Window_SetViewOffset( PyObject * self, PyObject * args );
85 static PyObject *M_Window_GetViewMatrix( PyObject * self );
86 static PyObject *M_Window_GetPerspMatrix( PyObject * self );
87 static PyObject *M_Window_FileSelector( PyObject * self, PyObject * args );
88 static PyObject *M_Window_ImageSelector( PyObject * self, PyObject * args );
89 static PyObject *M_Window_EditMode( PyObject * self, PyObject * args );
90 static PyObject *M_Window_PoseMode( PyObject * self, PyObject * args );
91 static PyObject *M_Window_ViewLayers( PyObject * self, PyObject * args );
92 static PyObject *M_Window_CameraView( PyObject * self, PyObject * args );
93 static PyObject *M_Window_QTest( PyObject * self );
94 static PyObject *M_Window_QRead( PyObject * self );
95 static PyObject *M_Window_QAdd( PyObject * self, PyObject * args );
96 static PyObject *M_Window_QHandle( PyObject * self, PyObject * args );
97 static PyObject *M_Window_GetMouseCoords( PyObject * self );
98 static PyObject *M_Window_SetMouseCoords( PyObject * self, PyObject * args );
99 static PyObject *M_Window_GetMouseButtons( PyObject * self );
100 static PyObject *M_Window_GetKeyQualifiers( PyObject * self );
101 static PyObject *M_Window_SetKeyQualifiers( PyObject * self, PyObject * args );
102 static PyObject *M_Window_GetAreaSize( PyObject * self );
103 static PyObject *M_Window_GetAreaID( PyObject * self );
104 static PyObject *M_Window_GetScreenSize( PyObject * self );
105 static PyObject *M_Window_GetScreens( PyObject * self );
106 static PyObject *M_Window_SetScreen( PyObject * self, PyObject * value );
107 static PyObject *M_Window_GetScreenInfo( PyObject * self, PyObject * args,
108                                          PyObject * kwords );
109 PyObject *Window_Init( void );
110
111
112 /*****************************************************************************/
113 /* The following string definitions are used for documentation strings.     */
114 /* In Python these will be written to the console when doing a              */
115 /* Blender.Window.__doc__                                                   */
116 /*****************************************************************************/
117 static char M_Window_doc[] = "The Blender Window module\n\n";
118
119 static char M_Window_Redraw_doc[] =
120         "() - Force a redraw of a specific Window Type (see Window.Types)";
121
122 static char M_Window_RedrawAll_doc[] = "() - Redraw all windows";
123
124 static char M_Window_QRedrawAll_doc[] =
125         "() - Redraw all windows by queue event";
126
127 static char M_Window_FileSelector_doc[] =
128         "(callback [, title, filename]) - Open a file selector window.\n\
129 The selected file name is used as argument to a function callback f(name)\n\
130 that you must provide. 'title' is optional and defaults to 'SELECT FILE'.\n\
131 'filename' is optional and defaults to Blender.Get('filename').\n\n\
132 Example:\n\n\
133 import Blender\n\n\
134 def my_function(filename):\n\
135         print 'The selected file was: ', filename\n\n\
136 Blender.Window.FileSelector(my_function, 'SAVE FILE')\n";
137
138 static char M_Window_ImageSelector_doc[] =
139         "(callback [, title, filename]) - Open an image selector window.\n\
140 The selected file name is used as argument to a function callback f(name)\n\
141 that you must provide. 'title' is optional and defaults to 'SELECT IMAGE'.\n\
142 'filename' is optional and defaults to Blender.Get('filename').\n\n\
143 Example:\n\n\
144 import Blender\n\n\
145 def my_function(filename):\n\
146         print 'The selected image file was: ', filename\n\n\
147 Blender.Window.ImageSelector(my_function, 'LOAD IMAGE')\n";
148
149 static char M_Window_DrawProgressBar_doc[] =
150         "(done, text) - Draw a progress bar.\n\
151 'done' is a float value <= 1.0, 'text' contains info about what is\n\
152 currently being done.";
153
154 static char M_Window_GetCursorPos_doc[] =
155         "() - Get the current 3d cursor position as a list of three floats.";
156
157 static char M_Window_SetCursorPos_doc[] =
158         "([f,f,f]) - Set the current 3d cursor position from a list of three floats.";
159
160 static char M_Window_WaitCursor_doc[] =
161         "(bool) - Set cursor to wait mode (nonzero bool) or normal mode (0).";
162
163 static char M_Window_GetViewVector_doc[] =
164         "() - Get the current 3d view vector as a list of three floats [x,y,z].";
165
166 static char M_Window_GetActiveLayer_doc[] =
167         "() - Get the current 3d views active layer where new objects are created.";
168
169 static char M_Window_SetActiveLayer_doc[] =
170         "(int) - Set the current 3d views active layer where new objects are created.";
171
172 static char M_Window_GetViewMatrix_doc[] =
173         "() - Get the current 3d view matrix.";
174
175 static char M_Window_GetPerspMatrix_doc[] =
176         "() - Get the current 3d Persp matrix.";
177
178 static char M_Window_EditMode_doc[] =
179         "() - Get the current status -- 0: not in edit mode; 1: in edit mode.\n\
180 (status) - if 1: enter edit mode; if 0: leave edit mode.\n\
181 Returns the current status.  This function is mostly useful to leave\n\
182 edit mode before applying changes to a mesh (otherwise the changes will\n\
183 be lost) and then returning to it upon leaving.";
184
185 static char M_Window_PoseMode_doc[] =
186                 "() - Get the current status -- 0: not in pose mode; 1: in edit mode";
187
188 static char M_Window_ViewLayers_doc[] =
189         "(layers = [], winid = None) - Get/set active layers in all 3d View windows.\n\
190 () - Make no changes, only return currently visible layers.\n\
191 (layers = []) - a list of integers, each in the range [1, 20].\n\
192 (layers = [], winid = int) - layers as above, winid is an optional.\n\
193 arg that makes the function only set layers for that view.\n\
194 This function returns the currently visible layers as a list of ints.";
195
196 static char M_Window_GetViewQuat_doc[] =
197         "() - Get the current VIEW3D view quaternion values.";
198
199 static char M_Window_SetViewQuat_doc[] =
200         "(quat) - Set the current VIEW3D view quaternion values.\n\
201 (quat) - [f,f,f,f] or f,f,f,f: the new float values.";
202
203 static char M_Window_GetViewOffset_doc[] =
204         "() - Get the current VIEW3D view offset values.";
205
206 static char M_Window_SetViewOffset_doc[] =
207         "(ofs) - Set the current VIEW3D view offset values.\n\
208 (ofs) - [f,f,f] or f,f,f: the new float values.";
209
210 static char M_Window_CameraView_doc[] =
211         "(camtov3d = 0) - Set the current VIEW3D view to the active camera's view.\n\
212 (camtov3d = 0) - bool: if nonzero it's the camera that gets positioned at the\n\
213 current view, instead of the view being changed to that of the camera.\n\n\
214 If no camera is the active object, the active camera for the current scene\n\
215 is used.";
216
217 static char M_Window_QTest_doc[] =
218         "() - Check if there are pending events in the event queue.";
219
220 static char M_Window_QRead_doc[] =
221         "() - Get the next pending event from the event queue.\n\
222 This function returns a list [event, val], where:\n\
223 event - int: the key or mouse event (see Blender.Draw module);\n\
224 val - int: if 1 it's a key or mouse button press, if 0 a release.  For\n\
225         mouse movement events 'val' returns the new coordinates in x or y.";
226
227 static char M_Window_QAdd_doc[] =
228         "(win, evt, val, after = 0) - Add an event to some window's event queue.\n\
229 (win) - int: the win id, see Blender.Window.GetScreenInfo();\n\
230 (evt) - int: the event number, see events in Blender.Draw;\n\
231 (val) - bool: 1 for a key press, 0 for a release;\n\
232 (after) - bool: if 1 the event is put after the current queue and added later.";
233
234 static char M_Window_QHandle_doc[] =
235         "(win) - Process all events for the given window (area) now.\n\
236 (win) - int: the window id, see Blender.Window.GetScreenInfo().\n\n\
237 See Blender.Window.QAdd() for how to send events to a particular window.";
238
239 static char M_Window_GetMouseCoords_doc[] =
240         "() - Get mouse pointer's current screen coordinates.";
241
242 static char M_Window_SetMouseCoords_doc[] =
243         "(x, y) - Set mouse pointer's current screen coordinates.\n\
244 (x,y) - ints ([x, y] also accepted): the new x, y coordinates.";
245
246 static char M_Window_GetMouseButtons_doc[] =
247         "() - Get the current mouse button state (see Blender.Window.MButs dict).";
248
249 static char M_Window_GetKeyQualifiers_doc[] =
250         "() - Get the current qualifier keys state.\n\
251 An int is returned: or'ed combination of values in Blender.Window.Qual's dict.";
252
253 static char M_Window_SetKeyQualifiers_doc[] =
254         "(qual) - Fake qualifier keys state.\n\
255 (qual) - int: an or'ed combination of the values in Blender.Window.Qual dict.\n\
256 Note: remember to reset to 0 after handling the related event (see QAdd()).";
257
258 static char M_Window_GetAreaID_doc[] =
259         "() - Get the current window's (area) ID.";
260
261 static char M_Window_GetAreaSize_doc[] =
262         "() - Get the current window's (area) size as [width, height].";
263
264 static char M_Window_GetScreenSize_doc[] =
265         "() - Get the screen's size as [width, height].";
266
267 static char M_Window_GetScreens_doc[] =
268         "() - Get a list with the names of all available screens.";
269
270 static char M_Window_SetScreen_doc[] =
271         "(name) - Set current screen to the one with the given 'name'.";
272
273 static char M_Window_GetScreenInfo_doc[] =
274         "(type = -1, rect = 'win', screen = None)\n\
275 - Get info about the the areas in the current screen setup.\n\
276 (type = -1) - int: the space type (Blender.Window.Types) to restrict the\n\
277         results to, all if -1;\n\
278 (rect = 'win') - str: the rectangle of interest.  This defines if the corner\n\
279         coordinates returned will refer to:\n\
280         - the whole area: 'total';\n\
281         - only the header: 'header';\n\
282         - only the window content (default): 'win'.\n\
283 (screen = None) - str: the screen name, current if not given.\n\n\
284 A list of dictionaries (one for each area) is returned.\n\
285 Each dictionary has keys:\n\
286 'vertices': [xmin, ymin, xmax, ymax] area corners;\n\
287 'win': window type, see Blender.Window.Types dict;\n\
288 'id': area's id.";
289
290 /*****************************************************************************/
291 /* Python method structure definition for Blender.Window module:        */
292 /*****************************************************************************/
293 struct PyMethodDef M_Window_methods[] = {
294         {"Redraw", M_Window_Redraw, METH_VARARGS, M_Window_Redraw_doc},
295         {"RedrawAll", M_Window_RedrawAll, METH_VARARGS,
296          M_Window_RedrawAll_doc},
297         {"QRedrawAll", M_Window_QRedrawAll, METH_VARARGS,
298          M_Window_QRedrawAll_doc},
299         {"FileSelector", M_Window_FileSelector, METH_VARARGS,
300          M_Window_FileSelector_doc},
301         {"ImageSelector", ( PyCFunction ) M_Window_ImageSelector, METH_VARARGS,
302          M_Window_ImageSelector_doc},
303         {"DrawProgressBar", M_Window_DrawProgressBar, METH_VARARGS,
304          M_Window_DrawProgressBar_doc},
305         {"drawProgressBar", M_Window_DrawProgressBar, METH_VARARGS,
306          M_Window_DrawProgressBar_doc},
307         {"GetCursorPos", ( PyCFunction ) M_Window_GetCursorPos, METH_NOARGS,
308          M_Window_GetCursorPos_doc},
309         {"SetCursorPos", M_Window_SetCursorPos, METH_VARARGS,
310          M_Window_SetCursorPos_doc},
311         {"WaitCursor", M_Window_WaitCursor, METH_VARARGS,
312          M_Window_WaitCursor_doc},
313         {"GetViewVector", ( PyCFunction ) M_Window_GetViewVector, METH_NOARGS,
314          M_Window_GetViewVector_doc},
315         {"GetActiveLayer", ( PyCFunction ) M_Window_GetActiveLayer, METH_NOARGS,
316          M_Window_GetActiveLayer_doc},
317         {"SetActiveLayer", ( PyCFunction ) M_Window_SetActiveLayer, METH_VARARGS,
318          M_Window_SetActiveLayer_doc},
319         {"GetViewQuat", ( PyCFunction ) M_Window_GetViewQuat, METH_NOARGS,
320          M_Window_GetViewQuat_doc},
321         {"SetViewQuat", ( PyCFunction ) M_Window_SetViewQuat, METH_VARARGS,
322          M_Window_SetViewQuat_doc},
323         {"GetViewOffset", ( PyCFunction ) M_Window_GetViewOffset, METH_NOARGS,
324          M_Window_GetViewOffset_doc},
325         {"SetViewOffset", ( PyCFunction ) M_Window_SetViewOffset, METH_VARARGS,
326          M_Window_SetViewOffset_doc},
327         {"GetViewMatrix", ( PyCFunction ) M_Window_GetViewMatrix, METH_NOARGS,
328          M_Window_GetViewMatrix_doc},
329         {"GetPerspMatrix", ( PyCFunction ) M_Window_GetPerspMatrix, METH_NOARGS,
330          M_Window_GetPerspMatrix_doc},
331         {"EditMode", ( PyCFunction ) M_Window_EditMode, METH_VARARGS,
332          M_Window_EditMode_doc},
333         {"PoseMode", ( PyCFunction ) M_Window_PoseMode, METH_VARARGS,
334          M_Window_PoseMode_doc},
335         {"ViewLayers", ( PyCFunction ) M_Window_ViewLayers, METH_VARARGS,
336          M_Window_ViewLayers_doc},
337          /* typo, deprecate someday: */
338         {"ViewLayer", ( PyCFunction ) M_Window_ViewLayers, METH_VARARGS,
339          M_Window_ViewLayers_doc},
340         {"CameraView", ( PyCFunction ) M_Window_CameraView, METH_VARARGS,
341          M_Window_CameraView_doc},
342         {"QTest", ( PyCFunction ) M_Window_QTest, METH_NOARGS,
343          M_Window_QTest_doc},
344         {"QRead", ( PyCFunction ) M_Window_QRead, METH_NOARGS,
345          M_Window_QRead_doc},
346         {"QAdd", ( PyCFunction ) M_Window_QAdd, METH_VARARGS,
347          M_Window_QAdd_doc},
348         {"QHandle", ( PyCFunction ) M_Window_QHandle, METH_VARARGS,
349          M_Window_QHandle_doc},
350         {"GetMouseCoords", ( PyCFunction ) M_Window_GetMouseCoords,
351          METH_NOARGS,
352          M_Window_GetMouseCoords_doc},
353         {"SetMouseCoords", ( PyCFunction ) M_Window_SetMouseCoords,
354          METH_VARARGS,
355          M_Window_SetMouseCoords_doc},
356         {"GetMouseButtons", ( PyCFunction ) M_Window_GetMouseButtons,
357          METH_NOARGS,
358          M_Window_GetMouseButtons_doc},
359         {"GetKeyQualifiers", ( PyCFunction ) M_Window_GetKeyQualifiers,
360          METH_NOARGS,
361          M_Window_GetKeyQualifiers_doc},
362         {"SetKeyQualifiers", ( PyCFunction ) M_Window_SetKeyQualifiers,
363          METH_VARARGS,
364          M_Window_SetKeyQualifiers_doc},
365         {"GetAreaSize", ( PyCFunction ) M_Window_GetAreaSize, METH_NOARGS,
366          M_Window_GetAreaSize_doc},
367         {"GetAreaID", ( PyCFunction ) M_Window_GetAreaID, METH_NOARGS,
368          M_Window_GetAreaID_doc},
369         {"GetScreenSize", ( PyCFunction ) M_Window_GetScreenSize, METH_NOARGS,
370          M_Window_GetScreenSize_doc},
371         {"GetScreens", ( PyCFunction ) M_Window_GetScreens, METH_NOARGS,
372          M_Window_GetScreens_doc},
373         {"SetScreen", ( PyCFunction ) M_Window_SetScreen, METH_O,
374          M_Window_SetScreen_doc},
375         {"GetScreenInfo", ( PyCFunction ) M_Window_GetScreenInfo,
376          METH_VARARGS | METH_KEYWORDS, M_Window_GetScreenInfo_doc},
377         {NULL, NULL, 0, NULL}
378 };
379
380 /*****************************************************************************/
381 /* Function:    M_Window_Redraw                                         */
382 /* Python equivalent:   Blender.Window.Redraw                           */
383 /*****************************************************************************/
384 /* not static so py_slider_update in Draw.[ch] can use it */
385 PyObject *M_Window_Redraw( PyObject * self, PyObject * args )
386 {
387         ScrArea *tempsa, *sa;
388         int wintype = SPACE_VIEW3D;
389         short redraw_all = 0;
390
391         if( !PyArg_ParseTuple( args, "|i", &wintype ) )
392                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
393                                                 "expected int argument (or nothing)" ) );
394
395         if( wintype < 0 )
396                 redraw_all = 1;
397
398         if( !during_script( ) && !G.background ) {
399                 tempsa = curarea;
400                 sa = G.curscreen->areabase.first;
401
402                 while( sa ) {
403
404                         if( sa->spacetype == wintype || redraw_all ) {
405                                 if (sa->spacetype == SPACE_SCRIPT && EXPP_disable_force_draw) {
406                                                 scrarea_queue_redraw(sa);
407                                 }
408                                 else {
409                                         /* do not call fancy hacks here like pop_space_text(st); (ton) */
410                                         scrarea_do_windraw( sa );
411                                         if( sa->headwin ) scrarea_do_headdraw( sa );
412                                 }
413                         }
414                         sa = sa->next;
415                 }
416
417                 if( curarea != tempsa )
418                         areawinset( tempsa->win );
419
420                 if( curarea ) { /* is null if Blender is in bg mode */
421                         if( curarea->headwin )
422                                 scrarea_do_headdraw( curarea );
423                         screen_swapbuffers(  );
424                 }
425         }
426
427         Py_RETURN_NONE;
428 }
429
430 /*****************************************************************************/
431 /* Function: M_Window_RedrawAll                                         */
432 /* Python equivalent:   Blender.Window.RedrawAll                        */
433 /*****************************************************************************/
434 static PyObject *M_Window_RedrawAll( PyObject * self, PyObject * args )
435 {
436         PyObject *arg = Py_BuildValue( "(i)", -1 );
437         PyObject *ret = M_Window_Redraw( self, arg );
438         Py_DECREF(arg);
439         return ret;
440 }
441
442 /*****************************************************************************/
443 /* Function:    M_Window_QRedrawAll                                     */
444 /* Python equivalent:                   Blender.Window.QRedrawAll       */
445 /*****************************************************************************/
446 static PyObject *M_Window_QRedrawAll( PyObject * self, PyObject * args )
447 {
448         EXPP_allqueue( REDRAWALL, 0 );
449         Py_RETURN_NONE;
450 }
451
452 /*****************************************************************************/
453 /* Function:    M_Window_FileSelector                                   */
454 /* Python equivalent:   Blender.Window.FileSelector                     */
455 /*****************************************************************************/
456
457 /* This is the callback to "activate_fileselect" below.  It receives the
458  * selected filename and (using it as argument) calls the Python callback
459  * provided by the script writer and stored in EXPP_FS_PyCallback. */
460
461 static void getSelectedFile( char *name )
462 {
463         PyObject *pycallback;
464         PyObject *result;
465         Script *script;
466
467         /* let's find the script that owns this callback */
468         script = G.main->script.first;
469         while (script) {
470                 if (script->flags & SCRIPT_RUNNING) break;
471                 script = script->id.next;
472         }
473
474         if (!script) {
475                 if (curarea->spacetype == SPACE_SCRIPT) {
476                         SpaceScript *sc = curarea->spacedata.first;
477                         script = sc->script;
478                 }
479         }
480
481         pycallback = script->py_browsercallback;
482
483         if (pycallback) {
484                 result = PyObject_CallFunction( pycallback, "s", name );
485
486                 if (!result) {
487                         if (G.f & G_DEBUG)
488                                 fprintf(stderr, "BPy error: Callback call failed!\n");
489                 }
490                 else Py_DECREF(result);
491
492                 if (script->py_browsercallback == pycallback)
493                         script->py_browsercallback = NULL;
494                 /* else another call to selector was made inside pycallback */
495
496                 Py_DECREF(pycallback);
497         }
498
499         return;
500 }
501
502 static PyObject *M_Window_FileSelector( PyObject * self, PyObject * args )
503 {
504         char *title = "SELECT FILE";
505         char *filename = G.sce;
506         SpaceScript *sc;
507         Script *script = NULL;
508         PyObject *pycallback = NULL;
509         int startspace = 0;
510
511         if (during_scriptlink())
512                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
513                         "script links can't call the file selector");
514
515         if (G.background)
516                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
517                         "the file selector is not available in background mode");
518
519         if((!PyArg_ParseTuple( args, "O|ss", &pycallback, &title, &filename))
520                 || (!PyCallable_Check(pycallback)))
521                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
522                         "\nexpected a callback function (and optionally one or two strings) "
523                         "as argument(s)" );
524
525         Py_INCREF(pycallback);
526
527 /* trick: we move to a spacescript because then the fileselector will properly
528  * unset our SCRIPT_FILESEL flag when the user chooses a file or cancels the
529  * selection.  This is necessary because when a user cancels, the
530  * getSelectedFile function above doesn't get called and so couldn't unset the
531  * flag. */
532         startspace = curarea->spacetype;
533         if( startspace != SPACE_SCRIPT )
534                 newspace( curarea, SPACE_SCRIPT );
535
536         sc = curarea->spacedata.first;
537
538         /* let's find the script that called us */
539         script = G.main->script.first;
540         while (script) {
541                 if (script->flags & SCRIPT_RUNNING) break;
542                 script = script->id.next;
543         }
544
545         if( !script ) {
546                 /* if not running, then we were already on a SpaceScript space, executing
547                  * a registered callback -- aka: this script has a gui */
548                 script = sc->script;    /* this is the right script */
549         } else {                /* still running, use the trick */
550                 script->lastspace = startspace;
551                 sc->script = script;
552         }
553
554         script->flags |= SCRIPT_FILESEL;
555
556         /* clear any previous callback (nested calls to selector) */
557         if (script->py_browsercallback) {
558                 Py_DECREF((PyObject *)script->py_browsercallback);
559         }
560         script->py_browsercallback = pycallback;
561
562         activate_fileselect( FILE_BLENDER, title, filename, getSelectedFile );
563
564         Py_RETURN_NONE;
565 }
566
567 static PyObject *M_Window_ImageSelector( PyObject * self, PyObject * args )
568 {
569         char *title = "SELECT IMAGE";
570         char *filename = G.sce;
571         SpaceScript *sc;
572         Script *script = NULL;
573         PyObject *pycallback = NULL;
574         int startspace = 0;
575
576         if (during_scriptlink())
577                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
578                         "script links can't call the image selector");
579
580         if (G.background)
581                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
582                         "the image selector is not available in background mode");
583
584         if( !PyArg_ParseTuple( args, "O|ss", &pycallback, &title, &filename ) 
585                 || (!PyCallable_Check(pycallback)))
586                 return EXPP_ReturnPyObjError ( PyExc_AttributeError,
587                         "\nexpected a callback function (and optionally one or two strings) "
588                         "as argument(s)" );
589
590         Py_INCREF(pycallback);
591
592 /* trick: we move to a spacescript because then the fileselector will properly
593  * unset our SCRIPT_FILESEL flag when the user chooses a file or cancels the
594  * selection.  This is necessary because when a user cancels, the
595  * getSelectedFile function above doesn't get called and so couldn't unset the
596  * flag. */
597         startspace = curarea->spacetype;
598         if( startspace != SPACE_SCRIPT )
599                 newspace( curarea, SPACE_SCRIPT );
600
601         sc = curarea->spacedata.first;
602
603         /* let's find the script that called us */
604         script = G.main->script.first;
605         while (script) {
606                 if (script->flags & SCRIPT_RUNNING) break;
607                 script = script->id.next;
608         }
609
610         if( !script ) {
611                 /* if not running, then we were already on a SpaceScript space, executing
612                  * a registered callback -- aka: this script has a gui */
613                 script = sc->script;    /* this is the right script */
614         } else {                /* still running, use the trick */
615                 script->lastspace = startspace;
616                 sc->script = script;
617         }
618
619         script->flags |= SCRIPT_FILESEL;        /* same flag as filesel */
620         /* clear any previous callback (nested calls to selector) */
621         if (script->py_browsercallback) {
622                 Py_DECREF((PyObject *)script->py_browsercallback);
623         }
624         script->py_browsercallback = pycallback;
625
626         activate_imageselect( FILE_BLENDER, title, filename, getSelectedFile );
627
628         Py_RETURN_NONE;
629 }
630
631 /*****************************************************************************/
632 /* Function:    M_Window_DrawProgressBar                                */
633 /* Python equivalent:   Blender.Window.DrawProgressBar                  */
634 /*****************************************************************************/
635 static PyObject *M_Window_DrawProgressBar( PyObject * self, PyObject * args )
636 {
637         float done;
638         char *info = NULL;
639         int retval = 0;
640         ScrArea *sa = curarea;
641
642         if (G.background)
643                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
644                         "the progress bar is not available in background mode");
645
646         if( !PyArg_ParseTuple( args, "fs", &done, &info ) )
647                 return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
648                         "expected a float and a string as arguments" ) );
649
650         retval = progress_bar( done, info );
651
652         areawinset(sa->win);
653
654         return Py_BuildValue( "i", retval );
655 }
656
657 /*****************************************************************************/
658 /* Function:   M_Window_GetCursorPos                                    */
659 /* Python equivalent:   Blender.Window.GetCursorPos                     */
660 /*****************************************************************************/
661 static PyObject *M_Window_GetCursorPos( PyObject * self )
662 {
663         float *cursor = NULL;
664         PyObject *pylist;
665
666         if( G.vd && G.vd->localview )
667                 cursor = G.vd->cursor;
668         else
669                 cursor = G.scene->cursor;
670
671         pylist = Py_BuildValue( "[fff]", cursor[0], cursor[1], cursor[2] );
672
673         if( !pylist )
674                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
675                                                 "GetCursorPos: couldn't create pylist" ) );
676
677         return pylist;
678 }
679
680 /*****************************************************************************/
681 /* Function:    M_Window_SetCursorPos                                   */
682 /* Python equivalent:   Blender.Window.SetCursorPos                     */
683 /*****************************************************************************/
684 static PyObject *M_Window_SetCursorPos( PyObject * self, PyObject * args )
685 {
686         int ok = 0;
687         float val[3];
688
689         if( PyObject_Length( args ) == 3 )
690                 ok = PyArg_ParseTuple( args, "fff", &val[0], &val[1],
691                                        &val[2] );
692         else
693                 ok = PyArg_ParseTuple( args, "(fff)", &val[0], &val[1],
694                                        &val[2] );
695
696         if( !ok )
697                 return EXPP_ReturnPyObjError( PyExc_TypeError,
698                                               "expected [f,f,f] or f,f,f as arguments" );
699
700         if( G.vd && G.vd->localview ) {
701                 G.vd->cursor[0] = val[0];
702                 G.vd->cursor[1] = val[1];
703                 G.vd->cursor[2] = val[2];
704         } else {
705                 G.scene->cursor[0] = val[0];
706                 G.scene->cursor[1] = val[1];
707                 G.scene->cursor[2] = val[2];
708         }
709
710         Py_RETURN_NONE;
711 }
712
713 static PyObject *M_Window_WaitCursor( PyObject * self, PyObject * args )
714 {
715         int bool;
716
717         if( !PyArg_ParseTuple( args, "i", &bool ) )
718                 return EXPP_ReturnPyObjError( PyExc_TypeError,
719                                               "expected bool (0 or 1) or nothing as argument" );
720
721         waitcursor( bool );     /* nonzero bool sets, zero unsets */
722
723         Py_RETURN_NONE;
724 }
725
726 /*****************************************************************************/
727 /* Function:    M_Window_GetViewVector                                  */
728 /* Python equivalent:   Blender.Window.GetViewVector                    */
729 /*****************************************************************************/
730 static PyObject *M_Window_GetViewVector( PyObject * self )
731 {
732         float *vec = NULL;
733
734         if( !G.vd )
735                 Py_RETURN_NONE;
736
737         vec = G.vd->viewinv[2];
738
739         return Py_BuildValue( "[fff]", vec[0], vec[1], vec[2] );
740 }
741
742 /*****************************************************************************/
743 /* Function:    M_Window_GetActiveLayer                                 */
744 /* Python equivalent:   Blender.Window.GetActiveLayer                   */
745 /*****************************************************************************/
746 static PyObject *M_Window_GetActiveLayer( PyObject * self )
747 {
748         if (!G.vd) {
749                 return PyInt_FromLong(0);
750         } else {
751                 return PyInt_FromLong( G.vd->layact );
752         }
753 }
754
755 static PyObject *M_Window_SetActiveLayer( PyObject * self, PyObject * args )
756 {
757         int layer, bit=1;
758         if( !PyArg_ParseTuple( args, "i", &layer ) )
759                 return ( EXPP_ReturnPyObjError( PyExc_TypeError,
760                                                 "expected an int" ) );
761         
762         if (!G.vd)
763                 Py_RETURN_FALSE;
764         
765         bit= 0;
766         while(bit<32) {
767                 if(layer & (1<<bit)) {
768                         G.vd->layact= 1<<bit;
769                         G.vd->lay |= G.vd->layact;
770                         
771                         if (G.vd->scenelock) {
772                                 G.scene->lay |= G.vd->layact; 
773                         }
774                         bit = -1; /* no error */
775                         break;
776                 }
777                 bit++;
778         }
779         
780         if (bit != -1)
781                 return ( EXPP_ReturnPyObjError( PyExc_ValueError,
782                                         "The flag could not be used for the active layer" ) );
783         
784         Py_RETURN_NONE;
785 }
786
787 static PyObject *M_Window_GetViewQuat( PyObject * self )
788 {
789         float *vec = NULL;
790
791         if( !G.vd )
792                 Py_RETURN_NONE;
793
794         vec = G.vd->viewquat;
795
796         return Py_BuildValue( "[ffff]", vec[0], vec[1], vec[2], vec[3] );
797 }
798
799 static PyObject *M_Window_SetViewQuat( PyObject * self, PyObject * args )
800 {
801         int ok = 0;
802         float val[4];
803
804         if( !G.vd )
805                 Py_RETURN_NONE;
806
807         if( PyObject_Length( args ) == 4 )
808                 ok = PyArg_ParseTuple( args, "ffff", &val[0], &val[1], &val[2],
809                                        &val[3] );
810         else
811                 ok = PyArg_ParseTuple( args, "(ffff)", &val[0], &val[1],
812                                        &val[2], &val[3] );
813
814         if( !ok )
815                 return EXPP_ReturnPyObjError( PyExc_TypeError,
816                                               "expected [f,f,f,f] or f,f,f,f as arguments" );
817
818         G.vd->viewquat[0] = val[0];
819         G.vd->viewquat[1] = val[1];
820         G.vd->viewquat[2] = val[2];
821         G.vd->viewquat[3] = val[3];
822
823         Py_RETURN_NONE;
824 }
825
826 static PyObject *M_Window_GetViewOffset( PyObject * self )
827 {
828         if( !G.vd )
829                 Py_RETURN_NONE;
830         return Py_BuildValue( "[fff]", G.vd->ofs[0], G.vd->ofs[1], G.vd->ofs[2] );
831 }
832
833 static PyObject *M_Window_SetViewOffset( PyObject * self, PyObject * args )
834 {
835         int ok = 0;
836         float val[3];
837
838         if( !G.vd )
839                 Py_RETURN_NONE;
840
841         if( PyObject_Length( args ) == 3 )
842                 ok = PyArg_ParseTuple( args, "fff", &val[0], &val[1],
843                                        &val[2] );
844         else
845                 ok = PyArg_ParseTuple( args, "(fff)", &val[0], &val[1],
846                                        &val[2] );
847
848         if( !ok )
849                 return EXPP_ReturnPyObjError( PyExc_TypeError,
850                                               "expected [f,f,f] or f,f,f as arguments" );
851
852         G.vd->ofs[0] = val[0];
853         G.vd->ofs[1] = val[1];
854         G.vd->ofs[2] = val[2];
855
856         Py_RETURN_NONE;
857 }
858
859
860 /*****************************************************************************/
861 /* Function:    M_Window_GetViewMatrix                          */
862 /* Python equivalent:   Blender.Window.GetViewMatrix            */
863 /*****************************************************************************/
864 static PyObject *M_Window_GetViewMatrix( PyObject * self )
865 {
866         if( !G.vd )
867                 Py_RETURN_NONE;
868
869         return newMatrixObject( ( float * ) G.vd->viewmat, 4, 4, Py_WRAP );
870 }
871
872 /*****************************************************************************/
873 /* Function:    M_Window_GetPerspMatrix                         */
874 /* Python equivalent:   Blender.Window.GetPerspMatrix           */
875 /*****************************************************************************/
876 static PyObject *M_Window_GetPerspMatrix( PyObject * self )
877 {
878         if( !G.vd )
879                 Py_RETURN_NONE;
880
881         return newMatrixObject( ( float * ) G.vd->persmat, 4, 4, Py_WRAP );
882 }
883
884
885 /* update_armature_weakrefs()
886  * helper function used in M_Window_EditMode.
887  * rebuilds list of Armature weakrefs in __main__
888  */
889
890 static int update_armature_weakrefs()
891 {
892         /* stuff for armature weak refs */
893         char *list_name = ARM_WEAKREF_LIST_NAME;
894         PyObject *maindict = NULL, *armlist = NULL;
895         PyObject *pyarmature = NULL;
896         int x;
897
898         maindict= PyModule_GetDict(PyImport_AddModule(  "__main__"));
899         armlist = PyDict_GetItemString(maindict, list_name);
900         if( !armlist){
901                 printf("Oops - update_armature_weakrefs()\n");
902                 return 0;
903         }
904
905         for (x = 0; x < PySequence_Size(armlist); x++){
906                 pyarmature = PyWeakref_GetObject(PySequence_GetItem(    armlist, x));
907                 if (pyarmature != Py_None)
908                         Armature_RebuildEditbones(pyarmature);
909         }
910         return 1;
911 }
912
913
914 static PyObject *M_Window_EditMode( PyObject * self, PyObject * args )
915 {
916         short status = -1;
917         char *undo_str = "From script";
918         int undo_str_len = 11;
919         int do_undo = 1;
920
921         if( !PyArg_ParseTuple( args,
922                                 "|hs#i", &status, &undo_str, &undo_str_len, &do_undo ) )
923                 return EXPP_ReturnPyObjError( PyExc_TypeError,
924                                 "expected optional int (bool), string and int (bool) as arguments" );
925
926         if( status >= 0 ) {
927                 if( status ) {
928                         if( !G.obedit ){
929
930                                 //update armatures
931                                 if(! update_armature_weakrefs()){
932                                         return EXPP_ReturnPyObjError( 
933                                                 PyExc_RuntimeError,
934                                                 "internal error -  update_armature_weakrefs");
935                                 }
936
937                                 //enter editmode
938                                 enter_editmode(0);
939                         }
940                 } else if( G.obedit ) {
941                         if( undo_str_len > 63 )
942                                 undo_str[63] = '\0';    /* 64 is max */
943                         BIF_undo_push( undo_str ); /* This checks user undo settings */
944                         exit_editmode( EM_FREEDATA );
945
946                         //update armatures
947                         if(! update_armature_weakrefs()){
948                                 return EXPP_ReturnPyObjError( 
949                                         PyExc_RuntimeError,
950                                         "internal error -  update_armature_weakrefs");
951                         }
952
953                 }
954         }
955
956         return Py_BuildValue( "h", G.obedit ? 1 : 0 );
957 }
958
959 static PyObject *M_Window_PoseMode( PyObject * self, PyObject * args )
960 {
961         short status = -1;
962         short is_posemode = 0;
963         Base *base;
964         
965         if( !PyArg_ParseTuple( args, "|h", &status ) )
966                 return EXPP_ReturnPyObjError( PyExc_TypeError,
967                                                                           "expected optional int (bool) as argument" );
968
969         if( status >= 0 ) {
970                 if( status ) {
971                         enter_posemode();
972                 } else if( G.obedit ) {
973                         exit_posemode();
974                 }
975         }
976
977         base= BASACT;
978         if (base && base->object->flag & OB_POSEMODE) {
979                 is_posemode = 1;
980         }
981         
982         return Py_BuildValue( "h", is_posemode );
983 }
984
985 static PyObject *M_Window_ViewLayers( PyObject * self, PyObject * args )
986 {
987         PyObject *item = NULL;
988         PyObject *list = NULL, *resl = NULL;
989         int val, i, bit = 0, layer = 0, len_list;
990         short winid = -1;
991
992         if( !G.scene ) {
993                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
994                         "can't get pointer to global scene" );
995         }
996
997         /* Pase Args, Nothing, One list, Or a list and an int */
998         if (PyTuple_GET_SIZE(args)!=0) {
999                 if( !PyArg_ParseTuple ( args, "O!|h", &PyList_Type, &list, &winid) ) {
1000                         return EXPP_ReturnPyObjError( PyExc_TypeError,
1001                                         "nothing or a list and optionaly a window ID argument" );       
1002                 }
1003         }
1004         
1005         if( list ) {
1006                 len_list = PyList_Size(list);
1007
1008                 if (len_list == 0)
1009                         return EXPP_ReturnPyObjError( PyExc_AttributeError,
1010                         "list can't be empty, at list one layer must be set" );
1011
1012                 for( i = 0; i < len_list; i++ ) {
1013                         item = PyList_GetItem( list, i );
1014                         if( !PyInt_Check( item ) )
1015                                 return EXPP_ReturnPyObjError
1016                                         ( PyExc_AttributeError,
1017                                           "list must contain only integer numbers" );
1018
1019                         val = ( int ) PyInt_AsLong( item );
1020                         if( val < 1 || val > 20 )
1021                                 return EXPP_ReturnPyObjError
1022                                         ( PyExc_AttributeError,
1023                                           "layer values must be in the range [1, 20]" );
1024
1025                         layer |= 1 << ( val - 1 );
1026                 }
1027                 
1028                 if (winid==-1) {
1029                         /* set scene and viewport */
1030                         G.scene->lay = layer;
1031                         if (G.vd) {
1032                                 G.vd->lay = layer;
1033         
1034                                 while( bit < 20 ) {
1035                                         val = 1 << bit;
1036                                         if( layer & val ) {
1037                                                 G.vd->layact = val;
1038                                                 break;
1039                                         }
1040                                         bit++;
1041                                 }
1042                         }
1043                 } else {
1044                         /* only set the windows layer */
1045                         ScrArea *sa;
1046                         SpaceLink *sl;
1047                         View3D *vd;
1048                          
1049                         if (G.curscreen) { /* can never be too careful */
1050                     for (sa=G.curscreen->areabase.first; sa; sa= sa->next) {
1051                         if (winid == sa->win) {
1052                                 
1053                                 for (sl= sa->spacedata.first; sl; sl= sl->next)
1054                                         if(sl->spacetype==SPACE_VIEW3D)
1055                                                 break;
1056                                 
1057                                 if (!sl)
1058                                         return EXPP_ReturnPyObjError( PyExc_ValueError,
1059                                                 "The window matching the winid has no 3d viewport" );
1060                                 
1061                                 vd= (View3D *) sl;
1062                                 vd->lay = layer;
1063                                 
1064                                 for(bit= 0; bit < 20; bit++) {
1065                                         val = 1 << bit;
1066                                         if( layer & val ) {
1067                                                 vd->layact = val;
1068                                                  break;
1069                                         }
1070                                 }
1071                                 
1072                                 winid = -1; /* so we know its done */
1073                                 break;
1074                         }
1075                     }
1076                                 if (winid!=-1)
1077                                         return EXPP_ReturnPyObjError( PyExc_TypeError,
1078                                                         "The winid argument did not match any window" );
1079                         }
1080                 }
1081         }
1082
1083         resl = PyList_New( 0 );
1084         if( !resl )
1085                 return ( EXPP_ReturnPyObjError( PyExc_MemoryError,
1086                                                 "couldn't create pylist!" ) );
1087
1088         layer = G.scene->lay;
1089
1090         bit = 0;
1091         while( bit < 20 ) {
1092                 val = 1 << bit;
1093                 if( layer & val ) {
1094                         item = Py_BuildValue( "i", bit + 1 );
1095                         PyList_Append( resl, item );
1096                         Py_DECREF( item );
1097                 }
1098                 bit++;
1099         }
1100
1101         return resl;
1102 }
1103
1104 static PyObject *M_Window_CameraView( PyObject * self, PyObject * args )
1105 {
1106         short camtov3d = 0;
1107
1108         if( !PyArg_ParseTuple( args, "|i", &camtov3d ) )
1109                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1110                                               "expected an int (from Window.Views) as argument" );
1111
1112         if( !G.vd )
1113                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1114                         "this function can only be used after a 3d View has been initialized" );
1115
1116         if( !G.vd->camera ) {
1117                 if( BASACT && OBACT->type == OB_CAMERA )
1118                         G.vd->camera = OBACT;
1119                 else
1120                         G.vd->camera = scene_find_camera( G.scene );
1121                 handle_view3d_lock(  );
1122         }
1123
1124         G.vd->persp = 2;
1125         G.vd->view = 0;
1126
1127         if( camtov3d )
1128                 setcameratoview3d(  );
1129
1130         Py_RETURN_NONE;
1131 }
1132
1133 static PyObject *M_Window_QTest( PyObject * self )
1134 {
1135         return Py_BuildValue( "h", qtest(  ) );
1136 }
1137
1138 static PyObject *M_Window_QRead( PyObject * self )
1139 {
1140         short val = 0;
1141         unsigned short event;
1142
1143         if (G.background)
1144                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
1145                         "QRead is not available in background mode");
1146
1147         event = extern_qread( &val );
1148
1149         return Py_BuildValue( "ii", event, val );
1150 }
1151
1152 static PyObject *M_Window_QAdd( PyObject * self, PyObject * args )
1153 {
1154         short win;
1155         short evt;              /* unsigned, we check below */
1156         short val;
1157         short after = 0;
1158
1159         if (G.background)
1160                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
1161                         "QAdd is not available in background mode");
1162
1163         if( !PyArg_ParseTuple( args, "hhh|h", &win, &evt, &val, &after ) )
1164                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1165                                               "expected three or four ints as arguments" );
1166
1167         if( evt < 0 )           /* evt is unsigned short */
1168                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1169                                               "event value must be a positive int, check events in Blender.Draw" );
1170
1171         if( after )
1172                 addafterqueue( win, evt, val );
1173         else
1174                 addqueue( win, evt, val );
1175
1176         Py_RETURN_NONE;
1177 }
1178
1179 static PyObject *M_Window_QHandle( PyObject * self, PyObject * args )
1180 {
1181         short win;
1182         ScrArea *sa;
1183         ScrArea *oldsa = NULL;
1184
1185         if (G.background)
1186                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
1187                         "QHandle is not available in background mode");
1188
1189         if (!G.curscreen)
1190                 return EXPP_ReturnPyObjError(PyExc_RuntimeError,
1191                         "No screens available");
1192         
1193         if( !PyArg_ParseTuple( args, "h", &win ) )
1194                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1195                                               "expected an int as argument" );
1196         
1197         for (sa= G.curscreen->areabase.first; sa; sa= sa->next)
1198                 if( sa->win == win )
1199                         break;
1200
1201         if( sa ) {
1202                 BWinEvent evt;
1203                 short do_redraw = 0, do_change = 0;
1204
1205                 if( sa != curarea || sa->win != mywinget(  ) ) {
1206                         oldsa = curarea;
1207                         areawinset( sa->win );
1208                         set_g_activearea( sa );
1209                 }
1210                 while( bwin_qread( sa->win, &evt ) ) {
1211                         if( evt.event == REDRAW ) {
1212                                 do_redraw = 1;
1213                         } else if( evt.event == CHANGED ) {
1214                                 sa->win_swap = 0;
1215                                 do_change = 1;
1216                                 do_redraw = 1;
1217                         } else {
1218                                 scrarea_do_winhandle( sa, &evt );
1219                         }
1220                 }
1221         }
1222
1223         if( oldsa ) {
1224                 areawinset( oldsa->win );
1225                 set_g_activearea( oldsa );
1226         }
1227
1228         Py_RETURN_NONE;
1229 }
1230
1231 static PyObject *M_Window_GetMouseCoords( PyObject * self )
1232 {
1233         short mval[2];
1234
1235         getmouse( mval );
1236
1237         return Py_BuildValue( "hh", mval[0], mval[1] );
1238 }
1239
1240 static PyObject *M_Window_SetMouseCoords( PyObject * self, PyObject * args )
1241 {
1242         int ok, x, y;
1243
1244         if( !G.curscreen )
1245                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1246                                               "no current screen to retrieve info from!" );
1247
1248         x = G.curscreen->sizex / 2;
1249         y = G.curscreen->sizey / 2;
1250
1251         if( PyObject_Length( args ) == 2 )
1252                 ok = PyArg_ParseTuple( args, "hh", &x, &y );
1253         else
1254                 ok = PyArg_ParseTuple( args, "|(hh)", &x, &y );
1255
1256         if( !ok )
1257                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1258                                               "expected [i, i] or i,i as arguments (or nothing)." );
1259
1260         warp_pointer( x, y );
1261
1262         Py_RETURN_NONE;
1263 }
1264
1265 static PyObject *M_Window_GetMouseButtons( PyObject * self )
1266 {
1267         short mbut = get_mbut(  );
1268
1269         return Py_BuildValue( "h", mbut );
1270 }
1271
1272 static PyObject *M_Window_GetKeyQualifiers( PyObject * self )
1273 {
1274         short qual = get_qual(  );
1275
1276         return Py_BuildValue( "h", qual );
1277 }
1278
1279 static PyObject *M_Window_SetKeyQualifiers( PyObject * self, PyObject * args )
1280 {
1281         short qual = 0;
1282
1283         if( !PyArg_ParseTuple( args, "|h", &qual ) )
1284                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1285                                               "expected nothing or an int (or'ed flags) as argument" );
1286
1287         if( qual < 0 )
1288                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1289                                               "value must be a positive int, check Blender.Window.Qual" );
1290
1291         G.qual = qual;
1292
1293         return Py_BuildValue( "h", qual );
1294 }
1295
1296 static PyObject *M_Window_GetAreaSize( PyObject * self )
1297 {
1298         ScrArea *sa = curarea;
1299
1300         if( !sa )
1301                 Py_RETURN_NONE;
1302
1303         return Py_BuildValue( "hh", sa->winx, sa->winy );
1304 }
1305
1306 static PyObject *M_Window_GetAreaID( PyObject * self )
1307 {
1308         ScrArea *sa = curarea;
1309
1310         if( !sa )
1311                 Py_RETURN_NONE;
1312
1313         return Py_BuildValue( "h", sa->win );
1314 }
1315
1316 static PyObject *M_Window_GetScreenSize( PyObject * self )
1317 {
1318         bScreen *scr = G.curscreen;
1319
1320         if( !scr )
1321                 Py_RETURN_NONE;
1322
1323         return Py_BuildValue( "hh", scr->sizex, scr->sizey );
1324 }
1325
1326
1327 static PyObject *M_Window_SetScreen( PyObject * self, PyObject * value )
1328 {
1329         bScreen *scr = G.main->screen.first;
1330         char *name = PyString_AsString(value);
1331
1332         if( !name )
1333                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1334                                               "expected string as argument" );
1335
1336         while( scr ) {
1337                 if( !strcmp( scr->id.name + 2, name ) ) {
1338                         setscreen( scr );
1339                         break;
1340                 }
1341                 scr = scr->id.next;
1342         }
1343
1344         if( !scr )
1345                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1346                                               "no such screen, check Window.GetScreens() for valid names" );
1347
1348         Py_RETURN_NONE;
1349 }
1350
1351 static PyObject *M_Window_GetScreens( PyObject * self )
1352 {
1353         bScreen *scr = G.main->screen.first;
1354         PyObject *list = PyList_New( 0 );
1355         PyObject *str = NULL;
1356
1357         if( !list )
1358                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
1359                                               "couldn't create py list!" );
1360
1361         while( scr ) {
1362                 str = PyString_FromString( scr->id.name + 2 );
1363
1364                 if( !str ) {
1365                         Py_DECREF( list );
1366                         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1367                                                       "couldn't create py string!" );
1368                 }
1369
1370                 PyList_Append( list, str );     /* incref's str */
1371                 Py_DECREF( str );
1372
1373                 scr = scr->id.next;
1374         }
1375
1376         return list;
1377 }
1378
1379 static PyObject *M_Window_GetScreenInfo( PyObject * self, PyObject * args,
1380                                          PyObject * kwords )
1381 {
1382         ScrArea *sa = G.curscreen->areabase.first;
1383         bScreen *scr = G.main->screen.first;
1384         PyObject *item, *list;
1385         rcti *rct;
1386         int type = -1;
1387         char *rect = "win";
1388         char *screen = "";
1389         static char *kwlist[] = { "type", "rect", "screen", NULL };
1390         int rctype = 0;
1391
1392         if( !PyArg_ParseTupleAndKeywords( args, kwords, "|iss", kwlist, &type,
1393                                           &rect, &screen ) )
1394                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1395                                               "expected nothing or an int and two strings as arguments" );
1396
1397         if( !strcmp( rect, "win" ) )
1398                 rctype = 0;
1399         else if( !strcmp( rect, "total" ) )
1400                 rctype = 1;
1401         else if( !strcmp( rect, "header" ) )
1402                 rctype = 2;
1403         else
1404                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1405                                               "requested invalid type for area rectangle coordinates." );
1406
1407         list = PyList_New( 0 );
1408
1409         if( screen && screen[0] != '\0' ) {
1410                 while( scr ) {
1411                         if( !strcmp( scr->id.name + 2, screen ) ) {
1412                                 sa = scr->areabase.first;
1413                                 break;
1414                         }
1415                         scr = scr->id.next;
1416                 }
1417         }
1418
1419         if( !scr ) {
1420                 Py_DECREF( list );
1421                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1422                                               "no such screen, see existing ones with Window.GetScreens." );
1423         }
1424
1425         while( sa ) {
1426                 if( type != -1 && sa->spacetype != type ) {
1427                         sa = sa->next;
1428                         continue;
1429                 }
1430
1431                 switch ( rctype ) {
1432                 case 0:
1433                         rct = &sa->winrct;
1434                         break;
1435                 case 1:
1436                         rct = &sa->totrct;
1437                         break;
1438                 case 2:
1439                 default:
1440                         rct = &sa->headrct;
1441                 }
1442
1443                 item = Py_BuildValue( "{s:[h,h,h,h],s:h,s:h}",
1444                                       "vertices", rct->xmin, rct->ymin,
1445                                       rct->xmax, rct->ymax, "type",
1446                                       ( short ) sa->spacetype, "id",
1447                                       ( short ) sa->win );
1448                 PyList_Append( list, item );
1449                 Py_DECREF( item );
1450
1451                 sa = sa->next;
1452         }
1453
1454         return list;
1455 }
1456
1457 /*****************************************************************************/
1458 /* Function:    Window_Init                                             */
1459 /*****************************************************************************/
1460 PyObject *Window_Init( void )
1461 {
1462         PyObject *submodule, *Types, *Qual, *MButs, *dict;
1463
1464         submodule =
1465                 Py_InitModule3( "Blender.Window", M_Window_methods,
1466                                 M_Window_doc );
1467
1468         dict = PyModule_GetDict( submodule );
1469         if( dict )
1470                 PyDict_SetItemString( dict, "Theme", Theme_Init(  ) );
1471
1472         Types = PyConstant_New(  );
1473         Qual = PyConstant_New(  );
1474         MButs = PyConstant_New(  );
1475
1476         if( Types ) {
1477                 BPy_constant *d = ( BPy_constant * ) Types;
1478
1479                 PyConstant_Insert( d, "VIEW3D", PyInt_FromLong( SPACE_VIEW3D ) );
1480                 PyConstant_Insert( d, "IPO", PyInt_FromLong( SPACE_IPO ) );
1481                 PyConstant_Insert( d, "OOPS", PyInt_FromLong( SPACE_OOPS ) );
1482                 PyConstant_Insert( d, "BUTS", PyInt_FromLong( SPACE_BUTS ) );
1483                 PyConstant_Insert( d, "FILE", PyInt_FromLong( SPACE_FILE ) );
1484                 PyConstant_Insert( d, "IMAGE", PyInt_FromLong( SPACE_IMAGE ) );
1485                 PyConstant_Insert( d, "INFO", PyInt_FromLong( SPACE_INFO ) );
1486                 PyConstant_Insert( d, "SEQ", PyInt_FromLong( SPACE_SEQ ) );
1487                 PyConstant_Insert( d, "IMASEL", PyInt_FromLong( SPACE_IMASEL ) );
1488                 PyConstant_Insert( d, "SOUND", PyInt_FromLong( SPACE_SOUND ) );
1489                 PyConstant_Insert( d, "ACTION", PyInt_FromLong( SPACE_ACTION ) );
1490                 PyConstant_Insert( d, "TEXT", PyInt_FromLong( SPACE_TEXT ) );
1491                 PyConstant_Insert( d, "NLA", PyInt_FromLong( SPACE_NLA ) );
1492                 PyConstant_Insert( d, "SCRIPT", PyInt_FromLong( SPACE_SCRIPT ) );
1493                 PyConstant_Insert( d, "TIME", PyInt_FromLong( SPACE_TIME ) );
1494                 PyConstant_Insert( d, "NODE", PyInt_FromLong( SPACE_NODE ) );
1495
1496                 PyModule_AddObject( submodule, "Types", Types );
1497         }
1498
1499         if( Qual ) {
1500                 BPy_constant *d = ( BPy_constant * ) Qual;
1501
1502                 PyConstant_Insert( d, "LALT", PyInt_FromLong( L_ALTKEY ) );
1503                 PyConstant_Insert( d, "RALT", PyInt_FromLong( R_ALTKEY ) );
1504                 PyConstant_Insert( d, "ALT", PyInt_FromLong( LR_ALTKEY ) );
1505                 PyConstant_Insert( d, "LCTRL", PyInt_FromLong( L_CTRLKEY ) );
1506                 PyConstant_Insert( d, "RCTRL", PyInt_FromLong( R_CTRLKEY ) );
1507                 PyConstant_Insert( d, "CTRL", PyInt_FromLong( LR_CTRLKEY ) );
1508                 PyConstant_Insert( d, "LSHIFT", PyInt_FromLong( L_SHIFTKEY ) );
1509                 PyConstant_Insert( d, "RSHIFT", PyInt_FromLong( R_SHIFTKEY ) );
1510                 PyConstant_Insert( d, "SHIFT", PyInt_FromLong( LR_SHIFTKEY ) );
1511
1512                 PyModule_AddObject( submodule, "Qual", Qual );
1513         }
1514
1515         if( MButs ) {
1516                 BPy_constant *d = ( BPy_constant * ) MButs;
1517
1518                 PyConstant_Insert( d, "L", PyInt_FromLong( L_MOUSE ) );
1519                 PyConstant_Insert( d, "M", PyInt_FromLong( M_MOUSE ) );
1520                 PyConstant_Insert( d, "R", PyInt_FromLong( R_MOUSE ) );
1521
1522                 PyModule_AddObject( submodule, "MButs", MButs );
1523         }
1524
1525         return submodule;
1526 }