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