diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 04cf2e17d538fcc..e5face72d1e5c9b 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -1562,25 +1562,28 @@ Borders and lines that parameter. Keyword parameters can *not* be used. The defaults are listed in this table: - +-----------+---------------------+-----------------------+ - | Parameter | Description | Default value | - +===========+=====================+=======================+ - | *ls* | Left side | :const:`ACS_VLINE` | - +-----------+---------------------+-----------------------+ - | *rs* | Right side | :const:`ACS_VLINE` | - +-----------+---------------------+-----------------------+ - | *ts* | Top | :const:`ACS_HLINE` | - +-----------+---------------------+-----------------------+ - | *bs* | Bottom | :const:`ACS_HLINE` | - +-----------+---------------------+-----------------------+ - | *tl* | Upper-left corner | :const:`ACS_ULCORNER` | - +-----------+---------------------+-----------------------+ - | *tr* | Upper-right corner | :const:`ACS_URCORNER` | - +-----------+---------------------+-----------------------+ - | *bl* | Bottom-left corner | :const:`ACS_LLCORNER` | - +-----------+---------------------+-----------------------+ - | *br* | Bottom-right corner | :const:`ACS_LRCORNER` | - +-----------+---------------------+-----------------------+ + +-----------+---------------------+-----------------------+------------------------+ + | Parameter | Description | Default value | Wide default value | + +===========+=====================+=======================+========================+ + | *ls* | Left side | :const:`ACS_VLINE` | :const:`WACS_VLINE` | + +-----------+---------------------+-----------------------+------------------------+ + | *rs* | Right side | :const:`ACS_VLINE` | :const:`WACS_VLINE` | + +-----------+---------------------+-----------------------+------------------------+ + | *ts* | Top | :const:`ACS_HLINE` | :const:`WACS_HLINE` | + +-----------+---------------------+-----------------------+------------------------+ + | *bs* | Bottom | :const:`ACS_HLINE` | :const:`WACS_HLINE` | + +-----------+---------------------+-----------------------+------------------------+ + | *tl* | Upper-left corner | :const:`ACS_ULCORNER` | :const:`WACS_ULCORNER` | + +-----------+---------------------+-----------------------+------------------------+ + | *tr* | Upper-right corner | :const:`ACS_URCORNER` | :const:`WACS_URCORNER` | + +-----------+---------------------+-----------------------+------------------------+ + | *bl* | Bottom-left corner | :const:`ACS_LLCORNER` | :const:`WACS_LLCORNER` | + +-----------+---------------------+-----------------------+------------------------+ + | *br* | Bottom-right corner | :const:`ACS_LRCORNER` | :const:`WACS_LRCORNER` | + +-----------+---------------------+-----------------------+------------------------+ + + The wide default value is used when the border is drawn from string + characters or :class:`complexchar` cells. .. versionchanged:: next Wide and combining characters, and :class:`complexchar` cells, are now @@ -2255,62 +2258,58 @@ Attributes Some constants are available to specify character cell attributes. The exact constants available are system dependent. -+------------------------+-------------------------------+ -| Attribute | Meaning | -+========================+===============================+ -| .. data:: A_ALTCHARSET | Alternate character set mode | -+------------------------+-------------------------------+ -| .. data:: A_BLINK | Blink mode | -+------------------------+-------------------------------+ -| .. data:: A_BOLD | Bold mode | -+------------------------+-------------------------------+ -| .. data:: A_DIM | Dim mode | -+------------------------+-------------------------------+ -| .. data:: A_INVIS | Invisible or blank mode | -+------------------------+-------------------------------+ -| .. data:: A_ITALIC | Italic mode | -+------------------------+-------------------------------+ -| .. data:: A_NORMAL | Normal attribute | -+------------------------+-------------------------------+ -| .. data:: A_PROTECT | Protected mode | -+------------------------+-------------------------------+ -| .. data:: A_REVERSE | Reverse background and | -| | foreground colors | -+------------------------+-------------------------------+ -| .. data:: A_STANDOUT | Standout mode | -+------------------------+-------------------------------+ -| .. data:: A_UNDERLINE | Underline mode | -+------------------------+-------------------------------+ -| .. data:: A_HORIZONTAL | Horizontal highlight | -+------------------------+-------------------------------+ -| .. data:: A_LEFT | Left highlight | -+------------------------+-------------------------------+ -| .. data:: A_LOW | Low highlight | -+------------------------+-------------------------------+ -| .. data:: A_RIGHT | Right highlight | -+------------------------+-------------------------------+ -| .. data:: A_TOP | Top highlight | -+------------------------+-------------------------------+ -| .. data:: A_VERTICAL | Vertical highlight | -+------------------------+-------------------------------+ +.. _curses-wa-constants: + ++------------------------+-------------------------+------------------------------------------+ +| Attribute | Wide attribute | Meaning | ++========================+=========================+==========================================+ +| .. data:: A_ALTCHARSET | .. data:: WA_ALTCHARSET | Alternate character set mode | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_BLINK | .. data:: WA_BLINK | Blink mode | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_BOLD | .. data:: WA_BOLD | Bold mode | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_DIM | .. data:: WA_DIM | Dim mode | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_INVIS | .. data:: WA_INVIS | Invisible or blank mode | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_ITALIC | .. data:: WA_ITALIC | Italic mode | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_NORMAL | .. data:: WA_NORMAL | Normal attribute | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_PROTECT | .. data:: WA_PROTECT | Protected mode | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_REVERSE | .. data:: WA_REVERSE | Reverse background and foreground colors | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_STANDOUT | .. data:: WA_STANDOUT | Standout mode | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_UNDERLINE | .. data:: WA_UNDERLINE | Underline mode | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_HORIZONTAL | .. data:: WA_HORIZONTAL | Horizontal highlight | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_LEFT | .. data:: WA_LEFT | Left highlight | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_LOW | .. data:: WA_LOW | Low highlight | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_RIGHT | .. data:: WA_RIGHT | Right highlight | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_TOP | .. data:: WA_TOP | Top highlight | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: A_VERTICAL | .. data:: WA_VERTICAL | Vertical highlight | ++------------------------+-------------------------+------------------------------------------+ .. versionadded:: 3.7 ``A_ITALIC`` was added. -.. _curses-wa-constants: - The :meth:`~window.attr_get`, :meth:`~window.attr_set`, :meth:`~window.attr_on` -and :meth:`~window.attr_off` methods use a parallel set of ``WA_*`` constants. -These have the same meaning as the corresponding ``A_*`` attributes above -(``WA_BOLD`` like :const:`A_BOLD`, and so on), but belong to the ``attr_t`` type -rather than being packed into a character. In ncurses the two sets share the -same values, but other curses implementations may give them different ones, so -use the ``WA_*`` constants with the ``attr_*`` methods. The available names are -``WA_ATTRIBUTES``, ``WA_NORMAL``, ``WA_STANDOUT``, ``WA_UNDERLINE``, -``WA_REVERSE``, ``WA_BLINK``, ``WA_DIM``, ``WA_BOLD``, ``WA_ALTCHARSET``, -``WA_INVIS``, ``WA_PROTECT``, ``WA_HORIZONTAL``, ``WA_LEFT``, ``WA_LOW``, -``WA_RIGHT``, ``WA_TOP``, ``WA_VERTICAL`` and ``WA_ITALIC`` (each available only -where the platform defines it). +and :meth:`~window.attr_off` methods use the parallel set of ``WA_*`` constants +listed above. +Each has the same meaning as the corresponding ``A_*`` attribute +(:const:`WA_BOLD` like :const:`A_BOLD`, and so on), but belongs to the +``attr_t`` type rather than being packed into a character. +In ncurses the two sets share the same values, but other curses implementations +may give them different ones, so use the ``WA_*`` constants with the ``attr_*`` +methods. .. versionadded:: next The ``WA_*`` constants were added. @@ -2318,18 +2317,15 @@ where the platform defines it). Several constants are available to extract corresponding attributes returned by some methods. -+-------------------------+-------------------------------+ -| Bit-mask | Meaning | -+=========================+===============================+ -| .. data:: A_ATTRIBUTES | Bit-mask to extract | -| | attributes | -+-------------------------+-------------------------------+ -| .. data:: A_CHARTEXT | Bit-mask to extract a | -| | character | -+-------------------------+-------------------------------+ -| .. data:: A_COLOR | Bit-mask to extract | -| | color-pair field information | -+-------------------------+-------------------------------+ ++-------------------------+--------------------------+--------------------------------------------------+ +| Bit-mask | Wide bit-mask | Meaning | ++=========================+==========================+==================================================+ +| .. data:: A_ATTRIBUTES | .. data:: WA_ATTRIBUTES | Bit-mask to extract attributes | ++-------------------------+--------------------------+--------------------------------------------------+ +| .. data:: A_CHARTEXT | | Bit-mask to extract a character | ++-------------------------+--------------------------+--------------------------------------------------+ +| .. data:: A_COLOR | | Bit-mask to extract color-pair field information | ++-------------------------+--------------------------+--------------------------------------------------+ Keys ~~~~ @@ -2564,99 +2560,165 @@ inherited from the VT100 terminal, and will generally be available on software emulations such as X terminals. When there is no graphic available, curses falls back on a crude printable ASCII approximation. +Every character has two names. +The ``ACS_*`` code is an integer character, restricted to the 8-bit +alternate character set of the terminal. +The ``WACS_*`` code is the same character as a :class:`complexchar` cell, +which is not restricted to the alternate character set. + .. note:: These are available only after :func:`initscr` has been called. + The ``WACS_*`` codes are only available if Python is built with + wide character support. -+------------------------+------------------------------------------+ -| ACS code | Meaning | -+========================+==========================================+ -| .. data:: ACS_BBSS | alternate name for upper-right corner | -+------------------------+------------------------------------------+ -| .. data:: ACS_BLOCK | solid square block | -+------------------------+------------------------------------------+ -| .. data:: ACS_BOARD | board of squares | -+------------------------+------------------------------------------+ -| .. data:: ACS_BSBS | alternate name for horizontal line | -+------------------------+------------------------------------------+ -| .. data:: ACS_BSSB | alternate name for upper-left corner | -+------------------------+------------------------------------------+ -| .. data:: ACS_BSSS | alternate name for top tee | -+------------------------+------------------------------------------+ -| .. data:: ACS_BTEE | bottom tee | -+------------------------+------------------------------------------+ -| .. data:: ACS_BULLET | bullet | -+------------------------+------------------------------------------+ -| .. data:: ACS_CKBOARD | checker board (stipple) | -+------------------------+------------------------------------------+ -| .. data:: ACS_DARROW | arrow pointing down | -+------------------------+------------------------------------------+ -| .. data:: ACS_DEGREE | degree symbol | -+------------------------+------------------------------------------+ -| .. data:: ACS_DIAMOND | diamond | -+------------------------+------------------------------------------+ -| .. data:: ACS_GEQUAL | greater-than-or-equal-to | -+------------------------+------------------------------------------+ -| .. data:: ACS_HLINE | horizontal line | -+------------------------+------------------------------------------+ -| .. data:: ACS_LANTERN | lantern symbol | -+------------------------+------------------------------------------+ -| .. data:: ACS_LARROW | left arrow | -+------------------------+------------------------------------------+ -| .. data:: ACS_LEQUAL | less-than-or-equal-to | -+------------------------+------------------------------------------+ -| .. data:: ACS_LLCORNER | lower-left corner | -+------------------------+------------------------------------------+ -| .. data:: ACS_LRCORNER | lower-right corner | -+------------------------+------------------------------------------+ -| .. data:: ACS_LTEE | left tee | -+------------------------+------------------------------------------+ -| .. data:: ACS_NEQUAL | not-equal sign | -+------------------------+------------------------------------------+ -| .. data:: ACS_PI | letter pi | -+------------------------+------------------------------------------+ -| .. data:: ACS_PLMINUS | plus-or-minus sign | -+------------------------+------------------------------------------+ -| .. data:: ACS_PLUS | big plus sign | -+------------------------+------------------------------------------+ -| .. data:: ACS_RARROW | right arrow | -+------------------------+------------------------------------------+ -| .. data:: ACS_RTEE | right tee | -+------------------------+------------------------------------------+ -| .. data:: ACS_S1 | scan line 1 | -+------------------------+------------------------------------------+ -| .. data:: ACS_S3 | scan line 3 | -+------------------------+------------------------------------------+ -| .. data:: ACS_S7 | scan line 7 | -+------------------------+------------------------------------------+ -| .. data:: ACS_S9 | scan line 9 | -+------------------------+------------------------------------------+ -| .. data:: ACS_SBBS | alternate name for lower-right corner | -+------------------------+------------------------------------------+ -| .. data:: ACS_SBSB | alternate name for vertical line | -+------------------------+------------------------------------------+ -| .. data:: ACS_SBSS | alternate name for right tee | -+------------------------+------------------------------------------+ -| .. data:: ACS_SSBB | alternate name for lower-left corner | -+------------------------+------------------------------------------+ -| .. data:: ACS_SSBS | alternate name for bottom tee | -+------------------------+------------------------------------------+ -| .. data:: ACS_SSSB | alternate name for left tee | -+------------------------+------------------------------------------+ -| .. data:: ACS_SSSS | alternate name for crossover or big plus | -+------------------------+------------------------------------------+ -| .. data:: ACS_STERLING | pound sterling | -+------------------------+------------------------------------------+ -| .. data:: ACS_TTEE | top tee | -+------------------------+------------------------------------------+ -| .. data:: ACS_UARROW | up arrow | -+------------------------+------------------------------------------+ -| .. data:: ACS_ULCORNER | upper-left corner | -+------------------------+------------------------------------------+ -| .. data:: ACS_URCORNER | upper-right corner | -+------------------------+------------------------------------------+ -| .. data:: ACS_VLINE | vertical line | -+------------------------+------------------------------------------+ +.. versionadded:: next + The ``WACS_*`` codes. + ++------------------------+-------------------------+------------------------------------------+ +| ACS code | WACS code | Meaning | ++========================+=========================+==========================================+ +| .. data:: ACS_BBSS | .. data:: WACS_BBSS | alternate name for upper-right corner | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_BLOCK | .. data:: WACS_BLOCK | solid square block | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_BOARD | .. data:: WACS_BOARD | board of squares | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_BSBS | .. data:: WACS_BSBS | alternate name for horizontal line | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_BSSB | .. data:: WACS_BSSB | alternate name for upper-left corner | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_BSSS | .. data:: WACS_BSSS | alternate name for top tee | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_BTEE | .. data:: WACS_BTEE | bottom tee | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_BULLET | .. data:: WACS_BULLET | bullet | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_CKBOARD | .. data:: WACS_CKBOARD | checker board (stipple) | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_DARROW | .. data:: WACS_DARROW | arrow pointing down | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_DEGREE | .. data:: WACS_DEGREE | degree symbol | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_DIAMOND | .. data:: WACS_DIAMOND | diamond | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_GEQUAL | .. data:: WACS_GEQUAL | greater-than-or-equal-to | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_HLINE | .. data:: WACS_HLINE | horizontal line | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_LANTERN | .. data:: WACS_LANTERN | lantern symbol | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_LARROW | .. data:: WACS_LARROW | left arrow | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_LEQUAL | .. data:: WACS_LEQUAL | less-than-or-equal-to | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_LLCORNER | .. data:: WACS_LLCORNER | lower-left corner | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_LRCORNER | .. data:: WACS_LRCORNER | lower-right corner | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_LTEE | .. data:: WACS_LTEE | left tee | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_NEQUAL | .. data:: WACS_NEQUAL | not-equal sign | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_PI | .. data:: WACS_PI | letter pi | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_PLMINUS | .. data:: WACS_PLMINUS | plus-or-minus sign | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_PLUS | .. data:: WACS_PLUS | big plus sign | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_RARROW | .. data:: WACS_RARROW | right arrow | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_RTEE | .. data:: WACS_RTEE | right tee | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_S1 | .. data:: WACS_S1 | scan line 1 | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_S3 | .. data:: WACS_S3 | scan line 3 | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_S7 | .. data:: WACS_S7 | scan line 7 | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_S9 | .. data:: WACS_S9 | scan line 9 | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_SBBS | .. data:: WACS_SBBS | alternate name for lower-right corner | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_SBSB | .. data:: WACS_SBSB | alternate name for vertical line | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_SBSS | .. data:: WACS_SBSS | alternate name for right tee | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_SSBB | .. data:: WACS_SSBB | alternate name for lower-left corner | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_SSBS | .. data:: WACS_SSBS | alternate name for bottom tee | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_SSSB | .. data:: WACS_SSSB | alternate name for left tee | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_SSSS | .. data:: WACS_SSSS | alternate name for crossover or big plus | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_STERLING | .. data:: WACS_STERLING | pound sterling | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_TTEE | .. data:: WACS_TTEE | top tee | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_UARROW | .. data:: WACS_UARROW | up arrow | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_ULCORNER | .. data:: WACS_ULCORNER | upper-left corner | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_URCORNER | .. data:: WACS_URCORNER | upper-right corner | ++------------------------+-------------------------+------------------------------------------+ +| .. data:: ACS_VLINE | .. data:: WACS_VLINE | vertical line | ++------------------------+-------------------------+------------------------------------------+ + +The following table lists the double-line and thick-line characters. +They have no ``ACS_*`` counterpart, and are not provided by every implementation. +As in the table above, the alternate name spells out the four sides of the +character, clockwise from the top: +``B`` for a blank side, ``S`` for a single line, ``D`` for a double line and +``T`` for a thick line. + ++---------------------------+---------------------+--------------------------------+ +| WACS code | Alternate name | Meaning | ++===========================+=====================+================================+ +| .. data:: WACS_D_BTEE | .. data:: WACS_DDBD | double-line bottom tee | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_HLINE | .. data:: WACS_BDBD | double-line horizontal line | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_LLCORNER | .. data:: WACS_DDBB | double-line lower-left corner | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_LRCORNER | .. data:: WACS_DBBD | double-line lower-right corner | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_LTEE | .. data:: WACS_DDDB | double-line left tee | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_PLUS | .. data:: WACS_DDDD | double-line big plus sign | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_RTEE | .. data:: WACS_DBDD | double-line right tee | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_TTEE | .. data:: WACS_BDDD | double-line top tee | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_ULCORNER | .. data:: WACS_BDDB | double-line upper-left corner | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_URCORNER | .. data:: WACS_BBDD | double-line upper-right corner | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_D_VLINE | .. data:: WACS_DBDB | double-line vertical line | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_BTEE | .. data:: WACS_TTBT | thick-line bottom tee | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_HLINE | .. data:: WACS_BTBT | thick-line horizontal line | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_LLCORNER | .. data:: WACS_TTBB | thick-line lower-left corner | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_LRCORNER | .. data:: WACS_TBBT | thick-line lower-right corner | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_LTEE | .. data:: WACS_TTTB | thick-line left tee | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_PLUS | .. data:: WACS_TTTT | thick-line big plus sign | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_RTEE | .. data:: WACS_TBTT | thick-line right tee | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_TTEE | .. data:: WACS_BTTT | thick-line top tee | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_ULCORNER | .. data:: WACS_BTTB | thick-line upper-left corner | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_URCORNER | .. data:: WACS_BBTT | thick-line upper-right corner | ++---------------------------+---------------------+--------------------------------+ +| .. data:: WACS_T_VLINE | .. data:: WACS_TBTB | thick-line vertical line | ++---------------------------+---------------------+--------------------------------+ Mouse buttons ~~~~~~~~~~~~~ diff --git a/Doc/whatsnew/3.16.rst b/Doc/whatsnew/3.16.rst index 063755e1eadcb53..a1a8415482b97aa 100644 --- a/Doc/whatsnew/3.16.rst +++ b/Doc/whatsnew/3.16.rst @@ -216,6 +216,11 @@ curses counterpart of :func:`curses.termattrs`. (Contributed by Serhiy Storchaka in :gh:`152332`.) +* Add the ``WACS_*`` constants to the :mod:`curses` module, the counterparts of + the :ref:`ACS_* ` line-drawing codes as + :class:`curses.complexchar` cells. + (Contributed by Serhiy Storchaka in :gh:`155863`.) + * Add the :mod:`curses` functions :func:`curses.alloc_pair`, :func:`curses.find_pair`, :func:`curses.free_pair` and :func:`curses.reset_color_pairs` for dynamic color-pair management, diff --git a/Lib/curses/__init__.py b/Lib/curses/__init__.py index e150c7f932385eb..1e372ecdc831396 100644 --- a/Lib/curses/__init__.py +++ b/Lib/curses/__init__.py @@ -14,8 +14,8 @@ import os as _os import sys as _sys -# Some constants, most notably the ACS_* ones, are only added to the C -# _curses module's dictionary after initscr() is called. (Some +# Some constants, most notably the ACS_* and WACS_* ones, are only added +# to the C _curses module's dictionary after initscr() is called. (Some # versions of SGI's curses don't define values for those constants # until initscr() has been called.) This wrapper function calls the # underlying C initscr(), and then copies the constants from the @@ -30,13 +30,13 @@ def initscr(): fd=_sys.__stdout__.fileno()) stdscr = _curses.initscr() for key, value in _curses.__dict__.items(): - if key.startswith('ACS_') or key in ('LINES', 'COLS'): + if key.startswith(('ACS_', 'WACS_')) or key in ('LINES', 'COLS'): setattr(curses, key, value) return stdscr -# newterm() is wrapped for the same reason as initscr(): the ACS_* constants -# and LINES/COLS only become available once a terminal is initialized, and are -# then copied to the curses package's dictionary. +# newterm() is wrapped for the same reason as initscr(): the ACS_* and WACS_* +# constants and LINES/COLS only become available once a terminal is +# initialized, and are then copied to the curses package's dictionary. try: newterm @@ -47,7 +47,7 @@ def newterm(type=None, fd=None, infd=None, /): import _curses, curses screen = _curses.newterm(type, fd, infd) for key, value in _curses.__dict__.items(): - if key.startswith('ACS_') or key in ('LINES', 'COLS'): + if key.startswith(('ACS_', 'WACS_')) or key in ('LINES', 'COLS'): setattr(curses, key, value) return screen diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index d87374a298fc337..9ffba543586e353 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -57,6 +57,23 @@ def wrapped(self, *args, **kwargs): return wrapped +# The WACS_* double-line and thick-line character cells, without the common +# prefix, paired with the alternate name spelling out their four sides +# (blank, double or thick, clockwise from the top). +WACS_LINE_ALIASES = [ + ('D_ULCORNER', 'BDDB'), ('D_LLCORNER', 'DDBB'), + ('D_URCORNER', 'BBDD'), ('D_LRCORNER', 'DBBD'), + ('D_LTEE', 'DDDB'), ('D_RTEE', 'DBDD'), + ('D_BTEE', 'DDBD'), ('D_TTEE', 'BDDD'), + ('D_HLINE', 'BDBD'), ('D_VLINE', 'DBDB'), ('D_PLUS', 'DDDD'), + ('T_ULCORNER', 'BTTB'), ('T_LLCORNER', 'TTBB'), + ('T_URCORNER', 'BBTT'), ('T_LRCORNER', 'TBBT'), + ('T_LTEE', 'TTTB'), ('T_RTEE', 'TBTT'), + ('T_BTEE', 'TTBT'), ('T_TTEE', 'BTTT'), + ('T_HLINE', 'BTBT'), ('T_VLINE', 'TBTB'), ('T_PLUS', 'TTTT'), +] + + def requires_colors(test): @functools.wraps(test) def wrapped(self, *args, **kwargs): @@ -470,6 +487,72 @@ def test_wide_characters(self): # border() and box() cannot mix integer and wide-string characters. self.assertRaises(TypeError, stdscr.box, vline, ord('-')) + @requires_wide_build + def test_wacs_constants(self): + # Every ACS_* code has a WACS_* character cell counterpart, plus the + # double-line and thick-line codes, which have no ACS_* counterpart. + acs = {name.removeprefix('ACS_') + for name in dir(curses) if name.startswith('ACS_')} + wacs = {name.removeprefix('WACS_') + for name in dir(curses) if name.startswith('WACS_')} + extra = {name for pair in WACS_LINE_ALIASES for name in pair} + self.assertEqual(wacs - extra, acs) + for name in sorted(wacs): + with self.subTest(name=name): + self.assertIsInstance(getattr(curses, 'WACS_' + name), + curses.complexchar) + # The alternate names refer to the same cells. + self.assertEqual(curses.WACS_BSSB, curses.WACS_ULCORNER) + self.assertEqual(curses.WACS_BSBS, curses.WACS_HLINE) + self.assertEqual(curses.WACS_SBSB, curses.WACS_VLINE) + self.assertEqual(curses.WACS_SSSS, curses.WACS_PLUS) + + @requires_wide_build + def test_wacs_line_constants(self): + # The double-line and thick-line codes are optional, but a supporting + # implementation provides the whole family under both names. + present = [name for name, alias in WACS_LINE_ALIASES + if hasattr(curses, 'WACS_' + name)] + if not present: + self.skipTest('requires double-line and thick-line characters') + self.assertEqual(len(present), len(WACS_LINE_ALIASES)) + for name, alias in WACS_LINE_ALIASES: + with self.subTest(name=name): + cell = getattr(curses, 'WACS_' + name) + self.assertIsInstance(cell, curses.complexchar) + self.assertEqual(getattr(curses, 'WACS_' + alias), cell) + # They are distinct from the single-line characters. + self.assertNotEqual(curses.WACS_D_HLINE, curses.WACS_HLINE) + self.assertNotEqual(curses.WACS_T_HLINE, curses.WACS_HLINE) + self.assertNotEqual(curses.WACS_D_HLINE, curses.WACS_T_HLINE) + stdscr = self.stdscr + stdscr.border(curses.WACS_D_VLINE, curses.WACS_D_VLINE, + curses.WACS_D_HLINE, curses.WACS_D_HLINE, + curses.WACS_D_ULCORNER, curses.WACS_D_URCORNER, + curses.WACS_D_LLCORNER, curses.WACS_D_LRCORNER) + self.assertEqual(stdscr.in_wch(0, 0), curses.WACS_D_ULCORNER) + self.assertEqual(stdscr.in_wch(0, 1), curses.WACS_D_HLINE) + + @requires_wide_build + def test_wacs_in_cell_methods(self): + # A WACS_* cell can be used wherever a character cell is accepted. + stdscr = self.stdscr + stdscr.addch(0, 0, curses.WACS_ULCORNER) + self.assertEqual(stdscr.in_wch(0, 0), curses.WACS_ULCORNER) + stdscr.insch(1, 0, curses.WACS_DIAMOND) + self.assertEqual(stdscr.in_wch(1, 0), curses.WACS_DIAMOND) + stdscr.hline(2, 0, curses.WACS_HLINE, 5) + self.assertEqual(stdscr.in_wch(2, 4), curses.WACS_HLINE) + stdscr.vline(3, 0, curses.WACS_VLINE, 3) + self.assertEqual(stdscr.in_wch(5, 0), curses.WACS_VLINE) + stdscr.border(curses.WACS_VLINE, curses.WACS_VLINE, + curses.WACS_HLINE, curses.WACS_HLINE, + curses.WACS_ULCORNER, curses.WACS_URCORNER, + curses.WACS_LLCORNER, curses.WACS_LRCORNER) + self.assertEqual(stdscr.in_wch(0, 0), curses.WACS_ULCORNER) + stdscr.box(curses.WACS_VLINE, curses.WACS_HLINE) + self.assertEqual(stdscr.in_wch(0, 1), curses.WACS_HLINE) + def test_complexchar_in_cell_methods(self): # Every single-character-cell method also accepts a complexchar, whose # attributes and color pair come from the cell itself. diff --git a/Misc/NEWS.d/next/Library/2026-08-15-17-40-12.gh-issue-155863.Kw3Vqp.rst b/Misc/NEWS.d/next/Library/2026-08-15-17-40-12.gh-issue-155863.Kw3Vqp.rst new file mode 100644 index 000000000000000..1266fbba5cc2325 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-08-15-17-40-12.gh-issue-155863.Kw3Vqp.rst @@ -0,0 +1,4 @@ +Add the ``WACS_*`` constants to the :mod:`curses` module. They are the +counterparts of the ``ACS_*`` line-drawing codes as :class:`curses.complexchar` +cells, and are added, like the latter, by :func:`curses.initscr` and +:func:`curses.newterm`. diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 383de378670ea97..e786b792aa8d32f 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -6555,6 +6555,179 @@ curses_init_dict(PyObject *module) SetDictInt("ACS_STERLING", (ACS_STERLING)); #endif +#ifdef HAVE_NCURSESW + /* The same graphic symbols as character cells, for the methods that take + a complexchar. Unlike the ACS_* codes, these are not restricted to the + 8-bit alternate character set. */ + cursesmodule_state *state = get_cursesmodule_state(module); +#define SetDictWACS(NAME, VALUE) \ + do { \ + PyObject *value = PyCursesComplexChar_New(state, (VALUE)); \ + if (value == NULL) { \ + return -1; \ + } \ + int rc = PyDict_SetItemString(module_dict, (NAME), value); \ + Py_DECREF(value); \ + if (rc < 0) { \ + return -1; \ + } \ + } while (0) + + SetDictWACS("WACS_ULCORNER", WACS_ULCORNER); + SetDictWACS("WACS_LLCORNER", WACS_LLCORNER); + SetDictWACS("WACS_URCORNER", WACS_URCORNER); + SetDictWACS("WACS_LRCORNER", WACS_LRCORNER); + SetDictWACS("WACS_LTEE", WACS_LTEE); + SetDictWACS("WACS_RTEE", WACS_RTEE); + SetDictWACS("WACS_BTEE", WACS_BTEE); + SetDictWACS("WACS_TTEE", WACS_TTEE); + SetDictWACS("WACS_HLINE", WACS_HLINE); + SetDictWACS("WACS_VLINE", WACS_VLINE); + SetDictWACS("WACS_PLUS", WACS_PLUS); + SetDictWACS("WACS_S1", WACS_S1); + SetDictWACS("WACS_S9", WACS_S9); + SetDictWACS("WACS_DIAMOND", WACS_DIAMOND); + SetDictWACS("WACS_CKBOARD", WACS_CKBOARD); + SetDictWACS("WACS_DEGREE", WACS_DEGREE); + SetDictWACS("WACS_PLMINUS", WACS_PLMINUS); + SetDictWACS("WACS_BULLET", WACS_BULLET); + SetDictWACS("WACS_LARROW", WACS_LARROW); + SetDictWACS("WACS_RARROW", WACS_RARROW); + SetDictWACS("WACS_DARROW", WACS_DARROW); + SetDictWACS("WACS_UARROW", WACS_UARROW); + SetDictWACS("WACS_BOARD", WACS_BOARD); + SetDictWACS("WACS_LANTERN", WACS_LANTERN); + SetDictWACS("WACS_BLOCK", WACS_BLOCK); + + SetDictWACS("WACS_BSSB", WACS_ULCORNER); + SetDictWACS("WACS_SSBB", WACS_LLCORNER); + SetDictWACS("WACS_BBSS", WACS_URCORNER); + SetDictWACS("WACS_SBBS", WACS_LRCORNER); + SetDictWACS("WACS_SBSS", WACS_RTEE); + SetDictWACS("WACS_SSSB", WACS_LTEE); + SetDictWACS("WACS_SSBS", WACS_BTEE); + SetDictWACS("WACS_BSSS", WACS_TTEE); + SetDictWACS("WACS_BSBS", WACS_HLINE); + SetDictWACS("WACS_SBSB", WACS_VLINE); + SetDictWACS("WACS_SSSS", WACS_PLUS); + + /* The following are never available with strict SYSV curses */ +#ifdef WACS_S3 + SetDictWACS("WACS_S3", WACS_S3); +#endif +#ifdef WACS_S7 + SetDictWACS("WACS_S7", WACS_S7); +#endif +#ifdef WACS_LEQUAL + SetDictWACS("WACS_LEQUAL", WACS_LEQUAL); +#endif +#ifdef WACS_GEQUAL + SetDictWACS("WACS_GEQUAL", WACS_GEQUAL); +#endif +#ifdef WACS_PI + SetDictWACS("WACS_PI", WACS_PI); +#endif +#ifdef WACS_NEQUAL + SetDictWACS("WACS_NEQUAL", WACS_NEQUAL); +#endif +#ifdef WACS_STERLING + SetDictWACS("WACS_STERLING", WACS_STERLING); +#endif + + /* Double-line and thick-line symbols have no ACS_* counterpart, and are + only provided by some implementations. */ +#ifdef WACS_D_ULCORNER + SetDictWACS("WACS_D_ULCORNER", WACS_D_ULCORNER); + SetDictWACS("WACS_BDDB", WACS_D_ULCORNER); +#endif +#ifdef WACS_D_LLCORNER + SetDictWACS("WACS_D_LLCORNER", WACS_D_LLCORNER); + SetDictWACS("WACS_DDBB", WACS_D_LLCORNER); +#endif +#ifdef WACS_D_URCORNER + SetDictWACS("WACS_D_URCORNER", WACS_D_URCORNER); + SetDictWACS("WACS_BBDD", WACS_D_URCORNER); +#endif +#ifdef WACS_D_LRCORNER + SetDictWACS("WACS_D_LRCORNER", WACS_D_LRCORNER); + SetDictWACS("WACS_DBBD", WACS_D_LRCORNER); +#endif +#ifdef WACS_D_LTEE + SetDictWACS("WACS_D_LTEE", WACS_D_LTEE); + SetDictWACS("WACS_DDDB", WACS_D_LTEE); +#endif +#ifdef WACS_D_RTEE + SetDictWACS("WACS_D_RTEE", WACS_D_RTEE); + SetDictWACS("WACS_DBDD", WACS_D_RTEE); +#endif +#ifdef WACS_D_BTEE + SetDictWACS("WACS_D_BTEE", WACS_D_BTEE); + SetDictWACS("WACS_DDBD", WACS_D_BTEE); +#endif +#ifdef WACS_D_TTEE + SetDictWACS("WACS_D_TTEE", WACS_D_TTEE); + SetDictWACS("WACS_BDDD", WACS_D_TTEE); +#endif +#ifdef WACS_D_HLINE + SetDictWACS("WACS_D_HLINE", WACS_D_HLINE); + SetDictWACS("WACS_BDBD", WACS_D_HLINE); +#endif +#ifdef WACS_D_VLINE + SetDictWACS("WACS_D_VLINE", WACS_D_VLINE); + SetDictWACS("WACS_DBDB", WACS_D_VLINE); +#endif +#ifdef WACS_D_PLUS + SetDictWACS("WACS_D_PLUS", WACS_D_PLUS); + SetDictWACS("WACS_DDDD", WACS_D_PLUS); +#endif + +#ifdef WACS_T_ULCORNER + SetDictWACS("WACS_T_ULCORNER", WACS_T_ULCORNER); + SetDictWACS("WACS_BTTB", WACS_T_ULCORNER); +#endif +#ifdef WACS_T_LLCORNER + SetDictWACS("WACS_T_LLCORNER", WACS_T_LLCORNER); + SetDictWACS("WACS_TTBB", WACS_T_LLCORNER); +#endif +#ifdef WACS_T_URCORNER + SetDictWACS("WACS_T_URCORNER", WACS_T_URCORNER); + SetDictWACS("WACS_BBTT", WACS_T_URCORNER); +#endif +#ifdef WACS_T_LRCORNER + SetDictWACS("WACS_T_LRCORNER", WACS_T_LRCORNER); + SetDictWACS("WACS_TBBT", WACS_T_LRCORNER); +#endif +#ifdef WACS_T_LTEE + SetDictWACS("WACS_T_LTEE", WACS_T_LTEE); + SetDictWACS("WACS_TTTB", WACS_T_LTEE); +#endif +#ifdef WACS_T_RTEE + SetDictWACS("WACS_T_RTEE", WACS_T_RTEE); + SetDictWACS("WACS_TBTT", WACS_T_RTEE); +#endif +#ifdef WACS_T_BTEE + SetDictWACS("WACS_T_BTEE", WACS_T_BTEE); + SetDictWACS("WACS_TTBT", WACS_T_BTEE); +#endif +#ifdef WACS_T_TTEE + SetDictWACS("WACS_T_TTEE", WACS_T_TTEE); + SetDictWACS("WACS_BTTT", WACS_T_TTEE); +#endif +#ifdef WACS_T_HLINE + SetDictWACS("WACS_T_HLINE", WACS_T_HLINE); + SetDictWACS("WACS_BTBT", WACS_T_HLINE); +#endif +#ifdef WACS_T_VLINE + SetDictWACS("WACS_T_VLINE", WACS_T_VLINE); + SetDictWACS("WACS_TBTB", WACS_T_VLINE); +#endif +#ifdef WACS_T_PLUS + SetDictWACS("WACS_T_PLUS", WACS_T_PLUS); + SetDictWACS("WACS_TTTT", WACS_T_PLUS); +#endif +#undef SetDictWACS +#endif /* HAVE_NCURSESW */ + SetDictInt("LINES", LINES); SetDictInt("COLS", COLS); #undef SetDictInt