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