e8a7571c59ffe80575455aa9624ee6621e76c4c1
[blender-staging.git] / source / blender / python / api2_2x / Draw.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, Campbell Barton, Ken Hughes
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 */
32
33 /* This file is the Blender.Draw part of opy_draw.c, from the old
34  * bpython/intern dir, with minor changes to adapt it to the new Python
35  * implementation.      Non-trivial original comments are marked with an
36  * @ symbol at their beginning. */
37
38 #include "Draw.h" /*This must come first*/
39
40 #include "BLI_blenlib.h"
41 #include "MEM_guardedalloc.h"
42 #include "BMF_Api.h"
43 #include "DNA_screen_types.h"
44 #include "BKE_global.h"
45 #include "BKE_image.h"
46 #include "BKE_object.h"
47 #include "BKE_main.h"
48 #include "BIF_gl.h"
49 #include "BIF_screen.h"
50 #include "BIF_space.h"
51 #include "BIF_interface.h"
52 #include "BIF_toolbox.h"
53 #include "BPI_script.h"         /* script struct */
54 #include "Image.h"              /* for accessing Blender.Image objects */
55 #include "IMB_imbuf_types.h"    /* for the IB_rect define */
56 #include "interface.h"
57 #include "mydevice.h"           /*@ for all the event constants */
58 #include "gen_utils.h"
59 #include "Window.h"
60 #include "../BPY_extern.h"
61
62 /* used so we can get G.scene->r.cfra for getting the
63 current image frame, some images change frame if they are a sequence */
64 #include "DNA_scene_types.h"
65
66 /* these delimit the free range for button events */
67 #define EXPP_BUTTON_EVENTS_OFFSET 1001
68 #define EXPP_BUTTON_EVENTS_MIN 0
69 #define EXPP_BUTTON_EVENTS_MAX 15382 /* 16384 - 1 - OFFSET */
70
71 #define ButtonObject_Check(v) ((v)->ob_type == &Button_Type)
72
73 /* pointer to main dictionary defined in Blender.c */
74 extern PyObject *g_blenderdict;
75
76 /*@ hack to flag that window redraw has happened inside slider callback: */
77 int EXPP_disable_force_draw = 0;
78
79 /* forward declarations for internal functions */
80 static void Button_dealloc( PyObject * self );
81 static PyObject *Button_getattr( PyObject * self, char *name );
82 static PyObject *Button_repr( PyObject * self );
83 static PyObject *Button_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type);
84 static int Button_setattr( PyObject * self, char *name, PyObject * v );
85
86 static Button *newbutton( void );
87
88 /* GUI interface routines */
89
90 static void exit_pydraw( SpaceScript * sc, short error );
91 static void exec_callback( SpaceScript * sc, PyObject * callback,
92                            PyObject * args );
93 static void spacescript_do_pywin_buttons( SpaceScript * sc,
94                                           unsigned short event );
95
96 static PyObject *Method_Exit( PyObject * self, PyObject * args );
97 static PyObject *Method_Register( PyObject * self, PyObject * args );
98 static PyObject *Method_Redraw( PyObject * self, PyObject * args );
99 static PyObject *Method_Draw( PyObject * self, PyObject * args );
100 static PyObject *Method_Create( PyObject * self, PyObject * args );
101
102 static PyObject *Method_Button( PyObject * self, PyObject * args );
103 static PyObject *Method_Menu( PyObject * self, PyObject * args );
104 static PyObject *Method_Toggle( PyObject * self, PyObject * args );
105 static PyObject *Method_Slider( PyObject * self, PyObject * args );
106 static PyObject *Method_Scrollbar( PyObject * self, PyObject * args );
107 static PyObject *Method_ColorPicker( PyObject * self, PyObject * args );
108 static PyObject *Method_Normal( PyObject * self, PyObject * args );
109 static PyObject *Method_Number( PyObject * self, PyObject * args );
110 static PyObject *Method_String( PyObject * self, PyObject * args );
111 static PyObject *Method_GetStringWidth( PyObject * self, PyObject * args );
112 static PyObject *Method_Text( PyObject * self, PyObject * args );
113 static PyObject *Method_PupMenu( PyObject * self, PyObject * args );
114 /* next Five by Campbell: */
115 static PyObject *Method_PupIntInput( PyObject * self, PyObject * args );
116 static PyObject *Method_PupFloatInput( PyObject * self, PyObject * args );
117 static PyObject *Method_PupStrInput( PyObject * self, PyObject * args );
118 static PyObject *Method_BeginAlign( PyObject * self, PyObject * args  );
119 static PyObject *Method_EndAlign( PyObject * self, PyObject * args  );
120 /* next by Jonathan Merritt (lancelet): */
121 static PyObject *Method_Image( PyObject * self, PyObject * args);
122 /* CLEVER NUMBUT */
123 static PyObject *Method_PupBlock( PyObject * self, PyObject * args );
124
125 static uiBlock *Get_uiBlock( void );
126 static void py_slider_update( void *butv, void *data2_unused );
127
128 static char Draw_doc[] = "The Blender.Draw submodule";
129
130 static char Method_Register_doc[] =
131         "(draw, event, button) - Register callbacks for windowing\n\n\
132 (draw) A function to draw the screen, taking no arguments\n\
133 (event) A function to handle events, taking 2 arguments (evt, val)\n\
134         (evt) The event number\n\
135         (val) The value modifier (for key and mouse press/release)\n\
136 (button) A function to handle button events, taking 1 argument (evt)\n\
137         (evt) The button number\n\n\
138 A None object can be passed if a callback is unused.";
139
140
141 static char Method_Redraw_doc[] = "([after]) - Queue a redraw event\n\n\
142 [after=0] Determines whether the redraw is processed before\n\
143 or after other input events.\n\n\
144 Redraw events are buffered so that regardless of how many events\n\
145 are queued the window only receives one redraw event.";
146
147 static char Method_Draw_doc[] = "() - Force an immediate redraw\n\n\
148 Forced redraws are not buffered, in other words the window is redrawn\n\
149 exactly once for everytime this function is called.";
150
151
152 static char Method_Create_doc[] =
153         "(value) - Create a default Button object\n\n\
154  (value) - The value to store in the button\n\n\
155  Valid values are ints, floats, and strings";
156
157 static char Method_Button_doc[] =
158         "(name, event, x, y, width, height, [tooltip]) - Create a new Button \
159 (push) button\n\n\
160 (name) A string to display on the button\n\
161 (event) The event number to pass to the button event function when activated\n\
162 (x, y) The lower left coordinate of the button\n\
163 (width, height) The button width and height\n\
164 [tooltip=] The button's tooltip\n\n\
165 This function can be called as Button() or PushButton().";
166
167 static char Method_BeginAlign_doc[] =
168         "Buttons after this function will draw aligned (button layout only)";
169
170 static char Method_EndAlign_doc[] =
171         "Use after BeginAlign() to stop aligning the buttons (button layout only).";
172
173 static char Method_Menu_doc[] =
174         "(name, event, x, y, width, height, default, [tooltip]) - Create a new Menu \
175 button\n\n\
176 (name) A string to display on the button\n\
177 (event) The event number to pass to the button event function when activated\n\
178 (x, y) The lower left coordinate of the button\n\
179 (width, height) The button width and height\n\
180 (default) The number of the option to be selected by default\n\
181 [tooltip=" "] The button's tooltip\n\n\
182 The menu options are specified through the name of the\n\
183 button. Options are followed by a format code and separated\n\
184 by the '|' (pipe) character.\n\
185 Valid format codes are\n\
186         %t - The option should be used as the title\n\
187         %xN - The option should set the integer N in the button value.";
188
189 static char Method_Toggle_doc[] =
190         "(name, event, x, y, width, height, default, [tooltip]) - Create a new Toggle \
191 button\n\n\
192 (name) A string to display on the button\n\
193 (event) The event number to pass to the button event function when activated\n\
194 (x, y) The lower left coordinate of the button\n\
195 (width, height) The button width and height\n\
196 (default) An integer (0 or 1) specifying the default state\n\
197 [tooltip=] The button's tooltip";
198
199
200 static char Method_Slider_doc[] =
201         "(name, event, x, y, width, height, initial, min, max, [update, tooltip]) - \
202 Create a new Slider button\n\n\
203 (name) A string to display on the button\n\
204 (event) The event number to pass to the button event function when activated\n\
205 (x, y) The lower left coordinate of the button\n\
206 (width, height) The button width and height\n\
207 (initial, min, max) Three values (int or float) specifying the initial \
208                                 and limit values.\n\
209 [update=1] A value controlling whether the slider will emit events as it \
210 is edited.\n\
211         A non-zero value (default) enables the events. A zero value supresses them.\n\
212 [tooltip=] The button's tooltip";
213
214
215 static char Method_Scrollbar_doc[] =
216         "(event, x, y, width, height, initial, min, max, [update, tooltip]) - Create a \
217 new Scrollbar\n\n\
218 (event) The event number to pass to the button event function when activated\n\
219 (x, y) The lower left coordinate of the button\n\
220 (width, height) The button width and height\n\
221 (initial, min, max) Three values (int or float) specifying the initial and limit values.\n\
222 [update=1] A value controlling whether the slider will emit events as it is edited.\n\
223         A non-zero value (default) enables the events. A zero value supresses them.\n\
224 [tooltip=] The button's tooltip";
225
226 static char Method_ColorPicker_doc[] = 
227         "(event, x, y, width, height, initial, [tooltip]) - Create a new Button \
228 Color picker button\n\n\
229 (event) The event number to pass to the button event function when the color changes\n\
230 (x, y) The lower left coordinate of the button\n\
231 (width, height) The button width and height\n\
232 (initial) 3-Float tuple of the color (values between 0 and 1)\
233 [tooltip=] The button's tooltip";
234
235 static char Method_Normal_doc[] = 
236         "(event, x, y, width, height, initial, [tooltip]) - Create a new Button \
237 Normal button (a sphere that you can roll to change the normal)\n\n\
238 (event) The event number to pass to the button event function when the color changes\n\
239 (x, y) The lower left coordinate of the button\n\
240 (width, height) The button width and height - non square will gave odd results\n\
241 (initial) 3-Float tuple of the normal vector (values between -1 and 1)\
242 [tooltip=] The button's tooltip";
243
244 static char Method_Number_doc[] =
245         "(name, event, x, y, width, height, initial, min, max, [tooltip]) - Create a \
246 new Number button\n\n\
247 (name) A string to display on the button\n\
248 (event) The event number to pass to the button event function when activated\n\
249 (x, y) The lower left coordinate of the button\n\
250 (width, height) The button width and height\n\
251 (initial, min, max) Three values (int or float) specifying the initial and \
252 limit values.\n\
253 [tooltip=] The button's tooltip";
254
255 static char Method_String_doc[] =
256         "(name, event, x, y, width, height, initial, length, [tooltip]) - Create a \
257 new String button\n\n\
258 (name) A string to display on the button\n\
259 (event) The event number to pass to the button event function when activated\n\
260 (x, y) The lower left coordinate of the button\n\
261 (width, height) The button width and height\n\
262 (initial) The string to display initially\n\
263 (length) The maximum input length\n\
264 [tooltip=] The button's tooltip";
265
266 static char Method_GetStringWidth_doc[] =
267         "(text, font = 'normal') - Return the width in pixels of the given string\n\
268 (font) The font size: 'normal' (default), 'small' or 'tiny'.";
269
270 static char Method_Text_doc[] =
271         "(text, font = 'normal') - Draw text onscreen\n\n\
272 (text) The text to draw\n\
273 (font) The font size: 'normal' (default), 'small' or 'tiny'.\n\n\
274 This function returns the width of the drawn string.";
275
276 static char Method_PupMenu_doc[] =
277         "(string, maxrow = None) - Display a pop-up menu at the screen.\n\
278 The contents of the pop-up are specified through the 'string' argument,\n\
279 like with Draw.Menu.\n\
280 'maxrow' is an optional int to control how many rows the pop-up should have.\n\
281 Options are followed by a format code and separated\n\
282 by the '|' (pipe) character.\n\
283 Valid format codes are\n\
284         %t - The option should be used as the title\n\
285         %xN - The option should set the integer N in the button value.\n\n\
286 Ex: Draw.PupMenu('OK?%t|QUIT BLENDER') # should be familiar ...";
287
288 static char Method_PupIntInput_doc[] =
289         "(text, default, min, max) - Display an int pop-up input.\n\
290 (text) - text string to display on the button;\n\
291 (default, min, max) - the default, min and max int values for the button;\n\
292 Return the user input value or None on user exit";
293
294 static char Method_PupFloatInput_doc[] =
295         "(text, default, min, max, clickStep, floatLen) - Display a float pop-up input.\n\
296 (text) - text string to display on the button;\n\
297 (default, min, max) - the default, min and max float values for the button;\n\
298 (clickStep) - float increment/decrement for each click on the button arrows;\n\
299 (floatLen) - an integer defining the precision (number of decimal places) of \n\
300 the float value show.\n\
301 Return the user input value or None on user exit";
302
303 static char Method_Image_doc[] =
304         "(image, x, y, zoomx = 1.0, zoomy = 1.0, [clipx, clipy, clipw, cliph])) \n\
305     - Draw an image.\n\
306 (image) - Blender.Image to draw.\n\
307 (x, y) - floats specifying the location of the image.\n\
308 (zoomx, zoomy) - float zoom factors in horizontal and vertical directions.\n\
309 (clipx, clipy, clipw, cliph) - integers specifying a clipping rectangle within the original image.";
310
311 static char Method_PupStrInput_doc[] =
312         "(text, default, max = 20) - Display a float pop-up input.\n\
313 (text) - text string to display on the button;\n\
314 (default) - the initial string to display (truncated to 'max' chars);\n\
315 (max = 20) - The maximum number of chars the user can input;\n\
316 Return the user input value or None on user exit";
317
318 static char Method_PupBlock_doc[] =
319         "(title, sequence) - Display a pop-up block.\n\
320 (title) - The title of the block.\n\
321 (sequence) - A sequence defining what the block contains. \
322 The order of the list is the order of appearance, from top down.\n\
323 Possible format for sequence items:\n\
324 [value is an object created with Create]\n\
325 \ttext: Defines a label in the block\n\
326 \t(text, value, tooltip = ''): Defines a toggle button \n\
327 \t(text, value, min, max, tooltip = ''): Defines a num or string button \n\
328 \t\t\tdepending on the value.\n\
329 \t\tFor string, max is the maximum length of the text and min is unused.\n\
330 Return 1 if the pop-up is confirmed, 0 otherwise. \n\
331 Warning: On cancel, the value objects are brought back to there previous values, \
332 \texcept for string values which will still contain the modified values.\n";
333
334 static char Method_Exit_doc[] = "() - Exit the windowing interface";
335
336 /*
337 * here we engage in some macro trickery to define the PyMethodDef table
338 */
339
340 #define _MethodDef(func, prefix) \
341         {#func, prefix##_##func, METH_VARARGS, prefix##_##func##_doc}
342
343 /* So that _MethodDef(delete, Scene) expands to:
344  * {"delete", Scene_delete, METH_VARARGS, Scene_delete_doc} */
345
346 #undef MethodDef
347 #define MethodDef(func) _MethodDef(func, Method)
348
349 static struct PyMethodDef Draw_methods[] = {
350         MethodDef( Create ),
351         MethodDef( Button ),
352         MethodDef( Toggle ),
353         MethodDef( Menu ),
354         MethodDef( Slider ),
355         MethodDef( Scrollbar ),
356         MethodDef( ColorPicker ),
357         MethodDef( Normal ),
358         MethodDef( Number ),
359         MethodDef( String ),
360         MethodDef( GetStringWidth ),
361         MethodDef( Text ),
362         MethodDef( PupMenu ),
363         MethodDef( PupIntInput ),
364         MethodDef( PupFloatInput ),
365         MethodDef( PupStrInput ),
366         MethodDef( PupBlock ),
367         MethodDef( Image ),
368         MethodDef( Exit ),
369         MethodDef( Redraw ),
370         MethodDef( Draw ),
371         MethodDef( Register ),
372         {"PushButton", Method_Button, METH_VARARGS, Method_Button_doc},
373         MethodDef( BeginAlign ),
374         MethodDef( EndAlign),
375         {NULL, NULL, 0, NULL}
376 };
377
378 PyTypeObject Button_Type = {
379         PyObject_HEAD_INIT( NULL ) 0,   /*ob_size */
380         "Button",               /*tp_name */
381         sizeof( Button ),       /*tp_basicsize */
382         0,                      /*tp_itemsize */
383         ( destructor ) Button_dealloc,  /*tp_dealloc */
384         ( printfunc ) 0,        /*tp_print */
385         ( getattrfunc ) Button_getattr, /*tp_getattr */
386         ( setattrfunc ) Button_setattr, /*tp_setattr */
387         NULL,           /*tp_cmp */
388         ( reprfunc ) Button_repr,       /*tp_repr */
389
390         /* Method suites for standard classes */
391
392         NULL,                       /* PyNumberMethods *tp_as_number; */
393         NULL,                       /* PySequenceMethods *tp_as_sequence; */
394         NULL,                       /* PyMappingMethods *tp_as_mapping; */
395
396         /* More standard operations (here for binary compatibility) */
397
398         NULL,                       /* hashfunc tp_hash; */
399         NULL,                       /* ternaryfunc tp_call; */
400         NULL,                       /* reprfunc tp_str; */
401         NULL,                       /* getattrofunc tp_getattro; */
402         NULL,                       /* setattrofunc tp_setattro; */
403
404         /* Functions to access object as input/output buffer */
405         NULL,                       /* PyBufferProcs *tp_as_buffer; */
406
407   /*** Flags to define presence of optional/expanded features ***/
408         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
409
410         NULL,                       /*  char *tp_doc;  Documentation string */
411   /*** Assigned meaning in release 2.0 ***/
412         /* call function for all accessible objects */
413         NULL,                       /* traverseproc tp_traverse; */
414
415         /* delete references to contained objects */
416         NULL,                       /* inquiry tp_clear; */
417
418   /***  Assigned meaning in release 2.1 ***/
419   /*** rich comparisons ***/
420         (richcmpfunc)Button_richcmpr,                       /* richcmpfunc tp_richcompare; */
421
422   /***  weak reference enabler ***/
423         0,                          /* long tp_weaklistoffset; */
424
425   /*** Added in release 2.2 ***/
426         /*   Iterators */
427         NULL,                       /* getiterfunc tp_iter; */
428         NULL,                       /* iternextfunc tp_iternext; */
429
430   /*** Attribute descriptor and subclassing stuff ***/
431         NULL,           /* struct PyMethodDef *tp_methods; */
432         NULL,                       /* struct PyMemberDef *tp_members; */
433         NULL,         /* struct PyGetSetDef *tp_getset; */
434         NULL,                       /* struct _typeobject *tp_base; */
435         NULL,                       /* PyObject *tp_dict; */
436         NULL,                       /* descrgetfunc tp_descr_get; */
437         NULL,                       /* descrsetfunc tp_descr_set; */
438         0,                          /* long tp_dictoffset; */
439         NULL,                       /* initproc tp_init; */
440         NULL,                       /* allocfunc tp_alloc; */
441         NULL,                       /* newfunc tp_new; */
442         /*  Low-level free-memory routine */
443         NULL,                       /* freefunc tp_free;  */
444         /* For PyObject_IS_GC */
445         NULL,                       /* inquiry tp_is_gc;  */
446         NULL,                       /* PyObject *tp_bases; */
447         /* method resolution order */
448         NULL,                       /* PyObject *tp_mro;  */
449         NULL,                       /* PyObject *tp_cache; */
450         NULL,                       /* PyObject *tp_subclasses; */
451         NULL,                       /* PyObject *tp_weaklist; */
452         NULL
453 };
454
455 static void Button_dealloc( PyObject * self )
456 {
457         Button *but = ( Button * ) self;
458
459         if( but->type == BSTRING_TYPE ) {
460                 if( but->val.asstr )
461                         MEM_freeN( but->val.asstr );
462         }
463
464         PyObject_DEL( self );
465 }
466
467 static PyObject *Button_getattr( PyObject * self, char *name )
468 {
469         Button *but = ( Button * ) self;
470         
471         if( strcmp( name, "val" ) == 0 ) {
472                 if( but->type == BINT_TYPE )
473                         return PyInt_FromLong( but->val.asint );
474                 else if( but->type == BFLOAT_TYPE )
475                         return PyFloat_FromDouble( but->val.asfloat );
476                 else if( but->type == BSTRING_TYPE )
477                         return PyString_FromString( but->val.asstr );
478                 else if( but->type == BVECTOR_TYPE )
479                         return Py_BuildValue( "fff", but->val.asvec[0], but->val.asvec[1], but->val.asvec[2] );
480         }
481
482         PyErr_SetString( PyExc_AttributeError, name );
483         return NULL;
484 }
485
486 static int Button_setattr( PyObject * self, char *name, PyObject * v )
487 {
488         Button *but = ( Button * ) self;
489
490         if( strcmp( name, "val" ) == 0 ) {
491                 if( but->type == BINT_TYPE && PyNumber_Check(v) ) {
492                         PyObject *pyVal = PyNumber_Int( v );
493                         if (pyVal) {
494                                 but->val.asint = (int)PyInt_AS_LONG( pyVal );
495                                 Py_DECREF(pyVal);
496                                 return 0;
497                         }
498                 }
499                 else if( but->type == BFLOAT_TYPE && PyNumber_Check(v) ) {
500                         PyObject *pyVal = PyNumber_Float( v );
501                         if (pyVal) {
502                                 but->val.asfloat = (float)PyFloat_AS_DOUBLE( pyVal );
503                                 Py_DECREF(pyVal);
504                                 return 0;
505                         }
506                 }
507                 else if( but->type == BVECTOR_TYPE ) {
508                         if ( PyArg_ParseTuple( v, "fff", but->val.asvec, but->val.asvec+1, but->val.asvec+2 ) )
509                                 return 0;
510                 }
511                 else if( but->type == BSTRING_TYPE && PyString_Check(v) ) {
512                         char *newstr;
513                         unsigned int newlen;
514
515                         PyString_AsStringAndSize( v, &newstr, &newlen );
516                         
517                         if (newlen+1> UI_MAX_DRAW_STR)
518                                 return EXPP_ReturnIntError( PyExc_ValueError, "Error: button string length exceeded max limit (399 chars).");
519
520                         /* if the length of the new string is the same as */
521                         /* the old one, just copy, else delete and realloc. */
522                         if( but->slen == newlen ) {
523                                 BLI_strncpy( but->val.asstr, newstr,
524                                              but->slen + 1 );
525
526                                 return 0;
527
528                         } else {
529                                 MEM_freeN( but->val.asstr );
530                                 but->slen = newlen;
531                                 but->val.asstr =
532                                         MEM_mallocN( but->slen + 1,
533                                                      "button setattr" );
534                                 BLI_strncpy( but->val.asstr, newstr,
535                                              but->slen + 1 );
536
537                                 return 0;
538                         }
539                 }
540         } else {
541                 /*
542                  * Accessing the wrong attribute.
543                  */
544                 return EXPP_ReturnIntError( PyExc_AttributeError, name );
545         }
546
547         /*
548          * Correct attribute but value is incompatible with current button value.
549          */
550         return EXPP_ReturnIntError( PyExc_ValueError, "value incompatible with current button type" );
551 }
552
553 static PyObject *Button_repr( PyObject * self )
554 {
555         return PyObject_Repr( Button_getattr( self, "val" ) );
556 }
557
558 static PyObject *Button_richcmpr(PyObject *objectA, PyObject *objectB, int comparison_type)
559 {
560         if (ButtonObject_Check(objectA))
561                 objectA = Button_getattr( objectA, "val" );
562         if (ButtonObject_Check(objectB))
563                 objectB = Button_getattr( objectB, "val" );
564         return PyObject_RichCompare(objectA, objectB, comparison_type);
565 }
566
567
568 static Button *newbutton( void )
569 {
570         Button *but = NULL;
571         
572         but = ( Button * ) PyObject_NEW( Button, &Button_Type );
573
574         return but;
575 }
576
577 /* GUI interface routines */
578
579 static void exit_pydraw( SpaceScript * sc, short err )
580 {
581         Script *script = NULL;
582
583         if( !sc || !sc->script )
584                 return;
585
586         script = sc->script;
587
588         if( err ) {
589                 PyErr_Print(  );
590                 script->flags = 0;      /* mark script struct for deletion */
591                 error( "Python script error: check console" );
592                 scrarea_queue_redraw( sc->area );
593         }
594
595         Py_XDECREF( ( PyObject * ) script->py_draw );
596         Py_XDECREF( ( PyObject * ) script->py_event );
597         Py_XDECREF( ( PyObject * ) script->py_button );
598
599         script->py_draw = script->py_event = script->py_button = NULL;
600 }
601
602 static void exec_callback( SpaceScript * sc, PyObject * callback,
603                            PyObject * args )
604 {
605         PyObject *result = PyObject_CallObject( callback, args );
606
607         if( result == NULL && sc->script ) {    /* errors in the script */
608
609                 if( sc->script->lastspace == SPACE_TEXT ) {     /*if it can be an ALT+P script */
610                         Text *text = G.main->text.first;
611
612                         while( text ) { /* find it and free its compiled code */
613
614                                 if( !strcmp
615                                     ( text->id.name + 2,
616                                       sc->script->id.name + 2 ) ) {
617                                         BPY_free_compiled_text( text );
618                                         break;
619                                 }
620
621                                 text = text->id.next;
622                         }
623                 }
624                 exit_pydraw( sc, 1 );
625         }
626
627         Py_XDECREF( result );
628         Py_DECREF( args );
629 }
630
631 /* BPY_spacescript_do_pywin_draw, the static spacescript_do_pywin_buttons and
632  * BPY_spacescript_do_pywin_event are the three functions responsible for
633  * calling the draw, buttons and event callbacks registered with Draw.Register
634  * (see Method_Register below).  They are called (only the two BPY_ ones)
635  * from blender/src/drawscript.c */
636
637 void BPY_spacescript_do_pywin_draw( SpaceScript * sc )
638 {
639         uiBlock *block;
640         char butblock[20];
641         Script *script = sc->script;
642
643         sprintf( butblock, "win %d", curarea->win );
644         block = uiNewBlock( &curarea->uiblocks, butblock, UI_EMBOSSX,
645                             UI_HELV, curarea->win );
646
647         if( script->py_draw ) {
648                 glPushAttrib( GL_ALL_ATTRIB_BITS );
649                 exec_callback( sc, script->py_draw, Py_BuildValue( "()" ) );
650                 glPopAttrib(  );
651         } else {
652                 glClearColor( 0.4375, 0.4375, 0.4375, 0.0 );
653                 glClear( GL_COLOR_BUFFER_BIT );
654         }
655
656         uiDrawBlock( block );
657
658         curarea->win_swap = WIN_BACK_OK;
659 }
660
661 static void spacescript_do_pywin_buttons( SpaceScript * sc,
662                                           unsigned short event )
663 {
664         if( sc->script->py_button )
665                 exec_callback( sc, sc->script->py_button,
666                                Py_BuildValue( "(i)", event ) );
667 }
668
669 void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
670         short val, char ascii )
671 {
672         if( event == QKEY && G.qual & ( LR_ALTKEY | LR_CTRLKEY ) ) {
673                 /* finish script: user pressed ALT+Q or CONTROL+Q */
674                 Script *script = sc->script;
675
676                 exit_pydraw( sc, 0 );
677
678                 script->flags &= ~SCRIPT_GUI;   /* we're done with this script */
679
680                 return;
681         }
682
683         if (val) {
684
685                 if (uiDoBlocks( &curarea->uiblocks, event ) != UI_NOTHING) event = 0;
686
687                 if (event == UI_BUT_EVENT) {
688                         /* check that event is in free range for script button events;
689                          * read the comment before check_button_event() below to understand */
690                         if (val >= EXPP_BUTTON_EVENTS_OFFSET && val < 0x4000)
691                                 spacescript_do_pywin_buttons(sc, val - EXPP_BUTTON_EVENTS_OFFSET);
692                         return;
693                 }
694         }
695
696         /* We use the "event" main module var, used by scriptlinks, to pass the ascii
697          * value to event callbacks (gui/event/button callbacks are not allowed
698          * inside scriptlinks, so this is ok) */
699         if( sc->script->py_event ) {
700                 int pass_ascii = 0;
701                 if (ascii > 31 && ascii != 127) {
702                         pass_ascii = 1;
703                         EXPP_dict_set_item_str(g_blenderdict, "event",
704                                         PyInt_FromLong((long)ascii));
705                 }
706                 exec_callback( sc, sc->script->py_event,
707                         Py_BuildValue( "(ii)", event, val ) );
708                 if (pass_ascii)
709                         EXPP_dict_set_item_str(g_blenderdict, "event",
710                                         PyString_FromString(""));
711         }
712 }
713
714 static PyObject *Method_Exit( PyObject * self, PyObject * args )
715 {
716         SpaceScript *sc;
717         Script *script;
718
719         /* if users call Draw.Exit when we are already out of the SPACE_SCRIPT, we
720          * simply return, for compatibility */
721         if( curarea->spacetype == SPACE_SCRIPT )
722                 sc = curarea->spacedata.first;
723         else
724                 return EXPP_incr_ret( Py_None );
725
726         if( !PyArg_ParseTuple( args, "" ) )
727                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
728                                               "expected empty argument list" );
729
730         exit_pydraw( sc, 0 );
731
732         script = sc->script;
733
734         /* remove our lock to the current namespace */
735         script->flags &= ~SCRIPT_GUI;
736
737         return EXPP_incr_ret( Py_None );
738 }
739
740 /* Method_Register (Draw.Register) registers callbacks for drawing, events
741  * and gui button events, so a script can continue executing after the
742  * interpreter reached its end and returned control to Blender.  Everytime
743  * the SPACE_SCRIPT window with this script is redrawn, the registered
744  * callbacks are executed. */
745 static PyObject *Method_Register( PyObject * self, PyObject * args )
746 {
747         PyObject *newdrawc = NULL, *neweventc = NULL, *newbuttonc = NULL;
748         SpaceScript *sc;
749         Script *script;
750         int startspace = 0;
751
752         if( !PyArg_ParseTuple
753             ( args, "O|OO", &newdrawc, &neweventc, &newbuttonc ) )
754                 return EXPP_ReturnPyObjError( PyExc_TypeError,
755                                               "expected one or three PyObjects" );
756
757         if( !PyCallable_Check( newdrawc ) )
758                 newdrawc = NULL;
759         if( !PyCallable_Check( neweventc ) )
760                 neweventc = NULL;
761         if( !PyCallable_Check( newbuttonc ) )
762                 newbuttonc = NULL;
763
764         if( !( newdrawc || neweventc || newbuttonc ) )
765                 return EXPP_incr_ret( Py_None );
766
767         startspace = curarea->spacetype;
768
769         /* first make sure the current area is of type SPACE_SCRIPT */
770         if( startspace != SPACE_SCRIPT )
771                 newspace( curarea, SPACE_SCRIPT );
772
773         sc = curarea->spacedata.first;
774
775         /* There are two kinds of scripts:
776          * a) those that simply run, finish and return control to Blender;
777          * b) those that do like 'a)' above but leave callbacks for drawing,
778          * events and button events, with this Method_Register (Draw.Register
779          * in Python).  These callbacks are called by scriptspaces (Scripts windows).
780          *
781          * We need to flag scripts that leave callbacks so their namespaces are
782          * not deleted when they 'finish' execution, because the callbacks will
783          * still need the namespace.
784          */
785
786         /* Let's see if this is a new script */
787         script = G.main->script.first;
788         while (script) {
789                 if (script->flags & SCRIPT_RUNNING) break;
790                 script = script->id.next;
791         }
792
793         if( !script ) {
794                 /* not new, it's a left callback calling Register again */
795                 script = sc->script;
796                 if( !script ) {
797                         return EXPP_ReturnPyObjError( PyExc_RuntimeError,
798                                 "Draw.Register can't be used inside script links" );
799                 }
800         }
801         else sc->script = script;
802
803         /* Now we have the right script and can set a lock so its namespace can't be
804          * deleted for as long as we need it */
805         script->flags |= SCRIPT_GUI;
806
807         /* save the last space so we can go back to it upon finishing */
808         if( !script->lastspace )
809                 script->lastspace = startspace;
810
811         /* clean the old callbacks */
812         exit_pydraw( sc, 0 );
813
814         /* prepare the new ones and insert them */
815         Py_XINCREF( newdrawc );
816         Py_XINCREF( neweventc );
817         Py_XINCREF( newbuttonc );
818
819         script->py_draw = newdrawc;
820         script->py_event = neweventc;
821         script->py_button = newbuttonc;
822
823         scrarea_queue_redraw( sc->area );
824
825         return EXPP_incr_ret( Py_None );
826 }
827
828 static PyObject *Method_Redraw( PyObject * self, PyObject * args )
829 {
830         int after = 0;
831
832         if( !PyArg_ParseTuple( args, "|i", &after ) )
833                 return EXPP_ReturnPyObjError( PyExc_TypeError,
834                                               "expected int argument (or nothing)" );
835
836         if( after )
837                 addafterqueue( curarea->win, REDRAW, 1 );
838         else
839                 scrarea_queue_winredraw( curarea );
840
841         return EXPP_incr_ret( Py_None );
842 }
843
844 static PyObject *Method_Draw( PyObject * self, PyObject * args )
845 {
846         /*@ If forced drawing is disable queue a redraw event instead */
847         if( EXPP_disable_force_draw ) {
848                 scrarea_queue_winredraw( curarea );
849                 return EXPP_incr_ret( Py_None );
850         }
851
852         if( !PyArg_ParseTuple( args, "" ) )
853                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
854                                               "expected empty argument list" );
855
856         scrarea_do_windraw( curarea );
857
858         screen_swapbuffers(  );
859
860         return EXPP_incr_ret( Py_None );
861 }
862
863 static PyObject *Method_Create( PyObject * self, PyObject * args )
864 {
865         Button *but = NULL;
866         PyObject *val;
867         char *newstr;
868
869         but = newbutton();
870
871         if ( PyArg_ParseTuple( args, "fff", but->val.asvec, but->val.asvec+1, but->val.asvec+2 ) ) {
872                 but->type = BVECTOR_TYPE;
873         }
874         else if ( PyArg_ParseTuple( args, "O!", &PyFloat_Type, &val ) ) {
875                 but->val.asfloat = (float)PyFloat_AS_DOUBLE(val);
876                 but->type = BFLOAT_TYPE;
877         }
878         else if ( PyArg_ParseTuple( args, "O!", &PyInt_Type, &val ) ) {
879                 but->val.asint = (int)PyInt_AS_LONG(val);
880                 but->type = BINT_TYPE;
881         }
882         else if ( PyArg_ParseTuple( args, "s#", &newstr, &but->slen ) ) {
883                 if (but->slen + 1 > UI_MAX_DRAW_STR) {
884                         PyObject_DEL( (PyObject *) but );
885                         but = NULL;
886                         PyErr_SetString( PyExc_TypeError, "string is longer then 399 chars");
887                 } else {
888                         but->type = BSTRING_TYPE;
889                         but->val.asstr = MEM_mallocN( but->slen + 1, "button string" );
890                         BLI_strncpy( but->val.asstr, newstr, but->slen+1 );
891                 }
892         }
893         else {
894                 PyObject_DEL( (PyObject *) but );
895                 but = NULL;
896                 PyErr_SetString( PyExc_TypeError, "expected string, float, int or 3-float tuple argument" );
897         }
898         
899         if (but != NULL) {
900                 PyErr_Clear();
901         }
902
903         return (PyObject*) but;
904 }
905
906 static uiBlock *Get_uiBlock( void )
907 {
908         char butblock[32];
909
910         sprintf( butblock, "win %d", curarea->win );
911
912         return uiGetBlock( butblock, curarea );
913 }
914
915 /* We restrict the acceptable event numbers to a proper "free" range
916  * according to other spaces in Blender.
917  * winqread***space() (space events callbacks) use short for events
918  * (called 'val' there) and we also translate by EXPP_BUTTON_EVENTS_OFFSET
919  * to get rid of unwanted events (check BPY_do_pywin_events above for
920  * explanation). This function takes care of that and proper checking: */
921 static int check_button_event(int *event) {
922         if ((*event < EXPP_BUTTON_EVENTS_MIN) ||
923                         (*event > EXPP_BUTTON_EVENTS_MAX)) {
924                 return -1;
925         }
926         *event += EXPP_BUTTON_EVENTS_OFFSET;
927         return 0;
928 }
929
930 static PyObject *Method_Button( PyObject * self, PyObject * args )
931 {
932         uiBlock *block;
933         char *name, *tip = NULL;
934         int event;
935         int x, y, w, h;
936
937         if( !PyArg_ParseTuple( args, "siiiii|s", &name, &event,
938                                &x, &y, &w, &h, &tip ) )
939                 return EXPP_ReturnPyObjError( PyExc_TypeError,
940                                               "expected a string, five ints and optionally another string as arguments" );
941
942         if (check_button_event(&event) == -1)
943                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
944                         "button event argument must be in the range [0, 16382]");
945
946         block = Get_uiBlock(  );
947
948         if( block )
949                 uiDefBut( block, BUT, event, name, (short)x, (short)y, (short)w, (short)h, 0, 0, 0, 0, 0,
950                           tip );
951
952         return EXPP_incr_ret( Py_None );
953 }
954
955
956
957 static PyObject *Method_BeginAlign( PyObject * self, PyObject * args )
958 {
959         uiBlock *block = Get_uiBlock(  );
960         
961         if (block)
962                 uiBlockBeginAlign(block);
963         
964         return EXPP_incr_ret( Py_None );
965 }
966
967 static PyObject *Method_EndAlign( PyObject * self, PyObject * args )
968 {
969         uiBlock *block = Get_uiBlock(  );
970         
971         if (block)
972                 uiBlockEndAlign(block);
973         
974         return EXPP_incr_ret( Py_None );
975 }
976
977 static PyObject *Method_Menu( PyObject * self, PyObject * args )
978 {
979         uiBlock *block;
980         char *name, *tip = NULL;
981         int event, def;
982         int x, y, w, h;
983         Button *but;
984
985         if( !PyArg_ParseTuple( args, "siiiiii|s", &name, &event,
986                                &x, &y, &w, &h, &def, &tip ) )
987                 return EXPP_ReturnPyObjError( PyExc_TypeError,
988                                               "expected a string, six ints and optionally another string as arguments" );
989
990         if (check_button_event(&event) == -1)
991                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
992                         "button event argument must be in the range [0, 16382]");
993
994         but = newbutton(  );
995         but->type = BINT_TYPE;
996         but->val.asint = def;
997
998         block = Get_uiBlock(  );
999         if( block )
1000                 uiDefButI( block, MENU, event, name, (short)x, (short)y, (short)w, (short)h,
1001                            &but->val.asint, 0, 0, 0, 0, tip );
1002
1003         return ( PyObject * ) but;
1004 }
1005
1006 static PyObject *Method_Toggle( PyObject * self, PyObject * args )
1007 {
1008         uiBlock *block;
1009         char *name, *tip = NULL;
1010         int event;
1011         int x, y, w, h, def;
1012         Button *but;
1013
1014         if( !PyArg_ParseTuple( args, "siiiiii|s", &name, &event,
1015                                &x, &y, &w, &h, &def, &tip ) )
1016                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1017                                               "expected a string, six ints and optionally another string as arguments" );
1018
1019         if (check_button_event(&event) == -1)
1020                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1021                         "button event argument must be in the range [0, 16382]");
1022
1023         but = newbutton(  );
1024         but->type = BINT_TYPE;
1025         but->val.asint = def;
1026
1027         block = Get_uiBlock(  );
1028         if( block )
1029                 uiDefButI( block, TOG, event, name, (short)x, (short)y, (short)w, (short)h,
1030                            &but->val.asint, 0, 0, 0, 0, tip );
1031
1032         return ( PyObject * ) but;
1033 }
1034
1035 /*@DO NOT TOUCH THIS FUNCTION !
1036          Redrawing a slider inside its own callback routine is actually forbidden
1037          with the current toolkit architecture (button routines are not reentrant).
1038          But it works anyway.
1039          XXX This is condemned to be dinosource in future - it's a hack.
1040          */
1041
1042 static void py_slider_update( void *butv, void *data2_unused )
1043 {
1044         uiBut *but = butv;
1045         PyObject *ref = Py_BuildValue( "(i)", SPACE_VIEW3D );
1046         PyObject *ret = NULL;
1047
1048         EXPP_disable_force_draw = 1;
1049         /*@ Disable forced drawing, otherwise the button object which
1050          * is still being used might be deleted */
1051
1052         curarea->win_swap = WIN_BACK_OK;
1053         /* removed global uiFrontBuf (contact ton when this goes wrong here) */
1054
1055         disable_where_script( 1 );
1056
1057         spacescript_do_pywin_buttons( curarea->spacedata.first,
1058                 (unsigned short)uiButGetRetVal( but ) );
1059
1060         /* XXX useless right now, investigate better before a bcon 5 */
1061         ret = M_Window_Redraw( 0, ref );
1062
1063         Py_DECREF(ref);
1064         if (ret) { Py_DECREF(ret); }
1065
1066         disable_where_script( 0 );
1067
1068         EXPP_disable_force_draw = 0;
1069 }
1070
1071 static PyObject *Method_Slider( PyObject * self, PyObject * args )
1072 {
1073         uiBlock *block;
1074         char *name, *tip = NULL;
1075         int event;
1076         int x, y, w, h, realtime = 1;
1077         Button *but;
1078         PyObject *mino, *maxo, *inio;
1079
1080         if( !PyArg_ParseTuple( args, "siiiiiOOO|is", &name, &event,
1081                                &x, &y, &w, &h, &inio, &mino, &maxo, &realtime,
1082                                &tip ) )
1083                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1084                                               "expected a string, five ints, three PyObjects\n\
1085                         and optionally another int and string as arguments" );
1086
1087         if (check_button_event(&event) == -1)
1088                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1089                         "button event argument must be in the range [0, 16382]");
1090
1091         but = newbutton(  );
1092
1093         if( PyFloat_Check( inio ) ) {
1094                 float ini, min, max;
1095
1096                 ini = (float)PyFloat_AsDouble( inio );
1097                 min = (float)PyFloat_AsDouble( mino );
1098                 max = (float)PyFloat_AsDouble( maxo );
1099
1100                 but->type = BFLOAT_TYPE;
1101                 but->val.asfloat = ini;
1102
1103                 block = Get_uiBlock(  );
1104                 if( block ) {
1105                         uiBut *ubut;
1106                         ubut = uiDefButF( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
1107                                           (short)h, &but->val.asfloat, min, max, 0, 0,
1108                                           tip );
1109                         if( realtime )
1110                                 uiButSetFunc( ubut, py_slider_update, ubut,
1111                                               NULL );
1112                 }
1113         } else {
1114                 int ini, min, max;
1115
1116                 ini = PyInt_AsLong( inio );
1117                 min = PyInt_AsLong( mino );
1118                 max = PyInt_AsLong( maxo );
1119
1120                 but->type = BINT_TYPE;
1121                 but->val.asint = ini;
1122
1123                 block = Get_uiBlock(  );
1124                 if( block ) {
1125                         uiBut *ubut;
1126                         ubut = uiDefButI( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
1127                                           (short)h, &but->val.asint, (float)min, (float)max, 0, 0,
1128                                           tip );
1129                         if( realtime )
1130                                 uiButSetFunc( ubut, py_slider_update, ubut,
1131                                               NULL );
1132                 }
1133         }
1134         return ( PyObject * ) but;
1135 }
1136
1137 static PyObject *Method_Scrollbar( PyObject * self, PyObject * args )
1138 {
1139         char *tip = NULL;
1140         uiBlock *block;
1141         int event;
1142         int x, y, w, h, realtime = 1;
1143         Button *but;
1144         PyObject *mino, *maxo, *inio;
1145         float ini, min, max;
1146
1147         if( !PyArg_ParseTuple( args, "iiiiiOOO|is", &event, &x, &y, &w, &h,
1148                                &inio, &mino, &maxo, &realtime, &tip ) )
1149                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1150                         "expected five ints, three PyObjects and optionally\n\
1151 another int and string as arguments" );
1152
1153         if( !PyNumber_Check( inio ) || !PyNumber_Check( inio )
1154             || !PyNumber_Check( inio ) )
1155                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1156                                               "expected numbers for initial, min, and max" );
1157
1158         if (check_button_event(&event) == -1)
1159                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1160                         "button event argument must be in the range [0, 16382]");
1161
1162         but = newbutton(  );
1163
1164         if( PyFloat_Check( inio ) )
1165                 but->type = BFLOAT_TYPE;
1166         else
1167                 but->type = BINT_TYPE;
1168
1169         ini = (float)PyFloat_AsDouble( inio );
1170         min = (float)PyFloat_AsDouble( mino );
1171         max = (float)PyFloat_AsDouble( maxo );
1172
1173         if( but->type == BFLOAT_TYPE ) {
1174                 but->val.asfloat = ini;
1175                 block = Get_uiBlock(  );
1176                 if( block ) {
1177                         uiBut *ubut;
1178                         ubut = uiDefButF( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
1179                                           &but->val.asfloat, min, max, 0, 0,
1180                                           tip );
1181                         if( realtime )
1182                                 uiButSetFunc( ubut, py_slider_update, ubut,
1183                                               NULL );
1184                 }
1185         } else {
1186                 but->val.asint = (int)ini;
1187                 block = Get_uiBlock(  );
1188                 if( block ) {
1189                         uiBut *ubut;
1190                         ubut = uiDefButI( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
1191                                           &but->val.asint, min, max, 0, 0,
1192                                           tip );
1193                         if( realtime )
1194                                 uiButSetFunc( ubut, py_slider_update, ubut,
1195                                               NULL );
1196                 }
1197         }
1198
1199         return ( PyObject * ) but;
1200 }
1201
1202 static PyObject *Method_ColorPicker( PyObject * self, PyObject * args )
1203 {
1204         char USAGE_ERROR[] = "expected a 3-float tuple of values between 0 and 1";
1205         Button *but;
1206         PyObject *inio;
1207         uiBlock *block;
1208         char *tip = NULL;
1209         float col[3];
1210         int event;
1211         short x, y, w, h;
1212         
1213         if( !PyArg_ParseTuple( args, "ihhhhO!|s", &event,
1214                                &x, &y, &w, &h, &PyTuple_Type, &inio, &tip ) )
1215                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1216                                               "expected five ints, one tuple and optionally a string as arguments." );
1217  
1218         if (check_button_event(&event) == -1)
1219                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1220                         "button event argument must be in the range [0, 16382]");
1221  
1222         if ( !PyArg_ParseTuple( inio, "fff", col, col+1, col+2 ) )
1223                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1224
1225         if      (       col[0] < 0 || col[0] > 1
1226                 ||      col[1] < 0 || col[1] > 1
1227                 ||      col[2] < 0 || col[2] > 1 )
1228                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1229
1230         if ( EXPP_check_sequence_consistency( inio, &PyFloat_Type ) != 1 )
1231                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1232  
1233         but = newbutton();
1234  
1235         but->type = BVECTOR_TYPE;
1236         but->val.asvec[0] = col[0];
1237         but->val.asvec[1] = col[1];
1238         but->val.asvec[2] = col[2];
1239         
1240         block = Get_uiBlock(  );
1241         if( block ) {
1242                 uiBut *ubut;
1243                 ubut = uiDefButF( block, COL, event, "", x, y, w, h, but->val.asvec, 0, 0, 0, 0, tip);
1244         }
1245
1246         return ( PyObject * ) but;
1247 }
1248
1249
1250
1251 static PyObject *Method_Normal( PyObject * self, PyObject * args )
1252 {
1253         char USAGE_ERROR[] = "expected a 3-float tuple of values between -1 and 1";
1254         Button *but;
1255         PyObject *inio;
1256         uiBlock *block;
1257         char *tip = NULL;
1258         float nor[3];
1259         int event;
1260         short x, y, w, h;
1261         
1262         if( !PyArg_ParseTuple( args, "ihhhhO!|s", &event,
1263                                &x, &y, &w, &h, &PyTuple_Type, &inio, &tip ) )
1264                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1265                                               "expected five ints, one tuple and optionally a string as arguments." );
1266  
1267         if (check_button_event(&event) == -1)
1268                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1269                         "button event argument must be in the range [0, 16382]");
1270  
1271         if ( !PyArg_ParseTuple( inio, "fff", nor, nor+1, nor+2 ) )
1272                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1273
1274         if ( EXPP_check_sequence_consistency( inio, &PyFloat_Type ) != 1 )
1275                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1276  
1277         but = newbutton();
1278  
1279         but->type = BVECTOR_TYPE;
1280         but->val.asvec[0] = nor[0];
1281         but->val.asvec[1] = nor[1];
1282         but->val.asvec[2] = nor[2];
1283         
1284         block = Get_uiBlock(  );
1285         if( block ) {
1286                 uiBut *ubut;
1287                 ubut = uiDefButF( block, BUT_NORMAL, event, "", x, y, w, h, but->val.asvec, 0.0f, 1.0f, 0, 0, tip);
1288         }
1289         
1290         return ( PyObject * ) but;
1291 }
1292
1293 static PyObject *Method_Number( PyObject * self, PyObject * args )
1294 {
1295         uiBlock *block;
1296         char *name, *tip = NULL;
1297         int event;
1298         int x, y, w, h;
1299         Button *but;
1300         PyObject *mino, *maxo, *inio;
1301
1302         if( !PyArg_ParseTuple( args, "siiiiiOOO|s", &name, &event,
1303                                &x, &y, &w, &h, &inio, &mino, &maxo, &tip ) )
1304                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1305                                               "expected a string, five ints, three PyObjects and\n\
1306                         optionally another string as arguments" );
1307
1308         if (check_button_event(&event) == -1)
1309                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1310                         "button event argument must be in the range [0, 16382]");
1311
1312         but = newbutton(  );
1313
1314         if( PyFloat_Check( inio ) ) {
1315                 float ini, min, max, range, precission=0;
1316
1317                 ini = (float)PyFloat_AsDouble( inio );
1318                 min = (float)PyFloat_AsDouble( mino );
1319                 max = (float)PyFloat_AsDouble( maxo );
1320                 
1321                 range= (float)fabs(max-min); /* Click step will be a 10th of the range. */
1322                 if (!range) range= 1.0f; /* avoid any odd errors */
1323                 
1324                 /* set the precission to display*/
1325                 if      (range>=100.0f) precission=1.0f;
1326                 else if (range>=10.0f) precission=2.0f;
1327                 else if (range>=1.0f) precission=3.0f;
1328                 else precission=4.0f;
1329                 
1330                 but->type = BFLOAT_TYPE;
1331                 but->val.asfloat = ini;
1332
1333                 block = Get_uiBlock(  );
1334                 if( block )
1335                         uiDefButF( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
1336                                    &but->val.asfloat, min, max, 10*range, precission, tip );
1337         } else {
1338                 int ini, min, max;
1339
1340                 ini = PyInt_AsLong( inio );
1341                 min = PyInt_AsLong( mino );
1342                 max = PyInt_AsLong( maxo );
1343
1344                 but->type = BINT_TYPE;
1345                 but->val.asint = ini;
1346
1347                 block = Get_uiBlock(  );
1348                 if( block )
1349                         uiDefButI( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
1350                                    &but->val.asint, (float)min, (float)max, 0, 0, tip );
1351         }
1352
1353         return ( PyObject * ) but;
1354 }
1355
1356 static PyObject *Method_String( PyObject * self, PyObject * args )
1357 {
1358         uiBlock *block;
1359         char *info_arg = NULL, *tip = NULL, *newstr = NULL;
1360         char *info_str = NULL, *info_str0 = " ";
1361         int event;
1362         int x, y, w, h, len, real_len = 0;
1363         Button *but;
1364
1365         if( !PyArg_ParseTuple( args, "siiiiisi|s", &info_arg, &event,
1366                         &x, &y, &w, &h, &newstr, &len, &tip ) )
1367                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1368                         "expected a string, five ints, a string, an int and\n\
1369         optionally another string as arguments" );
1370
1371         if (check_button_event(&event) == -1)
1372                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1373                         "button event argument must be in the range [0, 16382]");
1374
1375         if (len > (UI_MAX_DRAW_STR - 1))
1376                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1377                         "The maximum length of a string is 399, your value is too high.");
1378
1379         real_len = strlen(newstr);
1380         if (real_len > len) real_len = len;
1381
1382         but = newbutton(  );
1383         but->type = BSTRING_TYPE;
1384         but->slen = len;
1385         but->val.asstr = MEM_mallocN( len + 1, "pybutton str" );
1386
1387         BLI_strncpy( but->val.asstr, newstr, len + 1); /* adds '\0' */
1388         but->val.asstr[real_len] = '\0';
1389
1390         if (info_arg[0] == '\0') info_str = info_str0;
1391         else info_str = info_arg;
1392
1393         block = Get_uiBlock(  );
1394         if( block )
1395                 uiDefBut( block, TEX, event, info_str, (short)x, (short)y, (short)w, (short)h,
1396                           but->val.asstr, 0, (float)len, 0, 0, tip );
1397
1398         return ( PyObject * ) but;
1399 }
1400
1401 static PyObject *Method_GetStringWidth( PyObject * self, PyObject * args )
1402 {
1403         char *text;
1404         char *font_str = "normal";
1405         struct BMF_Font *font;
1406         PyObject *width;
1407
1408         if( !PyArg_ParseTuple( args, "s|s", &text, &font_str ) )
1409                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1410                                               "expected one or two string arguments" );
1411
1412         if( !strcmp( font_str, "normal" ) )
1413                 font = ( &G )->font;
1414         else if( !strcmp( font_str, "large" ) )
1415                 font = BMF_GetFont(BMF_kScreen15);
1416         else if( !strcmp( font_str, "small" ) )
1417                 font = ( &G )->fonts;
1418         else if( !strcmp( font_str, "tiny" ) )
1419                 font = ( &G )->fontss;
1420         else
1421                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1422                                               "\"font\" must be: 'large', 'normal' (default), 'small' or 'tiny'." );
1423
1424         width = PyInt_FromLong( BMF_GetStringWidth( font, text ) );
1425
1426         if( !width )
1427                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
1428                                               "couldn't create PyInt" );
1429
1430         return width;
1431 }
1432
1433 static PyObject *Method_Text( PyObject * self, PyObject * args )
1434 {
1435         char *text;
1436         char *font_str = NULL;
1437         struct BMF_Font *font;
1438
1439         if( !PyArg_ParseTuple( args, "s|s", &text, &font_str ) )
1440                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1441                                               "expected one or two string arguments" );
1442
1443         if( !font_str )
1444                 font = ( &G )->font;
1445         else if( !strcmp( font_str, "large" ) )
1446                 font = BMF_GetFont(BMF_kScreen15);
1447         else if( !strcmp( font_str, "normal" ) )
1448                 font = ( &G )->font;
1449         else if( !strcmp( font_str, "small" ) )
1450                 font = ( &G )->fonts;
1451         else if( !strcmp( font_str, "tiny" ) )
1452                 font = ( &G )->fontss;
1453         else
1454                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1455                                               "\"font\" must be: 'normal' (default), 'large', 'small' or 'tiny'." );
1456
1457         BMF_DrawString( font, text );
1458
1459         return PyInt_FromLong( BMF_GetStringWidth( font, text ) );
1460 }
1461
1462 static PyObject *Method_PupMenu( PyObject * self, PyObject * args )
1463 {
1464         char *text;
1465         int maxrow = -1;
1466         PyObject *ret;
1467
1468         if( !PyArg_ParseTuple( args, "s|i", &text, &maxrow ) )
1469                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1470                                               "expected a string and optionally an int as arguments" );
1471
1472         if( maxrow >= 0 )
1473                 ret = PyInt_FromLong( pupmenu_col( text, maxrow ) );
1474         else
1475                 ret = PyInt_FromLong( pupmenu( text ) );
1476
1477         if( ret )
1478                 return ret;
1479
1480         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1481                                       "couldn't create a PyInt" );
1482 }
1483
1484 static PyObject *Method_PupIntInput( PyObject * self, PyObject * args )
1485 {
1486         char *text = NULL;
1487         int min = 0, max = 1;
1488         short var = 0;
1489         PyObject *ret = NULL;
1490
1491         if( !PyArg_ParseTuple( args, "s|hii", &text, &var, &min, &max ) )
1492                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1493                                               "expected 1 string and 3 int arguments" );
1494
1495         if( button( &var, (short)min, (short)max, text ) == 0 ) {
1496                 Py_INCREF( Py_None );
1497                 return Py_None;
1498         }
1499         ret = PyInt_FromLong( var );
1500         if( ret )
1501                 return ret;
1502
1503         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1504                                       "couldn't create a PyInt" );
1505 }
1506
1507 static PyObject *Method_PupFloatInput( PyObject * self, PyObject * args )
1508 {
1509         char *text = NULL;
1510         float min = 0, max = 1, var = 0, a1 = 10, a2 = 2;
1511         PyObject *ret = NULL;
1512
1513         if( !PyArg_ParseTuple
1514             ( args, "s|fffff", &text, &var, &min, &max, &a1, &a2 ) )
1515                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1516                                               "expected 1 string and 5 float arguments" );
1517
1518         if( fbutton( &var, min, max, a1, a2, text ) == 0 ) {
1519                 Py_INCREF( Py_None );
1520                 return Py_None;
1521         }
1522         ret = PyFloat_FromDouble( var );
1523         if( ret )
1524                 return ret;
1525
1526         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1527                                       "couldn't create a PyFloat" );
1528 }
1529
1530 static PyObject *Method_PupStrInput( PyObject * self, PyObject * args )
1531 {
1532         char *text = NULL, *textMsg = NULL;
1533         char tmp[101];
1534         char max = 20;
1535         PyObject *ret = NULL;
1536
1537         if( !PyArg_ParseTuple( args, "ss|b", &textMsg, &text, &max ) )
1538                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1539                                               "expected 2 strings and 1 int" );
1540
1541         if( ( max <= 0 ) || ( max > 100 ) )
1542                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1543                                               "max string length value must be in the range [1, 100]." );
1544
1545         /* copying the text string handles both cases:
1546          * max < strlen(text) (by truncating) and
1547          * max > strlen(text) (by expanding to strlen(tmp)) */
1548         BLI_strncpy( tmp, text, max + 1 );
1549
1550         if( sbutton( tmp, 0, max, textMsg ) == 0 ) {
1551                 Py_INCREF( Py_None );
1552                 return Py_None;
1553         }
1554
1555         ret = PyString_FromString( tmp );
1556
1557         if( ret )
1558                 return ret;
1559
1560         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1561                                       "couldn't create a PyString" );
1562 }
1563
1564 static PyObject *Method_PupBlock( PyObject * self, PyObject * args )
1565 {
1566         PyObject *pyList, *pyItem;
1567         float min, max;
1568         int len, i;
1569         char *title;
1570
1571         if (!PyArg_ParseTuple( args, "sO", &title, &pyList ) || !PySequence_Check( pyList ))
1572                 return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a string and a sequence" );
1573
1574
1575         len = PySequence_Length(pyList);
1576
1577         if (len == 0)
1578                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string and a non-empty sequence." );
1579
1580         if (len > 120) /* LIMIT DEFINED IN toolbox.c    */
1581                 return EXPP_ReturnPyObjError( PyExc_ValueError, "sequence cannot have more than 120 elements" );
1582
1583         for ( i=0 ; i<len ; i++ ) {
1584                 PyObject *pyMin = NULL, *pyMax = NULL;
1585                 PyObject *f1, *f2;
1586                 Button *but = NULL;
1587                 int tlen;
1588                 char *text, *tip = NULL;
1589
1590                 pyItem = PySequence_GetItem( pyList, i );
1591                 if (!pyItem)
1592                         return NULL;
1593
1594                 if (PyString_Check( pyItem )) {
1595                         tlen = -2;      /* single string for label, giving it a special len for later */
1596                 }
1597                 else if (PyTuple_Check( pyItem )) {
1598                         /* tuple for other button, get the length for later */
1599                         tlen = PyTuple_Size( pyItem );
1600                 }
1601                 else {
1602                         /* Neither a string or a tuple, error */
1603                         Py_DECREF( pyItem );
1604                         return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string or a tuple containing 2 to 5 values." );
1605                 }
1606
1607                 switch (tlen) {
1608                 case -2:                /*      LABEL   */
1609                         text = PyString_AsString( pyItem );
1610                         add_numbut(i, LABEL, text, 0, 0, NULL, NULL);
1611                         break;
1612                 case 2:         /*      TOGGLE  (no tooltip)    */
1613                 case 3:         /*      TOGGLE  */
1614                         if (!PyArg_ParseTuple( pyItem, "sO!|s", &text, &Button_Type, &but, &tip )) {
1615                                 Py_DECREF( pyItem );
1616                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object and optionally a string for toggles" );
1617                         }
1618
1619                         if (but->type != BINT_TYPE) {
1620                                 Py_DECREF( pyItem );
1621                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "Button object for toggles should hold an integer" );
1622                         }
1623
1624                         add_numbut(i, TOG|INT, text, 0, 0, &but->val.asint, tip);
1625                         break;
1626                 case 4:         /*      TEX and NUM (no tooltip)        */
1627                 case 5:         /*      TEX and NUM     */
1628                         if (!PyArg_ParseTuple( pyItem, "sO!OO|s", &text, &Button_Type, &but, &pyMin, &pyMax, &tip )) {
1629                                 Py_DECREF( pyItem );
1630                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object, two numerical values and optionally a string for Text and Num buttons" );
1631                         }
1632
1633                         f1 = PyNumber_Float(pyMin);
1634                         f2 = PyNumber_Float(pyMax);
1635
1636                         if (!f1 || !f2) {
1637                                 Py_DECREF( pyItem );
1638                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object, two numerical values and optionally a string for Text and Num buttons" );
1639                         }
1640
1641                         min = (float)PyFloat_AS_DOUBLE(f1);
1642                         max = (float)PyFloat_AS_DOUBLE(f2);
1643                         Py_DECREF( f1 );
1644                         Py_DECREF( f2 );
1645
1646                         switch ( but->type ) {
1647                         case BINT_TYPE:
1648                                 add_numbut(i, NUM|INT, text, min, max, &but->val.asint, tip);
1649                                 break;
1650                         case BFLOAT_TYPE:
1651                                 add_numbut(i, NUM|FLO, text, min, max, &but->val.asfloat, tip);
1652                                 break;
1653                         case BSTRING_TYPE:
1654                                 if (max+1>UI_MAX_DRAW_STR) {
1655                                         Py_DECREF( pyItem );
1656                                         return EXPP_ReturnPyObjError( PyExc_ValueError, "length of a string buttons must be less then 400" );
1657                                 }
1658                                 max = (float)floor(max);
1659
1660                                 if (max > but->slen) {
1661                                         int old_len = but->slen;
1662                                         char *old_str = but->val.asstr;
1663                                         but->slen = (int)max;
1664                                         but->val.asstr = MEM_callocN( but->slen + 1, "button pupblock");
1665                                         BLI_strncpy( but->val.asstr, old_str, old_len + 1 );
1666                                         MEM_freeN(old_str);
1667                                 }
1668
1669                                 add_numbut(i, TEX, text, 0.0f, max, but->val.asstr, tip);
1670                         }
1671
1672                         break;
1673                 default:
1674                         Py_DECREF( pyItem );
1675                         return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string or a tuple containing 2 to 5 values." );
1676                 }
1677                 Py_DECREF( pyItem );
1678         }
1679
1680         if (do_clever_numbuts(title, len, REDRAW))
1681                 return EXPP_incr_ret_True();
1682         else
1683                 return EXPP_incr_ret_False();
1684 }
1685
1686
1687 /*****************************************************************************
1688  * Function:            Method_Image                                         *
1689  * Python equivalent:   Blender.Draw.Image                                   *
1690  *                                                                           *
1691  * @author Jonathan Merritt <j.merritt@pgrad.unimelb.edu.au>                 *
1692  ****************************************************************************/
1693 static PyObject *Method_Image( PyObject * self, PyObject * args )
1694 {
1695         PyObject *pyObjImage;
1696         BPy_Image *py_img;
1697         Image *image;
1698         ImBuf *ibuf;
1699         float originX, originY;
1700         float zoomX = 1.0, zoomY = 1.0;
1701         int clipX = 0, clipY = 0, clipW = -1, clipH = -1;
1702         /*GLfloat scissorBox[4];*/
1703
1704         /* parse the arguments passed-in from Python */
1705         if( !PyArg_ParseTuple( args, "Off|ffiiii", &pyObjImage, 
1706                 &originX, &originY, &zoomX, &zoomY, 
1707                 &clipX, &clipY, &clipW, &clipH ) )
1708                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1709                         "expected a Blender.Image and 2 floats, and " \
1710                         "optionally 2 floats and 4 ints as arguments" );
1711         /* check that the first PyObject is actually a Blender.Image */
1712         if( !BPy_Image_Check( pyObjImage ) )
1713                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1714                         "expected a Blender.Image and 2 floats, and " \
1715                         "optionally 2 floats and 4 ints as arguments" );
1716         /* check that the zoom factors are valid */
1717         if( ( zoomX <= 0.0 ) || ( zoomY <= 0.0 ) )
1718                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1719                         "invalid zoom factors - they must be >= 0.0" );
1720
1721         /* fetch a C Image pointer from the passed-in Python object */
1722         py_img = ( BPy_Image * ) pyObjImage;
1723         image = py_img->image;
1724         ibuf = BKE_image_get_ibuf( image, NULL );
1725                 
1726         if( !ibuf )      /* if failed to load the image */
1727                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1728                                                                           "couldn't load image data in Blender" );
1729         if( !ibuf->rect )      /* no float yet */
1730                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1731                                                                           "Image has no byte rect" );
1732         
1733         /* Update the time tag of the image */
1734         tag_image_time(image);
1735
1736         /* set up a valid clipping rectangle.  if no clip rectangle was
1737          * given, this results in inclusion of the entire image.  otherwise,
1738          * the clipping is just checked against the bounds of the image.
1739          * if clipW or clipH are less than zero then they include as much of
1740          * the image as they can. */
1741         clipX = EXPP_ClampInt( clipX, 0, ibuf->x );
1742         clipY = EXPP_ClampInt( clipY, 0, ibuf->y );
1743         if( ( clipW < 0 ) || ( clipW > ( ibuf->x - clipW ) ) )
1744                 clipW = ibuf->x - clipX;
1745         if( ( clipH < 0 ) || ( clipH > ( ibuf->y - clipH ) ) )
1746                 clipH = ibuf->y - clipY;
1747
1748         /* -- we are "Go" to Draw! -- */
1749
1750         /* set the raster position.
1751          *
1752          * If the raster position is negative, then using glRasterPos2i() 
1753          * directly would cause it to be clipped.  Instead, we first establish 
1754          * a valid raster position within the clipping rectangle of the 
1755          * window and then use glBitmap() with a NULL image pointer to offset 
1756          * it to the true position we require.  To pick an initial valid 
1757          * raster position within the viewport, we query the clipping rectangle
1758          * and use its lower-left pixel.
1759          *
1760          * This particular technique is documented in the glRasterPos() man
1761          * page, although I haven't seen it used elsewhere in Blender.
1762          */
1763
1764         /* update (W): to fix a bug where images wouldn't get drawn if the bottom
1765          * left corner of the Scripts win were above a given height or to the right
1766          * of a given width, the code below is being commented out.  It should not
1767          * be needed anyway, because spaces in Blender are projected to lie inside
1768          * their areas, see src/drawscript.c for example.  Note: the
1769          * glaRasterPosSafe2i function in src/glutil.c does use the commented out
1770          * technique, but with 0,0 instead of scissorBox.  This function can be
1771          * a little optimized, based on glaDrawPixelsSafe in that same fine, but
1772          * we're too close to release 2.37 right now. */
1773         /*
1774         glGetFloatv( GL_SCISSOR_BOX, scissorBox );
1775         glRasterPos2i( scissorBox[0], scissorBox[1] );
1776         glBitmap( 0, 0, 0.0, 0.0, 
1777                 originX-scissorBox[0], originY-scissorBox[1], NULL );
1778         */
1779
1780         /* update (cont.): using these two lines instead:
1781          * (based on glaRasterPosSafe2i, but Ken Hughes deserves credit
1782          * for suggesting this exact fix in the bug tracker) */
1783         glRasterPos2i(0, 0);
1784         glBitmap( 0, 0, 0.0, 0.0, originX, originY, NULL );
1785
1786         /* set the zoom */
1787         glPixelZoom( zoomX, zoomY );
1788
1789         /* set the width of the image (ROW_LENGTH), and the offset to the
1790          * clip origin within the image in x (SKIP_PIXELS) and 
1791          * y (SKIP_ROWS) */
1792         glPixelStorei( GL_UNPACK_ROW_LENGTH,  ibuf->x );
1793         glPixelStorei( GL_UNPACK_SKIP_PIXELS, clipX );
1794         glPixelStorei( GL_UNPACK_SKIP_ROWS,   clipY );
1795
1796         /* draw the image */
1797         glDrawPixels( clipW, clipH, GL_RGBA, GL_UNSIGNED_BYTE, 
1798                 ibuf->rect );
1799
1800         /* restore the defaults for some parameters (we could also use a
1801          * glPushClientAttrib() and glPopClientAttrib() pair). */
1802         glPixelZoom( 1.0, 1.0 );
1803         glPixelStorei( GL_UNPACK_SKIP_ROWS,   0 );
1804         glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
1805         glPixelStorei( GL_UNPACK_ROW_LENGTH,  0 );
1806
1807         Py_INCREF( Py_None );
1808         return Py_None;
1809
1810 }
1811
1812 PyObject *Draw_Init( void )
1813 {
1814         PyObject *submodule, *dict;
1815
1816         if( PyType_Ready( &Button_Type) < 0)
1817                 Py_RETURN_NONE;
1818
1819         submodule = Py_InitModule3( "Blender.Draw", Draw_methods, Draw_doc );
1820
1821         dict = PyModule_GetDict( submodule );
1822
1823 #define EXPP_ADDCONST(x) \
1824         EXPP_dict_set_item_str(dict, #x, PyInt_FromLong(x))
1825
1826         /* So, for example:
1827          * EXPP_ADDCONST(LEFTMOUSE) becomes
1828          * EXPP_dict_set_item_str(dict, "LEFTMOUSE", PyInt_FromLong(LEFTMOUSE)) 
1829          */
1830
1831         EXPP_ADDCONST( LEFTMOUSE );
1832         EXPP_ADDCONST( MIDDLEMOUSE );
1833         EXPP_ADDCONST( RIGHTMOUSE );
1834         EXPP_ADDCONST( WHEELUPMOUSE );
1835         EXPP_ADDCONST( WHEELDOWNMOUSE );
1836         EXPP_ADDCONST( MOUSEX );
1837         EXPP_ADDCONST( MOUSEY );
1838         EXPP_ADDCONST( TIMER0 );
1839         EXPP_ADDCONST( TIMER1 );
1840         EXPP_ADDCONST( TIMER2 );
1841         EXPP_ADDCONST( TIMER3 );
1842         EXPP_ADDCONST( KEYBD );
1843         EXPP_ADDCONST( RAWKEYBD );
1844         EXPP_ADDCONST( REDRAW );
1845         EXPP_ADDCONST( INPUTCHANGE );
1846         EXPP_ADDCONST( QFULL );
1847         EXPP_ADDCONST( WINFREEZE );
1848         EXPP_ADDCONST( WINTHAW );
1849         EXPP_ADDCONST( WINCLOSE );
1850         EXPP_ADDCONST( WINQUIT );
1851 #ifndef IRISGL
1852         EXPP_ADDCONST( Q_FIRSTTIME );
1853 #endif
1854         EXPP_ADDCONST( AKEY );
1855         EXPP_ADDCONST( BKEY );
1856         EXPP_ADDCONST( CKEY );
1857         EXPP_ADDCONST( DKEY );
1858         EXPP_ADDCONST( EKEY );
1859         EXPP_ADDCONST( FKEY );
1860         EXPP_ADDCONST( GKEY );
1861         EXPP_ADDCONST( HKEY );
1862         EXPP_ADDCONST( IKEY );
1863         EXPP_ADDCONST( JKEY );
1864         EXPP_ADDCONST( KKEY );
1865         EXPP_ADDCONST( LKEY );
1866         EXPP_ADDCONST( MKEY );
1867         EXPP_ADDCONST( NKEY );
1868         EXPP_ADDCONST( OKEY );
1869         EXPP_ADDCONST( PKEY );
1870         EXPP_ADDCONST( QKEY );
1871         EXPP_ADDCONST( RKEY );
1872         EXPP_ADDCONST( SKEY );
1873         EXPP_ADDCONST( TKEY );
1874         EXPP_ADDCONST( UKEY );
1875         EXPP_ADDCONST( VKEY );
1876         EXPP_ADDCONST( WKEY );
1877         EXPP_ADDCONST( XKEY );
1878         EXPP_ADDCONST( YKEY );
1879         EXPP_ADDCONST( ZKEY );
1880         EXPP_ADDCONST( ZEROKEY );
1881         EXPP_ADDCONST( ONEKEY );
1882         EXPP_ADDCONST( TWOKEY );
1883         EXPP_ADDCONST( THREEKEY );
1884         EXPP_ADDCONST( FOURKEY );
1885         EXPP_ADDCONST( FIVEKEY );
1886         EXPP_ADDCONST( SIXKEY );
1887         EXPP_ADDCONST( SEVENKEY );
1888         EXPP_ADDCONST( EIGHTKEY );
1889         EXPP_ADDCONST( NINEKEY );
1890         EXPP_ADDCONST( CAPSLOCKKEY );
1891         EXPP_ADDCONST( LEFTCTRLKEY );
1892         EXPP_ADDCONST( LEFTALTKEY );
1893         EXPP_ADDCONST( RIGHTALTKEY );
1894         EXPP_ADDCONST( RIGHTCTRLKEY );
1895         EXPP_ADDCONST( RIGHTSHIFTKEY );
1896         EXPP_ADDCONST( LEFTSHIFTKEY );
1897         EXPP_ADDCONST( ESCKEY );
1898         EXPP_ADDCONST( TABKEY );
1899         EXPP_ADDCONST( RETKEY );
1900         EXPP_ADDCONST( SPACEKEY );
1901         EXPP_ADDCONST( LINEFEEDKEY );
1902         EXPP_ADDCONST( BACKSPACEKEY );
1903         EXPP_ADDCONST( DELKEY );
1904         EXPP_ADDCONST( SEMICOLONKEY );
1905         EXPP_ADDCONST( PERIODKEY );
1906         EXPP_ADDCONST( COMMAKEY );
1907         EXPP_ADDCONST( QUOTEKEY );
1908         EXPP_ADDCONST( ACCENTGRAVEKEY );
1909         EXPP_ADDCONST( MINUSKEY );
1910         EXPP_ADDCONST( SLASHKEY );
1911         EXPP_ADDCONST( BACKSLASHKEY );
1912         EXPP_ADDCONST( EQUALKEY );
1913         EXPP_ADDCONST( LEFTBRACKETKEY );
1914         EXPP_ADDCONST( RIGHTBRACKETKEY );
1915         EXPP_ADDCONST( LEFTARROWKEY );
1916         EXPP_ADDCONST( DOWNARROWKEY );
1917         EXPP_ADDCONST( RIGHTARROWKEY );
1918         EXPP_ADDCONST( UPARROWKEY );
1919         EXPP_ADDCONST( PAD2 );
1920         EXPP_ADDCONST( PAD4 );
1921         EXPP_ADDCONST( PAD6 );
1922         EXPP_ADDCONST( PAD8 );
1923         EXPP_ADDCONST( PAD1 );
1924         EXPP_ADDCONST( PAD3 );
1925         EXPP_ADDCONST( PAD5 );
1926         EXPP_ADDCONST( PAD7 );
1927         EXPP_ADDCONST( PAD9 );
1928         EXPP_ADDCONST( PADPERIOD );
1929         EXPP_ADDCONST( PADSLASHKEY );
1930         EXPP_ADDCONST( PADASTERKEY );
1931         EXPP_ADDCONST( PAD0 );
1932         EXPP_ADDCONST( PADMINUS );
1933         EXPP_ADDCONST( PADENTER );
1934         EXPP_ADDCONST( PADPLUSKEY );
1935         EXPP_ADDCONST( F1KEY );
1936         EXPP_ADDCONST( F2KEY );
1937         EXPP_ADDCONST( F3KEY );
1938         EXPP_ADDCONST( F4KEY );
1939         EXPP_ADDCONST( F5KEY );
1940         EXPP_ADDCONST( F6KEY );
1941         EXPP_ADDCONST( F7KEY );
1942         EXPP_ADDCONST( F8KEY );
1943         EXPP_ADDCONST( F9KEY );
1944         EXPP_ADDCONST( F10KEY );
1945         EXPP_ADDCONST( F11KEY );
1946         EXPP_ADDCONST( F12KEY );
1947         EXPP_ADDCONST( PAUSEKEY );
1948         EXPP_ADDCONST( INSERTKEY );
1949         EXPP_ADDCONST( HOMEKEY );
1950         EXPP_ADDCONST( PAGEUPKEY );
1951         EXPP_ADDCONST( PAGEDOWNKEY );
1952         EXPP_ADDCONST( ENDKEY );
1953
1954         return submodule;
1955 }