├── .gitignore ├── README.md ├── blt.nim ├── blt.nimble └── examples ├── Orbitron Bold.ttf └── test.nim /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore all 2 | * 3 | 4 | # Unignore all with extensions 5 | !*.* 6 | 7 | # Unignore all dirs 8 | !*/ 9 | 10 | ### Above combination will ignore all files without extension ### 11 | 12 | 13 | nimcache/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # blt-nim 2 | Nim bindings to the terminal emulator BearLibTerminal 3 | 4 | ![BearLibTerminal](http://i.imgur.com/apNqlbu.png) 5 | -------------------------------------------------------------------------------- /blt.nim: -------------------------------------------------------------------------------- 1 | {.deadCodeElim: on.} 2 | when defined(windows): 3 | const 4 | libname* = "libbearlibterminal.dll" 5 | elif defined(macosx): 6 | const 7 | libname* = "libbearlibterminal.dylib" 8 | else: 9 | const 10 | libname* = "libbearlibterminal.so" 11 | 12 | # Keyboard scancodes for events/states 13 | 14 | const TK_A* = 0x04 15 | const TK_B* = 0x05 16 | const TK_C* = 0x06 17 | const TK_D* = 0x07 18 | const TK_E* = 0x08 19 | const TK_F* = 0x09 20 | const TK_G* = 0x0A 21 | const TK_H* = 0x0B 22 | const TK_I* = 0x0C 23 | const TK_J* = 0x0D 24 | const TK_K* = 0x0E 25 | const TK_L* = 0x0F 26 | const TK_M* = 0x10 27 | const TK_N* = 0x11 28 | const TK_O* = 0x12 29 | const TK_P* = 0x13 30 | const TK_Q* = 0x14 31 | const TK_R* = 0x15 32 | const TK_S* = 0x16 33 | const TK_T* = 0x17 34 | const TK_U* = 0x18 35 | const TK_V* = 0x19 36 | const TK_W* = 0x1A 37 | const TK_X* = 0x1B 38 | const TK_Y* = 0x1C 39 | const TK_Z* = 0x1D 40 | const TK_1* = 0x1E 41 | const TK_2* = 0x1F 42 | const TK_3* = 0x20 43 | const TK_4* = 0x21 44 | const TK_5* = 0x22 45 | const TK_6* = 0x23 46 | const TK_7* = 0x24 47 | const TK_8* = 0x25 48 | const TK_9* = 0x26 49 | const TK_0* = 0x27 50 | const TK_RETURN* = 0x28 51 | const TK_ENTER* = 0x28 52 | const TK_ESCAPE* = 0x29 53 | const TK_BACKSPACE* = 0x2A 54 | const TK_TAB* = 0x2B 55 | const TK_SPACE* = 0x2C 56 | const TK_MINUS* = 0x2D # - 57 | const TK_EQUALS* = 0x2E # = 58 | const TK_LBRACKET* = 0x2F # [ 59 | const TK_RBRACKET* = 0x30 # ] 60 | const TK_BACKSLASH* = 0x31 # \ 61 | const TK_SEMICOLON* = 0x33 # ; 62 | const TK_APOSTROPHE* = 0x34 # ' 63 | const TK_GRAVE* = 0x35 # ` 64 | const TK_COMMA* = 0x36 # , 65 | const TK_PERIOD* = 0x37 # . 66 | const TK_SLASH* = 0x38 # / 67 | const TK_F1* = 0x3A 68 | const TK_F2* = 0x3B 69 | const TK_F3* = 0x3C 70 | const TK_F4* = 0x3D 71 | const TK_F5* = 0x3E 72 | const TK_F6* = 0x3F 73 | const TK_F7* = 0x40 74 | const TK_F8* = 0x41 75 | const TK_F9* = 0x42 76 | const TK_F10* = 0x43 77 | const TK_F11* = 0x44 78 | const TK_F12* = 0x45 79 | const TK_PAUSE* = 0x48 # Pause/Break 80 | const TK_INSERT* = 0x49 81 | const TK_HOME* = 0x4A 82 | const TK_PAGEUP* = 0x4B 83 | const TK_DELETE* = 0x4C 84 | const TK_END* = 0x4D 85 | const TK_PAGEDOWN* = 0x4E 86 | const TK_RIGHT* = 0x4F # Right arrow 87 | const TK_LEFT* = 0x50 # Left arrow 88 | const TK_DOWN* = 0x51 # Down arrow 89 | const TK_UP* = 0x52 # Up arrow 90 | const TK_KP_DIVIDE* = 0x54 # '/' on numpad 91 | const TK_KP_MULTIPLY* = 0x55 # '*' on numpad 92 | const TK_KP_MINUS* = 0x56 # '-' on numpad 93 | const TK_KP_PLUS* = 0x57 # '+' on numpad 94 | const TK_KP_ENTER* = 0x58 95 | const TK_KP_1* = 0x59 96 | const TK_KP_2* = 0x5A 97 | const TK_KP_3* = 0x5B 98 | const TK_KP_4* = 0x5C 99 | const TK_KP_5* = 0x5D 100 | const TK_KP_6* = 0x5E 101 | const TK_KP_7* = 0x5F 102 | const TK_KP_8* = 0x60 103 | const TK_KP_9* = 0x61 104 | const TK_KP_0* = 0x62 105 | const TK_KP_PERIOD* = 0x63 # '.' on numpad 106 | const TK_SHIFT* = 0x70 107 | const TK_CONTROL* = 0x71 108 | const TK_ALT* = 0x72 109 | 110 | # Mouse events/states 111 | 112 | const TK_MOUSE_LEFT* = 0x80 # Buttons 113 | const TK_MOUSE_RIGHT* = 0x81 114 | const TK_MOUSE_MIDDLE* = 0x82 115 | const TK_MOUSE_X1* = 0x83 116 | const TK_MOUSE_X2* = 0x84 117 | const TK_MOUSE_MOVE* = 0x85 # Movement event 118 | const TK_MOUSE_SCROLL* = 0x86 # Mouse scroll event 119 | const TK_MOUSE_X* = 0x87 # Cusor position in cells 120 | const TK_MOUSE_Y* = 0x88 121 | const TK_MOUSE_PIXEL_X* = 0x89 # Cursor position in pixels 122 | const TK_MOUSE_PIXEL_Y* = 0x8A 123 | const TK_MOUSE_WHEEL* = 0x8B # Scroll direction and amount 124 | const TK_MOUSE_CLICKS* = 0x8C # Number of consecutive clicks 125 | 126 | # If key was released instead of pressed, it's code will be OR'ed with TK_KEY_RELEASED: 127 | # a) pressed 'A': 0x04 128 | # b) released 'A': 0x04|VK_KEY_RELEASED = 0x104 129 | 130 | const TK_KEY_RELEASED* = 0x100 131 | 132 | # Virtual key-codes for internal terminal states/variables. 133 | # These can be accessed via terminal_state function. 134 | 135 | const TK_WIDTH* = 0xC0 # Terminal window size in cells 136 | const TK_HEIGHT* = 0xC1 137 | const TK_CELL_WIDTH* = 0xC2 # Character cell size in pixels 138 | const TK_CELL_HEIGHT* = 0xC3 139 | const TK_COLOR* = 0xC4 # Current foregroung color 140 | const TK_BKCOLOR* = 0xC5 # Current background color 141 | const TK_LAYER* = 0xC6 # Current layer 142 | const TK_COMPOSITION* = 0xC7 # Current composition state 143 | const TK_CHAR* = 0xC8 # Translated ANSI code of last produced character 144 | const TK_WCHAR* = 0xC9 # Unicode codepoint of last produced character 145 | const TK_EVENT* = 0xCA # Last dequeued event 146 | const TK_FULLSCREEN* = 0xCB # Fullscreen state 147 | 148 | # Other events 149 | 150 | const TK_CLOSE* = 0xE0 151 | const TK_RESIZED* = 0xE1 152 | 153 | # Generic mode enum. 154 | # Right now it is used for composition option only. 155 | 156 | const TK_OFF* = 0 157 | const TK_ON* = 1 158 | 159 | # Input result codes for terminal_read function. 160 | 161 | const TK_INPUT_NONE* = 0 162 | const TK_INPUT_CANCELLED* = -1 163 | 164 | # Text printing alignment. 165 | 166 | const TK_ALIGN_DEFAULT* = 0 167 | const TK_ALIGN_LEFT* = 1 168 | const TK_ALIGN_RIGHT* = 2 169 | const TK_ALIGN_CENTER* = 3 170 | const TK_ALIGN_TOP* = 4 171 | const TK_ALIGN_BOTTOM* = 8 172 | const TK_ALIGN_MIDDLE* = 12 173 | 174 | type 175 | color_t* = uint32 176 | dimensions_t* = object 177 | width*: cint 178 | height*: cint 179 | 180 | 181 | proc terminal_open*(): cint {.cdecl, importc: "terminal_open", dynlib: libname.} 182 | proc terminal_close*() {.cdecl, importc: "terminal_close", dynlib: libname.} 183 | proc terminal_set8*(value: ptr int8): cint {.cdecl, importc: "terminal_set8", 184 | dynlib: libname.} 185 | proc terminal_set16*(value: ptr int16): cint {.cdecl, importc: "terminal_set16", 186 | dynlib: libname.} 187 | proc terminal_set32*(value: ptr int32): cint {.cdecl, importc: "terminal_set32", 188 | dynlib: libname.} 189 | proc terminal_refresh*() {.cdecl, importc: "terminal_refresh", dynlib: libname.} 190 | proc terminal_clear*() {.cdecl, importc: "terminal_clear", dynlib: libname.} 191 | proc terminal_clear_area*(x: cint; y: cint; w: cint; h: cint) {.cdecl, 192 | importc: "terminal_clear_area", dynlib: libname.} 193 | proc terminal_crop*(x: cint; y: cint; w: cint; h: cint) {.cdecl, importc: "terminal_crop", 194 | dynlib: libname.} 195 | proc terminal_layer*(index: cint) {.cdecl, importc: "terminal_layer", dynlib: libname.} 196 | proc terminal_color*(color: color_t) {.cdecl, importc: "terminal_color", 197 | dynlib: libname.} 198 | proc terminal_bkcolor*(color: color_t) {.cdecl, importc: "terminal_bkcolor", 199 | dynlib: libname.} 200 | proc terminal_composition*(mode: cint) {.cdecl, importc: "terminal_composition", 201 | dynlib: libname.} 202 | proc terminal_put*(x: cint; y: cint; code: cint) {.cdecl, importc: "terminal_put", 203 | dynlib: libname.} 204 | proc terminal_put_ext*(x: cint; y: cint; dx: cint; dy: cint; code: cint; 205 | corners: ptr color_t) {.cdecl, importc: "terminal_put_ext", 206 | dynlib: libname.} 207 | proc terminal_pick*(x: cint; y: cint; index: cint): cint {.cdecl, 208 | importc: "terminal_pick", dynlib: libname.} 209 | proc terminal_pick_color*(x: cint; y: cint; index: cint): color_t {.cdecl, 210 | importc: "terminal_pick_color", dynlib: libname.} 211 | proc terminal_pick_bkcolor*(x: cint; y: cint): color_t {.cdecl, 212 | importc: "terminal_pick_bkcolor", dynlib: libname.} 213 | proc terminal_print_ext8*(x: cint; y: cint; w: cint; h: cint; align: cint; s: ptr int8; 214 | out_w: ptr cint; out_h: ptr cint) {.cdecl, 215 | importc: "terminal_print_ext8", dynlib: libname.} 216 | proc terminal_print_ext16*(x: cint; y: cint; w: cint; h: cint; align: cint; s: ptr int16; 217 | out_w: ptr cint; out_h: ptr cint) {.cdecl, 218 | importc: "terminal_print_ext16", dynlib: libname.} 219 | proc terminal_print_ext32*(x: cint; y: cint; w: cint; h: cint; align: cint; s: ptr int32; 220 | out_w: ptr cint; out_h: ptr cint) {.cdecl, 221 | importc: "terminal_print_ext32", dynlib: libname.} 222 | proc terminal_measure_ext8*(w: cint; h: cint; s: ptr int8; out_w: ptr cint; out_h: ptr cint) {. 223 | cdecl, importc: "terminal_measure_ext8", dynlib: libname.} 224 | proc terminal_measure_ext16*(w: cint; h: cint; s: ptr int16; out_w: ptr cint; 225 | out_h: ptr cint) {.cdecl, 226 | importc: "terminal_measure_ext16", dynlib: libname.} 227 | proc terminal_measure_ext32*(w: cint; h: cint; s: ptr int32; out_w: ptr cint; 228 | out_h: ptr cint) {.cdecl, 229 | importc: "terminal_measure_ext32", dynlib: libname.} 230 | proc terminal_has_input*(): cint {.cdecl, importc: "terminal_has_input", 231 | dynlib: libname.} 232 | proc terminal_state*(code: cint): cint {.cdecl, importc: "terminal_state", 233 | dynlib: libname.} 234 | proc terminal_read*(): cint {.cdecl, importc: "terminal_read", dynlib: libname.} 235 | proc terminal_read_str8*(x: cint; y: cint; buffer: ptr int8; max: cint): cint {.cdecl, 236 | importc: "terminal_read_str8", dynlib: libname.} 237 | proc terminal_read_str16*(x: cint; y: cint; buffer: ptr int16; max: cint): cint {.cdecl, 238 | importc: "terminal_read_str16", dynlib: libname.} 239 | proc terminal_read_str32*(x: cint; y: cint; buffer: ptr int32; max: cint): cint {.cdecl, 240 | importc: "terminal_read_str32", dynlib: libname.} 241 | proc terminal_peek*(): cint {.cdecl, importc: "terminal_peek", dynlib: libname.} 242 | proc terminal_delay*(period: cint) {.cdecl, importc: "terminal_delay", dynlib: libname.} 243 | proc terminal_get8*(key: ptr int8; def: ptr int8): ptr int8 {.cdecl, 244 | importc: "terminal_get8", dynlib: libname.} 245 | proc terminal_get16*(key: ptr int16; def: ptr int16): ptr int16 {.cdecl, 246 | importc: "terminal_get16", dynlib: libname.} 247 | proc terminal_get32*(key: ptr int32; def: ptr int32): ptr int32 {.cdecl, 248 | importc: "terminal_get32", dynlib: libname.} 249 | proc color_from_name8*(name: ptr int8): color_t {.cdecl, importc: "color_from_name8", 250 | dynlib: libname.} 251 | proc color_from_name16*(name: ptr int16): color_t {.cdecl, 252 | importc: "color_from_name16", dynlib: libname.} 253 | proc color_from_name32*(name: ptr int32): color_t {.cdecl, 254 | importc: "color_from_name32", dynlib: libname.} 255 | 256 | import strutils 257 | 258 | proc terminal_set*(s: cstring): cint {.inline.} = 259 | return terminal_set8(cast[ptr int8](s)) 260 | 261 | proc terminal_setf*(s: string, args: varargs[string, `$`]) : cint = 262 | var ret : cint 263 | ret = terminal_set(format(s, args)) 264 | 265 | proc terminal_print_ext*(x,y,w,h: cint, alignment: cint, s: cstring) : dimensions_t = 266 | var ret : dimensions_t 267 | terminal_print_ext8(x, y, w, h, alignment, cast[ptr int8](s), addr(ret.width), addr(ret.height)) 268 | return ret 269 | 270 | proc terminal_print*(x: cint; y: cint; s: cstring): dimensions_t {.inline.} = 271 | return terminal_print_ext(x, y, 0, 0, TK_ALIGN_DEFAULT, s) 272 | 273 | proc terminal_printf*(x, y: cint, s: string, args: varargs[string, `$`]) : dimensions_t = 274 | var ret : dimensions_t 275 | ret = terminal_print(x, y, format(s, args)) 276 | return ret 277 | 278 | proc terminal_printf_ext*(x, y, w, h: cint, align: cint, s: string, args: varargs[string, `$`]) : dimensions_t = 279 | var ret : dimensions_t 280 | ret = terminal_print_ext(x, y, w, h, align, format(s, args)) 281 | return ret 282 | 283 | proc terminal_measure_ext*(w,h: cint, s: cstring) : dimensions_t = 284 | var ret : dimensions_t 285 | terminal_measure_ext8(w, h, cast[ptr int8](s), addr(ret.width), addr(ret.height)) 286 | 287 | proc terminal_measure*(s: cstring) : dimensions_t {.inline.} = 288 | echo repr s 289 | return terminal_measure_ext(0, 0, s) 290 | 291 | proc terminal_measuref*(s: string, args: varargs[string, `$`]) : dimensions_t = 292 | var ret: dimensions_t 293 | ret = terminal_measure(format(s, args)) 294 | return ret 295 | 296 | proc terminal_read_str*(x: cint; y: cint; buffer: cstring; max: cint): cint {.inline.} = 297 | return terminal_read_str8(x, y, cast[ptr int8](buffer), max) 298 | 299 | proc terminal_get*(key: cstring; default: cstring = cast[cstring](0)): cstring {.inline.} = 300 | return cast[cstring](terminal_get8(cast[ptr int8](key), 301 | cast[ptr int8](default))) 302 | 303 | proc color_from_name*(name: cstring): color_t {.inline.} = 304 | return color_from_name8(cast[ptr int8](name)) 305 | 306 | proc color_from_argb*(a: int; r: int; g: int; b: int): int {.inline.} = 307 | let ret = ((a shl 24) or (r shl 16) or (g shl 8) or b) 308 | echo repr ret 309 | ret 310 | 311 | proc terminal_check*(code: cint): cint {.inline.} = 312 | return cint terminal_state(code) > 0 313 | -------------------------------------------------------------------------------- /blt.nimble: -------------------------------------------------------------------------------- 1 | # Package 2 | 3 | version = "0.1.0" 4 | author = "Zachary Carter" 5 | description = "Bindings to the terminal emulator BearLibTerminal" 6 | license = "MIT" 7 | skipDirs = @["examples"] 8 | # Dependencies 9 | 10 | requires "nim >= 0.16.0" 11 | 12 | -------------------------------------------------------------------------------- /examples/Orbitron Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zacharycarter/blt-nim/6e254912131a3c3b7d2080bc0cfc7ca5cf4eff4e/examples/Orbitron Bold.ttf -------------------------------------------------------------------------------- /examples/test.nim: -------------------------------------------------------------------------------- 1 | import ../blt 2 | 3 | discard terminal_open() 4 | discard terminal_set("window.title='foo'; window.size=80x25;") 5 | discard terminal_printf(2, 23, "[color=orange]ESC.[/color] Exit") 6 | discard terminal_printf_ext(77, 22, 0, 0, TK_ALIGN_RIGHT, "library version $1", terminal_get("version")) 7 | discard terminal_printf_ext(77, 23, 0, 0, TK_ALIGN_RIGHT, "http://wyrd.name/en:bearlibterminal") 8 | 9 | terminal_color(color_from_name("white")) 10 | 11 | var n = terminal_printf(2, 1, "[color=orange]1.[/color] Wide color range: ").width 12 | 13 | let longWord = "antidisestablishmentarianism." 14 | for i in 0..│ 36 | │...........┌─┘ 37 | │<.@..┌─────┘ 38 | └─────┘ 39 | """) 40 | 41 | 42 | terminal_refresh() 43 | 44 | var key = terminal_read() 45 | 46 | while key != TK_CLOSE and key != TK_ESCAPE: 47 | key = terminal_read() 48 | 49 | terminal_close() --------------------------------------------------------------------------------