|
| 1 | +"""Minimal '_curses' module, the low-level interface for curses module |
| 2 | +which is not meant to be used directly. |
| 3 | +
|
| 4 | +Based on ctypes. It's too incomplete to be really called '_curses', so |
| 5 | +to use it, you have to import it and stick it in sys.modules['_curses'] |
| 6 | +manually. |
| 7 | +
|
| 8 | +Note that there is also a built-in module _minimal_curses which will |
| 9 | +hide this one if compiled in. |
| 10 | +""" |
| 11 | + |
| 12 | +import ctypes |
| 13 | +import ctypes.util |
| 14 | + |
| 15 | + |
| 16 | +class error(Exception): |
| 17 | + pass |
| 18 | + |
| 19 | + |
| 20 | +def _find_clib(): |
| 21 | + trylibs = ["ncursesw", "ncurses", "curses"] |
| 22 | + |
| 23 | + for lib in trylibs: |
| 24 | + path = ctypes.util.find_library(lib) |
| 25 | + if path: |
| 26 | + return path |
| 27 | + raise ModuleNotFoundError("curses library not found", name="_pyrepl._minimal_curses") |
| 28 | + |
| 29 | + |
| 30 | +_clibpath = _find_clib() |
| 31 | +clib = ctypes.cdll.LoadLibrary(_clibpath) |
| 32 | + |
| 33 | +clib.setupterm.argtypes = [ctypes.c_char_p, ctypes.c_int, ctypes.POINTER(ctypes.c_int)] |
| 34 | +clib.setupterm.restype = ctypes.c_int |
| 35 | + |
| 36 | +clib.tigetstr.argtypes = [ctypes.c_char_p] |
| 37 | +clib.tigetstr.restype = ctypes.POINTER(ctypes.c_char) |
| 38 | + |
| 39 | +clib.tparm.argtypes = [ctypes.c_char_p] + 9 * [ctypes.c_int] # type: ignore[operator] |
| 40 | +clib.tparm.restype = ctypes.c_char_p |
| 41 | + |
| 42 | +OK = 0 |
| 43 | +ERR = -1 |
| 44 | + |
| 45 | +# ____________________________________________________________ |
| 46 | + |
| 47 | + |
| 48 | +def setupterm(termstr, fd): |
| 49 | + err = ctypes.c_int(0) |
| 50 | + result = clib.setupterm(termstr, fd, ctypes.byref(err)) |
| 51 | + if result == ERR: |
| 52 | + raise error("setupterm() failed (err=%d)" % err.value) |
| 53 | + |
| 54 | + |
| 55 | +def tigetstr(cap): |
| 56 | + if not isinstance(cap, bytes): |
| 57 | + cap = cap.encode("ascii") |
| 58 | + result = clib.tigetstr(cap) |
| 59 | + if ctypes.cast(result, ctypes.c_void_p).value == ERR: |
| 60 | + return None |
| 61 | + return ctypes.cast(result, ctypes.c_char_p).value |
| 62 | + |
| 63 | + |
| 64 | +def tparm(str, i1=0, i2=0, i3=0, i4=0, i5=0, i6=0, i7=0, i8=0, i9=0): |
| 65 | + result = clib.tparm(str, i1, i2, i3, i4, i5, i6, i7, i8, i9) |
| 66 | + if result is None: |
| 67 | + raise error("tparm() returned NULL") |
| 68 | + return result |
0 commit comments