1 /*
2  *   This is a curses module for Python.
3  *
4  *   Based on prior work by Lance Ellinghaus and Oliver Andrich
5  *   Version 1.2 of this module: Copyright 1994 by Lance Ellinghouse,
6  *    Cathedral City, California Republic, United States of America.
7  *
8  *   Version 1.5b1, heavily extended for ncurses by Oliver Andrich:
9  *   Copyright 1996,1997 by Oliver Andrich, Koblenz, Germany.
10  *
11  *   Tidied for Python 1.6, and currently maintained by <[email protected]>.
12  *
13  *   Permission is hereby granted, free of charge, to any person obtaining
14  *   a copy of this source file to use, copy, modify, merge, or publish it
15  *   subject to the following conditions:
16  *
17  *   The above copyright notice and this permission notice shall be included
18  *   in all copies or in any new file that contains a substantial portion of
19  *   this file.
20  *
21  *   THE  AUTHOR  MAKES  NO  REPRESENTATIONS ABOUT  THE  SUITABILITY  OF
22  *   THE  SOFTWARE FOR  ANY  PURPOSE.  IT IS  PROVIDED  "AS IS"  WITHOUT
23  *   EXPRESS OR  IMPLIED WARRANTY.  THE AUTHOR DISCLAIMS  ALL WARRANTIES
24  *   WITH  REGARD TO  THIS  SOFTWARE, INCLUDING  ALL IMPLIED  WARRANTIES
25  *   OF   MERCHANTABILITY,  FITNESS   FOR  A   PARTICULAR  PURPOSE   AND
26  *   NON-INFRINGEMENT  OF THIRD  PARTY  RIGHTS. IN  NO  EVENT SHALL  THE
27  *   AUTHOR  BE LIABLE  TO  YOU  OR ANY  OTHER  PARTY  FOR ANY  SPECIAL,
28  *   INDIRECT,  OR  CONSEQUENTIAL  DAMAGES  OR  ANY  DAMAGES  WHATSOEVER
29  *   WHETHER IN AN  ACTION OF CONTRACT, NEGLIGENCE,  STRICT LIABILITY OR
30  *   ANY OTHER  ACTION ARISING OUT OF  OR IN CONNECTION WITH  THE USE OR
31  *   PERFORMANCE OF THIS SOFTWARE.
32  */
33 
34 /*
35 
36   A number of SysV or ncurses functions don't have wrappers yet; if you
37   need a given function, add it and send a patch.  See
38   http://www.python.org/dev/patches/ for instructions on how to submit
39   patches to Python.
40 
41   Here's a list of currently unsupported functions:
42 
43   addchnstr addchstr color_set define_key
44   del_curterm delscreen dupwin inchnstr inchstr innstr keyok
45   mcprint mvaddchnstr mvaddchstr mvcur mvinchnstr
46   mvinchstr mvinnstr mmvwaddchnstr mvwaddchstr
47   mvwinchnstr mvwinchstr mvwinnstr newterm
48   restartterm ripoffline scr_dump
49   scr_init scr_restore scr_set scrl set_curterm set_term setterm
50   tgetent tgetflag tgetnum tgetstr tgoto timeout tputs
51   vidattr vidputs waddchnstr waddchstr
52   wcolor_set winchnstr winchstr winnstr wmouse_trafo wscrl
53 
54   Low-priority:
55   slk_attr slk_attr_off slk_attr_on slk_attr_set slk_attroff
56   slk_attron slk_attrset slk_clear slk_color slk_init slk_label
57   slk_noutrefresh slk_refresh slk_restore slk_set slk_touch
58 
59   Menu extension (ncurses and probably SYSV):
60   current_item free_item free_menu item_count item_description
61   item_index item_init item_name item_opts item_opts_off
62   item_opts_on item_term item_userptr item_value item_visible
63   menu_back menu_driver menu_fore menu_format menu_grey
64   menu_init menu_items menu_mark menu_opts menu_opts_off
65   menu_opts_on menu_pad menu_pattern menu_request_by_name
66   menu_request_name menu_spacing menu_sub menu_term menu_userptr
67   menu_win new_item new_menu pos_menu_cursor post_menu
68   scale_menu set_current_item set_item_init set_item_opts
69   set_item_term set_item_userptr set_item_value set_menu_back
70   set_menu_fore set_menu_format set_menu_grey set_menu_init
71   set_menu_items set_menu_mark set_menu_opts set_menu_pad
72   set_menu_pattern set_menu_spacing set_menu_sub set_menu_term
73   set_menu_userptr set_menu_win set_top_row top_row unpost_menu
74 
75   Form extension (ncurses and probably SYSV):
76   current_field data_ahead data_behind dup_field
77   dynamic_fieldinfo field_arg field_back field_buffer
78   field_count field_fore field_index field_info field_init
79   field_just field_opts field_opts_off field_opts_on field_pad
80   field_status field_term field_type field_userptr form_driver
81   form_fields form_init form_opts form_opts_off form_opts_on
82   form_page form_request_by_name form_request_name form_sub
83   form_term form_userptr form_win free_field free_form
84   link_field link_fieldtype move_field new_field new_form
85   new_page pos_form_cursor post_form scale_form
86   set_current_field set_field_back set_field_buffer
87   set_field_fore set_field_init set_field_just set_field_opts
88   set_field_pad set_field_status set_field_term set_field_type
89   set_field_userptr set_fieldtype_arg set_fieldtype_choice
90   set_form_fields set_form_init set_form_opts set_form_page
91   set_form_sub set_form_term set_form_userptr set_form_win
92   set_max_field set_new_page unpost_form
93 
94 
95 */
96 
97 /* Release Number */
98 
99 char *PyCursesVersion = "2.2";
100 
101 /* Includes */
102 
103 #include "Python.h"
104 
105 #ifdef __osf__
106 #define STRICT_SYSV_CURSES      /* Don't use ncurses extensions */
107 #endif
108 
109 #ifdef __hpux
110 #define STRICT_SYSV_CURSES
111 #endif
112 
113 #define CURSES_MODULE
114 #include "py_curses.h"
115 
116 #if defined(HAVE_TERM_H) || defined(__sgi)
117 /* For termname, longname, putp, tigetflag, tigetnum, tigetstr, tparm
118    which are not declared in SysV curses and for setupterm. */
119 #include <term.h>
120 /* Including <term.h> #defines many common symbols. */
121 #undef lines
122 #undef columns
123 #endif
124 
125 #if !defined(HAVE_NCURSES_H) && (defined(sgi) || defined(__sun) || defined(SCO5))
126 #define STRICT_SYSV_CURSES       /* Don't use ncurses extensions */
127 typedef chtype attr_t;           /* No attr_t type is available */
128 #endif
129 
130 #if defined(_AIX)
131 #define STRICT_SYSV_CURSES
132 #endif
133 
134 /* Definition of exception curses.error */
135 
136 static PyObject *PyCursesError;
137 
138 /* Tells whether setupterm() has been called to initialise terminfo.  */
139 static int initialised_setupterm = FALSE;
140 
141 /* Tells whether initscr() has been called to initialise curses.  */
142 static int initialised = FALSE;
143 
144 /* Tells whether start_color() has been called to initialise color usage. */
145 static int initialisedcolors = FALSE;
146 
147 /* Utility Macros */
148 #define PyCursesSetupTermCalled                                         \
149     if (initialised_setupterm != TRUE) {                                \
150         PyErr_SetString(PyCursesError,                                  \
151                         "must call (at least) setupterm() first");      \
152         return 0; }
153 
154 #define PyCursesInitialised                             \
155     if (initialised != TRUE) {                          \
156         PyErr_SetString(PyCursesError,                  \
157                         "must call initscr() first");   \
158         return 0; }
159 
160 #define PyCursesInitialisedColor                                \
161     if (initialisedcolors != TRUE) {                            \
162         PyErr_SetString(PyCursesError,                          \
163                         "must call start_color() first");       \
164         return 0; }
165 
166 #ifndef MIN
167 #define MIN(x,y) ((x) < (y) ? (x) : (y))
168 #endif
169 
170 /* Utility Functions */
171 
172 /*
173  * Check the return code from a curses function and return None
174  * or raise an exception as appropriate.  These are exported using the
175  * capsule API.
176  */
177 
178 static PyObject *
PyCursesCheckERR(int code,char * fname)179 PyCursesCheckERR(int code, char *fname)
180 {
181     if (code != ERR) {
182         Py_INCREF(Py_None);
183         return Py_None;
184     } else {
185         if (fname == NULL) {
186             PyErr_SetString(PyCursesError, catchall_ERR);
187         } else {
188             PyErr_Format(PyCursesError, "%s() returned ERR", fname);
189         }
190         return NULL;
191     }
192 }
193 
194 static int
PyCurses_ConvertToChtype(PyObject * obj,chtype * ch)195 PyCurses_ConvertToChtype(PyObject *obj, chtype *ch)
196 {
197     if (_PyAnyInt_Check(obj)) {
198         *ch = (chtype) PyInt_AsLong(obj);
199         if (*ch == (chtype) -1 && PyErr_Occurred())
200             return 0;
201     } else if(PyString_Check(obj)
202               && (PyString_Size(obj) == 1)) {
203         *ch = (chtype) *PyString_AsString(obj);
204     } else {
205         return 0;
206     }
207     return 1;
208 }
209 
210 /* Function versions of the 3 functions for testing whether curses has been
211    initialised or not. */
212 
func_PyCursesSetupTermCalled(void)213 static int func_PyCursesSetupTermCalled(void)
214 {
215     PyCursesSetupTermCalled;
216     return 1;
217 }
218 
func_PyCursesInitialised(void)219 static int func_PyCursesInitialised(void)
220 {
221     PyCursesInitialised;
222     return 1;
223 }
224 
func_PyCursesInitialisedColor(void)225 static int func_PyCursesInitialisedColor(void)
226 {
227     PyCursesInitialisedColor;
228     return 1;
229 }
230 
231 /*****************************************************************************
232  The Window Object
233 ******************************************************************************/
234 
235 /* Definition of the window type */
236 
237 PyTypeObject PyCursesWindow_Type;
238 
239 /* Function prototype macros for Window object
240 
241    X - function name
242    TYPE - parameter Type
243    ERGSTR - format string for construction of the return value
244    PARSESTR - format string for argument parsing
245 */
246 
247 #define Window_NoArgNoReturnFunction(X)                 \
248     static PyObject *PyCursesWindow_ ## X               \
249     (PyCursesWindowObject *self, PyObject *args)        \
250     { return PyCursesCheckERR(X(self->win), # X); }
251 
252 #define Window_NoArgTrueFalseFunction(X)                                \
253     static PyObject * PyCursesWindow_ ## X                              \
254     (PyCursesWindowObject *self)                                        \
255     {                                                                   \
256         if (X (self->win) == FALSE) { Py_INCREF(Py_False); return Py_False; } \
257         else { Py_INCREF(Py_True); return Py_True; } }
258 
259 #define Window_NoArgNoReturnVoidFunction(X)                     \
260     static PyObject * PyCursesWindow_ ## X                      \
261     (PyCursesWindowObject *self)                                \
262     {                                                           \
263         X(self->win); Py_INCREF(Py_None); return Py_None; }
264 
265 #define Window_NoArg2TupleReturnFunction(X, TYPE, ERGSTR)               \
266     static PyObject * PyCursesWindow_ ## X                              \
267     (PyCursesWindowObject *self)                                        \
268     {                                                                   \
269         TYPE arg1, arg2;                                                \
270         X(self->win,arg1,arg2); return Py_BuildValue(ERGSTR, arg1, arg2); }
271 
272 #define Window_OneArgNoReturnVoidFunction(X, TYPE, PARSESTR)            \
273     static PyObject * PyCursesWindow_ ## X                              \
274     (PyCursesWindowObject *self, PyObject *args)                        \
275     {                                                                   \
276         TYPE arg1;                                                      \
277         if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) return NULL;      \
278         X(self->win,arg1); Py_INCREF(Py_None); return Py_None; }
279 
280 #define Window_OneArgNoReturnFunction(X, TYPE, PARSESTR)                \
281     static PyObject * PyCursesWindow_ ## X                              \
282     (PyCursesWindowObject *self, PyObject *args)                        \
283     {                                                                   \
284         TYPE arg1;                                                      \
285         if (!PyArg_ParseTuple(args,PARSESTR, &arg1)) return NULL;       \
286         return PyCursesCheckERR(X(self->win, arg1), # X); }
287 
288 #define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR)                \
289     static PyObject * PyCursesWindow_ ## X                              \
290     (PyCursesWindowObject *self, PyObject *args)                        \
291     {                                                                   \
292         TYPE arg1, arg2;                                                \
293         if (!PyArg_ParseTuple(args,PARSESTR, &arg1, &arg2)) return NULL; \
294         return PyCursesCheckERR(X(self->win, arg1, arg2), # X); }
295 
296 /* ------------- WINDOW routines --------------- */
297 
298 Window_NoArgNoReturnFunction(untouchwin)
Window_NoArgNoReturnFunction(touchwin)299 Window_NoArgNoReturnFunction(touchwin)
300 Window_NoArgNoReturnFunction(redrawwin)
301 Window_NoArgNoReturnFunction(winsertln)
302 Window_NoArgNoReturnFunction(werase)
303 Window_NoArgNoReturnFunction(wdeleteln)
304 
305 Window_NoArgTrueFalseFunction(is_wintouched)
306 
307 Window_NoArgNoReturnVoidFunction(wsyncup)
308 Window_NoArgNoReturnVoidFunction(wsyncdown)
309 Window_NoArgNoReturnVoidFunction(wstandend)
310 Window_NoArgNoReturnVoidFunction(wstandout)
311 Window_NoArgNoReturnVoidFunction(wcursyncup)
312 Window_NoArgNoReturnVoidFunction(wclrtoeol)
313 Window_NoArgNoReturnVoidFunction(wclrtobot)
314 Window_NoArgNoReturnVoidFunction(wclear)
315 
316 Window_OneArgNoReturnVoidFunction(idcok, int, "i;True(1) or False(0)")
317 #ifdef HAVE_CURSES_IMMEDOK
318 Window_OneArgNoReturnVoidFunction(immedok, int, "i;True(1) or False(0)")
319 #endif
320 Window_OneArgNoReturnVoidFunction(wtimeout, int, "i;delay")
321 
322 Window_NoArg2TupleReturnFunction(getyx, int, "ii")
323 Window_NoArg2TupleReturnFunction(getbegyx, int, "ii")
324 Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii")
325 Window_NoArg2TupleReturnFunction(getparyx, int, "ii")
326 
327 Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)")
328 Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)")
329 Window_OneArgNoReturnFunction(keypad, int, "i;True(1) or False(0)")
330 Window_OneArgNoReturnFunction(leaveok, int, "i;True(1) or False(0)")
331 Window_OneArgNoReturnFunction(nodelay, int, "i;True(1) or False(0)")
332 Window_OneArgNoReturnFunction(notimeout, int, "i;True(1) or False(0)")
333 Window_OneArgNoReturnFunction(scrollok, int, "i;True(1) or False(0)")
334 Window_OneArgNoReturnFunction(winsdelln, int, "i;nlines")
335 #ifdef HAVE_CURSES_SYNCOK
336 Window_OneArgNoReturnFunction(syncok, int, "i;True(1) or False(0)")
337 #endif
338 
339 Window_TwoArgNoReturnFunction(mvwin, int, "ii;y,x")
340 Window_TwoArgNoReturnFunction(mvderwin, int, "ii;y,x")
341 Window_TwoArgNoReturnFunction(wmove, int, "ii;y,x")
342 #ifndef STRICT_SYSV_CURSES
343 Window_TwoArgNoReturnFunction(wresize, int, "ii;lines,columns")
344 #endif
345 
346 /* Allocation and deallocation of Window Objects */
347 
348 static PyObject *
349 PyCursesWindow_New(WINDOW *win)
350 {
351     PyCursesWindowObject *wo;
352 
353     wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
354     if (wo == NULL) return NULL;
355     wo->win = win;
356     return (PyObject *)wo;
357 }
358 
359 static void
PyCursesWindow_Dealloc(PyCursesWindowObject * wo)360 PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
361 {
362     if (wo->win != stdscr) delwin(wo->win);
363     PyObject_DEL(wo);
364 }
365 
366 /* Addch, Addstr, Addnstr */
367 
368 static PyObject *
PyCursesWindow_AddCh(PyCursesWindowObject * self,PyObject * args)369 PyCursesWindow_AddCh(PyCursesWindowObject *self, PyObject *args)
370 {
371     int rtn, x, y, use_xy = FALSE;
372     PyObject *temp;
373     chtype ch = 0;
374     attr_t attr = A_NORMAL;
375     long lattr;
376 
377     switch (PyTuple_Size(args)) {
378     case 1:
379         if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
380             return NULL;
381         break;
382     case 2:
383         if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &lattr))
384             return NULL;
385         attr = lattr;
386         break;
387     case 3:
388         if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp))
389             return NULL;
390         use_xy = TRUE;
391         break;
392     case 4:
393         if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr",
394                               &y, &x, &temp, &lattr))
395             return NULL;
396         attr = lattr;
397         use_xy = TRUE;
398         break;
399     default:
400         PyErr_SetString(PyExc_TypeError, "addch requires 1 to 4 arguments");
401         return NULL;
402     }
403 
404     if (!PyCurses_ConvertToChtype(temp, &ch)) {
405         PyErr_SetString(PyExc_TypeError, "argument 1 or 3 must be a ch or an int");
406         return NULL;
407     }
408 
409     if (use_xy == TRUE)
410         rtn = mvwaddch(self->win,y,x, ch | attr);
411     else {
412         rtn = waddch(self->win, ch | attr);
413     }
414     return PyCursesCheckERR(rtn, "addch");
415 }
416 
417 static PyObject *
PyCursesWindow_AddStr(PyCursesWindowObject * self,PyObject * args)418 PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args)
419 {
420     int rtn;
421     int x, y;
422     char *str;
423     attr_t attr = A_NORMAL , attr_old = A_NORMAL;
424     long lattr;
425     int use_xy = FALSE, use_attr = FALSE;
426 
427     switch (PyTuple_Size(args)) {
428     case 1:
429         if (!PyArg_ParseTuple(args,"s;str", &str))
430             return NULL;
431         break;
432     case 2:
433         if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &lattr))
434             return NULL;
435         attr = lattr;
436         use_attr = TRUE;
437         break;
438     case 3:
439         if (!PyArg_ParseTuple(args,"iis;int,int,str", &y, &x, &str))
440             return NULL;
441         use_xy = TRUE;
442         break;
443     case 4:
444         if (!PyArg_ParseTuple(args,"iisl;int,int,str,attr", &y, &x, &str, &lattr))
445             return NULL;
446         attr = lattr;
447         use_xy = use_attr = TRUE;
448         break;
449     default:
450         PyErr_SetString(PyExc_TypeError, "addstr requires 1 to 4 arguments");
451         return NULL;
452     }
453 
454     if (use_attr == TRUE) {
455         attr_old = getattrs(self->win);
456         (void)wattrset(self->win,attr);
457     }
458     if (use_xy == TRUE)
459         rtn = mvwaddstr(self->win,y,x,str);
460     else
461         rtn = waddstr(self->win,str);
462     if (use_attr == TRUE)
463         (void)wattrset(self->win,attr_old);
464     return PyCursesCheckERR(rtn, "addstr");
465 }
466 
467 static PyObject *
PyCursesWindow_AddNStr(PyCursesWindowObject * self,PyObject * args)468 PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args)
469 {
470     int rtn, x, y, n;
471     char *str;
472     attr_t attr = A_NORMAL , attr_old = A_NORMAL;
473     long lattr;
474     int use_xy = FALSE, use_attr = FALSE;
475 
476     switch (PyTuple_Size(args)) {
477     case 2:
478         if (!PyArg_ParseTuple(args,"si;str,n", &str, &n))
479             return NULL;
480         break;
481     case 3:
482         if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &lattr))
483             return NULL;
484         attr = lattr;
485         use_attr = TRUE;
486         break;
487     case 4:
488         if (!PyArg_ParseTuple(args,"iisi;y,x,str,n", &y, &x, &str, &n))
489             return NULL;
490         use_xy = TRUE;
491         break;
492     case 5:
493         if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &lattr))
494             return NULL;
495         attr = lattr;
496         use_xy = use_attr = TRUE;
497         break;
498     default:
499         PyErr_SetString(PyExc_TypeError, "addnstr requires 2 to 5 arguments");
500         return NULL;
501     }
502 
503     if (use_attr == TRUE) {
504         attr_old = getattrs(self->win);
505         (void)wattrset(self->win,attr);
506     }
507     if (use_xy == TRUE)
508         rtn = mvwaddnstr(self->win,y,x,str,n);
509     else
510         rtn = waddnstr(self->win,str,n);
511     if (use_attr == TRUE)
512         (void)wattrset(self->win,attr_old);
513     return PyCursesCheckERR(rtn, "addnstr");
514 }
515 
516 static PyObject *
PyCursesWindow_Bkgd(PyCursesWindowObject * self,PyObject * args)517 PyCursesWindow_Bkgd(PyCursesWindowObject *self, PyObject *args)
518 {
519     PyObject *temp;
520     chtype bkgd;
521     attr_t attr = A_NORMAL;
522     long lattr;
523 
524     switch (PyTuple_Size(args)) {
525     case 1:
526         if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
527             return NULL;
528         break;
529     case 2:
530         if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr))
531             return NULL;
532         attr = lattr;
533         break;
534     default:
535         PyErr_SetString(PyExc_TypeError, "bkgd requires 1 or 2 arguments");
536         return NULL;
537     }
538 
539     if (!PyCurses_ConvertToChtype(temp, &bkgd)) {
540         PyErr_SetString(PyExc_TypeError, "argument 1 or 3 must be a ch or an int");
541         return NULL;
542     }
543 
544     return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd");
545 }
546 
547 static PyObject *
PyCursesWindow_AttrOff(PyCursesWindowObject * self,PyObject * args)548 PyCursesWindow_AttrOff(PyCursesWindowObject *self, PyObject *args)
549 {
550     long lattr;
551     if (!PyArg_ParseTuple(args,"l;attr", &lattr))
552         return NULL;
553     return PyCursesCheckERR(wattroff(self->win, (attr_t)lattr), "attroff");
554 }
555 
556 static PyObject *
PyCursesWindow_AttrOn(PyCursesWindowObject * self,PyObject * args)557 PyCursesWindow_AttrOn(PyCursesWindowObject *self, PyObject *args)
558 {
559     long lattr;
560     if (!PyArg_ParseTuple(args,"l;attr", &lattr))
561         return NULL;
562     return PyCursesCheckERR(wattron(self->win, (attr_t)lattr), "attron");
563 }
564 
565 static PyObject *
PyCursesWindow_AttrSet(PyCursesWindowObject * self,PyObject * args)566 PyCursesWindow_AttrSet(PyCursesWindowObject *self, PyObject *args)
567 {
568     long lattr;
569     if (!PyArg_ParseTuple(args,"l;attr", &lattr))
570         return NULL;
571     return PyCursesCheckERR(wattrset(self->win, (attr_t)lattr), "attrset");
572 }
573 
574 static PyObject *
PyCursesWindow_BkgdSet(PyCursesWindowObject * self,PyObject * args)575 PyCursesWindow_BkgdSet(PyCursesWindowObject *self, PyObject *args)
576 {
577     PyObject *temp;
578     chtype bkgd;
579     attr_t attr = A_NORMAL;
580     long lattr;
581 
582     switch (PyTuple_Size(args)) {
583     case 1:
584         if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
585             return NULL;
586         break;
587     case 2:
588         if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr))
589             return NULL;
590         attr = lattr;
591         break;
592     default:
593         PyErr_SetString(PyExc_TypeError, "bkgdset requires 1 or 2 arguments");
594         return NULL;
595     }
596 
597     if (!PyCurses_ConvertToChtype(temp, &bkgd)) {
598         PyErr_SetString(PyExc_TypeError, "argument 1 must be a ch or an int");
599         return NULL;
600     }
601 
602     wbkgdset(self->win, bkgd | attr);
603     return PyCursesCheckERR(0, "bkgdset");
604 }
605 
606 static PyObject *
PyCursesWindow_Border(PyCursesWindowObject * self,PyObject * args)607 PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args)
608 {
609     PyObject *temp[8];
610     chtype ch[8];
611     int i;
612 
613     /* Clear the array of parameters */
614     for(i=0; i<8; i++) {
615         temp[i] = NULL;
616         ch[i] = 0;
617     }
618 
619     if (!PyArg_ParseTuple(args,"|OOOOOOOO;ls,rs,ts,bs,tl,tr,bl,br",
620                           &temp[0], &temp[1], &temp[2], &temp[3],
621                           &temp[4], &temp[5], &temp[6], &temp[7]))
622         return NULL;
623 
624     for(i=0; i<8; i++) {
625         if (temp[i] != NULL && !PyCurses_ConvertToChtype(temp[i], &ch[i])) {
626             PyErr_Format(PyExc_TypeError,
627                          "argument %i must be a ch or an int", i+1);
628             return NULL;
629         }
630     }
631 
632     wborder(self->win,
633             ch[0], ch[1], ch[2], ch[3],
634             ch[4], ch[5], ch[6], ch[7]);
635     Py_INCREF(Py_None);
636     return Py_None;
637 }
638 
639 static PyObject *
PyCursesWindow_Box(PyCursesWindowObject * self,PyObject * args)640 PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args)
641 {
642     PyObject *temp1, *temp2;
643     chtype ch1=0,ch2=0;
644     switch(PyTuple_Size(args)){
645     case 0: break;
646     default:
647         if (!PyArg_ParseTuple(args,"OO;verch,horch", &temp1, &temp2))
648             return NULL;
649         if (!PyCurses_ConvertToChtype(temp1, &ch1)) {
650             return NULL;
651         }
652         if (!PyCurses_ConvertToChtype(temp2, &ch2)) {
653             return NULL;
654         }
655     }
656     box(self->win,ch1,ch2);
657     Py_INCREF(Py_None);
658     return Py_None;
659 }
660 
661 #if defined(HAVE_NCURSES_H) || defined(MVWDELCH_IS_EXPRESSION)
662 #define py_mvwdelch mvwdelch
663 #else
py_mvwdelch(WINDOW * w,int y,int x)664 int py_mvwdelch(WINDOW *w, int y, int x)
665 {
666     mvwdelch(w,y,x);
667     /* On HP/UX, mvwdelch already returns. On other systems,
668        we may well run into this return statement. */
669     return 0;
670 }
671 #endif
672 
673 #if defined(HAVE_CURSES_IS_PAD)
674 #define py_is_pad(win)      is_pad(win)
675 #elif defined(WINDOW_HAS_FLAGS)
676 #define py_is_pad(win)      ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE)
677 #endif
678 
679 /* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */
680 #ifdef HAVE_CURSES_WCHGAT
681 static PyObject *
PyCursesWindow_ChgAt(PyCursesWindowObject * self,PyObject * args)682 PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args)
683 {
684     int rtn;
685     int x, y;
686     int num = -1;
687     short color;
688     attr_t attr = A_NORMAL;
689     long lattr;
690     int use_xy = FALSE;
691 
692     switch (PyTuple_Size(args)) {
693     case 1:
694         if (!PyArg_ParseTuple(args,"l;attr", &lattr))
695             return NULL;
696         attr = lattr;
697         break;
698     case 2:
699         if (!PyArg_ParseTuple(args,"il;n,attr", &num, &lattr))
700             return NULL;
701         attr = lattr;
702         break;
703     case 3:
704         if (!PyArg_ParseTuple(args,"iil;int,int,attr", &y, &x, &lattr))
705             return NULL;
706         attr = lattr;
707         use_xy = TRUE;
708         break;
709     case 4:
710         if (!PyArg_ParseTuple(args,"iiil;int,int,n,attr", &y, &x, &num, &lattr))
711             return NULL;
712         attr = lattr;
713         use_xy = TRUE;
714         break;
715     default:
716         PyErr_SetString(PyExc_TypeError, "chgat requires 1 to 4 arguments");
717         return NULL;
718     }
719 
720     color = (short)((attr >> 8) & 0xff);
721     attr = attr - (color << 8);
722 
723     if (use_xy == TRUE) {
724         rtn = mvwchgat(self->win,y,x,num,attr,color,NULL);
725         touchline(self->win,y,1);
726     } else {
727         getyx(self->win,y,x);
728         rtn = wchgat(self->win,num,attr,color,NULL);
729         touchline(self->win,y,1);
730     }
731     return PyCursesCheckERR(rtn, "chgat");
732 }
733 #endif
734 
735 static PyObject *
PyCursesWindow_DelCh(PyCursesWindowObject * self,PyObject * args)736 PyCursesWindow_DelCh(PyCursesWindowObject *self, PyObject *args)
737 {
738     int rtn;
739     int x, y;
740 
741     switch (PyTuple_Size(args)) {
742     case 0:
743         rtn = wdelch(self->win);
744         break;
745     case 2:
746         if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x))
747             return NULL;
748         rtn = py_mvwdelch(self->win,y,x);
749         break;
750     default:
751         PyErr_SetString(PyExc_TypeError, "delch requires 0 or 2 arguments");
752         return NULL;
753     }
754     return PyCursesCheckERR(rtn, "[mv]wdelch");
755 }
756 
757 static PyObject *
PyCursesWindow_DerWin(PyCursesWindowObject * self,PyObject * args)758 PyCursesWindow_DerWin(PyCursesWindowObject *self, PyObject *args)
759 {
760     WINDOW *win;
761     int nlines, ncols, begin_y, begin_x;
762 
763     nlines = 0;
764     ncols  = 0;
765     switch (PyTuple_Size(args)) {
766     case 2:
767         if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x))
768             return NULL;
769         break;
770     case 4:
771         if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
772                               &nlines,&ncols,&begin_y,&begin_x))
773             return NULL;
774         break;
775     default:
776         PyErr_SetString(PyExc_TypeError, "derwin requires 2 or 4 arguments");
777         return NULL;
778     }
779 
780     win = derwin(self->win,nlines,ncols,begin_y,begin_x);
781 
782     if (win == NULL) {
783         PyErr_SetString(PyCursesError, catchall_NULL);
784         return NULL;
785     }
786 
787     return (PyObject *)PyCursesWindow_New(win);
788 }
789 
790 static PyObject *
PyCursesWindow_EchoChar(PyCursesWindowObject * self,PyObject * args)791 PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
792 {
793     PyObject *temp;
794     chtype ch;
795     attr_t attr = A_NORMAL;
796     long lattr;
797 
798     switch (PyTuple_Size(args)) {
799     case 1:
800         if (!PyArg_ParseTuple(args,"O;ch or int", &temp))
801             return NULL;
802         break;
803     case 2:
804         if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr))
805             return NULL;
806         attr = lattr;
807         break;
808     default:
809         PyErr_SetString(PyExc_TypeError, "echochar requires 1 or 2 arguments");
810 
811 
812         return NULL;
813     }
814 
815     if (!PyCurses_ConvertToChtype(temp, &ch)) {
816         PyErr_SetString(PyExc_TypeError, "argument 1 must be a ch or an int");
817         return NULL;
818     }
819 
820 #ifdef py_is_pad
821     if (py_is_pad(self->win)) {
822         return PyCursesCheckERR(pechochar(self->win, ch | attr),
823                                 "echochar");
824     }
825     else
826 #endif
827         return PyCursesCheckERR(wechochar(self->win, ch | attr),
828                                 "echochar");
829 }
830 
831 #ifdef NCURSES_MOUSE_VERSION
832 static PyObject *
PyCursesWindow_Enclose(PyCursesWindowObject * self,PyObject * args)833 PyCursesWindow_Enclose(PyCursesWindowObject *self, PyObject *args)
834 {
835     int x, y;
836     if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x))
837         return NULL;
838 
839     return PyInt_FromLong( wenclose(self->win,y,x) );
840 }
841 #endif
842 
843 static PyObject *
PyCursesWindow_GetBkgd(PyCursesWindowObject * self)844 PyCursesWindow_GetBkgd(PyCursesWindowObject *self)
845 {
846     return PyInt_FromLong((long) getbkgd(self->win));
847 }
848 
849 static PyObject *
PyCursesWindow_GetCh(PyCursesWindowObject * self,PyObject * args)850 PyCursesWindow_GetCh(PyCursesWindowObject *self, PyObject *args)
851 {
852     int x, y;
853     int rtn;
854 
855     switch (PyTuple_Size(args)) {
856     case 0:
857         Py_BEGIN_ALLOW_THREADS
858         rtn = wgetch(self->win);
859         Py_END_ALLOW_THREADS
860         break;
861     case 2:
862         if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
863             return NULL;
864         Py_BEGIN_ALLOW_THREADS
865         rtn = mvwgetch(self->win,y,x);
866         Py_END_ALLOW_THREADS
867         break;
868     default:
869         PyErr_SetString(PyExc_TypeError, "getch requires 0 or 2 arguments");
870         return NULL;
871     }
872     return PyInt_FromLong((long)rtn);
873 }
874 
875 static PyObject *
PyCursesWindow_GetKey(PyCursesWindowObject * self,PyObject * args)876 PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args)
877 {
878     int x, y;
879     int rtn;
880 
881     switch (PyTuple_Size(args)) {
882     case 0:
883         Py_BEGIN_ALLOW_THREADS
884         rtn = wgetch(self->win);
885         Py_END_ALLOW_THREADS
886         break;
887     case 2:
888         if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
889             return NULL;
890         Py_BEGIN_ALLOW_THREADS
891         rtn = mvwgetch(self->win,y,x);
892         Py_END_ALLOW_THREADS
893         break;
894     default:
895         PyErr_SetString(PyExc_TypeError, "getkey requires 0 or 2 arguments");
896         return NULL;
897     }
898     if (rtn == ERR) {
899         /* getch() returns ERR in nodelay mode */
900         PyErr_CheckSignals();
901         if (!PyErr_Occurred())
902             PyErr_SetString(PyCursesError, "no input");
903         return NULL;
904     } else if (rtn<=255) {
905         return Py_BuildValue("c", rtn);
906     } else {
907         const char *knp = keyname(rtn);
908         return PyString_FromString((knp == NULL) ? "" : knp);
909     }
910 }
911 
912 static PyObject *
PyCursesWindow_GetStr(PyCursesWindowObject * self,PyObject * args)913 PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args)
914 {
915     int x, y, n;
916     char rtn[1024]; /* This should be big enough.. I hope */
917     int rtn2;
918 
919     switch (PyTuple_Size(args)) {
920     case 0:
921         Py_BEGIN_ALLOW_THREADS
922         rtn2 = wgetnstr(self->win,rtn, 1023);
923         Py_END_ALLOW_THREADS
924         break;
925     case 1:
926         if (!PyArg_ParseTuple(args,"i;n", &n))
927             return NULL;
928         if (n < 0) {
929             PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
930             return NULL;
931         }
932         Py_BEGIN_ALLOW_THREADS
933         rtn2 = wgetnstr(self->win,rtn,MIN(n, 1023));
934         Py_END_ALLOW_THREADS
935         break;
936     case 2:
937         if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
938             return NULL;
939         Py_BEGIN_ALLOW_THREADS
940 #ifdef STRICT_SYSV_CURSES
941         rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023);
942 #else
943         rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023);
944 #endif
945         Py_END_ALLOW_THREADS
946         break;
947     case 3:
948         if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n))
949             return NULL;
950         if (n < 0) {
951             PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
952             return NULL;
953         }
954 #ifdef STRICT_SYSV_CURSES
955         Py_BEGIN_ALLOW_THREADS
956         rtn2 = wmove(self->win,y,x)==ERR ? ERR :
957         wgetnstr(self->win, rtn, MIN(n, 1023));
958         Py_END_ALLOW_THREADS
959 #else
960         Py_BEGIN_ALLOW_THREADS
961         rtn2 = mvwgetnstr(self->win, y, x, rtn, MIN(n, 1023));
962         Py_END_ALLOW_THREADS
963 #endif
964         break;
965     default:
966         PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 3 arguments");
967         return NULL;
968     }
969     if (rtn2 == ERR)
970         rtn[0] = 0;
971     return PyString_FromString(rtn);
972 }
973 
974 static PyObject *
PyCursesWindow_Hline(PyCursesWindowObject * self,PyObject * args)975 PyCursesWindow_Hline(PyCursesWindowObject *self, PyObject *args)
976 {
977     PyObject *temp;
978     chtype ch;
979     int n, x, y, code = OK;
980     attr_t attr = A_NORMAL;
981     long lattr;
982 
983     switch (PyTuple_Size(args)) {
984     case 2:
985         if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n))
986             return NULL;
987         break;
988     case 3:
989         if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr))
990             return NULL;
991         attr = lattr;
992         break;
993     case 4:
994         if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n))
995             return NULL;
996         code = wmove(self->win, y, x);
997         break;
998     case 5:
999         if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr",
1000                               &y, &x, &temp, &n, &lattr))
1001             return NULL;
1002         attr = lattr;
1003         code = wmove(self->win, y, x);
1004         break;
1005     default:
1006         PyErr_SetString(PyExc_TypeError, "hline requires 2 to 5 arguments");
1007         return NULL;
1008     }
1009 
1010     if (code != ERR) {
1011         if (!PyCurses_ConvertToChtype(temp, &ch)) {
1012             PyErr_SetString(PyExc_TypeError,
1013                             "argument 1 or 3 must be a ch or an int");
1014             return NULL;
1015         }
1016         return PyCursesCheckERR(whline(self->win, ch | attr, n), "hline");
1017     } else
1018         return PyCursesCheckERR(code, "wmove");
1019 }
1020 
1021 static PyObject *
PyCursesWindow_InsCh(PyCursesWindowObject * self,PyObject * args)1022 PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args)
1023 {
1024     int rtn, x, y, use_xy = FALSE;
1025     PyObject *temp;
1026     chtype ch = 0;
1027     attr_t attr = A_NORMAL;
1028     long lattr;
1029 
1030     switch (PyTuple_Size(args)) {
1031     case 1:
1032         if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
1033             return NULL;
1034         break;
1035     case 2:
1036         if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &lattr))
1037             return NULL;
1038         attr = lattr;
1039         break;
1040     case 3:
1041         if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp))
1042             return NULL;
1043         use_xy = TRUE;
1044         break;
1045     case 4:
1046         if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &lattr))
1047             return NULL;
1048         attr = lattr;
1049         use_xy = TRUE;
1050         break;
1051     default:
1052         PyErr_SetString(PyExc_TypeError, "insch requires 1 to 4 arguments");
1053         return NULL;
1054     }
1055 
1056     if (!PyCurses_ConvertToChtype(temp, &ch)) {
1057         PyErr_SetString(PyExc_TypeError,
1058                         "argument 1 or 3 must be a ch or an int");
1059         return NULL;
1060     }
1061 
1062     if (use_xy == TRUE)
1063         rtn = mvwinsch(self->win,y,x, ch | attr);
1064     else {
1065         rtn = winsch(self->win, ch | attr);
1066     }
1067     return PyCursesCheckERR(rtn, "insch");
1068 }
1069 
1070 static PyObject *
PyCursesWindow_InCh(PyCursesWindowObject * self,PyObject * args)1071 PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args)
1072 {
1073     int x, y, rtn;
1074 
1075     switch (PyTuple_Size(args)) {
1076     case 0:
1077         rtn = winch(self->win);
1078         break;
1079     case 2:
1080         if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1081             return NULL;
1082         rtn = mvwinch(self->win,y,x);
1083         break;
1084     default:
1085         PyErr_SetString(PyExc_TypeError, "inch requires 0 to 2 arguments");
1086         return NULL;
1087     }
1088     return PyInt_FromLong((long) rtn);
1089 }
1090 
1091 static PyObject *
PyCursesWindow_InStr(PyCursesWindowObject * self,PyObject * args)1092 PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args)
1093 {
1094     int x, y, n;
1095     char rtn[1024]; /* This should be big enough.. I hope */
1096     int rtn2;
1097 
1098     switch (PyTuple_Size(args)) {
1099     case 0:
1100         rtn2 = winnstr(self->win,rtn, 1023);
1101         break;
1102     case 1:
1103         if (!PyArg_ParseTuple(args,"i;n", &n))
1104             return NULL;
1105         if (n < 0) {
1106             PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1107             return NULL;
1108         }
1109         rtn2 = winnstr(self->win,rtn,MIN(n,1023));
1110         break;
1111     case 2:
1112         if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1113             return NULL;
1114         rtn2 = mvwinnstr(self->win,y,x,rtn,1023);
1115         break;
1116     case 3:
1117         if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n))
1118             return NULL;
1119         if (n < 0) {
1120             PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1121             return NULL;
1122         }
1123         rtn2 = mvwinnstr(self->win, y, x, rtn, MIN(n,1023));
1124         break;
1125     default:
1126         PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments");
1127         return NULL;
1128     }
1129     if (rtn2 == ERR)
1130         rtn[0] = 0;
1131     return PyString_FromString(rtn);
1132 }
1133 
1134 static PyObject *
PyCursesWindow_InsStr(PyCursesWindowObject * self,PyObject * args)1135 PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args)
1136 {
1137     int rtn;
1138     int x, y;
1139     char *str;
1140     attr_t attr = A_NORMAL , attr_old = A_NORMAL;
1141     long lattr;
1142     int use_xy = FALSE, use_attr = FALSE;
1143 
1144     switch (PyTuple_Size(args)) {
1145     case 1:
1146         if (!PyArg_ParseTuple(args,"s;str", &str))
1147             return NULL;
1148         break;
1149     case 2:
1150         if (!PyArg_ParseTuple(args,"sl;str,attr", &str, &lattr))
1151             return NULL;
1152         attr = lattr;
1153         use_attr = TRUE;
1154         break;
1155     case 3:
1156         if (!PyArg_ParseTuple(args,"iis;y,x,str", &y, &x, &str))
1157             return NULL;
1158         use_xy = TRUE;
1159         break;
1160     case 4:
1161         if (!PyArg_ParseTuple(args,"iisl;y,x,str,attr", &y, &x, &str, &lattr))
1162             return NULL;
1163         attr = lattr;
1164         use_xy = use_attr = TRUE;
1165         break;
1166     default:
1167         PyErr_SetString(PyExc_TypeError, "insstr requires 1 to 4 arguments");
1168         return NULL;
1169     }
1170 
1171     if (use_attr == TRUE) {
1172         attr_old = getattrs(self->win);
1173         (void)wattrset(self->win,attr);
1174     }
1175     if (use_xy == TRUE)
1176         rtn = mvwinsstr(self->win,y,x,str);
1177     else
1178         rtn = winsstr(self->win,str);
1179     if (use_attr == TRUE)
1180         (void)wattrset(self->win,attr_old);
1181     return PyCursesCheckERR(rtn, "insstr");
1182 }
1183 
1184 static PyObject *
PyCursesWindow_InsNStr(PyCursesWindowObject * self,PyObject * args)1185 PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args)
1186 {
1187     int rtn, x, y, n;
1188     char *str;
1189     attr_t attr = A_NORMAL , attr_old = A_NORMAL;
1190     long lattr;
1191     int use_xy = FALSE, use_attr = FALSE;
1192 
1193     switch (PyTuple_Size(args)) {
1194     case 2:
1195         if (!PyArg_ParseTuple(args,"si;str,n", &str, &n))
1196             return NULL;
1197         break;
1198     case 3:
1199         if (!PyArg_ParseTuple(args,"sil;str,n,attr", &str, &n, &lattr))
1200             return NULL;
1201         attr = lattr;
1202         use_attr = TRUE;
1203         break;
1204     case 4:
1205         if (!PyArg_ParseTuple(args,"iisi;y,x,str,n", &y, &x, &str, &n))
1206             return NULL;
1207         use_xy = TRUE;
1208         break;
1209     case 5:
1210         if (!PyArg_ParseTuple(args,"iisil;y,x,str,n,attr", &y, &x, &str, &n, &lattr))
1211             return NULL;
1212         attr = lattr;
1213         use_xy = use_attr = TRUE;
1214         break;
1215     default:
1216         PyErr_SetString(PyExc_TypeError, "insnstr requires 2 to 5 arguments");
1217         return NULL;
1218     }
1219 
1220     if (use_attr == TRUE) {
1221         attr_old = getattrs(self->win);
1222         (void)wattrset(self->win,attr);
1223     }
1224     if (use_xy == TRUE)
1225         rtn = mvwinsnstr(self->win,y,x,str,n);
1226     else
1227         rtn = winsnstr(self->win,str,n);
1228     if (use_attr == TRUE)
1229         (void)wattrset(self->win,attr_old);
1230     return PyCursesCheckERR(rtn, "insnstr");
1231 }
1232 
1233 static PyObject *
PyCursesWindow_Is_LineTouched(PyCursesWindowObject * self,PyObject * args)1234 PyCursesWindow_Is_LineTouched(PyCursesWindowObject *self, PyObject *args)
1235 {
1236     int line, erg;
1237     if (!PyArg_ParseTuple(args,"i;line", &line))
1238         return NULL;
1239     erg = is_linetouched(self->win, line);
1240     if (erg == ERR) {
1241         PyErr_SetString(PyExc_TypeError,
1242                         "is_linetouched: line number outside of boundaries");
1243         return NULL;
1244     } else
1245         if (erg == FALSE) {
1246             Py_INCREF(Py_False);
1247             return Py_False;
1248         } else {
1249             Py_INCREF(Py_True);
1250             return Py_True;
1251         }
1252 }
1253 
1254 static PyObject *
PyCursesWindow_NoOutRefresh(PyCursesWindowObject * self,PyObject * args)1255 PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args)
1256 {
1257     int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
1258     int rtn;
1259 
1260 #ifndef py_is_pad
1261     if (0)
1262 #else
1263         if (py_is_pad(self->win))
1264 #endif
1265         {
1266             switch(PyTuple_Size(args)) {
1267             case 6:
1268                 if (!PyArg_ParseTuple(args,
1269                                       "iiiiii;" \
1270                                       "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol",
1271                                       &pminrow, &pmincol, &sminrow,
1272                                       &smincol, &smaxrow, &smaxcol))
1273                     return NULL;
1274                 Py_BEGIN_ALLOW_THREADS
1275                 rtn = pnoutrefresh(self->win,
1276                                    pminrow, pmincol, sminrow,
1277                                    smincol, smaxrow, smaxcol);
1278                 Py_END_ALLOW_THREADS
1279                 return PyCursesCheckERR(rtn, "pnoutrefresh");
1280             default:
1281                 PyErr_SetString(PyCursesError,
1282                                 "noutrefresh() called for a pad "
1283                                 "requires 6 arguments");
1284                 return NULL;
1285             }
1286         } else {
1287             if (!PyArg_ParseTuple(args, ":noutrefresh"))
1288                 return NULL;
1289 
1290             Py_BEGIN_ALLOW_THREADS
1291             rtn = wnoutrefresh(self->win);
1292             Py_END_ALLOW_THREADS
1293             return PyCursesCheckERR(rtn, "wnoutrefresh");
1294         }
1295 }
1296 
1297 static PyObject *
PyCursesWindow_Overlay(PyCursesWindowObject * self,PyObject * args)1298 PyCursesWindow_Overlay(PyCursesWindowObject *self, PyObject *args)
1299 {
1300     PyCursesWindowObject *temp;
1301     int use_copywin = FALSE;
1302     int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol;
1303     int rtn;
1304 
1305     switch (PyTuple_Size(args)) {
1306     case 1:
1307         if (!PyArg_ParseTuple(args, "O!;window object",
1308                               &PyCursesWindow_Type, &temp))
1309             return NULL;
1310         break;
1311     case 7:
1312         if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int",
1313                               &PyCursesWindow_Type, &temp, &sminrow, &smincol,
1314                               &dminrow, &dmincol, &dmaxrow, &dmaxcol))
1315             return NULL;
1316         use_copywin = TRUE;
1317         break;
1318     default:
1319         PyErr_SetString(PyExc_TypeError,
1320                         "overlay requires one or seven arguments");
1321         return NULL;
1322     }
1323 
1324     if (use_copywin == TRUE) {
1325         rtn = copywin(self->win, temp->win, sminrow, smincol,
1326                       dminrow, dmincol, dmaxrow, dmaxcol, TRUE);
1327         return PyCursesCheckERR(rtn, "copywin");
1328     }
1329     else {
1330         rtn = overlay(self->win, temp->win);
1331         return PyCursesCheckERR(rtn, "overlay");
1332     }
1333 }
1334 
1335 static PyObject *
PyCursesWindow_Overwrite(PyCursesWindowObject * self,PyObject * args)1336 PyCursesWindow_Overwrite(PyCursesWindowObject *self, PyObject *args)
1337 {
1338     PyCursesWindowObject *temp;
1339     int use_copywin = FALSE;
1340     int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol;
1341     int rtn;
1342 
1343     switch (PyTuple_Size(args)) {
1344     case 1:
1345         if (!PyArg_ParseTuple(args, "O!;window object",
1346                               &PyCursesWindow_Type, &temp))
1347             return NULL;
1348         break;
1349     case 7:
1350         if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int",
1351                               &PyCursesWindow_Type, &temp, &sminrow, &smincol,
1352                               &dminrow, &dmincol, &dmaxrow, &dmaxcol))
1353             return NULL;
1354         use_copywin = TRUE;
1355         break;
1356     default:
1357         PyErr_SetString(PyExc_TypeError,
1358                         "overwrite requires one or seven arguments");
1359         return NULL;
1360     }
1361 
1362     if (use_copywin == TRUE) {
1363         rtn = copywin(self->win, temp->win, sminrow, smincol,
1364                       dminrow, dmincol, dmaxrow, dmaxcol, FALSE);
1365         return PyCursesCheckERR(rtn, "copywin");
1366     }
1367     else {
1368         rtn = overwrite(self->win, temp->win);
1369         return PyCursesCheckERR(rtn, "overwrite");
1370     }
1371 }
1372 
1373 static PyObject *
PyCursesWindow_PutWin(PyCursesWindowObject * self,PyObject * args)1374 PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *args)
1375 {
1376     PyObject *temp;
1377 
1378     if (!PyArg_ParseTuple(args, "O;fileobj", &temp))
1379         return NULL;
1380     if (!PyFile_Check(temp)) {
1381         PyErr_SetString(PyExc_TypeError, "argument must be a file object");
1382         return NULL;
1383     }
1384     return PyCursesCheckERR(putwin(self->win, PyFile_AsFile(temp)),
1385                             "putwin");
1386 }
1387 
1388 static PyObject *
PyCursesWindow_RedrawLine(PyCursesWindowObject * self,PyObject * args)1389 PyCursesWindow_RedrawLine(PyCursesWindowObject *self, PyObject *args)
1390 {
1391     int beg, num;
1392     if (!PyArg_ParseTuple(args, "ii;beg,num", &beg, &num))
1393         return NULL;
1394     return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln");
1395 }
1396 
1397 static PyObject *
PyCursesWindow_Refresh(PyCursesWindowObject * self,PyObject * args)1398 PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args)
1399 {
1400     int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
1401     int rtn;
1402 
1403 #ifndef py_is_pad
1404     if (0)
1405 #else
1406         if (py_is_pad(self->win))
1407 #endif
1408         {
1409             switch(PyTuple_Size(args)) {
1410             case 6:
1411                 if (!PyArg_ParseTuple(args,
1412                                       "iiiiii;" \
1413                                       "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol",
1414                                       &pminrow, &pmincol, &sminrow,
1415                                       &smincol, &smaxrow, &smaxcol))
1416                     return NULL;
1417 
1418                 Py_BEGIN_ALLOW_THREADS
1419                 rtn = prefresh(self->win,
1420                                pminrow, pmincol, sminrow,
1421                                smincol, smaxrow, smaxcol);
1422                 Py_END_ALLOW_THREADS
1423                 return PyCursesCheckERR(rtn, "prefresh");
1424             default:
1425                 PyErr_SetString(PyCursesError,
1426                                 "refresh() for a pad requires 6 arguments");
1427                 return NULL;
1428             }
1429         } else {
1430             if (!PyArg_ParseTuple(args, ":refresh"))
1431                 return NULL;
1432             Py_BEGIN_ALLOW_THREADS
1433             rtn = wrefresh(self->win);
1434             Py_END_ALLOW_THREADS
1435             return PyCursesCheckERR(rtn, "prefresh");
1436         }
1437 }
1438 
1439 static PyObject *
PyCursesWindow_SetScrollRegion(PyCursesWindowObject * self,PyObject * args)1440 PyCursesWindow_SetScrollRegion(PyCursesWindowObject *self, PyObject *args)
1441 {
1442     int x, y;
1443     if (!PyArg_ParseTuple(args,"ii;top, bottom",&y,&x))
1444         return NULL;
1445     return PyCursesCheckERR(wsetscrreg(self->win,y,x), "wsetscrreg");
1446 }
1447 
1448 static PyObject *
PyCursesWindow_SubWin(PyCursesWindowObject * self,PyObject * args)1449 PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args)
1450 {
1451     WINDOW *win;
1452     int nlines, ncols, begin_y, begin_x;
1453 
1454     nlines = 0;
1455     ncols  = 0;
1456     switch (PyTuple_Size(args)) {
1457     case 2:
1458         if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x))
1459             return NULL;
1460         break;
1461     case 4:
1462         if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
1463                               &nlines,&ncols,&begin_y,&begin_x))
1464             return NULL;
1465         break;
1466     default:
1467         PyErr_SetString(PyExc_TypeError, "subwin requires 2 or 4 arguments");
1468         return NULL;
1469     }
1470 
1471     /* printf("Subwin: %i %i %i %i   \n", nlines, ncols, begin_y, begin_x); */
1472 #ifdef py_is_pad
1473     if (py_is_pad(self->win)) {
1474         win = subpad(self->win, nlines, ncols, begin_y, begin_x);
1475     }
1476     else
1477 #endif
1478         win = subwin(self->win, nlines, ncols, begin_y, begin_x);
1479 
1480     if (win == NULL) {
1481         PyErr_SetString(PyCursesError, catchall_NULL);
1482         return NULL;
1483     }
1484 
1485     return (PyObject *)PyCursesWindow_New(win);
1486 }
1487 
1488 static PyObject *
PyCursesWindow_Scroll(PyCursesWindowObject * self,PyObject * args)1489 PyCursesWindow_Scroll(PyCursesWindowObject *self, PyObject *args)
1490 {
1491     int nlines;
1492     switch(PyTuple_Size(args)) {
1493     case 0:
1494         return PyCursesCheckERR(scroll(self->win), "scroll");
1495     case 1:
1496         if (!PyArg_ParseTuple(args, "i;nlines", &nlines))
1497             return NULL;
1498         return PyCursesCheckERR(wscrl(self->win, nlines), "scroll");
1499     default:
1500         PyErr_SetString(PyExc_TypeError, "scroll requires 0 or 1 arguments");
1501         return NULL;
1502     }
1503 }
1504 
1505 static PyObject *
PyCursesWindow_TouchLine(PyCursesWindowObject * self,PyObject * args)1506 PyCursesWindow_TouchLine(PyCursesWindowObject *self, PyObject *args)
1507 {
1508     int st, cnt, val;
1509     switch (PyTuple_Size(args)) {
1510     case 2:
1511         if (!PyArg_ParseTuple(args,"ii;start,count",&st,&cnt))
1512             return NULL;
1513         return PyCursesCheckERR(touchline(self->win,st,cnt), "touchline");
1514     case 3:
1515         if (!PyArg_ParseTuple(args, "iii;start,count,val", &st, &cnt, &val))
1516             return NULL;
1517         return PyCursesCheckERR(wtouchln(self->win, st, cnt, val), "touchline");
1518     default:
1519         PyErr_SetString(PyExc_TypeError, "touchline requires 2 or 3 arguments");
1520         return NULL;
1521     }
1522 }
1523 
1524 static PyObject *
PyCursesWindow_Vline(PyCursesWindowObject * self,PyObject * args)1525 PyCursesWindow_Vline(PyCursesWindowObject *self, PyObject *args)
1526 {
1527     PyObject *temp;
1528     chtype ch;
1529     int n, x, y, code = OK;
1530     attr_t attr = A_NORMAL;
1531     long lattr;
1532 
1533     switch (PyTuple_Size(args)) {
1534     case 2:
1535         if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n))
1536             return NULL;
1537         break;
1538     case 3:
1539         if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr))
1540             return NULL;
1541         attr = lattr;
1542         break;
1543     case 4:
1544         if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n))
1545             return NULL;
1546         code = wmove(self->win, y, x);
1547         break;
1548     case 5:
1549         if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr",
1550                               &y, &x, &temp, &n, &lattr))
1551             return NULL;
1552         attr = lattr;
1553         code = wmove(self->win, y, x);
1554         break;
1555     default:
1556         PyErr_SetString(PyExc_TypeError, "vline requires 2 to 5 arguments");
1557         return NULL;
1558     }
1559 
1560     if (code != ERR) {
1561         if (!PyCurses_ConvertToChtype(temp, &ch)) {
1562             PyErr_SetString(PyExc_TypeError,
1563                             "argument 1 or 3 must be a ch or an int");
1564             return NULL;
1565         }
1566         return PyCursesCheckERR(wvline(self->win, ch | attr, n), "vline");
1567     } else
1568         return PyCursesCheckERR(code, "wmove");
1569 }
1570 
1571 static PyMethodDef PyCursesWindow_Methods[] = {
1572     {"addch",           (PyCFunction)PyCursesWindow_AddCh, METH_VARARGS},
1573     {"addnstr",         (PyCFunction)PyCursesWindow_AddNStr, METH_VARARGS},
1574     {"addstr",          (PyCFunction)PyCursesWindow_AddStr, METH_VARARGS},
1575     {"attroff",         (PyCFunction)PyCursesWindow_AttrOff, METH_VARARGS},
1576     {"attron",          (PyCFunction)PyCursesWindow_AttrOn, METH_VARARGS},
1577     {"attrset",         (PyCFunction)PyCursesWindow_AttrSet, METH_VARARGS},
1578     {"bkgd",            (PyCFunction)PyCursesWindow_Bkgd, METH_VARARGS},
1579 #ifdef HAVE_CURSES_WCHGAT
1580     {"chgat",           (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS},
1581 #endif
1582     {"bkgdset",         (PyCFunction)PyCursesWindow_BkgdSet, METH_VARARGS},
1583     {"border",          (PyCFunction)PyCursesWindow_Border, METH_VARARGS},
1584     {"box",             (PyCFunction)PyCursesWindow_Box, METH_VARARGS},
1585     {"clear",           (PyCFunction)PyCursesWindow_wclear, METH_NOARGS},
1586     {"clearok",         (PyCFunction)PyCursesWindow_clearok, METH_VARARGS},
1587     {"clrtobot",        (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS},
1588     {"clrtoeol",        (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS},
1589     {"cursyncup",       (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS},
1590     {"delch",           (PyCFunction)PyCursesWindow_DelCh, METH_VARARGS},
1591     {"deleteln",        (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS},
1592     {"derwin",          (PyCFunction)PyCursesWindow_DerWin, METH_VARARGS},
1593     {"echochar",        (PyCFunction)PyCursesWindow_EchoChar, METH_VARARGS},
1594 #ifdef NCURSES_MOUSE_VERSION
1595     {"enclose",         (PyCFunction)PyCursesWindow_Enclose, METH_VARARGS},
1596 #endif
1597     {"erase",           (PyCFunction)PyCursesWindow_werase, METH_NOARGS},
1598     {"getbegyx",        (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS},
1599     {"getbkgd",         (PyCFunction)PyCursesWindow_GetBkgd, METH_NOARGS},
1600     {"getch",           (PyCFunction)PyCursesWindow_GetCh, METH_VARARGS},
1601     {"getkey",          (PyCFunction)PyCursesWindow_GetKey, METH_VARARGS},
1602     {"getmaxyx",        (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS},
1603     {"getparyx",        (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS},
1604     {"getstr",          (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS},
1605     {"getyx",           (PyCFunction)PyCursesWindow_getyx, METH_NOARGS},
1606     {"hline",           (PyCFunction)PyCursesWindow_Hline, METH_VARARGS},
1607     {"idcok",           (PyCFunction)PyCursesWindow_idcok, METH_VARARGS},
1608     {"idlok",           (PyCFunction)PyCursesWindow_idlok, METH_VARARGS},
1609 #ifdef HAVE_CURSES_IMMEDOK
1610     {"immedok",         (PyCFunction)PyCursesWindow_immedok, METH_VARARGS},
1611 #endif
1612     {"inch",            (PyCFunction)PyCursesWindow_InCh, METH_VARARGS},
1613     {"insch",           (PyCFunction)PyCursesWindow_InsCh, METH_VARARGS},
1614     {"insdelln",        (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS},
1615     {"insertln",        (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS},
1616     {"insnstr",         (PyCFunction)PyCursesWindow_InsNStr, METH_VARARGS},
1617     {"insstr",          (PyCFunction)PyCursesWindow_InsStr, METH_VARARGS},
1618     {"instr",           (PyCFunction)PyCursesWindow_InStr, METH_VARARGS},
1619     {"is_linetouched",  (PyCFunction)PyCursesWindow_Is_LineTouched, METH_VARARGS},
1620     {"is_wintouched",   (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS},
1621     {"keypad",          (PyCFunction)PyCursesWindow_keypad, METH_VARARGS},
1622     {"leaveok",         (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS},
1623     {"move",            (PyCFunction)PyCursesWindow_wmove, METH_VARARGS},
1624     {"mvderwin",        (PyCFunction)PyCursesWindow_mvderwin, METH_VARARGS},
1625     {"mvwin",           (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS},
1626     {"nodelay",         (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS},
1627     {"notimeout",       (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS},
1628     {"noutrefresh",     (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS},
1629     /* Backward compatibility alias -- remove in Python 2.3 */
1630     {"nooutrefresh",    (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS},
1631     {"overlay",         (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS},
1632     {"overwrite",       (PyCFunction)PyCursesWindow_Overwrite,
1633      METH_VARARGS},
1634     {"putwin",          (PyCFunction)PyCursesWindow_PutWin, METH_VARARGS},
1635     {"redrawln",        (PyCFunction)PyCursesWindow_RedrawLine, METH_VARARGS},
1636     {"redrawwin",       (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS},
1637     {"refresh",         (PyCFunction)PyCursesWindow_Refresh, METH_VARARGS},
1638 #ifndef STRICT_SYSV_CURSES
1639     {"resize",          (PyCFunction)PyCursesWindow_wresize, METH_VARARGS},
1640 #endif
1641     {"scroll",          (PyCFunction)PyCursesWindow_Scroll, METH_VARARGS},
1642     {"scrollok",        (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS},
1643     {"setscrreg",       (PyCFunction)PyCursesWindow_SetScrollRegion, METH_VARARGS},
1644     {"standend",        (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS},
1645     {"standout",        (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS},
1646     {"subpad",          (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
1647     {"subwin",          (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
1648     {"syncdown",        (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS},
1649 #ifdef HAVE_CURSES_SYNCOK
1650     {"syncok",          (PyCFunction)PyCursesWindow_syncok, METH_VARARGS},
1651 #endif
1652     {"syncup",          (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS},
1653     {"timeout",         (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS},
1654     {"touchline",       (PyCFunction)PyCursesWindow_TouchLine, METH_VARARGS},
1655     {"touchwin",        (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS},
1656     {"untouchwin",      (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS},
1657     {"vline",           (PyCFunction)PyCursesWindow_Vline, METH_VARARGS},
1658     {NULL,                  NULL}   /* sentinel */
1659 };
1660 
1661 static PyObject *
PyCursesWindow_GetAttr(PyCursesWindowObject * self,char * name)1662 PyCursesWindow_GetAttr(PyCursesWindowObject *self, char *name)
1663 {
1664     return Py_FindMethod(PyCursesWindow_Methods, (PyObject *)self, name);
1665 }
1666 
1667 /* -------------------------------------------------------*/
1668 
1669 PyTypeObject PyCursesWindow_Type = {
1670     PyVarObject_HEAD_INIT(NULL, 0)
1671     "_curses.curses window",            /*tp_name*/
1672     sizeof(PyCursesWindowObject),       /*tp_basicsize*/
1673     0,                          /*tp_itemsize*/
1674     /* methods */
1675     (destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/
1676     0,                          /*tp_print*/
1677     (getattrfunc)PyCursesWindow_GetAttr, /*tp_getattr*/
1678     (setattrfunc)0, /*tp_setattr*/
1679     0,                          /*tp_compare*/
1680     0,                          /*tp_repr*/
1681     0,                          /*tp_as_number*/
1682     0,                          /*tp_as_sequence*/
1683     0,                          /*tp_as_mapping*/
1684     0,                          /*tp_hash*/
1685 };
1686 
1687 /*********************************************************************
1688  Global Functions
1689 **********************************************************************/
1690 
1691 NoArgNoReturnFunction(beep)
NoArgNoReturnFunction(def_prog_mode)1692 NoArgNoReturnFunction(def_prog_mode)
1693 NoArgNoReturnFunction(def_shell_mode)
1694 NoArgNoReturnFunction(doupdate)
1695 NoArgNoReturnFunction(endwin)
1696 NoArgNoReturnFunction(flash)
1697 NoArgNoReturnFunction(nocbreak)
1698 NoArgNoReturnFunction(noecho)
1699 NoArgNoReturnFunction(nonl)
1700 NoArgNoReturnFunction(noraw)
1701 NoArgNoReturnFunction(reset_prog_mode)
1702 NoArgNoReturnFunction(reset_shell_mode)
1703 NoArgNoReturnFunction(resetty)
1704 NoArgNoReturnFunction(savetty)
1705 
1706 NoArgOrFlagNoReturnFunction(cbreak)
1707 NoArgOrFlagNoReturnFunction(echo)
1708 NoArgOrFlagNoReturnFunction(nl)
1709 NoArgOrFlagNoReturnFunction(raw)
1710 
1711 NoArgReturnIntFunction(baudrate)
1712 NoArgReturnIntFunction(termattrs)
1713 
1714 NoArgReturnStringFunction(termname)
1715 NoArgReturnStringFunction(longname)
1716 
1717 NoArgTrueFalseFunction(can_change_color)
1718 NoArgTrueFalseFunction(has_colors)
1719 NoArgTrueFalseFunction(has_ic)
1720 NoArgTrueFalseFunction(has_il)
1721 NoArgTrueFalseFunction(isendwin)
1722 NoArgNoReturnVoidFunction(flushinp)
1723 NoArgNoReturnVoidFunction(noqiflush)
1724 
1725 #ifdef HAVE_CURSES_FILTER
1726 static PyObject *
1727 PyCurses_filter(PyObject *self)
1728 {
1729     /* not checking for PyCursesInitialised here since filter() must
1730        be called before initscr() */
1731     filter();
1732     Py_INCREF(Py_None);
1733     return Py_None;
1734 }
1735 #endif
1736 
1737 static PyObject *
PyCurses_Color_Content(PyObject * self,PyObject * args)1738 PyCurses_Color_Content(PyObject *self, PyObject *args)
1739 {
1740     short color,r,g,b;
1741 
1742     PyCursesInitialised;
1743     PyCursesInitialisedColor;
1744 
1745     if (!PyArg_ParseTuple(args, "h:color_content", &color)) return NULL;
1746 
1747     if (color_content(color, &r, &g, &b) != ERR)
1748         return Py_BuildValue("(iii)", r, g, b);
1749     else {
1750         PyErr_SetString(PyCursesError,
1751                         "Argument 1 was out of range. Check value of COLORS.");
1752         return NULL;
1753     }
1754 }
1755 
1756 static PyObject *
PyCurses_color_pair(PyObject * self,PyObject * args)1757 PyCurses_color_pair(PyObject *self, PyObject *args)
1758 {
1759     int n;
1760 
1761     PyCursesInitialised;
1762     PyCursesInitialisedColor;
1763 
1764     if (!PyArg_ParseTuple(args, "i:color_pair", &n)) return NULL;
1765     return PyInt_FromLong((long) (n << 8));
1766 }
1767 
1768 static PyObject *
PyCurses_Curs_Set(PyObject * self,PyObject * args)1769 PyCurses_Curs_Set(PyObject *self, PyObject *args)
1770 {
1771     int vis,erg;
1772 
1773     PyCursesInitialised;
1774 
1775     if (!PyArg_ParseTuple(args, "i:curs_set", &vis)) return NULL;
1776 
1777     erg = curs_set(vis);
1778     if (erg == ERR) return PyCursesCheckERR(erg, "curs_set");
1779 
1780     return PyInt_FromLong((long) erg);
1781 }
1782 
1783 static PyObject *
PyCurses_Delay_Output(PyObject * self,PyObject * args)1784 PyCurses_Delay_Output(PyObject *self, PyObject *args)
1785 {
1786     int ms;
1787 
1788     PyCursesInitialised;
1789 
1790     if (!PyArg_ParseTuple(args, "i:delay_output", &ms)) return NULL;
1791 
1792     return PyCursesCheckERR(delay_output(ms), "delay_output");
1793 }
1794 
1795 static PyObject *
PyCurses_EraseChar(PyObject * self)1796 PyCurses_EraseChar(PyObject *self)
1797 {
1798     char ch;
1799 
1800     PyCursesInitialised;
1801 
1802     ch = erasechar();
1803 
1804     return PyString_FromStringAndSize(&ch, 1);
1805 }
1806 
1807 #ifdef getsyx
1808 static PyObject *
PyCurses_getsyx(PyObject * self)1809 PyCurses_getsyx(PyObject *self)
1810 {
1811     int x = 0;
1812     int y = 0;
1813 
1814     PyCursesInitialised;
1815 
1816     getsyx(y, x);
1817 
1818     return Py_BuildValue("(ii)", y, x);
1819 }
1820 #endif
1821 
1822 #ifdef NCURSES_MOUSE_VERSION
1823 static PyObject *
PyCurses_GetMouse(PyObject * self)1824 PyCurses_GetMouse(PyObject *self)
1825 {
1826     int rtn;
1827     MEVENT event;
1828 
1829     PyCursesInitialised;
1830 
1831     rtn = getmouse( &event );
1832     if (rtn == ERR) {
1833         PyErr_SetString(PyCursesError, "getmouse() returned ERR");
1834         return NULL;
1835     }
1836     return Py_BuildValue("(hiiik)",
1837                          (short)event.id,
1838                          (int)event.x, (int)event.y, (int)event.z,
1839                          (unsigned long) event.bstate);
1840 }
1841 
1842 static PyObject *
PyCurses_UngetMouse(PyObject * self,PyObject * args)1843 PyCurses_UngetMouse(PyObject *self, PyObject *args)
1844 {
1845     MEVENT event;
1846     short id;
1847     int x, y, z;
1848     unsigned long bstate;
1849 
1850     PyCursesInitialised;
1851     if (!PyArg_ParseTuple(args, "hiiik",
1852                           &id, &x, &y, &z, &bstate))
1853         return NULL;
1854 
1855     event.id = id;
1856     event.x = x;
1857     event.y = y;
1858     event.z = z;
1859     event.bstate = bstate;
1860     return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
1861 }
1862 #endif
1863 
1864 static PyObject *
PyCurses_GetWin(PyCursesWindowObject * self,PyObject * temp)1865 PyCurses_GetWin(PyCursesWindowObject *self, PyObject *temp)
1866 {
1867     WINDOW *win;
1868 
1869     PyCursesInitialised;
1870 
1871     if (!PyFile_Check(temp)) {
1872         PyErr_SetString(PyExc_TypeError, "argument must be a file object");
1873         return NULL;
1874     }
1875 
1876     win = getwin(PyFile_AsFile(temp));
1877 
1878     if (win == NULL) {
1879         PyErr_SetString(PyCursesError, catchall_NULL);
1880         return NULL;
1881     }
1882 
1883     return PyCursesWindow_New(win);
1884 }
1885 
1886 static PyObject *
PyCurses_HalfDelay(PyObject * self,PyObject * args)1887 PyCurses_HalfDelay(PyObject *self, PyObject *args)
1888 {
1889     unsigned char tenths;
1890 
1891     PyCursesInitialised;
1892 
1893     if (!PyArg_ParseTuple(args, "b:halfdelay", &tenths)) return NULL;
1894 
1895     return PyCursesCheckERR(halfdelay(tenths), "halfdelay");
1896 }
1897 
1898 #ifdef HAVE_CURSES_HAS_KEY
1899 static PyObject *
PyCurses_has_key(PyObject * self,PyObject * args)1900 PyCurses_has_key(PyObject *self, PyObject *args)
1901 {
1902     int ch;
1903 
1904     PyCursesInitialised;
1905 
1906     if (!PyArg_ParseTuple(args,"i",&ch)) return NULL;
1907 
1908     if (has_key(ch) == FALSE) {
1909         Py_INCREF(Py_False);
1910         return Py_False;
1911     }
1912     Py_INCREF(Py_True);
1913     return Py_True;
1914 }
1915 #endif
1916 
1917 static PyObject *
PyCurses_Init_Color(PyObject * self,PyObject * args)1918 PyCurses_Init_Color(PyObject *self, PyObject *args)
1919 {
1920     short color, r, g, b;
1921 
1922     PyCursesInitialised;
1923     PyCursesInitialisedColor;
1924 
1925     switch(PyTuple_Size(args)) {
1926     case 4:
1927         if (!PyArg_ParseTuple(args, "hhhh;color,r,g,b", &color, &r, &g, &b)) return NULL;
1928         break;
1929     default:
1930         PyErr_SetString(PyExc_TypeError, "init_color requires 4 arguments");
1931         return NULL;
1932     }
1933 
1934     return PyCursesCheckERR(init_color(color, r, g, b), "init_color");
1935 }
1936 
1937 static PyObject *
PyCurses_Init_Pair(PyObject * self,PyObject * args)1938 PyCurses_Init_Pair(PyObject *self, PyObject *args)
1939 {
1940     short pair, f, b;
1941 
1942     PyCursesInitialised;
1943     PyCursesInitialisedColor;
1944 
1945     if (PyTuple_Size(args) != 3) {
1946         PyErr_SetString(PyExc_TypeError, "init_pair requires 3 arguments");
1947         return NULL;
1948     }
1949 
1950     if (!PyArg_ParseTuple(args, "hhh;pair, f, b", &pair, &f, &b)) return NULL;
1951 
1952     return PyCursesCheckERR(init_pair(pair, f, b), "init_pair");
1953 }
1954 
1955 static PyObject *ModDict;
1956 
1957 static PyObject *
PyCurses_InitScr(PyObject * self)1958 PyCurses_InitScr(PyObject *self)
1959 {
1960     WINDOW *win;
1961 
1962     if (initialised == TRUE) {
1963         wrefresh(stdscr);
1964         return (PyObject *)PyCursesWindow_New(stdscr);
1965     }
1966 
1967     win = initscr();
1968 
1969     if (win == NULL) {
1970         PyErr_SetString(PyCursesError, catchall_NULL);
1971         return NULL;
1972     }
1973 
1974     initialised = initialised_setupterm = TRUE;
1975 
1976 /* This was moved from initcurses() because it core dumped on SGI,
1977    where they're not defined until you've called initscr() */
1978 #define SetDictInt(string,ch)                                           \
1979     do {                                                                \
1980         PyObject *o = PyInt_FromLong((long) (ch));                      \
1981         if (o && PyDict_SetItemString(ModDict, string, o) == 0)     {   \
1982             Py_DECREF(o);                                               \
1983         }                                                               \
1984     } while (0)
1985 
1986     /* Here are some graphic symbols you can use */
1987     SetDictInt("ACS_ULCORNER",      (ACS_ULCORNER));
1988     SetDictInt("ACS_LLCORNER",      (ACS_LLCORNER));
1989     SetDictInt("ACS_URCORNER",      (ACS_URCORNER));
1990     SetDictInt("ACS_LRCORNER",      (ACS_LRCORNER));
1991     SetDictInt("ACS_LTEE",          (ACS_LTEE));
1992     SetDictInt("ACS_RTEE",          (ACS_RTEE));
1993     SetDictInt("ACS_BTEE",          (ACS_BTEE));
1994     SetDictInt("ACS_TTEE",          (ACS_TTEE));
1995     SetDictInt("ACS_HLINE",         (ACS_HLINE));
1996     SetDictInt("ACS_VLINE",         (ACS_VLINE));
1997     SetDictInt("ACS_PLUS",          (ACS_PLUS));
1998 #if !defined(__hpux) || defined(HAVE_NCURSES_H)
1999     /* On HP/UX 11, these are of type cchar_t, which is not an
2000        integral type. If this is a problem on more platforms, a
2001        configure test should be added to determine whether ACS_S1
2002        is of integral type. */
2003     SetDictInt("ACS_S1",            (ACS_S1));
2004     SetDictInt("ACS_S9",            (ACS_S9));
2005     SetDictInt("ACS_DIAMOND",       (ACS_DIAMOND));
2006     SetDictInt("ACS_CKBOARD",       (ACS_CKBOARD));
2007     SetDictInt("ACS_DEGREE",        (ACS_DEGREE));
2008     SetDictInt("ACS_PLMINUS",       (ACS_PLMINUS));
2009     SetDictInt("ACS_BULLET",        (ACS_BULLET));
2010     SetDictInt("ACS_LARROW",        (ACS_LARROW));
2011     SetDictInt("ACS_RARROW",        (ACS_RARROW));
2012     SetDictInt("ACS_DARROW",        (ACS_DARROW));
2013     SetDictInt("ACS_UARROW",        (ACS_UARROW));
2014     SetDictInt("ACS_BOARD",         (ACS_BOARD));
2015     SetDictInt("ACS_LANTERN",       (ACS_LANTERN));
2016     SetDictInt("ACS_BLOCK",         (ACS_BLOCK));
2017 #endif
2018     SetDictInt("ACS_BSSB",          (ACS_ULCORNER));
2019     SetDictInt("ACS_SSBB",          (ACS_LLCORNER));
2020     SetDictInt("ACS_BBSS",          (ACS_URCORNER));
2021     SetDictInt("ACS_SBBS",          (ACS_LRCORNER));
2022     SetDictInt("ACS_SBSS",          (ACS_RTEE));
2023     SetDictInt("ACS_SSSB",          (ACS_LTEE));
2024     SetDictInt("ACS_SSBS",          (ACS_BTEE));
2025     SetDictInt("ACS_BSSS",          (ACS_TTEE));
2026     SetDictInt("ACS_BSBS",          (ACS_HLINE));
2027     SetDictInt("ACS_SBSB",          (ACS_VLINE));
2028     SetDictInt("ACS_SSSS",          (ACS_PLUS));
2029 
2030     /* The following are never available with strict SYSV curses */
2031 #ifdef ACS_S3
2032     SetDictInt("ACS_S3",            (ACS_S3));
2033 #endif
2034 #ifdef ACS_S7
2035     SetDictInt("ACS_S7",            (ACS_S7));
2036 #endif
2037 #ifdef ACS_LEQUAL
2038     SetDictInt("ACS_LEQUAL",        (ACS_LEQUAL));
2039 #endif
2040 #ifdef ACS_GEQUAL
2041     SetDictInt("ACS_GEQUAL",        (ACS_GEQUAL));
2042 #endif
2043 #ifdef ACS_PI
2044     SetDictInt("ACS_PI",            (ACS_PI));
2045 #endif
2046 #ifdef ACS_NEQUAL
2047     SetDictInt("ACS_NEQUAL",        (ACS_NEQUAL));
2048 #endif
2049 #ifdef ACS_STERLING
2050     SetDictInt("ACS_STERLING",      (ACS_STERLING));
2051 #endif
2052 
2053     SetDictInt("LINES", LINES);
2054     SetDictInt("COLS", COLS);
2055 
2056     return (PyObject *)PyCursesWindow_New(win);
2057 }
2058 
2059 static PyObject *
PyCurses_setupterm(PyObject * self,PyObject * args,PyObject * keywds)2060 PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds)
2061 {
2062     int fd = -1;
2063     int err;
2064     char* termstr = NULL;
2065 
2066     static char *kwlist[] = {"term", "fd", NULL};
2067 
2068     if (!PyArg_ParseTupleAndKeywords(
2069             args, keywds, "|zi:setupterm", kwlist, &termstr, &fd)) {
2070         return NULL;
2071     }
2072 
2073     if (fd == -1) {
2074         PyObject* sys_stdout;
2075 
2076         sys_stdout = PySys_GetObject("stdout");
2077 
2078         if (sys_stdout == NULL) {
2079             PyErr_SetString(
2080                 PyCursesError,
2081                 "lost sys.stdout");
2082             return NULL;
2083         }
2084 
2085         fd = PyObject_AsFileDescriptor(sys_stdout);
2086 
2087         if (fd == -1) {
2088             return NULL;
2089         }
2090     }
2091 
2092     if (!initialised_setupterm && setupterm(termstr,fd,&err) == ERR) {
2093         char* s = "setupterm: unknown error";
2094 
2095         if (err == 0) {
2096             s = "setupterm: could not find terminal";
2097         } else if (err == -1) {
2098             s = "setupterm: could not find terminfo database";
2099         }
2100 
2101         PyErr_SetString(PyCursesError,s);
2102         return NULL;
2103     }
2104 
2105     initialised_setupterm = TRUE;
2106 
2107     Py_INCREF(Py_None);
2108     return Py_None;
2109 }
2110 
2111 static PyObject *
PyCurses_IntrFlush(PyObject * self,PyObject * args)2112 PyCurses_IntrFlush(PyObject *self, PyObject *args)
2113 {
2114     int ch;
2115 
2116     PyCursesInitialised;
2117 
2118     switch(PyTuple_Size(args)) {
2119     case 1:
2120         if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL;
2121         break;
2122     default:
2123         PyErr_SetString(PyExc_TypeError, "intrflush requires 1 argument");
2124         return NULL;
2125     }
2126 
2127     return PyCursesCheckERR(intrflush(NULL,ch), "intrflush");
2128 }
2129 
2130 #ifdef HAVE_CURSES_IS_TERM_RESIZED
2131 static PyObject *
PyCurses_Is_Term_Resized(PyObject * self,PyObject * args)2132 PyCurses_Is_Term_Resized(PyObject *self, PyObject *args)
2133 {
2134     int lines;
2135     int columns;
2136     int result;
2137 
2138     PyCursesInitialised;
2139 
2140     if (!PyArg_ParseTuple(args,"ii:is_term_resized", &lines, &columns))
2141         return NULL;
2142     result = is_term_resized(lines, columns);
2143     if (result == TRUE) {
2144         Py_INCREF(Py_True);
2145         return Py_True;
2146     } else {
2147         Py_INCREF(Py_False);
2148         return Py_False;
2149     }
2150 }
2151 #endif /* HAVE_CURSES_IS_TERM_RESIZED */
2152 
2153 static PyObject *
PyCurses_KeyName(PyObject * self,PyObject * args)2154 PyCurses_KeyName(PyObject *self, PyObject *args)
2155 {
2156     const char *knp;
2157     int ch;
2158 
2159     PyCursesInitialised;
2160 
2161     if (!PyArg_ParseTuple(args,"i",&ch)) return NULL;
2162 
2163     if (ch < 0) {
2164         PyErr_SetString(PyExc_ValueError, "invalid key number");
2165         return NULL;
2166     }
2167     knp = keyname(ch);
2168 
2169     return PyString_FromString((knp == NULL) ? "" : (char *)knp);
2170 }
2171 
2172 static PyObject *
PyCurses_KillChar(PyObject * self)2173 PyCurses_KillChar(PyObject *self)
2174 {
2175     char ch;
2176 
2177     ch = killchar();
2178 
2179     return PyString_FromStringAndSize(&ch, 1);
2180 }
2181 
2182 static PyObject *
PyCurses_Meta(PyObject * self,PyObject * args)2183 PyCurses_Meta(PyObject *self, PyObject *args)
2184 {
2185     int ch;
2186 
2187     PyCursesInitialised;
2188 
2189     switch(PyTuple_Size(args)) {
2190     case 1:
2191         if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL;
2192         break;
2193     default:
2194         PyErr_SetString(PyExc_TypeError, "meta requires 1 argument");
2195         return NULL;
2196     }
2197 
2198     return PyCursesCheckERR(meta(stdscr, ch), "meta");
2199 }
2200 
2201 #ifdef NCURSES_MOUSE_VERSION
2202 static PyObject *
PyCurses_MouseInterval(PyObject * self,PyObject * args)2203 PyCurses_MouseInterval(PyObject *self, PyObject *args)
2204 {
2205     int interval;
2206     PyCursesInitialised;
2207 
2208     if (!PyArg_ParseTuple(args,"i;interval",&interval))
2209         return NULL;
2210     return PyCursesCheckERR(mouseinterval(interval), "mouseinterval");
2211 }
2212 
2213 static PyObject *
PyCurses_MouseMask(PyObject * self,PyObject * args)2214 PyCurses_MouseMask(PyObject *self, PyObject *args)
2215 {
2216     unsigned long newmask;
2217     mmask_t oldmask, availmask;
2218 
2219     PyCursesInitialised;
2220     if (!PyArg_ParseTuple(args,"k;mousemask",&newmask))
2221         return NULL;
2222     availmask = mousemask((mmask_t)newmask, &oldmask);
2223     return Py_BuildValue("(kk)",
2224                          (unsigned long)availmask, (unsigned long)oldmask);
2225 }
2226 #endif
2227 
2228 static PyObject *
PyCurses_Napms(PyObject * self,PyObject * args)2229 PyCurses_Napms(PyObject *self, PyObject *args)
2230 {
2231     int ms;
2232 
2233     PyCursesInitialised;
2234     if (!PyArg_ParseTuple(args, "i;ms", &ms)) return NULL;
2235 
2236     return Py_BuildValue("i", napms(ms));
2237 }
2238 
2239 
2240 static PyObject *
PyCurses_NewPad(PyObject * self,PyObject * args)2241 PyCurses_NewPad(PyObject *self, PyObject *args)
2242 {
2243     WINDOW *win;
2244     int nlines, ncols;
2245 
2246     PyCursesInitialised;
2247 
2248     if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols)) return NULL;
2249 
2250     win = newpad(nlines, ncols);
2251 
2252     if (win == NULL) {
2253         PyErr_SetString(PyCursesError, catchall_NULL);
2254         return NULL;
2255     }
2256 
2257     return (PyObject *)PyCursesWindow_New(win);
2258 }
2259 
2260 static PyObject *
PyCurses_NewWindow(PyObject * self,PyObject * args)2261 PyCurses_NewWindow(PyObject *self, PyObject *args)
2262 {
2263     WINDOW *win;
2264     int nlines, ncols, begin_y=0, begin_x=0;
2265 
2266     PyCursesInitialised;
2267 
2268     switch (PyTuple_Size(args)) {
2269     case 2:
2270         if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols))
2271             return NULL;
2272         break;
2273     case 4:
2274         if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
2275                               &nlines,&ncols,&begin_y,&begin_x))
2276             return NULL;
2277         break;
2278     default:
2279         PyErr_SetString(PyExc_TypeError, "newwin requires 2 or 4 arguments");
2280         return NULL;
2281     }
2282 
2283     win = newwin(nlines,ncols,begin_y,begin_x);
2284     if (win == NULL) {
2285         PyErr_SetString(PyCursesError, catchall_NULL);
2286         return NULL;
2287     }
2288 
2289     return (PyObject *)PyCursesWindow_New(win);
2290 }
2291 
2292 static PyObject *
PyCurses_Pair_Content(PyObject * self,PyObject * args)2293 PyCurses_Pair_Content(PyObject *self, PyObject *args)
2294 {
2295     short pair,f,b;
2296 
2297     PyCursesInitialised;
2298     PyCursesInitialisedColor;
2299 
2300     switch(PyTuple_Size(args)) {
2301     case 1:
2302         if (!PyArg_ParseTuple(args, "h;pair", &pair)) return NULL;
2303         break;
2304     default:
2305         PyErr_SetString(PyExc_TypeError, "pair_content requires 1 argument");
2306         return NULL;
2307     }
2308 
2309     if (pair_content(pair, &f, &b)==ERR) {
2310         PyErr_SetString(PyCursesError,
2311                         "Argument 1 was out of range. (1..COLOR_PAIRS-1)");
2312         return NULL;
2313     }
2314 
2315     return Py_BuildValue("(ii)", f, b);
2316 }
2317 
2318 static PyObject *
PyCurses_pair_number(PyObject * self,PyObject * args)2319 PyCurses_pair_number(PyObject *self, PyObject *args)
2320 {
2321     int n;
2322 
2323     PyCursesInitialised;
2324     PyCursesInitialisedColor;
2325 
2326     switch(PyTuple_Size(args)) {
2327     case 1:
2328         if (!PyArg_ParseTuple(args, "i;pairvalue", &n)) return NULL;
2329         break;
2330     default:
2331         PyErr_SetString(PyExc_TypeError,
2332                         "pair_number requires 1 argument");
2333         return NULL;
2334     }
2335 
2336     return PyInt_FromLong((long) ((n & A_COLOR) >> 8));
2337 }
2338 
2339 static PyObject *
PyCurses_Putp(PyObject * self,PyObject * args)2340 PyCurses_Putp(PyObject *self, PyObject *args)
2341 {
2342     char *str;
2343 
2344     if (!PyArg_ParseTuple(args,"s;str", &str)) return NULL;
2345     return PyCursesCheckERR(putp(str), "putp");
2346 }
2347 
2348 static PyObject *
PyCurses_QiFlush(PyObject * self,PyObject * args)2349 PyCurses_QiFlush(PyObject *self, PyObject *args)
2350 {
2351     int flag = 0;
2352 
2353     PyCursesInitialised;
2354 
2355     switch(PyTuple_Size(args)) {
2356     case 0:
2357         qiflush();
2358         Py_INCREF(Py_None);
2359         return Py_None;
2360     case 1:
2361         if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL;
2362         if (flag) qiflush();
2363         else noqiflush();
2364         Py_INCREF(Py_None);
2365         return Py_None;
2366     default:
2367         PyErr_SetString(PyExc_TypeError, "qiflush requires 0 or 1 arguments");
2368         return NULL;
2369     }
2370 }
2371 
2372 /* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES
2373  * and _curses.COLS */
2374 #if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)
2375 static int
update_lines_cols(void)2376 update_lines_cols(void)
2377 {
2378     PyObject *o;
2379     PyObject *m = PyImport_ImportModuleNoBlock("curses");
2380 
2381     if (!m)
2382         return 0;
2383 
2384     o = PyInt_FromLong(LINES);
2385     if (!o) {
2386         Py_DECREF(m);
2387         return 0;
2388     }
2389     if (PyObject_SetAttrString(m, "LINES", o)) {
2390         Py_DECREF(m);
2391         Py_DECREF(o);
2392         return 0;
2393     }
2394     if (PyDict_SetItemString(ModDict, "LINES", o)) {
2395         Py_DECREF(m);
2396         Py_DECREF(o);
2397         return 0;
2398     }
2399     Py_DECREF(o);
2400     o = PyInt_FromLong(COLS);
2401     if (!o) {
2402         Py_DECREF(m);
2403         return 0;
2404     }
2405     if (PyObject_SetAttrString(m, "COLS", o)) {
2406         Py_DECREF(m);
2407         Py_DECREF(o);
2408         return 0;
2409     }
2410     if (PyDict_SetItemString(ModDict, "COLS", o)) {
2411         Py_DECREF(m);
2412         Py_DECREF(o);
2413         return 0;
2414     }
2415     Py_DECREF(o);
2416     Py_DECREF(m);
2417     return 1;
2418 }
2419 #endif
2420 
2421 #ifdef HAVE_CURSES_RESIZETERM
2422 static PyObject *
PyCurses_ResizeTerm(PyObject * self,PyObject * args)2423 PyCurses_ResizeTerm(PyObject *self, PyObject *args)
2424 {
2425     int lines;
2426     int columns;
2427     PyObject *result;
2428 
2429     PyCursesInitialised;
2430 
2431     if (!PyArg_ParseTuple(args,"ii:resizeterm", &lines, &columns))
2432         return NULL;
2433 
2434     result = PyCursesCheckERR(resizeterm(lines, columns), "resizeterm");
2435     if (!result)
2436         return NULL;
2437     if (!update_lines_cols())
2438         return NULL;
2439     return result;
2440 }
2441 
2442 #endif
2443 
2444 #ifdef HAVE_CURSES_RESIZE_TERM
2445 static PyObject *
PyCurses_Resize_Term(PyObject * self,PyObject * args)2446 PyCurses_Resize_Term(PyObject *self, PyObject *args)
2447 {
2448     int lines;
2449     int columns;
2450 
2451     PyObject *result;
2452 
2453     PyCursesInitialised;
2454 
2455     if (!PyArg_ParseTuple(args,"ii:resize_term", &lines, &columns))
2456         return NULL;
2457 
2458     result = PyCursesCheckERR(resize_term(lines, columns), "resize_term");
2459     if (!result)
2460         return NULL;
2461     if (!update_lines_cols())
2462         return NULL;
2463     return result;
2464 }
2465 #endif /* HAVE_CURSES_RESIZE_TERM */
2466 
2467 #ifdef getsyx
2468 static PyObject *
PyCurses_setsyx(PyObject * self,PyObject * args)2469 PyCurses_setsyx(PyObject *self, PyObject *args)
2470 {
2471     int y,x;
2472 
2473     PyCursesInitialised;
2474 
2475     if (PyTuple_Size(args)!=2) {
2476         PyErr_SetString(PyExc_TypeError, "setsyx requires 2 arguments");
2477         return NULL;
2478     }
2479 
2480     if (!PyArg_ParseTuple(args, "ii;y, x", &y, &x)) return NULL;
2481 
2482     setsyx(y,x);
2483 
2484     Py_INCREF(Py_None);
2485     return Py_None;
2486 }
2487 #endif
2488 
2489 static PyObject *
PyCurses_Start_Color(PyObject * self)2490 PyCurses_Start_Color(PyObject *self)
2491 {
2492     int code;
2493     PyObject *c, *cp;
2494 
2495     PyCursesInitialised;
2496 
2497     code = start_color();
2498     if (code != ERR) {
2499         initialisedcolors = TRUE;
2500         c = PyInt_FromLong((long) COLORS);
2501         PyDict_SetItemString(ModDict, "COLORS", c);
2502         Py_DECREF(c);
2503         cp = PyInt_FromLong((long) COLOR_PAIRS);
2504         PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp);
2505         Py_DECREF(cp);
2506         Py_INCREF(Py_None);
2507         return Py_None;
2508     } else {
2509         PyErr_SetString(PyCursesError, "start_color() returned ERR");
2510         return NULL;
2511     }
2512 }
2513 
2514 static PyObject *
PyCurses_tigetflag(PyObject * self,PyObject * args)2515 PyCurses_tigetflag(PyObject *self, PyObject *args)
2516 {
2517     char *capname;
2518 
2519     PyCursesSetupTermCalled;
2520 
2521     if (!PyArg_ParseTuple(args, "s", &capname))
2522         return NULL;
2523 
2524     return PyInt_FromLong( (long) tigetflag( capname ) );
2525 }
2526 
2527 static PyObject *
PyCurses_tigetnum(PyObject * self,PyObject * args)2528 PyCurses_tigetnum(PyObject *self, PyObject *args)
2529 {
2530     char *capname;
2531 
2532     PyCursesSetupTermCalled;
2533 
2534     if (!PyArg_ParseTuple(args, "s", &capname))
2535         return NULL;
2536 
2537     return PyInt_FromLong( (long) tigetnum( capname ) );
2538 }
2539 
2540 static PyObject *
PyCurses_tigetstr(PyObject * self,PyObject * args)2541 PyCurses_tigetstr(PyObject *self, PyObject *args)
2542 {
2543     char *capname;
2544 
2545     PyCursesSetupTermCalled;
2546 
2547     if (!PyArg_ParseTuple(args, "s", &capname))
2548         return NULL;
2549 
2550     capname = tigetstr( capname );
2551     if (capname == 0 || capname == (char*) -1) {
2552         Py_INCREF(Py_None);
2553         return Py_None;
2554     }
2555     return PyString_FromString( capname );
2556 }
2557 
2558 static PyObject *
PyCurses_tparm(PyObject * self,PyObject * args)2559 PyCurses_tparm(PyObject *self, PyObject *args)
2560 {
2561     char* fmt;
2562     char* result = NULL;
2563     int i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0,i8=0,i9=0;
2564 
2565     PyCursesSetupTermCalled;
2566 
2567     if (!PyArg_ParseTuple(args, "s|iiiiiiiii:tparm",
2568                           &fmt, &i1, &i2, &i3, &i4,
2569                           &i5, &i6, &i7, &i8, &i9)) {
2570         return NULL;
2571     }
2572 
2573     result = tparm(fmt,i1,i2,i3,i4,i5,i6,i7,i8,i9);
2574     if (!result) {
2575         PyErr_SetString(PyCursesError, "tparm() returned NULL");
2576         return NULL;
2577     }
2578 
2579     return PyString_FromString(result);
2580 }
2581 
2582 #ifdef HAVE_CURSES_TYPEAHEAD
2583 static PyObject *
PyCurses_TypeAhead(PyObject * self,PyObject * args)2584 PyCurses_TypeAhead(PyObject *self, PyObject *args)
2585 {
2586     int fd;
2587 
2588     PyCursesInitialised;
2589 
2590     if (!PyArg_ParseTuple(args,"i;fd",&fd)) return NULL;
2591 
2592     return PyCursesCheckERR(typeahead( fd ), "typeahead");
2593 }
2594 #endif
2595 
2596 static PyObject *
PyCurses_UnCtrl(PyObject * self,PyObject * args)2597 PyCurses_UnCtrl(PyObject *self, PyObject *args)
2598 {
2599     PyObject *temp;
2600     chtype ch;
2601 
2602     PyCursesInitialised;
2603 
2604     if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL;
2605 
2606     if (_PyAnyInt_Check(temp)) {
2607         ch = (chtype) PyInt_AsLong(temp);
2608         if (ch == (chtype) -1 && PyErr_Occurred())
2609             return NULL;
2610     }
2611     else if (PyString_Check(temp))
2612         ch = (chtype) *PyString_AsString(temp);
2613     else {
2614         PyErr_SetString(PyExc_TypeError, "argument must be a ch or an int");
2615         return NULL;
2616     }
2617 
2618     return PyString_FromString(unctrl(ch));
2619 }
2620 
2621 static PyObject *
PyCurses_UngetCh(PyObject * self,PyObject * args)2622 PyCurses_UngetCh(PyObject *self, PyObject *args)
2623 {
2624     PyObject *temp;
2625     int ch;
2626 
2627     PyCursesInitialised;
2628 
2629     if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL;
2630 
2631     if (_PyAnyInt_Check(temp)) {
2632         ch = (int) PyInt_AsLong(temp);
2633         if (ch == -1 && PyErr_Occurred())
2634             return NULL;
2635     }
2636     else if (PyString_Check(temp))
2637         ch = (int) *PyString_AsString(temp);
2638     else {
2639         PyErr_SetString(PyExc_TypeError, "argument must be a ch or an int");
2640         return NULL;
2641     }
2642 
2643     return PyCursesCheckERR(ungetch(ch), "ungetch");
2644 }
2645 
2646 #ifdef HAVE_CURSES_TYPEAHEAD
2647 static PyObject *
PyCurses_Use_Env(PyObject * self,PyObject * args)2648 PyCurses_Use_Env(PyObject *self, PyObject *args)
2649 {
2650     int flag;
2651 
2652     switch(PyTuple_Size(args)) {
2653     case 1:
2654         if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&flag))
2655             return NULL;
2656         break;
2657     default:
2658         PyErr_SetString(PyExc_TypeError, "use_env requires 1 argument");
2659         return NULL;
2660     }
2661     use_env(flag);
2662     Py_INCREF(Py_None);
2663     return Py_None;
2664 }
2665 #endif
2666 
2667 #ifndef STRICT_SYSV_CURSES
2668 static PyObject *
PyCurses_Use_Default_Colors(PyObject * self)2669 PyCurses_Use_Default_Colors(PyObject *self)
2670 {
2671     int code;
2672 
2673     PyCursesInitialised;
2674     PyCursesInitialisedColor;
2675 
2676     code = use_default_colors();
2677     if (code != ERR) {
2678         Py_INCREF(Py_None);
2679         return Py_None;
2680     } else {
2681         PyErr_SetString(PyCursesError, "use_default_colors() returned ERR");
2682         return NULL;
2683     }
2684 }
2685 #endif /* STRICT_SYSV_CURSES */
2686 
2687 /* List of functions defined in the module */
2688 
2689 static PyMethodDef PyCurses_methods[] = {
2690     {"baudrate",            (PyCFunction)PyCurses_baudrate, METH_NOARGS},
2691     {"beep",                (PyCFunction)PyCurses_beep, METH_NOARGS},
2692     {"can_change_color",    (PyCFunction)PyCurses_can_change_color, METH_NOARGS},
2693     {"cbreak",              (PyCFunction)PyCurses_cbreak, METH_VARARGS},
2694     {"color_content",       (PyCFunction)PyCurses_Color_Content, METH_VARARGS},
2695     {"color_pair",          (PyCFunction)PyCurses_color_pair, METH_VARARGS},
2696     {"curs_set",            (PyCFunction)PyCurses_Curs_Set, METH_VARARGS},
2697     {"def_prog_mode",       (PyCFunction)PyCurses_def_prog_mode, METH_NOARGS},
2698     {"def_shell_mode",      (PyCFunction)PyCurses_def_shell_mode, METH_NOARGS},
2699     {"delay_output",        (PyCFunction)PyCurses_Delay_Output, METH_VARARGS},
2700     {"doupdate",            (PyCFunction)PyCurses_doupdate, METH_NOARGS},
2701     {"echo",                (PyCFunction)PyCurses_echo, METH_VARARGS},
2702     {"endwin",              (PyCFunction)PyCurses_endwin, METH_NOARGS},
2703     {"erasechar",           (PyCFunction)PyCurses_EraseChar, METH_NOARGS},
2704 #ifdef HAVE_CURSES_FILTER
2705     {"filter",              (PyCFunction)PyCurses_filter, METH_NOARGS},
2706 #endif
2707     {"flash",               (PyCFunction)PyCurses_flash, METH_NOARGS},
2708     {"flushinp",            (PyCFunction)PyCurses_flushinp, METH_NOARGS},
2709 #ifdef NCURSES_MOUSE_VERSION
2710     {"getmouse",            (PyCFunction)PyCurses_GetMouse, METH_NOARGS},
2711     {"ungetmouse",          (PyCFunction)PyCurses_UngetMouse, METH_VARARGS},
2712 #endif
2713 #ifdef getsyx
2714     {"getsyx",              (PyCFunction)PyCurses_getsyx, METH_NOARGS},
2715 #endif
2716     {"getwin",              (PyCFunction)PyCurses_GetWin, METH_O},
2717     {"has_colors",          (PyCFunction)PyCurses_has_colors, METH_NOARGS},
2718     {"has_ic",              (PyCFunction)PyCurses_has_ic, METH_NOARGS},
2719     {"has_il",              (PyCFunction)PyCurses_has_il, METH_NOARGS},
2720 #ifdef HAVE_CURSES_HAS_KEY
2721     {"has_key",             (PyCFunction)PyCurses_has_key, METH_VARARGS},
2722 #endif
2723     {"halfdelay",           (PyCFunction)PyCurses_HalfDelay, METH_VARARGS},
2724     {"init_color",          (PyCFunction)PyCurses_Init_Color, METH_VARARGS},
2725     {"init_pair",           (PyCFunction)PyCurses_Init_Pair, METH_VARARGS},
2726     {"initscr",             (PyCFunction)PyCurses_InitScr, METH_NOARGS},
2727     {"intrflush",           (PyCFunction)PyCurses_IntrFlush, METH_VARARGS},
2728     {"isendwin",            (PyCFunction)PyCurses_isendwin, METH_NOARGS},
2729 #ifdef HAVE_CURSES_IS_TERM_RESIZED
2730     {"is_term_resized",     (PyCFunction)PyCurses_Is_Term_Resized, METH_VARARGS},
2731 #endif
2732     {"keyname",             (PyCFunction)PyCurses_KeyName, METH_VARARGS},
2733     {"killchar",            (PyCFunction)PyCurses_KillChar, METH_NOARGS},
2734     {"longname",            (PyCFunction)PyCurses_longname, METH_NOARGS},
2735     {"meta",                (PyCFunction)PyCurses_Meta, METH_VARARGS},
2736 #ifdef NCURSES_MOUSE_VERSION
2737     {"mouseinterval",       (PyCFunction)PyCurses_MouseInterval, METH_VARARGS},
2738     {"mousemask",           (PyCFunction)PyCurses_MouseMask, METH_VARARGS},
2739 #endif
2740     {"napms",               (PyCFunction)PyCurses_Napms, METH_VARARGS},
2741     {"newpad",              (PyCFunction)PyCurses_NewPad, METH_VARARGS},
2742     {"newwin",              (PyCFunction)PyCurses_NewWindow, METH_VARARGS},
2743     {"nl",                  (PyCFunction)PyCurses_nl, METH_VARARGS},
2744     {"nocbreak",            (PyCFunction)PyCurses_nocbreak, METH_NOARGS},
2745     {"noecho",              (PyCFunction)PyCurses_noecho, METH_NOARGS},
2746     {"nonl",                (PyCFunction)PyCurses_nonl, METH_NOARGS},
2747     {"noqiflush",           (PyCFunction)PyCurses_noqiflush, METH_NOARGS},
2748     {"noraw",               (PyCFunction)PyCurses_noraw, METH_NOARGS},
2749     {"pair_content",        (PyCFunction)PyCurses_Pair_Content, METH_VARARGS},
2750     {"pair_number",         (PyCFunction)PyCurses_pair_number, METH_VARARGS},
2751     {"putp",                (PyCFunction)PyCurses_Putp, METH_VARARGS},
2752     {"qiflush",             (PyCFunction)PyCurses_QiFlush, METH_VARARGS},
2753     {"raw",                 (PyCFunction)PyCurses_raw, METH_VARARGS},
2754     {"reset_prog_mode",     (PyCFunction)PyCurses_reset_prog_mode, METH_NOARGS},
2755     {"reset_shell_mode",    (PyCFunction)PyCurses_reset_shell_mode, METH_NOARGS},
2756     {"resetty",             (PyCFunction)PyCurses_resetty, METH_NOARGS},
2757 #ifdef HAVE_CURSES_RESIZETERM
2758     {"resizeterm",          (PyCFunction)PyCurses_ResizeTerm, METH_VARARGS},
2759 #endif
2760 #ifdef HAVE_CURSES_RESIZE_TERM
2761     {"resize_term",         (PyCFunction)PyCurses_Resize_Term, METH_VARARGS},
2762 #endif
2763     {"savetty",             (PyCFunction)PyCurses_savetty, METH_NOARGS},
2764 #ifdef getsyx
2765     {"setsyx",              (PyCFunction)PyCurses_setsyx, METH_VARARGS},
2766 #endif
2767     {"setupterm",           (PyCFunction)PyCurses_setupterm,
2768      METH_VARARGS|METH_KEYWORDS},
2769     {"start_color",         (PyCFunction)PyCurses_Start_Color, METH_NOARGS},
2770     {"termattrs",           (PyCFunction)PyCurses_termattrs, METH_NOARGS},
2771     {"termname",            (PyCFunction)PyCurses_termname, METH_NOARGS},
2772     {"tigetflag",           (PyCFunction)PyCurses_tigetflag, METH_VARARGS},
2773     {"tigetnum",            (PyCFunction)PyCurses_tigetnum, METH_VARARGS},
2774     {"tigetstr",            (PyCFunction)PyCurses_tigetstr, METH_VARARGS},
2775     {"tparm",               (PyCFunction)PyCurses_tparm, METH_VARARGS},
2776 #ifdef HAVE_CURSES_TYPEAHEAD
2777     {"typeahead",           (PyCFunction)PyCurses_TypeAhead, METH_VARARGS},
2778 #endif
2779     {"unctrl",              (PyCFunction)PyCurses_UnCtrl, METH_VARARGS},
2780     {"ungetch",             (PyCFunction)PyCurses_UngetCh, METH_VARARGS},
2781 #ifdef HAVE_CURSES_USE_ENV
2782     {"use_env",             (PyCFunction)PyCurses_Use_Env, METH_VARARGS},
2783 #endif
2784 #ifndef STRICT_SYSV_CURSES
2785     {"use_default_colors",  (PyCFunction)PyCurses_Use_Default_Colors, METH_NOARGS},
2786 #endif
2787     {NULL,                  NULL}         /* sentinel */
2788 };
2789 
2790 /* Initialization function for the module */
2791 
2792 PyMODINIT_FUNC
init_curses(void)2793 init_curses(void)
2794 {
2795     PyObject *m, *d, *v, *c_api_object;
2796     static void *PyCurses_API[PyCurses_API_pointers];
2797 
2798     /* Initialize object type */
2799     Py_TYPE(&PyCursesWindow_Type) = &PyType_Type;
2800 
2801     /* Initialize the C API pointer array */
2802     PyCurses_API[0] = (void *)&PyCursesWindow_Type;
2803     PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled;
2804     PyCurses_API[2] = (void *)func_PyCursesInitialised;
2805     PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
2806 
2807     /* Create the module and add the functions */
2808     m = Py_InitModule("_curses", PyCurses_methods);
2809     if (m == NULL)
2810         return;
2811 
2812     /* Add some symbolic constants to the module */
2813     d = PyModule_GetDict(m);
2814     if (d == NULL)
2815         return;
2816     ModDict = d; /* For PyCurses_InitScr to use later */
2817 
2818     /* Add a capsule for the C API */
2819     c_api_object = PyCapsule_New(PyCurses_API, PyCurses_CAPSULE_NAME, NULL);
2820     PyDict_SetItemString(d, "_C_API", c_api_object);
2821     Py_DECREF(c_api_object);
2822 
2823     /* For exception curses.error */
2824     PyCursesError = PyErr_NewException("_curses.error", NULL, NULL);
2825     PyDict_SetItemString(d, "error", PyCursesError);
2826 
2827     /* Make the version available */
2828     v = PyString_FromString(PyCursesVersion);
2829     PyDict_SetItemString(d, "version", v);
2830     PyDict_SetItemString(d, "__version__", v);
2831     Py_DECREF(v);
2832 
2833     SetDictInt("ERR", ERR);
2834     SetDictInt("OK", OK);
2835 
2836     /* Here are some attributes you can add to chars to print */
2837 
2838     SetDictInt("A_ATTRIBUTES",      A_ATTRIBUTES);
2839     SetDictInt("A_NORMAL",              A_NORMAL);
2840     SetDictInt("A_STANDOUT",            A_STANDOUT);
2841     SetDictInt("A_UNDERLINE",           A_UNDERLINE);
2842     SetDictInt("A_REVERSE",             A_REVERSE);
2843     SetDictInt("A_BLINK",               A_BLINK);
2844     SetDictInt("A_DIM",                 A_DIM);
2845     SetDictInt("A_BOLD",                A_BOLD);
2846     SetDictInt("A_ALTCHARSET",          A_ALTCHARSET);
2847     SetDictInt("A_INVIS",           A_INVIS);
2848     SetDictInt("A_PROTECT",         A_PROTECT);
2849     SetDictInt("A_CHARTEXT",        A_CHARTEXT);
2850     SetDictInt("A_COLOR",           A_COLOR);
2851 
2852     /* The following are never available with strict SYSV curses */
2853 #ifdef A_HORIZONTAL
2854     SetDictInt("A_HORIZONTAL",      A_HORIZONTAL);
2855 #endif
2856 #ifdef A_LEFT
2857     SetDictInt("A_LEFT",            A_LEFT);
2858 #endif
2859 #ifdef A_LOW
2860     SetDictInt("A_LOW",             A_LOW);
2861 #endif
2862 #ifdef A_RIGHT
2863     SetDictInt("A_RIGHT",           A_RIGHT);
2864 #endif
2865 #ifdef A_TOP
2866     SetDictInt("A_TOP",             A_TOP);
2867 #endif
2868 #ifdef A_VERTICAL
2869     SetDictInt("A_VERTICAL",        A_VERTICAL);
2870 #endif
2871 
2872     SetDictInt("COLOR_BLACK",       COLOR_BLACK);
2873     SetDictInt("COLOR_RED",         COLOR_RED);
2874     SetDictInt("COLOR_GREEN",       COLOR_GREEN);
2875     SetDictInt("COLOR_YELLOW",      COLOR_YELLOW);
2876     SetDictInt("COLOR_BLUE",        COLOR_BLUE);
2877     SetDictInt("COLOR_MAGENTA",     COLOR_MAGENTA);
2878     SetDictInt("COLOR_CYAN",        COLOR_CYAN);
2879     SetDictInt("COLOR_WHITE",       COLOR_WHITE);
2880 
2881 #ifdef NCURSES_MOUSE_VERSION
2882     /* Mouse-related constants */
2883     SetDictInt("BUTTON1_PRESSED",          BUTTON1_PRESSED);
2884     SetDictInt("BUTTON1_RELEASED",         BUTTON1_RELEASED);
2885     SetDictInt("BUTTON1_CLICKED",          BUTTON1_CLICKED);
2886     SetDictInt("BUTTON1_DOUBLE_CLICKED",   BUTTON1_DOUBLE_CLICKED);
2887     SetDictInt("BUTTON1_TRIPLE_CLICKED",   BUTTON1_TRIPLE_CLICKED);
2888 
2889     SetDictInt("BUTTON2_PRESSED",          BUTTON2_PRESSED);
2890     SetDictInt("BUTTON2_RELEASED",         BUTTON2_RELEASED);
2891     SetDictInt("BUTTON2_CLICKED",          BUTTON2_CLICKED);
2892     SetDictInt("BUTTON2_DOUBLE_CLICKED",   BUTTON2_DOUBLE_CLICKED);
2893     SetDictInt("BUTTON2_TRIPLE_CLICKED",   BUTTON2_TRIPLE_CLICKED);
2894 
2895     SetDictInt("BUTTON3_PRESSED",          BUTTON3_PRESSED);
2896     SetDictInt("BUTTON3_RELEASED",         BUTTON3_RELEASED);
2897     SetDictInt("BUTTON3_CLICKED",          BUTTON3_CLICKED);
2898     SetDictInt("BUTTON3_DOUBLE_CLICKED",   BUTTON3_DOUBLE_CLICKED);
2899     SetDictInt("BUTTON3_TRIPLE_CLICKED",   BUTTON3_TRIPLE_CLICKED);
2900 
2901     SetDictInt("BUTTON4_PRESSED",          BUTTON4_PRESSED);
2902     SetDictInt("BUTTON4_RELEASED",         BUTTON4_RELEASED);
2903     SetDictInt("BUTTON4_CLICKED",          BUTTON4_CLICKED);
2904     SetDictInt("BUTTON4_DOUBLE_CLICKED",   BUTTON4_DOUBLE_CLICKED);
2905     SetDictInt("BUTTON4_TRIPLE_CLICKED",   BUTTON4_TRIPLE_CLICKED);
2906 
2907     SetDictInt("BUTTON_SHIFT",             BUTTON_SHIFT);
2908     SetDictInt("BUTTON_CTRL",              BUTTON_CTRL);
2909     SetDictInt("BUTTON_ALT",               BUTTON_ALT);
2910 
2911     SetDictInt("ALL_MOUSE_EVENTS",         ALL_MOUSE_EVENTS);
2912     SetDictInt("REPORT_MOUSE_POSITION",    REPORT_MOUSE_POSITION);
2913 #endif
2914     /* Now set everything up for KEY_ variables */
2915     {
2916         int key;
2917         char *key_n;
2918         char *key_n2;
2919         for (key=KEY_MIN;key < KEY_MAX; key++) {
2920             key_n = (char *)keyname(key);
2921             if (key_n == NULL || strcmp(key_n,"UNKNOWN KEY")==0)
2922                 continue;
2923             if (strncmp(key_n,"KEY_F(",6)==0) {
2924                 char *p1, *p2;
2925                 key_n2 = malloc(strlen(key_n)+1);
2926                 if (!key_n2) {
2927                     PyErr_NoMemory();
2928                     break;
2929                 }
2930                 p1 = key_n;
2931                 p2 = key_n2;
2932                 while (*p1) {
2933                     if (*p1 != '(' && *p1 != ')') {
2934                         *p2 = *p1;
2935                         p2++;
2936                     }
2937                     p1++;
2938                 }
2939                 *p2 = (char)0;
2940             } else
2941                 key_n2 = key_n;
2942             SetDictInt(key_n2,key);
2943             if (key_n2 != key_n)
2944                 free(key_n2);
2945         }
2946         SetDictInt("KEY_MIN", KEY_MIN);
2947         SetDictInt("KEY_MAX", KEY_MAX);
2948     }
2949 }
2950