1use std::borrow::ToOwned;
6use std::collections::HashMap;
7use std::convert::TryFrom;
8use std::ffi::CStr;
9use std::iter::FromIterator;
10use std::marker::PhantomData;
11use std::mem;
12use std::mem::transmute;
13use std::ptr;
14use std::sync::Mutex;
15
16use crate::gamepad;
17use crate::gamepad::{Axis, Button};
18use crate::get_error;
19use crate::joystick;
20use crate::joystick::HatState;
21use crate::keyboard;
22use crate::keyboard::Keycode;
23use crate::keyboard::Mod;
24use crate::keyboard::Scancode;
25use crate::mouse;
26use crate::mouse::{MouseButton, MouseState, MouseWheelDirection};
27use crate::pen::PenAxis;
28use crate::sys;
29use crate::sys::events::SDL_EventFilter;
30use crate::video::{Display, Orientation};
31use crate::Error;
32use libc::c_int;
33use libc::c_void;
34use sys::events::{
35 SDL_DisplayEvent, SDL_EventType, SDL_GamepadAxisEvent, SDL_GamepadButtonEvent,
36 SDL_GamepadDeviceEvent, SDL_JoyAxisEvent, SDL_JoyButtonEvent, SDL_JoyDeviceEvent,
37 SDL_JoyHatEvent, SDL_KeyboardEvent, SDL_MouseButtonEvent, SDL_MouseMotionEvent,
38 SDL_MouseWheelEvent,
39};
40use sys::everything::SDL_DisplayOrientation;
41use sys::stdinc::Uint16;
42
43struct CustomEventTypeMaps {
44 sdl_id_to_type_id: HashMap<u32, ::std::any::TypeId>,
45 type_id_to_sdl_id: HashMap<::std::any::TypeId, u32>,
46}
47
48impl CustomEventTypeMaps {
49 fn new() -> Self {
50 CustomEventTypeMaps {
51 sdl_id_to_type_id: HashMap::new(),
52 type_id_to_sdl_id: HashMap::new(),
53 }
54 }
55}
56
57lazy_static! {
58 static ref CUSTOM_EVENT_TYPES: Mutex<CustomEventTypeMaps> =
59 Mutex::new(CustomEventTypeMaps::new());
60}
61
62impl crate::EventSubsystem {
63 #[doc(alias = "SDL_FlushEvent")]
65 pub fn flush_event(&self, event_type: EventType) {
66 unsafe { sys::events::SDL_FlushEvent(event_type.into()) };
67 }
68
69 #[doc(alias = "SDL_FlushEvents")]
71 pub fn flush_events(&self, min_type: u32, max_type: u32) {
72 unsafe { sys::events::SDL_FlushEvents(min_type, max_type) };
73 }
74
75 #[doc(alias = "SDL_PeepEvents")]
96 pub fn peek_events<B>(&self, max_amount: u32) -> B
97 where
98 B: FromIterator<Event>,
99 {
100 unsafe {
101 let mut events = Vec::with_capacity(max_amount as usize);
102
103 let result = {
104 let events_ptr = events.as_mut_ptr();
105
106 sys::events::SDL_PeepEvents(
107 events_ptr,
108 max_amount as c_int,
109 sys::events::SDL_PEEKEVENT,
110 sys::events::SDL_EVENT_FIRST.into(),
111 sys::events::SDL_EVENT_LAST.into(),
112 )
113 };
114
115 if result < 0 {
116 panic!("{}", get_error());
118 } else {
119 events.set_len(result as usize);
120
121 events.into_iter().map(Event::from_ll).collect()
122 }
123 }
124 }
125
126 pub fn push_event(&self, event: Event) -> Result<(), Error> {
128 self.event_sender().push_event(event)
129 }
130
131 #[inline(always)]
159 pub unsafe fn register_event(&self) -> Result<u32, Error> {
160 Ok(*self.register_events(1)?.first().unwrap())
161 }
162
163 pub unsafe fn register_events(&self, nr: u32) -> Result<Vec<u32>, Error> {
167 let result = sys::events::SDL_RegisterEvents(nr as ::libc::c_int);
168 const ERR_NR: u32 = u32::MAX - 1;
169
170 match result {
171 ERR_NR => Err(Error(
172 "No more user events can be created; SDL_EVENT_LAST reached".to_owned(),
173 )),
174 _ => {
175 let event_ids = (result..(result + nr)).collect();
176 Ok(event_ids)
177 }
178 }
179 }
180
181 #[inline(always)]
188 pub fn register_custom_event<T: ::std::any::Any>(&self) -> Result<(), Error> {
189 use std::any::TypeId;
190 let event_id = *(unsafe { self.register_events(1) })?.first().unwrap();
191 let mut cet = CUSTOM_EVENT_TYPES.lock().unwrap();
192 let type_id = TypeId::of::<Box<T>>();
193
194 if cet.type_id_to_sdl_id.contains_key(&type_id) {
195 return Err(Error(
196 "The same event type can not be registered twice!".to_owned(),
197 ));
198 }
199
200 cet.sdl_id_to_type_id.insert(event_id, type_id);
201 cet.type_id_to_sdl_id.insert(type_id, event_id);
202
203 Ok(())
204 }
205
206 pub fn push_custom_event<T: ::std::any::Any>(&self, event: T) -> Result<(), Error> {
235 self.event_sender().push_custom_event(event)
236 }
237
238 pub fn event_sender(&self) -> EventSender {
243 EventSender { _priv: () }
244 }
245
246 pub fn add_event_watch<'a, CB: EventWatchCallback + 'a>(
264 &self,
265 callback: CB,
266 ) -> EventWatch<'a, CB> {
267 EventWatch::add(callback)
268 }
269}
270
271#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
273#[repr(u32)]
274pub enum EventType {
275 First = sys::events::SDL_EVENT_FIRST.0,
276
277 Quit = sys::events::SDL_EVENT_QUIT.0,
278 AppTerminating = sys::events::SDL_EVENT_TERMINATING.0,
279 AppLowMemory = sys::events::SDL_EVENT_LOW_MEMORY.0,
280 AppWillEnterBackground = sys::events::SDL_EVENT_WILL_ENTER_BACKGROUND.0,
281 AppDidEnterBackground = sys::events::SDL_EVENT_DID_ENTER_BACKGROUND.0,
282 AppWillEnterForeground = sys::events::SDL_EVENT_WILL_ENTER_FOREGROUND.0,
283 AppDidEnterForeground = sys::events::SDL_EVENT_DID_ENTER_FOREGROUND.0,
284
285 DisplayAdded = sys::events::SDL_EVENT_DISPLAY_ADDED.0,
286 DisplayRemoved = sys::events::SDL_EVENT_DISPLAY_REMOVED.0,
287 DisplayOrientation = sys::events::SDL_EVENT_DISPLAY_ORIENTATION.0,
288 DisplayMoved = sys::events::SDL_EVENT_DISPLAY_MOVED.0,
289 DisplayDesktopModeChanged = sys::events::SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED.0,
290 DisplayCurrentModeChanged = sys::events::SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED.0,
291 DisplayContentScaleChanged = sys::events::SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED.0,
292
293 WindowShown = sys::events::SDL_EVENT_WINDOW_SHOWN.0,
294 WindowHidden = sys::events::SDL_EVENT_WINDOW_HIDDEN.0,
295 WindowExposed = sys::events::SDL_EVENT_WINDOW_EXPOSED.0,
296 WindowMoved = sys::events::SDL_EVENT_WINDOW_MOVED.0,
297 WindowResized = sys::events::SDL_EVENT_WINDOW_RESIZED.0,
298 WindowPixelSizeChanged = sys::events::SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED.0,
299 WindowMinimized = sys::events::SDL_EVENT_WINDOW_MINIMIZED.0,
300 WindowMaximized = sys::events::SDL_EVENT_WINDOW_MAXIMIZED.0,
301 WindowRestored = sys::events::SDL_EVENT_WINDOW_RESTORED.0,
302 WindowMouseEnter = sys::events::SDL_EVENT_WINDOW_MOUSE_ENTER.0,
303 WindowMouseLeave = sys::events::SDL_EVENT_WINDOW_MOUSE_LEAVE.0,
304 WindowFocusGained = sys::events::SDL_EVENT_WINDOW_FOCUS_GAINED.0,
305 WindowFocusLost = sys::events::SDL_EVENT_WINDOW_FOCUS_LOST.0,
306 WindowCloseRequested = sys::events::SDL_EVENT_WINDOW_CLOSE_REQUESTED.0,
307 WindowHitTest = sys::events::SDL_EVENT_WINDOW_HIT_TEST.0,
308 WindowICCProfileChanged = sys::events::SDL_EVENT_WINDOW_ICCPROF_CHANGED.0,
309 WindowDisplayChanged = sys::events::SDL_EVENT_WINDOW_DISPLAY_CHANGED.0,
310
311 KeyDown = sys::events::SDL_EVENT_KEY_DOWN.0,
313 KeyUp = sys::events::SDL_EVENT_KEY_UP.0,
314 TextEditing = sys::events::SDL_EVENT_TEXT_EDITING.0,
315 TextInput = sys::events::SDL_EVENT_TEXT_INPUT.0,
316
317 MouseMotion = sys::events::SDL_EVENT_MOUSE_MOTION.0,
318 MouseButtonDown = sys::events::SDL_EVENT_MOUSE_BUTTON_DOWN.0,
319 MouseButtonUp = sys::events::SDL_EVENT_MOUSE_BUTTON_UP.0,
320 MouseWheel = sys::events::SDL_EVENT_MOUSE_WHEEL.0,
321
322 JoyAxisMotion = sys::events::SDL_EVENT_JOYSTICK_AXIS_MOTION.0,
323 JoyHatMotion = sys::events::SDL_EVENT_JOYSTICK_HAT_MOTION.0,
324 JoyButtonDown = sys::events::SDL_EVENT_JOYSTICK_BUTTON_DOWN.0,
325 JoyButtonUp = sys::events::SDL_EVENT_JOYSTICK_BUTTON_UP.0,
326 JoyDeviceAdded = sys::events::SDL_EVENT_JOYSTICK_ADDED.0,
327 JoyDeviceRemoved = sys::events::SDL_EVENT_JOYSTICK_REMOVED.0,
328
329 ControllerAxisMotion = sys::events::SDL_EVENT_GAMEPAD_AXIS_MOTION.0,
330 ControllerButtonDown = sys::events::SDL_EVENT_GAMEPAD_BUTTON_DOWN.0,
331 ControllerButtonUp = sys::events::SDL_EVENT_GAMEPAD_BUTTON_UP.0,
332 ControllerDeviceAdded = sys::events::SDL_EVENT_GAMEPAD_ADDED.0,
333 ControllerDeviceRemoved = sys::events::SDL_EVENT_GAMEPAD_REMOVED.0,
334 ControllerDeviceRemapped = sys::events::SDL_EVENT_GAMEPAD_REMAPPED.0,
335 ControllerTouchpadDown = sys::events::SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN.0,
336 ControllerTouchpadMotion = sys::events::SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION.0,
337 ControllerTouchpadUp = sys::events::SDL_EVENT_GAMEPAD_TOUCHPAD_UP.0,
338 #[cfg(feature = "hidapi")]
339 ControllerSensorUpdated = sys::events::SDL_EVENT_GAMEPAD_SENSOR_UPDATE.0,
340
341 FingerDown = sys::events::SDL_EVENT_FINGER_DOWN.0,
342 FingerUp = sys::events::SDL_EVENT_FINGER_UP.0,
343 FingerMotion = sys::events::SDL_EVENT_FINGER_MOTION.0,
344 ClipboardUpdate = sys::events::SDL_EVENT_CLIPBOARD_UPDATE.0,
346 DropFile = sys::events::SDL_EVENT_DROP_FILE.0,
347 DropText = sys::events::SDL_EVENT_DROP_TEXT.0,
348 DropBegin = sys::events::SDL_EVENT_DROP_BEGIN.0,
349 DropComplete = sys::events::SDL_EVENT_DROP_COMPLETE.0,
350
351 AudioDeviceAdded = sys::events::SDL_EVENT_AUDIO_DEVICE_ADDED.0,
352 AudioDeviceRemoved = sys::events::SDL_EVENT_AUDIO_DEVICE_REMOVED.0,
353
354 PenProximityIn = sys::events::SDL_EVENT_PEN_PROXIMITY_IN.0,
355 PenProximityOut = sys::events::SDL_EVENT_PEN_PROXIMITY_OUT.0,
356 PenDown = sys::events::SDL_EVENT_PEN_DOWN.0,
357 PenUp = sys::events::SDL_EVENT_PEN_UP.0,
358 PenButtonUp = sys::events::SDL_EVENT_PEN_BUTTON_UP.0,
359 PenButtonDown = sys::events::SDL_EVENT_PEN_BUTTON_DOWN.0,
360 PenMotion = sys::events::SDL_EVENT_PEN_MOTION.0,
361 PenAxis = sys::events::SDL_EVENT_PEN_AXIS.0,
362
363 RenderTargetsReset = sys::events::SDL_EVENT_RENDER_TARGETS_RESET.0,
364 RenderDeviceReset = sys::events::SDL_EVENT_RENDER_DEVICE_RESET.0,
365
366 User = sys::events::SDL_EVENT_USER.0,
367 Last = sys::events::SDL_EVENT_LAST.0,
368}
369
370impl From<EventType> for u32 {
371 fn from(t: EventType) -> u32 {
372 t as u32
373 }
374}
375impl From<EventType> for SDL_EventType {
376 fn from(t: EventType) -> SDL_EventType {
377 SDL_EventType(t as u32)
378 }
379}
380
381impl TryFrom<u32> for EventType {
382 type Error = ();
383
384 fn try_from(n: u32) -> Result<Self, Self::Error> {
385 use self::EventType::*;
386 use crate::sys::events::*;
387
388 Ok(match SDL_EventType(n) {
389 SDL_EVENT_FIRST => First,
390
391 SDL_EVENT_QUIT => Quit,
392 SDL_EVENT_TERMINATING => AppTerminating,
393 SDL_EVENT_LOW_MEMORY => AppLowMemory,
394 SDL_EVENT_WILL_ENTER_BACKGROUND => AppWillEnterBackground,
395 SDL_EVENT_DID_ENTER_BACKGROUND => AppDidEnterBackground,
396 SDL_EVENT_WILL_ENTER_FOREGROUND => AppWillEnterForeground,
397 SDL_EVENT_DID_ENTER_FOREGROUND => AppDidEnterForeground,
398
399 SDL_EVENT_DISPLAY_ADDED => DisplayAdded,
400 SDL_EVENT_DISPLAY_REMOVED => DisplayRemoved,
401 SDL_EVENT_DISPLAY_ORIENTATION => DisplayOrientation,
402 SDL_EVENT_DISPLAY_MOVED => DisplayMoved,
403 SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED => DisplayDesktopModeChanged,
404 SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED => DisplayCurrentModeChanged,
405 SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED => DisplayContentScaleChanged,
406
407 SDL_EVENT_WINDOW_SHOWN => WindowShown,
408 SDL_EVENT_WINDOW_HIDDEN => WindowHidden,
409 SDL_EVENT_WINDOW_EXPOSED => WindowExposed,
410 SDL_EVENT_WINDOW_MOVED => WindowMoved,
411 SDL_EVENT_WINDOW_RESIZED => WindowResized,
412 SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED => WindowPixelSizeChanged,
413 SDL_EVENT_WINDOW_MINIMIZED => WindowMinimized,
414 SDL_EVENT_WINDOW_MAXIMIZED => WindowMaximized,
415 SDL_EVENT_WINDOW_RESTORED => WindowRestored,
416 SDL_EVENT_WINDOW_MOUSE_ENTER => WindowMouseEnter,
417 SDL_EVENT_WINDOW_MOUSE_LEAVE => WindowMouseLeave,
418 SDL_EVENT_WINDOW_FOCUS_GAINED => WindowFocusGained,
419 SDL_EVENT_WINDOW_FOCUS_LOST => WindowFocusLost,
420 SDL_EVENT_WINDOW_CLOSE_REQUESTED => WindowCloseRequested,
421
422 SDL_EVENT_KEY_DOWN => KeyDown,
423 SDL_EVENT_KEY_UP => KeyUp,
424 SDL_EVENT_TEXT_EDITING => TextEditing,
425 SDL_EVENT_TEXT_INPUT => TextInput,
426
427 SDL_EVENT_MOUSE_MOTION => MouseMotion,
428 SDL_EVENT_MOUSE_BUTTON_DOWN => MouseButtonDown,
429 SDL_EVENT_MOUSE_BUTTON_UP => MouseButtonUp,
430 SDL_EVENT_MOUSE_WHEEL => MouseWheel,
431
432 SDL_EVENT_JOYSTICK_AXIS_MOTION => JoyAxisMotion,
433 SDL_EVENT_JOYSTICK_HAT_MOTION => JoyHatMotion,
434 SDL_EVENT_JOYSTICK_BUTTON_DOWN => JoyButtonDown,
435 SDL_EVENT_JOYSTICK_BUTTON_UP => JoyButtonUp,
436 SDL_EVENT_JOYSTICK_ADDED => JoyDeviceAdded,
437 SDL_EVENT_JOYSTICK_REMOVED => JoyDeviceRemoved,
438
439 SDL_EVENT_GAMEPAD_AXIS_MOTION => ControllerAxisMotion,
440 SDL_EVENT_GAMEPAD_BUTTON_DOWN => ControllerButtonDown,
441 SDL_EVENT_GAMEPAD_BUTTON_UP => ControllerButtonUp,
442 SDL_EVENT_GAMEPAD_ADDED => ControllerDeviceAdded,
443 SDL_EVENT_GAMEPAD_REMOVED => ControllerDeviceRemoved,
444 SDL_EVENT_GAMEPAD_REMAPPED => ControllerDeviceRemapped,
445 SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN => ControllerTouchpadDown,
446 SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION => ControllerTouchpadMotion,
447 SDL_EVENT_GAMEPAD_TOUCHPAD_UP => ControllerTouchpadUp,
448 #[cfg(feature = "hidapi")]
449 SDL_EVENT_GAMEPAD_SENSOR_UPDATE => ControllerSensorUpdated,
450
451 SDL_EVENT_FINGER_DOWN => FingerDown,
452 SDL_EVENT_FINGER_UP => FingerUp,
453 SDL_EVENT_FINGER_MOTION => FingerMotion,
454
455 SDL_EVENT_CLIPBOARD_UPDATE => ClipboardUpdate,
456 SDL_EVENT_DROP_FILE => DropFile,
457 SDL_EVENT_DROP_TEXT => DropText,
458 SDL_EVENT_DROP_BEGIN => DropBegin,
459 SDL_EVENT_DROP_COMPLETE => DropComplete,
460
461 SDL_EVENT_AUDIO_DEVICE_ADDED => AudioDeviceAdded,
462 SDL_EVENT_AUDIO_DEVICE_REMOVED => AudioDeviceRemoved,
463
464 SDL_EVENT_PEN_PROXIMITY_IN => PenProximityIn,
465 SDL_EVENT_PEN_PROXIMITY_OUT => PenProximityOut,
466 SDL_EVENT_PEN_DOWN => PenDown,
467 SDL_EVENT_PEN_UP => PenUp,
468 SDL_EVENT_PEN_BUTTON_UP => PenButtonUp,
469 SDL_EVENT_PEN_BUTTON_DOWN => PenButtonDown,
470 SDL_EVENT_PEN_MOTION => PenMotion,
471 SDL_EVENT_PEN_AXIS => PenAxis,
472
473 SDL_EVENT_RENDER_TARGETS_RESET => RenderTargetsReset,
474 SDL_EVENT_RENDER_DEVICE_RESET => RenderDeviceReset,
475
476 SDL_EVENT_USER => User,
477 SDL_EVENT_LAST => Last,
478
479 _ => return Err(()),
480 })
481 }
482}
483
484#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
485pub enum DisplayEvent {
487 None,
488 Orientation(Orientation),
489 Added,
490 Removed,
491 Moved,
492 DesktopModeChanged,
493 CurrentModeChanged,
494 ContentScaleChanged,
495}
496
497impl DisplayEvent {
498 #[allow(clippy::match_same_arms)]
499 fn from_ll(id: u32, data1: i32) -> DisplayEvent {
500 match unsafe { transmute(id) } {
501 sys::events::SDL_EVENT_DISPLAY_ORIENTATION => {
502 let orientation = if data1 > SDL_DisplayOrientation::PORTRAIT_FLIPPED.0 {
503 Orientation::Unknown
504 } else {
505 let sdl_orientation = SDL_DisplayOrientation(data1);
506 Orientation::from_ll(sdl_orientation)
507 };
508 DisplayEvent::Orientation(orientation)
509 }
510 sys::events::SDL_EVENT_DISPLAY_ADDED => DisplayEvent::Added,
511 sys::events::SDL_EVENT_DISPLAY_REMOVED => DisplayEvent::Removed,
512 sys::events::SDL_EVENT_DISPLAY_MOVED => DisplayEvent::Moved,
513 sys::events::SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED => DisplayEvent::DesktopModeChanged,
514 sys::events::SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED => DisplayEvent::CurrentModeChanged,
515 sys::events::SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED => {
516 DisplayEvent::ContentScaleChanged
517 }
518 _ => DisplayEvent::None,
519 }
520 }
521
522 fn to_ll(self) -> (u32, i32) {
523 match self {
524 DisplayEvent::Orientation(orientation) => (
525 sys::events::SDL_EVENT_DISPLAY_ORIENTATION.into(),
526 orientation.to_ll().into(),
527 ),
528 DisplayEvent::Added => (sys::events::SDL_EVENT_DISPLAY_ADDED.into(), 0),
529 DisplayEvent::Removed => (sys::events::SDL_EVENT_DISPLAY_REMOVED.into(), 0),
530 DisplayEvent::None => panic!("DisplayEvent::None cannot be converted"),
531 DisplayEvent::Moved => (sys::events::SDL_EVENT_DISPLAY_MOVED.into(), 0),
532 DisplayEvent::DesktopModeChanged => (
533 sys::events::SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED.into(),
534 0,
535 ),
536 DisplayEvent::CurrentModeChanged => (
537 sys::events::SDL_EVENT_DISPLAY_CURRENT_MODE_CHANGED.into(),
538 0,
539 ),
540 DisplayEvent::ContentScaleChanged => (
541 sys::events::SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED.into(),
542 0,
543 ),
544 }
545 }
546
547 pub fn is_same_kind_as(&self, other: &DisplayEvent) -> bool {
548 matches!(
549 (self, other),
550 (Self::None, Self::None)
551 | (Self::Orientation(_), Self::Orientation(_))
552 | (Self::Added, Self::Added)
553 | (Self::Removed, Self::Removed)
554 )
555 }
556}
557
558#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
559pub enum WindowEvent {
561 None,
562 Shown,
563 Hidden,
564 Exposed,
565 Moved(i32, i32),
566 Resized(i32, i32),
567 PixelSizeChanged(i32, i32),
568 Minimized,
569 Maximized,
570 Restored,
571 MouseEnter,
572 MouseLeave,
573 FocusGained,
574 FocusLost,
575 CloseRequested,
576 HitTest(i32, i32),
577 ICCProfChanged,
578 DisplayChanged(i32),
579}
580
581impl WindowEvent {
582 #[allow(clippy::match_same_arms)]
583 fn from_ll(id: u32, data1: i32, data2: i32) -> WindowEvent {
584 match EventType::try_from(id) {
585 Ok(ev) => match ev {
586 EventType::WindowShown => WindowEvent::Shown,
587 EventType::WindowHidden => WindowEvent::Hidden,
588 EventType::WindowExposed => WindowEvent::Exposed,
589 EventType::WindowMoved => WindowEvent::Moved(data1, data2),
590 EventType::WindowResized => WindowEvent::Resized(data1, data2),
591 EventType::WindowPixelSizeChanged => WindowEvent::PixelSizeChanged(data1, data2),
592 EventType::WindowMinimized => WindowEvent::Minimized,
593 EventType::WindowMaximized => WindowEvent::Maximized,
594 EventType::WindowRestored => WindowEvent::Restored,
595 EventType::WindowMouseEnter => WindowEvent::MouseEnter,
596 EventType::WindowMouseLeave => WindowEvent::MouseLeave,
597 EventType::WindowFocusGained => WindowEvent::FocusGained,
598 EventType::WindowFocusLost => WindowEvent::FocusLost,
599 EventType::WindowCloseRequested => WindowEvent::CloseRequested,
600 EventType::WindowHitTest => WindowEvent::HitTest(data1, data2),
601 EventType::WindowICCProfileChanged => WindowEvent::ICCProfChanged,
602 EventType::WindowDisplayChanged => WindowEvent::DisplayChanged(data1),
603 _ => WindowEvent::None,
604 },
605 Err(_) => WindowEvent::None,
606 }
607 }
608
609 fn to_ll(self) -> (EventType, i32, i32) {
610 match self {
611 WindowEvent::None => panic!("Cannot convert WindowEvent::None"),
612 WindowEvent::Shown => (EventType::WindowShown, 0, 0),
613 WindowEvent::Hidden => (EventType::WindowHidden, 0, 0),
614 WindowEvent::Exposed => (EventType::WindowExposed, 0, 0),
615 WindowEvent::Moved(d1, d2) => (EventType::WindowMoved, d1, d2),
616 WindowEvent::Resized(d1, d2) => (EventType::WindowResized, d1, d2),
617 WindowEvent::PixelSizeChanged(d1, d2) => (EventType::WindowPixelSizeChanged, d1, d2),
618 WindowEvent::Minimized => (EventType::WindowMinimized, 0, 0),
619 WindowEvent::Maximized => (EventType::WindowMaximized, 0, 0),
620 WindowEvent::Restored => (EventType::WindowRestored, 0, 0),
621 WindowEvent::MouseEnter => (EventType::WindowMouseEnter, 0, 0),
622 WindowEvent::MouseLeave => (EventType::WindowMouseLeave, 0, 0),
623 WindowEvent::FocusGained => (EventType::WindowFocusGained, 0, 0),
624 WindowEvent::FocusLost => (EventType::WindowFocusLost, 0, 0),
625 WindowEvent::CloseRequested => (EventType::WindowCloseRequested, 0, 0),
626 WindowEvent::HitTest(d1, d2) => (EventType::WindowHitTest, d1, d2),
627 WindowEvent::ICCProfChanged => (EventType::WindowICCProfileChanged, 0, 0),
628 WindowEvent::DisplayChanged(d1) => (EventType::WindowDisplayChanged, d1, 0),
629 }
630 }
631
632 pub fn is_same_kind_as(&self, other: &WindowEvent) -> bool {
633 matches!(
634 (self, other),
635 (Self::None, Self::None)
636 | (Self::Shown, Self::Shown)
637 | (Self::Hidden, Self::Hidden)
638 | (Self::Exposed, Self::Exposed)
639 | (Self::Moved(_, _), Self::Moved(_, _))
640 | (Self::Resized(_, _), Self::Resized(_, _))
641 | (Self::PixelSizeChanged(_, _), Self::PixelSizeChanged(_, _))
642 | (Self::Minimized, Self::Minimized)
643 | (Self::Maximized, Self::Maximized)
644 | (Self::Restored, Self::Restored)
645 | (Self::MouseEnter, Self::MouseEnter)
646 | (Self::MouseLeave, Self::MouseLeave)
647 | (Self::FocusGained, Self::FocusGained)
648 | (Self::FocusLost, Self::FocusLost)
649 | (Self::CloseRequested, Self::CloseRequested)
650 | (Self::HitTest(_, _), Self::HitTest(_, _))
651 | (Self::ICCProfChanged, Self::ICCProfChanged)
652 | (Self::DisplayChanged(_), Self::DisplayChanged(_))
653 )
654 }
655}
656
657#[derive(Clone, PartialEq, Debug)]
658pub enum Event {
660 Quit {
661 timestamp: u64,
662 },
663 AppTerminating {
664 timestamp: u64,
665 },
666 AppLowMemory {
667 timestamp: u64,
668 },
669 AppWillEnterBackground {
670 timestamp: u64,
671 },
672 AppDidEnterBackground {
673 timestamp: u64,
674 },
675 AppWillEnterForeground {
676 timestamp: u64,
677 },
678 AppDidEnterForeground {
679 timestamp: u64,
680 },
681
682 Window {
683 timestamp: u64,
684 window_id: u32,
685 win_event: WindowEvent,
686 },
687
688 KeyDown {
690 timestamp: u64,
691 window_id: u32,
692 keycode: Option<Keycode>,
693 scancode: Option<Scancode>,
694 keymod: Mod,
695 repeat: bool,
696 which: u32,
697 raw: Uint16,
698 },
699 KeyUp {
700 timestamp: u64,
701 window_id: u32,
702 keycode: Option<Keycode>,
703 scancode: Option<Scancode>,
704 keymod: Mod,
705 repeat: bool,
706 which: u32,
707 raw: Uint16,
708 },
709
710 TextEditing {
711 timestamp: u64,
712 window_id: u32,
713 text: String,
714 start: i32,
715 length: i32,
716 },
717
718 TextInput {
719 timestamp: u64,
720 window_id: u32,
721 text: String,
722 },
723
724 MouseMotion {
725 timestamp: u64,
726 window_id: u32,
727 which: u32,
728 mousestate: MouseState,
729 x: f32,
730 y: f32,
731 xrel: f32,
732 yrel: f32,
733 },
734
735 MouseButtonDown {
736 timestamp: u64,
737 window_id: u32,
738 which: u32,
739 mouse_btn: MouseButton,
740 clicks: u8,
741 x: f32,
742 y: f32,
743 },
744 MouseButtonUp {
745 timestamp: u64,
746 window_id: u32,
747 which: u32,
748 mouse_btn: MouseButton,
749 clicks: u8,
750 x: f32,
751 y: f32,
752 },
753
754 MouseWheel {
755 timestamp: u64,
756 window_id: u32,
757 which: u32,
758 x: f32,
759 y: f32,
760 direction: MouseWheelDirection,
761 mouse_x: f32,
762 mouse_y: f32,
763 },
764
765 JoyAxisMotion {
766 timestamp: u64,
767 which: u32,
769 axis_idx: u8,
770 value: i16,
771 },
772
773 JoyHatMotion {
774 timestamp: u64,
775 which: u32,
777 hat_idx: u8,
778 state: HatState,
779 },
780
781 JoyButtonDown {
782 timestamp: u64,
783 which: u32,
785 button_idx: u8,
786 },
787 JoyButtonUp {
788 timestamp: u64,
789 which: u32,
791 button_idx: u8,
792 },
793
794 JoyDeviceAdded {
795 timestamp: u64,
796 which: u32,
798 },
799 JoyDeviceRemoved {
800 timestamp: u64,
801 which: u32,
803 },
804
805 ControllerAxisMotion {
806 timestamp: u64,
807 which: u32,
809 axis: Axis,
810 value: i16,
811 },
812
813 ControllerButtonDown {
814 timestamp: u64,
815 which: u32,
817 button: Button,
818 },
819 ControllerButtonUp {
820 timestamp: u64,
821 which: u32,
823 button: Button,
824 },
825
826 ControllerDeviceAdded {
827 timestamp: u64,
828 which: u32,
830 },
831 ControllerDeviceRemoved {
832 timestamp: u64,
833 which: u32,
835 },
836 ControllerDeviceRemapped {
837 timestamp: u64,
838 which: u32,
840 },
841
842 ControllerTouchpadDown {
843 timestamp: u64,
844 which: u32,
846 touchpad: i32,
848 finger: i32,
850 x: f32,
852 y: f32,
854 pressure: f32,
856 },
857 ControllerTouchpadMotion {
858 timestamp: u64,
859 which: u32,
861 touchpad: i32,
863 finger: i32,
865 x: f32,
867 y: f32,
869 pressure: f32,
871 },
872 ControllerTouchpadUp {
873 timestamp: u64,
874 which: u32,
876 touchpad: i32,
878 finger: i32,
880 x: f32,
882 y: f32,
884 pressure: f32,
886 },
887
888 #[cfg(feature = "hidapi")]
890 ControllerSensorUpdated {
891 timestamp: u64,
892 which: u32,
893 sensor: crate::sensor::SensorType,
894 data: [f32; 3],
898 },
899
900 FingerDown {
901 timestamp: u64,
902 touch_id: u64,
903 finger_id: u64,
904 x: f32,
905 y: f32,
906 dx: f32,
907 dy: f32,
908 pressure: f32,
909 },
910 FingerUp {
911 timestamp: u64,
912 touch_id: u64,
913 finger_id: u64,
914 x: f32,
915 y: f32,
916 dx: f32,
917 dy: f32,
918 pressure: f32,
919 },
920 FingerMotion {
921 timestamp: u64,
922 touch_id: u64,
923 finger_id: u64,
924 x: f32,
925 y: f32,
926 dx: f32,
927 dy: f32,
928 pressure: f32,
929 },
930
931 DollarRecord {
932 timestamp: u64,
933 touch_id: i64,
934 gesture_id: i64,
935 num_fingers: u32,
936 error: f32,
937 x: f32,
938 y: f32,
939 },
940
941 MultiGesture {
942 timestamp: u64,
943 touch_id: i64,
944 d_theta: f32,
945 d_dist: f32,
946 x: f32,
947 y: f32,
948 num_fingers: u16,
949 },
950
951 ClipboardUpdate {
952 timestamp: u64,
953 },
954
955 DropFile {
956 timestamp: u64,
957 window_id: u32,
958 filename: String,
959 },
960 DropText {
961 timestamp: u64,
962 window_id: u32,
963 filename: String,
964 },
965 DropBegin {
966 timestamp: u64,
967 window_id: u32,
968 },
969 DropComplete {
970 timestamp: u64,
971 window_id: u32,
972 },
973
974 AudioDeviceAdded {
975 timestamp: u64,
976 which: u32,
977 iscapture: bool,
978 },
979 AudioDeviceRemoved {
980 timestamp: u64,
981 which: u32,
982 iscapture: bool,
983 },
984
985 PenProximityIn {
986 timestamp: u64,
987 which: u32,
988 window: u32,
989 },
990 PenProximityOut {
991 timestamp: u64,
992 which: u32,
993 window: u32,
994 },
995 PenDown {
996 timestamp: u64,
997 which: u32,
998 window: u32,
999 x: f32,
1000 y: f32,
1001 eraser: bool,
1002 },
1003 PenUp {
1004 timestamp: u64,
1005 which: u32,
1006 window: u32,
1007 x: f32,
1008 y: f32,
1009 eraser: bool,
1010 },
1011 PenMotion {
1012 timestamp: u64,
1013 which: u32,
1014 window: u32,
1015 x: f32,
1016 y: f32,
1017 },
1018 PenButtonUp {
1019 timestamp: u64,
1020 which: u32,
1021 window: u32,
1022 x: f32,
1023 y: f32,
1024 button: u8,
1025 },
1026 PenButtonDown {
1027 timestamp: u64,
1028 which: u32,
1029 window: u32,
1030 x: f32,
1031 y: f32,
1032 button: u8,
1033 },
1034 PenAxis {
1035 timestamp: u64,
1036 which: u32,
1037 window: u32,
1038 x: f32,
1039 y: f32,
1040 axis: PenAxis,
1041 value: f32,
1042 },
1043
1044 RenderTargetsReset {
1045 timestamp: u64,
1046 },
1047 RenderDeviceReset {
1048 timestamp: u64,
1049 },
1050
1051 User {
1052 timestamp: u64,
1053 window_id: u32,
1054 type_: u32,
1055 code: i32,
1056 data1: *mut c_void,
1057 data2: *mut c_void,
1058 },
1059
1060 Unknown {
1061 timestamp: u64,
1062 type_: u32,
1063 },
1064
1065 Display {
1066 timestamp: u64,
1067 display: Display,
1068 display_event: DisplayEvent,
1069 },
1070}
1071
1072unsafe impl Send for Event {}
1076
1077unsafe impl Sync for Event {}
1081
1082impl Event {
1086 fn to_ll(&self) -> Option<sys::events::SDL_Event> {
1087 let mut ret = mem::MaybeUninit::uninit();
1088 match *self {
1089 Event::User {
1090 window_id,
1091 type_,
1092 code,
1093 data1,
1094 data2,
1095 timestamp,
1096 } => {
1097 let event = sys::events::SDL_UserEvent {
1098 r#type: type_,
1099 timestamp,
1100 windowID: window_id,
1101 code,
1102 data1,
1103 data2,
1104 reserved: 0,
1105 };
1106 unsafe {
1107 ptr::copy(
1108 &event,
1109 ret.as_mut_ptr() as *mut sys::events::SDL_UserEvent,
1110 1,
1111 );
1112 Some(ret.assume_init())
1113 }
1114 }
1115
1116 Event::Quit { timestamp } => {
1117 let event = sys::events::SDL_QuitEvent {
1118 r#type: sys::events::SDL_EVENT_QUIT,
1119 timestamp,
1120 reserved: 0,
1121 };
1122 unsafe {
1123 ptr::copy(
1124 &event,
1125 ret.as_mut_ptr() as *mut sys::events::SDL_QuitEvent,
1126 1,
1127 );
1128 Some(ret.assume_init())
1129 }
1130 }
1131
1132 Event::Window {
1133 timestamp,
1134 window_id,
1135 win_event,
1136 } => {
1137 let (win_event_id, data1, data2) = win_event.to_ll();
1138 let event = sys::events::SDL_WindowEvent {
1139 r#type: win_event_id.into(),
1140 timestamp,
1141 windowID: window_id,
1142 data1,
1143 data2,
1144 reserved: 0,
1145 };
1146 unsafe {
1147 ptr::copy(
1148 &event,
1149 ret.as_mut_ptr() as *mut sys::events::SDL_WindowEvent,
1150 1,
1151 );
1152 Some(ret.assume_init())
1153 }
1154 }
1155
1156 Event::KeyDown {
1157 timestamp,
1158 window_id,
1159 keycode,
1160 scancode,
1161 keymod,
1162 repeat,
1163 which,
1164 raw,
1165 } => {
1166 let event = SDL_KeyboardEvent {
1167 r#type: sys::events::SDL_EVENT_KEY_DOWN,
1168 timestamp,
1169 windowID: window_id,
1170 repeat,
1171 reserved: 0,
1172 scancode: scancode?.into(),
1173 which,
1174 down: true,
1175 key: keycode?.into(),
1176 r#mod: keymod.bits(),
1177 raw,
1178 };
1179 unsafe {
1180 ptr::copy(
1181 &event,
1182 ret.as_mut_ptr() as *mut sys::events::SDL_KeyboardEvent,
1183 1,
1184 );
1185 Some(ret.assume_init())
1186 }
1187 }
1188 Event::KeyUp {
1189 timestamp,
1190 window_id,
1191 keycode,
1192 scancode,
1193 keymod,
1194 repeat,
1195 which,
1196 raw,
1197 } => {
1198 let event = SDL_KeyboardEvent {
1199 r#type: sys::events::SDL_EVENT_KEY_UP,
1200 timestamp,
1201 windowID: window_id,
1202 repeat,
1203 reserved: 0,
1204 scancode: scancode?.into(),
1205 which,
1206 down: false,
1207 key: keycode?.into(),
1208 r#mod: keymod.bits(),
1209 raw,
1210 };
1211 unsafe {
1212 ptr::copy(
1213 &event,
1214 ret.as_mut_ptr() as *mut sys::events::SDL_KeyboardEvent,
1215 1,
1216 );
1217 Some(ret.assume_init())
1218 }
1219 }
1220 Event::MouseMotion {
1221 timestamp,
1222 window_id,
1223 which,
1224 mousestate,
1225 x,
1226 y,
1227 xrel,
1228 yrel,
1229 } => {
1230 let state = mousestate.to_sdl_state();
1231 let event = SDL_MouseMotionEvent {
1232 r#type: sys::events::SDL_EVENT_MOUSE_MOTION,
1233 timestamp,
1234 windowID: window_id,
1235 which,
1236 state,
1237 x,
1238 y,
1239 xrel,
1240 yrel,
1241 reserved: 0,
1242 };
1243 unsafe {
1244 ptr::copy(
1245 &event,
1246 ret.as_mut_ptr() as *mut sys::events::SDL_MouseMotionEvent,
1247 1,
1248 );
1249 Some(ret.assume_init())
1250 }
1251 }
1252 Event::MouseButtonDown {
1253 timestamp,
1254 window_id,
1255 which,
1256 mouse_btn,
1257 clicks,
1258 x,
1259 y,
1260 } => {
1261 let event = SDL_MouseButtonEvent {
1262 r#type: sys::events::SDL_EVENT_MOUSE_BUTTON_DOWN,
1263 timestamp,
1264 windowID: window_id,
1265 which,
1266 button: mouse_btn as u8,
1267 down: true,
1268 clicks,
1269 x,
1270 y,
1271 padding: 0,
1272 reserved: 0,
1273 };
1274 unsafe {
1275 ptr::copy(
1276 &event,
1277 ret.as_mut_ptr() as *mut sys::events::SDL_MouseButtonEvent,
1278 1,
1279 );
1280 Some(ret.assume_init())
1281 }
1282 }
1283 Event::MouseButtonUp {
1284 timestamp,
1285 window_id,
1286 which,
1287 mouse_btn,
1288 clicks,
1289 x,
1290 y,
1291 } => {
1292 let event = sys::events::SDL_MouseButtonEvent {
1293 r#type: sys::events::SDL_EVENT_MOUSE_BUTTON_UP,
1294 timestamp,
1295 windowID: window_id,
1296 which,
1297 button: mouse_btn as u8,
1298 clicks,
1299 padding: 0,
1300 x,
1301 y,
1302 down: false,
1303 reserved: 0,
1304 };
1305 unsafe {
1306 ptr::copy(
1307 &event,
1308 ret.as_mut_ptr() as *mut sys::events::SDL_MouseButtonEvent,
1309 1,
1310 );
1311 Some(ret.assume_init())
1312 }
1313 }
1314
1315 Event::MouseWheel {
1316 timestamp,
1317 window_id,
1318 which,
1319 x,
1320 y,
1321 direction,
1322 mouse_x,
1323 mouse_y,
1324 } => {
1325 let event = SDL_MouseWheelEvent {
1326 r#type: sys::events::SDL_EVENT_MOUSE_WHEEL,
1327 timestamp,
1328 windowID: window_id,
1329 which,
1330 x,
1331 y,
1332 direction: direction.into(),
1333 mouse_x,
1334 mouse_y,
1335 integer_x: 0,
1336 integer_y: 0,
1337 reserved: 0,
1338 };
1339 unsafe {
1340 ptr::copy(
1341 &event,
1342 ret.as_mut_ptr() as *mut sys::events::SDL_MouseWheelEvent,
1343 1,
1344 );
1345 Some(ret.assume_init())
1346 }
1347 }
1348 Event::JoyAxisMotion {
1349 timestamp,
1350 which,
1351 axis_idx,
1352 value,
1353 } => {
1354 let event = SDL_JoyAxisEvent {
1355 r#type: sys::events::SDL_EVENT_JOYSTICK_AXIS_MOTION,
1356 timestamp,
1357 which,
1358 axis: axis_idx,
1359 value,
1360 padding1: 0,
1361 padding2: 0,
1362 padding3: 0,
1363 padding4: 0,
1364 reserved: 0,
1365 };
1366 unsafe {
1367 ptr::copy(
1368 &event,
1369 ret.as_mut_ptr() as *mut sys::events::SDL_JoyAxisEvent,
1370 1,
1371 );
1372 Some(ret.assume_init())
1373 }
1374 }
1375 Event::JoyHatMotion {
1376 timestamp,
1377 which,
1378 hat_idx,
1379 state,
1380 } => {
1381 let hatvalue = state.to_raw();
1382 let event = SDL_JoyHatEvent {
1383 r#type: sys::events::SDL_EVENT_JOYSTICK_HAT_MOTION,
1384 timestamp,
1385 which,
1386 hat: hat_idx,
1387 value: hatvalue,
1388 padding1: 0,
1389 padding2: 0,
1390 reserved: 0,
1391 };
1392 unsafe {
1393 ptr::copy(
1394 &event,
1395 ret.as_mut_ptr() as *mut sys::events::SDL_JoyHatEvent,
1396 1,
1397 );
1398 Some(ret.assume_init())
1399 }
1400 }
1401 Event::JoyButtonDown {
1402 timestamp,
1403 which,
1404 button_idx,
1405 } => {
1406 let event = SDL_JoyButtonEvent {
1407 r#type: sys::events::SDL_EVENT_JOYSTICK_BUTTON_DOWN,
1408 timestamp,
1409 which,
1410 button: button_idx,
1411 down: true,
1412 padding1: 0,
1413 padding2: 0,
1414 reserved: 0,
1415 };
1416 unsafe {
1417 ptr::copy(
1418 &event,
1419 ret.as_mut_ptr() as *mut sys::events::SDL_JoyButtonEvent,
1420 1,
1421 );
1422 Some(ret.assume_init())
1423 }
1424 }
1425
1426 Event::JoyButtonUp {
1427 timestamp,
1428 which,
1429 button_idx,
1430 } => {
1431 let event = SDL_JoyButtonEvent {
1432 r#type: sys::events::SDL_EVENT_JOYSTICK_BUTTON_UP,
1433 timestamp,
1434 which,
1435 button: button_idx,
1436 down: false,
1437 padding1: 0,
1438 padding2: 0,
1439 reserved: 0,
1440 };
1441 unsafe {
1442 ptr::copy(
1443 &event,
1444 ret.as_mut_ptr() as *mut sys::events::SDL_JoyButtonEvent,
1445 1,
1446 );
1447 Some(ret.assume_init())
1448 }
1449 }
1450
1451 Event::JoyDeviceAdded { timestamp, which } => {
1452 let event = SDL_JoyDeviceEvent {
1453 r#type: sys::events::SDL_EVENT_JOYSTICK_ADDED,
1454 timestamp,
1455 which,
1456 reserved: 0,
1457 };
1458 unsafe {
1459 ptr::copy(
1460 &event,
1461 ret.as_mut_ptr() as *mut sys::events::SDL_JoyDeviceEvent,
1462 1,
1463 );
1464 Some(ret.assume_init())
1465 }
1466 }
1467
1468 Event::JoyDeviceRemoved { timestamp, which } => {
1469 let event = SDL_JoyDeviceEvent {
1470 r#type: sys::events::SDL_EVENT_JOYSTICK_REMOVED,
1471 timestamp,
1472 which,
1473 reserved: 0,
1474 };
1475 unsafe {
1476 ptr::copy(
1477 &event,
1478 ret.as_mut_ptr() as *mut sys::events::SDL_JoyDeviceEvent,
1479 1,
1480 );
1481 Some(ret.assume_init())
1482 }
1483 }
1484 Event::ControllerAxisMotion {
1485 timestamp,
1486 which,
1487 axis,
1488 value,
1489 } => {
1490 let event = SDL_GamepadAxisEvent {
1491 r#type: sys::events::SDL_EVENT_GAMEPAD_AXIS_MOTION,
1492 timestamp,
1493 which,
1494 axis: axis.into(),
1495 value,
1496 padding1: 0,
1497 padding2: 0,
1498 padding3: 0,
1499 padding4: 0,
1500 reserved: 0,
1501 };
1502 unsafe {
1503 ptr::copy(
1504 &event,
1505 ret.as_mut_ptr() as *mut sys::events::SDL_GamepadAxisEvent,
1506 1,
1507 );
1508 Some(ret.assume_init())
1509 }
1510 }
1511 Event::ControllerButtonDown {
1512 timestamp,
1513 which,
1514 button,
1515 } => {
1516 let event = SDL_GamepadButtonEvent {
1517 r#type: sys::events::SDL_EVENT_GAMEPAD_BUTTON_DOWN,
1518 timestamp,
1519 which,
1520 button: button.into(),
1523 down: true,
1524 padding1: 0,
1525 padding2: 0,
1526 reserved: 0,
1527 };
1528 unsafe {
1529 ptr::copy(
1530 &event,
1531 ret.as_mut_ptr() as *mut sys::events::SDL_GamepadButtonEvent,
1532 1,
1533 );
1534 Some(ret.assume_init())
1535 }
1536 }
1537
1538 Event::ControllerButtonUp {
1539 timestamp,
1540 which,
1541 button,
1542 } => {
1543 let event = SDL_GamepadButtonEvent {
1544 r#type: sys::events::SDL_EVENT_GAMEPAD_BUTTON_UP,
1545 reserved: 0,
1546 timestamp,
1547 which,
1548 button: button.into(),
1549 down: false,
1550 padding1: 0,
1551 padding2: 0,
1552 };
1553 unsafe {
1554 ptr::copy(
1555 &event,
1556 ret.as_mut_ptr() as *mut sys::events::SDL_GamepadButtonEvent,
1557 1,
1558 );
1559 Some(ret.assume_init())
1560 }
1561 }
1562
1563 Event::ControllerDeviceAdded { timestamp, which } => {
1564 let event = SDL_GamepadDeviceEvent {
1565 r#type: sys::events::SDL_EVENT_GAMEPAD_ADDED,
1566 timestamp,
1567 which,
1568 reserved: 0,
1569 };
1570 unsafe {
1571 ptr::copy(
1572 &event,
1573 ret.as_mut_ptr() as *mut sys::events::SDL_GamepadDeviceEvent,
1574 1,
1575 );
1576 Some(ret.assume_init())
1577 }
1578 }
1579
1580 Event::ControllerDeviceRemoved { timestamp, which } => {
1581 let event = SDL_GamepadDeviceEvent {
1582 r#type: sys::events::SDL_EVENT_GAMEPAD_REMOVED,
1583 timestamp,
1584 which,
1585 reserved: 0,
1586 };
1587 unsafe {
1588 ptr::copy(
1589 &event,
1590 ret.as_mut_ptr() as *mut sys::events::SDL_GamepadDeviceEvent,
1591 1,
1592 );
1593 Some(ret.assume_init())
1594 }
1595 }
1596
1597 Event::ControllerDeviceRemapped { timestamp, which } => {
1598 let event = SDL_GamepadDeviceEvent {
1599 r#type: sys::events::SDL_EVENT_GAMEPAD_REMAPPED,
1600 timestamp,
1601 which,
1602 reserved: 0,
1603 };
1604 unsafe {
1605 ptr::copy(
1606 &event,
1607 ret.as_mut_ptr() as *mut sys::events::SDL_GamepadDeviceEvent,
1608 1,
1609 );
1610 Some(ret.assume_init())
1611 }
1612 }
1613
1614 Event::Display {
1615 timestamp,
1616 display,
1617 display_event,
1618 } => {
1619 let display_event = display_event.to_ll();
1620 let event = SDL_DisplayEvent {
1621 r#type: SDL_EventType(display_event.0),
1622 displayID: display.id,
1623 data1: display_event.1,
1624 data2: 0,
1625 timestamp,
1626 reserved: 0,
1627 };
1628 unsafe {
1629 ptr::copy(
1630 &event,
1631 ret.as_mut_ptr() as *mut sys::events::SDL_DisplayEvent,
1632 1,
1633 );
1634 Some(ret.assume_init())
1635 }
1636 }
1637
1638 Event::FingerDown { .. }
1639 | Event::FingerUp { .. }
1640 | Event::FingerMotion { .. }
1641 | Event::DollarRecord { .. }
1642 | Event::MultiGesture { .. }
1643 | Event::ClipboardUpdate { .. }
1644 | Event::DropFile { .. }
1645 | Event::TextEditing { .. }
1646 | Event::TextInput { .. }
1647 | Event::Unknown { .. }
1648 | _ => {
1649 None
1651 }
1652 }
1653 }
1654
1655 pub fn from_ll(raw: sys::events::SDL_Event) -> Event {
1656 let raw_type = unsafe { raw.r#type };
1657
1658 let event_type: EventType = EventType::try_from(raw_type).unwrap_or(EventType::User);
1660 unsafe {
1661 match event_type {
1662 EventType::WindowShown
1663 | EventType::WindowHidden
1664 | EventType::WindowExposed
1665 | EventType::WindowMoved
1666 | EventType::WindowResized
1667 | EventType::WindowPixelSizeChanged
1668 | EventType::WindowMinimized
1669 | EventType::WindowMaximized
1670 | EventType::WindowRestored
1671 | EventType::WindowMouseEnter
1672 | EventType::WindowMouseLeave
1673 | EventType::WindowFocusGained
1674 | EventType::WindowFocusLost
1675 | EventType::WindowCloseRequested
1676 | EventType::WindowHitTest
1677 | EventType::WindowICCProfileChanged
1678 | EventType::WindowDisplayChanged => {
1679 let event = raw.window;
1680 Event::Window {
1681 timestamp: event.timestamp,
1682 window_id: event.windowID,
1683 win_event: WindowEvent::from_ll(
1684 event.r#type.into(),
1685 event.data1,
1686 event.data2,
1687 ),
1688 }
1689 }
1690
1691 EventType::Quit => {
1692 let event = raw.quit;
1693 Event::Quit {
1694 timestamp: event.timestamp,
1695 }
1696 }
1697 EventType::AppTerminating => {
1698 let event = raw.common;
1699 Event::AppTerminating {
1700 timestamp: event.timestamp,
1701 }
1702 }
1703 EventType::AppLowMemory => {
1704 let event = raw.common;
1705 Event::AppLowMemory {
1706 timestamp: event.timestamp,
1707 }
1708 }
1709 EventType::AppWillEnterBackground => {
1710 let event = raw.common;
1711 Event::AppWillEnterBackground {
1712 timestamp: event.timestamp,
1713 }
1714 }
1715 EventType::AppDidEnterBackground => {
1716 let event = raw.common;
1717 Event::AppDidEnterBackground {
1718 timestamp: event.timestamp,
1719 }
1720 }
1721 EventType::AppWillEnterForeground => {
1722 let event = raw.common;
1723 Event::AppWillEnterForeground {
1724 timestamp: event.timestamp,
1725 }
1726 }
1727 EventType::AppDidEnterForeground => {
1728 let event = raw.common;
1729 Event::AppDidEnterForeground {
1730 timestamp: event.timestamp,
1731 }
1732 }
1733
1734 EventType::DisplayOrientation
1735 | EventType::DisplayAdded
1736 | EventType::DisplayRemoved
1737 | EventType::DisplayMoved
1738 | EventType::DisplayDesktopModeChanged
1739 | EventType::DisplayCurrentModeChanged
1740 | EventType::DisplayContentScaleChanged => {
1741 let event = raw.display;
1742
1743 Event::Display {
1744 timestamp: event.timestamp,
1745 display: Display::from_ll(event.displayID),
1746 display_event: DisplayEvent::from_ll(event.r#type.into(), event.data1),
1747 }
1748 }
1749
1750 EventType::KeyDown => {
1752 let event = raw.key;
1753
1754 Event::KeyDown {
1755 timestamp: event.timestamp,
1756 window_id: event.windowID,
1757 keycode: Keycode::from_i32(event.key as i32),
1758 scancode: Scancode::from_i32(event.scancode.into()),
1759 keymod: keyboard::Mod::from_bits_truncate(event.r#mod),
1760 repeat: event.repeat,
1761 which: event.which,
1762 raw: event.raw,
1763 }
1764 }
1765 EventType::KeyUp => {
1766 let event = raw.key;
1767
1768 Event::KeyUp {
1769 timestamp: event.timestamp,
1770 window_id: event.windowID,
1771 keycode: Keycode::from_i32(event.key as i32),
1772 scancode: Scancode::from_i32(event.scancode.into()),
1773 keymod: keyboard::Mod::from_bits_truncate(event.r#mod),
1774 repeat: event.repeat,
1775 which: event.which,
1776 raw: event.raw,
1777 }
1778 }
1779 EventType::TextEditing => {
1780 let event = raw.edit;
1781
1782 let c_str: &CStr = CStr::from_ptr(event.text);
1784
1785 let text_str = c_str.to_str().expect("Invalid UTF-8 string");
1787 let text = text_str.to_owned();
1788
1789 Event::TextEditing {
1790 timestamp: event.timestamp,
1791 window_id: event.windowID,
1792 text,
1793 start: event.start,
1794 length: event.length,
1795 }
1796 }
1797 EventType::TextInput => {
1798 let event = raw.text;
1799
1800 let c_str: &CStr = CStr::from_ptr(event.text);
1802
1803 let text_str = c_str.to_str().expect("Invalid UTF-8 string");
1805 let text = text_str.to_owned();
1806
1807 Event::TextInput {
1808 timestamp: event.timestamp,
1809 window_id: event.windowID,
1810 text,
1811 }
1812 }
1813
1814 EventType::MouseMotion => {
1815 let event = raw.motion;
1816
1817 Event::MouseMotion {
1818 timestamp: event.timestamp,
1819 window_id: event.windowID,
1820 which: event.which,
1821 mousestate: mouse::MouseState::from_sdl_state(event.state),
1822 x: event.x,
1823 y: event.y,
1824 xrel: event.xrel,
1825 yrel: event.yrel,
1826 }
1827 }
1828 EventType::MouseButtonDown => {
1829 let event = raw.button;
1830
1831 Event::MouseButtonDown {
1832 timestamp: event.timestamp,
1833 window_id: event.windowID,
1834 which: event.which,
1835 mouse_btn: mouse::MouseButton::from_ll(event.button),
1836 clicks: event.clicks,
1837 x: event.x,
1838 y: event.y,
1839 }
1840 }
1841 EventType::MouseButtonUp => {
1842 let event = raw.button;
1843
1844 Event::MouseButtonUp {
1845 timestamp: event.timestamp,
1846 window_id: event.windowID,
1847 which: event.which,
1848 mouse_btn: mouse::MouseButton::from_ll(event.button),
1849 clicks: event.clicks,
1850 x: event.x,
1851 y: event.y,
1852 }
1853 }
1854 EventType::MouseWheel => {
1855 let event = raw.wheel;
1856
1857 Event::MouseWheel {
1858 timestamp: event.timestamp,
1859 window_id: event.windowID,
1860 which: event.which,
1861 x: event.x,
1862 y: event.y,
1863 direction: event.direction.into(),
1864 mouse_x: event.mouse_x,
1865 mouse_y: event.mouse_y,
1866 }
1867 }
1868
1869 EventType::JoyAxisMotion => {
1870 let event = raw.jaxis;
1871 Event::JoyAxisMotion {
1872 timestamp: event.timestamp,
1873 which: event.which,
1874 axis_idx: event.axis,
1875 value: event.value,
1876 }
1877 }
1878 EventType::JoyHatMotion => {
1879 let event = raw.jhat;
1880 Event::JoyHatMotion {
1881 timestamp: event.timestamp,
1882 which: event.which,
1883 hat_idx: event.hat,
1884 state: joystick::HatState::from_raw(event.value),
1885 }
1886 }
1887 EventType::JoyButtonDown => {
1888 let event = raw.jbutton;
1889 Event::JoyButtonDown {
1890 timestamp: event.timestamp,
1891 which: event.which,
1892 button_idx: event.button,
1893 }
1894 }
1895 EventType::JoyButtonUp => {
1896 let event = raw.jbutton;
1897 Event::JoyButtonUp {
1898 timestamp: event.timestamp,
1899 which: event.which,
1900 button_idx: event.button,
1901 }
1902 }
1903 EventType::JoyDeviceAdded => {
1904 let event = raw.jdevice;
1905 Event::JoyDeviceAdded {
1906 timestamp: event.timestamp,
1907 which: event.which,
1908 }
1909 }
1910 EventType::JoyDeviceRemoved => {
1911 let event = raw.jdevice;
1912 Event::JoyDeviceRemoved {
1913 timestamp: event.timestamp,
1914 which: event.which,
1915 }
1916 }
1917
1918 EventType::ControllerAxisMotion => {
1919 let event = raw.gaxis;
1920 let axis = gamepad::Axis::from_ll(transmute(event.axis as i32)).unwrap();
1921
1922 Event::ControllerAxisMotion {
1923 timestamp: event.timestamp,
1924 which: event.which,
1925 axis,
1926 value: event.value,
1927 }
1928 }
1929 EventType::ControllerButtonDown => {
1930 let event = raw.gbutton;
1931 let button = gamepad::Button::from_ll(transmute(event.button as i32)).unwrap();
1932
1933 Event::ControllerButtonDown {
1934 timestamp: event.timestamp,
1935 which: event.which,
1936 button,
1937 }
1938 }
1939 EventType::ControllerButtonUp => {
1940 let event = raw.gbutton;
1941 let button = gamepad::Button::from_ll(transmute(event.button as i32)).unwrap();
1942
1943 Event::ControllerButtonUp {
1944 timestamp: event.timestamp,
1945 which: event.which,
1946 button,
1947 }
1948 }
1949 EventType::ControllerDeviceAdded => {
1950 let event = raw.gdevice;
1951 Event::ControllerDeviceAdded {
1952 timestamp: event.timestamp,
1953 which: event.which,
1954 }
1955 }
1956 EventType::ControllerDeviceRemoved => {
1957 let event = raw.gdevice;
1958 Event::ControllerDeviceRemoved {
1959 timestamp: event.timestamp,
1960 which: event.which,
1961 }
1962 }
1963 EventType::ControllerDeviceRemapped => {
1964 let event = raw.gdevice;
1965 Event::ControllerDeviceRemapped {
1966 timestamp: event.timestamp,
1967 which: event.which,
1968 }
1969 }
1970 EventType::ControllerTouchpadDown => {
1971 let event = raw.gtouchpad;
1972 Event::ControllerTouchpadDown {
1973 timestamp: event.timestamp,
1974 which: event.which,
1975 touchpad: event.touchpad,
1976 finger: event.finger,
1977 x: event.x,
1978 y: event.y,
1979 pressure: event.pressure,
1980 }
1981 }
1982 EventType::ControllerTouchpadMotion => {
1983 let event = raw.gtouchpad;
1984 Event::ControllerTouchpadMotion {
1985 timestamp: event.timestamp,
1986 which: event.which,
1987 touchpad: event.touchpad,
1988 finger: event.finger,
1989 x: event.x,
1990 y: event.y,
1991 pressure: event.pressure,
1992 }
1993 }
1994 EventType::ControllerTouchpadUp => {
1995 let event = raw.gtouchpad;
1996 Event::ControllerTouchpadUp {
1997 timestamp: event.timestamp,
1998 which: event.which,
1999 touchpad: event.touchpad,
2000 finger: event.finger,
2001 x: event.x,
2002 y: event.y,
2003 pressure: event.pressure,
2004 }
2005 }
2006 #[cfg(feature = "hidapi")]
2007 EventType::ControllerSensorUpdated => {
2008 let event = raw.gsensor;
2009 Event::ControllerSensorUpdated {
2010 timestamp: event.timestamp,
2011 which: event.which,
2012 sensor: crate::sensor::SensorType::from_ll(event.sensor),
2013 data: event.data,
2014 }
2015 }
2016
2017 EventType::FingerDown => {
2018 let event = raw.tfinger;
2019 Event::FingerDown {
2020 timestamp: event.timestamp,
2021 touch_id: event.touchID,
2022 finger_id: event.fingerID,
2023 x: event.x,
2024 y: event.y,
2025 dx: event.dx,
2026 dy: event.dy,
2027 pressure: event.pressure,
2028 }
2029 }
2030 EventType::FingerUp => {
2031 let event = raw.tfinger;
2032 Event::FingerUp {
2033 timestamp: event.timestamp,
2034 touch_id: event.touchID,
2035 finger_id: event.fingerID,
2036 x: event.x,
2037 y: event.y,
2038 dx: event.dx,
2039 dy: event.dy,
2040 pressure: event.pressure,
2041 }
2042 }
2043 EventType::FingerMotion => {
2044 let event = raw.tfinger;
2045 Event::FingerMotion {
2046 timestamp: event.timestamp,
2047 touch_id: event.touchID,
2048 finger_id: event.fingerID,
2049 x: event.x,
2050 y: event.y,
2051 dx: event.dx,
2052 dy: event.dy,
2053 pressure: event.pressure,
2054 }
2055 }
2056
2057 EventType::ClipboardUpdate => {
2058 let event = raw.common;
2059 Event::ClipboardUpdate {
2060 timestamp: event.timestamp,
2061 }
2062 }
2063 EventType::DropFile => {
2064 let event = raw.drop;
2065
2066 let buf = CStr::from_ptr(event.data as *const _).to_bytes();
2067 let text = String::from_utf8_lossy(buf).to_string();
2068
2069 Event::DropFile {
2070 timestamp: event.timestamp,
2071 window_id: event.windowID,
2072 filename: text,
2073 }
2074 }
2075 EventType::DropText => {
2076 let event = raw.drop;
2077
2078 let buf = CStr::from_ptr(event.data as *const _).to_bytes();
2079 let text = String::from_utf8_lossy(buf).to_string();
2080
2081 Event::DropText {
2082 timestamp: event.timestamp,
2083 window_id: event.windowID,
2084 filename: text,
2085 }
2086 }
2087 EventType::DropBegin => {
2088 let event = raw.drop;
2089
2090 Event::DropBegin {
2091 timestamp: event.timestamp,
2092 window_id: event.windowID,
2093 }
2094 }
2095 EventType::DropComplete => {
2096 let event = raw.drop;
2097
2098 Event::DropComplete {
2099 timestamp: event.timestamp,
2100 window_id: event.windowID,
2101 }
2102 }
2103 EventType::AudioDeviceAdded => {
2104 let event = raw.adevice;
2105 Event::AudioDeviceAdded {
2106 timestamp: event.timestamp,
2107 which: event.which,
2108 iscapture: event.recording,
2110 }
2111 }
2112 EventType::AudioDeviceRemoved => {
2113 let event = raw.adevice;
2114 Event::AudioDeviceRemoved {
2115 timestamp: event.timestamp,
2116 which: event.which,
2117 iscapture: event.recording,
2119 }
2120 }
2121
2122 EventType::PenProximityIn => {
2123 let event = raw.pproximity;
2124 Event::PenProximityIn {
2125 timestamp: event.timestamp,
2126 which: event.which,
2127 window: event.windowID,
2128 }
2129 }
2130 EventType::PenProximityOut => {
2131 let event = raw.pproximity;
2132 Event::PenProximityOut {
2133 timestamp: event.timestamp,
2134 which: event.which,
2135 window: event.windowID,
2136 }
2137 }
2138 EventType::PenDown => {
2139 let event = raw.ptouch;
2140 Event::PenDown {
2141 timestamp: event.timestamp,
2142 which: event.which,
2143 window: event.windowID,
2144 x: event.x,
2145 y: event.y,
2146 eraser: event.eraser,
2147 }
2148 }
2149 EventType::PenUp => {
2150 let event = raw.ptouch;
2151 Event::PenUp {
2152 timestamp: event.timestamp,
2153 which: event.which,
2154 window: event.windowID,
2155 x: event.x,
2156 y: event.y,
2157 eraser: event.eraser,
2158 }
2159 }
2160 EventType::PenMotion => {
2161 let event = raw.pmotion;
2162 Event::PenMotion {
2163 timestamp: event.timestamp,
2164 which: event.which,
2165 window: event.windowID,
2166 x: event.x,
2167 y: event.y,
2168 }
2169 }
2170
2171 EventType::PenButtonUp => {
2172 let event = raw.pbutton;
2173 Event::PenButtonUp {
2174 timestamp: event.timestamp,
2175 which: event.which,
2176 window: event.windowID,
2177 x: event.x,
2178 y: event.y,
2179 button: event.button,
2180 }
2181 }
2182 EventType::PenButtonDown => {
2183 let event = raw.pbutton;
2184 Event::PenButtonDown {
2185 timestamp: event.timestamp,
2186 which: event.which,
2187 window: event.windowID,
2188 x: event.x,
2189 y: event.y,
2190 button: event.button,
2191 }
2192 }
2193 EventType::PenAxis => {
2194 let event = raw.paxis;
2195 Event::PenAxis {
2196 timestamp: event.timestamp,
2197 which: event.which,
2198 window: event.windowID,
2199 x: event.x,
2200 y: event.y,
2201 axis: PenAxis::from_ll(event.axis),
2202 value: event.value,
2203 }
2204 }
2205
2206 EventType::RenderTargetsReset => Event::RenderTargetsReset {
2207 timestamp: raw.common.timestamp,
2208 },
2209 EventType::RenderDeviceReset => Event::RenderDeviceReset {
2210 timestamp: raw.common.timestamp,
2211 },
2212
2213 EventType::First => panic!("Unused event, EventType::First, was encountered"),
2214 EventType::Last => panic!("Unusable event, EventType::Last, was encountered"),
2215
2216 EventType::User => {
2219 if raw_type < 32_768 {
2220 let event = raw.common;
2223
2224 Event::Unknown {
2225 timestamp: event.timestamp,
2226 type_: event.r#type,
2227 }
2228 } else {
2229 let event = raw.user;
2230
2231 Event::User {
2232 timestamp: event.timestamp,
2233 window_id: event.windowID,
2234 type_: raw_type,
2235 code: event.code,
2236 data1: event.data1,
2237 data2: event.data2,
2238 }
2239 }
2240 }
2241 }
2242 } }
2244
2245 pub fn is_user_event(&self) -> bool {
2246 matches!(*self, Event::User { .. })
2247 }
2248
2249 pub fn as_user_event_type<T: ::std::any::Any>(&self) -> Option<T> {
2250 use std::any::TypeId;
2251 let type_id = TypeId::of::<Box<T>>();
2252
2253 let (event_id, event_box_ptr) = match *self {
2254 Event::User { type_, data1, .. } => (type_, data1),
2255 _ => return None,
2256 };
2257
2258 let cet = CUSTOM_EVENT_TYPES.lock().unwrap();
2259
2260 let event_type_id = match cet.sdl_id_to_type_id.get(&event_id) {
2261 Some(id) => id,
2262 None => {
2263 panic!("internal error; could not find typeid")
2264 }
2265 };
2266
2267 if &type_id != event_type_id {
2268 return None;
2269 }
2270
2271 let event_box: Box<T> = unsafe { Box::from_raw(event_box_ptr as *mut T) };
2272
2273 Some(*event_box)
2274 }
2275
2276 pub fn is_same_kind_as(&self, other: &Event) -> bool {
2298 match (self, other) {
2299 (Self::Quit { .. }, Self::Quit { .. })
2300 | (Self::AppTerminating { .. }, Self::AppTerminating { .. })
2301 | (Self::AppLowMemory { .. }, Self::AppLowMemory { .. })
2302 | (Self::AppWillEnterBackground { .. }, Self::AppWillEnterBackground { .. })
2303 | (Self::AppDidEnterBackground { .. }, Self::AppDidEnterBackground { .. })
2304 | (Self::AppWillEnterForeground { .. }, Self::AppWillEnterForeground { .. })
2305 | (Self::AppDidEnterForeground { .. }, Self::AppDidEnterForeground { .. })
2306 | (Self::Display { .. }, Self::Display { .. })
2307 | (Self::Window { .. }, Self::Window { .. })
2308 | (Self::KeyDown { .. }, Self::KeyDown { .. })
2309 | (Self::KeyUp { .. }, Self::KeyUp { .. })
2310 | (Self::TextEditing { .. }, Self::TextEditing { .. })
2311 | (Self::TextInput { .. }, Self::TextInput { .. })
2312 | (Self::MouseMotion { .. }, Self::MouseMotion { .. })
2313 | (Self::MouseButtonDown { .. }, Self::MouseButtonDown { .. })
2314 | (Self::MouseButtonUp { .. }, Self::MouseButtonUp { .. })
2315 | (Self::MouseWheel { .. }, Self::MouseWheel { .. })
2316 | (Self::JoyAxisMotion { .. }, Self::JoyAxisMotion { .. })
2317 | (Self::JoyHatMotion { .. }, Self::JoyHatMotion { .. })
2318 | (Self::JoyButtonDown { .. }, Self::JoyButtonDown { .. })
2319 | (Self::JoyButtonUp { .. }, Self::JoyButtonUp { .. })
2320 | (Self::JoyDeviceAdded { .. }, Self::JoyDeviceAdded { .. })
2321 | (Self::JoyDeviceRemoved { .. }, Self::JoyDeviceRemoved { .. })
2322 | (Self::ControllerAxisMotion { .. }, Self::ControllerAxisMotion { .. })
2323 | (Self::ControllerButtonDown { .. }, Self::ControllerButtonDown { .. })
2324 | (Self::ControllerButtonUp { .. }, Self::ControllerButtonUp { .. })
2325 | (Self::ControllerDeviceAdded { .. }, Self::ControllerDeviceAdded { .. })
2326 | (Self::ControllerDeviceRemoved { .. }, Self::ControllerDeviceRemoved { .. })
2327 | (Self::ControllerDeviceRemapped { .. }, Self::ControllerDeviceRemapped { .. })
2328 | (Self::FingerDown { .. }, Self::FingerDown { .. })
2329 | (Self::FingerUp { .. }, Self::FingerUp { .. })
2330 | (Self::FingerMotion { .. }, Self::FingerMotion { .. })
2331 | (Self::DollarRecord { .. }, Self::DollarRecord { .. })
2332 | (Self::MultiGesture { .. }, Self::MultiGesture { .. })
2333 | (Self::ClipboardUpdate { .. }, Self::ClipboardUpdate { .. })
2334 | (Self::DropFile { .. }, Self::DropFile { .. })
2335 | (Self::DropText { .. }, Self::DropText { .. })
2336 | (Self::DropBegin { .. }, Self::DropBegin { .. })
2337 | (Self::DropComplete { .. }, Self::DropComplete { .. })
2338 | (Self::AudioDeviceAdded { .. }, Self::AudioDeviceAdded { .. })
2339 | (Self::AudioDeviceRemoved { .. }, Self::AudioDeviceRemoved { .. })
2340 | (Self::RenderTargetsReset { .. }, Self::RenderTargetsReset { .. })
2341 | (Self::RenderDeviceReset { .. }, Self::RenderDeviceReset { .. })
2342 | (Self::User { .. }, Self::User { .. })
2343 | (Self::Unknown { .. }, Self::Unknown { .. }) => true,
2344 #[cfg(feature = "hidapi")]
2345 (Self::ControllerSensorUpdated { .. }, Self::ControllerSensorUpdated { .. }) => true,
2346 _ => false,
2347 }
2348 }
2349
2350 pub fn get_timestamp(&self) -> u64 {
2365 *match self {
2366 Self::Quit { timestamp, .. } => timestamp,
2367 Self::Window { timestamp, .. } => timestamp,
2368 Self::AppTerminating { timestamp, .. } => timestamp,
2369 Self::AppLowMemory { timestamp, .. } => timestamp,
2370 Self::AppWillEnterBackground { timestamp, .. } => timestamp,
2371 Self::AppDidEnterBackground { timestamp, .. } => timestamp,
2372 Self::AppWillEnterForeground { timestamp, .. } => timestamp,
2373 Self::AppDidEnterForeground { timestamp, .. } => timestamp,
2374 Self::Display { timestamp, .. } => timestamp,
2375 Self::KeyDown { timestamp, .. } => timestamp,
2376 Self::KeyUp { timestamp, .. } => timestamp,
2377 Self::TextEditing { timestamp, .. } => timestamp,
2378 Self::TextInput { timestamp, .. } => timestamp,
2379 Self::MouseMotion { timestamp, .. } => timestamp,
2380 Self::MouseButtonDown { timestamp, .. } => timestamp,
2381 Self::MouseButtonUp { timestamp, .. } => timestamp,
2382 Self::MouseWheel { timestamp, .. } => timestamp,
2383 Self::JoyAxisMotion { timestamp, .. } => timestamp,
2384 Self::JoyHatMotion { timestamp, .. } => timestamp,
2385 Self::JoyButtonDown { timestamp, .. } => timestamp,
2386 Self::JoyButtonUp { timestamp, .. } => timestamp,
2387 Self::JoyDeviceAdded { timestamp, .. } => timestamp,
2388 Self::JoyDeviceRemoved { timestamp, .. } => timestamp,
2389 Self::ControllerAxisMotion { timestamp, .. } => timestamp,
2390 Self::ControllerButtonDown { timestamp, .. } => timestamp,
2391 Self::ControllerButtonUp { timestamp, .. } => timestamp,
2392 Self::ControllerDeviceAdded { timestamp, .. } => timestamp,
2393 Self::ControllerDeviceRemoved { timestamp, .. } => timestamp,
2394 Self::ControllerDeviceRemapped { timestamp, .. } => timestamp,
2395 Self::ControllerTouchpadDown { timestamp, .. } => timestamp,
2396 Self::ControllerTouchpadMotion { timestamp, .. } => timestamp,
2397 Self::ControllerTouchpadUp { timestamp, .. } => timestamp,
2398 #[cfg(feature = "hidapi")]
2399 Self::ControllerSensorUpdated { timestamp, .. } => timestamp,
2400 Self::FingerDown { timestamp, .. } => timestamp,
2401 Self::FingerUp { timestamp, .. } => timestamp,
2402 Self::FingerMotion { timestamp, .. } => timestamp,
2403 Self::DollarRecord { timestamp, .. } => timestamp,
2404 Self::MultiGesture { timestamp, .. } => timestamp,
2405 Self::ClipboardUpdate { timestamp, .. } => timestamp,
2406 Self::DropFile { timestamp, .. } => timestamp,
2407 Self::DropText { timestamp, .. } => timestamp,
2408 Self::DropBegin { timestamp, .. } => timestamp,
2409 Self::DropComplete { timestamp, .. } => timestamp,
2410 Self::AudioDeviceAdded { timestamp, .. } => timestamp,
2411 Self::AudioDeviceRemoved { timestamp, .. } => timestamp,
2412 Self::PenProximityIn { timestamp, .. } => timestamp,
2413 Self::PenProximityOut { timestamp, .. } => timestamp,
2414 Self::PenDown { timestamp, .. } => timestamp,
2415 Self::PenUp { timestamp, .. } => timestamp,
2416 Self::PenMotion { timestamp, .. } => timestamp,
2417 Self::PenButtonUp { timestamp, .. } => timestamp,
2418 Self::PenButtonDown { timestamp, .. } => timestamp,
2419 Self::PenAxis { timestamp, .. } => timestamp,
2420 Self::RenderTargetsReset { timestamp, .. } => timestamp,
2421 Self::RenderDeviceReset { timestamp, .. } => timestamp,
2422 Self::User { timestamp, .. } => timestamp,
2423 Self::Unknown { timestamp, .. } => timestamp,
2424 }
2425 }
2426
2427 pub fn get_window_id(&self) -> Option<u32> {
2448 match self {
2449 Self::Window { window_id, .. } => Some(*window_id),
2450 Self::KeyDown { window_id, .. } => Some(*window_id),
2451 Self::KeyUp { window_id, .. } => Some(*window_id),
2452 Self::TextEditing { window_id, .. } => Some(*window_id),
2453 Self::TextInput { window_id, .. } => Some(*window_id),
2454 Self::MouseMotion { window_id, .. } => Some(*window_id),
2455 Self::MouseButtonDown { window_id, .. } => Some(*window_id),
2456 Self::MouseButtonUp { window_id, .. } => Some(*window_id),
2457 Self::MouseWheel { window_id, .. } => Some(*window_id),
2458 Self::DropFile { window_id, .. } => Some(*window_id),
2459 Self::DropText { window_id, .. } => Some(*window_id),
2460 Self::DropBegin { window_id, .. } => Some(*window_id),
2461 Self::DropComplete { window_id, .. } => Some(*window_id),
2462 Self::User { window_id, .. } => Some(*window_id),
2463 _ => None,
2464 }
2465 }
2466
2467 pub fn is_window(&self) -> bool {
2492 matches!(
2493 self,
2494 Self::Quit { .. }
2495 | Self::AppTerminating { .. }
2496 | Self::AppLowMemory { .. }
2497 | Self::AppWillEnterBackground { .. }
2498 | Self::AppDidEnterBackground { .. }
2499 | Self::AppWillEnterForeground { .. }
2500 | Self::AppDidEnterForeground { .. }
2501 | Self::Window { .. }
2502 )
2503 }
2504
2505 pub fn is_keyboard(&self) -> bool {
2531 matches!(self, Self::KeyDown { .. } | Self::KeyUp { .. })
2532 }
2533
2534 pub fn is_text(&self) -> bool {
2554 matches!(self, Self::TextEditing { .. } | Self::TextInput { .. })
2555 }
2556
2557 pub fn is_mouse(&self) -> bool {
2583 matches!(
2584 self,
2585 Self::MouseMotion { .. }
2586 | Self::MouseButtonDown { .. }
2587 | Self::MouseButtonUp { .. }
2588 | Self::MouseWheel { .. }
2589 )
2590 }
2591
2592 pub fn is_controller(&self) -> bool {
2611 matches!(
2612 self,
2613 Self::ControllerAxisMotion { .. }
2614 | Self::ControllerButtonDown { .. }
2615 | Self::ControllerButtonUp { .. }
2616 | Self::ControllerDeviceAdded { .. }
2617 | Self::ControllerDeviceRemoved { .. }
2618 | Self::ControllerDeviceRemapped { .. }
2619 )
2620 }
2621
2622 pub fn is_joy(&self) -> bool {
2642 matches!(
2643 self,
2644 Self::JoyAxisMotion { .. }
2645 | Self::JoyHatMotion { .. }
2646 | Self::JoyButtonDown { .. }
2647 | Self::JoyButtonUp { .. }
2648 | Self::JoyDeviceAdded { .. }
2649 | Self::JoyDeviceRemoved { .. }
2650 )
2651 }
2652
2653 pub fn is_finger(&self) -> bool {
2678 matches!(
2679 self,
2680 Self::FingerDown { .. } | Self::FingerUp { .. } | Self::FingerMotion { .. }
2681 )
2682 }
2683
2684 pub fn is_pen(&self) -> bool {
2707 matches!(
2708 self,
2709 Self::PenProximityIn { .. }
2710 | Self::PenProximityOut { .. }
2711 | Self::PenDown { .. }
2712 | Self::PenUp { .. }
2713 | Self::PenMotion { .. }
2714 | Self::PenButtonUp { .. }
2715 | Self::PenButtonDown { .. }
2716 | Self::PenAxis { .. }
2717 )
2718 }
2719
2720 pub fn is_drop(&self) -> bool {
2739 matches!(
2740 self,
2741 Self::DropFile { .. }
2742 | Self::DropText { .. }
2743 | Self::DropBegin { .. }
2744 | Self::DropComplete { .. }
2745 )
2746 }
2747
2748 pub fn is_audio(&self) -> bool {
2768 matches!(
2769 self,
2770 Self::AudioDeviceAdded { .. } | Self::AudioDeviceRemoved { .. }
2771 )
2772 }
2773
2774 pub fn is_render(&self) -> bool {
2792 matches!(
2793 self,
2794 Self::RenderTargetsReset { .. } | Self::RenderDeviceReset { .. }
2795 )
2796 }
2797
2798 pub fn is_user(&self) -> bool {
2821 matches!(self, Self::User { .. })
2822 }
2823
2824 pub fn is_unknown(&self) -> bool {
2843 matches!(self, Self::Unknown { .. })
2844 }
2845
2846 pub fn get_converted_coords<T: crate::render::RenderTarget>(
2848 &self,
2849 canvas: &crate::render::Canvas<T>,
2850 ) -> Option<Event> {
2851 let mut raw = self.to_ll()?;
2852 unsafe {
2853 sys::render::SDL_ConvertEventToRenderCoordinates(canvas.raw(), &mut raw);
2854 }
2855 Some(Self::from_ll(raw))
2856 }
2857
2858 pub fn convert_coords<T: crate::render::RenderTarget>(
2860 &mut self,
2861 canvas: &crate::render::Canvas<T>,
2862 ) -> bool {
2863 if let Some(mut raw) = self.to_ll() {
2864 unsafe {
2865 sys::render::SDL_ConvertEventToRenderCoordinates(canvas.raw(), &mut raw);
2866 }
2867 *self = Self::from_ll(raw);
2868 true
2869 } else {
2870 false
2871 }
2872 }
2873}
2874
2875unsafe fn poll_event() -> Option<Event> {
2876 let mut raw = mem::MaybeUninit::uninit();
2877 let has_pending = sys::events::SDL_PollEvent(raw.as_mut_ptr());
2878
2879 if has_pending {
2880 Some(Event::from_ll(raw.assume_init()))
2881 } else {
2882 None
2883 }
2884}
2885
2886unsafe fn wait_event() -> Event {
2887 let mut raw = mem::MaybeUninit::uninit();
2888 let success = sys::events::SDL_WaitEvent(raw.as_mut_ptr());
2889
2890 if success {
2891 Event::from_ll(raw.assume_init())
2892 } else {
2893 panic!("{}", get_error())
2894 }
2895}
2896
2897unsafe fn wait_event_timeout(timeout: u32) -> Option<Event> {
2898 let mut raw = mem::MaybeUninit::uninit();
2899 let success = sys::events::SDL_WaitEventTimeout(raw.as_mut_ptr(), timeout as c_int);
2900
2901 if success {
2902 Some(Event::from_ll(raw.assume_init()))
2903 } else {
2904 None
2905 }
2906}
2907
2908impl crate::EventPump {
2909 pub fn poll_event(&mut self) -> Option<Event> {
2913 unsafe { poll_event() }
2914 }
2915
2916 pub fn poll_iter(&mut self) -> EventPollIterator {
2933 EventPollIterator {
2934 _marker: PhantomData,
2935 }
2936 }
2937
2938 #[doc(alias = "SDL_PumpEvents")]
2940 pub fn pump_events(&mut self) {
2941 unsafe {
2942 sys::events::SDL_PumpEvents();
2943 };
2944 }
2945
2946 pub fn wait_event(&mut self) -> Event {
2948 unsafe { wait_event() }
2949 }
2950
2951 pub fn wait_event_timeout(&mut self, timeout: u32) -> Option<Event> {
2953 unsafe { wait_event_timeout(timeout) }
2954 }
2955
2956 pub fn wait_iter(&mut self) -> EventWaitIterator {
2960 EventWaitIterator {
2961 _marker: PhantomData,
2962 }
2963 }
2964
2965 pub fn wait_timeout_iter(&mut self, timeout: u32) -> EventWaitTimeoutIterator {
2970 EventWaitTimeoutIterator {
2971 _marker: PhantomData,
2972 timeout,
2973 }
2974 }
2975
2976 #[inline]
2977 pub fn keyboard_state(&self) -> crate::keyboard::KeyboardState {
2978 crate::keyboard::KeyboardState::new(self)
2979 }
2980
2981 #[inline]
2982 pub fn mouse_state(&self) -> crate::mouse::MouseState {
2983 crate::mouse::MouseState::new(self)
2984 }
2985
2986 #[inline]
2987 pub fn relative_mouse_state(&self) -> crate::mouse::RelativeMouseState {
2988 crate::mouse::RelativeMouseState::new(self)
2989 }
2990}
2991
2992#[must_use = "iterators are lazy and do nothing unless consumed"]
2994pub struct EventPollIterator<'a> {
2995 _marker: PhantomData<&'a ()>,
2996}
2997
2998impl Iterator for EventPollIterator<'_> {
2999 type Item = Event;
3000
3001 fn next(&mut self) -> Option<Event> {
3002 unsafe { poll_event() }
3003 }
3004}
3005
3006#[must_use = "iterators are lazy and do nothing unless consumed"]
3008pub struct EventWaitIterator<'a> {
3009 _marker: PhantomData<&'a ()>,
3010}
3011
3012impl Iterator for EventWaitIterator<'_> {
3013 type Item = Event;
3014 fn next(&mut self) -> Option<Event> {
3015 unsafe { Some(wait_event()) }
3016 }
3017}
3018
3019#[must_use = "iterators are lazy and do nothing unless consumed"]
3021pub struct EventWaitTimeoutIterator<'a> {
3022 _marker: PhantomData<&'a ()>,
3023 timeout: u32,
3024}
3025
3026impl Iterator for EventWaitTimeoutIterator<'_> {
3027 type Item = Event;
3028 fn next(&mut self) -> Option<Event> {
3029 unsafe { wait_event_timeout(self.timeout) }
3030 }
3031}
3032
3033pub struct EventSender {
3035 _priv: (),
3036}
3037
3038impl EventSender {
3039 #[doc(alias = "SDL_PushEvent")]
3041 pub fn push_event(&self, event: Event) -> Result<(), Error> {
3042 match event.to_ll() {
3043 Some(mut raw_event) => {
3044 let ok = unsafe { sys::events::SDL_PushEvent(&mut raw_event) };
3045 if ok {
3046 Ok(())
3047 } else {
3048 Err(get_error())
3049 }
3050 }
3051 None => Err(Error(
3052 "Cannot push unsupported event type to the queue".to_owned(),
3053 )),
3054 }
3055 }
3056
3057 pub fn push_custom_event<T: ::std::any::Any>(&self, event: T) -> Result<(), Error> {
3087 use std::any::TypeId;
3088 let cet = CUSTOM_EVENT_TYPES.lock().unwrap();
3089 let type_id = TypeId::of::<Box<T>>();
3090
3091 let user_event_id = *match cet.type_id_to_sdl_id.get(&type_id) {
3092 Some(id) => id,
3093 None => {
3094 return Err(Error(
3095 "Type is not registered as a custom event type!".to_owned(),
3096 ));
3097 }
3098 };
3099
3100 let event_box = Box::new(event);
3101 let event = Event::User {
3102 timestamp: 0,
3103 window_id: 0,
3104 type_: user_event_id,
3105 code: 0,
3106 data1: Box::into_raw(event_box) as *mut c_void,
3107 data2: ::std::ptr::null_mut(),
3108 };
3109 drop(cet);
3110
3111 self.push_event(event)?;
3112
3113 Ok(())
3114 }
3115}
3116
3117pub trait EventWatchCallback {
3119 fn callback(&mut self, event: Event);
3120}
3121
3122pub struct EventWatch<'a, CB: EventWatchCallback + 'a> {
3126 activated: bool,
3127 callback: Box<CB>,
3128 _phantom: PhantomData<&'a CB>,
3129}
3130
3131impl<'a, CB: EventWatchCallback + 'a> EventWatch<'a, CB> {
3132 fn add(callback: CB) -> EventWatch<'a, CB> {
3133 let f = Box::new(callback);
3134 let mut watch = EventWatch {
3135 activated: false,
3136 callback: f,
3137 _phantom: PhantomData,
3138 };
3139 watch.activate();
3140 watch
3141 }
3142
3143 pub fn activate(&mut self) {
3146 if !self.activated {
3147 self.activated = true;
3148 unsafe { sys::events::SDL_AddEventWatch(self.filter(), self.callback()) };
3149 }
3150 }
3151
3152 pub fn deactivate(&mut self) {
3155 if self.activated {
3156 self.activated = false;
3157 unsafe { sys::events::SDL_RemoveEventWatch(self.filter(), self.callback()) };
3158 }
3159 }
3160
3161 pub fn activated(&self) -> bool {
3163 self.activated
3164 }
3165
3166 pub fn set_activated(&mut self, activate: bool) {
3168 if activate {
3169 self.activate();
3170 } else {
3171 self.deactivate();
3172 }
3173 }
3174
3175 fn filter(&self) -> SDL_EventFilter {
3176 Some(event_callback_marshall::<CB>)
3177 }
3178
3179 fn callback(&mut self) -> *mut c_void {
3180 &mut *self.callback as *mut _ as *mut c_void
3181 }
3182}
3183
3184impl<'a, CB: EventWatchCallback + 'a> Drop for EventWatch<'a, CB> {
3185 fn drop(&mut self) {
3186 self.deactivate();
3187 }
3188}
3189
3190extern "C" fn event_callback_marshall<CB: EventWatchCallback>(
3191 user_data: *mut c_void,
3192 event: *mut sdl3_sys::events::SDL_Event,
3193) -> bool {
3194 let f: &mut CB = unsafe { &mut *(user_data as *mut _) };
3195 let event = Event::from_ll(unsafe { *event });
3196 f.callback(event);
3197 false
3198}
3199
3200impl<F: FnMut(Event)> EventWatchCallback for F {
3201 fn callback(&mut self, event: Event) {
3202 self(event)
3203 }
3204}
3205
3206#[cfg(test)]
3207mod test {
3208 use crate::video::Display;
3209
3210 use super::super::gamepad::{Axis, Button};
3211 use super::super::joystick::HatState;
3212 use super::super::keyboard::{Keycode, Mod, Scancode};
3213 use super::super::mouse::{MouseButton, MouseState, MouseWheelDirection};
3214 use super::super::video::Orientation;
3215 use super::DisplayEvent;
3216 use super::Event;
3217 use super::WindowEvent;
3218
3219 #[test]
3222 fn test_to_from_ll() {
3223 {
3224 let e = Event::Quit { timestamp: 0 };
3225 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3226 assert_eq!(e, e2);
3227 }
3228 {
3229 let e = Event::Display {
3230 timestamp: 0,
3231 display: Display::from_ll(1),
3232 display_event: DisplayEvent::Orientation(Orientation::LandscapeFlipped),
3233 };
3234 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3235 assert_eq!(e, e2);
3236 }
3237 {
3238 let e = Event::Window {
3239 timestamp: 0,
3240 window_id: 0,
3241 win_event: WindowEvent::Resized(1, 2),
3242 };
3243 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3244 assert_eq!(e, e2);
3245 }
3246 {
3247 let e = Event::KeyDown {
3248 timestamp: 0,
3249 window_id: 1,
3250 keycode: Some(Keycode::Q),
3251 scancode: Some(Scancode::Q),
3252 keymod: Mod::all(),
3253 repeat: false,
3254 which: 0,
3255 raw: 0,
3256 };
3257 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3258 assert_eq!(e, e2);
3259 }
3260 {
3261 let e = Event::KeyUp {
3262 timestamp: 123,
3263 window_id: 0,
3264 keycode: Some(Keycode::R),
3265 scancode: Some(Scancode::R),
3266 keymod: Mod::empty(),
3267 repeat: true,
3268 which: 0,
3269 raw: 0,
3270 };
3271 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3272 assert_eq!(e, e2);
3273 }
3274 {
3275 let e = Event::MouseMotion {
3276 timestamp: 0,
3277 window_id: 0,
3278 which: 1,
3279 mousestate: MouseState::from_sdl_state(1),
3280 x: 3.,
3281 y: 91.,
3282 xrel: -1.,
3283 yrel: 43.,
3284 };
3285 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3286 assert_eq!(e, e2);
3287 }
3288 {
3289 let e = Event::MouseButtonDown {
3290 timestamp: 5634,
3291 window_id: 2,
3292 which: 0,
3293 mouse_btn: MouseButton::Left,
3294 clicks: 1,
3295 x: 543.,
3296 y: 345.,
3297 };
3298 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3299 assert_eq!(e, e2);
3300 }
3301 {
3302 let e = Event::MouseButtonUp {
3303 timestamp: 0,
3304 window_id: 2,
3305 which: 0,
3306 mouse_btn: MouseButton::Left,
3307 clicks: 1,
3308 x: 543.,
3309 y: 345.,
3310 };
3311 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3312 assert_eq!(e, e2);
3313 }
3314 {
3315 let e = Event::MouseWheel {
3316 timestamp: 1,
3317 window_id: 0,
3318 which: 32,
3319 x: 23.,
3320 y: 91.,
3321 direction: MouseWheelDirection::Flipped,
3322 mouse_x: 2.,
3323 mouse_y: 3.,
3324 };
3325 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3326 assert_eq!(e, e2);
3327 }
3328 {
3329 let e = Event::JoyAxisMotion {
3330 timestamp: 0,
3331 which: 1,
3332 axis_idx: 1,
3333 value: 12,
3334 };
3335 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3336 assert_eq!(e, e2);
3337 }
3338 {
3339 let e = Event::JoyHatMotion {
3340 timestamp: 0,
3341 which: 3,
3342 hat_idx: 1,
3343 state: HatState::Left,
3344 };
3345 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3346 assert_eq!(e, e2);
3347 }
3348 {
3349 let e = Event::JoyButtonDown {
3350 timestamp: 0,
3351 which: 0,
3352 button_idx: 3,
3353 };
3354 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3355 assert_eq!(e, e2);
3356 }
3357 {
3358 let e = Event::JoyButtonUp {
3359 timestamp: 9876,
3360 which: 1,
3361 button_idx: 2,
3362 };
3363 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3364 assert_eq!(e, e2);
3365 }
3366 {
3367 let e = Event::JoyDeviceAdded {
3368 timestamp: 0,
3369 which: 1,
3370 };
3371 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3372 assert_eq!(e, e2);
3373 }
3374 {
3375 let e = Event::JoyDeviceRemoved {
3376 timestamp: 0,
3377 which: 2,
3378 };
3379 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3380 assert_eq!(e, e2);
3381 }
3382 {
3383 let e = Event::ControllerAxisMotion {
3384 timestamp: 53,
3385 which: 0,
3386 axis: Axis::LeftX,
3387 value: 3,
3388 };
3389 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3390 assert_eq!(e, e2);
3391 }
3392 {
3393 let e = Event::ControllerButtonDown {
3394 timestamp: 0,
3395 which: 1,
3396 button: Button::Guide,
3397 };
3398 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3399 assert_eq!(e, e2);
3400 }
3401 {
3402 let e = Event::ControllerButtonUp {
3403 timestamp: 654214,
3404 which: 0,
3405 button: Button::DPadRight,
3406 };
3407 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3408 assert_eq!(e, e2);
3409 }
3410 {
3411 let e = Event::ControllerDeviceAdded {
3412 timestamp: 543,
3413 which: 3,
3414 };
3415 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3416 assert_eq!(e, e2);
3417 }
3418 {
3419 let e = Event::ControllerDeviceRemoved {
3420 timestamp: 555,
3421 which: 3,
3422 };
3423 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3424 assert_eq!(e, e2);
3425 }
3426 {
3427 let e = Event::ControllerDeviceRemapped {
3428 timestamp: 654,
3429 which: 0,
3430 };
3431 let e2 = Event::from_ll(e.clone().to_ll().unwrap());
3432 assert_eq!(e, e2);
3433 }
3434 }
3435
3436 #[test]
3437 fn test_from_ll_keymod_keydown_unknown_bits() {
3438 let mut raw_event = Event::KeyDown {
3439 timestamp: 0,
3440 window_id: 1,
3441 keycode: Some(Keycode::Q),
3442 scancode: Some(Scancode::Q),
3443 keymod: Mod::empty(),
3444 repeat: false,
3445 which: 0,
3446 raw: 0,
3447 }
3448 .to_ll()
3449 .unwrap();
3450
3451 unsafe {
3453 raw_event.key.r#mod = 0xffff;
3454 }
3455
3456 if let Event::KeyDown { keymod, .. } = Event::from_ll(raw_event) {
3457 assert_eq!(keymod, Mod::all());
3458 } else {
3459 panic!()
3460 }
3461 }
3462
3463 #[test]
3464 fn test_from_ll_keymod_keyup_unknown_bits() {
3465 let mut raw_event = Event::KeyUp {
3466 timestamp: 0,
3467 window_id: 1,
3468 keycode: Some(Keycode::Q),
3469 scancode: Some(Scancode::Q),
3470 keymod: Mod::empty(),
3471 repeat: false,
3472 which: 0,
3473 raw: 0,
3474 }
3475 .to_ll()
3476 .unwrap();
3477
3478 unsafe {
3480 raw_event.key.r#mod = 0xffff;
3481 }
3482
3483 if let Event::KeyUp { keymod, .. } = Event::from_ll(raw_event) {
3484 assert_eq!(keymod, Mod::all());
3485 } else {
3486 panic!()
3487 }
3488 }
3489}