animate/legacy/input_device.rs
1use crate::{
2 Actor, Backend, DeviceManager, Event, EventSequence, InputAxis, InputDeviceType, InputMode,
3 InternalPoint, ModifierType, Stage,
4};
5use glib::{
6 object::{IsA, ObjectType as ObjectType_},
7 signal::{connect_raw, SignalHandlerId},
8 translate::*,
9 GString, StaticType, Value,
10};
11use std::boxed::Box as Box_;
12use std::{fmt, mem, mem::transmute};
13
14glib_wrapper! {
15 pub struct InputDevice(Object<ffi::ClutterInputDevice, ffi::ClutterInputDeviceClass, InputDeviceClass>);
16
17 match fn {
18 get_type => || ffi::clutter_input_device_get_type(),
19 }
20}
21
22impl InputDevice {
23 /// Retrieves a pointer to the `InputDevice` that has been
24 /// associated to `self`.
25 ///
26 /// If the `InputDevice:device-mode` property of `self` is
27 /// set to `InputMode::Master`, this function will return
28 /// `None`.
29 ///
30 /// # Returns
31 ///
32 /// a `InputDevice`, or `None`
33 pub fn get_associated_device(&self) -> Option<InputDevice> {
34 unsafe {
35 from_glib_none(ffi::clutter_input_device_get_associated_device(
36 self.to_glib_none().0,
37 ))
38 }
39 }
40
41 /// Retrieves the type of axis on `self` at the given index.
42 /// ## `index_`
43 /// the index of the axis
44 ///
45 /// # Returns
46 ///
47 /// the axis type
48 pub fn get_axis(&self, index_: u32) -> InputAxis {
49 unsafe {
50 from_glib(ffi::clutter_input_device_get_axis(
51 self.to_glib_none().0,
52 index_,
53 ))
54 }
55 }
56
57 //pub fn get_axis_value(&self, axes: &[f64], axis: InputAxis) -> Option<f64> {
58 // unsafe { TODO: call clutter_sys:clutter_input_device_get_axis_value() }
59 //}
60
61 // /// Retrieves the latest coordinates of a pointer or touch point of
62 // /// `self`.
63 // /// ## `sequence`
64 // /// a `EventSequence`, or `None` if
65 // /// the device is not touch-based
66 // /// ## `point`
67 // /// return location for the pointer
68 // /// or touch point
69 // ///
70 // /// # Returns
71 // ///
72 // /// `false` if the device's sequence hasn't been found,
73 // /// and `true` otherwise.
74 // pub fn get_coords(&self, sequence: Option<&mut EventSequence>) -> Option<Point> {
75 // unsafe {
76 // let mut point = Point::uninitialized();
77 // let ret = from_glib(ffi::clutter_input_device_get_coords(
78 // self.to_glib_none().0,
79 // sequence.to_glib_none_mut().0,
80 // point.to_glib_none_mut().0,
81 // ));
82 // if ret {
83 // Some(point)
84 // } else {
85 // None
86 // }
87 // }
88 // }
89
90 /// Retrieves the unique identifier of `self`
91 ///
92 /// # Returns
93 ///
94 /// the identifier of the device
95 pub fn get_device_id(&self) -> i32 {
96 unsafe { ffi::clutter_input_device_get_device_id(self.to_glib_none().0) }
97 }
98
99 /// Retrieves the `InputMode` of `self`.
100 ///
101 /// # Returns
102 ///
103 /// the device mode
104 pub fn get_device_mode(&self) -> InputMode {
105 unsafe {
106 from_glib(ffi::clutter_input_device_get_device_mode(
107 self.to_glib_none().0,
108 ))
109 }
110 }
111
112 /// Retrieves the name of the `self`
113 ///
114 /// # Returns
115 ///
116 /// the name of the device, or `None`. The returned string
117 /// is owned by the `InputDevice` and should never be modified
118 /// or freed
119 pub fn get_device_name(&self) -> Option<GString> {
120 unsafe {
121 from_glib_none(ffi::clutter_input_device_get_device_name(
122 self.to_glib_none().0,
123 ))
124 }
125 }
126
127 /// Retrieves the type of `self`
128 ///
129 /// # Returns
130 ///
131 /// the type of the device
132 pub fn get_device_type(&self) -> InputDeviceType {
133 unsafe {
134 from_glib(ffi::clutter_input_device_get_device_type(
135 self.to_glib_none().0,
136 ))
137 }
138 }
139
140 /// Retrieves whether `self` is enabled.
141 ///
142 /// # Returns
143 ///
144 /// `true` if the device is enabled
145 pub fn get_enabled(&self) -> bool {
146 unsafe { from_glib(ffi::clutter_input_device_get_enabled(self.to_glib_none().0)) }
147 }
148
149 /// Retrieves a pointer to the `Actor` currently grabbing all
150 /// the events coming from `self`.
151 ///
152 /// # Returns
153 ///
154 /// a `Actor`, or `None`
155 pub fn get_grabbed_actor(&self) -> Option<Actor> {
156 unsafe {
157 from_glib_none(ffi::clutter_input_device_get_grabbed_actor(
158 self.to_glib_none().0,
159 ))
160 }
161 }
162
163 /// Retrieves whether `self` has a pointer that follows the
164 /// device motion.
165 ///
166 /// # Returns
167 ///
168 /// `true` if the device has a cursor
169 pub fn get_has_cursor(&self) -> bool {
170 unsafe {
171 from_glib(ffi::clutter_input_device_get_has_cursor(
172 self.to_glib_none().0,
173 ))
174 }
175 }
176
177 /// Retrieves the key set using `InputDevice::set_key`
178 /// ## `index_`
179 /// the index of the key
180 /// ## `keyval`
181 /// return location for the keyval at `index_`
182 /// ## `modifiers`
183 /// return location for the modifiers at `index_`
184 ///
185 /// # Returns
186 ///
187 /// `true` if a key was set at the given index
188 pub fn get_key(&self, index_: u32) -> Option<(u32, ModifierType)> {
189 unsafe {
190 let mut keyval = mem::MaybeUninit::uninit();
191 let mut modifiers = mem::MaybeUninit::uninit();
192 let ret = from_glib(ffi::clutter_input_device_get_key(
193 self.to_glib_none().0,
194 index_,
195 keyval.as_mut_ptr(),
196 modifiers.as_mut_ptr(),
197 ));
198 let keyval = keyval.assume_init();
199 let modifiers = modifiers.assume_init();
200 if ret {
201 Some((keyval, from_glib(modifiers)))
202 } else {
203 None
204 }
205 }
206 }
207
208 /// Retrieves the current modifiers state of the device, as seen
209 /// by the last event processed.
210 ///
211 /// # Returns
212 ///
213 /// the last known modifier state
214 pub fn get_modifier_state(&self) -> ModifierType {
215 unsafe {
216 from_glib(ffi::clutter_input_device_get_modifier_state(
217 self.to_glib_none().0,
218 ))
219 }
220 }
221
222 /// Retrieves the number of axes available on `self`.
223 ///
224 /// # Returns
225 ///
226 /// the number of axes on the device
227 pub fn get_n_axes(&self) -> u32 {
228 unsafe { ffi::clutter_input_device_get_n_axes(self.to_glib_none().0) }
229 }
230
231 /// Retrieves the number of keys registered for `self`.
232 ///
233 /// # Returns
234 ///
235 /// the number of registered keys
236 pub fn get_n_keys(&self) -> u32 {
237 unsafe { ffi::clutter_input_device_get_n_keys(self.to_glib_none().0) }
238 }
239
240 /// Retrieves the `Actor` underneath the pointer of `self`
241 ///
242 /// # Returns
243 ///
244 /// a pointer to the `Actor` or `None`
245 pub fn get_pointer_actor(&self) -> Option<Actor> {
246 unsafe {
247 from_glib_none(ffi::clutter_input_device_get_pointer_actor(
248 self.to_glib_none().0,
249 ))
250 }
251 }
252
253 /// Retrieves the `Stage` underneath the pointer of `self`
254 ///
255 /// # Returns
256 ///
257 /// a pointer to the `Stage` or `None`
258 pub fn get_pointer_stage(&self) -> Option<Stage> {
259 unsafe {
260 from_glib_none(ffi::clutter_input_device_get_pointer_stage(
261 self.to_glib_none().0,
262 ))
263 }
264 }
265
266 /// Gets the product ID of this device.
267 ///
268 /// # Returns
269 ///
270 /// the product ID
271 pub fn get_product_id(&self) -> Option<GString> {
272 unsafe {
273 from_glib_none(ffi::clutter_input_device_get_product_id(
274 self.to_glib_none().0,
275 ))
276 }
277 }
278
279 /// Retrieves the slave devices attached to `self`.
280 ///
281 /// # Returns
282 ///
283 /// a
284 /// list of `InputDevice`, or `None`. The contents of the list are
285 /// owned by the device. Use `glib::List::free` when done
286 pub fn get_slave_devices(&self) -> Vec<InputDevice> {
287 unsafe {
288 FromGlibPtrContainer::from_glib_container(ffi::clutter_input_device_get_slave_devices(
289 self.to_glib_none().0,
290 ))
291 }
292 }
293
294 /// Gets the vendor ID of this device.
295 ///
296 /// # Returns
297 ///
298 /// the vendor ID
299 pub fn get_vendor_id(&self) -> Option<GString> {
300 unsafe {
301 from_glib_none(ffi::clutter_input_device_get_vendor_id(
302 self.to_glib_none().0,
303 ))
304 }
305 }
306
307 /// Acquires a grab on `actor` for the given `self`.
308 ///
309 /// Any event coming from `self` will be delivered to `actor`, bypassing
310 /// the usual event delivery mechanism, until the grab is released by
311 /// calling `InputDevice::ungrab`.
312 ///
313 /// The grab is client-side: even if the windowing system used by the
314 /// backend has the concept of "device grabs", it will not use them.
315 ///
316 /// Only `InputDevice` of types `InputDeviceType::PointerDevice` and
317 /// `InputDeviceType::KeyboardDevice` can hold a grab.
318 /// ## `actor`
319 /// a `Actor`
320 pub fn grab<P: IsA<Actor>>(&self, actor: &P) {
321 unsafe {
322 ffi::clutter_input_device_grab(self.to_glib_none().0, actor.as_ref().to_glib_none().0);
323 }
324 }
325
326 // /// Translates a hardware keycode from a `KeyEvent` to the
327 // /// equivalent evdev keycode. Note that depending on the input backend
328 // /// used by this function can fail if there is no obvious
329 // /// mapping between the key codes. The hardware keycode can be taken
330 // /// from the `KeyEvent.hardware_keycode` member of `KeyEvent`.
331 // /// ## `hardware_keycode`
332 // /// The hardware keycode from a `KeyEvent`
333 // /// ## `evdev_keycode`
334 // /// The return location for the evdev keycode
335 // ///
336 // /// # Returns
337 // ///
338 // /// `true` if the conversion succeeded, `false` otherwise.
339 // pub fn keycode_to_evdev(&self, hardware_keycode: u32, evdev_keycode: u32) -> bool {
340 // unsafe {
341 // from_glib(ffi::clutter_input_device_keycode_to_evdev(
342 // self.to_glib_none().0,
343 // hardware_keycode,
344 // evdev_keycode,
345 // ))
346 // }
347 // }
348
349 /// Retrieves a pointer to the `Actor` currently grabbing the
350 /// touch events coming from `self` given the `sequence`.
351 /// ## `sequence`
352 /// a `EventSequence`
353 ///
354 /// # Returns
355 ///
356 /// a `Actor`, or `None`
357 pub fn sequence_get_grabbed_actor(&self, sequence: &mut EventSequence) -> Option<Actor> {
358 unsafe {
359 from_glib_none(ffi::clutter_input_device_sequence_get_grabbed_actor(
360 self.to_glib_none().0,
361 sequence.to_glib_none_mut().0,
362 ))
363 }
364 }
365
366 /// Acquires a grab on `actor` for the given `self` and the given touch
367 /// `sequence`.
368 ///
369 /// Any touch event coming from `self` and from `sequence` will be
370 /// delivered to `actor`, bypassing the usual event delivery mechanism,
371 /// until the grab is released by calling
372 /// `InputDevice::sequence_ungrab`.
373 ///
374 /// The grab is client-side: even if the windowing system used by the
375 /// backend has the concept of "device grabs", it will not use them.
376 /// ## `sequence`
377 /// a `EventSequence`
378 /// ## `actor`
379 /// a `Actor`
380 pub fn sequence_grab<P: IsA<Actor>>(&self, sequence: &mut EventSequence, actor: &P) {
381 unsafe {
382 ffi::clutter_input_device_sequence_grab(
383 self.to_glib_none().0,
384 sequence.to_glib_none_mut().0,
385 actor.as_ref().to_glib_none().0,
386 );
387 }
388 }
389
390 /// Releases the grab on the `self` for the given `sequence`, if one is
391 /// in place.
392 /// ## `sequence`
393 /// a `EventSequence`
394 pub fn sequence_ungrab(&self, sequence: &mut EventSequence) {
395 unsafe {
396 ffi::clutter_input_device_sequence_ungrab(
397 self.to_glib_none().0,
398 sequence.to_glib_none_mut().0,
399 );
400 }
401 }
402
403 /// Enables or disables a `InputDevice`.
404 ///
405 /// Only devices with a `InputDevice:device-mode` property set
406 /// to `InputMode::Slave` or `InputMode::Floating` can
407 /// be disabled.
408 /// ## `enabled`
409 /// `true` to enable the `self`
410 pub fn set_enabled(&self, enabled: bool) {
411 unsafe {
412 ffi::clutter_input_device_set_enabled(self.to_glib_none().0, enabled.to_glib());
413 }
414 }
415
416 /// Sets the keyval and modifiers at the given `index_` for `self`.
417 ///
418 /// will use the keyval and modifiers set when filling out
419 /// an event coming from the same input device.
420 /// ## `index_`
421 /// the index of the key
422 /// ## `keyval`
423 /// the keyval
424 /// ## `modifiers`
425 /// a bitmask of modifiers
426 pub fn set_key(&self, index_: u32, keyval: u32, modifiers: ModifierType) {
427 unsafe {
428 ffi::clutter_input_device_set_key(
429 self.to_glib_none().0,
430 index_,
431 keyval,
432 modifiers.to_glib(),
433 );
434 }
435 }
436
437 /// Releases the grab on the `self`, if one is in place.
438 pub fn ungrab(&self) {
439 unsafe {
440 ffi::clutter_input_device_ungrab(self.to_glib_none().0);
441 }
442 }
443
444 /// Forcibly updates the state of the `self` using a `Event`
445 ///
446 /// This function should never be used by applications: it is meant
447 /// for integration with embedding toolkits, like clutter-gtk
448 ///
449 /// Embedding toolkits that disable the event collection inside
450 /// need to use this function to update the state of input devices depending
451 /// on a `Event` that they are going to submit to the event handling code
452 /// in it though `do_event`. Since the input devices hold the state
453 /// that is going to be used to fill in fields like the `ButtonEvent`
454 /// click count, or to emit synthesized events like `EventType::Enter` and
455 /// `EventType::Leave`, it is necessary for embedding toolkits to also be
456 /// responsible of updating the input device state.
457 ///
458 /// For instance, this might be the code to translate an embedding toolkit
459 /// native motion notification into a `MotionEvent` and ask
460 /// to process it:
461 ///
462 ///
463 /// ```text
464 /// Event c_event;
465 ///
466 /// translate_native_event_to_clutter (native_event, &c_event);
467 ///
468 /// do_event (&c_event);
469 /// ```
470 ///
471 /// Before letting `do_event` process the event, it is necessary to call
472 /// `InputDevice::update_from_event`:
473 ///
474 ///
475 /// ```text
476 /// Event c_event;
477 /// DeviceManager *manager;
478 /// InputDevice *device;
479 ///
480 /// translate_native_event_to_clutter (native_event, &c_event);
481 ///
482 /// // get the device manager
483 /// manager = device_manager_get_default ();
484 ///
485 /// // use the default Core Pointer that backends register by default
486 /// device = device_manager_get_core_device (manager, %POINTER_DEVICE);
487 ///
488 /// // update the state of the input device
489 /// input_device_update_from_event (device, &c_event, FALSE);
490 ///
491 /// do_event (&c_event);
492 /// ```
493 ///
494 /// The `update_stage` boolean argument should be used when the input device
495 /// enters and leaves a `Stage`; it will use the `Stage` field
496 /// of the passed `event` to update the stage associated to the input device.
497 /// ## `event`
498 /// a `Event`
499 /// ## `update_stage`
500 /// whether to update the `Stage` of the `self`
501 /// using the stage of the event
502 pub fn update_from_event(&self, event: &mut Event, update_stage: bool) {
503 unsafe {
504 ffi::clutter_input_device_update_from_event(
505 self.to_glib_none().0,
506 event.to_glib_none_mut().0,
507 update_stage.to_glib(),
508 );
509 }
510 }
511
512 /// The `Backend` that created the device.
513 pub fn get_property_backend(&self) -> Option<Backend> {
514 unsafe {
515 let mut value = Value::from_type(<Backend as StaticType>::static_type());
516 gobject_sys::g_object_get_property(
517 self.as_ptr() as *mut gobject_sys::GObject,
518 b"backend\0".as_ptr() as *const _,
519 value.to_glib_none_mut().0,
520 );
521 value
522 .get()
523 .expect("Return Value for property `backend` getter")
524 }
525 }
526
527 /// The `DeviceManager` instance which owns the device
528 pub fn get_property_device_manager(&self) -> Option<DeviceManager> {
529 unsafe {
530 let mut value = Value::from_type(<DeviceManager as StaticType>::static_type());
531 gobject_sys::g_object_get_property(
532 self.as_ptr() as *mut gobject_sys::GObject,
533 b"device-manager\0".as_ptr() as *const _,
534 value.to_glib_none_mut().0,
535 );
536 value
537 .get()
538 .expect("Return Value for property `device-manager` getter")
539 }
540 }
541
542 /// The unique identifier of the device
543 pub fn get_property_id(&self) -> i32 {
544 unsafe {
545 let mut value = Value::from_type(<i32 as StaticType>::static_type());
546 gobject_sys::g_object_get_property(
547 self.as_ptr() as *mut gobject_sys::GObject,
548 b"id\0".as_ptr() as *const _,
549 value.to_glib_none_mut().0,
550 );
551 value
552 .get()
553 .expect("Return Value for property `id` getter")
554 .unwrap()
555 }
556 }
557
558 /// The name of the device
559 pub fn get_property_name(&self) -> Option<GString> {
560 unsafe {
561 let mut value = Value::from_type(<GString as StaticType>::static_type());
562 gobject_sys::g_object_get_property(
563 self.as_ptr() as *mut gobject_sys::GObject,
564 b"name\0".as_ptr() as *const _,
565 value.to_glib_none_mut().0,
566 );
567 value
568 .get()
569 .expect("Return Value for property `name` getter")
570 }
571 }
572
573 pub fn connect_property_enabled_notify<F: Fn(&InputDevice) + 'static>(
574 &self,
575 f: F,
576 ) -> SignalHandlerId {
577 unsafe extern "C" fn notify_enabled_trampoline<F: Fn(&InputDevice) + 'static>(
578 this: *mut ffi::ClutterInputDevice,
579 _param_spec: glib_sys::gpointer,
580 f: glib_sys::gpointer,
581 ) {
582 let f: &F = &*(f as *const F);
583 f(&from_glib_borrow(this))
584 }
585 unsafe {
586 let f: Box_<F> = Box_::new(f);
587 connect_raw(
588 self.as_ptr() as *mut _,
589 b"notify::enabled\0".as_ptr() as *const _,
590 Some(transmute::<_, unsafe extern "C" fn()>(
591 notify_enabled_trampoline::<F> as *const (),
592 )),
593 Box_::into_raw(f),
594 )
595 }
596 }
597
598 pub fn connect_property_n_axes_notify<F: Fn(&InputDevice) + 'static>(
599 &self,
600 f: F,
601 ) -> SignalHandlerId {
602 unsafe extern "C" fn notify_n_axes_trampoline<F: Fn(&InputDevice) + 'static>(
603 this: *mut ffi::ClutterInputDevice,
604 _param_spec: glib_sys::gpointer,
605 f: glib_sys::gpointer,
606 ) {
607 let f: &F = &*(f as *const F);
608 f(&from_glib_borrow(this))
609 }
610 unsafe {
611 let f: Box_<F> = Box_::new(f);
612 connect_raw(
613 self.as_ptr() as *mut _,
614 b"notify::n-axes\0".as_ptr() as *const _,
615 Some(transmute::<_, unsafe extern "C" fn()>(
616 notify_n_axes_trampoline::<F> as *const (),
617 )),
618 Box_::into_raw(f),
619 )
620 }
621 }
622}
623
624impl fmt::Display for InputDevice {
625 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
626 write!(f, "InputDevice")
627 }
628}