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)), (_, 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}