added an option for python Draw.UIBlock(func, mouse_exit) so moving the mouse outside...
[blender.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, mouse_exit) - 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, w, h, tip, callback) - Draw a text label onscreen\n\n\
294 (text) The text to draw\n\
295 (x, y, w, h) The lower left coordinate of the lable, width and height";
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         int mouse_exit = 1;
1105
1106         if (G.background) {
1107                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1108                                               "Can't run Draw.UIBlock() in background mode." );
1109         }
1110         
1111         if ( !PyArg_ParseTuple( args, "O|i", &val, &mouse_exit ) || !PyCallable_Check( val ) ) 
1112                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1113                                               "expected 1 python function and an optional int" );
1114
1115         if (uiblock)
1116                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1117               "cannot run more then 1 UIBlock at a time" );
1118
1119         BPy_Set_DrawButtonsList(PyList_New(0));
1120         
1121         mywinset(G.curscreen->mainwin);
1122         uiblock= uiNewBlock(&listb, "numbuts", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
1123         
1124         uiBlockSetFlag(uiblock, UI_BLOCK_LOOP|UI_BLOCK_REDRAW);
1125         result = PyObject_CallObject( val, NULL );
1126         
1127         if (!result) {
1128                 PyErr_Print(  );
1129                 error_pyscript(  );
1130         } else {
1131                 /* copied from do_clever_numbuts in toolbox.c */
1132                 
1133                 /* Clear all events so tooltips work, this is not ideal and
1134                 only needed because calls from the menu still have some events
1135                 left over when do_clever_numbuts is called.
1136                 Calls from keyshortcuts do not have this problem.*/
1137                 ScrArea *sa;
1138                 BWinEvent temp_bevt;
1139                 for (sa= G.curscreen->areabase.first; sa; sa= sa->next) {
1140                         if(sa->win) {
1141                                 while( bwin_qread( sa->win, &temp_bevt ) ) {}
1142                         }
1143                         if(sa->headwin) {
1144                                 while( bwin_qread( sa->headwin, &temp_bevt ) ) {}
1145                         }
1146                 }
1147                 /* Done clearing events */
1148                 
1149                 uiBoundsBlock(uiblock, 5);
1150                 uiDoBlocks(&listb, 0, mouse_exit);
1151         }
1152         uiFreeBlocks(&listb);
1153         uiblock = NULL;
1154         BPy_Free_DrawButtonsList(); /*clear all temp button references*/
1155         
1156         Py_XDECREF( result );
1157         Py_RETURN_NONE;
1158 }
1159
1160 #if 0 /* not used yet */
1161 static void Set_uiBlock(uiBlock *block)
1162 {
1163         uiblock = block;
1164 }
1165 #endif
1166
1167 static uiBlock *Get_uiBlock( void )
1168 {
1169         char butblock[32];
1170         /* Global, used now for UIBlock */
1171         if (uiblock) {
1172                 return uiblock;
1173         }
1174         /* Local */
1175         sprintf( butblock, "win %d", curarea->win );
1176
1177         return uiGetBlock( butblock, curarea );
1178 }
1179
1180
1181 /* We restrict the acceptable event numbers to a proper "free" range
1182  * according to other spaces in Blender.
1183  * winqread***space() (space events callbacks) use short for events
1184  * (called 'val' there) and we also translate by EXPP_BUTTON_EVENTS_OFFSET
1185  * to get rid of unwanted events (check BPY_do_pywin_events above for
1186  * explanation). This function takes care of that and proper checking: */
1187 static int check_button_event(int *event) {
1188         if ((*event < EXPP_BUTTON_EVENTS_MIN) ||
1189                         (*event > EXPP_BUTTON_EVENTS_MAX)) {
1190                 return -1;
1191         }
1192         if (uiblock==NULL) /* For UIBlock we need non offset UI elements */
1193                 *event += EXPP_BUTTON_EVENTS_OFFSET;
1194         return 0;
1195 }
1196
1197 static PyObject *Method_BeginAlign( PyObject * self, PyObject * args )
1198 {
1199         uiBlock *block = Get_uiBlock(  );
1200         
1201         if (block)
1202                 uiBlockBeginAlign(block);
1203         
1204         Py_RETURN_NONE;
1205 }
1206
1207 static PyObject *Method_EndAlign( PyObject * self, PyObject * args )
1208 {
1209         uiBlock *block = Get_uiBlock(  );
1210         
1211         if (block)
1212                 uiBlockEndAlign(block);
1213         
1214         Py_RETURN_NONE;
1215 }
1216
1217 static PyObject *Method_Button( PyObject * self, PyObject * args )
1218 {
1219         uiBlock *block;
1220         char *name, *tip = NULL;
1221         int event;
1222         int x, y, w, h;
1223         PyObject *callback=NULL;
1224
1225         if (G.background) {
1226                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1227                                               "Can't run Draw.Button() in background mode." );
1228         }
1229         
1230         if( !PyArg_ParseTuple( args, "siiiii|sO", &name, &event,
1231                                &x, &y, &w, &h, &tip, &callback ) )
1232                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1233                                               "expected a string, five ints and optionally string and callback arguments" );
1234
1235         UI_METHOD_ERRORCHECK;
1236
1237         block = Get_uiBlock(  );
1238         if( block ) {
1239                 uiBut *ubut = uiDefBut( block, BUT, event, name, (short)x, (short)y, (short)w, (short)h, 0, 0, 0, 0, 0, tip );
1240                 set_pycallback(ubut, callback, NULL);
1241         }
1242         Py_RETURN_NONE;
1243 }
1244
1245 static PyObject *Method_Menu( PyObject * self, PyObject * args )
1246 {
1247         uiBlock *block;
1248         char *name, *tip = NULL;
1249         int event, def;
1250         int x, y, w, h;
1251         Button *but;
1252         PyObject *callback=NULL;
1253
1254         if (G.background) {
1255                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1256                                               "Can't run Draw.Menu() in background mode." );
1257         }
1258         
1259         if( !PyArg_ParseTuple( args, "siiiiii|sO", &name, &event,
1260                                &x, &y, &w, &h, &def, &tip, &callback ) )
1261                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1262                                               "expected a string, six ints and optionally string and callback arguments" );
1263
1264         UI_METHOD_ERRORCHECK;
1265         
1266         but = newbutton(  );
1267         but->type = BINT_TYPE;
1268         but->val.asint = def;
1269         if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
1270         
1271         block = Get_uiBlock(  );
1272         if( block ) {
1273                 uiBut *ubut = uiDefButI( block, MENU, event, name, (short)x, (short)y, (short)w, (short)h,
1274                            &but->val.asint, 0, 0, 0, 0, but->tooltip );
1275                 set_pycallback(ubut, callback, but);
1276         }
1277         return ( PyObject * ) but;
1278 }
1279
1280 static PyObject *Method_Toggle( PyObject * self, PyObject * args )
1281 {
1282         uiBlock *block;
1283         char *name, *tip = NULL;
1284         int event;
1285         int x, y, w, h, def;
1286         Button *but;
1287         PyObject *callback=NULL;
1288
1289         if (G.background) {
1290                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1291                                               "Can't run Draw.Toggle() in background mode." );
1292         }
1293         
1294         if( !PyArg_ParseTuple( args, "siiiiii|sO", &name, &event,
1295                                &x, &y, &w, &h, &def, &tip, &callback ) )
1296                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1297                                               "expected a string, six ints and optionally string and callback arguments" );
1298
1299         UI_METHOD_ERRORCHECK;
1300         
1301         but = newbutton(  );
1302         but->type = BINT_TYPE;
1303         but->val.asint = def;
1304         if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
1305         
1306         block = Get_uiBlock(  );
1307         if( block ) {
1308                 uiBut *ubut = uiDefButI( block, TOG, event, name, (short)x, (short)y, (short)w, (short)h,
1309                            &but->val.asint, 0, 0, 0, 0, but->tooltip );
1310                 set_pycallback(ubut, callback, but);
1311         }
1312         return ( PyObject * ) but;
1313 }
1314
1315 /*@DO NOT TOUCH THIS FUNCTION !
1316          Redrawing a slider inside its own callback routine is actually forbidden
1317          with the current toolkit architecture (button routines are not reentrant).
1318          But it works anyway.
1319          XXX This is condemned to be dinosource in future - it's a hack.
1320          */
1321
1322 static void py_slider_update( void *butv, void *data2_unused )
1323 {
1324         uiBut *but = butv;
1325         PyObject *ref = Py_BuildValue( "(i)", SPACE_VIEW3D );
1326         PyObject *ret = NULL;
1327
1328         EXPP_disable_force_draw = 1;
1329         /*@ Disable forced drawing, otherwise the button object which
1330          * is still being used might be deleted */
1331
1332         curarea->win_swap = WIN_BACK_OK;
1333         /* removed global uiFrontBuf (contact ton when this goes wrong here) */
1334
1335         disable_where_script( 1 );
1336
1337         spacescript_do_pywin_buttons( curarea->spacedata.first,
1338                 (unsigned short)uiButGetRetVal( but ) -  EXPP_BUTTON_EVENTS_OFFSET );
1339
1340         /* XXX useless right now, investigate better before a bcon 5 */
1341         ret = M_Window_Redraw( 0, ref );
1342
1343         Py_XDECREF(ref);
1344         Py_XDECREF(ret);
1345
1346         disable_where_script( 0 );
1347
1348         EXPP_disable_force_draw = 0;
1349 }
1350
1351 static PyObject *Method_Slider( PyObject * self, PyObject * args )
1352 {
1353         uiBlock *block;
1354         char *name, *tip = NULL;
1355         int event;
1356         int x, y, w, h, realtime = 1;
1357         Button *but;
1358         PyObject *mino, *maxo, *inio;
1359         PyObject *callback=NULL;
1360
1361         if (G.background) {
1362                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1363                                               "Can't run Draw.Sider() in background mode." );
1364         }
1365         
1366         if( !PyArg_ParseTuple( args, "siiiiiOOO|isO", &name, &event,
1367                                &x, &y, &w, &h, &inio, &mino, &maxo, &realtime,
1368                                &tip, &callback ) )
1369                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1370                                               "expected a string, five ints, three PyObjects\n\
1371                         and optionally int, string and callback arguments" );
1372
1373         if(realtime && uiblock)
1374                 realtime = 0; /* realtime dosnt work with UIBlock */
1375
1376         UI_METHOD_ERRORCHECK;
1377         
1378         but = newbutton(  );
1379
1380         if( PyFloat_Check( inio ) ) {
1381                 float ini, min, max;
1382
1383                 ini = (float)PyFloat_AsDouble( inio );
1384                 min = (float)PyFloat_AsDouble( mino );
1385                 max = (float)PyFloat_AsDouble( maxo );
1386
1387                 but->type = BFLOAT_TYPE;
1388                 but->val.asfloat = ini;
1389                 if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
1390                 
1391                 block = Get_uiBlock(  );
1392                 if( block ) {
1393                         uiBut *ubut;
1394                         ubut = uiDefButF( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
1395                                           (short)h, &but->val.asfloat, min, max, 0, 0,
1396                                           but->tooltip );
1397                         if( realtime )
1398                                 uiButSetFunc( ubut, py_slider_update, ubut, NULL );
1399                         else
1400                                 set_pycallback(ubut, callback, but);
1401                 }
1402         } else {
1403                 int ini, min, max;
1404
1405                 ini = PyInt_AsLong( inio );
1406                 min = PyInt_AsLong( mino );
1407                 max = PyInt_AsLong( maxo );
1408
1409                 but->type = BINT_TYPE;
1410                 but->val.asint = ini;
1411                 if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
1412                 
1413                 block = Get_uiBlock(  );
1414                 if( block ) {
1415                         uiBut *ubut;
1416                         ubut = uiDefButI( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
1417                                           (short)h, &but->val.asint, (float)min, (float)max, 0, 0,
1418                                           but->tooltip );
1419                         if( realtime )
1420                                 uiButSetFunc( ubut, py_slider_update, ubut, NULL );
1421                         else
1422                                 set_pycallback(ubut, callback, but);
1423                 }
1424         }
1425         return ( PyObject * ) but;
1426 }
1427
1428 static PyObject *Method_Scrollbar( PyObject * self, PyObject * args )
1429 {
1430         char *tip = NULL;
1431         uiBlock *block;
1432         int event;
1433         int x, y, w, h, realtime = 1;
1434         Button *but;
1435         PyObject *mino, *maxo, *inio;
1436         float ini, min, max;
1437         uiBut *ubut;
1438         
1439         if (G.background) {
1440                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1441                                               "Can't run Draw.Scrollbar() in background mode." );
1442         }
1443         
1444         if( !PyArg_ParseTuple( args, "iiiiiOOO|isO", &event, &x, &y, &w, &h,
1445                                &inio, &mino, &maxo, &realtime, &tip ) )
1446                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1447                         "expected five ints, three PyObjects and optionally\n\
1448 another int and string as arguments" );
1449
1450         if( !PyNumber_Check( inio ) || !PyNumber_Check( inio )
1451             || !PyNumber_Check( inio ) )
1452                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1453                                               "expected numbers for initial, min, and max" );
1454
1455         if (check_button_event(&event) == -1)
1456         return EXPP_ReturnPyObjError( PyExc_AttributeError,
1457                 "button event argument must be in the range [0, 16382]");
1458
1459         but = newbutton(  );
1460         if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
1461         
1462         if( PyFloat_Check( inio ) )
1463                 but->type = BFLOAT_TYPE;
1464         else
1465                 but->type = BINT_TYPE;
1466
1467         ini = (float)PyFloat_AsDouble( inio );
1468         min = (float)PyFloat_AsDouble( mino );
1469         max = (float)PyFloat_AsDouble( maxo );
1470         
1471         block = Get_uiBlock(  );
1472
1473         if( block ) {
1474                 if( but->type == BFLOAT_TYPE ) {
1475                         but->val.asfloat = ini;
1476                         ubut = uiDefButF( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
1477                                           &but->val.asfloat, min, max, 0, 0, but->tooltip );
1478                         if( realtime )
1479                                 uiButSetFunc( ubut, py_slider_update, ubut, NULL );
1480                 } else {
1481                         but->val.asint = (int)ini;
1482                         ubut = uiDefButI( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
1483                                           &but->val.asint, min, max, 0, 0, but->tooltip );
1484                         if( realtime )
1485                                 uiButSetFunc( ubut, py_slider_update, ubut, NULL );
1486                 }
1487         }
1488         return ( PyObject * ) but;
1489 }
1490
1491 static PyObject *Method_ColorPicker( PyObject * self, PyObject * args )
1492 {
1493         char USAGE_ERROR[] = "expected a 3-float tuple of values between 0 and 1";
1494         Button *but;
1495         PyObject *inio;
1496         uiBlock *block;
1497         char *tip = NULL;
1498         float col[3];
1499         int event;
1500         short x, y, w, h;
1501         PyObject *callback=NULL;
1502         
1503         if (G.background) {
1504                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1505                                               "Can't run Draw.ColorPicker() in background mode." );
1506         }
1507         
1508         if( !PyArg_ParseTuple( args, "ihhhhO!|sO", &event,
1509                                &x, &y, &w, &h, &PyTuple_Type, &inio, &tip, &callback ) )
1510                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1511                                               "expected five ints, one tuple and optionally string and callback arguments" );
1512  
1513         UI_METHOD_ERRORCHECK;
1514  
1515         if ( !PyArg_ParseTuple( inio, "fff", col, col+1, col+2 ) )
1516                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1517
1518         if      (       col[0] < 0 || col[0] > 1
1519                 ||      col[1] < 0 || col[1] > 1
1520                 ||      col[2] < 0 || col[2] > 1 )
1521                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1522
1523         if ( EXPP_check_sequence_consistency( inio, &PyFloat_Type ) != 1 )
1524                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1525  
1526         but = newbutton();
1527  
1528         but->type = BVECTOR_TYPE;
1529         but->val.asvec[0] = col[0];
1530         but->val.asvec[1] = col[1];
1531         but->val.asvec[2] = col[2];
1532         if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
1533         
1534         block = Get_uiBlock(  );
1535         if( block ) {
1536                 uiBut *ubut;
1537                 ubut = uiDefButF( block, COL, event, "", x, y, w, h, but->val.asvec, 0, 0, 0, 0, but->tooltip);
1538                 set_pycallback(ubut, callback, but);
1539         }
1540
1541         return ( PyObject * ) but;
1542 }
1543
1544
1545
1546 static PyObject *Method_Normal( PyObject * self, PyObject * args )
1547 {
1548         char USAGE_ERROR[] = "expected a 3-float tuple of values between -1 and 1";
1549         Button *but;
1550         PyObject *inio;
1551         uiBlock *block;
1552         char *tip = NULL;
1553         float nor[3];
1554         int event;
1555         short x, y, w, h;
1556         PyObject *callback=NULL;
1557         
1558         if (G.background) {
1559                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1560                                               "Can't run Draw.Normal() in background mode." );
1561         }
1562         
1563         if( !PyArg_ParseTuple( args, "ihhhhO!|sO", &event,
1564                                &x, &y, &w, &h, &PyTuple_Type, &inio, &tip, &callback ) )
1565                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1566                                               "expected five ints, one tuple and optionally string and callback arguments" );
1567  
1568         UI_METHOD_ERRORCHECK;
1569  
1570         if ( !PyArg_ParseTuple( inio, "fff", nor, nor+1, nor+2 ) )
1571                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1572
1573         if ( EXPP_check_sequence_consistency( inio, &PyFloat_Type ) != 1 )
1574                 return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
1575  
1576         but = newbutton();
1577         if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
1578         
1579         but->type = BVECTOR_TYPE;
1580         but->val.asvec[0] = nor[0];
1581         but->val.asvec[1] = nor[1];
1582         but->val.asvec[2] = nor[2];
1583         
1584         block = Get_uiBlock(  );
1585         if( block ) {
1586                 uiBut *ubut;
1587                 ubut = uiDefButF( block, BUT_NORMAL, event, "", x, y, w, h, but->val.asvec, 0.0f, 1.0f, 0, 0, but->tooltip);
1588                 set_pycallback(ubut, callback, but);
1589         }
1590         
1591         return ( PyObject * ) but;
1592 }
1593
1594 static PyObject *Method_Number( PyObject * self, PyObject * args )
1595 {
1596         uiBlock *block;
1597         char *name, *tip = NULL;
1598         int event;
1599         int x, y, w, h;
1600         Button *but;
1601         PyObject *mino, *maxo, *inio;
1602         PyObject *callback=NULL;
1603         uiBut *ubut= NULL;
1604         
1605         if (G.background) {
1606                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1607                                               "Can't run Draw.Number() in background mode." );
1608         }
1609         
1610         if( !PyArg_ParseTuple( args, "siiiiiOOO|sO", &name, &event,
1611                                &x, &y, &w, &h, &inio, &mino, &maxo, &tip, &callback ) )
1612                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1613                                               "expected a string, five ints, three PyObjects and\n\
1614                         optionally string and callback arguments" );
1615
1616         UI_METHOD_ERRORCHECK;
1617
1618         if ( !PyNumber_Check(inio) || !PyNumber_Check(mino) ||
1619                         !PyNumber_Check(maxo) ) {
1620                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1621                                 "expected ints or floats for the initial, min and max values" );
1622         }
1623
1624         but = newbutton(  );
1625         if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
1626         block = Get_uiBlock(  );
1627         
1628         if( PyFloat_Check( inio ) ) {
1629                 float ini, min, max, range, precission=0;
1630
1631                 ini = (float)PyFloat_AsDouble( inio );
1632                 min = (float)PyFloat_AsDouble( mino );
1633                 max = (float)PyFloat_AsDouble( maxo );
1634                 
1635                 range= (float)fabs(max-min); /* Click step will be a 10th of the range. */
1636                 if (!range) range= 1.0f; /* avoid any odd errors */
1637                 
1638                 /* set the precission to display*/
1639                 if      (range>=1000.0f) precission=1.0f;
1640                 else if (range>=100.0f) precission=2.0f;
1641                 else if (range>=10.0f) precission=3.0f;
1642                 else precission=4.0f;
1643                         
1644                 but->type = BFLOAT_TYPE;
1645                 but->val.asfloat = ini;
1646
1647                 
1648                 if( block )
1649                         ubut= uiDefButF( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
1650                                    &but->val.asfloat, min, max, 10*range, precission, but->tooltip );
1651         } else {
1652                 int ini, min, max;
1653
1654                 ini = PyInt_AsLong( inio );
1655                 min = PyInt_AsLong( mino );
1656                 max = PyInt_AsLong( maxo );
1657
1658                 but->type = BINT_TYPE;
1659                 but->val.asint = ini;
1660
1661                 if( block )
1662                         ubut= uiDefButI( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
1663                                    &but->val.asint, (float)min, (float)max, 0, 0, but->tooltip );
1664         }
1665         
1666         if (ubut) set_pycallback(ubut, callback, but);
1667         
1668         return ( PyObject * ) but;
1669 }
1670
1671 static PyObject *Method_String( PyObject * self, PyObject * args )
1672 {
1673         uiBlock *block;
1674         char *info_arg = NULL, *tip = NULL, *newstr = NULL;
1675         char *info_str = NULL, *info_str0 = " ";
1676         int event;
1677         int x, y, w, h, len, real_len = 0;
1678         Button *but;
1679         PyObject *callback=NULL;
1680
1681         if (G.background) {
1682                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1683                                               "Can't run Draw.String() in background mode." );
1684         }
1685         
1686         if( !PyArg_ParseTuple( args, "siiiiisi|sO", &info_arg, &event,
1687                         &x, &y, &w, &h, &newstr, &len, &tip, &callback ) )
1688                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1689                         "expected a string, five ints, a string, an int and\n\
1690         optionally string and callback arguments" );
1691
1692         UI_METHOD_ERRORCHECK;
1693
1694         if (len > (UI_MAX_DRAW_STR - 1))
1695                 return EXPP_ReturnPyObjError( PyExc_ValueError,
1696                         "The maximum length of a string is 399, your value is too high.");
1697
1698         real_len = strlen(newstr);
1699         if (real_len > len) real_len = len;
1700         
1701         but = newbutton(  );
1702         but->type = BSTRING_TYPE;
1703         but->slen = len;
1704         but->val.asstr = MEM_mallocN( len + 1, "pybutton str" );
1705         if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
1706
1707         BLI_strncpy( but->val.asstr, newstr, len + 1); /* adds '\0' */
1708         but->val.asstr[real_len] = '\0';
1709
1710         if (info_arg[0] == '\0') info_str = info_str0;
1711         else info_str = info_arg;
1712
1713         block = Get_uiBlock(  );
1714         if( block ) {
1715                 uiBut *ubut = uiDefBut( block, TEX, event, info_str, (short)x, (short)y, (short)w, (short)h,
1716                           but->val.asstr, 0, (float)len, 0, 0, but->tooltip );
1717                 set_pycallback(ubut, callback, but);
1718         }
1719         return ( PyObject * ) but;
1720 }
1721
1722 static PyObject *Method_GetStringWidth( PyObject * self, PyObject * args )
1723 {
1724         char *text;
1725         char *font_str = "normal";
1726         struct BMF_Font *font;
1727         PyObject *width;
1728
1729         if( !PyArg_ParseTuple( args, "s|s", &text, &font_str ) )
1730                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1731                                               "expected one or two string arguments" );
1732
1733         if( !strcmp( font_str, "normal" ) )
1734                 font = ( &G )->font;
1735         else if( !strcmp( font_str, "normalfix" ) )
1736                 font = BMF_GetFont(BMF_kScreen12);
1737         else if( !strcmp( font_str, "large" ) )
1738                 font = BMF_GetFont(BMF_kScreen15);
1739         else if( !strcmp( font_str, "small" ) )
1740                 font = ( &G )->fonts;
1741         else if( !strcmp( font_str, "tiny" ) )
1742                 font = ( &G )->fontss;
1743         else
1744                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1745                                               "\"font\" must be: 'large','normal' (default), 'normalfix', 'small' or 'tiny'." );
1746
1747         width = PyInt_FromLong( BMF_GetStringWidth( font, text ) );
1748
1749         if( !width )
1750                 return EXPP_ReturnPyObjError( PyExc_MemoryError,
1751                                               "couldn't create PyInt" );
1752
1753         return width;
1754 }
1755
1756 static PyObject *Method_Text( PyObject * self, PyObject * args )
1757 {
1758         char *text;
1759         char *font_str = NULL;
1760         struct BMF_Font *font;
1761
1762         if (G.background) {
1763                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1764                                               "Can't run Draw.Text() in background mode." );
1765         }
1766         
1767         if( !PyArg_ParseTuple( args, "s|s", &text, &font_str ) )
1768                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1769                                               "expected one or two string arguments" );
1770
1771         if( !font_str )
1772                 font = ( &G )->font;
1773         else if( !strcmp( font_str, "large" ) )
1774                 font = BMF_GetFont(BMF_kScreen15);
1775         else if( !strcmp( font_str, "normalfix" ) )
1776                 font = BMF_GetFont(BMF_kScreen12);
1777         else if( !strcmp( font_str, "normal" ) )
1778                 font = ( &G )->font;
1779         else if( !strcmp( font_str, "small" ) )
1780                 font = ( &G )->fonts;
1781         else if( !strcmp( font_str, "tiny" ) )
1782                 font = ( &G )->fontss;
1783         else
1784                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
1785                                               "\"font\" must be: 'large','normal' (default), 'normalfix', 'small' or 'tiny'." );
1786
1787         BMF_DrawString( font, text );
1788
1789         return PyInt_FromLong( BMF_GetStringWidth( font, text ) );
1790 }
1791
1792 static PyObject *Method_Label( PyObject * self, PyObject * args )
1793 {
1794         uiBlock *block;
1795         char *text;
1796         int x, y, w, h;
1797
1798         if (G.background) {
1799                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1800                                               "Can't run Draw.Label() in background mode." );
1801         }
1802         
1803         if( !PyArg_ParseTuple( args, "siiii", &text, &x, &y, &w, &h ) )
1804                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1805                         "expected a string and four ints" );
1806
1807         block = Get_uiBlock(  );
1808         uiDefBut(block, LABEL, 0, text, x, y, w, h, 0, 0, 0, 0, 0, "");
1809         
1810         Py_RETURN_NONE;
1811 }
1812
1813
1814 static PyObject *Method_PupMenu( PyObject * self, PyObject * args )
1815 {
1816         char *text;
1817         int maxrow = -1;
1818         PyObject *ret;
1819         
1820         if (G.background) {
1821                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1822                                               "Can't run Draw.PupMenu() in background mode." );
1823         }
1824         
1825         if( !PyArg_ParseTuple( args, "s|i", &text, &maxrow ) )
1826                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1827                                               "expected a string and optionally an int as arguments" );
1828
1829         if( maxrow >= 0 )
1830                 ret = PyInt_FromLong( pupmenu_col( text, maxrow ) );
1831         else
1832                 ret = PyInt_FromLong( pupmenu( text ) );
1833
1834         if( ret )
1835                 return ret;
1836
1837         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1838                                       "couldn't create a PyInt" );
1839 }
1840
1841 static int current_menu_ret;
1842 static void toolbox_event(void *arg, int event)
1843 {
1844         current_menu_ret = event;
1845 }
1846
1847 static TBitem * menu_from_pylist( PyObject * current_menu, ListBase *storage )
1848 {
1849         TBitem *tbarray, *tbitem;
1850         Link *link;
1851         PyObject *item, *submenu;
1852         int size, i;
1853         
1854         char *menutext;
1855         int event;
1856         
1857         size = PyList_Size( current_menu );
1858         
1859         link= MEM_callocN(sizeof(Link) + sizeof(TBitem)*(size+1), "python menu");
1860         
1861         if (link==NULL) {
1862                 PyErr_SetString( PyExc_MemoryError, "Could not allocate enough memory for the menu" );
1863                 BLI_freelistN(storage);
1864                 return NULL;
1865         }
1866         
1867         BLI_addtail(storage, link);
1868         
1869         tbarray = tbitem = (TBitem *)(link+1);
1870         
1871         for (i=0; i<size; i++, tbitem++) {
1872                 /* need to get these in */
1873                 item = PyList_GET_ITEM( current_menu, i);
1874                 
1875                 if (item == Py_None) {
1876                         tbitem->name = "SEPR";
1877                 } else if( PyArg_ParseTuple( item, "si", &menutext, &event ) ) {
1878                         tbitem->name = menutext;
1879                         tbitem->retval = event;
1880                         //current_menu_index
1881                 } else if( PyArg_ParseTuple( item, "sO!", &menutext, &PyList_Type, &submenu ) ) {
1882                         PyErr_Clear(); /* from PyArg_ParseTuple above */
1883                         tbitem->name = menutext;
1884                         tbitem->poin = menu_from_pylist(submenu, storage);
1885                         if (tbitem->poin == NULL) {
1886                                 BLI_freelistN(storage);
1887                                 return NULL; /* error should be set */
1888                         }
1889                 } else {
1890                         PyErr_Clear(); /* from PyArg_ParseTuple above */
1891                         
1892                         PyErr_SetString( PyExc_TypeError, "Expected a list of name,event tuples, None, or lists for submenus" );
1893                         BLI_freelistN(storage);
1894                         return NULL;
1895                 }
1896         }
1897         tbitem->icon= -1;       /* end signal */
1898         tbitem->name= "";
1899         tbitem->retval= 0;
1900         tbitem->poin= toolbox_event;
1901         
1902         return tbarray;
1903 }
1904
1905 static PyObject *Method_PupTreeMenu( PyObject * self, PyObject * args )
1906 {
1907         PyObject * current_menu;
1908         ListBase storage = {NULL, NULL};
1909         TBitem *tb;
1910         
1911         if (G.background) {
1912                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1913                                               "Can't run Draw.PupMenuTree() in background mode." );
1914         }
1915         
1916         if( !PyArg_ParseTuple( args, "O!", &PyList_Type, &current_menu ) )
1917                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1918                         "Expected a list" );
1919         
1920         mywinset(G.curscreen->mainwin); // we go to screenspace
1921         
1922         tb = menu_from_pylist(current_menu, &storage);
1923         
1924         if (!tb) { 
1925                 /* Error is set */
1926                 return NULL; 
1927         }
1928         
1929         current_menu_ret = -1;
1930         toolbox_generic(tb);
1931         
1932         /* free all dynamic entries... */
1933         BLI_freelistN(&storage);
1934         
1935         mywinset(curarea->win);
1936         return PyInt_FromLong( current_menu_ret ); /* current_menu_ret is set by toolbox_event callback */
1937 }
1938
1939 static PyObject *Method_PupIntInput( PyObject * self, PyObject * args )
1940 {
1941         char *text = NULL;
1942         int min = 0, max = 1;
1943         short var = 0;
1944         PyObject *ret = NULL;
1945
1946         if (G.background) {
1947                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1948                                               "Can't run Draw.PupIntInput() in background mode." );
1949         }
1950         
1951         if( !PyArg_ParseTuple( args, "s|hii", &text, &var, &min, &max ) )
1952                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1953                                               "expected 1 string and 3 int arguments" );
1954
1955         if( button( &var, (short)min, (short)max, text ) == 0 ) {
1956                 Py_INCREF( Py_None );
1957                 return Py_None;
1958         }
1959         ret = PyInt_FromLong( var );
1960         if( ret )
1961                 return ret;
1962
1963         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1964                                       "couldn't create a PyInt" );
1965 }
1966
1967 static PyObject *Method_PupFloatInput( PyObject * self, PyObject * args )
1968 {
1969         char *text = NULL;
1970         float min = 0, max = 1, var = 0, a1 = 10, a2 = 2;
1971         PyObject *ret = NULL;
1972
1973         if (G.background) {
1974                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
1975                                               "Can't run Draw.PupFloatInput() in background mode." );
1976         }
1977         
1978         if( !PyArg_ParseTuple
1979             ( args, "s|fffff", &text, &var, &min, &max, &a1, &a2 ) )
1980                 return EXPP_ReturnPyObjError( PyExc_TypeError,
1981                                               "expected 1 string and 5 float arguments" );
1982
1983         if( fbutton( &var, min, max, a1, a2, text ) == 0 ) {
1984                 Py_INCREF( Py_None );
1985                 return Py_None;
1986         }
1987         ret = PyFloat_FromDouble( var );
1988         if( ret )
1989                 return ret;
1990
1991         return EXPP_ReturnPyObjError( PyExc_MemoryError,
1992                                       "couldn't create a PyFloat" );
1993 }
1994
1995 static PyObject *Method_PupStrInput( PyObject * self, PyObject * args )
1996 {
1997         char *text = NULL, *textMsg = NULL;
1998         char tmp[101];
1999         char max = 20;
2000         PyObject *ret = NULL;
2001
2002         if (G.background) {
2003                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2004                                               "Can't run Draw.PupStrInput() in background mode." );
2005         }
2006         
2007         if( !PyArg_ParseTuple( args, "ss|b", &textMsg, &text, &max ) )
2008                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2009                                               "expected 2 strings and 1 int" );
2010
2011         if( ( max <= 0 ) || ( max > 100 ) )
2012                 return EXPP_ReturnPyObjError( PyExc_AttributeError,
2013                                               "max string length value must be in the range [1, 100]." );
2014
2015         /* copying the text string handles both cases:
2016          * max < strlen(text) (by truncating) and
2017          * max > strlen(text) (by expanding to strlen(tmp)) */
2018         BLI_strncpy( tmp, text, max + 1 );
2019
2020         if( sbutton( tmp, 0, max, textMsg ) == 0 ) {
2021                 Py_INCREF( Py_None );
2022                 return Py_None;
2023         }
2024
2025         ret = PyString_FromString( tmp );
2026
2027         if( ret )
2028                 return ret;
2029
2030         return EXPP_ReturnPyObjError( PyExc_MemoryError,
2031                                       "couldn't create a PyString" );
2032 }
2033
2034 static PyObject *Method_PupBlock( PyObject * self, PyObject * args )
2035 {
2036         PyObject *pyList, *pyItem;
2037         float min, max;
2038         int len, i;
2039         char *title;
2040
2041         if (G.background) {
2042                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2043                                               "Can't run Draw.PupBlock() in background mode." );
2044         }
2045         
2046         if (!PyArg_ParseTuple( args, "sO", &title, &pyList ) || !PySequence_Check( pyList ))
2047                 return EXPP_ReturnPyObjError( PyExc_TypeError, "expected a string and a sequence" );
2048
2049
2050         len = PySequence_Length(pyList);
2051
2052         if (len == 0)
2053                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string and a non-empty sequence." );
2054
2055         if (len > 120) /* LIMIT DEFINED IN toolbox.c    */
2056                 return EXPP_ReturnPyObjError( PyExc_ValueError, "sequence cannot have more than 120 elements" );
2057
2058         for ( i=0 ; i<len ; i++ ) {
2059                 PyObject *pyMin = NULL, *pyMax = NULL;
2060                 PyObject *f1, *f2;
2061                 Button *but = NULL;
2062                 int tlen;
2063                 char *text, *tip = NULL;
2064
2065                 pyItem = PySequence_GetItem( pyList, i );
2066                 if (!pyItem)
2067                         return NULL;
2068
2069                 if (PyString_Check( pyItem )) {
2070                         tlen = -2;      /* single string for label, giving it a special len for later */
2071                 }
2072                 else if (PyTuple_Check( pyItem )) {
2073                         /* tuple for other button, get the length for later */
2074                         tlen = PyTuple_Size( pyItem );
2075                 }
2076                 else {
2077                         /* Neither a string or a tuple, error */
2078                         Py_DECREF( pyItem );
2079                         return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string or a tuple containing 2 to 5 values." );
2080                 }
2081
2082                 switch (tlen) {
2083                 case -2:                /*      LABEL   */
2084                         text = PyString_AsString( pyItem );
2085                         add_numbut(i, LABEL, text, 0, 0, NULL, NULL);
2086                         break;
2087                 case 2:         /*      TOGGLE  (no tooltip)    */
2088                 case 3:         /*      TOGGLE  */
2089                         if (!PyArg_ParseTuple( pyItem, "sO!|s", &text, &Button_Type, &but, &tip )) {
2090                                 Py_DECREF( pyItem );
2091                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a tuple containing a string, a Button object and optionally a string for toggles" );
2092                         }
2093
2094                         if (but->type != BINT_TYPE) {
2095                                 Py_DECREF( pyItem );
2096                                 return EXPP_ReturnPyObjError( PyExc_ValueError, "Button object for toggles should hold an integer" );
2097                         }
2098
2099                         add_numbut(i, TOG|INT, text, 0, 0, &but->val.asint, tip);
2100                         break;
2101                 case 4:         /*      TEX and NUM (no tooltip)        */
2102                 case 5:         /*      TEX and NUM     */
2103                         if (!PyArg_ParseTuple( pyItem, "sO!OO|s", &text, &Button_Type, &but, &pyMin, &pyMax, &tip )) {
2104                                 Py_DECREF( pyItem );
2105                                 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" );
2106                         }
2107
2108                         f1 = PyNumber_Float(pyMin);
2109                         f2 = PyNumber_Float(pyMax);
2110
2111                         if (!f1 || !f2) {
2112                                 Py_DECREF( pyItem );
2113                                 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" );
2114                         }
2115
2116                         min = (float)PyFloat_AS_DOUBLE(f1);
2117                         max = (float)PyFloat_AS_DOUBLE(f2);
2118                         Py_DECREF( f1 );
2119                         Py_DECREF( f2 );
2120
2121                         switch ( but->type ) {
2122                         case BINT_TYPE:
2123                                 add_numbut(i, NUM|INT, text, min, max, &but->val.asint, tip);
2124                                 break;
2125                         case BFLOAT_TYPE:
2126                                 add_numbut(i, NUM|FLO, text, min, max, &but->val.asfloat, tip);
2127                                 break;
2128                         case BSTRING_TYPE:
2129                                 if (max+1>UI_MAX_DRAW_STR) {
2130                                         Py_DECREF( pyItem );
2131                                         return EXPP_ReturnPyObjError( PyExc_ValueError, "length of a string buttons must be less then 400" );
2132                                 }
2133                                 max = (float)floor(max);
2134
2135                                 if (max > but->slen) {
2136                                         int old_len = but->slen;
2137                                         char *old_str = but->val.asstr;
2138                                         but->slen = (int)max;
2139                                         but->val.asstr = MEM_callocN( but->slen + 1, "button pupblock");
2140                                         BLI_strncpy( but->val.asstr, old_str, old_len + 1 );
2141                                         MEM_freeN(old_str);
2142                                 }
2143
2144                                 add_numbut(i, TEX, text, 0.0f, max, but->val.asstr, tip);
2145                         }
2146
2147                         break;
2148                 default:
2149                         Py_DECREF( pyItem );
2150                         return EXPP_ReturnPyObjError( PyExc_ValueError, "expected a string or a tuple containing 2 to 5 values." );
2151                 }
2152                 Py_DECREF( pyItem );
2153         }
2154
2155         if (do_clever_numbuts(title, len, REDRAW))
2156                 return EXPP_incr_ret_True();
2157         else
2158                 return EXPP_incr_ret_False();
2159 }
2160
2161
2162 /*****************************************************************************
2163  * Function:            Method_Image                                         *
2164  * Python equivalent:   Blender.Draw.Image                                   *
2165  *                                                                           *
2166  * @author Jonathan Merritt <j.merritt@pgrad.unimelb.edu.au>                 *
2167  ****************************************************************************/
2168 static PyObject *Method_Image( PyObject * self, PyObject * args )
2169 {
2170         PyObject *pyObjImage;
2171         BPy_Image *py_img;
2172         Image *image;
2173         ImBuf *ibuf;
2174         float originX, originY;
2175         float zoomX = 1.0, zoomY = 1.0;
2176         int clipX = 0, clipY = 0, clipW = -1, clipH = -1;
2177         /*GLfloat scissorBox[4];*/
2178
2179         if (G.background) {
2180                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2181                                               "Can't run Draw.Image() in background mode." );
2182         }
2183         
2184         /* parse the arguments passed-in from Python */
2185         if( !PyArg_ParseTuple( args, "O!ff|ffiiii", &Image_Type, &pyObjImage, 
2186                 &originX, &originY, &zoomX, &zoomY, 
2187                 &clipX, &clipY, &clipW, &clipH ) )
2188                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2189                         "expected a Blender.Image and 2 floats, and " \
2190                         "optionally 2 floats and 4 ints as arguments" );
2191         /* check that the zoom factors are valid */
2192         if( ( zoomX < 0.0 ) || ( zoomY < 0.0 ) )
2193                 return EXPP_ReturnPyObjError( PyExc_TypeError,
2194                         "invalid zoom factors - they must be > 0.0" );
2195         if ((zoomX == 0.0 ) || ( zoomY == 0.0 )) {
2196                 /* sometimes python doubles can be converted from small values to a zero float, in this case just dont draw */
2197                 Py_RETURN_NONE;
2198         }
2199         
2200         
2201         /* fetch a C Image pointer from the passed-in Python object */
2202         py_img = ( BPy_Image * ) pyObjImage;
2203         image = py_img->image;
2204         ibuf = BKE_image_get_ibuf( image, NULL );
2205                 
2206         if( !ibuf )      /* if failed to load the image */
2207                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2208                                                                           "couldn't load image data in Blender" );
2209         if( !ibuf->rect )      /* no float yet */
2210                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
2211                                                                           "Image has no byte rect" );
2212         
2213         /* Update the time tag of the image */
2214         tag_image_time(image);
2215
2216         /* set up a valid clipping rectangle.  if no clip rectangle was
2217          * given, this results in inclusion of the entire image.  otherwise,
2218          * the clipping is just checked against the bounds of the image.
2219          * if clipW or clipH are less than zero then they include as much of
2220          * the image as they can. */
2221         clipX = EXPP_ClampInt( clipX, 0, ibuf->x );
2222         clipY = EXPP_ClampInt( clipY, 0, ibuf->y );
2223         if( ( clipW < 0 ) || ( clipX+clipW > ibuf->x ) )
2224                 clipW = ibuf->x - clipX;
2225         if( ( clipH < 0 ) || ( clipY+clipH > ibuf->y ) )
2226                 clipH = ibuf->y - clipY;
2227
2228         /* -- we are "Go" to Draw! -- */
2229
2230         /* set the raster position.
2231          *
2232          * If the raster position is negative, then using glRasterPos2i() 
2233          * directly would cause it to be clipped.  Instead, we first establish 
2234          * a valid raster position within the clipping rectangle of the 
2235          * window and then use glBitmap() with a NULL image pointer to offset 
2236          * it to the true position we require.  To pick an initial valid 
2237          * raster position within the viewport, we query the clipping rectangle
2238          * and use its lower-left pixel.
2239          *
2240          * This particular technique is documented in the glRasterPos() man
2241          * page, although I haven't seen it used elsewhere in Blender.
2242          */
2243
2244         /* update (W): to fix a bug where images wouldn't get drawn if the bottom
2245          * left corner of the Scripts win were above a given height or to the right
2246          * of a given width, the code below is being commented out.  It should not
2247          * be needed anyway, because spaces in Blender are projected to lie inside
2248          * their areas, see src/drawscript.c for example.  Note: the
2249          * glaRasterPosSafe2i function in src/glutil.c does use the commented out
2250          * technique, but with 0,0 instead of scissorBox.  This function can be
2251          * a little optimized, based on glaDrawPixelsSafe in that same fine, but
2252          * we're too close to release 2.37 right now. */
2253         /*
2254         glGetFloatv( GL_SCISSOR_BOX, scissorBox );
2255         glRasterPos2i( scissorBox[0], scissorBox[1] );
2256         glBitmap( 0, 0, 0.0, 0.0, 
2257                 originX-scissorBox[0], originY-scissorBox[1], NULL );
2258         */
2259
2260         /* update (cont.): using these two lines instead:
2261          * (based on glaRasterPosSafe2i, but Ken Hughes deserves credit
2262          * for suggesting this exact fix in the bug tracker) */
2263         glRasterPos2i(0, 0);
2264         glBitmap( 0, 0, 0.0, 0.0, originX, originY, NULL );
2265
2266         /* set the zoom */
2267         glPixelZoom( zoomX, zoomY );
2268
2269         /* set the width of the image (ROW_LENGTH), and the offset to the
2270          * clip origin within the image in x (SKIP_PIXELS) and 
2271          * y (SKIP_ROWS) */
2272         glPixelStorei( GL_UNPACK_ROW_LENGTH,  ibuf->x );
2273         glPixelStorei( GL_UNPACK_SKIP_PIXELS, clipX );
2274         glPixelStorei( GL_UNPACK_SKIP_ROWS,   clipY );
2275
2276         /* draw the image */
2277         glDrawPixels( clipW, clipH, GL_RGBA, GL_UNSIGNED_BYTE, 
2278                 ibuf->rect );
2279
2280         /* restore the defaults for some parameters (we could also use a
2281          * glPushClientAttrib() and glPopClientAttrib() pair). */
2282         glPixelZoom( 1.0, 1.0 );
2283         glPixelStorei( GL_UNPACK_SKIP_ROWS,   0 );
2284         glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
2285         glPixelStorei( GL_UNPACK_ROW_LENGTH,  0 );
2286
2287         Py_RETURN_NONE;
2288
2289 }
2290
2291 PyObject *Draw_Init( void )
2292 {
2293         PyObject *submodule, *dict;
2294
2295         if( PyType_Ready( &Button_Type) < 0)
2296                 Py_RETURN_NONE;
2297
2298         submodule = Py_InitModule3( "Blender.Draw", Draw_methods, Draw_doc );
2299
2300         dict = PyModule_GetDict( submodule );
2301
2302 #define EXPP_ADDCONST(x) \
2303         EXPP_dict_set_item_str(dict, #x, PyInt_FromLong(x))
2304
2305         /* So, for example:
2306          * EXPP_ADDCONST(LEFTMOUSE) becomes
2307          * EXPP_dict_set_item_str(dict, "LEFTMOUSE", PyInt_FromLong(LEFTMOUSE)) 
2308          */
2309
2310         EXPP_ADDCONST( LEFTMOUSE );
2311         EXPP_ADDCONST( MIDDLEMOUSE );
2312         EXPP_ADDCONST( RIGHTMOUSE );
2313         EXPP_ADDCONST( WHEELUPMOUSE );
2314         EXPP_ADDCONST( WHEELDOWNMOUSE );
2315         EXPP_ADDCONST( MOUSEX );
2316         EXPP_ADDCONST( MOUSEY );
2317         EXPP_ADDCONST( TIMER0 );
2318         EXPP_ADDCONST( TIMER1 );
2319         EXPP_ADDCONST( TIMER2 );
2320         EXPP_ADDCONST( TIMER3 );
2321         EXPP_ADDCONST( KEYBD );
2322         EXPP_ADDCONST( RAWKEYBD );
2323         EXPP_ADDCONST( REDRAW );
2324         EXPP_ADDCONST( INPUTCHANGE );
2325         EXPP_ADDCONST( QFULL );
2326         EXPP_ADDCONST( WINFREEZE );
2327         EXPP_ADDCONST( WINTHAW );
2328         EXPP_ADDCONST( WINCLOSE );
2329         EXPP_ADDCONST( WINQUIT );
2330 #ifndef IRISGL
2331         EXPP_ADDCONST( Q_FIRSTTIME );
2332 #endif
2333         EXPP_ADDCONST( AKEY );
2334         EXPP_ADDCONST( BKEY );
2335         EXPP_ADDCONST( CKEY );
2336         EXPP_ADDCONST( DKEY );
2337         EXPP_ADDCONST( EKEY );
2338         EXPP_ADDCONST( FKEY );
2339         EXPP_ADDCONST( GKEY );
2340         EXPP_ADDCONST( HKEY );
2341         EXPP_ADDCONST( IKEY );
2342         EXPP_ADDCONST( JKEY );
2343         EXPP_ADDCONST( KKEY );
2344         EXPP_ADDCONST( LKEY );
2345         EXPP_ADDCONST( MKEY );
2346         EXPP_ADDCONST( NKEY );
2347         EXPP_ADDCONST( OKEY );
2348         EXPP_ADDCONST( PKEY );
2349         EXPP_ADDCONST( QKEY );
2350         EXPP_ADDCONST( RKEY );
2351         EXPP_ADDCONST( SKEY );
2352         EXPP_ADDCONST( TKEY );
2353         EXPP_ADDCONST( UKEY );
2354         EXPP_ADDCONST( VKEY );
2355         EXPP_ADDCONST( WKEY );
2356         EXPP_ADDCONST( XKEY );
2357         EXPP_ADDCONST( YKEY );
2358         EXPP_ADDCONST( ZKEY );
2359         EXPP_ADDCONST( ZEROKEY );
2360         EXPP_ADDCONST( ONEKEY );
2361         EXPP_ADDCONST( TWOKEY );
2362         EXPP_ADDCONST( THREEKEY );
2363         EXPP_ADDCONST( FOURKEY );
2364         EXPP_ADDCONST( FIVEKEY );
2365         EXPP_ADDCONST( SIXKEY );
2366         EXPP_ADDCONST( SEVENKEY );
2367         EXPP_ADDCONST( EIGHTKEY );
2368         EXPP_ADDCONST( NINEKEY );
2369         EXPP_ADDCONST( CAPSLOCKKEY );
2370         EXPP_ADDCONST( LEFTCTRLKEY );
2371         EXPP_ADDCONST( LEFTALTKEY );
2372         EXPP_ADDCONST( RIGHTALTKEY );
2373         EXPP_ADDCONST( RIGHTCTRLKEY );
2374         EXPP_ADDCONST( RIGHTSHIFTKEY );
2375         EXPP_ADDCONST( LEFTSHIFTKEY );
2376         EXPP_ADDCONST( ESCKEY );
2377         EXPP_ADDCONST( TABKEY );
2378         EXPP_ADDCONST( RETKEY );
2379         EXPP_ADDCONST( SPACEKEY );
2380         EXPP_ADDCONST( LINEFEEDKEY );
2381         EXPP_ADDCONST( BACKSPACEKEY );
2382         EXPP_ADDCONST( DELKEY );
2383         EXPP_ADDCONST( SEMICOLONKEY );
2384         EXPP_ADDCONST( PERIODKEY );
2385         EXPP_ADDCONST( COMMAKEY );
2386         EXPP_ADDCONST( QUOTEKEY );
2387         EXPP_ADDCONST( ACCENTGRAVEKEY );
2388         EXPP_ADDCONST( MINUSKEY );
2389         EXPP_ADDCONST( SLASHKEY );
2390         EXPP_ADDCONST( BACKSLASHKEY );
2391         EXPP_ADDCONST( EQUALKEY );
2392         EXPP_ADDCONST( LEFTBRACKETKEY );
2393         EXPP_ADDCONST( RIGHTBRACKETKEY );
2394         EXPP_ADDCONST( LEFTARROWKEY );
2395         EXPP_ADDCONST( DOWNARROWKEY );
2396         EXPP_ADDCONST( RIGHTARROWKEY );
2397         EXPP_ADDCONST( UPARROWKEY );
2398         EXPP_ADDCONST( PAD2 );
2399         EXPP_ADDCONST( PAD4 );
2400         EXPP_ADDCONST( PAD6 );
2401         EXPP_ADDCONST( PAD8 );
2402         EXPP_ADDCONST( PAD1 );
2403         EXPP_ADDCONST( PAD3 );
2404         EXPP_ADDCONST( PAD5 );
2405         EXPP_ADDCONST( PAD7 );
2406         EXPP_ADDCONST( PAD9 );
2407         EXPP_ADDCONST( PADPERIOD );
2408         EXPP_ADDCONST( PADSLASHKEY );
2409         EXPP_ADDCONST( PADASTERKEY );
2410         EXPP_ADDCONST( PAD0 );
2411         EXPP_ADDCONST( PADMINUS );
2412         EXPP_ADDCONST( PADENTER );
2413         EXPP_ADDCONST( PADPLUSKEY );
2414         EXPP_ADDCONST( F1KEY );
2415         EXPP_ADDCONST( F2KEY );
2416         EXPP_ADDCONST( F3KEY );
2417         EXPP_ADDCONST( F4KEY );
2418         EXPP_ADDCONST( F5KEY );
2419         EXPP_ADDCONST( F6KEY );
2420         EXPP_ADDCONST( F7KEY );
2421         EXPP_ADDCONST( F8KEY );
2422         EXPP_ADDCONST( F9KEY );
2423         EXPP_ADDCONST( F10KEY );
2424         EXPP_ADDCONST( F11KEY );
2425         EXPP_ADDCONST( F12KEY );
2426         EXPP_ADDCONST( PAUSEKEY );
2427         EXPP_ADDCONST( INSERTKEY );
2428         EXPP_ADDCONST( HOMEKEY );
2429         EXPP_ADDCONST( PAGEUPKEY );
2430         EXPP_ADDCONST( PAGEDOWNKEY );
2431         EXPP_ADDCONST( ENDKEY );
2432
2433         return submodule;
2434 }