gdk4/auto/
content_provider.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// DO NOT EDIT
4
5use crate::{ffi, ContentFormats};
6use glib::{
7    object::ObjectType as _,
8    prelude::*,
9    signal::{connect_raw, SignalHandlerId},
10    translate::*,
11};
12use std::{boxed::Box as Box_, pin::Pin};
13
14glib::wrapper! {
15    /// A [`ContentProvider`][crate::ContentProvider] is used to provide content for the clipboard or
16    /// for drag-and-drop operations in a number of formats.
17    ///
18    /// To create a [`ContentProvider`][crate::ContentProvider], use [`for_value()`][Self::for_value()]
19    /// or [`for_bytes()`][Self::for_bytes()].
20    ///
21    /// GDK knows how to handle common text and image formats out-of-the-box. See
22    /// [`ContentSerializer`][crate::ContentSerializer] and [`ContentDeserializer`][crate::ContentDeserializer] if you want
23    /// to add support for application-specific data formats.
24    ///
25    /// ## Properties
26    ///
27    ///
28    /// #### `formats`
29    ///  The possible formats that the provider can provide its data in.
30    ///
31    /// Readable
32    ///
33    ///
34    /// #### `storable-formats`
35    ///  The subset of formats that clipboard managers should store this provider's data in.
36    ///
37    /// Readable
38    ///
39    /// ## Signals
40    ///
41    ///
42    /// #### `content-changed`
43    ///  Emitted whenever the content provided by this provider has changed.
44    ///
45    ///
46    ///
47    /// # Implements
48    ///
49    /// [`ContentProviderExt`][trait@crate::prelude::ContentProviderExt], [`ContentProviderExtManual`][trait@crate::prelude::ContentProviderExtManual]
50    #[doc(alias = "GdkContentProvider")]
51    pub struct ContentProvider(Object<ffi::GdkContentProvider, ffi::GdkContentProviderClass>);
52
53    match fn {
54        type_ => || ffi::gdk_content_provider_get_type(),
55    }
56}
57
58impl ContentProvider {
59    pub const NONE: Option<&'static ContentProvider> = None;
60
61    /// Create a content provider that provides the given @bytes as data for
62    /// the given @mime_type.
63    /// ## `mime_type`
64    /// the mime type
65    /// ## `bytes`
66    /// a `GBytes` with the data for @mime_type
67    ///
68    /// # Returns
69    ///
70    /// a new [`ContentProvider`][crate::ContentProvider]
71    #[doc(alias = "gdk_content_provider_new_for_bytes")]
72    #[doc(alias = "new_for_bytes")]
73    pub fn for_bytes(mime_type: &str, bytes: &glib::Bytes) -> ContentProvider {
74        assert_initialized_main_thread!();
75        unsafe {
76            from_glib_full(ffi::gdk_content_provider_new_for_bytes(
77                mime_type.to_glib_none().0,
78                bytes.to_glib_none().0,
79            ))
80        }
81    }
82
83    /// Create a content provider that provides the given @value.
84    /// ## `value`
85    /// a `GValue`
86    ///
87    /// # Returns
88    ///
89    /// a new [`ContentProvider`][crate::ContentProvider]
90    #[doc(alias = "gdk_content_provider_new_for_value")]
91    #[doc(alias = "new_for_value")]
92    pub fn for_value(value: &glib::Value) -> ContentProvider {
93        assert_initialized_main_thread!();
94        unsafe {
95            from_glib_full(ffi::gdk_content_provider_new_for_value(
96                value.to_glib_none().0,
97            ))
98        }
99    }
100
101    /// Creates a content provider that represents all the given @providers.
102    ///
103    /// Whenever data needs to be written, the union provider will try the given
104    /// @providers in the given order and the first one supporting a format will
105    /// be chosen to provide it.
106    ///
107    /// This allows an easy way to support providing data in different formats.
108    /// For example, an image may be provided by its file and by the image
109    /// contents with a call such as
110    /// **⚠️ The following code is in c ⚠️**
111    ///
112    /// ```c
113    /// gdk_content_provider_new_union ((GdkContentProvider *[2]) {
114    ///                                   gdk_content_provider_new_typed (G_TYPE_FILE, file),
115    ///                                   gdk_content_provider_new_typed (GDK_TYPE_TEXTURE, texture)
116    ///                                 }, 2);
117    /// ```
118    /// ## `providers`
119    ///
120    ///   The [`ContentProvider`][crate::ContentProvider]s to present the union of
121    ///
122    /// # Returns
123    ///
124    /// a new [`ContentProvider`][crate::ContentProvider]
125    #[doc(alias = "gdk_content_provider_new_union")]
126    pub fn new_union(providers: &[ContentProvider]) -> ContentProvider {
127        assert_initialized_main_thread!();
128        let n_providers = providers.len() as _;
129        unsafe {
130            from_glib_full(ffi::gdk_content_provider_new_union(
131                providers.to_glib_full(),
132                n_providers,
133            ))
134        }
135    }
136}
137
138mod sealed {
139    pub trait Sealed {}
140    impl<T: super::IsA<super::ContentProvider>> Sealed for T {}
141}
142
143/// Trait containing all [`struct@ContentProvider`] methods.
144///
145/// # Implementors
146///
147/// [`ContentProvider`][struct@crate::ContentProvider]
148pub trait ContentProviderExt: IsA<ContentProvider> + sealed::Sealed + 'static {
149    /// Emits the ::content-changed signal.
150    #[doc(alias = "gdk_content_provider_content_changed")]
151    fn content_changed(&self) {
152        unsafe {
153            ffi::gdk_content_provider_content_changed(self.as_ref().to_glib_none().0);
154        }
155    }
156
157    /// Gets the formats that the provider can provide its current contents in.
158    ///
159    /// # Returns
160    ///
161    /// The formats of the provider
162    #[doc(alias = "gdk_content_provider_ref_formats")]
163    #[doc(alias = "ref_formats")]
164    fn formats(&self) -> ContentFormats {
165        unsafe {
166            from_glib_full(ffi::gdk_content_provider_ref_formats(
167                self.as_ref().to_glib_none().0,
168            ))
169        }
170    }
171
172    /// Gets the formats that the provider suggests other applications to store
173    /// the data in.
174    ///
175    /// An example of such an application would be a clipboard manager.
176    ///
177    /// This can be assumed to be a subset of [`formats()`][Self::formats()].
178    ///
179    /// # Returns
180    ///
181    /// The storable formats of the provider
182    #[doc(alias = "gdk_content_provider_ref_storable_formats")]
183    #[doc(alias = "ref_storable_formats")]
184    #[doc(alias = "storable-formats")]
185    fn storable_formats(&self) -> ContentFormats {
186        unsafe {
187            from_glib_full(ffi::gdk_content_provider_ref_storable_formats(
188                self.as_ref().to_glib_none().0,
189            ))
190        }
191    }
192
193    /// Asynchronously writes the contents of @self to @stream in the given
194    /// @mime_type.
195    ///
196    /// The given mime type does not need to be listed in the formats returned by
197    /// [`formats()`][Self::formats()]. However, if the given `GType` is
198    /// not supported, `G_IO_ERROR_NOT_SUPPORTED` will be reported.
199    ///
200    /// The given @stream will not be closed.
201    /// ## `mime_type`
202    /// the mime type to provide the data in
203    /// ## `stream`
204    /// the `GOutputStream` to write to
205    /// ## `io_priority`
206    /// I/O priority of the request.
207    /// ## `cancellable`
208    /// optional `GCancellable` object, [`None`] to ignore.
209    /// ## `callback`
210    /// callback to call when the request is satisfied
211    #[doc(alias = "gdk_content_provider_write_mime_type_async")]
212    fn write_mime_type_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
213        &self,
214        mime_type: &str,
215        stream: &impl IsA<gio::OutputStream>,
216        io_priority: glib::Priority,
217        cancellable: Option<&impl IsA<gio::Cancellable>>,
218        callback: P,
219    ) {
220        let main_context = glib::MainContext::ref_thread_default();
221        let is_main_context_owner = main_context.is_owner();
222        let has_acquired_main_context = (!is_main_context_owner)
223            .then(|| main_context.acquire().ok())
224            .flatten();
225        assert!(
226            is_main_context_owner || has_acquired_main_context.is_some(),
227            "Async operations only allowed if the thread is owning the MainContext"
228        );
229
230        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
231            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
232        unsafe extern "C" fn write_mime_type_async_trampoline<
233            P: FnOnce(Result<(), glib::Error>) + 'static,
234        >(
235            _source_object: *mut glib::gobject_ffi::GObject,
236            res: *mut gio::ffi::GAsyncResult,
237            user_data: glib::ffi::gpointer,
238        ) {
239            let mut error = std::ptr::null_mut();
240            let _ = ffi::gdk_content_provider_write_mime_type_finish(
241                _source_object as *mut _,
242                res,
243                &mut error,
244            );
245            let result = if error.is_null() {
246                Ok(())
247            } else {
248                Err(from_glib_full(error))
249            };
250            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
251                Box_::from_raw(user_data as *mut _);
252            let callback: P = callback.into_inner();
253            callback(result);
254        }
255        let callback = write_mime_type_async_trampoline::<P>;
256        unsafe {
257            ffi::gdk_content_provider_write_mime_type_async(
258                self.as_ref().to_glib_none().0,
259                mime_type.to_glib_none().0,
260                stream.as_ref().to_glib_none().0,
261                io_priority.into_glib(),
262                cancellable.map(|p| p.as_ref()).to_glib_none().0,
263                Some(callback),
264                Box_::into_raw(user_data) as *mut _,
265            );
266        }
267    }
268
269    fn write_mime_type_future(
270        &self,
271        mime_type: &str,
272        stream: &(impl IsA<gio::OutputStream> + Clone + 'static),
273        io_priority: glib::Priority,
274    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
275        let mime_type = String::from(mime_type);
276        let stream = stream.clone();
277        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
278            obj.write_mime_type_async(
279                &mime_type,
280                &stream,
281                io_priority,
282                Some(cancellable),
283                move |res| {
284                    send.resolve(res);
285                },
286            );
287        }))
288    }
289
290    /// Emitted whenever the content provided by this provider has changed.
291    #[doc(alias = "content-changed")]
292    fn connect_content_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
293        unsafe extern "C" fn content_changed_trampoline<
294            P: IsA<ContentProvider>,
295            F: Fn(&P) + 'static,
296        >(
297            this: *mut ffi::GdkContentProvider,
298            f: glib::ffi::gpointer,
299        ) {
300            let f: &F = &*(f as *const F);
301            f(ContentProvider::from_glib_borrow(this).unsafe_cast_ref())
302        }
303        unsafe {
304            let f: Box_<F> = Box_::new(f);
305            connect_raw(
306                self.as_ptr() as *mut _,
307                b"content-changed\0".as_ptr() as *const _,
308                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
309                    content_changed_trampoline::<Self, F> as *const (),
310                )),
311                Box_::into_raw(f),
312            )
313        }
314    }
315
316    #[doc(alias = "formats")]
317    fn connect_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
318        unsafe extern "C" fn notify_formats_trampoline<
319            P: IsA<ContentProvider>,
320            F: Fn(&P) + 'static,
321        >(
322            this: *mut ffi::GdkContentProvider,
323            _param_spec: glib::ffi::gpointer,
324            f: glib::ffi::gpointer,
325        ) {
326            let f: &F = &*(f as *const F);
327            f(ContentProvider::from_glib_borrow(this).unsafe_cast_ref())
328        }
329        unsafe {
330            let f: Box_<F> = Box_::new(f);
331            connect_raw(
332                self.as_ptr() as *mut _,
333                b"notify::formats\0".as_ptr() as *const _,
334                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
335                    notify_formats_trampoline::<Self, F> as *const (),
336                )),
337                Box_::into_raw(f),
338            )
339        }
340    }
341
342    #[doc(alias = "storable-formats")]
343    fn connect_storable_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
344        unsafe extern "C" fn notify_storable_formats_trampoline<
345            P: IsA<ContentProvider>,
346            F: Fn(&P) + 'static,
347        >(
348            this: *mut ffi::GdkContentProvider,
349            _param_spec: glib::ffi::gpointer,
350            f: glib::ffi::gpointer,
351        ) {
352            let f: &F = &*(f as *const F);
353            f(ContentProvider::from_glib_borrow(this).unsafe_cast_ref())
354        }
355        unsafe {
356            let f: Box_<F> = Box_::new(f);
357            connect_raw(
358                self.as_ptr() as *mut _,
359                b"notify::storable-formats\0".as_ptr() as *const _,
360                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
361                    notify_storable_formats_trampoline::<Self, F> as *const (),
362                )),
363                Box_::into_raw(f),
364            )
365        }
366    }
367}
368
369impl<O: IsA<ContentProvider>> ContentProviderExt for O {}