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