1use crate::{ffi, AsyncResult, Cancellable};
6use glib::{
7 prelude::*,
8 signal::{connect_raw, SignalHandlerId},
9 translate::*,
10};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14 #[doc(alias = "GPermission")]
59 pub struct Permission(Object<ffi::GPermission, ffi::GPermissionClass>);
60
61 match fn {
62 type_ => || ffi::g_permission_get_type(),
63 }
64}
65
66impl Permission {
67 pub const NONE: Option<&'static Permission> = None;
68}
69
70pub trait PermissionExt: IsA<Permission> + 'static {
76 #[doc(alias = "g_permission_acquire")]
98 fn acquire(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
99 unsafe {
100 let mut error = std::ptr::null_mut();
101 let is_ok = ffi::g_permission_acquire(
102 self.as_ref().to_glib_none().0,
103 cancellable.map(|p| p.as_ref()).to_glib_none().0,
104 &mut error,
105 );
106 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
107 if error.is_null() {
108 Ok(())
109 } else {
110 Err(from_glib_full(error))
111 }
112 }
113 }
114
115 #[doc(alias = "g_permission_acquire_async")]
124 fn acquire_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
125 &self,
126 cancellable: Option<&impl IsA<Cancellable>>,
127 callback: P,
128 ) {
129 let main_context = glib::MainContext::ref_thread_default();
130 let is_main_context_owner = main_context.is_owner();
131 let has_acquired_main_context = (!is_main_context_owner)
132 .then(|| main_context.acquire().ok())
133 .flatten();
134 assert!(
135 is_main_context_owner || has_acquired_main_context.is_some(),
136 "Async operations only allowed if the thread is owning the MainContext"
137 );
138
139 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
140 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
141 unsafe extern "C" fn acquire_async_trampoline<
142 P: FnOnce(Result<(), glib::Error>) + 'static,
143 >(
144 _source_object: *mut glib::gobject_ffi::GObject,
145 res: *mut crate::ffi::GAsyncResult,
146 user_data: glib::ffi::gpointer,
147 ) {
148 let mut error = std::ptr::null_mut();
149 ffi::g_permission_acquire_finish(_source_object as *mut _, res, &mut error);
150 let result = if error.is_null() {
151 Ok(())
152 } else {
153 Err(from_glib_full(error))
154 };
155 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
156 Box_::from_raw(user_data as *mut _);
157 let callback: P = callback.into_inner();
158 callback(result);
159 }
160 let callback = acquire_async_trampoline::<P>;
161 unsafe {
162 ffi::g_permission_acquire_async(
163 self.as_ref().to_glib_none().0,
164 cancellable.map(|p| p.as_ref()).to_glib_none().0,
165 Some(callback),
166 Box_::into_raw(user_data) as *mut _,
167 );
168 }
169 }
170
171 fn acquire_future(
172 &self,
173 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
174 Box_::pin(crate::GioFuture::new(
175 self,
176 move |obj, cancellable, send| {
177 obj.acquire_async(Some(cancellable), move |res| {
178 send.resolve(res);
179 });
180 },
181 ))
182 }
183
184 #[doc(alias = "g_permission_get_allowed")]
192 #[doc(alias = "get_allowed")]
193 #[doc(alias = "allowed")]
194 fn is_allowed(&self) -> bool {
195 unsafe {
196 from_glib(ffi::g_permission_get_allowed(
197 self.as_ref().to_glib_none().0,
198 ))
199 }
200 }
201
202 #[doc(alias = "g_permission_get_can_acquire")]
210 #[doc(alias = "get_can_acquire")]
211 #[doc(alias = "can-acquire")]
212 fn can_acquire(&self) -> bool {
213 unsafe {
214 from_glib(ffi::g_permission_get_can_acquire(
215 self.as_ref().to_glib_none().0,
216 ))
217 }
218 }
219
220 #[doc(alias = "g_permission_get_can_release")]
228 #[doc(alias = "get_can_release")]
229 #[doc(alias = "can-release")]
230 fn can_release(&self) -> bool {
231 unsafe {
232 from_glib(ffi::g_permission_get_can_release(
233 self.as_ref().to_glib_none().0,
234 ))
235 }
236 }
237
238 #[doc(alias = "g_permission_impl_update")]
250 fn impl_update(&self, allowed: bool, can_acquire: bool, can_release: bool) {
251 unsafe {
252 ffi::g_permission_impl_update(
253 self.as_ref().to_glib_none().0,
254 allowed.into_glib(),
255 can_acquire.into_glib(),
256 can_release.into_glib(),
257 );
258 }
259 }
260
261 #[doc(alias = "g_permission_release")]
283 fn release(&self, cancellable: Option<&impl IsA<Cancellable>>) -> Result<(), glib::Error> {
284 unsafe {
285 let mut error = std::ptr::null_mut();
286 let is_ok = ffi::g_permission_release(
287 self.as_ref().to_glib_none().0,
288 cancellable.map(|p| p.as_ref()).to_glib_none().0,
289 &mut error,
290 );
291 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
292 if error.is_null() {
293 Ok(())
294 } else {
295 Err(from_glib_full(error))
296 }
297 }
298 }
299
300 #[doc(alias = "g_permission_release_async")]
309 fn release_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
310 &self,
311 cancellable: Option<&impl IsA<Cancellable>>,
312 callback: P,
313 ) {
314 let main_context = glib::MainContext::ref_thread_default();
315 let is_main_context_owner = main_context.is_owner();
316 let has_acquired_main_context = (!is_main_context_owner)
317 .then(|| main_context.acquire().ok())
318 .flatten();
319 assert!(
320 is_main_context_owner || has_acquired_main_context.is_some(),
321 "Async operations only allowed if the thread is owning the MainContext"
322 );
323
324 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
325 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
326 unsafe extern "C" fn release_async_trampoline<
327 P: FnOnce(Result<(), glib::Error>) + 'static,
328 >(
329 _source_object: *mut glib::gobject_ffi::GObject,
330 res: *mut crate::ffi::GAsyncResult,
331 user_data: glib::ffi::gpointer,
332 ) {
333 let mut error = std::ptr::null_mut();
334 ffi::g_permission_release_finish(_source_object as *mut _, res, &mut error);
335 let result = if error.is_null() {
336 Ok(())
337 } else {
338 Err(from_glib_full(error))
339 };
340 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
341 Box_::from_raw(user_data as *mut _);
342 let callback: P = callback.into_inner();
343 callback(result);
344 }
345 let callback = release_async_trampoline::<P>;
346 unsafe {
347 ffi::g_permission_release_async(
348 self.as_ref().to_glib_none().0,
349 cancellable.map(|p| p.as_ref()).to_glib_none().0,
350 Some(callback),
351 Box_::into_raw(user_data) as *mut _,
352 );
353 }
354 }
355
356 fn release_future(
357 &self,
358 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
359 Box_::pin(crate::GioFuture::new(
360 self,
361 move |obj, cancellable, send| {
362 obj.release_async(Some(cancellable), move |res| {
363 send.resolve(res);
364 });
365 },
366 ))
367 }
368
369 #[doc(alias = "allowed")]
370 fn connect_allowed_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
371 unsafe extern "C" fn notify_allowed_trampoline<P: IsA<Permission>, F: Fn(&P) + 'static>(
372 this: *mut ffi::GPermission,
373 _param_spec: glib::ffi::gpointer,
374 f: glib::ffi::gpointer,
375 ) {
376 let f: &F = &*(f as *const F);
377 f(Permission::from_glib_borrow(this).unsafe_cast_ref())
378 }
379 unsafe {
380 let f: Box_<F> = Box_::new(f);
381 connect_raw(
382 self.as_ptr() as *mut _,
383 c"notify::allowed".as_ptr() as *const _,
384 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
385 notify_allowed_trampoline::<Self, F> as *const (),
386 )),
387 Box_::into_raw(f),
388 )
389 }
390 }
391
392 #[doc(alias = "can-acquire")]
393 fn connect_can_acquire_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
394 unsafe extern "C" fn notify_can_acquire_trampoline<
395 P: IsA<Permission>,
396 F: Fn(&P) + 'static,
397 >(
398 this: *mut ffi::GPermission,
399 _param_spec: glib::ffi::gpointer,
400 f: glib::ffi::gpointer,
401 ) {
402 let f: &F = &*(f as *const F);
403 f(Permission::from_glib_borrow(this).unsafe_cast_ref())
404 }
405 unsafe {
406 let f: Box_<F> = Box_::new(f);
407 connect_raw(
408 self.as_ptr() as *mut _,
409 c"notify::can-acquire".as_ptr() as *const _,
410 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
411 notify_can_acquire_trampoline::<Self, F> as *const (),
412 )),
413 Box_::into_raw(f),
414 )
415 }
416 }
417
418 #[doc(alias = "can-release")]
419 fn connect_can_release_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
420 unsafe extern "C" fn notify_can_release_trampoline<
421 P: IsA<Permission>,
422 F: Fn(&P) + 'static,
423 >(
424 this: *mut ffi::GPermission,
425 _param_spec: glib::ffi::gpointer,
426 f: glib::ffi::gpointer,
427 ) {
428 let f: &F = &*(f as *const F);
429 f(Permission::from_glib_borrow(this).unsafe_cast_ref())
430 }
431 unsafe {
432 let f: Box_<F> = Box_::new(f);
433 connect_raw(
434 self.as_ptr() as *mut _,
435 c"notify::can-release".as_ptr() as *const _,
436 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
437 notify_can_release_trampoline::<Self, F> as *const (),
438 )),
439 Box_::into_raw(f),
440 )
441 }
442 }
443}
444
445impl<O: IsA<Permission>> PermissionExt for O {}