@@ -44,12 +44,11 @@ unsupported functions:
4444 mcprint mvaddchnstr mvaddchstr mvchgat mvcur mvinchnstr
4545 mvinchstr mvinnstr mmvwaddchnstr mvwaddchstr mvwchgat
4646 mvwgetnstr mvwinchnstr mvwinchstr mvwinnstr napms newterm
47- overlay overwrite resetty resizeterm restartterm ripoffline
48- savetty scr_dump scr_init scr_restore scr_set scrl set_curterm
49- set_term setterm setupterm tgetent tgetflag tgetnum tgetstr
50- tgoto timeout tputs typeahead use_default_colors vidattr
51- vidputs waddchnstr waddchstr wchgat wcolor_set winchnstr
52- winchstr winnstr wmouse_trafo wredrawln wscrl wtimeout
47+ overlay overwrite resizeterm restartterm ripoffline scr_dump
48+ scr_init scr_restore scr_set scrl set_curterm set_term setterm
49+ tgetent tgetflag tgetnum tgetstr tgoto timeout tputs
50+ use_default_colors vidattr vidputs waddchnstr waddchstr wchgat
51+ wcolor_set winchnstr winchstr winnstr wmouse_trafo wscrl
5352
5453Low-priority:
5554 slk_attr slk_attr_off slk_attr_on slk_attr_set slk_attroff
@@ -77,11 +76,12 @@ char *PyCursesVersion = "1.6";
7776#include <curses.h>
7877#endif
7978
79+ /* These prototypes are in <term.h>, but including this header
80+ #defines many common symbols (such as "lines") which breaks the
81+ curses module in other ways. So the code will just specify
82+ explicit prototypes here. */
83+ extern int setupterm (char * ,int ,int * );
8084#ifdef sgi
81- /* This prototype is in <term.h>, but including this header #defines
82- many common symbols (such as "lines") which breaks the curses
83- module in other ways. So the code will just specify an explicit
84- prototype here. */
8585extern char * tigetstr (char * );
8686#endif
8787
@@ -98,6 +98,9 @@ static PyObject *PyCursesError;
9898static char * catchall_ERR = "curses function returned ERR" ;
9999static char * catchall_NULL = "curses function returned NULL" ;
100100
101+ /* Tells whether setupterm() has been called to initialise terminfo. */
102+ static int initialised_setupterm = FALSE;
103+
101104/* Tells whether initscr() has been called to initialise curses. */
102105static int initialised = FALSE;
103106
@@ -108,6 +111,12 @@ static int initialisedcolors = FALSE;
108111#define ARG_COUNT (X ) \
109112 (((X) == NULL) ? 0 : (PyTuple_Check(X) ? PyTuple_Size(X) : 1))
110113
114+ #define PyCursesSetupTermCalled \
115+ if (initialised_setupterm != TRUE) { \
116+ PyErr_SetString(PyCursesError, \
117+ "must call (at least) setupterm() first"); \
118+ return NULL; }
119+
111120#define PyCursesInitialised \
112121 if (initialised != TRUE) { \
113122 PyErr_SetString(PyCursesError, \
@@ -1702,7 +1711,7 @@ PyCurses_InitScr(PyObject *self, PyObject *args)
17021711 return NULL ;
17031712 }
17041713
1705- initialised = TRUE;
1714+ initialised = initialised_setupterm = TRUE;
17061715
17071716/* This was moved from initcurses() because it core dumped on SGI,
17081717 where they're not defined until you've called initscr() */
@@ -1780,6 +1789,57 @@ PyCurses_InitScr(PyObject *self, PyObject *args)
17801789 return (PyObject * )PyCursesWindow_New (win );
17811790}
17821791
1792+ static PyObject *
1793+ PyCurses_setupterm (PyObject * self , PyObject * args , PyObject * keywds )
1794+ {
1795+ int fd = -1 ;
1796+ int err ;
1797+ char * termstr = NULL ;
1798+
1799+ static char * kwlist [] = {"term" , "fd" , NULL };
1800+
1801+ if (!PyArg_ParseTupleAndKeywords (
1802+ args ,keywds ,"|zi:setupterm" ,kwlist ,& termstr ,& fd )) {
1803+ return NULL ;
1804+ }
1805+
1806+ if (fd == -1 ) {
1807+ PyObject * sys_stdout ;
1808+
1809+ sys_stdout = PySys_GetObject ("stdout" );
1810+
1811+ if (sys_stdout == NULL ) {
1812+ PyErr_SetString (
1813+ PyCursesError ,
1814+ "lost sys.stdout" );
1815+ return NULL ;
1816+ }
1817+
1818+ fd = PyObject_AsFileDescriptor (sys_stdout );
1819+
1820+ if (fd == -1 ) {
1821+ return NULL ;
1822+ }
1823+ }
1824+
1825+ if (setupterm (termstr ,fd ,& err ) == ERR ) {
1826+ char * s = "setupterm: unknown error" ;
1827+
1828+ if (err == 0 ) {
1829+ s = "setupterm: could not find terminal" ;
1830+ } else if (err == -1 ) {
1831+ s = "setupterm: could not find terminfo database" ;
1832+ }
1833+
1834+ PyErr_SetString (PyCursesError ,s );
1835+ return NULL ;
1836+ }
1837+
1838+ initialised_setupterm = TRUE;
1839+
1840+ Py_INCREF (Py_None );
1841+ return Py_None ;
1842+ }
17831843
17841844static PyObject *
17851845PyCurses_IntrFlush (PyObject * self , PyObject * args )
@@ -2057,7 +2117,7 @@ PyCurses_tigetflag(PyObject *self, PyObject *args)
20572117{
20582118 char * capname ;
20592119
2060- PyCursesInitialised ;
2120+ PyCursesSetupTermCalled ;
20612121
20622122 if (!PyArg_ParseTuple (args , "z" , & capname ))
20632123 return NULL ;
@@ -2070,7 +2130,7 @@ PyCurses_tigetnum(PyObject *self, PyObject *args)
20702130{
20712131 char * capname ;
20722132
2073- PyCursesInitialised ;
2133+ PyCursesSetupTermCalled ;
20742134
20752135 if (!PyArg_ParseTuple (args , "z" , & capname ))
20762136 return NULL ;
@@ -2083,7 +2143,7 @@ PyCurses_tigetstr(PyObject *self, PyObject *args)
20832143{
20842144 char * capname ;
20852145
2086- PyCursesInitialised ;
2146+ PyCursesSetupTermCalled ;
20872147
20882148 if (!PyArg_ParseTuple (args , "z" , & capname ))
20892149 return NULL ;
@@ -2103,7 +2163,7 @@ PyCurses_tparm(PyObject *self, PyObject *args)
21032163 char * result = NULL ;
21042164 int i1 ,i2 ,i3 ,i4 ,i5 ,i6 ,i7 ,i8 ,i9 ;
21052165
2106- PyCursesInitialised ;
2166+ PyCursesSetupTermCalled ;
21072167
21082168 if (!PyArg_ParseTuple (args , "s|iiiiiiiii:tparm" ,
21092169 & fmt , & i1 , & i2 , & i3 , & i4 ,
@@ -2290,6 +2350,7 @@ static PyMethodDef PyCurses_methods[] = {
22902350 {"resetty" , (PyCFunction )PyCurses_resetty },
22912351 {"savetty" , (PyCFunction )PyCurses_savetty },
22922352 {"setsyx" , (PyCFunction )PyCurses_setsyx },
2353+ {"setupterm" , (PyCFunction )PyCurses_setupterm , METH_VARARGS |METH_KEYWORDS },
22932354 {"start_color" , (PyCFunction )PyCurses_Start_Color },
22942355 {"termattrs" , (PyCFunction )PyCurses_termattrs },
22952356 {"termname" , (PyCFunction )PyCurses_termname },
0 commit comments