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    /// 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            let mut error = std::ptr::null_mut();
235            ffi::gdk_content_provider_write_mime_type_finish(
236                _source_object as *mut _,
237                res,
238                &mut error,
239            );
240            let result = if error.is_null() {
241                Ok(())
242            } else {
243                Err(from_glib_full(error))
244            };
245            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
246                Box_::from_raw(user_data as *mut _);
247            let callback: P = callback.into_inner();
248            callback(result);
249        }
250        let callback = write_mime_type_async_trampoline::<P>;
251        unsafe {
252            ffi::gdk_content_provider_write_mime_type_async(
253                self.as_ref().to_glib_none().0,
254                mime_type.to_glib_none().0,
255                stream.as_ref().to_glib_none().0,
256                io_priority.into_glib(),
257                cancellable.map(|p| p.as_ref()).to_glib_none().0,
258                Some(callback),
259                Box_::into_raw(user_data) as *mut _,
260            );
261        }
262    }
263
264    fn write_mime_type_future(
265        &self,
266        mime_type: &str,
267        stream: &(impl IsA<gio::OutputStream> + Clone + 'static),
268        io_priority: glib::Priority,
269    ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
270        let mime_type = String::from(mime_type);
271        let stream = stream.clone();
272        Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
273            obj.write_mime_type_async(
274                &mime_type,
275                &stream,
276                io_priority,
277                Some(cancellable),
278                move |res| {
279                    send.resolve(res);
280                },
281            );
282        }))
283    }
284
285    /// Emitted whenever the content provided by this provider has changed.
286    #[doc(alias = "content-changed")]
287    fn connect_content_changed<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
288        unsafe extern "C" fn content_changed_trampoline<
289            P: IsA<ContentProvider>,
290            F: Fn(&P) + 'static,
291        >(
292            this: *mut ffi::GdkContentProvider,
293            f: glib::ffi::gpointer,
294        ) {
295            let f: &F = &*(f as *const F);
296            f(ContentProvider::from_glib_borrow(this).unsafe_cast_ref())
297        }
298        unsafe {
299            let f: Box_<F> = Box_::new(f);
300            connect_raw(
301                self.as_ptr() as *mut _,
302                c"content-changed".as_ptr() as *const _,
303                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
304                    content_changed_trampoline::<Self, F> as *const (),
305                )),
306                Box_::into_raw(f),
307            )
308        }
309    }
310
311    #[doc(alias = "formats")]
312    fn connect_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
313        unsafe extern "C" fn notify_formats_trampoline<
314            P: IsA<ContentProvider>,
315            F: Fn(&P) + 'static,
316        >(
317            this: *mut ffi::GdkContentProvider,
318            _param_spec: glib::ffi::gpointer,
319            f: glib::ffi::gpointer,
320        ) {
321            let f: &F = &*(f as *const F);
322            f(ContentProvider::from_glib_borrow(this).unsafe_cast_ref())
323        }
324        unsafe {
325            let f: Box_<F> = Box_::new(f);
326            connect_raw(
327                self.as_ptr() as *mut _,
328                c"notify::formats".as_ptr() as *const _,
329                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
330                    notify_formats_trampoline::<Self, F> as *const (),
331                )),
332                Box_::into_raw(f),
333            )
334        }
335    }
336
337    #[doc(alias = "storable-formats")]
338    fn connect_storable_formats_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
339        unsafe extern "C" fn notify_storable_formats_trampoline<
340            P: IsA<ContentProvider>,
341            F: Fn(&P) + 'static,
342        >(
343            this: *mut ffi::GdkContentProvider,
344            _param_spec: glib::ffi::gpointer,
345            f: glib::ffi::gpointer,
346        ) {
347            let f: &F = &*(f as *const F);
348            f(ContentProvider::from_glib_borrow(this).unsafe_cast_ref())
349        }
350        unsafe {
351            let f: Box_<F> = Box_::new(f);
352            connect_raw(
353                self.as_ptr() as *mut _,
354                c"notify::storable-formats".as_ptr() as *const _,
355                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
356                    notify_storable_formats_trampoline::<Self, F> as *const (),
357                )),
358                Box_::into_raw(f),
359            )
360        }
361    }
362}
363
364impl<O: IsA<ContentProvider>> ContentProviderExt for O {}