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().
This commit is contained in:
Masayuki Yamamoto 2017-11-01 21:05:26 +09:00 committed by Serhiy Storchaka
parent 280c22a82a
commit 8bc7d63560
6 changed files with 90 additions and 17 deletions

View File

@ -10,11 +10,6 @@
#ifdef _BSD_WCHAR_T_DEFINED_ #ifdef _BSD_WCHAR_T_DEFINED_
#define _WCHAR_T #define _WCHAR_T
#endif #endif
/* the following define is necessary for OS X 10.6; without it, the
Apple-supplied ncurses.h sets NCURSES_OPAQUE to 1, and then Python
can't get at the WINDOW flags field. */
#define NCURSES_OPAQUE 0
#endif /* __APPLE__ */ #endif /* __APPLE__ */
#ifdef __FreeBSD__ #ifdef __FreeBSD__
@ -44,6 +39,13 @@
#endif #endif
#endif #endif
#if !defined(HAVE_CURSES_IS_PAD) && defined(WINDOW_HAS_FLAGS)
/* The following definition is necessary for ncurses 5.7; without it,
some of [n]curses.h set NCURSES_OPAQUE to 1, and then Python
can't get at the WINDOW flags field. */
#define NCURSES_OPAQUE 0
#endif
#ifdef HAVE_NCURSES_H #ifdef HAVE_NCURSES_H
#include <ncurses.h> #include <ncurses.h>
#else #else
@ -52,10 +54,13 @@
#ifdef HAVE_NCURSES_H #ifdef HAVE_NCURSES_H
/* configure was checking <curses.h>, but we will /* configure was checking <curses.h>, but we will
use <ncurses.h>, which has all these features. */ use <ncurses.h>, which has some or all these features. */
#ifndef WINDOW_HAS_FLAGS #if !defined(WINDOW_HAS_FLAGS) && !(NCURSES_OPAQUE+0)
#define WINDOW_HAS_FLAGS 1 #define WINDOW_HAS_FLAGS 1
#endif #endif
#if !defined(HAVE_CURSES_IS_PAD) && NCURSES_VERSION_PATCH+0 >= 20090906
#define HAVE_CURSES_IS_PAD 1
#endif
#ifndef MVWDELCH_IS_EXPRESSION #ifndef MVWDELCH_IS_EXPRESSION
#define MVWDELCH_IS_EXPRESSION 1 #define MVWDELCH_IS_EXPRESSION 1
#endif #endif

View File

@ -0,0 +1,2 @@
Fix the method for checking pad state of curses WINDOW. Patch by Masayuki
Yamamoto.

View File

@ -934,6 +934,12 @@ int py_mvwdelch(WINDOW *w, int y, int x)
} }
#endif #endif
#if defined(HAVE_CURSES_IS_PAD)
#define py_is_pad(win) is_pad(win)
#elif defined(WINDOW_HAS_FLAGS)
#define py_is_pad(win) ((win) ? ((win)->_flags & _ISPAD) != 0 : FALSE)
#endif
/* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */ /* chgat, added by Fabian Kreutz <fabian.kreutz at gmx.net> */
static PyObject * static PyObject *
@ -1073,10 +1079,11 @@ PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args)
if (!PyCurses_ConvertToChtype(self, temp, &ch)) if (!PyCurses_ConvertToChtype(self, temp, &ch))
return NULL; return NULL;
#ifdef WINDOW_HAS_FLAGS #ifdef py_is_pad
if (self->win->_flags & _ISPAD) if (py_is_pad(self->win)) {
return PyCursesCheckERR(pechochar(self->win, ch | attr), return PyCursesCheckERR(pechochar(self->win, ch | attr),
"echochar"); "echochar");
}
else else
#endif #endif
return PyCursesCheckERR(wechochar(self->win, ch | attr), return PyCursesCheckERR(wechochar(self->win, ch | attr),
@ -1603,10 +1610,10 @@ PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args)
int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol; int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
int rtn; int rtn;
#ifndef WINDOW_HAS_FLAGS #ifndef py_is_pad
if (0) if (0)
#else #else
if (self->win->_flags & _ISPAD) if (py_is_pad(self->win))
#endif #endif
{ {
switch(PyTuple_Size(args)) { switch(PyTuple_Size(args)) {
@ -1766,10 +1773,10 @@ PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args)
int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol; int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol;
int rtn; int rtn;
#ifndef WINDOW_HAS_FLAGS #ifndef py_is_pad
if (0) if (0)
#else #else
if (self->win->_flags & _ISPAD) if (py_is_pad(self->win))
#endif #endif
{ {
switch(PyTuple_Size(args)) { switch(PyTuple_Size(args)) {
@ -1835,9 +1842,10 @@ PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args)
} }
/* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */ /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */
#ifdef WINDOW_HAS_FLAGS #ifdef py_is_pad
if (self->win->_flags & _ISPAD) if (py_is_pad(self->win)) {
win = subpad(self->win, nlines, ncols, begin_y, begin_x); win = subpad(self->win, nlines, ncols, begin_y, begin_x);
}
else else
#endif #endif
win = subwin(self->win, nlines, ncols, begin_y, begin_x); win = subwin(self->win, nlines, ncols, begin_y, begin_x);

39
configure vendored
View File

@ -15699,6 +15699,10 @@ $as_echo "#define MVWDELCH_IS_EXPRESSION 1" >>confdefs.h
fi fi
# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
# structs since version 5.7. If the macro is defined as zero before including
# [n]curses.h, ncurses will expose fields of the structs regardless of the
# configuration.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether WINDOW has _flags" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether WINDOW has _flags" >&5
$as_echo_n "checking whether WINDOW has _flags... " >&6; } $as_echo_n "checking whether WINDOW has _flags... " >&6; }
if ${ac_cv_window_has_flags+:} false; then : if ${ac_cv_window_has_flags+:} false; then :
@ -15706,7 +15710,10 @@ if ${ac_cv_window_has_flags+:} false; then :
else else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */ /* end confdefs.h. */
#include <curses.h>
#define NCURSES_OPAQUE 0
#include <curses.h>
int int
main () main ()
{ {
@ -15737,6 +15744,36 @@ $as_echo "#define WINDOW_HAS_FLAGS 1" >>confdefs.h
fi fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_pad" >&5
$as_echo_n "checking for is_pad... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <curses.h>
int
main ()
{
#ifndef is_pad
void *x=is_pad
#endif
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
$as_echo "#define HAVE_CURSES_IS_PAD 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_term_resized" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_term_resized" >&5
$as_echo_n "checking for is_term_resized... " >&6; } $as_echo_n "checking for is_term_resized... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext cat confdefs.h - <<_ACEOF >conftest.$ac_ext

View File

@ -4955,9 +4955,16 @@ then
[Define if mvwdelch in curses.h is an expression.]) [Define if mvwdelch in curses.h is an expression.])
fi fi
# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
# structs since version 5.7. If the macro is defined as zero before including
# [n]curses.h, ncurses will expose fields of the structs regardless of the
# configuration.
AC_MSG_CHECKING(whether WINDOW has _flags) AC_MSG_CHECKING(whether WINDOW has _flags)
AC_CACHE_VAL(ac_cv_window_has_flags, AC_CACHE_VAL(ac_cv_window_has_flags,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#define NCURSES_OPAQUE 0
#include <curses.h>
]], [[
WINDOW *w; WINDOW *w;
w->_flags = 0; w->_flags = 0;
]])], ]])],
@ -4972,6 +4979,17 @@ then
[Define if WINDOW in curses.h offers a field _flags.]) [Define if WINDOW in curses.h offers a field _flags.])
fi fi
AC_MSG_CHECKING(for is_pad)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[
#ifndef is_pad
void *x=is_pad
#endif
]])],
[AC_DEFINE(HAVE_CURSES_IS_PAD, 1, Define if you have the 'is_pad' function or macro.)
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)]
)
AC_MSG_CHECKING(for is_term_resized) AC_MSG_CHECKING(for is_term_resized)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[void *x=is_term_resized]])], AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <curses.h>]], [[void *x=is_term_resized]])],
[AC_DEFINE(HAVE_CURSES_IS_TERM_RESIZED, 1, Define if you have the 'is_term_resized' function.) [AC_DEFINE(HAVE_CURSES_IS_TERM_RESIZED, 1, Define if you have the 'is_term_resized' function.)

View File

@ -158,6 +158,9 @@
/* Define if you have the 'immedok' function. */ /* Define if you have the 'immedok' function. */
#undef HAVE_CURSES_IMMEDOK #undef HAVE_CURSES_IMMEDOK
/* Define if you have the 'is_pad' function or macro. */
#undef HAVE_CURSES_IS_PAD
/* Define if you have the 'is_term_resized' function. */ /* Define if you have the 'is_term_resized' function. */
#undef HAVE_CURSES_IS_TERM_RESIZED #undef HAVE_CURSES_IS_TERM_RESIZED