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 static inline int
color_pair_to_attr(short color_number)180 color_pair_to_attr(short color_number)
181 {
182 return ((int)color_number << 8);
183 }
184
185 static inline short
attr_to_color_pair(int attr)186 attr_to_color_pair(int attr)
187 {
188 return (short)((attr & A_COLOR) >> 8);
189 }
190
191 /*
192 * Check the return code from a curses function and return None
193 * or raise an exception as appropriate. These are exported using the
194 * capsule API.
195 */
196
197 static PyObject *
PyCursesCheckERR(int code,const char * fname)198 PyCursesCheckERR(int code, const char *fname)
199 {
200 if (code != ERR) {
201 Py_RETURN_NONE;
202 } else {
203 if (fname == NULL) {
204 PyErr_SetString(PyCursesError, catchall_ERR);
205 } else {
206 PyErr_Format(PyCursesError, "%s() returned ERR", fname);
207 }
208 return NULL;
209 }
210 }
211
212 /* Convert an object to a byte (an integer of type chtype):
213
214 - int
215 - bytes of length 1
216 - str of length 1
217
218 Return 1 on success, 0 on error (invalid type or integer overflow). */
219 static int
PyCurses_ConvertToChtype(PyCursesWindowObject * win,PyObject * obj,chtype * ch)220 PyCurses_ConvertToChtype(PyCursesWindowObject *win, PyObject *obj, chtype *ch)
221 {
222 long value;
223 if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) {
224 value = (unsigned char)PyBytes_AsString(obj)[0];
225 }
226 else if (PyUnicode_Check(obj)) {
227 if (PyUnicode_GetLength(obj) != 1) {
228 PyErr_Format(PyExc_TypeError,
229 "expect bytes or str of length 1, or int, "
230 "got a str of length %zi",
231 PyUnicode_GET_LENGTH(obj));
232 return 0;
233 }
234 value = PyUnicode_READ_CHAR(obj, 0);
235 if (128 < value) {
236 PyObject *bytes;
237 const char *encoding;
238 if (win)
239 encoding = win->encoding;
240 else
241 encoding = screen_encoding;
242 bytes = PyUnicode_AsEncodedString(obj, encoding, NULL);
243 if (bytes == NULL)
244 return 0;
245 if (PyBytes_GET_SIZE(bytes) == 1)
246 value = (unsigned char)PyBytes_AS_STRING(bytes)[0];
247 else
248 value = -1;
249 Py_DECREF(bytes);
250 if (value < 0)
251 goto overflow;
252 }
253 }
254 else if (PyLong_CheckExact(obj)) {
255 int long_overflow;
256 value = PyLong_AsLongAndOverflow(obj, &long_overflow);
257 if (long_overflow)
258 goto overflow;
259 }
260 else {
261 PyErr_Format(PyExc_TypeError,
262 "expect bytes or str of length 1, or int, got %s",
263 Py_TYPE(obj)->tp_name);
264 return 0;
265 }
266 *ch = (chtype)value;
267 if ((long)*ch != value)
268 goto overflow;
269 return 1;
270
271 overflow:
272 PyErr_SetString(PyExc_OverflowError,
273 "byte doesn't fit in chtype");
274 return 0;
275 }
276
277 /* Convert an object to a byte (chtype) or a character (cchar_t):
278
279 - int
280 - bytes of length 1
281 - str of length 1
282
283 Return:
284
285 - 2 if obj is a character (written into *wch)
286 - 1 if obj is a byte (written into *ch)
287 - 0 on error: raise an exception */
288 static int
PyCurses_ConvertToCchar_t(PyCursesWindowObject * win,PyObject * obj,chtype * ch,wchar_t * wch)289 PyCurses_ConvertToCchar_t(PyCursesWindowObject *win, PyObject *obj,
290 chtype *ch
291 #ifdef HAVE_NCURSESW
292 , wchar_t *wch
293 #endif
294 )
295 {
296 long value;
297 #ifdef HAVE_NCURSESW
298 wchar_t buffer[2];
299 #endif
300
301 if (PyUnicode_Check(obj)) {
302 #ifdef HAVE_NCURSESW
303 if (PyUnicode_AsWideChar(obj, buffer, 2) != 1) {
304 PyErr_Format(PyExc_TypeError,
305 "expect bytes or str of length 1, or int, "
306 "got a str of length %zi",
307 PyUnicode_GET_LENGTH(obj));
308 return 0;
309 }
310 *wch = buffer[0];
311 return 2;
312 #else
313 return PyCurses_ConvertToChtype(win, obj, ch);
314 #endif
315 }
316 else if(PyBytes_Check(obj) && PyBytes_Size(obj) == 1) {
317 value = (unsigned char)PyBytes_AsString(obj)[0];
318 }
319 else if (PyLong_CheckExact(obj)) {
320 int overflow;
321 value = PyLong_AsLongAndOverflow(obj, &overflow);
322 if (overflow) {
323 PyErr_SetString(PyExc_OverflowError,
324 "int doesn't fit in long");
325 return 0;
326 }
327 }
328 else {
329 PyErr_Format(PyExc_TypeError,
330 "expect bytes or str of length 1, or int, got %s",
331 Py_TYPE(obj)->tp_name);
332 return 0;
333 }
334
335 *ch = (chtype)value;
336 if ((long)*ch != value) {
337 PyErr_Format(PyExc_OverflowError,
338 "byte doesn't fit in chtype");
339 return 0;
340 }
341 return 1;
342 }
343
344 /* Convert an object to a byte string (char*) or a wide character string
345 (wchar_t*). Return:
346
347 - 2 if obj is a character string (written into *wch)
348 - 1 if obj is a byte string (written into *bytes)
349 - 0 on error: raise an exception */
350 static int
PyCurses_ConvertToString(PyCursesWindowObject * win,PyObject * obj,PyObject ** bytes,wchar_t ** wstr)351 PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj,
352 PyObject **bytes, wchar_t **wstr)
353 {
354 char *str;
355 if (PyUnicode_Check(obj)) {
356 #ifdef HAVE_NCURSESW
357 assert (wstr != NULL);
358
359 *wstr = PyUnicode_AsWideCharString(obj, NULL);
360 if (*wstr == NULL)
361 return 0;
362 return 2;
363 #else
364 assert (wstr == NULL);
365 *bytes = PyUnicode_AsEncodedString(obj, win->encoding, NULL);
366 if (*bytes == NULL)
367 return 0;
368 /* check for embedded null bytes */
369 if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) {
370 return 0;
371 }
372 return 1;
373 #endif
374 }
375 else if (PyBytes_Check(obj)) {
376 Py_INCREF(obj);
377 *bytes = obj;
378 /* check for embedded null bytes */
379 if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) {
380 return 0;
381 }
382 return 1;
383 }
384
385 PyErr_Format(PyExc_TypeError, "expect bytes or str, got %s",
386 Py_TYPE(obj)->tp_name);
387 return 0;
388 }
389
390 /* Function versions of the 3 functions for testing whether curses has been
391 initialised or not. */
392
func_PyCursesSetupTermCalled(void)393 static int func_PyCursesSetupTermCalled(void)
394 {
395 PyCursesSetupTermCalled;
396 return 1;
397 }
398
func_PyCursesInitialised(void)399 static int func_PyCursesInitialised(void)
400 {
401 PyCursesInitialised;
402 return 1;
403 }
404
func_PyCursesInitialisedColor(void)405 static int func_PyCursesInitialisedColor(void)
406 {
407 PyCursesInitialisedColor;
408 return 1;
409 }
410
411 /*****************************************************************************
412 The Window Object
413 ******************************************************************************/
414
415 /* Definition of the window type */
416
417 PyTypeObject PyCursesWindow_Type;
418
419 /* Function prototype macros for Window object
420
421 X - function name
422 TYPE - parameter Type
423 ERGSTR - format string for construction of the return value
424 PARSESTR - format string for argument parsing
425 */
426
427 #define Window_NoArgNoReturnFunction(X) \
428 static PyObject *PyCursesWindow_ ## X \
429 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \
430 { return PyCursesCheckERR(X(self->win), # X); }
431
432 #define Window_NoArgTrueFalseFunction(X) \
433 static PyObject * PyCursesWindow_ ## X \
434 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \
435 { \
436 return PyBool_FromLong(X(self->win)); }
437
438 #define Window_NoArgNoReturnVoidFunction(X) \
439 static PyObject * PyCursesWindow_ ## X \
440 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \
441 { \
442 X(self->win); Py_RETURN_NONE; }
443
444 #define Window_NoArg2TupleReturnFunction(X, TYPE, ERGSTR) \
445 static PyObject * PyCursesWindow_ ## X \
446 (PyCursesWindowObject *self, PyObject *Py_UNUSED(ignored)) \
447 { \
448 TYPE arg1, arg2; \
449 X(self->win,arg1,arg2); return Py_BuildValue(ERGSTR, arg1, arg2); }
450
451 #define Window_OneArgNoReturnVoidFunction(X, TYPE, PARSESTR) \
452 static PyObject * PyCursesWindow_ ## X \
453 (PyCursesWindowObject *self, PyObject *args) \
454 { \
455 TYPE arg1; \
456 if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) return NULL; \
457 X(self->win,arg1); Py_RETURN_NONE; }
458
459 #define Window_OneArgNoReturnFunction(X, TYPE, PARSESTR) \
460 static PyObject * PyCursesWindow_ ## X \
461 (PyCursesWindowObject *self, PyObject *args) \
462 { \
463 TYPE arg1; \
464 if (!PyArg_ParseTuple(args,PARSESTR, &arg1)) return NULL; \
465 return PyCursesCheckERR(X(self->win, arg1), # X); }
466
467 #define Window_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \
468 static PyObject * PyCursesWindow_ ## X \
469 (PyCursesWindowObject *self, PyObject *args) \
470 { \
471 TYPE arg1, arg2; \
472 if (!PyArg_ParseTuple(args,PARSESTR, &arg1, &arg2)) return NULL; \
473 return PyCursesCheckERR(X(self->win, arg1, arg2), # X); }
474
475 /* ------------- WINDOW routines --------------- */
476
477 Window_NoArgNoReturnFunction(untouchwin)
Window_NoArgNoReturnFunction(touchwin)478 Window_NoArgNoReturnFunction(touchwin)
479 Window_NoArgNoReturnFunction(redrawwin)
480 Window_NoArgNoReturnFunction(winsertln)
481 Window_NoArgNoReturnFunction(werase)
482 Window_NoArgNoReturnFunction(wdeleteln)
483
484 Window_NoArgTrueFalseFunction(is_wintouched)
485
486 Window_NoArgNoReturnVoidFunction(wsyncup)
487 Window_NoArgNoReturnVoidFunction(wsyncdown)
488 Window_NoArgNoReturnVoidFunction(wstandend)
489 Window_NoArgNoReturnVoidFunction(wstandout)
490 Window_NoArgNoReturnVoidFunction(wcursyncup)
491 Window_NoArgNoReturnVoidFunction(wclrtoeol)
492 Window_NoArgNoReturnVoidFunction(wclrtobot)
493 Window_NoArgNoReturnVoidFunction(wclear)
494
495 Window_OneArgNoReturnVoidFunction(idcok, int, "i;True(1) or False(0)")
496 #ifdef HAVE_CURSES_IMMEDOK
497 Window_OneArgNoReturnVoidFunction(immedok, int, "i;True(1) or False(0)")
498 #endif
499 Window_OneArgNoReturnVoidFunction(wtimeout, int, "i;delay")
500
501 Window_NoArg2TupleReturnFunction(getyx, int, "ii")
502 Window_NoArg2TupleReturnFunction(getbegyx, int, "ii")
503 Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii")
504 Window_NoArg2TupleReturnFunction(getparyx, int, "ii")
505
506 Window_OneArgNoReturnFunction(clearok, int, "i;True(1) or False(0)")
507 Window_OneArgNoReturnFunction(idlok, int, "i;True(1) or False(0)")
508 Window_OneArgNoReturnFunction(keypad, int, "i;True(1) or False(0)")
509 Window_OneArgNoReturnFunction(leaveok, int, "i;True(1) or False(0)")
510 Window_OneArgNoReturnFunction(nodelay, int, "i;True(1) or False(0)")
511 Window_OneArgNoReturnFunction(notimeout, int, "i;True(1) or False(0)")
512 Window_OneArgNoReturnFunction(scrollok, int, "i;True(1) or False(0)")
513 Window_OneArgNoReturnFunction(winsdelln, int, "i;nlines")
514 #ifdef HAVE_CURSES_SYNCOK
515 Window_OneArgNoReturnFunction(syncok, int, "i;True(1) or False(0)")
516 #endif
517
518 Window_TwoArgNoReturnFunction(mvwin, int, "ii;y,x")
519 Window_TwoArgNoReturnFunction(mvderwin, int, "ii;y,x")
520 Window_TwoArgNoReturnFunction(wmove, int, "ii;y,x")
521 #ifndef STRICT_SYSV_CURSES
522 Window_TwoArgNoReturnFunction(wresize, int, "ii;lines,columns")
523 #endif
524
525 /* Allocation and deallocation of Window Objects */
526
527 static PyObject *
528 PyCursesWindow_New(WINDOW *win, const char *encoding)
529 {
530 PyCursesWindowObject *wo;
531
532 if (encoding == NULL) {
533 #if defined(MS_WINDOWS)
534 char *buffer[100];
535 UINT cp;
536 cp = GetConsoleOutputCP();
537 if (cp != 0) {
538 PyOS_snprintf(buffer, sizeof(buffer), "cp%u", cp);
539 encoding = buffer;
540 }
541 #elif defined(CODESET)
542 const char *codeset = nl_langinfo(CODESET);
543 if (codeset != NULL && codeset[0] != 0)
544 encoding = codeset;
545 #endif
546 if (encoding == NULL)
547 encoding = "utf-8";
548 }
549
550 wo = PyObject_New(PyCursesWindowObject, &PyCursesWindow_Type);
551 if (wo == NULL) return NULL;
552 wo->win = win;
553 wo->encoding = _PyMem_Strdup(encoding);
554 if (wo->encoding == NULL) {
555 Py_DECREF(wo);
556 PyErr_NoMemory();
557 return NULL;
558 }
559 return (PyObject *)wo;
560 }
561
562 static void
PyCursesWindow_Dealloc(PyCursesWindowObject * wo)563 PyCursesWindow_Dealloc(PyCursesWindowObject *wo)
564 {
565 if (wo->win != stdscr) delwin(wo->win);
566 if (wo->encoding != NULL)
567 PyMem_Free(wo->encoding);
568 PyObject_DEL(wo);
569 }
570
571 /* Addch, Addstr, Addnstr */
572
573 /*[clinic input]
574 _curses.window.addch
575
576 [
577 y: int
578 Y-coordinate.
579 x: int
580 X-coordinate.
581 ]
582
583 ch: object
584 Character to add.
585
586 [
587 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
588 Attributes for the character.
589 ]
590 /
591
592 Paint the character.
593
594 Paint character ch at (y, x) with attributes attr,
595 overwriting any character previously painted at that location.
596 By default, the character position and attributes are the
597 current settings for the window object.
598 [clinic start generated code]*/
599
600 static PyObject *
_curses_window_addch_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * ch,int group_right_1,long attr)601 _curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1,
602 int y, int x, PyObject *ch, int group_right_1,
603 long attr)
604 /*[clinic end generated code: output=00f4c37af3378f45 input=95ce131578458196]*/
605 {
606 int coordinates_group = group_left_1;
607 int rtn;
608 int type;
609 chtype cch = 0;
610 #ifdef HAVE_NCURSESW
611 wchar_t wstr[2];
612 cchar_t wcval;
613 #endif
614 const char *funcname;
615
616 #ifdef HAVE_NCURSESW
617 type = PyCurses_ConvertToCchar_t(self, ch, &cch, wstr);
618 if (type == 2) {
619 funcname = "add_wch";
620 wstr[1] = L'\0';
621 setcchar(&wcval, wstr, attr, attr_to_color_pair(attr), NULL);
622 if (coordinates_group)
623 rtn = mvwadd_wch(self->win,y,x, &wcval);
624 else {
625 rtn = wadd_wch(self->win, &wcval);
626 }
627 }
628 else
629 #else
630 type = PyCurses_ConvertToCchar_t(self, ch, &cch);
631 #endif
632 if (type == 1) {
633 funcname = "addch";
634 if (coordinates_group)
635 rtn = mvwaddch(self->win,y,x, cch | (attr_t) attr);
636 else {
637 rtn = waddch(self->win, cch | (attr_t) attr);
638 }
639 }
640 else {
641 return NULL;
642 }
643 return PyCursesCheckERR(rtn, funcname);
644 }
645
646 /*[clinic input]
647 _curses.window.addstr
648
649 [
650 y: int
651 Y-coordinate.
652 x: int
653 X-coordinate.
654 ]
655
656 str: object
657 String to add.
658
659 [
660 attr: long
661 Attributes for characters.
662 ]
663 /
664
665 Paint the string.
666
667 Paint the string str at (y, x) with attributes attr,
668 overwriting anything previously on the display.
669 By default, the character position and attributes are the
670 current settings for the window object.
671 [clinic start generated code]*/
672
673 static PyObject *
_curses_window_addstr_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * str,int group_right_1,long attr)674 _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1,
675 int y, int x, PyObject *str, int group_right_1,
676 long attr)
677 /*[clinic end generated code: output=65a928ea85ff3115 input=ff6cbb91448a22a3]*/
678 {
679 int rtn;
680 int strtype;
681 PyObject *bytesobj = NULL;
682 #ifdef HAVE_NCURSESW
683 wchar_t *wstr = NULL;
684 #endif
685 attr_t attr_old = A_NORMAL;
686 int use_xy = group_left_1, use_attr = group_right_1;
687 const char *funcname;
688
689 #ifdef HAVE_NCURSESW
690 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr);
691 #else
692 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL);
693 #endif
694 if (strtype == 0)
695 return NULL;
696 if (use_attr) {
697 attr_old = getattrs(self->win);
698 (void)wattrset(self->win,attr);
699 }
700 #ifdef HAVE_NCURSESW
701 if (strtype == 2) {
702 funcname = "addwstr";
703 if (use_xy)
704 rtn = mvwaddwstr(self->win,y,x,wstr);
705 else
706 rtn = waddwstr(self->win,wstr);
707 PyMem_Free(wstr);
708 }
709 else
710 #endif
711 {
712 const char *str = PyBytes_AS_STRING(bytesobj);
713 funcname = "addstr";
714 if (use_xy)
715 rtn = mvwaddstr(self->win,y,x,str);
716 else
717 rtn = waddstr(self->win,str);
718 Py_DECREF(bytesobj);
719 }
720 if (use_attr)
721 (void)wattrset(self->win,attr_old);
722 return PyCursesCheckERR(rtn, funcname);
723 }
724
725 /*[clinic input]
726 _curses.window.addnstr
727
728 [
729 y: int
730 Y-coordinate.
731 x: int
732 X-coordinate.
733 ]
734
735 str: object
736 String to add.
737
738 n: int
739 Maximal number of characters.
740
741 [
742 attr: long
743 Attributes for characters.
744 ]
745 /
746
747 Paint at most n characters of the string.
748
749 Paint at most n characters of the string str at (y, x) with
750 attributes attr, overwriting anything previously on the display.
751 By default, the character position and attributes are the
752 current settings for the window object.
753 [clinic start generated code]*/
754
755 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)756 _curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1,
757 int y, int x, PyObject *str, int n,
758 int group_right_1, long attr)
759 /*[clinic end generated code: output=6d21cee2ce6876d9 input=72718415c2744a2a]*/
760 {
761 int rtn;
762 int strtype;
763 PyObject *bytesobj = NULL;
764 #ifdef HAVE_NCURSESW
765 wchar_t *wstr = NULL;
766 #endif
767 attr_t attr_old = A_NORMAL;
768 int use_xy = group_left_1, use_attr = group_right_1;
769 const char *funcname;
770
771 #ifdef HAVE_NCURSESW
772 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr);
773 #else
774 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL);
775 #endif
776 if (strtype == 0)
777 return NULL;
778
779 if (use_attr) {
780 attr_old = getattrs(self->win);
781 (void)wattrset(self->win,attr);
782 }
783 #ifdef HAVE_NCURSESW
784 if (strtype == 2) {
785 funcname = "addnwstr";
786 if (use_xy)
787 rtn = mvwaddnwstr(self->win,y,x,wstr,n);
788 else
789 rtn = waddnwstr(self->win,wstr,n);
790 PyMem_Free(wstr);
791 }
792 else
793 #endif
794 {
795 const char *str = PyBytes_AS_STRING(bytesobj);
796 funcname = "addnstr";
797 if (use_xy)
798 rtn = mvwaddnstr(self->win,y,x,str,n);
799 else
800 rtn = waddnstr(self->win,str,n);
801 Py_DECREF(bytesobj);
802 }
803 if (use_attr)
804 (void)wattrset(self->win,attr_old);
805 return PyCursesCheckERR(rtn, funcname);
806 }
807
808 /*[clinic input]
809 _curses.window.bkgd
810
811 ch: object
812 Background character.
813 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
814 Background attributes.
815 /
816
817 Set the background property of the window.
818 [clinic start generated code]*/
819
820 static PyObject *
_curses_window_bkgd_impl(PyCursesWindowObject * self,PyObject * ch,long attr)821 _curses_window_bkgd_impl(PyCursesWindowObject *self, PyObject *ch, long attr)
822 /*[clinic end generated code: output=058290afb2cf4034 input=634015bcb339283d]*/
823 {
824 chtype bkgd;
825
826 if (!PyCurses_ConvertToChtype(self, ch, &bkgd))
827 return NULL;
828
829 return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd");
830 }
831
832 /*[clinic input]
833 _curses.window.attroff
834
835 attr: long
836 /
837
838 Remove attribute attr from the "background" set.
839 [clinic start generated code]*/
840
841 static PyObject *
_curses_window_attroff_impl(PyCursesWindowObject * self,long attr)842 _curses_window_attroff_impl(PyCursesWindowObject *self, long attr)
843 /*[clinic end generated code: output=8a2fcd4df682fc64 input=786beedf06a7befe]*/
844 {
845 return PyCursesCheckERR(wattroff(self->win, (attr_t)attr), "attroff");
846 }
847
848 /*[clinic input]
849 _curses.window.attron
850
851 attr: long
852 /
853
854 Add attribute attr from the "background" set.
855 [clinic start generated code]*/
856
857 static PyObject *
_curses_window_attron_impl(PyCursesWindowObject * self,long attr)858 _curses_window_attron_impl(PyCursesWindowObject *self, long attr)
859 /*[clinic end generated code: output=7afea43b237fa870 input=5a88fba7b1524f32]*/
860 {
861 return PyCursesCheckERR(wattron(self->win, (attr_t)attr), "attron");
862 }
863
864 /*[clinic input]
865 _curses.window.attrset
866
867 attr: long
868 /
869
870 Set the "background" set of attributes.
871 [clinic start generated code]*/
872
873 static PyObject *
_curses_window_attrset_impl(PyCursesWindowObject * self,long attr)874 _curses_window_attrset_impl(PyCursesWindowObject *self, long attr)
875 /*[clinic end generated code: output=84e379bff20c0433 input=42e400c0d0154ab5]*/
876 {
877 return PyCursesCheckERR(wattrset(self->win, (attr_t)attr), "attrset");
878 }
879
880 /*[clinic input]
881 _curses.window.bkgdset
882
883 ch: object
884 Background character.
885 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
886 Background attributes.
887 /
888
889 Set the window's background.
890 [clinic start generated code]*/
891
892 static PyObject *
_curses_window_bkgdset_impl(PyCursesWindowObject * self,PyObject * ch,long attr)893 _curses_window_bkgdset_impl(PyCursesWindowObject *self, PyObject *ch,
894 long attr)
895 /*[clinic end generated code: output=8cb994fc4d7e2496 input=e09c682425c9e45b]*/
896 {
897 chtype bkgd;
898
899 if (!PyCurses_ConvertToChtype(self, ch, &bkgd))
900 return NULL;
901
902 wbkgdset(self->win, bkgd | attr);
903 return PyCursesCheckERR(0, "bkgdset");
904 }
905
906 /*[clinic input]
907 _curses.window.border
908
909 ls: object(c_default="NULL") = _curses.ACS_VLINE
910 Left side.
911 rs: object(c_default="NULL") = _curses.ACS_VLINE
912 Right side.
913 ts: object(c_default="NULL") = _curses.ACS_HLINE
914 Top side.
915 bs: object(c_default="NULL") = _curses.ACS_HLINE
916 Bottom side.
917 tl: object(c_default="NULL") = _curses.ACS_ULCORNER
918 Upper-left corner.
919 tr: object(c_default="NULL") = _curses.ACS_URCORNER
920 Upper-right corner.
921 bl: object(c_default="NULL") = _curses.ACS_LLCORNER
922 Bottom-left corner.
923 br: object(c_default="NULL") = _curses.ACS_LRCORNER
924 Bottom-right corner.
925 /
926
927 Draw a border around the edges of the window.
928
929 Each parameter specifies the character to use for a specific part of the
930 border. The characters can be specified as integers or as one-character
931 strings. A 0 value for any parameter will cause the default character to be
932 used for that parameter.
933 [clinic start generated code]*/
934
935 static PyObject *
_curses_window_border_impl(PyCursesWindowObject * self,PyObject * ls,PyObject * rs,PyObject * ts,PyObject * bs,PyObject * tl,PyObject * tr,PyObject * bl,PyObject * br)936 _curses_window_border_impl(PyCursesWindowObject *self, PyObject *ls,
937 PyObject *rs, PyObject *ts, PyObject *bs,
938 PyObject *tl, PyObject *tr, PyObject *bl,
939 PyObject *br)
940 /*[clinic end generated code: output=670ef38d3d7c2aa3 input=e015f735d67a240b]*/
941 {
942 chtype ch[8];
943 int i;
944
945 /* Clear the array of parameters */
946 for(i=0; i<8; i++)
947 ch[i] = 0;
948
949 #define CONVERTTOCHTYPE(obj, i) \
950 if ((obj) != NULL && !PyCurses_ConvertToChtype(self, (obj), &ch[(i)])) \
951 return NULL;
952
953 CONVERTTOCHTYPE(ls, 0);
954 CONVERTTOCHTYPE(rs, 1);
955 CONVERTTOCHTYPE(ts, 2);
956 CONVERTTOCHTYPE(bs, 3);
957 CONVERTTOCHTYPE(tl, 4);
958 CONVERTTOCHTYPE(tr, 5);
959 CONVERTTOCHTYPE(bl, 6);
960 CONVERTTOCHTYPE(br, 7);
961
962 #undef CONVERTTOCHTYPE
963
964 wborder(self->win,
965 ch[0], ch[1], ch[2], ch[3],
966 ch[4], ch[5], ch[6], ch[7]);
967 Py_RETURN_NONE;
968 }
969
970 /*[clinic input]
971 _curses.window.box
972
973 [
974 verch: object(c_default="_PyLong_Zero") = 0
975 Left and right side.
976 horch: object(c_default="_PyLong_Zero") = 0
977 Top and bottom side.
978 ]
979 /
980
981 Draw a border around the edges of the window.
982
983 Similar to border(), but both ls and rs are verch and both ts and bs are
984 horch. The default corner characters are always used by this function.
985 [clinic start generated code]*/
986
987 static PyObject *
_curses_window_box_impl(PyCursesWindowObject * self,int group_right_1,PyObject * verch,PyObject * horch)988 _curses_window_box_impl(PyCursesWindowObject *self, int group_right_1,
989 PyObject *verch, PyObject *horch)
990 /*[clinic end generated code: output=f3fcb038bb287192 input=465a121741c1efdf]*/
991 {
992 chtype ch1 = 0, ch2 = 0;
993 if (group_right_1) {
994 if (!PyCurses_ConvertToChtype(self, verch, &ch1)) {
995 return NULL;
996 }
997 if (!PyCurses_ConvertToChtype(self, horch, &ch2)) {
998 return NULL;
999 }
1000 }
1001 box(self->win,ch1,ch2);
1002 Py_RETURN_NONE;
1003 }
1004
1005 #if defined(HAVE_NCURSES_H) || defined(MVWDELCH_IS_EXPRESSION)
1006 #define py_mvwdelch mvwdelch
1007 #else
py_mvwdelch(WINDOW * w,int y,int x)1008 int py_mvwdelch(WINDOW *w, int y, int x)
1009 {
1010 mvwdelch(w,y,x);
1011 /* On HP/UX, mvwdelch already returns. On other systems,
1012 we may well run into this return statement. */
1013 return 0;
1014 }
1015 #endif
1016
1017 #if defined(HAVE_CURSES_IS_PAD)
1018 #define py_is_pad(win) is_pad(win)
1019 #elif defined(WINDOW_HAS_FLAGS)
1020 #define py_is_pad(win) ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE)
1021 #endif
1022
1023 /* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */
1024 #ifdef HAVE_CURSES_WCHGAT
1025 /*[-clinic input]
1026 _curses.window.chgat
1027
1028 [
1029 y: int
1030 Y-coordinate.
1031 x: int
1032 X-coordinate.
1033 ]
1034
1035 n: int = -1
1036 Number of characters.
1037
1038 attr: long
1039 Attributes for characters.
1040 /
1041
1042 Set the attributes of characters.
1043
1044 Set the attributes of num characters at the current cursor position, or at
1045 position (y, x) if supplied. If no value of num is given or num = -1, the
1046 attribute will be set on all the characters to the end of the line. This
1047 function does not move the cursor. The changed line will be touched using
1048 the touchline() method so that the contents will be redisplayed by the next
1049 window refresh.
1050 [-clinic start generated code]*/
1051 static PyObject *
PyCursesWindow_ChgAt(PyCursesWindowObject * self,PyObject * args)1052 PyCursesWindow_ChgAt(PyCursesWindowObject *self, PyObject *args)
1053 {
1054 int rtn;
1055 int x, y;
1056 int num = -1;
1057 short color;
1058 attr_t attr = A_NORMAL;
1059 long lattr;
1060 int use_xy = FALSE;
1061
1062 switch (PyTuple_Size(args)) {
1063 case 1:
1064 if (!PyArg_ParseTuple(args,"l;attr", &lattr))
1065 return NULL;
1066 attr = lattr;
1067 break;
1068 case 2:
1069 if (!PyArg_ParseTuple(args,"il;n,attr", &num, &lattr))
1070 return NULL;
1071 attr = lattr;
1072 break;
1073 case 3:
1074 if (!PyArg_ParseTuple(args,"iil;int,int,attr", &y, &x, &lattr))
1075 return NULL;
1076 attr = lattr;
1077 use_xy = TRUE;
1078 break;
1079 case 4:
1080 if (!PyArg_ParseTuple(args,"iiil;int,int,n,attr", &y, &x, &num, &lattr))
1081 return NULL;
1082 attr = lattr;
1083 use_xy = TRUE;
1084 break;
1085 default:
1086 PyErr_SetString(PyExc_TypeError, "chgat requires 1 to 4 arguments");
1087 return NULL;
1088 }
1089
1090 color = (short)((attr >> 8) & 0xff);
1091 attr = attr - (color << 8);
1092
1093 if (use_xy) {
1094 rtn = mvwchgat(self->win,y,x,num,attr,color,NULL);
1095 touchline(self->win,y,1);
1096 } else {
1097 getyx(self->win,y,x);
1098 rtn = wchgat(self->win,num,attr,color,NULL);
1099 touchline(self->win,y,1);
1100 }
1101 return PyCursesCheckERR(rtn, "chgat");
1102 }
1103 #endif
1104
1105 /*[clinic input]
1106 _curses.window.delch
1107
1108 [
1109 y: int
1110 Y-coordinate.
1111 x: int
1112 X-coordinate.
1113 ]
1114 /
1115
1116 Delete any character at (y, x).
1117 [clinic start generated code]*/
1118
1119 static PyObject *
_curses_window_delch_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1120 _curses_window_delch_impl(PyCursesWindowObject *self, int group_right_1,
1121 int y, int x)
1122 /*[clinic end generated code: output=22e77bb9fa11b461 input=d2f79e630a4fc6d0]*/
1123 {
1124 if (!group_right_1) {
1125 return PyCursesCheckERR(wdelch(self->win), "wdelch");
1126 }
1127 else {
1128 return PyCursesCheckERR(py_mvwdelch(self->win, y, x), "mvwdelch");
1129 }
1130 }
1131
1132 /*[clinic input]
1133 _curses.window.derwin
1134
1135 [
1136 nlines: int = 0
1137 Height.
1138 ncols: int = 0
1139 Width.
1140 ]
1141 begin_y: int
1142 Top side y-coordinate.
1143 begin_x: int
1144 Left side x-coordinate.
1145 /
1146
1147 Create a sub-window (window-relative coordinates).
1148
1149 derwin() is the same as calling subwin(), except that begin_y and begin_x
1150 are relative to the origin of the window, rather than relative to the entire
1151 screen.
1152 [clinic start generated code]*/
1153
1154 static PyObject *
_curses_window_derwin_impl(PyCursesWindowObject * self,int group_left_1,int nlines,int ncols,int begin_y,int begin_x)1155 _curses_window_derwin_impl(PyCursesWindowObject *self, int group_left_1,
1156 int nlines, int ncols, int begin_y, int begin_x)
1157 /*[clinic end generated code: output=7924b112d9f70d6e input=966d9481f7f5022e]*/
1158 {
1159 WINDOW *win;
1160
1161 win = derwin(self->win,nlines,ncols,begin_y,begin_x);
1162
1163 if (win == NULL) {
1164 PyErr_SetString(PyCursesError, catchall_NULL);
1165 return NULL;
1166 }
1167
1168 return (PyObject *)PyCursesWindow_New(win, NULL);
1169 }
1170
1171 /*[clinic input]
1172 _curses.window.echochar
1173
1174 ch: object
1175 Character to add.
1176
1177 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
1178 Attributes for the character.
1179 /
1180
1181 Add character ch with attribute attr, and refresh.
1182 [clinic start generated code]*/
1183
1184 static PyObject *
_curses_window_echochar_impl(PyCursesWindowObject * self,PyObject * ch,long attr)1185 _curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch,
1186 long attr)
1187 /*[clinic end generated code: output=13e7dd875d4b9642 input=e7f34b964e92b156]*/
1188 {
1189 chtype ch_;
1190
1191 if (!PyCurses_ConvertToChtype(self, ch, &ch_))
1192 return NULL;
1193
1194 #ifdef py_is_pad
1195 if (py_is_pad(self->win)) {
1196 return PyCursesCheckERR(pechochar(self->win, ch_ | (attr_t)attr),
1197 "echochar");
1198 }
1199 else
1200 #endif
1201 return PyCursesCheckERR(wechochar(self->win, ch_ | (attr_t)attr),
1202 "echochar");
1203 }
1204
1205 #ifdef NCURSES_MOUSE_VERSION
1206 /*[clinic input]
1207 _curses.window.enclose -> long
1208
1209 y: int
1210 Y-coordinate.
1211 x: int
1212 X-coordinate.
1213 /
1214
1215 Return True if the screen-relative coordinates are enclosed by the window.
1216 [clinic start generated code]*/
1217
1218 static long
_curses_window_enclose_impl(PyCursesWindowObject * self,int y,int x)1219 _curses_window_enclose_impl(PyCursesWindowObject *self, int y, int x)
1220 /*[clinic end generated code: output=5251c961cbe3df63 input=dfe1d9d4d05d8642]*/
1221 {
1222 return wenclose(self->win, y, x);
1223 }
1224 #endif
1225
1226 /*[clinic input]
1227 _curses.window.getbkgd -> long
1228
1229 Return the window's current background character/attribute pair.
1230 [clinic start generated code]*/
1231
1232 static long
_curses_window_getbkgd_impl(PyCursesWindowObject * self)1233 _curses_window_getbkgd_impl(PyCursesWindowObject *self)
1234 /*[clinic end generated code: output=c52b25dc16b215c3 input=a69db882fa35426c]*/
1235 {
1236 return (long) getbkgd(self->win);
1237 }
1238
1239 /*[clinic input]
1240 _curses.window.getch -> int
1241
1242 [
1243 y: int
1244 Y-coordinate.
1245 x: int
1246 X-coordinate.
1247 ]
1248 /
1249
1250 Get a character code from terminal keyboard.
1251
1252 The integer returned does not have to be in ASCII range: function keys,
1253 keypad keys and so on return numbers higher than 256. In no-delay mode, -1
1254 is returned if there is no input, else getch() waits until a key is pressed.
1255 [clinic start generated code]*/
1256
1257 static int
_curses_window_getch_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1258 _curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1,
1259 int y, int x)
1260 /*[clinic end generated code: output=980aa6af0c0ca387 input=bb24ebfb379f991f]*/
1261 {
1262 int rtn;
1263
1264 Py_BEGIN_ALLOW_THREADS
1265 if (!group_right_1) {
1266 rtn = wgetch(self->win);
1267 }
1268 else {
1269 rtn = mvwgetch(self->win, y, x);
1270 }
1271 Py_END_ALLOW_THREADS
1272
1273 return rtn;
1274 }
1275
1276 /*[clinic input]
1277 _curses.window.getkey
1278
1279 [
1280 y: int
1281 Y-coordinate.
1282 x: int
1283 X-coordinate.
1284 ]
1285 /
1286
1287 Get a character (string) from terminal keyboard.
1288
1289 Returning a string instead of an integer, as getch() does. Function keys,
1290 keypad keys and other special keys return a multibyte string containing the
1291 key name. In no-delay mode, an exception is raised if there is no input.
1292 [clinic start generated code]*/
1293
1294 static PyObject *
_curses_window_getkey_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1295 _curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1,
1296 int y, int x)
1297 /*[clinic end generated code: output=8490a182db46b10f input=be2dee34f5cf57f8]*/
1298 {
1299 int rtn;
1300
1301 Py_BEGIN_ALLOW_THREADS
1302 if (!group_right_1) {
1303 rtn = wgetch(self->win);
1304 }
1305 else {
1306 rtn = mvwgetch(self->win, y, x);
1307 }
1308 Py_END_ALLOW_THREADS
1309
1310 if (rtn == ERR) {
1311 /* getch() returns ERR in nodelay mode */
1312 PyErr_CheckSignals();
1313 if (!PyErr_Occurred())
1314 PyErr_SetString(PyCursesError, "no input");
1315 return NULL;
1316 } else if (rtn <= 255) {
1317 #ifdef NCURSES_VERSION_MAJOR
1318 #if NCURSES_VERSION_MAJOR*100+NCURSES_VERSION_MINOR <= 507
1319 /* Work around a bug in ncurses 5.7 and earlier */
1320 if (rtn < 0) {
1321 rtn += 256;
1322 }
1323 #endif
1324 #endif
1325 return PyUnicode_FromOrdinal(rtn);
1326 } else {
1327 const char *knp = keyname(rtn);
1328 return PyUnicode_FromString((knp == NULL) ? "" : knp);
1329 }
1330 }
1331
1332 #ifdef HAVE_NCURSESW
1333 /*[clinic input]
1334 _curses.window.get_wch
1335
1336 [
1337 y: int
1338 Y-coordinate.
1339 x: int
1340 X-coordinate.
1341 ]
1342 /
1343
1344 Get a wide character from terminal keyboard.
1345
1346 Return a character for most keys, or an integer for function keys,
1347 keypad keys, and other special keys.
1348 [clinic start generated code]*/
1349
1350 static PyObject *
_curses_window_get_wch_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1351 _curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1,
1352 int y, int x)
1353 /*[clinic end generated code: output=9f4f86e91fe50ef3 input=dd7e5367fb49dc48]*/
1354 {
1355 int ct;
1356 wint_t rtn;
1357
1358 Py_BEGIN_ALLOW_THREADS
1359 if (!group_right_1) {
1360 ct = wget_wch(self->win ,&rtn);
1361 }
1362 else {
1363 ct = mvwget_wch(self->win, y, x, &rtn);
1364 }
1365 Py_END_ALLOW_THREADS
1366
1367 if (ct == ERR) {
1368 if (PyErr_CheckSignals())
1369 return NULL;
1370
1371 /* get_wch() returns ERR in nodelay mode */
1372 PyErr_SetString(PyCursesError, "no input");
1373 return NULL;
1374 }
1375 if (ct == KEY_CODE_YES)
1376 return PyLong_FromLong(rtn);
1377 else
1378 return PyUnicode_FromOrdinal(rtn);
1379 }
1380 #endif
1381
1382 /*[-clinic input]
1383 _curses.window.getstr
1384
1385 [
1386 y: int
1387 Y-coordinate.
1388 x: int
1389 X-coordinate.
1390 ]
1391 n: int = 1023
1392 Maximal number of characters.
1393 /
1394
1395 Read a string from the user, with primitive line editing capacity.
1396 [-clinic start generated code]*/
1397
1398 static PyObject *
PyCursesWindow_GetStr(PyCursesWindowObject * self,PyObject * args)1399 PyCursesWindow_GetStr(PyCursesWindowObject *self, PyObject *args)
1400 {
1401 int x, y, n;
1402 char rtn[1024]; /* This should be big enough.. I hope */
1403 int rtn2;
1404
1405 switch (PyTuple_Size(args)) {
1406 case 0:
1407 Py_BEGIN_ALLOW_THREADS
1408 rtn2 = wgetnstr(self->win,rtn, 1023);
1409 Py_END_ALLOW_THREADS
1410 break;
1411 case 1:
1412 if (!PyArg_ParseTuple(args,"i;n", &n))
1413 return NULL;
1414 if (n < 0) {
1415 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1416 return NULL;
1417 }
1418 Py_BEGIN_ALLOW_THREADS
1419 rtn2 = wgetnstr(self->win, rtn, Py_MIN(n, 1023));
1420 Py_END_ALLOW_THREADS
1421 break;
1422 case 2:
1423 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1424 return NULL;
1425 Py_BEGIN_ALLOW_THREADS
1426 #ifdef STRICT_SYSV_CURSES
1427 rtn2 = wmove(self->win,y,x)==ERR ? ERR : wgetnstr(self->win, rtn, 1023);
1428 #else
1429 rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023);
1430 #endif
1431 Py_END_ALLOW_THREADS
1432 break;
1433 case 3:
1434 if (!PyArg_ParseTuple(args,"iii;y,x,n", &y, &x, &n))
1435 return NULL;
1436 if (n < 0) {
1437 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1438 return NULL;
1439 }
1440 #ifdef STRICT_SYSV_CURSES
1441 Py_BEGIN_ALLOW_THREADS
1442 rtn2 = wmove(self->win,y,x)==ERR ? ERR :
1443 wgetnstr(self->win, rtn, Py_MIN(n, 1023));
1444 Py_END_ALLOW_THREADS
1445 #else
1446 Py_BEGIN_ALLOW_THREADS
1447 rtn2 = mvwgetnstr(self->win, y, x, rtn, Py_MIN(n, 1023));
1448 Py_END_ALLOW_THREADS
1449 #endif
1450 break;
1451 default:
1452 PyErr_SetString(PyExc_TypeError, "getstr requires 0 to 3 arguments");
1453 return NULL;
1454 }
1455 if (rtn2 == ERR)
1456 rtn[0] = 0;
1457 return PyBytes_FromString(rtn);
1458 }
1459
1460 /*[clinic input]
1461 _curses.window.hline
1462
1463 [
1464 y: int
1465 Starting Y-coordinate.
1466 x: int
1467 Starting X-coordinate.
1468 ]
1469
1470 ch: object
1471 Character to draw.
1472 n: int
1473 Line length.
1474
1475 [
1476 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
1477 Attributes for the characters.
1478 ]
1479 /
1480
1481 Display a horizontal line.
1482 [clinic start generated code]*/
1483
1484 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)1485 _curses_window_hline_impl(PyCursesWindowObject *self, int group_left_1,
1486 int y, int x, PyObject *ch, int n,
1487 int group_right_1, long attr)
1488 /*[clinic end generated code: output=c00d489d61fc9eef input=81a4dea47268163e]*/
1489 {
1490 chtype ch_;
1491
1492 if (!PyCurses_ConvertToChtype(self, ch, &ch_))
1493 return NULL;
1494 if (group_left_1) {
1495 if (wmove(self->win, y, x) == ERR) {
1496 return PyCursesCheckERR(ERR, "wmove");
1497 }
1498 }
1499 return PyCursesCheckERR(whline(self->win, ch_ | (attr_t)attr, n), "hline");
1500 }
1501
1502 /*[clinic input]
1503 _curses.window.insch
1504
1505 [
1506 y: int
1507 Y-coordinate.
1508 x: int
1509 X-coordinate.
1510 ]
1511
1512 ch: object
1513 Character to insert.
1514
1515 [
1516 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
1517 Attributes for the character.
1518 ]
1519 /
1520
1521 Insert a character before the current or specified position.
1522
1523 All characters to the right of the cursor are shifted one position right, with
1524 the rightmost characters on the line being lost.
1525 [clinic start generated code]*/
1526
1527 static PyObject *
_curses_window_insch_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * ch,int group_right_1,long attr)1528 _curses_window_insch_impl(PyCursesWindowObject *self, int group_left_1,
1529 int y, int x, PyObject *ch, int group_right_1,
1530 long attr)
1531 /*[clinic end generated code: output=ade8cfe3a3bf3e34 input=336342756ee19812]*/
1532 {
1533 int rtn;
1534 chtype ch_ = 0;
1535
1536 if (!PyCurses_ConvertToChtype(self, ch, &ch_))
1537 return NULL;
1538
1539 if (!group_left_1) {
1540 rtn = winsch(self->win, ch_ | (attr_t)attr);
1541 }
1542 else {
1543 rtn = mvwinsch(self->win, y, x, ch_ | (attr_t)attr);
1544 }
1545
1546 return PyCursesCheckERR(rtn, "insch");
1547 }
1548
1549 /*[clinic input]
1550 _curses.window.inch -> unsigned_long
1551
1552 [
1553 y: int
1554 Y-coordinate.
1555 x: int
1556 X-coordinate.
1557 ]
1558 /
1559
1560 Return the character at the given position in the window.
1561
1562 The bottom 8 bits are the character proper, and upper bits are the attributes.
1563 [clinic start generated code]*/
1564
1565 static unsigned long
_curses_window_inch_impl(PyCursesWindowObject * self,int group_right_1,int y,int x)1566 _curses_window_inch_impl(PyCursesWindowObject *self, int group_right_1,
1567 int y, int x)
1568 /*[clinic end generated code: output=6c4719fe978fe86a input=fac23ee11e3b3a66]*/
1569 {
1570 unsigned long rtn;
1571
1572 if (!group_right_1) {
1573 rtn = winch(self->win);
1574 }
1575 else {
1576 rtn = mvwinch(self->win, y, x);
1577 }
1578
1579 return rtn;
1580 }
1581
1582 /*[-clinic input]
1583 _curses.window.instr
1584
1585 [
1586 y: int
1587 Y-coordinate.
1588 x: int
1589 X-coordinate.
1590 ]
1591 n: int = 1023
1592 Maximal number of characters.
1593 /
1594
1595 Return a string of characters, extracted from the window.
1596
1597 Return a string of characters, extracted from the window starting at the
1598 current cursor position, or at y, x if specified. Attributes are stripped
1599 from the characters. If n is specified, instr() returns a string at most
1600 n characters long (exclusive of the trailing NUL).
1601 [-clinic start generated code]*/
1602 static PyObject *
PyCursesWindow_InStr(PyCursesWindowObject * self,PyObject * args)1603 PyCursesWindow_InStr(PyCursesWindowObject *self, PyObject *args)
1604 {
1605 int x, y, n;
1606 char rtn[1024]; /* This should be big enough.. I hope */
1607 int rtn2;
1608
1609 switch (PyTuple_Size(args)) {
1610 case 0:
1611 rtn2 = winnstr(self->win,rtn, 1023);
1612 break;
1613 case 1:
1614 if (!PyArg_ParseTuple(args,"i;n", &n))
1615 return NULL;
1616 if (n < 0) {
1617 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1618 return NULL;
1619 }
1620 rtn2 = winnstr(self->win, rtn, Py_MIN(n, 1023));
1621 break;
1622 case 2:
1623 if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
1624 return NULL;
1625 rtn2 = mvwinnstr(self->win,y,x,rtn,1023);
1626 break;
1627 case 3:
1628 if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n))
1629 return NULL;
1630 if (n < 0) {
1631 PyErr_SetString(PyExc_ValueError, "'n' must be nonnegative");
1632 return NULL;
1633 }
1634 rtn2 = mvwinnstr(self->win, y, x, rtn, Py_MIN(n,1023));
1635 break;
1636 default:
1637 PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments");
1638 return NULL;
1639 }
1640 if (rtn2 == ERR)
1641 rtn[0] = 0;
1642 return PyBytes_FromString(rtn);
1643 }
1644
1645 /*[clinic input]
1646 _curses.window.insstr
1647
1648 [
1649 y: int
1650 Y-coordinate.
1651 x: int
1652 X-coordinate.
1653 ]
1654
1655 str: object
1656 String to insert.
1657
1658 [
1659 attr: long
1660 Attributes for characters.
1661 ]
1662 /
1663
1664 Insert the string before the current or specified position.
1665
1666 Insert a character string (as many characters as will fit on the line)
1667 before the character under the cursor. All characters to the right of
1668 the cursor are shifted right, with the rightmost characters on the line
1669 being lost. The cursor position does not change (after moving to y, x,
1670 if specified).
1671 [clinic start generated code]*/
1672
1673 static PyObject *
_curses_window_insstr_impl(PyCursesWindowObject * self,int group_left_1,int y,int x,PyObject * str,int group_right_1,long attr)1674 _curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1,
1675 int y, int x, PyObject *str, int group_right_1,
1676 long attr)
1677 /*[clinic end generated code: output=c259a5265ad0b777 input=6827cddc6340a7f3]*/
1678 {
1679 int rtn;
1680 int strtype;
1681 PyObject *bytesobj = NULL;
1682 #ifdef HAVE_NCURSESW
1683 wchar_t *wstr = NULL;
1684 #endif
1685 attr_t attr_old = A_NORMAL;
1686 int use_xy = group_left_1, use_attr = group_right_1;
1687 const char *funcname;
1688
1689 #ifdef HAVE_NCURSESW
1690 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr);
1691 #else
1692 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL);
1693 #endif
1694 if (strtype == 0)
1695 return NULL;
1696
1697 if (use_attr) {
1698 attr_old = getattrs(self->win);
1699 (void)wattrset(self->win, (attr_t)attr);
1700 }
1701 #ifdef HAVE_NCURSESW
1702 if (strtype == 2) {
1703 funcname = "inswstr";
1704 if (use_xy)
1705 rtn = mvwins_wstr(self->win,y,x,wstr);
1706 else
1707 rtn = wins_wstr(self->win,wstr);
1708 PyMem_Free(wstr);
1709 }
1710 else
1711 #endif
1712 {
1713 const char *str = PyBytes_AS_STRING(bytesobj);
1714 funcname = "insstr";
1715 if (use_xy)
1716 rtn = mvwinsstr(self->win,y,x,str);
1717 else
1718 rtn = winsstr(self->win,str);
1719 Py_DECREF(bytesobj);
1720 }
1721 if (use_attr)
1722 (void)wattrset(self->win,attr_old);
1723 return PyCursesCheckERR(rtn, funcname);
1724 }
1725
1726 /*[clinic input]
1727 _curses.window.insnstr
1728
1729 [
1730 y: int
1731 Y-coordinate.
1732 x: int
1733 X-coordinate.
1734 ]
1735
1736 str: object
1737 String to insert.
1738
1739 n: int
1740 Maximal number of characters.
1741
1742 [
1743 attr: long
1744 Attributes for characters.
1745 ]
1746 /
1747
1748 Insert at most n characters of the string.
1749
1750 Insert a character string (as many characters as will fit on the line)
1751 before the character under the cursor, up to n characters. If n is zero
1752 or negative, the entire string is inserted. All characters to the right
1753 of the cursor are shifted right, with the rightmost characters on the line
1754 being lost. The cursor position does not change (after moving to y, x, if
1755 specified).
1756 [clinic start generated code]*/
1757
1758 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)1759 _curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1,
1760 int y, int x, PyObject *str, int n,
1761 int group_right_1, long attr)
1762 /*[clinic end generated code: output=971a32ea6328ec8b input=70fa0cd543901a4c]*/
1763 {
1764 int rtn;
1765 int strtype;
1766 PyObject *bytesobj = NULL;
1767 #ifdef HAVE_NCURSESW
1768 wchar_t *wstr = NULL;
1769 #endif
1770 attr_t attr_old = A_NORMAL;
1771 int use_xy = group_left_1, use_attr = group_right_1;
1772 const char *funcname;
1773
1774 #ifdef HAVE_NCURSESW
1775 strtype = PyCurses_ConvertToString(self, str, &bytesobj, &wstr);
1776 #else
1777 strtype = PyCurses_ConvertToString(self, str, &bytesobj, NULL);
1778 #endif
1779 if (strtype == 0)
1780 return NULL;
1781
1782 if (use_attr) {
1783 attr_old = getattrs(self->win);
1784 (void)wattrset(self->win, (attr_t)attr);
1785 }
1786 #ifdef HAVE_NCURSESW
1787 if (strtype == 2) {
1788 funcname = "insn_wstr";
1789 if (use_xy)
1790 rtn = mvwins_nwstr(self->win,y,x,wstr,n);
1791 else
1792 rtn = wins_nwstr(self->win,wstr,n);
1793 PyMem_Free(wstr);
1794 }
1795 else
1796 #endif
1797 {
1798 const char *str = PyBytes_AS_STRING(bytesobj);
1799 funcname = "insnstr";
1800 if (use_xy)
1801 rtn = mvwinsnstr(self->win,y,x,str,n);
1802 else
1803 rtn = winsnstr(self->win,str,n);
1804 Py_DECREF(bytesobj);
1805 }
1806 if (use_attr)
1807 (void)wattrset(self->win,attr_old);
1808 return PyCursesCheckERR(rtn, funcname);
1809 }
1810
1811 /*[clinic input]
1812 _curses.window.is_linetouched
1813
1814 line: int
1815 Line number.
1816 /
1817
1818 Return True if the specified line was modified, otherwise return False.
1819
1820 Raise a curses.error exception if line is not valid for the given window.
1821 [clinic start generated code]*/
1822
1823 static PyObject *
_curses_window_is_linetouched_impl(PyCursesWindowObject * self,int line)1824 _curses_window_is_linetouched_impl(PyCursesWindowObject *self, int line)
1825 /*[clinic end generated code: output=ad4a4edfee2db08c input=a7be0c189f243914]*/
1826 {
1827 int erg;
1828 erg = is_linetouched(self->win, line);
1829 if (erg == ERR) {
1830 PyErr_SetString(PyExc_TypeError,
1831 "is_linetouched: line number outside of boundaries");
1832 return NULL;
1833 }
1834 return PyBool_FromLong(erg);
1835 }
1836
1837 #ifdef py_is_pad
1838 /*[clinic input]
1839 _curses.window.noutrefresh
1840
1841 [
1842 pminrow: int
1843 pmincol: int
1844 sminrow: int
1845 smincol: int
1846 smaxrow: int
1847 smaxcol: int
1848 ]
1849 /
1850
1851 Mark for refresh but wait.
1852
1853 This function updates the data structure representing the desired state of the
1854 window, but does not force an update of the physical screen. To accomplish
1855 that, call doupdate().
1856 [clinic start generated code]*/
1857
1858 static PyObject *
_curses_window_noutrefresh_impl(PyCursesWindowObject * self,int group_right_1,int pminrow,int pmincol,int sminrow,int smincol,int smaxrow,int smaxcol)1859 _curses_window_noutrefresh_impl(PyCursesWindowObject *self,
1860 int group_right_1, int pminrow, int pmincol,
1861 int sminrow, int smincol, int smaxrow,
1862 int smaxcol)
1863 /*[clinic end generated code: output=809a1f3c6a03e23e input=3e56898388cd739e]*/
1864 #else
1865 /*[clinic input]
1866 _curses.window.noutrefresh
1867
1868 Mark for refresh but wait.
1869
1870 This function updates the data structure representing the desired state of the
1871 window, but does not force an update of the physical screen. To accomplish
1872 that, call doupdate().
1873 [clinic start generated code]*/
1874
1875 static PyObject *
1876 _curses_window_noutrefresh_impl(PyCursesWindowObject *self)
1877 /*[clinic end generated code: output=6ef6dec666643fee input=876902e3fa431dbd]*/
1878 #endif
1879 {
1880 int rtn;
1881
1882 #ifdef py_is_pad
1883 if (py_is_pad(self->win)) {
1884 if (!group_right_1) {
1885 PyErr_SetString(PyCursesError,
1886 "noutrefresh() called for a pad "
1887 "requires 6 arguments");
1888 return NULL;
1889 }
1890 Py_BEGIN_ALLOW_THREADS
1891 rtn = pnoutrefresh(self->win, pminrow, pmincol,
1892 sminrow, smincol, smaxrow, smaxcol);
1893 Py_END_ALLOW_THREADS
1894 return PyCursesCheckERR(rtn, "pnoutrefresh");
1895 }
1896 if (group_right_1) {
1897 PyErr_SetString(PyExc_TypeError,
1898 "noutrefresh() takes no arguments (6 given)");
1899 return NULL;
1900 }
1901 #endif
1902 Py_BEGIN_ALLOW_THREADS
1903 rtn = wnoutrefresh(self->win);
1904 Py_END_ALLOW_THREADS
1905 return PyCursesCheckERR(rtn, "wnoutrefresh");
1906 }
1907
1908 /*[clinic input]
1909 _curses.window.overlay
1910
1911 destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type")
1912
1913 [
1914 sminrow: int
1915 smincol: int
1916 dminrow: int
1917 dmincol: int
1918 dmaxrow: int
1919 dmaxcol: int
1920 ]
1921 /
1922
1923 Overlay the window on top of destwin.
1924
1925 The windows need not be the same size, only the overlapping region is copied.
1926 This copy is non-destructive, which means that the current background
1927 character does not overwrite the old contents of destwin.
1928
1929 To get fine-grained control over the copied region, the second form of
1930 overlay() can be used. sminrow and smincol are the upper-left coordinates
1931 of the source window, and the other variables mark a rectangle in the
1932 destination window.
1933 [clinic start generated code]*/
1934
1935 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)1936 _curses_window_overlay_impl(PyCursesWindowObject *self,
1937 PyCursesWindowObject *destwin, int group_right_1,
1938 int sminrow, int smincol, int dminrow,
1939 int dmincol, int dmaxrow, int dmaxcol)
1940 /*[clinic end generated code: output=82bb2c4cb443ca58 input=7edd23ad22cc1984]*/
1941 {
1942 int rtn;
1943
1944 if (group_right_1) {
1945 rtn = copywin(self->win, destwin->win, sminrow, smincol,
1946 dminrow, dmincol, dmaxrow, dmaxcol, TRUE);
1947 return PyCursesCheckERR(rtn, "copywin");
1948 }
1949 else {
1950 rtn = overlay(self->win, destwin->win);
1951 return PyCursesCheckERR(rtn, "overlay");
1952 }
1953 }
1954
1955 /*[clinic input]
1956 _curses.window.overwrite
1957
1958 destwin: object(type="PyCursesWindowObject *", subclass_of="&PyCursesWindow_Type")
1959
1960 [
1961 sminrow: int
1962 smincol: int
1963 dminrow: int
1964 dmincol: int
1965 dmaxrow: int
1966 dmaxcol: int
1967 ]
1968 /
1969
1970 Overwrite the window on top of destwin.
1971
1972 The windows need not be the same size, in which case only the overlapping
1973 region is copied. This copy is destructive, which means that the current
1974 background character overwrites the old contents of destwin.
1975
1976 To get fine-grained control over the copied region, the second form of
1977 overwrite() can be used. sminrow and smincol are the upper-left coordinates
1978 of the source window, the other variables mark a rectangle in the destination
1979 window.
1980 [clinic start generated code]*/
1981
1982 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)1983 _curses_window_overwrite_impl(PyCursesWindowObject *self,
1984 PyCursesWindowObject *destwin,
1985 int group_right_1, int sminrow, int smincol,
1986 int dminrow, int dmincol, int dmaxrow,
1987 int dmaxcol)
1988 /*[clinic end generated code: output=12ae007d1681be28 input=ea5de1b35cd948e0]*/
1989 {
1990 int rtn;
1991
1992 if (group_right_1) {
1993 rtn = copywin(self->win, destwin->win, sminrow, smincol,
1994 dminrow, dmincol, dmaxrow, dmaxcol, FALSE);
1995 return PyCursesCheckERR(rtn, "copywin");
1996 }
1997 else {
1998 rtn = overwrite(self->win, destwin->win);
1999 return PyCursesCheckERR(rtn, "overwrite");
2000 }
2001 }
2002
2003 /*[clinic input]
2004 _curses.window.putwin
2005
2006 file: object
2007 /
2008
2009 Write all data associated with the window into the provided file object.
2010
2011 This information can be later retrieved using the getwin() function.
2012 [clinic start generated code]*/
2013
2014 static PyObject *
_curses_window_putwin(PyCursesWindowObject * self,PyObject * file)2015 _curses_window_putwin(PyCursesWindowObject *self, PyObject *file)
2016 /*[clinic end generated code: output=3a25e2a5e7a040ac input=0608648e09c8ea0a]*/
2017 {
2018 /* We have to simulate this by writing to a temporary FILE*,
2019 then reading back, then writing to the argument file. */
2020 FILE *fp;
2021 PyObject *res = NULL;
2022
2023 fp = tmpfile();
2024 if (fp == NULL)
2025 return PyErr_SetFromErrno(PyExc_OSError);
2026 if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0)
2027 goto exit;
2028 res = PyCursesCheckERR(putwin(self->win, fp), "putwin");
2029 if (res == NULL)
2030 goto exit;
2031 fseek(fp, 0, 0);
2032 while (1) {
2033 char buf[BUFSIZ];
2034 Py_ssize_t n = fread(buf, 1, BUFSIZ, fp);
2035 _Py_IDENTIFIER(write);
2036
2037 if (n <= 0)
2038 break;
2039 Py_DECREF(res);
2040 res = _PyObject_CallMethodId(file, &PyId_write, "y#", buf, n);
2041 if (res == NULL)
2042 break;
2043 }
2044
2045 exit:
2046 fclose(fp);
2047 return res;
2048 }
2049
2050 /*[clinic input]
2051 _curses.window.redrawln
2052
2053 beg: int
2054 Starting line number.
2055 num: int
2056 The number of lines.
2057 /
2058
2059 Mark the specified lines corrupted.
2060
2061 They should be completely redrawn on the next refresh() call.
2062 [clinic start generated code]*/
2063
2064 static PyObject *
_curses_window_redrawln_impl(PyCursesWindowObject * self,int beg,int num)2065 _curses_window_redrawln_impl(PyCursesWindowObject *self, int beg, int num)
2066 /*[clinic end generated code: output=ea216e334f9ce1b4 input=152155e258a77a7a]*/
2067 {
2068 return PyCursesCheckERR(wredrawln(self->win,beg,num), "redrawln");
2069 }
2070
2071 /*[clinic input]
2072 _curses.window.refresh
2073
2074 [
2075 pminrow: int
2076 pmincol: int
2077 sminrow: int
2078 smincol: int
2079 smaxrow: int
2080 smaxcol: int
2081 ]
2082 /
2083
2084 Update the display immediately.
2085
2086 Synchronize actual screen with previous drawing/deleting methods.
2087 The 6 optional arguments can only be specified when the window is a pad
2088 created with newpad(). The additional parameters are needed to indicate
2089 what part of the pad and screen are involved. pminrow and pmincol specify
2090 the upper left-hand corner of the rectangle to be displayed in the pad.
2091 sminrow, smincol, smaxrow, and smaxcol specify the edges of the rectangle to
2092 be displayed on the screen. The lower right-hand corner of the rectangle to
2093 be displayed in the pad is calculated from the screen coordinates, since the
2094 rectangles must be the same size. Both rectangles must be entirely contained
2095 within their respective structures. Negative values of pminrow, pmincol,
2096 sminrow, or smincol are treated as if they were zero.
2097 [clinic start generated code]*/
2098
2099 static PyObject *
_curses_window_refresh_impl(PyCursesWindowObject * self,int group_right_1,int pminrow,int pmincol,int sminrow,int smincol,int smaxrow,int smaxcol)2100 _curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1,
2101 int pminrow, int pmincol, int sminrow,
2102 int smincol, int smaxrow, int smaxcol)
2103 /*[clinic end generated code: output=42199543115e6e63 input=95e01cb5ffc635d0]*/
2104 {
2105 int rtn;
2106
2107 #ifdef py_is_pad
2108 if (py_is_pad(self->win)) {
2109 if (!group_right_1) {
2110 PyErr_SetString(PyCursesError,
2111 "refresh() for a pad requires 6 arguments");
2112 return NULL;
2113 }
2114 Py_BEGIN_ALLOW_THREADS
2115 rtn = prefresh(self->win, pminrow, pmincol,
2116 sminrow, smincol, smaxrow, smaxcol);
2117 Py_END_ALLOW_THREADS
2118 return PyCursesCheckERR(rtn, "prefresh");
2119 }
2120 #endif
2121 if (group_right_1) {
2122 PyErr_SetString(PyExc_TypeError,
2123 "refresh() takes no arguments (6 given)");
2124 return NULL;
2125 }
2126 Py_BEGIN_ALLOW_THREADS
2127 rtn = wrefresh(self->win);
2128 Py_END_ALLOW_THREADS
2129 return PyCursesCheckERR(rtn, "prefresh");
2130 }
2131
2132 /*[clinic input]
2133 _curses.window.setscrreg
2134
2135 top: int
2136 First line number.
2137 bottom: int
2138 Last line number.
2139 /
2140
2141 Define a software scrolling region.
2142
2143 All scrolling actions will take place in this region.
2144 [clinic start generated code]*/
2145
2146 static PyObject *
_curses_window_setscrreg_impl(PyCursesWindowObject * self,int top,int bottom)2147 _curses_window_setscrreg_impl(PyCursesWindowObject *self, int top,
2148 int bottom)
2149 /*[clinic end generated code: output=486ab5db218d2b1a input=1b517b986838bf0e]*/
2150 {
2151 return PyCursesCheckERR(wsetscrreg(self->win, top, bottom), "wsetscrreg");
2152 }
2153
2154 /*[clinic input]
2155 _curses.window.subwin
2156
2157 [
2158 nlines: int = 0
2159 Height.
2160 ncols: int = 0
2161 Width.
2162 ]
2163 begin_y: int
2164 Top side y-coordinate.
2165 begin_x: int
2166 Left side x-coordinate.
2167 /
2168
2169 Create a sub-window (screen-relative coordinates).
2170
2171 By default, the sub-window will extend from the specified position to the
2172 lower right corner of the window.
2173 [clinic start generated code]*/
2174
2175 static PyObject *
_curses_window_subwin_impl(PyCursesWindowObject * self,int group_left_1,int nlines,int ncols,int begin_y,int begin_x)2176 _curses_window_subwin_impl(PyCursesWindowObject *self, int group_left_1,
2177 int nlines, int ncols, int begin_y, int begin_x)
2178 /*[clinic end generated code: output=93e898afc348f59a input=2129fa47fd57721c]*/
2179 {
2180 WINDOW *win;
2181
2182 /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */
2183 #ifdef py_is_pad
2184 if (py_is_pad(self->win)) {
2185 win = subpad(self->win, nlines, ncols, begin_y, begin_x);
2186 }
2187 else
2188 #endif
2189 win = subwin(self->win, nlines, ncols, begin_y, begin_x);
2190
2191 if (win == NULL) {
2192 PyErr_SetString(PyCursesError, catchall_NULL);
2193 return NULL;
2194 }
2195
2196 return (PyObject *)PyCursesWindow_New(win, self->encoding);
2197 }
2198
2199 /*[clinic input]
2200 _curses.window.scroll
2201
2202 [
2203 lines: int = 1
2204 Number of lines to scroll.
2205 ]
2206 /
2207
2208 Scroll the screen or scrolling region.
2209
2210 Scroll upward if the argument is positive and downward if it is negative.
2211 [clinic start generated code]*/
2212
2213 static PyObject *
_curses_window_scroll_impl(PyCursesWindowObject * self,int group_right_1,int lines)2214 _curses_window_scroll_impl(PyCursesWindowObject *self, int group_right_1,
2215 int lines)
2216 /*[clinic end generated code: output=4541a8a11852d360 input=c969ca0cfabbdbec]*/
2217 {
2218 if (!group_right_1) {
2219 return PyCursesCheckERR(scroll(self->win), "scroll");
2220 }
2221 else {
2222 return PyCursesCheckERR(wscrl(self->win, lines), "scroll");
2223 }
2224 }
2225
2226 /*[clinic input]
2227 _curses.window.touchline
2228
2229 start: int
2230 count: int
2231 [
2232 changed: bool(accept={int}) = True
2233 ]
2234 /
2235
2236 Pretend count lines have been changed, starting with line start.
2237
2238 If changed is supplied, it specifies whether the affected lines are marked
2239 as having been changed (changed=True) or unchanged (changed=False).
2240 [clinic start generated code]*/
2241
2242 static PyObject *
_curses_window_touchline_impl(PyCursesWindowObject * self,int start,int count,int group_right_1,int changed)2243 _curses_window_touchline_impl(PyCursesWindowObject *self, int start,
2244 int count, int group_right_1, int changed)
2245 /*[clinic end generated code: output=65d05b3f7438c61d input=918ad1cbdadf93ea]*/
2246 {
2247 if (!group_right_1) {
2248 return PyCursesCheckERR(touchline(self->win, start, count), "touchline");
2249 }
2250 else {
2251 return PyCursesCheckERR(wtouchln(self->win, start, count, changed), "touchline");
2252 }
2253 }
2254
2255 /*[clinic input]
2256 _curses.window.vline
2257
2258 [
2259 y: int
2260 Starting Y-coordinate.
2261 x: int
2262 Starting X-coordinate.
2263 ]
2264
2265 ch: object
2266 Character to draw.
2267 n: int
2268 Line length.
2269
2270 [
2271 attr: long(c_default="A_NORMAL") = _curses.A_NORMAL
2272 Attributes for the character.
2273 ]
2274 /
2275
2276 Display a vertical line.
2277 [clinic start generated code]*/
2278
2279 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)2280 _curses_window_vline_impl(PyCursesWindowObject *self, int group_left_1,
2281 int y, int x, PyObject *ch, int n,
2282 int group_right_1, long attr)
2283 /*[clinic end generated code: output=287ad1cc8982217f input=a6f2dc86a4648b32]*/
2284 {
2285 chtype ch_;
2286
2287 if (!PyCurses_ConvertToChtype(self, ch, &ch_))
2288 return NULL;
2289 if (group_left_1) {
2290 if (wmove(self->win, y, x) == ERR)
2291 return PyCursesCheckERR(ERR, "wmove");
2292 }
2293 return PyCursesCheckERR(wvline(self->win, ch_ | (attr_t)attr, n), "vline");
2294 }
2295
2296 static PyObject *
PyCursesWindow_get_encoding(PyCursesWindowObject * self,void * closure)2297 PyCursesWindow_get_encoding(PyCursesWindowObject *self, void *closure)
2298 {
2299 return PyUnicode_FromString(self->encoding);
2300 }
2301
2302 static int
PyCursesWindow_set_encoding(PyCursesWindowObject * self,PyObject * value,void * Py_UNUSED (ignored))2303 PyCursesWindow_set_encoding(PyCursesWindowObject *self, PyObject *value, void *Py_UNUSED(ignored))
2304 {
2305 PyObject *ascii;
2306 char *encoding;
2307
2308 /* It is illegal to del win.encoding */
2309 if (value == NULL) {
2310 PyErr_SetString(PyExc_TypeError,
2311 "encoding may not be deleted");
2312 return -1;
2313 }
2314
2315 if (!PyUnicode_Check(value)) {
2316 PyErr_SetString(PyExc_TypeError,
2317 "setting encoding to a non-string");
2318 return -1;
2319 }
2320 ascii = PyUnicode_AsASCIIString(value);
2321 if (ascii == NULL)
2322 return -1;
2323 encoding = _PyMem_Strdup(PyBytes_AS_STRING(ascii));
2324 Py_DECREF(ascii);
2325 if (encoding == NULL) {
2326 PyErr_NoMemory();
2327 return -1;
2328 }
2329 PyMem_Free(self->encoding);
2330 self->encoding = encoding;
2331 return 0;
2332 }
2333
2334 #include "clinic/_cursesmodule.c.h"
2335
2336 static PyMethodDef PyCursesWindow_Methods[] = {
2337 _CURSES_WINDOW_ADDCH_METHODDEF
2338 _CURSES_WINDOW_ADDNSTR_METHODDEF
2339 _CURSES_WINDOW_ADDSTR_METHODDEF
2340 _CURSES_WINDOW_ATTROFF_METHODDEF
2341 _CURSES_WINDOW_ATTRON_METHODDEF
2342 _CURSES_WINDOW_ATTRSET_METHODDEF
2343 _CURSES_WINDOW_BKGD_METHODDEF
2344 #ifdef HAVE_CURSES_WCHGAT
2345 {"chgat", (PyCFunction)PyCursesWindow_ChgAt, METH_VARARGS},
2346 #endif
2347 _CURSES_WINDOW_BKGDSET_METHODDEF
2348 _CURSES_WINDOW_BORDER_METHODDEF
2349 _CURSES_WINDOW_BOX_METHODDEF
2350 {"clear", (PyCFunction)PyCursesWindow_wclear, METH_NOARGS},
2351 {"clearok", (PyCFunction)PyCursesWindow_clearok, METH_VARARGS},
2352 {"clrtobot", (PyCFunction)PyCursesWindow_wclrtobot, METH_NOARGS},
2353 {"clrtoeol", (PyCFunction)PyCursesWindow_wclrtoeol, METH_NOARGS},
2354 {"cursyncup", (PyCFunction)PyCursesWindow_wcursyncup, METH_NOARGS},
2355 _CURSES_WINDOW_DELCH_METHODDEF
2356 {"deleteln", (PyCFunction)PyCursesWindow_wdeleteln, METH_NOARGS},
2357 _CURSES_WINDOW_DERWIN_METHODDEF
2358 _CURSES_WINDOW_ECHOCHAR_METHODDEF
2359 _CURSES_WINDOW_ENCLOSE_METHODDEF
2360 {"erase", (PyCFunction)PyCursesWindow_werase, METH_NOARGS},
2361 {"getbegyx", (PyCFunction)PyCursesWindow_getbegyx, METH_NOARGS},
2362 _CURSES_WINDOW_GETBKGD_METHODDEF
2363 _CURSES_WINDOW_GETCH_METHODDEF
2364 _CURSES_WINDOW_GETKEY_METHODDEF
2365 _CURSES_WINDOW_GET_WCH_METHODDEF
2366 {"getmaxyx", (PyCFunction)PyCursesWindow_getmaxyx, METH_NOARGS},
2367 {"getparyx", (PyCFunction)PyCursesWindow_getparyx, METH_NOARGS},
2368 {"getstr", (PyCFunction)PyCursesWindow_GetStr, METH_VARARGS},
2369 {"getyx", (PyCFunction)PyCursesWindow_getyx, METH_NOARGS},
2370 _CURSES_WINDOW_HLINE_METHODDEF
2371 {"idcok", (PyCFunction)PyCursesWindow_idcok, METH_VARARGS},
2372 {"idlok", (PyCFunction)PyCursesWindow_idlok, METH_VARARGS},
2373 #ifdef HAVE_CURSES_IMMEDOK
2374 {"immedok", (PyCFunction)PyCursesWindow_immedok, METH_VARARGS},
2375 #endif
2376 _CURSES_WINDOW_INCH_METHODDEF
2377 _CURSES_WINDOW_INSCH_METHODDEF
2378 {"insdelln", (PyCFunction)PyCursesWindow_winsdelln, METH_VARARGS},
2379 {"insertln", (PyCFunction)PyCursesWindow_winsertln, METH_NOARGS},
2380 _CURSES_WINDOW_INSNSTR_METHODDEF
2381 _CURSES_WINDOW_INSSTR_METHODDEF
2382 {"instr", (PyCFunction)PyCursesWindow_InStr, METH_VARARGS},
2383 _CURSES_WINDOW_IS_LINETOUCHED_METHODDEF
2384 {"is_wintouched", (PyCFunction)PyCursesWindow_is_wintouched, METH_NOARGS},
2385 {"keypad", (PyCFunction)PyCursesWindow_keypad, METH_VARARGS},
2386 {"leaveok", (PyCFunction)PyCursesWindow_leaveok, METH_VARARGS},
2387 {"move", (PyCFunction)PyCursesWindow_wmove, METH_VARARGS},
2388 {"mvderwin", (PyCFunction)PyCursesWindow_mvderwin, METH_VARARGS},
2389 {"mvwin", (PyCFunction)PyCursesWindow_mvwin, METH_VARARGS},
2390 {"nodelay", (PyCFunction)PyCursesWindow_nodelay, METH_VARARGS},
2391 {"notimeout", (PyCFunction)PyCursesWindow_notimeout, METH_VARARGS},
2392 _CURSES_WINDOW_NOUTREFRESH_METHODDEF
2393 _CURSES_WINDOW_OVERLAY_METHODDEF
2394 _CURSES_WINDOW_OVERWRITE_METHODDEF
2395 _CURSES_WINDOW_PUTWIN_METHODDEF
2396 _CURSES_WINDOW_REDRAWLN_METHODDEF
2397 {"redrawwin", (PyCFunction)PyCursesWindow_redrawwin, METH_NOARGS},
2398 _CURSES_WINDOW_REFRESH_METHODDEF
2399 #ifndef STRICT_SYSV_CURSES
2400 {"resize", (PyCFunction)PyCursesWindow_wresize, METH_VARARGS},
2401 #endif
2402 _CURSES_WINDOW_SCROLL_METHODDEF
2403 {"scrollok", (PyCFunction)PyCursesWindow_scrollok, METH_VARARGS},
2404 _CURSES_WINDOW_SETSCRREG_METHODDEF
2405 {"standend", (PyCFunction)PyCursesWindow_wstandend, METH_NOARGS},
2406 {"standout", (PyCFunction)PyCursesWindow_wstandout, METH_NOARGS},
2407 {"subpad", (PyCFunction)_curses_window_subwin, METH_VARARGS, _curses_window_subwin__doc__},
2408 _CURSES_WINDOW_SUBWIN_METHODDEF
2409 {"syncdown", (PyCFunction)PyCursesWindow_wsyncdown, METH_NOARGS},
2410 #ifdef HAVE_CURSES_SYNCOK
2411 {"syncok", (PyCFunction)PyCursesWindow_syncok, METH_VARARGS},
2412 #endif
2413 {"syncup", (PyCFunction)PyCursesWindow_wsyncup, METH_NOARGS},
2414 {"timeout", (PyCFunction)PyCursesWindow_wtimeout, METH_VARARGS},
2415 _CURSES_WINDOW_TOUCHLINE_METHODDEF
2416 {"touchwin", (PyCFunction)PyCursesWindow_touchwin, METH_NOARGS},
2417 {"untouchwin", (PyCFunction)PyCursesWindow_untouchwin, METH_NOARGS},
2418 _CURSES_WINDOW_VLINE_METHODDEF
2419 {NULL, NULL} /* sentinel */
2420 };
2421
2422 static PyGetSetDef PyCursesWindow_getsets[] = {
2423 {"encoding",
2424 (getter)PyCursesWindow_get_encoding,
2425 (setter)PyCursesWindow_set_encoding,
2426 "the typecode character used to create the array"},
2427 {NULL, NULL, NULL, NULL } /* sentinel */
2428 };
2429
2430 /* -------------------------------------------------------*/
2431
2432 PyTypeObject PyCursesWindow_Type = {
2433 PyVarObject_HEAD_INIT(NULL, 0)
2434 "_curses.window", /*tp_name*/
2435 sizeof(PyCursesWindowObject), /*tp_basicsize*/
2436 0, /*tp_itemsize*/
2437 /* methods */
2438 (destructor)PyCursesWindow_Dealloc, /*tp_dealloc*/
2439 0, /*tp_vectorcall_offset*/
2440 (getattrfunc)0, /*tp_getattr*/
2441 (setattrfunc)0, /*tp_setattr*/
2442 0, /*tp_as_async*/
2443 0, /*tp_repr*/
2444 0, /*tp_as_number*/
2445 0, /*tp_as_sequence*/
2446 0, /*tp_as_mapping*/
2447 0, /*tp_hash*/
2448 0, /*tp_call*/
2449 0, /*tp_str*/
2450 0, /*tp_getattro*/
2451 0, /*tp_setattro*/
2452 0, /*tp_as_buffer*/
2453 Py_TPFLAGS_DEFAULT, /*tp_flags*/
2454 0, /*tp_doc*/
2455 0, /*tp_traverse*/
2456 0, /*tp_clear*/
2457 0, /*tp_richcompare*/
2458 0, /*tp_weaklistoffset*/
2459 0, /*tp_iter*/
2460 0, /*tp_iternext*/
2461 PyCursesWindow_Methods, /*tp_methods*/
2462 0, /* tp_members */
2463 PyCursesWindow_getsets, /* tp_getset */
2464 };
2465
2466 /* Function Prototype Macros - They are ugly but very, very useful. ;-)
2467
2468 X - function name
2469 TYPE - parameter Type
2470 ERGSTR - format string for construction of the return value
2471 PARSESTR - format string for argument parsing
2472 */
2473
2474 #define NoArgNoReturnFunctionBody(X) \
2475 { \
2476 PyCursesInitialised \
2477 return PyCursesCheckERR(X(), # X); }
2478
2479 #define NoArgOrFlagNoReturnFunctionBody(X, flag) \
2480 { \
2481 PyCursesInitialised \
2482 if (flag) \
2483 return PyCursesCheckERR(X(), # X); \
2484 else \
2485 return PyCursesCheckERR(no ## X(), # X); \
2486 }
2487
2488 #define NoArgReturnIntFunctionBody(X) \
2489 { \
2490 PyCursesInitialised \
2491 return PyLong_FromLong((long) X()); }
2492
2493
2494 #define NoArgReturnStringFunctionBody(X) \
2495 { \
2496 PyCursesInitialised \
2497 return PyBytes_FromString(X()); }
2498
2499 #define NoArgTrueFalseFunctionBody(X) \
2500 { \
2501 PyCursesInitialised \
2502 return PyBool_FromLong(X()); }
2503
2504 #define NoArgNoReturnVoidFunctionBody(X) \
2505 { \
2506 PyCursesInitialised \
2507 X(); \
2508 Py_RETURN_NONE; }
2509
2510 /*********************************************************************
2511 Global Functions
2512 **********************************************************************/
2513
2514 #ifdef HAVE_CURSES_FILTER
2515 /*[clinic input]
2516 _curses.filter
2517
2518 [clinic start generated code]*/
2519
2520 static PyObject *
_curses_filter_impl(PyObject * module)2521 _curses_filter_impl(PyObject *module)
2522 /*[clinic end generated code: output=fb5b8a3642eb70b5 input=668c75a6992d3624]*/
2523 {
2524 /* not checking for PyCursesInitialised here since filter() must
2525 be called before initscr() */
2526 filter();
2527 Py_RETURN_NONE;
2528 }
2529 #endif
2530
2531 /*[clinic input]
2532 _curses.baudrate
2533
2534 Return the output speed of the terminal in bits per second.
2535 [clinic start generated code]*/
2536
2537 static PyObject *
_curses_baudrate_impl(PyObject * module)2538 _curses_baudrate_impl(PyObject *module)
2539 /*[clinic end generated code: output=3c63c6c401d7d9c0 input=921f022ed04a0fd9]*/
2540 NoArgReturnIntFunctionBody(baudrate)
2541
2542 /*[clinic input]
2543 _curses.beep
2544
2545 Emit a short attention sound.
2546 [clinic start generated code]*/
2547
2548 static PyObject *
2549 _curses_beep_impl(PyObject *module)
2550 /*[clinic end generated code: output=425274962abe49a2 input=a35698ca7d0162bc]*/
2551 NoArgNoReturnFunctionBody(beep)
2552
2553 /*[clinic input]
2554 _curses.can_change_color
2555
2556 Return True if the programmer can change the colors displayed by the terminal.
2557 [clinic start generated code]*/
2558
2559 static PyObject *
2560 _curses_can_change_color_impl(PyObject *module)
2561 /*[clinic end generated code: output=359df8c3c77d8bf1 input=d7718884de0092f2]*/
2562 NoArgTrueFalseFunctionBody(can_change_color)
2563
2564 /*[clinic input]
2565 _curses.cbreak
2566
2567 flag: bool(accept={int}) = True
2568 If false, the effect is the same as calling nocbreak().
2569 /
2570
2571 Enter cbreak mode.
2572
2573 In cbreak mode (sometimes called "rare" mode) normal tty line buffering is
2574 turned off and characters are available to be read one by one. However,
2575 unlike raw mode, special characters (interrupt, quit, suspend, and flow
2576 control) retain their effects on the tty driver and calling program.
2577 Calling first raw() then cbreak() leaves the terminal in cbreak mode.
2578 [clinic start generated code]*/
2579
2580 static PyObject *
2581 _curses_cbreak_impl(PyObject *module, int flag)
2582 /*[clinic end generated code: output=9f9dee9664769751 input=150be619eb1f1458]*/
2583 NoArgOrFlagNoReturnFunctionBody(cbreak, flag)
2584
2585 /*[clinic input]
2586 _curses.color_content
2587
2588 color_number: short
2589 The number of the color (0 - COLORS).
2590 /
2591
2592 Return the red, green, and blue (RGB) components of the specified color.
2593
2594 A 3-tuple is returned, containing the R, G, B values for the given color,
2595 which will be between 0 (no component) and 1000 (maximum amount of component).
2596 [clinic start generated code]*/
2597
2598 static PyObject *
2599 _curses_color_content_impl(PyObject *module, short color_number)
2600 /*[clinic end generated code: output=cb15cf3120d4bfc1 input=5555abb1c11e11b7]*/
2601 {
2602 short r,g,b;
2603
2604 PyCursesInitialised;
2605 PyCursesInitialisedColor;
2606
2607 if (color_content(color_number, &r, &g, &b) != ERR)
2608 return Py_BuildValue("(iii)", r, g, b);
2609 else {
2610 PyErr_SetString(PyCursesError,
2611 "Argument 1 was out of range. Check value of COLORS.");
2612 return NULL;
2613 }
2614 }
2615
2616 /*[clinic input]
2617 _curses.color_pair
2618
2619 color_number: short
2620 The number of the color (0 - COLORS).
2621 /
2622
2623 Return the attribute value for displaying text in the specified color.
2624
2625 This attribute value can be combined with A_STANDOUT, A_REVERSE, and the
2626 other A_* attributes. pair_number() is the counterpart to this function.
2627 [clinic start generated code]*/
2628
2629 static PyObject *
_curses_color_pair_impl(PyObject * module,short color_number)2630 _curses_color_pair_impl(PyObject *module, short color_number)
2631 /*[clinic end generated code: output=6a84cb6b29ecaf9a input=a9d3eb6f50e4dc12]*/
2632 {
2633 PyCursesInitialised;
2634 PyCursesInitialisedColor;
2635
2636 return PyLong_FromLong(color_pair_to_attr(color_number));
2637 }
2638
2639 /*[clinic input]
2640 _curses.curs_set
2641
2642 visibility: int
2643 0 for invisible, 1 for normal visible, or 2 for very visible.
2644 /
2645
2646 Set the cursor state.
2647
2648 If the terminal supports the visibility requested, the previous cursor
2649 state is returned; otherwise, an exception is raised. On many terminals,
2650 the "visible" mode is an underline cursor and the "very visible" mode is
2651 a block cursor.
2652 [clinic start generated code]*/
2653
2654 static PyObject *
_curses_curs_set_impl(PyObject * module,int visibility)2655 _curses_curs_set_impl(PyObject *module, int visibility)
2656 /*[clinic end generated code: output=ee8e62483b1d6cd4 input=81a7924a65d29504]*/
2657 {
2658 int erg;
2659
2660 PyCursesInitialised;
2661
2662 erg = curs_set(visibility);
2663 if (erg == ERR) return PyCursesCheckERR(erg, "curs_set");
2664
2665 return PyLong_FromLong((long) erg);
2666 }
2667
2668 /*[clinic input]
2669 _curses.def_prog_mode
2670
2671 Save the current terminal mode as the "program" mode.
2672
2673 The "program" mode is the mode when the running program is using curses.
2674
2675 Subsequent calls to reset_prog_mode() will restore this mode.
2676 [clinic start generated code]*/
2677
2678 static PyObject *
_curses_def_prog_mode_impl(PyObject * module)2679 _curses_def_prog_mode_impl(PyObject *module)
2680 /*[clinic end generated code: output=05d5a351fff874aa input=768b9cace620dda5]*/
2681 NoArgNoReturnFunctionBody(def_prog_mode)
2682
2683 /*[clinic input]
2684 _curses.def_shell_mode
2685
2686 Save the current terminal mode as the "shell" mode.
2687
2688 The "shell" mode is the mode when the running program is not using curses.
2689
2690 Subsequent calls to reset_shell_mode() will restore this mode.
2691 [clinic start generated code]*/
2692
2693 static PyObject *
2694 _curses_def_shell_mode_impl(PyObject *module)
2695 /*[clinic end generated code: output=d6e42f5c768f860f input=5ead21f6f0baa894]*/
2696 NoArgNoReturnFunctionBody(def_shell_mode)
2697
2698 /*[clinic input]
2699 _curses.delay_output
2700
2701 ms: int
2702 Duration in milliseconds.
2703 /
2704
2705 Insert a pause in output.
2706 [clinic start generated code]*/
2707
2708 static PyObject *
2709 _curses_delay_output_impl(PyObject *module, int ms)
2710 /*[clinic end generated code: output=b6613a67f17fa4f4 input=5316457f5f59196c]*/
2711 {
2712 PyCursesInitialised;
2713
2714 return PyCursesCheckERR(delay_output(ms), "delay_output");
2715 }
2716
2717 /*[clinic input]
2718 _curses.doupdate
2719
2720 Update the physical screen to match the virtual screen.
2721 [clinic start generated code]*/
2722
2723 static PyObject *
_curses_doupdate_impl(PyObject * module)2724 _curses_doupdate_impl(PyObject *module)
2725 /*[clinic end generated code: output=f34536975a75680c input=8da80914432a6489]*/
2726 NoArgNoReturnFunctionBody(doupdate)
2727
2728 /*[clinic input]
2729 _curses.echo
2730
2731 flag: bool(accept={int}) = True
2732 If false, the effect is the same as calling noecho().
2733 /
2734
2735 Enter echo mode.
2736
2737 In echo mode, each character input is echoed to the screen as it is entered.
2738 [clinic start generated code]*/
2739
2740 static PyObject *
2741 _curses_echo_impl(PyObject *module, int flag)
2742 /*[clinic end generated code: output=03acb2ddfa6c8729 input=2e9e891d637eac5d]*/
2743 NoArgOrFlagNoReturnFunctionBody(echo, flag)
2744
2745 /*[clinic input]
2746 _curses.endwin
2747
2748 De-initialize the library, and return terminal to normal status.
2749 [clinic start generated code]*/
2750
2751 static PyObject *
2752 _curses_endwin_impl(PyObject *module)
2753 /*[clinic end generated code: output=c0150cd96d2f4128 input=e172cfa43062f3fa]*/
2754 NoArgNoReturnFunctionBody(endwin)
2755
2756 /*[clinic input]
2757 _curses.erasechar
2758
2759 Return the user's current erase character.
2760 [clinic start generated code]*/
2761
2762 static PyObject *
2763 _curses_erasechar_impl(PyObject *module)
2764 /*[clinic end generated code: output=3df305dc6b926b3f input=628c136c3c5758d3]*/
2765 {
2766 char ch;
2767
2768 PyCursesInitialised;
2769
2770 ch = erasechar();
2771
2772 return PyBytes_FromStringAndSize(&ch, 1);
2773 }
2774
2775 /*[clinic input]
2776 _curses.flash
2777
2778 Flash the screen.
2779
2780 That is, change it to reverse-video and then change it back in a short interval.
2781 [clinic start generated code]*/
2782
2783 static PyObject *
_curses_flash_impl(PyObject * module)2784 _curses_flash_impl(PyObject *module)
2785 /*[clinic end generated code: output=488b8a0ebd9ea9b8 input=02fdfb06c8fc3171]*/
2786 NoArgNoReturnFunctionBody(flash)
2787
2788 /*[clinic input]
2789 _curses.flushinp
2790
2791 Flush all input buffers.
2792
2793 This throws away any typeahead that has been typed by the user and has not
2794 yet been processed by the program.
2795 [clinic start generated code]*/
2796
2797 static PyObject *
2798 _curses_flushinp_impl(PyObject *module)
2799 /*[clinic end generated code: output=7e7a1fc1473960f5 input=59d042e705cef5ec]*/
2800 NoArgNoReturnVoidFunctionBody(flushinp)
2801
2802 #ifdef getsyx
2803 /*[clinic input]
2804 _curses.getsyx
2805
2806 Return the current coordinates of the virtual screen cursor.
2807
2808 Return a (y, x) tuple. If leaveok is currently true, return (-1, -1).
2809 [clinic start generated code]*/
2810
2811 static PyObject *
2812 _curses_getsyx_impl(PyObject *module)
2813 /*[clinic end generated code: output=c8e6c3f42349a038 input=9e1f862f3b4f7cba]*/
2814 {
2815 int x = 0;
2816 int y = 0;
2817
2818 PyCursesInitialised;
2819
2820 getsyx(y, x);
2821
2822 return Py_BuildValue("(ii)", y, x);
2823 }
2824 #endif
2825
2826 #ifdef NCURSES_MOUSE_VERSION
2827 /*[clinic input]
2828 _curses.getmouse
2829
2830 Retrieve the queued mouse event.
2831
2832 After getch() returns KEY_MOUSE to signal a mouse event, this function
2833 returns a 5-tuple (id, x, y, z, bstate).
2834 [clinic start generated code]*/
2835
2836 static PyObject *
_curses_getmouse_impl(PyObject * module)2837 _curses_getmouse_impl(PyObject *module)
2838 /*[clinic end generated code: output=ccf4242546b9cfa8 input=5b756ee6f5b481b1]*/
2839 {
2840 int rtn;
2841 MEVENT event;
2842
2843 PyCursesInitialised;
2844
2845 rtn = getmouse( &event );
2846 if (rtn == ERR) {
2847 PyErr_SetString(PyCursesError, "getmouse() returned ERR");
2848 return NULL;
2849 }
2850 return Py_BuildValue("(hiiik)",
2851 (short)event.id,
2852 (int)event.x, (int)event.y, (int)event.z,
2853 (unsigned long) event.bstate);
2854 }
2855
2856 /*[clinic input]
2857 _curses.ungetmouse
2858
2859 id: short
2860 x: int
2861 y: int
2862 z: int
2863 bstate: unsigned_long(bitwise=True)
2864 /
2865
2866 Push a KEY_MOUSE event onto the input queue.
2867
2868 The following getmouse() will return the given state data.
2869 [clinic start generated code]*/
2870
2871 static PyObject *
_curses_ungetmouse_impl(PyObject * module,short id,int x,int y,int z,unsigned long bstate)2872 _curses_ungetmouse_impl(PyObject *module, short id, int x, int y, int z,
2873 unsigned long bstate)
2874 /*[clinic end generated code: output=3430c9b0fc5c4341 input=fd650b2ca5a01e8f]*/
2875 {
2876 MEVENT event;
2877
2878 PyCursesInitialised;
2879
2880 event.id = id;
2881 event.x = x;
2882 event.y = y;
2883 event.z = z;
2884 event.bstate = bstate;
2885 return PyCursesCheckERR(ungetmouse(&event), "ungetmouse");
2886 }
2887 #endif
2888
2889 /*[clinic input]
2890 _curses.getwin
2891
2892 file: object
2893 /
2894
2895 Read window related data stored in the file by an earlier putwin() call.
2896
2897 The routine then creates and initializes a new window using that data,
2898 returning the new window object.
2899 [clinic start generated code]*/
2900
2901 static PyObject *
_curses_getwin(PyObject * module,PyObject * file)2902 _curses_getwin(PyObject *module, PyObject *file)
2903 /*[clinic end generated code: output=a79e0df3379af756 input=f713d2bba0e4c929]*/
2904 {
2905 FILE *fp;
2906 PyObject *data;
2907 size_t datalen;
2908 WINDOW *win;
2909 _Py_IDENTIFIER(read);
2910 PyObject *res = NULL;
2911
2912 PyCursesInitialised;
2913
2914 fp = tmpfile();
2915 if (fp == NULL)
2916 return PyErr_SetFromErrno(PyExc_OSError);
2917
2918 if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0)
2919 goto error;
2920
2921 data = _PyObject_CallMethodIdNoArgs(file, &PyId_read);
2922 if (data == NULL)
2923 goto error;
2924 if (!PyBytes_Check(data)) {
2925 PyErr_Format(PyExc_TypeError,
2926 "f.read() returned %.100s instead of bytes",
2927 Py_TYPE(data)->tp_name);
2928 Py_DECREF(data);
2929 goto error;
2930 }
2931 datalen = PyBytes_GET_SIZE(data);
2932 if (fwrite(PyBytes_AS_STRING(data), 1, datalen, fp) != datalen) {
2933 Py_DECREF(data);
2934 PyErr_SetFromErrno(PyExc_OSError);
2935 goto error;
2936 }
2937 Py_DECREF(data);
2938
2939 fseek(fp, 0, 0);
2940 win = getwin(fp);
2941 if (win == NULL) {
2942 PyErr_SetString(PyCursesError, catchall_NULL);
2943 goto error;
2944 }
2945 res = PyCursesWindow_New(win, NULL);
2946
2947 error:
2948 fclose(fp);
2949 return res;
2950 }
2951
2952 /*[clinic input]
2953 _curses.halfdelay
2954
2955 tenths: byte
2956 Maximal blocking delay in tenths of seconds (1 - 255).
2957 /
2958
2959 Enter half-delay mode.
2960
2961 Use nocbreak() to leave half-delay mode.
2962 [clinic start generated code]*/
2963
2964 static PyObject *
_curses_halfdelay_impl(PyObject * module,unsigned char tenths)2965 _curses_halfdelay_impl(PyObject *module, unsigned char tenths)
2966 /*[clinic end generated code: output=e92cdf0ef33c0663 input=e42dce7259c15100]*/
2967 {
2968 PyCursesInitialised;
2969
2970 return PyCursesCheckERR(halfdelay(tenths), "halfdelay");
2971 }
2972
2973 /*[clinic input]
2974 _curses.has_colors
2975
2976 Return True if the terminal can display colors; otherwise, return False.
2977 [clinic start generated code]*/
2978
2979 static PyObject *
_curses_has_colors_impl(PyObject * module)2980 _curses_has_colors_impl(PyObject *module)
2981 /*[clinic end generated code: output=db5667483139e3e2 input=b2ec41b739d896c6]*/
2982 NoArgTrueFalseFunctionBody(has_colors)
2983
2984 /*[clinic input]
2985 _curses.has_ic
2986
2987 Return True if the terminal has insert- and delete-character capabilities.
2988 [clinic start generated code]*/
2989
2990 static PyObject *
2991 _curses_has_ic_impl(PyObject *module)
2992 /*[clinic end generated code: output=6be24da9cb1268fe input=9bc2d3a797cc7324]*/
2993 NoArgTrueFalseFunctionBody(has_ic)
2994
2995 /*[clinic input]
2996 _curses.has_il
2997
2998 Return True if the terminal has insert- and delete-line capabilities.
2999 [clinic start generated code]*/
3000
3001 static PyObject *
3002 _curses_has_il_impl(PyObject *module)
3003 /*[clinic end generated code: output=d45bd7788ff9f5f4 input=cd939d5607ee5427]*/
3004 NoArgTrueFalseFunctionBody(has_il)
3005
3006 #ifdef HAVE_CURSES_HAS_KEY
3007 /*[clinic input]
3008 _curses.has_key
3009
3010 key: int
3011 Key number.
3012 /
3013
3014 Return True if the current terminal type recognizes a key with that value.
3015 [clinic start generated code]*/
3016
3017 static PyObject *
3018 _curses_has_key_impl(PyObject *module, int key)
3019 /*[clinic end generated code: output=19ad48319414d0b1 input=78bd44acf1a4997c]*/
3020 {
3021 PyCursesInitialised;
3022
3023 return PyBool_FromLong(has_key(key));
3024 }
3025 #endif
3026
3027 /*[clinic input]
3028 _curses.init_color
3029
3030 color_number: short
3031 The number of the color to be changed (0 - COLORS).
3032 r: short
3033 Red component (0 - 1000).
3034 g: short
3035 Green component (0 - 1000).
3036 b: short
3037 Blue component (0 - 1000).
3038 /
3039
3040 Change the definition of a color.
3041
3042 When init_color() is used, all occurrences of that color on the screen
3043 immediately change to the new definition. This function is a no-op on
3044 most terminals; it is active only if can_change_color() returns 1.
3045 [clinic start generated code]*/
3046
3047 static PyObject *
_curses_init_color_impl(PyObject * module,short color_number,short r,short g,short b)3048 _curses_init_color_impl(PyObject *module, short color_number, short r,
3049 short g, short b)
3050 /*[clinic end generated code: output=280236f5efe9776a input=f3a05bd38f619175]*/
3051 {
3052 PyCursesInitialised;
3053 PyCursesInitialisedColor;
3054
3055 return PyCursesCheckERR(init_color(color_number, r, g, b), "init_color");
3056 }
3057
3058 /*[clinic input]
3059 _curses.init_pair
3060
3061 pair_number: short
3062 The number of the color-pair to be changed (1 - (COLOR_PAIRS-1)).
3063 fg: short
3064 Foreground color number (0 - COLORS).
3065 bg: short
3066 Background color number (0 - COLORS).
3067 /
3068
3069 Change the definition of a color-pair.
3070
3071 If the color-pair was previously initialized, the screen is refreshed and
3072 all occurrences of that color-pair are changed to the new definition.
3073 [clinic start generated code]*/
3074
3075 static PyObject *
_curses_init_pair_impl(PyObject * module,short pair_number,short fg,short bg)3076 _curses_init_pair_impl(PyObject *module, short pair_number, short fg,
3077 short bg)
3078 /*[clinic end generated code: output=9c2ce39c22f376b6 input=c9f0b11b17a2ac6d]*/
3079 {
3080 PyCursesInitialised;
3081 PyCursesInitialisedColor;
3082
3083 return PyCursesCheckERR(init_pair(pair_number, fg, bg), "init_pair");
3084 }
3085
3086 static PyObject *ModDict;
3087
3088 /*[clinic input]
3089 _curses.initscr
3090
3091 Initialize the library.
3092
3093 Return a WindowObject which represents the whole screen.
3094 [clinic start generated code]*/
3095
3096 static PyObject *
_curses_initscr_impl(PyObject * module)3097 _curses_initscr_impl(PyObject *module)
3098 /*[clinic end generated code: output=619fb68443810b7b input=514f4bce1821f6b5]*/
3099 {
3100 WINDOW *win;
3101 PyCursesWindowObject *winobj;
3102
3103 if (initialised) {
3104 wrefresh(stdscr);
3105 return (PyObject *)PyCursesWindow_New(stdscr, NULL);
3106 }
3107
3108 win = initscr();
3109
3110 if (win == NULL) {
3111 PyErr_SetString(PyCursesError, catchall_NULL);
3112 return NULL;
3113 }
3114
3115 initialised = initialised_setupterm = TRUE;
3116
3117 /* This was moved from initcurses() because it core dumped on SGI,
3118 where they're not defined until you've called initscr() */
3119 #define SetDictInt(string,ch) \
3120 do { \
3121 PyObject *o = PyLong_FromLong((long) (ch)); \
3122 if (o && PyDict_SetItemString(ModDict, string, o) == 0) { \
3123 Py_DECREF(o); \
3124 } \
3125 } while (0)
3126
3127 /* Here are some graphic symbols you can use */
3128 SetDictInt("ACS_ULCORNER", (ACS_ULCORNER));
3129 SetDictInt("ACS_LLCORNER", (ACS_LLCORNER));
3130 SetDictInt("ACS_URCORNER", (ACS_URCORNER));
3131 SetDictInt("ACS_LRCORNER", (ACS_LRCORNER));
3132 SetDictInt("ACS_LTEE", (ACS_LTEE));
3133 SetDictInt("ACS_RTEE", (ACS_RTEE));
3134 SetDictInt("ACS_BTEE", (ACS_BTEE));
3135 SetDictInt("ACS_TTEE", (ACS_TTEE));
3136 SetDictInt("ACS_HLINE", (ACS_HLINE));
3137 SetDictInt("ACS_VLINE", (ACS_VLINE));
3138 SetDictInt("ACS_PLUS", (ACS_PLUS));
3139 #if !defined(__hpux) || defined(HAVE_NCURSES_H)
3140 /* On HP/UX 11, these are of type cchar_t, which is not an
3141 integral type. If this is a problem on more platforms, a
3142 configure test should be added to determine whether ACS_S1
3143 is of integral type. */
3144 SetDictInt("ACS_S1", (ACS_S1));
3145 SetDictInt("ACS_S9", (ACS_S9));
3146 SetDictInt("ACS_DIAMOND", (ACS_DIAMOND));
3147 SetDictInt("ACS_CKBOARD", (ACS_CKBOARD));
3148 SetDictInt("ACS_DEGREE", (ACS_DEGREE));
3149 SetDictInt("ACS_PLMINUS", (ACS_PLMINUS));
3150 SetDictInt("ACS_BULLET", (ACS_BULLET));
3151 SetDictInt("ACS_LARROW", (ACS_LARROW));
3152 SetDictInt("ACS_RARROW", (ACS_RARROW));
3153 SetDictInt("ACS_DARROW", (ACS_DARROW));
3154 SetDictInt("ACS_UARROW", (ACS_UARROW));
3155 SetDictInt("ACS_BOARD", (ACS_BOARD));
3156 SetDictInt("ACS_LANTERN", (ACS_LANTERN));
3157 SetDictInt("ACS_BLOCK", (ACS_BLOCK));
3158 #endif
3159 SetDictInt("ACS_BSSB", (ACS_ULCORNER));
3160 SetDictInt("ACS_SSBB", (ACS_LLCORNER));
3161 SetDictInt("ACS_BBSS", (ACS_URCORNER));
3162 SetDictInt("ACS_SBBS", (ACS_LRCORNER));
3163 SetDictInt("ACS_SBSS", (ACS_RTEE));
3164 SetDictInt("ACS_SSSB", (ACS_LTEE));
3165 SetDictInt("ACS_SSBS", (ACS_BTEE));
3166 SetDictInt("ACS_BSSS", (ACS_TTEE));
3167 SetDictInt("ACS_BSBS", (ACS_HLINE));
3168 SetDictInt("ACS_SBSB", (ACS_VLINE));
3169 SetDictInt("ACS_SSSS", (ACS_PLUS));
3170
3171 /* The following are never available with strict SYSV curses */
3172 #ifdef ACS_S3
3173 SetDictInt("ACS_S3", (ACS_S3));
3174 #endif
3175 #ifdef ACS_S7
3176 SetDictInt("ACS_S7", (ACS_S7));
3177 #endif
3178 #ifdef ACS_LEQUAL
3179 SetDictInt("ACS_LEQUAL", (ACS_LEQUAL));
3180 #endif
3181 #ifdef ACS_GEQUAL
3182 SetDictInt("ACS_GEQUAL", (ACS_GEQUAL));
3183 #endif
3184 #ifdef ACS_PI
3185 SetDictInt("ACS_PI", (ACS_PI));
3186 #endif
3187 #ifdef ACS_NEQUAL
3188 SetDictInt("ACS_NEQUAL", (ACS_NEQUAL));
3189 #endif
3190 #ifdef ACS_STERLING
3191 SetDictInt("ACS_STERLING", (ACS_STERLING));
3192 #endif
3193
3194 SetDictInt("LINES", LINES);
3195 SetDictInt("COLS", COLS);
3196
3197 winobj = (PyCursesWindowObject *)PyCursesWindow_New(win, NULL);
3198 screen_encoding = winobj->encoding;
3199 return (PyObject *)winobj;
3200 }
3201
3202 /*[clinic input]
3203 _curses.setupterm
3204
3205 term: str(accept={str, NoneType}) = None
3206 Terminal name.
3207 If omitted, the value of the TERM environment variable will be used.
3208 fd: int = -1
3209 File descriptor to which any initialization sequences will be sent.
3210 If not supplied, the file descriptor for sys.stdout will be used.
3211
3212 Initialize the terminal.
3213 [clinic start generated code]*/
3214
3215 static PyObject *
_curses_setupterm_impl(PyObject * module,const char * term,int fd)3216 _curses_setupterm_impl(PyObject *module, const char *term, int fd)
3217 /*[clinic end generated code: output=4584e587350f2848 input=4511472766af0c12]*/
3218 {
3219 int err;
3220
3221 if (fd == -1) {
3222 PyObject* sys_stdout;
3223
3224 sys_stdout = PySys_GetObject("stdout");
3225
3226 if (sys_stdout == NULL || sys_stdout == Py_None) {
3227 PyErr_SetString(
3228 PyCursesError,
3229 "lost sys.stdout");
3230 return NULL;
3231 }
3232
3233 fd = PyObject_AsFileDescriptor(sys_stdout);
3234
3235 if (fd == -1) {
3236 return NULL;
3237 }
3238 }
3239
3240 if (!initialised_setupterm && setupterm((char *)term, fd, &err) == ERR) {
3241 const char* s = "setupterm: unknown error";
3242
3243 if (err == 0) {
3244 s = "setupterm: could not find terminal";
3245 } else if (err == -1) {
3246 s = "setupterm: could not find terminfo database";
3247 }
3248
3249 PyErr_SetString(PyCursesError,s);
3250 return NULL;
3251 }
3252
3253 initialised_setupterm = TRUE;
3254
3255 Py_RETURN_NONE;
3256 }
3257
3258 #if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20081102
3259 // https://invisible-island.net/ncurses/NEWS.html#index-t20080119
3260
3261 /*[clinic input]
3262 _curses.get_escdelay
3263
3264 Gets the curses ESCDELAY setting.
3265
3266 Gets the number of milliseconds to wait after reading an escape character,
3267 to distinguish between an individual escape character entered on the
3268 keyboard from escape sequences sent by cursor and function keys.
3269 [clinic start generated code]*/
3270
3271 static PyObject *
_curses_get_escdelay_impl(PyObject * module)3272 _curses_get_escdelay_impl(PyObject *module)
3273 /*[clinic end generated code: output=222fa1a822555d60 input=be2d5b3dd974d0a4]*/
3274 {
3275 return PyLong_FromLong(ESCDELAY);
3276 }
3277 /*[clinic input]
3278 _curses.set_escdelay
3279 ms: int
3280 length of the delay in milliseconds.
3281 /
3282
3283 Sets the curses ESCDELAY setting.
3284
3285 Sets the number of milliseconds to wait after reading an escape character,
3286 to distinguish between an individual escape character entered on the
3287 keyboard from escape sequences sent by cursor and function keys.
3288 [clinic start generated code]*/
3289
3290 static PyObject *
_curses_set_escdelay_impl(PyObject * module,int ms)3291 _curses_set_escdelay_impl(PyObject *module, int ms)
3292 /*[clinic end generated code: output=43818efbf7980ac4 input=7796fe19f111e250]*/
3293 {
3294 if (ms <= 0) {
3295 PyErr_SetString(PyExc_ValueError, "ms must be > 0");
3296 return NULL;
3297 }
3298
3299 return PyCursesCheckERR(set_escdelay(ms), "set_escdelay");
3300 }
3301
3302 /*[clinic input]
3303 _curses.get_tabsize
3304
3305 Gets the curses TABSIZE setting.
3306
3307 Gets the number of columns used by the curses library when converting a tab
3308 character to spaces as it adds the tab to a window.
3309 [clinic start generated code]*/
3310
3311 static PyObject *
_curses_get_tabsize_impl(PyObject * module)3312 _curses_get_tabsize_impl(PyObject *module)
3313 /*[clinic end generated code: output=7e9e51fb6126fbdf input=74af86bf6c9f5d7e]*/
3314 {
3315 return PyLong_FromLong(TABSIZE);
3316 }
3317 /*[clinic input]
3318 _curses.set_tabsize
3319 size: int
3320 rendered cell width of a tab character.
3321 /
3322
3323 Sets the curses TABSIZE setting.
3324
3325 Sets the number of columns used by the curses library when converting a tab
3326 character to spaces as it adds the tab to a window.
3327 [clinic start generated code]*/
3328
3329 static PyObject *
_curses_set_tabsize_impl(PyObject * module,int size)3330 _curses_set_tabsize_impl(PyObject *module, int size)
3331 /*[clinic end generated code: output=c1de5a76c0daab1e input=78cba6a3021ad061]*/
3332 {
3333 if (size <= 0) {
3334 PyErr_SetString(PyExc_ValueError, "size must be > 0");
3335 return NULL;
3336 }
3337
3338 return PyCursesCheckERR(set_tabsize(size), "set_tabsize");
3339 }
3340 #endif
3341
3342 /*[clinic input]
3343 _curses.intrflush
3344
3345 flag: bool(accept={int})
3346 /
3347
3348 [clinic start generated code]*/
3349
3350 static PyObject *
_curses_intrflush_impl(PyObject * module,int flag)3351 _curses_intrflush_impl(PyObject *module, int flag)
3352 /*[clinic end generated code: output=c1986df35e999a0f input=fcba57bb28dfd795]*/
3353 {
3354 PyCursesInitialised;
3355
3356 return PyCursesCheckERR(intrflush(NULL, flag), "intrflush");
3357 }
3358
3359 /*[clinic input]
3360 _curses.isendwin
3361
3362 Return True if endwin() has been called.
3363 [clinic start generated code]*/
3364
3365 static PyObject *
_curses_isendwin_impl(PyObject * module)3366 _curses_isendwin_impl(PyObject *module)
3367 /*[clinic end generated code: output=d73179e4a7e1eb8c input=6cdb01a7ebf71397]*/
3368 NoArgTrueFalseFunctionBody(isendwin)
3369
3370 #ifdef HAVE_CURSES_IS_TERM_RESIZED
3371 /*[clinic input]
3372 _curses.is_term_resized
3373
3374 nlines: int
3375 Height.
3376 ncols: int
3377 Width.
3378 /
3379
3380 Return True if resize_term() would modify the window structure, False otherwise.
3381 [clinic start generated code]*/
3382
3383 static PyObject *
3384 _curses_is_term_resized_impl(PyObject *module, int nlines, int ncols)
3385 /*[clinic end generated code: output=aafe04afe50f1288 input=ca9c0bd0fb8ab444]*/
3386 {
3387 PyCursesInitialised;
3388
3389 return PyBool_FromLong(is_term_resized(nlines, ncols));
3390 }
3391 #endif /* HAVE_CURSES_IS_TERM_RESIZED */
3392
3393 /*[clinic input]
3394 _curses.keyname
3395
3396 key: int
3397 Key number.
3398 /
3399
3400 Return the name of specified key.
3401 [clinic start generated code]*/
3402
3403 static PyObject *
_curses_keyname_impl(PyObject * module,int key)3404 _curses_keyname_impl(PyObject *module, int key)
3405 /*[clinic end generated code: output=fa2675ab3f4e056b input=ee4b1d0f243a2a2b]*/
3406 {
3407 const char *knp;
3408
3409 PyCursesInitialised;
3410
3411 if (key < 0) {
3412 PyErr_SetString(PyExc_ValueError, "invalid key number");
3413 return NULL;
3414 }
3415 knp = keyname(key);
3416
3417 return PyBytes_FromString((knp == NULL) ? "" : knp);
3418 }
3419
3420 /*[clinic input]
3421 _curses.killchar
3422
3423 Return the user's current line kill character.
3424 [clinic start generated code]*/
3425
3426 static PyObject *
_curses_killchar_impl(PyObject * module)3427 _curses_killchar_impl(PyObject *module)
3428 /*[clinic end generated code: output=31c3a45b2c528269 input=1ff171c38df5ccad]*/
3429 {
3430 char ch;
3431
3432 ch = killchar();
3433
3434 return PyBytes_FromStringAndSize(&ch, 1);
3435 }
3436
3437 /*[clinic input]
3438 _curses.longname
3439
3440 Return the terminfo long name field describing the current terminal.
3441
3442 The maximum length of a verbose description is 128 characters. It is defined
3443 only after the call to initscr().
3444 [clinic start generated code]*/
3445
3446 static PyObject *
_curses_longname_impl(PyObject * module)3447 _curses_longname_impl(PyObject *module)
3448 /*[clinic end generated code: output=fdf30433727ef568 input=84c3f20201b1098e]*/
3449 NoArgReturnStringFunctionBody(longname)
3450
3451 /*[clinic input]
3452 _curses.meta
3453
3454 yes: bool(accept={int})
3455 /
3456
3457 Enable/disable meta keys.
3458
3459 If yes is True, allow 8-bit characters to be input. If yes is False,
3460 allow only 7-bit characters.
3461 [clinic start generated code]*/
3462
3463 static PyObject *
3464 _curses_meta_impl(PyObject *module, int yes)
3465 /*[clinic end generated code: output=22f5abda46a605d8 input=af9892e3a74f35db]*/
3466 {
3467 PyCursesInitialised;
3468
3469 return PyCursesCheckERR(meta(stdscr, yes), "meta");
3470 }
3471
3472 #ifdef NCURSES_MOUSE_VERSION
3473 /*[clinic input]
3474 _curses.mouseinterval
3475
3476 interval: int
3477 Time in milliseconds.
3478 /
3479
3480 Set and retrieve the maximum time between press and release in a click.
3481
3482 Set the maximum time that can elapse between press and release events in
3483 order for them to be recognized as a click, and return the previous interval
3484 value.
3485 [clinic start generated code]*/
3486
3487 static PyObject *
_curses_mouseinterval_impl(PyObject * module,int interval)3488 _curses_mouseinterval_impl(PyObject *module, int interval)
3489 /*[clinic end generated code: output=c4f5ff04354634c5 input=75aaa3f0db10ac4e]*/
3490 {
3491 PyCursesInitialised;
3492
3493 return PyCursesCheckERR(mouseinterval(interval), "mouseinterval");
3494 }
3495
3496 /*[clinic input]
3497 _curses.mousemask
3498
3499 newmask: unsigned_long(bitwise=True)
3500 /
3501
3502 Set the mouse events to be reported, and return a tuple (availmask, oldmask).
3503
3504 Return a tuple (availmask, oldmask). availmask indicates which of the
3505 specified mouse events can be reported; on complete failure it returns 0.
3506 oldmask is the previous value of the given window's mouse event mask.
3507 If this function is never called, no mouse events are ever reported.
3508 [clinic start generated code]*/
3509
3510 static PyObject *
_curses_mousemask_impl(PyObject * module,unsigned long newmask)3511 _curses_mousemask_impl(PyObject *module, unsigned long newmask)
3512 /*[clinic end generated code: output=9406cf1b8a36e485 input=bdf76b7568a3c541]*/
3513 {
3514 mmask_t oldmask, availmask;
3515
3516 PyCursesInitialised;
3517 availmask = mousemask((mmask_t)newmask, &oldmask);
3518 return Py_BuildValue("(kk)",
3519 (unsigned long)availmask, (unsigned long)oldmask);
3520 }
3521 #endif
3522
3523 /*[clinic input]
3524 _curses.napms
3525
3526 ms: int
3527 Duration in milliseconds.
3528 /
3529
3530 Sleep for specified time.
3531 [clinic start generated code]*/
3532
3533 static PyObject *
_curses_napms_impl(PyObject * module,int ms)3534 _curses_napms_impl(PyObject *module, int ms)
3535 /*[clinic end generated code: output=a40a1da2e39ea438 input=20cd3af2b6900f56]*/
3536 {
3537 PyCursesInitialised;
3538
3539 return Py_BuildValue("i", napms(ms));
3540 }
3541
3542
3543 /*[clinic input]
3544 _curses.newpad
3545
3546 nlines: int
3547 Height.
3548 ncols: int
3549 Width.
3550 /
3551
3552 Create and return a pointer to a new pad data structure.
3553 [clinic start generated code]*/
3554
3555 static PyObject *
_curses_newpad_impl(PyObject * module,int nlines,int ncols)3556 _curses_newpad_impl(PyObject *module, int nlines, int ncols)
3557 /*[clinic end generated code: output=de52a56eb1098ec9 input=93f1272f240d8894]*/
3558 {
3559 WINDOW *win;
3560
3561 PyCursesInitialised;
3562
3563 win = newpad(nlines, ncols);
3564
3565 if (win == NULL) {
3566 PyErr_SetString(PyCursesError, catchall_NULL);
3567 return NULL;
3568 }
3569
3570 return (PyObject *)PyCursesWindow_New(win, NULL);
3571 }
3572
3573 /*[clinic input]
3574 _curses.newwin
3575
3576 nlines: int
3577 Height.
3578 ncols: int
3579 Width.
3580 [
3581 begin_y: int = 0
3582 Top side y-coordinate.
3583 begin_x: int = 0
3584 Left side x-coordinate.
3585 ]
3586 /
3587
3588 Return a new window.
3589
3590 By default, the window will extend from the specified position to the lower
3591 right corner of the screen.
3592 [clinic start generated code]*/
3593
3594 static PyObject *
_curses_newwin_impl(PyObject * module,int nlines,int ncols,int group_right_1,int begin_y,int begin_x)3595 _curses_newwin_impl(PyObject *module, int nlines, int ncols,
3596 int group_right_1, int begin_y, int begin_x)
3597 /*[clinic end generated code: output=c1e0a8dc8ac2826c input=29312c15a72a003d]*/
3598 {
3599 WINDOW *win;
3600
3601 PyCursesInitialised;
3602
3603 win = newwin(nlines,ncols,begin_y,begin_x);
3604 if (win == NULL) {
3605 PyErr_SetString(PyCursesError, catchall_NULL);
3606 return NULL;
3607 }
3608
3609 return (PyObject *)PyCursesWindow_New(win, NULL);
3610 }
3611
3612 /*[clinic input]
3613 _curses.nl
3614
3615 flag: bool(accept={int}) = True
3616 If false, the effect is the same as calling nonl().
3617 /
3618
3619 Enter newline mode.
3620
3621 This mode translates the return key into newline on input, and translates
3622 newline into return and line-feed on output. Newline mode is initially on.
3623 [clinic start generated code]*/
3624
3625 static PyObject *
_curses_nl_impl(PyObject * module,int flag)3626 _curses_nl_impl(PyObject *module, int flag)
3627 /*[clinic end generated code: output=b39cc0ffc9015003 input=cf36a63f7b86e28a]*/
3628 NoArgOrFlagNoReturnFunctionBody(nl, flag)
3629
3630 /*[clinic input]
3631 _curses.nocbreak
3632
3633 Leave cbreak mode.
3634
3635 Return to normal "cooked" mode with line buffering.
3636 [clinic start generated code]*/
3637
3638 static PyObject *
3639 _curses_nocbreak_impl(PyObject *module)
3640 /*[clinic end generated code: output=eabf3833a4fbf620 input=e4b65f7d734af400]*/
3641 NoArgNoReturnFunctionBody(nocbreak)
3642
3643 /*[clinic input]
3644 _curses.noecho
3645
3646 Leave echo mode.
3647
3648 Echoing of input characters is turned off.
3649 [clinic start generated code]*/
3650
3651 static PyObject *
3652 _curses_noecho_impl(PyObject *module)
3653 /*[clinic end generated code: output=cc95ab45bc98f41b input=76714df529e614c3]*/
3654 NoArgNoReturnFunctionBody(noecho)
3655
3656 /*[clinic input]
3657 _curses.nonl
3658
3659 Leave newline mode.
3660
3661 Disable translation of return into newline on input, and disable low-level
3662 translation of newline into newline/return on output.
3663 [clinic start generated code]*/
3664
3665 static PyObject *
3666 _curses_nonl_impl(PyObject *module)
3667 /*[clinic end generated code: output=99e917e9715770c6 input=9d37dd122d3022fc]*/
3668 NoArgNoReturnFunctionBody(nonl)
3669
3670 /*[clinic input]
3671 _curses.noqiflush
3672
3673 Disable queue flushing.
3674
3675 When queue flushing is disabled, normal flush of input and output queues
3676 associated with the INTR, QUIT and SUSP characters will not be done.
3677 [clinic start generated code]*/
3678
3679 static PyObject *
3680 _curses_noqiflush_impl(PyObject *module)
3681 /*[clinic end generated code: output=8b95a4229bbf0877 input=ba3e6b2e3e54c4df]*/
3682 NoArgNoReturnVoidFunctionBody(noqiflush)
3683
3684 /*[clinic input]
3685 _curses.noraw
3686
3687 Leave raw mode.
3688
3689 Return to normal "cooked" mode with line buffering.
3690 [clinic start generated code]*/
3691
3692 static PyObject *
3693 _curses_noraw_impl(PyObject *module)
3694 /*[clinic end generated code: output=39894e5524c430cc input=6ec86692096dffb5]*/
3695 NoArgNoReturnFunctionBody(noraw)
3696
3697 /*[clinic input]
3698 _curses.pair_content
3699
3700 pair_number: short
3701 The number of the color pair (1 - (COLOR_PAIRS-1)).
3702 /
3703
3704 Return a tuple (fg, bg) containing the colors for the requested color pair.
3705 [clinic start generated code]*/
3706
3707 static PyObject *
3708 _curses_pair_content_impl(PyObject *module, short pair_number)
3709 /*[clinic end generated code: output=5a72aa1a28bbacf3 input=f4d7fec5643b976b]*/
3710 {
3711 short f, b;
3712
3713 PyCursesInitialised;
3714 PyCursesInitialisedColor;
3715
3716 if (pair_content(pair_number, &f, &b)==ERR) {
3717 PyErr_SetString(PyCursesError,
3718 "Argument 1 was out of range. (1..COLOR_PAIRS-1)");
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(attr_to_color_pair(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