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 <amk@amk.ca>.
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 #define PY_SSIZE_T_CLEAN
104
105 #include "Python.h"
106
107
108 #ifdef __hpux
109 #define STRICT_SYSV_CURSES
110 #endif
111
112 #define CURSES_MODULE
113 #include "py_curses.h"
114
115 /* These prototypes are in <term.h>, but including this header
116 #defines many common symbols (such as "lines") which breaks the
117 curses module in other ways. So the code will just specify
118 explicit prototypes here. */
119 extern int setupterm(char *,int,int *);
120 #ifdef __sgi
121 #include <term.h>
122 #endif
123
124 #ifdef HAVE_LANGINFO_H
125 #include <langinfo.h>
126 #endif
127
128 #if !defined(HAVE_NCURSES_H) && (defined(sgi) || defined(__sun) || defined(SCO5))
129 #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
130 typedef chtype attr_t; /* No attr_t type is available */
131 #endif
132
133 #if defined(_AIX)
134 #define STRICT_SYSV_CURSES
135 #endif
136
137 /*[clinic input]
138 module curses
139 class curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type"
140 [clinic start generated code]*/
141 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=88c860abdbb50e0c]*/
142
143 #include "clinic/_cursesmodule.c.h"
144
145 /* Definition of exception curses.error */
146
147 static PyObject *PyCursesError;
148
149 /* Tells whether setupterm() has been called to initialise terminfo. */
150 static int initialised_setupterm = FALSE;
151
152 /* Tells whether initscr() has been called to initialise curses. */
153 static int initialised = FALSE;
154
155 /* Tells whether start_color() has been called to initialise color usage. */
156 static int initialisedcolors = FALSE;
157
158 static char *screen_encoding = NULL;
159
160 /* Utility Macros */
161 #define PyCursesSetupTermCalled \
162 if (initialised_setupterm != TRUE) { \
163 PyErr_SetString(PyCursesError, \
164 "must call (at least) setupterm() first"); \
165 return 0; }
166
167 #define PyCursesInitialised \
168 if (initialised != TRUE) { \
169 PyErr_SetString(PyCursesError, \
170 "must call initscr() first"); \
171 return 0; }
172
173 #define PyCursesInitialisedColor \
174 if (initialisedcolors != TRUE) { \
175 PyErr_SetString(PyCursesError, \
176 "must call start_color() first"); \
177 return 0; }
178
179 /* Utility Functions */
180
181 /*
182 * Check the return code from a curses function and return None
183 * or raise an exception as appropriate. These are exported using the
184 * capsule API.
185 */
186
187 static PyObject *
PyCursesCheckERR(int code,const char * fname)188 PyCursesCheckERR(int code, const char *fname)
189 {
190 if (code != ERR) {
191 Py_INCREF(Py_None);
192 return Py_None;
193 } else {
194 if (fname == NULL) {
195 PyErr_SetString(PyCursesError, catchall_ERR);
196 } else {
197 PyErr_Format(PyCursesError, "%s() returned ERR", fname);
198 }
199 return NULL;
200 }
201 }
202
203 /* Convert an object to a byte (an integer of type chtype):
204
205 - int
206 - bytes of length 1
207 - str of length 1
208
209 Return 1 on success, 0 on error (invalid type or integer overflow). */
210 static int
PyCurses_ConvertToChtype(PyCursesWindowObject * win,PyObject * obj,chtype * ch)211 PyCurses_ConvertToChtype(PyCursesWindowObject *win, PyObject *obj, chtype *ch)
212 {
213 long value;
214 if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) {
215 value = (unsigned char)PyBytes_AsString(obj)[0];
216 }
217 else if (PyUnicode_Check(obj)) {
218 if (PyUnicode_GetLength(obj) != 1) {
219 PyErr_Format(PyExc_TypeError,
220 "expect bytes or str of length 1, or int, "
221 "got a str of length %zi",
222 PyUnicode_GET_LENGTH(obj));
223 return 0;
224 }
225 value = PyUnicode_READ_CHAR(obj, 0);
226 if (128 < value) {
227 PyObject *bytes;
228 const char *encoding;
229 if (win)
230 encoding = win->encoding;
231 else
232 encoding = screen_encoding;
233 bytes = PyUnicode_AsEncodedString(obj, encoding, NULL);
234 if (bytes == NULL)
235 return 0;
236 if (PyBytes_GET_SIZE(bytes) == 1)
237 value = (unsigned char)PyBytes_AS_STRING(bytes)[0];
238 else
239 value = -1;
240 Py_DECREF(bytes);
241 if (value < 0)
242 goto overflow;
243 }
244 }
245 else if (PyLong_CheckExact(obj)) {
246 int long_overflow;
247 value = PyLong_AsLongAndOverflow(obj, &long_overflow);
248 if (long_overflow)
249 goto overflow;
250 }
251 else {
252 PyErr_Format(PyExc_TypeError,
253 "expect bytes or str of length 1, or int, got %s",
254 Py_TYPE(obj)->tp_name);
255 return 0;
256 }
257 *ch = (chtype)value;
258 if ((long)*ch != value)
259 goto overflow;
260 return 1;
261
262 overflow:
263 PyErr_SetString(PyExc_OverflowError,
264 "byte doesn't fit in chtype");
265 return 0;
266 }
267
268 /* Convert an object to a byte (chtype) or a character (cchar_t):
269
270 - int
271 - bytes of length 1
272 - str of length 1
273
274 Return:
275
276 - 2 if obj is a character (written into *wch)
277 - 1 if obj is a byte (written into *ch)
278 - 0 on error: raise an exception */
279 static int
PyCurses_ConvertToCchar_t(PyCursesWindowObject * win,PyObject * obj,chtype * ch,wchar_t * wch)280 PyCurses_ConvertToCchar_t(PyCursesWindowObject *win, PyObject *obj,
281 chtype *ch
282 #ifdef HAVE_NCURSESW
283 , wchar_t *wch
284 #endif
285 )
286 {
287 long value;
288 #ifdef HAVE_NCURSESW
289 wchar_t buffer[2];
290 #endif
291
292 if (PyUnicode_Check(obj)) {
293 #ifdef HAVE_NCURSESW
294 if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) {
295 PyErr_Format(PyExc_TypeError,
296 "expect bytes or str of length 1, or int, "
297 "got a str of length %zi",
298 PyUnicode_GET_LENGTH(obj));
299 return 0;
300 }
301 *wch = buffer[0];
302 return 2;
303 #else
304 return PyCurses_ConvertToChtype(win, obj, ch);
305 #endif
306 }
307 else if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) {
308 value = (unsigned char)PyBytes_AsString(obj)[0];
309 }
310 else if (PyLong_CheckExact(obj)) {
311 int overflow;
312 value = PyLong_AsLongAndOverflow(obj, &overflow);
313 if (overflow) {
314 PyErr_SetString(PyExc_OverflowError,
315 "int doesn't fit in long");
316 return 0;
317 }
318 }
319 else {
320 PyErr_Format(PyExc_TypeError,
321 "expect bytes or str of length 1, or int, got %s",
322 Py_TYPE(obj)->tp_name);
323 return 0;
324 }
325
326 *ch = (chtype)value;
327 if ((long)*ch != value) {
328 PyErr_Format(PyExc_OverflowError,
329 "byte doesn't fit in chtype");
330 return 0;
331 }
332 return 1;
333 }
334
335 /* Convert an object to a byte string (char*) or a wide character string
336 (wchar_t*). Return:
337
338 - 2 if obj is a character string (written into *wch)
339 - 1 if obj is a byte string (written into *bytes)
340 - 0 on error: raise an exception */
341 static int
PyCurses_ConvertToString(PyCursesWindowObject * win,PyObject * obj,PyObject ** bytes,wchar_t ** wstr)342 PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj,
343 PyObject **bytes, wchar_t **wstr)
344 {
345 if (PyUnicode_Check(obj)) {
346 #ifdef HAVE_NCURSESW
347 assert (wstr != NULL);
348 *wstr = PyUnicode_AsWideCharString(obj, NULL);
349 if (*wstr == NULL)
350 return 0;
351 return 2;
352 #else
353 assert (wstr == NULL);
354 *bytes = PyUnicode_AsEncodedString(obj, win->encoding, NULL);
355 if (*bytes == NULL)
356 return 0;
357 return 1;
358 #endif
359 }
360 else if (PyBytes_Check(obj)) {
361 Py_INCREF(obj);
362 *bytes = obj;
363 return 1;
364 }
365
366 PyErr_Format(PyExc_TypeError, "expect bytes or str, got %s",
367 Py_TYPE(obj)->tp_name);
368 return 0;
369 }
370
371 /* Function versions of the 3 functions for testing whether curses has been
372 initialised or not. */
373
func_PyCursesSetupTermCalled(void)374 static int func_PyCursesSetupTermCalled(void)
375 {
376 PyCursesSetupTermCalled;
377 return 1;
378 }
379
func_PyCursesInitialised(void)380 static int func_PyCursesInitialised(void)
381 {
382 PyCursesInitialised;
383 return 1;
384 }
385
func_PyCursesInitialisedColor(void)386 static int func_PyCursesInitialisedColor(void)
387 {
388 PyCursesInitialisedColor;
389 return 1;
390 }
391
392 /*****************************************************************************
393 The Window Object
394 ******************************************************************************/
395
396 /* Definition of the window type */
397
398 PyTypeObject PyCursesWindow_Type;
399
400 /* Function prototype macros for Window object
401
402 X - function name
403 TYPE - parameter Type
404 ERGSTR - format string for construction of the return value
405 PARSESTR - format string for argument parsing
406 */
407
408 #define Window_NoArgNoReturnFunction(X) \
409 static PyObject *PyCursesWindow_ ## X \
410 (PyCursesWindowObject *self, PyObject *args) \
411 { return PyCursesCheckERR(X(self->win), # X); }
412
413 #define Window_NoArgTrueFalseFunction(X) \
414 static PyObject * PyCursesWindow_ ## X \
415 (PyCursesWindowObject *self) \
416 { \
417 if (X (self->win) == FALSE) { Py_INCREF(Py_False); return Py_False; } \
418 else { Py_INCREF(Py_True); return Py_True; } }
419
420 #define Window_NoArgNoReturnVoidFunction(X) \
421 static PyObject * PyCursesWindow_ ## X \
422 (PyCursesWindowObject *self) \
423 { \
424 X(self->win); Py_INCREF(Py_None); return Py_None; }
425
426 #define Window_NoArg2TupleReturnFunction(X, TYPE, ERGSTR) \
427 static PyObject * PyCursesWindow_ ## X \
428 (PyCursesWindowObject *self) \
429 { \
430 TYPE arg1, arg2; \
431 X(self->win,arg1,arg2); return Py_BuildValue(ERGSTR, arg1, arg2); }
432
433 #define Window_OneArgNoReturnVoidFunction(X, TYPE, PARSESTR) \
434 static PyObject * PyCursesWindow_ ## X \
435 (PyCursesWindowObject *self, PyObject *args) \
436 { \
437 TYPE arg1; \
438 if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) return NULL; \
439 X(self->win,arg1); Py_INCREF(Py_None); return Py_None; }
440
441 #define Window_OneArgNoReturnFunction(X, TYPE, PARSESTR) \
442 static PyObject * PyCursesWindow_ ## X \
443 (PyCursesWindowObject *self, PyObject *args) \
444 { \
445 TYPE arg1; \
446 if (!PyArg_ParseTuple(args,PARSESTR, &arg1)) return NULL; \
447 return PyCursesCheckERR(X(self->win, arg1), # X); }
448
449 #define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \
450 static PyObject * PyCursesWindow_ ## X \
451 (PyCursesWindowObject *self, PyObject *args) \
452 { \
453 TYPE arg1, arg2; \
454 if (!PyArg_ParseTuple(args,PARSESTR, &arg1, &arg2)) return NULL; \
455 return PyCursesCheckERR(X(self->win, arg1, arg2), # X); }
456
457 /* ------------- WINDOW routines --------------- */
458
459 Window_NoArgNoReturnFunction(untouchwin)
Window_NoArgNoReturnFunction(touchwin)460 Window_NoArgNoReturnFunction(touchwin)
461 Window_NoArgNoReturnFunction(redrawwin)
462 Window_NoArgNoReturnFunction(winsertln)
463 Window_NoArgNoReturnFunction(werase)
464 Window_NoArgNoReturnFunction(wdeleteln)
465
466 Window_NoArgTrueFalseFunction(is_wintouched)
467
468 Window_NoArgNoReturnVoidFunction(wsyncup)
469 Window_NoArgNoReturnVoidFunction(wsyncdown)
470 Window_NoArgNoReturnVoidFunction(wstandend)
471 Window_NoArgNoReturnVoidFunction(wstandout)
472 Window_NoArgNoReturnVoidFunction(wcursyncup)
473 Window_NoArgNoReturnVoidFunction(wclrtoeol)
474 Window_NoArgNoReturnVoidFunction(wclrtobot)
475 Window_NoArgNoReturnVoidFunction(wclear)
476
477 Window_OneArgNoReturnVoidFunction(idcok, int, "i;True(1) or False(0)")
478 Window_OneArgNoReturnVoidFunction(immedok, int, "i;True(1) or False(0)")
479 Window_OneArgNoReturnVoidFunction(wtimeout, int, "i;delay")
480
481 Window_NoArg2TupleReturnFunction(getyx, int, "ii")
482 Window_NoArg2TupleReturnFunction(getbegyx, int, "ii")
483 Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii")
484 Window_NoArg2TupleReturnFunction(getparyx, int, "ii")
485
486 Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)")
487 Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)")
488 #if defined(__NetBSD__)
489 Window_OneArgNoReturnVoidFunction(keypad, int, "i;True(1) or False(0)")
490 #else
491 Window_OneArgNoReturnFunction(keypad, int, "i;True(1) or False(0)")
492 #endif
493 Window_OneArgNoReturnFunction(leaveok, int, "i;True(1) or False(0)")
494 #if defined(__NetBSD__)
495 Window_OneArgNoReturnVoidFunction(nodelay, int, "i;True(1) or False(0)")
496 #else
497 Window_OneArgNoReturnFunction(nodelay, int, "i;True(1) or False(0)")
498 #endif
499 Window_OneArgNoReturnFunction(notimeout, int, "i;True(1) or False(0)")
500 Window_OneArgNoReturnFunction(scrollok, int, "i;True(1) or False(0)")
501 Window_OneArgNoReturnFunction(winsdelln, int, "i;nlines")
502 Window_OneArgNoReturnFunction(syncok, int, "i;True(1) or False(0)")
503
504 Window_TwoArgNoReturnFunction(mvwin, int, "ii;y,x")
505 Window_TwoArgNoReturnFunction(mvderwin, int, "ii;y,x")
506 Window_TwoArgNoReturnFunction(wmove, int, "ii;y,x")
507 #ifndef STRICT_SYSV_CURSES
508 Window_TwoArgNoReturnFunction(wresize, int, "ii;lines,columns")
509 #endif
510
511 /* Allocation and deallocation of Window Objects */
512
513 static PyObject *
514 PyCursesWindow_New(WINDOW *win, const char *encoding)
515 {
516 PyCursesWindowObject *wo;
517
518 if (encoding == NULL) {
519 #if defined(MS_WINDOWS)
520 char *buffer[100];
521 UINT cp;
522 cp = GetConsoleOutputCP();
523 if (cp != 0) {
524 PyOS_snprintf(buffer, sizeof(buffer), "cp%u", cp);
525 encoding = buffer;
526 }
527 #elif defined(CODESET)
528 const char *codeset = nl_langinfo(CODESET);
529 if (codeset != NULL && codeset[0] != 0)
530 encoding = codeset;
531 #endif
532 if (encoding == NULL)
533 encoding = "utf-8";
534 }
535
536 wo = PyObject_NEW(PyCursesWindowObject, &PyCursesWindow_Type);
537 if (wo == NULL) return NULL;
538 wo->win = win;
539 wo->encoding = _PyMem_Strdup(encoding);
540 if (wo->encoding == NULL) {
541 Py_DECREF(wo);
542 PyErr_NoMemory();
543 return NULL;
544 }
545 return (PyObject *)wo;
546 }
547
548 static void
PyCursesWindow_Dealloc(PyCursesWindowObject * wo)549 PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
550 {
551 if (wo->win != stdscr) delwin(wo->win);
552 if (wo->encoding != NULL)
553 PyMem_Free(wo->encoding);
554 PyObject_DEL(wo);
555 }
556
557 /* Addch, Addstr, Addnstr */
558
559 /*[clinic input]
560
561 curses.window.addch
562
563 [
564 y: int
565 Y-coordinate.
566 x: int
567 X-coordinate.
568 ]
569
570 ch: object
571 Character to add.
572
573 [
574 attr: long
575 Attributes for the character.
576 ]
577 /
578
579 Paint character ch at (y, x) with attributes attr.
580
581 Paint character ch at (y, x) with attributes attr,
582 overwriting any character previously painted at that location.
583 By default, the character position and attributes are the
584 current settings for the window object.
585 [clinic start generated code]*/
586
587 static PyObject *
curses_window_addch_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * ch,int group_right_1,long attr)588 curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y,
589 int x, PyObject *ch, int group_right_1, long attr)
590 /*[clinic end generated code: output=99f7f85078ec06c3 input=5a41efb34a2de338]*/
591 {
592 PyCursesWindowObject *cwself = (PyCursesWindowObject *)self;
593 int coordinates_group = group_left_1;
594 int attr_group = group_right_1;
595 int rtn;
596 int type;
597 chtype cch;
598 #ifdef HAVE_NCURSESW
599 wchar_t wstr[2];
600 cchar_t wcval;
601 #endif
602 const char *funcname;
603
604 if (!attr_group)
605 attr = A_NORMAL;
606
607 #ifdef HAVE_NCURSESW
608 type = PyCurses_ConvertToCchar_t(cwself, ch, &cch, wstr);
609 if (type == 2) {
610 funcname = "add_wch";
611 wstr[1] = L'\0';
612 setcchar(&wcval, wstr, attr, 0, NULL);
613 if (coordinates_group)
614 rtn = mvwadd_wch(cwself->win,y,x, &wcval);
615 else {
616 rtn = wadd_wch(cwself->win, &wcval);
617 }
618 }
619 else
620 #else
621 type = PyCurses_ConvertToCchar_t(cwself, ch, &cch);
622 #endif
623 if (type == 1) {
624 funcname = "addch";
625 if (coordinates_group)
626 rtn = mvwaddch(cwself->win,y,x, cch | attr);
627 else {
628 rtn = waddch(cwself->win, cch | attr);
629 }
630 }
631 else {
632 return NULL;
633 }
634 return PyCursesCheckERR(rtn, funcname);
635 }
636
637 static PyObject *
PyCursesWindow_AddStr(PyCursesWindowObject * self,PyObject * args)638 PyCursesWindow_AddStr(PyCursesWindowObject *self, PyObject *args)
639 {
640 int rtn;
641 int x, y;
642 int strtype;
643 PyObject *strobj, *bytesobj = NULL;
644 #ifdef HAVE_NCURSESW
645 wchar_t *wstr = NULL;
646 #endif
647 attr_t attr = A_NORMAL , attr_old = A_NORMAL;
648 long lattr;
649 int use_xy = FALSE, use_attr = FALSE;
650 const char *funcname;
651
652 switch (PyTuple_Size(args)) {
653 case 1:
654 if (!PyArg_ParseTuple(args,"O;str", &strobj))
655 return NULL;
656 break;
657 case 2:
658 if (!PyArg_ParseTuple(args,"Ol;str,attr", &strobj, &lattr))
659 return NULL;
660 attr = lattr;
661 use_attr = TRUE;
662 break;
663 case 3:
664 if (!PyArg_ParseTuple(args,"iiO;int,int,str", &y, &x, &strobj))
665 return NULL;
666 use_xy = TRUE;
667 break;
668 case 4:
669 if (!PyArg_ParseTuple(args,"iiOl;int,int,str,attr", &y, &x, &strobj, &lattr))
670 return NULL;
671 attr = lattr;
672 use_xy = use_attr = TRUE;
673 break;
674 default:
675 PyErr_SetString(PyExc_TypeError, "addstr requires 1 to 4 arguments");
676 return NULL;
677 }
678 #ifdef HAVE_NCURSESW
679 strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr);
680 #else
681 strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL);
682 #endif
683 if (strtype == 0)
684 return NULL;
685 if (use_attr == TRUE) {
686 attr_old = getattrs(self->win);
687 (void)wattrset(self->win,attr);
688 }
689 #ifdef HAVE_NCURSESW
690 if (strtype == 2) {
691 funcname = "addwstr";
692 if (use_xy == TRUE)
693 rtn = mvwaddwstr(self->win,y,x,wstr);
694 else
695 rtn = waddwstr(self->win,wstr);
696 PyMem_Free(wstr);
697 }
698 else
699 #endif
700 {
701 char *str = PyBytes_AS_STRING(bytesobj);
702 funcname = "addstr";
703 if (use_xy == TRUE)
704 rtn = mvwaddstr(self->win,y,x,str);
705 else
706 rtn = waddstr(self->win,str);
707 Py_DECREF(bytesobj);
708 }
709 if (use_attr == TRUE)
710 (void)wattrset(self->win,attr_old);
711 return PyCursesCheckERR(rtn, funcname);
712 }
713
714 static PyObject *
PyCursesWindow_AddNStr(PyCursesWindowObject * self,PyObject * args)715 PyCursesWindow_AddNStr(PyCursesWindowObject *self, PyObject *args)
716 {
717 int rtn, x, y, n;
718 int strtype;
719 PyObject *strobj, *bytesobj = NULL;
720 #ifdef HAVE_NCURSESW
721 wchar_t *wstr = NULL;
722 #endif
723 attr_t attr = A_NORMAL , attr_old = A_NORMAL;
724 long lattr;
725 int use_xy = FALSE, use_attr = FALSE;
726 const char *funcname;
727
728 switch (PyTuple_Size(args)) {
729 case 2:
730 if (!PyArg_ParseTuple(args,"Oi;str,n", &strobj, &n))
731 return NULL;
732 break;
733 case 3:
734 if (!PyArg_ParseTuple(args,"Oil;str,n,attr", &strobj, &n, &lattr))
735 return NULL;
736 attr = lattr;
737 use_attr = TRUE;
738 break;
739 case 4:
740 if (!PyArg_ParseTuple(args,"iiOi;y,x,str,n", &y, &x, &strobj, &n))
741 return NULL;
742 use_xy = TRUE;
743 break;
744 case 5:
745 if (!PyArg_ParseTuple(args,"iiOil;y,x,str,n,attr", &y, &x, &strobj, &n, &lattr))
746 return NULL;
747 attr = lattr;
748 use_xy = use_attr = TRUE;
749 break;
750 default:
751 PyErr_SetString(PyExc_TypeError, "addnstr requires 2 to 5 arguments");
752 return NULL;
753 }
754 #ifdef HAVE_NCURSESW
755 strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr);
756 #else
757 strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL);
758 #endif
759 if (strtype == 0)
760 return NULL;
761
762 if (use_attr == TRUE) {
763 attr_old = getattrs(self->win);
764 (void)wattrset(self->win,attr);
765 }
766 #ifdef HAVE_NCURSESW
767 if (strtype == 2) {
768 funcname = "addnwstr";
769 if (use_xy == TRUE)
770 rtn = mvwaddnwstr(self->win,y,x,wstr,n);
771 else
772 rtn = waddnwstr(self->win,wstr,n);
773 PyMem_Free(wstr);
774 }
775 else
776 #endif
777 {
778 char *str = PyBytes_AS_STRING(bytesobj);
779 funcname = "addnstr";
780 if (use_xy == TRUE)
781 rtn = mvwaddnstr(self->win,y,x,str,n);
782 else
783 rtn = waddnstr(self->win,str,n);
784 Py_DECREF(bytesobj);
785 }
786 if (use_attr == TRUE)
787 (void)wattrset(self->win,attr_old);
788 return PyCursesCheckERR(rtn, funcname);
789 }
790
791 static PyObject *
PyCursesWindow_Bkgd(PyCursesWindowObject * self,PyObject * args)792 PyCursesWindow_Bkgd(PyCursesWindowObject *self, PyObject *args)
793 {
794 PyObject *temp;
795 chtype bkgd;
796 attr_t attr = A_NORMAL;
797 long lattr;
798
799 switch (PyTuple_Size(args)) {
800 case 1:
801 if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
802 return NULL;
803 break;
804 case 2:
805 if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr))
806 return NULL;
807 attr = lattr;
808 break;
809 default:
810 PyErr_SetString(PyExc_TypeError, "bkgd requires 1 or 2 arguments");
811 return NULL;
812 }
813
814 if (!PyCurses_ConvertToChtype(self, temp, &bkgd))
815 return NULL;
816
817 return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd");
818 }
819
820 static PyObject *
PyCursesWindow_AttrOff(PyCursesWindowObject * self,PyObject * args)821 PyCursesWindow_AttrOff(PyCursesWindowObject *self, PyObject *args)
822 {
823 long lattr;
824 if (!PyArg_ParseTuple(args,"l;attr", &lattr))
825 return NULL;
826 return PyCursesCheckERR(wattroff(self->win, (attr_t)lattr), "attroff");
827 }
828
829 static PyObject *
PyCursesWindow_AttrOn(PyCursesWindowObject * self,PyObject * args)830 PyCursesWindow_AttrOn(PyCursesWindowObject *self, PyObject *args)
831 {
832 long lattr;
833 if (!PyArg_ParseTuple(args,"l;attr", &lattr))
834 return NULL;
835 return PyCursesCheckERR(wattron(self->win, (attr_t)lattr), "attron");
836 }
837
838 static PyObject *
PyCursesWindow_AttrSet(PyCursesWindowObject * self,PyObject * args)839 PyCursesWindow_AttrSet(PyCursesWindowObject *self, PyObject *args)
840 {
841 long lattr;
842 if (!PyArg_ParseTuple(args,"l;attr", &lattr))
843 return NULL;
844 return PyCursesCheckERR(wattrset(self->win, (attr_t)lattr), "attrset");
845 }
846
847 static PyObject *
PyCursesWindow_BkgdSet(PyCursesWindowObject * self,PyObject * args)848 PyCursesWindow_BkgdSet(PyCursesWindowObject *self, PyObject *args)
849 {
850 PyObject *temp;
851 chtype bkgd;
852 attr_t attr = A_NORMAL;
853 long lattr;
854
855 switch (PyTuple_Size(args)) {
856 case 1:
857 if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
858 return NULL;
859 break;
860 case 2:
861 if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr))
862 return NULL;
863 attr = lattr;
864 break;
865 default:
866 PyErr_SetString(PyExc_TypeError, "bkgdset requires 1 or 2 arguments");
867 return NULL;
868 }
869
870 if (!PyCurses_ConvertToChtype(self, temp, &bkgd))
871 return NULL;
872
873 wbkgdset(self->win, bkgd | attr);
874 return PyCursesCheckERR(0, "bkgdset");
875 }
876
877 static PyObject *
PyCursesWindow_Border(PyCursesWindowObject * self,PyObject * args)878 PyCursesWindow_Border(PyCursesWindowObject *self, PyObject *args)
879 {
880 PyObject *temp[8];
881 chtype ch[8];
882 int i;
883
884 /* Clear the array of parameters */
885 for(i=0; i<8; i++) {
886 temp[i] = NULL;
887 ch[i] = 0;
888 }
889
890 if (!PyArg_ParseTuple(args,"|OOOOOOOO;ls,rs,ts,bs,tl,tr,bl,br",
891 &temp[0], &temp[1], &temp[2], &temp[3],
892 &temp[4], &temp[5], &temp[6], &temp[7]))
893 return NULL;
894
895 for(i=0; i<8; i++) {
896 if (temp[i] != NULL && !PyCurses_ConvertToChtype(self, temp[i], &ch[i]))
897 return NULL;
898 }
899
900 wborder(self->win,
901 ch[0], ch[1], ch[2], ch[3],
902 ch[4], ch[5], ch[6], ch[7]);
903 Py_INCREF(Py_None);
904 return Py_None;
905 }
906
907 static PyObject *
PyCursesWindow_Box(PyCursesWindowObject * self,PyObject * args)908 PyCursesWindow_Box(PyCursesWindowObject *self, PyObject *args)
909 {
910 chtype ch1=0,ch2=0;
911 switch(PyTuple_Size(args)){
912 case 0: break;
913 default:
914 if (!PyArg_ParseTuple(args,"ll;vertint,horint", &ch1, &ch2))
915 return NULL;
916 }
917 box(self->win,ch1,ch2);
918 Py_INCREF(Py_None);
919 return Py_None;
920 }
921
922 #if defined(HAVE_NCURSES_H) || defined(MVWDELCH_IS_EXPRESSION)
923 #define py_mvwdelch mvwdelch
924 #else
py_mvwdelch(WINDOW * w,int y,int x)925 int py_mvwdelch(WINDOW *w, int y, int x)
926 {
927 mvwdelch(w,y,x);
928 /* On HP/UX, mvwdelch already returns. On other systems,
929 we may well run into this return statement. */
930 return 0;
931 }
932 #endif
933
934 /* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */
935
936 static PyObject *
PyCursesWindow_ChgAt(PyCursesWindowObject * self,PyObject * args)937 PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args)
938 {
939 int rtn;
940 int x, y;
941 int num = -1;
942 short color;
943 attr_t attr = A_NORMAL;
944 long lattr;
945 int use_xy = FALSE;
946
947 switch (PyTuple_Size(args)) {
948 case 1:
949 if (!PyArg_ParseTuple(args,"l;attr", &lattr))
950 return NULL;
951 attr = lattr;
952 break;
953 case 2:
954 if (!PyArg_ParseTuple(args,"il;n,attr", &num, &lattr))
955 return NULL;
956 attr = lattr;
957 break;
958 case 3:
959 if (!PyArg_ParseTuple(args,"iil;int,int,attr", &y, &x, &lattr))
960 return NULL;
961 attr = lattr;
962 use_xy = TRUE;
963 break;
964 case 4:
965 if (!PyArg_ParseTuple(args,"iiil;int,int,n,attr", &y, &x, &num, &lattr))
966 return NULL;
967 attr = lattr;
968 use_xy = TRUE;
969 break;
970 default:
971 PyErr_SetString(PyExc_TypeError, "chgat requires 1 to 4 arguments");
972 return NULL;
973 }
974
975 color = (short)((attr >> 8) & 0xff);
976 attr = attr - (color << 8);
977
978 if (use_xy == TRUE) {
979 rtn = mvwchgat(self->win,y,x,num,attr,color,NULL);
980 touchline(self->win,y,1);
981 } else {
982 getyx(self->win,y,x);
983 rtn = wchgat(self->win,num,attr,color,NULL);
984 touchline(self->win,y,1);
985 }
986 return PyCursesCheckERR(rtn, "chgat");
987 }
988
989
990 static PyObject *
PyCursesWindow_DelCh(PyCursesWindowObject * self,PyObject * args)991 PyCursesWindow_DelCh(PyCursesWindowObject *self, PyObject *args)
992 {
993 int rtn;
994 int x, y;
995
996 switch (PyTuple_Size(args)) {
997 case 0:
998 rtn = wdelch(self->win);
999 break;
1000 case 2:
1001 if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x))
1002 return NULL;
1003 rtn = py_mvwdelch(self->win,y,x);
1004 break;
1005 default:
1006 PyErr_SetString(PyExc_TypeError, "delch requires 0 or 2 arguments");
1007 return NULL;
1008 }
1009 return PyCursesCheckERR(rtn, "[mv]wdelch");
1010 }
1011
1012 static PyObject *
PyCursesWindow_DerWin(PyCursesWindowObject * self,PyObject * args)1013 PyCursesWindow_DerWin(PyCursesWindowObject *self, PyObject *args)
1014 {
1015 WINDOW *win;
1016 int nlines, ncols, begin_y, begin_x;
1017
1018 nlines = 0;
1019 ncols = 0;
1020 switch (PyTuple_Size(args)) {
1021 case 2:
1022 if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x))
1023 return NULL;
1024 break;
1025 case 4:
1026 if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
1027 &nlines,&ncols,&begin_y,&begin_x))
1028 return NULL;
1029 break;
1030 default:
1031 PyErr_SetString(PyExc_TypeError, "derwin requires 2 or 4 arguments");
1032 return NULL;
1033 }
1034
1035 win = derwin(self->win,nlines,ncols,begin_y,begin_x);
1036
1037 if (win == NULL) {
1038 PyErr_SetString(PyCursesError, catchall_NULL);
1039 return NULL;
1040 }
1041
1042 return (PyObject *)PyCursesWindow_New(win, NULL);
1043 }
1044
1045 static PyObject *
PyCursesWindow_EchoChar(PyCursesWindowObject * self,PyObject * args)1046 PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
1047 {
1048 PyObject *temp;
1049 chtype ch;
1050 attr_t attr = A_NORMAL;
1051 long lattr;
1052
1053 switch (PyTuple_Size(args)) {
1054 case 1:
1055 if (!PyArg_ParseTuple(args,"O;ch or int", &temp))
1056 return NULL;
1057 break;
1058 case 2:
1059 if (!PyArg_ParseTuple(args,"Ol;ch or int,attr", &temp, &lattr))
1060 return NULL;
1061 attr = lattr;
1062 break;
1063 default:
1064 PyErr_SetString(PyExc_TypeError, "echochar requires 1 or 2 arguments");
1065
1066
1067 return NULL;
1068 }
1069
1070 if (!PyCurses_ConvertToChtype(self, temp, &ch))
1071 return NULL;
1072
1073 #ifdef WINDOW_HAS_FLAGS
1074 if (self->win->_flags & _ISPAD)
1075 return PyCursesCheckERR(pechochar(self->win, ch | attr),
1076 "echochar");
1077 else
1078 #endif
1079 return PyCursesCheckERR(wechochar(self->win, ch | attr),
1080 "echochar");
1081 }
1082
1083 #ifdef NCURSES_MOUSE_VERSION
1084 static PyObject *
PyCursesWindow_Enclose(PyCursesWindowObject * self,PyObject * args)1085 PyCursesWindow_Enclose(PyCursesWindowObject *self, PyObject *args)
1086 {
1087 int x, y;
1088 if (!PyArg_ParseTuple(args,"ii;y,x", &y, &x))
1089 return NULL;
1090
1091 return PyLong_FromLong( wenclose(self->win,y,x) );
1092 }
1093 #endif
1094
1095 static PyObject *
PyCursesWindow_GetBkgd(PyCursesWindowObject * self)1096 PyCursesWindow_GetBkgd(PyCursesWindowObject *self)
1097 {
1098 return PyLong_FromLong((long) getbkgd(self->win));
1099 }
1100
1101 static PyObject *
PyCursesWindow_GetCh(PyCursesWindowObject * self,PyObject * args)1102 PyCursesWindow_GetCh(PyCursesWindowObject *self, PyObject *args)
1103 {
1104 int x, y;
1105 int rtn;
1106
1107 switch (PyTuple_Size(args)) {
1108 case 0:
1109 Py_BEGIN_ALLOW_THREADS
1110 rtn = wgetch(self->win);
1111 Py_END_ALLOW_THREADS
1112 break;
1113 case 2:
1114 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1115 return NULL;
1116 Py_BEGIN_ALLOW_THREADS
1117 rtn = mvwgetch(self->win,y,x);
1118 Py_END_ALLOW_THREADS
1119 break;
1120 default:
1121 PyErr_SetString(PyExc_TypeError, "getch requires 0 or 2 arguments");
1122 return NULL;
1123 }
1124 return PyLong_FromLong((long)rtn);
1125 }
1126
1127 static PyObject *
PyCursesWindow_GetKey(PyCursesWindowObject * self,PyObject * args)1128 PyCursesWindow_GetKey(PyCursesWindowObject *self, PyObject *args)
1129 {
1130 int x, y;
1131 int rtn;
1132
1133 switch (PyTuple_Size(args)) {
1134 case 0:
1135 Py_BEGIN_ALLOW_THREADS
1136 rtn = wgetch(self->win);
1137 Py_END_ALLOW_THREADS
1138 break;
1139 case 2:
1140 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1141 return NULL;
1142 Py_BEGIN_ALLOW_THREADS
1143 rtn = mvwgetch(self->win,y,x);
1144 Py_END_ALLOW_THREADS
1145 break;
1146 default:
1147 PyErr_SetString(PyExc_TypeError, "getkey requires 0 or 2 arguments");
1148 return NULL;
1149 }
1150 if (rtn == ERR) {
1151 /* getch() returns ERR in nodelay mode */
1152 PyErr_CheckSignals();
1153 if (!PyErr_Occurred())
1154 PyErr_SetString(PyCursesError, "no input");
1155 return NULL;
1156 } else if (rtn<=255) {
1157 return Py_BuildValue("C", rtn);
1158 } else {
1159 const char *knp;
1160 #if defined(__NetBSD__)
1161 knp = unctrl(rtn);
1162 #else
1163 knp = keyname(rtn);
1164 #endif
1165 return PyUnicode_FromString((knp == NULL) ? "" : knp);
1166 }
1167 }
1168
1169 #ifdef HAVE_NCURSESW
1170 static PyObject *
PyCursesWindow_Get_WCh(PyCursesWindowObject * self,PyObject * args)1171 PyCursesWindow_Get_WCh(PyCursesWindowObject *self, PyObject *args)
1172 {
1173 int x, y;
1174 int ct;
1175 wint_t rtn;
1176
1177 switch (PyTuple_Size(args)) {
1178 case 0:
1179 Py_BEGIN_ALLOW_THREADS
1180 ct = wget_wch(self->win,&rtn);
1181 Py_END_ALLOW_THREADS
1182 break;
1183 case 2:
1184 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1185 return NULL;
1186 Py_BEGIN_ALLOW_THREADS
1187 ct = mvwget_wch(self->win,y,x,&rtn);
1188 Py_END_ALLOW_THREADS
1189 break;
1190 default:
1191 PyErr_SetString(PyExc_TypeError, "get_wch requires 0 or 2 arguments");
1192 return NULL;
1193 }
1194 if (ct == ERR) {
1195 if (PyErr_CheckSignals())
1196 return NULL;
1197
1198 /* get_wch() returns ERR in nodelay mode */
1199 PyErr_SetString(PyCursesError, "no input");
1200 return NULL;
1201 }
1202 if (ct == KEY_CODE_YES)
1203 return PyLong_FromLong(rtn);
1204 else
1205 return PyUnicode_FromOrdinal(rtn);
1206 }
1207 #endif
1208
1209 static PyObject *
PyCursesWindow_GetStr(PyCursesWindowObject * self,PyObject * args)1210 PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args)
1211 {
1212 int x, y, n;
1213 char rtn[1024]; /* This should be big enough.. I hope */
1214 int rtn2;
1215
1216 switch (PyTuple_Size(args)) {
1217 case 0:
1218 Py_BEGIN_ALLOW_THREADS
1219 rtn2 = wgetnstr(self->win,rtn, 1023);
1220 Py_END_ALLOW_THREADS
1221 break;
1222 case 1:
1223 if (!PyArg_ParseTuple(args,"i;n", &n))
1224 return NULL;
1225 if (n < 0) {
1226 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1227 return NULL;
1228 }
1229 Py_BEGIN_ALLOW_THREADS
1230 rtn2 = wgetnstr(self->win, rtn, Py_MIN(n, 1023));
1231 Py_END_ALLOW_THREADS
1232 break;
1233 case 2:
1234 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1235 return NULL;
1236 Py_BEGIN_ALLOW_THREADS
1237 #ifdef STRICT_SYSV_CURSES
1238 rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023);
1239 #else
1240 rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023);
1241 #endif
1242 Py_END_ALLOW_THREADS
1243 break;
1244 case 3:
1245 if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n))
1246 return NULL;
1247 if (n < 0) {
1248 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1249 return NULL;
1250 }
1251 #ifdef STRICT_SYSV_CURSES
1252 Py_BEGIN_ALLOW_THREADS
1253 rtn2 = wmove(self->win,y,x)==ERR ? ERR :
1254 wgetnstr(self->win, rtn, Py_MIN(n, 1023));
1255 Py_END_ALLOW_THREADS
1256 #else
1257 Py_BEGIN_ALLOW_THREADS
1258 rtn2 = mvwgetnstr(self->win, y, x, rtn, Py_MIN(n, 1023));
1259 Py_END_ALLOW_THREADS
1260 #endif
1261 break;
1262 default:
1263 PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 3 arguments");
1264 return NULL;
1265 }
1266 if (rtn2 == ERR)
1267 rtn[0] = 0;
1268 return PyBytes_FromString(rtn);
1269 }
1270
1271 static PyObject *
PyCursesWindow_Hline(PyCursesWindowObject * self,PyObject * args)1272 PyCursesWindow_Hline(PyCursesWindowObject *self, PyObject *args)
1273 {
1274 PyObject *temp;
1275 chtype ch;
1276 int n, x, y, code = OK;
1277 attr_t attr = A_NORMAL;
1278 long lattr;
1279
1280 switch (PyTuple_Size(args)) {
1281 case 2:
1282 if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n))
1283 return NULL;
1284 break;
1285 case 3:
1286 if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr))
1287 return NULL;
1288 attr = lattr;
1289 break;
1290 case 4:
1291 if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n))
1292 return NULL;
1293 code = wmove(self->win, y, x);
1294 break;
1295 case 5:
1296 if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr",
1297 &y, &x, &temp, &n, &lattr))
1298 return NULL;
1299 attr = lattr;
1300 code = wmove(self->win, y, x);
1301 break;
1302 default:
1303 PyErr_SetString(PyExc_TypeError, "hline requires 2 to 5 arguments");
1304 return NULL;
1305 }
1306
1307 if (code != ERR) {
1308 if (!PyCurses_ConvertToChtype(self, temp, &ch))
1309 return NULL;
1310 return PyCursesCheckERR(whline(self->win, ch | attr, n), "hline");
1311 } else
1312 return PyCursesCheckERR(code, "wmove");
1313 }
1314
1315 static PyObject *
PyCursesWindow_InsCh(PyCursesWindowObject * self,PyObject * args)1316 PyCursesWindow_InsCh(PyCursesWindowObject *self, PyObject *args)
1317 {
1318 int rtn, x, y, use_xy = FALSE;
1319 PyObject *temp;
1320 chtype ch = 0;
1321 attr_t attr = A_NORMAL;
1322 long lattr;
1323
1324 switch (PyTuple_Size(args)) {
1325 case 1:
1326 if (!PyArg_ParseTuple(args, "O;ch or int", &temp))
1327 return NULL;
1328 break;
1329 case 2:
1330 if (!PyArg_ParseTuple(args, "Ol;ch or int,attr", &temp, &lattr))
1331 return NULL;
1332 attr = lattr;
1333 break;
1334 case 3:
1335 if (!PyArg_ParseTuple(args,"iiO;y,x,ch or int", &y, &x, &temp))
1336 return NULL;
1337 use_xy = TRUE;
1338 break;
1339 case 4:
1340 if (!PyArg_ParseTuple(args,"iiOl;y,x,ch or int, attr", &y, &x, &temp, &lattr))
1341 return NULL;
1342 attr = lattr;
1343 use_xy = TRUE;
1344 break;
1345 default:
1346 PyErr_SetString(PyExc_TypeError, "insch requires 1 or 4 arguments");
1347 return NULL;
1348 }
1349
1350 if (!PyCurses_ConvertToChtype(self, temp, &ch))
1351 return NULL;
1352
1353 if (use_xy == TRUE)
1354 rtn = mvwinsch(self->win,y,x, ch | attr);
1355 else {
1356 rtn = winsch(self->win, ch | attr);
1357 }
1358 return PyCursesCheckERR(rtn, "insch");
1359 }
1360
1361 static PyObject *
PyCursesWindow_InCh(PyCursesWindowObject * self,PyObject * args)1362 PyCursesWindow_InCh(PyCursesWindowObject *self, PyObject *args)
1363 {
1364 int x, y;
1365 unsigned long rtn;
1366
1367 switch (PyTuple_Size(args)) {
1368 case 0:
1369 rtn = winch(self->win);
1370 break;
1371 case 2:
1372 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1373 return NULL;
1374 rtn = mvwinch(self->win,y,x);
1375 break;
1376 default:
1377 PyErr_SetString(PyExc_TypeError, "inch requires 0 or 2 arguments");
1378 return NULL;
1379 }
1380 return PyLong_FromUnsignedLong(rtn);
1381 }
1382
1383 static PyObject *
PyCursesWindow_InStr(PyCursesWindowObject * self,PyObject * args)1384 PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args)
1385 {
1386 int x, y, n;
1387 char rtn[1024]; /* This should be big enough.. I hope */
1388 int rtn2;
1389
1390 switch (PyTuple_Size(args)) {
1391 case 0:
1392 rtn2 = winnstr(self->win,rtn, 1023);
1393 break;
1394 case 1:
1395 if (!PyArg_ParseTuple(args,"i;n", &n))
1396 return NULL;
1397 if (n < 0) {
1398 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1399 return NULL;
1400 }
1401 rtn2 = winnstr(self->win, rtn, Py_MIN(n, 1023));
1402 break;
1403 case 2:
1404 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1405 return NULL;
1406 rtn2 = mvwinnstr(self->win,y,x,rtn,1023);
1407 break;
1408 case 3:
1409 if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n))
1410 return NULL;
1411 if (n < 0) {
1412 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1413 return NULL;
1414 }
1415 rtn2 = mvwinnstr(self->win, y, x, rtn, Py_MIN(n,1023));
1416 break;
1417 default:
1418 PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments");
1419 return NULL;
1420 }
1421 if (rtn2 == ERR)
1422 rtn[0] = 0;
1423 return PyBytes_FromString(rtn);
1424 }
1425
1426 static PyObject *
PyCursesWindow_InsStr(PyCursesWindowObject * self,PyObject * args)1427 PyCursesWindow_InsStr(PyCursesWindowObject *self, PyObject *args)
1428 {
1429 int rtn;
1430 int x, y;
1431 int strtype;
1432 PyObject *strobj, *bytesobj = NULL;
1433 #ifdef HAVE_NCURSESW
1434 wchar_t *wstr = NULL;
1435 #endif
1436 attr_t attr = A_NORMAL , attr_old = A_NORMAL;
1437 long lattr;
1438 int use_xy = FALSE, use_attr = FALSE;
1439 const char *funcname;
1440
1441 switch (PyTuple_Size(args)) {
1442 case 1:
1443 if (!PyArg_ParseTuple(args,"O;str", &strobj))
1444 return NULL;
1445 break;
1446 case 2:
1447 if (!PyArg_ParseTuple(args,"Ol;str,attr", &strobj, &lattr))
1448 return NULL;
1449 attr = lattr;
1450 use_attr = TRUE;
1451 break;
1452 case 3:
1453 if (!PyArg_ParseTuple(args,"iiO;y,x,str", &y, &x, &strobj))
1454 return NULL;
1455 use_xy = TRUE;
1456 break;
1457 case 4:
1458 if (!PyArg_ParseTuple(args,"iiOl;y,x,str,attr", &y, &x, &strobj, &lattr))
1459 return NULL;
1460 attr = lattr;
1461 use_xy = use_attr = TRUE;
1462 break;
1463 default:
1464 PyErr_SetString(PyExc_TypeError, "insstr requires 1 to 4 arguments");
1465 return NULL;
1466 }
1467
1468 #ifdef HAVE_NCURSESW
1469 strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr);
1470 #else
1471 strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL);
1472 #endif
1473 if (strtype == 0)
1474 return NULL;
1475
1476 if (use_attr == TRUE) {
1477 attr_old = getattrs(self->win);
1478 (void)wattrset(self->win,attr);
1479 }
1480 #ifdef HAVE_NCURSESW
1481 if (strtype == 2) {
1482 funcname = "inswstr";
1483 if (use_xy == TRUE)
1484 rtn = mvwins_wstr(self->win,y,x,wstr);
1485 else
1486 rtn = wins_wstr(self->win,wstr);
1487 PyMem_Free(wstr);
1488 }
1489 else
1490 #endif
1491 {
1492 char *str = PyBytes_AS_STRING(bytesobj);
1493 funcname = "insstr";
1494 if (use_xy == TRUE)
1495 rtn = mvwinsstr(self->win,y,x,str);
1496 else
1497 rtn = winsstr(self->win,str);
1498 Py_DECREF(bytesobj);
1499 }
1500 if (use_attr == TRUE)
1501 (void)wattrset(self->win,attr_old);
1502 return PyCursesCheckERR(rtn, funcname);
1503 }
1504
1505 static PyObject *
PyCursesWindow_InsNStr(PyCursesWindowObject * self,PyObject * args)1506 PyCursesWindow_InsNStr(PyCursesWindowObject *self, PyObject *args)
1507 {
1508 int rtn, x, y, n;
1509 int strtype;
1510 PyObject *strobj, *bytesobj = NULL;
1511 #ifdef HAVE_NCURSESW
1512 wchar_t *wstr = NULL;
1513 #endif
1514 attr_t attr = A_NORMAL , attr_old = A_NORMAL;
1515 long lattr;
1516 int use_xy = FALSE, use_attr = FALSE;
1517 const char *funcname;
1518
1519 switch (PyTuple_Size(args)) {
1520 case 2:
1521 if (!PyArg_ParseTuple(args,"Oi;str,n", &strobj, &n))
1522 return NULL;
1523 break;
1524 case 3:
1525 if (!PyArg_ParseTuple(args,"Oil;str,n,attr", &strobj, &n, &lattr))
1526 return NULL;
1527 attr = lattr;
1528 use_attr = TRUE;
1529 break;
1530 case 4:
1531 if (!PyArg_ParseTuple(args,"iiOi;y,x,str,n", &y, &x, &strobj, &n))
1532 return NULL;
1533 use_xy = TRUE;
1534 break;
1535 case 5:
1536 if (!PyArg_ParseTuple(args,"iiOil;y,x,str,n,attr", &y, &x, &strobj, &n, &lattr))
1537 return NULL;
1538 attr = lattr;
1539 use_xy = use_attr = TRUE;
1540 break;
1541 default:
1542 PyErr_SetString(PyExc_TypeError, "insnstr requires 2 to 5 arguments");
1543 return NULL;
1544 }
1545
1546 #ifdef HAVE_NCURSESW
1547 strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, &wstr);
1548 #else
1549 strtype = PyCurses_ConvertToString(self, strobj, &bytesobj, NULL);
1550 #endif
1551 if (strtype == 0)
1552 return NULL;
1553
1554 if (use_attr == TRUE) {
1555 attr_old = getattrs(self->win);
1556 (void)wattrset(self->win,attr);
1557 }
1558 #ifdef HAVE_NCURSESW
1559 if (strtype == 2) {
1560 funcname = "insn_wstr";
1561 if (use_xy == TRUE)
1562 rtn = mvwins_nwstr(self->win,y,x,wstr,n);
1563 else
1564 rtn = wins_nwstr(self->win,wstr,n);
1565 PyMem_Free(wstr);
1566 }
1567 else
1568 #endif
1569 {
1570 char *str = PyBytes_AS_STRING(bytesobj);
1571 funcname = "insnstr";
1572 if (use_xy == TRUE)
1573 rtn = mvwinsnstr(self->win,y,x,str,n);
1574 else
1575 rtn = winsnstr(self->win,str,n);
1576 Py_DECREF(bytesobj);
1577 }
1578 if (use_attr == TRUE)
1579 (void)wattrset(self->win,attr_old);
1580 return PyCursesCheckERR(rtn, funcname);
1581 }
1582
1583 static PyObject *
PyCursesWindow_Is_LineTouched(PyCursesWindowObject * self,PyObject * args)1584 PyCursesWindow_Is_LineTouched(PyCursesWindowObject *self, PyObject *args)
1585 {
1586 int line, erg;
1587 if (!PyArg_ParseTuple(args,"i;line", &line))
1588 return NULL;
1589 erg = is_linetouched(self->win, line);
1590 if (erg == ERR) {
1591 PyErr_SetString(PyExc_TypeError,
1592 "is_linetouched: line number outside of boundaries");
1593 return NULL;
1594 } else
1595 if (erg == FALSE) {
1596 Py_INCREF(Py_False);
1597 return Py_False;
1598 } else {
1599 Py_INCREF(Py_True);
1600 return Py_True;
1601 }
1602 }
1603
1604 static PyObject *
PyCursesWindow_NoOutRefresh(PyCursesWindowObject * self,PyObject * args)1605 PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args)
1606 {
1607 int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
1608 int rtn;
1609
1610 #ifndef WINDOW_HAS_FLAGS
1611 if (0)
1612 #else
1613 if (self->win->_flags & _ISPAD)
1614 #endif
1615 {
1616 switch(PyTuple_Size(args)) {
1617 case 6:
1618 if (!PyArg_ParseTuple(args,
1619 "iiiiii;" \
1620 "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol",
1621 &pminrow, &pmincol, &sminrow,
1622 &smincol, &smaxrow, &smaxcol))
1623 return NULL;
1624 Py_BEGIN_ALLOW_THREADS
1625 rtn = pnoutrefresh(self->win,
1626 pminrow, pmincol, sminrow,
1627 smincol, smaxrow, smaxcol);
1628 Py_END_ALLOW_THREADS
1629 return PyCursesCheckERR(rtn, "pnoutrefresh");
1630 default:
1631 PyErr_SetString(PyCursesError,
1632 "noutrefresh() called for a pad "
1633 "requires 6 arguments");
1634 return NULL;
1635 }
1636 } else {
1637 if (!PyArg_ParseTuple(args, ":noutrefresh"))
1638 return NULL;
1639
1640 Py_BEGIN_ALLOW_THREADS
1641 rtn = wnoutrefresh(self->win);
1642 Py_END_ALLOW_THREADS
1643 return PyCursesCheckERR(rtn, "wnoutrefresh");
1644 }
1645 }
1646
1647 static PyObject *
PyCursesWindow_Overlay(PyCursesWindowObject * self,PyObject * args)1648 PyCursesWindow_Overlay(PyCursesWindowObject *self, PyObject *args)
1649 {
1650 PyCursesWindowObject *temp;
1651 int use_copywin = FALSE;
1652 int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol;
1653 int rtn;
1654
1655 switch (PyTuple_Size(args)) {
1656 case 1:
1657 if (!PyArg_ParseTuple(args, "O!;window object",
1658 &PyCursesWindow_Type, &temp))
1659 return NULL;
1660 break;
1661 case 7:
1662 if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int",
1663 &PyCursesWindow_Type, &temp, &sminrow, &smincol,
1664 &dminrow, &dmincol, &dmaxrow, &dmaxcol))
1665 return NULL;
1666 use_copywin = TRUE;
1667 break;
1668 default:
1669 PyErr_SetString(PyExc_TypeError,
1670 "overlay requires one or seven arguments");
1671 return NULL;
1672 }
1673
1674 if (use_copywin == TRUE) {
1675 rtn = copywin(self->win, temp->win, sminrow, smincol,
1676 dminrow, dmincol, dmaxrow, dmaxcol, TRUE);
1677 return PyCursesCheckERR(rtn, "copywin");
1678 }
1679 else {
1680 rtn = overlay(self->win, temp->win);
1681 return PyCursesCheckERR(rtn, "overlay");
1682 }
1683 }
1684
1685 static PyObject *
PyCursesWindow_Overwrite(PyCursesWindowObject * self,PyObject * args)1686 PyCursesWindow_Overwrite(PyCursesWindowObject *self, PyObject *args)
1687 {
1688 PyCursesWindowObject *temp;
1689 int use_copywin = FALSE;
1690 int sminrow, smincol, dminrow, dmincol, dmaxrow, dmaxcol;
1691 int rtn;
1692
1693 switch (PyTuple_Size(args)) {
1694 case 1:
1695 if (!PyArg_ParseTuple(args, "O!;window object",
1696 &PyCursesWindow_Type, &temp))
1697 return NULL;
1698 break;
1699 case 7:
1700 if (!PyArg_ParseTuple(args, "O!iiiiii;window object, int, int, int, int, int, int",
1701 &PyCursesWindow_Type, &temp, &sminrow, &smincol,
1702 &dminrow, &dmincol, &dmaxrow, &dmaxcol))
1703 return NULL;
1704 use_copywin = TRUE;
1705 break;
1706 default:
1707 PyErr_SetString(PyExc_TypeError,
1708 "overwrite requires one or seven arguments");
1709 return NULL;
1710 }
1711
1712 if (use_copywin == TRUE) {
1713 rtn = copywin(self->win, temp->win, sminrow, smincol,
1714 dminrow, dmincol, dmaxrow, dmaxcol, FALSE);
1715 return PyCursesCheckERR(rtn, "copywin");
1716 }
1717 else {
1718 rtn = overwrite(self->win, temp->win);
1719 return PyCursesCheckERR(rtn, "overwrite");
1720 }
1721 }
1722
1723 static PyObject *
PyCursesWindow_PutWin(PyCursesWindowObject * self,PyObject * stream)1724 PyCursesWindow_PutWin(PyCursesWindowObject *self, PyObject *stream)
1725 {
1726 /* We have to simulate this by writing to a temporary FILE*,
1727 then reading back, then writing to the argument stream. */
1728 char fn[100];
1729 int fd = -1;
1730 FILE *fp = NULL;
1731 PyObject *res = NULL;
1732
1733 strcpy(fn, "/tmp/py.curses.putwin.XXXXXX");
1734 fd = mkstemp(fn);
1735 if (fd < 0)
1736 return PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn);
1737 if (_Py_set_inheritable(fd, 0, NULL) < 0)
1738 goto exit;
1739 fp = fdopen(fd, "wb+");
1740 if (fp == NULL) {
1741 PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn);
1742 goto exit;
1743 }
1744 res = PyCursesCheckERR(putwin(self->win, fp), "putwin");
1745 if (res == NULL)
1746 goto exit;
1747 fseek(fp, 0, 0);
1748 while (1) {
1749 char buf[BUFSIZ];
1750 Py_ssize_t n = fread(buf, 1, BUFSIZ, fp);
1751 _Py_IDENTIFIER(write);
1752
1753 if (n <= 0)
1754 break;
1755 Py_DECREF(res);
1756 res = _PyObject_CallMethodId(stream, &PyId_write, "y#", buf, n);
1757 if (res == NULL)
1758 break;
1759 }
1760
1761 exit:
1762 if (fp != NULL)
1763 fclose(fp);
1764 else if (fd != -1)
1765 close(fd);
1766 remove(fn);
1767 return res;
1768 }
1769
1770 static PyObject *
PyCursesWindow_RedrawLine(PyCursesWindowObject * self,PyObject * args)1771 PyCursesWindow_RedrawLine(PyCursesWindowObject *self, PyObject *args)
1772 {
1773 int beg, num;
1774 if (!PyArg_ParseTuple(args, "ii;beg,num", &beg, &num))
1775 return NULL;
1776 return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln");
1777 }
1778
1779 static PyObject *
PyCursesWindow_Refresh(PyCursesWindowObject * self,PyObject * args)1780 PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args)
1781 {
1782 int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
1783 int rtn;
1784
1785 #ifndef WINDOW_HAS_FLAGS
1786 if (0)
1787 #else
1788 if (self->win->_flags & _ISPAD)
1789 #endif
1790 {
1791 switch(PyTuple_Size(args)) {
1792 case 6:
1793 if (!PyArg_ParseTuple(args,
1794 "iiiiii;" \
1795 "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol",
1796 &pminrow, &pmincol, &sminrow,
1797 &smincol, &smaxrow, &smaxcol))
1798 return NULL;
1799
1800 Py_BEGIN_ALLOW_THREADS
1801 rtn = prefresh(self->win,
1802 pminrow, pmincol, sminrow,
1803 smincol, smaxrow, smaxcol);
1804 Py_END_ALLOW_THREADS
1805 return PyCursesCheckERR(rtn, "prefresh");
1806 default:
1807 PyErr_SetString(PyCursesError,
1808 "refresh() for a pad requires 6 arguments");
1809 return NULL;
1810 }
1811 } else {
1812 if (!PyArg_ParseTuple(args, ":refresh"))
1813 return NULL;
1814 Py_BEGIN_ALLOW_THREADS
1815 rtn = wrefresh(self->win);
1816 Py_END_ALLOW_THREADS
1817 return PyCursesCheckERR(rtn, "prefresh");
1818 }
1819 }
1820
1821 static PyObject *
PyCursesWindow_SetScrollRegion(PyCursesWindowObject * self,PyObject * args)1822 PyCursesWindow_SetScrollRegion(PyCursesWindowObject *self, PyObject *args)
1823 {
1824 int x, y;
1825 if (!PyArg_ParseTuple(args,"ii;top, bottom",&y,&x))
1826 return NULL;
1827 return PyCursesCheckERR(wsetscrreg(self->win,y,x), "wsetscrreg");
1828 }
1829
1830 static PyObject *
PyCursesWindow_SubWin(PyCursesWindowObject * self,PyObject * args)1831 PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args)
1832 {
1833 WINDOW *win;
1834 int nlines, ncols, begin_y, begin_x;
1835
1836 nlines = 0;
1837 ncols = 0;
1838 switch (PyTuple_Size(args)) {
1839 case 2:
1840 if (!PyArg_ParseTuple(args,"ii;begin_y,begin_x",&begin_y,&begin_x))
1841 return NULL;
1842 break;
1843 case 4:
1844 if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
1845 &nlines,&ncols,&begin_y,&begin_x))
1846 return NULL;
1847 break;
1848 default:
1849 PyErr_SetString(PyExc_TypeError, "subwin requires 2 or 4 arguments");
1850 return NULL;
1851 }
1852
1853 /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */
1854 #ifdef WINDOW_HAS_FLAGS
1855 if (self->win->_flags & _ISPAD)
1856 win = subpad(self->win, nlines, ncols, begin_y, begin_x);
1857 else
1858 #endif
1859 win = subwin(self->win, nlines, ncols, begin_y, begin_x);
1860
1861 if (win == NULL) {
1862 PyErr_SetString(PyCursesError, catchall_NULL);
1863 return NULL;
1864 }
1865
1866 return (PyObject *)PyCursesWindow_New(win, self->encoding);
1867 }
1868
1869 static PyObject *
PyCursesWindow_Scroll(PyCursesWindowObject * self,PyObject * args)1870 PyCursesWindow_Scroll(PyCursesWindowObject *self, PyObject *args)
1871 {
1872 int nlines;
1873 switch(PyTuple_Size(args)) {
1874 case 0:
1875 return PyCursesCheckERR(scroll(self->win), "scroll");
1876 case 1:
1877 if (!PyArg_ParseTuple(args, "i;nlines", &nlines))
1878 return NULL;
1879 return PyCursesCheckERR(wscrl(self->win, nlines), "scroll");
1880 default:
1881 PyErr_SetString(PyExc_TypeError, "scroll requires 0 or 1 arguments");
1882 return NULL;
1883 }
1884 }
1885
1886 static PyObject *
PyCursesWindow_TouchLine(PyCursesWindowObject * self,PyObject * args)1887 PyCursesWindow_TouchLine(PyCursesWindowObject *self, PyObject *args)
1888 {
1889 int st, cnt, val;
1890 switch (PyTuple_Size(args)) {
1891 case 2:
1892 if (!PyArg_ParseTuple(args,"ii;start,count",&st,&cnt))
1893 return NULL;
1894 return PyCursesCheckERR(touchline(self->win,st,cnt), "touchline");
1895 case 3:
1896 if (!PyArg_ParseTuple(args, "iii;start,count,val", &st, &cnt, &val))
1897 return NULL;
1898 return PyCursesCheckERR(wtouchln(self->win, st, cnt, val), "touchline");
1899 default:
1900 PyErr_SetString(PyExc_TypeError, "touchline requires 2 or 3 arguments");
1901 return NULL;
1902 }
1903 }
1904
1905 static PyObject *
PyCursesWindow_Vline(PyCursesWindowObject * self,PyObject * args)1906 PyCursesWindow_Vline(PyCursesWindowObject *self, PyObject *args)
1907 {
1908 PyObject *temp;
1909 chtype ch;
1910 int n, x, y, code = OK;
1911 attr_t attr = A_NORMAL;
1912 long lattr;
1913
1914 switch (PyTuple_Size(args)) {
1915 case 2:
1916 if (!PyArg_ParseTuple(args, "Oi;ch or int,n", &temp, &n))
1917 return NULL;
1918 break;
1919 case 3:
1920 if (!PyArg_ParseTuple(args, "Oil;ch or int,n,attr", &temp, &n, &lattr))
1921 return NULL;
1922 attr = lattr;
1923 break;
1924 case 4:
1925 if (!PyArg_ParseTuple(args, "iiOi;y,x,ch or int,n", &y, &x, &temp, &n))
1926 return NULL;
1927 code = wmove(self->win, y, x);
1928 break;
1929 case 5:
1930 if (!PyArg_ParseTuple(args, "iiOil; y,x,ch or int,n,attr",
1931 &y, &x, &temp, &n, &lattr))
1932 return NULL;
1933 attr = lattr;
1934 code = wmove(self->win, y, x);
1935 break;
1936 default:
1937 PyErr_SetString(PyExc_TypeError, "vline requires 2 to 5 arguments");
1938 return NULL;
1939 }
1940
1941 if (code != ERR) {
1942 if (!PyCurses_ConvertToChtype(self, temp, &ch))
1943 return NULL;
1944 return PyCursesCheckERR(wvline(self->win, ch | attr, n), "vline");
1945 } else
1946 return PyCursesCheckERR(code, "wmove");
1947 }
1948
1949 static PyObject *
PyCursesWindow_get_encoding(PyCursesWindowObject * self,void * closure)1950 PyCursesWindow_get_encoding(PyCursesWindowObject *self, void *closure)
1951 {
1952 return PyUnicode_FromString(self->encoding);
1953 }
1954
1955 static int
PyCursesWindow_set_encoding(PyCursesWindowObject * self,PyObject * value)1956 PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value)
1957 {
1958 PyObject *ascii;
1959 char *encoding;
1960
1961 /* It is illegal to del win.encoding */
1962 if (value == NULL) {
1963 PyErr_SetString(PyExc_TypeError,
1964 "encoding may not be deleted");
1965 return -1;
1966 }
1967
1968 if (!PyUnicode_Check(value)) {
1969 PyErr_SetString(PyExc_TypeError,
1970 "setting encoding to a non-string");
1971 return -1;
1972 }
1973 ascii = PyUnicode_AsASCIIString(value);
1974 if (ascii == NULL)
1975 return -1;
1976 encoding = _PyMem_Strdup(PyBytes_AS_STRING(ascii));
1977 Py_DECREF(ascii);
1978 if (encoding == NULL) {
1979 PyErr_NoMemory();
1980 return -1;
1981 }
1982 PyMem_Free(self->encoding);
1983 self->encoding = encoding;
1984 return 0;
1985 }
1986
1987
1988 static PyMethodDef PyCursesWindow_Methods[] = {
1989 CURSES_WINDOW_ADDCH_METHODDEF
1990 {"addnstr", (PyCFunction)PyCursesWindow_AddNStr, METH_VARARGS},
1991 {"addstr", (PyCFunction)PyCursesWindow_AddStr, METH_VARARGS},
1992 {"attroff", (PyCFunction)PyCursesWindow_AttrOff, METH_VARARGS},
1993 {"attron", (PyCFunction)PyCursesWindow_AttrOn, METH_VARARGS},
1994 {"attrset", (PyCFunction)PyCursesWindow_AttrSet, METH_VARARGS},
1995 {"bkgd", (PyCFunction)PyCursesWindow_Bkgd, METH_VARARGS},
1996 {"chgat", (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS},
1997 {"bkgdset", (PyCFunction)PyCursesWindow_BkgdSet, METH_VARARGS},
1998 {"border", (PyCFunction)PyCursesWindow_Border, METH_VARARGS},
1999 {"box", (PyCFunction)PyCursesWindow_Box, METH_VARARGS},
2000 {"clear", (PyCFunction)PyCursesWindow_wclear, METH_NOARGS},
2001 {"clearok", (PyCFunction)PyCursesWindow_clearok, METH_VARARGS},
2002 {"clrtobot", (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS},
2003 {"clrtoeol", (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS},
2004 {"cursyncup", (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS},
2005 {"delch", (PyCFunction)PyCursesWindow_DelCh, METH_VARARGS},
2006 {"deleteln", (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS},
2007 {"derwin", (PyCFunction)PyCursesWindow_DerWin, METH_VARARGS},
2008 {"echochar", (PyCFunction)PyCursesWindow_EchoChar, METH_VARARGS},
2009 #ifdef NCURSES_MOUSE_VERSION
2010 {"enclose", (PyCFunction)PyCursesWindow_Enclose, METH_VARARGS},
2011 #endif
2012 {"erase", (PyCFunction)PyCursesWindow_werase, METH_NOARGS},
2013 {"getbegyx", (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS},
2014 {"getbkgd", (PyCFunction)PyCursesWindow_GetBkgd, METH_NOARGS},
2015 {"getch", (PyCFunction)PyCursesWindow_GetCh, METH_VARARGS},
2016 {"getkey", (PyCFunction)PyCursesWindow_GetKey, METH_VARARGS},
2017 #ifdef HAVE_NCURSESW
2018 {"get_wch", (PyCFunction)PyCursesWindow_Get_WCh, METH_VARARGS},
2019 #endif
2020 {"getmaxyx", (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS},
2021 {"getparyx", (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS},
2022 {"getstr", (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS},
2023 {"getyx", (PyCFunction)PyCursesWindow_getyx, METH_NOARGS},
2024 {"hline", (PyCFunction)PyCursesWindow_Hline, METH_VARARGS},
2025 {"idcok", (PyCFunction)PyCursesWindow_idcok, METH_VARARGS},
2026 {"idlok", (PyCFunction)PyCursesWindow_idlok, METH_VARARGS},
2027 {"immedok", (PyCFunction)PyCursesWindow_immedok, METH_VARARGS},
2028 {"inch", (PyCFunction)PyCursesWindow_InCh, METH_VARARGS},
2029 {"insch", (PyCFunction)PyCursesWindow_InsCh, METH_VARARGS},
2030 {"insdelln", (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS},
2031 {"insertln", (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS},
2032 {"insnstr", (PyCFunction)PyCursesWindow_InsNStr, METH_VARARGS},
2033 {"insstr", (PyCFunction)PyCursesWindow_InsStr, METH_VARARGS},
2034 {"instr", (PyCFunction)PyCursesWindow_InStr, METH_VARARGS},
2035 {"is_linetouched", (PyCFunction)PyCursesWindow_Is_LineTouched, METH_VARARGS},
2036 {"is_wintouched", (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS},
2037 {"keypad", (PyCFunction)PyCursesWindow_keypad, METH_VARARGS},
2038 {"leaveok", (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS},
2039 {"move", (PyCFunction)PyCursesWindow_wmove, METH_VARARGS},
2040 {"mvderwin", (PyCFunction)PyCursesWindow_mvderwin, METH_VARARGS},
2041 {"mvwin", (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS},
2042 {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS},
2043 {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS},
2044 {"noutrefresh", (PyCFunction)PyCursesWindow_NoOutRefresh, METH_VARARGS},
2045 {"overlay", (PyCFunction)PyCursesWindow_Overlay, METH_VARARGS},
2046 {"overwrite", (PyCFunction)PyCursesWindow_Overwrite,
2047 METH_VARARGS},
2048 {"putwin", (PyCFunction)PyCursesWindow_PutWin, METH_O},
2049 {"redrawln", (PyCFunction)PyCursesWindow_RedrawLine, METH_VARARGS},
2050 {"redrawwin", (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS},
2051 {"refresh", (PyCFunction)PyCursesWindow_Refresh, METH_VARARGS},
2052 #ifndef STRICT_SYSV_CURSES
2053 {"resize", (PyCFunction)PyCursesWindow_wresize, METH_VARARGS},
2054 #endif
2055 {"scroll", (PyCFunction)PyCursesWindow_Scroll, METH_VARARGS},
2056 {"scrollok", (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS},
2057 {"setscrreg", (PyCFunction)PyCursesWindow_SetScrollRegion, METH_VARARGS},
2058 {"standend", (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS},
2059 {"standout", (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS},
2060 {"subpad", (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
2061 {"subwin", (PyCFunction)PyCursesWindow_SubWin, METH_VARARGS},
2062 {"syncdown", (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS},
2063 {"syncok", (PyCFunction)PyCursesWindow_syncok, METH_VARARGS},
2064 {"syncup", (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS},
2065 {"timeout", (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS},
2066 {"touchline", (PyCFunction)PyCursesWindow_TouchLine, METH_VARARGS},
2067 {"touchwin", (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS},
2068 {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS},
2069 {"vline", (PyCFunction)PyCursesWindow_Vline, METH_VARARGS},
2070 {NULL, NULL} /* sentinel */
2071 };
2072
2073 static PyGetSetDef PyCursesWindow_getsets[] = {
2074 {"encoding",
2075 (getter)PyCursesWindow_get_encoding,
2076 (setter)PyCursesWindow_set_encoding,
2077 "the typecode character used to create the array"},
2078 {NULL, NULL, NULL, NULL } /* sentinel */
2079 };
2080
2081 /* -------------------------------------------------------*/
2082
2083 PyTypeObject PyCursesWindow_Type = {
2084 PyVarObject_HEAD_INIT(NULL, 0)
2085 "_curses.curses window", /*tp_name*/
2086 sizeof(PyCursesWindowObject), /*tp_basicsize*/
2087 0, /*tp_itemsize*/
2088 /* methods */
2089 (destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/
2090 0, /*tp_print*/
2091 (getattrfunc)0, /*tp_getattr*/
2092 (setattrfunc)0, /*tp_setattr*/
2093 0, /*tp_reserved*/
2094 0, /*tp_repr*/
2095 0, /*tp_as_number*/
2096 0, /*tp_as_sequence*/
2097 0, /*tp_as_mapping*/
2098 0, /*tp_hash*/
2099 0, /*tp_call*/
2100 0, /*tp_str*/
2101 0, /*tp_getattro*/
2102 0, /*tp_setattro*/
2103 0, /*tp_as_buffer*/
2104 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2105 0, /*tp_doc*/
2106 0, /*tp_traverse*/
2107 0, /*tp_clear*/
2108 0, /*tp_richcompare*/
2109 0, /*tp_weaklistoffset*/
2110 0, /*tp_iter*/
2111 0, /*tp_iternext*/
2112 PyCursesWindow_Methods, /*tp_methods*/
2113 0, /* tp_members */
2114 PyCursesWindow_getsets, /* tp_getset */
2115 };
2116
2117 /*********************************************************************
2118 Global Functions
2119 **********************************************************************/
2120
2121 NoArgNoReturnFunction(beep)
NoArgNoReturnFunction(def_prog_mode)2122 NoArgNoReturnFunction(def_prog_mode)
2123 NoArgNoReturnFunction(def_shell_mode)
2124 NoArgNoReturnFunction(doupdate)
2125 NoArgNoReturnFunction(endwin)
2126 NoArgNoReturnFunction(flash)
2127 NoArgNoReturnFunction(nocbreak)
2128 NoArgNoReturnFunction(noecho)
2129 NoArgNoReturnFunction(nonl)
2130 NoArgNoReturnFunction(noraw)
2131 NoArgNoReturnFunction(reset_prog_mode)
2132 NoArgNoReturnFunction(reset_shell_mode)
2133 NoArgNoReturnFunction(resetty)
2134 NoArgNoReturnFunction(savetty)
2135
2136 NoArgOrFlagNoReturnFunction(cbreak)
2137 NoArgOrFlagNoReturnFunction(echo)
2138 NoArgOrFlagNoReturnFunction(nl)
2139 NoArgOrFlagNoReturnFunction(raw)
2140
2141 NoArgReturnIntFunction(baudrate)
2142 NoArgReturnIntFunction(termattrs)
2143
2144 NoArgReturnStringFunction(termname)
2145 NoArgReturnStringFunction(longname)
2146
2147 NoArgTrueFalseFunction(can_change_color)
2148 NoArgTrueFalseFunction(has_colors)
2149 NoArgTrueFalseFunction(has_ic)
2150 NoArgTrueFalseFunction(has_il)
2151 NoArgTrueFalseFunction(isendwin)
2152 NoArgNoReturnVoidFunction(flushinp)
2153 NoArgNoReturnVoidFunction(noqiflush)
2154
2155 static PyObject *
2156 PyCurses_filter(PyObject *self)
2157 {
2158 /* not checking for PyCursesInitialised here since filter() must
2159 be called before initscr() */
2160 filter();
2161 Py_INCREF(Py_None);
2162 return Py_None;
2163 }
2164
2165 static PyObject *
PyCurses_Color_Content(PyObject * self,PyObject * args)2166 PyCurses_Color_Content(PyObject *self, PyObject *args)
2167 {
2168 short color,r,g,b;
2169
2170 PyCursesInitialised;
2171 PyCursesInitialisedColor;
2172
2173 if (!PyArg_ParseTuple(args, "h:color_content", &color)) return NULL;
2174
2175 if (color_content(color, &r, &g, &b) != ERR)
2176 return Py_BuildValue("(iii)", r, g, b);
2177 else {
2178 PyErr_SetString(PyCursesError,
2179 "Argument 1 was out of range. Check value of COLORS.");
2180 return NULL;
2181 }
2182 }
2183
2184 static PyObject *
PyCurses_color_pair(PyObject * self,PyObject * args)2185 PyCurses_color_pair(PyObject *self, PyObject *args)
2186 {
2187 int n;
2188
2189 PyCursesInitialised;
2190 PyCursesInitialisedColor;
2191
2192 if (!PyArg_ParseTuple(args, "i:color_pair", &n)) return NULL;
2193 return PyLong_FromLong((long) (n << 8));
2194 }
2195
2196 static PyObject *
PyCurses_Curs_Set(PyObject * self,PyObject * args)2197 PyCurses_Curs_Set(PyObject *self, PyObject *args)
2198 {
2199 int vis,erg;
2200
2201 PyCursesInitialised;
2202
2203 if (!PyArg_ParseTuple(args, "i:curs_set", &vis)) return NULL;
2204
2205 erg = curs_set(vis);
2206 if (erg == ERR) return PyCursesCheckERR(erg, "curs_set");
2207
2208 return PyLong_FromLong((long) erg);
2209 }
2210
2211 static PyObject *
PyCurses_Delay_Output(PyObject * self,PyObject * args)2212 PyCurses_Delay_Output(PyObject *self, PyObject *args)
2213 {
2214 int ms;
2215
2216 PyCursesInitialised;
2217
2218 if (!PyArg_ParseTuple(args, "i:delay_output", &ms)) return NULL;
2219
2220 return PyCursesCheckERR(delay_output(ms), "delay_output");
2221 }
2222
2223 static PyObject *
PyCurses_EraseChar(PyObject * self)2224 PyCurses_EraseChar(PyObject *self)
2225 {
2226 char ch;
2227
2228 PyCursesInitialised;
2229
2230 ch = erasechar();
2231
2232 return PyBytes_FromStringAndSize(&ch, 1);
2233 }
2234
2235 static PyObject *
PyCurses_getsyx(PyObject * self)2236 PyCurses_getsyx(PyObject *self)
2237 {
2238 int x = 0;
2239 int y = 0;
2240
2241 PyCursesInitialised;
2242
2243 getsyx(y, x);
2244
2245 return Py_BuildValue("(ii)", y, x);
2246 }
2247
2248 #ifdef NCURSES_MOUSE_VERSION
2249 static PyObject *
PyCurses_GetMouse(PyObject * self)2250 PyCurses_GetMouse(PyObject *self)
2251 {
2252 int rtn;
2253 MEVENT event;
2254
2255 PyCursesInitialised;
2256
2257 rtn = getmouse( &event );
2258 if (rtn == ERR) {
2259 PyErr_SetString(PyCursesError, "getmouse() returned ERR");
2260 return NULL;
2261 }
2262 return Py_BuildValue("(hiiil)",
2263 (short)event.id,
2264 event.x, event.y, event.z,
2265 (long) event.bstate);
2266 }
2267
2268 static PyObject *
PyCurses_UngetMouse(PyObject * self,PyObject * args)2269 PyCurses_UngetMouse(PyObject *self, PyObject *args)
2270 {
2271 MEVENT event;
2272
2273 PyCursesInitialised;
2274 if (!PyArg_ParseTuple(args, "hiiil",
2275 &event.id,
2276 &event.x, &event.y, &event.z,
2277 (int *) &event.bstate))
2278 return NULL;
2279
2280 return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
2281 }
2282 #endif
2283
2284 static PyObject *
PyCurses_GetWin(PyCursesWindowObject * self,PyObject * stream)2285 PyCurses_GetWin(PyCursesWindowObject *self, PyObject *stream)
2286 {
2287 char fn[100];
2288 int fd = -1;
2289 FILE *fp = NULL;
2290 PyObject *data;
2291 size_t datalen;
2292 WINDOW *win;
2293 _Py_IDENTIFIER(read);
2294 PyObject *res = NULL;
2295
2296 PyCursesInitialised;
2297
2298 strcpy(fn, "/tmp/py.curses.getwin.XXXXXX");
2299 fd = mkstemp(fn);
2300 if (fd < 0)
2301 return PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn);
2302 if (_Py_set_inheritable(fd, 0, NULL) < 0)
2303 goto error;
2304 fp = fdopen(fd, "wb+");
2305 if (fp == NULL) {
2306 PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn);
2307 goto error;
2308 }
2309
2310 data = _PyObject_CallMethodId(stream, &PyId_read, NULL);
2311 if (data == NULL)
2312 goto error;
2313 if (!PyBytes_Check(data)) {
2314 PyErr_Format(PyExc_TypeError,
2315 "f.read() returned %.100s instead of bytes",
2316 data->ob_type->tp_name);
2317 Py_DECREF(data);
2318 goto error;
2319 }
2320 datalen = PyBytes_GET_SIZE(data);
2321 if (fwrite(PyBytes_AS_STRING(data), 1, datalen, fp) != datalen) {
2322 Py_DECREF(data);
2323 PyErr_SetFromErrnoWithFilename(PyExc_IOError, fn);
2324 goto error;
2325 }
2326 Py_DECREF(data);
2327
2328 fseek(fp, 0, 0);
2329 win = getwin(fp);
2330 if (win == NULL) {
2331 PyErr_SetString(PyCursesError, catchall_NULL);
2332 goto error;
2333 }
2334 res = PyCursesWindow_New(win, NULL);
2335
2336 error:
2337 if (fp != NULL)
2338 fclose(fp);
2339 else if (fd != -1)
2340 close(fd);
2341 remove(fn);
2342 return res;
2343 }
2344
2345 static PyObject *
PyCurses_HalfDelay(PyObject * self,PyObject * args)2346 PyCurses_HalfDelay(PyObject *self, PyObject *args)
2347 {
2348 unsigned char tenths;
2349
2350 PyCursesInitialised;
2351
2352 if (!PyArg_ParseTuple(args, "b:halfdelay", &tenths)) return NULL;
2353
2354 return PyCursesCheckERR(halfdelay(tenths), "halfdelay");
2355 }
2356
2357 #ifndef STRICT_SYSV_CURSES
2358 /* No has_key! */
PyCurses_has_key(PyObject * self,PyObject * args)2359 static PyObject * PyCurses_has_key(PyObject *self, PyObject *args)
2360 {
2361 int ch;
2362
2363 PyCursesInitialised;
2364
2365 if (!PyArg_ParseTuple(args,"i",&ch)) return NULL;
2366
2367 if (has_key(ch) == FALSE) {
2368 Py_INCREF(Py_False);
2369 return Py_False;
2370 }
2371 Py_INCREF(Py_True);
2372 return Py_True;
2373 }
2374 #endif /* STRICT_SYSV_CURSES */
2375
2376 static PyObject *
PyCurses_Init_Color(PyObject * self,PyObject * args)2377 PyCurses_Init_Color(PyObject *self, PyObject *args)
2378 {
2379 short color, r, g, b;
2380
2381 PyCursesInitialised;
2382 PyCursesInitialisedColor;
2383
2384 switch(PyTuple_Size(args)) {
2385 case 4:
2386 if (!PyArg_ParseTuple(args, "hhhh;color,r,g,b", &color, &r, &g, &b)) return NULL;
2387 break;
2388 default:
2389 PyErr_SetString(PyExc_TypeError, "init_color requires 4 arguments");
2390 return NULL;
2391 }
2392
2393 return PyCursesCheckERR(init_color(color, r, g, b), "init_color");
2394 }
2395
2396 static PyObject *
PyCurses_Init_Pair(PyObject * self,PyObject * args)2397 PyCurses_Init_Pair(PyObject *self, PyObject *args)
2398 {
2399 short pair, f, b;
2400
2401 PyCursesInitialised;
2402 PyCursesInitialisedColor;
2403
2404 if (PyTuple_Size(args) != 3) {
2405 PyErr_SetString(PyExc_TypeError, "init_pair requires 3 arguments");
2406 return NULL;
2407 }
2408
2409 if (!PyArg_ParseTuple(args, "hhh;pair, f, b", &pair, &f, &b)) return NULL;
2410
2411 return PyCursesCheckERR(init_pair(pair, f, b), "init_pair");
2412 }
2413
2414 static PyObject *ModDict;
2415
2416 static PyObject *
PyCurses_InitScr(PyObject * self)2417 PyCurses_InitScr(PyObject *self)
2418 {
2419 WINDOW *win;
2420 PyCursesWindowObject *winobj;
2421
2422 if (initialised == TRUE) {
2423 wrefresh(stdscr);
2424 return (PyObject *)PyCursesWindow_New(stdscr, NULL);
2425 }
2426
2427 win = initscr();
2428
2429 if (win == NULL) {
2430 PyErr_SetString(PyCursesError, catchall_NULL);
2431 return NULL;
2432 }
2433
2434 initialised = initialised_setupterm = TRUE;
2435
2436 /* This was moved from initcurses() because it core dumped on SGI,
2437 where they're not defined until you've called initscr() */
2438 #define SetDictInt(string,ch) \
2439 do { \
2440 PyObject *o = PyLong_FromLong((long) (ch)); \
2441 if (o && PyDict_SetItemString(ModDict, string, o) == 0) { \
2442 Py_DECREF(o); \
2443 } \
2444 } while (0)
2445
2446 /* Here are some graphic symbols you can use */
2447 SetDictInt("ACS_ULCORNER", (ACS_ULCORNER));
2448 SetDictInt("ACS_LLCORNER", (ACS_LLCORNER));
2449 SetDictInt("ACS_URCORNER", (ACS_URCORNER));
2450 SetDictInt("ACS_LRCORNER", (ACS_LRCORNER));
2451 SetDictInt("ACS_LTEE", (ACS_LTEE));
2452 SetDictInt("ACS_RTEE", (ACS_RTEE));
2453 SetDictInt("ACS_BTEE", (ACS_BTEE));
2454 SetDictInt("ACS_TTEE", (ACS_TTEE));
2455 SetDictInt("ACS_HLINE", (ACS_HLINE));
2456 SetDictInt("ACS_VLINE", (ACS_VLINE));
2457 SetDictInt("ACS_PLUS", (ACS_PLUS));
2458 #if !defined(__hpux) || defined(HAVE_NCURSES_H)
2459 /* On HP/UX 11, these are of type cchar_t, which is not an
2460 integral type. If this is a problem on more platforms, a
2461 configure test should be added to determine whether ACS_S1
2462 is of integral type. */
2463 SetDictInt("ACS_S1", (ACS_S1));
2464 SetDictInt("ACS_S9", (ACS_S9));
2465 SetDictInt("ACS_DIAMOND", (ACS_DIAMOND));
2466 SetDictInt("ACS_CKBOARD", (ACS_CKBOARD));
2467 SetDictInt("ACS_DEGREE", (ACS_DEGREE));
2468 SetDictInt("ACS_PLMINUS", (ACS_PLMINUS));
2469 SetDictInt("ACS_BULLET", (ACS_BULLET));
2470 SetDictInt("ACS_LARROW", (ACS_LARROW));
2471 SetDictInt("ACS_RARROW", (ACS_RARROW));
2472 SetDictInt("ACS_DARROW", (ACS_DARROW));
2473 SetDictInt("ACS_UARROW", (ACS_UARROW));
2474 SetDictInt("ACS_BOARD", (ACS_BOARD));
2475 SetDictInt("ACS_LANTERN", (ACS_LANTERN));
2476 SetDictInt("ACS_BLOCK", (ACS_BLOCK));
2477 #endif
2478 SetDictInt("ACS_BSSB", (ACS_ULCORNER));
2479 SetDictInt("ACS_SSBB", (ACS_LLCORNER));
2480 SetDictInt("ACS_BBSS", (ACS_URCORNER));
2481 SetDictInt("ACS_SBBS", (ACS_LRCORNER));
2482 SetDictInt("ACS_SBSS", (ACS_RTEE));
2483 SetDictInt("ACS_SSSB", (ACS_LTEE));
2484 SetDictInt("ACS_SSBS", (ACS_BTEE));
2485 SetDictInt("ACS_BSSS", (ACS_TTEE));
2486 SetDictInt("ACS_BSBS", (ACS_HLINE));
2487 SetDictInt("ACS_SBSB", (ACS_VLINE));
2488 SetDictInt("ACS_SSSS", (ACS_PLUS));
2489
2490 /* The following are never available with strict SYSV curses */
2491 #ifdef ACS_S3
2492 SetDictInt("ACS_S3", (ACS_S3));
2493 #endif
2494 #ifdef ACS_S7
2495 SetDictInt("ACS_S7", (ACS_S7));
2496 #endif
2497 #ifdef ACS_LEQUAL
2498 SetDictInt("ACS_LEQUAL", (ACS_LEQUAL));
2499 #endif
2500 #ifdef ACS_GEQUAL
2501 SetDictInt("ACS_GEQUAL", (ACS_GEQUAL));
2502 #endif
2503 #ifdef ACS_PI
2504 SetDictInt("ACS_PI", (ACS_PI));
2505 #endif
2506 #ifdef ACS_NEQUAL
2507 SetDictInt("ACS_NEQUAL", (ACS_NEQUAL));
2508 #endif
2509 #ifdef ACS_STERLING
2510 SetDictInt("ACS_STERLING", (ACS_STERLING));
2511 #endif
2512
2513 SetDictInt("LINES", LINES);
2514 SetDictInt("COLS", COLS);
2515
2516 winobj = (PyCursesWindowObject *)PyCursesWindow_New(win, NULL);
2517 screen_encoding = winobj->encoding;
2518 return (PyObject *)winobj;
2519 }
2520
2521 static PyObject *
PyCurses_setupterm(PyObject * self,PyObject * args,PyObject * keywds)2522 PyCurses_setupterm(PyObject* self, PyObject *args, PyObject* keywds)
2523 {
2524 int fd = -1;
2525 int err;
2526 char* termstr = NULL;
2527
2528 static char *kwlist[] = {"term", "fd", NULL};
2529
2530 if (!PyArg_ParseTupleAndKeywords(
2531 args, keywds, "|zi:setupterm", kwlist, &termstr, &fd)) {
2532 return NULL;
2533 }
2534
2535 if (fd == -1) {
2536 PyObject* sys_stdout;
2537
2538 sys_stdout = PySys_GetObject("stdout");
2539
2540 if (sys_stdout == NULL || sys_stdout == Py_None) {
2541 PyErr_SetString(
2542 PyCursesError,
2543 "lost sys.stdout");
2544 return NULL;
2545 }
2546
2547 fd = PyObject_AsFileDescriptor(sys_stdout);
2548
2549 if (fd == -1) {
2550 return NULL;
2551 }
2552 }
2553
2554 if (!initialised_setupterm && setupterm(termstr,fd,&err) == ERR) {
2555 char* s = "setupterm: unknown error";
2556
2557 if (err == 0) {
2558 s = "setupterm: could not find terminal";
2559 } else if (err == -1) {
2560 s = "setupterm: could not find terminfo database";
2561 }
2562
2563 PyErr_SetString(PyCursesError,s);
2564 return NULL;
2565 }
2566
2567 initialised_setupterm = TRUE;
2568
2569 Py_INCREF(Py_None);
2570 return Py_None;
2571 }
2572
2573 static PyObject *
PyCurses_IntrFlush(PyObject * self,PyObject * args)2574 PyCurses_IntrFlush(PyObject *self, PyObject *args)
2575 {
2576 int ch;
2577
2578 PyCursesInitialised;
2579
2580 switch(PyTuple_Size(args)) {
2581 case 1:
2582 if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL;
2583 break;
2584 default:
2585 PyErr_SetString(PyExc_TypeError, "intrflush requires 1 argument");
2586 return NULL;
2587 }
2588
2589 return PyCursesCheckERR(intrflush(NULL,ch), "intrflush");
2590 }
2591
2592 #ifdef HAVE_CURSES_IS_TERM_RESIZED
2593 static PyObject *
PyCurses_Is_Term_Resized(PyObject * self,PyObject * args)2594 PyCurses_Is_Term_Resized(PyObject *self, PyObject *args)
2595 {
2596 int lines;
2597 int columns;
2598 int result;
2599
2600 PyCursesInitialised;
2601
2602 if (!PyArg_ParseTuple(args,"ii:is_term_resized", &lines, &columns))
2603 return NULL;
2604 result = is_term_resized(lines, columns);
2605 if (result == TRUE) {
2606 Py_INCREF(Py_True);
2607 return Py_True;
2608 } else {
2609 Py_INCREF(Py_False);
2610 return Py_False;
2611 }
2612 }
2613 #endif /* HAVE_CURSES_IS_TERM_RESIZED */
2614
2615 #if !defined(__NetBSD__)
2616 static PyObject *
PyCurses_KeyName(PyObject * self,PyObject * args)2617 PyCurses_KeyName(PyObject *self, PyObject *args)
2618 {
2619 const char *knp;
2620 int ch;
2621
2622 PyCursesInitialised;
2623
2624 if (!PyArg_ParseTuple(args,"i",&ch)) return NULL;
2625
2626 if (ch < 0) {
2627 PyErr_SetString(PyExc_ValueError, "invalid key number");
2628 return NULL;
2629 }
2630 knp = keyname(ch);
2631
2632 return PyBytes_FromString((knp == NULL) ? "" : knp);
2633 }
2634 #endif
2635
2636 static PyObject *
PyCurses_KillChar(PyObject * self)2637 PyCurses_KillChar(PyObject *self)
2638 {
2639 char ch;
2640
2641 ch = killchar();
2642
2643 return PyBytes_FromStringAndSize(&ch, 1);
2644 }
2645
2646 static PyObject *
PyCurses_Meta(PyObject * self,PyObject * args)2647 PyCurses_Meta(PyObject *self, PyObject *args)
2648 {
2649 int ch;
2650
2651 PyCursesInitialised;
2652
2653 switch(PyTuple_Size(args)) {
2654 case 1:
2655 if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&ch)) return NULL;
2656 break;
2657 default:
2658 PyErr_SetString(PyExc_TypeError, "meta requires 1 argument");
2659 return NULL;
2660 }
2661
2662 return PyCursesCheckERR(meta(stdscr, ch), "meta");
2663 }
2664
2665 #ifdef NCURSES_MOUSE_VERSION
2666 static PyObject *
PyCurses_MouseInterval(PyObject * self,PyObject * args)2667 PyCurses_MouseInterval(PyObject *self, PyObject *args)
2668 {
2669 int interval;
2670 PyCursesInitialised;
2671
2672 if (!PyArg_ParseTuple(args,"i;interval",&interval))
2673 return NULL;
2674 return PyCursesCheckERR(mouseinterval(interval), "mouseinterval");
2675 }
2676
2677 static PyObject *
PyCurses_MouseMask(PyObject * self,PyObject * args)2678 PyCurses_MouseMask(PyObject *self, PyObject *args)
2679 {
2680 int newmask;
2681 mmask_t oldmask, availmask;
2682
2683 PyCursesInitialised;
2684 if (!PyArg_ParseTuple(args,"i;mousemask",&newmask))
2685 return NULL;
2686 availmask = mousemask(newmask, &oldmask);
2687 return Py_BuildValue("(ll)", (long)availmask, (long)oldmask);
2688 }
2689 #endif
2690
2691 static PyObject *
PyCurses_Napms(PyObject * self,PyObject * args)2692 PyCurses_Napms(PyObject *self, PyObject *args)
2693 {
2694 int ms;
2695
2696 PyCursesInitialised;
2697 if (!PyArg_ParseTuple(args, "i;ms", &ms)) return NULL;
2698
2699 return Py_BuildValue("i", napms(ms));
2700 }
2701
2702
2703 static PyObject *
PyCurses_NewPad(PyObject * self,PyObject * args)2704 PyCurses_NewPad(PyObject *self, PyObject *args)
2705 {
2706 WINDOW *win;
2707 int nlines, ncols;
2708
2709 PyCursesInitialised;
2710
2711 if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols)) return NULL;
2712
2713 win = newpad(nlines, ncols);
2714
2715 if (win == NULL) {
2716 PyErr_SetString(PyCursesError, catchall_NULL);
2717 return NULL;
2718 }
2719
2720 return (PyObject *)PyCursesWindow_New(win, NULL);
2721 }
2722
2723 static PyObject *
PyCurses_NewWindow(PyObject * self,PyObject * args)2724 PyCurses_NewWindow(PyObject *self, PyObject *args)
2725 {
2726 WINDOW *win;
2727 int nlines, ncols, begin_y=0, begin_x=0;
2728
2729 PyCursesInitialised;
2730
2731 switch (PyTuple_Size(args)) {
2732 case 2:
2733 if (!PyArg_ParseTuple(args,"ii;nlines,ncols",&nlines,&ncols))
2734 return NULL;
2735 break;
2736 case 4:
2737 if (!PyArg_ParseTuple(args, "iiii;nlines,ncols,begin_y,begin_x",
2738 &nlines,&ncols,&begin_y,&begin_x))
2739 return NULL;
2740 break;
2741 default:
2742 PyErr_SetString(PyExc_TypeError, "newwin requires 2 or 4 arguments");
2743 return NULL;
2744 }
2745
2746 win = newwin(nlines,ncols,begin_y,begin_x);
2747 if (win == NULL) {
2748 PyErr_SetString(PyCursesError, catchall_NULL);
2749 return NULL;
2750 }
2751
2752 return (PyObject *)PyCursesWindow_New(win, NULL);
2753 }
2754
2755 static PyObject *
PyCurses_Pair_Content(PyObject * self,PyObject * args)2756 PyCurses_Pair_Content(PyObject *self, PyObject *args)
2757 {
2758 short pair,f,b;
2759
2760 PyCursesInitialised;
2761 PyCursesInitialisedColor;
2762
2763 switch(PyTuple_Size(args)) {
2764 case 1:
2765 if (!PyArg_ParseTuple(args, "h;pair", &pair)) return NULL;
2766 break;
2767 default:
2768 PyErr_SetString(PyExc_TypeError, "pair_content requires 1 argument");
2769 return NULL;
2770 }
2771
2772 if (pair_content(pair, &f, &b)==ERR) {
2773 PyErr_SetString(PyCursesError,
2774 "Argument 1 was out of range. (1..COLOR_PAIRS-1)");
2775 return NULL;
2776 }
2777
2778 return Py_BuildValue("(ii)", f, b);
2779 }
2780
2781 static PyObject *
PyCurses_pair_number(PyObject * self,PyObject * args)2782 PyCurses_pair_number(PyObject *self, PyObject *args)
2783 {
2784 int n;
2785
2786 PyCursesInitialised;
2787 PyCursesInitialisedColor;
2788
2789 switch(PyTuple_Size(args)) {
2790 case 1:
2791 if (!PyArg_ParseTuple(args, "i;pairvalue", &n)) return NULL;
2792 break;
2793 default:
2794 PyErr_SetString(PyExc_TypeError,
2795 "pair_number requires 1 argument");
2796 return NULL;
2797 }
2798
2799 return PyLong_FromLong((long) ((n & A_COLOR) >> 8));
2800 }
2801
2802 static PyObject *
PyCurses_Putp(PyObject * self,PyObject * args)2803 PyCurses_Putp(PyObject *self, PyObject *args)
2804 {
2805 char *str;
2806
2807 if (!PyArg_ParseTuple(args,"y;str", &str))
2808 return NULL;
2809 return PyCursesCheckERR(putp(str), "putp");
2810 }
2811
2812 static PyObject *
PyCurses_QiFlush(PyObject * self,PyObject * args)2813 PyCurses_QiFlush(PyObject *self, PyObject *args)
2814 {
2815 int flag = 0;
2816
2817 PyCursesInitialised;
2818
2819 switch(PyTuple_Size(args)) {
2820 case 0:
2821 qiflush();
2822 Py_INCREF(Py_None);
2823 return Py_None;
2824 case 1:
2825 if (!PyArg_ParseTuple(args, "i;True(1) or False(0)", &flag)) return NULL;
2826 if (flag) qiflush();
2827 else noqiflush();
2828 Py_INCREF(Py_None);
2829 return Py_None;
2830 default:
2831 PyErr_SetString(PyExc_TypeError, "qiflush requires 0 or 1 arguments");
2832 return NULL;
2833 }
2834 }
2835
2836 /* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES
2837 * and _curses.COLS */
2838 #if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)
2839 static int
update_lines_cols(void)2840 update_lines_cols(void)
2841 {
2842 PyObject *o;
2843 PyObject *m = PyImport_ImportModuleNoBlock("curses");
2844 _Py_IDENTIFIER(LINES);
2845 _Py_IDENTIFIER(COLS);
2846
2847 if (!m)
2848 return 0;
2849
2850 o = PyLong_FromLong(LINES);
2851 if (!o) {
2852 Py_DECREF(m);
2853 return 0;
2854 }
2855 if (_PyObject_SetAttrId(m, &PyId_LINES, o)) {
2856 Py_DECREF(m);
2857 Py_DECREF(o);
2858 return 0;
2859 }
2860 /* PyId_LINES.object will be initialized here. */
2861 if (PyDict_SetItem(ModDict, PyId_LINES.object, o)) {
2862 Py_DECREF(m);
2863 Py_DECREF(o);
2864 return 0;
2865 }
2866 Py_DECREF(o);
2867 o = PyLong_FromLong(COLS);
2868 if (!o) {
2869 Py_DECREF(m);
2870 return 0;
2871 }
2872 if (_PyObject_SetAttrId(m, &PyId_COLS, o)) {
2873 Py_DECREF(m);
2874 Py_DECREF(o);
2875 return 0;
2876 }
2877 if (PyDict_SetItem(ModDict, PyId_COLS.object, o)) {
2878 Py_DECREF(m);
2879 Py_DECREF(o);
2880 return 0;
2881 }
2882 Py_DECREF(o);
2883 Py_DECREF(m);
2884 return 1;
2885 }
2886
2887 static PyObject *
PyCurses_update_lines_cols(PyObject * self)2888 PyCurses_update_lines_cols(PyObject *self)
2889 {
2890 return PyLong_FromLong((long) update_lines_cols());
2891 }
2892
2893 #endif
2894
2895 #ifdef HAVE_CURSES_RESIZETERM
2896 static PyObject *
PyCurses_ResizeTerm(PyObject * self,PyObject * args)2897 PyCurses_ResizeTerm(PyObject *self, PyObject *args)
2898 {
2899 int lines;
2900 int columns;
2901 PyObject *result;
2902
2903 PyCursesInitialised;
2904
2905 if (!PyArg_ParseTuple(args,"ii:resizeterm", &lines, &columns))
2906 return NULL;
2907
2908 result = PyCursesCheckERR(resizeterm(lines, columns), "resizeterm");
2909 if (!result)
2910 return NULL;
2911 if (!update_lines_cols())
2912 return NULL;
2913 return result;
2914 }
2915
2916 #endif
2917
2918 #ifdef HAVE_CURSES_RESIZE_TERM
2919 static PyObject *
PyCurses_Resize_Term(PyObject * self,PyObject * args)2920 PyCurses_Resize_Term(PyObject *self, PyObject *args)
2921 {
2922 int lines;
2923 int columns;
2924
2925 PyObject *result;
2926
2927 PyCursesInitialised;
2928
2929 if (!PyArg_ParseTuple(args,"ii:resize_term", &lines, &columns))
2930 return NULL;
2931
2932 result = PyCursesCheckERR(resize_term(lines, columns), "resize_term");
2933 if (!result)
2934 return NULL;
2935 if (!update_lines_cols())
2936 return NULL;
2937 return result;
2938 }
2939 #endif /* HAVE_CURSES_RESIZE_TERM */
2940
2941 static PyObject *
PyCurses_setsyx(PyObject * self,PyObject * args)2942 PyCurses_setsyx(PyObject *self, PyObject *args)
2943 {
2944 int y,x;
2945
2946 PyCursesInitialised;
2947
2948 if (PyTuple_Size(args)!=2) {
2949 PyErr_SetString(PyExc_TypeError, "setsyx requires 2 arguments");
2950 return NULL;
2951 }
2952
2953 if (!PyArg_ParseTuple(args, "ii;y, x", &y, &x)) return NULL;
2954
2955 setsyx(y,x);
2956
2957 Py_INCREF(Py_None);
2958 return Py_None;
2959 }
2960
2961 static PyObject *
PyCurses_Start_Color(PyObject * self)2962 PyCurses_Start_Color(PyObject *self)
2963 {
2964 int code;
2965 PyObject *c, *cp;
2966
2967 PyCursesInitialised;
2968
2969 code = start_color();
2970 if (code != ERR) {
2971 initialisedcolors = TRUE;
2972 c = PyLong_FromLong((long) COLORS);
2973 if (c == NULL)
2974 return NULL;
2975 PyDict_SetItemString(ModDict, "COLORS", c);
2976 Py_DECREF(c);
2977 cp = PyLong_FromLong((long) COLOR_PAIRS);
2978 if (cp == NULL)
2979 return NULL;
2980 PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp);
2981 Py_DECREF(cp);
2982 Py_INCREF(Py_None);
2983 return Py_None;
2984 } else {
2985 PyErr_SetString(PyCursesError, "start_color() returned ERR");
2986 return NULL;
2987 }
2988 }
2989
2990 static PyObject *
PyCurses_tigetflag(PyObject * self,PyObject * args)2991 PyCurses_tigetflag(PyObject *self, PyObject *args)
2992 {
2993 char *capname;
2994
2995 PyCursesSetupTermCalled;
2996
2997 if (!PyArg_ParseTuple(args, "s", &capname))
2998 return NULL;
2999
3000 return PyLong_FromLong( (long) tigetflag( capname ) );
3001 }
3002
3003 static PyObject *
PyCurses_tigetnum(PyObject * self,PyObject * args)3004 PyCurses_tigetnum(PyObject *self, PyObject *args)
3005 {
3006 char *capname;
3007
3008 PyCursesSetupTermCalled;
3009
3010 if (!PyArg_ParseTuple(args, "s", &capname))
3011 return NULL;
3012
3013 return PyLong_FromLong( (long) tigetnum( capname ) );
3014 }
3015
3016 static PyObject *
PyCurses_tigetstr(PyObject * self,PyObject * args)3017 PyCurses_tigetstr(PyObject *self, PyObject *args)
3018 {
3019 char *capname;
3020
3021 PyCursesSetupTermCalled;
3022
3023 if (!PyArg_ParseTuple(args, "s", &capname))
3024 return NULL;
3025
3026 capname = tigetstr( capname );
3027 if (capname == 0 || capname == (char*) -1) {
3028 Py_INCREF(Py_None);
3029 return Py_None;
3030 }
3031 return PyBytes_FromString( capname );
3032 }
3033
3034 static PyObject *
PyCurses_tparm(PyObject * self,PyObject * args)3035 PyCurses_tparm(PyObject *self, PyObject *args)
3036 {
3037 char* fmt;
3038 char* result = NULL;
3039 int i1=0,i2=0,i3=0,i4=0,i5=0,i6=0,i7=0,i8=0,i9=0;
3040
3041 PyCursesSetupTermCalled;
3042
3043 if (!PyArg_ParseTuple(args, "y|iiiiiiiii:tparm",
3044 &fmt, &i1, &i2, &i3, &i4,
3045 &i5, &i6, &i7, &i8, &i9)) {
3046 return NULL;
3047 }
3048
3049 result = tparm(fmt,i1,i2,i3,i4,i5,i6,i7,i8,i9);
3050 if (!result) {
3051 PyErr_SetString(PyCursesError, "tparm() returned NULL");
3052 return NULL;
3053 }
3054
3055 return PyBytes_FromString(result);
3056 }
3057
3058 static PyObject *
PyCurses_TypeAhead(PyObject * self,PyObject * args)3059 PyCurses_TypeAhead(PyObject *self, PyObject *args)
3060 {
3061 int fd;
3062
3063 PyCursesInitialised;
3064
3065 if (!PyArg_ParseTuple(args,"i;fd",&fd)) return NULL;
3066
3067 return PyCursesCheckERR(typeahead( fd ), "typeahead");
3068 }
3069
3070 static PyObject *
PyCurses_UnCtrl(PyObject * self,PyObject * args)3071 PyCurses_UnCtrl(PyObject *self, PyObject *args)
3072 {
3073 PyObject *temp;
3074 chtype ch;
3075
3076 PyCursesInitialised;
3077
3078 if (!PyArg_ParseTuple(args,"O;ch or int",&temp)) return NULL;
3079
3080 if (!PyCurses_ConvertToChtype(NULL, temp, &ch))
3081 return NULL;
3082
3083 return PyBytes_FromString(unctrl(ch));
3084 }
3085
3086 static PyObject *
PyCurses_UngetCh(PyObject * self,PyObject * args)3087 PyCurses_UngetCh(PyObject *self, PyObject *args)
3088 {
3089 PyObject *temp;
3090 chtype ch;
3091
3092 PyCursesInitialised;
3093
3094 if (!PyArg_ParseTuple(args,"O;ch or int",&temp))
3095 return NULL;
3096
3097 if (!PyCurses_ConvertToChtype(NULL, temp, &ch))
3098 return NULL;
3099
3100 return PyCursesCheckERR(ungetch(ch), "ungetch");
3101 }
3102
3103 #ifdef HAVE_NCURSESW
3104 /* Convert an object to a character (wchar_t):
3105
3106 - int
3107 - str of length 1
3108
3109 Return 1 on success, 0 on error. */
3110 static int
PyCurses_ConvertToWchar_t(PyObject * obj,wchar_t * wch)3111 PyCurses_ConvertToWchar_t(PyObject *obj,
3112 wchar_t *wch)
3113 {
3114 if (PyUnicode_Check(obj)) {
3115 wchar_t buffer[2];
3116 if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) {
3117 PyErr_Format(PyExc_TypeError,
3118 "expect bytes or str of length 1, or int, "
3119 "got a str of length %zi",
3120 PyUnicode_GET_LENGTH(obj));
3121 return 0;
3122 }
3123 *wch = buffer[0];
3124 return 2;
3125 }
3126 else if (PyLong_CheckExact(obj)) {
3127 long value;
3128 int overflow;
3129 value = PyLong_AsLongAndOverflow(obj, &overflow);
3130 if (overflow) {
3131 PyErr_SetString(PyExc_OverflowError,
3132 "int doesn't fit in long");
3133 return 0;
3134 }
3135 *wch = (wchar_t)value;
3136 if ((long)*wch != value) {
3137 PyErr_Format(PyExc_OverflowError,
3138 "character doesn't fit in wchar_t");
3139 return 0;
3140 }
3141 return 1;
3142 }
3143 else {
3144 PyErr_Format(PyExc_TypeError,
3145 "expect bytes or str of length 1, or int, got %s",
3146 Py_TYPE(obj)->tp_name);
3147 return 0;
3148 }
3149 }
3150
3151 static PyObject *
PyCurses_Unget_Wch(PyObject * self,PyObject * args)3152 PyCurses_Unget_Wch(PyObject *self, PyObject *args)
3153 {
3154 PyObject *obj;
3155 wchar_t wch;
3156
3157 PyCursesInitialised;
3158
3159 if (!PyArg_ParseTuple(args,"O", &obj))
3160 return NULL;
3161
3162 if (!PyCurses_ConvertToWchar_t(obj, &wch))
3163 return NULL;
3164 return PyCursesCheckERR(unget_wch(wch), "unget_wch");
3165 }
3166 #endif
3167
3168 static PyObject *
PyCurses_Use_Env(PyObject * self,PyObject * args)3169 PyCurses_Use_Env(PyObject *self, PyObject *args)
3170 {
3171 int flag;
3172
3173 switch(PyTuple_Size(args)) {
3174 case 1:
3175 if (!PyArg_ParseTuple(args,"i;True(1), False(0)",&flag))
3176 return NULL;
3177 break;
3178 default:
3179 PyErr_SetString(PyExc_TypeError, "use_env requires 1 argument");
3180 return NULL;
3181 }
3182 use_env(flag);
3183 Py_INCREF(Py_None);
3184 return Py_None;
3185 }
3186
3187 #ifndef STRICT_SYSV_CURSES
3188 static PyObject *
PyCurses_Use_Default_Colors(PyObject * self)3189 PyCurses_Use_Default_Colors(PyObject *self)
3190 {
3191 int code;
3192
3193 PyCursesInitialised;
3194 PyCursesInitialisedColor;
3195
3196 code = use_default_colors();
3197 if (code != ERR) {
3198 Py_INCREF(Py_None);
3199 return Py_None;
3200 } else {
3201 PyErr_SetString(PyCursesError, "use_default_colors() returned ERR");
3202 return NULL;
3203 }
3204 }
3205 #endif /* STRICT_SYSV_CURSES */
3206
3207 /* List of functions defined in the module */
3208
3209 static PyMethodDef PyCurses_methods[] = {
3210 {"baudrate", (PyCFunction)PyCurses_baudrate, METH_NOARGS},
3211 {"beep", (PyCFunction)PyCurses_beep, METH_NOARGS},
3212 {"can_change_color", (PyCFunction)PyCurses_can_change_color, METH_NOARGS},
3213 {"cbreak", (PyCFunction)PyCurses_cbreak, METH_VARARGS},
3214 {"color_content", (PyCFunction)PyCurses_Color_Content, METH_VARARGS},
3215 {"color_pair", (PyCFunction)PyCurses_color_pair, METH_VARARGS},
3216 {"curs_set", (PyCFunction)PyCurses_Curs_Set, METH_VARARGS},
3217 {"def_prog_mode", (PyCFunction)PyCurses_def_prog_mode, METH_NOARGS},
3218 {"def_shell_mode", (PyCFunction)PyCurses_def_shell_mode, METH_NOARGS},
3219 {"delay_output", (PyCFunction)PyCurses_Delay_Output, METH_VARARGS},
3220 {"doupdate", (PyCFunction)PyCurses_doupdate, METH_NOARGS},
3221 {"echo", (PyCFunction)PyCurses_echo, METH_VARARGS},
3222 {"endwin", (PyCFunction)PyCurses_endwin, METH_NOARGS},
3223 {"erasechar", (PyCFunction)PyCurses_EraseChar, METH_NOARGS},
3224 {"filter", (PyCFunction)PyCurses_filter, METH_NOARGS},
3225 {"flash", (PyCFunction)PyCurses_flash, METH_NOARGS},
3226 {"flushinp", (PyCFunction)PyCurses_flushinp, METH_NOARGS},
3227 #ifdef NCURSES_MOUSE_VERSION
3228 {"getmouse", (PyCFunction)PyCurses_GetMouse, METH_NOARGS},
3229 {"ungetmouse", (PyCFunction)PyCurses_UngetMouse, METH_VARARGS},
3230 #endif
3231 {"getsyx", (PyCFunction)PyCurses_getsyx, METH_NOARGS},
3232 {"getwin", (PyCFunction)PyCurses_GetWin, METH_O},
3233 {"has_colors", (PyCFunction)PyCurses_has_colors, METH_NOARGS},
3234 {"has_ic", (PyCFunction)PyCurses_has_ic, METH_NOARGS},
3235 {"has_il", (PyCFunction)PyCurses_has_il, METH_NOARGS},
3236 #ifndef STRICT_SYSV_CURSES
3237 {"has_key", (PyCFunction)PyCurses_has_key, METH_VARARGS},
3238 #endif
3239 {"halfdelay", (PyCFunction)PyCurses_HalfDelay, METH_VARARGS},
3240 {"init_color", (PyCFunction)PyCurses_Init_Color, METH_VARARGS},
3241 {"init_pair", (PyCFunction)PyCurses_Init_Pair, METH_VARARGS},
3242 {"initscr", (PyCFunction)PyCurses_InitScr, METH_NOARGS},
3243 {"intrflush", (PyCFunction)PyCurses_IntrFlush, METH_VARARGS},
3244 {"isendwin", (PyCFunction)PyCurses_isendwin, METH_NOARGS},
3245 #ifdef HAVE_CURSES_IS_TERM_RESIZED
3246 {"is_term_resized", (PyCFunction)PyCurses_Is_Term_Resized, METH_VARARGS},
3247 #endif
3248 #if !defined(__NetBSD__)
3249 {"keyname", (PyCFunction)PyCurses_KeyName, METH_VARARGS},
3250 #endif
3251 {"killchar", (PyCFunction)PyCurses_KillChar, METH_NOARGS},
3252 {"longname", (PyCFunction)PyCurses_longname, METH_NOARGS},
3253 {"meta", (PyCFunction)PyCurses_Meta, METH_VARARGS},
3254 #ifdef NCURSES_MOUSE_VERSION
3255 {"mouseinterval", (PyCFunction)PyCurses_MouseInterval, METH_VARARGS},
3256 {"mousemask", (PyCFunction)PyCurses_MouseMask, METH_VARARGS},
3257 #endif
3258 {"napms", (PyCFunction)PyCurses_Napms, METH_VARARGS},
3259 {"newpad", (PyCFunction)PyCurses_NewPad, METH_VARARGS},
3260 {"newwin", (PyCFunction)PyCurses_NewWindow, METH_VARARGS},
3261 {"nl", (PyCFunction)PyCurses_nl, METH_VARARGS},
3262 {"nocbreak", (PyCFunction)PyCurses_nocbreak, METH_NOARGS},
3263 {"noecho", (PyCFunction)PyCurses_noecho, METH_NOARGS},
3264 {"nonl", (PyCFunction)PyCurses_nonl, METH_NOARGS},
3265 {"noqiflush", (PyCFunction)PyCurses_noqiflush, METH_NOARGS},
3266 {"noraw", (PyCFunction)PyCurses_noraw, METH_NOARGS},
3267 {"pair_content", (PyCFunction)PyCurses_Pair_Content, METH_VARARGS},
3268 {"pair_number", (PyCFunction)PyCurses_pair_number, METH_VARARGS},
3269 {"putp", (PyCFunction)PyCurses_Putp, METH_VARARGS},
3270 {"qiflush", (PyCFunction)PyCurses_QiFlush, METH_VARARGS},
3271 {"raw", (PyCFunction)PyCurses_raw, METH_VARARGS},
3272 {"reset_prog_mode", (PyCFunction)PyCurses_reset_prog_mode, METH_NOARGS},
3273 {"reset_shell_mode", (PyCFunction)PyCurses_reset_shell_mode, METH_NOARGS},
3274 {"resetty", (PyCFunction)PyCurses_resetty, METH_NOARGS},
3275 #ifdef HAVE_CURSES_RESIZETERM
3276 {"resizeterm", (PyCFunction)PyCurses_ResizeTerm, METH_VARARGS},
3277 #endif
3278 #ifdef HAVE_CURSES_RESIZE_TERM
3279 {"resize_term", (PyCFunction)PyCurses_Resize_Term, METH_VARARGS},
3280 #endif
3281 {"savetty", (PyCFunction)PyCurses_savetty, METH_NOARGS},
3282 {"setsyx", (PyCFunction)PyCurses_setsyx, METH_VARARGS},
3283 {"setupterm", (PyCFunction)PyCurses_setupterm,
3284 METH_VARARGS|METH_KEYWORDS},
3285 {"start_color", (PyCFunction)PyCurses_Start_Color, METH_NOARGS},
3286 {"termattrs", (PyCFunction)PyCurses_termattrs, METH_NOARGS},
3287 {"termname", (PyCFunction)PyCurses_termname, METH_NOARGS},
3288 {"tigetflag", (PyCFunction)PyCurses_tigetflag, METH_VARARGS},
3289 {"tigetnum", (PyCFunction)PyCurses_tigetnum, METH_VARARGS},
3290 {"tigetstr", (PyCFunction)PyCurses_tigetstr, METH_VARARGS},
3291 {"tparm", (PyCFunction)PyCurses_tparm, METH_VARARGS},
3292 {"typeahead", (PyCFunction)PyCurses_TypeAhead, METH_VARARGS},
3293 {"unctrl", (PyCFunction)PyCurses_UnCtrl, METH_VARARGS},
3294 {"ungetch", (PyCFunction)PyCurses_UngetCh, METH_VARARGS},
3295 #if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)
3296 {"update_lines_cols", (PyCFunction)PyCurses_update_lines_cols, METH_NOARGS},
3297 #endif
3298 #ifdef HAVE_NCURSESW
3299 {"unget_wch", (PyCFunction)PyCurses_Unget_Wch, METH_VARARGS},
3300 #endif
3301 {"use_env", (PyCFunction)PyCurses_Use_Env, METH_VARARGS},
3302 #ifndef STRICT_SYSV_CURSES
3303 {"use_default_colors", (PyCFunction)PyCurses_Use_Default_Colors, METH_NOARGS},
3304 #endif
3305 {NULL, NULL} /* sentinel */
3306 };
3307
3308 /* Initialization function for the module */
3309
3310
3311 static struct PyModuleDef _cursesmodule = {
3312 PyModuleDef_HEAD_INIT,
3313 "_curses",
3314 NULL,
3315 -1,
3316 PyCurses_methods,
3317 NULL,
3318 NULL,
3319 NULL,
3320 NULL
3321 };
3322
3323 PyMODINIT_FUNC
PyInit__curses(void)3324 PyInit__curses(void)
3325 {
3326 PyObject *m, *d, *v, *c_api_object;
3327 static void *PyCurses_API[PyCurses_API_pointers];
3328
3329 /* Initialize object type */
3330 if (PyType_Ready(&PyCursesWindow_Type) < 0)
3331 return NULL;
3332
3333 /* Initialize the C API pointer array */
3334 PyCurses_API[0] = (void *)&PyCursesWindow_Type;
3335 PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled;
3336 PyCurses_API[2] = (void *)func_PyCursesInitialised;
3337 PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
3338
3339 /* Create the module and add the functions */
3340 m = PyModule_Create(&_cursesmodule);
3341 if (m == NULL)
3342 return NULL;
3343
3344 /* Add some symbolic constants to the module */
3345 d = PyModule_GetDict(m);
3346 if (d == NULL)
3347 return NULL;
3348 ModDict = d; /* For PyCurses_InitScr to use later */
3349
3350 /* Add a capsule for the C API */
3351 c_api_object = PyCapsule_New(PyCurses_API, PyCurses_CAPSULE_NAME, NULL);
3352 PyDict_SetItemString(d, "_C_API", c_api_object);
3353 Py_DECREF(c_api_object);
3354
3355 /* For exception curses.error */
3356 PyCursesError = PyErr_NewException("_curses.error", NULL, NULL);
3357 PyDict_SetItemString(d, "error", PyCursesError);
3358
3359 /* Make the version available */
3360 v = PyBytes_FromString(PyCursesVersion);
3361 PyDict_SetItemString(d, "version", v);
3362 PyDict_SetItemString(d, "__version__", v);
3363 Py_DECREF(v);
3364
3365 SetDictInt("ERR", ERR);
3366 SetDictInt("OK", OK);
3367
3368 /* Here are some attributes you can add to chars to print */
3369
3370 SetDictInt("A_ATTRIBUTES", A_ATTRIBUTES);
3371 SetDictInt("A_NORMAL", A_NORMAL);
3372 SetDictInt("A_STANDOUT", A_STANDOUT);
3373 SetDictInt("A_UNDERLINE", A_UNDERLINE);
3374 SetDictInt("A_REVERSE", A_REVERSE);
3375 SetDictInt("A_BLINK", A_BLINK);
3376 SetDictInt("A_DIM", A_DIM);
3377 SetDictInt("A_BOLD", A_BOLD);
3378 SetDictInt("A_ALTCHARSET", A_ALTCHARSET);
3379 #if !defined(__NetBSD__)
3380 SetDictInt("A_INVIS", A_INVIS);
3381 #endif
3382 SetDictInt("A_PROTECT", A_PROTECT);
3383 SetDictInt("A_CHARTEXT", A_CHARTEXT);
3384 SetDictInt("A_COLOR", A_COLOR);
3385
3386 /* The following are never available with strict SYSV curses */
3387 #ifdef A_HORIZONTAL
3388 SetDictInt("A_HORIZONTAL", A_HORIZONTAL);
3389 #endif
3390 #ifdef A_LEFT
3391 SetDictInt("A_LEFT", A_LEFT);
3392 #endif
3393 #ifdef A_LOW
3394 SetDictInt("A_LOW", A_LOW);
3395 #endif
3396 #ifdef A_RIGHT
3397 SetDictInt("A_RIGHT", A_RIGHT);
3398 #endif
3399 #ifdef A_TOP
3400 SetDictInt("A_TOP", A_TOP);
3401 #endif
3402 #ifdef A_VERTICAL
3403 SetDictInt("A_VERTICAL", A_VERTICAL);
3404 #endif
3405
3406 SetDictInt("COLOR_BLACK", COLOR_BLACK);
3407 SetDictInt("COLOR_RED", COLOR_RED);
3408 SetDictInt("COLOR_GREEN", COLOR_GREEN);
3409 SetDictInt("COLOR_YELLOW", COLOR_YELLOW);
3410 SetDictInt("COLOR_BLUE", COLOR_BLUE);
3411 SetDictInt("COLOR_MAGENTA", COLOR_MAGENTA);
3412 SetDictInt("COLOR_CYAN", COLOR_CYAN);
3413 SetDictInt("COLOR_WHITE", COLOR_WHITE);
3414
3415 #ifdef NCURSES_MOUSE_VERSION
3416 /* Mouse-related constants */
3417 SetDictInt("BUTTON1_PRESSED", BUTTON1_PRESSED);
3418 SetDictInt("BUTTON1_RELEASED", BUTTON1_RELEASED);
3419 SetDictInt("BUTTON1_CLICKED", BUTTON1_CLICKED);
3420 SetDictInt("BUTTON1_DOUBLE_CLICKED", BUTTON1_DOUBLE_CLICKED);
3421 SetDictInt("BUTTON1_TRIPLE_CLICKED", BUTTON1_TRIPLE_CLICKED);
3422
3423 SetDictInt("BUTTON2_PRESSED", BUTTON2_PRESSED);
3424 SetDictInt("BUTTON2_RELEASED", BUTTON2_RELEASED);
3425 SetDictInt("BUTTON2_CLICKED", BUTTON2_CLICKED);
3426 SetDictInt("BUTTON2_DOUBLE_CLICKED", BUTTON2_DOUBLE_CLICKED);
3427 SetDictInt("BUTTON2_TRIPLE_CLICKED", BUTTON2_TRIPLE_CLICKED);
3428
3429 SetDictInt("BUTTON3_PRESSED", BUTTON3_PRESSED);
3430 SetDictInt("BUTTON3_RELEASED", BUTTON3_RELEASED);
3431 SetDictInt("BUTTON3_CLICKED", BUTTON3_CLICKED);
3432 SetDictInt("BUTTON3_DOUBLE_CLICKED", BUTTON3_DOUBLE_CLICKED);
3433 SetDictInt("BUTTON3_TRIPLE_CLICKED", BUTTON3_TRIPLE_CLICKED);
3434
3435 SetDictInt("BUTTON4_PRESSED", BUTTON4_PRESSED);
3436 SetDictInt("BUTTON4_RELEASED", BUTTON4_RELEASED);
3437 SetDictInt("BUTTON4_CLICKED", BUTTON4_CLICKED);
3438 SetDictInt("BUTTON4_DOUBLE_CLICKED", BUTTON4_DOUBLE_CLICKED);
3439 SetDictInt("BUTTON4_TRIPLE_CLICKED", BUTTON4_TRIPLE_CLICKED);
3440
3441 SetDictInt("BUTTON_SHIFT", BUTTON_SHIFT);
3442 SetDictInt("BUTTON_CTRL", BUTTON_CTRL);
3443 SetDictInt("BUTTON_ALT", BUTTON_ALT);
3444
3445 SetDictInt("ALL_MOUSE_EVENTS", ALL_MOUSE_EVENTS);
3446 SetDictInt("REPORT_MOUSE_POSITION", REPORT_MOUSE_POSITION);
3447 #endif
3448 /* Now set everything up for KEY_ variables */
3449 {
3450 int key;
3451 char *key_n;
3452 char *key_n2;
3453 #if !defined(__NetBSD__)
3454 for (key=KEY_MIN;key < KEY_MAX; key++) {
3455 key_n = (char *)keyname(key);
3456 if (key_n == NULL || strcmp(key_n,"UNKNOWN KEY")==0)
3457 continue;
3458 if (strncmp(key_n,"KEY_F(",6)==0) {
3459 char *p1, *p2;
3460 key_n2 = PyMem_Malloc(strlen(key_n)+1);
3461 if (!key_n2) {
3462 PyErr_NoMemory();
3463 break;
3464 }
3465 p1 = key_n;
3466 p2 = key_n2;
3467 while (*p1) {
3468 if (*p1 != '(' && *p1 != ')') {
3469 *p2 = *p1;
3470 p2++;
3471 }
3472 p1++;
3473 }
3474 *p2 = (char)0;
3475 } else
3476 key_n2 = key_n;
3477 SetDictInt(key_n2,key);
3478 if (key_n2 != key_n)
3479 PyMem_Free(key_n2);
3480 }
3481 #endif
3482 SetDictInt("KEY_MIN", KEY_MIN);
3483 SetDictInt("KEY_MAX", KEY_MAX);
3484 }
3485 return m;
3486 }
3487