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