Skip to content

Commit 9b0c969

Browse files
committed
Add example implementation for termbox API
Commiting raw files from termbox revision b20c0a11
1 parent 383ee1c commit 9b0c969

File tree

3 files changed

+431
-0
lines changed

3 files changed

+431
-0
lines changed

examples/termbox/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
API of `termbox` Python module implemented in `tld`.
2+
3+
The code here are modified files from
4+
[termbox repository](https://github.com/nsf/termbox/), so please consult
5+
it for the license and other info.
6+
7+
8+
The code consists of two part - `termbox.py` module with API, translation
9+
of official binding form the description below into `tld`:
10+
11+
https://github.com/nsf/termbox/blob/b20c0a11/src/python/termboxmodule.pyx
12+
13+
And the example `termboxtest.py` which is copied verbatim from:
14+
15+
https://github.com/nsf/termbox/blob/b20c0a11/test_termboxmodule.py
16+

examples/termbox/termbox.py

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
"""Termbox library python binding.
2+
3+
This is a binding module for termbox library.
4+
"""
5+
6+
include "termboxconfig.pyx"
7+
8+
## No unichr in python3, use chr instead.
9+
if PY_MAJOR_VERSION == 3:
10+
unichr = chr
11+
12+
cdef extern from "stdint.h":
13+
ctypedef unsigned int uint32_t
14+
ctypedef unsigned short uint16_t
15+
ctypedef signed int int32_t
16+
17+
cdef extern from "../termbox.h":
18+
struct tb_event:
19+
uint16_t type
20+
uint32_t ch
21+
uint16_t key
22+
uint16_t mod
23+
int32_t w
24+
int32_t h
25+
int32_t x
26+
int32_t y
27+
int tb_init()
28+
void tb_shutdown()
29+
void tb_present()
30+
void tb_clear()
31+
void tb_change_cell(int x, int y, uint32_t ch, uint16_t fg, uint16_t bg)
32+
int tb_width()
33+
int tb_height()
34+
void tb_set_cursor(int x, int y)
35+
int tb_select_input_mode(int mode)
36+
int tb_select_output_mode(int mode)
37+
int tb_peek_event(tb_event *event, int timeout) nogil
38+
int tb_poll_event(tb_event *event) nogil
39+
40+
class TermboxException(Exception):
41+
def __init__(self, msg):
42+
self.msg = msg
43+
def __str__(self):
44+
return self.msg
45+
46+
import threading
47+
48+
__instance = None
49+
50+
# keys ----------------------------------
51+
KEY_F1 = (0xFFFF-0)
52+
KEY_F2 = (0xFFFF-1)
53+
KEY_F3 = (0xFFFF-2)
54+
KEY_F4 = (0xFFFF-3)
55+
KEY_F5 = (0xFFFF-4)
56+
KEY_F6 = (0xFFFF-5)
57+
KEY_F7 = (0xFFFF-6)
58+
KEY_F8 = (0xFFFF-7)
59+
KEY_F9 = (0xFFFF-8)
60+
KEY_F10 = (0xFFFF-9)
61+
KEY_F11 = (0xFFFF-10)
62+
KEY_F12 = (0xFFFF-11)
63+
KEY_INSERT = (0xFFFF-12)
64+
KEY_DELETE = (0xFFFF-13)
65+
KEY_HOME = (0xFFFF-14)
66+
KEY_END = (0xFFFF-15)
67+
KEY_PGUP = (0xFFFF-16)
68+
KEY_PGDN = (0xFFFF-17)
69+
KEY_ARROW_UP = (0xFFFF-18)
70+
KEY_ARROW_DOWN = (0xFFFF-19)
71+
KEY_ARROW_LEFT = (0xFFFF-20)
72+
KEY_ARROW_RIGHT = (0xFFFF-21)
73+
KEY_MOUSE_LEFT =(0xFFFF-22)
74+
KEY_MOUSE_RIGHT =(0xFFFF-23)
75+
KEY_MOUSE_MIDDLE =(0xFFFF-24)
76+
KEY_MOUSE_RELEASE =(0xFFFF-25)
77+
KEY_MOUSE_WHEEL_UP =(0xFFFF-26)
78+
KEY_MOUSE_WHEEL_DOWN =(0xFFFF-27)
79+
80+
KEY_CTRL_TILDE = 0x00
81+
KEY_CTRL_2 = 0x00
82+
KEY_CTRL_A = 0x01
83+
KEY_CTRL_B = 0x02
84+
KEY_CTRL_C = 0x03
85+
KEY_CTRL_D = 0x04
86+
KEY_CTRL_E = 0x05
87+
KEY_CTRL_F = 0x06
88+
KEY_CTRL_G = 0x07
89+
KEY_BACKSPACE = 0x08
90+
KEY_CTRL_H = 0x08
91+
KEY_TAB = 0x09
92+
KEY_CTRL_I = 0x09
93+
KEY_CTRL_J = 0x0A
94+
KEY_CTRL_K = 0x0B
95+
KEY_CTRL_L = 0x0C
96+
KEY_ENTER = 0x0D
97+
KEY_CTRL_M = 0x0D
98+
KEY_CTRL_N = 0x0E
99+
KEY_CTRL_O = 0x0F
100+
KEY_CTRL_P = 0x10
101+
KEY_CTRL_Q = 0x11
102+
KEY_CTRL_R = 0x12
103+
KEY_CTRL_S = 0x13
104+
KEY_CTRL_T = 0x14
105+
KEY_CTRL_U = 0x15
106+
KEY_CTRL_V = 0x16
107+
KEY_CTRL_W = 0x17
108+
KEY_CTRL_X = 0x18
109+
KEY_CTRL_Y = 0x19
110+
KEY_CTRL_Z = 0x1A
111+
KEY_ESC = 0x1B
112+
KEY_CTRL_LSQ_BRACKET = 0x1B
113+
KEY_CTRL_3 = 0x1B
114+
KEY_CTRL_4 = 0x1C
115+
KEY_CTRL_BACKSLASH = 0x1C
116+
KEY_CTRL_5 = 0x1D
117+
KEY_CTRL_RSQ_BRACKET = 0x1D
118+
KEY_CTRL_6 = 0x1E
119+
KEY_CTRL_7 = 0x1F
120+
KEY_CTRL_SLASH = 0x1F
121+
KEY_CTRL_UNDERSCORE = 0x1F
122+
KEY_SPACE = 0x20
123+
KEY_BACKSPACE2 = 0x7F
124+
KEY_CTRL_8 = 0x7F
125+
126+
MOD_ALT = 0x01
127+
128+
# attributes ----------------------
129+
130+
DEFAULT = 0x00
131+
BLACK = 0x01
132+
RED = 0x02
133+
GREEN = 0x03
134+
YELLOW = 0x04
135+
BLUE = 0x05
136+
MAGENTA = 0x06
137+
CYAN = 0x07
138+
WHITE = 0x08
139+
140+
BOLD = 0x10
141+
UNDERLINE = 0x20
142+
REVERSE = 0x40
143+
144+
# misc ----------------------------
145+
146+
HIDE_CURSOR = -1
147+
INPUT_CURRENT = 0
148+
INPUT_ESC = 1
149+
INPUT_ALT = 2
150+
OUTPUT_CURRENT = 0
151+
OUTPUT_NORMAL = 1
152+
OUTPUT_256 = 2
153+
OUTPUT_216 = 3
154+
OUTPUT_GRAYSCALE = 4
155+
EVENT_KEY = 1
156+
EVENT_RESIZE = 2
157+
EVENT_MOUSE = 3
158+
159+
cdef class Termbox:
160+
cdef int created
161+
cdef object _poll_lock
162+
163+
def __cinit__(self):
164+
cdef int ret
165+
global __instance
166+
167+
self.created = 0
168+
self._poll_lock = threading.Lock()
169+
170+
if __instance:
171+
raise TermboxException("It is possible to create only one instance of Termbox")
172+
173+
ret = tb_init()
174+
ret = 1
175+
if ret < 0:
176+
raise TermboxException("Failed to init Termbox")
177+
__instance = self
178+
self.created = 1
179+
180+
def __dealloc__(self):
181+
self.close()
182+
183+
def __del__(self):
184+
self.close()
185+
186+
def __exit__(self, *args):#t, value, traceback):
187+
self.close()
188+
189+
def __enter__(self):
190+
return self
191+
192+
def close(self):
193+
global __instance
194+
if self.created:
195+
tb_shutdown()
196+
self.created = 0
197+
__instance = None
198+
199+
def present(self):
200+
"""Sync state of the internal cell buffer with the terminal.
201+
"""
202+
tb_present()
203+
pass
204+
205+
def change_cell(self, int x, int y, int ch, uint16_t fg, uint16_t bg):
206+
"""Change cell in position (x;y).
207+
"""
208+
tb_change_cell(x, y, ch, fg, bg)
209+
210+
def width(self):
211+
"""Returns width of the terminal screen.
212+
"""
213+
return int(tb_width())
214+
215+
def height(self):
216+
"""Return height of the terminal screen.
217+
"""
218+
return int(tb_height())
219+
220+
def clear(self):
221+
"""Clear the internal cell buffer.
222+
"""
223+
tb_clear()
224+
225+
def set_cursor(self, int x, int y):
226+
"""Set cursor position to (x;y).
227+
228+
Set both arguments to HIDE_CURSOR or use 'hide_cursor' function to hide it.
229+
"""
230+
tb_set_cursor(x, y)
231+
232+
def hide_cursor(self):
233+
"""Hide cursor.
234+
"""
235+
tb_set_cursor(-1, -1)
236+
237+
def select_input_mode(self, int mode):
238+
"""Select preferred input mode: INPUT_ESC or INPUT_ALT.
239+
240+
INPUT_CURRENT returns the selected mode without changing anything.
241+
"""
242+
return int(tb_select_input_mode(mode))
243+
244+
def select_output_mode(self, int mode):
245+
"""Select preferred output mode: one of OUTPUT_* constants.
246+
247+
OUTPUT_CURRENT returns the selected mode without changing anything.
248+
"""
249+
return int(tb_select_output_mode(mode))
250+
251+
def peek_event(self, int timeout=0):
252+
"""Wait for an event up to 'timeout' milliseconds and return it.
253+
254+
Returns None if there was no event and timeout is expired.
255+
Returns a tuple otherwise: (type, unicode character, key, mod, width, height, mousex, mousey).
256+
"""
257+
cdef tb_event e
258+
cdef int result
259+
with self._poll_lock:
260+
with nogil:
261+
result = tb_peek_event(&e, timeout)
262+
assert(result >= 0)
263+
if result == 0:
264+
return None
265+
if e.ch:
266+
uch = unichr(e.ch)
267+
else:
268+
uch = None
269+
return (e.type, uch, e.key, e.mod, e.w, e.h, e.x, e.y)
270+
271+
def poll_event(self):
272+
"""Wait for an event and return it.
273+
274+
Returns a tuple: (type, unicode character, key, mod, width, height, mousex, mousey).
275+
"""
276+
cdef tb_event e
277+
cdef int result
278+
with self._poll_lock:
279+
with nogil:
280+
result = tb_poll_event(&e)
281+
assert(result >= 0)
282+
if e.ch:
283+
uch = unichr(e.ch)
284+
else:
285+
uch = None
286+
return (e.type, uch, e.key, e.mod, e.w, e.h, e.x, e.y)

0 commit comments

Comments
 (0)