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