"""Termbox library python binding.
This is a binding module for termbox library.
"""
include "termboxconfig.pyx"
## No unichr in python3, use chr instead.
if PY_MAJOR_VERSION == 3:
unichr = chr
cdef extern from "stdint.h":
ctypedef unsigned int uint32_t
ctypedef unsigned short uint16_t
ctypedef signed int int32_t
cdef extern from "../termbox.h":
struct tb_event:
uint16_t type
uint32_t ch
uint16_t key
uint16_t mod
int32_t w
int32_t h
int32_t x
int32_t y
int tb_init()
void tb_shutdown()
void tb_present()
void tb_clear()
void tb_change_cell(int x, int y, uint32_t ch, uint16_t fg, uint16_t bg)
int tb_width()
int tb_height()
void tb_set_cursor(int x, int y)
int tb_select_input_mode(int mode)
int tb_select_output_mode(int mode)
int tb_peek_event(tb_event *event, int timeout) nogil
int tb_poll_event(tb_event *event) nogil
class TermboxException(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
import threading
__instance = None
# keys ----------------------------------
KEY_F1 = (0xFFFF-0)
KEY_F2 = (0xFFFF-1)
KEY_F3 = (0xFFFF-2)
KEY_F4 = (0xFFFF-3)
KEY_F5 = (0xFFFF-4)
KEY_F6 = (0xFFFF-5)
KEY_F7 = (0xFFFF-6)
KEY_F8 = (0xFFFF-7)
KEY_F9 = (0xFFFF-8)
KEY_F10 = (0xFFFF-9)
KEY_F11 = (0xFFFF-10)
KEY_F12 = (0xFFFF-11)
KEY_INSERT = (0xFFFF-12)
KEY_DELETE = (0xFFFF-13)
KEY_HOME = (0xFFFF-14)
KEY_END = (0xFFFF-15)
KEY_PGUP = (0xFFFF-16)
KEY_PGDN = (0xFFFF-17)
KEY_ARROW_UP = (0xFFFF-18)
KEY_ARROW_DOWN = (0xFFFF-19)
KEY_ARROW_LEFT = (0xFFFF-20)
KEY_ARROW_RIGHT = (0xFFFF-21)
KEY_MOUSE_LEFT =(0xFFFF-22)
KEY_MOUSE_RIGHT =(0xFFFF-23)
KEY_MOUSE_MIDDLE =(0xFFFF-24)
KEY_MOUSE_RELEASE =(0xFFFF-25)
KEY_MOUSE_WHEEL_UP =(0xFFFF-26)
KEY_MOUSE_WHEEL_DOWN =(0xFFFF-27)
KEY_CTRL_TILDE = 0x00
KEY_CTRL_2 = 0x00
KEY_CTRL_A = 0x01
KEY_CTRL_B = 0x02
KEY_CTRL_C = 0x03
KEY_CTRL_D = 0x04
KEY_CTRL_E = 0x05
KEY_CTRL_F = 0x06
KEY_CTRL_G = 0x07
KEY_BACKSPACE = 0x08
KEY_CTRL_H = 0x08
KEY_TAB = 0x09
KEY_CTRL_I = 0x09
KEY_CTRL_J = 0x0A
KEY_CTRL_K = 0x0B
KEY_CTRL_L = 0x0C
KEY_ENTER = 0x0D
KEY_CTRL_M = 0x0D
KEY_CTRL_N = 0x0E
KEY_CTRL_O = 0x0F
KEY_CTRL_P = 0x10
KEY_CTRL_Q = 0x11
KEY_CTRL_R = 0x12
KEY_CTRL_S = 0x13
KEY_CTRL_T = 0x14
KEY_CTRL_U = 0x15
KEY_CTRL_V = 0x16
KEY_CTRL_W = 0x17
KEY_CTRL_X = 0x18
KEY_CTRL_Y = 0x19
KEY_CTRL_Z = 0x1A
KEY_ESC = 0x1B
KEY_CTRL_LSQ_BRACKET = 0x1B
KEY_CTRL_3 = 0x1B
KEY_CTRL_4 = 0x1C
KEY_CTRL_BACKSLASH = 0x1C
KEY_CTRL_5 = 0x1D
KEY_CTRL_RSQ_BRACKET = 0x1D
KEY_CTRL_6 = 0x1E
KEY_CTRL_7 = 0x1F
KEY_CTRL_SLASH = 0x1F
KEY_CTRL_UNDERSCORE = 0x1F
KEY_SPACE = 0x20
KEY_BACKSPACE2 = 0x7F
KEY_CTRL_8 = 0x7F
MOD_ALT = 0x01
# attributes ----------------------
DEFAULT = 0x00
BLACK = 0x01
RED = 0x02
GREEN = 0x03
YELLOW = 0x04
BLUE = 0x05
MAGENTA = 0x06
CYAN = 0x07
WHITE = 0x08
BOLD = 0x0100
UNDERLINE = 0x0200
REVERSE = 0x0400
# misc ----------------------------
HIDE_CURSOR = -1
INPUT_CURRENT = 0
INPUT_ESC = 1
INPUT_ALT = 2
OUTPUT_CURRENT = 0
OUTPUT_NORMAL = 1
OUTPUT_256 = 2
OUTPUT_216 = 3
OUTPUT_GRAYSCALE = 4
EVENT_KEY = 1
EVENT_RESIZE = 2
EVENT_MOUSE = 3
cdef class Termbox:
cdef int created
cdef object _poll_lock
def __cinit__(self):
cdef int ret
global __instance
self.created = 0
self._poll_lock = threading.Lock()
if __instance:
raise TermboxException("It is possible to create only one instance of Termbox")
ret = tb_init()
ret = 1
if ret < 0:
raise TermboxException("Failed to init Termbox")
__instance = self
self.created = 1
def __dealloc__(self):
self.close()
def __del__(self):
self.close()
def __exit__(self, *args):#t, value, traceback):
self.close()
def __enter__(self):
return self
def close(self):
global __instance
if self.created:
tb_shutdown()
self.created = 0
__instance = None
def present(self):
"""Sync state of the internal cell buffer with the terminal.
"""
tb_present()
pass
def change_cell(self, int x, int y, int ch, uint16_t fg, uint16_t bg):
"""Change cell in position (x;y).
"""
tb_change_cell(x, y, ch, fg, bg)
def width(self):
"""Returns width of the terminal screen.
"""
return int(tb_width())
def height(self):
"""Return height of the terminal screen.
"""
return int(tb_height())
def clear(self):
"""Clear the internal cell buffer.
"""
tb_clear()
def set_cursor(self, int x, int y):
"""Set cursor position to (x;y).
Set both arguments to HIDE_CURSOR or use 'hide_cursor' function to hide it.
"""
tb_set_cursor(x, y)
def hide_cursor(self):
"""Hide cursor.
"""
tb_set_cursor(-1, -1)
def select_input_mode(self, int mode):
"""Select preferred input mode: INPUT_ESC or INPUT_ALT.
INPUT_CURRENT returns the selected mode without changing anything.
"""
return int(tb_select_input_mode(mode))
def select_output_mode(self, int mode):
"""Select preferred output mode: one of OUTPUT_* constants.
OUTPUT_CURRENT returns the selected mode without changing anything.
"""
return int(tb_select_output_mode(mode))
def peek_event(self, int timeout=0):
"""Wait for an event up to 'timeout' milliseconds and return it.
Returns None if there was no event and timeout is expired.
Returns a tuple otherwise: (type, unicode character, key, mod, width, height, mousex, mousey).
"""
cdef tb_event e
cdef int result
with self._poll_lock:
with nogil:
result = tb_peek_event(&e, timeout)
assert(result >= 0)
if result == 0:
return None
if e.ch:
uch = unichr(e.ch)
else:
uch = None
return (e.type, uch, e.key, e.mod, e.w, e.h, e.x, e.y)
def poll_event(self):
"""Wait for an event and return it.
Returns a tuple: (type, unicode character, key, mod, width, height, mousex, mousey).
"""
cdef tb_event e
cdef int result
with self._poll_lock:
with nogil:
result = tb_poll_event(&e)
assert(result >= 0)
if e.ch:
uch = unichr(e.ch)
else:
uch = None
return (e.type, uch, e.key, e.mod, e.w, e.h, e.x, e.y)