bear_lib_terminal_sys/
lib.rs

1extern crate libc;
2
3use std::mem;
4use std::ffi::CString;
5
6
7pub const TK_A          : i32 = 0x04;
8pub const TK_B          : i32 = 0x05;
9pub const TK_C          : i32 = 0x06;
10pub const TK_D          : i32 = 0x07;
11pub const TK_E          : i32 = 0x08;
12pub const TK_F          : i32 = 0x09;
13pub const TK_G          : i32 = 0x0A;
14pub const TK_H          : i32 = 0x0B;
15pub const TK_I          : i32 = 0x0C;
16pub const TK_J          : i32 = 0x0D;
17pub const TK_K          : i32 = 0x0E;
18pub const TK_L          : i32 = 0x0F;
19pub const TK_M          : i32 = 0x10;
20pub const TK_N          : i32 = 0x11;
21pub const TK_O          : i32 = 0x12;
22pub const TK_P          : i32 = 0x13;
23pub const TK_Q          : i32 = 0x14;
24pub const TK_R          : i32 = 0x15;
25pub const TK_S          : i32 = 0x16;
26pub const TK_T          : i32 = 0x17;
27pub const TK_U          : i32 = 0x18;
28pub const TK_V          : i32 = 0x19;
29pub const TK_W          : i32 = 0x1A;
30pub const TK_X          : i32 = 0x1B;
31pub const TK_Y          : i32 = 0x1C;
32pub const TK_Z          : i32 = 0x1D;
33pub const TK_1          : i32 = 0x1E;
34pub const TK_2          : i32 = 0x1F;
35pub const TK_3          : i32 = 0x20;
36pub const TK_4          : i32 = 0x21;
37pub const TK_5          : i32 = 0x22;
38pub const TK_6          : i32 = 0x23;
39pub const TK_7          : i32 = 0x24;
40pub const TK_8          : i32 = 0x25;
41pub const TK_9          : i32 = 0x26;
42pub const TK_0          : i32 = 0x27;
43pub const TK_ENTER      : i32 = 0x28;
44pub const TK_ESCAPE     : i32 = 0x29;
45pub const TK_BACKSPACE  : i32 = 0x2A;
46pub const TK_TAB        : i32 = 0x2B;
47pub const TK_SPACE      : i32 = 0x2C;
48pub const TK_MINUS      : i32 = 0x2D;
49pub const TK_EQUALS     : i32 = 0x2E;
50pub const TK_LBRACKET   : i32 = 0x2F;
51pub const TK_RBRACKET   : i32 = 0x30;
52pub const TK_BACKSLASH  : i32 = 0x31;
53pub const TK_SEMICOLON  : i32 = 0x33;
54pub const TK_APOSTROPHE : i32 = 0x34;
55pub const TK_GRAVE      : i32 = 0x35;
56pub const TK_COMMA      : i32 = 0x36;
57pub const TK_PERIOD     : i32 = 0x37;
58pub const TK_SLASH      : i32 = 0x38;
59pub const TK_F1         : i32 = 0x3A;
60pub const TK_F2         : i32 = 0x3B;
61pub const TK_F3         : i32 = 0x3C;
62pub const TK_F4         : i32 = 0x3D;
63pub const TK_F5         : i32 = 0x3E;
64pub const TK_F6         : i32 = 0x3F;
65pub const TK_F7         : i32 = 0x40;
66pub const TK_F8         : i32 = 0x41;
67pub const TK_F9         : i32 = 0x42;
68pub const TK_F10        : i32 = 0x43;
69pub const TK_F11        : i32 = 0x44;
70pub const TK_F12        : i32 = 0x45;
71pub const TK_PAUSE      : i32 = 0x48;
72pub const TK_INSERT     : i32 = 0x49;
73pub const TK_HOME       : i32 = 0x4A;
74pub const TK_PAGEUP     : i32 = 0x4B;
75pub const TK_DELETE     : i32 = 0x4C;
76pub const TK_END        : i32 = 0x4D;
77pub const TK_PAGEDOWN   : i32 = 0x4E;
78pub const TK_RIGHT      : i32 = 0x4F;
79pub const TK_LEFT       : i32 = 0x50;
80pub const TK_DOWN       : i32 = 0x51;
81pub const TK_UP         : i32 = 0x52;
82pub const TK_KP_DIVIDE  : i32 = 0x54;
83pub const TK_KP_MULTIPLY: i32 = 0x55;
84pub const TK_KP_MINUS   : i32 = 0x56;
85pub const TK_KP_PLUS    : i32 = 0x57;
86pub const TK_KP_ENTER   : i32 = 0x58;
87pub const TK_KP_1       : i32 = 0x59;
88pub const TK_KP_2       : i32 = 0x5A;
89pub const TK_KP_3       : i32 = 0x5B;
90pub const TK_KP_4       : i32 = 0x5C;
91pub const TK_KP_5       : i32 = 0x5D;
92pub const TK_KP_6       : i32 = 0x5E;
93pub const TK_KP_7       : i32 = 0x5F;
94pub const TK_KP_8       : i32 = 0x60;
95pub const TK_KP_9       : i32 = 0x61;
96pub const TK_KP_0       : i32 = 0x62;
97pub const TK_KP_PERIOD  : i32 = 0x63;
98pub const TK_SHIFT      : i32 = 0x70;
99pub const TK_CONTROL    : i32 = 0x71;
100pub const TK_ALT        : i32 = 0x72;
101
102pub const TK_MOUSE_LEFT   : i32 = 0x80;
103pub const TK_MOUSE_RIGHT  : i32 = 0x81;
104pub const TK_MOUSE_MIDDLE : i32 = 0x82;
105pub const TK_MOUSE_X1     : i32 = 0x83;
106pub const TK_MOUSE_X2     : i32 = 0x84;
107pub const TK_MOUSE_MOVE   : i32 = 0x85;
108pub const TK_MOUSE_SCROLL : i32 = 0x86;
109pub const TK_MOUSE_X      : i32 = 0x87;
110pub const TK_MOUSE_Y      : i32 = 0x88;
111pub const TK_MOUSE_PIXEL_X: i32 = 0x89;
112pub const TK_MOUSE_PIXEL_Y: i32 = 0x8A;
113pub const TK_MOUSE_WHEEL  : i32 = 0x8B;
114pub const TK_MOUSE_CLICKS : i32 = 0x8C;
115
116pub const TK_KEY_RELEASED: i32 = 0x100;
117
118pub const TK_WIDTH      : i32 = 0xC0;
119pub const TK_HEIGHT     : i32 = 0xC1;
120pub const TK_CELL_WIDTH : i32 = 0xC2;
121pub const TK_CELL_HEIGHT: i32 = 0xC3;
122pub const TK_COLOR      : i32 = 0xC4;
123pub const TK_BKCOLOR    : i32 = 0xC5;
124pub const TK_LAYER      : i32 = 0xC6;
125pub const TK_COMPOSITION: i32 = 0xC7;
126pub const TK_CHAR       : i32 = 0xC8;
127pub const TK_WCHAR      : i32 = 0xC9;
128pub const TK_EVENT      : i32 = 0xCA;
129pub const TK_FULLSCREEN : i32 = 0xCB;
130
131pub const TK_CLOSE  : i32 = 0xE0;
132pub const TK_RESIZED: i32 = 0xE1;
133
134pub const TK_OFF: i32 = 0;
135pub const TK_ON : i32 = 1;
136
137pub const TK_INPUT_NONE     : i32 = 0;
138pub const TK_INPUT_CANCELLED: i32 = -1;
139
140pub const TK_ALIGN_DEFAULT: i32 = 0;
141pub const TK_ALIGN_LEFT   : i32 = 1;
142pub const TK_ALIGN_RIGHT  : i32 = 2;
143pub const TK_ALIGN_CENTER : i32 = 3;
144pub const TK_ALIGN_TOP    : i32 = 4;
145pub const TK_ALIGN_BOTTOM : i32 = 5;
146pub const TK_ALIGN_MIDDLE : i32 = 6;
147
148pub type ColorT = u32;
149
150
151pub fn open() -> bool {
152	unsafe {
153		terminal_open() != 0
154	}
155}
156
157pub fn close() {
158	unsafe {
159		terminal_close()
160	}
161}
162
163pub fn set(value: &str) -> bool {
164	with_utf8_ptr(value, |ptr|
165		unsafe {
166			terminal_set8(ptr) != 0
167		}
168	)
169}
170
171pub fn refresh() {
172	unsafe {
173		terminal_refresh()
174	}
175}
176
177pub fn clear() {
178	unsafe {
179		terminal_clear()
180	}
181}
182
183pub fn clear_area(x: i32, y: i32, width: i32, height: i32) {
184	assert!(x >= 0);
185	assert!(y >= 0);
186	assert!(width >= 0);
187	assert!(height >= 0);
188
189	unsafe {
190		terminal_clear_area(x, y, width, height)
191	}
192}
193
194pub fn crop(x: i32, y: i32, width: i32, height: i32) {
195	assert!(x >= 0);
196	assert!(y >= 0);
197	assert!(width >= 0);
198	assert!(height >= 0);
199
200	unsafe {
201		terminal_crop(x, y, width, height)
202	}
203}
204
205pub fn layer(index: i32) {
206	assert!(index >= 0);
207	assert!(index <= 255);
208
209	unsafe {
210		terminal_layer(index)
211	}
212}
213
214pub fn color(value: ColorT) {
215	unsafe {
216		terminal_color(value)
217	}
218}
219
220pub fn bkcolor(value: ColorT) {
221	unsafe {
222		terminal_bkcolor(value)
223	}
224}
225
226pub fn composition(enable: bool) {
227	let value = if enable {TK_ON} else {TK_OFF};
228	unsafe {
229		terminal_composition(value)
230	}
231}
232
233pub fn put(x: i32, y: i32, code: i32) {
234	assert!(x >= 0);
235	assert!(y >= 0);
236	assert!(code >= 0);
237
238	unsafe {
239		terminal_put(x, y, code)
240	}
241}
242
243pub fn put_ext(x: i32, y: i32, dx: i32, dy: i32, code: i32, corners: &[ColorT]) {
244	assert!(x >= 0);
245	assert!(y >= 0);
246	assert!(code >= 0);
247	assert_eq!(corners.len(), 4);
248
249	let corners_ptr = corners.as_ptr();
250	unsafe {
251		terminal_put_ext(x, y, dx, dy, code, corners_ptr)
252	}
253}
254
255pub fn pick(x: i32, y: i32, index: i32) -> i32 {
256	assert!(x >= 0);
257	assert!(y >= 0);
258	assert!(index >= 0);
259
260	unsafe {
261		terminal_pick(x, y, index)
262	}
263}
264
265pub fn pick_color(x: i32, y: i32, index: i32) -> ColorT {
266	assert!(x >= 0);
267	assert!(y >= 0);
268	assert!(index >= 0);
269
270	unsafe {
271		terminal_pick_color(x, y, index)
272	}
273}
274
275pub fn pick_bkcolor(x: i32, y: i32) -> ColorT {
276	assert!(x >= 0);
277	assert!(y >= 0);
278
279	unsafe {
280		terminal_pick_bkcolor(x, y)
281	}
282}
283
284pub fn print(x: i32, y: i32, value: &str) {
285	assert!(x >= 0);
286	assert!(y >= 0);
287
288	with_utf8_ptr(value, |ptr| {
289		unsafe {
290			let mut out_w = 0;
291			let mut out_h = 0;
292			terminal_print_ext8(x, y, 0, 0, TK_ALIGN_DEFAULT, ptr, &mut out_w, &mut out_h);
293		}
294	});
295}
296
297pub fn measure(value: &str) -> i32 {
298	with_utf8_ptr(value, |ptr|
299		unsafe {
300			terminal_measure_ext8(ptr)
301		}
302	)
303}
304
305pub fn has_input() -> bool {
306	unsafe {
307		terminal_has_input() != 0
308	}
309}
310
311pub fn state(code: i32) -> i32 {
312	assert!(code >= 0);
313
314	unsafe {
315		terminal_state(code)
316	}
317}
318
319pub fn state_color(code: i32) -> ColorT {
320	unsafe {
321		let color = state(code);
322		mem::transmute::<i32, ColorT>(color)
323	}
324}
325
326pub fn check(code: i32) -> bool {
327	state(code) > 0
328}
329
330pub fn read() -> i32 {
331	unsafe {
332		terminal_read()
333	}
334}
335
336pub fn peek() -> i32 {
337	unsafe {
338		terminal_peek()
339	}
340}
341
342pub fn read_str(x: i32, y: i32, max: i32) -> Option<String> {
343	assert!(x >= 0);
344	assert!(y >= 0);
345	assert!(max >= 0);
346
347	match unsafe {
348		let i8_ptr = mem::transmute::<*mut libc::c_char, *mut i8>(CString::from_vec_unchecked(vec![0; max as usize]).into_raw());
349		(terminal_read_str8(x, y, i8_ptr, max) as i32, CString::from_raw(i8_ptr))
350	} {
351		(TK_INPUT_CANCELLED, _) => None,
352		(TK_INPUT_NONE,      _) => Some(String::with_capacity(0)),  // Utilize zero-alloc here
353		(_,             string) => Some(string.to_str().unwrap().to_string()),
354	}
355}
356
357pub fn delay(period: i32) {
358	unsafe {
359		terminal_delay(period)
360	}
361}
362
363
364#[link(name = "BearLibTerminal")]
365extern {
366	fn terminal_open() -> i32;
367	fn terminal_close();
368	fn terminal_set8(value: *const i8) -> i32;
369	fn terminal_refresh();
370	fn terminal_clear();
371	fn terminal_clear_area(x: i32, y: i32, w: i32, h: i32);
372	fn terminal_crop(x: i32, y: i32, w: i32, h: i32);
373	fn terminal_layer(index: i32);
374	fn terminal_color(color: ColorT);
375	fn terminal_bkcolor(color: ColorT);
376	fn terminal_composition(mode: i32);
377	fn terminal_put(x: i32, y: i32, code: i32);
378	fn terminal_put_ext(x: i32, y: i32, dx: i32, dy: i32, code: i32, corners: *const ColorT);
379	fn terminal_pick(x: i32, y: i32, index: i32) -> i32;
380	fn terminal_pick_color(x: i32, y: i32, index: i32) -> ColorT;
381	fn terminal_pick_bkcolor(x: i32, y: i32) -> ColorT;
382	fn terminal_print_ext8(x: i32, y: i32, w: i32, h: i32, align: i32, value: *const i8, out_w: *mut i32, out_h: *mut i32);
383	fn terminal_measure_ext8(value: *const i8) -> i32;
384	fn terminal_has_input() -> i32;
385	fn terminal_state(code: i32) -> i32;
386	fn terminal_read() -> i32;
387	fn terminal_peek() -> i32;
388	fn terminal_read_str8(x: i32, y: i32, buffer: *mut i8, max: i32) -> ColorT;
389	fn terminal_delay(period: i32);
390}
391
392
393fn with_utf8_ptr<T, F: Fn(*const i8) -> T>(value: &str, callback: F) -> T {
394	let converted = CString::new(value).unwrap();
395	let char_ptr = converted.as_ptr();
396	unsafe {
397		let i8_ptr = mem::transmute::<*const libc::c_char, *const i8>(char_ptr);
398		callback(i8_ptr)
399	}
400}