1use core::ops::{Deref, DerefMut};
4use core::{char, mem, slice};
5
6pub const EVENT_NONE: i64 = 0;
7pub const EVENT_KEY: i64 = 1;
8pub const EVENT_MOUSE: i64 = 2;
9pub const EVENT_BUTTON: i64 = 3;
10pub const EVENT_SCROLL: i64 = 4;
11pub const EVENT_QUIT: i64 = 5;
12pub const EVENT_FOCUS: i64 = 6;
13pub const EVENT_MOVE: i64 = 7;
14pub const EVENT_RESIZE: i64 = 8;
15pub const EVENT_SCREEN: i64 = 9;
16pub const EVENT_CLIPBOARD: i64 = 10;
17pub const EVENT_MOUSE_RELATIVE: i64 = 11;
18pub const EVENT_DROP: i64 = 12;
19pub const EVENT_TEXT_INPUT: i64 = 13;
20pub const EVENT_CLIPBOARD_UPDATE: i64 = 14;
21pub const EVENT_HOVER: i64 = 15;
22
23#[derive(Copy, Clone, Debug)]
25pub enum EventOption {
26 Key(KeyEvent),
28 TextInput(TextInputEvent),
30 Mouse(MouseEvent),
32 MouseRelative(MouseRelativeEvent),
34 Button(ButtonEvent),
36 Scroll(ScrollEvent),
38 Quit(QuitEvent),
40 Focus(FocusEvent),
42 Move(MoveEvent),
44 Resize(ResizeEvent),
46 Screen(ScreenEvent),
48 Clipboard(ClipboardEvent),
50 ClipboardUpdate(ClipboardUpdateEvent),
52 Drop(DropEvent),
54 Hover(HoverEvent),
56 Unknown(Event),
58 None,
60}
61
62#[derive(Copy, Clone, Debug)]
64#[repr(packed)]
65pub struct Event {
66 pub code: i64,
67 pub a: i64,
68 pub b: i64,
69}
70
71#[allow(clippy::new_without_default)]
72impl Event {
73 pub fn new() -> Event {
75 Event {
76 code: 0,
77 a: 0,
78 b: 0,
79 }
80 }
81
82 pub fn to_option(self) -> EventOption {
85 match self.code {
86 EVENT_NONE => EventOption::None,
87 EVENT_KEY => EventOption::Key(KeyEvent::from_event(self)),
88 EVENT_TEXT_INPUT => EventOption::TextInput(TextInputEvent::from_event(self)),
89 EVENT_MOUSE => EventOption::Mouse(MouseEvent::from_event(self)),
90 EVENT_MOUSE_RELATIVE => {
91 EventOption::MouseRelative(MouseRelativeEvent::from_event(self))
92 }
93 EVENT_BUTTON => EventOption::Button(ButtonEvent::from_event(self)),
94 EVENT_SCROLL => EventOption::Scroll(ScrollEvent::from_event(self)),
95 EVENT_QUIT => EventOption::Quit(QuitEvent::from_event(self)),
96 EVENT_FOCUS => EventOption::Focus(FocusEvent::from_event(self)),
97 EVENT_MOVE => EventOption::Move(MoveEvent::from_event(self)),
98 EVENT_RESIZE => EventOption::Resize(ResizeEvent::from_event(self)),
99 EVENT_SCREEN => EventOption::Screen(ScreenEvent::from_event(self)),
100 EVENT_CLIPBOARD => EventOption::Clipboard(ClipboardEvent::from_event(self)),
101 EVENT_CLIPBOARD_UPDATE => {
102 EventOption::ClipboardUpdate(ClipboardUpdateEvent::from_event(self))
103 }
104 EVENT_DROP => EventOption::Drop(DropEvent::from_event(self)),
105 EVENT_HOVER => EventOption::Hover(HoverEvent::from_event(self)),
106 _ => EventOption::Unknown(self),
107 }
108 }
109}
110
111impl Deref for Event {
112 type Target = [u8];
113 fn deref(&self) -> &[u8] {
114 unsafe {
115 slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::<Event>())
116 as &[u8]
117 }
118 }
119}
120
121impl DerefMut for Event {
122 fn deref_mut(&mut self) -> &mut [u8] {
123 unsafe {
124 slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::<Event>())
125 as &mut [u8]
126 }
127 }
128}
129
130pub const K_A: u8 = 0x1E;
135pub const K_B: u8 = 0x30;
136pub const K_C: u8 = 0x2E;
137pub const K_D: u8 = 0x20;
138pub const K_E: u8 = 0x12;
139pub const K_F: u8 = 0x21;
140pub const K_G: u8 = 0x22;
141pub const K_H: u8 = 0x23;
142pub const K_I: u8 = 0x17;
143pub const K_J: u8 = 0x24;
144pub const K_K: u8 = 0x25;
145pub const K_L: u8 = 0x26;
146pub const K_M: u8 = 0x32;
147pub const K_N: u8 = 0x31;
148pub const K_O: u8 = 0x18;
149pub const K_P: u8 = 0x19;
150pub const K_Q: u8 = 0x10;
151pub const K_R: u8 = 0x13;
152pub const K_S: u8 = 0x1F;
153pub const K_T: u8 = 0x14;
154pub const K_U: u8 = 0x16;
155pub const K_V: u8 = 0x2F;
156pub const K_W: u8 = 0x11;
157pub const K_X: u8 = 0x2D;
158pub const K_Y: u8 = 0x15;
159pub const K_Z: u8 = 0x2C;
160pub const K_0: u8 = 0x0B;
161pub const K_1: u8 = 0x02;
162pub const K_2: u8 = 0x03;
163pub const K_3: u8 = 0x04;
164pub const K_4: u8 = 0x05;
165pub const K_5: u8 = 0x06;
166pub const K_6: u8 = 0x07;
167pub const K_7: u8 = 0x08;
168pub const K_8: u8 = 0x09;
169pub const K_9: u8 = 0x0A;
170
171pub const K_NUM_0: u8 = 0x70;
174pub const K_NUM_1: u8 = 0x71;
175pub const K_NUM_2: u8 = 0x72;
176pub const K_NUM_3: u8 = 0x73;
177pub const K_NUM_4: u8 = 0x74;
178pub const K_NUM_5: u8 = 0x75;
179pub const K_NUM_6: u8 = 0x76;
180pub const K_NUM_7: u8 = 0x77;
181pub const K_NUM_8: u8 = 0x78;
182pub const K_NUM_9: u8 = 0x79;
183pub const K_NUM_PERIOD: u8 = 0x7a;
184pub const K_NUM_PLUS: u8 = 0x7c;
185pub const K_NUM_MINUS: u8 = 0x7b;
186pub const K_NUM_ASTERISK: u8 = 0x7d;
187pub const K_NUM_SLASH: u8 = 0x7e;
188pub const K_NUM_ENTER: u8 = 0x7f;
189
190pub const K_TICK: u8 = 0x29;
192pub const K_MINUS: u8 = 0x0C;
194pub const K_EQUALS: u8 = 0x0D;
196pub const K_BACKSLASH: u8 = 0x2B;
198pub const K_BRACE_OPEN: u8 = 0x1A;
200pub const K_BRACE_CLOSE: u8 = 0x1B;
202pub const K_SEMICOLON: u8 = 0x27;
204pub const K_QUOTE: u8 = 0x28;
206pub const K_COMMA: u8 = 0x33;
208pub const K_PERIOD: u8 = 0x34;
210pub const K_SLASH: u8 = 0x35;
212pub const K_BKSP: u8 = 0x0E;
214pub const K_SPACE: u8 = 0x39;
216pub const K_TAB: u8 = 0x0F;
218pub const K_CAPS: u8 = 0x3A;
220pub const K_LEFT_SHIFT: u8 = 0x2A;
222pub const K_RIGHT_SHIFT: u8 = 0x36;
224pub const K_CTRL: u8 = 0x1D;
226pub const K_LEFT_CTRL: u8 = 0x1D;
228pub const K_RIGHT_CTRL: u8 = 0x64;
230pub const K_ALT: u8 = 0x38;
232pub const K_ALT_GR: u8 = 0x64;
234pub const K_ENTER: u8 = 0x1C;
236pub const K_ESC: u8 = 0x01;
238pub const K_PRTSC: u8 = 0x37;
240pub const K_F1: u8 = 0x3B;
242pub const K_F2: u8 = 0x3C;
244pub const K_F3: u8 = 0x3D;
246pub const K_F4: u8 = 0x3E;
248pub const K_F5: u8 = 0x3F;
250pub const K_F6: u8 = 0x40;
252pub const K_F7: u8 = 0x41;
254pub const K_F8: u8 = 0x42;
256pub const K_F9: u8 = 0x43;
258pub const K_F10: u8 = 0x44;
260pub const K_NUM: u8 = 0x45;
262pub const K_SCROLL: u8 = 0x46;
264pub const K_HOME: u8 = 0x47;
266pub const K_UP: u8 = 0x48;
268pub const K_PGUP: u8 = 0x49;
270pub const K_LEFT: u8 = 0x4B;
272pub const K_RIGHT: u8 = 0x4D;
274pub const K_END: u8 = 0x4F;
276pub const K_DOWN: u8 = 0x50;
278pub const K_PGDN: u8 = 0x51;
280pub const K_INS: u8 = 0x52;
282pub const K_DEL: u8 = 0x53;
284pub const K_F11: u8 = 0x57;
286pub const K_F12: u8 = 0x58;
288pub const K_SUPER: u8 = 0x5B;
290pub const K_LEFT_SUPER: u8 = 0x5B;
292pub const K_RIGHT_SUPER: u8 = 0x5C;
294pub const K_APP: u8 = 0x5D;
296pub const K_POWER: u8 = 0x5E;
298pub const K_SLEEP: u8 = 0x5F;
300
301pub const K_VOLUME_TOGGLE: u8 = 0x80 + 0x20;
306pub const K_VOLUME_DOWN: u8 = 0x80 + 0x2E;
308pub const K_VOLUME_UP: u8 = 0x80 + 0x30;
310pub const K_MEDIA_PLAY_PAUSE: u8 = 0x80 + 0x22;
312pub const K_MEDIA_STOP: u8 = 0x80 + 0x24;
314pub const K_MEDIA_FAST_FORWARD: u8 = 0x80 + 0x19;
316pub const K_MEDIA_REWIND: u8 = 0x80 + 0x10;
318
319#[derive(Copy, Clone, Debug)]
321pub struct KeyEvent {
322 pub character: char,
324 pub scancode: u8,
326 pub pressed: bool,
328}
329
330impl KeyEvent {
331 pub fn to_event(&self) -> Event {
333 Event {
334 code: EVENT_KEY,
335 a: self.character as i64,
336 b: self.scancode as i64 | (self.pressed as i64) << 8,
337 }
338 }
339
340 pub fn from_event(event: Event) -> KeyEvent {
342 KeyEvent {
343 character: char::from_u32(event.a as u32).unwrap_or('\0'),
344 scancode: event.b as u8,
345 pressed: event.b & 1 << 8 == 1 << 8,
346 }
347 }
348}
349
350#[derive(Copy, Clone, Debug)]
351pub struct TextInputEvent {
352 pub character: char,
353}
354
355impl TextInputEvent {
356 pub fn to_event(&self) -> Event {
358 Event {
359 code: EVENT_TEXT_INPUT,
360 a: self.character as i64,
361 b: 0,
362 }
363 }
364
365 pub fn from_event(event: Event) -> TextInputEvent {
367 TextInputEvent {
368 character: char::from_u32(event.a as u32).unwrap_or('\0'),
369 }
370 }
371}
372
373#[derive(Copy, Clone, Debug)]
375pub struct MouseEvent {
376 pub x: i32,
378 pub y: i32,
380}
381
382impl MouseEvent {
383 pub fn to_event(&self) -> Event {
385 Event {
386 code: EVENT_MOUSE,
387 a: self.x as i64,
388 b: self.y as i64,
389 }
390 }
391
392 pub fn from_event(event: Event) -> MouseEvent {
394 MouseEvent {
395 x: event.a as i32,
396 y: event.b as i32,
397 }
398 }
399}
400
401#[derive(Copy, Clone, Debug)]
403pub struct MouseRelativeEvent {
404 pub dx: i32,
406 pub dy: i32,
408}
409
410impl MouseRelativeEvent {
411 pub fn to_event(&self) -> Event {
413 Event {
414 code: EVENT_MOUSE_RELATIVE,
415 a: self.dx as i64,
416 b: self.dy as i64,
417 }
418 }
419
420 pub fn from_event(event: Event) -> MouseRelativeEvent {
422 MouseRelativeEvent {
423 dx: event.a as i32,
424 dy: event.b as i32,
425 }
426 }
427}
428
429#[derive(Copy, Clone, Debug)]
431pub struct ButtonEvent {
432 pub left: bool,
434 pub middle: bool,
436 pub right: bool,
438}
439
440impl ButtonEvent {
441 pub fn to_event(&self) -> Event {
443 Event {
444 code: EVENT_BUTTON,
445 a: self.left as i64 | (self.middle as i64) << 1 | (self.right as i64) << 2,
446 b: 0,
447 }
448 }
449
450 pub fn from_event(event: Event) -> ButtonEvent {
452 ButtonEvent {
453 left: event.a & 1 == 1,
454 middle: event.a & 2 == 2,
455 right: event.a & 4 == 4,
456 }
457 }
458}
459
460#[derive(Copy, Clone, Debug)]
462pub struct ScrollEvent {
463 pub x: i32,
465 pub y: i32,
467}
468
469impl ScrollEvent {
470 pub fn to_event(&self) -> Event {
472 Event {
473 code: EVENT_SCROLL,
474 a: self.x as i64,
475 b: self.y as i64,
476 }
477 }
478
479 pub fn from_event(event: Event) -> ScrollEvent {
481 ScrollEvent {
482 x: event.a as i32,
483 y: event.b as i32,
484 }
485 }
486}
487
488#[derive(Copy, Clone, Debug)]
489pub struct QuitEvent;
490
491impl QuitEvent {
492 pub fn to_event(&self) -> Event {
493 Event {
494 code: EVENT_QUIT,
495 a: 0,
496 b: 0,
497 }
498 }
499
500 pub fn from_event(_: Event) -> QuitEvent {
501 QuitEvent
502 }
503}
504
505#[derive(Copy, Clone, Debug)]
507pub struct FocusEvent {
508 pub focused: bool,
510}
511
512impl FocusEvent {
513 pub fn to_event(&self) -> Event {
514 Event {
515 code: EVENT_FOCUS,
516 a: self.focused as i64,
517 b: 0,
518 }
519 }
520
521 pub fn from_event(event: Event) -> FocusEvent {
522 FocusEvent {
523 focused: event.a > 0,
524 }
525 }
526}
527
528#[derive(Copy, Clone, Debug)]
530pub struct MoveEvent {
531 pub x: i32,
532 pub y: i32,
533}
534
535impl MoveEvent {
536 pub fn to_event(&self) -> Event {
537 Event {
538 code: EVENT_MOVE,
539 a: self.x as i64,
540 b: self.y as i64,
541 }
542 }
543
544 pub fn from_event(event: Event) -> MoveEvent {
545 MoveEvent {
546 x: event.a as i32,
547 y: event.b as i32,
548 }
549 }
550}
551
552#[derive(Copy, Clone, Debug)]
554pub struct ResizeEvent {
555 pub width: u32,
556 pub height: u32,
557}
558
559impl ResizeEvent {
560 pub fn to_event(&self) -> Event {
561 Event {
562 code: EVENT_RESIZE,
563 a: self.width as i64,
564 b: self.height as i64,
565 }
566 }
567
568 pub fn from_event(event: Event) -> ResizeEvent {
569 ResizeEvent {
570 width: event.a as u32,
571 height: event.b as u32,
572 }
573 }
574}
575
576#[derive(Copy, Clone, Debug)]
578pub struct ScreenEvent {
579 pub width: u32,
580 pub height: u32,
581}
582
583impl ScreenEvent {
584 pub fn to_event(&self) -> Event {
585 Event {
586 code: EVENT_SCREEN,
587 a: self.width as i64,
588 b: self.height as i64,
589 }
590 }
591
592 pub fn from_event(event: Event) -> ScreenEvent {
593 ScreenEvent {
594 width: event.a as u32,
595 height: event.b as u32,
596 }
597 }
598}
599
600pub const CLIPBOARD_COPY: u8 = 0;
601pub const CLIPBOARD_CUT: u8 = 1;
602pub const CLIPBOARD_PASTE: u8 = 2;
603
604#[derive(Copy, Clone, Debug)]
606pub struct ClipboardUpdateEvent;
607
608impl ClipboardUpdateEvent {
609 pub fn to_event(&self) -> Event {
610 Event {
611 code: EVENT_CLIPBOARD_UPDATE,
612 a: 0,
613 b: 0,
614 }
615 }
616
617 pub fn from_event(_: Event) -> ClipboardUpdateEvent {
618 ClipboardUpdateEvent
619 }
620}
621
622#[derive(Copy, Clone, Debug)]
624pub struct ClipboardEvent {
625 pub kind: u8,
626 pub size: usize,
627}
628
629impl ClipboardEvent {
630 pub fn to_event(&self) -> Event {
631 Event {
632 code: EVENT_CLIPBOARD,
633 a: self.kind as i64,
634 b: self.size as i64,
635 }
636 }
637
638 pub fn from_event(event: Event) -> ClipboardEvent {
639 ClipboardEvent {
640 kind: event.a as u8,
641 size: event.b as usize,
642 }
643 }
644}
645
646pub const DROP_FILE: u8 = 0;
647pub const DROP_TEXT: u8 = 1;
648
649#[derive(Copy, Clone, Debug)]
651pub struct DropEvent {
652 pub kind: u8,
653}
654
655impl DropEvent {
656 pub fn to_event(&self) -> Event {
657 Event {
658 code: EVENT_DROP,
659 a: self.kind as i64,
660 b: 0,
661 }
662 }
663
664 pub fn from_event(event: Event) -> DropEvent {
665 DropEvent {
666 kind: event.a as u8,
667 }
668 }
669}
670
671#[derive(Copy, Clone, Debug)]
673pub struct HoverEvent {
674 pub entered: bool,
676}
677
678impl HoverEvent {
679 pub fn to_event(&self) -> Event {
680 Event {
681 code: EVENT_HOVER,
682 a: self.entered as i64,
683 b: 0,
684 }
685 }
686
687 pub fn from_event(event: Event) -> HoverEvent {
688 HoverEvent {
689 entered: event.a > 0,
690 }
691 }
692}