1use core::mem;
2use core::slice;
3use core::str;
4
5use cstr_core::CStr;
6use cty::*;
7use ndless::prelude::*;
8use num::FromPrimitive;
9
10pub mod ll {
11 #![allow(non_camel_case_types)]
12
13 use core::mem;
14
15 use cty::{c_char as c_schar, c_int, c_uchar, c_uint, c_void, int16_t, uint16_t, uint8_t};
16
17 pub use crate::keysym::*;
18
19 pub type SDL_EventType = c_uint;
20 pub type SDLMod = c_uint;
21 pub type SDL_SysWMmsg = c_void;
22
23 pub const SDL_NOEVENT: SDL_EventType = 0;
24 pub const SDL_ACTIVEEVENT: SDL_EventType = 1;
25 pub const SDL_KEYDOWN: SDL_EventType = 2;
26 pub const SDL_KEYUP: SDL_EventType = 3;
27 pub const SDL_MOUSEMOTION: SDL_EventType = 4;
28 pub const SDL_MOUSEBUTTONDOWN: SDL_EventType = 5;
29 pub const SDL_MOUSEBUTTONUP: SDL_EventType = 6;
30 pub const SDL_JOYAXISMOTION: SDL_EventType = 7;
31 pub const SDL_JOYBALLMOTION: SDL_EventType = 8;
32 pub const SDL_JOYHATMOTION: SDL_EventType = 9;
33 pub const SDL_JOYBUTTONDOWN: SDL_EventType = 10;
34 pub const SDL_JOYBUTTONUP: SDL_EventType = 11;
35 pub const SDL_QUIT: SDL_EventType = 12;
36 pub const SDL_SYSWMEVENT: SDL_EventType = 13;
37 pub const SDL_VIDEORESIZE: SDL_EventType = 16;
38 pub const SDL_VIDEOEXPOSE: SDL_EventType = 17;
39 pub const SDL_USEREVENT: SDL_EventType = 24;
40
41 pub const SDL_DISABLE: c_int = 0;
42 pub const SDL_ENABLE: c_int = 1;
43 pub const SDL_QUERY: c_int = -1;
44
45 pub const SDL_APPMOUSEFOCUS: c_int = 0x01;
46 pub const SDL_APPINPUTFOCUS: c_int = 0x02;
47 pub const SDL_APPACTIVE: c_int = 0x04;
48
49 #[repr(C)]
50 #[derive(Debug, Copy, Clone)]
51 pub struct SDL_keysym {
52 pub scancode: uint8_t,
53 pub sym: SDLKey,
54 pub _mod: SDLMod,
55 pub unicode: uint16_t,
56 }
57
58 #[repr(C)]
59 #[derive(Debug, Copy, Clone)]
60 pub struct SDL_Event {
61 pub data: [c_uchar; 24],
62 }
63
64 #[repr(C)]
65 #[derive(Debug, Copy, Clone)]
66 pub struct SDL_ActiveEvent {
67 pub _type: uint8_t,
68 pub gain: uint8_t,
69 pub state: uint8_t,
70 }
71
72 #[repr(C)]
73 #[derive(Debug, Copy, Clone)]
74 pub struct SDL_KeyboardEvent {
75 pub _type: uint8_t,
76 pub which: uint8_t,
77 pub state: uint8_t,
78 pub keysym: SDL_keysym,
79 }
80
81 #[repr(C)]
82 #[derive(Debug, Copy, Clone)]
83 pub struct SDL_MouseMotionEvent {
84 pub _type: uint8_t,
85 pub which: uint8_t,
86 pub state: uint8_t,
87 pub x: uint16_t,
88 pub y: uint16_t,
89 pub xrel: int16_t,
90 pub yrel: int16_t,
91 }
92
93 #[repr(C)]
94 #[derive(Debug, Copy, Clone)]
95 pub struct SDL_MouseButtonEvent {
96 pub _type: uint8_t,
97 pub which: uint8_t,
98 pub button: uint8_t,
99 pub state: uint8_t,
100 pub x: uint16_t,
101 pub y: uint16_t,
102 }
103
104 #[repr(C)]
105 #[derive(Debug, Copy, Clone)]
106 pub struct SDL_ResizeEvent {
107 pub _type: uint8_t,
108 pub w: c_int,
109 pub h: c_int,
110 }
111
112 #[repr(C)]
113 #[derive(Debug, Copy, Clone)]
114 pub struct SDL_ExposeEvent {
115 pub _type: uint8_t,
116 }
117
118 #[repr(C)]
119 #[derive(Debug, Copy, Clone)]
120 pub struct SDL_QuitEvent {
121 pub _type: uint8_t,
122 }
123
124 #[repr(C)]
125 #[derive(Debug, Copy, Clone)]
126 pub struct SDL_UserEvent {
127 pub _type: uint8_t,
128 pub code: c_int,
129 pub data1: *mut c_void,
130 pub data2: *mut c_void,
131 }
132
133 #[repr(C)]
134 #[derive(Debug, Copy, Clone)]
135 pub struct SDL_SysWMEvent {
136 pub _type: uint8_t,
137 pub msg: *mut SDL_SysWMmsg,
138 }
139
140 impl SDL_Event {
141 pub fn _type(&self) -> *const uint8_t {
142 unsafe { mem::transmute_copy(&self) }
143 }
144
145 pub fn active(&self) -> *const SDL_ActiveEvent {
146 unsafe { mem::transmute_copy(&self) }
147 }
148
149 pub fn key(&self) -> *const SDL_KeyboardEvent {
150 unsafe { mem::transmute_copy(&self) }
151 }
152
153 pub fn motion(&self) -> *const SDL_MouseMotionEvent {
154 unsafe { mem::transmute_copy(&self) }
155 }
156
157 pub fn button(&self) -> *const SDL_MouseButtonEvent {
158 unsafe { mem::transmute_copy(&self) }
159 }
160
161 pub fn resize(&self) -> *const SDL_ResizeEvent {
162 unsafe { mem::transmute_copy(&self) }
163 }
164
165 pub fn expose(&self) -> *const SDL_ExposeEvent {
166 unsafe { mem::transmute_copy(&self) }
167 }
168
169 pub fn quit(&self) -> *const SDL_QuitEvent {
170 unsafe { mem::transmute_copy(&self) }
171 }
172
173 pub fn user(&self) -> *const SDL_UserEvent {
174 unsafe { mem::transmute_copy(&self) }
175 }
176
177 pub fn syswm(&self) -> *const SDL_SysWMEvent {
178 unsafe { mem::transmute_copy(&self) }
179 }
180 }
181
182 extern "C" {
183 pub fn SDL_PollEvent(event: *mut SDL_Event) -> c_int;
184 pub fn SDL_WaitEvent(event: *mut SDL_Event) -> c_int;
185 pub fn SDL_EventState(_type: uint8_t, state: c_int) -> uint8_t;
186 pub fn SDL_GetKeyState(numkeys: *mut c_int) -> *mut uint8_t;
187 pub fn SDL_GetModState() -> SDLMod;
188 pub fn SDL_GetKeyName(key: SDLKey) -> *mut c_schar;
189 pub fn SDL_GetAppState() -> uint8_t;
190 pub fn SDL_EnableUNICODE(enable: c_int) -> c_int;
191 pub fn SDL_EnableKeyRepeat(delay: c_int, interval: c_int) -> c_int;
192 pub fn SDL_SetModState(modstate: SDLMod);
193 pub fn SDL_PumpEvents();
194 }
195}
196
197#[derive(Debug, PartialEq, Eq, Copy, Clone)]
198pub enum AppState {
199 MouseFocus = ll::SDL_APPMOUSEFOCUS as isize,
200 InputFocus = ll::SDL_APPINPUTFOCUS as isize,
201 Active = ll::SDL_APPACTIVE as isize,
202}
203
204fn wrap_app_state(bitflags: u8) -> Vec<AppState> {
205 let flags = [AppState::MouseFocus, AppState::InputFocus, AppState::Active];
206
207 flags
208 .iter()
209 .filter_map(|&flag| {
210 if bitflags & (flag as u8) != 0 {
211 Some(flag)
212 } else {
213 None
214 }
215 })
216 .collect()
217}
218
219#[derive(PartialEq, Copy, Clone)]
220pub enum RepeatDelay {
221 Default,
222 Custom(isize),
223}
224
225#[derive(PartialEq, Copy, Clone)]
226pub enum RepeatInterval {
227 Default,
228 Custom(isize),
229}
230
231#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)]
232pub enum Key {
233 Unknown = ll::SDLK_UNKNOWN as isize,
234 Backspace = ll::SDLK_BACKSPACE as isize,
235 Tab = ll::SDLK_TAB as isize,
236 Clear = ll::SDLK_CLEAR as isize,
237 Return = ll::SDLK_RETURN as isize,
238 Pause = ll::SDLK_PAUSE as isize,
239 Escape = ll::SDLK_ESCAPE as isize,
240 Space = ll::SDLK_SPACE as isize,
241 Exclaim = ll::SDLK_EXCLAIM as isize,
242 Quotedbl = ll::SDLK_QUOTEDBL as isize,
243 Hash = ll::SDLK_HASH as isize,
244 Dollar = ll::SDLK_DOLLAR as isize,
245 Ampersand = ll::SDLK_AMPERSAND as isize,
246 Quote = ll::SDLK_QUOTE as isize,
247 LeftParen = ll::SDLK_LEFTPAREN as isize,
248 RightParen = ll::SDLK_RIGHTPAREN as isize,
249 Asterisk = ll::SDLK_ASTERISK as isize,
250 Plus = ll::SDLK_PLUS as isize,
251 Comma = ll::SDLK_COMMA as isize,
252 Minus = ll::SDLK_MINUS as isize,
253 Period = ll::SDLK_PERIOD as isize,
254 Slash = ll::SDLK_SLASH as isize,
255 Num0 = ll::SDLK_0 as isize,
256 Num1 = ll::SDLK_1 as isize,
257 Num2 = ll::SDLK_2 as isize,
258 Num3 = ll::SDLK_3 as isize,
259 Num4 = ll::SDLK_4 as isize,
260 Num5 = ll::SDLK_5 as isize,
261 Num6 = ll::SDLK_6 as isize,
262 Num7 = ll::SDLK_7 as isize,
263 Num8 = ll::SDLK_8 as isize,
264 Num9 = ll::SDLK_9 as isize,
265 Colon = ll::SDLK_COLON as isize,
266 Semicolon = ll::SDLK_SEMICOLON as isize,
267 Less = ll::SDLK_LESS as isize,
268 Equals = ll::SDLK_EQUALS as isize,
269 Greater = ll::SDLK_GREATER as isize,
270 Question = ll::SDLK_QUESTION as isize,
271 At = ll::SDLK_AT as isize,
272 LeftBracket = ll::SDLK_LEFTBRACKET as isize,
273 Backslash = ll::SDLK_BACKSLASH as isize,
274 RightBracket = ll::SDLK_RIGHTBRACKET as isize,
275 Caret = ll::SDLK_CARET as isize,
276 Underscore = ll::SDLK_UNDERSCORE as isize,
277 Backquote = ll::SDLK_BACKQUOTE as isize,
278 A = ll::SDLK_a as isize,
279 B = ll::SDLK_b as isize,
280 C = ll::SDLK_c as isize,
281 D = ll::SDLK_d as isize,
282 E = ll::SDLK_e as isize,
283 F = ll::SDLK_f as isize,
284 G = ll::SDLK_g as isize,
285 H = ll::SDLK_h as isize,
286 I = ll::SDLK_i as isize,
287 J = ll::SDLK_j as isize,
288 K = ll::SDLK_k as isize,
289 L = ll::SDLK_l as isize,
290 M = ll::SDLK_m as isize,
291 N = ll::SDLK_n as isize,
292 O = ll::SDLK_o as isize,
293 P = ll::SDLK_p as isize,
294 Q = ll::SDLK_q as isize,
295 R = ll::SDLK_r as isize,
296 S = ll::SDLK_s as isize,
297 T = ll::SDLK_t as isize,
298 U = ll::SDLK_u as isize,
299 V = ll::SDLK_v as isize,
300 W = ll::SDLK_w as isize,
301 X = ll::SDLK_x as isize,
302 Y = ll::SDLK_y as isize,
303 Z = ll::SDLK_z as isize,
304 Delete = ll::SDLK_DELETE as isize,
305 World0 = ll::SDLK_WORLD_0 as isize,
306 World1 = ll::SDLK_WORLD_1 as isize,
307 World2 = ll::SDLK_WORLD_2 as isize,
308 World3 = ll::SDLK_WORLD_3 as isize,
309 World4 = ll::SDLK_WORLD_4 as isize,
310 World5 = ll::SDLK_WORLD_5 as isize,
311 World6 = ll::SDLK_WORLD_6 as isize,
312 World7 = ll::SDLK_WORLD_7 as isize,
313 World8 = ll::SDLK_WORLD_8 as isize,
314 World9 = ll::SDLK_WORLD_9 as isize,
315 World10 = ll::SDLK_WORLD_10 as isize,
316 World11 = ll::SDLK_WORLD_11 as isize,
317 World12 = ll::SDLK_WORLD_12 as isize,
318 World13 = ll::SDLK_WORLD_13 as isize,
319 World14 = ll::SDLK_WORLD_14 as isize,
320 World15 = ll::SDLK_WORLD_15 as isize,
321 World16 = ll::SDLK_WORLD_16 as isize,
322 World17 = ll::SDLK_WORLD_17 as isize,
323 World18 = ll::SDLK_WORLD_18 as isize,
324 World19 = ll::SDLK_WORLD_19 as isize,
325 World20 = ll::SDLK_WORLD_20 as isize,
326 World21 = ll::SDLK_WORLD_21 as isize,
327 World22 = ll::SDLK_WORLD_22 as isize,
328 World23 = ll::SDLK_WORLD_23 as isize,
329 World24 = ll::SDLK_WORLD_24 as isize,
330 World25 = ll::SDLK_WORLD_25 as isize,
331 World26 = ll::SDLK_WORLD_26 as isize,
332 World27 = ll::SDLK_WORLD_27 as isize,
333 World28 = ll::SDLK_WORLD_28 as isize,
334 World29 = ll::SDLK_WORLD_29 as isize,
335 World30 = ll::SDLK_WORLD_30 as isize,
336 World31 = ll::SDLK_WORLD_31 as isize,
337 World32 = ll::SDLK_WORLD_32 as isize,
338 World33 = ll::SDLK_WORLD_33 as isize,
339 World34 = ll::SDLK_WORLD_34 as isize,
340 World35 = ll::SDLK_WORLD_35 as isize,
341 World36 = ll::SDLK_WORLD_36 as isize,
342 World37 = ll::SDLK_WORLD_37 as isize,
343 World38 = ll::SDLK_WORLD_38 as isize,
344 World39 = ll::SDLK_WORLD_39 as isize,
345 World40 = ll::SDLK_WORLD_40 as isize,
346 World41 = ll::SDLK_WORLD_41 as isize,
347 World42 = ll::SDLK_WORLD_42 as isize,
348 World43 = ll::SDLK_WORLD_43 as isize,
349 World44 = ll::SDLK_WORLD_44 as isize,
350 World45 = ll::SDLK_WORLD_45 as isize,
351 World46 = ll::SDLK_WORLD_46 as isize,
352 World47 = ll::SDLK_WORLD_47 as isize,
353 World48 = ll::SDLK_WORLD_48 as isize,
354 World49 = ll::SDLK_WORLD_49 as isize,
355 World50 = ll::SDLK_WORLD_50 as isize,
356 World51 = ll::SDLK_WORLD_51 as isize,
357 World52 = ll::SDLK_WORLD_52 as isize,
358 World53 = ll::SDLK_WORLD_53 as isize,
359 World54 = ll::SDLK_WORLD_54 as isize,
360 World55 = ll::SDLK_WORLD_55 as isize,
361 World56 = ll::SDLK_WORLD_56 as isize,
362 World57 = ll::SDLK_WORLD_57 as isize,
363 World58 = ll::SDLK_WORLD_58 as isize,
364 World59 = ll::SDLK_WORLD_59 as isize,
365 World60 = ll::SDLK_WORLD_60 as isize,
366 World61 = ll::SDLK_WORLD_61 as isize,
367 World62 = ll::SDLK_WORLD_62 as isize,
368 World63 = ll::SDLK_WORLD_63 as isize,
369 World64 = ll::SDLK_WORLD_64 as isize,
370 World65 = ll::SDLK_WORLD_65 as isize,
371 World66 = ll::SDLK_WORLD_66 as isize,
372 World67 = ll::SDLK_WORLD_67 as isize,
373 World68 = ll::SDLK_WORLD_68 as isize,
374 World69 = ll::SDLK_WORLD_69 as isize,
375 World70 = ll::SDLK_WORLD_70 as isize,
376 World71 = ll::SDLK_WORLD_71 as isize,
377 World72 = ll::SDLK_WORLD_72 as isize,
378 World73 = ll::SDLK_WORLD_73 as isize,
379 World74 = ll::SDLK_WORLD_74 as isize,
380 World75 = ll::SDLK_WORLD_75 as isize,
381 World76 = ll::SDLK_WORLD_76 as isize,
382 World77 = ll::SDLK_WORLD_77 as isize,
383 World78 = ll::SDLK_WORLD_78 as isize,
384 World79 = ll::SDLK_WORLD_79 as isize,
385 World80 = ll::SDLK_WORLD_80 as isize,
386 World81 = ll::SDLK_WORLD_81 as isize,
387 World82 = ll::SDLK_WORLD_82 as isize,
388 World83 = ll::SDLK_WORLD_83 as isize,
389 World84 = ll::SDLK_WORLD_84 as isize,
390 World85 = ll::SDLK_WORLD_85 as isize,
391 World86 = ll::SDLK_WORLD_86 as isize,
392 World87 = ll::SDLK_WORLD_87 as isize,
393 World88 = ll::SDLK_WORLD_88 as isize,
394 World89 = ll::SDLK_WORLD_89 as isize,
395 World90 = ll::SDLK_WORLD_90 as isize,
396 World91 = ll::SDLK_WORLD_91 as isize,
397 World92 = ll::SDLK_WORLD_92 as isize,
398 World93 = ll::SDLK_WORLD_93 as isize,
399 World94 = ll::SDLK_WORLD_94 as isize,
400 World95 = ll::SDLK_WORLD_95 as isize,
401 Kp0 = ll::SDLK_KP0 as isize,
402 Kp1 = ll::SDLK_KP1 as isize,
403 Kp2 = ll::SDLK_KP2 as isize,
404 Kp3 = ll::SDLK_KP3 as isize,
405 Kp4 = ll::SDLK_KP4 as isize,
406 Kp5 = ll::SDLK_KP5 as isize,
407 Kp6 = ll::SDLK_KP6 as isize,
408 Kp7 = ll::SDLK_KP7 as isize,
409 Kp8 = ll::SDLK_KP8 as isize,
410 Kp9 = ll::SDLK_KP9 as isize,
411 KpPeriod = ll::SDLK_KP_PERIOD as isize,
412 KpDivide = ll::SDLK_KP_DIVIDE as isize,
413 KpMultiply = ll::SDLK_KP_MULTIPLY as isize,
414 KpMinus = ll::SDLK_KP_MINUS as isize,
415 KpPlus = ll::SDLK_KP_PLUS as isize,
416 KpEnter = ll::SDLK_KP_ENTER as isize,
417 KpEquals = ll::SDLK_KP_EQUALS as isize,
418 Up = ll::SDLK_UP as isize,
419 Down = ll::SDLK_DOWN as isize,
420 Right = ll::SDLK_RIGHT as isize,
421 Left = ll::SDLK_LEFT as isize,
422 Insert = ll::SDLK_INSERT as isize,
423 Home = ll::SDLK_HOME as isize,
424 End = ll::SDLK_END as isize,
425 PageUp = ll::SDLK_PAGEUP as isize,
426 PageDown = ll::SDLK_PAGEDOWN as isize,
427 F1 = ll::SDLK_F1 as isize,
428 F2 = ll::SDLK_F2 as isize,
429 F3 = ll::SDLK_F3 as isize,
430 F4 = ll::SDLK_F4 as isize,
431 F5 = ll::SDLK_F5 as isize,
432 F6 = ll::SDLK_F6 as isize,
433 F7 = ll::SDLK_F7 as isize,
434 F8 = ll::SDLK_F8 as isize,
435 F9 = ll::SDLK_F9 as isize,
436 F10 = ll::SDLK_F10 as isize,
437 F11 = ll::SDLK_F11 as isize,
438 F12 = ll::SDLK_F12 as isize,
439 F13 = ll::SDLK_F13 as isize,
440 F14 = ll::SDLK_F14 as isize,
441 F15 = ll::SDLK_F15 as isize,
442 NumLock = ll::SDLK_NUMLOCK as isize,
443 CapsLock = ll::SDLK_CAPSLOCK as isize,
444 ScrolLock = ll::SDLK_SCROLLOCK as isize,
445 RShift = ll::SDLK_RSHIFT as isize,
446 LShift = ll::SDLK_LSHIFT as isize,
447 RCtrl = ll::SDLK_RCTRL as isize,
448 LCtrl = ll::SDLK_LCTRL as isize,
449 RAlt = ll::SDLK_RALT as isize,
450 LAlt = ll::SDLK_LALT as isize,
451 RMeta = ll::SDLK_RMETA as isize,
452 LMeta = ll::SDLK_LMETA as isize,
453 LSuper = ll::SDLK_LSUPER as isize,
454 RSuper = ll::SDLK_RSUPER as isize,
455 Mode = ll::SDLK_MODE as isize,
456 Compose = ll::SDLK_COMPOSE as isize,
457 Help = ll::SDLK_HELP as isize,
458 Print = ll::SDLK_PRINT as isize,
459 SysReq = ll::SDLK_SYSREQ as isize,
460 Break = ll::SDLK_BREAK as isize,
461 Menu = ll::SDLK_MENU as isize,
462 Power = ll::SDLK_POWER as isize,
463 Euro = ll::SDLK_EURO as isize,
464 Undo = ll::SDLK_UNDO as isize,
465 Last,
466}
467
468impl FromPrimitive for Key {
469 fn from_i64(n: i64) -> Option<Key> {
470 use self::Key::*;
471
472 Some(match n as ll::SDLKey {
473 ll::SDLK_UNKNOWN => Unknown,
474 ll::SDLK_BACKSPACE => Backspace,
475 ll::SDLK_TAB => Tab,
476 ll::SDLK_CLEAR => Clear,
477 ll::SDLK_RETURN => Return,
478 ll::SDLK_PAUSE => Pause,
479 ll::SDLK_ESCAPE => Escape,
480 ll::SDLK_SPACE => Space,
481 ll::SDLK_EXCLAIM => Exclaim,
482 ll::SDLK_QUOTEDBL => Quotedbl,
483 ll::SDLK_HASH => Hash,
484 ll::SDLK_DOLLAR => Dollar,
485 ll::SDLK_AMPERSAND => Ampersand,
486 ll::SDLK_QUOTE => Quote,
487 ll::SDLK_LEFTPAREN => LeftParen,
488 ll::SDLK_RIGHTPAREN => RightParen,
489 ll::SDLK_ASTERISK => Asterisk,
490 ll::SDLK_PLUS => Plus,
491 ll::SDLK_COMMA => Comma,
492 ll::SDLK_MINUS => Minus,
493 ll::SDLK_PERIOD => Period,
494 ll::SDLK_SLASH => Slash,
495 ll::SDLK_0 => Num0,
496 ll::SDLK_1 => Num1,
497 ll::SDLK_2 => Num2,
498 ll::SDLK_3 => Num3,
499 ll::SDLK_4 => Num4,
500 ll::SDLK_5 => Num5,
501 ll::SDLK_6 => Num6,
502 ll::SDLK_7 => Num7,
503 ll::SDLK_8 => Num8,
504 ll::SDLK_9 => Num9,
505 ll::SDLK_COLON => Colon,
506 ll::SDLK_SEMICOLON => Semicolon,
507 ll::SDLK_LESS => Less,
508 ll::SDLK_EQUALS => Equals,
509 ll::SDLK_GREATER => Greater,
510 ll::SDLK_QUESTION => Question,
511 ll::SDLK_AT => At,
512 ll::SDLK_LEFTBRACKET => LeftBracket,
513 ll::SDLK_BACKSLASH => Backslash,
514 ll::SDLK_RIGHTBRACKET => RightBracket,
515 ll::SDLK_CARET => Caret,
516 ll::SDLK_UNDERSCORE => Underscore,
517 ll::SDLK_BACKQUOTE => Backquote,
518 ll::SDLK_a => A,
519 ll::SDLK_b => B,
520 ll::SDLK_c => C,
521 ll::SDLK_d => D,
522 ll::SDLK_e => E,
523 ll::SDLK_f => F,
524 ll::SDLK_g => G,
525 ll::SDLK_h => H,
526 ll::SDLK_i => I,
527 ll::SDLK_j => J,
528 ll::SDLK_k => K,
529 ll::SDLK_l => L,
530 ll::SDLK_m => M,
531 ll::SDLK_n => N,
532 ll::SDLK_o => O,
533 ll::SDLK_p => P,
534 ll::SDLK_q => Q,
535 ll::SDLK_r => R,
536 ll::SDLK_s => S,
537 ll::SDLK_t => T,
538 ll::SDLK_u => U,
539 ll::SDLK_v => V,
540 ll::SDLK_w => W,
541 ll::SDLK_x => X,
542 ll::SDLK_y => Y,
543 ll::SDLK_z => Z,
544 ll::SDLK_DELETE => Delete,
545 ll::SDLK_WORLD_0 => World0,
546 ll::SDLK_WORLD_1 => World1,
547 ll::SDLK_WORLD_2 => World2,
548 ll::SDLK_WORLD_3 => World3,
549 ll::SDLK_WORLD_4 => World4,
550 ll::SDLK_WORLD_5 => World5,
551 ll::SDLK_WORLD_6 => World6,
552 ll::SDLK_WORLD_7 => World7,
553 ll::SDLK_WORLD_8 => World8,
554 ll::SDLK_WORLD_9 => World9,
555 ll::SDLK_WORLD_10 => World10,
556 ll::SDLK_WORLD_11 => World11,
557 ll::SDLK_WORLD_12 => World12,
558 ll::SDLK_WORLD_13 => World13,
559 ll::SDLK_WORLD_14 => World14,
560 ll::SDLK_WORLD_15 => World15,
561 ll::SDLK_WORLD_16 => World16,
562 ll::SDLK_WORLD_17 => World17,
563 ll::SDLK_WORLD_18 => World18,
564 ll::SDLK_WORLD_19 => World19,
565 ll::SDLK_WORLD_20 => World20,
566 ll::SDLK_WORLD_21 => World21,
567 ll::SDLK_WORLD_22 => World22,
568 ll::SDLK_WORLD_23 => World23,
569 ll::SDLK_WORLD_24 => World24,
570 ll::SDLK_WORLD_25 => World25,
571 ll::SDLK_WORLD_26 => World26,
572 ll::SDLK_WORLD_27 => World27,
573 ll::SDLK_WORLD_28 => World28,
574 ll::SDLK_WORLD_29 => World29,
575 ll::SDLK_WORLD_30 => World30,
576 ll::SDLK_WORLD_31 => World31,
577 ll::SDLK_WORLD_32 => World32,
578 ll::SDLK_WORLD_33 => World33,
579 ll::SDLK_WORLD_34 => World34,
580 ll::SDLK_WORLD_35 => World35,
581 ll::SDLK_WORLD_36 => World36,
582 ll::SDLK_WORLD_37 => World37,
583 ll::SDLK_WORLD_38 => World38,
584 ll::SDLK_WORLD_39 => World39,
585 ll::SDLK_WORLD_40 => World40,
586 ll::SDLK_WORLD_41 => World41,
587 ll::SDLK_WORLD_42 => World42,
588 ll::SDLK_WORLD_43 => World43,
589 ll::SDLK_WORLD_44 => World44,
590 ll::SDLK_WORLD_45 => World45,
591 ll::SDLK_WORLD_46 => World46,
592 ll::SDLK_WORLD_47 => World47,
593 ll::SDLK_WORLD_48 => World48,
594 ll::SDLK_WORLD_49 => World49,
595 ll::SDLK_WORLD_50 => World50,
596 ll::SDLK_WORLD_51 => World51,
597 ll::SDLK_WORLD_52 => World52,
598 ll::SDLK_WORLD_53 => World53,
599 ll::SDLK_WORLD_54 => World54,
600 ll::SDLK_WORLD_55 => World55,
601 ll::SDLK_WORLD_56 => World56,
602 ll::SDLK_WORLD_57 => World57,
603 ll::SDLK_WORLD_58 => World58,
604 ll::SDLK_WORLD_59 => World59,
605 ll::SDLK_WORLD_60 => World60,
606 ll::SDLK_WORLD_61 => World61,
607 ll::SDLK_WORLD_62 => World62,
608 ll::SDLK_WORLD_63 => World63,
609 ll::SDLK_WORLD_64 => World64,
610 ll::SDLK_WORLD_65 => World65,
611 ll::SDLK_WORLD_66 => World66,
612 ll::SDLK_WORLD_67 => World67,
613 ll::SDLK_WORLD_68 => World68,
614 ll::SDLK_WORLD_69 => World69,
615 ll::SDLK_WORLD_70 => World70,
616 ll::SDLK_WORLD_71 => World71,
617 ll::SDLK_WORLD_72 => World72,
618 ll::SDLK_WORLD_73 => World73,
619 ll::SDLK_WORLD_74 => World74,
620 ll::SDLK_WORLD_75 => World75,
621 ll::SDLK_WORLD_76 => World76,
622 ll::SDLK_WORLD_77 => World77,
623 ll::SDLK_WORLD_78 => World78,
624 ll::SDLK_WORLD_79 => World79,
625 ll::SDLK_WORLD_80 => World80,
626 ll::SDLK_WORLD_81 => World81,
627 ll::SDLK_WORLD_82 => World82,
628 ll::SDLK_WORLD_83 => World83,
629 ll::SDLK_WORLD_84 => World84,
630 ll::SDLK_WORLD_85 => World85,
631 ll::SDLK_WORLD_86 => World86,
632 ll::SDLK_WORLD_87 => World87,
633 ll::SDLK_WORLD_88 => World88,
634 ll::SDLK_WORLD_89 => World89,
635 ll::SDLK_WORLD_90 => World90,
636 ll::SDLK_WORLD_91 => World91,
637 ll::SDLK_WORLD_92 => World92,
638 ll::SDLK_WORLD_93 => World93,
639 ll::SDLK_WORLD_94 => World94,
640 ll::SDLK_WORLD_95 => World95,
641 ll::SDLK_KP0 => Kp0,
642 ll::SDLK_KP1 => Kp1,
643 ll::SDLK_KP2 => Kp2,
644 ll::SDLK_KP3 => Kp3,
645 ll::SDLK_KP4 => Kp4,
646 ll::SDLK_KP5 => Kp5,
647 ll::SDLK_KP6 => Kp6,
648 ll::SDLK_KP7 => Kp7,
649 ll::SDLK_KP8 => Kp8,
650 ll::SDLK_KP9 => Kp9,
651 ll::SDLK_KP_PERIOD => KpPeriod,
652 ll::SDLK_KP_DIVIDE => KpDivide,
653 ll::SDLK_KP_MULTIPLY => KpMultiply,
654 ll::SDLK_KP_MINUS => KpMinus,
655 ll::SDLK_KP_PLUS => KpPlus,
656 ll::SDLK_KP_ENTER => KpEnter,
657 ll::SDLK_KP_EQUALS => KpEquals,
658 ll::SDLK_UP => Up,
659 ll::SDLK_DOWN => Down,
660 ll::SDLK_RIGHT => Right,
661 ll::SDLK_LEFT => Left,
662 ll::SDLK_INSERT => Insert,
663 ll::SDLK_HOME => Home,
664 ll::SDLK_END => End,
665 ll::SDLK_PAGEUP => PageUp,
666 ll::SDLK_PAGEDOWN => PageDown,
667 ll::SDLK_F1 => F1,
668 ll::SDLK_F2 => F2,
669 ll::SDLK_F3 => F3,
670 ll::SDLK_F4 => F4,
671 ll::SDLK_F5 => F5,
672 ll::SDLK_F6 => F6,
673 ll::SDLK_F7 => F7,
674 ll::SDLK_F8 => F8,
675 ll::SDLK_F9 => F9,
676 ll::SDLK_F10 => F10,
677 ll::SDLK_F11 => F11,
678 ll::SDLK_F12 => F12,
679 ll::SDLK_F13 => F13,
680 ll::SDLK_F14 => F14,
681 ll::SDLK_F15 => F15,
682 ll::SDLK_NUMLOCK => NumLock,
683 ll::SDLK_CAPSLOCK => CapsLock,
684 ll::SDLK_SCROLLOCK => ScrolLock,
685 ll::SDLK_RSHIFT => RShift,
686 ll::SDLK_LSHIFT => LShift,
687 ll::SDLK_RCTRL => RCtrl,
688 ll::SDLK_LCTRL => LCtrl,
689 ll::SDLK_RALT => RAlt,
690 ll::SDLK_LALT => LAlt,
691 ll::SDLK_RMETA => RMeta,
692 ll::SDLK_LMETA => LMeta,
693 ll::SDLK_LSUPER => LSuper,
694 ll::SDLK_RSUPER => RSuper,
695 ll::SDLK_MODE => Mode,
696 ll::SDLK_COMPOSE => Compose,
697 ll::SDLK_HELP => Help,
698 ll::SDLK_PRINT => Print,
699 ll::SDLK_SYSREQ => SysReq,
700 ll::SDLK_BREAK => Break,
701 ll::SDLK_MENU => Menu,
702 ll::SDLK_POWER => Power,
703 ll::SDLK_EURO => Euro,
704 ll::SDLK_UNDO => Undo,
705 _ => return None,
706 })
707 }
708
709 fn from_u64(n: u64) -> Option<Key> {
710 FromPrimitive::from_i64(n as i64)
711 }
712}
713
714fn wrap_key(i: ll::SDLKey) -> Option<Key> {
715 FromPrimitive::from_usize(i as usize)
716}
717
718#[derive(Debug, PartialEq, Eq, Copy, Clone)]
719pub enum Mod {
720 None = 0x0000,
721 LShift = 0x0001,
722 RShift = 0x0002,
723 LCtrl = 0x0040,
724 RCtrl = 0x0080,
725 LAlt = 0x0100,
726 RAlt = 0x0200,
727 LMeta = 0x0400,
728 RMeta = 0x0800,
729 Num = 0x1000,
730 Caps = 0x2000,
731 Mode = 0x4000,
732 Reserved = 0x8000,
733}
734
735fn wrap_mod_state(bitflags: ll::SDLMod) -> Vec<Mod> {
736 let flags = [
737 Mod::None,
738 Mod::LShift,
739 Mod::RShift,
740 Mod::LCtrl,
741 Mod::RCtrl,
742 Mod::LAlt,
743 Mod::RAlt,
744 Mod::LMeta,
745 Mod::RMeta,
746 Mod::Num,
747 Mod::Caps,
748 Mod::Mode,
749 Mod::Reserved,
750 ];
751
752 flags
753 .iter()
754 .filter_map(|&flag| {
755 if bitflags & (flag as ll::SDLMod) != 0 {
756 Some(flag)
757 } else {
758 None
759 }
760 })
761 .collect()
762}
763
764#[derive(Debug, PartialEq, Eq, Copy, Clone)]
765pub enum HatState {
766 Centered,
767 Up,
768 Right,
769 Down,
770 Left,
771}
772
773#[derive(Debug, PartialEq, Eq, Copy, Clone)]
774pub enum Mouse {
775 Left = 1,
776 Middle,
777 Right,
778 WheelUp,
779 WheelDown,
780}
781
782impl FromPrimitive for Mouse {
783 fn from_i64(n: i64) -> Option<Mouse> {
784 Some(match n {
785 1 => Mouse::Left,
786 2 => Mouse::Middle,
787 3 => Mouse::Right,
788 4 => Mouse::WheelUp,
789 5 => Mouse::WheelDown,
790 _ => return None,
791 })
792 }
793
794 fn from_u64(n: u64) -> Option<Mouse> {
795 FromPrimitive::from_i64(n as i64)
796 }
797}
798
799fn wrap_mouse(bitflags: u8) -> Option<Mouse> {
800 FromPrimitive::from_u8(bitflags)
801}
802
803#[derive(Debug, PartialEq, Eq, Copy, Clone)]
804pub enum MouseState {
805 Left = 1,
806 Middle,
807 Right,
808 WheelUp,
809 WheelDown,
810 X1,
811 X2,
812}
813
814fn wrap_mouse_state(bitflags: u8) -> Vec<MouseState> {
815 let flags = [
816 MouseState::Left,
817 MouseState::Middle,
818 MouseState::Right,
819 MouseState::WheelUp,
820 MouseState::WheelDown,
821 MouseState::X1,
822 MouseState::X2,
823 ];
824
825 flags
826 .iter()
827 .filter_map(|&flag| {
828 if bitflags & (flag as u8) != 0 {
829 Some(flag)
830 } else {
831 None
832 }
833 })
834 .collect()
835}
836
837#[derive(Debug, PartialEq)]
838pub enum Event {
839 None,
841 Active(bool, Vec<AppState>),
842 Key(Key, bool, Vec<Mod>, u16),
843 MouseMotion(Vec<MouseState>, u16, u16, i16, i16),
845 MouseButton(Mouse, bool, u16, u16),
846 JoyAxis(isize, isize, i16),
847 JoyBall(isize, isize, i16, i16),
848 JoyHat(isize, isize, Vec<HatState>),
849 JoyButton(isize, isize, bool),
850 Quit,
851 Resize(isize, isize),
853 Expose,
854 }
856
857fn null_event() -> ll::SDL_Event {
858 ll::SDL_Event { data: [0; 24] }
859}
860
861fn wrap_event(raw: ll::SDL_Event) -> Event {
862 unsafe {
863 let ty = raw._type();
864 let ty = if ty.is_null() {
865 return Event::None;
866 } else {
867 *ty
868 };
869
870 let ty: EventType = match FromPrimitive::from_usize(ty as usize) {
871 Some(ty) => ty,
872 None => return Event::None,
873 };
874
875 match ty {
876 EventType::None => Event::None,
877 EventType::Active => {
878 let active = raw.active();
879 let active = if active.is_null() {
880 return Event::None;
881 } else {
882 *active
883 };
884
885 Event::Active(active.gain == 1, wrap_app_state(active.state))
886 }
887 EventType::KeyDown | EventType::KeyUp => {
888 let key = raw.key();
889 let (key, okey) = if key.is_null() {
890 return Event::None;
891 } else {
892 ((*key).keysym, *key)
893 };
894
895 match wrap_key(key.sym) {
896 Some(sym) => {
897 Event::Key(sym, okey.state == 1, wrap_mod_state(key._mod), key.unicode)
898 }
899 None => Event::None,
900 }
901 }
902 EventType::MouseMotion => {
903 let motion = raw.motion();
904 let motion = if motion.is_null() {
905 return Event::None;
906 } else {
907 *motion
908 };
909
910 Event::MouseMotion(
911 wrap_mouse_state(motion.state),
912 motion.x,
913 motion.y,
914 motion.xrel,
915 motion.yrel,
916 )
917 }
918 EventType::MouseButtonDown | EventType::MouseButtonUp => {
919 let obutton = raw.button();
920 let obutton = if obutton.is_null() {
921 return Event::None;
922 } else {
923 *obutton
924 };
925
926 match wrap_mouse(obutton.button) {
927 Some(button) => {
928 Event::MouseButton(button, obutton.state == 1, obutton.x, obutton.y)
929 }
930 None => Event::None,
931 }
932 }
933 EventType::Quit => Event::Quit,
934 EventType::Resize => {
935 let resize = raw.resize();
936 let resize = if resize.is_null() {
937 return Event::None;
938 } else {
939 *resize
940 };
941
942 Event::Resize(resize.w as isize, resize.h as isize)
943 }
944 EventType::Expose => Event::Expose,
945 _ => Event::None,
946 }
947 }
948}
949
950#[derive(Debug, PartialEq, Eq, Copy, Clone)]
951pub enum EventType {
952 None = ll::SDL_NOEVENT as isize,
954 Active = ll::SDL_ACTIVEEVENT as isize,
955 KeyDown = ll::SDL_KEYDOWN as isize,
956 KeyUp = ll::SDL_KEYUP as isize,
957 MouseMotion = ll::SDL_MOUSEMOTION as isize,
958 MouseButtonDown = ll::SDL_MOUSEBUTTONDOWN as isize,
959 MouseButtonUp = ll::SDL_MOUSEBUTTONUP as isize,
960 JoyAxisMotion = ll::SDL_JOYAXISMOTION as isize,
961 JoyBallMotion = ll::SDL_JOYBALLMOTION as isize,
962 JoyHatMotion = ll::SDL_JOYHATMOTION as isize,
963 JoyButtonDown = ll::SDL_JOYBUTTONDOWN as isize,
964 JoyButtonUp = ll::SDL_JOYBUTTONUP as isize,
965 Quit = ll::SDL_QUIT as isize,
966 SysWM = ll::SDL_SYSWMEVENT as isize,
967 Resize = ll::SDL_VIDEORESIZE as isize,
968 Expose = ll::SDL_VIDEOEXPOSE as isize,
969 User = ll::SDL_USEREVENT as isize,
970}
971
972impl EventType {
973 pub fn get_state(self) -> bool {
974 get_event_state(self)
975 }
976 pub fn set_state(self, state: bool) {
977 set_event_state(self, state)
978 }
979}
980
981impl FromPrimitive for EventType {
982 fn from_i64(n: i64) -> Option<EventType> {
983 Some(match n as ll::SDL_EventType {
984 ll::SDL_NOEVENT => EventType::None,
985 ll::SDL_ACTIVEEVENT => EventType::Active,
986 ll::SDL_KEYDOWN => EventType::KeyDown,
987 ll::SDL_KEYUP => EventType::KeyUp,
988 ll::SDL_MOUSEMOTION => EventType::MouseMotion,
989 ll::SDL_MOUSEBUTTONDOWN => EventType::MouseButtonDown,
990 ll::SDL_MOUSEBUTTONUP => EventType::MouseButtonUp,
991 ll::SDL_JOYAXISMOTION => EventType::JoyAxisMotion,
992 ll::SDL_JOYBALLMOTION => EventType::JoyBallMotion,
993 ll::SDL_JOYHATMOTION => EventType::JoyHatMotion,
994 ll::SDL_JOYBUTTONDOWN => EventType::JoyButtonDown,
995 ll::SDL_JOYBUTTONUP => EventType::JoyButtonUp,
996 ll::SDL_QUIT => EventType::Quit,
997 ll::SDL_SYSWMEVENT => EventType::SysWM,
998 ll::SDL_VIDEORESIZE => EventType::Resize,
999 ll::SDL_VIDEOEXPOSE => EventType::Expose,
1000 ll::SDL_USEREVENT => EventType::User,
1001 _ => return None,
1002 })
1003 }
1004
1005 fn from_u64(n: u64) -> Option<EventType> {
1006 FromPrimitive::from_i64(n as i64)
1007 }
1008}
1009
1010pub fn pump_events() {
1011 unsafe {
1012 ll::SDL_PumpEvents();
1013 }
1014}
1015
1016pub fn wait_event() -> Event {
1019 let mut raw = null_event();
1020 let success = unsafe { ll::SDL_WaitEvent(&mut raw) == 1 as c_int };
1021
1022 if success {
1023 wrap_event(raw)
1024 } else {
1025 Event::None
1026 }
1027}
1028
1029pub fn poll_event() -> Event {
1030 pump_events();
1031
1032 let mut raw = null_event();
1033 let have = unsafe { ll::SDL_PollEvent(&mut raw) };
1034
1035 if have != 1 {
1036 return Event::None;
1037 }
1038
1039 wrap_event(raw)
1040}
1041
1042pub fn set_event_state(ty: EventType, state: bool) {
1045 unsafe {
1046 ll::SDL_EventState(ty as u8, state as c_int);
1047 }
1048}
1049
1050pub fn get_event_state(ty: EventType) -> bool {
1051 unsafe { ll::SDL_EventState(ty as u8, ll::SDL_QUERY as c_int) == ll::SDL_ENABLE as u8 }
1052}
1053
1054pub fn get_key_state() -> Vec<(Key, bool)> {
1055 let mut num = 0;
1056 let data = unsafe { ll::SDL_GetKeyState(&mut num) };
1057 let mut i = -1isize;
1058
1059 let buf = data as *const u8;
1060 let buf = unsafe { slice::from_raw_parts(buf, num as usize) };
1061 buf.iter()
1062 .filter_map(|&state| {
1063 i += 1;
1064
1065 match wrap_key(i as ll::SDLKey) {
1066 Some(key) => Some((key, state == 1)),
1067 None => None,
1068 }
1069 })
1070 .collect()
1071}
1072
1073pub fn get_mod_state() -> Vec<Mod> {
1074 unsafe { wrap_mod_state(ll::SDL_GetModState()) }
1075}
1076
1077pub fn set_mod_state(states: &[Mod]) {
1078 unsafe {
1079 ll::SDL_SetModState(
1080 states
1081 .iter()
1082 .fold(0u32, |states, &state| states | state as ll::SDLMod),
1083 );
1084 }
1085}
1086
1087pub fn get_key_name(key: Key) -> String {
1088 unsafe {
1089 let cstr = ll::SDL_GetKeyName(key as ll::SDLKey);
1090
1091 str::from_utf8(CStr::from_ptr(mem::transmute_copy(&cstr)).to_bytes())
1092 .unwrap()
1093 .to_string()
1094 }
1095}
1096
1097pub fn get_app_state() -> Vec<AppState> {
1098 let bitflags = unsafe { ll::SDL_GetAppState() };
1099
1100 wrap_app_state(bitflags)
1101}
1102
1103pub fn enable_unicode(enable: bool) {
1104 unsafe {
1105 ll::SDL_EnableUNICODE(enable as c_int);
1106 }
1107}
1108
1109pub fn is_unicode_enabled() -> bool {
1110 unsafe { ll::SDL_EnableUNICODE(-1 as c_int) == 1 }
1111}
1112
1113pub fn enable_key_repeat(delay: RepeatDelay, interval: RepeatInterval) -> bool {
1114 let delay = match delay {
1115 RepeatDelay::Default => 500,
1116 RepeatDelay::Custom(delay) => delay,
1117 };
1118 let interval = match interval {
1119 RepeatInterval::Default => 30,
1120 RepeatInterval::Custom(interval) => interval,
1121 };
1122
1123 unsafe { ll::SDL_EnableKeyRepeat(delay as c_int, interval as c_int) == 0 as c_int }
1124}
1125
1126