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