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;
131pub const K_B: u8 = 0x30;
132pub const K_C: u8 = 0x2E;
133pub const K_D: u8 = 0x20;
134pub const K_E: u8 = 0x12;
135pub const K_F: u8 = 0x21;
136pub const K_G: u8 = 0x22;
137pub const K_H: u8 = 0x23;
138pub const K_I: u8 = 0x17;
139pub const K_J: u8 = 0x24;
140pub const K_K: u8 = 0x25;
141pub const K_L: u8 = 0x26;
142pub const K_M: u8 = 0x32;
143pub const K_N: u8 = 0x31;
144pub const K_O: u8 = 0x18;
145pub const K_P: u8 = 0x19;
146pub const K_Q: u8 = 0x10;
147pub const K_R: u8 = 0x13;
148pub const K_S: u8 = 0x1F;
149pub const K_T: u8 = 0x14;
150pub const K_U: u8 = 0x16;
151pub const K_V: u8 = 0x2F;
152pub const K_W: u8 = 0x11;
153pub const K_X: u8 = 0x2D;
154pub const K_Y: u8 = 0x15;
155pub const K_Z: u8 = 0x2C;
156pub const K_0: u8 = 0x0B;
157pub const K_1: u8 = 0x02;
158pub const K_2: u8 = 0x03;
159pub const K_3: u8 = 0x04;
160pub const K_4: u8 = 0x05;
161pub const K_5: u8 = 0x06;
162pub const K_6: u8 = 0x07;
163pub const K_7: u8 = 0x08;
164pub const K_8: u8 = 0x09;
165pub const K_9: u8 = 0x0A;
166
167pub const K_NUM_0: u8 = 0x70;
169pub const K_NUM_1: u8 = 0x71;
170pub const K_NUM_2: u8 = 0x72;
171pub const K_NUM_3: u8 = 0x73;
172pub const K_NUM_4: u8 = 0x74;
173pub const K_NUM_5: u8 = 0x75;
174pub const K_NUM_6: u8 = 0x76;
175pub const K_NUM_7: u8 = 0x77;
176pub const K_NUM_8: u8 = 0x78;
177pub const K_NUM_9: u8 = 0x79;
178
179pub const K_TICK: u8 = 0x29;
181pub const K_MINUS: u8 = 0x0C;
183pub const K_EQUALS: u8 = 0x0D;
185pub const K_BACKSLASH: u8 = 0x2B;
187pub const K_BRACE_OPEN: u8 = 0x1A;
189pub const K_BRACE_CLOSE: u8 = 0x1B;
191pub const K_SEMICOLON: u8 = 0x27;
193pub const K_QUOTE: u8 = 0x28;
195pub const K_COMMA: u8 = 0x33;
197pub const K_PERIOD: u8 = 0x34;
199pub const K_SLASH: u8 = 0x35;
201pub const K_BKSP: u8 = 0x0E;
203pub const K_SPACE: u8 = 0x39;
205pub const K_TAB: u8 = 0x0F;
207pub const K_CAPS: u8 = 0x3A;
209pub const K_LEFT_SHIFT: u8 = 0x2A;
211pub const K_RIGHT_SHIFT: u8 = 0x36;
213pub const K_CTRL: u8 = 0x1D;
215pub const K_ALT: u8 = 0x38;
217pub const K_ALT_GR: u8 = 0x64;
219pub const K_ENTER: u8 = 0x1C;
221pub const K_ESC: u8 = 0x01;
223pub const K_F1: u8 = 0x3B;
225pub const K_F2: u8 = 0x3C;
227pub const K_F3: u8 = 0x3D;
229pub const K_F4: u8 = 0x3E;
231pub const K_F5: u8 = 0x3F;
233pub const K_F6: u8 = 0x40;
235pub const K_F7: u8 = 0x41;
237pub const K_F8: u8 = 0x42;
239pub const K_F9: u8 = 0x43;
241pub const K_F10: u8 = 0x44;
243pub const K_HOME: u8 = 0x47;
245pub const K_UP: u8 = 0x48;
247pub const K_PGUP: u8 = 0x49;
249pub const K_LEFT: u8 = 0x4B;
251pub const K_RIGHT: u8 = 0x4D;
253pub const K_END: u8 = 0x4F;
255pub const K_DOWN: u8 = 0x50;
257pub const K_PGDN: u8 = 0x51;
259pub const K_DEL: u8 = 0x53;
261pub const K_F11: u8 = 0x57;
263pub const K_F12: u8 = 0x58;
265pub const K_SUPER: u8 = 0x5B;
267pub const K_VOLUME_TOGGLE: u8 = 0x80 + 0x20;
269pub const K_VOLUME_DOWN: u8 = 0x80 + 0x2E;
271pub const K_VOLUME_UP: u8 = 0x80 + 0x30;
273
274#[derive(Copy, Clone, Debug)]
276pub struct KeyEvent {
277 pub character: char,
279 pub scancode: u8,
281 pub pressed: bool,
283}
284
285impl KeyEvent {
286 pub fn to_event(&self) -> Event {
288 Event {
289 code: EVENT_KEY,
290 a: self.character as i64,
291 b: self.scancode as i64 | (self.pressed as i64) << 8,
292 }
293 }
294
295 pub fn from_event(event: Event) -> KeyEvent {
297 KeyEvent {
298 character: char::from_u32(event.a as u32).unwrap_or('\0'),
299 scancode: event.b as u8,
300 pressed: event.b & 1 << 8 == 1 << 8,
301 }
302 }
303}
304
305#[derive(Copy, Clone, Debug)]
306pub struct TextInputEvent {
307 pub character: char,
308}
309
310impl TextInputEvent {
311 pub fn to_event(&self) -> Event {
313 Event {
314 code: EVENT_TEXT_INPUT,
315 a: self.character as i64,
316 b: 0,
317 }
318 }
319
320 pub fn from_event(event: Event) -> TextInputEvent {
322 TextInputEvent {
323 character: char::from_u32(event.a as u32).unwrap_or('\0'),
324 }
325 }
326}
327
328#[derive(Copy, Clone, Debug)]
330pub struct MouseEvent {
331 pub x: i32,
333 pub y: i32,
335}
336
337impl MouseEvent {
338 pub fn to_event(&self) -> Event {
340 Event {
341 code: EVENT_MOUSE,
342 a: self.x as i64,
343 b: self.y as i64,
344 }
345 }
346
347 pub fn from_event(event: Event) -> MouseEvent {
349 MouseEvent {
350 x: event.a as i32,
351 y: event.b as i32,
352 }
353 }
354}
355
356#[derive(Copy, Clone, Debug)]
358pub struct MouseRelativeEvent {
359 pub dx: i32,
361 pub dy: i32,
363}
364
365impl MouseRelativeEvent {
366 pub fn to_event(&self) -> Event {
368 Event {
369 code: EVENT_MOUSE_RELATIVE,
370 a: self.dx as i64,
371 b: self.dy as i64,
372 }
373 }
374
375 pub fn from_event(event: Event) -> MouseRelativeEvent {
377 MouseRelativeEvent {
378 dx: event.a as i32,
379 dy: event.b as i32,
380 }
381 }
382}
383
384#[derive(Copy, Clone, Debug)]
386pub struct ButtonEvent {
387 pub left: bool,
389 pub middle: bool,
391 pub right: bool,
393}
394
395impl ButtonEvent {
396 pub fn to_event(&self) -> Event {
398 Event {
399 code: EVENT_BUTTON,
400 a: self.left as i64 | (self.middle as i64) << 1 | (self.right as i64) << 2,
401 b: 0,
402 }
403 }
404
405 pub fn from_event(event: Event) -> ButtonEvent {
407 ButtonEvent {
408 left: event.a & 1 == 1,
409 middle: event.a & 2 == 2,
410 right: event.a & 4 == 4,
411 }
412 }
413}
414
415#[derive(Copy, Clone, Debug)]
417pub struct ScrollEvent {
418 pub x: i32,
420 pub y: i32,
422}
423
424impl ScrollEvent {
425 pub fn to_event(&self) -> Event {
427 Event {
428 code: EVENT_SCROLL,
429 a: self.x as i64,
430 b: self.y as i64,
431 }
432 }
433
434 pub fn from_event(event: Event) -> ScrollEvent {
436 ScrollEvent {
437 x: event.a as i32,
438 y: event.b as i32,
439 }
440 }
441}
442
443#[derive(Copy, Clone, Debug)]
444pub struct QuitEvent;
445
446impl QuitEvent {
447 pub fn to_event(&self) -> Event {
448 Event {
449 code: EVENT_QUIT,
450 a: 0,
451 b: 0,
452 }
453 }
454
455 pub fn from_event(_: Event) -> QuitEvent {
456 QuitEvent
457 }
458}
459
460#[derive(Copy, Clone, Debug)]
462pub struct FocusEvent {
463 pub focused: bool,
465}
466
467impl FocusEvent {
468 pub fn to_event(&self) -> Event {
469 Event {
470 code: EVENT_FOCUS,
471 a: self.focused as i64,
472 b: 0,
473 }
474 }
475
476 pub fn from_event(event: Event) -> FocusEvent {
477 FocusEvent {
478 focused: event.a > 0,
479 }
480 }
481}
482
483#[derive(Copy, Clone, Debug)]
485pub struct MoveEvent {
486 pub x: i32,
487 pub y: i32,
488}
489
490impl MoveEvent {
491 pub fn to_event(&self) -> Event {
492 Event {
493 code: EVENT_MOVE,
494 a: self.x as i64,
495 b: self.y as i64,
496 }
497 }
498
499 pub fn from_event(event: Event) -> MoveEvent {
500 MoveEvent {
501 x: event.a as i32,
502 y: event.b as i32,
503 }
504 }
505}
506
507#[derive(Copy, Clone, Debug)]
509pub struct ResizeEvent {
510 pub width: u32,
511 pub height: u32,
512}
513
514impl ResizeEvent {
515 pub fn to_event(&self) -> Event {
516 Event {
517 code: EVENT_RESIZE,
518 a: self.width as i64,
519 b: self.height as i64,
520 }
521 }
522
523 pub fn from_event(event: Event) -> ResizeEvent {
524 ResizeEvent {
525 width: event.a as u32,
526 height: event.b as u32,
527 }
528 }
529}
530
531#[derive(Copy, Clone, Debug)]
533pub struct ScreenEvent {
534 pub width: u32,
535 pub height: u32,
536}
537
538impl ScreenEvent {
539 pub fn to_event(&self) -> Event {
540 Event {
541 code: EVENT_SCREEN,
542 a: self.width as i64,
543 b: self.height as i64,
544 }
545 }
546
547 pub fn from_event(event: Event) -> ScreenEvent {
548 ScreenEvent {
549 width: event.a as u32,
550 height: event.b as u32,
551 }
552 }
553}
554
555pub const CLIPBOARD_COPY: u8 = 0;
556pub const CLIPBOARD_CUT: u8 = 1;
557pub const CLIPBOARD_PASTE: u8 = 2;
558
559#[derive(Copy, Clone, Debug)]
561pub struct ClipboardUpdateEvent;
562
563impl ClipboardUpdateEvent {
564 pub fn to_event(&self) -> Event {
565 Event {
566 code: EVENT_CLIPBOARD_UPDATE,
567 a: 0,
568 b: 0,
569 }
570 }
571
572 pub fn from_event(_: Event) -> ClipboardUpdateEvent {
573 ClipboardUpdateEvent
574 }
575}
576
577#[derive(Copy, Clone, Debug)]
579pub struct ClipboardEvent {
580 pub kind: u8,
581 pub size: usize,
582}
583
584impl ClipboardEvent {
585 pub fn to_event(&self) -> Event {
586 Event {
587 code: EVENT_CLIPBOARD,
588 a: self.kind as i64,
589 b: self.size as i64,
590 }
591 }
592
593 pub fn from_event(event: Event) -> ClipboardEvent {
594 ClipboardEvent {
595 kind: event.a as u8,
596 size: event.b as usize,
597 }
598 }
599}
600
601pub const DROP_FILE: u8 = 0;
602pub const DROP_TEXT: u8 = 1;
603
604#[derive(Copy, Clone, Debug)]
606pub struct DropEvent {
607 pub kind: u8,
608}
609
610impl DropEvent {
611 pub fn to_event(&self) -> Event {
612 Event {
613 code: EVENT_DROP,
614 a: self.kind as i64,
615 b: 0,
616 }
617 }
618
619 pub fn from_event(event: Event) -> DropEvent {
620 DropEvent {
621 kind: event.a as u8,
622 }
623 }
624}
625
626#[derive(Copy, Clone, Debug)]
628pub struct HoverEvent {
629 pub entered: bool,
631}
632
633impl HoverEvent {
634 pub fn to_event(&self) -> Event {
635 Event {
636 code: EVENT_HOVER,
637 a: self.entered as i64,
638 b: 0,
639 }
640 }
641
642 pub fn from_event(event: Event) -> HoverEvent {
643 HoverEvent {
644 entered: event.a > 0,
645 }
646 }
647}