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