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 https://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 #ifndef Py_BUILD_CORE_BUILTIN
104 # define Py_BUILD_CORE_MODULE 1
105 #endif
106
107 #define PY_SSIZE_T_CLEAN
108
109 #include "Python.h"
110 #include "pycore_long.h" // _PyLong_GetZero()
111 #include "pycore_structseq.h" // PyStructSequence_InitType()
112
113 #ifdef __hpux
114 #define STRICT_SYSV_CURSES
115 #endif
116
117 #define CURSES_MODULE
118 #include "py_curses.h"
119
120 #if defined(HAVE_TERM_H) || defined(__sgi)
121 /* For termname, longname, putp, tigetflag, tigetnum, tigetstr, tparm
122 which are not declared in SysV curses and for setupterm. */
123 #include <term.h>
124 /* Including <term.h> #defines many common symbols. */
125 #undef lines
126 #undef columns
127 #endif
128
129 #ifdef HAVE_LANGINFO_H
130 #include <langinfo.h>
131 #endif
132
133 #if !defined(HAVE_NCURSES_H) && (defined(sgi) || defined(__sun) || defined(SCO5))
134 #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
135 typedef chtype attr_t; /* No attr_t type is available */
136 #endif
137
138 #if defined(_AIX)
139 #define STRICT_SYSV_CURSES
140 #endif
141
142 #if NCURSES_EXT_FUNCS+0 >= 20170401 && NCURSES_EXT_COLORS+0 >= 20170401
143 #define _NCURSES_EXTENDED_COLOR_FUNCS 1
144 #else
145 #define _NCURSES_EXTENDED_COLOR_FUNCS 0
146 #endif
147
148 #if _NCURSES_EXTENDED_COLOR_FUNCS
149 #define _CURSES_COLOR_VAL_TYPE int
150 #define _CURSES_COLOR_NUM_TYPE int
151 #define _CURSES_INIT_COLOR_FUNC init_extended_color
152 #define _CURSES_INIT_PAIR_FUNC init_extended_pair
153 #define _COLOR_CONTENT_FUNC extended_color_content
154 #define _CURSES_PAIR_CONTENT_FUNC extended_pair_content
155 #else
156 #define _CURSES_COLOR_VAL_TYPE short
157 #define _CURSES_COLOR_NUM_TYPE short
158 #define _CURSES_INIT_COLOR_FUNC init_color
159 #define _CURSES_INIT_PAIR_FUNC init_pair
160 #define _COLOR_CONTENT_FUNC color_content
161 #define _CURSES_PAIR_CONTENT_FUNC pair_content
162 #endif /* _NCURSES_EXTENDED_COLOR_FUNCS */
163
164 /*[clinic input]
165 module _curses
166 class _curses.window "PyCursesWindowObject *" "&PyCursesWindow_Type"
167 [clinic start generated code]*/
168 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=43265c372c2887d6]*/
169
170 /* Definition of exception curses.error */
171
172 static PyObject *PyCursesError;
173
174 /* Tells whether setupterm() has been called to initialise terminfo. */
175 static int initialised_setupterm = FALSE;
176
177 /* Tells whether initscr() has been called to initialise curses. */
178 static int initialised = FALSE;
179
180 /* Tells whether start_color() has been called to initialise color usage. */
181 static int initialisedcolors = FALSE;
182
183 static char *screen_encoding = NULL;
184
185 /* Utility Macros */
186 #define PyCursesSetupTermCalled \
187 if (initialised_setupterm != TRUE) { \
188 PyErr_SetString(PyCursesError, \
189 "must call (at least) setupterm() first"); \
190 return 0; }
191
192 #define PyCursesInitialised \
193 if (initialised != TRUE) { \
194 PyErr_SetString(PyCursesError, \
195 "must call initscr() first"); \
196 return 0; }
197
198 #define PyCursesInitialisedColor \
199 if (initialisedcolors != TRUE) { \
200 PyErr_SetString(PyCursesError, \
201 "must call start_color() first"); \
202 return 0; }
203
204 /* Utility Functions */
205
206 /*
207 * Check the return code from a curses function and return None
208 * or raise an exception as appropriate. These are exported using the
209 * capsule API.
210 */
211
212 static PyObject *
PyCursesCheckERR(int code,const char * fname)213 PyCursesCheckERR(int code, const char *fname)
214 {
215 if (code != ERR) {
216 Py_RETURN_NONE;
217 } else {
218 if (fname == NULL) {
219 PyErr_SetString(PyCursesError, catchall_ERR);
220 } else {
221 PyErr_Format(PyCursesError, "%s() returned ERR", fname);
222 }
223 return NULL;
224 }
225 }
226
227 /* Convert an object to a byte (an integer of type chtype):
228
229 - int
230 - bytes of length 1
231 - str of length 1
232
233 Return 1 on success, 0 on error (invalid type or integer overflow). */
234 static int
PyCurses_ConvertToChtype(PyCursesWindowObject * win,PyObject * obj,chtype * ch)235 PyCurses_ConvertToChtype(PyCursesWindowObject *win, PyObject *obj, chtype *ch)
236 {
237 long value;
238 if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) {
239 value = (unsigned char)PyBytes_AsString(obj)[0];
240 }
241 else if (PyUnicode_Check(obj)) {
242 if (PyUnicode_GetLength(obj) != 1) {
243 PyErr_Format(PyExc_TypeError,
244 "expect bytes or str of length 1, or int, "
245 "got a str of length %zi",
246 PyUnicode_GET_LENGTH(obj));
247 return 0;
248 }
249 value = PyUnicode_READ_CHAR(obj, 0);
250 if (128 < value) {
251 PyObject *bytes;
252 const char *encoding;
253 if (win)
254 encoding = win->encoding;
255 else
256 encoding = screen_encoding;
257 bytes = PyUnicode_AsEncodedString(obj, encoding, NULL);
258 if (bytes == NULL)
259 return 0;
260 if (PyBytes_GET_SIZE(bytes) == 1)
261 value = (unsigned char)PyBytes_AS_STRING(bytes)[0];
262 else
263 value = -1;
264 Py_DECREF(bytes);
265 if (value < 0)
266 goto overflow;
267 }
268 }
269 else if (PyLong_CheckExact(obj)) {
270 int long_overflow;
271 value = PyLong_AsLongAndOverflow(obj, &long_overflow);
272 if (long_overflow)
273 goto overflow;
274 }
275 else {
276 PyErr_Format(PyExc_TypeError,
277 "expect bytes or str of length 1, or int, got %s",
278 Py_TYPE(obj)->tp_name);
279 return 0;
280 }
281 *ch = (chtype)value;
282 if ((long)*ch != value)
283 goto overflow;
284 return 1;
285
286 overflow:
287 PyErr_SetString(PyExc_OverflowError,
288 "byte doesn't fit in chtype");
289 return 0;
290 }
291
292 /* Convert an object to a byte (chtype) or a character (cchar_t):
293
294 - int
295 - bytes of length 1
296 - str of length 1
297
298 Return:
299
300 - 2 if obj is a character (written into *wch)
301 - 1 if obj is a byte (written into *ch)
302 - 0 on error: raise an exception */
303 static int
PyCurses_ConvertToCchar_t(PyCursesWindowObject * win,PyObject * obj,chtype * ch,wchar_t * wch)304 PyCurses_ConvertToCchar_t(PyCursesWindowObject *win, PyObject *obj,
305 chtype *ch
306 #ifdef HAVE_NCURSESW
307 , wchar_t *wch
308 #endif
309 )
310 {
311 long value;
312 #ifdef HAVE_NCURSESW
313 wchar_t buffer[2];
314 #endif
315
316 if (PyUnicode_Check(obj)) {
317 #ifdef HAVE_NCURSESW
318 if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) {
319 PyErr_Format(PyExc_TypeError,
320 "expect bytes or str of length 1, or int, "
321 "got a str of length %zi",
322 PyUnicode_GET_LENGTH(obj));
323 return 0;
324 }
325 *wch = buffer[0];
326 return 2;
327 #else
328 return PyCurses_ConvertToChtype(win, obj, ch);
329 #endif
330 }
331 else if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) {
332 value = (unsigned char)PyBytes_AsString(obj)[0];
333 }
334 else if (PyLong_CheckExact(obj)) {
335 int overflow;
336 value = PyLong_AsLongAndOverflow(obj, &overflow);
337 if (overflow) {
338 PyErr_SetString(PyExc_OverflowError,
339 "int doesn't fit in long");
340 return 0;
341 }
342 }
343 else {
344 PyErr_Format(PyExc_TypeError,
345 "expect bytes or str of length 1, or int, got %s",
346 Py_TYPE(obj)->tp_name);
347 return 0;
348 }
349
350 *ch = (chtype)value;
351 if ((long)*ch != value) {
352 PyErr_Format(PyExc_OverflowError,
353 "byte doesn't fit in chtype");
354 return 0;
355 }
356 return 1;
357 }
358
359 /* Convert an object to a byte string (char*) or a wide character string
360 (wchar_t*). Return:
361
362 - 2 if obj is a character string (written into *wch)
363 - 1 if obj is a byte string (written into *bytes)
364 - 0 on error: raise an exception */
365 static int
PyCurses_ConvertToString(PyCursesWindowObject * win,PyObject * obj,PyObject ** bytes,wchar_t ** wstr)366 PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj,
367 PyObject **bytes, wchar_t **wstr)
368 {
369 char *str;
370 if (PyUnicode_Check(obj)) {
371 #ifdef HAVE_NCURSESW
372 assert (wstr != NULL);
373
374 *wstr = PyUnicode_AsWideCharString(obj, NULL);
375 if (*wstr == NULL)
376 return 0;
377 return 2;
378 #else
379 assert (wstr == NULL);
380 *bytes = PyUnicode_AsEncodedString(obj, win->encoding, NULL);
381 if (*bytes == NULL)
382 return 0;
383 /* check for embedded null bytes */
384 if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) {
385 return 0;
386 }
387 return 1;
388 #endif
389 }
390 else if (PyBytes_Check(obj)) {
391 Py_INCREF(obj);
392 *bytes = obj;
393 /* check for embedded null bytes */
394 if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) {
395 Py_DECREF(obj);
396 return 0;
397 }
398 return 1;
399 }
400
401 PyErr_Format(PyExc_TypeError, "expect bytes or str, got %s",
402 Py_TYPE(obj)->tp_name);
403 return 0;
404 }
405
406 static int
color_allow_default_converter(PyObject * arg,void * ptr)407 color_allow_default_converter(PyObject *arg, void *ptr)
408 {
409 long color_number;
410 int overflow;
411
412 color_number = PyLong_AsLongAndOverflow(arg, &overflow);
413 if (color_number == -1 && PyErr_Occurred())
414 return 0;
415
416 if (overflow > 0 || color_number >= COLORS) {
417 PyErr_Format(PyExc_ValueError,
418 "Color number is greater than COLORS-1 (%d).",
419 COLORS - 1);
420 return 0;
421 }
422 else if (overflow < 0 || color_number < 0) {
423 color_number = -1;
424 }
425
426 *(int *)ptr = (int)color_number;
427 return 1;
428 }
429
430 static int
color_converter(PyObject * arg,void * ptr)431 color_converter(PyObject *arg, void *ptr)
432 {
433 if (!color_allow_default_converter(arg, ptr)) {
434 return 0;
435 }
436 if (*(int *)ptr < 0) {
437 PyErr_SetString(PyExc_ValueError,
438 "Color number is less than 0.");
439 return 0;
440 }
441 return 1;
442 }
443
444 /*[python input]
445 class color_converter(CConverter):
446 type = 'int'
447 converter = 'color_converter'
448 [python start generated code]*/
449 /*[python end generated code: output=da39a3ee5e6b4b0d input=4260d2b6e66b3709]*/
450
451 /*[python input]
452 class color_allow_default_converter(CConverter):
453 type = 'int'
454 converter = 'color_allow_default_converter'
455 [python start generated code]*/
456 /*[python end generated code: output=da39a3ee5e6b4b0d input=975602bc058a872d]*/
457
458 static int
pair_converter(PyObject * arg,void * ptr)459 pair_converter(PyObject *arg, void *ptr)
460 {
461 long pair_number;
462 int overflow;
463
464 pair_number = PyLong_AsLongAndOverflow(arg, &overflow);
465 if (pair_number == -1 && PyErr_Occurred())
466 return 0;
467
468 #if _NCURSES_EXTENDED_COLOR_FUNCS
469 if (overflow > 0 || pair_number > INT_MAX) {
470 PyErr_Format(PyExc_ValueError,
471 "Color pair is greater than maximum (%d).",
472 INT_MAX);
473 return 0;
474 }
475 #else
476 if (overflow > 0 || pair_number >= COLOR_PAIRS) {
477 PyErr_Format(PyExc_ValueError,
478 "Color pair is greater than COLOR_PAIRS-1 (%d).",
479 COLOR_PAIRS - 1);
480 return 0;
481 }
482 #endif
483 else if (overflow < 0 || pair_number < 0) {
484 PyErr_SetString(PyExc_ValueError,
485 "Color pair is less than 0.");
486 return 0;
487 }
488
489 *(int *)ptr = (int)pair_number;
490 return 1;
491 }
492
493 /*[python input]
494 class pair_converter(CConverter):
495 type = 'int'
496 converter = 'pair_converter'
497 [python start generated code]*/
498 /*[python end generated code: output=da39a3ee5e6b4b0d input=1a918ae6a1b32af7]*/
499
500 static int
component_converter(PyObject * arg,void * ptr)501 component_converter(PyObject *arg, void *ptr)
502 {
503 long component;
504 int overflow;
505
506 component = PyLong_AsLongAndOverflow(arg, &overflow);
507 if (component == -1 && PyErr_Occurred())
508 return 0;
509
510 if (overflow > 0 || component > 1000) {
511 PyErr_SetString(PyExc_ValueError,
512 "Color component is greater than 1000");
513 return 0;
514 }
515 else if (overflow < 0 || component < 0) {
516 PyErr_SetString(PyExc_ValueError,
517 "Color component is less than 0");
518 return 0;
519 }
520
521 *(short *)ptr = (short)component;
522 return 1;
523 }
524
525 /*[python input]
526 class component_converter(CConverter):
527 type = 'short'
528 converter = 'component_converter'
529 [python start generated code]*/
530 /*[python end generated code: output=da39a3ee5e6b4b0d input=38e9be01d33927fb]*/
531
532 /* Function versions of the 3 functions for testing whether curses has been
533 initialised or not. */
534
func_PyCursesSetupTermCalled(void)535 static int func_PyCursesSetupTermCalled(void)
536 {
537 PyCursesSetupTermCalled;
538 return 1;
539 }
540
func_PyCursesInitialised(void)541 static int func_PyCursesInitialised(void)
542 {
543 PyCursesInitialised;
544 return 1;
545 }
546
func_PyCursesInitialisedColor(void)547 static int func_PyCursesInitialisedColor(void)
548 {
549 PyCursesInitialisedColor;
550 return 1;
551 }
552
553 /*****************************************************************************
554 The Window Object
555 ******************************************************************************/
556
557 /* Definition of the window type */
558
559 PyTypeObject PyCursesWindow_Type;
560
561 /* Function prototype macros for Window object
562
563 X - function name
564 TYPE - parameter Type
565 ERGSTR - format string for construction of the return value
566 PARSESTR - format string for argument parsing
567 */
568
569 #define Window_NoArgNoReturnFunction(X) \
570 static PyObject *PyCursesWindow_ ## X \
571 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \
572 { return PyCursesCheckERR(X(self->win), # X); }
573
574 #define Window_NoArgTrueFalseFunction(X) \
575 static PyObject * PyCursesWindow_ ## X \
576 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \
577 { \
578 return PyBool_FromLong(X(self->win)); }
579
580 #define Window_NoArgNoReturnVoidFunction(X) \
581 static PyObject * PyCursesWindow_ ## X \
582 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \
583 { \
584 X(self->win); Py_RETURN_NONE; }
585
586 #define Window_NoArg2TupleReturnFunction(X, TYPE, ERGSTR) \
587 static PyObject * PyCursesWindow_ ## X \
588 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \
589 { \
590 TYPE arg1, arg2; \
591 X(self->win,arg1,arg2); return Py_BuildValue(ERGSTR, arg1, arg2); }
592
593 #define Window_OneArgNoReturnVoidFunction(X, TYPE, PARSESTR) \
594 static PyObject * PyCursesWindow_ ## X \
595 (PyCursesWindowObject *self, PyObject *args) \
596 { \
597 TYPE arg1; \
598 if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) return NULL; \
599 X(self->win,arg1); Py_RETURN_NONE; }
600
601 #define Window_OneArgNoReturnFunction(X, TYPE, PARSESTR) \
602 static PyObject * PyCursesWindow_ ## X \
603 (PyCursesWindowObject *self, PyObject *args) \
604 { \
605 TYPE arg1; \
606 if (!PyArg_ParseTuple(args,PARSESTR, &arg1)) return NULL; \
607 return PyCursesCheckERR(X(self->win, arg1), # X); }
608
609 #define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \
610 static PyObject * PyCursesWindow_ ## X \
611 (PyCursesWindowObject *self, PyObject *args) \
612 { \
613 TYPE arg1, arg2; \
614 if (!PyArg_ParseTuple(args,PARSESTR, &arg1, &arg2)) return NULL; \
615 return PyCursesCheckERR(X(self->win, arg1, arg2), # X); }
616
617 /* ------------- WINDOW routines --------------- */
618
619 Window_NoArgNoReturnFunction(untouchwin)
Window_NoArgNoReturnFunction(touchwin)620 Window_NoArgNoReturnFunction(touchwin)
621 Window_NoArgNoReturnFunction(redrawwin)
622 Window_NoArgNoReturnFunction(winsertln)
623 Window_NoArgNoReturnFunction(werase)
624 Window_NoArgNoReturnFunction(wdeleteln)
625
626 Window_NoArgTrueFalseFunction(is_wintouched)
627
628 Window_NoArgNoReturnVoidFunction(wsyncup)
629 Window_NoArgNoReturnVoidFunction(wsyncdown)
630 Window_NoArgNoReturnVoidFunction(wstandend)
631 Window_NoArgNoReturnVoidFunction(wstandout)
632 Window_NoArgNoReturnVoidFunction(wcursyncup)
633 Window_NoArgNoReturnVoidFunction(wclrtoeol)
634 Window_NoArgNoReturnVoidFunction(wclrtobot)
635 Window_NoArgNoReturnVoidFunction(wclear)
636
637 Window_OneArgNoReturnVoidFunction(idcok, int, "i;True(1) or False(0)")
638 #ifdef HAVE_CURSES_IMMEDOK
639 Window_OneArgNoReturnVoidFunction(immedok, int, "i;True(1) or False(0)")
640 #endif
641 Window_OneArgNoReturnVoidFunction(wtimeout, int, "i;delay")
642
643 Window_NoArg2TupleReturnFunction(getyx, int, "ii")
644 Window_NoArg2TupleReturnFunction(getbegyx, int, "ii")
645 Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii")
646 Window_NoArg2TupleReturnFunction(getparyx, int, "ii")
647
648 Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)")
649 Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)")
650 Window_OneArgNoReturnFunction(keypad, int, "i;True(1) or False(0)")
651 Window_OneArgNoReturnFunction(leaveok, int, "i;True(1) or False(0)")
652 Window_OneArgNoReturnFunction(nodelay, int, "i;True(1) or False(0)")
653 Window_OneArgNoReturnFunction(notimeout, int, "i;True(1) or False(0)")
654 Window_OneArgNoReturnFunction(scrollok, int, "i;True(1) or False(0)")
655 Window_OneArgNoReturnFunction(winsdelln, int, "i;nlines")
656 #ifdef HAVE_CURSES_SYNCOK
657 Window_OneArgNoReturnFunction(syncok, int, "i;True(1) or False(0)")
658 #endif
659
660 Window_TwoArgNoReturnFunction(mvwin, int, "ii;y,x")
661 Window_TwoArgNoReturnFunction(mvderwin, int, "ii;y,x")
662 Window_TwoArgNoReturnFunction(wmove, int, "ii;y,x")
663 #ifndef STRICT_SYSV_CURSES
664 Window_TwoArgNoReturnFunction(wresize, int, "ii;lines,columns")
665 #endif
666
667 /* Allocation and deallocation of Window Objects */
668
669 static PyObject *
670 PyCursesWindow_New(WINDOW *win, const char *encoding)
671 {
672 PyCursesWindowObject *wo;
673
674 if (encoding == NULL) {
675 #if defined(MS_WINDOWS)
676 char *buffer[100];
677 UINT cp;
678 cp = GetConsoleOutputCP();
679 if (cp != 0) {
680 PyOS_snprintf(buffer, sizeof(buffer), "cp%u", cp);
681 encoding = buffer;
682 }
683 #elif defined(CODESET)
684 const char *codeset = nl_langinfo(CODESET);
685 if (codeset != NULL && codeset[0] != 0)
686 encoding = codeset;
687 #endif
688 if (encoding == NULL)
689 encoding = "utf-8";
690 }
691
692 wo = PyObject_New(PyCursesWindowObject, &PyCursesWindow_Type);
693 if (wo == NULL) return NULL;
694 wo->win = win;
695 wo->encoding = _PyMem_Strdup(encoding);
696 if (wo->encoding == NULL) {
697 Py_DECREF(wo);
698 PyErr_NoMemory();
699 return NULL;
700 }
701 return (PyObject *)wo;
702 }
703
704 static void
PyCursesWindow_Dealloc(PyCursesWindowObject * wo)705 PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
706 {
707 if (wo->win != stdscr) delwin(wo->win);
708 if (wo->encoding != NULL)
709 PyMem_Free(wo->encoding);
710 PyObject_Free(wo);
711 }
712
713 /* Addch, Addstr, Addnstr */
714
715 /*[clinic input]
716 _curses.window.addch
717
718 [
719 y: int
720 Y-coordinate.
721 x: int
722 X-coordinate.
723 ]
724
725 ch: object
726 Character to add.
727
728 [
729 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
730 Attributes for the character.
731 ]
732 /
733
734 Paint the character.
735
736 Paint character ch at (y, x) with attributes attr,
737 overwriting any character previously painted at that location.
738 By default, the character position and attributes are the
739 current settings for the window object.
740 [clinic start generated code]*/
741
742 static PyObject *
_curses_window_addch_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * ch,int group_right_1,long attr)743 _curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1,
744 int y, int x, PyObject *ch, int group_right_1,
745 long attr)
746 /*[clinic end generated code: output=00f4c37af3378f45 input=95ce131578458196]*/
747 {
748 int coordinates_group = group_left_1;
749 int rtn;
750 int type;
751 chtype cch = 0;
752 #ifdef HAVE_NCURSESW
753 wchar_t wstr[2];
754 cchar_t wcval;
755 #endif
756 const char *funcname;
757
758 #ifdef HAVE_NCURSESW
759 type = PyCurses_ConvertToCchar_t(self, ch, &cch, wstr);
760 if (type == 2) {
761 funcname = "add_wch";
762 wstr[1] = L'\0';
763 setcchar(&wcval, wstr, attr, PAIR_NUMBER(attr), NULL);
764 if (coordinates_group)
765 rtn = mvwadd_wch(self->win,y,x, &wcval);
766 else {
767 rtn = wadd_wch(self->win, &wcval);
768 }
769 }
770 else
771 #else
772 type = PyCurses_ConvertToCchar_t(self, ch, &cch);
773 #endif
774 if (type == 1) {
775 funcname = "addch";
776 if (coordinates_group)
777 rtn = mvwaddch(self->win,y,x, cch | (attr_t) attr);
778 else {
779 rtn = waddch(self->win, cch | (attr_t) attr);
780 }
781 }
782 else {
783 return NULL;
784 }
785 return PyCursesCheckERR(rtn, funcname);
786 }
787
788 /*[clinic input]
789 _curses.window.addstr
790
791 [
792 y: int
793 Y-coordinate.
794 x: int
795 X-coordinate.
796 ]
797
798 str: object
799 String to add.
800
801 [
802 attr: long
803 Attributes for characters.
804 ]
805 /
806
807 Paint the string.
808
809 Paint the string str at (y, x) with attributes attr,
810 overwriting anything previously on the display.
811 By default, the character position and attributes are the
812 current settings for the window object.
813 [clinic start generated code]*/
814
815 static PyObject *
_curses_window_addstr_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * str,int group_right_1,long attr)816 _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1,
817 int y, int x, PyObject *str, int group_right_1,
818 long attr)
819 /*[clinic end generated code: output=65a928ea85ff3115 input=ff6cbb91448a22a3]*/
820 {
821 int rtn;
822 int strtype;
823 PyObject *bytesobj = NULL;
824 #ifdef HAVE_NCURSESW
825 wchar_t *wstr = NULL;
826 #endif
827 attr_t attr_old = A_NORMAL;
828 int use_xy = group_left_1, use_attr = group_right_1;
829 const char *funcname;
830
831 #ifdef HAVE_NCURSESW
832 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr);
833 #else
834 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL);
835 #endif
836 if (strtype == 0) {
837 return NULL;
838 }
839 if (use_attr) {
840 attr_old = getattrs(self->win);
841 (void)wattrset(self->win,attr);
842 }
843 #ifdef HAVE_NCURSESW
844 if (strtype == 2) {
845 funcname = "addwstr";
846 if (use_xy)
847 rtn = mvwaddwstr(self->win,y,x,wstr);
848 else
849 rtn = waddwstr(self->win,wstr);
850 PyMem_Free(wstr);
851 }
852 else
853 #endif
854 {
855 const char *str = PyBytes_AS_STRING(bytesobj);
856 funcname = "addstr";
857 if (use_xy)
858 rtn = mvwaddstr(self->win,y,x,str);
859 else
860 rtn = waddstr(self->win,str);
861 Py_DECREF(bytesobj);
862 }
863 if (use_attr)
864 (void)wattrset(self->win,attr_old);
865 return PyCursesCheckERR(rtn, funcname);
866 }
867
868 /*[clinic input]
869 _curses.window.addnstr
870
871 [
872 y: int
873 Y-coordinate.
874 x: int
875 X-coordinate.
876 ]
877
878 str: object
879 String to add.
880
881 n: int
882 Maximal number of characters.
883
884 [
885 attr: long
886 Attributes for characters.
887 ]
888 /
889
890 Paint at most n characters of the string.
891
892 Paint at most n characters of the string str at (y, x) with
893 attributes attr, overwriting anything previously on the display.
894 By default, the character position and attributes are the
895 current settings for the window object.
896 [clinic start generated code]*/
897
898 static PyObject *
_curses_window_addnstr_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * str,int n,int group_right_1,long attr)899 _curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1,
900 int y, int x, PyObject *str, int n,
901 int group_right_1, long attr)
902 /*[clinic end generated code: output=6d21cee2ce6876d9 input=72718415c2744a2a]*/
903 {
904 int rtn;
905 int strtype;
906 PyObject *bytesobj = NULL;
907 #ifdef HAVE_NCURSESW
908 wchar_t *wstr = NULL;
909 #endif
910 attr_t attr_old = A_NORMAL;
911 int use_xy = group_left_1, use_attr = group_right_1;
912 const char *funcname;
913
914 #ifdef HAVE_NCURSESW
915 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr);
916 #else
917 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL);
918 #endif
919 if (strtype == 0)
920 return NULL;
921
922 if (use_attr) {
923 attr_old = getattrs(self->win);
924 (void)wattrset(self->win,attr);
925 }
926 #ifdef HAVE_NCURSESW
927 if (strtype == 2) {
928 funcname = "addnwstr";
929 if (use_xy)
930 rtn = mvwaddnwstr(self->win,y,x,wstr,n);
931 else
932 rtn = waddnwstr(self->win,wstr,n);
933 PyMem_Free(wstr);
934 }
935 else
936 #endif
937 {
938 const char *str = PyBytes_AS_STRING(bytesobj);
939 funcname = "addnstr";
940 if (use_xy)
941 rtn = mvwaddnstr(self->win,y,x,str,n);
942 else
943 rtn = waddnstr(self->win,str,n);
944 Py_DECREF(bytesobj);
945 }
946 if (use_attr)
947 (void)wattrset(self->win,attr_old);
948 return PyCursesCheckERR(rtn, funcname);
949 }
950
951 /*[clinic input]
952 _curses.window.bkgd
953
954 ch: object
955 Background character.
956 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
957 Background attributes.
958 /
959
960 Set the background property of the window.
961 [clinic start generated code]*/
962
963 static PyObject *
_curses_window_bkgd_impl(PyCursesWindowObject * self,PyObject * ch,long attr)964 _curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr)
965 /*[clinic end generated code: output=058290afb2cf4034 input=634015bcb339283d]*/
966 {
967 chtype bkgd;
968
969 if (!PyCurses_ConvertToChtype(self, ch, &bkgd))
970 return NULL;
971
972 return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd");
973 }
974
975 /*[clinic input]
976 _curses.window.attroff
977
978 attr: long
979 /
980
981 Remove attribute attr from the "background" set.
982 [clinic start generated code]*/
983
984 static PyObject *
_curses_window_attroff_impl(PyCursesWindowObject * self,long attr)985 _curses_window_attroff_impl(PyCursesWindowObject *self, long attr)
986 /*[clinic end generated code: output=8a2fcd4df682fc64 input=786beedf06a7befe]*/
987 {
988 return PyCursesCheckERR(wattroff(self->win, (attr_t)attr), "attroff");
989 }
990
991 /*[clinic input]
992 _curses.window.attron
993
994 attr: long
995 /
996
997 Add attribute attr from the "background" set.
998 [clinic start generated code]*/
999
1000 static PyObject *
_curses_window_attron_impl(PyCursesWindowObject * self,long attr)1001 _curses_window_attron_impl(PyCursesWindowObject *self, long attr)
1002 /*[clinic end generated code: output=7afea43b237fa870 input=5a88fba7b1524f32]*/
1003 {
1004 return PyCursesCheckERR(wattron(self->win, (attr_t)attr), "attron");
1005 }
1006
1007 /*[clinic input]
1008 _curses.window.attrset
1009
1010 attr: long
1011 /
1012
1013 Set the "background" set of attributes.
1014 [clinic start generated code]*/
1015
1016 static PyObject *
_curses_window_attrset_impl(PyCursesWindowObject * self,long attr)1017 _curses_window_attrset_impl(PyCursesWindowObject *self, long attr)
1018 /*[clinic end generated code: output=84e379bff20c0433 input=42e400c0d0154ab5]*/
1019 {
1020 return PyCursesCheckERR(wattrset(self->win, (attr_t)attr), "attrset");
1021 }
1022
1023 /*[clinic input]
1024 _curses.window.bkgdset
1025
1026 ch: object
1027 Background character.
1028 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
1029 Background attributes.
1030 /
1031
1032 Set the window's background.
1033 [clinic start generated code]*/
1034
1035 static PyObject *
_curses_window_bkgdset_impl(PyCursesWindowObject * self,PyObject * ch,long attr)1036 _curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch,
1037 long attr)
1038 /*[clinic end generated code: output=8cb994fc4d7e2496 input=e09c682425c9e45b]*/
1039 {
1040 chtype bkgd;
1041
1042 if (!PyCurses_ConvertToChtype(self, ch, &bkgd))
1043 return NULL;
1044
1045 wbkgdset(self->win, bkgd | attr);
1046 return PyCursesCheckERR(0, "bkgdset");
1047 }
1048
1049 /*[clinic input]
1050 _curses.window.border
1051
1052 ls: object(c_default="NULL") = _curses.ACS_VLINE
1053 Left side.
1054 rs: object(c_default="NULL") = _curses.ACS_VLINE
1055 Right side.
1056 ts: object(c_default="NULL") = _curses.ACS_HLINE
1057 Top side.
1058 bs: object(c_default="NULL") = _curses.ACS_HLINE
1059 Bottom side.
1060 tl: object(c_default="NULL") = _curses.ACS_ULCORNER
1061 Upper-left corner.
1062 tr: object(c_default="NULL") = _curses.ACS_URCORNER
1063 Upper-right corner.
1064 bl: object(c_default="NULL") = _curses.ACS_LLCORNER
1065 Bottom-left corner.
1066 br: object(c_default="NULL") = _curses.ACS_LRCORNER
1067 Bottom-right corner.
1068 /
1069
1070 Draw a border around the edges of the window.
1071
1072 Each parameter specifies the character to use for a specific part of the
1073 border. The characters can be specified as integers or as one-character
1074 strings. A 0 value for any parameter will cause the default character to be
1075 used for that parameter.
1076 [clinic start generated code]*/
1077
1078 static PyObject *
_curses_window_border_impl(PyCursesWindowObject * self,PyObject * ls,PyObject * rs,PyObject * ts,PyObject * bs,PyObject * tl,PyObject * tr,PyObject * bl,PyObject * br)1079 _curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls,
1080 PyObject *rs, PyObject *ts, PyObject *bs,
1081 PyObject *tl, PyObject *tr, PyObject *bl,
1082 PyObject *br)
1083 /*[clinic end generated code: output=670ef38d3d7c2aa3 input=e015f735d67a240b]*/
1084 {
1085 chtype ch[8];
1086 int i;
1087
1088 /* Clear the array of parameters */
1089 for(i=0; i<8; i++)
1090 ch[i] = 0;
1091
1092 #define CONVERTTOCHTYPE(obj, i) \
1093 if ((obj) != NULL && !PyCurses_ConvertToChtype(self, (obj), &ch[(i)])) \
1094 return NULL;
1095
1096 CONVERTTOCHTYPE(ls, 0);
1097 CONVERTTOCHTYPE(rs, 1);
1098 CONVERTTOCHTYPE(ts, 2);
1099 CONVERTTOCHTYPE(bs, 3);
1100 CONVERTTOCHTYPE(tl, 4);
1101 CONVERTTOCHTYPE(tr, 5);
1102 CONVERTTOCHTYPE(bl, 6);
1103 CONVERTTOCHTYPE(br, 7);
1104
1105 #undef CONVERTTOCHTYPE
1106
1107 wborder(self->win,
1108 ch[0], ch[1], ch[2], ch[3],
1109 ch[4], ch[5], ch[6], ch[7]);
1110 Py_RETURN_NONE;
1111 }
1112
1113 /*[clinic input]
1114 _curses.window.box
1115
1116 [
1117 verch: object(c_default="_PyLong_GetZero()") = 0
1118 Left and right side.
1119 horch: object(c_default="_PyLong_GetZero()") = 0
1120 Top and bottom side.
1121 ]
1122 /
1123
1124 Draw a border around the edges of the window.
1125
1126 Similar to border(), but both ls and rs are verch and both ts and bs are
1127 horch. The default corner characters are always used by this function.
1128 [clinic start generated code]*/
1129
1130 static PyObject *
_curses_window_box_impl(PyCursesWindowObject * self,int group_right_1,PyObject * verch,PyObject * horch)1131 _curses_window_box_impl(PyCursesWindowObject *self, int group_right_1,
1132 PyObject *verch, PyObject *horch)
1133 /*[clinic end generated code: output=f3fcb038bb287192 input=f00435f9c8c98f60]*/
1134 {
1135 chtype ch1 = 0, ch2 = 0;
1136 if (group_right_1) {
1137 if (!PyCurses_ConvertToChtype(self, verch, &ch1)) {
1138 return NULL;
1139 }
1140 if (!PyCurses_ConvertToChtype(self, horch, &ch2)) {
1141 return NULL;
1142 }
1143 }
1144 box(self->win,ch1,ch2);
1145 Py_RETURN_NONE;
1146 }
1147
1148 #if defined(HAVE_NCURSES_H) || defined(MVWDELCH_IS_EXPRESSION)
1149 #define py_mvwdelch mvwdelch
1150 #else
py_mvwdelch(WINDOW * w,int y,int x)1151 int py_mvwdelch(WINDOW *w, int y, int x)
1152 {
1153 mvwdelch(w,y,x);
1154 /* On HP/UX, mvwdelch already returns. On other systems,
1155 we may well run into this return statement. */
1156 return 0;
1157 }
1158 #endif
1159
1160 #if defined(HAVE_CURSES_IS_PAD)
1161 #define py_is_pad(win) is_pad(win)
1162 #elif defined(WINDOW_HAS_FLAGS)
1163 #define py_is_pad(win) ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE)
1164 #endif
1165
1166 /* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */
1167 #ifdef HAVE_CURSES_WCHGAT
1168 /*[-clinic input]
1169 _curses.window.chgat
1170
1171 [
1172 y: int
1173 Y-coordinate.
1174 x: int
1175 X-coordinate.
1176 ]
1177
1178 n: int = -1
1179 Number of characters.
1180
1181 attr: long
1182 Attributes for characters.
1183 /
1184
1185 Set the attributes of characters.
1186
1187 Set the attributes of num characters at the current cursor position, or at
1188 position (y, x) if supplied. If no value of num is given or num = -1, the
1189 attribute will be set on all the characters to the end of the line. This
1190 function does not move the cursor. The changed line will be touched using
1191 the touchline() method so that the contents will be redisplayed by the next
1192 window refresh.
1193 [-clinic start generated code]*/
1194 static PyObject *
PyCursesWindow_ChgAt(PyCursesWindowObject * self,PyObject * args)1195 PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args)
1196 {
1197 int rtn;
1198 int x, y;
1199 int num = -1;
1200 short color;
1201 attr_t attr = A_NORMAL;
1202 long lattr;
1203 int use_xy = FALSE;
1204
1205 switch (PyTuple_Size(args)) {
1206 case 1:
1207 if (!PyArg_ParseTuple(args,"l;attr", &lattr))
1208 return NULL;
1209 attr = lattr;
1210 break;
1211 case 2:
1212 if (!PyArg_ParseTuple(args,"il;n,attr", &num, &lattr))
1213 return NULL;
1214 attr = lattr;
1215 break;
1216 case 3:
1217 if (!PyArg_ParseTuple(args,"iil;int,int,attr", &y, &x, &lattr))
1218 return NULL;
1219 attr = lattr;
1220 use_xy = TRUE;
1221 break;
1222 case 4:
1223 if (!PyArg_ParseTuple(args,"iiil;int,int,n,attr", &y, &x, &num, &lattr))
1224 return NULL;
1225 attr = lattr;
1226 use_xy = TRUE;
1227 break;
1228 default:
1229 PyErr_SetString(PyExc_TypeError, "chgat requires 1 to 4 arguments");
1230 return NULL;
1231 }
1232
1233 color = (short)((attr >> 8) & 0xff);
1234 attr = attr - (color << 8);
1235
1236 if (use_xy) {
1237 rtn = mvwchgat(self->win,y,x,num,attr,color,NULL);
1238 touchline(self->win,y,1);
1239 } else {
1240 getyx(self->win,y,x);
1241 rtn = wchgat(self->win,num,attr,color,NULL);
1242 touchline(self->win,y,1);
1243 }
1244 return PyCursesCheckERR(rtn, "chgat");
1245 }
1246 #endif
1247
1248 /*[clinic input]
1249 _curses.window.delch
1250
1251 [
1252 y: int
1253 Y-coordinate.
1254 x: int
1255 X-coordinate.
1256 ]
1257 /
1258
1259 Delete any character at (y, x).
1260 [clinic start generated code]*/
1261
1262 static PyObject *
_curses_window_delch_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1263 _curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1,
1264 int y, int x)
1265 /*[clinic end generated code: output=22e77bb9fa11b461 input=d2f79e630a4fc6d0]*/
1266 {
1267 if (!group_right_1) {
1268 return PyCursesCheckERR(wdelch(self->win), "wdelch");
1269 }
1270 else {
1271 return PyCursesCheckERR(py_mvwdelch(self->win, y, x), "mvwdelch");
1272 }
1273 }
1274
1275 /*[clinic input]
1276 _curses.window.derwin
1277
1278 [
1279 nlines: int = 0
1280 Height.
1281 ncols: int = 0
1282 Width.
1283 ]
1284 begin_y: int
1285 Top side y-coordinate.
1286 begin_x: int
1287 Left side x-coordinate.
1288 /
1289
1290 Create a sub-window (window-relative coordinates).
1291
1292 derwin() is the same as calling subwin(), except that begin_y and begin_x
1293 are relative to the origin of the window, rather than relative to the entire
1294 screen.
1295 [clinic start generated code]*/
1296
1297 static PyObject *
_curses_window_derwin_impl(PyCursesWindowObject * self,int group_left_1,int nlines,int ncols,int begin_y,int begin_x)1298 _curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1,
1299 int nlines, int ncols, int begin_y, int begin_x)
1300 /*[clinic end generated code: output=7924b112d9f70d6e input=966d9481f7f5022e]*/
1301 {
1302 WINDOW *win;
1303
1304 win = derwin(self->win,nlines,ncols,begin_y,begin_x);
1305
1306 if (win == NULL) {
1307 PyErr_SetString(PyCursesError, catchall_NULL);
1308 return NULL;
1309 }
1310
1311 return (PyObject *)PyCursesWindow_New(win, NULL);
1312 }
1313
1314 /*[clinic input]
1315 _curses.window.echochar
1316
1317 ch: object
1318 Character to add.
1319
1320 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
1321 Attributes for the character.
1322 /
1323
1324 Add character ch with attribute attr, and refresh.
1325 [clinic start generated code]*/
1326
1327 static PyObject *
_curses_window_echochar_impl(PyCursesWindowObject * self,PyObject * ch,long attr)1328 _curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch,
1329 long attr)
1330 /*[clinic end generated code: output=13e7dd875d4b9642 input=e7f34b964e92b156]*/
1331 {
1332 chtype ch_;
1333
1334 if (!PyCurses_ConvertToChtype(self, ch, &ch_))
1335 return NULL;
1336
1337 #ifdef py_is_pad
1338 if (py_is_pad(self->win)) {
1339 return PyCursesCheckERR(pechochar(self->win, ch_ | (attr_t)attr),
1340 "echochar");
1341 }
1342 else
1343 #endif
1344 return PyCursesCheckERR(wechochar(self->win, ch_ | (attr_t)attr),
1345 "echochar");
1346 }
1347
1348 #ifdef NCURSES_MOUSE_VERSION
1349 /*[clinic input]
1350 _curses.window.enclose
1351
1352 y: int
1353 Y-coordinate.
1354 x: int
1355 X-coordinate.
1356 /
1357
1358 Return True if the screen-relative coordinates are enclosed by the window.
1359 [clinic start generated code]*/
1360
1361 static PyObject *
_curses_window_enclose_impl(PyCursesWindowObject * self,int y,int x)1362 _curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x)
1363 /*[clinic end generated code: output=8679beef50502648 input=4fd3355d723f7bc9]*/
1364 {
1365 return PyBool_FromLong(wenclose(self->win, y, x));
1366 }
1367 #endif
1368
1369 /*[clinic input]
1370 _curses.window.getbkgd -> long
1371
1372 Return the window's current background character/attribute pair.
1373 [clinic start generated code]*/
1374
1375 static long
_curses_window_getbkgd_impl(PyCursesWindowObject * self)1376 _curses_window_getbkgd_impl(PyCursesWindowObject *self)
1377 /*[clinic end generated code: output=c52b25dc16b215c3 input=a69db882fa35426c]*/
1378 {
1379 return (long) getbkgd(self->win);
1380 }
1381
1382 /*[clinic input]
1383 _curses.window.getch -> int
1384
1385 [
1386 y: int
1387 Y-coordinate.
1388 x: int
1389 X-coordinate.
1390 ]
1391 /
1392
1393 Get a character code from terminal keyboard.
1394
1395 The integer returned does not have to be in ASCII range: function keys,
1396 keypad keys and so on return numbers higher than 256. In no-delay mode, -1
1397 is returned if there is no input, else getch() waits until a key is pressed.
1398 [clinic start generated code]*/
1399
1400 static int
_curses_window_getch_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1401 _curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1,
1402 int y, int x)
1403 /*[clinic end generated code: output=980aa6af0c0ca387 input=bb24ebfb379f991f]*/
1404 {
1405 int rtn;
1406
1407 Py_BEGIN_ALLOW_THREADS
1408 if (!group_right_1) {
1409 rtn = wgetch(self->win);
1410 }
1411 else {
1412 rtn = mvwgetch(self->win, y, x);
1413 }
1414 Py_END_ALLOW_THREADS
1415
1416 return rtn;
1417 }
1418
1419 /*[clinic input]
1420 _curses.window.getkey
1421
1422 [
1423 y: int
1424 Y-coordinate.
1425 x: int
1426 X-coordinate.
1427 ]
1428 /
1429
1430 Get a character (string) from terminal keyboard.
1431
1432 Returning a string instead of an integer, as getch() does. Function keys,
1433 keypad keys and other special keys return a multibyte string containing the
1434 key name. In no-delay mode, an exception is raised if there is no input.
1435 [clinic start generated code]*/
1436
1437 static PyObject *
_curses_window_getkey_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1438 _curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1,
1439 int y, int x)
1440 /*[clinic end generated code: output=8490a182db46b10f input=be2dee34f5cf57f8]*/
1441 {
1442 int rtn;
1443
1444 Py_BEGIN_ALLOW_THREADS
1445 if (!group_right_1) {
1446 rtn = wgetch(self->win);
1447 }
1448 else {
1449 rtn = mvwgetch(self->win, y, x);
1450 }
1451 Py_END_ALLOW_THREADS
1452
1453 if (rtn == ERR) {
1454 /* getch() returns ERR in nodelay mode */
1455 PyErr_CheckSignals();
1456 if (!PyErr_Occurred())
1457 PyErr_SetString(PyCursesError, "no input");
1458 return NULL;
1459 } else if (rtn <= 255) {
1460 #ifdef NCURSES_VERSION_MAJOR
1461 #if NCURSES_VERSION_MAJOR*100+NCURSES_VERSION_MINOR <= 507
1462 /* Work around a bug in ncurses 5.7 and earlier */
1463 if (rtn < 0) {
1464 rtn += 256;
1465 }
1466 #endif
1467 #endif
1468 return PyUnicode_FromOrdinal(rtn);
1469 } else {
1470 const char *knp = keyname(rtn);
1471 return PyUnicode_FromString((knp == NULL) ? "" : knp);
1472 }
1473 }
1474
1475 #ifdef HAVE_NCURSESW
1476 /*[clinic input]
1477 _curses.window.get_wch
1478
1479 [
1480 y: int
1481 Y-coordinate.
1482 x: int
1483 X-coordinate.
1484 ]
1485 /
1486
1487 Get a wide character from terminal keyboard.
1488
1489 Return a character for most keys, or an integer for function keys,
1490 keypad keys, and other special keys.
1491 [clinic start generated code]*/
1492
1493 static PyObject *
_curses_window_get_wch_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1494 _curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1,
1495 int y, int x)
1496 /*[clinic end generated code: output=9f4f86e91fe50ef3 input=dd7e5367fb49dc48]*/
1497 {
1498 int ct;
1499 wint_t rtn;
1500
1501 Py_BEGIN_ALLOW_THREADS
1502 if (!group_right_1) {
1503 ct = wget_wch(self->win ,&rtn);
1504 }
1505 else {
1506 ct = mvwget_wch(self->win, y, x, &rtn);
1507 }
1508 Py_END_ALLOW_THREADS
1509
1510 if (ct == ERR) {
1511 if (PyErr_CheckSignals())
1512 return NULL;
1513
1514 /* get_wch() returns ERR in nodelay mode */
1515 PyErr_SetString(PyCursesError, "no input");
1516 return NULL;
1517 }
1518 if (ct == KEY_CODE_YES)
1519 return PyLong_FromLong(rtn);
1520 else
1521 return PyUnicode_FromOrdinal(rtn);
1522 }
1523 #endif
1524
1525 /*[-clinic input]
1526 _curses.window.getstr
1527
1528 [
1529 y: int
1530 Y-coordinate.
1531 x: int
1532 X-coordinate.
1533 ]
1534 n: int = 1023
1535 Maximal number of characters.
1536 /
1537
1538 Read a string from the user, with primitive line editing capacity.
1539 [-clinic start generated code]*/
1540
1541 static PyObject *
PyCursesWindow_GetStr(PyCursesWindowObject * self,PyObject * args)1542 PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args)
1543 {
1544 int x, y, n;
1545 char rtn[1024]; /* This should be big enough.. I hope */
1546 int rtn2;
1547
1548 switch (PyTuple_Size(args)) {
1549 case 0:
1550 Py_BEGIN_ALLOW_THREADS
1551 rtn2 = wgetnstr(self->win,rtn, 1023);
1552 Py_END_ALLOW_THREADS
1553 break;
1554 case 1:
1555 if (!PyArg_ParseTuple(args,"i;n", &n))
1556 return NULL;
1557 if (n < 0) {
1558 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1559 return NULL;
1560 }
1561 Py_BEGIN_ALLOW_THREADS
1562 rtn2 = wgetnstr(self->win, rtn, Py_MIN(n, 1023));
1563 Py_END_ALLOW_THREADS
1564 break;
1565 case 2:
1566 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1567 return NULL;
1568 Py_BEGIN_ALLOW_THREADS
1569 #ifdef STRICT_SYSV_CURSES
1570 rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023);
1571 #else
1572 rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023);
1573 #endif
1574 Py_END_ALLOW_THREADS
1575 break;
1576 case 3:
1577 if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n))
1578 return NULL;
1579 if (n < 0) {
1580 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1581 return NULL;
1582 }
1583 #ifdef STRICT_SYSV_CURSES
1584 Py_BEGIN_ALLOW_THREADS
1585 rtn2 = wmove(self->win,y,x)==ERR ? ERR :
1586 wgetnstr(self->win, rtn, Py_MIN(n, 1023));
1587 Py_END_ALLOW_THREADS
1588 #else
1589 Py_BEGIN_ALLOW_THREADS
1590 rtn2 = mvwgetnstr(self->win, y, x, rtn, Py_MIN(n, 1023));
1591 Py_END_ALLOW_THREADS
1592 #endif
1593 break;
1594 default:
1595 PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 3 arguments");
1596 return NULL;
1597 }
1598 if (rtn2 == ERR)
1599 rtn[0] = 0;
1600 return PyBytes_FromString(rtn);
1601 }
1602
1603 /*[clinic input]
1604 _curses.window.hline
1605
1606 [
1607 y: int
1608 Starting Y-coordinate.
1609 x: int
1610 Starting X-coordinate.
1611 ]
1612
1613 ch: object
1614 Character to draw.
1615 n: int
1616 Line length.
1617
1618 [
1619 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
1620 Attributes for the characters.
1621 ]
1622 /
1623
1624 Display a horizontal line.
1625 [clinic start generated code]*/
1626
1627 static PyObject *
_curses_window_hline_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * ch,int n,int group_right_1,long attr)1628 _curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1,
1629 int y, int x, PyObject *ch, int n,
1630 int group_right_1, long attr)
1631 /*[clinic end generated code: output=c00d489d61fc9eef input=81a4dea47268163e]*/
1632 {
1633 chtype ch_;
1634
1635 if (!PyCurses_ConvertToChtype(self, ch, &ch_))
1636 return NULL;
1637 if (group_left_1) {
1638 if (wmove(self->win, y, x) == ERR) {
1639 return PyCursesCheckERR(ERR, "wmove");
1640 }
1641 }
1642 return PyCursesCheckERR(whline(self->win, ch_ | (attr_t)attr, n), "hline");
1643 }
1644
1645 /*[clinic input]
1646 _curses.window.insch
1647
1648 [
1649 y: int
1650 Y-coordinate.
1651 x: int
1652 X-coordinate.
1653 ]
1654
1655 ch: object
1656 Character to insert.
1657
1658 [
1659 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
1660 Attributes for the character.
1661 ]
1662 /
1663
1664 Insert a character before the current or specified position.
1665
1666 All characters to the right of the cursor are shifted one position right, with
1667 the rightmost characters on the line being lost.
1668 [clinic start generated code]*/
1669
1670 static PyObject *
_curses_window_insch_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * ch,int group_right_1,long attr)1671 _curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1,
1672 int y, int x, PyObject *ch, int group_right_1,
1673 long attr)
1674 /*[clinic end generated code: output=ade8cfe3a3bf3e34 input=336342756ee19812]*/
1675 {
1676 int rtn;
1677 chtype ch_ = 0;
1678
1679 if (!PyCurses_ConvertToChtype(self, ch, &ch_))
1680 return NULL;
1681
1682 if (!group_left_1) {
1683 rtn = winsch(self->win, ch_ | (attr_t)attr);
1684 }
1685 else {
1686 rtn = mvwinsch(self->win, y, x, ch_ | (attr_t)attr);
1687 }
1688
1689 return PyCursesCheckERR(rtn, "insch");
1690 }
1691
1692 /*[clinic input]
1693 _curses.window.inch -> unsigned_long
1694
1695 [
1696 y: int
1697 Y-coordinate.
1698 x: int
1699 X-coordinate.
1700 ]
1701 /
1702
1703 Return the character at the given position in the window.
1704
1705 The bottom 8 bits are the character proper, and upper bits are the attributes.
1706 [clinic start generated code]*/
1707
1708 static unsigned long
_curses_window_inch_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1709 _curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1,
1710 int y, int x)
1711 /*[clinic end generated code: output=6c4719fe978fe86a input=fac23ee11e3b3a66]*/
1712 {
1713 unsigned long rtn;
1714
1715 if (!group_right_1) {
1716 rtn = winch(self->win);
1717 }
1718 else {
1719 rtn = mvwinch(self->win, y, x);
1720 }
1721
1722 return rtn;
1723 }
1724
1725 /*[-clinic input]
1726 _curses.window.instr
1727
1728 [
1729 y: int
1730 Y-coordinate.
1731 x: int
1732 X-coordinate.
1733 ]
1734 n: int = 1023
1735 Maximal number of characters.
1736 /
1737
1738 Return a string of characters, extracted from the window.
1739
1740 Return a string of characters, extracted from the window starting at the
1741 current cursor position, or at y, x if specified. Attributes are stripped
1742 from the characters. If n is specified, instr() returns a string at most
1743 n characters long (exclusive of the trailing NUL).
1744 [-clinic start generated code]*/
1745 static PyObject *
PyCursesWindow_InStr(PyCursesWindowObject * self,PyObject * args)1746 PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args)
1747 {
1748 int x, y, n;
1749 char rtn[1024]; /* This should be big enough.. I hope */
1750 int rtn2;
1751
1752 switch (PyTuple_Size(args)) {
1753 case 0:
1754 rtn2 = winnstr(self->win,rtn, 1023);
1755 break;
1756 case 1:
1757 if (!PyArg_ParseTuple(args,"i;n", &n))
1758 return NULL;
1759 if (n < 0) {
1760 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1761 return NULL;
1762 }
1763 rtn2 = winnstr(self->win, rtn, Py_MIN(n, 1023));
1764 break;
1765 case 2:
1766 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1767 return NULL;
1768 rtn2 = mvwinnstr(self->win,y,x,rtn,1023);
1769 break;
1770 case 3:
1771 if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n))
1772 return NULL;
1773 if (n < 0) {
1774 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1775 return NULL;
1776 }
1777 rtn2 = mvwinnstr(self->win, y, x, rtn, Py_MIN(n,1023));
1778 break;
1779 default:
1780 PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments");
1781 return NULL;
1782 }
1783 if (rtn2 == ERR)
1784 rtn[0] = 0;
1785 return PyBytes_FromString(rtn);
1786 }
1787
1788 /*[clinic input]
1789 _curses.window.insstr
1790
1791 [
1792 y: int
1793 Y-coordinate.
1794 x: int
1795 X-coordinate.
1796 ]
1797
1798 str: object
1799 String to insert.
1800
1801 [
1802 attr: long
1803 Attributes for characters.
1804 ]
1805 /
1806
1807 Insert the string before the current or specified position.
1808
1809 Insert a character string (as many characters as will fit on the line)
1810 before the character under the cursor. All characters to the right of
1811 the cursor are shifted right, with the rightmost characters on the line
1812 being lost. The cursor position does not change (after moving to y, x,
1813 if specified).
1814 [clinic start generated code]*/
1815
1816 static PyObject *
_curses_window_insstr_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * str,int group_right_1,long attr)1817 _curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1,
1818 int y, int x, PyObject *str, int group_right_1,
1819 long attr)
1820 /*[clinic end generated code: output=c259a5265ad0b777 input=6827cddc6340a7f3]*/
1821 {
1822 int rtn;
1823 int strtype;
1824 PyObject *bytesobj = NULL;
1825 #ifdef HAVE_NCURSESW
1826 wchar_t *wstr = NULL;
1827 #endif
1828 attr_t attr_old = A_NORMAL;
1829 int use_xy = group_left_1, use_attr = group_right_1;
1830 const char *funcname;
1831
1832 #ifdef HAVE_NCURSESW
1833 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr);
1834 #else
1835 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL);
1836 #endif
1837 if (strtype == 0)
1838 return NULL;
1839
1840 if (use_attr) {
1841 attr_old = getattrs(self->win);
1842 (void)wattrset(self->win, (attr_t)attr);
1843 }
1844 #ifdef HAVE_NCURSESW
1845 if (strtype == 2) {
1846 funcname = "inswstr";
1847 if (use_xy)
1848 rtn = mvwins_wstr(self->win,y,x,wstr);
1849 else
1850 rtn = wins_wstr(self->win,wstr);
1851 PyMem_Free(wstr);
1852 }
1853 else
1854 #endif
1855 {
1856 const char *str = PyBytes_AS_STRING(bytesobj);
1857 funcname = "insstr";
1858 if (use_xy)
1859 rtn = mvwinsstr(self->win,y,x,str);
1860 else
1861 rtn = winsstr(self->win,str);
1862 Py_DECREF(bytesobj);
1863 }
1864 if (use_attr)
1865 (void)wattrset(self->win,attr_old);
1866 return PyCursesCheckERR(rtn, funcname);
1867 }
1868
1869 /*[clinic input]
1870 _curses.window.insnstr
1871
1872 [
1873 y: int
1874 Y-coordinate.
1875 x: int
1876 X-coordinate.
1877 ]
1878
1879 str: object
1880 String to insert.
1881
1882 n: int
1883 Maximal number of characters.
1884
1885 [
1886 attr: long
1887 Attributes for characters.
1888 ]
1889 /
1890
1891 Insert at most n characters of the string.
1892
1893 Insert a character string (as many characters as will fit on the line)
1894 before the character under the cursor, up to n characters. If n is zero
1895 or negative, the entire string is inserted. All characters to the right
1896 of the cursor are shifted right, with the rightmost characters on the line
1897 being lost. The cursor position does not change (after moving to y, x, if
1898 specified).
1899 [clinic start generated code]*/
1900
1901 static PyObject *
_curses_window_insnstr_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * str,int n,int group_right_1,long attr)1902 _curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1,
1903 int y, int x, PyObject *str, int n,
1904 int group_right_1, long attr)
1905 /*[clinic end generated code: output=971a32ea6328ec8b input=70fa0cd543901a4c]*/
1906 {
1907 int rtn;
1908 int strtype;
1909 PyObject *bytesobj = NULL;
1910 #ifdef HAVE_NCURSESW
1911 wchar_t *wstr = NULL;
1912 #endif
1913 attr_t attr_old = A_NORMAL;
1914 int use_xy = group_left_1, use_attr = group_right_1;
1915 const char *funcname;
1916
1917 #ifdef HAVE_NCURSESW
1918 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr);
1919 #else
1920 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL);
1921 #endif
1922 if (strtype == 0)
1923 return NULL;
1924
1925 if (use_attr) {
1926 attr_old = getattrs(self->win);
1927 (void)wattrset(self->win, (attr_t)attr);
1928 }
1929 #ifdef HAVE_NCURSESW
1930 if (strtype == 2) {
1931 funcname = "insn_wstr";
1932 if (use_xy)
1933 rtn = mvwins_nwstr(self->win,y,x,wstr,n);
1934 else
1935 rtn = wins_nwstr(self->win,wstr,n);
1936 PyMem_Free(wstr);
1937 }
1938 else
1939 #endif
1940 {
1941 const char *str = PyBytes_AS_STRING(bytesobj);
1942 funcname = "insnstr";
1943 if (use_xy)
1944 rtn = mvwinsnstr(self->win,y,x,str,n);
1945 else
1946 rtn = winsnstr(self->win,str,n);
1947 Py_DECREF(bytesobj);
1948 }
1949 if (use_attr)
1950 (void)wattrset(self->win,attr_old);
1951 return PyCursesCheckERR(rtn, funcname);
1952 }
1953
1954 /*[clinic input]
1955 _curses.window.is_linetouched
1956
1957 line: int
1958 Line number.
1959 /
1960
1961 Return True if the specified line was modified, otherwise return False.
1962
1963 Raise a curses.error exception if line is not valid for the given window.
1964 [clinic start generated code]*/
1965
1966 static PyObject *
_curses_window_is_linetouched_impl(PyCursesWindowObject * self,int line)1967 _curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line)
1968 /*[clinic end generated code: output=ad4a4edfee2db08c input=a7be0c189f243914]*/
1969 {
1970 int erg;
1971 erg = is_linetouched(self->win, line);
1972 if (erg == ERR) {
1973 PyErr_SetString(PyExc_TypeError,
1974 "is_linetouched: line number outside of boundaries");
1975 return NULL;
1976 }
1977 return PyBool_FromLong(erg);
1978 }
1979
1980 #ifdef py_is_pad
1981 /*[clinic input]
1982 _curses.window.noutrefresh
1983
1984 [
1985 pminrow: int
1986 pmincol: int
1987 sminrow: int
1988 smincol: int
1989 smaxrow: int
1990 smaxcol: int
1991 ]
1992 /
1993
1994 Mark for refresh but wait.
1995
1996 This function updates the data structure representing the desired state of the
1997 window, but does not force an update of the physical screen. To accomplish
1998 that, call doupdate().
1999 [clinic start generated code]*/
2000
2001 static PyObject *
_curses_window_noutrefresh_impl(PyCursesWindowObject * self,int group_right_1,int pminrow,int pmincol,int sminrow,int smincol,int smaxrow,int smaxcol)2002 _curses_window_noutrefresh_impl(PyCursesWindowObject *self,
2003 int group_right_1, int pminrow, int pmincol,
2004 int sminrow, int smincol, int smaxrow,
2005 int smaxcol)
2006 /*[clinic end generated code: output=809a1f3c6a03e23e input=3e56898388cd739e]*/
2007 #else
2008 /*[clinic input]
2009 _curses.window.noutrefresh
2010
2011 Mark for refresh but wait.
2012
2013 This function updates the data structure representing the desired state of the
2014 window, but does not force an update of the physical screen. To accomplish
2015 that, call doupdate().
2016 [clinic start generated code]*/
2017
2018 static PyObject *
2019 _curses_window_noutrefresh_impl(PyCursesWindowObject *self)
2020 /*[clinic end generated code: output=6ef6dec666643fee input=876902e3fa431dbd]*/
2021 #endif
2022 {
2023 int rtn;
2024
2025 #ifdef py_is_pad
2026 if (py_is_pad(self->win)) {
2027 if (!group_right_1) {
2028 PyErr_SetString(PyCursesError,
2029 "noutrefresh() called for a pad "
2030 "requires 6 arguments");
2031 return NULL;
2032 }
2033 Py_BEGIN_ALLOW_THREADS
2034 rtn = pnoutrefresh(self->win, pminrow, pmincol,
2035 sminrow, smincol, smaxrow, smaxcol);
2036 Py_END_ALLOW_THREADS
2037 return PyCursesCheckERR(rtn, "pnoutrefresh");
2038 }
2039 if (group_right_1) {
2040 PyErr_SetString(PyExc_TypeError,
2041 "noutrefresh() takes no arguments (6 given)");
2042 return NULL;
2043 }
2044 #endif
2045 Py_BEGIN_ALLOW_THREADS
2046 rtn = wnoutrefresh(self->win);
2047 Py_END_ALLOW_THREADS
2048 return PyCursesCheckERR(rtn, "wnoutrefresh");
2049 }
2050
2051 /*[clinic input]
2052 _curses.window.overlay
2053
2054 destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type")
2055
2056 [
2057 sminrow: int
2058 smincol: int
2059 dminrow: int
2060 dmincol: int
2061 dmaxrow: int
2062 dmaxcol: int
2063 ]
2064 /
2065
2066 Overlay the window on top of destwin.
2067
2068 The windows need not be the same size, only the overlapping region is copied.
2069 This copy is non-destructive, which means that the current background
2070 character does not overwrite the old contents of destwin.
2071
2072 To get fine-grained control over the copied region, the second form of
2073 overlay() can be used. sminrow and smincol are the upper-left coordinates
2074 of the source window, and the other variables mark a rectangle in the
2075 destination window.
2076 [clinic start generated code]*/
2077
2078 static PyObject *
_curses_window_overlay_impl(PyCursesWindowObject * self,PyCursesWindowObject * destwin,int group_right_1,int sminrow,int smincol,int dminrow,int dmincol,int dmaxrow,int dmaxcol)2079 _curses_window_overlay_impl(PyCursesWindowObject *self,
2080 PyCursesWindowObject *destwin, int group_right_1,
2081 int sminrow, int smincol, int dminrow,
2082 int dmincol, int dmaxrow, int dmaxcol)
2083 /*[clinic end generated code: output=82bb2c4cb443ca58 input=7edd23ad22cc1984]*/
2084 {
2085 int rtn;
2086
2087 if (group_right_1) {
2088 rtn = copywin(self->win, destwin->win, sminrow, smincol,
2089 dminrow, dmincol, dmaxrow, dmaxcol, TRUE);
2090 return PyCursesCheckERR(rtn, "copywin");
2091 }
2092 else {
2093 rtn = overlay(self->win, destwin->win);
2094 return PyCursesCheckERR(rtn, "overlay");
2095 }
2096 }
2097
2098 /*[clinic input]
2099 _curses.window.overwrite
2100
2101 destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type")
2102
2103 [
2104 sminrow: int
2105 smincol: int
2106 dminrow: int
2107 dmincol: int
2108 dmaxrow: int
2109 dmaxcol: int
2110 ]
2111 /
2112
2113 Overwrite the window on top of destwin.
2114
2115 The windows need not be the same size, in which case only the overlapping
2116 region is copied. This copy is destructive, which means that the current
2117 background character overwrites the old contents of destwin.
2118
2119 To get fine-grained control over the copied region, the second form of
2120 overwrite() can be used. sminrow and smincol are the upper-left coordinates
2121 of the source window, the other variables mark a rectangle in the destination
2122 window.
2123 [clinic start generated code]*/
2124
2125 static PyObject *
_curses_window_overwrite_impl(PyCursesWindowObject * self,PyCursesWindowObject * destwin,int group_right_1,int sminrow,int smincol,int dminrow,int dmincol,int dmaxrow,int dmaxcol)2126 _curses_window_overwrite_impl(PyCursesWindowObject *self,
2127 PyCursesWindowObject *destwin,
2128 int group_right_1, int sminrow, int smincol,
2129 int dminrow, int dmincol, int dmaxrow,
2130 int dmaxcol)
2131 /*[clinic end generated code: output=12ae007d1681be28 input=ea5de1b35cd948e0]*/
2132 {
2133 int rtn;
2134
2135 if (group_right_1) {
2136 rtn = copywin(self->win, destwin->win, sminrow, smincol,
2137 dminrow, dmincol, dmaxrow, dmaxcol, FALSE);
2138 return PyCursesCheckERR(rtn, "copywin");
2139 }
2140 else {
2141 rtn = overwrite(self->win, destwin->win);
2142 return PyCursesCheckERR(rtn, "overwrite");
2143 }
2144 }
2145
2146 /*[clinic input]
2147 _curses.window.putwin
2148
2149 file: object
2150 /
2151
2152 Write all data associated with the window into the provided file object.
2153
2154 This information can be later retrieved using the getwin() function.
2155 [clinic start generated code]*/
2156
2157 static PyObject *
_curses_window_putwin(PyCursesWindowObject * self,PyObject * file)2158 _curses_window_putwin(PyCursesWindowObject *self, PyObject *file)
2159 /*[clinic end generated code: output=3a25e2a5e7a040ac input=0608648e09c8ea0a]*/
2160 {
2161 /* We have to simulate this by writing to a temporary FILE*,
2162 then reading back, then writing to the argument file. */
2163 FILE *fp;
2164 PyObject *res = NULL;
2165
2166 fp = tmpfile();
2167 if (fp == NULL)
2168 return PyErr_SetFromErrno(PyExc_OSError);
2169 if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0)
2170 goto exit;
2171 res = PyCursesCheckERR(putwin(self->win, fp), "putwin");
2172 if (res == NULL)
2173 goto exit;
2174 fseek(fp, 0, 0);
2175 while (1) {
2176 char buf[BUFSIZ];
2177 Py_ssize_t n = fread(buf, 1, BUFSIZ, fp);
2178 _Py_IDENTIFIER(write);
2179
2180 if (n <= 0)
2181 break;
2182 Py_DECREF(res);
2183 res = _PyObject_CallMethodId(file, &PyId_write, "y#", buf, n);
2184 if (res == NULL)
2185 break;
2186 }
2187
2188 exit:
2189 fclose(fp);
2190 return res;
2191 }
2192
2193 /*[clinic input]
2194 _curses.window.redrawln
2195
2196 beg: int
2197 Starting line number.
2198 num: int
2199 The number of lines.
2200 /
2201
2202 Mark the specified lines corrupted.
2203
2204 They should be completely redrawn on the next refresh() call.
2205 [clinic start generated code]*/
2206
2207 static PyObject *
_curses_window_redrawln_impl(PyCursesWindowObject * self,int beg,int num)2208 _curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num)
2209 /*[clinic end generated code: output=ea216e334f9ce1b4 input=152155e258a77a7a]*/
2210 {
2211 return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln");
2212 }
2213
2214 /*[clinic input]
2215 _curses.window.refresh
2216
2217 [
2218 pminrow: int
2219 pmincol: int
2220 sminrow: int
2221 smincol: int
2222 smaxrow: int
2223 smaxcol: int
2224 ]
2225 /
2226
2227 Update the display immediately.
2228
2229 Synchronize actual screen with previous drawing/deleting methods.
2230 The 6 optional arguments can only be specified when the window is a pad
2231 created with newpad(). The additional parameters are needed to indicate
2232 what part of the pad and screen are involved. pminrow and pmincol specify
2233 the upper left-hand corner of the rectangle to be displayed in the pad.
2234 sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to
2235 be displayed on the screen. The lower right-hand corner of the rectangle to
2236 be displayed in the pad is calculated from the screen coordinates, since the
2237 rectangles must be the same size. Both rectangles must be entirely contained
2238 within their respective structures. Negative values of pminrow, pmincol,
2239 sminrow, or smincol are treated as if they were zero.
2240 [clinic start generated code]*/
2241
2242 static PyObject *
_curses_window_refresh_impl(PyCursesWindowObject * self,int group_right_1,int pminrow,int pmincol,int sminrow,int smincol,int smaxrow,int smaxcol)2243 _curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1,
2244 int pminrow, int pmincol, int sminrow,
2245 int smincol, int smaxrow, int smaxcol)
2246 /*[clinic end generated code: output=42199543115e6e63 input=95e01cb5ffc635d0]*/
2247 {
2248 int rtn;
2249
2250 #ifdef py_is_pad
2251 if (py_is_pad(self->win)) {
2252 if (!group_right_1) {
2253 PyErr_SetString(PyCursesError,
2254 "refresh() for a pad requires 6 arguments");
2255 return NULL;
2256 }
2257 Py_BEGIN_ALLOW_THREADS
2258 rtn = prefresh(self->win, pminrow, pmincol,
2259 sminrow, smincol, smaxrow, smaxcol);
2260 Py_END_ALLOW_THREADS
2261 return PyCursesCheckERR(rtn, "prefresh");
2262 }
2263 #endif
2264 if (group_right_1) {
2265 PyErr_SetString(PyExc_TypeError,
2266 "refresh() takes no arguments (6 given)");
2267 return NULL;
2268 }
2269 Py_BEGIN_ALLOW_THREADS
2270 rtn = wrefresh(self->win);
2271 Py_END_ALLOW_THREADS
2272 return PyCursesCheckERR(rtn, "prefresh");
2273 }
2274
2275 /*[clinic input]
2276 _curses.window.setscrreg
2277
2278 top: int
2279 First line number.
2280 bottom: int
2281 Last line number.
2282 /
2283
2284 Define a software scrolling region.
2285
2286 All scrolling actions will take place in this region.
2287 [clinic start generated code]*/
2288
2289 static PyObject *
_curses_window_setscrreg_impl(PyCursesWindowObject * self,int top,int bottom)2290 _curses_window_setscrreg_impl(PyCursesWindowObject *self, int top,
2291 int bottom)
2292 /*[clinic end generated code: output=486ab5db218d2b1a input=1b517b986838bf0e]*/
2293 {
2294 return PyCursesCheckERR(wsetscrreg(self->win, top, bottom), "wsetscrreg");
2295 }
2296
2297 /*[clinic input]
2298 _curses.window.subwin
2299
2300 [
2301 nlines: int = 0
2302 Height.
2303 ncols: int = 0
2304 Width.
2305 ]
2306 begin_y: int
2307 Top side y-coordinate.
2308 begin_x: int
2309 Left side x-coordinate.
2310 /
2311
2312 Create a sub-window (screen-relative coordinates).
2313
2314 By default, the sub-window will extend from the specified position to the
2315 lower right corner of the window.
2316 [clinic start generated code]*/
2317
2318 static PyObject *
_curses_window_subwin_impl(PyCursesWindowObject * self,int group_left_1,int nlines,int ncols,int begin_y,int begin_x)2319 _curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1,
2320 int nlines, int ncols, int begin_y, int begin_x)
2321 /*[clinic end generated code: output=93e898afc348f59a input=2129fa47fd57721c]*/
2322 {
2323 WINDOW *win;
2324
2325 /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */
2326 #ifdef py_is_pad
2327 if (py_is_pad(self->win)) {
2328 win = subpad(self->win, nlines, ncols, begin_y, begin_x);
2329 }
2330 else
2331 #endif
2332 win = subwin(self->win, nlines, ncols, begin_y, begin_x);
2333
2334 if (win == NULL) {
2335 PyErr_SetString(PyCursesError, catchall_NULL);
2336 return NULL;
2337 }
2338
2339 return (PyObject *)PyCursesWindow_New(win, self->encoding);
2340 }
2341
2342 /*[clinic input]
2343 _curses.window.scroll
2344
2345 [
2346 lines: int = 1
2347 Number of lines to scroll.
2348 ]
2349 /
2350
2351 Scroll the screen or scrolling region.
2352
2353 Scroll upward if the argument is positive and downward if it is negative.
2354 [clinic start generated code]*/
2355
2356 static PyObject *
_curses_window_scroll_impl(PyCursesWindowObject * self,int group_right_1,int lines)2357 _curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1,
2358 int lines)
2359 /*[clinic end generated code: output=4541a8a11852d360 input=c969ca0cfabbdbec]*/
2360 {
2361 if (!group_right_1) {
2362 return PyCursesCheckERR(scroll(self->win), "scroll");
2363 }
2364 else {
2365 return PyCursesCheckERR(wscrl(self->win, lines), "scroll");
2366 }
2367 }
2368
2369 /*[clinic input]
2370 _curses.window.touchline
2371
2372 start: int
2373 count: int
2374 [
2375 changed: bool(accept={int}) = True
2376 ]
2377 /
2378
2379 Pretend count lines have been changed, starting with line start.
2380
2381 If changed is supplied, it specifies whether the affected lines are marked
2382 as having been changed (changed=True) or unchanged (changed=False).
2383 [clinic start generated code]*/
2384
2385 static PyObject *
_curses_window_touchline_impl(PyCursesWindowObject * self,int start,int count,int group_right_1,int changed)2386 _curses_window_touchline_impl(PyCursesWindowObject *self, int start,
2387 int count, int group_right_1, int changed)
2388 /*[clinic end generated code: output=65d05b3f7438c61d input=918ad1cbdadf93ea]*/
2389 {
2390 if (!group_right_1) {
2391 return PyCursesCheckERR(touchline(self->win, start, count), "touchline");
2392 }
2393 else {
2394 return PyCursesCheckERR(wtouchln(self->win, start, count, changed), "touchline");
2395 }
2396 }
2397
2398 /*[clinic input]
2399 _curses.window.vline
2400
2401 [
2402 y: int
2403 Starting Y-coordinate.
2404 x: int
2405 Starting X-coordinate.
2406 ]
2407
2408 ch: object
2409 Character to draw.
2410 n: int
2411 Line length.
2412
2413 [
2414 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
2415 Attributes for the character.
2416 ]
2417 /
2418
2419 Display a vertical line.
2420 [clinic start generated code]*/
2421
2422 static PyObject *
_curses_window_vline_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * ch,int n,int group_right_1,long attr)2423 _curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1,
2424 int y, int x, PyObject *ch, int n,
2425 int group_right_1, long attr)
2426 /*[clinic end generated code: output=287ad1cc8982217f input=a6f2dc86a4648b32]*/
2427 {
2428 chtype ch_;
2429
2430 if (!PyCurses_ConvertToChtype(self, ch, &ch_))
2431 return NULL;
2432 if (group_left_1) {
2433 if (wmove(self->win, y, x) == ERR)
2434 return PyCursesCheckERR(ERR, "wmove");
2435 }
2436 return PyCursesCheckERR(wvline(self->win, ch_ | (attr_t)attr, n), "vline");
2437 }
2438
2439 static PyObject *
PyCursesWindow_get_encoding(PyCursesWindowObject * self,void * closure)2440 PyCursesWindow_get_encoding(PyCursesWindowObject *self, void *closure)
2441 {
2442 return PyUnicode_FromString(self->encoding);
2443 }
2444
2445 static int
PyCursesWindow_set_encoding(PyCursesWindowObject * self,PyObject * value,void * Py_UNUSED (ignored))2446 PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value, void *Py_UNUSED(ignored))
2447 {
2448 PyObject *ascii;
2449 char *encoding;
2450
2451 /* It is illegal to del win.encoding */
2452 if (value == NULL) {
2453 PyErr_SetString(PyExc_TypeError,
2454 "encoding may not be deleted");
2455 return -1;
2456 }
2457
2458 if (!PyUnicode_Check(value)) {
2459 PyErr_SetString(PyExc_TypeError,
2460 "setting encoding to a non-string");
2461 return -1;
2462 }
2463 ascii = PyUnicode_AsASCIIString(value);
2464 if (ascii == NULL)
2465 return -1;
2466 encoding = _PyMem_Strdup(PyBytes_AS_STRING(ascii));
2467 Py_DECREF(ascii);
2468 if (encoding == NULL) {
2469 PyErr_NoMemory();
2470 return -1;
2471 }
2472 PyMem_Free(self->encoding);
2473 self->encoding = encoding;
2474 return 0;
2475 }
2476
2477 #include "clinic/_cursesmodule.c.h"
2478
2479 static PyMethodDef PyCursesWindow_Methods[] = {
2480 _CURSES_WINDOW_ADDCH_METHODDEF
2481 _CURSES_WINDOW_ADDNSTR_METHODDEF
2482 _CURSES_WINDOW_ADDSTR_METHODDEF
2483 _CURSES_WINDOW_ATTROFF_METHODDEF
2484 _CURSES_WINDOW_ATTRON_METHODDEF
2485 _CURSES_WINDOW_ATTRSET_METHODDEF
2486 _CURSES_WINDOW_BKGD_METHODDEF
2487 #ifdef HAVE_CURSES_WCHGAT
2488 {"chgat", (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS},
2489 #endif
2490 _CURSES_WINDOW_BKGDSET_METHODDEF
2491 _CURSES_WINDOW_BORDER_METHODDEF
2492 _CURSES_WINDOW_BOX_METHODDEF
2493 {"clear", (PyCFunction)PyCursesWindow_wclear, METH_NOARGS},
2494 {"clearok", (PyCFunction)PyCursesWindow_clearok, METH_VARARGS},
2495 {"clrtobot", (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS},
2496 {"clrtoeol", (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS},
2497 {"cursyncup", (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS},
2498 _CURSES_WINDOW_DELCH_METHODDEF
2499 {"deleteln", (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS},
2500 _CURSES_WINDOW_DERWIN_METHODDEF
2501 _CURSES_WINDOW_ECHOCHAR_METHODDEF
2502 _CURSES_WINDOW_ENCLOSE_METHODDEF
2503 {"erase", (PyCFunction)PyCursesWindow_werase, METH_NOARGS},
2504 {"getbegyx", (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS},
2505 _CURSES_WINDOW_GETBKGD_METHODDEF
2506 _CURSES_WINDOW_GETCH_METHODDEF
2507 _CURSES_WINDOW_GETKEY_METHODDEF
2508 _CURSES_WINDOW_GET_WCH_METHODDEF
2509 {"getmaxyx", (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS},
2510 {"getparyx", (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS},
2511 {"getstr", (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS},
2512 {"getyx", (PyCFunction)PyCursesWindow_getyx, METH_NOARGS},
2513 _CURSES_WINDOW_HLINE_METHODDEF
2514 {"idcok", (PyCFunction)PyCursesWindow_idcok, METH_VARARGS},
2515 {"idlok", (PyCFunction)PyCursesWindow_idlok, METH_VARARGS},
2516 #ifdef HAVE_CURSES_IMMEDOK
2517 {"immedok", (PyCFunction)PyCursesWindow_immedok, METH_VARARGS},
2518 #endif
2519 _CURSES_WINDOW_INCH_METHODDEF
2520 _CURSES_WINDOW_INSCH_METHODDEF
2521 {"insdelln", (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS},
2522 {"insertln", (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS},
2523 _CURSES_WINDOW_INSNSTR_METHODDEF
2524 _CURSES_WINDOW_INSSTR_METHODDEF
2525 {"instr", (PyCFunction)PyCursesWindow_InStr, METH_VARARGS},
2526 _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF
2527 {"is_wintouched", (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS},
2528 {"keypad", (PyCFunction)PyCursesWindow_keypad, METH_VARARGS},
2529 {"leaveok", (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS},
2530 {"move", (PyCFunction)PyCursesWindow_wmove, METH_VARARGS},
2531 {"mvderwin", (PyCFunction)PyCursesWindow_mvderwin, METH_VARARGS},
2532 {"mvwin", (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS},
2533 {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS},
2534 {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS},
2535 _CURSES_WINDOW_NOUTREFRESH_METHODDEF
2536 _CURSES_WINDOW_OVERLAY_METHODDEF
2537 _CURSES_WINDOW_OVERWRITE_METHODDEF
2538 _CURSES_WINDOW_PUTWIN_METHODDEF
2539 _CURSES_WINDOW_REDRAWLN_METHODDEF
2540 {"redrawwin", (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS},
2541 _CURSES_WINDOW_REFRESH_METHODDEF
2542 #ifndef STRICT_SYSV_CURSES
2543 {"resize", (PyCFunction)PyCursesWindow_wresize, METH_VARARGS},
2544 #endif
2545 _CURSES_WINDOW_SCROLL_METHODDEF
2546 {"scrollok", (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS},
2547 _CURSES_WINDOW_SETSCRREG_METHODDEF
2548 {"standend", (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS},
2549 {"standout", (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS},
2550 {"subpad", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__},
2551 _CURSES_WINDOW_SUBWIN_METHODDEF
2552 {"syncdown", (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS},
2553 #ifdef HAVE_CURSES_SYNCOK
2554 {"syncok", (PyCFunction)PyCursesWindow_syncok, METH_VARARGS},
2555 #endif
2556 {"syncup", (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS},
2557 {"timeout", (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS},
2558 _CURSES_WINDOW_TOUCHLINE_METHODDEF
2559 {"touchwin", (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS},
2560 {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS},
2561 _CURSES_WINDOW_VLINE_METHODDEF
2562 {NULL, NULL} /* sentinel */
2563 };
2564
2565 static PyGetSetDef PyCursesWindow_getsets[] = {
2566 {"encoding",
2567 (getter)PyCursesWindow_get_encoding,
2568 (setter)PyCursesWindow_set_encoding,
2569 "the typecode character used to create the array"},
2570 {NULL, NULL, NULL, NULL } /* sentinel */
2571 };
2572
2573 /* -------------------------------------------------------*/
2574
2575 PyTypeObject PyCursesWindow_Type = {
2576 PyVarObject_HEAD_INIT(NULL, 0)
2577 "_curses.window", /*tp_name*/
2578 sizeof(PyCursesWindowObject), /*tp_basicsize*/
2579 0, /*tp_itemsize*/
2580 /* methods */
2581 (destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/
2582 0, /*tp_vectorcall_offset*/
2583 (getattrfunc)0, /*tp_getattr*/
2584 (setattrfunc)0, /*tp_setattr*/
2585 0, /*tp_as_async*/
2586 0, /*tp_repr*/
2587 0, /*tp_as_number*/
2588 0, /*tp_as_sequence*/
2589 0, /*tp_as_mapping*/
2590 0, /*tp_hash*/
2591 0, /*tp_call*/
2592 0, /*tp_str*/
2593 0, /*tp_getattro*/
2594 0, /*tp_setattro*/
2595 0, /*tp_as_buffer*/
2596 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2597 0, /*tp_doc*/
2598 0, /*tp_traverse*/
2599 0, /*tp_clear*/
2600 0, /*tp_richcompare*/
2601 0, /*tp_weaklistoffset*/
2602 0, /*tp_iter*/
2603 0, /*tp_iternext*/
2604 PyCursesWindow_Methods, /*tp_methods*/
2605 0, /* tp_members */
2606 PyCursesWindow_getsets, /* tp_getset */
2607 };
2608
2609 /* Function Prototype Macros - They are ugly but very, very useful. ;-)
2610
2611 X - function name
2612 TYPE - parameter Type
2613 ERGSTR - format string for construction of the return value
2614 PARSESTR - format string for argument parsing
2615 */
2616
2617 #define NoArgNoReturnFunctionBody(X) \
2618 { \
2619 PyCursesInitialised \
2620 return PyCursesCheckERR(X(), # X); }
2621
2622 #define NoArgOrFlagNoReturnFunctionBody(X, flag) \
2623 { \
2624 PyCursesInitialised \
2625 if (flag) \
2626 return PyCursesCheckERR(X(), # X); \
2627 else \
2628 return PyCursesCheckERR(no ## X(), # X); \
2629 }
2630
2631 #define NoArgReturnIntFunctionBody(X) \
2632 { \
2633 PyCursesInitialised \
2634 return PyLong_FromLong((long) X()); }
2635
2636
2637 #define NoArgReturnStringFunctionBody(X) \
2638 { \
2639 PyCursesInitialised \
2640 return PyBytes_FromString(X()); }
2641
2642 #define NoArgTrueFalseFunctionBody(X) \
2643 { \
2644 PyCursesInitialised \
2645 return PyBool_FromLong(X()); }
2646
2647 #define NoArgNoReturnVoidFunctionBody(X) \
2648 { \
2649 PyCursesInitialised \
2650 X(); \
2651 Py_RETURN_NONE; }
2652
2653 /*********************************************************************
2654 Global Functions
2655 **********************************************************************/
2656
2657 #ifdef HAVE_CURSES_FILTER
2658 /*[clinic input]
2659 _curses.filter
2660
2661 [clinic start generated code]*/
2662
2663 static PyObject *
_curses_filter_impl(PyObject * module)2664 _curses_filter_impl(PyObject *module)
2665 /*[clinic end generated code: output=fb5b8a3642eb70b5 input=668c75a6992d3624]*/
2666 {
2667 /* not checking for PyCursesInitialised here since filter() must
2668 be called before initscr() */
2669 filter();
2670 Py_RETURN_NONE;
2671 }
2672 #endif
2673
2674 /*[clinic input]
2675 _curses.baudrate
2676
2677 Return the output speed of the terminal in bits per second.
2678 [clinic start generated code]*/
2679
2680 static PyObject *
_curses_baudrate_impl(PyObject * module)2681 _curses_baudrate_impl(PyObject *module)
2682 /*[clinic end generated code: output=3c63c6c401d7d9c0 input=921f022ed04a0fd9]*/
2683 NoArgReturnIntFunctionBody(baudrate)
2684
2685 /*[clinic input]
2686 _curses.beep
2687
2688 Emit a short attention sound.
2689 [clinic start generated code]*/
2690
2691 static PyObject *
2692 _curses_beep_impl(PyObject *module)
2693 /*[clinic end generated code: output=425274962abe49a2 input=a35698ca7d0162bc]*/
2694 NoArgNoReturnFunctionBody(beep)
2695
2696 /*[clinic input]
2697 _curses.can_change_color
2698
2699 Return True if the programmer can change the colors displayed by the terminal.
2700 [clinic start generated code]*/
2701
2702 static PyObject *
2703 _curses_can_change_color_impl(PyObject *module)
2704 /*[clinic end generated code: output=359df8c3c77d8bf1 input=d7718884de0092f2]*/
2705 NoArgTrueFalseFunctionBody(can_change_color)
2706
2707 /*[clinic input]
2708 _curses.cbreak
2709
2710 flag: bool(accept={int}) = True
2711 If false, the effect is the same as calling nocbreak().
2712 /
2713
2714 Enter cbreak mode.
2715
2716 In cbreak mode (sometimes called "rare" mode) normal tty line buffering is
2717 turned off and characters are available to be read one by one. However,
2718 unlike raw mode, special characters (interrupt, quit, suspend, and flow
2719 control) retain their effects on the tty driver and calling program.
2720 Calling first raw() then cbreak() leaves the terminal in cbreak mode.
2721 [clinic start generated code]*/
2722
2723 static PyObject *
2724 _curses_cbreak_impl(PyObject *module, int flag)
2725 /*[clinic end generated code: output=9f9dee9664769751 input=150be619eb1f1458]*/
2726 NoArgOrFlagNoReturnFunctionBody(cbreak, flag)
2727
2728 /*[clinic input]
2729 _curses.color_content
2730
2731 color_number: color
2732 The number of the color (0 - (COLORS-1)).
2733 /
2734
2735 Return the red, green, and blue (RGB) components of the specified color.
2736
2737 A 3-tuple is returned, containing the R, G, B values for the given color,
2738 which will be between 0 (no component) and 1000 (maximum amount of component).
2739 [clinic start generated code]*/
2740
2741 static PyObject *
2742 _curses_color_content_impl(PyObject *module, int color_number)
2743 /*[clinic end generated code: output=17b466df7054e0de input=03b5ed0472662aea]*/
2744 {
2745 _CURSES_COLOR_VAL_TYPE r,g,b;
2746
2747 PyCursesInitialised;
2748 PyCursesInitialisedColor;
2749
2750 if (_COLOR_CONTENT_FUNC(color_number, &r, &g, &b) == ERR) {
2751 PyErr_Format(PyCursesError, "%s() returned ERR",
2752 Py_STRINGIFY(_COLOR_CONTENT_FUNC));
2753 return NULL;
2754 }
2755
2756 return Py_BuildValue("(iii)", r, g, b);
2757 }
2758
2759 /*[clinic input]
2760 _curses.color_pair
2761
2762 pair_number: int
2763 The number of the color pair.
2764 /
2765
2766 Return the attribute value for displaying text in the specified color.
2767
2768 This attribute value can be combined with A_STANDOUT, A_REVERSE, and the
2769 other A_* attributes. pair_number() is the counterpart to this function.
2770 [clinic start generated code]*/
2771
2772 static PyObject *
_curses_color_pair_impl(PyObject * module,int pair_number)2773 _curses_color_pair_impl(PyObject *module, int pair_number)
2774 /*[clinic end generated code: output=60718abb10ce9feb input=6034e9146f343802]*/
2775 {
2776 PyCursesInitialised;
2777 PyCursesInitialisedColor;
2778
2779 return PyLong_FromLong(COLOR_PAIR(pair_number));
2780 }
2781
2782 /*[clinic input]
2783 _curses.curs_set
2784
2785 visibility: int
2786 0 for invisible, 1 for normal visible, or 2 for very visible.
2787 /
2788
2789 Set the cursor state.
2790
2791 If the terminal supports the visibility requested, the previous cursor
2792 state is returned; otherwise, an exception is raised. On many terminals,
2793 the "visible" mode is an underline cursor and the "very visible" mode is
2794 a block cursor.
2795 [clinic start generated code]*/
2796
2797 static PyObject *
_curses_curs_set_impl(PyObject * module,int visibility)2798 _curses_curs_set_impl(PyObject *module, int visibility)
2799 /*[clinic end generated code: output=ee8e62483b1d6cd4 input=81a7924a65d29504]*/
2800 {
2801 int erg;
2802
2803 PyCursesInitialised;
2804
2805 erg = curs_set(visibility);
2806 if (erg == ERR) return PyCursesCheckERR(erg, "curs_set");
2807
2808 return PyLong_FromLong((long) erg);
2809 }
2810
2811 /*[clinic input]
2812 _curses.def_prog_mode
2813
2814 Save the current terminal mode as the "program" mode.
2815
2816 The "program" mode is the mode when the running program is using curses.
2817
2818 Subsequent calls to reset_prog_mode() will restore this mode.
2819 [clinic start generated code]*/
2820
2821 static PyObject *
_curses_def_prog_mode_impl(PyObject * module)2822 _curses_def_prog_mode_impl(PyObject *module)
2823 /*[clinic end generated code: output=05d5a351fff874aa input=768b9cace620dda5]*/
2824 NoArgNoReturnFunctionBody(def_prog_mode)
2825
2826 /*[clinic input]
2827 _curses.def_shell_mode
2828
2829 Save the current terminal mode as the "shell" mode.
2830
2831 The "shell" mode is the mode when the running program is not using curses.
2832
2833 Subsequent calls to reset_shell_mode() will restore this mode.
2834 [clinic start generated code]*/
2835
2836 static PyObject *
2837 _curses_def_shell_mode_impl(PyObject *module)
2838 /*[clinic end generated code: output=d6e42f5c768f860f input=5ead21f6f0baa894]*/
2839 NoArgNoReturnFunctionBody(def_shell_mode)
2840
2841 /*[clinic input]
2842 _curses.delay_output
2843
2844 ms: int
2845 Duration in milliseconds.
2846 /
2847
2848 Insert a pause in output.
2849 [clinic start generated code]*/
2850
2851 static PyObject *
2852 _curses_delay_output_impl(PyObject *module, int ms)
2853 /*[clinic end generated code: output=b6613a67f17fa4f4 input=5316457f5f59196c]*/
2854 {
2855 PyCursesInitialised;
2856
2857 return PyCursesCheckERR(delay_output(ms), "delay_output");
2858 }
2859
2860 /*[clinic input]
2861 _curses.doupdate
2862
2863 Update the physical screen to match the virtual screen.
2864 [clinic start generated code]*/
2865
2866 static PyObject *
_curses_doupdate_impl(PyObject * module)2867 _curses_doupdate_impl(PyObject *module)
2868 /*[clinic end generated code: output=f34536975a75680c input=8da80914432a6489]*/
2869 NoArgNoReturnFunctionBody(doupdate)
2870
2871 /*[clinic input]
2872 _curses.echo
2873
2874 flag: bool(accept={int}) = True
2875 If false, the effect is the same as calling noecho().
2876 /
2877
2878 Enter echo mode.
2879
2880 In echo mode, each character input is echoed to the screen as it is entered.
2881 [clinic start generated code]*/
2882
2883 static PyObject *
2884 _curses_echo_impl(PyObject *module, int flag)
2885 /*[clinic end generated code: output=03acb2ddfa6c8729 input=2e9e891d637eac5d]*/
2886 NoArgOrFlagNoReturnFunctionBody(echo, flag)
2887
2888 /*[clinic input]
2889 _curses.endwin
2890
2891 De-initialize the library, and return terminal to normal status.
2892 [clinic start generated code]*/
2893
2894 static PyObject *
2895 _curses_endwin_impl(PyObject *module)
2896 /*[clinic end generated code: output=c0150cd96d2f4128 input=e172cfa43062f3fa]*/
2897 NoArgNoReturnFunctionBody(endwin)
2898
2899 /*[clinic input]
2900 _curses.erasechar
2901
2902 Return the user's current erase character.
2903 [clinic start generated code]*/
2904
2905 static PyObject *
2906 _curses_erasechar_impl(PyObject *module)
2907 /*[clinic end generated code: output=3df305dc6b926b3f input=628c136c3c5758d3]*/
2908 {
2909 char ch;
2910
2911 PyCursesInitialised;
2912
2913 ch = erasechar();
2914
2915 return PyBytes_FromStringAndSize(&ch, 1);
2916 }
2917
2918 /*[clinic input]
2919 _curses.flash
2920
2921 Flash the screen.
2922
2923 That is, change it to reverse-video and then change it back in a short interval.
2924 [clinic start generated code]*/
2925
2926 static PyObject *
_curses_flash_impl(PyObject * module)2927 _curses_flash_impl(PyObject *module)
2928 /*[clinic end generated code: output=488b8a0ebd9ea9b8 input=02fdfb06c8fc3171]*/
2929 NoArgNoReturnFunctionBody(flash)
2930
2931 /*[clinic input]
2932 _curses.flushinp
2933
2934 Flush all input buffers.
2935
2936 This throws away any typeahead that has been typed by the user and has not
2937 yet been processed by the program.
2938 [clinic start generated code]*/
2939
2940 static PyObject *
2941 _curses_flushinp_impl(PyObject *module)
2942 /*[clinic end generated code: output=7e7a1fc1473960f5 input=59d042e705cef5ec]*/
2943 NoArgNoReturnVoidFunctionBody(flushinp)
2944
2945 #ifdef getsyx
2946 /*[clinic input]
2947 _curses.getsyx
2948
2949 Return the current coordinates of the virtual screen cursor.
2950
2951 Return a (y, x) tuple. If leaveok is currently true, return (-1, -1).
2952 [clinic start generated code]*/
2953
2954 static PyObject *
2955 _curses_getsyx_impl(PyObject *module)
2956 /*[clinic end generated code: output=c8e6c3f42349a038 input=9e1f862f3b4f7cba]*/
2957 {
2958 int x = 0;
2959 int y = 0;
2960
2961 PyCursesInitialised;
2962
2963 getsyx(y, x);
2964
2965 return Py_BuildValue("(ii)", y, x);
2966 }
2967 #endif
2968
2969 #ifdef NCURSES_MOUSE_VERSION
2970 /*[clinic input]
2971 _curses.getmouse
2972
2973 Retrieve the queued mouse event.
2974
2975 After getch() returns KEY_MOUSE to signal a mouse event, this function
2976 returns a 5-tuple (id, x, y, z, bstate).
2977 [clinic start generated code]*/
2978
2979 static PyObject *
_curses_getmouse_impl(PyObject * module)2980 _curses_getmouse_impl(PyObject *module)
2981 /*[clinic end generated code: output=ccf4242546b9cfa8 input=5b756ee6f5b481b1]*/
2982 {
2983 int rtn;
2984 MEVENT event;
2985
2986 PyCursesInitialised;
2987
2988 rtn = getmouse( &event );
2989 if (rtn == ERR) {
2990 PyErr_SetString(PyCursesError, "getmouse() returned ERR");
2991 return NULL;
2992 }
2993 return Py_BuildValue("(hiiik)",
2994 (short)event.id,
2995 (int)event.x, (int)event.y, (int)event.z,
2996 (unsigned long) event.bstate);
2997 }
2998
2999 /*[clinic input]
3000 _curses.ungetmouse
3001
3002 id: short
3003 x: int
3004 y: int
3005 z: int
3006 bstate: unsigned_long(bitwise=True)
3007 /
3008
3009 Push a KEY_MOUSE event onto the input queue.
3010
3011 The following getmouse() will return the given state data.
3012 [clinic start generated code]*/
3013
3014 static PyObject *
_curses_ungetmouse_impl(PyObject * module,short id,int x,int y,int z,unsigned long bstate)3015 _curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z,
3016 unsigned long bstate)
3017 /*[clinic end generated code: output=3430c9b0fc5c4341 input=fd650b2ca5a01e8f]*/
3018 {
3019 MEVENT event;
3020
3021 PyCursesInitialised;
3022
3023 event.id = id;
3024 event.x = x;
3025 event.y = y;
3026 event.z = z;
3027 event.bstate = bstate;
3028 return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
3029 }
3030 #endif
3031
3032 /*[clinic input]
3033 _curses.getwin
3034
3035 file: object
3036 /
3037
3038 Read window related data stored in the file by an earlier putwin() call.
3039
3040 The routine then creates and initializes a new window using that data,
3041 returning the new window object.
3042 [clinic start generated code]*/
3043
3044 static PyObject *
_curses_getwin(PyObject * module,PyObject * file)3045 _curses_getwin(PyObject *module, PyObject *file)
3046 /*[clinic end generated code: output=a79e0df3379af756 input=f713d2bba0e4c929]*/
3047 {
3048 FILE *fp;
3049 PyObject *data;
3050 size_t datalen;
3051 WINDOW *win;
3052 _Py_IDENTIFIER(read);
3053 PyObject *res = NULL;
3054
3055 PyCursesInitialised;
3056
3057 fp = tmpfile();
3058 if (fp == NULL)
3059 return PyErr_SetFromErrno(PyExc_OSError);
3060
3061 if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0)
3062 goto error;
3063
3064 data = _PyObject_CallMethodIdNoArgs(file, &PyId_read);
3065 if (data == NULL)
3066 goto error;
3067 if (!PyBytes_Check(data)) {
3068 PyErr_Format(PyExc_TypeError,
3069 "f.read() returned %.100s instead of bytes",
3070 Py_TYPE(data)->tp_name);
3071 Py_DECREF(data);
3072 goto error;
3073 }
3074 datalen = PyBytes_GET_SIZE(data);
3075 if (fwrite(PyBytes_AS_STRING(data), 1, datalen, fp) != datalen) {
3076 Py_DECREF(data);
3077 PyErr_SetFromErrno(PyExc_OSError);
3078 goto error;
3079 }
3080 Py_DECREF(data);
3081
3082 fseek(fp, 0, 0);
3083 win = getwin(fp);
3084 if (win == NULL) {
3085 PyErr_SetString(PyCursesError, catchall_NULL);
3086 goto error;
3087 }
3088 res = PyCursesWindow_New(win, NULL);
3089
3090 error:
3091 fclose(fp);
3092 return res;
3093 }
3094
3095 /*[clinic input]
3096 _curses.halfdelay
3097
3098 tenths: byte
3099 Maximal blocking delay in tenths of seconds (1 - 255).
3100 /
3101
3102 Enter half-delay mode.
3103
3104 Use nocbreak() to leave half-delay mode.
3105 [clinic start generated code]*/
3106
3107 static PyObject *
_curses_halfdelay_impl(PyObject * module,unsigned char tenths)3108 _curses_halfdelay_impl(PyObject *module, unsigned char tenths)
3109 /*[clinic end generated code: output=e92cdf0ef33c0663 input=e42dce7259c15100]*/
3110 {
3111 PyCursesInitialised;
3112
3113 return PyCursesCheckERR(halfdelay(tenths), "halfdelay");
3114 }
3115
3116 /*[clinic input]
3117 _curses.has_colors
3118
3119 Return True if the terminal can display colors; otherwise, return False.
3120 [clinic start generated code]*/
3121
3122 static PyObject *
_curses_has_colors_impl(PyObject * module)3123 _curses_has_colors_impl(PyObject *module)
3124 /*[clinic end generated code: output=db5667483139e3e2 input=b2ec41b739d896c6]*/
3125 NoArgTrueFalseFunctionBody(has_colors)
3126
3127 /*[clinic input]
3128 _curses.has_ic
3129
3130 Return True if the terminal has insert- and delete-character capabilities.
3131 [clinic start generated code]*/
3132
3133 static PyObject *
3134 _curses_has_ic_impl(PyObject *module)
3135 /*[clinic end generated code: output=6be24da9cb1268fe input=9bc2d3a797cc7324]*/
3136 NoArgTrueFalseFunctionBody(has_ic)
3137
3138 /*[clinic input]
3139 _curses.has_il
3140
3141 Return True if the terminal has insert- and delete-line capabilities.
3142 [clinic start generated code]*/
3143
3144 static PyObject *
3145 _curses_has_il_impl(PyObject *module)
3146 /*[clinic end generated code: output=d45bd7788ff9f5f4 input=cd939d5607ee5427]*/
3147 NoArgTrueFalseFunctionBody(has_il)
3148
3149 #ifdef HAVE_CURSES_HAS_KEY
3150 /*[clinic input]
3151 _curses.has_key
3152
3153 key: int
3154 Key number.
3155 /
3156
3157 Return True if the current terminal type recognizes a key with that value.
3158 [clinic start generated code]*/
3159
3160 static PyObject *
3161 _curses_has_key_impl(PyObject *module, int key)
3162 /*[clinic end generated code: output=19ad48319414d0b1 input=78bd44acf1a4997c]*/
3163 {
3164 PyCursesInitialised;
3165
3166 return PyBool_FromLong(has_key(key));
3167 }
3168 #endif
3169
3170 /*[clinic input]
3171 _curses.init_color
3172
3173 color_number: color
3174 The number of the color to be changed (0 - (COLORS-1)).
3175 r: component
3176 Red component (0 - 1000).
3177 g: component
3178 Green component (0 - 1000).
3179 b: component
3180 Blue component (0 - 1000).
3181 /
3182
3183 Change the definition of a color.
3184
3185 When init_color() is used, all occurrences of that color on the screen
3186 immediately change to the new definition. This function is a no-op on
3187 most terminals; it is active only if can_change_color() returns true.
3188 [clinic start generated code]*/
3189
3190 static PyObject *
_curses_init_color_impl(PyObject * module,int color_number,short r,short g,short b)3191 _curses_init_color_impl(PyObject *module, int color_number, short r, short g,
3192 short b)
3193 /*[clinic end generated code: output=d7ed71b2d818cdf2 input=ae2b8bea0f152c80]*/
3194 {
3195 PyCursesInitialised;
3196 PyCursesInitialisedColor;
3197
3198 return PyCursesCheckERR(_CURSES_INIT_COLOR_FUNC(color_number, r, g, b),
3199 Py_STRINGIFY(_CURSES_INIT_COLOR_FUNC));
3200 }
3201
3202 /*[clinic input]
3203 _curses.init_pair
3204
3205 pair_number: pair
3206 The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).
3207 fg: color_allow_default
3208 Foreground color number (-1 - (COLORS-1)).
3209 bg: color_allow_default
3210 Background color number (-1 - (COLORS-1)).
3211 /
3212
3213 Change the definition of a color-pair.
3214
3215 If the color-pair was previously initialized, the screen is refreshed and
3216 all occurrences of that color-pair are changed to the new definition.
3217 [clinic start generated code]*/
3218
3219 static PyObject *
_curses_init_pair_impl(PyObject * module,int pair_number,int fg,int bg)3220 _curses_init_pair_impl(PyObject *module, int pair_number, int fg, int bg)
3221 /*[clinic end generated code: output=a0bba03d2bbc3ee6 input=54b421b44c12c389]*/
3222 {
3223 PyCursesInitialised;
3224 PyCursesInitialisedColor;
3225
3226 if (_CURSES_INIT_PAIR_FUNC(pair_number, fg, bg) == ERR) {
3227 if (pair_number >= COLOR_PAIRS) {
3228 PyErr_Format(PyExc_ValueError,
3229 "Color pair is greater than COLOR_PAIRS-1 (%d).",
3230 COLOR_PAIRS - 1);
3231 }
3232 else {
3233 PyErr_Format(PyCursesError, "%s() returned ERR",
3234 Py_STRINGIFY(_CURSES_INIT_PAIR_FUNC));
3235 }
3236 return NULL;
3237 }
3238
3239 Py_RETURN_NONE;
3240 }
3241
3242 static PyObject *ModDict;
3243
3244 /*[clinic input]
3245 _curses.initscr
3246
3247 Initialize the library.
3248
3249 Return a WindowObject which represents the whole screen.
3250 [clinic start generated code]*/
3251
3252 static PyObject *
_curses_initscr_impl(PyObject * module)3253 _curses_initscr_impl(PyObject *module)
3254 /*[clinic end generated code: output=619fb68443810b7b input=514f4bce1821f6b5]*/
3255 {
3256 WINDOW *win;
3257 PyCursesWindowObject *winobj;
3258
3259 if (initialised) {
3260 wrefresh(stdscr);
3261 return (PyObject *)PyCursesWindow_New(stdscr, NULL);
3262 }
3263
3264 win = initscr();
3265
3266 if (win == NULL) {
3267 PyErr_SetString(PyCursesError, catchall_NULL);
3268 return NULL;
3269 }
3270
3271 initialised = initialised_setupterm = TRUE;
3272
3273 /* This was moved from initcurses() because it core dumped on SGI,
3274 where they're not defined until you've called initscr() */
3275 #define SetDictInt(string,ch) \
3276 do { \
3277 PyObject *o = PyLong_FromLong((long) (ch)); \
3278 if (o && PyDict_SetItemString(ModDict, string, o) == 0) { \
3279 Py_DECREF(o); \
3280 } \
3281 } while (0)
3282
3283 /* Here are some graphic symbols you can use */
3284 SetDictInt("ACS_ULCORNER", (ACS_ULCORNER));
3285 SetDictInt("ACS_LLCORNER", (ACS_LLCORNER));
3286 SetDictInt("ACS_URCORNER", (ACS_URCORNER));
3287 SetDictInt("ACS_LRCORNER", (ACS_LRCORNER));
3288 SetDictInt("ACS_LTEE", (ACS_LTEE));
3289 SetDictInt("ACS_RTEE", (ACS_RTEE));
3290 SetDictInt("ACS_BTEE", (ACS_BTEE));
3291 SetDictInt("ACS_TTEE", (ACS_TTEE));
3292 SetDictInt("ACS_HLINE", (ACS_HLINE));
3293 SetDictInt("ACS_VLINE", (ACS_VLINE));
3294 SetDictInt("ACS_PLUS", (ACS_PLUS));
3295 #if !defined(__hpux) || defined(HAVE_NCURSES_H)
3296 /* On HP/UX 11, these are of type cchar_t, which is not an
3297 integral type. If this is a problem on more platforms, a
3298 configure test should be added to determine whether ACS_S1
3299 is of integral type. */
3300 SetDictInt("ACS_S1", (ACS_S1));
3301 SetDictInt("ACS_S9", (ACS_S9));
3302 SetDictInt("ACS_DIAMOND", (ACS_DIAMOND));
3303 SetDictInt("ACS_CKBOARD", (ACS_CKBOARD));
3304 SetDictInt("ACS_DEGREE", (ACS_DEGREE));
3305 SetDictInt("ACS_PLMINUS", (ACS_PLMINUS));
3306 SetDictInt("ACS_BULLET", (ACS_BULLET));
3307 SetDictInt("ACS_LARROW", (ACS_LARROW));
3308 SetDictInt("ACS_RARROW", (ACS_RARROW));
3309 SetDictInt("ACS_DARROW", (ACS_DARROW));
3310 SetDictInt("ACS_UARROW", (ACS_UARROW));
3311 SetDictInt("ACS_BOARD", (ACS_BOARD));
3312 SetDictInt("ACS_LANTERN", (ACS_LANTERN));
3313 SetDictInt("ACS_BLOCK", (ACS_BLOCK));
3314 #endif
3315 SetDictInt("ACS_BSSB", (ACS_ULCORNER));
3316 SetDictInt("ACS_SSBB", (ACS_LLCORNER));
3317 SetDictInt("ACS_BBSS", (ACS_URCORNER));
3318 SetDictInt("ACS_SBBS", (ACS_LRCORNER));
3319 SetDictInt("ACS_SBSS", (ACS_RTEE));
3320 SetDictInt("ACS_SSSB", (ACS_LTEE));
3321 SetDictInt("ACS_SSBS", (ACS_BTEE));
3322 SetDictInt("ACS_BSSS", (ACS_TTEE));
3323 SetDictInt("ACS_BSBS", (ACS_HLINE));
3324 SetDictInt("ACS_SBSB", (ACS_VLINE));
3325 SetDictInt("ACS_SSSS", (ACS_PLUS));
3326
3327 /* The following are never available with strict SYSV curses */
3328 #ifdef ACS_S3
3329 SetDictInt("ACS_S3", (ACS_S3));
3330 #endif
3331 #ifdef ACS_S7
3332 SetDictInt("ACS_S7", (ACS_S7));
3333 #endif
3334 #ifdef ACS_LEQUAL
3335 SetDictInt("ACS_LEQUAL", (ACS_LEQUAL));
3336 #endif
3337 #ifdef ACS_GEQUAL
3338 SetDictInt("ACS_GEQUAL", (ACS_GEQUAL));
3339 #endif
3340 #ifdef ACS_PI
3341 SetDictInt("ACS_PI", (ACS_PI));
3342 #endif
3343 #ifdef ACS_NEQUAL
3344 SetDictInt("ACS_NEQUAL", (ACS_NEQUAL));
3345 #endif
3346 #ifdef ACS_STERLING
3347 SetDictInt("ACS_STERLING", (ACS_STERLING));
3348 #endif
3349
3350 SetDictInt("LINES", LINES);
3351 SetDictInt("COLS", COLS);
3352
3353 winobj = (PyCursesWindowObject *)PyCursesWindow_New(win, NULL);
3354 screen_encoding = winobj->encoding;
3355 return (PyObject *)winobj;
3356 }
3357
3358 /*[clinic input]
3359 _curses.setupterm
3360
3361 term: str(accept={str, NoneType}) = None
3362 Terminal name.
3363 If omitted, the value of the TERM environment variable will be used.
3364 fd: int = -1
3365 File descriptor to which any initialization sequences will be sent.
3366 If not supplied, the file descriptor for sys.stdout will be used.
3367
3368 Initialize the terminal.
3369 [clinic start generated code]*/
3370
3371 static PyObject *
_curses_setupterm_impl(PyObject * module,const char * term,int fd)3372 _curses_setupterm_impl(PyObject *module, const char *term, int fd)
3373 /*[clinic end generated code: output=4584e587350f2848 input=4511472766af0c12]*/
3374 {
3375 int err;
3376
3377 if (fd == -1) {
3378 PyObject* sys_stdout;
3379
3380 sys_stdout = PySys_GetObject("stdout");
3381
3382 if (sys_stdout == NULL || sys_stdout == Py_None) {
3383 PyErr_SetString(
3384 PyCursesError,
3385 "lost sys.stdout");
3386 return NULL;
3387 }
3388
3389 fd = PyObject_AsFileDescriptor(sys_stdout);
3390
3391 if (fd == -1) {
3392 return NULL;
3393 }
3394 }
3395
3396 if (!initialised_setupterm && setupterm((char *)term, fd, &err) == ERR) {
3397 const char* s = "setupterm: unknown error";
3398
3399 if (err == 0) {
3400 s = "setupterm: could not find terminal";
3401 } else if (err == -1) {
3402 s = "setupterm: could not find terminfo database";
3403 }
3404
3405 PyErr_SetString(PyCursesError,s);
3406 return NULL;
3407 }
3408
3409 initialised_setupterm = TRUE;
3410
3411 Py_RETURN_NONE;
3412 }
3413
3414 #if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20081102
3415 // https://invisible-island.net/ncurses/NEWS.html#index-t20080119
3416
3417 /*[clinic input]
3418 _curses.get_escdelay
3419
3420 Gets the curses ESCDELAY setting.
3421
3422 Gets the number of milliseconds to wait after reading an escape character,
3423 to distinguish between an individual escape character entered on the
3424 keyboard from escape sequences sent by cursor and function keys.
3425 [clinic start generated code]*/
3426
3427 static PyObject *
_curses_get_escdelay_impl(PyObject * module)3428 _curses_get_escdelay_impl(PyObject *module)
3429 /*[clinic end generated code: output=222fa1a822555d60 input=be2d5b3dd974d0a4]*/
3430 {
3431 return PyLong_FromLong(ESCDELAY);
3432 }
3433 /*[clinic input]
3434 _curses.set_escdelay
3435 ms: int
3436 length of the delay in milliseconds.
3437 /
3438
3439 Sets the curses ESCDELAY setting.
3440
3441 Sets the number of milliseconds to wait after reading an escape character,
3442 to distinguish between an individual escape character entered on the
3443 keyboard from escape sequences sent by cursor and function keys.
3444 [clinic start generated code]*/
3445
3446 static PyObject *
_curses_set_escdelay_impl(PyObject * module,int ms)3447 _curses_set_escdelay_impl(PyObject *module, int ms)
3448 /*[clinic end generated code: output=43818efbf7980ac4 input=7796fe19f111e250]*/
3449 {
3450 if (ms <= 0) {
3451 PyErr_SetString(PyExc_ValueError, "ms must be > 0");
3452 return NULL;
3453 }
3454
3455 return PyCursesCheckERR(set_escdelay(ms), "set_escdelay");
3456 }
3457
3458 /*[clinic input]
3459 _curses.get_tabsize
3460
3461 Gets the curses TABSIZE setting.
3462
3463 Gets the number of columns used by the curses library when converting a tab
3464 character to spaces as it adds the tab to a window.
3465 [clinic start generated code]*/
3466
3467 static PyObject *
_curses_get_tabsize_impl(PyObject * module)3468 _curses_get_tabsize_impl(PyObject *module)
3469 /*[clinic end generated code: output=7e9e51fb6126fbdf input=74af86bf6c9f5d7e]*/
3470 {
3471 return PyLong_FromLong(TABSIZE);
3472 }
3473 /*[clinic input]
3474 _curses.set_tabsize
3475 size: int
3476 rendered cell width of a tab character.
3477 /
3478
3479 Sets the curses TABSIZE setting.
3480
3481 Sets the number of columns used by the curses library when converting a tab
3482 character to spaces as it adds the tab to a window.
3483 [clinic start generated code]*/
3484
3485 static PyObject *
_curses_set_tabsize_impl(PyObject * module,int size)3486 _curses_set_tabsize_impl(PyObject *module, int size)
3487 /*[clinic end generated code: output=c1de5a76c0daab1e input=78cba6a3021ad061]*/
3488 {
3489 if (size <= 0) {
3490 PyErr_SetString(PyExc_ValueError, "size must be > 0");
3491 return NULL;
3492 }
3493
3494 return PyCursesCheckERR(set_tabsize(size), "set_tabsize");
3495 }
3496 #endif
3497
3498 /*[clinic input]
3499 _curses.intrflush
3500
3501 flag: bool(accept={int})
3502 /
3503
3504 [clinic start generated code]*/
3505
3506 static PyObject *
_curses_intrflush_impl(PyObject * module,int flag)3507 _curses_intrflush_impl(PyObject *module, int flag)
3508 /*[clinic end generated code: output=c1986df35e999a0f input=fcba57bb28dfd795]*/
3509 {
3510 PyCursesInitialised;
3511
3512 return PyCursesCheckERR(intrflush(NULL, flag), "intrflush");
3513 }
3514
3515 /*[clinic input]
3516 _curses.isendwin
3517
3518 Return True if endwin() has been called.
3519 [clinic start generated code]*/
3520
3521 static PyObject *
_curses_isendwin_impl(PyObject * module)3522 _curses_isendwin_impl(PyObject *module)
3523 /*[clinic end generated code: output=d73179e4a7e1eb8c input=6cdb01a7ebf71397]*/
3524 NoArgTrueFalseFunctionBody(isendwin)
3525
3526 #ifdef HAVE_CURSES_IS_TERM_RESIZED
3527 /*[clinic input]
3528 _curses.is_term_resized
3529
3530 nlines: int
3531 Height.
3532 ncols: int
3533 Width.
3534 /
3535
3536 Return True if resize_term() would modify the window structure, False otherwise.
3537 [clinic start generated code]*/
3538
3539 static PyObject *
3540 _curses_is_term_resized_impl(PyObject *module, int nlines, int ncols)
3541 /*[clinic end generated code: output=aafe04afe50f1288 input=ca9c0bd0fb8ab444]*/
3542 {
3543 PyCursesInitialised;
3544
3545 return PyBool_FromLong(is_term_resized(nlines, ncols));
3546 }
3547 #endif /* HAVE_CURSES_IS_TERM_RESIZED */
3548
3549 /*[clinic input]
3550 _curses.keyname
3551
3552 key: int
3553 Key number.
3554 /
3555
3556 Return the name of specified key.
3557 [clinic start generated code]*/
3558
3559 static PyObject *
_curses_keyname_impl(PyObject * module,int key)3560 _curses_keyname_impl(PyObject *module, int key)
3561 /*[clinic end generated code: output=fa2675ab3f4e056b input=ee4b1d0f243a2a2b]*/
3562 {
3563 const char *knp;
3564
3565 PyCursesInitialised;
3566
3567 if (key < 0) {
3568 PyErr_SetString(PyExc_ValueError, "invalid key number");
3569 return NULL;
3570 }
3571 knp = keyname(key);
3572
3573 return PyBytes_FromString((knp == NULL) ? "" : knp);
3574 }
3575
3576 /*[clinic input]
3577 _curses.killchar
3578
3579 Return the user's current line kill character.
3580 [clinic start generated code]*/
3581
3582 static PyObject *
_curses_killchar_impl(PyObject * module)3583 _curses_killchar_impl(PyObject *module)
3584 /*[clinic end generated code: output=31c3a45b2c528269 input=1ff171c38df5ccad]*/
3585 {
3586 char ch;
3587
3588 ch = killchar();
3589
3590 return PyBytes_FromStringAndSize(&ch, 1);
3591 }
3592
3593 /*[clinic input]
3594 _curses.longname
3595
3596 Return the terminfo long name field describing the current terminal.
3597
3598 The maximum length of a verbose description is 128 characters. It is defined
3599 only after the call to initscr().
3600 [clinic start generated code]*/
3601
3602 static PyObject *
_curses_longname_impl(PyObject * module)3603 _curses_longname_impl(PyObject *module)
3604 /*[clinic end generated code: output=fdf30433727ef568 input=84c3f20201b1098e]*/
3605 NoArgReturnStringFunctionBody(longname)
3606
3607 /*[clinic input]
3608 _curses.meta
3609
3610 yes: bool(accept={int})
3611 /
3612
3613 Enable/disable meta keys.
3614
3615 If yes is True, allow 8-bit characters to be input. If yes is False,
3616 allow only 7-bit characters.
3617 [clinic start generated code]*/
3618
3619 static PyObject *
3620 _curses_meta_impl(PyObject *module, int yes)
3621 /*[clinic end generated code: output=22f5abda46a605d8 input=af9892e3a74f35db]*/
3622 {
3623 PyCursesInitialised;
3624
3625 return PyCursesCheckERR(meta(stdscr, yes), "meta");
3626 }
3627
3628 #ifdef NCURSES_MOUSE_VERSION
3629 /*[clinic input]
3630 _curses.mouseinterval
3631
3632 interval: int
3633 Time in milliseconds.
3634 /
3635
3636 Set and retrieve the maximum time between press and release in a click.
3637
3638 Set the maximum time that can elapse between press and release events in
3639 order for them to be recognized as a click, and return the previous interval
3640 value.
3641 [clinic start generated code]*/
3642
3643 static PyObject *
_curses_mouseinterval_impl(PyObject * module,int interval)3644 _curses_mouseinterval_impl(PyObject *module, int interval)
3645 /*[clinic end generated code: output=c4f5ff04354634c5 input=75aaa3f0db10ac4e]*/
3646 {
3647 PyCursesInitialised;
3648
3649 return PyCursesCheckERR(mouseinterval(interval), "mouseinterval");
3650 }
3651
3652 /*[clinic input]
3653 _curses.mousemask
3654
3655 newmask: unsigned_long(bitwise=True)
3656 /
3657
3658 Set the mouse events to be reported, and return a tuple (availmask, oldmask).
3659
3660 Return a tuple (availmask, oldmask). availmask indicates which of the
3661 specified mouse events can be reported; on complete failure it returns 0.
3662 oldmask is the previous value of the given window's mouse event mask.
3663 If this function is never called, no mouse events are ever reported.
3664 [clinic start generated code]*/
3665
3666 static PyObject *
_curses_mousemask_impl(PyObject * module,unsigned long newmask)3667 _curses_mousemask_impl(PyObject *module, unsigned long newmask)
3668 /*[clinic end generated code: output=9406cf1b8a36e485 input=bdf76b7568a3c541]*/
3669 {
3670 mmask_t oldmask, availmask;
3671
3672 PyCursesInitialised;
3673 availmask = mousemask((mmask_t)newmask, &oldmask);
3674 return Py_BuildValue("(kk)",
3675 (unsigned long)availmask, (unsigned long)oldmask);
3676 }
3677 #endif
3678
3679 /*[clinic input]
3680 _curses.napms
3681
3682 ms: int
3683 Duration in milliseconds.
3684 /
3685
3686 Sleep for specified time.
3687 [clinic start generated code]*/
3688
3689 static PyObject *
_curses_napms_impl(PyObject * module,int ms)3690 _curses_napms_impl(PyObject *module, int ms)
3691 /*[clinic end generated code: output=a40a1da2e39ea438 input=20cd3af2b6900f56]*/
3692 {
3693 PyCursesInitialised;
3694
3695 return Py_BuildValue("i", napms(ms));
3696 }
3697
3698
3699 /*[clinic input]
3700 _curses.newpad
3701
3702 nlines: int
3703 Height.
3704 ncols: int
3705 Width.
3706 /
3707
3708 Create and return a pointer to a new pad data structure.
3709 [clinic start generated code]*/
3710
3711 static PyObject *
_curses_newpad_impl(PyObject * module,int nlines,int ncols)3712 _curses_newpad_impl(PyObject *module, int nlines, int ncols)
3713 /*[clinic end generated code: output=de52a56eb1098ec9 input=93f1272f240d8894]*/
3714 {
3715 WINDOW *win;
3716
3717 PyCursesInitialised;
3718
3719 win = newpad(nlines, ncols);
3720
3721 if (win == NULL) {
3722 PyErr_SetString(PyCursesError, catchall_NULL);
3723 return NULL;
3724 }
3725
3726 return (PyObject *)PyCursesWindow_New(win, NULL);
3727 }
3728
3729 /*[clinic input]
3730 _curses.newwin
3731
3732 nlines: int
3733 Height.
3734 ncols: int
3735 Width.
3736 [
3737 begin_y: int = 0
3738 Top side y-coordinate.
3739 begin_x: int = 0
3740 Left side x-coordinate.
3741 ]
3742 /
3743
3744 Return a new window.
3745
3746 By default, the window will extend from the specified position to the lower
3747 right corner of the screen.
3748 [clinic start generated code]*/
3749
3750 static PyObject *
_curses_newwin_impl(PyObject * module,int nlines,int ncols,int group_right_1,int begin_y,int begin_x)3751 _curses_newwin_impl(PyObject *module, int nlines, int ncols,
3752 int group_right_1, int begin_y, int begin_x)
3753 /*[clinic end generated code: output=c1e0a8dc8ac2826c input=29312c15a72a003d]*/
3754 {
3755 WINDOW *win;
3756
3757 PyCursesInitialised;
3758
3759 win = newwin(nlines,ncols,begin_y,begin_x);
3760 if (win == NULL) {
3761 PyErr_SetString(PyCursesError, catchall_NULL);
3762 return NULL;
3763 }
3764
3765 return (PyObject *)PyCursesWindow_New(win, NULL);
3766 }
3767
3768 /*[clinic input]
3769 _curses.nl
3770
3771 flag: bool(accept={int}) = True
3772 If false, the effect is the same as calling nonl().
3773 /
3774
3775 Enter newline mode.
3776
3777 This mode translates the return key into newline on input, and translates
3778 newline into return and line-feed on output. Newline mode is initially on.
3779 [clinic start generated code]*/
3780
3781 static PyObject *
_curses_nl_impl(PyObject * module,int flag)3782 _curses_nl_impl(PyObject *module, int flag)
3783 /*[clinic end generated code: output=b39cc0ffc9015003 input=cf36a63f7b86e28a]*/
3784 NoArgOrFlagNoReturnFunctionBody(nl, flag)
3785
3786 /*[clinic input]
3787 _curses.nocbreak
3788
3789 Leave cbreak mode.
3790
3791 Return to normal "cooked" mode with line buffering.
3792 [clinic start generated code]*/
3793
3794 static PyObject *
3795 _curses_nocbreak_impl(PyObject *module)
3796 /*[clinic end generated code: output=eabf3833a4fbf620 input=e4b65f7d734af400]*/
3797 NoArgNoReturnFunctionBody(nocbreak)
3798
3799 /*[clinic input]
3800 _curses.noecho
3801
3802 Leave echo mode.
3803
3804 Echoing of input characters is turned off.
3805 [clinic start generated code]*/
3806
3807 static PyObject *
3808 _curses_noecho_impl(PyObject *module)
3809 /*[clinic end generated code: output=cc95ab45bc98f41b input=76714df529e614c3]*/
3810 NoArgNoReturnFunctionBody(noecho)
3811
3812 /*[clinic input]
3813 _curses.nonl
3814
3815 Leave newline mode.
3816
3817 Disable translation of return into newline on input, and disable low-level
3818 translation of newline into newline/return on output.
3819 [clinic start generated code]*/
3820
3821 static PyObject *
3822 _curses_nonl_impl(PyObject *module)
3823 /*[clinic end generated code: output=99e917e9715770c6 input=9d37dd122d3022fc]*/
3824 NoArgNoReturnFunctionBody(nonl)
3825
3826 /*[clinic input]
3827 _curses.noqiflush
3828
3829 Disable queue flushing.
3830
3831 When queue flushing is disabled, normal flush of input and output queues
3832 associated with the INTR, QUIT and SUSP characters will not be done.
3833 [clinic start generated code]*/
3834
3835 static PyObject *
3836 _curses_noqiflush_impl(PyObject *module)
3837 /*[clinic end generated code: output=8b95a4229bbf0877 input=ba3e6b2e3e54c4df]*/
3838 NoArgNoReturnVoidFunctionBody(noqiflush)
3839
3840 /*[clinic input]
3841 _curses.noraw
3842
3843 Leave raw mode.
3844
3845 Return to normal "cooked" mode with line buffering.
3846 [clinic start generated code]*/
3847
3848 static PyObject *
3849 _curses_noraw_impl(PyObject *module)
3850 /*[clinic end generated code: output=39894e5524c430cc input=6ec86692096dffb5]*/
3851 NoArgNoReturnFunctionBody(noraw)
3852
3853 /*[clinic input]
3854 _curses.pair_content
3855
3856 pair_number: pair
3857 The number of the color pair (0 - (COLOR_PAIRS-1)).
3858 /
3859
3860 Return a tuple (fg, bg) containing the colors for the requested color pair.
3861 [clinic start generated code]*/
3862
3863 static PyObject *
3864 _curses_pair_content_impl(PyObject *module, int pair_number)
3865 /*[clinic end generated code: output=4a726dd0e6885f3f input=03970f840fc7b739]*/
3866 {
3867 _CURSES_COLOR_NUM_TYPE f, b;
3868
3869 PyCursesInitialised;
3870 PyCursesInitialisedColor;
3871
3872 if (_CURSES_PAIR_CONTENT_FUNC(pair_number, &f, &b) == ERR) {
3873 if (pair_number >= COLOR_PAIRS) {
3874 PyErr_Format(PyExc_ValueError,
3875 "Color pair is greater than COLOR_PAIRS-1 (%d).",
3876 COLOR_PAIRS - 1);
3877 }
3878 else {
3879 PyErr_Format(PyCursesError, "%s() returned ERR",
3880 Py_STRINGIFY(_CURSES_PAIR_CONTENT_FUNC));
3881 }
3882 return NULL;
3883 }
3884
3885 return Py_BuildValue("(ii)", f, b);
3886 }
3887
3888 /*[clinic input]
3889 _curses.pair_number
3890
3891 attr: int
3892 /
3893
3894 Return the number of the color-pair set by the specified attribute value.
3895
3896 color_pair() is the counterpart to this function.
3897 [clinic start generated code]*/
3898
3899 static PyObject *
_curses_pair_number_impl(PyObject * module,int attr)3900 _curses_pair_number_impl(PyObject *module, int attr)
3901 /*[clinic end generated code: output=85bce7d65c0aa3f4 input=d478548e33f5e61a]*/
3902 {
3903 PyCursesInitialised;
3904 PyCursesInitialisedColor;
3905
3906 return PyLong_FromLong(PAIR_NUMBER(attr));
3907 }
3908
3909 /*[clinic input]
3910 _curses.putp
3911
3912 string: str(accept={robuffer})
3913 /
3914
3915 Emit the value of a specified terminfo capability for the current terminal.
3916
3917 Note that the output of putp() always goes to standard output.
3918 [clinic start generated code]*/
3919
3920 static PyObject *
_curses_putp_impl(PyObject * module,const char * string)3921 _curses_putp_impl(PyObject *module, const char *string)
3922 /*[clinic end generated code: output=e98081d1b8eb5816 input=1601faa828b44cb3]*/
3923 {
3924 return PyCursesCheckERR(putp(string), "putp");
3925 }
3926
3927 /*[clinic input]
3928 _curses.qiflush
3929
3930 flag: bool(accept={int}) = True
3931 If false, the effect is the same as calling noqiflush().
3932 /
3933
3934 Enable queue flushing.
3935
3936 If queue flushing is enabled, all output in the display driver queue
3937 will be flushed when the INTR, QUIT and SUSP characters are read.
3938 [clinic start generated code]*/
3939
3940 static PyObject *
_curses_qiflush_impl(PyObject * module,int flag)3941 _curses_qiflush_impl(PyObject *module, int flag)
3942 /*[clinic end generated code: output=9167e862f760ea30 input=e9e4a389946a0dbc]*/
3943 {
3944 PyCursesInitialised;
3945
3946 if (flag) {
3947 qiflush();
3948 }
3949 else {
3950 noqiflush();
3951 }
3952 Py_RETURN_NONE;
3953 }
3954
3955 /* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES
3956 * and _curses.COLS */
3957 #if defined(HAVE_CURSES_RESIZETERM) || defined(HAVE_CURSES_RESIZE_TERM)
3958 static int
update_lines_cols(void)3959 update_lines_cols(void)
3960 {
3961 PyObject *o;
3962 PyObject *m = PyImport_ImportModuleNoBlock("curses");
3963 _Py_IDENTIFIER(LINES);
3964 _Py_IDENTIFIER(COLS);
3965
3966 if (!m)
3967 return 0;
3968
3969 o = PyLong_FromLong(LINES);
3970 if (!o) {
3971 Py_DECREF(m);
3972 return 0;
3973 }
3974 if (_PyObject_SetAttrId(m, &PyId_LINES, o)) {
3975 Py_DECREF(m);
3976 Py_DECREF(o);
3977 return 0;
3978 }
3979 /* PyId_LINES.object will be initialized here. */
3980 if (PyDict_SetItem(ModDict, _PyUnicode_FromId(&PyId_LINES), o)) {
3981 Py_DECREF(m);
3982 Py_DECREF(o);
3983 return 0;
3984 }
3985 Py_DECREF(o);
3986 o = PyLong_FromLong(COLS);
3987 if (!o) {
3988 Py_DECREF(m);
3989 return 0;
3990 }
3991 if (_PyObject_SetAttrId(m, &PyId_COLS, o)) {
3992 Py_DECREF(m);
3993 Py_DECREF(o);
3994 return 0;
3995 }
3996 if (PyDict_SetItem(ModDict, _PyUnicode_FromId(&PyId_COLS), o)) {
3997 Py_DECREF(m);
3998 Py_DECREF(o);
3999 return 0;
4000 }
4001 Py_DECREF(o);
4002 Py_DECREF(m);
4003 return 1;
4004 }
4005
4006 /*[clinic input]
4007 _curses.update_lines_cols
4008
4009 [clinic start generated code]*/
4010
4011 static PyObject *
_curses_update_lines_cols_impl(PyObject * module)4012 _curses_update_lines_cols_impl(PyObject *module)
4013 /*[clinic end generated code: output=423f2b1e63ed0f75 input=5f065ab7a28a5d90]*/
4014 {
4015 if (!update_lines_cols()) {
4016 return NULL;
4017 }
4018 Py_RETURN_NONE;
4019 }
4020
4021 #endif
4022
4023 /*[clinic input]
4024 _curses.raw
4025
4026 flag: bool(accept={int}) = True
4027 If false, the effect is the same as calling noraw().
4028 /
4029
4030 Enter raw mode.
4031
4032 In raw mode, normal line buffering and processing of interrupt, quit,
4033 suspend, and flow control keys are turned off; characters are presented to
4034 curses input functions one by one.
4035 [clinic start generated code]*/
4036
4037 static PyObject *
_curses_raw_impl(PyObject * module,int flag)4038 _curses_raw_impl(PyObject *module, int flag)
4039 /*[clinic end generated code: output=a750e4b342be015b input=e36d8db27832b848]*/
4040 NoArgOrFlagNoReturnFunctionBody(raw, flag)
4041
4042 /*[clinic input]
4043 _curses.reset_prog_mode
4044
4045 Restore the terminal to "program" mode, as previously saved by def_prog_mode().
4046 [clinic start generated code]*/
4047
4048 static PyObject *
4049 _curses_reset_prog_mode_impl(PyObject *module)
4050 /*[clinic end generated code: output=15eb765abf0b6575 input=3d82bea2b3243471]*/
4051 NoArgNoReturnFunctionBody(reset_prog_mode)
4052
4053 /*[clinic input]
4054 _curses.reset_shell_mode
4055
4056 Restore the terminal to "shell" mode, as previously saved by def_shell_mode().
4057 [clinic start generated code]*/
4058
4059 static PyObject *
4060 _curses_reset_shell_mode_impl(PyObject *module)
4061 /*[clinic end generated code: output=0238de2962090d33 input=1c738fa64bd1a24f]*/
4062 NoArgNoReturnFunctionBody(reset_shell_mode)
4063
4064 /*[clinic input]
4065 _curses.resetty
4066
4067 Restore terminal mode.
4068 [clinic start generated code]*/
4069
4070 static PyObject *
4071 _curses_resetty_impl(PyObject *module)
4072 /*[clinic end generated code: output=ff4b448e80a7cd63 input=940493de03624bb0]*/
4073 NoArgNoReturnFunctionBody(resetty)
4074
4075 #ifdef HAVE_CURSES_RESIZETERM
4076 /*[clinic input]
4077 _curses.resizeterm
4078
4079 nlines: int
4080 Height.
4081 ncols: int
4082 Width.
4083 /
4084
4085 Resize the standard and current windows to the specified dimensions.
4086
4087 Adjusts other bookkeeping data used by the curses library that record the
4088 window dimensions (in particular the SIGWINCH handler).
4089 [clinic start generated code]*/
4090
4091 static PyObject *
4092 _curses_resizeterm_impl(PyObject *module, int nlines, int ncols)
4093 /*[clinic end generated code: output=56d6bcc5194ad055 input=0fca02ebad5ffa82]*/
4094 {
4095 PyObject *result;
4096
4097 PyCursesInitialised;
4098
4099 result = PyCursesCheckERR(resizeterm(nlines, ncols), "resizeterm");
4100 if (!result)
4101 return NULL;
4102 if (!update_lines_cols()) {
4103 Py_DECREF(result);
4104 return NULL;
4105 }
4106 return result;
4107 }
4108
4109 #endif
4110
4111 #ifdef HAVE_CURSES_RESIZE_TERM
4112 /*[clinic input]
4113 _curses.resize_term
4114
4115 nlines: int
4116 Height.
4117 ncols: int
4118 Width.
4119 /
4120
4121 Backend function used by resizeterm(), performing most of the work.
4122
4123 When resizing the windows, resize_term() blank-fills the areas that are
4124 extended. The calling application should fill in these areas with appropriate
4125 data. The resize_term() function attempts to resize all windows. However,
4126 due to the calling convention of pads, it is not possible to resize these
4127 without additional interaction with the application.
4128 [clinic start generated code]*/
4129
4130 static PyObject *
_curses_resize_term_impl(PyObject * module,int nlines,int ncols)4131 _curses_resize_term_impl(PyObject *module, int nlines, int ncols)
4132 /*[clinic end generated code: output=9e26d8b9ea311ed2 input=2197edd05b049ed4]*/
4133 {
4134 PyObject *result;
4135
4136 PyCursesInitialised;
4137
4138 result = PyCursesCheckERR(resize_term(nlines, ncols), "resize_term");
4139 if (!result)
4140 return NULL;
4141 if (!update_lines_cols()) {
4142 Py_DECREF(result);
4143 return NULL;
4144 }
4145 return result;
4146 }
4147 #endif /* HAVE_CURSES_RESIZE_TERM */
4148
4149 /*[clinic input]
4150 _curses.savetty
4151
4152 Save terminal mode.
4153 [clinic start generated code]*/
4154
4155 static PyObject *
_curses_savetty_impl(PyObject * module)4156 _curses_savetty_impl(PyObject *module)
4157 /*[clinic end generated code: output=6babc49f12b42199 input=fce6b2b7d2200102]*/
4158 NoArgNoReturnFunctionBody(savetty)
4159
4160 #ifdef getsyx
4161 /*[clinic input]
4162 _curses.setsyx
4163
4164 y: int
4165 Y-coordinate.
4166 x: int
4167 X-coordinate.
4168 /
4169
4170 Set the virtual screen cursor.
4171
4172 If y and x are both -1, then leaveok is set.
4173 [clinic start generated code]*/
4174
4175 static PyObject *
4176 _curses_setsyx_impl(PyObject *module, int y, int x)
4177 /*[clinic end generated code: output=23dcf753511a2464 input=fa7f2b208e10a557]*/
4178 {
4179 PyCursesInitialised;
4180
4181 setsyx(y,x);
4182
4183 Py_RETURN_NONE;
4184 }
4185 #endif
4186
4187 /*[clinic input]
4188 _curses.start_color
4189
4190 Initializes eight basic colors and global variables COLORS and COLOR_PAIRS.
4191
4192 Must be called if the programmer wants to use colors, and before any other
4193 color manipulation routine is called. It is good practice to call this
4194 routine right after initscr().
4195
4196 It also restores the colors on the terminal to the values they had when the
4197 terminal was just turned on.
4198 [clinic start generated code]*/
4199
4200 static PyObject *
_curses_start_color_impl(PyObject * module)4201 _curses_start_color_impl(PyObject *module)
4202 /*[clinic end generated code: output=8b772b41d8090ede input=0ca0ecb2b77e1a12]*/
4203 {
4204 int code;
4205 PyObject *c, *cp;
4206
4207 PyCursesInitialised;
4208
4209 code = start_color();
4210 if (code != ERR) {
4211 initialisedcolors = TRUE;
4212 c = PyLong_FromLong((long) COLORS);
4213 if (c == NULL)
4214 return NULL;
4215 if (PyDict_SetItemString(ModDict, "COLORS", c) < 0) {
4216 Py_DECREF(c);
4217 return NULL;
4218 }
4219 Py_DECREF(c);
4220 cp = PyLong_FromLong((long) COLOR_PAIRS);
4221 if (cp == NULL)
4222 return NULL;
4223 if (PyDict_SetItemString(ModDict, "COLOR_PAIRS", cp) < 0) {
4224 Py_DECREF(cp);
4225 return NULL;
4226 }
4227 Py_DECREF(cp);
4228 Py_RETURN_NONE;
4229 } else {
4230 PyErr_SetString(PyCursesError, "start_color() returned ERR");
4231 return NULL;
4232 }
4233 }
4234
4235 /*[clinic input]
4236 _curses.termattrs
4237
4238 Return a logical OR of all video attributes supported by the terminal.
4239 [clinic start generated code]*/
4240
4241 static PyObject *
_curses_termattrs_impl(PyObject * module)4242 _curses_termattrs_impl(PyObject *module)
4243 /*[clinic end generated code: output=b06f437fce1b6fc4 input=0559882a04f84d1d]*/
4244 NoArgReturnIntFunctionBody(termattrs)
4245
4246 /*[clinic input]
4247 _curses.termname
4248
4249 Return the value of the environment variable TERM, truncated to 14 characters.
4250 [clinic start generated code]*/
4251
4252 static PyObject *
4253 _curses_termname_impl(PyObject *module)
4254 /*[clinic end generated code: output=96375577ebbd67fd input=33c08d000944f33f]*/
4255 NoArgReturnStringFunctionBody(termname)
4256
4257 /*[clinic input]
4258 _curses.tigetflag
4259
4260 capname: str
4261 The terminfo capability name.
4262 /
4263
4264 Return the value of the Boolean capability.
4265
4266 The value -1 is returned if capname is not a Boolean capability, or 0 if
4267 it is canceled or absent from the terminal description.
4268 [clinic start generated code]*/
4269
4270 static PyObject *
4271 _curses_tigetflag_impl(PyObject *module, const char *capname)
4272 /*[clinic end generated code: output=8853c0e55542195b input=b0787af9e3e9a6ce]*/
4273 {
4274 PyCursesSetupTermCalled;
4275
4276 return PyLong_FromLong( (long) tigetflag( (char *)capname ) );
4277 }
4278
4279 /*[clinic input]
4280 _curses.tigetnum
4281
4282 capname: str
4283 The terminfo capability name.
4284 /
4285
4286 Return the value of the numeric capability.
4287
4288 The value -2 is returned if capname is not a numeric capability, or -1 if
4289 it is canceled or absent from the terminal description.
4290 [clinic start generated code]*/
4291
4292 static PyObject *
_curses_tigetnum_impl(PyObject * module,const char * capname)4293 _curses_tigetnum_impl(PyObject *module, const char *capname)
4294 /*[clinic end generated code: output=46f8b0a1b5dff42f input=5cdf2f410b109720]*/
4295 {
4296 PyCursesSetupTermCalled;
4297
4298 return PyLong_FromLong( (long) tigetnum( (char *)capname ) );
4299 }
4300
4301 /*[clinic input]
4302 _curses.tigetstr
4303
4304 capname: str
4305 The terminfo capability name.
4306 /
4307
4308 Return the value of the string capability.
4309
4310 None is returned if capname is not a string capability, or is canceled or
4311 absent from the terminal description.
4312 [clinic start generated code]*/
4313
4314 static PyObject *
_curses_tigetstr_impl(PyObject * module,const char * capname)4315 _curses_tigetstr_impl(PyObject *module, const char *capname)
4316 /*[clinic end generated code: output=f22b576ad60248f3 input=36644df25c73c0a7]*/
4317 {
4318 PyCursesSetupTermCalled;
4319
4320 capname = tigetstr( (char *)capname );
4321 if (capname == NULL || capname == (char*) -1) {
4322 Py_RETURN_NONE;
4323 }
4324 return PyBytes_FromString( capname );
4325 }
4326
4327 /*[clinic input]
4328 _curses.tparm
4329
4330 str: str(accept={robuffer})
4331 Parameterized byte string obtained from the terminfo database.
4332 i1: int = 0
4333 i2: int = 0
4334 i3: int = 0
4335 i4: int = 0
4336 i5: int = 0
4337 i6: int = 0
4338 i7: int = 0
4339 i8: int = 0
4340 i9: int = 0
4341 /
4342
4343 Instantiate the specified byte string with the supplied parameters.
4344 [clinic start generated code]*/
4345
4346 static PyObject *
_curses_tparm_impl(PyObject * module,const char * str,int i1,int i2,int i3,int i4,int i5,int i6,int i7,int i8,int i9)4347 _curses_tparm_impl(PyObject *module, const char *str, int i1, int i2, int i3,
4348 int i4, int i5, int i6, int i7, int i8, int i9)
4349 /*[clinic end generated code: output=599f62b615c667ff input=5e30b15786f032aa]*/
4350 {
4351 char* result = NULL;
4352
4353 PyCursesSetupTermCalled;
4354
4355 result = tparm((char *)str,i1,i2,i3,i4,i5,i6,i7,i8,i9);
4356 if (!result) {
4357 PyErr_SetString(PyCursesError, "tparm() returned NULL");
4358 return NULL;
4359 }
4360
4361 return PyBytes_FromString(result);
4362 }
4363
4364 #ifdef HAVE_CURSES_TYPEAHEAD
4365 /*[clinic input]
4366 _curses.typeahead
4367
4368 fd: int
4369 File descriptor.
4370 /
4371
4372 Specify that the file descriptor fd be used for typeahead checking.
4373
4374 If fd is -1, then no typeahead checking is done.
4375 [clinic start generated code]*/
4376
4377 static PyObject *
_curses_typeahead_impl(PyObject * module,int fd)4378 _curses_typeahead_impl(PyObject *module, int fd)
4379 /*[clinic end generated code: output=084bb649d7066583 input=f2968d8e1805051b]*/
4380 {
4381 PyCursesInitialised;
4382
4383 return PyCursesCheckERR(typeahead( fd ), "typeahead");
4384 }
4385 #endif
4386
4387 /*[clinic input]
4388 _curses.unctrl
4389
4390 ch: object
4391 /
4392
4393 Return a string which is a printable representation of the character ch.
4394
4395 Control characters are displayed as a caret followed by the character,
4396 for example as ^C. Printing characters are left as they are.
4397 [clinic start generated code]*/
4398
4399 static PyObject *
_curses_unctrl(PyObject * module,PyObject * ch)4400 _curses_unctrl(PyObject *module, PyObject *ch)
4401 /*[clinic end generated code: output=8e07fafc430c9434 input=cd1e35e16cd1ace4]*/
4402 {
4403 chtype ch_;
4404
4405 PyCursesInitialised;
4406
4407 if (!PyCurses_ConvertToChtype(NULL, ch, &ch_))
4408 return NULL;
4409
4410 return PyBytes_FromString(unctrl(ch_));
4411 }
4412
4413 /*[clinic input]
4414 _curses.ungetch
4415
4416 ch: object
4417 /
4418
4419 Push ch so the next getch() will return it.
4420 [clinic start generated code]*/
4421
4422 static PyObject *
_curses_ungetch(PyObject * module,PyObject * ch)4423 _curses_ungetch(PyObject *module, PyObject *ch)
4424 /*[clinic end generated code: output=9b19d8268376d887 input=6681e6ae4c42e5eb]*/
4425 {
4426 chtype ch_;
4427
4428 PyCursesInitialised;
4429
4430 if (!PyCurses_ConvertToChtype(NULL, ch, &ch_))
4431 return NULL;
4432
4433 return PyCursesCheckERR(ungetch(ch_), "ungetch");
4434 }
4435
4436 #ifdef HAVE_NCURSESW
4437 /* Convert an object to a character (wchar_t):
4438
4439 - int
4440 - str of length 1
4441
4442 Return 1 on success, 0 on error. */
4443 static int
PyCurses_ConvertToWchar_t(PyObject * obj,wchar_t * wch)4444 PyCurses_ConvertToWchar_t(PyObject *obj,
4445 wchar_t *wch)
4446 {
4447 if (PyUnicode_Check(obj)) {
4448 wchar_t buffer[2];
4449 if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) {
4450 PyErr_Format(PyExc_TypeError,
4451 "expect str of length 1 or int, "
4452 "got a str of length %zi",
4453 PyUnicode_GET_LENGTH(obj));
4454 return 0;
4455 }
4456 *wch = buffer[0];
4457 return 2;
4458 }
4459 else if (PyLong_CheckExact(obj)) {
4460 long value;
4461 int overflow;
4462 value = PyLong_AsLongAndOverflow(obj, &overflow);
4463 if (overflow) {
4464 PyErr_SetString(PyExc_OverflowError,
4465 "int doesn't fit in long");
4466 return 0;
4467 }
4468 *wch = (wchar_t)value;
4469 if ((long)*wch != value) {
4470 PyErr_Format(PyExc_OverflowError,
4471 "character doesn't fit in wchar_t");
4472 return 0;
4473 }
4474 return 1;
4475 }
4476 else {
4477 PyErr_Format(PyExc_TypeError,
4478 "expect str of length 1 or int, got %s",
4479 Py_TYPE(obj)->tp_name);
4480 return 0;
4481 }
4482 }
4483
4484 /*[clinic input]
4485 _curses.unget_wch
4486
4487 ch: object
4488 /
4489
4490 Push ch so the next get_wch() will return it.
4491 [clinic start generated code]*/
4492
4493 static PyObject *
_curses_unget_wch(PyObject * module,PyObject * ch)4494 _curses_unget_wch(PyObject *module, PyObject *ch)
4495 /*[clinic end generated code: output=1974c9fb01d37863 input=0d56dc65a46feebb]*/
4496 {
4497 wchar_t wch;
4498
4499 PyCursesInitialised;
4500
4501 if (!PyCurses_ConvertToWchar_t(ch, &wch))
4502 return NULL;
4503 return PyCursesCheckERR(unget_wch(wch), "unget_wch");
4504 }
4505 #endif
4506
4507 #ifdef HAVE_CURSES_USE_ENV
4508 /*[clinic input]
4509 _curses.use_env
4510
4511 flag: bool(accept={int})
4512 /
4513
4514 Use environment variables LINES and COLUMNS.
4515
4516 If used, this function should be called before initscr() or newterm() are
4517 called.
4518
4519 When flag is False, the values of lines and columns specified in the terminfo
4520 database will be used, even if environment variables LINES and COLUMNS (used
4521 by default) are set, or if curses is running in a window (in which case
4522 default behavior would be to use the window size if LINES and COLUMNS are
4523 not set).
4524 [clinic start generated code]*/
4525
4526 static PyObject *
_curses_use_env_impl(PyObject * module,int flag)4527 _curses_use_env_impl(PyObject *module, int flag)
4528 /*[clinic end generated code: output=b2c445e435c0b164 input=1778eb1e9151ea37]*/
4529 {
4530 use_env(flag);
4531 Py_RETURN_NONE;
4532 }
4533 #endif
4534
4535 #ifndef STRICT_SYSV_CURSES
4536 /*[clinic input]
4537 _curses.use_default_colors
4538
4539 Allow use of default values for colors on terminals supporting this feature.
4540
4541 Use this to support transparency in your application. The default color
4542 is assigned to the color number -1.
4543 [clinic start generated code]*/
4544
4545 static PyObject *
_curses_use_default_colors_impl(PyObject * module)4546 _curses_use_default_colors_impl(PyObject *module)
4547 /*[clinic end generated code: output=a3b81ff71dd901be input=656844367470e8fc]*/
4548 {
4549 int code;
4550
4551 PyCursesInitialised;
4552 PyCursesInitialisedColor;
4553
4554 code = use_default_colors();
4555 if (code != ERR) {
4556 Py_RETURN_NONE;
4557 } else {
4558 PyErr_SetString(PyCursesError, "use_default_colors() returned ERR");
4559 return NULL;
4560 }
4561 }
4562 #endif /* STRICT_SYSV_CURSES */
4563
4564
4565 #ifdef NCURSES_VERSION
4566
4567 PyDoc_STRVAR(ncurses_version__doc__,
4568 "curses.ncurses_version\n\
4569 \n\
4570 Ncurses version information as a named tuple.");
4571
4572 static PyTypeObject NcursesVersionType;
4573
4574 static PyStructSequence_Field ncurses_version_fields[] = {
4575 {"major", "Major release number"},
4576 {"minor", "Minor release number"},
4577 {"patch", "Patch release number"},
4578 {0}
4579 };
4580
4581 static PyStructSequence_Desc ncurses_version_desc = {
4582 "curses.ncurses_version", /* name */
4583 ncurses_version__doc__, /* doc */
4584 ncurses_version_fields, /* fields */
4585 3
4586 };
4587
4588 static PyObject *
make_ncurses_version(void)4589 make_ncurses_version(void)
4590 {
4591 PyObject *ncurses_version;
4592 int pos = 0;
4593
4594 ncurses_version = PyStructSequence_New(&NcursesVersionType);
4595 if (ncurses_version == NULL) {
4596 return NULL;
4597 }
4598
4599 #define SetIntItem(flag) \
4600 PyStructSequence_SET_ITEM(ncurses_version, pos++, PyLong_FromLong(flag)); \
4601 if (PyErr_Occurred()) { \
4602 Py_CLEAR(ncurses_version); \
4603 return NULL; \
4604 }
4605
4606 SetIntItem(NCURSES_VERSION_MAJOR)
4607 SetIntItem(NCURSES_VERSION_MINOR)
4608 SetIntItem(NCURSES_VERSION_PATCH)
4609 #undef SetIntItem
4610
4611 return ncurses_version;
4612 }
4613
4614 #endif /* NCURSES_VERSION */
4615
4616 /*[clinic input]
4617 _curses.has_extended_color_support
4618
4619 Return True if the module supports extended colors; otherwise, return False.
4620
4621 Extended color support allows more than 256 color-pairs for terminals
4622 that support more than 16 colors (e.g. xterm-256color).
4623 [clinic start generated code]*/
4624
4625 static PyObject *
_curses_has_extended_color_support_impl(PyObject * module)4626 _curses_has_extended_color_support_impl(PyObject *module)
4627 /*[clinic end generated code: output=68f1be2b57d92e22 input=4b905f046e35ee9f]*/
4628 {
4629 return PyBool_FromLong(_NCURSES_EXTENDED_COLOR_FUNCS);
4630 }
4631
4632 /* List of functions defined in the module */
4633
4634 static PyMethodDef PyCurses_methods[] = {
4635 _CURSES_BAUDRATE_METHODDEF
4636 _CURSES_BEEP_METHODDEF
4637 _CURSES_CAN_CHANGE_COLOR_METHODDEF
4638 _CURSES_CBREAK_METHODDEF
4639 _CURSES_COLOR_CONTENT_METHODDEF
4640 _CURSES_COLOR_PAIR_METHODDEF
4641 _CURSES_CURS_SET_METHODDEF
4642 _CURSES_DEF_PROG_MODE_METHODDEF
4643 _CURSES_DEF_SHELL_MODE_METHODDEF
4644 _CURSES_DELAY_OUTPUT_METHODDEF
4645 _CURSES_DOUPDATE_METHODDEF
4646 _CURSES_ECHO_METHODDEF
4647 _CURSES_ENDWIN_METHODDEF
4648 _CURSES_ERASECHAR_METHODDEF
4649 _CURSES_FILTER_METHODDEF
4650 _CURSES_FLASH_METHODDEF
4651 _CURSES_FLUSHINP_METHODDEF
4652 _CURSES_GETMOUSE_METHODDEF
4653 _CURSES_UNGETMOUSE_METHODDEF
4654 _CURSES_GETSYX_METHODDEF
4655 _CURSES_GETWIN_METHODDEF
4656 _CURSES_HAS_COLORS_METHODDEF
4657 _CURSES_HAS_EXTENDED_COLOR_SUPPORT_METHODDEF
4658 _CURSES_HAS_IC_METHODDEF
4659 _CURSES_HAS_IL_METHODDEF
4660 _CURSES_HAS_KEY_METHODDEF
4661 _CURSES_HALFDELAY_METHODDEF
4662 _CURSES_INIT_COLOR_METHODDEF
4663 _CURSES_INIT_PAIR_METHODDEF
4664 _CURSES_INITSCR_METHODDEF
4665 _CURSES_INTRFLUSH_METHODDEF
4666 _CURSES_ISENDWIN_METHODDEF
4667 _CURSES_IS_TERM_RESIZED_METHODDEF
4668 _CURSES_KEYNAME_METHODDEF
4669 _CURSES_KILLCHAR_METHODDEF
4670 _CURSES_LONGNAME_METHODDEF
4671 _CURSES_META_METHODDEF
4672 _CURSES_MOUSEINTERVAL_METHODDEF
4673 _CURSES_MOUSEMASK_METHODDEF
4674 _CURSES_NAPMS_METHODDEF
4675 _CURSES_NEWPAD_METHODDEF
4676 _CURSES_NEWWIN_METHODDEF
4677 _CURSES_NL_METHODDEF
4678 _CURSES_NOCBREAK_METHODDEF
4679 _CURSES_NOECHO_METHODDEF
4680 _CURSES_NONL_METHODDEF
4681 _CURSES_NOQIFLUSH_METHODDEF
4682 _CURSES_NORAW_METHODDEF
4683 _CURSES_PAIR_CONTENT_METHODDEF
4684 _CURSES_PAIR_NUMBER_METHODDEF
4685 _CURSES_PUTP_METHODDEF
4686 _CURSES_QIFLUSH_METHODDEF
4687 _CURSES_RAW_METHODDEF
4688 _CURSES_RESET_PROG_MODE_METHODDEF
4689 _CURSES_RESET_SHELL_MODE_METHODDEF
4690 _CURSES_RESETTY_METHODDEF
4691 _CURSES_RESIZETERM_METHODDEF
4692 _CURSES_RESIZE_TERM_METHODDEF
4693 _CURSES_SAVETTY_METHODDEF
4694 #if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20081102
4695 _CURSES_GET_ESCDELAY_METHODDEF
4696 _CURSES_SET_ESCDELAY_METHODDEF
4697 #endif
4698 _CURSES_GET_TABSIZE_METHODDEF
4699 _CURSES_SET_TABSIZE_METHODDEF
4700 _CURSES_SETSYX_METHODDEF
4701 _CURSES_SETUPTERM_METHODDEF
4702 _CURSES_START_COLOR_METHODDEF
4703 _CURSES_TERMATTRS_METHODDEF
4704 _CURSES_TERMNAME_METHODDEF
4705 _CURSES_TIGETFLAG_METHODDEF
4706 _CURSES_TIGETNUM_METHODDEF
4707 _CURSES_TIGETSTR_METHODDEF
4708 _CURSES_TPARM_METHODDEF
4709 _CURSES_TYPEAHEAD_METHODDEF
4710 _CURSES_UNCTRL_METHODDEF
4711 _CURSES_UNGETCH_METHODDEF
4712 _CURSES_UPDATE_LINES_COLS_METHODDEF
4713 _CURSES_UNGET_WCH_METHODDEF
4714 _CURSES_USE_ENV_METHODDEF
4715 _CURSES_USE_DEFAULT_COLORS_METHODDEF
4716 {NULL, NULL} /* sentinel */
4717 };
4718
4719 /* Initialization function for the module */
4720
4721
4722 static struct PyModuleDef _cursesmodule = {
4723 PyModuleDef_HEAD_INIT,
4724 "_curses",
4725 NULL,
4726 -1,
4727 PyCurses_methods,
4728 NULL,
4729 NULL,
4730 NULL,
4731 NULL
4732 };
4733
4734 static void
curses_destructor(PyObject * op)4735 curses_destructor(PyObject *op)
4736 {
4737 void *ptr = PyCapsule_GetPointer(op, PyCurses_CAPSULE_NAME);
4738 Py_DECREF(*(void **)ptr);
4739 PyMem_Free(ptr);
4740 }
4741
4742 PyMODINIT_FUNC
PyInit__curses(void)4743 PyInit__curses(void)
4744 {
4745 PyObject *m, *d, *v, *c_api_object;
4746
4747 /* Initialize object type */
4748 if (PyType_Ready(&PyCursesWindow_Type) < 0)
4749 return NULL;
4750
4751 /* Create the module and add the functions */
4752 m = PyModule_Create(&_cursesmodule);
4753 if (m == NULL)
4754 return NULL;
4755
4756 /* Add some symbolic constants to the module */
4757 d = PyModule_GetDict(m);
4758 if (d == NULL)
4759 return NULL;
4760 ModDict = d; /* For PyCurses_InitScr to use later */
4761
4762 void **PyCurses_API = PyMem_Calloc(PyCurses_API_pointers, sizeof(void *));
4763 if (PyCurses_API == NULL) {
4764 PyErr_NoMemory();
4765 return NULL;
4766 }
4767 /* Initialize the C API pointer array */
4768 PyCurses_API[0] = (void *)Py_NewRef(&PyCursesWindow_Type);
4769 PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled;
4770 PyCurses_API[2] = (void *)func_PyCursesInitialised;
4771 PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
4772
4773 /* Add a capsule for the C API */
4774 c_api_object = PyCapsule_New(PyCurses_API, PyCurses_CAPSULE_NAME,
4775 curses_destructor);
4776 if (c_api_object == NULL) {
4777 Py_DECREF(PyCurses_API[0]);
4778 PyMem_Free(PyCurses_API);
4779 return NULL;
4780 }
4781 if (PyDict_SetItemString(d, "_C_API", c_api_object) < 0) {
4782 Py_DECREF(c_api_object);
4783 return NULL;
4784 }
4785 Py_DECREF(c_api_object);
4786
4787 /* For exception curses.error */
4788 PyCursesError = PyErr_NewException("_curses.error", NULL, NULL);
4789 PyDict_SetItemString(d, "error", PyCursesError);
4790
4791 /* Make the version available */
4792 v = PyBytes_FromString(PyCursesVersion);
4793 PyDict_SetItemString(d, "version", v);
4794 PyDict_SetItemString(d, "__version__", v);
4795 Py_DECREF(v);
4796
4797 #ifdef NCURSES_VERSION
4798 /* ncurses_version */
4799 if (NcursesVersionType.tp_name == NULL) {
4800 if (_PyStructSequence_InitType(&NcursesVersionType,
4801 &ncurses_version_desc,
4802 Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
4803 return NULL;
4804 }
4805 }
4806 v = make_ncurses_version();
4807 if (v == NULL) {
4808 return NULL;
4809 }
4810 PyDict_SetItemString(d, "ncurses_version", v);
4811 Py_DECREF(v);
4812 #endif /* NCURSES_VERSION */
4813
4814 SetDictInt("ERR", ERR);
4815 SetDictInt("OK", OK);
4816
4817 /* Here are some attributes you can add to chars to print */
4818
4819 SetDictInt("A_ATTRIBUTES", A_ATTRIBUTES);
4820 SetDictInt("A_NORMAL", A_NORMAL);
4821 SetDictInt("A_STANDOUT", A_STANDOUT);
4822 SetDictInt("A_UNDERLINE", A_UNDERLINE);
4823 SetDictInt("A_REVERSE", A_REVERSE);
4824 SetDictInt("A_BLINK", A_BLINK);
4825 SetDictInt("A_DIM", A_DIM);
4826 SetDictInt("A_BOLD", A_BOLD);
4827 SetDictInt("A_ALTCHARSET", A_ALTCHARSET);
4828 SetDictInt("A_INVIS", A_INVIS);
4829 SetDictInt("A_PROTECT", A_PROTECT);
4830 SetDictInt("A_CHARTEXT", A_CHARTEXT);
4831 SetDictInt("A_COLOR", A_COLOR);
4832
4833 /* The following are never available with strict SYSV curses */
4834 #ifdef A_HORIZONTAL
4835 SetDictInt("A_HORIZONTAL", A_HORIZONTAL);
4836 #endif
4837 #ifdef A_LEFT
4838 SetDictInt("A_LEFT", A_LEFT);
4839 #endif
4840 #ifdef A_LOW
4841 SetDictInt("A_LOW", A_LOW);
4842 #endif
4843 #ifdef A_RIGHT
4844 SetDictInt("A_RIGHT", A_RIGHT);
4845 #endif
4846 #ifdef A_TOP
4847 SetDictInt("A_TOP", A_TOP);
4848 #endif
4849 #ifdef A_VERTICAL
4850 SetDictInt("A_VERTICAL", A_VERTICAL);
4851 #endif
4852
4853 /* ncurses extension */
4854 #ifdef A_ITALIC
4855 SetDictInt("A_ITALIC", A_ITALIC);
4856 #endif
4857
4858 SetDictInt("COLOR_BLACK", COLOR_BLACK);
4859 SetDictInt("COLOR_RED", COLOR_RED);
4860 SetDictInt("COLOR_GREEN", COLOR_GREEN);
4861 SetDictInt("COLOR_YELLOW", COLOR_YELLOW);
4862 SetDictInt("COLOR_BLUE", COLOR_BLUE);
4863 SetDictInt("COLOR_MAGENTA", COLOR_MAGENTA);
4864 SetDictInt("COLOR_CYAN", COLOR_CYAN);
4865 SetDictInt("COLOR_WHITE", COLOR_WHITE);
4866
4867 #ifdef NCURSES_MOUSE_VERSION
4868 /* Mouse-related constants */
4869 SetDictInt("BUTTON1_PRESSED", BUTTON1_PRESSED);
4870 SetDictInt("BUTTON1_RELEASED", BUTTON1_RELEASED);
4871 SetDictInt("BUTTON1_CLICKED", BUTTON1_CLICKED);
4872 SetDictInt("BUTTON1_DOUBLE_CLICKED", BUTTON1_DOUBLE_CLICKED);
4873 SetDictInt("BUTTON1_TRIPLE_CLICKED", BUTTON1_TRIPLE_CLICKED);
4874
4875 SetDictInt("BUTTON2_PRESSED", BUTTON2_PRESSED);
4876 SetDictInt("BUTTON2_RELEASED", BUTTON2_RELEASED);
4877 SetDictInt("BUTTON2_CLICKED", BUTTON2_CLICKED);
4878 SetDictInt("BUTTON2_DOUBLE_CLICKED", BUTTON2_DOUBLE_CLICKED);
4879 SetDictInt("BUTTON2_TRIPLE_CLICKED", BUTTON2_TRIPLE_CLICKED);
4880
4881 SetDictInt("BUTTON3_PRESSED", BUTTON3_PRESSED);
4882 SetDictInt("BUTTON3_RELEASED", BUTTON3_RELEASED);
4883 SetDictInt("BUTTON3_CLICKED", BUTTON3_CLICKED);
4884 SetDictInt("BUTTON3_DOUBLE_CLICKED", BUTTON3_DOUBLE_CLICKED);
4885 SetDictInt("BUTTON3_TRIPLE_CLICKED", BUTTON3_TRIPLE_CLICKED);
4886
4887 SetDictInt("BUTTON4_PRESSED", BUTTON4_PRESSED);
4888 SetDictInt("BUTTON4_RELEASED", BUTTON4_RELEASED);
4889 SetDictInt("BUTTON4_CLICKED", BUTTON4_CLICKED);
4890 SetDictInt("BUTTON4_DOUBLE_CLICKED", BUTTON4_DOUBLE_CLICKED);
4891 SetDictInt("BUTTON4_TRIPLE_CLICKED", BUTTON4_TRIPLE_CLICKED);
4892
4893 #if NCURSES_MOUSE_VERSION > 1
4894 SetDictInt("BUTTON5_PRESSED", BUTTON5_PRESSED);
4895 SetDictInt("BUTTON5_RELEASED", BUTTON5_RELEASED);
4896 SetDictInt("BUTTON5_CLICKED", BUTTON5_CLICKED);
4897 SetDictInt("BUTTON5_DOUBLE_CLICKED", BUTTON5_DOUBLE_CLICKED);
4898 SetDictInt("BUTTON5_TRIPLE_CLICKED", BUTTON5_TRIPLE_CLICKED);
4899 #endif
4900
4901 SetDictInt("BUTTON_SHIFT", BUTTON_SHIFT);
4902 SetDictInt("BUTTON_CTRL", BUTTON_CTRL);
4903 SetDictInt("BUTTON_ALT", BUTTON_ALT);
4904
4905 SetDictInt("ALL_MOUSE_EVENTS", ALL_MOUSE_EVENTS);
4906 SetDictInt("REPORT_MOUSE_POSITION", REPORT_MOUSE_POSITION);
4907 #endif
4908 /* Now set everything up for KEY_ variables */
4909 {
4910 int key;
4911 char *key_n;
4912 char *key_n2;
4913 for (key=KEY_MIN;key < KEY_MAX; key++) {
4914 key_n = (char *)keyname(key);
4915 if (key_n == NULL || strcmp(key_n,"UNKNOWN KEY")==0)
4916 continue;
4917 if (strncmp(key_n,"KEY_F(",6)==0) {
4918 char *p1, *p2;
4919 key_n2 = PyMem_Malloc(strlen(key_n)+1);
4920 if (!key_n2) {
4921 PyErr_NoMemory();
4922 break;
4923 }
4924 p1 = key_n;
4925 p2 = key_n2;
4926 while (*p1) {
4927 if (*p1 != '(' && *p1 != ')') {
4928 *p2 = *p1;
4929 p2++;
4930 }
4931 p1++;
4932 }
4933 *p2 = (char)0;
4934 } else
4935 key_n2 = key_n;
4936 SetDictInt(key_n2,key);
4937 if (key_n2 != key_n)
4938 PyMem_Free(key_n2);
4939 }
4940 SetDictInt("KEY_MIN", KEY_MIN);
4941 SetDictInt("KEY_MAX", KEY_MAX);
4942 }
4943
4944 if (PyModule_AddType(m, &PyCursesWindow_Type) < 0) {
4945 return NULL;
4946 }
4947 return m;
4948 }
4949