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