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