Skip to main content

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::{ContentFormats, ffi};
6use glib::{
7    object::ObjectType as _,
8    prelude::*,
9    signal::{SignalHandlerId, connect_raw},
10    translate::*,
11};
12use std::{boxed::Box as Box_, pin::Pin};
13
14glib::wrapper! {
15    /// Provides content for the clipboard or for drag-and-drop operations
16    /// 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
138/// Trait containing all [`struct@ContentProvider`] methods.
139///
140/// # Implementors
141///
142/// [`ContentProvider`][struct@crate::ContentProvider]
143pub trait ContentProviderExt: IsA<ContentProvider> + 'static {
144    /// Emits the ::content-changed signal.
145    #[doc(alias = "gdk_content_provider_content_changed")]
146    fn content_changed(&self) {
147        unsafe {
148            ffi::gdk_content_provider_content_changed(self.as_ref().to_glib_none().0);
149        }
150    }
151
152    /// Gets the formats that the provider can provide its current contents in.
153    ///
154    /// # Returns
155    ///
156    /// The formats of the provider
157    #[doc(alias = "gdk_content_provider_ref_formats")]
158    #[doc(alias = "ref_formats")]
159    fn formats(&self) -> ContentFormats {
160        unsafe {
161            from_glib_full(ffi::gdk_content_provider_ref_formats(
162                self.as_ref().to_glib_none().0,
163            ))
164        }
165    }
166
167    /// Gets the formats that the provider suggests other applications to store
168    /// the data in.
169    ///
170    /// An example of such an application would be a clipboard manager.
171    ///
172    /// This can be assumed to be a subset of [`formats()`][Self::formats()].
173    ///
174    /// # Returns
175    ///
176    /// The storable formats of the provider
177    #[doc(alias = "gdk_content_provider_ref_storable_formats")]
178    #[doc(alias = "ref_storable_formats")]
179    #[doc(alias = "storable-formats")]
180    fn storable_formats(&self) -> ContentFormats {
181        unsafe {
182            from_glib_full(ffi::gdk_content_provider_ref_storable_formats(
183                self.as_ref().to_glib_none().0,
184            ))
185        }
186    }
187
188    /// Asynchronously writes the contents of @self to @stream in the given
189    /// @mime_type.
190    ///
191    /// The given mime type does not need to be listed in the formats returned by
192    /// [`formats()`][Self::formats()]. However, if the given `GType` is
193    /// not supported, `G_IO_ERROR_NOT_SUPPORTED` will be reported.
194    ///
195    /// The given @stream will not be closed.
196    /// ## `mime_type`
197    /// the mime type to provide the data in
198    /// ## `stream`
199    /// the `GOutputStream` to write to
200    /// ## `io_priority`
201    /// I/O priority of the request.
202    /// ## `cancellable`
203    /// optional `GCancellable` object, [`None`] to ignore.
204    /// ## `callback`
205    /// callback to call when the request is satisfied
206    #[doc(alias = "gdk_content_provider_write_mime_type_async")]
207    fn write_mime_type_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
208        &self,
209        mime_type: &str,
210        stream: &impl IsA<gio::OutputStream>,
211        io_priority: glib::Priority,
212        cancellable: Option<&impl IsA<gio::Cancellable>>,
213        callback: P,
214    ) {
215        let main_context = glib::MainContext::ref_thread_default();
216        let is_main_context_owner = main_context.is_owner();
217        let has_acquired_main_context = (!is_main_context_owner)
218            .then(|| main_context.acquire().ok())
219            .flatten();
220        assert!(
221            is_main_context_owner || has_acquired_main_context.is_some(),
222            "Async operations only allowed if the thread is owning the MainContext"
223        );
224
225        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
226            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
227        unsafe extern "C" fn write_mime_type_async_trampoline<
228            P: FnOnce(Result<(), glib::Error>) + 'static,
229        >(
230            _source_object: *mut glib::gobject_ffi::GObject,
231            res: *mut gio::ffi::GAsyncResult,
232            user_data: glib::ffi::gpointer,
233        ) {
234            unsafe {
235                let mut error = std::ptr::null_mut();
236                ffi::gdk_content_provider_write_mime_type_finish(
237                    _source_object as *mut _,
238                    res,
239                    &mut error,
240                );
241                let result = if error.is_null() {
242                    Ok(())
243                } else {
244                    Err(from_glib_full(error))
245                };
246                let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
247                    Box_::from_raw(user_data as *mut _);
248                let callback: P = callback.into_inner();
249                callback(result);
250            }
251        }
252        let callback = write_mime_type_async_trampoline::<P>;
253        unsafe {
254            ffi::gdk_content_provider_write_mime_type_async(
255                self.as_ref().to_glib_none().0,
256                mime_type.to_glib_none().0,
257                stream.as_ref().to_glib_none().0,
258                io_priority.into_glib(),
259                cancellable.map(|p| p.as_ref()).to_glib_none().0,
260                Some(callback),
261                Box_::into_raw(user_data) as *mut _,
262            );
263        }
264    }
265
266    fn write_mime_type_future(
267        &self,
268        mime_type: &str,
269        stream: &(impl IsA<gio::OutputStream> + Clone + 'static),
270        io_priority: glib::Priority,
271    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
272        let mime_type = String::from(mime_type);
273        let stream = stream.clone();
274        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
275            obj.write_mime_type_async(
276                &mime_type,
277                &stream,
278                io_priority,
279                Some(cancellable),
280                move |res| {
281                    send.resolve(res);
282                },
283            );
284        }))
285    }
286
287    /// Emitted whenever the content provided by this provider has changed.
288    #[doc(alias = "content-changed")]
289    fn connect_content_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
290        unsafe extern "C" fn content_changed_trampoline<
291            P: IsA<ContentProvider>,
292            F: Fn(&P) + 'static,
293        >(
294            this: *mut ffi::GdkContentProvider,
295            f: glib::ffi::gpointer,
296        ) {
297            unsafe {
298                let f: &F = &*(f as *const F);
299                f(ContentProvider::from_glib_borrow(this).unsafe_cast_ref())
300            }
301        }
302        unsafe {
303            let f: Box_<F> = Box_::new(f);
304            connect_raw(
305                self.as_ptr() as *mut _,
306                c"content-changed".as_ptr() as *const _,
307                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
308                    content_changed_trampoline::<Self, F> as *const (),
309                )),
310                Box_::into_raw(f),
311            )
312        }
313    }
314
315    #[doc(alias = "formats")]
316    fn connect_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
317        unsafe extern "C" fn notify_formats_trampoline<
318            P: IsA<ContentProvider>,
319            F: Fn(&P) + 'static,
320        >(
321            this: *mut ffi::GdkContentProvider,
322            _param_spec: glib::ffi::gpointer,
323            f: glib::ffi::gpointer,
324        ) {
325            unsafe {
326                let f: &F = &*(f as *const F);
327                f(ContentProvider::from_glib_borrow(this).unsafe_cast_ref())
328            }
329        }
330        unsafe {
331            let f: Box_<F> = Box_::new(f);
332            connect_raw(
333                self.as_ptr() as *mut _,
334                c"notify::formats".as_ptr() as *const _,
335                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
336                    notify_formats_trampoline::<Self, F> as *const (),
337                )),
338                Box_::into_raw(f),
339            )
340        }
341    }
342
343    #[doc(alias = "storable-formats")]
344    fn connect_storable_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
345        unsafe extern "C" fn notify_storable_formats_trampoline<
346            P: IsA<ContentProvider>,
347            F: Fn(&P) + 'static,
348        >(
349            this: *mut ffi::GdkContentProvider,
350            _param_spec: glib::ffi::gpointer,
351            f: glib::ffi::gpointer,
352        ) {
353            unsafe {
354                let f: &F = &*(f as *const F);
355                f(ContentProvider::from_glib_borrow(this).unsafe_cast_ref())
356            }
357        }
358        unsafe {
359            let f: Box_<F> = Box_::new(f);
360            connect_raw(
361                self.as_ptr() as *mut _,
362                c"notify::storable-formats".as_ptr() as *const _,
363                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
364                    notify_storable_formats_trampoline::<Self, F> as *const (),
365                )),
366                Box_::into_raw(f),
367            )
368        }
369    }
370}
371
372impl<O: IsA<ContentProvider>> ContentProviderExt for O {}