0a7d7e6f0da78ef8319b33ebefdfba4b7647d0e0
[blender-staging.git] / source / blender / python / api2_2x / Draw.c
1 /* 
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA        02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * This is a new part of Blender.
27  *
28  * Contributor(s): Willian P. Germano, Campbell Barton
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31 */
32
33 /* This file is the Blender.Draw part of opy_draw.c, from the old
34  * bpython/intern dir, with minor changes to adapt it to the new Python
35  * implementation.      Non-trivial original comments are marked with an
36  * @ symbol at their beginning. */
37
38 #include "Draw.h"
39
40 #ifdef HAVE_CONFIG_H
41 #include <config.h>
42 #endif
43
44 #ifdef WIN32
45 #include "BLI_winstuff.h"
46 #endif
47
48 #include "BLI_blenlib.h"
49 #include "MEM_guardedalloc.h"
50
51 #include "BMF_Api.h"
52
53 #include "DNA_screen_types.h"
54
55 #include "DNA_text_types.h"
56
57 #include "BKE_global.h"
58 #include "BKE_library.h"
59 #include "BKE_object.h"
60
61 #include "BIF_gl.h"
62 #include "BIF_screen.h"
63 #include "BIF_space.h"
64 #include "BIF_interface.h"
65 #include "BIF_mywindow.h"
66 #include "BIF_toolbox.h"
67
68 #include "BPI_script.h" /* script struct */
69
70 #include "interface.h"
71 #include "mydevice.h"   /*@ for all the event constants */
72
73 /* This one was an extern in BPY_main.h, but only opy_draw.c was using it */
74 int g_window_redrawn;
75
76 /*@ hack to flag that window redraw has happened inside slider callback: */
77 int EXPP_disable_force_draw = 0;
78
79 /* forward declarations for internal functions */
80 static void Button_dealloc (PyObject *self);
81 static PyObject *Button_getattr (PyObject *self, char *name);
82 static PyObject *Button_repr (PyObject *self);
83 static int Button_setattr (PyObject *self, char *name, PyObject *v);
84
85 static Button *newbutton (void);
86
87 /* GUI interface routines */
88
89 static void exit_pydraw (SpaceScript *sc, short error);
90 static void exec_callback (SpaceScript *sc, PyObject *callback,
91         PyObject *args);
92 static void spacescript_do_pywin_buttons (SpaceScript *sc,
93         unsigned short event);
94
95 static PyObject *Method_Exit (PyObject * self, PyObject * args);
96 static PyObject *Method_Register (PyObject * self, PyObject * args);
97 static PyObject *Method_Redraw (PyObject * self, PyObject * args);
98 static PyObject *Method_Draw (PyObject * self, PyObject * args);
99 static PyObject *Method_Create (PyObject * self, PyObject * args);
100
101 static PyObject *Method_Button (PyObject * self, PyObject * args);
102 static PyObject *Method_Menu (PyObject * self, PyObject * args);
103 static PyObject *Method_Toggle (PyObject * self, PyObject * args);
104 static PyObject *Method_Slider (PyObject * self, PyObject * args);
105 static PyObject *Method_Scrollbar (PyObject * self, PyObject * args);
106 static PyObject *Method_Number (PyObject * self, PyObject * args);
107 static PyObject *Method_String (PyObject * self, PyObject * args);
108 static PyObject *Method_GetStringWidth (PyObject * self, PyObject * args);
109 static PyObject *Method_Text (PyObject * self, PyObject * args);
110 static PyObject *Method_PupMenu (PyObject * self, PyObject * args);
111 /* next three by Campbell: */
112 static PyObject *Method_PupIntInput (PyObject * self, PyObject * args);
113 static PyObject *Method_PupFloatInput (PyObject * self, PyObject * args);
114 static PyObject *Method_PupStrInput (PyObject * self, PyObject * args);
115
116 static uiBlock *Get_uiBlock (void);
117 static void py_slider_update (void *butv, void *data2_unused);
118
119 static char Draw_doc[] = "The Blender.Draw submodule";
120
121 static char Method_Register_doc[] =
122 "(draw, event, button) - Register callbacks for windowing\n\n\
123 (draw) A function to draw the screen, taking no arguments\n\
124 (event) A function to handle events, taking 2 arguments (evt, val)\n\
125         (evt) The event number\n\
126         (val) The value modifier (for key and mouse press/release)\n\
127 (button) A function to handle button events, taking 1 argument (evt)\n\
128         (evt) The button number\n\n\
129 A None object can be passed if a callback is unused.";
130
131
132 static char Method_Redraw_doc[] = "([after]) - Queue a redraw event\n\n\
133 [after=0] Determines whether the redraw is processed before\n\
134 or after other input events.\n\n\
135 Redraw events are buffered so that regardless of how many events\n\
136 are queued the window only receives one redraw event.";
137
138 static char Method_Draw_doc[] = "() - Force an immediate redraw\n\n\
139 Forced redraws are not buffered, in other words the window is redrawn\n\
140 exactly once for everytime this function is called.";
141
142
143 static char Method_Create_doc[] =
144 "(value) - Create a default Button object\n\n\
145  (value) - The value to store in the button\n\n\
146  Valid values are ints, floats, and strings";
147
148 static char Method_Button_doc[] =
149 "(name, event, x, y, width, height, [tooltip]) - Create a new Button \
150 (push) button\n\n\
151 (name) A string to display on the button\n\
152 (event) The event number to pass to the button event function when activated\n\
153 (x, y) The lower left coordinate of the button\n\
154 (width, height) The button width and height\n\
155 [tooltip=] The button's tooltip\n\n\
156 This function can be called as Button() or PushButton().";
157
158 static char Method_Menu_doc[] =
159 "(name, event, x, y, width, height, default, [tooltip]) - Create a new Menu \
160 button\n\n\
161 (name) A string to display on the button\n\
162 (event) The event number to pass to the button event function when activated\n\
163 (x, y) The lower left coordinate of the button\n\
164 (width, height) The button width and height\n\
165 (default) The number of the option to be selected by default\n\
166 [tooltip=" "] The button's tooltip\n\n\
167 The menu options are specified through the name of the\n\
168 button. Options are followed by a format code and separated\n\
169 by the '|' (pipe) character.\n\
170 Valid format codes are\n\
171         %t - The option should be used as the title\n\
172         %xN - The option should set the integer N in the button value.";
173
174 static char Method_Toggle_doc[] =
175 "(name, event, x, y, width, height, default, [tooltip]) - Create a new Toggle \
176 button\n\n\
177 (name) A string to display on the button\n\
178 (event) The event number to pass to the button event function when activated\n\
179 (x, y) The lower left coordinate of the button\n\
180 (width, height) The button width and height\n\
181 (default) An integer (0 or 1) specifying the default state\n\
182 [tooltip=] The button's tooltip";
183
184
185 static char Method_Slider_doc[] =
186 "(name, event, x, y, width, height, initial, min, max, [update, tooltip]) - \
187 Create a new Slider button\n\n\
188 (name) A string to display on the button\n\
189 (event) The event number to pass to the button event function when activated\n\
190 (x, y) The lower left coordinate of the button\n\
191 (width, height) The button width and height\n\
192 (initial, min, max) Three values (int or float) specifying the initial \
193                                 and limit values.\n\
194 [update=1] A value controlling whether the slider will emit events as it \
195 is edited.\n\
196         A non-zero value (default) enables the events. A zero value supresses them.\n\
197 [tooltip=] The button's tooltip";
198
199
200 static char Method_Scrollbar_doc[] =
201 "(event, x, y, width, height, initial, min, max, [update, tooltip]) - Create a \
202 new Scrollbar\n\n\
203 (event) The event number to pass to the button event function when activated\n\
204 (x, y) The lower left coordinate of the button\n\
205 (width, height) The button width and height\n\
206 (initial, min, max) Three values (int or float) specifying the initial and limit values.\n\
207 [update=1] A value controlling whether the slider will emit events as it is edited.\n\
208         A non-zero value (default) enables the events. A zero value supresses them.\n\
209 [tooltip=] The button's tooltip";
210
211 static char Method_Number_doc[] =
212 "(name, event, x, y, width, height, initial, min, max, [tooltip]) - Create a \
213 new Number button\n\n\
214 (name) A string to display on the button\n\
215 (event) The event number to pass to the button event function when activated\n\
216 (x, y) The lower left coordinate of the button\n\
217 (width, height) The button width and height\n\
218 (initial, min, max) Three values (int or float) specifying the initial and \
219 limit values.\n\
220 [tooltip=] The button's tooltip";
221
222 static char Method_String_doc[] =
223 "(name, event, x, y, width, height, initial, length, [tooltip]) - Create a \
224 new String button\n\n\
225 (name) A string to display on the button\n\
226 (event) The event number to pass to the button event function when activated\n\
227 (x, y) The lower left coordinate of the button\n\
228 (width, height) The button width and height\n\
229 (initial) The string to display initially\n\
230 (length) The maximum input length\n\
231 [tooltip=] The button's tooltip";
232
233 static char Method_GetStringWidth_doc[] =
234 "(text, font = 'normal') - Return the width in pixels of the given string\n\
235 (font) The font size: 'normal' (default), 'small' or 'tiny'.";
236
237 static char Method_Text_doc[] =
238 "(text, font = 'normal') - Draw text onscreen\n\n\
239 (text) The text to draw\n\
240 (font) The font size: 'normal' (default), 'small' or 'tiny'.\n\n\
241 This function returns the width of the drawn string.";
242
243 static char Method_PupMenu_doc[] =
244 "(string, maxrow = None) - Display a pop-up menu at the screen.\n\
245 The contents of the pop-up are specified through the 'string' argument,\n\
246 like with Draw.Menu.\n\
247 'maxrow' is an optional int to control how many rows the pop-up should have.\n\
248 Options are followed by a format code and separated\n\
249 by the '|' (pipe) character.\n\
250 Valid format codes are\n\
251         %t - The option should be used as the title\n\
252         %xN - The option should set the integer N in the button value.\n\n\
253 Ex: Draw.PupMenu('OK?%t|QUIT BLENDER') # should be familiar ...";
254
255 static char Method_PupIntInput_doc[] =
256 "(text, default, min, max) - Display an int pop-up input.\n\
257 (text) - text string to display on the button;\n\
258 (default, min, max) - the default, min and max int values for the button;\n\
259 Return the user input value or None on user exit";
260
261 static char Method_PupFloatInput_doc[] =
262 "(text, default, min, max, clickStep, floatLen) - Display a float pop-up input.\n\
263 (text) - text string to display on the button;\n\
264 (default, min, max) - the default, min and max float values for the button;\n\
265 (clickStep) - float increment/decrement for each click on the button arrows;\n\
266 (floatLen) - an integer defining the precision (number of decimal places) of \n\
267 the float value show.\n\
268 Return the user input value or None on user exit";
269
270 static char Method_PupStrInput_doc[] =
271 "(text, default, max = 20) - Display a float pop-up input.\n\
272 (text) - text string to display on the button;\n\
273 (default) - the initial string to display (truncated to 'max' chars);\n\
274 (max = 20) - The maximum number of chars the user can input;\n\
275 Return the user input value or None on user exit";
276
277 static char Method_Exit_doc[] = "() - Exit the windowing interface";
278
279 /*
280 * here we engage in some macro trickery to define the PyMethodDef table
281 */
282
283 #define _MethodDef(func, prefix) \
284         {#func, prefix##_##func, METH_VARARGS, prefix##_##func##_doc}
285
286 /* So that _MethodDef(delete, Scene) expands to:
287  * {"delete", Scene_delete, METH_VARARGS, Scene_delete_doc} */
288
289 #undef MethodDef
290 #define MethodDef(func) _MethodDef(func, Method)
291
292 static struct PyMethodDef Draw_methods[] = {
293         MethodDef (Create),
294         MethodDef (Button),
295         MethodDef (Toggle),
296         MethodDef (Menu),
297         MethodDef (Slider),
298         MethodDef (Scrollbar),
299         MethodDef (Number),
300         MethodDef (String),
301         MethodDef (GetStringWidth),
302         MethodDef (Text),
303         MethodDef (PupMenu),
304         MethodDef (PupIntInput),
305         MethodDef (PupFloatInput),
306         MethodDef (PupStrInput),
307         MethodDef (Exit),
308         MethodDef (Redraw),
309         MethodDef (Draw),
310         MethodDef (Register),
311   {"PushButton", Method_Button, METH_VARARGS, Method_Button_doc},
312         {NULL, NULL,0,NULL}
313 };
314
315 PyTypeObject Button_Type = {
316         PyObject_HEAD_INIT (NULL) 0,    /*ob_size */
317         "Button",                       /*tp_name */
318         sizeof (Button),                /*tp_basicsize */
319         0,                              /*tp_itemsize */
320         (destructor) Button_dealloc,    /*tp_dealloc */
321         (printfunc) 0,          /*tp_print */
322         (getattrfunc) Button_getattr,   /*tp_getattr */
323         (setattrfunc) Button_setattr,   /*tp_setattr */
324         (cmpfunc) 0,                    /*tp_cmp */
325         (reprfunc) Button_repr, /*tp_repr */
326 };
327
328
329 static void Button_dealloc (PyObject *self)
330 {
331         Button *but = (Button *) self;
332
333         if (but->type == 3) MEM_freeN (but->val.asstr);
334
335         PyObject_DEL (self);
336 }
337
338 static PyObject *Button_getattr (PyObject *self, char *name)
339 {
340         Button *but = (Button *) self;
341
342         if (strcmp (name, "val") == 0) {
343                 if (but->type == 1)
344                         return Py_BuildValue ("i", but->val.asint);
345                 else if (but->type == 2)
346                         return Py_BuildValue ("f", but->val.asfloat);
347                 else if (but->type == 3)
348                         return Py_BuildValue ("s", but->val.asstr);
349         }
350
351         PyErr_SetString (PyExc_AttributeError, name);
352         return NULL;
353 }
354
355 static int Button_setattr (PyObject *self, char *name, PyObject *v)
356 {
357         Button *but = (Button *) self;
358
359         if (strcmp (name, "val") == 0) {
360                 if (but->type == 1)
361                         PyArg_Parse (v, "i", &but->val.asint);
362                 else if (but->type == 2)
363                         PyArg_Parse (v, "f", &but->val.asfloat);
364                 else if (but->type == 3) {
365                         char *newstr;
366                         PyArg_Parse (v, "s", &newstr);
367
368                         /* if the length of the new string is the same as */
369                         /* the old one, just copy, else delete and realloc. */
370                         if (but->slen == strlen (newstr)) {
371                                 BLI_strncpy (but->val.asstr, newstr, but->slen);
372                         }
373                         else {
374                                 MEM_freeN (but->val.asstr);
375                                 but->slen = strlen (newstr);
376                                 but->val.asstr = MEM_mallocN (but->slen + 1, "button setattr");
377                                 strcpy (but->val.asstr, newstr);
378                         }
379                 }
380         }
381         else {
382                 PyErr_SetString (PyExc_AttributeError, name);
383                 return -1;
384         }
385
386         return 0;
387 }
388
389 static PyObject *Button_repr (PyObject * self)
390 {
391         return PyObject_Repr (Button_getattr (self, "val"));
392 }
393
394 static Button *newbutton (void)
395 {
396         Button *but = (Button *) PyObject_NEW (Button, &Button_Type);
397
398         return but;
399 }
400
401 /* GUI interface routines */
402
403 static void exit_pydraw (SpaceScript *sc, short err)
404 {
405         Script *script = NULL;
406
407         if (!sc || !sc->script) return;
408
409         script = sc->script;
410
411         if (err) {
412                 PyErr_Print ();
413                 script->flags = 0;      /* mark script struct for deletion */
414                 error ("Python script error: check console");
415                 scrarea_queue_redraw (sc->area);
416         }
417
418         Py_XDECREF ((PyObject *) script->py_draw);
419         Py_XDECREF ((PyObject *) script->py_event);
420         Py_XDECREF ((PyObject *) script->py_button);
421
422         script->py_draw = script->py_event = script->py_button = NULL;
423 }
424
425 static void exec_callback (SpaceScript *sc, PyObject *callback, PyObject *args)
426 {
427         PyObject *result = PyObject_CallObject (callback, args);
428
429         if (result == NULL && sc->script) {/* errors in the script */
430
431                 if (sc->script->lastspace == SPACE_TEXT) {/*if it can be an ALT+P script */
432                         Text *text = G.main->text.first;
433
434                         while (text) {/* find it and free its compiled code */
435
436                                 if (!strcmp (text->id.name + 2, sc->script->id.name + 2)) {
437                                         BPY_free_compiled_text (text);
438                                         break;
439                                 }
440
441                                 text = text->id.next;
442                         }
443                 }
444                 exit_pydraw (sc, 1);
445         }
446
447         Py_XDECREF (result);
448         Py_DECREF (args);
449 }
450
451 /* BPY_spacescript_do_pywin_draw, the static spacescript_do_pywin_buttons and
452  * BPY_spacescript_do_pywin_event are the three functions responsible for
453  * calling the draw, buttons and event callbacks registered with Draw.Register
454  * (see Method_Register below).  They are called (only the two BPY_ ones)
455  * from blender/src/drawscript.c */
456
457 void BPY_spacescript_do_pywin_draw (SpaceScript *sc)
458 {
459         uiBlock *block;
460         char butblock[20];
461         Script *script = sc->script;
462
463         sprintf (butblock, "win %d", curarea->win);
464         block = uiNewBlock (&curarea->uiblocks, butblock, UI_EMBOSSX,
465                 UI_HELV, curarea->win);
466
467         if (script->py_draw) {
468                 glPushAttrib (GL_ALL_ATTRIB_BITS);
469                 exec_callback (sc, script->py_draw, Py_BuildValue ("()"));
470                 glPopAttrib ();
471         }
472         else {
473                 glClearColor (0.4375, 0.4375, 0.4375, 0.0);
474                 glClear (GL_COLOR_BUFFER_BIT);
475         }
476
477         uiDrawBlock (block);
478
479         curarea->win_swap = WIN_BACK_OK;
480 }
481
482 static void spacescript_do_pywin_buttons (SpaceScript *sc, unsigned short event)
483 {
484         if (sc->script->py_button)
485                 exec_callback (sc, sc->script->py_button, Py_BuildValue ("(i)", event));
486 }
487
488 void BPY_spacescript_do_pywin_event (SpaceScript *sc, unsigned short event,
489         short val)
490 {
491         static int menu_hack = 0;
492
493         /* about menu_hack above: when a menu returns after an entry is chosen,
494          * two events are generated, the second one with val = 4.  We don't want
495          * this second one to be passed to Python, because it can be confused with
496          * some event with same number defined by the script.
497          * What we do is set menu_hack to 1 if a button event occurs.
498          * Then if the next one is also a button event, w/ val = 4, we discard it. */
499
500         if (event != UI_BUT_EVENT || !val) menu_hack = 0;
501
502         if (event == QKEY && G.qual & (LR_ALTKEY | LR_CTRLKEY)) {
503                 /* finish script: user pressed ALT+Q or CONTROL+Q */
504                 Script *script = sc->script;
505
506                 exit_pydraw (sc, 0);
507
508                 script->flags &= ~SCRIPT_GUI;   /* we're done with this script */
509
510                 return;
511         }
512
513         if (val) {
514                 if (uiDoBlocks (&curarea->uiblocks, event) != UI_NOTHING) event = 0;
515
516                 if (event == UI_BUT_EVENT) {
517
518                         if (menu_hack && (val == 4)) { /* "false" event? */
519                                 menu_hack = 0; /* if so, discard it and clear menu_hack */
520                         }
521                         else {
522                                 menu_hack = 1;
523                                 spacescript_do_pywin_buttons (sc, val);
524                         }
525
526                 }
527         }
528
529         if (sc->script->py_event)
530                 exec_callback (sc, sc->script->py_event, Py_BuildValue("(ii)", event, val));
531 }
532
533 static PyObject *Method_Exit (PyObject *self, PyObject *args)
534 {
535         SpaceScript *sc;
536         Script *script;
537
538         /* if users call Draw.Exit when we are already out of the SPACE_SCRIPT, we
539          * simply return, for compatibility */
540         if (curarea->spacetype == SPACE_SCRIPT)
541                 sc = curarea->spacedata.first;
542         else
543                 return EXPP_incr_ret (Py_None);
544
545         if (!PyArg_ParseTuple (args, ""))
546                 return EXPP_ReturnPyObjError (PyExc_AttributeError,
547                         "expected empty argument list");
548
549         exit_pydraw (sc, 0);
550
551         script = sc->script;
552
553         /* remove our lock to the current namespace */
554         script->flags &= ~SCRIPT_GUI;
555
556         return EXPP_incr_ret (Py_None);
557 }
558
559 /* Method_Register (Draw.Register) registers callbacks for drawing, events
560  * and gui button events, so a script can continue executing after the
561  * interpreter reached its end and returned control to Blender.  Everytime
562  * the SPACE_SCRIPT window with this script is redrawn, the registered
563  * callbacks are executed. */
564 static PyObject *Method_Register (PyObject *self, PyObject *args)
565 {
566         PyObject *newdrawc = NULL, *neweventc = NULL, *newbuttonc = NULL;
567         SpaceScript *sc;
568         Script *script;
569         int startspace = 0;
570
571         if (!PyArg_ParseTuple (args, "O|OO", &newdrawc, &neweventc, &newbuttonc))
572                 return EXPP_ReturnPyObjError (PyExc_TypeError,
573                         "expected one or three PyObjects");
574
575         if (!PyCallable_Check (newdrawc))
576                 newdrawc = NULL;
577         if (!PyCallable_Check (neweventc))
578                 neweventc = NULL;
579         if (!PyCallable_Check (newbuttonc))
580                 newbuttonc = NULL;
581
582         if (!(newdrawc || neweventc || newbuttonc))
583                 return EXPP_incr_ret (Py_None);
584
585         startspace = curarea->spacetype;
586
587         /* first make sure the current area is of type SPACE_SCRIPT */
588         if (startspace != SPACE_SCRIPT)
589                 newspace (curarea, SPACE_SCRIPT);
590
591         sc = curarea->spacedata.first;
592
593         /* this is a little confusing: we need to know which script is being executed
594          * now, so we can preserve its namespace from being deleted.
595          * There are two possibilities:
596          * a) One new script was created and the interpreter still hasn't returned
597          * from executing it.
598          * b) Any number of scripts were executed but left registered callbacks and
599          * so were not deleted yet. */
600
601         /* To find out if we're dealing with a) or b), we start with the last
602          * created one: */
603         script = G.main->script.last;
604
605         if (!script) {
606                 return EXPP_ReturnPyObjError (PyExc_RuntimeError,
607                         "Draw.Register: couldn't get pointer to script struct");
608         }
609
610         /* if the flag SCRIPT_RUNNING is set, this script is case a): */
611         if (!(script->flags & SCRIPT_RUNNING)) {
612                 script = sc->script;
613         }
614         /* otherwise it's case b) and the script we want is here: */
615         else
616                 sc->script = script;
617
618         /* Now we have the right script and can set a lock so its namespace can't be
619          * deleted for as long as we need it */
620         script->flags |= SCRIPT_GUI;
621
622         /* save the last space so we can go back to it upon finishing */
623         if (!script->lastspace)
624                 script->lastspace = startspace;
625
626         /* clean the old callbacks */
627         exit_pydraw (sc, 0);
628
629         /* prepare the new ones and insert them */
630         Py_XINCREF (newdrawc);
631         Py_XINCREF (neweventc);
632         Py_XINCREF (newbuttonc);
633
634         script->py_draw = newdrawc;
635         script->py_event = neweventc;
636         script->py_button = newbuttonc;
637
638         scrarea_queue_redraw (sc->area);
639
640         return EXPP_incr_ret (Py_None);
641 }
642
643 static PyObject *Method_Redraw (PyObject *self, PyObject *args)
644 {
645         int after = 0;
646
647         if (!PyArg_ParseTuple (args, "|i", &after))
648                 return EXPP_ReturnPyObjError (PyExc_TypeError,
649                         "expected int argument (or nothing)");
650
651         /* XXX shouldn't we redraw all spacescript wins with this script on ? */
652         if (after)
653                 addafterqueue (curarea->win, REDRAW, 1);
654         else
655                 scrarea_queue_winredraw (curarea);
656
657         return EXPP_incr_ret (Py_None);
658 }
659
660 static PyObject *Method_Draw (PyObject * self, PyObject * args)
661 {
662         /*@ If forced drawing is disable queue a redraw event instead */
663         if (EXPP_disable_force_draw) {
664                 scrarea_queue_winredraw (curarea);
665                 return EXPP_incr_ret (Py_None);
666         }
667
668         if (!PyArg_ParseTuple (args, ""))
669                 return EXPP_ReturnPyObjError (PyExc_AttributeError,
670                         "expected empty argument list");
671
672         scrarea_do_windraw (curarea);
673
674         screen_swapbuffers ();
675
676         return EXPP_incr_ret (Py_None);
677 }
678
679 static PyObject *Method_Create (PyObject *self, PyObject *args)
680 {
681         Button *but;
682         PyObject *in;
683
684         if (!PyArg_ParseTuple (args, "O", &in))
685                 return EXPP_ReturnPyObjError (PyExc_TypeError,
686                         "expected PyObject argument");
687
688         but = newbutton ();
689         if (PyFloat_Check (in)) {
690                 but->type = 2;
691                 but->val.asfloat = PyFloat_AsDouble (in);
692         }
693         else if (PyInt_Check (in)) {
694                 but->type = 1;
695                 but->val.asint = PyInt_AsLong (in);
696         }
697         else if (PyString_Check (in)) {
698                 char *newstr = PyString_AsString (in);
699
700                 but->type = 3;
701                 but->slen = strlen (newstr);
702                 but->val.asstr = MEM_mallocN (but->slen + 1, "button string");
703
704                 strcpy (but->val.asstr, newstr);
705         }
706
707         return (PyObject *) but;
708 }
709
710 static uiBlock *Get_uiBlock (void)
711 {
712         char butblock[32];
713
714         sprintf (butblock, "win %d", curarea->win);
715
716         return uiGetBlock (butblock, curarea);
717 }
718
719 static PyObject *Method_Button (PyObject *self, PyObject *args)
720 {
721         uiBlock *block;
722         char *name, *tip = NULL;
723         int event;
724         int x, y, w, h;
725
726         if (!PyArg_ParseTuple (args, "siiiii|s", &name, &event,
727                         &x, &y, &w, &h, &tip))
728                 return EXPP_ReturnPyObjError (PyExc_TypeError,
729                 "expected a string, five ints and optionally another string as arguments");
730
731         block = Get_uiBlock ();
732
733         if (block)
734                 uiDefBut (block, BUT, event, name, x, y, w, h, 0, 0, 0, 0, 0, tip);
735
736         return EXPP_incr_ret (Py_None);
737 }
738
739 static PyObject *Method_Menu (PyObject *self, PyObject *args)
740 {
741         uiBlock *block;
742         char *name, *tip = NULL;
743         int event, def;
744         int x, y, w, h;
745         Button *but;
746
747         if (!PyArg_ParseTuple (args, "siiiiii|s", &name, &event,
748                          &x, &y, &w, &h, &def, &tip))
749                 return EXPP_ReturnPyObjError (PyExc_TypeError,
750                         "expected a string, six ints and optionally another string as arguments");
751
752         but = newbutton ();
753         but->type = 1;
754         but->val.asint = def;
755
756         block = Get_uiBlock ();
757         if (block)
758                 uiDefButI (block, MENU, event, name, x, y, w, h,
759                         &but->val.asint, 0, 0, 0, 0, tip);
760
761         return (PyObject *) but;
762 }
763
764 static PyObject *Method_Toggle (PyObject *self, PyObject *args)
765 {
766         uiBlock *block;
767         char *name, *tip = NULL;
768         int event;
769         int x, y, w, h, def;
770         Button *but;
771
772         if (!PyArg_ParseTuple (args, "siiiiii|s", &name, &event,
773                          &x, &y, &w, &h, &def, &tip))
774                 return EXPP_ReturnPyObjError (PyExc_TypeError,
775                         "expected a string, six ints and optionally another string as arguments");
776
777         but = newbutton ();
778         but->type = 1;
779         but->val.asint = def;
780
781         block = Get_uiBlock ();
782         if (block)
783                 uiDefButI (block, TOG, event, name, x, y, w, h,
784                         &but->val.asint, 0, 0, 0, 0, tip);
785
786         return (PyObject *) but;
787 }
788
789 /*@DO NOT TOUCH THIS FUNCTION !
790          Redrawing a slider inside its own callback routine is actually forbidden
791          with the current toolkit architecture (button routines are not reentrant).
792          But it works anyway.
793          XXX This is condemned to be dinosource in future - it's a hack.
794          */
795
796 static void     py_slider_update (void *butv, void *data2_unused)
797 {
798         uiBut *but = butv;
799
800         EXPP_disable_force_draw = 1;
801         /*@
802                  Disable forced drawing, otherwise the button object which
803                  is still being used might be deleted 
804          */
805
806         /*@  
807                  spacetext_do_pywin_buttons(curarea->spacedata.first, but->retval); */
808
809         g_window_redrawn = 0;
810         curarea->win_swap = WIN_BACK_OK;
811         /* removed global uiFrontBuf (contact ton when this goes wrong here) */
812         spacescript_do_pywin_buttons (curarea->spacedata.first,
813                                 uiButGetRetVal (but));
814
815         if (!g_window_redrawn) { /*@ if Redraw already called */
816                 disable_where_script (1);
817                 M_Window_Redraw (0, Py_BuildValue ("(i)", SPACE_VIEW3D));
818                 disable_where_script (0);
819         }
820
821         EXPP_disable_force_draw = 0;
822 }
823
824 static PyObject *Method_Slider (PyObject *self, PyObject *args)
825 {
826         uiBlock *block;
827         char *name, *tip = NULL;
828         int event;
829         int x, y, w, h, realtime = 1;
830         Button *but;
831         PyObject *mino, *maxo, *inio;
832
833         if (!PyArg_ParseTuple (args, "siiiiiOOO|is", &name, &event,
834                         &x, &y, &w, &h, &inio, &mino, &maxo, &realtime, &tip))
835                 return EXPP_ReturnPyObjError (PyExc_TypeError,
836                         "expected a string, five ints, three PyObjects\n\
837                         and optionally another int and string as arguments");
838
839         but = newbutton ();
840
841         if (PyFloat_Check (inio)) {
842                 float ini, min, max;
843
844                 ini = PyFloat_AsDouble (inio);
845                 min = PyFloat_AsDouble (mino);
846                 max = PyFloat_AsDouble (maxo);
847
848                 but->type = 2;
849                 but->val.asfloat = ini;
850
851                 block = Get_uiBlock ();
852                 if (block) {
853                         uiBut *ubut;
854                         ubut = uiDefButF (block, NUMSLI, event, name, x, y, w, h,
855                                 &but->val.asfloat, min, max, 0, 0, tip);
856                         if (realtime)
857                                 uiButSetFunc (ubut, py_slider_update, ubut, NULL);
858                 }
859         }
860         else {
861                 int ini, min, max;
862
863                 ini = PyInt_AsLong (inio);
864                 min = PyInt_AsLong (mino);
865                 max = PyInt_AsLong (maxo);
866
867                 but->type = 1;
868                 but->val.asint = ini;
869
870                 block = Get_uiBlock ();
871                 if (block) {
872                         uiBut *ubut;
873                         ubut = uiDefButI (block, NUMSLI, event, name, x, y, w, h,
874                                 &but->val.asint, min, max, 0, 0, tip);
875                         if (realtime)
876                                 uiButSetFunc (ubut, py_slider_update, ubut, NULL);
877                 }
878         }
879         return (PyObject *) but;
880 }
881
882 static PyObject *Method_Scrollbar (PyObject *self, PyObject *args)
883 {
884         char *tip = NULL;
885         uiBlock *block;
886         int event;
887         int x, y, w, h, realtime = 1;
888         Button *but;
889         PyObject *mino, *maxo, *inio;
890         float ini, min, max;
891
892         if (!PyArg_ParseTuple (args, "iiiiiOOO|is", &event, &x, &y, &w, &h,
893                          &inio, &mino, &maxo, &realtime, &tip))
894                 return EXPP_ReturnPyObjError (PyExc_TypeError,
895                         "expected five ints, three PyObjects and optionally\n\
896                         another int and string as arguments");
897
898         if (!PyNumber_Check (inio) || !PyNumber_Check (inio)
899                         || !PyNumber_Check (inio))
900                 return EXPP_ReturnPyObjError (PyExc_AttributeError,
901                         "expected numbers for initial, min, and max");
902
903         but = newbutton ();
904
905         if (PyFloat_Check (inio))
906                 but->type = 2;
907         else
908                 but->type = 1;
909
910         ini = PyFloat_AsDouble (inio);
911         min = PyFloat_AsDouble (mino);
912         max = PyFloat_AsDouble (maxo);
913
914         if (but->type == 2) {
915                 but->val.asfloat = ini;
916                 block = Get_uiBlock ();
917                 if (block) {
918                         uiBut *ubut;
919                         ubut = uiDefButF (block, SCROLL, event, "", x, y, w, h,
920                                 &but->val.asfloat, min, max, 0, 0, tip);
921                         if (realtime)
922                                 uiButSetFunc (ubut, py_slider_update, ubut, NULL);
923                 }
924         }
925         else {
926                 but->val.asint = ini;
927                 block = Get_uiBlock ();
928                 if (block) {
929                         uiBut *ubut;
930                         ubut = uiDefButI (block, SCROLL, event, "", x, y, w, h,
931                                 &but->val.asint, min, max, 0, 0, tip);
932                         if (realtime)
933                                 uiButSetFunc (ubut, py_slider_update, ubut, NULL);
934                 }
935         }
936
937         return (PyObject *) but;
938 }
939
940 static PyObject *Method_Number (PyObject *self, PyObject *args)
941 {
942         uiBlock *block;
943         char *name, *tip = NULL;
944         int event;
945         int x, y, w, h;
946         Button *but;
947         PyObject *mino, *maxo, *inio;
948
949         if (!PyArg_ParseTuple (args, "siiiiiOOO|s", &name, &event,
950                         &x, &y, &w, &h, &inio, &mino, &maxo, &tip))
951                 return EXPP_ReturnPyObjError (PyExc_TypeError,
952                         "expected a string, five ints, three PyObjects and\n\
953                         optionally another string as arguments");
954
955         but = newbutton ();
956
957         if (PyFloat_Check (inio)) {
958                 float ini, min, max;
959
960                 ini = PyFloat_AsDouble (inio);
961                 min = PyFloat_AsDouble (mino);
962                 max = PyFloat_AsDouble (maxo);
963
964                 but->type = 2;
965                 but->val.asfloat = ini;
966
967                 block = Get_uiBlock ();
968                 if (block)
969                         uiDefButF (block, NUM, event, name, x, y, w, h,
970                                 &but->val.asfloat, min, max, 0, 0, tip);
971         }
972         else {
973                 int ini, min, max;
974
975                 ini = PyInt_AsLong (inio);
976                 min = PyInt_AsLong (mino);
977                 max = PyInt_AsLong (maxo);
978
979                 but->type = 1;
980                 but->val.asint = ini;
981
982                 block = Get_uiBlock ();
983                 if (block)
984                         uiDefButI (block, NUM, event, name, x, y, w, h,
985                                 &but->val.asint, min, max, 0, 0, tip);
986         }
987
988         return (PyObject *) but;
989 }
990
991 static PyObject *Method_String (PyObject *self, PyObject *args)
992 {
993         uiBlock *block;
994         char *name, *tip = NULL, *newstr;
995         int event;
996         int x, y, w, h, len;
997         Button *but;
998
999         if (!PyArg_ParseTuple (args, "siiiiisi|s", &name, &event,
1000                         &x, &y, &w, &h, &newstr, &len, &tip))
1001                 return EXPP_ReturnPyObjError (PyExc_TypeError,
1002                         "expected a string, five ints, a string, an int and\n\
1003                         optionally another string as arguments");
1004
1005         but = newbutton ();
1006         but->type = 3;
1007         but->slen = len;
1008         but->val.asstr = MEM_mallocN (len + 1, "button string");
1009
1010         strncpy (but->val.asstr, newstr, len);
1011         but->val.asstr[len] = 0;
1012
1013         block = Get_uiBlock ();
1014         if (block)
1015                 uiDefBut (block, TEX, event, name, x, y, w, h,
1016                         but->val.asstr, 0, len, 0, 0, tip);
1017
1018         return (PyObject *) but;
1019 }
1020
1021 static PyObject *Method_GetStringWidth (PyObject *self, PyObject *args)
1022 {
1023         char *text;
1024         char *font_str = "normal";
1025         struct BMF_Font *font;
1026         PyObject *width;
1027
1028         if (!PyArg_ParseTuple (args, "s|s", &text, &font_str))
1029                 return EXPP_ReturnPyObjError (PyExc_TypeError,
1030                                         "expected one or two string arguments");
1031
1032         if (!strcmp (font_str, "normal"))
1033                 font = (&G)->font;
1034         else if (!strcmp (font_str, "small"))
1035                 font = (&G)->fonts;
1036         else if (!strcmp (font_str, "tiny"))
1037                 font = (&G)->fontss;
1038         else
1039                 return EXPP_ReturnPyObjError (PyExc_AttributeError,
1040                                         "\"font\" must be: 'normal' (default), 'small' or 'tiny'.");
1041
1042         width = PyInt_FromLong (BMF_GetStringWidth (font, text));
1043
1044         if (!width)
1045                 return EXPP_ReturnPyObjError (PyExc_MemoryError, "couldn't create PyInt");
1046
1047         return width;
1048 }
1049
1050 static PyObject *Method_Text (PyObject *self, PyObject *args)
1051 {
1052         char *text;
1053         char *font_str = NULL;
1054         struct BMF_Font *font;
1055
1056         if (!PyArg_ParseTuple (args, "s|s", &text, &font_str))
1057                 return EXPP_ReturnPyObjError (PyExc_TypeError,
1058                         "expected one or two string arguments");
1059
1060         if (!font_str)
1061                 font = (&G)->font;
1062         else if (!strcmp (font_str, "normal"))
1063                 font = (&G)->font;
1064         else if (!strcmp (font_str, "small"))
1065                 font = (&G)->fonts;
1066         else if (!strcmp (font_str, "tiny"))
1067                 font = (&G)->fontss;
1068         else
1069                 return EXPP_ReturnPyObjError (PyExc_AttributeError,
1070                         "\"font\" must be: 'normal' (default), 'small' or 'tiny'.");
1071
1072         BMF_DrawString (font, text);
1073
1074         return PyInt_FromLong (BMF_GetStringWidth (font, text));
1075 }
1076
1077 static PyObject *Method_PupMenu (PyObject *self, PyObject *args)
1078 {
1079         char *text;
1080         int maxrow = -1;
1081         PyObject *ret;
1082
1083         if (!PyArg_ParseTuple (args, "s|i", &text, &maxrow))
1084                 return EXPP_ReturnPyObjError (PyExc_TypeError,
1085                         "expected a string and optionally an int as arguments");
1086
1087         if (maxrow >= 0)
1088                 ret = PyInt_FromLong (pupmenu_col (text, maxrow));
1089         else
1090                 ret = PyInt_FromLong (pupmenu (text));
1091
1092         if (ret) return ret;
1093
1094         return EXPP_ReturnPyObjError (PyExc_MemoryError, "couldn't create a PyInt");
1095 }
1096
1097 static PyObject *Method_PupIntInput (PyObject *self, PyObject *args)
1098 {
1099         char *text = NULL;
1100         int min = 0, max = 1;
1101         short var = 0;
1102         PyObject *ret = NULL;
1103         
1104         if (!PyArg_ParseTuple (args, "s|hii", &text, &var, &min, &max))
1105                 return EXPP_ReturnPyObjError (PyExc_TypeError,
1106                         "expected 1 string and 3 int arguments");
1107         
1108         if (button(&var, min, max, text) == 0) {
1109                 Py_INCREF(Py_None);
1110                 return Py_None;
1111         }
1112         ret = PyInt_FromLong (var);
1113         if (ret) return ret;
1114                 
1115         return EXPP_ReturnPyObjError (PyExc_MemoryError, "couldn't create a PyInt");
1116 }
1117
1118 static PyObject *Method_PupFloatInput (PyObject *self, PyObject *args)
1119 {
1120         char *text = NULL;
1121         float min = 0, max = 1, var = 0, a1 = 10, a2 = 2;
1122         PyObject *ret = NULL;
1123
1124         if (!PyArg_ParseTuple (args, "s|fffff", &text, &var, &min, &max, &a1, &a2))
1125                 return EXPP_ReturnPyObjError (PyExc_TypeError,
1126                         "expected 1 string and 5 float arguments");
1127
1128         if(fbutton(&var, min, max, a1, a2, text)==0) {
1129                 Py_INCREF(Py_None);
1130                 return Py_None;
1131         }
1132         ret = PyFloat_FromDouble (var);
1133         if (ret) return ret;
1134
1135         return EXPP_ReturnPyObjError (PyExc_MemoryError, "couldn't create a PyFloat");
1136 }
1137
1138 static PyObject *Method_PupStrInput (PyObject *self, PyObject *args)
1139 {
1140         char *text = NULL, *textMsg = NULL;
1141         char tmp[101];
1142         char max = 20;
1143         PyObject *ret = NULL;
1144
1145         if (!PyArg_ParseTuple (args, "ss|b", &textMsg, &text, &max))
1146                 return EXPP_ReturnPyObjError (PyExc_TypeError,
1147                         "expected 2 strings and 1 int");
1148
1149         if ((max <= 0) || (max > 100))
1150                 return EXPP_ReturnPyObjError (PyExc_AttributeError,
1151                         "max string length value must be in the range [1, 100].");
1152
1153         /* copying the text string handles both cases:
1154          * max < strlen(text) (by truncating) and
1155          * max > strlen(text) (by expanding to strlen(tmp)) */
1156         BLI_strncpy(tmp, text, max);
1157
1158         if (sbutton (tmp, 0, max, textMsg) == 0) {
1159                 Py_INCREF (Py_None);
1160                 return Py_None;
1161         }
1162
1163         ret = Py_BuildValue ("s", tmp);
1164
1165         if (ret) return ret;
1166         
1167         return EXPP_ReturnPyObjError(PyExc_MemoryError, "couldn't create a PyString");
1168 }
1169
1170
1171 PyObject *Draw_Init (void)
1172 {
1173         PyObject *submodule, *dict;
1174
1175         Button_Type.ob_type = &PyType_Type;
1176
1177         submodule = Py_InitModule3 ("Blender.Draw", Draw_methods, Draw_doc);
1178
1179         dict = PyModule_GetDict (submodule);
1180
1181 #define EXPP_ADDCONST(x) \
1182         PyDict_SetItemString(dict, #x, PyInt_FromLong(x))
1183
1184         /* So, for example:
1185          * EXPP_ADDCONST(LEFTMOUSE) becomes
1186          * PyDict_SetItemString(dict, "LEFTMOUSE", PyInt_FromLong(LEFTMOUSE)) 
1187          */
1188
1189         EXPP_ADDCONST (LEFTMOUSE);
1190         EXPP_ADDCONST (MIDDLEMOUSE);
1191         EXPP_ADDCONST (RIGHTMOUSE);
1192         EXPP_ADDCONST (MOUSEX);
1193         EXPP_ADDCONST (MOUSEY);
1194         EXPP_ADDCONST (TIMER0);
1195         EXPP_ADDCONST (TIMER1);
1196         EXPP_ADDCONST (TIMER2);
1197         EXPP_ADDCONST (TIMER3);
1198         EXPP_ADDCONST (KEYBD);
1199         EXPP_ADDCONST (RAWKEYBD);
1200         EXPP_ADDCONST (REDRAW);
1201         EXPP_ADDCONST (INPUTCHANGE);
1202         EXPP_ADDCONST (QFULL);
1203         EXPP_ADDCONST (WINFREEZE);
1204         EXPP_ADDCONST (WINTHAW);
1205         EXPP_ADDCONST (WINCLOSE);
1206         EXPP_ADDCONST (WINQUIT);
1207 #ifndef IRISGL
1208         EXPP_ADDCONST (Q_FIRSTTIME);
1209 #endif
1210         EXPP_ADDCONST (AKEY);
1211         EXPP_ADDCONST (BKEY);
1212         EXPP_ADDCONST (CKEY);
1213         EXPP_ADDCONST (DKEY);
1214         EXPP_ADDCONST (EKEY);
1215         EXPP_ADDCONST (FKEY);
1216         EXPP_ADDCONST (GKEY);
1217         EXPP_ADDCONST (HKEY);
1218         EXPP_ADDCONST (IKEY);
1219         EXPP_ADDCONST (JKEY);
1220         EXPP_ADDCONST (KKEY);
1221         EXPP_ADDCONST (LKEY);
1222         EXPP_ADDCONST (MKEY);
1223         EXPP_ADDCONST (NKEY);
1224         EXPP_ADDCONST (OKEY);
1225         EXPP_ADDCONST (PKEY);
1226         EXPP_ADDCONST (QKEY);
1227         EXPP_ADDCONST (RKEY);
1228         EXPP_ADDCONST (SKEY);
1229         EXPP_ADDCONST (TKEY);
1230         EXPP_ADDCONST (UKEY);
1231         EXPP_ADDCONST (VKEY);
1232         EXPP_ADDCONST (WKEY);
1233         EXPP_ADDCONST (XKEY);
1234         EXPP_ADDCONST (YKEY);
1235         EXPP_ADDCONST (ZKEY);
1236         EXPP_ADDCONST (ZEROKEY);
1237         EXPP_ADDCONST (ONEKEY);
1238         EXPP_ADDCONST (TWOKEY);
1239         EXPP_ADDCONST (THREEKEY);
1240         EXPP_ADDCONST (FOURKEY);
1241         EXPP_ADDCONST (FIVEKEY);
1242         EXPP_ADDCONST (SIXKEY);
1243         EXPP_ADDCONST (SEVENKEY);
1244         EXPP_ADDCONST (EIGHTKEY);
1245         EXPP_ADDCONST (NINEKEY);
1246         EXPP_ADDCONST (CAPSLOCKKEY);
1247         EXPP_ADDCONST (LEFTCTRLKEY);
1248         EXPP_ADDCONST (LEFTALTKEY);
1249         EXPP_ADDCONST (RIGHTALTKEY);
1250         EXPP_ADDCONST (RIGHTCTRLKEY);
1251         EXPP_ADDCONST (RIGHTSHIFTKEY);
1252         EXPP_ADDCONST (LEFTSHIFTKEY);
1253         EXPP_ADDCONST (ESCKEY);
1254         EXPP_ADDCONST (TABKEY);
1255         EXPP_ADDCONST (RETKEY);
1256         EXPP_ADDCONST (SPACEKEY);
1257         EXPP_ADDCONST (LINEFEEDKEY);
1258         EXPP_ADDCONST (BACKSPACEKEY);
1259         EXPP_ADDCONST (DELKEY);
1260         EXPP_ADDCONST (SEMICOLONKEY);
1261         EXPP_ADDCONST (PERIODKEY);
1262         EXPP_ADDCONST (COMMAKEY);
1263         EXPP_ADDCONST (QUOTEKEY);
1264         EXPP_ADDCONST (ACCENTGRAVEKEY);
1265         EXPP_ADDCONST (MINUSKEY);
1266         EXPP_ADDCONST (SLASHKEY);
1267         EXPP_ADDCONST (BACKSLASHKEY);
1268         EXPP_ADDCONST (EQUALKEY);
1269         EXPP_ADDCONST (LEFTBRACKETKEY);
1270         EXPP_ADDCONST (RIGHTBRACKETKEY);
1271         EXPP_ADDCONST (LEFTARROWKEY);
1272         EXPP_ADDCONST (DOWNARROWKEY);
1273         EXPP_ADDCONST (RIGHTARROWKEY);
1274         EXPP_ADDCONST (UPARROWKEY);
1275         EXPP_ADDCONST (PAD2);
1276         EXPP_ADDCONST (PAD4);
1277         EXPP_ADDCONST (PAD6);
1278         EXPP_ADDCONST (PAD8);
1279         EXPP_ADDCONST (PAD1);
1280         EXPP_ADDCONST (PAD3);
1281         EXPP_ADDCONST (PAD5);
1282         EXPP_ADDCONST (PAD7);
1283         EXPP_ADDCONST (PAD9);
1284         EXPP_ADDCONST (PADPERIOD);
1285         EXPP_ADDCONST (PADSLASHKEY);
1286         EXPP_ADDCONST (PADASTERKEY);
1287         EXPP_ADDCONST (PAD0);
1288         EXPP_ADDCONST (PADMINUS);
1289         EXPP_ADDCONST (PADENTER);
1290         EXPP_ADDCONST (PADPLUSKEY);
1291         EXPP_ADDCONST (F1KEY);
1292         EXPP_ADDCONST (F2KEY);
1293         EXPP_ADDCONST (F3KEY);
1294         EXPP_ADDCONST (F4KEY);
1295         EXPP_ADDCONST (F5KEY);
1296         EXPP_ADDCONST (F6KEY);
1297         EXPP_ADDCONST (F7KEY);
1298         EXPP_ADDCONST (F8KEY);
1299         EXPP_ADDCONST (F9KEY);
1300         EXPP_ADDCONST (F10KEY);
1301         EXPP_ADDCONST (F11KEY);
1302         EXPP_ADDCONST (F12KEY);
1303         EXPP_ADDCONST (PAUSEKEY);
1304         EXPP_ADDCONST (INSERTKEY);
1305         EXPP_ADDCONST (HOMEKEY);
1306         EXPP_ADDCONST (PAGEUPKEY);
1307         EXPP_ADDCONST (PAGEDOWNKEY);
1308         EXPP_ADDCONST (ENDKEY);
1309
1310         return submodule;
1311 }