xref: /third_party/python/Lib/curses/__init__.py (revision 7db96d56)
17db96d56Sopenharmony_ci"""curses
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ciThe main package for curses support for Python.  Normally used by importing
47db96d56Sopenharmony_cithe package, and perhaps a particular module inside it.
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci   import curses
77db96d56Sopenharmony_ci   from curses import textpad
87db96d56Sopenharmony_ci   curses.initscr()
97db96d56Sopenharmony_ci   ...
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci"""
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_cifrom _curses import *
147db96d56Sopenharmony_ciimport os as _os
157db96d56Sopenharmony_ciimport sys as _sys
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci# Some constants, most notably the ACS_* ones, are only added to the C
187db96d56Sopenharmony_ci# _curses module's dictionary after initscr() is called.  (Some
197db96d56Sopenharmony_ci# versions of SGI's curses don't define values for those constants
207db96d56Sopenharmony_ci# until initscr() has been called.)  This wrapper function calls the
217db96d56Sopenharmony_ci# underlying C initscr(), and then copies the constants from the
227db96d56Sopenharmony_ci# _curses module to the curses package's dictionary.  Don't do 'from
237db96d56Sopenharmony_ci# curses import *' if you'll be needing the ACS_* constants.
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_cidef initscr():
267db96d56Sopenharmony_ci    import _curses, curses
277db96d56Sopenharmony_ci    # we call setupterm() here because it raises an error
287db96d56Sopenharmony_ci    # instead of calling exit() in error cases.
297db96d56Sopenharmony_ci    setupterm(term=_os.environ.get("TERM", "unknown"),
307db96d56Sopenharmony_ci              fd=_sys.__stdout__.fileno())
317db96d56Sopenharmony_ci    stdscr = _curses.initscr()
327db96d56Sopenharmony_ci    for key, value in _curses.__dict__.items():
337db96d56Sopenharmony_ci        if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'):
347db96d56Sopenharmony_ci            setattr(curses, key, value)
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci    return stdscr
377db96d56Sopenharmony_ci
387db96d56Sopenharmony_ci# This is a similar wrapper for start_color(), which adds the COLORS and
397db96d56Sopenharmony_ci# COLOR_PAIRS variables which are only available after start_color() is
407db96d56Sopenharmony_ci# called.
417db96d56Sopenharmony_ci
427db96d56Sopenharmony_cidef start_color():
437db96d56Sopenharmony_ci    import _curses, curses
447db96d56Sopenharmony_ci    retval = _curses.start_color()
457db96d56Sopenharmony_ci    if hasattr(_curses, 'COLORS'):
467db96d56Sopenharmony_ci        curses.COLORS = _curses.COLORS
477db96d56Sopenharmony_ci    if hasattr(_curses, 'COLOR_PAIRS'):
487db96d56Sopenharmony_ci        curses.COLOR_PAIRS = _curses.COLOR_PAIRS
497db96d56Sopenharmony_ci    return retval
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_ci# Import Python has_key() implementation if _curses doesn't contain has_key()
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_citry:
547db96d56Sopenharmony_ci    has_key
557db96d56Sopenharmony_ciexcept NameError:
567db96d56Sopenharmony_ci    from .has_key import has_key
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci# Wrapper for the entire curses-based application.  Runs a function which
597db96d56Sopenharmony_ci# should be the rest of your curses-based application.  If the application
607db96d56Sopenharmony_ci# raises an exception, wrapper() will restore the terminal to a sane state so
617db96d56Sopenharmony_ci# you can read the resulting traceback.
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_cidef wrapper(func, /, *args, **kwds):
647db96d56Sopenharmony_ci    """Wrapper function that initializes curses and calls another function,
657db96d56Sopenharmony_ci    restoring normal keyboard/screen behavior on error.
667db96d56Sopenharmony_ci    The callable object 'func' is then passed the main window 'stdscr'
677db96d56Sopenharmony_ci    as its first argument, followed by any other arguments passed to
687db96d56Sopenharmony_ci    wrapper().
697db96d56Sopenharmony_ci    """
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci    try:
727db96d56Sopenharmony_ci        # Initialize curses
737db96d56Sopenharmony_ci        stdscr = initscr()
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ci        # Turn off echoing of keys, and enter cbreak mode,
767db96d56Sopenharmony_ci        # where no buffering is performed on keyboard input
777db96d56Sopenharmony_ci        noecho()
787db96d56Sopenharmony_ci        cbreak()
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ci        # In keypad mode, escape sequences for special keys
817db96d56Sopenharmony_ci        # (like the cursor keys) will be interpreted and
827db96d56Sopenharmony_ci        # a special value like curses.KEY_LEFT will be returned
837db96d56Sopenharmony_ci        stdscr.keypad(1)
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci        # Start color, too.  Harmless if the terminal doesn't have
867db96d56Sopenharmony_ci        # color; user can test with has_color() later on.  The try/catch
877db96d56Sopenharmony_ci        # works around a minor bit of over-conscientiousness in the curses
887db96d56Sopenharmony_ci        # module -- the error return from C start_color() is ignorable.
897db96d56Sopenharmony_ci        try:
907db96d56Sopenharmony_ci            start_color()
917db96d56Sopenharmony_ci        except:
927db96d56Sopenharmony_ci            pass
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_ci        return func(stdscr, *args, **kwds)
957db96d56Sopenharmony_ci    finally:
967db96d56Sopenharmony_ci        # Set everything back to normal
977db96d56Sopenharmony_ci        if 'stdscr' in locals():
987db96d56Sopenharmony_ci            stdscr.keypad(0)
997db96d56Sopenharmony_ci            echo()
1007db96d56Sopenharmony_ci            nocbreak()
1017db96d56Sopenharmony_ci            endwin()
102