Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Doc/library/curses.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 7 additions & 0 deletions Include/py_curses.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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``).
71 changes: 42 additions & 29 deletions Modules/_cursesmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand All @@ -4890,15 +4898,15 @@ 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."},
#endif
{"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."},
Expand Down Expand Up @@ -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()."},
Expand All @@ -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()."},
Expand All @@ -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"
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
Loading
Loading