@@ -356,6 +356,35 @@ _PyCursesStatefulCheckFunction(PyObject *module,
356356 return 0 ;
357357}
358358
359+ /*
360+ * Function to check that the current screen has a terminal, by testing
361+ * stdscr, which a screen made by new_prescr() does not have. If an error
362+ * occurs, a PyCursesError is set and this returns 0. Otherwise this
363+ * returns 1.
364+ */
365+ static int
366+ _PyCursesStatefulCheckTerminal (PyObject * module )
367+ {
368+ if (stdscr != NULL ) {
369+ return 1 ;
370+ }
371+ cursesmodule_state * state = get_cursesmodule_state (module );
372+ PyErr_SetString (state -> error , "the current screen has no terminal" );
373+ return 0 ;
374+ }
375+
376+ /* Same as _PyCursesStatefulCheckTerminal() for a Window object. */
377+ static int
378+ curses_window_check_terminal (PyCursesWindowObject * win )
379+ {
380+ if (stdscr != NULL ) {
381+ return 1 ;
382+ }
383+ cursesmodule_state * state = get_cursesmodule_state_by_win (win );
384+ PyErr_SetString (state -> error , "the current screen has no terminal" );
385+ return 0 ;
386+ }
387+
359388#define PyCursesStatefulSetupTermCalled (MODULE ) \
360389 do { \
361390 if (!_PyCursesStatefulCheckFunction(MODULE, \
@@ -370,7 +399,8 @@ _PyCursesStatefulCheckFunction(PyObject *module,
370399 do { \
371400 if (!_PyCursesStatefulCheckFunction(MODULE, \
372401 curses_initscr_called, \
373- "initscr")) \
402+ "initscr") \
403+ || !_PyCursesStatefulCheckTerminal(MODULE)) \
374404 { \
375405 return 0; \
376406 } \
@@ -1793,6 +1823,42 @@ curses_window_put_cells(PyCursesWindowObject *self, PyObject *obj,
17931823 Py_RETURN_NONE; \
17941824 }
17951825
1826+ /* Same as Window_OneArgNoReturnVoidFunction() for a function that needs
1827+ a terminal. */
1828+ #define Window_OneArgNoReturnVoidTerminalFunction (X , TYPE , PARSESTR ) \
1829+ static PyObject * PyCursesWindow_ ## X \
1830+ (PyObject *op, PyObject *args) \
1831+ { \
1832+ TYPE arg1; \
1833+ if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) { \
1834+ return NULL; \
1835+ } \
1836+ PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op); \
1837+ if (!curses_window_check_terminal(self)) { \
1838+ return NULL; \
1839+ } \
1840+ X(self->win, arg1); \
1841+ Py_RETURN_NONE; \
1842+ }
1843+
1844+ /* Same as Window_OneArgNoReturnFunction() for a function that needs
1845+ a terminal. */
1846+ #define Window_OneArgNoReturnTerminalFunction (X , TYPE , PARSESTR ) \
1847+ static PyObject * PyCursesWindow_ ## X \
1848+ (PyObject *op, PyObject *args) \
1849+ { \
1850+ TYPE arg1; \
1851+ if (!PyArg_ParseTuple(args, PARSESTR, &arg1)) { \
1852+ return NULL; \
1853+ } \
1854+ PyCursesWindowObject *self = _PyCursesWindowObject_CAST(op); \
1855+ if (!curses_window_check_terminal(self)) { \
1856+ return NULL; \
1857+ } \
1858+ int code = X(self->win, arg1); \
1859+ return curses_window_check_err(self, code, # X, NULL); \
1860+ }
1861+
17961862#define Window_OneArgNoReturnFunction (X , TYPE , PARSESTR ) \
17971863 static PyObject * PyCursesWindow_ ## X \
17981864 (PyObject *op, PyObject *args) \
@@ -1893,7 +1959,7 @@ Window_NoArgNoReturnVoidFunction(wclrtoeol)
18931959Window_NoArgNoReturnVoidFunction (wclrtobot )
18941960Window_NoArgNoReturnVoidFunction (wclear )
18951961
1896- Window_OneArgNoReturnVoidFunction (idcok , int , "i;True(1) or False(0)" )
1962+ Window_OneArgNoReturnVoidTerminalFunction (idcok , int , "i;True(1) or False(0)" )
18971963#ifdef HAVE_CURSES_IMMEDOK
18981964Window_OneArgNoReturnVoidFunction (immedok , int , "i;True(1) or False(0)" )
18991965#endif
@@ -1905,8 +1971,8 @@ Window_NoArg2TupleReturnFunction(getmaxyx, int, "ii")
19051971Window_NoArg2TupleReturnFunction (getparyx , int , "ii" )
19061972
19071973Window_OneArgNoReturnFunction (clearok , int , "i;True(1) or False(0)" )
1908- Window_OneArgNoReturnFunction (idlok , int , "i;True(1) or False(0)" )
1909- Window_OneArgNoReturnFunction (keypad , int , "i;True(1) or False(0)" )
1974+ Window_OneArgNoReturnTerminalFunction (idlok , int , "i;True(1) or False(0)" )
1975+ Window_OneArgNoReturnTerminalFunction (keypad , int , "i;True(1) or False(0)" )
19101976Window_OneArgNoReturnFunction (leaveok , int , "i;True(1) or False(0)" )
19111977Window_OneArgNoReturnFunction (nodelay , int , "i;True(1) or False(0)" )
19121978Window_OneArgNoReturnFunction (notimeout , int , "i;True(1) or False(0)" )
@@ -2960,6 +3026,10 @@ _curses_window_echochar_impl(PyCursesWindowObject *self, PyObject *ch,
29603026 int group_right_1 , attr_t attr )
29613027/*[clinic end generated code: output=ab03afa580aa6a2a input=cd74c42aadcc7e30]*/
29623028{
3029+ if (!curses_window_check_terminal (self )) {
3030+ return NULL ;
3031+ }
3032+
29633033 chtype ch_ ;
29643034#ifdef HAVE_NCURSESW
29653035 cchar_t wch ;
@@ -3206,6 +3276,10 @@ _curses_window_getch_impl(PyCursesWindowObject *self, int group_right_1,
32063276{
32073277 int rtn ;
32083278
3279+ if (!curses_window_check_terminal (self )) {
3280+ return NULL ;
3281+ }
3282+
32093283 Py_BEGIN_ALLOW_THREADS
32103284 if (!group_right_1 ) {
32113285 rtn = wgetch (self -> win );
@@ -3254,6 +3328,10 @@ _curses_window_getkey_impl(PyCursesWindowObject *self, int group_right_1,
32543328{
32553329 int rtn ;
32563330
3331+ if (!curses_window_check_terminal (self )) {
3332+ return NULL ;
3333+ }
3334+
32573335 Py_BEGIN_ALLOW_THREADS
32583336 if (!group_right_1 ) {
32593337 rtn = wgetch (self -> win );
@@ -3305,6 +3383,10 @@ _curses_window_get_wch_impl(PyCursesWindowObject *self, int group_right_1,
33053383 int y , int x )
33063384/*[clinic end generated code: output=9f4f86e91fe50ef3 input=dd7e5367fb49dc48]*/
33073385{
3386+ if (!curses_window_check_terminal (self )) {
3387+ return NULL ;
3388+ }
3389+
33083390#ifdef HAVE_NCURSESW
33093391 int ct ;
33103392 wint_t rtn ;
@@ -3454,6 +3536,10 @@ static PyObject *
34543536PyCursesWindow_getstr (PyObject * op , PyObject * args )
34553537{
34563538 PyCursesWindowObject * self = _PyCursesWindowObject_CAST (op );
3539+
3540+ if (!curses_window_check_terminal (self )) {
3541+ return NULL ;
3542+ }
34573543 return curses_window_getstr_bytes (self , args , "_curses.window.getstr" );
34583544}
34593545
@@ -3755,6 +3841,10 @@ static PyObject *
37553841PyCursesWindow_get_wstr (PyObject * op , PyObject * args )
37563842{
37573843 PyCursesWindowObject * self = _PyCursesWindowObject_CAST (op );
3844+
3845+ if (!curses_window_check_terminal (self )) {
3846+ return NULL ;
3847+ }
37583848#ifdef HAVE_NCURSESW
37593849 int rtn , use_xy = 0 , y = 0 , x = 0 ;
37603850 unsigned int max_buf_size = 2048 ;
@@ -4271,6 +4361,10 @@ _curses_window_noutrefresh_impl(PyCursesWindowObject *self)
42714361{
42724362 int rtn ;
42734363
4364+ if (!curses_window_check_terminal (self )) {
4365+ return NULL ;
4366+ }
4367+
42744368#ifdef py_is_pad
42754369 if (py_is_pad (self -> win )) {
42764370 if (!group_right_1 ) {
@@ -4501,6 +4595,10 @@ _curses_window_refresh_impl(PyCursesWindowObject *self, int group_right_1,
45014595{
45024596 int rtn ;
45034597
4598+ if (!curses_window_check_terminal (self )) {
4599+ return NULL ;
4600+ }
4601+
45044602#ifdef py_is_pad
45054603 if (py_is_pad (self -> win )) {
45064604 if (!group_right_1 ) {
0 commit comments