Skip to content

Commit 8bc7d63

Browse files
ma8maserhiy-storchaka
authored andcommitted
bpo-25720: Fix the method for checking pad state of curses WINDOW (#4164)
Modify the code to use ncurses is_pad() instead of checking WINDOW _flags field. If your platform does not provide the is_pad(), the existing way that checks the field will be enabled. Note: This change does not drop support for platforms where do not have both WINDOW _flags field and is_pad().
1 parent 280c22a commit 8bc7d63

File tree

6 files changed

+90
-17
lines changed

6 files changed

+90
-17
lines changed

Include/py_curses.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@
1010
#ifdef _BSD_WCHAR_T_DEFINED_
1111
#define _WCHAR_T
1212
#endif
13-
14-
/* the following define is necessary for OS X 10.6; without it, the
15-
Apple-supplied ncurses.h sets NCURSES_OPAQUE to 1, and then Python
16-
can't get at the WINDOW flags field. */
17-
#define NCURSES_OPAQUE 0
1813
#endif /* __APPLE__ */
1914

2015
#ifdef __FreeBSD__
@@ -44,6 +39,13 @@
4439
#endif
4540
#endif
4641

42+
#if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS)
43+
/* The following definition is necessary for ncurses 5.7; without it,
44+
some of [n]curses.h set NCURSES_OPAQUE to 1, and then Python
45+
can't get at the WINDOW flags field. */
46+
#define NCURSES_OPAQUE 0
47+
#endif
48+
4749
#ifdef HAVE_NCURSES_H
4850
#include <ncurses.h>
4951
#else
@@ -52,10 +54,13 @@
5254

5355
#ifdef HAVE_NCURSES_H
5456
/* configure was checking <curses.h>, but we will
55-
use <ncurses.h>, which has all these features. */
56-
#ifndef WINDOW_HAS_FLAGS
57+
use <ncurses.h>, which has some or all these features. */
58+
#if !defined(WINDOW_HAS_FLAGS) && !(NCURSES_OPAQUE+0)
5759
#define WINDOW_HAS_FLAGS 1
5860
#endif
61+
#if !defined(HAVE_CURSES_IS_PAD) && NCURSES_VERSION_PATCH+0 >= 20090906
62+
#define HAVE_CURSES_IS_PAD 1
63+
#endif
5964
#ifndef MVWDELCH_IS_EXPRESSION
6065
#define MVWDELCH_IS_EXPRESSION 1
6166
#endif
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix the method for checking pad state of curses WINDOW. Patch by Masayuki
2+
Yamamoto.

Modules/_cursesmodule.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,12 @@ int py_mvwdelch(WINDOW *w, int y, int x)
934934
}
935935
#endif
936936

937+
#if defined(HAVE_CURSES_IS_PAD)
938+
#define py_is_pad(win) is_pad(win)
939+
#elif defined(WINDOW_HAS_FLAGS)
940+
#define py_is_pad(win) ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE)
941+
#endif
942+
937943
/* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */
938944

939945
static PyObject *
@@ -1073,10 +1079,11 @@ PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
10731079
if (!PyCurses_ConvertToChtype(self, temp, &ch))
10741080
return NULL;
10751081

1076-
#ifdef WINDOW_HAS_FLAGS
1077-
if (self->win->_flags & _ISPAD)
1082+
#ifdef py_is_pad
1083+
if (py_is_pad(self->win)) {
10781084
return PyCursesCheckERR(pechochar(self->win, ch | attr),
10791085
"echochar");
1086+
}
10801087
else
10811088
#endif
10821089
return PyCursesCheckERR(wechochar(self->win, ch | attr),
@@ -1603,10 +1610,10 @@ PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args)
16031610
int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
16041611
int rtn;
16051612

1606-
#ifndef WINDOW_HAS_FLAGS
1613+
#ifndef py_is_pad
16071614
if (0)
16081615
#else
1609-
if (self->win->_flags & _ISPAD)
1616+
if (py_is_pad(self->win))
16101617
#endif
16111618
{
16121619
switch(PyTuple_Size(args)) {
@@ -1766,10 +1773,10 @@ PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args)
17661773
int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
17671774
int rtn;
17681775

1769-
#ifndef WINDOW_HAS_FLAGS
1776+
#ifndef py_is_pad
17701777
if (0)
17711778
#else
1772-
if (self->win->_flags & _ISPAD)
1779+
if (py_is_pad(self->win))
17731780
#endif
17741781
{
17751782
switch(PyTuple_Size(args)) {
@@ -1835,9 +1842,10 @@ PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args)
18351842
}
18361843

18371844
/* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */
1838-
#ifdef WINDOW_HAS_FLAGS
1839-
if (self->win->_flags & _ISPAD)
1845+
#ifdef py_is_pad
1846+
if (py_is_pad(self->win)) {
18401847
win = subpad(self->win, nlines, ncols, begin_y, begin_x);
1848+
}
18411849
else
18421850
#endif
18431851
win = subwin(self->win, nlines, ncols, begin_y, begin_x);

configure

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15699,14 +15699,21 @@ $as_echo "#define MVWDELCH_IS_EXPRESSION 1" >>confdefs.h
1569915699

1570015700
fi
1570115701

15702+
# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
15703+
# structs since version 5.7. If the macro is defined as zero before including
15704+
# [n]curses.h, ncurses will expose fields of the structs regardless of the
15705+
# configuration.
1570215706
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether WINDOW has _flags" >&5
1570315707
$as_echo_n "checking whether WINDOW has _flags... " >&6; }
1570415708
if ${ac_cv_window_has_flags+:} false; then :
1570515709
$as_echo_n "(cached) " >&6
1570615710
else
1570715711
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
1570815712
/* end confdefs.h. */
15709-
#include <curses.h>
15713+
15714+
#define NCURSES_OPAQUE 0
15715+
#include <curses.h>
15716+
1571015717
int
1571115718
main ()
1571215719
{
@@ -15737,6 +15744,36 @@ $as_echo "#define WINDOW_HAS_FLAGS 1" >>confdefs.h
1573715744

1573815745
fi
1573915746

15747+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_pad" >&5
15748+
$as_echo_n "checking for is_pad... " >&6; }
15749+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
15750+
/* end confdefs.h. */
15751+
#include <curses.h>
15752+
int
15753+
main ()
15754+
{
15755+
15756+
#ifndef is_pad
15757+
void *x=is_pad
15758+
#endif
15759+
15760+
;
15761+
return 0;
15762+
}
15763+
_ACEOF
15764+
if ac_fn_c_try_compile "$LINENO"; then :
15765+
15766+
$as_echo "#define HAVE_CURSES_IS_PAD 1" >>confdefs.h
15767+
15768+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
15769+
$as_echo "yes" >&6; }
15770+
else
15771+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
15772+
$as_echo "no" >&6; }
15773+
15774+
fi
15775+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
15776+
1574015777
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_term_resized" >&5
1574115778
$as_echo_n "checking for is_term_resized... " >&6; }
1574215779
cat confdefs.h - <<_ACEOF >conftest.$ac_ext

configure.ac

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4955,9 +4955,16 @@ then
49554955
[Define if mvwdelch in curses.h is an expression.])
49564956
fi
49574957

4958+
# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
4959+
# structs since version 5.7. If the macro is defined as zero before including
4960+
# [n]curses.h, ncurses will expose fields of the structs regardless of the
4961+
# configuration.
49584962
AC_MSG_CHECKING(whether WINDOW has _flags)
49594963
AC_CACHE_VAL(ac_cv_window_has_flags,
4960-
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
4964+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
4965+
#define NCURSES_OPAQUE 0
4966+
#include <curses.h>
4967+
]], [[
49614968
WINDOW *w;
49624969
w->_flags = 0;
49634970
]])],
@@ -4972,6 +4979,17 @@ then
49724979
[Define if WINDOW in curses.h offers a field _flags.])
49734980
fi
49744981

4982+
AC_MSG_CHECKING(for is_pad)
4983+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
4984+
#ifndef is_pad
4985+
void *x=is_pad
4986+
#endif
4987+
]])],
4988+
[AC_DEFINE(HAVE_CURSES_IS_PAD, 1, Define if you have the 'is_pad' function or macro.)
4989+
AC_MSG_RESULT(yes)],
4990+
[AC_MSG_RESULT(no)]
4991+
)
4992+
49754993
AC_MSG_CHECKING(for is_term_resized)
49764994
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[void *x=is_term_resized]])],
49774995
[AC_DEFINE(HAVE_CURSES_IS_TERM_RESIZED, 1, Define if you have the 'is_term_resized' function.)

pyconfig.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@
158158
/* Define if you have the 'immedok' function. */
159159
#undef HAVE_CURSES_IMMEDOK
160160

161+
/* Define if you have the 'is_pad' function or macro. */
162+
#undef HAVE_CURSES_IS_PAD
163+
161164
/* Define if you have the 'is_term_resized' function. */
162165
#undef HAVE_CURSES_IS_TERM_RESIZED
163166

0 commit comments

Comments
 (0)