use crate::{AxisUse, Device, Display, EventType, ModifierType, Seat, Surface, TimeCoord};
use glib::translate::*;
use glib::{StaticType, Type};
use std::fmt;
use std::mem;
glib::wrapper! {
#[doc(alias = "GdkEvent")]
pub struct Event(Shared<ffi::GdkEvent>);
match fn {
ref => |ptr| ffi::gdk_event_ref(ptr),
unref => |ptr| ffi::gdk_event_unref(ptr),
}
}
pub const NONE_EVENT: Option<&Event> = None;
impl StaticType for Event {
#[doc(alias = "gdk_event_get_type")]
fn static_type() -> Type {
unsafe { from_glib(ffi::gdk_event_get_type()) }
}
}
impl Event {
pub fn downcast<T: EventKind>(self) -> Result<T, Event> {
unsafe {
if T::event_types().contains(&self.event_type()) {
Ok(from_glib_full(self.to_glib_full()))
} else {
Err(self)
}
}
}
pub fn downcast_ref<T: EventKind>(&self) -> Option<&T> {
unsafe {
if T::event_types().contains(&self.event_type()) {
Some(&*(self as *const Event as *const T))
} else {
None
}
}
}
#[doc(alias = "gdk_events_get_angle")]
#[doc(alias = "get_angle")]
pub fn angle<P: AsRef<Event>>(&self, event: P) -> Option<f64> {
skip_assert_initialized!();
unsafe {
let mut angle = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gdk_events_get_angle(
self.to_glib_none().0,
event.as_ref().to_glib_none().0,
angle.as_mut_ptr(),
));
if ret {
let angle = angle.assume_init();
Some(angle)
} else {
None
}
}
}
#[doc(alias = "gdk_events_get_center")]
#[doc(alias = "get_center")]
pub fn center<P: AsRef<Event>>(&self, event: P) -> Option<(f64, f64)> {
skip_assert_initialized!();
unsafe {
let mut x = mem::MaybeUninit::uninit();
let mut y = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gdk_events_get_center(
self.to_glib_none().0,
event.as_ref().to_glib_none().0,
x.as_mut_ptr(),
y.as_mut_ptr(),
));
if ret {
let x = x.assume_init();
let y = y.assume_init();
Some((x, y))
} else {
None
}
}
}
#[doc(alias = "gdk_events_get_distance")]
#[doc(alias = "get_distance")]
pub fn distance<P: AsRef<Event>>(&self, event: P) -> Option<f64> {
skip_assert_initialized!();
unsafe {
let mut distance = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gdk_events_get_distance(
self.to_glib_none().0,
event.as_ref().to_glib_none().0,
distance.as_mut_ptr(),
));
if ret {
let distance = distance.assume_init();
Some(distance)
} else {
None
}
}
}
#[doc(alias = "gdk_event_get_axis")]
#[doc(alias = "get_axis")]
pub fn axis(&self, axis_use: AxisUse) -> Option<f64> {
unsafe {
let mut value = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gdk_event_get_axis(
self.to_glib_none().0,
axis_use.into_glib(),
value.as_mut_ptr(),
));
if ret {
let value = value.assume_init();
Some(value)
} else {
None
}
}
}
#[doc(alias = "gdk_event_get_device")]
#[doc(alias = "get_device")]
pub fn device(&self) -> Option<Device> {
unsafe { from_glib_none(ffi::gdk_event_get_device(self.to_glib_none().0)) }
}
#[doc(alias = "gdk_event_get_display")]
#[doc(alias = "get_display")]
pub fn display(&self) -> Option<Display> {
unsafe { from_glib_none(ffi::gdk_event_get_display(self.to_glib_none().0)) }
}
#[doc(alias = "gdk_event_get_event_type")]
#[doc(alias = "get_event_type")]
pub fn event_type(&self) -> EventType {
unsafe { from_glib(ffi::gdk_event_get_event_type(self.to_glib_none().0)) }
}
#[doc(alias = "gdk_event_get_history")]
#[doc(alias = "get_history")]
pub fn history(&self) -> Vec<TimeCoord> {
unsafe {
let mut out_n_coords = mem::MaybeUninit::uninit();
let ret = FromGlibContainer::from_glib_container_num(
ffi::gdk_event_get_history(self.to_glib_none().0, out_n_coords.as_mut_ptr()),
out_n_coords.assume_init() as usize,
);
ret
}
}
#[doc(alias = "gdk_event_get_modifier_state")]
#[doc(alias = "get_modifier_state")]
pub fn modifier_state(&self) -> ModifierType {
unsafe { from_glib(ffi::gdk_event_get_modifier_state(self.to_glib_none().0)) }
}
#[doc(alias = "gdk_event_get_pointer_emulated")]
#[doc(alias = "get_pointer_emulated")]
pub fn is_pointer_emulated(&self) -> bool {
unsafe { from_glib(ffi::gdk_event_get_pointer_emulated(self.to_glib_none().0)) }
}
#[doc(alias = "gdk_event_get_position")]
#[doc(alias = "get_position")]
pub fn position(&self) -> Option<(f64, f64)> {
unsafe {
let mut x = mem::MaybeUninit::uninit();
let mut y = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gdk_event_get_position(
self.to_glib_none().0,
x.as_mut_ptr(),
y.as_mut_ptr(),
));
if ret {
let x = x.assume_init();
let y = y.assume_init();
Some((x, y))
} else {
None
}
}
}
#[doc(alias = "gdk_event_get_seat")]
#[doc(alias = "get_seat")]
pub fn seat(&self) -> Option<Seat> {
unsafe { from_glib_none(ffi::gdk_event_get_seat(self.to_glib_none().0)) }
}
#[doc(alias = "gdk_event_get_surface")]
#[doc(alias = "get_surface")]
pub fn surface(&self) -> Option<Surface> {
unsafe { from_glib_none(ffi::gdk_event_get_surface(self.to_glib_none().0)) }
}
#[doc(alias = "gdk_event_get_time")]
#[doc(alias = "get_time")]
pub fn time(&self) -> u32 {
unsafe { ffi::gdk_event_get_time(self.to_glib_none().0) }
}
#[doc(alias = "gdk_event_triggers_context_menu")]
pub fn triggers_context_menu(&self) -> bool {
unsafe { from_glib(ffi::gdk_event_triggers_context_menu(self.to_glib_none().0)) }
}
}
impl fmt::Display for Event {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Event")
.field("event_type", &self.event_type())
.field("history", &self.history())
.field("modifier_state", &self.modifier_state())
.field("pointer_emulated", &self.is_pointer_emulated())
.field("position", &self.position())
.field("time", &self.time())
.field("triggers_context_menu", &self.triggers_context_menu())
.finish()
}
}
impl fmt::Debug for Event {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_fmt(format_args!("{}", self))
}
}
#[doc(hidden)]
impl AsRef<Event> for Event {
fn as_ref(&self) -> &Self {
self
}
}
pub unsafe trait EventKind:
StaticType + FromGlibPtrFull<*mut ffi::GdkEvent> + 'static
{
fn event_types() -> &'static [EventType];
}
macro_rules! define_event {
($rust_type:ident, $ffi_type:path, $ffi_type_path:path, $event_event_types:expr) => {
impl glib::StaticType for $rust_type {
fn static_type() -> glib::Type {
unsafe { from_glib($ffi_type_path()) }
}
}
unsafe impl crate::event::EventKind for $rust_type {
fn event_types() -> &'static [crate::EventType] {
$event_event_types
}
}
impl std::ops::Deref for $rust_type {
type Target = crate::Event;
fn deref(&self) -> &Self::Target {
unsafe { &*(self as *const $rust_type as *const crate::Event) }
}
}
impl AsRef<crate::Event> for $rust_type {
fn as_ref(&self) -> &crate::Event {
self.upcast_ref()
}
}
#[doc(hidden)]
impl glib::translate::FromGlibPtrFull<*mut ffi::GdkEvent> for $rust_type {
unsafe fn from_glib_full(ptr: *mut ffi::GdkEvent) -> Self {
glib::translate::FromGlibPtrFull::from_glib_full(ptr as *mut $ffi_type)
}
}
impl $rust_type {
pub fn upcast(self) -> crate::Event {
unsafe { std::mem::transmute(self) }
}
pub fn upcast_ref(&self) -> &crate::Event {
&*self
}
}
impl std::fmt::Debug for $rust_type {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.write_fmt(format_args!("{}", self))
}
}
};
}