From 0a8d34bc2301fac3b575bcabaadba575eaf45bcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 18 Nov 2018 16:36:28 +0200 Subject: [PATCH] Port ChildProxy subclassing --- gstreamer/src/subclass/child_proxy.rs | 159 ++++++++++++++++++++++++++ gstreamer/src/subclass/mod.rs | 3 + gstreamer/src/subclass/uri_handler.rs | 4 +- 3 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 gstreamer/src/subclass/child_proxy.rs diff --git a/gstreamer/src/subclass/child_proxy.rs b/gstreamer/src/subclass/child_proxy.rs new file mode 100644 index 000000000..83555f555 --- /dev/null +++ b/gstreamer/src/subclass/child_proxy.rs @@ -0,0 +1,159 @@ +// Copyright (C) 2018 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use glib_ffi; +use gobject_ffi; + +use glib; +use glib::subclass::prelude::*; +use glib::translate::*; + +use libc; + +use std::ptr; + +use ChildProxy; + +pub trait ChildProxyImpl: super::element::ElementImpl + Send + Sync + 'static { + fn get_child_by_name(&self, object: &ChildProxy, name: &str) -> Option { + unsafe { + let type_ = ffi::gst_child_proxy_get_type(); + let iface = gobject_ffi::g_type_default_interface_ref(type_) + as *mut ffi::GstChildProxyInterface; + assert!(!iface.is_null()); + + let ret = ((*iface).get_child_by_name.as_ref().unwrap())( + object.to_glib_none().0, + name.to_glib_none().0, + ); + + gobject_ffi::g_type_default_interface_unref(iface as glib_ffi::gpointer); + + from_glib_full(ret) + } + } + + fn get_child_by_index(&self, object: &ChildProxy, index: u32) -> Option; + fn get_children_count(&self, object: &ChildProxy) -> u32; + + fn child_added(&self, object: &ChildProxy, child: &glib::Object, name: &str); + fn child_removed(&self, object: &ChildProxy, child: &glib::Object, name: &str); +} + +unsafe extern "C" fn child_proxy_get_child_by_name( + child_proxy: *mut ffi::GstChildProxy, + name: *const libc::c_char, +) -> *mut gobject_ffi::GObject +where + T: ChildProxyImpl, +{ + glib_floating_reference_guard!(child_proxy); + let instance = &*(child_proxy as *mut T::Instance); + let imp = instance.get_impl(); + + imp.get_child_by_name( + &from_glib_borrow(child_proxy), + String::from_glib_none(name).as_str(), + ) + .to_glib_full() +} + +unsafe extern "C" fn child_proxy_get_child_by_index( + child_proxy: *mut ffi::GstChildProxy, + index: u32, +) -> *mut gobject_ffi::GObject +where + T: ChildProxyImpl, +{ + glib_floating_reference_guard!(child_proxy); + let instance = &*(child_proxy as *mut T::Instance); + let imp = instance.get_impl(); + + imp.get_child_by_index(&from_glib_borrow(child_proxy), index) + .to_glib_full() +} + +unsafe extern "C" fn child_proxy_get_children_count( + child_proxy: *mut ffi::GstChildProxy, +) -> u32 +where + T: ChildProxyImpl, +{ + glib_floating_reference_guard!(child_proxy); + let instance = &*(child_proxy as *mut T::Instance); + let imp = instance.get_impl(); + + imp.get_children_count(&from_glib_borrow(child_proxy)) +} + +unsafe extern "C" fn child_proxy_child_added( + child_proxy: *mut ffi::GstChildProxy, + child: *mut gobject_ffi::GObject, + name: *const libc::c_char, +) where + T: ChildProxyImpl, +{ + glib_floating_reference_guard!(child_proxy); + let instance = &*(child_proxy as *mut T::Instance); + let imp = instance.get_impl(); + + imp.child_added( + &from_glib_borrow(child_proxy), + &from_glib_borrow(child), + String::from_glib_none(name).as_str(), + ) +} + +unsafe extern "C" fn child_proxy_child_removed( + child_proxy: *mut ffi::GstChildProxy, + child: *mut gobject_ffi::GObject, + name: *const libc::c_char, +) where + T: ChildProxyImpl, +{ + glib_floating_reference_guard!(child_proxy); + let instance = &*(child_proxy as *mut T::Instance); + let imp = instance.get_impl(); + + imp.child_removed( + &from_glib_borrow(child_proxy), + &from_glib_borrow(child), + String::from_glib_none(name).as_str(), + ) +} + +unsafe extern "C" fn child_proxy_init( + iface: glib_ffi::gpointer, + _iface_data: glib_ffi::gpointer, +) where + T: ChildProxyImpl, +{ + let child_proxy_iface = &mut *(iface as *mut ffi::GstChildProxyInterface); + + child_proxy_iface.get_child_by_name = Some(child_proxy_get_child_by_name::); + child_proxy_iface.get_child_by_index = Some(child_proxy_get_child_by_index::); + child_proxy_iface.get_children_count = Some(child_proxy_get_children_count::); + child_proxy_iface.child_added = Some(child_proxy_child_added::); + child_proxy_iface.child_removed = Some(child_proxy_child_removed::); +} + +pub fn register(type_: glib::subclass::InitializingType) { + unsafe { + let iface_info = gobject_ffi::GInterfaceInfo { + interface_init: Some(child_proxy_init::), + interface_finalize: None, + interface_data: ptr::null_mut(), + }; + gobject_ffi::g_type_add_interface_static( + type_.to_glib(), + ffi::gst_child_proxy_get_type(), + &iface_info, + ); + } +} diff --git a/gstreamer/src/subclass/mod.rs b/gstreamer/src/subclass/mod.rs index 3841d881d..7b82354ee 100644 --- a/gstreamer/src/subclass/mod.rs +++ b/gstreamer/src/subclass/mod.rs @@ -13,9 +13,12 @@ pub mod error; #[macro_use] pub mod plugin; +pub mod child_proxy; pub mod element; +pub mod uri_handler; pub mod prelude { + pub use super::child_proxy::ChildProxyImpl; pub use super::element::{ElementClassSubclassExt, ElementImpl, ElementImplExt}; pub use super::uri_handler::URIHandlerImpl; pub use super::PanicPoison; diff --git a/gstreamer/src/subclass/uri_handler.rs b/gstreamer/src/subclass/uri_handler.rs index 425f875cb..e59efb062 100644 --- a/gstreamer/src/subclass/uri_handler.rs +++ b/gstreamer/src/subclass/uri_handler.rs @@ -109,9 +109,7 @@ unsafe extern "C" fn uri_handler_init( uri_handler_iface.set_uri = Some(uri_handler_set_uri::); } -pub fn register( - type_: &glib::subclass::InitializingType, -) { +pub fn register(type_: &glib::subclass::InitializingType) { unsafe { let iface_info = gobject_ffi::GInterfaceInfo { interface_init: Some(uri_handler_init::),