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