diff --git a/Include/py_curses.h b/Include/py_curses.h index 336c95d360d159..d98bf82655896b 100644 --- a/Include/py_curses.h +++ b/Include/py_curses.h @@ -7,14 +7,9 @@ ** On Mac OS X 10.2 [n]curses.h and stdlib.h use different guards ** against multiple definition of wchar_t. */ -#ifdef _BSD_WCHAR_T_DEFINED_ +#ifdef _BSD_WCHAR_T_DEFINED_ #define _WCHAR_T #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__ */ #ifdef __FreeBSD__ @@ -22,7 +17,7 @@ ** On FreeBSD, [n]curses.h and stdlib.h/wchar.h use different guards ** against multiple definition of wchar_t and wint_t. */ -#ifdef _XOPEN_SOURCE_EXTENDED +#ifdef _XOPEN_SOURCE_EXTENDED #ifndef __FreeBSD_version #include #endif @@ -44,6 +39,15 @@ #endif #endif +#if !defined(HAVE_CURSES_IS_PAD) && !defined(WINDOW_HAS_FLAGS) +/* If ncurses doesn't have both is_pad function and _flags field of WINDOW, + there is no method to check whether WINDOW is a pad. Therefore, add the + definitions to make WINDOW to non-opaque type before including [n]curses.h. +*/ +#define NCURSES_OPAQUE 0 +#define WINDOW_HAS_FLAGS 1 +#endif + #ifdef HAVE_NCURSES_H #include #else @@ -57,9 +61,6 @@ #ifdef HAVE_NCURSES_H /* configure was checking , but we will use , which has all these features. */ -#ifndef WINDOW_HAS_FLAGS -#define WINDOW_HAS_FLAGS 1 -#endif #ifndef MVWDELCH_IS_EXPRESSION #define MVWDELCH_IS_EXPRESSION 1 #endif @@ -74,12 +75,12 @@ extern "C" { /* Type declarations */ typedef struct { - PyObject_HEAD - WINDOW *win; - char *encoding; + PyObject_HEAD + WINDOW *win; + char *encoding; } PyCursesWindowObject; -#define PyCursesWindow_Check(v) (Py_TYPE(v) == &PyCursesWindow_Type) +#define PyCursesWindow_Check(v) (Py_TYPE(v) == &PyCursesWindow_Type) #define PyCurses_CAPSULE_NAME "_curses._C_API" diff --git a/Misc/NEWS.d/next/Library/2017-06-24-13-47-00.bpo-25720.iEVYvL.rst b/Misc/NEWS.d/next/Library/2017-06-24-13-47-00.bpo-25720.iEVYvL.rst new file mode 100644 index 00000000000000..f7a66fe11e937f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-06-24-13-47-00.bpo-25720.iEVYvL.rst @@ -0,0 +1 @@ +curses: Fix check for whether WINDOW is a pad. diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 5dc0865c1c4dda..1ee69004c8f972 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -928,6 +928,12 @@ int py_mvwdelch(WINDOW *w, int y, int x) } #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 */ static PyObject * @@ -1067,8 +1073,8 @@ PyCursesWindow_EchoChar(PyCursesWindowObject *self, PyObject *args) if (!PyCurses_ConvertToChtype(self, temp, &ch)) return NULL; -#ifdef WINDOW_HAS_FLAGS - if (self->win->_flags & _ISPAD) +#ifdef py_is_pad + if (py_is_pad(self->win)) return PyCursesCheckERR(pechochar(self->win, ch | attr), "echochar"); else @@ -1602,41 +1608,42 @@ PyCursesWindow_NoOutRefresh(PyCursesWindowObject *self, PyObject *args) int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol; int rtn; -#ifndef WINDOW_HAS_FLAGS +#ifndef py_is_pad if (0) #else - if (self->win->_flags & _ISPAD) -#endif - { - switch(PyTuple_Size(args)) { - case 6: - if (!PyArg_ParseTuple(args, - "iiiiii;" \ - "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", - &pminrow, &pmincol, &sminrow, - &smincol, &smaxrow, &smaxcol)) - return NULL; - Py_BEGIN_ALLOW_THREADS - rtn = pnoutrefresh(self->win, - pminrow, pmincol, sminrow, - smincol, smaxrow, smaxcol); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "pnoutrefresh"); - default: - PyErr_SetString(PyCursesError, - "noutrefresh() called for a pad " - "requires 6 arguments"); - return NULL; - } - } else { - if (!PyArg_ParseTuple(args, ":noutrefresh")) + if (py_is_pad(self->win)) +#endif + { + switch(PyTuple_Size(args)) { + case 6: + if (!PyArg_ParseTuple(args, + "iiiiii;" \ + "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", + &pminrow, &pmincol, &sminrow, + &smincol, &smaxrow, &smaxcol)) return NULL; Py_BEGIN_ALLOW_THREADS - rtn = wnoutrefresh(self->win); + rtn = pnoutrefresh(self->win, + pminrow, pmincol, sminrow, + smincol, smaxrow, smaxcol); Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "wnoutrefresh"); + return PyCursesCheckERR(rtn, "pnoutrefresh"); + default: + PyErr_SetString(PyCursesError, + "noutrefresh() called for a pad " + "requires 6 arguments"); + return NULL; } + } else { + if (!PyArg_ParseTuple(args, ":noutrefresh")) + return NULL; + + Py_BEGIN_ALLOW_THREADS + rtn = wnoutrefresh(self->win); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "wnoutrefresh"); + } } static PyObject * @@ -1765,40 +1772,41 @@ PyCursesWindow_Refresh(PyCursesWindowObject *self, PyObject *args) int pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol; int rtn; -#ifndef WINDOW_HAS_FLAGS +#ifndef py_is_pad if (0) #else - if (self->win->_flags & _ISPAD) -#endif - { - switch(PyTuple_Size(args)) { - case 6: - if (!PyArg_ParseTuple(args, - "iiiiii;" \ - "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", - &pminrow, &pmincol, &sminrow, - &smincol, &smaxrow, &smaxcol)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - rtn = prefresh(self->win, - pminrow, pmincol, sminrow, - smincol, smaxrow, smaxcol); - Py_END_ALLOW_THREADS - return PyCursesCheckERR(rtn, "prefresh"); - default: - PyErr_SetString(PyCursesError, - "refresh() for a pad requires 6 arguments"); - return NULL; - } - } else { - if (!PyArg_ParseTuple(args, ":refresh")) + if (py_is_pad(self->win)) +#endif + { + switch(PyTuple_Size(args)) { + case 6: + if (!PyArg_ParseTuple(args, + "iiiiii;" \ + "pminrow,pmincol,sminrow,smincol,smaxrow,smaxcol", + &pminrow, &pmincol, &sminrow, + &smincol, &smaxrow, &smaxcol)) return NULL; + Py_BEGIN_ALLOW_THREADS - rtn = wrefresh(self->win); + rtn = prefresh(self->win, + pminrow, pmincol, sminrow, + smincol, smaxrow, smaxcol); Py_END_ALLOW_THREADS return PyCursesCheckERR(rtn, "prefresh"); + default: + PyErr_SetString(PyCursesError, + "refresh() for a pad requires 6 arguments"); + return NULL; } + } else { + if (!PyArg_ParseTuple(args, ":refresh")) + return NULL; + + Py_BEGIN_ALLOW_THREADS + rtn = wrefresh(self->win); + Py_END_ALLOW_THREADS + return PyCursesCheckERR(rtn, "prefresh"); + } } static PyObject * @@ -1834,8 +1842,8 @@ PyCursesWindow_SubWin(PyCursesWindowObject *self, PyObject *args) } /* printf("Subwin: %i %i %i %i \n", nlines, ncols, begin_y, begin_x); */ -#ifdef WINDOW_HAS_FLAGS - if (self->win->_flags & _ISPAD) +#ifdef py_is_pad + if (py_is_pad(self->win)) win = subpad(self->win, nlines, ncols, begin_y, begin_x); else #endif diff --git a/configure b/configure index ec42e08f8961c1..30ec12b5ea6fdd 100755 --- a/configure +++ b/configure @@ -15957,6 +15957,36 @@ $as_echo "#define MVWDELCH_IS_EXPRESSION 1" >>confdefs.h 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 +int +main () +{ + + bool b; + WINDOW *w; + b = is_pad(w); + + ; + 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 whether WINDOW has _flags" >&5 $as_echo_n "checking whether WINDOW has _flags... " >&6; } if ${ac_cv_window_has_flags+:} false; then : diff --git a/configure.ac b/configure.ac index 18b940ab329172..d0cb28edd9ddab 100644 --- a/configure.ac +++ b/configure.ac @@ -5044,6 +5044,18 @@ then [Define if mvwdelch in curses.h is an expression.]) fi +AC_MSG_CHECKING(for is_pad) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + bool b; + WINDOW *w; + b = is_pad(w); + ]])], + [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(whether WINDOW has _flags) AC_CACHE_VAL(ac_cv_window_has_flags, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ diff --git a/pyconfig.h.in b/pyconfig.h.in index fa2792b18ad419..422443201304b7 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -149,6 +149,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_CURSES_H +/* Define if you have the 'is_pad' function or macro. */ +#undef HAVE_CURSES_IS_PAD + /* Define if you have the 'is_term_resized' function. */ #undef HAVE_CURSES_IS_TERM_RESIZED