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