├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── build-wheels.bat ├── examples ├── README ├── life.py ├── ncurses.py ├── rain.py ├── repeat.py ├── tclock.py └── xmas.py ├── py27 ├── _curses_panel.c └── _cursesmodule.c ├── py310 ├── _curses_panel.c ├── _cursesmodule.c └── clinic │ ├── _curses_panel.c.h │ └── _cursesmodule.c.h ├── py311 ├── _curses_panel.c ├── _cursesmodule.c └── clinic │ ├── _curses_panel.c.h │ └── _cursesmodule.c.h ├── py312 ├── _curses_panel.c ├── _cursesmodule.c └── clinic │ ├── _curses_panel.c.h │ └── _cursesmodule.c.h ├── py313 ├── _curses_panel.c ├── _cursesmodule.c └── clinic │ ├── _curses_panel.c.h │ └── _cursesmodule.c.h ├── py34 ├── _curses_panel.c ├── _cursesmodule.c ├── clinic │ └── _cursesmodule.c.h └── mkstemp.c ├── py35 ├── _curses_panel.c ├── _cursesmodule.c └── clinic │ └── _cursesmodule.c.h ├── py36 ├── _curses_panel.c ├── _cursesmodule.c └── clinic │ └── _cursesmodule.c.h ├── py37 ├── _curses_panel.c ├── _cursesmodule.c └── clinic │ └── _cursesmodule.c.h ├── py38 ├── _curses_panel.c ├── _cursesmodule.c └── clinic │ ├── _curses_panel.c.h │ └── _cursesmodule.c.h ├── py39 ├── _curses_panel.c ├── _cursesmodule.c └── clinic │ ├── _curses_panel.c.h │ └── _cursesmodule.c.h ├── setup.py ├── term.h └── terminfo.c /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - v*-branch 8 | pull_request: 9 | branches: 10 | - main 11 | - v*-branch 12 | workflow_call: 13 | 14 | concurrency: 15 | group: ${{ github.ref }} 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | build: 20 | name: Build (Python ${{ matrix.target.python }}, ${{ matrix.arch }}) 21 | runs-on: ${{ matrix.target.builder }} 22 | 23 | defaults: 24 | run: 25 | shell: bash 26 | 27 | strategy: 28 | fail-fast: false 29 | matrix: 30 | target: 31 | # Python 3.6 32 | - python: '3.6' 33 | builder: windows-2019 34 | toolset: '14.25' # Visual Studio 2019 35 | winsdk: '10.0.14393.0' # Windows 10 1607 36 | # Python 3.7 37 | - python: '3.7' 38 | builder: windows-2019 39 | toolset: '14.25' # Visual Studio 2019 40 | winsdk: '10.0.14393.0' # Windows 10 1607 41 | # Python 3.8 42 | - python: '3.8' 43 | builder: windows-2019 44 | toolset: '14.25' # Visual Studio 2019 45 | winsdk: '10.0.14393.0' # Windows 10 1607 46 | # Python 3.9 47 | - python: '3.9' 48 | builder: windows-2019 49 | toolset: '14.25' # Visual Studio 2019 50 | winsdk: '10.0.14393.0' # Windows 10 1607 51 | # Python 3.10 52 | - python: '3.10' 53 | builder: windows-2022 54 | toolset: '14.42' # Visual Studio 2022 55 | winsdk: '10.0.17763.0' # Windows 10 1809 56 | # Python 3.11 57 | - python: '3.11' 58 | builder: windows-2022 59 | toolset: '14.42' # Visual Studio 2022 60 | winsdk: '10.0.17763.0' # Windows 10 1809 61 | # Python 3.12 62 | - python: '3.12' 63 | builder: windows-2022 64 | toolset: '14.42' # Visual Studio 2022 65 | winsdk: '10.0.17763.0' # Windows 10 1809 66 | # Python 3.13 67 | - python: '3.13' 68 | builder: windows-2022 69 | toolset: '14.42' # Visual Studio 2022 70 | winsdk: '10.0.17763.0' # Windows 10 1809 71 | arch: 72 | - x86 73 | - x64 74 | 75 | steps: 76 | - name: Set up Python 77 | uses: actions/setup-python@v5 78 | with: 79 | python-version: ${{ matrix.target.python }} 80 | architecture: ${{ matrix.arch }} 81 | 82 | - name: Check Python version 83 | run: | 84 | set -x 85 | python --version 86 | pip --version 87 | python -c "import platform; print(platform.architecture())" 88 | 89 | - name: Install Python dependencies 90 | run: | 91 | pip install --user setuptools wheel 92 | 93 | - name: Set up Visual Studio Build Tools 94 | uses: ilammy/msvc-dev-cmd@v1 95 | with: 96 | arch: ${{ matrix.arch }} 97 | sdk: ${{ matrix.target.winsdk }} 98 | toolset: ${{ matrix.target.toolset }} 99 | 100 | - name: Checkout 101 | uses: actions/checkout@v4 102 | with: 103 | submodules: recursive 104 | 105 | - name: Build wheel 106 | id: build-wheel 107 | run: | 108 | ./build-wheels.bat ${{ matrix.target.python }}${{ matrix.arch == 'x86' && '-32' || '' }} 109 | ls -l dist 110 | files=(dist/*.whl) 111 | filename=$(basename ${files[0]}) 112 | echo "filename=${filename}" >> $GITHUB_OUTPUT 113 | 114 | - name: Test wheel 115 | run: | 116 | pip install --user dist/${{ steps.build-wheel.outputs.filename }} 117 | 118 | - name: Upload build artifact 119 | uses: actions/upload-artifact@v4 120 | with: 121 | name: ${{ steps.build-wheel.outputs.filename }} 122 | path: dist/${{ steps.build-wheel.outputs.filename }} 123 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | release: 5 | types: [ published ] 6 | 7 | jobs: 8 | ci: 9 | name: CI 10 | uses: ./.github/workflows/ci.yml 11 | 12 | release: 13 | name: Release 14 | environment: release 15 | needs: [ ci ] 16 | runs-on: ubuntu-20.04 17 | 18 | permissions: 19 | contents: write 20 | id-token: write 21 | 22 | steps: 23 | - name: Download build artifacts 24 | uses: actions/download-artifact@v4 25 | with: 26 | path: artifacts 27 | 28 | - name: Prepare release assets 29 | run: | 30 | mkdir -p assets 31 | cp artifacts/*/*.whl assets 32 | 33 | - name: Upload release assets 34 | uses: softprops/action-gh-release@v2 35 | with: 36 | files: | 37 | assets/*.whl 38 | 39 | - name: Publish package to PyPI 40 | uses: pypa/gh-action-pypi-publish@release/v1 41 | with: 42 | packages-dir: assets/ 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | dist 3 | *.egg-info 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "PDCurses"] 2 | path = PDCurses 3 | url = https://github.com/zephyrproject-rtos/PDCurses.git 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | A. HISTORY OF THE SOFTWARE 2 | ========================== 3 | 4 | Python was created in the early 1990s by Guido van Rossum at Stichting 5 | Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands 6 | as a successor of a language called ABC. Guido remains Python's 7 | principal author, although it includes many contributions from others. 8 | 9 | In 1995, Guido continued his work on Python at the Corporation for 10 | National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) 11 | in Reston, Virginia where he released several versions of the 12 | software. 13 | 14 | In May 2000, Guido and the Python core development team moved to 15 | BeOpen.com to form the BeOpen PythonLabs team. In October of the same 16 | year, the PythonLabs team moved to Digital Creations, which became 17 | Zope Corporation. In 2001, the Python Software Foundation (PSF, see 18 | https://www.python.org/psf/) was formed, a non-profit organization 19 | created specifically to own Python-related Intellectual Property. 20 | Zope Corporation was a sponsoring member of the PSF. 21 | 22 | All Python releases are Open Source (see http://www.opensource.org for 23 | the Open Source Definition). Historically, most, but not all, Python 24 | releases have also been GPL-compatible; the table below summarizes 25 | the various releases. 26 | 27 | Release Derived Year Owner GPL- 28 | from compatible? (1) 29 | 30 | 0.9.0 thru 1.2 1991-1995 CWI yes 31 | 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes 32 | 1.6 1.5.2 2000 CNRI no 33 | 2.0 1.6 2000 BeOpen.com no 34 | 1.6.1 1.6 2001 CNRI yes (2) 35 | 2.1 2.0+1.6.1 2001 PSF no 36 | 2.0.1 2.0+1.6.1 2001 PSF yes 37 | 2.1.1 2.1+2.0.1 2001 PSF yes 38 | 2.1.2 2.1.1 2002 PSF yes 39 | 2.1.3 2.1.2 2002 PSF yes 40 | 2.2 and above 2.1.1 2001-now PSF yes 41 | 42 | Footnotes: 43 | 44 | (1) GPL-compatible doesn't mean that we're distributing Python under 45 | the GPL. All Python licenses, unlike the GPL, let you distribute 46 | a modified version without making your changes open source. The 47 | GPL-compatible licenses make it possible to combine Python with 48 | other software that is released under the GPL; the others don't. 49 | 50 | (2) According to Richard Stallman, 1.6.1 is not GPL-compatible, 51 | because its license has a choice of law clause. According to 52 | CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 53 | is "not incompatible" with the GPL. 54 | 55 | Thanks to the many outside volunteers who have worked under Guido's 56 | direction to make these releases possible. 57 | 58 | 59 | B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON 60 | =============================================================== 61 | 62 | PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 63 | -------------------------------------------- 64 | 65 | 1. This LICENSE AGREEMENT is between the Python Software Foundation 66 | ("PSF"), and the Individual or Organization ("Licensee") accessing and 67 | otherwise using this software ("Python") in source or binary form and 68 | its associated documentation. 69 | 70 | 2. Subject to the terms and conditions of this License Agreement, PSF hereby 71 | grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, 72 | analyze, test, perform and/or display publicly, prepare derivative works, 73 | distribute, and otherwise use Python alone or in any derivative version, 74 | provided, however, that PSF's License Agreement and PSF's notice of copyright, 75 | i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 76 | 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation; All 77 | Rights Reserved" are retained in Python alone or in any derivative version 78 | prepared by Licensee. 79 | 80 | 3. In the event Licensee prepares a derivative work that is based on 81 | or incorporates Python or any part thereof, and wants to make 82 | the derivative work available to others as provided herein, then 83 | Licensee hereby agrees to include in any such work a brief summary of 84 | the changes made to Python. 85 | 86 | 4. PSF is making Python available to Licensee on an "AS IS" 87 | basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR 88 | IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND 89 | DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS 90 | FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT 91 | INFRINGE ANY THIRD PARTY RIGHTS. 92 | 93 | 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 94 | FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS 95 | A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, 96 | OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 97 | 98 | 6. This License Agreement will automatically terminate upon a material 99 | breach of its terms and conditions. 100 | 101 | 7. Nothing in this License Agreement shall be deemed to create any 102 | relationship of agency, partnership, or joint venture between PSF and 103 | Licensee. This License Agreement does not grant permission to use PSF 104 | trademarks or trade name in a trademark sense to endorse or promote 105 | products or services of Licensee, or any third party. 106 | 107 | 8. By copying, installing or otherwise using Python, Licensee 108 | agrees to be bound by the terms and conditions of this License 109 | Agreement. 110 | 111 | 112 | BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 113 | ------------------------------------------- 114 | 115 | BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 116 | 117 | 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an 118 | office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the 119 | Individual or Organization ("Licensee") accessing and otherwise using 120 | this software in source or binary form and its associated 121 | documentation ("the Software"). 122 | 123 | 2. Subject to the terms and conditions of this BeOpen Python License 124 | Agreement, BeOpen hereby grants Licensee a non-exclusive, 125 | royalty-free, world-wide license to reproduce, analyze, test, perform 126 | and/or display publicly, prepare derivative works, distribute, and 127 | otherwise use the Software alone or in any derivative version, 128 | provided, however, that the BeOpen Python License is retained in the 129 | Software, alone or in any derivative version prepared by Licensee. 130 | 131 | 3. BeOpen is making the Software available to Licensee on an "AS IS" 132 | basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR 133 | IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND 134 | DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS 135 | FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT 136 | INFRINGE ANY THIRD PARTY RIGHTS. 137 | 138 | 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE 139 | SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS 140 | AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY 141 | DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 142 | 143 | 5. This License Agreement will automatically terminate upon a material 144 | breach of its terms and conditions. 145 | 146 | 6. This License Agreement shall be governed by and interpreted in all 147 | respects by the law of the State of California, excluding conflict of 148 | law provisions. Nothing in this License Agreement shall be deemed to 149 | create any relationship of agency, partnership, or joint venture 150 | between BeOpen and Licensee. This License Agreement does not grant 151 | permission to use BeOpen trademarks or trade names in a trademark 152 | sense to endorse or promote products or services of Licensee, or any 153 | third party. As an exception, the "BeOpen Python" logos available at 154 | http://www.pythonlabs.com/logos.html may be used according to the 155 | permissions granted on that web page. 156 | 157 | 7. By copying, installing or otherwise using the software, Licensee 158 | agrees to be bound by the terms and conditions of this License 159 | Agreement. 160 | 161 | 162 | CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 163 | --------------------------------------- 164 | 165 | 1. This LICENSE AGREEMENT is between the Corporation for National 166 | Research Initiatives, having an office at 1895 Preston White Drive, 167 | Reston, VA 20191 ("CNRI"), and the Individual or Organization 168 | ("Licensee") accessing and otherwise using Python 1.6.1 software in 169 | source or binary form and its associated documentation. 170 | 171 | 2. Subject to the terms and conditions of this License Agreement, CNRI 172 | hereby grants Licensee a nonexclusive, royalty-free, world-wide 173 | license to reproduce, analyze, test, perform and/or display publicly, 174 | prepare derivative works, distribute, and otherwise use Python 1.6.1 175 | alone or in any derivative version, provided, however, that CNRI's 176 | License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) 177 | 1995-2001 Corporation for National Research Initiatives; All Rights 178 | Reserved" are retained in Python 1.6.1 alone or in any derivative 179 | version prepared by Licensee. Alternately, in lieu of CNRI's License 180 | Agreement, Licensee may substitute the following text (omitting the 181 | quotes): "Python 1.6.1 is made available subject to the terms and 182 | conditions in CNRI's License Agreement. This Agreement together with 183 | Python 1.6.1 may be located on the Internet using the following 184 | unique, persistent identifier (known as a handle): 1895.22/1013. This 185 | Agreement may also be obtained from a proxy server on the Internet 186 | using the following URL: http://hdl.handle.net/1895.22/1013". 187 | 188 | 3. In the event Licensee prepares a derivative work that is based on 189 | or incorporates Python 1.6.1 or any part thereof, and wants to make 190 | the derivative work available to others as provided herein, then 191 | Licensee hereby agrees to include in any such work a brief summary of 192 | the changes made to Python 1.6.1. 193 | 194 | 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" 195 | basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR 196 | IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND 197 | DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS 198 | FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT 199 | INFRINGE ANY THIRD PARTY RIGHTS. 200 | 201 | 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 202 | 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS 203 | A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, 204 | OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 205 | 206 | 6. This License Agreement will automatically terminate upon a material 207 | breach of its terms and conditions. 208 | 209 | 7. This License Agreement shall be governed by the federal 210 | intellectual property law of the United States, including without 211 | limitation the federal copyright law, and, to the extent such 212 | U.S. federal law does not apply, by the law of the Commonwealth of 213 | Virginia, excluding Virginia's conflict of law provisions. 214 | Notwithstanding the foregoing, with regard to derivative works based 215 | on Python 1.6.1 that incorporate non-separable material that was 216 | previously distributed under the GNU General Public License (GPL), the 217 | law of the Commonwealth of Virginia shall govern this License 218 | Agreement only as to issues arising under or with respect to 219 | Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this 220 | License Agreement shall be deemed to create any relationship of 221 | agency, partnership, or joint venture between CNRI and Licensee. This 222 | License Agreement does not grant permission to use CNRI trademarks or 223 | trade name in a trademark sense to endorse or promote products or 224 | services of Licensee, or any third party. 225 | 226 | 8. By clicking on the "ACCEPT" button where indicated, or by copying, 227 | installing or otherwise using Python 1.6.1, Licensee agrees to be 228 | bound by the terms and conditions of this License Agreement. 229 | 230 | ACCEPT 231 | 232 | 233 | CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 234 | -------------------------------------------------- 235 | 236 | Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, 237 | The Netherlands. All rights reserved. 238 | 239 | Permission to use, copy, modify, and distribute this software and its 240 | documentation for any purpose and without fee is hereby granted, 241 | provided that the above copyright notice appear in all copies and that 242 | both that copyright notice and this permission notice appear in 243 | supporting documentation, and that the name of Stichting Mathematisch 244 | Centrum or CWI not be used in advertising or publicity pertaining to 245 | distribution of the software without specific, written prior 246 | permission. 247 | 248 | STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO 249 | THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 250 | FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE 251 | FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 252 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 253 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 254 | OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 255 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Python curses wheels for Windows 2 | ================================ 3 | 4 | ![Latest Version](https://img.shields.io/pypi/v/windows-curses) 5 | ![Supported Python Implementations](https://img.shields.io/pypi/implementation/windows-curses) 6 | 7 | This is the repository for the [windows-curses wheels on 8 | PyPI](https://pypi.org/project/windows-curses). The wheels are based on the 9 | [wheels on Christoph Gohlke's 10 | page](https://www.lfd.uci.edu/~gohlke/pythonlibs/#curses). 11 | 12 | Only `build-wheels.bat` is original work. 13 | 14 | Wheels built from this repository can be installed with this command: 15 | 16 | pip install windows-curses 17 | 18 | Starting with version 2.0, these wheels include a hack to make resizing work 19 | for Python applications that haven't been specifically adapted for PDCurses. 20 | See [this 21 | commit](https://github.com/zephyrproject-rtos/windows-curses/commit/30ca08bfbcb7a332228ddcde026181b2009ea0a7). 22 | The description on PyPI has a longer explanation. 23 | 24 | Note that this hack is not in Gohlke's wheels. 25 | 26 | Maintainers Wanted 27 | ------------------ 28 | 29 | This project is not actively maintained and is looking for maintainers. 30 | 31 | If you are interested, please let us know by either creating an issue here or messaging in the 32 | [#windows-support channel on Zephyr Discord](https://discord.gg/ygfnbCZCtU). 33 | 34 | Background 35 | ---------- 36 | 37 | The `curses` module is in the Python standard library, but is not available on 38 | Windows. Trying to import `curses` gives an import error for `_curses`, which 39 | is provided by `Modules/_cursesmodule.c` in the CPython source code. 40 | 41 | The wheels provided here are based on patches from 42 | https://bugs.python.org/issue2889, which make minor modifications to 43 | `_cursesmodule.c` to make it compatible with Windows and the 44 | [PDCurses](https://pdcurses.sourceforge.io) curses implementation. `setup.py` 45 | defines `HAVE_*` macros for features available in PDCurses and makes some minor 46 | additional compatibility tweaks. 47 | 48 | The patched `_cursesmodule.c` is linked against PDCurses to produce a wheel 49 | that provides the `_curses` module on Windows and allows the standard `curses` 50 | module to run. 51 | 52 | Unicode support 53 | --------------- 54 | 55 | The wheels are built with wide character support and force the encoding to 56 | UTF-8. Remove `UTF8=y` from the `nmake` line in `build-wheels.bat` to use the 57 | default system encoding instead. 58 | 59 | Build instructions 60 | ------------------ 61 | 62 | 1. Clone the repository with the following command: 63 | 64 | git clone --recurse-submodules https://github.com/zephyrproject-rtos/windows-curses.git 65 | 66 | `--recurse-submodules` pulls in the required PDCurses Git submodule. 67 | 68 | 2. Install compilers compatible with the Python versions that you want to 69 | builds wheel for by following the instructions at 70 | https://wiki.python.org/moin/WindowsCompilers. 71 | 72 | Visual Studio 2019 will work for Python 3.6-3.9. 73 | 74 | Visual Studio 2022 will work for Python 3.10-3.13. 75 | 76 | 3. Install Python 3.6 or later to get 77 | the [Python launcher for Windows](https://docs.python.org/3/using/windows.html#launcher). 78 | 79 | 4. Install any other Python versions you want to build wheels for. 80 | 81 | Only the Python X.Y versions that have `pyXY\` directories are supported. 82 | 83 | 5. Install/upgrade the `wheel` and `setuptools` packages for all Python 84 | versions. Taking Python 3.6 as an example, the following command will do 85 | it: 86 | 87 | py -3.6 -m pip install --upgrade wheel setuptools 88 | 89 | `py` is the Python launcher, which makes it easy to run a particular Python 90 | version. 91 | 92 | 6. Open the Visual Studio 93 | [Developer Command Prompt](https://docs.microsoft.com/en-us/dotnet/framework/tools/developer-command-prompt-for-vs) 94 | of the compiler required by the version of Python that you want to build 95 | a wheel for. 96 | 97 | Use the 32-bit version (`x86 Native Tools Command Prompt for VS 2022`) to build wheels for 32-bit 98 | Python versions, and the 64-bit version (e.g. 99 | `x64 Native Tools Command Prompt for VS 2022`) to build wheels for 64-bit Python versions. 100 | 101 | 7. Run `build-wheels.bat`, passing it the Python version you're building a 102 | wheel for. For example, the following command will build a wheel for 103 | Python 3.6: 104 | 105 | build-wheels.bat 3.6 106 | 107 | If you have both 32-bit and 64-bit versions of the same Python version 108 | installed and are building a 32-bit wheel, add "-32" to the version 109 | number, like in the following example: 110 | 111 | build-wheels.bat 3.6-32 112 | 113 | If you are building multiple wheels for Python versions that are all 114 | compatible with the same compiler, you can list all of them in the same 115 | command: 116 | 117 | build-wheels.bat 3.6 3.7 118 | 119 | `build-wheels.bat` first cleans and rebuilds PDCurses, and then builds and 120 | links the source code in `pyXY\` for each of the specified Python versions, 121 | producing wheels as output in `dist\`. 122 | 123 | ### Rebuilding the wheels for Python 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, and 3.13 124 | 125 | In `x86 Native Tools Command Prompt for VS 2022`: 126 | 127 | build-wheels.bat 3.6-32 3.7-32 3.8-32 3.9-32 3.10-32 3.11-32 3.12-32 3.13-32 128 | 129 | In `x64 Native Tools Command Prompt for VS 2022`: 130 | 131 | build-wheels.bat 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 132 | 133 | 134 | This gives a set of wheels in `dist\`. 135 | 136 | Compatibility note 137 | ------------------ 138 | 139 | This building scheme above should be the safest one to use. In practice, many 140 | of the resulting wheels seem to be forwards- and backwards-compatible. 141 | 142 | Making a new release 143 | -------------------- 144 | 145 | 1. Bump the version number in `setup.py` according to the [Semantic versioning](https://semver.org/). 146 | 147 | 2. Create a Git tag for the release: 148 | 149 | git tag -s -m "windows-curses 1.2.3" v1.2.3 150 | git push upstream v1.2.3 151 | 152 | For pre-releases, add `aNUMBER` after the release name (e.g. `v1.2.3a1`, `v1.2.3a2`, ...). 153 | 154 | 3. [Create a GitHub release](https://github.com/zephyrproject-rtos/windows-curses/releases/new) 155 | from the tag. 156 | 157 | The name of the GitHub release should match the name of the release tag (e.g. `v1.2.3`) and its 158 | body should contain a brief release note. 159 | 160 | Once a GitHub release is created, the GitHub Actions CI will automatically build and upload the 161 | wheels to the PyPI. 162 | 163 | Uploading to PyPI 164 | ----------------- 165 | 166 | **NOTE: The process of uploading wheels for releases is automated using the GitHub Actions and 167 | manual uploads should not be necessary under normal circumstances.** 168 | 169 | Don't forget to bump the version number in `setup.py` before building new 170 | wheels. [Semantic versioning](https://semver.org/) is intended. 171 | 172 | Once the wheels are built, follow the instructions 173 | [here](https://packaging.python.org/tutorials/distributing-packages/#uploading-your-project-to-pypi) 174 | to upload them to PyPI. 175 | 176 | `pip`/PyPI will look at the wheel metadata and automatically install the right 177 | version of the wheel. 178 | 179 | Adding support for a new Python version 180 | --------------------------------------- 181 | 182 | 1. Create a new directory `pyXY` for the Python version X.Y (e.g. `py39` for 183 | Python 3.9). 184 | 185 | 2. Copy `Modules/_cursesmodule.c` and `Modules/_curses_panel.c` from the 186 | CPython source code to `pyXY/_cursesmodule.c` and `pyXY/_curses_panel.c`, 187 | respectively. 188 | 189 | 3. Apply the following PDCurses compatibility patches: 190 | 191 | * https://github.com/zephyrproject-rtos/windows-curses/commit/b1cf4e10cecb9ba3e43766407c2ed2b138571f85 192 | * https://github.com/zephyrproject-rtos/windows-curses/commit/30ca08bfbcb7a332228ddcde026181b2009ea0a7 193 | * https://github.com/zephyrproject-rtos/windows-curses/commit/3e4fa8c6427483641300efb21a3e9af78b146c83 194 | 195 | 4. Run `Tools/clinic/clinic.py` script from the CPython source code on 196 | `pyXY/_cursesmodule.c` and `pyXY/_curses_panel.c` in order to generate the 197 | respective header files under `pyXY/clinic/`. 198 | 199 | 5. Add the build specifications for the new Python version in 200 | `.github/workflows/ci.yml`. 201 | 202 | In practice, `Modules\_cursesmodule.c` from newer Python 3 versions is likely 203 | to be compatible with older Python 3 versions too. The Python 3.6 and 3.7 204 | wheels are currently built from identical `_cursesmodule.c` files (but not the 205 | Python 3.8 or 3.9 wheels). 206 | -------------------------------------------------------------------------------- /build-wheels.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | if -%1-==-- ( 4 | echo Usage: %0 ^ [^ ...] 5 | exit /b 1 6 | ) 7 | 8 | 9 | :: 10 | :: Build PDCurses 11 | :: 12 | 13 | :: nmake doesn't seem to have an option for switching the working directory 14 | pushd PDCurses\wincon 15 | 16 | :: Always build PDCurses from scratch. This avoids issues with doing a 32-bit 17 | :: build after a 64-bit build for example. 18 | 19 | echo Cleaning PDCurses 20 | 21 | nmake -f Makefile.vc clean 22 | 23 | echo Building PDCurses 24 | 25 | nmake -f Makefile.vc WIDE=y UTF8=y 26 | if %errorlevel% neq 0 ( 27 | popd 28 | echo Check that you're using the Developer Command Prompt 29 | exit /b %errorlevel% 30 | ) 31 | 32 | popd 33 | 34 | 35 | :: 36 | :: Build wheels 37 | :: 38 | 39 | :: Process arguments one by one 40 | :nextarg 41 | if -%1-==-- goto end 42 | 43 | echo Building wheel for Python %1 44 | 45 | :: Clean the setuptools build directory before building the wheel, to make sure 46 | :: we build from scratch 47 | py -%1 setup.py clean --all build_ext bdist_wheel 48 | if %errorlevel% neq 0 ( 49 | echo Check that you have the 'wheel' module installed for Python %1 and are 50 | echo building with the right compiler 51 | exit /b %errorlevel% 52 | ) 53 | 54 | shift 55 | goto nextarg 56 | :end 57 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | This is a collection of demos and tests for the curses module. 2 | 3 | ncurses demos 4 | ============= 5 | 6 | These demos are converted from the C versions in the ncurses 7 | distribution, and were contributed by Thomas Gellekum 8 | I didn't strive for a `pythonic' style, but bluntly copied the 9 | originals. I won't attempt to `beautify' the program anytime soon, but 10 | I wouldn't mind someone else making an effort in that direction, of 11 | course. 12 | 13 | ncurses.py -- currently only a panels demo 14 | rain.py -- raindrops keep falling on my desktop 15 | tclock.py -- ASCII clock, by Howard Jones 16 | xmas.py -- I'm dreaming of an ASCII christmas 17 | 18 | Please submit bugfixes and new contributions to the Python bug tracker. 19 | 20 | 21 | Other demos 22 | =========== 23 | 24 | life.py -- Simple game of Life 25 | repeat.py -- Repeatedly execute a shell command (like watch(1)) 26 | -------------------------------------------------------------------------------- /examples/life.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # life.py -- A curses-based version of Conway's Game of Life. 3 | # Contributed by AMK 4 | # 5 | # An empty board will be displayed, and the following commands are available: 6 | # E : Erase the board 7 | # R : Fill the board randomly 8 | # S : Step for a single generation 9 | # C : Update continuously until a key is struck 10 | # Q : Quit 11 | # Cursor keys : Move the cursor around the board 12 | # Space or Enter : Toggle the contents of the cursor's position 13 | # 14 | # TODO : 15 | # Support the mouse 16 | # Use colour if available 17 | # Make board updates faster 18 | # 19 | 20 | import random, string, traceback 21 | import curses 22 | 23 | class LifeBoard: 24 | """Encapsulates a Life board 25 | 26 | Attributes: 27 | X,Y : horizontal and vertical size of the board 28 | state : dictionary mapping (x,y) to 0 or 1 29 | 30 | Methods: 31 | display(update_board) -- If update_board is true, compute the 32 | next generation. Then display the state 33 | of the board and refresh the screen. 34 | erase() -- clear the entire board 35 | makeRandom() -- fill the board randomly 36 | set(y,x) -- set the given cell to Live; doesn't refresh the screen 37 | toggle(y,x) -- change the given cell from live to dead, or vice 38 | versa, and refresh the screen display 39 | 40 | """ 41 | def __init__(self, scr, char=ord('*')): 42 | """Create a new LifeBoard instance. 43 | 44 | scr -- curses screen object to use for display 45 | char -- character used to render live cells (default: '*') 46 | """ 47 | self.state = {} 48 | self.scr = scr 49 | Y, X = self.scr.getmaxyx() 50 | self.X, self.Y = X-2, Y-2-1 51 | self.char = char 52 | self.scr.clear() 53 | 54 | # Draw a border around the board 55 | border_line = '+'+(self.X*'-')+'+' 56 | self.scr.addstr(0, 0, border_line) 57 | self.scr.addstr(self.Y+1,0, border_line) 58 | for y in range(0, self.Y): 59 | self.scr.addstr(1+y, 0, '|') 60 | self.scr.addstr(1+y, self.X+1, '|') 61 | self.scr.refresh() 62 | 63 | def set(self, y, x): 64 | """Set a cell to the live state""" 65 | if x<0 or self.X<=x or y<0 or self.Y<=y: 66 | raise ValueError("Coordinates out of range %i,%i"% (y,x)) 67 | self.state[x,y] = 1 68 | 69 | def toggle(self, y, x): 70 | """Toggle a cell's state between live and dead""" 71 | if x<0 or self.X<=x or y<0 or self.Y<=y: 72 | raise ValueError("Coordinates out of range %i,%i"% (y,x)) 73 | if (x, y) in self.state: 74 | del self.state[x,y] 75 | self.scr.addch(y+1, x+1, ' ') 76 | else: 77 | self.state[x,y] = 1 78 | self.scr.addch(y+1, x+1, self.char) 79 | self.scr.refresh() 80 | 81 | def erase(self): 82 | """Clear the entire board and update the board display""" 83 | self.state = {} 84 | self.display(update_board=False) 85 | 86 | def display(self, update_board=True): 87 | """Display the whole board, optionally computing one generation""" 88 | M,N = self.X, self.Y 89 | if not update_board: 90 | for i in range(0, M): 91 | for j in range(0, N): 92 | if (i, j) in self.state: 93 | self.scr.addch(j+1, i+1, self.char) 94 | else: 95 | self.scr.addch(j+1, i+1, ' ') 96 | self.scr.refresh() 97 | return 98 | 99 | d = {} 100 | self.boring = 1 101 | for i in range(0, M): 102 | L = range( max(0, i-1), min(M, i+2) ) 103 | for j in range(0, N): 104 | s = 0 105 | live = (i, j) in self.state 106 | for k in range( max(0, j-1), min(N, j+2) ): 107 | for l in L: 108 | if (l, k) in self.state: 109 | s += 1 110 | s -= live 111 | if s == 3: 112 | # Birth 113 | d[i,j] = 1 114 | self.scr.addch(j+1, i+1, self.char) 115 | if not live: self.boring = 0 116 | elif s == 2 and live: d[i,j] = 1 # Survival 117 | elif live: 118 | # Death 119 | self.scr.addch(j+1, i+1, ' ') 120 | self.boring = 0 121 | self.state = d 122 | self.scr.refresh() 123 | 124 | def makeRandom(self): 125 | "Fill the board with a random pattern" 126 | self.state = {} 127 | for i in range(0, self.X): 128 | for j in range(0, self.Y): 129 | if random.random() > 0.5: 130 | self.set(j,i) 131 | 132 | 133 | def erase_menu(stdscr, menu_y): 134 | "Clear the space where the menu resides" 135 | stdscr.move(menu_y, 0) 136 | stdscr.clrtoeol() 137 | stdscr.move(menu_y+1, 0) 138 | stdscr.clrtoeol() 139 | 140 | def display_menu(stdscr, menu_y): 141 | "Display the menu of possible keystroke commands" 142 | erase_menu(stdscr, menu_y) 143 | stdscr.addstr(menu_y, 4, 144 | 'Use the cursor keys to move, and space or Enter to toggle a cell.') 145 | stdscr.addstr(menu_y+1, 4, 146 | 'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit') 147 | 148 | def keyloop(stdscr): 149 | # Clear the screen and display the menu of keys 150 | stdscr.clear() 151 | stdscr_y, stdscr_x = stdscr.getmaxyx() 152 | menu_y = (stdscr_y-3)-1 153 | display_menu(stdscr, menu_y) 154 | 155 | # Allocate a subwindow for the Life board and create the board object 156 | subwin = stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0) 157 | board = LifeBoard(subwin, char=ord('*')) 158 | board.display(update_board=False) 159 | 160 | # xpos, ypos are the cursor's position 161 | xpos, ypos = board.X//2, board.Y//2 162 | 163 | # Main loop: 164 | while (1): 165 | stdscr.move(1+ypos, 1+xpos) # Move the cursor 166 | c = stdscr.getch() # Get a keystroke 167 | if 00: ypos -= 1 203 | elif c == curses.KEY_DOWN and ypos0: xpos -= 1 205 | elif c == curses.KEY_RIGHT and xpos", "LAST"] 74 | 75 | stdscr.refresh() 76 | 77 | for y in range(0, curses.LINES - 1): 78 | for x in range(0, curses.COLS): 79 | stdscr.addstr("%d" % ((y + x) % 10)) 80 | 81 | 82 | 83 | for y in range(0, 1): 84 | 85 | p1 = mkpanel(curses.COLOR_RED, 86 | curses.LINES // 2 - 2, 87 | curses.COLS // 8 + 1, 88 | 0, 89 | 0) 90 | 91 | p1.set_userptr("p1") 92 | 93 | 94 | p2 = mkpanel(curses.COLOR_GREEN, 95 | curses.LINES // 2 + 1, 96 | curses.COLS // 7, 97 | curses.LINES // 4, 98 | curses.COLS // 10) 99 | p2.set_userptr("p2") 100 | 101 | p3 = mkpanel(curses.COLOR_YELLOW, 102 | curses.LINES // 4, 103 | curses.COLS // 10, 104 | curses.LINES // 2, 105 | curses.COLS // 9) 106 | p3.set_userptr("p3") 107 | 108 | p4 = mkpanel(curses.COLOR_BLUE, 109 | curses.LINES // 2 - 2, 110 | curses.COLS // 8, 111 | curses.LINES // 2 - 2, 112 | curses.COLS // 3) 113 | p4.set_userptr("p4") 114 | 115 | p5 = mkpanel(curses.COLOR_MAGENTA, 116 | curses.LINES // 2 - 2, 117 | curses.COLS // 8, 118 | curses.LINES // 2, 119 | curses.COLS // 2 - 2) 120 | p5.set_userptr("p5") 121 | 122 | fill_panel(p1) 123 | fill_panel(p2) 124 | fill_panel(p3) 125 | fill_panel(p4) 126 | fill_panel(p5) 127 | p4.hide() 128 | p5.hide() 129 | #pflush() 130 | saywhat("press any key to continue") 131 | wait_a_while() 132 | 133 | saywhat("h3 s1 s2 s4 s5;press any key to continue") 134 | p1.move(0, 0) 135 | p3.hide() 136 | p1.show() 137 | p2.show() 138 | p4.show() 139 | p5.show() 140 | pflush() 141 | wait_a_while() 142 | 143 | saywhat("s1; press any key to continue") 144 | p1.show() 145 | pflush() 146 | wait_a_while() 147 | 148 | saywhat("s2; press any key to continue") 149 | p2.show() 150 | pflush() 151 | wait_a_while() 152 | 153 | saywhat("m2; press any key to continue") 154 | p2.move(curses.LINES // 3 + 1, curses.COLS // 8) 155 | pflush() 156 | wait_a_while() 157 | 158 | saywhat("s3; press any key to continue") 159 | p3.show() 160 | pflush() 161 | wait_a_while() 162 | 163 | saywhat("m3; press any key to continue") 164 | p3.move(curses.LINES // 4 + 1, curses.COLS // 15) 165 | pflush() 166 | wait_a_while() 167 | 168 | saywhat("b3; press any key to continue") 169 | p3.bottom() 170 | pflush() 171 | wait_a_while() 172 | 173 | saywhat("s4; press any key to continue") 174 | p4.show() 175 | pflush() 176 | wait_a_while() 177 | 178 | saywhat("s5; press any key to continue") 179 | p5.show() 180 | pflush() 181 | wait_a_while() 182 | 183 | saywhat("t3; press any key to continue") 184 | p3.top() 185 | pflush() 186 | wait_a_while() 187 | 188 | saywhat("t1; press any key to continue") 189 | p1.show() 190 | pflush() 191 | wait_a_while() 192 | 193 | saywhat("t2; press any key to continue") 194 | p2.show() 195 | pflush() 196 | wait_a_while() 197 | 198 | saywhat("t3; press any key to continue") 199 | p3.show() 200 | pflush() 201 | wait_a_while() 202 | 203 | saywhat("t4; press any key to continue") 204 | p4.show() 205 | pflush() 206 | wait_a_while() 207 | 208 | for itmp in range(0, 6): 209 | w4 = p4.window() 210 | w5 = p5.window() 211 | 212 | saywhat("m4; press any key to continue") 213 | w4.move(curses.LINES // 8, 1) 214 | w4.addstr(mod[itmp]) 215 | p4.move(curses.LINES // 6, itmp * curses.COLS // 8) 216 | w5.move(curses.LINES // 6, 1) 217 | w5.addstr(mod[itmp]) 218 | pflush() 219 | wait_a_while() 220 | 221 | saywhat("m5; press any key to continue") 222 | w4.move(curses.LINES // 6, 1) 223 | w4.addstr(mod[itmp]) 224 | p5.move(curses.LINES // 3 - 1, itmp * 10 + 6) 225 | w5.move(curses.LINES // 8, 1) 226 | w5.addstr(mod[itmp]) 227 | pflush() 228 | wait_a_while() 229 | 230 | saywhat("m4; press any key to continue") 231 | p4.move(curses.LINES // 6, (itmp + 1) * curses.COLS // 8) 232 | pflush() 233 | wait_a_while() 234 | 235 | saywhat("t5; press any key to continue") 236 | p5.top() 237 | pflush() 238 | wait_a_while() 239 | 240 | saywhat("t2; press any key to continue") 241 | p2.top() 242 | pflush() 243 | wait_a_while() 244 | 245 | saywhat("t1; press any key to continue") 246 | p1.top() 247 | pflush() 248 | wait_a_while() 249 | 250 | saywhat("d2; press any key to continue") 251 | del p2 252 | pflush() 253 | wait_a_while() 254 | 255 | saywhat("h3; press any key to continue") 256 | p3.hide() 257 | pflush() 258 | wait_a_while() 259 | 260 | saywhat("d1; press any key to continue") 261 | del p1 262 | pflush() 263 | wait_a_while() 264 | 265 | saywhat("d4; press any key to continue") 266 | del p4 267 | pflush() 268 | wait_a_while() 269 | 270 | saywhat("d5; press any key to continue") 271 | del p5 272 | pflush() 273 | wait_a_while() 274 | if nap_msec == 1: 275 | break 276 | nap_msec = 100 277 | 278 | # 279 | # one fine day there'll be the menu at this place 280 | # 281 | curses.wrapper(demo_panels) 282 | -------------------------------------------------------------------------------- /examples/rain.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # $Id: rain.py 46625 2006-06-03 23:02:15Z andrew.kuchling $ 4 | # 5 | # somebody should probably check the randrange()s... 6 | 7 | import curses 8 | from random import randrange 9 | 10 | def next_j(j): 11 | if j == 0: 12 | j = 4 13 | else: 14 | j -= 1 15 | 16 | if curses.has_colors(): 17 | z = randrange(0, 3) 18 | color = curses.color_pair(z) 19 | if z: 20 | color = color | curses.A_BOLD 21 | stdscr.attrset(color) 22 | 23 | return j 24 | 25 | def main(win): 26 | # we know that the first argument from curses.wrapper() is stdscr. 27 | # Initialize it globally for convenience. 28 | global stdscr 29 | stdscr = win 30 | 31 | if curses.has_colors(): 32 | bg = curses.COLOR_BLACK 33 | curses.init_pair(1, curses.COLOR_BLUE, bg) 34 | curses.init_pair(2, curses.COLOR_CYAN, bg) 35 | 36 | curses.nl() 37 | curses.noecho() 38 | # XXX curs_set() always returns ERR 39 | # curses.curs_set(0) 40 | stdscr.timeout(0) 41 | 42 | c = curses.COLS - 4 43 | r = curses.LINES - 4 44 | xpos = [0] * c 45 | ypos = [0] * r 46 | for j in range(4, -1, -1): 47 | xpos[j] = randrange(0, c) + 2 48 | ypos[j] = randrange(0, r) + 2 49 | 50 | j = 0 51 | while True: 52 | x = randrange(0, c) + 2 53 | y = randrange(0, r) + 2 54 | 55 | stdscr.addch(y, x, ord('.')) 56 | 57 | stdscr.addch(ypos[j], xpos[j], ord('o')) 58 | 59 | j = next_j(j) 60 | stdscr.addch(ypos[j], xpos[j], ord('O')) 61 | 62 | j = next_j(j) 63 | stdscr.addch( ypos[j] - 1, xpos[j], ord('-')) 64 | stdscr.addstr(ypos[j], xpos[j] - 1, "|.|") 65 | stdscr.addch( ypos[j] + 1, xpos[j], ord('-')) 66 | 67 | j = next_j(j) 68 | stdscr.addch( ypos[j] - 2, xpos[j], ord('-')) 69 | stdscr.addstr(ypos[j] - 1, xpos[j] - 1, "/ \\") 70 | stdscr.addstr(ypos[j], xpos[j] - 2, "| O |") 71 | stdscr.addstr(ypos[j] + 1, xpos[j] - 1, "\\ /") 72 | stdscr.addch( ypos[j] + 2, xpos[j], ord('-')) 73 | 74 | j = next_j(j) 75 | stdscr.addch( ypos[j] - 2, xpos[j], ord(' ')) 76 | stdscr.addstr(ypos[j] - 1, xpos[j] - 1, " ") 77 | stdscr.addstr(ypos[j], xpos[j] - 2, " ") 78 | stdscr.addstr(ypos[j] + 1, xpos[j] - 1, " ") 79 | stdscr.addch( ypos[j] + 2, xpos[j], ord(' ')) 80 | 81 | xpos[j] = x 82 | ypos[j] = y 83 | 84 | ch = stdscr.getch() 85 | if ch == ord('q') or ch == ord('Q'): 86 | return 87 | elif ch == ord('s'): 88 | stdscr.nodelay(0) 89 | elif ch == ord(' '): 90 | stdscr.nodelay(1) 91 | 92 | curses.napms(50) 93 | 94 | curses.wrapper(main) 95 | -------------------------------------------------------------------------------- /examples/repeat.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | """repeat 4 | 5 | This simple program repeatedly (at 1-second intervals) executes the 6 | shell command given on the command line and displays the output (or as 7 | much of it as fits on the screen). It uses curses to paint each new 8 | output on top of the old output, so that if nothing changes, the 9 | screen doesn't change. This is handy to watch for changes in e.g. a 10 | directory or process listing. 11 | 12 | To end, hit Control-C. 13 | """ 14 | 15 | # Author: Guido van Rossum 16 | 17 | # Disclaimer: there's a Linux program named 'watch' that does the same 18 | # thing. Honestly, I didn't know of its existence when I wrote this! 19 | 20 | # To do: add features until it has the same functionality as watch(1); 21 | # then compare code size and development time. 22 | 23 | from __future__ import print_function 24 | 25 | import os 26 | import sys 27 | import time 28 | import curses 29 | 30 | def main(): 31 | if not sys.argv[1:]: 32 | print(__doc__) 33 | sys.exit(0) 34 | cmd = " ".join(sys.argv[1:]) 35 | p = os.popen(cmd, "r") 36 | text = p.read() 37 | sts = p.close() 38 | if sts: 39 | print >>sys.stderr, "Exit code:", sts 40 | sys.exit(sts) 41 | w = curses.initscr() 42 | try: 43 | while True: 44 | w.erase() 45 | try: 46 | w.addstr(text) 47 | except curses.error: 48 | pass 49 | w.refresh() 50 | time.sleep(1) 51 | p = os.popen(cmd, "r") 52 | text = p.read() 53 | sts = p.close() 54 | if sts: 55 | print >>sys.stderr, "Exit code:", sts 56 | sys.exit(sts) 57 | finally: 58 | curses.endwin() 59 | 60 | main() 61 | -------------------------------------------------------------------------------- /examples/tclock.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # $Id: tclock.py 46626 2006-06-03 23:07:21Z andrew.kuchling $ 4 | # 5 | # From tclock.c, Copyright Howard Jones , September 1994. 6 | 7 | from math import * 8 | import curses, time 9 | 10 | ASPECT = 2.2 11 | 12 | def sign(_x): 13 | if _x < 0: return -1 14 | return 1 15 | 16 | def A2XY(angle, radius): 17 | return (int(round(ASPECT * radius * sin(angle))), 18 | int(round(radius * cos(angle)))) 19 | 20 | def plot(x, y, col): 21 | stdscr.addch(y, x, col) 22 | 23 | # draw a diagonal line using Bresenham's algorithm 24 | def dline(pair, from_x, from_y, x2, y2, ch): 25 | if curses.has_colors(): 26 | stdscr.attrset(curses.color_pair(pair)) 27 | 28 | dx = x2 - from_x 29 | dy = y2 - from_y 30 | 31 | ax = abs(dx * 2) 32 | ay = abs(dy * 2) 33 | 34 | sx = sign(dx) 35 | sy = sign(dy) 36 | 37 | x = from_x 38 | y = from_y 39 | 40 | if ax > ay: 41 | d = ay - ax // 2 42 | 43 | while True: 44 | plot(x, y, ch) 45 | if x == x2: 46 | return 47 | 48 | if d >= 0: 49 | y += sy 50 | d -= ax 51 | x += sx 52 | d += ay 53 | else: 54 | d = ax - ay // 2 55 | 56 | while True: 57 | plot(x, y, ch) 58 | if y == y2: 59 | return 60 | 61 | if d >= 0: 62 | x += sx 63 | d -= ay 64 | y += sy 65 | d += ax 66 | 67 | def main(win): 68 | global stdscr 69 | stdscr = win 70 | 71 | lastbeep = -1 72 | my_bg = curses.COLOR_BLACK 73 | 74 | stdscr.nodelay(1) 75 | stdscr.timeout(0) 76 | # curses.curs_set(0) 77 | if curses.has_colors(): 78 | curses.init_pair(1, curses.COLOR_RED, my_bg) 79 | curses.init_pair(2, curses.COLOR_MAGENTA, my_bg) 80 | curses.init_pair(3, curses.COLOR_GREEN, my_bg) 81 | 82 | cx = (curses.COLS - 1) // 2 83 | cy = curses.LINES // 2 84 | ch = min( cy-1, int(cx // ASPECT) - 1) 85 | mradius = (3 * ch) // 4 86 | hradius = ch // 2 87 | sradius = 5 * ch // 6 88 | 89 | for i in range(0, 12): 90 | sangle = (i + 1) * 2.0 * pi / 12.0 91 | sdx, sdy = A2XY(sangle, sradius) 92 | 93 | stdscr.addstr(cy - sdy, cx + sdx, "%d" % (i + 1)) 94 | 95 | stdscr.addstr(0, 0, 96 | "ASCII Clock by Howard Jones , 1994") 97 | 98 | sradius = max(sradius-4, 8) 99 | 100 | while True: 101 | curses.napms(1000) 102 | 103 | tim = time.time() 104 | t = time.localtime(tim) 105 | 106 | hours = t[3] + t[4] / 60.0 107 | if hours > 12.0: 108 | hours -= 12.0 109 | 110 | mangle = t[4] * 2 * pi / 60.0 111 | mdx, mdy = A2XY(mangle, mradius) 112 | 113 | hangle = hours * 2 * pi / 12.0 114 | hdx, hdy = A2XY(hangle, hradius) 115 | 116 | sangle = t[5] * 2 * pi / 60.0 117 | sdx, sdy = A2XY(sangle, sradius) 118 | 119 | dline(3, cx, cy, cx + mdx, cy - mdy, ord('#')) 120 | 121 | stdscr.attrset(curses.A_REVERSE) 122 | dline(2, cx, cy, cx + hdx, cy - hdy, ord('.')) 123 | stdscr.attroff(curses.A_REVERSE) 124 | 125 | if curses.has_colors(): 126 | stdscr.attrset(curses.color_pair(1)) 127 | 128 | plot(cx + sdx, cy - sdy, ord('O')) 129 | 130 | if curses.has_colors(): 131 | stdscr.attrset(curses.color_pair(0)) 132 | 133 | stdscr.addstr(curses.LINES - 2, 0, time.ctime(tim)) 134 | stdscr.refresh() 135 | if (t[5] % 5) == 0 and t[5] != lastbeep: 136 | lastbeep = t[5] 137 | curses.beep() 138 | 139 | ch = stdscr.getch() 140 | if ch == ord('q'): 141 | return 0 142 | 143 | plot(cx + sdx, cy - sdy, ord(' ')) 144 | dline(0, cx, cy, cx + hdx, cy - hdy, ord(' ')) 145 | dline(0, cx, cy, cx + mdx, cy - mdy, ord(' ')) 146 | 147 | curses.wrapper(main) 148 | -------------------------------------------------------------------------------- /py27/_curses_panel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Interface to the ncurses panel library 3 | * 4 | * Original version by Thomas Gellekum 5 | */ 6 | 7 | /* Release Number */ 8 | 9 | static char *PyCursesVersion = "2.1"; 10 | 11 | /* Includes */ 12 | 13 | #include "Python.h" 14 | 15 | #include "py_curses.h" 16 | 17 | #include 18 | 19 | static PyObject *PyCursesError; 20 | 21 | 22 | /* Utility Functions */ 23 | 24 | /* 25 | * Check the return code from a curses function and return None 26 | * or raise an exception as appropriate. 27 | */ 28 | 29 | static PyObject * 30 | PyCursesCheckERR(int code, char *fname) 31 | { 32 | if (code != ERR) { 33 | Py_INCREF(Py_None); 34 | return Py_None; 35 | } else { 36 | if (fname == NULL) { 37 | PyErr_SetString(PyCursesError, catchall_ERR); 38 | } else { 39 | PyErr_Format(PyCursesError, "%s() returned ERR", fname); 40 | } 41 | return NULL; 42 | } 43 | } 44 | 45 | /***************************************************************************** 46 | The Panel Object 47 | ******************************************************************************/ 48 | 49 | /* Definition of the panel object and panel type */ 50 | 51 | typedef struct { 52 | PyObject_HEAD 53 | PANEL *pan; 54 | PyCursesWindowObject *wo; /* for reference counts */ 55 | } PyCursesPanelObject; 56 | 57 | PyTypeObject PyCursesPanel_Type; 58 | 59 | #define PyCursesPanel_Check(v) (Py_TYPE(v) == &PyCursesPanel_Type) 60 | 61 | /* Some helper functions. The problem is that there's always a window 62 | associated with a panel. To ensure that Python's GC doesn't pull 63 | this window from under our feet we need to keep track of references 64 | to the corresponding window object within Python. We can't use 65 | dupwin(oldwin) to keep a copy of the curses WINDOW because the 66 | contents of oldwin is copied only once; code like 67 | 68 | win = newwin(...) 69 | pan = win.panel() 70 | win.addstr(some_string) 71 | pan.window().addstr(other_string) 72 | 73 | will fail. */ 74 | 75 | /* We keep a linked list of PyCursesPanelObjects, lop. A list should 76 | suffice, I don't expect more than a handful or at most a few 77 | dozens of panel objects within a typical program. */ 78 | typedef struct _list_of_panels { 79 | PyCursesPanelObject *po; 80 | struct _list_of_panels *next; 81 | } list_of_panels; 82 | 83 | /* list anchor */ 84 | static list_of_panels *lop; 85 | 86 | /* Insert a new panel object into lop */ 87 | static int 88 | insert_lop(PyCursesPanelObject *po) 89 | { 90 | list_of_panels *new; 91 | 92 | if ((new = (list_of_panels *)malloc(sizeof(list_of_panels))) == NULL) { 93 | PyErr_NoMemory(); 94 | return -1; 95 | } 96 | new->po = po; 97 | new->next = lop; 98 | lop = new; 99 | return 0; 100 | } 101 | 102 | /* Remove the panel object from lop */ 103 | static void 104 | remove_lop(PyCursesPanelObject *po) 105 | { 106 | list_of_panels *temp, *n; 107 | 108 | temp = lop; 109 | if (temp->po == po) { 110 | lop = temp->next; 111 | free(temp); 112 | return; 113 | } 114 | while (temp->next == NULL || temp->next->po != po) { 115 | if (temp->next == NULL) { 116 | PyErr_SetString(PyExc_RuntimeError, 117 | "remove_lop: can't find Panel Object"); 118 | return; 119 | } 120 | temp = temp->next; 121 | } 122 | n = temp->next->next; 123 | free(temp->next); 124 | temp->next = n; 125 | return; 126 | } 127 | 128 | /* Return the panel object that corresponds to pan */ 129 | static PyCursesPanelObject * 130 | find_po(PANEL *pan) 131 | { 132 | list_of_panels *temp; 133 | for (temp = lop; temp->po->pan != pan; temp = temp->next) 134 | if (temp->next == NULL) return NULL; /* not found!? */ 135 | return temp->po; 136 | } 137 | 138 | /* Function Prototype Macros - They are ugly but very, very useful. ;-) 139 | 140 | X - function name 141 | TYPE - parameter Type 142 | ERGSTR - format string for construction of the return value 143 | PARSESTR - format string for argument parsing */ 144 | 145 | #define Panel_NoArgNoReturnFunction(X) \ 146 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ 147 | { return PyCursesCheckERR(X(self->pan), # X); } 148 | 149 | #define Panel_NoArgTrueFalseFunction(X) \ 150 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ 151 | { \ 152 | if (X (self->pan) == FALSE) { Py_INCREF(Py_False); return Py_False; } \ 153 | else { Py_INCREF(Py_True); return Py_True; } } 154 | 155 | #define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \ 156 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \ 157 | { \ 158 | TYPE arg1, arg2; \ 159 | if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \ 160 | return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); } 161 | 162 | /* ------------- PANEL routines --------------- */ 163 | 164 | Panel_NoArgNoReturnFunction(bottom_panel) 165 | Panel_NoArgNoReturnFunction(hide_panel) 166 | Panel_NoArgNoReturnFunction(show_panel) 167 | Panel_NoArgNoReturnFunction(top_panel) 168 | Panel_NoArgTrueFalseFunction(panel_hidden) 169 | Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x") 170 | 171 | /* Allocation and deallocation of Panel Objects */ 172 | 173 | static PyObject * 174 | PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo) 175 | { 176 | PyCursesPanelObject *po; 177 | 178 | po = PyObject_NEW(PyCursesPanelObject, &PyCursesPanel_Type); 179 | if (po == NULL) return NULL; 180 | po->pan = pan; 181 | if (insert_lop(po) < 0) { 182 | po->wo = NULL; 183 | Py_DECREF(po); 184 | return NULL; 185 | } 186 | po->wo = wo; 187 | Py_INCREF(wo); 188 | return (PyObject *)po; 189 | } 190 | 191 | static void 192 | PyCursesPanel_Dealloc(PyCursesPanelObject *po) 193 | { 194 | PyObject *obj = (PyObject *) panel_userptr(po->pan); 195 | if (obj) { 196 | (void)set_panel_userptr(po->pan, NULL); 197 | Py_DECREF(obj); 198 | } 199 | (void)del_panel(po->pan); 200 | if (po->wo != NULL) { 201 | Py_DECREF(po->wo); 202 | remove_lop(po); 203 | } 204 | PyObject_DEL(po); 205 | } 206 | 207 | /* panel_above(NULL) returns the bottom panel in the stack. To get 208 | this behaviour we use curses.panel.bottom_panel(). */ 209 | static PyObject * 210 | PyCursesPanel_above(PyCursesPanelObject *self) 211 | { 212 | PANEL *pan; 213 | PyCursesPanelObject *po; 214 | 215 | pan = panel_above(self->pan); 216 | 217 | if (pan == NULL) { /* valid output, it means the calling panel 218 | is on top of the stack */ 219 | Py_INCREF(Py_None); 220 | return Py_None; 221 | } 222 | po = find_po(pan); 223 | if (po == NULL) { 224 | PyErr_SetString(PyExc_RuntimeError, 225 | "panel_above: can't find Panel Object"); 226 | return NULL; 227 | } 228 | Py_INCREF(po); 229 | return (PyObject *)po; 230 | } 231 | 232 | /* panel_below(NULL) returns the top panel in the stack. To get 233 | this behaviour we use curses.panel.top_panel(). */ 234 | static PyObject * 235 | PyCursesPanel_below(PyCursesPanelObject *self) 236 | { 237 | PANEL *pan; 238 | PyCursesPanelObject *po; 239 | 240 | pan = panel_below(self->pan); 241 | 242 | if (pan == NULL) { /* valid output, it means the calling panel 243 | is on the bottom of the stack */ 244 | Py_INCREF(Py_None); 245 | return Py_None; 246 | } 247 | po = find_po(pan); 248 | if (po == NULL) { 249 | PyErr_SetString(PyExc_RuntimeError, 250 | "panel_below: can't find Panel Object"); 251 | return NULL; 252 | } 253 | Py_INCREF(po); 254 | return (PyObject *)po; 255 | } 256 | 257 | static PyObject * 258 | PyCursesPanel_window(PyCursesPanelObject *self) 259 | { 260 | Py_INCREF(self->wo); 261 | return (PyObject *)self->wo; 262 | } 263 | 264 | static PyObject * 265 | PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args) 266 | { 267 | PyCursesPanelObject *po; 268 | PyCursesWindowObject *temp; 269 | int rtn; 270 | 271 | if (PyTuple_Size(args) != 1) { 272 | PyErr_SetString(PyExc_TypeError, "replace requires one argument"); 273 | return NULL; 274 | } 275 | if (!PyArg_ParseTuple(args, "O!;window object", 276 | &PyCursesWindow_Type, &temp)) 277 | return NULL; 278 | 279 | po = find_po(self->pan); 280 | if (po == NULL) { 281 | PyErr_SetString(PyExc_RuntimeError, 282 | "replace_panel: can't find Panel Object"); 283 | return NULL; 284 | } 285 | 286 | rtn = replace_panel(self->pan, temp->win); 287 | if (rtn == ERR) { 288 | PyErr_SetString(PyCursesError, "replace_panel() returned ERR"); 289 | return NULL; 290 | } 291 | Py_INCREF(temp); 292 | Py_SETREF(po->wo, temp); 293 | Py_INCREF(Py_None); 294 | return Py_None; 295 | } 296 | 297 | static PyObject * 298 | PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) 299 | { 300 | PyObject *oldobj; 301 | int rc; 302 | PyCursesInitialised; 303 | Py_INCREF(obj); 304 | oldobj = (PyObject *) panel_userptr(self->pan); 305 | rc = set_panel_userptr(self->pan, (void*)obj); 306 | if (rc == ERR) { 307 | /* In case of an ncurses error, decref the new object again */ 308 | Py_DECREF(obj); 309 | } 310 | Py_XDECREF(oldobj); 311 | return PyCursesCheckERR(rc, "set_panel_userptr"); 312 | } 313 | 314 | static PyObject * 315 | PyCursesPanel_userptr(PyCursesPanelObject *self) 316 | { 317 | PyObject *obj; 318 | PyCursesInitialised; 319 | obj = (PyObject *) panel_userptr(self->pan); 320 | if (obj == NULL) { 321 | PyErr_SetString(PyCursesError, "no userptr set"); 322 | return NULL; 323 | } 324 | 325 | Py_INCREF(obj); 326 | return obj; 327 | } 328 | 329 | 330 | /* Module interface */ 331 | 332 | static PyMethodDef PyCursesPanel_Methods[] = { 333 | {"above", (PyCFunction)PyCursesPanel_above, METH_NOARGS}, 334 | {"below", (PyCFunction)PyCursesPanel_below, METH_NOARGS}, 335 | {"bottom", (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS}, 336 | {"hidden", (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS}, 337 | {"hide", (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS}, 338 | {"move", (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS}, 339 | {"replace", (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS}, 340 | {"set_userptr", (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O}, 341 | {"show", (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS}, 342 | {"top", (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS}, 343 | {"userptr", (PyCFunction)PyCursesPanel_userptr, METH_NOARGS}, 344 | {"window", (PyCFunction)PyCursesPanel_window, METH_NOARGS}, 345 | {NULL, NULL} /* sentinel */ 346 | }; 347 | 348 | static PyObject * 349 | PyCursesPanel_GetAttr(PyCursesPanelObject *self, char *name) 350 | { 351 | return Py_FindMethod(PyCursesPanel_Methods, (PyObject *)self, name); 352 | } 353 | 354 | /* -------------------------------------------------------*/ 355 | 356 | PyTypeObject PyCursesPanel_Type = { 357 | PyVarObject_HEAD_INIT(NULL, 0) 358 | "_curses_panel.curses panel", /*tp_name*/ 359 | sizeof(PyCursesPanelObject), /*tp_basicsize*/ 360 | 0, /*tp_itemsize*/ 361 | /* methods */ 362 | (destructor)PyCursesPanel_Dealloc, /*tp_dealloc*/ 363 | 0, /*tp_print*/ 364 | (getattrfunc)PyCursesPanel_GetAttr, /*tp_getattr*/ 365 | (setattrfunc)0, /*tp_setattr*/ 366 | 0, /*tp_compare*/ 367 | 0, /*tp_repr*/ 368 | 0, /*tp_as_number*/ 369 | 0, /*tp_as_sequence*/ 370 | 0, /*tp_as_mapping*/ 371 | 0, /*tp_hash*/ 372 | }; 373 | 374 | /* Wrapper for panel_above(NULL). This function returns the bottom 375 | panel of the stack, so it's renamed to bottom_panel(). 376 | panel.above() *requires* a panel object in the first place which 377 | may be undesirable. */ 378 | static PyObject * 379 | PyCurses_bottom_panel(PyObject *self) 380 | { 381 | PANEL *pan; 382 | PyCursesPanelObject *po; 383 | 384 | PyCursesInitialised; 385 | 386 | pan = panel_above(NULL); 387 | 388 | if (pan == NULL) { /* valid output, it means 389 | there's no panel at all */ 390 | Py_INCREF(Py_None); 391 | return Py_None; 392 | } 393 | po = find_po(pan); 394 | if (po == NULL) { 395 | PyErr_SetString(PyExc_RuntimeError, 396 | "panel_above: can't find Panel Object"); 397 | return NULL; 398 | } 399 | Py_INCREF(po); 400 | return (PyObject *)po; 401 | } 402 | 403 | static PyObject * 404 | PyCurses_new_panel(PyObject *self, PyObject *args) 405 | { 406 | PyCursesWindowObject *win; 407 | PANEL *pan; 408 | 409 | if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win)) 410 | return NULL; 411 | pan = new_panel(win->win); 412 | if (pan == NULL) { 413 | PyErr_SetString(PyCursesError, catchall_NULL); 414 | return NULL; 415 | } 416 | return (PyObject *)PyCursesPanel_New(pan, win); 417 | } 418 | 419 | 420 | /* Wrapper for panel_below(NULL). This function returns the top panel 421 | of the stack, so it's renamed to top_panel(). panel.below() 422 | *requires* a panel object in the first place which may be 423 | undesirable. */ 424 | static PyObject * 425 | PyCurses_top_panel(PyObject *self) 426 | { 427 | PANEL *pan; 428 | PyCursesPanelObject *po; 429 | 430 | PyCursesInitialised; 431 | 432 | pan = panel_below(NULL); 433 | 434 | if (pan == NULL) { /* valid output, it means 435 | there's no panel at all */ 436 | Py_INCREF(Py_None); 437 | return Py_None; 438 | } 439 | po = find_po(pan); 440 | if (po == NULL) { 441 | PyErr_SetString(PyExc_RuntimeError, 442 | "panel_below: can't find Panel Object"); 443 | return NULL; 444 | } 445 | Py_INCREF(po); 446 | return (PyObject *)po; 447 | } 448 | 449 | static PyObject *PyCurses_update_panels(PyObject *self) 450 | { 451 | PyCursesInitialised; 452 | update_panels(); 453 | Py_INCREF(Py_None); 454 | return Py_None; 455 | } 456 | 457 | 458 | /* List of functions defined in the module */ 459 | 460 | static PyMethodDef PyCurses_methods[] = { 461 | {"bottom_panel", (PyCFunction)PyCurses_bottom_panel, METH_NOARGS}, 462 | {"new_panel", (PyCFunction)PyCurses_new_panel, METH_VARARGS}, 463 | {"top_panel", (PyCFunction)PyCurses_top_panel, METH_NOARGS}, 464 | {"update_panels", (PyCFunction)PyCurses_update_panels, METH_NOARGS}, 465 | {NULL, NULL} /* sentinel */ 466 | }; 467 | 468 | /* Initialization function for the module */ 469 | 470 | PyMODINIT_FUNC 471 | init_curses_panel(void) 472 | { 473 | PyObject *m, *d, *v; 474 | 475 | /* Initialize object type */ 476 | Py_TYPE(&PyCursesPanel_Type) = &PyType_Type; 477 | 478 | import_curses(); 479 | 480 | /* Create the module and add the functions */ 481 | m = Py_InitModule("_curses_panel", PyCurses_methods); 482 | if (m == NULL) 483 | return; 484 | d = PyModule_GetDict(m); 485 | 486 | /* For exception _curses_panel.error */ 487 | PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL); 488 | PyDict_SetItemString(d, "error", PyCursesError); 489 | 490 | /* Make the version available */ 491 | v = PyString_FromString(PyCursesVersion); 492 | PyDict_SetItemString(d, "version", v); 493 | PyDict_SetItemString(d, "__version__", v); 494 | Py_DECREF(v); 495 | } 496 | -------------------------------------------------------------------------------- /py310/clinic/_curses_panel.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, 6 | "bottom($self, /)\n" 7 | "--\n" 8 | "\n" 9 | "Push the panel to the bottom of the stack."); 10 | 11 | #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ 12 | {"bottom", (PyCFunction)(void(*)(void))_curses_panel_panel_bottom, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__}, 13 | 14 | static PyObject * 15 | _curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); 16 | 17 | static PyObject * 18 | _curses_panel_panel_bottom(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 19 | { 20 | PyObject *return_value = NULL; 21 | static const char * const _keywords[] = { NULL}; 22 | static _PyArg_Parser _parser = {":bottom", _keywords, 0}; 23 | 24 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 25 | )) { 26 | goto exit; 27 | } 28 | return_value = _curses_panel_panel_bottom_impl(self, cls); 29 | 30 | exit: 31 | return return_value; 32 | } 33 | 34 | PyDoc_STRVAR(_curses_panel_panel_hide__doc__, 35 | "hide($self, /)\n" 36 | "--\n" 37 | "\n" 38 | "Hide the panel.\n" 39 | "\n" 40 | "This does not delete the object, it just makes the window on screen invisible."); 41 | 42 | #define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ 43 | {"hide", (PyCFunction)(void(*)(void))_curses_panel_panel_hide, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__}, 44 | 45 | static PyObject * 46 | _curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); 47 | 48 | static PyObject * 49 | _curses_panel_panel_hide(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 50 | { 51 | PyObject *return_value = NULL; 52 | static const char * const _keywords[] = { NULL}; 53 | static _PyArg_Parser _parser = {":hide", _keywords, 0}; 54 | 55 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 56 | )) { 57 | goto exit; 58 | } 59 | return_value = _curses_panel_panel_hide_impl(self, cls); 60 | 61 | exit: 62 | return return_value; 63 | } 64 | 65 | PyDoc_STRVAR(_curses_panel_panel_show__doc__, 66 | "show($self, /)\n" 67 | "--\n" 68 | "\n" 69 | "Display the panel (which might have been hidden)."); 70 | 71 | #define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ 72 | {"show", (PyCFunction)(void(*)(void))_curses_panel_panel_show, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__}, 73 | 74 | static PyObject * 75 | _curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); 76 | 77 | static PyObject * 78 | _curses_panel_panel_show(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 79 | { 80 | PyObject *return_value = NULL; 81 | static const char * const _keywords[] = { NULL}; 82 | static _PyArg_Parser _parser = {":show", _keywords, 0}; 83 | 84 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 85 | )) { 86 | goto exit; 87 | } 88 | return_value = _curses_panel_panel_show_impl(self, cls); 89 | 90 | exit: 91 | return return_value; 92 | } 93 | 94 | PyDoc_STRVAR(_curses_panel_panel_top__doc__, 95 | "top($self, /)\n" 96 | "--\n" 97 | "\n" 98 | "Push panel to the top of the stack."); 99 | 100 | #define _CURSES_PANEL_PANEL_TOP_METHODDEF \ 101 | {"top", (PyCFunction)(void(*)(void))_curses_panel_panel_top, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__}, 102 | 103 | static PyObject * 104 | _curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); 105 | 106 | static PyObject * 107 | _curses_panel_panel_top(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 108 | { 109 | PyObject *return_value = NULL; 110 | static const char * const _keywords[] = { NULL}; 111 | static _PyArg_Parser _parser = {":top", _keywords, 0}; 112 | 113 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 114 | )) { 115 | goto exit; 116 | } 117 | return_value = _curses_panel_panel_top_impl(self, cls); 118 | 119 | exit: 120 | return return_value; 121 | } 122 | 123 | PyDoc_STRVAR(_curses_panel_panel_above__doc__, 124 | "above($self, /)\n" 125 | "--\n" 126 | "\n" 127 | "Return the panel above the current panel."); 128 | 129 | #define _CURSES_PANEL_PANEL_ABOVE_METHODDEF \ 130 | {"above", (PyCFunction)_curses_panel_panel_above, METH_NOARGS, _curses_panel_panel_above__doc__}, 131 | 132 | static PyObject * 133 | _curses_panel_panel_above_impl(PyCursesPanelObject *self); 134 | 135 | static PyObject * 136 | _curses_panel_panel_above(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 137 | { 138 | return _curses_panel_panel_above_impl(self); 139 | } 140 | 141 | PyDoc_STRVAR(_curses_panel_panel_below__doc__, 142 | "below($self, /)\n" 143 | "--\n" 144 | "\n" 145 | "Return the panel below the current panel."); 146 | 147 | #define _CURSES_PANEL_PANEL_BELOW_METHODDEF \ 148 | {"below", (PyCFunction)_curses_panel_panel_below, METH_NOARGS, _curses_panel_panel_below__doc__}, 149 | 150 | static PyObject * 151 | _curses_panel_panel_below_impl(PyCursesPanelObject *self); 152 | 153 | static PyObject * 154 | _curses_panel_panel_below(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 155 | { 156 | return _curses_panel_panel_below_impl(self); 157 | } 158 | 159 | PyDoc_STRVAR(_curses_panel_panel_hidden__doc__, 160 | "hidden($self, /)\n" 161 | "--\n" 162 | "\n" 163 | "Return True if the panel is hidden (not visible), False otherwise."); 164 | 165 | #define _CURSES_PANEL_PANEL_HIDDEN_METHODDEF \ 166 | {"hidden", (PyCFunction)_curses_panel_panel_hidden, METH_NOARGS, _curses_panel_panel_hidden__doc__}, 167 | 168 | static PyObject * 169 | _curses_panel_panel_hidden_impl(PyCursesPanelObject *self); 170 | 171 | static PyObject * 172 | _curses_panel_panel_hidden(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 173 | { 174 | return _curses_panel_panel_hidden_impl(self); 175 | } 176 | 177 | PyDoc_STRVAR(_curses_panel_panel_move__doc__, 178 | "move($self, y, x, /)\n" 179 | "--\n" 180 | "\n" 181 | "Move the panel to the screen coordinates (y, x)."); 182 | 183 | #define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ 184 | {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__}, 185 | 186 | static PyObject * 187 | _curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls, 188 | int y, int x); 189 | 190 | static PyObject * 191 | _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 192 | { 193 | PyObject *return_value = NULL; 194 | static const char * const _keywords[] = {"", "", NULL}; 195 | static _PyArg_Parser _parser = {"ii:move", _keywords, 0}; 196 | int y; 197 | int x; 198 | 199 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, 200 | &y, &x)) { 201 | goto exit; 202 | } 203 | return_value = _curses_panel_panel_move_impl(self, cls, y, x); 204 | 205 | exit: 206 | return return_value; 207 | } 208 | 209 | PyDoc_STRVAR(_curses_panel_panel_window__doc__, 210 | "window($self, /)\n" 211 | "--\n" 212 | "\n" 213 | "Return the window object associated with the panel."); 214 | 215 | #define _CURSES_PANEL_PANEL_WINDOW_METHODDEF \ 216 | {"window", (PyCFunction)_curses_panel_panel_window, METH_NOARGS, _curses_panel_panel_window__doc__}, 217 | 218 | static PyObject * 219 | _curses_panel_panel_window_impl(PyCursesPanelObject *self); 220 | 221 | static PyObject * 222 | _curses_panel_panel_window(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 223 | { 224 | return _curses_panel_panel_window_impl(self); 225 | } 226 | 227 | PyDoc_STRVAR(_curses_panel_panel_replace__doc__, 228 | "replace($self, win, /)\n" 229 | "--\n" 230 | "\n" 231 | "Change the window associated with the panel to the window win."); 232 | 233 | #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ 234 | {"replace", (PyCFunction)(void(*)(void))_curses_panel_panel_replace, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__}, 235 | 236 | static PyObject * 237 | _curses_panel_panel_replace_impl(PyCursesPanelObject *self, 238 | PyTypeObject *cls, 239 | PyCursesWindowObject *win); 240 | 241 | static PyObject * 242 | _curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 243 | { 244 | PyObject *return_value = NULL; 245 | static const char * const _keywords[] = {"", NULL}; 246 | static _PyArg_Parser _parser = {"O!:replace", _keywords, 0}; 247 | PyCursesWindowObject *win; 248 | 249 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, 250 | &PyCursesWindow_Type, &win)) { 251 | goto exit; 252 | } 253 | return_value = _curses_panel_panel_replace_impl(self, cls, win); 254 | 255 | exit: 256 | return return_value; 257 | } 258 | 259 | PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, 260 | "set_userptr($self, obj, /)\n" 261 | "--\n" 262 | "\n" 263 | "Set the panel\'s user pointer to obj."); 264 | 265 | #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ 266 | {"set_userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_set_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_set_userptr__doc__}, 267 | 268 | static PyObject * 269 | _curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self, 270 | PyTypeObject *cls, PyObject *obj); 271 | 272 | static PyObject * 273 | _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 274 | { 275 | PyObject *return_value = NULL; 276 | static const char * const _keywords[] = {"", NULL}; 277 | static _PyArg_Parser _parser = {"O:set_userptr", _keywords, 0}; 278 | PyObject *obj; 279 | 280 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, 281 | &obj)) { 282 | goto exit; 283 | } 284 | return_value = _curses_panel_panel_set_userptr_impl(self, cls, obj); 285 | 286 | exit: 287 | return return_value; 288 | } 289 | 290 | PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, 291 | "userptr($self, /)\n" 292 | "--\n" 293 | "\n" 294 | "Return the user pointer for the panel."); 295 | 296 | #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ 297 | {"userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__}, 298 | 299 | static PyObject * 300 | _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, 301 | PyTypeObject *cls); 302 | 303 | static PyObject * 304 | _curses_panel_panel_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 305 | { 306 | PyObject *return_value = NULL; 307 | static const char * const _keywords[] = { NULL}; 308 | static _PyArg_Parser _parser = {":userptr", _keywords, 0}; 309 | 310 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 311 | )) { 312 | goto exit; 313 | } 314 | return_value = _curses_panel_panel_userptr_impl(self, cls); 315 | 316 | exit: 317 | return return_value; 318 | } 319 | 320 | PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, 321 | "bottom_panel($module, /)\n" 322 | "--\n" 323 | "\n" 324 | "Return the bottom panel in the panel stack."); 325 | 326 | #define _CURSES_PANEL_BOTTOM_PANEL_METHODDEF \ 327 | {"bottom_panel", (PyCFunction)_curses_panel_bottom_panel, METH_NOARGS, _curses_panel_bottom_panel__doc__}, 328 | 329 | static PyObject * 330 | _curses_panel_bottom_panel_impl(PyObject *module); 331 | 332 | static PyObject * 333 | _curses_panel_bottom_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 334 | { 335 | return _curses_panel_bottom_panel_impl(module); 336 | } 337 | 338 | PyDoc_STRVAR(_curses_panel_new_panel__doc__, 339 | "new_panel($module, win, /)\n" 340 | "--\n" 341 | "\n" 342 | "Return a panel object, associating it with the given window win."); 343 | 344 | #define _CURSES_PANEL_NEW_PANEL_METHODDEF \ 345 | {"new_panel", (PyCFunction)_curses_panel_new_panel, METH_O, _curses_panel_new_panel__doc__}, 346 | 347 | static PyObject * 348 | _curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win); 349 | 350 | static PyObject * 351 | _curses_panel_new_panel(PyObject *module, PyObject *arg) 352 | { 353 | PyObject *return_value = NULL; 354 | PyCursesWindowObject *win; 355 | 356 | if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { 357 | _PyArg_BadArgument("new_panel", "argument", (&PyCursesWindow_Type)->tp_name, arg); 358 | goto exit; 359 | } 360 | win = (PyCursesWindowObject *)arg; 361 | return_value = _curses_panel_new_panel_impl(module, win); 362 | 363 | exit: 364 | return return_value; 365 | } 366 | 367 | PyDoc_STRVAR(_curses_panel_top_panel__doc__, 368 | "top_panel($module, /)\n" 369 | "--\n" 370 | "\n" 371 | "Return the top panel in the panel stack."); 372 | 373 | #define _CURSES_PANEL_TOP_PANEL_METHODDEF \ 374 | {"top_panel", (PyCFunction)_curses_panel_top_panel, METH_NOARGS, _curses_panel_top_panel__doc__}, 375 | 376 | static PyObject * 377 | _curses_panel_top_panel_impl(PyObject *module); 378 | 379 | static PyObject * 380 | _curses_panel_top_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 381 | { 382 | return _curses_panel_top_panel_impl(module); 383 | } 384 | 385 | PyDoc_STRVAR(_curses_panel_update_panels__doc__, 386 | "update_panels($module, /)\n" 387 | "--\n" 388 | "\n" 389 | "Updates the virtual screen after changes in the panel stack.\n" 390 | "\n" 391 | "This does not call curses.doupdate(), so you\'ll have to do this yourself."); 392 | 393 | #define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \ 394 | {"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__}, 395 | 396 | static PyObject * 397 | _curses_panel_update_panels_impl(PyObject *module); 398 | 399 | static PyObject * 400 | _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) 401 | { 402 | return _curses_panel_update_panels_impl(module); 403 | } 404 | /*[clinic end generated code: output=3081ef24e5560cb0 input=a9049054013a1b77]*/ 405 | -------------------------------------------------------------------------------- /py311/clinic/_curses_panel.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, 6 | "bottom($self, /)\n" 7 | "--\n" 8 | "\n" 9 | "Push the panel to the bottom of the stack."); 10 | 11 | #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ 12 | {"bottom", (PyCFunction)(void(*)(void))_curses_panel_panel_bottom, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__}, 13 | 14 | static PyObject * 15 | _curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); 16 | 17 | static PyObject * 18 | _curses_panel_panel_bottom(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 19 | { 20 | PyObject *return_value = NULL; 21 | static const char * const _keywords[] = { NULL}; 22 | static _PyArg_Parser _parser = {":bottom", _keywords, 0}; 23 | 24 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 25 | )) { 26 | goto exit; 27 | } 28 | return_value = _curses_panel_panel_bottom_impl(self, cls); 29 | 30 | exit: 31 | return return_value; 32 | } 33 | 34 | PyDoc_STRVAR(_curses_panel_panel_hide__doc__, 35 | "hide($self, /)\n" 36 | "--\n" 37 | "\n" 38 | "Hide the panel.\n" 39 | "\n" 40 | "This does not delete the object, it just makes the window on screen invisible."); 41 | 42 | #define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ 43 | {"hide", (PyCFunction)(void(*)(void))_curses_panel_panel_hide, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__}, 44 | 45 | static PyObject * 46 | _curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); 47 | 48 | static PyObject * 49 | _curses_panel_panel_hide(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 50 | { 51 | PyObject *return_value = NULL; 52 | static const char * const _keywords[] = { NULL}; 53 | static _PyArg_Parser _parser = {":hide", _keywords, 0}; 54 | 55 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 56 | )) { 57 | goto exit; 58 | } 59 | return_value = _curses_panel_panel_hide_impl(self, cls); 60 | 61 | exit: 62 | return return_value; 63 | } 64 | 65 | PyDoc_STRVAR(_curses_panel_panel_show__doc__, 66 | "show($self, /)\n" 67 | "--\n" 68 | "\n" 69 | "Display the panel (which might have been hidden)."); 70 | 71 | #define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ 72 | {"show", (PyCFunction)(void(*)(void))_curses_panel_panel_show, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__}, 73 | 74 | static PyObject * 75 | _curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); 76 | 77 | static PyObject * 78 | _curses_panel_panel_show(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 79 | { 80 | PyObject *return_value = NULL; 81 | static const char * const _keywords[] = { NULL}; 82 | static _PyArg_Parser _parser = {":show", _keywords, 0}; 83 | 84 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 85 | )) { 86 | goto exit; 87 | } 88 | return_value = _curses_panel_panel_show_impl(self, cls); 89 | 90 | exit: 91 | return return_value; 92 | } 93 | 94 | PyDoc_STRVAR(_curses_panel_panel_top__doc__, 95 | "top($self, /)\n" 96 | "--\n" 97 | "\n" 98 | "Push panel to the top of the stack."); 99 | 100 | #define _CURSES_PANEL_PANEL_TOP_METHODDEF \ 101 | {"top", (PyCFunction)(void(*)(void))_curses_panel_panel_top, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__}, 102 | 103 | static PyObject * 104 | _curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); 105 | 106 | static PyObject * 107 | _curses_panel_panel_top(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 108 | { 109 | PyObject *return_value = NULL; 110 | static const char * const _keywords[] = { NULL}; 111 | static _PyArg_Parser _parser = {":top", _keywords, 0}; 112 | 113 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 114 | )) { 115 | goto exit; 116 | } 117 | return_value = _curses_panel_panel_top_impl(self, cls); 118 | 119 | exit: 120 | return return_value; 121 | } 122 | 123 | PyDoc_STRVAR(_curses_panel_panel_above__doc__, 124 | "above($self, /)\n" 125 | "--\n" 126 | "\n" 127 | "Return the panel above the current panel."); 128 | 129 | #define _CURSES_PANEL_PANEL_ABOVE_METHODDEF \ 130 | {"above", (PyCFunction)_curses_panel_panel_above, METH_NOARGS, _curses_panel_panel_above__doc__}, 131 | 132 | static PyObject * 133 | _curses_panel_panel_above_impl(PyCursesPanelObject *self); 134 | 135 | static PyObject * 136 | _curses_panel_panel_above(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 137 | { 138 | return _curses_panel_panel_above_impl(self); 139 | } 140 | 141 | PyDoc_STRVAR(_curses_panel_panel_below__doc__, 142 | "below($self, /)\n" 143 | "--\n" 144 | "\n" 145 | "Return the panel below the current panel."); 146 | 147 | #define _CURSES_PANEL_PANEL_BELOW_METHODDEF \ 148 | {"below", (PyCFunction)_curses_panel_panel_below, METH_NOARGS, _curses_panel_panel_below__doc__}, 149 | 150 | static PyObject * 151 | _curses_panel_panel_below_impl(PyCursesPanelObject *self); 152 | 153 | static PyObject * 154 | _curses_panel_panel_below(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 155 | { 156 | return _curses_panel_panel_below_impl(self); 157 | } 158 | 159 | PyDoc_STRVAR(_curses_panel_panel_hidden__doc__, 160 | "hidden($self, /)\n" 161 | "--\n" 162 | "\n" 163 | "Return True if the panel is hidden (not visible), False otherwise."); 164 | 165 | #define _CURSES_PANEL_PANEL_HIDDEN_METHODDEF \ 166 | {"hidden", (PyCFunction)_curses_panel_panel_hidden, METH_NOARGS, _curses_panel_panel_hidden__doc__}, 167 | 168 | static PyObject * 169 | _curses_panel_panel_hidden_impl(PyCursesPanelObject *self); 170 | 171 | static PyObject * 172 | _curses_panel_panel_hidden(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 173 | { 174 | return _curses_panel_panel_hidden_impl(self); 175 | } 176 | 177 | PyDoc_STRVAR(_curses_panel_panel_move__doc__, 178 | "move($self, y, x, /)\n" 179 | "--\n" 180 | "\n" 181 | "Move the panel to the screen coordinates (y, x)."); 182 | 183 | #define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ 184 | {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__}, 185 | 186 | static PyObject * 187 | _curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls, 188 | int y, int x); 189 | 190 | static PyObject * 191 | _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 192 | { 193 | PyObject *return_value = NULL; 194 | static const char * const _keywords[] = {"", "", NULL}; 195 | static _PyArg_Parser _parser = {"ii:move", _keywords, 0}; 196 | int y; 197 | int x; 198 | 199 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, 200 | &y, &x)) { 201 | goto exit; 202 | } 203 | return_value = _curses_panel_panel_move_impl(self, cls, y, x); 204 | 205 | exit: 206 | return return_value; 207 | } 208 | 209 | PyDoc_STRVAR(_curses_panel_panel_window__doc__, 210 | "window($self, /)\n" 211 | "--\n" 212 | "\n" 213 | "Return the window object associated with the panel."); 214 | 215 | #define _CURSES_PANEL_PANEL_WINDOW_METHODDEF \ 216 | {"window", (PyCFunction)_curses_panel_panel_window, METH_NOARGS, _curses_panel_panel_window__doc__}, 217 | 218 | static PyObject * 219 | _curses_panel_panel_window_impl(PyCursesPanelObject *self); 220 | 221 | static PyObject * 222 | _curses_panel_panel_window(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 223 | { 224 | return _curses_panel_panel_window_impl(self); 225 | } 226 | 227 | PyDoc_STRVAR(_curses_panel_panel_replace__doc__, 228 | "replace($self, win, /)\n" 229 | "--\n" 230 | "\n" 231 | "Change the window associated with the panel to the window win."); 232 | 233 | #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ 234 | {"replace", (PyCFunction)(void(*)(void))_curses_panel_panel_replace, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__}, 235 | 236 | static PyObject * 237 | _curses_panel_panel_replace_impl(PyCursesPanelObject *self, 238 | PyTypeObject *cls, 239 | PyCursesWindowObject *win); 240 | 241 | static PyObject * 242 | _curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 243 | { 244 | PyObject *return_value = NULL; 245 | static const char * const _keywords[] = {"", NULL}; 246 | static _PyArg_Parser _parser = {"O!:replace", _keywords, 0}; 247 | PyCursesWindowObject *win; 248 | 249 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, 250 | &PyCursesWindow_Type, &win)) { 251 | goto exit; 252 | } 253 | return_value = _curses_panel_panel_replace_impl(self, cls, win); 254 | 255 | exit: 256 | return return_value; 257 | } 258 | 259 | PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, 260 | "set_userptr($self, obj, /)\n" 261 | "--\n" 262 | "\n" 263 | "Set the panel\'s user pointer to obj."); 264 | 265 | #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ 266 | {"set_userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_set_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_set_userptr__doc__}, 267 | 268 | static PyObject * 269 | _curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self, 270 | PyTypeObject *cls, PyObject *obj); 271 | 272 | static PyObject * 273 | _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 274 | { 275 | PyObject *return_value = NULL; 276 | static const char * const _keywords[] = {"", NULL}; 277 | static _PyArg_Parser _parser = {"O:set_userptr", _keywords, 0}; 278 | PyObject *obj; 279 | 280 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, 281 | &obj)) { 282 | goto exit; 283 | } 284 | return_value = _curses_panel_panel_set_userptr_impl(self, cls, obj); 285 | 286 | exit: 287 | return return_value; 288 | } 289 | 290 | PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, 291 | "userptr($self, /)\n" 292 | "--\n" 293 | "\n" 294 | "Return the user pointer for the panel."); 295 | 296 | #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ 297 | {"userptr", (PyCFunction)(void(*)(void))_curses_panel_panel_userptr, METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__}, 298 | 299 | static PyObject * 300 | _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, 301 | PyTypeObject *cls); 302 | 303 | static PyObject * 304 | _curses_panel_panel_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 305 | { 306 | PyObject *return_value = NULL; 307 | static const char * const _keywords[] = { NULL}; 308 | static _PyArg_Parser _parser = {":userptr", _keywords, 0}; 309 | 310 | if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser 311 | )) { 312 | goto exit; 313 | } 314 | return_value = _curses_panel_panel_userptr_impl(self, cls); 315 | 316 | exit: 317 | return return_value; 318 | } 319 | 320 | PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, 321 | "bottom_panel($module, /)\n" 322 | "--\n" 323 | "\n" 324 | "Return the bottom panel in the panel stack."); 325 | 326 | #define _CURSES_PANEL_BOTTOM_PANEL_METHODDEF \ 327 | {"bottom_panel", (PyCFunction)_curses_panel_bottom_panel, METH_NOARGS, _curses_panel_bottom_panel__doc__}, 328 | 329 | static PyObject * 330 | _curses_panel_bottom_panel_impl(PyObject *module); 331 | 332 | static PyObject * 333 | _curses_panel_bottom_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 334 | { 335 | return _curses_panel_bottom_panel_impl(module); 336 | } 337 | 338 | PyDoc_STRVAR(_curses_panel_new_panel__doc__, 339 | "new_panel($module, win, /)\n" 340 | "--\n" 341 | "\n" 342 | "Return a panel object, associating it with the given window win."); 343 | 344 | #define _CURSES_PANEL_NEW_PANEL_METHODDEF \ 345 | {"new_panel", (PyCFunction)_curses_panel_new_panel, METH_O, _curses_panel_new_panel__doc__}, 346 | 347 | static PyObject * 348 | _curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win); 349 | 350 | static PyObject * 351 | _curses_panel_new_panel(PyObject *module, PyObject *arg) 352 | { 353 | PyObject *return_value = NULL; 354 | PyCursesWindowObject *win; 355 | 356 | if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { 357 | _PyArg_BadArgument("new_panel", "argument", (&PyCursesWindow_Type)->tp_name, arg); 358 | goto exit; 359 | } 360 | win = (PyCursesWindowObject *)arg; 361 | return_value = _curses_panel_new_panel_impl(module, win); 362 | 363 | exit: 364 | return return_value; 365 | } 366 | 367 | PyDoc_STRVAR(_curses_panel_top_panel__doc__, 368 | "top_panel($module, /)\n" 369 | "--\n" 370 | "\n" 371 | "Return the top panel in the panel stack."); 372 | 373 | #define _CURSES_PANEL_TOP_PANEL_METHODDEF \ 374 | {"top_panel", (PyCFunction)_curses_panel_top_panel, METH_NOARGS, _curses_panel_top_panel__doc__}, 375 | 376 | static PyObject * 377 | _curses_panel_top_panel_impl(PyObject *module); 378 | 379 | static PyObject * 380 | _curses_panel_top_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 381 | { 382 | return _curses_panel_top_panel_impl(module); 383 | } 384 | 385 | PyDoc_STRVAR(_curses_panel_update_panels__doc__, 386 | "update_panels($module, /)\n" 387 | "--\n" 388 | "\n" 389 | "Updates the virtual screen after changes in the panel stack.\n" 390 | "\n" 391 | "This does not call curses.doupdate(), so you\'ll have to do this yourself."); 392 | 393 | #define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \ 394 | {"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__}, 395 | 396 | static PyObject * 397 | _curses_panel_update_panels_impl(PyObject *module); 398 | 399 | static PyObject * 400 | _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) 401 | { 402 | return _curses_panel_update_panels_impl(module); 403 | } 404 | /*[clinic end generated code: output=3081ef24e5560cb0 input=a9049054013a1b77]*/ 405 | -------------------------------------------------------------------------------- /py312/clinic/_curses_panel.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) 6 | # include "pycore_gc.h" // PyGC_Head 7 | # include "pycore_runtime.h" // _Py_ID() 8 | #endif 9 | 10 | 11 | PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, 12 | "bottom($self, /)\n" 13 | "--\n" 14 | "\n" 15 | "Push the panel to the bottom of the stack."); 16 | 17 | #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ 18 | {"bottom", _PyCFunction_CAST(_curses_panel_panel_bottom), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__}, 19 | 20 | static PyObject * 21 | _curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); 22 | 23 | static PyObject * 24 | _curses_panel_panel_bottom(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 25 | { 26 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 27 | PyErr_SetString(PyExc_TypeError, "bottom() takes no arguments"); 28 | return NULL; 29 | } 30 | return _curses_panel_panel_bottom_impl(self, cls); 31 | } 32 | 33 | PyDoc_STRVAR(_curses_panel_panel_hide__doc__, 34 | "hide($self, /)\n" 35 | "--\n" 36 | "\n" 37 | "Hide the panel.\n" 38 | "\n" 39 | "This does not delete the object, it just makes the window on screen invisible."); 40 | 41 | #define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ 42 | {"hide", _PyCFunction_CAST(_curses_panel_panel_hide), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__}, 43 | 44 | static PyObject * 45 | _curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); 46 | 47 | static PyObject * 48 | _curses_panel_panel_hide(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 49 | { 50 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 51 | PyErr_SetString(PyExc_TypeError, "hide() takes no arguments"); 52 | return NULL; 53 | } 54 | return _curses_panel_panel_hide_impl(self, cls); 55 | } 56 | 57 | PyDoc_STRVAR(_curses_panel_panel_show__doc__, 58 | "show($self, /)\n" 59 | "--\n" 60 | "\n" 61 | "Display the panel (which might have been hidden)."); 62 | 63 | #define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ 64 | {"show", _PyCFunction_CAST(_curses_panel_panel_show), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__}, 65 | 66 | static PyObject * 67 | _curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); 68 | 69 | static PyObject * 70 | _curses_panel_panel_show(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 71 | { 72 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 73 | PyErr_SetString(PyExc_TypeError, "show() takes no arguments"); 74 | return NULL; 75 | } 76 | return _curses_panel_panel_show_impl(self, cls); 77 | } 78 | 79 | PyDoc_STRVAR(_curses_panel_panel_top__doc__, 80 | "top($self, /)\n" 81 | "--\n" 82 | "\n" 83 | "Push panel to the top of the stack."); 84 | 85 | #define _CURSES_PANEL_PANEL_TOP_METHODDEF \ 86 | {"top", _PyCFunction_CAST(_curses_panel_panel_top), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__}, 87 | 88 | static PyObject * 89 | _curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); 90 | 91 | static PyObject * 92 | _curses_panel_panel_top(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 93 | { 94 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 95 | PyErr_SetString(PyExc_TypeError, "top() takes no arguments"); 96 | return NULL; 97 | } 98 | return _curses_panel_panel_top_impl(self, cls); 99 | } 100 | 101 | PyDoc_STRVAR(_curses_panel_panel_above__doc__, 102 | "above($self, /)\n" 103 | "--\n" 104 | "\n" 105 | "Return the panel above the current panel."); 106 | 107 | #define _CURSES_PANEL_PANEL_ABOVE_METHODDEF \ 108 | {"above", (PyCFunction)_curses_panel_panel_above, METH_NOARGS, _curses_panel_panel_above__doc__}, 109 | 110 | static PyObject * 111 | _curses_panel_panel_above_impl(PyCursesPanelObject *self); 112 | 113 | static PyObject * 114 | _curses_panel_panel_above(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 115 | { 116 | return _curses_panel_panel_above_impl(self); 117 | } 118 | 119 | PyDoc_STRVAR(_curses_panel_panel_below__doc__, 120 | "below($self, /)\n" 121 | "--\n" 122 | "\n" 123 | "Return the panel below the current panel."); 124 | 125 | #define _CURSES_PANEL_PANEL_BELOW_METHODDEF \ 126 | {"below", (PyCFunction)_curses_panel_panel_below, METH_NOARGS, _curses_panel_panel_below__doc__}, 127 | 128 | static PyObject * 129 | _curses_panel_panel_below_impl(PyCursesPanelObject *self); 130 | 131 | static PyObject * 132 | _curses_panel_panel_below(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 133 | { 134 | return _curses_panel_panel_below_impl(self); 135 | } 136 | 137 | PyDoc_STRVAR(_curses_panel_panel_hidden__doc__, 138 | "hidden($self, /)\n" 139 | "--\n" 140 | "\n" 141 | "Return True if the panel is hidden (not visible), False otherwise."); 142 | 143 | #define _CURSES_PANEL_PANEL_HIDDEN_METHODDEF \ 144 | {"hidden", (PyCFunction)_curses_panel_panel_hidden, METH_NOARGS, _curses_panel_panel_hidden__doc__}, 145 | 146 | static PyObject * 147 | _curses_panel_panel_hidden_impl(PyCursesPanelObject *self); 148 | 149 | static PyObject * 150 | _curses_panel_panel_hidden(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 151 | { 152 | return _curses_panel_panel_hidden_impl(self); 153 | } 154 | 155 | PyDoc_STRVAR(_curses_panel_panel_move__doc__, 156 | "move($self, y, x, /)\n" 157 | "--\n" 158 | "\n" 159 | "Move the panel to the screen coordinates (y, x)."); 160 | 161 | #define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ 162 | {"move", _PyCFunction_CAST(_curses_panel_panel_move), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__}, 163 | 164 | static PyObject * 165 | _curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls, 166 | int y, int x); 167 | 168 | static PyObject * 169 | _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 170 | { 171 | PyObject *return_value = NULL; 172 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) 173 | # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) 174 | #else 175 | # define KWTUPLE NULL 176 | #endif 177 | 178 | static const char * const _keywords[] = {"", "", NULL}; 179 | static _PyArg_Parser _parser = { 180 | .keywords = _keywords, 181 | .fname = "move", 182 | .kwtuple = KWTUPLE, 183 | }; 184 | #undef KWTUPLE 185 | PyObject *argsbuf[2]; 186 | int y; 187 | int x; 188 | 189 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); 190 | if (!args) { 191 | goto exit; 192 | } 193 | y = _PyLong_AsInt(args[0]); 194 | if (y == -1 && PyErr_Occurred()) { 195 | goto exit; 196 | } 197 | x = _PyLong_AsInt(args[1]); 198 | if (x == -1 && PyErr_Occurred()) { 199 | goto exit; 200 | } 201 | return_value = _curses_panel_panel_move_impl(self, cls, y, x); 202 | 203 | exit: 204 | return return_value; 205 | } 206 | 207 | PyDoc_STRVAR(_curses_panel_panel_window__doc__, 208 | "window($self, /)\n" 209 | "--\n" 210 | "\n" 211 | "Return the window object associated with the panel."); 212 | 213 | #define _CURSES_PANEL_PANEL_WINDOW_METHODDEF \ 214 | {"window", (PyCFunction)_curses_panel_panel_window, METH_NOARGS, _curses_panel_panel_window__doc__}, 215 | 216 | static PyObject * 217 | _curses_panel_panel_window_impl(PyCursesPanelObject *self); 218 | 219 | static PyObject * 220 | _curses_panel_panel_window(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 221 | { 222 | return _curses_panel_panel_window_impl(self); 223 | } 224 | 225 | PyDoc_STRVAR(_curses_panel_panel_replace__doc__, 226 | "replace($self, win, /)\n" 227 | "--\n" 228 | "\n" 229 | "Change the window associated with the panel to the window win."); 230 | 231 | #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ 232 | {"replace", _PyCFunction_CAST(_curses_panel_panel_replace), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__}, 233 | 234 | static PyObject * 235 | _curses_panel_panel_replace_impl(PyCursesPanelObject *self, 236 | PyTypeObject *cls, 237 | PyCursesWindowObject *win); 238 | 239 | static PyObject * 240 | _curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 241 | { 242 | PyObject *return_value = NULL; 243 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) 244 | # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) 245 | #else 246 | # define KWTUPLE NULL 247 | #endif 248 | 249 | static const char * const _keywords[] = {"", NULL}; 250 | static _PyArg_Parser _parser = { 251 | .keywords = _keywords, 252 | .fname = "replace", 253 | .kwtuple = KWTUPLE, 254 | }; 255 | #undef KWTUPLE 256 | PyObject *argsbuf[1]; 257 | PyCursesWindowObject *win; 258 | 259 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); 260 | if (!args) { 261 | goto exit; 262 | } 263 | if (!PyObject_TypeCheck(args[0], &PyCursesWindow_Type)) { 264 | _PyArg_BadArgument("replace", "argument 1", (&PyCursesWindow_Type)->tp_name, args[0]); 265 | goto exit; 266 | } 267 | win = (PyCursesWindowObject *)args[0]; 268 | return_value = _curses_panel_panel_replace_impl(self, cls, win); 269 | 270 | exit: 271 | return return_value; 272 | } 273 | 274 | PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, 275 | "set_userptr($self, obj, /)\n" 276 | "--\n" 277 | "\n" 278 | "Set the panel\'s user pointer to obj."); 279 | 280 | #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ 281 | {"set_userptr", _PyCFunction_CAST(_curses_panel_panel_set_userptr), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_set_userptr__doc__}, 282 | 283 | static PyObject * 284 | _curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self, 285 | PyTypeObject *cls, PyObject *obj); 286 | 287 | static PyObject * 288 | _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 289 | { 290 | PyObject *return_value = NULL; 291 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) 292 | # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) 293 | #else 294 | # define KWTUPLE NULL 295 | #endif 296 | 297 | static const char * const _keywords[] = {"", NULL}; 298 | static _PyArg_Parser _parser = { 299 | .keywords = _keywords, 300 | .fname = "set_userptr", 301 | .kwtuple = KWTUPLE, 302 | }; 303 | #undef KWTUPLE 304 | PyObject *argsbuf[1]; 305 | PyObject *obj; 306 | 307 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); 308 | if (!args) { 309 | goto exit; 310 | } 311 | obj = args[0]; 312 | return_value = _curses_panel_panel_set_userptr_impl(self, cls, obj); 313 | 314 | exit: 315 | return return_value; 316 | } 317 | 318 | PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, 319 | "userptr($self, /)\n" 320 | "--\n" 321 | "\n" 322 | "Return the user pointer for the panel."); 323 | 324 | #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ 325 | {"userptr", _PyCFunction_CAST(_curses_panel_panel_userptr), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__}, 326 | 327 | static PyObject * 328 | _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, 329 | PyTypeObject *cls); 330 | 331 | static PyObject * 332 | _curses_panel_panel_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 333 | { 334 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 335 | PyErr_SetString(PyExc_TypeError, "userptr() takes no arguments"); 336 | return NULL; 337 | } 338 | return _curses_panel_panel_userptr_impl(self, cls); 339 | } 340 | 341 | PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, 342 | "bottom_panel($module, /)\n" 343 | "--\n" 344 | "\n" 345 | "Return the bottom panel in the panel stack."); 346 | 347 | #define _CURSES_PANEL_BOTTOM_PANEL_METHODDEF \ 348 | {"bottom_panel", (PyCFunction)_curses_panel_bottom_panel, METH_NOARGS, _curses_panel_bottom_panel__doc__}, 349 | 350 | static PyObject * 351 | _curses_panel_bottom_panel_impl(PyObject *module); 352 | 353 | static PyObject * 354 | _curses_panel_bottom_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 355 | { 356 | return _curses_panel_bottom_panel_impl(module); 357 | } 358 | 359 | PyDoc_STRVAR(_curses_panel_new_panel__doc__, 360 | "new_panel($module, win, /)\n" 361 | "--\n" 362 | "\n" 363 | "Return a panel object, associating it with the given window win."); 364 | 365 | #define _CURSES_PANEL_NEW_PANEL_METHODDEF \ 366 | {"new_panel", (PyCFunction)_curses_panel_new_panel, METH_O, _curses_panel_new_panel__doc__}, 367 | 368 | static PyObject * 369 | _curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win); 370 | 371 | static PyObject * 372 | _curses_panel_new_panel(PyObject *module, PyObject *arg) 373 | { 374 | PyObject *return_value = NULL; 375 | PyCursesWindowObject *win; 376 | 377 | if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { 378 | _PyArg_BadArgument("new_panel", "argument", (&PyCursesWindow_Type)->tp_name, arg); 379 | goto exit; 380 | } 381 | win = (PyCursesWindowObject *)arg; 382 | return_value = _curses_panel_new_panel_impl(module, win); 383 | 384 | exit: 385 | return return_value; 386 | } 387 | 388 | PyDoc_STRVAR(_curses_panel_top_panel__doc__, 389 | "top_panel($module, /)\n" 390 | "--\n" 391 | "\n" 392 | "Return the top panel in the panel stack."); 393 | 394 | #define _CURSES_PANEL_TOP_PANEL_METHODDEF \ 395 | {"top_panel", (PyCFunction)_curses_panel_top_panel, METH_NOARGS, _curses_panel_top_panel__doc__}, 396 | 397 | static PyObject * 398 | _curses_panel_top_panel_impl(PyObject *module); 399 | 400 | static PyObject * 401 | _curses_panel_top_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 402 | { 403 | return _curses_panel_top_panel_impl(module); 404 | } 405 | 406 | PyDoc_STRVAR(_curses_panel_update_panels__doc__, 407 | "update_panels($module, /)\n" 408 | "--\n" 409 | "\n" 410 | "Updates the virtual screen after changes in the panel stack.\n" 411 | "\n" 412 | "This does not call curses.doupdate(), so you\'ll have to do this yourself."); 413 | 414 | #define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \ 415 | {"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__}, 416 | 417 | static PyObject * 418 | _curses_panel_update_panels_impl(PyObject *module); 419 | 420 | static PyObject * 421 | _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) 422 | { 423 | return _curses_panel_update_panels_impl(module); 424 | } 425 | /*[clinic end generated code: output=550ee3ad1ce9ec07 input=a9049054013a1b77]*/ 426 | -------------------------------------------------------------------------------- /py313/clinic/_curses_panel.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) 6 | # include "pycore_runtime.h" // _Py_SINGLETON() 7 | #endif 8 | 9 | // Export for 'math' shared extension 10 | PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywords( 11 | PyObject *const *args, 12 | Py_ssize_t nargs, 13 | PyObject *kwargs, 14 | PyObject *kwnames, 15 | struct _PyArg_Parser *parser, 16 | int minpos, 17 | int maxpos, 18 | int minkw, 19 | PyObject **buf); 20 | #define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \ 21 | (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \ 22 | (minpos) <= (nargs) && (nargs) <= (maxpos) && (args) != NULL) ? (args) : \ 23 | _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \ 24 | (minpos), (maxpos), (minkw), (buf))) 25 | 26 | // Export for '_heapq' shared extension 27 | PyAPI_FUNC(void) _PyArg_BadArgument( 28 | const char *fname, 29 | const char *displayname, 30 | const char *expected, 31 | PyObject *arg); 32 | 33 | PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, 34 | "bottom($self, /)\n" 35 | "--\n" 36 | "\n" 37 | "Push the panel to the bottom of the stack."); 38 | 39 | #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ 40 | {"bottom", _PyCFunction_CAST(_curses_panel_panel_bottom), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_bottom__doc__}, 41 | 42 | static PyObject * 43 | _curses_panel_panel_bottom_impl(PyCursesPanelObject *self, PyTypeObject *cls); 44 | 45 | static PyObject * 46 | _curses_panel_panel_bottom(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 47 | { 48 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 49 | PyErr_SetString(PyExc_TypeError, "bottom() takes no arguments"); 50 | return NULL; 51 | } 52 | return _curses_panel_panel_bottom_impl(self, cls); 53 | } 54 | 55 | PyDoc_STRVAR(_curses_panel_panel_hide__doc__, 56 | "hide($self, /)\n" 57 | "--\n" 58 | "\n" 59 | "Hide the panel.\n" 60 | "\n" 61 | "This does not delete the object, it just makes the window on screen invisible."); 62 | 63 | #define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ 64 | {"hide", _PyCFunction_CAST(_curses_panel_panel_hide), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_hide__doc__}, 65 | 66 | static PyObject * 67 | _curses_panel_panel_hide_impl(PyCursesPanelObject *self, PyTypeObject *cls); 68 | 69 | static PyObject * 70 | _curses_panel_panel_hide(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 71 | { 72 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 73 | PyErr_SetString(PyExc_TypeError, "hide() takes no arguments"); 74 | return NULL; 75 | } 76 | return _curses_panel_panel_hide_impl(self, cls); 77 | } 78 | 79 | PyDoc_STRVAR(_curses_panel_panel_show__doc__, 80 | "show($self, /)\n" 81 | "--\n" 82 | "\n" 83 | "Display the panel (which might have been hidden)."); 84 | 85 | #define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ 86 | {"show", _PyCFunction_CAST(_curses_panel_panel_show), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_show__doc__}, 87 | 88 | static PyObject * 89 | _curses_panel_panel_show_impl(PyCursesPanelObject *self, PyTypeObject *cls); 90 | 91 | static PyObject * 92 | _curses_panel_panel_show(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 93 | { 94 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 95 | PyErr_SetString(PyExc_TypeError, "show() takes no arguments"); 96 | return NULL; 97 | } 98 | return _curses_panel_panel_show_impl(self, cls); 99 | } 100 | 101 | PyDoc_STRVAR(_curses_panel_panel_top__doc__, 102 | "top($self, /)\n" 103 | "--\n" 104 | "\n" 105 | "Push panel to the top of the stack."); 106 | 107 | #define _CURSES_PANEL_PANEL_TOP_METHODDEF \ 108 | {"top", _PyCFunction_CAST(_curses_panel_panel_top), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_top__doc__}, 109 | 110 | static PyObject * 111 | _curses_panel_panel_top_impl(PyCursesPanelObject *self, PyTypeObject *cls); 112 | 113 | static PyObject * 114 | _curses_panel_panel_top(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 115 | { 116 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 117 | PyErr_SetString(PyExc_TypeError, "top() takes no arguments"); 118 | return NULL; 119 | } 120 | return _curses_panel_panel_top_impl(self, cls); 121 | } 122 | 123 | PyDoc_STRVAR(_curses_panel_panel_above__doc__, 124 | "above($self, /)\n" 125 | "--\n" 126 | "\n" 127 | "Return the panel above the current panel."); 128 | 129 | #define _CURSES_PANEL_PANEL_ABOVE_METHODDEF \ 130 | {"above", (PyCFunction)_curses_panel_panel_above, METH_NOARGS, _curses_panel_panel_above__doc__}, 131 | 132 | static PyObject * 133 | _curses_panel_panel_above_impl(PyCursesPanelObject *self); 134 | 135 | static PyObject * 136 | _curses_panel_panel_above(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 137 | { 138 | return _curses_panel_panel_above_impl(self); 139 | } 140 | 141 | PyDoc_STRVAR(_curses_panel_panel_below__doc__, 142 | "below($self, /)\n" 143 | "--\n" 144 | "\n" 145 | "Return the panel below the current panel."); 146 | 147 | #define _CURSES_PANEL_PANEL_BELOW_METHODDEF \ 148 | {"below", (PyCFunction)_curses_panel_panel_below, METH_NOARGS, _curses_panel_panel_below__doc__}, 149 | 150 | static PyObject * 151 | _curses_panel_panel_below_impl(PyCursesPanelObject *self); 152 | 153 | static PyObject * 154 | _curses_panel_panel_below(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 155 | { 156 | return _curses_panel_panel_below_impl(self); 157 | } 158 | 159 | PyDoc_STRVAR(_curses_panel_panel_hidden__doc__, 160 | "hidden($self, /)\n" 161 | "--\n" 162 | "\n" 163 | "Return True if the panel is hidden (not visible), False otherwise."); 164 | 165 | #define _CURSES_PANEL_PANEL_HIDDEN_METHODDEF \ 166 | {"hidden", (PyCFunction)_curses_panel_panel_hidden, METH_NOARGS, _curses_panel_panel_hidden__doc__}, 167 | 168 | static PyObject * 169 | _curses_panel_panel_hidden_impl(PyCursesPanelObject *self); 170 | 171 | static PyObject * 172 | _curses_panel_panel_hidden(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 173 | { 174 | return _curses_panel_panel_hidden_impl(self); 175 | } 176 | 177 | PyDoc_STRVAR(_curses_panel_panel_move__doc__, 178 | "move($self, y, x, /)\n" 179 | "--\n" 180 | "\n" 181 | "Move the panel to the screen coordinates (y, x)."); 182 | 183 | #define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ 184 | {"move", _PyCFunction_CAST(_curses_panel_panel_move), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_move__doc__}, 185 | 186 | static PyObject * 187 | _curses_panel_panel_move_impl(PyCursesPanelObject *self, PyTypeObject *cls, 188 | int y, int x); 189 | 190 | static PyObject * 191 | _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 192 | { 193 | PyObject *return_value = NULL; 194 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) 195 | # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) 196 | #else 197 | # define KWTUPLE NULL 198 | #endif 199 | 200 | static const char * const _keywords[] = {"", "", NULL}; 201 | static _PyArg_Parser _parser = { 202 | .keywords = _keywords, 203 | .fname = "move", 204 | .kwtuple = KWTUPLE, 205 | }; 206 | #undef KWTUPLE 207 | PyObject *argsbuf[2]; 208 | int y; 209 | int x; 210 | 211 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); 212 | if (!args) { 213 | goto exit; 214 | } 215 | y = PyLong_AsInt(args[0]); 216 | if (y == -1 && PyErr_Occurred()) { 217 | goto exit; 218 | } 219 | x = PyLong_AsInt(args[1]); 220 | if (x == -1 && PyErr_Occurred()) { 221 | goto exit; 222 | } 223 | return_value = _curses_panel_panel_move_impl(self, cls, y, x); 224 | 225 | exit: 226 | return return_value; 227 | } 228 | 229 | PyDoc_STRVAR(_curses_panel_panel_window__doc__, 230 | "window($self, /)\n" 231 | "--\n" 232 | "\n" 233 | "Return the window object associated with the panel."); 234 | 235 | #define _CURSES_PANEL_PANEL_WINDOW_METHODDEF \ 236 | {"window", (PyCFunction)_curses_panel_panel_window, METH_NOARGS, _curses_panel_panel_window__doc__}, 237 | 238 | static PyObject * 239 | _curses_panel_panel_window_impl(PyCursesPanelObject *self); 240 | 241 | static PyObject * 242 | _curses_panel_panel_window(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 243 | { 244 | return _curses_panel_panel_window_impl(self); 245 | } 246 | 247 | PyDoc_STRVAR(_curses_panel_panel_replace__doc__, 248 | "replace($self, win, /)\n" 249 | "--\n" 250 | "\n" 251 | "Change the window associated with the panel to the window win."); 252 | 253 | #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ 254 | {"replace", _PyCFunction_CAST(_curses_panel_panel_replace), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_replace__doc__}, 255 | 256 | static PyObject * 257 | _curses_panel_panel_replace_impl(PyCursesPanelObject *self, 258 | PyTypeObject *cls, 259 | PyCursesWindowObject *win); 260 | 261 | static PyObject * 262 | _curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 263 | { 264 | PyObject *return_value = NULL; 265 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) 266 | # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) 267 | #else 268 | # define KWTUPLE NULL 269 | #endif 270 | 271 | static const char * const _keywords[] = {"", NULL}; 272 | static _PyArg_Parser _parser = { 273 | .keywords = _keywords, 274 | .fname = "replace", 275 | .kwtuple = KWTUPLE, 276 | }; 277 | #undef KWTUPLE 278 | PyObject *argsbuf[1]; 279 | PyCursesWindowObject *win; 280 | 281 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); 282 | if (!args) { 283 | goto exit; 284 | } 285 | if (!PyObject_TypeCheck(args[0], &PyCursesWindow_Type)) { 286 | _PyArg_BadArgument("replace", "argument 1", (&PyCursesWindow_Type)->tp_name, args[0]); 287 | goto exit; 288 | } 289 | win = (PyCursesWindowObject *)args[0]; 290 | return_value = _curses_panel_panel_replace_impl(self, cls, win); 291 | 292 | exit: 293 | return return_value; 294 | } 295 | 296 | PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, 297 | "set_userptr($self, obj, /)\n" 298 | "--\n" 299 | "\n" 300 | "Set the panel\'s user pointer to obj."); 301 | 302 | #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ 303 | {"set_userptr", _PyCFunction_CAST(_curses_panel_panel_set_userptr), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_set_userptr__doc__}, 304 | 305 | static PyObject * 306 | _curses_panel_panel_set_userptr_impl(PyCursesPanelObject *self, 307 | PyTypeObject *cls, PyObject *obj); 308 | 309 | static PyObject * 310 | _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 311 | { 312 | PyObject *return_value = NULL; 313 | #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) 314 | # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) 315 | #else 316 | # define KWTUPLE NULL 317 | #endif 318 | 319 | static const char * const _keywords[] = {"", NULL}; 320 | static _PyArg_Parser _parser = { 321 | .keywords = _keywords, 322 | .fname = "set_userptr", 323 | .kwtuple = KWTUPLE, 324 | }; 325 | #undef KWTUPLE 326 | PyObject *argsbuf[1]; 327 | PyObject *obj; 328 | 329 | args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); 330 | if (!args) { 331 | goto exit; 332 | } 333 | obj = args[0]; 334 | return_value = _curses_panel_panel_set_userptr_impl(self, cls, obj); 335 | 336 | exit: 337 | return return_value; 338 | } 339 | 340 | PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, 341 | "userptr($self, /)\n" 342 | "--\n" 343 | "\n" 344 | "Return the user pointer for the panel."); 345 | 346 | #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ 347 | {"userptr", _PyCFunction_CAST(_curses_panel_panel_userptr), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _curses_panel_panel_userptr__doc__}, 348 | 349 | static PyObject * 350 | _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, 351 | PyTypeObject *cls); 352 | 353 | static PyObject * 354 | _curses_panel_panel_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) 355 | { 356 | if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { 357 | PyErr_SetString(PyExc_TypeError, "userptr() takes no arguments"); 358 | return NULL; 359 | } 360 | return _curses_panel_panel_userptr_impl(self, cls); 361 | } 362 | 363 | PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, 364 | "bottom_panel($module, /)\n" 365 | "--\n" 366 | "\n" 367 | "Return the bottom panel in the panel stack."); 368 | 369 | #define _CURSES_PANEL_BOTTOM_PANEL_METHODDEF \ 370 | {"bottom_panel", (PyCFunction)_curses_panel_bottom_panel, METH_NOARGS, _curses_panel_bottom_panel__doc__}, 371 | 372 | static PyObject * 373 | _curses_panel_bottom_panel_impl(PyObject *module); 374 | 375 | static PyObject * 376 | _curses_panel_bottom_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 377 | { 378 | return _curses_panel_bottom_panel_impl(module); 379 | } 380 | 381 | PyDoc_STRVAR(_curses_panel_new_panel__doc__, 382 | "new_panel($module, win, /)\n" 383 | "--\n" 384 | "\n" 385 | "Return a panel object, associating it with the given window win."); 386 | 387 | #define _CURSES_PANEL_NEW_PANEL_METHODDEF \ 388 | {"new_panel", (PyCFunction)_curses_panel_new_panel, METH_O, _curses_panel_new_panel__doc__}, 389 | 390 | static PyObject * 391 | _curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win); 392 | 393 | static PyObject * 394 | _curses_panel_new_panel(PyObject *module, PyObject *arg) 395 | { 396 | PyObject *return_value = NULL; 397 | PyCursesWindowObject *win; 398 | 399 | if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { 400 | _PyArg_BadArgument("new_panel", "argument", (&PyCursesWindow_Type)->tp_name, arg); 401 | goto exit; 402 | } 403 | win = (PyCursesWindowObject *)arg; 404 | return_value = _curses_panel_new_panel_impl(module, win); 405 | 406 | exit: 407 | return return_value; 408 | } 409 | 410 | PyDoc_STRVAR(_curses_panel_top_panel__doc__, 411 | "top_panel($module, /)\n" 412 | "--\n" 413 | "\n" 414 | "Return the top panel in the panel stack."); 415 | 416 | #define _CURSES_PANEL_TOP_PANEL_METHODDEF \ 417 | {"top_panel", (PyCFunction)_curses_panel_top_panel, METH_NOARGS, _curses_panel_top_panel__doc__}, 418 | 419 | static PyObject * 420 | _curses_panel_top_panel_impl(PyObject *module); 421 | 422 | static PyObject * 423 | _curses_panel_top_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 424 | { 425 | return _curses_panel_top_panel_impl(module); 426 | } 427 | 428 | PyDoc_STRVAR(_curses_panel_update_panels__doc__, 429 | "update_panels($module, /)\n" 430 | "--\n" 431 | "\n" 432 | "Updates the virtual screen after changes in the panel stack.\n" 433 | "\n" 434 | "This does not call curses.doupdate(), so you\'ll have to do this yourself."); 435 | 436 | #define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \ 437 | {"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__}, 438 | 439 | static PyObject * 440 | _curses_panel_update_panels_impl(PyObject *module); 441 | 442 | static PyObject * 443 | _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) 444 | { 445 | return _curses_panel_update_panels_impl(module); 446 | } 447 | /*[clinic end generated code: output=18dc5571174c7189 input=a9049054013a1b77]*/ 448 | -------------------------------------------------------------------------------- /py34/clinic/_cursesmodule.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | PyDoc_STRVAR(curses_window_addch__doc__, 6 | "addch([y, x,] ch, [attr])\n" 7 | "Paint character ch at (y, x) with attributes attr.\n" 8 | "\n" 9 | " y\n" 10 | " Y-coordinate.\n" 11 | " x\n" 12 | " X-coordinate.\n" 13 | " ch\n" 14 | " Character to add.\n" 15 | " attr\n" 16 | " Attributes for the character.\n" 17 | "\n" 18 | "Paint character ch at (y, x) with attributes attr,\n" 19 | "overwriting any character previously painted at that location.\n" 20 | "By default, the character position and attributes are the\n" 21 | "current settings for the window object."); 22 | 23 | #define CURSES_WINDOW_ADDCH_METHODDEF \ 24 | {"addch", (PyCFunction)curses_window_addch, METH_VARARGS, curses_window_addch__doc__}, 25 | 26 | static PyObject * 27 | curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, 28 | int x, PyObject *ch, int group_right_1, long attr); 29 | 30 | static PyObject * 31 | curses_window_addch(PyCursesWindowObject *self, PyObject *args) 32 | { 33 | PyObject *return_value = NULL; 34 | int group_left_1 = 0; 35 | int y = 0; 36 | int x = 0; 37 | PyObject *ch; 38 | int group_right_1 = 0; 39 | long attr = 0; 40 | 41 | switch (PyTuple_GET_SIZE(args)) { 42 | case 1: 43 | if (!PyArg_ParseTuple(args, "O:addch", &ch)) { 44 | goto exit; 45 | } 46 | break; 47 | case 2: 48 | if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) { 49 | goto exit; 50 | } 51 | group_right_1 = 1; 52 | break; 53 | case 3: 54 | if (!PyArg_ParseTuple(args, "iiO:addch", &y, &x, &ch)) { 55 | goto exit; 56 | } 57 | group_left_1 = 1; 58 | break; 59 | case 4: 60 | if (!PyArg_ParseTuple(args, "iiOl:addch", &y, &x, &ch, &attr)) { 61 | goto exit; 62 | } 63 | group_right_1 = 1; 64 | group_left_1 = 1; 65 | break; 66 | default: 67 | PyErr_SetString(PyExc_TypeError, "curses.window.addch requires 1 to 4 arguments"); 68 | goto exit; 69 | } 70 | return_value = curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); 71 | 72 | exit: 73 | return return_value; 74 | } 75 | /*[clinic end generated code: output=13ffc5f8d79cbfbf input=a9049054013a1b77]*/ 76 | -------------------------------------------------------------------------------- /py34/mkstemp.c: -------------------------------------------------------------------------------- 1 | /* $NiH: mkstemp.c,v 1.3 2006/04/23 14:51:45 wiz Exp $ */ 2 | 3 | /* Adapted from NetBSB libc by Dieter Baron */ 4 | 5 | /* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */ 6 | 7 | /* 8 | * Copyright (c) 1987, 1993 9 | * The Regents of the University of California. All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. Neither the name of the University nor the names of its contributors 20 | * may be used to endorse or promote products derived from this software 21 | * without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 | * SUCH DAMAGE. 34 | */ 35 | 36 | #include 37 | #include 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #ifdef _WIN32 47 | #include 48 | #include 49 | #define getpid() _getpid() 50 | typedef int pid_t; 51 | #define S_ISDIR(m) (((m) & (_S_IFMT)) == (_S_IFDIR)) 52 | #define open(p, f, m) _open((p), ((f) | _O_BINARY), _S_IREAD | _S_IWRITE) 53 | #endif 54 | 55 | int 56 | mkstemp(char *path) 57 | { 58 | int fd; 59 | char *start, *trv; 60 | struct stat sbuf; 61 | pid_t pid; 62 | 63 | /* To guarantee multiple calls generate unique names even if 64 | the file is not created. 676 different possibilities with 7 65 | or more X's, 26 with 6 or less. */ 66 | static char xtra[2] = "aa"; 67 | int xcnt = 0; 68 | 69 | pid = getpid(); 70 | 71 | /* Move to end of path and count trailing X's. */ 72 | for (trv = path; *trv; ++trv) 73 | if (*trv == 'X') 74 | xcnt++; 75 | else 76 | xcnt = 0; 77 | 78 | /* Use at least one from xtra. Use 2 if more than 6 X's. */ 79 | if (*(trv - 1) == 'X') 80 | *--trv = xtra[0]; 81 | if (xcnt > 6 && *(trv - 1) == 'X') 82 | *--trv = xtra[1]; 83 | 84 | /* Set remaining X's to pid digits with 0's to the left. */ 85 | while (*--trv == 'X') { 86 | *trv = (pid % 10) + '0'; 87 | pid /= 10; 88 | } 89 | 90 | /* update xtra for next call. */ 91 | if (xtra[0] != 'z') 92 | xtra[0]++; 93 | else { 94 | xtra[0] = 'a'; 95 | if (xtra[1] != 'z') 96 | xtra[1]++; 97 | else 98 | xtra[1] = 'a'; 99 | } 100 | 101 | /* 102 | * check the target directory; if you have six X's and it 103 | * doesn't exist this runs for a *very* long time. 104 | */ 105 | for (start = trv + 1;; --trv) { 106 | if (trv <= path) 107 | break; 108 | if (*trv == '/') { 109 | *trv = '\0'; 110 | if (stat(path, &sbuf)) 111 | return (0); 112 | if (!S_ISDIR(sbuf.st_mode)) { 113 | errno = ENOTDIR; 114 | return (0); 115 | } 116 | *trv = '/'; 117 | break; 118 | } 119 | } 120 | 121 | for (;;) { 122 | if ((fd = open(path, O_CREAT | O_EXCL | O_RDWR, 0600)) >= 0) 123 | return (fd); 124 | if (errno != EEXIST) 125 | return (0); 126 | 127 | /* tricky little algorithm for backward compatibility */ 128 | for (trv = start;;) { 129 | if (!*trv) 130 | return (0); 131 | if (*trv == 'z') 132 | *trv++ = 'a'; 133 | else { 134 | if (isdigit((unsigned char)*trv)) 135 | *trv = 'a'; 136 | else 137 | ++*trv; 138 | break; 139 | } 140 | } 141 | } 142 | /*NOTREACHED*/ 143 | } 144 | -------------------------------------------------------------------------------- /py35/_curses_panel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Interface to the ncurses panel library 3 | * 4 | * Original version by Thomas Gellekum 5 | */ 6 | 7 | /* Release Number */ 8 | 9 | static const char PyCursesVersion[] = "2.1"; 10 | 11 | /* Includes */ 12 | 13 | #include "Python.h" 14 | 15 | #include "py_curses.h" 16 | 17 | #include 18 | 19 | typedef struct { 20 | PyObject *PyCursesError; 21 | PyObject *PyCursesPanel_Type; 22 | } _curses_panelstate; 23 | 24 | #define _curses_panelstate(o) ((_curses_panelstate *)PyModule_GetState(o)) 25 | 26 | static int 27 | _curses_panel_clear(PyObject *m) 28 | { 29 | Py_CLEAR(_curses_panelstate(m)->PyCursesError); 30 | return 0; 31 | } 32 | 33 | static int 34 | _curses_panel_traverse(PyObject *m, visitproc visit, void *arg) 35 | { 36 | Py_VISIT(_curses_panelstate(m)->PyCursesError); 37 | return 0; 38 | } 39 | 40 | static void 41 | _curses_panel_free(void *m) 42 | { 43 | _curses_panel_clear((PyObject *) m); 44 | } 45 | 46 | static struct PyModuleDef _curses_panelmodule; 47 | 48 | #define _curses_panelstate_global \ 49 | ((_curses_panelstate *) PyModule_GetState(PyState_FindModule(&_curses_panelmodule))) 50 | 51 | /* Utility Functions */ 52 | 53 | /* 54 | * Check the return code from a curses function and return None 55 | * or raise an exception as appropriate. 56 | */ 57 | 58 | static PyObject * 59 | PyCursesCheckERR(int code, const char *fname) 60 | { 61 | if (code != ERR) { 62 | Py_RETURN_NONE; 63 | } else { 64 | if (fname == NULL) { 65 | PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_ERR); 66 | } else { 67 | PyErr_Format(_curses_panelstate_global->PyCursesError, "%s() returned ERR", fname); 68 | } 69 | return NULL; 70 | } 71 | } 72 | 73 | /***************************************************************************** 74 | The Panel Object 75 | ******************************************************************************/ 76 | 77 | /* Definition of the panel object and panel type */ 78 | 79 | typedef struct { 80 | PyObject_HEAD 81 | PANEL *pan; 82 | PyCursesWindowObject *wo; /* for reference counts */ 83 | } PyCursesPanelObject; 84 | 85 | #define PyCursesPanel_Check(v) \ 86 | (Py_TYPE(v) == _curses_panelstate_global->PyCursesPanel_Type) 87 | 88 | /* Some helper functions. The problem is that there's always a window 89 | associated with a panel. To ensure that Python's GC doesn't pull 90 | this window from under our feet we need to keep track of references 91 | to the corresponding window object within Python. We can't use 92 | dupwin(oldwin) to keep a copy of the curses WINDOW because the 93 | contents of oldwin is copied only once; code like 94 | 95 | win = newwin(...) 96 | pan = win.panel() 97 | win.addstr(some_string) 98 | pan.window().addstr(other_string) 99 | 100 | will fail. */ 101 | 102 | /* We keep a linked list of PyCursesPanelObjects, lop. A list should 103 | suffice, I don't expect more than a handful or at most a few 104 | dozens of panel objects within a typical program. */ 105 | typedef struct _list_of_panels { 106 | PyCursesPanelObject *po; 107 | struct _list_of_panels *next; 108 | } list_of_panels; 109 | 110 | /* list anchor */ 111 | static list_of_panels *lop; 112 | 113 | /* Insert a new panel object into lop */ 114 | static int 115 | insert_lop(PyCursesPanelObject *po) 116 | { 117 | list_of_panels *new; 118 | 119 | if ((new = (list_of_panels *)PyMem_Malloc(sizeof(list_of_panels))) == NULL) { 120 | PyErr_NoMemory(); 121 | return -1; 122 | } 123 | new->po = po; 124 | new->next = lop; 125 | lop = new; 126 | return 0; 127 | } 128 | 129 | /* Remove the panel object from lop */ 130 | static void 131 | remove_lop(PyCursesPanelObject *po) 132 | { 133 | list_of_panels *temp, *n; 134 | 135 | temp = lop; 136 | if (temp->po == po) { 137 | lop = temp->next; 138 | PyMem_Free(temp); 139 | return; 140 | } 141 | while (temp->next == NULL || temp->next->po != po) { 142 | if (temp->next == NULL) { 143 | PyErr_SetString(PyExc_RuntimeError, 144 | "remove_lop: can't find Panel Object"); 145 | return; 146 | } 147 | temp = temp->next; 148 | } 149 | n = temp->next->next; 150 | PyMem_Free(temp->next); 151 | temp->next = n; 152 | return; 153 | } 154 | 155 | /* Return the panel object that corresponds to pan */ 156 | static PyCursesPanelObject * 157 | find_po(PANEL *pan) 158 | { 159 | list_of_panels *temp; 160 | for (temp = lop; temp->po->pan != pan; temp = temp->next) 161 | if (temp->next == NULL) return NULL; /* not found!? */ 162 | return temp->po; 163 | } 164 | 165 | /* Function Prototype Macros - They are ugly but very, very useful. ;-) 166 | 167 | X - function name 168 | TYPE - parameter Type 169 | ERGSTR - format string for construction of the return value 170 | PARSESTR - format string for argument parsing */ 171 | 172 | #define Panel_NoArgNoReturnFunction(X) \ 173 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ 174 | { return PyCursesCheckERR(X(self->pan), # X); } 175 | 176 | #define Panel_NoArgTrueFalseFunction(X) \ 177 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ 178 | { \ 179 | if (X (self->pan) == FALSE) { Py_RETURN_FALSE; } \ 180 | else { Py_RETURN_TRUE; } } 181 | 182 | #define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \ 183 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \ 184 | { \ 185 | TYPE arg1, arg2; \ 186 | if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \ 187 | return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); } 188 | 189 | /* ------------- PANEL routines --------------- */ 190 | 191 | Panel_NoArgNoReturnFunction(bottom_panel) 192 | Panel_NoArgNoReturnFunction(hide_panel) 193 | Panel_NoArgNoReturnFunction(show_panel) 194 | Panel_NoArgNoReturnFunction(top_panel) 195 | Panel_NoArgTrueFalseFunction(panel_hidden) 196 | Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x") 197 | 198 | /* Allocation and deallocation of Panel Objects */ 199 | 200 | static PyObject * 201 | PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo) 202 | { 203 | PyCursesPanelObject *po; 204 | 205 | po = PyObject_NEW(PyCursesPanelObject, 206 | (PyTypeObject *)(_curses_panelstate_global)->PyCursesPanel_Type); 207 | if (po == NULL) return NULL; 208 | po->pan = pan; 209 | if (insert_lop(po) < 0) { 210 | po->wo = NULL; 211 | Py_DECREF(po); 212 | return NULL; 213 | } 214 | po->wo = wo; 215 | Py_INCREF(wo); 216 | return (PyObject *)po; 217 | } 218 | 219 | static void 220 | PyCursesPanel_Dealloc(PyCursesPanelObject *po) 221 | { 222 | PyObject *obj = (PyObject *) panel_userptr(po->pan); 223 | if (obj) { 224 | (void)set_panel_userptr(po->pan, NULL); 225 | Py_DECREF(obj); 226 | } 227 | (void)del_panel(po->pan); 228 | if (po->wo != NULL) { 229 | Py_DECREF(po->wo); 230 | remove_lop(po); 231 | } 232 | PyObject_DEL(po); 233 | } 234 | 235 | /* panel_above(NULL) returns the bottom panel in the stack. To get 236 | this behaviour we use curses.panel.bottom_panel(). */ 237 | static PyObject * 238 | PyCursesPanel_above(PyCursesPanelObject *self) 239 | { 240 | PANEL *pan; 241 | PyCursesPanelObject *po; 242 | 243 | pan = panel_above(self->pan); 244 | 245 | if (pan == NULL) { /* valid output, it means the calling panel 246 | is on top of the stack */ 247 | Py_RETURN_NONE; 248 | } 249 | po = find_po(pan); 250 | if (po == NULL) { 251 | PyErr_SetString(PyExc_RuntimeError, 252 | "panel_above: can't find Panel Object"); 253 | return NULL; 254 | } 255 | Py_INCREF(po); 256 | return (PyObject *)po; 257 | } 258 | 259 | /* panel_below(NULL) returns the top panel in the stack. To get 260 | this behaviour we use curses.panel.top_panel(). */ 261 | static PyObject * 262 | PyCursesPanel_below(PyCursesPanelObject *self) 263 | { 264 | PANEL *pan; 265 | PyCursesPanelObject *po; 266 | 267 | pan = panel_below(self->pan); 268 | 269 | if (pan == NULL) { /* valid output, it means the calling panel 270 | is on the bottom of the stack */ 271 | Py_RETURN_NONE; 272 | } 273 | po = find_po(pan); 274 | if (po == NULL) { 275 | PyErr_SetString(PyExc_RuntimeError, 276 | "panel_below: can't find Panel Object"); 277 | return NULL; 278 | } 279 | Py_INCREF(po); 280 | return (PyObject *)po; 281 | } 282 | 283 | static PyObject * 284 | PyCursesPanel_window(PyCursesPanelObject *self) 285 | { 286 | Py_INCREF(self->wo); 287 | return (PyObject *)self->wo; 288 | } 289 | 290 | static PyObject * 291 | PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args) 292 | { 293 | PyCursesPanelObject *po; 294 | PyCursesWindowObject *temp; 295 | int rtn; 296 | 297 | if (PyTuple_Size(args) != 1) { 298 | PyErr_SetString(PyExc_TypeError, "replace requires one argument"); 299 | return NULL; 300 | } 301 | if (!PyArg_ParseTuple(args, "O!;window object", 302 | &PyCursesWindow_Type, &temp)) 303 | return NULL; 304 | 305 | po = find_po(self->pan); 306 | if (po == NULL) { 307 | PyErr_SetString(PyExc_RuntimeError, 308 | "replace_panel: can't find Panel Object"); 309 | return NULL; 310 | } 311 | 312 | rtn = replace_panel(self->pan, temp->win); 313 | if (rtn == ERR) { 314 | PyErr_SetString(_curses_panelstate_global->PyCursesError, "replace_panel() returned ERR"); 315 | return NULL; 316 | } 317 | Py_INCREF(temp); 318 | Py_SETREF(po->wo, temp); 319 | Py_RETURN_NONE; 320 | } 321 | 322 | static PyObject * 323 | PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) 324 | { 325 | PyObject *oldobj; 326 | int rc; 327 | PyCursesInitialised; 328 | Py_INCREF(obj); 329 | oldobj = (PyObject *) panel_userptr(self->pan); 330 | rc = set_panel_userptr(self->pan, (void*)obj); 331 | if (rc == ERR) { 332 | /* In case of an ncurses error, decref the new object again */ 333 | Py_DECREF(obj); 334 | } 335 | Py_XDECREF(oldobj); 336 | return PyCursesCheckERR(rc, "set_panel_userptr"); 337 | } 338 | 339 | static PyObject * 340 | PyCursesPanel_userptr(PyCursesPanelObject *self) 341 | { 342 | PyObject *obj; 343 | PyCursesInitialised; 344 | obj = (PyObject *) panel_userptr(self->pan); 345 | if (obj == NULL) { 346 | PyErr_SetString(_curses_panelstate_global->PyCursesError, "no userptr set"); 347 | return NULL; 348 | } 349 | 350 | Py_INCREF(obj); 351 | return obj; 352 | } 353 | 354 | 355 | /* Module interface */ 356 | 357 | static PyMethodDef PyCursesPanel_Methods[] = { 358 | {"above", (PyCFunction)PyCursesPanel_above, METH_NOARGS}, 359 | {"below", (PyCFunction)PyCursesPanel_below, METH_NOARGS}, 360 | {"bottom", (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS}, 361 | {"hidden", (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS}, 362 | {"hide", (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS}, 363 | {"move", (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS}, 364 | {"replace", (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS}, 365 | {"set_userptr", (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O}, 366 | {"show", (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS}, 367 | {"top", (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS}, 368 | {"userptr", (PyCFunction)PyCursesPanel_userptr, METH_NOARGS}, 369 | {"window", (PyCFunction)PyCursesPanel_window, METH_NOARGS}, 370 | {NULL, NULL} /* sentinel */ 371 | }; 372 | 373 | /* -------------------------------------------------------*/ 374 | 375 | static PyType_Slot PyCursesPanel_Type_slots[] = { 376 | {Py_tp_dealloc, PyCursesPanel_Dealloc}, 377 | {Py_tp_methods, PyCursesPanel_Methods}, 378 | {0, 0}, 379 | }; 380 | 381 | static PyType_Spec PyCursesPanel_Type_spec = { 382 | "_curses_panel.curses panel", 383 | sizeof(PyCursesPanelObject), 384 | 0, 385 | Py_TPFLAGS_DEFAULT, 386 | PyCursesPanel_Type_slots 387 | }; 388 | 389 | /* Wrapper for panel_above(NULL). This function returns the bottom 390 | panel of the stack, so it's renamed to bottom_panel(). 391 | panel.above() *requires* a panel object in the first place which 392 | may be undesirable. */ 393 | static PyObject * 394 | PyCurses_bottom_panel(PyObject *self) 395 | { 396 | PANEL *pan; 397 | PyCursesPanelObject *po; 398 | 399 | PyCursesInitialised; 400 | 401 | pan = panel_above(NULL); 402 | 403 | if (pan == NULL) { /* valid output, it means 404 | there's no panel at all */ 405 | Py_RETURN_NONE; 406 | } 407 | po = find_po(pan); 408 | if (po == NULL) { 409 | PyErr_SetString(PyExc_RuntimeError, 410 | "panel_above: can't find Panel Object"); 411 | return NULL; 412 | } 413 | Py_INCREF(po); 414 | return (PyObject *)po; 415 | } 416 | 417 | static PyObject * 418 | PyCurses_new_panel(PyObject *self, PyObject *args) 419 | { 420 | PyCursesWindowObject *win; 421 | PANEL *pan; 422 | 423 | if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win)) 424 | return NULL; 425 | pan = new_panel(win->win); 426 | if (pan == NULL) { 427 | PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_NULL); 428 | return NULL; 429 | } 430 | return (PyObject *)PyCursesPanel_New(pan, win); 431 | } 432 | 433 | 434 | /* Wrapper for panel_below(NULL). This function returns the top panel 435 | of the stack, so it's renamed to top_panel(). panel.below() 436 | *requires* a panel object in the first place which may be 437 | undesirable. */ 438 | static PyObject * 439 | PyCurses_top_panel(PyObject *self) 440 | { 441 | PANEL *pan; 442 | PyCursesPanelObject *po; 443 | 444 | PyCursesInitialised; 445 | 446 | pan = panel_below(NULL); 447 | 448 | if (pan == NULL) { /* valid output, it means 449 | there's no panel at all */ 450 | Py_RETURN_NONE; 451 | } 452 | po = find_po(pan); 453 | if (po == NULL) { 454 | PyErr_SetString(PyExc_RuntimeError, 455 | "panel_below: can't find Panel Object"); 456 | return NULL; 457 | } 458 | Py_INCREF(po); 459 | return (PyObject *)po; 460 | } 461 | 462 | static PyObject *PyCurses_update_panels(PyObject *self) 463 | { 464 | PyCursesInitialised; 465 | update_panels(); 466 | Py_RETURN_NONE; 467 | } 468 | 469 | 470 | /* List of functions defined in the module */ 471 | 472 | static PyMethodDef PyCurses_methods[] = { 473 | {"bottom_panel", (PyCFunction)PyCurses_bottom_panel, METH_NOARGS}, 474 | {"new_panel", (PyCFunction)PyCurses_new_panel, METH_VARARGS}, 475 | {"top_panel", (PyCFunction)PyCurses_top_panel, METH_NOARGS}, 476 | {"update_panels", (PyCFunction)PyCurses_update_panels, METH_NOARGS}, 477 | {NULL, NULL} /* sentinel */ 478 | }; 479 | 480 | /* Initialization function for the module */ 481 | 482 | 483 | static struct PyModuleDef _curses_panelmodule = { 484 | PyModuleDef_HEAD_INIT, 485 | "_curses_panel", 486 | NULL, 487 | sizeof(_curses_panelstate), 488 | PyCurses_methods, 489 | NULL, 490 | _curses_panel_traverse, 491 | _curses_panel_clear, 492 | _curses_panel_free 493 | }; 494 | 495 | PyMODINIT_FUNC 496 | PyInit__curses_panel(void) 497 | { 498 | PyObject *m, *d, *v; 499 | 500 | /* Create the module and add the functions */ 501 | m = PyModule_Create(&_curses_panelmodule); 502 | if (m == NULL) 503 | goto fail; 504 | d = PyModule_GetDict(m); 505 | 506 | /* Initialize object type */ 507 | v = PyType_FromSpec(&PyCursesPanel_Type_spec); 508 | if (v == NULL) 509 | goto fail; 510 | ((PyTypeObject *)v)->tp_new = NULL; 511 | _curses_panelstate(m)->PyCursesPanel_Type = v; 512 | 513 | import_curses(); 514 | if (PyErr_Occurred()) 515 | goto fail; 516 | 517 | /* For exception _curses_panel.error */ 518 | _curses_panelstate(m)->PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL); 519 | PyDict_SetItemString(d, "error", _curses_panelstate(m)->PyCursesError); 520 | 521 | /* Make the version available */ 522 | v = PyUnicode_FromString(PyCursesVersion); 523 | PyDict_SetItemString(d, "version", v); 524 | PyDict_SetItemString(d, "__version__", v); 525 | Py_DECREF(v); 526 | return m; 527 | fail: 528 | Py_XDECREF(m); 529 | return NULL; 530 | } 531 | -------------------------------------------------------------------------------- /py35/clinic/_cursesmodule.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | PyDoc_STRVAR(curses_window_addch__doc__, 6 | "addch([y, x,] ch, [attr])\n" 7 | "Paint character ch at (y, x) with attributes attr.\n" 8 | "\n" 9 | " y\n" 10 | " Y-coordinate.\n" 11 | " x\n" 12 | " X-coordinate.\n" 13 | " ch\n" 14 | " Character to add.\n" 15 | " attr\n" 16 | " Attributes for the character.\n" 17 | "\n" 18 | "Paint character ch at (y, x) with attributes attr,\n" 19 | "overwriting any character previously painted at that location.\n" 20 | "By default, the character position and attributes are the\n" 21 | "current settings for the window object."); 22 | 23 | #define CURSES_WINDOW_ADDCH_METHODDEF \ 24 | {"addch", (PyCFunction)curses_window_addch, METH_VARARGS, curses_window_addch__doc__}, 25 | 26 | static PyObject * 27 | curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, 28 | int x, PyObject *ch, int group_right_1, long attr); 29 | 30 | static PyObject * 31 | curses_window_addch(PyCursesWindowObject *self, PyObject *args) 32 | { 33 | PyObject *return_value = NULL; 34 | int group_left_1 = 0; 35 | int y = 0; 36 | int x = 0; 37 | PyObject *ch; 38 | int group_right_1 = 0; 39 | long attr = 0; 40 | 41 | switch (PyTuple_GET_SIZE(args)) { 42 | case 1: 43 | if (!PyArg_ParseTuple(args, "O:addch", &ch)) { 44 | goto exit; 45 | } 46 | break; 47 | case 2: 48 | if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) { 49 | goto exit; 50 | } 51 | group_right_1 = 1; 52 | break; 53 | case 3: 54 | if (!PyArg_ParseTuple(args, "iiO:addch", &y, &x, &ch)) { 55 | goto exit; 56 | } 57 | group_left_1 = 1; 58 | break; 59 | case 4: 60 | if (!PyArg_ParseTuple(args, "iiOl:addch", &y, &x, &ch, &attr)) { 61 | goto exit; 62 | } 63 | group_right_1 = 1; 64 | group_left_1 = 1; 65 | break; 66 | default: 67 | PyErr_SetString(PyExc_TypeError, "curses.window.addch requires 1 to 4 arguments"); 68 | goto exit; 69 | } 70 | return_value = curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); 71 | 72 | exit: 73 | return return_value; 74 | } 75 | /*[clinic end generated code: output=13ffc5f8d79cbfbf input=a9049054013a1b77]*/ 76 | -------------------------------------------------------------------------------- /py36/_curses_panel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Interface to the ncurses panel library 3 | * 4 | * Original version by Thomas Gellekum 5 | */ 6 | 7 | /* Release Number */ 8 | 9 | static const char PyCursesVersion[] = "2.1"; 10 | 11 | /* Includes */ 12 | 13 | #include "Python.h" 14 | 15 | #include "py_curses.h" 16 | 17 | #include 18 | 19 | typedef struct { 20 | PyObject *PyCursesError; 21 | PyObject *PyCursesPanel_Type; 22 | } _curses_panelstate; 23 | 24 | #define _curses_panelstate(o) ((_curses_panelstate *)PyModule_GetState(o)) 25 | 26 | static int 27 | _curses_panel_clear(PyObject *m) 28 | { 29 | Py_CLEAR(_curses_panelstate(m)->PyCursesError); 30 | return 0; 31 | } 32 | 33 | static int 34 | _curses_panel_traverse(PyObject *m, visitproc visit, void *arg) 35 | { 36 | Py_VISIT(_curses_panelstate(m)->PyCursesError); 37 | return 0; 38 | } 39 | 40 | static void 41 | _curses_panel_free(void *m) 42 | { 43 | _curses_panel_clear((PyObject *) m); 44 | } 45 | 46 | static struct PyModuleDef _curses_panelmodule; 47 | 48 | #define _curses_panelstate_global \ 49 | ((_curses_panelstate *) PyModule_GetState(PyState_FindModule(&_curses_panelmodule))) 50 | 51 | /* Utility Functions */ 52 | 53 | /* 54 | * Check the return code from a curses function and return None 55 | * or raise an exception as appropriate. 56 | */ 57 | 58 | static PyObject * 59 | PyCursesCheckERR(int code, const char *fname) 60 | { 61 | if (code != ERR) { 62 | Py_RETURN_NONE; 63 | } else { 64 | if (fname == NULL) { 65 | PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_ERR); 66 | } else { 67 | PyErr_Format(_curses_panelstate_global->PyCursesError, "%s() returned ERR", fname); 68 | } 69 | return NULL; 70 | } 71 | } 72 | 73 | /***************************************************************************** 74 | The Panel Object 75 | ******************************************************************************/ 76 | 77 | /* Definition of the panel object and panel type */ 78 | 79 | typedef struct { 80 | PyObject_HEAD 81 | PANEL *pan; 82 | PyCursesWindowObject *wo; /* for reference counts */ 83 | } PyCursesPanelObject; 84 | 85 | #define PyCursesPanel_Check(v) \ 86 | (Py_TYPE(v) == _curses_panelstate_global->PyCursesPanel_Type) 87 | 88 | /* Some helper functions. The problem is that there's always a window 89 | associated with a panel. To ensure that Python's GC doesn't pull 90 | this window from under our feet we need to keep track of references 91 | to the corresponding window object within Python. We can't use 92 | dupwin(oldwin) to keep a copy of the curses WINDOW because the 93 | contents of oldwin is copied only once; code like 94 | 95 | win = newwin(...) 96 | pan = win.panel() 97 | win.addstr(some_string) 98 | pan.window().addstr(other_string) 99 | 100 | will fail. */ 101 | 102 | /* We keep a linked list of PyCursesPanelObjects, lop. A list should 103 | suffice, I don't expect more than a handful or at most a few 104 | dozens of panel objects within a typical program. */ 105 | typedef struct _list_of_panels { 106 | PyCursesPanelObject *po; 107 | struct _list_of_panels *next; 108 | } list_of_panels; 109 | 110 | /* list anchor */ 111 | static list_of_panels *lop; 112 | 113 | /* Insert a new panel object into lop */ 114 | static int 115 | insert_lop(PyCursesPanelObject *po) 116 | { 117 | list_of_panels *new; 118 | 119 | if ((new = (list_of_panels *)PyMem_Malloc(sizeof(list_of_panels))) == NULL) { 120 | PyErr_NoMemory(); 121 | return -1; 122 | } 123 | new->po = po; 124 | new->next = lop; 125 | lop = new; 126 | return 0; 127 | } 128 | 129 | /* Remove the panel object from lop */ 130 | static void 131 | remove_lop(PyCursesPanelObject *po) 132 | { 133 | list_of_panels *temp, *n; 134 | 135 | temp = lop; 136 | if (temp->po == po) { 137 | lop = temp->next; 138 | PyMem_Free(temp); 139 | return; 140 | } 141 | while (temp->next == NULL || temp->next->po != po) { 142 | if (temp->next == NULL) { 143 | PyErr_SetString(PyExc_RuntimeError, 144 | "remove_lop: can't find Panel Object"); 145 | return; 146 | } 147 | temp = temp->next; 148 | } 149 | n = temp->next->next; 150 | PyMem_Free(temp->next); 151 | temp->next = n; 152 | return; 153 | } 154 | 155 | /* Return the panel object that corresponds to pan */ 156 | static PyCursesPanelObject * 157 | find_po(PANEL *pan) 158 | { 159 | list_of_panels *temp; 160 | for (temp = lop; temp->po->pan != pan; temp = temp->next) 161 | if (temp->next == NULL) return NULL; /* not found!? */ 162 | return temp->po; 163 | } 164 | 165 | /* Function Prototype Macros - They are ugly but very, very useful. ;-) 166 | 167 | X - function name 168 | TYPE - parameter Type 169 | ERGSTR - format string for construction of the return value 170 | PARSESTR - format string for argument parsing */ 171 | 172 | #define Panel_NoArgNoReturnFunction(X) \ 173 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ 174 | { return PyCursesCheckERR(X(self->pan), # X); } 175 | 176 | #define Panel_NoArgTrueFalseFunction(X) \ 177 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ 178 | { \ 179 | if (X (self->pan) == FALSE) { Py_RETURN_FALSE; } \ 180 | else { Py_RETURN_TRUE; } } 181 | 182 | #define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \ 183 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \ 184 | { \ 185 | TYPE arg1, arg2; \ 186 | if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \ 187 | return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); } 188 | 189 | /* ------------- PANEL routines --------------- */ 190 | 191 | Panel_NoArgNoReturnFunction(bottom_panel) 192 | Panel_NoArgNoReturnFunction(hide_panel) 193 | Panel_NoArgNoReturnFunction(show_panel) 194 | Panel_NoArgNoReturnFunction(top_panel) 195 | Panel_NoArgTrueFalseFunction(panel_hidden) 196 | Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x") 197 | 198 | /* Allocation and deallocation of Panel Objects */ 199 | 200 | static PyObject * 201 | PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo) 202 | { 203 | PyCursesPanelObject *po; 204 | 205 | po = PyObject_NEW(PyCursesPanelObject, 206 | (PyTypeObject *)(_curses_panelstate_global)->PyCursesPanel_Type); 207 | if (po == NULL) return NULL; 208 | po->pan = pan; 209 | if (insert_lop(po) < 0) { 210 | po->wo = NULL; 211 | Py_DECREF(po); 212 | return NULL; 213 | } 214 | po->wo = wo; 215 | Py_INCREF(wo); 216 | return (PyObject *)po; 217 | } 218 | 219 | static void 220 | PyCursesPanel_Dealloc(PyCursesPanelObject *po) 221 | { 222 | PyObject *obj = (PyObject *) panel_userptr(po->pan); 223 | if (obj) { 224 | (void)set_panel_userptr(po->pan, NULL); 225 | Py_DECREF(obj); 226 | } 227 | (void)del_panel(po->pan); 228 | if (po->wo != NULL) { 229 | Py_DECREF(po->wo); 230 | remove_lop(po); 231 | } 232 | PyObject_DEL(po); 233 | } 234 | 235 | /* panel_above(NULL) returns the bottom panel in the stack. To get 236 | this behaviour we use curses.panel.bottom_panel(). */ 237 | static PyObject * 238 | PyCursesPanel_above(PyCursesPanelObject *self) 239 | { 240 | PANEL *pan; 241 | PyCursesPanelObject *po; 242 | 243 | pan = panel_above(self->pan); 244 | 245 | if (pan == NULL) { /* valid output, it means the calling panel 246 | is on top of the stack */ 247 | Py_RETURN_NONE; 248 | } 249 | po = find_po(pan); 250 | if (po == NULL) { 251 | PyErr_SetString(PyExc_RuntimeError, 252 | "panel_above: can't find Panel Object"); 253 | return NULL; 254 | } 255 | Py_INCREF(po); 256 | return (PyObject *)po; 257 | } 258 | 259 | /* panel_below(NULL) returns the top panel in the stack. To get 260 | this behaviour we use curses.panel.top_panel(). */ 261 | static PyObject * 262 | PyCursesPanel_below(PyCursesPanelObject *self) 263 | { 264 | PANEL *pan; 265 | PyCursesPanelObject *po; 266 | 267 | pan = panel_below(self->pan); 268 | 269 | if (pan == NULL) { /* valid output, it means the calling panel 270 | is on the bottom of the stack */ 271 | Py_RETURN_NONE; 272 | } 273 | po = find_po(pan); 274 | if (po == NULL) { 275 | PyErr_SetString(PyExc_RuntimeError, 276 | "panel_below: can't find Panel Object"); 277 | return NULL; 278 | } 279 | Py_INCREF(po); 280 | return (PyObject *)po; 281 | } 282 | 283 | static PyObject * 284 | PyCursesPanel_window(PyCursesPanelObject *self) 285 | { 286 | Py_INCREF(self->wo); 287 | return (PyObject *)self->wo; 288 | } 289 | 290 | static PyObject * 291 | PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args) 292 | { 293 | PyCursesPanelObject *po; 294 | PyCursesWindowObject *temp; 295 | int rtn; 296 | 297 | if (PyTuple_Size(args) != 1) { 298 | PyErr_SetString(PyExc_TypeError, "replace requires one argument"); 299 | return NULL; 300 | } 301 | if (!PyArg_ParseTuple(args, "O!;window object", 302 | &PyCursesWindow_Type, &temp)) 303 | return NULL; 304 | 305 | po = find_po(self->pan); 306 | if (po == NULL) { 307 | PyErr_SetString(PyExc_RuntimeError, 308 | "replace_panel: can't find Panel Object"); 309 | return NULL; 310 | } 311 | 312 | rtn = replace_panel(self->pan, temp->win); 313 | if (rtn == ERR) { 314 | PyErr_SetString(_curses_panelstate_global->PyCursesError, "replace_panel() returned ERR"); 315 | return NULL; 316 | } 317 | Py_INCREF(temp); 318 | Py_SETREF(po->wo, temp); 319 | Py_RETURN_NONE; 320 | } 321 | 322 | static PyObject * 323 | PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) 324 | { 325 | PyObject *oldobj; 326 | int rc; 327 | PyCursesInitialised; 328 | Py_INCREF(obj); 329 | oldobj = (PyObject *) panel_userptr(self->pan); 330 | rc = set_panel_userptr(self->pan, (void*)obj); 331 | if (rc == ERR) { 332 | /* In case of an ncurses error, decref the new object again */ 333 | Py_DECREF(obj); 334 | } 335 | Py_XDECREF(oldobj); 336 | return PyCursesCheckERR(rc, "set_panel_userptr"); 337 | } 338 | 339 | static PyObject * 340 | PyCursesPanel_userptr(PyCursesPanelObject *self) 341 | { 342 | PyObject *obj; 343 | PyCursesInitialised; 344 | obj = (PyObject *) panel_userptr(self->pan); 345 | if (obj == NULL) { 346 | PyErr_SetString(_curses_panelstate_global->PyCursesError, "no userptr set"); 347 | return NULL; 348 | } 349 | 350 | Py_INCREF(obj); 351 | return obj; 352 | } 353 | 354 | 355 | /* Module interface */ 356 | 357 | static PyMethodDef PyCursesPanel_Methods[] = { 358 | {"above", (PyCFunction)PyCursesPanel_above, METH_NOARGS}, 359 | {"below", (PyCFunction)PyCursesPanel_below, METH_NOARGS}, 360 | {"bottom", (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS}, 361 | {"hidden", (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS}, 362 | {"hide", (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS}, 363 | {"move", (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS}, 364 | {"replace", (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS}, 365 | {"set_userptr", (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O}, 366 | {"show", (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS}, 367 | {"top", (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS}, 368 | {"userptr", (PyCFunction)PyCursesPanel_userptr, METH_NOARGS}, 369 | {"window", (PyCFunction)PyCursesPanel_window, METH_NOARGS}, 370 | {NULL, NULL} /* sentinel */ 371 | }; 372 | 373 | /* -------------------------------------------------------*/ 374 | 375 | static PyType_Slot PyCursesPanel_Type_slots[] = { 376 | {Py_tp_dealloc, PyCursesPanel_Dealloc}, 377 | {Py_tp_methods, PyCursesPanel_Methods}, 378 | {0, 0}, 379 | }; 380 | 381 | static PyType_Spec PyCursesPanel_Type_spec = { 382 | "_curses_panel.curses panel", 383 | sizeof(PyCursesPanelObject), 384 | 0, 385 | Py_TPFLAGS_DEFAULT, 386 | PyCursesPanel_Type_slots 387 | }; 388 | 389 | /* Wrapper for panel_above(NULL). This function returns the bottom 390 | panel of the stack, so it's renamed to bottom_panel(). 391 | panel.above() *requires* a panel object in the first place which 392 | may be undesirable. */ 393 | static PyObject * 394 | PyCurses_bottom_panel(PyObject *self) 395 | { 396 | PANEL *pan; 397 | PyCursesPanelObject *po; 398 | 399 | PyCursesInitialised; 400 | 401 | pan = panel_above(NULL); 402 | 403 | if (pan == NULL) { /* valid output, it means 404 | there's no panel at all */ 405 | Py_RETURN_NONE; 406 | } 407 | po = find_po(pan); 408 | if (po == NULL) { 409 | PyErr_SetString(PyExc_RuntimeError, 410 | "panel_above: can't find Panel Object"); 411 | return NULL; 412 | } 413 | Py_INCREF(po); 414 | return (PyObject *)po; 415 | } 416 | 417 | static PyObject * 418 | PyCurses_new_panel(PyObject *self, PyObject *args) 419 | { 420 | PyCursesWindowObject *win; 421 | PANEL *pan; 422 | 423 | if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win)) 424 | return NULL; 425 | pan = new_panel(win->win); 426 | if (pan == NULL) { 427 | PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_NULL); 428 | return NULL; 429 | } 430 | return (PyObject *)PyCursesPanel_New(pan, win); 431 | } 432 | 433 | 434 | /* Wrapper for panel_below(NULL). This function returns the top panel 435 | of the stack, so it's renamed to top_panel(). panel.below() 436 | *requires* a panel object in the first place which may be 437 | undesirable. */ 438 | static PyObject * 439 | PyCurses_top_panel(PyObject *self) 440 | { 441 | PANEL *pan; 442 | PyCursesPanelObject *po; 443 | 444 | PyCursesInitialised; 445 | 446 | pan = panel_below(NULL); 447 | 448 | if (pan == NULL) { /* valid output, it means 449 | there's no panel at all */ 450 | Py_RETURN_NONE; 451 | } 452 | po = find_po(pan); 453 | if (po == NULL) { 454 | PyErr_SetString(PyExc_RuntimeError, 455 | "panel_below: can't find Panel Object"); 456 | return NULL; 457 | } 458 | Py_INCREF(po); 459 | return (PyObject *)po; 460 | } 461 | 462 | static PyObject *PyCurses_update_panels(PyObject *self) 463 | { 464 | PyCursesInitialised; 465 | update_panels(); 466 | Py_RETURN_NONE; 467 | } 468 | 469 | 470 | /* List of functions defined in the module */ 471 | 472 | static PyMethodDef PyCurses_methods[] = { 473 | {"bottom_panel", (PyCFunction)PyCurses_bottom_panel, METH_NOARGS}, 474 | {"new_panel", (PyCFunction)PyCurses_new_panel, METH_VARARGS}, 475 | {"top_panel", (PyCFunction)PyCurses_top_panel, METH_NOARGS}, 476 | {"update_panels", (PyCFunction)PyCurses_update_panels, METH_NOARGS}, 477 | {NULL, NULL} /* sentinel */ 478 | }; 479 | 480 | /* Initialization function for the module */ 481 | 482 | 483 | static struct PyModuleDef _curses_panelmodule = { 484 | PyModuleDef_HEAD_INIT, 485 | "_curses_panel", 486 | NULL, 487 | sizeof(_curses_panelstate), 488 | PyCurses_methods, 489 | NULL, 490 | _curses_panel_traverse, 491 | _curses_panel_clear, 492 | _curses_panel_free 493 | }; 494 | 495 | PyMODINIT_FUNC 496 | PyInit__curses_panel(void) 497 | { 498 | PyObject *m, *d, *v; 499 | 500 | /* Create the module and add the functions */ 501 | m = PyModule_Create(&_curses_panelmodule); 502 | if (m == NULL) 503 | goto fail; 504 | d = PyModule_GetDict(m); 505 | 506 | /* Initialize object type */ 507 | v = PyType_FromSpec(&PyCursesPanel_Type_spec); 508 | if (v == NULL) 509 | goto fail; 510 | ((PyTypeObject *)v)->tp_new = NULL; 511 | _curses_panelstate(m)->PyCursesPanel_Type = v; 512 | 513 | import_curses(); 514 | if (PyErr_Occurred()) 515 | goto fail; 516 | 517 | /* For exception _curses_panel.error */ 518 | _curses_panelstate(m)->PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL); 519 | PyDict_SetItemString(d, "error", _curses_panelstate(m)->PyCursesError); 520 | 521 | /* Make the version available */ 522 | v = PyUnicode_FromString(PyCursesVersion); 523 | PyDict_SetItemString(d, "version", v); 524 | PyDict_SetItemString(d, "__version__", v); 525 | Py_DECREF(v); 526 | return m; 527 | fail: 528 | Py_XDECREF(m); 529 | return NULL; 530 | } 531 | -------------------------------------------------------------------------------- /py36/clinic/_cursesmodule.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | PyDoc_STRVAR(curses_window_addch__doc__, 6 | "addch([y, x,] ch, [attr])\n" 7 | "Paint character ch at (y, x) with attributes attr.\n" 8 | "\n" 9 | " y\n" 10 | " Y-coordinate.\n" 11 | " x\n" 12 | " X-coordinate.\n" 13 | " ch\n" 14 | " Character to add.\n" 15 | " attr\n" 16 | " Attributes for the character.\n" 17 | "\n" 18 | "Paint character ch at (y, x) with attributes attr,\n" 19 | "overwriting any character previously painted at that location.\n" 20 | "By default, the character position and attributes are the\n" 21 | "current settings for the window object."); 22 | 23 | #define CURSES_WINDOW_ADDCH_METHODDEF \ 24 | {"addch", (PyCFunction)curses_window_addch, METH_VARARGS, curses_window_addch__doc__}, 25 | 26 | static PyObject * 27 | curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, 28 | int x, PyObject *ch, int group_right_1, long attr); 29 | 30 | static PyObject * 31 | curses_window_addch(PyCursesWindowObject *self, PyObject *args) 32 | { 33 | PyObject *return_value = NULL; 34 | int group_left_1 = 0; 35 | int y = 0; 36 | int x = 0; 37 | PyObject *ch; 38 | int group_right_1 = 0; 39 | long attr = 0; 40 | 41 | switch (PyTuple_GET_SIZE(args)) { 42 | case 1: 43 | if (!PyArg_ParseTuple(args, "O:addch", &ch)) { 44 | goto exit; 45 | } 46 | break; 47 | case 2: 48 | if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) { 49 | goto exit; 50 | } 51 | group_right_1 = 1; 52 | break; 53 | case 3: 54 | if (!PyArg_ParseTuple(args, "iiO:addch", &y, &x, &ch)) { 55 | goto exit; 56 | } 57 | group_left_1 = 1; 58 | break; 59 | case 4: 60 | if (!PyArg_ParseTuple(args, "iiOl:addch", &y, &x, &ch, &attr)) { 61 | goto exit; 62 | } 63 | group_right_1 = 1; 64 | group_left_1 = 1; 65 | break; 66 | default: 67 | PyErr_SetString(PyExc_TypeError, "curses.window.addch requires 1 to 4 arguments"); 68 | goto exit; 69 | } 70 | return_value = curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); 71 | 72 | exit: 73 | return return_value; 74 | } 75 | /*[clinic end generated code: output=13ffc5f8d79cbfbf input=a9049054013a1b77]*/ 76 | -------------------------------------------------------------------------------- /py37/_curses_panel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Interface to the ncurses panel library 3 | * 4 | * Original version by Thomas Gellekum 5 | */ 6 | 7 | /* Release Number */ 8 | 9 | static const char PyCursesVersion[] = "2.1"; 10 | 11 | /* Includes */ 12 | 13 | #include "Python.h" 14 | 15 | #include "py_curses.h" 16 | 17 | #include 18 | 19 | typedef struct { 20 | PyObject *PyCursesError; 21 | PyObject *PyCursesPanel_Type; 22 | } _curses_panelstate; 23 | 24 | #define _curses_panelstate(o) ((_curses_panelstate *)PyModule_GetState(o)) 25 | 26 | static int 27 | _curses_panel_clear(PyObject *m) 28 | { 29 | Py_CLEAR(_curses_panelstate(m)->PyCursesError); 30 | return 0; 31 | } 32 | 33 | static int 34 | _curses_panel_traverse(PyObject *m, visitproc visit, void *arg) 35 | { 36 | Py_VISIT(_curses_panelstate(m)->PyCursesError); 37 | return 0; 38 | } 39 | 40 | static void 41 | _curses_panel_free(void *m) 42 | { 43 | _curses_panel_clear((PyObject *) m); 44 | } 45 | 46 | static struct PyModuleDef _curses_panelmodule; 47 | 48 | #define _curses_panelstate_global \ 49 | ((_curses_panelstate *) PyModule_GetState(PyState_FindModule(&_curses_panelmodule))) 50 | 51 | /* Utility Functions */ 52 | 53 | /* 54 | * Check the return code from a curses function and return None 55 | * or raise an exception as appropriate. 56 | */ 57 | 58 | static PyObject * 59 | PyCursesCheckERR(int code, const char *fname) 60 | { 61 | if (code != ERR) { 62 | Py_RETURN_NONE; 63 | } else { 64 | if (fname == NULL) { 65 | PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_ERR); 66 | } else { 67 | PyErr_Format(_curses_panelstate_global->PyCursesError, "%s() returned ERR", fname); 68 | } 69 | return NULL; 70 | } 71 | } 72 | 73 | /***************************************************************************** 74 | The Panel Object 75 | ******************************************************************************/ 76 | 77 | /* Definition of the panel object and panel type */ 78 | 79 | typedef struct { 80 | PyObject_HEAD 81 | PANEL *pan; 82 | PyCursesWindowObject *wo; /* for reference counts */ 83 | } PyCursesPanelObject; 84 | 85 | #define PyCursesPanel_Check(v) \ 86 | (Py_TYPE(v) == _curses_panelstate_global->PyCursesPanel_Type) 87 | 88 | /* Some helper functions. The problem is that there's always a window 89 | associated with a panel. To ensure that Python's GC doesn't pull 90 | this window from under our feet we need to keep track of references 91 | to the corresponding window object within Python. We can't use 92 | dupwin(oldwin) to keep a copy of the curses WINDOW because the 93 | contents of oldwin is copied only once; code like 94 | 95 | win = newwin(...) 96 | pan = win.panel() 97 | win.addstr(some_string) 98 | pan.window().addstr(other_string) 99 | 100 | will fail. */ 101 | 102 | /* We keep a linked list of PyCursesPanelObjects, lop. A list should 103 | suffice, I don't expect more than a handful or at most a few 104 | dozens of panel objects within a typical program. */ 105 | typedef struct _list_of_panels { 106 | PyCursesPanelObject *po; 107 | struct _list_of_panels *next; 108 | } list_of_panels; 109 | 110 | /* list anchor */ 111 | static list_of_panels *lop; 112 | 113 | /* Insert a new panel object into lop */ 114 | static int 115 | insert_lop(PyCursesPanelObject *po) 116 | { 117 | list_of_panels *new; 118 | 119 | if ((new = (list_of_panels *)PyMem_Malloc(sizeof(list_of_panels))) == NULL) { 120 | PyErr_NoMemory(); 121 | return -1; 122 | } 123 | new->po = po; 124 | new->next = lop; 125 | lop = new; 126 | return 0; 127 | } 128 | 129 | /* Remove the panel object from lop */ 130 | static void 131 | remove_lop(PyCursesPanelObject *po) 132 | { 133 | list_of_panels *temp, *n; 134 | 135 | temp = lop; 136 | if (temp->po == po) { 137 | lop = temp->next; 138 | PyMem_Free(temp); 139 | return; 140 | } 141 | while (temp->next == NULL || temp->next->po != po) { 142 | if (temp->next == NULL) { 143 | PyErr_SetString(PyExc_RuntimeError, 144 | "remove_lop: can't find Panel Object"); 145 | return; 146 | } 147 | temp = temp->next; 148 | } 149 | n = temp->next->next; 150 | PyMem_Free(temp->next); 151 | temp->next = n; 152 | return; 153 | } 154 | 155 | /* Return the panel object that corresponds to pan */ 156 | static PyCursesPanelObject * 157 | find_po(PANEL *pan) 158 | { 159 | list_of_panels *temp; 160 | for (temp = lop; temp->po->pan != pan; temp = temp->next) 161 | if (temp->next == NULL) return NULL; /* not found!? */ 162 | return temp->po; 163 | } 164 | 165 | /* Function Prototype Macros - They are ugly but very, very useful. ;-) 166 | 167 | X - function name 168 | TYPE - parameter Type 169 | ERGSTR - format string for construction of the return value 170 | PARSESTR - format string for argument parsing */ 171 | 172 | #define Panel_NoArgNoReturnFunction(X) \ 173 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ 174 | { return PyCursesCheckERR(X(self->pan), # X); } 175 | 176 | #define Panel_NoArgTrueFalseFunction(X) \ 177 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self) \ 178 | { \ 179 | if (X (self->pan) == FALSE) { Py_RETURN_FALSE; } \ 180 | else { Py_RETURN_TRUE; } } 181 | 182 | #define Panel_TwoArgNoReturnFunction(X, TYPE, PARSESTR) \ 183 | static PyObject *PyCursesPanel_##X(PyCursesPanelObject *self, PyObject *args) \ 184 | { \ 185 | TYPE arg1, arg2; \ 186 | if (!PyArg_ParseTuple(args, PARSESTR, &arg1, &arg2)) return NULL; \ 187 | return PyCursesCheckERR(X(self->pan, arg1, arg2), # X); } 188 | 189 | /* ------------- PANEL routines --------------- */ 190 | 191 | Panel_NoArgNoReturnFunction(bottom_panel) 192 | Panel_NoArgNoReturnFunction(hide_panel) 193 | Panel_NoArgNoReturnFunction(show_panel) 194 | Panel_NoArgNoReturnFunction(top_panel) 195 | Panel_NoArgTrueFalseFunction(panel_hidden) 196 | Panel_TwoArgNoReturnFunction(move_panel, int, "ii;y,x") 197 | 198 | /* Allocation and deallocation of Panel Objects */ 199 | 200 | static PyObject * 201 | PyCursesPanel_New(PANEL *pan, PyCursesWindowObject *wo) 202 | { 203 | PyCursesPanelObject *po; 204 | 205 | po = PyObject_NEW(PyCursesPanelObject, 206 | (PyTypeObject *)(_curses_panelstate_global)->PyCursesPanel_Type); 207 | if (po == NULL) return NULL; 208 | po->pan = pan; 209 | if (insert_lop(po) < 0) { 210 | po->wo = NULL; 211 | Py_DECREF(po); 212 | return NULL; 213 | } 214 | po->wo = wo; 215 | Py_INCREF(wo); 216 | return (PyObject *)po; 217 | } 218 | 219 | static void 220 | PyCursesPanel_Dealloc(PyCursesPanelObject *po) 221 | { 222 | PyObject *obj = (PyObject *) panel_userptr(po->pan); 223 | if (obj) { 224 | (void)set_panel_userptr(po->pan, NULL); 225 | Py_DECREF(obj); 226 | } 227 | (void)del_panel(po->pan); 228 | if (po->wo != NULL) { 229 | Py_DECREF(po->wo); 230 | remove_lop(po); 231 | } 232 | PyObject_DEL(po); 233 | } 234 | 235 | /* panel_above(NULL) returns the bottom panel in the stack. To get 236 | this behaviour we use curses.panel.bottom_panel(). */ 237 | static PyObject * 238 | PyCursesPanel_above(PyCursesPanelObject *self) 239 | { 240 | PANEL *pan; 241 | PyCursesPanelObject *po; 242 | 243 | pan = panel_above(self->pan); 244 | 245 | if (pan == NULL) { /* valid output, it means the calling panel 246 | is on top of the stack */ 247 | Py_RETURN_NONE; 248 | } 249 | po = find_po(pan); 250 | if (po == NULL) { 251 | PyErr_SetString(PyExc_RuntimeError, 252 | "panel_above: can't find Panel Object"); 253 | return NULL; 254 | } 255 | Py_INCREF(po); 256 | return (PyObject *)po; 257 | } 258 | 259 | /* panel_below(NULL) returns the top panel in the stack. To get 260 | this behaviour we use curses.panel.top_panel(). */ 261 | static PyObject * 262 | PyCursesPanel_below(PyCursesPanelObject *self) 263 | { 264 | PANEL *pan; 265 | PyCursesPanelObject *po; 266 | 267 | pan = panel_below(self->pan); 268 | 269 | if (pan == NULL) { /* valid output, it means the calling panel 270 | is on the bottom of the stack */ 271 | Py_RETURN_NONE; 272 | } 273 | po = find_po(pan); 274 | if (po == NULL) { 275 | PyErr_SetString(PyExc_RuntimeError, 276 | "panel_below: can't find Panel Object"); 277 | return NULL; 278 | } 279 | Py_INCREF(po); 280 | return (PyObject *)po; 281 | } 282 | 283 | static PyObject * 284 | PyCursesPanel_window(PyCursesPanelObject *self) 285 | { 286 | Py_INCREF(self->wo); 287 | return (PyObject *)self->wo; 288 | } 289 | 290 | static PyObject * 291 | PyCursesPanel_replace_panel(PyCursesPanelObject *self, PyObject *args) 292 | { 293 | PyCursesPanelObject *po; 294 | PyCursesWindowObject *temp; 295 | int rtn; 296 | 297 | if (PyTuple_Size(args) != 1) { 298 | PyErr_SetString(PyExc_TypeError, "replace requires one argument"); 299 | return NULL; 300 | } 301 | if (!PyArg_ParseTuple(args, "O!;window object", 302 | &PyCursesWindow_Type, &temp)) 303 | return NULL; 304 | 305 | po = find_po(self->pan); 306 | if (po == NULL) { 307 | PyErr_SetString(PyExc_RuntimeError, 308 | "replace_panel: can't find Panel Object"); 309 | return NULL; 310 | } 311 | 312 | rtn = replace_panel(self->pan, temp->win); 313 | if (rtn == ERR) { 314 | PyErr_SetString(_curses_panelstate_global->PyCursesError, "replace_panel() returned ERR"); 315 | return NULL; 316 | } 317 | Py_INCREF(temp); 318 | Py_SETREF(po->wo, temp); 319 | Py_RETURN_NONE; 320 | } 321 | 322 | static PyObject * 323 | PyCursesPanel_set_panel_userptr(PyCursesPanelObject *self, PyObject *obj) 324 | { 325 | PyObject *oldobj; 326 | int rc; 327 | PyCursesInitialised; 328 | Py_INCREF(obj); 329 | oldobj = (PyObject *) panel_userptr(self->pan); 330 | rc = set_panel_userptr(self->pan, (void*)obj); 331 | if (rc == ERR) { 332 | /* In case of an ncurses error, decref the new object again */ 333 | Py_DECREF(obj); 334 | } 335 | Py_XDECREF(oldobj); 336 | return PyCursesCheckERR(rc, "set_panel_userptr"); 337 | } 338 | 339 | static PyObject * 340 | PyCursesPanel_userptr(PyCursesPanelObject *self) 341 | { 342 | PyObject *obj; 343 | PyCursesInitialised; 344 | obj = (PyObject *) panel_userptr(self->pan); 345 | if (obj == NULL) { 346 | PyErr_SetString(_curses_panelstate_global->PyCursesError, "no userptr set"); 347 | return NULL; 348 | } 349 | 350 | Py_INCREF(obj); 351 | return obj; 352 | } 353 | 354 | 355 | /* Module interface */ 356 | 357 | static PyMethodDef PyCursesPanel_Methods[] = { 358 | {"above", (PyCFunction)PyCursesPanel_above, METH_NOARGS}, 359 | {"below", (PyCFunction)PyCursesPanel_below, METH_NOARGS}, 360 | {"bottom", (PyCFunction)PyCursesPanel_bottom_panel, METH_NOARGS}, 361 | {"hidden", (PyCFunction)PyCursesPanel_panel_hidden, METH_NOARGS}, 362 | {"hide", (PyCFunction)PyCursesPanel_hide_panel, METH_NOARGS}, 363 | {"move", (PyCFunction)PyCursesPanel_move_panel, METH_VARARGS}, 364 | {"replace", (PyCFunction)PyCursesPanel_replace_panel, METH_VARARGS}, 365 | {"set_userptr", (PyCFunction)PyCursesPanel_set_panel_userptr, METH_O}, 366 | {"show", (PyCFunction)PyCursesPanel_show_panel, METH_NOARGS}, 367 | {"top", (PyCFunction)PyCursesPanel_top_panel, METH_NOARGS}, 368 | {"userptr", (PyCFunction)PyCursesPanel_userptr, METH_NOARGS}, 369 | {"window", (PyCFunction)PyCursesPanel_window, METH_NOARGS}, 370 | {NULL, NULL} /* sentinel */ 371 | }; 372 | 373 | /* -------------------------------------------------------*/ 374 | 375 | static PyType_Slot PyCursesPanel_Type_slots[] = { 376 | {Py_tp_dealloc, PyCursesPanel_Dealloc}, 377 | {Py_tp_methods, PyCursesPanel_Methods}, 378 | {0, 0}, 379 | }; 380 | 381 | static PyType_Spec PyCursesPanel_Type_spec = { 382 | "_curses_panel.curses panel", 383 | sizeof(PyCursesPanelObject), 384 | 0, 385 | Py_TPFLAGS_DEFAULT, 386 | PyCursesPanel_Type_slots 387 | }; 388 | 389 | /* Wrapper for panel_above(NULL). This function returns the bottom 390 | panel of the stack, so it's renamed to bottom_panel(). 391 | panel.above() *requires* a panel object in the first place which 392 | may be undesirable. */ 393 | static PyObject * 394 | PyCurses_bottom_panel(PyObject *self) 395 | { 396 | PANEL *pan; 397 | PyCursesPanelObject *po; 398 | 399 | PyCursesInitialised; 400 | 401 | pan = panel_above(NULL); 402 | 403 | if (pan == NULL) { /* valid output, it means 404 | there's no panel at all */ 405 | Py_RETURN_NONE; 406 | } 407 | po = find_po(pan); 408 | if (po == NULL) { 409 | PyErr_SetString(PyExc_RuntimeError, 410 | "panel_above: can't find Panel Object"); 411 | return NULL; 412 | } 413 | Py_INCREF(po); 414 | return (PyObject *)po; 415 | } 416 | 417 | static PyObject * 418 | PyCurses_new_panel(PyObject *self, PyObject *args) 419 | { 420 | PyCursesWindowObject *win; 421 | PANEL *pan; 422 | 423 | if (!PyArg_ParseTuple(args, "O!", &PyCursesWindow_Type, &win)) 424 | return NULL; 425 | pan = new_panel(win->win); 426 | if (pan == NULL) { 427 | PyErr_SetString(_curses_panelstate_global->PyCursesError, catchall_NULL); 428 | return NULL; 429 | } 430 | return (PyObject *)PyCursesPanel_New(pan, win); 431 | } 432 | 433 | 434 | /* Wrapper for panel_below(NULL). This function returns the top panel 435 | of the stack, so it's renamed to top_panel(). panel.below() 436 | *requires* a panel object in the first place which may be 437 | undesirable. */ 438 | static PyObject * 439 | PyCurses_top_panel(PyObject *self) 440 | { 441 | PANEL *pan; 442 | PyCursesPanelObject *po; 443 | 444 | PyCursesInitialised; 445 | 446 | pan = panel_below(NULL); 447 | 448 | if (pan == NULL) { /* valid output, it means 449 | there's no panel at all */ 450 | Py_RETURN_NONE; 451 | } 452 | po = find_po(pan); 453 | if (po == NULL) { 454 | PyErr_SetString(PyExc_RuntimeError, 455 | "panel_below: can't find Panel Object"); 456 | return NULL; 457 | } 458 | Py_INCREF(po); 459 | return (PyObject *)po; 460 | } 461 | 462 | static PyObject *PyCurses_update_panels(PyObject *self) 463 | { 464 | PyCursesInitialised; 465 | update_panels(); 466 | Py_RETURN_NONE; 467 | } 468 | 469 | 470 | /* List of functions defined in the module */ 471 | 472 | static PyMethodDef PyCurses_methods[] = { 473 | {"bottom_panel", (PyCFunction)PyCurses_bottom_panel, METH_NOARGS}, 474 | {"new_panel", (PyCFunction)PyCurses_new_panel, METH_VARARGS}, 475 | {"top_panel", (PyCFunction)PyCurses_top_panel, METH_NOARGS}, 476 | {"update_panels", (PyCFunction)PyCurses_update_panels, METH_NOARGS}, 477 | {NULL, NULL} /* sentinel */ 478 | }; 479 | 480 | /* Initialization function for the module */ 481 | 482 | 483 | static struct PyModuleDef _curses_panelmodule = { 484 | PyModuleDef_HEAD_INIT, 485 | "_curses_panel", 486 | NULL, 487 | sizeof(_curses_panelstate), 488 | PyCurses_methods, 489 | NULL, 490 | _curses_panel_traverse, 491 | _curses_panel_clear, 492 | _curses_panel_free 493 | }; 494 | 495 | PyMODINIT_FUNC 496 | PyInit__curses_panel(void) 497 | { 498 | PyObject *m, *d, *v; 499 | 500 | /* Create the module and add the functions */ 501 | m = PyModule_Create(&_curses_panelmodule); 502 | if (m == NULL) 503 | goto fail; 504 | d = PyModule_GetDict(m); 505 | 506 | /* Initialize object type */ 507 | v = PyType_FromSpec(&PyCursesPanel_Type_spec); 508 | if (v == NULL) 509 | goto fail; 510 | ((PyTypeObject *)v)->tp_new = NULL; 511 | _curses_panelstate(m)->PyCursesPanel_Type = v; 512 | 513 | import_curses(); 514 | if (PyErr_Occurred()) 515 | goto fail; 516 | 517 | /* For exception _curses_panel.error */ 518 | _curses_panelstate(m)->PyCursesError = PyErr_NewException("_curses_panel.error", NULL, NULL); 519 | PyDict_SetItemString(d, "error", _curses_panelstate(m)->PyCursesError); 520 | 521 | /* Make the version available */ 522 | v = PyUnicode_FromString(PyCursesVersion); 523 | PyDict_SetItemString(d, "version", v); 524 | PyDict_SetItemString(d, "__version__", v); 525 | Py_DECREF(v); 526 | return m; 527 | fail: 528 | Py_XDECREF(m); 529 | return NULL; 530 | } 531 | -------------------------------------------------------------------------------- /py37/clinic/_cursesmodule.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | PyDoc_STRVAR(curses_window_addch__doc__, 6 | "addch([y, x,] ch, [attr])\n" 7 | "Paint character ch at (y, x) with attributes attr.\n" 8 | "\n" 9 | " y\n" 10 | " Y-coordinate.\n" 11 | " x\n" 12 | " X-coordinate.\n" 13 | " ch\n" 14 | " Character to add.\n" 15 | " attr\n" 16 | " Attributes for the character.\n" 17 | "\n" 18 | "Paint character ch at (y, x) with attributes attr,\n" 19 | "overwriting any character previously painted at that location.\n" 20 | "By default, the character position and attributes are the\n" 21 | "current settings for the window object."); 22 | 23 | #define CURSES_WINDOW_ADDCH_METHODDEF \ 24 | {"addch", (PyCFunction)curses_window_addch, METH_VARARGS, curses_window_addch__doc__}, 25 | 26 | static PyObject * 27 | curses_window_addch_impl(PyCursesWindowObject *self, int group_left_1, int y, 28 | int x, PyObject *ch, int group_right_1, long attr); 29 | 30 | static PyObject * 31 | curses_window_addch(PyCursesWindowObject *self, PyObject *args) 32 | { 33 | PyObject *return_value = NULL; 34 | int group_left_1 = 0; 35 | int y = 0; 36 | int x = 0; 37 | PyObject *ch; 38 | int group_right_1 = 0; 39 | long attr = 0; 40 | 41 | switch (PyTuple_GET_SIZE(args)) { 42 | case 1: 43 | if (!PyArg_ParseTuple(args, "O:addch", &ch)) { 44 | goto exit; 45 | } 46 | break; 47 | case 2: 48 | if (!PyArg_ParseTuple(args, "Ol:addch", &ch, &attr)) { 49 | goto exit; 50 | } 51 | group_right_1 = 1; 52 | break; 53 | case 3: 54 | if (!PyArg_ParseTuple(args, "iiO:addch", &y, &x, &ch)) { 55 | goto exit; 56 | } 57 | group_left_1 = 1; 58 | break; 59 | case 4: 60 | if (!PyArg_ParseTuple(args, "iiOl:addch", &y, &x, &ch, &attr)) { 61 | goto exit; 62 | } 63 | group_right_1 = 1; 64 | group_left_1 = 1; 65 | break; 66 | default: 67 | PyErr_SetString(PyExc_TypeError, "curses.window.addch requires 1 to 4 arguments"); 68 | goto exit; 69 | } 70 | return_value = curses_window_addch_impl(self, group_left_1, y, x, ch, group_right_1, attr); 71 | 72 | exit: 73 | return return_value; 74 | } 75 | /*[clinic end generated code: output=13ffc5f8d79cbfbf input=a9049054013a1b77]*/ 76 | -------------------------------------------------------------------------------- /py38/clinic/_curses_panel.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, 6 | "bottom($self, /)\n" 7 | "--\n" 8 | "\n" 9 | "Push the panel to the bottom of the stack."); 10 | 11 | #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ 12 | {"bottom", (PyCFunction)_curses_panel_panel_bottom, METH_NOARGS, _curses_panel_panel_bottom__doc__}, 13 | 14 | static PyObject * 15 | _curses_panel_panel_bottom_impl(PyCursesPanelObject *self); 16 | 17 | static PyObject * 18 | _curses_panel_panel_bottom(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 19 | { 20 | return _curses_panel_panel_bottom_impl(self); 21 | } 22 | 23 | PyDoc_STRVAR(_curses_panel_panel_hide__doc__, 24 | "hide($self, /)\n" 25 | "--\n" 26 | "\n" 27 | "Hide the panel.\n" 28 | "\n" 29 | "This does not delete the object, it just makes the window on screen invisible."); 30 | 31 | #define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ 32 | {"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, _curses_panel_panel_hide__doc__}, 33 | 34 | static PyObject * 35 | _curses_panel_panel_hide_impl(PyCursesPanelObject *self); 36 | 37 | static PyObject * 38 | _curses_panel_panel_hide(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 39 | { 40 | return _curses_panel_panel_hide_impl(self); 41 | } 42 | 43 | PyDoc_STRVAR(_curses_panel_panel_show__doc__, 44 | "show($self, /)\n" 45 | "--\n" 46 | "\n" 47 | "Display the panel (which might have been hidden)."); 48 | 49 | #define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ 50 | {"show", (PyCFunction)_curses_panel_panel_show, METH_NOARGS, _curses_panel_panel_show__doc__}, 51 | 52 | static PyObject * 53 | _curses_panel_panel_show_impl(PyCursesPanelObject *self); 54 | 55 | static PyObject * 56 | _curses_panel_panel_show(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 57 | { 58 | return _curses_panel_panel_show_impl(self); 59 | } 60 | 61 | PyDoc_STRVAR(_curses_panel_panel_top__doc__, 62 | "top($self, /)\n" 63 | "--\n" 64 | "\n" 65 | "Push panel to the top of the stack."); 66 | 67 | #define _CURSES_PANEL_PANEL_TOP_METHODDEF \ 68 | {"top", (PyCFunction)_curses_panel_panel_top, METH_NOARGS, _curses_panel_panel_top__doc__}, 69 | 70 | static PyObject * 71 | _curses_panel_panel_top_impl(PyCursesPanelObject *self); 72 | 73 | static PyObject * 74 | _curses_panel_panel_top(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 75 | { 76 | return _curses_panel_panel_top_impl(self); 77 | } 78 | 79 | PyDoc_STRVAR(_curses_panel_panel_above__doc__, 80 | "above($self, /)\n" 81 | "--\n" 82 | "\n" 83 | "Return the panel above the current panel."); 84 | 85 | #define _CURSES_PANEL_PANEL_ABOVE_METHODDEF \ 86 | {"above", (PyCFunction)_curses_panel_panel_above, METH_NOARGS, _curses_panel_panel_above__doc__}, 87 | 88 | static PyObject * 89 | _curses_panel_panel_above_impl(PyCursesPanelObject *self); 90 | 91 | static PyObject * 92 | _curses_panel_panel_above(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 93 | { 94 | return _curses_panel_panel_above_impl(self); 95 | } 96 | 97 | PyDoc_STRVAR(_curses_panel_panel_below__doc__, 98 | "below($self, /)\n" 99 | "--\n" 100 | "\n" 101 | "Return the panel below the current panel."); 102 | 103 | #define _CURSES_PANEL_PANEL_BELOW_METHODDEF \ 104 | {"below", (PyCFunction)_curses_panel_panel_below, METH_NOARGS, _curses_panel_panel_below__doc__}, 105 | 106 | static PyObject * 107 | _curses_panel_panel_below_impl(PyCursesPanelObject *self); 108 | 109 | static PyObject * 110 | _curses_panel_panel_below(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 111 | { 112 | return _curses_panel_panel_below_impl(self); 113 | } 114 | 115 | PyDoc_STRVAR(_curses_panel_panel_hidden__doc__, 116 | "hidden($self, /)\n" 117 | "--\n" 118 | "\n" 119 | "Return True if the panel is hidden (not visible), False otherwise."); 120 | 121 | #define _CURSES_PANEL_PANEL_HIDDEN_METHODDEF \ 122 | {"hidden", (PyCFunction)_curses_panel_panel_hidden, METH_NOARGS, _curses_panel_panel_hidden__doc__}, 123 | 124 | static PyObject * 125 | _curses_panel_panel_hidden_impl(PyCursesPanelObject *self); 126 | 127 | static PyObject * 128 | _curses_panel_panel_hidden(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 129 | { 130 | return _curses_panel_panel_hidden_impl(self); 131 | } 132 | 133 | PyDoc_STRVAR(_curses_panel_panel_move__doc__, 134 | "move($self, y, x, /)\n" 135 | "--\n" 136 | "\n" 137 | "Move the panel to the screen coordinates (y, x)."); 138 | 139 | #define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ 140 | {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_FASTCALL, _curses_panel_panel_move__doc__}, 141 | 142 | static PyObject * 143 | _curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x); 144 | 145 | static PyObject * 146 | _curses_panel_panel_move(PyCursesPanelObject *self, PyObject *const *args, Py_ssize_t nargs) 147 | { 148 | PyObject *return_value = NULL; 149 | int y; 150 | int x; 151 | 152 | if (!_PyArg_CheckPositional("move", nargs, 2, 2)) { 153 | goto exit; 154 | } 155 | if (PyFloat_Check(args[0])) { 156 | PyErr_SetString(PyExc_TypeError, 157 | "integer argument expected, got float" ); 158 | goto exit; 159 | } 160 | y = _PyLong_AsInt(args[0]); 161 | if (y == -1 && PyErr_Occurred()) { 162 | goto exit; 163 | } 164 | if (PyFloat_Check(args[1])) { 165 | PyErr_SetString(PyExc_TypeError, 166 | "integer argument expected, got float" ); 167 | goto exit; 168 | } 169 | x = _PyLong_AsInt(args[1]); 170 | if (x == -1 && PyErr_Occurred()) { 171 | goto exit; 172 | } 173 | return_value = _curses_panel_panel_move_impl(self, y, x); 174 | 175 | exit: 176 | return return_value; 177 | } 178 | 179 | PyDoc_STRVAR(_curses_panel_panel_window__doc__, 180 | "window($self, /)\n" 181 | "--\n" 182 | "\n" 183 | "Return the window object associated with the panel."); 184 | 185 | #define _CURSES_PANEL_PANEL_WINDOW_METHODDEF \ 186 | {"window", (PyCFunction)_curses_panel_panel_window, METH_NOARGS, _curses_panel_panel_window__doc__}, 187 | 188 | static PyObject * 189 | _curses_panel_panel_window_impl(PyCursesPanelObject *self); 190 | 191 | static PyObject * 192 | _curses_panel_panel_window(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 193 | { 194 | return _curses_panel_panel_window_impl(self); 195 | } 196 | 197 | PyDoc_STRVAR(_curses_panel_panel_replace__doc__, 198 | "replace($self, win, /)\n" 199 | "--\n" 200 | "\n" 201 | "Change the window associated with the panel to the window win."); 202 | 203 | #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ 204 | {"replace", (PyCFunction)_curses_panel_panel_replace, METH_O, _curses_panel_panel_replace__doc__}, 205 | 206 | static PyObject * 207 | _curses_panel_panel_replace_impl(PyCursesPanelObject *self, 208 | PyCursesWindowObject *win); 209 | 210 | static PyObject * 211 | _curses_panel_panel_replace(PyCursesPanelObject *self, PyObject *arg) 212 | { 213 | PyObject *return_value = NULL; 214 | PyCursesWindowObject *win; 215 | 216 | if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { 217 | _PyArg_BadArgument("replace", 0, (&PyCursesWindow_Type)->tp_name, arg); 218 | goto exit; 219 | } 220 | win = (PyCursesWindowObject *)arg; 221 | return_value = _curses_panel_panel_replace_impl(self, win); 222 | 223 | exit: 224 | return return_value; 225 | } 226 | 227 | PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, 228 | "set_userptr($self, obj, /)\n" 229 | "--\n" 230 | "\n" 231 | "Set the panel\'s user pointer to obj."); 232 | 233 | #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ 234 | {"set_userptr", (PyCFunction)_curses_panel_panel_set_userptr, METH_O, _curses_panel_panel_set_userptr__doc__}, 235 | 236 | PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, 237 | "userptr($self, /)\n" 238 | "--\n" 239 | "\n" 240 | "Return the user pointer for the panel."); 241 | 242 | #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ 243 | {"userptr", (PyCFunction)_curses_panel_panel_userptr, METH_NOARGS, _curses_panel_panel_userptr__doc__}, 244 | 245 | static PyObject * 246 | _curses_panel_panel_userptr_impl(PyCursesPanelObject *self); 247 | 248 | static PyObject * 249 | _curses_panel_panel_userptr(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 250 | { 251 | return _curses_panel_panel_userptr_impl(self); 252 | } 253 | 254 | PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, 255 | "bottom_panel($module, /)\n" 256 | "--\n" 257 | "\n" 258 | "Return the bottom panel in the panel stack."); 259 | 260 | #define _CURSES_PANEL_BOTTOM_PANEL_METHODDEF \ 261 | {"bottom_panel", (PyCFunction)_curses_panel_bottom_panel, METH_NOARGS, _curses_panel_bottom_panel__doc__}, 262 | 263 | static PyObject * 264 | _curses_panel_bottom_panel_impl(PyObject *module); 265 | 266 | static PyObject * 267 | _curses_panel_bottom_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 268 | { 269 | return _curses_panel_bottom_panel_impl(module); 270 | } 271 | 272 | PyDoc_STRVAR(_curses_panel_new_panel__doc__, 273 | "new_panel($module, win, /)\n" 274 | "--\n" 275 | "\n" 276 | "Return a panel object, associating it with the given window win."); 277 | 278 | #define _CURSES_PANEL_NEW_PANEL_METHODDEF \ 279 | {"new_panel", (PyCFunction)_curses_panel_new_panel, METH_O, _curses_panel_new_panel__doc__}, 280 | 281 | static PyObject * 282 | _curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win); 283 | 284 | static PyObject * 285 | _curses_panel_new_panel(PyObject *module, PyObject *arg) 286 | { 287 | PyObject *return_value = NULL; 288 | PyCursesWindowObject *win; 289 | 290 | if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { 291 | _PyArg_BadArgument("new_panel", 0, (&PyCursesWindow_Type)->tp_name, arg); 292 | goto exit; 293 | } 294 | win = (PyCursesWindowObject *)arg; 295 | return_value = _curses_panel_new_panel_impl(module, win); 296 | 297 | exit: 298 | return return_value; 299 | } 300 | 301 | PyDoc_STRVAR(_curses_panel_top_panel__doc__, 302 | "top_panel($module, /)\n" 303 | "--\n" 304 | "\n" 305 | "Return the top panel in the panel stack."); 306 | 307 | #define _CURSES_PANEL_TOP_PANEL_METHODDEF \ 308 | {"top_panel", (PyCFunction)_curses_panel_top_panel, METH_NOARGS, _curses_panel_top_panel__doc__}, 309 | 310 | static PyObject * 311 | _curses_panel_top_panel_impl(PyObject *module); 312 | 313 | static PyObject * 314 | _curses_panel_top_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 315 | { 316 | return _curses_panel_top_panel_impl(module); 317 | } 318 | 319 | PyDoc_STRVAR(_curses_panel_update_panels__doc__, 320 | "update_panels($module, /)\n" 321 | "--\n" 322 | "\n" 323 | "Updates the virtual screen after changes in the panel stack.\n" 324 | "\n" 325 | "This does not call curses.doupdate(), so you\'ll have to do this yourself."); 326 | 327 | #define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \ 328 | {"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__}, 329 | 330 | static PyObject * 331 | _curses_panel_update_panels_impl(PyObject *module); 332 | 333 | static PyObject * 334 | _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) 335 | { 336 | return _curses_panel_update_panels_impl(module); 337 | } 338 | /*[clinic end generated code: output=3cc16062281b7e07 input=a9049054013a1b77]*/ 339 | -------------------------------------------------------------------------------- /py39/clinic/_curses_panel.c.h: -------------------------------------------------------------------------------- 1 | /*[clinic input] 2 | preserve 3 | [clinic start generated code]*/ 4 | 5 | PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, 6 | "bottom($self, /)\n" 7 | "--\n" 8 | "\n" 9 | "Push the panel to the bottom of the stack."); 10 | 11 | #define _CURSES_PANEL_PANEL_BOTTOM_METHODDEF \ 12 | {"bottom", (PyCFunction)_curses_panel_panel_bottom, METH_NOARGS, _curses_panel_panel_bottom__doc__}, 13 | 14 | static PyObject * 15 | _curses_panel_panel_bottom_impl(PyCursesPanelObject *self); 16 | 17 | static PyObject * 18 | _curses_panel_panel_bottom(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 19 | { 20 | return _curses_panel_panel_bottom_impl(self); 21 | } 22 | 23 | PyDoc_STRVAR(_curses_panel_panel_hide__doc__, 24 | "hide($self, /)\n" 25 | "--\n" 26 | "\n" 27 | "Hide the panel.\n" 28 | "\n" 29 | "This does not delete the object, it just makes the window on screen invisible."); 30 | 31 | #define _CURSES_PANEL_PANEL_HIDE_METHODDEF \ 32 | {"hide", (PyCFunction)_curses_panel_panel_hide, METH_NOARGS, _curses_panel_panel_hide__doc__}, 33 | 34 | static PyObject * 35 | _curses_panel_panel_hide_impl(PyCursesPanelObject *self); 36 | 37 | static PyObject * 38 | _curses_panel_panel_hide(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 39 | { 40 | return _curses_panel_panel_hide_impl(self); 41 | } 42 | 43 | PyDoc_STRVAR(_curses_panel_panel_show__doc__, 44 | "show($self, /)\n" 45 | "--\n" 46 | "\n" 47 | "Display the panel (which might have been hidden)."); 48 | 49 | #define _CURSES_PANEL_PANEL_SHOW_METHODDEF \ 50 | {"show", (PyCFunction)_curses_panel_panel_show, METH_NOARGS, _curses_panel_panel_show__doc__}, 51 | 52 | static PyObject * 53 | _curses_panel_panel_show_impl(PyCursesPanelObject *self); 54 | 55 | static PyObject * 56 | _curses_panel_panel_show(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 57 | { 58 | return _curses_panel_panel_show_impl(self); 59 | } 60 | 61 | PyDoc_STRVAR(_curses_panel_panel_top__doc__, 62 | "top($self, /)\n" 63 | "--\n" 64 | "\n" 65 | "Push panel to the top of the stack."); 66 | 67 | #define _CURSES_PANEL_PANEL_TOP_METHODDEF \ 68 | {"top", (PyCFunction)_curses_panel_panel_top, METH_NOARGS, _curses_panel_panel_top__doc__}, 69 | 70 | static PyObject * 71 | _curses_panel_panel_top_impl(PyCursesPanelObject *self); 72 | 73 | static PyObject * 74 | _curses_panel_panel_top(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 75 | { 76 | return _curses_panel_panel_top_impl(self); 77 | } 78 | 79 | PyDoc_STRVAR(_curses_panel_panel_above__doc__, 80 | "above($self, /)\n" 81 | "--\n" 82 | "\n" 83 | "Return the panel above the current panel."); 84 | 85 | #define _CURSES_PANEL_PANEL_ABOVE_METHODDEF \ 86 | {"above", (PyCFunction)_curses_panel_panel_above, METH_NOARGS, _curses_panel_panel_above__doc__}, 87 | 88 | static PyObject * 89 | _curses_panel_panel_above_impl(PyCursesPanelObject *self); 90 | 91 | static PyObject * 92 | _curses_panel_panel_above(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 93 | { 94 | return _curses_panel_panel_above_impl(self); 95 | } 96 | 97 | PyDoc_STRVAR(_curses_panel_panel_below__doc__, 98 | "below($self, /)\n" 99 | "--\n" 100 | "\n" 101 | "Return the panel below the current panel."); 102 | 103 | #define _CURSES_PANEL_PANEL_BELOW_METHODDEF \ 104 | {"below", (PyCFunction)_curses_panel_panel_below, METH_NOARGS, _curses_panel_panel_below__doc__}, 105 | 106 | static PyObject * 107 | _curses_panel_panel_below_impl(PyCursesPanelObject *self); 108 | 109 | static PyObject * 110 | _curses_panel_panel_below(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 111 | { 112 | return _curses_panel_panel_below_impl(self); 113 | } 114 | 115 | PyDoc_STRVAR(_curses_panel_panel_hidden__doc__, 116 | "hidden($self, /)\n" 117 | "--\n" 118 | "\n" 119 | "Return True if the panel is hidden (not visible), False otherwise."); 120 | 121 | #define _CURSES_PANEL_PANEL_HIDDEN_METHODDEF \ 122 | {"hidden", (PyCFunction)_curses_panel_panel_hidden, METH_NOARGS, _curses_panel_panel_hidden__doc__}, 123 | 124 | static PyObject * 125 | _curses_panel_panel_hidden_impl(PyCursesPanelObject *self); 126 | 127 | static PyObject * 128 | _curses_panel_panel_hidden(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 129 | { 130 | return _curses_panel_panel_hidden_impl(self); 131 | } 132 | 133 | PyDoc_STRVAR(_curses_panel_panel_move__doc__, 134 | "move($self, y, x, /)\n" 135 | "--\n" 136 | "\n" 137 | "Move the panel to the screen coordinates (y, x)."); 138 | 139 | #define _CURSES_PANEL_PANEL_MOVE_METHODDEF \ 140 | {"move", (PyCFunction)(void(*)(void))_curses_panel_panel_move, METH_FASTCALL, _curses_panel_panel_move__doc__}, 141 | 142 | static PyObject * 143 | _curses_panel_panel_move_impl(PyCursesPanelObject *self, int y, int x); 144 | 145 | static PyObject * 146 | _curses_panel_panel_move(PyCursesPanelObject *self, PyObject *const *args, Py_ssize_t nargs) 147 | { 148 | PyObject *return_value = NULL; 149 | int y; 150 | int x; 151 | 152 | if (!_PyArg_CheckPositional("move", nargs, 2, 2)) { 153 | goto exit; 154 | } 155 | if (PyFloat_Check(args[0])) { 156 | PyErr_SetString(PyExc_TypeError, 157 | "integer argument expected, got float" ); 158 | goto exit; 159 | } 160 | y = _PyLong_AsInt(args[0]); 161 | if (y == -1 && PyErr_Occurred()) { 162 | goto exit; 163 | } 164 | if (PyFloat_Check(args[1])) { 165 | PyErr_SetString(PyExc_TypeError, 166 | "integer argument expected, got float" ); 167 | goto exit; 168 | } 169 | x = _PyLong_AsInt(args[1]); 170 | if (x == -1 && PyErr_Occurred()) { 171 | goto exit; 172 | } 173 | return_value = _curses_panel_panel_move_impl(self, y, x); 174 | 175 | exit: 176 | return return_value; 177 | } 178 | 179 | PyDoc_STRVAR(_curses_panel_panel_window__doc__, 180 | "window($self, /)\n" 181 | "--\n" 182 | "\n" 183 | "Return the window object associated with the panel."); 184 | 185 | #define _CURSES_PANEL_PANEL_WINDOW_METHODDEF \ 186 | {"window", (PyCFunction)_curses_panel_panel_window, METH_NOARGS, _curses_panel_panel_window__doc__}, 187 | 188 | static PyObject * 189 | _curses_panel_panel_window_impl(PyCursesPanelObject *self); 190 | 191 | static PyObject * 192 | _curses_panel_panel_window(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 193 | { 194 | return _curses_panel_panel_window_impl(self); 195 | } 196 | 197 | PyDoc_STRVAR(_curses_panel_panel_replace__doc__, 198 | "replace($self, win, /)\n" 199 | "--\n" 200 | "\n" 201 | "Change the window associated with the panel to the window win."); 202 | 203 | #define _CURSES_PANEL_PANEL_REPLACE_METHODDEF \ 204 | {"replace", (PyCFunction)_curses_panel_panel_replace, METH_O, _curses_panel_panel_replace__doc__}, 205 | 206 | static PyObject * 207 | _curses_panel_panel_replace_impl(PyCursesPanelObject *self, 208 | PyCursesWindowObject *win); 209 | 210 | static PyObject * 211 | _curses_panel_panel_replace(PyCursesPanelObject *self, PyObject *arg) 212 | { 213 | PyObject *return_value = NULL; 214 | PyCursesWindowObject *win; 215 | 216 | if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { 217 | _PyArg_BadArgument("replace", "argument", (&PyCursesWindow_Type)->tp_name, arg); 218 | goto exit; 219 | } 220 | win = (PyCursesWindowObject *)arg; 221 | return_value = _curses_panel_panel_replace_impl(self, win); 222 | 223 | exit: 224 | return return_value; 225 | } 226 | 227 | PyDoc_STRVAR(_curses_panel_panel_set_userptr__doc__, 228 | "set_userptr($self, obj, /)\n" 229 | "--\n" 230 | "\n" 231 | "Set the panel\'s user pointer to obj."); 232 | 233 | #define _CURSES_PANEL_PANEL_SET_USERPTR_METHODDEF \ 234 | {"set_userptr", (PyCFunction)_curses_panel_panel_set_userptr, METH_O, _curses_panel_panel_set_userptr__doc__}, 235 | 236 | PyDoc_STRVAR(_curses_panel_panel_userptr__doc__, 237 | "userptr($self, /)\n" 238 | "--\n" 239 | "\n" 240 | "Return the user pointer for the panel."); 241 | 242 | #define _CURSES_PANEL_PANEL_USERPTR_METHODDEF \ 243 | {"userptr", (PyCFunction)_curses_panel_panel_userptr, METH_NOARGS, _curses_panel_panel_userptr__doc__}, 244 | 245 | static PyObject * 246 | _curses_panel_panel_userptr_impl(PyCursesPanelObject *self); 247 | 248 | static PyObject * 249 | _curses_panel_panel_userptr(PyCursesPanelObject *self, PyObject *Py_UNUSED(ignored)) 250 | { 251 | return _curses_panel_panel_userptr_impl(self); 252 | } 253 | 254 | PyDoc_STRVAR(_curses_panel_bottom_panel__doc__, 255 | "bottom_panel($module, /)\n" 256 | "--\n" 257 | "\n" 258 | "Return the bottom panel in the panel stack."); 259 | 260 | #define _CURSES_PANEL_BOTTOM_PANEL_METHODDEF \ 261 | {"bottom_panel", (PyCFunction)_curses_panel_bottom_panel, METH_NOARGS, _curses_panel_bottom_panel__doc__}, 262 | 263 | static PyObject * 264 | _curses_panel_bottom_panel_impl(PyObject *module); 265 | 266 | static PyObject * 267 | _curses_panel_bottom_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 268 | { 269 | return _curses_panel_bottom_panel_impl(module); 270 | } 271 | 272 | PyDoc_STRVAR(_curses_panel_new_panel__doc__, 273 | "new_panel($module, win, /)\n" 274 | "--\n" 275 | "\n" 276 | "Return a panel object, associating it with the given window win."); 277 | 278 | #define _CURSES_PANEL_NEW_PANEL_METHODDEF \ 279 | {"new_panel", (PyCFunction)_curses_panel_new_panel, METH_O, _curses_panel_new_panel__doc__}, 280 | 281 | static PyObject * 282 | _curses_panel_new_panel_impl(PyObject *module, PyCursesWindowObject *win); 283 | 284 | static PyObject * 285 | _curses_panel_new_panel(PyObject *module, PyObject *arg) 286 | { 287 | PyObject *return_value = NULL; 288 | PyCursesWindowObject *win; 289 | 290 | if (!PyObject_TypeCheck(arg, &PyCursesWindow_Type)) { 291 | _PyArg_BadArgument("new_panel", "argument", (&PyCursesWindow_Type)->tp_name, arg); 292 | goto exit; 293 | } 294 | win = (PyCursesWindowObject *)arg; 295 | return_value = _curses_panel_new_panel_impl(module, win); 296 | 297 | exit: 298 | return return_value; 299 | } 300 | 301 | PyDoc_STRVAR(_curses_panel_top_panel__doc__, 302 | "top_panel($module, /)\n" 303 | "--\n" 304 | "\n" 305 | "Return the top panel in the panel stack."); 306 | 307 | #define _CURSES_PANEL_TOP_PANEL_METHODDEF \ 308 | {"top_panel", (PyCFunction)_curses_panel_top_panel, METH_NOARGS, _curses_panel_top_panel__doc__}, 309 | 310 | static PyObject * 311 | _curses_panel_top_panel_impl(PyObject *module); 312 | 313 | static PyObject * 314 | _curses_panel_top_panel(PyObject *module, PyObject *Py_UNUSED(ignored)) 315 | { 316 | return _curses_panel_top_panel_impl(module); 317 | } 318 | 319 | PyDoc_STRVAR(_curses_panel_update_panels__doc__, 320 | "update_panels($module, /)\n" 321 | "--\n" 322 | "\n" 323 | "Updates the virtual screen after changes in the panel stack.\n" 324 | "\n" 325 | "This does not call curses.doupdate(), so you\'ll have to do this yourself."); 326 | 327 | #define _CURSES_PANEL_UPDATE_PANELS_METHODDEF \ 328 | {"update_panels", (PyCFunction)_curses_panel_update_panels, METH_NOARGS, _curses_panel_update_panels__doc__}, 329 | 330 | static PyObject * 331 | _curses_panel_update_panels_impl(PyObject *module); 332 | 333 | static PyObject * 334 | _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) 335 | { 336 | return _curses_panel_update_panels_impl(module); 337 | } 338 | /*[clinic end generated code: output=d96dc1fd68e898d9 input=a9049054013a1b77]*/ 339 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | from setuptools import setup, Extension 4 | 5 | libraries = ['pdcurses', 'user32', 'advapi32', 'gdi32', 'comdlg32', 'shell32'] 6 | 7 | define_macros = [ 8 | ('PDC_WIDE', None), 9 | ('HAVE_CURSES_H', None), 10 | ('HAVE_PANEL_H', None), 11 | ('HAVE_NCURSESW', None), 12 | ('HAVE_TERM_H', None), 13 | ('HAVE_CURSES_IS_TERM_RESIZED', None), 14 | ('HAVE_CURSES_RESIZE_TERM', None), 15 | ('HAVE_CURSES_TYPEAHEAD', None), 16 | ('HAVE_CURSES_HAS_KEY', None), 17 | ('HAVE_CURSES_FILTER', None), 18 | ('HAVE_CURSES_WCHGAT', None), 19 | ('HAVE_CURSES_USE_ENV', None), 20 | ('HAVE_CURSES_IMMEDOK', None), 21 | ('HAVE_CURSES_SYNCOK', None), 22 | # ('HAVE_CURSES_IS_PAD', None), 23 | ('WINDOW_HAS_FLAGS', None), 24 | ('NCURSES_MOUSE_VERSION', 2), 25 | ('_ISPAD', 0x10), 26 | ('is_term_resized', 'is_termresized'), 27 | ] 28 | 29 | srcdir = 'py%i%i//' % sys.version_info[:2] 30 | 31 | include_dirs = ["PDCurses", "."] 32 | library_dirs = ["PDCurses/wincon"] 33 | 34 | LONG_DESCRIPTION = """ 35 | Adds support for the standard Python `curses` module on Windows. Based on 36 | [these wheels](https://www.lfd.uci.edu/~gohlke/pythonlibs/#curses). Uses the 37 | PDCurses curses implementation. 38 | 39 | The wheels are built from [this GitHub 40 | repository](https://github.com/zephyrproject-rtos/windows-curses). 41 | 42 | PDCurses is compiled with wide character support, meaning `get_wch()` is 43 | available. UTF-8 is forced as the encoding. 44 | 45 | Starting from windows-curses 2.0, in the name of pragmatism, these wheels (but 46 | not Gohlke's) include a hack to make resizing work for applications developed 47 | against ncurses without Python code changes: Whenever `getch()`, `getkey()`, or 48 | `get_wch()` return `KEY_RESIZE`, `resize_term(0, 0)` is called automatically. 49 | This gives behavior similar to the automatic `SIGWINCH` handling in ncurses 50 | (see PDCurses' `resize_term()` documentation). [This 51 | commit](https://github.com/zephyrproject-rtos/windows-curses/commit/30ca08bfbcb7a332228ddcde026181b2009ea0a7) 52 | implements the hack. 53 | 54 | To add the same hack in Python code (which is harmless, and needed if you want 55 | resizing to work with older windows-curses versions or with Gohlke's wheels), 56 | call `curses.resize_term(0, 0)` after receiving `KEY_RESIZE`, and ignore any 57 | `curses.error` exceptions. ncurses reliably fails and does nothing for 58 | `resize_term(0, 0)`, so this is safe on *nix. 59 | 60 | Please tell me if the `resize_term(0, 0)` hackery causes you any trouble. 61 | """[1:-1] 62 | 63 | setup( 64 | name='windows-curses', 65 | version='2.4.1', 66 | description="Support for the standard curses module on Windows", 67 | long_description=LONG_DESCRIPTION, 68 | long_description_content_type="text/markdown", 69 | url="https://github.com/zephyrproject-rtos/windows-curses", 70 | license='PSF2', 71 | ext_modules=[ 72 | Extension('_curses', 73 | # term.h and terminfo.c was removed from PDCurses in commit 74 | # 6b569295 ("Eliminated term.h, terminfo.c; moved mvcur() to 75 | # move.c"). They provide functions that are called 76 | # unconditionally by _cursesmodule.c, so we keep a copy of 77 | # the last versions in this repo. 78 | # 79 | # See https://github.com/wmcbrine/PDCurses/issue/55. 80 | sources=[srcdir + '_cursesmodule.c', 'terminfo.c'], 81 | define_macros=define_macros, 82 | include_dirs=include_dirs, 83 | library_dirs=library_dirs, 84 | libraries=libraries), 85 | Extension('_curses_panel', 86 | sources=[srcdir + '_curses_panel.c'], 87 | define_macros=define_macros, 88 | include_dirs=include_dirs, 89 | library_dirs=library_dirs, 90 | libraries=libraries) 91 | ], 92 | project_urls={ 93 | "GitHub repository": "https://github.com/zephyrproject-rtos/windows-curses", 94 | }, 95 | classifiers = [ 96 | 'Development Status :: 4 - Beta', 97 | 'Environment :: Console :: Curses', 98 | 'Environment :: Win32 (MS Windows)', 99 | 'License :: OSI Approved :: Python Software Foundation License', 100 | 'Operating System :: Microsoft :: Windows', 101 | 'Programming Language :: C', 102 | 'Programming Language :: Python', 103 | 'Programming Language :: Python :: 3.6', 104 | 'Programming Language :: Python :: 3.7', 105 | 'Programming Language :: Python :: 3.8', 106 | 'Programming Language :: Python :: 3.9', 107 | 'Programming Language :: Python :: 3.10', 108 | 'Programming Language :: Python :: 3.11', 109 | 'Programming Language :: Python :: 3.12', 110 | 'Programming Language :: Python :: 3.13', 111 | 'Programming Language :: Python :: Implementation :: CPython', 112 | 'Topic :: Software Development', 113 | 'Topic :: Software Development :: Libraries :: Python Modules', 114 | ] 115 | ) 116 | -------------------------------------------------------------------------------- /term.h: -------------------------------------------------------------------------------- 1 | /* Public Domain Curses */ 2 | 3 | /* PDCurses doesn't operate with terminfo, but we need these functions for 4 | compatibility, to allow some things (notably, interface libraries for 5 | other languages) to be compiled. Anyone who tries to actually _use_ 6 | them will be disappointed, since they only return ERR. */ 7 | 8 | #ifndef __PDCURSES_TERM_H__ 9 | #define __PDCURSES_TERM_H__ 1 10 | 11 | #include 12 | 13 | #if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) 14 | extern "C" 15 | { 16 | #endif 17 | 18 | typedef struct 19 | { 20 | const char *_termname; 21 | } TERMINAL; 22 | 23 | PDCEX TERMINAL *cur_term; 24 | 25 | PDCEX int del_curterm(TERMINAL *); 26 | PDCEX int putp(const char *); 27 | PDCEX int restartterm(const char *, int, int *); 28 | PDCEX TERMINAL *set_curterm(TERMINAL *); 29 | PDCEX int setterm(const char *); 30 | PDCEX int setupterm(const char *, int, int *); 31 | PDCEX int tgetent(char *, const char *); 32 | PDCEX int tgetflag(const char *); 33 | PDCEX int tgetnum(const char *); 34 | PDCEX char *tgetstr(const char *, char **); 35 | PDCEX char *tgoto(const char *, int, int); 36 | PDCEX int tigetflag(const char *); 37 | PDCEX int tigetnum(const char *); 38 | PDCEX char *tigetstr(const char *); 39 | PDCEX char *tparm(const char *, long, long, long, long, long, 40 | long, long, long, long); 41 | PDCEX int tputs(const char *, int, int (*)(int)); 42 | 43 | #if defined(__cplusplus) || defined(__cplusplus__) || defined(__CPLUSPLUS) 44 | } 45 | #endif 46 | 47 | #endif /* __PDCURSES_TERM_H__ */ 48 | -------------------------------------------------------------------------------- /terminfo.c: -------------------------------------------------------------------------------- 1 | /* Public Domain Curses */ 2 | 3 | #include 4 | 5 | /*man-start************************************************************** 6 | 7 | terminfo 8 | -------- 9 | 10 | ### Synopsis 11 | 12 | int mvcur(int oldrow, int oldcol, int newrow, int newcol); 13 | int vidattr(chtype attr); 14 | int vid_attr(attr_t attr, short color_pair, void *opt); 15 | int vidputs(chtype attr, int (*putfunc)(int)); 16 | int vid_puts(attr_t attr, short color_pair, void *opt, 17 | int (*putfunc)(int)); 18 | 19 | int del_curterm(TERMINAL *); 20 | int putp(const char *); 21 | int restartterm(const char *, int, int *); 22 | TERMINAL *set_curterm(TERMINAL *); 23 | int setterm(const char *term); 24 | int setupterm(const char *, int, int *); 25 | int tgetent(char *, const char *); 26 | int tgetflag(const char *); 27 | int tgetnum(const char *); 28 | char *tgetstr(const char *, char **); 29 | char *tgoto(const char *, int, int); 30 | int tigetflag(const char *); 31 | int tigetnum(const char *); 32 | char *tigetstr(const char *); 33 | char *tparm(const char *,long, long, long, long, long, long, 34 | long, long, long); 35 | int tputs(const char *, int, int (*)(int)); 36 | 37 | ### Description 38 | 39 | mvcur() lets you move the physical cursor without updating any 40 | window cursor positions. It returns OK or ERR. 41 | 42 | The rest of these functions are currently implemented as stubs, 43 | returning the appropriate errors and doing nothing else. 44 | 45 | ### Portability 46 | X/Open BSD SYS V 47 | mvcur Y Y Y 48 | 49 | **man-end****************************************************************/ 50 | 51 | #include 52 | 53 | TERMINAL *cur_term = NULL; 54 | 55 | /* 56 | 57 | windows-curses note 58 | =================== 59 | 60 | This function was moved rather than deleted terminfo.c was removed from 61 | PDCurses, so remove it here. 62 | 63 | int mvcur(int oldrow, int oldcol, int newrow, int newcol) 64 | { 65 | PDC_LOG(("mvcur() - called: oldrow %d oldcol %d newrow %d newcol %d\n", 66 | oldrow, oldcol, newrow, newcol)); 67 | 68 | if ((newrow >= LINES) || (newcol >= COLS) || (newrow < 0) || (newcol < 0)) 69 | return ERR; 70 | 71 | PDC_gotoyx(newrow, newcol); 72 | SP->cursrow = newrow; 73 | SP->curscol = newcol; 74 | 75 | return OK; 76 | } 77 | 78 | */ 79 | 80 | int vidattr(chtype attr) 81 | { 82 | PDC_LOG(("vidattr() - called: attr %d\n", attr)); 83 | 84 | return ERR; 85 | } 86 | 87 | int vid_attr(attr_t attr, short color_pair, void *opt) 88 | { 89 | PDC_LOG(("vid_attr() - called\n")); 90 | 91 | return ERR; 92 | } 93 | 94 | int vidputs(chtype attr, int (*putfunc)(int)) 95 | { 96 | PDC_LOG(("vidputs() - called: attr %d\n", attr)); 97 | 98 | return ERR; 99 | } 100 | 101 | int vid_puts(attr_t attr, short color_pair, void *opt, int (*putfunc)(int)) 102 | { 103 | PDC_LOG(("vid_puts() - called\n")); 104 | 105 | return ERR; 106 | } 107 | 108 | int del_curterm(TERMINAL *oterm) 109 | { 110 | PDC_LOG(("del_curterm() - called\n")); 111 | 112 | return ERR; 113 | } 114 | 115 | int putp(const char *str) 116 | { 117 | PDC_LOG(("putp() - called: str %s\n", str)); 118 | 119 | return ERR; 120 | } 121 | 122 | int restartterm(const char *term, int filedes, int *errret) 123 | { 124 | PDC_LOG(("restartterm() - called\n")); 125 | 126 | if (errret) 127 | *errret = -1; 128 | 129 | return ERR; 130 | } 131 | 132 | TERMINAL *set_curterm(TERMINAL *nterm) 133 | { 134 | PDC_LOG(("set_curterm() - called\n")); 135 | 136 | return (TERMINAL *)NULL; 137 | } 138 | 139 | int setterm(const char *term) 140 | { 141 | PDC_LOG(("setterm() - called\n")); 142 | 143 | return ERR; 144 | } 145 | 146 | int setupterm(const char *term, int filedes, int *errret) 147 | { 148 | PDC_LOG(("setupterm() - called\n")); 149 | 150 | if (errret) 151 | *errret = -1; 152 | else 153 | fprintf(stderr, "There is no terminfo database\n"); 154 | 155 | return ERR; 156 | } 157 | 158 | int tgetent(char *bp, const char *name) 159 | { 160 | PDC_LOG(("tgetent() - called: name %s\n", name)); 161 | 162 | return ERR; 163 | } 164 | 165 | int tgetflag(const char *id) 166 | { 167 | PDC_LOG(("tgetflag() - called: id %s\n", id)); 168 | 169 | return ERR; 170 | } 171 | 172 | int tgetnum(const char *id) 173 | { 174 | PDC_LOG(("tgetnum() - called: id %s\n", id)); 175 | 176 | return ERR; 177 | } 178 | 179 | char *tgetstr(const char *id, char **area) 180 | { 181 | PDC_LOG(("tgetstr() - called: id %s\n", id)); 182 | 183 | return (char *)NULL; 184 | } 185 | 186 | char *tgoto(const char *cap, int col, int row) 187 | { 188 | PDC_LOG(("tgoto() - called\n")); 189 | 190 | return (char *)NULL; 191 | } 192 | 193 | int tigetflag(const char *capname) 194 | { 195 | PDC_LOG(("tigetflag() - called: capname %s\n", capname)); 196 | 197 | return -1; 198 | } 199 | 200 | int tigetnum(const char *capname) 201 | { 202 | PDC_LOG(("tigetnum() - called: capname %s\n", capname)); 203 | 204 | return -2; 205 | } 206 | 207 | char *tigetstr(const char *capname) 208 | { 209 | PDC_LOG(("tigetstr() - called: capname %s\n", capname)); 210 | 211 | return (char *)(-1); 212 | } 213 | 214 | char *tparm(const char *cap, long p1, long p2, long p3, long p4, 215 | long p5, long p6, long p7, long p8, long p9) 216 | { 217 | PDC_LOG(("tparm() - called: cap %s\n", cap)); 218 | 219 | return (char *)NULL; 220 | } 221 | 222 | int tputs(const char *str, int affcnt, int (*putfunc)(int)) 223 | { 224 | PDC_LOG(("tputs() - called\n")); 225 | 226 | return ERR; 227 | } 228 | --------------------------------------------------------------------------------