video: update navigation API for recent changes

Add support for the new send_event_simple and event_get/set_coordinates
functions, as well as touchscreen events and modifier state. See:
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1633
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2010
This commit is contained in:
Vivienne Watermeier 2022-03-15 14:18:08 +01:00 committed by Sebastian Dröge
parent 23e4d1efa8
commit 1274a59472
9 changed files with 674 additions and 358 deletions

View file

@ -1,135 +0,0 @@
From e2873bc614e50d19f1b8aa939514c83933b10136 Mon Sep 17 00:00:00 2001
From: Eli Schwartz <eschwartz@archlinux.org>
Date: Thu, 10 Mar 2022 00:08:36 -0500
Subject: [PATCH 1/2] meson: use proper handling of wayland-protocols
dependency
Ensure that resolution of the subproject occurs via the dependency
interface, not the "poke at subprojects manually" interface, and make
that actually work via --wrap-mode=forcefallback.
There's no need to mark it as not-required and then manually invoke
subproject(), since fallback should work correctly and it is always
needed.
However, if fallback was performed (or forced) it would error out since
get_variable() was instructed to only use pkg-config while the relevant
variable was exported by the subproject as an internal fallback
dependency.
---
meson.build | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/meson.build b/meson.build
index 63b4d73bfe..17fdb1cfe7 100644
--- a/meson.build
+++ b/meson.build
@@ -517,15 +517,11 @@ if wayland_enabled
wlclientdep = dependency('wayland-client', version: wayland_req,
fallback: 'wayland',
default_options: ['documentation=false'])
- wlprotocolsdep = dependency('wayland-protocols', version: wayland_proto_req, required: false)
+ wlprotocolsdep = dependency('wayland-protocols', version: wayland_proto_req)
wlegldep = dependency('wayland-egl',
fallback: 'wayland')
- if not wlprotocolsdep.found()
- wlproto_dir = subproject('wayland-protocols').get_variable('wayland_protocols_srcdir')
- else
- wlproto_dir = wlprotocolsdep.get_variable(pkgconfig: 'pkgdatadir')
- endif
+ wlproto_dir = wlprotocolsdep.get_variable('pkgdatadir')
wayland_pkgs = [
'wayland-client @0@'.format(wayland_req),
--
GitLab
From dc875b6af9311f3b5275961618ad867bf1f57a1e Mon Sep 17 00:00:00 2001
From: Jordan Petridis <jordan@centricular.com>
Date: Wed, 16 Mar 2022 09:53:16 +0200
Subject: [PATCH 2/2] meson: switch some .wrap files to stable branches
To avoid random failures if one of the projects starts
depending on new things or has incompatible changes.
---
subprojects/glib.wrap | 2 +-
subprojects/graphene.wrap | 2 +-
subprojects/libepoxy.wrap | 2 +-
subprojects/sysprof.wrap | 2 +-
subprojects/wayland-protocols.wrap | 2 +-
subprojects/wayland.wrap | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/subprojects/glib.wrap b/subprojects/glib.wrap
index c785910d9f..ec5febde86 100644
--- a/subprojects/glib.wrap
+++ b/subprojects/glib.wrap
@@ -2,5 +2,5 @@
directory=glib
url=https://gitlab.gnome.org/GNOME/glib.git
push-url=ssh://git@gitlab.gnome.org:GNOME/glib.git
-revision=main
+revision=glib-2-68
depth=1
diff --git a/subprojects/graphene.wrap b/subprojects/graphene.wrap
index 902095dbd7..d9503ab978 100644
--- a/subprojects/graphene.wrap
+++ b/subprojects/graphene.wrap
@@ -1,5 +1,5 @@
[wrap-git]
directory=graphene
url=https://github.com/ebassi/graphene.git
-revision=master
+revision=1.10.6
depth=1
diff --git a/subprojects/libepoxy.wrap b/subprojects/libepoxy.wrap
index fc5147a22b..0ab256ef26 100644
--- a/subprojects/libepoxy.wrap
+++ b/subprojects/libepoxy.wrap
@@ -1,5 +1,5 @@
[wrap-git]
directory=libepoxy
url=https://github.com/anholt/libepoxy.git
-revision=master
+revision=1.5.9
depth=1
diff --git a/subprojects/sysprof.wrap b/subprojects/sysprof.wrap
index 99aa36ce87..41fb7c6ee2 100644
--- a/subprojects/sysprof.wrap
+++ b/subprojects/sysprof.wrap
@@ -1,5 +1,5 @@
[wrap-git]
directory=sysprof
url=https://gitlab.gnome.org/GNOME/sysprof.git
-revision=master
+revision=sysprof-3-38
depth=1
diff --git a/subprojects/wayland-protocols.wrap b/subprojects/wayland-protocols.wrap
index 065651db63..5361f0c540 100644
--- a/subprojects/wayland-protocols.wrap
+++ b/subprojects/wayland-protocols.wrap
@@ -1,5 +1,5 @@
[wrap-git]
directory=wayland-protocols
url=https://gitlab.freedesktop.org/wayland/wayland-protocols.git
-revision=main
+revision=1.23
depth=1
diff --git a/subprojects/wayland.wrap b/subprojects/wayland.wrap
index 5be67bf491..bdb12d3aa7 100644
--- a/subprojects/wayland.wrap
+++ b/subprojects/wayland.wrap
@@ -1,7 +1,7 @@
[wrap-git]
directory=wayland
url=https://gitlab.freedesktop.org/wayland/wayland.git
-revision=main
+revision=1.20.0
depth=1
[provide]
--
GitLab

View file

@ -4,7 +4,6 @@ BRANCH=gtk-4-6
git clone https://gitlab.gnome.org/GNOME/gtk.git --branch $BRANCH --depth=1 git clone https://gitlab.gnome.org/GNOME/gtk.git --branch $BRANCH --depth=1
cd gtk cd gtk
git apply ../ci/4580.patch
meson build -D prefix=/usr/local -Dbuild-tests=false meson build -D prefix=/usr/local -Dbuild-tests=false
ninja -C build ninja -C build
ninja -C build install ninja -C build install

View file

@ -112,10 +112,6 @@ status = "generate"
name = "event_parse_key_event" name = "event_parse_key_event"
manual = true manual = true
[[object.function]]
name = "send_event"
manual = true
[[object.function]] [[object.function]]
name = "event_parse_mouse_button_event" name = "event_parse_mouse_button_event"
manual = true manual = true
@ -129,21 +125,21 @@ status = "generate"
manual = true manual = true
[[object.function]] [[object.function]]
name = "message_parse_event" name = "event_parse_touch_event"
manual = true manual = true
[[object.function]] [[object.function]]
name = "message_get_type" name = "event_parse_touch_up_event"
manual = true
[[object.function]]
name = "message_new_event"
manual = true manual = true
[[object.function]] [[object.function]]
name = "event_parse_mouse_scroll_event" name = "event_parse_mouse_scroll_event"
manual = true manual = true
[[object.function]]
name = "event_parse_modifier_state"
manual = true
[[object.function]] [[object.function]]
name = "event_get_type" name = "event_get_type"
manual = true manual = true
@ -176,6 +172,68 @@ status = "generate"
name = "event_new_mouse_scroll" name = "event_new_mouse_scroll"
manual = true manual = true
[[object.function]]
name = "event_new_touch_down"
manual = true
[[object.function]]
name = "event_new_touch_motion"
manual = true
[[object.function]]
name = "event_new_touch_up"
manual = true
[[object.function]]
name = "event_new_touch_frame"
manual = true
[[object.function]]
name = "event_new_touch_cancel"
manual = true
[[object.function]]
name = "event_get_coordinates"
manual = true
[[object.function]]
name = "event_set_coordinates"
manual = true
[[object.function]]
name = "send_event"
manual = true
[[object.function]]
name = "send_event_simple"
manual = true
[[object.function]]
name = "send_key_event"
[[object.function]]
name = "send_mouse_event"
[[object.function]]
name = "send_mouse_scroll_event"
[[object.function]]
name = "send_command"
[[object.function]]
name = "message_parse_event"
manual = true
[[object.function]]
name = "message_get_type"
manual = true
[[object.function]]
name = "message_new_event"
manual = true
[[object.function]] [[object.function]]
name = "message_new_commands_changed" name = "message_new_commands_changed"
ignore = true ignore = true
@ -239,6 +297,31 @@ status = "generate"
[[object.member]] [[object.member]]
name = "mouse_scroll" name = "mouse_scroll"
version = "1.18" version = "1.18"
[[object.member]]
name = "touch_down"
version = "1.22"
[[object.member]]
name = "touch_motion"
version = "1.22"
[[object.member]]
name = "touch_up"
version = "1.22"
[[object.member]]
name = "touch_frame"
version = "1.22"
[[object.member]]
name = "touch_cancel"
version = "1.22"
[[object]]
name = "GstVideo.NavigationModifierType"
status = "generate"
[[object.member]]
name = "none"
ignore = true
[[object.member]]
name = "mask"
ignore = true
[[object]] [[object]]
name = "GstVideo.VideoAggregatorConvertPad" name = "GstVideo.VideoAggregatorConvertPad"

View file

@ -11,6 +11,100 @@ use glib::StaticType;
use glib::Type; use glib::Type;
use std::fmt; use std::fmt;
#[cfg(any(feature = "v1_22", feature = "dox"))]
bitflags! {
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "GstNavigationModifierType")]
pub struct NavigationModifierType: u32 {
#[doc(alias = "GST_NAVIGATION_MODIFIER_SHIFT_MASK")]
const SHIFT_MASK = ffi::GST_NAVIGATION_MODIFIER_SHIFT_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_LOCK_MASK")]
const LOCK_MASK = ffi::GST_NAVIGATION_MODIFIER_LOCK_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_CONTROL_MASK")]
const CONTROL_MASK = ffi::GST_NAVIGATION_MODIFIER_CONTROL_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_ALT_MASK")]
const ALT_MASK = ffi::GST_NAVIGATION_MODIFIER_ALT_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_BUTTON1_MASK")]
const BUTTON1_MASK = ffi::GST_NAVIGATION_MODIFIER_BUTTON1_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_BUTTON2_MASK")]
const BUTTON2_MASK = ffi::GST_NAVIGATION_MODIFIER_BUTTON2_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_BUTTON3_MASK")]
const BUTTON3_MASK = ffi::GST_NAVIGATION_MODIFIER_BUTTON3_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_BUTTON4_MASK")]
const BUTTON4_MASK = ffi::GST_NAVIGATION_MODIFIER_BUTTON4_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_BUTTON5_MASK")]
const BUTTON5_MASK = ffi::GST_NAVIGATION_MODIFIER_BUTTON5_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_SUPER_MASK")]
const SUPER_MASK = ffi::GST_NAVIGATION_MODIFIER_SUPER_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_HYPER_MASK")]
const HYPER_MASK = ffi::GST_NAVIGATION_MODIFIER_HYPER_MASK as u32;
#[doc(alias = "GST_NAVIGATION_MODIFIER_META_MASK")]
const META_MASK = ffi::GST_NAVIGATION_MODIFIER_META_MASK as u32;
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(hidden)]
impl IntoGlib for NavigationModifierType {
type GlibType = ffi::GstNavigationModifierType;
fn into_glib(self) -> ffi::GstNavigationModifierType {
self.bits()
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(hidden)]
impl FromGlib<ffi::GstNavigationModifierType> for NavigationModifierType {
unsafe fn from_glib(value: ffi::GstNavigationModifierType) -> Self {
skip_assert_initialized!();
Self::from_bits_truncate(value)
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
impl StaticType for NavigationModifierType {
fn static_type() -> Type {
unsafe { from_glib(ffi::gst_navigation_modifier_type_get_type()) }
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
impl glib::value::ValueType for NavigationModifierType {
type Type = Self;
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
unsafe impl<'a> FromValue<'a> for NavigationModifierType {
type Checker = glib::value::GenericValueTypeChecker<Self>;
unsafe fn from_value(value: &'a glib::Value) -> Self {
skip_assert_initialized!();
from_glib(glib::gobject_ffi::g_value_get_flags(value.to_glib_none().0))
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
impl ToValue for NavigationModifierType {
fn to_value(&self) -> glib::Value {
let mut value = glib::Value::for_value_type::<Self>();
unsafe {
glib::gobject_ffi::g_value_set_flags(value.to_glib_none_mut().0, self.into_glib());
}
value
}
fn value_type(&self) -> glib::Type {
Self::static_type()
}
}
bitflags! { bitflags! {
#[doc(alias = "GstVideoBufferFlags")] #[doc(alias = "GstVideoBufferFlags")]
pub struct VideoBufferFlags: u32 { pub struct VideoBufferFlags: u32 {

View file

@ -99,6 +99,9 @@ pub use self::enums::VideoTileMode;
pub use self::enums::VideoTransferFunction; pub use self::enums::VideoTransferFunction;
mod flags; mod flags;
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
pub use self::flags::NavigationModifierType;
pub use self::flags::VideoBufferFlags; pub use self::flags::VideoBufferFlags;
pub use self::flags::VideoChromaSite; pub use self::flags::VideoChromaSite;
pub use self::flags::VideoCodecFrameFlags; pub use self::flags::VideoCodecFrameFlags;

View file

@ -6,9 +6,6 @@
use crate::NavigationCommand; use crate::NavigationCommand;
use glib::object::IsA; use glib::object::IsA;
use glib::translate::*; use glib::translate::*;
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
use std::mem;
glib::wrapper! { glib::wrapper! {
#[doc(alias = "GstNavigation")] #[doc(alias = "GstNavigation")]
@ -22,140 +19,6 @@ glib::wrapper! {
impl Navigation { impl Navigation {
pub const NONE: Option<&'static Navigation> = None; pub const NONE: Option<&'static Navigation> = None;
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_event_get_coordinates")]
pub fn event_get_coordinates(event: &gst::Event) -> Option<(f64, f64)> {
assert_initialized_main_thread!();
unsafe {
let mut x = mem::MaybeUninit::uninit();
let mut y = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gst_navigation_event_get_coordinates(
event.to_glib_none().0,
x.as_mut_ptr(),
y.as_mut_ptr(),
));
let x = x.assume_init();
let y = y.assume_init();
if ret {
Some((x, y))
} else {
None
}
}
}
//#[cfg(any(feature = "v1_22", feature = "dox"))]
//#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
//#[doc(alias = "gst_navigation_event_new_touch_cancel")]
//pub fn event_new_touch_cancel(state: /*Ignored*/NavigationModifierType) -> Option<gst::Event> {
// unsafe { TODO: call ffi:gst_navigation_event_new_touch_cancel() }
//}
//#[cfg(any(feature = "v1_22", feature = "dox"))]
//#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
//#[doc(alias = "gst_navigation_event_new_touch_down")]
//pub fn event_new_touch_down(identifier: u32, x: f64, y: f64, pressure: f64, state: /*Ignored*/NavigationModifierType) -> Option<gst::Event> {
// unsafe { TODO: call ffi:gst_navigation_event_new_touch_down() }
//}
//#[cfg(any(feature = "v1_22", feature = "dox"))]
//#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
//#[doc(alias = "gst_navigation_event_new_touch_frame")]
//pub fn event_new_touch_frame(state: /*Ignored*/NavigationModifierType) -> Option<gst::Event> {
// unsafe { TODO: call ffi:gst_navigation_event_new_touch_frame() }
//}
//#[cfg(any(feature = "v1_22", feature = "dox"))]
//#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
//#[doc(alias = "gst_navigation_event_new_touch_motion")]
//pub fn event_new_touch_motion(identifier: u32, x: f64, y: f64, pressure: f64, state: /*Ignored*/NavigationModifierType) -> Option<gst::Event> {
// unsafe { TODO: call ffi:gst_navigation_event_new_touch_motion() }
//}
//#[cfg(any(feature = "v1_22", feature = "dox"))]
//#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
//#[doc(alias = "gst_navigation_event_new_touch_up")]
//pub fn event_new_touch_up(identifier: u32, x: f64, y: f64, state: /*Ignored*/NavigationModifierType) -> Option<gst::Event> {
// unsafe { TODO: call ffi:gst_navigation_event_new_touch_up() }
//}
//#[cfg(any(feature = "v1_22", feature = "dox"))]
//#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
//#[doc(alias = "gst_navigation_event_parse_modifier_state")]
//pub fn event_parse_modifier_state(event: &gst::Event, state: /*Ignored*/NavigationModifierType) -> bool {
// unsafe { TODO: call ffi:gst_navigation_event_parse_modifier_state() }
//}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_event_parse_touch_event")]
pub fn event_parse_touch_event(event: &gst::Event) -> Option<(u32, f64, f64, f64)> {
assert_initialized_main_thread!();
unsafe {
let mut identifier = mem::MaybeUninit::uninit();
let mut x = mem::MaybeUninit::uninit();
let mut y = mem::MaybeUninit::uninit();
let mut pressure = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gst_navigation_event_parse_touch_event(
event.to_glib_none().0,
identifier.as_mut_ptr(),
x.as_mut_ptr(),
y.as_mut_ptr(),
pressure.as_mut_ptr(),
));
let identifier = identifier.assume_init();
let x = x.assume_init();
let y = y.assume_init();
let pressure = pressure.assume_init();
if ret {
Some((identifier, x, y, pressure))
} else {
None
}
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_event_parse_touch_up_event")]
pub fn event_parse_touch_up_event(event: &gst::Event) -> Option<(u32, f64, f64)> {
assert_initialized_main_thread!();
unsafe {
let mut identifier = mem::MaybeUninit::uninit();
let mut x = mem::MaybeUninit::uninit();
let mut y = mem::MaybeUninit::uninit();
let ret = from_glib(ffi::gst_navigation_event_parse_touch_up_event(
event.to_glib_none().0,
identifier.as_mut_ptr(),
x.as_mut_ptr(),
y.as_mut_ptr(),
));
let identifier = identifier.assume_init();
let x = x.assume_init();
let y = y.assume_init();
if ret {
Some((identifier, x, y))
} else {
None
}
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_event_set_coordinates")]
pub fn event_set_coordinates(event: &gst::Event, x: f64, y: f64) -> bool {
assert_initialized_main_thread!();
unsafe {
from_glib(ffi::gst_navigation_event_set_coordinates(
event.to_glib_none().0,
x,
y,
))
}
}
//#[doc(alias = "gst_navigation_query_set_commands")] //#[doc(alias = "gst_navigation_query_set_commands")]
//pub fn query_set_commands(query: &gst::Query, n_cmds: i32, : /*Unknown conversion*//*Unimplemented*/Fundamental: VarArgs) { //pub fn query_set_commands(query: &gst::Query, n_cmds: i32, : /*Unknown conversion*//*Unimplemented*/Fundamental: VarArgs) {
// unsafe { TODO: call ffi:gst_navigation_query_set_commands() } // unsafe { TODO: call ffi:gst_navigation_query_set_commands() }
@ -174,11 +37,6 @@ pub trait NavigationExt: 'static {
#[doc(alias = "gst_navigation_send_command")] #[doc(alias = "gst_navigation_send_command")]
fn send_command(&self, command: NavigationCommand); fn send_command(&self, command: NavigationCommand);
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_send_event_simple")]
fn send_event_simple(&self, event: &gst::Event);
#[doc(alias = "gst_navigation_send_key_event")] #[doc(alias = "gst_navigation_send_key_event")]
fn send_key_event(&self, event: &str, key: &str); fn send_key_event(&self, event: &str, key: &str);
@ -198,17 +56,6 @@ impl<O: IsA<Navigation>> NavigationExt for O {
} }
} }
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
fn send_event_simple(&self, event: &gst::Event) {
unsafe {
ffi::gst_navigation_send_event_simple(
self.as_ref().to_glib_none().0,
event.to_glib_full(),
);
}
}
fn send_key_event(&self, event: &str, key: &str) { fn send_key_event(&self, event: &str, key: &str) {
unsafe { unsafe {
ffi::gst_navigation_send_key_event( ffi::gst_navigation_send_key_event(

View file

@ -5,6 +5,11 @@ use glib::translate::ToGlibPtr;
pub trait NavigationExtManual: 'static { pub trait NavigationExtManual: 'static {
#[doc(alias = "gst_navigation_send_event")] #[doc(alias = "gst_navigation_send_event")]
fn send_event(&self, structure: gst::Structure); fn send_event(&self, structure: gst::Structure);
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_send_event_simple")]
fn send_event_simple(&self, event: gst::Event);
} }
impl<O: IsA<Navigation>> NavigationExtManual for O { impl<O: IsA<Navigation>> NavigationExtManual for O {
@ -13,4 +18,12 @@ impl<O: IsA<Navigation>> NavigationExtManual for O {
ffi::gst_navigation_send_event(self.as_ref().to_glib_none().0, structure.into_ptr()); ffi::gst_navigation_send_event(self.as_ref().to_glib_none().0, structure.into_ptr());
} }
} }
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
fn send_event_simple(&self, event: gst::Event) {
unsafe {
ffi::gst_navigation_send_event_simple(self.as_ref().to_glib_none().0, event.into_ptr());
}
}
} }

View file

@ -5,16 +5,30 @@ use glib::translate::*;
use glib::subclass::prelude::*; use glib::subclass::prelude::*;
use gst::ffi::GstStructure;
use crate::Navigation; use crate::Navigation;
pub trait NavigationImpl: ObjectImpl { pub trait NavigationImpl: ObjectImpl {
fn send_event(&self, nav: &Self::Type, structure: gst::Structure); fn send_event(&self, nav: &Self::Type, structure: gst::Structure);
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
fn send_event_simple(&self, nav: &Self::Type, event: gst::Event) {
if let Some(structure) = event.structure() {
self.send_event(nav, structure.to_owned());
}
}
} }
pub trait NavigationImplExt: ObjectSubclass { pub trait NavigationImplExt: ObjectSubclass {
fn parent_send_event(&self, nav: &Self::Type, structure: gst::Structure); fn parent_send_event(&self, nav: &Self::Type, structure: gst::Structure);
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
fn parent_send_event_simple(&self, nav: &Self::Type, event: gst::Event) {
if let Some(structure) = event.structure() {
self.parent_send_event(nav, structure.to_owned());
}
}
} }
impl<T: NavigationImpl> NavigationImplExt for T { impl<T: NavigationImpl> NavigationImplExt for T {
@ -35,19 +49,49 @@ impl<T: NavigationImpl> NavigationImplExt for T {
); );
} }
} }
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
fn parent_send_event_simple(&self, nav: &Self::Type, event: gst::Event) {
unsafe {
let type_data = Self::type_data();
let parent_iface = type_data.as_ref().parent_interface::<Navigation>()
as *const ffi::GstNavigationInterface;
let func = match (*parent_iface).send_event_simple {
Some(func) => func,
None => return,
};
func(
nav.unsafe_cast_ref::<Navigation>().to_glib_none().0,
event.into_ptr(),
);
}
}
} }
unsafe impl<T: NavigationImpl> IsImplementable<T> for Navigation { unsafe impl<T: NavigationImpl> IsImplementable<T> for Navigation {
#[cfg(not(feature = "v1_22"))]
fn interface_init(iface: &mut glib::Interface<Self>) { fn interface_init(iface: &mut glib::Interface<Self>) {
let iface = iface.as_mut(); let iface = iface.as_mut();
iface.send_event = Some(navigation_send_event::<T>); iface.send_event = Some(navigation_send_event::<T>);
} }
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
fn interface_init(iface: &mut glib::Interface<Self>) {
let iface = iface.as_mut();
iface.send_event = Some(navigation_send_event::<T>);
iface.send_event_simple = Some(navigation_send_event_simple::<T>);
}
} }
unsafe extern "C" fn navigation_send_event<T: NavigationImpl>( unsafe extern "C" fn navigation_send_event<T: NavigationImpl>(
nav: *mut ffi::GstNavigation, nav: *mut ffi::GstNavigation,
structure: *mut GstStructure, structure: *mut gst::ffi::GstStructure,
) { ) {
let instance = &*(nav as *mut T::Instance); let instance = &*(nav as *mut T::Instance);
let imp = instance.imp(); let imp = instance.imp();
@ -57,3 +101,18 @@ unsafe extern "C" fn navigation_send_event<T: NavigationImpl>(
from_glib_full(structure), from_glib_full(structure),
); );
} }
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
unsafe extern "C" fn navigation_send_event_simple<T: NavigationImpl>(
nav: *mut ffi::GstNavigation,
event: *mut gst::ffi::GstEvent,
) {
let instance = &*(nav as *mut T::Instance);
let imp = instance.imp();
imp.send_event_simple(
from_glib_borrow::<_, Navigation>(nav).unsafe_cast_ref(),
from_glib_full(event),
);
}

View file

@ -2,8 +2,13 @@
use crate::{NavigationCommand, NavigationEventType}; use crate::{NavigationCommand, NavigationEventType};
use glib::translate::{from_glib, from_glib_full, IntoGlib}; use glib::translate::{from_glib, from_glib_full, IntoGlib};
use glib::ToSendValue; use glib::ToSendValue;
use gst::EventType;
use std::mem; use std::mem;
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
use crate::NavigationModifierType;
// FIXME: Copy from gstreamer/src/event.rs // FIXME: Copy from gstreamer/src/event.rs
macro_rules! event_builder_generic_impl { macro_rules! event_builder_generic_impl {
($new_fn:expr) => { ($new_fn:expr) => {
@ -357,26 +362,44 @@ const NAVIGATION_EVENT_NAME: &str = "application/x-gst-navigation";
pub enum NavigationEvent { pub enum NavigationEvent {
KeyPress { KeyPress {
key: String, key: String,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType,
}, },
KeyRelease { KeyRelease {
key: String, key: String,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType,
}, },
MouseMove { MouseMove {
x: f64, x: f64,
y: f64, y: f64,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType,
}, },
MouseButtonPress { MouseButtonPress {
button: i32, button: i32,
x: f64, x: f64,
y: f64, y: f64,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType,
}, },
MouseButtonRelease { MouseButtonRelease {
button: i32, button: i32,
x: f64, x: f64,
y: f64, y: f64,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType,
}, },
Command { Command {
command: NavigationCommand, command: NavigationCommand,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType,
}, },
#[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
@ -385,6 +408,45 @@ pub enum NavigationEvent {
y: f64, y: f64,
delta_x: f64, delta_x: f64,
delta_y: f64, delta_y: f64,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType,
},
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
TouchDown {
identifier: u32,
x: f64,
y: f64,
pressure: f64,
modifier_state: NavigationModifierType,
},
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
TouchMotion {
identifier: u32,
x: f64,
y: f64,
pressure: f64,
modifier_state: NavigationModifierType,
},
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
TouchUp {
identifier: u32,
x: f64,
y: f64,
modifier_state: NavigationModifierType,
},
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
TouchFrame {
modifier_state: NavigationModifierType,
},
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
TouchCancel {
modifier_state: NavigationModifierType,
}, },
} }
@ -394,6 +456,9 @@ impl NavigationEvent {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
Self::KeyPress { Self::KeyPress {
key: key.to_string(), key: key.to_string(),
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
} }
} }
@ -402,25 +467,48 @@ impl NavigationEvent {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
Self::KeyRelease { Self::KeyRelease {
key: key.to_string(), key: key.to_string(),
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
} }
} }
#[doc(alias = "gst_navigation_event_new_mouse_move")] #[doc(alias = "gst_navigation_event_new_mouse_move")]
pub fn new_mouse_move(x: f64, y: f64) -> NavigationEvent { pub fn new_mouse_move(x: f64, y: f64) -> NavigationEvent {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
Self::MouseMove { x, y } Self::MouseMove {
x,
y,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
}
} }
#[doc(alias = "gst_navigation_event_new_mouse_button_press")] #[doc(alias = "gst_navigation_event_new_mouse_button_press")]
pub fn new_mouse_button_press(button: i32, x: f64, y: f64) -> NavigationEvent { pub fn new_mouse_button_press(button: i32, x: f64, y: f64) -> NavigationEvent {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
Self::MouseButtonPress { button, x, y } Self::MouseButtonPress {
button,
x,
y,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
}
} }
#[doc(alias = "gst_navigation_event_new_mouse_button_release")] #[doc(alias = "gst_navigation_event_new_mouse_button_release")]
pub fn new_mouse_button_release(button: i32, x: f64, y: f64) -> NavigationEvent { pub fn new_mouse_button_release(button: i32, x: f64, y: f64) -> NavigationEvent {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
Self::MouseButtonRelease { button, x, y } Self::MouseButtonRelease {
button,
x,
y,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
}
} }
#[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg(any(feature = "v1_18", feature = "dox"))]
@ -433,13 +521,92 @@ impl NavigationEvent {
y, y,
delta_x, delta_x,
delta_y, delta_y,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
} }
} }
#[doc(alias = "gst_navigation_event_new_command")] #[doc(alias = "gst_navigation_event_new_command")]
pub fn new_command(command: NavigationCommand) -> NavigationEvent { pub fn new_command(command: NavigationCommand) -> NavigationEvent {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
Self::Command { command } Self::Command {
command,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_event_new_touch_down")]
pub fn new_touch_down(identifier: u32, x: f64, y: f64, pressure: f64) -> NavigationEvent {
assert_initialized_main_thread!();
Self::TouchDown {
identifier,
x,
y,
pressure,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_event_new_touch_motion")]
pub fn new_touch_motion(identifier: u32, x: f64, y: f64, pressure: f64) -> NavigationEvent {
assert_initialized_main_thread!();
Self::TouchMotion {
identifier,
x,
y,
pressure,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_event_new_touch_up")]
pub fn new_touch_up(identifier: u32, x: f64, y: f64) -> NavigationEvent {
assert_initialized_main_thread!();
Self::TouchUp {
identifier,
x,
y,
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_event_new_touch_frame")]
pub fn new_touch_frame() -> NavigationEvent {
assert_initialized_main_thread!();
Self::TouchFrame {
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
}
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
#[doc(alias = "gst_navigation_event_new_touch_cancel")]
pub fn new_touch_cancel() -> NavigationEvent {
assert_initialized_main_thread!();
Self::TouchCancel {
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state: NavigationModifierType::empty(),
}
} }
#[doc(alias = "gst_navigation_event_get_type")] #[doc(alias = "gst_navigation_event_get_type")]
@ -448,107 +615,196 @@ impl NavigationEvent {
unsafe { from_glib(ffi::gst_navigation_event_get_type(event.as_mut_ptr())) } unsafe { from_glib(ffi::gst_navigation_event_get_type(event.as_mut_ptr())) }
} }
#[doc(alias = "gst_navigation_event_parse_key_event")]
#[doc(alias = "gst_navigation_event_parse_mouse_button_event")] #[doc(alias = "gst_navigation_event_parse_mouse_button_event")]
#[doc(alias = "gst_navigation_event_parse_mouse_command")]
#[doc(alias = "gst_navigation_event_parse_mouse_scroll_event")] #[doc(alias = "gst_navigation_event_parse_mouse_scroll_event")]
#[doc(alias = "gst_navigation_event_parse_mouse_move_event")] #[doc(alias = "gst_navigation_event_parse_mouse_move_event")]
#[doc(alias = "gst_navigation_event_parse_touch_event")]
#[doc(alias = "gst_navigation_event_parse_touch_up_event")]
#[doc(alias = "gst_navigation_event_parse_command")]
pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> { pub fn parse(event: &gst::EventRef) -> Result<Self, glib::error::BoolError> {
skip_assert_initialized!(); skip_assert_initialized!();
if event.type_() != EventType::Navigation {
return Err(glib::bool_error!("Invalid navigation event"));
}
let structure = event let structure = event
.structure() .structure()
.ok_or_else(|| glib::bool_error!("Invalid mouse event"))?; .ok_or_else(|| glib::bool_error!("Invalid navigation event"))?;
Ok(match Self::type_(event) { if structure.name() != NAVIGATION_EVENT_NAME {
NavigationEventType::MouseMove => Self::new_mouse_move( return Err(glib::bool_error!("Invalid navigation event"));
structure }
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
let modifier_state = structure
.get("state")
.unwrap_or(NavigationModifierType::empty());
let event = match Self::type_(event) {
NavigationEventType::MouseMove => NavigationEvent::MouseMove {
x: structure
.get("pointer_x") .get("pointer_x")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
structure y: structure
.get("pointer_y") .get("pointer_y")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
), #[cfg(any(feature = "v1_22", feature = "dox"))]
NavigationEventType::MouseButtonPress => Self::new_mouse_button_press( #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
structure modifier_state,
},
NavigationEventType::MouseButtonPress => NavigationEvent::MouseButtonPress {
button: structure
.get("button") .get("button")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
structure x: structure
.get("pointer_x") .get("pointer_x")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
structure y: structure
.get("pointer_y") .get("pointer_y")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
), #[cfg(any(feature = "v1_22", feature = "dox"))]
NavigationEventType::MouseButtonRelease => Self::new_mouse_button_press( #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
structure modifier_state,
},
NavigationEventType::MouseButtonRelease => NavigationEvent::MouseButtonRelease {
button: structure
.get("button") .get("button")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
structure x: structure
.get("pointer_x") .get("pointer_x")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
structure y: structure
.get("pointer_y") .get("pointer_y")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
), #[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state,
},
#[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
NavigationEventType::MouseScroll => Self::new_mouse_scroll( NavigationEventType::MouseScroll => NavigationEvent::MouseScroll {
structure x: structure
.get("pointer_x") .get("pointer_x")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
structure y: structure
.get("pointer_y") .get("pointer_y")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
structure delta_x: structure
.get("delta_pointer_x") .get("delta_pointer_x")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
structure delta_y: structure
.get("delta_pointer_y") .get("delta_pointer_y")
.map_err(|_| glib::bool_error!("Invalid mouse event"))?, .map_err(|_| glib::bool_error!("Invalid mouse event"))?,
), #[cfg(any(feature = "v1_22", feature = "dox"))]
NavigationEventType::KeyPress => Self::new_key_press( #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
structure modifier_state,
},
NavigationEventType::KeyPress => NavigationEvent::KeyPress {
key: structure
.get("key") .get("key")
.map_err(|_| glib::bool_error!("Invalid key press event"))?, .map_err(|_| glib::bool_error!("Invalid key press event"))?,
), #[cfg(any(feature = "v1_22", feature = "dox"))]
NavigationEventType::KeyRelease => Self::new_key_release( #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
structure modifier_state,
},
NavigationEventType::KeyRelease => NavigationEvent::KeyRelease {
key: structure
.get("key") .get("key")
.map_err(|_| glib::bool_error!("Invalid key press event"))?, .map_err(|_| glib::bool_error!("Invalid key press event"))?,
), #[cfg(any(feature = "v1_22", feature = "dox"))]
NavigationEventType::Command => Self::new_command( #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
structure modifier_state,
},
NavigationEventType::Command => NavigationEvent::Command {
command: structure
.get("command-code") .get("command-code")
.map_err(|_| glib::bool_error!("Invalid key press event"))?, .map_err(|_| glib::bool_error!("Invalid key press event"))?,
), #[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
modifier_state,
},
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
NavigationEventType::TouchDown => NavigationEvent::TouchDown {
identifier: structure
.get("identifier")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
x: structure
.get("pointer_x")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
y: structure
.get("pointer_y")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
pressure: structure
.get("pressure")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
modifier_state,
},
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
NavigationEventType::TouchMotion => NavigationEvent::TouchMotion {
identifier: structure
.get("identifier")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
x: structure
.get("pointer_x")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
y: structure
.get("pointer_y")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
pressure: structure
.get("pressure")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
modifier_state,
},
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
NavigationEventType::TouchUp => NavigationEvent::TouchUp {
identifier: structure
.get("identifier")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
x: structure
.get("pointer_x")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
y: structure
.get("pointer_y")
.map_err(|_| glib::bool_error!("Invalid touch event"))?,
modifier_state,
},
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
NavigationEventType::TouchFrame => NavigationEvent::TouchFrame { modifier_state },
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
NavigationEventType::TouchCancel => NavigationEvent::TouchCancel { modifier_state },
NavigationEventType::Invalid | NavigationEventType::__Unknown(_) => { NavigationEventType::Invalid | NavigationEventType::__Unknown(_) => {
return Err(glib::bool_error!("Invalid navigation event")) return Err(glib::bool_error!("Invalid navigation event"))
} }
}) };
Ok(event)
} }
pub fn structure(&self) -> gst::Structure { pub fn structure(&self) -> gst::Structure {
skip_assert_initialized!(); skip_assert_initialized!();
match self { #[allow(unused_mut)]
Self::MouseMove { x, y } => gst::Structure::builder(NAVIGATION_EVENT_NAME) let mut structure = match self {
Self::MouseMove { x, y, .. } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "mouse-move") .field("event", "mouse-move")
.field("pointer_x", x) .field("pointer_x", x)
.field("pointer_y", y) .field("pointer_y", y),
.build(), Self::MouseButtonPress { button, x, y, .. } => {
Self::MouseButtonPress { button, x, y } => {
gst::Structure::builder(NAVIGATION_EVENT_NAME) gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "mouse-button-press") .field("event", "mouse-button-press")
.field("button", button) .field("button", button)
.field("pointer_x", x) .field("pointer_x", x)
.field("pointer_y", y) .field("pointer_y", y)
.build()
} }
Self::MouseButtonRelease { button, x, y } => { Self::MouseButtonRelease { button, x, y, .. } => {
gst::Structure::builder(NAVIGATION_EVENT_NAME) gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "mouse-button-release") .field("event", "mouse-button-release")
.field("button", button) .field("button", button)
.field("pointer_x", x) .field("pointer_x", x)
.field("pointer_y", y) .field("pointer_y", y)
.build()
} }
#[cfg(any(feature = "v1_18", feature = "dox"))] #[cfg(any(feature = "v1_18", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))] #[cfg_attr(feature = "dox", doc(cfg(feature = "v1_18")))]
@ -557,26 +813,101 @@ impl NavigationEvent {
y, y,
delta_x, delta_x,
delta_y, delta_y,
..
} => gst::Structure::builder(NAVIGATION_EVENT_NAME) } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "mouse-scroll") .field("event", "mouse-scroll")
.field("pointer_x", x) .field("pointer_x", x)
.field("pointer_y", y) .field("pointer_y", y)
.field("delta_pointer_x", delta_x) .field("delta_pointer_x", delta_x)
.field("delta_pointer_y", delta_y) .field("delta_pointer_y", delta_y),
.build(), Self::KeyPress { key, .. } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
Self::KeyPress { key } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "key-press") .field("event", "key-press")
.field("key", key) .field("key", key),
.build(), Self::KeyRelease { key, .. } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
Self::KeyRelease { key } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "key-release") .field("event", "key-release")
.field("key", key) .field("key", key),
.build(), Self::Command { command, .. } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
Self::Command { command } => gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "command") .field("event", "command")
.field("command-code", command) .field("command-code", command),
.build(), #[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
Self::TouchDown {
identifier,
x,
y,
pressure,
..
} => gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "touch-down")
.field("identifier", identifier)
.field("pointer_x", x)
.field("pointer_y", y)
.field("pressure", pressure),
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
Self::TouchMotion {
identifier,
x,
y,
pressure,
..
} => gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "touch-motion")
.field("identifier", identifier)
.field("pointer_x", x)
.field("pointer_y", y)
.field("pressure", pressure),
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
Self::TouchUp {
identifier, x, y, ..
} => gst::Structure::builder(NAVIGATION_EVENT_NAME)
.field("event", "touch-up")
.field("identifier", identifier)
.field("pointer_x", x)
.field("pointer_y", y),
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
Self::TouchFrame { .. } => {
gst::Structure::builder(NAVIGATION_EVENT_NAME).field("event", "touch-frame")
}
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
Self::TouchCancel { .. } => {
gst::Structure::builder(NAVIGATION_EVENT_NAME).field("event", "touch-cancel")
}
};
#[cfg(any(feature = "v1_22", feature = "dox"))]
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
if true {
structure = match self {
Self::MouseMove { modifier_state, .. } => structure.field("state", modifier_state),
Self::MouseButtonPress { modifier_state, .. } => {
structure.field("state", modifier_state)
}
Self::MouseButtonRelease { modifier_state, .. } => {
structure.field("state", modifier_state)
}
Self::MouseScroll { modifier_state, .. } => {
structure.field("state", modifier_state)
}
Self::KeyPress { modifier_state, .. } => structure.field("state", modifier_state),
Self::KeyRelease { modifier_state, .. } => structure.field("state", modifier_state),
Self::Command { modifier_state, .. } => structure.field("state", modifier_state),
Self::TouchDown { modifier_state, .. } => structure.field("state", modifier_state),
Self::TouchMotion { modifier_state, .. } => {
structure.field("state", modifier_state)
}
Self::TouchUp { modifier_state, .. } => structure.field("state", modifier_state),
Self::TouchFrame { modifier_state, .. } => structure.field("state", modifier_state),
Self::TouchCancel { modifier_state, .. } => {
structure.field("state", modifier_state)
}
};
} }
structure.build()
} }
pub fn build(&self) -> gst::Event { pub fn build(&self) -> gst::Event {
@ -653,5 +984,27 @@ mod tests {
let json_event = serde_json::to_string(&navigation_event).unwrap(); let json_event = serde_json::to_string(&navigation_event).unwrap();
assert_eq!(json_event, r#"{"event":"KeyRelease","key":"a"}"#); assert_eq!(json_event, r#"{"event":"KeyRelease","key":"a"}"#);
let ev = NavigationEvent::new_touch_motion(0, 1.0, 2.0, 0.5).build();
let navigation_event = NavigationEvent::parse(&ev).unwrap();
match &navigation_event {
NavigationEvent::TouchMotion { id, x, y, pressure } => {
assert!(*id == 0 && *x = 1.0 && *y == 2.0 && *pressure == 0.5);
}
_ => unreachable!(),
}
let json_event = serde_json::to_string(&navigation_event).unwrap();
assert_eq!(
json_event,
r#"{"event":"TouchMotion","identifier":0,"x":1.0,"y":2.0,"pressure":0.5}"#
);
let ev = NavigationEvent::new_touch_cancel().build();
let navigation_event = NavigationEvent::parse(&ev).unwrap();
assert!(matches!(&navigation_event, NavigationEvent::TouchCancel {}));
let json_event = serde_json::to_string(&navigation_event).unwrap();
assert_eq!(json_event, r#"{"event":"TouchCancel"}"#);
} }
} }