https://github.com/python/cpython/commit/7bbea4f4868ef89b07b986d7a0d4b585e8271f27
commit: 7bbea4f4868ef89b07b986d7a0d4b585e8271f27
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-06-30T19:24:07Z
summary:

gh-152502: Detect the curses mouse interface and is_* methods portably 
(GH-152705)

The mouse interface (getmouse(), has_mouse(), the BUTTON* constants,
window.mouse_trafo(), ...) and the window is_*() state-query methods were gated
on ncurses-specific macros, so they were dropped on other curses implementations
that provide them, such as NetBSD curses and PDCurses.

Gate them instead on configure capability probes (for functions NetBSD curses
provides, since it defines no identifying macro) or on NCURSES_EXT_FUNCS or the
PDCURSES macro (for functions only ncurses and PDCurses provide).  Probe for
getmouse() with its X/Open getmouse(MEVENT *) signature, since PDCurses declares
an incompatible getmouse(void) unless built for the ncurses mouse API, which
PDC_NCMOUSE now always selects.

Co-authored-by: Claude Opus 4.8 <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-06-30-14-30-00.gh-issue-152502.Mq7Kx2.rst
M Doc/library/curses.rst
M Include/py_curses.h
M Modules/_cursesmodule.c
M Modules/clinic/_cursesmodule.c.h
M configure
M configure.ac
M pyconfig.h.in

diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst
index 7178325e708bc1..bbe29e5f46ed1d 100644
--- a/Doc/library/curses.rst
+++ b/Doc/library/curses.rst
@@ -465,7 +465,7 @@ Mouse
 
    Return ``True`` if the mouse driver has been successfully initialized.
 
-   Availability: ncurses 5.8 or later.
+   Availability: if the underlying curses library provides ``has_mouse()``.
 
    .. versionadded:: next
 
diff --git a/Include/py_curses.h b/Include/py_curses.h
index 3d2ca278f809cb..23e67c4e6e634d 100644
--- a/Include/py_curses.h
+++ b/Include/py_curses.h
@@ -36,6 +36,13 @@
 #define NCURSES_OPAQUE 0
 #endif
 
+/* PDCurses exposes its ncurses-compatible mouse API, the one this module uses,
+   only when this is defined before the curses header is included below.
+   Ignored by other curses implementations. */
+#ifndef PDC_NCMOUSE
+#  define PDC_NCMOUSE
+#endif
+
 #if defined(HAVE_NCURSESW_NCURSES_H)
 #  include <ncursesw/ncurses.h>
 #elif defined(HAVE_NCURSESW_CURSES_H)
diff --git 
a/Misc/NEWS.d/next/Library/2026-06-30-14-30-00.gh-issue-152502.Mq7Kx2.rst 
b/Misc/NEWS.d/next/Library/2026-06-30-14-30-00.gh-issue-152502.Mq7Kx2.rst
new file mode 100644
index 00000000000000..6f343f0ab0c162
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-06-30-14-30-00.gh-issue-152502.Mq7Kx2.rst
@@ -0,0 +1,6 @@
+Detect the :mod:`curses` mouse interface (:func:`~curses.getmouse`,
+:func:`~curses.has_mouse`, the ``BUTTON*`` constants, and others) and the
+window ``is_*`` state-query methods with configure capability probes or library
+macros instead of gating them on ncurses-specific macros.  They are now also
+available with other curses implementations that provide them, such as NetBSD
+curses and PDCurses (the latter underpins ``windows-curses``).
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index dc373c8cef932c..6fc671cc6c6803 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -1828,20 +1828,28 @@ Window_NoArgNoReturnFunction(wdeleteln)
 
 Window_NoArgTrueFalseFunction(is_wintouched)
 
-#if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404
+#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404) || 
defined(PDCURSES)
 Window_NoArgTrueFalseFunction(is_cleared)
 Window_NoArgTrueFalseFunction(is_idcok)
 Window_NoArgTrueFalseFunction(is_idlok)
 Window_NoArgTrueFalseFunction(is_immedok)
-Window_NoArgTrueFalseFunction(is_keypad)
-Window_NoArgTrueFalseFunction(is_leaveok)
 Window_NoArgTrueFalseFunction(is_nodelay)
 Window_NoArgTrueFalseFunction(is_notimeout)
-Window_NoArgTrueFalseFunction(is_pad)
 Window_NoArgTrueFalseFunction(is_scrollok)
 Window_NoArgTrueFalseFunction(is_subwin)
 Window_NoArgTrueFalseFunction(is_syncok)
+#endif
+#if defined(HAVE_CURSES_IS_KEYPAD) || defined(PDCURSES)
+Window_NoArgTrueFalseFunction(is_keypad)
+#endif
+#if defined(HAVE_CURSES_IS_LEAVEOK) || defined(PDCURSES)
+Window_NoArgTrueFalseFunction(is_leaveok)
+#endif
+#if defined(HAVE_CURSES_IS_PAD) || defined(PDCURSES)
+Window_NoArgTrueFalseFunction(is_pad)
+#endif
 
+#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404) || 
defined(PDCURSES)
 static PyObject *
 PyCursesWindow_getdelay(PyObject *op, PyObject *Py_UNUSED(ignored))
 {
@@ -1872,7 +1880,7 @@ PyCursesWindow_getparent(PyObject *op, PyObject 
*Py_UNUSED(ignored))
     }
     return Py_NewRef((PyObject *)self->orig);
 }
-#endif /* NCURSES_EXT_FUNCS */
+#endif /* NCURSES_EXT_FUNCS >= 20110404 || PDCURSES */
 
 Window_NoArgNoReturnVoidFunction(wsyncup)
 Window_NoArgNoReturnVoidFunction(wsyncdown)
@@ -2985,7 +2993,7 @@ _curses_window_echochar_impl(PyCursesWindowObject *self, 
PyObject *ch,
     return curses_window_check_err(self, rtn, funcname, "echochar");
 }
 
-#ifdef NCURSES_MOUSE_VERSION
+#if defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)
 /*[clinic input]
 @permit_long_summary
 _curses.window.enclose
@@ -4881,7 +4889,7 @@ static PyMethodDef PyCursesWindow_methods[] = {
     _CURSES_WINDOW_GETCH_METHODDEF
     _CURSES_WINDOW_GETKEY_METHODDEF
     _CURSES_WINDOW_GET_WCH_METHODDEF
-#if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404
+#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404) || 
defined(PDCURSES)
     {"getdelay", PyCursesWindow_getdelay, METH_NOARGS,
      "getdelay($self, /)\n--\n\n"
      "Return the window's read timeout in milliseconds.\n\n"
@@ -4890,7 +4898,7 @@ static PyMethodDef PyCursesWindow_methods[] = {
     {"getmaxyx", PyCursesWindow_getmaxyx, METH_NOARGS,
      "getmaxyx($self, /)\n--\n\n"
      "Return a tuple (y, x) of the window height and width."},
-#if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404
+#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404) || 
defined(PDCURSES)
     {"getparent", PyCursesWindow_getparent, METH_NOARGS,
      "getparent($self, /)\n--\n\n"
      "Return the parent window, or None if this is not a subwindow."},
@@ -4898,7 +4906,7 @@ static PyMethodDef PyCursesWindow_methods[] = {
     {"getparyx", PyCursesWindow_getparyx, METH_NOARGS,
      "getparyx($self, /)\n--\n\n"
      "Return (y, x) relative to the parent window, or (-1, -1) if none."},
-#if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404
+#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404) || 
defined(PDCURSES)
     {"getscrreg", PyCursesWindow_getscrreg, METH_NOARGS,
      "getscrreg($self, /)\n--\n\n"
      "Return a tuple (top, bottom) of the current scrolling region."},
@@ -4953,7 +4961,7 @@ static PyMethodDef PyCursesWindow_methods[] = {
     {"is_wintouched", PyCursesWindow_is_wintouched, METH_NOARGS,
      "is_wintouched($self, /)\n--\n\n"
      "Return True if the window changed since the last refresh()."},
-#if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404
+#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20110404) || 
defined(PDCURSES)
     {"is_cleared", PyCursesWindow_is_cleared, METH_NOARGS,
      "is_cleared($self, /)\n--\n\n"
      "Return the current value set by clearok()."},
@@ -4966,21 +4974,12 @@ static PyMethodDef PyCursesWindow_methods[] = {
     {"is_immedok", PyCursesWindow_is_immedok, METH_NOARGS,
      "is_immedok($self, /)\n--\n\n"
      "Return the current value set by immedok()."},
-    {"is_keypad", PyCursesWindow_is_keypad, METH_NOARGS,
-     "is_keypad($self, /)\n--\n\n"
-     "Return the current value set by keypad()."},
-    {"is_leaveok", PyCursesWindow_is_leaveok, METH_NOARGS,
-     "is_leaveok($self, /)\n--\n\n"
-     "Return the current value set by leaveok()."},
     {"is_nodelay", PyCursesWindow_is_nodelay, METH_NOARGS,
      "is_nodelay($self, /)\n--\n\n"
      "Return the current value set by nodelay()."},
     {"is_notimeout", PyCursesWindow_is_notimeout, METH_NOARGS,
      "is_notimeout($self, /)\n--\n\n"
      "Return the current value set by notimeout()."},
-    {"is_pad", PyCursesWindow_is_pad, METH_NOARGS,
-     "is_pad($self, /)\n--\n\n"
-     "Return True if the window is a pad."},
     {"is_scrollok", PyCursesWindow_is_scrollok, METH_NOARGS,
      "is_scrollok($self, /)\n--\n\n"
      "Return the current value set by scrollok()."},
@@ -4990,6 +4989,21 @@ static PyMethodDef PyCursesWindow_methods[] = {
     {"is_syncok", PyCursesWindow_is_syncok, METH_NOARGS,
      "is_syncok($self, /)\n--\n\n"
      "Return the current value set by syncok()."},
+#endif
+#if defined(HAVE_CURSES_IS_KEYPAD) || defined(PDCURSES)
+    {"is_keypad", PyCursesWindow_is_keypad, METH_NOARGS,
+     "is_keypad($self, /)\n--\n\n"
+     "Return the current value set by keypad()."},
+#endif
+#if defined(HAVE_CURSES_IS_LEAVEOK) || defined(PDCURSES)
+    {"is_leaveok", PyCursesWindow_is_leaveok, METH_NOARGS,
+     "is_leaveok($self, /)\n--\n\n"
+     "Return the current value set by leaveok()."},
+#endif
+#if defined(HAVE_CURSES_IS_PAD) || defined(PDCURSES)
+    {"is_pad", PyCursesWindow_is_pad, METH_NOARGS,
+     "is_pad($self, /)\n--\n\n"
+     "Return True if the window is a pad."},
 #endif
     {"keypad", PyCursesWindow_keypad, METH_VARARGS,
      "keypad($self, flag, /)\n--\n\n"
@@ -5477,7 +5491,7 @@ _curses_cbreak_impl(PyObject *module, int flag)
 NoArgOrFlagNoReturnFunctionBody(cbreak, flag)
 
 /* is_cbreak()/is_echo()/is_nl()/is_raw() were added in ncurses 6.5. */
-#if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427
+#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) || 
defined(PDCURSES)
 /*[clinic input]
 _curses.is_cbreak
 
@@ -5533,7 +5547,7 @@ _curses_is_raw_impl(PyObject *module)
     PyCursesStatefulInitialised(module);
     return PyBool_FromLong(is_raw());
 }
-#endif /* NCURSES_EXT_FUNCS */
+#endif /* NCURSES_EXT_FUNCS >= 20240427 || PDCURSES */
 
 /*[clinic input]
 _curses.color_content
@@ -5837,7 +5851,7 @@ _curses_getsyx_impl(PyObject *module)
 }
 #endif
 
-#ifdef NCURSES_MOUSE_VERSION
+#if defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)
 /*[clinic input]
 _curses.getmouse
 
@@ -7040,9 +7054,8 @@ _curses_meta_impl(PyObject *module, int yes)
     return curses_check_err(module, meta(stdscr, yes), "meta", NULL);
 }
 
-#ifdef NCURSES_MOUSE_VERSION
-/* has_mouse() was added to ncurses after the 5.7 release. */
-#if defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20081122
+#if defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)
+#if defined(HAVE_CURSES_HAS_MOUSE) || defined(PDCURSES)
 /*[clinic input]
 _curses.has_mouse
 
@@ -7057,7 +7070,7 @@ _curses_has_mouse_impl(PyObject *module)
 
     return PyBool_FromLong(has_mouse());
 }
-#endif /* NCURSES_EXT_FUNCS >= 20081122 */
+#endif /* HAVE_CURSES_HAS_MOUSE || PDCURSES */
 
 /*[clinic input]
 _curses.mouseinterval
@@ -8291,7 +8304,7 @@ _curses_slk_attrset_impl(PyObject *module, long attr)
                             "slk_attrset", NULL);
 }
 
-#ifdef NCURSES_EXT_FUNCS
+#if defined(NCURSES_EXT_FUNCS) || defined(PDCURSES)
 /*[clinic input]
 _curses.slk_attr
 
@@ -9036,7 +9049,7 @@ cursesmodule_exec(PyObject *module)
     SetDictInt("COLOR_CYAN",        COLOR_CYAN);
     SetDictInt("COLOR_WHITE",       COLOR_WHITE);
 
-#ifdef NCURSES_MOUSE_VERSION
+#if defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)
     /* Mouse-related constants */
     SetDictInt("BUTTON1_PRESSED",          BUTTON1_PRESSED);
     SetDictInt("BUTTON1_RELEASED",         BUTTON1_RELEASED);
@@ -9062,7 +9075,7 @@ cursesmodule_exec(PyObject *module)
     SetDictInt("BUTTON4_DOUBLE_CLICKED",   BUTTON4_DOUBLE_CLICKED);
     SetDictInt("BUTTON4_TRIPLE_CLICKED",   BUTTON4_TRIPLE_CLICKED);
 
-#if NCURSES_MOUSE_VERSION > 1
+#ifdef BUTTON5_PRESSED
     SetDictInt("BUTTON5_PRESSED",          BUTTON5_PRESSED);
     SetDictInt("BUTTON5_RELEASED",         BUTTON5_RELEASED);
     SetDictInt("BUTTON5_CLICKED",          BUTTON5_CLICKED);
diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h
index e69be47549cf65..da1b97c0ea5ad8 100644
--- a/Modules/clinic/_cursesmodule.c.h
+++ b/Modules/clinic/_cursesmodule.c.h
@@ -1048,7 +1048,7 @@ _curses_window_echochar(PyObject *self, PyObject *args)
     return return_value;
 }
 
-#if defined(NCURSES_MOUSE_VERSION)
+#if (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_window_enclose__doc__,
 "enclose($self, y, x, /)\n"
@@ -1091,9 +1091,9 @@ _curses_window_enclose(PyObject *self, PyObject *const 
*args, Py_ssize_t nargs)
     return return_value;
 }
 
-#endif /* defined(NCURSES_MOUSE_VERSION) */
+#endif /* (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)) */
 
-#if defined(NCURSES_MOUSE_VERSION)
+#if (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_window_mouse_trafo__doc__,
 "mouse_trafo($self, y, x, to_screen, /)\n"
@@ -1148,7 +1148,7 @@ _curses_window_mouse_trafo(PyObject *self, PyObject 
*const *args, Py_ssize_t nar
     return return_value;
 }
 
-#endif /* defined(NCURSES_MOUSE_VERSION) */
+#endif /* (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)) */
 
 PyDoc_STRVAR(_curses_window_getbkgd__doc__,
 "getbkgd($self, /)\n"
@@ -2473,7 +2473,7 @@ _curses_cbreak(PyObject *module, PyObject *const *args, 
Py_ssize_t nargs)
     return return_value;
 }
 
-#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427)
+#if ((defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) || 
defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_is_cbreak__doc__,
 "is_cbreak($module, /)\n"
@@ -2493,9 +2493,9 @@ _curses_is_cbreak(PyObject *module, PyObject 
*Py_UNUSED(ignored))
     return _curses_is_cbreak_impl(module);
 }
 
-#endif /* (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) */
+#endif /* ((defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) || 
defined(PDCURSES)) */
 
-#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427)
+#if ((defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) || 
defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_is_echo__doc__,
 "is_echo($module, /)\n"
@@ -2515,9 +2515,9 @@ _curses_is_echo(PyObject *module, PyObject 
*Py_UNUSED(ignored))
     return _curses_is_echo_impl(module);
 }
 
-#endif /* (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) */
+#endif /* ((defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) || 
defined(PDCURSES)) */
 
-#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427)
+#if ((defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) || 
defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_is_nl__doc__,
 "is_nl($module, /)\n"
@@ -2537,9 +2537,9 @@ _curses_is_nl(PyObject *module, PyObject 
*Py_UNUSED(ignored))
     return _curses_is_nl_impl(module);
 }
 
-#endif /* (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) */
+#endif /* ((defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) || 
defined(PDCURSES)) */
 
-#if (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427)
+#if ((defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) || 
defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_is_raw__doc__,
 "is_raw($module, /)\n"
@@ -2559,7 +2559,7 @@ _curses_is_raw(PyObject *module, PyObject 
*Py_UNUSED(ignored))
     return _curses_is_raw_impl(module);
 }
 
-#endif /* (defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) */
+#endif /* ((defined(NCURSES_EXT_FUNCS) && NCURSES_EXT_FUNCS >= 20240427) || 
defined(PDCURSES)) */
 
 PyDoc_STRVAR(_curses_color_content__doc__,
 "color_content($module, color_number, /)\n"
@@ -2921,7 +2921,7 @@ _curses_getsyx(PyObject *module, PyObject 
*Py_UNUSED(ignored))
 
 #endif /* defined(getsyx) */
 
-#if defined(NCURSES_MOUSE_VERSION)
+#if (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_getmouse__doc__,
 "getmouse($module, /)\n"
@@ -2944,9 +2944,9 @@ _curses_getmouse(PyObject *module, PyObject 
*Py_UNUSED(ignored))
     return _curses_getmouse_impl(module);
 }
 
-#endif /* defined(NCURSES_MOUSE_VERSION) */
+#endif /* (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)) */
 
-#if defined(NCURSES_MOUSE_VERSION)
+#if (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_ungetmouse__doc__,
 "ungetmouse($module, id, x, y, z, bstate, /)\n"
@@ -3033,7 +3033,7 @@ _curses_ungetmouse(PyObject *module, PyObject *const 
*args, Py_ssize_t nargs)
     return return_value;
 }
 
-#endif /* defined(NCURSES_MOUSE_VERSION) */
+#endif /* (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)) */
 
 PyDoc_STRVAR(_curses_getwin__doc__,
 "getwin($module, file, /)\n"
@@ -4232,7 +4232,7 @@ _curses_meta(PyObject *module, PyObject *arg)
     return return_value;
 }
 
-#if defined(NCURSES_MOUSE_VERSION) && (defined(NCURSES_EXT_FUNCS) && 
NCURSES_EXT_FUNCS >= 20081122)
+#if (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)) && 
(defined(HAVE_CURSES_HAS_MOUSE) || defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_has_mouse__doc__,
 "has_mouse($module, /)\n"
@@ -4252,9 +4252,9 @@ _curses_has_mouse(PyObject *module, PyObject 
*Py_UNUSED(ignored))
     return _curses_has_mouse_impl(module);
 }
 
-#endif /* defined(NCURSES_MOUSE_VERSION) && (defined(NCURSES_EXT_FUNCS) && 
NCURSES_EXT_FUNCS >= 20081122) */
+#endif /* (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)) && 
(defined(HAVE_CURSES_HAS_MOUSE) || defined(PDCURSES)) */
 
-#if defined(NCURSES_MOUSE_VERSION)
+#if (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_mouseinterval__doc__,
 "mouseinterval($module, interval, /)\n"
@@ -4291,9 +4291,9 @@ _curses_mouseinterval(PyObject *module, PyObject *arg)
     return return_value;
 }
 
-#endif /* defined(NCURSES_MOUSE_VERSION) */
+#endif /* (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)) */
 
-#if defined(NCURSES_MOUSE_VERSION)
+#if (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_mousemask__doc__,
 "mousemask($module, newmask, /)\n"
@@ -4344,7 +4344,7 @@ _curses_mousemask(PyObject *module, PyObject *arg)
     return return_value;
 }
 
-#endif /* defined(NCURSES_MOUSE_VERSION) */
+#endif /* (defined(HAVE_CURSES_GETMOUSE) || defined(PDCURSES)) */
 
 PyDoc_STRVAR(_curses_napms__doc__,
 "napms($module, ms, /)\n"
@@ -5733,7 +5733,7 @@ _curses_slk_attrset(PyObject *module, PyObject *arg)
     return return_value;
 }
 
-#if defined(NCURSES_EXT_FUNCS)
+#if (defined(NCURSES_EXT_FUNCS) || defined(PDCURSES))
 
 PyDoc_STRVAR(_curses_slk_attr__doc__,
 "slk_attr($module, /)\n"
@@ -5753,7 +5753,7 @@ _curses_slk_attr(PyObject *module, PyObject 
*Py_UNUSED(ignored))
     return _curses_slk_attr_impl(module);
 }
 
-#endif /* defined(NCURSES_EXT_FUNCS) */
+#endif /* (defined(NCURSES_EXT_FUNCS) || defined(PDCURSES)) */
 
 PyDoc_STRVAR(_curses_slk_attr_on__doc__,
 "slk_attr_on($module, attr, /)\n"
@@ -6174,4 +6174,4 @@ _curses_has_extended_color_support(PyObject *module, 
PyObject *Py_UNUSED(ignored
 #ifndef _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
     #define _CURSES_ASSUME_DEFAULT_COLORS_METHODDEF
 #endif /* !defined(_CURSES_ASSUME_DEFAULT_COLORS_METHODDEF) */
-/*[clinic end generated code: output=809e4680d429b870 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=36fcacafc5044720 input=a9049054013a1b77]*/
diff --git a/configure b/configure
index d0738c1909be7b..01faef615a3d5e 100755
--- a/configure
+++ b/configure
@@ -30420,6 +30420,186 @@ fi
 
 
 
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function 
has_mouse" >&5
+printf %s "checking for curses function has_mouse... " >&6; }
+if test ${ac_cv_lib_curses_has_mouse+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef has_mouse
+        void *x=has_mouse
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_has_mouse=yes
+else case e in #(
+  e) ac_cv_lib_curses_has_mouse=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 
$ac_cv_lib_curses_has_mouse" >&5
+printf "%s\n" "$ac_cv_lib_curses_has_mouse" >&6; }
+  if test "x$ac_cv_lib_curses_has_mouse" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_HAS_MOUSE 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function 
is_keypad" >&5
+printf %s "checking for curses function is_keypad... " >&6; }
+if test ${ac_cv_lib_curses_is_keypad+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef is_keypad
+        void *x=is_keypad
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_is_keypad=yes
+else case e in #(
+  e) ac_cv_lib_curses_is_keypad=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 
$ac_cv_lib_curses_is_keypad" >&5
+printf "%s\n" "$ac_cv_lib_curses_is_keypad" >&6; }
+  if test "x$ac_cv_lib_curses_is_keypad" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_IS_KEYPAD 1" >>confdefs.h
+
+fi
+
+
+
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function 
is_leaveok" >&5
+printf %s "checking for curses function is_leaveok... " >&6; }
+if test ${ac_cv_lib_curses_is_leaveok+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+
+        #ifndef is_leaveok
+        void *x=is_leaveok
+        #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_is_leaveok=yes
+else case e in #(
+  e) ac_cv_lib_curses_is_leaveok=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 
$ac_cv_lib_curses_is_leaveok" >&5
+printf "%s\n" "$ac_cv_lib_curses_is_leaveok" >&6; }
+  if test "x$ac_cv_lib_curses_is_leaveok" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_IS_LEAVEOK 1" >>confdefs.h
+
+fi
+
+
+
+
+
   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function 
typeahead" >&5
 printf %s "checking for curses function typeahead... " >&6; }
 if test ${ac_cv_lib_curses_typeahead+y}
@@ -31195,6 +31375,58 @@ fi
 
 
 
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncurses-style 
curses function getmouse" >&5
+printf %s "checking for ncurses-style curses function getmouse... " >&6; }
+if test ${ac_cv_lib_curses_getmouse+y}
+then :
+  printf %s "(cached) " >&6
+else case e in #(
+  e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+#  include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+#  include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+#  include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+#  include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+#  include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+#  include <curses.h>
+#endif
+
+int
+main (void)
+{
+MEVENT event; (void)getmouse(&event);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_lib_curses_getmouse=yes
+else case e in #(
+  e) ac_cv_lib_curses_getmouse=no ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: 
$ac_cv_lib_curses_getmouse" >&5
+printf "%s\n" "$ac_cv_lib_curses_getmouse" >&6; }
+if test "x$ac_cv_lib_curses_getmouse" = xyes
+then :
+
+printf "%s\n" "#define HAVE_CURSES_GETMOUSE 1" >>confdefs.h
+
+fi
+
+
 
   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function 
scr_dump" >&5
 printf %s "checking for curses function scr_dump... " >&6; }
diff --git a/configure.ac b/configure.ac
index 622d6f6593a1a9..a9fe5c269618fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7219,6 +7219,9 @@ PY_CHECK_CURSES_FUNC([wchgat])
 PY_CHECK_CURSES_FUNC([filter])
 PY_CHECK_CURSES_FUNC([nofilter])
 PY_CHECK_CURSES_FUNC([has_key])
+PY_CHECK_CURSES_FUNC([has_mouse])
+PY_CHECK_CURSES_FUNC([is_keypad])
+PY_CHECK_CURSES_FUNC([is_leaveok])
 PY_CHECK_CURSES_FUNC([typeahead])
 PY_CHECK_CURSES_FUNC([use_env])
 PY_CHECK_CURSES_FUNC([new_prescr])
@@ -7232,6 +7235,19 @@ PY_CHECK_CURSES_FUNC([set_escdelay])
 PY_CHECK_CURSES_FUNC([set_tabsize])
 PY_CHECK_CURSES_VAR([ESCDELAY])
 PY_CHECK_CURSES_VAR([TABSIZE])
+
+dnl Probe for the X/Open getmouse(MEVENT *) signature specifically: PDCurses
+dnl declares an incompatible getmouse(void) unless built for the ncurses mouse 
API.
+AC_CACHE_CHECK([for ncurses-style curses function getmouse],
+  [ac_cv_lib_curses_getmouse],
+  [AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM(_CURSES_INCLUDES, [MEVENT event; 
(void)getmouse(&event);])],
+    [ac_cv_lib_curses_getmouse=yes],
+    [ac_cv_lib_curses_getmouse=no])])
+AS_VAR_IF([ac_cv_lib_curses_getmouse], [yes],
+  [AC_DEFINE([HAVE_CURSES_GETMOUSE], [1],
+    [Define if you have the 'getmouse' function with the X/Open signature.])])
+
 dnl scr_dump and its companions scr_restore/scr_init/scr_set are an inseparable
 dnl group; probing scr_dump alone gates the whole family.
 PY_CHECK_CURSES_FUNC([scr_dump])
diff --git a/pyconfig.h.in b/pyconfig.h.in
index 45db7b1dc57a96..ce97099315bfe4 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -209,15 +209,27 @@
 /* Define if you have the 'filter' function. */
 #undef HAVE_CURSES_FILTER
 
+/* Define if you have the 'getmouse' function with the X/Open signature. */
+#undef HAVE_CURSES_GETMOUSE
+
 /* Define to 1 if you have the <curses.h> header file. */
 #undef HAVE_CURSES_H
 
 /* Define if you have the 'has_key' function. */
 #undef HAVE_CURSES_HAS_KEY
 
+/* Define if you have the 'has_mouse' function. */
+#undef HAVE_CURSES_HAS_MOUSE
+
 /* Define if you have the 'immedok' function. */
 #undef HAVE_CURSES_IMMEDOK
 
+/* Define if you have the 'is_keypad' function. */
+#undef HAVE_CURSES_IS_KEYPAD
+
+/* Define if you have the 'is_leaveok' function. */
+#undef HAVE_CURSES_IS_LEAVEOK
+
 /* Define if you have the 'is_pad' function. */
 #undef HAVE_CURSES_IS_PAD
 

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to