1 // Written in the D programming language. 2 module BearLibTerminal; 3 4 private import std.string: toStringz, format; 5 private import std.array: join; 6 7 public alias color_t = uint; 8 9 private extern (C) { 10 public struct dimensions_t { int width, height; } 11 int terminal_open(); 12 void terminal_close(); 13 int terminal_set8(const char*); 14 char *terminal_get8(const char*, const char*); 15 void terminal_color(color_t); 16 void terminal_bkcolor(color_t); 17 void terminal_composition(int); 18 void terminal_font8(const char*); 19 void terminal_layer(int); 20 void terminal_clear(); 21 void terminal_clear_area(int, int, int, int); 22 void terminal_crop(int, int, int, int); 23 void terminal_refresh(); 24 void terminal_put(int, int, int); 25 int terminal_pick(int, int, int); 26 color_t terminal_pick_color(int, int, int); 27 color_t terminal_pick_bkcolor(int, int); 28 void terminal_put_ext(int, int, int, int, int, color_t*); 29 void terminal_print_ext8(int, int, int, int, int, const char*, int*, int*); 30 void terminal_measure_ext8(int, int, const char*, int*, int*); 31 int terminal_state(int); 32 int terminal_check(int); 33 int terminal_has_input(); 34 int terminal_read(); 35 int terminal_peek(); 36 color_t terminal_read_str8(int, int, char*, int); 37 void terminal_delay(int); 38 color_t color_from_name8(const char*); 39 color_t color_from_argb(byte, byte, byte, byte); 40 } 41 42 // namespace called "terminal" 43 pragma(inline, true) { struct terminal { static { 44 45 46 // Has to be inline, for now 47 enum keycode { 48 a = 0x04, 49 b = 0x05, 50 c = 0x06, 51 d = 0x07, 52 e = 0x08, 53 f = 0x09, 54 g = 0x0a, 55 h = 0x0b, 56 i = 0x0c, 57 j = 0x0d, 58 k = 0x0e, 59 l = 0x0f, 60 m = 0x10, 61 n = 0x11, 62 o = 0x12, 63 p = 0x13, 64 q = 0x14, 65 r = 0x15, 66 s = 0x16, 67 t = 0x17, 68 u = 0x18, 69 v = 0x19, 70 w = 0x1a, 71 x = 0x1b, 72 y = 0x1c, 73 z = 0x1d, 74 K_1 = 0x1E, 75 K_2 = 0x1F, 76 K_3 = 0x20, 77 K_4 = 0x21, 78 K_5 = 0x22, 79 K_6 = 0x23, 80 K_7 = 0x24, 81 K_8 = 0x25, 82 K_9 = 0x26, 83 K_0 = 0x27, 84 enter = 0x28, 85 escape = 0x29, 86 backspace = 0x2a, 87 tab = 0x2b, 88 space = 0x2c, 89 minus = 0x2d /* - */, 90 equals = 0x2e /* = */, 91 lbracket = 0x2f /* [ */, 92 rbracket = 0x30 /* ] */, 93 backslash = 0x31 /* \ */, 94 semicolon = 0x33 /* , */, 95 apostrophe = 0x34 /* ' */, 96 grave = 0x35 /* ` */, 97 comma = 0x36 /* , */, 98 period = 0x37 /* . */, 99 slash = 0x38 /* / */, 100 F1 = 0x3A, 101 F2 = 0x3B, 102 F3 = 0x3C, 103 F4 = 0x3D, 104 F5 = 0x3E, 105 F6 = 0x3F, 106 F7 = 0x40, 107 F8 = 0x41, 108 F9 = 0x42, 109 F10 = 0x43, 110 F11 = 0x44, 111 F12 = 0x45, 112 pause = 0x48 /* Pause/Break */, 113 insert = 0x49, 114 home = 0x4a, 115 pageup = 0x4b, 116 K_delete = 0x4c, 117 end = 0x4d, 118 pagedown = 0x4e, 119 right = 0x4F /* Right arrow */, 120 left = 0x50 /* Left arrow */, 121 down = 0x51 /* Down arrow */, 122 up = 0x52 /* Up arrow */, 123 KP_divide = 0x54 /* '/' on numpad */, 124 KP_multiply = 0x55 /* '*' on numpad */, 125 KP_minus = 0x56 /* '-' on numpad */, 126 KP_plus = 0x57 /* '+' on numpad */, 127 KP_enter = 0x58, 128 KP_1 = 0x59, 129 KP_2 = 0x5A, 130 KP_3 = 0x5B, 131 KP_4 = 0x5C, 132 KP_5 = 0x5D, 133 KP_6 = 0x5E, 134 KP_7 = 0x5F, 135 KP_8 = 0x60, 136 KP_9 = 0x61, 137 KP_0 = 0x62, 138 kp_period = 0x63 /* '.' on numpad */, 139 shift = 0x70, 140 control = 0x71, 141 ctrl = 0x71, // the same 142 alt = 0x72, 143 144 /* 145 * Mouse events/states 146 */ 147 mouse_left = 0x80 /* Buttons */, 148 mouse_right = 0x81, 149 mouse_middle = 0x82, 150 mouse_x1 = 0x83, 151 mouse_x2 = 0x84, 152 mouse_move = 0x85 /* Movement event */, 153 mouse_scroll = 0x86 /* Mouse scroll event */, 154 mouse_x = 0x87 /* Cusor position in cells */, 155 mouse_y = 0x88, 156 mouse_pixel_x = 0x89 /* Cursor position in pixels */, 157 mouse_pixel_y = 0x8A, 158 mouse_wheel = 0x8B /* Scroll direction and amount */, 159 mouse_clicks = 0x8C /* Number of consecutive clicks */, 160 161 /* 162 * If key was released instead of pressed, it's code will be OR'ed with key_released: 163 * a) pressed 'A': 0x04 164 * b) released 'A': 0x04|terminal.keycodes.key_released = 0x104 165 */ 166 key_released = 0x100, 167 168 /* 169 * Virtual key-codes for internal terminal states/variables. 170 * These can be accessed via terminal_state function. 171 */ 172 width = 0xC0 /* Terminal window size in cells */, 173 height = 0xC1, 174 cell_width = 0xC2 /* Character cell size in pixels */, 175 cell_height = 0xC3, 176 color = 0xC4 /* Current foregroung color */, 177 colour = 0xC4, 178 bkcolor = 0xC5 /* Current background color */, 179 bkcolour = 0xC5, 180 layer = 0xC6 /* Current layer */, 181 composition = 0xC7 /* Current composition state */, 182 character = 0xC8 /* Translated ANSI code of last produced character */, 183 wcharacter = 0xC9 /* Unicode codepoint of last produced character */, 184 event = 0xCA /* Last dequeued event */, 185 fullscreen = 0xCB /* Fullscreen state */, 186 187 /* 188 * Other events 189 */ 190 close = 0xe0, 191 resized = 0xe1, 192 193 /* 194 * Generic mode enum. 195 * Right now it is used for composition option only. 196 */ 197 off = 0, 198 on = 1, 199 200 // Input result codes for the terminal_read function. 201 input_none = 0, 202 input_cancelled = -1, 203 204 // Text printing alignment 205 align_default = 0, 206 align_left = 1, 207 align_right = 2, 208 align_center = 3, 209 align_centre = 3, 210 align_top = 4, 211 align_bottom = 8, 212 align_middle = 12 213 } 214 alias keycodes = keycode; 215 216 int open(string title="BearLibTerminal") { int c = terminal_open(); setf("window.title=%s", title); return c; }; 217 void close() { terminal_close(); }; 218 int set(string[] s...) { return terminal_set8(toStringz(join(s))); }; 219 string get(string key, string defaultval) { import std.conv: to; return to!string(terminal_get8(toStringz(key), toStringz(defaultval))); } 220 int setf(T...)(string s, T args) { return terminal_set8(toStringz(format(s, args))); } 221 222 void color(color_t clr) { terminal_color(clr); }; 223 void color(string clr) { terminal_color(color_from_name(clr)); } 224 alias colour = color; 225 226 void bkcolor(color_t clr) { terminal_bkcolor(clr); }; 227 void bkcolor(string clr) { terminal_bkcolor(color_from_name(clr)); }; 228 alias bkcolour = bkcolor; 229 230 void composition(int mode) { terminal_composition(mode); }; 231 232 void font(string name) { terminal_font8(toStringz(name)); } 233 void layer(int lyr) { terminal_layer(lyr); }; 234 void clear() { terminal_clear(); }; 235 void clear_area(int x, int y, int w, int h) { terminal_clear_area(x, y, w, h); }; 236 void crop(int x, int y, int w, int h) { terminal_crop(x, y, w, h); }; 237 void refresh() { terminal_refresh(); }; 238 void put(int x, int y, int code) { terminal_put(x, y, code); }; 239 int pick(int x, int y, int index) { return terminal_pick(x, y, index); }; 240 color_t pick_color(int x, int y, int index) { return terminal_pick_color(x, y, index); }; 241 color_t pick_bkcolor(int x, int y) { return terminal_pick_bkcolor(x, y); }; 242 alias pick_colour = pick_color; 243 alias pick_bkcolour = pick_bkcolor; 244 245 void put_ext(int x, int y, int dx, int dy, int code) { terminal_put_ext(x, y, dx, dy, code, null); }; 246 void put_ext(int x, int y, int dx, int dy, int code, color_t[4] corners) { terminal_put_ext(x, y, dx, dy, code, corners.ptr); }; 247 248 dimensions_t print_ext(int x, int y, int w, int h, int alignment, string[] s...) { 249 dimensions_t tmp; 250 terminal_print_ext8(x, y, w, h, alignment, toStringz(join(s)), &tmp.width, &tmp.height); 251 return tmp; 252 } 253 dimensions_t printf_ext(T...)(int x, int y, int w, int h, int alignment, string s, T args) { return print_ext(x, y, w, h, alignment, format(s, args)); } 254 dimensions_t print(int x, int y, string[] s...) { 255 return print_ext(x, y, 0, 0, 0, join(s)); 256 }; 257 dimensions_t printf(T...)(int x, int y, string s, T args) { return print(x, y, format(s, args)); }; 258 259 dimensions_t measure_ext(int w, int h, string[] s...) { 260 dimensions_t tmp; 261 terminal_measure_ext8(w, h, toStringz(join(s)), &tmp.width, &tmp.height); 262 return tmp; 263 } 264 dimensions_t measuref_ext(T...)(int w, in h, string s, T args) { return measure_ext(w, h, format(s, args)); } 265 dimensions_t measure(string[] s...) { return measure_ext(0, 0, s); }; 266 dimensions_t measuref(T...)(string s, T args) { return measure(format(s, args)); }; 267 268 int state(int slot) { return terminal_state(slot); }; 269 bool check(int slot) { return terminal_state(slot) > 0; }; 270 int has_input() { return terminal_has_input(); }; 271 keycode read() { return cast(keycode)terminal_read(); }; 272 int peek() { return terminal_peek(); }; 273 string read_str(int x, int y, int max, string prompt="") { 274 assert (prompt.length <= max); 275 import std.conv: to; 276 import core.stdc.stdlib: malloc, free; 277 278 print(x, y, prompt); 279 280 char[] buf = new char[](max); 281 buf[] = 0; 282 283 string tmp; 284 285 terminal_read_str8(x+cast(int)prompt.length, y, buf.ptr, max); 286 tmp = to!string(buf); 287 delete buf; 288 return tmp; 289 }; 290 void delay(int period) { terminal_delay(period); }; 291 uint color_from_name(string name) { return color_from_name8(toStringz(name)); }; 292 alias colour_from_name = color_from_name; 293 294 pure uint color_from_argb(ubyte a, ubyte r, ubyte g, ubyte b) { return (a << 24) | (r << 16) | (g << 8) | b; } 295 pure uint color_from_rgb(ubyte r, ubyte g, ubyte b) { return (255 << 24) | (r << 16) | (g << 8) | b; } 296 alias colour_from_argb = color_from_argb; 297 alias colour_from_rgb = color_from_rgb; 298 299 }}}