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