From 2fb69cd33153979f97f3d1337b9212d146a2010a Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Fri, 17 Feb 2023 12:40:20 +0100 Subject: [PATCH] gio: Add FileMonitor subclassing support --- gio/src/subclass/file_monitor.rs | 85 ++++++++++++++++++++++++++++++++ gio/src/subclass/mod.rs | 2 + 2 files changed, 87 insertions(+) create mode 100644 gio/src/subclass/file_monitor.rs diff --git a/gio/src/subclass/file_monitor.rs b/gio/src/subclass/file_monitor.rs new file mode 100644 index 000000000000..95a5e9cf4305 --- /dev/null +++ b/gio/src/subclass/file_monitor.rs @@ -0,0 +1,85 @@ +// Take a look at the license at the top of the repository in the LICENSE file. + +use crate::{subclass::prelude::*, File, FileMonitor, FileMonitorEvent}; +use glib::{prelude::*, translate::*}; + +pub trait FileMonitorImpl: ObjectImpl { + fn changed(&self, file: &File, other_file: &File, event_type: FileMonitorEvent) { + self.parent_changed(file, other_file, event_type) + } + fn cancel(&self) -> bool { + self.parent_cancel() + } +} + +pub trait FileMonitorImplExt: ObjectSubclass { + fn parent_changed(&self, file: &File, other_file: &File, event_type: FileMonitorEvent); + fn parent_cancel(&self) -> bool; +} + +impl FileMonitorImplExt for T { + fn parent_changed(&self, file: &File, other_file: &File, event_type: FileMonitorEvent) { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GFileMonitorClass; + if let Some(f) = (*parent_class).changed { + f( + self.obj().unsafe_cast_ref::().to_glib_none().0, + file.to_glib_none().0, + other_file.to_glib_none().0, + event_type.into_glib(), + ) + } + } + } + + fn parent_cancel(&self) -> bool { + unsafe { + let data = T::type_data(); + let parent_class = data.as_ref().parent_class() as *mut ffi::GFileMonitorClass; + let f = (*parent_class) + .cancel + .expect("No parent class implementation for \"cancel\""); + from_glib(f(self + .obj() + .unsafe_cast_ref::() + .to_glib_none() + .0)) + } + } +} + +unsafe impl IsSubclassable for FileMonitor { + fn class_init(class: &mut ::glib::Class) { + Self::parent_class_init::(class); + + let klass = class.as_mut(); + klass.changed = Some(file_monitor_changed::); + klass.cancel = Some(file_monitor_cancel::); + } +} + +unsafe extern "C" fn file_monitor_changed( + ptr: *mut ffi::GFileMonitor, + file: *mut ffi::GFile, + other_file: *mut ffi::GFile, + event: ffi::GFileMonitorEvent, +) { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + + imp.changed( + &from_glib_borrow(file), + &from_glib_borrow(other_file), + from_glib(event), + ) +} + +unsafe extern "C" fn file_monitor_cancel( + ptr: *mut ffi::GFileMonitor, +) -> glib::ffi::gboolean { + let instance = &*(ptr as *mut T::Instance); + let imp = instance.imp(); + + imp.cancel().into_glib() +} diff --git a/gio/src/subclass/mod.rs b/gio/src/subclass/mod.rs index 728c05bea3dc..7ac3fc33746d 100644 --- a/gio/src/subclass/mod.rs +++ b/gio/src/subclass/mod.rs @@ -5,6 +5,7 @@ mod action_map; mod app_launch_context; mod application; mod async_initable; +mod file_monitor; mod initable; mod input_stream; mod io_stream; @@ -24,6 +25,7 @@ pub mod prelude { app_launch_context::{AppLaunchContextImpl, AppLaunchContextImplExt}, application::{ApplicationImpl, ApplicationImplExt}, async_initable::{AsyncInitableImpl, AsyncInitableImplExt}, + file_monitor::{FileMonitorImpl, FileMonitorImplExt}, initable::{InitableImpl, InitableImplExt}, input_stream::{InputStreamImpl, InputStreamImplExt}, io_stream::{IOStreamImpl, IOStreamImplExt},