1use glib::translate::*;
4use libc::c_void;
5use std::fmt;
6use std::mem;
7use std::ptr;
8
9use crate::AxisUse;
10use crate::Device;
11use crate::DeviceTool;
12use crate::EventSequence;
13use crate::EventType;
14use crate::ModifierType;
15use crate::Screen;
16use crate::ScrollDirection;
17use crate::Seat;
18use crate::Window;
19
20glib::wrapper! {
21 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
23 #[doc(alias = "GdkEvent")]
24 pub struct Event(Boxed<ffi::GdkEvent>);
25
26 match fn {
27 copy => |ptr| ffi::gdk_event_copy(ptr),
28 free => |ptr| ffi::gdk_event_free(ptr),
29 type_ => || ffi::gdk_event_get_type(),
30 }
31}
32
33impl Event {
34 #[doc(alias = "gdk_event_new")]
36 pub fn new(type_: EventType) -> Event {
37 assert_initialized_main_thread!();
38 unsafe { from_glib_none(ffi::gdk_event_new(type_.into_glib())) }
39 }
40
41 #[doc(alias = "gdk_event_get")]
42 pub fn get() -> Option<Event> {
43 assert_initialized_main_thread!();
44 unsafe { from_glib_none(ffi::gdk_event_get()) }
45 }
46
47 #[doc(alias = "gdk_event_put")]
48 pub fn put(&self) {
49 unsafe { ffi::gdk_event_put(self.to_glib_none().0) }
50 }
51
52 #[doc(alias = "gdk_event_handler_set")]
57 pub fn set_handler<F: Fn(&mut Event) + 'static>(handler: Option<F>) {
58 assert_initialized_main_thread!();
59 unsafe extern "C" fn event_handler_trampoline<F: Fn(&mut Event) + 'static>(
60 event: *mut ffi::GdkEvent,
61 ptr: glib::ffi::gpointer,
62 ) {
63 if !ptr.is_null() {
64 let f: &F = &*(ptr as *mut _);
65 let mut event = from_glib_none(event);
66 f(&mut event)
67 }
68 }
69 unsafe extern "C" fn event_handler_destroy<F: Fn(&mut Event) + 'static>(
70 ptr: glib::ffi::gpointer,
71 ) {
72 if !ptr.is_null() {
73 let _boxed: Box<F> = Box::from_raw(ptr as *mut _);
75 }
76 }
77 if let Some(handler) = handler {
78 let boxed: Box<F> = Box::new(handler);
81 let ptr: *mut c_void = Box::into_raw(boxed) as *mut _;
82 unsafe {
83 ffi::gdk_event_handler_set(
84 Some(event_handler_trampoline::<F>),
85 ptr,
86 Some(event_handler_destroy::<F>),
87 )
88 }
89 } else {
90 unsafe { ffi::gdk_event_handler_set(None, ptr::null_mut(), None) }
91 }
92 }
93
94 #[doc(alias = "gdk_event_get_axis")]
95 #[doc(alias = "get_axis")]
96 pub fn axis(&self, axis_use: AxisUse) -> Option<f64> {
97 let mut value = 0f64;
98 if unsafe {
99 from_glib(ffi::gdk_event_get_axis(
100 self.to_glib_none().0,
101 axis_use.into_glib(),
102 &mut value,
103 ))
104 } {
105 Some(value)
106 } else {
107 None
108 }
109 }
110
111 #[doc(alias = "gdk_event_get_button")]
112 #[doc(alias = "get_button")]
113 pub fn button(&self) -> Option<u32> {
114 let mut button = 0u32;
115 if unsafe {
116 from_glib(ffi::gdk_event_get_button(
117 self.to_glib_none().0,
118 &mut button,
119 ))
120 } {
121 Some(button)
122 } else {
123 None
124 }
125 }
126
127 #[doc(alias = "gdk_event_get_click_count")]
128 #[doc(alias = "get_click_count")]
129 pub fn click_count(&self) -> Option<u32> {
130 let mut click_count = 0u32;
131 if unsafe {
132 from_glib(ffi::gdk_event_get_click_count(
133 self.to_glib_none().0,
134 &mut click_count,
135 ))
136 } {
137 Some(click_count)
138 } else {
139 None
140 }
141 }
142
143 #[doc(alias = "gdk_event_get_coords")]
144 #[doc(alias = "get_coords")]
145 pub fn coords(&self) -> Option<(f64, f64)> {
146 let mut x_win = 0f64;
147 let mut y_win = 0f64;
148 if unsafe {
149 from_glib(ffi::gdk_event_get_coords(
150 self.to_glib_none().0,
151 &mut x_win,
152 &mut y_win,
153 ))
154 } {
155 Some((x_win, y_win))
156 } else {
157 None
158 }
159 }
160
161 #[doc(alias = "gdk_event_get_keycode")]
162 #[doc(alias = "get_keycode")]
163 pub fn keycode(&self) -> Option<u16> {
164 let mut keycode = 0u16;
165 if unsafe {
166 from_glib(ffi::gdk_event_get_keycode(
167 self.to_glib_none().0,
168 &mut keycode,
169 ))
170 } {
171 Some(keycode)
172 } else {
173 None
174 }
175 }
176
177 #[doc(alias = "gdk_event_get_keyval")]
178 #[doc(alias = "get_keyval")]
179 pub fn keyval(&self) -> Option<u32> {
180 let mut keyval = 0u32;
181 if unsafe {
182 from_glib(ffi::gdk_event_get_keyval(
183 self.to_glib_none().0,
184 &mut keyval,
185 ))
186 } {
187 Some(keyval)
188 } else {
189 None
190 }
191 }
192
193 #[doc(alias = "gdk_event_get_root_coords")]
194 #[doc(alias = "get_root_coords")]
195 pub fn root_coords(&self) -> Option<(f64, f64)> {
196 let mut x_root = 0f64;
197 let mut y_root = 0f64;
198 if unsafe {
199 from_glib(ffi::gdk_event_get_root_coords(
200 self.to_glib_none().0,
201 &mut x_root,
202 &mut y_root,
203 ))
204 } {
205 Some((x_root, y_root))
206 } else {
207 None
208 }
209 }
210
211 #[doc(alias = "gdk_event_get_scroll_direction")]
212 #[doc(alias = "get_scroll_direction")]
213 pub fn scroll_direction(&self) -> Option<ScrollDirection> {
214 unsafe {
215 let mut direction = mem::MaybeUninit::uninit();
216 if from_glib(ffi::gdk_event_get_scroll_direction(
217 self.to_glib_none().0,
218 direction.as_mut_ptr(),
219 )) {
220 Some(from_glib(direction.assume_init()))
221 } else {
222 None
223 }
224 }
225 }
226
227 #[doc(alias = "gdk_event_get_scroll_deltas")]
228 #[doc(alias = "get_scroll_deltas")]
229 pub fn scroll_deltas(&self) -> Option<(f64, f64)> {
230 let mut delta_x = 0f64;
231 let mut delta_y = 0f64;
232 if unsafe {
233 from_glib(ffi::gdk_event_get_scroll_deltas(
234 self.to_glib_none().0,
235 &mut delta_x,
236 &mut delta_y,
237 ))
238 } {
239 Some((delta_x, delta_y))
240 } else {
241 None
242 }
243 }
244
245 #[doc(alias = "gdk_event_is_scroll_stop_event")]
246 pub fn is_scroll_stop_event(&self) -> bool {
247 unsafe { from_glib(ffi::gdk_event_is_scroll_stop_event(self.to_glib_none().0)) }
248 }
249
250 #[doc(alias = "gdk_event_get_state")]
251 #[doc(alias = "get_state")]
252 pub fn state(&self) -> Option<ModifierType> {
253 unsafe {
254 let mut state = mem::MaybeUninit::uninit();
255 if from_glib(ffi::gdk_event_get_state(
256 self.to_glib_none().0,
257 state.as_mut_ptr(),
258 )) {
259 Some(from_glib(state.assume_init() as _))
260 } else {
261 None
262 }
263 }
264 }
265
266 #[doc(alias = "gdk_event_get_time")]
267 #[doc(alias = "get_time")]
268 pub fn time(&self) -> u32 {
269 unsafe { ffi::gdk_event_get_time(self.to_glib_none().0) }
270 }
271
272 #[doc(alias = "gdk_event_get_window")]
274 #[doc(alias = "get_window")]
275 pub fn window(&self) -> Option<Window> {
276 unsafe { from_glib_none(ffi::gdk_event_get_window(self.to_glib_none().0)) }
277 }
278
279 #[doc(alias = "gdk_event_get_event_sequence")]
280 #[doc(alias = "get_event_sequence")]
281 pub fn event_sequence(&self) -> Option<EventSequence> {
282 unsafe { from_glib_none(ffi::gdk_event_get_event_sequence(self.to_glib_none().0)) }
283 }
284
285 #[doc(alias = "gdk_event_triggers_context_menu")]
286 pub fn triggers_context_menu(&self) -> bool {
287 unsafe { from_glib(ffi::gdk_event_triggers_context_menu(self.to_glib_none().0)) }
288 }
289
290 #[doc(alias = "gdk_event_get_seat")]
291 #[doc(alias = "get_seat")]
292 pub fn seat(&self) -> Option<Seat> {
293 unsafe { from_glib_none(ffi::gdk_event_get_seat(self.to_glib_none().0)) }
294 }
295
296 #[doc(alias = "gdk_event_get_scancode")]
297 #[doc(alias = "get_scancode")]
298 pub fn scancode(&self) -> i32 {
299 unsafe { ffi::gdk_event_get_scancode(mut_override(self.to_glib_none().0)) }
300 }
301
302 #[doc(alias = "gdk_event_get_pointer_emulated")]
303 #[doc(alias = "get_pointer_emulated")]
304 pub fn is_pointer_emulated(&self) -> bool {
305 unsafe {
306 from_glib(ffi::gdk_event_get_pointer_emulated(mut_override(
307 self.to_glib_none().0,
308 )))
309 }
310 }
311
312 #[doc(alias = "gdk_event_set_screen")]
313 pub fn set_screen(&mut self, screen: Option<&Screen>) {
314 unsafe { ffi::gdk_event_set_screen(self.to_glib_none_mut().0, screen.to_glib_none().0) }
315 }
316
317 #[doc(alias = "gdk_event_get_screen")]
318 #[doc(alias = "get_screen")]
319 pub fn screen(&self) -> Option<Screen> {
320 unsafe { from_glib_none(ffi::gdk_event_get_screen(self.to_glib_none().0)) }
321 }
322
323 #[doc(alias = "gdk_event_set_device")]
324 pub fn set_device(&mut self, device: Option<&Device>) {
325 unsafe { ffi::gdk_event_set_device(self.to_glib_none_mut().0, device.to_glib_none().0) }
326 }
327
328 #[doc(alias = "gdk_event_get_device")]
329 #[doc(alias = "get_device")]
330 pub fn device(&self) -> Option<Device> {
331 unsafe { from_glib_none(ffi::gdk_event_get_device(self.to_glib_none().0)) }
332 }
333
334 #[doc(alias = "gdk_event_set_source_device")]
335 pub fn set_source_device(&mut self, device: Option<&Device>) {
336 unsafe {
337 ffi::gdk_event_set_source_device(self.to_glib_none_mut().0, device.to_glib_none().0)
338 }
339 }
340
341 #[doc(alias = "gdk_event_get_source_device")]
342 #[doc(alias = "get_source_device")]
343 pub fn source_device(&self) -> Option<Device> {
344 unsafe { from_glib_none(ffi::gdk_event_get_source_device(self.to_glib_none().0)) }
345 }
346
347 #[doc(alias = "gdk_event_set_device_tool")]
348 pub fn set_device_tool(&mut self, device: Option<&DeviceTool>) {
349 unsafe {
350 ffi::gdk_event_set_device_tool(self.to_glib_none_mut().0, device.to_glib_none().0)
351 }
352 }
353
354 #[doc(alias = "gdk_event_get_device_tool")]
355 #[doc(alias = "get_device_tool")]
356 pub fn device_tool(&self) -> Option<DeviceTool> {
357 unsafe { from_glib_none(ffi::gdk_event_get_device_tool(self.to_glib_none().0)) }
358 }
359
360 #[doc(alias = "get_event_type")]
362 pub fn event_type(&self) -> EventType {
363 unsafe { from_glib(self.as_ref().type_) }
364 }
365
366 #[allow(clippy::cast_lossless)]
368 #[doc(alias = "get_send_event")]
369 pub fn is_send_event(&self) -> bool {
370 unsafe { from_glib(self.as_ref().send_event as i32) }
371 }
372
373 pub fn is<T: FromEvent>(&self) -> bool {
375 T::is(self)
376 }
377
378 pub fn downcast<T: FromEvent>(self) -> Result<T, Self> {
380 T::from(self)
381 }
382
383 pub fn downcast_ref<T: FromEvent>(&self) -> Option<&T> {
385 if T::is(self) {
386 unsafe { Some(&*(self as *const _ as *const _)) }
387 } else {
388 None
389 }
390 }
391
392 pub fn downcast_mut<T: FromEvent>(&mut self) -> Option<&mut T> {
394 if T::is(self) {
395 unsafe { Some(&mut *(self as *mut _ as *mut _)) }
396 } else {
397 None
398 }
399 }
400}
401
402impl fmt::Debug for Event {
403 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
404 fmt.debug_struct("Event")
405 .field("inner", &self.inner)
406 .field("type", &self.event_type())
407 .finish()
408 }
409}
410
411pub unsafe trait FromEvent: Sized {
413 fn is(ev: &Event) -> bool;
414 fn from(ev: Event) -> Result<Self, Event>;
415}
416
417macro_rules! event_wrapper {
418 ($name:ident, $ffi_name:ident) => {
419 impl<'a> ToGlibPtr<'a, *const ::ffi::$ffi_name> for $name {
420 type Storage = &'a Self;
421
422 #[inline]
423 fn to_glib_none(&'a self) -> Stash<'a, *const ::ffi::$ffi_name, Self> {
424 let ptr =
425 <$crate::Event as ToGlibPtr<*const ::ffi::GdkEvent>>::to_glib_none(&*self).0;
426 Stash(ptr as *const ::ffi::$ffi_name, self)
427 }
428 }
429
430 impl<'a> ToGlibPtrMut<'a, *mut ::ffi::$ffi_name> for $name {
431 type Storage = &'a mut Self;
432
433 #[inline]
434 fn to_glib_none_mut(&'a mut self) -> StashMut<'a, *mut ::ffi::$ffi_name, Self> {
435 let ptr = <$crate::Event as ToGlibPtrMut<*mut ::ffi::GdkEvent>>::to_glib_none_mut(
436 &mut *self,
437 )
438 .0;
439 StashMut(ptr as *mut ::ffi::$ffi_name, self)
440 }
441 }
442
443 impl FromGlibPtrNone<*mut ::ffi::$ffi_name> for $name {
444 #[inline]
445 unsafe fn from_glib_none(ptr: *mut ::ffi::$ffi_name) -> Self {
446 <$name as crate::event::FromEvent>::from(from_glib_none(
447 ptr as *mut ::ffi::GdkEvent,
448 ))
449 .unwrap()
450 }
451 }
452
453 impl FromGlibPtrBorrow<*mut ::ffi::$ffi_name> for $name {
454 #[inline]
455 unsafe fn from_glib_borrow(
456 ptr: *mut ::ffi::$ffi_name,
457 ) -> glib::translate::Borrowed<Self> {
458 glib::translate::Borrowed::new(
459 <$name as crate::event::FromEvent>::from(
460 crate::Event::from_glib_borrow(ptr as *mut ::ffi::GdkEvent).into_inner(),
461 )
462 .map_err(std::mem::forget)
463 .unwrap(),
464 )
465 }
466 }
467
468 impl FromGlibPtrFull<*mut ::ffi::$ffi_name> for $name {
469 #[inline]
470 unsafe fn from_glib_full(ptr: *mut ::ffi::$ffi_name) -> Self {
471 <$name as crate::event::FromEvent>::from(from_glib_full(
472 ptr as *mut ::ffi::GdkEvent,
473 ))
474 .unwrap()
475 }
476 }
477
478 impl AsRef<::ffi::$ffi_name> for $name {
479 #[inline]
480 fn as_ref(&self) -> &::ffi::$ffi_name {
481 unsafe {
482 let ptr: *const ::ffi::$ffi_name = self.to_glib_none().0;
483 &*ptr
484 }
485 }
486 }
487
488 impl AsMut<::ffi::$ffi_name> for $name {
489 #[inline]
490 fn as_mut(&mut self) -> &mut ::ffi::$ffi_name {
491 unsafe {
492 let ptr: *mut ::ffi::$ffi_name = self.to_glib_none_mut().0;
493 &mut *ptr
494 }
495 }
496 }
497 };
498}
499
500event_wrapper!(Event, GdkEventAny);
501
502macro_rules! event_subtype {
503 ($name:ident, $($ty:path)|+) => {
504 unsafe impl crate::event::FromEvent for $name {
505 #[inline]
506 fn is(ev: &crate::event::Event) -> bool {
507 skip_assert_initialized!();
508 matches!(ev.as_ref().type_, $($ty)|+)
509 }
510
511 #[inline]
512 fn from(ev: crate::event::Event) -> Result<Self, crate::event::Event> {
513 skip_assert_initialized!();
514 if Self::is(&ev) {
515 Ok($name(ev))
516 } else {
517 Err(ev)
518 }
519 }
520 }
521
522 impl ::std::ops::Deref for $name {
523 type Target = crate::event::Event;
524
525 fn deref(&self) -> &crate::event::Event {
526 &self.0
527 }
528 }
529
530 impl ::std::ops::DerefMut for $name {
531 fn deref_mut(&mut self) -> &mut crate::event::Event {
532 &mut self.0
533 }
534 }
535 };
536}
537
538unsafe impl FromEvent for Event {
539 #[inline]
540 fn is(_ev: &Event) -> bool {
541 skip_assert_initialized!();
542 true
543 }
544
545 #[inline]
546 fn from(ev: Event) -> Result<Self, Event> {
547 skip_assert_initialized!();
548 Ok(ev)
549 }
550}