@@ -2161,6 +2161,56 @@ curses_wattrset(PyCursesWindowObject *self, attr_t attr, const char *funcname)
21612161 return 0 ;
21622162}
21632163
2164+ /* Read the rendition a write with an *attr* argument has to put back. The
2165+ color pair is read apart from the attributes because the A_COLOR field of a
2166+ chtype holds only pairs 0 to 255, while a window can use a larger one. */
2167+ static int
2168+ curses_wattr_save (PyCursesWindowObject * self , attr_t * attrs , int * pair ,
2169+ const char * funcname )
2170+ {
2171+ #if defined(HAVE_CURSES_WATTR_GET ) && defined(HAVE_CURSES_WATTR_SET )
2172+ int rtn ;
2173+ #if _NCURSES_EXTENDED_COLOR_FUNCS
2174+ short legacy_pair ;
2175+ rtn = wattr_get (self -> win , attrs , & legacy_pair , pair );
2176+ #else
2177+ short spair ;
2178+ rtn = wattr_get (self -> win , attrs , & spair , NULL );
2179+ * pair = spair ;
2180+ #endif
2181+ if (rtn == ERR ) {
2182+ curses_window_set_error (self , "wattr_get" , funcname );
2183+ return -1 ;
2184+ }
2185+ #else
2186+ * attrs = getattrs (self -> win );
2187+ * pair = 0 ;
2188+ #endif
2189+ return 0 ;
2190+ }
2191+
2192+ /* Put the rendition back. The name of the curses function used is
2193+ _CURSES_WATTR_RESTORE_FUNC, for the caller to name it in an error. */
2194+ #if defined(HAVE_CURSES_WATTR_GET ) && defined(HAVE_CURSES_WATTR_SET )
2195+ #define _CURSES_WATTR_RESTORE_FUNC "wattr_set"
2196+ #else
2197+ #define _CURSES_WATTR_RESTORE_FUNC "wattrset"
2198+ #endif
2199+
2200+ static int
2201+ curses_wattr_restore (PyCursesWindowObject * self , attr_t attrs , int pair )
2202+ {
2203+ #if defined(HAVE_CURSES_WATTR_GET ) && defined(HAVE_CURSES_WATTR_SET )
2204+ #if _NCURSES_EXTENDED_COLOR_FUNCS
2205+ return wattr_set (self -> win , attrs , 0 , & pair );
2206+ #else
2207+ return wattr_set (self -> win , attrs , (short )pair , NULL );
2208+ #endif
2209+ #else
2210+ return wattrset (self -> win , attrs );
2211+ #endif
2212+ }
2213+
21642214/*[clinic input]
21652215_curses.window.addstr
21662216
@@ -2201,6 +2251,7 @@ _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1,
22012251 wchar_t * wstr = NULL ;
22022252#endif
22032253 attr_t attr_old = A_NORMAL ;
2254+ int pair_old = 0 ;
22042255 int use_xy = group_left_1 , use_attr = group_right_1 ;
22052256 const char * funcname ;
22062257
@@ -2225,8 +2276,9 @@ _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1,
22252276 return NULL ;
22262277 }
22272278 if (use_attr ) {
2228- attr_old = getattrs (self -> win );
2229- if (curses_wattrset (self , attr , "addstr" ) < 0 ) {
2279+ if (curses_wattr_save (self , & attr_old , & pair_old , "addstr" ) < 0 ||
2280+ curses_wattrset (self , attr , "addstr" ) < 0 )
2281+ {
22302282 curses_release_wstr (strtype , wstr );
22312283 Py_XDECREF (bytesobj );
22322284 return NULL ;
@@ -2263,10 +2315,10 @@ _curses_window_addstr_impl(PyCursesWindowObject *self, int group_left_1,
22632315 Py_DECREF (bytesobj );
22642316 }
22652317 if (use_attr ) {
2266- int attr_rtn = wattrset (self -> win , attr_old );
2318+ int attr_rtn = curses_wattr_restore (self , attr_old , pair_old );
22672319 if (rtn != ERR ) {
22682320 rtn = attr_rtn ;
2269- funcname = "wattrset" ;
2321+ funcname = _CURSES_WATTR_RESTORE_FUNC ;
22702322 }
22712323 }
22722324 return curses_window_check_err (self , rtn , funcname , "addstr" );
@@ -2315,6 +2367,7 @@ _curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1,
23152367 wchar_t * wstr = NULL ;
23162368#endif
23172369 attr_t attr_old = A_NORMAL ;
2370+ int pair_old = 0 ;
23182371 int use_xy = group_left_1 , use_attr = group_right_1 ;
23192372 const char * funcname ;
23202373
@@ -2339,8 +2392,9 @@ _curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1,
23392392 return NULL ;
23402393
23412394 if (use_attr ) {
2342- attr_old = getattrs (self -> win );
2343- if (curses_wattrset (self , attr , "addnstr" ) < 0 ) {
2395+ if (curses_wattr_save (self , & attr_old , & pair_old , "addnstr" ) < 0 ||
2396+ curses_wattrset (self , attr , "addnstr" ) < 0 )
2397+ {
23442398 curses_release_wstr (strtype , wstr );
23452399 Py_XDECREF (bytesobj );
23462400 return NULL ;
@@ -2373,10 +2427,10 @@ _curses_window_addnstr_impl(PyCursesWindowObject *self, int group_left_1,
23732427 Py_DECREF (bytesobj );
23742428 }
23752429 if (use_attr ) {
2376- int attr_rtn = wattrset (self -> win , attr_old );
2430+ int attr_rtn = curses_wattr_restore (self , attr_old , pair_old );
23772431 if (rtn != ERR ) {
23782432 rtn = attr_rtn ;
2379- funcname = "wattrset" ;
2433+ funcname = _CURSES_WATTR_RESTORE_FUNC ;
23802434 }
23812435 }
23822436 return curses_window_check_err (self , rtn , funcname , "addnstr" );
@@ -4035,6 +4089,7 @@ _curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1,
40354089 wchar_t * wstr = NULL ;
40364090#endif
40374091 attr_t attr_old = A_NORMAL ;
4092+ int pair_old = 0 ;
40384093 int use_xy = group_left_1 , use_attr = group_right_1 ;
40394094 const char * funcname ;
40404095
@@ -4059,8 +4114,9 @@ _curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1,
40594114 return NULL ;
40604115
40614116 if (use_attr ) {
4062- attr_old = getattrs (self -> win );
4063- if (curses_wattrset (self , attr , "insstr" ) < 0 ) {
4117+ if (curses_wattr_save (self , & attr_old , & pair_old , "insstr" ) < 0 ||
4118+ curses_wattrset (self , attr , "insstr" ) < 0 )
4119+ {
40644120 curses_release_wstr (strtype , wstr );
40654121 Py_XDECREF (bytesobj );
40664122 return NULL ;
@@ -4093,10 +4149,10 @@ _curses_window_insstr_impl(PyCursesWindowObject *self, int group_left_1,
40934149 Py_DECREF (bytesobj );
40944150 }
40954151 if (use_attr ) {
4096- int attr_rtn = wattrset (self -> win , attr_old );
4152+ int attr_rtn = curses_wattr_restore (self , attr_old , pair_old );
40974153 if (rtn != ERR ) {
40984154 rtn = attr_rtn ;
4099- funcname = "wattrset" ;
4155+ funcname = _CURSES_WATTR_RESTORE_FUNC ;
41004156 }
41014157 }
41024158 return curses_window_check_err (self , rtn , funcname , "insstr" );
@@ -4147,6 +4203,7 @@ _curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1,
41474203 wchar_t * wstr = NULL ;
41484204#endif
41494205 attr_t attr_old = A_NORMAL ;
4206+ int pair_old = 0 ;
41504207 int use_xy = group_left_1 , use_attr = group_right_1 ;
41514208 const char * funcname ;
41524209
@@ -4171,8 +4228,9 @@ _curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1,
41714228 return NULL ;
41724229
41734230 if (use_attr ) {
4174- attr_old = getattrs (self -> win );
4175- if (curses_wattrset (self , attr , "insnstr" ) < 0 ) {
4231+ if (curses_wattr_save (self , & attr_old , & pair_old , "insnstr" ) < 0 ||
4232+ curses_wattrset (self , attr , "insnstr" ) < 0 )
4233+ {
41764234 curses_release_wstr (strtype , wstr );
41774235 return NULL ;
41784236 }
@@ -4204,10 +4262,10 @@ _curses_window_insnstr_impl(PyCursesWindowObject *self, int group_left_1,
42044262 Py_DECREF (bytesobj );
42054263 }
42064264 if (use_attr ) {
4207- int attr_rtn = wattrset (self -> win , attr_old );
4265+ int attr_rtn = curses_wattr_restore (self , attr_old , pair_old );
42084266 if (rtn != ERR ) {
42094267 rtn = attr_rtn ;
4210- funcname = "wattrset" ;
4268+ funcname = _CURSES_WATTR_RESTORE_FUNC ;
42114269 }
42124270 }
42134271 return curses_window_check_err (self , rtn , funcname , "insnstr" );
0 commit comments